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>
This commit is contained in:
parent
14d4031d21
commit
5f619704d1
3 changed files with 23 additions and 2 deletions
|
@ -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)
|
||||||
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)
|
||||||
|
|
||||||
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)
|
||||||
|
|
||||||
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 @@
|
||||||
#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);
|
||||||
#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 */
|
||||||
|
|
Loading…
Reference in a new issue