diff options
author | Richard Purdie <rpurdie@rpsys.net> | 2007-12-31 18:09:44 -0500 |
---|---|---|
committer | Richard Purdie <rpurdie@rpsys.net> | 2007-12-31 18:09:44 -0500 |
commit | 72f8da329e07ad8a72c1f0e96b8955cfeb7c7329 (patch) | |
tree | 7440f70caf2fb70e987f814cebcdf233a17b425c /drivers/leds | |
parent | e697789d64f8748cb219d7f5c413c512953802cc (diff) |
leds: Fix leds_list_lock locking issues
Covert leds_list_lock to a rw_sempahore to match previous LED trigger
locking fixes, fixing lock ordering.
Signed-off-by: Richard Purdie <rpurdie@rpsys.net>
Diffstat (limited to 'drivers/leds')
-rw-r--r-- | drivers/leds/led-class.c | 8 | ||||
-rw-r--r-- | drivers/leds/led-core.c | 4 | ||||
-rw-r--r-- | drivers/leds/led-triggers.c | 8 | ||||
-rw-r--r-- | drivers/leds/leds.h | 3 |
4 files changed, 12 insertions, 11 deletions
diff --git a/drivers/leds/led-class.c b/drivers/leds/led-class.c index ba8b04b03b9f..64c66b3769c9 100644 --- a/drivers/leds/led-class.c +++ b/drivers/leds/led-class.c | |||
@@ -106,9 +106,9 @@ int led_classdev_register(struct device *parent, struct led_classdev *led_cdev) | |||
106 | goto err_out; | 106 | goto err_out; |
107 | 107 | ||
108 | /* add to the list of leds */ | 108 | /* add to the list of leds */ |
109 | write_lock(&leds_list_lock); | 109 | down_write(&leds_list_lock); |
110 | list_add_tail(&led_cdev->node, &leds_list); | 110 | list_add_tail(&led_cdev->node, &leds_list); |
111 | write_unlock(&leds_list_lock); | 111 | up_write(&leds_list_lock); |
112 | 112 | ||
113 | #ifdef CONFIG_LEDS_TRIGGERS | 113 | #ifdef CONFIG_LEDS_TRIGGERS |
114 | init_rwsem(&led_cdev->trigger_lock); | 114 | init_rwsem(&led_cdev->trigger_lock); |
@@ -155,9 +155,9 @@ void led_classdev_unregister(struct led_classdev *led_cdev) | |||
155 | 155 | ||
156 | device_unregister(led_cdev->dev); | 156 | device_unregister(led_cdev->dev); |
157 | 157 | ||
158 | write_lock(&leds_list_lock); | 158 | down_write(&leds_list_lock); |
159 | list_del(&led_cdev->node); | 159 | list_del(&led_cdev->node); |
160 | write_unlock(&leds_list_lock); | 160 | up_write(&leds_list_lock); |
161 | } | 161 | } |
162 | EXPORT_SYMBOL_GPL(led_classdev_unregister); | 162 | EXPORT_SYMBOL_GPL(led_classdev_unregister); |
163 | 163 | ||
diff --git a/drivers/leds/led-core.c b/drivers/leds/led-core.c index 9b015f9af351..5d1ca10524b6 100644 --- a/drivers/leds/led-core.c +++ b/drivers/leds/led-core.c | |||
@@ -14,11 +14,11 @@ | |||
14 | #include <linux/kernel.h> | 14 | #include <linux/kernel.h> |
15 | #include <linux/list.h> | 15 | #include <linux/list.h> |
16 | #include <linux/module.h> | 16 | #include <linux/module.h> |
17 | #include <linux/spinlock.h> | 17 | #include <linux/rwsem.h> |
18 | #include <linux/leds.h> | 18 | #include <linux/leds.h> |
19 | #include "leds.h" | 19 | #include "leds.h" |
20 | 20 | ||
21 | DEFINE_RWLOCK(leds_list_lock); | 21 | DECLARE_RWSEM(leds_list_lock); |
22 | LIST_HEAD(leds_list); | 22 | LIST_HEAD(leds_list); |
23 | 23 | ||
24 | EXPORT_SYMBOL_GPL(leds_list); | 24 | EXPORT_SYMBOL_GPL(leds_list); |
diff --git a/drivers/leds/led-triggers.c b/drivers/leds/led-triggers.c index 0bdb786210b1..13c9026d68af 100644 --- a/drivers/leds/led-triggers.c +++ b/drivers/leds/led-triggers.c | |||
@@ -169,7 +169,7 @@ int led_trigger_register(struct led_trigger *trigger) | |||
169 | up_write(&triggers_list_lock); | 169 | up_write(&triggers_list_lock); |
170 | 170 | ||
171 | /* Register with any LEDs that have this as a default trigger */ | 171 | /* Register with any LEDs that have this as a default trigger */ |
172 | read_lock(&leds_list_lock); | 172 | down_read(&leds_list_lock); |
173 | list_for_each_entry(led_cdev, &leds_list, node) { | 173 | list_for_each_entry(led_cdev, &leds_list, node) { |
174 | down_write(&led_cdev->trigger_lock); | 174 | down_write(&led_cdev->trigger_lock); |
175 | if (!led_cdev->trigger && led_cdev->default_trigger && | 175 | if (!led_cdev->trigger && led_cdev->default_trigger && |
@@ -177,7 +177,7 @@ int led_trigger_register(struct led_trigger *trigger) | |||
177 | led_trigger_set(led_cdev, trigger); | 177 | led_trigger_set(led_cdev, trigger); |
178 | up_write(&led_cdev->trigger_lock); | 178 | up_write(&led_cdev->trigger_lock); |
179 | } | 179 | } |
180 | read_unlock(&leds_list_lock); | 180 | up_read(&leds_list_lock); |
181 | 181 | ||
182 | return 0; | 182 | return 0; |
183 | } | 183 | } |
@@ -212,14 +212,14 @@ void led_trigger_unregister(struct led_trigger *trigger) | |||
212 | up_write(&triggers_list_lock); | 212 | up_write(&triggers_list_lock); |
213 | 213 | ||
214 | /* Remove anyone actively using this trigger */ | 214 | /* Remove anyone actively using this trigger */ |
215 | read_lock(&leds_list_lock); | 215 | down_read(&leds_list_lock); |
216 | list_for_each_entry(led_cdev, &leds_list, node) { | 216 | list_for_each_entry(led_cdev, &leds_list, node) { |
217 | down_write(&led_cdev->trigger_lock); | 217 | down_write(&led_cdev->trigger_lock); |
218 | if (led_cdev->trigger == trigger) | 218 | if (led_cdev->trigger == trigger) |
219 | led_trigger_set(led_cdev, NULL); | 219 | led_trigger_set(led_cdev, NULL); |
220 | up_write(&led_cdev->trigger_lock); | 220 | up_write(&led_cdev->trigger_lock); |
221 | } | 221 | } |
222 | read_unlock(&leds_list_lock); | 222 | up_read(&leds_list_lock); |
223 | } | 223 | } |
224 | 224 | ||
225 | void led_trigger_unregister_simple(struct led_trigger *trigger) | 225 | void led_trigger_unregister_simple(struct led_trigger *trigger) |
diff --git a/drivers/leds/leds.h b/drivers/leds/leds.h index f2f3884fe063..12b6fe93b135 100644 --- a/drivers/leds/leds.h +++ b/drivers/leds/leds.h | |||
@@ -14,6 +14,7 @@ | |||
14 | #define __LEDS_H_INCLUDED | 14 | #define __LEDS_H_INCLUDED |
15 | 15 | ||
16 | #include <linux/device.h> | 16 | #include <linux/device.h> |
17 | #include <linux/rwsem.h> | ||
17 | #include <linux/leds.h> | 18 | #include <linux/leds.h> |
18 | 19 | ||
19 | static inline void led_set_brightness(struct led_classdev *led_cdev, | 20 | static inline void led_set_brightness(struct led_classdev *led_cdev, |
@@ -26,7 +27,7 @@ static inline void led_set_brightness(struct led_classdev *led_cdev, | |||
26 | led_cdev->brightness_set(led_cdev, value); | 27 | led_cdev->brightness_set(led_cdev, value); |
27 | } | 28 | } |
28 | 29 | ||
29 | extern rwlock_t leds_list_lock; | 30 | extern struct rw_semaphore leds_list_lock; |
30 | extern struct list_head leds_list; | 31 | extern struct list_head leds_list; |
31 | 32 | ||
32 | #ifdef CONFIG_LEDS_TRIGGERS | 33 | #ifdef CONFIG_LEDS_TRIGGERS |