101ebea1bSChristian Daudt /*
201ebea1bSChristian Daudt  * Copyright (C) 2013 Broadcom Corporation
301ebea1bSChristian Daudt  *
401ebea1bSChristian Daudt  * This program is free software; you can redistribute it and/or
501ebea1bSChristian Daudt  * modify it under the terms of the GNU General Public License as
601ebea1bSChristian Daudt  * published by the Free Software Foundation version 2.
701ebea1bSChristian Daudt  *
801ebea1bSChristian Daudt  * This program is distributed "as is" WITHOUT ANY WARRANTY of any
901ebea1bSChristian Daudt  * kind, whether express or implied; without even the implied warranty
1001ebea1bSChristian Daudt  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1101ebea1bSChristian Daudt  * GNU General Public License for more details.
1201ebea1bSChristian Daudt  */
1301ebea1bSChristian Daudt 
1401ebea1bSChristian Daudt #include <linux/kernel.h>
1501ebea1bSChristian Daudt #include <linux/module.h>
1601ebea1bSChristian Daudt #include <linux/delay.h>
1701ebea1bSChristian Daudt #include <linux/highmem.h>
1801ebea1bSChristian Daudt #include <linux/platform_device.h>
1901ebea1bSChristian Daudt #include <linux/mmc/host.h>
2001ebea1bSChristian Daudt #include <linux/io.h>
2101ebea1bSChristian Daudt #include <linux/gpio.h>
2201ebea1bSChristian Daudt #include <linux/clk.h>
2301ebea1bSChristian Daudt #include <linux/regulator/consumer.h>
2401ebea1bSChristian Daudt #include <linux/of.h>
2501ebea1bSChristian Daudt #include <linux/of_device.h>
2601ebea1bSChristian Daudt #include <linux/of_gpio.h>
2701ebea1bSChristian Daudt #include <linux/mmc/slot-gpio.h>
2801ebea1bSChristian Daudt 
2901ebea1bSChristian Daudt #include "sdhci-pltfm.h"
3001ebea1bSChristian Daudt #include "sdhci.h"
3101ebea1bSChristian Daudt 
3201ebea1bSChristian Daudt #define SDHCI_SOFT_RESET			0x01000000
3301ebea1bSChristian Daudt #define KONA_SDHOST_CORECTRL			0x8000
3401ebea1bSChristian Daudt #define KONA_SDHOST_CD_PINCTRL			0x00000008
3501ebea1bSChristian Daudt #define KONA_SDHOST_STOP_HCLK			0x00000004
3601ebea1bSChristian Daudt #define KONA_SDHOST_RESET			0x00000002
3701ebea1bSChristian Daudt #define KONA_SDHOST_EN				0x00000001
3801ebea1bSChristian Daudt 
3901ebea1bSChristian Daudt #define KONA_SDHOST_CORESTAT			0x8004
4001ebea1bSChristian Daudt #define KONA_SDHOST_WP				0x00000002
4101ebea1bSChristian Daudt #define KONA_SDHOST_CD_SW			0x00000001
4201ebea1bSChristian Daudt 
4301ebea1bSChristian Daudt #define KONA_SDHOST_COREIMR			0x8008
4401ebea1bSChristian Daudt #define KONA_SDHOST_IP				0x00000001
4501ebea1bSChristian Daudt 
4601ebea1bSChristian Daudt #define KONA_SDHOST_COREISR			0x800C
4701ebea1bSChristian Daudt #define KONA_SDHOST_COREIMSR			0x8010
4801ebea1bSChristian Daudt #define KONA_SDHOST_COREDBG1			0x8014
4901ebea1bSChristian Daudt #define KONA_SDHOST_COREGPO_MASK		0x8018
5001ebea1bSChristian Daudt 
5101ebea1bSChristian Daudt #define SD_DETECT_GPIO_DEBOUNCE_128MS		128
5201ebea1bSChristian Daudt 
5301ebea1bSChristian Daudt #define KONA_MMC_AUTOSUSPEND_DELAY		(50)
5401ebea1bSChristian Daudt 
5501ebea1bSChristian Daudt struct sdhci_bcm_kona_dev {
5601ebea1bSChristian Daudt 	struct mutex	write_lock; /* protect back to back writes */
5701ebea1bSChristian Daudt };
5801ebea1bSChristian Daudt 
5901ebea1bSChristian Daudt 
6001ebea1bSChristian Daudt static int sdhci_bcm_kona_sd_reset(struct sdhci_host *host)
6101ebea1bSChristian Daudt {
6201ebea1bSChristian Daudt 	unsigned int val;
6301ebea1bSChristian Daudt 	unsigned long timeout;
6401ebea1bSChristian Daudt 
6501ebea1bSChristian Daudt 	/* This timeout should be sufficent for core to reset */
6601ebea1bSChristian Daudt 	timeout = jiffies + msecs_to_jiffies(100);
6701ebea1bSChristian Daudt 
6801ebea1bSChristian Daudt 	/* reset the host using the top level reset */
6901ebea1bSChristian Daudt 	val = sdhci_readl(host, KONA_SDHOST_CORECTRL);
7001ebea1bSChristian Daudt 	val |= KONA_SDHOST_RESET;
7101ebea1bSChristian Daudt 	sdhci_writel(host, val, KONA_SDHOST_CORECTRL);
7201ebea1bSChristian Daudt 
7301ebea1bSChristian Daudt 	while (!(sdhci_readl(host, KONA_SDHOST_CORECTRL) & KONA_SDHOST_RESET)) {
7401ebea1bSChristian Daudt 		if (time_is_before_jiffies(timeout)) {
7501ebea1bSChristian Daudt 			pr_err("Error: sd host is stuck in reset!!!\n");
7601ebea1bSChristian Daudt 			return -EFAULT;
7701ebea1bSChristian Daudt 		}
7801ebea1bSChristian Daudt 	}
7901ebea1bSChristian Daudt 
8001ebea1bSChristian Daudt 	/* bring the host out of reset */
8101ebea1bSChristian Daudt 	val = sdhci_readl(host, KONA_SDHOST_CORECTRL);
8201ebea1bSChristian Daudt 	val &= ~KONA_SDHOST_RESET;
8301ebea1bSChristian Daudt 
8401ebea1bSChristian Daudt 	/*
8501ebea1bSChristian Daudt 	 * Back-to-Back register write needs a delay of 1ms at bootup (min 10uS)
8601ebea1bSChristian Daudt 	 * Back-to-Back writes to same register needs delay when SD bus clock
8701ebea1bSChristian Daudt 	 * is very low w.r.t AHB clock, mainly during boot-time and during card
8801ebea1bSChristian Daudt 	 * insert-removal.
8901ebea1bSChristian Daudt 	 */
9001ebea1bSChristian Daudt 	usleep_range(1000, 5000);
9101ebea1bSChristian Daudt 	sdhci_writel(host, val, KONA_SDHOST_CORECTRL);
9201ebea1bSChristian Daudt 
9301ebea1bSChristian Daudt 	return 0;
9401ebea1bSChristian Daudt }
9501ebea1bSChristian Daudt 
9601ebea1bSChristian Daudt static void sdhci_bcm_kona_sd_init(struct sdhci_host *host)
9701ebea1bSChristian Daudt {
9801ebea1bSChristian Daudt 	unsigned int val;
9901ebea1bSChristian Daudt 
10001ebea1bSChristian Daudt 	/* enable the interrupt from the IP core */
10101ebea1bSChristian Daudt 	val = sdhci_readl(host, KONA_SDHOST_COREIMR);
10201ebea1bSChristian Daudt 	val |= KONA_SDHOST_IP;
10301ebea1bSChristian Daudt 	sdhci_writel(host, val, KONA_SDHOST_COREIMR);
10401ebea1bSChristian Daudt 
10501ebea1bSChristian Daudt 	/* Enable the AHB clock gating module to the host */
10601ebea1bSChristian Daudt 	val = sdhci_readl(host, KONA_SDHOST_CORECTRL);
10701ebea1bSChristian Daudt 	val |= KONA_SDHOST_EN;
10801ebea1bSChristian Daudt 
10901ebea1bSChristian Daudt 	/*
11001ebea1bSChristian Daudt 	 * Back-to-Back register write needs a delay of 1ms at bootup (min 10uS)
11101ebea1bSChristian Daudt 	 * Back-to-Back writes to same register needs delay when SD bus clock
11201ebea1bSChristian Daudt 	 * is very low w.r.t AHB clock, mainly during boot-time and during card
11301ebea1bSChristian Daudt 	 * insert-removal.
11401ebea1bSChristian Daudt 	 */
11501ebea1bSChristian Daudt 	usleep_range(1000, 5000);
11601ebea1bSChristian Daudt 	sdhci_writel(host, val, KONA_SDHOST_CORECTRL);
11701ebea1bSChristian Daudt }
11801ebea1bSChristian Daudt 
11901ebea1bSChristian Daudt /*
12001ebea1bSChristian Daudt  * Software emulation of the SD card insertion/removal. Set insert=1 for insert
12101ebea1bSChristian Daudt  * and insert=0 for removal. The card detection is done by GPIO. For Broadcom
12201ebea1bSChristian Daudt  * IP to function properly the bit 0 of CORESTAT register needs to be set/reset
12301ebea1bSChristian Daudt  * to generate the CD IRQ handled in sdhci.c which schedules card_tasklet.
12401ebea1bSChristian Daudt  */
12501ebea1bSChristian Daudt static int sdhci_bcm_kona_sd_card_emulate(struct sdhci_host *host, int insert)
12601ebea1bSChristian Daudt {
12701ebea1bSChristian Daudt 	struct sdhci_pltfm_host *pltfm_priv = sdhci_priv(host);
12801ebea1bSChristian Daudt 	struct sdhci_bcm_kona_dev *kona_dev = sdhci_pltfm_priv(pltfm_priv);
12901ebea1bSChristian Daudt 	u32 val;
13001ebea1bSChristian Daudt 
13101ebea1bSChristian Daudt 	/*
13201ebea1bSChristian Daudt 	 * Back-to-Back register write needs a delay of min 10uS.
13301ebea1bSChristian Daudt 	 * Back-to-Back writes to same register needs delay when SD bus clock
13401ebea1bSChristian Daudt 	 * is very low w.r.t AHB clock, mainly during boot-time and during card
13501ebea1bSChristian Daudt 	 * insert-removal.
13601ebea1bSChristian Daudt 	 * We keep 20uS
13701ebea1bSChristian Daudt 	 */
13801ebea1bSChristian Daudt 	mutex_lock(&kona_dev->write_lock);
13901ebea1bSChristian Daudt 	udelay(20);
14001ebea1bSChristian Daudt 	val = sdhci_readl(host, KONA_SDHOST_CORESTAT);
14101ebea1bSChristian Daudt 
14201ebea1bSChristian Daudt 	if (insert) {
14301ebea1bSChristian Daudt 		int ret;
14401ebea1bSChristian Daudt 
14501ebea1bSChristian Daudt 		ret = mmc_gpio_get_ro(host->mmc);
14601ebea1bSChristian Daudt 		if (ret >= 0)
14701ebea1bSChristian Daudt 			val = (val & ~KONA_SDHOST_WP) |
14801ebea1bSChristian Daudt 				((ret) ? KONA_SDHOST_WP : 0);
14901ebea1bSChristian Daudt 
15001ebea1bSChristian Daudt 		val |= KONA_SDHOST_CD_SW;
15101ebea1bSChristian Daudt 		sdhci_writel(host, val, KONA_SDHOST_CORESTAT);
15201ebea1bSChristian Daudt 	} else {
15301ebea1bSChristian Daudt 		val &= ~KONA_SDHOST_CD_SW;
15401ebea1bSChristian Daudt 		sdhci_writel(host, val, KONA_SDHOST_CORESTAT);
15501ebea1bSChristian Daudt 	}
15601ebea1bSChristian Daudt 	mutex_unlock(&kona_dev->write_lock);
15701ebea1bSChristian Daudt 
15801ebea1bSChristian Daudt 	return 0;
15901ebea1bSChristian Daudt }
16001ebea1bSChristian Daudt 
16101ebea1bSChristian Daudt /*
16201ebea1bSChristian Daudt  * SD card interrupt event callback
16301ebea1bSChristian Daudt  */
164ceb2ea19SSachin Kamat static void sdhci_bcm_kona_card_event(struct sdhci_host *host)
16501ebea1bSChristian Daudt {
16601ebea1bSChristian Daudt 	if (mmc_gpio_get_cd(host->mmc) > 0) {
16701ebea1bSChristian Daudt 		dev_dbg(mmc_dev(host->mmc),
16801ebea1bSChristian Daudt 			"card inserted\n");
16901ebea1bSChristian Daudt 		sdhci_bcm_kona_sd_card_emulate(host, 1);
17001ebea1bSChristian Daudt 	} else {
17101ebea1bSChristian Daudt 		dev_dbg(mmc_dev(host->mmc),
17201ebea1bSChristian Daudt 			"card removed\n");
17301ebea1bSChristian Daudt 		sdhci_bcm_kona_sd_card_emulate(host, 0);
17401ebea1bSChristian Daudt 	}
17501ebea1bSChristian Daudt }
17601ebea1bSChristian Daudt 
17701ebea1bSChristian Daudt static void sdhci_bcm_kona_init_74_clocks(struct sdhci_host *host,
17801ebea1bSChristian Daudt 				u8 power_mode)
17901ebea1bSChristian Daudt {
18001ebea1bSChristian Daudt 	/*
18101ebea1bSChristian Daudt 	 *  JEDEC and SD spec specify supplying 74 continuous clocks to
18201ebea1bSChristian Daudt 	 * device after power up. With minimum bus (100KHz) that
18301ebea1bSChristian Daudt 	 * that translates to 740us
18401ebea1bSChristian Daudt 	 */
18501ebea1bSChristian Daudt 	if (power_mode != MMC_POWER_OFF)
18601ebea1bSChristian Daudt 		udelay(740);
18701ebea1bSChristian Daudt }
18801ebea1bSChristian Daudt 
18901ebea1bSChristian Daudt static struct sdhci_ops sdhci_bcm_kona_ops = {
1901771059cSRussell King 	.set_clock = sdhci_set_clock,
1912290fcb3SKevin Hao 	.get_max_clock = sdhci_pltfm_clk_get_max_clock,
1922290fcb3SKevin Hao 	.get_timeout_clock = sdhci_pltfm_clk_get_max_clock,
19301ebea1bSChristian Daudt 	.platform_send_init_74_clocks = sdhci_bcm_kona_init_74_clocks,
1942317f56cSRussell King 	.set_bus_width = sdhci_set_bus_width,
19503231f9bSRussell King 	.reset = sdhci_reset,
19696d7b78cSRussell King 	.set_uhs_signaling = sdhci_set_uhs_signaling,
19701ebea1bSChristian Daudt 	.card_event = sdhci_bcm_kona_card_event,
19801ebea1bSChristian Daudt };
19901ebea1bSChristian Daudt 
20001ebea1bSChristian Daudt static struct sdhci_pltfm_data sdhci_pltfm_data_kona = {
20101ebea1bSChristian Daudt 	.ops    = &sdhci_bcm_kona_ops,
20201ebea1bSChristian Daudt 	.quirks = SDHCI_QUIRK_NO_CARD_NO_RESET |
20301ebea1bSChristian Daudt 		SDHCI_QUIRK_BROKEN_TIMEOUT_VAL | SDHCI_QUIRK_32BIT_DMA_ADDR |
20401ebea1bSChristian Daudt 		SDHCI_QUIRK_32BIT_DMA_SIZE | SDHCI_QUIRK_32BIT_ADMA_SIZE |
20501ebea1bSChristian Daudt 		SDHCI_QUIRK_FORCE_BLK_SZ_2048 |
20601ebea1bSChristian Daudt 		SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN,
20701ebea1bSChristian Daudt };
20801ebea1bSChristian Daudt 
209b3f635adSBehan Webster static const struct of_device_id sdhci_bcm_kona_of_match[] = {
210aea237bfSChristian Daudt 	{ .compatible = "brcm,kona-sdhci"},
211aea237bfSChristian Daudt 	{ .compatible = "bcm,kona-sdhci"}, /* deprecated name */
21201ebea1bSChristian Daudt 	{}
21301ebea1bSChristian Daudt };
21401ebea1bSChristian Daudt MODULE_DEVICE_TABLE(of, sdhci_bcm_kona_of_match);
21501ebea1bSChristian Daudt 
216058feb53SMarkus Mayer static int sdhci_bcm_kona_probe(struct platform_device *pdev)
21701ebea1bSChristian Daudt {
21801ebea1bSChristian Daudt 	struct sdhci_bcm_kona_dev *kona_dev = NULL;
21901ebea1bSChristian Daudt 	struct sdhci_pltfm_host *pltfm_priv;
22001ebea1bSChristian Daudt 	struct device *dev = &pdev->dev;
22101ebea1bSChristian Daudt 	struct sdhci_host *host;
22201ebea1bSChristian Daudt 	int ret;
22301ebea1bSChristian Daudt 
22401ebea1bSChristian Daudt 	ret = 0;
22501ebea1bSChristian Daudt 
22601ebea1bSChristian Daudt 	host = sdhci_pltfm_init(pdev, &sdhci_pltfm_data_kona,
22701ebea1bSChristian Daudt 			sizeof(*kona_dev));
22801ebea1bSChristian Daudt 	if (IS_ERR(host))
22901ebea1bSChristian Daudt 		return PTR_ERR(host);
23001ebea1bSChristian Daudt 
23101ebea1bSChristian Daudt 	dev_dbg(dev, "%s: inited. IOADDR=%p\n", __func__, host->ioaddr);
23201ebea1bSChristian Daudt 
23301ebea1bSChristian Daudt 	pltfm_priv = sdhci_priv(host);
23401ebea1bSChristian Daudt 
23501ebea1bSChristian Daudt 	kona_dev = sdhci_pltfm_priv(pltfm_priv);
23601ebea1bSChristian Daudt 	mutex_init(&kona_dev->write_lock);
23701ebea1bSChristian Daudt 
238acfa77b1SUlf Hansson 	ret = mmc_of_parse(host->mmc);
239acfa77b1SUlf Hansson 	if (ret)
240acfa77b1SUlf Hansson 		goto err_pltfm_free;
24101ebea1bSChristian Daudt 
24201ebea1bSChristian Daudt 	if (!host->mmc->f_max) {
24301ebea1bSChristian Daudt 		dev_err(&pdev->dev, "Missing max-freq for SDHCI cfg\n");
24401ebea1bSChristian Daudt 		ret = -ENXIO;
24501ebea1bSChristian Daudt 		goto err_pltfm_free;
24601ebea1bSChristian Daudt 	}
24701ebea1bSChristian Daudt 
2482290fcb3SKevin Hao 	/* Get and enable the core clock */
2492290fcb3SKevin Hao 	pltfm_priv->clk = devm_clk_get(dev, NULL);
2502290fcb3SKevin Hao 	if (IS_ERR(pltfm_priv->clk)) {
2512290fcb3SKevin Hao 		dev_err(dev, "Failed to get core clock\n");
2522290fcb3SKevin Hao 		ret = PTR_ERR(pltfm_priv->clk);
253a6492c02STim Kryger 		goto err_pltfm_free;
254a6492c02STim Kryger 	}
255a6492c02STim Kryger 
2562290fcb3SKevin Hao 	if (clk_set_rate(pltfm_priv->clk, host->mmc->f_max) != 0) {
2572290fcb3SKevin Hao 		dev_err(dev, "Failed to set rate core clock\n");
258a6492c02STim Kryger 		goto err_pltfm_free;
259a6492c02STim Kryger 	}
260a6492c02STim Kryger 
2612290fcb3SKevin Hao 	if (clk_prepare_enable(pltfm_priv->clk) != 0) {
2622290fcb3SKevin Hao 		dev_err(dev, "Failed to enable core clock\n");
263a6492c02STim Kryger 		goto err_pltfm_free;
264a6492c02STim Kryger 	}
265a6492c02STim Kryger 
26601ebea1bSChristian Daudt 	dev_dbg(dev, "non-removable=%c\n",
26701ebea1bSChristian Daudt 		(host->mmc->caps & MMC_CAP_NONREMOVABLE) ? 'Y' : 'N');
26801ebea1bSChristian Daudt 	dev_dbg(dev, "cd_gpio %c, wp_gpio %c\n",
26901ebea1bSChristian Daudt 		(mmc_gpio_get_cd(host->mmc) != -ENOSYS) ? 'Y' : 'N',
27001ebea1bSChristian Daudt 		(mmc_gpio_get_ro(host->mmc) != -ENOSYS) ? 'Y' : 'N');
27101ebea1bSChristian Daudt 
272cf68b629SChristian Daudt 	if (host->mmc->caps & MMC_CAP_NONREMOVABLE)
27301ebea1bSChristian Daudt 		host->quirks |= SDHCI_QUIRK_BROKEN_CARD_DETECTION;
27401ebea1bSChristian Daudt 
27501ebea1bSChristian Daudt 	dev_dbg(dev, "is_8bit=%c\n",
27628804293SJavier Martinez Canillas 		(host->mmc->caps & MMC_CAP_8_BIT_DATA) ? 'Y' : 'N');
27701ebea1bSChristian Daudt 
27801ebea1bSChristian Daudt 	ret = sdhci_bcm_kona_sd_reset(host);
27901ebea1bSChristian Daudt 	if (ret)
280a6492c02STim Kryger 		goto err_clk_disable;
28101ebea1bSChristian Daudt 
28201ebea1bSChristian Daudt 	sdhci_bcm_kona_sd_init(host);
28301ebea1bSChristian Daudt 
28401ebea1bSChristian Daudt 	ret = sdhci_add_host(host);
28501ebea1bSChristian Daudt 	if (ret) {
28601ebea1bSChristian Daudt 		dev_err(dev, "Failed sdhci_add_host\n");
28701ebea1bSChristian Daudt 		goto err_reset;
28801ebea1bSChristian Daudt 	}
28901ebea1bSChristian Daudt 
29001ebea1bSChristian Daudt 	/* if device is eMMC, emulate card insert right here */
291cf68b629SChristian Daudt 	if (host->mmc->caps & MMC_CAP_NONREMOVABLE) {
29201ebea1bSChristian Daudt 		ret = sdhci_bcm_kona_sd_card_emulate(host, 1);
29301ebea1bSChristian Daudt 		if (ret) {
29401ebea1bSChristian Daudt 			dev_err(dev,
29501ebea1bSChristian Daudt 				"unable to emulate card insertion\n");
29601ebea1bSChristian Daudt 			goto err_remove_host;
29701ebea1bSChristian Daudt 		}
29801ebea1bSChristian Daudt 	}
29901ebea1bSChristian Daudt 	/*
30001ebea1bSChristian Daudt 	 * Since the card detection GPIO interrupt is configured to be
30101ebea1bSChristian Daudt 	 * edge sensitive, check the initial GPIO value here, emulate
30201ebea1bSChristian Daudt 	 * only if the card is present
30301ebea1bSChristian Daudt 	 */
30401ebea1bSChristian Daudt 	if (mmc_gpio_get_cd(host->mmc) > 0)
30501ebea1bSChristian Daudt 		sdhci_bcm_kona_sd_card_emulate(host, 1);
30601ebea1bSChristian Daudt 
30701ebea1bSChristian Daudt 	dev_dbg(dev, "initialized properly\n");
30801ebea1bSChristian Daudt 	return 0;
30901ebea1bSChristian Daudt 
31001ebea1bSChristian Daudt err_remove_host:
31101ebea1bSChristian Daudt 	sdhci_remove_host(host, 0);
31201ebea1bSChristian Daudt 
31301ebea1bSChristian Daudt err_reset:
31401ebea1bSChristian Daudt 	sdhci_bcm_kona_sd_reset(host);
31501ebea1bSChristian Daudt 
316a6492c02STim Kryger err_clk_disable:
3172290fcb3SKevin Hao 	clk_disable_unprepare(pltfm_priv->clk);
318a6492c02STim Kryger 
31901ebea1bSChristian Daudt err_pltfm_free:
32001ebea1bSChristian Daudt 	sdhci_pltfm_free(pdev);
32101ebea1bSChristian Daudt 
32201ebea1bSChristian Daudt 	dev_err(dev, "Probing of sdhci-pltfm failed: %d\n", ret);
32301ebea1bSChristian Daudt 	return ret;
32401ebea1bSChristian Daudt }
32501ebea1bSChristian Daudt 
32601ebea1bSChristian Daudt static struct platform_driver sdhci_bcm_kona_driver = {
32701ebea1bSChristian Daudt 	.driver		= {
32801ebea1bSChristian Daudt 		.name	= "sdhci-kona",
32901ebea1bSChristian Daudt 		.pm	= SDHCI_PLTFM_PMOPS,
330058feb53SMarkus Mayer 		.of_match_table = sdhci_bcm_kona_of_match,
33101ebea1bSChristian Daudt 	},
33201ebea1bSChristian Daudt 	.probe		= sdhci_bcm_kona_probe,
333caebcae9SKevin Hao 	.remove		= sdhci_pltfm_unregister,
33401ebea1bSChristian Daudt };
33501ebea1bSChristian Daudt module_platform_driver(sdhci_bcm_kona_driver);
33601ebea1bSChristian Daudt 
33701ebea1bSChristian Daudt MODULE_DESCRIPTION("SDHCI driver for Broadcom Kona platform");
33801ebea1bSChristian Daudt MODULE_AUTHOR("Broadcom");
33901ebea1bSChristian Daudt MODULE_LICENSE("GPL v2");
340