From patchwork Fri Oct 21 17:35:50 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stephen Warren X-Patchwork-Id: 121029 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 41A491007D1 for ; Sat, 22 Oct 2011 04:36:01 +1100 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754516Ab1JURgA (ORCPT ); Fri, 21 Oct 2011 13:36:00 -0400 Received: from avon.wwwdotorg.org ([70.85.31.133]:42526 "EHLO avon.wwwdotorg.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754267Ab1JURf7 (ORCPT ); Fri, 21 Oct 2011 13:35:59 -0400 Received: from severn.wwwdotorg.org (unknown [192.168.65.5]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by avon.wwwdotorg.org (Postfix) with ESMTPS id 092DF631B; Fri, 21 Oct 2011 11:37:02 -0600 (MDT) Received: from localhost.localdomain (searspoint.nvidia.com [216.228.112.21]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by severn.wwwdotorg.org (Postfix) with ESMTPSA id 7229CE40EB; Fri, 21 Oct 2011 11:35:56 -0600 (MDT) From: Stephen Warren To: Olof Johansson , Colin Cross , Grant Likely Cc: Peter De Schrijver , linux-tegra@vger.kernel.org, linux-arm-kernel@lists.infradead.org, devicetree-discuss@lists.ozlabs.org, Stephen Warren Subject: [PATCH] arm/tegra: Don't create duplicate gpio and pinmux devices Date: Fri, 21 Oct 2011 11:35:50 -0600 Message-Id: <1319218550-26002-1-git-send-email-swarren@nvidia.com> X-Mailer: git-send-email 1.7.0.4 X-NVConfidentiality: public X-Virus-Scanned: clamav-milter 0.96.5 at avon.wwwdotorg.org X-Virus-Status: Clean Sender: linux-tegra-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-tegra@vger.kernel.org *_pinmux_init() register the GPIO and pinmux devices so that they're ready before any other device needs them. *_pinmux_init() are also called by board-dt.c in order to set up the GPIO and pinmux configurations. In this case, if we register the devices, they end up being probed once due to this registration, and a second time due to a device-tree node (or vice-versa). The second probe fails since the memory regions are already requested. Besides, we don't actually want the duplicated devices. To avoid this duplicate registration, pass a parameter into *_pinmux_init() indicating whether they should register the device or not. Set this true for non-DT boards, and false otherwise. Finally, modify board-dt.c to call the *_pinmux_init() after all devices have been instantiated from device-tree. This allows the GPIO and pinmux devices to be instantiated and initialized before calling functions to configure the hardware. This has one disadvantage: The pinmux and GPIO initialization now happens after /all/ devices are instantiated, rather than after just gpio and pinmux, but before anything else. So the correct HW configuration is not in place when e.g. the SD/MMC device is probed. Long-term, this should be solved by doing both: a) Initializing the HW state from DT nodes during GPIO and pinmux device probe. b) Using the deferred driver probe mechanism, so that drivers can defer their probe until after the gpio and pinmux drivers have probed. Signed-off-by: Stephen Warren --- Grant, Olof, Colin, What are your thoughts here? Both with and without the patch there are disadvantages. I'm not sure which one is better... arch/arm/mach-tegra/board-dt.c | 23 ++++++++++++----------- arch/arm/mach-tegra/board-harmony-pinmux.c | 6 ++++-- arch/arm/mach-tegra/board-harmony.c | 2 +- arch/arm/mach-tegra/board-harmony.h | 2 +- arch/arm/mach-tegra/board-paz00-pinmux.c | 6 ++++-- arch/arm/mach-tegra/board-paz00.c | 2 +- arch/arm/mach-tegra/board-paz00.h | 2 +- arch/arm/mach-tegra/board-seaboard-pinmux.c | 14 ++++++++------ arch/arm/mach-tegra/board-seaboard.c | 2 +- arch/arm/mach-tegra/board-seaboard.h | 2 +- arch/arm/mach-tegra/board-trimslice-pinmux.c | 6 ++++-- arch/arm/mach-tegra/board-trimslice.c | 2 +- arch/arm/mach-tegra/board-trimslice.h | 2 +- 13 files changed, 40 insertions(+), 31 deletions(-) diff --git a/arch/arm/mach-tegra/board-dt.c b/arch/arm/mach-tegra/board-dt.c index d368f8d..0d22212 100644 --- a/arch/arm/mach-tegra/board-dt.c +++ b/arch/arm/mach-tegra/board-dt.c @@ -45,9 +45,9 @@ #include "clock.h" #include "devices.h" -void harmony_pinmux_init(void); -void seaboard_pinmux_init(void); -void ventana_pinmux_init(void); +void harmony_pinmux_init(int is_dt); +void seaboard_pinmux_init(int is_dt); +void ventana_pinmux_init(int is_dt); struct of_dev_auxdata tegra20_auxdata_lookup[] __initdata = { OF_DEV_AUXDATA("nvidia,tegra20-sdhci", TEGRA_SDMMC1_BASE, "sdhci-tegra.0", NULL), @@ -82,7 +82,7 @@ static struct of_device_id tegra_dt_gic_match[] __initdata = { static struct { char *machine; - void (*init)(void); + void (*init)(int is_dt); } pinmux_configs[] = { { "nvidia,harmony", harmony_pinmux_init }, { "nvidia,seaboard", seaboard_pinmux_init }, @@ -101,21 +101,22 @@ static void __init tegra_dt_init(void) tegra_clk_init_from_table(tegra_dt_clk_init_table); + /* + * Finished with the static registrations now; fill in the missing + * devices + */ + of_platform_populate(NULL, tegra_dt_match_table, + tegra20_auxdata_lookup, NULL); + for (i = 0; i < ARRAY_SIZE(pinmux_configs); i++) { if (of_machine_is_compatible(pinmux_configs[i].machine)) { - pinmux_configs[i].init(); + pinmux_configs[i].init(1); break; } } WARN(i == ARRAY_SIZE(pinmux_configs), "Unknown platform! Pinmuxing not initialized\n"); - - /* - * Finished with the static registrations now; fill in the missing - * devices - */ - of_platform_populate(NULL, tegra_dt_match_table, tegra20_auxdata_lookup, NULL); } static const char * tegra_dt_board_compat[] = { diff --git a/arch/arm/mach-tegra/board-harmony-pinmux.c b/arch/arm/mach-tegra/board-harmony-pinmux.c index e99b456..c1f58dd 100644 --- a/arch/arm/mach-tegra/board-harmony-pinmux.c +++ b/arch/arm/mach-tegra/board-harmony-pinmux.c @@ -159,9 +159,11 @@ static struct tegra_gpio_table gpio_table[] = { { .gpio = TEGRA_GPIO_EXT_MIC_EN, .enable = true }, }; -void harmony_pinmux_init(void) +void harmony_pinmux_init(int is_dt) { - platform_add_devices(pinmux_devices, ARRAY_SIZE(pinmux_devices)); + if (!is_dt) + platform_add_devices(pinmux_devices, + ARRAY_SIZE(pinmux_devices)); tegra_pinmux_config_table(harmony_pinmux, ARRAY_SIZE(harmony_pinmux)); diff --git a/arch/arm/mach-tegra/board-harmony.c b/arch/arm/mach-tegra/board-harmony.c index f0bdc5e..e595901 100644 --- a/arch/arm/mach-tegra/board-harmony.c +++ b/arch/arm/mach-tegra/board-harmony.c @@ -170,7 +170,7 @@ static void __init tegra_harmony_init(void) { tegra_clk_init_from_table(harmony_clk_init_table); - harmony_pinmux_init(); + harmony_pinmux_init(0); tegra_sdhci_device1.dev.platform_data = &sdhci_pdata1; tegra_sdhci_device2.dev.platform_data = &sdhci_pdata2; diff --git a/arch/arm/mach-tegra/board-harmony.h b/arch/arm/mach-tegra/board-harmony.h index 139d96c..c194ec5 100644 --- a/arch/arm/mach-tegra/board-harmony.h +++ b/arch/arm/mach-tegra/board-harmony.h @@ -35,7 +35,7 @@ #define TEGRA_GPIO_EXT_MIC_EN TEGRA_GPIO_PX1 #define TEGRA_GPIO_EN_VDD_1V05_GPIO HARMONY_GPIO_TPS6586X(2) -void harmony_pinmux_init(void); +void harmony_pinmux_init(int is_dt); int harmony_regulator_init(void); #endif diff --git a/arch/arm/mach-tegra/board-paz00-pinmux.c b/arch/arm/mach-tegra/board-paz00-pinmux.c index fb20894..c8301fd 100644 --- a/arch/arm/mach-tegra/board-paz00-pinmux.c +++ b/arch/arm/mach-tegra/board-paz00-pinmux.c @@ -156,9 +156,11 @@ static struct tegra_gpio_table gpio_table[] = { { .gpio = TEGRA_WIFI_LED, .enable = true }, }; -void paz00_pinmux_init(void) +void paz00_pinmux_init(int is_dt) { - platform_add_devices(pinmux_devices, ARRAY_SIZE(pinmux_devices)); + if (!is_dt) + platform_add_devices(pinmux_devices, + ARRAY_SIZE(pinmux_devices)); tegra_pinmux_config_table(paz00_pinmux, ARRAY_SIZE(paz00_pinmux)); diff --git a/arch/arm/mach-tegra/board-paz00.c b/arch/arm/mach-tegra/board-paz00.c index 602f8dd..1709e5e 100644 --- a/arch/arm/mach-tegra/board-paz00.c +++ b/arch/arm/mach-tegra/board-paz00.c @@ -173,7 +173,7 @@ static void __init tegra_paz00_init(void) { tegra_clk_init_from_table(paz00_clk_init_table); - paz00_pinmux_init(); + paz00_pinmux_init(0); tegra_sdhci_device1.dev.platform_data = &sdhci_pdata1; tegra_sdhci_device4.dev.platform_data = &sdhci_pdata4; diff --git a/arch/arm/mach-tegra/board-paz00.h b/arch/arm/mach-tegra/board-paz00.h index 2dc1899..8695518 100644 --- a/arch/arm/mach-tegra/board-paz00.h +++ b/arch/arm/mach-tegra/board-paz00.h @@ -32,6 +32,6 @@ #define TEGRA_WIFI_RST TEGRA_GPIO_PD1 #define TEGRA_WIFI_LED TEGRA_GPIO_PD0 -void paz00_pinmux_init(void); +void paz00_pinmux_init(int is_dt); #endif diff --git a/arch/arm/mach-tegra/board-seaboard-pinmux.c b/arch/arm/mach-tegra/board-seaboard-pinmux.c index fbce31d..a63bc0e 100644 --- a/arch/arm/mach-tegra/board-seaboard-pinmux.c +++ b/arch/arm/mach-tegra/board-seaboard-pinmux.c @@ -216,9 +216,11 @@ static void __init update_pinmux(struct tegra_pingroup_config *newtbl, int size) } } -void __init seaboard_common_pinmux_init(void) +void __init seaboard_common_pinmux_init(int is_dt) { - platform_add_devices(pinmux_devices, ARRAY_SIZE(pinmux_devices)); + if (!is_dt) + platform_add_devices(pinmux_devices, + ARRAY_SIZE(pinmux_devices)); tegra_pinmux_config_table(seaboard_pinmux, ARRAY_SIZE(seaboard_pinmux)); @@ -228,14 +230,14 @@ void __init seaboard_common_pinmux_init(void) tegra_gpio_config(common_gpio_table, ARRAY_SIZE(common_gpio_table)); } -void __init seaboard_pinmux_init(void) +void __init seaboard_pinmux_init(int is_dt) { - seaboard_common_pinmux_init(); + seaboard_common_pinmux_init(is_dt); } -void __init ventana_pinmux_init(void) +void __init ventana_pinmux_init(int is_dt) { update_pinmux(ventana_pinmux, ARRAY_SIZE(ventana_pinmux)); - seaboard_common_pinmux_init(); + seaboard_common_pinmux_init(is_dt); } diff --git a/arch/arm/mach-tegra/board-seaboard.c b/arch/arm/mach-tegra/board-seaboard.c index bf13ea3..c41e01a 100644 --- a/arch/arm/mach-tegra/board-seaboard.c +++ b/arch/arm/mach-tegra/board-seaboard.c @@ -226,7 +226,7 @@ static void __init seaboard_i2c_init(void) static void __init seaboard_common_init(void) { - seaboard_pinmux_init(); + seaboard_pinmux_init(0); tegra_clk_init_from_table(seaboard_clk_init_table); diff --git a/arch/arm/mach-tegra/board-seaboard.h b/arch/arm/mach-tegra/board-seaboard.h index 4c45d4c..d4460c3 100644 --- a/arch/arm/mach-tegra/board-seaboard.h +++ b/arch/arm/mach-tegra/board-seaboard.h @@ -42,6 +42,6 @@ #define TEGRA_GPIO_HP_DET TEGRA_GPIO_PX1 #define TEGRA_GPIO_KAEN_HP_MUTE TEGRA_GPIO_PA5 -void seaboard_pinmux_init(void); +void seaboard_pinmux_init(int is_dt); #endif diff --git a/arch/arm/mach-tegra/board-trimslice-pinmux.c b/arch/arm/mach-tegra/board-trimslice-pinmux.c index 4969dd2..3aa05f9 100644 --- a/arch/arm/mach-tegra/board-trimslice-pinmux.c +++ b/arch/arm/mach-tegra/board-trimslice-pinmux.c @@ -155,9 +155,11 @@ static struct tegra_gpio_table gpio_table[] = { { .gpio = TRIMSLICE_GPIO_USB2_RST, .enable = true }, /* USB2 PHY rst */ }; -void __init trimslice_pinmux_init(void) +void __init trimslice_pinmux_init(int is_dt) { - platform_add_devices(pinmux_devices, ARRAY_SIZE(pinmux_devices)); + if (!is_dt) + platform_add_devices(pinmux_devices, + ARRAY_SIZE(pinmux_devices)); tegra_pinmux_config_table(trimslice_pinmux, ARRAY_SIZE(trimslice_pinmux)); tegra_gpio_config(gpio_table, ARRAY_SIZE(gpio_table)); } diff --git a/arch/arm/mach-tegra/board-trimslice.c b/arch/arm/mach-tegra/board-trimslice.c index e008c0e..2b2f262 100644 --- a/arch/arm/mach-tegra/board-trimslice.c +++ b/arch/arm/mach-tegra/board-trimslice.c @@ -160,7 +160,7 @@ static void __init tegra_trimslice_init(void) { tegra_clk_init_from_table(trimslice_clk_init_table); - trimslice_pinmux_init(); + trimslice_pinmux_init(0); tegra_sdhci_device1.dev.platform_data = &sdhci_pdata1; tegra_sdhci_device4.dev.platform_data = &sdhci_pdata4; diff --git a/arch/arm/mach-tegra/board-trimslice.h b/arch/arm/mach-tegra/board-trimslice.h index 50f128d..4d19a11 100644 --- a/arch/arm/mach-tegra/board-trimslice.h +++ b/arch/arm/mach-tegra/board-trimslice.h @@ -25,6 +25,6 @@ #define TRIMSLICE_GPIO_USB1_MODE TEGRA_GPIO_PV2 /* USB1 mode */ #define TRIMSLICE_GPIO_USB2_RST TEGRA_GPIO_PV0 /* USB2 PHY reset */ -void trimslice_pinmux_init(void); +void trimslice_pinmux_init(int is_dt); #endif