static int brcmstb_cpu_kill(u32 cpu) { u32 tmp; pr_info("SMP: Powering down CPU%d...\n", cpu); while (per_cpu_sw_state_rd(cpu)) ; /* Program zone reset */ pwr_ctrl_wr(cpu, ZONE_RESET_STATE_MASK | ZONE_BLK_RST_ASSERT_MASK | ZONE_PWR_DN_REQ_MASK); /* Verify zone reset */ tmp = pwr_ctrl_rd(cpu); if (!(tmp & ZONE_RESET_STATE_MASK)) pr_err("%s: Zone reset bit for CPU %d not asserted!\n", __func__, cpu); /* Wait for power down */ do { tmp = pwr_ctrl_rd(cpu); } while (!(tmp & ZONE_PWR_OFF_STATE_MASK)); /* Settle-time from Broadcom-internal DVT reference code */ udelay(7); /* Assert reset on the CPU */ cpu_rst_cfg_set(cpu, 1); return 1; }
static int pwr_ctrl_wait_tmout(unsigned int cpu, u32 set, u32 mask) { const unsigned long timeo = jiffies + msecs_to_jiffies(POLL_TMOUT_MS); u32 tmp; do { tmp = pwr_ctrl_rd(cpu) & mask; if (!set == !tmp) return 0; } while (time_before(jiffies, timeo)); tmp = pwr_ctrl_rd(cpu) & mask; if (!set == !tmp) return 0; return -ETIMEDOUT; }
static void brcmstb_cpu_power_on(u32 cpu) { /* * The secondary cores power was cut, so we must go through * power-on initialization. */ u32 tmp; pr_info("SMP: Powering up CPU%d...\n", cpu); /* Request zone power up */ pwr_ctrl_wr(cpu, ZONE_PWR_UP_REQ_MASK); /* Wait for the power up FSM to complete */ do { tmp = pwr_ctrl_rd(cpu); } while (!(tmp & ZONE_PWR_ON_STATE_MASK)); per_cpu_sw_state_wr(cpu, 1); }
int brcmstb_cpu_get_power_state(unsigned int cpu) { int tmp = pwr_ctrl_rd(cpu); return (tmp & ZONE_RESET_STATE_MASK) ? 0 : 1; }