RE: [SHDCI] Heavy (thousands) DMA leaks
Hi Js, I carefully review my patch, all the DMA memory mapped in sdhci_pre_req() is unmapped in sdhci_post_req. Can you provide the method of your testing DMA leaks? You said over 4000 leaked mappings during one card transfer, if true, We can't map any dma memory after some sd transfer, do you meet this? Best Regards Haibo Chen -Original Message- From: Jiri Slaby [mailto:jsl...@suse.cz] Sent: Thursday, July 30, 2015 5:32 PM To: Chen Haibo-B51421 Cc: Ulf Hansson; linux-mmc@vger.kernel.org; Linux kernel mailing list Subject: [SHDCI] Heavy (thousands) DMA leaks Hi, after commit 348487cb28e66b032bae1b38424d81bf5b08 Author: Haibo Chen haibo.c...@freescale.com Date: Tue Dec 9 17:04:05 2014 +0800 mmc: sdhci: use pipeline mmc requests to improve performance I see heavy DMA leaks which result in warnings of the dma api debug code: WARNING: CPU: 0 PID: 0 at lib/dma-debug.c:509 add_dma_entry+0x138/0x150() DMA-API: exceeded 7 overlapping mappings of cacheline 0x0b20ec00 And mainly this one upon sdhci module removal. It is over 4000 leaked mappings during one card transfer. mmc0: card e624 removed [ cut here ] WARNING: CPU: 2 PID: 1263 at lib/dma-debug.c:974 dma_debug_device_change+0x158/0x1c0() pci :02:00.0: DMA-API: device driver has pending DMA allocations while released from device [count=4041] One of leaked entries details: [device address=0xddff] [size=65536 bytes] [mapped with DMA_FROM_DEVICE] [mapped as scather- gather] Modules linked in: CPU: 2 PID: 1263 Comm: bash Tainted: GW 4.2.0-rc4 #12 Hardware name: LENOVO 23252SG/23252SG, BIOS G2ET33WW (1.13 ) 07/24/2012 81cc5e32 8800d03c3b68 81820938 8800d03c3bb8 8800d03c3ba8 810b827a 000100260021 88030e50 0fc9 88030d95aeb8 88030e4ddd68 Call Trace: [81820938] dump_stack+0x4c/0x6e [810b827a] warn_slowpath_common+0x8a/0xc0 [810b82f6] warn_slowpath_fmt+0x46/0x50 [813248c8] dma_debug_device_change+0x158/0x1c0 [810d4e9d] notifier_call_chain+0x4d/0x80 [810d51fd] __blocking_notifier_call_chain+0x4d/0x70 [810d5236] blocking_notifier_call_chain+0x16/0x20 [814db395] __device_release_driver+0x105/0x130 [814db3e3] device_release_driver+0x23/0x30 [814d95ca] unbind_store+0xba/0xe0 [8123c638] ? kernfs_fop_write+0xe8/0x170 [814d8ac4] drv_attr_store+0x24/0x30 [8123ce4a] sysfs_kf_write+0x3a/0x50 [8123c670] kernfs_fop_write+0x120/0x170 [811ce9e8] __vfs_write+0x28/0xe0 [811d1209] ? __sb_start_write+0x49/0xe0 [810e3ba5] ? local_clock+0x25/0x30 [811cf041] vfs_write+0xa1/0x170 [810e43c4] ? vtime_account_user+0x54/0x60 [811cfce6] SyS_write+0x46/0xa0 [81180f83] ? context_tracking_user_exit+0x13/0x20 [8182a017] entry_SYSCALL_64_fastpath+0x12/0x6a ---[ end trace 398181ad32332b33 ]--- Mapped at: [81324492] debug_dma_map_sg+0x122/0x140 [81616dd3] sdhci_pre_dma_transfer+0xc3/0x1b0 [81616f02] sdhci_pre_req+0x42/0x70 [81601492] mmc_pre_req+0x42/0x60 [8160290e] mmc_start_req+0x3e/0x400 I already fixed one symptom -- memory corruption. Could you revisit the commit once again, as there is surely at least one more bug? thanks, -- js suse labs -- 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: Fix coding style issues
This patch fixes the following issues reported by checkpatch.pl: - use -EINVAL instead of -ENOSYS, to fix warning message: ENOSYS means 'invalid syscall nr' and nothing else - split lines whose length is greater than 80 characters - avoid quoted string split across lines - use min_t instead of min, to fix warning message: min() should probably be min_t(int, cnt, host-part_buf_count) - fix missing a blank line after declarations Signed-off-by: Shawn Lin shawn@rock-chips.com --- Changes in v2: - Keep consistency of comments - Rebase on https://patchwork.kernel.org/patch/6672581 drivers/mmc/host/dw_mmc.c | 90 +-- 1 file changed, 56 insertions(+), 34 deletions(-) diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c index e41fb74..3f070d9 100644 --- a/drivers/mmc/host/dw_mmc.c +++ b/drivers/mmc/host/dw_mmc.c @@ -238,8 +238,8 @@ static u32 dw_mci_prepare_command(struct mmc_host *mmc, struct mmc_command *cmd) struct dw_mci *host = slot-host; const struct dw_mci_drv_data *drv_data = slot-host-drv_data; u32 cmdr; - cmd-error = -EINPROGRESS; + cmd-error = -EINPROGRESS; cmdr = cmd-opcode; if (cmd-opcode == MMC_STOP_TRANSMISSION || @@ -374,7 +374,7 @@ static void dw_mci_start_command(struct dw_mci *host, cmd-arg, cmd_flags); mci_writel(host, CMDARG, cmd-arg); - wmb(); + wmb(); /* drain writebuffer */ dw_mci_wait_while_busy(host, cmd_flags); mci_writel(host, CMD, cmd_flags | SDMMC_CMD_START); @@ -383,6 +383,7 @@ static void dw_mci_start_command(struct dw_mci *host, static inline void send_stop_abort(struct dw_mci *host, struct mmc_data *data) { struct mmc_command *stop = data-stop ? data-stop : host-stop_abort; + dw_mci_start_command(host, stop, host-stop_cmdr); } @@ -467,6 +468,7 @@ static void dw_mci_translate_sglist(struct dw_mci *host, struct mmc_data *data, { unsigned int desc_len; int i; + if (host-dma_64bit_address == 1) { struct idmac_desc_64addr *desc_first, *desc_last, *desc; @@ -474,6 +476,7 @@ static void dw_mci_translate_sglist(struct dw_mci *host, struct mmc_data *data, for (i = 0; i sg_len; i++) { unsigned int length = sg_dma_len(data-sg[i]); + u64 mem_addr = sg_dma_address(data-sg[i]); for ( ; length ; desc++) { @@ -518,6 +521,7 @@ static void dw_mci_translate_sglist(struct dw_mci *host, struct mmc_data *data, for (i = 0; i sg_len; i++) { unsigned int length = sg_dma_len(data-sg[i]); + u32 mem_addr = sg_dma_address(data-sg[i]); for ( ; length ; desc++) { @@ -557,7 +561,7 @@ static void dw_mci_translate_sglist(struct dw_mci *host, struct mmc_data *data, desc_last-des0 |= cpu_to_le32(IDMAC_DES0_LD); } - wmb(); + wmb(); /* drain writebuffer */ } static void dw_mci_idmac_start_dma(struct dw_mci *host, unsigned int sg_len) @@ -575,6 +579,7 @@ static void dw_mci_idmac_start_dma(struct dw_mci *host, unsigned int sg_len) temp |= SDMMC_CTRL_USE_IDMAC; mci_writel(host, CTRL, temp); + /* drain writebuffer */ wmb(); /* Enable the IDMAC */ @@ -622,7 +627,9 @@ static int dw_mci_idmac_init(struct dw_mci *host) host-ring_size = PAGE_SIZE / sizeof(struct idmac_desc); /* Forward link the descriptor list */ - for (i = 0, p = host-sg_cpu; i host-ring_size - 1; i++, p++) { + for (i = 0, p = host-sg_cpu; +i host-ring_size - 1; +i++, p++) { p-des3 = cpu_to_le32(host-sg_dma + (sizeof(struct idmac_desc) * (i + 1))); p-des1 = 0; @@ -751,7 +758,7 @@ static void dw_mci_adjust_fifoth(struct dw_mci *host, struct mmc_data *data) u32 fifo_width = 1 host-data_shift; u32 blksz_depth = blksz / fifo_width, fifoth_val; u32 msize = 0, rx_wmark = 1, tx_wmark, tx_wmark_invers; - int idx = (sizeof(mszs) / sizeof(mszs[0])) - 1; + int idx = ARRAY_SIZE(mszs) - 1; tx_wmark = (host-fifo_depth) / 2; tx_wmark_invers = host-fifo_depth - tx_wmark; @@ -876,6 +883,7 @@ static int dw_mci_submit_data_dma(struct dw_mci *host, struct mmc_data *data) static void dw_mci_submit_data(struct dw_mci *host, struct mmc_data *data) { unsigned long irqflags; + int flags = SG_MITER_ATOMIC; u32 temp; data-error = -EINPROGRESS; @@ -892,7 +900,6 @@ static void dw_mci_submit_data(struct dw_mci *host, struct mmc_data *data) } if (dw_mci_submit_data_dma(host, data)) { - int flags = SG_MITER_ATOMIC; if (host-data-flags
Re: [PATCH 00/17] omap_hsmmc: regulator usage cleanup and fixes
Hi Kishon, Thanks for taking a look at the regulator code. Do you have a public git repository so I can pull your patches instead of cherry picking 1-by-1? /Andi 2015-07-29 13:09 GMT+02:00 Kishon Vijay Abraham I kis...@ti.com: This patch series does the following *) Uses devm_regulator_get_optional() for vmmc and then removes the CONFIG_REGULATOR check altogether. *) return on -EPROBE_DEFER *) enable/disable vmmc_aux regulator based on prior state This series is in preparation for implementing the voltage switch sequence so that UHS cards can be supported. Did basic read/write test in J6, J6 Eco, Beagle-x15, AM437x EVM, Beaglebone black, OMAP5 uEVM and OMAP4 PANDA. Kishon Vijay Abraham I (16): mmc: host: omap_hsmmc: use devm_regulator_get_optional() for vmmc mmc: host: omap_hsmmc: return error from omap_hsmmc_reg_get on -EPROBE_DEFER mmc: host: omap_hsmmc: cleanup omap_hsmmc_reg_get() mmc: host: omap_hsmmc: use the ocrmask provided by the vmmc regulator mmc: host: omap_hsmmc: use mmc_host's vmmc and vqmmc mmc: host: omap_hsmmc: remove unnecessary pbias set_voltage mmc: host: omap_hsmmc: return error if any of the regulator APIs fail mmc: host: omap_hsmmc: add separate functions for enable/disable supply mmc: host: omap_hsmmc: add separate function to set pbias mmc: host: omap_hsmmc: avoid pbias regulator enable on power off mmc: host: omap_hsmmc: don't use -set_power to set initial regulator state ARM: dts: am57xx-beagle-x15: Fix regulator populated in MMC1 dt node mmc: host: omap_hsmmc: enable/disable vmmc_aux regulator based on prior state mmc: host: omap_hsmmc: use regulator_is_enabled to find pbias status mmc: host: omap_hsmmc: use ios-vdd for setting vmmc voltage mmc: host: omap_hsmmc: remove CONFIG_REGULATOR check Roger Quadros (1): mmc: host: omap_hsmmc: use mmc_of_parse_voltage to get ocr_avail .../devicetree/bindings/mmc/ti-omap-hsmmc.txt |2 + arch/arm/boot/dts/am57xx-beagle-x15.dts|1 - drivers/mmc/host/omap_hsmmc.c | 333 +--- 3 files changed, 216 insertions(+), 120 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
Re: [SHDCI] Heavy (thousands) DMA leaks
Hi, On 08/03/2015, 11:30 AM, Chen Bough wrote: I carefully review my patch, all the DMA memory mapped in sdhci_pre_req() is unmapped in sdhci_post_req. I suspect 'host_cookie' or 'next' handling is bad somewhere. But I don't know... Can you provide the method of your testing DMA leaks? boot kernel with CONFIG_DMA_API_DEBUG insert the card mount it rsync from the card ~200 MB umount it unload the sdhci driver the leak warning is reported I am not sure whether suspend-resume is needed after the first step. You said over 4000 leaked mappings during one card transfer, if true, We can't map any dma memory after some sd transfer, do you meet this? Yes, I see: sdhci-pci :02:00.0: swiotlb buffer is full (sz: 65536 bytes) after some time. The driver falls back to non-DMA transfers after that. It also generates a warning about that: WARNING: CPU: 0 PID: 0 at drivers/mmc/host/sdhci.c:857 sdhci_prepare_data+0x8ec/0x900 [sdhci]() thanks, -- js suse labs -- 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: [RFC PATCH v1 1/1] mmc: sprd: add MMC host driver for Spreadtrum SoC
On 2015-7-31 21:02, wuh...@gmail.com wrote: This patch adds MMC host driver for Spreadtrum SoC. The following coding style may be not meet kernel coding style. I am not sure this kind of coding style is better or worse. 1) A macro that represent some bits of a register is added a prefix __, for example: #define SDHOST_16_HOST_CTRL_2 0x3E #define __TIMING_MODE_SDR12 0x #define __TIMING_MODE_SDR25 0x0001 #define __TIMING_MODE_SDR50 0x0002 I think it is more useful to distinguish a register from a bit of this register. 2) A function in order to operate a register is also added a prefix _. If the functions(A) call other function(B), we added a prefix __ before B, for example: static inline void _sdhost_enable_int(struct sdhost_host *host, u32 mask) { __local_writel(mask, host, SDHOST_32_INT_ST_EN); __local_writel(mask, host, SDHOST_32_INT_SIG_EN); } I think this make the relationship of the function call more explicit. Signed-off-by: Billows Wu(WuHongtao) wuh...@gmail.com --- drivers/mmc/host/Kconfig |6 + drivers/mmc/host/Makefile |1 + drivers/mmc/host/sprd_sdhost.c | 1183 drivers/mmc/host/sprd_sdhost.h | 592 drivers/mmc/host/sprd_sdhost_debugfs.c | 213 ++ drivers/mmc/host/sprd_sdhost_debugfs.h | 27 + 6 files changed, 2022 insertions(+) create mode 100644 drivers/mmc/host/sprd_sdhost.c create mode 100644 drivers/mmc/host/sprd_sdhost.h create mode 100644 drivers/mmc/host/sprd_sdhost_debugfs.c create mode 100644 drivers/mmc/host/sprd_sdhost_debugfs.h diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig index fd9a58e..c43d938 100644 --- a/drivers/mmc/host/Kconfig +++ b/drivers/mmc/host/Kconfig @@ -264,6 +264,12 @@ config MMC_SDHCI_SPEAR If you have a controller with this interface, say Y or M here. +config SPRD_MMC_SDHOST + tristate Spreadtrum SDIO host Controller support + help + This selects the SDIO Host Controller in spreadtrum platform + + If you have a controller with this interface, say Y or M here. If unsure, say N. config MMC_SDHCI_S3C_DMA diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile index e928d61..e00227f 100644 --- a/drivers/mmc/host/Makefile +++ b/drivers/mmc/host/Makefile @@ -74,6 +74,7 @@ obj-$(CONFIG_MMC_SDHCI_BCM2835) += sdhci-bcm2835.o obj-$(CONFIG_MMC_SDHCI_IPROC) += sdhci-iproc.o obj-$(CONFIG_MMC_SDHCI_MSM) += sdhci-msm.o obj-$(CONFIG_MMC_SDHCI_ST)+= sdhci-st.o +obj-$(CONFIG_SPRD_MMC_SDHOST) += sprd_sdhost.o sprd_sdhost_debugfs.o ifeq ($(CONFIG_CB710_DEBUG),y) CFLAGS-cb710-mmc+= -DDEBUG diff --git a/drivers/mmc/host/sprd_sdhost.c b/drivers/mmc/host/sprd_sdhost.c new file mode 100644 index 000..18c9449 --- /dev/null +++ b/drivers/mmc/host/sprd_sdhost.c @@ -0,0 +1,1183 @@ +/* + * linux/drivers/mmc/host/sprd_sdhost.c - Secure Digital Host Controller + * Interface driver + * + * Copyright (C) 2015 Spreadtrum corporation. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + */ + +#include linux/delay.h +#include linux/dma-mapping.h +#include linux/highmem.h +#include linux/io.h +#include linux/module.h +#include linux/of.h +#include linux/of_device.h +#include linux/of_gpio.h +#include linux/platform_device.h +#include linux/pm_runtime.h +#include linux/regulator/consumer.h +#include linux/slab.h +#include linux/scatterlist.h + +#include sprd_sdhost.h +#include sprd_sdhost_debugfs.h + +#define DRIVER_NAME sdhost +#define SDHOST_CAPS \ + (MMC_CAP_4_BIT_DATA | MMC_CAP_SD_HIGHSPEED | \ + MMC_CAP_ERASE | MMC_CAP_UHS_SDR50 | \ + MMC_CAP_CMD23 | MMC_CAP_HW_RESET) + +struct sdhost_caps_data { + char *name; + u32 ocr_avail; + u32 caps; + u32 caps2; + u32 pm_caps; + u32 base_clk; + u32 signal_default_voltage; +}; + +struct sdhost_caps_data caps_info_map[] = { + { + .name = sd, + .ocr_avail = MMC_VDD_29_30 | MMC_VDD_30_31, + .caps = SDHOST_CAPS, + .caps2 = MMC_CAP2_HC_ERASE_SZ, + .base_clk = 19200, + .signal_default_voltage = 300, + }, + { + .name = wifi, + .ocr_avail = MMC_VDD_165_195 | MMC_VDD_29_30 | + MMC_VDD_30_31 | MMC_VDD_32_33 | MMC_VDD_33_34, + .caps = SDHOST_CAPS | MMC_CAP_POWER_OFF_CARD | + MMC_CAP_UHS_SDR12, + .base_clk = 7600, + }, + { + .name = emmc, +
Re: [PATCH] mmc: dw_mmc: Fix coding style issues
On 2015-8-3 12:07, Jaehoon Chung wrote: Hi, Shawn. On 07/28/2015 12:06 PM, Shawn Lin wrote: This patch fixes the following issues reported by checkpatch.pl: - use -EINVAL instead of -ENOSYS, to fix warning message: ENOSYS means 'invalid syscall nr' and nothing else - split lines whose length is greater than 80 characters - avoid quoted string split across lines - use min_t instead of min, to fix warning message: min() should probably be min_t(int, cnt, host-part_buf_count) Thanks for fixing coding style. But i will apply this patch(https://patchwork.kernel.org/patch/6672581/). So if you can fix with this patch, then it's helpful to me. If you can't, i will modify your patch before applying. How about? Okay, I will fix with this patch and resend it. Signed-off-by: Shawn Lin shawn@rock-chips.com --- drivers/mmc/host/dw_mmc.c | 85 ++- 1 file changed, 54 insertions(+), 31 deletions(-) diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c index 40e9d8e..6aede38 100644 --- a/drivers/mmc/host/dw_mmc.c +++ b/drivers/mmc/host/dw_mmc.c @@ -235,8 +235,8 @@ static u32 dw_mci_prepare_command(struct mmc_host *mmc, struct mmc_command *cmd) struct dw_mci *host = slot-host; const struct dw_mci_drv_data *drv_data = slot-host-drv_data; u32 cmdr; - cmd-error = -EINPROGRESS; + cmd-error = -EINPROGRESS; cmdr = cmd-opcode; if (cmd-opcode == MMC_STOP_TRANSMISSION || @@ -371,6 +371,7 @@ static void dw_mci_start_command(struct dw_mci *host, cmd-arg, cmd_flags); mci_writel(host, CMDARG, cmd-arg); + /* Make sure CMDARG is configured before CMD */ wmb(); dw_mci_wait_while_busy(host, cmd_flags); @@ -380,6 +381,7 @@ static void dw_mci_start_command(struct dw_mci *host, static inline void send_stop_abort(struct dw_mci *host, struct mmc_data *data) { struct mmc_command *stop = data-stop ? data-stop : host-stop_abort; + dw_mci_start_command(host, stop, host-stop_cmdr); } @@ -463,6 +465,7 @@ static void dw_mci_translate_sglist(struct dw_mci *host, struct mmc_data *data, unsigned int sg_len) { int i; + if (host-dma_64bit_address == 1) { struct idmac_desc_64addr *desc = host-sg_cpu; @@ -524,7 +527,7 @@ static void dw_mci_translate_sglist(struct dw_mci *host, struct mmc_data *data, desc-des0 |= cpu_to_le32(IDMAC_DES0_LD); } - wmb(); + wmb(); /* drain writebuffer */ } static void dw_mci_idmac_start_dma(struct dw_mci *host, unsigned int sg_len) @@ -542,7 +545,7 @@ static void dw_mci_idmac_start_dma(struct dw_mci *host, unsigned int sg_len) temp |= SDMMC_CTRL_USE_IDMAC; mci_writel(host, CTRL, temp); - wmb(); + wmb(); /* drain writebuffer */ /* Enable the IDMAC */ temp = mci_readl(host, BMOD); @@ -589,7 +592,9 @@ static int dw_mci_idmac_init(struct dw_mci *host) host-ring_size = PAGE_SIZE / sizeof(struct idmac_desc); /* Forward link the descriptor list */ - for (i = 0, p = host-sg_cpu; i host-ring_size - 1; i++, p++) { + for (i = 0, p = host-sg_cpu; +i host-ring_size - 1; +i++, p++) { p-des3 = cpu_to_le32(host-sg_dma + (sizeof(struct idmac_desc) * (i + 1))); p-des1 = 0; @@ -718,7 +723,7 @@ static void dw_mci_adjust_fifoth(struct dw_mci *host, struct mmc_data *data) u32 fifo_width = 1 host-data_shift; u32 blksz_depth = blksz / fifo_width, fifoth_val; u32 msize = 0, rx_wmark = 1, tx_wmark, tx_wmark_invers; - int idx = (sizeof(mszs) / sizeof(mszs[0])) - 1; + int idx = ARRAY_SIZE(mszs) - 1; tx_wmark = (host-fifo_depth) / 2; tx_wmark_invers = host-fifo_depth - tx_wmark; @@ -843,6 +848,7 @@ static int dw_mci_submit_data_dma(struct dw_mci *host, struct mmc_data *data) static void dw_mci_submit_data(struct dw_mci *host, struct mmc_data *data) { unsigned long irqflags; + int flags = SG_MITER_ATOMIC; u32 temp; data-error = -EINPROGRESS; @@ -859,7 +865,6 @@ static void dw_mci_submit_data(struct dw_mci *host, struct mmc_data *data) } if (dw_mci_submit_data_dma(host, data)) { - int flags = SG_MITER_ATOMIC; if (host-data-flags MMC_DATA_READ) flags |= SG_MITER_TO_SG; else @@ -906,6 +911,7 @@ static void mci_send_cmd(struct dw_mci_slot *slot, u32 cmd, u32 arg) unsigned int cmd_status = 0; mci_writel(host, CMDARG, arg); + /* Make sure CMDARG is configured before CMD */ wmb(); dw_mci_wait_while_busy(host, cmd); mci_writel(host, CMD, SDMMC_CMD_START | cmd); @@ -1019,6 +1025,7 @@ static
[PATCH] mmc: dw_mmc: fix pio mode when internal dmac is enabled
The dw_mci_init_dma() may decide to not use dma, but pio instead, caused by things like wrong dma settings in the system. Till now the code dw_mci_init_slot() always assumed that dma is available when CONFIG_MMC_DW_IDMAC was defined, ignoring the host-use_dma var set during dma init. So when now the dma init failed for whatever reason, the transfer sizes would still be set for dma transfers, especially including the maximum block-count calculated from host-ring_size and resulting in a [4.991109] [ cut here ] [4.99] kernel BUG at drivers/mmc/core/core.c:256! [4.991113] Internal error: Oops - BUG: 0 [#1] SMP ARM because host-ring_size is 0 in this case and the slot init code uses the wrong code to calculate the values. Fix this by selecting the correct calculations using the host-use_dma variable instead of the CONFIG_MMC_DW_IDMAC config option. Signed-off-by: Heiko Stuebner he...@sntech.de --- drivers/mmc/host/dw_mmc.c | 27 ++- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c index 40e9d8e..9ec3521 100644 --- a/drivers/mmc/host/dw_mmc.c +++ b/drivers/mmc/host/dw_mmc.c @@ -2391,19 +2391,20 @@ static int dw_mci_init_slot(struct dw_mci *host, unsigned int id) mmc-max_seg_size = host-pdata-blk_settings-max_seg_size; } else { /* Useful defaults if platform data is unset. */ -#ifdef CONFIG_MMC_DW_IDMAC - mmc-max_segs = host-ring_size; - mmc-max_blk_size = 65536; - mmc-max_seg_size = 0x1000; - mmc-max_req_size = mmc-max_seg_size * host-ring_size; - mmc-max_blk_count = mmc-max_req_size / 512; -#else - mmc-max_segs = 64; - mmc-max_blk_size = 65536; /* BLKSIZ is 16 bits */ - mmc-max_blk_count = 512; - mmc-max_req_size = mmc-max_blk_size * mmc-max_blk_count; - mmc-max_seg_size = mmc-max_req_size; -#endif /* CONFIG_MMC_DW_IDMAC */ + if (host-use_dma) { + mmc-max_segs = host-ring_size; + mmc-max_blk_size = 65536; + mmc-max_seg_size = 0x1000; + mmc-max_req_size = mmc-max_seg_size * host-ring_size; + mmc-max_blk_count = mmc-max_req_size / 512; + } else { + mmc-max_segs = 64; + mmc-max_blk_size = 65536; /* BLKSIZ is 16 bits */ + mmc-max_blk_count = 512; + mmc-max_req_size = mmc-max_blk_size * + mmc-max_blk_count; + mmc-max_seg_size = mmc-max_req_size; + } } if (dw_mci_get_cd(mmc)) -- 2.1.4 -- 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 v3 6/6] mmc: sdhci-esdhc-imx: set back the burst_length_enable bit to 1
On Mon, Aug 03, 2015 at 09:08:28AM +0800, Chen Haibo-B51421 wrote: -Original Message- From: Dong Aisheng [mailto:aisheng.d...@freescale.com] Sent: Friday, July 31, 2015 10:58 PM To: Chen Haibo-B51421 Cc: robh...@kernel.org; pawel.m...@arm.com; mark.rutl...@arm.com; ijc+devicet...@hellion.org.uk; ga...@codeaurora.org; shawn...@kernel.org; ker...@pengutronix.de; li...@arm.linux.org.uk; ulf.hans...@linaro.org; johan.dery...@barco.com; Estevam Fabio-R49496; Dong Aisheng-B29396; devicet...@vger.kernel.org; linux-ker...@vger.kernel.org; linux-arm- ker...@lists.infradead.org; linux-mmc@vger.kernel.org Subject: Re: [PATCH v3 6/6] mmc: sdhci-esdhc-imx: set back the burst_length_enable bit to 1 On Wed, Jul 29, 2015 at 05:03:57PM +0800, Haibo Chen wrote: Currently we find that if a usdhc is choosed to boot system, then ROM code will set the burst length enable bit of this usdhc as 0. This will make performance drop a lot if this usdhc's burst length is 16. So this patch set back the burst_length_enable bit as 1, which is the default value, and means burst length is enabled for INCR. Signed-off-by: Haibo Chen haibo.c...@freescale.com --- drivers/mmc/host/sdhci-esdhc-imx.c | 11 +++ 1 file changed, 11 insertions(+) diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c index 37d0095..dd945e5 100644 --- a/drivers/mmc/host/sdhci-esdhc-imx.c +++ b/drivers/mmc/host/sdhci-esdhc-imx.c @@ -32,6 +32,7 @@ #include sdhci-esdhc.h #define ESDHC_CTRL_D3CD 0x08 +#define ESDHC_BURST_LEN_EN_INCR (1 27) /* VENDOR SPEC register */ #define ESDHC_VENDOR_SPEC0xc0 #define ESDHC_VENDOR_SPEC_SDIO_QUIRK(1 1) @@ -1158,6 +1159,16 @@ static int sdhci_esdhc_imx_probe(struct platform_device *pdev) host-quirks2 |= SDHCI_QUIRK2_PRESET_VALUE_BROKEN; host-mmc-caps |= MMC_CAP_1_8V_DDR; + /* + * ROM code will change the burst_length_enable setting to + * zero if this usdhc is choosed to boot system. Change it + * back here, otherwise it will impact the performance a + * lot if the burst length is 16. Can you clarify a bit more on why performance drops a lot if burst length is 16? Caused by the burst length setting did not work due to ROM disabled it? [haibo] this bit is used to enable/disable the burst length for the external AHB2AXI bridge, It's useful especially for INCR transfer because without burst length indicator, the AHB2AXI bridge doesn't know the burst length in advance. And without burst length indicator, AHB INCR transfers can only be converted to singles on the AXI side. Seting this bit means burst length enabled for INCR. If this bit is not set, performance will drop a lot when burst length is 8 or 16. I will add this in the commit log. Thanks for clarify. One question: with this patch, can we set the default watermark level to 64 by default for all SoC types? If yes, we may not need patch 5 anymore. [PATCH v3 5/6] mmc: sdhci-esdhc-imx: config watermark level and burst length Regards Dong Aisheng Regards Dong Aisheng + */ + writel(readl(host-ioaddr + SDHCI_HOST_CONTROL) + | ESDHC_BURST_LEN_EN_INCR, + host-ioaddr + SDHCI_HOST_CONTROL); + if (!(imx_data-socdata-flags ESDHC_FLAG_HS200)) host-quirks2 |= SDHCI_QUIRK2_BROKEN_HS200; -- 1.9.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 v2 00/16] omap_hsmmc: regulator usage cleanup and fixes
Changes from v1: *) return on -EPROBE_DEFER and other fatal errors. (Don't return only if the return value is -ENODEV) *) Remove the beagle x15 dts patch. It can be part of a different series. *) Avoid using regulator_is_enabled for vqmmc since if the regulator is shared and the other users are not using regulator_is_enabled then there can be unbalanced regulator_enable/regulator_disable This patch series does the following *) Uses devm_regulator_get_optional() for vmmc and then removes the CONFIG_REGULATOR check altogether. *) return on -EPROBE_DEFER and any other fatal errors *) enable/disable vmmc_aux regulator based on prior state I've pushed this patch series to git://git.ti.com/linux-phy/linux-phy.git mmc_regulator_cleanup_fixes_v2 Please note the branch also has the pbias fixes [1] [2]. [1] - https://lkml.org/lkml/2015/7/27/358 [2] - https://lkml.org/lkml/2015/7/27/391 This series is in preparation for implementing the voltage switch sequence so that UHS cards can be supported. Did basic read/write test in J6, J6 Eco, Beagle-x15, AM437x EVM, Beaglebone black, OMAP5 uEVM and OMAP4 PANDA. Kishon Vijay Abraham I (15): mmc: host: omap_hsmmc: use devm_regulator_get_optional() for vmmc mmc: host: omap_hsmmc: return on fatal errors from omap_hsmmc_reg_get mmc: host: omap_hsmmc: cleanup omap_hsmmc_reg_get() mmc: host: omap_hsmmc: use the ocrmask provided by the vmmc regulator mmc: host: omap_hsmmc: use mmc_host's vmmc and vqmmc mmc: host: omap_hsmmc: remove unnecessary pbias set_voltage mmc: host: omap_hsmmc: return error if any of the regulator APIs fail mmc: host: omap_hsmmc: add separate functions for enable/disable supply mmc: host: omap_hsmmc: add separate function to set pbias mmc: host: omap_hsmmc: avoid pbias regulator enable on power off mmc: host: omap_hsmmc: don't use -set_power to set initial regulator state mmc: host: omap_hsmmc: enable/disable vmmc_aux regulator based on previous state mmc: host: omap_hsmmc: use regulator_is_enabled to find pbias status mmc: host: omap_hsmmc: use ios-vdd for setting vmmc voltage mmc: host: omap_hsmmc: remove CONFIG_REGULATOR check Roger Quadros (1): mmc: host: omap_hsmmc: use mmc_of_parse_voltage to get ocr_avail .../devicetree/bindings/mmc/ti-omap-hsmmc.txt |2 + drivers/mmc/host/omap_hsmmc.c | 340 +--- 2 files changed, 224 insertions(+), 118 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
Re: [PATCH v2] mmc: dw_mmc: Add external dma interface support
Hi Shawn, Am Montag, 3. August 2015, 11:27:19 schrieb Shawn Lin: DesignWare MMC Controller can support two types of DMA mode: external dma and internal dma. We get a RK312x platform integrated dw_mmc and ARM pl330 dma controller. This patch add edmac ops to suuport these platforms. I've tested it on RK312x platform with edmac mode and RK3288 platform with idmac mode. Patch is based on next of git://git.linaro.org/people/ulf.hansson/mmc Signed-off-by: Shawn Lin shawn@rock-chips.com --- Changes in v2: - Fix typo of dev_info msg - remove unused dmach from declaration of dw_mci_dma_slave drivers/mmc/host/Kconfig| 24 +- drivers/mmc/host/dw_mmc-pltfm.c | 4 + drivers/mmc/host/dw_mmc.c | 169 ++-- include/linux/mmc/dw_mmc.h | 18 - 4 files changed, 205 insertions(+), 10 deletions(-) diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig index 6a0f9c7..2a66b08 100644 --- a/drivers/mmc/host/Kconfig +++ b/drivers/mmc/host/Kconfig @@ -607,16 +607,36 @@ config MMC_DW help This selects support for the Synopsys DesignWare Mobile Storage IP block, this provides host support for SD and MMC interfaces, in both - PIO and external DMA modes. + PIO, internal DMA mode and external DMA modes. + +choice + prompt DesignWare MMC transfer mode + depends on MMC_DW + +config MMC_DW_PIO + bool Use PIO transfers only + help + Use PIO to transfer data between memory and the hardware. + PIO is slower than DMA as it requires CPU instructions to + move the data. This has been the traditional default for + the DW MCI driver. config MMC_DW_IDMAC bool Internal DMAC interface - depends on MMC_DW help This selects support for the internal DMAC block within the Synopsys Designware Mobile Storage IP block. This disables the external DMA interface. +config MMC_DW_EDMAC + bool External DMAC interface + help + This selects support for the external DMAC block outside the Synopsys + Designware Mobile Storage IP block. This disables the internal DMA + interface. + +endchoice + more a drive-by comment: This should definitly not be a choice. We're in multiplatform times, where you can have support for a multitude of socs using dw_mmc in one kernel. And one might want to use pio, one might want to use the internal dma while another one might want to use the external dma. So which dma to use should definitly be decided at runtime and not at compile- time. Heiko -- 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 09/16] mmc: host: omap_hsmmc: add separate function to set pbias
No functional change. Cleanup omap_hsmmc_set_power by adding separate functions to set pbias and invoke it from omap_hsmmc_set_power. Signed-off-by: Kishon Vijay Abraham I kis...@ti.com --- drivers/mmc/host/omap_hsmmc.c | 78 + 1 file changed, 48 insertions(+), 30 deletions(-) diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c index 81bec66..194c59f 100644 --- a/drivers/mmc/host/omap_hsmmc.c +++ b/drivers/mmc/host/omap_hsmmc.c @@ -306,6 +306,48 @@ err_set_ocr: return ret; } +static int omap_hsmmc_set_pbias(struct omap_hsmmc_host *host, bool power_on, + int vdd) +{ + int ret; + + if (!host-pbias) + return 0; + + if (power_on) { + if (vdd = VDD_165_195) + ret = regulator_set_voltage(host-pbias, VDD_1V8, + VDD_1V8); + else + ret = regulator_set_voltage(host-pbias, VDD_3V0, + VDD_3V0); + if (ret 0) { + dev_err(host-dev, pbias set voltage fail\n); + return ret; + } + + if (host-pbias_enabled == 0) { + ret = regulator_enable(host-pbias); + if (ret) { + dev_err(host-dev, pbias reg enable fail\n); + return ret; + } + host-pbias_enabled = 1; + } + } else { + if (host-pbias_enabled == 1) { + ret = regulator_disable(host-pbias); + if (ret) { + dev_err(host-dev, pbias reg disable fail\n); + return ret; + } + host-pbias_enabled = 0; + } + } + + return 0; +} + static int omap_hsmmc_set_power(struct device *dev, int power_on, int vdd) { struct omap_hsmmc_host *host = @@ -323,16 +365,9 @@ static int omap_hsmmc_set_power(struct device *dev, int power_on, int vdd) if (mmc_pdata(host)-before_set_reg) mmc_pdata(host)-before_set_reg(dev, power_on, vdd); - if (host-pbias) { - if (host-pbias_enabled == 1) { - ret = regulator_disable(host-pbias); - if (ret) { - dev_err(dev, pbias reg disable failed\n); - return ret; - } - host-pbias_enabled = 0; - } - } + ret = omap_hsmmc_set_pbias(host, false, 0); + if (ret) + return ret; /* * Assume Vcc regulator is used only to power the card ... OMAP @@ -357,26 +392,9 @@ static int omap_hsmmc_set_power(struct device *dev, int power_on, int vdd) return ret; } - if (host-pbias) { - if (vdd = VDD_165_195) - ret = regulator_set_voltage(host-pbias, VDD_1V8, - VDD_1V8); - else - ret = regulator_set_voltage(host-pbias, VDD_3V0, - VDD_3V0); - if (ret 0) - goto err_set_voltage; - - if (host-pbias_enabled == 0) { - ret = regulator_enable(host-pbias); - if (ret) { - dev_err(dev, pbias reg enable failed\n); - goto err_set_voltage; - } else { - host-pbias_enabled = 1; - } - } - } + ret = omap_hsmmc_set_pbias(host, true, vdd); + if (ret) + goto err_set_voltage; if (mmc_pdata(host)-after_set_reg) mmc_pdata(host)-after_set_reg(dev, power_on, vdd); -- 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 v2 13/16] mmc: host: omap_hsmmc: use regulator_is_enabled to find pbias status
Use regulator_is_enabled of pbias regulator to find pbias regulator status instead of maintaining a custom bookkeeping pbias_enabled variable. Signed-off-by: Kishon Vijay Abraham I kis...@ti.com --- drivers/mmc/host/omap_hsmmc.c |8 ++-- 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c index 98e0289..e04060b 100644 --- a/drivers/mmc/host/omap_hsmmc.c +++ b/drivers/mmc/host/omap_hsmmc.c @@ -182,7 +182,6 @@ struct omap_hsmmc_host { struct clk *fclk; struct clk *dbclk; struct regulator *pbias; - boolpbias_enabled; void__iomem *base; int vqmmc_enabled; resource_size_t mapbase; @@ -331,22 +330,20 @@ static int omap_hsmmc_set_pbias(struct omap_hsmmc_host *host, bool power_on, return ret; } - if (host-pbias_enabled == 0) { + if (!regulator_is_enabled(host-pbias)) { ret = regulator_enable(host-pbias); if (ret) { dev_err(host-dev, pbias reg enable fail\n); return ret; } - host-pbias_enabled = 1; } } else { - if (host-pbias_enabled == 1) { + if (regulator_is_enabled(host-pbias)) { ret = regulator_disable(host-pbias); if (ret) { dev_err(host-dev, pbias reg disable fail\n); return ret; } - host-pbias_enabled = 0; } } @@ -2081,7 +2078,6 @@ static int omap_hsmmc_probe(struct platform_device *pdev) host-base = base + pdata-reg_offset; host-power_mode = MMC_POWER_OFF; host-next_data.cookie = 1; - host-pbias_enabled = 0; host-vqmmc_enabled = 0; ret = omap_hsmmc_gpio_init(mmc, host, pdata); -- 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 v2 12/16] mmc: host: omap_hsmmc: enable/disable vmmc_aux regulator based on previous state
enable vmmc_aux regulator only if it is in disabled state and disable vmmc_aux regulator only if it is in enabled state. Signed-off-by: Kishon Vijay Abraham I kis...@ti.com --- drivers/mmc/host/omap_hsmmc.c | 10 -- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c index 635ac18..98e0289 100644 --- a/drivers/mmc/host/omap_hsmmc.c +++ b/drivers/mmc/host/omap_hsmmc.c @@ -184,6 +184,7 @@ struct omap_hsmmc_host { struct regulator *pbias; boolpbias_enabled; void__iomem *base; + int vqmmc_enabled; resource_size_t mapbase; spinlock_t irq_lock; /* Prevent races with irq handler */ unsigned intdma_len; @@ -250,6 +251,7 @@ static int omap_hsmmc_get_cover_state(struct device *dev) static int omap_hsmmc_enable_supply(struct mmc_host *mmc, int vdd) { int ret; + struct omap_hsmmc_host *host = mmc_priv(mmc); if (mmc-supply.vmmc) { ret = mmc_regulator_set_ocr(mmc, mmc-supply.vmmc, vdd); @@ -258,12 +260,13 @@ static int omap_hsmmc_enable_supply(struct mmc_host *mmc, int vdd) } /* Enable interface voltage rail, if needed */ - if (mmc-supply.vqmmc) { + if (mmc-supply.vqmmc !host-vqmmc_enabled) { ret = regulator_enable(mmc-supply.vqmmc); if (ret) { dev_err(mmc_dev(mmc), vmmc_aux reg enable failed\n); goto err_vqmmc; } + host-vqmmc_enabled = 1; } return 0; @@ -279,13 +282,15 @@ static int omap_hsmmc_disable_supply(struct mmc_host *mmc) { int ret; int status; + struct omap_hsmmc_host *host = mmc_priv(mmc); - if (mmc-supply.vqmmc) { + if (mmc-supply.vqmmc host-vqmmc_enabled) { ret = regulator_disable(mmc-supply.vqmmc); if (ret) { dev_err(mmc_dev(mmc), vmmc_aux reg disable failed\n); return ret; } + host-vqmmc_enabled = 0; } if (mmc-supply.vmmc) { @@ -2077,6 +2082,7 @@ static int omap_hsmmc_probe(struct platform_device *pdev) host-power_mode = MMC_POWER_OFF; host-next_data.cookie = 1; host-pbias_enabled = 0; + host-vqmmc_enabled = 0; ret = omap_hsmmc_gpio_init(mmc, host, pdata); if (ret) -- 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 v2 15/16] mmc: host: omap_hsmmc: remove CONFIG_REGULATOR check
Now that support for platforms which have optional regulator is added, remove CONFIG_REGULATOR check in omap_hsmmc. Signed-off-by: Kishon Vijay Abraham I kis...@ti.com --- drivers/mmc/host/omap_hsmmc.c | 35 +++ 1 file changed, 3 insertions(+), 32 deletions(-) diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c index 9a28719..15973f1 100644 --- a/drivers/mmc/host/omap_hsmmc.c +++ b/drivers/mmc/host/omap_hsmmc.c @@ -204,7 +204,6 @@ struct omap_hsmmc_host { int context_loss; int protect_card; int reqs_blocked; - int use_reg; int req_in_progress; unsigned long clk_rate; unsigned intflags; @@ -245,8 +244,6 @@ static int omap_hsmmc_get_cover_state(struct device *dev) return mmc_gpio_get_cd(host-mmc); } -#ifdef CONFIG_REGULATOR - static int omap_hsmmc_enable_supply(struct mmc_host *mmc) { int ret; @@ -521,29 +518,6 @@ static void omap_hsmmc_reg_put(struct omap_hsmmc_host *host) mmc_pdata(host)-set_power = NULL; } -static inline int omap_hsmmc_have_reg(void) -{ - return 1; -} - -#else - -static inline int omap_hsmmc_reg_get(struct omap_hsmmc_host *host) -{ - return -EINVAL; -} - -static inline void omap_hsmmc_reg_put(struct omap_hsmmc_host *host) -{ -} - -static inline int omap_hsmmc_have_reg(void) -{ - return 0; -} - -#endif - static irqreturn_t omap_hsmmc_cover_irq(int irq, void *dev_id); static int omap_hsmmc_gpio_init(struct mmc_host *mmc, @@ -2204,11 +2178,10 @@ static int omap_hsmmc_probe(struct platform_device *pdev) goto err_irq; } - if (omap_hsmmc_have_reg() !mmc_pdata(host)-set_power) { + if (!mmc_pdata(host)-set_power) { ret = omap_hsmmc_reg_get(host); if (ret) goto err_irq; - host-use_reg = 1; } mmc-ocr_avail = mmc_pdata(host)-ocr_mask; @@ -2251,8 +2224,7 @@ static int omap_hsmmc_probe(struct platform_device *pdev) err_slot_name: mmc_remove_host(mmc); - if (host-use_reg) - omap_hsmmc_reg_put(host); + omap_hsmmc_reg_put(host); err_irq: device_init_wakeup(pdev-dev, false); if (host-tx_chan) @@ -2276,8 +2248,7 @@ static int omap_hsmmc_remove(struct platform_device *pdev) pm_runtime_get_sync(host-dev); mmc_remove_host(host-mmc); - if (host-use_reg) - omap_hsmmc_reg_put(host); + omap_hsmmc_reg_put(host); if (host-tx_chan) dma_release_channel(host-tx_chan); -- 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 v2 16/16] mmc: host: omap_hsmmc: use mmc_of_parse_voltage to get ocr_avail
From: Roger Quadros rog...@ti.com For platforms that doesn't have explicit regulator control in MMC, populate voltage-ranges in MMC device tree node and use mmc_of_parse_voltage to get ocr_avail Signed-off-by: Roger Quadros rog...@ti.com Signed-off-by: Lokesh Vutla lokeshvu...@ti.com Signed-off-by: Murali Karicheri m-kariche...@ti.com Signed-off-by: Franklin S Cooper Jr fcoo...@ti.com Signed-off-by: Kishon Vijay Abraham I kis...@ti.com --- .../devicetree/bindings/mmc/ti-omap-hsmmc.txt |2 ++ drivers/mmc/host/omap_hsmmc.c |9 - 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/mmc/ti-omap-hsmmc.txt b/Documentation/devicetree/bindings/mmc/ti-omap-hsmmc.txt index 76bf087..2408e87 100644 --- a/Documentation/devicetree/bindings/mmc/ti-omap-hsmmc.txt +++ b/Documentation/devicetree/bindings/mmc/ti-omap-hsmmc.txt @@ -22,6 +22,8 @@ ti,dual-volt: boolean, supports dual voltage cards ti,non-removable: non-removable slot (like eMMC) ti,needs-special-reset: Requires a special softreset sequence ti,needs-special-hs-handling: HSMMC IP needs special setting for handling High Speed +voltage-ranges: Specify the voltage range supported if regulator framework +isn't enabled. dmas: List of DMA specifiers with the controller specific format as described in the generic DMA client binding. A tx and rx specifier is required. diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c index 15973f1..d884d8f 100644 --- a/drivers/mmc/host/omap_hsmmc.c +++ b/drivers/mmc/host/omap_hsmmc.c @@ -2184,7 +2184,13 @@ static int omap_hsmmc_probe(struct platform_device *pdev) goto err_irq; } - mmc-ocr_avail = mmc_pdata(host)-ocr_mask; + if (!mmc_pdata(host)-ocr_mask) { + ret = mmc_of_parse_voltage(pdev-dev.of_node, mmc-ocr_avail); + if (ret) + goto err_parse_voltage; + } else { + mmc-ocr_avail = mmc_pdata(host)-ocr_mask; + } omap_hsmmc_disable_irq(host); @@ -2224,6 +2230,7 @@ static int omap_hsmmc_probe(struct platform_device *pdev) err_slot_name: mmc_remove_host(mmc); +err_parse_voltage: omap_hsmmc_reg_put(host); err_irq: device_init_wakeup(pdev-dev, false); -- 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
Re: [PATCH 00/17] omap_hsmmc: regulator usage cleanup and fixes
Hi, On Monday 03 August 2015 12:58 PM, Andreas Fenkart wrote: Hi Kishon, Thanks for taking a look at the regulator code. Do you have a public git repository so I can pull your patches instead of cherry picking 1-by-1? I'll post v2 shortly. With that I'll have the patches in a git tree. Thanks Kishon /Andi 2015-07-29 13:09 GMT+02:00 Kishon Vijay Abraham I kis...@ti.com: This patch series does the following *) Uses devm_regulator_get_optional() for vmmc and then removes the CONFIG_REGULATOR check altogether. *) return on -EPROBE_DEFER *) enable/disable vmmc_aux regulator based on prior state This series is in preparation for implementing the voltage switch sequence so that UHS cards can be supported. Did basic read/write test in J6, J6 Eco, Beagle-x15, AM437x EVM, Beaglebone black, OMAP5 uEVM and OMAP4 PANDA. Kishon Vijay Abraham I (16): mmc: host: omap_hsmmc: use devm_regulator_get_optional() for vmmc mmc: host: omap_hsmmc: return error from omap_hsmmc_reg_get on -EPROBE_DEFER mmc: host: omap_hsmmc: cleanup omap_hsmmc_reg_get() mmc: host: omap_hsmmc: use the ocrmask provided by the vmmc regulator mmc: host: omap_hsmmc: use mmc_host's vmmc and vqmmc mmc: host: omap_hsmmc: remove unnecessary pbias set_voltage mmc: host: omap_hsmmc: return error if any of the regulator APIs fail mmc: host: omap_hsmmc: add separate functions for enable/disable supply mmc: host: omap_hsmmc: add separate function to set pbias mmc: host: omap_hsmmc: avoid pbias regulator enable on power off mmc: host: omap_hsmmc: don't use -set_power to set initial regulator state ARM: dts: am57xx-beagle-x15: Fix regulator populated in MMC1 dt node mmc: host: omap_hsmmc: enable/disable vmmc_aux regulator based on prior state mmc: host: omap_hsmmc: use regulator_is_enabled to find pbias status mmc: host: omap_hsmmc: use ios-vdd for setting vmmc voltage mmc: host: omap_hsmmc: remove CONFIG_REGULATOR check Roger Quadros (1): mmc: host: omap_hsmmc: use mmc_of_parse_voltage to get ocr_avail .../devicetree/bindings/mmc/ti-omap-hsmmc.txt |2 + arch/arm/boot/dts/am57xx-beagle-x15.dts|1 - drivers/mmc/host/omap_hsmmc.c | 333 +--- 3 files changed, 216 insertions(+), 120 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
Re: [PATCH v3 1/6] mmc: sdhci-esdhc-imx: add imx7d support and support HS400
On Sun, Aug 02, 2015 at 04:59:04PM +0800, Chen Haibo-B51421 wrote: -Original Message- From: Dong Aisheng [mailto:aisheng.d...@freescale.com] Sent: Friday, July 31, 2015 10:15 PM To: Chen Haibo-B51421 Cc: robh...@kernel.org; pawel.m...@arm.com; mark.rutl...@arm.com; ijc+devicet...@hellion.org.uk; ga...@codeaurora.org; shawn...@kernel.org; ker...@pengutronix.de; li...@arm.linux.org.uk; ulf.hans...@linaro.org; johan.dery...@barco.com; Estevam Fabio-R49496; Dong Aisheng-B29396; devicet...@vger.kernel.org; linux-ker...@vger.kernel.org; linux-arm- ker...@lists.infradead.org; linux-mmc@vger.kernel.org Subject: Re: [PATCH v3 1/6] mmc: sdhci-esdhc-imx: add imx7d support and support HS400 On Wed, Jul 29, 2015 at 05:03:52PM +0800, Haibo Chen wrote: The imx7d usdhc is derived from imx6sx, the difference is that imx7d support HS400. So introduce a new compatible string for imx7d and add HS400 support for imx7d usdhc. Signed-off-by: Haibo Chen haibo.c...@freescale.com --- drivers/mmc/host/sdhci-esdhc-imx.c | 66 ++ 1 file changed, 66 insertions(+) diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c index c6b9f64..b441eed 100644 --- a/drivers/mmc/host/sdhci-esdhc-imx.c +++ b/drivers/mmc/host/sdhci-esdhc-imx.c @@ -44,6 +44,7 @@ #define ESDHC_MIX_CTRL_EXE_TUNE (1 22) #define ESDHC_MIX_CTRL_SMPCLK_SEL (1 23) #define ESDHC_MIX_CTRL_FBCLK_SEL(1 25) +#define ESDHC_MIX_CTRL_HS400_EN (1 26) /* Bits 3 and 6 are not SDHCI standard definitions */ #define ESDHC_MIX_CTRL_SDHCI_MASK 0xb7 /* Tuning bits */ @@ -60,6 +61,16 @@ #define ESDHC_TUNE_CTRL_MIN 0 #define ESDHC_TUNE_CTRL_MAX ((1 7) - 1) +/* strobe dll register */ +#define ESDHC_STROBE_DLL_CTRL0x70 +#define ESDHC_STROBE_DLL_CTRL_ENABLE (1 0) +#define ESDHC_STROBE_DLL_CTRL_RESET (1 1) +#define ESDHC_STROBE_DLL_CTRL_SLV_DLY_TARGET_SHIFT 3 + +#define ESDHC_STROBE_DLL_STATUS 0x74 +#define ESDHC_STROBE_DLL_STS_REF_LOCK(1 1) +#define ESDHC_STROBE_DLL_STS_SLV_LOCK0x1 + #define ESDHC_TUNING_CTRL0xcc #define ESDHC_STD_TUNING_EN (1 24) /* NOTE: the minimum valid tuning start tap for mx6sl is 1 */ @@ -120,6 +131,8 @@ #define ESDHC_FLAG_ERR004536 BIT(7) /* The IP supports HS200 mode */ #define ESDHC_FLAG_HS200 BIT(8) +/* The IP supports HS400 mode */ +#define ESDHC_FLAG_SUP_HS400 BIT(9) struct esdhc_soc_data { u32 flags; @@ -156,6 +169,12 @@ static struct esdhc_soc_data usdhc_imx6sx_data = { | ESDHC_FLAG_HAVE_CAP1 | ESDHC_FLAG_HS200, }; +static struct esdhc_soc_data usdhc_imx7d_data = { + .flags = ESDHC_FLAG_USDHC | ESDHC_FLAG_STD_TUNING + | ESDHC_FLAG_HAVE_CAP1 | ESDHC_FLAG_HS200 + | ESDHC_FLAG_SUP_HS400, +}; + struct pltfm_imx_data { u32 scratchpad; struct pinctrl *pinctrl; @@ -199,6 +218,7 @@ static const struct of_device_id imx_esdhc_dt_ids[] = { { .compatible = fsl,imx6sx-usdhc, .data = usdhc_imx6sx_data, }, { .compatible = fsl,imx6sl-usdhc, .data = usdhc_imx6sl_data, }, { .compatible = fsl,imx6q-usdhc, .data = usdhc_imx6q_data, }, + { .compatible = fsl,imx7d-usdhc, .data = usdhc_imx7d_data, }, { /* sentinel */ } }; MODULE_DEVICE_TABLE(of, imx_esdhc_dt_ids); @@ -274,6 +294,10 @@ static u32 esdhc_readl_le(struct sdhci_host *host, int reg) val = SDHCI_SUPPORT_DDR50 | SDHCI_SUPPORT_SDR104 | SDHCI_SUPPORT_SDR50 | SDHCI_USE_SDR50_TUNING; + + /* imx7d does not have a support_hs400 register, fake one */ You could remove this line. It's bit, not register and i think no need such comment. + if (imx_data-socdata-flags ESDHC_FLAG_SUP_HS400) + val |= SDHCI_SUPPORT_HS400; } } @@ -774,6 +798,7 @@ static int esdhc_change_pinstate(struct sdhci_host *host, break; case MMC_TIMING_UHS_SDR104: case MMC_TIMING_MMC_HS200: + case MMC_TIMING_MMC_HS400: pinctrl = imx_data-pins_200mhz; break; default: @@ -784,6 +809,30 @@ static int esdhc_change_pinstate(struct sdhci_host *host, return pinctrl_select_state(imx_data-pinctrl, pinctrl); } +static void esdhc_set_strobe_dll(struct sdhci_host *host) It would be good if we can add some comments for this function for better understand. [haibo] okay, I will add comments here. +{ + u32 v; + + /* force a reset on strobe dll */ + writel(ESDHC_STROBE_DLL_CTRL_RESET, host-ioaddr +
[PATCH v2 06/16] mmc: host: omap_hsmmc: remove unnecessary pbias set_voltage
Remove the unnecessary pbias regulator_set_voltage done after pbias regulator_disable in omap_hsmmc_set_power. Signed-off-by: Kishon Vijay Abraham I kis...@ti.com Reviewed-by: Roger Quadros rog...@ti.com --- drivers/mmc/host/omap_hsmmc.c |1 - 1 file changed, 1 deletion(-) diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c index f6b056f..d635a38 100644 --- a/drivers/mmc/host/omap_hsmmc.c +++ b/drivers/mmc/host/omap_hsmmc.c @@ -270,7 +270,6 @@ static int omap_hsmmc_set_power(struct device *dev, int power_on, int vdd) if (!ret) host-pbias_enabled = 0; } - regulator_set_voltage(host-pbias, VDD_3V0, VDD_3V0); } /* -- 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 v2 05/16] mmc: host: omap_hsmmc: use mmc_host's vmmc and vqmmc
No functional change. Instead of using omap_hsmmc_host's vcc and vcc_aux members, use vmmc and vqmmc present in mmc_host which is present for the same purpose. Signed-off-by: Kishon Vijay Abraham I kis...@ti.com Reviewed-by: Roger Quadros rog...@ti.com --- drivers/mmc/host/omap_hsmmc.c | 63 ++--- 1 file changed, 28 insertions(+), 35 deletions(-) diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c index 8cf040f..f6b056f 100644 --- a/drivers/mmc/host/omap_hsmmc.c +++ b/drivers/mmc/host/omap_hsmmc.c @@ -181,15 +181,6 @@ struct omap_hsmmc_host { struct mmc_data*data; struct clk *fclk; struct clk *dbclk; - /* -* vcc == configured supply -* vcc_aux == optional -* - MMC1, supply for DAT4..DAT7 -* - MMC2/MMC2, external level shifter voltage supply, for -* chip (SDIO, eMMC, etc) or transceiver (MMC2 only) -*/ - struct regulator *vcc; - struct regulator *vcc_aux; struct regulator *pbias; boolpbias_enabled; void__iomem *base; @@ -260,13 +251,14 @@ static int omap_hsmmc_set_power(struct device *dev, int power_on, int vdd) { struct omap_hsmmc_host *host = platform_get_drvdata(to_platform_device(dev)); + struct mmc_host *mmc = host-mmc; int ret = 0; /* * If we don't see a Vcc regulator, assume it's a fixed * voltage always-on regulator. */ - if (!host-vcc) + if (!mmc-supply.vmmc) return 0; if (mmc_pdata(host)-before_set_reg) @@ -295,23 +287,23 @@ static int omap_hsmmc_set_power(struct device *dev, int power_on, int vdd) * chips/cards need an interface voltage rail too. */ if (power_on) { - if (host-vcc) - ret = mmc_regulator_set_ocr(host-mmc, host-vcc, vdd); + if (mmc-supply.vmmc) + ret = mmc_regulator_set_ocr(mmc, mmc-supply.vmmc, vdd); /* Enable interface voltage rail, if needed */ - if (ret == 0 host-vcc_aux) { - ret = regulator_enable(host-vcc_aux); - if (ret 0 host-vcc) - ret = mmc_regulator_set_ocr(host-mmc, - host-vcc, 0); + if (ret == 0 mmc-supply.vqmmc) { + ret = regulator_enable(mmc-supply.vqmmc); + if (ret 0 mmc-supply.vmmc) + ret = mmc_regulator_set_ocr(mmc, + mmc-supply.vmmc, + 0); } } else { /* Shut down the rail */ - if (host-vcc_aux) - ret = regulator_disable(host-vcc_aux); - if (host-vcc) { + if (mmc-supply.vqmmc) + ret = regulator_disable(mmc-supply.vqmmc); + if (mmc-supply.vmmc) { /* Then proceed to shut down the local regulator */ - ret = mmc_regulator_set_ocr(host-mmc, - host-vcc, 0); + ret = mmc_regulator_set_ocr(mmc, mmc-supply.vmmc, 0); } } @@ -343,31 +335,32 @@ static int omap_hsmmc_reg_get(struct omap_hsmmc_host *host) { int ocr_value = 0; int ret; + struct mmc_host *mmc = host-mmc; - host-vcc = devm_regulator_get_optional(host-dev, vmmc); - if (IS_ERR(host-vcc)) { - ret = PTR_ERR(host-vcc); + mmc-supply.vmmc = devm_regulator_get_optional(host-dev, vmmc); + if (IS_ERR(mmc-supply.vmmc)) { + ret = PTR_ERR(mmc-supply.vmmc); if (ret != -ENODEV) return ret; dev_dbg(host-dev, unable to get vmmc regulator %ld\n, - PTR_ERR(host-vcc)); - host-vcc = NULL; + PTR_ERR(mmc-supply.vmmc)); + mmc-supply.vmmc = NULL; } else { - ocr_value = mmc_regulator_get_ocrmask(host-vcc); + ocr_value = mmc_regulator_get_ocrmask(mmc-supply.vmmc); if (ocr_value 0) mmc_pdata(host)-ocr_mask = ocr_value; } mmc_pdata(host)-set_power = omap_hsmmc_set_power; /* Allow an aux regulator */ - host-vcc_aux = devm_regulator_get_optional(host-dev, vmmc_aux); - if (IS_ERR(host-vcc_aux)) { - ret = PTR_ERR(host-vcc_aux); + mmc-supply.vqmmc = devm_regulator_get_optional(host-dev, vmmc_aux); + if (IS_ERR(mmc-supply.vqmmc)) { + ret = PTR_ERR(mmc-supply.vqmmc);
[PATCH v2 07/16] mmc: host: omap_hsmmc: return error if any of the regulator APIs fail
Return error if any of the regulator APIs (regulator_enable, regulator_disable, regulator_set_voltage) fails in omap_hsmmc_set_power to avoid undefined behavior. Signed-off-by: Kishon Vijay Abraham I kis...@ti.com --- drivers/mmc/host/omap_hsmmc.c | 52 +++-- 1 file changed, 40 insertions(+), 12 deletions(-) diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c index d635a38..63c9fe7 100644 --- a/drivers/mmc/host/omap_hsmmc.c +++ b/drivers/mmc/host/omap_hsmmc.c @@ -267,8 +267,11 @@ static int omap_hsmmc_set_power(struct device *dev, int power_on, int vdd) if (host-pbias) { if (host-pbias_enabled == 1) { ret = regulator_disable(host-pbias); - if (!ret) - host-pbias_enabled = 0; + if (ret) { + dev_err(dev, pbias reg disable failed\n); + return ret; + } + host-pbias_enabled = 0; } } @@ -286,23 +289,35 @@ static int omap_hsmmc_set_power(struct device *dev, int power_on, int vdd) * chips/cards need an interface voltage rail too. */ if (power_on) { - if (mmc-supply.vmmc) + if (mmc-supply.vmmc) { ret = mmc_regulator_set_ocr(mmc, mmc-supply.vmmc, vdd); + if (ret) + return ret; + } + /* Enable interface voltage rail, if needed */ - if (ret == 0 mmc-supply.vqmmc) { + if (mmc-supply.vqmmc) { ret = regulator_enable(mmc-supply.vqmmc); - if (ret 0 mmc-supply.vmmc) - ret = mmc_regulator_set_ocr(mmc, - mmc-supply.vmmc, - 0); + if (ret) { + dev_err(dev, vmmc_aux reg enable failed\n); + goto err_set_vqmmc; + } } } else { /* Shut down the rail */ - if (mmc-supply.vqmmc) + if (mmc-supply.vqmmc) { ret = regulator_disable(mmc-supply.vqmmc); + if (ret) { + dev_err(dev, vmmc_aux reg disable failed\n); + return ret; + } + } + if (mmc-supply.vmmc) { /* Then proceed to shut down the local regulator */ ret = mmc_regulator_set_ocr(mmc, mmc-supply.vmmc, 0); + if (ret) + return ret; } } @@ -314,19 +329,32 @@ static int omap_hsmmc_set_power(struct device *dev, int power_on, int vdd) ret = regulator_set_voltage(host-pbias, VDD_3V0, VDD_3V0); if (ret 0) - goto error_set_power; + goto err_set_voltage; if (host-pbias_enabled == 0) { ret = regulator_enable(host-pbias); - if (!ret) + if (ret) { + dev_err(dev, pbias reg enable failed\n); + goto err_set_voltage; + } else { host-pbias_enabled = 1; + } } } if (mmc_pdata(host)-after_set_reg) mmc_pdata(host)-after_set_reg(dev, power_on, vdd); -error_set_power: + return 0; + +err_set_voltage: + if (mmc-supply.vqmmc) + regulator_disable(mmc-supply.vqmmc); + +err_set_vqmmc: + if (mmc-supply.vmmc) + mmc_regulator_set_ocr(mmc, mmc-supply.vmmc, 0); + return ret; } -- 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 v2 02/16] mmc: host: omap_hsmmc: return on fatal errors from omap_hsmmc_reg_get
Now return error only if the return value of devm_regulator_get_optional() is not the same as -ENODEV, since with -EPROBE_DEFER, the regulator can be obtained later and all other errors are fatal. Signed-off-by: Kishon Vijay Abraham I kis...@ti.com --- drivers/mmc/host/omap_hsmmc.c | 22 -- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c index b4b1bde..5637793 100644 --- a/drivers/mmc/host/omap_hsmmc.c +++ b/drivers/mmc/host/omap_hsmmc.c @@ -371,10 +371,28 @@ static int omap_hsmmc_reg_get(struct omap_hsmmc_host *host) /* Allow an aux regulator */ reg = devm_regulator_get_optional(host-dev, vmmc_aux); - host-vcc_aux = IS_ERR(reg) ? NULL : reg; + if (IS_ERR(reg)) { + ret = PTR_ERR(reg); + if (ret != -ENODEV) + return ret; + host-vcc_aux = NULL; + dev_dbg(host-dev, unable to get vmmc_aux regulator %ld\n, + PTR_ERR(reg)); + } else { + host-vcc_aux = reg; + } reg = devm_regulator_get_optional(host-dev, pbias); - host-pbias = IS_ERR(reg) ? NULL : reg; + if (IS_ERR(reg)) { + ret = PTR_ERR(reg); + if (ret != -ENODEV) + return ret; + host-pbias = NULL; + dev_dbg(host-dev, unable to get pbias regulator %ld\n, + PTR_ERR(reg)); + } else { + host-pbias = reg; + } /* For eMMC do not power off when not in sleep state */ if (mmc_pdata(host)-no_regulator_off_init) -- 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 v2 04/16] mmc: host: omap_hsmmc: use the ocrmask provided by the vmmc regulator
If the vmmc regulator provides a valid ocrmask, use it. By this even if the pdata has a valid ocrmask, it will be overwritten with the ocrmask of the vmmc regulator. Also remove the unnecessary compatibility check between the ocrmask in the pdata and the ocrmask from the vmmc regulator. Signed-off-by: Kishon Vijay Abraham I kis...@ti.com --- drivers/mmc/host/omap_hsmmc.c | 10 +- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c index 9d062a1..8cf040f 100644 --- a/drivers/mmc/host/omap_hsmmc.c +++ b/drivers/mmc/host/omap_hsmmc.c @@ -354,16 +354,8 @@ static int omap_hsmmc_reg_get(struct omap_hsmmc_host *host) host-vcc = NULL; } else { ocr_value = mmc_regulator_get_ocrmask(host-vcc); - if (!mmc_pdata(host)-ocr_mask) { + if (ocr_value 0) mmc_pdata(host)-ocr_mask = ocr_value; - } else { - if (!(mmc_pdata(host)-ocr_mask ocr_value)) { - dev_err(host-dev, ocrmask %x is not supported\n, - mmc_pdata(host)-ocr_mask); - mmc_pdata(host)-ocr_mask = 0; - return -EINVAL; - } - } } mmc_pdata(host)-set_power = omap_hsmmc_set_power; -- 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 v2 03/16] mmc: host: omap_hsmmc: cleanup omap_hsmmc_reg_get()
No functional change. Instead of using a local regulator variable in omap_hsmmc_reg_get() for holding the return value of devm_regulator_get_optional() and then assigning to omap_hsmmc_host regulator members: vcc, vcc_aux and pbias, directly use the omap_hsmmc_host regulator members. Signed-off-by: Kishon Vijay Abraham I kis...@ti.com Reviewed-by: Roger Quadros rog...@ti.com --- drivers/mmc/host/omap_hsmmc.c | 38 -- 1 file changed, 16 insertions(+), 22 deletions(-) diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c index 5637793..9d062a1 100644 --- a/drivers/mmc/host/omap_hsmmc.c +++ b/drivers/mmc/host/omap_hsmmc.c @@ -341,21 +341,19 @@ error_set_power: static int omap_hsmmc_reg_get(struct omap_hsmmc_host *host) { - struct regulator *reg; int ocr_value = 0; int ret; - reg = devm_regulator_get_optional(host-dev, vmmc); - if (IS_ERR(reg)) { - ret = PTR_ERR(reg); + host-vcc = devm_regulator_get_optional(host-dev, vmmc); + if (IS_ERR(host-vcc)) { + ret = PTR_ERR(host-vcc); if (ret != -ENODEV) return ret; - host-vcc = NULL; dev_dbg(host-dev, unable to get vmmc regulator %ld\n, - PTR_ERR(reg)); + PTR_ERR(host-vcc)); + host-vcc = NULL; } else { - host-vcc = reg; - ocr_value = mmc_regulator_get_ocrmask(reg); + ocr_value = mmc_regulator_get_ocrmask(host-vcc); if (!mmc_pdata(host)-ocr_mask) { mmc_pdata(host)-ocr_mask = ocr_value; } else { @@ -370,28 +368,24 @@ static int omap_hsmmc_reg_get(struct omap_hsmmc_host *host) mmc_pdata(host)-set_power = omap_hsmmc_set_power; /* Allow an aux regulator */ - reg = devm_regulator_get_optional(host-dev, vmmc_aux); - if (IS_ERR(reg)) { - ret = PTR_ERR(reg); + host-vcc_aux = devm_regulator_get_optional(host-dev, vmmc_aux); + if (IS_ERR(host-vcc_aux)) { + ret = PTR_ERR(host-vcc_aux); if (ret != -ENODEV) return ret; - host-vcc_aux = NULL; dev_dbg(host-dev, unable to get vmmc_aux regulator %ld\n, - PTR_ERR(reg)); - } else { - host-vcc_aux = reg; + PTR_ERR(host-vcc_aux)); + host-vcc_aux = NULL; } - reg = devm_regulator_get_optional(host-dev, pbias); - if (IS_ERR(reg)) { - ret = PTR_ERR(reg); + host-pbias = devm_regulator_get_optional(host-dev, pbias); + if (IS_ERR(host-pbias)) { + ret = PTR_ERR(host-pbias); if (ret != -ENODEV) return ret; - host-pbias = NULL; dev_dbg(host-dev, unable to get pbias regulator %ld\n, - PTR_ERR(reg)); - } else { - host-pbias = reg; + PTR_ERR(host-pbias)); + host-pbias = NULL; } /* For eMMC do not power off when not in sleep state */ -- 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] mmc: enable mmc host device to suspend/resume asynchronously
Enable mmc host device to suspend/resume asynchronously. This can improve system suspend/resume speed. Signed-off-by: Zhonghui Fu zhonghui...@linux.intel.com --- drivers/mmc/core/host.c |1 + 1 files changed, 1 insertions(+), 0 deletions(-) diff --git a/drivers/mmc/core/host.c b/drivers/mmc/core/host.c index 99a9c90..85f2bbb 100644 --- a/drivers/mmc/core/host.c +++ b/drivers/mmc/core/host.c @@ -577,6 +577,7 @@ struct mmc_host *mmc_alloc_host(int extra, struct device *dev) host-class_dev.parent = dev; host-class_dev.class = mmc_host_class; device_initialize(host-class_dev); + device_enable_async_suspend(host-class_dev); if (mmc_gpio_alloc(host)) { put_device(host-class_dev); -- 1.7.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