diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2013-05-04 13:45:17 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-05-04 13:45:17 -0700 |
commit | 173192958d06b8d1eb44f56d74373052ad6a9a60 (patch) | |
tree | 838a4f063c994d4d0a6259a85f21005c4098b752 | |
parent | e72a5d1ceb1c5cbe39c35c1c7a7f5909cbe8451a (diff) | |
parent | e4404fab2e0b70287a471a1e760c9338ce683fde (diff) |
Merge tag 'mmc-updates-for-3.10-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/cjb/mmc
Pull MMC update from Chris Ball:
"MMC highlights for 3.10:
Core:
- Introduce MMC_CAP2_NO_PRESCAN_POWERUP to allow skipping
mmc_power_up() at boot/initialization time if it's already
happened, for performance (faster boot time) reasons.
- Fix a bit width test failure that resulted in old eMMC cards being
put into 1-bit mode when 4-bit mode was available.
- Expose fwrev/hwrev for MMCv4 parts.
- Improve card removal logic in the case where the card's removed
slowly; we were missing card removal events if the card retained
contact with the slot pads for long enough to reply to a CMD13
while being removed.
Drivers:
- davinci_mmc: Support using PIO instead of DMA.
- dw_mmc: Add support for Exynos4412.
- mxcmmc: DT support, use slot-gpio API.
- mxs-mmc: Add broken-cd/cd-inverted/non-removable DT property
support.
- sdhci-sirf: New sdhci-pltfm driver for CSR SiRF SoCs:
SiRFprimaII: unicore ARM Cortex-A9
SiRFatlas6: unicore ARM Cortex-A9
SiRFmarco: dual core ARM Cortex-A9 SMP
- sdhci-tegra: Add support for Tegra114 platforms, use
mmc_of_parse()"
* tag 'mmc-updates-for-3.10-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/cjb/mmc: (66 commits)
mmc: sdhci-tegra: fix MODULE_DEVICE_TABLE
mmc: core: fix init controller performance regression, updated patch
mmc: mxcmmc: enable DMA support on mpc512x
mmc: mxcmmc: constify mxcmci_devtype
mmc: mxcmmc: use slot-gpio API for write-protect detection
mmc: mxcmmc: add mpc512x SDHC support
mmc: mxcmmc: fix race conditions for host->req and host->data access
mmc: mxcmmc: DT support
mmc: dw_mmc: let device core setup the default pin configuration
mmc: mxs-mmc: add broken-cd property
mmc: mxs-mmc: add non-removable property
mmc: mxs-mmc: add cd-inverted property
mmc: core: call pm_runtime_put_noidle in pm_runtime_get_sync failed case
mmc: mxcmmc: Fix bug when card is present during boot
mmc: core: fix performance regression initializing MMC host controllers
Revert "mmc: core: wait while adding MMC host to ensure root mounts successfully"
mmc: atmel-mci: pio hang on block errors
mmc: core: Fix bit width test failing on old eMMC cards
mmc: dw_mmc: Use pr_info instead of printk
mmc: dw_mmc: Check return value of regulator_enable
...
49 files changed, 824 insertions, 547 deletions
diff --git a/Documentation/devicetree/bindings/mmc/fsl-imx-mmc.txt b/Documentation/devicetree/bindings/mmc/fsl-imx-mmc.txt new file mode 100644 index 00000000000..db442355cd2 --- /dev/null +++ b/Documentation/devicetree/bindings/mmc/fsl-imx-mmc.txt @@ -0,0 +1,24 @@ +* Freescale Secure Digital Host Controller for i.MX2/3 series + +This file documents differences to the properties defined in mmc.txt. + +Required properties: +- compatible : Should be "fsl,<chip>-mmc", chip can be imx21 or imx31 + +Optional properties: +- dmas: One DMA phandle with arguments as defined by the devicetree bindings + of the used DMA controller. +- dma-names: Has to be "rx-tx". + +Example: + +sdhci1: sdhci@10014000 { + compatible = "fsl,imx27-mmc", "fsl,imx21-mmc"; + reg = <0x10014000 0x1000>; + interrupts = <11>; + dmas = <&dma 7>; + dma-names = "rx-tx"; + bus-width = <4>; + cd-gpios = <&gpio3 29>; + status = "okay"; +}; diff --git a/Documentation/devicetree/bindings/mmc/samsung-sdhci.txt b/Documentation/devicetree/bindings/mmc/samsung-sdhci.txt index 3b3a1ee055f..328e990d254 100644 --- a/Documentation/devicetree/bindings/mmc/samsung-sdhci.txt +++ b/Documentation/devicetree/bindings/mmc/samsung-sdhci.txt @@ -5,13 +5,6 @@ MMC, SD and eMMC storage mediums. This file documents differences between the core mmc properties described by mmc.txt and the properties used by the Samsung implmentation of the SDHCI controller. -Note: The mmc core bindings documentation states that if none of the core -card-detect bindings are used, then the standard sdhci card detect mechanism -is used. The Samsung's SDHCI controller bindings extends this as listed below. - -[A] The property "samsung,cd-pinmux-gpio" can be used as stated in the - "Optional Board Specific Properties" section below. - Required SoC Specific Properties: - compatible: should be one of the following - "samsung,s3c6410-sdhci": For controllers compatible with s3c6410 sdhci @@ -20,18 +13,8 @@ Required SoC Specific Properties: controller. Required Board Specific Properties: -- Samsung GPIO variant (will be completely replaced by pinctrl): - - gpios: Should specify the gpios used for clock, command and data lines. The - gpio specifier format depends on the gpio controller. -- Pinctrl variant (preferred if available): - - pinctrl-0: Should specify pin control groups used for this controller. - - pinctrl-names: Should contain only one value - "default". - -Optional Board Specific Properties: -- samsung,cd-pinmux-gpio: Specifies the card detect line that is routed - through a pinmux to the card-detect pin of the card slot. This property - should be used only if none of the mmc core card-detect properties are - used. Only for Samsung GPIO variant. +- pinctrl-0: Should specify pin control groups used for this controller. +- pinctrl-names: Should contain only one value - "default". Example: sdhci@12530000 { @@ -39,19 +22,9 @@ Example: reg = <0x12530000 0x100>; interrupts = <0 75 0>; bus-width = <4>; - cd-gpios = <&gpk2 2 2 3 3>; - - /* Samsung GPIO variant */ - gpios = <&gpk2 0 2 0 3>, /* clock line */ - <&gpk2 1 2 0 3>, /* command line */ - <&gpk2 3 2 3 3>, /* data line 0 */ - <&gpk2 4 2 3 3>, /* data line 1 */ - <&gpk2 5 2 3 3>, /* data line 2 */ - <&gpk2 6 2 3 3>; /* data line 3 */ - - /* Pinctrl variant */ - pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus4>; + cd-gpios = <&gpk2 2 0>; pinctrl-names = "default"; + pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus4>; }; Note: This example shows both SoC specific and board specific properties diff --git a/Documentation/devicetree/bindings/mmc/sdhci-sirf.txt b/Documentation/devicetree/bindings/mmc/sdhci-sirf.txt new file mode 100644 index 00000000000..dd6ed464bcb --- /dev/null +++ b/Documentation/devicetree/bindings/mmc/sdhci-sirf.txt @@ -0,0 +1,18 @@ +* SiRFprimII/marco/atlas6 SDHCI Controller + +This file documents differences between the core properties in mmc.txt +and the properties used by the sdhci-sirf driver. + +Required properties: +- compatible: sirf,prima2-sdhc + +Optional properties: +- cd-gpios: card detect gpio, with zero flags. + +Example: + + sd0: sdhci@56000000 { + compatible = "sirf,prima2-sdhc"; + reg = <0xcd000000 0x100000>; + cd-gpios = <&gpio 6 0>; + }; diff --git a/Documentation/mmc/mmc-dev-attrs.txt b/Documentation/mmc/mmc-dev-attrs.txt index 0d98fac8893..189bab09255 100644 --- a/Documentation/mmc/mmc-dev-attrs.txt +++ b/Documentation/mmc/mmc-dev-attrs.txt @@ -22,6 +22,7 @@ All attributes are read-only. manfid Manufacturer ID (from CID Register) name Product Name (from CID Register) oemid OEM/Application ID (from CID Register) + prv Product Revision (from CID Register) (SD and MMCv4 only) serial Product Serial Number (from CID Register) erase_size Erase group size preferred_erase_size Preferred erase size diff --git a/MAINTAINERS b/MAINTAINERS index 59d708f2924..e1f5fac1838 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -801,6 +801,7 @@ S: Maintained F: arch/arm/mach-prima2/ F: drivers/dma/sirf-dma.c F: drivers/i2c/busses/i2c-sirf.c +F: drivers/mmc/host/sdhci-sirf.c F: drivers/pinctrl/pinctrl-sirf.c F: drivers/spi/spi-sirf.c diff --git a/arch/arm/configs/at91sam9g45_defconfig b/arch/arm/configs/at91sam9g45_defconfig index 5f551b76cb6..18964cdacd6 100644 --- a/arch/arm/configs/at91sam9g45_defconfig +++ b/arch/arm/configs/at91sam9g45_defconfig @@ -173,7 +173,6 @@ CONFIG_MMC=y # CONFIG_MMC_BLOCK_BOUNCE is not set CONFIG_SDIO_UART=m CONFIG_MMC_ATMELMCI=y -CONFIG_MMC_ATMELMCI_DMA=y CONFIG_LEDS_ATMEL_PWM=y CONFIG_LEDS_GPIO=y CONFIG_LEDS_TRIGGER_TIMER=y diff --git a/arch/avr32/configs/favr-32_defconfig b/arch/avr32/configs/favr-32_defconfig index 57788a42ff8..c90fbf6d35b 100644 --- a/arch/avr32/configs/favr-32_defconfig +++ b/arch/avr32/configs/favr-32_defconfig @@ -122,7 +122,6 @@ CONFIG_USB_G_SERIAL=m CONFIG_USB_CDC_COMPOSITE=m CONFIG_MMC=y CONFIG_MMC_ATMELMCI=y -CONFIG_MMC_ATMELMCI_DMA=y CONFIG_NEW_LEDS=y CONFIG_LEDS_CLASS=y CONFIG_LEDS_ATMEL_PWM=m diff --git a/arch/avr32/configs/merisc_defconfig b/arch/avr32/configs/merisc_defconfig index 3befab96682..65de4431108 100644 --- a/arch/avr32/configs/merisc_defconfig +++ b/arch/avr32/configs/merisc_defconfig @@ -102,7 +102,6 @@ CONFIG_FRAMEBUFFER_CONSOLE=y CONFIG_LOGO=y CONFIG_MMC=y CONFIG_MMC_ATMELMCI=y -CONFIG_MMC_ATMELMCI_DMA=y CONFIG_NEW_LEDS=y CONFIG_LEDS_CLASS=y CONFIG_LEDS_ATMEL_PWM=y diff --git a/arch/powerpc/boot/dts/mpc5121.dtsi b/arch/powerpc/boot/dts/mpc5121.dtsi index 2e82d0e71dd..bd14c00e514 100644 --- a/arch/powerpc/boot/dts/mpc5121.dtsi +++ b/arch/powerpc/boot/dts/mpc5121.dtsi @@ -152,6 +152,8 @@ compatible = "fsl,mpc5121-sdhc"; reg = <0x1500 0x100>; interrupts = <8 0x8>; + dmas = <&dma0 30>; + dma-names = "rx-tx"; }; i2c@1700 { diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c index 5bab73b91c2..e12a03cc2a6 100644 --- a/drivers/mmc/card/block.c +++ b/drivers/mmc/card/block.c @@ -1932,8 +1932,14 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req) } out: - if (!req && !(mq->flags & MMC_QUEUE_NEW_REQUEST)) - /* release host only when there are no more requests */ + if ((!req && !(mq->flags & MMC_QUEUE_NEW_REQUEST)) || + (req && (req->cmd_flags & MMC_REQ_SPECIAL_MASK))) + /* + * Release host when there are no more requests + * and after special request(discard, flush) is done. + * In case sepecial request, there is no reentry to + * the 'mmc_blk_issue_rq' with 'mqrq_prev->req'. + */ mmc_release_host(card->host); return ret; } diff --git a/drivers/mmc/card/queue.c b/drivers/mmc/card/queue.c index fa4e44ee796..9447a0e970d 100644 --- a/drivers/mmc/card/queue.c +++ b/drivers/mmc/card/queue.c @@ -22,9 +22,6 @@ #define MMC_QUEUE_BOUNCESZ 65536 - -#define MMC_REQ_SPECIAL_MASK (REQ_DISCARD | REQ_FLUSH) - /* * Prepare a MMC request. This just filters out odd stuff. */ diff --git a/drivers/mmc/card/queue.h b/drivers/mmc/card/queue.h index 031bf6376c9..5752d50049a 100644 --- a/drivers/mmc/card/queue.h +++ b/drivers/mmc/card/queue.h @@ -1,6 +1,8 @@ #ifndef MMC_QUEUE_H #define MMC_QUEUE_H +#define MMC_REQ_SPECIAL_MASK (REQ_DISCARD | REQ_FLUSH) + struct request; struct task_struct; diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index 9290bb51a06..c40396f2320 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c @@ -2289,6 +2289,19 @@ int _mmc_detect_card_removed(struct mmc_host *host) return 1; ret = host->bus_ops->alive(host); + + /* + * Card detect status and alive check may be out of sync if card is + * removed slowly, when card detect switch changes while card/slot + * pads are still contacted in hardware (refer to "SD Card Mechanical + * Addendum, Appendix C: Card Detection Switch"). So reschedule a + * detect work 200ms later for this case. + */ + if (!ret && host->ops->get_cd && !host->ops->get_cd(host)) { + mmc_detect_change(host, msecs_to_jiffies(200)); + pr_debug("%s: card removed too slowly\n", mmc_hostname(host)); + } + if (ret) { mmc_card_set_removed(host->card); pr_debug("%s: card remove detected\n", mmc_hostname(host)); @@ -2403,7 +2416,10 @@ void mmc_start_host(struct mmc_host *host) { host->f_init = max(freqs[0], host->f_min); host->rescan_disable = 0; - mmc_power_up(host); + if (host->caps2 & MMC_CAP2_NO_PRESCAN_POWERUP) + mmc_power_off(host); + else + mmc_power_up(host); mmc_detect_change(host, 0); } diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c index c8f3d6e0684..0cbd1effe96 100644 --- a/drivers/mmc/core/mmc.c +++ b/drivers/mmc/core/mmc.c @@ -96,6 +96,7 @@ static int mmc_decode_cid(struct mmc_card *card) card->cid.prod_name[3] = UNSTUFF_BITS(resp, 72, 8); card->cid.prod_name[4] = UNSTUFF_BITS(resp, 64, 8); card->cid.prod_name[5] = UNSTUFF_BITS(resp, 56, 8); + card->cid.prv = UNSTUFF_BITS(resp, 48, 8); card->cid.serial = UNSTUFF_BITS(resp, 16, 32); card->cid.month = UNSTUFF_BITS(resp, 12, 4); card->cid.year = UNSTUFF_BITS(resp, 8, 4) + 1997; @@ -368,13 +369,13 @@ static int mmc_read_ext_csd(struct mmc_card *card, u8 *ext_csd) ext_csd[EXT_CSD_SEC_FEATURE_SUPPORT]; card->ext_csd.raw_trim_mult = ext_csd[EXT_CSD_TRIM_MULT]; + card->ext_csd.raw_partition_support = ext_csd[EXT_CSD_PARTITION_SUPPORT]; if (card->ext_csd.rev >= 4) { /* * Enhanced area feature support -- check whether the eMMC * card has the Enhanced area enabled. If so, export enhanced * area offset and size to user by adding sysfs interface. */ - card->ext_csd.raw_partition_support = ext_csd[EXT_CSD_PARTITION_SUPPORT]; if ((ext_csd[EXT_CSD_PARTITION_SUPPORT] & 0x2) && (ext_csd[EXT_CSD_PARTITION_ATTRIBUTE] & 0x1)) { hc_erase_grp_sz = @@ -627,6 +628,7 @@ MMC_DEV_ATTR(hwrev, "0x%x\n", card->cid.hwrev); MMC_DEV_ATTR(manfid, "0x%06x\n", card->cid.manfid); MMC_DEV_ATTR(name, "%s\n", card->cid.prod_name); MMC_DEV_ATTR(oemid, "0x%04x\n", card->cid.oemid); +MMC_DEV_ATTR(prv, "0x%x\n", card->cid.prv); MMC_DEV_ATTR(serial, "0x%08x\n", card->cid.serial); MMC_DEV_ATTR(enhanced_area_offset, "%llu\n", card->ext_csd.enhanced_area_offset); @@ -645,6 +647,7 @@ static struct attribute *mmc_std_attrs[] = { &dev_attr_manfid.attr, &dev_attr_name.attr, &dev_attr_oemid.attr, + &dev_attr_prv.attr, &dev_attr_serial.attr, &dev_attr_enhanced_area_offset.attr, &dev_attr_enhanced_area_size.attr, diff --git a/drivers/mmc/core/sdio.c b/drivers/mmc/core/sdio.c index aa0719a4dfd..6889a821c1d 100644 --- a/drivers/mmc/core/sdio.c +++ b/drivers/mmc/core/sdio.c @@ -861,8 +861,10 @@ static void mmc_sdio_detect(struct mmc_host *host) /* Make sure card is powered before detecting it */ if (host->caps & MMC_CAP_POWER_OFF_CARD) { err = pm_runtime_get_sync(&host->card->dev); - if (err < 0) + if (err < 0) { + pm_runtime_put_noidle(&host->card->dev); goto out; + } } mmc_claim_host(host); diff --git a/drivers/mmc/core/sdio_bus.c b/drivers/mmc/core/sdio_bus.c index 5e57048e2c1..546c67c2bbb 100644 --- a/drivers/mmc/core/sdio_bus.c +++ b/drivers/mmc/core/sdio_bus.c @@ -16,6 +16,7 @@ #include <linux/export.h> #include <linux/slab.h> #include <linux/pm_runtime.h> +#include <linux/acpi.h> #include <linux/mmc/card.h> #include <linux/mmc/host.h> @@ -137,7 +138,7 @@ static int sdio_bus_probe(struct device *dev) if (func->card->host->caps & MMC_CAP_POWER_OFF_CARD) { ret = pm_runtime_get_sync(dev); if (ret < 0) - goto out; + goto disable_runtimepm; } /* Set the default block size so the driver is sure it's something @@ -157,7 +158,6 @@ static int sdio_bus_probe(struct device *dev) disable_runtimepm: if (func->card->host->caps & MMC_CAP_POWER_OFF_CARD) pm_runtime_put_noidle(dev); -out: return ret; } @@ -299,6 +299,19 @@ struct sdio_func *sdio_alloc_func(struct mmc_card *card) return func; } +#ifdef CONFIG_ACPI +static void sdio_acpi_set_handle(struct sdio_func *func) +{ + struct mmc_host *host = func->card->host; + u64 addr = (host->slotno << 16) | func->num; + + ACPI_HANDLE_SET(&func->dev, + acpi_get_child(ACPI_HANDLE(host->parent), addr)); +} +#else +static inline void sdio_acpi_set_handle(struct sdio_func *func) {} +#endif + /* * Register a new SDIO function with the driver model. */ @@ -308,9 +321,12 @@ int sdio_add_func(struct sdio_func *func) dev_set_name(&func->dev, "%s:%d", mmc_card_id(func->card), func->num); + sdio_acpi_set_handle(func); ret = device_add(&func->dev); - if (ret == 0) + if (ret == 0) { sdio_func_set_present(func); + acpi_dev_pm_attach(&func->dev, false); + } return ret; } @@ -326,6 +342,7 @@ void sdio_remove_func(struct sdio_func *func) if (!sdio_func_present(func)) return; + acpi_dev_pm_detach(&func->dev, false); device_del(&func->dev); put_device(&func->dev); } diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig index d88219e1d86..9ab8f8dee94 100644 --- a/drivers/mmc/host/Kconfig +++ b/drivers/mmc/host/Kconfig @@ -190,6 +190,17 @@ config MMC_SDHCI_S3C If unsure, say N. +config MMC_SDHCI_SIRF + tristate "SDHCI support on CSR SiRFprimaII and SiRFmarco SoCs" + depends on ARCH_SIRF + depends on MMC_SDHCI_PLTFM + help + This selects the SDHCI support for SiRF System-on-Chip devices. + + If you have a controller with this interface, say Y or M here. + + If unsure, say N. + config MMC_SDHCI_PXAV3 tristate "Marvell MMP2 SD Host Controller support (PXAV3)" depends on CLKDEV_LOOKUP @@ -300,16 +311,6 @@ config MMC_ATMELMCI If unsure, say N. -config MMC_ATMELMCI_DMA - bool "Atmel MCI DMA support" - depends on MMC_ATMELMCI && (AVR32 || ARCH_AT91SAM9G45) && DMA_ENGINE - help - Say Y here to have the Atmel MCI driver use a DMA engine to - do data transfers and thus increase the throughput and - reduce the CPU utilization. - - If unsure, say N. - config MMC_MSM tristate "Qualcomm SDCC Controller Support" depends on MMC && ARCH_MSM @@ -319,12 +320,12 @@ config MMC_MSM support for SDIO devices. config MMC_MXC - tristate "Freescale i.MX21/27/31 Multimedia Card Interface support" - depends on ARCH_MXC + tristate "Freescale i.MX21/27/31 or MPC512x Multimedia Card support" + depends on ARCH_MXC || PPC_MPC512x help - This selects the Freescale i.MX21, i.MX27 and i.MX31 Multimedia card - Interface. If you have a i.MX platform with a Multimedia Card slot, - say Y or M here. + This selects the Freescale i.MX21, i.MX27, i.MX31 or MPC512x + Multimedia Card Interface. If you have an i.MX or MPC512x platform + with a Multimedia Card slot, say Y or M here. If unsure, say N. diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile index c380e3cf0a3..cd322807555 100644 --- a/drivers/mmc/host/Makefile +++ b/drivers/mmc/host/Makefile @@ -13,6 +13,7 @@ obj-$(CONFIG_MMC_SDHCI_ACPI) += sdhci-acpi.o obj-$(CONFIG_MMC_SDHCI_PXAV3) += sdhci-pxav3.o obj-$(CONFIG_MMC_SDHCI_PXAV2) += sdhci-pxav2.o obj-$(CONFIG_MMC_SDHCI_S3C) += sdhci-s3c.o +obj-$(CONFIG_MMC_SDHCI_SIRF) += sdhci-sirf.o obj-$(CONFIG_MMC_SDHCI_SPEAR) += sdhci-spear.o obj-$(CONFIG_MMC_WBSD) += wbsd.o obj-$(CONFIG_MMC_AU1X) += au1xmmc.o diff --git a/drivers/mmc/host/android-goldfish.c b/drivers/mmc/host/android-goldfish.c index ef3aef0f376..7780c14704c 100644 --- a/drivers/mmc/host/android-goldfish.c +++ b/drivers/mmc/host/android-goldfish.c @@ -476,7 +476,7 @@ static int goldfish_mmc_probe(struct platform_device *pdev) host->mmc = mmc; pr_err("mmc: Mapping %lX to %lX\n", (long)res->start, (long)res->end); - host->reg_base = ioremap(res->start, res->end - res->start + 1); + host->reg_base = ioremap(res->start, resource_size(res)); if (host->reg_base == NULL) { ret = -ENOMEM; goto ioremap_failed; diff --git a/drivers/mmc/host/atmel-mci.c b/drivers/mmc/host/atmel-mci.c index 722af1de796..e75774f7260 100644 --- a/drivers/mmc/host/atmel-mci.c +++ b/drivers/mmc/host/atmel-mci.c @@ -178,6 +178,7 @@ struct atmel_mci { void __iomem *regs; struct scatterlist *sg; + unsigned int sg_len; unsigned int pio_offset; unsigned int *buffer; unsigned int buf_size; @@ -892,6 +893,7 @@ static u32 atmci_prepare_data(struct atmel_mci *host, struct mmc_data *data) data->error = -EINPROGRESS; host->sg = data->sg; + host->sg_len = data->sg_len; host->data = data; host->data_chan = NULL; @@ -1826,7 +1828,8 @@ static void atmci_read_data_pio(struct atmel_mci *host) if (offset == sg->length) { flush_dcache_page(sg_page(sg)); host->sg = sg = sg_next(sg); - if (!sg) + host->sg_len--; + if (!sg || !host->sg_len) goto done; offset = 0; @@ -1839,7 +1842,8 @@ static void atmci_read_data_pio(struct atmel_mci *host) flush_dcache_page(sg_page(sg)); host->sg = sg = sg_next(sg); - if (!sg) + host->sg_len--; + if (!sg || !host->sg_len) goto done; offset = 4 - remaining; @@ -1890,7 +1894,8 @@ static void atmci_write_data_pio(struct atmel_mci *host) nbytes += 4; if (offset == sg->length) { host->sg = sg = sg_next(sg); - if (!sg) + host->sg_len--; + if (!sg || !host->sg_len) goto done; offset = 0; @@ -1904,7 +1909,8 @@ static void atmci_write_data_pio(struct atmel_mci *host) nbytes += remaining; host->sg = sg = sg_next(sg); - if (!sg) { + host->sg_len--; + if (!sg || !host->sg_len) { atmci_writel(host, ATMCI_TDR, value); goto done; } @@ -2487,10 +2493,8 @@ static int __exit atmci_remove(struct platform_device *pdev) atmci_readl(host, ATMCI_SR); clk_disable(host->mck); -#ifdef CONFIG_MMC_ATMELMCI_DMA if (host->dma.chan) dma_release_channel(host->dma.chan); -#endif free_irq(platform_get_irq(pdev, 0), host); iounmap(host->regs); diff --git a/drivers/mmc/host/davinci_mmc.c b/drivers/mmc/host/davinci_mmc.c index f8a96d652e9..3946a0eb3a0 100644 --- a/drivers/mmc/host/davinci_mmc.c +++ b/drivers/mmc/host/davinci_mmc.c @@ -1264,13 +1264,15 @@ static int __init davinci_mmcsd_probe(struct platform_device *pdev) r = platform_get_resource(pdev, IORESOURCE_DMA, 0); if (!r) - goto out; - host->rxdma = r->start; + dev_ |