diff options
author | Johannes Berg <johannes@sipsolutions.net> | 2006-06-13 11:43:42 -0400 |
---|---|---|
committer | Paul Mackerras <paulus@samba.org> | 2006-06-15 05:31:27 -0400 |
commit | 4312dc76a88146c4f1d693fc4643d1df12aaf755 (patch) | |
tree | dc416a6b6c562c2563c37d00656fcf6ad2166c12 /arch/powerpc/platforms/powermac | |
parent | 368a6ba5d188552aea2a668301a259164c9f355e (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.c | 14 |
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); | |||
885 | void pmf_unregister_irq_client(struct pmf_irq_client *client) | 892 | void 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); |