diff options
Diffstat (limited to 'drivers/firmware/arm_sdei.c')
| -rw-r--r-- | drivers/firmware/arm_sdei.c | 37 | 
1 files changed, 20 insertions, 17 deletions
diff --git a/drivers/firmware/arm_sdei.c b/drivers/firmware/arm_sdei.c index 1e1a51510e83..f9040bd61081 100644 --- a/drivers/firmware/arm_sdei.c +++ b/drivers/firmware/arm_sdei.c @@ -43,6 +43,8 @@ static asmlinkage void (*sdei_firmware_call)(unsigned long function_id,  /* entry point from firmware to arch asm code */  static unsigned long sdei_entry_point; +static int sdei_hp_state; +  struct sdei_event {  	/* These three are protected by the sdei_list_lock */  	struct list_head	list; @@ -301,8 +303,6 @@ int sdei_mask_local_cpu(void)  {  	int err; -	WARN_ON_ONCE(preemptible()); -  	err = invoke_sdei_fn(SDEI_1_0_FN_SDEI_PE_MASK, 0, 0, 0, 0, 0, NULL);  	if (err && err != -EIO) {  		pr_warn_once("failed to mask CPU[%u]: %d\n", @@ -315,6 +315,7 @@ int sdei_mask_local_cpu(void)  static void _ipi_mask_cpu(void *ignored)  { +	WARN_ON_ONCE(preemptible());  	sdei_mask_local_cpu();  } @@ -322,8 +323,6 @@ int sdei_unmask_local_cpu(void)  {  	int err; -	WARN_ON_ONCE(preemptible()); -  	err = invoke_sdei_fn(SDEI_1_0_FN_SDEI_PE_UNMASK, 0, 0, 0, 0, 0, NULL);  	if (err && err != -EIO) {  		pr_warn_once("failed to unmask CPU[%u]: %d\n", @@ -336,6 +335,7 @@ int sdei_unmask_local_cpu(void)  static void _ipi_unmask_cpu(void *ignored)  { +	WARN_ON_ONCE(preemptible());  	sdei_unmask_local_cpu();  } @@ -343,6 +343,8 @@ static void _ipi_private_reset(void *ignored)  {  	int err; +	WARN_ON_ONCE(preemptible()); +  	err = invoke_sdei_fn(SDEI_1_0_FN_SDEI_PRIVATE_RESET, 0, 0, 0, 0, 0,  			     NULL);  	if (err && err != -EIO) @@ -389,8 +391,6 @@ static void _local_event_enable(void *data)  	int err;  	struct sdei_crosscall_args *arg = data; -	WARN_ON_ONCE(preemptible()); -  	err = sdei_api_event_enable(arg->event->event_num);  	sdei_cross_call_return(arg, err); @@ -479,8 +479,6 @@ static void _local_event_unregister(void *data)  	int err;  	struct sdei_crosscall_args *arg = data; -	WARN_ON_ONCE(preemptible()); -  	err = sdei_api_event_unregister(arg->event->event_num);  	sdei_cross_call_return(arg, err); @@ -561,8 +559,6 @@ static void _local_event_register(void *data)  	struct sdei_registered_event *reg;  	struct sdei_crosscall_args *arg = data; -	WARN_ON(preemptible()); -  	reg = per_cpu_ptr(arg->event->private_registered, smp_processor_id());  	err = sdei_api_event_register(arg->event->event_num, sdei_entry_point,  				      reg, 0, 0); @@ -717,6 +713,8 @@ static int sdei_pm_notifier(struct notifier_block *nb, unsigned long action,  {  	int rv; +	WARN_ON_ONCE(preemptible()); +  	switch (action) {  	case CPU_PM_ENTER:  		rv = sdei_mask_local_cpu(); @@ -765,7 +763,7 @@ static int sdei_device_freeze(struct device *dev)  	int err;  	/* unregister private events */ -	cpuhp_remove_state(CPUHP_AP_ARM_SDEI_STARTING); +	cpuhp_remove_state(sdei_entry_point);  	err = sdei_unregister_shared();  	if (err) @@ -786,12 +784,15 @@ static int sdei_device_thaw(struct device *dev)  		return err;  	} -	err = cpuhp_setup_state(CPUHP_AP_ARM_SDEI_STARTING, "SDEI", +	err = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "SDEI",  				&sdei_cpuhp_up, &sdei_cpuhp_down); -	if (err) +	if (err < 0) {  		pr_warn("Failed to re-register CPU hotplug notifier...\n"); +		return err; +	} -	return err; +	sdei_hp_state = err; +	return 0;  }  static int sdei_device_restore(struct device *dev) @@ -823,7 +824,7 @@ static int sdei_reboot_notifier(struct notifier_block *nb, unsigned long action,  	 * We are going to reset the interface, after this there is no point  	 * doing work when we take CPUs offline.  	 */ -	cpuhp_remove_state(CPUHP_AP_ARM_SDEI_STARTING); +	cpuhp_remove_state(sdei_hp_state);  	sdei_platform_reset(); @@ -1003,13 +1004,15 @@ static int sdei_probe(struct platform_device *pdev)  		goto remove_cpupm;  	} -	err = cpuhp_setup_state(CPUHP_AP_ARM_SDEI_STARTING, "SDEI", +	err = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "SDEI",  				&sdei_cpuhp_up, &sdei_cpuhp_down); -	if (err) { +	if (err < 0) {  		pr_warn("Failed to register CPU hotplug notifier...\n");  		goto remove_reboot;  	} +	sdei_hp_state = err; +  	return 0;  remove_reboot:  |