[PATCH v2 5/7] ARM: OMAP2+: Split omap2_hsmmc_init() to properly support I2C GPIO pins
Igor Grinberg
grinberg at compulab.co.il
Thu Feb 23 09:28:15 EST 2012
Hi Tony, Rajendra,
On 02/23/12 13:40, Rajendra Nayak wrote:
> From: Tony Lindgren <tony at atomide.com>
>
> Otherwise omap_device_build() and omap_mux related functions
> can't be marked as __init when twl is build as a module.
>
> If a board is using GPIO pins or regulators configured by an
> external chip, such as TWL PMIC on I2C bus, the board must
> mark those MMC controllers as deferred. Additionally both
> omap_hsmmc_init() and omap_hsmmc_deferred_add() must be called
> by the board.
>
> For MMC controllers using internal GPIO pins for card
> detect and regulators the slots don't need to be marked
> deferred. In this case calling omap_hsmmc_init() is sufficient.
>
> Note that this patch does not change the behaviour for
> board-4430sdp.c board-omap4panda.c. These boards wrongly
> rely on the omap_hsmmc.c init function callback to configure
> the PMIC GPIO interrupt lines on external chip. If the PMIC
> interrupt lines are not configured during init, they will
> fail.
>
> Reported-by: Russell King <rmk+kernel at arm.linux.org.uk>
> Signed-off-by: Tony Lindgren <tony at atomide.com>
> Signed-off-by: Rajendra Nayak <rnayak at ti.com>
> ---
> arch/arm/mach-omap2/board-2430sdp.c | 2 +-
> arch/arm/mach-omap2/board-3430sdp.c | 12 ++--
> arch/arm/mach-omap2/board-4430sdp.c | 4 +-
> arch/arm/mach-omap2/board-am3517evm.c | 2 +-
> arch/arm/mach-omap2/board-cm-t35.c | 10 +-
> arch/arm/mach-omap2/board-devkit8000.c | 7 +-
> arch/arm/mach-omap2/board-igep0020.c | 11 ++-
> arch/arm/mach-omap2/board-ldp.c | 2 +-
> arch/arm/mach-omap2/board-omap3beagle.c | 7 +-
> arch/arm/mach-omap2/board-omap3evm.c | 9 +-
> arch/arm/mach-omap2/board-omap3logic.c | 2 +-
> arch/arm/mach-omap2/board-omap3pandora.c | 13 ++--
> arch/arm/mach-omap2/board-omap3stalker.c | 14 ++--
> arch/arm/mach-omap2/board-omap3touchbook.c | 7 +-
> arch/arm/mach-omap2/board-omap4panda.c | 4 +-
> arch/arm/mach-omap2/board-overo.c | 5 +-
> arch/arm/mach-omap2/board-rm680.c | 2 +-
> arch/arm/mach-omap2/board-rx51-peripherals.c | 2 +-
> arch/arm/mach-omap2/board-zoom-peripherals.c | 9 ++-
> arch/arm/mach-omap2/hsmmc.c | 117 +++++++++++++++++++-------
> arch/arm/mach-omap2/hsmmc.h | 13 ++-
> 21 files changed, 165 insertions(+), 89 deletions(-)
[...]
> diff --git a/arch/arm/mach-omap2/board-cm-t35.c b/arch/arm/mach-omap2/board-cm-t35.c
> index d73316e..14df109 100644
> --- a/arch/arm/mach-omap2/board-cm-t35.c
> +++ b/arch/arm/mach-omap2/board-cm-t35.c
> @@ -411,9 +411,9 @@ static struct omap2_hsmmc_info mmc[] = {
> {
> .mmc = 1,
> .caps = MMC_CAP_4_BIT_DATA,
> - .gpio_cd = -EINVAL,
> + .gpio_cd = OMAP_MAX_GPIO_LINES + 0,
> .gpio_wp = -EINVAL,
> -
> + .deferred = true,
> },
> {
> .mmc = 2,
> @@ -422,6 +422,7 @@ static struct omap2_hsmmc_info mmc[] = {
> .gpio_cd = -EINVAL,
> .gpio_wp = -EINVAL,
> .ocr_mask = 0x00100000, /* 3.3V */
> + .deferred = true,
Why do you defer this one?
It does not use external GPIO chip, in fact it does not use CD/WP at all.
> },
> {} /* Terminator */
> };
> @@ -469,9 +470,7 @@ static int cm_t35_twl_gpio_setup(struct device *dev, unsigned gpio,
> pr_err("CM-T35: could not obtain gpio for WiFi reset\n");
> }
>
> - /* gpio + 0 is "mmc0_cd" (input/IRQ) */
> - mmc[0].gpio_cd = gpio + 0;
> - omap2_hsmmc_init(mmc);
> + omap_hsmmc_deferred_add(mmc);
>
> return 0;
> }
> @@ -639,6 +638,7 @@ static void __init cm_t3x_common_init(void)
> omap_serial_init();
> omap_sdrc_init(mt46h32m32lf6_sdrc_params,
> mt46h32m32lf6_sdrc_params);
> + omap_hsmmc_init(mmc);
> cm_t35_init_i2c();
> omap_ads7846_init(1, CM_T35_GPIO_PENDOWN, 0, NULL);
> cm_t35_init_ethernet();
Other then the comment above, looks fine.
I will probably be able to test this on Sunday.
[...]
> diff --git a/arch/arm/mach-omap2/board-igep0020.c b/arch/arm/mach-omap2/board-igep0020.c
> index a59ace0..11a6aa4 100644
> --- a/arch/arm/mach-omap2/board-igep0020.c
> +++ b/arch/arm/mach-omap2/board-igep0020.c
> @@ -293,8 +293,9 @@ static struct omap2_hsmmc_info mmc[] = {
> {
> .mmc = 1,
> .caps = MMC_CAP_4_BIT_DATA,
> - .gpio_cd = -EINVAL,
> + .gpio_cd = OMAP_MAX_GPIO_LINES + 0,
> .gpio_wp = -EINVAL,
> + .deferred = true,
> },
> #if defined(CONFIG_LIBERTAS_SDIO) || defined(CONFIG_LIBERTAS_SDIO_MODULE)
> {
> @@ -302,6 +303,7 @@ static struct omap2_hsmmc_info mmc[] = {
> .caps = MMC_CAP_4_BIT_DATA,
> .gpio_cd = -EINVAL,
> .gpio_wp = -EINVAL,
> + .deferred = true,
same here, why defer it?
> },
> #endif
> {} /* Terminator */
> @@ -400,9 +402,7 @@ static int igep_twl_gpio_setup(struct device *dev,
> {
> int ret;
>
> - /* gpio + 0 is "mmc0_cd" (input/IRQ) */
> - mmc[0].gpio_cd = gpio + 0;
> - omap2_hsmmc_init(mmc);
> + omap_hsmmc_deferred_add(mmc);
>
> /* TWL4030_GPIO_MAX + 1 == ledB (out, active low LED) */
> #if !defined(CONFIG_LEDS_GPIO) && !defined(CONFIG_LEDS_GPIO_MODULE)
> @@ -639,6 +639,9 @@ static void __init igep_init(void)
>
> /* Get IGEP2 hardware revision */
> igep2_get_revision();
> +
> + omap_hsmmc_init(mmc);
> +
> /* Register I2C busses and drivers */
> igep_i2c_init();
> platform_add_devices(igep_devices, ARRAY_SIZE(igep_devices));
[...]
> diff --git a/arch/arm/mach-omap2/board-omap3evm.c b/arch/arm/mach-omap2/board-omap3evm.c
> index c775bea..b736c4d 100644
> --- a/arch/arm/mach-omap2/board-omap3evm.c
> +++ b/arch/arm/mach-omap2/board-omap3evm.c
> @@ -315,8 +315,9 @@ static struct omap2_hsmmc_info mmc[] = {
> {
> .mmc = 1,
> .caps = MMC_CAP_4_BIT_DATA,
> - .gpio_cd = -EINVAL,
> + .gpio_cd = OMAP_MAX_GPIO_LINES + 0,
> .gpio_wp = 63,
> + .deferred = true,
> },
> #ifdef CONFIG_WL12XX_PLATFORM_DATA
> {
> @@ -326,6 +327,7 @@ static struct omap2_hsmmc_info mmc[] = {
> .gpio_wp = -EINVAL,
> .gpio_cd = -EINVAL,
> .nonremovable = true,
> + .deferred = true,
ditto
> },
> #endif
> {} /* Terminator */
> @@ -360,10 +362,8 @@ static int omap3evm_twl_gpio_setup(struct device *dev,
> {
> int r, lcd_bl_en;
>
> - /* gpio + 0 is "mmc0_cd" (input/IRQ) */
> omap_mux_init_gpio(63, OMAP_PIN_INPUT);
> - mmc[0].gpio_cd = gpio + 0;
> - omap2_hsmmc_init(mmc);
> + omap_hsmmc_deferred_add(mmc);
>
> /*
> * Most GPIOs are for USB OTG. Some are mostly sent to
> @@ -644,6 +644,7 @@ static void __init omap3_evm_init(void)
> omap_board_config = omap3_evm_config;
> omap_board_config_size = ARRAY_SIZE(omap3_evm_config);
>
> + omap_hsmmc_init(mmc);
> omap3_evm_i2c_init();
>
> omap_display_init(&omap3_evm_dss_data);
[...]
> diff --git a/arch/arm/mach-omap2/board-omap3pandora.c b/arch/arm/mach-omap2/board-omap3pandora.c
> index 1644b73..d984048 100644
> --- a/arch/arm/mach-omap2/board-omap3pandora.c
> +++ b/arch/arm/mach-omap2/board-omap3pandora.c
> @@ -270,17 +270,19 @@ static struct omap2_hsmmc_info omap3pandora_mmc[] = {
> {
> .mmc = 1,
> .caps = MMC_CAP_4_BIT_DATA,
> - .gpio_cd = -EINVAL,
> + .gpio_cd = OMAP_MAX_GPIO_LINES + 0,
> .gpio_wp = 126,
> .ext_clock = 0,
> + .deferred = true,
> },
> {
> .mmc = 2,
> .caps = MMC_CAP_4_BIT_DATA,
> - .gpio_cd = -EINVAL,
> + .gpio_cd = OMAP_MAX_GPIO_LINES + 1,
> .gpio_wp = 127,
> .ext_clock = 1,
> .transceiver = true,
> + .deferred = true,
> },
> {
> .mmc = 3,
> @@ -288,6 +290,7 @@ static struct omap2_hsmmc_info omap3pandora_mmc[] = {
> .gpio_cd = -EINVAL,
> .gpio_wp = -EINVAL,
> .init_card = pandora_wl1251_init_card,
> + .deferred = true,
ditto
> },
> {} /* Terminator */
> };
> @@ -297,10 +300,7 @@ static int omap3pandora_twl_gpio_setup(struct device *dev,
> {
> int ret, gpio_32khz;
>
> - /* gpio + {0,1} is "mmc{0,1}_cd" (input/IRQ) */
> - omap3pandora_mmc[0].gpio_cd = gpio + 0;
> - omap3pandora_mmc[1].gpio_cd = gpio + 1;
> - omap2_hsmmc_init(omap3pandora_mmc);
> + omap_hsmmc_deferred_add(omap3pandora_mmc);
>
> /* gpio + 13 drives 32kHz buffer for wifi module */
> gpio_32khz = gpio + 13;
> @@ -580,6 +580,7 @@ static struct omap_board_mux board_mux[] __initdata = {
> static void __init omap3pandora_init(void)
> {
> omap3_mux_init(board_mux, OMAP_PACKAGE_CBB);
> + omap_hsmmc_init(omap3pandora_mmc);
> omap3pandora_i2c_init();
> pandora_wl1251_init();
> platform_add_devices(omap3pandora_devices,
[...]
> diff --git a/arch/arm/mach-omap2/board-overo.c b/arch/arm/mach-omap2/board-overo.c
> index 52c0cef..8b6065b 100644
> --- a/arch/arm/mach-omap2/board-overo.c
> +++ b/arch/arm/mach-omap2/board-overo.c
> @@ -301,6 +301,7 @@ static struct omap2_hsmmc_info mmc[] = {
> .caps = MMC_CAP_4_BIT_DATA,
> .gpio_cd = -EINVAL,
> .gpio_wp = -EINVAL,
> + .deferred = true,
> },
> {
> .mmc = 2,
> @@ -309,6 +310,7 @@ static struct omap2_hsmmc_info mmc[] = {
> .gpio_wp = -EINVAL,
> .transceiver = true,
> .ocr_mask = 0x00100000, /* 3.3V */
> + .deferred = true,
> },
> {} /* Terminator */
> };
> @@ -407,7 +409,7 @@ static inline void __init overo_init_keys(void) { return; }
> static int overo_twl_gpio_setup(struct device *dev,
> unsigned gpio, unsigned ngpio)
> {
> - omap2_hsmmc_init(mmc);
> + omap_hsmmc_deferred_add(mmc);
This board does not look like using external chip for MMC GPIOs,
if that is true, then the above can be just removed.
Added Steve to Cc.
>
> #if defined(CONFIG_LEDS_GPIO) || defined(CONFIG_LEDS_GPIO_MODULE)
> /* TWL4030_GPIO_MAX + 1 == ledB, PMU_STAT (out, active low LED) */
> @@ -505,6 +507,7 @@ static void __init overo_init(void)
> int ret;
>
> omap3_mux_init(board_mux, OMAP_PACKAGE_CBB);
> + omap_hsmmc_init(mmc);
> overo_i2c_init();
> omap_display_init(&overo_dss_data);
> omap_serial_init();
[...]
> diff --git a/arch/arm/mach-omap2/board-zoom-peripherals.c b/arch/arm/mach-omap2/board-zoom-peripherals.c
> index c126461..f99284f 100644
> --- a/arch/arm/mach-omap2/board-zoom-peripherals.c
> +++ b/arch/arm/mach-omap2/board-zoom-peripherals.c
> @@ -203,8 +203,10 @@ static struct omap2_hsmmc_info mmc[] = {
> .name = "external",
> .mmc = 1,
> .caps = MMC_CAP_4_BIT_DATA,
> + .gpio_cd = OMAP_MAX_GPIO_LINES + 0,
> .gpio_wp = -EINVAL,
> .power_saving = true,
> + .deferred = true,
> },
> {
> .name = "internal",
> @@ -214,6 +216,7 @@ static struct omap2_hsmmc_info mmc[] = {
> .gpio_wp = -EINVAL,
> .nonremovable = true,
> .power_saving = true,
> + .deferred = true,
ditto, why defer?
> },
> {
> .name = "wl1271",
> @@ -222,6 +225,7 @@ static struct omap2_hsmmc_info mmc[] = {
> .gpio_wp = -EINVAL,
> .gpio_cd = -EINVAL,
> .nonremovable = true,
> + .deferred = true,
ditto
> },
> {} /* Terminator */
> };
> @@ -231,9 +235,7 @@ static int zoom_twl_gpio_setup(struct device *dev,
> {
> int ret;
>
> - /* gpio + 0 is "mmc0_cd" (input/IRQ) */
> - mmc[0].gpio_cd = gpio + 0;
> - omap2_hsmmc_init(mmc);
> + omap_hsmmc_deferred_add(mmc);
>
> ret = gpio_request_one(LCD_PANEL_ENABLE_GPIO, GPIOF_OUT_INIT_LOW,
> "lcd enable");
> @@ -301,6 +303,7 @@ void __init zoom_peripherals_init(void)
> if (ret)
> pr_err("error setting wl12xx data: %d\n", ret);
>
> + omap_hsmmc_init(mmc);
> omap_i2c_init();
> platform_device_register(&omap_vwlan_device);
> usb_musb_init(NULL);
[...]
--
Regards,
Igor.
More information about the linux-arm-kernel
mailing list