RE: [PATCH RESEND v7 1/2] block: ioctl support for sanitize in eMMC 4.5
Hi Jens, The sanitize feature is a mandatory feature for eMMC4.5. This feature requires changes in the block and MMC layers to allow the ability to trigger the sanitize request. Chris Ball agreed to merge the MMC changes of this patch but due to the dependency on the block layer it is on hold for more than 6 months. Our previous requests to you to merge the block layer patches were not replied. If you see any issues that prevents this patch from being merged into the block layer please let us know. Otherwise, we would like to push this patch ASAP. Thanks, Maya -Original Message- From: linux-mmc-ow...@vger.kernel.org [mailto:linux-mmc-ow...@vger.kernel.org] On Behalf Of Yaniv Gardi Sent: Thursday, June 28, 2012 11:33 AM To: linux-mmc@vger.kernel.org Cc: yga...@codeaurora.org; me...@codeaurora.org; linux-arm-...@vger.kernel.org; open list Subject: [PATCH RESEND v7 1/2] block: ioctl support for sanitize in eMMC 4.5 Adding a new ioctl to support sanitize operation in eMMC cards version 4.5. The sanitize ioctl support helps performing this operation via user application. Signed-off-by: Yaniv Gardi yga...@codeaurora.org --- block/blk-core.c | 15 ++-- block/blk-lib.c | 51 + block/blk-merge.c |4 +++ block/elevator.c |2 +- block/ioctl.c |9 include/linux/blk_types.h |5 +++- include/linux/blkdev.h|3 ++ include/linux/fs.h|1 + kernel/trace/blktrace.c |2 + 9 files changed, 87 insertions(+), 5 deletions(-) diff --git a/block/blk-core.c b/block/blk-core.c index 3c923a7..4a56102b 100644 --- a/block/blk-core.c +++ b/block/blk-core.c @@ -1641,7 +1641,7 @@ generic_make_request_checks(struct bio *bio) goto end_io; } - if (unlikely(!(bio-bi_rw REQ_DISCARD) + if (unlikely(!(bio-bi_rw (REQ_DISCARD | REQ_SANITIZE)) nr_sectors queue_max_hw_sectors(q))) { printk(KERN_ERR bio too big device %s (%u %u)\n, bdevname(bio-bi_bdev, b), @@ -1689,6 +1689,14 @@ generic_make_request_checks(struct bio *bio) goto end_io; } + if ((bio-bi_rw REQ_SANITIZE) + (!blk_queue_sanitize(q))) { + pr_info(%s - got a SANITIZE request but the queue + doesn't support sanitize requests, __func__); + err = -EOPNOTSUPP; + goto end_io; + } + if (blk_throtl_bio(q, bio)) return false; /* throttled, will be resubmitted later */ @@ -1794,7 +1802,8 @@ void submit_bio(int rw, struct bio *bio) * If it's a regular read/write or a barrier with data attached, * go through the normal accounting stuff before submission. */ - if (bio_has_data(bio) !(rw REQ_DISCARD)) { + if (bio_has_data(bio) + (!(rw (REQ_DISCARD | REQ_SANITIZE { if (rw WRITE) { count_vm_events(PGPGOUT, count); } else { @@ -1840,7 +1849,7 @@ EXPORT_SYMBOL(submit_bio); */ int blk_rq_check_limits(struct request_queue *q, struct request *rq) { - if (rq-cmd_flags REQ_DISCARD) + if (rq-cmd_flags (REQ_DISCARD | REQ_SANITIZE)) return 0; if (blk_rq_sectors(rq) queue_max_sectors(q) || diff --git a/block/blk-lib.c b/block/blk-lib.c index 2b461b4..280d63e 100644 --- a/block/blk-lib.c +++ b/block/blk-lib.c @@ -115,6 +115,57 @@ int blkdev_issue_discard(struct block_device *bdev, sector_t sector, EXPORT_SYMBOL(blkdev_issue_discard); /** + * blkdev_issue_sanitize - queue a sanitize request + * @bdev: blockdev to issue sanitize for + * @gfp_mask: memory allocation flags (for bio_alloc) + * + * Description: + *Issue a sanitize request for the specified block device + */ +int blkdev_issue_sanitize(struct block_device *bdev, gfp_t gfp_mask) { + DECLARE_COMPLETION_ONSTACK(wait); + struct request_queue *q = bdev_get_queue(bdev); + int type = REQ_WRITE | REQ_SANITIZE; + struct bio_batch bb; + struct bio *bio; + int ret = 0; + + if (!q) + return -ENXIO; + + if (!blk_queue_sanitize(q)) { + pr_err(%s - card doesn't support sanitize, __func__); + return -EOPNOTSUPP; + } + + bio = bio_alloc(gfp_mask, 1); + if (!bio) + return -ENOMEM; + + atomic_set(bb.done, 1); + bb.flags = 1 BIO_UPTODATE; + bb.wait = wait; + + bio-bi_end_io = bio_batch_end_io; + bio-bi_bdev = bdev; + bio-bi_private = bb; + + atomic_inc(bb.done); + submit_bio(type, bio); + + /* Wait for bios in-flight */ + if (!atomic_dec_and_test(bb.done)) + wait_for_completion(wait); + + if (!test_bit(BIO_UPTODATE, bb.flags)) + ret = -EIO; + + return ret; +}
[PATCH 18/33] mmc: Convert to devm_ioremap_resource()
Convert all uses of devm_request_and_ioremap() to the newly introduced devm_ioremap_resource() which provides more consistent error handling. devm_ioremap_resource() provides its own error messages so all explicit error messages can be removed from the failure code paths. Signed-off-by: Thierry Reding thierry.red...@avionic-design.de Cc: Chris Ball c...@laptop.org Cc: Ben Dooks ben-li...@fluff.org Cc: linux-mmc@vger.kernel.org --- drivers/mmc/host/dw_mmc-pltfm.c | 7 --- drivers/mmc/host/mxs-mmc.c | 6 +++--- drivers/mmc/host/sdhci-s3c.c| 7 +++ 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/drivers/mmc/host/dw_mmc-pltfm.c b/drivers/mmc/host/dw_mmc-pltfm.c index 5e1fb1d..41c27b7 100644 --- a/drivers/mmc/host/dw_mmc-pltfm.c +++ b/drivers/mmc/host/dw_mmc-pltfm.c @@ -10,6 +10,7 @@ * (at your option) any later version. */ +#include linux/err.h #include linux/interrupt.h #include linux/module.h #include linux/io.h @@ -46,9 +47,9 @@ int dw_mci_pltfm_register(struct platform_device *pdev, host-dev = pdev-dev; host-irq_flags = 0; host-pdata = pdev-dev.platform_data; - host-regs = devm_request_and_ioremap(pdev-dev, regs); - if (!host-regs) - return -ENOMEM; + host-regs = devm_ioremap_resource(pdev-dev, regs); + if (IS_ERR(host-regs)) + return PTR_ERR(host-regs); if (drv_data drv_data-init) { ret = drv_data-init(host); diff --git a/drivers/mmc/host/mxs-mmc.c b/drivers/mmc/host/mxs-mmc.c index 206fe49..5b66555 100644 --- a/drivers/mmc/host/mxs-mmc.c +++ b/drivers/mmc/host/mxs-mmc.c @@ -614,9 +614,9 @@ static int mxs_mmc_probe(struct platform_device *pdev) host = mmc_priv(mmc); ssp = host-ssp; ssp-dev = pdev-dev; - ssp-base = devm_request_and_ioremap(pdev-dev, iores); - if (!ssp-base) { - ret = -EADDRNOTAVAIL; + ssp-base = devm_ioremap_resource(pdev-dev, iores); + if (IS_ERR(ssp-base)) { + ret = PTR_ERR(ssp-base); goto out_mmc_free; } diff --git a/drivers/mmc/host/sdhci-s3c.c b/drivers/mmc/host/sdhci-s3c.c index 82a8de1..a0c6214 100644 --- a/drivers/mmc/host/sdhci-s3c.c +++ b/drivers/mmc/host/sdhci-s3c.c @@ -651,10 +651,9 @@ static int sdhci_s3c_probe(struct platform_device *pdev) #endif res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - host-ioaddr = devm_request_and_ioremap(pdev-dev, res); - if (!host-ioaddr) { - dev_err(dev, failed to map registers\n); - ret = -ENXIO; + host-ioaddr = devm_ioremap_resource(pdev-dev, res); + if (IS_ERR(host-ioaddr)) { + ret = PTR_ERR(host-ioaddr); goto err_req_regs; } -- 1.8.1.1 -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 6/6] mmc: dt: bus-width can be an optional property
None of mmc drivers implements bus-width as a required device tree property. Instead, some drivers like atmel-mci, dw_mmc, sdhci-s3c implement it as an optional one, and will force bus width to be 1 when the property is absent. Let's change the common binding to reflect what the drivers are usually doing. Signed-off-by: Shawn Guo shawn@linaro.org Cc: devicetree-disc...@lists.ozlabs.org --- Documentation/devicetree/bindings/mmc/mmc.txt |5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/Documentation/devicetree/bindings/mmc/mmc.txt b/Documentation/devicetree/bindings/mmc/mmc.txt index a591c67..cef217d 100644 --- a/Documentation/devicetree/bindings/mmc/mmc.txt +++ b/Documentation/devicetree/bindings/mmc/mmc.txt @@ -6,9 +6,6 @@ Interpreted by the OF core: - reg: Registers location and length. - interrupts: Interrupts used by the MMC controller. -Required properties: -- bus-width: Number of data lines, can be 1, 4, or 8 - Card detection: If no property below is supplied, standard SDHCI card detect is used. Only one of the properties in this section should be supplied: @@ -17,6 +14,8 @@ Only one of the properties in this section should be supplied: - non-removable: non-removable slot (like eMMC); assume always present. Optional properties: +- bus-width: Number of data lines, can be 1, 4, or 8. The default + will be 1 if the property is absent. - wp-gpios: Specify GPIOs for write protection, see gpio binding - cd-inverted: when present, polarity on the cd gpio line is inverted - wp-inverted: when present, polarity on the wp gpio line is inverted -- 1.7.9.5 -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 4/6] mmc: sdhci: rename platform_8bit_width to platform_bus_width
From: Sascha Hauer s.ha...@pengutronix.de The 8bit in the function name is misleading. When set, it will be used to set the bus width, regardless of whether 8bit or another bus width is requested, so change the function name to platform_bus_width. Signed-off-by: Sascha Hauer s.ha...@pengutronix.de Signed-off-by: Shawn Guo shawn@linaro.org --- drivers/mmc/host/sdhci-pci.c |4 ++-- drivers/mmc/host/sdhci-pxav2.c |2 +- drivers/mmc/host/sdhci-s3c.c |8 drivers/mmc/host/sdhci-tegra.c |4 ++-- drivers/mmc/host/sdhci.c |8 drivers/mmc/host/sdhci.h |2 +- 6 files changed, 14 insertions(+), 14 deletions(-) diff --git a/drivers/mmc/host/sdhci-pci.c b/drivers/mmc/host/sdhci-pci.c index c7dd0cb..c7ccf30 100644 --- a/drivers/mmc/host/sdhci-pci.c +++ b/drivers/mmc/host/sdhci-pci.c @@ -935,7 +935,7 @@ static int sdhci_pci_enable_dma(struct sdhci_host *host) return 0; } -static int sdhci_pci_8bit_width(struct sdhci_host *host, int width) +static int sdhci_pci_bus_width(struct sdhci_host *host, int width) { u8 ctrl; @@ -977,7 +977,7 @@ static void sdhci_pci_hw_reset(struct sdhci_host *host) static struct sdhci_ops sdhci_pci_ops = { .enable_dma = sdhci_pci_enable_dma, - .platform_8bit_width= sdhci_pci_8bit_width, + .platform_bus_width = sdhci_pci_bus_width, .hw_reset = sdhci_pci_hw_reset, }; diff --git a/drivers/mmc/host/sdhci-pxav2.c b/drivers/mmc/host/sdhci-pxav2.c index ac854aa..7e57565 100644 --- a/drivers/mmc/host/sdhci-pxav2.c +++ b/drivers/mmc/host/sdhci-pxav2.c @@ -121,7 +121,7 @@ static u32 pxav2_get_max_clock(struct sdhci_host *host) static struct sdhci_ops pxav2_sdhci_ops = { .get_max_clock = pxav2_get_max_clock, .platform_reset_exit = pxav2_set_private_registers, - .platform_8bit_width = pxav2_mmc_set_width, + .platform_bus_width = pxav2_mmc_set_width, }; #ifdef CONFIG_OF diff --git a/drivers/mmc/host/sdhci-s3c.c b/drivers/mmc/host/sdhci-s3c.c index 82a8de1..b16dae0 100644 --- a/drivers/mmc/host/sdhci-s3c.c +++ b/drivers/mmc/host/sdhci-s3c.c @@ -332,14 +332,14 @@ static void sdhci_cmu_set_clock(struct sdhci_host *host, unsigned int clock) } /** - * sdhci_s3c_platform_8bit_width - support 8bit buswidth + * sdhci_s3c_platform_bus_width - support 8bit buswidth * @host: The SDHCI host being queried * @width: MMC_BUS_WIDTH_ macro for the bus width being requested * * We have 8-bit width support but is not a v3 controller. - * So we add platform_8bit_width() and support 8bit width. + * So we add platform_bus_width() and support 8bit width. */ -static int sdhci_s3c_platform_8bit_width(struct sdhci_host *host, int width) +static int sdhci_s3c_platform_bus_width(struct sdhci_host *host, int width) { u8 ctrl; @@ -369,7 +369,7 @@ static struct sdhci_ops sdhci_s3c_ops = { .get_max_clock = sdhci_s3c_get_max_clk, .set_clock = sdhci_s3c_set_clock, .get_min_clock = sdhci_s3c_get_min_clock, - .platform_8bit_width= sdhci_s3c_platform_8bit_width, + .platform_bus_width = sdhci_s3c_platform_bus_width, }; static void sdhci_s3c_notify_change(struct platform_device *dev, int state) diff --git a/drivers/mmc/host/sdhci-tegra.c b/drivers/mmc/host/sdhci-tegra.c index 3695b2e..5a600a5 100644 --- a/drivers/mmc/host/sdhci-tegra.c +++ b/drivers/mmc/host/sdhci-tegra.c @@ -143,7 +143,7 @@ static void tegra_sdhci_reset_exit(struct sdhci_host *host, u8 mask) } } -static int tegra_sdhci_8bit(struct sdhci_host *host, int bus_width) +static int tegra_sdhci_buswidth(struct sdhci_host *host, int bus_width) { struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); struct sdhci_tegra *tegra_host = pltfm_host-priv; @@ -170,7 +170,7 @@ static struct sdhci_ops tegra_sdhci_ops = { .read_l = tegra_sdhci_readl, .read_w = tegra_sdhci_readw, .write_l= tegra_sdhci_writel, - .platform_8bit_width = tegra_sdhci_8bit, + .platform_bus_width = tegra_sdhci_buswidth, .platform_reset_exit = tegra_sdhci_reset_exit, }; diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index 336ab06..3bb9b88 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c @@ -1395,11 +1395,11 @@ static void sdhci_do_set_ios(struct sdhci_host *host, struct mmc_ios *ios) /* * If your platform has 8-bit width support but is not a v3 controller, * or if it requires special setup code, you should implement that in -* platform_8bit_width(). +* platform_bus_width(). */ - if (host-ops-platform_8bit_width) - host-ops-platform_8bit_width(host, ios-bus_width); - else { + if (host-ops-platform_bus_width) { + host-ops-platform_bus_width(host, ios-bus_width); + } else { ctrl = sdhci_readb(host,
[PATCH 1/6] mmc: sdhci-esdhc-imx: separate transfer mode from command write for usdhc
The combining of SDHCI_TRANSFER_MODE and SDHCI_COMMAND writes is only required for esdhc, but not necessarily for usdhc. Different from esdhc where the bits for transfer mode and command are all in the same register CMD_XFR_TYP, usdhc has a newly introduced register MIX_CTRL to hold transfer mode bits. So it makes more sense to separate transfer mode from command write for usdhc. Signed-off-by: Shawn Guo shawn@linaro.org --- drivers/mmc/host/sdhci-esdhc-imx.c | 25 ++--- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c index 370c052..48832c5 100644 --- a/drivers/mmc/host/sdhci-esdhc-imx.c +++ b/drivers/mmc/host/sdhci-esdhc-imx.c @@ -239,10 +239,6 @@ static void esdhc_writew_le(struct sdhci_host *host, u16 val, int reg) switch (reg) { case SDHCI_TRANSFER_MODE: - /* -* Postpone this write, we must do it together with a -* command write that is down below. -*/ if ((imx_data-flags ESDHC_FLAG_MULTIBLK_NO_INT) (host-cmd-opcode == SD_IO_RW_EXTENDED) (host-cmd-data-blocks 1) @@ -252,7 +248,18 @@ static void esdhc_writew_le(struct sdhci_host *host, u16 val, int reg) v |= ESDHC_VENDOR_SPEC_SDIO_QUIRK; writel(v, host-ioaddr + ESDHC_VENDOR_SPEC); } - imx_data-scratchpad = val; + + if (is_imx6q_usdhc(imx_data)) { + u32 m = readl(host-ioaddr + ESDHC_MIX_CTRL); + m = val | (m 0x); + writel(m, host-ioaddr + ESDHC_MIX_CTRL); + } else { + /* +* Postpone this write, we must do it together with a +* command write that is down below. +*/ + imx_data-scratchpad = val; + } return; case SDHCI_COMMAND: if ((host-cmd-opcode == MMC_STOP_TRANSMISSION || @@ -260,16 +267,12 @@ static void esdhc_writew_le(struct sdhci_host *host, u16 val, int reg) (imx_data-flags ESDHC_FLAG_MULTIBLK_NO_INT)) val |= SDHCI_CMD_ABORTCMD; - if (is_imx6q_usdhc(imx_data)) { - u32 m = readl(host-ioaddr + ESDHC_MIX_CTRL); - m = imx_data-scratchpad | (m 0x); - writel(m, host-ioaddr + ESDHC_MIX_CTRL); + if (is_imx6q_usdhc(imx_data)) writel(val 16, host-ioaddr + SDHCI_TRANSFER_MODE); - } else { + else writel(val 16 | imx_data-scratchpad, host-ioaddr + SDHCI_TRANSFER_MODE); - } return; case SDHCI_BLOCK_SIZE: val = ~SDHCI_MAKE_BLKSZ(0x7, 0); -- 1.7.9.5 -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 0/6] sdhci-esdhc-imx: 8bit mmc support
The series makes Auto CMD23 work for imx6q usdhc and then adds 8bit mmc support. Sascha Hauer (2): mmc: sdhci: rename platform_8bit_width to platform_bus_width mmc: sdhci-esdhc-imx: support 8bit mode Shawn Guo (4): mmc: sdhci-esdhc-imx: separate transfer mode from command write for usdhc mmc: sdhci-esdhc-imx: manually reset MIX_CTRL for usdhc mmc: sdhci-esdhc-imx: Auto CMD23 support for usdhc mmc: dt: bus-width can be an optional property Documentation/devicetree/bindings/mmc/mmc.txt |5 +- drivers/mmc/host/sdhci-esdhc-imx.c| 98 + drivers/mmc/host/sdhci-pci.c |4 +- drivers/mmc/host/sdhci-pxav2.c|2 +- drivers/mmc/host/sdhci-s3c.c |8 +- drivers/mmc/host/sdhci-tegra.c|4 +- drivers/mmc/host/sdhci.c |8 +- drivers/mmc/host/sdhci.h |2 +- include/linux/platform_data/mmc-esdhc-imx.h |1 + 9 files changed, 101 insertions(+), 31 deletions(-) -- 1.7.9.5 -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 3/6] mmc: sdhci-esdhc-imx: Auto CMD23 support for usdhc
SDHCI core will try to use Auto CMD23 for mmc card. Currently, we will see the following message with mmc card on usdhc due to the lacking of Auto CMD23 support in the driver. $ mmc0: new high speed MMC card at address 0001 mmcblk1: mmc0:0001 MMC02G 1.87 GiB mmcblk1: error -84 transferring data, sector 0, nr 8, cmd response 0x900, card status 0xb00 mmcblk1: retrying using single block read mmcblk1: Enable Auto CMD23 support for usdhc so that mmc card can work in multiple block mode. Signed-off-by: Shawn Guo shawn@linaro.org --- drivers/mmc/host/sdhci-esdhc-imx.c | 10 +- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c index 968a70f..24daaf4 100644 --- a/drivers/mmc/host/sdhci-esdhc-imx.c +++ b/drivers/mmc/host/sdhci-esdhc-imx.c @@ -36,6 +36,9 @@ #define ESDHC_VENDOR_SPEC_SDIO_QUIRK (1 1) #define ESDHC_WTMK_LVL 0x44 #define ESDHC_MIX_CTRL 0x48 +#define ESDHC_MIX_CTRL_AC23EN (1 7) +/* Bits 3 and 6 are not SDHCI standard definitions */ +#define ESDHC_MIX_CTRL_SDHCI_MASK 0xb7 /* * There is an INT DMA ERR mis-match between eSDHC and STD SDHC SPEC: @@ -251,7 +254,12 @@ static void esdhc_writew_le(struct sdhci_host *host, u16 val, int reg) if (is_imx6q_usdhc(imx_data)) { u32 m = readl(host-ioaddr + ESDHC_MIX_CTRL); - m = val | (m 0x); + /* Swap AC23 bit */ + if (val SDHCI_TRNS_AUTO_CMD23) { + val = ~SDHCI_TRNS_AUTO_CMD23; + val |= ESDHC_MIX_CTRL_AC23EN; + } + m = val | (m ~ESDHC_MIX_CTRL_SDHCI_MASK); writel(m, host-ioaddr + ESDHC_MIX_CTRL); } else { /* -- 1.7.9.5 -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 2/6] mmc: sdhci-esdhc-imx: manually reset MIX_CTRL for usdhc
It's another violation to SDHC spec that software reset on usdhc does not reset MIX_CTRL register. Have to do it manually, otherwise the preserving of the register bits (e.g. AC23EN) may cause mmc card fail to be initialized. Signed-off-by: Shawn Guo shawn@linaro.org --- drivers/mmc/host/sdhci-esdhc-imx.c |9 - 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c index 48832c5..968a70f 100644 --- a/drivers/mmc/host/sdhci-esdhc-imx.c +++ b/drivers/mmc/host/sdhci-esdhc-imx.c @@ -318,8 +318,15 @@ static void esdhc_writeb_le(struct sdhci_host *host, u8 val, int reg) * circuit relies on. To work around it, we turn the clocks on back * to keep card detection circuit functional. */ - if ((reg == SDHCI_SOFTWARE_RESET) (val 1)) + if ((reg == SDHCI_SOFTWARE_RESET) (val 1)) { esdhc_clrset_le(host, 0x7, 0x7, ESDHC_SYSTEM_CONTROL); + /* +* The reset on usdhc fails to clear MIX_CTRL register. +* Do it manually here. +*/ + if (is_imx6q_usdhc(imx_data)) + writel(0, host-ioaddr + ESDHC_MIX_CTRL); + } } static unsigned int esdhc_pltfm_get_max_clock(struct sdhci_host *host) -- 1.7.9.5 -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 5/6] mmc: sdhci-esdhc-imx: support 8bit mode
From: Sascha Hauer s.ha...@pengutronix.de The i.MX esdhc has a nonstandard bit layout for the SDHCI_HOST_CONTROL register. To support 8bit bus width on i.MX populate the platform_bus_width callback. This is tested on an i.MX25, but should according to the datasheets work on the other i.MX using this hardware aswell. The i.MX6, while having a SDHCI_SPEC_300 controller, still uses the same nonstandard register layout. Signed-off-by: Sascha Hauer s.ha...@pengutronix.de Signed-off-by: Shawn Guo shawn@linaro.org --- drivers/mmc/host/sdhci-esdhc-imx.c | 56 ++- include/linux/platform_data/mmc-esdhc-imx.h |1 + 2 files changed, 55 insertions(+), 2 deletions(-) diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c index 24daaf4..f7ee5e6 100644 --- a/drivers/mmc/host/sdhci-esdhc-imx.c +++ b/drivers/mmc/host/sdhci-esdhc-imx.c @@ -41,6 +41,13 @@ #define ESDHC_MIX_CTRL_SDHCI_MASK 0xb7 /* + * Our interpretation of the SDHCI_HOST_CONTROL register + */ +#define ESDHC_CTRL_4BITBUS (0x1 1) +#define ESDHC_CTRL_8BITBUS (0x2 1) +#define ESDHC_CTRL_BUSWIDTH_MASK (0x3 1) + +/* * There is an INT DMA ERR mis-match between eSDHC and STD SDHC SPEC: * Bit25 is used in STD SPEC, and is reserved in fsl eSDHC design, * but bit28 is used as the INT DMA ERR in fsl eSDHC design. @@ -294,6 +301,7 @@ static void esdhc_writeb_le(struct sdhci_host *host, u8 val, int reg) struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); struct pltfm_imx_data *imx_data = pltfm_host-priv; u32 new_val; + u32 mask; switch (reg) { case SDHCI_POWER_CONTROL: @@ -304,7 +312,7 @@ static void esdhc_writeb_le(struct sdhci_host *host, u8 val, int reg) return; case SDHCI_HOST_CONTROL: /* FSL messed up here, so we need to manually compose it. */ - new_val = val (SDHCI_CTRL_LED | SDHCI_CTRL_4BITBUS); + new_val = val SDHCI_CTRL_LED; /* ensure the endianness */ new_val |= ESDHC_HOST_CONTROL_LE; /* bits 89 are reserved on mx25 */ @@ -313,7 +321,13 @@ static void esdhc_writeb_le(struct sdhci_host *host, u8 val, int reg) new_val |= (val SDHCI_CTRL_DMA_MASK) 5; } - esdhc_clrset_le(host, 0x, new_val, reg); + /* +* Do not touch buswidth bits here. This is done in +* esdhc_pltfm_bus_width. +*/ + mask = 0x ~ESDHC_CTRL_BUSWIDTH_MASK; + + esdhc_clrset_le(host, mask, new_val, reg); return; } esdhc_clrset_le(host, 0xff, val, reg); @@ -370,6 +384,28 @@ static unsigned int esdhc_pltfm_get_ro(struct sdhci_host *host) return -ENOSYS; } +static int esdhc_pltfm_bus_width(struct sdhci_host *host, int width) +{ + u32 ctrl; + + switch (width) { + case MMC_BUS_WIDTH_8: + ctrl = ESDHC_CTRL_8BITBUS; + break; + case MMC_BUS_WIDTH_4: + ctrl = ESDHC_CTRL_4BITBUS; + break; + default: + ctrl = 0; + break; + } + + esdhc_clrset_le(host, ESDHC_CTRL_BUSWIDTH_MASK, ctrl, + SDHCI_HOST_CONTROL); + + return 0; +} + static struct sdhci_ops sdhci_esdhc_ops = { .read_l = esdhc_readl_le, .read_w = esdhc_readw_le, @@ -380,6 +416,7 @@ static struct sdhci_ops sdhci_esdhc_ops = { .get_max_clock = esdhc_pltfm_get_max_clock, .get_min_clock = esdhc_pltfm_get_min_clock, .get_ro = esdhc_pltfm_get_ro, + .platform_bus_width = esdhc_pltfm_bus_width, }; static struct sdhci_pltfm_data sdhci_esdhc_imx_pdata = { @@ -417,6 +454,8 @@ sdhci_esdhc_imx_probe_dt(struct platform_device *pdev, if (gpio_is_valid(boarddata-wp_gpio)) boarddata-wp_type = ESDHC_WP_GPIO; + of_property_read_u32(np, bus-width, boarddata-max_bus_width); + return 0; } #else @@ -548,6 +587,19 @@ static int sdhci_esdhc_imx_probe(struct platform_device *pdev) break; } + switch (boarddata-max_bus_width) { + case 8: + host-mmc-caps |= MMC_CAP_8_BIT_DATA | MMC_CAP_4_BIT_DATA; + break; + case 4: + host-mmc-caps |= MMC_CAP_4_BIT_DATA; + break; + case 1: + default: + host-quirks |= SDHCI_QUIRK_FORCE_1_BIT_DATA; + break; + } + err = sdhci_add_host(host); if (err) goto disable_clk; diff --git a/include/linux/platform_data/mmc-esdhc-imx.h b/include/linux/platform_data/mmc-esdhc-imx.h index aaf9748..b4a0521 100644 --- a/include/linux/platform_data/mmc-esdhc-imx.h +++ b/include/linux/platform_data/mmc-esdhc-imx.h @@ -39,5 +39,6 @@ struct esdhc_platform_data {
Re: [PATCH] mmc: dw_mmc: read all data in FIFO after Data transfer over interrupt in pio mode
On Mon, Jan 21, 2013 at 10:19 AM, Kyoungil Kim ki0351@samsung.com wrote: In dwc manual, the below contents are described. During end of packet, interrupt is not generated if threshold programming is larger than any remaining data. It is responsibility of host to read remaining bytes on seeing Data Transfer Done interrupt We also have seen the data cannot be read fully when sg_miter-length is less than FIFO size. Signed-off-by: Kyoungil Kim ki0351@samsung.com Signed-off-by: Seungwon Jeon tgih@samsung.com --- drivers/mmc/host/dw_mmc.c | 11 +++ 1 files changed, 7 insertions(+), 4 deletions(-) diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c index 323c502..afcc0f4 100644 --- a/drivers/mmc/host/dw_mmc.c +++ b/drivers/mmc/host/dw_mmc.c @@ -1430,7 +1430,7 @@ static void dw_mci_pull_data(struct dw_mci *host, void *buf, int cnt) host-pull_data(host, buf, cnt); } -static void dw_mci_read_data_pio(struct dw_mci *host) +static void dw_mci_read_data_pio(struct dw_mci *host, u8 int_data_over) The data_over argument should probably be a bool. -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
RE: [PATCH] mmc: dw_mmc: read all data in FIFO after Data transfer over interrupt in pio mode
On Mon, Jan 21, 2013 at 7:45 PM, Will Newton wrote: On Mon, Jan 21, 2013 at 10:19 AM, Kyoungil Kim ki0351@samsung.com wrote: In dwc manual, the below contents are described. During end of packet, interrupt is not generated if threshold programming is larger than any remaining data. It is responsibility of host to read remaining bytes on seeing Data Transfer Done interrupt We also have seen the data cannot be read fully when sg_miter-length is less than FIFO size. Signed-off-by: Kyoungil Kim ki0351@samsung.com Signed-off-by: Seungwon Jeon tgih@samsung.com --- drivers/mmc/host/dw_mmc.c | 11 +++ 1 files changed, 7 insertions(+), 4 deletions(-) diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c index 323c502..afcc0f4 100644 --- a/drivers/mmc/host/dw_mmc.c +++ b/drivers/mmc/host/dw_mmc.c @@ -1430,7 +1430,7 @@ static void dw_mci_pull_data(struct dw_mci *host, void *buf, int cnt) host-pull_data(host, buf, cnt); } -static void dw_mci_read_data_pio(struct dw_mci *host) +static void dw_mci_read_data_pio(struct dw_mci *host, u8 int_data_over) The data_over argument should probably be a bool. Thank you. I'll apply and submit again. -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2] mmc: dw_mmc: read all data in FIFO after Data transfer over interrupt in pio mode
In dwc manual, the below contents are described. During end of packet, interrupt is not generated if threshold programming is larger than any remaining data. It is responsibility of host to read remaining bytes on seeing Data Transfer Done interrupt We also have seen the data cannot be read fully when sg_miter-length is less than FIFO size. Signed-off-by: Kyoungil Kim ki0351@samsung.com Signed-off-by: Seungwon Jeon tgih@samsung.com --- drivers/mmc/host/dw_mmc.c | 11 +++ 1 files changed, 7 insertions(+), 4 deletions(-) diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c index 323c502..064c010 100644 --- a/drivers/mmc/host/dw_mmc.c +++ b/drivers/mmc/host/dw_mmc.c @@ -1430,7 +1430,7 @@ static void dw_mci_pull_data(struct dw_mci *host, void *buf, int cnt) host-pull_data(host, buf, cnt); } -static void dw_mci_read_data_pio(struct dw_mci *host) +static void dw_mci_read_data_pio(struct dw_mci *host, bool int_data_over) { struct sg_mapping_iter *sg_miter = host-sg_miter; void *buf; @@ -1465,7 +1465,10 @@ static void dw_mci_read_data_pio(struct dw_mci *host) sg_miter-consumed = offset; status = mci_readl(host, MINTSTS); mci_writel(host, RINTSTS, SDMMC_INT_RXDR); - } while (status SDMMC_INT_RXDR); /*if the RXDR is ready read again*/ + /* if the RXDR is ready read again */ + } while ((status SDMMC_INT_RXDR) || + (int_data_over +SDMMC_GET_FCNT(mci_readl(host, STATUS; data-bytes_xfered += nbytes; if (!remain) { @@ -1597,7 +1600,7 @@ static irqreturn_t dw_mci_interrupt(int irq, void *dev_id) smp_wmb(); if (host-dir_status == DW_MCI_RECV_STATUS) { if (host-sg != NULL) - dw_mci_read_data_pio(host); + dw_mci_read_data_pio(host, 1); } set_bit(EVENT_DATA_COMPLETE, host-pending_events); tasklet_schedule(host-tasklet); @@ -1606,7 +1609,7 @@ static irqreturn_t dw_mci_interrupt(int irq, void *dev_id) if (pending SDMMC_INT_RXDR) { mci_writel(host, RINTSTS, SDMMC_INT_RXDR); if (host-dir_status == DW_MCI_RECV_STATUS host-sg) - dw_mci_read_data_pio(host); + dw_mci_read_data_pio(host, 0); } if (pending SDMMC_INT_TXDR) { -- 1.7.4.1 -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: Help needed on an error during SD card enumeration
Hi Shashidhar Hiremath, snip mmc0:host doesn't support card's voltages set_ios invoked Poweroff Done mmc0: error -22 whilst initializing SDIO card Could you check whether the MMC host controller regulator is configured properly. eventhough I have inserted a SD card Which SD card you are using ? snip Regards, Kishore -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2 0/3] dmaengine: add per channel capabilities api
On Mon, Jan 21, 2013 at 03:15:23AM +, Vinod Koul wrote: On Sun, Jan 20, 2013 at 11:37:35AM -0500, Matt Porter wrote: On Sun, Jan 20, 2013 at 12:37:34PM +, Vinod Koul wrote: On Thu, Jan 10, 2013 at 02:07:03PM -0500, Matt Porter wrote: The call is implemented as follows: struct dmaengine_chan_caps *dma_get_channel_caps(struct dma_chan *chan, enum dma_transfer_direction dir); The dma transfer direction parameter may appear a bit out of place but it is necessary since the direction field in struct dma_slave_config was deprecated. In some cases, EDMA for one, it is necessary for the dmaengine driver to have the burst and address width slave configuration parameters available in order to compute the maximum segment size that can be handle. Due to this requirement, the calling order of this api is as follows: Well you are passing direction as argument so even in EDMA it doesn't seem to help you as you seem to need burst and width!. So why do you even need the direction to compute the capablities Yes, I need burst and width, but they are dependent on direction (dst vs src, as stored in the slave channel config). Ok, so I think I know where this is leading...the problem is probably that I made an implicit dependency on burst and width here. The expectation in this And also due to wrong documentation. This is what you have put up the flow as: Due to this requirement, the calling order of this api is as follows: 1. Allocate a DMA slave channel 1a. [Optionally] Get channel capabilities 2. Set slave and controller specific parameters 3. Get a descriptor for transaction 4. Submit the transaction 5. Issue pending requests and wait for callback notification Now when we query capablities, slave parameters _are_not_set_. So seems like you have thought something and written something else! Agreed. My documentation is incorrect. My bad, it should have been ordered 1, 2, 1a, ... as you've noted. Which brings me to the point on what are we trying to query: a) API capability, dont need slave parameters for that agreed b) Sg segment length and numbers: Well these are capabilities, so it tells you what is the maximum I can do. IMO it doesn't make sense to tie it down to burst, width etc. For that configuration you are checking maximum. What this needs to return is what is the maximum length it supports and maximum number of sg list the h/w can use. Also if you return your burst and width capablity, then any client can easily find out what is the length byte value it can hold. Ok, so I could report the max burst size to the client, but on EDMA it's going to be SZ_64K-1, as that's the hw limit. Max addr width would also be the same or capped at the maximum enum the current API support of 8 bytes. This information is not useful to the client in my case. Only the client knows its FIFO size, and thus the actual burst size it needs to request as that is a value specific to the IP the client driver controls. So it knows actual burst size and the width of that fifo transfer, because we already support telling the dmaengine driver this info in the current API. But, the client driver has no idea what DMAC it's using under the API. So, whereas if the omap_hsmmc driver is running on omap-dma, it can handle any SG segment size, if the driver happens to be running on edma, it needs to know the actual allowed max segment size for the slave channel parameters that it has set. The theoretical max segment size on EDMA is far larger than the actual maximum for a configured slave channel. This is why (yes, I screwed up and the documentation had the ordering wrong) I had the intention of dma_get_channel_caps() only being valid *after* dma_slave_config() was called. This is, in fact, the only point at which the edma driver has enough information to be able to report a valid max number of segments back to a client driver. Consider that on another channel, with burst size configured by a client driver to a high value (e.g. twice as big of a FIFO), now the edma driver has to report a small max segment size that can be used. The client driver has no idea it's on an edma controller so it needs some help from the dmaengine API to choose the optimal constraints when it builds SG lists. Too large and the EDMA driver has to reject it, too small and we lose performance and also run into the constraint edma has on the total number of segments we can handle in one sg list. If you feel this computaion if client specific, though looking at doesnt make me think so, you can add a callback for this computaion given the parameters. It's client-specific in the sense that the client peripheral is what provides the address width and burst size constraint (based on the FIFO integrated with that peripheral instantiation), but the abstracted dmaengine peripheral is what provides the segment size
Re: [PATCH v2 2/3] dma: edma: add device_channel_caps() support
On Mon, Jan 21, 2013 at 03:16:32AM +, Vinod Koul wrote: On Sun, Jan 20, 2013 at 11:51:08AM -0500, Matt Porter wrote: The explanation in the cover letter mentions that dmaengine_slave_config() is required to be called prior to dmaengine_get_channel_caps(). If we switch to the alternative API, then that would go away including the dependency on direction. Nope you got that wrong! :) Yes, dropped the ball there, should have been for the api to make sense as implemented: 1. Allocate a DMA slave channel 2. Set slave and controller specific parameters 2a. [Optionally] Get channel capabilities 3. Get a descriptor for transaction 4. Submit the transaction 5. Issue pending requests and wait for callback notification FWIW, the implementation example in the davinci mmc client driver shows proper use as in the correct documentation above. -Matt -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] goldfish: emulated MMC device
From: Mike Lockwood lockw...@android.com This driver handles the virtual MMC device present in the Goldfish emulator. The patch folds together initial work from Mike Lockwood and patches by San Mehat, Jun Nakajima and Tom Keel thomas.k...@intel.com plus cleanups by Alan Cox to get it all into 3.6 shape. Signed-off-by: Mike A. Chan mikec...@google.com [cleaned up and x86 support added] Signed-off-by: Sheng Yang sh...@linux.intel.com Signed-off-by: Yunhong Jiang yunhong.ji...@intel.com Signed-off-by: Xiaohui Xin xiaohui@intel.com Signed-off-by: Jun Nakajima jun.nakaj...@intel.com Signed-off-by: Bruce Beare bruce.j.be...@intel.com [Moved to 3.4] Signed-off-by: Tom Keel thomas.k...@intel.com [Moved to 3.7] Signed-off-by: Alan Cox a...@linux.intel.com --- drivers/mmc/host/Kconfig|7 + drivers/mmc/host/Makefile |1 drivers/mmc/host/goldfish.c | 566 +++ 3 files changed, 574 insertions(+) create mode 100644 drivers/mmc/host/goldfish.c diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig index 7684f7f..aebe265 100644 --- a/drivers/mmc/host/Kconfig +++ b/drivers/mmc/host/Kconfig @@ -372,6 +372,13 @@ config MMC_DAVINCI If you have an DAVINCI board with a Multimedia Card slot, say Y or M here. If unsure, say N. +config MMC_GOLDFISH + tristate goldfish qemu Multimedia Card Interface support + depends on GOLDFISH + help + This selects the Goldfish Multimedia card Interface emulation + found on the Goldfish Android virtual device emulation. + config MMC_SPI tristate MMC/SD/SDIO over SPI depends on SPI_MASTER !HIGHMEM HAS_DMA diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile index d5ea0722..82eba3e 100644 --- a/drivers/mmc/host/Makefile +++ b/drivers/mmc/host/Makefile @@ -23,6 +23,7 @@ obj-$(CONFIG_MMC_TIFM_SD) += tifm_sd.o obj-$(CONFIG_MMC_MSM) += msm_sdcc.o obj-$(CONFIG_MMC_MVSDIO) += mvsdio.o obj-$(CONFIG_MMC_DAVINCI) += davinci_mmc.o +obj-$(CONFIG_MMC_GOLDFISH) += goldfish.o obj-$(CONFIG_MMC_SPI) += mmc_spi.o ifeq ($(CONFIG_OF),y) obj-$(CONFIG_MMC_SPI) += of_mmc_spi.o diff --git a/drivers/mmc/host/goldfish.c b/drivers/mmc/host/goldfish.c new file mode 100644 index 000..5763f78 --- /dev/null +++ b/drivers/mmc/host/goldfish.c @@ -0,0 +1,566 @@ +/* + * Copyright 2007, Google Inc. + * Copyright 2012, Intel Inc. + * + * based on omap.c driver, which was + * Copyright (C) 2004 Nokia Corporation + * Written by Tuukka Tikkanen and Juha Yrj�l�juha.yrj...@nokia.com + * Misc hacks here and there by Tony Lindgren t...@atomide.com + * Other hacks (DMA, SD, etc) by David Brownell + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include linux/module.h +#include linux/platform_device.h +#include linux/major.h + +#include linux/types.h +#include linux/pci.h +#include linux/interrupt.h + +#include linux/kernel.h +#include linux/fs.h +#include linux/errno.h +#include linux/hdreg.h +#include linux/kdev_t.h +#include linux/blkdev.h +#include linux/mutex.h +#include linux/scatterlist.h +#include linux/mmc/mmc.h +#include linux/mmc/sdio.h +#include linux/mmc/host.h +#include linux/mmc/card.h + +#include linux/moduleparam.h +#include linux/init.h +#include linux/ioport.h +#include linux/dma-mapping.h +#include linux/delay.h +#include linux/spinlock.h +#include linux/timer.h +#include linux/clk.h + +#include asm/io.h +#include asm/irq.h +#include asm/scatterlist.h + +#include asm/types.h +#include asm/io.h +#include asm/uaccess.h + +#define DRIVER_NAME goldfish_mmc + +#define BUFFER_SIZE 16384 + +#define GOLDFISH_MMC_READ(host, addr) (readl(host-reg_base + addr)) +#define GOLDFISH_MMC_WRITE(host, addr, x) (writel(x, host-reg_base + addr)) + + +enum { + /* status register */ + MMC_INT_STATUS = 0x00, + /* set this to enable IRQ */ + MMC_INT_ENABLE = 0x04, + /* set this to specify buffer address */ + MMC_SET_BUFFER = 0x08, + + /* MMC command number */ + MMC_CMD = 0x0C, + + /* MMC argument */ + MMC_ARG = 0x10, + + /* MMC response (or R2 bits 0 - 31) */ + MMC_RESP_0 = 0x14, + + /* MMC R2 response bits 32 - 63 */ + MMC_RESP_1 = 0x18, + + /* MMC R2 response bits 64 - 95 */ + MMC_RESP_2 = 0x1C, + + /* MMC R2 response bits 96 - 127 */ + MMC_RESP_3 = 0x20, + + MMC_BLOCK_LENGTH= 0x24, + MMC_BLOCK_COUNT = 0x28, + + /* MMC state flags */ + MMC_STATE = 0x2C, + + /* MMC_INT_STATUS bits */ + + MMC_STAT_END_OF_CMD = 1U 0, + MMC_STAT_END_OF_DATA
Re: [PATCH v2] mmc: dw_mmc: read all data in FIFO after Data transfer over interrupt in pio mode
Hi, i didn't test with this patch. But it makes sense. Just i have minor comment. Acked-by: Jaehoon Chung jh80.ch...@samsung.com On 01/21/2013 09:28 PM, Kyoungil Kim wrote: In dwc manual, the below contents are described. During end of packet, interrupt is not generated if threshold programming is larger than any remaining data. It is responsibility of host to read remaining bytes on seeing Data Transfer Done interrupt We also have seen the data cannot be read fully when sg_miter-length is less than FIFO size. Signed-off-by: Kyoungil Kim ki0351@samsung.com Signed-off-by: Seungwon Jeon tgih@samsung.com --- drivers/mmc/host/dw_mmc.c | 11 +++ 1 files changed, 7 insertions(+), 4 deletions(-) diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c index 323c502..064c010 100644 --- a/drivers/mmc/host/dw_mmc.c +++ b/drivers/mmc/host/dw_mmc.c @@ -1430,7 +1430,7 @@ static void dw_mci_pull_data(struct dw_mci *host, void *buf, int cnt) host-pull_data(host, buf, cnt); } -static void dw_mci_read_data_pio(struct dw_mci *host) +static void dw_mci_read_data_pio(struct dw_mci *host, bool int_data_over) { struct sg_mapping_iter *sg_miter = host-sg_miter; void *buf; @@ -1465,7 +1465,10 @@ static void dw_mci_read_data_pio(struct dw_mci *host) sg_miter-consumed = offset; status = mci_readl(host, MINTSTS); mci_writel(host, RINTSTS, SDMMC_INT_RXDR); - } while (status SDMMC_INT_RXDR); /*if the RXDR is ready read again*/ + /* if the RXDR is ready read again */ + } while ((status SDMMC_INT_RXDR) || + (int_data_over + SDMMC_GET_FCNT(mci_readl(host, STATUS; If you can change int_data_over, we can use the one line. Best Regards, Jaehoon Chung data-bytes_xfered += nbytes; if (!remain) { @@ -1597,7 +1600,7 @@ static irqreturn_t dw_mci_interrupt(int irq, void *dev_id) smp_wmb(); if (host-dir_status == DW_MCI_RECV_STATUS) { if (host-sg != NULL) - dw_mci_read_data_pio(host); + dw_mci_read_data_pio(host, 1); } set_bit(EVENT_DATA_COMPLETE, host-pending_events); tasklet_schedule(host-tasklet); @@ -1606,7 +1609,7 @@ static irqreturn_t dw_mci_interrupt(int irq, void *dev_id) if (pending SDMMC_INT_RXDR) { mci_writel(host, RINTSTS, SDMMC_INT_RXDR); if (host-dir_status == DW_MCI_RECV_STATUS host-sg) - dw_mci_read_data_pio(host); + dw_mci_read_data_pio(host, 0); } if (pending SDMMC_INT_TXDR) { -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v4 0/8] rtsx patchset for MFD and MMC tree
于 2013年01月22日 11:31, Samuel Ortiz 写道: Hi Wei, On Wed, Jan 16, 2013 at 05:02:37PM +0800, wwang wrote: 于 2013年01月08日 17:57, 王炜 写道: From: Wei WANG wei_w...@realsil.com.cn v2: 1. Add commit message for patch 2 2. Move pci_set_dma_mask before the pci_enable_device(pcidev) call v3: 1. Add commit message for patch 3 2. Add patch 8: Use macro defines to replace some variables v4: 1. Describe why patch 3 is needed 2. Modify a comment character in patch 7 Wei WANG (8): MFD:rtsx: Fix typo in comment MFD:rtsx: Remove redundant code MFD:rtsx: Declare that the DMA address limitation is 32bit explicitly MFD:rtsx: Add callback function switch_output_voltage MMC:rtsx: Using callback function to switch output voltage MFD:rtsx: Add callback function conv_clk_and_div_n MFD:rtsx: Fix checkpatch warning MFD:rtsx: Use macro defines to replace some variables drivers/mfd/rtl8411.c | 29 drivers/mfd/rts5209.c | 21 + drivers/mfd/rts5229.c | 21 + drivers/mfd/rtsx_pcr.c| 45 + drivers/mfd/rtsx_pcr.h|3 +++ drivers/mmc/host/rtsx_pci_sdmmc.c | 30 + include/linux/mfd/rtsx_common.h |3 +++ include/linux/mfd/rtsx_pci.h | 27 +- 8 files changed, 135 insertions(+), 44 deletions(-) Hi Chris and Samuel: This patchset is trying to fix some bugs and some coding style issues. Would you please help to merge it to v3.8 kernel? I'll only take bug fixes for 3.8, even minor ones, and I don't see real bug fixes here. Am I missing something ? Cheers, Samuel. Hi Samuel: The commits below are all bug fix ( fix rtl8411 specifically) MFD:rtsx: Add callback function switch_output_voltage MMC:rtsx: Using callback function to switch output voltage MFD:rtsx: Add callback function conv_clk_and_div_n The other commits are for coding style issues BR, Wei WANG -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
RE: [PATCH v2] mmc: dw_mmc: read all data in FIFO after Data transfer over interrupt in pio mode
Kyoungil, Could you resend the following change considering Jaehoon's comment? - int_data_over - dto - use boolean constants(true, false) for dw_mci_read_data_pio argument. Thanks, Seungwon Jeon On Tuesday, January 22, 2013, Jaehoon Chung wrote: Hi, i didn't test with this patch. But it makes sense. Just i have minor comment. Acked-by: Jaehoon Chung jh80.ch...@samsung.com On 01/21/2013 09:28 PM, Kyoungil Kim wrote: In dwc manual, the below contents are described. During end of packet, interrupt is not generated if threshold programming is larger than any remaining data. It is responsibility of host to read remaining bytes on seeing Data Transfer Done interrupt We also have seen the data cannot be read fully when sg_miter-length is less than FIFO size. Signed-off-by: Kyoungil Kim ki0351@samsung.com Signed-off-by: Seungwon Jeon tgih@samsung.com --- drivers/mmc/host/dw_mmc.c | 11 +++ 1 files changed, 7 insertions(+), 4 deletions(-) diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c index 323c502..064c010 100644 --- a/drivers/mmc/host/dw_mmc.c +++ b/drivers/mmc/host/dw_mmc.c @@ -1430,7 +1430,7 @@ static void dw_mci_pull_data(struct dw_mci *host, void *buf, int cnt) host-pull_data(host, buf, cnt); } -static void dw_mci_read_data_pio(struct dw_mci *host) +static void dw_mci_read_data_pio(struct dw_mci *host, bool int_data_over) { struct sg_mapping_iter *sg_miter = host-sg_miter; void *buf; @@ -1465,7 +1465,10 @@ static void dw_mci_read_data_pio(struct dw_mci *host) sg_miter-consumed = offset; status = mci_readl(host, MINTSTS); mci_writel(host, RINTSTS, SDMMC_INT_RXDR); - } while (status SDMMC_INT_RXDR); /*if the RXDR is ready read again*/ + /* if the RXDR is ready read again */ + } while ((status SDMMC_INT_RXDR) || + (int_data_over +SDMMC_GET_FCNT(mci_readl(host, STATUS; If you can change int_data_over, we can use the one line. Best Regards, Jaehoon Chung data-bytes_xfered += nbytes; if (!remain) { @@ -1597,7 +1600,7 @@ static irqreturn_t dw_mci_interrupt(int irq, void *dev_id) smp_wmb(); if (host-dir_status == DW_MCI_RECV_STATUS) { if (host-sg != NULL) - dw_mci_read_data_pio(host); + dw_mci_read_data_pio(host, 1); } set_bit(EVENT_DATA_COMPLETE, host-pending_events); tasklet_schedule(host-tasklet); @@ -1606,7 +1609,7 @@ static irqreturn_t dw_mci_interrupt(int irq, void *dev_id) if (pending SDMMC_INT_RXDR) { mci_writel(host, RINTSTS, SDMMC_INT_RXDR); if (host-dir_status == DW_MCI_RECV_STATUS host-sg) - dw_mci_read_data_pio(host); + dw_mci_read_data_pio(host, 0); } if (pending SDMMC_INT_TXDR) { -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
RE: [PATCH v2] mmc: dw_mmc: read all data in FIFO after Data transfer over interrupt in pio mode
Thank you for review. I'll apply. On Tuesday, January 22, 2013 3:08 PM, Seungwon Jeon wrote: Kyoungil, Could you resend the following change considering Jaehoon's comment? - int_data_over - dto - use boolean constants(true, false) for dw_mci_read_data_pio argument. Thanks, Seungwon Jeon On Tuesday, January 22, 2013, Jaehoon Chung wrote: Hi, i didn't test with this patch. But it makes sense. Just i have minor comment. Acked-by: Jaehoon Chung jh80.ch...@samsung.com On 01/21/2013 09:28 PM, Kyoungil Kim wrote: In dwc manual, the below contents are described. During end of packet, interrupt is not generated if threshold programming is larger than any remaining data. It is responsibility of host to read remaining bytes on seeing Data Transfer Done interrupt We also have seen the data cannot be read fully when sg_miter-length is less than FIFO size. Signed-off-by: Kyoungil Kim ki0351@samsung.com Signed-off-by: Seungwon Jeon tgih@samsung.com --- drivers/mmc/host/dw_mmc.c | 11 +++ 1 files changed, 7 insertions(+), 4 deletions(-) diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c index 323c502..064c010 100644 --- a/drivers/mmc/host/dw_mmc.c +++ b/drivers/mmc/host/dw_mmc.c @@ -1430,7 +1430,7 @@ static void dw_mci_pull_data(struct dw_mci *host, void *buf, int cnt) host-pull_data(host, buf, cnt); } -static void dw_mci_read_data_pio(struct dw_mci *host) +static void dw_mci_read_data_pio(struct dw_mci *host, bool int_data_over) { struct sg_mapping_iter *sg_miter = host-sg_miter; void *buf; @@ -1465,7 +1465,10 @@ static void dw_mci_read_data_pio(struct dw_mci *host) sg_miter-consumed = offset; status = mci_readl(host, MINTSTS); mci_writel(host, RINTSTS, SDMMC_INT_RXDR); - } while (status SDMMC_INT_RXDR); /*if the RXDR is ready read again*/ + /* if the RXDR is ready read again */ + } while ((status SDMMC_INT_RXDR) || + (int_data_over + SDMMC_GET_FCNT(mci_readl(host, STATUS; If you can change int_data_over, we can use the one line. Best Regards, Jaehoon Chung -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3] mmc: dw_mmc: read all data in FIFO after Data transfer over interrupt in pio mode
In dwc manual, the below contents are described. During end of packet, interrupt is not generated if threshold programming is larger than any remaining data. It is responsibility of host to read remaining bytes on seeing Data Transfer Done interrupt We also have seen the data cannot be read fully when sg_miter-length is less than FIFO size. Signed-off-by: Kyoungil Kim ki0351@samsung.com Signed-off-by: Seungwon Jeon tgih@samsung.com Acked-by: Jaehoon Chung jh80.ch...@samsung.com --- drivers/mmc/host/dw_mmc.c | 10 ++ 1 files changed, 6 insertions(+), 4 deletions(-) diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c index 323c502..41d59da 100644 --- a/drivers/mmc/host/dw_mmc.c +++ b/drivers/mmc/host/dw_mmc.c @@ -1430,7 +1430,7 @@ static void dw_mci_pull_data(struct dw_mci *host, void *buf, int cnt) host-pull_data(host, buf, cnt); } -static void dw_mci_read_data_pio(struct dw_mci *host) +static void dw_mci_read_data_pio(struct dw_mci *host, bool dto) { struct sg_mapping_iter *sg_miter = host-sg_miter; void *buf; @@ -1465,7 +1465,9 @@ static void dw_mci_read_data_pio(struct dw_mci *host) sg_miter-consumed = offset; status = mci_readl(host, MINTSTS); mci_writel(host, RINTSTS, SDMMC_INT_RXDR); - } while (status SDMMC_INT_RXDR); /*if the RXDR is ready read again*/ + /* if the RXDR is ready read again */ + } while ((status SDMMC_INT_RXDR) || + (dto SDMMC_GET_FCNT(mci_readl(host, STATUS; data-bytes_xfered += nbytes; if (!remain) { @@ -1597,7 +1599,7 @@ static irqreturn_t dw_mci_interrupt(int irq, void *dev_id) smp_wmb(); if (host-dir_status == DW_MCI_RECV_STATUS) { if (host-sg != NULL) - dw_mci_read_data_pio(host); + dw_mci_read_data_pio(host, true); } set_bit(EVENT_DATA_COMPLETE, host-pending_events); tasklet_schedule(host-tasklet); @@ -1606,7 +1608,7 @@ static irqreturn_t dw_mci_interrupt(int irq, void *dev_id) if (pending SDMMC_INT_RXDR) { mci_writel(host, RINTSTS, SDMMC_INT_RXDR); if (host-dir_status == DW_MCI_RECV_STATUS host-sg) - dw_mci_read_data_pio(host); + dw_mci_read_data_pio(host, false); } if (pending SDMMC_INT_TXDR) { -- 1.7.4.1 -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html