aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArnd Bergmann <arnd@arndb.de>2011-10-20 12:15:30 -0400
committerArnd Bergmann <arnd@arndb.de>2011-10-20 12:15:30 -0400
commit107532920226a37e595697959b2a6a823cfa2497 (patch)
tree7d35c84ed324e6cabeed29282f1fc97994fd204b
parent29ea35969b92a4be122a58c4aceea8c5e2c388d9 (diff)
parentecb7b0e33e048e63d1169e6fee277430c70ddf0b (diff)
Merge branch 'tegra/devel' into next/devel
-rw-r--r--Documentation/devicetree/bindings/pinmux/pinmux_nvidia.txt5
-rw-r--r--arch/arm/boot/dts/tegra-ventana.dts32
-rw-r--r--arch/arm/boot/dts/tegra20.dtsi8
-rw-r--r--arch/arm/configs/tegra_defconfig39
-rw-r--r--arch/arm/mach-tegra/Kconfig6
-rw-r--r--arch/arm/mach-tegra/Makefile1
-rw-r--r--arch/arm/mach-tegra/Makefile.boot1
-rw-r--r--arch/arm/mach-tegra/board-dt.c26
-rw-r--r--arch/arm/mach-tegra/board-harmony-pinmux.c8
-rw-r--r--arch/arm/mach-tegra/board-harmony-power.c13
-rw-r--r--arch/arm/mach-tegra/board-paz00-pinmux.c8
-rw-r--r--arch/arm/mach-tegra/board-seaboard-pinmux.c69
-rw-r--r--arch/arm/mach-tegra/board-trimslice-pinmux.c7
-rw-r--r--arch/arm/mach-tegra/devices.c84
-rw-r--r--arch/arm/mach-tegra/devices.h2
-rw-r--r--arch/arm/mach-tegra/include/mach/pinmux.h4
-rw-r--r--arch/arm/mach-tegra/pinmux-t2-tables.c76
-rw-r--r--arch/arm/mach-tegra/pinmux.c163
-rw-r--r--drivers/gpio/gpio-tegra.c143
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 @@
1NVIDIA Tegra 2 pinmux controller
2
3Required 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
25CONFIG_MACH_PAZ00=y 25CONFIG_MACH_PAZ00=y
26CONFIG_MACH_TRIMSLICE=y 26CONFIG_MACH_TRIMSLICE=y
27CONFIG_MACH_WARIO=y 27CONFIG_MACH_WARIO=y
28CONFIG_MACH_VENTANA=y
28CONFIG_TEGRA_DEBUG_UARTD=y 29CONFIG_TEGRA_DEBUG_UARTD=y
29CONFIG_ARM_ERRATA_742230=y 30CONFIG_ARM_ERRATA_742230=y
30CONFIG_NO_HZ=y 31CONFIG_NO_HZ=y
@@ -38,7 +39,6 @@ CONFIG_HIGHMEM=y
38CONFIG_ZBOOT_ROM_TEXT=0x0 39CONFIG_ZBOOT_ROM_TEXT=0x0
39CONFIG_ZBOOT_ROM_BSS=0x0 40CONFIG_ZBOOT_ROM_BSS=0x0
40CONFIG_VFP=y 41CONFIG_VFP=y
41CONFIG_PM=y
42CONFIG_NET=y 42CONFIG_NET=y
43CONFIG_PACKET=y 43CONFIG_PACKET=y
44CONFIG_UNIX=y 44CONFIG_UNIX=y
@@ -65,6 +65,7 @@ CONFIG_IPV6_TUNNEL=y
65CONFIG_IPV6_MULTIPLE_TABLES=y 65CONFIG_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
68CONFIG_PROC_DEVICETREE=y
68CONFIG_BLK_DEV_LOOP=y 69CONFIG_BLK_DEV_LOOP=y
69CONFIG_MISC_DEVICES=y 70CONFIG_MISC_DEVICES=y
70CONFIG_AD525X_DPOT=y 71CONFIG_AD525X_DPOT=y
@@ -72,34 +73,61 @@ CONFIG_AD525X_DPOT_I2C=y
72CONFIG_ICS932S401=y 73CONFIG_ICS932S401=y
73CONFIG_APDS9802ALS=y 74CONFIG_APDS9802ALS=y
74CONFIG_ISL29003=y 75CONFIG_ISL29003=y
76CONFIG_SCSI=y
77CONFIG_BLK_DEV_SD=y
78# CONFIG_SCSI_LOWLEVEL is not set
75CONFIG_NETDEVICES=y 79CONFIG_NETDEVICES=y
76CONFIG_DUMMY=y 80CONFIG_DUMMY=y
81CONFIG_NET_ETHERNET=y
77CONFIG_R8169=y 82CONFIG_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
85CONFIG_USB_PEGASUS=y
86CONFIG_USB_USBNET=y
87CONFIG_USB_NET_SMSC75XX=y
88CONFIG_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
84CONFIG_SERIAL_8250=y 94CONFIG_SERIAL_8250=y
85CONFIG_SERIAL_8250_CONSOLE=y 95CONFIG_SERIAL_8250_CONSOLE=y
86# CONFIG_LEGACY_PTYS is not set 96CONFIG_SERIAL_OF_PLATFORM=y
87# CONFIG_HW_RANDOM is not set 97# CONFIG_HW_RANDOM is not set
88CONFIG_I2C=y 98CONFIG_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
91CONFIG_I2C_TEGRA=y 101CONFIG_I2C_TEGRA=y
102CONFIG_SPI=y
103CONFIG_SPI_TEGRA=y
92CONFIG_SENSORS_LM90=y 104CONFIG_SENSORS_LM90=y
93CONFIG_MFD_TPS6586X=y 105CONFIG_MFD_TPS6586X=y
94CONFIG_REGULATOR=y 106CONFIG_REGULATOR=y
95CONFIG_REGULATOR_TPS6586X=y 107CONFIG_REGULATOR_TPS6586X=y
96# CONFIG_USB_SUPPORT is not set 108CONFIG_SOUND=y
109CONFIG_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
116CONFIG_SND_SOC=y
117CONFIG_SND_SOC_TEGRA=y
118CONFIG_SND_SOC_TEGRA_WM8903=y
119CONFIG_SND_SOC_TEGRA_TRIMSLICE=y
120CONFIG_USB=y
121CONFIG_USB_EHCI_HCD=y
122CONFIG_USB_EHCI_TEGRA=y
123CONFIG_USB_STORAGE=y
97CONFIG_MMC=y 124CONFIG_MMC=y
98CONFIG_MMC_SDHCI=y 125CONFIG_MMC_SDHCI=y
99CONFIG_MMC_SDHCI_PLTFM=y 126CONFIG_MMC_SDHCI_PLTFM=y
100CONFIG_MMC_SDHCI_TEGRA=y 127CONFIG_MMC_SDHCI_TEGRA=y
128CONFIG_RTC_CLASS=y
129CONFIG_RTC_DRV_TEGRA=y
101CONFIG_STAGING=y 130CONFIG_STAGING=y
102# CONFIG_STAGING_EXCLUDE_BUILD is not set
103CONFIG_IIO=y 131CONFIG_IIO=y
104CONFIG_SENSORS_ISL29018=y 132CONFIG_SENSORS_ISL29018=y
105CONFIG_SENSORS_AK8975=y 133CONFIG_SENSORS_AK8975=y
@@ -123,18 +151,15 @@ CONFIG_NLS_ISO8859_1=y
123CONFIG_PRINTK_TIME=y 151CONFIG_PRINTK_TIME=y
124CONFIG_MAGIC_SYSRQ=y 152CONFIG_MAGIC_SYSRQ=y
125CONFIG_DEBUG_FS=y 153CONFIG_DEBUG_FS=y
126CONFIG_DEBUG_KERNEL=y
127CONFIG_DETECT_HUNG_TASK=y 154CONFIG_DETECT_HUNG_TASK=y
128CONFIG_SCHEDSTATS=y 155CONFIG_SCHEDSTATS=y
129CONFIG_TIMER_STATS=y 156CONFIG_TIMER_STATS=y
130CONFIG_DEBUG_SLAB=y 157CONFIG_DEBUG_SLAB=y
131# CONFIG_DEBUG_PREEMPT is not set 158# CONFIG_DEBUG_PREEMPT is not set
132CONFIG_DEBUG_MUTEXES=y 159CONFIG_DEBUG_MUTEXES=y
133CONFIG_DEBUG_SPINLOCK_SLEEP=y
134CONFIG_DEBUG_INFO=y 160CONFIG_DEBUG_INFO=y
135CONFIG_DEBUG_VM=y 161CONFIG_DEBUG_VM=y
136CONFIG_DEBUG_SG=y 162CONFIG_DEBUG_SG=y
137# CONFIG_RCU_CPU_STALL_DETECTOR is not set
138CONFIG_DEBUG_LL=y 163CONFIG_DEBUG_LL=y
139CONFIG_EARLY_PRINTK=y 164CONFIG_EARLY_PRINTK=y
140CONFIG_CRYPTO_ECB=y 165CONFIG_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
72config MACH_VENTANA
73 bool "Ventana board"
74 select MACH_TEGRA_DT
75 help
76 Support for the nVidia Ventana development platform
77
72choice 78choice
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
32obj-${CONFIG_MACH_TEGRA_DT} += board-dt.o 32obj-${CONFIG_MACH_TEGRA_DT} += board-dt.o
33obj-${CONFIG_MACH_TEGRA_DT} += board-harmony-pinmux.o 33obj-${CONFIG_MACH_TEGRA_DT} += board-harmony-pinmux.o
34obj-${CONFIG_MACH_TEGRA_DT} += board-seaboard-pinmux.o
34 35
35obj-${CONFIG_MACH_TRIMSLICE} += board-trimslice.o 36obj-${CONFIG_MACH_TRIMSLICE} += board-trimslice.o
36obj-${CONFIG_MACH_TRIMSLICE} += board-trimslice-pinmux.o 37obj-${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
5dtb-$(CONFIG_MACH_HARMONY) += tegra-harmony.dtb 5dtb-$(CONFIG_MACH_HARMONY) += tegra-harmony.dtb
6dtb-$(CONFIG_MACH_SEABOARD) += tegra-seaboard.dtb 6dtb-$(CONFIG_MACH_SEABOARD) += tegra-seaboard.dtb
7dtb-$(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
48void harmony_pinmux_init(void); 48void harmony_pinmux_init(void);
49void seaboard_pinmux_init(void); 49void seaboard_pinmux_init(void);
50 50void ventana_pinmux_init(void);
51 51
52struct of_dev_auxdata tegra20_auxdata_lookup[] __initdata = { 52struct 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
83static 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
83static void __init tegra_dt_init(void) 92static 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)
106static const char * tegra_dt_board_compat[] = { 121static 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
24static struct tegra_pingroup_config harmony_pinmux[] = { 25static 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
144static struct platform_device *pinmux_devices[] = {
145 &tegra_gpio_device,
146 &tegra_pinmux_device,
147};
148
143static struct tegra_gpio_table gpio_table[] = { 149static 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
156void harmony_pinmux_init(void) 162void 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
114int __init harmony_regulator_init(void) 115int __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
24static struct tegra_pingroup_config paz00_pinmux[] = { 25static 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
144static struct platform_device *pinmux_devices[] = {
145 &tegra_gpio_device,
146 &tegra_pinmux_device,
147};
148
143static struct tegra_gpio_table gpio_table[] = { 149static 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
150void paz00_pinmux_init(void) 156void 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
162static __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
183static struct platform_device *pinmux_devices[] = {
184 &tegra_gpio_device,
185 &tegra_pinmux_device,
186};
161 187
162 188static struct tegra_gpio_table common_gpio_table[] = {
163static 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
172void __init seaboard_pinmux_init(void) 197static 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
217void __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
229void __init seaboard_pinmux_init(void)
230{
231 seaboard_common_pinmux_init();
180} 232}
233
234void __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
26static __initdata struct tegra_pingroup_config trimslice_pinmux[] = { 27static __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
146static struct platform_device *pinmux_devices[] = {
147 &tegra_gpio_device,
148 &tegra_pinmux_device,
149};
150
145static struct tegra_gpio_table gpio_table[] = { 151static 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
153void __init trimslice_pinmux_init(void) 159void __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
34static 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
77struct 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
84static 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
111struct 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
34static struct resource i2c_resource1[] = { 118static 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
24extern struct platform_device tegra_gpio_device;
25extern struct platform_device tegra_pinmux_device;
24extern struct platform_device tegra_sdhci_device1; 26extern struct platform_device tegra_sdhci_device1;
25extern struct platform_device tegra_sdhci_device2; 27extern struct platform_device tegra_sdhci_device2;
26extern struct platform_device tegra_sdhci_device3; 28extern 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
200struct tegra_drive_pingroup_desc { 200struct 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
40const struct tegra_drive_pingroup_desc tegra_soc_drive_pingroups[TEGRA_MAX_DRIVE_PINGROUP] = { 46const 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
229static u32 pinmux_reg[TRISTATE_REG_NUM + PIN_MUX_CTL_REG_NUM +
230 PULLUPDOWN_REG_NUM +
231 ARRAY_SIZE(tegra_soc_drive_pingroups)];
232
233static inline unsigned long pg_readl(unsigned long offset)
234{
235 return readl(IO_TO_VIRT(TEGRA_APB_MISC_BASE + offset));
236}
237
238static inline void pg_writel(unsigned long value, unsigned long offset)
239{
240 writel(value, IO_TO_VIRT(TEGRA_APB_MISC_BASE + offset));
241}
242
243void 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
261void 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
173static int nbanks;
174static void __iomem **regs;
172 175
173static inline unsigned long pg_readl(unsigned long offset) 176static 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
178static inline void pg_writel(unsigned long value, unsigned long offset) 181static 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
183static int tegra_pinmux_set_func(const struct tegra_pingroup_config *config) 186static 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
671static 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
744static struct of_device_id tegra_pinmux_of_match[] __devinitdata = {
745 { .compatible = "nvidia,tegra20-pinmux", },
746 { },
747};
748
749static 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
758static int __init tegra_pinmux_init(void)
759{
760 return platform_driver_register(&tegra_pinmux_driver);
761}
762postcore_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
78static struct tegra_gpio_bank tegra_gpio_banks[] = { 77static void __iomem *regs;
79 {.bank = 0, .irq = INT_GPIO1}, 78static struct tegra_gpio_bank tegra_gpio_banks[7];
80 {.bank = 1, .irq = INT_GPIO2}, 79
81 {.bank = 2, .irq = INT_GPIO3}, 80static 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}; 85static inline u32 tegra_gpio_readl(u32 reg)
86{
87 return __raw_readl(regs + reg);
88}
87 89
88static int tegra_gpio_compose(int bank, int port, int bit) 90static 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
103void tegra_gpio_enable(int gpio) 105void tegra_gpio_enable(int gpio)
@@ -117,7 +119,7 @@ static void tegra_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
117 119
118static int tegra_gpio_get(struct gpio_chip *chip, unsigned offset) 120static 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
123static int tegra_gpio_direction_input(struct gpio_chip *chip, unsigned offset) 125static 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
156static void tegra_gpio_irq_mask(struct irq_data *d) 158static 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 */
329static struct lock_class_key gpio_lock_class; 331static struct lock_class_key gpio_lock_class;
330 332
331static int __init tegra_gpio_init(void) 333static 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
407static struct of_device_id tegra_gpio_of_match[] __devinitdata = {
408 { .compatible = "nvidia,tegra20-gpio", },
409 { },
410};
411
412static 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
421static int __init tegra_gpio_init(void)
422{
423 return platform_driver_register(&tegra_gpio_driver);
424}
378postcore_initcall(tegra_gpio_init); 425postcore_initcall(tegra_gpio_init);
379 426
380void __init tegra_gpio_config(struct tegra_gpio_table *table, int num) 427void __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;