aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-tegra/board-pinmux.c
diff options
context:
space:
mode:
authorStephen Warren <swarren@nvidia.com>2011-12-16 17:12:32 -0500
committerOlof Johansson <olof@lixom.net>2011-12-19 21:03:11 -0500
commita58116f331fd30462b4a7372725e090e1a7d0eb7 (patch)
treef095c9fba0e480bc4449a4ee4893cb52525017b0 /arch/arm/mach-tegra/board-pinmux.c
parent54862bf00968427cf8f7ffcb6dacf03161eae862 (diff)
arm/tegra: Use bus notifiers to trigger pinmux setup
Currently, the Tegra pinmux is initialized at different times when booting with and without device tree: Without device tree: 1) Pinmux and GPIO drivers are registered. 2) Pinmux is configured. 3) All other drivers are registered. With device tree: 1) All drivers are registered and probed, including pinmux and GPIO. 2) Pinmux is configured. This change modifies board-pinmux.c to detect pinmux and GPIO driver registration using bus notifiers. This allows pinmux configuration to happen immediately after the pinmux driver is probed, irrespective of whether the pinmux driver is manually registered by board-pinmux.c, or if it's instantiated during device tree parsing. To support this with device tree, the pinmux init functions must be called prior to instantiating devices from device tree, so that the notifiers are set up before-hand. Signed-off-by: Stephen Warren <swarren@nvidia.com> Signed-off-by: Olof Johansson <olof@lixom.net>
Diffstat (limited to 'arch/arm/mach-tegra/board-pinmux.c')
-rw-r--r--arch/arm/mach-tegra/board-pinmux.c72
1 files changed, 62 insertions, 10 deletions
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 @@
12 * 12 *
13 */ 13 */
14 14
15#include <linux/device.h>
16#include <linux/kernel.h>
17#include <linux/notifier.h>
15#include <linux/of.h> 18#include <linux/of.h>
19#include <linux/string.h>
16 20
17#include <mach/gpio-tegra.h> 21#include <mach/gpio-tegra.h>
18#include <mach/pinmux.h> 22#include <mach/pinmux.h>
@@ -20,19 +24,23 @@
20#include "board-pinmux.h" 24#include "board-pinmux.h"
21#include "devices.h" 25#include "devices.h"
22 26
23static struct platform_device *devices[] = { 27struct tegra_board_pinmux_conf *confs[2];
24 &tegra_gpio_device,
25 &tegra_pinmux_device,
26};
27 28
28void tegra_board_pinmux_init(struct tegra_board_pinmux_conf *conf_a, 29static void tegra_board_pinmux_setup_gpios(void)
29 struct tegra_board_pinmux_conf *conf_b)
30{ 30{
31 struct tegra_board_pinmux_conf *confs[] = {conf_a, conf_b};
32 int i; 31 int i;
33 32
34 if (of_machine_is_compatible("nvidia,tegra20")) 33 for (i = 0; i < ARRAY_SIZE(confs); i++) {
35 platform_add_devices(devices, ARRAY_SIZE(devices)); 34 if (!confs[i])
35 continue;
36
37 tegra_gpio_config(confs[i]->gpios, confs[i]->gpio_count);
38 }
39}
40
41static void tegra_board_pinmux_setup_pinmux(void)
42{
43 int i;
36 44
37 for (i = 0; i < ARRAY_SIZE(confs); i++) { 45 for (i = 0; i < ARRAY_SIZE(confs); i++) {
38 if (!confs[i]) 46 if (!confs[i])
@@ -43,10 +51,54 @@ void tegra_board_pinmux_init(struct tegra_board_pinmux_conf *conf_a,
43 if (confs[i]->drives) 51 if (confs[i]->drives)
44 tegra_drive_pinmux_config_table(confs[i]->drives, 52 tegra_drive_pinmux_config_table(confs[i]->drives,
45 confs[i]->drive_count); 53 confs[i]->drive_count);
54 }
55}
46 56
47 tegra_gpio_config(confs[i]->gpios, confs[i]->gpio_count); 57static int tegra_board_pinmux_bus_notify(struct notifier_block *nb,
58 unsigned long event, void *vdev)
59{
60 static bool had_gpio;
61 static bool had_pinmux;
62
63 struct device *dev = vdev;
64 const char *devname;
65
66 if (event != BUS_NOTIFY_BOUND_DRIVER)
67 return NOTIFY_DONE;
68
69 devname = dev_name(dev);
70
71 if (!had_gpio && !strcmp(devname, GPIO_DEV)) {
72 tegra_board_pinmux_setup_gpios();
73 had_gpio = true;
74 } else if (!had_pinmux && !strcmp(devname, PINMUX_DEV)) {
75 tegra_board_pinmux_setup_pinmux();
76 had_pinmux = true;
48 } 77 }
49 78
79 if (had_gpio && had_pinmux)
80 return NOTIFY_STOP_MASK;
81 else
82 return NOTIFY_DONE;
83}
84
85static struct notifier_block nb = {
86 .notifier_call = tegra_board_pinmux_bus_notify,
87};
88
89static struct platform_device *devices[] = {
90 &tegra_gpio_device,
91 &tegra_pinmux_device,
92};
93
94void tegra_board_pinmux_init(struct tegra_board_pinmux_conf *conf_a,
95 struct tegra_board_pinmux_conf *conf_b)
96{
97 confs[0] = conf_a;
98 confs[1] = conf_b;
99
100 bus_register_notifier(&platform_bus_type, &nb);
101
50 if (!of_machine_is_compatible("nvidia,tegra20")) 102 if (!of_machine_is_compatible("nvidia,tegra20"))
51 platform_add_devices(devices, ARRAY_SIZE(devices)); 103 platform_add_devices(devices, ARRAY_SIZE(devices));
52} 104}