Skip to content

Commit 30cf280

Browse files
ahunter6storulf
authored andcommitted
mmc: sdhci-pci: Let suspend/resume callbacks replace default callbacks
The suspend / resume callbacks lack the flexibility to allow a device to specify a different function entirely. Change them around so that device functions are called directly and they in turn can call the default implementations if needed. Signed-off-by: Adrian Hunter <adrian.hunter@intel.com> Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org> Tested-by: Ludovic Desroches <ludovic.desroches@microchip.com>
1 parent b7813f0 commit 30cf280

File tree

3 files changed

+104
-72
lines changed

3 files changed

+104
-72
lines changed

drivers/mmc/host/sdhci-pci-core.c

Lines changed: 99 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,88 @@ static int sdhci_pci_enable_dma(struct sdhci_host *host);
3737
static void sdhci_pci_set_bus_width(struct sdhci_host *host, int width);
3838
static void sdhci_pci_hw_reset(struct sdhci_host *host);
3939

40+
#ifdef CONFIG_PM_SLEEP
41+
static int __sdhci_pci_suspend_host(struct sdhci_pci_chip *chip)
42+
{
43+
int i, ret;
44+
45+
for (i = 0; i < chip->num_slots; i++) {
46+
struct sdhci_pci_slot *slot = chip->slots[i];
47+
struct sdhci_host *host;
48+
49+
if (!slot)
50+
continue;
51+
52+
host = slot->host;
53+
54+
if (chip->pm_retune && host->tuning_mode != SDHCI_TUNING_MODE_3)
55+
mmc_retune_needed(host->mmc);
56+
57+
ret = sdhci_suspend_host(host);
58+
if (ret)
59+
goto err_pci_suspend;
60+
61+
if (host->mmc->pm_flags & MMC_PM_WAKE_SDIO_IRQ)
62+
sdhci_enable_irq_wakeups(host);
63+
}
64+
65+
return 0;
66+
67+
err_pci_suspend:
68+
while (--i >= 0)
69+
sdhci_resume_host(chip->slots[i]->host);
70+
return ret;
71+
}
72+
73+
static int sdhci_pci_init_wakeup(struct sdhci_pci_chip *chip)
74+
{
75+
mmc_pm_flag_t pm_flags = 0;
76+
int i;
77+
78+
for (i = 0; i < chip->num_slots; i++) {
79+
struct sdhci_pci_slot *slot = chip->slots[i];
80+
81+
if (slot)
82+
pm_flags |= slot->host->mmc->pm_flags;
83+
}
84+
85+
return device_init_wakeup(&chip->pdev->dev,
86+
(pm_flags & MMC_PM_KEEP_POWER) &&
87+
(pm_flags & MMC_PM_WAKE_SDIO_IRQ));
88+
}
89+
90+
static int sdhci_pci_suspend_host(struct sdhci_pci_chip *chip)
91+
{
92+
int ret;
93+
94+
ret = __sdhci_pci_suspend_host(chip);
95+
if (ret)
96+
return ret;
97+
98+
sdhci_pci_init_wakeup(chip);
99+
100+
return 0;
101+
}
102+
103+
int sdhci_pci_resume_host(struct sdhci_pci_chip *chip)
104+
{
105+
struct sdhci_pci_slot *slot;
106+
int i, ret;
107+
108+
for (i = 0; i < chip->num_slots; i++) {
109+
slot = chip->slots[i];
110+
if (!slot)
111+
continue;
112+
113+
ret = sdhci_resume_host(slot->host);
114+
if (ret)
115+
return ret;
116+
}
117+
118+
return 0;
119+
}
120+
#endif
121+
40122
/*****************************************************************************\
41123
* *
42124
* Hardware specific quirk handling *
@@ -74,7 +156,7 @@ static int ricoh_mmc_resume(struct sdhci_pci_chip *chip)
74156
/* Otherwise it becomes confused if card state changed
75157
during suspend */
76158
msleep(500);
77-
return 0;
159+
return sdhci_pci_resume_host(chip);
78160
}
79161
#endif
80162

@@ -758,14 +840,20 @@ static void jmicron_remove_slot(struct sdhci_pci_slot *slot, int dead)
758840
#ifdef CONFIG_PM_SLEEP
759841
static int jmicron_suspend(struct sdhci_pci_chip *chip)
760842
{
761-
int i;
843+
int i, ret;
844+
845+
ret = __sdhci_pci_suspend_host(chip);
846+
if (ret)
847+
return ret;
762848

763849
if (chip->pdev->device == PCI_DEVICE_ID_JMICRON_JMB38X_MMC ||
764850
chip->pdev->device == PCI_DEVICE_ID_JMICRON_JMB388_ESD) {
765851
for (i = 0; i < chip->num_slots; i++)
766852
jmicron_enable_mmc(chip->slots[i]->host, 0);
767853
}
768854

855+
sdhci_pci_init_wakeup(chip);
856+
769857
return 0;
770858
}
771859

