From mboxrd@z Thu Jan 1 00:00:00 1970 From: bryan.wu@canonical.com (Bryan Wu) Date: Sat, 25 Jun 2011 09:42:31 +0800 Subject: [PATCH 1/3] leds: create a trigger for ARM CPU activity In-Reply-To: <1308763983-24749-1-git-send-email-linus.walleij@stericsson.com> References: <1308763983-24749-1-git-send-email-linus.walleij@stericsson.com> Message-ID: To: linux-arm-kernel@lists.infradead.org List-Id: linux-arm-kernel.lists.infradead.org On Thu, Jun 23, 2011 at 1:33 AM, Linus Walleij wrote: > From: Linus Walleij > > Attempting to consolidate the ARM LED code, this removes the > custom RealView LED trigger code to turn LEDs on and off in > response to CPU activity and replace it with a standard trigger. > It uses the existing kernel hooks deep inside to > get CPU activity. > I've been thinking about moving the arm led_event interface to drivers/leds/. And maybe other machines can simply benefit from this trigger driver, since the led_event interface is actually not really ARM specific. So what about add a new trigger just named ledtrig-cpu.c which can be shared by other machines as well as ARM monsters. > Cc: Bryan Wu > Cc: Richard Purdie > Signed-off-by: Linus Walleij > --- > ?drivers/leds/Kconfig ? ? ? ? ? | ? 15 +++++ > ?drivers/leds/Makefile ? ? ? ? ?| ? ?1 + > ?drivers/leds/ledtrig-arm-cpu.c | ?114 ++++++++++++++++++++++++++++++++++++++++ > ?3 files changed, 130 insertions(+), 0 deletions(-) > ?create mode 100644 drivers/leds/ledtrig-arm-cpu.c > > diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig > index 713d43b..f725ae2 100644 > --- a/drivers/leds/Kconfig > +++ b/drivers/leds/Kconfig > @@ -446,6 +446,21 @@ config LEDS_TRIGGER_BACKLIGHT > > ? ? ? ? ?If unsure, say N. > > +# Notice that this uses the CONFIG_LEDS i.e. the "old" LEDS > +config LEDS_TRIGGER_ARM_CPU > + ? ? ? bool "LED ARM CPU Trigger" > + ? ? ? depends on LEDS_TRIGGERS && ARM > + ? ? ? select LEDS > + ? ? ? select LEDS_CPU > + ? ? ? default y if ARCH_REALVIEW > + ? ? ? default y if ARCH_VERSATILE How about remove this and let REALVIEW to select this option > + ? ? ? help > + ? ? ? ? This allows LEDs to be controlled by active ARM CPUs. This > + ? ? ? ? shows the active CPUs across an array of LEDs so you can see > + ? ? ? ? what CPUs are active on the system at any given moment. > + > + ? ? ? ? If unsure, say N. > + > ?config LEDS_TRIGGER_GPIO > ? ? ? ?tristate "LED GPIO Trigger" > ? ? ? ?depends on LEDS_TRIGGERS > diff --git a/drivers/leds/Makefile b/drivers/leds/Makefile > index bbfd2e3..a32a99c 100644 > --- a/drivers/leds/Makefile > +++ b/drivers/leds/Makefile > @@ -53,4 +53,5 @@ obj-$(CONFIG_LEDS_TRIGGER_IDE_DISK) ? += ledtrig-ide-disk.o > ?obj-$(CONFIG_LEDS_TRIGGER_HEARTBEAT) ? += ledtrig-heartbeat.o > ?obj-$(CONFIG_LEDS_TRIGGER_BACKLIGHT) ? += ledtrig-backlight.o > ?obj-$(CONFIG_LEDS_TRIGGER_GPIO) ? ? ? ? ? ? ? ?+= ledtrig-gpio.o > +obj-$(CONFIG_LEDS_TRIGGER_ARM_CPU) ? ? += ledtrig-arm-cpu.o > ?obj-$(CONFIG_LEDS_TRIGGER_DEFAULT_ON) ?+= ledtrig-default-on.o > diff --git a/drivers/leds/ledtrig-arm-cpu.c b/drivers/leds/ledtrig-arm-cpu.c > new file mode 100644 > index 0000000..7776d61 > --- /dev/null > +++ b/drivers/leds/ledtrig-arm-cpu.c > @@ -0,0 +1,114 @@ > +/* > + * ledtrig-arm-cpu.c - LED trigger based on ARM CPU activity > + * > + * Copyright 2011 Linus Walleij > + * > + * This program is free software; you can redistribute it and/or modify > + * it under the terms of the GNU General Public License version 2 as > + * published by the Free Software Foundation. > + * > + */ > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include How about moving this out to drivers/leds/ledtrigg-cpu.h? > +#include "leds.h" > + > +struct arm_cpu_trig_data { > + ? ? ? struct led_classdev *led; > +}; > + > +static DEFINE_PER_CPU(struct arm_cpu_trig_data *, arm_cpu_triggers); > + > +void arm_cpu_leds_event(led_event_t ledevt) > +{ > + ? ? ? struct arm_cpu_trig_data *trigdata = __get_cpu_var(arm_cpu_triggers); > + > + ? ? ? if (!trigdata) > + ? ? ? ? ? ? ? return; > + > + ? ? ? /* Locate the correct CPU LED */ > + > + ? ? ? switch (ledevt) { > + ? ? ? case led_halted: > + ? ? ? case led_idle_start: > + ? ? ? ? ? ? ? /* Will turn the LED off */ > + ? ? ? ? ? ? ? if (trigdata->led) > + ? ? ? ? ? ? ? ? ? ? ? led_set_brightness(trigdata->led, LED_OFF); > + ? ? ? ? ? ? ? break; > + > + ? ? ? case led_idle_end: > + ? ? ? ? ? ? ? /* Will turn the LED on, max brightness */ > + ? ? ? ? ? ? ? if (trigdata->led) > + ? ? ? ? ? ? ? ? ? ? ? led_set_brightness(trigdata->led, > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?trigdata->led->max_brightness); > + ? ? ? ? ? ? ? break; > + > + ? ? ? default: > + ? ? ? ? ? ? ? /* Will leave the LED as it is */ > + ? ? ? ? ? ? ? break; > + ? ? ? } > +} > + > +static void arm_cpu_trig_activate_cpu(void *data) > +{ > + ? ? ? struct arm_cpu_trig_data *arm_cpu_data; > + ? ? ? struct led_classdev *led = data; > + ? ? ? int my_cpu = smp_processor_id(); > + ? ? ? unsigned long target_cpu = (unsigned long) led->trigger_data; > + > + ? ? ? if (target_cpu != my_cpu) > + ? ? ? ? ? ? ? return; > + > + ? ? ? arm_cpu_data = kzalloc(sizeof(*arm_cpu_data), GFP_KERNEL); > + ? ? ? if (!arm_cpu_data) > + ? ? ? ? ? ? ? return; > + > + ? ? ? dev_info(led->dev, "led %s indicate activity on CPU %d\n", > + ? ? ? ? ? ? ? ?led->name, my_cpu); > + > + ? ? ? arm_cpu_data->led = led; > + ? ? ? __get_cpu_var(arm_cpu_triggers) = arm_cpu_data; > +} > + > +static void arm_cpu_trig_activate(struct led_classdev *led) > +{ > + ? ? ? on_each_cpu(arm_cpu_trig_activate_cpu, led, 1); > + > + ? ? ? /* Hook into ARM core kernel event callback */ > + ? ? ? leds_event = arm_cpu_leds_event; > +} > + > +static void arm_cpu_trig_deactivate(struct led_classdev *led) > +{ > + ? ? ? struct arm_cpu_trig_data *arm_cpu_data = led->trigger_data; > + > + ? ? ? if (arm_cpu_data) > + ? ? ? ? ? ? ? kfree(arm_cpu_data); > +} > + > +static struct led_trigger arm_cpu_led_trigger = { > + ? ? ? .name ? ? ? ? ? = "arm-cpu", > + ? ? ? .activate ? ? ? = arm_cpu_trig_activate, > + ? ? ? .deactivate ? ? = arm_cpu_trig_deactivate, > +}; > + > +static int __init arm_cpu_trig_init(void) > +{ > + ? ? ? return led_trigger_register(&arm_cpu_led_trigger); > +} > +module_init(arm_cpu_trig_init); > + > +static void __exit arm_cpu_trig_exit(void) > +{ > + ? ? ? led_trigger_unregister(&arm_cpu_led_trigger); > +} > +module_exit(arm_cpu_trig_exit); > + > +MODULE_AUTHOR("Linus Walleij "); > +MODULE_DESCRIPTION("ARM CPU LED trigger"); > +MODULE_LICENSE("GPL"); > -- > 1.7.3.2 > > Thanks, this work is really what I want to do. -- Bryan Wu Kernel Developer ? ?+86.138-1617-6545 Mobile Ubuntu Kernel Team Canonical Ltd. ? ? ?www.canonical.com Ubuntu - Linux for human beings | www.ubuntu.com