From 2f730fec83be76f1b3b8f0066b3447f55c50d7a0 Mon Sep 17 00:00:00 2001 From: Pierre Ossman Date: Mon, 17 Mar 2008 10:29:38 +0100 Subject: [PATCH] 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 --- drivers/mmc/host/sdhci.c | 44 ++++++++++++++++++++++++++++++++++++++++ drivers/mmc/host/sdhci.h | 4 ++++ 2 files changed, 48 insertions(+) diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index 71e020d671..6250eb5f98 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c @@ -19,6 +19,8 @@ #include #include +#include + #include #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 3288e209ba..7fb02e177a 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 */ -- 2.39.5