* [PATCH 2/3] led-triggers: use atomic kzalloc during led trigger registering
2012-03-08 9:11 [PATCH 1/3] led-class: change back LEDS_CLASS to tristate instead of bool Bryan Wu
@ 2012-03-08 9:11 ` Bryan Wu
2012-03-08 9:29 ` Uwe Kleine-König
2012-03-08 9:11 ` [PATCH 3/3] led-triggers: create a trigger for CPU activity Bryan Wu
` (3 subsequent siblings)
4 siblings, 1 reply; 14+ messages in thread
From: Bryan Wu @ 2012-03-08 9:11 UTC (permalink / raw)
To: linux-arm-kernel
kzalloc might cause sleep and will generate some warning detected by lockdep,
when call led_trigger_register_simple on each cpu cores in SMP. This patch fix
this.
[ 1.999938] ------------[ cut here ]------------
[ 2.004791] WARNING: at kernel/lockdep.c:2664 lockdep_trace_alloc+0xd8/0xf0()
[ 2.012298] Modules linked in:
[ 2.015563] [<c001b0cc>] (unwind_backtrace+0x0/0xf0) from [<c0052408>] (warn_slowpath_common+0x4c/0x64)
[ 2.025451] [<c0052408>] (warn_slowpath_common+0x4c/0x64) from [<c005243c>] (warn_slowpath_null+0x1c/0x24)
[ 2.035583] [<c005243c>] (warn_slowpath_null+0x1c/0x24) from [<c008be28>] (lockdep_trace_alloc+0xd8/0xf0)
[ 2.045684] [<c008be28>] (lockdep_trace_alloc+0xd8/0xf0) from [<c00feeb4>] (kmem_cache_alloc_trace+0x2c/0x148)
[ 2.056213] [<c00feeb4>] (kmem_cache_alloc_trace+0x2c/0x148) from [<c03770a0>] (led_trigger_register_simple+0x20/0x74)
[ 2.067474] [<c03770a0>] (led_trigger_register_simple+0x20/0x74) from [<c0627a30>] (ledtrig_cpu_register+0x4c/0x8c)
[ 2.078460] [<c0627a30>] (ledtrig_cpu_register+0x4c/0x8c) from [<c0094ca4>] (generic_smp_call_function_single_interrupt+0xcc/0x138)
[ 2.090911] [<c0094ca4>] (generic_smp_call_function_single_interrupt+0xcc/0x138) from [<c0008408>] (do_IPI+0xb0/0x128)
[ 2.102172] [<c0008408>] (do_IPI+0xb0/0x128) from [<c045921c>] (__irq_svc+0x3c/0x100)
[ 2.110412] Exception stack(0xc07adf70 to 0xc07adfb8)
[ 2.115722] df60: c07c80f8 0000fb45 00000000 c07c80f8
[ 2.124328] df80: c07ac000 c0837be4 c0464b64 c07c9d8c 00000000 411fc092 00000000 00000000
[ 2.132934] dfa0: c0649760 c07adfb8 c07c5c58 c0014d50 20000013 ffffffff
[ 2.139892] [<c045921c>] (__irq_svc+0x3c/0x100) from [<c0014d50>] (default_idle+0x30/0x38)
[ 2.148590] [<c0014d50>] (default_idle+0x30/0x38) from [<c0014f74>] (cpu_idle+0xb4/0xf4)
[ 2.157135] [<c0014f74>] (cpu_idle+0xb4/0xf4) from [<c0602778>] (start_kernel+0x2a8/0x2fc)
[ 2.165832] [<c0602778>] (start_kernel+0x2a8/0x2fc) from [<80008040>] (0x80008040)
[ 2.173797] ---[ end trace 97549d21d8dad3f5 ]---
Signed-off-by: Bryan Wu <bryan.wu@canonical.com>
---
drivers/leds/led-triggers.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/drivers/leds/led-triggers.c b/drivers/leds/led-triggers.c
index 46b4c76..74d0ba7 100644
--- a/drivers/leds/led-triggers.c
+++ b/drivers/leds/led-triggers.c
@@ -255,7 +255,7 @@ void led_trigger_register_simple(const char *name, struct led_trigger **tp)
struct led_trigger *trigger;
int err;
- trigger = kzalloc(sizeof(struct led_trigger), GFP_KERNEL);
+ trigger = kzalloc(sizeof(struct led_trigger), GFP_ATOMIC);
if (trigger) {
trigger->name = name;
--
1.7.9
^ permalink raw reply related [flat|nested] 14+ messages in thread* [PATCH 2/3] led-triggers: use atomic kzalloc during led trigger registering
2012-03-08 9:11 ` [PATCH 2/3] led-triggers: use atomic kzalloc during led trigger registering Bryan Wu
@ 2012-03-08 9:29 ` Uwe Kleine-König
2012-03-10 11:15 ` Bryan Wu
0 siblings, 1 reply; 14+ messages in thread
From: Uwe Kleine-König @ 2012-03-08 9:29 UTC (permalink / raw)
To: linux-arm-kernel
On Thu, Mar 08, 2012 at 05:11:02PM +0800, Bryan Wu wrote:
> kzalloc might cause sleep and will generate some warning detected by lockdep,
> when call led_trigger_register_simple on each cpu cores in SMP. This patch fix
> this.
The obvious (and IMHO better) alternative is to call
led_trigger_register_simple from non-atomic context.
For registering this should be OK, shouldn't it?
Best regards
Uwe
>
> [ 1.999938] ------------[ cut here ]------------
> [ 2.004791] WARNING: at kernel/lockdep.c:2664 lockdep_trace_alloc+0xd8/0xf0()
> [ 2.012298] Modules linked in:
> [ 2.015563] [<c001b0cc>] (unwind_backtrace+0x0/0xf0) from [<c0052408>] (warn_slowpath_common+0x4c/0x64)
> [ 2.025451] [<c0052408>] (warn_slowpath_common+0x4c/0x64) from [<c005243c>] (warn_slowpath_null+0x1c/0x24)
> [ 2.035583] [<c005243c>] (warn_slowpath_null+0x1c/0x24) from [<c008be28>] (lockdep_trace_alloc+0xd8/0xf0)
> [ 2.045684] [<c008be28>] (lockdep_trace_alloc+0xd8/0xf0) from [<c00feeb4>] (kmem_cache_alloc_trace+0x2c/0x148)
> [ 2.056213] [<c00feeb4>] (kmem_cache_alloc_trace+0x2c/0x148) from [<c03770a0>] (led_trigger_register_simple+0x20/0x74)
> [ 2.067474] [<c03770a0>] (led_trigger_register_simple+0x20/0x74) from [<c0627a30>] (ledtrig_cpu_register+0x4c/0x8c)
> [ 2.078460] [<c0627a30>] (ledtrig_cpu_register+0x4c/0x8c) from [<c0094ca4>] (generic_smp_call_function_single_interrupt+0xcc/0x138)
> [ 2.090911] [<c0094ca4>] (generic_smp_call_function_single_interrupt+0xcc/0x138) from [<c0008408>] (do_IPI+0xb0/0x128)
> [ 2.102172] [<c0008408>] (do_IPI+0xb0/0x128) from [<c045921c>] (__irq_svc+0x3c/0x100)
> [ 2.110412] Exception stack(0xc07adf70 to 0xc07adfb8)
> [ 2.115722] df60: c07c80f8 0000fb45 00000000 c07c80f8
> [ 2.124328] df80: c07ac000 c0837be4 c0464b64 c07c9d8c 00000000 411fc092 00000000 00000000
> [ 2.132934] dfa0: c0649760 c07adfb8 c07c5c58 c0014d50 20000013 ffffffff
> [ 2.139892] [<c045921c>] (__irq_svc+0x3c/0x100) from [<c0014d50>] (default_idle+0x30/0x38)
> [ 2.148590] [<c0014d50>] (default_idle+0x30/0x38) from [<c0014f74>] (cpu_idle+0xb4/0xf4)
> [ 2.157135] [<c0014f74>] (cpu_idle+0xb4/0xf4) from [<c0602778>] (start_kernel+0x2a8/0x2fc)
> [ 2.165832] [<c0602778>] (start_kernel+0x2a8/0x2fc) from [<80008040>] (0x80008040)
> [ 2.173797] ---[ end trace 97549d21d8dad3f5 ]---
>
> Signed-off-by: Bryan Wu <bryan.wu@canonical.com>
> ---
> drivers/leds/led-triggers.c | 2 +-
> 1 files changed, 1 insertions(+), 1 deletions(-)
>
> diff --git a/drivers/leds/led-triggers.c b/drivers/leds/led-triggers.c
> index 46b4c76..74d0ba7 100644
> --- a/drivers/leds/led-triggers.c
> +++ b/drivers/leds/led-triggers.c
> @@ -255,7 +255,7 @@ void led_trigger_register_simple(const char *name, struct led_trigger **tp)
> struct led_trigger *trigger;
> int err;
>
> - trigger = kzalloc(sizeof(struct led_trigger), GFP_KERNEL);
> + trigger = kzalloc(sizeof(struct led_trigger), GFP_ATOMIC);
>
> if (trigger) {
> trigger->name = name;
> --
> 1.7.9
>
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
>
--
Pengutronix e.K. | Uwe Kleine-K?nig |
Industrial Linux Solutions | http://www.pengutronix.de/ |
^ permalink raw reply [flat|nested] 14+ messages in thread* [PATCH 2/3] led-triggers: use atomic kzalloc during led trigger registering
2012-03-08 9:29 ` Uwe Kleine-König
@ 2012-03-10 11:15 ` Bryan Wu
2012-03-12 19:37 ` Linus Walleij
0 siblings, 1 reply; 14+ messages in thread
From: Bryan Wu @ 2012-03-10 11:15 UTC (permalink / raw)
To: linux-arm-kernel
2012/3/8 Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>:
> On Thu, Mar 08, 2012 at 05:11:02PM +0800, Bryan Wu wrote:
>> kzalloc might cause sleep and will generate some warning detected by lockdep,
>> when call led_trigger_register_simple on each cpu cores in SMP. This patch fix
>> this.
> The obvious (and IMHO better) alternative is to call
> led_trigger_register_simple from non-atomic context.
>
> For registering this should be OK, shouldn't it?
>
Thanks Uwe, it's my bad. I think I should not use on_each_cpu() API to
run led_trigger_register_simple. on_each_cpu() will disable interrupt.
Let's ignore this patch and I will update my ledtrig-cpu patch to use
for_each_cpu().
And thanks Ming for your advice.
Best Regards,
-Bryan
>
>>
>> [ ? ?1.999938] ------------[ cut here ]------------
>> [ ? ?2.004791] WARNING: at kernel/lockdep.c:2664 lockdep_trace_alloc+0xd8/0xf0()
>> [ ? ?2.012298] Modules linked in:
>> [ ? ?2.015563] [<c001b0cc>] (unwind_backtrace+0x0/0xf0) from [<c0052408>] (warn_slowpath_common+0x4c/0x64)
>> [ ? ?2.025451] [<c0052408>] (warn_slowpath_common+0x4c/0x64) from [<c005243c>] (warn_slowpath_null+0x1c/0x24)
>> [ ? ?2.035583] [<c005243c>] (warn_slowpath_null+0x1c/0x24) from [<c008be28>] (lockdep_trace_alloc+0xd8/0xf0)
>> [ ? ?2.045684] [<c008be28>] (lockdep_trace_alloc+0xd8/0xf0) from [<c00feeb4>] (kmem_cache_alloc_trace+0x2c/0x148)
>> [ ? ?2.056213] [<c00feeb4>] (kmem_cache_alloc_trace+0x2c/0x148) from [<c03770a0>] (led_trigger_register_simple+0x20/0x74)
>> [ ? ?2.067474] [<c03770a0>] (led_trigger_register_simple+0x20/0x74) from [<c0627a30>] (ledtrig_cpu_register+0x4c/0x8c)
>> [ ? ?2.078460] [<c0627a30>] (ledtrig_cpu_register+0x4c/0x8c) from [<c0094ca4>] (generic_smp_call_function_single_interrupt+0xcc/0x138)
>> [ ? ?2.090911] [<c0094ca4>] (generic_smp_call_function_single_interrupt+0xcc/0x138) from [<c0008408>] (do_IPI+0xb0/0x128)
>> [ ? ?2.102172] [<c0008408>] (do_IPI+0xb0/0x128) from [<c045921c>] (__irq_svc+0x3c/0x100)
>> [ ? ?2.110412] Exception stack(0xc07adf70 to 0xc07adfb8)
>> [ ? ?2.115722] df60: ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? c07c80f8 0000fb45 00000000 c07c80f8
>> [ ? ?2.124328] df80: c07ac000 c0837be4 c0464b64 c07c9d8c 00000000 411fc092 00000000 00000000
>> [ ? ?2.132934] dfa0: c0649760 c07adfb8 c07c5c58 c0014d50 20000013 ffffffff
>> [ ? ?2.139892] [<c045921c>] (__irq_svc+0x3c/0x100) from [<c0014d50>] (default_idle+0x30/0x38)
>> [ ? ?2.148590] [<c0014d50>] (default_idle+0x30/0x38) from [<c0014f74>] (cpu_idle+0xb4/0xf4)
>> [ ? ?2.157135] [<c0014f74>] (cpu_idle+0xb4/0xf4) from [<c0602778>] (start_kernel+0x2a8/0x2fc)
>> [ ? ?2.165832] [<c0602778>] (start_kernel+0x2a8/0x2fc) from [<80008040>] (0x80008040)
>> [ ? ?2.173797] ---[ end trace 97549d21d8dad3f5 ]---
>>
>> Signed-off-by: Bryan Wu <bryan.wu@canonical.com>
>> ---
>> ?drivers/leds/led-triggers.c | ? ?2 +-
>> ?1 files changed, 1 insertions(+), 1 deletions(-)
>>
>> diff --git a/drivers/leds/led-triggers.c b/drivers/leds/led-triggers.c
>> index 46b4c76..74d0ba7 100644
>> --- a/drivers/leds/led-triggers.c
>> +++ b/drivers/leds/led-triggers.c
>> @@ -255,7 +255,7 @@ void led_trigger_register_simple(const char *name, struct led_trigger **tp)
>> ? ? ? struct led_trigger *trigger;
>> ? ? ? int err;
>>
>> - ? ? trigger = kzalloc(sizeof(struct led_trigger), GFP_KERNEL);
>> + ? ? trigger = kzalloc(sizeof(struct led_trigger), GFP_ATOMIC);
>>
>> ? ? ? if (trigger) {
>> ? ? ? ? ? ? ? trigger->name = name;
>> --
>> 1.7.9
>>
>>
>> _______________________________________________
>> linux-arm-kernel mailing list
>> linux-arm-kernel at lists.infradead.org
>> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
>>
>
> --
> Pengutronix e.K. ? ? ? ? ? ? ? ? ? ? ? ? ? | Uwe Kleine-K?nig ? ? ? ? ? ?|
> Industrial Linux Solutions ? ? ? ? ? ? ? ? | http://www.pengutronix.de/ ?|
--
Bryan Wu <bryan.wu@canonical.com>
Kernel Developer ? ?+86.138-1617-6545 Mobile
Ubuntu ARM Team
Canonical Ltd. ? ? ?www.canonical.com
Ubuntu - Linux for human beings | www.ubuntu.com
^ permalink raw reply [flat|nested] 14+ messages in thread* [PATCH 2/3] led-triggers: use atomic kzalloc during led trigger registering
2012-03-10 11:15 ` Bryan Wu
@ 2012-03-12 19:37 ` Linus Walleij
2012-03-13 8:50 ` Bryan Wu
0 siblings, 1 reply; 14+ messages in thread
From: Linus Walleij @ 2012-03-12 19:37 UTC (permalink / raw)
To: linux-arm-kernel
2012/3/10 Bryan Wu <bryan.wu@canonical.com>:
> 2012/3/8 Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>:
>> On Thu, Mar 08, 2012 at 05:11:02PM +0800, Bryan Wu wrote:
>>> kzalloc might cause sleep and will generate some warning detected by lockdep,
>>> when call led_trigger_register_simple on each cpu cores in SMP. This patch fix
>>> this.
>> The obvious (and IMHO better) alternative is to call
>> led_trigger_register_simple from non-atomic context.
>>
>> For registering this should be OK, shouldn't it?
>>
> Thanks Uwe, it's my bad. I think I should not use on_each_cpu() API to
> run led_trigger_register_simple. on_each_cpu() will disable interrupt.
It might have been my mistake even so not your fault ... :-)
Thanks,
Linus Walleij
^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH 2/3] led-triggers: use atomic kzalloc during led trigger registering
2012-03-12 19:37 ` Linus Walleij
@ 2012-03-13 8:50 ` Bryan Wu
0 siblings, 0 replies; 14+ messages in thread
From: Bryan Wu @ 2012-03-13 8:50 UTC (permalink / raw)
To: linux-arm-kernel
On Tue, Mar 13, 2012 at 3:37 AM, Linus Walleij <linus.walleij@linaro.org> wrote:
> 2012/3/10 Bryan Wu <bryan.wu@canonical.com>:
>> 2012/3/8 Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>:
>>> On Thu, Mar 08, 2012 at 05:11:02PM +0800, Bryan Wu wrote:
>>>> kzalloc might cause sleep and will generate some warning detected by lockdep,
>>>> when call led_trigger_register_simple on each cpu cores in SMP. This patch fix
>>>> this.
>>> The obvious (and IMHO better) alternative is to call
>>> led_trigger_register_simple from non-atomic context.
>>>
>>> For registering this should be OK, shouldn't it?
>>>
>> Thanks Uwe, it's my bad. I think I should not use on_each_cpu() API to
>> run led_trigger_register_simple. on_each_cpu() will disable interrupt.
>
> It might have been my mistake even so not your fault ... :-)
>
No problem, man. I just simply replaced GFP_KERNEL with GFP_ATOMIC
without thinking deeper.
Best Regards,
--
Bryan Wu <bryan.wu@canonical.com>
Kernel Developer ? ?+86.138-1617-6545 Mobile
Canonical Ltd. ? ? ?www.canonical.com
Ubuntu - Linux for human beings | www.ubuntu.com
^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH 3/3] led-triggers: create a trigger for CPU activity
2012-03-08 9:11 [PATCH 1/3] led-class: change back LEDS_CLASS to tristate instead of bool Bryan Wu
2012-03-08 9:11 ` [PATCH 2/3] led-triggers: use atomic kzalloc during led trigger registering Bryan Wu
@ 2012-03-08 9:11 ` Bryan Wu
2012-03-13 23:11 ` Andrew Morton
2012-03-11 7:45 ` [PATCH 1/3] led-class: change back LEDS_CLASS to tristate instead of bool Bryan Wu
` (2 subsequent siblings)
4 siblings, 1 reply; 14+ messages in thread
From: Bryan Wu @ 2012-03-08 9:11 UTC (permalink / raw)
To: linux-arm-kernel
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.
(bryan.wu at canonical.com:
It moves arch/arm/kernel/leds.c syscore stubs into this trigger.
It also provides ledtrig_cpu trigger event stub in <linux/leds.h>.
Although it was inspired by ARM work, it can be used in other arch.)
Cc: Richard Purdie <rpurdie@rpsys.net>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Bryan Wu <bryan.wu@canonical.com>
Reviewed-by: Jamie Iles <jamie@jamieiles.com>
Tested-by: Jochen Friedrich <jochen@scram.de>
---
drivers/leds/Kconfig | 10 ++++
drivers/leds/Makefile | 1 +
drivers/leds/ledtrig-cpu.c | 119 ++++++++++++++++++++++++++++++++++++++++++++
include/linux/leds.h | 15 ++++++
4 files changed, 145 insertions(+), 0 deletions(-)
create mode 100644 drivers/leds/ledtrig-cpu.c
diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig
index 3f17f0d..f7f4761 100644
--- a/drivers/leds/Kconfig
+++ b/drivers/leds/Kconfig
@@ -457,6 +457,16 @@ config LEDS_TRIGGER_BACKLIGHT
If unsure, say N.
+config LEDS_TRIGGER_CPU
+ tristate "LED CPU Trigger"
+ depends on LEDS_TRIGGERS
+ help
+ This allows LEDs to be controlled by active 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 1fc6875..6629916 100644
--- a/drivers/leds/Makefile
+++ b/drivers/leds/Makefile
@@ -56,4 +56,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_CPU) += ledtrig-cpu.o
obj-$(CONFIG_LEDS_TRIGGER_DEFAULT_ON) += ledtrig-default-on.o
diff --git a/drivers/leds/ledtrig-cpu.c b/drivers/leds/ledtrig-cpu.c
new file mode 100644
index 0000000..49f7879
--- /dev/null
+++ b/drivers/leds/ledtrig-cpu.c
@@ -0,0 +1,119 @@
+/*
+ * ledtrig-cpu.c - LED trigger based on CPU activity
+ *
+ * Copyright 2011 Linus Walleij <linus.walleij@linaro.org>
+ * Copyright 2011 Bryan Wu <bryan.wu@canonical.com>
+ *
+ * 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 <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/percpu.h>
+#include <linux/syscore_ops.h>
+#include "leds.h"
+
+static DEFINE_PER_CPU(struct led_trigger *, cpu_trig);
+static DEFINE_PER_CPU(char [8], trig_name);
+
+void ledtrig_cpu(enum cpu_led_event ledevt)
+{
+ struct led_trigger *trig = __get_cpu_var(cpu_trig);
+
+ if (!trig)
+ return;
+
+ /* 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, LED_FULL);
+ break;
+
+ case CPU_LED_IDLE_START:
+ case CPU_LED_STOP:
+ case CPU_LED_HALTED:
+ /* Will turn the LED off */
+ led_trigger_event(trig, LED_OFF);
+ break;
+
+ default:
+ /* Will leave the LED as it is */
+ break;
+ }
+}
+EXPORT_SYMBOL(ledtrig_cpu);
+
+static int ledtrig_cpu_syscore_suspend(void)
+{
+ ledtrig_cpu(CPU_LED_STOP);
+ return 0;
+}
+
+static void ledtrig_cpu_syscore_resume(void)
+{
+ ledtrig_cpu(CPU_LED_START);
+}
+
+static void ledtrig_cpu_syscore_shutdown(void)
+{
+ ledtrig_cpu(CPU_LED_HALTED);
+}
+
+static struct syscore_ops ledtrig_cpu_syscore_ops = {
+ .shutdown = ledtrig_cpu_syscore_shutdown,
+ .suspend = ledtrig_cpu_syscore_suspend,
+ .resume = ledtrig_cpu_syscore_resume,
+};
+
+static void __init ledtrig_cpu_register(void *info)
+{
+ int cpuid = smp_processor_id();
+ struct led_trigger *trig;
+ char *name = __get_cpu_var(trig_name);
+
+ snprintf(name, 8, "cpu%d", cpuid);
+ led_trigger_register_simple(name, &trig);
+
+ pr_info("LED trigger %s indicate activity on CPU %d\n",
+ trig->name, cpuid);
+
+ __get_cpu_var(cpu_trig) = trig;
+}
+
+static void __exit ledtrig_cpu_unregister(void *info)
+{
+ struct led_trigger *trig = __get_cpu_var(cpu_trig);
+ char *name = __get_cpu_var(trig_name);
+
+ led_trigger_unregister_simple(trig);
+ __get_cpu_var(cpu_trig) = NULL;
+ memset(name, 0, 8);
+}
+
+static int __init ledtrig_cpu_init(void)
+{
+ on_each_cpu(ledtrig_cpu_register, NULL, 1);
+ register_syscore_ops(&ledtrig_cpu_syscore_ops);
+
+ return 0;
+}
+module_init(ledtrig_cpu_init);
+
+static void __exit ledtrig_cpu_exit(void)
+{
+ on_each_cpu(ledtrig_cpu_unregister, NULL, 1);
+ unregister_syscore_ops(&ledtrig_cpu_syscore_ops);
+}
+module_exit(ledtrig_cpu_exit);
+
+MODULE_AUTHOR("Linus Walleij <linus.walleij@linaro.org>");
+MODULE_AUTHOR("Bryan Wu <bryan.wu@canonical.com>");
+MODULE_DESCRIPTION("CPU LED trigger");
+MODULE_LICENSE("GPL");
diff --git a/include/linux/leds.h b/include/linux/leds.h
index 5884def..2afecb7 100644
--- a/include/linux/leds.h
+++ b/include/linux/leds.h
@@ -210,4 +210,19 @@ struct gpio_led_platform_data {
struct platform_device *gpio_led_register_device(
int id, const struct gpio_led_platform_data *pdata);
+#if defined(CONFIG_LEDS_TRIGGER_CPU) || defined(CONFIG_LEDS_TRIGGER_CPU_MODULE)
+enum cpu_led_event {
+ CPU_LED_IDLE_START, /* CPU enters idle */
+ CPU_LED_IDLE_END, /* CPU idle ends */
+ CPU_LED_START, /* Machine starts, especially resume */
+ CPU_LED_STOP, /* Machine stops, especially suspend */
+ CPU_LED_HALTED, /* Machine shutdown */
+};
+
+/* Use this routine to handle LEDs */
+extern void ledtrig_cpu(enum cpu_led_event evt);
+#else
+#define ledtrig_cpu(evt) do {} while (0)
+#endif
+
#endif /* __LINUX_LEDS_H_INCLUDED */
--
1.7.9
^ permalink raw reply related [flat|nested] 14+ messages in thread* [PATCH 3/3] led-triggers: create a trigger for CPU activity
2012-03-08 9:11 ` [PATCH 3/3] led-triggers: create a trigger for CPU activity Bryan Wu
@ 2012-03-13 23:11 ` Andrew Morton
2012-03-14 9:01 ` Linus Walleij
2012-03-15 5:08 ` Bryan Wu
0 siblings, 2 replies; 14+ messages in thread
From: Andrew Morton @ 2012-03-13 23:11 UTC (permalink / raw)
To: linux-arm-kernel
On Thu, 8 Mar 2012 17:11:03 +0800
Bryan Wu <bryan.wu@canonical.com> wrote:
> 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.
>
> (bryan.wu at canonical.com:
> It moves arch/arm/kernel/leds.c syscore stubs into this trigger.
> It also provides ledtrig_cpu trigger event stub in <linux/leds.h>.
> Although it was inspired by ARM work, it can be used in other arch.)
The patch doesn't "remove" or "move" anything. It wholly consists of
additions. Confused.
> Cc: Richard Purdie <rpurdie@rpsys.net>
> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
> Signed-off-by: Bryan Wu <bryan.wu@canonical.com>
>
> Reviewed-by: Jamie Iles <jamie@jamieiles.com>
> Tested-by: Jochen Friedrich <jochen@scram.de>
The authorship is a bit unclear. You're the primary author, yes?
> --- /dev/null
> +++ b/drivers/leds/ledtrig-cpu.c
> @@ -0,0 +1,119 @@
> +/*
> + * ledtrig-cpu.c - LED trigger based on CPU activity
> + *
> + * Copyright 2011 Linus Walleij <linus.walleij@linaro.org>
> + * Copyright 2011 Bryan Wu <bryan.wu@canonical.com>
> + *
> + * 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 <linux/module.h>
> +#include <linux/kernel.h>
> +#include <linux/init.h>
> +#include <linux/slab.h>
> +#include <linux/percpu.h>
> +#include <linux/syscore_ops.h>
> +#include "leds.h"
> +
> +static DEFINE_PER_CPU(struct led_trigger *, cpu_trig);
> +static DEFINE_PER_CPU(char [8], trig_name);
> +
> +void ledtrig_cpu(enum cpu_led_event ledevt)
> +{
> + struct led_trigger *trig = __get_cpu_var(cpu_trig);
> +
> + if (!trig)
> + return;
> +
> + /* 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, LED_FULL);
> + break;
> +
> + case CPU_LED_IDLE_START:
> + case CPU_LED_STOP:
> + case CPU_LED_HALTED:
> + /* Will turn the LED off */
> + led_trigger_event(trig, LED_OFF);
> + break;
> +
> + default:
> + /* Will leave the LED as it is */
> + break;
> + }
> +}
> +EXPORT_SYMBOL(ledtrig_cpu);
This is a global, exported-to-modules API function. It should be
documented.
It should especially be documented if it has tricky unobvious calling
conditions, as this function does. AFAICT it must be called by code
which is running on the target CPU and which is pinned to that CPU via
either preempt_disable() or set_cpus_allowed().
Or something else - I don't have a clue, and the author didn't tell me :(
> +static int ledtrig_cpu_syscore_suspend(void)
> +{
> + ledtrig_cpu(CPU_LED_STOP);
> + return 0;
> +}
> +
> +static void ledtrig_cpu_syscore_resume(void)
> +{
> + ledtrig_cpu(CPU_LED_START);
> +}
> +
> +static void ledtrig_cpu_syscore_shutdown(void)
> +{
> + ledtrig_cpu(CPU_LED_HALTED);
> +}
> +
> +static struct syscore_ops ledtrig_cpu_syscore_ops = {
> + .shutdown = ledtrig_cpu_syscore_shutdown,
> + .suspend = ledtrig_cpu_syscore_suspend,
> + .resume = ledtrig_cpu_syscore_resume,
> +};
> +
> +static void __init ledtrig_cpu_register(void *info)
> +{
> + int cpuid = smp_processor_id();
> + struct led_trigger *trig;
> + char *name = __get_cpu_var(trig_name);
> +
> + snprintf(name, 8, "cpu%d", cpuid);
This explodes at 10,000 CPUS ;)
> + led_trigger_register_simple(name, &trig);
> +
> + pr_info("LED trigger %s indicate activity on CPU %d\n",
> + trig->name, cpuid);
> +
> + __get_cpu_var(cpu_trig) = trig;
> +}
> +
> +static void __exit ledtrig_cpu_unregister(void *info)
> +{
> + struct led_trigger *trig = __get_cpu_var(cpu_trig);
> + char *name = __get_cpu_var(trig_name);
> +
> + led_trigger_unregister_simple(trig);
> + __get_cpu_var(cpu_trig) = NULL;
> + memset(name, 0, 8);
> +}
> +
> +static int __init ledtrig_cpu_init(void)
> +{
> + on_each_cpu(ledtrig_cpu_register, NULL, 1);
on_each_cpu() only calls the function on presently-onlined CPUs. How
does this code interact with CPU hotplug?
And as you've already noted, led_trigger_register_simple() is totally
not callable from interrupt context. And we're not just talking about
under local_irq_disable() here: on_each_cpu() will raise cross-cpu hard
interrupts to call the function on remote CPUs. We end up trying to do
down_write() and who knows what else from within a hard interrupt
handler.
> --- a/include/linux/leds.h
> +++ b/include/linux/leds.h
> @@ -210,4 +210,19 @@ struct gpio_led_platform_data {
> struct platform_device *gpio_led_register_device(
> int id, const struct gpio_led_platform_data *pdata);
>
> +#if defined(CONFIG_LEDS_TRIGGER_CPU) || defined(CONFIG_LEDS_TRIGGER_CPU_MODULE)
> +enum cpu_led_event {
> + CPU_LED_IDLE_START, /* CPU enters idle */
> + CPU_LED_IDLE_END, /* CPU idle ends */
> + CPU_LED_START, /* Machine starts, especially resume */
> + CPU_LED_STOP, /* Machine stops, especially suspend */
> + CPU_LED_HALTED, /* Machine shutdown */
> +};
> +
> +/* Use this routine to handle LEDs */
> +extern void ledtrig_cpu(enum cpu_led_event evt);
> +#else
> +#define ledtrig_cpu(evt) do {} while (0)
> +#endif
a) the stub function should be written in C, not CPP please
b) it makes no sense to provide the stub function when the
definition of its argument type (enum cpu_led_event) is not
also available.
^ permalink raw reply [flat|nested] 14+ messages in thread* [PATCH 3/3] led-triggers: create a trigger for CPU activity
2012-03-13 23:11 ` Andrew Morton
@ 2012-03-14 9:01 ` Linus Walleij
2012-03-15 5:08 ` Bryan Wu
1 sibling, 0 replies; 14+ messages in thread
From: Linus Walleij @ 2012-03-14 9:01 UTC (permalink / raw)
To: linux-arm-kernel
On Wed, Mar 14, 2012 at 12:11 AM, Andrew Morton
<akpm@linux-foundation.org> wrote:
> On Thu, ?8 Mar 2012 17:11:03 +0800
> Bryan Wu <bryan.wu@canonical.com> wrote:
>
>> 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.
>>
>> (bryan.wu at canonical.com:
>> It moves arch/arm/kernel/leds.c syscore stubs into this trigger.
>> It also provides ledtrig_cpu trigger event stub in <linux/leds.h>.
>> Although it was inspired by ARM work, it can be used in other arch.)
>
> The patch doesn't "remove" or "move" anything. ?It wholly consists of
> additions. ?Confused.
>
>> Cc: Richard Purdie <rpurdie@rpsys.net>
>> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
>> Signed-off-by: Bryan Wu <bryan.wu@canonical.com>
>> Reviewed-by: Jamie Iles <jamie@jamieiles.com>
>> Tested-by: Jochen Friedrich <jochen@scram.de>
>
> The authorship is a bit unclear. ?You're the primary author, yes?
It's based on a patch I wrote ages ago, but I don't care much.
Since Bryan's been driving it since, let's say Bryan wrote it.
Just remove the signoff if it's confusing.
Linus Walleij
^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH 3/3] led-triggers: create a trigger for CPU activity
2012-03-13 23:11 ` Andrew Morton
2012-03-14 9:01 ` Linus Walleij
@ 2012-03-15 5:08 ` Bryan Wu
1 sibling, 0 replies; 14+ messages in thread
From: Bryan Wu @ 2012-03-15 5:08 UTC (permalink / raw)
To: linux-arm-kernel
On Wed, Mar 14, 2012 at 7:11 AM, Andrew Morton
<akpm@linux-foundation.org> wrote:
> On Thu, ?8 Mar 2012 17:11:03 +0800
> Bryan Wu <bryan.wu@canonical.com> wrote:
>
>> 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.
>>
>> (bryan.wu at canonical.com:
>> It moves arch/arm/kernel/leds.c syscore stubs into this trigger.
>> It also provides ledtrig_cpu trigger event stub in <linux/leds.h>.
>> Although it was inspired by ARM work, it can be used in other arch.)
>
> The patch doesn't "remove" or "move" anything. ?It wholly consists of
> additions. ?Confused.
>
I'm working on rebase my previous ARM leds consolidation patches to
the linux-next. So this patch will come with those patches soon.
Thanks for pointing out this.
>> Cc: Richard Purdie <rpurdie@rpsys.net>
>> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
>> Signed-off-by: Bryan Wu <bryan.wu@canonical.com>
>>
>> Reviewed-by: Jamie Iles <jamie@jamieiles.com>
>> Tested-by: Jochen Friedrich <jochen@scram.de>
>
> The authorship is a bit unclear. ?You're the primary author, yes?
>
My work is based on Linus Walleij's patch, so I keep his signed off
here. Basically I rewrote most of things.
>> --- /dev/null
>> +++ b/drivers/leds/ledtrig-cpu.c
>> @@ -0,0 +1,119 @@
>> +/*
>> + * ledtrig-cpu.c - LED trigger based on CPU activity
>> + *
>> + * Copyright 2011 Linus Walleij <linus.walleij@linaro.org>
>> + * Copyright 2011 Bryan Wu <bryan.wu@canonical.com>
>> + *
>> + * 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 <linux/module.h>
>> +#include <linux/kernel.h>
>> +#include <linux/init.h>
>> +#include <linux/slab.h>
>> +#include <linux/percpu.h>
>> +#include <linux/syscore_ops.h>
>> +#include "leds.h"
>> +
>> +static DEFINE_PER_CPU(struct led_trigger *, cpu_trig);
>> +static DEFINE_PER_CPU(char [8], trig_name);
>> +
>> +void ledtrig_cpu(enum cpu_led_event ledevt)
>> +{
>> + ? ? struct led_trigger *trig = __get_cpu_var(cpu_trig);
>> +
>> + ? ? if (!trig)
>> + ? ? ? ? ? ? return;
>> +
>> + ? ? /* 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, LED_FULL);
>> + ? ? ? ? ? ? break;
>> +
>> + ? ? case CPU_LED_IDLE_START:
>> + ? ? case CPU_LED_STOP:
>> + ? ? case CPU_LED_HALTED:
>> + ? ? ? ? ? ? /* Will turn the LED off */
>> + ? ? ? ? ? ? led_trigger_event(trig, LED_OFF);
>> + ? ? ? ? ? ? break;
>> +
>> + ? ? default:
>> + ? ? ? ? ? ? /* Will leave the LED as it is */
>> + ? ? ? ? ? ? break;
>> + ? ? }
>> +}
>> +EXPORT_SYMBOL(ledtrig_cpu);
>
> This is a global, exported-to-modules API function. ?It should be
> documented.
>
> It should especially be documented if it has tricky unobvious calling
> conditions, as this function does. ?AFAICT it must be called by code
> which is running on the target CPU and which is pinned to that CPU via
> either preempt_disable() or set_cpus_allowed().
>
> Or something else - I don't have a clue, and the author didn't tell me :(
>
OK, I will sort out the documents about this API.
>> +static int ledtrig_cpu_syscore_suspend(void)
>> +{
>> + ? ? ledtrig_cpu(CPU_LED_STOP);
>> + ? ? return 0;
>> +}
>> +
>> +static void ledtrig_cpu_syscore_resume(void)
>> +{
>> + ? ? ledtrig_cpu(CPU_LED_START);
>> +}
>> +
>> +static void ledtrig_cpu_syscore_shutdown(void)
>> +{
>> + ? ? ledtrig_cpu(CPU_LED_HALTED);
>> +}
>> +
>> +static struct syscore_ops ledtrig_cpu_syscore_ops = {
>> + ? ? .shutdown ? ? ? = ledtrig_cpu_syscore_shutdown,
>> + ? ? .suspend ? ? ? ?= ledtrig_cpu_syscore_suspend,
>> + ? ? .resume ? ? ? ? = ledtrig_cpu_syscore_resume,
>> +};
>> +
>> +static void __init ledtrig_cpu_register(void *info)
>> +{
>> + ? ? int cpuid = smp_processor_id();
>> + ? ? struct led_trigger *trig;
>> + ? ? char *name = __get_cpu_var(trig_name);
>> +
>> + ? ? snprintf(name, 8, "cpu%d", cpuid);
>
> This explodes at 10,000 CPUS ;)
>
I think it's enough for a while -:). or need I use snprintf(name,
4+NR_CPUS, "cpu%d", cpuid);
>> + ? ? led_trigger_register_simple(name, &trig);
>> +
>> + ? ? pr_info("LED trigger %s indicate activity on CPU %d\n",
>> + ? ? ? ? ? ? trig->name, cpuid);
>> +
>> + ? ? __get_cpu_var(cpu_trig) = trig;
>> +}
>> +
>> +static void __exit ledtrig_cpu_unregister(void *info)
>> +{
>> + ? ? struct led_trigger *trig = __get_cpu_var(cpu_trig);
>> + ? ? char *name = __get_cpu_var(trig_name);
>> +
>> + ? ? led_trigger_unregister_simple(trig);
>> + ? ? __get_cpu_var(cpu_trig) = NULL;
>> + ? ? memset(name, 0, 8);
>> +}
>> +
>> +static int __init ledtrig_cpu_init(void)
>> +{
>> + ? ? on_each_cpu(ledtrig_cpu_register, NULL, 1);
>
> on_each_cpu() only calls the function on presently-onlined CPUs. ?How
> does this code interact with CPU hotplug?
>
> And as you've already noted, led_trigger_register_simple() is totally
> not callable from interrupt context. ?And we're not just talking about
> under local_irq_disable() here: on_each_cpu() will raise cross-cpu hard
> interrupts to call the function on remote CPUs. ?We end up trying to do
> down_write() and who knows what else from within a hard interrupt
> handler.
>
Right, I will change that to for_each_cpu() and resubmmit the patch.
>> --- a/include/linux/leds.h
>> +++ b/include/linux/leds.h
>> @@ -210,4 +210,19 @@ struct gpio_led_platform_data {
>> ?struct platform_device *gpio_led_register_device(
>> ? ? ? ? ? ? ? int id, const struct gpio_led_platform_data *pdata);
>>
>> +#if defined(CONFIG_LEDS_TRIGGER_CPU) || defined(CONFIG_LEDS_TRIGGER_CPU_MODULE)
>> +enum cpu_led_event {
>> + ? ? CPU_LED_IDLE_START, ? ? /* CPU enters idle */
>> + ? ? CPU_LED_IDLE_END, ? ? ? /* CPU idle ends */
>> + ? ? CPU_LED_START, ? ? ? ? ?/* Machine starts, especially resume */
>> + ? ? CPU_LED_STOP, ? ? ? ? ? /* Machine stops, especially suspend */
>> + ? ? CPU_LED_HALTED, ? ? ? ? /* Machine shutdown */
>> +};
>> +
>> +/* Use this routine to handle LEDs */
>> +extern void ledtrig_cpu(enum cpu_led_event evt);
>> +#else
>> +#define ledtrig_cpu(evt) do {} while (0)
>> +#endif
>
> a) the stub function should be written in C, not CPP please
>
Actually, I'm only familiar with C and forget to write CPP for a
while. is this looks like CPP?
> b) it makes no sense to provide the stub function when the
> ? definition of its argument type (enum cpu_led_event) is not
> ? also available.
>
OK, l will move out the enum cpu_led_event out of this ifdef.
Thanks,
--
Bryan Wu <bryan.wu@canonical.com>
Kernel Developer ? ?+86.138-1617-6545 Mobile
Canonical Ltd. ? ? ?www.canonical.com
Ubuntu - Linux for human beings | www.ubuntu.com
^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH 1/3] led-class: change back LEDS_CLASS to tristate instead of bool
2012-03-08 9:11 [PATCH 1/3] led-class: change back LEDS_CLASS to tristate instead of bool Bryan Wu
2012-03-08 9:11 ` [PATCH 2/3] led-triggers: use atomic kzalloc during led trigger registering Bryan Wu
2012-03-08 9:11 ` [PATCH 3/3] led-triggers: create a trigger for CPU activity Bryan Wu
@ 2012-03-11 7:45 ` Bryan Wu
2012-03-11 13:13 ` Richard Purdie
2012-03-12 19:35 ` Linus Walleij
4 siblings, 0 replies; 14+ messages in thread
From: Bryan Wu @ 2012-03-11 7:45 UTC (permalink / raw)
To: linux-arm-kernel
Richard,
How about this patch we discussed before? Thanks,
-Bryan
On Thu, Mar 8, 2012 at 5:11 PM, Bryan Wu <bryan.wu@canonical.com> wrote:
> After moving some core functions to led-core.c, led-class.c can be built as
> module again.
>
> Signed-off-by: Bryan Wu <bryan.wu@canonical.com>
> ---
> ?drivers/leds/Kconfig ? ? | ? ?2 +-
> ?drivers/leds/led-class.c | ? 70 ----------------------------------------------
> ?drivers/leds/led-core.c ?| ? 70 ++++++++++++++++++++++++++++++++++++++++++++++
> ?3 files changed, 71 insertions(+), 71 deletions(-)
>
> diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig
> index 9ca28fc..3f17f0d 100644
> --- a/drivers/leds/Kconfig
> +++ b/drivers/leds/Kconfig
> @@ -17,7 +17,7 @@ menuconfig NEW_LEDS
> ?if NEW_LEDS
>
> ?config LEDS_CLASS
> - ? ? ? bool "LED Class Support"
> + ? ? ? tristate "LED Class Support"
> ? ? ? ?help
> ? ? ? ? ?This option enables the led sysfs class in /sys/class/leds. ?You'll
> ? ? ? ? ?need this to do anything useful with LEDs. ?If unsure, say N.
> diff --git a/drivers/leds/led-class.c b/drivers/leds/led-class.c
> index 0c8739c..5bff843 100644
> --- a/drivers/leds/led-class.c
> +++ b/drivers/leds/led-class.c
> @@ -110,50 +110,6 @@ static void led_timer_function(unsigned long data)
> ? ? ? ?mod_timer(&led_cdev->blink_timer, jiffies + msecs_to_jiffies(delay));
> ?}
>
> -static void led_stop_software_blink(struct led_classdev *led_cdev)
> -{
> - ? ? ? /* deactivate previous settings */
> - ? ? ? del_timer_sync(&led_cdev->blink_timer);
> - ? ? ? led_cdev->blink_delay_on = 0;
> - ? ? ? led_cdev->blink_delay_off = 0;
> -}
> -
> -static void led_set_software_blink(struct led_classdev *led_cdev,
> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?unsigned long delay_on,
> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?unsigned long delay_off)
> -{
> - ? ? ? int current_brightness;
> -
> - ? ? ? current_brightness = led_get_brightness(led_cdev);
> - ? ? ? if (current_brightness)
> - ? ? ? ? ? ? ? led_cdev->blink_brightness = current_brightness;
> - ? ? ? if (!led_cdev->blink_brightness)
> - ? ? ? ? ? ? ? led_cdev->blink_brightness = led_cdev->max_brightness;
> -
> - ? ? ? if (led_get_trigger_data(led_cdev) &&
> - ? ? ? ? ? delay_on == led_cdev->blink_delay_on &&
> - ? ? ? ? ? delay_off == led_cdev->blink_delay_off)
> - ? ? ? ? ? ? ? return;
> -
> - ? ? ? led_stop_software_blink(led_cdev);
> -
> - ? ? ? led_cdev->blink_delay_on = delay_on;
> - ? ? ? led_cdev->blink_delay_off = delay_off;
> -
> - ? ? ? /* never on - don't blink */
> - ? ? ? if (!delay_on)
> - ? ? ? ? ? ? ? return;
> -
> - ? ? ? /* never off - just set to brightness */
> - ? ? ? if (!delay_off) {
> - ? ? ? ? ? ? ? led_set_brightness(led_cdev, led_cdev->blink_brightness);
> - ? ? ? ? ? ? ? return;
> - ? ? ? }
> -
> - ? ? ? mod_timer(&led_cdev->blink_timer, jiffies + 1);
> -}
> -
> -
> ?/**
> ?* led_classdev_suspend - suspend an led_classdev.
> ?* @led_cdev: the led_classdev to suspend.
> @@ -262,32 +218,6 @@ void led_classdev_unregister(struct led_classdev *led_cdev)
> ?}
> ?EXPORT_SYMBOL_GPL(led_classdev_unregister);
>
> -void led_blink_set(struct led_classdev *led_cdev,
> - ? ? ? ? ? ? ? ? ?unsigned long *delay_on,
> - ? ? ? ? ? ? ? ? ?unsigned long *delay_off)
> -{
> - ? ? ? del_timer_sync(&led_cdev->blink_timer);
> -
> - ? ? ? if (led_cdev->blink_set &&
> - ? ? ? ? ? !led_cdev->blink_set(led_cdev, delay_on, delay_off))
> - ? ? ? ? ? ? ? return;
> -
> - ? ? ? /* blink with 1 Hz as default if nothing specified */
> - ? ? ? if (!*delay_on && !*delay_off)
> - ? ? ? ? ? ? ? *delay_on = *delay_off = 500;
> -
> - ? ? ? led_set_software_blink(led_cdev, *delay_on, *delay_off);
> -}
> -EXPORT_SYMBOL(led_blink_set);
> -
> -void led_brightness_set(struct led_classdev *led_cdev,
> - ? ? ? ? ? ? ? ? ? ? ? enum led_brightness brightness)
> -{
> - ? ? ? led_stop_software_blink(led_cdev);
> - ? ? ? led_cdev->brightness_set(led_cdev, brightness);
> -}
> -EXPORT_SYMBOL(led_brightness_set);
> -
> ?static int __init leds_init(void)
> ?{
> ? ? ? ?leds_class = class_create(THIS_MODULE, "leds");
> diff --git a/drivers/leds/led-core.c b/drivers/leds/led-core.c
> index 016d19f..d686004 100644
> --- a/drivers/leds/led-core.c
> +++ b/drivers/leds/led-core.c
> @@ -23,3 +23,73 @@ EXPORT_SYMBOL_GPL(leds_list_lock);
>
> ?LIST_HEAD(leds_list);
> ?EXPORT_SYMBOL_GPL(leds_list);
> +
> +static void led_stop_software_blink(struct led_classdev *led_cdev)
> +{
> + ? ? ? /* deactivate previous settings */
> + ? ? ? del_timer_sync(&led_cdev->blink_timer);
> + ? ? ? led_cdev->blink_delay_on = 0;
> + ? ? ? led_cdev->blink_delay_off = 0;
> +}
> +
> +static void led_set_software_blink(struct led_classdev *led_cdev,
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?unsigned long delay_on,
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?unsigned long delay_off)
> +{
> + ? ? ? int current_brightness;
> +
> + ? ? ? current_brightness = led_get_brightness(led_cdev);
> + ? ? ? if (current_brightness)
> + ? ? ? ? ? ? ? led_cdev->blink_brightness = current_brightness;
> + ? ? ? if (!led_cdev->blink_brightness)
> + ? ? ? ? ? ? ? led_cdev->blink_brightness = led_cdev->max_brightness;
> +
> + ? ? ? if (led_get_trigger_data(led_cdev) &&
> + ? ? ? ? ? delay_on == led_cdev->blink_delay_on &&
> + ? ? ? ? ? delay_off == led_cdev->blink_delay_off)
> + ? ? ? ? ? ? ? return;
> +
> + ? ? ? led_stop_software_blink(led_cdev);
> +
> + ? ? ? led_cdev->blink_delay_on = delay_on;
> + ? ? ? led_cdev->blink_delay_off = delay_off;
> +
> + ? ? ? /* never on - don't blink */
> + ? ? ? if (!delay_on)
> + ? ? ? ? ? ? ? return;
> +
> + ? ? ? /* never off - just set to brightness */
> + ? ? ? if (!delay_off) {
> + ? ? ? ? ? ? ? led_set_brightness(led_cdev, led_cdev->blink_brightness);
> + ? ? ? ? ? ? ? return;
> + ? ? ? }
> +
> + ? ? ? mod_timer(&led_cdev->blink_timer, jiffies + 1);
> +}
> +
> +
> +void led_blink_set(struct led_classdev *led_cdev,
> + ? ? ? ? ? ? ? ? ?unsigned long *delay_on,
> + ? ? ? ? ? ? ? ? ?unsigned long *delay_off)
> +{
> + ? ? ? del_timer_sync(&led_cdev->blink_timer);
> +
> + ? ? ? if (led_cdev->blink_set &&
> + ? ? ? ? ? !led_cdev->blink_set(led_cdev, delay_on, delay_off))
> + ? ? ? ? ? ? ? return;
> +
> + ? ? ? /* blink with 1 Hz as default if nothing specified */
> + ? ? ? if (!*delay_on && !*delay_off)
> + ? ? ? ? ? ? ? *delay_on = *delay_off = 500;
> +
> + ? ? ? led_set_software_blink(led_cdev, *delay_on, *delay_off);
> +}
> +EXPORT_SYMBOL(led_blink_set);
> +
> +void led_brightness_set(struct led_classdev *led_cdev,
> + ? ? ? ? ? ? ? ? ? ? ? enum led_brightness brightness)
> +{
> + ? ? ? led_stop_software_blink(led_cdev);
> + ? ? ? led_cdev->brightness_set(led_cdev, brightness);
> +}
> +EXPORT_SYMBOL(led_brightness_set);
> --
> 1.7.9
>
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
--
Bryan Wu <bryan.wu@canonical.com>
Kernel Developer ? ?+86.138-1617-6545 Mobile
Ubuntu ARM Team
Canonical Ltd. ? ? ?www.canonical.com
Ubuntu - Linux for human beings | www.ubuntu.com
^ permalink raw reply [flat|nested] 14+ messages in thread* [PATCH 1/3] led-class: change back LEDS_CLASS to tristate instead of bool
2012-03-08 9:11 [PATCH 1/3] led-class: change back LEDS_CLASS to tristate instead of bool Bryan Wu
` (2 preceding siblings ...)
2012-03-11 7:45 ` [PATCH 1/3] led-class: change back LEDS_CLASS to tristate instead of bool Bryan Wu
@ 2012-03-11 13:13 ` Richard Purdie
2012-03-12 2:32 ` Bryan Wu
2012-03-12 19:35 ` Linus Walleij
4 siblings, 1 reply; 14+ messages in thread
From: Richard Purdie @ 2012-03-11 13:13 UTC (permalink / raw)
To: linux-arm-kernel
On Thu, 2012-03-08 at 17:11 +0800, Bryan Wu wrote:
> After moving some core functions to led-core.c, led-class.c can be built as
> module again.
>
> Signed-off-by: Bryan Wu <bryan.wu@canonical.com>
I'd prefer to have less code being required in led-core.c but this is
better than many of the alternatives. I'm happy to see it becoming
modular again, thanks!
Acked-by: Richard Purdie <richard.purdie@linuxfoundation.org>
> ---
> drivers/leds/Kconfig | 2 +-
> drivers/leds/led-class.c | 70 ----------------------------------------------
> drivers/leds/led-core.c | 70 ++++++++++++++++++++++++++++++++++++++++++++++
> 3 files changed, 71 insertions(+), 71 deletions(-)
>
> diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig
> index 9ca28fc..3f17f0d 100644
> --- a/drivers/leds/Kconfig
> +++ b/drivers/leds/Kconfig
> @@ -17,7 +17,7 @@ menuconfig NEW_LEDS
> if NEW_LEDS
>
> config LEDS_CLASS
> - bool "LED Class Support"
> + tristate "LED Class Support"
> help
> This option enables the led sysfs class in /sys/class/leds. You'll
> need this to do anything useful with LEDs. If unsure, say N.
> diff --git a/drivers/leds/led-class.c b/drivers/leds/led-class.c
> index 0c8739c..5bff843 100644
> --- a/drivers/leds/led-class.c
> +++ b/drivers/leds/led-class.c
> @@ -110,50 +110,6 @@ static void led_timer_function(unsigned long data)
> mod_timer(&led_cdev->blink_timer, jiffies + msecs_to_jiffies(delay));
> }
>
> -static void led_stop_software_blink(struct led_classdev *led_cdev)
> -{
> - /* deactivate previous settings */
> - del_timer_sync(&led_cdev->blink_timer);
> - led_cdev->blink_delay_on = 0;
> - led_cdev->blink_delay_off = 0;
> -}
> -
> -static void led_set_software_blink(struct led_classdev *led_cdev,
> - unsigned long delay_on,
> - unsigned long delay_off)
> -{
> - int current_brightness;
> -
> - current_brightness = led_get_brightness(led_cdev);
> - if (current_brightness)
> - led_cdev->blink_brightness = current_brightness;
> - if (!led_cdev->blink_brightness)
> - led_cdev->blink_brightness = led_cdev->max_brightness;
> -
> - if (led_get_trigger_data(led_cdev) &&
> - delay_on == led_cdev->blink_delay_on &&
> - delay_off == led_cdev->blink_delay_off)
> - return;
> -
> - led_stop_software_blink(led_cdev);
> -
> - led_cdev->blink_delay_on = delay_on;
> - led_cdev->blink_delay_off = delay_off;
> -
> - /* never on - don't blink */
> - if (!delay_on)
> - return;
> -
> - /* never off - just set to brightness */
> - if (!delay_off) {
> - led_set_brightness(led_cdev, led_cdev->blink_brightness);
> - return;
> - }
> -
> - mod_timer(&led_cdev->blink_timer, jiffies + 1);
> -}
> -
> -
> /**
> * led_classdev_suspend - suspend an led_classdev.
> * @led_cdev: the led_classdev to suspend.
> @@ -262,32 +218,6 @@ void led_classdev_unregister(struct led_classdev *led_cdev)
> }
> EXPORT_SYMBOL_GPL(led_classdev_unregister);
>
> -void led_blink_set(struct led_classdev *led_cdev,
> - unsigned long *delay_on,
> - unsigned long *delay_off)
> -{
> - del_timer_sync(&led_cdev->blink_timer);
> -
> - if (led_cdev->blink_set &&
> - !led_cdev->blink_set(led_cdev, delay_on, delay_off))
> - return;
> -
> - /* blink with 1 Hz as default if nothing specified */
> - if (!*delay_on && !*delay_off)
> - *delay_on = *delay_off = 500;
> -
> - led_set_software_blink(led_cdev, *delay_on, *delay_off);
> -}
> -EXPORT_SYMBOL(led_blink_set);
> -
> -void led_brightness_set(struct led_classdev *led_cdev,
> - enum led_brightness brightness)
> -{
> - led_stop_software_blink(led_cdev);
> - led_cdev->brightness_set(led_cdev, brightness);
> -}
> -EXPORT_SYMBOL(led_brightness_set);
> -
> static int __init leds_init(void)
> {
> leds_class = class_create(THIS_MODULE, "leds");
> diff --git a/drivers/leds/led-core.c b/drivers/leds/led-core.c
> index 016d19f..d686004 100644
> --- a/drivers/leds/led-core.c
> +++ b/drivers/leds/led-core.c
> @@ -23,3 +23,73 @@ EXPORT_SYMBOL_GPL(leds_list_lock);
>
> LIST_HEAD(leds_list);
> EXPORT_SYMBOL_GPL(leds_list);
> +
> +static void led_stop_software_blink(struct led_classdev *led_cdev)
> +{
> + /* deactivate previous settings */
> + del_timer_sync(&led_cdev->blink_timer);
> + led_cdev->blink_delay_on = 0;
> + led_cdev->blink_delay_off = 0;
> +}
> +
> +static void led_set_software_blink(struct led_classdev *led_cdev,
> + unsigned long delay_on,
> + unsigned long delay_off)
> +{
> + int current_brightness;
> +
> + current_brightness = led_get_brightness(led_cdev);
> + if (current_brightness)
> + led_cdev->blink_brightness = current_brightness;
> + if (!led_cdev->blink_brightness)
> + led_cdev->blink_brightness = led_cdev->max_brightness;
> +
> + if (led_get_trigger_data(led_cdev) &&
> + delay_on == led_cdev->blink_delay_on &&
> + delay_off == led_cdev->blink_delay_off)
> + return;
> +
> + led_stop_software_blink(led_cdev);
> +
> + led_cdev->blink_delay_on = delay_on;
> + led_cdev->blink_delay_off = delay_off;
> +
> + /* never on - don't blink */
> + if (!delay_on)
> + return;
> +
> + /* never off - just set to brightness */
> + if (!delay_off) {
> + led_set_brightness(led_cdev, led_cdev->blink_brightness);
> + return;
> + }
> +
> + mod_timer(&led_cdev->blink_timer, jiffies + 1);
> +}
> +
> +
> +void led_blink_set(struct led_classdev *led_cdev,
> + unsigned long *delay_on,
> + unsigned long *delay_off)
> +{
> + del_timer_sync(&led_cdev->blink_timer);
> +
> + if (led_cdev->blink_set &&
> + !led_cdev->blink_set(led_cdev, delay_on, delay_off))
> + return;
> +
> + /* blink with 1 Hz as default if nothing specified */
> + if (!*delay_on && !*delay_off)
> + *delay_on = *delay_off = 500;
> +
> + led_set_software_blink(led_cdev, *delay_on, *delay_off);
> +}
> +EXPORT_SYMBOL(led_blink_set);
> +
> +void led_brightness_set(struct led_classdev *led_cdev,
> + enum led_brightness brightness)
> +{
> + led_stop_software_blink(led_cdev);
> + led_cdev->brightness_set(led_cdev, brightness);
> +}
> +EXPORT_SYMBOL(led_brightness_set);
^ permalink raw reply [flat|nested] 14+ messages in thread* [PATCH 1/3] led-class: change back LEDS_CLASS to tristate instead of bool
2012-03-11 13:13 ` Richard Purdie
@ 2012-03-12 2:32 ` Bryan Wu
0 siblings, 0 replies; 14+ messages in thread
From: Bryan Wu @ 2012-03-12 2:32 UTC (permalink / raw)
To: linux-arm-kernel
On Sun, Mar 11, 2012 at 9:13 PM, Richard Purdie
<richard.purdie@linuxfoundation.org> wrote:
> On Thu, 2012-03-08 at 17:11 +0800, Bryan Wu wrote:
>> After moving some core functions to led-core.c, led-class.c can be built as
>> module again.
>>
>> Signed-off-by: Bryan Wu <bryan.wu@canonical.com>
>
> I'd prefer to have less code being required in led-core.c but this is
> better than many of the alternatives. I'm happy to see it becoming
> modular again, thanks!
>
> Acked-by: Richard Purdie <richard.purdie@linuxfoundation.org>
>
Great, Thank you very much.
-Bryan
>> ---
>> ?drivers/leds/Kconfig ? ? | ? ?2 +-
>> ?drivers/leds/led-class.c | ? 70 ----------------------------------------------
>> ?drivers/leds/led-core.c ?| ? 70 ++++++++++++++++++++++++++++++++++++++++++++++
>> ?3 files changed, 71 insertions(+), 71 deletions(-)
>>
>> diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig
>> index 9ca28fc..3f17f0d 100644
>> --- a/drivers/leds/Kconfig
>> +++ b/drivers/leds/Kconfig
>> @@ -17,7 +17,7 @@ menuconfig NEW_LEDS
>> ?if NEW_LEDS
>>
>> ?config LEDS_CLASS
>> - ? ? bool "LED Class Support"
>> + ? ? tristate "LED Class Support"
>> ? ? ? help
>> ? ? ? ? This option enables the led sysfs class in /sys/class/leds. ?You'll
>> ? ? ? ? need this to do anything useful with LEDs. ?If unsure, say N.
>> diff --git a/drivers/leds/led-class.c b/drivers/leds/led-class.c
>> index 0c8739c..5bff843 100644
>> --- a/drivers/leds/led-class.c
>> +++ b/drivers/leds/led-class.c
>> @@ -110,50 +110,6 @@ static void led_timer_function(unsigned long data)
>> ? ? ? mod_timer(&led_cdev->blink_timer, jiffies + msecs_to_jiffies(delay));
>> ?}
>>
>> -static void led_stop_software_blink(struct led_classdev *led_cdev)
>> -{
>> - ? ? /* deactivate previous settings */
>> - ? ? del_timer_sync(&led_cdev->blink_timer);
>> - ? ? led_cdev->blink_delay_on = 0;
>> - ? ? led_cdev->blink_delay_off = 0;
>> -}
>> -
>> -static void led_set_software_blink(struct led_classdev *led_cdev,
>> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?unsigned long delay_on,
>> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?unsigned long delay_off)
>> -{
>> - ? ? int current_brightness;
>> -
>> - ? ? current_brightness = led_get_brightness(led_cdev);
>> - ? ? if (current_brightness)
>> - ? ? ? ? ? ? led_cdev->blink_brightness = current_brightness;
>> - ? ? if (!led_cdev->blink_brightness)
>> - ? ? ? ? ? ? led_cdev->blink_brightness = led_cdev->max_brightness;
>> -
>> - ? ? if (led_get_trigger_data(led_cdev) &&
>> - ? ? ? ? delay_on == led_cdev->blink_delay_on &&
>> - ? ? ? ? delay_off == led_cdev->blink_delay_off)
>> - ? ? ? ? ? ? return;
>> -
>> - ? ? led_stop_software_blink(led_cdev);
>> -
>> - ? ? led_cdev->blink_delay_on = delay_on;
>> - ? ? led_cdev->blink_delay_off = delay_off;
>> -
>> - ? ? /* never on - don't blink */
>> - ? ? if (!delay_on)
>> - ? ? ? ? ? ? return;
>> -
>> - ? ? /* never off - just set to brightness */
>> - ? ? if (!delay_off) {
>> - ? ? ? ? ? ? led_set_brightness(led_cdev, led_cdev->blink_brightness);
>> - ? ? ? ? ? ? return;
>> - ? ? }
>> -
>> - ? ? mod_timer(&led_cdev->blink_timer, jiffies + 1);
>> -}
>> -
>> -
>> ?/**
>> ? * led_classdev_suspend - suspend an led_classdev.
>> ? * @led_cdev: the led_classdev to suspend.
>> @@ -262,32 +218,6 @@ void led_classdev_unregister(struct led_classdev *led_cdev)
>> ?}
>> ?EXPORT_SYMBOL_GPL(led_classdev_unregister);
>>
>> -void led_blink_set(struct led_classdev *led_cdev,
>> - ? ? ? ? ? ? ? ?unsigned long *delay_on,
>> - ? ? ? ? ? ? ? ?unsigned long *delay_off)
>> -{
>> - ? ? del_timer_sync(&led_cdev->blink_timer);
>> -
>> - ? ? if (led_cdev->blink_set &&
>> - ? ? ? ? !led_cdev->blink_set(led_cdev, delay_on, delay_off))
>> - ? ? ? ? ? ? return;
>> -
>> - ? ? /* blink with 1 Hz as default if nothing specified */
>> - ? ? if (!*delay_on && !*delay_off)
>> - ? ? ? ? ? ? *delay_on = *delay_off = 500;
>> -
>> - ? ? led_set_software_blink(led_cdev, *delay_on, *delay_off);
>> -}
>> -EXPORT_SYMBOL(led_blink_set);
>> -
>> -void led_brightness_set(struct led_classdev *led_cdev,
>> - ? ? ? ? ? ? ? ? ? ? enum led_brightness brightness)
>> -{
>> - ? ? led_stop_software_blink(led_cdev);
>> - ? ? led_cdev->brightness_set(led_cdev, brightness);
>> -}
>> -EXPORT_SYMBOL(led_brightness_set);
>> -
>> ?static int __init leds_init(void)
>> ?{
>> ? ? ? leds_class = class_create(THIS_MODULE, "leds");
>> diff --git a/drivers/leds/led-core.c b/drivers/leds/led-core.c
>> index 016d19f..d686004 100644
>> --- a/drivers/leds/led-core.c
>> +++ b/drivers/leds/led-core.c
>> @@ -23,3 +23,73 @@ EXPORT_SYMBOL_GPL(leds_list_lock);
>>
>> ?LIST_HEAD(leds_list);
>> ?EXPORT_SYMBOL_GPL(leds_list);
>> +
>> +static void led_stop_software_blink(struct led_classdev *led_cdev)
>> +{
>> + ? ? /* deactivate previous settings */
>> + ? ? del_timer_sync(&led_cdev->blink_timer);
>> + ? ? led_cdev->blink_delay_on = 0;
>> + ? ? led_cdev->blink_delay_off = 0;
>> +}
>> +
>> +static void led_set_software_blink(struct led_classdev *led_cdev,
>> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?unsigned long delay_on,
>> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?unsigned long delay_off)
>> +{
>> + ? ? int current_brightness;
>> +
>> + ? ? current_brightness = led_get_brightness(led_cdev);
>> + ? ? if (current_brightness)
>> + ? ? ? ? ? ? led_cdev->blink_brightness = current_brightness;
>> + ? ? if (!led_cdev->blink_brightness)
>> + ? ? ? ? ? ? led_cdev->blink_brightness = led_cdev->max_brightness;
>> +
>> + ? ? if (led_get_trigger_data(led_cdev) &&
>> + ? ? ? ? delay_on == led_cdev->blink_delay_on &&
>> + ? ? ? ? delay_off == led_cdev->blink_delay_off)
>> + ? ? ? ? ? ? return;
>> +
>> + ? ? led_stop_software_blink(led_cdev);
>> +
>> + ? ? led_cdev->blink_delay_on = delay_on;
>> + ? ? led_cdev->blink_delay_off = delay_off;
>> +
>> + ? ? /* never on - don't blink */
>> + ? ? if (!delay_on)
>> + ? ? ? ? ? ? return;
>> +
>> + ? ? /* never off - just set to brightness */
>> + ? ? if (!delay_off) {
>> + ? ? ? ? ? ? led_set_brightness(led_cdev, led_cdev->blink_brightness);
>> + ? ? ? ? ? ? return;
>> + ? ? }
>> +
>> + ? ? mod_timer(&led_cdev->blink_timer, jiffies + 1);
>> +}
>> +
>> +
>> +void led_blink_set(struct led_classdev *led_cdev,
>> + ? ? ? ? ? ? ? ?unsigned long *delay_on,
>> + ? ? ? ? ? ? ? ?unsigned long *delay_off)
>> +{
>> + ? ? del_timer_sync(&led_cdev->blink_timer);
>> +
>> + ? ? if (led_cdev->blink_set &&
>> + ? ? ? ? !led_cdev->blink_set(led_cdev, delay_on, delay_off))
>> + ? ? ? ? ? ? return;
>> +
>> + ? ? /* blink with 1 Hz as default if nothing specified */
>> + ? ? if (!*delay_on && !*delay_off)
>> + ? ? ? ? ? ? *delay_on = *delay_off = 500;
>> +
>> + ? ? led_set_software_blink(led_cdev, *delay_on, *delay_off);
>> +}
>> +EXPORT_SYMBOL(led_blink_set);
>> +
>> +void led_brightness_set(struct led_classdev *led_cdev,
>> + ? ? ? ? ? ? ? ? ? ? enum led_brightness brightness)
>> +{
>> + ? ? led_stop_software_blink(led_cdev);
>> + ? ? led_cdev->brightness_set(led_cdev, brightness);
>> +}
>> +EXPORT_SYMBOL(led_brightness_set);
>
>
--
Bryan Wu <bryan.wu@canonical.com>
Kernel Developer ? ?+86.138-1617-6545 Mobile
Canonical Ltd. ? ? ?www.canonical.com
Ubuntu - Linux for human beings | www.ubuntu.com
^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH 1/3] led-class: change back LEDS_CLASS to tristate instead of bool
2012-03-08 9:11 [PATCH 1/3] led-class: change back LEDS_CLASS to tristate instead of bool Bryan Wu
` (3 preceding siblings ...)
2012-03-11 13:13 ` Richard Purdie
@ 2012-03-12 19:35 ` Linus Walleij
4 siblings, 0 replies; 14+ messages in thread
From: Linus Walleij @ 2012-03-12 19:35 UTC (permalink / raw)
To: linux-arm-kernel
On Thu, Mar 8, 2012 at 10:11 AM, Bryan Wu <bryan.wu@canonical.com> wrote:
> After moving some core functions to led-core.c, led-class.c can be built as
> module again.
>
> Signed-off-by: Bryan Wu <bryan.wu@canonical.com>
Thanks for driving this Bryan,
Acked-by: Linus Walleij <linus.walleij@linaro.org>
Yours,
Linus Walleij
^ permalink raw reply [flat|nested] 14+ messages in thread