From: Michael Hanselmann <linux-kernel@hansmi.ch>
To: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: linuxppc-dev@ozlabs.org, johannes@sipsolutions.net,
linux-kernel@killerfox.forkbomb.ch
Subject: Re: [PATCH] SMU LED driver
Date: Mon, 15 Jan 2007 01:26:17 +0100 [thread overview]
Message-ID: <20070115002617.GA29698@hansmi.ch> (raw)
In-Reply-To: <1168811339.4803.23.camel@localhost.localdomain>
[-- 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 --]
prev parent reply other threads:[~2007-01-15 0:26 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
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 message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20070115002617.GA29698@hansmi.ch \
--to=linux-kernel@hansmi.ch \
--cc=benh@kernel.crashing.org \
--cc=johannes@sipsolutions.net \
--cc=linux-kernel@killerfox.forkbomb.ch \
--cc=linuxppc-dev@ozlabs.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.