[go: nahoru, domu]

1c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter/*
2c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter * Secure Digital Host Controller Interface ACPI driver.
3c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter *
4c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter * Copyright (c) 2012, Intel Corporation.
5c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter *
6c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter * This program is free software; you can redistribute it and/or modify it
7c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter * under the terms and conditions of the GNU General Public License,
8c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter * version 2, as published by the Free Software Foundation.
9c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter *
10c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter * This program is distributed in the hope it will be useful, but WITHOUT
11c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
13c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter * more details.
14c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter *
15c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter * You should have received a copy of the GNU General Public License along with
16c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter * this program; if not, write to the Free Software Foundation, Inc.,
17c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
18c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter *
19c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter */
20c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter
21c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter#include <linux/init.h>
22c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter#include <linux/export.h>
23c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter#include <linux/module.h>
24c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter#include <linux/device.h>
25c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter#include <linux/platform_device.h>
26c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter#include <linux/ioport.h>
27c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter#include <linux/io.h>
28c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter#include <linux/dma-mapping.h>
29c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter#include <linux/compiler.h>
30c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter#include <linux/stddef.h>
31c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter#include <linux/bitops.h>
32c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter#include <linux/types.h>
33c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter#include <linux/err.h>
34c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter#include <linux/interrupt.h>
35c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter#include <linux/acpi.h>
36c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter#include <linux/pm.h>
37c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter#include <linux/pm_runtime.h>
38b04fa064e72c301e075c2d52c146282f8f464083Adrian Hunter#include <linux/delay.h>
39c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter
40c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter#include <linux/mmc/host.h>
41c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter#include <linux/mmc/pm.h>
424fd4409c81e2c756a5cfbedc598c48d6a3ed3fd5Adrian Hunter#include <linux/mmc/slot-gpio.h>
43c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter#include <linux/mmc/sdhci.h>
44c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter
45c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter#include "sdhci.h"
46c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter
47c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunterenum {
484fd4409c81e2c756a5cfbedc598c48d6a3ed3fd5Adrian Hunter	SDHCI_ACPI_SD_CD		= BIT(0),
494fd4409c81e2c756a5cfbedc598c48d6a3ed3fd5Adrian Hunter	SDHCI_ACPI_RUNTIME_PM		= BIT(1),
504fd4409c81e2c756a5cfbedc598c48d6a3ed3fd5Adrian Hunter	SDHCI_ACPI_SD_CD_OVERRIDE_LEVEL	= BIT(2),
51c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter};
52c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter
53c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunterstruct sdhci_acpi_chip {
54c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter	const struct	sdhci_ops *ops;
55c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter	unsigned int	quirks;
56c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter	unsigned int	quirks2;
57c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter	unsigned long	caps;
58c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter	unsigned int	caps2;
59c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter	mmc_pm_flag_t	pm_caps;
60c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter};
61c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter
62c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunterstruct sdhci_acpi_slot {
63c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter	const struct	sdhci_acpi_chip *chip;
64c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter	unsigned int	quirks;
65c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter	unsigned int	quirks2;
66c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter	unsigned long	caps;
67c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter	unsigned int	caps2;
68c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter	mmc_pm_flag_t	pm_caps;
69c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter	unsigned int	flags;
707dafca835a459ab31792d9def69ed30cf6dc08abAdrian Hunter	int (*probe_slot)(struct platform_device *, const char *, const char *);
71578b36b69c31c874f8303c62efb40b8bb9b46ae5Gao, Yunpeng	int (*remove_slot)(struct platform_device *);
72c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter};
73c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter
74c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunterstruct sdhci_acpi_host {
75c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter	struct sdhci_host		*host;
76c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter	const struct sdhci_acpi_slot	*slot;
77c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter	struct platform_device		*pdev;
78c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter	bool				use_runtime_pm;
79c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter};
80c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter
81c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunterstatic inline bool sdhci_acpi_flag(struct sdhci_acpi_host *c, unsigned int flag)
82c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter{
83c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter	return c->slot && (c->slot->flags & flag);
84c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter}
85c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter
86c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunterstatic int sdhci_acpi_enable_dma(struct sdhci_host *host)
87c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter{
88c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter	return 0;
89c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter}
90c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter
91b04fa064e72c301e075c2d52c146282f8f464083Adrian Hunterstatic void sdhci_acpi_int_hw_reset(struct sdhci_host *host)
92b04fa064e72c301e075c2d52c146282f8f464083Adrian Hunter{
93b04fa064e72c301e075c2d52c146282f8f464083Adrian Hunter	u8 reg;
94b04fa064e72c301e075c2d52c146282f8f464083Adrian Hunter
95b04fa064e72c301e075c2d52c146282f8f464083Adrian Hunter	reg = sdhci_readb(host, SDHCI_POWER_CONTROL);
96b04fa064e72c301e075c2d52c146282f8f464083Adrian Hunter	reg |= 0x10;
97b04fa064e72c301e075c2d52c146282f8f464083Adrian Hunter	sdhci_writeb(host, reg, SDHCI_POWER_CONTROL);
98b04fa064e72c301e075c2d52c146282f8f464083Adrian Hunter	/* For eMMC, minimum is 1us but give it 9us for good measure */
99b04fa064e72c301e075c2d52c146282f8f464083Adrian Hunter	udelay(9);
100b04fa064e72c301e075c2d52c146282f8f464083Adrian Hunter	reg &= ~0x10;
101b04fa064e72c301e075c2d52c146282f8f464083Adrian Hunter	sdhci_writeb(host, reg, SDHCI_POWER_CONTROL);
102b04fa064e72c301e075c2d52c146282f8f464083Adrian Hunter	/* For eMMC, minimum is 200us but give it 300us for good measure */
103b04fa064e72c301e075c2d52c146282f8f464083Adrian Hunter	usleep_range(300, 1000);
104b04fa064e72c301e075c2d52c146282f8f464083Adrian Hunter}
105b04fa064e72c301e075c2d52c146282f8f464083Adrian Hunter
106c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunterstatic const struct sdhci_ops sdhci_acpi_ops_dflt = {
1071771059cf5f9c09e37ef6315df8acf120f2642fcRussell King	.set_clock = sdhci_set_clock,
108c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter	.enable_dma = sdhci_acpi_enable_dma,
1092317f56c055fcad524bf6a873df48a754e7ebc4dRussell King	.set_bus_width = sdhci_set_bus_width,
11003231f9b781f24205c0af0398ce3cbef70090939Russell King	.reset = sdhci_reset,
11196d7b78cfc2fd6b1539704e2d33239dbaa097cc4Russell King	.set_uhs_signaling = sdhci_set_uhs_signaling,
112c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter};
113c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter
114b04fa064e72c301e075c2d52c146282f8f464083Adrian Hunterstatic const struct sdhci_ops sdhci_acpi_ops_int = {
1151771059cf5f9c09e37ef6315df8acf120f2642fcRussell King	.set_clock = sdhci_set_clock,
116b04fa064e72c301e075c2d52c146282f8f464083Adrian Hunter	.enable_dma = sdhci_acpi_enable_dma,
1172317f56c055fcad524bf6a873df48a754e7ebc4dRussell King	.set_bus_width = sdhci_set_bus_width,
11803231f9b781f24205c0af0398ce3cbef70090939Russell King	.reset = sdhci_reset,
11996d7b78cfc2fd6b1539704e2d33239dbaa097cc4Russell King	.set_uhs_signaling = sdhci_set_uhs_signaling,
120b04fa064e72c301e075c2d52c146282f8f464083Adrian Hunter	.hw_reset   = sdhci_acpi_int_hw_reset,
121b04fa064e72c301e075c2d52c146282f8f464083Adrian Hunter};
122b04fa064e72c301e075c2d52c146282f8f464083Adrian Hunter
123b04fa064e72c301e075c2d52c146282f8f464083Adrian Hunterstatic const struct sdhci_acpi_chip sdhci_acpi_chip_int = {
124b04fa064e72c301e075c2d52c146282f8f464083Adrian Hunter	.ops = &sdhci_acpi_ops_int,
125b04fa064e72c301e075c2d52c146282f8f464083Adrian Hunter};
126b04fa064e72c301e075c2d52c146282f8f464083Adrian Hunter
1277dafca835a459ab31792d9def69ed30cf6dc08abAdrian Hunterstatic int sdhci_acpi_emmc_probe_slot(struct platform_device *pdev,
1287dafca835a459ab31792d9def69ed30cf6dc08abAdrian Hunter				      const char *hid, const char *uid)
129578b36b69c31c874f8303c62efb40b8bb9b46ae5Gao, Yunpeng{
130578b36b69c31c874f8303c62efb40b8bb9b46ae5Gao, Yunpeng	struct sdhci_acpi_host *c = platform_get_drvdata(pdev);
131578b36b69c31c874f8303c62efb40b8bb9b46ae5Gao, Yunpeng	struct sdhci_host *host;
132578b36b69c31c874f8303c62efb40b8bb9b46ae5Gao, Yunpeng
133578b36b69c31c874f8303c62efb40b8bb9b46ae5Gao, Yunpeng	if (!c || !c->host)
134578b36b69c31c874f8303c62efb40b8bb9b46ae5Gao, Yunpeng		return 0;
135578b36b69c31c874f8303c62efb40b8bb9b46ae5Gao, Yunpeng
136578b36b69c31c874f8303c62efb40b8bb9b46ae5Gao, Yunpeng	host = c->host;
137578b36b69c31c874f8303c62efb40b8bb9b46ae5Gao, Yunpeng
138578b36b69c31c874f8303c62efb40b8bb9b46ae5Gao, Yunpeng	/* Platform specific code during emmc proble slot goes here */
139578b36b69c31c874f8303c62efb40b8bb9b46ae5Gao, Yunpeng
1408024379e0ae43b1154978c2291ce20f772cbb3bdAdrian Hunter	if (hid && uid && !strcmp(hid, "80860F14") && !strcmp(uid, "1") &&
1418024379e0ae43b1154978c2291ce20f772cbb3bdAdrian Hunter	    sdhci_readl(host, SDHCI_CAPABILITIES) == 0x446cc8b2 &&
1428024379e0ae43b1154978c2291ce20f772cbb3bdAdrian Hunter	    sdhci_readl(host, SDHCI_CAPABILITIES_1) == 0x00000807)
1438024379e0ae43b1154978c2291ce20f772cbb3bdAdrian Hunter		host->timeout_clk = 1000; /* 1000 kHz i.e. 1 MHz */
1448024379e0ae43b1154978c2291ce20f772cbb3bdAdrian Hunter
145578b36b69c31c874f8303c62efb40b8bb9b46ae5Gao, Yunpeng	return 0;
146578b36b69c31c874f8303c62efb40b8bb9b46ae5Gao, Yunpeng}
147578b36b69c31c874f8303c62efb40b8bb9b46ae5Gao, Yunpeng
1487dafca835a459ab31792d9def69ed30cf6dc08abAdrian Hunterstatic int sdhci_acpi_sdio_probe_slot(struct platform_device *pdev,
1497dafca835a459ab31792d9def69ed30cf6dc08abAdrian Hunter				      const char *hid, const char *uid)
150578b36b69c31c874f8303c62efb40b8bb9b46ae5Gao, Yunpeng{
151578b36b69c31c874f8303c62efb40b8bb9b46ae5Gao, Yunpeng	struct sdhci_acpi_host *c = platform_get_drvdata(pdev);
152578b36b69c31c874f8303c62efb40b8bb9b46ae5Gao, Yunpeng	struct sdhci_host *host;
153578b36b69c31c874f8303c62efb40b8bb9b46ae5Gao, Yunpeng
154578b36b69c31c874f8303c62efb40b8bb9b46ae5Gao, Yunpeng	if (!c || !c->host)
155578b36b69c31c874f8303c62efb40b8bb9b46ae5Gao, Yunpeng		return 0;
156578b36b69c31c874f8303c62efb40b8bb9b46ae5Gao, Yunpeng
157578b36b69c31c874f8303c62efb40b8bb9b46ae5Gao, Yunpeng	host = c->host;
158578b36b69c31c874f8303c62efb40b8bb9b46ae5Gao, Yunpeng
159578b36b69c31c874f8303c62efb40b8bb9b46ae5Gao, Yunpeng	/* Platform specific code during emmc proble slot goes here */
160578b36b69c31c874f8303c62efb40b8bb9b46ae5Gao, Yunpeng
161578b36b69c31c874f8303c62efb40b8bb9b46ae5Gao, Yunpeng	return 0;
162578b36b69c31c874f8303c62efb40b8bb9b46ae5Gao, Yunpeng}
163578b36b69c31c874f8303c62efb40b8bb9b46ae5Gao, Yunpeng
1647dafca835a459ab31792d9def69ed30cf6dc08abAdrian Hunterstatic int sdhci_acpi_sd_probe_slot(struct platform_device *pdev,
1657dafca835a459ab31792d9def69ed30cf6dc08abAdrian Hunter				    const char *hid, const char *uid)
166578b36b69c31c874f8303c62efb40b8bb9b46ae5Gao, Yunpeng{
167578b36b69c31c874f8303c62efb40b8bb9b46ae5Gao, Yunpeng	struct sdhci_acpi_host *c = platform_get_drvdata(pdev);
168578b36b69c31c874f8303c62efb40b8bb9b46ae5Gao, Yunpeng	struct sdhci_host *host;
169578b36b69c31c874f8303c62efb40b8bb9b46ae5Gao, Yunpeng
170578b36b69c31c874f8303c62efb40b8bb9b46ae5Gao, Yunpeng	if (!c || !c->host || !c->slot)
171578b36b69c31c874f8303c62efb40b8bb9b46ae5Gao, Yunpeng		return 0;
172578b36b69c31c874f8303c62efb40b8bb9b46ae5Gao, Yunpeng
173578b36b69c31c874f8303c62efb40b8bb9b46ae5Gao, Yunpeng	host = c->host;
174578b36b69c31c874f8303c62efb40b8bb9b46ae5Gao, Yunpeng
175578b36b69c31c874f8303c62efb40b8bb9b46ae5Gao, Yunpeng	/* Platform specific code during emmc proble slot goes here */
176578b36b69c31c874f8303c62efb40b8bb9b46ae5Gao, Yunpeng
177578b36b69c31c874f8303c62efb40b8bb9b46ae5Gao, Yunpeng	return 0;
178578b36b69c31c874f8303c62efb40b8bb9b46ae5Gao, Yunpeng}
179578b36b69c31c874f8303c62efb40b8bb9b46ae5Gao, Yunpeng
18007a588837be0a18075fedf71e6963b5109abec03Adrian Hunterstatic const struct sdhci_acpi_slot sdhci_acpi_slot_int_emmc = {
181b04fa064e72c301e075c2d52c146282f8f464083Adrian Hunter	.chip    = &sdhci_acpi_chip_int,
182f25c33724d1512a72554c0ad4cb70b43ba15374eMaurice Petallo	.caps    = MMC_CAP_8_BIT_DATA | MMC_CAP_NONREMOVABLE |
183f25c33724d1512a72554c0ad4cb70b43ba15374eMaurice Petallo		   MMC_CAP_HW_RESET | MMC_CAP_1_8V_DDR,
18407a588837be0a18075fedf71e6963b5109abec03Adrian Hunter	.caps2   = MMC_CAP2_HC_ERASE_SZ,
18507a588837be0a18075fedf71e6963b5109abec03Adrian Hunter	.flags   = SDHCI_ACPI_RUNTIME_PM,
186934e31b9dc848df56a65768388609358a1836ba0Adrian Hunter	.quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN | SDHCI_QUIRK2_STOP_WITH_TC,
187578b36b69c31c874f8303c62efb40b8bb9b46ae5Gao, Yunpeng	.probe_slot	= sdhci_acpi_emmc_probe_slot,
18807a588837be0a18075fedf71e6963b5109abec03Adrian Hunter};
18907a588837be0a18075fedf71e6963b5109abec03Adrian Hunter
190e5571397175be315bc6177ba39945dab538793b1Adrian Hunterstatic const struct sdhci_acpi_slot sdhci_acpi_slot_int_sdio = {
191c67480173f72e883235dd0ad09d90156c8f87600Adrian Hunter	.quirks  = SDHCI_QUIRK_BROKEN_CARD_DETECTION,
192e5571397175be315bc6177ba39945dab538793b1Adrian Hunter	.quirks2 = SDHCI_QUIRK2_HOST_OFF_CARD_ON,
193e5571397175be315bc6177ba39945dab538793b1Adrian Hunter	.caps    = MMC_CAP_NONREMOVABLE | MMC_CAP_POWER_OFF_CARD,
194e5571397175be315bc6177ba39945dab538793b1Adrian Hunter	.flags   = SDHCI_ACPI_RUNTIME_PM,
195e5571397175be315bc6177ba39945dab538793b1Adrian Hunter	.pm_caps = MMC_PM_KEEP_POWER,
196578b36b69c31c874f8303c62efb40b8bb9b46ae5Gao, Yunpeng	.probe_slot	= sdhci_acpi_sdio_probe_slot,
197e5571397175be315bc6177ba39945dab538793b1Adrian Hunter};
198e5571397175be315bc6177ba39945dab538793b1Adrian Hunter
19907a588837be0a18075fedf71e6963b5109abec03Adrian Hunterstatic const struct sdhci_acpi_slot sdhci_acpi_slot_int_sd = {
2004fd4409c81e2c756a5cfbedc598c48d6a3ed3fd5Adrian Hunter	.flags   = SDHCI_ACPI_SD_CD | SDHCI_ACPI_SD_CD_OVERRIDE_LEVEL |
2014fd4409c81e2c756a5cfbedc598c48d6a3ed3fd5Adrian Hunter		   SDHCI_ACPI_RUNTIME_PM,
202934e31b9dc848df56a65768388609358a1836ba0Adrian Hunter	.quirks2 = SDHCI_QUIRK2_CARD_ON_NEEDS_BUS_ON |
203934e31b9dc848df56a65768388609358a1836ba0Adrian Hunter		   SDHCI_QUIRK2_STOP_WITH_TC,
204578b36b69c31c874f8303c62efb40b8bb9b46ae5Gao, Yunpeng	.probe_slot	= sdhci_acpi_sd_probe_slot,
20507a588837be0a18075fedf71e6963b5109abec03Adrian Hunter};
20607a588837be0a18075fedf71e6963b5109abec03Adrian Hunter
20707a588837be0a18075fedf71e6963b5109abec03Adrian Hunterstruct sdhci_acpi_uid_slot {
20807a588837be0a18075fedf71e6963b5109abec03Adrian Hunter	const char *hid;
20907a588837be0a18075fedf71e6963b5109abec03Adrian Hunter	const char *uid;
21007a588837be0a18075fedf71e6963b5109abec03Adrian Hunter	const struct sdhci_acpi_slot *slot;
21107a588837be0a18075fedf71e6963b5109abec03Adrian Hunter};
21207a588837be0a18075fedf71e6963b5109abec03Adrian Hunter
21307a588837be0a18075fedf71e6963b5109abec03Adrian Hunterstatic const struct sdhci_acpi_uid_slot sdhci_acpi_uids[] = {
21407a588837be0a18075fedf71e6963b5109abec03Adrian Hunter	{ "80860F14" , "1" , &sdhci_acpi_slot_int_emmc },
21507a588837be0a18075fedf71e6963b5109abec03Adrian Hunter	{ "80860F14" , "3" , &sdhci_acpi_slot_int_sd   },
216aad95dc49c6dad19b49af7cd90c53473ec0536d1Adrian Hunter	{ "80860F16" , NULL, &sdhci_acpi_slot_int_sd   },
21707a588837be0a18075fedf71e6963b5109abec03Adrian Hunter	{ "INT33BB"  , "2" , &sdhci_acpi_slot_int_sdio },
2187147eaf3a4fe7e7dbb6e1f89e328ea0507e0c32cAdrian Hunter	{ "INT33BB"  , "3" , &sdhci_acpi_slot_int_sd },
21907a588837be0a18075fedf71e6963b5109abec03Adrian Hunter	{ "INT33C6"  , NULL, &sdhci_acpi_slot_int_sdio },
22007c001c119c7de92be9c8ad1f1a3e5af459cb3d4Mika Westerberg	{ "INT3436"  , NULL, &sdhci_acpi_slot_int_sdio },
22107a588837be0a18075fedf71e6963b5109abec03Adrian Hunter	{ "PNP0D40"  },
22207a588837be0a18075fedf71e6963b5109abec03Adrian Hunter	{ },
22307a588837be0a18075fedf71e6963b5109abec03Adrian Hunter};
22407a588837be0a18075fedf71e6963b5109abec03Adrian Hunter
225c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunterstatic const struct acpi_device_id sdhci_acpi_ids[] = {
22607a588837be0a18075fedf71e6963b5109abec03Adrian Hunter	{ "80860F14" },
227aad95dc49c6dad19b49af7cd90c53473ec0536d1Adrian Hunter	{ "80860F16" },
22807a588837be0a18075fedf71e6963b5109abec03Adrian Hunter	{ "INT33BB"  },
22907a588837be0a18075fedf71e6963b5109abec03Adrian Hunter	{ "INT33C6"  },
23007c001c119c7de92be9c8ad1f1a3e5af459cb3d4Mika Westerberg	{ "INT3436"  },
23107a588837be0a18075fedf71e6963b5109abec03Adrian Hunter	{ "PNP0D40"  },
232c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter	{ },
233c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter};
234c4e050376c69bb9d67895842665264df2a2004d9Adrian HunterMODULE_DEVICE_TABLE(acpi, sdhci_acpi_ids);
235c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter
2363db3525196a992da628fb210776d73ec4bb59460Adrian Hunterstatic const struct sdhci_acpi_slot *sdhci_acpi_get_slot(const char *hid,
2373db3525196a992da628fb210776d73ec4bb59460Adrian Hunter							 const char *uid)
238c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter{
23907a588837be0a18075fedf71e6963b5109abec03Adrian Hunter	const struct sdhci_acpi_uid_slot *u;
24007a588837be0a18075fedf71e6963b5109abec03Adrian Hunter
24107a588837be0a18075fedf71e6963b5109abec03Adrian Hunter	for (u = sdhci_acpi_uids; u->hid; u++) {
24207a588837be0a18075fedf71e6963b5109abec03Adrian Hunter		if (strcmp(u->hid, hid))
24307a588837be0a18075fedf71e6963b5109abec03Adrian Hunter			continue;
24407a588837be0a18075fedf71e6963b5109abec03Adrian Hunter		if (!u->uid)
24507a588837be0a18075fedf71e6963b5109abec03Adrian Hunter			return u->slot;
24607a588837be0a18075fedf71e6963b5109abec03Adrian Hunter		if (uid && !strcmp(u->uid, uid))
24707a588837be0a18075fedf71e6963b5109abec03Adrian Hunter			return u->slot;
24807a588837be0a18075fedf71e6963b5109abec03Adrian Hunter	}
249c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter	return NULL;
250c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter}
251c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter
2524e608e4ed9fea873c60749bdba2fbbbfb234bee0Greg Kroah-Hartmanstatic int sdhci_acpi_probe(struct platform_device *pdev)
253c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter{
254c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter	struct device *dev = &pdev->dev;
255c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter	acpi_handle handle = ACPI_HANDLE(dev);
256c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter	struct acpi_device *device;
257c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter	struct sdhci_acpi_host *c;
258c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter	struct sdhci_host *host;
259c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter	struct resource *iomem;
260c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter	resource_size_t len;
261c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter	const char *hid;
2623db3525196a992da628fb210776d73ec4bb59460Adrian Hunter	const char *uid;
263878756553271dd631ee7f06fe489103957753fddMika Westerberg	int err;
264c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter
265c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter	if (acpi_bus_get_device(handle, &device))
266c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter		return -ENODEV;
267c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter
268c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter	if (acpi_bus_get_status(device) || !device->status.present)
269c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter		return -ENODEV;
270c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter
271c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter	hid = acpi_device_hid(device);
2723db3525196a992da628fb210776d73ec4bb59460Adrian Hunter	uid = device->pnp.unique_id;
273c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter
274c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter	iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
275c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter	if (!iomem)
276c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter		return -ENOMEM;
277c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter
278c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter	len = resource_size(iomem);
279c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter	if (len < 0x100)
280c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter		dev_err(dev, "Invalid iomem size!\n");
281c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter
282c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter	if (!devm_request_mem_region(dev, iomem->start, len, dev_name(dev)))
283c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter		return -ENOMEM;
284c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter
285c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter	host = sdhci_alloc_host(dev, sizeof(struct sdhci_acpi_host));
286c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter	if (IS_ERR(host))
287c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter		return PTR_ERR(host);
288c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter
289c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter	c = sdhci_priv(host);
290c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter	c->host = host;
2913db3525196a992da628fb210776d73ec4bb59460Adrian Hunter	c->slot = sdhci_acpi_get_slot(hid, uid);
292c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter	c->pdev = pdev;
293c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter	c->use_runtime_pm = sdhci_acpi_flag(c, SDHCI_ACPI_RUNTIME_PM);
294c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter
295c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter	platform_set_drvdata(pdev, c);
296c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter
297c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter	host->hw_name	= "ACPI";
298c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter	host->ops	= &sdhci_acpi_ops_dflt;
299c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter	host->irq	= platform_get_irq(pdev, 0);
300c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter
301c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter	host->ioaddr = devm_ioremap_nocache(dev, iomem->start,
302c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter					    resource_size(iomem));
303c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter	if (host->ioaddr == NULL) {
304c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter		err = -ENOMEM;
305c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter		goto err_free;
306c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter	}
307c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter
308c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter	if (!dev->dma_mask) {
309c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter		u64 dma_mask;
310c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter
311c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter		if (sdhci_readl(host, SDHCI_CAPABILITIES) & SDHCI_CAN_64BIT) {
312c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter			/* 64-bit DMA is not supported at present */
313c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter			dma_mask = DMA_BIT_MASK(32);
314c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter		} else {
315c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter			dma_mask = DMA_BIT_MASK(32);
316c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter		}
317c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter
31807f4450c9961b2980dd6485875a374923f0ccb63Russell King		err = dma_coerce_mask_and_coherent(dev, dma_mask);
31907f4450c9961b2980dd6485875a374923f0ccb63Russell King		if (err)
32007f4450c9961b2980dd6485875a374923f0ccb63Russell King			goto err_free;
321c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter	}
322c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter
323c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter	if (c->slot) {
324578b36b69c31c874f8303c62efb40b8bb9b46ae5Gao, Yunpeng		if (c->slot->probe_slot) {
3257dafca835a459ab31792d9def69ed30cf6dc08abAdrian Hunter			err = c->slot->probe_slot(pdev, hid, uid);
326578b36b69c31c874f8303c62efb40b8bb9b46ae5Gao, Yunpeng			if (err)
327578b36b69c31c874f8303c62efb40b8bb9b46ae5Gao, Yunpeng				goto err_free;
328578b36b69c31c874f8303c62efb40b8bb9b46ae5Gao, Yunpeng		}
329c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter		if (c->slot->chip) {
330c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter			host->ops            = c->slot->chip->ops;
331c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter			host->quirks        |= c->slot->chip->quirks;
332c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter			host->quirks2       |= c->slot->chip->quirks2;
333c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter			host->mmc->caps     |= c->slot->chip->caps;
334c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter			host->mmc->caps2    |= c->slot->chip->caps2;
335c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter			host->mmc->pm_caps  |= c->slot->chip->pm_caps;
336c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter		}
337c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter		host->quirks        |= c->slot->quirks;
338c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter		host->quirks2       |= c->slot->quirks2;
339c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter		host->mmc->caps     |= c->slot->caps;
340c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter		host->mmc->caps2    |= c->slot->caps2;
341c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter		host->mmc->pm_caps  |= c->slot->pm_caps;
342c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter	}
343c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter
3440d3e3350d5871c53464be4c92d57198744247005Adrian Hunter	host->mmc->caps2 |= MMC_CAP2_NO_PRESCAN_POWERUP;
3450d3e3350d5871c53464be4c92d57198744247005Adrian Hunter
346a61abe6eebfda1add8cb54e6e10384ea747d68a5Adrian Hunter	if (sdhci_acpi_flag(c, SDHCI_ACPI_SD_CD)) {
3474fd4409c81e2c756a5cfbedc598c48d6a3ed3fd5Adrian Hunter		bool v = sdhci_acpi_flag(c, SDHCI_ACPI_SD_CD_OVERRIDE_LEVEL);
3484fd4409c81e2c756a5cfbedc598c48d6a3ed3fd5Adrian Hunter
34989168b48991537bec2573b3b6a8841df74465b12Linus Walleij		if (mmc_gpiod_request_cd(host->mmc, NULL, 0, v, 0, NULL)) {
3504fd4409c81e2c756a5cfbedc598c48d6a3ed3fd5Adrian Hunter			dev_warn(dev, "failed to setup card detect gpio\n");
351a61abe6eebfda1add8cb54e6e10384ea747d68a5Adrian Hunter			c->use_runtime_pm = false;
3524fd4409c81e2c756a5cfbedc598c48d6a3ed3fd5Adrian Hunter		}
353a61abe6eebfda1add8cb54e6e10384ea747d68a5Adrian Hunter	}
354a61abe6eebfda1add8cb54e6e10384ea747d68a5Adrian Hunter
3554fd4409c81e2c756a5cfbedc598c48d6a3ed3fd5Adrian Hunter	err = sdhci_add_host(host);
3564fd4409c81e2c756a5cfbedc598c48d6a3ed3fd5Adrian Hunter	if (err)
3574fd4409c81e2c756a5cfbedc598c48d6a3ed3fd5Adrian Hunter		goto err_free;
3584fd4409c81e2c756a5cfbedc598c48d6a3ed3fd5Adrian Hunter
359c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter	if (c->use_runtime_pm) {
3601d1ff45871984364056ebfc528ed31ff7f03f970Adrian Hunter		pm_runtime_set_active(dev);
361c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter		pm_suspend_ignore_children(dev, 1);
362c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter		pm_runtime_set_autosuspend_delay(dev, 50);
363c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter		pm_runtime_use_autosuspend(dev);
364c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter		pm_runtime_enable(dev);
365c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter	}
366c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter
367c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter	return 0;
368c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter
369c4e050376c69bb9d67895842665264df2a2004d9Adrian Huntererr_free:
370c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter	sdhci_free_host(c->host);
371c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter	return err;
372c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter}
373c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter
3744e608e4ed9fea873c60749bdba2fbbbfb234bee0Greg Kroah-Hartmanstatic int sdhci_acpi_remove(struct platform_device *pdev)
375c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter{
376c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter	struct sdhci_acpi_host *c = platform_get_drvdata(pdev);
377c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter	struct device *dev = &pdev->dev;
378c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter	int dead;
379c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter
380c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter	if (c->use_runtime_pm) {
381c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter		pm_runtime_get_sync(dev);
382c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter		pm_runtime_disable(dev);
383c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter		pm_runtime_put_noidle(dev);
384c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter	}
385c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter
386578b36b69c31c874f8303c62efb40b8bb9b46ae5Gao, Yunpeng	if (c->slot && c->slot->remove_slot)
387578b36b69c31c874f8303c62efb40b8bb9b46ae5Gao, Yunpeng		c->slot->remove_slot(pdev);
388578b36b69c31c874f8303c62efb40b8bb9b46ae5Gao, Yunpeng
389c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter	dead = (sdhci_readl(c->host, SDHCI_INT_STATUS) == ~0);
390c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter	sdhci_remove_host(c->host, dead);
391c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter	sdhci_free_host(c->host);
392c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter
393c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter	return 0;
394c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter}
395c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter
396c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter#ifdef CONFIG_PM_SLEEP
397c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter
398c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunterstatic int sdhci_acpi_suspend(struct device *dev)
399c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter{
400c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter	struct sdhci_acpi_host *c = dev_get_drvdata(dev);
401c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter
402c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter	return sdhci_suspend_host(c->host);
403c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter}
404c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter
405c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunterstatic int sdhci_acpi_resume(struct device *dev)
406c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter{
407c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter	struct sdhci_acpi_host *c = dev_get_drvdata(dev);
408c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter
409c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter	return sdhci_resume_host(c->host);
410c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter}
411c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter
412c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter#else
413c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter
414c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter#define sdhci_acpi_suspend	NULL
415c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter#define sdhci_acpi_resume	NULL
416c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter
417c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter#endif
418c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter
419c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter#ifdef CONFIG_PM_RUNTIME
420c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter
421c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunterstatic int sdhci_acpi_runtime_suspend(struct device *dev)
422c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter{
423c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter	struct sdhci_acpi_host *c = dev_get_drvdata(dev);
424c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter
425c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter	return sdhci_runtime_suspend_host(c->host);
426c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter}
427c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter
428c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunterstatic int sdhci_acpi_runtime_resume(struct device *dev)
429c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter{
430c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter	struct sdhci_acpi_host *c = dev_get_drvdata(dev);
431c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter
432c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter	return sdhci_runtime_resume_host(c->host);
433c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter}
434c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter
435c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunterstatic int sdhci_acpi_runtime_idle(struct device *dev)
436c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter{
437c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter	return 0;
438c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter}
439c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter
440c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter#endif
441c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter
442c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunterstatic const struct dev_pm_ops sdhci_acpi_pm_ops = {
443c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter	.suspend		= sdhci_acpi_suspend,
444c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter	.resume			= sdhci_acpi_resume,
4451d75f74b14dbeee1bd9f1e96efa1cbebeb2804cbPeter Griffin	SET_RUNTIME_PM_OPS(sdhci_acpi_runtime_suspend,
4461d75f74b14dbeee1bd9f1e96efa1cbebeb2804cbPeter Griffin			sdhci_acpi_runtime_resume, sdhci_acpi_runtime_idle)
447c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter};
448c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter
449c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunterstatic struct platform_driver sdhci_acpi_driver = {
450c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter	.driver = {
451c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter		.name			= "sdhci-acpi",
452c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter		.owner			= THIS_MODULE,
453c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter		.acpi_match_table	= sdhci_acpi_ids,
454c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter		.pm			= &sdhci_acpi_pm_ops,
455c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter	},
456c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter	.probe	= sdhci_acpi_probe,
4574e608e4ed9fea873c60749bdba2fbbbfb234bee0Greg Kroah-Hartman	.remove	= sdhci_acpi_remove,
458c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter};
459c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter
460c4e050376c69bb9d67895842665264df2a2004d9Adrian Huntermodule_platform_driver(sdhci_acpi_driver);
461c4e050376c69bb9d67895842665264df2a2004d9Adrian Hunter
462c4e050376c69bb9d67895842665264df2a2004d9Adrian HunterMODULE_DESCRIPTION("Secure Digital Host Controller Interface ACPI driver");
463c4e050376c69bb9d67895842665264df2a2004d9Adrian HunterMODULE_AUTHOR("Adrian Hunter");
464c4e050376c69bb9d67895842665264df2a2004d9Adrian HunterMODULE_LICENSE("GPL v2");
465