12aec85b2SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only
22aec85b2SThomas Gleixner // Copyright (C) 2013 Broadcom Corporation
301ebea1bSChristian Daudt 
401ebea1bSChristian Daudt #include <linux/kernel.h>
501ebea1bSChristian Daudt #include <linux/module.h>
601ebea1bSChristian Daudt #include <linux/delay.h>
701ebea1bSChristian Daudt #include <linux/highmem.h>
801ebea1bSChristian Daudt #include <linux/platform_device.h>
901ebea1bSChristian Daudt #include <linux/mmc/host.h>
1001ebea1bSChristian Daudt #include <linux/io.h>
1101ebea1bSChristian Daudt #include <linux/clk.h>
1201ebea1bSChristian Daudt #include <linux/regulator/consumer.h>
1301ebea1bSChristian Daudt #include <linux/of.h>
1401ebea1bSChristian Daudt #include <linux/mmc/slot-gpio.h>
1501ebea1bSChristian Daudt 
1601ebea1bSChristian Daudt #include "sdhci-pltfm.h"
1701ebea1bSChristian Daudt #include "sdhci.h"
1801ebea1bSChristian Daudt 
1901ebea1bSChristian Daudt #define SDHCI_SOFT_RESET			0x01000000
2001ebea1bSChristian Daudt #define KONA_SDHOST_CORECTRL			0x8000
2101ebea1bSChristian Daudt #define KONA_SDHOST_CD_PINCTRL			0x00000008
2201ebea1bSChristian Daudt #define KONA_SDHOST_STOP_HCLK			0x00000004
2301ebea1bSChristian Daudt #define KONA_SDHOST_RESET			0x00000002
2401ebea1bSChristian Daudt #define KONA_SDHOST_EN				0x00000001
2501ebea1bSChristian Daudt 
2601ebea1bSChristian Daudt #define KONA_SDHOST_CORESTAT			0x8004
2701ebea1bSChristian Daudt #define KONA_SDHOST_WP				0x00000002
2801ebea1bSChristian Daudt #define KONA_SDHOST_CD_SW			0x00000001
2901ebea1bSChristian Daudt 
3001ebea1bSChristian Daudt #define KONA_SDHOST_COREIMR			0x8008
3101ebea1bSChristian Daudt #define KONA_SDHOST_IP				0x00000001
3201ebea1bSChristian Daudt 
3301ebea1bSChristian Daudt #define KONA_SDHOST_COREISR			0x800C
3401ebea1bSChristian Daudt #define KONA_SDHOST_COREIMSR			0x8010
3501ebea1bSChristian Daudt #define KONA_SDHOST_COREDBG1			0x8014
3601ebea1bSChristian Daudt #define KONA_SDHOST_COREGPO_MASK		0x8018
3701ebea1bSChristian Daudt 
3801ebea1bSChristian Daudt #define SD_DETECT_GPIO_DEBOUNCE_128MS		128
3901ebea1bSChristian Daudt 
4001ebea1bSChristian Daudt #define KONA_MMC_AUTOSUSPEND_DELAY		(50)
4101ebea1bSChristian Daudt 
4201ebea1bSChristian Daudt struct sdhci_bcm_kona_dev {
4301ebea1bSChristian Daudt 	struct mutex	write_lock; /* protect back to back writes */
4401ebea1bSChristian Daudt };
4501ebea1bSChristian Daudt 
4601ebea1bSChristian Daudt 
sdhci_bcm_kona_sd_reset(struct sdhci_host * host)4701ebea1bSChristian Daudt static int sdhci_bcm_kona_sd_reset(struct sdhci_host *host)
4801ebea1bSChristian Daudt {
4901ebea1bSChristian Daudt 	unsigned int val;
5001ebea1bSChristian Daudt 	unsigned long timeout;
5101ebea1bSChristian Daudt 
5201ebea1bSChristian Daudt 	/* This timeout should be sufficent for core to reset */
5301ebea1bSChristian Daudt 	timeout = jiffies + msecs_to_jiffies(100);
5401ebea1bSChristian Daudt 
5501ebea1bSChristian Daudt 	/* reset the host using the top level reset */
5601ebea1bSChristian Daudt 	val = sdhci_readl(host, KONA_SDHOST_CORECTRL);
5701ebea1bSChristian Daudt 	val |= KONA_SDHOST_RESET;
5801ebea1bSChristian Daudt 	sdhci_writel(host, val, KONA_SDHOST_CORECTRL);
5901ebea1bSChristian Daudt 
6001ebea1bSChristian Daudt 	while (!(sdhci_readl(host, KONA_SDHOST_CORECTRL) & KONA_SDHOST_RESET)) {
6101ebea1bSChristian Daudt 		if (time_is_before_jiffies(timeout)) {
6201ebea1bSChristian Daudt 			pr_err("Error: sd host is stuck in reset!!!\n");
6301ebea1bSChristian Daudt 			return -EFAULT;
6401ebea1bSChristian Daudt 		}
6501ebea1bSChristian Daudt 	}
6601ebea1bSChristian Daudt 
6701ebea1bSChristian Daudt 	/* bring the host out of reset */
6801ebea1bSChristian Daudt 	val = sdhci_readl(host, KONA_SDHOST_CORECTRL);
6901ebea1bSChristian Daudt 	val &= ~KONA_SDHOST_RESET;
7001ebea1bSChristian Daudt 
7101ebea1bSChristian Daudt 	/*
7201ebea1bSChristian Daudt 	 * Back-to-Back register write needs a delay of 1ms at bootup (min 10uS)
7301ebea1bSChristian Daudt 	 * Back-to-Back writes to same register needs delay when SD bus clock
7401ebea1bSChristian Daudt 	 * is very low w.r.t AHB clock, mainly during boot-time and during card
7501ebea1bSChristian Daudt 	 * insert-removal.
7601ebea1bSChristian Daudt 	 */
7701ebea1bSChristian Daudt 	usleep_range(1000, 5000);
7801ebea1bSChristian Daudt 	sdhci_writel(host, val, KONA_SDHOST_CORECTRL);
7901ebea1bSChristian Daudt 
8001ebea1bSChristian Daudt 	return 0;
8101ebea1bSChristian Daudt }
8201ebea1bSChristian Daudt 
sdhci_bcm_kona_sd_init(struct sdhci_host * host)8301ebea1bSChristian Daudt static void sdhci_bcm_kona_sd_init(struct sdhci_host *host)
8401ebea1bSChristian Daudt {
8501ebea1bSChristian Daudt 	unsigned int val;
8601ebea1bSChristian Daudt 
8701ebea1bSChristian Daudt 	/* enable the interrupt from the IP core */
8801ebea1bSChristian Daudt 	val = sdhci_readl(host, KONA_SDHOST_COREIMR);
8901ebea1bSChristian Daudt 	val |= KONA_SDHOST_IP;
9001ebea1bSChristian Daudt 	sdhci_writel(host, val, KONA_SDHOST_COREIMR);
9101ebea1bSChristian Daudt 
9201ebea1bSChristian Daudt 	/* Enable the AHB clock gating module to the host */
9301ebea1bSChristian Daudt 	val = sdhci_readl(host, KONA_SDHOST_CORECTRL);
9401ebea1bSChristian Daudt 	val |= KONA_SDHOST_EN;
9501ebea1bSChristian Daudt 
9601ebea1bSChristian Daudt 	/*
9701ebea1bSChristian Daudt 	 * Back-to-Back register write needs a delay of 1ms at bootup (min 10uS)
9801ebea1bSChristian Daudt 	 * Back-to-Back writes to same register needs delay when SD bus clock
9901ebea1bSChristian Daudt 	 * is very low w.r.t AHB clock, mainly during boot-time and during card
10001ebea1bSChristian Daudt 	 * insert-removal.
10101ebea1bSChristian Daudt 	 */
10201ebea1bSChristian Daudt 	usleep_range(1000, 5000);
10301ebea1bSChristian Daudt 	sdhci_writel(host, val, KONA_SDHOST_CORECTRL);
10401ebea1bSChristian Daudt }
10501ebea1bSChristian Daudt 
10601ebea1bSChristian Daudt /*
10701ebea1bSChristian Daudt  * Software emulation of the SD card insertion/removal. Set insert=1 for insert
10801ebea1bSChristian Daudt  * and insert=0 for removal. The card detection is done by GPIO. For Broadcom
10901ebea1bSChristian Daudt  * IP to function properly the bit 0 of CORESTAT register needs to be set/reset
11001ebea1bSChristian Daudt  * to generate the CD IRQ handled in sdhci.c which schedules card_tasklet.
11101ebea1bSChristian Daudt  */
sdhci_bcm_kona_sd_card_emulate(struct sdhci_host * host,int insert)11201ebea1bSChristian Daudt static int sdhci_bcm_kona_sd_card_emulate(struct sdhci_host *host, int insert)
11301ebea1bSChristian Daudt {
11401ebea1bSChristian Daudt 	struct sdhci_pltfm_host *pltfm_priv = sdhci_priv(host);
11501ebea1bSChristian Daudt 	struct sdhci_bcm_kona_dev *kona_dev = sdhci_pltfm_priv(pltfm_priv);
11601ebea1bSChristian Daudt 	u32 val;
11701ebea1bSChristian Daudt 
11801ebea1bSChristian Daudt 	/*
11901ebea1bSChristian Daudt 	 * Back-to-Back register write needs a delay of min 10uS.
12001ebea1bSChristian Daudt 	 * Back-to-Back writes to same register needs delay when SD bus clock
12101ebea1bSChristian Daudt 	 * is very low w.r.t AHB clock, mainly during boot-time and during card
12201ebea1bSChristian Daudt 	 * insert-removal.
12301ebea1bSChristian Daudt 	 * We keep 20uS
12401ebea1bSChristian Daudt 	 */
12501ebea1bSChristian Daudt 	mutex_lock(&kona_dev->write_lock);
12601ebea1bSChristian Daudt 	udelay(20);
12701ebea1bSChristian Daudt 	val = sdhci_readl(host, KONA_SDHOST_CORESTAT);
12801ebea1bSChristian Daudt 
12901ebea1bSChristian Daudt 	if (insert) {
13001ebea1bSChristian Daudt 		int ret;
13101ebea1bSChristian Daudt 
13201ebea1bSChristian Daudt 		ret = mmc_gpio_get_ro(host->mmc);
13301ebea1bSChristian Daudt 		if (ret >= 0)
13401ebea1bSChristian Daudt 			val = (val & ~KONA_SDHOST_WP) |
13501ebea1bSChristian Daudt 				((ret) ? KONA_SDHOST_WP : 0);
13601ebea1bSChristian Daudt 
13701ebea1bSChristian Daudt 		val |= KONA_SDHOST_CD_SW;
13801ebea1bSChristian Daudt 		sdhci_writel(host, val, KONA_SDHOST_CORESTAT);
13901ebea1bSChristian Daudt 	} else {
14001ebea1bSChristian Daudt 		val &= ~KONA_SDHOST_CD_SW;
14101ebea1bSChristian Daudt 		sdhci_writel(host, val, KONA_SDHOST_CORESTAT);
14201ebea1bSChristian Daudt 	}
14301ebea1bSChristian Daudt 	mutex_unlock(&kona_dev->write_lock);
14401ebea1bSChristian Daudt 
14501ebea1bSChristian Daudt 	return 0;
14601ebea1bSChristian Daudt }
14701ebea1bSChristian Daudt 
14801ebea1bSChristian Daudt /*
14901ebea1bSChristian Daudt  * SD card interrupt event callback
15001ebea1bSChristian Daudt  */
sdhci_bcm_kona_card_event(struct sdhci_host * host)151ceb2ea19SSachin Kamat static void sdhci_bcm_kona_card_event(struct sdhci_host *host)
15201ebea1bSChristian Daudt {
15301ebea1bSChristian Daudt 	if (mmc_gpio_get_cd(host->mmc) > 0) {
15401ebea1bSChristian Daudt 		dev_dbg(mmc_dev(host->mmc),
15501ebea1bSChristian Daudt 			"card inserted\n");
15601ebea1bSChristian Daudt 		sdhci_bcm_kona_sd_card_emulate(host, 1);
15701ebea1bSChristian Daudt 	} else {
15801ebea1bSChristian Daudt 		dev_dbg(mmc_dev(host->mmc),
15901ebea1bSChristian Daudt 			"card removed\n");
16001ebea1bSChristian Daudt 		sdhci_bcm_kona_sd_card_emulate(host, 0);
16101ebea1bSChristian Daudt 	}
16201ebea1bSChristian Daudt }
16301ebea1bSChristian Daudt 
sdhci_bcm_kona_init_74_clocks(struct sdhci_host * host,u8 power_mode)16401ebea1bSChristian Daudt static void sdhci_bcm_kona_init_74_clocks(struct sdhci_host *host,
16501ebea1bSChristian Daudt 				u8 power_mode)
16601ebea1bSChristian Daudt {
16701ebea1bSChristian Daudt 	/*
16801ebea1bSChristian Daudt 	 *  JEDEC and SD spec specify supplying 74 continuous clocks to
16901ebea1bSChristian Daudt 	 * device after power up. With minimum bus (100KHz) that
170ff50df9aSAdrian Hunter 	 * translates to 740us
17101ebea1bSChristian Daudt 	 */
17201ebea1bSChristian Daudt 	if (power_mode != MMC_POWER_OFF)
17301ebea1bSChristian Daudt 		udelay(740);
17401ebea1bSChristian Daudt }
17501ebea1bSChristian Daudt 
176b78f8a8cSJulia Lawall static const struct sdhci_ops sdhci_bcm_kona_ops = {
1771771059cSRussell King 	.set_clock = sdhci_set_clock,
1782290fcb3SKevin Hao 	.get_max_clock = sdhci_pltfm_clk_get_max_clock,
1792290fcb3SKevin Hao 	.get_timeout_clock = sdhci_pltfm_clk_get_max_clock,
18001ebea1bSChristian Daudt 	.platform_send_init_74_clocks = sdhci_bcm_kona_init_74_clocks,
1812317f56cSRussell King 	.set_bus_width = sdhci_set_bus_width,
18203231f9bSRussell King 	.reset = sdhci_reset,
18396d7b78cSRussell King 	.set_uhs_signaling = sdhci_set_uhs_signaling,
18401ebea1bSChristian Daudt 	.card_event = sdhci_bcm_kona_card_event,
18501ebea1bSChristian Daudt };
18601ebea1bSChristian Daudt 
187b78f8a8cSJulia Lawall static const struct sdhci_pltfm_data sdhci_pltfm_data_kona = {
18801ebea1bSChristian Daudt 	.ops    = &sdhci_bcm_kona_ops,
18901ebea1bSChristian Daudt 	.quirks = SDHCI_QUIRK_NO_CARD_NO_RESET |
19001ebea1bSChristian Daudt 		SDHCI_QUIRK_BROKEN_TIMEOUT_VAL | SDHCI_QUIRK_32BIT_DMA_ADDR |
19101ebea1bSChristian Daudt 		SDHCI_QUIRK_32BIT_DMA_SIZE | SDHCI_QUIRK_32BIT_ADMA_SIZE |
19201ebea1bSChristian Daudt 		SDHCI_QUIRK_FORCE_BLK_SZ_2048 |
19301ebea1bSChristian Daudt 		SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN,
19401ebea1bSChristian Daudt };
19501ebea1bSChristian Daudt 
196b3f635adSBehan Webster static const struct of_device_id sdhci_bcm_kona_of_match[] = {
197aea237bfSChristian Daudt 	{ .compatible = "brcm,kona-sdhci"},
198aea237bfSChristian Daudt 	{ .compatible = "bcm,kona-sdhci"}, /* deprecated name */
19901ebea1bSChristian Daudt 	{}
20001ebea1bSChristian Daudt };
20101ebea1bSChristian Daudt MODULE_DEVICE_TABLE(of, sdhci_bcm_kona_of_match);
20201ebea1bSChristian Daudt 
sdhci_bcm_kona_probe(struct platform_device * pdev)203058feb53SMarkus Mayer static int sdhci_bcm_kona_probe(struct platform_device *pdev)
20401ebea1bSChristian Daudt {
20501ebea1bSChristian Daudt 	struct sdhci_bcm_kona_dev *kona_dev = NULL;
20601ebea1bSChristian Daudt 	struct sdhci_pltfm_host *pltfm_priv;
20701ebea1bSChristian Daudt 	struct device *dev = &pdev->dev;
20801ebea1bSChristian Daudt 	struct sdhci_host *host;
20901ebea1bSChristian Daudt 	int ret;
21001ebea1bSChristian Daudt 
21101ebea1bSChristian Daudt 	ret = 0;
21201ebea1bSChristian Daudt 
21301ebea1bSChristian Daudt 	host = sdhci_pltfm_init(pdev, &sdhci_pltfm_data_kona,
21401ebea1bSChristian Daudt 			sizeof(*kona_dev));
21501ebea1bSChristian Daudt 	if (IS_ERR(host))
21601ebea1bSChristian Daudt 		return PTR_ERR(host);
21701ebea1bSChristian Daudt 
21801ebea1bSChristian Daudt 	dev_dbg(dev, "%s: inited. IOADDR=%p\n", __func__, host->ioaddr);
21901ebea1bSChristian Daudt 
22001ebea1bSChristian Daudt 	pltfm_priv = sdhci_priv(host);
22101ebea1bSChristian Daudt 
22201ebea1bSChristian Daudt 	kona_dev = sdhci_pltfm_priv(pltfm_priv);
22301ebea1bSChristian Daudt 	mutex_init(&kona_dev->write_lock);
22401ebea1bSChristian Daudt 
225acfa77b1SUlf Hansson 	ret = mmc_of_parse(host->mmc);
226acfa77b1SUlf Hansson 	if (ret)
227acfa77b1SUlf Hansson 		goto err_pltfm_free;
22801ebea1bSChristian Daudt 
22901ebea1bSChristian Daudt 	if (!host->mmc->f_max) {
23001ebea1bSChristian Daudt 		dev_err(&pdev->dev, "Missing max-freq for SDHCI cfg\n");
23101ebea1bSChristian Daudt 		ret = -ENXIO;
23201ebea1bSChristian Daudt 		goto err_pltfm_free;
23301ebea1bSChristian Daudt 	}
23401ebea1bSChristian Daudt 
2352290fcb3SKevin Hao 	/* Get and enable the core clock */
2362290fcb3SKevin Hao 	pltfm_priv->clk = devm_clk_get(dev, NULL);
2372290fcb3SKevin Hao 	if (IS_ERR(pltfm_priv->clk)) {
2382290fcb3SKevin Hao 		dev_err(dev, "Failed to get core clock\n");
2392290fcb3SKevin Hao 		ret = PTR_ERR(pltfm_priv->clk);
240a6492c02STim Kryger 		goto err_pltfm_free;
241a6492c02STim Kryger 	}
242a6492c02STim Kryger 
24366fe6ac5SWei Yongjun 	ret = clk_set_rate(pltfm_priv->clk, host->mmc->f_max);
24466fe6ac5SWei Yongjun 	if (ret) {
2452290fcb3SKevin Hao 		dev_err(dev, "Failed to set rate core clock\n");
246a6492c02STim Kryger 		goto err_pltfm_free;
247a6492c02STim Kryger 	}
248a6492c02STim Kryger 
24966fe6ac5SWei Yongjun 	ret = clk_prepare_enable(pltfm_priv->clk);
25066fe6ac5SWei Yongjun 	if (ret) {
2512290fcb3SKevin Hao 		dev_err(dev, "Failed to enable core clock\n");
252a6492c02STim Kryger 		goto err_pltfm_free;
253a6492c02STim Kryger 	}
254a6492c02STim Kryger 
25501ebea1bSChristian Daudt 	dev_dbg(dev, "non-removable=%c\n",
256860951c5SJaehoon Chung 		mmc_card_is_removable(host->mmc) ? 'N' : 'Y');
25701ebea1bSChristian Daudt 	dev_dbg(dev, "cd_gpio %c, wp_gpio %c\n",
25801ebea1bSChristian Daudt 		(mmc_gpio_get_cd(host->mmc) != -ENOSYS) ? 'Y' : 'N',
25901ebea1bSChristian Daudt 		(mmc_gpio_get_ro(host->mmc) != -ENOSYS) ? 'Y' : 'N');
26001ebea1bSChristian Daudt 
261860951c5SJaehoon Chung 	if (!mmc_card_is_removable(host->mmc))
26201ebea1bSChristian Daudt 		host->quirks |= SDHCI_QUIRK_BROKEN_CARD_DETECTION;
26301ebea1bSChristian Daudt 
26401ebea1bSChristian Daudt 	dev_dbg(dev, "is_8bit=%c\n",
26528804293SJavier Martinez Canillas 		(host->mmc->caps & MMC_CAP_8_BIT_DATA) ? 'Y' : 'N');
26601ebea1bSChristian Daudt 
26701ebea1bSChristian Daudt 	ret = sdhci_bcm_kona_sd_reset(host);
26801ebea1bSChristian Daudt 	if (ret)
269a6492c02STim Kryger 		goto err_clk_disable;
27001ebea1bSChristian Daudt 
27101ebea1bSChristian Daudt 	sdhci_bcm_kona_sd_init(host);
27201ebea1bSChristian Daudt 
27301ebea1bSChristian Daudt 	ret = sdhci_add_host(host);
274fb8617e1SJisheng Zhang 	if (ret)
27501ebea1bSChristian Daudt 		goto err_reset;
27601ebea1bSChristian Daudt 
27701ebea1bSChristian Daudt 	/* if device is eMMC, emulate card insert right here */
278860951c5SJaehoon Chung 	if (!mmc_card_is_removable(host->mmc)) {
27901ebea1bSChristian Daudt 		ret = sdhci_bcm_kona_sd_card_emulate(host, 1);
28001ebea1bSChristian Daudt 		if (ret) {
28101ebea1bSChristian Daudt 			dev_err(dev,
28201ebea1bSChristian Daudt 				"unable to emulate card insertion\n");
28301ebea1bSChristian Daudt 			goto err_remove_host;
28401ebea1bSChristian Daudt 		}
28501ebea1bSChristian Daudt 	}
28601ebea1bSChristian Daudt 	/*
28701ebea1bSChristian Daudt 	 * Since the card detection GPIO interrupt is configured to be
28801ebea1bSChristian Daudt 	 * edge sensitive, check the initial GPIO value here, emulate
28901ebea1bSChristian Daudt 	 * only if the card is present
29001ebea1bSChristian Daudt 	 */
29101ebea1bSChristian Daudt 	if (mmc_gpio_get_cd(host->mmc) > 0)
29201ebea1bSChristian Daudt 		sdhci_bcm_kona_sd_card_emulate(host, 1);
29301ebea1bSChristian Daudt 
29401ebea1bSChristian Daudt 	dev_dbg(dev, "initialized properly\n");
29501ebea1bSChristian Daudt 	return 0;
29601ebea1bSChristian Daudt 
29701ebea1bSChristian Daudt err_remove_host:
29801ebea1bSChristian Daudt 	sdhci_remove_host(host, 0);
29901ebea1bSChristian Daudt 
30001ebea1bSChristian Daudt err_reset:
30101ebea1bSChristian Daudt 	sdhci_bcm_kona_sd_reset(host);
30201ebea1bSChristian Daudt 
303a6492c02STim Kryger err_clk_disable:
3042290fcb3SKevin Hao 	clk_disable_unprepare(pltfm_priv->clk);
305a6492c02STim Kryger 
30601ebea1bSChristian Daudt err_pltfm_free:
30701ebea1bSChristian Daudt 	sdhci_pltfm_free(pdev);
30801ebea1bSChristian Daudt 
30901ebea1bSChristian Daudt 	dev_err(dev, "Probing of sdhci-pltfm failed: %d\n", ret);
31001ebea1bSChristian Daudt 	return ret;
31101ebea1bSChristian Daudt }
31201ebea1bSChristian Daudt 
sdhci_bcm_kona_remove(struct platform_device * pdev)313*8ebb607aSAdrian Hunter static void sdhci_bcm_kona_remove(struct platform_device *pdev)
314*8ebb607aSAdrian Hunter {
315*8ebb607aSAdrian Hunter 	struct sdhci_host *host = platform_get_drvdata(pdev);
316*8ebb607aSAdrian Hunter 	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
317*8ebb607aSAdrian Hunter 	struct clk *clk = pltfm_host->clk;
318*8ebb607aSAdrian Hunter 
319*8ebb607aSAdrian Hunter 	sdhci_pltfm_remove(pdev);
320*8ebb607aSAdrian Hunter 	clk_disable_unprepare(clk);
321*8ebb607aSAdrian Hunter }
322*8ebb607aSAdrian Hunter 
32301ebea1bSChristian Daudt static struct platform_driver sdhci_bcm_kona_driver = {
32401ebea1bSChristian Daudt 	.driver		= {
32501ebea1bSChristian Daudt 		.name	= "sdhci-kona",
32621b2cec6SDouglas Anderson 		.probe_type = PROBE_PREFER_ASYNCHRONOUS,
327fa243f64SUlf Hansson 		.pm	= &sdhci_pltfm_pmops,
328058feb53SMarkus Mayer 		.of_match_table = sdhci_bcm_kona_of_match,
32901ebea1bSChristian Daudt 	},
33001ebea1bSChristian Daudt 	.probe		= sdhci_bcm_kona_probe,
331*8ebb607aSAdrian Hunter 	.remove_new	= sdhci_bcm_kona_remove,
33201ebea1bSChristian Daudt };
33301ebea1bSChristian Daudt module_platform_driver(sdhci_bcm_kona_driver);
33401ebea1bSChristian Daudt 
33501ebea1bSChristian Daudt MODULE_DESCRIPTION("SDHCI driver for Broadcom Kona platform");
33601ebea1bSChristian Daudt MODULE_AUTHOR("Broadcom");
33701ebea1bSChristian Daudt MODULE_LICENSE("GPL v2");
338