summaryrefslogtreecommitdiffstats
path: root/drivers/mmc/host/omap_hsmmc.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mmc/host/omap_hsmmc.c')
-rw-r--r--drivers/mmc/host/omap_hsmmc.c65
1 files changed, 44 insertions, 21 deletions
diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index bc5807873b2..eccedc7d06a 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -161,6 +161,7 @@ struct omap_hsmmc_host {
*/
struct regulator *vcc;
struct regulator *vcc_aux;
+ int pbias_disable;
void __iomem *base;
resource_size_t mapbase;
spinlock_t irq_lock; /* Prevent races with irq handler */
@@ -255,11 +256,11 @@ static int omap_hsmmc_set_power(struct device *dev, int slot, int power_on,
if (!host->vcc)
return 0;
/*
- * With DT, never turn OFF the regulator. This is because
+ * With DT, never turn OFF the regulator for MMC1. This is because
* the pbias cell programming support is still missing when
* booting with Device tree
*/
- if (dev->of_node && !vdd)
+ if (host->pbias_disable && !vdd)
return 0;
if (mmc_slot(host).before_set_reg)
@@ -1520,10 +1521,10 @@ static void omap_hsmmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
(ios->vdd == DUAL_VOLT_OCR_BIT) &&
/*
* With pbias cell programming missing, this
- * can't be allowed when booting with device
+ * can't be allowed on MMC1 when booting with device
* tree.
*/
- !host->dev->of_node) {
+ !host->pbias_disable) {
/*
* The mmc_select_voltage fn of the core does
* not seem to set the power_mode to
@@ -1717,6 +1718,12 @@ static struct omap_mmc_platform_data *of_get_hsmmc_pdata(struct device *dev)
struct omap_mmc_platform_data *pdata;
struct device_node *np = dev->of_node;
u32 bus_width, max_freq;
+ int cd_gpio, wp_gpio;
+
+ cd_gpio = of_get_named_gpio(np, "cd-gpios", 0);
+ wp_gpio = of_get_named_gpio(np, "wp-gpios", 0);
+ if (cd_gpio == -EPROBE_DEFER || wp_gpio == -EPROBE_DEFER)
+ return ERR_PTR(-EPROBE_DEFER);
pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
if (!pdata)
@@ -1727,8 +1734,8 @@ static struct omap_mmc_platform_data *of_get_hsmmc_pdata(struct device *dev)
/* This driver only supports 1 slot */
pdata->nr_slots = 1;
- pdata->slots[0].switch_pin = of_get_named_gpio(np, "cd-gpios", 0);
- pdata->slots[0].gpio_wp = of_get_named_gpio(np, "wp-gpios", 0);
+ pdata->slots[0].switch_pin = cd_gpio;
+ pdata->slots[0].gpio_wp = wp_gpio;
if (of_find_property(np, "ti,non-removable", NULL)) {
pdata->slots[0].nonremovable = true;
@@ -1774,6 +1781,10 @@ static int omap_hsmmc_probe(struct platform_device *pdev)
match = of_match_device(of_match_ptr(omap_mmc_of_match), &pdev->dev);
if (match) {
pdata = of_get_hsmmc_pdata(&pdev->dev);
+
+ if (IS_ERR(pdata))
+ return PTR_ERR(pdata);
+
if (match->data) {
const u16 *offsetp = match->data;
pdata->reg_offset = *offsetp;
@@ -1861,6 +1872,10 @@ static int omap_hsmmc_probe(struct platform_device *pdev)
omap_hsmmc_context_save(host);
+ /* This can be removed once we support PBIAS with DT */
+ if (host->dev->of_node && host->mapbase == 0x4809c000)
+ host->pbias_disable = 1;
+
host->dbclk = clk_get(&pdev->dev, "mmchsdb_fck");
/*
* MMC can still work without debounce clock.
@@ -1896,33 +1911,41 @@ static int omap_hsmmc_probe(struct platform_device *pdev)
omap_hsmmc_conf_bus_power(host);
- res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "tx");
- if (!res) {
- dev_err(mmc_dev(host->mmc), "cannot get DMA TX channel\n");
- ret = -ENXIO;
- goto err_irq;
- }
- tx_req = res->start;
+ if (!pdev->dev.of_node) {
+ res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "tx");
+ if (!res) {
+ dev_err(mmc_dev(host->mmc), "cannot get DMA TX channel\n");
+ ret = -ENXIO;
+ goto err_irq;
+ }
+ tx_req = res->start;
- res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "rx");
- if (!res) {
- dev_err(mmc_dev(host->mmc), "cannot get DMA RX channel\n");
- ret = -ENXIO;
- goto err_irq;
+ res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "rx");
+ if (!res) {
+ dev_err(mmc_dev(host->mmc), "cannot get DMA RX channel\n");
+ ret = -ENXIO;
+ goto err_irq;
+ }
+ rx_req = res->start;
}
- rx_req = res->start;
dma_cap_zero(mask);
dma_cap_set(DMA_SLAVE, mask);
- host->rx_chan = dma_request_channel(mask, omap_dma_filter_fn, &rx_req);
+ host->rx_chan =
+ dma_request_slave_channel_compat(mask, omap_dma_filter_fn,
+ &rx_req, &pdev->dev, "rx");
+
if (!host->rx_chan) {
dev_err(mmc_dev(host->mmc), "unable to obtain RX DMA engine channel %u\n", rx_req);
ret = -ENXIO;
goto err_irq;
}
- host->tx_chan = dma_request_channel(mask, omap_dma_filter_fn, &tx_req);
+ host->tx_chan =
+ dma_request_slave_channel_compat(mask, omap_dma_filter_fn,
+ &tx_req, &pdev->dev, "tx");
+
if (!host->tx_chan) {
dev_err(mmc_dev(host->mmc), "unable to obtain TX DMA engine channel %u\n", tx_req);
ret = -ENXIO;