summaryrefslogtreecommitdiff
path: root/drivers/mmc/host
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mmc/host')
-rw-r--r--drivers/mmc/host/Kconfig5
-rw-r--r--drivers/mmc/host/alcor.c6
-rw-r--r--drivers/mmc/host/atmel-mci.c140
-rw-r--r--drivers/mmc/host/au1xmmc.c5
-rw-r--r--drivers/mmc/host/bcm2835.c6
-rw-r--r--drivers/mmc/host/cavium-octeon.c7
-rw-r--r--drivers/mmc/host/cavium-thunderx.c1
-rw-r--r--drivers/mmc/host/cb710-mmc.c5
-rw-r--r--drivers/mmc/host/davinci_mmc.c9
-rw-r--r--drivers/mmc/host/dw_mmc-exynos.c6
-rw-r--r--drivers/mmc/host/dw_mmc-hi3798cv200.c6
-rw-r--r--drivers/mmc/host/dw_mmc-rockchip.c6
-rw-r--r--drivers/mmc/host/jz4740_mmc.c6
-rw-r--r--drivers/mmc/host/litex_mmc.c5
-rw-r--r--drivers/mmc/host/meson-gx-mmc.c11
-rw-r--r--drivers/mmc/host/meson-mx-sdhc-mmc.c6
-rw-r--r--drivers/mmc/host/meson-mx-sdio.c6
-rw-r--r--drivers/mmc/host/mmci.c39
-rw-r--r--drivers/mmc/host/moxart-mmc.c16
-rw-r--r--drivers/mmc/host/mtk-sd.c10
-rw-r--r--drivers/mmc/host/mvsdio.c6
-rw-r--r--drivers/mmc/host/mxcmmc.c10
-rw-r--r--drivers/mmc/host/mxs-mmc.c7
-rw-r--r--drivers/mmc/host/omap.c6
-rw-r--r--drivers/mmc/host/omap_hsmmc.c11
-rw-r--r--drivers/mmc/host/owl-mmc.c9
-rw-r--r--drivers/mmc/host/pxamci.c12
-rw-r--r--drivers/mmc/host/renesas_sdhi.h2
-rw-r--r--drivers/mmc/host/renesas_sdhi_core.c26
-rw-r--r--drivers/mmc/host/renesas_sdhi_internal_dmac.c5
-rw-r--r--drivers/mmc/host/renesas_sdhi_sys_dmac.c5
-rw-r--r--drivers/mmc/host/rtsx_pci_sdmmc.c9
-rw-r--r--drivers/mmc/host/rtsx_usb_sdmmc.c8
-rw-r--r--drivers/mmc/host/sdhci-acpi.c6
-rw-r--r--drivers/mmc/host/sdhci-bcm-kona.c13
-rw-r--r--drivers/mmc/host/sdhci-brcmstb.c18
-rw-r--r--drivers/mmc/host/sdhci-cadence.c19
-rw-r--r--drivers/mmc/host/sdhci-dove.c8
-rw-r--r--drivers/mmc/host/sdhci-esdhc-imx.c15
-rw-r--r--drivers/mmc/host/sdhci-esdhc-mcf.c6
-rw-r--r--drivers/mmc/host/sdhci-iproc.c16
-rw-r--r--drivers/mmc/host/sdhci-milbeaut.c8
-rw-r--r--drivers/mmc/host/sdhci-msm.c7
-rw-r--r--drivers/mmc/host/sdhci-of-arasan.c14
-rw-r--r--drivers/mmc/host/sdhci-of-aspeed.c15
-rw-r--r--drivers/mmc/host/sdhci-of-at91.c10
-rw-r--r--drivers/mmc/host/sdhci-of-dwcmshc.c93
-rw-r--r--drivers/mmc/host/sdhci-of-esdhc.c2
-rw-r--r--drivers/mmc/host/sdhci-of-hlwd.c4
-rw-r--r--drivers/mmc/host/sdhci-of-sparx5.c19
-rw-r--r--drivers/mmc/host/sdhci-omap.c7
-rw-r--r--drivers/mmc/host/sdhci-pci-core.c4
-rw-r--r--drivers/mmc/host/sdhci-pci-o2micro.c211
-rw-r--r--drivers/mmc/host/sdhci-pci.h4
-rw-r--r--drivers/mmc/host/sdhci-pic32.c6
-rw-r--r--drivers/mmc/host/sdhci-pltfm.c16
-rw-r--r--drivers/mmc/host/sdhci-pltfm.h8
-rw-r--r--drivers/mmc/host/sdhci-pxav2.c20
-rw-r--r--drivers/mmc/host/sdhci-pxav3.c6
-rw-r--r--drivers/mmc/host/sdhci-s3c.c7
-rw-r--r--drivers/mmc/host/sdhci-spear.c10
-rw-r--r--drivers/mmc/host/sdhci-sprd.c156
-rw-r--r--drivers/mmc/host/sdhci-st.c15
-rw-r--r--drivers/mmc/host/sdhci-tegra.c7
-rw-r--r--drivers/mmc/host/sdhci-xenon.c6
-rw-r--r--drivers/mmc/host/sdhci_am654.c14
-rw-r--r--drivers/mmc/host/sdhci_f_sdh30.c77
-rw-r--r--drivers/mmc/host/sh_mmcif.c7
-rw-r--r--drivers/mmc/host/sunplus-mmc.c35
-rw-r--r--drivers/mmc/host/sunxi-mmc.c6
-rw-r--r--drivers/mmc/host/uniphier-sd.c19
-rw-r--r--drivers/mmc/host/usdhi6rol0.c6
-rw-r--r--drivers/mmc/host/via-sdmmc.c2
-rw-r--r--drivers/mmc/host/wbsd.c11
-rw-r--r--drivers/mmc/host/wmt-sdmmc.c7
75 files changed, 804 insertions, 553 deletions
diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig
index 159a3e9490ae..554e67103c1a 100644
--- a/drivers/mmc/host/Kconfig
+++ b/drivers/mmc/host/Kconfig
@@ -526,11 +526,12 @@ config MMC_ALCOR
of Alcor Micro PCI-E card reader
config MMC_AU1X
- tristate "Alchemy AU1XX0 MMC Card Interface support"
+ bool "Alchemy AU1XX0 MMC Card Interface support"
depends on MIPS_ALCHEMY
+ depends on MMC=y
help
This selects the AMD Alchemy(R) Multimedia card interface.
- If you have a Alchemy platform with a MMC slot, say Y or M here.
+ If you have a Alchemy platform with a MMC slot, say Y here.
If unsure, say N.
diff --git a/drivers/mmc/host/alcor.c b/drivers/mmc/host/alcor.c
index d01df01d4b4d..42aa43740ba8 100644
--- a/drivers/mmc/host/alcor.c
+++ b/drivers/mmc/host/alcor.c
@@ -1125,7 +1125,7 @@ free_host:
return ret;
}
-static int alcor_pci_sdmmc_drv_remove(struct platform_device *pdev)
+static void alcor_pci_sdmmc_drv_remove(struct platform_device *pdev)
{
struct alcor_sdmmc_host *host = dev_get_drvdata(&pdev->dev);
struct mmc_host *mmc = mmc_from_priv(host);
@@ -1136,8 +1136,6 @@ static int alcor_pci_sdmmc_drv_remove(struct platform_device *pdev)
alcor_hw_uninit(host);
mmc_remove_host(mmc);
mmc_free_host(mmc);
-
- return 0;
}
#ifdef CONFIG_PM_SLEEP
@@ -1177,7 +1175,7 @@ MODULE_DEVICE_TABLE(platform, alcor_pci_sdmmc_ids);
static struct platform_driver alcor_pci_sdmmc_driver = {
.probe = alcor_pci_sdmmc_drv_probe,
- .remove = alcor_pci_sdmmc_drv_remove,
+ .remove_new = alcor_pci_sdmmc_drv_remove,
.id_table = alcor_pci_sdmmc_ids,
.driver = {
.name = DRV_NAME_ALCOR_PCI_SDMMC,
diff --git a/drivers/mmc/host/atmel-mci.c b/drivers/mmc/host/atmel-mci.c
index dd18440a90c5..535783c43105 100644
--- a/drivers/mmc/host/atmel-mci.c
+++ b/drivers/mmc/host/atmel-mci.c
@@ -11,15 +11,14 @@
#include <linux/dmaengine.h>
#include <linux/dma-mapping.h>
#include <linux/err.h>
-#include <linux/gpio.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/ioport.h>
#include <linux/module.h>
#include <linux/of.h>
-#include <linux/of_device.h>
-#include <linux/of_gpio.h>
+#include <linux/irq.h>
+#include <linux/gpio/consumer.h>
#include <linux/platform_device.h>
#include <linux/scatterlist.h>
#include <linux/seq_file.h>
@@ -30,7 +29,6 @@
#include <linux/mmc/host.h>
#include <linux/mmc/sdio.h>
-#include <linux/atmel-mci.h>
#include <linux/atmel_pdc.h>
#include <linux/pm.h>
#include <linux/pm_runtime.h>
@@ -40,6 +38,8 @@
#include <asm/io.h>
#include <asm/unaligned.h>
+#define ATMCI_MAX_NR_SLOTS 2
+
/*
* Superset of MCI IP registers integrated in Atmel AT91 Processor
* Registers and bitfields marked with [2] are only available in MCI2
@@ -201,6 +201,40 @@ enum atmci_pdc_buf {
PDC_SECOND_BUF,
};
+/**
+ * struct mci_slot_pdata - board-specific per-slot configuration
+ * @bus_width: Number of data lines wired up the slot
+ * @detect_pin: GPIO pin wired to the card detect switch
+ * @wp_pin: GPIO pin wired to the write protect sensor
+ * @non_removable: The slot is not removable, only detect once
+ *
+ * If a given slot is not present on the board, @bus_width should be
+ * set to 0. The other fields are ignored in this case.
+ *
+ * Any pins that aren't available should be set to a negative value.
+ *
+ * Note that support for multiple slots is experimental -- some cards
+ * might get upset if we don't get the clock management exactly right.
+ * But in most cases, it should work just fine.
+ */
+struct mci_slot_pdata {
+ unsigned int bus_width;
+ struct gpio_desc *detect_pin;
+ struct gpio_desc *wp_pin;
+ bool non_removable;
+};
+
+/**
+ * struct mci_platform_data - board-specific MMC/SDcard configuration
+ * @dma_slave: DMA slave interface to use in data transfers.
+ * @slot: Per-slot configuration data.
+ */
+struct mci_platform_data {
+ void *dma_slave;
+ dma_filter_fn dma_filter;
+ struct mci_slot_pdata slot[ATMCI_MAX_NR_SLOTS];
+};
+
struct atmel_mci_caps {
bool has_dma_conf_reg;
bool has_pdc;
@@ -369,7 +403,6 @@ struct atmel_mci {
* available.
* @wp_pin: GPIO pin used for card write protect sending, or negative
* if not available.
- * @detect_is_active_high: The state of the detect pin when it is active.
* @detect_timer: Timer used for debouncing @detect_pin interrupts.
*/
struct atmel_mci_slot {
@@ -388,9 +421,8 @@ struct atmel_mci_slot {
#define ATMCI_CARD_NEED_INIT 1
#define ATMCI_SHUTDOWN 2
- int detect_pin;
- int wp_pin;
- bool detect_is_active_high;
+ struct gpio_desc *detect_pin;
+ struct gpio_desc *wp_pin;
struct timer_list detect_timer;
};
@@ -608,6 +640,7 @@ atmci_of_init(struct platform_device *pdev)
struct device_node *cnp;
struct mci_platform_data *pdata;
u32 slot_id;
+ int err;
if (!np) {
dev_err(&pdev->dev, "device node not found\n");
@@ -637,16 +670,27 @@ atmci_of_init(struct platform_device *pdev)
pdata->slot[slot_id].bus_width = 1;
pdata->slot[slot_id].detect_pin =
- of_get_named_gpio(cnp, "cd-gpios", 0);
-
- pdata->slot[slot_id].detect_is_active_high =
- of_property_read_bool(cnp, "cd-inverted");
+ devm_fwnode_gpiod_get(&pdev->dev, of_fwnode_handle(cnp),
+ "cd", GPIOD_IN, "cd-gpios");
+ err = PTR_ERR_OR_ZERO(pdata->slot[slot_id].detect_pin);
+ if (err) {
+ if (err != -ENOENT)
+ return ERR_PTR(err);
+ pdata->slot[slot_id].detect_pin = NULL;
+ }
pdata->slot[slot_id].non_removable =
of_property_read_bool(cnp, "non-removable");
pdata->slot[slot_id].wp_pin =
- of_get_named_gpio(cnp, "wp-gpios", 0);
+ devm_fwnode_gpiod_get(&pdev->dev, of_fwnode_handle(cnp),
+ "wp", GPIOD_IN, "wp-gpios");
+ err = PTR_ERR_OR_ZERO(pdata->slot[slot_id].wp_pin);
+ if (err) {
+ if (err != -ENOENT)
+ return ERR_PTR(err);
+ pdata->slot[slot_id].wp_pin = NULL;
+ }
}
return pdata;
@@ -1509,8 +1553,8 @@ static int atmci_get_ro(struct mmc_host *mmc)
int read_only = -ENOSYS;
struct atmel_mci_slot *slot = mmc_priv(mmc);
- if (gpio_is_valid(slot->wp_pin)) {
- read_only = gpio_get_value(slot->wp_pin);
+ if (slot->wp_pin) {
+ read_only = gpiod_get_value(slot->wp_pin);
dev_dbg(&mmc->class_dev, "card is %s\n",
read_only ? "read-only" : "read-write");
}
@@ -1523,9 +1567,8 @@ static int atmci_get_cd(struct mmc_host *mmc)
int present = -ENOSYS;
struct atmel_mci_slot *slot = mmc_priv(mmc);
- if (gpio_is_valid(slot->detect_pin)) {
- present = !(gpio_get_value(slot->detect_pin) ^
- slot->detect_is_active_high);
+ if (slot->detect_pin) {
+ present = gpiod_get_value_cansleep(slot->detect_pin);
dev_dbg(&mmc->class_dev, "card is %spresent\n",
present ? "" : "not ");
}
@@ -1637,9 +1680,8 @@ static void atmci_detect_change(struct timer_list *t)
if (test_bit(ATMCI_SHUTDOWN, &slot->flags))
return;
- enable_irq(gpio_to_irq(slot->detect_pin));
- present = !(gpio_get_value(slot->detect_pin) ^
- slot->detect_is_active_high);
+ enable_irq(gpiod_to_irq(slot->detect_pin));
+ present = gpiod_get_value_cansleep(slot->detect_pin);
present_old = test_bit(ATMCI_CARD_PRESENT, &slot->flags);
dev_vdbg(&slot->mmc->class_dev, "detect change: %d (was %d)\n",
@@ -2230,16 +2272,15 @@ static int atmci_init_slot(struct atmel_mci *host,
slot->host = host;
slot->detect_pin = slot_data->detect_pin;
slot->wp_pin = slot_data->wp_pin;
- slot->detect_is_active_high = slot_data->detect_is_active_high;
slot->sdc_reg = sdc_reg;
slot->sdio_irq = sdio_irq;
dev_dbg(&mmc->class_dev,
"slot[%u]: bus_width=%u, detect_pin=%d, "
"detect_is_active_high=%s, wp_pin=%d\n",
- id, slot_data->bus_width, slot_data->detect_pin,
- slot_data->detect_is_active_high ? "true" : "false",
- slot_data->wp_pin);
+ id, slot_data->bus_width, desc_to_gpio(slot_data->detect_pin),
+ !gpiod_is_active_low(slot_data->detect_pin) ? "true" : "false",
+ desc_to_gpio(slot_data->wp_pin));
mmc->ops = &atmci_ops;
mmc->f_min = DIV_ROUND_UP(host->bus_hz, 512);
@@ -2275,31 +2316,22 @@ static int atmci_init_slot(struct atmel_mci *host,
/* Assume card is present initially */
set_bit(ATMCI_CARD_PRESENT, &slot->flags);
- if (gpio_is_valid(slot->detect_pin)) {
- if (devm_gpio_request(&host->pdev->dev, slot->detect_pin,
- "mmc_detect")) {
- dev_dbg(&mmc->class_dev, "no detect pin available\n");
- slot->detect_pin = -EBUSY;
- } else if (gpio_get_value(slot->detect_pin) ^
- slot->detect_is_active_high) {
+ if (slot->detect_pin) {
+ if (!gpiod_get_value_cansleep(slot->detect_pin))
clear_bit(ATMCI_CARD_PRESENT, &slot->flags);
- }
+ } else {
+ dev_dbg(&mmc->class_dev, "no detect pin available\n");
}
- if (!gpio_is_valid(slot->detect_pin)) {
+ if (!slot->detect_pin) {
if (slot_data->non_removable)
mmc->caps |= MMC_CAP_NONREMOVABLE;
else
mmc->caps |= MMC_CAP_NEEDS_POLL;
}
- if (gpio_is_valid(slot->wp_pin)) {
- if (devm_gpio_request(&host->pdev->dev, slot->wp_pin,
- "mmc_wp")) {
- dev_dbg(&mmc->class_dev, "no WP pin available\n");
- slot->wp_pin = -EBUSY;
- }
- }
+ if (!slot->wp_pin)
+ dev_dbg(&mmc->class_dev, "no WP pin available\n");
host->slot[id] = slot;
mmc_regulator_get_supply(mmc);
@@ -2309,18 +2341,18 @@ static int atmci_init_slot(struct atmel_mci *host,
return ret;
}
- if (gpio_is_valid(slot->detect_pin)) {
+ if (slot->detect_pin) {
timer_setup(&slot->detect_timer, atmci_detect_change, 0);
- ret = request_irq(gpio_to_irq(slot->detect_pin),
- atmci_detect_interrupt,
- IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING,
- "mmc-detect", slot);
+ ret = request_irq(gpiod_to_irq(slot->detect_pin),
+ atmci_detect_interrupt,
+ IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING,
+ "mmc-detect", slot);
if (ret) {
dev_dbg(&mmc->class_dev,
"could not request IRQ %d for detect pin\n",
- gpio_to_irq(slot->detect_pin));
- slot->detect_pin = -EBUSY;
+ gpiod_to_irq(slot->detect_pin));
+ slot->detect_pin = NULL;
}
}
@@ -2339,10 +2371,8 @@ static void atmci_cleanup_slot(struct atmel_mci_slot *slot,
mmc_remove_host(slot->mmc);
- if (gpio_is_valid(slot->detect_pin)) {
- int pin = slot->detect_pin;
-
- free_irq(gpio_to_irq(pin), slot);
+ if (slot->detect_pin) {
+ free_irq(gpiod_to_irq(slot->detect_pin), slot);
del_timer_sync(&slot->detect_timer);
}
@@ -2600,7 +2630,7 @@ err_dma_probe_defer:
return ret;
}
-static int atmci_remove(struct platform_device *pdev)
+static void atmci_remove(struct platform_device *pdev)
{
struct atmel_mci *host = platform_get_drvdata(pdev);
unsigned int i;
@@ -2630,8 +2660,6 @@ static int atmci_remove(struct platform_device *pdev)
pm_runtime_disable(&pdev->dev);
pm_runtime_put_noidle(&pdev->dev);
-
- return 0;
}
#ifdef CONFIG_PM
@@ -2664,7 +2692,7 @@ static const struct dev_pm_ops atmci_dev_pm_ops = {
static struct platform_driver atmci_driver = {
.probe = atmci_probe,
- .remove = atmci_remove,
+ .remove_new = atmci_remove,
.driver = {
.name = "atmel_mci",
.probe_type = PROBE_PREFER_ASYNCHRONOUS,
diff --git a/drivers/mmc/host/au1xmmc.c b/drivers/mmc/host/au1xmmc.c
index 82dd0ae40305..b5a5c6a2fe8b 100644
--- a/drivers/mmc/host/au1xmmc.c
+++ b/drivers/mmc/host/au1xmmc.c
@@ -1114,7 +1114,7 @@ out0:
return ret;
}
-static int au1xmmc_remove(struct platform_device *pdev)
+static void au1xmmc_remove(struct platform_device *pdev)
{
struct au1xmmc_host *host = platform_get_drvdata(pdev);
@@ -1153,7 +1153,6 @@ static int au1xmmc_remove(struct platform_device *pdev)
mmc_free_host(host->mmc);
}
- return 0;
}
#ifdef CONFIG_PM
@@ -1185,7 +1184,7 @@ static int au1xmmc_resume(struct platform_device *pdev)
static struct platform_driver au1xmmc_driver = {
.probe = au1xmmc_probe,
- .remove = au1xmmc_remove,
+ .remove_new = au1xmmc_remove,
.suspend = au1xmmc_suspend,
.resume = au1xmmc_resume,
.driver = {
diff --git a/drivers/mmc/host/bcm2835.c b/drivers/mmc/host/bcm2835.c
index eea208856ce0..35d8fdea668b 100644
--- a/drivers/mmc/host/bcm2835.c
+++ b/drivers/mmc/host/bcm2835.c
@@ -1431,7 +1431,7 @@ err:
return ret;
}
-static int bcm2835_remove(struct platform_device *pdev)
+static void bcm2835_remove(struct platform_device *pdev)
{
struct bcm2835_host *host = platform_get_drvdata(pdev);
struct mmc_host *mmc = mmc_from_priv(host);
@@ -1449,8 +1449,6 @@ static int bcm2835_remove(struct platform_device *pdev)
dma_release_channel(host->dma_chan_rxtx);
mmc_free_host(mmc);
-
- return 0;
}
static const struct of_device_id bcm2835_match[] = {
@@ -1461,7 +1459,7 @@ MODULE_DEVICE_TABLE(of, bcm2835_match);
static struct platform_driver bcm2835_driver = {
.probe = bcm2835_probe,
- .remove = bcm2835_remove,
+ .remove_new = bcm2835_remove,
.driver = {
.name = "sdhost-bcm2835",
.probe_type = PROBE_PREFER_ASYNCHRONOUS,
diff --git a/drivers/mmc/host/cavium-octeon.c b/drivers/mmc/host/cavium-octeon.c
index 12dca91a8ef6..060ec4f4800f 100644
--- a/drivers/mmc/host/cavium-octeon.c
+++ b/drivers/mmc/host/cavium-octeon.c
@@ -13,7 +13,9 @@
#include <linux/mmc/mmc.h>
#include <linux/mmc/slot-gpio.h>
#include <linux/module.h>
+#include <linux/of.h>
#include <linux/of_platform.h>
+#include <linux/platform_device.h>
#include <asm/octeon/octeon.h>
#include "cavium.h"
@@ -294,7 +296,7 @@ error:
return ret;
}
-static int octeon_mmc_remove(struct platform_device *pdev)
+static void octeon_mmc_remove(struct platform_device *pdev)
{
struct cvm_mmc_host *host = platform_get_drvdata(pdev);
u64 dma_cfg;
@@ -309,7 +311,6 @@ static int octeon_mmc_remove(struct platform_device *pdev)
writeq(dma_cfg, host->dma_base + MIO_EMM_DMA_CFG(host));
octeon_mmc_set_shared_power(host, 0);
- return 0;
}
static const struct of_device_id octeon_mmc_match[] = {
@@ -325,7 +326,7 @@ MODULE_DEVICE_TABLE(of, octeon_mmc_match);
static struct platform_driver octeon_mmc_driver = {
.probe = octeon_mmc_probe,
- .remove = octeon_mmc_remove,
+ .remove_new = octeon_mmc_remove,
.driver = {
.name = KBUILD_MODNAME,
.probe_type = PROBE_PREFER_ASYNCHRONOUS,
diff --git a/drivers/mmc/host/cavium-thunderx.c b/drivers/mmc/host/cavium-thunderx.c
index 202b1d6da678..2e2ff984f0b3 100644
--- a/drivers/mmc/host/cavium-thunderx.c
+++ b/drivers/mmc/host/cavium-thunderx.c
@@ -14,6 +14,7 @@
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_platform.h>
+#include <linux/platform_device.h>
#include <linux/pci.h>
#include "cavium.h"
diff --git a/drivers/mmc/host/cb710-mmc.c b/drivers/mmc/host/cb710-mmc.c
index 6d623b2681c3..0aec33b88bef 100644
--- a/drivers/mmc/host/cb710-mmc.c
+++ b/drivers/mmc/host/cb710-mmc.c
@@ -745,7 +745,7 @@ err_free_mmc:
return err;
}
-static int cb710_mmc_exit(struct platform_device *pdev)
+static void cb710_mmc_exit(struct platform_device *pdev)
{
struct cb710_slot *slot = cb710_pdev_to_slot(pdev);
struct mmc_host *mmc = cb710_slot_to_mmc(slot);
@@ -766,13 +766,12 @@ static int cb710_mmc_exit(struct platform_device *pdev)
tasklet_kill(&reader->finish_req_tasklet);
mmc_free_host(mmc);
- return 0;
}
static struct platform_driver cb710_mmc_driver = {
.driver.name = "cb710-mmc",
.probe = cb710_mmc_init,
- .remove = cb710_mmc_exit,
+ .remove_new = cb710_mmc_exit,
#ifdef CONFIG_PM
.suspend = cb710_mmc_suspend,
.resume = cb710_mmc_resume,
diff --git a/drivers/mmc/host/davinci_mmc.c b/drivers/mmc/host/davinci_mmc.c
index 7138dfa065bf..ee3b1a4e0848 100644
--- a/drivers/mmc/host/davinci_mmc.c
+++ b/drivers/mmc/host/davinci_mmc.c
@@ -21,7 +21,6 @@
#include <linux/dma-mapping.h>
#include <linux/mmc/mmc.h>
#include <linux/of.h>
-#include <linux/of_device.h>
#include <linux/mmc/slot-gpio.h>
#include <linux/interrupt.h>
@@ -1257,7 +1256,7 @@ static int davinci_mmcsd_probe(struct platform_device *pdev)
host->use_dma = use_dma;
host->mmc_irq = irq;
- host->sdio_irq = platform_get_irq(pdev, 1);
+ host->sdio_irq = platform_get_irq_optional(pdev, 1);
if (host->use_dma) {
ret = davinci_acquire_dma_channels(host);
@@ -1345,7 +1344,7 @@ ioremap_fail:
return ret;
}
-static int __exit davinci_mmcsd_remove(struct platform_device *pdev)
+static void __exit davinci_mmcsd_remove(struct platform_device *pdev)
{
struct mmc_davinci_host *host = platform_get_drvdata(pdev);
@@ -1354,8 +1353,6 @@ static int __exit davinci_mmcsd_remove(struct platform_device *pdev)
davinci_release_dma_channels(host);
clk_disable_unprepare(host->clk);
mmc_free_host(host->mmc);
-
- return 0;
}
#ifdef CONFIG_PM
@@ -1402,7 +1399,7 @@ static struct platform_driver davinci_mmcsd_driver = {
.of_match_table = davinci_mmc_dt_ids,
},
.probe = davinci_mmcsd_probe,
- .remove = __exit_p(davinci_mmcsd_remove),
+ .remove_new = __exit_p(davinci_mmcsd_remove),
.id_table = davinci_mmc_devtype,
};
diff --git a/drivers/mmc/host/dw_mmc-exynos.c b/drivers/mmc/host/dw_mmc-exynos.c
index 9f20ac524c8b..698408e8bad0 100644
--- a/drivers/mmc/host/dw_mmc-exynos.c
+++ b/drivers/mmc/host/dw_mmc-exynos.c
@@ -664,15 +664,13 @@ static int dw_mci_exynos_probe(struct platform_device *pdev)
return 0;
}
-static int dw_mci_exynos_remove(struct platform_device *pdev)
+static void dw_mci_exynos_remove(struct platform_device *pdev)
{
pm_runtime_disable(&pdev->dev);
pm_runtime_set_suspended(&pdev->dev);
pm_runtime_put_noidle(&pdev->dev);
dw_mci_pltfm_remove(pdev);
-
- return 0;
}
static const struct dev_pm_ops dw_mci_exynos_pmops = {
@@ -685,7 +683,7 @@ static const struct dev_pm_ops dw_mci_exynos_pmops = {
static struct platform_driver dw_mci_exynos_pltfm_driver = {
.probe = dw_mci_exynos_probe,
- .remove = dw_mci_exynos_remove,
+ .remove_new = dw_mci_exynos_remove,
.driver = {
.name = "dwmmc_exynos",
.probe_type = PROBE_PREFER_ASYNCHRONOUS,
diff --git a/drivers/mmc/host/dw_mmc-hi3798cv200.c b/drivers/mmc/host/dw_mmc-hi3798cv200.c
index 6f22fe054087..e9470c50a348 100644
--- a/drivers/mmc/host/dw_mmc-hi3798cv200.c
+++ b/drivers/mmc/host/dw_mmc-hi3798cv200.c
@@ -171,7 +171,7 @@ static int dw_mci_hi3798cv200_probe(struct platform_device *pdev)
return dw_mci_pltfm_register(pdev, &hi3798cv200_data);
}
-static int dw_mci_hi3798cv200_remove(struct platform_device *pdev)
+static void dw_mci_hi3798cv200_remove(struct platform_device *pdev)
{
struct dw_mci *host = platform_get_drvdata(pdev);
struct hi3798cv200_priv *priv = host->priv;
@@ -180,8 +180,6 @@ static int dw_mci_hi3798cv200_remove(struct platform_device *pdev)
clk_disable_unprepare(priv->sample_clk);
dw_mci_pltfm_remove(pdev);
-
- return 0;
}
static const struct of_device_id dw_mci_hi3798cv200_match[] = {
@@ -192,7 +190,7 @@ static const struct of_device_id dw_mci_hi3798cv200_match[] = {
MODULE_DEVICE_TABLE(of, dw_mci_hi3798cv200_match);
static struct platform_driver dw_mci_hi3798cv200_driver = {
.probe = dw_mci_hi3798cv200_probe,
- .remove = dw_mci_hi3798cv200_remove,
+ .remove_new = dw_mci_hi3798cv200_remove,
.driver = {
.name = "dwmmc_hi3798cv200",
.probe_type = PROBE_PREFER_ASYNCHRONOUS,
diff --git a/drivers/mmc/host/dw_mmc-rockchip.c b/drivers/mmc/host/dw_mmc-rockchip.c
index 2a99f15f527f..b07190ba4b7a 100644
--- a/drivers/mmc/host/dw_mmc-rockchip.c
+++ b/drivers/mmc/host/dw_mmc-rockchip.c
@@ -371,15 +371,13 @@ static int dw_mci_rockchip_probe(struct platform_device *pdev)
return 0;
}
-static int dw_mci_rockchip_remove(struct platform_device *pdev)
+static void dw_mci_rockchip_remove(struct platform_device *pdev)
{
pm_runtime_get_sync(&pdev->dev);
pm_runtime_disable(&pdev->dev);
pm_runtime_put_noidle(&pdev->dev);
dw_mci_pltfm_remove(pdev);
-
- return 0;
}
static const struct dev_pm_ops dw_mci_rockchip_dev_pm_ops = {
@@ -392,7 +390,7 @@ static const struct dev_pm_ops dw_mci_rockchip_dev_pm_ops = {
static struct platform_driver dw_mci_rockchip_pltfm_driver = {
.probe = dw_mci_rockchip_probe,
- .remove = dw_mci_rockchip_remove,
+ .remove_new = dw_mci_rockchip_remove,
.driver = {
.name = "dwmmc_rockchip",
.probe_type = PROBE_PREFER_ASYNCHRONOUS,
diff --git a/drivers/mmc/host/jz4740_mmc.c b/drivers/mmc/host/jz4740_mmc.c
index 1846a05210e3..f379ce5b582d 100644
--- a/drivers/mmc/host/jz4740_mmc.c
+++ b/drivers/mmc/host/jz4740_mmc.c
@@ -1163,7 +1163,7 @@ err_free_host:
return ret;
}
-static int jz4740_mmc_remove(struct platform_device *pdev)
+static void jz4740_mmc_remove(struct platform_device *pdev)
{
struct jz4740_mmc_host *host = platform_get_drvdata(pdev);
@@ -1179,8 +1179,6 @@ static int jz4740_mmc_remove(struct platform_device *pdev)
jz4740_mmc_release_dma_channels(host);
mmc_free_host(host->mmc);
-
- return 0;
}
static int jz4740_mmc_suspend(struct device *dev)
@@ -1198,7 +1196,7 @@ static DEFINE_SIMPLE_DEV_PM_OPS(jz4740_mmc_pm_ops, jz4740_mmc_suspend,
static struct platform_driver jz4740_mmc_driver = {
.probe = jz4740_mmc_probe,
- .remove = jz4740_mmc_remove,
+ .remove_new = jz4740_mmc_remove,
.driver = {
.name = "jz4740-mmc",
.probe_type = PROBE_PREFER_ASYNCHRONOUS,
diff --git a/drivers/mmc/host/litex_mmc.c b/drivers/mmc/host/litex_mmc.c
index 9af6b0902efe..4ec8072dc60b 100644
--- a/drivers/mmc/host/litex_mmc.c
+++ b/drivers/mmc/host/litex_mmc.c
@@ -629,12 +629,11 @@ static int litex_mmc_probe(struct platform_device *pdev)
return 0;
}
-static int litex_mmc_remove(struct platform_device *pdev)
+static void litex_mmc_remove(struct platform_device *pdev)
{
struct litex_mmc_host *host = platform_get_drvdata(pdev);
mmc_remove_host(host->mmc);
- return 0;
}
static const struct of_device_id litex_match[] = {
@@ -645,7 +644,7 @@ MODULE_DEVICE_TABLE(of, litex_match);
static struct platform_driver litex_mmc_driver = {
.probe = litex_mmc_probe,
- .remove = litex_mmc_remove,
+ .remove_new = litex_mmc_remove,
.driver = {
.name = "litex-mmc",
.of_match_table = litex_match,
diff --git a/drivers/mmc/host/meson-gx-mmc.c b/drivers/mmc/host/meson-gx-mmc.c
index ee9a25b900ae..9837dab096e6 100644
--- a/drivers/mmc/host/meson-gx-mmc.c
+++ b/drivers/mmc/host/meson-gx-mmc.c
@@ -11,7 +11,7 @@
#include <linux/delay.h>
#include <linux/device.h>
#include <linux/iopoll.h>
-#include <linux/of_device.h>
+#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/ioport.h>
#include <linux/dma-mapping.h>
@@ -948,9 +948,6 @@ static irqreturn_t meson_mmc_irq(int irq, void *dev_id)
return IRQ_NONE;
}
- if (WARN_ON(!host))
- return IRQ_NONE;
-
/* ack all raised interrupts */
writel(status, host->regs + SD_EMMC_STATUS);
@@ -1297,7 +1294,7 @@ err_init_clk:
return ret;
}
-static int meson_mmc_remove(struct platform_device *pdev)
+static void meson_mmc_remove(struct platform_device *pdev)
{
struct meson_host *host = dev_get_drvdata(&pdev->dev);
@@ -1308,8 +1305,6 @@ static int meson_mmc_remove(struct platform_device *pdev)
free_irq(host->irq, host);
clk_disable_unprepare(host->mmc_clk);
-
- return 0;
}
static const struct meson_mmc_data meson_gx_data = {
@@ -1340,7 +1335,7 @@ MODULE_DEVICE_TABLE(of, meson_mmc_of_match);
static struct platform_driver meson_mmc_driver = {
.probe = meson_mmc_probe,
- .remove = meson_mmc_remove,
+ .remove_new = meson_mmc_remove,
.driver = {
.name = DRIVER_NAME,
.probe_type = PROBE_PREFER_ASYNCHRONOUS,
diff --git a/drivers/mmc/host/meson-mx-sdhc-mmc.c b/drivers/mmc/host/meson-mx-sdhc-mmc.c
index 97168cdfa8e9..528ec8166e7c 100644
--- a/drivers/mmc/host/meson-mx-sdhc-mmc.c
+++ b/drivers/mmc/host/meson-mx-sdhc-mmc.c
@@ -880,7 +880,7 @@ err_disable_pclk:
return ret;
}
-static int meson_mx_sdhc_remove(struct platform_device *pdev)
+static void meson_mx_sdhc_remove(struct platform_device *pdev)
{
struct meson_mx_sdhc_host *host = platform_get_drvdata(pdev);
@@ -889,8 +889,6 @@ static int meson_mx_sdhc_remove(struct platform_device *pdev)
meson_mx_sdhc_disable_clks(host->mmc);
clk_disable_unprepare(host->pclk);
-
- return 0;
}
static const struct meson_mx_sdhc_data meson_mx_sdhc_data_meson8 = {
@@ -925,7 +923,7 @@ MODULE_DEVICE_TABLE(of, meson_mx_sdhc_of_match);
static struct platform_driver meson_mx_sdhc_driver = {
.probe = meson_mx_sdhc_probe,
- .remove = meson_mx_sdhc_remove,
+ .remove_new = meson_mx_sdhc_remove,
.driver = {
.name = "meson-mx-sdhc",
.probe_type = PROBE_PREFER_ASYNCHRONOUS,
diff --git a/drivers/mmc/host/meson-mx-sdio.c b/drivers/mmc/host/meson-mx-sdio.c
index 3a19a05ef55a..a11577f2ee69 100644
--- a/drivers/mmc/host/meson-mx-sdio.c
+++ b/drivers/mmc/host/meson-mx-sdio.c
@@ -728,7 +728,7 @@ error_unregister_slot_pdev:
return ret;
}
-static int meson_mx_mmc_remove(struct platform_device *pdev)
+static void meson_mx_mmc_remove(struct platform_device *pdev)
{
struct meson_mx_mmc_host *host = platform_get_drvdata(pdev);
struct device *slot_dev = mmc_dev(host->mmc);
@@ -743,8 +743,6 @@ static int meson_mx_mmc_remove(struct platform_device *pdev)
clk_disable_unprepare(host->core_clk);
mmc_free_host(host->mmc);
-
- return 0;
}
static const struct of_device_id meson_mx_mmc_of_match[] = {
@@ -756,7 +754,7 @@ MODULE_DEVICE_TABLE(of, meson_mx_mmc_of_match);
static struct platform_driver meson_mx_mmc_driver = {
.probe = meson_mx_mmc_probe,
- .remove = meson_mx_mmc_remove,
+ .remove_new = meson_mx_mmc_remove,
.driver = {
.name = "meson-mx-sdio",
.probe_type = PROBE_PREFER_ASYNCHRONOUS,
diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c
index 769b34afa835..dda756a56379 100644
--- a/drivers/mmc/host/mmci.c
+++ b/drivers/mmc/host/mmci.c
@@ -764,7 +764,8 @@ static bool ux500_busy_complete(struct mmci_host *host, struct mmc_command *cmd,
}
retries--;
}
- dev_dbg(mmc_dev(host->mmc), "no busy signalling in time\n");
+ dev_dbg(mmc_dev(host->mmc),
+ "no busy signalling in time CMD%02x\n", cmd->opcode);
ux500_busy_clear_mask_done(host);
break;
@@ -786,7 +787,8 @@ static bool ux500_busy_complete(struct mmci_host *host, struct mmc_command *cmd,
host->busy_state = MMCI_BUSY_WAITING_FOR_END_IRQ;
} else {
dev_dbg(mmc_dev(host->mmc),
- "lost busy status when waiting for busy start IRQ\n");
+ "lost busy status when waiting for busy start IRQ CMD%02x\n",
+ cmd->opcode);
cancel_delayed_work(&host->ux500_busy_timeout_work);
ux500_busy_clear_mask_done(host);
}
@@ -800,13 +802,14 @@ static bool ux500_busy_complete(struct mmci_host *host, struct mmc_command *cmd,
ux500_busy_clear_mask_done(host);
} else {
dev_dbg(mmc_dev(host->mmc),
- "busy status still asserted when handling busy end IRQ - will keep waiting\n");
+ "busy status still asserted when handling busy end IRQ - will keep waiting CMD%02x\n",
+ cmd->opcode);
}
break;
default:
- dev_dbg(mmc_dev(host->mmc), "fell through on state %d\n",
- host->busy_state);
+ dev_dbg(mmc_dev(host->mmc), "fell through on state %d, CMD%02x\n",
+ host->busy_state, cmd->opcode);
break;
}
@@ -1533,6 +1536,20 @@ mmci_cmd_irq(struct mmci_host *host, struct mmc_command *cmd,
}
}
+static char *ux500_state_str(struct mmci_host *host)
+{
+ switch (host->busy_state) {
+ case MMCI_BUSY_WAITING_FOR_START_IRQ:
+ return "waiting for start IRQ";
+ case MMCI_BUSY_WAITING_FOR_END_IRQ:
+ return "waiting for end IRQ";
+ case MMCI_BUSY_DONE:
+ return "not waiting for IRQs";
+ default:
+ return "unknown";
+ }
+}
+
/*
* This busy timeout worker is used to "kick" the command IRQ if a
* busy detect IRQ fails to appear in reasonable time. Only used on
@@ -1548,12 +1565,18 @@ static void ux500_busy_timeout_work(struct work_struct *work)
spin_lock_irqsave(&host->lock, flags);
if (host->cmd) {
- dev_dbg(mmc_dev(host->mmc), "timeout waiting for busy IRQ\n");
-
/* If we are still busy let's tag on a cmd-timeout error. */
status = readl(host->base + MMCISTATUS);
- if (status & host->variant->busy_detect_flag)
+ if (status & host->variant->busy_detect_flag) {
status |= MCI_CMDTIMEOUT;
+ dev_err(mmc_dev(host->mmc),
+ "timeout in state %s still busy with CMD%02x\n",
+ ux500_state_str(host), host->cmd->opcode);
+ } else {
+ dev_err(mmc_dev(host->mmc),
+ "timeout in state %s waiting for busy CMD%02x\n",
+ ux500_state_str(host), host->cmd->opcode);
+ }
mmci_cmd_irq(host, host->cmd, status);
}
diff --git a/drivers/mmc/host/moxart-mmc.c b/drivers/mmc/host/moxart-mmc.c
index 2d002c81dcf3..5cfdd3a86e54 100644
--- a/drivers/mmc/host/moxart-mmc.c
+++ b/drivers/mmc/host/moxart-mmc.c
@@ -338,13 +338,7 @@ static void moxart_transfer_pio(struct moxart_host *host)
return;
}
for (len = 0; len < remain && len < host->fifo_width;) {
- /* SCR data must be read in big endian. */
- if (data->mrq->cmd->opcode == SD_APP_SEND_SCR)
- *sgp = ioread32be(host->base +
- REG_DATA_WINDOW);
- else
- *sgp = ioread32(host->base +
- REG_DATA_WINDOW);
+ *sgp = ioread32(host->base + REG_DATA_WINDOW);
sgp++;
len += 4;
}
@@ -693,13 +687,11 @@ out_mmc:
return ret;
}
-static int moxart_remove(struct platform_device *pdev)
+static void moxart_remove(struct platform_device *pdev)
{
struct mmc_host *mmc = dev_get_drvdata(&pdev->dev);
struct moxart_host *host = mmc_priv(mmc);
- dev_set_drvdata(&pdev->dev, NULL);
-
if (!IS_ERR_OR_NULL(host->dma_chan_tx))
dma_release_channel(host->dma_chan_tx);
if (!IS_ERR_OR_NULL(host->dma_chan_rx))
@@ -711,8 +703,6 @@ static int moxart_remove(struct platform_device *pdev)
writel(readl(host->base + REG_CLOCK_CONTROL) | CLK_OFF,
host->base + REG_CLOCK_CONTROL);
mmc_free_host(mmc);
-
- return 0;
}
static const struct of_device_id moxart_mmc_match[] = {
@@ -724,7 +714,7 @@ MODULE_DEVICE_TABLE(of, moxart_mmc_match);
static struct platform_driver moxart_mmc_driver = {
.probe = moxart_probe,
- .remove = moxart_remove,
+ .remove_new = moxart_remove,
.driver = {
.name = "mmc-moxart",
.probe_type = PROBE_PREFER_ASYNCHRONOUS,
diff --git a/drivers/mmc/host/mtk-sd.c b/drivers/mmc/host/mtk-sd.c
index 02403ff99e0d..5392200cfdf7 100644
--- a/drivers/mmc/host/mtk-sd.c
+++ b/drivers/mmc/host/mtk-sd.c
@@ -12,9 +12,7 @@
#include <linux/iopoll.h>
#include <linux/ioport.h>
#include <linux/irq.h>
-#include <linux/of_address.h>
-#include <linux/of_device.h>
-#include <linux/of_irq.h>
+#include <linux/of.h>
#include <linux/of_gpio.h>
#include <linux/pinctrl/consumer.h>
#include <linux/platform_device.h>
@@ -2887,7 +2885,7 @@ host_free:
return ret;
}
-static int msdc_drv_remove(struct platform_device *pdev)
+static void msdc_drv_remove(struct platform_device *pdev)
{
struct mmc_host *mmc;
struct msdc_host *host;
@@ -2911,8 +2909,6 @@ static int msdc_drv_remove(struct platform_device *pdev)
host->dma.bd, host->dma.bd_addr);
mmc_free_host(mmc);
-
- return 0;
}
static void msdc_save_reg(struct msdc_host *host)
@@ -3054,7 +3050,7 @@ static const struct dev_pm_ops msdc_dev_pm_ops = {
static struct platform_driver mt_msdc_driver = {
.probe = msdc_drv_probe,
- .remove = msdc_drv_remove,
+ .remove_new = msdc_drv_remove,
.driver = {
.name = "mtk-msdc",
.probe_type = PROBE_PREFER_ASYNCHRONOUS,
diff --git a/drivers/mmc/host/mvsdio.c b/drivers/mmc/host/mvsdio.c
index b4f6a0a2fcb5..ca01b7d204ba 100644
--- a/drivers/mmc/host/mvsdio.c
+++ b/drivers/mmc/host/mvsdio.c
@@ -796,7 +796,7 @@ out:
return ret;
}
-static int mvsd_remove(struct platform_device *pdev)
+static void mvsd_remove(struct platform_device *pdev)
{
struct mmc_host *mmc = platform_get_drvdata(pdev);
@@ -809,8 +809,6 @@ static int mvsd_remove(struct platform_device *pdev)
if (!IS_ERR(host->clk))
clk_disable_unprepare(host->clk);
mmc_free_host(mmc);
-
- return 0;
}
static const struct of_device_id mvsdio_dt_ids[] = {
@@ -821,7 +819,7 @@ MODULE_DEVICE_TABLE(of, mvsdio_dt_ids);
static struct platform_driver mvsd_driver = {
.probe = mvsd_probe,
- .remove = mvsd_remove,
+ .remove_new = mvsd_remove,
.driver = {
.name = DRIVER_NAME,
.probe_type = PROBE_PREFER_ASYNCHRONOUS,
diff --git a/drivers/mmc/host/mxcmmc.c b/drivers/mmc/host/mxcmmc.c
index 668f865f3efb..5b3ab0e20505 100644
--- a/drivers/mmc/host/mxcmmc.c
+++ b/drivers/mmc/host/mxcmmc.c
@@ -31,7 +31,6 @@
#include <linux/dmaengine.h>
#include <linux/types.h>
#include <linux/of.h>
-#include <linux/of_device.h>
#include <linux/of_dma.h>
#include <linux/mmc/slot-gpio.h>
@@ -989,7 +988,6 @@ static int mxcmci_probe(struct platform_device *pdev)
pr_info("i.MX/MPC512x SDHC driver\n");
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
irq = platform_get_irq(pdev, 0);
if (irq < 0)
return irq;
@@ -1000,7 +998,7 @@ static int mxcmci_probe(struct platform_device *pdev)
host = mmc_priv(mmc);
- host->base = devm_ioremap_resource(&pdev->dev, res);
+ host->base = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
if (IS_ERR(host->base)) {
ret = PTR_ERR(host->base);
goto out_free;
@@ -1164,7 +1162,7 @@ out_free:
return ret;
}
-static int mxcmci_remove(struct platform_device *pdev)
+static void mxcmci_remove(struct platform_device *pdev)
{
struct mmc_host *mmc = platform_get_drvdata(pdev);
struct mxcmci_host *host = mmc_priv(mmc);
@@ -1181,8 +1179,6 @@ static int mxcmci_remove(struct platform_device *pdev)
clk_disable_unprepare(host->clk_ipg);
mmc_free_host(mmc);
-
- return 0;
}
static int mxcmci_suspend(struct device *dev)
@@ -1216,7 +1212,7 @@ static DEFINE_SIMPLE_DEV_PM_OPS(mxcmci_pm_ops, mxcmci_suspend, mxcmci_resume);
static struct platform_driver mxcmci_driver = {
.probe = mxcmci_probe,
- .remove = mxcmci_remove,
+ .remove_new = mxcmci_remove,
.driver = {
.name = DRIVER_NAME,
.probe_type = PROBE_PREFER_ASYNCHRONOUS,
diff --git a/drivers/mmc/host/mxs-mmc.c b/drivers/mmc/host/mxs-mmc.c
index 8c3655d3be96..6751da9b60f9 100644
--- a/drivers/mmc/host/mxs-mmc.c
+++ b/drivers/mmc/host/mxs-mmc.c
@@ -11,7 +11,6 @@
#include <linux/init.h>
#include <linux/ioport.h>
#include <linux/of.h>
-#include <linux/of_device.h>
#include <linux/platform_device.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
@@ -674,7 +673,7 @@ out_mmc_free:
return ret;
}
-static int mxs_mmc_remove(struct platform_device *pdev)
+static void mxs_mmc_remove(struct platform_device *pdev)
{
struct mmc_host *mmc = platform_get_drvdata(pdev);
struct mxs_mmc_host *host = mmc_priv(mmc);
@@ -688,8 +687,6 @@ static int mxs_mmc_remove(struct platform_device *pdev)
clk_disable_unprepare(ssp->clk);
mmc_free_host(mmc);
-
- return 0;
}
#ifdef CONFIG_PM_SLEEP
@@ -717,7 +714,7 @@ static SIMPLE_DEV_PM_OPS(mxs_mmc_pm_ops, mxs_mmc_suspend, mxs_mmc_resume);
static struct platform_driver mxs_mmc_driver = {
.probe = mxs_mmc_probe,
- .remove = mxs_mmc_remove,
+ .remove_new = mxs_mmc_remove,
.driver = {
.name = DRIVER_NAME,
.probe_type = PROBE_PREFER_ASYNCHRONOUS,
diff --git a/drivers/mmc/host/omap.c b/drivers/mmc/host/omap.c
index 6a259563690d..9fb8995b43a1 100644
--- a/drivers/mmc/host/omap.c
+++ b/drivers/mmc/host/omap.c
@@ -1506,7 +1506,7 @@ err_free_iclk:
return ret;
}
-static int mmc_omap_remove(struct platform_device *pdev)
+static void mmc_omap_remove(struct platform_device *pdev)
{
struct mmc_omap_host *host = platform_get_drvdata(pdev);
int i;
@@ -1532,8 +1532,6 @@ static int mmc_omap_remove(struct platform_device *pdev)
dma_release_channel(host->dma_rx);
destroy_workqueue(host->mmc_omap_wq);
-
- return 0;
}
#if IS_BUILTIN(CONFIG_OF)
@@ -1546,7 +1544,7 @@ MODULE_DEVICE_TABLE(of, mmc_omap_match);
static struct platform_driver mmc_omap_driver = {
.probe = mmc_omap_probe,
- .remove = mmc_omap_remove,
+ .remove_new = mmc_omap_remove,
.driver = {
.name = DRIVER_NAME,
.probe_type = PROBE_PREFER_ASYNCHRONOUS,
diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index 1e0f2d7774bd..e120aeb869b8 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -1790,14 +1790,11 @@ static int omap_hsmmc_probe(struct platform_device *pdev)
return -ENXIO;
}
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!res)
- return -ENXIO;
irq = platform_get_irq(pdev, 0);
if (irq < 0)
return irq;
- base = devm_ioremap_resource(&pdev->dev, res);
+ base = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
if (IS_ERR(base))
return PTR_ERR(base);
@@ -1982,7 +1979,7 @@ err:
return ret;
}
-static int omap_hsmmc_remove(struct platform_device *pdev)
+static void omap_hsmmc_remove(struct platform_device *pdev)
{
struct omap_hsmmc_host *host = platform_get_drvdata(pdev);
@@ -2000,8 +1997,6 @@ static int omap_hsmmc_remove(struct platform_device *pdev)
clk_disable_unprepare(host->dbclk);
mmc_free_host(host->mmc);
-
- return 0;
}
#ifdef CONFIG_PM_SLEEP
@@ -2126,7 +2121,7 @@ static const struct dev_pm_ops omap_hsmmc_dev_pm_ops = {
static struct platform_driver omap_hsmmc_driver = {
.probe = omap_hsmmc_probe,
- .remove = omap_hsmmc_remove,
+ .remove_new = omap_hsmmc_remove,
.driver = {
.name = DRIVER_NAME,
.probe_type = PROBE_PREFER_ASYNCHRONOUS,
diff --git a/drivers/mmc/host/owl-mmc.c b/drivers/mmc/host/owl-mmc.c
index 1bf22b08b373..fc08f25c34eb 100644
--- a/drivers/mmc/host/owl-mmc.c
+++ b/drivers/mmc/host/owl-mmc.c
@@ -16,8 +16,9 @@
#include <linux/interrupt.h>
#include <linux/mmc/host.h>
#include <linux/mmc/slot-gpio.h>
+#include <linux/mod_devicetable.h>
#include <linux/module.h>
-#include <linux/of_platform.h>
+#include <linux/platform_device.h>
#include <linux/reset.h>
#include <linux/spinlock.h>
@@ -667,7 +668,7 @@ err_free_host:
return ret;
}
-static int owl_mmc_remove(struct platform_device *pdev)
+static void owl_mmc_remove(struct platform_device *pdev)
{
struct mmc_host *mmc = platform_get_drvdata(pdev);
struct owl_mmc_host *owl_host = mmc_priv(mmc);
@@ -676,8 +677,6 @@ static int owl_mmc_remove(struct platform_device *pdev)
disable_irq(owl_host->irq);
dma_release_channel(owl_host->dma);
mmc_free_host(mmc);
-
- return 0;
}
static const struct of_device_id owl_mmc_of_match[] = {
@@ -693,7 +692,7 @@ static struct platform_driver owl_mmc_driver = {
.of_match_table = owl_mmc_of_match,
},
.probe = owl_mmc_probe,
- .remove = owl_mmc_remove,
+ .remove_new = owl_mmc_remove,
};
module_platform_driver(owl_mmc_driver);
diff --git a/drivers/mmc/host/pxamci.c b/drivers/mmc/host/pxamci.c
index 2a988f942b6c..fae3192c3a14 100644
--- a/drivers/mmc/host/pxamci.c
+++ b/drivers/mmc/host/pxamci.c
@@ -30,7 +30,6 @@
#include <linux/gpio/consumer.h>
#include <linux/gfp.h>
#include <linux/of.h>
-#include <linux/of_device.h>
#include <linux/soc/pxa/cpu.h>
#include <linux/sizes.h>
@@ -612,7 +611,6 @@ static int pxamci_probe(struct platform_device *pdev)
struct resource *r;
int ret, irq;
- r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
irq = platform_get_irq(pdev, 0);
if (irq < 0)
return irq;
@@ -685,14 +683,14 @@ static int pxamci_probe(struct platform_device *pdev)
}
spin_lock_init(&host->lock);
- host->res = r;
host->imask = MMC_I_MASK_ALL;
- host->base = devm_ioremap_resource(dev, r);
+ host->base = devm_platform_get_and_ioremap_resource(pdev, 0, &r);
if (IS_ERR(host->base)) {
ret = PTR_ERR(host->base);
goto out;
}
+ host->res = r;
/*
* Ensure that the host controller is shut down, and setup
@@ -784,7 +782,7 @@ out:
return ret;
}
-static int pxamci_remove(struct platform_device *pdev)
+static void pxamci_remove(struct platform_device *pdev)
{
struct mmc_host *mmc = platform_get_drvdata(pdev);
@@ -808,13 +806,11 @@ static int pxamci_remove(struct platform_device *pdev)
mmc_free_host(mmc);
}
-
- return 0;
}
static struct platform_driver pxamci_driver = {
.probe = pxamci_probe,
- .remove = pxamci_remove,
+ .remove_new = pxamci_remove,
.driver = {
.name = DRIVER_NAME,
.probe_type = PROBE_PREFER_ASYNCHRONOUS,
diff --git a/drivers/mmc/host/renesas_sdhi.h b/drivers/mmc/host/renesas_sdhi.h
index 68da3da9e2e5..c1fb9740eab0 100644
--- a/drivers/mmc/host/renesas_sdhi.h
+++ b/drivers/mmc/host/renesas_sdhi.h
@@ -101,5 +101,5 @@ int renesas_sdhi_probe(struct platform_device *pdev,
const struct tmio_mmc_dma_ops *dma_ops,
const struct renesas_sdhi_of_data *of_data,
const struct renesas_sdhi_quirks *quirks);
-int renesas_sdhi_remove(struct platform_device *pdev);
+void renesas_sdhi_remove(struct platform_device *pdev);
#endif
diff --git a/drivers/mmc/host/renesas_sdhi_core.c b/drivers/mmc/host/renesas_sdhi_core.c
index 345934e4f59e..c675dec587ef 100644
--- a/drivers/mmc/host/renesas_sdhi_core.c
+++ b/drivers/mmc/host/renesas_sdhi_core.c
@@ -983,12 +983,12 @@ int renesas_sdhi_probe(struct platform_device *pdev,
}
- host->write16_hook = renesas_sdhi_write16_hook;
- host->clk_enable = renesas_sdhi_clk_enable;
- host->clk_disable = renesas_sdhi_clk_disable;
- host->set_clock = renesas_sdhi_set_clock;
- host->multi_io_quirk = renesas_sdhi_multi_io_quirk;
- host->dma_ops = dma_ops;
+ host->write16_hook = renesas_sdhi_write16_hook;
+ host->clk_enable = renesas_sdhi_clk_enable;
+ host->clk_disable = renesas_sdhi_clk_disable;
+ host->set_clock = renesas_sdhi_set_clock;
+ host->multi_io_quirk = renesas_sdhi_multi_io_quirk;
+ host->dma_ops = dma_ops;
if (sdhi_has_quirk(priv, hs400_disabled))
host->mmc->caps2 &= ~(MMC_CAP2_HS400 | MMC_CAP2_HS400_ES);
@@ -1006,6 +1006,8 @@ int renesas_sdhi_probe(struct platform_device *pdev,
host->sdcard_irq_setbit_mask = TMIO_STAT_ALWAYS_SET_27;
host->sdcard_irq_mask_all = TMIO_MASK_ALL_RCAR2;
host->reset = renesas_sdhi_reset;
+ } else {
+ host->sdcard_irq_mask_all = TMIO_MASK_ALL;
}
/* Orginally registers were 16 bit apart, could be 32 or 64 nowadays */
@@ -1100,9 +1102,7 @@ int renesas_sdhi_probe(struct platform_device *pdev,
host->ops.hs400_complete = renesas_sdhi_hs400_complete;
}
- ret = tmio_mmc_host_probe(host);
- if (ret < 0)
- goto edisclk;
+ sd_ctrl_write32_as_16_and_16(host, CTL_IRQ_MASK, host->sdcard_irq_mask_all);
num_irqs = platform_irq_count(pdev);
if (num_irqs < 0) {
@@ -1129,6 +1129,10 @@ int renesas_sdhi_probe(struct platform_device *pdev,
goto eirq;
}
+ ret = tmio_mmc_host_probe(host);
+ if (ret < 0)
+ goto edisclk;
+
dev_info(&pdev->dev, "%s base at %pa, max clock rate %u MHz\n",
mmc_hostname(host->mmc), &res->start, host->mmc->f_max / 1000000);
@@ -1145,15 +1149,13 @@ efree:
}
EXPORT_SYMBOL_GPL(renesas_sdhi_probe);
-int renesas_sdhi_remove(struct platform_device *pdev)
+void renesas_sdhi_remove(struct platform_device *pdev)
{
struct tmio_mmc_host *host = platform_get_drvdata(pdev);
tmio_mmc_host_remove(host);
renesas_sdhi_clk_disable(host);
tmio_mmc_host_free(host);
-
- return 0;
}
EXPORT_SYMBOL_GPL(renesas_sdhi_remove);
diff --git a/drivers/mmc/host/renesas_sdhi_internal_dmac.c b/drivers/mmc/host/renesas_sdhi_internal_dmac.c
index 9ab813903b2c..53d34c3eddce 100644
--- a/drivers/mmc/host/renesas_sdhi_internal_dmac.c
+++ b/drivers/mmc/host/renesas_sdhi_internal_dmac.c
@@ -15,7 +15,8 @@
#include <linux/mmc/host.h>
#include <linux/mod_devicetable.h>
#include <linux/module.h>
-#include <linux/of_device.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
#include <linux/pagemap.h>
#include <linux/scatterlist.h>
#include <linux/sys_soc.h>
@@ -609,7 +610,7 @@ static struct platform_driver renesas_internal_dmac_sdhi_driver = {
.of_match_table = renesas_sdhi_internal_dmac_of_match,
},
.probe = renesas_sdhi_internal_dmac_probe,
- .remove = renesas_sdhi_remove,
+ .remove_new = renesas_sdhi_remove,
};
module_platform_driver(renesas_internal_dmac_sdhi_driver);
diff --git a/drivers/mmc/host/renesas_sdhi_sys_dmac.c b/drivers/mmc/host/renesas_sdhi_sys_dmac.c
index b559ad38b667..9cf7f9feab72 100644
--- a/drivers/mmc/host/renesas_sdhi_sys_dmac.c
+++ b/drivers/mmc/host/renesas_sdhi_sys_dmac.c
@@ -15,7 +15,8 @@
#include <linux/mmc/host.h>
#include <linux/mod_devicetable.h>
#include <linux/module.h>
-#include <linux/of_device.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
#include <linux/pagemap.h>
#include <linux/scatterlist.h>
#include <linux/sys_soc.h>
@@ -470,7 +471,7 @@ static struct platform_driver renesas_sys_dmac_sdhi_driver = {
.of_match_table = renesas_sdhi_sys_dmac_of_match,
},
.probe = renesas_sdhi_sys_dmac_probe,
- .remove = renesas_sdhi_remove,
+ .remove_new = renesas_sdhi_remove,
};
module_platform_driver(renesas_sys_dmac_sdhi_driver);
diff --git a/drivers/mmc/host/rtsx_pci_sdmmc.c b/drivers/mmc/host/rtsx_pci_sdmmc.c
index 8098726dcc0b..87d78432a1e0 100644
--- a/drivers/mmc/host/rtsx_pci_sdmmc.c
+++ b/drivers/mmc/host/rtsx_pci_sdmmc.c
@@ -1523,15 +1523,12 @@ static int rtsx_pci_sdmmc_drv_probe(struct platform_device *pdev)
return 0;
}
-static int rtsx_pci_sdmmc_drv_remove(struct platform_device *pdev)
+static void rtsx_pci_sdmmc_drv_remove(struct platform_device *pdev)
{
struct realtek_pci_sdmmc *host = platform_get_drvdata(pdev);
struct rtsx_pcr *pcr;
struct mmc_host *mmc;
- if (!host)
- return 0;
-
pcr = host->pcr;
pcr->slots[RTSX_SD_CARD].p_dev = NULL;
pcr->slots[RTSX_SD_CARD].card_event = NULL;
@@ -1566,8 +1563,6 @@ static int rtsx_pci_sdmmc_drv_remove(struct platform_device *pdev)
dev_dbg(&(pdev->dev),
": Realtek PCI-E SDMMC controller has been removed\n");
-
- return 0;
}
static const struct platform_device_id rtsx_pci_sdmmc_ids[] = {
@@ -1581,7 +1576,7 @@ MODULE_DEVICE_TABLE(platform, rtsx_pci_sdmmc_ids);
static struct platform_driver rtsx_pci_sdmmc_driver = {
.probe = rtsx_pci_sdmmc_drv_probe,
- .remove = rtsx_pci_sdmmc_drv_remove,
+ .remove_new = rtsx_pci_sdmmc_drv_remove,
.id_table = rtsx_pci_sdmmc_ids,
.driver = {
.name = DRV_NAME_RTSX_PCI_SDMMC,
diff --git a/drivers/mmc/host/rtsx_usb_sdmmc.c b/drivers/mmc/host/rtsx_usb_sdmmc.c
index 2c650cd58693..ded9b6849e35 100644
--- a/drivers/mmc/host/rtsx_usb_sdmmc.c
+++ b/drivers/mmc/host/rtsx_usb_sdmmc.c
@@ -1379,13 +1379,13 @@ static int rtsx_usb_sdmmc_drv_probe(struct platform_device *pdev)
return 0;
}
-static int rtsx_usb_sdmmc_drv_remove(struct platform_device *pdev)
+static void rtsx_usb_sdmmc_drv_remove(struct platform_device *pdev)
{
struct rtsx_usb_sdmmc *host = platform_get_drvdata(pdev);
struct mmc_host *mmc;
if (!host)
- return 0;
+ return;
mmc = host->mmc;
host->host_removal = true;
@@ -1415,8 +1415,6 @@ static int rtsx_usb_sdmmc_drv_remove(struct platform_device *pdev)
dev_dbg(&(pdev->dev),
": Realtek USB SD/MMC module has been removed\n");
-
- return 0;
}
#ifdef CONFIG_PM
@@ -1455,7 +1453,7 @@ MODULE_DEVICE_TABLE(platform, rtsx_usb_sdmmc_ids);
static struct platform_driver rtsx_usb_sdmmc_driver = {
.probe = rtsx_usb_sdmmc_drv_probe,
- .remove = rtsx_usb_sdmmc_drv_remove,
+ .remove_new = rtsx_usb_sdmmc_drv_remove,
.id_table = rtsx_usb_sdmmc_ids,
.driver = {
.name = "rtsx_usb_sdmmc",
diff --git a/drivers/mmc/host/sdhci-acpi.c b/drivers/mmc/host/sdhci-acpi.c
index edf2e6c14dc6..acf5fc3ad7e4 100644
--- a/drivers/mmc/host/sdhci-acpi.c
+++ b/drivers/mmc/host/sdhci-acpi.c
@@ -917,7 +917,7 @@ err_free:
return err;
}
-static int sdhci_acpi_remove(struct platform_device *pdev)
+static void sdhci_acpi_remove(struct platform_device *pdev)
{
struct sdhci_acpi_host *c = platform_get_drvdata(pdev);
struct device *dev = &pdev->dev;
@@ -939,8 +939,6 @@ static int sdhci_acpi_remove(struct platform_device *pdev)
c->slot->free_slot(pdev);
sdhci_free_host(c->host);
-
- return 0;
}
static void __maybe_unused sdhci_acpi_reset_signal_voltage_if_needed(
@@ -1033,7 +1031,7 @@ static struct platform_driver sdhci_acpi_driver = {
.pm = &sdhci_acpi_pm_ops,
},
.probe = sdhci_acpi_probe,
- .remove = sdhci_acpi_remove,
+ .remove_new = sdhci_acpi_remove,
};
module_platform_driver(sdhci_acpi_driver);
diff --git a/drivers/mmc/host/sdhci-bcm-kona.c b/drivers/mmc/host/sdhci-bcm-kona.c
index 6a93a54fe067..cb9152c6a65d 100644
--- a/drivers/mmc/host/sdhci-bcm-kona.c
+++ b/drivers/mmc/host/sdhci-bcm-kona.c
@@ -11,7 +11,6 @@
#include <linux/clk.h>
#include <linux/regulator/consumer.h>
#include <linux/of.h>
-#include <linux/of_device.h>
#include <linux/mmc/slot-gpio.h>
#include "sdhci-pltfm.h"
@@ -311,6 +310,16 @@ err_pltfm_free:
return ret;
}
+static void sdhci_bcm_kona_remove(struct platform_device *pdev)
+{
+ struct sdhci_host *host = platform_get_drvdata(pdev);
+ struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+ struct clk *clk = pltfm_host->clk;
+
+ sdhci_pltfm_remove(pdev);
+ clk_disable_unprepare(clk);
+}
+
static struct platform_driver sdhci_bcm_kona_driver = {
.driver = {
.name = "sdhci-kona",
@@ -319,7 +328,7 @@ static struct platform_driver sdhci_bcm_kona_driver = {
.of_match_table = sdhci_bcm_kona_of_match,
},
.probe = sdhci_bcm_kona_probe,
- .remove = sdhci_pltfm_unregister,
+ .remove_new = sdhci_bcm_kona_remove,
};
module_platform_driver(sdhci_bcm_kona_driver);
diff --git a/drivers/mmc/host/sdhci-brcmstb.c b/drivers/mmc/host/sdhci-brcmstb.c
index 4c22337199cf..c23251bb95f3 100644
--- a/drivers/mmc/host/sdhci-brcmstb.c
+++ b/drivers/mmc/host/sdhci-brcmstb.c
@@ -264,23 +264,17 @@ static int sdhci_brcmstb_probe(struct platform_device *pdev)
dev_dbg(&pdev->dev, "Probe found match for %s\n", match->compatible);
- clk = devm_clk_get_optional(&pdev->dev, NULL);
+ clk = devm_clk_get_optional_enabled(&pdev->dev, NULL);
if (IS_ERR(clk))
return dev_err_probe(&pdev->dev, PTR_ERR(clk),
- "Failed to get clock from Device Tree\n");
-
- res = clk_prepare_enable(clk);
- if (res)
- return res;
+ "Failed to get and enable clock from Device Tree\n");
memset(&brcmstb_pdata, 0, sizeof(brcmstb_pdata));
brcmstb_pdata.ops = match_priv->ops;
host = sdhci_pltfm_init(pdev, &brcmstb_pdata,
sizeof(struct sdhci_brcmstb_priv));
- if (IS_ERR(host)) {
- res = PTR_ERR(host);
- goto err_clk;
- }
+ if (IS_ERR(host))
+ return PTR_ERR(host);
pltfm_host = sdhci_priv(host);
priv = sdhci_pltfm_priv(pltfm_host);
@@ -369,9 +363,7 @@ add_host:
err:
sdhci_pltfm_free(pdev);
-err_clk:
clk_disable_unprepare(base_clk);
- clk_disable_unprepare(clk);
return res;
}
@@ -430,7 +422,7 @@ static struct platform_driver sdhci_brcmstb_driver = {
.of_match_table = of_match_ptr(sdhci_brcm_of_match),
},
.probe = sdhci_brcmstb_probe,
- .remove = sdhci_pltfm_unregister,
+ .remove_new = sdhci_pltfm_remove,
.shutdown = sdhci_brcmstb_shutdown,
};
diff --git a/drivers/mmc/host/sdhci-cadence.c b/drivers/mmc/host/sdhci-cadence.c
index d2f625054689..be1505e8c536 100644
--- a/drivers/mmc/host/sdhci-cadence.c
+++ b/drivers/mmc/host/sdhci-cadence.c
@@ -11,7 +11,7 @@
#include <linux/mmc/host.h>
#include <linux/mmc/mmc.h>
#include <linux/of.h>
-#include <linux/of_device.h>
+#include <linux/platform_device.h>
#include <linux/reset.h>
#include "sdhci-pltfm.h"
@@ -487,14 +487,10 @@ static int sdhci_cdns_probe(struct platform_device *pdev)
struct device *dev = &pdev->dev;
static const u16 version = SDHCI_SPEC_400 << SDHCI_SPEC_VER_SHIFT;
- clk = devm_clk_get(dev, NULL);
+ clk = devm_clk_get_enabled(dev, NULL);
if (IS_ERR(clk))
return PTR_ERR(clk);
- ret = clk_prepare_enable(clk);
- if (ret)
- return ret;
-
data = of_device_get_match_data(dev);
if (!data)
data = &sdhci_cdns_drv_data;
@@ -502,10 +498,8 @@ static int sdhci_cdns_probe(struct platform_device *pdev)
nr_phy_params = sdhci_cdns_phy_param_count(dev->of_node);
host = sdhci_pltfm_init(pdev, &data->pltfm_data,
struct_size(priv, phy_params, nr_phy_params));
- if (IS_ERR(host)) {
- ret = PTR_ERR(host);
- goto disable_clk;
- }
+ if (IS_ERR(host))
+ return PTR_ERR(host);
pltfm_host = sdhci_priv(host);
pltfm_host->clk = clk;
@@ -556,9 +550,6 @@ static int sdhci_cdns_probe(struct platform_device *pdev)
return 0;
free:
sdhci_pltfm_free(pdev);
-disable_clk:
- clk_disable_unprepare(clk);
-
return ret;
}
@@ -617,7 +608,7 @@ static struct platform_driver sdhci_cdns_driver = {
.of_match_table = sdhci_cdns_match,
},
.probe = sdhci_cdns_probe,
- .remove = sdhci_pltfm_unregister,
+ .remove_new = sdhci_pltfm_remove,
};
module_platform_driver(sdhci_cdns_driver);
diff --git a/drivers/mmc/host/sdhci-dove.c b/drivers/mmc/host/sdhci-dove.c
index 5e5bf82e5976..88ec23417808 100644
--- a/drivers/mmc/host/sdhci-dove.c
+++ b/drivers/mmc/host/sdhci-dove.c
@@ -75,10 +75,7 @@ static int sdhci_dove_probe(struct platform_device *pdev)
return PTR_ERR(host);
pltfm_host = sdhci_priv(host);
- pltfm_host->clk = devm_clk_get(&pdev->dev, NULL);
-
- if (!IS_ERR(pltfm_host->clk))
- clk_prepare_enable(pltfm_host->clk);
+ pltfm_host->clk = devm_clk_get_enabled(&pdev->dev, NULL);
ret = mmc_of_parse(host->mmc);
if (ret)
@@ -91,7 +88,6 @@ static int sdhci_dove_probe(struct platform_device *pdev)
return 0;
err_sdhci_add:
- clk_disable_unprepare(pltfm_host->clk);
sdhci_pltfm_free(pdev);
return ret;
}
@@ -110,7 +106,7 @@ static struct platform_driver sdhci_dove_driver = {
.of_match_table = sdhci_dove_of_match_table,
},
.probe = sdhci_dove_probe,
- .remove = sdhci_pltfm_unregister,
+ .remove_new = sdhci_pltfm_remove,
};
module_platform_driver(sdhci_dove_driver);
diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c
index eebf94604a7f..3b8030f3552a 100644
--- a/drivers/mmc/host/sdhci-esdhc-imx.c
+++ b/drivers/mmc/host/sdhci-esdhc-imx.c
@@ -22,7 +22,7 @@
#include <linux/mmc/sdio.h>
#include <linux/mmc/slot-gpio.h>
#include <linux/of.h>
-#include <linux/of_device.h>
+#include <linux/platform_device.h>
#include <linux/pinctrl/consumer.h>
#include <linux/pm_runtime.h>
#include "sdhci-cqhci.h"
@@ -171,8 +171,8 @@
#define ESDHC_FLAG_HS400 BIT(9)
/*
* The IP has errata ERR010450
- * uSDHC: Due to the I/O timing limit, for SDR mode, SD card clock can't
- * exceed 150MHz, for DDR mode, SD card clock can't exceed 45MHz.
+ * uSDHC: At 1.8V due to the I/O timing limit, for SDR mode, SD card
+ * clock can't exceed 150MHz, for DDR mode, SD card clock can't exceed 45MHz.
*/
#define ESDHC_FLAG_ERR010450 BIT(10)
/* The IP supports HS400ES mode */
@@ -961,7 +961,8 @@ static inline void esdhc_pltfm_set_clock(struct sdhci_host *host,
| ESDHC_CLOCK_MASK);
sdhci_writel(host, temp, ESDHC_SYSTEM_CONTROL);
- if (imx_data->socdata->flags & ESDHC_FLAG_ERR010450) {
+ if ((imx_data->socdata->flags & ESDHC_FLAG_ERR010450) &&
+ (!(host->quirks2 & SDHCI_QUIRK2_NO_1_8_V))) {
unsigned int max_clock;
max_clock = imx_data->is_ddr ? 45000000 : 150000000;
@@ -1802,7 +1803,7 @@ free_sdhci:
return err;
}
-static int sdhci_esdhc_imx_remove(struct platform_device *pdev)
+static void sdhci_esdhc_imx_remove(struct platform_device *pdev)
{
struct sdhci_host *host = platform_get_drvdata(pdev);
struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
@@ -1824,8 +1825,6 @@ static int sdhci_esdhc_imx_remove(struct platform_device *pdev)
cpu_latency_qos_remove_request(&imx_data->pm_qos_req);
sdhci_pltfm_free(pdev);
-
- return 0;
}
#ifdef CONFIG_PM_SLEEP
@@ -1986,7 +1985,7 @@ static struct platform_driver sdhci_esdhc_imx_driver = {
.pm = &sdhci_esdhc_pmops,
},
.probe = sdhci_esdhc_imx_probe,
- .remove = sdhci_esdhc_imx_remove,
+ .remove_new = sdhci_esdhc_imx_remove,
};
module_platform_driver(sdhci_esdhc_imx_driver);
diff --git a/drivers/mmc/host/sdhci-esdhc-mcf.c b/drivers/mmc/host/sdhci-esdhc-mcf.c
index 05926bf5ecf9..a07f8333cd6b 100644
--- a/drivers/mmc/host/sdhci-esdhc-mcf.c
+++ b/drivers/mmc/host/sdhci-esdhc-mcf.c
@@ -489,7 +489,7 @@ err_exit:
return err;
}
-static int sdhci_esdhc_mcf_remove(struct platform_device *pdev)
+static void sdhci_esdhc_mcf_remove(struct platform_device *pdev)
{
struct sdhci_host *host = platform_get_drvdata(pdev);
struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
@@ -502,8 +502,6 @@ static int sdhci_esdhc_mcf_remove(struct platform_device *pdev)
clk_disable_unprepare(mcf_data->clk_per);
sdhci_pltfm_free(pdev);
-
- return 0;
}
static struct platform_driver sdhci_esdhc_mcf_driver = {
@@ -512,7 +510,7 @@ static struct platform_driver sdhci_esdhc_mcf_driver = {
.probe_type = PROBE_PREFER_ASYNCHRONOUS,
},
.probe = sdhci_esdhc_mcf_probe,
- .remove = sdhci_esdhc_mcf_remove,
+ .remove_new = sdhci_esdhc_mcf_remove,
};
module_platform_driver(sdhci_esdhc_mcf_driver);
diff --git a/drivers/mmc/host/sdhci-iproc.c b/drivers/mmc/host/sdhci-iproc.c
index 86eb0045515e..10235fdff246 100644
--- a/drivers/mmc/host/sdhci-iproc.c
+++ b/drivers/mmc/host/sdhci-iproc.c
@@ -10,7 +10,7 @@
#include <linux/module.h>
#include <linux/mmc/host.h>
#include <linux/of.h>
-#include <linux/of_device.h>
+#include <linux/platform_device.h>
#include "sdhci-pltfm.h"
struct sdhci_iproc_data {
@@ -386,16 +386,11 @@ static int sdhci_iproc_probe(struct platform_device *pdev)
host->mmc->caps |= iproc_host->data->mmc_caps;
if (dev->of_node) {
- pltfm_host->clk = devm_clk_get(dev, NULL);
+ pltfm_host->clk = devm_clk_get_enabled(dev, NULL);
if (IS_ERR(pltfm_host->clk)) {
ret = PTR_ERR(pltfm_host->clk);
goto err;
}
- ret = clk_prepare_enable(pltfm_host->clk);
- if (ret) {
- dev_err(dev, "failed to enable host clk\n");
- goto err;
- }
}
if (iproc_host->data->missing_caps) {
@@ -406,13 +401,10 @@ static int sdhci_iproc_probe(struct platform_device *pdev)
ret = sdhci_add_host(host);
if (ret)
- goto err_clk;
+ goto err;
return 0;
-err_clk:
- if (dev->of_node)
- clk_disable_unprepare(pltfm_host->clk);
err:
sdhci_pltfm_free(pdev);
return ret;
@@ -432,7 +424,7 @@ static struct platform_driver sdhci_iproc_driver = {
.pm = &sdhci_pltfm_pmops,
},
.probe = sdhci_iproc_probe,
- .remove = sdhci_pltfm_unregister,
+ .remove_new = sdhci_pltfm_remove,
.shutdown = sdhci_iproc_shutdown,
};
module_platform_driver(sdhci_iproc_driver);
diff --git a/drivers/mmc/host/sdhci-milbeaut.c b/drivers/mmc/host/sdhci-milbeaut.c
index 148b37ac6564..83706edc9796 100644
--- a/drivers/mmc/host/sdhci-milbeaut.c
+++ b/drivers/mmc/host/sdhci-milbeaut.c
@@ -313,7 +313,7 @@ err:
return ret;
}
-static int sdhci_milbeaut_remove(struct platform_device *pdev)
+static void sdhci_milbeaut_remove(struct platform_device *pdev)
{
struct sdhci_host *host = platform_get_drvdata(pdev);
struct f_sdhost_priv *priv = sdhci_priv(host);
@@ -326,18 +326,16 @@ static int sdhci_milbeaut_remove(struct platform_device *pdev)
sdhci_free_host(host);
platform_set_drvdata(pdev, NULL);
-
- return 0;
}
static struct platform_driver sdhci_milbeaut_driver = {
.driver = {
.name = "sdhci-milbeaut",
.probe_type = PROBE_PREFER_ASYNCHRONOUS,
- .of_match_table = of_match_ptr(mlb_dt_ids),
+ .of_match_table = mlb_dt_ids,
},
.probe = sdhci_milbeaut_probe,
- .remove = sdhci_milbeaut_remove,
+ .remove_new = sdhci_milbeaut_remove,
};
module_platform_driver(sdhci_milbeaut_driver);
diff --git a/drivers/mmc/host/sdhci-msm.c b/drivers/mmc/host/sdhci-msm.c
index 1c935b5bafe1..668e0aceeeba 100644
--- a/drivers/mmc/host/sdhci-msm.c
+++ b/drivers/mmc/host/sdhci-msm.c
@@ -6,7 +6,6 @@
*/
#include <linux/module.h>
-#include <linux/of_device.h>
#include <linux/delay.h>
#include <linux/mmc/mmc.h>
#include <linux/pm_runtime.h>
@@ -15,6 +14,7 @@
#include <linux/iopoll.h>
#include <linux/regulator/consumer.h>
#include <linux/interconnect.h>
+#include <linux/of.h>
#include <linux/pinctrl/consumer.h>
#include <linux/reset.h>
@@ -2668,7 +2668,7 @@ pltfm_free:
return ret;
}
-static int sdhci_msm_remove(struct platform_device *pdev)
+static void sdhci_msm_remove(struct platform_device *pdev)
{
struct sdhci_host *host = platform_get_drvdata(pdev);
struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
@@ -2687,7 +2687,6 @@ static int sdhci_msm_remove(struct platform_device *pdev)
if (!IS_ERR(msm_host->bus_clk))
clk_disable_unprepare(msm_host->bus_clk);
sdhci_pltfm_free(pdev);
- return 0;
}
static __maybe_unused int sdhci_msm_runtime_suspend(struct device *dev)
@@ -2740,7 +2739,7 @@ static const struct dev_pm_ops sdhci_msm_pm_ops = {
static struct platform_driver sdhci_msm_driver = {
.probe = sdhci_msm_probe,
- .remove = sdhci_msm_remove,
+ .remove_new = sdhci_msm_remove,
.driver = {
.name = "sdhci_msm",
.of_match_table = sdhci_msm_dt_match,
diff --git a/drivers/mmc/host/sdhci-of-arasan.c b/drivers/mmc/host/sdhci-of-arasan.c
index 294dd605fd2b..5edd024347bd 100644
--- a/drivers/mmc/host/sdhci-of-arasan.c
+++ b/drivers/mmc/host/sdhci-of-arasan.c
@@ -18,11 +18,11 @@
#include <linux/clk-provider.h>
#include <linux/mfd/syscon.h>
#include <linux/module.h>
-#include <linux/of_device.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
#include <linux/phy/phy.h>
#include <linux/regmap.h>
#include <linux/reset.h>
-#include <linux/of.h>
#include <linux/firmware/xlnx-zynqmp.h>
#include "cqhci.h"
@@ -2016,12 +2016,13 @@ err_pltfm_free:
return ret;
}
-static int sdhci_arasan_remove(struct platform_device *pdev)
+static void sdhci_arasan_remove(struct platform_device *pdev)
{
struct sdhci_host *host = platform_get_drvdata(pdev);
struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
struct sdhci_arasan_data *sdhci_arasan = sdhci_pltfm_priv(pltfm_host);
struct clk *clk_ahb = sdhci_arasan->clk_ahb;
+ struct clk *clk_xin = pltfm_host->clk;
if (!IS_ERR(sdhci_arasan->phy)) {
if (sdhci_arasan->is_phy_on)
@@ -2031,11 +2032,10 @@ static int sdhci_arasan_remove(struct platform_device *pdev)
sdhci_arasan_unregister_sdclk(&pdev->dev);
- sdhci_pltfm_unregister(pdev);
+ sdhci_pltfm_remove(pdev);
+ clk_disable_unprepare(clk_xin);
clk_disable_unprepare(clk_ahb);
-
- return 0;
}
static struct platform_driver sdhci_arasan_driver = {
@@ -2046,7 +2046,7 @@ static struct platform_driver sdhci_arasan_driver = {
.pm = &sdhci_arasan_dev_pm_ops,
},
.probe = sdhci_arasan_probe,
- .remove = sdhci_arasan_remove,
+ .remove_new = sdhci_arasan_remove,
};
module_platform_driver(sdhci_arasan_driver);
diff --git a/drivers/mmc/host/sdhci-of-aspeed.c b/drivers/mmc/host/sdhci-of-aspeed.c
index 25b4073f698b..42d54532cabe 100644
--- a/drivers/mmc/host/sdhci-of-aspeed.c
+++ b/drivers/mmc/host/sdhci-of-aspeed.c
@@ -450,22 +450,19 @@ err_pltfm_free:
return ret;
}
-static int aspeed_sdhci_remove(struct platform_device *pdev)
+static void aspeed_sdhci_remove(struct platform_device *pdev)
{
struct sdhci_pltfm_host *pltfm_host;
struct sdhci_host *host;
- int dead = 0;
host = platform_get_drvdata(pdev);
pltfm_host = sdhci_priv(host);
- sdhci_remove_host(host, dead);
+ sdhci_remove_host(host, 0);
clk_disable_unprepare(pltfm_host->clk);
sdhci_pltfm_free(pdev);
-
- return 0;
}
static const struct aspeed_sdhci_pdata ast2400_sdhci_pdata = {
@@ -521,7 +518,7 @@ static struct platform_driver aspeed_sdhci_driver = {
.of_match_table = aspeed_sdhci_of_match,
},
.probe = aspeed_sdhci_probe,
- .remove = aspeed_sdhci_remove,
+ .remove_new = aspeed_sdhci_remove,
};
static int aspeed_sdc_probe(struct platform_device *pdev)
@@ -574,13 +571,11 @@ err_clk:
return ret;
}
-static int aspeed_sdc_remove(struct platform_device *pdev)
+static void aspeed_sdc_remove(struct platform_device *pdev)
{
struct aspeed_sdc *sdc = dev_get_drvdata(&pdev->dev);
clk_disable_unprepare(sdc->clk);
-
- return 0;
}
static const struct of_device_id aspeed_sdc_of_match[] = {
@@ -600,7 +595,7 @@ static struct platform_driver aspeed_sdc_driver = {
.of_match_table = aspeed_sdc_of_match,
},
.probe = aspeed_sdc_probe,
- .remove = aspeed_sdc_remove,
+ .remove_new = aspeed_sdc_remove,
};
#if defined(CONFIG_MMC_SDHCI_OF_ASPEED_TEST)
diff --git a/drivers/mmc/host/sdhci-of-at91.c b/drivers/mmc/host/sdhci-of-at91.c
index cd0134580a90..23a9faad2ff8 100644
--- a/drivers/mmc/host/sdhci-of-at91.c
+++ b/drivers/mmc/host/sdhci-of-at91.c
@@ -17,7 +17,7 @@
#include <linux/mmc/slot-gpio.h>
#include <linux/module.h>
#include <linux/of.h>
-#include <linux/of_device.h>
+#include <linux/platform_device.h>
#include <linux/pm.h>
#include <linux/pm_runtime.h>
@@ -443,7 +443,7 @@ sdhci_pltfm_free:
return ret;
}
-static int sdhci_at91_remove(struct platform_device *pdev)
+static void sdhci_at91_remove(struct platform_device *pdev)
{
struct sdhci_host *host = platform_get_drvdata(pdev);
struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
@@ -456,13 +456,11 @@ static int sdhci_at91_remove(struct platform_device *pdev)
pm_runtime_disable(&pdev->dev);
pm_runtime_put_noidle(&pdev->dev);
- sdhci_pltfm_unregister(pdev);
+ sdhci_pltfm_remove(pdev);
clk_disable_unprepare(gck);
clk_disable_unprepare(hclock);
clk_disable_unprepare(mainck);
-
- return 0;
}
static struct platform_driver sdhci_at91_driver = {
@@ -473,7 +471,7 @@ static struct platform_driver sdhci_at91_driver = {
.pm = &sdhci_at91_dev_pm_ops,
},
.probe = sdhci_at91_probe,
- .remove = sdhci_at91_remove,
+ .remove_new = sdhci_at91_remove,
};
module_platform_driver(sdhci_at91_driver);
diff --git a/drivers/mmc/host/sdhci-of-dwcmshc.c b/drivers/mmc/host/sdhci-of-dwcmshc.c
index e68cd87998c8..3a3bae6948a8 100644
--- a/drivers/mmc/host/sdhci-of-dwcmshc.c
+++ b/drivers/mmc/host/sdhci-of-dwcmshc.c
@@ -14,7 +14,8 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/of.h>
-#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
#include <linux/reset.h>
#include <linux/sizes.h>
@@ -548,9 +549,13 @@ static int dwcmshc_probe(struct platform_device *pdev)
host->mmc->caps |= MMC_CAP_WAIT_WHILE_BUSY;
+ pm_runtime_get_noresume(dev);
+ pm_runtime_set_active(dev);
+ pm_runtime_enable(dev);
+
err = sdhci_setup_host(host);
if (err)
- goto err_clk;
+ goto err_rpm;
if (rk_priv)
dwcmshc_rk35xx_postinit(host, priv);
@@ -559,10 +564,15 @@ static int dwcmshc_probe(struct platform_device *pdev)
if (err)
goto err_setup_host;
+ pm_runtime_put(dev);
+
return 0;
err_setup_host:
sdhci_cleanup_host(host);
+err_rpm:
+ pm_runtime_disable(dev);
+ pm_runtime_put_noidle(dev);
err_clk:
clk_disable_unprepare(pltfm_host->clk);
clk_disable_unprepare(priv->bus_clk);
@@ -574,7 +584,7 @@ free_pltfm:
return err;
}
-static int dwcmshc_remove(struct platform_device *pdev)
+static void dwcmshc_remove(struct platform_device *pdev)
{
struct sdhci_host *host = platform_get_drvdata(pdev);
struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
@@ -589,8 +599,6 @@ static int dwcmshc_remove(struct platform_device *pdev)
clk_bulk_disable_unprepare(RK35xx_MAX_CLKS,
rk_priv->rockchip_clks);
sdhci_pltfm_free(pdev);
-
- return 0;
}
#ifdef CONFIG_PM_SLEEP
@@ -602,6 +610,8 @@ static int dwcmshc_suspend(struct device *dev)
struct rk35xx_priv *rk_priv = priv->priv;
int ret;
+ pm_runtime_resume(dev);
+
ret = sdhci_suspend_host(host);
if (ret)
return ret;
@@ -632,21 +642,84 @@ static int dwcmshc_resume(struct device *dev)
if (!IS_ERR(priv->bus_clk)) {
ret = clk_prepare_enable(priv->bus_clk);
if (ret)
- return ret;
+ goto disable_clk;
}
if (rk_priv) {
ret = clk_bulk_prepare_enable(RK35xx_MAX_CLKS,
rk_priv->rockchip_clks);
if (ret)
- return ret;
+ goto disable_bus_clk;
}
- return sdhci_resume_host(host);
+ ret = sdhci_resume_host(host);
+ if (ret)
+ goto disable_rockchip_clks;
+
+ return 0;
+
+disable_rockchip_clks:
+ if (rk_priv)
+ clk_bulk_disable_unprepare(RK35xx_MAX_CLKS,
+ rk_priv->rockchip_clks);
+disable_bus_clk:
+ if (!IS_ERR(priv->bus_clk))
+ clk_disable_unprepare(priv->bus_clk);
+disable_clk:
+ clk_disable_unprepare(pltfm_host->clk);
+ return ret;
}
#endif
-static SIMPLE_DEV_PM_OPS(dwcmshc_pmops, dwcmshc_suspend, dwcmshc_resume);
+#ifdef CONFIG_PM
+
+static void dwcmshc_enable_card_clk(struct sdhci_host *host)
+{
+ u16 ctrl;
+
+ ctrl = sdhci_readw(host, SDHCI_CLOCK_CONTROL);
+ if ((ctrl & SDHCI_CLOCK_INT_EN) && !(ctrl & SDHCI_CLOCK_CARD_EN)) {
+ ctrl |= SDHCI_CLOCK_CARD_EN;
+ sdhci_writew(host, ctrl, SDHCI_CLOCK_CONTROL);
+ }
+}
+
+static void dwcmshc_disable_card_clk(struct sdhci_host *host)
+{
+ u16 ctrl;
+
+ ctrl = sdhci_readw(host, SDHCI_CLOCK_CONTROL);
+ if (ctrl & SDHCI_CLOCK_CARD_EN) {
+ ctrl &= ~SDHCI_CLOCK_CARD_EN;
+ sdhci_writew(host, ctrl, SDHCI_CLOCK_CONTROL);
+ }
+}
+
+static int dwcmshc_runtime_suspend(struct device *dev)
+{
+ struct sdhci_host *host = dev_get_drvdata(dev);
+
+ dwcmshc_disable_card_clk(host);
+
+ return 0;
+}
+
+static int dwcmshc_runtime_resume(struct device *dev)
+{
+ struct sdhci_host *host = dev_get_drvdata(dev);
+
+ dwcmshc_enable_card_clk(host);
+
+ return 0;
+}
+
+#endif
+
+static const struct dev_pm_ops dwcmshc_pmops = {
+ SET_SYSTEM_SLEEP_PM_OPS(dwcmshc_suspend, dwcmshc_resume)
+ SET_RUNTIME_PM_OPS(dwcmshc_runtime_suspend,
+ dwcmshc_runtime_resume, NULL)
+};
static struct platform_driver sdhci_dwcmshc_driver = {
.driver = {
@@ -657,7 +730,7 @@ static struct platform_driver sdhci_dwcmshc_driver = {
.pm = &dwcmshc_pmops,
},
.probe = dwcmshc_probe,
- .remove = dwcmshc_remove,
+ .remove_new = dwcmshc_remove,
};
module_platform_driver(sdhci_dwcmshc_driver);
diff --git a/drivers/mmc/host/sdhci-of-esdhc.c b/drivers/mmc/host/sdhci-of-esdhc.c
index 48ca1cf15b19..3ae9aa25745a 100644
--- a/drivers/mmc/host/sdhci-of-esdhc.c
+++ b/drivers/mmc/host/sdhci-of-esdhc.c
@@ -1521,7 +1521,7 @@ static struct platform_driver sdhci_esdhc_driver = {
.pm = &esdhc_of_dev_pm_ops,
},
.probe = sdhci_esdhc_probe,
- .remove = sdhci_pltfm_unregister,
+ .remove_new = sdhci_pltfm_remove,
};
module_platform_driver(sdhci_esdhc_driver);
diff --git a/drivers/mmc/host/sdhci-of-hlwd.c b/drivers/mmc/host/sdhci-of-hlwd.c
index 12675797b296..9c1c0ce610ef 100644
--- a/drivers/mmc/host/sdhci-of-hlwd.c
+++ b/drivers/mmc/host/sdhci-of-hlwd.c
@@ -68,7 +68,7 @@ static const struct sdhci_pltfm_data sdhci_hlwd_pdata = {
static int sdhci_hlwd_probe(struct platform_device *pdev)
{
- return sdhci_pltfm_register(pdev, &sdhci_hlwd_pdata, 0);
+ return sdhci_pltfm_init_and_add_host(pdev, &sdhci_hlwd_pdata, 0);
}
static const struct of_device_id sdhci_hlwd_of_match[] = {
@@ -85,7 +85,7 @@ static struct platform_driver sdhci_hlwd_driver = {
.pm = &sdhci_pltfm_pmops,
},
.probe = sdhci_hlwd_probe,
- .remove = sdhci_pltfm_unregister,
+ .remove_new = sdhci_pltfm_remove,
};
module_platform_driver(sdhci_hlwd_driver);
diff --git a/drivers/mmc/host/sdhci-of-sparx5.c b/drivers/mmc/host/sdhci-of-sparx5.c
index 28e4ee69e100..64b77e7d14cd 100644
--- a/drivers/mmc/host/sdhci-of-sparx5.c
+++ b/drivers/mmc/host/sdhci-of-sparx5.c
@@ -13,9 +13,9 @@
#include <linux/delay.h>
#include <linux/module.h>
#include <linux/regmap.h>
-#include <linux/of_device.h>
#include <linux/mfd/syscon.h>
#include <linux/dma-mapping.h>
+#include <linux/of.h>
#include "sdhci-pltfm.h"
@@ -184,15 +184,12 @@ static int sdhci_sparx5_probe(struct platform_device *pdev)
sdhci_sparx5 = sdhci_pltfm_priv(pltfm_host);
sdhci_sparx5->host = host;
- pltfm_host->clk = devm_clk_get(&pdev->dev, "core");
+ pltfm_host->clk = devm_clk_get_enabled(&pdev->dev, "core");
if (IS_ERR(pltfm_host->clk)) {
ret = PTR_ERR(pltfm_host->clk);
- dev_err(&pdev->dev, "failed to get core clk: %d\n", ret);
+ dev_err(&pdev->dev, "failed to get and enable core clk: %d\n", ret);
goto free_pltfm;
}
- ret = clk_prepare_enable(pltfm_host->clk);
- if (ret)
- goto free_pltfm;
if (!of_property_read_u32(np, "microchip,clock-delay", &value) &&
(value > 0 && value <= MSHC_DLY_CC_MAX))
@@ -202,13 +199,13 @@ static int sdhci_sparx5_probe(struct platform_device *pdev)
ret = mmc_of_parse(host->mmc);
if (ret)
- goto err_clk;
+ goto free_pltfm;
sdhci_sparx5->cpu_ctrl = syscon_regmap_lookup_by_compatible(syscon);
if (IS_ERR(sdhci_sparx5->cpu_ctrl)) {
dev_err(&pdev->dev, "No CPU syscon regmap !\n");
ret = PTR_ERR(sdhci_sparx5->cpu_ctrl);
- goto err_clk;
+ goto free_pltfm;
}
if (sdhci_sparx5->delay_clock >= 0)
@@ -225,7 +222,7 @@ static int sdhci_sparx5_probe(struct platform_device *pdev)
ret = sdhci_add_host(host);
if (ret)
- goto err_clk;
+ goto free_pltfm;
/* Set AXI bus master to use un-cached access (for DMA) */
if (host->flags & (SDHCI_USE_SDMA | SDHCI_USE_ADMA) &&
@@ -239,8 +236,6 @@ static int sdhci_sparx5_probe(struct platform_device *pdev)
return ret;
-err_clk:
- clk_disable_unprepare(pltfm_host->clk);
free_pltfm:
sdhci_pltfm_free(pdev);
return ret;
@@ -260,7 +255,7 @@ static struct platform_driver sdhci_sparx5_driver = {
.pm = &sdhci_pltfm_pmops,
},
.probe = sdhci_sparx5_probe,
- .remove = sdhci_pltfm_unregister,
+ .remove_new = sdhci_pltfm_remove,
};
module_platform_driver(sdhci_sparx5_driver);
diff --git a/drivers/mmc/host/sdhci-omap.c b/drivers/mmc/host/sdhci-omap.c
index 8ed9256b83da..1e0bc7bace1b 100644
--- a/drivers/mmc/host/sdhci-omap.c
+++ b/drivers/mmc/host/sdhci-omap.c
@@ -11,7 +11,6 @@
#include <linux/mmc/slot-gpio.h>
#include <linux/module.h>
#include <linux/of.h>
-#include <linux/of_device.h>
#include <linux/of_irq.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
@@ -1394,7 +1393,7 @@ err_pltfm_free:
return ret;
}
-static int sdhci_omap_remove(struct platform_device *pdev)
+static void sdhci_omap_remove(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct sdhci_host *host = platform_get_drvdata(pdev);
@@ -1408,8 +1407,6 @@ static int sdhci_omap_remove(struct platform_device *pdev)
/* Ensure device gets disabled despite userspace sysfs config */
pm_runtime_force_suspend(dev);
sdhci_pltfm_free(pdev);
-
- return 0;
}
#ifdef CONFIG_PM
@@ -1478,7 +1475,7 @@ static const struct dev_pm_ops sdhci_omap_dev_pm_ops = {
static struct platform_driver sdhci_omap_driver = {
.probe = sdhci_omap_probe,
- .remove = sdhci_omap_remove,
+ .remove_new = sdhci_omap_remove,
.driver = {
.name = "sdhci-omap",
.probe_type = PROBE_PREFER_ASYNCHRONOUS,
diff --git a/drivers/mmc/host/sdhci-pci-core.c b/drivers/mmc/host/sdhci-pci-core.c
index 1c2572c0f012..7c14feb5db77 100644
--- a/drivers/mmc/host/sdhci-pci-core.c
+++ b/drivers/mmc/host/sdhci-pci-core.c
@@ -1898,6 +1898,10 @@ static const struct pci_device_id pci_ids[] = {
SDHCI_PCI_DEVICE(O2, SDS1, o2),
SDHCI_PCI_DEVICE(O2, SEABIRD0, o2),
SDHCI_PCI_DEVICE(O2, SEABIRD1, o2),
+ SDHCI_PCI_DEVICE(O2, GG8_9860, o2),
+ SDHCI_PCI_DEVICE(O2, GG8_9861, o2),
+ SDHCI_PCI_DEVICE(O2, GG8_9862, o2),
+ SDHCI_PCI_DEVICE(O2, GG8_9863, o2),
SDHCI_PCI_DEVICE(ARASAN, PHY_EMMC, arasan),
SDHCI_PCI_DEVICE(SYNOPSYS, DWC_MSHC, snps),
SDHCI_PCI_DEVICE(GLI, 9750, gl9750),
diff --git a/drivers/mmc/host/sdhci-pci-o2micro.c b/drivers/mmc/host/sdhci-pci-o2micro.c
index 620f52ad9667..7bfee28116af 100644
--- a/drivers/mmc/host/sdhci-pci-o2micro.c
+++ b/drivers/mmc/host/sdhci-pci-o2micro.c
@@ -21,6 +21,7 @@
* O2Micro device registers
*/
+#define O2_SD_PCIE_SWITCH 0x54
#define O2_SD_MISC_REG5 0x64
#define O2_SD_LD0_CTRL 0x68
#define O2_SD_DEV_CTRL 0x88
@@ -36,6 +37,7 @@
#define O2_SD_INF_MOD 0xF1
#define O2_SD_MISC_CTRL4 0xFC
#define O2_SD_MISC_CTRL 0x1C0
+#define O2_SD_EXP_INT_REG 0x1E0
#define O2_SD_PWR_FORCE_L0 0x0002
#define O2_SD_TUNING_CTRL 0x300
#define O2_SD_PLL_SETTING 0x304
@@ -49,6 +51,9 @@
#define O2_SD_UHS2_L1_CTRL 0x35C
#define O2_SD_FUNC_REG3 0x3E0
#define O2_SD_FUNC_REG4 0x3E4
+#define O2_SD_PARA_SET_REG1 0x444
+#define O2_SD_VDDX_CTRL_REG 0x508
+#define O2_SD_GPIO_CTRL_REG1 0x510
#define O2_SD_LED_ENABLE BIT(6)
#define O2_SD_FREG0_LEDOFF BIT(13)
#define O2_SD_SEL_DLL BIT(16)
@@ -334,33 +339,45 @@ static int sdhci_o2_execute_tuning(struct mmc_host *mmc, u32 opcode)
scratch |= O2_SD_PWR_FORCE_L0;
sdhci_writew(host, scratch, O2_SD_MISC_CTRL);
- /* Stop clk */
- reg_val = sdhci_readw(host, SDHCI_CLOCK_CONTROL);
- reg_val &= ~SDHCI_CLOCK_CARD_EN;
- sdhci_writew(host, reg_val, SDHCI_CLOCK_CONTROL);
-
- if ((host->timing == MMC_TIMING_MMC_HS200) ||
- (host->timing == MMC_TIMING_UHS_SDR104)) {
- /* UnLock WP */
- pci_read_config_byte(chip->pdev, O2_SD_LOCK_WP, &scratch_8);
- scratch_8 &= 0x7f;
- pci_write_config_byte(chip->pdev, O2_SD_LOCK_WP, scratch_8);
-
- /* Set pcr 0x354[16] to choose dll clock, and set the default phase */
- pci_read_config_dword(chip->pdev, O2_SD_OUTPUT_CLK_SOURCE_SWITCH, &reg_val);
- reg_val &= ~(O2_SD_SEL_DLL | O2_SD_PHASE_MASK);
- reg_val |= (O2_SD_SEL_DLL | O2_SD_FIX_PHASE);
- pci_write_config_dword(chip->pdev, O2_SD_OUTPUT_CLK_SOURCE_SWITCH, reg_val);
+ /* Update output phase */
+ switch (chip->pdev->device) {
+ case PCI_DEVICE_ID_O2_SDS0:
+ case PCI_DEVICE_ID_O2_SEABIRD0:
+ case PCI_DEVICE_ID_O2_SEABIRD1:
+ case PCI_DEVICE_ID_O2_SDS1:
+ case PCI_DEVICE_ID_O2_FUJIN2:
+ /* Stop clk */
+ reg_val = sdhci_readw(host, SDHCI_CLOCK_CONTROL);
+ reg_val &= ~SDHCI_CLOCK_CARD_EN;
+ sdhci_writew(host, reg_val, SDHCI_CLOCK_CONTROL);
+
+ if (host->timing == MMC_TIMING_MMC_HS200 ||
+ host->timing == MMC_TIMING_UHS_SDR104) {
+ /* UnLock WP */
+ pci_read_config_byte(chip->pdev, O2_SD_LOCK_WP, &scratch_8);
+ scratch_8 &= 0x7f;
+ pci_write_config_byte(chip->pdev, O2_SD_LOCK_WP, scratch_8);
+
+ /* Set pcr 0x354[16] to choose dll clock, and set the default phase */
+ pci_read_config_dword(chip->pdev, O2_SD_OUTPUT_CLK_SOURCE_SWITCH, &reg_val);
+ reg_val &= ~(O2_SD_SEL_DLL | O2_SD_PHASE_MASK);
+ reg_val |= (O2_SD_SEL_DLL | O2_SD_FIX_PHASE);
+ pci_write_config_dword(chip->pdev, O2_SD_OUTPUT_CLK_SOURCE_SWITCH, reg_val);
+
+ /* Lock WP */
+ pci_read_config_byte(chip->pdev, O2_SD_LOCK_WP, &scratch_8);
+ scratch_8 |= 0x80;
+ pci_write_config_byte(chip->pdev, O2_SD_LOCK_WP, scratch_8);
+ }
- /* Lock WP */
- pci_read_config_byte(chip->pdev, O2_SD_LOCK_WP, &scratch_8);
- scratch_8 |= 0x80;
- pci_write_config_byte(chip->pdev, O2_SD_LOCK_WP, scratch_8);
+ /* Start clk */
+ reg_val = sdhci_readw(host, SDHCI_CLOCK_CONTROL);
+ reg_val |= SDHCI_CLOCK_CARD_EN;
+ sdhci_writew(host, reg_val, SDHCI_CLOCK_CONTROL);
+ break;
+ default:
+ break;
}
- /* Start clk */
- reg_val = sdhci_readw(host, SDHCI_CLOCK_CONTROL);
- reg_val |= SDHCI_CLOCK_CARD_EN;
- sdhci_writew(host, reg_val, SDHCI_CLOCK_CONTROL);
/* wait DLL lock, timeout value 5ms */
if (readx_poll_timeout(sdhci_o2_pll_dll_wdt_control, host,
@@ -563,6 +580,7 @@ static void sdhci_pci_o2_set_clock(struct sdhci_host *host, unsigned int clock)
u16 clk;
u8 scratch;
u32 scratch_32;
+ u32 dmdn_208m, dmdn_200m;
struct sdhci_pci_slot *slot = sdhci_priv(host);
struct sdhci_pci_chip *chip = slot->chip;
@@ -578,16 +596,27 @@ static void sdhci_pci_o2_set_clock(struct sdhci_host *host, unsigned int clock)
scratch &= 0x7f;
pci_write_config_byte(chip->pdev, O2_SD_LOCK_WP, scratch);
+ if (chip->pdev->device == PCI_DEVICE_ID_O2_GG8_9860 ||
+ chip->pdev->device == PCI_DEVICE_ID_O2_GG8_9861 ||
+ chip->pdev->device == PCI_DEVICE_ID_O2_GG8_9862 ||
+ chip->pdev->device == PCI_DEVICE_ID_O2_GG8_9863) {
+ dmdn_208m = 0x2c500000;
+ dmdn_200m = 0x25200000;
+ } else {
+ dmdn_208m = 0x2c280000;
+ dmdn_200m = 0x25100000;
+ }
+
if ((host->timing == MMC_TIMING_UHS_SDR104) && (clock == 200000000)) {
pci_read_config_dword(chip->pdev, O2_SD_PLL_SETTING, &scratch_32);
- if ((scratch_32 & 0xFFFF0000) != 0x2c280000)
- o2_pci_set_baseclk(chip, 0x2c280000);
+ if ((scratch_32 & 0xFFFF0000) != dmdn_208m)
+ o2_pci_set_baseclk(chip, dmdn_208m);
} else {
pci_read_config_dword(chip->pdev, O2_SD_PLL_SETTING, &scratch_32);
- if ((scratch_32 & 0xFFFF0000) != 0x25100000)
- o2_pci_set_baseclk(chip, 0x25100000);
+ if ((scratch_32 & 0xFFFF0000) != dmdn_200m)
+ o2_pci_set_baseclk(chip, dmdn_200m);
}
pci_read_config_dword(chip->pdev, O2_SD_OUTPUT_CLK_SOURCE_SWITCH, &scratch_32);
@@ -603,6 +632,67 @@ static void sdhci_pci_o2_set_clock(struct sdhci_host *host, unsigned int clock)
sdhci_o2_enable_clk(host, clk);
}
+static int sdhci_pci_o2_init_sd_express(struct mmc_host *mmc, struct mmc_ios *ios)
+{
+ struct sdhci_host *host = mmc_priv(mmc);
+ struct sdhci_pci_slot *slot = sdhci_priv(host);
+ struct sdhci_pci_chip *chip = slot->chip;
+ u8 scratch8;
+ u16 scratch16;
+ int ret;
+
+ /* Disable clock */
+ sdhci_writeb(host, 0, SDHCI_CLOCK_CONTROL);
+
+ /* Set VDD2 voltage*/
+ scratch8 = sdhci_readb(host, SDHCI_POWER_CONTROL);
+ scratch8 &= 0x0F;
+ if (host->mmc->ios.timing == MMC_TIMING_SD_EXP_1_2V &&
+ host->mmc->caps2 & MMC_CAP2_SD_EXP_1_2V) {
+ scratch8 |= SDHCI_VDD2_POWER_ON | SDHCI_VDD2_POWER_120;
+ } else {
+ scratch8 |= SDHCI_VDD2_POWER_ON | SDHCI_VDD2_POWER_180;
+ }
+
+ sdhci_writeb(host, scratch8, SDHCI_POWER_CONTROL);
+
+ /* UnLock WP */
+ pci_read_config_byte(chip->pdev, O2_SD_LOCK_WP, &scratch8);
+ scratch8 &= 0x7f;
+ pci_write_config_byte(chip->pdev, O2_SD_LOCK_WP, scratch8);
+
+ /* Wait for express card clkreqn assert */
+ ret = read_poll_timeout(sdhci_readb, scratch8, !(scratch8 & BIT(0)),
+ 1, 30000, false, host, O2_SD_EXP_INT_REG);
+
+ if (!ret) {
+ /* Switch to PCIe mode */
+ scratch16 = sdhci_readw(host, O2_SD_PCIE_SWITCH);
+ scratch16 |= BIT(8);
+ sdhci_writew(host, scratch16, O2_SD_PCIE_SWITCH);
+ } else {
+ /* Power off VDD2 voltage*/
+ scratch8 = sdhci_readb(host, SDHCI_POWER_CONTROL);
+ scratch8 &= 0x0F;
+ sdhci_writeb(host, scratch8, SDHCI_POWER_CONTROL);
+
+ /* Keep mode as UHSI */
+ pci_read_config_word(chip->pdev, O2_SD_PARA_SET_REG1, &scratch16);
+ scratch16 &= ~BIT(11);
+ pci_write_config_word(chip->pdev, O2_SD_PARA_SET_REG1, scratch16);
+
+ host->mmc->ios.timing = MMC_TIMING_LEGACY;
+ pr_info("%s: Express card initialization failed, falling back to Legacy\n",
+ mmc_hostname(host->mmc));
+ }
+ /* Lock WP */
+ pci_read_config_byte(chip->pdev, O2_SD_LOCK_WP, &scratch8);
+ scratch8 |= 0x80;
+ pci_write_config_byte(chip->pdev, O2_SD_LOCK_WP, scratch8);
+
+ return 0;
+}
+
static int sdhci_pci_o2_probe_slot(struct sdhci_pci_slot *slot)
{
struct sdhci_pci_chip *chip;
@@ -624,6 +714,11 @@ static int sdhci_pci_o2_probe_slot(struct sdhci_pci_slot *slot)
if (caps & SDHCI_CAN_DO_8BIT)
host->mmc->caps |= MMC_CAP_8_BIT_DATA;
+ host->quirks2 |= SDHCI_QUIRK2_BROKEN_DDR50;
+
+ sdhci_pci_o2_enable_msi(chip, host);
+
+ host->mmc_host_ops.execute_tuning = sdhci_o2_execute_tuning;
switch (chip->pdev->device) {
case PCI_DEVICE_ID_O2_SDS0:
case PCI_DEVICE_ID_O2_SEABIRD0:
@@ -634,10 +729,6 @@ static int sdhci_pci_o2_probe_slot(struct sdhci_pci_slot *slot)
if (reg & 0x1)
host->quirks |= SDHCI_QUIRK_MULTIBLOCK_READ_ACMD12;
- host->quirks2 |= SDHCI_QUIRK2_BROKEN_DDR50;
-
- sdhci_pci_o2_enable_msi(chip, host);
-
if (chip->pdev->device == PCI_DEVICE_ID_O2_SEABIRD0) {
ret = pci_read_config_dword(chip->pdev,
O2_SD_MISC_SETTING, &reg);
@@ -663,15 +754,22 @@ static int sdhci_pci_o2_probe_slot(struct sdhci_pci_slot *slot)
host->quirks2 |= SDHCI_QUIRK2_PRESET_VALUE_BROKEN;
}
- host->mmc_host_ops.execute_tuning = sdhci_o2_execute_tuning;
-
if (chip->pdev->device != PCI_DEVICE_ID_O2_FUJIN2)
break;
/* set dll watch dog timer */
reg = sdhci_readl(host, O2_SD_VENDOR_SETTING2);
reg |= (1 << 12);
sdhci_writel(host, reg, O2_SD_VENDOR_SETTING2);
-
+ break;
+ case PCI_DEVICE_ID_O2_GG8_9860:
+ case PCI_DEVICE_ID_O2_GG8_9861:
+ case PCI_DEVICE_ID_O2_GG8_9862:
+ case PCI_DEVICE_ID_O2_GG8_9863:
+ host->mmc->caps2 |= MMC_CAP2_NO_SDIO | MMC_CAP2_SD_EXP | MMC_CAP2_SD_EXP_1_2V;
+ host->mmc->caps |= MMC_CAP_HW_RESET;
+ host->quirks2 |= SDHCI_QUIRK2_PRESET_VALUE_BROKEN;
+ slot->host->mmc_host_ops.get_cd = sdhci_o2_get_cd;
+ host->mmc_host_ops.init_sd_express = sdhci_pci_o2_init_sd_express;
break;
default:
break;
@@ -684,6 +782,7 @@ static int sdhci_pci_o2_probe(struct sdhci_pci_chip *chip)
{
int ret;
u8 scratch;
+ u16 scratch16;
u32 scratch_32;
switch (chip->pdev->device) {
@@ -893,6 +992,46 @@ static int sdhci_pci_o2_probe(struct sdhci_pci_chip *chip)
scratch |= 0x80;
pci_write_config_byte(chip->pdev, O2_SD_LOCK_WP, scratch);
break;
+ case PCI_DEVICE_ID_O2_GG8_9860:
+ case PCI_DEVICE_ID_O2_GG8_9861:
+ case PCI_DEVICE_ID_O2_GG8_9862:
+ case PCI_DEVICE_ID_O2_GG8_9863:
+ /* UnLock WP */
+ ret = pci_read_config_byte(chip->pdev, O2_SD_LOCK_WP, &scratch);
+ if (ret)
+ return ret;
+ scratch &= 0x7f;
+ pci_write_config_byte(chip->pdev, O2_SD_LOCK_WP, scratch);
+
+ /* Select mode switch source as software control */
+ pci_read_config_word(chip->pdev, O2_SD_PARA_SET_REG1, &scratch16);
+ scratch16 &= 0xF8FF;
+ scratch16 |= BIT(9);
+ pci_write_config_word(chip->pdev, O2_SD_PARA_SET_REG1, scratch16);
+
+ /* set VDD1 supply source */
+ pci_read_config_word(chip->pdev, O2_SD_VDDX_CTRL_REG, &scratch16);
+ scratch16 &= 0xFFE3;
+ scratch16 |= BIT(3);
+ pci_write_config_word(chip->pdev, O2_SD_VDDX_CTRL_REG, scratch16);
+
+ /* Set host drive strength*/
+ scratch16 = 0x0025;
+ pci_write_config_word(chip->pdev, O2_SD_PLL_SETTING, scratch16);
+
+ /* Set output delay*/
+ pci_read_config_dword(chip->pdev, O2_SD_OUTPUT_CLK_SOURCE_SWITCH, &scratch_32);
+ scratch_32 &= 0xFF0FFF00;
+ scratch_32 |= 0x00B0003B;
+ pci_write_config_dword(chip->pdev, O2_SD_OUTPUT_CLK_SOURCE_SWITCH, scratch_32);
+
+ /* Lock WP */
+ ret = pci_read_config_byte(chip->pdev, O2_SD_LOCK_WP, &scratch);
+ if (ret)
+ return ret;
+ scratch |= 0x80;
+ pci_write_config_byte(chip->pdev, O2_SD_LOCK_WP, scratch);
+ break;
}
return 0;
diff --git a/drivers/mmc/host/sdhci-pci.h b/drivers/mmc/host/sdhci-pci.h
index 9c8863956381..153704f812ed 100644
--- a/drivers/mmc/host/sdhci-pci.h
+++ b/drivers/mmc/host/sdhci-pci.h
@@ -11,6 +11,10 @@
#define PCI_DEVICE_ID_O2_FUJIN2 0x8520
#define PCI_DEVICE_ID_O2_SEABIRD0 0x8620
#define PCI_DEVICE_ID_O2_SEABIRD1 0x8621
+#define PCI_DEVICE_ID_O2_GG8_9860 0x9860
+#define PCI_DEVICE_ID_O2_GG8_9861 0x9861
+#define PCI_DEVICE_ID_O2_GG8_9862 0x9862
+#define PCI_DEVICE_ID_O2_GG8_9863 0x9863
#define PCI_DEVICE_ID_INTEL_PCH_SDIO0 0x8809
#define PCI_DEVICE_ID_INTEL_PCH_SDIO1 0x880a
diff --git a/drivers/mmc/host/sdhci-pic32.c b/drivers/mmc/host/sdhci-pic32.c
index 6696b6bdd88e..7a0351a9c74e 100644
--- a/drivers/mmc/host/sdhci-pic32.c
+++ b/drivers/mmc/host/sdhci-pic32.c
@@ -210,7 +210,7 @@ err:
return ret;
}
-static int pic32_sdhci_remove(struct platform_device *pdev)
+static void pic32_sdhci_remove(struct platform_device *pdev)
{
struct sdhci_host *host = platform_get_drvdata(pdev);
struct pic32_sdhci_priv *sdhci_pdata = sdhci_priv(host);
@@ -221,8 +221,6 @@ static int pic32_sdhci_remove(struct platform_device *pdev)
clk_disable_unprepare(sdhci_pdata->base_clk);
clk_disable_unprepare(sdhci_pdata->sys_clk);
sdhci_pltfm_free(pdev);
-
- return 0;
}
static const struct of_device_id pic32_sdhci_id_table[] = {
@@ -238,7 +236,7 @@ static struct platform_driver pic32_sdhci_driver = {
.of_match_table = of_match_ptr(pic32_sdhci_id_table),
},
.probe = pic32_sdhci_probe,
- .remove = pic32_sdhci_remove,
+ .remove_new = pic32_sdhci_remove,
};
module_platform_driver(pic32_sdhci_driver);
diff --git a/drivers/mmc/host/sdhci-pltfm.c b/drivers/mmc/host/sdhci-pltfm.c
index 673e750a8490..a72e123a585d 100644
--- a/drivers/mmc/host/sdhci-pltfm.c
+++ b/drivers/mmc/host/sdhci-pltfm.c
@@ -166,9 +166,9 @@ void sdhci_pltfm_free(struct platform_device *pdev)
}
EXPORT_SYMBOL_GPL(sdhci_pltfm_free);
-int sdhci_pltfm_register(struct platform_device *pdev,
- const struct sdhci_pltfm_data *pdata,
- size_t priv_size)
+int sdhci_pltfm_init_and_add_host(struct platform_device *pdev,
+ const struct sdhci_pltfm_data *pdata,
+ size_t priv_size)
{
struct sdhci_host *host;
int ret = 0;
@@ -185,21 +185,17 @@ int sdhci_pltfm_register(struct platform_device *pdev,
return ret;
}
-EXPORT_SYMBOL_GPL(sdhci_pltfm_register);
+EXPORT_SYMBOL_GPL(sdhci_pltfm_init_and_add_host);
-int sdhci_pltfm_unregister(struct platform_device *pdev)
+void sdhci_pltfm_remove(struct platform_device *pdev)
{
struct sdhci_host *host = platform_get_drvdata(pdev);
- struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
int dead = (readl(host->ioaddr + SDHCI_INT_STATUS) == 0xffffffff);
sdhci_remove_host(host, dead);
- clk_disable_unprepare(pltfm_host->clk);
sdhci_pltfm_free(pdev);
-
- return 0;
}
-EXPORT_SYMBOL_GPL(sdhci_pltfm_unregister);
+EXPORT_SYMBOL_GPL(sdhci_pltfm_remove);
#ifdef CONFIG_PM_SLEEP
int sdhci_pltfm_suspend(struct device *dev)
diff --git a/drivers/mmc/host/sdhci-pltfm.h b/drivers/mmc/host/sdhci-pltfm.h
index 9bd717ff784b..b81d5b0fd616 100644
--- a/drivers/mmc/host/sdhci-pltfm.h
+++ b/drivers/mmc/host/sdhci-pltfm.h
@@ -99,10 +99,10 @@ extern struct sdhci_host *sdhci_pltfm_init(struct platform_device *pdev,
size_t priv_size);
extern void sdhci_pltfm_free(struct platform_device *pdev);
-extern int sdhci_pltfm_register(struct platform_device *pdev,
- const struct sdhci_pltfm_data *pdata,
- size_t priv_size);
-extern int sdhci_pltfm_unregister(struct platform_device *pdev);
+extern int sdhci_pltfm_init_and_add_host(struct platform_device *pdev,
+ const struct sdhci_pltfm_data *pdata,
+ size_t priv_size);
+extern void sdhci_pltfm_remove(struct platform_device *pdev);
extern unsigned int sdhci_pltfm_clk_get_max_clock(struct sdhci_host *host);
diff --git a/drivers/mmc/host/sdhci-pxav2.c b/drivers/mmc/host/sdhci-pxav2.c
index 91aca8f8d6ef..b75cbea88b40 100644
--- a/drivers/mmc/host/sdhci-pxav2.c
+++ b/drivers/mmc/host/sdhci-pxav2.c
@@ -19,7 +19,6 @@
#include <linux/platform_data/pxa_sdhci.h>
#include <linux/slab.h>
#include <linux/of.h>
-#include <linux/of_device.h>
#include <linux/mmc/sdio.h>
#include <linux/mmc/mmc.h>
#include <linux/pinctrl/consumer.h>
@@ -269,26 +268,21 @@ static int sdhci_pxav2_probe(struct platform_device *pdev)
pltfm_host = sdhci_priv(host);
pxav2_host = sdhci_pltfm_priv(pltfm_host);
- clk = devm_clk_get(dev, "io");
- if (IS_ERR(clk) && PTR_ERR(clk) != -EPROBE_DEFER)
- clk = devm_clk_get(dev, NULL);
+ clk = devm_clk_get_optional_enabled(dev, "io");
+ if (!clk)
+ clk = devm_clk_get_enabled(dev, NULL);
if (IS_ERR(clk)) {
ret = PTR_ERR(clk);
dev_err_probe(dev, ret, "failed to get io clock\n");
goto free;
}
pltfm_host->clk = clk;
- ret = clk_prepare_enable(clk);
- if (ret) {
- dev_err(dev, "failed to enable io clock\n");
- goto free;
- }
clk_core = devm_clk_get_optional_enabled(dev, "core");
if (IS_ERR(clk_core)) {
ret = PTR_ERR(clk_core);
dev_err_probe(dev, ret, "failed to enable core clock\n");
- goto disable_clk;
+ goto free;
}
host->quirks = SDHCI_QUIRK_BROKEN_ADMA
@@ -340,12 +334,10 @@ static int sdhci_pxav2_probe(struct platform_device *pdev)
ret = sdhci_add_host(host);
if (ret)
- goto disable_clk;
+ goto free;
return 0;
-disable_clk:
- clk_disable_unprepare(clk);
free:
sdhci_pltfm_free(pdev);
return ret;
@@ -359,7 +351,7 @@ static struct platform_driver sdhci_pxav2_driver = {
.pm = &sdhci_pltfm_pmops,
},
.probe = sdhci_pxav2_probe,
- .remove = sdhci_pltfm_unregister,
+ .remove_new = sdhci_pltfm_remove,
};
module_platform_driver(sdhci_pxav2_driver);
diff --git a/drivers/mmc/host/sdhci-pxav3.c b/drivers/mmc/host/sdhci-pxav3.c
index e39dcc998772..3af43ac05825 100644
--- a/drivers/mmc/host/sdhci-pxav3.c
+++ b/drivers/mmc/host/sdhci-pxav3.c
@@ -470,7 +470,7 @@ err_clk_get:
return ret;
}
-static int sdhci_pxav3_remove(struct platform_device *pdev)
+static void sdhci_pxav3_remove(struct platform_device *pdev)
{
struct sdhci_host *host = platform_get_drvdata(pdev);
struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
@@ -486,8 +486,6 @@ static int sdhci_pxav3_remove(struct platform_device *pdev)
clk_disable_unprepare(pxa->clk_core);
sdhci_pltfm_free(pdev);
-
- return 0;
}
#ifdef CONFIG_PM_SLEEP
@@ -570,7 +568,7 @@ static struct platform_driver sdhci_pxav3_driver = {
.pm = &sdhci_pxav3_pmops,
},
.probe = sdhci_pxav3_probe,
- .remove = sdhci_pxav3_remove,
+ .remove_new = sdhci_pxav3_remove,
};
module_platform_driver(sdhci_pxav3_driver);
diff --git a/drivers/mmc/host/sdhci-s3c.c b/drivers/mmc/host/sdhci-s3c.c
index 504015e84308..0e8a8ac14e56 100644
--- a/drivers/mmc/host/sdhci-s3c.c
+++ b/drivers/mmc/host/sdhci-s3c.c
@@ -20,7 +20,6 @@
#include <linux/gpio.h>
#include <linux/module.h>
#include <linux/of.h>
-#include <linux/of_device.h>
#include <linux/of_gpio.h>
#include <linux/pm.h>
#include <linux/pm_runtime.h>
@@ -668,7 +667,7 @@ static int sdhci_s3c_probe(struct platform_device *pdev)
return ret;
}
-static int sdhci_s3c_remove(struct platform_device *pdev)
+static void sdhci_s3c_remove(struct platform_device *pdev)
{
struct sdhci_host *host = platform_get_drvdata(pdev);
struct sdhci_s3c *sc = sdhci_priv(host);
@@ -688,8 +687,6 @@ static int sdhci_s3c_remove(struct platform_device *pdev)
clk_disable_unprepare(sc->clk_io);
sdhci_free_host(host);
-
- return 0;
}
#ifdef CONFIG_PM_SLEEP
@@ -776,7 +773,7 @@ MODULE_DEVICE_TABLE(of, sdhci_s3c_dt_match);
static struct platform_driver sdhci_s3c_driver = {
.probe = sdhci_s3c_probe,
- .remove = sdhci_s3c_remove,
+ .remove_new = sdhci_s3c_remove,
.id_table = sdhci_s3c_driver_ids,
.driver = {
.name = "s3c-sdhci",
diff --git a/drivers/mmc/host/sdhci-spear.c b/drivers/mmc/host/sdhci-spear.c
index c79035727b20..c81bdfa97b89 100644
--- a/drivers/mmc/host/sdhci-spear.c
+++ b/drivers/mmc/host/sdhci-spear.c
@@ -117,7 +117,7 @@ err:
return ret;
}
-static int sdhci_remove(struct platform_device *pdev)
+static void sdhci_remove(struct platform_device *pdev)
{
struct sdhci_host *host = platform_get_drvdata(pdev);
struct spear_sdhci *sdhci = sdhci_priv(host);
@@ -131,8 +131,6 @@ static int sdhci_remove(struct platform_device *pdev)
sdhci_remove_host(host, dead);
clk_disable_unprepare(sdhci->clk);
sdhci_free_host(host);
-
- return 0;
}
#ifdef CONFIG_PM_SLEEP
@@ -170,23 +168,21 @@ static int sdhci_resume(struct device *dev)
static SIMPLE_DEV_PM_OPS(sdhci_pm_ops, sdhci_suspend, sdhci_resume);
-#ifdef CONFIG_OF
static const struct of_device_id sdhci_spear_id_table[] = {
{ .compatible = "st,spear300-sdhci" },
{}
};
MODULE_DEVICE_TABLE(of, sdhci_spear_id_table);
-#endif
static struct platform_driver sdhci_driver = {
.driver = {
.name = "sdhci",
.probe_type = PROBE_PREFER_ASYNCHRONOUS,
.pm = &sdhci_pm_ops,
- .of_match_table = of_match_ptr(sdhci_spear_id_table),
+ .of_match_table = sdhci_spear_id_table,
},
.probe = sdhci_probe,
- .remove = sdhci_remove,
+ .remove_new = sdhci_remove,
};
module_platform_driver(sdhci_driver);
diff --git a/drivers/mmc/host/sdhci-sprd.c b/drivers/mmc/host/sdhci-sprd.c
index 7f4ee2e12735..649ae075e229 100644
--- a/drivers/mmc/host/sdhci-sprd.c
+++ b/drivers/mmc/host/sdhci-sprd.c
@@ -9,9 +9,10 @@
#include <linux/dma-mapping.h>
#include <linux/highmem.h>
#include <linux/iopoll.h>
+#include <linux/mmc/host.h>
+#include <linux/mmc/mmc.h>
#include <linux/module.h>
#include <linux/of.h>
-#include <linux/of_device.h>
#include <linux/of_gpio.h>
#include <linux/pinctrl/consumer.h>
#include <linux/platform_device.h>
@@ -73,6 +74,11 @@
#define SDHCI_SPRD_CLK_DEF_RATE 26000000
#define SDHCI_SPRD_PHY_DLL_CLK 52000000
+#define SDHCI_SPRD_MAX_RANGE 0xff
+#define SDHCI_SPRD_CMD_DLY_MASK GENMASK(15, 8)
+#define SDHCI_SPRD_POSRD_DLY_MASK GENMASK(23, 16)
+#define SDHCI_SPRD_CPST_EN GENMASK(27, 24)
+
struct sdhci_sprd_host {
u32 version;
struct clk *clk_sdio;
@@ -86,6 +92,11 @@ struct sdhci_sprd_host {
u32 phy_delay[MMC_TIMING_MMC_HS400 + 2];
};
+enum sdhci_sprd_tuning_type {
+ SDHCI_SPRD_TUNING_SD_HS_CMD,
+ SDHCI_SPRD_TUNING_SD_HS_DATA,
+};
+
struct sdhci_sprd_phy_cfg {
const char *property;
u8 timing;
@@ -533,6 +544,138 @@ static void sdhci_sprd_hs400_enhanced_strobe(struct mmc_host *mmc,
SDHCI_SPRD_REG_32_DLL_DLY);
}
+static int mmc_send_tuning_cmd(struct mmc_card *card)
+{
+ return mmc_send_status(card, NULL);
+}
+
+static int mmc_send_tuning_data(struct mmc_card *card)
+{
+ u8 *status;
+ int ret;
+
+ status = kmalloc(64, GFP_KERNEL);
+ if (!status)
+ return -ENOMEM;
+
+ ret = mmc_sd_switch(card, 0, 0, 0, status);
+
+ kfree(status);
+
+ return ret;
+}
+
+static int sdhci_sprd_get_best_clk_sample(struct mmc_host *mmc, u8 *value)
+{
+ int range_end = SDHCI_SPRD_MAX_RANGE;
+ int range_length = 0;
+ int middle_range = 0;
+ int count = 0;
+ int i;
+
+ for (i = 0; i <= SDHCI_SPRD_MAX_RANGE; i++) {
+ if (value[i]) {
+ pr_debug("%s: tuning ok: %d\n", mmc_hostname(mmc), i);
+ count++;
+ } else {
+ pr_debug("%s: tuning fail: %d\n", mmc_hostname(mmc), i);
+ if (range_length < count) {
+ range_length = count;
+ range_end = i - 1;
+ count = 0;
+ }
+ }
+ }
+
+ if (!count)
+ return -EIO;
+
+ if (count > range_length) {
+ range_length = count;
+ range_end = i - 1;
+ }
+
+ middle_range = range_end - (range_length - 1) / 2;
+
+ return middle_range;
+}
+
+static int sdhci_sprd_tuning(struct mmc_host *mmc, struct mmc_card *card,
+ enum sdhci_sprd_tuning_type type)
+{
+ struct sdhci_host *host = mmc_priv(mmc);
+ struct sdhci_sprd_host *sprd_host = TO_SPRD_HOST(host);
+ u32 *p = sprd_host->phy_delay;
+ u32 dll_cfg, dll_dly;
+ int best_clk_sample;
+ int err = 0;
+ u8 *value;
+ int i;
+
+ value = kmalloc(SDHCI_SPRD_MAX_RANGE + 1, GFP_KERNEL);
+ if (!value)
+ return -ENOMEM;
+
+ sdhci_reset(host, SDHCI_RESET_CMD | SDHCI_RESET_DATA);
+
+ dll_cfg = sdhci_readl(host, SDHCI_SPRD_REG_32_DLL_CFG);
+ dll_cfg &= ~SDHCI_SPRD_CPST_EN;
+ sdhci_writel(host, dll_cfg, SDHCI_SPRD_REG_32_DLL_CFG);
+
+ dll_dly = p[mmc->ios.timing];
+
+ for (i = 0; i <= SDHCI_SPRD_MAX_RANGE; i++) {
+ if (type == SDHCI_SPRD_TUNING_SD_HS_CMD) {
+ dll_dly &= ~SDHCI_SPRD_CMD_DLY_MASK;
+ dll_dly |= ((i << 8) & SDHCI_SPRD_CMD_DLY_MASK);
+ } else {
+ dll_dly &= ~SDHCI_SPRD_POSRD_DLY_MASK;
+ dll_dly |= ((i << 16) & SDHCI_SPRD_POSRD_DLY_MASK);
+ }
+
+ sdhci_writel(host, dll_dly, SDHCI_SPRD_REG_32_DLL_DLY);
+
+ if (type == SDHCI_SPRD_TUNING_SD_HS_CMD)
+ value[i] = !mmc_send_tuning_cmd(card);
+ else
+ value[i] = !mmc_send_tuning_data(card);
+ }
+
+ best_clk_sample = sdhci_sprd_get_best_clk_sample(mmc, value);
+ if (best_clk_sample < 0) {
+ dev_err(mmc_dev(host->mmc), "all tuning phase fail!\n");
+ goto out;
+ }
+
+ if (type == SDHCI_SPRD_TUNING_SD_HS_CMD) {
+ p[mmc->ios.timing] &= ~SDHCI_SPRD_CMD_DLY_MASK;
+ p[mmc->ios.timing] |= ((best_clk_sample << 8) & SDHCI_SPRD_CMD_DLY_MASK);
+ } else {
+ p[mmc->ios.timing] &= ~(SDHCI_SPRD_POSRD_DLY_MASK);
+ p[mmc->ios.timing] |= ((best_clk_sample << 16) & SDHCI_SPRD_POSRD_DLY_MASK);
+ }
+
+ pr_debug("%s: the best clk sample %d, delay value 0x%08x\n",
+ mmc_hostname(host->mmc), best_clk_sample, p[mmc->ios.timing]);
+
+out:
+ sdhci_writel(host, p[mmc->ios.timing], SDHCI_SPRD_REG_32_DLL_DLY);
+
+ kfree(value);
+
+ return err;
+}
+
+static int sdhci_sprd_prepare_sd_hs_cmd_tuning(struct mmc_host *mmc, struct mmc_card *card)
+{
+ return sdhci_sprd_tuning(mmc, card, SDHCI_SPRD_TUNING_SD_HS_CMD);
+}
+
+static int sdhci_sprd_execute_sd_hs_data_tuning(struct mmc_host *mmc, struct mmc_card *card)
+{
+ return sdhci_sprd_tuning(mmc, card, SDHCI_SPRD_TUNING_SD_HS_DATA);
+}
+
static void sdhci_sprd_phy_param_parse(struct sdhci_sprd_host *sprd_host,
struct device_node *np)
{
@@ -577,6 +720,11 @@ static int sdhci_sprd_probe(struct platform_device *pdev)
host->mmc_host_ops.request = sdhci_sprd_request;
host->mmc_host_ops.hs400_enhanced_strobe =
sdhci_sprd_hs400_enhanced_strobe;
+ host->mmc_host_ops.prepare_sd_hs_tuning =
+ sdhci_sprd_prepare_sd_hs_cmd_tuning;
+ host->mmc_host_ops.execute_sd_hs_tuning =
+ sdhci_sprd_execute_sd_hs_data_tuning;
+
/*
* We can not use the standard ops to change and detect the voltage
* signal for Spreadtrum SD host controller, since our voltage regulator
@@ -720,7 +868,7 @@ pltfm_free:
return ret;
}
-static int sdhci_sprd_remove(struct platform_device *pdev)
+static void sdhci_sprd_remove(struct platform_device *pdev)
{
struct sdhci_host *host = platform_get_drvdata(pdev);
struct sdhci_sprd_host *sprd_host = TO_SPRD_HOST(host);
@@ -732,8 +880,6 @@ static int sdhci_sprd_remove(struct platform_device *pdev)
clk_disable_unprepare(sprd_host->clk_2x_enable);
sdhci_pltfm_free(pdev);
-
- return 0;
}
static const struct of_device_id sdhci_sprd_of_match[] = {
@@ -800,7 +946,7 @@ static const struct dev_pm_ops sdhci_sprd_pm_ops = {
static struct platform_driver sdhci_sprd_driver = {
.probe = sdhci_sprd_probe,
- .remove = sdhci_sprd_remove,
+ .remove_new = sdhci_sprd_remove,
.driver = {
.name = "sdhci_sprd_r11",
.probe_type = PROBE_PREFER_ASYNCHRONOUS,
diff --git a/drivers/mmc/host/sdhci-st.c b/drivers/mmc/host/sdhci-st.c
index 6415916fbd91..d12532b96b51 100644
--- a/drivers/mmc/host/sdhci-st.c
+++ b/drivers/mmc/host/sdhci-st.c
@@ -348,7 +348,6 @@ static int sdhci_st_probe(struct platform_device *pdev)
struct clk *clk, *icnclk;
int ret = 0;
u16 host_version;
- struct resource *res;
struct reset_control *rstc;
clk = devm_clk_get(&pdev->dev, "mmc");
@@ -397,9 +396,7 @@ static int sdhci_st_probe(struct platform_device *pdev)
}
/* Configure the FlashSS Top registers for setting eMMC TX/RX delay */
- res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
- "top-mmc-delay");
- pdata->top_ioaddr = devm_ioremap_resource(&pdev->dev, res);
+ pdata->top_ioaddr = devm_platform_ioremap_resource_byname(pdev, "top-mmc-delay");
if (IS_ERR(pdata->top_ioaddr))
pdata->top_ioaddr = NULL;
@@ -434,20 +431,20 @@ err_pltfm_init:
return ret;
}
-static int sdhci_st_remove(struct platform_device *pdev)
+static void sdhci_st_remove(struct platform_device *pdev)
{
struct sdhci_host *host = platform_get_drvdata(pdev);
struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
struct st_mmc_platform_data *pdata = sdhci_pltfm_priv(pltfm_host);
struct reset_control *rstc = pdata->rstc;
+ struct clk *clk = pltfm_host->clk;
- sdhci_pltfm_unregister(pdev);
+ sdhci_pltfm_remove(pdev);
clk_disable_unprepare(pdata->icnclk);
+ clk_disable_unprepare(clk);
reset_control_assert(rstc);
-
- return 0;
}
#ifdef CONFIG_PM_SLEEP
@@ -510,7 +507,7 @@ MODULE_DEVICE_TABLE(of, st_sdhci_match);
static struct platform_driver sdhci_st_driver = {
.probe = sdhci_st_probe,
- .remove = sdhci_st_remove,
+ .remove_new = sdhci_st_remove,
.driver = {
.name = "sdhci-st",
.probe_type = PROBE_PREFER_ASYNCHRONOUS,
diff --git a/drivers/mmc/host/sdhci-tegra.c b/drivers/mmc/host/sdhci-tegra.c
index bff084f178c9..1ad0a6b3a2eb 100644
--- a/drivers/mmc/host/sdhci-tegra.c
+++ b/drivers/mmc/host/sdhci-tegra.c
@@ -19,7 +19,6 @@
#include <linux/mmc/mmc.h>
#include <linux/mmc/slot-gpio.h>
#include <linux/module.h>
-#include <linux/of_device.h>
#include <linux/of.h>
#include <linux/pinctrl/consumer.h>
#include <linux/platform_device.h>
@@ -1818,7 +1817,7 @@ err_parse_dt:
return rc;
}
-static int sdhci_tegra_remove(struct platform_device *pdev)
+static void sdhci_tegra_remove(struct platform_device *pdev)
{
struct sdhci_host *host = platform_get_drvdata(pdev);
struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
@@ -1834,8 +1833,6 @@ static int sdhci_tegra_remove(struct platform_device *pdev)
clk_disable_unprepare(tegra_host->tmclk);
sdhci_pltfm_free(pdev);
-
- return 0;
}
static int __maybe_unused sdhci_tegra_runtime_suspend(struct device *dev)
@@ -1933,7 +1930,7 @@ static struct platform_driver sdhci_tegra_driver = {
.pm = &sdhci_tegra_dev_pm_ops,
},
.probe = sdhci_tegra_probe,
- .remove = sdhci_tegra_remove,
+ .remove_new = sdhci_tegra_remove,
};
module_platform_driver(sdhci_tegra_driver);
diff --git a/drivers/mmc/host/sdhci-xenon.c b/drivers/mmc/host/sdhci-xenon.c
index 08e838400b52..25ba7aecc3be 100644
--- a/drivers/mmc/host/sdhci-xenon.c
+++ b/drivers/mmc/host/sdhci-xenon.c
@@ -578,7 +578,7 @@ free_pltfm:
return err;
}
-static int xenon_remove(struct platform_device *pdev)
+static void xenon_remove(struct platform_device *pdev)
{
struct sdhci_host *host = platform_get_drvdata(pdev);
struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
@@ -595,8 +595,6 @@ static int xenon_remove(struct platform_device *pdev)
clk_disable_unprepare(pltfm_host->clk);
sdhci_pltfm_free(pdev);
-
- return 0;
}
#ifdef CONFIG_PM_SLEEP
@@ -705,7 +703,7 @@ static struct platform_driver sdhci_xenon_driver = {
.pm = &sdhci_xenon_dev_pm_ops,
},
.probe = xenon_probe,
- .remove = xenon_remove,
+ .remove_new = xenon_remove,
};
module_platform_driver(sdhci_xenon_driver);
diff --git a/drivers/mmc/host/sdhci_am654.c b/drivers/mmc/host/sdhci_am654.c
index 7cdf0f54e3a5..c125485ba80e 100644
--- a/drivers/mmc/host/sdhci_am654.c
+++ b/drivers/mmc/host/sdhci_am654.c
@@ -866,22 +866,22 @@ err_pltfm_free:
return ret;
}
-static int sdhci_am654_remove(struct platform_device *pdev)
+static void sdhci_am654_remove(struct platform_device *pdev)
{
struct sdhci_host *host = platform_get_drvdata(pdev);
struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+ struct device *dev = &pdev->dev;
int ret;
- ret = pm_runtime_resume_and_get(&pdev->dev);
+ ret = pm_runtime_get_sync(dev);
if (ret < 0)
- return ret;
+ dev_err(dev, "pm_runtime_get_sync() Failed\n");
sdhci_remove_host(host, true);
clk_disable_unprepare(pltfm_host->clk);
- pm_runtime_disable(&pdev->dev);
- pm_runtime_put_noidle(&pdev->dev);
+ pm_runtime_disable(dev);
+ pm_runtime_put_noidle(dev);
sdhci_pltfm_free(pdev);
- return 0;
}
#ifdef CONFIG_PM
@@ -993,7 +993,7 @@ static struct platform_driver sdhci_am654_driver = {
.of_match_table = sdhci_am654_of_match,
},
.probe = sdhci_am654_probe,
- .remove = sdhci_am654_remove,
+ .remove_new = sdhci_am654_remove,
};
module_platform_driver(sdhci_am654_driver);
diff --git a/drivers/mmc/host/sdhci_f_sdh30.c b/drivers/mmc/host/sdhci_f_sdh30.c
index a202a69a4b08..c58e7cb1e2a7 100644
--- a/drivers/mmc/host/sdhci_f_sdh30.c
+++ b/drivers/mmc/host/sdhci_f_sdh30.c
@@ -29,9 +29,16 @@ struct f_sdhost_priv {
bool enable_cmd_dat_delay;
};
+static void *sdhci_f_sdhost_priv(struct sdhci_host *host)
+{
+ struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+
+ return sdhci_pltfm_priv(pltfm_host);
+}
+
static void sdhci_f_sdh30_soft_voltage_switch(struct sdhci_host *host)
{
- struct f_sdhost_priv *priv = sdhci_priv(host);
+ struct f_sdhost_priv *priv = sdhci_f_sdhost_priv(host);
u32 ctrl = 0;
usleep_range(2500, 3000);
@@ -64,7 +71,7 @@ static unsigned int sdhci_f_sdh30_get_min_clock(struct sdhci_host *host)
static void sdhci_f_sdh30_reset(struct sdhci_host *host, u8 mask)
{
- struct f_sdhost_priv *priv = sdhci_priv(host);
+ struct f_sdhost_priv *priv = sdhci_f_sdhost_priv(host);
u32 ctl;
if (sdhci_readw(host, SDHCI_CLOCK_CONTROL) == 0)
@@ -95,30 +102,32 @@ static const struct sdhci_ops sdhci_f_sdh30_ops = {
.set_uhs_signaling = sdhci_set_uhs_signaling,
};
+static const struct sdhci_pltfm_data sdhci_f_sdh30_pltfm_data = {
+ .ops = &sdhci_f_sdh30_ops,
+ .quirks = SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC
+ | SDHCI_QUIRK_INVERTED_WRITE_PROTECT,
+ .quirks2 = SDHCI_QUIRK2_SUPPORT_SINGLE
+ | SDHCI_QUIRK2_TUNING_WORK_AROUND,
+};
+
static int sdhci_f_sdh30_probe(struct platform_device *pdev)
{
struct sdhci_host *host;
struct device *dev = &pdev->dev;
- int irq, ctrl = 0, ret = 0;
+ int ctrl = 0, ret = 0;
struct f_sdhost_priv *priv;
+ struct sdhci_pltfm_host *pltfm_host;
u32 reg = 0;
- irq = platform_get_irq(pdev, 0);
- if (irq < 0)
- return irq;
-
- host = sdhci_alloc_host(dev, sizeof(struct f_sdhost_priv));
+ host = sdhci_pltfm_init(pdev, &sdhci_f_sdh30_pltfm_data,
+ sizeof(struct f_sdhost_priv));
if (IS_ERR(host))
return PTR_ERR(host);
- priv = sdhci_priv(host);
+ pltfm_host = sdhci_priv(host);
+ priv = sdhci_pltfm_priv(pltfm_host);
priv->dev = dev;
- host->quirks = SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC |
- SDHCI_QUIRK_INVERTED_WRITE_PROTECT;
- host->quirks2 = SDHCI_QUIRK2_SUPPORT_SINGLE |
- SDHCI_QUIRK2_TUNING_WORK_AROUND;
-
priv->enable_cmd_dat_delay = device_property_read_bool(dev,
"fujitsu,cmd-dat-delay-select");
@@ -126,18 +135,6 @@ static int sdhci_f_sdh30_probe(struct platform_device *pdev)
if (ret)
goto err;
- platform_set_drvdata(pdev, host);
-
- host->hw_name = "f_sdh30";
- host->ops = &sdhci_f_sdh30_ops;
- host->irq = irq;
-
- host->ioaddr = devm_platform_ioremap_resource(pdev, 0);
- if (IS_ERR(host->ioaddr)) {
- ret = PTR_ERR(host->ioaddr);
- goto err;
- }
-
if (dev_of_node(dev)) {
sdhci_get_of_property(pdev);
@@ -204,26 +201,24 @@ err_rst:
err_clk:
clk_disable_unprepare(priv->clk_iface);
err:
- sdhci_free_host(host);
+ sdhci_pltfm_free(pdev);
+
return ret;
}
-static int sdhci_f_sdh30_remove(struct platform_device *pdev)
+static void sdhci_f_sdh30_remove(struct platform_device *pdev)
{
struct sdhci_host *host = platform_get_drvdata(pdev);
- struct f_sdhost_priv *priv = sdhci_priv(host);
-
- sdhci_remove_host(host, readl(host->ioaddr + SDHCI_INT_STATUS) ==
- 0xffffffff);
+ struct f_sdhost_priv *priv = sdhci_f_sdhost_priv(host);
+ struct clk *clk_iface = priv->clk_iface;
+ struct reset_control *rst = priv->rst;
+ struct clk *clk = priv->clk;
- reset_control_assert(priv->rst);
- clk_disable_unprepare(priv->clk);
- clk_disable_unprepare(priv->clk_iface);
+ sdhci_pltfm_remove(pdev);
- sdhci_free_host(host);
- platform_set_drvdata(pdev, NULL);
-
- return 0;
+ reset_control_assert(rst);
+ clk_disable_unprepare(clk);
+ clk_disable_unprepare(clk_iface);
}
#ifdef CONFIG_OF
@@ -251,8 +246,8 @@ static struct platform_driver sdhci_f_sdh30_driver = {
.acpi_match_table = ACPI_PTR(f_sdh30_acpi_ids),
.pm = &sdhci_pltfm_pmops,
},
- .probe = sdhci_f_sdh30_probe,
- .remove = sdhci_f_sdh30_remove,
+ .probe = sdhci_f_sdh30_probe,
+ .remove_new = sdhci_f_sdh30_remove,
};
module_platform_driver(sdhci_f_sdh30_driver);
diff --git a/drivers/mmc/host/sh_mmcif.c b/drivers/mmc/host/sh_mmcif.c
index 5cf53348372a..077d711e964e 100644
--- a/drivers/mmc/host/sh_mmcif.c
+++ b/drivers/mmc/host/sh_mmcif.c
@@ -46,7 +46,6 @@
#include <linux/mmc/slot-gpio.h>
#include <linux/mod_devicetable.h>
#include <linux/mutex.h>
-#include <linux/of_device.h>
#include <linux/pagemap.h>
#include <linux/platform_data/sh_mmcif.h>
#include <linux/platform_device.h>
@@ -1509,7 +1508,7 @@ err_host:
return ret;
}
-static int sh_mmcif_remove(struct platform_device *pdev)
+static void sh_mmcif_remove(struct platform_device *pdev)
{
struct sh_mmcif_host *host = platform_get_drvdata(pdev);
@@ -1533,8 +1532,6 @@ static int sh_mmcif_remove(struct platform_device *pdev)
mmc_free_host(host->mmc);
pm_runtime_put_sync(&pdev->dev);
pm_runtime_disable(&pdev->dev);
-
- return 0;
}
#ifdef CONFIG_PM_SLEEP
@@ -1561,7 +1558,7 @@ static const struct dev_pm_ops sh_mmcif_dev_pm_ops = {
static struct platform_driver sh_mmcif_driver = {
.probe = sh_mmcif_probe,
- .remove = sh_mmcif_remove,
+ .remove_new = sh_mmcif_remove,
.driver = {
.name = DRIVER_NAME,
.probe_type = PROBE_PREFER_ASYNCHRONOUS,
diff --git a/drivers/mmc/host/sunplus-mmc.c b/drivers/mmc/host/sunplus-mmc.c
index db5e0dcdfa7f..13c7cc0b6180 100644
--- a/drivers/mmc/host/sunplus-mmc.c
+++ b/drivers/mmc/host/sunplus-mmc.c
@@ -863,11 +863,9 @@ static int spmmc_drv_probe(struct platform_device *pdev)
struct spmmc_host *host;
int ret = 0;
- mmc = mmc_alloc_host(sizeof(*host), &pdev->dev);
- if (!mmc) {
- ret = -ENOMEM;
- goto probe_free_host;
- }
+ mmc = devm_mmc_alloc_host(&pdev->dev, sizeof(struct spmmc_host));
+ if (!mmc)
+ return -ENOMEM;
host = mmc_priv(mmc);
host->mmc = mmc;
@@ -887,7 +885,7 @@ static int spmmc_drv_probe(struct platform_device *pdev)
return dev_err_probe(&pdev->dev, PTR_ERR(host->rstc), "rst get fail\n");
host->irq = platform_get_irq(pdev, 0);
- if (host->irq <= 0)
+ if (host->irq < 0)
return host->irq;
ret = devm_request_threaded_irq(&pdev->dev, host->irq,
@@ -902,7 +900,7 @@ static int spmmc_drv_probe(struct platform_device *pdev)
ret = mmc_of_parse(mmc);
if (ret)
- goto probe_free_host;
+ goto clk_disable;
mmc->ops = &spmmc_ops;
mmc->f_min = SPMMC_MIN_CLK;
@@ -911,7 +909,7 @@ static int spmmc_drv_probe(struct platform_device *pdev)
ret = mmc_regulator_get_supply(mmc);
if (ret)
- goto probe_free_host;
+ goto clk_disable;
if (!mmc->ocr_avail)
mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34;
@@ -927,18 +925,21 @@ static int spmmc_drv_probe(struct platform_device *pdev)
host->tuning_info.enable_tuning = 1;
pm_runtime_set_active(&pdev->dev);
pm_runtime_enable(&pdev->dev);
- mmc_add_host(mmc);
+ ret = mmc_add_host(mmc);
+ if (ret)
+ goto pm_disable;
- return ret;
+ return 0;
-probe_free_host:
- if (mmc)
- mmc_free_host(mmc);
+pm_disable:
+ pm_runtime_disable(&pdev->dev);
+clk_disable:
+ clk_disable_unprepare(host->clk);
return ret;
}
-static int spmmc_drv_remove(struct platform_device *dev)
+static void spmmc_drv_remove(struct platform_device *dev)
{
struct spmmc_host *host = platform_get_drvdata(dev);
@@ -947,10 +948,6 @@ static int spmmc_drv_remove(struct platform_device *dev)
clk_disable_unprepare(host->clk);
pm_runtime_put_noidle(&dev->dev);
pm_runtime_disable(&dev->dev);
- platform_set_drvdata(dev, NULL);
- mmc_free_host(host->mmc);
-
- return 0;
}
static int spmmc_pm_runtime_suspend(struct device *dev)
@@ -985,7 +982,7 @@ MODULE_DEVICE_TABLE(of, spmmc_of_table);
static struct platform_driver spmmc_driver = {
.probe = spmmc_drv_probe,
- .remove = spmmc_drv_remove,
+ .remove_new = spmmc_drv_remove,
.driver = {
.name = "spmmc",
.pm = pm_ptr(&spmmc_pm_ops),
diff --git a/drivers/mmc/host/sunxi-mmc.c b/drivers/mmc/host/sunxi-mmc.c
index 69dcb8805e05..d3bd0ac99ec4 100644
--- a/drivers/mmc/host/sunxi-mmc.c
+++ b/drivers/mmc/host/sunxi-mmc.c
@@ -1486,7 +1486,7 @@ error_free_host:
return ret;
}
-static int sunxi_mmc_remove(struct platform_device *pdev)
+static void sunxi_mmc_remove(struct platform_device *pdev)
{
struct mmc_host *mmc = platform_get_drvdata(pdev);
struct sunxi_mmc_host *host = mmc_priv(mmc);
@@ -1499,8 +1499,6 @@ static int sunxi_mmc_remove(struct platform_device *pdev)
}
dma_free_coherent(&pdev->dev, PAGE_SIZE, host->sg_cpu, host->sg_dma);
mmc_free_host(mmc);
-
- return 0;
}
#ifdef CONFIG_PM
@@ -1556,7 +1554,7 @@ static struct platform_driver sunxi_mmc_driver = {
.pm = &sunxi_mmc_pm_ops,
},
.probe = sunxi_mmc_probe,
- .remove = sunxi_mmc_remove,
+ .remove_new = sunxi_mmc_remove,
};
module_platform_driver(sunxi_mmc_driver);
diff --git a/drivers/mmc/host/uniphier-sd.c b/drivers/mmc/host/uniphier-sd.c
index 61acd69fac0e..1404989e6151 100644
--- a/drivers/mmc/host/uniphier-sd.c
+++ b/drivers/mmc/host/uniphier-sd.c
@@ -13,7 +13,6 @@
#include <linux/mmc/host.h>
#include <linux/module.h>
#include <linux/of.h>
-#include <linux/of_device.h>
#include <linux/pinctrl/consumer.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
@@ -706,19 +705,19 @@ static int uniphier_sd_probe(struct platform_device *pdev)
tmio_data->max_segs = 1;
tmio_data->max_blk_count = U16_MAX;
- ret = tmio_mmc_host_probe(host);
- if (ret)
- goto disable_clk;
+ sd_ctrl_write32_as_16_and_16(host, CTL_IRQ_MASK, TMIO_MASK_ALL);
ret = devm_request_irq(dev, irq, tmio_mmc_irq, IRQF_SHARED,
dev_name(dev), host);
if (ret)
- goto remove_host;
+ goto disable_clk;
+
+ ret = tmio_mmc_host_probe(host);
+ if (ret)
+ goto disable_clk;
return 0;
-remove_host:
- tmio_mmc_host_remove(host);
disable_clk:
uniphier_sd_clk_disable(host);
free_host:
@@ -727,15 +726,13 @@ free_host:
return ret;
}
-static int uniphier_sd_remove(struct platform_device *pdev)
+static void uniphier_sd_remove(struct platform_device *pdev)
{
struct tmio_mmc_host *host = platform_get_drvdata(pdev);
tmio_mmc_host_remove(host);
uniphier_sd_clk_disable(host);
tmio_mmc_host_free(host);
-
- return 0;
}
static const struct of_device_id uniphier_sd_match[] = {
@@ -757,7 +754,7 @@ MODULE_DEVICE_TABLE(of, uniphier_sd_match);
static struct platform_driver uniphier_sd_driver = {
.probe = uniphier_sd_probe,
- .remove = uniphier_sd_remove,
+ .remove_new = uniphier_sd_remove,
.driver = {
.name = "uniphier-sd",
.probe_type = PROBE_PREFER_ASYNCHRONOUS,
diff --git a/drivers/mmc/host/usdhi6rol0.c b/drivers/mmc/host/usdhi6rol0.c
index 2e17903658fc..6e421445d56c 100644
--- a/drivers/mmc/host/usdhi6rol0.c
+++ b/drivers/mmc/host/usdhi6rol0.c
@@ -1884,7 +1884,7 @@ e_free_mmc:
return ret;
}
-static int usdhi6_remove(struct platform_device *pdev)
+static void usdhi6_remove(struct platform_device *pdev)
{
struct usdhi6_host *host = platform_get_drvdata(pdev);
@@ -1895,13 +1895,11 @@ static int usdhi6_remove(struct platform_device *pdev)
usdhi6_dma_release(host);
clk_disable_unprepare(host->clk);
mmc_free_host(host->mmc);
-
- return 0;
}
static struct platform_driver usdhi6_driver = {
.probe = usdhi6_probe,
- .remove = usdhi6_remove,
+ .remove_new = usdhi6_remove,
.driver = {
.name = "usdhi6rol0",
.probe_type = PROBE_PREFER_ASYNCHRONOUS,
diff --git a/drivers/mmc/host/via-sdmmc.c b/drivers/mmc/host/via-sdmmc.c
index a2b0d9461665..ba6044b16e07 100644
--- a/drivers/mmc/host/via-sdmmc.c
+++ b/drivers/mmc/host/via-sdmmc.c
@@ -1160,7 +1160,6 @@ static int via_sd_probe(struct pci_dev *pcidev,
unmap:
iounmap(sdhost->mmiobase);
free_mmc_host:
- dev_set_drvdata(&pcidev->dev, NULL);
mmc_free_host(mmc);
release:
pci_release_regions(pcidev);
@@ -1212,7 +1211,6 @@ static void via_sd_remove(struct pci_dev *pcidev)
writeb(gatt, sdhost->pcictrl_mmiobase + VIA_CRDR_PCICLKGATT);
iounmap(sdhost->mmiobase);
- dev_set_drvdata(&pcidev->dev, NULL);
mmc_free_host(sdhost->mmc);
pci_release_regions(pcidev);
pci_disable_device(pcidev);
diff --git a/drivers/mmc/host/wbsd.c b/drivers/mmc/host/wbsd.c
index 521af9251f33..001a468bc149 100644
--- a/drivers/mmc/host/wbsd.c
+++ b/drivers/mmc/host/wbsd.c
@@ -1264,8 +1264,6 @@ static void wbsd_free_mmc(struct device *dev)
del_timer_sync(&host->ignore_timer);
mmc_free_host(mmc);
-
- dev_set_drvdata(dev, NULL);
}
/*
@@ -1705,8 +1703,6 @@ static int wbsd_init(struct device *dev, int base, int irq, int dma,
wbsd_release_resources(host);
wbsd_free_mmc(dev);
-
- mmc_free_host(mmc);
return ret;
}
@@ -1758,11 +1754,9 @@ static int wbsd_probe(struct platform_device *dev)
return wbsd_init(&dev->dev, param_io, param_irq, param_dma, 0);
}
-static int wbsd_remove(struct platform_device *dev)
+static void wbsd_remove(struct platform_device *dev)
{
wbsd_shutdown(&dev->dev, 0);
-
- return 0;
}
/*
@@ -1904,8 +1898,7 @@ static struct platform_device *wbsd_device;
static struct platform_driver wbsd_driver = {
.probe = wbsd_probe,
- .remove = wbsd_remove,
-
+ .remove_new = wbsd_remove,
.suspend = wbsd_platform_suspend,
.resume = wbsd_platform_resume,
.driver = {
diff --git a/drivers/mmc/host/wmt-sdmmc.c b/drivers/mmc/host/wmt-sdmmc.c
index 68525d900046..77d5f1d24489 100644
--- a/drivers/mmc/host/wmt-sdmmc.c
+++ b/drivers/mmc/host/wmt-sdmmc.c
@@ -21,7 +21,6 @@
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/of_irq.h>
-#include <linux/of_device.h>
#include <linux/mmc/host.h>
#include <linux/mmc/mmc.h>
@@ -880,7 +879,7 @@ fail1:
return ret;
}
-static int wmt_mci_remove(struct platform_device *pdev)
+static void wmt_mci_remove(struct platform_device *pdev)
{
struct mmc_host *mmc;
struct wmt_mci_priv *priv;
@@ -918,8 +917,6 @@ static int wmt_mci_remove(struct platform_device *pdev)
mmc_free_host(mmc);
dev_info(&pdev->dev, "WMT MCI device removed\n");
-
- return 0;
}
#ifdef CONFIG_PM
@@ -989,7 +986,7 @@ static const struct dev_pm_ops wmt_mci_pm = {
static struct platform_driver wmt_mci_driver = {
.probe = wmt_mci_probe,
- .remove = wmt_mci_remove,
+ .remove_new = wmt_mci_remove,
.driver = {
.name = DRIVER_NAME,
.probe_type = PROBE_PREFER_ASYNCHRONOUS,