From 5074d25dc97ac2d93fca7852563b7e204f03464a Mon Sep 17 00:00:00 2001 From: Ulf Hansson Date: Tue, 13 Dec 2011 16:53:17 +0100 Subject: ARM: 7216/1: mmc: mmci: Do not release spinlock in request_end The patch "mmc: core: move ->request() call from atomic context", is the reason to why this change is possible. This simplifies the error handling code execution path quite a lot and potentially also fixes some error handling hang problems. Tested-by: Linus Walleij Signed-off-by: Ulf Hansson Signed-off-by: Russell King --- drivers/mmc/host/mmci.c | 6 ------ 1 file changed, 6 deletions(-) (limited to 'drivers/mmc/host/mmci.c') diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c index 0d955ffaf44e..0e04138b1759 100644 --- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c @@ -166,14 +166,8 @@ mmci_request_end(struct mmci_host *host, struct mmc_request *mrq) host->mrq = NULL; host->cmd = NULL; - /* - * Need to drop the host lock here; mmc_request_done may call - * back into the driver... - */ - spin_unlock(&host->lock); pm_runtime_put(mmc_dev(host->mmc)); mmc_request_done(host->mmc, mrq); - spin_lock(&host->lock); } static void mmci_set_mask1(struct mmci_host *host, unsigned int mask) -- cgit v1.2.3 From 7d72a1d48af95211677ea83157945a8ef76b0751 Mon Sep 17 00:00:00 2001 From: Ulf Hansson Date: Tue, 13 Dec 2011 16:54:55 +0100 Subject: ARM: 7217/1: mmc: mmci: Put power register deviations in variant data Use variant data to store hardware controller deviations concerning power registers to improve readability of the code. Signed-off-by: Sebastian Rasmussen Tested-by: Linus Walleij Signed-off-by: Ulf Hansson Signed-off-by: Russell King --- drivers/mmc/host/mmci.c | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) (limited to 'drivers/mmc/host/mmci.c') diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c index 0e04138b1759..7cc89beee87f 100644 --- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c @@ -53,6 +53,7 @@ static unsigned int fmax = 515633; * @sdio: variant supports SDIO * @st_clkdiv: true if using a ST-specific clock divider algorithm * @blksz_datactrl16: true if Block size is at b16..b30 position in datactrl register + * @pwrreg_powerup: power up value for MMCIPOWER register */ struct variant_data { unsigned int clkreg; @@ -63,18 +64,21 @@ struct variant_data { bool sdio; bool st_clkdiv; bool blksz_datactrl16; + u32 pwrreg_powerup; }; static struct variant_data variant_arm = { .fifosize = 16 * 4, .fifohalfsize = 8 * 4, .datalength_bits = 16, + .pwrreg_powerup = MCI_PWR_UP, }; static struct variant_data variant_arm_extended_fifo = { .fifosize = 128 * 4, .fifohalfsize = 64 * 4, .datalength_bits = 16, + .pwrreg_powerup = MCI_PWR_UP, }; static struct variant_data variant_u300 = { @@ -83,6 +87,7 @@ static struct variant_data variant_u300 = { .clkreg_enable = MCI_ST_U300_HWFCEN, .datalength_bits = 16, .sdio = true, + .pwrreg_powerup = MCI_PWR_ON, }; static struct variant_data variant_ux500 = { @@ -93,6 +98,7 @@ static struct variant_data variant_ux500 = { .datalength_bits = 24, .sdio = true, .st_clkdiv = true, + .pwrreg_powerup = MCI_PWR_ON, }; static struct variant_data variant_ux500v2 = { @@ -104,6 +110,7 @@ static struct variant_data variant_ux500v2 = { .sdio = true, .st_clkdiv = true, .blksz_datactrl16 = true, + .pwrreg_powerup = MCI_PWR_ON, }; /* @@ -1009,6 +1016,7 @@ static void mmci_request(struct mmc_host *mmc, struct mmc_request *mrq) static void mmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) { struct mmci_host *host = mmc_priv(mmc); + struct variant_data *variant = host->variant; u32 pwr = 0; unsigned long flags; int ret; @@ -1035,11 +1043,15 @@ static void mmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) if (host->plat->vdd_handler) pwr |= host->plat->vdd_handler(mmc_dev(mmc), ios->vdd, ios->power_mode); - /* The ST version does not have this, fall through to POWER_ON */ - if (host->hw_designer != AMBA_VENDOR_ST) { - pwr |= MCI_PWR_UP; - break; - } + + /* + * The ST Micro variant doesn't have the PL180s MCI_PWR_UP + * and instead uses MCI_PWR_ON so apply whatever value is + * configured in the variant data. + */ + pwr |= variant->pwrreg_powerup; + + break; case MMC_POWER_ON: pwr |= MCI_PWR_ON; break; -- cgit v1.2.3 From 4d1a3a0dc551cfa7304ca46e014231500f3b81a6 Mon Sep 17 00:00:00 2001 From: Ulf Hansson Date: Tue, 13 Dec 2011 16:57:07 +0100 Subject: ARM: 7218/1: mmc: mmci: Provide option to configure bus signal direction The ST Micro variant supports bus signal direction indication. A new member in the variant struct is added for this. Moreover the actual signal direction configuration is board specific, thus the amba mmci platform data is extended with a new member to be able provide mmci with these specific board configurations. This patch is based upon a patch from Sebastian Rasmussen. Tested-by: Linus Walleij Signed-off-by: Sebastian Rasmussen Signed-off-by: Ulf Hansson Signed-off-by: Russell King --- drivers/mmc/host/mmci.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) (limited to 'drivers/mmc/host/mmci.c') diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c index 7cc89beee87f..eb11ce61941d 100644 --- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c @@ -54,6 +54,7 @@ static unsigned int fmax = 515633; * @st_clkdiv: true if using a ST-specific clock divider algorithm * @blksz_datactrl16: true if Block size is at b16..b30 position in datactrl register * @pwrreg_powerup: power up value for MMCIPOWER register + * @signal_direction: input/out direction of bus signals can be indicated */ struct variant_data { unsigned int clkreg; @@ -65,6 +66,7 @@ struct variant_data { bool st_clkdiv; bool blksz_datactrl16; u32 pwrreg_powerup; + bool signal_direction; }; static struct variant_data variant_arm = { @@ -88,6 +90,7 @@ static struct variant_data variant_u300 = { .datalength_bits = 16, .sdio = true, .pwrreg_powerup = MCI_PWR_ON, + .signal_direction = true, }; static struct variant_data variant_ux500 = { @@ -99,6 +102,7 @@ static struct variant_data variant_ux500 = { .sdio = true, .st_clkdiv = true, .pwrreg_powerup = MCI_PWR_ON, + .signal_direction = true, }; static struct variant_data variant_ux500v2 = { @@ -111,6 +115,7 @@ static struct variant_data variant_ux500v2 = { .st_clkdiv = true, .blksz_datactrl16 = true, .pwrreg_powerup = MCI_PWR_ON, + .signal_direction = true, }; /* @@ -1057,6 +1062,22 @@ static void mmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) break; } + if (variant->signal_direction && ios->power_mode != MMC_POWER_OFF) { + /* + * The ST Micro variant has some additional bits + * indicating signal direction for the signals in + * the SD/MMC bus and feedback-clock usage. + */ + pwr |= host->plat->sigdir; + + if (ios->bus_width == MMC_BUS_WIDTH_4) + pwr &= ~MCI_ST_DATA74DIREN; + else if (ios->bus_width == MMC_BUS_WIDTH_1) + pwr &= (~MCI_ST_DATA74DIREN & + ~MCI_ST_DATA31DIREN & + ~MCI_ST_DATA2DIREN); + } + if (ios->bus_mode == MMC_BUSMODE_OPENDRAIN) { if (host->hw_designer != AMBA_VENDOR_ST) pwr |= MCI_ROD; -- cgit v1.2.3 From bc521818e28042bb6018d91c353d24fb01ccb162 Mon Sep 17 00:00:00 2001 From: Ulf Hansson Date: Tue, 13 Dec 2011 16:57:55 +0100 Subject: ARM: 7219/1: mmc: mmci: Change vdd_handler to a generic ios_handler The purpose of the vdd_handler does not make sense. We remove it and use a generic approach instead. A new ios_handler is added, the purpose of which e.g. can be to control GPIO pins to a levelshifter. Previously the vdd_handler was also used for making additional changes to the power register bits. This option is superfluous and is therefore removed. Adaptaptions from the old vdd_handler to the new ios_handler is done for mach-ux500 board, which was the only one using the vdd_handler. This patch is based upon a patch from Sebastian Rasmussen. Tested-by: Linus Walleij Signed-off-by: Sebastian Rasmussen Signed-off-by: Ulf Hansson Signed-off-by: Russell King --- drivers/mmc/host/mmci.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers/mmc/host/mmci.c') diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c index eb11ce61941d..0af1507d15c0 100644 --- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c @@ -1026,6 +1026,10 @@ static void mmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) unsigned long flags; int ret; + if (host->plat->ios_handler && + host->plat->ios_handler(mmc_dev(mmc), ios)) + dev_err(mmc_dev(mmc), "platform ios_handler failed\n"); + switch (ios->power_mode) { case MMC_POWER_OFF: if (host->vcc) @@ -1045,10 +1049,6 @@ static void mmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) return; } } - if (host->plat->vdd_handler) - pwr |= host->plat->vdd_handler(mmc_dev(mmc), ios->vdd, - ios->power_mode); - /* * The ST Micro variant doesn't have the PL180s MCI_PWR_UP * and instead uses MCI_PWR_ON so apply whatever value is -- cgit v1.2.3 From 48fa700388bec2ba79e9c8cc087f39c800a6fff5 Mon Sep 17 00:00:00 2001 From: Ulf Hansson Date: Tue, 13 Dec 2011 16:59:34 +0100 Subject: ARM: 7221/1: mmc: mmci: Change from using legacy suspend This patch switch from using the legacy suspend/resume to the new way of registering PM callbacks. No functional change is done. Tested-by: Linus Walleij Signed-off-by: Ulf Hansson Signed-off-by: Russell King --- drivers/mmc/host/mmci.c | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) (limited to 'drivers/mmc/host/mmci.c') diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c index 0af1507d15c0..544995b3cb95 100644 --- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c @@ -1456,10 +1456,11 @@ static int __devexit mmci_remove(struct amba_device *dev) return 0; } -#ifdef CONFIG_PM -static int mmci_suspend(struct amba_device *dev, pm_message_t state) +#ifdef CONFIG_SUSPEND +static int mmci_suspend(struct device *dev) { - struct mmc_host *mmc = amba_get_drvdata(dev); + struct amba_device *adev = to_amba_device(dev); + struct mmc_host *mmc = amba_get_drvdata(adev); int ret = 0; if (mmc) { @@ -1473,9 +1474,10 @@ static int mmci_suspend(struct amba_device *dev, pm_message_t state) return ret; } -static int mmci_resume(struct amba_device *dev) +static int mmci_resume(struct device *dev) { - struct mmc_host *mmc = amba_get_drvdata(dev); + struct amba_device *adev = to_amba_device(dev); + struct mmc_host *mmc = amba_get_drvdata(adev); int ret = 0; if (mmc) { @@ -1488,11 +1490,12 @@ static int mmci_resume(struct amba_device *dev) return ret; } -#else -#define mmci_suspend NULL -#define mmci_resume NULL #endif +static const struct dev_pm_ops mmci_dev_pm_ops = { + SET_SYSTEM_SLEEP_PM_OPS(mmci_suspend, mmci_resume) +}; + static struct amba_id mmci_ids[] = { { .id = 0x00041180, @@ -1538,11 +1541,10 @@ MODULE_DEVICE_TABLE(amba, mmci_ids); static struct amba_driver mmci_driver = { .drv = { .name = DRIVER_NAME, + .pm = &mmci_dev_pm_ops, }, .probe = mmci_probe, .remove = __devexit_p(mmci_remove), - .suspend = mmci_suspend, - .resume = mmci_resume, .id_table = mmci_ids, }; -- cgit v1.2.3 From 2cd976c46472e34460349ed43a217e34f90bad55 Mon Sep 17 00:00:00 2001 From: Ulf Hansson Date: Tue, 13 Dec 2011 17:01:11 +0100 Subject: ARM: 7223/1: mmc: mmci: Fixup use of runtime PM and use autosuspend Added use of runtime PM autosuspend feature, with a fixed timeout of 50 ms. This will prevent adding a latency, although very minor, for _every_ request. Moreover the runtime_get_sync is now also used in set_ios and suspend since the runtime resourses are needed here as well. Tested-by: Linus Walleij Signed-off-by: Ulf Hansson Signed-off-by: Russell King --- drivers/mmc/host/mmci.c | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) (limited to 'drivers/mmc/host/mmci.c') diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c index 544995b3cb95..6a21fc0bf3d8 100644 --- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c @@ -178,8 +178,10 @@ mmci_request_end(struct mmci_host *host, struct mmc_request *mrq) host->mrq = NULL; host->cmd = NULL; - pm_runtime_put(mmc_dev(host->mmc)); mmc_request_done(host->mmc, mrq); + + pm_runtime_mark_last_busy(mmc_dev(host->mmc)); + pm_runtime_put_autosuspend(mmc_dev(host->mmc)); } static void mmci_set_mask1(struct mmci_host *host, unsigned int mask) @@ -1026,6 +1028,8 @@ static void mmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) unsigned long flags; int ret; + pm_runtime_get_sync(mmc_dev(mmc)); + if (host->plat->ios_handler && host->plat->ios_handler(mmc_dev(mmc), ios)) dev_err(mmc_dev(mmc), "platform ios_handler failed\n"); @@ -1046,7 +1050,7 @@ static void mmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) * power should be rare so we print an error * and return here. */ - return; + goto out; } } /* @@ -1100,6 +1104,10 @@ static void mmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) } spin_unlock_irqrestore(&host->lock, flags); + + out: + pm_runtime_mark_last_busy(mmc_dev(mmc)); + pm_runtime_put_autosuspend(mmc_dev(mmc)); } static int mmci_get_ro(struct mmc_host *mmc) @@ -1372,6 +1380,8 @@ static int __devinit mmci_probe(struct amba_device *dev, mmci_dma_setup(host); + pm_runtime_set_autosuspend_delay(&dev->dev, 50); + pm_runtime_use_autosuspend(&dev->dev); pm_runtime_put(&dev->dev); mmc_add_host(mmc); @@ -1467,8 +1477,10 @@ static int mmci_suspend(struct device *dev) struct mmci_host *host = mmc_priv(mmc); ret = mmc_suspend_host(mmc); - if (ret == 0) + if (ret == 0) { + pm_runtime_get_sync(dev); writel(0, host->base + MMCIMASK0); + } } return ret; @@ -1484,6 +1496,7 @@ static int mmci_resume(struct device *dev) struct mmci_host *host = mmc_priv(mmc); writel(MCI_IRQENABLE, host->base + MMCIMASK0); + pm_runtime_put(dev); ret = mmc_resume_host(mmc); } -- cgit v1.2.3 From 7258db7efe7d9c5eb80151554faa1fa7411d6e3e Mon Sep 17 00:00:00 2001 From: Ulf Hansson Date: Tue, 13 Dec 2011 17:05:28 +0100 Subject: ARM: 7227/1: mmc: mmci: Prepare for SDIO before setting up DMA job Move the SDIO preparation to be done before the DMA job is setup. This makes it possible to do DMA for SDIO transfers as well as the earlier supported pio mode. Signed-off-by: Ulf Hansson Signed-off-by: Stefan Nilsson XK Signed-off-by: Russell King --- drivers/mmc/host/mmci.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers/mmc/host/mmci.c') diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c index 6a21fc0bf3d8..b09ccb7223e5 100644 --- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c @@ -615,6 +615,11 @@ static void mmci_start_data(struct mmci_host *host, struct mmc_data *data) if (data->flags & MMC_DATA_READ) datactrl |= MCI_DPSM_DIRECTION; + /* The ST Micro variants has a special bit to enable SDIO */ + if (variant->sdio && host->mmc->card) + if (mmc_card_sdio(host->mmc->card)) + datactrl |= MCI_ST_DPSM_SDIOEN; + /* * Attempt to use DMA operation mode, if this * should fail, fall back to PIO mode @@ -643,11 +648,6 @@ static void mmci_start_data(struct mmci_host *host, struct mmc_data *data) irqmask = MCI_TXFIFOHALFEMPTYMASK; } - /* The ST Micro variants has a special bit to enable SDIO */ - if (variant->sdio && host->mmc->card) - if (mmc_card_sdio(host->mmc->card)) - datactrl |= MCI_ST_DPSM_SDIOEN; - writel(datactrl, base + MMCIDATACTRL); writel(readl(base + MMCIMASK0) & ~MCI_DATAENDMASK, base + MMCIMASK0); mmci_set_mask1(host, irqmask); -- cgit v1.2.3 From 393e5e24165d0bef60489ecd0baef085e9af2e5a Mon Sep 17 00:00:00 2001 From: Ulf Hansson Date: Tue, 13 Dec 2011 17:08:04 +0100 Subject: ARM: 7230/1: mmc: mmci: Fix PIO read for small SDIO packets Corrects a bug in MMCI host driver which silently causes small reads (< 4 bytes as only used in SDIO) from PL-18X to fail. Signed-off-by: Stefan Nilsson XK Signed-off-by: Ulf Hansson Signed-off-by: Fredrik Soderstedt Signed-off-by: Russell King --- drivers/mmc/host/mmci.c | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) (limited to 'drivers/mmc/host/mmci.c') diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c index b09ccb7223e5..1f8832699cdf 100644 --- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c @@ -794,7 +794,24 @@ static int mmci_pio_read(struct mmci_host *host, char *buffer, unsigned int rema if (count <= 0) break; - readsl(base + MMCIFIFO, ptr, count >> 2); + /* + * SDIO especially may want to send something that is + * not divisible by 4 (as opposed to card sectors + * etc). Therefore make sure to always read the last bytes + * while only doing full 32-bit reads towards the FIFO. + */ + if (unlikely(count & 0x3)) { + if (count < 4) { + unsigned char buf[4]; + readsl(base + MMCIFIFO, buf, 1); + memcpy(ptr, buf, count); + } else { + readsl(base + MMCIFIFO, ptr, count >> 2); + count &= ~0x3; + } + } else { + readsl(base + MMCIFIFO, ptr, count >> 2); + } ptr += count; remain -= count; -- cgit v1.2.3 From 023f117c547719fbc087ad72276aec5a026370df Mon Sep 17 00:00:00 2001 From: Russell King Date: Sun, 18 Dec 2011 11:31:51 +0000 Subject: ARM: amba: make irq 0 invalid Fix core bus and MMCI such that irq 0 means that there is no IRQ attached. Signed-off-by: Russell King --- drivers/mmc/host/mmci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/mmc/host/mmci.c') diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c index 0d955ffaf44e..304f2f98b680 100644 --- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c @@ -1325,7 +1325,7 @@ static int __devinit mmci_probe(struct amba_device *dev, if (ret) goto unmap; - if (dev->irq[1] == NO_IRQ) + if (dev->irq[1] == NO_IRQ || !dev->irq[1]) host->singleirq = true; else { ret = request_irq(dev->irq[1], mmci_pio_irq, IRQF_SHARED, -- cgit v1.2.3 From 7437cfa532842ce75189826742bddf1ba137f58e Mon Sep 17 00:00:00 2001 From: Ulf Hansson Date: Wed, 18 Jan 2012 09:17:27 +0100 Subject: ARM: 7280/1: mmc: mmci: Cache MMCICLOCK and MMCIPOWER register Instead of reading a register value everytime we need to apply a new value for it, maintain a cached copy for it. This also means we are able to skip writes that are not needed. Tested-by: Linus Walleij Signed-off-by: Ulf Hansson Signed-off-by: Linus Walleij Signed-off-by: Russell King --- drivers/mmc/host/mmci.c | 41 +++++++++++++++++++++++++++++------------ 1 file changed, 29 insertions(+), 12 deletions(-) (limited to 'drivers/mmc/host/mmci.c') diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c index 1f8832699cdf..f36d8b8c891f 100644 --- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c @@ -118,6 +118,28 @@ static struct variant_data variant_ux500v2 = { .signal_direction = true, }; +/* + * This must be called with host->lock held + */ +static void mmci_write_clkreg(struct mmci_host *host, u32 clk) +{ + if (host->clk_reg != clk) { + host->clk_reg = clk; + writel(clk, host->base + MMCICLOCK); + } +} + +/* + * This must be called with host->lock held + */ +static void mmci_write_pwrreg(struct mmci_host *host, u32 pwr) +{ + if (host->pwr_reg != pwr) { + host->pwr_reg = pwr; + writel(pwr, host->base + MMCIPOWER); + } +} + /* * This must be called with host->lock held */ @@ -165,7 +187,7 @@ static void mmci_set_clkreg(struct mmci_host *host, unsigned int desired) if (host->mmc->ios.bus_width == MMC_BUS_WIDTH_8) clk |= MCI_ST_8BIT_BUS; - writel(clk, host->base + MMCICLOCK); + mmci_write_clkreg(host, clk); } static void @@ -846,14 +868,13 @@ static int mmci_pio_write(struct mmci_host *host, char *buffer, unsigned int rem */ if (variant->sdio && mmc_card_sdio(host->mmc->card)) { + u32 clk; if (count < 8) - writel(readl(host->base + MMCICLOCK) & - ~variant->clkreg_enable, - host->base + MMCICLOCK); + clk = host->clk_reg & ~variant->clkreg_enable; else - writel(readl(host->base + MMCICLOCK) | - variant->clkreg_enable, - host->base + MMCICLOCK); + clk = host->clk_reg | variant->clkreg_enable; + + mmci_write_clkreg(host, clk); } /* @@ -1114,11 +1135,7 @@ static void mmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) spin_lock_irqsave(&host->lock, flags); mmci_set_clkreg(host, ios->clock); - - if (host->pwr != pwr) { - host->pwr = pwr; - writel(pwr, host->base + MMCIPOWER); - } + mmci_write_pwrreg(host, pwr); spin_unlock_irqrestore(&host->lock, flags); -- cgit v1.2.3 From 258aea76f552cc755da92e7e823abbb85e021514 Mon Sep 17 00:00:00 2001 From: Viresh Kumar Date: Wed, 1 Feb 2012 16:12:19 +0530 Subject: dmaengine: Pass dma_slave_config .device_fc = NULL for all existing users .device_fc is added in struct dma_slave_config recently. All user drivers, which want DMA to be the flow controller must pass this field as false. As earlier driver don't look to use this feature, mark it false for now. Signed-off-by: Viresh Kumar Acked-by: Linus Walleij Signed-off-by: Vinod Koul --- drivers/mmc/host/mmci.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers/mmc/host/mmci.c') diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c index 0d955ffaf44e..a09c06ba046c 100644 --- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include @@ -370,6 +371,7 @@ static int mmci_dma_prep_data(struct mmci_host *host, struct mmc_data *data, .dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES, .src_maxburst = variant->fifohalfsize >> 2, /* # of words */ .dst_maxburst = variant->fifohalfsize >> 2, /* # of words */ + .device_fc = false, }; struct dma_chan *chan; struct dma_device *device; -- cgit v1.2.3 From 8f7f6b7e46117edb83d12a508fffa0f013457677 Mon Sep 17 00:00:00 2001 From: Will Deacon Date: Fri, 24 Feb 2012 11:25:21 +0000 Subject: mmc: mmci: reduce max_blk_count to avoid overflowing max_req_size On a system with large pages (64k in my case), the following BUG is triggered in MMC core: [ 2.338023] BUG: failure at drivers/mmc/core/core.c:221/mmc_start_request()! [ 2.338102] Kernel panic - not syncing: BUG! [ 2.338155] Call trace: [ 2.338228] [] dump_backtrace+0x0/0x120 [ 2.338317] [] dump_stack+0x14/0x1c [ 2.338403] [] panic+0xbc/0x1f0 [ 2.338498] [] mmc_start_request+0x154/0x184 [ 2.338600] [] mmc_start_req+0x110/0x140 [ 2.338701] [] mmc_blk_issue_rw_rq+0x7c/0x39c [ 2.338804] [] mmc_blk_issue_rq+0x1c0/0x468 [ 2.338905] [] mmc_queue_thread+0x68/0x118 [ 2.338995] [] kthread+0x84/0x8c This is because of a 64k request with a max_req_size of 64k-1 bytes. The following patch fixes the problem by limiting the max_blk_count such that max_blk_count * max_blk_size == max_req_size. I couldn't pursuade the compiler to emit a shift instead of a div without encoding the shift explicitly. Signed-off-by: Will Deacon Signed-off-by: Chris Ball --- drivers/mmc/host/mmci.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'drivers/mmc/host/mmci.c') diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c index 0d955ffaf44e..11e589cd8233 100644 --- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c @@ -1271,12 +1271,13 @@ static int __devinit mmci_probe(struct amba_device *dev, /* * Block size can be up to 2048 bytes, but must be a power of two. */ - mmc->max_blk_size = 2048; + mmc->max_blk_size = 1 << 11; /* - * No limit on the number of blocks transferred. + * Limit the number of blocks transferred so that we don't overflow + * the maximum request size. */ - mmc->max_blk_count = mmc->max_req_size; + mmc->max_blk_count = mmc->max_req_size >> 11; spin_lock_init(&host->lock); -- cgit v1.2.3 From 9e5ed094c89e55fbf11d2e81d60be98eb12346c0 Mon Sep 17 00:00:00 2001 From: viresh kumar Date: Thu, 15 Mar 2012 10:40:38 +0100 Subject: ARM: 7362/1: AMBA: Add module_amba_driver() helper macro for amba_driver For simple modules that contain a single amba_driver without any additional setup code then ends up being a block of duplicated boilerplate. This patch adds a new macro, module_amba_driver(), which replaces the module_init()/module_exit() registrations with template functions. Signed-off-by: Viresh Kumar Signed-off-by: Russell King --- drivers/mmc/host/mmci.c | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) (limited to 'drivers/mmc/host/mmci.c') diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c index 304f2f98b680..6692392c05dd 100644 --- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c @@ -1519,18 +1519,8 @@ static struct amba_driver mmci_driver = { .id_table = mmci_ids, }; -static int __init mmci_init(void) -{ - return amba_driver_register(&mmci_driver); -} - -static void __exit mmci_exit(void) -{ - amba_driver_unregister(&mmci_driver); -} +module_amba_driver(mmci_driver); -module_init(mmci_init); -module_exit(mmci_exit); module_param(fmax, uint, 0444); MODULE_DESCRIPTION("ARM PrimeCell PL180/181 Multimedia Card Interface driver"); -- cgit v1.2.3 From 16052827d98fbc13c31ebad560af4bd53e2b4dd5 Mon Sep 17 00:00:00 2001 From: Alexandre Bounine Date: Thu, 8 Mar 2012 16:11:18 -0500 Subject: dmaengine/dma_slave: introduce inline wrappers Add inline wrappers for device_prep_slave_sg() and device_prep_dma_cyclic() interfaces to hide new parameter from current users of affected interfaces. Convert current users to use new wrappers instead of direct calls. Suggested by Russell King [https://lkml.org/lkml/2012/2/3/269]. Signed-off-by: Alexandre Bounine Signed-off-by: Vinod Koul --- drivers/mmc/host/mmci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/mmc/host/mmci.c') diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c index a09c06ba046c..c55f9663eb13 100644 --- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c @@ -413,7 +413,7 @@ static int mmci_dma_prep_data(struct mmci_host *host, struct mmc_data *data, return -EINVAL; dmaengine_slave_config(chan, &conf); - desc = device->device_prep_slave_sg(chan, data->sg, nr_sg, + desc = dmaengine_prep_slave_sg(chan, data->sg, nr_sg, conf.direction, DMA_CTRL_ACK); if (!desc) goto unmap_exit; -- cgit v1.2.3