aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/platforms/powermac
diff options
context:
space:
mode:
authorJohannes Berg <johannes@sipsolutions.net>2006-06-13 11:43:42 -0400
committerPaul Mackerras <paulus@samba.org>2006-06-15 05:31:27 -0400
commit4312dc76a88146c4f1d693fc4643d1df12aaf755 (patch)
treedc416a6b6c562c2563c37d00656fcf6ad2166c12 /arch/powerpc/platforms/powermac
parent368a6ba5d188552aea2a668301a259164c9f355e (diff)
[POWERPC] make pmf irq_client functions safe against pmf interrupts coming in
This fixes the pmf irq_client functions to be safe against pmf interrupts coming in while a client is registered/unregistered. Signed-off-by: Johannes Berg <johannes@sipsolutions.net> Signed-off-by: Paul Mackerras <paulus@samba.org>
Diffstat (limited to 'arch/powerpc/platforms/powermac')
-rw-r--r--arch/powerpc/platforms/powermac/pfunc_core.c14
1 files changed, 14 insertions, 0 deletions
diff --git a/arch/powerpc/platforms/powermac/pfunc_core.c b/arch/powerpc/platforms/powermac/pfunc_core.c
index f08173b0f065..047f954a89eb 100644
--- a/arch/powerpc/platforms/powermac/pfunc_core.c
+++ b/arch/powerpc/platforms/powermac/pfunc_core.c
@@ -871,10 +871,17 @@ int pmf_register_irq_client(struct device_node *target,
871 spin_unlock_irqrestore(&pmf_lock, flags); 871 spin_unlock_irqrestore(&pmf_lock, flags);
872 if (func == NULL) 872 if (func == NULL)
873 return -ENODEV; 873 return -ENODEV;
874
875 /* guard against manipulations of list */
874 mutex_lock(&pmf_irq_mutex); 876 mutex_lock(&pmf_irq_mutex);
875 if (list_empty(&func->irq_clients)) 877 if (list_empty(&func->irq_clients))
876 func->dev->handlers->irq_enable(func); 878 func->dev->handlers->irq_enable(func);
879
880 /* guard against pmf_do_irq while changing list */
881 spin_lock_irqsave(&pmf_lock, flags);
877 list_add(&client->link, &func->irq_clients); 882 list_add(&client->link, &func->irq_clients);
883 spin_unlock_irqrestore(&pmf_lock, flags);
884
878 client->func = func; 885 client->func = func;
879 mutex_unlock(&pmf_irq_mutex); 886 mutex_unlock(&pmf_irq_mutex);
880 887
@@ -885,12 +892,19 @@ EXPORT_SYMBOL_GPL(pmf_register_irq_client);
885void pmf_unregister_irq_client(struct pmf_irq_client *client) 892void pmf_unregister_irq_client(struct pmf_irq_client *client)
886{ 893{
887 struct pmf_function *func = client->func; 894 struct pmf_function *func = client->func;
895 unsigned long flags;
888 896
889 BUG_ON(func == NULL); 897 BUG_ON(func == NULL);
890 898
899 /* guard against manipulations of list */
891 mutex_lock(&pmf_irq_mutex); 900 mutex_lock(&pmf_irq_mutex);
892 client->func = NULL; 901 client->func = NULL;
902
903 /* guard against pmf_do_irq while changing list */
904 spin_lock_irqsave(&pmf_lock, flags);
893 list_del(&client->link); 905 list_del(&client->link);
906 spin_unlock_irqrestore(&pmf_lock, flags);
907
894 if (list_empty(&func->irq_clients)) 908 if (list_empty(&func->irq_clients))
895 func->dev->handlers->irq_disable(func); 909 func->dev->handlers->irq_disable(func);
896 mutex_unlock(&pmf_irq_mutex); 910 mutex_unlock(&pmf_irq_mutex);