summaryrefslogtreecommitdiffstats
path: root/drivers/mmc
diff options
context:
space:
mode:
authorPierre Ossman <drzeus@drzeus.cx>2008-03-17 10:29:38 +0100
committerPierre Ossman <drzeus@drzeus.cx>2008-04-18 20:05:27 +0200
commit2f730fec83be76f1b3b8f0066b3447f55c50d7a0 (patch)
tree1535e9ae05511c44feea173b1c2fd935d1945ae3 /drivers/mmc
parentb69c9058907642f8e1b32076906755c6623ea060 (diff)
sdhci: allow led to be controlled freely
Hook up the controller LED to the LED subsystem, allowing more flexible control than simply indicating an ongoing request. Signed-off-by: Pierre Ossman <drzeus@drzeus.cx>
Diffstat (limited to 'drivers/mmc')
-rw-r--r--drivers/mmc/host/sdhci.c44
-rw-r--r--drivers/mmc/host/sdhci.h4
2 files changed, 48 insertions, 0 deletions
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index 71e020d6718..6250eb5f98a 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -19,6 +19,8 @@
#include <linux/dma-mapping.h>
#include <linux/scatterlist.h>
+#include <linux/leds.h>
+
#include <linux/mmc/host.h>
#include "sdhci.h"
@@ -252,6 +254,24 @@ static void sdhci_deactivate_led(struct sdhci_host *host)
writeb(ctrl, host->ioaddr + SDHCI_HOST_CONTROL);
}
+#ifdef CONFIG_LEDS_CLASS
+static void sdhci_led_control(struct led_classdev *led,
+ enum led_brightness brightness)
+{
+ struct sdhci_host *host = container_of(led, struct sdhci_host, led);
+ unsigned long flags;
+
+ spin_lock_irqsave(&host->lock, flags);
+
+ if (brightness == LED_OFF)
+ sdhci_deactivate_led(host);
+ else
+ sdhci_activate_led(host);
+
+ spin_unlock_irqrestore(&host->lock, flags);
+}
+#endif
+
/*****************************************************************************\
* *
* Core functions *
@@ -769,7 +789,9 @@ static void sdhci_request(struct mmc_host *mmc, struct mmc_request *mrq)
WARN_ON(host->mrq != NULL);
+#ifndef CONFIG_LEDS_CLASS
sdhci_activate_led(host);
+#endif
host->mrq = mrq;
@@ -961,7 +983,9 @@ static void sdhci_tasklet_finish(unsigned long param)
host->cmd = NULL;
host->data = NULL;
+#ifndef CONFIG_LEDS_CLASS
sdhci_deactivate_led(host);
+#endif
mmiowb();
spin_unlock_irqrestore(&host->lock, flags);
@@ -1485,6 +1509,17 @@ static int __devinit sdhci_probe_slot(struct pci_dev *pdev, int slot)
sdhci_dumpregs(host);
#endif
+#ifdef CONFIG_LEDS_CLASS
+ host->led.name = mmc_hostname(mmc);
+ host->led.brightness = LED_OFF;
+ host->led.default_trigger = mmc_hostname(mmc);
+ host->led.brightness_set = sdhci_led_control;
+
+ ret = led_classdev_register(&pdev->dev, &host->led);
+ if (ret)
+ goto reset;
+#endif
+
mmiowb();
mmc_add_host(mmc);
@@ -1495,6 +1530,11 @@ static int __devinit sdhci_probe_slot(struct pci_dev *pdev, int slot)
return 0;
+#ifdef CONFIG_LEDS_CLASS
+reset:
+ sdhci_reset(host, SDHCI_RESET_ALL);
+ free_irq(host->irq, host);
+#endif
untasklet:
tasklet_kill(&host->card_tasklet);
tasklet_kill(&host->finish_tasklet);
@@ -1522,6 +1562,10 @@ static void sdhci_remove_slot(struct pci_dev *pdev, int slot)
mmc_remove_host(mmc);
+#ifdef CONFIG_LEDS_CLASS
+ led_classdev_unregister(&host->led);
+#endif
+
sdhci_reset(host, SDHCI_RESET_ALL);
free_irq(host->irq, host);
diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h
index 3288e209ba4..7fb02e177a3 100644
--- a/drivers/mmc/host/sdhci.h
+++ b/drivers/mmc/host/sdhci.h
@@ -168,6 +168,10 @@ struct sdhci_host {
struct sdhci_chip *chip;
struct mmc_host *mmc; /* MMC structure */
+#ifdef CONFIG_LEDS_CLASS
+ struct led_classdev led; /* LED control */
+#endif
+
spinlock_t lock; /* Mutex */
int flags; /* Host attributes */