diff --git a/arch/arm/mach-tegra/board-dt.c b/arch/arm/mach-tegra/board-dt.c index 96f4df598238..909065f62e38 100644 --- a/arch/arm/mach-tegra/board-dt.c +++ b/arch/arm/mach-tegra/board-dt.c @@ -103,13 +103,6 @@ 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(); @@ -119,6 +112,13 @@ static void __init tegra_dt_init(void) 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-pinmux.c b/arch/arm/mach-tegra/board-pinmux.c index 103ef65ca62a..adc3efe979b3 100644 --- a/arch/arm/mach-tegra/board-pinmux.c +++ b/arch/arm/mach-tegra/board-pinmux.c @@ -12,7 +12,11 @@ * */ +#include +#include +#include #include +#include #include #include @@ -20,19 +24,23 @@ #include "board-pinmux.h" #include "devices.h" -static struct platform_device *devices[] = { - &tegra_gpio_device, - &tegra_pinmux_device, -}; +struct tegra_board_pinmux_conf *confs[2]; -void tegra_board_pinmux_init(struct tegra_board_pinmux_conf *conf_a, - struct tegra_board_pinmux_conf *conf_b) +static void tegra_board_pinmux_setup_gpios(void) { - struct tegra_board_pinmux_conf *confs[] = {conf_a, conf_b}; int i; - if (of_machine_is_compatible("nvidia,tegra20")) - platform_add_devices(devices, ARRAY_SIZE(devices)); + for (i = 0; i < ARRAY_SIZE(confs); i++) { + if (!confs[i]) + continue; + + tegra_gpio_config(confs[i]->gpios, confs[i]->gpio_count); + } +} + +static void tegra_board_pinmux_setup_pinmux(void) +{ + int i; for (i = 0; i < ARRAY_SIZE(confs); i++) { if (!confs[i]) @@ -43,9 +51,53 @@ void tegra_board_pinmux_init(struct tegra_board_pinmux_conf *conf_a, if (confs[i]->drives) tegra_drive_pinmux_config_table(confs[i]->drives, confs[i]->drive_count); - - tegra_gpio_config(confs[i]->gpios, confs[i]->gpio_count); } +} + +static int tegra_board_pinmux_bus_notify(struct notifier_block *nb, + unsigned long event, void *vdev) +{ + static bool had_gpio; + static bool had_pinmux; + + struct device *dev = vdev; + const char *devname; + + if (event != BUS_NOTIFY_BOUND_DRIVER) + return NOTIFY_DONE; + + devname = dev_name(dev); + + if (!had_gpio && !strcmp(devname, GPIO_DEV)) { + tegra_board_pinmux_setup_gpios(); + had_gpio = true; + } else if (!had_pinmux && !strcmp(devname, PINMUX_DEV)) { + tegra_board_pinmux_setup_pinmux(); + had_pinmux = true; + } + + if (had_gpio && had_pinmux) + return NOTIFY_STOP_MASK; + else + return NOTIFY_DONE; +} + +static struct notifier_block nb = { + .notifier_call = tegra_board_pinmux_bus_notify, +}; + +static struct platform_device *devices[] = { + &tegra_gpio_device, + &tegra_pinmux_device, +}; + +void tegra_board_pinmux_init(struct tegra_board_pinmux_conf *conf_a, + struct tegra_board_pinmux_conf *conf_b) +{ + confs[0] = conf_a; + confs[1] = conf_b; + + bus_register_notifier(&platform_bus_type, &nb); if (!of_machine_is_compatible("nvidia,tegra20")) platform_add_devices(devices, ARRAY_SIZE(devices));