1 // SPDX-License-Identifier: GPL-2.0-only
3 * Kernel Panic LED Trigger
5 * Copyright 2016 Ezequiel Garcia <ezequiel@vanguardiasur.com.ar>
8 #include <linux/kernel.h>
9 #include <linux/init.h>
10 #include <linux/notifier.h>
11 #include <linux/leds.h>
14 static struct led_trigger
*trigger
;
17 * This is called in a special context by the atomic panic
18 * notifier. This means the trigger can be changed without
19 * worrying about locking.
21 static void led_trigger_set_panic(struct led_classdev
*led_cdev
)
23 struct led_trigger
*trig
;
25 list_for_each_entry(trig
, &trigger_list
, next_trig
) {
26 if (strcmp("panic", trig
->name
))
28 if (led_cdev
->trigger
)
29 list_del(&led_cdev
->trig_list
);
30 list_add_tail(&led_cdev
->trig_list
, &trig
->led_cdevs
);
32 /* Avoid the delayed blink path */
33 led_cdev
->blink_delay_on
= 0;
34 led_cdev
->blink_delay_off
= 0;
36 led_cdev
->trigger
= trig
;
38 trig
->activate(led_cdev
);
43 static int led_trigger_panic_notifier(struct notifier_block
*nb
,
44 unsigned long code
, void *unused
)
46 struct led_classdev
*led_cdev
;
48 list_for_each_entry(led_cdev
, &leds_list
, node
)
49 if (led_cdev
->flags
& LED_PANIC_INDICATOR
)
50 led_trigger_set_panic(led_cdev
);
54 static struct notifier_block led_trigger_panic_nb
= {
55 .notifier_call
= led_trigger_panic_notifier
,
58 static long led_panic_blink(int state
)
60 led_trigger_event(trigger
, state
? LED_FULL
: LED_OFF
);
64 static int __init
ledtrig_panic_init(void)
66 atomic_notifier_chain_register(&panic_notifier_list
,
67 &led_trigger_panic_nb
);
69 led_trigger_register_simple("panic", &trigger
);
70 panic_blink
= led_panic_blink
;
73 device_initcall(ledtrig_panic_init
);