diff options
author | Pierre Ossman <drzeus@drzeus.cx> | 2008-03-17 10:29:38 +0100 |
---|---|---|
committer | Pierre Ossman <drzeus@drzeus.cx> | 2008-04-18 20:05:27 +0200 |
commit | 2f730fec83be76f1b3b8f0066b3447f55c50d7a0 (patch) | |
tree | 1535e9ae05511c44feea173b1c2fd935d1945ae3 | |
parent | b69c9058907642f8e1b32076906755c6623ea060 (diff) | |
download | op-kernel-dev-2f730fec83be76f1b3b8f0066b3447f55c50d7a0.zip op-kernel-dev-2f730fec83be76f1b3b8f0066b3447f55c50d7a0.tar.gz |
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>
-rw-r--r-- | drivers/mmc/host/sdhci.c | 44 | ||||
-rw-r--r-- | drivers/mmc/host/sdhci.h | 4 |
2 files changed, 48 insertions, 0 deletions
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index 71e020d6..6250eb5 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 3288e209..7fb02e1 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 */ |