> One more patch is needed to sort out the remaining issue with > omap4 that has yet another luck based initialization for the > same issue.. > I did this patch on top of your series which should fix the issue on all omap4 boards too. Tested on omap4panda and omap4sdp boards. >From 5a4bbd64fd1e791b922b76ea8f12dac4216c0a0f Mon Sep 17 00:00:00 2001 From: Rajendra Nayak <rnayak@xxxxxx> Date: Thu, 16 Feb 2012 17:24:13 +0530 Subject: [PATCH] ARM: OMAP2+: Fix sequencing issues with omap4_twl6030_hsmmc_late_init omap4_twl6030_hsmmc_late_init() relies on twl initialization to happen before the mmc device is probed, which seems to work today just by luck. Now that we have support for deferred mmc init using omap_hsmmc_late_init(), make omap4_twl6030_hsmmc_late_init() to be called only after twl initialization and use omap_hsmmc_late_init() for deferred mmc init. This also fixes mmc card detect on omap4panda, which seems to be broken as card_detect_irq was never passed from omap4panda board file. Reported-by: Tony Lindgren <tony@xxxxxxxxxxx> Signed-off-by: Rajendra Nayak <rnayak@xxxxxx> --- arch/arm/mach-omap2/board-4430sdp.c | 39 +++++----------------------- arch/arm/mach-omap2/board-omap4panda.c | 44 ++++++-------------------------- arch/arm/mach-omap2/hsmmc.c | 7 +++++ drivers/mfd/twl-core.c | 7 +++++ include/linux/i2c/twl.h | 1 + 5 files changed, 30 insertions(+), 68 deletions(-) diff --git a/arch/arm/mach-omap2/board-4430sdp.c b/arch/arm/mach-omap2/board-4430sdp.c index ece9e3a..966ea8d 100644 --- a/arch/arm/mach-omap2/board-4430sdp.c +++ b/arch/arm/mach-omap2/board-4430sdp.c @@ -407,6 +407,7 @@ static struct omap2_hsmmc_info mmc[] = { .caps = MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA, .gpio_cd = -EINVAL, .gpio_wp = -EINVAL, + .deferred = true, }, { .mmc = 5, @@ -455,46 +456,19 @@ static struct platform_device omap_vwlan_device = { }, }; -static int omap4_twl6030_hsmmc_late_init(struct device *dev) +static int omap4_twl6030_hsmmc_late_init(void) { int ret = 0; - struct platform_device *pdev = container_of(dev, - struct platform_device, dev); - struct omap_mmc_platform_data *pdata = dev->platform_data; - - /* Setting MMC1 Card detect Irq */ - if (pdev->id == 0) { - ret = twl6030_mmc_card_detect_config(); - if (ret) - pr_err("Failed configuring MMC1 card detect\n"); - pdata->slots[0].card_detect_irq = TWL6030_IRQ_BASE + - MMCDETECT_INTR_OFFSET; - pdata->slots[0].card_detect = twl6030_mmc_card_detect; - } + ret = twl6030_mmc_card_detect_config(); + if (ret) + pr_err("Failed configuring MMC1 card detect\n"); + omap_hsmmc_late_init(mmc); return ret; } -static __init void omap4_twl6030_hsmmc_set_late_init(struct device *dev) -{ - struct omap_mmc_platform_data *pdata; - - /* dev can be null if CONFIG_MMC_OMAP_HS is not set */ - if (!dev) { - pr_err("Failed %s\n", __func__); - return; - } - pdata = dev->platform_data; - pdata->init = omap4_twl6030_hsmmc_late_init; -} - static int __init omap4_twl6030_hsmmc_init(struct omap2_hsmmc_info *controllers) { - struct omap2_hsmmc_info *c; - omap_hsmmc_init(controllers); - for (c = controllers; c->mmc; c++) - omap4_twl6030_hsmmc_set_late_init(&c->pdev->dev); - return 0; } @@ -583,6 +557,7 @@ static int __init omap4_i2c_init(void) TWL_COMMON_REGULATOR_VCXIO | TWL_COMMON_REGULATOR_VUSB | TWL_COMMON_REGULATOR_CLK32KG); + sdp4430_twldata.setup = omap4_twl6030_hsmmc_late_init; omap4_pmic_init("twl6030", &sdp4430_twldata); omap_register_i2c_bus(2, 400, NULL, 0); omap_register_i2c_bus(3, 400, sdp4430_i2c_3_boardinfo, diff --git a/arch/arm/mach-omap2/board-omap4panda.c b/arch/arm/mach-omap2/board-omap4panda.c index 7ca7a5c..493aa0a 100644 --- a/arch/arm/mach-omap2/board-omap4panda.c +++ b/arch/arm/mach-omap2/board-omap4panda.c @@ -155,6 +155,7 @@ static struct omap2_hsmmc_info mmc[] = { .caps = MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA, .gpio_wp = -EINVAL, .gpio_cd = -EINVAL, + .deferred = true, }, { .name = "wl1271", @@ -204,51 +205,21 @@ struct wl12xx_platform_data omap_panda_wlan_data __initdata = { .board_ref_clock = 2, }; -static int omap4_twl6030_hsmmc_late_init(struct device *dev) +static int omap4_twl6030_hsmmc_late_init(void) { int ret = 0; - struct platform_device *pdev = container_of(dev, - struct platform_device, dev); - struct omap_mmc_platform_data *pdata = dev->platform_data; - if (!pdata) { - dev_err(dev, "%s: NULL platform data\n", __func__); - return -EINVAL; - } - /* Setting MMC1 Card detect Irq */ - if (pdev->id == 0) { - ret = twl6030_mmc_card_detect_config(); - if (ret) - dev_err(dev, "%s: Error card detect config(%d)\n", - __func__, ret); - else - pdata->slots[0].card_detect = twl6030_mmc_card_detect; - } + ret = twl6030_mmc_card_detect_config(); + if (ret) + pr_err("%s: Error MMC card detect config(%d)\n", + __func__, ret); + omap_hsmmc_late_init(mmc); return ret; } -static __init void omap4_twl6030_hsmmc_set_late_init(struct device *dev) -{ - struct omap_mmc_platform_data *pdata; - - /* dev can be null if CONFIG_MMC_OMAP_HS is not set */ - if (!dev) { - pr_err("Failed omap4_twl6030_hsmmc_set_late_init\n"); - return; - } - pdata = dev->platform_data; - - pdata->init = omap4_twl6030_hsmmc_late_init; -} - static int __init omap4_twl6030_hsmmc_init(struct omap2_hsmmc_info *controllers) { - struct omap2_hsmmc_info *c; - omap_hsmmc_init(controllers); - for (c = controllers; c->mmc; c++) - omap4_twl6030_hsmmc_set_late_init(&c->pdev->dev); - return 0; } @@ -277,6 +248,7 @@ static int __init omap4_panda_i2c_init(void) TWL_COMMON_REGULATOR_VCXIO | TWL_COMMON_REGULATOR_VUSB | TWL_COMMON_REGULATOR_CLK32KG); + omap4_panda_twldata.setup = omap4_twl6030_hsmmc_late_init; omap4_pmic_init("twl6030", &omap4_panda_twldata); omap_register_i2c_bus(2, 400, NULL, 0); /* diff --git a/arch/arm/mach-omap2/hsmmc.c b/arch/arm/mach-omap2/hsmmc.c index 59c3ee4..ca9192a 100644 --- a/arch/arm/mach-omap2/hsmmc.c +++ b/arch/arm/mach-omap2/hsmmc.c @@ -14,6 +14,7 @@ #include <linux/string.h> #include <linux/delay.h> #include <linux/gpio.h> +#include <linux/i2c/twl.h> #include <mach/hardware.h> #include <plat/mmc.h> #include <plat/omap-pm.h> @@ -390,6 +391,12 @@ static int __init omap_hsmmc_pdata_init(struct omap2_hsmmc_info *c, if (cpu_is_omap3517() || cpu_is_omap3505()) mmc->slots[0].set_power = nop_mmc_set_power; + if (cpu_is_omap44xx()) { + mmc->slots[0].card_detect = twl6030_mmc_card_detect; + mmc->slots[0].card_detect_irq = TWL6030_IRQ_BASE + + MMCDETECT_INTR_OFFSET; + } + /* OMAP3630 HSMMC1 supports only 4-bit */ if (cpu_is_omap3630() && (c->caps & MMC_CAP_8_BIT_DATA)) { diff --git a/drivers/mfd/twl-core.c b/drivers/mfd/twl-core.c index 8ce3959..753a829 100644 --- a/drivers/mfd/twl-core.c +++ b/drivers/mfd/twl-core.c @@ -1322,6 +1322,13 @@ twl_probe(struct i2c_client *client, const struct i2c_device_id *id) #endif status = add_children(pdata, id->driver_data); + if (pdata->setup) { + int status; + status = pdata->setup(); + if (status) + dev_dbg(&client->dev, "setup --> %d\n", status); + } + fail: if (status < 0) twl_remove(client); diff --git a/include/linux/i2c/twl.h b/include/linux/i2c/twl.h index 78d3465..e2d23bc 100644 --- a/include/linux/i2c/twl.h +++ b/include/linux/i2c/twl.h @@ -747,6 +747,7 @@ struct twl4030_platform_data { struct regulator_init_data *smps3; struct regulator_init_data *smps4; struct regulator_init_data *vio6025; + int (*setup)(void); }; /*----------------------------------------------------------------------*/ -- 1.7.1 -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html