[PATCH] pmf_register_irq_client() gives sleep with locks held warning

From: Benjamin Herrenschmidt <benh@kernel.crashing.org>

This fixes request_irq() potentially called from atomic context.

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>

authored by Benjamin Herrenschmidt and committed by Linus Torvalds 78b86e57 6d09bb62

+11 -7
+11 -7
arch/powerpc/platforms/powermac/pfunc_core.c
··· 11 #include <linux/kernel.h> 12 #include <linux/spinlock.h> 13 #include <linux/module.h> 14 15 #include <asm/semaphore.h> 16 #include <asm/prom.h> ··· 547 548 static LIST_HEAD(pmf_devices); 549 static spinlock_t pmf_lock = SPIN_LOCK_UNLOCKED; 550 551 static void pmf_release_device(struct kref *kref) 552 { ··· 866 867 spin_lock_irqsave(&pmf_lock, flags); 868 func = __pmf_find_function(target, name, PMF_FLAGS_INT_GEN); 869 - if (func == NULL) { 870 - spin_unlock_irqrestore(&pmf_lock, flags); 871 return -ENODEV; 872 - } 873 if (list_empty(&func->irq_clients)) 874 func->dev->handlers->irq_enable(func); 875 list_add(&client->link, &func->irq_clients); 876 client->func = func; 877 - spin_unlock_irqrestore(&pmf_lock, flags); 878 879 return 0; 880 } ··· 885 void pmf_unregister_irq_client(struct pmf_irq_client *client) 886 { 887 struct pmf_function *func = client->func; 888 - unsigned long flags; 889 890 BUG_ON(func == NULL); 891 892 - spin_lock_irqsave(&pmf_lock, flags); 893 client->func = NULL; 894 list_del(&client->link); 895 if (list_empty(&func->irq_clients)) 896 func->dev->handlers->irq_disable(func); 897 - spin_unlock_irqrestore(&pmf_lock, flags); 898 } 899 EXPORT_SYMBOL_GPL(pmf_unregister_irq_client); 900
··· 11 #include <linux/kernel.h> 12 #include <linux/spinlock.h> 13 #include <linux/module.h> 14 + #include <linux/mutex.h> 15 16 #include <asm/semaphore.h> 17 #include <asm/prom.h> ··· 546 547 static LIST_HEAD(pmf_devices); 548 static spinlock_t pmf_lock = SPIN_LOCK_UNLOCKED; 549 + static DEFINE_MUTEX(pmf_irq_mutex); 550 551 static void pmf_release_device(struct kref *kref) 552 { ··· 864 865 spin_lock_irqsave(&pmf_lock, flags); 866 func = __pmf_find_function(target, name, PMF_FLAGS_INT_GEN); 867 + if (func) 868 + func = pmf_get_function(func); 869 + spin_unlock_irqrestore(&pmf_lock, flags); 870 + if (func == NULL) 871 return -ENODEV; 872 + mutex_lock(&pmf_irq_mutex); 873 if (list_empty(&func->irq_clients)) 874 func->dev->handlers->irq_enable(func); 875 list_add(&client->link, &func->irq_clients); 876 client->func = func; 877 + mutex_unlock(&pmf_irq_mutex); 878 879 return 0; 880 } ··· 881 void pmf_unregister_irq_client(struct pmf_irq_client *client) 882 { 883 struct pmf_function *func = client->func; 884 885 BUG_ON(func == NULL); 886 887 + mutex_lock(&pmf_irq_mutex); 888 client->func = NULL; 889 list_del(&client->link); 890 if (list_empty(&func->irq_clients)) 891 func->dev->handlers->irq_disable(func); 892 + mutex_unlock(&pmf_irq_mutex); 893 + pmf_put_function(func); 894 } 895 EXPORT_SYMBOL_GPL(pmf_unregister_irq_client); 896