[PATCH 2/3] mmc: sdhci-esdhc: broken card detection is not a default quirk
It can be worked around using a GPIO which will be done for i.MX later. Signed-off-by: Wolfram Sang Acked-by: Anton Vorontsov Tested-by: Marc Reilly Tested-by: Eric Benard --- change since last version: * none drivers/mmc/host/sdhci-esdhc-imx.c |3 ++- drivers/mmc/host/sdhci-esdhc.h |1 - drivers/mmc/host/sdhci-of-esdhc.c |3 ++- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c index 65df00b..49c9801 100644 --- a/drivers/mmc/host/sdhci-esdhc-imx.c +++ b/drivers/mmc/host/sdhci-esdhc-imx.c @@ -171,7 +171,8 @@ static void esdhc_pltfm_exit(struct sdhci_host *host) } struct sdhci_pltfm_data sdhci_esdhc_imx_pdata = { - .quirks = ESDHC_DEFAULT_QUIRKS | SDHCI_QUIRK_BROKEN_ADMA, + .quirks = ESDHC_DEFAULT_QUIRKS | SDHCI_QUIRK_BROKEN_ADMA + | SDHCI_QUIRK_BROKEN_CARD_DETECTION, /* ADMA has issues. Might be fixable */ .ops = &sdhci_esdhc_ops, .init = esdhc_pltfm_init, diff --git a/drivers/mmc/host/sdhci-esdhc.h b/drivers/mmc/host/sdhci-esdhc.h index afaf1bc..c55aae8 100644 --- a/drivers/mmc/host/sdhci-esdhc.h +++ b/drivers/mmc/host/sdhci-esdhc.h @@ -19,7 +19,6 @@ */ #define ESDHC_DEFAULT_QUIRKS (SDHCI_QUIRK_FORCE_BLK_SZ_2048 | \ - SDHCI_QUIRK_BROKEN_CARD_DETECTION | \ SDHCI_QUIRK_NO_BUSY_IRQ | \ SDHCI_QUIRK_NONSTANDARD_CLOCK | \ SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK | \ diff --git a/drivers/mmc/host/sdhci-of-esdhc.c b/drivers/mmc/host/sdhci-of-esdhc.c index fcd0e1f..08161f6 100644 --- a/drivers/mmc/host/sdhci-of-esdhc.c +++ b/drivers/mmc/host/sdhci-of-esdhc.c @@ -73,7 +73,8 @@ static unsigned int esdhc_of_get_min_clock(struct sdhci_host *host) } struct sdhci_of_data sdhci_esdhc = { - .quirks = ESDHC_DEFAULT_QUIRKS, + /* card detection could be handled via GPIO */ + .quirks = ESDHC_DEFAULT_QUIRKS | SDHCI_QUIRK_BROKEN_CARD_DETECTION, .ops = { .read_l = sdhci_be32bs_readl, .read_w = esdhc_readw, -- 1.7.2.3 -- To unsubscribe from this list: send the line "unsubscribe linux-mmc" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 3/3] mmc: sdhci-esdhc-imx: add card detect on custom GPIO for mx25/35
Signed-off-by: Wolfram Sang Tested-by: Marc Reilly Tested-by: Eric Benard --- change since last version: * BROKEN_CARD is default again for now * i.MX5x won't apply the custom IRQ -> same behaviour for i.MX5x as before arch/arm/plat-mxc/include/mach/esdhc.h |2 + drivers/mmc/host/sdhci-esdhc-imx.c | 79 2 files changed, 81 insertions(+), 0 deletions(-) diff --git a/arch/arm/plat-mxc/include/mach/esdhc.h b/arch/arm/plat-mxc/include/mach/esdhc.h index 47da109..86003f4 100644 --- a/arch/arm/plat-mxc/include/mach/esdhc.h +++ b/arch/arm/plat-mxc/include/mach/esdhc.h @@ -16,9 +16,11 @@ * strongly recommended for i.MX25/35, not needed for other variants * * @wp_gpio: gpio for write_protect (-EINVAL if unused) + * @cd_gpio: gpio for card_detect interrupt (-EINVAL if unused) */ struct esdhc_platform_data { unsigned int wp_gpio; + unsigned int cd_gpio; }; #endif /* __ASM_ARCH_IMX_ESDHC_H */ diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c index 49c9801..9be2c3e 100644 --- a/drivers/mmc/host/sdhci-esdhc-imx.c +++ b/drivers/mmc/host/sdhci-esdhc-imx.c @@ -32,6 +32,39 @@ static inline void esdhc_clrset_le(struct sdhci_host *host, u32 mask, u32 val, i writel(((readl(base) & ~(mask << shift)) | (val << shift)), base); } +static u32 esdhc_readl_le(struct sdhci_host *host, int reg) +{ + /* fake CARD_PRESENT flag on mx25/35 */ + u32 val = readl(host->ioaddr + reg); + + if (unlikely(reg == SDHCI_PRESENT_STATE)) { + struct esdhc_platform_data *boarddata = + host->mmc->parent->platform_data; + + if (boarddata && gpio_is_valid(boarddata->cd_gpio) + && gpio_get_value(boarddata->cd_gpio)) + /* no card, if a valid gpio says so... */ + val &= SDHCI_CARD_PRESENT; + else + /* ... in all other cases assume card is present */ + val |= SDHCI_CARD_PRESENT; + } + + return val; +} + +static void esdhc_writel_le(struct sdhci_host *host, u32 val, int reg) +{ + if (unlikely(reg == SDHCI_INT_ENABLE || reg == SDHCI_SIGNAL_ENABLE)) + /* +* these interrupts won't work with a custom card_detect gpio +* (only applied to mx25/35) +*/ + val &= ~(SDHCI_INT_CARD_REMOVE | SDHCI_INT_CARD_INSERT); + + writel(val, host->ioaddr + reg); +} + static u16 esdhc_readw_le(struct sdhci_host *host, int reg) { if (unlikely(reg == SDHCI_HOST_VERSION)) @@ -121,6 +154,14 @@ static struct sdhci_ops sdhci_esdhc_ops = { .get_min_clock = esdhc_pltfm_get_min_clock, }; +static irqreturn_t cd_irq(int irq, void *data) +{ + struct sdhci_host *sdhost = (struct sdhci_host *)data; + + tasklet_schedule(&sdhost->card_tasklet); + return IRQ_HANDLED; +}; + static int esdhc_pltfm_init(struct sdhci_host *host, struct sdhci_pltfm_data *pdata) { struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); @@ -153,9 +194,40 @@ static int esdhc_pltfm_init(struct sdhci_host *host, struct sdhci_pltfm_data *pd "no write-protect pin available!\n"); boarddata->wp_gpio = err; } + + err = gpio_request_one(boarddata->cd_gpio, GPIOF_IN, "ESDHC_CD"); + if (err) { + dev_warn(mmc_dev(host->mmc), + "no card-detect pin available!\n"); + goto no_card_detect_pin; + } + + /* i.MX5x has issues to be researched */ + if (!cpu_is_mx25() && !cpu_is_mx35()) + goto not_supported; + + err = request_irq(gpio_to_irq(boarddata->cd_gpio), cd_irq, +IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING, +mmc_hostname(host->mmc), host); + if (err) { + dev_warn(mmc_dev(host->mmc), "request irq error\n"); + goto no_card_detect_irq; + } + + sdhci_esdhc_ops.write_l = esdhc_writel_le; + sdhci_esdhc_ops.read_l = esdhc_readl_le; + /* Now we have a working card_detect again */ + host->quirks &= ~SDHCI_QUIRK_BROKEN_CARD_DETECTION; } return 0; + + no_card_detect_irq: + gpio_free(boarddata->cd_gpio); + no_card_detect_pin: + boarddata->cd_gpio = err; + not_supported: + return 0; } static void esdhc_pltfm_exit(struct sdhci_host *host) @@ -166,6 +238,13 @@ static void esdhc_pltfm_exit(struct sdhci_host *host) if (boarddata && gpio_is_valid(boarddata->wp_gpio)) gpio_free(boarddata->wp_gpio); + if (boarddata && gpio_is_valid(boarddata->cd_gpio)) { + gp
[PATCH 1/3] mmc: sdhci-esdhc-imx: add support for write protect on custom GPIO on mx25/35
Signed-off-by: Wolfram Sang Tested-by: Marc Reilly Tested-by: Eric Benard --- change since last version: * none arch/arm/plat-mxc/include/mach/esdhc.h | 10 +- drivers/mmc/host/sdhci-esdhc-imx.c | 52 +--- 2 files changed, 50 insertions(+), 12 deletions(-) diff --git a/arch/arm/plat-mxc/include/mach/esdhc.h b/arch/arm/plat-mxc/include/mach/esdhc.h index a48a9aa..47da109 100644 --- a/arch/arm/plat-mxc/include/mach/esdhc.h +++ b/arch/arm/plat-mxc/include/mach/esdhc.h @@ -10,7 +10,15 @@ #ifndef __ASM_ARCH_IMX_ESDHC_H #define __ASM_ARCH_IMX_ESDHC_H +/** + * struct esdhc_platform_data - optional platform data for esdhc on i.MX + * + * strongly recommended for i.MX25/35, not needed for other variants + * + * @wp_gpio: gpio for write_protect (-EINVAL if unused) + */ + struct esdhc_platform_data { - unsigned int wp_gpio; /* write protect pin */ + unsigned int wp_gpio; }; #endif /* __ASM_ARCH_IMX_ESDHC_H */ diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c index 9b82910..65df00b 100644 --- a/drivers/mmc/host/sdhci-esdhc-imx.c +++ b/drivers/mmc/host/sdhci-esdhc-imx.c @@ -15,9 +15,11 @@ #include #include #include +#include #include #include #include +#include #include "sdhci.h" #include "sdhci-pltfm.h" #include "sdhci-esdhc.h" @@ -100,10 +102,31 @@ static unsigned int esdhc_pltfm_get_min_clock(struct sdhci_host *host) return clk_get_rate(pltfm_host->clk) / 256 / 16; } +static unsigned int esdhc_pltfm_get_ro(struct sdhci_host *host) +{ + struct esdhc_platform_data *boarddata = host->mmc->parent->platform_data; + + if (boarddata && gpio_is_valid(boarddata->wp_gpio)) + return gpio_get_value(boarddata->wp_gpio); + else + return -ENOSYS; +} + +static struct sdhci_ops sdhci_esdhc_ops = { + .read_w = esdhc_readw_le, + .write_w = esdhc_writew_le, + .write_b = esdhc_writeb_le, + .set_clock = esdhc_set_clock, + .get_max_clock = esdhc_pltfm_get_max_clock, + .get_min_clock = esdhc_pltfm_get_min_clock, +}; + static int esdhc_pltfm_init(struct sdhci_host *host, struct sdhci_pltfm_data *pdata) { struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); + struct esdhc_platform_data *boarddata = host->mmc->parent->platform_data; struct clk *clk; + int err; clk = clk_get(mmc_dev(host->mmc), NULL); if (IS_ERR(clk)) { @@ -116,9 +139,21 @@ static int esdhc_pltfm_init(struct sdhci_host *host, struct sdhci_pltfm_data *pd if (cpu_is_mx35() || cpu_is_mx51()) host->quirks |= SDHCI_QUIRK_BROKEN_TIMEOUT_VAL; - /* Fix errata ENGcm07207 which is present on i.MX25 and i.MX35 */ - if (cpu_is_mx25() || cpu_is_mx35()) + if (cpu_is_mx25() || cpu_is_mx35()) { + /* Fix errata ENGcm07207 present on i.MX25 and i.MX35 */ host->quirks |= SDHCI_QUIRK_NO_MULTIBLOCK; + /* write_protect can't be routed to controller, use gpio */ + sdhci_esdhc_ops.get_ro = esdhc_pltfm_get_ro; + } + + if (boarddata) { + err = gpio_request_one(boarddata->wp_gpio, GPIOF_IN, "ESDHC_WP"); + if (err) { + dev_warn(mmc_dev(host->mmc), + "no write-protect pin available!\n"); + boarddata->wp_gpio = err; + } + } return 0; } @@ -126,20 +161,15 @@ static int esdhc_pltfm_init(struct sdhci_host *host, struct sdhci_pltfm_data *pd static void esdhc_pltfm_exit(struct sdhci_host *host) { struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); + struct esdhc_platform_data *boarddata = host->mmc->parent->platform_data; + + if (boarddata && gpio_is_valid(boarddata->wp_gpio)) + gpio_free(boarddata->wp_gpio); clk_disable(pltfm_host->clk); clk_put(pltfm_host->clk); } -static struct sdhci_ops sdhci_esdhc_ops = { - .read_w = esdhc_readw_le, - .write_w = esdhc_writew_le, - .write_b = esdhc_writeb_le, - .set_clock = esdhc_set_clock, - .get_max_clock = esdhc_pltfm_get_max_clock, - .get_min_clock = esdhc_pltfm_get_min_clock, -}; - struct sdhci_pltfm_data sdhci_esdhc_imx_pdata = { .quirks = ESDHC_DEFAULT_QUIRKS | SDHCI_QUIRK_BROKEN_ADMA, /* ADMA has issues. Might be fixable */ -- 1.7.2.3 -- 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 V4 0/3] adding write_protect and card_detect for mx25/35
Last tests showed some problems with MX51, especially with card_detect. While the approach in general will suffice for i.MX5x, it seems there are a few details missing right now. Because I do not have the resources (both time and hardware) to deal with these issues, I propose a step by step approach. Let's add the functionality for mx25/35 first and make sure there is no difference in behaviour for mx5x. (Note that the i.MX5x can route the pins directly to the controller, so a properly designed board should not need these gpio-additions.) That is what this patch series does: The main change is that mx5x won't notice any difference. For mx25/35, it is the same as it has been tested by Eric and Marc. Thanks to all involved in providing feedback, I hope it can go in now. If you want to add support for it to your board, please CC me. Have a nice weekend, Wolfram Wolfram Sang (3): mmc: sdhci-esdhc-imx: add support for write protect on custom GPIO on mx25/35 mmc: sdhci-esdhc: broken card detection is not a default quirk mmc: sdhci-esdhc-imx: add card detect on custom GPIO for mx25/35 arch/arm/plat-mxc/include/mach/esdhc.h | 12 +++- drivers/mmc/host/sdhci-esdhc-imx.c | 134 +--- drivers/mmc/host/sdhci-esdhc.h |1 - drivers/mmc/host/sdhci-of-esdhc.c |3 +- 4 files changed, 135 insertions(+), 15 deletions(-) -- 1.7.2.3 -- 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
[RESEND v5 PATCH 2/8] OMAP2430: hwmod data: Add HSMMC
From: Paul Walmsley Update the omap2430 hwmod data with the HSMMC info. For testing OMAP2430SDP with hsmmc hwmod adaptation has dependency on 1) Pauls clock domain fix patch for hsmmc2 http://www.spinics.net/lists/linux-omap/msg47088.html 2) Balaji's regulator patch https://patchwork.kernel.org/patch/538301/ Signed-off-by: Paul Walmsley Signed-off-by: Kevin Hilman Signed-off-by: Rajendra Nayak Cc: Benoit Cousson --- arch/arm/mach-omap2/omap_hwmod_2430_data.c | 148 1 files changed, 148 insertions(+), 0 deletions(-) diff --git a/arch/arm/mach-omap2/omap_hwmod_2430_data.c b/arch/arm/mach-omap2/omap_hwmod_2430_data.c index de0015d..cba1800 100644 --- a/arch/arm/mach-omap2/omap_hwmod_2430_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_2430_data.c @@ -54,6 +54,8 @@ static struct omap_hwmod omap2430_dma_system_hwmod; static struct omap_hwmod omap2430_mcspi1_hwmod; static struct omap_hwmod omap2430_mcspi2_hwmod; static struct omap_hwmod omap2430_mcspi3_hwmod; +static struct omap_hwmod omap2430_mmc1_hwmod; +static struct omap_hwmod omap2430_mmc2_hwmod; /* L3 -> L4_CORE interface */ static struct omap_hwmod_ocp_if omap2430_l3_main__l4_core = { @@ -250,6 +252,42 @@ static struct omap_hwmod_ocp_if *omap2430_usbhsotg_slaves[] = { &omap2430_l4_core__usbhsotg, }; +/* L4 CORE -> MMC1 interface */ +static struct omap_hwmod_addr_space omap2430_mmc1_addr_space[] = { + { + .pa_start = 0x4809c000, + .pa_end = 0x4809c1ff, + .flags = ADDR_TYPE_RT, + }, +}; + +static struct omap_hwmod_ocp_if omap2430_l4_core__mmc1 = { + .master = &omap2430_l4_core_hwmod, + .slave = &omap2430_mmc1_hwmod, + .clk= "mmchs1_ick", + .addr = omap2430_mmc1_addr_space, + .addr_cnt = ARRAY_SIZE(omap2430_mmc1_addr_space), + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* L4 CORE -> MMC2 interface */ +static struct omap_hwmod_addr_space omap2430_mmc2_addr_space[] = { + { + .pa_start = 0x480b4000, + .pa_end = 0x480b41ff, + .flags = ADDR_TYPE_RT, + }, +}; + +static struct omap_hwmod_ocp_if omap2430_l4_core__mmc2 = { + .master = &omap2430_l4_core_hwmod, + .slave = &omap2430_mmc2_hwmod, + .addr = omap2430_mmc2_addr_space, + .clk= "mmchs2_ick", + .addr_cnt = ARRAY_SIZE(omap2430_mmc2_addr_space), + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + /* Slave interfaces on the L4_CORE interconnect */ static struct omap_hwmod_ocp_if *omap2430_l4_core_slaves[] = { &omap2430_l3_main__l4_core, @@ -258,6 +296,8 @@ static struct omap_hwmod_ocp_if *omap2430_l4_core_slaves[] = { /* Master interfaces on the L4_CORE interconnect */ static struct omap_hwmod_ocp_if *omap2430_l4_core_masters[] = { &omap2430_l4_core__l4_wkup, + &omap2430_l4_core__mmc1, + &omap2430_l4_core__mmc2, }; /* L4 CORE */ @@ -1508,6 +1548,112 @@ static struct omap_hwmod omap2430_usbhsotg_hwmod = { +/* MMC/SD/SDIO common */ + +static struct omap_hwmod_class_sysconfig omap2430_mmc_sysc = { + .rev_offs = 0x1fc, + .sysc_offs = 0x10, + .syss_offs = 0x14, + .sysc_flags = (SYSC_HAS_CLOCKACTIVITY | SYSC_HAS_SIDLEMODE | + SYSC_HAS_ENAWAKEUP | SYSC_HAS_SOFTRESET | + SYSC_HAS_AUTOIDLE | SYSS_HAS_RESET_STATUS), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), + .sysc_fields= &omap_hwmod_sysc_type1, +}; + +static struct omap_hwmod_class omap2430_mmc_class = { + .name = "mmc", + .sysc = &omap2430_mmc_sysc, +}; + +/* MMC/SD/SDIO1 */ + +static struct omap_hwmod_irq_info omap2430_mmc1_mpu_irqs[] = { + { .irq = 83 }, +}; + +static struct omap_hwmod_dma_info omap2430_mmc1_sdma_reqs[] = { + { .name = "tx", .dma_req = 61 }, /* DMA_MMC1_TX */ + { .name = "rx", .dma_req = 62 }, /* DMA_MMC1_RX */ +}; + +static struct omap_hwmod_opt_clk omap2430_mmc1_opt_clks[] = { + { .role = "dbck", .clk = "mmchsdb1_fck" }, +}; + +static struct omap_hwmod_ocp_if *omap2430_mmc1_slaves[] = { + &omap2430_l4_core__mmc1, +}; + +static struct omap_hwmod omap2430_mmc1_hwmod = { + .name = "mmc1", + .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET, + .mpu_irqs = omap2430_mmc1_mpu_irqs, + .mpu_irqs_cnt = ARRAY_SIZE(omap2430_mmc1_mpu_irqs), + .sdma_reqs = omap2430_mmc1_sdma_reqs, + .sdma_reqs_cnt = ARRAY_SIZE(omap2430_mmc1_sdma_reqs), + .opt_clks = omap2430_mmc1_opt_clks, + .opt_clks_cnt = ARRAY_SIZE(omap2430_mmc1_opt_clks), + .main_clk = "mmchs1_fck", + .prcm = { + .omap2 = { + .module_offs = CORE_MOD, +
[RESEND v5 PATCH 5/8] OMAP: hwmod data: Add dev_attr and use in the host driver
Add a device attribute to hwmod data of omap2430, omap3, omap4. Currently the device attribute holds information regarding dual volt MMC card support by the controller which will be later passed to the host driver via platform data. Signed-off-by: Kevin Hilman Signed-off-by: Kishore Kadiyala Acked-by: Benoit Cousson --- arch/arm/mach-omap2/omap_hwmod_2430_data.c |6 ++ arch/arm/mach-omap2/omap_hwmod_3xxx_data.c |6 ++ arch/arm/mach-omap2/omap_hwmod_44xx_data.c |8 arch/arm/plat-omap/include/plat/mmc.h |9 + 4 files changed, 29 insertions(+), 0 deletions(-) diff --git a/arch/arm/mach-omap2/omap_hwmod_2430_data.c b/arch/arm/mach-omap2/omap_hwmod_2430_data.c index cba1800..d144540 100644 --- a/arch/arm/mach-omap2/omap_hwmod_2430_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_2430_data.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include "omap_hwmod_common_data.h" @@ -1585,6 +1586,10 @@ static struct omap_hwmod_ocp_if *omap2430_mmc1_slaves[] = { &omap2430_l4_core__mmc1, }; +static struct omap_mmc_dev_attr mmc1_dev_attr = { + .flags = OMAP_HSMMC_SUPPORTS_DUAL_VOLT, +}; + static struct omap_hwmod omap2430_mmc1_hwmod = { .name = "mmc1", .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET, @@ -1604,6 +1609,7 @@ static struct omap_hwmod omap2430_mmc1_hwmod = { .idlest_idle_bit = OMAP2430_ST_MMCHS1_SHIFT, }, }, + .dev_attr = &mmc1_dev_attr, .slaves = omap2430_mmc1_slaves, .slaves_cnt = ARRAY_SIZE(omap2430_mmc1_slaves), .class = &omap2430_mmc_class, diff --git a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c index 7726932..07065c3 100644 --- a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include @@ -2309,6 +2310,10 @@ static struct omap_hwmod_ocp_if *omap3xxx_mmc1_slaves[] = { &omap3xxx_l4_core__mmc1, }; +static struct omap_mmc_dev_attr mmc1_dev_attr = { + .flags = OMAP_HSMMC_SUPPORTS_DUAL_VOLT, +}; + static struct omap_hwmod omap3xxx_mmc1_hwmod = { .name = "mmc1", .mpu_irqs = omap34xx_mmc1_mpu_irqs, @@ -2327,6 +2332,7 @@ static struct omap_hwmod omap3xxx_mmc1_hwmod = { .idlest_idle_bit = OMAP3430_ST_MMC1_SHIFT, }, }, + .dev_attr = &mmc1_dev_attr, .slaves = omap3xxx_mmc1_slaves, .slaves_cnt = ARRAY_SIZE(omap3xxx_mmc1_slaves), .class = &omap34xx_mmc_class, diff --git a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c index dd39e75..0f7d02b 100644 --- a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c @@ -25,6 +25,7 @@ #include #include #include +#include #include "omap_hwmod_common_data.h" @@ -3383,6 +3384,7 @@ static struct omap_hwmod_class omap44xx_mmc_hwmod_class = { }; /* mmc1 */ + static struct omap_hwmod_irq_info omap44xx_mmc1_irqs[] = { { .irq = 83 + OMAP44XX_IRQ_GIC_START }, }; @@ -3420,6 +3422,11 @@ static struct omap_hwmod_ocp_if *omap44xx_mmc1_slaves[] = { &omap44xx_l4_per__mmc1, }; +/* mmc1 dev_attr */ +static struct omap_mmc_dev_attr mmc1_dev_attr = { + .flags = OMAP_HSMMC_SUPPORTS_DUAL_VOLT, +}; + static struct omap_hwmod omap44xx_mmc1_hwmod = { .name = "mmc1", .class = &omap44xx_mmc_hwmod_class, @@ -3433,6 +3440,7 @@ static struct omap_hwmod omap44xx_mmc1_hwmod = { .clkctrl_reg = OMAP4430_CM_L3INIT_MMC1_CLKCTRL, }, }, + .dev_attr = &mmc1_dev_attr, .slaves = omap44xx_mmc1_slaves, .slaves_cnt = ARRAY_SIZE(omap44xx_mmc1_slaves), .masters= omap44xx_mmc1_masters, diff --git a/arch/arm/plat-omap/include/plat/mmc.h b/arch/arm/plat-omap/include/plat/mmc.h index e5de5d4..a7afab0 100644 --- a/arch/arm/plat-omap/include/plat/mmc.h +++ b/arch/arm/plat-omap/include/plat/mmc.h @@ -43,6 +43,12 @@ #define OMAP_MMC_MAX_SLOTS 2 +#define OMAP_HSMMC_SUPPORTS_DUAL_VOLT BIT(1) + +struct omap_mmc_dev_attr { + u8 flags; +}; + struct omap_mmc_platform_data { /* back-link to device */ struct device *dev; @@ -71,6 +77,9 @@ struct omap_mmc_platform_data { u64 dma_mask; + /* Integrating attributes from the omap_hwmod layer */ + u8 controller_flags; + /* Register offset deviation */ u16 reg_offset; -- 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
Re: [PATCH] msm_sdcc: remove needless cache flush after dma_unmap_sg()
On Wed, Feb 16, 2011 at 11:28 PM, Linus Walleij wrote: > dma_unmap_sg() already flushes the cache, I don't get what this > code is doing here. > > Signed-off-by: Linus Walleij Any feedback on this? I'd prefer the maintainer(s) Acked-by, but the patch is pretty clear as it stands I believe and I will request Chris to include it anyway, intuitively it is correct. Yours, Linus Walleij -- 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 v5 7/8] OMAP: adapt hsmmc to hwmod framework
Hi Tony, On Sat, Feb 26, 2011 at 2:27 AM, Tony Lindgren wrote: > * Tony Lindgren [110225 12:42]: >> * Kishore Kadiyala [110225 09:00]: >> > +static int omap_mmc_init(struct omap_hwmod *oh, void *hsmmcinfo) >> ... >> >> > + static int mmc_num; >> > + >> > + c += mmc_num; >> >> This does not look right.. omap2_hsmmc_info is filled in respective board files and will have a call to omap2_hsmmc_init [hsmm.c]. In omap2_hsmmc_init, it will call omap_hwmod_for_each_by_class which takes 3 arguments out of which 2nd one is a callback and 3rd one is void pointer to be passed to call back if necessary. With this the callback "omap_mmc_init" will be called multiple times based on the class entry in hwmod data file for each controller. Say you have 3 controllers as in OMAP3, then "omap_mmc_init" will be called thrice. Here the argument "hsmmcinfo" needs to be incremented for each call, so having a static mmc_num and incrementing it on each call. > > So since mmc_num is static, it gets initialized to 0, then increased > for each call.. What if you want to intialize controller 1 and 3 but > not 2? The current implementation for initialization of MMC controllers will work with any of the below order of devices: 1) MMC1, MMC2, MMC3 2) MMC1, MMC3 3) MMC2, MMC1 4) MMC3, MMC2, MMC1 5) MMC3 > > Also, why do you pass void *hsmmcinfo to the function and then cast > it to struct omap2_hsmmc_inf *? Why not pass struct omap2_hsmmc_info * > to start with? Its because the 3rd argument in omap_hwmod_for_each_by_class is void * . > > Regards, > > Tony > Regards, Kishore -- To unsubscribe from this list: send the line "unsubscribe linux-mmc" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v5 2/8] OMAP2430: hwmod data: Add HSMMC
Hi Paul, On Sat, Feb 26, 2011 at 3:07 AM, Paul Walmsley wrote: > Hello Kishore, > > There are several problems with this data that generate warning messages > on boot on 2430SDP. > > Did you actually test this on 2430SDP? The warning messages would have > been obvious in the boot log. Thanks for catching this. Sorry I missed the warning messages in the boot log. I will resend the patch fixing the comments. > > Comments below: > > On Fri, 25 Feb 2011, Kishore Kadiyala wrote: > >> From: Paul Walmsley >> >> Update the omap2430 hwmod data with the HSMMC info. >> >> Signed-off-by: Paul Walmsley >> Signed-off-by: Kevin Hilman >> Signed-off-by: Rajendra Nayak > Signed-off-by: Kishore Kadiyala >> Cc: Benoit Cousson >> --- >> arch/arm/mach-omap2/omap_hwmod_2430_data.c | 146 >> >> 1 files changed, 146 insertions(+), 0 deletions(-) >> >> diff --git a/arch/arm/mach-omap2/omap_hwmod_2430_data.c >> b/arch/arm/mach-omap2/omap_hwmod_2430_data.c >> index de0015d..a1c3c5e 100644 >> --- a/arch/arm/mach-omap2/omap_hwmod_2430_data.c >> +++ b/arch/arm/mach-omap2/omap_hwmod_2430_data.c >> @@ -54,6 +54,8 @@ static struct omap_hwmod omap2430_dma_system_hwmod; >> static struct omap_hwmod omap2430_mcspi1_hwmod; >> static struct omap_hwmod omap2430_mcspi2_hwmod; >> static struct omap_hwmod omap2430_mcspi3_hwmod; >> +static struct omap_hwmod omap2430_mmc1_hwmod; >> +static struct omap_hwmod omap2430_mmc2_hwmod; >> >> /* L3 -> L4_CORE interface */ >> static struct omap_hwmod_ocp_if omap2430_l3_main__l4_core = { >> @@ -250,6 +252,42 @@ static struct omap_hwmod_ocp_if >> *omap2430_usbhsotg_slaves[] = { >> &omap2430_l4_core__usbhsotg, >> }; >> >> +/* L4 CORE -> MMC1 interface */ >> +static struct omap_hwmod_addr_space omap2430_mmc1_addr_space[] = { >> + { >> + .pa_start = 0x4809c000, >> + .pa_end = 0x4809c1ff, >> + .flags = ADDR_TYPE_RT, >> + }, >> +}; >> + >> +static struct omap_hwmod_ocp_if omap2430_l4_core__mmc1 = { >> + .master = &omap2430_l4_core_hwmod, >> + .slave = &omap2430_mmc1_hwmod, >> + .clk = "mmchs1_ick", >> + .addr = omap2430_mmc1_addr_space, >> + .addr_cnt = ARRAY_SIZE(omap2430_mmc1_addr_space), >> + .user = OCP_USER_MPU | OCP_USER_SDMA, >> +}; >> + >> +/* L4 CORE -> MMC2 interface */ >> +static struct omap_hwmod_addr_space omap2430_mmc2_addr_space[] = { >> + { >> + .pa_start = 0x480b4000, >> + .pa_end = 0x480b41ff, >> + .flags = ADDR_TYPE_RT, >> + }, >> +}; >> + >> +static struct omap_hwmod_ocp_if omap2430_l4_core__mmc2 = { >> + .master = &omap2430_l4_core_hwmod, >> + .slave = &omap2430_mmc2_hwmod, >> + .addr = omap2430_mmc2_addr_space, >> + .clk = "mmchs2_ick", >> + .addr_cnt = ARRAY_SIZE(omap2430_mmc2_addr_space), >> + .user = OCP_USER_MPU | OCP_USER_SDMA, >> +}; >> + >> /* Slave interfaces on the L4_CORE interconnect */ >> static struct omap_hwmod_ocp_if *omap2430_l4_core_slaves[] = { >> &omap2430_l3_main__l4_core, >> @@ -258,6 +296,8 @@ static struct omap_hwmod_ocp_if >> *omap2430_l4_core_slaves[] = { >> /* Master interfaces on the L4_CORE interconnect */ >> static struct omap_hwmod_ocp_if *omap2430_l4_core_masters[] = { >> &omap2430_l4_core__l4_wkup, >> + &omap2430_l4_core__mmc1, >> + &omap2430_l4_core__mmc2, >> }; >> >> /* L4 CORE */ >> @@ -1508,6 +1548,110 @@ static struct omap_hwmod omap2430_usbhsotg_hwmod = { >> >> >> >> +/* MMC/SD/SDIO common */ >> + >> +static struct omap_hwmod_class_sysconfig omap2430_mmc_sysc = { >> + .rev_offs = 0x1fc, >> + .sysc_offs = 0x10, >> + .syss_offs = 0x14, >> + .sysc_flags = (SYSC_HAS_CLOCKACTIVITY | SYSC_HAS_SIDLEMODE | >> + SYSC_HAS_ENAWAKEUP | SYSC_HAS_SOFTRESET | >> + SYSC_HAS_AUTOIDLE | SYSS_HAS_RESET_STATUS), >> + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), >> + .sysc_fields = &omap_hwmod_sysc_type1, >> +}; >> + >> +static struct omap_hwmod_class omap2430_mmc_class = { >> + .name = "mmc", >> + .sysc = &omap2430_mmc_sysc, >> +}; >> + >> +/* MMC/SD/SDIO1 */ >> + >> +static struct omap_hwmod_irq_info omap2430_mmc1_mpu_irqs[] = { >> + { .irq = 83 }, >> +}; >> + >> +static struct omap_hwmod_dma_info omap2430_mmc1_sdma_reqs[] = { >> + { .name = "tx", .dma_req = 61 }, /* DMA_MMC1_TX */ >> + { .name = "rx", .dma_req = 62 }, /* DMA_MMC1_RX */ >> +}; >> + >> +static struct omap_hwmod_opt_clk omap2430_mmc1_opt_clks[] = { >> + { .role = "dbck", .clk = "mmchsdb_fck" }, > > This is not the correct name of the clock. This generates warnings on > boot and prevents the HSMMC block from being soft-reset. Ok , will fix > >> +}; >> + >> +static struct omap_hwmod_ocp_if *omap2430_mmc1_slaves[] = {