@@ -785,7 +873,7 @@ static int jmicron_resume(struct sdhci_pci_chip *chip)
785873
return ret;
786874
}
787875

788-
return 0;
876+
return sdhci_pci_resume_host(chip);
789877
}
790878
#endif
791879

@@ -1678,89 +1766,29 @@ static const struct sdhci_ops sdhci_pci_ops = {
16781766
static int sdhci_pci_suspend(struct device *dev)
16791767
{
16801768
struct pci_dev *pdev = to_pci_dev(dev);
1681-
struct sdhci_pci_chip *chip;
1682-
struct sdhci_pci_slot *slot;
1683-
struct sdhci_host *host;
1684-
mmc_pm_flag_t slot_pm_flags;
1685-
mmc_pm_flag_t pm_flags = 0;
1686-
int i, ret;
1769+
struct sdhci_pci_chip *chip = pci_get_drvdata(pdev);
16871770

1688-
chip = pci_get_drvdata(pdev);
16891771
if (!chip)
16901772
return 0;
16911773

1692-
for (i = 0; i < chip->num_slots; i++) {
1693-
slot = chip->slots[i];
1694-
if (!slot)
1695-
continue;
1696-
1697-
host = slot->host;
1698-
1699-
if (chip->pm_retune && host->tuning_mode != SDHCI_TUNING_MODE_3)
1700-
mmc_retune_needed(host->mmc);
1701-
1702-
ret = sdhci_suspend_host(host);
1703-
1704-
if (ret)
1705-
goto err_pci_suspend;
1706-
1707-
slot_pm_flags = host->mmc->pm_flags;
1708-
if (slot_pm_flags & MMC_PM_WAKE_SDIO_IRQ)
1709-
sdhci_enable_irq_wakeups(host);
1774+
if (chip->fixes && chip->fixes->suspend)
1775+
return chip->fixes->suspend(chip);
17101776

1711-
pm_flags |= slot_pm_flags;
1712-
}
1713-
1714-
if (chip->fixes && chip->fixes->suspend) {
1715-
ret = chip->fixes->suspend(chip);
1716-
if (ret)
1717-
goto err_pci_suspend;
1718-
}
1719-
1720-
if (pm_flags & MMC_PM_KEEP_POWER) {
1721-
if (pm_flags & MMC_PM_WAKE_SDIO_IRQ)
1722-
device_init_wakeup(dev, true);
1723-
else
1724-
device_init_wakeup(dev, false);
1725-
} else
1726-
device_init_wakeup(dev, false);
1727-
1728-
return 0;
1729-
1730-
err_pci_suspend:
1731-
while (--i >= 0)
1732-
sdhci_resume_host(chip->slots[i]->host);
1733-
return ret;
1777+
return sdhci_pci_suspend_host(chip);
17341778
}
17351779

17361780
static int sdhci_pci_resume(struct device *dev)
17371781
{
17381782
struct pci_dev *pdev = to_pci_dev(dev);
1739-
struct sdhci_pci_chip *chip;
1740-
struct sdhci_pci_slot *slot;
1741-
int i, ret;
1783+
struct sdhci_pci_chip *chip = pci_get_drvdata(pdev);
17421784

1743-
chip = pci_get_drvdata(pdev);
17441785
if (!chip)
17451786
return 0;
17461787

1747-
if (chip->fixes && chip->fixes->resume) {
1748-
ret = chip->fixes->resume(chip);
1749-
if (ret)
1750-
return ret;
1751-
}
1752-
1753-
for (i = 0; i < chip->num_slots; i++) {
1754-
slot = chip->slots[i];
1755-
if (!slot)
1756-
continue;
1757-
1758-
ret = sdhci_resume_host(slot->host);
1759-
if (ret)
1760-
return ret;
1761-
}
1788+
if (chip->fixes && chip->fixes->resume)
1789+
return chip->fixes->resume(chip);
17621790

1763-
return 0;
1791+
return sdhci_pci_resume_host(chip);
17641792
}
17651793
#endif
17661794

drivers/mmc/host/sdhci-pci-o2micro.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -388,6 +388,6 @@ int sdhci_pci_o2_probe(struct sdhci_pci_chip *chip)
388388
int sdhci_pci_o2_resume(struct sdhci_pci_chip *chip)
389389
{
390390
sdhci_pci_o2_probe(chip);
391-
return 0;
391+
return sdhci_pci_resume_host(chip);
392392
}
393393
#endif

drivers/mmc/host/sdhci-pci.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,4 +111,8 @@ static inline void *sdhci_pci_priv(struct sdhci_pci_slot *slot)
111111
return (void *)slot->private;
112112
}
113113

114+
#ifdef CONFIG_PM_SLEEP
115+
int sdhci_pci_resume_host(struct sdhci_pci_chip *chip);
116+
#endif
117+
114118
#endif /* __SDHCI_PCI_H */

0 commit comments

Comments
 (0)