extern int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state);
extern int omap4_finish_suspend(unsigned long cpu_state);
extern void omap4_cpu_resume(void);
+extern int omap4_hotplug_cpu(unsigned int cpu, unsigned int power_state);
#else
static inline int omap4_enter_lowpower(unsigned int cpu,
unsigned int power_state)
return 0;
}
+static inline int omap4_hotplug_cpu(unsigned int cpu, unsigned int power_state)
+{
+ cpu_do_idle();
+ return 0;
+}
+
static inline int omap4_mpuss_init(void)
{
return 0;
#include "common.h"
+#include "powerdomain.h"
+
int platform_cpu_kill(unsigned int cpu)
{
return 1;
*/
void platform_cpu_die(unsigned int cpu)
{
+ unsigned int this_cpu;
+
flush_cache_all();
dsb();
* we're ready for shutdown now, so do it
*/
if (omap_modify_auxcoreboot0(0x0, 0x200) != 0x0)
- printk(KERN_CRIT "Secure clear status failed\n");
+ pr_err("Secure clear status failed\n");
for (;;) {
/*
- * Execute WFI
+ * Enter into low power state
*/
- do_wfi();
-
- if (omap_read_auxcoreboot0() == cpu) {
+ omap4_hotplug_cpu(cpu, PWRDM_POWER_OFF);
+ this_cpu = smp_processor_id();
+ if (omap_read_auxcoreboot0() == this_cpu) {
/*
* OK, proper wakeup, we're done
*/
return 0;
}
+/**
+ * omap4_hotplug_cpu: OMAP4 CPU hotplug entry
+ * @cpu : CPU ID
+ * @power_state: CPU low power state.
+ */
+int omap4_hotplug_cpu(unsigned int cpu, unsigned int power_state)
+{
+ unsigned int cpu_state = 0;
+
+ if (omap_rev() == OMAP4430_REV_ES1_0)
+ return -ENXIO;
+
+ if (power_state == PWRDM_POWER_OFF)
+ cpu_state = 1;
+
+ clear_cpu_prev_pwrst(cpu);
+ set_cpu_next_pwrst(cpu, power_state);
+ set_cpu_wakeup_addr(cpu, virt_to_phys(omap_secondary_startup));
+ scu_pwrst_prepare(cpu, power_state);
+
+ /*
+ * CPU never retuns back if targetted power state is OFF mode.
+ * CPU ONLINE follows normal CPU ONLINE ptah via
+ * omap_secondary_startup().
+ */
+ omap4_finish_suspend(cpu_state);
+
+ set_cpu_next_pwrst(cpu, PWRDM_POWER_ON);
+ return 0;
+}
+
+
/*
* Initialise OMAP4 MPUSS
*/
spin_unlock_irqrestore(&wakeupgen_lock, flags);
}
+#ifdef CONFIG_HOTPLUG_CPU
+static int __cpuinit irq_cpu_hotplug_notify(struct notifier_block *self,
+ unsigned long action, void *hcpu)
+{
+ unsigned int cpu = (unsigned int)hcpu;
+
+ switch (action) {
+ case CPU_ONLINE:
+ wakeupgen_irqmask_all(cpu, 0);
+ break;
+ case CPU_DEAD:
+ wakeupgen_irqmask_all(cpu, 1);
+ break;
+ }
+ return NOTIFY_OK;
+}
+
+static struct notifier_block __refdata irq_hotplug_notifier = {
+ .notifier_call = irq_cpu_hotplug_notify,
+};
+
+static void __init irq_hotplug_init(void)
+{
+ register_hotcpu_notifier(&irq_hotplug_notifier);
+}
+#else
+static void __init irq_hotplug_init(void)
+{}
+#endif
+
/*
* Initialise the wakeupgen module.
*/
for (i = 0; i < NR_IRQS; i++)
irq_target_cpu[i] = boot_cpu;
+ irq_hotplug_init();
+
return 0;
}