From d418ed87c4e3ecf45d42718c4ead91180997681f Mon Sep 17 00:00:00 2001 From: Daniel Mack Date: Sun, 19 Feb 2012 13:20:33 +0100 Subject: ARM: OMAP: hsmmc: add max_freq field External circuitry like level shifters may limit the maximum operation speed of the hsmmc controller. Add a field to struct omap2_hsmmc_info so boards can adjust the setting on demand. Signed-off-by: Daniel Mack Acked-by: Tony Lindgren Signed-off-by: Chris Ball --- drivers/mmc/host/omap_hsmmc.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'drivers/mmc/host/omap_hsmmc.c') diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c index fd0c661bbad3..36e7f5bc58a3 100644 --- a/drivers/mmc/host/omap_hsmmc.c +++ b/drivers/mmc/host/omap_hsmmc.c @@ -1912,8 +1912,12 @@ static int __init omap_hsmmc_probe(struct platform_device *pdev) if (mmc_slot(host).vcc_aux_disable_is_sleep) mmc_slot(host).no_off = 1; - mmc->f_min = OMAP_MMC_MIN_CLOCK; - mmc->f_max = OMAP_MMC_MAX_CLOCK; + mmc->f_min = OMAP_MMC_MIN_CLOCK; + + if (pdata->max_freq > 0) + mmc->f_max = pdata->max_freq; + else + mmc->f_max = OMAP_MMC_MAX_CLOCK; spin_lock_init(&host->irq_lock); -- cgit v1.2.3 From b7bf773b0eaac633276a8c3b2867db4d8b64c04a Mon Sep 17 00:00:00 2001 From: Balaji T K Date: Wed, 7 Mar 2012 09:55:30 -0500 Subject: mmc: omap_hsmmc: use platform_get_resource_byname for tx/rx DMA channels Git rid of hardcoded tx/rx DMA channels based on pdev->id and use platform_get_resource_byname() to retrieve them instead. Signed-off-by: Balaji T K Signed-off-by: Rajendra Nayak Tested-by: Venkatraman S Signed-off-by: Chris Ball --- drivers/mmc/host/omap_hsmmc.c | 35 +++++++++++------------------------ 1 file changed, 11 insertions(+), 24 deletions(-) (limited to 'drivers/mmc/host/omap_hsmmc.c') diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c index 36e7f5bc58a3..a6f19f17f0d8 100644 --- a/drivers/mmc/host/omap_hsmmc.c +++ b/drivers/mmc/host/omap_hsmmc.c @@ -1981,32 +1981,19 @@ static int __init omap_hsmmc_probe(struct platform_device *pdev) omap_hsmmc_conf_bus_power(host); - /* Select DMA lines */ - switch (host->id) { - case OMAP_MMC1_DEVID: - host->dma_line_tx = OMAP24XX_DMA_MMC1_TX; - host->dma_line_rx = OMAP24XX_DMA_MMC1_RX; - break; - case OMAP_MMC2_DEVID: - host->dma_line_tx = OMAP24XX_DMA_MMC2_TX; - host->dma_line_rx = OMAP24XX_DMA_MMC2_RX; - break; - case OMAP_MMC3_DEVID: - host->dma_line_tx = OMAP34XX_DMA_MMC3_TX; - host->dma_line_rx = OMAP34XX_DMA_MMC3_RX; - break; - case OMAP_MMC4_DEVID: - host->dma_line_tx = OMAP44XX_DMA_MMC4_TX; - host->dma_line_rx = OMAP44XX_DMA_MMC4_RX; - break; - case OMAP_MMC5_DEVID: - host->dma_line_tx = OMAP44XX_DMA_MMC5_TX; - host->dma_line_rx = OMAP44XX_DMA_MMC5_RX; - break; - default: - dev_err(mmc_dev(host->mmc), "Invalid MMC id\n"); + res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "tx"); + if (!res) { + dev_err(mmc_dev(host->mmc), "cannot get DMA TX channel\n"); + goto err_irq; + } + host->dma_line_tx = 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"); goto err_irq; } + host->dma_line_rx = res->start; /* Request IRQ for MMC operations */ ret = request_irq(host->irq, omap_hsmmc_irq, 0, -- cgit v1.2.3 From 80d17f3a1bd8b5045fedb7dee6b41208497c72d0 Mon Sep 17 00:00:00 2001 From: Balaji T K Date: Wed, 7 Mar 2012 09:55:30 -0500 Subject: mmc: omap_hsmmc: remove unused .set_sleep function set_sleep seems to be unused in omap_hsmmc driver. so get rid of it. Signed-off-by: Balaji T K Signed-off-by: Rajendra Nayak Tested-by: Venkatraman S Signed-off-by: Chris Ball --- drivers/mmc/host/omap_hsmmc.c | 60 ------------------------------------------- 1 file changed, 60 deletions(-) (limited to 'drivers/mmc/host/omap_hsmmc.c') diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c index a6f19f17f0d8..3f77fd94e5d8 100644 --- a/drivers/mmc/host/omap_hsmmc.c +++ b/drivers/mmc/host/omap_hsmmc.c @@ -324,61 +324,6 @@ static int omap_hsmmc_4_set_power(struct device *dev, int slot, int power_on, return 0; } -static int omap_hsmmc_1_set_sleep(struct device *dev, int slot, int sleep, - int vdd, int cardsleep) -{ - struct omap_hsmmc_host *host = - platform_get_drvdata(to_platform_device(dev)); - int mode = sleep ? REGULATOR_MODE_STANDBY : REGULATOR_MODE_NORMAL; - - return regulator_set_mode(host->vcc, mode); -} - -static int omap_hsmmc_235_set_sleep(struct device *dev, int slot, int sleep, - int vdd, int cardsleep) -{ - struct omap_hsmmc_host *host = - platform_get_drvdata(to_platform_device(dev)); - int err, mode; - - /* - * If we don't see a Vcc regulator, assume it's a fixed - * voltage always-on regulator. - */ - if (!host->vcc) - return 0; - - mode = sleep ? REGULATOR_MODE_STANDBY : REGULATOR_MODE_NORMAL; - - if (!host->vcc_aux) - return regulator_set_mode(host->vcc, mode); - - if (cardsleep) { - /* VCC can be turned off if card is asleep */ - if (sleep) - err = mmc_regulator_set_ocr(host->mmc, host->vcc, 0); - else - err = mmc_regulator_set_ocr(host->mmc, host->vcc, vdd); - } else - err = regulator_set_mode(host->vcc, mode); - if (err) - return err; - - if (!mmc_slot(host).vcc_aux_disable_is_sleep) - return regulator_set_mode(host->vcc_aux, mode); - - if (sleep) - return regulator_disable(host->vcc_aux); - else - return regulator_enable(host->vcc_aux); -} - -static int omap_hsmmc_4_set_sleep(struct device *dev, int slot, int sleep, - int vdd, int cardsleep) -{ - return 0; -} - static int omap_hsmmc_reg_get(struct omap_hsmmc_host *host) { struct regulator *reg; @@ -389,18 +334,15 @@ static int omap_hsmmc_reg_get(struct omap_hsmmc_host *host) case OMAP_MMC1_DEVID: /* On-chip level shifting via PBIAS0/PBIAS1 */ mmc_slot(host).set_power = omap_hsmmc_1_set_power; - mmc_slot(host).set_sleep = omap_hsmmc_1_set_sleep; break; case OMAP_MMC2_DEVID: case OMAP_MMC3_DEVID: case OMAP_MMC5_DEVID: /* Off-chip level shifting, or none */ mmc_slot(host).set_power = omap_hsmmc_235_set_power; - mmc_slot(host).set_sleep = omap_hsmmc_235_set_sleep; break; case OMAP_MMC4_DEVID: mmc_slot(host).set_power = omap_hsmmc_4_set_power; - mmc_slot(host).set_sleep = omap_hsmmc_4_set_sleep; default: pr_err("MMC%d configuration not supported!\n", host->id); return -EINVAL; @@ -462,7 +404,6 @@ static int omap_hsmmc_reg_get(struct omap_hsmmc_host *host) err: mmc_slot(host).set_power = NULL; - mmc_slot(host).set_sleep = NULL; return ret; } @@ -471,7 +412,6 @@ static void omap_hsmmc_reg_put(struct omap_hsmmc_host *host) regulator_put(host->vcc); regulator_put(host->vcc_aux); mmc_slot(host).set_power = NULL; - mmc_slot(host).set_sleep = NULL; } static inline int omap_hsmmc_have_reg(void) -- cgit v1.2.3 From c2200efb5d7ca7922e5b9e430598473941d5eb0b Mon Sep 17 00:00:00 2001 From: Balaji T K Date: Wed, 7 Mar 2012 09:55:30 -0500 Subject: mmc: omap_hsmmc: Use OMAP_HSMMC_SUPPORTS_DUAL_VOLT flag to remove host->id based hardcoding Use OMAP_HSMMC_SUPPORTS_DUAL_VOLT flag instead of host->id for identifying SD bus voltage capabilities. Signed-off-by: Balaji T K Signed-off-by: Rajendra Nayak Tested-by: Venkatraman S Signed-off-by: Chris Ball --- drivers/mmc/host/omap_hsmmc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/mmc/host/omap_hsmmc.c') diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c index 3f77fd94e5d8..cfb4b48c212b 100644 --- a/drivers/mmc/host/omap_hsmmc.c +++ b/drivers/mmc/host/omap_hsmmc.c @@ -650,7 +650,7 @@ static int omap_hsmmc_context_restore(struct omap_hsmmc_host *host) OMAP_HSMMC_WRITE(host->base, SYSCONFIG, OMAP_HSMMC_READ(host->base, SYSCONFIG) | AUTOIDLE); - if (host->id == OMAP_MMC1_DEVID) { + if (host->pdata->controller_flags & OMAP_HSMMC_SUPPORTS_DUAL_VOLT) { if (host->power_mode != MMC_POWER_OFF && (1 << ios->vdd) <= MMC_VDD_23_24) hctl = SDVS18; -- cgit v1.2.3 From 69b07ecee936c49f8b7a2099b4276fec7dff6827 Mon Sep 17 00:00:00 2001 From: Rajendra Nayak Date: Wed, 7 Mar 2012 09:55:30 -0500 Subject: mmc: omap_hsmmc: Get rid of omap_hsmmc_1_set_power function Use omap_hsmmc_235_set_poweri() (now renamed as omap_hsmmc_set_power()) for MMC1 instance as well and get rid of omap_hsmmc_1_set_power() completely. omap_hsmmc_235_set_power() seems to be implemented as a superset of omap_hsmmc_1_set_power() with additional functionality implemented based on additional checks and hence should just work for MMC1 as well. Signed-off-by: Rajendra Nayak Tested-by: Venkatraman S Tested-by: Balaji T K Signed-off-by: Chris Ball --- drivers/mmc/host/omap_hsmmc.c | 30 +++--------------------------- 1 file changed, 3 insertions(+), 27 deletions(-) (limited to 'drivers/mmc/host/omap_hsmmc.c') diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c index cfb4b48c212b..11e8c8fe46dc 100644 --- a/drivers/mmc/host/omap_hsmmc.c +++ b/drivers/mmc/host/omap_hsmmc.c @@ -241,28 +241,7 @@ static int omap_hsmmc_resume_cdirq(struct device *dev, int slot) #ifdef CONFIG_REGULATOR -static int omap_hsmmc_1_set_power(struct device *dev, int slot, int power_on, - int vdd) -{ - struct omap_hsmmc_host *host = - platform_get_drvdata(to_platform_device(dev)); - int ret; - - if (mmc_slot(host).before_set_reg) - mmc_slot(host).before_set_reg(dev, slot, power_on, vdd); - - if (power_on) - ret = mmc_regulator_set_ocr(host->mmc, host->vcc, vdd); - else - ret = mmc_regulator_set_ocr(host->mmc, host->vcc, 0); - - if (mmc_slot(host).after_set_reg) - mmc_slot(host).after_set_reg(dev, slot, power_on, vdd); - - return ret; -} - -static int omap_hsmmc_235_set_power(struct device *dev, int slot, int power_on, +static int omap_hsmmc_set_power(struct device *dev, int slot, int power_on, int vdd) { struct omap_hsmmc_host *host = @@ -332,14 +311,11 @@ static int omap_hsmmc_reg_get(struct omap_hsmmc_host *host) switch (host->id) { case OMAP_MMC1_DEVID: - /* On-chip level shifting via PBIAS0/PBIAS1 */ - mmc_slot(host).set_power = omap_hsmmc_1_set_power; - break; case OMAP_MMC2_DEVID: case OMAP_MMC3_DEVID: case OMAP_MMC5_DEVID: - /* Off-chip level shifting, or none */ - mmc_slot(host).set_power = omap_hsmmc_235_set_power; + /* On-chip level shifting via PBIAS0/PBIAS1 */ + mmc_slot(host).set_power = omap_hsmmc_set_power; break; case OMAP_MMC4_DEVID: mmc_slot(host).set_power = omap_hsmmc_4_set_power; -- cgit v1.2.3 From 1cb9af49a1ba2d7fc1c7236df5513449dda30a12 Mon Sep 17 00:00:00 2001 From: Rajendra Nayak Date: Wed, 7 Mar 2012 09:55:31 -0500 Subject: mmc: omap_hsmmc: Get rid of omap_hsmmc_4_set_power function Now that omap_hsmmc_set_power() already has a check to return 0 if !host->vcc, it seems like it can be used even on MMC4 instead of the dummy omap_hsmmc_4_set_power(). This also helps get rid of all the host->id based check to populate the right function for on-chip/external level shifting and use omap_hsmmc_set_power() for all MMC modules. Signed-off-by: Rajendra Nayak Tested-by: Venkatraman S Tested-by: Balaji T K Signed-off-by: Chris Ball --- drivers/mmc/host/omap_hsmmc.c | 21 +-------------------- 1 file changed, 1 insertion(+), 20 deletions(-) (limited to 'drivers/mmc/host/omap_hsmmc.c') diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c index 11e8c8fe46dc..e9215c264988 100644 --- a/drivers/mmc/host/omap_hsmmc.c +++ b/drivers/mmc/host/omap_hsmmc.c @@ -297,32 +297,13 @@ static int omap_hsmmc_set_power(struct device *dev, int slot, int power_on, return ret; } -static int omap_hsmmc_4_set_power(struct device *dev, int slot, int power_on, - int vdd) -{ - return 0; -} - static int omap_hsmmc_reg_get(struct omap_hsmmc_host *host) { struct regulator *reg; int ret = 0; int ocr_value = 0; - switch (host->id) { - case OMAP_MMC1_DEVID: - case OMAP_MMC2_DEVID: - case OMAP_MMC3_DEVID: - case OMAP_MMC5_DEVID: - /* On-chip level shifting via PBIAS0/PBIAS1 */ - mmc_slot(host).set_power = omap_hsmmc_set_power; - break; - case OMAP_MMC4_DEVID: - mmc_slot(host).set_power = omap_hsmmc_4_set_power; - default: - pr_err("MMC%d configuration not supported!\n", host->id); - return -EINVAL; - } + mmc_slot(host).set_power = omap_hsmmc_set_power; reg = regulator_get(host->dev, "vmmc"); if (IS_ERR(reg)) { -- cgit v1.2.3 From e3f1adb63cfa6f6ef6b4e63a546e13210c5f3cb2 Mon Sep 17 00:00:00 2001 From: Rajendra Nayak Date: Wed, 7 Mar 2012 09:55:31 -0500 Subject: mmc: omap_hsmmc: Don't expect MMC1 to always have vmmc supply MMC1 is not the only instance that can be used/wired for SD. So remove this assumption from the driver. Now that all the mmc id based usage is removed, get rid of all the DEVID defines and also the 'id' field from the omap_hsmmc_host structure. Signed-off-by: Rajendra Nayak Tested-by: Venkatraman S Tested-by: Balaji T K Signed-off-by: Chris Ball --- drivers/mmc/host/omap_hsmmc.c | 31 ++----------------------------- 1 file changed, 2 insertions(+), 29 deletions(-) (limited to 'drivers/mmc/host/omap_hsmmc.c') diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c index e9215c264988..e5501704b2db 100644 --- a/drivers/mmc/host/omap_hsmmc.c +++ b/drivers/mmc/host/omap_hsmmc.c @@ -106,17 +106,6 @@ #define SOFTRESET (1 << 1) #define RESETDONE (1 << 0) -/* - * FIXME: Most likely all the data using these _DEVID defines should come - * from the platform_data, or implemented in controller and slot specific - * functions. - */ -#define OMAP_MMC1_DEVID 0 -#define OMAP_MMC2_DEVID 1 -#define OMAP_MMC3_DEVID 2 -#define OMAP_MMC4_DEVID 3 -#define OMAP_MMC5_DEVID 4 - #define MMC_AUTOSUSPEND_DELAY 100 #define MMC_TIMEOUT_MS 20 #define OMAP_MMC_MIN_CLOCK 400000 @@ -164,7 +153,6 @@ struct omap_hsmmc_host { void __iomem *base; resource_size_t mapbase; spinlock_t irq_lock; /* Prevent races with irq handler */ - unsigned int id; unsigned int dma_len; unsigned int dma_sg_idx; unsigned char bus_mode; @@ -300,7 +288,6 @@ static int omap_hsmmc_set_power(struct device *dev, int slot, int power_on, static int omap_hsmmc_reg_get(struct omap_hsmmc_host *host) { struct regulator *reg; - int ret = 0; int ocr_value = 0; mmc_slot(host).set_power = omap_hsmmc_set_power; @@ -308,15 +295,6 @@ static int omap_hsmmc_reg_get(struct omap_hsmmc_host *host) reg = regulator_get(host->dev, "vmmc"); if (IS_ERR(reg)) { dev_dbg(host->dev, "vmmc regulator missing\n"); - /* - * HACK: until fixed.c regulator is usable, - * we don't require a main regulator - * for MMC2 or MMC3 - */ - if (host->id == OMAP_MMC1_DEVID) { - ret = PTR_ERR(reg); - goto err; - } } else { host->vcc = reg; ocr_value = mmc_regulator_get_ocrmask(reg); @@ -324,8 +302,8 @@ static int omap_hsmmc_reg_get(struct omap_hsmmc_host *host) mmc_slot(host).ocr_mask = ocr_value; } else { if (!(mmc_slot(host).ocr_mask & ocr_value)) { - pr_err("MMC%d ocrmask %x is not supported\n", - host->id, mmc_slot(host).ocr_mask); + pr_err("MMC ocrmask %x is not supported\n", + mmc_slot(host).ocr_mask); mmc_slot(host).ocr_mask = 0; return -EINVAL; } @@ -358,10 +336,6 @@ static int omap_hsmmc_reg_get(struct omap_hsmmc_host *host) } return 0; - -err: - mmc_slot(host).set_power = NULL; - return ret; } static void omap_hsmmc_reg_put(struct omap_hsmmc_host *host) @@ -1791,7 +1765,6 @@ static int __init omap_hsmmc_probe(struct platform_device *pdev) host->dev->dma_mask = &pdata->dma_mask; host->dma_ch = -1; host->irq = irq; - host->id = pdev->id; host->slot_id = 0; host->mapbase = res->start; host->base = ioremap(host->mapbase, SZ_4K); -- cgit v1.2.3 From 907d2e7cc7ebba4ab398422a7f0435e1802be65b Mon Sep 17 00:00:00 2001 From: Adrian Hunter Date: Wed, 29 Feb 2012 09:17:21 +0200 Subject: mmc: start removing enable / disable API Most parts of the enable / disable API are no longer used and can be removed. Signed-off-by: Adrian Hunter Tested-by: Venkatraman S Tested-by: Jaehoon Chung Signed-off-by: Chris Ball --- drivers/mmc/host/omap_hsmmc.c | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) (limited to 'drivers/mmc/host/omap_hsmmc.c') diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c index e5501704b2db..98adf0c51e05 100644 --- a/drivers/mmc/host/omap_hsmmc.c +++ b/drivers/mmc/host/omap_hsmmc.c @@ -167,7 +167,6 @@ struct omap_hsmmc_host { int got_dbclk; int response_busy; int context_loss; - int dpm_state; int vdd; int protect_card; int reqs_blocked; @@ -1619,7 +1618,7 @@ static int omap_hsmmc_enable_fclk(struct mmc_host *mmc) return 0; } -static int omap_hsmmc_disable_fclk(struct mmc_host *mmc, int lazy) +static int omap_hsmmc_disable_fclk(struct mmc_host *mmc) { struct omap_hsmmc_host *host = mmc_priv(mmc); @@ -1653,15 +1652,8 @@ static int omap_hsmmc_regs_show(struct seq_file *s, void *data) if (host->pdata->get_context_loss_count) context_loss = host->pdata->get_context_loss_count(host->dev); - seq_printf(s, "mmc%d:\n" - " enabled:\t%d\n" - " dpm_state:\t%d\n" - " nesting_cnt:\t%d\n" - " ctx_loss:\t%d:%d\n" - "\nregs:\n", - mmc->index, mmc->enabled ? 1 : 0, - host->dpm_state, mmc->nesting_cnt, - host->context_loss, context_loss); + seq_printf(s, "mmc%d:\n ctx_loss:\t%d:%d\n\nregs:\n", + mmc->index, host->context_loss, context_loss); if (host->suspended) { seq_printf(s, "host suspended, can't read registers\n"); @@ -1800,7 +1792,6 @@ static int __init omap_hsmmc_probe(struct platform_device *pdev) omap_hsmmc_context_save(host); - mmc->caps |= MMC_CAP_DISABLE; if (host->pdata->controller_flags & OMAP_HSMMC_BROKEN_MULTIBLOCK_READ) { dev_info(&pdev->dev, "multiblock reads disabled due to 35xx erratum 2.1.1.128; MMC read performance may suffer\n"); mmc->caps2 |= MMC_CAP2_NO_MULTI_READ; -- cgit v1.2.3 From 37f6190d54f4d90b886784fadbb9cf82d5c8b1ef Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Thu, 8 Mar 2012 23:41:35 -0500 Subject: mmc: omap_hsmmc: Fix "Unbalanced pm_runtime_enable!" warning Otherwise we can get following warning when re-loading the omap_hsmmc driver module when gpio_twl4030 module is not loaded: omap_hsmmc omap_hsmmc.0: Unbalanced pm_runtime_enable! omap_hsmmc omap_hsmmc.0: Unable to grab MMC CD IRQ omap_hsmmc: probe of omap_hsmmc.0 failed with error -22 Signed-off-by: Tony Lindgren Signed-off-by: Chris Ball --- drivers/mmc/host/omap_hsmmc.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/mmc/host/omap_hsmmc.c') diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c index 98adf0c51e05..94d463859e9b 100644 --- a/drivers/mmc/host/omap_hsmmc.c +++ b/drivers/mmc/host/omap_hsmmc.c @@ -1935,6 +1935,7 @@ err_irq_cd_init: err_irq: pm_runtime_mark_last_busy(host->dev); pm_runtime_put_autosuspend(host->dev); + pm_runtime_disable(host->dev); clk_put(host->fclk); if (host->got_dbclk) { clk_disable(host->dbclk); -- cgit v1.2.3 From 2cecdf002300bca86ce83b17a60f907d5a4ce7dc Mon Sep 17 00:00:00 2001 From: Rajendra Nayak Date: Thu, 23 Feb 2012 17:02:20 +0530 Subject: mmc: omap_hsmmc: convert all pr_* to dev_* Convert all instances of pr_* prints within the driver to instead use dev_* prints. Reported-by: Russell King Signed-off-by: Rajendra Nayak Signed-off-by: Chris Ball --- drivers/mmc/host/omap_hsmmc.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers/mmc/host/omap_hsmmc.c') diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c index 94d463859e9b..0306aea329d4 100644 --- a/drivers/mmc/host/omap_hsmmc.c +++ b/drivers/mmc/host/omap_hsmmc.c @@ -301,7 +301,7 @@ static int omap_hsmmc_reg_get(struct omap_hsmmc_host *host) mmc_slot(host).ocr_mask = ocr_value; } else { if (!(mmc_slot(host).ocr_mask & ocr_value)) { - pr_err("MMC ocrmask %x is not supported\n", + dev_err(host->dev, "ocrmask %x is not supported\n", mmc_slot(host).ocr_mask); mmc_slot(host).ocr_mask = 0; return -EINVAL; @@ -1131,14 +1131,14 @@ static void omap_hsmmc_protect_card(struct omap_hsmmc_host *host) host->reqs_blocked = 0; if (mmc_slot(host).get_cover_state(host->dev, host->slot_id)) { if (host->protect_card) { - pr_info("%s: cover is closed, " + dev_info(host->dev, "%s: cover is closed, " "card is now accessible\n", mmc_hostname(host->mmc)); host->protect_card = 0; } } else { if (!host->protect_card) { - pr_info("%s: cover is open, " + dev_info(host->dev, "%s: cover is open, " "card is now inaccessible\n", mmc_hostname(host->mmc)); host->protect_card = 1; @@ -1275,7 +1275,7 @@ static int omap_hsmmc_pre_dma_transfer(struct omap_hsmmc_host *host, if (!next && data->host_cookie && data->host_cookie != host->next_data.cookie) { - pr_warning("[%s] invalid cookie: data->host_cookie %d" + dev_warn(host->dev, "[%s] invalid cookie: data->host_cookie %d" " host->next_data.cookie %d\n", __func__, data->host_cookie, host->next_data.cookie); data->host_cookie = 0; -- cgit v1.2.3 From 46856a68dcb5f67c779d211fd6bcb5d7a2a7f19b Mon Sep 17 00:00:00 2001 From: Rajendra Nayak Date: Mon, 12 Mar 2012 20:32:37 +0530 Subject: mmc: omap_hsmmc: Convert hsmmc driver to use device tree Define dt bindings for the ti-omap-hsmmc, and adapt the driver to extract data (which was earlier passed as platform_data) from device tree. Signed-off-by: Rajendra Nayak Acked-by: Rob Herring Signed-off-by: Chris Ball --- drivers/mmc/host/omap_hsmmc.c | 73 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) (limited to 'drivers/mmc/host/omap_hsmmc.c') diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c index 0306aea329d4..e0808d4a7681 100644 --- a/drivers/mmc/host/omap_hsmmc.c +++ b/drivers/mmc/host/omap_hsmmc.c @@ -26,6 +26,9 @@ #include #include #include +#include +#include +#include #include #include #include @@ -1710,6 +1713,65 @@ static void omap_hsmmc_debugfs(struct mmc_host *mmc) #endif +#ifdef CONFIG_OF +static u16 omap4_reg_offset = 0x100; + +static const struct of_device_id omap_mmc_of_match[] = { + { + .compatible = "ti,omap2-hsmmc", + }, + { + .compatible = "ti,omap3-hsmmc", + }, + { + .compatible = "ti,omap4-hsmmc", + .data = &omap4_reg_offset, + }, + {}, +} +MODULE_DEVICE_TABLE(of, omap_mmc_of_match); + +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; + + pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL); + if (!pdata) + return NULL; /* out of memory */ + + if (of_find_property(np, "ti,dual-volt", NULL)) + pdata->controller_flags |= OMAP_HSMMC_SUPPORTS_DUAL_VOLT; + + /* 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); + + if (of_find_property(np, "ti,non-removable", NULL)) { + pdata->slots[0].nonremovable = true; + pdata->slots[0].no_regulator_off_init = true; + } + of_property_read_u32(np, "ti,bus-width", &bus_width); + if (bus_width == 4) + pdata->slots[0].caps |= MMC_CAP_4_BIT_DATA; + else if (bus_width == 8) + pdata->slots[0].caps |= MMC_CAP_8_BIT_DATA; + + if (of_find_property(np, "ti,needs-special-reset", NULL)) + pdata->slots[0].features |= HSMMC_HAS_UPDATED_RESET; + + return pdata; +} +#else +static inline struct omap_mmc_platform_data + *of_get_hsmmc_pdata(struct device *dev) +{ + return NULL; +} +#endif + static int __init omap_hsmmc_probe(struct platform_device *pdev) { struct omap_mmc_platform_data *pdata = pdev->dev.platform_data; @@ -1717,6 +1779,16 @@ static int __init omap_hsmmc_probe(struct platform_device *pdev) struct omap_hsmmc_host *host = NULL; struct resource *res; int ret, irq; + const struct of_device_id *match; + + match = of_match_device(of_match_ptr(omap_mmc_of_match), &pdev->dev); + if (match) { + pdata = of_get_hsmmc_pdata(&pdev->dev); + if (match->data) { + u16 *offsetp = match->data; + pdata->reg_offset = *offsetp; + } + } if (pdata == NULL) { dev_err(&pdev->dev, "Platform Data is missing\n"); @@ -2122,6 +2194,7 @@ static struct platform_driver omap_hsmmc_driver = { .name = DRIVER_NAME, .owner = THIS_MODULE, .pm = &omap_hsmmc_dev_pm_ops, + .of_match_table = of_match_ptr(omap_mmc_of_match), }, }; -- cgit v1.2.3 From 1f84b71b3fa834faa87e14c8dc5d5a7c1fa084e8 Mon Sep 17 00:00:00 2001 From: Rajendra Nayak Date: Mon, 12 Mar 2012 20:32:38 +0530 Subject: mmc: omap_hsmmc: Avoid a regulator voltage change with dt When booting with Device tree, the omap_hsmmc driver does not program the pbias cell (inside OMAP control module) during a regulator voltage change. In case of non-dt boot, this is handled using callbacks from within platform_data and implemented in machine code. To be able to do this with device tree, without invoking any machine code, a OMAP control module driver is needed which is yet missing. The pbias cell is used to provide a 1.8v or 3.0v reference to the mmc/sd/sdio1 interface supporting both 1.8v and 3.0v voltages. Until a OMAP control module driver is available to handle this, when booting with a device tree blob, never change the regulator voltage which might then require a pbias cell re-program. There are 2 instances where in the mmc regulator voltage can be changed. -1- when the regulator is turned OFF. -2- when attempting a switch to 1.8v from 3.0v for dual volt cards This patch avoids a voltage change in both cases when booting from device tree, and hence compromises on power savings. Once the OMAP control module driver is available and hsmmc driver is modified to then do pbias programming even when booting with device tree, these limitaions can be removed to achieve better power savings. Signed-off-by: Rajendra Nayak Tested-by: Balaji T K Signed-off-by: Chris Ball --- drivers/mmc/host/omap_hsmmc.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) (limited to 'drivers/mmc/host/omap_hsmmc.c') diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c index e0808d4a7681..47adb161d3ad 100644 --- a/drivers/mmc/host/omap_hsmmc.c +++ b/drivers/mmc/host/omap_hsmmc.c @@ -244,6 +244,13 @@ 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 + * the pbias cell programming support is still missing when + * booting with Device tree + */ + if (of_have_populated_dt() && !vdd) + return 0; if (mmc_slot(host).before_set_reg) mmc_slot(host).before_set_reg(dev, slot, power_on, vdd); @@ -1536,7 +1543,13 @@ static void omap_hsmmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) * of external transceiver; but they all handle 1.8V. */ if ((OMAP_HSMMC_READ(host->base, HCTL) & SDVSDET) && - (ios->vdd == DUAL_VOLT_OCR_BIT)) { + (ios->vdd == DUAL_VOLT_OCR_BIT) && + /* + * With pbias cell programming missing, this + * can't be allowed when booting with device + * tree. + */ + (!of_have_populated_dt())) { /* * The mmc_select_voltage fn of the core does * not seem to set the power_mode to -- cgit v1.2.3 From d59d77ed1e0cdd254f99260013b27d64dc1dffac Mon Sep 17 00:00:00 2001 From: Balaji T K Date: Fri, 24 Feb 2012 21:14:33 +0530 Subject: mmc: omap_hsmmc: use runtime put sync in probe error patch pm_runtime_put_sync instead of autosuspend pm runtime API because iounmap(host->base) follows immediately. Reported-by: Rajendra Nayak Signed-off-by: Balaji T K Signed-off-by: Venkatraman S Cc: Signed-off-by: Chris Ball --- drivers/mmc/host/omap_hsmmc.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers/mmc/host/omap_hsmmc.c') diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c index 47adb161d3ad..f15b04b9da27 100644 --- a/drivers/mmc/host/omap_hsmmc.c +++ b/drivers/mmc/host/omap_hsmmc.c @@ -2018,8 +2018,7 @@ err_reg: err_irq_cd_init: free_irq(host->irq, host); err_irq: - pm_runtime_mark_last_busy(host->dev); - pm_runtime_put_autosuspend(host->dev); + pm_runtime_put_sync(host->dev); pm_runtime_disable(host->dev); clk_put(host->fclk); if (host->got_dbclk) { -- cgit v1.2.3 From 92a3aebf06bdef849cc53aba99f963a9ae397e9d Mon Sep 17 00:00:00 2001 From: Balaji T K Date: Fri, 24 Feb 2012 21:14:34 +0530 Subject: mmc: omap_hsmmc: context save after enabling runtime pm Call context save api after enabling runtime pm to make sure that register access in context save api happens with clk enabled. Signed-off-by: Balaji T K Signed-off-by: Venkatraman S Cc: Signed-off-by: Chris Ball --- drivers/mmc/host/omap_hsmmc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/mmc/host/omap_hsmmc.c') diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c index f15b04b9da27..4ee1570d18d6 100644 --- a/drivers/mmc/host/omap_hsmmc.c +++ b/drivers/mmc/host/omap_hsmmc.c @@ -1875,8 +1875,6 @@ static int __init omap_hsmmc_probe(struct platform_device *pdev) goto err1; } - omap_hsmmc_context_save(host); - if (host->pdata->controller_flags & OMAP_HSMMC_BROKEN_MULTIBLOCK_READ) { dev_info(&pdev->dev, "multiblock reads disabled due to 35xx erratum 2.1.1.128; MMC read performance may suffer\n"); mmc->caps2 |= MMC_CAP2_NO_MULTI_READ; @@ -1887,6 +1885,8 @@ static int __init omap_hsmmc_probe(struct platform_device *pdev) pm_runtime_set_autosuspend_delay(host->dev, MMC_AUTOSUSPEND_DELAY); pm_runtime_use_autosuspend(host->dev); + omap_hsmmc_context_save(host); + if (cpu_is_omap2430()) { host->dbclk = clk_get(&pdev->dev, "mmchsdb_fck"); /* -- cgit v1.2.3 From 927ce944aebdcac0fa757d4e6448a6972184db8c Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Wed, 14 Mar 2012 11:18:27 +0200 Subject: mmc: omap_hsmmc: trivial cleanups A bunch of non-functional cleanups to the omap_hsmmc driver. It basically decreases indentation level, drop unneded dereferences and drop unneded accesses to the platform_device structure. Signed-off-by: Felipe Balbi Signed-off-by: Venkatraman S Signed-off-by: Chris Ball --- drivers/mmc/host/omap_hsmmc.c | 147 ++++++++++++++++++++---------------------- 1 file changed, 70 insertions(+), 77 deletions(-) (limited to 'drivers/mmc/host/omap_hsmmc.c') diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c index 4ee1570d18d6..920964ac3214 100644 --- a/drivers/mmc/host/omap_hsmmc.c +++ b/drivers/mmc/host/omap_hsmmc.c @@ -2041,30 +2041,28 @@ static int omap_hsmmc_remove(struct platform_device *pdev) struct omap_hsmmc_host *host = platform_get_drvdata(pdev); struct resource *res; - if (host) { - pm_runtime_get_sync(host->dev); - mmc_remove_host(host->mmc); - if (host->use_reg) - omap_hsmmc_reg_put(host); - if (host->pdata->cleanup) - host->pdata->cleanup(&pdev->dev); - free_irq(host->irq, host); - if (mmc_slot(host).card_detect_irq) - free_irq(mmc_slot(host).card_detect_irq, host); - - pm_runtime_put_sync(host->dev); - pm_runtime_disable(host->dev); - clk_put(host->fclk); - if (host->got_dbclk) { - clk_disable(host->dbclk); - clk_put(host->dbclk); - } + pm_runtime_get_sync(host->dev); + mmc_remove_host(host->mmc); + if (host->use_reg) + omap_hsmmc_reg_put(host); + if (host->pdata->cleanup) + host->pdata->cleanup(&pdev->dev); + free_irq(host->irq, host); + if (mmc_slot(host).card_detect_irq) + free_irq(mmc_slot(host).card_detect_irq, host); - mmc_free_host(host->mmc); - iounmap(host->base); - omap_hsmmc_gpio_free(pdev->dev.platform_data); + pm_runtime_put_sync(host->dev); + pm_runtime_disable(host->dev); + clk_put(host->fclk); + if (host->got_dbclk) { + clk_disable(host->dbclk); + clk_put(host->dbclk); } + mmc_free_host(host->mmc); + iounmap(host->base); + omap_hsmmc_gpio_free(pdev->dev.platform_data); + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (res) release_mem_region(res->start, resource_size(res)); @@ -2077,49 +2075,45 @@ static int omap_hsmmc_remove(struct platform_device *pdev) static int omap_hsmmc_suspend(struct device *dev) { int ret = 0; - struct platform_device *pdev = to_platform_device(dev); - struct omap_hsmmc_host *host = platform_get_drvdata(pdev); + struct omap_hsmmc_host *host = dev_get_drvdata(dev); - if (host && host->suspended) + if (!host) return 0; - if (host) { - pm_runtime_get_sync(host->dev); - host->suspended = 1; - if (host->pdata->suspend) { - ret = host->pdata->suspend(&pdev->dev, - host->slot_id); - if (ret) { - dev_dbg(mmc_dev(host->mmc), - "Unable to handle MMC board" - " level suspend\n"); - host->suspended = 0; - return ret; - } - } - ret = mmc_suspend_host(host->mmc); + if (host && host->suspended) + return 0; + pm_runtime_get_sync(host->dev); + host->suspended = 1; + if (host->pdata->suspend) { + ret = host->pdata->suspend(dev, host->slot_id); if (ret) { + dev_dbg(dev, "Unable to handle MMC board" + " level suspend\n"); host->suspended = 0; - if (host->pdata->resume) { - ret = host->pdata->resume(&pdev->dev, - host->slot_id); - if (ret) - dev_dbg(mmc_dev(host->mmc), - "Unmask interrupt failed\n"); - } - goto err; + return ret; } + } + ret = mmc_suspend_host(host->mmc); - if (!(host->mmc->pm_flags & MMC_PM_KEEP_POWER)) { - omap_hsmmc_disable_irq(host); - OMAP_HSMMC_WRITE(host->base, HCTL, - OMAP_HSMMC_READ(host->base, HCTL) & ~SDBP); + if (ret) { + host->suspended = 0; + if (host->pdata->resume) { + ret = host->pdata->resume(dev, host->slot_id); + if (ret) + dev_dbg(dev, "Unmask interrupt failed\n"); } - if (host->got_dbclk) - clk_disable(host->dbclk); + goto err; + } + if (!(host->mmc->pm_flags & MMC_PM_KEEP_POWER)) { + omap_hsmmc_disable_irq(host); + OMAP_HSMMC_WRITE(host->base, HCTL, + OMAP_HSMMC_READ(host->base, HCTL) & ~SDBP); } + + if (host->got_dbclk) + clk_disable(host->dbclk); err: pm_runtime_put_sync(host->dev); return ret; @@ -2129,38 +2123,37 @@ err: static int omap_hsmmc_resume(struct device *dev) { int ret = 0; - struct platform_device *pdev = to_platform_device(dev); - struct omap_hsmmc_host *host = platform_get_drvdata(pdev); + struct omap_hsmmc_host *host = dev_get_drvdata(dev); + + if (!host) + return 0; if (host && !host->suspended) return 0; - if (host) { - pm_runtime_get_sync(host->dev); + pm_runtime_get_sync(host->dev); - if (host->got_dbclk) - clk_enable(host->dbclk); + if (host->got_dbclk) + clk_enable(host->dbclk); - if (!(host->mmc->pm_flags & MMC_PM_KEEP_POWER)) - omap_hsmmc_conf_bus_power(host); + if (!(host->mmc->pm_flags & MMC_PM_KEEP_POWER)) + omap_hsmmc_conf_bus_power(host); - if (host->pdata->resume) { - ret = host->pdata->resume(&pdev->dev, host->slot_id); - if (ret) - dev_dbg(mmc_dev(host->mmc), - "Unmask interrupt failed\n"); - } + if (host->pdata->resume) { + ret = host->pdata->resume(dev, host->slot_id); + if (ret) + dev_dbg(dev, "Unmask interrupt failed\n"); + } - omap_hsmmc_protect_card(host); + omap_hsmmc_protect_card(host); - /* Notify the core to resume the host */ - ret = mmc_resume_host(host->mmc); - if (ret == 0) - host->suspended = 0; + /* Notify the core to resume the host */ + ret = mmc_resume_host(host->mmc); + if (ret == 0) + host->suspended = 0; - pm_runtime_mark_last_busy(host->dev); - pm_runtime_put_autosuspend(host->dev); - } + pm_runtime_mark_last_busy(host->dev); + pm_runtime_put_autosuspend(host->dev); return ret; @@ -2177,7 +2170,7 @@ static int omap_hsmmc_runtime_suspend(struct device *dev) host = platform_get_drvdata(to_platform_device(dev)); omap_hsmmc_context_save(host); - dev_dbg(mmc_dev(host->mmc), "disabled\n"); + dev_dbg(dev, "disabled\n"); return 0; } @@ -2188,7 +2181,7 @@ static int omap_hsmmc_runtime_resume(struct device *dev) host = platform_get_drvdata(to_platform_device(dev)); omap_hsmmc_context_restore(host); - dev_dbg(mmc_dev(host->mmc), "enabled\n"); + dev_dbg(dev, "enabled\n"); return 0; } -- cgit v1.2.3 From efa25fd3a33275861aa74ff03a512423873a8805 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Wed, 14 Mar 2012 11:18:28 +0200 Subject: mmc: omap_hsmmc: make it behave well as a module If we put probe() on __init section, that will never work for multiple module insertions/removals. In order to make it work properly, move probe to __devinit section and use platform_driver_register() instead of platform_driver_probe(). Signed-off-by: Felipe Balbi Signed-off-by: Venkatraman S Signed-off-by: Chris Ball --- drivers/mmc/host/omap_hsmmc.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'drivers/mmc/host/omap_hsmmc.c') diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c index 920964ac3214..2aa963dcbdbd 100644 --- a/drivers/mmc/host/omap_hsmmc.c +++ b/drivers/mmc/host/omap_hsmmc.c @@ -1785,7 +1785,7 @@ static inline struct omap_mmc_platform_data } #endif -static int __init omap_hsmmc_probe(struct platform_device *pdev) +static int __devinit omap_hsmmc_probe(struct platform_device *pdev) { struct omap_mmc_platform_data *pdata = pdev->dev.platform_data; struct mmc_host *mmc; @@ -2036,7 +2036,7 @@ err: return ret; } -static int omap_hsmmc_remove(struct platform_device *pdev) +static int __devexit omap_hsmmc_remove(struct platform_device *pdev) { struct omap_hsmmc_host *host = platform_get_drvdata(pdev); struct resource *res; @@ -2194,7 +2194,8 @@ static struct dev_pm_ops omap_hsmmc_dev_pm_ops = { }; static struct platform_driver omap_hsmmc_driver = { - .remove = omap_hsmmc_remove, + .probe = omap_hsmmc_probe, + .remove = __devexit_p(omap_hsmmc_remove), .driver = { .name = DRIVER_NAME, .owner = THIS_MODULE, @@ -2206,7 +2207,7 @@ static struct platform_driver omap_hsmmc_driver = { static int __init omap_hsmmc_init(void) { /* Register the MMC driver */ - return platform_driver_probe(&omap_hsmmc_driver, omap_hsmmc_probe); + return platform_driver_register(&omap_hsmmc_driver); } static void __exit omap_hsmmc_cleanup(void) -- cgit v1.2.3 From b796450b4590dbaee2d31c85b04791cafacff9b4 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Wed, 14 Mar 2012 11:18:32 +0200 Subject: mmc: omap_hsmmc: convert to module_platform_driver This will delete some boilerplate code, no functional changes. Signed-off-by: Felipe Balbi Signed-off-by: Venkatraman S Signed-off-by: Chris Ball --- drivers/mmc/host/omap_hsmmc.c | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-) (limited to 'drivers/mmc/host/omap_hsmmc.c') diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c index 2aa963dcbdbd..b4c59eac348f 100644 --- a/drivers/mmc/host/omap_hsmmc.c +++ b/drivers/mmc/host/omap_hsmmc.c @@ -2204,21 +2204,7 @@ static struct platform_driver omap_hsmmc_driver = { }, }; -static int __init omap_hsmmc_init(void) -{ - /* Register the MMC driver */ - return platform_driver_register(&omap_hsmmc_driver); -} - -static void __exit omap_hsmmc_cleanup(void) -{ - /* Unregister MMC driver */ - platform_driver_unregister(&omap_hsmmc_driver); -} - -module_init(omap_hsmmc_init); -module_exit(omap_hsmmc_cleanup); - +module_platform_driver(omap_hsmmc_driver); MODULE_DESCRIPTION("OMAP High Speed Multimedia Card driver"); MODULE_LICENSE("GPL"); MODULE_ALIAS("platform:" DRIVER_NAME); -- cgit v1.2.3 From fc307df88f0d77505c19756d95be66c981c421ea Mon Sep 17 00:00:00 2001 From: Balaji T K Date: Mon, 2 Apr 2012 12:26:47 +0530 Subject: mmc: omap_hsmmc: fix module re-insertion OMAP4 and OMAP3 HSMMC IP registers differ by 0x100 offset. Adding the offset to platform_device resource structure increments the start address for every insmod operation. MMC command fails on re-insertion as module due to incorrect register base. Fix this by updating the ioremap base address only. Signed-off-by: Balaji T K Signed-off-by: Venkatraman S Signed-off-by: Chris Ball --- drivers/mmc/host/omap_hsmmc.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers/mmc/host/omap_hsmmc.c') diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c index b4c59eac348f..5c2b1c10af9c 100644 --- a/drivers/mmc/host/omap_hsmmc.c +++ b/drivers/mmc/host/omap_hsmmc.c @@ -1818,8 +1818,6 @@ static int __devinit omap_hsmmc_probe(struct platform_device *pdev) if (res == NULL || irq < 0) return -ENXIO; - res->start += pdata->reg_offset; - res->end += pdata->reg_offset; res = request_mem_region(res->start, resource_size(res), pdev->name); if (res == NULL) return -EBUSY; @@ -1843,7 +1841,7 @@ static int __devinit omap_hsmmc_probe(struct platform_device *pdev) host->dma_ch = -1; host->irq = irq; host->slot_id = 0; - host->mapbase = res->start; + host->mapbase = res->start + pdata->reg_offset; host->base = ioremap(host->mapbase, SZ_4K); host->power_mode = MMC_POWER_OFF; host->next_data.cookie = 1; -- cgit v1.2.3