leds: cpcap: Convert to global non-reentrant workqueue
authorColin Cross <ccross@android.com>
Wed, 12 Jan 2011 20:03:05 +0000 (12:03 -0800)
committerColin Cross <ccross@android.com>
Wed, 12 Jan 2011 20:06:26 +0000 (12:06 -0800)
schedule_work puts work items into a global workqueue that is
not single threaded.  If the work item is running when a
second schedule_work is called, the second one could be
immediately scheduled onto the second cpu while the first
one is running, breaking the synchronization expected in
cpcap_brightness_work.

Fix by converting schedule_work to queue_work(system_nrt_wq),
which puts the work on a global single-threaded workqueue.

Change-Id: Ieba89e0353b86f11350cb37552afbce5abe87088
Signed-off-by: Colin Cross <ccross@android.com>
drivers/leds/leds-ld-cpcap.c

index acd0fe4fe2271856d1a04e79bc0da5f7984164fe..1bcdf7faad5f926252bb730d2a7db7437e62e33e 100755 (executable)
@@ -48,7 +48,7 @@ static void cpcap_set(struct led_classdev *led_cdev,
                brightness = 255;
 
        cpcap_led_data->brightness = brightness;
-       schedule_work(&cpcap_led_data->brightness_work);
+       queue_work(system_nrt_wq, &cpcap_led_data->brightness_work);
 }
 EXPORT_SYMBOL(cpcap_set);
 
@@ -62,7 +62,7 @@ cpcap_led_set_blink(struct cpcap_led_data *info, unsigned long blink)
                        cpcap_uc_start(info->cpcap, CPCAP_MACRO_6);
                } else {
                        cpcap_uc_stop(info->cpcap, CPCAP_MACRO_6);
-                       schedule_work(&info->brightness_work);
+                       queue_work(system_nrt_wq, &info->brightness_work);
                }
        }
 }