diff options
Diffstat (limited to 'kernel/cpu_pm.c')
| -rw-r--r-- | kernel/cpu_pm.c | 48 | 
1 files changed, 18 insertions, 30 deletions
diff --git a/kernel/cpu_pm.c b/kernel/cpu_pm.c index 44a259338e33..f7e1d0eccdbc 100644 --- a/kernel/cpu_pm.c +++ b/kernel/cpu_pm.c @@ -15,18 +15,28 @@  static ATOMIC_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 ret;  	/* -	 * __atomic_notifier_call_chain has a RCU read critical section, which +	 * atomic_notifier_call_chain has a RCU read critical section, which  	 * could be disfunctional in cpu idle. Copy RCU_NONIDLE code to let  	 * RCU know this.  	 */  	rcu_irq_enter_irqson(); -	ret = __atomic_notifier_call_chain(&cpu_pm_notifier_chain, event, NULL, -		nr_to_call, nr_calls); +	ret = atomic_notifier_call_chain(&cpu_pm_notifier_chain, event, NULL); +	rcu_irq_exit_irqson(); + +	return notifier_to_errno(ret); +} + +static int cpu_pm_notify_robust(enum cpu_pm_event event_up, enum cpu_pm_event event_down) +{ +	int ret; + +	rcu_irq_enter_irqson(); +	ret = atomic_notifier_call_chain_robust(&cpu_pm_notifier_chain, event_up, event_down, NULL);  	rcu_irq_exit_irqson();  	return notifier_to_errno(ret); @@ -80,18 +90,7 @@ EXPORT_SYMBOL_GPL(cpu_pm_unregister_notifier);   */  int cpu_pm_enter(void)  { -	int nr_calls = 0; -	int ret = 0; - -	ret = cpu_pm_notify(CPU_PM_ENTER, -1, &nr_calls); -	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); - -	return ret; +	return cpu_pm_notify_robust(CPU_PM_ENTER, CPU_PM_ENTER_FAILED);  }  EXPORT_SYMBOL_GPL(cpu_pm_enter); @@ -109,7 +108,7 @@ EXPORT_SYMBOL_GPL(cpu_pm_enter);   */  int cpu_pm_exit(void)  { -	return cpu_pm_notify(CPU_PM_EXIT, -1, NULL); +	return cpu_pm_notify(CPU_PM_EXIT);  }  EXPORT_SYMBOL_GPL(cpu_pm_exit); @@ -131,18 +130,7 @@ EXPORT_SYMBOL_GPL(cpu_pm_exit);   */  int cpu_cluster_pm_enter(void)  { -	int nr_calls = 0; -	int ret = 0; - -	ret = cpu_pm_notify(CPU_CLUSTER_PM_ENTER, -1, &nr_calls); -	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); - -	return ret; +	return cpu_pm_notify_robust(CPU_CLUSTER_PM_ENTER, CPU_CLUSTER_PM_ENTER_FAILED);  }  EXPORT_SYMBOL_GPL(cpu_cluster_pm_enter); @@ -163,7 +151,7 @@ EXPORT_SYMBOL_GPL(cpu_cluster_pm_enter);   */  int cpu_cluster_pm_exit(void)  { -	return cpu_pm_notify(CPU_CLUSTER_PM_EXIT, -1, NULL); +	return cpu_pm_notify(CPU_CLUSTER_PM_EXIT);  }  EXPORT_SYMBOL_GPL(cpu_cluster_pm_exit);  |