diff options
author | Gao, Yunpeng <yunpeng.gao@intel.com> | 2014-08-31 23:35:40 -0400 |
---|---|---|
committer | Ulf Hansson <ulf.hansson@linaro.org> | 2014-09-09 07:59:24 -0400 |
commit | 578b36b69c31c874f8303c62efb40b8bb9b46ae5 (patch) | |
tree | 4b25a06cae8107f5a72c3e323badbfac4e032c42 /drivers/mmc | |
parent | f1b55a55e4ee6fe6d791cff994f6e4d990f69c1e (diff) |
mmc: sdhci-acpi: add probe_slot method for emmc/sd/sdio
Similar to sdhci-pci controller, also add probe_slot
and remove_slot method in the sdhci-acpi driver.
Signed-off-by: Yunpeng Gao <yunpeng.gao@intel.com>
Signed-off-by: Chuanxiao Dong <chuanxiao.dong@intel.com>
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
Diffstat (limited to 'drivers/mmc')
-rw-r--r-- | drivers/mmc/host/sdhci-acpi.c | 58 |
1 files changed, 58 insertions, 0 deletions
diff --git a/drivers/mmc/host/sdhci-acpi.c b/drivers/mmc/host/sdhci-acpi.c index cc65b3fd0a60..3483c089baa7 100644 --- a/drivers/mmc/host/sdhci-acpi.c +++ b/drivers/mmc/host/sdhci-acpi.c | |||
@@ -67,6 +67,8 @@ struct sdhci_acpi_slot { | |||
67 | unsigned int caps2; | 67 | unsigned int caps2; |
68 | mmc_pm_flag_t pm_caps; | 68 | mmc_pm_flag_t pm_caps; |
69 | unsigned int flags; | 69 | unsigned int flags; |
70 | int (*probe_slot)(struct platform_device *); | ||
71 | int (*remove_slot)(struct platform_device *); | ||
70 | }; | 72 | }; |
71 | 73 | ||
72 | struct sdhci_acpi_host { | 74 | struct sdhci_acpi_host { |
@@ -122,6 +124,51 @@ static const struct sdhci_acpi_chip sdhci_acpi_chip_int = { | |||
122 | .ops = &sdhci_acpi_ops_int, | 124 | .ops = &sdhci_acpi_ops_int, |
123 | }; | 125 | }; |
124 | 126 | ||
127 | static int sdhci_acpi_emmc_probe_slot(struct platform_device *pdev) | ||
128 | { | ||
129 | struct sdhci_acpi_host *c = platform_get_drvdata(pdev); | ||
130 | struct sdhci_host *host; | ||
131 | |||
132 | if (!c || !c->host) | ||
133 | return 0; | ||
134 | |||
135 | host = c->host; | ||
136 | |||
137 | /* Platform specific code during emmc proble slot goes here */ | ||
138 | |||
139 | return 0; | ||
140 | } | ||
141 | |||
142 | static int sdhci_acpi_sdio_probe_slot(struct platform_device *pdev) | ||
143 | { | ||
144 | struct sdhci_acpi_host *c = platform_get_drvdata(pdev); | ||
145 | struct sdhci_host *host; | ||
146 | |||
147 | if (!c || !c->host) | ||
148 | return 0; | ||
149 | |||
150 | host = c->host; | ||
151 | |||
152 | /* Platform specific code during emmc proble slot goes here */ | ||
153 | |||
154 | return 0; | ||
155 | } | ||
156 | |||
157 | static int sdhci_acpi_sd_probe_slot(struct platform_device *pdev) | ||
158 | { | ||
159 | struct sdhci_acpi_host *c = platform_get_drvdata(pdev); | ||
160 | struct sdhci_host *host; | ||
161 | |||
162 | if (!c || !c->host || !c->slot) | ||
163 | return 0; | ||
164 | |||
165 | host = c->host; | ||
166 | |||
167 | /* Platform specific code during emmc proble slot goes here */ | ||
168 | |||
169 | return 0; | ||
170 | } | ||
171 | |||
125 | static const struct sdhci_acpi_slot sdhci_acpi_slot_int_emmc = { | 172 | static const struct sdhci_acpi_slot sdhci_acpi_slot_int_emmc = { |
126 | .chip = &sdhci_acpi_chip_int, | 173 | .chip = &sdhci_acpi_chip_int, |
127 | .caps = MMC_CAP_8_BIT_DATA | MMC_CAP_NONREMOVABLE | | 174 | .caps = MMC_CAP_8_BIT_DATA | MMC_CAP_NONREMOVABLE | |
@@ -129,6 +176,7 @@ static const struct sdhci_acpi_slot sdhci_acpi_slot_int_emmc = { | |||
129 | .caps2 = MMC_CAP2_HC_ERASE_SZ, | 176 | .caps2 = MMC_CAP2_HC_ERASE_SZ, |
130 | .flags = SDHCI_ACPI_RUNTIME_PM, | 177 | .flags = SDHCI_ACPI_RUNTIME_PM, |
131 | .quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN, | 178 | .quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN, |
179 | .probe_slot = sdhci_acpi_emmc_probe_slot, | ||
132 | }; | 180 | }; |
133 | 181 | ||
134 | static const struct sdhci_acpi_slot sdhci_acpi_slot_int_sdio = { | 182 | static const struct sdhci_acpi_slot sdhci_acpi_slot_int_sdio = { |
@@ -137,12 +185,14 @@ static const struct sdhci_acpi_slot sdhci_acpi_slot_int_sdio = { | |||
137 | .caps = MMC_CAP_NONREMOVABLE | MMC_CAP_POWER_OFF_CARD, | 185 | .caps = MMC_CAP_NONREMOVABLE | MMC_CAP_POWER_OFF_CARD, |
138 | .flags = SDHCI_ACPI_RUNTIME_PM, | 186 | .flags = SDHCI_ACPI_RUNTIME_PM, |
139 | .pm_caps = MMC_PM_KEEP_POWER, | 187 | .pm_caps = MMC_PM_KEEP_POWER, |
188 | .probe_slot = sdhci_acpi_sdio_probe_slot, | ||
140 | }; | 189 | }; |
141 | 190 | ||
142 | static const struct sdhci_acpi_slot sdhci_acpi_slot_int_sd = { | 191 | static const struct sdhci_acpi_slot sdhci_acpi_slot_int_sd = { |
143 | .flags = SDHCI_ACPI_SD_CD | SDHCI_ACPI_SD_CD_OVERRIDE_LEVEL | | 192 | .flags = SDHCI_ACPI_SD_CD | SDHCI_ACPI_SD_CD_OVERRIDE_LEVEL | |
144 | SDHCI_ACPI_RUNTIME_PM, | 193 | SDHCI_ACPI_RUNTIME_PM, |
145 | .quirks2 = SDHCI_QUIRK2_CARD_ON_NEEDS_BUS_ON, | 194 | .quirks2 = SDHCI_QUIRK2_CARD_ON_NEEDS_BUS_ON, |
195 | .probe_slot = sdhci_acpi_sd_probe_slot, | ||
146 | }; | 196 | }; |
147 | 197 | ||
148 | struct sdhci_acpi_uid_slot { | 198 | struct sdhci_acpi_uid_slot { |
@@ -277,6 +327,11 @@ static int sdhci_acpi_probe(struct platform_device *pdev) | |||
277 | } | 327 | } |
278 | 328 | ||
279 | if (c->slot) { | 329 | if (c->slot) { |
330 | if (c->slot->probe_slot) { | ||
331 | err = c->slot->probe_slot(pdev); | ||
332 | if (err) | ||
333 | goto err_free; | ||
334 | } | ||
280 | if (c->slot->chip) { | 335 | if (c->slot->chip) { |
281 | host->ops = c->slot->chip->ops; | 336 | host->ops = c->slot->chip->ops; |
282 | host->quirks |= c->slot->chip->quirks; | 337 | host->quirks |= c->slot->chip->quirks; |
@@ -334,6 +389,9 @@ static int sdhci_acpi_remove(struct platform_device *pdev) | |||
334 | pm_runtime_put_noidle(dev); | 389 | pm_runtime_put_noidle(dev); |
335 | } | 390 | } |
336 | 391 | ||
392 | if (c->slot && c->slot->remove_slot) | ||
393 | c->slot->remove_slot(pdev); | ||
394 | |||
337 | dead = (sdhci_readl(c->host, SDHCI_INT_STATUS) == ~0); | 395 | dead = (sdhci_readl(c->host, SDHCI_INT_STATUS) == ~0); |
338 | sdhci_remove_host(c->host, dead); | 396 | sdhci_remove_host(c->host, dead); |
339 | sdhci_free_host(c->host); | 397 | sdhci_free_host(c->host); |