diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-11-01 23:31:25 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-11-01 23:31:25 -0400 |
commit | 16ee792e45cf0c97ce061fce03c36cab5551ec72 (patch) | |
tree | dc68af705fbac4b5d71325aa972730199bb187dd /arch/arm/mach-tegra | |
parent | f906fb1d70e016726fccfb0d978c5d425503db9d (diff) | |
parent | efa62e1355f0495f37f1296754b8880947c8da72 (diff) |
Merge branch 'next/devel' of git://git.linaro.org/people/arnd/arm-soc
* 'next/devel' of git://git.linaro.org/people/arnd/arm-soc: (50 commits)
ARM: tegra: update defconfig
arm/tegra: Harmony: Configure PMC for low-level interrupts
arm/tegra: device tree support for ventana board
arm/tegra: add support for ventana pinmuxing
arm/tegra: prepare Seaboard pinmux code for derived boards
arm/tegra: pinmux: ioremap registers
gpio/tegra: Convert to a platform device
arm/tegra: Convert pinmux driver to a platform device
arm/dt: Tegra: Add pinmux node to tegra20.dtsi
arm/tegra: Prep boards for gpio/pinmux conversion to pdevs
ARM: mx5: fix clock usage for suspend
ARM i.MX entry-macro.S: remove now unused code
ARM i.MX boards: use CONFIG_MULTI_IRQ_HANDLER
ARM i.MX tzic: add handle_irq function
ARM i.MX avic: add handle_irq function
ARM: mx25: Add the missing IIM base definition
ARM i.MX avic: convert to use generic irq chip
mx31moboard: Add poweroff support
ARM: mach-qong: Add watchdog support
ARM: davinci: AM18x: Add wl1271/wlan support
...
Fix up conflicts in:
arch/arm/mach-at91/at91sam9g45.c
arch/arm/mach-mx5/devices-imx53.h
arch/arm/plat-mxc/include/mach/memory.h
Diffstat (limited to 'arch/arm/mach-tegra')
-rw-r--r-- | arch/arm/mach-tegra/Kconfig | 6 | ||||
-rw-r--r-- | arch/arm/mach-tegra/Makefile | 1 | ||||
-rw-r--r-- | arch/arm/mach-tegra/Makefile.boot | 1 | ||||
-rw-r--r-- | arch/arm/mach-tegra/board-dt.c | 26 | ||||
-rw-r--r-- | arch/arm/mach-tegra/board-harmony-pinmux.c | 8 | ||||
-rw-r--r-- | arch/arm/mach-tegra/board-harmony-power.c | 13 | ||||
-rw-r--r-- | arch/arm/mach-tegra/board-paz00-pinmux.c | 8 | ||||
-rw-r--r-- | arch/arm/mach-tegra/board-seaboard-pinmux.c | 69 | ||||
-rw-r--r-- | arch/arm/mach-tegra/board-trimslice-pinmux.c | 7 | ||||
-rw-r--r-- | arch/arm/mach-tegra/devices.c | 84 | ||||
-rw-r--r-- | arch/arm/mach-tegra/devices.h | 2 | ||||
-rw-r--r-- | arch/arm/mach-tegra/include/mach/pinmux.h | 4 | ||||
-rw-r--r-- | arch/arm/mach-tegra/pinmux-t2-tables.c | 76 | ||||
-rw-r--r-- | arch/arm/mach-tegra/pinmux.c | 163 |
14 files changed, 363 insertions, 105 deletions
diff --git a/arch/arm/mach-tegra/Kconfig b/arch/arm/mach-tegra/Kconfig index d82ebab50e11..91aff7cb8284 100644 --- a/arch/arm/mach-tegra/Kconfig +++ b/arch/arm/mach-tegra/Kconfig | |||
@@ -69,6 +69,12 @@ config MACH_WARIO | |||
69 | help | 69 | help |
70 | Support for the Wario version of Seaboard | 70 | Support for the Wario version of Seaboard |
71 | 71 | ||
72 | config MACH_VENTANA | ||
73 | bool "Ventana board" | ||
74 | select MACH_TEGRA_DT | ||
75 | help | ||
76 | Support for the nVidia Ventana development platform | ||
77 | |||
72 | choice | 78 | choice |
73 | prompt "Low-level debug console UART" | 79 | prompt "Low-level debug console UART" |
74 | default TEGRA_DEBUG_UART_NONE | 80 | default TEGRA_DEBUG_UART_NONE |
diff --git a/arch/arm/mach-tegra/Makefile b/arch/arm/mach-tegra/Makefile index f11b9100114a..91a07e187208 100644 --- a/arch/arm/mach-tegra/Makefile +++ b/arch/arm/mach-tegra/Makefile | |||
@@ -31,6 +31,7 @@ obj-${CONFIG_MACH_SEABOARD} += board-seaboard-pinmux.o | |||
31 | 31 | ||
32 | obj-${CONFIG_MACH_TEGRA_DT} += board-dt.o | 32 | obj-${CONFIG_MACH_TEGRA_DT} += board-dt.o |
33 | obj-${CONFIG_MACH_TEGRA_DT} += board-harmony-pinmux.o | 33 | obj-${CONFIG_MACH_TEGRA_DT} += board-harmony-pinmux.o |
34 | obj-${CONFIG_MACH_TEGRA_DT} += board-seaboard-pinmux.o | ||
34 | 35 | ||
35 | obj-${CONFIG_MACH_TRIMSLICE} += board-trimslice.o | 36 | obj-${CONFIG_MACH_TRIMSLICE} += board-trimslice.o |
36 | obj-${CONFIG_MACH_TRIMSLICE} += board-trimslice-pinmux.o | 37 | obj-${CONFIG_MACH_TRIMSLICE} += board-trimslice-pinmux.o |
diff --git a/arch/arm/mach-tegra/Makefile.boot b/arch/arm/mach-tegra/Makefile.boot index 5e870d29eca1..bd12c9fb81e8 100644 --- a/arch/arm/mach-tegra/Makefile.boot +++ b/arch/arm/mach-tegra/Makefile.boot | |||
@@ -4,3 +4,4 @@ initrd_phys-$(CONFIG_ARCH_TEGRA_2x_SOC) := 0x00800000 | |||
4 | 4 | ||
5 | dtb-$(CONFIG_MACH_HARMONY) += tegra-harmony.dtb | 5 | dtb-$(CONFIG_MACH_HARMONY) += tegra-harmony.dtb |
6 | dtb-$(CONFIG_MACH_SEABOARD) += tegra-seaboard.dtb | 6 | dtb-$(CONFIG_MACH_SEABOARD) += tegra-seaboard.dtb |
7 | dtb-$(CONFIG_MACH_VENTANA) += tegra-ventana.dtb | ||
diff --git a/arch/arm/mach-tegra/board-dt.c b/arch/arm/mach-tegra/board-dt.c index 9f47e04446f3..d368f8dafcfd 100644 --- a/arch/arm/mach-tegra/board-dt.c +++ b/arch/arm/mach-tegra/board-dt.c | |||
@@ -47,7 +47,7 @@ | |||
47 | 47 | ||
48 | void harmony_pinmux_init(void); | 48 | void harmony_pinmux_init(void); |
49 | void seaboard_pinmux_init(void); | 49 | void seaboard_pinmux_init(void); |
50 | 50 | void ventana_pinmux_init(void); | |
51 | 51 | ||
52 | struct of_dev_auxdata tegra20_auxdata_lookup[] __initdata = { | 52 | struct of_dev_auxdata tegra20_auxdata_lookup[] __initdata = { |
53 | OF_DEV_AUXDATA("nvidia,tegra20-sdhci", TEGRA_SDMMC1_BASE, "sdhci-tegra.0", NULL), | 53 | OF_DEV_AUXDATA("nvidia,tegra20-sdhci", TEGRA_SDMMC1_BASE, "sdhci-tegra.0", NULL), |
@@ -80,9 +80,19 @@ static struct of_device_id tegra_dt_gic_match[] __initdata = { | |||
80 | {} | 80 | {} |
81 | }; | 81 | }; |
82 | 82 | ||
83 | static struct { | ||
84 | char *machine; | ||
85 | void (*init)(void); | ||
86 | } pinmux_configs[] = { | ||
87 | { "nvidia,harmony", harmony_pinmux_init }, | ||
88 | { "nvidia,seaboard", seaboard_pinmux_init }, | ||
89 | { "nvidia,ventana", ventana_pinmux_init }, | ||
90 | }; | ||
91 | |||
83 | static void __init tegra_dt_init(void) | 92 | static void __init tegra_dt_init(void) |
84 | { | 93 | { |
85 | struct device_node *node; | 94 | struct device_node *node; |
95 | int i; | ||
86 | 96 | ||
87 | node = of_find_matching_node_by_address(NULL, tegra_dt_gic_match, | 97 | node = of_find_matching_node_by_address(NULL, tegra_dt_gic_match, |
88 | TEGRA_ARM_INT_DIST_BASE); | 98 | TEGRA_ARM_INT_DIST_BASE); |
@@ -91,10 +101,15 @@ static void __init tegra_dt_init(void) | |||
91 | 101 | ||
92 | tegra_clk_init_from_table(tegra_dt_clk_init_table); | 102 | tegra_clk_init_from_table(tegra_dt_clk_init_table); |
93 | 103 | ||
94 | if (of_machine_is_compatible("nvidia,harmony")) | 104 | for (i = 0; i < ARRAY_SIZE(pinmux_configs); i++) { |
95 | harmony_pinmux_init(); | 105 | if (of_machine_is_compatible(pinmux_configs[i].machine)) { |
96 | else if (of_machine_is_compatible("nvidia,seaboard")) | 106 | pinmux_configs[i].init(); |
97 | seaboard_pinmux_init(); | 107 | break; |
108 | } | ||
109 | } | ||
110 | |||
111 | WARN(i == ARRAY_SIZE(pinmux_configs), | ||
112 | "Unknown platform! Pinmuxing not initialized\n"); | ||
98 | 113 | ||
99 | /* | 114 | /* |
100 | * Finished with the static registrations now; fill in the missing | 115 | * Finished with the static registrations now; fill in the missing |
@@ -106,6 +121,7 @@ static void __init tegra_dt_init(void) | |||
106 | static const char * tegra_dt_board_compat[] = { | 121 | static const char * tegra_dt_board_compat[] = { |
107 | "nvidia,harmony", | 122 | "nvidia,harmony", |
108 | "nvidia,seaboard", | 123 | "nvidia,seaboard", |
124 | "nvidia,ventana", | ||
109 | NULL | 125 | NULL |
110 | }; | 126 | }; |
111 | 127 | ||
diff --git a/arch/arm/mach-tegra/board-harmony-pinmux.c b/arch/arm/mach-tegra/board-harmony-pinmux.c index 4d63e2e97a8d..e99b45618cd0 100644 --- a/arch/arm/mach-tegra/board-harmony-pinmux.c +++ b/arch/arm/mach-tegra/board-harmony-pinmux.c | |||
@@ -20,6 +20,7 @@ | |||
20 | 20 | ||
21 | #include "gpio-names.h" | 21 | #include "gpio-names.h" |
22 | #include "board-harmony.h" | 22 | #include "board-harmony.h" |
23 | #include "devices.h" | ||
23 | 24 | ||
24 | static struct tegra_pingroup_config harmony_pinmux[] = { | 25 | static struct tegra_pingroup_config harmony_pinmux[] = { |
25 | {TEGRA_PINGROUP_ATA, TEGRA_MUX_IDE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, | 26 | {TEGRA_PINGROUP_ATA, TEGRA_MUX_IDE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, |
@@ -140,6 +141,11 @@ static struct tegra_pingroup_config harmony_pinmux[] = { | |||
140 | {TEGRA_PINGROUP_XM2D, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, | 141 | {TEGRA_PINGROUP_XM2D, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, |
141 | }; | 142 | }; |
142 | 143 | ||
144 | static struct platform_device *pinmux_devices[] = { | ||
145 | &tegra_gpio_device, | ||
146 | &tegra_pinmux_device, | ||
147 | }; | ||
148 | |||
143 | static struct tegra_gpio_table gpio_table[] = { | 149 | static struct tegra_gpio_table gpio_table[] = { |
144 | { .gpio = TEGRA_GPIO_SD2_CD, .enable = true }, | 150 | { .gpio = TEGRA_GPIO_SD2_CD, .enable = true }, |
145 | { .gpio = TEGRA_GPIO_SD2_WP, .enable = true }, | 151 | { .gpio = TEGRA_GPIO_SD2_WP, .enable = true }, |
@@ -155,6 +161,8 @@ static struct tegra_gpio_table gpio_table[] = { | |||
155 | 161 | ||
156 | void harmony_pinmux_init(void) | 162 | void harmony_pinmux_init(void) |
157 | { | 163 | { |
164 | platform_add_devices(pinmux_devices, ARRAY_SIZE(pinmux_devices)); | ||
165 | |||
158 | tegra_pinmux_config_table(harmony_pinmux, ARRAY_SIZE(harmony_pinmux)); | 166 | tegra_pinmux_config_table(harmony_pinmux, ARRAY_SIZE(harmony_pinmux)); |
159 | 167 | ||
160 | tegra_gpio_config(gpio_table, ARRAY_SIZE(gpio_table)); | 168 | tegra_gpio_config(gpio_table, ARRAY_SIZE(gpio_table)); |
diff --git a/arch/arm/mach-tegra/board-harmony-power.c b/arch/arm/mach-tegra/board-harmony-power.c index 5ad8b2f94f8d..21d1285731b3 100644 --- a/arch/arm/mach-tegra/board-harmony-power.c +++ b/arch/arm/mach-tegra/board-harmony-power.c | |||
@@ -18,10 +18,11 @@ | |||
18 | #include <linux/i2c.h> | 18 | #include <linux/i2c.h> |
19 | #include <linux/platform_device.h> | 19 | #include <linux/platform_device.h> |
20 | #include <linux/gpio.h> | 20 | #include <linux/gpio.h> |
21 | 21 | #include <linux/io.h> | |
22 | #include <linux/regulator/machine.h> | 22 | #include <linux/regulator/machine.h> |
23 | #include <linux/mfd/tps6586x.h> | 23 | #include <linux/mfd/tps6586x.h> |
24 | 24 | ||
25 | #include <mach/iomap.h> | ||
25 | #include <mach/irqs.h> | 26 | #include <mach/irqs.h> |
26 | 27 | ||
27 | #include "board-harmony.h" | 28 | #include "board-harmony.h" |
@@ -113,6 +114,16 @@ static struct i2c_board_info __initdata harmony_regulators[] = { | |||
113 | 114 | ||
114 | int __init harmony_regulator_init(void) | 115 | int __init harmony_regulator_init(void) |
115 | { | 116 | { |
117 | void __iomem *pmc = IO_ADDRESS(TEGRA_PMC_BASE); | ||
118 | u32 pmc_ctrl; | ||
119 | |||
120 | /* | ||
121 | * Configure the power management controller to trigger PMU | ||
122 | * interrupts when low | ||
123 | */ | ||
124 | pmc_ctrl = readl(pmc + PMC_CTRL); | ||
125 | writel(pmc_ctrl | PMC_CTRL_INTR_LOW, pmc + PMC_CTRL); | ||
126 | |||
116 | i2c_register_board_info(3, harmony_regulators, 1); | 127 | i2c_register_board_info(3, harmony_regulators, 1); |
117 | 128 | ||
118 | return 0; | 129 | return 0; |
diff --git a/arch/arm/mach-tegra/board-paz00-pinmux.c b/arch/arm/mach-tegra/board-paz00-pinmux.c index 22257697d3ee..fb20894862b0 100644 --- a/arch/arm/mach-tegra/board-paz00-pinmux.c +++ b/arch/arm/mach-tegra/board-paz00-pinmux.c | |||
@@ -20,6 +20,7 @@ | |||
20 | 20 | ||
21 | #include "gpio-names.h" | 21 | #include "gpio-names.h" |
22 | #include "board-paz00.h" | 22 | #include "board-paz00.h" |
23 | #include "devices.h" | ||
23 | 24 | ||
24 | static struct tegra_pingroup_config paz00_pinmux[] = { | 25 | static struct tegra_pingroup_config paz00_pinmux[] = { |
25 | {TEGRA_PINGROUP_ATA, TEGRA_MUX_GMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, | 26 | {TEGRA_PINGROUP_ATA, TEGRA_MUX_GMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, |
@@ -140,6 +141,11 @@ static struct tegra_pingroup_config paz00_pinmux[] = { | |||
140 | {TEGRA_PINGROUP_XM2D, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, | 141 | {TEGRA_PINGROUP_XM2D, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, |
141 | }; | 142 | }; |
142 | 143 | ||
144 | static struct platform_device *pinmux_devices[] = { | ||
145 | &tegra_gpio_device, | ||
146 | &tegra_pinmux_device, | ||
147 | }; | ||
148 | |||
143 | static struct tegra_gpio_table gpio_table[] = { | 149 | static struct tegra_gpio_table gpio_table[] = { |
144 | { .gpio = TEGRA_GPIO_SD1_CD, .enable = true }, | 150 | { .gpio = TEGRA_GPIO_SD1_CD, .enable = true }, |
145 | { .gpio = TEGRA_GPIO_SD1_WP, .enable = true }, | 151 | { .gpio = TEGRA_GPIO_SD1_WP, .enable = true }, |
@@ -152,6 +158,8 @@ static struct tegra_gpio_table gpio_table[] = { | |||
152 | 158 | ||
153 | void paz00_pinmux_init(void) | 159 | void paz00_pinmux_init(void) |
154 | { | 160 | { |
161 | platform_add_devices(pinmux_devices, ARRAY_SIZE(pinmux_devices)); | ||
162 | |||
155 | tegra_pinmux_config_table(paz00_pinmux, ARRAY_SIZE(paz00_pinmux)); | 163 | tegra_pinmux_config_table(paz00_pinmux, ARRAY_SIZE(paz00_pinmux)); |
156 | 164 | ||
157 | tegra_gpio_config(gpio_table, ARRAY_SIZE(gpio_table)); | 165 | tegra_gpio_config(gpio_table, ARRAY_SIZE(gpio_table)); |
diff --git a/arch/arm/mach-tegra/board-seaboard-pinmux.c b/arch/arm/mach-tegra/board-seaboard-pinmux.c index 74f78b7e3f19..fbce31daa3c9 100644 --- a/arch/arm/mach-tegra/board-seaboard-pinmux.c +++ b/arch/arm/mach-tegra/board-seaboard-pinmux.c | |||
@@ -1,5 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (C) 2010 NVIDIA Corporation | 2 | * Copyright (C) 2010,2011 NVIDIA Corporation |
3 | * Copyright (C) 2011 Google, Inc. | ||
3 | * | 4 | * |
4 | * This software is licensed under the terms of the GNU General Public | 5 | * This software is licensed under the terms of the GNU General Public |
5 | * License version 2, as published by the Free Software Foundation, and | 6 | * License version 2, as published by the Free Software Foundation, and |
@@ -21,6 +22,7 @@ | |||
21 | 22 | ||
22 | #include "gpio-names.h" | 23 | #include "gpio-names.h" |
23 | #include "board-seaboard.h" | 24 | #include "board-seaboard.h" |
25 | #include "devices.h" | ||
24 | 26 | ||
25 | #define DEFAULT_DRIVE(_name) \ | 27 | #define DEFAULT_DRIVE(_name) \ |
26 | { \ | 28 | { \ |
@@ -157,10 +159,33 @@ static __initdata struct tegra_pingroup_config seaboard_pinmux[] = { | |||
157 | {TEGRA_PINGROUP_XM2D, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, | 159 | {TEGRA_PINGROUP_XM2D, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, |
158 | }; | 160 | }; |
159 | 161 | ||
162 | static __initdata struct tegra_pingroup_config ventana_pinmux[] = { | ||
163 | {TEGRA_PINGROUP_DAP3, TEGRA_MUX_DAP3, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE}, | ||
164 | {TEGRA_PINGROUP_DDC, TEGRA_MUX_RSVD2, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, | ||
165 | {TEGRA_PINGROUP_DTA, TEGRA_MUX_VI, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL}, | ||
166 | {TEGRA_PINGROUP_DTB, TEGRA_MUX_VI, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL}, | ||
167 | {TEGRA_PINGROUP_DTC, TEGRA_MUX_VI, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL}, | ||
168 | {TEGRA_PINGROUP_DTD, TEGRA_MUX_VI, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL}, | ||
169 | {TEGRA_PINGROUP_GMD, TEGRA_MUX_SFLASH, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE}, | ||
170 | {TEGRA_PINGROUP_LPW0, TEGRA_MUX_RSVD4, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, | ||
171 | {TEGRA_PINGROUP_LPW2, TEGRA_MUX_RSVD4, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, | ||
172 | {TEGRA_PINGROUP_LSC1, TEGRA_MUX_RSVD4, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, | ||
173 | {TEGRA_PINGROUP_LSCK, TEGRA_MUX_RSVD4, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE}, | ||
174 | {TEGRA_PINGROUP_LSDA, TEGRA_MUX_RSVD4, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE}, | ||
175 | {TEGRA_PINGROUP_PTA, TEGRA_MUX_RSVD2, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, | ||
176 | {TEGRA_PINGROUP_SLXC, TEGRA_MUX_SDIO3, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, | ||
177 | {TEGRA_PINGROUP_SLXK, TEGRA_MUX_SDIO3, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, | ||
178 | {TEGRA_PINGROUP_SPIA, TEGRA_MUX_GMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE}, | ||
179 | {TEGRA_PINGROUP_SPIC, TEGRA_MUX_GMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE}, | ||
180 | {TEGRA_PINGROUP_SPIG, TEGRA_MUX_SPI2_ALT, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE}, | ||
181 | }; | ||
160 | 182 | ||
183 | static struct platform_device *pinmux_devices[] = { | ||
184 | &tegra_gpio_device, | ||
185 | &tegra_pinmux_device, | ||
186 | }; | ||
161 | 187 | ||
162 | 188 | static struct tegra_gpio_table common_gpio_table[] = { | |
163 | static struct tegra_gpio_table gpio_table[] = { | ||
164 | { .gpio = TEGRA_GPIO_SD2_CD, .enable = true }, | 189 | { .gpio = TEGRA_GPIO_SD2_CD, .enable = true }, |
165 | { .gpio = TEGRA_GPIO_SD2_WP, .enable = true }, | 190 | { .gpio = TEGRA_GPIO_SD2_WP, .enable = true }, |
166 | { .gpio = TEGRA_GPIO_SD2_POWER, .enable = true }, | 191 | { .gpio = TEGRA_GPIO_SD2_POWER, .enable = true }, |
@@ -171,12 +196,46 @@ static struct tegra_gpio_table gpio_table[] = { | |||
171 | { .gpio = TEGRA_GPIO_USB1, .enable = true }, | 196 | { .gpio = TEGRA_GPIO_USB1, .enable = true }, |
172 | }; | 197 | }; |
173 | 198 | ||
174 | void __init seaboard_pinmux_init(void) | 199 | static void __init update_pinmux(struct tegra_pingroup_config *newtbl, int size) |
200 | { | ||
201 | int i, j; | ||
202 | struct tegra_pingroup_config *new_pingroup, *base_pingroup; | ||
203 | |||
204 | /* Update base seaboard pinmux table with secondary board | ||
205 | * specific pinmux table table. | ||
206 | */ | ||
207 | for (i = 0; i < size; i++) { | ||
208 | new_pingroup = &newtbl[i]; | ||
209 | for (j = 0; j < ARRAY_SIZE(seaboard_pinmux); j++) { | ||
210 | base_pingroup = &seaboard_pinmux[j]; | ||
211 | if (new_pingroup->pingroup == base_pingroup->pingroup) { | ||
212 | *base_pingroup = *new_pingroup; | ||
213 | break; | ||
214 | } | ||
215 | } | ||
216 | } | ||
217 | } | ||
218 | |||
219 | void __init seaboard_common_pinmux_init(void) | ||
175 | { | 220 | { |
221 | platform_add_devices(pinmux_devices, ARRAY_SIZE(pinmux_devices)); | ||
222 | |||
176 | tegra_pinmux_config_table(seaboard_pinmux, ARRAY_SIZE(seaboard_pinmux)); | 223 | tegra_pinmux_config_table(seaboard_pinmux, ARRAY_SIZE(seaboard_pinmux)); |
177 | 224 | ||
178 | tegra_drive_pinmux_config_table(seaboard_drive_pinmux, | 225 | tegra_drive_pinmux_config_table(seaboard_drive_pinmux, |
179 | ARRAY_SIZE(seaboard_drive_pinmux)); | 226 | ARRAY_SIZE(seaboard_drive_pinmux)); |
180 | 227 | ||
181 | tegra_gpio_config(gpio_table, ARRAY_SIZE(gpio_table)); | 228 | tegra_gpio_config(common_gpio_table, ARRAY_SIZE(common_gpio_table)); |
229 | } | ||
230 | |||
231 | void __init seaboard_pinmux_init(void) | ||
232 | { | ||
233 | seaboard_common_pinmux_init(); | ||
182 | } | 234 | } |
235 | |||
236 | void __init ventana_pinmux_init(void) | ||
237 | { | ||
238 | update_pinmux(ventana_pinmux, ARRAY_SIZE(ventana_pinmux)); | ||
239 | seaboard_common_pinmux_init(); | ||
240 | } | ||
241 | |||
diff --git a/arch/arm/mach-tegra/board-trimslice-pinmux.c b/arch/arm/mach-tegra/board-trimslice-pinmux.c index bcb1916e68b9..4969dd28a04c 100644 --- a/arch/arm/mach-tegra/board-trimslice-pinmux.c +++ b/arch/arm/mach-tegra/board-trimslice-pinmux.c | |||
@@ -21,6 +21,7 @@ | |||
21 | 21 | ||
22 | #include "gpio-names.h" | 22 | #include "gpio-names.h" |
23 | #include "board-trimslice.h" | 23 | #include "board-trimslice.h" |
24 | #include "devices.h" | ||
24 | 25 | ||
25 | static __initdata struct tegra_pingroup_config trimslice_pinmux[] = { | 26 | static __initdata struct tegra_pingroup_config trimslice_pinmux[] = { |
26 | {TEGRA_PINGROUP_ATA, TEGRA_MUX_IDE, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE}, | 27 | {TEGRA_PINGROUP_ATA, TEGRA_MUX_IDE, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE}, |
@@ -141,6 +142,11 @@ static __initdata struct tegra_pingroup_config trimslice_pinmux[] = { | |||
141 | {TEGRA_PINGROUP_XM2D, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, | 142 | {TEGRA_PINGROUP_XM2D, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, |
142 | }; | 143 | }; |
143 | 144 | ||
145 | static struct platform_device *pinmux_devices[] = { | ||
146 | &tegra_gpio_device, | ||
147 | &tegra_pinmux_device, | ||
148 | }; | ||
149 | |||
144 | static struct tegra_gpio_table gpio_table[] = { | 150 | static struct tegra_gpio_table gpio_table[] = { |
145 | { .gpio = TRIMSLICE_GPIO_SD4_CD, .enable = true }, /* mmc4 cd */ | 151 | { .gpio = TRIMSLICE_GPIO_SD4_CD, .enable = true }, /* mmc4 cd */ |
146 | { .gpio = TRIMSLICE_GPIO_SD4_WP, .enable = true }, /* mmc4 wp */ | 152 | { .gpio = TRIMSLICE_GPIO_SD4_WP, .enable = true }, /* mmc4 wp */ |
@@ -151,6 +157,7 @@ static struct tegra_gpio_table gpio_table[] = { | |||
151 | 157 | ||
152 | void __init trimslice_pinmux_init(void) | 158 | void __init trimslice_pinmux_init(void) |
153 | { | 159 | { |
160 | platform_add_devices(pinmux_devices, ARRAY_SIZE(pinmux_devices)); | ||
154 | tegra_pinmux_config_table(trimslice_pinmux, ARRAY_SIZE(trimslice_pinmux)); | 161 | tegra_pinmux_config_table(trimslice_pinmux, ARRAY_SIZE(trimslice_pinmux)); |
155 | tegra_gpio_config(gpio_table, ARRAY_SIZE(gpio_table)); | 162 | tegra_gpio_config(gpio_table, ARRAY_SIZE(gpio_table)); |
156 | } | 163 | } |
diff --git a/arch/arm/mach-tegra/devices.c b/arch/arm/mach-tegra/devices.c index 489e82b5282a..7a2a02dbd632 100644 --- a/arch/arm/mach-tegra/devices.c +++ b/arch/arm/mach-tegra/devices.c | |||
@@ -33,6 +33,90 @@ | |||
33 | #include "gpio-names.h" | 33 | #include "gpio-names.h" |
34 | #include "devices.h" | 34 | #include "devices.h" |
35 | 35 | ||
36 | static struct resource gpio_resource[] = { | ||
37 | [0] = { | ||
38 | .start = TEGRA_GPIO_BASE, | ||
39 | .end = TEGRA_GPIO_BASE + TEGRA_GPIO_SIZE-1, | ||
40 | .flags = IORESOURCE_MEM, | ||
41 | }, | ||
42 | [1] = { | ||
43 | .start = INT_GPIO1, | ||
44 | .end = INT_GPIO1, | ||
45 | .flags = IORESOURCE_IRQ, | ||
46 | }, | ||
47 | [2] = { | ||
48 | .start = INT_GPIO2, | ||
49 | .end = INT_GPIO2, | ||
50 | .flags = IORESOURCE_IRQ, | ||
51 | }, | ||
52 | [3] = { | ||
53 | .start = INT_GPIO3, | ||
54 | .end = INT_GPIO3, | ||
55 | .flags = IORESOURCE_IRQ, | ||
56 | }, | ||
57 | [4] = { | ||
58 | .start = INT_GPIO4, | ||
59 | .end = INT_GPIO4, | ||
60 | .flags = IORESOURCE_IRQ, | ||
61 | }, | ||
62 | [5] = { | ||
63 | .start = INT_GPIO5, | ||
64 | .end = INT_GPIO5, | ||
65 | .flags = IORESOURCE_IRQ, | ||
66 | }, | ||
67 | [6] = { | ||
68 | .start = INT_GPIO6, | ||
69 | .end = INT_GPIO6, | ||
70 | .flags = IORESOURCE_IRQ, | ||
71 | }, | ||
72 | [7] = { | ||
73 | .start = INT_GPIO7, | ||
74 | .end = INT_GPIO7, | ||
75 | .flags = IORESOURCE_IRQ, | ||
76 | }, | ||
77 | }; | ||
78 | |||
79 | struct platform_device tegra_gpio_device = { | ||
80 | .name = "tegra-gpio", | ||
81 | .id = -1, | ||
82 | .resource = gpio_resource, | ||
83 | .num_resources = ARRAY_SIZE(gpio_resource), | ||
84 | }; | ||
85 | |||
86 | static struct resource pinmux_resource[] = { | ||
87 | [0] = { | ||
88 | /* Tri-state registers */ | ||
89 | .start = TEGRA_APB_MISC_BASE + 0x14, | ||
90 | .end = TEGRA_APB_MISC_BASE + 0x20 + 3, | ||
91 | .flags = IORESOURCE_MEM, | ||
92 | }, | ||
93 | [1] = { | ||
94 | /* Mux registers */ | ||
95 | .start = TEGRA_APB_MISC_BASE + 0x80, | ||
96 | .end = TEGRA_APB_MISC_BASE + 0x9c + 3, | ||
97 | .flags = IORESOURCE_MEM, | ||
98 | }, | ||
99 | [2] = { | ||
100 | /* Pull-up/down registers */ | ||
101 | .start = TEGRA_APB_MISC_BASE + 0xa0, | ||
102 | .end = TEGRA_APB_MISC_BASE + 0xb0 + 3, | ||
103 | .flags = IORESOURCE_MEM, | ||
104 | }, | ||
105 | [3] = { | ||
106 | /* Pad control registers */ | ||
107 | .start = TEGRA_APB_MISC_BASE + 0x868, | ||
108 | .end = TEGRA_APB_MISC_BASE + 0x90c + 3, | ||
109 | .flags = IORESOURCE_MEM, | ||
110 | }, | ||
111 | }; | ||
112 | |||
113 | struct platform_device tegra_pinmux_device = { | ||
114 | .name = "tegra-pinmux", | ||
115 | .id = -1, | ||
116 | .resource = pinmux_resource, | ||
117 | .num_resources = ARRAY_SIZE(pinmux_resource), | ||
118 | }; | ||
119 | |||
36 | static struct resource i2c_resource1[] = { | 120 | static struct resource i2c_resource1[] = { |
37 | [0] = { | 121 | [0] = { |
38 | .start = INT_I2C, | 122 | .start = INT_I2C, |
diff --git a/arch/arm/mach-tegra/devices.h b/arch/arm/mach-tegra/devices.h index 4a7dc0a097d6..873ecb2f8ae6 100644 --- a/arch/arm/mach-tegra/devices.h +++ b/arch/arm/mach-tegra/devices.h | |||
@@ -21,6 +21,8 @@ | |||
21 | 21 | ||
22 | #include <linux/platform_device.h> | 22 | #include <linux/platform_device.h> |
23 | 23 | ||
24 | extern struct platform_device tegra_gpio_device; | ||
25 | extern struct platform_device tegra_pinmux_device; | ||
24 | extern struct platform_device tegra_sdhci_device1; | 26 | extern struct platform_device tegra_sdhci_device1; |
25 | extern struct platform_device tegra_sdhci_device2; | 27 | extern struct platform_device tegra_sdhci_device2; |
26 | extern struct platform_device tegra_sdhci_device3; | 28 | extern struct platform_device tegra_sdhci_device3; |
diff --git a/arch/arm/mach-tegra/include/mach/pinmux.h b/arch/arm/mach-tegra/include/mach/pinmux.h index defd8775defa..bb7dfdb61205 100644 --- a/arch/arm/mach-tegra/include/mach/pinmux.h +++ b/arch/arm/mach-tegra/include/mach/pinmux.h | |||
@@ -199,6 +199,7 @@ struct tegra_drive_pingroup_config { | |||
199 | 199 | ||
200 | struct tegra_drive_pingroup_desc { | 200 | struct tegra_drive_pingroup_desc { |
201 | const char *name; | 201 | const char *name; |
202 | s16 reg_bank; | ||
202 | s16 reg; | 203 | s16 reg; |
203 | }; | 204 | }; |
204 | 205 | ||
@@ -207,6 +208,9 @@ struct tegra_pingroup_desc { | |||
207 | int funcs[4]; | 208 | int funcs[4]; |
208 | int func_safe; | 209 | int func_safe; |
209 | int vddio; | 210 | int vddio; |
211 | s16 tri_bank; /* Register bank the tri_reg exists within */ | ||
212 | s16 mux_bank; /* Register bank the mux_reg exists within */ | ||
213 | s16 pupd_bank; /* Register bank the pupd_reg exists within */ | ||
210 | s16 tri_reg; /* offset into the TRISTATE_REG_* register bank */ | 214 | s16 tri_reg; /* offset into the TRISTATE_REG_* register bank */ |
211 | s16 mux_reg; /* offset into the PIN_MUX_CTL_* register bank */ | 215 | s16 mux_reg; /* offset into the PIN_MUX_CTL_* register bank */ |
212 | s16 pupd_reg; /* offset into the PULL_UPDOWN_REG_* register bank */ | 216 | s16 pupd_reg; /* offset into the PULL_UPDOWN_REG_* register bank */ |
diff --git a/arch/arm/mach-tegra/pinmux-t2-tables.c b/arch/arm/mach-tegra/pinmux-t2-tables.c index a475367befa3..a0dc2bc28ed3 100644 --- a/arch/arm/mach-tegra/pinmux-t2-tables.c +++ b/arch/arm/mach-tegra/pinmux-t2-tables.c | |||
@@ -31,10 +31,16 @@ | |||
31 | #include <mach/pinmux.h> | 31 | #include <mach/pinmux.h> |
32 | #include <mach/suspend.h> | 32 | #include <mach/suspend.h> |
33 | 33 | ||
34 | #define TRISTATE_REG_A 0x14 | ||
35 | #define PIN_MUX_CTL_REG_A 0x80 | ||
36 | #define PULLUPDOWN_REG_A 0xa0 | ||
37 | #define PINGROUP_REG_A 0x868 | ||
38 | |||
34 | #define DRIVE_PINGROUP(pg_name, r) \ | 39 | #define DRIVE_PINGROUP(pg_name, r) \ |
35 | [TEGRA_DRIVE_PINGROUP_ ## pg_name] = { \ | 40 | [TEGRA_DRIVE_PINGROUP_ ## pg_name] = { \ |
36 | .name = #pg_name, \ | 41 | .name = #pg_name, \ |
37 | .reg = r \ | 42 | .reg_bank = 3, \ |
43 | .reg = ((r) - PINGROUP_REG_A) \ | ||
38 | } | 44 | } |
39 | 45 | ||
40 | const struct tegra_drive_pingroup_desc tegra_soc_drive_pingroups[TEGRA_MAX_DRIVE_PINGROUP] = { | 46 | const struct tegra_drive_pingroup_desc tegra_soc_drive_pingroups[TEGRA_MAX_DRIVE_PINGROUP] = { |
@@ -90,11 +96,14 @@ const struct tegra_drive_pingroup_desc tegra_soc_drive_pingroups[TEGRA_MAX_DRIVE | |||
90 | TEGRA_MUX_ ## f3, \ | 96 | TEGRA_MUX_ ## f3, \ |
91 | }, \ | 97 | }, \ |
92 | .func_safe = TEGRA_MUX_ ## f_safe, \ | 98 | .func_safe = TEGRA_MUX_ ## f_safe, \ |
93 | .tri_reg = tri_r, \ | 99 | .tri_bank = 0, \ |
100 | .tri_reg = ((tri_r) - TRISTATE_REG_A), \ | ||
94 | .tri_bit = tri_b, \ | 101 | .tri_bit = tri_b, \ |
95 | .mux_reg = mux_r, \ | 102 | .mux_bank = 1, \ |
103 | .mux_reg = ((mux_r) - PIN_MUX_CTL_REG_A), \ | ||
96 | .mux_bit = mux_b, \ | 104 | .mux_bit = mux_b, \ |
97 | .pupd_reg = pupd_r, \ | 105 | .pupd_bank = 2, \ |
106 | .pupd_reg = ((pupd_r) - PULLUPDOWN_REG_A), \ | ||
98 | .pupd_bit = pupd_b, \ | 107 | .pupd_bit = pupd_b, \ |
99 | } | 108 | } |
100 | 109 | ||
@@ -217,62 +226,3 @@ const struct tegra_pingroup_desc tegra_soc_pingroups[TEGRA_MAX_PINGROUP] = { | |||
217 | PINGROUP(XM2C, DDR, RSVD, RSVD, RSVD, RSVD, RSVD, -1, -1, -1, -1, 0xA8, 30), | 226 | PINGROUP(XM2C, DDR, RSVD, RSVD, RSVD, RSVD, RSVD, -1, -1, -1, -1, 0xA8, 30), |
218 | PINGROUP(XM2D, DDR, RSVD, RSVD, RSVD, RSVD, RSVD, -1, -1, -1, -1, 0xA8, 28), | 227 | PINGROUP(XM2D, DDR, RSVD, RSVD, RSVD, RSVD, RSVD, -1, -1, -1, -1, 0xA8, 28), |
219 | }; | 228 | }; |
220 | |||
221 | #ifdef CONFIG_PM | ||
222 | #define TRISTATE_REG_A 0x14 | ||
223 | #define TRISTATE_REG_NUM 4 | ||
224 | #define PIN_MUX_CTL_REG_A 0x80 | ||
225 | #define PIN_MUX_CTL_REG_NUM 8 | ||
226 | #define PULLUPDOWN_REG_A 0xa0 | ||
227 | #define PULLUPDOWN_REG_NUM 5 | ||
228 | |||
229 | static u32 pinmux_reg[TRISTATE_REG_NUM + PIN_MUX_CTL_REG_NUM + | ||
230 | PULLUPDOWN_REG_NUM + | ||
231 | ARRAY_SIZE(tegra_soc_drive_pingroups)]; | ||
232 | |||
233 | static inline unsigned long pg_readl(unsigned long offset) | ||
234 | { | ||
235 | return readl(IO_TO_VIRT(TEGRA_APB_MISC_BASE + offset)); | ||
236 | } | ||
237 | |||
238 | static inline void pg_writel(unsigned long value, unsigned long offset) | ||
239 | { | ||
240 | writel(value, IO_TO_VIRT(TEGRA_APB_MISC_BASE + offset)); | ||
241 | } | ||
242 | |||
243 | void tegra_pinmux_suspend(void) | ||
244 | { | ||
245 | unsigned int i; | ||
246 | u32 *ctx = pinmux_reg; | ||
247 | |||
248 | for (i = 0; i < PIN_MUX_CTL_REG_NUM; i++) | ||
249 | *ctx++ = pg_readl(PIN_MUX_CTL_REG_A + i*4); | ||
250 | |||
251 | for (i = 0; i < PULLUPDOWN_REG_NUM; i++) | ||
252 | *ctx++ = pg_readl(PULLUPDOWN_REG_A + i*4); | ||
253 | |||
254 | for (i = 0; i < TRISTATE_REG_NUM; i++) | ||
255 | *ctx++ = pg_readl(TRISTATE_REG_A + i*4); | ||
256 | |||
257 | for (i = 0; i < ARRAY_SIZE(tegra_soc_drive_pingroups); i++) | ||
258 | *ctx++ = pg_readl(tegra_soc_drive_pingroups[i].reg); | ||
259 | } | ||
260 | |||
261 | void tegra_pinmux_resume(void) | ||
262 | { | ||
263 | unsigned int i; | ||
264 | u32 *ctx = pinmux_reg; | ||
265 | |||
266 | for (i = 0; i < PIN_MUX_CTL_REG_NUM; i++) | ||
267 | pg_writel(*ctx++, PIN_MUX_CTL_REG_A + i*4); | ||
268 | |||
269 | for (i = 0; i < PULLUPDOWN_REG_NUM; i++) | ||
270 | pg_writel(*ctx++, PULLUPDOWN_REG_A + i*4); | ||
271 | |||
272 | for (i = 0; i < TRISTATE_REG_NUM; i++) | ||
273 | pg_writel(*ctx++, TRISTATE_REG_A + i*4); | ||
274 | |||
275 | for (i = 0; i < ARRAY_SIZE(tegra_soc_drive_pingroups); i++) | ||
276 | pg_writel(*ctx++, tegra_soc_drive_pingroups[i].reg); | ||
277 | } | ||
278 | #endif | ||
diff --git a/arch/arm/mach-tegra/pinmux.c b/arch/arm/mach-tegra/pinmux.c index f80d507671bc..1d201650d7a4 100644 --- a/arch/arm/mach-tegra/pinmux.c +++ b/arch/arm/mach-tegra/pinmux.c | |||
@@ -20,6 +20,7 @@ | |||
20 | #include <linux/errno.h> | 20 | #include <linux/errno.h> |
21 | #include <linux/spinlock.h> | 21 | #include <linux/spinlock.h> |
22 | #include <linux/io.h> | 22 | #include <linux/io.h> |
23 | #include <linux/platform_device.h> | ||
23 | 24 | ||
24 | #include <mach/iomap.h> | 25 | #include <mach/iomap.h> |
25 | #include <mach/pinmux.h> | 26 | #include <mach/pinmux.h> |
@@ -169,15 +170,17 @@ static const char *pupd_name(unsigned long val) | |||
169 | } | 170 | } |
170 | } | 171 | } |
171 | 172 | ||
173 | static int nbanks; | ||
174 | static void __iomem **regs; | ||
172 | 175 | ||
173 | static inline unsigned long pg_readl(unsigned long offset) | 176 | static inline u32 pg_readl(u32 bank, u32 reg) |
174 | { | 177 | { |
175 | return readl(IO_TO_VIRT(TEGRA_APB_MISC_BASE + offset)); | 178 | return readl(regs[bank] + reg); |
176 | } | 179 | } |
177 | 180 | ||
178 | static inline void pg_writel(unsigned long value, unsigned long offset) | 181 | static inline void pg_writel(u32 val, u32 bank, u32 reg) |
179 | { | 182 | { |
180 | writel(value, IO_TO_VIRT(TEGRA_APB_MISC_BASE + offset)); | 183 | writel(val, regs[bank] + reg); |
181 | } | 184 | } |
182 | 185 | ||
183 | static int tegra_pinmux_set_func(const struct tegra_pingroup_config *config) | 186 | static int tegra_pinmux_set_func(const struct tegra_pingroup_config *config) |
@@ -217,10 +220,10 @@ static int tegra_pinmux_set_func(const struct tegra_pingroup_config *config) | |||
217 | 220 | ||
218 | spin_lock_irqsave(&mux_lock, flags); | 221 | spin_lock_irqsave(&mux_lock, flags); |
219 | 222 | ||
220 | reg = pg_readl(pingroups[pg].mux_reg); | 223 | reg = pg_readl(pingroups[pg].mux_bank, pingroups[pg].mux_reg); |
221 | reg &= ~(0x3 << pingroups[pg].mux_bit); | 224 | reg &= ~(0x3 << pingroups[pg].mux_bit); |
222 | reg |= mux << pingroups[pg].mux_bit; | 225 | reg |= mux << pingroups[pg].mux_bit; |
223 | pg_writel(reg, pingroups[pg].mux_reg); | 226 | pg_writel(reg, pingroups[pg].mux_bank, pingroups[pg].mux_reg); |
224 | 227 | ||
225 | spin_unlock_irqrestore(&mux_lock, flags); | 228 | spin_unlock_irqrestore(&mux_lock, flags); |
226 | 229 | ||
@@ -241,11 +244,11 @@ int tegra_pinmux_set_tristate(enum tegra_pingroup pg, | |||
241 | 244 | ||
242 | spin_lock_irqsave(&mux_lock, flags); | 245 | spin_lock_irqsave(&mux_lock, flags); |
243 | 246 | ||
244 | reg = pg_readl(pingroups[pg].tri_reg); | 247 | reg = pg_readl(pingroups[pg].tri_bank, pingroups[pg].tri_reg); |
245 | reg &= ~(0x1 << pingroups[pg].tri_bit); | 248 | reg &= ~(0x1 << pingroups[pg].tri_bit); |
246 | if (tristate) | 249 | if (tristate) |
247 | reg |= 1 << pingroups[pg].tri_bit; | 250 | reg |= 1 << pingroups[pg].tri_bit; |
248 | pg_writel(reg, pingroups[pg].tri_reg); | 251 | pg_writel(reg, pingroups[pg].tri_bank, pingroups[pg].tri_reg); |
249 | 252 | ||
250 | spin_unlock_irqrestore(&mux_lock, flags); | 253 | spin_unlock_irqrestore(&mux_lock, flags); |
251 | 254 | ||
@@ -272,10 +275,10 @@ int tegra_pinmux_set_pullupdown(enum tegra_pingroup pg, | |||
272 | 275 | ||
273 | spin_lock_irqsave(&mux_lock, flags); | 276 | spin_lock_irqsave(&mux_lock, flags); |
274 | 277 | ||
275 | reg = pg_readl(pingroups[pg].pupd_reg); | 278 | reg = pg_readl(pingroups[pg].pupd_bank, pingroups[pg].pupd_reg); |
276 | reg &= ~(0x3 << pingroups[pg].pupd_bit); | 279 | reg &= ~(0x3 << pingroups[pg].pupd_bit); |
277 | reg |= pupd << pingroups[pg].pupd_bit; | 280 | reg |= pupd << pingroups[pg].pupd_bit; |
278 | pg_writel(reg, pingroups[pg].pupd_reg); | 281 | pg_writel(reg, pingroups[pg].pupd_bank, pingroups[pg].pupd_reg); |
279 | 282 | ||
280 | spin_unlock_irqrestore(&mux_lock, flags); | 283 | spin_unlock_irqrestore(&mux_lock, flags); |
281 | 284 | ||
@@ -362,12 +365,12 @@ static int tegra_drive_pinmux_set_hsm(enum tegra_drive_pingroup pg, | |||
362 | 365 | ||
363 | spin_lock_irqsave(&mux_lock, flags); | 366 | spin_lock_irqsave(&mux_lock, flags); |
364 | 367 | ||
365 | reg = pg_readl(drive_pingroups[pg].reg); | 368 | reg = pg_readl(drive_pingroups[pg].reg_bank, drive_pingroups[pg].reg); |
366 | if (hsm == TEGRA_HSM_ENABLE) | 369 | if (hsm == TEGRA_HSM_ENABLE) |
367 | reg |= (1 << 2); | 370 | reg |= (1 << 2); |
368 | else | 371 | else |
369 | reg &= ~(1 << 2); | 372 | reg &= ~(1 << 2); |
370 | pg_writel(reg, drive_pingroups[pg].reg); | 373 | pg_writel(reg, drive_pingroups[pg].reg_bank, drive_pingroups[pg].reg); |
371 | 374 | ||
372 | spin_unlock_irqrestore(&mux_lock, flags); | 375 | spin_unlock_irqrestore(&mux_lock, flags); |
373 | 376 | ||
@@ -387,12 +390,12 @@ static int tegra_drive_pinmux_set_schmitt(enum tegra_drive_pingroup pg, | |||
387 | 390 | ||
388 | spin_lock_irqsave(&mux_lock, flags); | 391 | spin_lock_irqsave(&mux_lock, flags); |
389 | 392 | ||
390 | reg = pg_readl(drive_pingroups[pg].reg); | 393 | reg = pg_readl(drive_pingroups[pg].reg_bank, drive_pingroups[pg].reg); |
391 | if (schmitt == TEGRA_SCHMITT_ENABLE) | 394 | if (schmitt == TEGRA_SCHMITT_ENABLE) |
392 | reg |= (1 << 3); | 395 | reg |= (1 << 3); |
393 | else | 396 | else |
394 | reg &= ~(1 << 3); | 397 | reg &= ~(1 << 3); |
395 | pg_writel(reg, drive_pingroups[pg].reg); | 398 | pg_writel(reg, drive_pingroups[pg].reg_bank, drive_pingroups[pg].reg); |
396 | 399 | ||
397 | spin_unlock_irqrestore(&mux_lock, flags); | 400 | spin_unlock_irqrestore(&mux_lock, flags); |
398 | 401 | ||
@@ -412,10 +415,10 @@ static int tegra_drive_pinmux_set_drive(enum tegra_drive_pingroup pg, | |||
412 | 415 | ||
413 | spin_lock_irqsave(&mux_lock, flags); | 416 | spin_lock_irqsave(&mux_lock, flags); |
414 | 417 | ||
415 | reg = pg_readl(drive_pingroups[pg].reg); | 418 | reg = pg_readl(drive_pingroups[pg].reg_bank, drive_pingroups[pg].reg); |
416 | reg &= ~(0x3 << 4); | 419 | reg &= ~(0x3 << 4); |
417 | reg |= drive << 4; | 420 | reg |= drive << 4; |
418 | pg_writel(reg, drive_pingroups[pg].reg); | 421 | pg_writel(reg, drive_pingroups[pg].reg_bank, drive_pingroups[pg].reg); |
419 | 422 | ||
420 | spin_unlock_irqrestore(&mux_lock, flags); | 423 | spin_unlock_irqrestore(&mux_lock, flags); |
421 | 424 | ||
@@ -435,10 +438,10 @@ static int tegra_drive_pinmux_set_pull_down(enum tegra_drive_pingroup pg, | |||
435 | 438 | ||
436 | spin_lock_irqsave(&mux_lock, flags); | 439 | spin_lock_irqsave(&mux_lock, flags); |
437 | 440 | ||
438 | reg = pg_readl(drive_pingroups[pg].reg); | 441 | reg = pg_readl(drive_pingroups[pg].reg_bank, drive_pingroups[pg].reg); |
439 | reg &= ~(0x1f << 12); | 442 | reg &= ~(0x1f << 12); |
440 | reg |= pull_down << 12; | 443 | reg |= pull_down << 12; |
441 | pg_writel(reg, drive_pingroups[pg].reg); | 444 | pg_writel(reg, drive_pingroups[pg].reg_bank, drive_pingroups[pg].reg); |
442 | 445 | ||
443 | spin_unlock_irqrestore(&mux_lock, flags); | 446 | spin_unlock_irqrestore(&mux_lock, flags); |
444 | 447 | ||
@@ -458,10 +461,10 @@ static int tegra_drive_pinmux_set_pull_up(enum tegra_drive_pingroup pg, | |||
458 | 461 | ||
459 | spin_lock_irqsave(&mux_lock, flags); | 462 | spin_lock_irqsave(&mux_lock, flags); |
460 | 463 | ||
461 | reg = pg_readl(drive_pingroups[pg].reg); | 464 | reg = pg_readl(drive_pingroups[pg].reg_bank, drive_pingroups[pg].reg); |
462 | reg &= ~(0x1f << 12); | 465 | reg &= ~(0x1f << 12); |
463 | reg |= pull_up << 12; | 466 | reg |= pull_up << 12; |
464 | pg_writel(reg, drive_pingroups[pg].reg); | 467 | pg_writel(reg, drive_pingroups[pg].reg_bank, drive_pingroups[pg].reg); |
465 | 468 | ||
466 | spin_unlock_irqrestore(&mux_lock, flags); | 469 | spin_unlock_irqrestore(&mux_lock, flags); |
467 | 470 | ||
@@ -481,10 +484,10 @@ static int tegra_drive_pinmux_set_slew_rising(enum tegra_drive_pingroup pg, | |||
481 | 484 | ||
482 | spin_lock_irqsave(&mux_lock, flags); | 485 | spin_lock_irqsave(&mux_lock, flags); |
483 | 486 | ||
484 | reg = pg_readl(drive_pingroups[pg].reg); | 487 | reg = pg_readl(drive_pingroups[pg].reg_bank, drive_pingroups[pg].reg); |
485 | reg &= ~(0x3 << 28); | 488 | reg &= ~(0x3 << 28); |
486 | reg |= slew_rising << 28; | 489 | reg |= slew_rising << 28; |
487 | pg_writel(reg, drive_pingroups[pg].reg); | 490 | pg_writel(reg, drive_pingroups[pg].reg_bank, drive_pingroups[pg].reg); |
488 | 491 | ||
489 | spin_unlock_irqrestore(&mux_lock, flags); | 492 | spin_unlock_irqrestore(&mux_lock, flags); |
490 | 493 | ||
@@ -504,10 +507,10 @@ static int tegra_drive_pinmux_set_slew_falling(enum tegra_drive_pingroup pg, | |||
504 | 507 | ||
505 | spin_lock_irqsave(&mux_lock, flags); | 508 | spin_lock_irqsave(&mux_lock, flags); |
506 | 509 | ||
507 | reg = pg_readl(drive_pingroups[pg].reg); | 510 | reg = pg_readl(drive_pingroups[pg].reg_bank, drive_pingroups[pg].reg); |
508 | reg &= ~(0x3 << 30); | 511 | reg &= ~(0x3 << 30); |
509 | reg |= slew_falling << 30; | 512 | reg |= slew_falling << 30; |
510 | pg_writel(reg, drive_pingroups[pg].reg); | 513 | pg_writel(reg, drive_pingroups[pg].reg_bank, drive_pingroups[pg].reg); |
511 | 514 | ||
512 | spin_unlock_irqrestore(&mux_lock, flags); | 515 | spin_unlock_irqrestore(&mux_lock, flags); |
513 | 516 | ||
@@ -665,6 +668,99 @@ void tegra_pinmux_config_pullupdown_table(const struct tegra_pingroup_config *co | |||
665 | } | 668 | } |
666 | } | 669 | } |
667 | 670 | ||
671 | static int __devinit tegra_pinmux_probe(struct platform_device *pdev) | ||
672 | { | ||
673 | struct resource *res; | ||
674 | int i; | ||
675 | int config_bad = 0; | ||
676 | |||
677 | for (i = 0; ; i++) { | ||
678 | res = platform_get_resource(pdev, IORESOURCE_MEM, i); | ||
679 | if (!res) | ||
680 | break; | ||
681 | } | ||
682 | nbanks = i; | ||
683 | |||
684 | for (i = 0; i < TEGRA_MAX_PINGROUP; i++) { | ||
685 | if (pingroups[i].tri_bank >= nbanks) { | ||
686 | dev_err(&pdev->dev, "pingroup %d: bad tri_bank\n", i); | ||
687 | config_bad = 1; | ||
688 | } | ||
689 | |||
690 | if (pingroups[i].mux_bank >= nbanks) { | ||
691 | dev_err(&pdev->dev, "pingroup %d: bad mux_bank\n", i); | ||
692 | config_bad = 1; | ||
693 | } | ||
694 | |||
695 | if (pingroups[i].pupd_bank >= nbanks) { | ||
696 | dev_err(&pdev->dev, "pingroup %d: bad pupd_bank\n", i); | ||
697 | config_bad = 1; | ||
698 | } | ||
699 | } | ||
700 | |||
701 | for (i = 0; i < TEGRA_MAX_DRIVE_PINGROUP; i++) { | ||
702 | if (drive_pingroups[i].reg_bank >= nbanks) { | ||
703 | dev_err(&pdev->dev, | ||
704 | "drive pingroup %d: bad reg_bank\n", i); | ||
705 | config_bad = 1; | ||
706 | } | ||
707 | } | ||
708 | |||
709 | if (config_bad) | ||
710 | return -ENODEV; | ||
711 | |||
712 | regs = devm_kzalloc(&pdev->dev, nbanks * sizeof(*regs), GFP_KERNEL); | ||
713 | if (!regs) { | ||
714 | dev_err(&pdev->dev, "Can't alloc regs pointer\n"); | ||
715 | return -ENODEV; | ||
716 | } | ||
717 | |||
718 | for (i = 0; i < nbanks; i++) { | ||
719 | res = platform_get_resource(pdev, IORESOURCE_MEM, i); | ||
720 | if (!res) { | ||
721 | dev_err(&pdev->dev, "Missing MEM resource\n"); | ||
722 | return -ENODEV; | ||
723 | } | ||
724 | |||
725 | if (!devm_request_mem_region(&pdev->dev, res->start, | ||
726 | resource_size(res), | ||
727 | dev_name(&pdev->dev))) { | ||
728 | dev_err(&pdev->dev, | ||
729 | "Couldn't request MEM resource %d\n", i); | ||
730 | return -ENODEV; | ||
731 | } | ||
732 | |||
733 | regs[i] = devm_ioremap(&pdev->dev, res->start, | ||
734 | resource_size(res)); | ||
735 | if (!regs) { | ||
736 | dev_err(&pdev->dev, "Couldn't ioremap regs %d\n", i); | ||
737 | return -ENODEV; | ||
738 | } | ||
739 | } | ||
740 | |||
741 | return 0; | ||
742 | } | ||
743 | |||
744 | static struct of_device_id tegra_pinmux_of_match[] __devinitdata = { | ||
745 | { .compatible = "nvidia,tegra20-pinmux", }, | ||
746 | { }, | ||
747 | }; | ||
748 | |||
749 | static struct platform_driver tegra_pinmux_driver = { | ||
750 | .driver = { | ||
751 | .name = "tegra-pinmux", | ||
752 | .owner = THIS_MODULE, | ||
753 | .of_match_table = tegra_pinmux_of_match, | ||
754 | }, | ||
755 | .probe = tegra_pinmux_probe, | ||
756 | }; | ||
757 | |||
758 | static int __init tegra_pinmux_init(void) | ||
759 | { | ||
760 | return platform_driver_register(&tegra_pinmux_driver); | ||
761 | } | ||
762 | postcore_initcall(tegra_pinmux_init); | ||
763 | |||
668 | #ifdef CONFIG_DEBUG_FS | 764 | #ifdef CONFIG_DEBUG_FS |
669 | 765 | ||
670 | #include <linux/debugfs.h> | 766 | #include <linux/debugfs.h> |
@@ -684,6 +780,7 @@ static int dbg_pinmux_show(struct seq_file *s, void *unused) | |||
684 | int len; | 780 | int len; |
685 | 781 | ||
686 | for (i = 0; i < TEGRA_MAX_PINGROUP; i++) { | 782 | for (i = 0; i < TEGRA_MAX_PINGROUP; i++) { |
783 | unsigned long reg; | ||
687 | unsigned long tri; | 784 | unsigned long tri; |
688 | unsigned long mux; | 785 | unsigned long mux; |
689 | unsigned long pupd; | 786 | unsigned long pupd; |
@@ -696,8 +793,9 @@ static int dbg_pinmux_show(struct seq_file *s, void *unused) | |||
696 | seq_printf(s, "TEGRA_MUX_NONE"); | 793 | seq_printf(s, "TEGRA_MUX_NONE"); |
697 | len = strlen("NONE"); | 794 | len = strlen("NONE"); |
698 | } else { | 795 | } else { |
699 | mux = (pg_readl(pingroups[i].mux_reg) >> | 796 | reg = pg_readl(pingroups[i].mux_bank, |
700 | pingroups[i].mux_bit) & 0x3; | 797 | pingroups[i].mux_reg); |
798 | mux = (reg >> pingroups[i].mux_bit) & 0x3; | ||
701 | if (pingroups[i].funcs[mux] == TEGRA_MUX_RSVD) { | 799 | if (pingroups[i].funcs[mux] == TEGRA_MUX_RSVD) { |
702 | seq_printf(s, "TEGRA_MUX_RSVD%1lu", mux+1); | 800 | seq_printf(s, "TEGRA_MUX_RSVD%1lu", mux+1); |
703 | len = 5; | 801 | len = 5; |
@@ -713,8 +811,9 @@ static int dbg_pinmux_show(struct seq_file *s, void *unused) | |||
713 | seq_printf(s, "TEGRA_PUPD_NORMAL"); | 811 | seq_printf(s, "TEGRA_PUPD_NORMAL"); |
714 | len = strlen("NORMAL"); | 812 | len = strlen("NORMAL"); |
715 | } else { | 813 | } else { |
716 | pupd = (pg_readl(pingroups[i].pupd_reg) >> | 814 | reg = pg_readl(pingroups[i].pupd_bank, |
717 | pingroups[i].pupd_bit) & 0x3; | 815 | pingroups[i].pupd_reg); |
816 | pupd = (reg >> pingroups[i].pupd_bit) & 0x3; | ||
718 | seq_printf(s, "TEGRA_PUPD_%s", pupd_name(pupd)); | 817 | seq_printf(s, "TEGRA_PUPD_%s", pupd_name(pupd)); |
719 | len = strlen(pupd_name(pupd)); | 818 | len = strlen(pupd_name(pupd)); |
720 | } | 819 | } |
@@ -723,8 +822,9 @@ static int dbg_pinmux_show(struct seq_file *s, void *unused) | |||
723 | if (pingroups[i].tri_reg < 0) { | 822 | if (pingroups[i].tri_reg < 0) { |
724 | seq_printf(s, "TEGRA_TRI_NORMAL"); | 823 | seq_printf(s, "TEGRA_TRI_NORMAL"); |
725 | } else { | 824 | } else { |
726 | tri = (pg_readl(pingroups[i].tri_reg) >> | 825 | reg = pg_readl(pingroups[i].tri_bank, |
727 | pingroups[i].tri_bit) & 0x1; | 826 | pingroups[i].tri_reg); |
827 | tri = (reg >> pingroups[i].tri_bit) & 0x1; | ||
728 | 828 | ||
729 | seq_printf(s, "TEGRA_TRI_%s", tri_name(tri)); | 829 | seq_printf(s, "TEGRA_TRI_%s", tri_name(tri)); |
730 | } | 830 | } |
@@ -759,7 +859,8 @@ static int dbg_drive_pinmux_show(struct seq_file *s, void *unused) | |||
759 | dbg_pad_field(s, 7 - len); | 859 | dbg_pad_field(s, 7 - len); |
760 | 860 | ||
761 | 861 | ||
762 | reg = pg_readl(drive_pingroups[i].reg); | 862 | reg = pg_readl(drive_pingroups[i].reg_bank, |
863 | drive_pingroups[i].reg); | ||
763 | if (HSM_EN(reg)) { | 864 | if (HSM_EN(reg)) { |
764 | seq_printf(s, "TEGRA_HSM_ENABLE"); | 865 | seq_printf(s, "TEGRA_HSM_ENABLE"); |
765 | len = 16; | 866 | len = 16; |