mirror of https://github.com/Qortal/Brooklyn
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
73 lines
1.7 KiB
73 lines
1.7 KiB
// SPDX-License-Identifier: GPL-2.0-only |
|
/* |
|
* Kernel Panic LED Trigger |
|
* |
|
* Copyright 2016 Ezequiel Garcia <[email protected]> |
|
*/ |
|
|
|
#include <linux/kernel.h> |
|
#include <linux/init.h> |
|
#include <linux/notifier.h> |
|
#include <linux/leds.h> |
|
#include "../leds.h" |
|
|
|
static struct led_trigger *trigger; |
|
|
|
/* |
|
* This is called in a special context by the atomic panic |
|
* notifier. This means the trigger can be changed without |
|
* worrying about locking. |
|
*/ |
|
static void led_trigger_set_panic(struct led_classdev *led_cdev) |
|
{ |
|
struct led_trigger *trig; |
|
|
|
list_for_each_entry(trig, &trigger_list, next_trig) { |
|
if (strcmp("panic", trig->name)) |
|
continue; |
|
if (led_cdev->trigger) |
|
list_del(&led_cdev->trig_list); |
|
list_add_tail(&led_cdev->trig_list, &trig->led_cdevs); |
|
|
|
/* Avoid the delayed blink path */ |
|
led_cdev->blink_delay_on = 0; |
|
led_cdev->blink_delay_off = 0; |
|
|
|
led_cdev->trigger = trig; |
|
if (trig->activate) |
|
trig->activate(led_cdev); |
|
break; |
|
} |
|
} |
|
|
|
static int led_trigger_panic_notifier(struct notifier_block *nb, |
|
unsigned long code, void *unused) |
|
{ |
|
struct led_classdev *led_cdev; |
|
|
|
list_for_each_entry(led_cdev, &leds_list, node) |
|
if (led_cdev->flags & LED_PANIC_INDICATOR) |
|
led_trigger_set_panic(led_cdev); |
|
return NOTIFY_DONE; |
|
} |
|
|
|
static struct notifier_block led_trigger_panic_nb = { |
|
.notifier_call = led_trigger_panic_notifier, |
|
}; |
|
|
|
static long led_panic_blink(int state) |
|
{ |
|
led_trigger_event(trigger, state ? LED_FULL : LED_OFF); |
|
return 0; |
|
} |
|
|
|
static int __init ledtrig_panic_init(void) |
|
{ |
|
atomic_notifier_chain_register(&panic_notifier_list, |
|
&led_trigger_panic_nb); |
|
|
|
led_trigger_register_simple("panic", &trigger); |
|
panic_blink = led_panic_blink; |
|
return 0; |
|
} |
|
device_initcall(ledtrig_panic_init);
|
|
|