diff --git a/arch/arm/mach-highbank/pm.c b/arch/arm/mach-highbank/pm.c index 400311695548..165e44e1844a 100644 --- a/arch/arm/mach-highbank/pm.c +++ b/arch/arm/mach-highbank/pm.c @@ -36,11 +36,11 @@ static int highbank_suspend_finish(unsigned long val) static int highbank_pm_enter(suspend_state_t state) { cpu_pm_enter(); - cpu_cluster_pm_enter(); + cpu_cluster_pm_enter(0); cpu_suspend(0, highbank_suspend_finish); - cpu_cluster_pm_exit(); + cpu_cluster_pm_exit(0); cpu_pm_exit(); return 0; diff --git a/arch/arm/mach-omap2/cpuidle44xx.c b/arch/arm/mach-omap2/cpuidle44xx.c index 4b8e9f4d59ea..96698652e697 100644 --- a/arch/arm/mach-omap2/cpuidle44xx.c +++ b/arch/arm/mach-omap2/cpuidle44xx.c @@ -127,7 +127,7 @@ static int omap_enter_idle_coupled(struct cpuidle_device *dev, * to save GIC and wakeupgen context. */ if (mpuss_can_lose_context) - cpu_cluster_pm_enter(); + cpu_cluster_pm_enter(0); } omap4_enter_lowpower(dev->cpu, cx->cpu_state); @@ -165,7 +165,7 @@ static int omap_enter_idle_coupled(struct cpuidle_device *dev, * to restore GIC and wakeupgen context. */ if (dev->cpu == 0 && mpuss_can_lose_context) - cpu_cluster_pm_exit(); + cpu_cluster_pm_exit(0); tick_broadcast_exit(); diff --git a/arch/arm/mach-tegra/pm.c b/arch/arm/mach-tegra/pm.c index b0f48a3946fa..9eabddce6d8d 100644 --- a/arch/arm/mach-tegra/pm.c +++ b/arch/arm/mach-tegra/pm.c @@ -192,13 +192,13 @@ void tegra_idle_lp2_last(void) { tegra_pm_set(TEGRA_SUSPEND_LP2); - cpu_cluster_pm_enter(); + cpu_cluster_pm_enter(0); suspend_cpu_complex(); cpu_suspend(PHYS_OFFSET - PAGE_OFFSET, &tegra_sleep_cpu); restore_cpu_complex(); - cpu_cluster_pm_exit(); + cpu_cluster_pm_exit(0); } enum tegra_suspend_mode tegra_pm_validate_suspend_mode( diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c index 18252fd3bec6..087c31ab3326 100644 --- a/drivers/irqchip/irq-gic.c +++ b/drivers/irqchip/irq-gic.c @@ -766,7 +766,8 @@ static void gic_cpu_restore(unsigned int gic_nr) gic_cpu_if_up(&gic_data[gic_nr]); } -static int gic_notifier(struct notifier_block *self, unsigned long cmd, void *v) +static int gic_notifier(struct notifier_block *self, unsigned long cmd, + void *aff_level) { int i; @@ -785,11 +786,20 @@ static int gic_notifier(struct notifier_block *self, unsigned long cmd, void *v) gic_cpu_restore(i); break; case CPU_CLUSTER_PM_ENTER: - gic_dist_save(i); + /* + * Affinity level of the node + * eg: + * cpu level = 0 + * l2 level = 1 + * cci level = 2 + */ + if (!(unsigned long)aff_level) + gic_dist_save(i); break; case CPU_CLUSTER_PM_ENTER_FAILED: case CPU_CLUSTER_PM_EXIT: - gic_dist_restore(i); + if (!(unsigned long)aff_level) + gic_dist_restore(i); break; } } diff --git a/include/linux/cpu_pm.h b/include/linux/cpu_pm.h index 455b233dd3b1..91117bcc665a 100644 --- a/include/linux/cpu_pm.h +++ b/include/linux/cpu_pm.h @@ -71,8 +71,8 @@ int cpu_pm_register_notifier(struct notifier_block *nb); int cpu_pm_unregister_notifier(struct notifier_block *nb); int cpu_pm_enter(void); int cpu_pm_exit(void); -int cpu_cluster_pm_enter(void); -int cpu_cluster_pm_exit(void); +int cpu_cluster_pm_enter(unsigned long aff_level); +int cpu_cluster_pm_exit(unsigned long aff_level); #else @@ -96,12 +96,12 @@ static inline int cpu_pm_exit(void) return 0; } -static inline int cpu_cluster_pm_enter(void) +static inline int cpu_cluster_pm_enter(unsigned long aff_level) { return 0; } -static inline int cpu_cluster_pm_exit(void) +static inline int cpu_cluster_pm_exit(unsigned long aff_level) { return 0; } diff --git a/kernel/cpu_pm.c b/kernel/cpu_pm.c index 009cc9a17d95..6c3523f83776 100644 --- a/kernel/cpu_pm.c +++ b/kernel/cpu_pm.c @@ -25,11 +25,12 @@ static DEFINE_RWLOCK(cpu_pm_notifier_lock); static RAW_NOTIFIER_HEAD(cpu_pm_notifier_chain); -static int cpu_pm_notify(enum cpu_pm_event event, int nr_to_call, int *nr_calls) +static int cpu_pm_notify(enum cpu_pm_event event, int nr_to_call, int *nr_calls, + void *data) { int ret; - ret = __raw_notifier_call_chain(&cpu_pm_notifier_chain, event, NULL, + ret = __raw_notifier_call_chain(&cpu_pm_notifier_chain, event, data, nr_to_call, nr_calls); return notifier_to_errno(ret); @@ -101,13 +102,13 @@ int cpu_pm_enter(void) int ret = 0; read_lock(&cpu_pm_notifier_lock); - ret = cpu_pm_notify(CPU_PM_ENTER, -1, &nr_calls); + ret = cpu_pm_notify(CPU_PM_ENTER, -1, &nr_calls, NULL); if (ret) /* * Inform listeners (nr_calls - 1) about failure of CPU PM * PM entry who are notified earlier to prepare for it. */ - cpu_pm_notify(CPU_PM_ENTER_FAILED, nr_calls - 1, NULL); + cpu_pm_notify(CPU_PM_ENTER_FAILED, nr_calls - 1, NULL, NULL); read_unlock(&cpu_pm_notifier_lock); return ret; @@ -131,7 +132,7 @@ int cpu_pm_exit(void) int ret; read_lock(&cpu_pm_notifier_lock); - ret = cpu_pm_notify(CPU_PM_EXIT, -1, NULL); + ret = cpu_pm_notify(CPU_PM_EXIT, -1, NULL, NULL); read_unlock(&cpu_pm_notifier_lock); return ret; @@ -154,19 +155,21 @@ EXPORT_SYMBOL_GPL(cpu_pm_exit); * * Return conditions are same as __raw_notifier_call_chain. */ -int cpu_cluster_pm_enter(void) +int cpu_cluster_pm_enter(unsigned long aff_level) { int nr_calls; int ret = 0; read_lock(&cpu_pm_notifier_lock); - ret = cpu_pm_notify(CPU_CLUSTER_PM_ENTER, -1, &nr_calls); + ret = cpu_pm_notify(CPU_CLUSTER_PM_ENTER, -1, &nr_calls, + (void *) aff_level); if (ret) /* * Inform listeners (nr_calls - 1) about failure of CPU cluster * PM entry who are notified earlier to prepare for it. */ - cpu_pm_notify(CPU_CLUSTER_PM_ENTER_FAILED, nr_calls - 1, NULL); + cpu_pm_notify(CPU_CLUSTER_PM_ENTER_FAILED, nr_calls - 1, NULL, + (void *) aff_level); read_unlock(&cpu_pm_notifier_lock); return ret; @@ -188,12 +191,12 @@ EXPORT_SYMBOL_GPL(cpu_cluster_pm_enter); * * Return conditions are same as __raw_notifier_call_chain. */ -int cpu_cluster_pm_exit(void) +int cpu_cluster_pm_exit(unsigned long aff_level) { int ret; read_lock(&cpu_pm_notifier_lock); - ret = cpu_pm_notify(CPU_CLUSTER_PM_EXIT, -1, NULL); + ret = cpu_pm_notify(CPU_CLUSTER_PM_EXIT, -1, NULL, (void *) aff_level); read_unlock(&cpu_pm_notifier_lock); return ret; @@ -209,13 +212,13 @@ static int cpu_pm_suspend(void) if (ret) return ret; - ret = cpu_cluster_pm_enter(); + ret = cpu_cluster_pm_enter(0); return ret; } static void cpu_pm_resume(void) { - cpu_cluster_pm_exit(); + cpu_cluster_pm_exit(0); cpu_pm_exit(); }