diff options
author | Arnd Bergmann <arnd@arndb.de> | 2011-10-20 12:15:30 -0400 |
---|---|---|
committer | Arnd Bergmann <arnd@arndb.de> | 2011-10-20 12:15:30 -0400 |
commit | 107532920226a37e595697959b2a6a823cfa2497 (patch) | |
tree | 7d35c84ed324e6cabeed29282f1fc97994fd204b | |
parent | 29ea35969b92a4be122a58c4aceea8c5e2c388d9 (diff) | |
parent | ecb7b0e33e048e63d1169e6fee277430c70ddf0b (diff) |
Merge branch 'tegra/devel' into next/devel
-rw-r--r-- | Documentation/devicetree/bindings/pinmux/pinmux_nvidia.txt | 5 | ||||
-rw-r--r-- | arch/arm/boot/dts/tegra-ventana.dts | 32 | ||||
-rw-r--r-- | arch/arm/boot/dts/tegra20.dtsi | 8 | ||||
-rw-r--r-- | arch/arm/configs/tegra_defconfig | 39 | ||||
-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 | ||||
-rw-r--r-- | drivers/gpio/gpio-tegra.c | 143 |
19 files changed, 535 insertions, 160 deletions
diff --git a/Documentation/devicetree/bindings/pinmux/pinmux_nvidia.txt b/Documentation/devicetree/bindings/pinmux/pinmux_nvidia.txt new file mode 100644 index 000000000000..36f82dbdd14d --- /dev/null +++ b/Documentation/devicetree/bindings/pinmux/pinmux_nvidia.txt | |||
@@ -0,0 +1,5 @@ | |||
1 | NVIDIA Tegra 2 pinmux controller | ||
2 | |||
3 | Required properties: | ||
4 | - compatible : "nvidia,tegra20-pinmux" | ||
5 | |||
diff --git a/arch/arm/boot/dts/tegra-ventana.dts b/arch/arm/boot/dts/tegra-ventana.dts new file mode 100644 index 000000000000..9b29a623aaf1 --- /dev/null +++ b/arch/arm/boot/dts/tegra-ventana.dts | |||
@@ -0,0 +1,32 @@ | |||
1 | /dts-v1/; | ||
2 | |||
3 | /memreserve/ 0x1c000000 0x04000000; | ||
4 | /include/ "tegra20.dtsi" | ||
5 | |||
6 | / { | ||
7 | model = "NVIDIA Tegra2 Ventana evaluation board"; | ||
8 | compatible = "nvidia,ventana", "nvidia,tegra20"; | ||
9 | |||
10 | chosen { | ||
11 | bootargs = "vmalloc=192M video=tegrafb console=ttyS0,115200n8 root=/dev/ram rdinit=/sbin/init"; | ||
12 | }; | ||
13 | |||
14 | memory { | ||
15 | reg = < 0x00000000 0x40000000 >; | ||
16 | }; | ||
17 | |||
18 | serial@70006300 { | ||
19 | clock-frequency = < 216000000 >; | ||
20 | }; | ||
21 | |||
22 | sdhci@c8000400 { | ||
23 | cd-gpios = <&gpio 69 0>; /* gpio PI5 */ | ||
24 | wp-gpios = <&gpio 57 0>; /* gpio PH1 */ | ||
25 | power-gpios = <&gpio 155 0>; /* gpio PT3 */ | ||
26 | }; | ||
27 | |||
28 | sdhci@c8000600 { | ||
29 | power-gpios = <&gpio 70 0>; /* gpio PI6 */ | ||
30 | support-8bit; | ||
31 | }; | ||
32 | }; | ||
diff --git a/arch/arm/boot/dts/tegra20.dtsi b/arch/arm/boot/dts/tegra20.dtsi index 5727595cde61..65d7e6a333eb 100644 --- a/arch/arm/boot/dts/tegra20.dtsi +++ b/arch/arm/boot/dts/tegra20.dtsi | |||
@@ -77,6 +77,14 @@ | |||
77 | gpio-controller; | 77 | gpio-controller; |
78 | }; | 78 | }; |
79 | 79 | ||
80 | pinmux: pinmux@70000000 { | ||
81 | compatible = "nvidia,tegra20-pinmux"; | ||
82 | reg = < 0x70000014 0x10 /* Tri-state registers */ | ||
83 | 0x70000080 0x20 /* Mux registers */ | ||
84 | 0x700000a0 0x14 /* Pull-up/down registers */ | ||
85 | 0x70000868 0xa8 >; /* Pad control registers */ | ||
86 | }; | ||
87 | |||
80 | serial@70006000 { | 88 | serial@70006000 { |
81 | compatible = "nvidia,tegra20-uart"; | 89 | compatible = "nvidia,tegra20-uart"; |
82 | reg = <0x70006000 0x40>; | 90 | reg = <0x70006000 0x40>; |
diff --git a/arch/arm/configs/tegra_defconfig b/arch/arm/configs/tegra_defconfig index 8845f1c9925d..195729760aeb 100644 --- a/arch/arm/configs/tegra_defconfig +++ b/arch/arm/configs/tegra_defconfig | |||
@@ -25,6 +25,7 @@ CONFIG_MACH_KAEN=y | |||
25 | CONFIG_MACH_PAZ00=y | 25 | CONFIG_MACH_PAZ00=y |
26 | CONFIG_MACH_TRIMSLICE=y | 26 | CONFIG_MACH_TRIMSLICE=y |
27 | CONFIG_MACH_WARIO=y | 27 | CONFIG_MACH_WARIO=y |
28 | CONFIG_MACH_VENTANA=y | ||
28 | CONFIG_TEGRA_DEBUG_UARTD=y | 29 | CONFIG_TEGRA_DEBUG_UARTD=y |
29 | CONFIG_ARM_ERRATA_742230=y | 30 | CONFIG_ARM_ERRATA_742230=y |
30 | CONFIG_NO_HZ=y | 31 | CONFIG_NO_HZ=y |
@@ -38,7 +39,6 @@ CONFIG_HIGHMEM=y | |||
38 | CONFIG_ZBOOT_ROM_TEXT=0x0 | 39 | CONFIG_ZBOOT_ROM_TEXT=0x0 |
39 | CONFIG_ZBOOT_ROM_BSS=0x0 | 40 | CONFIG_ZBOOT_ROM_BSS=0x0 |
40 | CONFIG_VFP=y | 41 | CONFIG_VFP=y |
41 | CONFIG_PM=y | ||
42 | CONFIG_NET=y | 42 | CONFIG_NET=y |
43 | CONFIG_PACKET=y | 43 | CONFIG_PACKET=y |
44 | CONFIG_UNIX=y | 44 | CONFIG_UNIX=y |
@@ -65,6 +65,7 @@ CONFIG_IPV6_TUNNEL=y | |||
65 | CONFIG_IPV6_MULTIPLE_TABLES=y | 65 | CONFIG_IPV6_MULTIPLE_TABLES=y |
66 | # CONFIG_WIRELESS is not set | 66 | # CONFIG_WIRELESS is not set |
67 | # CONFIG_FIRMWARE_IN_KERNEL is not set | 67 | # CONFIG_FIRMWARE_IN_KERNEL is not set |
68 | CONFIG_PROC_DEVICETREE=y | ||
68 | CONFIG_BLK_DEV_LOOP=y | 69 | CONFIG_BLK_DEV_LOOP=y |
69 | CONFIG_MISC_DEVICES=y | 70 | CONFIG_MISC_DEVICES=y |
70 | CONFIG_AD525X_DPOT=y | 71 | CONFIG_AD525X_DPOT=y |
@@ -72,34 +73,61 @@ CONFIG_AD525X_DPOT_I2C=y | |||
72 | CONFIG_ICS932S401=y | 73 | CONFIG_ICS932S401=y |
73 | CONFIG_APDS9802ALS=y | 74 | CONFIG_APDS9802ALS=y |
74 | CONFIG_ISL29003=y | 75 | CONFIG_ISL29003=y |
76 | CONFIG_SCSI=y | ||
77 | CONFIG_BLK_DEV_SD=y | ||
78 | # CONFIG_SCSI_LOWLEVEL is not set | ||
75 | CONFIG_NETDEVICES=y | 79 | CONFIG_NETDEVICES=y |
76 | CONFIG_DUMMY=y | 80 | CONFIG_DUMMY=y |
81 | CONFIG_NET_ETHERNET=y | ||
77 | CONFIG_R8169=y | 82 | CONFIG_R8169=y |
78 | # CONFIG_NETDEV_10000 is not set | 83 | # CONFIG_NETDEV_10000 is not set |
79 | # CONFIG_WLAN is not set | 84 | # CONFIG_WLAN is not set |
85 | CONFIG_USB_PEGASUS=y | ||
86 | CONFIG_USB_USBNET=y | ||
87 | CONFIG_USB_NET_SMSC75XX=y | ||
88 | CONFIG_USB_NET_SMSC95XX=y | ||
80 | # CONFIG_INPUT is not set | 89 | # CONFIG_INPUT is not set |
81 | # CONFIG_SERIO is not set | 90 | # CONFIG_SERIO is not set |
82 | # CONFIG_VT is not set | 91 | # CONFIG_VT is not set |
92 | # CONFIG_LEGACY_PTYS is not set | ||
83 | # CONFIG_DEVKMEM is not set | 93 | # CONFIG_DEVKMEM is not set |
84 | CONFIG_SERIAL_8250=y | 94 | CONFIG_SERIAL_8250=y |
85 | CONFIG_SERIAL_8250_CONSOLE=y | 95 | CONFIG_SERIAL_8250_CONSOLE=y |
86 | # CONFIG_LEGACY_PTYS is not set | 96 | CONFIG_SERIAL_OF_PLATFORM=y |
87 | # CONFIG_HW_RANDOM is not set | 97 | # CONFIG_HW_RANDOM is not set |
88 | CONFIG_I2C=y | 98 | CONFIG_I2C=y |
89 | # CONFIG_I2C_COMPAT is not set | 99 | # CONFIG_I2C_COMPAT is not set |
90 | # CONFIG_I2C_HELPER_AUTO is not set | 100 | # CONFIG_I2C_HELPER_AUTO is not set |
91 | CONFIG_I2C_TEGRA=y | 101 | CONFIG_I2C_TEGRA=y |
102 | CONFIG_SPI=y | ||
103 | CONFIG_SPI_TEGRA=y | ||
92 | CONFIG_SENSORS_LM90=y | 104 | CONFIG_SENSORS_LM90=y |
93 | CONFIG_MFD_TPS6586X=y | 105 | CONFIG_MFD_TPS6586X=y |
94 | CONFIG_REGULATOR=y | 106 | CONFIG_REGULATOR=y |
95 | CONFIG_REGULATOR_TPS6586X=y | 107 | CONFIG_REGULATOR_TPS6586X=y |
96 | # CONFIG_USB_SUPPORT is not set | 108 | CONFIG_SOUND=y |
109 | CONFIG_SND=y | ||
110 | # CONFIG_SND_SUPPORT_OLD_API is not set | ||
111 | # CONFIG_SND_DRIVERS is not set | ||
112 | # CONFIG_SND_PCI is not set | ||
113 | # CONFIG_SND_ARM is not set | ||
114 | # CONFIG_SND_SPI is not set | ||
115 | # CONFIG_SND_USB is not set | ||
116 | CONFIG_SND_SOC=y | ||
117 | CONFIG_SND_SOC_TEGRA=y | ||
118 | CONFIG_SND_SOC_TEGRA_WM8903=y | ||
119 | CONFIG_SND_SOC_TEGRA_TRIMSLICE=y | ||
120 | CONFIG_USB=y | ||
121 | CONFIG_USB_EHCI_HCD=y | ||
122 | CONFIG_USB_EHCI_TEGRA=y | ||
123 | CONFIG_USB_STORAGE=y | ||
97 | CONFIG_MMC=y | 124 | CONFIG_MMC=y |
98 | CONFIG_MMC_SDHCI=y | 125 | CONFIG_MMC_SDHCI=y |
99 | CONFIG_MMC_SDHCI_PLTFM=y | 126 | CONFIG_MMC_SDHCI_PLTFM=y |
100 | CONFIG_MMC_SDHCI_TEGRA=y | 127 | CONFIG_MMC_SDHCI_TEGRA=y |
128 | CONFIG_RTC_CLASS=y | ||
129 | CONFIG_RTC_DRV_TEGRA=y | ||
101 | CONFIG_STAGING=y | 130 | CONFIG_STAGING=y |
102 | # CONFIG_STAGING_EXCLUDE_BUILD is not set | ||
103 | CONFIG_IIO=y | 131 | CONFIG_IIO=y |
104 | CONFIG_SENSORS_ISL29018=y | 132 | CONFIG_SENSORS_ISL29018=y |
105 | CONFIG_SENSORS_AK8975=y | 133 | CONFIG_SENSORS_AK8975=y |
@@ -123,18 +151,15 @@ CONFIG_NLS_ISO8859_1=y | |||
123 | CONFIG_PRINTK_TIME=y | 151 | CONFIG_PRINTK_TIME=y |
124 | CONFIG_MAGIC_SYSRQ=y | 152 | CONFIG_MAGIC_SYSRQ=y |
125 | CONFIG_DEBUG_FS=y | 153 | CONFIG_DEBUG_FS=y |
126 | CONFIG_DEBUG_KERNEL=y | ||
127 | CONFIG_DETECT_HUNG_TASK=y | 154 | CONFIG_DETECT_HUNG_TASK=y |
128 | CONFIG_SCHEDSTATS=y | 155 | CONFIG_SCHEDSTATS=y |
129 | CONFIG_TIMER_STATS=y | 156 | CONFIG_TIMER_STATS=y |
130 | CONFIG_DEBUG_SLAB=y | 157 | CONFIG_DEBUG_SLAB=y |
131 | # CONFIG_DEBUG_PREEMPT is not set | 158 | # CONFIG_DEBUG_PREEMPT is not set |
132 | CONFIG_DEBUG_MUTEXES=y | 159 | CONFIG_DEBUG_MUTEXES=y |
133 | CONFIG_DEBUG_SPINLOCK_SLEEP=y | ||
134 | CONFIG_DEBUG_INFO=y | 160 | CONFIG_DEBUG_INFO=y |
135 | CONFIG_DEBUG_VM=y | 161 | CONFIG_DEBUG_VM=y |
136 | CONFIG_DEBUG_SG=y | 162 | CONFIG_DEBUG_SG=y |
137 | # CONFIG_RCU_CPU_STALL_DETECTOR is not set | ||
138 | CONFIG_DEBUG_LL=y | 163 | CONFIG_DEBUG_LL=y |
139 | CONFIG_EARLY_PRINTK=y | 164 | CONFIG_EARLY_PRINTK=y |
140 | CONFIG_CRYPTO_ECB=y | 165 | CONFIG_CRYPTO_ECB=y |
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 428ad122be03..a2356ad3c8c1 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 bdd2627dd87b..43633f4d4bcf 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 }, |
@@ -149,6 +155,8 @@ static struct tegra_gpio_table gpio_table[] = { | |||
149 | 155 | ||
150 | void paz00_pinmux_init(void) | 156 | void paz00_pinmux_init(void) |
151 | { | 157 | { |
158 | platform_add_devices(pinmux_devices, ARRAY_SIZE(pinmux_devices)); | ||
159 | |||
152 | tegra_pinmux_config_table(paz00_pinmux, ARRAY_SIZE(paz00_pinmux)); | 160 | tegra_pinmux_config_table(paz00_pinmux, ARRAY_SIZE(paz00_pinmux)); |
153 | 161 | ||
154 | tegra_gpio_config(gpio_table, ARRAY_SIZE(gpio_table)); | 162 | 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 0bda495e9742..dd3b7405b4d4 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 }, |
@@ -169,12 +194,46 @@ static struct tegra_gpio_table gpio_table[] = { | |||
169 | { .gpio = TEGRA_GPIO_ISL29018_IRQ, .enable = true }, | 194 | { .gpio = TEGRA_GPIO_ISL29018_IRQ, .enable = true }, |
170 | }; | 195 | }; |
171 | 196 | ||
172 | void __init seaboard_pinmux_init(void) | 197 | static void __init update_pinmux(struct tegra_pingroup_config *newtbl, int size) |
198 | { | ||
199 | int i, j; | ||
200 | struct tegra_pingroup_config *new_pingroup, *base_pingroup; | ||
201 | |||
202 | /* Update base seaboard pinmux table with secondary board | ||
203 | * specific pinmux table table. | ||
204 | */ | ||
205 | for (i = 0; i < size; i++) { | ||
206 | new_pingroup = &newtbl[i]; | ||
207 | for (j = 0; j < ARRAY_SIZE(seaboard_pinmux); j++) { | ||
208 | base_pingroup = &seaboard_pinmux[j]; | ||
209 | if (new_pingroup->pingroup == base_pingroup->pingroup) { | ||
210 | *base_pingroup = *new_pingroup; | ||
211 | break; | ||
212 | } | ||
213 | } | ||
214 | } | ||
215 | } | ||
216 | |||
217 | void __init seaboard_common_pinmux_init(void) | ||
173 | { | 218 | { |
219 | platform_add_devices(pinmux_devices, ARRAY_SIZE(pinmux_devices)); | ||
220 | |||
174 | tegra_pinmux_config_table(seaboard_pinmux, ARRAY_SIZE(seaboard_pinmux)); | 221 | tegra_pinmux_config_table(seaboard_pinmux, ARRAY_SIZE(seaboard_pinmux)); |
175 | 222 | ||
176 | tegra_drive_pinmux_config_table(seaboard_drive_pinmux, | 223 | tegra_drive_pinmux_config_table(seaboard_drive_pinmux, |
177 | ARRAY_SIZE(seaboard_drive_pinmux)); | 224 | ARRAY_SIZE(seaboard_drive_pinmux)); |
178 | 225 | ||
179 | tegra_gpio_config(gpio_table, ARRAY_SIZE(gpio_table)); | 226 | tegra_gpio_config(common_gpio_table, ARRAY_SIZE(common_gpio_table)); |
227 | } | ||
228 | |||
229 | void __init seaboard_pinmux_init(void) | ||
230 | { | ||
231 | seaboard_common_pinmux_init(); | ||
180 | } | 232 | } |
233 | |||
234 | void __init ventana_pinmux_init(void) | ||
235 | { | ||
236 | update_pinmux(ventana_pinmux, ARRAY_SIZE(ventana_pinmux)); | ||
237 | seaboard_common_pinmux_init(); | ||
238 | } | ||
239 | |||
diff --git a/arch/arm/mach-tegra/board-trimslice-pinmux.c b/arch/arm/mach-tegra/board-trimslice-pinmux.c index 47c596cdbf32..8417ba77f765 100644 --- a/arch/arm/mach-tegra/board-trimslice-pinmux.c +++ b/arch/arm/mach-tegra/board-trimslice-pinmux.c | |||
@@ -22,6 +22,7 @@ | |||
22 | 22 | ||
23 | #include "gpio-names.h" | 23 | #include "gpio-names.h" |
24 | #include "board-trimslice.h" | 24 | #include "board-trimslice.h" |
25 | #include "devices.h" | ||
25 | 26 | ||
26 | static __initdata struct tegra_pingroup_config trimslice_pinmux[] = { | 27 | static __initdata struct tegra_pingroup_config trimslice_pinmux[] = { |
27 | {TEGRA_PINGROUP_ATA, TEGRA_MUX_IDE, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE}, | 28 | {TEGRA_PINGROUP_ATA, TEGRA_MUX_IDE, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE}, |
@@ -142,6 +143,11 @@ static __initdata struct tegra_pingroup_config trimslice_pinmux[] = { | |||
142 | {TEGRA_PINGROUP_XM2D, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, | 143 | {TEGRA_PINGROUP_XM2D, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, |
143 | }; | 144 | }; |
144 | 145 | ||
146 | static struct platform_device *pinmux_devices[] = { | ||
147 | &tegra_gpio_device, | ||
148 | &tegra_pinmux_device, | ||
149 | }; | ||
150 | |||
145 | static struct tegra_gpio_table gpio_table[] = { | 151 | static struct tegra_gpio_table gpio_table[] = { |
146 | { .gpio = TRIMSLICE_GPIO_SD4_CD, .enable = true }, /* mmc4 cd */ | 152 | { .gpio = TRIMSLICE_GPIO_SD4_CD, .enable = true }, /* mmc4 cd */ |
147 | { .gpio = TRIMSLICE_GPIO_SD4_WP, .enable = true }, /* mmc4 wp */ | 153 | { .gpio = TRIMSLICE_GPIO_SD4_WP, .enable = true }, /* mmc4 wp */ |
@@ -152,6 +158,7 @@ static struct tegra_gpio_table gpio_table[] = { | |||
152 | 158 | ||
153 | void __init trimslice_pinmux_init(void) | 159 | void __init trimslice_pinmux_init(void) |
154 | { | 160 | { |
161 | platform_add_devices(pinmux_devices, ARRAY_SIZE(pinmux_devices)); | ||
155 | tegra_pinmux_config_table(trimslice_pinmux, ARRAY_SIZE(trimslice_pinmux)); | 162 | tegra_pinmux_config_table(trimslice_pinmux, ARRAY_SIZE(trimslice_pinmux)); |
156 | tegra_gpio_config(gpio_table, ARRAY_SIZE(gpio_table)); | 163 | tegra_gpio_config(gpio_table, ARRAY_SIZE(gpio_table)); |
157 | } | 164 | } |
diff --git a/arch/arm/mach-tegra/devices.c b/arch/arm/mach-tegra/devices.c index 57e35d20c24c..240d5dc58928 100644 --- a/arch/arm/mach-tegra/devices.c +++ b/arch/arm/mach-tegra/devices.c | |||
@@ -31,6 +31,90 @@ | |||
31 | #include <mach/usb_phy.h> | 31 | #include <mach/usb_phy.h> |
32 | #include "gpio-names.h" | 32 | #include "gpio-names.h" |
33 | 33 | ||
34 | static struct resource gpio_resource[] = { | ||
35 | [0] = { | ||
36 | .start = TEGRA_GPIO_BASE, | ||
37 | .end = TEGRA_GPIO_BASE + TEGRA_GPIO_SIZE-1, | ||
38 | .flags = IORESOURCE_MEM, | ||
39 | }, | ||
40 | [1] = { | ||
41 | .start = INT_GPIO1, | ||
42 | .end = INT_GPIO1, | ||
43 | .flags = IORESOURCE_IRQ, | ||
44 | }, | ||
45 | [2] = { | ||
46 | .start = INT_GPIO2, | ||
47 | .end = INT_GPIO2, | ||
48 | .flags = IORESOURCE_IRQ, | ||
49 | }, | ||
50 | [3] = { | ||
51 | .start = INT_GPIO3, | ||
52 | .end = INT_GPIO3, | ||
53 | .flags = IORESOURCE_IRQ, | ||
54 | }, | ||
55 | [4] = { | ||
56 | .start = INT_GPIO4, | ||
57 | .end = INT_GPIO4, | ||
58 | .flags = IORESOURCE_IRQ, | ||
59 | }, | ||
60 | [5] = { | ||
61 | .start = INT_GPIO5, | ||
62 | .end = INT_GPIO5, | ||
63 | .flags = IORESOURCE_IRQ, | ||
64 | }, | ||
65 | [6] = { | ||
66 | .start = INT_GPIO6, | ||
67 | .end = INT_GPIO6, | ||
68 | .flags = IORESOURCE_IRQ, | ||
69 | }, | ||
70 | [7] = { | ||
71 | .start = INT_GPIO7, | ||
72 | .end = INT_GPIO7, | ||
73 | .flags = IORESOURCE_IRQ, | ||
74 | }, | ||
75 | }; | ||
76 | |||
77 | struct platform_device tegra_gpio_device = { | ||
78 | .name = "tegra-gpio", | ||
79 | .id = -1, | ||
80 | .resource = gpio_resource, | ||
81 | .num_resources = ARRAY_SIZE(gpio_resource), | ||
82 | }; | ||
83 | |||
84 | static struct resource pinmux_resource[] = { | ||
85 | [0] = { | ||
86 | /* Tri-state registers */ | ||
87 | .start = TEGRA_APB_MISC_BASE + 0x14, | ||
88 | .end = TEGRA_APB_MISC_BASE + 0x20 + 3, | ||
89 | .flags = IORESOURCE_MEM, | ||
90 | }, | ||
91 | [1] = { | ||
92 | /* Mux registers */ | ||
93 | .start = TEGRA_APB_MISC_BASE + 0x80, | ||
94 | .end = TEGRA_APB_MISC_BASE + 0x9c + 3, | ||
95 | .flags = IORESOURCE_MEM, | ||
96 | }, | ||
97 | [2] = { | ||
98 | /* Pull-up/down registers */ | ||
99 | .start = TEGRA_APB_MISC_BASE + 0xa0, | ||
100 | .end = TEGRA_APB_MISC_BASE + 0xb0 + 3, | ||
101 | .flags = IORESOURCE_MEM, | ||
102 | }, | ||
103 | [3] = { | ||
104 | /* Pad control registers */ | ||
105 | .start = TEGRA_APB_MISC_BASE + 0x868, | ||
106 | .end = TEGRA_APB_MISC_BASE + 0x90c + 3, | ||
107 | .flags = IORESOURCE_MEM, | ||
108 | }, | ||
109 | }; | ||
110 | |||
111 | struct platform_device tegra_pinmux_device = { | ||
112 | .name = "tegra-pinmux", | ||
113 | .id = -1, | ||
114 | .resource = pinmux_resource, | ||
115 | .num_resources = ARRAY_SIZE(pinmux_resource), | ||
116 | }; | ||
117 | |||
34 | static struct resource i2c_resource1[] = { | 118 | static struct resource i2c_resource1[] = { |
35 | [0] = { | 119 | [0] = { |
36 | .start = INT_I2C, | 120 | .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; |
diff --git a/drivers/gpio/gpio-tegra.c b/drivers/gpio/gpio-tegra.c index 747eb40e8afe..75cf91138b69 100644 --- a/drivers/gpio/gpio-tegra.c +++ b/drivers/gpio/gpio-tegra.c | |||
@@ -20,10 +20,11 @@ | |||
20 | #include <linux/init.h> | 20 | #include <linux/init.h> |
21 | #include <linux/irq.h> | 21 | #include <linux/irq.h> |
22 | #include <linux/interrupt.h> | 22 | #include <linux/interrupt.h> |
23 | |||
24 | #include <linux/io.h> | 23 | #include <linux/io.h> |
25 | #include <linux/gpio.h> | 24 | #include <linux/gpio.h> |
26 | #include <linux/of.h> | 25 | #include <linux/of.h> |
26 | #include <linux/platform_device.h> | ||
27 | #include <linux/module.h> | ||
27 | 28 | ||
28 | #include <asm/mach/irq.h> | 29 | #include <asm/mach/irq.h> |
29 | 30 | ||
@@ -34,9 +35,7 @@ | |||
34 | #define GPIO_PORT(x) (((x) >> 3) & 0x3) | 35 | #define GPIO_PORT(x) (((x) >> 3) & 0x3) |
35 | #define GPIO_BIT(x) ((x) & 0x7) | 36 | #define GPIO_BIT(x) ((x) & 0x7) |
36 | 37 | ||
37 | #define GPIO_REG(x) (IO_TO_VIRT(TEGRA_GPIO_BASE) + \ | 38 | #define GPIO_REG(x) (GPIO_BANK(x) * 0x80 + GPIO_PORT(x) * 4) |
38 | GPIO_BANK(x) * 0x80 + \ | ||
39 | GPIO_PORT(x) * 4) | ||
40 | 39 | ||
41 | #define GPIO_CNF(x) (GPIO_REG(x) + 0x00) | 40 | #define GPIO_CNF(x) (GPIO_REG(x) + 0x00) |
42 | #define GPIO_OE(x) (GPIO_REG(x) + 0x10) | 41 | #define GPIO_OE(x) (GPIO_REG(x) + 0x10) |
@@ -75,15 +74,18 @@ struct tegra_gpio_bank { | |||
75 | }; | 74 | }; |
76 | 75 | ||
77 | 76 | ||
78 | static struct tegra_gpio_bank tegra_gpio_banks[] = { | 77 | static void __iomem *regs; |
79 | {.bank = 0, .irq = INT_GPIO1}, | 78 | static struct tegra_gpio_bank tegra_gpio_banks[7]; |
80 | {.bank = 1, .irq = INT_GPIO2}, | 79 | |
81 | {.bank = 2, .irq = INT_GPIO3}, | 80 | static inline void tegra_gpio_writel(u32 val, u32 reg) |
82 | {.bank = 3, .irq = INT_GPIO4}, | 81 | { |
83 | {.bank = 4, .irq = INT_GPIO5}, | 82 | __raw_writel(val, regs + reg); |
84 | {.bank = 5, .irq = INT_GPIO6}, | 83 | } |
85 | {.bank = 6, .irq = INT_GPIO7}, | 84 | |
86 | }; | 85 | static inline u32 tegra_gpio_readl(u32 reg) |
86 | { | ||
87 | return __raw_readl(regs + reg); | ||
88 | } | ||
87 | 89 | ||
88 | static int tegra_gpio_compose(int bank, int port, int bit) | 90 | static int tegra_gpio_compose(int bank, int port, int bit) |
89 | { | 91 | { |
@@ -97,7 +99,7 @@ static void tegra_gpio_mask_write(u32 reg, int gpio, int value) | |||
97 | val = 0x100 << GPIO_BIT(gpio); | 99 | val = 0x100 << GPIO_BIT(gpio); |
98 | if (value) | 100 | if (value) |
99 | val |= 1 << GPIO_BIT(gpio); | 101 | val |= 1 << GPIO_BIT(gpio); |
100 | __raw_writel(val, reg); | 102 | tegra_gpio_writel(val, reg); |
101 | } | 103 | } |
102 | 104 | ||
103 | void tegra_gpio_enable(int gpio) | 105 | void tegra_gpio_enable(int gpio) |
@@ -117,7 +119,7 @@ static void tegra_gpio_set(struct gpio_chip *chip, unsigned offset, int value) | |||
117 | 119 | ||
118 | static int tegra_gpio_get(struct gpio_chip *chip, unsigned offset) | 120 | static int tegra_gpio_get(struct gpio_chip *chip, unsigned offset) |
119 | { | 121 | { |
120 | return (__raw_readl(GPIO_IN(offset)) >> GPIO_BIT(offset)) & 0x1; | 122 | return (tegra_gpio_readl(GPIO_IN(offset)) >> GPIO_BIT(offset)) & 0x1; |
121 | } | 123 | } |
122 | 124 | ||
123 | static int tegra_gpio_direction_input(struct gpio_chip *chip, unsigned offset) | 125 | static int tegra_gpio_direction_input(struct gpio_chip *chip, unsigned offset) |
@@ -150,7 +152,7 @@ static void tegra_gpio_irq_ack(struct irq_data *d) | |||
150 | { | 152 | { |
151 | int gpio = d->irq - INT_GPIO_BASE; | 153 | int gpio = d->irq - INT_GPIO_BASE; |
152 | 154 | ||
153 | __raw_writel(1 << GPIO_BIT(gpio), GPIO_INT_CLR(gpio)); | 155 | tegra_gpio_writel(1 << GPIO_BIT(gpio), GPIO_INT_CLR(gpio)); |
154 | } | 156 | } |
155 | 157 | ||
156 | static void tegra_gpio_irq_mask(struct irq_data *d) | 158 | static void tegra_gpio_irq_mask(struct irq_data *d) |
@@ -203,10 +205,10 @@ static int tegra_gpio_irq_set_type(struct irq_data *d, unsigned int type) | |||
203 | 205 | ||
204 | spin_lock_irqsave(&bank->lvl_lock[port], flags); | 206 | spin_lock_irqsave(&bank->lvl_lock[port], flags); |
205 | 207 | ||
206 | val = __raw_readl(GPIO_INT_LVL(gpio)); | 208 | val = tegra_gpio_readl(GPIO_INT_LVL(gpio)); |
207 | val &= ~(GPIO_INT_LVL_MASK << GPIO_BIT(gpio)); | 209 | val &= ~(GPIO_INT_LVL_MASK << GPIO_BIT(gpio)); |
208 | val |= lvl_type << GPIO_BIT(gpio); | 210 | val |= lvl_type << GPIO_BIT(gpio); |
209 | __raw_writel(val, GPIO_INT_LVL(gpio)); | 211 | tegra_gpio_writel(val, GPIO_INT_LVL(gpio)); |
210 | 212 | ||
211 | spin_unlock_irqrestore(&bank->lvl_lock[port], flags); | 213 | spin_unlock_irqrestore(&bank->lvl_lock[port], flags); |
212 | 214 | ||
@@ -232,12 +234,12 @@ static void tegra_gpio_irq_handler(unsigned int irq, struct irq_desc *desc) | |||
232 | 234 | ||
233 | for (port = 0; port < 4; port++) { | 235 | for (port = 0; port < 4; port++) { |
234 | int gpio = tegra_gpio_compose(bank->bank, port, 0); | 236 | int gpio = tegra_gpio_compose(bank->bank, port, 0); |
235 | unsigned long sta = __raw_readl(GPIO_INT_STA(gpio)) & | 237 | unsigned long sta = tegra_gpio_readl(GPIO_INT_STA(gpio)) & |
236 | __raw_readl(GPIO_INT_ENB(gpio)); | 238 | tegra_gpio_readl(GPIO_INT_ENB(gpio)); |
237 | u32 lvl = __raw_readl(GPIO_INT_LVL(gpio)); | 239 | u32 lvl = tegra_gpio_readl(GPIO_INT_LVL(gpio)); |
238 | 240 | ||
239 | for_each_set_bit(pin, &sta, 8) { | 241 | for_each_set_bit(pin, &sta, 8) { |
240 | __raw_writel(1 << pin, GPIO_INT_CLR(gpio)); | 242 | tegra_gpio_writel(1 << pin, GPIO_INT_CLR(gpio)); |
241 | 243 | ||
242 | /* if gpio is edge triggered, clear condition | 244 | /* if gpio is edge triggered, clear condition |
243 | * before executing the hander so that we don't | 245 | * before executing the hander so that we don't |
@@ -271,11 +273,11 @@ void tegra_gpio_resume(void) | |||
271 | 273 | ||
272 | for (p = 0; p < ARRAY_SIZE(bank->oe); p++) { | 274 | for (p = 0; p < ARRAY_SIZE(bank->oe); p++) { |
273 | unsigned int gpio = (b<<5) | (p<<3); | 275 | unsigned int gpio = (b<<5) | (p<<3); |
274 | __raw_writel(bank->cnf[p], GPIO_CNF(gpio)); | 276 | tegra_gpio_writel(bank->cnf[p], GPIO_CNF(gpio)); |
275 | __raw_writel(bank->out[p], GPIO_OUT(gpio)); | 277 | tegra_gpio_writel(bank->out[p], GPIO_OUT(gpio)); |
276 | __raw_writel(bank->oe[p], GPIO_OE(gpio)); | 278 | tegra_gpio_writel(bank->oe[p], GPIO_OE(gpio)); |
277 | __raw_writel(bank->int_lvl[p], GPIO_INT_LVL(gpio)); | 279 | tegra_gpio_writel(bank->int_lvl[p], GPIO_INT_LVL(gpio)); |
278 | __raw_writel(bank->int_enb[p], GPIO_INT_ENB(gpio)); | 280 | tegra_gpio_writel(bank->int_enb[p], GPIO_INT_ENB(gpio)); |
279 | } | 281 | } |
280 | } | 282 | } |
281 | 283 | ||
@@ -294,11 +296,11 @@ void tegra_gpio_suspend(void) | |||
294 | 296 | ||
295 | for (p = 0; p < ARRAY_SIZE(bank->oe); p++) { | 297 | for (p = 0; p < ARRAY_SIZE(bank->oe); p++) { |
296 | unsigned int gpio = (b<<5) | (p<<3); | 298 | unsigned int gpio = (b<<5) | (p<<3); |
297 | bank->cnf[p] = __raw_readl(GPIO_CNF(gpio)); | 299 | bank->cnf[p] = tegra_gpio_readl(GPIO_CNF(gpio)); |
298 | bank->out[p] = __raw_readl(GPIO_OUT(gpio)); | 300 | bank->out[p] = tegra_gpio_readl(GPIO_OUT(gpio)); |
299 | bank->oe[p] = __raw_readl(GPIO_OE(gpio)); | 301 | bank->oe[p] = tegra_gpio_readl(GPIO_OE(gpio)); |
300 | bank->int_enb[p] = __raw_readl(GPIO_INT_ENB(gpio)); | 302 | bank->int_enb[p] = tegra_gpio_readl(GPIO_INT_ENB(gpio)); |
301 | bank->int_lvl[p] = __raw_readl(GPIO_INT_LVL(gpio)); | 303 | bank->int_lvl[p] = tegra_gpio_readl(GPIO_INT_LVL(gpio)); |
302 | } | 304 | } |
303 | } | 305 | } |
304 | local_irq_restore(flags); | 306 | local_irq_restore(flags); |
@@ -328,27 +330,54 @@ static struct irq_chip tegra_gpio_irq_chip = { | |||
328 | */ | 330 | */ |
329 | static struct lock_class_key gpio_lock_class; | 331 | static struct lock_class_key gpio_lock_class; |
330 | 332 | ||
331 | static int __init tegra_gpio_init(void) | 333 | static int __devinit tegra_gpio_probe(struct platform_device *pdev) |
332 | { | 334 | { |
335 | struct resource *res; | ||
333 | struct tegra_gpio_bank *bank; | 336 | struct tegra_gpio_bank *bank; |
334 | int i; | 337 | int i; |
335 | int j; | 338 | int j; |
336 | 339 | ||
340 | for (i = 0; i < ARRAY_SIZE(tegra_gpio_banks); i++) { | ||
341 | res = platform_get_resource(pdev, IORESOURCE_IRQ, i); | ||
342 | if (!res) { | ||
343 | dev_err(&pdev->dev, "Missing IRQ resource\n"); | ||
344 | return -ENODEV; | ||
345 | } | ||
346 | |||
347 | bank = &tegra_gpio_banks[i]; | ||
348 | bank->bank = i; | ||
349 | bank->irq = res->start; | ||
350 | } | ||
351 | |||
352 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
353 | if (!res) { | ||
354 | dev_err(&pdev->dev, "Missing MEM resource\n"); | ||
355 | return -ENODEV; | ||
356 | } | ||
357 | |||
358 | if (!devm_request_mem_region(&pdev->dev, res->start, | ||
359 | resource_size(res), | ||
360 | dev_name(&pdev->dev))) { | ||
361 | dev_err(&pdev->dev, "Couldn't request MEM resource\n"); | ||
362 | return -ENODEV; | ||
363 | } | ||
364 | |||
365 | regs = devm_ioremap(&pdev->dev, res->start, resource_size(res)); | ||
366 | if (!regs) { | ||
367 | dev_err(&pdev->dev, "Couldn't ioremap regs\n"); | ||
368 | return -ENODEV; | ||
369 | } | ||
370 | |||
337 | for (i = 0; i < 7; i++) { | 371 | for (i = 0; i < 7; i++) { |
338 | for (j = 0; j < 4; j++) { | 372 | for (j = 0; j < 4; j++) { |
339 | int gpio = tegra_gpio_compose(i, j, 0); | 373 | int gpio = tegra_gpio_compose(i, j, 0); |
340 | __raw_writel(0x00, GPIO_INT_ENB(gpio)); | 374 | tegra_gpio_writel(0x00, GPIO_INT_ENB(gpio)); |
341 | } | 375 | } |
342 | } | 376 | } |
343 | 377 | ||
344 | #ifdef CONFIG_OF_GPIO | 378 | #ifdef CONFIG_OF_GPIO |
345 | /* | 379 | tegra_gpio_chip.of_node = pdev->dev.of_node; |
346 | * This isn't ideal, but it gets things hooked up until this | 380 | #endif |
347 | * driver is converted into a platform_device | ||
348 | */ | ||
349 | tegra_gpio_chip.of_node = of_find_compatible_node(NULL, NULL, | ||
350 | "nvidia,tegra20-gpio"); | ||
351 | #endif /* CONFIG_OF_GPIO */ | ||
352 | 381 | ||
353 | gpiochip_add(&tegra_gpio_chip); | 382 | gpiochip_add(&tegra_gpio_chip); |
354 | 383 | ||
@@ -375,6 +404,24 @@ static int __init tegra_gpio_init(void) | |||
375 | return 0; | 404 | return 0; |
376 | } | 405 | } |
377 | 406 | ||
407 | static struct of_device_id tegra_gpio_of_match[] __devinitdata = { | ||
408 | { .compatible = "nvidia,tegra20-gpio", }, | ||
409 | { }, | ||
410 | }; | ||
411 | |||
412 | static struct platform_driver tegra_gpio_driver = { | ||
413 | .driver = { | ||
414 | .name = "tegra-gpio", | ||
415 | .owner = THIS_MODULE, | ||
416 | .of_match_table = tegra_gpio_of_match, | ||
417 | }, | ||
418 | .probe = tegra_gpio_probe, | ||
419 | }; | ||
420 | |||
421 | static int __init tegra_gpio_init(void) | ||
422 | { | ||
423 | return platform_driver_register(&tegra_gpio_driver); | ||
424 | } | ||
378 | postcore_initcall(tegra_gpio_init); | 425 | postcore_initcall(tegra_gpio_init); |
379 | 426 | ||
380 | void __init tegra_gpio_config(struct tegra_gpio_table *table, int num) | 427 | void __init tegra_gpio_config(struct tegra_gpio_table *table, int num) |
@@ -407,13 +454,13 @@ static int dbg_gpio_show(struct seq_file *s, void *unused) | |||
407 | seq_printf(s, | 454 | seq_printf(s, |
408 | "%d:%d %02x %02x %02x %02x %02x %02x %06x\n", | 455 | "%d:%d %02x %02x %02x %02x %02x %02x %06x\n", |
409 | i, j, | 456 | i, j, |
410 | __raw_readl(GPIO_CNF(gpio)), | 457 | tegra_gpio_readl(GPIO_CNF(gpio)), |
411 | __raw_readl(GPIO_OE(gpio)), | 458 | tegra_gpio_readl(GPIO_OE(gpio)), |
412 | __raw_readl(GPIO_OUT(gpio)), | 459 | tegra_gpio_readl(GPIO_OUT(gpio)), |
413 | __raw_readl(GPIO_IN(gpio)), | 460 | tegra_gpio_readl(GPIO_IN(gpio)), |
414 | __raw_readl(GPIO_INT_STA(gpio)), | 461 | tegra_gpio_readl(GPIO_INT_STA(gpio)), |
415 | __raw_readl(GPIO_INT_ENB(gpio)), | 462 | tegra_gpio_readl(GPIO_INT_ENB(gpio)), |
416 | __raw_readl(GPIO_INT_LVL(gpio))); | 463 | tegra_gpio_readl(GPIO_INT_LVL(gpio))); |
417 | } | 464 | } |
418 | } | 465 | } |
419 | return 0; | 466 | return 0; |