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/panic_notifier.h>
12 #include <linux/leds.h>
15 static struct led_trigger
*trigger
;
18 * This is called in a special context by the atomic panic
19 * notifier. This means the trigger can be changed without
20 * worrying about locking.
22 static void led_trigger_set_panic(struct led_classdev
*led_cdev
)
24 if (led_cdev
->trigger
)
25 list_del(&led_cdev
->trig_list
);
26 list_add_tail(&led_cdev
->trig_list
, &trigger
->led_cdevs
);
28 /* Avoid the delayed blink path */
29 led_cdev
->blink_delay_on
= 0;
30 led_cdev
->blink_delay_off
= 0;
32 led_cdev
->trigger
= trigger
;
35 static int led_trigger_panic_notifier(struct notifier_block
*nb
,
36 unsigned long code
, void *unused
)
38 struct led_classdev
*led_cdev
;
40 list_for_each_entry(led_cdev
, &leds_list
, node
)
41 if (led_cdev
->flags
& LED_PANIC_INDICATOR
)
42 led_trigger_set_panic(led_cdev
);
46 static struct notifier_block led_trigger_panic_nb
= {
47 .notifier_call
= led_trigger_panic_notifier
,
50 static long led_panic_blink(int state
)
52 led_trigger_event(trigger
, state
? LED_FULL
: LED_OFF
);
56 static int __init
ledtrig_panic_init(void)
58 led_trigger_register_simple("panic", &trigger
);
62 atomic_notifier_chain_register(&panic_notifier_list
,
63 &led_trigger_panic_nb
);
65 panic_blink
= led_panic_blink
;
68 device_initcall(ledtrig_panic_init
);