|
@@ -31,12 +31,16 @@
|
|
|
#define MAX_NAME_LEN 8
|
|
|
|
|
|
struct led_trigger_cpu {
|
|
|
+ bool is_active;
|
|
|
char name[MAX_NAME_LEN];
|
|
|
struct led_trigger *_trig;
|
|
|
};
|
|
|
|
|
|
static DEFINE_PER_CPU(struct led_trigger_cpu, cpu_trig);
|
|
|
|
|
|
+static struct led_trigger *trig_cpu_all;
|
|
|
+static atomic_t num_active_cpus = ATOMIC_INIT(0);
|
|
|
+
|
|
|
/**
|
|
|
* ledtrig_cpu - emit a CPU event as a trigger
|
|
|
* @evt: CPU event to be emitted
|
|
@@ -47,26 +51,46 @@ static DEFINE_PER_CPU(struct led_trigger_cpu, cpu_trig);
|
|
|
void ledtrig_cpu(enum cpu_led_event ledevt)
|
|
|
{
|
|
|
struct led_trigger_cpu *trig = this_cpu_ptr(&cpu_trig);
|
|
|
+ bool is_active = trig->is_active;
|
|
|
|
|
|
/* Locate the correct CPU LED */
|
|
|
switch (ledevt) {
|
|
|
case CPU_LED_IDLE_END:
|
|
|
case CPU_LED_START:
|
|
|
/* Will turn the LED on, max brightness */
|
|
|
- led_trigger_event(trig->_trig, LED_FULL);
|
|
|
+ is_active = true;
|
|
|
break;
|
|
|
|
|
|
case CPU_LED_IDLE_START:
|
|
|
case CPU_LED_STOP:
|
|
|
case CPU_LED_HALTED:
|
|
|
/* Will turn the LED off */
|
|
|
- led_trigger_event(trig->_trig, LED_OFF);
|
|
|
+ is_active = false;
|
|
|
break;
|
|
|
|
|
|
default:
|
|
|
/* Will leave the LED as it is */
|
|
|
break;
|
|
|
}
|
|
|
+
|
|
|
+ if (is_active != trig->is_active) {
|
|
|
+ unsigned int active_cpus;
|
|
|
+ unsigned int total_cpus;
|
|
|
+
|
|
|
+ /* Update trigger state */
|
|
|
+ trig->is_active = is_active;
|
|
|
+ atomic_add(is_active ? 1 : -1, &num_active_cpus);
|
|
|
+ active_cpus = atomic_read(&num_active_cpus);
|
|
|
+ total_cpus = num_present_cpus();
|
|
|
+
|
|
|
+ led_trigger_event(trig->_trig,
|
|
|
+ is_active ? LED_FULL : LED_OFF);
|
|
|
+
|
|
|
+
|
|
|
+ led_trigger_event(trig_cpu_all,
|
|
|
+ DIV_ROUND_UP(LED_FULL * active_cpus, total_cpus));
|
|
|
+
|
|
|
+ }
|
|
|
}
|
|
|
EXPORT_SYMBOL(ledtrig_cpu);
|
|
|
|
|
@@ -112,6 +136,11 @@ static int __init ledtrig_cpu_init(void)
|
|
|
/* Supports up to 9999 cpu cores */
|
|
|
BUILD_BUG_ON(CONFIG_NR_CPUS > 9999);
|
|
|
|
|
|
+ /*
|
|
|
+ * Registering a trigger for all CPUs.
|
|
|
+ */
|
|
|
+ led_trigger_register_simple("cpu", &trig_cpu_all);
|
|
|
+
|
|
|
/*
|
|
|
* Registering CPU led trigger for each CPU core here
|
|
|
* ignores CPU hotplug, but after this CPU hotplug works
|