Commit | Line | Data |
---|---|---|
d2912cb1 | 1 | // SPDX-License-Identifier: GPL-2.0-only |
916fe619 EG |
2 | /* |
3 | * Kernel Panic LED Trigger | |
4 | * | |
5 | * Copyright 2016 Ezequiel Garcia <ezequiel@vanguardiasur.com.ar> | |
916fe619 EG |
6 | */ |
7 | ||
8 | #include <linux/kernel.h> | |
9 | #include <linux/init.h> | |
ba93cdce | 10 | #include <linux/notifier.h> |
f39650de | 11 | #include <linux/panic_notifier.h> |
916fe619 | 12 | #include <linux/leds.h> |
ba93cdce | 13 | #include "../leds.h" |
916fe619 EG |
14 | |
15 | static struct led_trigger *trigger; | |
16 | ||
ba93cdce EG |
17 | /* |
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. | |
21 | */ | |
22 | static void led_trigger_set_panic(struct led_classdev *led_cdev) | |
23 | { | |
7eef64da HK |
24 | if (led_cdev->trigger) |
25 | list_del(&led_cdev->trig_list); | |
26 | list_add_tail(&led_cdev->trig_list, &trigger->led_cdevs); | |
ba93cdce | 27 | |
7eef64da HK |
28 | /* Avoid the delayed blink path */ |
29 | led_cdev->blink_delay_on = 0; | |
30 | led_cdev->blink_delay_off = 0; | |
ba93cdce | 31 | |
7eef64da | 32 | led_cdev->trigger = trigger; |
ba93cdce EG |
33 | } |
34 | ||
35 | static int led_trigger_panic_notifier(struct notifier_block *nb, | |
36 | unsigned long code, void *unused) | |
37 | { | |
38 | struct led_classdev *led_cdev; | |
39 | ||
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); | |
43 | return NOTIFY_DONE; | |
44 | } | |
45 | ||
46 | static struct notifier_block led_trigger_panic_nb = { | |
47 | .notifier_call = led_trigger_panic_notifier, | |
48 | }; | |
49 | ||
916fe619 EG |
50 | static long led_panic_blink(int state) |
51 | { | |
52 | led_trigger_event(trigger, state ? LED_FULL : LED_OFF); | |
53 | return 0; | |
54 | } | |
55 | ||
56 | static int __init ledtrig_panic_init(void) | |
57 | { | |
afacb218 HK |
58 | led_trigger_register_simple("panic", &trigger); |
59 | if (!trigger) | |
60 | return -ENOMEM; | |
61 | ||
ba93cdce EG |
62 | atomic_notifier_chain_register(&panic_notifier_list, |
63 | &led_trigger_panic_nb); | |
64 | ||
916fe619 EG |
65 | panic_blink = led_panic_blink; |
66 | return 0; | |
67 | } | |
68 | device_initcall(ledtrig_panic_init); |