* [PATCH] SMU LED driver
@ 2006-12-24 11:23 Michael Hanselmann
2006-12-25 21:25 ` Benjamin Herrenschmidt
0 siblings, 1 reply; 8+ messages in thread
From: Michael Hanselmann @ 2006-12-24 11:23 UTC (permalink / raw)
To: benh; +Cc: linuxppc-dev, johannes
This patch adds a driver for the front LED in recent PowerMacs which
have an SMU.
Signed-off-by: Michael Hanselmann <linux-kernel@hansmi.ch>
---
diff -Nrup --exclude-from linux-exclude-from linux-2.6.19.1.orig/drivers/macintosh/Kconfig linux-2.6.19.1/drivers/macintosh/Kconfig
--- linux-2.6.19.1.orig/drivers/macintosh/Kconfig 2006-12-24 12:19:05.000000000 +0100
+++ linux-2.6.19.1/drivers/macintosh/Kconfig 2006-12-24 12:19:41.000000000 +0100
@@ -107,6 +107,15 @@ config PMAC_SMU
on the "SMU" system control chip which replaces the old PMU.
If you don't know, say Y.
+config PMAC_SMU_LED
+ tristate "Support for the PowerMac front LED"
+ depends on PMAC_SMU
+ select NEW_LEDS
+ select LEDS_CLASS
+ help
+ Support the front LED on PowerMacs as a generic LED that can be
+ triggered by any of the supported triggers.
+
config PMAC_APM_EMU
tristate "APM emulation"
depends on PPC_PMAC && PPC32 && PM && ADB_PMU
diff -Nrup --exclude-from linux-exclude-from linux-2.6.19.1.orig/drivers/macintosh/Makefile linux-2.6.19.1/drivers/macintosh/Makefile
--- linux-2.6.19.1.orig/drivers/macintosh/Makefile 2006-12-24 12:19:05.000000000 +0100
+++ linux-2.6.19.1/drivers/macintosh/Makefile 2006-12-24 12:19:24.000000000 +0100
@@ -17,6 +17,7 @@ obj-$(CONFIG_PMAC_BACKLIGHT) += via-pmu-
obj-$(CONFIG_ADB_CUDA) += via-cuda.o
obj-$(CONFIG_PMAC_APM_EMU) += apm_emu.o
obj-$(CONFIG_PMAC_SMU) += smu.o
+obj-$(CONFIG_PMAC_SMU_LED) += smu-led.o
obj-$(CONFIG_ADB) += adb.o
obj-$(CONFIG_ADB_MACII) += via-macii.o
diff -Nrup --exclude-from linux-exclude-from linux-2.6.19.1.orig/drivers/macintosh/smu-led.c linux-2.6.19.1/drivers/macintosh/smu-led.c
--- linux-2.6.19.1.orig/drivers/macintosh/smu-led.c 1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.19.1/drivers/macintosh/smu-led.c 2006-12-24 12:19:24.000000000 +0100
@@ -0,0 +1,91 @@
+/*
+ * smu LED class device
+ *
+ * Copyright 2006 Michael Hanselmann <linux-kernel@hansmi.ch>
+ *
+ * This code is based upon via-pmu-led, written by Johannes Berg, and a sample
+ * program written by Benjamin Herrenschmidt.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/device.h>
+#include <linux/leds.h>
+#include <asm/smu.h>
+
+static void smu_led_set(struct led_classdev *led_cdev,
+ enum led_brightness brightness)
+{
+ struct smu_simple_cmd cmd;
+ DECLARE_COMPLETION_ONSTACK(comp);
+ unsigned int value;
+ int rc;
+
+ switch (brightness) {
+ case LED_OFF:
+ value = 0;
+ break;
+
+ case LED_FULL:
+ value = 1;
+ break;
+
+ default:
+ return;
+ }
+
+ rc = smu_queue_simple(&cmd, SMU_CMD_MISC_ee_COMMAND, 3,
+ smu_done_complete, &comp,
+ SMU_CMD_MISC_ee_LEDS_CTRL, 0x00, value);
+ if (rc) {
+ printk(KERN_ERR "smu-led: "
+ "Queueing failed, error %d\n", rc);
+ return;
+ }
+
+ wait_for_completion(&comp);
+
+ if (cmd.cmd.status != 0) {
+ printk(KERN_ERR "smu-led: Setting LED value failed\n");
+ return;
+ }
+}
+
+static struct led_classdev smu_led = {
+ .name = "smu-front-led",
+ .brightness_set = smu_led_set,
+};
+
+static int __init smu_led_init(void)
+{
+ if (!smu_present())
+ return -ENODEV;
+
+ return led_classdev_register(NULL, &smu_led);
+}
+
+static void __exit smu_led_exit(void)
+{
+}
+
+module_init(smu_led_init);
+module_exit(smu_led_exit);
+
+MODULE_AUTHOR("Michael Hanselmann <linux-kernel@hansmi.ch>");
+MODULE_DESCRIPTION("Front LED support for SMU based PowerMacs");
+MODULE_LICENSE("GPL");
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH] SMU LED driver
2006-12-24 11:23 [PATCH] SMU LED driver Michael Hanselmann
@ 2006-12-25 21:25 ` Benjamin Herrenschmidt
2006-12-26 22:38 ` Johannes Berg
2007-01-06 21:19 ` Michael Hanselmann
0 siblings, 2 replies; 8+ messages in thread
From: Benjamin Herrenschmidt @ 2006-12-25 21:25 UTC (permalink / raw)
To: Michael Hanselmann; +Cc: linuxppc-dev, johannes
On Sun, 2006-12-24 at 12:23 +0100, Michael Hanselmann wrote:
> This patch adds a driver for the front LED in recent PowerMacs which
> have an SMU.
As for the PMU driver, I'm pretty unhappy that it sycnhronously waits
for the completion. The original code I wrote was fully asynchronous.
Ben.
> Signed-off-by: Michael Hanselmann <linux-kernel@hansmi.ch>
>
> ---
> diff -Nrup --exclude-from linux-exclude-from linux-2.6.19.1.orig/drivers/macintosh/Kconfig linux-2.6.19.1/drivers/macintosh/Kconfig
> --- linux-2.6.19.1.orig/drivers/macintosh/Kconfig 2006-12-24 12:19:05.000000000 +0100
> +++ linux-2.6.19.1/drivers/macintosh/Kconfig 2006-12-24 12:19:41.000000000 +0100
> @@ -107,6 +107,15 @@ config PMAC_SMU
> on the "SMU" system control chip which replaces the old PMU.
> If you don't know, say Y.
>
> +config PMAC_SMU_LED
> + tristate "Support for the PowerMac front LED"
> + depends on PMAC_SMU
> + select NEW_LEDS
> + select LEDS_CLASS
> + help
> + Support the front LED on PowerMacs as a generic LED that can be
> + triggered by any of the supported triggers.
> +
> config PMAC_APM_EMU
> tristate "APM emulation"
> depends on PPC_PMAC && PPC32 && PM && ADB_PMU
> diff -Nrup --exclude-from linux-exclude-from linux-2.6.19.1.orig/drivers/macintosh/Makefile linux-2.6.19.1/drivers/macintosh/Makefile
> --- linux-2.6.19.1.orig/drivers/macintosh/Makefile 2006-12-24 12:19:05.000000000 +0100
> +++ linux-2.6.19.1/drivers/macintosh/Makefile 2006-12-24 12:19:24.000000000 +0100
> @@ -17,6 +17,7 @@ obj-$(CONFIG_PMAC_BACKLIGHT) += via-pmu-
> obj-$(CONFIG_ADB_CUDA) += via-cuda.o
> obj-$(CONFIG_PMAC_APM_EMU) += apm_emu.o
> obj-$(CONFIG_PMAC_SMU) += smu.o
> +obj-$(CONFIG_PMAC_SMU_LED) += smu-led.o
>
> obj-$(CONFIG_ADB) += adb.o
> obj-$(CONFIG_ADB_MACII) += via-macii.o
> diff -Nrup --exclude-from linux-exclude-from linux-2.6.19.1.orig/drivers/macintosh/smu-led.c linux-2.6.19.1/drivers/macintosh/smu-led.c
> --- linux-2.6.19.1.orig/drivers/macintosh/smu-led.c 1970-01-01 01:00:00.000000000 +0100
> +++ linux-2.6.19.1/drivers/macintosh/smu-led.c 2006-12-24 12:19:24.000000000 +0100
> @@ -0,0 +1,91 @@
> +/*
> + * smu LED class device
> + *
> + * Copyright 2006 Michael Hanselmann <linux-kernel@hansmi.ch>
> + *
> + * This code is based upon via-pmu-led, written by Johannes Berg, and a sample
> + * program written by Benjamin Herrenschmidt.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful, but
> + * WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
> + * NON INFRINGEMENT. See the GNU General Public License for more
> + * details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
> + */
> +
> +#include <linux/types.h>
> +#include <linux/kernel.h>
> +#include <linux/device.h>
> +#include <linux/leds.h>
> +#include <asm/smu.h>
> +
> +static void smu_led_set(struct led_classdev *led_cdev,
> + enum led_brightness brightness)
> +{
> + struct smu_simple_cmd cmd;
> + DECLARE_COMPLETION_ONSTACK(comp);
> + unsigned int value;
> + int rc;
> +
> + switch (brightness) {
> + case LED_OFF:
> + value = 0;
> + break;
> +
> + case LED_FULL:
> + value = 1;
> + break;
> +
> + default:
> + return;
> + }
> +
> + rc = smu_queue_simple(&cmd, SMU_CMD_MISC_ee_COMMAND, 3,
> + smu_done_complete, &comp,
> + SMU_CMD_MISC_ee_LEDS_CTRL, 0x00, value);
> + if (rc) {
> + printk(KERN_ERR "smu-led: "
> + "Queueing failed, error %d\n", rc);
> + return;
> + }
> +
> + wait_for_completion(&comp);
> +
> + if (cmd.cmd.status != 0) {
> + printk(KERN_ERR "smu-led: Setting LED value failed\n");
> + return;
> + }
> +}
> +
> +static struct led_classdev smu_led = {
> + .name = "smu-front-led",
> + .brightness_set = smu_led_set,
> +};
> +
> +static int __init smu_led_init(void)
> +{
> + if (!smu_present())
> + return -ENODEV;
> +
> + return led_classdev_register(NULL, &smu_led);
> +}
> +
> +static void __exit smu_led_exit(void)
> +{
> +}
> +
> +module_init(smu_led_init);
> +module_exit(smu_led_exit);
> +
> +MODULE_AUTHOR("Michael Hanselmann <linux-kernel@hansmi.ch>");
> +MODULE_DESCRIPTION("Front LED support for SMU based PowerMacs");
> +MODULE_LICENSE("GPL");
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH] SMU LED driver
2006-12-25 21:25 ` Benjamin Herrenschmidt
@ 2006-12-26 22:38 ` Johannes Berg
2007-01-06 21:19 ` Michael Hanselmann
1 sibling, 0 replies; 8+ messages in thread
From: Johannes Berg @ 2006-12-26 22:38 UTC (permalink / raw)
To: Benjamin Herrenschmidt; +Cc: linuxppc-dev
[-- Attachment #1: Type: text/plain, Size: 450 bytes --]
On Tue, 2006-12-26 at 08:25 +1100, Benjamin Herrenschmidt wrote:
> On Sun, 2006-12-24 at 12:23 +0100, Michael Hanselmann wrote:
> > This patch adds a driver for the front LED in recent PowerMacs which
> > have an SMU.
>
> As for the PMU driver, I'm pretty unhappy that it sycnhronously waits
> for the completion. The original code I wrote was fully asynchronous.
That'd be my code. I can see if I can somehow get rid of that.
johannes
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 190 bytes --]
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH] SMU LED driver
2006-12-25 21:25 ` Benjamin Herrenschmidt
2006-12-26 22:38 ` Johannes Berg
@ 2007-01-06 21:19 ` Michael Hanselmann
2007-01-08 1:02 ` Benjamin Herrenschmidt
1 sibling, 1 reply; 8+ messages in thread
From: Michael Hanselmann @ 2007-01-06 21:19 UTC (permalink / raw)
To: Benjamin Herrenschmidt; +Cc: linuxppc-dev, johannes, linux-kernel
[-- Attachment #1: Type: text/plain, Size: 5358 bytes --]
On Tue, Dec 26, 2006 at 08:25:52AM +1100, Benjamin Herrenschmidt wrote:
> On Sun, 2006-12-24 at 12:23 +0100, Michael Hanselmann wrote:
> > This patch adds a driver for the front LED in recent PowerMacs which
> > have an SMU.
> As for the PMU driver, I'm pretty unhappy that it sycnhronously waits
> for the completion. The original code I wrote was fully asynchronous.
Unfortunately, I can't see another way than doing it synchronously when
one shouldn't use kmalloc(). The command (struct smu_simple_cmd) is kept
on the stack. It contains the buffer used for both sending and
retrieving data to/from the SMU. Making it module-global wouldn't work,
because one request could conflict with another. struct smu_cmd can't be
locked, so we can't check or wait for the status like via-pmu-led does.
So, what should I do?
On another note, it seems like the PMU LED driver is already
asynchronous.
Signed-off-by: Michael Hanselmann <linux-kernel@hansmi.ch>
---
diff -Nrup --exclude-from linux-exclude-from linux-2.6.19.1.orig/drivers/macintosh/Kconfig linux-2.6.19.1/drivers/macintosh/Kconfig
--- linux-2.6.19.1.orig/drivers/macintosh/Kconfig 2007-01-06 00:47:14.000000000 +0100
+++ linux-2.6.19.1/drivers/macintosh/Kconfig 2007-01-06 01:06:59.000000000 +0100
@@ -107,6 +107,15 @@ config PMAC_SMU
on the "SMU" system control chip which replaces the old PMU.
If you don't know, say Y.
+config PMAC_SMU_LED
+ tristate "Support for the PowerMac front LED"
+ depends on PMAC_SMU
+ select NEW_LEDS
+ select LEDS_CLASS
+ help
+ Support the front LED on PowerMacs as a generic LED that can be
+ triggered by any of the supported triggers.
+
config PMAC_APM_EMU
tristate "APM emulation"
depends on PPC_PMAC && PPC32 && PM && ADB_PMU
diff -Nrup --exclude-from linux-exclude-from linux-2.6.19.1.orig/drivers/macintosh/Makefile linux-2.6.19.1/drivers/macintosh/Makefile
--- linux-2.6.19.1.orig/drivers/macintosh/Makefile 2007-01-06 00:47:14.000000000 +0100
+++ linux-2.6.19.1/drivers/macintosh/Makefile 2007-01-06 01:06:59.000000000 +0100
@@ -17,6 +17,7 @@ obj-$(CONFIG_PMAC_BACKLIGHT) += via-pmu-
obj-$(CONFIG_ADB_CUDA) += via-cuda.o
obj-$(CONFIG_PMAC_APM_EMU) += apm_emu.o
obj-$(CONFIG_PMAC_SMU) += smu.o
+obj-$(CONFIG_PMAC_SMU_LED) += smu-led.o
obj-$(CONFIG_ADB) += adb.o
obj-$(CONFIG_ADB_MACII) += via-macii.o
diff -Nrup --exclude-from linux-exclude-from linux-2.6.19.1.orig/drivers/macintosh/smu-led.c linux-2.6.19.1/drivers/macintosh/smu-led.c
--- linux-2.6.19.1.orig/drivers/macintosh/smu-led.c 1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.19.1/drivers/macintosh/smu-led.c 2007-01-06 03:23:30.000000000 +0100
@@ -0,0 +1,97 @@
+/*
+ * smu LED class device
+ *
+ * Copyright 2006 Michael Hanselmann <linux-kernel@hansmi.ch>
+ *
+ * This code is based upon via-pmu-led, written by Johannes Berg, and a sample
+ * program written by Benjamin Herrenschmidt.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/device.h>
+#include <linux/leds.h>
+#include <asm/smu.h>
+
+static void smu_led_set(struct led_classdev *led_cdev,
+ enum led_brightness brightness)
+{
+ DECLARE_COMPLETION_ONSTACK(comp);
+ struct smu_simple_cmd cmd;
+ unsigned int value;
+ int rc;
+
+ /* As of now, this driver can't reset the LED to its default half
+ * bright status (LED_HALF) because we don't know for sure how to
+ * switch back into that mode.
+ */
+
+ switch (brightness) {
+ case LED_OFF:
+ value = 0x00;
+ break;
+
+ case LED_FULL:
+ value = 0x01;
+ break;
+
+ default:
+ return;
+ }
+
+ rc = smu_queue_simple(&cmd, SMU_CMD_MISC_ee_COMMAND, 3,
+ smu_done_complete, &comp,
+ SMU_CMD_MISC_ee_LEDS_CTRL, 0x00, value);
+ if (rc) {
+ printk(KERN_ERR "smu-led: "
+ "Command queueing failed, error %d\n", rc);
+ return;
+ }
+
+ wait_for_completion(&comp);
+
+ if (cmd.cmd.status) {
+ printk(KERN_ERR "smu-led: SMU command failed\n");
+ return;
+ }
+}
+
+static struct led_classdev smu_led = {
+ .name = "smu-front-led",
+ .brightness_set = smu_led_set,
+};
+
+static int __init smu_led_init(void)
+{
+ if (!smu_present())
+ return -ENODEV;
+
+ return led_classdev_register(NULL, &smu_led);
+}
+
+static void __exit smu_led_exit(void)
+{
+ led_classdev_unregister(&smu_led);
+}
+
+module_init(smu_led_init);
+module_exit(smu_led_exit);
+
+MODULE_AUTHOR("Michael Hanselmann <linux-kernel@hansmi.ch>");
+MODULE_DESCRIPTION("Front LED support for SMU based PowerMacs");
+MODULE_LICENSE("GPL");
[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH] SMU LED driver
2007-01-06 21:19 ` Michael Hanselmann
@ 2007-01-08 1:02 ` Benjamin Herrenschmidt
2007-01-14 13:31 ` Michael Hanselmann
0 siblings, 1 reply; 8+ messages in thread
From: Benjamin Herrenschmidt @ 2007-01-08 1:02 UTC (permalink / raw)
To: Michael Hanselmann; +Cc: linuxppc-dev, johannes, linux-kernel
On Sat, 2007-01-06 at 22:19 +0100, Michael Hanselmann wrote:
> On Tue, Dec 26, 2006 at 08:25:52AM +1100, Benjamin Herrenschmidt wrote:
> > On Sun, 2006-12-24 at 12:23 +0100, Michael Hanselmann wrote:
> > > This patch adds a driver for the front LED in recent PowerMacs which
> > > have an SMU.
>
> > As for the PMU driver, I'm pretty unhappy that it sycnhronously waits
> > for the completion. The original code I wrote was fully asynchronous.
>
> Unfortunately, I can't see another way than doing it synchronously when
> one shouldn't use kmalloc(). The command (struct smu_simple_cmd) is kept
> on the stack. It contains the buffer used for both sending and
> retrieving data to/from the SMU. Making it module-global wouldn't work,
> because one request could conflict with another. struct smu_cmd can't be
> locked, so we can't check or wait for the status like via-pmu-led does.
> So, what should I do?
>
> On another note, it seems like the PMU LED driver is already
> asynchronous.
Just have 1 request allocated once for all. Then, have a global set to
what status you want the LED at. Once the completion of any request
arrives, if the new status is different from what you want, send a new
one to fix it up :-)
That's the easy way.
The old PMU code did something more subtle because it was based on the
assumption that the LED was used to emit "pulses" based on HD activity.
Ben.
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH] SMU LED driver
2007-01-08 1:02 ` Benjamin Herrenschmidt
@ 2007-01-14 13:31 ` Michael Hanselmann
2007-01-14 21:48 ` Benjamin Herrenschmidt
0 siblings, 1 reply; 8+ messages in thread
From: Michael Hanselmann @ 2007-01-14 13:31 UTC (permalink / raw)
To: Benjamin Herrenschmidt; +Cc: linuxppc-dev, johannes, linux-kernel
[-- Attachment #1: Type: text/plain, Size: 5723 bytes --]
On Mon, Jan 08, 2007 at 12:02:45PM +1100, Benjamin Herrenschmidt wrote:
> Just have 1 request allocated once for all. Then, have a global set to
> what status you want the LED at. Once the completion of any request
> arrives, if the new status is different from what you want, send a new
> one to fix it up :-)
Implemented that. See below.
There's a race condition between setting the LED value and unloading the
module. smu_led_exit can't return an error. Is it possible to prevent
unloading the module while an SMU request is still running, and if yes,
how?
Signed-off-by: Michael Hanselmann <linux-kernel@hansmi.ch>
---
diff -Nrup --exclude-from linux-exclude-from linux-2.6.19.1.orig/drivers/macintosh/Kconfig linux-2.6.19.1/drivers/macintosh/Kconfig
--- linux-2.6.19.1.orig/drivers/macintosh/Kconfig 2007-01-14 12:58:25.000000000 +0100
+++ linux-2.6.19.1/drivers/macintosh/Kconfig 2007-01-14 13:03:49.000000000 +0100
@@ -107,6 +107,15 @@ config PMAC_SMU
on the "SMU" system control chip which replaces the old PMU.
If you don't know, say Y.
+config PMAC_SMU_LED
+ tristate "Support for the PowerMac front LED"
+ depends on PMAC_SMU
+ select NEW_LEDS
+ select LEDS_CLASS
+ help
+ Support the front LED on PowerMacs as a generic LED that can be
+ triggered by any of the supported triggers.
+
config PMAC_APM_EMU
tristate "APM emulation"
depends on PPC_PMAC && PPC32 && PM && ADB_PMU
diff -Nrup --exclude-from linux-exclude-from linux-2.6.19.1.orig/drivers/macintosh/Makefile linux-2.6.19.1/drivers/macintosh/Makefile
--- linux-2.6.19.1.orig/drivers/macintosh/Makefile 2007-01-14 12:58:25.000000000 +0100
+++ linux-2.6.19.1/drivers/macintosh/Makefile 2007-01-14 13:03:49.000000000 +0100
@@ -17,6 +17,7 @@ obj-$(CONFIG_PMAC_BACKLIGHT) += via-pmu-
obj-$(CONFIG_ADB_CUDA) += via-cuda.o
obj-$(CONFIG_PMAC_APM_EMU) += apm_emu.o
obj-$(CONFIG_PMAC_SMU) += smu.o
+obj-$(CONFIG_PMAC_SMU_LED) += smu-led.o
obj-$(CONFIG_ADB) += adb.o
obj-$(CONFIG_ADB_MACII) += via-macii.o
diff -Nrup --exclude-from linux-exclude-from linux-2.6.19.1.orig/drivers/macintosh/smu-led.c linux-2.6.19.1/drivers/macintosh/smu-led.c
--- linux-2.6.19.1.orig/drivers/macintosh/smu-led.c 1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.19.1/drivers/macintosh/smu-led.c 2007-01-14 14:25:03.000000000 +0100
@@ -0,0 +1,132 @@
+/*
+ * smu LED class device
+ *
+ * Copyright 2006, 2007 Michael Hanselmann <linux-kernel@hansmi.ch>
+ *
+ * This code is based upon via-pmu-led, written by Johannes Berg, and a sample
+ * program written by Benjamin Herrenschmidt.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/device.h>
+#include <linux/leds.h>
+#include <linux/spinlock.h>
+#include <asm/smu.h>
+
+static DEFINE_SPINLOCK(lock);
+static struct smu_simple_cmd cmd;
+static unsigned char cmd_value;
+static int wanted = -1;
+
+static void __smu_led_set(struct led_classdev*, unsigned char);
+
+static void smu_led_done(struct smu_cmd *cmd, void *misc)
+{
+ struct led_classdev *led_cdev = misc;
+
+ if (cmd->status) {
+ printk(KERN_ERR "smu-led: SMU command failed\n");
+ }
+
+ spin_lock(&lock);
+
+ if (wanted != -1) {
+ if (cmd_value == wanted)
+ wanted = -1;
+ else
+ __smu_led_set(led_cdev, wanted);
+ }
+
+ spin_unlock(&lock);
+}
+
+/* Call with lock held */
+static void __smu_led_set(struct led_classdev *led_cdev,
+ unsigned char value)
+{
+ int rc;
+
+ cmd_value = value;
+ rc = smu_queue_simple(&cmd, SMU_CMD_MISC_ee_COMMAND, 3,
+ smu_led_done, led_cdev,
+ SMU_CMD_MISC_ee_LEDS_CTRL, 0x00, value);
+ if (rc) {
+ printk(KERN_ERR "smu-led: "
+ "Command queueing failed, error %d\n", rc);
+ }
+}
+
+static void smu_led_set(struct led_classdev *led_cdev,
+ enum led_brightness brightness)
+{
+ unsigned char value;
+
+ /* Setting the LED to its default half bright status isn't possible
+ * yet. Reason is that we don't know for sure how to do it.
+ */
+
+ switch (brightness) {
+ case LED_OFF:
+ value = 0x00;
+ break;
+
+ case LED_FULL:
+ value = 0x01;
+ break;
+
+ default:
+ /* Unknown brightness, do nothing */
+ return;
+ }
+
+ spin_lock(&lock);
+
+ if (wanted == -1) {
+ wanted = value;
+ __smu_led_set(led_cdev, value);
+ } else
+ wanted = value;
+
+ spin_unlock(&lock);
+}
+
+static struct led_classdev smu_led = {
+ .name = "smu-front-led",
+ .brightness_set = smu_led_set,
+};
+
+static int __init smu_led_init(void)
+{
+ if (!smu_present())
+ return -ENODEV;
+
+ return led_classdev_register(NULL, &smu_led);
+}
+
+static void __exit smu_led_exit(void)
+{
+ led_classdev_unregister(&smu_led);
+}
+
+module_init(smu_led_init);
+module_exit(smu_led_exit);
+
+MODULE_AUTHOR("Michael Hanselmann <linux-kernel@hansmi.ch>");
+MODULE_DESCRIPTION("Front LED support for SMU based PowerMacs");
+MODULE_LICENSE("GPL");
[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH] SMU LED driver
2007-01-14 13:31 ` Michael Hanselmann
@ 2007-01-14 21:48 ` Benjamin Herrenschmidt
2007-01-15 0:26 ` Michael Hanselmann
0 siblings, 1 reply; 8+ messages in thread
From: Benjamin Herrenschmidt @ 2007-01-14 21:48 UTC (permalink / raw)
To: Michael Hanselmann; +Cc: linuxppc-dev, johannes, linux-kernel
On Sun, 2007-01-14 at 14:31 +0100, Michael Hanselmann wrote:
> On Mon, Jan 08, 2007 at 12:02:45PM +1100, Benjamin Herrenschmidt wrote:
> > Just have 1 request allocated once for all. Then, have a global set to
> > what status you want the LED at. Once the completion of any request
> > arrives, if the new status is different from what you want, send a new
> > one to fix it up :-)
>
> Implemented that. See below.
>
> There's a race condition between setting the LED value and unloading the
> module. smu_led_exit can't return an error. Is it possible to prevent
> unloading the module while an SMU request is still running, and if yes,
> how?
No, you have to deal with it in the unload. You can for example wait for
the SMU request to complete after setting wanted to -1, that sort of
thing.
Also, use spin_lock_irqsave/restore or you'll deadlock if the SMU
completion interrupt happens to interrupt your request function.
Ben.
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH] SMU LED driver
2007-01-14 21:48 ` Benjamin Herrenschmidt
@ 2007-01-15 0:26 ` Michael Hanselmann
0 siblings, 0 replies; 8+ messages in thread
From: Michael Hanselmann @ 2007-01-15 0:26 UTC (permalink / raw)
To: Benjamin Herrenschmidt; +Cc: linuxppc-dev, johannes, linux-kernel
[-- Attachment #1: Type: text/plain, Size: 6024 bytes --]
On Mon, Jan 15, 2007 at 08:48:59AM +1100, Benjamin Herrenschmidt wrote:
> No, you have to deal with it in the unload. You can for example wait for
> the SMU request to complete after setting wanted to -1, that sort of
> thing.
Done in the patch below.
> Also, use spin_lock_irqsave/restore or you'll deadlock if the SMU
> completion interrupt happens to interrupt your request function.
Okay, didn't notice the done function is called in interrupt context.
Signed-off-by: Michael Hanselmann <linux-kernel@hansmi.ch>
---
diff -Nrup --exclude-from linux-exclude-from linux-2.6.19.1.orig/drivers/macintosh/Kconfig linux-2.6.19.1/drivers/macintosh/Kconfig
--- linux-2.6.19.1.orig/drivers/macintosh/Kconfig 2007-01-14 12:58:25.000000000 +0100
+++ linux-2.6.19.1/drivers/macintosh/Kconfig 2007-01-15 00:57:16.000000000 +0100
@@ -107,6 +107,15 @@ config PMAC_SMU
on the "SMU" system control chip which replaces the old PMU.
If you don't know, say Y.
+config PMAC_SMU_LED
+ tristate "Support for the PowerMac front LED"
+ depends on PMAC_SMU
+ select NEW_LEDS
+ select LEDS_CLASS
+ help
+ Support the front LED on PowerMacs as a generic LED that can be
+ triggered by any of the supported triggers.
+
config PMAC_APM_EMU
tristate "APM emulation"
depends on PPC_PMAC && PPC32 && PM && ADB_PMU
diff -Nrup --exclude-from linux-exclude-from linux-2.6.19.1.orig/drivers/macintosh/Makefile linux-2.6.19.1/drivers/macintosh/Makefile
--- linux-2.6.19.1.orig/drivers/macintosh/Makefile 2007-01-14 12:58:25.000000000 +0100
+++ linux-2.6.19.1/drivers/macintosh/Makefile 2007-01-15 00:57:16.000000000 +0100
@@ -17,6 +17,7 @@ obj-$(CONFIG_PMAC_BACKLIGHT) += via-pmu-
obj-$(CONFIG_ADB_CUDA) += via-cuda.o
obj-$(CONFIG_PMAC_APM_EMU) += apm_emu.o
obj-$(CONFIG_PMAC_SMU) += smu.o
+obj-$(CONFIG_PMAC_SMU_LED) += smu-led.o
obj-$(CONFIG_ADB) += adb.o
obj-$(CONFIG_ADB_MACII) += via-macii.o
diff -Nrup --exclude-from linux-exclude-from linux-2.6.19.1.orig/drivers/macintosh/smu-led.c linux-2.6.19.1/drivers/macintosh/smu-led.c
--- linux-2.6.19.1.orig/drivers/macintosh/smu-led.c 1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.19.1/drivers/macintosh/smu-led.c 2007-01-15 01:19:11.000000000 +0100
@@ -0,0 +1,147 @@
+/*
+ * smu LED class device
+ *
+ * Copyright 2006, 2007 Michael Hanselmann <linux-kernel@hansmi.ch>
+ *
+ * This code is based upon via-pmu-led, written by Johannes Berg, and a sample
+ * program written by Benjamin Herrenschmidt.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/device.h>
+#include <linux/leds.h>
+#include <linux/spinlock.h>
+#include <asm/smu.h>
+
+static DEFINE_SPINLOCK(lock);
+static struct smu_simple_cmd cmd;
+static unsigned char cmd_value;
+static int wanted = -1;
+
+static void __smu_led_set(struct led_classdev*, unsigned char);
+
+static void smu_led_done(struct smu_cmd *cmd, void *misc)
+{
+ struct led_classdev *led_cdev = misc;
+ unsigned long flags;
+
+ if (cmd->status) {
+ printk(KERN_ERR "smu-led: SMU command failed\n");
+ }
+
+ spin_lock_irqsave(&lock, flags);
+
+ if (wanted != -1) {
+ if (cmd_value == wanted)
+ wanted = -1;
+ else
+ __smu_led_set(led_cdev, wanted);
+ }
+
+ spin_unlock_irqrestore(&lock, flags);
+}
+
+/* Call with lock held */
+static void __smu_led_set(struct led_classdev *led_cdev,
+ unsigned char value)
+{
+ int rc;
+
+ cmd_value = value;
+ rc = smu_queue_simple(&cmd, SMU_CMD_MISC_ee_COMMAND, 3,
+ smu_led_done, led_cdev,
+ SMU_CMD_MISC_ee_LEDS_CTRL, 0x00, value);
+ if (rc) {
+ printk(KERN_ERR "smu-led: "
+ "Command queueing failed, error %d\n", rc);
+ }
+}
+
+static void smu_led_set(struct led_classdev *led_cdev,
+ enum led_brightness brightness)
+{
+ unsigned long flags;
+ unsigned char value;
+
+ /* Setting the LED to its default half bright status isn't possible
+ * yet. Reason is that we don't know for sure how to do it.
+ */
+
+ switch (brightness) {
+ case LED_OFF:
+ value = 0x00;
+ break;
+
+ case LED_FULL:
+ value = 0x01;
+ break;
+
+ default:
+ /* Unknown brightness, do nothing */
+ return;
+ }
+
+ spin_lock_irqsave(&lock, flags);
+
+ if (wanted == -1) {
+ wanted = value;
+ __smu_led_set(led_cdev, value);
+ } else
+ wanted = value;
+
+ spin_unlock_irqrestore(&lock, flags);
+}
+
+static struct led_classdev smu_led = {
+ .name = "smu-front-led",
+ .brightness_set = smu_led_set,
+};
+
+static int __init smu_led_init(void)
+{
+ if (!smu_present())
+ return -ENODEV;
+
+ return led_classdev_register(NULL, &smu_led);
+}
+
+static void __exit smu_led_exit(void)
+{
+ unsigned long flags;
+
+ led_classdev_unregister(&smu_led);
+
+ spin_lock_irqsave(&lock, flags);
+ while (wanted != -1) {
+ spin_unlock_irqrestore(&lock, flags);
+
+ /* Wait for pending request */
+ smu_spinwait_cmd(&cmd.cmd);
+
+ spin_lock_irqsave(&lock, flags);
+ }
+ spin_unlock_irqrestore(&lock, flags);
+}
+
+module_init(smu_led_init);
+module_exit(smu_led_exit);
+
+MODULE_AUTHOR("Michael Hanselmann <linux-kernel@hansmi.ch>");
+MODULE_DESCRIPTION("Front LED support for SMU based PowerMacs");
+MODULE_LICENSE("GPL");
[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2007-01-15 0:26 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-12-24 11:23 [PATCH] SMU LED driver Michael Hanselmann
2006-12-25 21:25 ` Benjamin Herrenschmidt
2006-12-26 22:38 ` Johannes Berg
2007-01-06 21:19 ` Michael Hanselmann
2007-01-08 1:02 ` Benjamin Herrenschmidt
2007-01-14 13:31 ` Michael Hanselmann
2007-01-14 21:48 ` Benjamin Herrenschmidt
2007-01-15 0:26 ` Michael Hanselmann
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).