@@ -157,7 +157,6 @@ EXPORT_SYMBOL_GPL(led_trigger_read);
157
157
/* Caller must ensure led_cdev->trigger_lock held */
158
158
int led_trigger_set (struct led_classdev * led_cdev , struct led_trigger * trig )
159
159
{
160
- unsigned long flags ;
161
160
char * event = NULL ;
162
161
char * envp [2 ];
163
162
const char * name ;
@@ -171,10 +170,13 @@ int led_trigger_set(struct led_classdev *led_cdev, struct led_trigger *trig)
171
170
172
171
/* Remove any existing trigger */
173
172
if (led_cdev -> trigger ) {
174
- write_lock_irqsave (& led_cdev -> trigger -> leddev_list_lock , flags );
175
- list_del (& led_cdev -> trig_list );
176
- write_unlock_irqrestore (& led_cdev -> trigger -> leddev_list_lock ,
177
- flags );
173
+ spin_lock (& led_cdev -> trigger -> leddev_list_lock );
174
+ list_del_rcu (& led_cdev -> trig_list );
175
+ spin_unlock (& led_cdev -> trigger -> leddev_list_lock );
176
+
177
+ /* ensure it's no longer visible on the led_cdevs list */
178
+ synchronize_rcu ();
179
+
178
180
cancel_work_sync (& led_cdev -> set_brightness_work );
179
181
led_stop_software_blink (led_cdev );
180
182
if (led_cdev -> trigger -> deactivate )
@@ -186,9 +188,9 @@ int led_trigger_set(struct led_classdev *led_cdev, struct led_trigger *trig)
186
188
led_set_brightness (led_cdev , LED_OFF );
187
189
}
188
190
if (trig ) {
189
- write_lock_irqsave (& trig -> leddev_list_lock , flags );
190
- list_add_tail (& led_cdev -> trig_list , & trig -> led_cdevs );
191
- write_unlock_irqrestore (& trig -> leddev_list_lock , flags );
191
+ spin_lock (& trig -> leddev_list_lock );
192
+ list_add_tail_rcu (& led_cdev -> trig_list , & trig -> led_cdevs );
193
+ spin_unlock (& trig -> leddev_list_lock );
192
194
led_cdev -> trigger = trig ;
193
195
194
196
if (trig -> activate )
@@ -223,9 +225,10 @@ int led_trigger_set(struct led_classdev *led_cdev, struct led_trigger *trig)
223
225
trig -> deactivate (led_cdev );
224
226
err_activate :
225
227
226
- write_lock_irqsave (& led_cdev -> trigger -> leddev_list_lock , flags );
227
- list_del (& led_cdev -> trig_list );
228
- write_unlock_irqrestore (& led_cdev -> trigger -> leddev_list_lock , flags );
228
+ spin_lock (& led_cdev -> trigger -> leddev_list_lock );
229
+ list_del_rcu (& led_cdev -> trig_list );
230
+ spin_unlock (& led_cdev -> trigger -> leddev_list_lock );
231
+ synchronize_rcu ();
229
232
led_cdev -> trigger = NULL ;
230
233
led_cdev -> trigger_data = NULL ;
231
234
led_set_brightness (led_cdev , LED_OFF );
@@ -285,7 +288,7 @@ int led_trigger_register(struct led_trigger *trig)
285
288
struct led_classdev * led_cdev ;
286
289
struct led_trigger * _trig ;
287
290
288
- rwlock_init (& trig -> leddev_list_lock );
291
+ spin_lock_init (& trig -> leddev_list_lock );
289
292
INIT_LIST_HEAD (& trig -> led_cdevs );
290
293
291
294
down_write (& triggers_list_lock );
@@ -378,15 +381,14 @@ void led_trigger_event(struct led_trigger *trig,
378
381
enum led_brightness brightness )
379
382
{
380
383
struct led_classdev * led_cdev ;
381
- unsigned long flags ;
382
384
383
385
if (!trig )
384
386
return ;
385
387
386
- read_lock_irqsave ( & trig -> leddev_list_lock , flags );
387
- list_for_each_entry (led_cdev , & trig -> led_cdevs , trig_list )
388
+ rcu_read_lock ( );
389
+ list_for_each_entry_rcu (led_cdev , & trig -> led_cdevs , trig_list )
388
390
led_set_brightness (led_cdev , brightness );
389
- read_unlock_irqrestore ( & trig -> leddev_list_lock , flags );
391
+ rcu_read_unlock ( );
390
392
}
391
393
EXPORT_SYMBOL_GPL (led_trigger_event );
392
394
@@ -397,20 +399,19 @@ static void led_trigger_blink_setup(struct led_trigger *trig,
397
399
int invert )
398
400
{
399
401
struct led_classdev * led_cdev ;
400
- unsigned long flags ;
401
402
402
403
if (!trig )
403
404
return ;
404
405
405
- read_lock_irqsave ( & trig -> leddev_list_lock , flags );
406
- list_for_each_entry (led_cdev , & trig -> led_cdevs , trig_list ) {
406
+ rcu_read_lock ( );
407
+ list_for_each_entry_rcu (led_cdev , & trig -> led_cdevs , trig_list ) {
407
408
if (oneshot )
408
409
led_blink_set_oneshot (led_cdev , delay_on , delay_off ,
409
410
invert );
410
411
else
411
412
led_blink_set (led_cdev , delay_on , delay_off );
412
413
}
413
- read_unlock_irqrestore ( & trig -> leddev_list_lock , flags );
414
+ rcu_read_unlock ( );
414
415
}
415
416
416
417
void led_trigger_blink (struct led_trigger * trig ,
0 commit comments