Commit 5f619704 authored by Daniel Drake's avatar Daniel Drake Committed by Chris Ball

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: default avatarDaniel Drake <dsd@laptop.org>
Signed-off-by: default avatarChris Ball <cjb@laptop.org>
parent 14d4031d
...@@ -637,6 +637,7 @@ static int sdhci_pci_suspend (struct pci_dev *pdev, pm_message_t state) ...@@ -637,6 +637,7 @@ static int sdhci_pci_suspend (struct pci_dev *pdev, pm_message_t state)
{ {
struct sdhci_pci_chip *chip; struct sdhci_pci_chip *chip;
struct sdhci_pci_slot *slot; struct sdhci_pci_slot *slot;
mmc_pm_flag_t slot_pm_flags;
mmc_pm_flag_t pm_flags = 0; mmc_pm_flag_t pm_flags = 0;
int i, ret; int i, ret;
...@@ -657,7 +658,11 @@ static int sdhci_pci_suspend (struct pci_dev *pdev, pm_message_t state) ...@@ -657,7 +658,11 @@ static int sdhci_pci_suspend (struct pci_dev *pdev, pm_message_t state)
return ret; return ret;
} }
pm_flags |= slot->host->mmc->pm_flags; slot_pm_flags = slot->host->mmc->pm_flags;
if (slot_pm_flags & MMC_PM_WAKE_SDIO_IRQ)
sdhci_enable_irq_wakeups(slot->host);
pm_flags |= slot_pm_flags;
} }
if (chip->fixes && chip->fixes->suspend) { if (chip->fixes && chip->fixes->suspend) {
...@@ -671,8 +676,10 @@ static int sdhci_pci_suspend (struct pci_dev *pdev, pm_message_t state) ...@@ -671,8 +676,10 @@ static int sdhci_pci_suspend (struct pci_dev *pdev, pm_message_t state)
pci_save_state(pdev); pci_save_state(pdev);
if (pm_flags & MMC_PM_KEEP_POWER) { if (pm_flags & MMC_PM_KEEP_POWER) {
if (pm_flags & MMC_PM_WAKE_SDIO_IRQ) if (pm_flags & MMC_PM_WAKE_SDIO_IRQ) {
pci_pme_active(pdev, true);
pci_enable_wake(pdev, PCI_D3hot, 1); pci_enable_wake(pdev, PCI_D3hot, 1);
}
pci_set_power_state(pdev, PCI_D3hot); pci_set_power_state(pdev, PCI_D3hot);
} else { } else {
pci_enable_wake(pdev, pci_choose_state(pdev, state), 0); pci_enable_wake(pdev, pci_choose_state(pdev, state), 0);
......
...@@ -1681,6 +1681,16 @@ int sdhci_resume_host(struct sdhci_host *host) ...@@ -1681,6 +1681,16 @@ int sdhci_resume_host(struct sdhci_host *host)
EXPORT_SYMBOL_GPL(sdhci_resume_host); EXPORT_SYMBOL_GPL(sdhci_resume_host);
void sdhci_enable_irq_wakeups(struct sdhci_host *host)
{
u8 val;
val = sdhci_readb(host, SDHCI_WAKE_UP_CONTROL);
val |= SDHCI_WAKE_ON_INT;
sdhci_writeb(host, val, SDHCI_WAKE_UP_CONTROL);
}
EXPORT_SYMBOL_GPL(sdhci_enable_irq_wakeups);
#endif /* CONFIG_PM */ #endif /* CONFIG_PM */
/*****************************************************************************\ /*****************************************************************************\
......
...@@ -87,6 +87,9 @@ ...@@ -87,6 +87,9 @@
#define SDHCI_BLOCK_GAP_CONTROL 0x2A #define SDHCI_BLOCK_GAP_CONTROL 0x2A
#define SDHCI_WAKE_UP_CONTROL 0x2B #define SDHCI_WAKE_UP_CONTROL 0x2B
#define SDHCI_WAKE_ON_INT 0x01
#define SDHCI_WAKE_ON_INSERT 0x02
#define SDHCI_WAKE_ON_REMOVE 0x04
#define SDHCI_CLOCK_CONTROL 0x2C #define SDHCI_CLOCK_CONTROL 0x2C
#define SDHCI_DIVIDER_SHIFT 8 #define SDHCI_DIVIDER_SHIFT 8
...@@ -317,6 +320,7 @@ extern void sdhci_remove_host(struct sdhci_host *host, int dead); ...@@ -317,6 +320,7 @@ extern void sdhci_remove_host(struct sdhci_host *host, int dead);
#ifdef CONFIG_PM #ifdef CONFIG_PM
extern int sdhci_suspend_host(struct sdhci_host *host, pm_message_t state); extern int sdhci_suspend_host(struct sdhci_host *host, pm_message_t state);
extern int sdhci_resume_host(struct sdhci_host *host); extern int sdhci_resume_host(struct sdhci_host *host);
extern void sdhci_enable_irq_wakeups(struct sdhci_host *host);
#endif #endif
#endif /* __SDHCI_HW_H */ #endif /* __SDHCI_HW_H */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment