Re: [PATCH 12/17] ARM: dts: am57xx-beagle-x15: Fix regulator populated in MMC1 dt node
On 07/29/2015 06:09 AM, Kishon Vijay Abraham I wrote: For beagle x15, both the vdd and io lines are connected to the same regulator (ldo1_reg). However vmmc_aux is populated to vdd_3v3. Remove it. Signed-off-by: Kishon Vijay Abraham I kis...@ti.com --- arch/arm/boot/dts/am57xx-beagle-x15.dts |1 - 1 file changed, 1 deletion(-) diff --git a/arch/arm/boot/dts/am57xx-beagle-x15.dts b/arch/arm/boot/dts/am57xx-beagle-x15.dts index a63bf78..d0db5c5 100644 --- a/arch/arm/boot/dts/am57xx-beagle-x15.dts +++ b/arch/arm/boot/dts/am57xx-beagle-x15.dts @@ -579,7 +579,6 @@ pinctrl-0 = mmc1_pins_default; vmmc-supply = ldo1_reg; - vmmc_aux-supply = vdd_3v3; pbias-supply = pbias_mmc_reg; bus-width = 4; cd-gpios = gpio6 27 0; /* gpio 219 */ Acked-by: Nishanth Menon n...@ti.com -- Regards, Nishanth Menon -- 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: dw_mmc: Add external dma interface support
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. Signed-off-by: Shawn Lin shawn@rock-chips.com --- 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 | 19 - 4 files changed, 206 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 + config MMC_DW_PLTFM tristate Synopsys Designware MCI Support as platform device depends on MMC_DW diff --git a/drivers/mmc/host/dw_mmc-pltfm.c b/drivers/mmc/host/dw_mmc-pltfm.c index ec6dbcd..9475b9f 100644 --- a/drivers/mmc/host/dw_mmc-pltfm.c +++ b/drivers/mmc/host/dw_mmc-pltfm.c @@ -59,6 +59,10 @@ int dw_mci_pltfm_register(struct platform_device *pdev, host-pdata = pdev-dev.platform_data; regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); +#ifdef CONFIG_MMC_DW_EDMAC + /* Get registers' physical base address */ + host-phy_regs = (void *)(regs-start); +#endif host-regs = devm_ioremap_resource(pdev-dev, regs); if (IS_ERR(host-regs)) return PTR_ERR(host-regs); diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c index 40e9d8e..31bb7bb 100644 --- a/drivers/mmc/host/dw_mmc.c +++ b/drivers/mmc/host/dw_mmc.c @@ -441,8 +441,9 @@ static void dw_mci_idmac_stop_dma(struct dw_mci *host) mci_writel(host, BMOD, temp); } -static void dw_mci_idmac_complete_dma(struct dw_mci *host) +static void dw_mci_idmac_complete_dma(void *arg) { + struct dw_mci *host = arg; struct mmc_data *data = host-data; dev_vdbg(host-dev, DMA complete\n); @@ -527,7 +528,7 @@ static void dw_mci_translate_sglist(struct dw_mci *host, struct mmc_data *data, wmb(); } -static void dw_mci_idmac_start_dma(struct dw_mci *host, unsigned int sg_len) +static int dw_mci_idmac_start_dma(struct dw_mci *host, unsigned int sg_len) { u32 temp; @@ -551,6 +552,8 @@ static void dw_mci_idmac_start_dma(struct dw_mci *host, unsigned int sg_len) /* Start it running */ mci_writel(host, PLDMND, 1); + + return 0; } static int dw_mci_idmac_init(struct dw_mci *host) @@ -634,6 +637,144 @@ static const struct dw_mci_dma_ops dw_mci_idmac_ops = { }; #endif /* CONFIG_MMC_DW_IDMAC */ +#ifdef CONFIG_MMC_DW_EDMAC +static void dw_mci_edmac_cleanup(struct dw_mci *host) +{ + struct mmc_data *data = host-data; + + if (data (!data-host_cookie)) + dma_unmap_sg(host-dev, data-sg, +data-sg_len, dw_mci_get_dma_dir(data)); +} + +static void dw_mci_edmac_stop_dma(struct dw_mci *host) +{ + dmaengine_terminate_all(host-dms-ch); +} + +static void dw_mci_edmac_complete_dma(void *arg) +{ + struct dw_mci *host = arg; + struct mmc_data *data = host-data; + + dev_vdbg(host-dev, DMA complete\n); + + if (data data-flags MMC_DATA_READ) + /* Invalidate cache after read */ + dma_sync_sg_for_cpu(mmc_dev(host-cur_slot-mmc), data-sg, + data-sg_len, DMA_FROM_DEVICE); + + host-dma_ops-cleanup(host); + + /* + * If the card was removed, data will be NULL. No point in trying to + * send the stop command or waiting for NBUSY in this case. + */ + if (data) { +
[PATCH v3 6/6] mmc: sdhci-esdhc-imx: set back the burst_length_enable bit to 1
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 #defineESDHC_CTRL_D3CD 0x08 +#define ESDHC_BURST_LEN_EN_INCR(1 27) /* VENDOR SPEC register */ #define ESDHC_VENDOR_SPEC 0xc0 #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. +*/ + 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 v3 4/6] mmc: sdhci-esdhc-imx: add compatible string in bingding doc
Add a required property fsl,imx7d-usdhc in binding doc. Add an optional property fsl,tuning-step in binding doc. Signed-off-by: Haibo Chen haibo.c...@freescale.com --- Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.txt b/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.txt index 211e778..c6624bc 100644 --- a/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.txt +++ b/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.txt @@ -15,6 +15,7 @@ Required properties: fsl,imx6q-usdhc fsl,imx6sl-usdhc fsl,imx6sx-usdhc + fsl,imx7d-usdhc Optional properties: - fsl,wp-controller : Indicate to use controller internal write protection @@ -27,6 +28,7 @@ Optional properties: transparent level shifters on the outputs of the controller. Two cells are required, first cell specifies minimum slot voltage (mV), second cell specifies maximum slot voltage (mV). Several ranges could be specified. +- fsl,tuning-step: Specify the increasing delay cell steps in tuning procedure. Examples: -- 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 v3 3/6] ARM: dts: imx7d-sdb: add eMMC5.0 support
imx7d-sdb board has a eMMC5.0 on usdhc3. This eMMC support HS400. This patch add usdhc3 support for HS400 Signed-off-by: Haibo Chen haibo.c...@freescale.com --- arch/arm/boot/dts/imx7d-sdb.dts | 13 + 1 file changed, 13 insertions(+) diff --git a/arch/arm/boot/dts/imx7d-sdb.dts b/arch/arm/boot/dts/imx7d-sdb.dts index fdd1d7c..8059458 100644 --- a/arch/arm/boot/dts/imx7d-sdb.dts +++ b/arch/arm/boot/dts/imx7d-sdb.dts @@ -241,6 +241,19 @@ status = okay; }; +usdhc3 { + pinctrl-names = default, state_100mhz, state_200mhz; + pinctrl-0 = pinctrl_usdhc3; + pinctrl-1 = pinctrl_usdhc3_100mhz; + pinctrl-2 = pinctrl_usdhc3_200mhz; + assigned-clocks = clks IMX7D_USDHC3_ROOT_CLK; + assigned-clock-rates = 4; + bus-width = 8; + fsl,tuning-step = 2; + non-removable; + status = okay; +}; + iomuxc { pinctrl-names = default; pinctrl-0 = pinctrl_hog; -- 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 v3 5/6] mmc: sdhci-esdhc-imx: config watermark level and burst length
i.MX7D support eMMC HS400 mode, this mode can run in 8 bit,200MHZ DDR mode. So the I/O speed improve a lot compare to SD3.0 The default burst length is 8, if we don't change this value, in HS400 mode, when we do eMMC read operation, we can find that the clock signal will stop for a period of time. This means the speed of data moving on AHB bus is slower than I/O speed. So we should improve the speed of data moving on AHB bus. For imx7d usdhc, this patch set the burst length as 16, and set watermark level as 64. The test result is the clock signal has no stop during the eMMC HS400 operation. For other imx usdhc, remain the default value: burst length as 8, watermark level as 16. Signed-off-by: Haibo Chen haibo.c...@freescale.com --- drivers/mmc/host/sdhci-esdhc-imx.c | 11 ++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c index 158f93b..37d0095 100644 --- a/drivers/mmc/host/sdhci-esdhc-imx.c +++ b/drivers/mmc/host/sdhci-esdhc-imx.c @@ -239,6 +239,11 @@ static inline int is_imx6q_usdhc(struct pltfm_imx_data *data) return data-socdata == usdhc_imx6q_data; } +static inline int is_imx7d_usdhc(struct pltfm_imx_data *data) +{ + return data-socdata == usdhc_imx7d_data; +} + static inline int esdhc_is_usdhc(struct pltfm_imx_data *data) { return !!(data-socdata-flags ESDHC_FLAG_USDHC); @@ -1145,7 +1150,11 @@ static int sdhci_esdhc_imx_probe(struct platform_device *pdev) * to something insane. Change it back here. */ if (esdhc_is_usdhc(imx_data)) { - writel(0x08100810, host-ioaddr + ESDHC_WTMK_LVL); + if (is_imx7d_usdhc(imx_data)) + writel(0x10401040, host-ioaddr + ESDHC_WTMK_LVL); + else + writel(0x08100810, host-ioaddr + ESDHC_WTMK_LVL); + host-quirks2 |= SDHCI_QUIRK2_PRESET_VALUE_BROKEN; host-mmc-caps |= MMC_CAP_1_8V_DDR; -- 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 v3 2/6] mmc: sdhci-esdhc-imx: add tuning-step seting support
tuning-step is the delay cell steps in tuning procedure. The default value of tuning-step is 1. For imx6 series usdhc, tuning procedure can be passed when the tuning-step value is 1. But imx7d usdhc need the tuning-step value as 2, otherwise it can't pass the tuning procedure. So this patch add the tuning-step setting in driver, so that user can set the tuning-step value in dts. Signed-off-by: Haibo Chen haibo.c...@freescale.com --- drivers/mmc/host/sdhci-esdhc-imx.c | 9 + include/linux/platform_data/mmc-esdhc-imx.h | 1 + 2 files changed, 10 insertions(+) diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c index b441eed..158f93b 100644 --- a/drivers/mmc/host/sdhci-esdhc-imx.c +++ b/drivers/mmc/host/sdhci-esdhc-imx.c @@ -75,6 +75,7 @@ #define ESDHC_STD_TUNING_EN(1 24) /* NOTE: the minimum valid tuning start tap for mx6sl is 1 */ #define ESDHC_TUNING_START_TAP 0x1 +#define ESDHC_TUNING_STEP_SHIFT16 /* pinctrl state */ #define ESDHC_PINCTRL_STATE_100MHZ state_100mhz @@ -472,6 +473,7 @@ static void esdhc_writew_le(struct sdhci_host *host, u16 val, int reg) } else if (imx_data-socdata-flags ESDHC_FLAG_STD_TUNING) { u32 v = readl(host-ioaddr + SDHCI_ACMD12_ERR); u32 m = readl(host-ioaddr + ESDHC_MIX_CTRL); + u32 tuning_ctrl; if (val SDHCI_CTRL_TUNED_CLK) { v |= ESDHC_MIX_CTRL_SMPCLK_SEL; } else { @@ -482,6 +484,11 @@ static void esdhc_writew_le(struct sdhci_host *host, u16 val, int reg) if (val SDHCI_CTRL_EXEC_TUNING) { v |= ESDHC_MIX_CTRL_EXE_TUNE; m |= ESDHC_MIX_CTRL_FBCLK_SEL; + tuning_ctrl = readl(host-ioaddr + ESDHC_TUNING_CTRL); + tuning_ctrl |= ESDHC_STD_TUNING_EN | ESDHC_TUNING_START_TAP; + if (imx_data-boarddata.tuning_step) + tuning_ctrl |= imx_data-boarddata.tuning_step ESDHC_TUNING_STEP_SHIFT; + writel(tuning_ctrl, host-ioaddr + ESDHC_TUNING_CTRL); } else { v = ~ESDHC_MIX_CTRL_EXE_TUNE; } @@ -949,6 +956,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, fsl,tuning-step, boarddata-tuning_step); + if (of_find_property(np, no-1-8-v, NULL)) boarddata-support_vsel = false; else diff --git a/include/linux/platform_data/mmc-esdhc-imx.h b/include/linux/platform_data/mmc-esdhc-imx.h index e1571ef..95ccab3 100644 --- a/include/linux/platform_data/mmc-esdhc-imx.h +++ b/include/linux/platform_data/mmc-esdhc-imx.h @@ -45,5 +45,6 @@ struct esdhc_platform_data { int max_bus_width; bool support_vsel; unsigned int delay_line; + unsigned int tuning_step; /* The delay cell steps in tuning procedure */ }; #endif /* __ASM_ARCH_IMX_ESDHC_H */ -- 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 v3 1/6] mmc: sdhci-esdhc-imx: add imx7d support and support HS400
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_CTRL 0x70 +#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_STATUS0x74 +#define ESDHC_STROBE_DLL_STS_REF_LOCK (1 1) +#define ESDHC_STROBE_DLL_STS_SLV_LOCK 0x1 + #define ESDHC_TUNING_CTRL 0xcc #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 */ + 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) +{ + u32 v; + + /* force a reset on strobe dll */ + writel(ESDHC_STROBE_DLL_CTRL_RESET, host-ioaddr + ESDHC_STROBE_DLL_CTRL); + /* +* enable strobe dll ctrl and adjust the delay target +* for the uSDHC loopback read clock +*/ + v = ESDHC_STROBE_DLL_CTRL_ENABLE | + (7 ESDHC_STROBE_DLL_CTRL_SLV_DLY_TARGET_SHIFT); + writel(v, host-ioaddr + ESDHC_STROBE_DLL_CTRL); + /* wait 1us to make sure strobe dll status register stable */ + udelay(1); + v = readl(host-ioaddr + ESDHC_STROBE_DLL_STATUS); + if (!(v ESDHC_STROBE_DLL_STS_REF_LOCK)) + dev_warn(mmc_dev(host-mmc), + warning! HS400 strobe DLL status REF not lock!\n); + if (!(v ESDHC_STROBE_DLL_STS_SLV_LOCK)) + dev_warn(mmc_dev(host-mmc), + warning! HS400 strobe DLL status SLV not lock!\n); +} + static void esdhc_set_uhs_signaling(struct sdhci_host *host, unsigned timing) { struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); @@ -795,7 +844,13 @@ static void esdhc_set_uhs_signaling(struct sdhci_host *host, unsigned timing) case MMC_TIMING_UHS_SDR25: case MMC_TIMING_UHS_SDR50: case
[PATCH v3 0/6] mmc: imx: a few fixes and new feature
Changes for v3: -Add property describe in binding doc. Haibo Chen (6): mmc: sdhci-esdhc-imx: add imx7d support and support HS400 mmc: sdhci-esdhc-imx: add tuning-step seting support ARM: dts: imx7d-sdb: add eMMC5.0 support mmc: sdhci-esdhc-imx: add compatible string in bingding doc mmc: sdhci-esdhc-imx: config watermark level and burst length mmc: sdhci-esdhc-imx: set back the burst_length_enable bit to 1 .../devicetree/bindings/mmc/fsl-imx-esdhc.txt | 2 + arch/arm/boot/dts/imx7d-sdb.dts| 13 +++ drivers/mmc/host/sdhci-esdhc-imx.c | 97 +- include/linux/platform_data/mmc-esdhc-imx.h| 1 + 4 files changed, 112 insertions(+), 1 deletion(-) -- 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
Re: [PATCH v3 0/6] mmc: imx: a few fixes and new feature
On Wed, Jul 29, 2015 at 05:03:51PM +0800, Haibo Chen wrote: Changes for v3: -Add property describe in binding doc. Haibo Chen (6): mmc: sdhci-esdhc-imx: add imx7d support and support HS400 mmc: sdhci-esdhc-imx: add tuning-step seting support ARM: dts: imx7d-sdb: add eMMC5.0 support mmc: sdhci-esdhc-imx: add compatible string in bingding doc mmc: sdhci-esdhc-imx: config watermark level and burst length mmc: sdhci-esdhc-imx: set back the burst_length_enable bit to 1 Hi Haibo, I'm a little busy these days. Will help review it ASAP, maybe can do it tomorrow. Regards Dong Aisheng .../devicetree/bindings/mmc/fsl-imx-esdhc.txt | 2 + arch/arm/boot/dts/imx7d-sdb.dts| 13 +++ drivers/mmc/host/sdhci-esdhc-imx.c | 97 +- include/linux/platform_data/mmc-esdhc-imx.h| 1 + 4 files changed, 112 insertions(+), 1 deletion(-) -- 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
Virtex-5 FPGA PCIE single-function device
[ Please keep me in CC as I'm not subscribed to the list] Hello, We are using the “Virtex-5 FPGA Integrated Endpoint Block for PCI Express” in Linux platform. It supports only a single-function(Header Type, Bit 7 is zero), but actually it is having different functions in different Bar’s. It has UART hardware module implemented in the first Base Address Register and MMC host controller in other Base Address Register. We are planning to develop our own pcie based uart driver for UART hardware and planning to use the MMC kernel stack for MMC host controller. By default MMC kernel stack gets attached to this device. In the pcie based uart driver, tried configuring the uart module after getting the pci_dev structure with pci_get_device(not used the pci_register_driver). After that I could able to communicate with the UART registers even though MMC stack is attached to the device. Now I am puzzled and stuck with how to proceed further on UART Interrupt Service Routine for this kind of device. Can I use request_irq() for uart isr, do you have any suggestion on this? Any hint or help would be greatly appreciated. Regards, Sekhar -- 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 12/17] ARM: dts: am57xx-beagle-x15: Fix regulator populated in MMC1 dt node
For beagle x15, both the vdd and io lines are connected to the same regulator (ldo1_reg). However vmmc_aux is populated to vdd_3v3. Remove it. Signed-off-by: Kishon Vijay Abraham I kis...@ti.com --- arch/arm/boot/dts/am57xx-beagle-x15.dts |1 - 1 file changed, 1 deletion(-) diff --git a/arch/arm/boot/dts/am57xx-beagle-x15.dts b/arch/arm/boot/dts/am57xx-beagle-x15.dts index a63bf78..d0db5c5 100644 --- a/arch/arm/boot/dts/am57xx-beagle-x15.dts +++ b/arch/arm/boot/dts/am57xx-beagle-x15.dts @@ -579,7 +579,6 @@ pinctrl-0 = mmc1_pins_default; vmmc-supply = ldo1_reg; - vmmc_aux-supply = vdd_3v3; pbias-supply = pbias_mmc_reg; bus-width = 4; cd-gpios = gpio6 27 0; /* gpio 219 */ -- 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 13/17] mmc: host: omap_hsmmc: enable/disable vmmc_aux regulator based on prior 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 |4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c index 58bda42..001f8a0 100644 --- a/drivers/mmc/host/omap_hsmmc.c +++ b/drivers/mmc/host/omap_hsmmc.c @@ -258,7 +258,7 @@ 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 !regulator_is_enabled(mmc-supply.vqmmc)) { ret = regulator_enable(mmc-supply.vqmmc); if (ret) { dev_err(mmc_dev(mmc), vmmc_aux reg enable failed\n); @@ -280,7 +280,7 @@ static int omap_hsmmc_disable_supply(struct mmc_host *mmc) int ret; int status; - if (mmc-supply.vqmmc) { + if (mmc-supply.vqmmc regulator_is_enabled(mmc-supply.vqmmc)) { ret = regulator_disable(mmc-supply.vqmmc); if (ret) { dev_err(mmc_dev(mmc), vmmc_aux reg disable failed\n); -- 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 15/17] mmc: host: omap_hsmmc: use ios-vdd for setting vmmc voltage
vdd voltage is set in mmc core to ios-vdd and vmmc should actually be set to this voltage. Modify omap_hsmmc_enable_supply to not take vdd as argument since now it's directly set to the voltage in ios-vdd. Signed-off-by: Kishon Vijay Abraham I kis...@ti.com --- drivers/mmc/host/omap_hsmmc.c |7 --- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c index a50edbc..5116c42 100644 --- a/drivers/mmc/host/omap_hsmmc.c +++ b/drivers/mmc/host/omap_hsmmc.c @@ -246,12 +246,13 @@ static int omap_hsmmc_get_cover_state(struct device *dev) #ifdef CONFIG_REGULATOR -static int omap_hsmmc_enable_supply(struct mmc_host *mmc, int vdd) +static int omap_hsmmc_enable_supply(struct mmc_host *mmc) { int ret; + struct mmc_ios *ios = mmc-ios; if (mmc-supply.vmmc) { - ret = mmc_regulator_set_ocr(mmc, mmc-supply.vmmc, vdd); + ret = mmc_regulator_set_ocr(mmc, mmc-supply.vmmc, ios-vdd); if (ret) return ret; } @@ -380,7 +381,7 @@ 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) { - ret = omap_hsmmc_enable_supply(mmc, vdd); + ret = omap_hsmmc_enable_supply(mmc); if (ret) 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 16/17] 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 5116c42..aa4ba28 100644 --- a/drivers/mmc/host/omap_hsmmc.c +++ b/drivers/mmc/host/omap_hsmmc.c @@ -203,7 +203,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; @@ -244,8 +243,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; @@ -513,29 +510,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, @@ -2195,11 +2169,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; @@ -2242,8 +2215,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) @@ -2267,8 +2239,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 17/17] 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 aa4ba28..6d52873 100644 --- a/drivers/mmc/host/omap_hsmmc.c +++ b/drivers/mmc/host/omap_hsmmc.c @@ -2175,7 +2175,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); @@ -2215,6 +2221,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
[PATCH 14/17] 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 001f8a0..a50edbc 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; resource_size_t mapbase; spinlock_t irq_lock; /* Prevent races with irq handler */ @@ -326,22 +325,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; } } @@ -2073,7 +2070,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; 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 09/17] 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 a0f8c1d..8bb3f60 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 04/17] 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 a78e15e..0e690d7 100644 --- a/drivers/mmc/host/omap_hsmmc.c +++ b/drivers/mmc/host/omap_hsmmc.c @@ -352,16 +352,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 10/17] mmc: host: omap_hsmmc: avoid pbias regulator enable on power off
Fix omap_hsmmc_set_power so that pbias regulator is not enabled during power off. Signed-off-by: Kishon Vijay Abraham I kis...@ti.com --- drivers/mmc/host/omap_hsmmc.c |8 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c index 8bb3f60..2e5c7cd 100644 --- a/drivers/mmc/host/omap_hsmmc.c +++ b/drivers/mmc/host/omap_hsmmc.c @@ -386,16 +386,16 @@ static int omap_hsmmc_set_power(struct device *dev, int power_on, int vdd) ret = omap_hsmmc_enable_supply(mmc, vdd); if (ret) return ret; + + ret = omap_hsmmc_set_pbias(host, true, vdd); + if (ret) + goto err_set_voltage; } else { ret = omap_hsmmc_disable_supply(mmc); if (ret) return ret; } - 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 03/17] 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 7f7625d..a78e15e 100644 --- a/drivers/mmc/host/omap_hsmmc.c +++ b/drivers/mmc/host/omap_hsmmc.c @@ -341,19 +341,17 @@ error_set_power: static int omap_hsmmc_reg_get(struct omap_hsmmc_host *host) { - struct regulator *reg; int ocr_value = 0; - reg = devm_regulator_get_optional(host-dev, vmmc); - if (IS_ERR(reg)) { - if (PTR_ERR(reg) == -EPROBE_DEFER) + host-vcc = devm_regulator_get_optional(host-dev, vmmc); + if (IS_ERR(host-vcc)) { + if (PTR_ERR(host-vcc) == -EPROBE_DEFER) return -EPROBE_DEFER; - 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 { @@ -368,26 +366,22 @@ 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)) { - if (PTR_ERR(reg) == -EPROBE_DEFER) + host-vcc_aux = devm_regulator_get_optional(host-dev, vmmc_aux); + if (IS_ERR(host-vcc_aux)) { + if (PTR_ERR(host-vcc_aux) == -EPROBE_DEFER) return -EPROBE_DEFER; - 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)) { - if (PTR_ERR(reg) == -EPROBE_DEFER) + host-pbias = devm_regulator_get_optional(host-dev, pbias); + if (IS_ERR(host-pbias)) { + if (PTR_ERR(host-pbias) == -EPROBE_DEFER) return -EPROBE_DEFER; - 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 00/17] omap_hsmmc: regulator usage cleanup and fixes
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
[PATCH 01/17] mmc: host: omap_hsmmc: use devm_regulator_get_optional() for vmmc
Since vmmc can be optional for some platforms, use devm_regulator_get_optional() for vmmc. Now return error only in the case of -EPROBE_DEFER and for all other cases set host-vcc to NULL. Signed-off-by: Kishon Vijay Abraham I kis...@ti.com --- drivers/mmc/host/omap_hsmmc.c |8 +--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c index 4d12032..b673e59 100644 --- a/drivers/mmc/host/omap_hsmmc.c +++ b/drivers/mmc/host/omap_hsmmc.c @@ -344,11 +344,13 @@ static int omap_hsmmc_reg_get(struct omap_hsmmc_host *host) struct regulator *reg; int ocr_value = 0; - reg = devm_regulator_get(host-dev, vmmc); + reg = devm_regulator_get_optional(host-dev, vmmc); if (IS_ERR(reg)) { - dev_err(host-dev, unable to get vmmc regulator %ld\n, + if (PTR_ERR(reg) == -EPROBE_DEFER) + return -EPROBE_DEFER; + host-vcc = NULL; + dev_dbg(host-dev, unable to get vmmc regulator %ld\n, PTR_ERR(reg)); - return PTR_ERR(reg); } else { host-vcc = reg; ocr_value = mmc_regulator_get_ocrmask(reg); -- 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 11/17] mmc: host: omap_hsmmc: don't use -set_power to set initial regulator state
If the regulator is enabled on boot (checked using regulator_is_enabled), invoke regulator_enable() so that the usecount reflects the correct state of the regulator and then disable the regulator so that the initial state of the regulator is disabled. Avoid using -set_power, since set_power also takes care of setting the voltages which is not needed at this point. Signed-off-by: Kishon Vijay Abraham I kis...@ti.com --- drivers/mmc/host/omap_hsmmc.c | 67 +++-- 1 file changed, 57 insertions(+), 10 deletions(-) diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c index 2e5c7cd..58bda42 100644 --- a/drivers/mmc/host/omap_hsmmc.c +++ b/drivers/mmc/host/omap_hsmmc.c @@ -407,9 +407,63 @@ err_set_voltage: return ret; } +static int omap_hsmmc_disable_boot_regulator(struct regulator *reg) +{ + int ret; + + if (!reg) + return 0; + + if (regulator_is_enabled(reg)) { + ret = regulator_enable(reg); + if (ret) + return ret; + + ret = regulator_disable(reg); + if (ret) + return ret; + } + + return 0; +} + +static int omap_hsmmc_disable_boot_regulators(struct omap_hsmmc_host *host) +{ + struct mmc_host *mmc = host-mmc; + int ret; + + /* +* disable regulators enabled during boot and get the usecount +* right so that regulators can be enabled/disabled by checking +* the return value of regulator_is_enabled +*/ + ret = omap_hsmmc_disable_boot_regulator(mmc-supply.vmmc); + if (ret) { + dev_err(host-dev, fail to disable boot enabled vmmc reg\n); + return ret; + } + + ret = omap_hsmmc_disable_boot_regulator(mmc-supply.vqmmc); + if (ret) { + dev_err(host-dev, + fail to disable boot enabled vmmc_aux reg\n); + return ret; + } + + ret = omap_hsmmc_disable_boot_regulator(host-pbias); + if (ret) { + dev_err(host-dev, + failed to disable boot enabled pbias reg\n); + return ret; + } + + return 0; +} + static int omap_hsmmc_reg_get(struct omap_hsmmc_host *host) { int ocr_value = 0; + int ret; struct mmc_host *mmc = host-mmc; mmc-supply.vmmc = devm_regulator_get_optional(host-dev, vmmc); @@ -448,17 +502,10 @@ static int omap_hsmmc_reg_get(struct omap_hsmmc_host *host) /* For eMMC do not power off when not in sleep state */ if (mmc_pdata(host)-no_regulator_off_init) return 0; - /* -* To disable boot_on regulator, enable regulator -* to increase usecount and then disable it. -*/ - if ((mmc-supply.vmmc regulator_is_enabled(mmc-supply.vmmc) 0) || - (mmc-supply.vqmmc regulator_is_enabled(mmc-supply.vqmmc))) { - int vdd = ffs(mmc_pdata(host)-ocr_mask) - 1; - mmc_pdata(host)-set_power(host-dev, 1, vdd); - mmc_pdata(host)-set_power(host-dev, 0, 0); - } + ret = omap_hsmmc_disable_boot_regulators(host); + if (ret) + return ret; return 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 08/17] mmc: host: omap_hsmmc: add separate functions for enable/disable supply
No functional change. Cleanup omap_hsmmc_set_power by adding separate functions for enable/disable supply and invoke it from omap_hsmmc_set_power. Signed-off-by: Kishon Vijay Abraham I kis...@ti.com --- drivers/mmc/host/omap_hsmmc.c | 101 +++-- 1 file changed, 66 insertions(+), 35 deletions(-) diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c index d308552..a0f8c1d 100644 --- a/drivers/mmc/host/omap_hsmmc.c +++ b/drivers/mmc/host/omap_hsmmc.c @@ -247,6 +247,65 @@ static int omap_hsmmc_get_cover_state(struct device *dev) #ifdef CONFIG_REGULATOR +static int omap_hsmmc_enable_supply(struct mmc_host *mmc, int vdd) +{ + int ret; + + 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 (mmc-supply.vqmmc) { + ret = regulator_enable(mmc-supply.vqmmc); + if (ret) { + dev_err(mmc_dev(mmc), vmmc_aux reg enable failed\n); + goto err_vqmmc; + } + } + + return 0; + +err_vqmmc: + if (mmc-supply.vmmc) + mmc_regulator_set_ocr(mmc, mmc-supply.vmmc, 0); + + return ret; +} + +static int omap_hsmmc_disable_supply(struct mmc_host *mmc) +{ + int ret; + int status; + + if (mmc-supply.vqmmc) { + ret = regulator_disable(mmc-supply.vqmmc); + if (ret) { + dev_err(mmc_dev(mmc), vmmc_aux reg disable failed\n); + return ret; + } + } + + if (mmc-supply.vmmc) { + ret = mmc_regulator_set_ocr(mmc, mmc-supply.vmmc, 0); + if (ret) + goto err_set_ocr; + } + + return 0; + +err_set_ocr: + if (mmc-supply.vqmmc) { + status = regulator_enable(mmc-supply.vqmmc); + if (status) + dev_err(mmc_dev(mmc), vmmc_aux re-enable failed\n); + } + + return ret; +} + static int omap_hsmmc_set_power(struct device *dev, int power_on, int vdd) { struct omap_hsmmc_host *host = @@ -289,36 +348,13 @@ 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) { - ret = mmc_regulator_set_ocr(mmc, mmc-supply.vmmc, vdd); - if (ret) - return ret; - } - - /* Enable interface voltage rail, if needed */ - if (mmc-supply.vqmmc) { - ret = regulator_enable(mmc-supply.vqmmc); - if (ret) { - dev_err(dev, vmmc_aux reg enable failed\n); - goto err_set_vqmmc; - } - } + ret = omap_hsmmc_enable_supply(mmc, vdd); + if (ret) + return ret; } else { - /* Shut down the rail */ - 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; - } + ret = omap_hsmmc_disable_supply(mmc); + if (ret) + return ret; } if (host-pbias) { @@ -348,12 +384,7 @@ static int omap_hsmmc_set_power(struct device *dev, int power_on, int vdd) 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); + omap_hsmmc_disable_supply(mmc); 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 07/17] 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 7aee1a0..d308552 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 05/17] mmc: host: omap_hsmmc: use mmc_host's vmmc and vqmmc
No functional change. Instead of using our own 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 0e690d7..dad1473 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); } } @@ -342,29 +334,30 @@ error_set_power: static int omap_hsmmc_reg_get(struct omap_hsmmc_host *host) { int ocr_value = 0; + struct mmc_host *mmc = host-mmc; - host-vcc = devm_regulator_get_optional(host-dev, vmmc); - if (IS_ERR(host-vcc)) { - if (PTR_ERR(host-vcc) == -EPROBE_DEFER) + mmc-supply.vmmc = devm_regulator_get_optional(host-dev, vmmc); + if (IS_ERR(mmc-supply.vmmc)) { + if (PTR_ERR(mmc-supply.vmmc) == -EPROBE_DEFER) return -EPROBE_DEFER; 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)) { - if (PTR_ERR(host-vcc_aux) == -EPROBE_DEFER) + mmc-supply.vqmmc = devm_regulator_get_optional(host-dev, vmmc_aux); + if (IS_ERR(mmc-supply.vqmmc)) { + if (PTR_ERR(mmc-supply.vqmmc) ==
[PATCH 02/17] mmc: host: omap_hsmmc: return error from omap_hsmmc_reg_get on -EPROBE_DEFER
EPROBE_DEFER is not fatal and it means the regulator can still be obtained. Hence return error if devm_regulator_get_optional for vmmc_aux and pbias returns -EPROBE_DEFER. This gives omap_hsmmc driver another chance to get these regulators. Signed-off-by: Kishon Vijay Abraham I kis...@ti.com --- drivers/mmc/host/omap_hsmmc.c | 20 ++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c index b673e59..7f7625d 100644 --- a/drivers/mmc/host/omap_hsmmc.c +++ b/drivers/mmc/host/omap_hsmmc.c @@ -369,10 +369,26 @@ 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)) { + if (PTR_ERR(reg) == -EPROBE_DEFER) + return -EPROBE_DEFER; + 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)) { + if (PTR_ERR(reg) == -EPROBE_DEFER) + return -EPROBE_DEFER; + 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
Re: [PATCH 01/17] mmc: host: omap_hsmmc: use devm_regulator_get_optional() for vmmc
On 07/29/2015 02:09 PM, Kishon Vijay Abraham I wrote: Since vmmc can be optional for some platforms, use devm_regulator_get_optional() for vmmc. Now return error only in the case of -EPROBE_DEFER and for all other cases set host-vcc to NULL. Signed-off-by: Kishon Vijay Abraham I kis...@ti.com --- drivers/mmc/host/omap_hsmmc.c |8 +--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c index 4d12032..b673e59 100644 --- a/drivers/mmc/host/omap_hsmmc.c +++ b/drivers/mmc/host/omap_hsmmc.c @@ -344,11 +344,13 @@ static int omap_hsmmc_reg_get(struct omap_hsmmc_host *host) struct regulator *reg; int ocr_value = 0; - reg = devm_regulator_get(host-dev, vmmc); + reg = devm_regulator_get_optional(host-dev, vmmc); if (IS_ERR(reg)) { - dev_err(host-dev, unable to get vmmc regulator %ld\n, + if (PTR_ERR(reg) == -EPROBE_DEFER) + return -EPROBE_DEFER; + host-vcc = NULL; + dev_dbg(host-dev, unable to get vmmc regulator %ld\n, PTR_ERR(reg)); - return PTR_ERR(reg); I think, It could be unsafe to just drop this return. regulator_get_optional may return: 1 valid pointer on regulator : success; 2 ERR_PTR(-ENODEV) : regulator is not assigned, can proceed. 3 ERR_PTR(-EPROBE_DEFER) : regulator is assigned, but not ready yet, retry. 4 ERR_PTR(other error codes: regulator is assigned, but can't be retrieved, failure, can't proceed So, It's allowed to continue with host-vcc = NULL; only in case [2], while in case [4] probe should fail. } else { host-vcc = reg; ocr_value = mmc_regulator_get_ocrmask(reg); -- regards, -grygorii -- 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 3/3] MAINTAINERS: add entry for Atmel sdhci-of-at91 driver
Add an entry for Atmel SDMMC device. Signed-off-by: Ludovic Desroches ludovic.desroc...@atmel.com --- MAINTAINERS | 6 ++ 1 file changed, 6 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index e7bdbac..6480ce9 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1880,6 +1880,12 @@ L: linux-...@lists.infradead.org S: Supported F: drivers/mtd/nand/atmel_nand* +ATMEL SDMMC DRIVER +M: Ludovic Desroches ludovic.desroc...@atmel.com +L: linux-mmc@vger.kernel.org +S: Supported +F: drivers/mmc/host/sdhci-of-at91.c + ATMEL SPI DRIVER M: Nicolas Ferre nicolas.fe...@atmel.com S: Supported -- 2.5.0 -- 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 0/3] introduce driver for the Atmel SDMMC
Hi, This set of patches introduce a driver for the new Atmel SDMMC device avaible on SAMA5D2 SoC. There is also a resend of an old patch which has not been taken. Ulf asked for some reviews since it could impact all sdhci devices but nobody did it... This patch is not necessary for patch 2/3. It only fixes a special use case. If there are objections about it, drop it, I don't want to delay the Atmel SDMMC driver inclusion only for this patch. Changes: - from v1: - update license Ludovic Desroches (3): mmc: sdhci: switch from programmable clock mode to divided one if needed mmc: sdhci-of-at91: introduce driver for the Atmel SDMMC MAINTAINERS: add entry for Atmel sdhci-of-at91 driver .../devicetree/bindings/mmc/sdhci-atmel.txt| 21 +++ MAINTAINERS| 6 + drivers/mmc/host/Kconfig | 8 + drivers/mmc/host/Makefile | 1 + drivers/mmc/host/sdhci-of-at91.c | 192 + drivers/mmc/host/sdhci.c | 29 +++- 6 files changed, 248 insertions(+), 9 deletions(-) create mode 100644 Documentation/devicetree/bindings/mmc/sdhci-atmel.txt create mode 100644 drivers/mmc/host/sdhci-of-at91.c -- 2.5.0 -- 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 2/3] mmc: sdhci-of-at91: introduce driver for the Atmel SDMMC
Introduce driver for he Atmel SDMMC available on sama5d2. It is a sdhci compliant controller. Signed-off-by: Ludovic Desroches ludovic.desroc...@atmel.com --- .../devicetree/bindings/mmc/sdhci-atmel.txt| 21 +++ drivers/mmc/host/Kconfig | 8 + drivers/mmc/host/Makefile | 1 + drivers/mmc/host/sdhci-of-at91.c | 192 + 4 files changed, 222 insertions(+) create mode 100644 Documentation/devicetree/bindings/mmc/sdhci-atmel.txt create mode 100644 drivers/mmc/host/sdhci-of-at91.c diff --git a/Documentation/devicetree/bindings/mmc/sdhci-atmel.txt b/Documentation/devicetree/bindings/mmc/sdhci-atmel.txt new file mode 100644 index 000..1b662d7 --- /dev/null +++ b/Documentation/devicetree/bindings/mmc/sdhci-atmel.txt @@ -0,0 +1,21 @@ +* Atmel SDHCI controller + +This file documents the differences between the core properties in +Documentation/devicetree/bindings/mmc/mmc.txt and the properties used by the +sdhci-of-at91 driver. + +Required properties: +- compatible: Must be atmel,sama5d2-sdhci. +- clocks: Phandlers to the clocks. +- clock-names: Must be hclock, multclk, baseclk; + + +Example: + +sdmmc0: sdio-host@a000 { + compatible = atmel,sama5d2-sdhci; + reg = 0xa000 0x300; + interrupts = 31 IRQ_TYPE_LEVEL_HIGH 0; + clocks = sdmmc0_hclk, sdmmc0_gclk, main; + clock-names = hclock, multclk, baseclk; +}; diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig index fd9a58e..c1c75e8 100644 --- a/drivers/mmc/host/Kconfig +++ b/drivers/mmc/host/Kconfig @@ -129,6 +129,14 @@ config MMC_SDHCI_OF_ARASAN If unsure, say N. +config MMC_SDHCI_OF_AT91 + tristate SDHCI OF support for the Atmel SDMMC controller + depends on MMC_SDHCI_PLTFM + depends on OF + select MMC_SDHCI_IO_ACCESSORS + help + This selects the Atmel SDMMC driver + config MMC_SDHCI_OF_ESDHC tristate SDHCI OF support for the Freescale eSDHC controller depends on MMC_SDHCI_PLTFM diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile index e928d61..4f3452a 100644 --- a/drivers/mmc/host/Makefile +++ b/drivers/mmc/host/Makefile @@ -67,6 +67,7 @@ obj-$(CONFIG_MMC_SDHCI_ESDHC_IMX) += sdhci-esdhc-imx.o obj-$(CONFIG_MMC_SDHCI_DOVE) += sdhci-dove.o obj-$(CONFIG_MMC_SDHCI_TEGRA) += sdhci-tegra.o obj-$(CONFIG_MMC_SDHCI_OF_ARASAN) += sdhci-of-arasan.o +obj-$(CONFIG_MMC_SDHCI_OF_AT91)+= sdhci-of-at91.o obj-$(CONFIG_MMC_SDHCI_OF_ESDHC) += sdhci-of-esdhc.o obj-$(CONFIG_MMC_SDHCI_OF_HLWD)+= sdhci-of-hlwd.o obj-$(CONFIG_MMC_SDHCI_BCM_KONA) += sdhci-bcm-kona.o diff --git a/drivers/mmc/host/sdhci-of-at91.c b/drivers/mmc/host/sdhci-of-at91.c new file mode 100644 index 000..7a9f4b1 --- /dev/null +++ b/drivers/mmc/host/sdhci-of-at91.c @@ -0,0 +1,192 @@ +/* + * Atmel SDMMC controller driver. + * + * Copyright (C) 2015 Atmel, + * 2015 Ludovic Desroches ludovic.desroc...@atmel.com + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include linux/clk.h +#include linux/err.h +#include linux/io.h +#include linux/mmc/host.h +#include linux/module.h +#include linux/of.h +#include linux/of_device.h + +#include sdhci-pltfm.h + +#define SDMMC_CACR 0x230 +#defineSDMMC_CACR_CAPWREN BIT(0) +#defineSDMMC_CACR_KEY (0x46 8) + +struct sdhci_at91_priv { + struct clk *hclock; + struct clk *gck; + struct clk *mainck; +}; + +static const struct sdhci_ops sdhci_at91_sama5d2_ops = { + .set_clock = sdhci_set_clock, + .set_bus_width = sdhci_set_bus_width, + .reset = sdhci_reset, + .set_uhs_signaling = sdhci_set_uhs_signaling, +}; + +static const struct sdhci_pltfm_data soc_data_sama5d2 = { + .ops = sdhci_at91_sama5d2_ops, +}; + +static const struct of_device_id sdhci_at91_dt_match[] = { + { .compatible = atmel,sama5d2-sdhci, .data = soc_data_sama5d2 }, + {} +}; + +static int sdhci_at91_probe(struct platform_device *pdev) +{ + const struct of_device_id *match; + const struct sdhci_pltfm_data *soc_data; + struct sdhci_host *host; + struct sdhci_pltfm_host *pltfm_host; + struct sdhci_at91_priv *priv; + unsigned intcaps0, caps1; + unsigned intclk_base, clk_mul; +
[PATCH v2 1/3] mmc: sdhci: switch from programmable clock mode to divided one if needed
In programmable mode, if the clock frequency is too high, the divider can be too small to meet the clock frequency requirement especially to init the SD card. In this case, switch to the divided clock mode. Signed-off-by: Ludovic Desroches ludovic.desroc...@atmel.com --- drivers/mmc/host/sdhci.c | 29 - 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index bc14452..32cf274 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c @@ -1152,6 +1152,7 @@ void sdhci_set_clock(struct sdhci_host *host, unsigned int clock) int real_div = div, clk_mul = 1; u16 clk = 0; unsigned long timeout; + bool switch_base_clk = false; host-mmc-actual_clock = 0; @@ -1189,15 +1190,25 @@ void sdhci_set_clock(struct sdhci_host *host, unsigned int clock) = clock) break; } - /* -* Set Programmable Clock Mode in the Clock -* Control register. -*/ - clk = SDHCI_PROG_CLOCK_MODE; - real_div = div; - clk_mul = host-clk_mul; - div--; - } else { + if ((host-max_clk * host-clk_mul / div) = clock) { + /* +* Set Programmable Clock Mode in the Clock +* Control register. +*/ + clk = SDHCI_PROG_CLOCK_MODE; + real_div = div; + clk_mul = host-clk_mul; + div--; + } else { + /* +* Divisor can be too small to reach clock +* speed requirement. Then use the base clock. +*/ + switch_base_clk = true; + } + } + + if (!host-clk_mul || switch_base_clk) { /* Version 3.00 divisors must be a multiple of 2. */ if (host-max_clk = clock) div = 1; -- 2.5.0 -- 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