drivers/leds/led-core.c
Source file repositories/reference/linux-study-clean/drivers/leds/led-core.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/leds/led-core.c- Extension
.c- Size
- 17836 bytes
- Lines
- 626
- Domain
- Driver Families
- Bucket
- drivers/leds
- Inferred role
- Driver Families: exported/initcall integration point
- Status
- integration implementation candidate
Why This File Exists
Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Exports symbols or registers init work; inspect boot/module ordering and who consumes the exported contract.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/kernel.hlinux/led-class-multicolor.hlinux/leds.hlinux/list.hlinux/module.hlinux/mutex.hlinux/of.hlinux/property.hlinux/rwsem.hlinux/slab.huapi/linux/uleds.hleds.h
Detected Declarations
function __led_set_brightnessfunction __led_set_brightness_blockingfunction led_timer_functionfunction set_brightness_delayed_set_brightnessfunction set_brightness_delayedfunction led_set_brightnessfunction led_set_software_blinkfunction led_blink_setupfunction led_init_corefunction led_blink_setfunction led_blink_set_oneshotfunction led_blink_set_nosleepfunction led_stop_software_blinkfunction led_set_brightnessfunction led_set_brightness_nopmfunction led_set_brightness_nosleepfunction led_set_brightness_syncfunction led_mc_set_brightnessfunction led_update_brightnessfunction led_sysfs_disablefunction led_sysfs_enablefunction led_parse_fwnode_propsfunction led_compose_namefunction led_init_default_state_getexport leds_list_lockexport leds_listexport led_init_coreexport led_blink_setexport led_blink_set_oneshotexport led_blink_set_nosleepexport led_stop_software_blinkexport led_set_brightnessexport led_set_brightness_nopmexport led_set_brightness_nosleepexport led_set_brightness_syncexport led_mc_set_brightnessexport led_update_brightnessexport led_get_default_patternexport led_sysfs_disableexport led_sysfs_enableexport led_compose_nameexport led_get_color_nameexport led_init_default_state_get
Annotated Snippet
if (test_bit(LED_BLINK_INVERT, &led_cdev->work_flags)) {
if (brightness)
set_bit(LED_BLINK_ONESHOT_STOP,
&led_cdev->work_flags);
} else {
if (!brightness)
set_bit(LED_BLINK_ONESHOT_STOP,
&led_cdev->work_flags);
}
}
mod_timer(&led_cdev->blink_timer, jiffies + msecs_to_jiffies(delay));
}
static void set_brightness_delayed_set_brightness(struct led_classdev *led_cdev,
unsigned int value)
{
int ret;
ret = __led_set_brightness(led_cdev, value);
if (ret == -ENOTSUPP) {
ret = __led_set_brightness_blocking(led_cdev, value);
if (ret == -ENOTSUPP)
/* No back-end support to set a fixed brightness value */
return;
}
/* LED HW might have been unplugged, therefore don't warn */
if (ret == -ENODEV && led_cdev->flags & LED_UNREGISTERING &&
led_cdev->flags & LED_HW_PLUGGABLE)
return;
if (ret < 0)
dev_err(led_cdev->dev,
"Setting an LED's brightness failed (%d)\n", ret);
}
static void set_brightness_delayed(struct work_struct *ws)
{
struct led_classdev *led_cdev =
container_of(ws, struct led_classdev, set_brightness_work);
if (test_and_clear_bit(LED_BLINK_DISABLE, &led_cdev->work_flags)) {
led_stop_software_blink(led_cdev);
set_bit(LED_SET_BRIGHTNESS_OFF, &led_cdev->work_flags);
}
/*
* Triggers may call led_set_brightness(LED_OFF),
* led_set_brightness(LED_FULL) in quick succession to disable blinking
* and turn the LED on. Both actions may have been scheduled to run
* before this work item runs once. To make sure this works properly
* handle LED_SET_BRIGHTNESS_OFF first.
*/
if (test_and_clear_bit(LED_SET_BRIGHTNESS_OFF, &led_cdev->work_flags)) {
set_brightness_delayed_set_brightness(led_cdev, LED_OFF);
/*
* The consecutives led_set_brightness(LED_OFF),
* led_set_brightness(LED_FULL) could have been executed out of
* order (LED_FULL first), if the work_flags has been set
* between LED_SET_BRIGHTNESS_OFF and LED_SET_BRIGHTNESS of this
* work. To avoid ending with the LED turned off, turn the LED
* on again.
*/
if (led_cdev->delayed_set_value != LED_OFF)
set_bit(LED_SET_BRIGHTNESS, &led_cdev->work_flags);
}
if (test_and_clear_bit(LED_SET_BRIGHTNESS, &led_cdev->work_flags))
set_brightness_delayed_set_brightness(led_cdev, led_cdev->delayed_set_value);
if (test_and_clear_bit(LED_SET_BLINK, &led_cdev->work_flags)) {
unsigned long delay_on = led_cdev->delayed_delay_on;
unsigned long delay_off = led_cdev->delayed_delay_off;
led_blink_set(led_cdev, &delay_on, &delay_off);
}
}
static void led_set_software_blink(struct led_classdev *led_cdev,
unsigned long delay_on,
unsigned long delay_off)
{
int current_brightness;
current_brightness = led_get_brightness(led_cdev);
if (current_brightness)
led_cdev->blink_brightness = current_brightness;
if (!led_cdev->blink_brightness)
led_cdev->blink_brightness = led_cdev->max_brightness;
Annotation
- Immediate include surface: `linux/kernel.h`, `linux/led-class-multicolor.h`, `linux/leds.h`, `linux/list.h`, `linux/module.h`, `linux/mutex.h`, `linux/of.h`, `linux/property.h`.
- Detected declarations: `function __led_set_brightness`, `function __led_set_brightness_blocking`, `function led_timer_function`, `function set_brightness_delayed_set_brightness`, `function set_brightness_delayed`, `function led_set_brightness`, `function led_set_software_blink`, `function led_blink_setup`, `function led_init_core`, `function led_blink_set`.
- Atlas domain: Driver Families / drivers/leds.
- Implementation status: integration implementation candidate.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.