diff options
author | Pierre Ossman <drzeus@drzeus.cx> | 2008-03-17 05:29:38 -0400 |
---|---|---|
committer | Pierre Ossman <drzeus@drzeus.cx> | 2008-04-18 14:05:27 -0400 |
commit | 2f730fec83be76f1b3b8f0066b3447f55c50d7a0 (patch) | |
tree | 1535e9ae05511c44feea173b1c2fd935d1945ae3 /drivers/mmc | |
parent | b69c9058907642f8e1b32076906755c6623ea060 (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.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 71e020d6718d..6250eb5f98a8 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c | |||
@@ -19,6 +19,8 @@ | |||
19 | #include <linux/dma-mapping.h> | 19 | #include <linux/dma-mapping.h> |
20 | #include <linux/scatterlist.h> | 20 | #include <linux/scatterlist.h> |
21 | 21 | ||
22 | #include <linux/leds.h> | ||
23 | |||
22 | #include <linux/mmc/host.h> | 24 | #include <linux/mmc/host.h> |
23 | 25 | ||
24 | #include "sdhci.h" | 26 | #include "sdhci.h" |
@@ -252,6 +254,24 @@ static void sdhci_deactivate_led(struct sdhci_host *host) | |||
252 | writeb(ctrl, host->ioaddr + SDHCI_HOST_CONTROL); | 254 | writeb(ctrl, host->ioaddr + SDHCI_HOST_CONTROL); |
253 | } | 255 | } |
254 | 256 | ||
257 | #ifdef CONFIG_LEDS_CLASS | ||
258 | static void sdhci_led_control(struct led_classdev *led, | ||
259 | enum led_brightness brightness) | ||
260 | { | ||
261 | struct sdhci_host *host = container_of(led, struct sdhci_host, led); | ||
262 | unsigned long flags; | ||
263 | |||
264 | spin_lock_irqsave(&host->lock, flags); | ||
265 | |||
266 | if (brightness == LED_OFF) | ||
267 | sdhci_deactivate_led(host); | ||
268 | else | ||
269 | sdhci_activate_led(host); | ||
270 | |||
271 | spin_unlock_irqrestore(&host->lock, flags); | ||
272 | } | ||
273 | #endif | ||
274 | |||
255 | /*****************************************************************************\ | 275 | /*****************************************************************************\ |
256 | * * | 276 | * * |
257 | * Core functions * | 277 | * Core functions * |
@@ -769,7 +789,9 @@ static void sdhci_request(struct mmc_host *mmc, struct mmc_request *mrq) | |||
769 | 789 | ||
770 | WARN_ON(host->mrq != NULL); | 790 | WARN_ON(host->mrq != NULL); |
771 | 791 | ||
792 | #ifndef CONFIG_LEDS_CLASS | ||
772 | sdhci_activate_led(host); | 793 | sdhci_activate_led(host); |
794 | #endif | ||
773 | 795 | ||
774 | host->mrq = mrq; | 796 | host->mrq = mrq; |
775 | 797 | ||
@@ -961,7 +983,9 @@ static void sdhci_tasklet_finish(unsigned long param) | |||
961 | host->cmd = NULL; | 983 | host->cmd = NULL; |
962 | host->data = NULL; | 984 | host->data = NULL; |
963 | 985 | ||
986 | #ifndef CONFIG_LEDS_CLASS | ||
964 | sdhci_deactivate_led(host); | 987 | sdhci_deactivate_led(host); |
988 | #endif | ||
965 | 989 | ||
966 | mmiowb(); | 990 | mmiowb(); |
967 | spin_unlock_irqrestore(&host->lock, flags); | 991 | spin_unlock_irqrestore(&host->lock, flags); |
@@ -1485,6 +1509,17 @@ static int __devinit sdhci_probe_slot(struct pci_dev *pdev, int slot) | |||
1485 | sdhci_dumpregs(host); | 1509 | sdhci_dumpregs(host); |
1486 | #endif | 1510 | #endif |
1487 | 1511 | ||
1512 | #ifdef CONFIG_LEDS_CLASS | ||
1513 | host->led.name = mmc_hostname(mmc); | ||
1514 | host->led.brightness = LED_OFF; | ||
1515 | host->led.default_trigger = mmc_hostname(mmc); | ||
1516 | host->led.brightness_set = sdhci_led_control; | ||
1517 | |||
1518 | ret = led_classdev_register(&pdev->dev, &host->led); | ||
1519 | if (ret) | ||
1520 | goto reset; | ||
1521 | #endif | ||
1522 | |||
1488 | mmiowb(); | 1523 | mmiowb(); |
1489 | 1524 | ||
1490 | mmc_add_host(mmc); | 1525 | mmc_add_host(mmc); |
@@ -1495,6 +1530,11 @@ static int __devinit sdhci_probe_slot(struct pci_dev *pdev, int slot) | |||
1495 | 1530 | ||
1496 | return 0; | 1531 | return 0; |
1497 | 1532 | ||
1533 | #ifdef CONFIG_LEDS_CLASS | ||
1534 | reset: | ||
1535 | sdhci_reset(host, SDHCI_RESET_ALL); | ||
1536 | free_irq(host->irq, host); | ||
1537 | #endif | ||
1498 | untasklet: | 1538 | untasklet: |
1499 | tasklet_kill(&host->card_tasklet); | 1539 | tasklet_kill(&host->card_tasklet); |
1500 | tasklet_kill(&host->finish_tasklet); | 1540 | tasklet_kill(&host->finish_tasklet); |
@@ -1522,6 +1562,10 @@ static void sdhci_remove_slot(struct pci_dev *pdev, int slot) | |||
1522 | 1562 | ||
1523 | mmc_remove_host(mmc); | 1563 | mmc_remove_host(mmc); |
1524 | 1564 | ||
1565 | #ifdef CONFIG_LEDS_CLASS | ||
1566 | led_classdev_unregister(&host->led); | ||
1567 | #endif | ||
1568 | |||
1525 | sdhci_reset(host, SDHCI_RESET_ALL); | 1569 | sdhci_reset(host, SDHCI_RESET_ALL); |
1526 | 1570 | ||
1527 | free_irq(host->irq, host); | 1571 | free_irq(host->irq, host); |
diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h index 3288e209ba44..7fb02e177a3d 100644 --- a/drivers/mmc/host/sdhci.h +++ b/drivers/mmc/host/sdhci.h | |||
@@ -168,6 +168,10 @@ struct sdhci_host { | |||
168 | struct sdhci_chip *chip; | 168 | struct sdhci_chip *chip; |
169 | struct mmc_host *mmc; /* MMC structure */ | 169 | struct mmc_host *mmc; /* MMC structure */ |
170 | 170 | ||
171 | #ifdef CONFIG_LEDS_CLASS | ||
172 | struct led_classdev led; /* LED control */ | ||
173 | #endif | ||
174 | |||
171 | spinlock_t lock; /* Mutex */ | 175 | spinlock_t lock; /* Mutex */ |
172 | 176 | ||
173 | int flags; /* Host attributes */ | 177 | int flags; /* Host attributes */ |