led: core: Use atomic bit-field for the blink-flags

All the LED_BLINK* flags are accessed read-modify-write from e.g.
led_set_brightness and led_blink_set_oneshot while both
set_brightness_work and the blink_timer may be running.

If these race then the modify step done by one of them may be lost,
switch the LED_BLINK* flags to a new atomic work_flags bit-field
to avoid this race.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Jacek Anaszewski <j.anaszewski@samsung.com>
This commit is contained in:
Hans de Goede 2016-11-08 14:38:46 +01:00 committed by Jacek Anaszewski
parent 8338eab50f
commit a9c6ce57ec
3 changed files with 42 additions and 35 deletions

View file

@ -42,16 +42,20 @@ struct led_classdev {
#define LED_UNREGISTERING (1 << 1)
/* Upper 16 bits reflect control information */
#define LED_CORE_SUSPENDRESUME (1 << 16)
#define LED_BLINK_SW (1 << 17)
#define LED_BLINK_ONESHOT (1 << 18)
#define LED_BLINK_ONESHOT_STOP (1 << 19)
#define LED_BLINK_INVERT (1 << 20)
#define LED_BLINK_BRIGHTNESS_CHANGE (1 << 21)
#define LED_BLINK_DISABLE (1 << 22)
#define LED_SYSFS_DISABLE (1 << 23)
#define LED_DEV_CAP_FLASH (1 << 24)
#define LED_HW_PLUGGABLE (1 << 25)
#define LED_PANIC_INDICATOR (1 << 26)
#define LED_SYSFS_DISABLE (1 << 17)
#define LED_DEV_CAP_FLASH (1 << 18)
#define LED_HW_PLUGGABLE (1 << 19)
#define LED_PANIC_INDICATOR (1 << 20)
/* set_brightness_work / blink_timer flags, atomic, private. */
unsigned long work_flags;
#define LED_BLINK_SW 0
#define LED_BLINK_ONESHOT 1
#define LED_BLINK_ONESHOT_STOP 2
#define LED_BLINK_INVERT 3
#define LED_BLINK_BRIGHTNESS_CHANGE 4
#define LED_BLINK_DISABLE 5
/* Set LED brightness level
* Must not sleep. Use brightness_set_blocking for drivers