From: Grazvydas Ignotas Date: Sat, 19 Mar 2016 01:28:14 +0000 (+0200) Subject: leds-twl4030-pwm: fix another race X-Git-Tag: sz_175~46 X-Git-Url: https://git.openpandora.org/cgi-bin/gitweb.cgi?p=pandora-kernel.git;a=commitdiff_plain;h=01f551de7fa4a384027f3f8d9119c45ca9d0fd1a leds-twl4030-pwm: fix another race This is a race between twl4030_pwmled_work() reading led->new_brightness vs twl4030_pwmled_brightness() writing to it. Probably needs a proper lock, but we want twl4030_pwmled_brightness() to not block and assume work items come from single queue and should not race each other. --- diff --git a/drivers/leds/leds-twl4030-pwm.c b/drivers/leds/leds-twl4030-pwm.c index f6d656ed414d..66f431d46d03 100644 --- a/drivers/leds/leds-twl4030-pwm.c +++ b/drivers/leds/leds-twl4030-pwm.c @@ -99,18 +99,20 @@ static void twl4030_enable_pwm01(enum twl4030_led led, bool enable) static void twl4030_pwmled_work(struct work_struct *work) { + enum led_brightness new_brightness; struct twl4030_pwmled *led; int val; led = container_of(work, struct twl4030_pwmled, work); - if (led->new_brightness == LED_OFF) { + new_brightness = ACCESS_ONCE(led->new_brightness); + if (new_brightness == LED_OFF) { if (led->old_brightness != LED_OFF) led->enable(led->id, 0); goto out; } - val = led->new_brightness * 0x7f / LED_FULL; + val = new_brightness * 0x7f / LED_FULL; /* avoid 0: on = off = 0 means full brightness */ if (val == 0) val = 1; @@ -121,7 +123,7 @@ static void twl4030_pwmled_work(struct work_struct *work) led->enable(led->id, 1); out: - led->old_brightness = led->new_brightness; + led->old_brightness = new_brightness; } static void twl4030_pwmled_brightness(struct led_classdev *cdev,