diff options
51 files changed, 2376 insertions, 413 deletions
diff --git a/Documentation/leds/00-INDEX b/Documentation/leds/00-INDEX index 29f481df32c..5fefe374892 100644 --- a/Documentation/leds/00-INDEX +++ b/Documentation/leds/00-INDEX @@ -6,3 +6,5 @@ leds-lp5521.txt - notes on how to use the leds-lp5521 driver. leds-lp5523.txt - notes on how to use the leds-lp5523 driver. +leds-lm3556.txt + - notes on how to use the leds-lm3556 driver. diff --git a/Documentation/leds/leds-blinkm.txt b/Documentation/leds/leds-blinkm.txt new file mode 100644 index 00000000000..9dd92f4cf4e --- /dev/null +++ b/Documentation/leds/leds-blinkm.txt @@ -0,0 +1,80 @@ +The leds-blinkm driver supports the devices of the BlinkM family. + +They are RGB-LED modules driven by a (AT)tiny microcontroller and +communicate through I2C. The default address of these modules is +0x09 but this can be changed through a command. By this you could +dasy-chain up to 127 BlinkMs on an I2C bus. + +The device accepts RGB and HSB color values through separate commands. +Also you can store blinking sequences as "scripts" in +the controller and run them. Also fading is an option. + +The interface this driver provides is 2-fold: + +a) LED class interface for use with triggers +############################################ + +The registration follows the scheme: +blinkm-<i2c-bus-nr>-<i2c-device-nr>-<color> + +$ ls -h /sys/class/leds/blinkm-6-* +/sys/class/leds/blinkm-6-9-blue: +brightness device max_brightness power subsystem trigger uevent + +/sys/class/leds/blinkm-6-9-green: +brightness device max_brightness power subsystem trigger uevent + +/sys/class/leds/blinkm-6-9-red: +brightness device max_brightness power subsystem trigger uevent + +(same is /sys/bus/i2c/devices/6-0009/leds) + +We can control the colors separated into red, green and blue and +assign triggers on each color. + +E.g.: + +$ cat blinkm-6-9-blue/brightness +05 + +$ echo 200 > blinkm-6-9-blue/brightness +$ + +$ modprobe ledtrig-heartbeat +$ echo heartbeat > blinkm-6-9-green/trigger +$ + + +b) Sysfs group to control rgb, fade, hsb, scripts ... +##################################################### + +This extended interface is available as folder blinkm +in the sysfs folder of the I2C device. +E.g. below /sys/bus/i2c/devices/6-0009/blinkm + +$ ls -h /sys/bus/i2c/devices/6-0009/blinkm/ +blue green red test + +Currently supported is just setting red, green, blue +and a test sequence. + +E.g.: + +$ cat * +00 +00 +00 +#Write into test to start test sequence!# + +$ echo 1 > test +$ + +$ echo 255 > red +$ + + + +as of 6/2012 + +dl9pf <at> gmx <dot> de + diff --git a/Documentation/leds/leds-lm3556.txt b/Documentation/leds/leds-lm3556.txt new file mode 100644 index 00000000000..d9eb91b5191 --- /dev/null +++ b/Documentation/leds/leds-lm3556.txt @@ -0,0 +1,85 @@ +Kernel driver for lm3556 +======================== + +*Texas Instrument: + 1.5 A Synchronous Boost LED Flash Driver w/ High-Side Current Source +* Datasheet: http://www.national.com/ds/LM/LM3556.pdf + +Authors: + Daniel Jeong + Contact:Daniel Jeong(daniel.jeong-at-ti.com, gshark.jeong-at-gmail.com) + +Description +----------- +There are 3 functions in LM3556, Flash, Torch and Indicator. + +FLASH MODE +In Flash Mode, the LED current source(LED) provides 16 target current levels +from 93.75 mA to 1500 mA.The Flash currents are adjusted via the CURRENT +CONTROL REGISTER(0x09).Flash mode is activated by the ENABLE REGISTER(0x0A), +or by pulling the STROBE pin HIGH. +LM3556 Flash can be controlled through sys/class/leds/flash/brightness file +* if STROBE pin is enabled, below example control brightness only, and +ON / OFF will be controlled by STROBE pin. + +Flash Example: +OFF : #echo 0 > sys/class/leds/flash/brightness +93.75 mA: #echo 1 > sys/class/leds/flash/brightness +... ..... +1500 mA: #echo 16 > sys/class/leds/flash/brightness + +TORCH MODE +In Torch Mode, the current source(LED) is programmed via the CURRENT CONTROL +REGISTER(0x09).Torch Mode is activated by the ENABLE REGISTER(0x0A) or by the +hardware TORCH input. +LM3556 torch can be controlled through sys/class/leds/torch/brightness file. +* if TORCH pin is enabled, below example control brightness only, +and ON / OFF will be controlled by TORCH pin. + +Torch Example: +OFF : #echo 0 > sys/class/leds/torch/brightness +46.88 mA: #echo 1 > sys/class/leds/torch/brightness +... ..... +375 mA : #echo 8 > sys/class/leds/torch/brightness + +INDICATOR MODE +Indicator pattern can be set through sys/class/leds/indicator/pattern file, +and 4 patterns are pre-defined in indicator_pattern array. +According to N-lank, Pulse time and N Period values, different pattern wiill +be generated.If you want new patterns for your own device, change +indicator_pattern array with your own values and INDIC_PATTERN_SIZE. +Please refer datasheet for more detail about N-Blank, Pulse time and N Period. + +Indicator pattern example: +pattern 0: #echo 0 > sys/class/leds/indicator/pattern +.... +pattern 3: #echo 3 > sys/class/leds/indicator/pattern + +Indicator brightness can be controlled through +sys/class/leds/indicator/brightness file. + +Example: +OFF : #echo 0 > sys/class/leds/indicator/brightness +5.86 mA : #echo 1 > sys/class/leds/indicator/brightness +........ +46.875mA : #echo 8 > sys/class/leds/indicator/brightness + +Notes +----- +Driver expects it is registered using the i2c_board_info mechanism. +To register the chip at address 0x63 on specific adapter, set the platform data +according to include/linux/platform_data/leds-lm3556.h, set the i2c board info + +Example: + static struct i2c_board_info __initdata board_i2c_ch4[] = { + { + I2C_BOARD_INFO(LM3556_NAME, 0x63), + .platform_data = &lm3556_pdata, + }, + }; + +and register it in the platform init function + +Example: + board_register_i2c_bus(4, 400, + board_i2c_ch4, ARRAY_SIZE(board_i2c_ch4)); diff --git a/Documentation/leds/ledtrig-oneshot.txt b/Documentation/leds/ledtrig-oneshot.txt new file mode 100644 index 00000000000..07cd1fa41a3 --- /dev/null +++ b/Documentation/leds/ledtrig-oneshot.txt @@ -0,0 +1,59 @@ +One-shot LED Trigger +==================== + +This is a LED trigger useful for signaling the user of an event where there are +no clear trap points to put standard led-on and led-off settings. Using this +trigger, the application needs only to signal the trigger when an event has +happened, than the trigger turns the LED on and than keeps it off for a +specified amount of time. + +This trigger is meant to be usable both for sporadic and dense events. In the +first case, the trigger produces a clear single controlled blink for each +event, while in the latter it keeps blinking at constant rate, as to signal +that the events are arriving continuously. + +A one-shot LED only stays in a constant state when there are no events. An +additional "invert" property specifies if the LED has to stay off (normal) or +on (inverted) when not rearmed. + +The trigger can be activated from user space on led class devices as shown +below: + + echo oneshot > trigger + +This adds the following sysfs attributes to the LED: + + delay_on - specifies for how many milliseconds the LED has to stay at + LED_FULL brightness after it has been armed. + Default to 100 ms. + + delay_off - specifies for how many milliseconds the LED has to stay at + LED_OFF brightness after it has been armed. + Default to 100 ms. + + invert - reverse the blink logic. If set to 0 (default) blink on for delay_on + ms, then blink off for delay_off ms, leaving the LED normally off. If + set to 1, blink off for delay_off ms, then blink on for delay_on ms, + leaving the LED normally on. + Setting this value also immediately change the LED state. + + shot - write any non-empty string to signal an events, this starts a blink + sequence if not already running. + +Example use-case: network devices, initialization: + + echo oneshot > trigger # set trigger for this led + echo 33 > delay_on # blink at 1 / (33 + 33) Hz on continuous traffic + echo 33 > delay_off + +interface goes up: + + echo 1 > invert # set led as normally-on, turn the led on + +packet received/transmitted: + + echo 1 > shot # led starts blinking, ignored if already blinking + +interface goes down + + echo 0 > invert # set led as normally-off, turn the led off diff --git a/MAINTAINERS b/MAINTAINERS index 8f363b00522..3bc49687b65 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1529,6 +1529,11 @@ W: http://blackfin.uclinux.org/ S: Supported F: drivers/i2c/busses/i2c-bfin-twi.c +BLINKM RGB LED DRIVER +M: Jan-Simon Moeller <jansimon.moeller@gmx.de> +S: Maintained +F: drivers/leds/leds-blinkm.c + BLOCK LAYER M: Jens Axboe <axboe@kernel.dk> T: git git://git.kernel.org/pub/scm/linux/kernel/git/axboe/linux-block.git diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig index 12b2b55c519..c96bbaadeeb 100644 --- a/drivers/leds/Kconfig +++ b/drivers/leds/Kconfig @@ -200,6 +200,13 @@ config LEDS_LP5523 Driver provides direct control via LED class and interface for programming the engines. +config LEDS_LP8788 + tristate "LED support for the TI LP8788 PMIC" + depends on LEDS_CLASS + depends on MFD_LP8788 + help + This option enables support for the Keyboard LEDs on the LP8788 PMIC. + config LEDS_CLEVO_MAIL tristate "Mail LED on Clevo notebook" depends on LEDS_CLASS @@ -415,6 +422,14 @@ config LEDS_MAX8997 This option enables support for on-chip LED drivers on MAXIM MAX8997 PMIC. +config LEDS_LM3556 + tristate "LED support for LM3556 Chip" + depends on LEDS_CLASS && I2C + select REGMAP_I2C + help + This option enables support for LEDs connected to LM3556. + LM3556 includes Torch, Flash and Indicator functions. + config LEDS_OT200 tristate "LED support for the Bachmann OT200" depends on LEDS_CLASS && HAS_IOMEM @@ -422,6 +437,14 @@ config LEDS_OT200 This option enables support for the LEDs on the Bachmann OT200. Say Y to enable LEDs on the Bachmann OT200. +config LEDS_BLINKM + tristate "LED support for the BlinkM I2C RGB LED" + depends on LEDS_CLASS + depends on I2C + help + This option enables support for the BlinkM RGB LED connected + through I2C. Say Y to enable support for the BlinkM LED. + config LEDS_TRIGGERS bool "LED Trigger support" depends on LEDS_CLASS @@ -443,6 +466,20 @@ config LEDS_TRIGGER_TIMER If unsure, say Y. +config LEDS_TRIGGER_ONESHOT + tristate "LED One-shot Trigger" + depends on LEDS_TRIGGERS + help + This allows LEDs to blink in one-shot pulses with parameters + controlled via sysfs. It's useful to notify the user on + sporadic events, when there are no clear begin and end trap points, + or on dense events, where this blinks the LED at constant rate if + rearmed continuously. + + It also shows how to use the led_blink_set_oneshot() function. + + If unsure, say Y. + config LEDS_TRIGGER_IDE_DISK bool "LED IDE Disk Trigger" depends on IDE_GD_ATA @@ -497,7 +534,7 @@ config LEDS_TRIGGER_TRANSIENT depends on LEDS_TRIGGERS help This allows one time activation of a transient state on - GPIO/PWM based hadrware. + GPIO/PWM based hardware. If unsure, say Y. endif # NEW_LEDS diff --git a/drivers/leds/Makefile b/drivers/leds/Makefile index f8958cd6cf6..a4429a9217b 100644 --- a/drivers/leds/Makefile +++ b/drivers/leds/Makefile @@ -24,6 +24,7 @@ obj-$(CONFIG_LEDS_GPIO) += leds-gpio.o obj-$(CONFIG_LEDS_LP3944) += leds-lp3944.o obj-$(CONFIG_LEDS_LP5521) += leds-lp5521.o obj-$(CONFIG_LEDS_LP5523) += leds-lp5523.o +obj-$(CONFIG_LEDS_LP8788) += leds-lp8788.o obj-$(CONFIG_LEDS_TCA6507) += leds-tca6507.o obj-$(CONFIG_LEDS_CLEVO_MAIL) += leds-clevo-mail.o obj-$(CONFIG_LEDS_HP6XX) += leds-hp6xx.o @@ -47,12 +48,15 @@ obj-$(CONFIG_LEDS_NETXBIG) += leds-netxbig.o obj-$(CONFIG_LEDS_ASIC3) += leds-asic3.o obj-$(CONFIG_LEDS_RENESAS_TPU) += leds-renesas-tpu.o obj-$(CONFIG_LEDS_MAX8997) += leds-max8997.o +obj-$(CONFIG_LEDS_LM3556) += leds-lm3556.o +obj-$(CONFIG_LEDS_BLINKM) += leds-blinkm.o # LED SPI Drivers obj-$(CONFIG_LEDS_DAC124S085) += leds-dac124s085.o # LED Triggers obj-$(CONFIG_LEDS_TRIGGER_TIMER) += ledtrig-timer.o +obj-$(CONFIG_LEDS_TRIGGER_ONESHOT) += ledtrig-oneshot.o obj-$(CONFIG_LEDS_TRIGGER_IDE_DISK) += ledtrig-ide-disk.o obj-$(CONFIG_LEDS_TRIGGER_HEARTBEAT) += ledtrig-heartbeat.o obj-$(CONFIG_LEDS_TRIGGER_BACKLIGHT) += ledtrig-backlight.o diff --git a/drivers/leds/led-class.c b/drivers/leds/led-class.c index e663e6f413e..c599095bc00 100644 --- a/drivers/leds/led-class.c +++ b/drivers/leds/led-class.c @@ -53,7 +53,7 @@ static ssize_t led_brightness_store(struct device *dev, if (state == LED_OFF) led_trigger_remove(led_cdev); - led_set_brightness(led_cdev, state); + __led_set_brightness(led_cdev, state); return size; } @@ -82,7 +82,12 @@ static void led_timer_function(unsigned long data) unsigned long delay; if (!led_cdev->blink_delay_on || !led_cdev->blink_delay_off) { - led_set_brightness(led_cdev, LED_OFF); + __led_set_brightness(led_cdev, LED_OFF); + return; + } + + if (led_cdev->flags & LED_BLINK_ONESHOT_STOP) { + led_cdev->flags &= ~LED_BLINK_ONESHOT_STOP; return; } @@ -100,7 +105,21 @@ static void led_timer_function(unsigned long data) delay = led_cdev->blink_delay_off; } - led_set_brightness(led_cdev, brightness); + __led_set_brightness(led_cdev, brightness); + + /* Return in next iteration if led is in one-shot mode and we are in + * the final blink state so that the led is toggled each delay_on + + * delay_off milliseconds in worst case. + */ + if (led_cdev->flags & LED_BLINK_ONESHOT) { + if (led_cdev->flags & LED_BLINK_INVERT) { + if (brightness) + led_cdev->flags |= LED_BLINK_ONESHOT_STOP; + } else { + if (!brightness) + led_cdev->flags |= LED_BLINK_ONESHOT_STOP; + } + } mod_timer(&led_cdev->blink_timer, jiffies + msecs_to_jiffies(delay)); } @@ -203,7 +222,7 @@ void led_classdev_unregister(struct led_classdev *led_cdev) #endif /* Stop blinking */ - led_brightness_set(led_cdev, LED_OFF); + led_set_brightness(led_cdev, LED_OFF); device_unregister(led_cdev->dev); diff --git a/drivers/leds/led-core.c b/drivers/leds/led-core.c index d65353d8d3f..2ab05af3de3 100644 --- a/drivers/leds/led-core.c +++ b/drivers/leds/led-core.c @@ -24,14 +24,6 @@ EXPORT_SYMBOL_GPL(leds_list_lock); LIST_HEAD(leds_list); EXPORT_SYMBOL_GPL(leds_list); -static void led_stop_software_blink(struct led_classdev *led_cdev) -{ - /* deactivate previous settings */ - del_timer_sync(&led_cdev->blink_timer); - led_cdev->blink_delay_on = 0; - led_cdev->blink_delay_off = 0; -} - static void led_set_software_blink(struct led_classdev *led_cdev, unsigned long delay_on, unsigned long delay_off) @@ -53,7 +45,7 @@ static void led_set_software_blink(struct led_classdev *led_cdev, /* never off - just set to brightness */ if (!delay_off) { - led_set_brightness(led_cdev, led_cdev->blink_brightness); + __led_set_brightness(led_cdev, led_cdev->blink_brightness); return; } @@ -61,13 +53,12 @@ static void led_set_software_blink(struct led_classdev *led_cdev, } -void led_blink_set(struct led_classdev *led_cdev, - unsigned long *delay_on, - unsigned long *delay_off) +static void led_blink_setup(struct led_classdev *led_cdev, + unsigned long *delay_on, + unsigned long *delay_off) { - del_timer_sync(&led_cdev->blink_timer); - - if (led_cdev->blink_set && + if (!(led_cdev->flags & LED_BLINK_ONESHOT) && + led_cdev->blink_set && !led_cdev->blink_set(led_cdev, delay_on, delay_off)) return; @@ -77,12 +68,49 @@ void led_blink_set(struct led_classdev *led_cdev, led_set_software_blink(led_cdev, *delay_on, *delay_off); } + +void led_blink_set(struct led_classdev *led_cdev, + unsigned long *delay_on, + unsigned long *delay_off) +{ + del_timer_sync(&led_cdev->blink_timer); + + led_cdev->flags &= ~LED_BLINK_ONESHOT; + led_cdev->flags &= ~LED_BLINK_ONESHOT_STOP; + + led_blink_setup(led_cdev, delay_on, delay_off); +} EXPORT_SYMBOL(led_blink_set); -void led_brightness_set(struct led_classdev *led_cdev, +void led_blink_set_oneshot(struct led_classdev *led_cdev, + unsigned long *delay_on, + unsigned long *delay_off, + int invert) +{ + if ((led_cdev->flags & LED_BLINK_ONESHOT) && + timer_pending(&led_cdev->blink_timer)) + return; + + led_cdev->flags |= LED_BLINK_ONESHOT; + led_cdev->flags &= ~LED_BLINK_ONESHOT_STOP; + + if (invert) + led_cdev->flags |= LED_BLINK_INVERT; + else + led_cdev->flags &= ~LED_BLINK_INVERT; + + led_blink_setup(led_cdev, delay_on, delay_off); +} +EXPORT_SYMBOL(led_blink_set_oneshot); + +void led_set_brightness(struct led_classdev *led_cdev, enum led_brightness brightness) { - led_stop_software_blink(led_cdev); - led_cdev->brightness_set(led_cdev, brightness); + /* stop and clear soft-blink timer */ + del_timer_sync(&led_cdev->blink_timer); + led_cdev->blink_delay_on = 0; + led_cdev->blink_delay_off = 0; + + __led_set_brightness(led_cdev, brightness); } -EXPORT_SYMBOL(led_brightness_set); +EXPORT_SYMBOL(led_set_brightness); diff --git a/drivers/leds/led-triggers.c b/drivers/leds/led-triggers.c index 46b4c766335..6157cbbf411 100644 --- a/drivers/leds/led-triggers.c +++ b/drivers/leds/led-triggers.c @@ -99,7 +99,7 @@ ssize_t led_trigger_show(struct device *dev, struct device_attribute *attr, EXPORT_SYMBOL_GPL(led_trigger_show); /* Caller must ensure led_cdev->trigger_lock held */ -void led_trigger_set(struct led_classdev *led_cdev, struct led_trigger *trigger) +void led_trigger_set(struct led_classdev *led_cdev, struct led_trigger *trig) { unsigned long flags; @@ -112,15 +112,15 @@ void led_trigger_set(struct led_classdev *led_cdev, struct led_trigger *trigger) if (led_cdev->trigger->deactivate) led_cdev->trigger->deactivate(led_cdev); led_cdev->trigger = NULL; - led_brightness_set(led_cdev, LED_OFF); + led_set_brightness(led_cdev, LED_OFF); } - if (trigger) { - write_lock_irqsave(&trigger->leddev_list_lock, flags); - list_add_tail(&led_cdev->trig_list, &trigger->led_cdevs); - write_unlock_irqrestore(&trigger->leddev_list_lock, flags); - led_cdev->trigger = trigger; - if (trigger->activate) - trigger->activate(led_cdev); + if (trig) { + write_lock_irqsave(&trig->leddev_list_lock, flags); + list_add_tail(&led_cdev->trig_list, &trig->led_cdevs); + write_unlock_irqrestore(&trig->leddev_list_lock, flags); + led_cdev->trigger = trig; + if (trig->activate) + trig->activate(led_cdev); } } EXPORT_SYMBOL_GPL(led_trigger_set); @@ -153,24 +153,24 @@ EXPORT_SYMBOL_GPL(led_trigger_set_default); /* LED Trigger Interface */ -int led_trigger_register(struct led_trigger *trigger) +int led_trigger_register(struct led_trigger *trig) { struct led_classdev *led_cdev; - struct led_trigger *trig; + struct led_trigger *_trig; - rwlock_init(&trigger->leddev_list_lock); - INIT_LIST_HEAD(&trigger->led_cdevs); + rwlock_init(&trig->leddev_list_lock); + INIT_LIST_HEAD(&trig->led_cdevs); down_write(&triggers_list_lock); /* Make sure the trigger's name isn't already in use */ - list_for_each_entry(trig, &trigger_list, next_trig) { - if (!strcmp(trig->name, trigger->name)) { + list_for_each_entry(_trig, &trigger_list, next_trig) { + if (!strcmp(_trig->name, trig->name)) { up_write(&triggers_list_lock); return -EEXIST; } } /* Add to the list of led triggers */ - list_add_tail(&trigger->next_trig, &trigger_list); + list_add_tail(&trig->next_trig, &trigger_list); up_write(&triggers_list_lock); /* Register with any LEDs that have this as a default trigger */ @@ -178,8 +178,8 @@ int led_trigger_register(struct led_trigger *trigger) list_for_each_entry(led_cdev, &leds_list, node) { down_write(&led_cdev->trigger_lock); if (!led_cdev->trigger && led_cdev->default_trigger && - !strcmp(led_cdev->default_trigger, trigger->name)) - led_trigger_set(led_cdev, trigger); + !strcmp(led_cdev->default_trigger, trig->name)) + led_trigger_set(led_cdev, trig); up_write(&led_cdev->trigger_lock); } up_read(&leds_list_lock); @@ -188,20 +188,20 @@ int led_trigger_register(struct led_trigger *trigger) } EXPORT_SYMBOL_GPL(led_trigger_register); -void led_trigger_unregister(struct led_trigger *trigger) +void led_trigger_unregister(struct led_trigger *trig) { struct led_classdev *led_cdev; /* Remove from the list of led triggers */ down_write(&triggers_list_lock); - list_del(&trigger->next_trig); + list_del(&trig->next_trig); up_write(&triggers_list_lock); /* Remove anyone actively using this trigger */ down_read(&leds_list_lock); list_for_each_entry(led_cdev, &leds_list, node) { down_write(&led_cdev->trigger_lock); - if (led_cdev->trigger == trigger) + if (led_cdev->trigger == trig) led_trigger_set(led_cdev, NULL); up_write(&led_cdev->trigger_lock); } @@ -211,58 +211,80 @@ EXPORT_SYMBOL_GPL(led_trigger_unregister); /* Simple LED Tigger Interface */ -void led_trigger_event(struct led_trigger *trigger, +void led_trigger_event(struct led_trigger *trig, enum led_brightness brightness) { struct list_head *entry; - if (!trigger) + if (!trig) return; - read_lock(&trigger->leddev_list_lock); - list_for_each(entry, &trigger->led_cdevs) { + read_lock(&trig->leddev_list_lock); + list_for_each(entry, &trig->led_cdevs) { struct led_classdev *led_cdev; led_cdev = list_entry(entry, struct led_classdev, trig_list); led_set_brightness(led_cdev, brightness); } - read_unlock(&trigger->leddev_list_lock); + read_unlock(&trig->leddev_list_lock); } EXPORT_SYMBOL_GPL(led_trigger_event); -void led_trigger_blink(struct led_trigger *trigger, - unsigned long *delay_on, - unsigned long *delay_off) +static void led_trigger_blink_setup(struct led_trigger *trig, + unsigned long *delay_on, + unsigned long *delay_off, + int oneshot, + int invert) { struct list_head *entry; - if (!trigger) + if (!trig) return; - read_lock(&trigger->leddev_list_lock); - list_for_each(entry, &trigger->led_cdevs) { + read_lock(&trig->leddev_list_lock); + list_for_each(entry, &trig->led_cdevs) { struct led_classdev *led_cdev; led_cdev = list_entry(entry, struct led_classdev |