diff options
author | Daniel Drake <dsd@laptop.org> | 2010-11-04 18:20:39 -0400 |
---|---|---|
committer | Chris Ball <cjb@laptop.org> | 2010-11-07 16:45:11 -0500 |
commit | 5f619704d18b93869d045abc49e09cdba109b04b (patch) | |
tree | 50d523926d50bac76448fea6ab25c1e118537e06 | |
parent | 14d4031d21d8a63ad84e5ab9198d0503efabc780 (diff) |
mmc: sdhci: Properly enable SDIO IRQ wakeups
A little more work was needed for SDIO IRQ wakeups to be functional.
Wake-on-WLAN on the SD WiFi adapter in the XO-1.5 laptop is now working.
Signed-off-by: Daniel Drake <dsd@laptop.org>
Signed-off-by: Chris Ball <cjb@laptop.org>
-rw-r--r-- | drivers/mmc/host/sdhci-pci.c | 11 | ||||
-rw-r--r-- | drivers/mmc/host/sdhci.c | 10 | ||||
-rw-r--r-- | drivers/mmc/host/sdhci.h | 4 |
3 files changed, 23 insertions, 2 deletions
diff --git a/drivers/mmc/host/sdhci-pci.c b/drivers/mmc/host/sdhci-pci.c index 55746bac2f44..d196e77a93dc 100644 --- a/drivers/mmc/host/sdhci-pci.c +++ b/drivers/mmc/host/sdhci-pci.c | |||
@@ -637,6 +637,7 @@ static int sdhci_pci_suspend (struct pci_dev *pdev, pm_message_t state) | |||
637 | { | 637 | { |
638 | struct sdhci_pci_chip *chip; | 638 | struct sdhci_pci_chip *chip; |
639 | struct sdhci_pci_slot *slot; | 639 | struct sdhci_pci_slot *slot; |
640 | mmc_pm_flag_t slot_pm_flags; | ||
640 | mmc_pm_flag_t pm_flags = 0; | 641 | mmc_pm_flag_t pm_flags = 0; |
641 | int i, ret; | 642 | int i, ret; |
642 | 643 | ||
@@ -657,7 +658,11 @@ static int sdhci_pci_suspend (struct pci_dev *pdev, pm_message_t state) | |||
657 | return ret; | 658 | return ret; |
658 | } | 659 | } |
659 | 660 | ||
660 | pm_flags |= slot->host->mmc->pm_flags; | 661 | slot_pm_flags = slot->host->mmc->pm_flags; |
662 | if (slot_pm_flags & MMC_PM_WAKE_SDIO_IRQ) | ||
663 | sdhci_enable_irq_wakeups(slot->host); | ||
664 | |||
665 | pm_flags |= slot_pm_flags; | ||
661 | } | 666 | } |
662 | 667 | ||
663 | if (chip->fixes && chip->fixes->suspend) { | 668 | if (chip->fixes && chip->fixes->suspend) { |
@@ -671,8 +676,10 @@ static int sdhci_pci_suspend (struct pci_dev *pdev, pm_message_t state) | |||
671 | 676 | ||
672 | pci_save_state(pdev); | 677 | pci_save_state(pdev); |
673 | if (pm_flags & MMC_PM_KEEP_POWER) { | 678 | if (pm_flags & MMC_PM_KEEP_POWER) { |
674 | if (pm_flags & MMC_PM_WAKE_SDIO_IRQ) | 679 | if (pm_flags & MMC_PM_WAKE_SDIO_IRQ) { |
680 | pci_pme_active(pdev, true); | ||
675 | pci_enable_wake(pdev, PCI_D3hot, 1); | 681 | pci_enable_wake(pdev, PCI_D3hot, 1); |
682 | } | ||
676 | pci_set_power_state(pdev, PCI_D3hot); | 683 | pci_set_power_state(pdev, PCI_D3hot); |
677 | } else { | 684 | } else { |
678 | pci_enable_wake(pdev, pci_choose_state(pdev, state), 0); | 685 | pci_enable_wake(pdev, pci_choose_state(pdev, state), 0); |
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index 782c0ee3c925..154cbf83c1ab 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c | |||
@@ -1681,6 +1681,16 @@ int sdhci_resume_host(struct sdhci_host *host) | |||
1681 | 1681 | ||
1682 | EXPORT_SYMBOL_GPL(sdhci_resume_host); | 1682 | EXPORT_SYMBOL_GPL(sdhci_resume_host); |
1683 | 1683 | ||
1684 | void sdhci_enable_irq_wakeups(struct sdhci_host *host) | ||
1685 | { | ||
1686 | u8 val; | ||
1687 | val = sdhci_readb(host, SDHCI_WAKE_UP_CONTROL); | ||
1688 | val |= SDHCI_WAKE_ON_INT; | ||
1689 | sdhci_writeb(host, val, SDHCI_WAKE_UP_CONTROL); | ||
1690 | } | ||
1691 | |||
1692 | EXPORT_SYMBOL_GPL(sdhci_enable_irq_wakeups); | ||
1693 | |||
1684 | #endif /* CONFIG_PM */ | 1694 | #endif /* CONFIG_PM */ |
1685 | 1695 | ||
1686 | /*****************************************************************************\ | 1696 | /*****************************************************************************\ |
diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h index b7b8a3b28b01..d52a7163b97a 100644 --- a/drivers/mmc/host/sdhci.h +++ b/drivers/mmc/host/sdhci.h | |||
@@ -87,6 +87,9 @@ | |||
87 | #define SDHCI_BLOCK_GAP_CONTROL 0x2A | 87 | #define SDHCI_BLOCK_GAP_CONTROL 0x2A |
88 | 88 | ||
89 | #define SDHCI_WAKE_UP_CONTROL 0x2B | 89 | #define SDHCI_WAKE_UP_CONTROL 0x2B |
90 | #define SDHCI_WAKE_ON_INT 0x01 | ||
91 | #define SDHCI_WAKE_ON_INSERT 0x02 | ||
92 | #define SDHCI_WAKE_ON_REMOVE 0x04 | ||
90 | 93 | ||
91 | #define SDHCI_CLOCK_CONTROL 0x2C | 94 | #define SDHCI_CLOCK_CONTROL 0x2C |
92 | #define SDHCI_DIVIDER_SHIFT 8 | 95 | #define SDHCI_DIVIDER_SHIFT 8 |
@@ -317,6 +320,7 @@ extern void sdhci_remove_host(struct sdhci_host *host, int dead); | |||
317 | #ifdef CONFIG_PM | 320 | #ifdef CONFIG_PM |
318 | extern int sdhci_suspend_host(struct sdhci_host *host, pm_message_t state); | 321 | extern int sdhci_suspend_host(struct sdhci_host *host, pm_message_t state); |
319 | extern int sdhci_resume_host(struct sdhci_host *host); | 322 | extern int sdhci_resume_host(struct sdhci_host *host); |
323 | extern void sdhci_enable_irq_wakeups(struct sdhci_host *host); | ||
320 | #endif | 324 | #endif |
321 | 325 | ||
322 | #endif /* __SDHCI_HW_H */ | 326 | #endif /* __SDHCI_HW_H */ |