diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-07-22 17:50:57 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-07-22 17:50:57 -0400 |
commit | c7c8518498e82591d7784452f5674c3aeb4d079c (patch) | |
tree | 790ff7e6b6741daf32ec686b9a302b957b07c0f4 | |
parent | ece236ce2fad9c27a6fd2530f899289025194bce (diff) | |
parent | 591567a5ea25852f20b7ef2953f6f72020121199 (diff) |
Merge branch 'gpio/next' of git://git.secretlab.ca/git/linux-2.6
* 'gpio/next' of git://git.secretlab.ca/git/linux-2.6: (61 commits)
gpio/mxc/mxs: fix build error introduced by the irq_gc_ack() renaming
mcp23s08: add i2c support
mcp23s08: isolate spi specific parts
mcp23s08: get rid of setup/teardown callbacks
gpio/tegra: dt: add binding for gpio polarity
mcp23s08: remove unused work queue
gpio/da9052: remove a redundant assignment for gpio->da9052
gpio/mxc: add device tree probe support
ARM: mxc: use ARCH_NR_GPIOS to define gpio number
gpio/mxc: get rid of the uses of cpu_is_mx()
gpio/mxc: add missing initialization of basic_mmio_gpio shadow variables
gpio: Move mpc5200 gpio driver to drivers/gpio
GPIO: DA9052 GPIO module v3
gpio/tegra: Use engineering names in DT compatible property
of/gpio: Add new method for getting gpios under different property names
gpio/dt: Refine GPIO device tree binding
gpio/ml-ioh: fix off-by-one for displaying variable i in dev_err
gpio/pca953x: Deprecate meaningless device-tree bindings
gpio/pca953x: Remove dynamic platform data pointer
gpio/pca953x: Fix IRQ support.
...
137 files changed, 2291 insertions, 1917 deletions
diff --git a/Documentation/devicetree/bindings/gpio/fsl-imx-gpio.txt b/Documentation/devicetree/bindings/gpio/fsl-imx-gpio.txt new file mode 100644 index 000000000000..4363ae4b3c14 --- /dev/null +++ b/Documentation/devicetree/bindings/gpio/fsl-imx-gpio.txt | |||
@@ -0,0 +1,22 @@ | |||
1 | * Freescale i.MX/MXC GPIO controller | ||
2 | |||
3 | Required properties: | ||
4 | - compatible : Should be "fsl,<soc>-gpio" | ||
5 | - reg : Address and length of the register set for the device | ||
6 | - interrupts : Should be the port interrupt shared by all 32 pins, if | ||
7 | one number. If two numbers, the first one is the interrupt shared | ||
8 | by low 16 pins and the second one is for high 16 pins. | ||
9 | - gpio-controller : Marks the device node as a gpio controller. | ||
10 | - #gpio-cells : Should be two. The first cell is the pin number and | ||
11 | the second cell is used to specify optional parameters (currently | ||
12 | unused). | ||
13 | |||
14 | Example: | ||
15 | |||
16 | gpio0: gpio@73f84000 { | ||
17 | compatible = "fsl,imx51-gpio", "fsl,imx31-gpio"; | ||
18 | reg = <0x73f84000 0x4000>; | ||
19 | interrupts = <50 51>; | ||
20 | gpio-controller; | ||
21 | #gpio-cells = <2>; | ||
22 | }; | ||
diff --git a/Documentation/devicetree/bindings/gpio/gpio.txt b/Documentation/devicetree/bindings/gpio/gpio.txt index edaa84d288a1..4e16ba4feab0 100644 --- a/Documentation/devicetree/bindings/gpio/gpio.txt +++ b/Documentation/devicetree/bindings/gpio/gpio.txt | |||
@@ -4,17 +4,45 @@ Specifying GPIO information for devices | |||
4 | 1) gpios property | 4 | 1) gpios property |
5 | ----------------- | 5 | ----------------- |
6 | 6 | ||
7 | Nodes that makes use of GPIOs should define them using `gpios' property, | 7 | Nodes that makes use of GPIOs should specify them using one or more |
8 | format of which is: <&gpio-controller1-phandle gpio1-specifier | 8 | properties, each containing a 'gpio-list': |
9 | &gpio-controller2-phandle gpio2-specifier | ||
10 | 0 /* holes are permitted, means no GPIO 3 */ | ||
11 | &gpio-controller4-phandle gpio4-specifier | ||
12 | ...>; | ||
13 | 9 | ||
14 | Note that gpio-specifier length is controller dependent. | 10 | gpio-list ::= <single-gpio> [gpio-list] |
11 | single-gpio ::= <gpio-phandle> <gpio-specifier> | ||
12 | gpio-phandle : phandle to gpio controller node | ||
13 | gpio-specifier : Array of #gpio-cells specifying specific gpio | ||
14 | (controller specific) | ||
15 | |||
16 | GPIO properties should be named "[<name>-]gpios". Exact | ||
17 | meaning of each gpios property must be documented in the device tree | ||
18 | binding for each device. | ||
19 | |||
20 | For example, the following could be used to describe gpios pins to use | ||
21 | as chip select lines; with chip selects 0, 1 and 3 populated, and chip | ||
22 | select 2 left empty: | ||
23 | |||
24 | gpio1: gpio1 { | ||
25 | gpio-controller | ||
26 | #gpio-cells = <2>; | ||
27 | }; | ||
28 | gpio2: gpio2 { | ||
29 | gpio-controller | ||
30 | #gpio-cells = <1>; | ||
31 | }; | ||
32 | [...] | ||
33 | chipsel-gpios = <&gpio1 12 0>, | ||
34 | <&gpio1 13 0>, | ||
35 | <0>, /* holes are permitted, means no GPIO 2 */ | ||
36 | <&gpio2 2>; | ||
37 | |||
38 | Note that gpio-specifier length is controller dependent. In the | ||
39 | above example, &gpio1 uses 2 cells to specify a gpio, while &gpio2 | ||
40 | only uses one. | ||
15 | 41 | ||
16 | gpio-specifier may encode: bank, pin position inside the bank, | 42 | gpio-specifier may encode: bank, pin position inside the bank, |
17 | whether pin is open-drain and whether pin is logically inverted. | 43 | whether pin is open-drain and whether pin is logically inverted. |
44 | Exact meaning of each specifier cell is controller specific, and must | ||
45 | be documented in the device tree binding for the device. | ||
18 | 46 | ||
19 | Example of the node using GPIOs: | 47 | Example of the node using GPIOs: |
20 | 48 | ||
@@ -28,8 +56,8 @@ and empty GPIO flags as accepted by the "qe_pio_e" gpio-controller. | |||
28 | 2) gpio-controller nodes | 56 | 2) gpio-controller nodes |
29 | ------------------------ | 57 | ------------------------ |
30 | 58 | ||
31 | Every GPIO controller node must have #gpio-cells property defined, | 59 | Every GPIO controller node must both an empty "gpio-controller" |
32 | this information will be used to translate gpio-specifiers. | 60 | property, and have #gpio-cells contain the size of the gpio-specifier. |
33 | 61 | ||
34 | Example of two SOC GPIO banks defined as gpio-controller nodes: | 62 | Example of two SOC GPIO banks defined as gpio-controller nodes: |
35 | 63 | ||
diff --git a/Documentation/devicetree/bindings/gpio/gpio_nvidia.txt b/Documentation/devicetree/bindings/gpio/gpio_nvidia.txt new file mode 100644 index 000000000000..eb4b530d64e1 --- /dev/null +++ b/Documentation/devicetree/bindings/gpio/gpio_nvidia.txt | |||
@@ -0,0 +1,8 @@ | |||
1 | NVIDIA Tegra 2 GPIO controller | ||
2 | |||
3 | Required properties: | ||
4 | - compatible : "nvidia,tegra20-gpio" | ||
5 | - #gpio-cells : Should be two. The first cell is the pin number and the | ||
6 | second cell is used to specify optional parameters: | ||
7 | - bit 0 specifies polarity (0 for normal, 1 for inverted) | ||
8 | - gpio-controller : Marks the device node as a GPIO controller. | ||
diff --git a/arch/arm/mach-ep93xx/Makefile b/arch/arm/mach-ep93xx/Makefile index 33ee2c863d18..6b7c41d155df 100644 --- a/arch/arm/mach-ep93xx/Makefile +++ b/arch/arm/mach-ep93xx/Makefile | |||
@@ -1,7 +1,7 @@ | |||
1 | # | 1 | # |
2 | # Makefile for the linux kernel. | 2 | # Makefile for the linux kernel. |
3 | # | 3 | # |
4 | obj-y := core.o clock.o dma-m2p.o gpio.o | 4 | obj-y := core.o clock.o dma-m2p.o |
5 | obj-m := | 5 | obj-m := |
6 | obj-n := | 6 | obj-n := |
7 | obj- := | 7 | obj- := |
diff --git a/arch/arm/mach-ep93xx/core.c b/arch/arm/mach-ep93xx/core.c index 6659a0d137a3..c488e4bd61e7 100644 --- a/arch/arm/mach-ep93xx/core.c +++ b/arch/arm/mach-ep93xx/core.c | |||
@@ -174,14 +174,10 @@ struct sys_timer ep93xx_timer = { | |||
174 | /************************************************************************* | 174 | /************************************************************************* |
175 | * EP93xx IRQ handling | 175 | * EP93xx IRQ handling |
176 | *************************************************************************/ | 176 | *************************************************************************/ |
177 | extern void ep93xx_gpio_init_irq(void); | ||
178 | |||
179 | void __init ep93xx_init_irq(void) | 177 | void __init ep93xx_init_irq(void) |
180 | { | 178 | { |
181 | vic_init(EP93XX_VIC1_BASE, 0, EP93XX_VIC1_VALID_IRQ_MASK, 0); | 179 | vic_init(EP93XX_VIC1_BASE, 0, EP93XX_VIC1_VALID_IRQ_MASK, 0); |
182 | vic_init(EP93XX_VIC2_BASE, 32, EP93XX_VIC2_VALID_IRQ_MASK, 0); | 180 | vic_init(EP93XX_VIC2_BASE, 32, EP93XX_VIC2_VALID_IRQ_MASK, 0); |
183 | |||
184 | ep93xx_gpio_init_irq(); | ||
185 | } | 181 | } |
186 | 182 | ||
187 | 183 | ||
@@ -241,6 +237,24 @@ unsigned int ep93xx_chip_revision(void) | |||
241 | } | 237 | } |
242 | 238 | ||
243 | /************************************************************************* | 239 | /************************************************************************* |
240 | * EP93xx GPIO | ||
241 | *************************************************************************/ | ||
242 | static struct resource ep93xx_gpio_resource[] = { | ||
243 | { | ||
244 | .start = EP93XX_GPIO_PHYS_BASE, | ||
245 | .end = EP93XX_GPIO_PHYS_BASE + 0xcc - 1, | ||
246 | .flags = IORESOURCE_MEM, | ||
247 | }, | ||
248 | }; | ||
249 | |||
250 | static struct platform_device ep93xx_gpio_device = { | ||
251 | .name = "gpio-ep93xx", | ||
252 | .id = -1, | ||
253 | .num_resources = ARRAY_SIZE(ep93xx_gpio_resource), | ||
254 | .resource = ep93xx_gpio_resource, | ||
255 | }; | ||
256 | |||
257 | /************************************************************************* | ||
244 | * EP93xx peripheral handling | 258 | * EP93xx peripheral handling |
245 | *************************************************************************/ | 259 | *************************************************************************/ |
246 | #define EP93XX_UART_MCR_OFFSET (0x0100) | 260 | #define EP93XX_UART_MCR_OFFSET (0x0100) |
@@ -870,14 +884,13 @@ void __init ep93xx_register_ac97(void) | |||
870 | platform_device_register(&ep93xx_pcm_device); | 884 | platform_device_register(&ep93xx_pcm_device); |
871 | } | 885 | } |
872 | 886 | ||
873 | extern void ep93xx_gpio_init(void); | ||
874 | |||
875 | void __init ep93xx_init_devices(void) | 887 | void __init ep93xx_init_devices(void) |
876 | { | 888 | { |
877 | /* Disallow access to MaverickCrunch initially */ | 889 | /* Disallow access to MaverickCrunch initially */ |
878 | ep93xx_devcfg_clear_bits(EP93XX_SYSCON_DEVCFG_CPENA); | 890 | ep93xx_devcfg_clear_bits(EP93XX_SYSCON_DEVCFG_CPENA); |
879 | 891 | ||
880 | ep93xx_gpio_init(); | 892 | /* Get the GPIO working early, other devices need it */ |
893 | platform_device_register(&ep93xx_gpio_device); | ||
881 | 894 | ||
882 | amba_device_register(&uart1_device, &iomem_resource); | 895 | amba_device_register(&uart1_device, &iomem_resource); |
883 | amba_device_register(&uart2_device, &iomem_resource); | 896 | amba_device_register(&uart2_device, &iomem_resource); |
diff --git a/arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h b/arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h index 9ac4d1055097..c4a7b84ef06d 100644 --- a/arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h +++ b/arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h | |||
@@ -98,6 +98,7 @@ | |||
98 | 98 | ||
99 | #define EP93XX_SECURITY_BASE EP93XX_APB_IOMEM(0x00030000) | 99 | #define EP93XX_SECURITY_BASE EP93XX_APB_IOMEM(0x00030000) |
100 | 100 | ||
101 | #define EP93XX_GPIO_PHYS_BASE EP93XX_APB_PHYS(0x00040000) | ||
101 | #define EP93XX_GPIO_BASE EP93XX_APB_IOMEM(0x00040000) | 102 | #define EP93XX_GPIO_BASE EP93XX_APB_IOMEM(0x00040000) |
102 | #define EP93XX_GPIO_REG(x) (EP93XX_GPIO_BASE + (x)) | 103 | #define EP93XX_GPIO_REG(x) (EP93XX_GPIO_BASE + (x)) |
103 | #define EP93XX_GPIO_F_INT_STATUS EP93XX_GPIO_REG(0x5c) | 104 | #define EP93XX_GPIO_F_INT_STATUS EP93XX_GPIO_REG(0x5c) |
diff --git a/arch/arm/mach-imx/mach-apf9328.c b/arch/arm/mach-imx/mach-apf9328.c index 15e45c84e371..59d2a3b137d9 100644 --- a/arch/arm/mach-imx/mach-apf9328.c +++ b/arch/arm/mach-imx/mach-apf9328.c | |||
@@ -115,6 +115,8 @@ static struct platform_device *devices[] __initdata = { | |||
115 | 115 | ||
116 | static void __init apf9328_init(void) | 116 | static void __init apf9328_init(void) |
117 | { | 117 | { |
118 | imx1_soc_init(); | ||
119 | |||
118 | mxc_gpio_setup_multiple_pins(apf9328_pins, | 120 | mxc_gpio_setup_multiple_pins(apf9328_pins, |
119 | ARRAY_SIZE(apf9328_pins), | 121 | ARRAY_SIZE(apf9328_pins), |
120 | "APF9328"); | 122 | "APF9328"); |
diff --git a/arch/arm/mach-imx/mach-armadillo5x0.c b/arch/arm/mach-imx/mach-armadillo5x0.c index ffb40ff619b1..ede2710f8b76 100644 --- a/arch/arm/mach-imx/mach-armadillo5x0.c +++ b/arch/arm/mach-imx/mach-armadillo5x0.c | |||
@@ -490,6 +490,8 @@ static struct platform_device *devices[] __initdata = { | |||
490 | */ | 490 | */ |
491 | static void __init armadillo5x0_init(void) | 491 | static void __init armadillo5x0_init(void) |
492 | { | 492 | { |
493 | imx31_soc_init(); | ||
494 | |||
493 | mxc_iomux_setup_multiple_pins(armadillo5x0_pins, | 495 | mxc_iomux_setup_multiple_pins(armadillo5x0_pins, |
494 | ARRAY_SIZE(armadillo5x0_pins), "armadillo5x0"); | 496 | ARRAY_SIZE(armadillo5x0_pins), "armadillo5x0"); |
495 | 497 | ||
diff --git a/arch/arm/mach-imx/mach-bug.c b/arch/arm/mach-imx/mach-bug.c index 42e4f078a19c..f49470553bdf 100644 --- a/arch/arm/mach-imx/mach-bug.c +++ b/arch/arm/mach-imx/mach-bug.c | |||
@@ -42,6 +42,8 @@ static const unsigned int bug_pins[] __initconst = { | |||
42 | 42 | ||
43 | static void __init bug_board_init(void) | 43 | static void __init bug_board_init(void) |
44 | { | 44 | { |
45 | imx31_soc_init(); | ||
46 | |||
45 | mxc_iomux_setup_multiple_pins(bug_pins, | 47 | mxc_iomux_setup_multiple_pins(bug_pins, |
46 | ARRAY_SIZE(bug_pins), "uart-4"); | 48 | ARRAY_SIZE(bug_pins), "uart-4"); |
47 | imx31_add_imx_uart4(&uart_pdata); | 49 | imx31_add_imx_uart4(&uart_pdata); |
diff --git a/arch/arm/mach-imx/mach-cpuimx27.c b/arch/arm/mach-imx/mach-cpuimx27.c index 46a2e41d43d2..87887ac5806b 100644 --- a/arch/arm/mach-imx/mach-cpuimx27.c +++ b/arch/arm/mach-imx/mach-cpuimx27.c | |||
@@ -250,6 +250,8 @@ __setup("otg_mode=", eukrea_cpuimx27_otg_mode); | |||
250 | 250 | ||
251 | static void __init eukrea_cpuimx27_init(void) | 251 | static void __init eukrea_cpuimx27_init(void) |
252 | { | 252 | { |
253 | imx27_soc_init(); | ||
254 | |||
253 | mxc_gpio_setup_multiple_pins(eukrea_cpuimx27_pins, | 255 | mxc_gpio_setup_multiple_pins(eukrea_cpuimx27_pins, |
254 | ARRAY_SIZE(eukrea_cpuimx27_pins), "CPUIMX27"); | 256 | ARRAY_SIZE(eukrea_cpuimx27_pins), "CPUIMX27"); |
255 | 257 | ||
diff --git a/arch/arm/mach-imx/mach-cpuimx35.c b/arch/arm/mach-imx/mach-cpuimx35.c index 3f8ef825fa6f..f39a478ba1a6 100644 --- a/arch/arm/mach-imx/mach-cpuimx35.c +++ b/arch/arm/mach-imx/mach-cpuimx35.c | |||
@@ -156,6 +156,8 @@ __setup("otg_mode=", eukrea_cpuimx35_otg_mode); | |||
156 | */ | 156 | */ |
157 | static void __init eukrea_cpuimx35_init(void) | 157 | static void __init eukrea_cpuimx35_init(void) |
158 | { | 158 | { |
159 | imx35_soc_init(); | ||
160 | |||
159 | mxc_iomux_v3_setup_multiple_pads(eukrea_cpuimx35_pads, | 161 | mxc_iomux_v3_setup_multiple_pads(eukrea_cpuimx35_pads, |
160 | ARRAY_SIZE(eukrea_cpuimx35_pads)); | 162 | ARRAY_SIZE(eukrea_cpuimx35_pads)); |
161 | 163 | ||
diff --git a/arch/arm/mach-imx/mach-eukrea_cpuimx25.c b/arch/arm/mach-imx/mach-eukrea_cpuimx25.c index 148cff2819b9..da36da52969d 100644 --- a/arch/arm/mach-imx/mach-eukrea_cpuimx25.c +++ b/arch/arm/mach-imx/mach-eukrea_cpuimx25.c | |||
@@ -125,6 +125,8 @@ __setup("otg_mode=", eukrea_cpuimx25_otg_mode); | |||
125 | 125 | ||
126 | static void __init eukrea_cpuimx25_init(void) | 126 | static void __init eukrea_cpuimx25_init(void) |
127 | { | 127 | { |
128 | imx25_soc_init(); | ||
129 | |||
128 | if (mxc_iomux_v3_setup_multiple_pads(eukrea_cpuimx25_pads, | 130 | if (mxc_iomux_v3_setup_multiple_pads(eukrea_cpuimx25_pads, |
129 | ARRAY_SIZE(eukrea_cpuimx25_pads))) | 131 | ARRAY_SIZE(eukrea_cpuimx25_pads))) |
130 | printk(KERN_ERR "error setting cpuimx25 pads !\n"); | 132 | printk(KERN_ERR "error setting cpuimx25 pads !\n"); |
diff --git a/arch/arm/mach-imx/mach-imx27_visstrim_m10.c b/arch/arm/mach-imx/mach-imx27_visstrim_m10.c index 7ae43b1ec517..c6269d60ddbc 100644 --- a/arch/arm/mach-imx/mach-imx27_visstrim_m10.c +++ b/arch/arm/mach-imx/mach-imx27_visstrim_m10.c | |||
@@ -231,6 +231,8 @@ static void __init visstrim_m10_board_init(void) | |||
231 | { | 231 | { |
232 | int ret; | 232 | int ret; |
233 | 233 | ||
234 | imx27_soc_init(); | ||
235 | |||
234 | ret = mxc_gpio_setup_multiple_pins(visstrim_m10_pins, | 236 | ret = mxc_gpio_setup_multiple_pins(visstrim_m10_pins, |
235 | ARRAY_SIZE(visstrim_m10_pins), "VISSTRIM_M10"); | 237 | ARRAY_SIZE(visstrim_m10_pins), "VISSTRIM_M10"); |
236 | if (ret) | 238 | if (ret) |
diff --git a/arch/arm/mach-imx/mach-imx27ipcam.c b/arch/arm/mach-imx/mach-imx27ipcam.c index 9be6cd6fbf8c..272f793e9247 100644 --- a/arch/arm/mach-imx/mach-imx27ipcam.c +++ b/arch/arm/mach-imx/mach-imx27ipcam.c | |||
@@ -50,6 +50,8 @@ static const int mx27ipcam_pins[] __initconst = { | |||
50 | 50 | ||
51 | static void __init mx27ipcam_init(void) | 51 | static void __init mx27ipcam_init(void) |
52 | { | 52 | { |
53 | imx27_soc_init(); | ||
54 | |||
53 | mxc_gpio_setup_multiple_pins(mx27ipcam_pins, ARRAY_SIZE(mx27ipcam_pins), | 55 | mxc_gpio_setup_multiple_pins(mx27ipcam_pins, ARRAY_SIZE(mx27ipcam_pins), |
54 | "mx27ipcam"); | 56 | "mx27ipcam"); |
55 | 57 | ||
diff --git a/arch/arm/mach-imx/mach-imx27lite.c b/arch/arm/mach-imx/mach-imx27lite.c index 841140516ede..d81a769fe895 100644 --- a/arch/arm/mach-imx/mach-imx27lite.c +++ b/arch/arm/mach-imx/mach-imx27lite.c | |||
@@ -59,6 +59,8 @@ static const struct imxuart_platform_data uart_pdata __initconst = { | |||
59 | 59 | ||
60 | static void __init mx27lite_init(void) | 60 | static void __init mx27lite_init(void) |
61 | { | 61 | { |
62 | imx27_soc_init(); | ||
63 | |||
62 | mxc_gpio_setup_multiple_pins(mx27lite_pins, ARRAY_SIZE(mx27lite_pins), | 64 | mxc_gpio_setup_multiple_pins(mx27lite_pins, ARRAY_SIZE(mx27lite_pins), |
63 | "imx27lite"); | 65 | "imx27lite"); |
64 | imx27_add_imx_uart0(&uart_pdata); | 66 | imx27_add_imx_uart0(&uart_pdata); |
diff --git a/arch/arm/mach-imx/mach-kzm_arm11_01.c b/arch/arm/mach-imx/mach-kzm_arm11_01.c index 1ecae20cf4e3..e472a1d88058 100644 --- a/arch/arm/mach-imx/mach-kzm_arm11_01.c +++ b/arch/arm/mach-imx/mach-kzm_arm11_01.c | |||
@@ -223,6 +223,8 @@ static int kzm_pins[] __initdata = { | |||
223 | */ | 223 | */ |
224 | static void __init kzm_board_init(void) | 224 | static void __init kzm_board_init(void) |
225 | { | 225 | { |
226 | imx31_soc_init(); | ||
227 | |||
226 | mxc_iomux_setup_multiple_pins(kzm_pins, | 228 | mxc_iomux_setup_multiple_pins(kzm_pins, |
227 | ARRAY_SIZE(kzm_pins), "kzm"); | 229 | ARRAY_SIZE(kzm_pins), "kzm"); |
228 | kzm_init_ext_uart(); | 230 | kzm_init_ext_uart(); |
diff --git a/arch/arm/mach-imx/mach-mx1ads.c b/arch/arm/mach-imx/mach-mx1ads.c index 38ec5cbbda9b..5cd8bee46960 100644 --- a/arch/arm/mach-imx/mach-mx1ads.c +++ b/arch/arm/mach-imx/mach-mx1ads.c | |||
@@ -115,6 +115,8 @@ static struct i2c_board_info mx1ads_i2c_devices[] = { | |||
115 | */ | 115 | */ |
116 | static void __init mx1ads_init(void) | 116 | static void __init mx1ads_init(void) |
117 | { | 117 | { |
118 | imx1_soc_init(); | ||
119 | |||
118 | mxc_gpio_setup_multiple_pins(mx1ads_pins, | 120 | mxc_gpio_setup_multiple_pins(mx1ads_pins, |
119 | ARRAY_SIZE(mx1ads_pins), "mx1ads"); | 121 | ARRAY_SIZE(mx1ads_pins), "mx1ads"); |
120 | 122 | ||
diff --git a/arch/arm/mach-imx/mach-mx21ads.c b/arch/arm/mach-imx/mach-mx21ads.c index 74ac88978ddd..d389ecf9b5a8 100644 --- a/arch/arm/mach-imx/mach-mx21ads.c +++ b/arch/arm/mach-imx/mach-mx21ads.c | |||
@@ -279,6 +279,8 @@ static struct platform_device *platform_devices[] __initdata = { | |||
279 | 279 | ||
280 | static void __init mx21ads_board_init(void) | 280 | static void __init mx21ads_board_init(void) |
281 | { | 281 | { |
282 | imx21_soc_init(); | ||
283 | |||
282 | mxc_gpio_setup_multiple_pins(mx21ads_pins, ARRAY_SIZE(mx21ads_pins), | 284 | mxc_gpio_setup_multiple_pins(mx21ads_pins, ARRAY_SIZE(mx21ads_pins), |
283 | "mx21ads"); | 285 | "mx21ads"); |
284 | 286 | ||
diff --git a/arch/arm/mach-imx/mach-mx25_3ds.c b/arch/arm/mach-imx/mach-mx25_3ds.c index 58ea3fdf0911..01534bb61305 100644 --- a/arch/arm/mach-imx/mach-mx25_3ds.c +++ b/arch/arm/mach-imx/mach-mx25_3ds.c | |||
@@ -219,6 +219,8 @@ static const struct esdhc_platform_data mx25pdk_esdhc_pdata __initconst = { | |||
219 | 219 | ||
220 | static void __init mx25pdk_init(void) | 220 | static void __init mx25pdk_init(void) |
221 | { | 221 | { |
222 | imx25_soc_init(); | ||
223 | |||
222 | mxc_iomux_v3_setup_multiple_pads(mx25pdk_pads, | 224 | mxc_iomux_v3_setup_multiple_pads(mx25pdk_pads, |
223 | ARRAY_SIZE(mx25pdk_pads)); | 225 | ARRAY_SIZE(mx25pdk_pads)); |
224 | 226 | ||
diff --git a/arch/arm/mach-imx/mach-mx27_3ds.c b/arch/arm/mach-imx/mach-mx27_3ds.c index 6e1accf93f81..117ce0a50f4e 100644 --- a/arch/arm/mach-imx/mach-mx27_3ds.c +++ b/arch/arm/mach-imx/mach-mx27_3ds.c | |||
@@ -267,6 +267,8 @@ static const struct imxi2c_platform_data mx27_3ds_i2c0_data __initconst = { | |||
267 | 267 | ||
268 | static void __init mx27pdk_init(void) | 268 | static void __init mx27pdk_init(void) |
269 | { | 269 | { |
270 | imx27_soc_init(); | ||
271 | |||
270 | mxc_gpio_setup_multiple_pins(mx27pdk_pins, ARRAY_SIZE(mx27pdk_pins), | 272 | mxc_gpio_setup_multiple_pins(mx27pdk_pins, ARRAY_SIZE(mx27pdk_pins), |
271 | "mx27pdk"); | 273 | "mx27pdk"); |
272 | mx27_3ds_sdhc1_enable_level_translator(); | 274 | mx27_3ds_sdhc1_enable_level_translator(); |
diff --git a/arch/arm/mach-imx/mach-mx27ads.c b/arch/arm/mach-imx/mach-mx27ads.c index 1db79506f5e4..fc26ed71b9ed 100644 --- a/arch/arm/mach-imx/mach-mx27ads.c +++ b/arch/arm/mach-imx/mach-mx27ads.c | |||
@@ -288,6 +288,8 @@ static const struct imxuart_platform_data uart_pdata __initconst = { | |||
288 | 288 | ||
289 | static void __init mx27ads_board_init(void) | 289 | static void __init mx27ads_board_init(void) |
290 | { | 290 | { |
291 | imx27_soc_init(); | ||
292 | |||
291 | mxc_gpio_setup_multiple_pins(mx27ads_pins, ARRAY_SIZE(mx27ads_pins), | 293 | mxc_gpio_setup_multiple_pins(mx27ads_pins, ARRAY_SIZE(mx27ads_pins), |
292 | "mx27ads"); | 294 | "mx27ads"); |
293 | 295 | ||
diff --git a/arch/arm/mach-imx/mach-mx31_3ds.c b/arch/arm/mach-imx/mach-mx31_3ds.c index b5ecc26d08a4..441fbb83f39c 100644 --- a/arch/arm/mach-imx/mach-mx31_3ds.c +++ b/arch/arm/mach-imx/mach-mx31_3ds.c | |||
@@ -690,6 +690,8 @@ static void __init mx31_3ds_init(void) | |||
690 | { | 690 | { |
691 | int ret; | 691 | int ret; |
692 | 692 | ||
693 | imx31_soc_init(); | ||
694 | |||
693 | mxc_iomux_setup_multiple_pins(mx31_3ds_pins, ARRAY_SIZE(mx31_3ds_pins), | 695 | mxc_iomux_setup_multiple_pins(mx31_3ds_pins, ARRAY_SIZE(mx31_3ds_pins), |
694 | "mx31_3ds"); | 696 | "mx31_3ds"); |
695 | 697 | ||
diff --git a/arch/arm/mach-imx/mach-mx31ads.c b/arch/arm/mach-imx/mach-mx31ads.c index f4dee0254634..0ce49478a479 100644 --- a/arch/arm/mach-imx/mach-mx31ads.c +++ b/arch/arm/mach-imx/mach-mx31ads.c | |||
@@ -516,6 +516,8 @@ static void __init mx31ads_init_irq(void) | |||
516 | 516 | ||
517 | static void __init mx31ads_init(void) | 517 | static void __init mx31ads_init(void) |
518 | { | 518 | { |
519 | imx31_soc_init(); | ||
520 | |||
519 | mxc_init_extuart(); | 521 | mxc_init_extuart(); |
520 | mxc_init_imx_uart(); | 522 | mxc_init_imx_uart(); |
521 | mxc_init_i2c(); | 523 | mxc_init_i2c(); |
diff --git a/arch/arm/mach-imx/mach-mx31lilly.c b/arch/arm/mach-imx/mach-mx31lilly.c index 410e676ae087..750368ddf0f9 100644 --- a/arch/arm/mach-imx/mach-mx31lilly.c +++ b/arch/arm/mach-imx/mach-mx31lilly.c | |||
@@ -243,6 +243,8 @@ core_param(mx31lilly_baseboard, mx31lilly_baseboard, int, 0444); | |||
243 | 243 | ||
244 | static void __init mx31lilly_board_init(void) | 244 | static void __init mx31lilly_board_init(void) |
245 | { | 245 | { |
246 | imx31_soc_init(); | ||
247 | |||
246 | switch (mx31lilly_baseboard) { | 248 | switch (mx31lilly_baseboard) { |
247 | case MX31LILLY_NOBOARD: | 249 | case MX31LILLY_NOBOARD: |
248 | break; | 250 | break; |
diff --git a/arch/arm/mach-imx/mach-mx31lite.c b/arch/arm/mach-imx/mach-mx31lite.c index ac9b4cad320e..4b47fd9fdd89 100644 --- a/arch/arm/mach-imx/mach-mx31lite.c +++ b/arch/arm/mach-imx/mach-mx31lite.c | |||
@@ -230,6 +230,8 @@ static void __init mx31lite_init(void) | |||
230 | { | 230 | { |
231 | int ret; | 231 | int ret; |
232 | 232 | ||
233 | imx31_soc_init(); | ||
234 | |||
233 | switch (mx31lite_baseboard) { | 235 | switch (mx31lite_baseboard) { |
234 | case MX31LITE_NOBOARD: | 236 | case MX31LITE_NOBOARD: |
235 | break; | 237 | break; |
diff --git a/arch/arm/mach-imx/mach-mx31moboard.c b/arch/arm/mach-imx/mach-mx31moboard.c index eaa51e49ca95..a52fd36e2b52 100644 --- a/arch/arm/mach-imx/mach-mx31moboard.c +++ b/arch/arm/mach-imx/mach-mx31moboard.c | |||
@@ -507,6 +507,8 @@ core_param(mx31moboard_baseboard, mx31moboard_baseboard, int, 0444); | |||
507 | */ | 507 | */ |
508 | static void __init mx31moboard_init(void) | 508 | static void __init mx31moboard_init(void) |
509 | { | 509 | { |
510 | imx31_soc_init(); | ||
511 | |||
510 | mxc_iomux_setup_multiple_pins(moboard_pins, ARRAY_SIZE(moboard_pins), | 512 | mxc_iomux_setup_multiple_pins(moboard_pins, ARRAY_SIZE(moboard_pins), |
511 | "moboard"); | 513 | "moboard"); |
512 | 514 | ||
diff --git a/arch/arm/mach-imx/mach-mx35_3ds.c b/arch/arm/mach-imx/mach-mx35_3ds.c index 882880ac1bbc..48b3c6fd5cf0 100644 --- a/arch/arm/mach-imx/mach-mx35_3ds.c +++ b/arch/arm/mach-imx/mach-mx35_3ds.c | |||
@@ -179,6 +179,8 @@ static const struct imxi2c_platform_data mx35_3ds_i2c0_data __initconst = { | |||
179 | */ | 179 | */ |
180 | static void __init mx35_3ds_init(void) | 180 | static void __init mx35_3ds_init(void) |
181 | { | 181 | { |
182 | imx35_soc_init(); | ||
183 | |||
182 | mxc_iomux_v3_setup_multiple_pads(mx35pdk_pads, ARRAY_SIZE(mx35pdk_pads)); | 184 | mxc_iomux_v3_setup_multiple_pads(mx35pdk_pads, ARRAY_SIZE(mx35pdk_pads)); |
183 | 185 | ||
184 | imx35_add_fec(NULL); | 186 | imx35_add_fec(NULL); |
diff --git a/arch/arm/mach-imx/mach-mxt_td60.c b/arch/arm/mach-imx/mach-mxt_td60.c index 2774541511e7..c85876fed663 100644 --- a/arch/arm/mach-imx/mach-mxt_td60.c +++ b/arch/arm/mach-imx/mach-mxt_td60.c | |||
@@ -233,6 +233,8 @@ static const struct imxuart_platform_data uart_pdata __initconst = { | |||
233 | 233 | ||
234 | static void __init mxt_td60_board_init(void) | 234 | static void __init mxt_td60_board_init(void) |
235 | { | 235 | { |
236 | imx27_soc_init(); | ||
237 | |||
236 | mxc_gpio_setup_multiple_pins(mxt_td60_pins, ARRAY_SIZE(mxt_td60_pins), | 238 | mxc_gpio_setup_multiple_pins(mxt_td60_pins, ARRAY_SIZE(mxt_td60_pins), |
237 | "MXT_TD60"); | 239 | "MXT_TD60"); |
238 | 240 | ||
diff --git a/arch/arm/mach-imx/mach-pca100.c b/arch/arm/mach-imx/mach-pca100.c index bbddc5a11c43..71083aa16038 100644 --- a/arch/arm/mach-imx/mach-pca100.c +++ b/arch/arm/mach-imx/mach-pca100.c | |||
@@ -357,6 +357,8 @@ static void __init pca100_init(void) | |||
357 | { | 357 | { |
358 | int ret; | 358 | int ret; |
359 | 359 | ||
360 | imx27_soc_init(); | ||
361 | |||
360 | /* SSI unit */ | 362 | /* SSI unit */ |
361 | mxc_audmux_v1_configure_port(MX27_AUDMUX_HPCR1_SSI0, | 363 | mxc_audmux_v1_configure_port(MX27_AUDMUX_HPCR1_SSI0, |
362 | MXC_AUDMUX_V1_PCR_SYN | /* 4wire mode */ | 364 | MXC_AUDMUX_V1_PCR_SYN | /* 4wire mode */ |
diff --git a/arch/arm/mach-imx/mach-pcm037.c b/arch/arm/mach-imx/mach-pcm037.c index 89c213b81295..f45b7cd72c8a 100644 --- a/arch/arm/mach-imx/mach-pcm037.c +++ b/arch/arm/mach-imx/mach-pcm037.c | |||
@@ -576,6 +576,8 @@ static void __init pcm037_init(void) | |||
576 | { | 576 | { |
577 | int ret; | 577 | int ret; |
578 | 578 | ||
579 | imx31_soc_init(); | ||
580 | |||
579 | mxc_iomux_set_gpr(MUX_PGP_UH2, 1); | 581 | mxc_iomux_set_gpr(MUX_PGP_UH2, 1); |
580 | 582 | ||
581 | mxc_iomux_setup_multiple_pins(pcm037_pins, ARRAY_SIZE(pcm037_pins), | 583 | mxc_iomux_setup_multiple_pins(pcm037_pins, ARRAY_SIZE(pcm037_pins), |
diff --git a/arch/arm/mach-imx/mach-pcm038.c b/arch/arm/mach-imx/mach-pcm038.c index 853bb871c7ed..2d6a64bbac44 100644 --- a/arch/arm/mach-imx/mach-pcm038.c +++ b/arch/arm/mach-imx/mach-pcm038.c | |||
@@ -295,6 +295,8 @@ static const struct mxc_usbh_platform_data usbh2_pdata __initconst = { | |||
295 | 295 | ||
296 | static void __init pcm038_init(void) | 296 | static void __init pcm038_init(void) |
297 | { | 297 | { |
298 | imx27_soc_init(); | ||
299 | |||
298 | mxc_gpio_setup_multiple_pins(pcm038_pins, ARRAY_SIZE(pcm038_pins), | 300 | mxc_gpio_setup_multiple_pins(pcm038_pins, ARRAY_SIZE(pcm038_pins), |
299 | "PCM038"); | 301 | "PCM038"); |
300 | 302 | ||
diff --git a/arch/arm/mach-imx/mach-pcm043.c b/arch/arm/mach-imx/mach-pcm043.c index 026441628dfa..163cc318cafb 100644 --- a/arch/arm/mach-imx/mach-pcm043.c +++ b/arch/arm/mach-imx/mach-pcm043.c | |||
@@ -356,6 +356,8 @@ static struct esdhc_platform_data sd1_pdata = { | |||
356 | */ | 356 | */ |
357 | static void __init pcm043_init(void) | 357 | static void __init pcm043_init(void) |
358 | { | 358 | { |
359 | imx35_soc_init(); | ||
360 | |||
359 | mxc_iomux_v3_setup_multiple_pads(pcm043_pads, ARRAY_SIZE(pcm043_pads)); | 361 | mxc_iomux_v3_setup_multiple_pads(pcm043_pads, ARRAY_SIZE(pcm043_pads)); |
360 | 362 | ||
361 | mxc_audmux_v2_configure_port(3, | 363 | mxc_audmux_v2_configure_port(3, |
diff --git a/arch/arm/mach-imx/mach-qong.c b/arch/arm/mach-imx/mach-qong.c index c16328715939..3626f486498a 100644 --- a/arch/arm/mach-imx/mach-qong.c +++ b/arch/arm/mach-imx/mach-qong.c | |||
@@ -244,6 +244,8 @@ static void __init qong_init_fpga(void) | |||
244 | */ | 244 | */ |
245 | static void __init qong_init(void) | 245 | static void __init qong_init(void) |
246 | { | 246 | { |
247 | imx31_soc_init(); | ||
248 | |||
247 | mxc_init_imx_uart(); | 249 | mxc_init_imx_uart(); |
248 | qong_init_nor_mtd(); | 250 | qong_init_nor_mtd(); |
249 | qong_init_fpga(); | 251 | qong_init_fpga(); |
diff --git a/arch/arm/mach-imx/mach-scb9328.c b/arch/arm/mach-imx/mach-scb9328.c index dcaee043628e..82805260e19c 100644 --- a/arch/arm/mach-imx/mach-scb9328.c +++ b/arch/arm/mach-imx/mach-scb9328.c | |||
@@ -129,6 +129,8 @@ static struct platform_device *devices[] __initdata = { | |||
129 | */ | 129 | */ |
130 | static void __init scb9328_init(void) | 130 | static void __init scb9328_init(void) |
131 | { | 131 | { |
132 | imx1_soc_init(); | ||
133 | |||
132 | imx1_add_imx_uart0(&uart_pdata); | 134 | imx1_add_imx_uart0(&uart_pdata); |
133 | 135 | ||
134 | printk(KERN_INFO"Scb9328: Adding devices\n"); | 136 | printk(KERN_INFO"Scb9328: Adding devices\n"); |
diff --git a/arch/arm/mach-imx/mach-vpr200.c b/arch/arm/mach-imx/mach-vpr200.c index d74e3473d236..7d8e012a6335 100644 --- a/arch/arm/mach-imx/mach-vpr200.c +++ b/arch/arm/mach-imx/mach-vpr200.c | |||
@@ -267,6 +267,8 @@ static struct platform_device *devices[] __initdata = { | |||
267 | */ | 267 | */ |
268 | static void __init vpr200_board_init(void) | 268 | static void __init vpr200_board_init(void) |
269 | { | 269 | { |
270 | imx35_soc_init(); | ||
271 | |||
270 | mxc_iomux_v3_setup_multiple_pads(vpr200_pads, ARRAY_SIZE(vpr200_pads)); | 272 | mxc_iomux_v3_setup_multiple_pads(vpr200_pads, ARRAY_SIZE(vpr200_pads)); |
271 | 273 | ||
272 | imx35_add_fec(NULL); | 274 | imx35_add_fec(NULL); |
diff --git a/arch/arm/mach-imx/mm-imx1.c b/arch/arm/mach-imx/mm-imx1.c index 2e482ba5a0e7..2bded591d5c2 100644 --- a/arch/arm/mach-imx/mm-imx1.c +++ b/arch/arm/mach-imx/mm-imx1.c | |||
@@ -23,7 +23,6 @@ | |||
23 | 23 | ||
24 | #include <mach/common.h> | 24 | #include <mach/common.h> |
25 | #include <mach/hardware.h> | 25 | #include <mach/hardware.h> |
26 | #include <mach/gpio.h> | ||
27 | #include <mach/irqs.h> | 26 | #include <mach/irqs.h> |
28 | #include <mach/iomux-v1.h> | 27 | #include <mach/iomux-v1.h> |
29 | 28 | ||
@@ -44,15 +43,19 @@ void __init imx1_init_early(void) | |||
44 | MX1_NUM_GPIO_PORT); | 43 | MX1_NUM_GPIO_PORT); |
45 | } | 44 | } |
46 | 45 | ||
47 | static struct mxc_gpio_port imx1_gpio_ports[] = { | ||
48 | DEFINE_IMX_GPIO_PORT_IRQ(MX1, 0, 1, MX1_GPIO_INT_PORTA), | ||
49 | DEFINE_IMX_GPIO_PORT_IRQ(MX1, 1, 2, MX1_GPIO_INT_PORTB), | ||
50 | DEFINE_IMX_GPIO_PORT_IRQ(MX1, 2, 3, MX1_GPIO_INT_PORTC), | ||
51 | DEFINE_IMX_GPIO_PORT_IRQ(MX1, 3, 4, MX1_GPIO_INT_PORTD), | ||
52 | }; | ||
53 | |||
54 | void __init mx1_init_irq(void) | 46 | void __init mx1_init_irq(void) |
55 | { | 47 | { |
56 | mxc_init_irq(MX1_IO_ADDRESS(MX1_AVIC_BASE_ADDR)); | 48 | mxc_init_irq(MX1_IO_ADDRESS(MX1_AVIC_BASE_ADDR)); |
57 | mxc_gpio_init(imx1_gpio_ports, ARRAY_SIZE(imx1_gpio_ports)); | 49 | } |
50 | |||
51 | void __init imx1_soc_init(void) | ||
52 | { | ||
53 | mxc_register_gpio("imx1-gpio", 0, MX1_GPIO1_BASE_ADDR, SZ_256, | ||
54 | MX1_GPIO_INT_PORTA, 0); | ||
55 | mxc_register_gpio("imx1-gpio", 1, MX1_GPIO2_BASE_ADDR, SZ_256, | ||
56 | MX1_GPIO_INT_PORTB, 0); | ||
57 | mxc_register_gpio("imx1-gpio", 2, MX1_GPIO3_BASE_ADDR, SZ_256, | ||
58 | MX1_GPIO_INT_PORTC, 0); | ||
59 | mxc_register_gpio("imx1-gpio", 3, MX1_GPIO4_BASE_ADDR, SZ_256, | ||
60 | MX1_GPIO_INT_PORTD, 0); | ||
58 | } | 61 | } |
diff --git a/arch/arm/mach-imx/mm-imx21.c b/arch/arm/mach-imx/mm-imx21.c index 7a0c500ac2c8..6d7d518686a5 100644 --- a/arch/arm/mach-imx/mm-imx21.c +++ b/arch/arm/mach-imx/mm-imx21.c | |||
@@ -24,7 +24,6 @@ | |||
24 | #include <mach/common.h> | 24 | #include <mach/common.h> |
25 | #include <asm/pgtable.h> | 25 | #include <asm/pgtable.h> |
26 | #include <asm/mach/map.h> | 26 | #include <asm/mach/map.h> |
27 | #include <mach/gpio.h> | ||
28 | #include <mach/irqs.h> | 27 | #include <mach/irqs.h> |
29 | #include <mach/iomux-v1.h> | 28 | #include <mach/iomux-v1.h> |
30 | 29 | ||
@@ -70,17 +69,17 @@ void __init imx21_init_early(void) | |||
70 | MX21_NUM_GPIO_PORT); | 69 | MX21_NUM_GPIO_PORT); |
71 | } | 70 | } |
72 | 71 | ||
73 | static struct mxc_gpio_port imx21_gpio_ports[] = { | ||
74 | DEFINE_IMX_GPIO_PORT_IRQ(MX21, 0, 1, MX21_INT_GPIO), | ||
75 | DEFINE_IMX_GPIO_PORT(MX21, 1, 2), | ||
76 | DEFINE_IMX_GPIO_PORT(MX21, 2, 3), | ||
77 | DEFINE_IMX_GPIO_PORT(MX21, 3, 4), | ||
78 | DEFINE_IMX_GPIO_PORT(MX21, 4, 5), | ||
79 | DEFINE_IMX_GPIO_PORT(MX21, 5, 6), | ||
80 | }; | ||
81 | |||
82 | void __init mx21_init_irq(void) | 72 | void __init mx21_init_irq(void) |
83 | { | 73 | { |
84 | mxc_init_irq(MX21_IO_ADDRESS(MX21_AVIC_BASE_ADDR)); | 74 | mxc_init_irq(MX21_IO_ADDRESS(MX21_AVIC_BASE_ADDR)); |
85 | mxc_gpio_init(imx21_gpio_ports, ARRAY_SIZE(imx21_gpio_ports)); | 75 | } |
76 | |||
77 | void __init imx21_soc_init(void) | ||
78 | { | ||
79 | mxc_register_gpio("imx21-gpio", 0, MX21_GPIO1_BASE_ADDR, SZ_256, MX21_INT_GPIO, 0); | ||
80 | mxc_register_gpio("imx21-gpio", 1, MX21_GPIO2_BASE_ADDR, SZ_256, MX21_INT_GPIO, 0); | ||
81 | mxc_register_gpio("imx21-gpio", 2, MX21_GPIO3_BASE_ADDR, SZ_256, MX21_INT_GPIO, 0); | ||
82 | mxc_register_gpio("imx21-gpio", 3, MX21_GPIO4_BASE_ADDR, SZ_256, MX21_INT_GPIO, 0); | ||
83 | mxc_register_gpio("imx21-gpio", 4, MX21_GPIO5_BASE_ADDR, SZ_256, MX21_INT_GPIO, 0); | ||
84 | mxc_register_gpio("imx21-gpio", 5, MX21_GPIO6_BASE_ADDR, SZ_256, MX21_INT_GPIO, 0); | ||
86 | } | 85 | } |
diff --git a/arch/arm/mach-imx/mm-imx25.c b/arch/arm/mach-imx/mm-imx25.c index 02f7b5c7fa8e..9a1591c2508d 100644 --- a/arch/arm/mach-imx/mm-imx25.c +++ b/arch/arm/mach-imx/mm-imx25.c | |||
@@ -27,7 +27,6 @@ | |||
27 | #include <mach/hardware.h> | 27 | #include <mach/hardware.h> |
28 | #include <mach/mx25.h> | 28 | #include <mach/mx25.h> |
29 | #include <mach/iomux-v3.h> | 29 | #include <mach/iomux-v3.h> |
30 | #include <mach/gpio.h> | ||
31 | #include <mach/irqs.h> | 30 | #include <mach/irqs.h> |
32 | 31 | ||
33 | /* | 32 | /* |
@@ -57,16 +56,16 @@ void __init imx25_init_early(void) | |||
57 | mxc_arch_reset_init(MX25_IO_ADDRESS(MX25_WDOG_BASE_ADDR)); | 56 | mxc_arch_reset_init(MX25_IO_ADDRESS(MX25_WDOG_BASE_ADDR)); |
58 | } | 57 | } |
59 | 58 | ||
60 | static struct mxc_gpio_port imx25_gpio_ports[] = { | ||
61 | DEFINE_IMX_GPIO_PORT_IRQ(MX25, 0, 1, MX25_INT_GPIO1), | ||
62 | DEFINE_IMX_GPIO_PORT_IRQ(MX25, 1, 2, MX25_INT_GPIO2), | ||
63 | DEFINE_IMX_GPIO_PORT_IRQ(MX25, 2, 3, MX25_INT_GPIO3), | ||
64 | DEFINE_IMX_GPIO_PORT_IRQ(MX25, 3, 4, MX25_INT_GPIO4), | ||
65 | }; | ||
66 | |||
67 | void __init mx25_init_irq(void) | 59 | void __init mx25_init_irq(void) |
68 | { | 60 | { |
69 | mxc_init_irq(MX25_IO_ADDRESS(MX25_AVIC_BASE_ADDR)); | 61 | mxc_init_irq(MX25_IO_ADDRESS(MX25_AVIC_BASE_ADDR)); |
70 | mxc_gpio_init(imx25_gpio_ports, ARRAY_SIZE(imx25_gpio_ports)); | ||
71 | } | 62 | } |
72 | 63 | ||
64 | void __init imx25_soc_init(void) | ||
65 | { | ||
66 | /* i.mx25 has the i.mx31 type gpio */ | ||
67 | mxc_register_gpio("imx31-gpio", 0, MX25_GPIO1_BASE_ADDR, SZ_16K, MX25_INT_GPIO1, 0); | ||
68 | mxc_register_gpio("imx31-gpio", 1, MX25_GPIO2_BASE_ADDR, SZ_16K, MX25_INT_GPIO2, 0); | ||
69 | mxc_register_gpio("imx31-gpio", 2, MX25_GPIO3_BASE_ADDR, SZ_16K, MX25_INT_GPIO3, 0); | ||
70 | mxc_register_gpio("imx31-gpio", 3, MX25_GPIO4_BASE_ADDR, SZ_16K, MX25_INT_GPIO4, 0); | ||
71 | } | ||
diff --git a/arch/arm/mach-imx/mm-imx27.c b/arch/arm/mach-imx/mm-imx27.c index a6761a39f08c..133b30003ddb 100644 --- a/arch/arm/mach-imx/mm-imx27.c +++ b/arch/arm/mach-imx/mm-imx27.c | |||
@@ -24,7 +24,6 @@ | |||
24 | #include <mach/common.h> | 24 | #include <mach/common.h> |
25 | #include <asm/pgtable.h> | 25 | #include <asm/pgtable.h> |
26 | #include <asm/mach/map.h> | 26 | #include <asm/mach/map.h> |
27 | #include <mach/gpio.h> | ||
28 | #include <mach/irqs.h> | 27 | #include <mach/irqs.h> |
29 | #include <mach/iomux-v1.h> | 28 | #include <mach/iomux-v1.h> |
30 | 29 | ||
@@ -70,17 +69,18 @@ void __init imx27_init_early(void) | |||
70 | MX27_NUM_GPIO_PORT); | 69 | MX27_NUM_GPIO_PORT); |
71 | } | 70 | } |
72 | 71 | ||
73 | static struct mxc_gpio_port imx27_gpio_ports[] = { | ||
74 | DEFINE_IMX_GPIO_PORT_IRQ(MX27, 0, 1, MX27_INT_GPIO), | ||
75 | DEFINE_IMX_GPIO_PORT(MX27, 1, 2), | ||
76 | DEFINE_IMX_GPIO_PORT(MX27, 2, 3), | ||
77 | DEFINE_IMX_GPIO_PORT(MX27, 3, 4), | ||
78 | DEFINE_IMX_GPIO_PORT(MX27, 4, 5), | ||
79 | DEFINE_IMX_GPIO_PORT(MX27, 5, 6), | ||
80 | }; | ||
81 | |||
82 | void __init mx27_init_irq(void) | 72 | void __init mx27_init_irq(void) |
83 | { | 73 | { |
84 | mxc_init_irq(MX27_IO_ADDRESS(MX27_AVIC_BASE_ADDR)); | 74 | mxc_init_irq(MX27_IO_ADDRESS(MX27_AVIC_BASE_ADDR)); |
85 | mxc_gpio_init(imx27_gpio_ports, ARRAY_SIZE(imx27_gpio_ports)); | 75 | } |
76 | |||
77 | void __init imx27_soc_init(void) | ||
78 | { | ||
79 | /* i.mx27 has the i.mx21 type gpio */ | ||
80 | mxc_register_gpio("imx21-gpio", 0, MX27_GPIO1_BASE_ADDR, SZ_256, MX27_INT_GPIO, 0); | ||
81 | mxc_register_gpio("imx21-gpio", 1, MX27_GPIO2_BASE_ADDR, SZ_256, MX27_INT_GPIO, 0); | ||
82 | mxc_register_gpio("imx21-gpio", 2, MX27_GPIO3_BASE_ADDR, SZ_256, MX27_INT_GPIO, 0); | ||
83 | mxc_register_gpio("imx21-gpio", 3, MX27_GPIO4_BASE_ADDR, SZ_256, MX27_INT_GPIO, 0); | ||
84 | mxc_register_gpio("imx21-gpio", 4, MX27_GPIO5_BASE_ADDR, SZ_256, MX27_INT_GPIO, 0); | ||
85 | mxc_register_gpio("imx21-gpio", 5, MX27_GPIO6_BASE_ADDR, SZ_256, MX27_INT_GPIO, 0); | ||
86 | } | 86 | } |
diff --git a/arch/arm/mach-imx/mm-imx31.c b/arch/arm/mach-imx/mm-imx31.c index 86b9b45864d2..6d103c01b8b9 100644 --- a/arch/arm/mach-imx/mm-imx31.c +++ b/arch/arm/mach-imx/mm-imx31.c | |||
@@ -26,7 +26,6 @@ | |||
26 | #include <mach/common.h> | 26 | #include <mach/common.h> |
27 | #include <mach/hardware.h> | 27 | #include <mach/hardware.h> |
28 | #include <mach/iomux-v3.h> | 28 | #include <mach/iomux-v3.h> |
29 | #include <mach/gpio.h> | ||
30 | #include <mach/irqs.h> | 29 | #include <mach/irqs.h> |
31 | 30 | ||
32 | static struct map_desc mx31_io_desc[] __initdata = { | 31 | static struct map_desc mx31_io_desc[] __initdata = { |
@@ -53,14 +52,14 @@ void __init imx31_init_early(void) | |||
53 | mxc_arch_reset_init(MX31_IO_ADDRESS(MX31_WDOG_BASE_ADDR)); | 52 | mxc_arch_reset_init(MX31_IO_ADDRESS(MX31_WDOG_BASE_ADDR)); |
54 | } | 53 | } |
55 | 54 | ||
56 | static struct mxc_gpio_port imx31_gpio_ports[] = { | ||
57 | DEFINE_IMX_GPIO_PORT_IRQ(MX31, 0, 1, MX31_INT_GPIO1), | ||
58 | DEFINE_IMX_GPIO_PORT_IRQ(MX31, 1, 2, MX31_INT_GPIO2), | ||
59 | DEFINE_IMX_GPIO_PORT_IRQ(MX31, 2, 3, MX31_INT_GPIO3), | ||
60 | }; | ||
61 | |||
62 | void __init mx31_init_irq(void) | 55 | void __init mx31_init_irq(void) |
63 | { | 56 | { |
64 | mxc_init_irq(MX31_IO_ADDRESS(MX31_AVIC_BASE_ADDR)); | 57 | mxc_init_irq(MX31_IO_ADDRESS(MX31_AVIC_BASE_ADDR)); |
65 | mxc_gpio_init(imx31_gpio_ports, ARRAY_SIZE(imx31_gpio_ports)); | 58 | } |
59 | |||
60 | void __init imx31_soc_init(void) | ||
61 | { | ||
62 | mxc_register_gpio("imx31-gpio", 0, MX31_GPIO1_BASE_ADDR, SZ_16K, MX31_INT_GPIO1, 0); | ||
63 | mxc_register_gpio("imx31-gpio", 1, MX31_GPIO2_BASE_ADDR, SZ_16K, MX31_INT_GPIO2, 0); | ||
64 | mxc_register_gpio("imx31-gpio", 2, MX31_GPIO3_BASE_ADDR, SZ_16K, MX31_INT_GPIO3, 0); | ||
66 | } | 65 | } |
diff --git a/arch/arm/mach-imx/mm-imx35.c b/arch/arm/mach-imx/mm-imx35.c index c880e6d1ae55..bb068bc8dab7 100644 --- a/arch/arm/mach-imx/mm-imx35.c +++ b/arch/arm/mach-imx/mm-imx35.c | |||
@@ -27,7 +27,6 @@ | |||
27 | #include <mach/common.h> | 27 | #include <mach/common.h> |
28 | #include <mach/hardware.h> | 28 | #include <mach/hardware.h> |
29 | #include <mach/iomux-v3.h> | 29 | #include <mach/iomux-v3.h> |
30 | #include <mach/gpio.h> | ||
31 | #include <mach/irqs.h> | 30 | #include <mach/irqs.h> |
32 | 31 | ||
33 | static struct map_desc mx35_io_desc[] __initdata = { | 32 | static struct map_desc mx35_io_desc[] __initdata = { |
@@ -50,14 +49,15 @@ void __init imx35_init_early(void) | |||
50 | mxc_arch_reset_init(MX35_IO_ADDRESS(MX35_WDOG_BASE_ADDR)); | 49 | mxc_arch_reset_init(MX35_IO_ADDRESS(MX35_WDOG_BASE_ADDR)); |
51 | } | 50 | } |
52 | 51 | ||
53 | static struct mxc_gpio_port imx35_gpio_ports[] = { | ||
54 | DEFINE_IMX_GPIO_PORT_IRQ(MX35, 0, 1, MX35_INT_GPIO1), | ||
55 | DEFINE_IMX_GPIO_PORT_IRQ(MX35, 1, 2, MX35_INT_GPIO2), | ||
56 | DEFINE_IMX_GPIO_PORT_IRQ(MX35, 2, 3, MX35_INT_GPIO3), | ||
57 | }; | ||
58 | |||
59 | void __init mx35_init_irq(void) | 52 | void __init mx35_init_irq(void) |
60 | { | 53 | { |
61 | mxc_init_irq(MX35_IO_ADDRESS(MX35_AVIC_BASE_ADDR)); | 54 | mxc_init_irq(MX35_IO_ADDRESS(MX35_AVIC_BASE_ADDR)); |
62 | mxc_gpio_init(imx35_gpio_ports, ARRAY_SIZE(imx35_gpio_ports)); | 55 | } |
56 | |||
57 | void __init imx35_soc_init(void) | ||
58 | { | ||
59 | /* i.mx35 has the i.mx31 type gpio */ | ||
60 | mxc_register_gpio("imx31-gpio", 0, MX35_GPIO1_BASE_ADDR, SZ_16K, MX35_INT_GPIO1, 0); | ||
61 | mxc_register_gpio("imx31-gpio", 1, MX35_GPIO2_BASE_ADDR, SZ_16K, MX35_INT_GPIO2, 0); | ||
62 | mxc_register_gpio("imx31-gpio", 2, MX35_GPIO3_BASE_ADDR, SZ_16K, MX35_INT_GPIO3, 0); | ||
63 | } | 63 | } |
diff --git a/arch/arm/mach-mx5/board-cpuimx51.c b/arch/arm/mach-mx5/board-cpuimx51.c index 4efa02ee1639..add0d42de7af 100644 --- a/arch/arm/mach-mx5/board-cpuimx51.c +++ b/arch/arm/mach-mx5/board-cpuimx51.c | |||
@@ -245,6 +245,8 @@ __setup("otg_mode=", eukrea_cpuimx51_otg_mode); | |||
245 | */ | 245 | */ |
246 | static void __init eukrea_cpuimx51_init(void) | 246 | static void __init eukrea_cpuimx51_init(void) |
247 | { | 247 | { |
248 | imx51_soc_init(); | ||
249 | |||
248 | mxc_iomux_v3_setup_multiple_pads(eukrea_cpuimx51_pads, | 250 | mxc_iomux_v3_setup_multiple_pads(eukrea_cpuimx51_pads, |
249 | ARRAY_SIZE(eukrea_cpuimx51_pads)); | 251 | ARRAY_SIZE(eukrea_cpuimx51_pads)); |
250 | 252 | ||
diff --git a/arch/arm/mach-mx5/board-cpuimx51sd.c b/arch/arm/mach-mx5/board-cpuimx51sd.c index 5ef25a596143..ff096d587299 100644 --- a/arch/arm/mach-mx5/board-cpuimx51sd.c +++ b/arch/arm/mach-mx5/board-cpuimx51sd.c | |||
@@ -264,6 +264,8 @@ static struct platform_device *platform_devices[] __initdata = { | |||
264 | 264 | ||
265 | static void __init eukrea_cpuimx51sd_init(void) | 265 | static void __init eukrea_cpuimx51sd_init(void) |
266 | { | 266 | { |
267 | imx51_soc_init(); | ||
268 | |||
267 | mxc_iomux_v3_setup_multiple_pads(eukrea_cpuimx51sd_pads, | 269 | mxc_iomux_v3_setup_multiple_pads(eukrea_cpuimx51sd_pads, |
268 | ARRAY_SIZE(eukrea_cpuimx51sd_pads)); | 270 | ARRAY_SIZE(eukrea_cpuimx51sd_pads)); |
269 | 271 | ||
diff --git a/arch/arm/mach-mx5/board-mx50_rdp.c b/arch/arm/mach-mx5/board-mx50_rdp.c index 11210e1ae42a..7de25c6712eb 100644 --- a/arch/arm/mach-mx5/board-mx50_rdp.c +++ b/arch/arm/mach-mx5/board-mx50_rdp.c | |||
@@ -192,6 +192,8 @@ static const struct imxi2c_platform_data i2c_data __initconst = { | |||
192 | */ | 192 | */ |
193 | static void __init mx50_rdp_board_init(void) | 193 | static void __init mx50_rdp_board_init(void) |
194 | { | 194 | { |
195 | imx50_soc_init(); | ||
196 | |||
195 | mxc_iomux_v3_setup_multiple_pads(mx50_rdp_pads, | 197 | mxc_iomux_v3_setup_multiple_pads(mx50_rdp_pads, |
196 | ARRAY_SIZE(mx50_rdp_pads)); | 198 | ARRAY_SIZE(mx50_rdp_pads)); |
197 | 199 | ||
diff --git a/arch/arm/mach-mx5/board-mx51_3ds.c b/arch/arm/mach-mx5/board-mx51_3ds.c index 63dfbeafbc1e..3112d15feebc 100644 --- a/arch/arm/mach-mx5/board-mx51_3ds.c +++ b/arch/arm/mach-mx5/board-mx51_3ds.c | |||
@@ -135,6 +135,8 @@ static struct spi_board_info mx51_3ds_spi_nor_device[] = { | |||
135 | */ | 135 | */ |
136 | static void __init mx51_3ds_init(void) | 136 | static void __init mx51_3ds_init(void) |
137 | { | 137 | { |
138 | imx51_soc_init(); | ||
139 | |||
138 | mxc_iomux_v3_setup_multiple_pads(mx51_3ds_pads, | 140 | mxc_iomux_v3_setup_multiple_pads(mx51_3ds_pads, |
139 | ARRAY_SIZE(mx51_3ds_pads)); | 141 | ARRAY_SIZE(mx51_3ds_pads)); |
140 | 142 | ||
diff --git a/arch/arm/mach-mx5/board-mx51_babbage.c b/arch/arm/mach-mx5/board-mx51_babbage.c index c7b3fabf50f9..6021dd00ec75 100644 --- a/arch/arm/mach-mx5/board-mx51_babbage.c +++ b/arch/arm/mach-mx5/board-mx51_babbage.c | |||
@@ -340,6 +340,8 @@ static void __init mx51_babbage_init(void) | |||
340 | iomux_v3_cfg_t power_key = _MX51_PAD_EIM_A27__GPIO2_21 | | 340 | iomux_v3_cfg_t power_key = _MX51_PAD_EIM_A27__GPIO2_21 | |
341 | MUX_PAD_CTRL(PAD_CTL_SRE_FAST | PAD_CTL_DSE_HIGH | PAD_CTL_PUS_100K_UP); | 341 | MUX_PAD_CTRL(PAD_CTL_SRE_FAST | PAD_CTL_DSE_HIGH | PAD_CTL_PUS_100K_UP); |
342 | 342 | ||
343 | imx51_soc_init(); | ||
344 | |||
343 | #if defined(CONFIG_CPU_FREQ_IMX) | 345 | #if defined(CONFIG_CPU_FREQ_IMX) |
344 | get_cpu_op = mx51_get_cpu_op; | 346 | get_cpu_op = mx51_get_cpu_op; |
345 | #endif | 347 | #endif |
diff --git a/arch/arm/mach-mx5/board-mx51_efikamx.c b/arch/arm/mach-mx5/board-mx51_efikamx.c index 6e362315291b..3be603b9075a 100644 --- a/arch/arm/mach-mx5/board-mx51_efikamx.c +++ b/arch/arm/mach-mx5/board-mx51_efikamx.c | |||
@@ -236,6 +236,8 @@ late_initcall(mx51_efikamx_power_init); | |||
236 | 236 | ||
237 | static void __init mx51_efikamx_init(void) | 237 | static void __init mx51_efikamx_init(void) |
238 | { | 238 | { |
239 | imx51_soc_init(); | ||
240 | |||
239 | mxc_iomux_v3_setup_multiple_pads(mx51efikamx_pads, | 241 | mxc_iomux_v3_setup_multiple_pads(mx51efikamx_pads, |
240 | ARRAY_SIZE(mx51efikamx_pads)); | 242 | ARRAY_SIZE(mx51efikamx_pads)); |
241 | efika_board_common_init(); | 243 | efika_board_common_init(); |
diff --git a/arch/arm/mach-mx5/board-mx51_efikasb.c b/arch/arm/mach-mx5/board-mx51_efikasb.c index 474fc6e4c6df..4b2e522de0f8 100644 --- a/arch/arm/mach-mx5/board-mx51_efikasb.c +++ b/arch/arm/mach-mx5/board-mx51_efikasb.c | |||
@@ -248,6 +248,8 @@ static void __init mx51_efikasb_board_id(void) | |||
248 | 248 | ||
249 | static void __init efikasb_board_init(void) | 249 | static void __init efikasb_board_init(void) |
250 | { | 250 | { |
251 | imx51_soc_init(); | ||
252 | |||
251 | mxc_iomux_v3_setup_multiple_pads(mx51efikasb_pads, | 253 | mxc_iomux_v3_setup_multiple_pads(mx51efikasb_pads, |
252 | ARRAY_SIZE(mx51efikasb_pads)); | 254 | ARRAY_SIZE(mx51efikasb_pads)); |
253 | efika_board_common_init(); | 255 | efika_board_common_init(); |
diff --git a/arch/arm/mach-mx5/board-mx53_evk.c b/arch/arm/mach-mx5/board-mx53_evk.c index f87d571882c6..0d9218a6e2d2 100644 --- a/arch/arm/mach-mx5/board-mx53_evk.c +++ b/arch/arm/mach-mx5/board-mx53_evk.c | |||
@@ -117,6 +117,8 @@ static const struct spi_imx_master mx53_evk_spi_data __initconst = { | |||
117 | 117 | ||
118 | static void __init mx53_evk_board_init(void) | 118 | static void __init mx53_evk_board_init(void) |
119 | { | 119 | { |
120 | imx53_soc_init(); | ||
121 | |||
120 | mxc_iomux_v3_setup_multiple_pads(mx53_evk_pads, | 122 | mxc_iomux_v3_setup_multiple_pads(mx53_evk_pads, |
121 | ARRAY_SIZE(mx53_evk_pads)); | 123 | ARRAY_SIZE(mx53_evk_pads)); |
122 | mx53_evk_init_uart(); | 124 | mx53_evk_init_uart(); |
diff --git a/arch/arm/mach-mx5/board-mx53_loco.c b/arch/arm/mach-mx5/board-mx53_loco.c index 1b947e8c9c0c..359c3e248add 100644 --- a/arch/arm/mach-mx5/board-mx53_loco.c +++ b/arch/arm/mach-mx5/board-mx53_loco.c | |||
@@ -227,6 +227,8 @@ static const struct imxi2c_platform_data mx53_loco_i2c_data __initconst = { | |||
227 | 227 | ||
228 | static void __init mx53_loco_board_init(void) | 228 | static void __init mx53_loco_board_init(void) |
229 | { | 229 | { |
230 | imx53_soc_init(); | ||
231 | |||
230 | mxc_iomux_v3_setup_multiple_pads(mx53_loco_pads, | 232 | mxc_iomux_v3_setup_multiple_pads(mx53_loco_pads, |
231 | ARRAY_SIZE(mx53_loco_pads)); | 233 | ARRAY_SIZE(mx53_loco_pads)); |
232 | imx53_add_imx_uart(0, NULL); | 234 | imx53_add_imx_uart(0, NULL); |
diff --git a/arch/arm/mach-mx5/board-mx53_smd.c b/arch/arm/mach-mx5/board-mx53_smd.c index 817c08938f55..bc02894eafef 100644 --- a/arch/arm/mach-mx5/board-mx53_smd.c +++ b/arch/arm/mach-mx5/board-mx53_smd.c | |||
@@ -113,6 +113,8 @@ static const struct imxi2c_platform_data mx53_smd_i2c_data __initconst = { | |||
113 | 113 | ||
114 | static void __init mx53_smd_board_init(void) | 114 | static void __init mx53_smd_board_init(void) |
115 | { | 115 | { |
116 | imx53_soc_init(); | ||
117 | |||
116 | mxc_iomux_v3_setup_multiple_pads(mx53_smd_pads, | 118 | mxc_iomux_v3_setup_multiple_pads(mx53_smd_pads, |
117 | ARRAY_SIZE(mx53_smd_pads)); | 119 | ARRAY_SIZE(mx53_smd_pads)); |
118 | mx53_smd_init_uart(); | 120 | mx53_smd_init_uart(); |
diff --git a/arch/arm/mach-mx5/devices.c b/arch/arm/mach-mx5/devices.c index 153ada53e575..371ca8c8414c 100644 --- a/arch/arm/mach-mx5/devices.c +++ b/arch/arm/mach-mx5/devices.c | |||
@@ -12,7 +12,6 @@ | |||
12 | 12 | ||
13 | #include <linux/platform_device.h> | 13 | #include <linux/platform_device.h> |
14 | #include <linux/dma-mapping.h> | 14 | #include <linux/dma-mapping.h> |
15 | #include <linux/gpio.h> | ||
16 | #include <mach/hardware.h> | 15 | #include <mach/hardware.h> |
17 | #include <mach/imx-uart.h> | 16 | #include <mach/imx-uart.h> |
18 | #include <mach/irqs.h> | 17 | #include <mach/irqs.h> |
@@ -119,66 +118,3 @@ struct platform_device mxc_usbh2_device = { | |||
119 | .coherent_dma_mask = DMA_BIT_MASK(32), | 118 | .coherent_dma_mask = DMA_BIT_MASK(32), |
120 | }, | 119 | }, |
121 | }; | 120 | }; |
122 | |||
123 | static struct mxc_gpio_port mxc_gpio_ports[] = { | ||
124 | { | ||
125 | .chip.label = "gpio-0", | ||
126 | .base = MX51_IO_ADDRESS(MX51_GPIO1_BASE_ADDR), | ||
127 | .irq = MX51_MXC_INT_GPIO1_LOW, | ||
128 | .irq_high = MX51_MXC_INT_GPIO1_HIGH, | ||
129 | .virtual_irq_start = MXC_GPIO_IRQ_START | ||
130 | }, | ||
131 | { | ||
132 | .chip.label = "gpio-1", | ||
133 | .base = MX51_IO_ADDRESS(MX51_GPIO2_BASE_ADDR), | ||
134 | .irq = MX51_MXC_INT_GPIO2_LOW, | ||
135 | .irq_high = MX51_MXC_INT_GPIO2_HIGH, | ||
136 | .virtual_irq_start = MXC_GPIO_IRQ_START + 32 * 1 | ||
137 | }, | ||
138 | { | ||
139 | .chip.label = "gpio-2", | ||
140 | .base = MX51_IO_ADDRESS(MX51_GPIO3_BASE_ADDR), | ||
141 | .irq = MX51_MXC_INT_GPIO3_LOW, | ||
142 | .irq_high = MX51_MXC_INT_GPIO3_HIGH, | ||
143 | .virtual_irq_start = MXC_GPIO_IRQ_START + 32 * 2 | ||
144 | }, | ||
145 | { | ||
146 | .chip.label = "gpio-3", | ||
147 | .base = MX51_IO_ADDRESS(MX51_GPIO4_BASE_ADDR), | ||
148 | .irq = MX51_MXC_INT_GPIO4_LOW, | ||
149 | .irq_high = MX51_MXC_INT_GPIO4_HIGH, | ||
150 | .virtual_irq_start = MXC_GPIO_IRQ_START + 32 * 3 | ||
151 | }, | ||
152 | { | ||
153 | .chip.label = "gpio-4", | ||
154 | .base = MX53_IO_ADDRESS(MX53_GPIO5_BASE_ADDR), | ||
155 | .irq = MX53_INT_GPIO5_LOW, | ||
156 | .irq_high = MX53_INT_GPIO5_HIGH, | ||
157 | .virtual_irq_start = MXC_GPIO_IRQ_START + 32 * 4 | ||
158 | }, | ||
159 | { | ||
160 | .chip.label = "gpio-5", | ||
161 | .base = MX53_IO_ADDRESS(MX53_GPIO6_BASE_ADDR), | ||
162 | .irq = MX53_INT_GPIO6_LOW, | ||
163 | .irq_high = MX53_INT_GPIO6_HIGH, | ||
164 | .virtual_irq_start = MXC_GPIO_IRQ_START + 32 * 5 | ||
165 | }, | ||
166 | { | ||
167 | .chip.label = "gpio-6", | ||
168 | .base = MX53_IO_ADDRESS(MX53_GPIO7_BASE_ADDR), | ||
169 | .irq = MX53_INT_GPIO7_LOW, | ||
170 | .irq_high = MX53_INT_GPIO7_HIGH, | ||
171 | .virtual_irq_start = MXC_GPIO_IRQ_START + 32 * 6 | ||
172 | }, | ||
173 | }; | ||
174 | |||
175 | int __init imx51_register_gpios(void) | ||
176 | { | ||
177 | return mxc_gpio_init(mxc_gpio_ports, 4); | ||
178 | } | ||
179 | |||
180 | int __init imx53_register_gpios(void) | ||
181 | { | ||
182 | return mxc_gpio_init(mxc_gpio_ports, ARRAY_SIZE(mxc_gpio_ports)); | ||
183 | } | ||
184 | |||
diff --git a/arch/arm/mach-mx5/mm-mx50.c b/arch/arm/mach-mx5/mm-mx50.c index b9c363b514a9..77e374c726fa 100644 --- a/arch/arm/mach-mx5/mm-mx50.c +++ b/arch/arm/mach-mx5/mm-mx50.c | |||
@@ -26,7 +26,6 @@ | |||
26 | #include <mach/hardware.h> | 26 | #include <mach/hardware.h> |
27 | #include <mach/common.h> | 27 | #include <mach/common.h> |
28 | #include <mach/iomux-v3.h> | 28 | #include <mach/iomux-v3.h> |
29 | #include <mach/gpio.h> | ||
30 | #include <mach/irqs.h> | 29 | #include <mach/irqs.h> |
31 | 30 | ||
32 | /* | 31 | /* |
@@ -56,17 +55,18 @@ void __init imx50_init_early(void) | |||
56 | mxc_arch_reset_init(MX50_IO_ADDRESS(MX50_WDOG_BASE_ADDR)); | 55 | mxc_arch_reset_init(MX50_IO_ADDRESS(MX50_WDOG_BASE_ADDR)); |
57 | } | 56 | } |
58 | 57 | ||
59 | static struct mxc_gpio_port imx50_gpio_ports[] = { | ||
60 | DEFINE_IMX_GPIO_PORT_IRQ_HIGH(MX50, 0, 1, MX50_INT_GPIO1_LOW, MX50_INT_GPIO1_HIGH), | ||
61 | DEFINE_IMX_GPIO_PORT_IRQ_HIGH(MX50, 1, 2, MX50_INT_GPIO2_LOW, MX50_INT_GPIO2_HIGH), | ||
62 | DEFINE_IMX_GPIO_PORT_IRQ_HIGH(MX50, 2, 3, MX50_INT_GPIO3_LOW, MX50_INT_GPIO3_HIGH), | ||
63 | DEFINE_IMX_GPIO_PORT_IRQ_HIGH(MX50, 3, 4, MX50_INT_GPIO3_LOW, MX50_INT_GPIO3_HIGH), | ||
64 | DEFINE_IMX_GPIO_PORT_IRQ_HIGH(MX50, 4, 5, MX50_INT_GPIO3_LOW, MX50_INT_GPIO3_HIGH), | ||
65 | DEFINE_IMX_GPIO_PORT_IRQ_HIGH(MX50, 5, 6, MX50_INT_GPIO3_LOW, MX50_INT_GPIO3_HIGH), | ||
66 | }; | ||
67 | |||
68 | void __init mx50_init_irq(void) | 58 | void __init mx50_init_irq(void) |
69 | { | 59 | { |
70 | tzic_init_irq(MX50_IO_ADDRESS(MX50_TZIC_BASE_ADDR)); | 60 | tzic_init_irq(MX50_IO_ADDRESS(MX50_TZIC_BASE_ADDR)); |
71 | mxc_gpio_init(imx50_gpio_ports, ARRAY_SIZE(imx50_gpio_ports)); | 61 | } |
62 | |||
63 | void __init imx50_soc_init(void) | ||
64 | { | ||
65 | /* i.mx50 has the i.mx31 type gpio */ | ||
66 | mxc_register_gpio("imx31-gpio", 0, MX50_GPIO1_BASE_ADDR, SZ_16K, MX50_INT_GPIO1_LOW, MX50_INT_GPIO1_HIGH); | ||
67 | mxc_register_gpio("imx31-gpio", 1, MX50_GPIO2_BASE_ADDR, SZ_16K, MX50_INT_GPIO2_LOW, MX50_INT_GPIO2_HIGH); | ||
68 | mxc_register_gpio("imx31-gpio", 2, MX50_GPIO3_BASE_ADDR, SZ_16K, MX50_INT_GPIO3_LOW, MX50_INT_GPIO3_HIGH); | ||
69 | mxc_register_gpio("imx31-gpio", 3, MX50_GPIO4_BASE_ADDR, SZ_16K, MX50_INT_GPIO4_LOW, MX50_INT_GPIO4_HIGH); | ||
70 | mxc_register_gpio("imx31-gpio", 4, MX50_GPIO5_BASE_ADDR, SZ_16K, MX50_INT_GPIO5_LOW, MX50_INT_GPIO5_HIGH); | ||
71 | mxc_register_gpio("imx31-gpio", 5, MX50_GPIO6_BASE_ADDR, SZ_16K, MX50_INT_GPIO6_LOW, MX50_INT_GPIO6_HIGH); | ||
72 | } | 72 | } |
diff --git a/arch/arm/mach-mx5/mm.c b/arch/arm/mach-mx5/mm.c index ff557301b42b..665843d6c2b2 100644 --- a/arch/arm/mach-mx5/mm.c +++ b/arch/arm/mach-mx5/mm.c | |||
@@ -69,8 +69,6 @@ void __init imx53_init_early(void) | |||
69 | mxc_arch_reset_init(MX53_IO_ADDRESS(MX53_WDOG1_BASE_ADDR)); | 69 | mxc_arch_reset_init(MX53_IO_ADDRESS(MX53_WDOG1_BASE_ADDR)); |
70 | } | 70 | } |
71 | 71 | ||
72 | int imx51_register_gpios(void); | ||
73 | |||
74 | void __init mx51_init_irq(void) | 72 | void __init mx51_init_irq(void) |
75 | { | 73 | { |
76 | unsigned long tzic_addr; | 74 | unsigned long tzic_addr; |
@@ -86,11 +84,8 @@ void __init mx51_init_irq(void) | |||
86 | panic("unable to map TZIC interrupt controller\n"); | 84 | panic("unable to map TZIC interrupt controller\n"); |
87 | 85 | ||
88 | tzic_init_irq(tzic_virt); | 86 | tzic_init_irq(tzic_virt); |
89 | imx51_register_gpios(); | ||
90 | } | 87 | } |
91 | 88 | ||
92 | int imx53_register_gpios(void); | ||
93 | |||
94 | void __init mx53_init_irq(void) | 89 | void __init mx53_init_irq(void) |
95 | { | 90 | { |
96 | unsigned long tzic_addr; | 91 | unsigned long tzic_addr; |
@@ -103,5 +98,25 @@ void __init mx53_init_irq(void) | |||
103 | panic("unable to map TZIC interrupt controller\n"); | 98 | panic("unable to map TZIC interrupt controller\n"); |
104 | 99 | ||
105 | tzic_init_irq(tzic_virt); | 100 | tzic_init_irq(tzic_virt); |
106 | imx53_register_gpios(); | 101 | } |
102 | |||
103 | void __init imx51_soc_init(void) | ||
104 | { | ||
105 | /* i.mx51 has the i.mx31 type gpio */ | ||
106 | mxc_register_gpio("imx31-gpio", 0, MX51_GPIO1_BASE_ADDR, SZ_16K, MX51_MXC_INT_GPIO1_LOW, MX51_MXC_INT_GPIO1_HIGH); | ||
107 | mxc_register_gpio("imx31-gpio", 1, MX51_GPIO2_BASE_ADDR, SZ_16K, MX51_MXC_INT_GPIO2_LOW, MX51_MXC_INT_GPIO2_HIGH); | ||
108 | mxc_register_gpio("imx31-gpio", 2, MX51_GPIO3_BASE_ADDR, SZ_16K, MX51_MXC_INT_GPIO3_LOW, MX51_MXC_INT_GPIO3_HIGH); | ||
109 | mxc_register_gpio("imx31-gpio", 3, MX51_GPIO4_BASE_ADDR, SZ_16K, MX51_MXC_INT_GPIO4_LOW, MX51_MXC_INT_GPIO4_HIGH); | ||
110 | } | ||
111 | |||
112 | void __init imx53_soc_init(void) | ||
113 | { | ||
114 | /* i.mx53 has the i.mx31 type gpio */ | ||
115 | mxc_register_gpio("imx31-gpio", 0, MX53_GPIO1_BASE_ADDR, SZ_16K, MX53_INT_GPIO1_LOW, MX53_INT_GPIO1_HIGH); | ||
116 | mxc_register_gpio("imx31-gpio", 1, MX53_GPIO2_BASE_ADDR, SZ_16K, MX53_INT_GPIO2_LOW, MX53_INT_GPIO2_HIGH); | ||
117 | mxc_register_gpio("imx31-gpio", 2, MX53_GPIO3_BASE_ADDR, SZ_16K, MX53_INT_GPIO3_LOW, MX53_INT_GPIO3_HIGH); | ||
118 | mxc_register_gpio("imx31-gpio", 3, MX53_GPIO4_BASE_ADDR, SZ_16K, MX53_INT_GPIO4_LOW, MX53_INT_GPIO4_HIGH); | ||
119 | mxc_register_gpio("imx31-gpio", 4, MX53_GPIO5_BASE_ADDR, SZ_16K, MX53_INT_GPIO5_LOW, MX53_INT_GPIO5_HIGH); | ||
120 | mxc_register_gpio("imx31-gpio", 5, MX53_GPIO6_BASE_ADDR, SZ_16K, MX53_INT_GPIO6_LOW, MX53_INT_GPIO6_HIGH); | ||
121 | mxc_register_gpio("imx31-gpio", 6, MX53_GPIO7_BASE_ADDR, SZ_16K, MX53_INT_GPIO7_LOW, MX53_INT_GPIO7_HIGH); | ||
107 | } | 122 | } |
diff --git a/arch/arm/mach-mxs/Makefile b/arch/arm/mach-mxs/Makefile index 58e892376bf2..6c38262a3aaa 100644 --- a/arch/arm/mach-mxs/Makefile +++ b/arch/arm/mach-mxs/Makefile | |||
@@ -1,5 +1,5 @@ | |||
1 | # Common support | 1 | # Common support |
2 | obj-y := clock.o devices.o gpio.o icoll.o iomux.o system.o timer.o | 2 | obj-y := clock.o devices.o icoll.o iomux.o system.o timer.o |
3 | 3 | ||
4 | obj-$(CONFIG_MXS_OCOTP) += ocotp.o | 4 | obj-$(CONFIG_MXS_OCOTP) += ocotp.o |
5 | obj-$(CONFIG_PM) += pm.o | 5 | obj-$(CONFIG_PM) += pm.o |
diff --git a/arch/arm/mach-mxs/devices.c b/arch/arm/mach-mxs/devices.c index cfdb6b284702..fe3e847930c9 100644 --- a/arch/arm/mach-mxs/devices.c +++ b/arch/arm/mach-mxs/devices.c | |||
@@ -88,3 +88,14 @@ int __init mxs_add_amba_device(const struct amba_device *dev) | |||
88 | 88 | ||
89 | return amba_device_register(adev, &iomem_resource); | 89 | return amba_device_register(adev, &iomem_resource); |
90 | } | 90 | } |
91 | |||
92 | struct device mxs_apbh_bus = { | ||
93 | .init_name = "mxs_apbh", | ||
94 | .parent = &platform_bus, | ||
95 | }; | ||
96 | |||
97 | static int __init mxs_device_init(void) | ||
98 | { | ||
99 | return device_register(&mxs_apbh_bus); | ||
100 | } | ||
101 | core_initcall(mxs_device_init); | ||
diff --git a/arch/arm/mach-mxs/devices/Makefile b/arch/arm/mach-mxs/devices/Makefile index 324f2824d38d..351915c683ff 100644 --- a/arch/arm/mach-mxs/devices/Makefile +++ b/arch/arm/mach-mxs/devices/Makefile | |||
@@ -6,4 +6,5 @@ obj-$(CONFIG_MXS_HAVE_PLATFORM_FLEXCAN) += platform-flexcan.o | |||
6 | obj-$(CONFIG_MXS_HAVE_PLATFORM_MXS_I2C) += platform-mxs-i2c.o | 6 | obj-$(CONFIG_MXS_HAVE_PLATFORM_MXS_I2C) += platform-mxs-i2c.o |
7 | obj-$(CONFIG_MXS_HAVE_PLATFORM_MXS_MMC) += platform-mxs-mmc.o | 7 | obj-$(CONFIG_MXS_HAVE_PLATFORM_MXS_MMC) += platform-mxs-mmc.o |
8 | obj-$(CONFIG_MXS_HAVE_PLATFORM_MXS_PWM) += platform-mxs-pwm.o | 8 | obj-$(CONFIG_MXS_HAVE_PLATFORM_MXS_PWM) += platform-mxs-pwm.o |
9 | obj-y += platform-gpio-mxs.o | ||
9 | obj-$(CONFIG_MXS_HAVE_PLATFORM_MXSFB) += platform-mxsfb.o | 10 | obj-$(CONFIG_MXS_HAVE_PLATFORM_MXSFB) += platform-mxsfb.o |
diff --git a/arch/arm/mach-mxs/devices/platform-gpio-mxs.c b/arch/arm/mach-mxs/devices/platform-gpio-mxs.c new file mode 100644 index 000000000000..ed0885e414e0 --- /dev/null +++ b/arch/arm/mach-mxs/devices/platform-gpio-mxs.c | |||
@@ -0,0 +1,53 @@ | |||
1 | /* | ||
2 | * Copyright 2011 Freescale Semiconductor, Inc. All Rights Reserved. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify it under | ||
5 | * the terms of the GNU General Public License version 2 as published by the | ||
6 | * Free Software Foundation. | ||
7 | */ | ||
8 | #include <linux/compiler.h> | ||
9 | #include <linux/err.h> | ||
10 | #include <linux/init.h> | ||
11 | |||
12 | #include <mach/mx23.h> | ||
13 | #include <mach/mx28.h> | ||
14 | #include <mach/devices-common.h> | ||
15 | |||
16 | struct platform_device *__init mxs_add_gpio( | ||
17 | int id, resource_size_t iobase, int irq) | ||
18 | { | ||
19 | struct resource res[] = { | ||
20 | { | ||
21 | .start = iobase, | ||
22 | .end = iobase + SZ_8K - 1, | ||
23 | .flags = IORESOURCE_MEM, | ||
24 | }, { | ||
25 | .start = irq, | ||
26 | .end = irq, | ||
27 | .flags = IORESOURCE_IRQ, | ||
28 | }, | ||
29 | }; | ||
30 | |||
31 | return platform_device_register_resndata(&mxs_apbh_bus, | ||
32 | "gpio-mxs", id, res, ARRAY_SIZE(res), NULL, 0); | ||
33 | } | ||
34 | |||
35 | static int __init mxs_add_mxs_gpio(void) | ||
36 | { | ||
37 | if (cpu_is_mx23()) { | ||
38 | mxs_add_gpio(0, MX23_PINCTRL_BASE_ADDR, MX23_INT_GPIO0); | ||
39 | mxs_add_gpio(1, MX23_PINCTRL_BASE_ADDR, MX23_INT_GPIO1); | ||
40 | mxs_add_gpio(2, MX23_PINCTRL_BASE_ADDR, MX23_INT_GPIO2); | ||
41 | } | ||
42 | |||
43 | if (cpu_is_mx28()) { | ||
44 | mxs_add_gpio(0, MX28_PINCTRL_BASE_ADDR, MX28_INT_GPIO0); | ||
45 | mxs_add_gpio(1, MX28_PINCTRL_BASE_ADDR, MX28_INT_GPIO1); | ||
46 | mxs_add_gpio(2, MX28_PINCTRL_BASE_ADDR, MX28_INT_GPIO2); | ||
47 | mxs_add_gpio(3, MX28_PINCTRL_BASE_ADDR, MX28_INT_GPIO3); | ||
48 | mxs_add_gpio(4, MX28_PINCTRL_BASE_ADDR, MX28_INT_GPIO4); | ||
49 | } | ||
50 | |||
51 | return 0; | ||
52 | } | ||
53 | postcore_initcall(mxs_add_mxs_gpio); | ||
diff --git a/arch/arm/mach-mxs/gpio.c b/arch/arm/mach-mxs/gpio.c deleted file mode 100644 index 2c950fef71a8..000000000000 --- a/arch/arm/mach-mxs/gpio.c +++ /dev/null | |||
@@ -1,331 +0,0 @@ | |||
1 | /* | ||
2 | * MXC GPIO support. (c) 2008 Daniel Mack <daniel@caiaq.de> | ||
3 | * Copyright 2008 Juergen Beisert, kernel@pengutronix.de | ||
4 | * | ||
5 | * Based on code from Freescale, | ||
6 | * Copyright (C) 2004-2010 Freescale Semiconductor, Inc. All Rights Reserved. | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or | ||
9 | * modify it under the terms of the GNU General Public License | ||
10 | * as published by the Free Software Foundation; either version 2 | ||
11 | * of the License, or (at your option) any later version. | ||
12 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License | ||
18 | * along with this program; if not, write to the Free Software | ||
19 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, | ||
20 | * MA 02110-1301, USA. | ||
21 | */ | ||
22 | |||
23 | #include <linux/init.h> | ||
24 | #include <linux/interrupt.h> | ||
25 | #include <linux/io.h> | ||
26 | #include <linux/irq.h> | ||
27 | #include <linux/gpio.h> | ||
28 | #include <mach/mx23.h> | ||
29 | #include <mach/mx28.h> | ||
30 | #include <asm-generic/bug.h> | ||
31 | |||
32 | #include "gpio.h" | ||
33 | |||
34 | static struct mxs_gpio_port *mxs_gpio_ports; | ||
35 | static int gpio_table_size; | ||
36 | |||
37 | #define PINCTRL_DOUT(n) ((cpu_is_mx23() ? 0x0500 : 0x0700) + (n) * 0x10) | ||
38 | #define PINCTRL_DIN(n) ((cpu_is_mx23() ? 0x0600 : 0x0900) + (n) * 0x10) | ||
39 | #define PINCTRL_DOE(n) ((cpu_is_mx23() ? 0x0700 : 0x0b00) + (n) * 0x10) | ||
40 | #define PINCTRL_PIN2IRQ(n) ((cpu_is_mx23() ? 0x0800 : 0x1000) + (n) * 0x10) | ||
41 | #define PINCTRL_IRQEN(n) ((cpu_is_mx23() ? 0x0900 : 0x1100) + (n) * 0x10) | ||
42 | #define PINCTRL_IRQLEV(n) ((cpu_is_mx23() ? 0x0a00 : 0x1200) + (n) * 0x10) | ||
43 | #define PINCTRL_IRQPOL(n) ((cpu_is_mx23() ? 0x0b00 : 0x1300) + (n) * 0x10) | ||
44 | #define PINCTRL_IRQSTAT(n) ((cpu_is_mx23() ? 0x0c00 : 0x1400) + (n) * 0x10) | ||
45 | |||
46 | #define GPIO_INT_FALL_EDGE 0x0 | ||
47 | #define GPIO_INT_LOW_LEV 0x1 | ||
48 | #define GPIO_INT_RISE_EDGE 0x2 | ||
49 | #define GPIO_INT_HIGH_LEV 0x3 | ||
50 | #define GPIO_INT_LEV_MASK (1 << 0) | ||
51 | #define GPIO_INT_POL_MASK (1 << 1) | ||
52 | |||
53 | /* Note: This driver assumes 32 GPIOs are handled in one register */ | ||
54 | |||
55 | static void clear_gpio_irqstatus(struct mxs_gpio_port *port, u32 index) | ||
56 | { | ||
57 | __mxs_clrl(1 << index, port->base + PINCTRL_IRQSTAT(port->id)); | ||
58 | } | ||
59 | |||
60 | static void set_gpio_irqenable(struct mxs_gpio_port *port, u32 index, | ||
61 | int enable) | ||
62 | { | ||
63 | if (enable) { | ||
64 | __mxs_setl(1 << index, port->base + PINCTRL_IRQEN(port->id)); | ||
65 | __mxs_setl(1 << index, port->base + PINCTRL_PIN2IRQ(port->id)); | ||
66 | } else { | ||
67 | __mxs_clrl(1 << index, port->base + PINCTRL_IRQEN(port->id)); | ||
68 | } | ||
69 | } | ||
70 | |||
71 | static void mxs_gpio_ack_irq(struct irq_data *d) | ||
72 | { | ||
73 | u32 gpio = irq_to_gpio(d->irq); | ||
74 | clear_gpio_irqstatus(&mxs_gpio_ports[gpio / 32], gpio & 0x1f); | ||
75 | } | ||
76 | |||
77 | static void mxs_gpio_mask_irq(struct irq_data *d) | ||
78 | { | ||
79 | u32 gpio = irq_to_gpio(d->irq); | ||
80 | set_gpio_irqenable(&mxs_gpio_ports[gpio / 32], gpio & 0x1f, 0); | ||
81 | } | ||
82 | |||
83 | static void mxs_gpio_unmask_irq(struct irq_data *d) | ||
84 | { | ||
85 | u32 gpio = irq_to_gpio(d->irq); | ||
86 | set_gpio_irqenable(&mxs_gpio_ports[gpio / 32], gpio & 0x1f, 1); | ||
87 | } | ||
88 | |||
89 | static int mxs_gpio_get(struct gpio_chip *chip, unsigned offset); | ||
90 | |||
91 | static int mxs_gpio_set_irq_type(struct irq_data *d, unsigned int type) | ||
92 | { | ||
93 | u32 gpio = irq_to_gpio(d->irq); | ||
94 | u32 pin_mask = 1 << (gpio & 31); | ||
95 | struct mxs_gpio_port *port = &mxs_gpio_ports[gpio / 32]; | ||
96 | void __iomem *pin_addr; | ||
97 | int edge; | ||
98 | |||
99 | switch (type) { | ||
100 | case IRQ_TYPE_EDGE_RISING: | ||
101 | edge = GPIO_INT_RISE_EDGE; | ||
102 | break; | ||
103 | case IRQ_TYPE_EDGE_FALLING: | ||
104 | edge = GPIO_INT_FALL_EDGE; | ||
105 | break; | ||
106 | case IRQ_TYPE_LEVEL_LOW: | ||
107 | edge = GPIO_INT_LOW_LEV; | ||
108 | break; | ||
109 | case IRQ_TYPE_LEVEL_HIGH: | ||
110 | edge = GPIO_INT_HIGH_LEV; | ||
111 | break; | ||
112 | default: | ||
113 | return -EINVAL; | ||
114 | } | ||
115 | |||
116 | /* set level or edge */ | ||
117 | pin_addr = port->base + PINCTRL_IRQLEV(port->id); | ||
118 | if (edge & GPIO_INT_LEV_MASK) | ||
119 | __mxs_setl(pin_mask, pin_addr); | ||
120 | else | ||
121 | __mxs_clrl(pin_mask, pin_addr); | ||
122 | |||
123 | /* set polarity */ | ||
124 | pin_addr = port->base + PINCTRL_IRQPOL(port->id); | ||
125 | if (edge & GPIO_INT_POL_MASK) | ||
126 | __mxs_setl(pin_mask, pin_addr); | ||
127 | else | ||
128 | __mxs_clrl(pin_mask, pin_addr); | ||
129 | |||
130 | clear_gpio_irqstatus(port, gpio & 0x1f); | ||
131 | |||
132 | return 0; | ||
133 | } | ||
134 | |||
135 | /* MXS has one interrupt *per* gpio port */ | ||
136 | static void mxs_gpio_irq_handler(u32 irq, struct irq_desc *desc) | ||
137 | { | ||
138 | u32 irq_stat; | ||
139 | struct mxs_gpio_port *port = (struct mxs_gpio_port *)irq_get_handler_data(irq); | ||
140 | u32 gpio_irq_no_base = port->virtual_irq_start; | ||
141 | |||
142 | desc->irq_data.chip->irq_ack(&desc->irq_data); | ||
143 | |||
144 | irq_stat = __raw_readl(port->base + PINCTRL_IRQSTAT(port->id)) & | ||
145 | __raw_readl(port->base + PINCTRL_IRQEN(port->id)); | ||
146 | |||
147 | while (irq_stat != 0) { | ||
148 | int irqoffset = fls(irq_stat) - 1; | ||
149 | generic_handle_irq(gpio_irq_no_base + irqoffset); | ||
150 | irq_stat &= ~(1 << irqoffset); | ||
151 | } | ||
152 | } | ||
153 | |||
154 | /* | ||
155 | * Set interrupt number "irq" in the GPIO as a wake-up source. | ||
156 | * While system is running, all registered GPIO interrupts need to have | ||
157 | * wake-up enabled. When system is suspended, only selected GPIO interrupts | ||
158 | * need to have wake-up enabled. | ||
159 | * @param irq interrupt source number | ||
160 | * @param enable enable as wake-up if equal to non-zero | ||
161 | * @return This function returns 0 on success. | ||
162 | */ | ||
163 | static int mxs_gpio_set_wake_irq(struct irq_data *d, unsigned int enable) | ||
164 | { | ||
165 | u32 gpio = irq_to_gpio(d->irq); | ||
166 | u32 gpio_idx = gpio & 0x1f; | ||
167 | struct mxs_gpio_port *port = &mxs_gpio_ports[gpio / 32]; | ||
168 | |||
169 | if (enable) { | ||
170 | if (port->irq_high && (gpio_idx >= 16)) | ||
171 | enable_irq_wake(port->irq_high); | ||
172 | else | ||
173 | enable_irq_wake(port->irq); | ||
174 | } else { | ||
175 | if (port->irq_high && (gpio_idx >= 16)) | ||
176 | disable_irq_wake(port->irq_high); | ||
177 | else | ||
178 | disable_irq_wake(port->irq); | ||
179 | } | ||
180 | |||
181 | return 0; | ||
182 | } | ||
183 | |||
184 | static struct irq_chip gpio_irq_chip = { | ||
185 | .name = "mxs gpio", | ||
186 | .irq_ack = mxs_gpio_ack_irq, | ||
187 | .irq_mask = mxs_gpio_mask_irq, | ||
188 | .irq_unmask = mxs_gpio_unmask_irq, | ||
189 | .irq_set_type = mxs_gpio_set_irq_type, | ||
190 | .irq_set_wake = mxs_gpio_set_wake_irq, | ||
191 | }; | ||
192 | |||
193 | static void mxs_set_gpio_direction(struct gpio_chip *chip, unsigned offset, | ||
194 | int dir) | ||
195 | { | ||
196 | struct mxs_gpio_port *port = | ||
197 | container_of(chip, struct mxs_gpio_port, chip); | ||
198 | void __iomem *pin_addr = port->base + PINCTRL_DOE(port->id); | ||
199 | |||
200 | if (dir) | ||
201 | __mxs_setl(1 << offset, pin_addr); | ||
202 | else | ||
203 | __mxs_clrl(1 << offset, pin_addr); | ||
204 | } | ||
205 | |||
206 | static int mxs_gpio_get(struct gpio_chip *chip, unsigned offset) | ||
207 | { | ||
208 | struct mxs_gpio_port *port = | ||
209 | container_of(chip, struct mxs_gpio_port, chip); | ||
210 | |||
211 | return (__raw_readl(port->base + PINCTRL_DIN(port->id)) >> offset) & 1; | ||
212 | } | ||
213 | |||
214 | static void mxs_gpio_set(struct gpio_chip *chip, unsigned offset, int value) | ||
215 | { | ||
216 | struct mxs_gpio_port *port = | ||
217 | container_of(chip, struct mxs_gpio_port, chip); | ||
218 | void __iomem *pin_addr = port->base + PINCTRL_DOUT(port->id); | ||
219 | |||
220 | if (value) | ||
221 | __mxs_setl(1 << offset, pin_addr); | ||
222 | else | ||
223 | __mxs_clrl(1 << offset, pin_addr); | ||
224 | } | ||
225 | |||
226 | static int mxs_gpio_to_irq(struct gpio_chip *chip, unsigned offset) | ||
227 | { | ||
228 | struct mxs_gpio_port *port = | ||
229 | container_of(chip, struct mxs_gpio_port, chip); | ||
230 | |||
231 | return port->virtual_irq_start + offset; | ||
232 | } | ||
233 | |||
234 | static int mxs_gpio_direction_input(struct gpio_chip *chip, unsigned offset) | ||
235 | { | ||
236 | mxs_set_gpio_direction(chip, offset, 0); | ||
237 | return 0; | ||
238 | } | ||
239 | |||
240 | static int mxs_gpio_direction_output(struct gpio_chip *chip, | ||
241 | unsigned offset, int value) | ||
242 | { | ||
243 | mxs_gpio_set(chip, offset, value); | ||
244 | mxs_set_gpio_direction(chip, offset, 1); | ||
245 | return 0; | ||
246 | } | ||
247 | |||
248 | int __init mxs_gpio_init(struct mxs_gpio_port *port, int cnt) | ||
249 | { | ||
250 | int i, j; | ||
251 | |||
252 | /* save for local usage */ | ||
253 | mxs_gpio_ports = port; | ||
254 | gpio_table_size = cnt; | ||
255 | |||
256 | pr_info("MXS GPIO hardware\n"); | ||
257 | |||
258 | for (i = 0; i < cnt; i++) { | ||
259 | /* disable the interrupt and clear the status */ | ||
260 | __raw_writel(0, port[i].base + PINCTRL_PIN2IRQ(i)); | ||
261 | __raw_writel(0, port[i].base + PINCTRL_IRQEN(i)); | ||
262 | |||
263 | /* clear address has to be used to clear IRQSTAT bits */ | ||
264 | __mxs_clrl(~0U, port[i].base + PINCTRL_IRQSTAT(i)); | ||
265 | |||
266 | for (j = port[i].virtual_irq_start; | ||
267 | j < port[i].virtual_irq_start + 32; j++) { | ||
268 | irq_set_chip_and_handler(j, &gpio_irq_chip, | ||
269 | handle_level_irq); | ||
270 | set_irq_flags(j, IRQF_VALID); | ||
271 | } | ||
272 | |||
273 | /* setup one handler for each entry */ | ||
274 | irq_set_chained_handler(port[i].irq, mxs_gpio_irq_handler); | ||
275 | irq_set_handler_data(port[i].irq, &port[i]); | ||
276 | |||
277 | /* register gpio chip */ | ||
278 | port[i].chip.direction_input = mxs_gpio_direction_input; | ||
279 | port[i].chip.direction_output = mxs_gpio_direction_output; | ||
280 | port[i].chip.get = mxs_gpio_get; | ||
281 | port[i].chip.set = mxs_gpio_set; | ||
282 | port[i].chip.to_irq = mxs_gpio_to_irq; | ||
283 | port[i].chip.base = i * 32; | ||
284 | port[i].chip.ngpio = 32; | ||
285 | |||
286 | /* its a serious configuration bug when it fails */ | ||
287 | BUG_ON(gpiochip_add(&port[i].chip) < 0); | ||
288 | } | ||
289 | |||
290 | return 0; | ||
291 | } | ||
292 | |||
293 | #define MX23_GPIO_BASE MX23_IO_ADDRESS(MX23_PINCTRL_BASE_ADDR) | ||
294 | #define MX28_GPIO_BASE MX28_IO_ADDRESS(MX28_PINCTRL_BASE_ADDR) | ||
295 | |||
296 | #define DEFINE_MXS_GPIO_PORT(_base, _irq, _id) \ | ||
297 | { \ | ||
298 | .chip.label = "gpio-" #_id, \ | ||
299 | .id = _id, \ | ||
300 | .irq = _irq, \ | ||
301 | .base = _base, \ | ||
302 | .virtual_irq_start = MXS_GPIO_IRQ_START + (_id) * 32, \ | ||
303 | } | ||
304 | |||
305 | #ifdef CONFIG_SOC_IMX23 | ||
306 | static struct mxs_gpio_port mx23_gpio_ports[] = { | ||
307 | DEFINE_MXS_GPIO_PORT(MX23_GPIO_BASE, MX23_INT_GPIO0, 0), | ||
308 | DEFINE_MXS_GPIO_PORT(MX23_GPIO_BASE, MX23_INT_GPIO1, 1), | ||
309 | DEFINE_MXS_GPIO_PORT(MX23_GPIO_BASE, MX23_INT_GPIO2, 2), | ||
310 | }; | ||
311 | |||
312 | int __init mx23_register_gpios(void) | ||
313 | { | ||
314 | return mxs_gpio_init(mx23_gpio_ports, ARRAY_SIZE(mx23_gpio_ports)); | ||
315 | } | ||
316 | #endif | ||
317 | |||
318 | #ifdef CONFIG_SOC_IMX28 | ||
319 | static struct mxs_gpio_port mx28_gpio_ports[] = { | ||
320 | DEFINE_MXS_GPIO_PORT(MX28_GPIO_BASE, MX28_INT_GPIO0, 0), | ||
321 | DEFINE_MXS_GPIO_PORT(MX28_GPIO_BASE, MX28_INT_GPIO1, 1), | ||
322 | DEFINE_MXS_GPIO_PORT(MX28_GPIO_BASE, MX28_INT_GPIO2, 2), | ||
323 | DEFINE_MXS_GPIO_PORT(MX28_GPIO_BASE, MX28_INT_GPIO3, 3), | ||
324 | DEFINE_MXS_GPIO_PORT(MX28_GPIO_BASE, MX28_INT_GPIO4, 4), | ||
325 | }; | ||
326 | |||
327 | int __init mx28_register_gpios(void) | ||
328 | { | ||
329 | return mxs_gpio_init(mx28_gpio_ports, ARRAY_SIZE(mx28_gpio_ports)); | ||
330 | } | ||
331 | #endif | ||
diff --git a/arch/arm/mach-mxs/gpio.h b/arch/arm/mach-mxs/gpio.h deleted file mode 100644 index 005bb06630b1..000000000000 --- a/arch/arm/mach-mxs/gpio.h +++ /dev/null | |||
@@ -1,34 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright 2007 Freescale Semiconductor, Inc. All Rights Reserved. | ||
3 | * Copyright 2008 Juergen Beisert, kernel@pengutronix.de | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or | ||
6 | * modify it under the terms of the GNU General Public License | ||
7 | * as published by the Free Software Foundation; either version 2 | ||
8 | * of the License, or (at your option) any later version. | ||
9 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License | ||
15 | * along with this program; if not, write to the Free Software | ||
16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, | ||
17 | * MA 02110-1301, USA. | ||
18 | */ | ||
19 | |||
20 | #ifndef __MXS_GPIO_H__ | ||
21 | #define __MXS_GPIO_H__ | ||
22 | |||
23 | struct mxs_gpio_port { | ||
24 | void __iomem *base; | ||
25 | int id; | ||
26 | int irq; | ||
27 | int irq_high; | ||
28 | int virtual_irq_start; | ||
29 | struct gpio_chip chip; | ||
30 | }; | ||
31 | |||
32 | int mxs_gpio_init(struct mxs_gpio_port*, int); | ||
33 | |||
34 | #endif /* __MXS_GPIO_H__ */ | ||
diff --git a/arch/arm/mach-mxs/include/mach/devices-common.h b/arch/arm/mach-mxs/include/mach/devices-common.h index 7a37469ed5bf..812d7a813a78 100644 --- a/arch/arm/mach-mxs/include/mach/devices-common.h +++ b/arch/arm/mach-mxs/include/mach/devices-common.h | |||
@@ -11,6 +11,8 @@ | |||
11 | #include <linux/init.h> | 11 | #include <linux/init.h> |
12 | #include <linux/amba/bus.h> | 12 | #include <linux/amba/bus.h> |
13 | 13 | ||
14 | extern struct device mxs_apbh_bus; | ||
15 | |||
14 | struct platform_device *mxs_add_platform_device_dmamask( | 16 | struct platform_device *mxs_add_platform_device_dmamask( |
15 | const char *name, int id, | 17 | const char *name, int id, |
16 | const struct resource *res, unsigned int num_resources, | 18 | const struct resource *res, unsigned int num_resources, |
diff --git a/arch/arm/mach-mxs/mach-mx28evk.c b/arch/arm/mach-mxs/mach-mx28evk.c index eacdc6b0e70a..56767a5cce0e 100644 --- a/arch/arm/mach-mxs/mach-mx28evk.c +++ b/arch/arm/mach-mxs/mach-mx28evk.c | |||
@@ -26,7 +26,6 @@ | |||
26 | #include <mach/iomux-mx28.h> | 26 | #include <mach/iomux-mx28.h> |
27 | 27 | ||
28 | #include "devices-mx28.h" | 28 | #include "devices-mx28.h" |
29 | #include "gpio.h" | ||
30 | 29 | ||
31 | #define MX28EVK_FLEXCAN_SWITCH MXS_GPIO_NR(2, 13) | 30 | #define MX28EVK_FLEXCAN_SWITCH MXS_GPIO_NR(2, 13) |
32 | #define MX28EVK_FEC_PHY_POWER MXS_GPIO_NR(2, 15) | 31 | #define MX28EVK_FEC_PHY_POWER MXS_GPIO_NR(2, 15) |
diff --git a/arch/arm/mach-mxs/mm-mx23.c b/arch/arm/mach-mxs/mm-mx23.c index 5148cd64a6b7..1b2345ac1a87 100644 --- a/arch/arm/mach-mxs/mm-mx23.c +++ b/arch/arm/mach-mxs/mm-mx23.c | |||
@@ -41,5 +41,4 @@ void __init mx23_map_io(void) | |||
41 | void __init mx23_init_irq(void) | 41 | void __init mx23_init_irq(void) |
42 | { | 42 | { |
43 | icoll_init_irq(); | 43 | icoll_init_irq(); |
44 | mx23_register_gpios(); | ||
45 | } | 44 | } |
diff --git a/arch/arm/mach-mxs/mm-mx28.c b/arch/arm/mach-mxs/mm-mx28.c index 7e4cea32ebc6..b6e18ddb92c0 100644 --- a/arch/arm/mach-mxs/mm-mx28.c +++ b/arch/arm/mach-mxs/mm-mx28.c | |||
@@ -41,5 +41,4 @@ void __init mx28_map_io(void) | |||
41 | void __init mx28_init_irq(void) | 41 | void __init mx28_init_irq(void) |
42 | { | 42 | { |
43 | icoll_init_irq(); | 43 | icoll_init_irq(); |
44 | mx28_register_gpios(); | ||
45 | } | 44 | } |
diff --git a/arch/arm/mach-omap1/gpio15xx.c b/arch/arm/mach-omap1/gpio15xx.c index 364137c2042c..399da4ce017b 100644 --- a/arch/arm/mach-omap1/gpio15xx.c +++ b/arch/arm/mach-omap1/gpio15xx.c | |||
@@ -34,11 +34,22 @@ static struct __initdata resource omap15xx_mpu_gpio_resources[] = { | |||
34 | }, | 34 | }, |
35 | }; | 35 | }; |
36 | 36 | ||
37 | static struct omap_gpio_reg_offs omap15xx_mpuio_regs = { | ||
38 | .revision = USHRT_MAX, | ||
39 | .direction = OMAP_MPUIO_IO_CNTL, | ||
40 | .datain = OMAP_MPUIO_INPUT_LATCH, | ||
41 | .dataout = OMAP_MPUIO_OUTPUT, | ||
42 | .irqstatus = OMAP_MPUIO_GPIO_INT, | ||
43 | .irqenable = OMAP_MPUIO_GPIO_MASKIT, | ||
44 | .irqenable_inv = true, | ||
45 | }; | ||
46 | |||
37 | static struct __initdata omap_gpio_platform_data omap15xx_mpu_gpio_config = { | 47 | static struct __initdata omap_gpio_platform_data omap15xx_mpu_gpio_config = { |
38 | .virtual_irq_start = IH_MPUIO_BASE, | 48 | .virtual_irq_start = IH_MPUIO_BASE, |
39 | .bank_type = METHOD_MPUIO, | 49 | .bank_type = METHOD_MPUIO, |
40 | .bank_width = 16, | 50 | .bank_width = 16, |
41 | .bank_stride = 1, | 51 | .bank_stride = 1, |
52 | .regs = &omap15xx_mpuio_regs, | ||
42 | }; | 53 | }; |
43 | 54 | ||
44 | static struct platform_device omap15xx_mpu_gpio = { | 55 | static struct platform_device omap15xx_mpu_gpio = { |
@@ -64,10 +75,21 @@ static struct __initdata resource omap15xx_gpio_resources[] = { | |||
64 | }, | 75 | }, |
65 | }; | 76 | }; |
66 | 77 | ||
78 | static struct omap_gpio_reg_offs omap15xx_gpio_regs = { | ||
79 | .revision = USHRT_MAX, | ||
80 | .direction = OMAP1510_GPIO_DIR_CONTROL, | ||
81 | .datain = OMAP1510_GPIO_DATA_INPUT, | ||
82 | .dataout = OMAP1510_GPIO_DATA_OUTPUT, | ||
83 | .irqstatus = OMAP1510_GPIO_INT_STATUS, | ||
84 | .irqenable = OMAP1510_GPIO_INT_MASK, | ||
85 | .irqenable_inv = true, | ||
86 | }; | ||
87 | |||
67 | static struct __initdata omap_gpio_platform_data omap15xx_gpio_config = { | 88 | static struct __initdata omap_gpio_platform_data omap15xx_gpio_config = { |
68 | .virtual_irq_start = IH_GPIO_BASE, | 89 | .virtual_irq_start = IH_GPIO_BASE, |
69 | .bank_type = METHOD_GPIO_1510, | 90 | .bank_type = METHOD_GPIO_1510, |
70 | .bank_width = 16, | 91 | .bank_width = 16, |
92 | .regs = &omap15xx_gpio_regs, | ||
71 | }; | 93 | }; |
72 | 94 | ||
73 | static struct platform_device omap15xx_gpio = { | 95 | static struct platform_device omap15xx_gpio = { |
diff --git a/arch/arm/mach-omap1/gpio16xx.c b/arch/arm/mach-omap1/gpio16xx.c index 293a246e2824..0f399bd0e70e 100644 --- a/arch/arm/mach-omap1/gpio16xx.c +++ b/arch/arm/mach-omap1/gpio16xx.c | |||
@@ -37,11 +37,22 @@ static struct __initdata resource omap16xx_mpu_gpio_resources[] = { | |||
37 | }, | 37 | }, |
38 | }; | 38 | }; |
39 | 39 | ||
40 | static struct omap_gpio_reg_offs omap16xx_mpuio_regs = { | ||
41 | .revision = USHRT_MAX, | ||
42 | .direction = OMAP_MPUIO_IO_CNTL, | ||
43 | .datain = OMAP_MPUIO_INPUT_LATCH, | ||
44 | .dataout = OMAP_MPUIO_OUTPUT, | ||
45 | .irqstatus = OMAP_MPUIO_GPIO_INT, | ||
46 | .irqenable = OMAP_MPUIO_GPIO_MASKIT, | ||
47 | .irqenable_inv = true, | ||
48 | }; | ||
49 | |||
40 | static struct __initdata omap_gpio_platform_data omap16xx_mpu_gpio_config = { | 50 | static struct __initdata omap_gpio_platform_data omap16xx_mpu_gpio_config = { |
41 | .virtual_irq_start = IH_MPUIO_BASE, | 51 | .virtual_irq_start = IH_MPUIO_BASE, |
42 | .bank_type = METHOD_MPUIO, | 52 | .bank_type = METHOD_MPUIO, |
43 | .bank_width = 16, | 53 | .bank_width = 16, |
44 | .bank_stride = 1, | 54 | .bank_stride = 1, |
55 | .regs = &omap16xx_mpuio_regs, | ||
45 | }; | 56 | }; |
46 | 57 | ||
47 | static struct platform_device omap16xx_mpu_gpio = { | 58 | static struct platform_device omap16xx_mpu_gpio = { |
@@ -67,10 +78,24 @@ static struct __initdata resource omap16xx_gpio1_resources[] = { | |||
67 | }, | 78 | }, |
68 | }; | 79 | }; |
69 | 80 | ||
81 | static struct omap_gpio_reg_offs omap16xx_gpio_regs = { | ||
82 | .revision = OMAP1610_GPIO_REVISION, | ||
83 | .direction = OMAP1610_GPIO_DIRECTION, | ||
84 | .set_dataout = OMAP1610_GPIO_SET_DATAOUT, | ||
85 | .clr_dataout = OMAP1610_GPIO_CLEAR_DATAOUT, | ||
86 | .datain = OMAP1610_GPIO_DATAIN, | ||
87 | .dataout = OMAP1610_GPIO_DATAOUT, | ||
88 | .irqstatus = OMAP1610_GPIO_IRQSTATUS1, | ||
89 | .irqenable = OMAP1610_GPIO_IRQENABLE1, | ||
90 | .set_irqenable = OMAP1610_GPIO_SET_IRQENABLE1, | ||
91 | .clr_irqenable = OMAP1610_GPIO_CLEAR_IRQENABLE1, | ||
92 | }; | ||
93 | |||
70 | static struct __initdata omap_gpio_platform_data omap16xx_gpio1_config = { | 94 | static struct __initdata omap_gpio_platform_data omap16xx_gpio1_config = { |
71 | .virtual_irq_start = IH_GPIO_BASE, | 95 | .virtual_irq_start = IH_GPIO_BASE, |
72 | .bank_type = METHOD_GPIO_1610, | 96 | .bank_type = METHOD_GPIO_1610, |
73 | .bank_width = 16, | 97 | .bank_width = 16, |
98 | .regs = &omap16xx_gpio_regs, | ||
74 | }; | 99 | }; |
75 | 100 | ||
76 | static struct platform_device omap16xx_gpio1 = { | 101 | static struct platform_device omap16xx_gpio1 = { |
@@ -100,6 +125,7 @@ static struct __initdata omap_gpio_platform_data omap16xx_gpio2_config = { | |||
100 | .virtual_irq_start = IH_GPIO_BASE + 16, | 125 | .virtual_irq_start = IH_GPIO_BASE + 16, |
101 | .bank_type = METHOD_GPIO_1610, | 126 | .bank_type = METHOD_GPIO_1610, |
102 | .bank_width = 16, | 127 | .bank_width = 16, |
128 | .regs = &omap16xx_gpio_regs, | ||
103 | }; | 129 | }; |
104 | 130 | ||
105 | static struct platform_device omap16xx_gpio2 = { | 131 | static struct platform_device omap16xx_gpio2 = { |
@@ -129,6 +155,7 @@ static struct __initdata omap_gpio_platform_data omap16xx_gpio3_config = { | |||
129 | .virtual_irq_start = IH_GPIO_BASE + 32, | 155 | .virtual_irq_start = IH_GPIO_BASE + 32, |
130 | .bank_type = METHOD_GPIO_1610, | 156 | .bank_type = METHOD_GPIO_1610, |
131 | .bank_width = 16, | 157 | .bank_width = 16, |
158 | .regs = &omap16xx_gpio_regs, | ||
132 | }; | 159 | }; |
133 | 160 | ||
134 | static struct platform_device omap16xx_gpio3 = { | 161 | static struct platform_device omap16xx_gpio3 = { |
@@ -158,6 +185,7 @@ static struct __initdata omap_gpio_platform_data omap16xx_gpio4_config = { | |||
158 | .virtual_irq_start = IH_GPIO_BASE + 48, | 185 | .virtual_irq_start = IH_GPIO_BASE + 48, |
159 | .bank_type = METHOD_GPIO_1610, | 186 | .bank_type = METHOD_GPIO_1610, |
160 | .bank_width = 16, | 187 | .bank_width = 16, |
188 | .regs = &omap16xx_gpio_regs, | ||
161 | }; | 189 | }; |
162 | 190 | ||
163 | static struct platform_device omap16xx_gpio4 = { | 191 | static struct platform_device omap16xx_gpio4 = { |
diff --git a/arch/arm/mach-omap1/gpio7xx.c b/arch/arm/mach-omap1/gpio7xx.c index c6ad248d63a6..5ab63eab0ff5 100644 --- a/arch/arm/mach-omap1/gpio7xx.c +++ b/arch/arm/mach-omap1/gpio7xx.c | |||
@@ -39,11 +39,22 @@ static struct __initdata resource omap7xx_mpu_gpio_resources[] = { | |||
39 | }, | 39 | }, |
40 | }; | 40 | }; |
41 | 41 | ||
42 | static struct omap_gpio_reg_offs omap7xx_mpuio_regs = { | ||
43 | .revision = USHRT_MAX, | ||
44 | .direction = OMAP_MPUIO_IO_CNTL / 2, | ||
45 | .datain = OMAP_MPUIO_INPUT_LATCH / 2, | ||
46 | .dataout = OMAP_MPUIO_OUTPUT / 2, | ||
47 | .irqstatus = OMAP_MPUIO_GPIO_INT / 2, | ||
48 | .irqenable = OMAP_MPUIO_GPIO_MASKIT / 2, | ||
49 | .irqenable_inv = true, | ||
50 | }; | ||
51 | |||
42 | static struct __initdata omap_gpio_platform_data omap7xx_mpu_gpio_config = { | 52 | static struct __initdata omap_gpio_platform_data omap7xx_mpu_gpio_config = { |
43 | .virtual_irq_start = IH_MPUIO_BASE, | 53 | .virtual_irq_start = IH_MPUIO_BASE, |
44 | .bank_type = METHOD_MPUIO, | 54 | .bank_type = METHOD_MPUIO, |
45 | .bank_width = 32, | 55 | .bank_width = 32, |
46 | .bank_stride = 2, | 56 | .bank_stride = 2, |
57 | .regs = &omap7xx_mpuio_regs, | ||
47 | }; | 58 | }; |
48 | 59 | ||
49 | static struct platform_device omap7xx_mpu_gpio = { | 60 | static struct platform_device omap7xx_mpu_gpio = { |
@@ -69,10 +80,21 @@ static struct __initdata resource omap7xx_gpio1_resources[] = { | |||
69 | }, | 80 | }, |
70 | }; | 81 | }; |
71 | 82 | ||
83 | static struct omap_gpio_reg_offs omap7xx_gpio_regs = { | ||
84 | .revision = USHRT_MAX, | ||
85 | .direction = OMAP7XX_GPIO_DIR_CONTROL, | ||
86 | .datain = OMAP7XX_GPIO_DATA_INPUT, | ||
87 | .dataout = OMAP7XX_GPIO_DATA_OUTPUT, | ||
88 | .irqstatus = OMAP7XX_GPIO_INT_STATUS, | ||
89 | .irqenable = OMAP7XX_GPIO_INT_MASK, | ||
90 | .irqenable_inv = true, | ||
91 | }; | ||
92 | |||
72 | static struct __initdata omap_gpio_platform_data omap7xx_gpio1_config = { | 93 | static struct __initdata omap_gpio_platform_data omap7xx_gpio1_config = { |
73 | .virtual_irq_start = IH_GPIO_BASE, | 94 | .virtual_irq_start = IH_GPIO_BASE, |
74 | .bank_type = METHOD_GPIO_7XX, | 95 | .bank_type = METHOD_GPIO_7XX, |
75 | .bank_width = 32, | 96 | .bank_width = 32, |
97 | .regs = &omap7xx_gpio_regs, | ||
76 | }; | 98 | }; |
77 | 99 | ||
78 | static struct platform_device omap7xx_gpio1 = { | 100 | static struct platform_device omap7xx_gpio1 = { |
@@ -102,6 +124,7 @@ static struct __initdata omap_gpio_platform_data omap7xx_gpio2_config = { | |||
102 | .virtual_irq_start = IH_GPIO_BASE + 32, | 124 | .virtual_irq_start = IH_GPIO_BASE + 32, |
103 | .bank_type = METHOD_GPIO_7XX, | 125 | .bank_type = METHOD_GPIO_7XX, |
104 | .bank_width = 32, | 126 | .bank_width = 32, |
127 | .regs = &omap7xx_gpio_regs, | ||
105 | }; | 128 | }; |
106 | 129 | ||
107 | static struct platform_device omap7xx_gpio2 = { | 130 | static struct platform_device omap7xx_gpio2 = { |
@@ -131,6 +154,7 @@ static struct __initdata omap_gpio_platform_data omap7xx_gpio3_config = { | |||
131 | .virtual_irq_start = IH_GPIO_BASE + 64, | 154 | .virtual_irq_start = IH_GPIO_BASE + 64, |
132 | .bank_type = METHOD_GPIO_7XX, | 155 | .bank_type = METHOD_GPIO_7XX, |
133 | .bank_width = 32, | 156 | .bank_width = 32, |
157 | .regs = &omap7xx_gpio_regs, | ||
134 | }; | 158 | }; |
135 | 159 | ||
136 | static struct platform_device omap7xx_gpio3 = { | 160 | static struct platform_device omap7xx_gpio3 = { |
@@ -160,6 +184,7 @@ static struct __initdata omap_gpio_platform_data omap7xx_gpio4_config = { | |||
160 | .virtual_irq_start = IH_GPIO_BASE + 96, | 184 | .virtual_irq_start = IH_GPIO_BASE + 96, |
161 | .bank_type = METHOD_GPIO_7XX, | 185 | .bank_type = METHOD_GPIO_7XX, |
162 | .bank_width = 32, | 186 | .bank_width = 32, |
187 | .regs = &omap7xx_gpio_regs, | ||
163 | }; | 188 | }; |
164 | 189 | ||
165 | static struct platform_device omap7xx_gpio4 = { | 190 | static struct platform_device omap7xx_gpio4 = { |
@@ -189,6 +214,7 @@ static struct __initdata omap_gpio_platform_data omap7xx_gpio5_config = { | |||
189 | .virtual_irq_start = IH_GPIO_BASE + 128, | 214 | .virtual_irq_start = IH_GPIO_BASE + 128, |
190 | .bank_type = METHOD_GPIO_7XX, | 215 | .bank_type = METHOD_GPIO_7XX, |
191 | .bank_width = 32, | 216 | .bank_width = 32, |
217 | .regs = &omap7xx_gpio_regs, | ||
192 | }; | 218 | }; |
193 | 219 | ||
194 | static struct platform_device omap7xx_gpio5 = { | 220 | static struct platform_device omap7xx_gpio5 = { |
@@ -218,6 +244,7 @@ static struct __initdata omap_gpio_platform_data omap7xx_gpio6_config = { | |||
218 | .virtual_irq_start = IH_GPIO_BASE + 160, | 244 | .virtual_irq_start = IH_GPIO_BASE + 160, |
219 | .bank_type = METHOD_GPIO_7XX, | 245 | .bank_type = METHOD_GPIO_7XX, |
220 | .bank_width = 32, | 246 | .bank_width = 32, |
247 | .regs = &omap7xx_gpio_regs, | ||
221 | }; | 248 | }; |
222 | 249 | ||
223 | static struct platform_device omap7xx_gpio6 = { | 250 | static struct platform_device omap7xx_gpio6 = { |
diff --git a/arch/arm/mach-omap2/gpio.c b/arch/arm/mach-omap2/gpio.c index 9529842ae054..9a46d7773a48 100644 --- a/arch/arm/mach-omap2/gpio.c +++ b/arch/arm/mach-omap2/gpio.c | |||
@@ -61,13 +61,45 @@ static int omap2_gpio_dev_init(struct omap_hwmod *oh, void *unused) | |||
61 | pdata->dbck_flag = dev_attr->dbck_flag; | 61 | pdata->dbck_flag = dev_attr->dbck_flag; |
62 | pdata->virtual_irq_start = IH_GPIO_BASE + 32 * (id - 1); | 62 | pdata->virtual_irq_start = IH_GPIO_BASE + 32 * (id - 1); |
63 | 63 | ||
64 | pdata->regs = kzalloc(sizeof(struct omap_gpio_reg_offs), GFP_KERNEL); | ||
65 | if (!pdata) { | ||
66 | pr_err("gpio%d: Memory allocation failed\n", id); | ||
67 | return -ENOMEM; | ||
68 | } | ||
69 | |||
64 | switch (oh->class->rev) { | 70 | switch (oh->class->rev) { |
65 | case 0: | 71 | case 0: |
66 | case 1: | 72 | case 1: |
67 | pdata->bank_type = METHOD_GPIO_24XX; | 73 | pdata->bank_type = METHOD_GPIO_24XX; |
74 | pdata->regs->revision = OMAP24XX_GPIO_REVISION; | ||
75 | pdata->regs->direction = OMAP24XX_GPIO_OE; | ||
76 | pdata->regs->datain = OMAP24XX_GPIO_DATAIN; | ||
77 | pdata->regs->dataout = OMAP24XX_GPIO_DATAOUT; | ||
78 | pdata->regs->set_dataout = OMAP24XX_GPIO_SETDATAOUT; | ||
79 | pdata->regs->clr_dataout = OMAP24XX_GPIO_CLEARDATAOUT; | ||
80 | pdata->regs->irqstatus = OMAP24XX_GPIO_IRQSTATUS1; | ||
81 | pdata->regs->irqstatus2 = OMAP24XX_GPIO_IRQSTATUS2; | ||
82 | pdata->regs->irqenable = OMAP24XX_GPIO_IRQENABLE1; | ||
83 | pdata->regs->set_irqenable = OMAP24XX_GPIO_SETIRQENABLE1; | ||
84 | pdata->regs->clr_irqenable = OMAP24XX_GPIO_CLEARIRQENABLE1; | ||
85 | pdata->regs->debounce = OMAP24XX_GPIO_DEBOUNCE_VAL; | ||
86 | pdata->regs->debounce_en = OMAP24XX_GPIO_DEBOUNCE_EN; | ||
68 | break; | 87 | break; |
69 | case 2: | 88 | case 2: |
70 | pdata->bank_type = METHOD_GPIO_44XX; | 89 | pdata->bank_type = METHOD_GPIO_44XX; |
90 | pdata->regs->revision = OMAP4_GPIO_REVISION; | ||
91 | pdata->regs->direction = OMAP4_GPIO_OE; | ||
92 | pdata->regs->datain = OMAP4_GPIO_DATAIN; | ||
93 | pdata->regs->dataout = OMAP4_GPIO_DATAOUT; | ||
94 | pdata->regs->set_dataout = OMAP4_GPIO_SETDATAOUT; | ||
95 | pdata->regs->clr_dataout = OMAP4_GPIO_CLEARDATAOUT; | ||
96 | pdata->regs->irqstatus = OMAP4_GPIO_IRQSTATUS0; | ||
97 | pdata->regs->irqstatus2 = OMAP4_GPIO_IRQSTATUS1; | ||
98 | pdata->regs->irqenable = OMAP4_GPIO_IRQSTATUSSET0; | ||
99 | pdata->regs->set_irqenable = OMAP4_GPIO_IRQSTATUSSET0; | ||
100 | pdata->regs->clr_irqenable = OMAP4_GPIO_IRQSTATUSCLR0; | ||
101 | pdata->regs->debounce = OMAP4_GPIO_DEBOUNCINGTIME; | ||
102 | pdata->regs->debounce_en = OMAP4_GPIO_DEBOUNCENABLE; | ||
71 | break; | 103 | break; |
72 | default: | 104 | default: |
73 | WARN(1, "Invalid gpio bank_type\n"); | 105 | WARN(1, "Invalid gpio bank_type\n"); |
diff --git a/arch/arm/mach-tegra/Makefile b/arch/arm/mach-tegra/Makefile index 823c703e573c..ed58ef9019b5 100644 --- a/arch/arm/mach-tegra/Makefile +++ b/arch/arm/mach-tegra/Makefile | |||
@@ -4,7 +4,6 @@ obj-y += io.o | |||
4 | obj-y += irq.o | 4 | obj-y += irq.o |
5 | obj-y += clock.o | 5 | obj-y += clock.o |
6 | obj-y += timer.o | 6 | obj-y += timer.o |
7 | obj-y += gpio.o | ||
8 | obj-y += pinmux.o | 7 | obj-y += pinmux.o |
9 | obj-y += powergate.o | 8 | obj-y += powergate.o |
10 | obj-y += fuse.o | 9 | obj-y += fuse.o |
diff --git a/arch/arm/plat-mxc/Makefile b/arch/arm/plat-mxc/Makefile index a1387875a491..d53c35fe2ea7 100644 --- a/arch/arm/plat-mxc/Makefile +++ b/arch/arm/plat-mxc/Makefile | |||
@@ -3,7 +3,7 @@ | |||
3 | # | 3 | # |
4 | 4 | ||
5 | # Common support | 5 | # Common support |
6 | obj-y := clock.o gpio.o time.o devices.o cpu.o system.o irq-common.o | 6 | obj-y := clock.o time.o devices.o cpu.o system.o irq-common.o |
7 | 7 | ||
8 | # MX51 uses the TZIC interrupt controller, older platforms use AVIC | 8 | # MX51 uses the TZIC interrupt controller, older platforms use AVIC |
9 | obj-$(CONFIG_MXC_TZIC) += tzic.o | 9 | obj-$(CONFIG_MXC_TZIC) += tzic.o |
diff --git a/arch/arm/plat-mxc/devices.c b/arch/arm/plat-mxc/devices.c index eee1b6096a08..fb166b20f60f 100644 --- a/arch/arm/plat-mxc/devices.c +++ b/arch/arm/plat-mxc/devices.c | |||
@@ -89,3 +89,14 @@ err: | |||
89 | 89 | ||
90 | return pdev; | 90 | return pdev; |
91 | } | 91 | } |
92 | |||
93 | struct device mxc_aips_bus = { | ||
94 | .init_name = "mxc_aips", | ||
95 | .parent = &platform_bus, | ||
96 | }; | ||
97 | |||
98 | static int __init mxc_device_init(void) | ||
99 | { | ||
100 | return device_register(&mxc_aips_bus); | ||
101 | } | ||
102 | core_initcall(mxc_device_init); | ||
diff --git a/arch/arm/plat-mxc/devices/Makefile b/arch/arm/plat-mxc/devices/Makefile index ad2922acf480..b41bf972b54b 100644 --- a/arch/arm/plat-mxc/devices/Makefile +++ b/arch/arm/plat-mxc/devices/Makefile | |||
@@ -2,6 +2,7 @@ obj-$(CONFIG_IMX_HAVE_PLATFORM_FEC) += platform-fec.o | |||
2 | obj-$(CONFIG_IMX_HAVE_PLATFORM_FLEXCAN) += platform-flexcan.o | 2 | obj-$(CONFIG_IMX_HAVE_PLATFORM_FLEXCAN) += platform-flexcan.o |
3 | obj-$(CONFIG_IMX_HAVE_PLATFORM_FSL_USB2_UDC) += platform-fsl-usb2-udc.o | 3 | obj-$(CONFIG_IMX_HAVE_PLATFORM_FSL_USB2_UDC) += platform-fsl-usb2-udc.o |
4 | obj-$(CONFIG_IMX_HAVE_PLATFORM_GPIO_KEYS) += platform-gpio_keys.o | 4 | obj-$(CONFIG_IMX_HAVE_PLATFORM_GPIO_KEYS) += platform-gpio_keys.o |
5 | obj-y += platform-gpio-mxc.o | ||
5 | obj-$(CONFIG_IMX_HAVE_PLATFORM_IMX21_HCD) += platform-imx21-hcd.o | 6 | obj-$(CONFIG_IMX_HAVE_PLATFORM_IMX21_HCD) += platform-imx21-hcd.o |
6 | obj-$(CONFIG_IMX_HAVE_PLATFORM_IMX2_WDT) += platform-imx2-wdt.o | 7 | obj-$(CONFIG_IMX_HAVE_PLATFORM_IMX2_WDT) += platform-imx2-wdt.o |
7 | obj-$(CONFIG_IMX_HAVE_PLATFORM_IMXDI_RTC) += platform-imxdi_rtc.o | 8 | obj-$(CONFIG_IMX_HAVE_PLATFORM_IMXDI_RTC) += platform-imxdi_rtc.o |
diff --git a/arch/arm/plat-mxc/devices/platform-gpio-mxc.c b/arch/arm/plat-mxc/devices/platform-gpio-mxc.c new file mode 100644 index 000000000000..a7919a241032 --- /dev/null +++ b/arch/arm/plat-mxc/devices/platform-gpio-mxc.c | |||
@@ -0,0 +1,32 @@ | |||
1 | /* | ||
2 | * Copyright 2011 Freescale Semiconductor, Inc. All Rights Reserved. | ||
3 | * Copyright 2011 Linaro Limited | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it under | ||
6 | * the terms of the GNU General Public License version 2 as published by the | ||
7 | * Free Software Foundation. | ||
8 | */ | ||
9 | #include <mach/devices-common.h> | ||
10 | |||
11 | struct platform_device *__init mxc_register_gpio(char *name, int id, | ||
12 | resource_size_t iobase, resource_size_t iosize, int irq, int irq_high) | ||
13 | { | ||
14 | struct resource res[] = { | ||
15 | { | ||
16 | .start = iobase, | ||
17 | .end = iobase + iosize - 1, | ||
18 | .flags = IORESOURCE_MEM, | ||
19 | }, { | ||
20 | .start = irq, | ||
21 | .end = irq, | ||
22 | .flags = IORESOURCE_IRQ, | ||
23 | }, { | ||
24 | .start = irq_high, | ||
25 | .end = irq_high, | ||
26 | .flags = IORESOURCE_IRQ, | ||
27 | }, | ||
28 | }; | ||
29 | |||
30 | return platform_device_register_resndata(&mxc_aips_bus, | ||
31 | name, id, res, ARRAY_SIZE(res), NULL, 0); | ||
32 | } | ||
diff --git a/arch/arm/plat-mxc/gpio.c b/arch/arm/plat-mxc/gpio.c deleted file mode 100644 index 6cd6d7f686f6..000000000000 --- a/arch/arm/plat-mxc/gpio.c +++ /dev/null | |||
@@ -1,361 +0,0 @@ | |||
1 | /* | ||
2 | * MXC GPIO support. (c) 2008 Daniel Mack <daniel@caiaq.de> | ||
3 | * Copyright 2008 Juergen Beisert, kernel@pengutronix.de | ||
4 | * | ||
5 | * Based on code from Freescale, | ||
6 | * Copyright (C) 2004-2010 Freescale Semiconductor, Inc. All Rights Reserved. | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or | ||
9 | * modify it under the terms of the GNU General Public License | ||
10 | * as published by the Free Software Foundation; either version 2 | ||
11 | * of the License, or (at your option) any later version. | ||
12 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License | ||
18 | * along with this program; if not, write to the Free Software | ||
19 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | ||
20 | */ | ||
21 | |||
22 | #include <linux/init.h> | ||
23 | #include <linux/interrupt.h> | ||
24 | #include <linux/io.h> | ||
25 | #include <linux/irq.h> | ||
26 | #include <linux/gpio.h> | ||
27 | #include <mach/hardware.h> | ||
28 | #include <asm-generic/bug.h> | ||
29 | |||
30 | static struct mxc_gpio_port *mxc_gpio_ports; | ||
31 | static int gpio_table_size; | ||
32 | |||
33 | #define cpu_is_mx1_mx2() (cpu_is_mx1() || cpu_is_mx2()) | ||
34 | |||
35 | #define GPIO_DR (cpu_is_mx1_mx2() ? 0x1c : 0x00) | ||
36 | #define GPIO_GDIR (cpu_is_mx1_mx2() ? 0x00 : 0x04) | ||
37 | #define GPIO_PSR (cpu_is_mx1_mx2() ? 0x24 : 0x08) | ||
38 | #define GPIO_ICR1 (cpu_is_mx1_mx2() ? 0x28 : 0x0C) | ||
39 | #define GPIO_ICR2 (cpu_is_mx1_mx2() ? 0x2C : 0x10) | ||
40 | #define GPIO_IMR (cpu_is_mx1_mx2() ? 0x30 : 0x14) | ||
41 | #define GPIO_ISR (cpu_is_mx1_mx2() ? 0x34 : 0x18) | ||
42 | |||
43 | #define GPIO_INT_LOW_LEV (cpu_is_mx1_mx2() ? 0x3 : 0x0) | ||
44 | #define GPIO_INT_HIGH_LEV (cpu_is_mx1_mx2() ? 0x2 : 0x1) | ||
45 | #define GPIO_INT_RISE_EDGE (cpu_is_mx1_mx2() ? 0x0 : 0x2) | ||
46 | #define GPIO_INT_FALL_EDGE (cpu_is_mx1_mx2() ? 0x1 : 0x3) | ||
47 | #define GPIO_INT_NONE 0x4 | ||
48 | |||
49 | /* Note: This driver assumes 32 GPIOs are handled in one register */ | ||
50 | |||
51 | static void _clear_gpio_irqstatus(struct mxc_gpio_port *port, u32 index) | ||
52 | { | ||
53 | __raw_writel(1 << index, port->base + GPIO_ISR); | ||
54 | } | ||
55 | |||
56 | static void _set_gpio_irqenable(struct mxc_gpio_port *port, u32 index, | ||
57 | int enable) | ||
58 | { | ||
59 | u32 l; | ||
60 | |||
61 | l = __raw_readl(port->base + GPIO_IMR); | ||
62 | l = (l & (~(1 << index))) | (!!enable << index); | ||
63 | __raw_writel(l, port->base + GPIO_IMR); | ||
64 | } | ||
65 | |||
66 | static void gpio_ack_irq(struct irq_data *d) | ||
67 | { | ||
68 | u32 gpio = irq_to_gpio(d->irq); | ||
69 | _clear_gpio_irqstatus(&mxc_gpio_ports[gpio / 32], gpio & 0x1f); | ||
70 | } | ||
71 | |||
72 | static void gpio_mask_irq(struct irq_data *d) | ||
73 | { | ||
74 | u32 gpio = irq_to_gpio(d->irq); | ||
75 | _set_gpio_irqenable(&mxc_gpio_ports[gpio / 32], gpio & 0x1f, 0); | ||
76 | } | ||
77 | |||
78 | static void gpio_unmask_irq(struct irq_data *d) | ||
79 | { | ||
80 | u32 gpio = irq_to_gpio(d->irq); | ||
81 | _set_gpio_irqenable(&mxc_gpio_ports[gpio / 32], gpio & 0x1f, 1); | ||
82 | } | ||
83 | |||
84 | static int mxc_gpio_get(struct gpio_chip *chip, unsigned offset); | ||
85 | |||
86 | static int gpio_set_irq_type(struct irq_data *d, u32 type) | ||
87 | { | ||
88 | u32 gpio = irq_to_gpio(d->irq); | ||
89 | struct mxc_gpio_port *port = &mxc_gpio_ports[gpio / 32]; | ||
90 | u32 bit, val; | ||
91 | int edge; | ||
92 | void __iomem *reg = port->base; | ||
93 | |||
94 | port->both_edges &= ~(1 << (gpio & 31)); | ||
95 | switch (type) { | ||
96 | case IRQ_TYPE_EDGE_RISING: | ||
97 | edge = GPIO_INT_RISE_EDGE; | ||
98 | break; | ||
99 | case IRQ_TYPE_EDGE_FALLING: | ||
100 | edge = GPIO_INT_FALL_EDGE; | ||
101 | break; | ||
102 | case IRQ_TYPE_EDGE_BOTH: | ||
103 | val = mxc_gpio_get(&port->chip, gpio & 31); | ||
104 | if (val) { | ||
105 | edge = GPIO_INT_LOW_LEV; | ||
106 | pr_debug("mxc: set GPIO %d to low trigger\n", gpio); | ||
107 | } else { | ||
108 | edge = GPIO_INT_HIGH_LEV; | ||
109 | pr_debug("mxc: set GPIO %d to high trigger\n", gpio); | ||
110 | } | ||
111 | port->both_edges |= 1 << (gpio & 31); | ||
112 | break; | ||
113 | case IRQ_TYPE_LEVEL_LOW: | ||
114 | edge = GPIO_INT_LOW_LEV; | ||
115 | break; | ||
116 | case IRQ_TYPE_LEVEL_HIGH: | ||
117 | edge = GPIO_INT_HIGH_LEV; | ||
118 | break; | ||
119 | default: | ||
120 | return -EINVAL; | ||
121 | } | ||
122 | |||
123 | reg += GPIO_ICR1 + ((gpio & 0x10) >> 2); /* lower or upper register */ | ||
124 | bit = gpio & 0xf; | ||
125 | val = __raw_readl(reg) & ~(0x3 << (bit << 1)); | ||
126 | __raw_writel(val | (edge << (bit << 1)), reg); | ||
127 | _clear_gpio_irqstatus(port, gpio & 0x1f); | ||
128 | |||
129 | return 0; | ||
130 | } | ||
131 | |||
132 | static void mxc_flip_edge(struct mxc_gpio_port *port, u32 gpio) | ||
133 | { | ||
134 | void __iomem *reg = port->base; | ||
135 | u32 bit, val; | ||
136 | int edge; | ||
137 | |||
138 | reg += GPIO_ICR1 + ((gpio & 0x10) >> 2); /* lower or upper register */ | ||
139 | bit = gpio & 0xf; | ||
140 | val = __raw_readl(reg); | ||
141 | edge = (val >> (bit << 1)) & 3; | ||
142 | val &= ~(0x3 << (bit << 1)); | ||
143 | if (edge == GPIO_INT_HIGH_LEV) { | ||
144 | edge = GPIO_INT_LOW_LEV; | ||
145 | pr_debug("mxc: switch GPIO %d to low trigger\n", gpio); | ||
146 | } else if (edge == GPIO_INT_LOW_LEV) { | ||
147 | edge = GPIO_INT_HIGH_LEV; | ||
148 | pr_debug("mxc: switch GPIO %d to high trigger\n", gpio); | ||
149 | } else { | ||
150 | pr_err("mxc: invalid configuration for GPIO %d: %x\n", | ||
151 | gpio, edge); | ||
152 | return; | ||
153 | } | ||
154 | __raw_writel(val | (edge << (bit << 1)), reg); | ||
155 | } | ||
156 | |||
157 | /* handle 32 interrupts in one status register */ | ||
158 | static void mxc_gpio_irq_handler(struct mxc_gpio_port *port, u32 irq_stat) | ||
159 | { | ||
160 | u32 gpio_irq_no_base = port->virtual_irq_start; | ||
161 | |||
162 | while (irq_stat != 0) { | ||
163 | int irqoffset = fls(irq_stat) - 1; | ||
164 | |||
165 | if (port->both_edges & (1 << irqoffset)) | ||
166 | mxc_flip_edge(port, irqoffset); | ||
167 | |||
168 | generic_handle_irq(gpio_irq_no_base + irqoffset); | ||
169 | |||
170 | irq_stat &= ~(1 << irqoffset); | ||
171 | } | ||
172 | } | ||
173 | |||
174 | /* MX1 and MX3 has one interrupt *per* gpio port */ | ||
175 | static void mx3_gpio_irq_handler(u32 irq, struct irq_desc *desc) | ||
176 | { | ||
177 | u32 irq_stat; | ||
178 | struct mxc_gpio_port *port = irq_get_handler_data(irq); | ||
179 | |||
180 | irq_stat = __raw_readl(port->base + GPIO_ISR) & | ||
181 | __raw_readl(port->base + GPIO_IMR); | ||
182 | |||
183 | mxc_gpio_irq_handler(port, irq_stat); | ||
184 | } | ||
185 | |||
186 | /* MX2 has one interrupt *for all* gpio ports */ | ||
187 | static void mx2_gpio_irq_handler(u32 irq, struct irq_desc *desc) | ||
188 | { | ||
189 | int i; | ||
190 | u32 irq_msk, irq_stat; | ||
191 | struct mxc_gpio_port *port = irq_get_handler_data(irq); | ||
192 | |||
193 | /* walk through all interrupt status registers */ | ||
194 | for (i = 0; i < gpio_table_size; i++) { | ||
195 | irq_msk = __raw_readl(port[i].base + GPIO_IMR); | ||
196 | if (!irq_msk) | ||
197 | continue; | ||
198 | |||
199 | irq_stat = __raw_readl(port[i].base + GPIO_ISR) & irq_msk; | ||
200 | if (irq_stat) | ||
201 | mxc_gpio_irq_handler(&port[i], irq_stat); | ||
202 | } | ||
203 | } | ||
204 | |||
205 | /* | ||
206 | * Set interrupt number "irq" in the GPIO as a wake-up source. | ||
207 | * While system is running, all registered GPIO interrupts need to have | ||
208 | * wake-up enabled. When system is suspended, only selected GPIO interrupts | ||
209 | * need to have wake-up enabled. | ||
210 | * @param irq interrupt source number | ||
211 | * @param enable enable as wake-up if equal to non-zero | ||
212 | * @return This function returns 0 on success. | ||
213 | */ | ||
214 | static int gpio_set_wake_irq(struct irq_data *d, u32 enable) | ||
215 | { | ||
216 | u32 gpio = irq_to_gpio(d->irq); | ||
217 | u32 gpio_idx = gpio & 0x1F; | ||
218 | struct mxc_gpio_port *port = &mxc_gpio_ports[gpio / 32]; | ||
219 | |||
220 | if (enable) { | ||
221 | if (port->irq_high && (gpio_idx >= 16)) | ||
222 | enable_irq_wake(port->irq_high); | ||
223 | else | ||
224 | enable_irq_wake(port->irq); | ||
225 | } else { | ||
226 | if (port->irq_high && (gpio_idx >= 16)) | ||
227 | disable_irq_wake(port->irq_high); | ||
228 | else | ||
229 | disable_irq_wake(port->irq); | ||
230 | } | ||
231 | |||
232 | return 0; | ||
233 | } | ||
234 | |||
235 | static struct irq_chip gpio_irq_chip = { | ||
236 | .name = "GPIO", | ||
237 | .irq_ack = gpio_ack_irq, | ||
238 | .irq_mask = gpio_mask_irq, | ||
239 | .irq_unmask = gpio_unmask_irq, | ||
240 | .irq_set_type = gpio_set_irq_type, | ||
241 | .irq_set_wake = gpio_set_wake_irq, | ||
242 | }; | ||
243 | |||
244 | static void _set_gpio_direction(struct gpio_chip *chip, unsigned offset, | ||
245 | int dir) | ||
246 | { | ||
247 | struct mxc_gpio_port *port = | ||
248 | container_of(chip, struct mxc_gpio_port, chip); | ||
249 | u32 l; | ||
250 | unsigned long flags; | ||
251 | |||
252 | spin_lock_irqsave(&port->lock, flags); | ||
253 | l = __raw_readl(port->base + GPIO_GDIR); | ||
254 | if (dir) | ||
255 | l |= 1 << offset; | ||
256 | else | ||
257 | l &= ~(1 << offset); | ||
258 | __raw_writel(l, port->base + GPIO_GDIR); | ||
259 | spin_unlock_irqrestore(&port->lock, flags); | ||
260 | } | ||
261 | |||
262 | static void mxc_gpio_set(struct gpio_chip *chip, unsigned offset, int value) | ||
263 | { | ||
264 | struct mxc_gpio_port *port = | ||
265 | container_of(chip, struct mxc_gpio_port, chip); | ||
266 | void __iomem *reg = port->base + GPIO_DR; | ||
267 | u32 l; | ||
268 | unsigned long flags; | ||
269 | |||
270 | spin_lock_irqsave(&port->lock, flags); | ||
271 | l = (__raw_readl(reg) & (~(1 << offset))) | (!!value << offset); | ||
272 | __raw_writel(l, reg); | ||
273 | spin_unlock_irqrestore(&port->lock, flags); | ||
274 | } | ||
275 | |||
276 | static int mxc_gpio_get(struct gpio_chip *chip, unsigned offset) | ||
277 | { | ||
278 | struct mxc_gpio_port *port = | ||
279 | container_of(chip, struct mxc_gpio_port, chip); | ||
280 | |||
281 | return (__raw_readl(port->base + GPIO_PSR) >> offset) & 1; | ||
282 | } | ||
283 | |||
284 | static int mxc_gpio_direction_input(struct gpio_chip *chip, unsigned offset) | ||
285 | { | ||
286 | _set_gpio_direction(chip, offset, 0); | ||
287 | return 0; | ||
288 | } | ||
289 | |||
290 | static int mxc_gpio_direction_output(struct gpio_chip *chip, | ||
291 | unsigned offset, int value) | ||
292 | { | ||
293 | mxc_gpio_set(chip, offset, value); | ||
294 | _set_gpio_direction(chip, offset, 1); | ||
295 | return 0; | ||
296 | } | ||
297 | |||
298 | /* | ||
299 | * This lock class tells lockdep that GPIO irqs are in a different | ||
300 | * category than their parents, so it won't report false recursion. | ||
301 | */ | ||
302 | static struct lock_class_key gpio_lock_class; | ||
303 | |||
304 | int __init mxc_gpio_init(struct mxc_gpio_port *port, int cnt) | ||
305 | { | ||
306 | int i, j; | ||
307 | |||
308 | /* save for local usage */ | ||
309 | mxc_gpio_ports = port; | ||
310 | gpio_table_size = cnt; | ||
311 | |||
312 | printk(KERN_INFO "MXC GPIO hardware\n"); | ||
313 | |||
314 | for (i = 0; i < cnt; i++) { | ||
315 | /* disable the interrupt and clear the status */ | ||
316 | __raw_writel(0, port[i].base + GPIO_IMR); | ||
317 | __raw_writel(~0, port[i].base + GPIO_ISR); | ||
318 | for (j = port[i].virtual_irq_start; | ||
319 | j < port[i].virtual_irq_start + 32; j++) { | ||
320 | irq_set_lockdep_class(j, &gpio_lock_class); | ||
321 | irq_set_chip_and_handler(j, &gpio_irq_chip, | ||
322 | handle_level_irq); | ||
323 | set_irq_flags(j, IRQF_VALID); | ||
324 | } | ||
325 | |||
326 | /* register gpio chip */ | ||
327 | port[i].chip.direction_input = mxc_gpio_direction_input; | ||
328 | port[i].chip.direction_output = mxc_gpio_direction_output; | ||
329 | port[i].chip.get = mxc_gpio_get; | ||
330 | port[i].chip.set = mxc_gpio_set; | ||
331 | port[i].chip.base = i * 32; | ||
332 | port[i].chip.ngpio = 32; | ||
333 | |||
334 | spin_lock_init(&port[i].lock); | ||
335 | |||
336 | /* its a serious configuration bug when it fails */ | ||
337 | BUG_ON( gpiochip_add(&port[i].chip) < 0 ); | ||
338 | |||
339 | if (cpu_is_mx1() || cpu_is_mx3() || cpu_is_mx25() || cpu_is_mx51()) { | ||
340 | /* setup one handler for each entry */ | ||
341 | irq_set_chained_handler(port[i].irq, | ||
342 | mx3_gpio_irq_handler); | ||
343 | irq_set_handler_data(port[i].irq, &port[i]); | ||
344 | if (port[i].irq_high) { | ||
345 | /* setup handler for GPIO 16 to 31 */ | ||
346 | irq_set_chained_handler(port[i].irq_high, | ||
347 | mx3_gpio_irq_handler); | ||
348 | irq_set_handler_data(port[i].irq_high, | ||
349 | &port[i]); | ||
350 | } | ||
351 | } | ||
352 | } | ||
353 | |||
354 | if (cpu_is_mx2()) { | ||
355 | /* setup one handler for all GPIO interrupts */ | ||
356 | irq_set_chained_handler(port[0].irq, mx2_gpio_irq_handler); | ||
357 | irq_set_handler_data(port[0].irq, port); | ||
358 | } | ||
359 | |||
360 | return 0; | ||
361 | } | ||
diff --git a/arch/arm/plat-mxc/include/mach/common.h b/arch/arm/plat-mxc/include/mach/common.h index da7991832af6..4e3d97890d69 100644 --- a/arch/arm/plat-mxc/include/mach/common.h +++ b/arch/arm/plat-mxc/include/mach/common.h | |||
@@ -43,6 +43,15 @@ extern void mx35_init_irq(void); | |||
43 | extern void mx50_init_irq(void); | 43 | extern void mx50_init_irq(void); |
44 | extern void mx51_init_irq(void); | 44 | extern void mx51_init_irq(void); |
45 | extern void mx53_init_irq(void); | 45 | extern void mx53_init_irq(void); |
46 | extern void imx1_soc_init(void); | ||
47 | extern void imx21_soc_init(void); | ||
48 | extern void imx25_soc_init(void); | ||
49 | extern void imx27_soc_init(void); | ||
50 | extern void imx31_soc_init(void); | ||
51 | extern void imx35_soc_init(void); | ||
52 | extern void imx50_soc_init(void); | ||
53 | extern void imx51_soc_init(void); | ||
54 | extern void imx53_soc_init(void); | ||
46 | extern void epit_timer_init(struct clk *timer_clk, void __iomem *base, int irq); | 55 | extern void epit_timer_init(struct clk *timer_clk, void __iomem *base, int irq); |
47 | extern void mxc_timer_init(struct clk *timer_clk, void __iomem *, int); | 56 | extern void mxc_timer_init(struct clk *timer_clk, void __iomem *, int); |
48 | extern int mx1_clocks_init(unsigned long fref); | 57 | extern int mx1_clocks_init(unsigned long fref); |
@@ -55,7 +64,8 @@ extern int mx51_clocks_init(unsigned long ckil, unsigned long osc, | |||
55 | unsigned long ckih1, unsigned long ckih2); | 64 | unsigned long ckih1, unsigned long ckih2); |
56 | extern int mx53_clocks_init(unsigned long ckil, unsigned long osc, | 65 | extern int mx53_clocks_init(unsigned long ckil, unsigned long osc, |
57 | unsigned long ckih1, unsigned long ckih2); | 66 | unsigned long ckih1, unsigned long ckih2); |
58 | extern int mxc_register_gpios(void); | 67 | extern struct platform_device *mxc_register_gpio(char *name, int id, |
68 | resource_size_t iobase, resource_size_t iosize, int irq, int irq_high); | ||
59 | extern int mxc_register_device(struct platform_device *pdev, void *data); | 69 | extern int mxc_register_device(struct platform_device *pdev, void *data); |
60 | extern void mxc_set_cpu_type(unsigned int type); | 70 | extern void mxc_set_cpu_type(unsigned int type); |
61 | extern void mxc_arch_reset_init(void __iomem *); | 71 | extern void mxc_arch_reset_init(void __iomem *); |
diff --git a/arch/arm/plat-mxc/include/mach/devices-common.h b/arch/arm/plat-mxc/include/mach/devices-common.h index fa8477337f91..03f626645374 100644 --- a/arch/arm/plat-mxc/include/mach/devices-common.h +++ b/arch/arm/plat-mxc/include/mach/devices-common.h | |||
@@ -10,6 +10,8 @@ | |||
10 | #include <linux/platform_device.h> | 10 | #include <linux/platform_device.h> |
11 | #include <linux/init.h> | 11 | #include <linux/init.h> |
12 | 12 | ||
13 | extern struct device mxc_aips_bus; | ||
14 | |||
13 | struct platform_device *imx_add_platform_device_dmamask( | 15 | struct platform_device *imx_add_platform_device_dmamask( |
14 | const char *name, int id, | 16 | const char *name, int id, |
15 | const struct resource *res, unsigned int num_resources, | 17 | const struct resource *res, unsigned int num_resources, |
diff --git a/arch/arm/plat-mxc/include/mach/gpio.h b/arch/arm/plat-mxc/include/mach/gpio.h index a2747f12813e..31c820c1b796 100644 --- a/arch/arm/plat-mxc/include/mach/gpio.h +++ b/arch/arm/plat-mxc/include/mach/gpio.h | |||
@@ -36,31 +36,4 @@ | |||
36 | #define gpio_to_irq(gpio) (MXC_GPIO_IRQ_START + (gpio)) | 36 | #define gpio_to_irq(gpio) (MXC_GPIO_IRQ_START + (gpio)) |
37 | #define irq_to_gpio(irq) ((irq) - MXC_GPIO_IRQ_START) | 37 | #define irq_to_gpio(irq) ((irq) - MXC_GPIO_IRQ_START) |
38 | 38 | ||
39 | struct mxc_gpio_port { | ||
40 | void __iomem *base; | ||
41 | int irq; | ||
42 | int irq_high; | ||
43 | int virtual_irq_start; | ||
44 | struct gpio_chip chip; | ||
45 | u32 both_edges; | ||
46 | spinlock_t lock; | ||
47 | }; | ||
48 | |||
49 | #define DEFINE_IMX_GPIO_PORT_IRQ_HIGH(soc, _id, _hwid, _irq, _irq_high) \ | ||
50 | { \ | ||
51 | .chip.label = "gpio-" #_id, \ | ||
52 | .irq = _irq, \ | ||
53 | .irq_high = _irq_high, \ | ||
54 | .base = soc ## _IO_ADDRESS( \ | ||
55 | soc ## _GPIO ## _hwid ## _BASE_ADDR), \ | ||
56 | .virtual_irq_start = MXC_GPIO_IRQ_START + (_id) * 32, \ | ||
57 | } | ||
58 | |||
59 | #define DEFINE_IMX_GPIO_PORT_IRQ(soc, _id, _hwid, _irq) \ | ||
60 | DEFINE_IMX_GPIO_PORT_IRQ_HIGH(soc, _id, _hwid, _irq, 0) | ||
61 | #define DEFINE_IMX_GPIO_PORT(soc, _id, _hwid) \ | ||
62 | DEFINE_IMX_GPIO_PORT_IRQ(soc, _id, _hwid, 0) | ||
63 | |||
64 | int mxc_gpio_init(struct mxc_gpio_port*, int); | ||
65 | |||
66 | #endif | 39 | #endif |
diff --git a/arch/arm/plat-mxc/include/mach/irqs.h b/arch/arm/plat-mxc/include/mach/irqs.h index 35c89bcdf758..00e812bbd81d 100644 --- a/arch/arm/plat-mxc/include/mach/irqs.h +++ b/arch/arm/plat-mxc/include/mach/irqs.h | |||
@@ -11,6 +11,8 @@ | |||
11 | #ifndef __ASM_ARCH_MXC_IRQS_H__ | 11 | #ifndef __ASM_ARCH_MXC_IRQS_H__ |
12 | #define __ASM_ARCH_MXC_IRQS_H__ | 12 | #define __ASM_ARCH_MXC_IRQS_H__ |
13 | 13 | ||
14 | #include <asm-generic/gpio.h> | ||
15 | |||
14 | /* | 16 | /* |
15 | * SoCs with TZIC interrupt controller have 128 IRQs, those with AVIC have 64 | 17 | * SoCs with TZIC interrupt controller have 128 IRQs, those with AVIC have 64 |
16 | */ | 18 | */ |
@@ -22,30 +24,13 @@ | |||
22 | 24 | ||
23 | #define MXC_GPIO_IRQ_START MXC_INTERNAL_IRQS | 25 | #define MXC_GPIO_IRQ_START MXC_INTERNAL_IRQS |
24 | 26 | ||
25 | /* these are ordered by size to support multi-SoC kernels */ | ||
26 | #if defined CONFIG_SOC_IMX53 | ||
27 | #define MXC_GPIO_IRQS (32 * 7) | ||
28 | #elif defined CONFIG_ARCH_MX2 | ||
29 | #define MXC_GPIO_IRQS (32 * 6) | ||
30 | #elif defined CONFIG_SOC_IMX50 | ||
31 | #define MXC_GPIO_IRQS (32 * 6) | ||
32 | #elif defined CONFIG_ARCH_MX1 | ||
33 | #define MXC_GPIO_IRQS (32 * 4) | ||
34 | #elif defined CONFIG_ARCH_MX25 | ||
35 | #define MXC_GPIO_IRQS (32 * 4) | ||
36 | #elif defined CONFIG_SOC_IMX51 | ||
37 | #define MXC_GPIO_IRQS (32 * 4) | ||
38 | #elif defined CONFIG_ARCH_MX3 | ||
39 | #define MXC_GPIO_IRQS (32 * 3) | ||
40 | #endif | ||
41 | |||
42 | /* | 27 | /* |
43 | * The next 16 interrupts are for board specific purposes. Since | 28 | * The next 16 interrupts are for board specific purposes. Since |
44 | * the kernel can only run on one machine at a time, we can re-use | 29 | * the kernel can only run on one machine at a time, we can re-use |
45 | * these. If you need more, increase MXC_BOARD_IRQS, but keep it | 30 | * these. If you need more, increase MXC_BOARD_IRQS, but keep it |
46 | * within sensible limits. | 31 | * within sensible limits. |
47 | */ | 32 | */ |
48 | #define MXC_BOARD_IRQ_START (MXC_INTERNAL_IRQS + MXC_GPIO_IRQS) | 33 | #define MXC_BOARD_IRQ_START (MXC_INTERNAL_IRQS + ARCH_NR_GPIOS) |
49 | 34 | ||
50 | #ifdef CONFIG_MACH_MX31ADS_WM1133_EV1 | 35 | #ifdef CONFIG_MACH_MX31ADS_WM1133_EV1 |
51 | #define MXC_BOARD_IRQS 80 | 36 | #define MXC_BOARD_IRQS 80 |
diff --git a/arch/arm/plat-omap/include/plat/gpio.h b/arch/arm/plat-omap/include/plat/gpio.h index ec97e00cb581..91e8de3db085 100644 --- a/arch/arm/plat-omap/include/plat/gpio.h +++ b/arch/arm/plat-omap/include/plat/gpio.h | |||
@@ -174,12 +174,32 @@ struct omap_gpio_dev_attr { | |||
174 | bool dbck_flag; /* dbck required or not - True for OMAP3&4 */ | 174 | bool dbck_flag; /* dbck required or not - True for OMAP3&4 */ |
175 | }; | 175 | }; |
176 | 176 | ||
177 | struct omap_gpio_reg_offs { | ||
178 | u16 revision; | ||
179 | u16 direction; | ||
180 | u16 datain; | ||
181 | u16 dataout; | ||
182 | u16 set_dataout; | ||
183 | u16 clr_dataout; | ||
184 | u16 irqstatus; | ||
185 | u16 irqstatus2; | ||
186 | u16 irqenable; | ||
187 | u16 set_irqenable; | ||
188 | u16 clr_irqenable; | ||
189 | u16 debounce; | ||
190 | u16 debounce_en; | ||
191 | |||
192 | bool irqenable_inv; | ||
193 | }; | ||
194 | |||
177 | struct omap_gpio_platform_data { | 195 | struct omap_gpio_platform_data { |
178 | u16 virtual_irq_start; | 196 | u16 virtual_irq_start; |
179 | int bank_type; | 197 | int bank_type; |
180 | int bank_width; /* GPIO bank width */ | 198 | int bank_width; /* GPIO bank width */ |
181 | int bank_stride; /* Only needed for omap1 MPUIO */ | 199 | int bank_stride; /* Only needed for omap1 MPUIO */ |
182 | bool dbck_flag; /* dbck required or not - True for OMAP3&4 */ | 200 | bool dbck_flag; /* dbck required or not - True for OMAP3&4 */ |
201 | |||
202 | struct omap_gpio_reg_offs *regs; | ||
183 | }; | 203 | }; |
184 | 204 | ||
185 | /* TODO: Analyze removing gpio_bank_count usage from driver code */ | 205 | /* TODO: Analyze removing gpio_bank_count usage from driver code */ |
diff --git a/arch/powerpc/platforms/52xx/Kconfig b/arch/powerpc/platforms/52xx/Kconfig index 47ea1be1481b..90f4496017e4 100644 --- a/arch/powerpc/platforms/52xx/Kconfig +++ b/arch/powerpc/platforms/52xx/Kconfig | |||
@@ -55,14 +55,6 @@ config PPC_MPC5200_BUGFIX | |||
55 | 55 | ||
56 | It is safe to say 'Y' here | 56 | It is safe to say 'Y' here |
57 | 57 | ||
58 | config PPC_MPC5200_GPIO | ||
59 | bool "MPC5200 GPIO support" | ||
60 | depends on PPC_MPC52xx | ||
61 | select ARCH_REQUIRE_GPIOLIB | ||
62 | select GENERIC_GPIO | ||
63 | help | ||
64 | Enable gpiolib support for mpc5200 based boards | ||
65 | |||
66 | config PPC_MPC5200_LPBFIFO | 58 | config PPC_MPC5200_LPBFIFO |
67 | tristate "MPC5200 LocalPlus bus FIFO driver" | 59 | tristate "MPC5200 LocalPlus bus FIFO driver" |
68 | depends on PPC_MPC52xx | 60 | depends on PPC_MPC52xx |
diff --git a/arch/powerpc/platforms/52xx/Makefile b/arch/powerpc/platforms/52xx/Makefile index 2bc8cd0c5cfc..4e62486791e9 100644 --- a/arch/powerpc/platforms/52xx/Makefile +++ b/arch/powerpc/platforms/52xx/Makefile | |||
@@ -14,5 +14,4 @@ ifeq ($(CONFIG_PPC_LITE5200),y) | |||
14 | obj-$(CONFIG_PM) += lite5200_sleep.o lite5200_pm.o | 14 | obj-$(CONFIG_PM) += lite5200_sleep.o lite5200_pm.o |
15 | endif | 15 | endif |
16 | 16 | ||
17 | obj-$(CONFIG_PPC_MPC5200_GPIO) += mpc52xx_gpio.o | ||
18 | obj-$(CONFIG_PPC_MPC5200_LPBFIFO) += mpc52xx_lpbfifo.o | 17 | obj-$(CONFIG_PPC_MPC5200_LPBFIFO) += mpc52xx_lpbfifo.o |
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index 2967002a9f82..363498697c2c 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig | |||
@@ -63,33 +63,58 @@ config GPIO_SYSFS | |||
63 | Kernel drivers may also request that a particular GPIO be | 63 | Kernel drivers may also request that a particular GPIO be |
64 | exported to userspace; this can be useful when debugging. | 64 | exported to userspace; this can be useful when debugging. |
65 | 65 | ||
66 | config GPIO_GENERIC | ||
67 | tristate | ||
68 | |||
66 | # put drivers in the right section, in alphabetical order | 69 | # put drivers in the right section, in alphabetical order |
67 | 70 | ||
71 | config GPIO_DA9052 | ||
72 | tristate "Dialog DA9052 GPIO" | ||
73 | depends on PMIC_DA9052 | ||
74 | help | ||
75 | Say yes here to enable the GPIO driver for the DA9052 chip. | ||
76 | |||
68 | config GPIO_MAX730X | 77 | config GPIO_MAX730X |
69 | tristate | 78 | tristate |
70 | 79 | ||
71 | comment "Memory mapped GPIO drivers:" | 80 | comment "Memory mapped GPIO drivers:" |
72 | 81 | ||
73 | config GPIO_BASIC_MMIO_CORE | 82 | config GPIO_GENERIC_PLATFORM |
74 | tristate | 83 | tristate "Generic memory-mapped GPIO controller support (MMIO platform device)" |
75 | help | 84 | select GPIO_GENERIC |
76 | Provides core functionality for basic memory-mapped GPIO controllers. | ||
77 | |||
78 | config GPIO_BASIC_MMIO | ||
79 | tristate "Basic memory-mapped GPIO controllers support" | ||
80 | select GPIO_BASIC_MMIO_CORE | ||
81 | help | 85 | help |
82 | Say yes here to support basic memory-mapped GPIO controllers. | 86 | Say yes here to support basic platform_device memory-mapped GPIO controllers. |
83 | 87 | ||
84 | config GPIO_IT8761E | 88 | config GPIO_IT8761E |
85 | tristate "IT8761E GPIO support" | 89 | tristate "IT8761E GPIO support" |
86 | help | 90 | help |
87 | Say yes here to support GPIO functionality of IT8761E super I/O chip. | 91 | Say yes here to support GPIO functionality of IT8761E super I/O chip. |
88 | 92 | ||
93 | config GPIO_EP93XX | ||
94 | def_bool y | ||
95 | depends on ARCH_EP93XX | ||
96 | select GPIO_GENERIC | ||
97 | |||
89 | config GPIO_EXYNOS4 | 98 | config GPIO_EXYNOS4 |
90 | def_bool y | 99 | def_bool y |
91 | depends on CPU_EXYNOS4210 | 100 | depends on CPU_EXYNOS4210 |
92 | 101 | ||
102 | config GPIO_MPC5200 | ||
103 | def_bool y | ||
104 | depends on PPC_MPC52xx | ||
105 | |||
106 | config GPIO_MXC | ||
107 | def_bool y | ||
108 | depends on ARCH_MXC | ||
109 | select GPIO_GENERIC | ||
110 | select GENERIC_IRQ_CHIP | ||
111 | |||
112 | config GPIO_MXS | ||
113 | def_bool y | ||
114 | depends on ARCH_MXS | ||
115 | select GPIO_GENERIC | ||
116 | select GENERIC_IRQ_CHIP | ||
117 | |||
93 | config GPIO_PLAT_SAMSUNG | 118 | config GPIO_PLAT_SAMSUNG |
94 | def_bool y | 119 | def_bool y |
95 | depends on SAMSUNG_GPIOLIB_4BIT | 120 | depends on SAMSUNG_GPIOLIB_4BIT |
@@ -137,9 +162,6 @@ config GPIO_SCH | |||
137 | The Intel Tunnel Creek processor has 5 GPIOs powered by the | 162 | The Intel Tunnel Creek processor has 5 GPIOs powered by the |
138 | core power rail and 9 from suspend power supply. | 163 | core power rail and 9 from suspend power supply. |
139 | 164 | ||
140 | This driver can also be built as a module. If so, the module | ||
141 | will be called sch-gpio. | ||
142 | |||
143 | config GPIO_VX855 | 165 | config GPIO_VX855 |
144 | tristate "VIA VX855/VX875 GPIO" | 166 | tristate "VIA VX855/VX875 GPIO" |
145 | depends on MFD_SUPPORT && PCI | 167 | depends on MFD_SUPPORT && PCI |
@@ -202,9 +224,6 @@ config GPIO_PCA953X | |||
202 | 224 | ||
203 | 16 bits: pca9535, pca9539, pca9555, tca6416 | 225 | 16 bits: pca9535, pca9539, pca9555, tca6416 |
204 | 226 | ||
205 | This driver can also be built as a module. If so, the module | ||
206 | will be called pca953x. | ||
207 | |||
208 | config GPIO_PCA953X_IRQ | 227 | config GPIO_PCA953X_IRQ |
209 | bool "Interrupt controller support for PCA953x" | 228 | bool "Interrupt controller support for PCA953x" |
210 | depends on GPIO_PCA953X=y | 229 | depends on GPIO_PCA953X=y |
@@ -296,17 +315,12 @@ config GPIO_ADP5520 | |||
296 | This option enables support for on-chip GPIO found | 315 | This option enables support for on-chip GPIO found |
297 | on Analog Devices ADP5520 PMICs. | 316 | on Analog Devices ADP5520 PMICs. |
298 | 317 | ||
299 | To compile this driver as a module, choose M here: the module will | ||
300 | be called adp5520-gpio. | ||
301 | |||
302 | config GPIO_ADP5588 | 318 | config GPIO_ADP5588 |
303 | tristate "ADP5588 I2C GPIO expander" | 319 | tristate "ADP5588 I2C GPIO expander" |
304 | depends on I2C | 320 | depends on I2C |
305 | help | 321 | help |
306 | This option enables support for 18 GPIOs found | 322 | This option enables support for 18 GPIOs found |
307 | on Analog Devices ADP5588 GPIO Expanders. | 323 | on Analog Devices ADP5588 GPIO Expanders. |
308 | To compile this driver as a module, choose M here: the module will be | ||
309 | called adp5588-gpio. | ||
310 | 324 | ||
311 | config GPIO_ADP5588_IRQ | 325 | config GPIO_ADP5588_IRQ |
312 | bool "Interrupt controller support for ADP5588" | 326 | bool "Interrupt controller support for ADP5588" |
@@ -398,10 +412,11 @@ config GPIO_MAX7301 | |||
398 | GPIO driver for Maxim MAX7301 SPI-based GPIO expander. | 412 | GPIO driver for Maxim MAX7301 SPI-based GPIO expander. |
399 | 413 | ||
400 | config GPIO_MCP23S08 | 414 | config GPIO_MCP23S08 |
401 | tristate "Microchip MCP23Sxx I/O expander" | 415 | tristate "Microchip MCP23xxx I/O expander" |
402 | depends on SPI_MASTER | 416 | depends on SPI_MASTER || I2C |
403 | help | 417 | help |
404 | SPI driver for Microchip MCP23S08/MPC23S17 I/O expanders. | 418 | SPI/I2C driver for Microchip MCP23S08/MCP23S17/MCP23008/MCP23017 |
419 | I/O expanders. | ||
405 | This provides a GPIO interface supporting inputs and outputs. | 420 | This provides a GPIO interface supporting inputs and outputs. |
406 | 421 | ||
407 | config GPIO_MC33880 | 422 | config GPIO_MC33880 |
@@ -428,9 +443,6 @@ config GPIO_UCB1400 | |||
428 | This enables support for the Philips UCB1400 GPIO pins. | 443 | This enables support for the Philips UCB1400 GPIO pins. |
429 | The UCB1400 is an AC97 audio codec. | 444 | The UCB1400 is an AC97 audio codec. |
430 | 445 | ||
431 | To compile this driver as a module, choose M here: the | ||
432 | module will be called ucb1400_gpio. | ||
433 | |||
434 | comment "MODULbus GPIO expanders:" | 446 | comment "MODULbus GPIO expanders:" |
435 | 447 | ||
436 | config GPIO_JANZ_TTL | 448 | config GPIO_JANZ_TTL |
@@ -441,7 +453,7 @@ config GPIO_JANZ_TTL | |||
441 | This driver provides support for driving the pins in output | 453 | This driver provides support for driving the pins in output |
442 | mode only. Input mode is not supported. | 454 | mode only. Input mode is not supported. |
443 | 455 | ||
444 | config AB8500_GPIO | 456 | config GPIO_AB8500 |
445 | bool "ST-Ericsson AB8500 Mixed Signal Circuit gpio functions" | 457 | bool "ST-Ericsson AB8500 Mixed Signal Circuit gpio functions" |
446 | depends on AB8500_CORE && BROKEN | 458 | depends on AB8500_CORE && BROKEN |
447 | help | 459 | help |
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile index b605f8ec6fbe..720711251391 100644 --- a/drivers/gpio/Makefile +++ b/drivers/gpio/Makefile | |||
@@ -4,47 +4,56 @@ ccflags-$(CONFIG_DEBUG_GPIO) += -DDEBUG | |||
4 | 4 | ||
5 | obj-$(CONFIG_GPIOLIB) += gpiolib.o | 5 | obj-$(CONFIG_GPIOLIB) += gpiolib.o |
6 | 6 | ||
7 | obj-$(CONFIG_GPIO_ADP5520) += adp5520-gpio.o | 7 | # Device drivers. Generally keep list sorted alphabetically |
8 | obj-$(CONFIG_GPIO_ADP5588) += adp5588-gpio.o | 8 | obj-$(CONFIG_GPIO_GENERIC) += gpio-generic.o |
9 | obj-$(CONFIG_GPIO_BASIC_MMIO_CORE) += basic_mmio_gpio.o | 9 | |
10 | obj-$(CONFIG_GPIO_BASIC_MMIO) += basic_mmio_gpio.o | 10 | obj-$(CONFIG_GPIO_74X164) += gpio-74x164.o |
11 | obj-$(CONFIG_GPIO_AB8500) += gpio-ab8500.o | ||
12 | obj-$(CONFIG_GPIO_ADP5520) += gpio-adp5520.o | ||
13 | obj-$(CONFIG_GPIO_ADP5588) += gpio-adp5588.o | ||
14 | obj-$(CONFIG_GPIO_BT8XX) += gpio-bt8xx.o | ||
15 | obj-$(CONFIG_GPIO_CS5535) += gpio-cs5535.o | ||
16 | obj-$(CONFIG_GPIO_DA9052) += gpio-da9052.o | ||
17 | obj-$(CONFIG_GPIO_EP93XX) += gpio-ep93xx.o | ||
11 | obj-$(CONFIG_GPIO_EXYNOS4) += gpio-exynos4.o | 18 | obj-$(CONFIG_GPIO_EXYNOS4) += gpio-exynos4.o |
19 | obj-$(CONFIG_GPIO_IT8761E) += gpio-it8761e.o | ||
20 | obj-$(CONFIG_GPIO_JANZ_TTL) += gpio-janz-ttl.o | ||
21 | obj-$(CONFIG_GPIO_LANGWELL) += gpio-langwell.o | ||
22 | obj-$(CONFIG_GPIO_MAX730X) += gpio-max730x.o | ||
23 | obj-$(CONFIG_GPIO_MAX7300) += gpio-max7300.o | ||
24 | obj-$(CONFIG_GPIO_MAX7301) += gpio-max7301.o | ||
25 | obj-$(CONFIG_GPIO_MAX732X) += gpio-max732x.o | ||
26 | obj-$(CONFIG_GPIO_MC33880) += gpio-mc33880.o | ||
27 | obj-$(CONFIG_GPIO_MCP23S08) += gpio-mcp23s08.o | ||
28 | obj-$(CONFIG_GPIO_ML_IOH) += gpio-ml-ioh.o | ||
29 | obj-$(CONFIG_GPIO_MPC5200) += gpio-mpc5200.o | ||
30 | obj-$(CONFIG_GPIO_MXC) += gpio-mxc.o | ||
31 | obj-$(CONFIG_GPIO_MXS) += gpio-mxs.o | ||
32 | obj-$(CONFIG_PLAT_NOMADIK) += gpio-nomadik.o | ||
33 | obj-$(CONFIG_ARCH_OMAP) += gpio-omap.o | ||
34 | obj-$(CONFIG_GPIO_PCA953X) += gpio-pca953x.o | ||
35 | obj-$(CONFIG_GPIO_PCF857X) += gpio-pcf857x.o | ||
36 | obj-$(CONFIG_GPIO_PCH) += gpio-pch.o | ||
37 | obj-$(CONFIG_GPIO_PL061) += gpio-pl061.o | ||
38 | obj-$(CONFIG_GPIO_RDC321X) += gpio-rdc321x.o | ||
39 | |||
12 | obj-$(CONFIG_GPIO_PLAT_SAMSUNG) += gpio-plat-samsung.o | 40 | obj-$(CONFIG_GPIO_PLAT_SAMSUNG) += gpio-plat-samsung.o |
13 | obj-$(CONFIG_GPIO_S5PC100) += gpio-s5pc100.o | 41 | obj-$(CONFIG_GPIO_S5PC100) += gpio-s5pc100.o |
14 | obj-$(CONFIG_GPIO_S5PV210) += gpio-s5pv210.o | 42 | obj-$(CONFIG_GPIO_S5PV210) += gpio-s5pv210.o |
15 | obj-$(CONFIG_GPIO_LANGWELL) += langwell_gpio.o | 43 | |
16 | obj-$(CONFIG_GPIO_MAX730X) += max730x.o | 44 | obj-$(CONFIG_GPIO_SCH) += gpio-sch.o |
17 | obj-$(CONFIG_GPIO_MAX7300) += max7300.o | 45 | obj-$(CONFIG_GPIO_STMPE) += gpio-stmpe.o |
18 | obj-$(CONFIG_GPIO_MAX7301) += max7301.o | 46 | obj-$(CONFIG_GPIO_SX150X) += gpio-sx150x.o |
19 | obj-$(CONFIG_GPIO_MAX732X) += max732x.o | 47 | obj-$(CONFIG_GPIO_TC3589X) += gpio-tc3589x.o |
20 | obj-$(CONFIG_GPIO_MC33880) += mc33880.o | 48 | obj-$(CONFIG_ARCH_TEGRA) += gpio-tegra.o |
21 | obj-$(CONFIG_GPIO_MCP23S08) += mcp23s08.o | 49 | obj-$(CONFIG_GPIO_TIMBERDALE) += gpio-timberdale.o |
22 | obj-$(CONFIG_GPIO_74X164) += 74x164.o | 50 | obj-$(CONFIG_GPIO_TPS65910) += gpio-tps65910.o |
23 | obj-$(CONFIG_ARCH_OMAP) += gpio-omap.o | 51 | obj-$(CONFIG_GPIO_TWL4030) += gpio-twl4030.o |
24 | obj-$(CONFIG_GPIO_PCA953X) += pca953x.o | ||
25 | obj-$(CONFIG_GPIO_PCF857X) += pcf857x.o | ||
26 | obj-$(CONFIG_GPIO_PCH) += pch_gpio.o | ||
27 | obj-$(CONFIG_GPIO_PL061) += pl061.o | ||
28 | obj-$(CONFIG_GPIO_STMPE) += stmpe-gpio.o | ||
29 | obj-$(CONFIG_GPIO_TC3589X) += tc3589x-gpio.o | ||
30 | obj-$(CONFIG_GPIO_TIMBERDALE) += timbgpio.o | ||
31 | obj-$(CONFIG_GPIO_TWL4030) += twl4030-gpio.o | ||
32 | obj-$(CONFIG_GPIO_UCB1400) += ucb1400_gpio.o | ||
33 | obj-$(CONFIG_GPIO_XILINX) += xilinx_gpio.o | ||
34 | obj-$(CONFIG_GPIO_CS5535) += cs5535-gpio.o | ||
35 | obj-$(CONFIG_GPIO_BT8XX) += bt8xxgpio.o | ||
36 | obj-$(CONFIG_GPIO_IT8761E) += it8761e_gpio.o | ||
37 | obj-$(CONFIG_GPIO_VR41XX) += vr41xx_giu.o | ||
38 | obj-$(CONFIG_GPIO_WM831X) += wm831x-gpio.o | ||
39 | obj-$(CONFIG_GPIO_WM8350) += wm8350-gpiolib.o | ||
40 | obj-$(CONFIG_GPIO_WM8994) += wm8994-gpio.o | ||
41 | obj-$(CONFIG_GPIO_SCH) += sch_gpio.o | ||
42 | obj-$(CONFIG_MACH_U300) += gpio-u300.o | 52 | obj-$(CONFIG_MACH_U300) += gpio-u300.o |
43 | obj-$(CONFIG_PLAT_NOMADIK) += gpio-nomadik.o | 53 | obj-$(CONFIG_GPIO_UCB1400) += gpio-ucb1400.o |
44 | obj-$(CONFIG_GPIO_RDC321X) += rdc321x-gpio.o | 54 | obj-$(CONFIG_GPIO_VR41XX) += gpio-vr41xx.o |
45 | obj-$(CONFIG_GPIO_JANZ_TTL) += janz-ttl.o | 55 | obj-$(CONFIG_GPIO_VX855) += gpio-vx855.o |
46 | obj-$(CONFIG_GPIO_SX150X) += sx150x.o | 56 | obj-$(CONFIG_GPIO_WM831X) += gpio-wm831x.o |
47 | obj-$(CONFIG_GPIO_VX855) += vx855_gpio.o | 57 | obj-$(CONFIG_GPIO_WM8350) += gpio-wm8350.o |
48 | obj-$(CONFIG_GPIO_ML_IOH) += ml_ioh_gpio.o | 58 | obj-$(CONFIG_GPIO_WM8994) += gpio-wm8994.o |
49 | obj-$(CONFIG_AB8500_GPIO) += ab8500-gpio.o | 59 | obj-$(CONFIG_GPIO_XILINX) += gpio-xilinx.o |
50 | obj-$(CONFIG_GPIO_TPS65910) += tps65910-gpio.o | ||
diff --git a/drivers/gpio/74x164.c b/drivers/gpio/gpio-74x164.c index 84e070219839..ff525c0958dd 100644 --- a/drivers/gpio/74x164.c +++ b/drivers/gpio/gpio-74x164.c | |||
@@ -16,9 +16,6 @@ | |||
16 | #include <linux/gpio.h> | 16 | #include <linux/gpio.h> |
17 | #include <linux/slab.h> | 17 | #include <linux/slab.h> |
18 | 18 | ||
19 | #define GEN_74X164_GPIO_COUNT 8 | ||
20 | |||
21 | |||
22 | struct gen_74x164_chip { | 19 | struct gen_74x164_chip { |
23 | struct spi_device *spi; | 20 | struct spi_device *spi; |
24 | struct gpio_chip gpio_chip; | 21 | struct gpio_chip gpio_chip; |
@@ -26,9 +23,7 @@ struct gen_74x164_chip { | |||
26 | u8 port_config; | 23 | u8 port_config; |
27 | }; | 24 | }; |
28 | 25 | ||
29 | static void gen_74x164_set_value(struct gpio_chip *, unsigned, int); | 26 | static struct gen_74x164_chip *gpio_to_74x164_chip(struct gpio_chip *gc) |
30 | |||
31 | static struct gen_74x164_chip *gpio_to_chip(struct gpio_chip *gc) | ||
32 | { | 27 | { |
33 | return container_of(gc, struct gen_74x164_chip, gpio_chip); | 28 | return container_of(gc, struct gen_74x164_chip, gpio_chip); |
34 | } | 29 | } |
@@ -39,16 +34,9 @@ static int __gen_74x164_write_config(struct gen_74x164_chip *chip) | |||
39 | &chip->port_config, sizeof(chip->port_config)); | 34 | &chip->port_config, sizeof(chip->port_config)); |
40 | } | 35 | } |
41 | 36 | ||
42 | static int gen_74x164_direction_output(struct gpio_chip *gc, | ||
43 | unsigned offset, int val) | ||
44 | { | ||
45 | gen_74x164_set_value(gc, offset, val); | ||
46 | return 0; | ||
47 | } | ||
48 | |||
49 | static int gen_74x164_get_value(struct gpio_chip *gc, unsigned offset) | 37 | static int gen_74x164_get_value(struct gpio_chip *gc, unsigned offset) |
50 | { | 38 | { |
51 | struct gen_74x164_chip *chip = gpio_to_chip(gc); | 39 | struct gen_74x164_chip *chip = gpio_to_74x164_chip(gc); |
52 | int ret; | 40 | int ret; |
53 | 41 | ||
54 | mutex_lock(&chip->lock); | 42 | mutex_lock(&chip->lock); |
@@ -61,7 +49,7 @@ static int gen_74x164_get_value(struct gpio_chip *gc, unsigned offset) | |||
61 | static void gen_74x164_set_value(struct gpio_chip *gc, | 49 | static void gen_74x164_set_value(struct gpio_chip *gc, |
62 | unsigned offset, int val) | 50 | unsigned offset, int val) |
63 | { | 51 | { |
64 | struct gen_74x164_chip *chip = gpio_to_chip(gc); | 52 | struct gen_74x164_chip *chip = gpio_to_74x164_chip(gc); |
65 | 53 | ||
66 | mutex_lock(&chip->lock); | 54 | mutex_lock(&chip->lock); |
67 | if (val) | 55 | if (val) |
@@ -73,6 +61,13 @@ static void gen_74x164_set_value(struct gpio_chip *gc, | |||
73 | mutex_unlock(&chip->lock); | 61 | mutex_unlock(&chip->lock); |
74 | } | 62 | } |
75 | 63 | ||
64 | static int gen_74x164_direction_output(struct gpio_chip *gc, | ||
65 | unsigned offset, int val) | ||
66 | { | ||
67 | gen_74x164_set_value(gc, offset, val); | ||
68 | return 0; | ||
69 | } | ||
70 | |||
76 | static int __devinit gen_74x164_probe(struct spi_device *spi) | 71 | static int __devinit gen_74x164_probe(struct spi_device *spi) |
77 | { | 72 | { |
78 | struct gen_74x164_chip *chip; | 73 | struct gen_74x164_chip *chip; |
@@ -104,12 +99,12 @@ static int __devinit gen_74x164_probe(struct spi_device *spi) | |||
104 | 99 | ||
105 | chip->spi = spi; | 100 | chip->spi = spi; |
106 | 101 | ||
107 | chip->gpio_chip.label = GEN_74X164_DRIVER_NAME, | 102 | chip->gpio_chip.label = spi->modalias; |
108 | chip->gpio_chip.direction_output = gen_74x164_direction_output; | 103 | chip->gpio_chip.direction_output = gen_74x164_direction_output; |
109 | chip->gpio_chip.get = gen_74x164_get_value; | 104 | chip->gpio_chip.get = gen_74x164_get_value; |
110 | chip->gpio_chip.set = gen_74x164_set_value; | 105 | chip->gpio_chip.set = gen_74x164_set_value; |
111 | chip->gpio_chip.base = pdata->base; | 106 | chip->gpio_chip.base = pdata->base; |
112 | chip->gpio_chip.ngpio = GEN_74X164_GPIO_COUNT; | 107 | chip->gpio_chip.ngpio = 8; |
113 | chip->gpio_chip.can_sleep = 1; | 108 | chip->gpio_chip.can_sleep = 1; |
114 | chip->gpio_chip.dev = &spi->dev; | 109 | chip->gpio_chip.dev = &spi->dev; |
115 | chip->gpio_chip.owner = THIS_MODULE; | 110 | chip->gpio_chip.owner = THIS_MODULE; |
@@ -157,7 +152,7 @@ static int __devexit gen_74x164_remove(struct spi_device *spi) | |||
157 | 152 | ||
158 | static struct spi_driver gen_74x164_driver = { | 153 | static struct spi_driver gen_74x164_driver = { |
159 | .driver = { | 154 | .driver = { |
160 | .name = GEN_74X164_DRIVER_NAME, | 155 | .name = "74x164", |
161 | .owner = THIS_MODULE, | 156 | .owner = THIS_MODULE, |
162 | }, | 157 | }, |
163 | .probe = gen_74x164_probe, | 158 | .probe = gen_74x164_probe, |
diff --git a/drivers/gpio/ab8500-gpio.c b/drivers/gpio/gpio-ab8500.c index 970053c89ff7..970053c89ff7 100644 --- a/drivers/gpio/ab8500-gpio.c +++ b/drivers/gpio/gpio-ab8500.c | |||
diff --git a/drivers/gpio/adp5520-gpio.c b/drivers/gpio/gpio-adp5520.c index 9f2781537001..9f2781537001 100644 --- a/drivers/gpio/adp5520-gpio.c +++ b/drivers/gpio/gpio-adp5520.c | |||
diff --git a/drivers/gpio/adp5588-gpio.c b/drivers/gpio/gpio-adp5588.c index 3525ad918771..3525ad918771 100644 --- a/drivers/gpio/adp5588-gpio.c +++ b/drivers/gpio/gpio-adp5588.c | |||
diff --git a/drivers/gpio/bt8xxgpio.c b/drivers/gpio/gpio-bt8xx.c index aa4f09ad3ced..aa4f09ad3ced 100644 --- a/drivers/gpio/bt8xxgpio.c +++ b/drivers/gpio/gpio-bt8xx.c | |||
diff --git a/drivers/gpio/cs5535-gpio.c b/drivers/gpio/gpio-cs5535.c index 6e16cba56ad2..6e16cba56ad2 100644 --- a/drivers/gpio/cs5535-gpio.c +++ b/drivers/gpio/gpio-cs5535.c | |||
diff --git a/drivers/gpio/gpio-da9052.c b/drivers/gpio/gpio-da9052.c new file mode 100644 index 000000000000..038f5eb8b13d --- /dev/null +++ b/drivers/gpio/gpio-da9052.c | |||
@@ -0,0 +1,277 @@ | |||
1 | /* | ||
2 | * GPIO Driver for Dialog DA9052 PMICs. | ||
3 | * | ||
4 | * Copyright(c) 2011 Dialog Semiconductor Ltd. | ||
5 | * | ||
6 | * Author: David Dajun Chen <dchen@diasemi.com> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify it | ||
9 | * under the terms of the GNU General Public License as published by the | ||
10 | * Free Software Foundation; either version 2 of the License, or (at your | ||
11 | * option) any later version. | ||
12 | * | ||
13 | */ | ||
14 | #include <linux/module.h> | ||
15 | #include <linux/fs.h> | ||
16 | #include <linux/uaccess.h> | ||
17 | #include <linux/platform_device.h> | ||
18 | #include <linux/gpio.h> | ||
19 | #include <linux/syscalls.h> | ||
20 | #include <linux/seq_file.h> | ||
21 | |||
22 | #include <linux/mfd/da9052/da9052.h> | ||
23 | #include <linux/mfd/da9052/reg.h> | ||
24 | #include <linux/mfd/da9052/pdata.h> | ||
25 | #include <linux/mfd/da9052/gpio.h> | ||
26 | |||
27 | #define DA9052_INPUT 1 | ||
28 | #define DA9052_OUTPUT_OPENDRAIN 2 | ||
29 | #define DA9052_OUTPUT_PUSHPULL 3 | ||
30 | |||
31 | #define DA9052_SUPPLY_VDD_IO1 0 | ||
32 | |||
33 | #define DA9052_DEBOUNCING_OFF 0 | ||
34 | #define DA9052_DEBOUNCING_ON 1 | ||
35 | |||
36 | #define DA9052_OUTPUT_LOWLEVEL 0 | ||
37 | |||
38 | #define DA9052_ACTIVE_LOW 0 | ||
39 | #define DA9052_ACTIVE_HIGH 1 | ||
40 | |||
41 | #define DA9052_GPIO_MAX_PORTS_PER_REGISTER 8 | ||
42 | #define DA9052_GPIO_SHIFT_COUNT(no) (no%8) | ||
43 | #define DA9052_GPIO_MASK_UPPER_NIBBLE 0xF0 | ||
44 | #define DA9052_GPIO_MASK_LOWER_NIBBLE 0x0F | ||
45 | #define DA9052_GPIO_NIBBLE_SHIFT 4 | ||
46 | |||
47 | struct da9052_gpio { | ||
48 | struct da9052 *da9052; | ||
49 | struct gpio_chip gp; | ||
50 | }; | ||
51 | |||
52 | static inline struct da9052_gpio *to_da9052_gpio(struct gpio_chip *chip) | ||
53 | { | ||
54 | return container_of(chip, struct da9052_gpio, gp); | ||
55 | } | ||
56 | |||
57 | static unsigned char da9052_gpio_port_odd(unsigned offset) | ||
58 | { | ||
59 | return offset % 2; | ||
60 | } | ||
61 | |||
62 | static int da9052_gpio_get(struct gpio_chip *gc, unsigned offset) | ||
63 | { | ||
64 | struct da9052_gpio *gpio = to_da9052_gpio(gc); | ||
65 | int da9052_port_direction = 0; | ||
66 | int ret; | ||
67 | |||
68 | ret = da9052_reg_read(gpio->da9052, | ||
69 | DA9052_GPIO_0_1_REG + (offset >> 1)); | ||
70 | if (ret < 0) | ||
71 | return ret; | ||
72 | |||
73 | if (da9052_gpio_port_odd(offset)) { | ||
74 | da9052_port_direction = ret & DA9052_GPIO_ODD_PORT_PIN; | ||
75 | da9052_port_direction >>= 4; | ||
76 | } else { | ||
77 | da9052_port_direction = ret & DA9052_GPIO_EVEN_PORT_PIN; | ||
78 | } | ||
79 | |||
80 | switch (da9052_port_direction) { | ||
81 | case DA9052_INPUT: | ||
82 | if (offset < DA9052_GPIO_MAX_PORTS_PER_REGISTER) | ||
83 | ret = da9052_reg_read(gpio->da9052, | ||
84 | DA9052_STATUS_C_REG); | ||
85 | else | ||
86 | ret = da9052_reg_read(gpio->da9052, | ||
87 | DA9052_STATUS_D_REG); | ||
88 | if (ret < 0) | ||
89 | return ret; | ||
90 | if (ret & (1 << DA9052_GPIO_SHIFT_COUNT(offset))) | ||
91 | return 1; | ||
92 | else | ||
93 | return 0; | ||
94 | case DA9052_OUTPUT_PUSHPULL: | ||
95 | if (da9052_gpio_port_odd(offset)) | ||
96 | return ret & DA9052_GPIO_ODD_PORT_MODE; | ||
97 | else | ||
98 | return ret & DA9052_GPIO_EVEN_PORT_MODE; | ||
99 | default: | ||
100 | return -EINVAL; | ||
101 | } | ||
102 | } | ||
103 | |||
104 | static void da9052_gpio_set(struct gpio_chip *gc, unsigned offset, int value) | ||
105 | { | ||
106 | struct da9052_gpio *gpio = to_da9052_gpio(gc); | ||
107 | unsigned char register_value = 0; | ||
108 | int ret; | ||
109 | |||
110 | if (da9052_gpio_port_odd(offset)) { | ||
111 | if (value) { | ||
112 | register_value = DA9052_GPIO_ODD_PORT_MODE; | ||
113 | ret = da9052_reg_update(gpio->da9052, (offset >> 1) + | ||
114 | DA9052_GPIO_0_1_REG, | ||
115 | DA9052_GPIO_ODD_PORT_MODE, | ||
116 | register_value); | ||
117 | if (ret != 0) | ||
118 | dev_err(gpio->da9052->dev, | ||
119 | "Failed to updated gpio odd reg,%d", | ||
120 | ret); | ||
121 | } | ||
122 | } else { | ||
123 | if (value) { | ||
124 | register_value = DA9052_GPIO_EVEN_PORT_MODE; | ||
125 | ret = da9052_reg_update(gpio->da9052, (offset >> 1) + | ||
126 | DA9052_GPIO_0_1_REG, | ||
127 | DA9052_GPIO_EVEN_PORT_MODE, | ||
128 | register_value); | ||
129 | if (ret != 0) | ||
130 | dev_err(gpio->da9052->dev, | ||
131 | "Failed to updated gpio even reg,%d", | ||
132 | ret); | ||
133 | } | ||
134 | } | ||
135 | } | ||
136 | |||
137 | static int da9052_gpio_direction_input(struct gpio_chip *gc, unsigned offset) | ||
138 | { | ||
139 | struct da9052_gpio *gpio = to_da9052_gpio(gc); | ||
140 | unsigned char register_value; | ||
141 | int ret; | ||
142 | |||
143 | /* Format: function - 2 bits type - 1 bit mode - 1 bit */ | ||
144 | register_value = DA9052_INPUT | DA9052_ACTIVE_LOW << 2 | | ||
145 | DA9052_DEBOUNCING_ON << 3; | ||
146 | |||
147 | if (da9052_gpio_port_odd(offset)) | ||
148 | ret = da9052_reg_update(gpio->da9052, (offset >> 1) + | ||
149 | DA9052_GPIO_0_1_REG, | ||
150 | DA9052_GPIO_MASK_UPPER_NIBBLE, | ||
151 | (register_value << | ||
152 | DA9052_GPIO_NIBBLE_SHIFT)); | ||
153 | else | ||
154 | ret = da9052_reg_update(gpio->da9052, (offset >> 1) + | ||
155 | DA9052_GPIO_0_1_REG, | ||
156 | DA9052_GPIO_MASK_LOWER_NIBBLE, | ||
157 | register_value); | ||
158 | |||
159 | return ret; | ||
160 | } | ||
161 | |||
162 | static int da9052_gpio_direction_output(struct gpio_chip *gc, | ||
163 | unsigned offset, int value) | ||
164 | { | ||
165 | struct da9052_gpio *gpio = to_da9052_gpio(gc); | ||
166 | unsigned char register_value; | ||
167 | int ret; | ||
168 | |||
169 | /* Format: Function - 2 bits Type - 1 bit Mode - 1 bit */ | ||
170 | register_value = DA9052_OUTPUT_PUSHPULL | DA9052_SUPPLY_VDD_IO1 << 2 | | ||
171 | value << 3; | ||
172 | |||
173 | if (da9052_gpio_port_odd(offset)) | ||
174 | ret = da9052_reg_update(gpio->da9052, (offset >> 1) + | ||
175 | DA9052_GPIO_0_1_REG, | ||
176 | DA9052_GPIO_MASK_UPPER_NIBBLE, | ||
177 | (register_value << | ||
178 | DA9052_GPIO_NIBBLE_SHIFT)); | ||
179 | else | ||
180 | ret = da9052_reg_update(gpio->da9052, (offset >> 1) + | ||
181 | DA9052_GPIO_0_1_REG, | ||
182 | DA9052_GPIO_MASK_LOWER_NIBBLE, | ||
183 | register_value); | ||
184 | |||
185 | return ret; | ||
186 | } | ||
187 | |||
188 | static int da9052_gpio_to_irq(struct gpio_chip *gc, u32 offset) | ||
189 | { | ||
190 | struct da9052_gpio *gpio = to_da9052_gpio(gc); | ||
191 | struct da9052 *da9052 = gpio->da9052; | ||
192 | |||
193 | return da9052->irq_base + DA9052_IRQ_GPI0 + offset; | ||
194 | } | ||
195 | |||
196 | static struct gpio_chip reference_gp __devinitdata = { | ||
197 | .label = "da9052-gpio", | ||
198 | .owner = THIS_MODULE, | ||
199 | .get = da9052_gpio_get, | ||
200 | .set = da9052_gpio_set, | ||
201 | .direction_input = da9052_gpio_direction_input, | ||
202 | .direction_output = da9052_gpio_direction_output, | ||
203 | .to_irq = da9052_gpio_to_irq, | ||
204 | .can_sleep = 1; | ||
205 | .ngpio = 16; | ||
206 | .base = -1; | ||
207 | }; | ||
208 | |||
209 | static int __devinit da9052_gpio_probe(struct platform_device *pdev) | ||
210 | { | ||
211 | struct da9052_gpio *gpio; | ||
212 | struct da9052_pdata *pdata; | ||
213 | int ret; | ||
214 | |||
215 | gpio = kzalloc(sizeof(*gpio), GFP_KERNEL); | ||
216 | if (gpio == NULL) | ||
217 | return -ENOMEM; | ||
218 | |||
219 | gpio->da9052 = dev_get_drvdata(pdev->dev.parent); | ||
220 | pdata = gpio->da9052->dev->platform_data; | ||
221 | |||
222 | gpio->gp = reference_gp; | ||
223 | if (pdata && pdata->gpio_base) | ||
224 | gpio->gp.base = pdata->gpio_base; | ||
225 | |||
226 | ret = gpiochip_add(&gpio->gp); | ||
227 | if (ret < 0) { | ||
228 | dev_err(&pdev->dev, "Could not register gpiochip, %d\n", ret); | ||
229 | goto err_mem; | ||
230 | } | ||
231 | |||
232 | platform_set_drvdata(pdev, gpio); | ||
233 | |||
234 | return 0; | ||
235 | |||
236 | err_mem: | ||
237 | kfree(gpio); | ||
238 | return ret; | ||
239 | } | ||
240 | |||
241 | static int __devexit da9052_gpio_remove(struct platform_device *pdev) | ||
242 | { | ||
243 | struct da9052_gpio *gpio = platform_get_drvdata(pdev); | ||
244 | int ret; | ||
245 | |||
246 | ret = gpiochip_remove(&gpio->gp); | ||
247 | if (ret == 0) | ||
248 | kfree(gpio); | ||
249 | |||
250 | return ret; | ||
251 | } | ||
252 | |||
253 | static struct platform_driver da9052_gpio_driver = { | ||
254 | .probe = da9052_gpio_probe, | ||
255 | .remove = __devexit_p(da9052_gpio_remove), | ||
256 | .driver = { | ||
257 | .name = "da9052-gpio", | ||
258 | .owner = THIS_MODULE, | ||
259 | }, | ||
260 | }; | ||
261 | |||
262 | static int __init da9052_gpio_init(void) | ||
263 | { | ||
264 | return platform_driver_register(&da9052_gpio_driver); | ||
265 | } | ||
266 | module_init(da9052_gpio_init); | ||
267 | |||
268 | static void __exit da9052_gpio_exit(void) | ||
269 | { | ||
270 | return platform_driver_unregister(&da9052_gpio_driver); | ||
271 | } | ||
272 | module_exit(da9052_gpio_exit); | ||
273 | |||
274 | MODULE_AUTHOR("David Dajun Chen <dchen@diasemi.com>"); | ||
275 | MODULE_DESCRIPTION("DA9052 GPIO Device Driver"); | ||
276 | MODULE_LICENSE("GPL"); | ||
277 | MODULE_ALIAS("platform:da9052-gpio"); | ||
diff --git a/arch/arm/mach-ep93xx/gpio.c b/drivers/gpio/gpio-ep93xx.c index 415dce37b88c..3bfd3417ab11 100644 --- a/arch/arm/mach-ep93xx/gpio.c +++ b/drivers/gpio/gpio-ep93xx.c | |||
@@ -1,9 +1,8 @@ | |||
1 | /* | 1 | /* |
2 | * linux/arch/arm/mach-ep93xx/gpio.c | ||
3 | * | ||
4 | * Generic EP93xx GPIO handling | 2 | * Generic EP93xx GPIO handling |
5 | * | 3 | * |
6 | * Copyright (c) 2008 Ryan Mallon <ryan@bluewatersys.com> | 4 | * Copyright (c) 2008 Ryan Mallon <ryan@bluewatersys.com> |
5 | * Copyright (c) 2011 H Hartley Sweeten <hsweeten@visionengravers.com> | ||
7 | * | 6 | * |
8 | * Based on code originally from: | 7 | * Based on code originally from: |
9 | * linux/arch/arm/mach-ep93xx/core.c | 8 | * linux/arch/arm/mach-ep93xx/core.c |
@@ -13,17 +12,23 @@ | |||
13 | * published by the Free Software Foundation. | 12 | * published by the Free Software Foundation. |
14 | */ | 13 | */ |
15 | 14 | ||
16 | #define pr_fmt(fmt) "ep93xx " KBUILD_MODNAME ": " fmt | 15 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt |
17 | 16 | ||
18 | #include <linux/init.h> | 17 | #include <linux/init.h> |
19 | #include <linux/module.h> | 18 | #include <linux/platform_device.h> |
20 | #include <linux/seq_file.h> | ||
21 | #include <linux/io.h> | 19 | #include <linux/io.h> |
22 | #include <linux/gpio.h> | 20 | #include <linux/gpio.h> |
23 | #include <linux/irq.h> | 21 | #include <linux/irq.h> |
22 | #include <linux/slab.h> | ||
23 | #include <linux/basic_mmio_gpio.h> | ||
24 | 24 | ||
25 | #include <mach/hardware.h> | 25 | #include <mach/hardware.h> |
26 | 26 | ||
27 | struct ep93xx_gpio { | ||
28 | void __iomem *mmio_base; | ||
29 | struct bgpio_chip bgc[8]; | ||
30 | }; | ||
31 | |||
27 | /************************************************************************* | 32 | /************************************************************************* |
28 | * Interrupt handling for EP93xx on-chip GPIOs | 33 | * Interrupt handling for EP93xx on-chip GPIOs |
29 | *************************************************************************/ | 34 | *************************************************************************/ |
@@ -225,7 +230,7 @@ static struct irq_chip ep93xx_gpio_irq_chip = { | |||
225 | .irq_set_type = ep93xx_gpio_irq_type, | 230 | .irq_set_type = ep93xx_gpio_irq_type, |
226 | }; | 231 | }; |
227 | 232 | ||
228 | void __init ep93xx_gpio_init_irq(void) | 233 | static void ep93xx_gpio_init_irq(void) |
229 | { | 234 | { |
230 | int gpio_irq; | 235 | int gpio_irq; |
231 | 236 | ||
@@ -260,151 +265,141 @@ void __init ep93xx_gpio_init_irq(void) | |||
260 | /************************************************************************* | 265 | /************************************************************************* |
261 | * gpiolib interface for EP93xx on-chip GPIOs | 266 | * gpiolib interface for EP93xx on-chip GPIOs |
262 | *************************************************************************/ | 267 | *************************************************************************/ |
263 | struct ep93xx_gpio_chip { | 268 | struct ep93xx_gpio_bank { |
264 | struct gpio_chip chip; | 269 | const char *label; |
265 | 270 | int data; | |
266 | void __iomem *data_reg; | 271 | int dir; |
267 | void __iomem *data_dir_reg; | 272 | int base; |
273 | bool has_debounce; | ||
268 | }; | 274 | }; |
269 | 275 | ||
270 | #define to_ep93xx_gpio_chip(c) container_of(c, struct ep93xx_gpio_chip, chip) | 276 | #define EP93XX_GPIO_BANK(_label, _data, _dir, _base, _debounce) \ |
277 | { \ | ||
278 | .label = _label, \ | ||
279 | .data = _data, \ | ||
280 | .dir = _dir, \ | ||
281 | .base = _base, \ | ||
282 | .has_debounce = _debounce, \ | ||
283 | } | ||
284 | |||
285 | static struct ep93xx_gpio_bank ep93xx_gpio_banks[] = { | ||
286 | EP93XX_GPIO_BANK("A", 0x00, 0x10, 0, true), | ||
287 | EP93XX_GPIO_BANK("B", 0x04, 0x14, 8, true), | ||
288 | EP93XX_GPIO_BANK("C", 0x08, 0x18, 40, false), | ||
289 | EP93XX_GPIO_BANK("D", 0x0c, 0x1c, 24, false), | ||
290 | EP93XX_GPIO_BANK("E", 0x20, 0x24, 32, false), | ||
291 | EP93XX_GPIO_BANK("F", 0x30, 0x34, 16, true), | ||
292 | EP93XX_GPIO_BANK("G", 0x38, 0x3c, 48, false), | ||
293 | EP93XX_GPIO_BANK("H", 0x40, 0x44, 56, false), | ||
294 | }; | ||
271 | 295 | ||
272 | static int ep93xx_gpio_direction_input(struct gpio_chip *chip, unsigned offset) | 296 | static int ep93xx_gpio_set_debounce(struct gpio_chip *chip, |
297 | unsigned offset, unsigned debounce) | ||
273 | { | 298 | { |
274 | struct ep93xx_gpio_chip *ep93xx_chip = to_ep93xx_gpio_chip(chip); | 299 | int gpio = chip->base + offset; |
275 | unsigned long flags; | 300 | int irq = gpio_to_irq(gpio); |
276 | u8 v; | 301 | |
302 | if (irq < 0) | ||
303 | return -EINVAL; | ||
277 | 304 | ||
278 | local_irq_save(flags); | 305 | ep93xx_gpio_int_debounce(irq, debounce ? true : false); |
279 | v = __raw_readb(ep93xx_chip->data_dir_reg); | ||
280 | v &= ~(1 << offset); | ||
281 | __raw_writeb(v, ep93xx_chip->data_dir_reg); | ||
282 | local_irq_restore(flags); | ||
283 | 306 | ||
284 | return 0; | 307 | return 0; |
285 | } | 308 | } |
286 | 309 | ||
287 | static int ep93xx_gpio_direction_output(struct gpio_chip *chip, | 310 | static int ep93xx_gpio_add_bank(struct bgpio_chip *bgc, struct device *dev, |
288 | unsigned offset, int val) | 311 | void __iomem *mmio_base, struct ep93xx_gpio_bank *bank) |
289 | { | 312 | { |
290 | struct ep93xx_gpio_chip *ep93xx_chip = to_ep93xx_gpio_chip(chip); | 313 | void __iomem *data = mmio_base + bank->data; |
291 | unsigned long flags; | 314 | void __iomem *dir = mmio_base + bank->dir; |
292 | int line; | 315 | int err; |
293 | u8 v; | ||
294 | 316 | ||
295 | local_irq_save(flags); | 317 | err = bgpio_init(bgc, dev, 1, data, NULL, NULL, dir, NULL, false); |
318 | if (err) | ||
319 | return err; | ||
296 | 320 | ||
297 | /* Set the value */ | 321 | bgc->gc.label = bank->label; |
298 | v = __raw_readb(ep93xx_chip->data_reg); | 322 | bgc->gc.base = bank->base; |
299 | if (val) | ||
300 | v |= (1 << offset); | ||
301 | else | ||
302 | v &= ~(1 << offset); | ||
303 | __raw_writeb(v, ep93xx_chip->data_reg); | ||
304 | |||
305 | /* Drive as an output */ | ||
306 | line = chip->base + offset; | ||
307 | if (line <= EP93XX_GPIO_LINE_MAX_IRQ) { | ||
308 | /* Ports A/B/F */ | ||
309 | ep93xx_gpio_int_mask(line); | ||
310 | ep93xx_gpio_update_int_params(line >> 3); | ||
311 | } | ||
312 | 323 | ||
313 | v = __raw_readb(ep93xx_chip->data_dir_reg); | 324 | if (bank->has_debounce) |
314 | v |= (1 << offset); | 325 | bgc->gc.set_debounce = ep93xx_gpio_set_debounce; |
315 | __raw_writeb(v, ep93xx_chip->data_dir_reg); | ||
316 | 326 | ||
317 | local_irq_restore(flags); | 327 | return gpiochip_add(&bgc->gc); |
318 | |||
319 | return 0; | ||
320 | } | 328 | } |
321 | 329 | ||
322 | static int ep93xx_gpio_get(struct gpio_chip *chip, unsigned offset) | 330 | static int __devinit ep93xx_gpio_probe(struct platform_device *pdev) |
323 | { | 331 | { |
324 | struct ep93xx_gpio_chip *ep93xx_chip = to_ep93xx_gpio_chip(chip); | 332 | struct ep93xx_gpio *ep93xx_gpio; |
333 | struct resource *res; | ||
334 | void __iomem *mmio; | ||
335 | int i; | ||
336 | int ret; | ||
325 | 337 | ||
326 | return !!(__raw_readb(ep93xx_chip->data_reg) & (1 << offset)); | 338 | ep93xx_gpio = kzalloc(sizeof(*ep93xx_gpio), GFP_KERNEL); |
327 | } | 339 | if (!ep93xx_gpio) |
340 | return -ENOMEM; | ||
328 | 341 | ||
329 | static void ep93xx_gpio_set(struct gpio_chip *chip, unsigned offset, int val) | 342 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
330 | { | 343 | if (!res) { |
331 | struct ep93xx_gpio_chip *ep93xx_chip = to_ep93xx_gpio_chip(chip); | 344 | ret = -ENXIO; |
332 | unsigned long flags; | 345 | goto exit_free; |
333 | u8 v; | 346 | } |
334 | |||
335 | local_irq_save(flags); | ||
336 | v = __raw_readb(ep93xx_chip->data_reg); | ||
337 | if (val) | ||
338 | v |= (1 << offset); | ||
339 | else | ||
340 | v &= ~(1 << offset); | ||
341 | __raw_writeb(v, ep93xx_chip->data_reg); | ||
342 | local_irq_restore(flags); | ||
343 | } | ||
344 | 347 | ||
345 | static int ep93xx_gpio_set_debounce(struct gpio_chip *chip, | 348 | if (!request_mem_region(res->start, resource_size(res), pdev->name)) { |
346 | unsigned offset, unsigned debounce) | 349 | ret = -EBUSY; |
347 | { | 350 | goto exit_free; |
348 | int gpio = chip->base + offset; | 351 | } |
349 | int irq = gpio_to_irq(gpio); | ||
350 | 352 | ||
351 | if (irq < 0) | 353 | mmio = ioremap(res->start, resource_size(res)); |
352 | return -EINVAL; | 354 | if (!mmio) { |
355 | ret = -ENXIO; | ||
356 | goto exit_release; | ||
357 | } | ||
358 | ep93xx_gpio->mmio_base = mmio; | ||
353 | 359 | ||
354 | ep93xx_gpio_int_debounce(irq, debounce ? true : false); | 360 | /* Default all ports to GPIO */ |
361 | ep93xx_devcfg_set_bits(EP93XX_SYSCON_DEVCFG_KEYS | | ||
362 | EP93XX_SYSCON_DEVCFG_GONK | | ||
363 | EP93XX_SYSCON_DEVCFG_EONIDE | | ||
364 | EP93XX_SYSCON_DEVCFG_GONIDE | | ||
365 | EP93XX_SYSCON_DEVCFG_HONIDE); | ||
355 | 366 | ||
356 | return 0; | 367 | for (i = 0; i < ARRAY_SIZE(ep93xx_gpio_banks); i++) { |
357 | } | 368 | struct bgpio_chip *bgc = &ep93xx_gpio->bgc[i]; |
369 | struct ep93xx_gpio_bank *bank = &ep93xx_gpio_banks[i]; | ||
358 | 370 | ||
359 | #define EP93XX_GPIO_BANK(name, dr, ddr, base_gpio) \ | 371 | if (ep93xx_gpio_add_bank(bgc, &pdev->dev, mmio, bank)) |
360 | { \ | 372 | dev_warn(&pdev->dev, "Unable to add gpio bank %s\n", |
361 | .chip = { \ | 373 | bank->label); |
362 | .label = name, \ | ||
363 | .direction_input = ep93xx_gpio_direction_input, \ | ||
364 | .direction_output = ep93xx_gpio_direction_output, \ | ||
365 | .get = ep93xx_gpio_get, \ | ||
366 | .set = ep93xx_gpio_set, \ | ||
367 | .base = base_gpio, \ | ||
368 | .ngpio = 8, \ | ||
369 | }, \ | ||
370 | .data_reg = EP93XX_GPIO_REG(dr), \ | ||
371 | .data_dir_reg = EP93XX_GPIO_REG(ddr), \ | ||
372 | } | 374 | } |
373 | 375 | ||
374 | static struct ep93xx_gpio_chip ep93xx_gpio_banks[] = { | 376 | ep93xx_gpio_init_irq(); |
375 | EP93XX_GPIO_BANK("A", 0x00, 0x10, 0), | ||
376 | EP93XX_GPIO_BANK("B", 0x04, 0x14, 8), | ||
377 | EP93XX_GPIO_BANK("C", 0x08, 0x18, 40), | ||
378 | EP93XX_GPIO_BANK("D", 0x0c, 0x1c, 24), | ||
379 | EP93XX_GPIO_BANK("E", 0x20, 0x24, 32), | ||
380 | EP93XX_GPIO_BANK("F", 0x30, 0x34, 16), | ||
381 | EP93XX_GPIO_BANK("G", 0x38, 0x3c, 48), | ||
382 | EP93XX_GPIO_BANK("H", 0x40, 0x44, 56), | ||
383 | }; | ||
384 | 377 | ||
385 | void __init ep93xx_gpio_init(void) | 378 | return 0; |
386 | { | ||
387 | int i; | ||
388 | 379 | ||
389 | /* Set Ports C, D, E, G, and H for GPIO use */ | 380 | exit_release: |
390 | ep93xx_devcfg_set_bits(EP93XX_SYSCON_DEVCFG_KEYS | | 381 | release_mem_region(res->start, resource_size(res)); |
391 | EP93XX_SYSCON_DEVCFG_GONK | | 382 | exit_free: |
392 | EP93XX_SYSCON_DEVCFG_EONIDE | | 383 | kfree(ep93xx_gpio); |
393 | EP93XX_SYSCON_DEVCFG_GONIDE | | 384 | dev_info(&pdev->dev, "%s failed with errno %d\n", __func__, ret); |
394 | EP93XX_SYSCON_DEVCFG_HONIDE); | 385 | return ret; |
386 | } | ||
395 | 387 | ||
396 | for (i = 0; i < ARRAY_SIZE(ep93xx_gpio_banks); i++) { | 388 | static struct platform_driver ep93xx_gpio_driver = { |
397 | struct gpio_chip *chip = &ep93xx_gpio_banks[i].chip; | 389 | .driver = { |
398 | 390 | .name = "gpio-ep93xx", | |
399 | /* | 391 | .owner = THIS_MODULE, |
400 | * Ports A, B, and F support input debouncing when | 392 | }, |
401 | * used as interrupts. | 393 | .probe = ep93xx_gpio_probe, |
402 | */ | 394 | }; |
403 | if (!strcmp(chip->label, "A") || | 395 | |
404 | !strcmp(chip->label, "B") || | 396 | static int __init ep93xx_gpio_init(void) |
405 | !strcmp(chip->label, "F")) | 397 | { |
406 | chip->set_debounce = ep93xx_gpio_set_debounce; | 398 | return platform_driver_register(&ep93xx_gpio_driver); |
407 | |||
408 | gpiochip_add(chip); | ||
409 | } | ||
410 | } | 399 | } |
400 | postcore_initcall(ep93xx_gpio_init); | ||
401 | |||
402 | MODULE_AUTHOR("Ryan Mallon <ryan@bluewatersys.com> " | ||
403 | "H Hartley Sweeten <hsweeten@visionengravers.com>"); | ||
404 | MODULE_DESCRIPTION("EP93XX GPIO driver"); | ||
405 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/gpio/gpio-exynos4.c b/drivers/gpio/gpio-exynos4.c index 9029835112e7..d24b337cf1ac 100644 --- a/drivers/gpio/gpio-exynos4.c +++ b/drivers/gpio/gpio-exynos4.c | |||
@@ -1,10 +1,9 @@ | |||
1 | /* linux/arch/arm/mach-exynos4/gpiolib.c | 1 | /* |
2 | * EXYNOS4 - GPIOlib support | ||
2 | * | 3 | * |
3 | * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd. | 4 | * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd. |
4 | * http://www.samsung.com | 5 | * http://www.samsung.com |
5 | * | 6 | * |
6 | * EXYNOS4 - GPIOlib support | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | 7 | * This program is free software; you can redistribute it and/or modify |
9 | * it under the terms of the GNU General Public License version 2 as | 8 | * it under the terms of the GNU General Public License version 2 as |
10 | * published by the Free Software Foundation. | 9 | * published by the Free Software Foundation. |
diff --git a/drivers/gpio/basic_mmio_gpio.c b/drivers/gpio/gpio-generic.c index 8152e9f516b0..231714def4d2 100644 --- a/drivers/gpio/basic_mmio_gpio.c +++ b/drivers/gpio/gpio-generic.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Driver for basic memory-mapped GPIO controllers. | 2 | * Generic driver for memory-mapped GPIO controllers. |
3 | * | 3 | * |
4 | * Copyright 2008 MontaVista Software, Inc. | 4 | * Copyright 2008 MontaVista Software, Inc. |
5 | * Copyright 2008,2010 Anton Vorontsov <cbouatmailru@gmail.com> | 5 | * Copyright 2008,2010 Anton Vorontsov <cbouatmailru@gmail.com> |
@@ -404,7 +404,7 @@ int __devinit bgpio_init(struct bgpio_chip *bgc, | |||
404 | } | 404 | } |
405 | EXPORT_SYMBOL_GPL(bgpio_init); | 405 | EXPORT_SYMBOL_GPL(bgpio_init); |
406 | 406 | ||
407 | #ifdef CONFIG_GPIO_BASIC_MMIO | 407 | #ifdef CONFIG_GPIO_GENERIC_PLATFORM |
408 | 408 | ||
409 | static void __iomem *bgpio_map(struct platform_device *pdev, | 409 | static void __iomem *bgpio_map(struct platform_device *pdev, |
410 | const char *name, | 410 | const char *name, |
@@ -541,7 +541,7 @@ static void __exit bgpio_platform_exit(void) | |||
541 | } | 541 | } |
542 | module_exit(bgpio_platform_exit); | 542 | module_exit(bgpio_platform_exit); |
543 | 543 | ||
544 | #endif /* CONFIG_GPIO_BASIC_MMIO */ | 544 | #endif /* CONFIG_GPIO_GENERIC_PLATFORM */ |
545 | 545 | ||
546 | MODULE_DESCRIPTION("Driver for basic memory-mapped GPIO controllers"); | 546 | MODULE_DESCRIPTION("Driver for basic memory-mapped GPIO controllers"); |
547 | MODULE_AUTHOR("Anton Vorontsov <cbouatmailru@gmail.com>"); | 547 | MODULE_AUTHOR("Anton Vorontsov <cbouatmailru@gmail.com>"); |
diff --git a/drivers/gpio/it8761e_gpio.c b/drivers/gpio/gpio-it8761e.c index 48fc43c4bdd1..278b81317010 100644 --- a/drivers/gpio/it8761e_gpio.c +++ b/drivers/gpio/gpio-it8761e.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * it8761_gpio.c - GPIO interface for IT8761E Super I/O chip | 2 | * GPIO interface for IT8761E Super I/O chip |
3 | * | 3 | * |
4 | * Author: Denis Turischev <denis@compulab.co.il> | 4 | * Author: Denis Turischev <denis@compulab.co.il> |
5 | * | 5 | * |
diff --git a/drivers/gpio/janz-ttl.c b/drivers/gpio/gpio-janz-ttl.c index 813ac077e5d7..813ac077e5d7 100644 --- a/drivers/gpio/janz-ttl.c +++ b/drivers/gpio/gpio-janz-ttl.c | |||
diff --git a/drivers/gpio/langwell_gpio.c b/drivers/gpio/gpio-langwell.c index 644ba1255d3c..d2eb57c60e0e 100644 --- a/drivers/gpio/langwell_gpio.c +++ b/drivers/gpio/gpio-langwell.c | |||
@@ -1,4 +1,6 @@ | |||
1 | /* langwell_gpio.c Moorestown platform Langwell chip GPIO driver | 1 | /* |
2 | * Moorestown platform Langwell chip GPIO driver | ||
3 | * | ||
2 | * Copyright (c) 2008 - 2009, Intel Corporation. | 4 | * Copyright (c) 2008 - 2009, Intel Corporation. |
3 | * | 5 | * |
4 | * This program is free software; you can redistribute it and/or modify | 6 | * This program is free software; you can redistribute it and/or modify |
diff --git a/drivers/gpio/max7300.c b/drivers/gpio/gpio-max7300.c index 962f661c18c7..a5ca0ab1b372 100644 --- a/drivers/gpio/max7300.c +++ b/drivers/gpio/gpio-max7300.c | |||
@@ -1,6 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * drivers/gpio/max7300.c | ||
3 | * | ||
4 | * Copyright (C) 2009 Wolfram Sang, Pengutronix | 2 | * Copyright (C) 2009 Wolfram Sang, Pengutronix |
5 | * | 3 | * |
6 | * This program is free software; you can redistribute it and/or modify | 4 | * This program is free software; you can redistribute it and/or modify |
diff --git a/drivers/gpio/max7301.c b/drivers/gpio/gpio-max7301.c index 92a100ddef6b..741acfcbe761 100644 --- a/drivers/gpio/max7301.c +++ b/drivers/gpio/gpio-max7301.c | |||
@@ -1,6 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * drivers/gpio/max7301.c | ||
3 | * | ||
4 | * Copyright (C) 2006 Juergen Beisert, Pengutronix | 2 | * Copyright (C) 2006 Juergen Beisert, Pengutronix |
5 | * Copyright (C) 2008 Guennadi Liakhovetski, Pengutronix | 3 | * Copyright (C) 2008 Guennadi Liakhovetski, Pengutronix |
6 | * Copyright (C) 2009 Wolfram Sang, Pengutronix | 4 | * Copyright (C) 2009 Wolfram Sang, Pengutronix |
diff --git a/drivers/gpio/max730x.c b/drivers/gpio/gpio-max730x.c index 94ce773f95f8..05e2dac60b3b 100644 --- a/drivers/gpio/max730x.c +++ b/drivers/gpio/gpio-max730x.c | |||
@@ -1,6 +1,4 @@ | |||
1 | /** | 1 | /** |
2 | * drivers/gpio/max7301.c | ||
3 | * | ||
4 | * Copyright (C) 2006 Juergen Beisert, Pengutronix | 2 | * Copyright (C) 2006 Juergen Beisert, Pengutronix |
5 | * Copyright (C) 2008 Guennadi Liakhovetski, Pengutronix | 3 | * Copyright (C) 2008 Guennadi Liakhovetski, Pengutronix |
6 | * Copyright (C) 2009 Wolfram Sang, Pengutronix | 4 | * Copyright (C) 2009 Wolfram Sang, Pengutronix |
diff --git a/drivers/gpio/max732x.c b/drivers/gpio/gpio-max732x.c index ad6951edc16c..9504120812a5 100644 --- a/drivers/gpio/max732x.c +++ b/drivers/gpio/gpio-max732x.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * max732x.c - I2C Port Expander with 8/16 I/O | 2 | * MAX732x I2C Port Expander with 8/16 I/O |
3 | * | 3 | * |
4 | * Copyright (C) 2007 Marvell International Ltd. | 4 | * Copyright (C) 2007 Marvell International Ltd. |
5 | * Copyright (C) 2008 Jack Ren <jack.ren@marvell.com> | 5 | * Copyright (C) 2008 Jack Ren <jack.ren@marvell.com> |
diff --git a/drivers/gpio/mc33880.c b/drivers/gpio/gpio-mc33880.c index 4ec797593bdb..b3b4652e89ec 100644 --- a/drivers/gpio/mc33880.c +++ b/drivers/gpio/gpio-mc33880.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * mc33880.c MC33880 high-side/low-side switch GPIO driver | 2 | * MC33880 high-side/low-side switch GPIO driver |
3 | * Copyright (c) 2009 Intel Corporation | 3 | * Copyright (c) 2009 Intel Corporation |
4 | * | 4 | * |
5 | * This program is free software; you can redistribute it and/or modify | 5 | * This program is free software; you can redistribute it and/or modify |
diff --git a/drivers/gpio/mcp23s08.c b/drivers/gpio/gpio-mcp23s08.c index 40e076083ec0..1ef46e6c2a2a 100644 --- a/drivers/gpio/mcp23s08.c +++ b/drivers/gpio/gpio-mcp23s08.c | |||
@@ -1,12 +1,12 @@ | |||
1 | /* | 1 | /* |
2 | * mcp23s08.c - SPI gpio expander driver | 2 | * MCP23S08 SPI/GPIO gpio expander driver |
3 | */ | 3 | */ |
4 | 4 | ||
5 | #include <linux/kernel.h> | 5 | #include <linux/kernel.h> |
6 | #include <linux/device.h> | 6 | #include <linux/device.h> |
7 | #include <linux/workqueue.h> | ||
8 | #include <linux/mutex.h> | 7 | #include <linux/mutex.h> |
9 | #include <linux/gpio.h> | 8 | #include <linux/gpio.h> |
9 | #include <linux/i2c.h> | ||
10 | #include <linux/spi/spi.h> | 10 | #include <linux/spi/spi.h> |
11 | #include <linux/spi/mcp23s08.h> | 11 | #include <linux/spi/mcp23s08.h> |
12 | #include <linux/slab.h> | 12 | #include <linux/slab.h> |
@@ -17,13 +17,13 @@ | |||
17 | */ | 17 | */ |
18 | #define MCP_TYPE_S08 0 | 18 | #define MCP_TYPE_S08 0 |
19 | #define MCP_TYPE_S17 1 | 19 | #define MCP_TYPE_S17 1 |
20 | #define MCP_TYPE_008 2 | ||
21 | #define MCP_TYPE_017 3 | ||
20 | 22 | ||
21 | /* Registers are all 8 bits wide. | 23 | /* Registers are all 8 bits wide. |
22 | * | 24 | * |
23 | * The mcp23s17 has twice as many bits, and can be configured to work | 25 | * The mcp23s17 has twice as many bits, and can be configured to work |
24 | * with either 16 bit registers or with two adjacent 8 bit banks. | 26 | * with either 16 bit registers or with two adjacent 8 bit banks. |
25 | * | ||
26 | * Also, there are I2C versions of both chips. | ||
27 | */ | 27 | */ |
28 | #define MCP_IODIR 0x00 /* init/reset: all ones */ | 28 | #define MCP_IODIR 0x00 /* init/reset: all ones */ |
29 | #define MCP_IPOL 0x01 | 29 | #define MCP_IPOL 0x01 |
@@ -51,7 +51,6 @@ struct mcp23s08_ops { | |||
51 | }; | 51 | }; |
52 | 52 | ||
53 | struct mcp23s08 { | 53 | struct mcp23s08 { |
54 | struct spi_device *spi; | ||
55 | u8 addr; | 54 | u8 addr; |
56 | 55 | ||
57 | u16 cache[11]; | 56 | u16 cache[11]; |
@@ -60,9 +59,8 @@ struct mcp23s08 { | |||
60 | 59 | ||
61 | struct gpio_chip chip; | 60 | struct gpio_chip chip; |
62 | 61 | ||
63 | struct work_struct work; | ||
64 | |||
65 | const struct mcp23s08_ops *ops; | 62 | const struct mcp23s08_ops *ops; |
63 | void *data; /* ops specific data */ | ||
66 | }; | 64 | }; |
67 | 65 | ||
68 | /* A given spi_device can represent up to eight mcp23sxx chips | 66 | /* A given spi_device can represent up to eight mcp23sxx chips |
@@ -76,6 +74,74 @@ struct mcp23s08_driver_data { | |||
76 | struct mcp23s08 chip[]; | 74 | struct mcp23s08 chip[]; |
77 | }; | 75 | }; |
78 | 76 | ||
77 | /*----------------------------------------------------------------------*/ | ||
78 | |||
79 | #ifdef CONFIG_I2C | ||
80 | |||
81 | static int mcp23008_read(struct mcp23s08 *mcp, unsigned reg) | ||
82 | { | ||
83 | return i2c_smbus_read_byte_data(mcp->data, reg); | ||
84 | } | ||
85 | |||
86 | static int mcp23008_write(struct mcp23s08 *mcp, unsigned reg, unsigned val) | ||
87 | { | ||
88 | return i2c_smbus_write_byte_data(mcp->data, reg, val); | ||
89 | } | ||
90 | |||
91 | static int | ||
92 | mcp23008_read_regs(struct mcp23s08 *mcp, unsigned reg, u16 *vals, unsigned n) | ||
93 | { | ||
94 | while (n--) { | ||
95 | int ret = mcp23008_read(mcp, reg++); | ||
96 | if (ret < 0) | ||
97 | return ret; | ||
98 | *vals++ = ret; | ||
99 | } | ||
100 | |||
101 | return 0; | ||
102 | } | ||
103 | |||
104 | static int mcp23017_read(struct mcp23s08 *mcp, unsigned reg) | ||
105 | { | ||
106 | return i2c_smbus_read_word_data(mcp->data, reg << 1); | ||
107 | } | ||
108 | |||
109 | static int mcp23017_write(struct mcp23s08 *mcp, unsigned reg, unsigned val) | ||
110 | { | ||
111 | return i2c_smbus_write_word_data(mcp->data, reg << 1, val); | ||
112 | } | ||
113 | |||
114 | static int | ||
115 | mcp23017_read_regs(struct mcp23s08 *mcp, unsigned reg, u16 *vals, unsigned n) | ||
116 | { | ||
117 | while (n--) { | ||
118 | int ret = mcp23017_read(mcp, reg++); | ||
119 | if (ret < 0) | ||
120 | return ret; | ||
121 | *vals++ = ret; | ||
122 | } | ||
123 | |||
124 | return 0; | ||
125 | } | ||
126 | |||
127 | static const struct mcp23s08_ops mcp23008_ops = { | ||
128 | .read = mcp23008_read, | ||
129 | .write = mcp23008_write, | ||
130 | .read_regs = mcp23008_read_regs, | ||
131 | }; | ||
132 | |||
133 | static const struct mcp23s08_ops mcp23017_ops = { | ||
134 | .read = mcp23017_read, | ||
135 | .write = mcp23017_write, | ||
136 | .read_regs = mcp23017_read_regs, | ||
137 | }; | ||
138 | |||
139 | #endif /* CONFIG_I2C */ | ||
140 | |||
141 | /*----------------------------------------------------------------------*/ | ||
142 | |||
143 | #ifdef CONFIG_SPI_MASTER | ||
144 | |||
79 | static int mcp23s08_read(struct mcp23s08 *mcp, unsigned reg) | 145 | static int mcp23s08_read(struct mcp23s08 *mcp, unsigned reg) |
80 | { | 146 | { |
81 | u8 tx[2], rx[1]; | 147 | u8 tx[2], rx[1]; |
@@ -83,7 +149,7 @@ static int mcp23s08_read(struct mcp23s08 *mcp, unsigned reg) | |||
83 | 149 | ||
84 | tx[0] = mcp->addr | 0x01; | 150 | tx[0] = mcp->addr | 0x01; |
85 | tx[1] = reg; | 151 | tx[1] = reg; |
86 | status = spi_write_then_read(mcp->spi, tx, sizeof tx, rx, sizeof rx); | 152 | status = spi_write_then_read(mcp->data, tx, sizeof tx, rx, sizeof rx); |
87 | return (status < 0) ? status : rx[0]; | 153 | return (status < 0) ? status : rx[0]; |
88 | } | 154 | } |
89 | 155 | ||
@@ -94,7 +160,7 @@ static int mcp23s08_write(struct mcp23s08 *mcp, unsigned reg, unsigned val) | |||
94 | tx[0] = mcp->addr; | 160 | tx[0] = mcp->addr; |
95 | tx[1] = reg; | 161 | tx[1] = reg; |
96 | tx[2] = val; | 162 | tx[2] = val; |
97 | return spi_write_then_read(mcp->spi, tx, sizeof tx, NULL, 0); | 163 | return spi_write_then_read(mcp->data, tx, sizeof tx, NULL, 0); |
98 | } | 164 | } |
99 | 165 | ||
100 | static int | 166 | static int |
@@ -109,7 +175,7 @@ mcp23s08_read_regs(struct mcp23s08 *mcp, unsigned reg, u16 *vals, unsigned n) | |||
109 | tx[1] = reg; | 175 | tx[1] = reg; |
110 | 176 | ||
111 | tmp = (u8 *)vals; | 177 | tmp = (u8 *)vals; |
112 | status = spi_write_then_read(mcp->spi, tx, sizeof tx, tmp, n); | 178 | status = spi_write_then_read(mcp->data, tx, sizeof tx, tmp, n); |
113 | if (status >= 0) { | 179 | if (status >= 0) { |
114 | while (n--) | 180 | while (n--) |
115 | vals[n] = tmp[n]; /* expand to 16bit */ | 181 | vals[n] = tmp[n]; /* expand to 16bit */ |
@@ -124,7 +190,7 @@ static int mcp23s17_read(struct mcp23s08 *mcp, unsigned reg) | |||
124 | 190 | ||
125 | tx[0] = mcp->addr | 0x01; | 191 | tx[0] = mcp->addr | 0x01; |
126 | tx[1] = reg << 1; | 192 | tx[1] = reg << 1; |
127 | status = spi_write_then_read(mcp->spi, tx, sizeof tx, rx, sizeof rx); | 193 | status = spi_write_then_read(mcp->data, tx, sizeof tx, rx, sizeof rx); |
128 | return (status < 0) ? status : (rx[0] | (rx[1] << 8)); | 194 | return (status < 0) ? status : (rx[0] | (rx[1] << 8)); |
129 | } | 195 | } |
130 | 196 | ||
@@ -136,7 +202,7 @@ static int mcp23s17_write(struct mcp23s08 *mcp, unsigned reg, unsigned val) | |||
136 | tx[1] = reg << 1; | 202 | tx[1] = reg << 1; |
137 | tx[2] = val; | 203 | tx[2] = val; |
138 | tx[3] = val >> 8; | 204 | tx[3] = val >> 8; |
139 | return spi_write_then_read(mcp->spi, tx, sizeof tx, NULL, 0); | 205 | return spi_write_then_read(mcp->data, tx, sizeof tx, NULL, 0); |
140 | } | 206 | } |
141 | 207 | ||
142 | static int | 208 | static int |
@@ -150,7 +216,7 @@ mcp23s17_read_regs(struct mcp23s08 *mcp, unsigned reg, u16 *vals, unsigned n) | |||
150 | tx[0] = mcp->addr | 0x01; | 216 | tx[0] = mcp->addr | 0x01; |
151 | tx[1] = reg << 1; | 217 | tx[1] = reg << 1; |
152 | 218 | ||
153 | status = spi_write_then_read(mcp->spi, tx, sizeof tx, | 219 | status = spi_write_then_read(mcp->data, tx, sizeof tx, |
154 | (u8 *)vals, n * 2); | 220 | (u8 *)vals, n * 2); |
155 | if (status >= 0) { | 221 | if (status >= 0) { |
156 | while (n--) | 222 | while (n--) |
@@ -172,6 +238,7 @@ static const struct mcp23s08_ops mcp23s17_ops = { | |||
172 | .read_regs = mcp23s17_read_regs, | 238 | .read_regs = mcp23s17_read_regs, |
173 | }; | 239 | }; |
174 | 240 | ||
241 | #endif /* CONFIG_SPI_MASTER */ | ||
175 | 242 | ||
176 | /*----------------------------------------------------------------------*/ | 243 | /*----------------------------------------------------------------------*/ |
177 | 244 | ||
@@ -299,17 +366,16 @@ done: | |||
299 | 366 | ||
300 | /*----------------------------------------------------------------------*/ | 367 | /*----------------------------------------------------------------------*/ |
301 | 368 | ||
302 | static int mcp23s08_probe_one(struct spi_device *spi, unsigned addr, | 369 | static int mcp23s08_probe_one(struct mcp23s08 *mcp, struct device *dev, |
370 | void *data, unsigned addr, | ||
303 | unsigned type, unsigned base, unsigned pullups) | 371 | unsigned type, unsigned base, unsigned pullups) |
304 | { | 372 | { |
305 | struct mcp23s08_driver_data *data = spi_get_drvdata(spi); | 373 | int status; |
306 | struct mcp23s08 *mcp = data->mcp[addr]; | ||
307 | int status; | ||
308 | 374 | ||
309 | mutex_init(&mcp->lock); | 375 | mutex_init(&mcp->lock); |
310 | 376 | ||
311 | mcp->spi = spi; | 377 | mcp->data = data; |
312 | mcp->addr = 0x40 | (addr << 1); | 378 | mcp->addr = addr; |
313 | 379 | ||
314 | mcp->chip.direction_input = mcp23s08_direction_input; | 380 | mcp->chip.direction_input = mcp23s08_direction_input; |
315 | mcp->chip.get = mcp23s08_get; | 381 | mcp->chip.get = mcp23s08_get; |
@@ -317,18 +383,43 @@ static int mcp23s08_probe_one(struct spi_device *spi, unsigned addr, | |||
317 | mcp->chip.set = mcp23s08_set; | 383 | mcp->chip.set = mcp23s08_set; |
318 | mcp->chip.dbg_show = mcp23s08_dbg_show; | 384 | mcp->chip.dbg_show = mcp23s08_dbg_show; |
319 | 385 | ||
320 | if (type == MCP_TYPE_S17) { | 386 | switch (type) { |
387 | #ifdef CONFIG_SPI_MASTER | ||
388 | case MCP_TYPE_S08: | ||
389 | mcp->ops = &mcp23s08_ops; | ||
390 | mcp->chip.ngpio = 8; | ||
391 | mcp->chip.label = "mcp23s08"; | ||
392 | break; | ||
393 | |||
394 | case MCP_TYPE_S17: | ||
321 | mcp->ops = &mcp23s17_ops; | 395 | mcp->ops = &mcp23s17_ops; |
322 | mcp->chip.ngpio = 16; | 396 | mcp->chip.ngpio = 16; |
323 | mcp->chip.label = "mcp23s17"; | 397 | mcp->chip.label = "mcp23s17"; |
324 | } else { | 398 | break; |
325 | mcp->ops = &mcp23s08_ops; | 399 | #endif /* CONFIG_SPI_MASTER */ |
400 | |||
401 | #ifdef CONFIG_I2C | ||
402 | case MCP_TYPE_008: | ||
403 | mcp->ops = &mcp23008_ops; | ||
326 | mcp->chip.ngpio = 8; | 404 | mcp->chip.ngpio = 8; |
327 | mcp->chip.label = "mcp23s08"; | 405 | mcp->chip.label = "mcp23008"; |
406 | break; | ||
407 | |||
408 | case MCP_TYPE_017: | ||
409 | mcp->ops = &mcp23017_ops; | ||
410 | mcp->chip.ngpio = 16; | ||
411 | mcp->chip.label = "mcp23017"; | ||
412 | break; | ||
413 | #endif /* CONFIG_I2C */ | ||
414 | |||
415 | default: | ||
416 | dev_err(dev, "invalid device type (%d)\n", type); | ||
417 | return -EINVAL; | ||
328 | } | 418 | } |
419 | |||
329 | mcp->chip.base = base; | 420 | mcp->chip.base = base; |
330 | mcp->chip.can_sleep = 1; | 421 | mcp->chip.can_sleep = 1; |
331 | mcp->chip.dev = &spi->dev; | 422 | mcp->chip.dev = dev; |
332 | mcp->chip.owner = THIS_MODULE; | 423 | mcp->chip.owner = THIS_MODULE; |
333 | 424 | ||
334 | /* verify MCP_IOCON.SEQOP = 0, so sequential reads work, | 425 | /* verify MCP_IOCON.SEQOP = 0, so sequential reads work, |
@@ -374,11 +465,98 @@ static int mcp23s08_probe_one(struct spi_device *spi, unsigned addr, | |||
374 | status = gpiochip_add(&mcp->chip); | 465 | status = gpiochip_add(&mcp->chip); |
375 | fail: | 466 | fail: |
376 | if (status < 0) | 467 | if (status < 0) |
377 | dev_dbg(&spi->dev, "can't setup chip %d, --> %d\n", | 468 | dev_dbg(dev, "can't setup chip %d, --> %d\n", |
378 | addr, status); | 469 | addr, status); |
379 | return status; | 470 | return status; |
380 | } | 471 | } |
381 | 472 | ||
473 | /*----------------------------------------------------------------------*/ | ||
474 | |||
475 | #ifdef CONFIG_I2C | ||
476 | |||
477 | static int __devinit mcp230xx_probe(struct i2c_client *client, | ||
478 | const struct i2c_device_id *id) | ||
479 | { | ||
480 | struct mcp23s08_platform_data *pdata; | ||
481 | struct mcp23s08 *mcp; | ||
482 | int status; | ||
483 | |||
484 | pdata = client->dev.platform_data; | ||
485 | if (!pdata || !gpio_is_valid(pdata->base)) { | ||
486 | dev_dbg(&client->dev, "invalid or missing platform data\n"); | ||
487 | return -EINVAL; | ||
488 | } | ||
489 | |||
490 | mcp = kzalloc(sizeof *mcp, GFP_KERNEL); | ||
491 | if (!mcp) | ||
492 | return -ENOMEM; | ||
493 | |||
494 | status = mcp23s08_probe_one(mcp, &client->dev, client, client->addr, | ||
495 | id->driver_data, pdata->base, | ||
496 | pdata->chip[0].pullups); | ||
497 | if (status) | ||
498 | goto fail; | ||
499 | |||
500 | i2c_set_clientdata(client, mcp); | ||
501 | |||
502 | return 0; | ||
503 | |||
504 | fail: | ||
505 | kfree(mcp); | ||
506 | |||
507 | return status; | ||
508 | } | ||
509 | |||
510 | static int __devexit mcp230xx_remove(struct i2c_client *client) | ||
511 | { | ||
512 | struct mcp23s08 *mcp = i2c_get_clientdata(client); | ||
513 | int status; | ||
514 | |||
515 | status = gpiochip_remove(&mcp->chip); | ||
516 | if (status == 0) | ||
517 | kfree(mcp); | ||
518 | |||
519 | return status; | ||
520 | } | ||
521 | |||
522 | static const struct i2c_device_id mcp230xx_id[] = { | ||
523 | { "mcp23008", MCP_TYPE_008 }, | ||
524 | { "mcp23017", MCP_TYPE_017 }, | ||
525 | { }, | ||
526 | }; | ||
527 | MODULE_DEVICE_TABLE(i2c, mcp230xx_id); | ||
528 | |||
529 | static struct i2c_driver mcp230xx_driver = { | ||
530 | .driver = { | ||
531 | .name = "mcp230xx", | ||
532 | .owner = THIS_MODULE, | ||
533 | }, | ||
534 | .probe = mcp230xx_probe, | ||
535 | .remove = __devexit_p(mcp230xx_remove), | ||
536 | .id_table = mcp230xx_id, | ||
537 | }; | ||
538 | |||
539 | static int __init mcp23s08_i2c_init(void) | ||
540 | { | ||
541 | return i2c_add_driver(&mcp230xx_driver); | ||
542 | } | ||
543 | |||
544 | static void mcp23s08_i2c_exit(void) | ||
545 | { | ||
546 | i2c_del_driver(&mcp230xx_driver); | ||
547 | } | ||
548 | |||
549 | #else | ||
550 | |||
551 | static int __init mcp23s08_i2c_init(void) { return 0; } | ||
552 | static void mcp23s08_i2c_exit(void) { } | ||
553 | |||
554 | #endif /* CONFIG_I2C */ | ||
555 | |||
556 | /*----------------------------------------------------------------------*/ | ||
557 | |||
558 | #ifdef CONFIG_SPI_MASTER | ||
559 | |||
382 | static int mcp23s08_probe(struct spi_device *spi) | 560 | static int mcp23s08_probe(struct spi_device *spi) |
383 | { | 561 | { |
384 | struct mcp23s08_platform_data *pdata; | 562 | struct mcp23s08_platform_data *pdata; |
@@ -421,7 +599,8 @@ static int mcp23s08_probe(struct spi_device *spi) | |||
421 | continue; | 599 | continue; |
422 | chips--; | 600 | chips--; |
423 | data->mcp[addr] = &data->chip[chips]; | 601 | data->mcp[addr] = &data->chip[chips]; |
424 | status = mcp23s08_probe_one(spi, addr, type, base, | 602 | status = mcp23s08_probe_one(data->mcp[addr], &spi->dev, spi, |
603 | 0x40 | (addr << 1), type, base, | ||
425 | pdata->chip[addr].pullups); | 604 | pdata->chip[addr].pullups); |
426 | if (status < 0) | 605 | if (status < 0) |
427 | goto fail; | 606 | goto fail; |
@@ -435,14 +614,6 @@ static int mcp23s08_probe(struct spi_device *spi) | |||
435 | * handled here... | 614 | * handled here... |
436 | */ | 615 | */ |
437 | 616 | ||
438 | if (pdata->setup) { | ||
439 | status = pdata->setup(spi, | ||
440 | pdata->base, data->ngpio, | ||
441 | pdata->context); | ||
442 | if (status < 0) | ||
443 | dev_dbg(&spi->dev, "setup --> %d\n", status); | ||
444 | } | ||
445 | |||
446 | return 0; | 617 | return 0; |
447 | 618 | ||
448 | fail: | 619 | fail: |
@@ -462,20 +633,9 @@ fail: | |||
462 | static int mcp23s08_remove(struct spi_device *spi) | 633 | static int mcp23s08_remove(struct spi_device *spi) |
463 | { | 634 | { |
464 | struct mcp23s08_driver_data *data = spi_get_drvdata(spi); | 635 | struct mcp23s08_driver_data *data = spi_get_drvdata(spi); |
465 | struct mcp23s08_platform_data *pdata = spi->dev.platform_data; | ||
466 | unsigned addr; | 636 | unsigned addr; |
467 | int status = 0; | 637 | int status = 0; |
468 | 638 | ||
469 | if (pdata->teardown) { | ||
470 | status = pdata->teardown(spi, | ||
471 | pdata->base, data->ngpio, | ||
472 | pdata->context); | ||
473 | if (status < 0) { | ||
474 | dev_err(&spi->dev, "%s --> %d\n", "teardown", status); | ||
475 | return status; | ||
476 | } | ||
477 | } | ||
478 | |||
479 | for (addr = 0; addr < ARRAY_SIZE(data->mcp); addr++) { | 639 | for (addr = 0; addr < ARRAY_SIZE(data->mcp); addr++) { |
480 | int tmp; | 640 | int tmp; |
481 | 641 | ||
@@ -510,20 +670,53 @@ static struct spi_driver mcp23s08_driver = { | |||
510 | }, | 670 | }, |
511 | }; | 671 | }; |
512 | 672 | ||
673 | static int __init mcp23s08_spi_init(void) | ||
674 | { | ||
675 | return spi_register_driver(&mcp23s08_driver); | ||
676 | } | ||
677 | |||
678 | static void mcp23s08_spi_exit(void) | ||
679 | { | ||
680 | spi_unregister_driver(&mcp23s08_driver); | ||
681 | } | ||
682 | |||
683 | #else | ||
684 | |||
685 | static int __init mcp23s08_spi_init(void) { return 0; } | ||
686 | static void mcp23s08_spi_exit(void) { } | ||
687 | |||
688 | #endif /* CONFIG_SPI_MASTER */ | ||
689 | |||
513 | /*----------------------------------------------------------------------*/ | 690 | /*----------------------------------------------------------------------*/ |
514 | 691 | ||
515 | static int __init mcp23s08_init(void) | 692 | static int __init mcp23s08_init(void) |
516 | { | 693 | { |
517 | return spi_register_driver(&mcp23s08_driver); | 694 | int ret; |
695 | |||
696 | ret = mcp23s08_spi_init(); | ||
697 | if (ret) | ||
698 | goto spi_fail; | ||
699 | |||
700 | ret = mcp23s08_i2c_init(); | ||
701 | if (ret) | ||
702 | goto i2c_fail; | ||
703 | |||
704 | return 0; | ||
705 | |||
706 | i2c_fail: | ||
707 | mcp23s08_spi_exit(); | ||
708 | spi_fail: | ||
709 | return ret; | ||
518 | } | 710 | } |
519 | /* register after spi postcore initcall and before | 711 | /* register after spi/i2c postcore initcall and before |
520 | * subsys initcalls that may rely on these GPIOs | 712 | * subsys initcalls that may rely on these GPIOs |
521 | */ | 713 | */ |
522 | subsys_initcall(mcp23s08_init); | 714 | subsys_initcall(mcp23s08_init); |
523 | 715 | ||
524 | static void __exit mcp23s08_exit(void) | 716 | static void __exit mcp23s08_exit(void) |
525 | { | 717 | { |
526 | spi_unregister_driver(&mcp23s08_driver); | 718 | mcp23s08_spi_exit(); |
719 | mcp23s08_i2c_exit(); | ||
527 | } | 720 | } |
528 | module_exit(mcp23s08_exit); | 721 | module_exit(mcp23s08_exit); |
529 | 722 | ||
diff --git a/drivers/gpio/ml_ioh_gpio.c b/drivers/gpio/gpio-ml-ioh.c index 1bc621ac3536..a9016f56ed7e 100644 --- a/drivers/gpio/ml_ioh_gpio.c +++ b/drivers/gpio/gpio-ml-ioh.c | |||
@@ -233,7 +233,7 @@ static int __devinit ioh_gpio_probe(struct pci_dev *pdev, | |||
233 | return 0; | 233 | return 0; |
234 | 234 | ||
235 | err_gpiochip_add: | 235 | err_gpiochip_add: |
236 | for (; i != 0; i--) { | 236 | while (--i >= 0) { |
237 | chip--; | 237 | chip--; |
238 | ret = gpiochip_remove(&chip->gpio); | 238 | ret = gpiochip_remove(&chip->gpio); |
239 | if (ret) | 239 | if (ret) |
diff --git a/arch/powerpc/platforms/52xx/mpc52xx_gpio.c b/drivers/gpio/gpio-mpc5200.c index 1757d1db4b51..52d3ed208105 100644 --- a/arch/powerpc/platforms/52xx/mpc52xx_gpio.c +++ b/drivers/gpio/gpio-mpc5200.c | |||
@@ -184,15 +184,13 @@ static int mpc52xx_gpiochip_remove(struct platform_device *ofdev) | |||
184 | } | 184 | } |
185 | 185 | ||
186 | static const struct of_device_id mpc52xx_wkup_gpiochip_match[] = { | 186 | static const struct of_device_id mpc52xx_wkup_gpiochip_match[] = { |
187 | { | 187 | { .compatible = "fsl,mpc5200-gpio-wkup", }, |
188 | .compatible = "fsl,mpc5200-gpio-wkup", | ||
189 | }, | ||
190 | {} | 188 | {} |
191 | }; | 189 | }; |
192 | 190 | ||
193 | static struct platform_driver mpc52xx_wkup_gpiochip_driver = { | 191 | static struct platform_driver mpc52xx_wkup_gpiochip_driver = { |
194 | .driver = { | 192 | .driver = { |
195 | .name = "gpio_wkup", | 193 | .name = "mpc5200-gpio-wkup", |
196 | .owner = THIS_MODULE, | 194 | .owner = THIS_MODULE, |
197 | .of_match_table = mpc52xx_wkup_gpiochip_match, | 195 | .of_match_table = mpc52xx_wkup_gpiochip_match, |
198 | }, | 196 | }, |
@@ -341,15 +339,13 @@ static int __devinit mpc52xx_simple_gpiochip_probe(struct platform_device *ofdev | |||
341 | } | 339 | } |
342 | 340 | ||
343 | static const struct of_device_id mpc52xx_simple_gpiochip_match[] = { | 341 | static const struct of_device_id mpc52xx_simple_gpiochip_match[] = { |
344 | { | 342 | { .compatible = "fsl,mpc5200-gpio", }, |
345 | .compatible = "fsl,mpc5200-gpio", | ||
346 | }, | ||
347 | {} | 343 | {} |
348 | }; | 344 | }; |
349 | 345 | ||
350 | static struct platform_driver mpc52xx_simple_gpiochip_driver = { | 346 | static struct platform_driver mpc52xx_simple_gpiochip_driver = { |
351 | .driver = { | 347 | .driver = { |
352 | .name = "gpio", | 348 | .name = "mpc5200-gpio", |
353 | .owner = THIS_MODULE, | 349 | .owner = THIS_MODULE, |
354 | .of_match_table = mpc52xx_simple_gpiochip_match, | 350 | .of_match_table = mpc52xx_simple_gpiochip_match, |
355 | }, | 351 | }, |
diff --git a/drivers/gpio/gpio-mxc.c b/drivers/gpio/gpio-mxc.c new file mode 100644 index 000000000000..4340acae3bd3 --- /dev/null +++ b/drivers/gpio/gpio-mxc.c | |||
@@ -0,0 +1,460 @@ | |||
1 | /* | ||
2 | * MXC GPIO support. (c) 2008 Daniel Mack <daniel@caiaq.de> | ||
3 | * Copyright 2008 Juergen Beisert, kernel@pengutronix.de | ||
4 | * | ||
5 | * Based on code from Freescale, | ||
6 | * Copyright (C) 2004-2010 Freescale Semiconductor, Inc. All Rights Reserved. | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or | ||
9 | * modify it under the terms of the GNU General Public License | ||
10 | * as published by the Free Software Foundation; either version 2 | ||
11 | * of the License, or (at your option) any later version. | ||
12 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License | ||
18 | * along with this program; if not, write to the Free Software | ||
19 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | ||
20 | */ | ||
21 | |||
22 | #include <linux/init.h> | ||
23 | #include <linux/interrupt.h> | ||
24 | #include <linux/io.h> | ||
25 | #include <linux/irq.h> | ||
26 | #include <linux/gpio.h> | ||
27 | #include <linux/platform_device.h> | ||
28 | #include <linux/slab.h> | ||
29 | #include <linux/basic_mmio_gpio.h> | ||
30 | #include <linux/of.h> | ||
31 | #include <linux/of_device.h> | ||
32 | #include <asm-generic/bug.h> | ||
33 | |||
34 | enum mxc_gpio_hwtype { | ||
35 | IMX1_GPIO, /* runs on i.mx1 */ | ||
36 | IMX21_GPIO, /* runs on i.mx21 and i.mx27 */ | ||
37 | IMX31_GPIO, /* runs on all other i.mx */ | ||
38 | }; | ||
39 | |||
40 | /* device type dependent stuff */ | ||
41 | struct mxc_gpio_hwdata { | ||
42 | unsigned dr_reg; | ||
43 | unsigned gdir_reg; | ||
44 | unsigned psr_reg; | ||
45 | unsigned icr1_reg; | ||
46 | unsigned icr2_reg; | ||
47 | unsigned imr_reg; | ||
48 | unsigned isr_reg; | ||
49 | unsigned low_level; | ||
50 | unsigned high_level; | ||
51 | unsigned rise_edge; | ||
52 | unsigned fall_edge; | ||
53 | }; | ||
54 | |||
55 | struct mxc_gpio_port { | ||
56 | struct list_head node; | ||
57 | void __iomem *base; | ||
58 | int irq; | ||
59 | int irq_high; | ||
60 | int virtual_irq_start; | ||
61 | struct bgpio_chip bgc; | ||
62 | u32 both_edges; | ||
63 | }; | ||
64 | |||
65 | static struct mxc_gpio_hwdata imx1_imx21_gpio_hwdata = { | ||
66 | .dr_reg = 0x1c, | ||
67 | .gdir_reg = 0x00, | ||
68 | .psr_reg = 0x24, | ||
69 | .icr1_reg = 0x28, | ||
70 | .icr2_reg = 0x2c, | ||
71 | .imr_reg = 0x30, | ||
72 | .isr_reg = 0x34, | ||
73 | .low_level = 0x03, | ||
74 | .high_level = 0x02, | ||
75 | .rise_edge = 0x00, | ||
76 | .fall_edge = 0x01, | ||
77 | }; | ||
78 | |||
79 | static struct mxc_gpio_hwdata imx31_gpio_hwdata = { | ||
80 | .dr_reg = 0x00, | ||
81 | .gdir_reg = 0x04, | ||
82 | .psr_reg = 0x08, | ||
83 | .icr1_reg = 0x0c, | ||
84 | .icr2_reg = 0x10, | ||
85 | .imr_reg = 0x14, | ||
86 | .isr_reg = 0x18, | ||
87 | .low_level = 0x00, | ||
88 | .high_level = 0x01, | ||
89 | .rise_edge = 0x02, | ||
90 | .fall_edge = 0x03, | ||
91 | }; | ||
92 | |||
93 | static enum mxc_gpio_hwtype mxc_gpio_hwtype; | ||
94 | static struct mxc_gpio_hwdata *mxc_gpio_hwdata; | ||
95 | |||
96 | #define GPIO_DR (mxc_gpio_hwdata->dr_reg) | ||
97 | #define GPIO_GDIR (mxc_gpio_hwdata->gdir_reg) | ||
98 | #define GPIO_PSR (mxc_gpio_hwdata->psr_reg) | ||
99 | #define GPIO_ICR1 (mxc_gpio_hwdata->icr1_reg) | ||
100 | #define GPIO_ICR2 (mxc_gpio_hwdata->icr2_reg) | ||
101 | #define GPIO_IMR (mxc_gpio_hwdata->imr_reg) | ||
102 | #define GPIO_ISR (mxc_gpio_hwdata->isr_reg) | ||
103 | |||
104 | #define GPIO_INT_LOW_LEV (mxc_gpio_hwdata->low_level) | ||
105 | #define GPIO_INT_HIGH_LEV (mxc_gpio_hwdata->high_level) | ||
106 | #define GPIO_INT_RISE_EDGE (mxc_gpio_hwdata->rise_edge) | ||
107 | #define GPIO_INT_FALL_EDGE (mxc_gpio_hwdata->fall_edge) | ||
108 | #define GPIO_INT_NONE 0x4 | ||
109 | |||
110 | static struct platform_device_id mxc_gpio_devtype[] = { | ||
111 | { | ||
112 | .name = "imx1-gpio", | ||
113 | .driver_data = IMX1_GPIO, | ||
114 | }, { | ||
115 | .name = "imx21-gpio", | ||
116 | .driver_data = IMX21_GPIO, | ||
117 | }, { | ||
118 | .name = "imx31-gpio", | ||
119 | .driver_data = IMX31_GPIO, | ||
120 | }, { | ||
121 | /* sentinel */ | ||
122 | } | ||
123 | }; | ||
124 | |||
125 | static const struct of_device_id mxc_gpio_dt_ids[] = { | ||
126 | { .compatible = "fsl,imx1-gpio", .data = &mxc_gpio_devtype[IMX1_GPIO], }, | ||
127 | { .compatible = "fsl,imx21-gpio", .data = &mxc_gpio_devtype[IMX21_GPIO], }, | ||
128 | { .compatible = "fsl,imx31-gpio", .data = &mxc_gpio_devtype[IMX31_GPIO], }, | ||
129 | { /* sentinel */ } | ||
130 | }; | ||
131 | |||
132 | /* | ||
133 | * MX2 has one interrupt *for all* gpio ports. The list is used | ||
134 | * to save the references to all ports, so that mx2_gpio_irq_handler | ||
135 | * can walk through all interrupt status registers. | ||
136 | */ | ||
137 | static LIST_HEAD(mxc_gpio_ports); | ||
138 | |||
139 | /* Note: This driver assumes 32 GPIOs are handled in one register */ | ||
140 | |||
141 | static int gpio_set_irq_type(struct irq_data *d, u32 type) | ||
142 | { | ||
143 | u32 gpio = irq_to_gpio(d->irq); | ||
144 | struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); | ||
145 | struct mxc_gpio_port *port = gc->private; | ||
146 | u32 bit, val; | ||
147 | int edge; | ||
148 | void __iomem *reg = port->base; | ||
149 | |||
150 | port->both_edges &= ~(1 << (gpio & 31)); | ||
151 | switch (type) { | ||
152 | case IRQ_TYPE_EDGE_RISING: | ||
153 | edge = GPIO_INT_RISE_EDGE; | ||
154 | break; | ||
155 | case IRQ_TYPE_EDGE_FALLING: | ||
156 | edge = GPIO_INT_FALL_EDGE; | ||
157 | break; | ||
158 | case IRQ_TYPE_EDGE_BOTH: | ||
159 | val = gpio_get_value(gpio); | ||
160 | if (val) { | ||
161 | edge = GPIO_INT_LOW_LEV; | ||
162 | pr_debug("mxc: set GPIO %d to low trigger\n", gpio); | ||
163 | } else { | ||
164 | edge = GPIO_INT_HIGH_LEV; | ||
165 | pr_debug("mxc: set GPIO %d to high trigger\n", gpio); | ||
166 | } | ||
167 | port->both_edges |= 1 << (gpio & 31); | ||
168 | break; | ||
169 | case IRQ_TYPE_LEVEL_LOW: | ||
170 | edge = GPIO_INT_LOW_LEV; | ||
171 | break; | ||
172 | case IRQ_TYPE_LEVEL_HIGH: | ||
173 | edge = GPIO_INT_HIGH_LEV; | ||
174 | break; | ||
175 | default: | ||
176 | return -EINVAL; | ||
177 | } | ||
178 | |||
179 | reg += GPIO_ICR1 + ((gpio & 0x10) >> 2); /* lower or upper register */ | ||
180 | bit = gpio & 0xf; | ||
181 | val = readl(reg) & ~(0x3 << (bit << 1)); | ||
182 | writel(val | (edge << (bit << 1)), reg); | ||
183 | writel(1 << (gpio & 0x1f), port->base + GPIO_ISR); | ||
184 | |||
185 | return 0; | ||
186 | } | ||
187 | |||
188 | static void mxc_flip_edge(struct mxc_gpio_port *port, u32 gpio) | ||
189 | { | ||
190 | void __iomem *reg = port->base; | ||
191 | u32 bit, val; | ||
192 | int edge; | ||
193 | |||
194 | reg += GPIO_ICR1 + ((gpio & 0x10) >> 2); /* lower or upper register */ | ||
195 | bit = gpio & 0xf; | ||
196 | val = readl(reg); | ||
197 | edge = (val >> (bit << 1)) & 3; | ||
198 | val &= ~(0x3 << (bit << 1)); | ||
199 | if (edge == GPIO_INT_HIGH_LEV) { | ||
200 | edge = GPIO_INT_LOW_LEV; | ||
201 | pr_debug("mxc: switch GPIO %d to low trigger\n", gpio); | ||
202 | } else if (edge == GPIO_INT_LOW_LEV) { | ||
203 | edge = GPIO_INT_HIGH_LEV; | ||
204 | pr_debug("mxc: switch GPIO %d to high trigger\n", gpio); | ||
205 | } else { | ||
206 | pr_err("mxc: invalid configuration for GPIO %d: %x\n", | ||
207 | gpio, edge); | ||
208 | return; | ||
209 | } | ||
210 | writel(val | (edge << (bit << 1)), reg); | ||
211 | } | ||
212 | |||
213 | /* handle 32 interrupts in one status register */ | ||
214 | static void mxc_gpio_irq_handler(struct mxc_gpio_port *port, u32 irq_stat) | ||
215 | { | ||
216 | u32 gpio_irq_no_base = port->virtual_irq_start; | ||
217 | |||
218 | while (irq_stat != 0) { | ||
219 | int irqoffset = fls(irq_stat) - 1; | ||
220 | |||
221 | if (port->both_edges & (1 << irqoffset)) | ||
222 | mxc_flip_edge(port, irqoffset); | ||
223 | |||
224 | generic_handle_irq(gpio_irq_no_base + irqoffset); | ||
225 | |||
226 | irq_stat &= ~(1 << irqoffset); | ||
227 | } | ||
228 | } | ||
229 | |||
230 | /* MX1 and MX3 has one interrupt *per* gpio port */ | ||
231 | static void mx3_gpio_irq_handler(u32 irq, struct irq_desc *desc) | ||
232 | { | ||
233 | u32 irq_stat; | ||
234 | struct mxc_gpio_port *port = irq_get_handler_data(irq); | ||
235 | |||
236 | irq_stat = readl(port->base + GPIO_ISR) & readl(port->base + GPIO_IMR); | ||
237 | |||
238 | mxc_gpio_irq_handler(port, irq_stat); | ||
239 | } | ||
240 | |||
241 | /* MX2 has one interrupt *for all* gpio ports */ | ||
242 | static void mx2_gpio_irq_handler(u32 irq, struct irq_desc *desc) | ||
243 | { | ||
244 | u32 irq_msk, irq_stat; | ||
245 | struct mxc_gpio_port *port; | ||
246 | |||
247 | /* walk through all interrupt status registers */ | ||
248 | list_for_each_entry(port, &mxc_gpio_ports, node) { | ||
249 | irq_msk = readl(port->base + GPIO_IMR); | ||
250 | if (!irq_msk) | ||
251 | continue; | ||
252 | |||
253 | irq_stat = readl(port->base + GPIO_ISR) & irq_msk; | ||
254 | if (irq_stat) | ||
255 | mxc_gpio_irq_handler(port, irq_stat); | ||
256 | } | ||
257 | } | ||
258 | |||
259 | /* | ||
260 | * Set interrupt number "irq" in the GPIO as a wake-up source. | ||
261 | * While system is running, all registered GPIO interrupts need to have | ||
262 | * wake-up enabled. When system is suspended, only selected GPIO interrupts | ||
263 | * need to have wake-up enabled. | ||
264 | * @param irq interrupt source number | ||
265 | * @param enable enable as wake-up if equal to non-zero | ||
266 | * @return This function returns 0 on success. | ||
267 | */ | ||
268 | static int gpio_set_wake_irq(struct irq_data *d, u32 enable) | ||
269 | { | ||
270 | u32 gpio = irq_to_gpio(d->irq); | ||
271 | u32 gpio_idx = gpio & 0x1F; | ||
272 | struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); | ||
273 | struct mxc_gpio_port *port = gc->private; | ||
274 | |||
275 | if (enable) { | ||
276 | if (port->irq_high && (gpio_idx >= 16)) | ||
277 | enable_irq_wake(port->irq_high); | ||
278 | else | ||
279 | enable_irq_wake(port->irq); | ||
280 | } else { | ||
281 | if (port->irq_high && (gpio_idx >= 16)) | ||
282 | disable_irq_wake(port->irq_high); | ||
283 | else | ||
284 | disable_irq_wake(port->irq); | ||
285 | } | ||
286 | |||
287 | return 0; | ||
288 | } | ||
289 | |||
290 | static void __init mxc_gpio_init_gc(struct mxc_gpio_port *port) | ||
291 | { | ||
292 | struct irq_chip_generic *gc; | ||
293 | struct irq_chip_type *ct; | ||
294 | |||
295 | gc = irq_alloc_generic_chip("gpio-mxc", 1, port->virtual_irq_start, | ||
296 | port->base, handle_level_irq); | ||
297 | gc->private = port; | ||
298 | |||
299 | ct = gc->chip_types; | ||
300 | ct->chip.irq_ack = irq_gc_ack_set_bit; | ||
301 | ct->chip.irq_mask = irq_gc_mask_clr_bit; | ||
302 | ct->chip.irq_unmask = irq_gc_mask_set_bit; | ||
303 | ct->chip.irq_set_type = gpio_set_irq_type; | ||
304 | ct->chip.irq_set_wake = gpio_set_wake_irq; | ||
305 | ct->regs.ack = GPIO_ISR; | ||
306 | ct->regs.mask = GPIO_IMR; | ||
307 | |||
308 | irq_setup_generic_chip(gc, IRQ_MSK(32), IRQ_GC_INIT_NESTED_LOCK, | ||
309 | IRQ_NOREQUEST, 0); | ||
310 | } | ||
311 | |||
312 | static void __devinit mxc_gpio_get_hw(struct platform_device *pdev) | ||
313 | { | ||
314 | const struct of_device_id *of_id = | ||
315 | of_match_device(mxc_gpio_dt_ids, &pdev->dev); | ||
316 | enum mxc_gpio_hwtype hwtype; | ||
317 | |||
318 | if (of_id) | ||
319 | pdev->id_entry = of_id->data; | ||
320 | hwtype = pdev->id_entry->driver_data; | ||
321 | |||
322 | if (mxc_gpio_hwtype) { | ||
323 | /* | ||
324 | * The driver works with a reasonable presupposition, | ||
325 | * that is all gpio ports must be the same type when | ||
326 | * running on one soc. | ||
327 | */ | ||
328 | BUG_ON(mxc_gpio_hwtype != hwtype); | ||
329 | return; | ||
330 | } | ||
331 | |||
332 | if (hwtype == IMX31_GPIO) | ||
333 | mxc_gpio_hwdata = &imx31_gpio_hwdata; | ||
334 | else | ||
335 | mxc_gpio_hwdata = &imx1_imx21_gpio_hwdata; | ||
336 | |||
337 | mxc_gpio_hwtype = hwtype; | ||
338 | } | ||
339 | |||
340 | static int __devinit mxc_gpio_probe(struct platform_device *pdev) | ||
341 | { | ||
342 | struct device_node *np = pdev->dev.of_node; | ||
343 | struct mxc_gpio_port *port; | ||
344 | struct resource *iores; | ||
345 | int err; | ||
346 | |||
347 | mxc_gpio_get_hw(pdev); | ||
348 | |||
349 | port = kzalloc(sizeof(struct mxc_gpio_port), GFP_KERNEL); | ||
350 | if (!port) | ||
351 | return -ENOMEM; | ||
352 | |||
353 | iores = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
354 | if (!iores) { | ||
355 | err = -ENODEV; | ||
356 | goto out_kfree; | ||
357 | } | ||
358 | |||
359 | if (!request_mem_region(iores->start, resource_size(iores), | ||
360 | pdev->name)) { | ||
361 | err = -EBUSY; | ||
362 | goto out_kfree; | ||
363 | } | ||
364 | |||
365 | port->base = ioremap(iores->start, resource_size(iores)); | ||
366 | if (!port->base) { | ||
367 | err = -ENOMEM; | ||
368 | goto out_release_mem; | ||
369 | } | ||
370 | |||
371 | port->irq_high = platform_get_irq(pdev, 1); | ||
372 | port->irq = platform_get_irq(pdev, 0); | ||
373 | if (port->irq < 0) { | ||
374 | err = -EINVAL; | ||
375 | goto out_iounmap; | ||
376 | } | ||
377 | |||
378 | /* disable the interrupt and clear the status */ | ||
379 | writel(0, port->base + GPIO_IMR); | ||
380 | writel(~0, port->base + GPIO_ISR); | ||
381 | |||
382 | if (mxc_gpio_hwtype == IMX21_GPIO) { | ||
383 | /* setup one handler for all GPIO interrupts */ | ||
384 | if (pdev->id == 0) | ||
385 | irq_set_chained_handler(port->irq, | ||
386 | mx2_gpio_irq_handler); | ||
387 | } else { | ||
388 | /* setup one handler for each entry */ | ||
389 | irq_set_chained_handler(port->irq, mx3_gpio_irq_handler); | ||
390 | irq_set_handler_data(port->irq, port); | ||
391 | if (port->irq_high > 0) { | ||
392 | /* setup handler for GPIO 16 to 31 */ | ||
393 | irq_set_chained_handler(port->irq_high, | ||
394 | mx3_gpio_irq_handler); | ||
395 | irq_set_handler_data(port->irq_high, port); | ||
396 | } | ||
397 | } | ||
398 | |||
399 | err = bgpio_init(&port->bgc, &pdev->dev, 4, | ||
400 | port->base + GPIO_PSR, | ||
401 | port->base + GPIO_DR, NULL, | ||
402 | port->base + GPIO_GDIR, NULL, false); | ||
403 | if (err) | ||
404 | goto out_iounmap; | ||
405 | |||
406 | port->bgc.gc.base = pdev->id * 32; | ||
407 | port->bgc.dir = port->bgc.read_reg(port->bgc.reg_dir); | ||
408 | port->bgc.data = port->bgc.read_reg(port->bgc.reg_set); | ||
409 | |||
410 | err = gpiochip_add(&port->bgc.gc); | ||
411 | if (err) | ||
412 | goto out_bgpio_remove; | ||
413 | |||
414 | /* | ||
415 | * In dt case, we use gpio number range dynamically | ||
416 | * allocated by gpio core. | ||
417 | */ | ||
418 | port->virtual_irq_start = MXC_GPIO_IRQ_START + (np ? port->bgc.gc.base : | ||
419 | pdev->id * 32); | ||
420 | |||
421 | /* gpio-mxc can be a generic irq chip */ | ||
422 | mxc_gpio_init_gc(port); | ||
423 | |||
424 | list_add_tail(&port->node, &mxc_gpio_ports); | ||
425 | |||
426 | return 0; | ||
427 | |||
428 | out_bgpio_remove: | ||
429 | bgpio_remove(&port->bgc); | ||
430 | out_iounmap: | ||
431 | iounmap(port->base); | ||
432 | out_release_mem: | ||
433 | release_mem_region(iores->start, resource_size(iores)); | ||
434 | out_kfree: | ||
435 | kfree(port); | ||
436 | dev_info(&pdev->dev, "%s failed with errno %d\n", __func__, err); | ||
437 | return err; | ||
438 | } | ||
439 | |||
440 | static struct platform_driver mxc_gpio_driver = { | ||
441 | .driver = { | ||
442 | .name = "gpio-mxc", | ||
443 | .owner = THIS_MODULE, | ||
444 | .of_match_table = mxc_gpio_dt_ids, | ||
445 | }, | ||
446 | .probe = mxc_gpio_probe, | ||
447 | .id_table = mxc_gpio_devtype, | ||
448 | }; | ||
449 | |||
450 | static int __init gpio_mxc_init(void) | ||
451 | { | ||
452 | return platform_driver_register(&mxc_gpio_driver); | ||
453 | } | ||
454 | postcore_initcall(gpio_mxc_init); | ||
455 | |||
456 | MODULE_AUTHOR("Freescale Semiconductor, " | ||
457 | "Daniel Mack <danielncaiaq.de>, " | ||
458 | "Juergen Beisert <kernel@pengutronix.de>"); | ||
459 | MODULE_DESCRIPTION("Freescale MXC GPIO"); | ||
460 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/gpio/gpio-mxs.c b/drivers/gpio/gpio-mxs.c new file mode 100644 index 000000000000..af55a8577c2e --- /dev/null +++ b/drivers/gpio/gpio-mxs.c | |||
@@ -0,0 +1,289 @@ | |||
1 | /* | ||
2 | * MXC GPIO support. (c) 2008 Daniel Mack <daniel@caiaq.de> | ||
3 | * Copyright 2008 Juergen Beisert, kernel@pengutronix.de | ||
4 | * | ||
5 | * Based on code from Freescale, | ||
6 | * Copyright (C) 2004-2010 Freescale Semiconductor, Inc. All Rights Reserved. | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or | ||
9 | * modify it under the terms of the GNU General Public License | ||
10 | * as published by the Free Software Foundation; either version 2 | ||
11 | * of the License, or (at your option) any later version. | ||
12 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License | ||
18 | * along with this program; if not, write to the Free Software | ||
19 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, | ||
20 | * MA 02110-1301, USA. | ||
21 | */ | ||
22 | |||
23 | #include <linux/init.h> | ||
24 | #include <linux/interrupt.h> | ||
25 | #include <linux/io.h> | ||
26 | #include <linux/irq.h> | ||
27 | #include <linux/gpio.h> | ||
28 | #include <linux/platform_device.h> | ||
29 | #include <linux/slab.h> | ||
30 | #include <linux/basic_mmio_gpio.h> | ||
31 | #include <mach/mxs.h> | ||
32 | |||
33 | #define MXS_SET 0x4 | ||
34 | #define MXS_CLR 0x8 | ||
35 | |||
36 | #define PINCTRL_DOUT(n) ((cpu_is_mx23() ? 0x0500 : 0x0700) + (n) * 0x10) | ||
37 | #define PINCTRL_DIN(n) ((cpu_is_mx23() ? 0x0600 : 0x0900) + (n) * 0x10) | ||
38 | #define PINCTRL_DOE(n) ((cpu_is_mx23() ? 0x0700 : 0x0b00) + (n) * 0x10) | ||
39 | #define PINCTRL_PIN2IRQ(n) ((cpu_is_mx23() ? 0x0800 : 0x1000) + (n) * 0x10) | ||
40 | #define PINCTRL_IRQEN(n) ((cpu_is_mx23() ? 0x0900 : 0x1100) + (n) * 0x10) | ||
41 | #define PINCTRL_IRQLEV(n) ((cpu_is_mx23() ? 0x0a00 : 0x1200) + (n) * 0x10) | ||
42 | #define PINCTRL_IRQPOL(n) ((cpu_is_mx23() ? 0x0b00 : 0x1300) + (n) * 0x10) | ||
43 | #define PINCTRL_IRQSTAT(n) ((cpu_is_mx23() ? 0x0c00 : 0x1400) + (n) * 0x10) | ||
44 | |||
45 | #define GPIO_INT_FALL_EDGE 0x0 | ||
46 | #define GPIO_INT_LOW_LEV 0x1 | ||
47 | #define GPIO_INT_RISE_EDGE 0x2 | ||
48 | #define GPIO_INT_HIGH_LEV 0x3 | ||
49 | #define GPIO_INT_LEV_MASK (1 << 0) | ||
50 | #define GPIO_INT_POL_MASK (1 << 1) | ||
51 | |||
52 | struct mxs_gpio_port { | ||
53 | void __iomem *base; | ||
54 | int id; | ||
55 | int irq; | ||
56 | int virtual_irq_start; | ||
57 | struct bgpio_chip bgc; | ||
58 | }; | ||
59 | |||
60 | /* Note: This driver assumes 32 GPIOs are handled in one register */ | ||
61 | |||
62 | static int mxs_gpio_set_irq_type(struct irq_data *d, unsigned int type) | ||
63 | { | ||
64 | u32 gpio = irq_to_gpio(d->irq); | ||
65 | u32 pin_mask = 1 << (gpio & 31); | ||
66 | struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); | ||
67 | struct mxs_gpio_port *port = gc->private; | ||
68 | void __iomem *pin_addr; | ||
69 | int edge; | ||
70 | |||
71 | switch (type) { | ||
72 | case IRQ_TYPE_EDGE_RISING: | ||
73 | edge = GPIO_INT_RISE_EDGE; | ||
74 | break; | ||
75 | case IRQ_TYPE_EDGE_FALLING: | ||
76 | edge = GPIO_INT_FALL_EDGE; | ||
77 | break; | ||
78 | case IRQ_TYPE_LEVEL_LOW: | ||
79 | edge = GPIO_INT_LOW_LEV; | ||
80 | break; | ||
81 | case IRQ_TYPE_LEVEL_HIGH: | ||
82 | edge = GPIO_INT_HIGH_LEV; | ||
83 | break; | ||
84 | default: | ||
85 | return -EINVAL; | ||
86 | } | ||
87 | |||
88 | /* set level or edge */ | ||
89 | pin_addr = port->base + PINCTRL_IRQLEV(port->id); | ||
90 | if (edge & GPIO_INT_LEV_MASK) | ||
91 | writel(pin_mask, pin_addr + MXS_SET); | ||
92 | else | ||
93 | writel(pin_mask, pin_addr + MXS_CLR); | ||
94 | |||
95 | /* set polarity */ | ||
96 | pin_addr = port->base + PINCTRL_IRQPOL(port->id); | ||
97 | if (edge & GPIO_INT_POL_MASK) | ||
98 | writel(pin_mask, pin_addr + MXS_SET); | ||
99 | else | ||
100 | writel(pin_mask, pin_addr + MXS_CLR); | ||
101 | |||
102 | writel(1 << (gpio & 0x1f), | ||
103 | port->base + PINCTRL_IRQSTAT(port->id) + MXS_CLR); | ||
104 | |||
105 | return 0; | ||
106 | } | ||
107 | |||
108 | /* MXS has one interrupt *per* gpio port */ | ||
109 | static void mxs_gpio_irq_handler(u32 irq, struct irq_desc *desc) | ||
110 | { | ||
111 | u32 irq_stat; | ||
112 | struct mxs_gpio_port *port = irq_get_handler_data(irq); | ||
113 | u32 gpio_irq_no_base = port->virtual_irq_start; | ||
114 | |||
115 | desc->irq_data.chip->irq_ack(&desc->irq_data); | ||
116 | |||
117 | irq_stat = readl(port->base + PINCTRL_IRQSTAT(port->id)) & | ||
118 | readl(port->base + PINCTRL_IRQEN(port->id)); | ||
119 | |||
120 | while (irq_stat != 0) { | ||
121 | int irqoffset = fls(irq_stat) - 1; | ||
122 | generic_handle_irq(gpio_irq_no_base + irqoffset); | ||
123 | irq_stat &= ~(1 << irqoffset); | ||
124 | } | ||
125 | } | ||
126 | |||
127 | /* | ||
128 | * Set interrupt number "irq" in the GPIO as a wake-up source. | ||
129 | * While system is running, all registered GPIO interrupts need to have | ||
130 | * wake-up enabled. When system is suspended, only selected GPIO interrupts | ||
131 | * need to have wake-up enabled. | ||
132 | * @param irq interrupt source number | ||
133 | * @param enable enable as wake-up if equal to non-zero | ||
134 | * @return This function returns 0 on success. | ||
135 | */ | ||
136 | static int mxs_gpio_set_wake_irq(struct irq_data *d, unsigned int enable) | ||
137 | { | ||
138 | struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); | ||
139 | struct mxs_gpio_port *port = gc->private; | ||
140 | |||
141 | if (enable) | ||
142 | enable_irq_wake(port->irq); | ||
143 | else | ||
144 | disable_irq_wake(port->irq); | ||
145 | |||
146 | return 0; | ||
147 | } | ||
148 | |||
149 | static void __init mxs_gpio_init_gc(struct mxs_gpio_port *port) | ||
150 | { | ||
151 | struct irq_chip_generic *gc; | ||
152 | struct irq_chip_type *ct; | ||
153 | |||
154 | gc = irq_alloc_generic_chip("gpio-mxs", 1, port->virtual_irq_start, | ||
155 | port->base, handle_level_irq); | ||
156 | gc->private = port; | ||
157 | |||
158 | ct = gc->chip_types; | ||
159 | ct->chip.irq_ack = irq_gc_ack_set_bit; | ||
160 | ct->chip.irq_mask = irq_gc_mask_clr_bit; | ||
161 | ct->chip.irq_unmask = irq_gc_mask_set_bit; | ||
162 | ct->chip.irq_set_type = mxs_gpio_set_irq_type; | ||
163 | ct->chip.irq_set_wake = mxs_gpio_set_wake_irq; | ||
164 | ct->regs.ack = PINCTRL_IRQSTAT(port->id) + MXS_CLR; | ||
165 | ct->regs.mask = PINCTRL_IRQEN(port->id); | ||
166 | |||
167 | irq_setup_generic_chip(gc, IRQ_MSK(32), 0, IRQ_NOREQUEST, 0); | ||
168 | } | ||
169 | |||
170 | static int mxs_gpio_to_irq(struct gpio_chip *gc, unsigned offset) | ||
171 | { | ||
172 | struct bgpio_chip *bgc = to_bgpio_chip(gc); | ||
173 | struct mxs_gpio_port *port = | ||
174 | container_of(bgc, struct mxs_gpio_port, bgc); | ||
175 | |||
176 | return port->virtual_irq_start + offset; | ||
177 | } | ||
178 | |||
179 | static int __devinit mxs_gpio_probe(struct platform_device *pdev) | ||
180 | { | ||
181 | static void __iomem *base; | ||
182 | struct mxs_gpio_port *port; | ||
183 | struct resource *iores = NULL; | ||
184 | int err; | ||
185 | |||
186 | port = kzalloc(sizeof(struct mxs_gpio_port), GFP_KERNEL); | ||
187 | if (!port) | ||
188 | return -ENOMEM; | ||
189 | |||
190 | port->id = pdev->id; | ||
191 | port->virtual_irq_start = MXS_GPIO_IRQ_START + port->id * 32; | ||
192 | |||
193 | /* | ||
194 | * map memory region only once, as all the gpio ports | ||
195 | * share the same one | ||
196 | */ | ||
197 | if (!base) { | ||
198 | iores = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
199 | if (!iores) { | ||
200 | err = -ENODEV; | ||
201 | goto out_kfree; | ||
202 | } | ||
203 | |||
204 | if (!request_mem_region(iores->start, resource_size(iores), | ||
205 | pdev->name)) { | ||
206 | err = -EBUSY; | ||
207 | goto out_kfree; | ||
208 | } | ||
209 | |||
210 | base = ioremap(iores->start, resource_size(iores)); | ||
211 | if (!base) { | ||
212 | err = -ENOMEM; | ||
213 | goto out_release_mem; | ||
214 | } | ||
215 | } | ||
216 | port->base = base; | ||
217 | |||
218 | port->irq = platform_get_irq(pdev, 0); | ||
219 | if (port->irq < 0) { | ||
220 | err = -EINVAL; | ||
221 | goto out_iounmap; | ||
222 | } | ||
223 | |||
224 | /* | ||
225 | * select the pin interrupt functionality but initially | ||
226 | * disable the interrupts | ||
227 | */ | ||
228 | writel(~0U, port->base + PINCTRL_PIN2IRQ(port->id)); | ||
229 | writel(0, port->base + PINCTRL_IRQEN(port->id)); | ||
230 | |||
231 | /* clear address has to be used to clear IRQSTAT bits */ | ||
232 | writel(~0U, port->base + PINCTRL_IRQSTAT(port->id) + MXS_CLR); | ||
233 | |||
234 | /* gpio-mxs can be a generic irq chip */ | ||
235 | mxs_gpio_init_gc(port); | ||
236 | |||
237 | /* setup one handler for each entry */ | ||
238 | irq_set_chained_handler(port->irq, mxs_gpio_irq_handler); | ||
239 | irq_set_handler_data(port->irq, port); | ||
240 | |||
241 | err = bgpio_init(&port->bgc, &pdev->dev, 4, | ||
242 | port->base + PINCTRL_DIN(port->id), | ||
243 | port->base + PINCTRL_DOUT(port->id), NULL, | ||
244 | port->base + PINCTRL_DOE(port->id), NULL, false); | ||
245 | if (err) | ||
246 | goto out_iounmap; | ||
247 | |||
248 | port->bgc.gc.to_irq = mxs_gpio_to_irq; | ||
249 | port->bgc.gc.base = port->id * 32; | ||
250 | |||
251 | err = gpiochip_add(&port->bgc.gc); | ||
252 | if (err) | ||
253 | goto out_bgpio_remove; | ||
254 | |||
255 | return 0; | ||
256 | |||
257 | out_bgpio_remove: | ||
258 | bgpio_remove(&port->bgc); | ||
259 | out_iounmap: | ||
260 | if (iores) | ||
261 | iounmap(port->base); | ||
262 | out_release_mem: | ||
263 | if (iores) | ||
264 | release_mem_region(iores->start, resource_size(iores)); | ||
265 | out_kfree: | ||
266 | kfree(port); | ||
267 | dev_info(&pdev->dev, "%s failed with errno %d\n", __func__, err); | ||
268 | return err; | ||
269 | } | ||
270 | |||
271 | static struct platform_driver mxs_gpio_driver = { | ||
272 | .driver = { | ||
273 | .name = "gpio-mxs", | ||
274 | .owner = THIS_MODULE, | ||
275 | }, | ||
276 | .probe = mxs_gpio_probe, | ||
277 | }; | ||
278 | |||
279 | static int __init mxs_gpio_init(void) | ||
280 | { | ||
281 | return platform_driver_register(&mxs_gpio_driver); | ||
282 | } | ||
283 | postcore_initcall(mxs_gpio_init); | ||
284 | |||
285 | MODULE_AUTHOR("Freescale Semiconductor, " | ||
286 | "Daniel Mack <danielncaiaq.de>, " | ||
287 | "Juergen Beisert <kernel@pengutronix.de>"); | ||
288 | MODULE_DESCRIPTION("Freescale MXS GPIO"); | ||
289 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c index 35bebde23e83..0599854e2217 100644 --- a/drivers/gpio/gpio-omap.c +++ b/drivers/gpio/gpio-omap.c | |||
@@ -54,6 +54,11 @@ struct gpio_bank { | |||
54 | struct device *dev; | 54 | struct device *dev; |
55 | bool dbck_flag; | 55 | bool dbck_flag; |
56 | int stride; | 56 | int stride; |
57 | u32 width; | ||
58 | |||
59 | void (*set_dataout)(struct gpio_bank *bank, int gpio, int enable); | ||
60 | |||
61 | struct omap_gpio_reg_offs *regs; | ||
57 | }; | 62 | }; |
58 | 63 | ||
59 | #ifdef CONFIG_ARCH_OMAP3 | 64 | #ifdef CONFIG_ARCH_OMAP3 |
@@ -79,121 +84,18 @@ static struct omap3_gpio_regs gpio_context[OMAP34XX_NR_GPIOS]; | |||
79 | */ | 84 | */ |
80 | static struct gpio_bank *gpio_bank; | 85 | static struct gpio_bank *gpio_bank; |
81 | 86 | ||
82 | static int bank_width; | ||
83 | |||
84 | /* TODO: Analyze removing gpio_bank_count usage from driver code */ | 87 | /* TODO: Analyze removing gpio_bank_count usage from driver code */ |
85 | int gpio_bank_count; | 88 | int gpio_bank_count; |
86 | 89 | ||
87 | static inline struct gpio_bank *get_gpio_bank(int gpio) | 90 | #define GPIO_INDEX(bank, gpio) (gpio % bank->width) |
88 | { | 91 | #define GPIO_BIT(bank, gpio) (1 << GPIO_INDEX(bank, gpio)) |
89 | if (cpu_is_omap15xx()) { | ||
90 | if (OMAP_GPIO_IS_MPUIO(gpio)) | ||
91 | return &gpio_bank[0]; | ||
92 | return &gpio_bank[1]; | ||
93 | } | ||
94 | if (cpu_is_omap16xx()) { | ||
95 | if (OMAP_GPIO_IS_MPUIO(gpio)) | ||
96 | return &gpio_bank[0]; | ||
97 | return &gpio_bank[1 + (gpio >> 4)]; | ||
98 | } | ||
99 | if (cpu_is_omap7xx()) { | ||
100 | if (OMAP_GPIO_IS_MPUIO(gpio)) | ||
101 | return &gpio_bank[0]; | ||
102 | return &gpio_bank[1 + (gpio >> 5)]; | ||
103 | } | ||
104 | if (cpu_is_omap24xx()) | ||
105 | return &gpio_bank[gpio >> 5]; | ||
106 | if (cpu_is_omap34xx() || cpu_is_omap44xx()) | ||
107 | return &gpio_bank[gpio >> 5]; | ||
108 | BUG(); | ||
109 | return NULL; | ||
110 | } | ||
111 | |||
112 | static inline int get_gpio_index(int gpio) | ||
113 | { | ||
114 | if (cpu_is_omap7xx()) | ||
115 | return gpio & 0x1f; | ||
116 | if (cpu_is_omap24xx()) | ||
117 | return gpio & 0x1f; | ||
118 | if (cpu_is_omap34xx() || cpu_is_omap44xx()) | ||
119 | return gpio & 0x1f; | ||
120 | return gpio & 0x0f; | ||
121 | } | ||
122 | |||
123 | static inline int gpio_valid(int gpio) | ||
124 | { | ||
125 | if (gpio < 0) | ||
126 | return -1; | ||
127 | if (cpu_class_is_omap1() && OMAP_GPIO_IS_MPUIO(gpio)) { | ||
128 | if (gpio >= OMAP_MAX_GPIO_LINES + 16) | ||
129 | return -1; | ||
130 | return 0; | ||
131 | } | ||
132 | if (cpu_is_omap15xx() && gpio < 16) | ||
133 | return 0; | ||
134 | if ((cpu_is_omap16xx()) && gpio < 64) | ||
135 | return 0; | ||
136 | if (cpu_is_omap7xx() && gpio < 192) | ||
137 | return 0; | ||
138 | if (cpu_is_omap2420() && gpio < 128) | ||
139 | return 0; | ||
140 | if (cpu_is_omap2430() && gpio < 160) | ||
141 | return 0; | ||
142 | if ((cpu_is_omap34xx() || cpu_is_omap44xx()) && gpio < 192) | ||
143 | return 0; | ||
144 | return -1; | ||
145 | } | ||
146 | |||
147 | static int check_gpio(int gpio) | ||
148 | { | ||
149 | if (unlikely(gpio_valid(gpio) < 0)) { | ||
150 | printk(KERN_ERR "omap-gpio: invalid GPIO %d\n", gpio); | ||
151 | dump_stack(); | ||
152 | return -1; | ||
153 | } | ||
154 | return 0; | ||
155 | } | ||
156 | 92 | ||
157 | static void _set_gpio_direction(struct gpio_bank *bank, int gpio, int is_input) | 93 | static void _set_gpio_direction(struct gpio_bank *bank, int gpio, int is_input) |
158 | { | 94 | { |
159 | void __iomem *reg = bank->base; | 95 | void __iomem *reg = bank->base; |
160 | u32 l; | 96 | u32 l; |
161 | 97 | ||
162 | switch (bank->method) { | 98 | reg += bank->regs->direction; |
163 | #ifdef CONFIG_ARCH_OMAP1 | ||
164 | case METHOD_MPUIO: | ||
165 | reg += OMAP_MPUIO_IO_CNTL / bank->stride; | ||
166 | break; | ||
167 | #endif | ||
168 | #ifdef CONFIG_ARCH_OMAP15XX | ||
169 | case METHOD_GPIO_1510: | ||
170 | reg += OMAP1510_GPIO_DIR_CONTROL; | ||
171 | break; | ||
172 | #endif | ||
173 | #ifdef CONFIG_ARCH_OMAP16XX | ||
174 | case METHOD_GPIO_1610: | ||
175 | reg += OMAP1610_GPIO_DIRECTION; | ||
176 | break; | ||
177 | #endif | ||
178 | #if defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850) | ||
179 | case METHOD_GPIO_7XX: | ||
180 | reg += OMAP7XX_GPIO_DIR_CONTROL; | ||
181 | break; | ||
182 | #endif | ||
183 | #if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3) | ||
184 | case METHOD_GPIO_24XX: | ||
185 | reg += OMAP24XX_GPIO_OE; | ||
186 | break; | ||
187 | #endif | ||
188 | #if defined(CONFIG_ARCH_OMAP4) | ||
189 | case METHOD_GPIO_44XX: | ||
190 | reg += OMAP4_GPIO_OE; | ||
191 | break; | ||
192 | #endif | ||
193 | default: | ||
194 | WARN_ON(1); | ||
195 | return; | ||
196 | } | ||
197 | l = __raw_readl(reg); | 99 | l = __raw_readl(reg); |
198 | if (is_input) | 100 | if (is_input) |
199 | l |= 1 << gpio; | 101 | l |= 1 << gpio; |
@@ -202,165 +104,48 @@ static void _set_gpio_direction(struct gpio_bank *bank, int gpio, int is_input) | |||
202 | __raw_writel(l, reg); | 104 | __raw_writel(l, reg); |
203 | } | 105 | } |
204 | 106 | ||
205 | static void _set_gpio_dataout(struct gpio_bank *bank, int gpio, int enable) | 107 | |
108 | /* set data out value using dedicate set/clear register */ | ||
109 | static void _set_gpio_dataout_reg(struct gpio_bank *bank, int gpio, int enable) | ||
206 | { | 110 | { |
207 | void __iomem *reg = bank->base; | 111 | void __iomem *reg = bank->base; |
208 | u32 l = 0; | 112 | u32 l = GPIO_BIT(bank, gpio); |
113 | |||
114 | if (enable) | ||
115 | reg += bank->regs->set_dataout; | ||
116 | else | ||
117 | reg += bank->regs->clr_dataout; | ||
209 | 118 | ||
210 | switch (bank->method) { | ||
211 | #ifdef CONFIG_ARCH_OMAP1 | ||
212 | case METHOD_MPUIO: | ||
213 | reg += OMAP_MPUIO_OUTPUT / bank->stride; | ||
214 | l = __raw_readl(reg); | ||
215 | if (enable) | ||
216 | l |= 1 << gpio; | ||
217 | else | ||
218 | l &= ~(1 << gpio); | ||
219 | break; | ||
220 | #endif | ||
221 | #ifdef CONFIG_ARCH_OMAP15XX | ||
222 | case METHOD_GPIO_1510: | ||
223 | reg += OMAP1510_GPIO_DATA_OUTPUT; | ||
224 | l = __raw_readl(reg); | ||
225 | if (enable) | ||
226 | l |= 1 << gpio; | ||
227 | else | ||
228 | l &= ~(1 << gpio); | ||
229 | break; | ||
230 | #endif | ||
231 | #ifdef CONFIG_ARCH_OMAP16XX | ||
232 | case METHOD_GPIO_1610: | ||
233 | if (enable) | ||
234 | reg += OMAP1610_GPIO_SET_DATAOUT; | ||
235 | else | ||
236 | reg += OMAP1610_GPIO_CLEAR_DATAOUT; | ||
237 | l = 1 << gpio; | ||
238 | break; | ||
239 | #endif | ||
240 | #if defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850) | ||
241 | case METHOD_GPIO_7XX: | ||
242 | reg += OMAP7XX_GPIO_DATA_OUTPUT; | ||
243 | l = __raw_readl(reg); | ||
244 | if (enable) | ||
245 | l |= 1 << gpio; | ||
246 | else | ||
247 | l &= ~(1 << gpio); | ||
248 | break; | ||
249 | #endif | ||
250 | #if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3) | ||
251 | case METHOD_GPIO_24XX: | ||
252 | if (enable) | ||
253 | reg += OMAP24XX_GPIO_SETDATAOUT; | ||
254 | else | ||
255 | reg += OMAP24XX_GPIO_CLEARDATAOUT; | ||
256 | l = 1 << gpio; | ||
257 | break; | ||
258 | #endif | ||
259 | #ifdef CONFIG_ARCH_OMAP4 | ||
260 | case METHOD_GPIO_44XX: | ||
261 | if (enable) | ||
262 | reg += OMAP4_GPIO_SETDATAOUT; | ||
263 | else | ||
264 | reg += OMAP4_GPIO_CLEARDATAOUT; | ||
265 | l = 1 << gpio; | ||
266 | break; | ||
267 | #endif | ||
268 | default: | ||
269 | WARN_ON(1); | ||
270 | return; | ||
271 | } | ||
272 | __raw_writel(l, reg); | 119 | __raw_writel(l, reg); |
273 | } | 120 | } |
274 | 121 | ||
275 | static int _get_gpio_datain(struct gpio_bank *bank, int gpio) | 122 | /* set data out value using mask register */ |
123 | static void _set_gpio_dataout_mask(struct gpio_bank *bank, int gpio, int enable) | ||
276 | { | 124 | { |
277 | void __iomem *reg; | 125 | void __iomem *reg = bank->base + bank->regs->dataout; |
126 | u32 gpio_bit = GPIO_BIT(bank, gpio); | ||
127 | u32 l; | ||
278 | 128 | ||
279 | if (check_gpio(gpio) < 0) | 129 | l = __raw_readl(reg); |
280 | return -EINVAL; | 130 | if (enable) |
281 | reg = bank->base; | 131 | l |= gpio_bit; |
282 | switch (bank->method) { | 132 | else |
283 | #ifdef CONFIG_ARCH_OMAP1 | 133 | l &= ~gpio_bit; |
284 | case METHOD_MPUIO: | 134 | __raw_writel(l, reg); |
285 | reg += OMAP_MPUIO_INPUT_LATCH / bank->stride; | ||
286 | break; | ||
287 | #endif | ||
288 | #ifdef CONFIG_ARCH_OMAP15XX | ||
289 | case METHOD_GPIO_1510: | ||
290 | reg += OMAP1510_GPIO_DATA_INPUT; | ||
291 | break; | ||
292 | #endif | ||
293 | #ifdef CONFIG_ARCH_OMAP16XX | ||
294 | case METHOD_GPIO_1610: | ||
295 | reg += OMAP1610_GPIO_DATAIN; | ||
296 | break; | ||
297 | #endif | ||
298 | #if defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850) | ||
299 | case METHOD_GPIO_7XX: | ||
300 | reg += OMAP7XX_GPIO_DATA_INPUT; | ||
301 | break; | ||
302 | #endif | ||
303 | #if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3) | ||
304 | case METHOD_GPIO_24XX: | ||
305 | reg += OMAP24XX_GPIO_DATAIN; | ||
306 | break; | ||
307 | #endif | ||
308 | #ifdef CONFIG_ARCH_OMAP4 | ||
309 | case METHOD_GPIO_44XX: | ||
310 | reg += OMAP4_GPIO_DATAIN; | ||
311 | break; | ||
312 | #endif | ||
313 | default: | ||
314 | return -EINVAL; | ||
315 | } | ||
316 | return (__raw_readl(reg) | ||
317 | & (1 << get_gpio_index(gpio))) != 0; | ||
318 | } | 135 | } |
319 | 136 | ||
320 | static int _get_gpio_dataout(struct gpio_bank *bank, int gpio) | 137 | static int _get_gpio_datain(struct gpio_bank *bank, int gpio) |
321 | { | 138 | { |
322 | void __iomem *reg; | 139 | void __iomem *reg = bank->base + bank->regs->datain; |
323 | 140 | ||
324 | if (check_gpio(gpio) < 0) | 141 | return (__raw_readl(reg) & GPIO_BIT(bank, gpio)) != 0; |
325 | return -EINVAL; | 142 | } |
326 | reg = bank->base; | ||
327 | 143 | ||
328 | switch (bank->method) { | 144 | static int _get_gpio_dataout(struct gpio_bank *bank, int gpio) |
329 | #ifdef CONFIG_ARCH_OMAP1 | 145 | { |
330 | case METHOD_MPUIO: | 146 | void __iomem *reg = bank->base + bank->regs->dataout; |
331 | reg += OMAP_MPUIO_OUTPUT / bank->stride; | ||
332 | break; | ||
333 | #endif | ||
334 | #ifdef CONFIG_ARCH_OMAP15XX | ||
335 | case METHOD_GPIO_1510: | ||
336 | reg += OMAP1510_GPIO_DATA_OUTPUT; | ||
337 | break; | ||
338 | #endif | ||
339 | #ifdef CONFIG_ARCH_OMAP16XX | ||
340 | case METHOD_GPIO_1610: | ||
341 | reg += OMAP1610_GPIO_DATAOUT; | ||
342 | break; | ||
343 | #endif | ||
344 | #if defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850) | ||
345 | case METHOD_GPIO_7XX: | ||
346 | reg += OMAP7XX_GPIO_DATA_OUTPUT; | ||
347 | break; | ||
348 | #endif | ||
349 | #if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3) | ||
350 | case METHOD_GPIO_24XX: | ||
351 | reg += OMAP24XX_GPIO_DATAOUT; | ||
352 | break; | ||
353 | #endif | ||
354 | #ifdef CONFIG_ARCH_OMAP4 | ||
355 | case METHOD_GPIO_44XX: | ||
356 | reg += OMAP4_GPIO_DATAOUT; | ||
357 | break; | ||
358 | #endif | ||
359 | default: | ||
360 | return -EINVAL; | ||
361 | } | ||
362 | 147 | ||
363 | return (__raw_readl(reg) & (1 << get_gpio_index(gpio))) != 0; | 148 | return (__raw_readl(reg) & GPIO_BIT(bank, gpio)) != 0; |
364 | } | 149 | } |
365 | 150 | ||
366 | #define MOD_REG_BIT(reg, bit_mask, set) \ | 151 | #define MOD_REG_BIT(reg, bit_mask, set) \ |
@@ -383,7 +168,7 @@ do { \ | |||
383 | static void _set_gpio_debounce(struct gpio_bank *bank, unsigned gpio, | 168 | static void _set_gpio_debounce(struct gpio_bank *bank, unsigned gpio, |
384 | unsigned debounce) | 169 | unsigned debounce) |
385 | { | 170 | { |
386 | void __iomem *reg = bank->base; | 171 | void __iomem *reg; |
387 | u32 val; | 172 | u32 val; |
388 | u32 l; | 173 | u32 l; |
389 | 174 | ||
@@ -397,21 +182,12 @@ static void _set_gpio_debounce(struct gpio_bank *bank, unsigned gpio, | |||
397 | else | 182 | else |
398 | debounce = (debounce / 0x1f) - 1; | 183 | debounce = (debounce / 0x1f) - 1; |
399 | 184 | ||
400 | l = 1 << get_gpio_index(gpio); | 185 | l = GPIO_BIT(bank, gpio); |
401 | |||
402 | if (bank->method == METHOD_GPIO_44XX) | ||
403 | reg += OMAP4_GPIO_DEBOUNCINGTIME; | ||
404 | else | ||
405 | reg += OMAP24XX_GPIO_DEBOUNCE_VAL; | ||
406 | 186 | ||
187 | reg = bank->base + bank->regs->debounce; | ||
407 | __raw_writel(debounce, reg); | 188 | __raw_writel(debounce, reg); |
408 | 189 | ||
409 | reg = bank->base; | 190 | reg = bank->base + bank->regs->debounce_en; |
410 | if (bank->method == METHOD_GPIO_44XX) | ||
411 | reg += OMAP4_GPIO_DEBOUNCENABLE; | ||
412 | else | ||
413 | reg += OMAP24XX_GPIO_DEBOUNCE_EN; | ||
414 | |||
415 | val = __raw_readl(reg); | 191 | val = __raw_readl(reg); |
416 | 192 | ||
417 | if (debounce) { | 193 | if (debounce) { |
@@ -629,9 +405,6 @@ static int gpio_irq_type(struct irq_data *d, unsigned type) | |||
629 | else | 405 | else |
630 | gpio = d->irq - IH_GPIO_BASE; | 406 | gpio = d->irq - IH_GPIO_BASE; |
631 | 407 | ||
632 | if (check_gpio(gpio) < 0) | ||
633 | return -EINVAL; | ||
634 | |||
635 | if (type & ~IRQ_TYPE_SENSE_MASK) | 408 | if (type & ~IRQ_TYPE_SENSE_MASK) |
636 | return -EINVAL; | 409 | return -EINVAL; |
637 | 410 | ||
@@ -642,7 +415,7 @@ static int gpio_irq_type(struct irq_data *d, unsigned type) | |||
642 | 415 | ||
643 | bank = irq_data_get_irq_chip_data(d); | 416 | bank = irq_data_get_irq_chip_data(d); |
644 | spin_lock_irqsave(&bank->lock, flags); | 417 | spin_lock_irqsave(&bank->lock, flags); |
645 | retval = _set_gpio_triggering(bank, get_gpio_index(gpio), type); | 418 | retval = _set_gpio_triggering(bank, GPIO_INDEX(bank, gpio), type); |
646 | spin_unlock_irqrestore(&bank->lock, flags); | 419 | spin_unlock_irqrestore(&bank->lock, flags); |
647 | 420 | ||
648 | if (type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_LEVEL_HIGH)) | 421 | if (type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_LEVEL_HIGH)) |
@@ -657,195 +430,81 @@ static void _clear_gpio_irqbank(struct gpio_bank *bank, int gpio_mask) | |||
657 | { | 430 | { |
658 | void __iomem *reg = bank->base; | 431 | void __iomem *reg = bank->base; |
659 | 432 | ||
660 | switch (bank->method) { | 433 | reg += bank->regs->irqstatus; |
661 | #ifdef CONFIG_ARCH_OMAP1 | ||
662 | case METHOD_MPUIO: | ||
663 | /* MPUIO irqstatus is reset by reading the status register, | ||
664 | * so do nothing here */ | ||
665 | return; | ||
666 | #endif | ||
667 | #ifdef CONFIG_ARCH_OMAP15XX | ||
668 | case METHOD_GPIO_1510: | ||
669 | reg += OMAP1510_GPIO_INT_STATUS; | ||
670 | break; | ||
671 | #endif | ||
672 | #ifdef CONFIG_ARCH_OMAP16XX | ||
673 | case METHOD_GPIO_1610: | ||
674 | reg += OMAP1610_GPIO_IRQSTATUS1; | ||
675 | break; | ||
676 | #endif | ||
677 | #if defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850) | ||
678 | case METHOD_GPIO_7XX: | ||
679 | reg += OMAP7XX_GPIO_INT_STATUS; | ||
680 | break; | ||
681 | #endif | ||
682 | #if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3) | ||
683 | case METHOD_GPIO_24XX: | ||
684 | reg += OMAP24XX_GPIO_IRQSTATUS1; | ||
685 | break; | ||
686 | #endif | ||
687 | #if defined(CONFIG_ARCH_OMAP4) | ||
688 | case METHOD_GPIO_44XX: | ||
689 | reg += OMAP4_GPIO_IRQSTATUS0; | ||
690 | break; | ||
691 | #endif | ||
692 | default: | ||
693 | WARN_ON(1); | ||
694 | return; | ||
695 | } | ||
696 | __raw_writel(gpio_mask, reg); | 434 | __raw_writel(gpio_mask, reg); |
697 | 435 | ||
698 | /* Workaround for clearing DSP GPIO interrupts to allow retention */ | 436 | /* Workaround for clearing DSP GPIO interrupts to allow retention */ |
699 | if (cpu_is_omap24xx() || cpu_is_omap34xx()) | 437 | if (bank->regs->irqstatus2) { |
700 | reg = bank->base + OMAP24XX_GPIO_IRQSTATUS2; | 438 | reg = bank->base + bank->regs->irqstatus2; |
701 | else if (cpu_is_omap44xx()) | ||
702 | reg = bank->base + OMAP4_GPIO_IRQSTATUS1; | ||
703 | |||
704 | if (cpu_is_omap24xx() || cpu_is_omap34xx() || cpu_is_omap44xx()) { | ||
705 | __raw_writel(gpio_mask, reg); | 439 | __raw_writel(gpio_mask, reg); |
440 | } | ||
706 | 441 | ||
707 | /* Flush posted write for the irq status to avoid spurious interrupts */ | 442 | /* Flush posted write for the irq status to avoid spurious interrupts */ |
708 | __raw_readl(reg); | 443 | __raw_readl(reg); |
709 | } | ||
710 | } | 444 | } |
711 | 445 | ||
712 | static inline void _clear_gpio_irqstatus(struct gpio_bank *bank, int gpio) | 446 | static inline void _clear_gpio_irqstatus(struct gpio_bank *bank, int gpio) |
713 | { | 447 | { |
714 | _clear_gpio_irqbank(bank, 1 << get_gpio_index(gpio)); | 448 | _clear_gpio_irqbank(bank, GPIO_BIT(bank, gpio)); |
715 | } | 449 | } |
716 | 450 | ||
717 | static u32 _get_gpio_irqbank_mask(struct gpio_bank *bank) | 451 | static u32 _get_gpio_irqbank_mask(struct gpio_bank *bank) |
718 | { | 452 | { |
719 | void __iomem *reg = bank->base; | 453 | void __iomem *reg = bank->base; |
720 | int inv = 0; | ||
721 | u32 l; | 454 | u32 l; |
722 | u32 mask; | 455 | u32 mask = (1 << bank->width) - 1; |
723 | |||
724 | switch (bank->method) { | ||
725 | #ifdef CONFIG_ARCH_OMAP1 | ||
726 | case METHOD_MPUIO: | ||
727 | reg += OMAP_MPUIO_GPIO_MASKIT / bank->stride; | ||
728 | mask = 0xffff; | ||
729 | inv = 1; | ||
730 | break; | ||
731 | #endif | ||
732 | #ifdef CONFIG_ARCH_OMAP15XX | ||
733 | case METHOD_GPIO_1510: | ||
734 | reg += OMAP1510_GPIO_INT_MASK; | ||
735 | mask = 0xffff; | ||
736 | inv = 1; | ||
737 | break; | ||
738 | #endif | ||
739 | #ifdef CONFIG_ARCH_OMAP16XX | ||
740 | case METHOD_GPIO_1610: | ||
741 | reg += OMAP1610_GPIO_IRQENABLE1; | ||
742 | mask = 0xffff; | ||
743 | break; | ||
744 | #endif | ||
745 | #if defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850) | ||
746 | case METHOD_GPIO_7XX: | ||
747 | reg += OMAP7XX_GPIO_INT_MASK; | ||
748 | mask = 0xffffffff; | ||
749 | inv = 1; | ||
750 | break; | ||
751 | #endif | ||
752 | #if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3) | ||
753 | case METHOD_GPIO_24XX: | ||
754 | reg += OMAP24XX_GPIO_IRQENABLE1; | ||
755 | mask = 0xffffffff; | ||
756 | break; | ||
757 | #endif | ||
758 | #if defined(CONFIG_ARCH_OMAP4) | ||
759 | case METHOD_GPIO_44XX: | ||
760 | reg += OMAP4_GPIO_IRQSTATUSSET0; | ||
761 | mask = 0xffffffff; | ||
762 | break; | ||
763 | #endif | ||
764 | default: | ||
765 | WARN_ON(1); | ||
766 | return 0; | ||
767 | } | ||
768 | 456 | ||
457 | reg += bank->regs->irqenable; | ||
769 | l = __raw_readl(reg); | 458 | l = __raw_readl(reg); |
770 | if (inv) | 459 | if (bank->regs->irqenable_inv) |
771 | l = ~l; | 460 | l = ~l; |
772 | l &= mask; | 461 | l &= mask; |
773 | return l; | 462 | return l; |
774 | } | 463 | } |
775 | 464 | ||
776 | static void _enable_gpio_irqbank(struct gpio_bank *bank, int gpio_mask, int enable) | 465 | static void _enable_gpio_irqbank(struct gpio_bank *bank, int gpio_mask) |
777 | { | 466 | { |
778 | void __iomem *reg = bank->base; | 467 | void __iomem *reg = bank->base; |
779 | u32 l; | 468 | u32 l; |
780 | 469 | ||
781 | switch (bank->method) { | 470 | if (bank->regs->set_irqenable) { |
782 | #ifdef CONFIG_ARCH_OMAP1 | 471 | reg += bank->regs->set_irqenable; |
783 | case METHOD_MPUIO: | 472 | l = gpio_mask; |
784 | reg += OMAP_MPUIO_GPIO_MASKIT / bank->stride; | 473 | } else { |
785 | l = __raw_readl(reg); | 474 | reg += bank->regs->irqenable; |
786 | if (enable) | ||
787 | l &= ~(gpio_mask); | ||
788 | else | ||
789 | l |= gpio_mask; | ||
790 | break; | ||
791 | #endif | ||
792 | #ifdef CONFIG_ARCH_OMAP15XX | ||
793 | case METHOD_GPIO_1510: | ||
794 | reg += OMAP1510_GPIO_INT_MASK; | ||
795 | l = __raw_readl(reg); | 475 | l = __raw_readl(reg); |
796 | if (enable) | 476 | if (bank->regs->irqenable_inv) |
797 | l &= ~(gpio_mask); | 477 | l &= ~gpio_mask; |
798 | else | 478 | else |
799 | l |= gpio_mask; | 479 | l |= gpio_mask; |
800 | break; | 480 | } |
801 | #endif | 481 | |
802 | #ifdef CONFIG_ARCH_OMAP16XX | 482 | __raw_writel(l, reg); |
803 | case METHOD_GPIO_1610: | 483 | } |
804 | if (enable) | 484 | |
805 | reg += OMAP1610_GPIO_SET_IRQENABLE1; | 485 | static void _disable_gpio_irqbank(struct gpio_bank *bank, int gpio_mask) |
806 | else | 486 | { |
807 | reg += OMAP1610_GPIO_CLEAR_IRQENABLE1; | 487 | void __iomem *reg = bank->base; |
488 | u32 l; | ||
489 | |||
490 | if (bank->regs->clr_irqenable) { | ||
491 | reg += bank->regs->clr_irqenable; | ||
808 | l = gpio_mask; | 492 | l = gpio_mask; |
809 | break; | 493 | } else { |
810 | #endif | 494 | reg += bank->regs->irqenable; |
811 | #if defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850) | ||
812 | case METHOD_GPIO_7XX: | ||
813 | reg += OMAP7XX_GPIO_INT_MASK; | ||
814 | l = __raw_readl(reg); | 495 | l = __raw_readl(reg); |
815 | if (enable) | 496 | if (bank->regs->irqenable_inv) |
816 | l &= ~(gpio_mask); | ||
817 | else | ||
818 | l |= gpio_mask; | 497 | l |= gpio_mask; |
819 | break; | ||
820 | #endif | ||
821 | #if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3) | ||
822 | case METHOD_GPIO_24XX: | ||
823 | if (enable) | ||
824 | reg += OMAP24XX_GPIO_SETIRQENABLE1; | ||
825 | else | ||
826 | reg += OMAP24XX_GPIO_CLEARIRQENABLE1; | ||
827 | l = gpio_mask; | ||
828 | break; | ||
829 | #endif | ||
830 | #ifdef CONFIG_ARCH_OMAP4 | ||
831 | case METHOD_GPIO_44XX: | ||
832 | if (enable) | ||
833 | reg += OMAP4_GPIO_IRQSTATUSSET0; | ||
834 | else | 498 | else |
835 | reg += OMAP4_GPIO_IRQSTATUSCLR0; | 499 | l &= ~gpio_mask; |
836 | l = gpio_mask; | ||
837 | break; | ||
838 | #endif | ||
839 | default: | ||
840 | WARN_ON(1); | ||
841 | return; | ||
842 | } | 500 | } |
501 | |||
843 | __raw_writel(l, reg); | 502 | __raw_writel(l, reg); |
844 | } | 503 | } |
845 | 504 | ||
846 | static inline void _set_gpio_irqenable(struct gpio_bank *bank, int gpio, int enable) | 505 | static inline void _set_gpio_irqenable(struct gpio_bank *bank, int gpio, int enable) |
847 | { | 506 | { |
848 | _enable_gpio_irqbank(bank, 1 << get_gpio_index(gpio), enable); | 507 | _enable_gpio_irqbank(bank, GPIO_BIT(bank, gpio)); |
849 | } | 508 | } |
850 | 509 | ||
851 | /* | 510 | /* |
@@ -858,50 +517,32 @@ static inline void _set_gpio_irqenable(struct gpio_bank *bank, int gpio, int ena | |||
858 | */ | 517 | */ |
859 | static int _set_gpio_wakeup(struct gpio_bank *bank, int gpio, int enable) | 518 | static int _set_gpio_wakeup(struct gpio_bank *bank, int gpio, int enable) |
860 | { | 519 | { |
861 | unsigned long uninitialized_var(flags); | 520 | u32 gpio_bit = GPIO_BIT(bank, gpio); |
521 | unsigned long flags; | ||
862 | 522 | ||
863 | switch (bank->method) { | 523 | if (bank->non_wakeup_gpios & gpio_bit) { |
864 | #ifdef CONFIG_ARCH_OMAP16XX | 524 | dev_err(bank->dev, |
865 | case METHOD_MPUIO: | 525 | "Unable to modify wakeup on non-wakeup GPIO%d\n", gpio); |
866 | case METHOD_GPIO_1610: | ||
867 | spin_lock_irqsave(&bank->lock, flags); | ||
868 | if (enable) | ||
869 | bank->suspend_wakeup |= (1 << gpio); | ||
870 | else | ||
871 | bank->suspend_wakeup &= ~(1 << gpio); | ||
872 | spin_unlock_irqrestore(&bank->lock, flags); | ||
873 | return 0; | ||
874 | #endif | ||
875 | #ifdef CONFIG_ARCH_OMAP2PLUS | ||
876 | case METHOD_GPIO_24XX: | ||
877 | case METHOD_GPIO_44XX: | ||
878 | if (bank->non_wakeup_gpios & (1 << gpio)) { | ||
879 | printk(KERN_ERR "Unable to modify wakeup on " | ||
880 | "non-wakeup GPIO%d\n", | ||
881 | (bank - gpio_bank) * 32 + gpio); | ||
882 | return -EINVAL; | ||
883 | } | ||
884 | spin_lock_irqsave(&bank->lock, flags); | ||
885 | if (enable) | ||
886 | bank->suspend_wakeup |= (1 << gpio); | ||
887 | else | ||
888 | bank->suspend_wakeup &= ~(1 << gpio); | ||
889 | spin_unlock_irqrestore(&bank->lock, flags); | ||
890 | return 0; | ||
891 | #endif | ||
892 | default: | ||
893 | printk(KERN_ERR "Can't enable GPIO wakeup for method %i\n", | ||
894 | bank->method); | ||
895 | return -EINVAL; | 526 | return -EINVAL; |
896 | } | 527 | } |
528 | |||
529 | spin_lock_irqsave(&bank->lock, flags); | ||
530 | if (enable) | ||
531 | bank->suspend_wakeup |= gpio_bit; | ||
532 | else | ||
533 | bank->suspend_wakeup &= ~gpio_bit; | ||
534 | |||
535 | spin_unlock_irqrestore(&bank->lock, flags); | ||
536 | |||
537 | return 0; | ||
897 | } | 538 | } |
898 | 539 | ||
899 | static void _reset_gpio(struct gpio_bank *bank, int gpio) | 540 | static void _reset_gpio(struct gpio_bank *bank, int gpio) |
900 | { | 541 | { |
901 | _set_gpio_direction(bank, get_gpio_index(gpio), 1); | 542 | _set_gpio_direction(bank, GPIO_INDEX(bank, gpio), 1); |
902 | _set_gpio_irqenable(bank, gpio, 0); | 543 | _set_gpio_irqenable(bank, gpio, 0); |
903 | _clear_gpio_irqstatus(bank, gpio); | 544 | _clear_gpio_irqstatus(bank, gpio); |
904 | _set_gpio_triggering(bank, get_gpio_index(gpio), IRQ_TYPE_NONE); | 545 | _set_gpio_triggering(bank, GPIO_INDEX(bank, gpio), IRQ_TYPE_NONE); |
905 | } | 546 | } |
906 | 547 | ||
907 | /* Use disable_irq_wake() and enable_irq_wake() functions from drivers */ | 548 | /* Use disable_irq_wake() and enable_irq_wake() functions from drivers */ |
@@ -911,10 +552,8 @@ static int gpio_wake_enable(struct irq_data *d, unsigned int enable) | |||
911 | struct gpio_bank *bank; | 552 | struct gpio_bank *bank; |
912 | int retval; | 553 | int retval; |
913 | 554 | ||
914 | if (check_gpio(gpio) < 0) | ||
915 | return -ENODEV; | ||
916 | bank = irq_data_get_irq_chip_data(d); | 555 | bank = irq_data_get_irq_chip_data(d); |
917 | retval = _set_gpio_wakeup(bank, get_gpio_index(gpio), enable); | 556 | retval = _set_gpio_wakeup(bank, gpio, enable); |
918 | 557 | ||
919 | return retval; | 558 | return retval; |
920 | } | 559 | } |
@@ -1030,31 +669,7 @@ static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc) | |||
1030 | chained_irq_enter(chip, desc); | 669 | chained_irq_enter(chip, desc); |
1031 | 670 | ||
1032 | bank = irq_get_handler_data(irq); | 671 | bank = irq_get_handler_data(irq); |
1033 | #ifdef CONFIG_ARCH_OMAP1 | 672 | isr_reg = bank->base + bank->regs->irqstatus; |
1034 | if (bank->method == METHOD_MPUIO) | ||
1035 | isr_reg = bank->base + | ||
1036 | OMAP_MPUIO_GPIO_INT / bank->stride; | ||
1037 | #endif | ||
1038 | #ifdef CONFIG_ARCH_OMAP15XX | ||
1039 | if (bank->method == METHOD_GPIO_1510) | ||
1040 | isr_reg = bank->base + OMAP1510_GPIO_INT_STATUS; | ||
1041 | #endif | ||
1042 | #if defined(CONFIG_ARCH_OMAP16XX) | ||
1043 | if (bank->method == METHOD_GPIO_1610) | ||
1044 | isr_reg = bank->base + OMAP1610_GPIO_IRQSTATUS1; | ||
1045 | #endif | ||
1046 | #if defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850) | ||
1047 | if (bank->method == METHOD_GPIO_7XX) | ||
1048 | isr_reg = bank->base + OMAP7XX_GPIO_INT_STATUS; | ||
1049 | #endif | ||
1050 | #if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3) | ||
1051 | if (bank->method == METHOD_GPIO_24XX) | ||
1052 | isr_reg = bank->base + OMAP24XX_GPIO_IRQSTATUS1; | ||
1053 | #endif | ||
1054 | #if defined(CONFIG_ARCH_OMAP4) | ||
1055 | if (bank->method == METHOD_GPIO_44XX) | ||
1056 | isr_reg = bank->base + OMAP4_GPIO_IRQSTATUS0; | ||
1057 | #endif | ||
1058 | 673 | ||
1059 | if (WARN_ON(!isr_reg)) | 674 | if (WARN_ON(!isr_reg)) |
1060 | goto exit; | 675 | goto exit; |
@@ -1076,9 +691,9 @@ static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc) | |||
1076 | /* clear edge sensitive interrupts before handler(s) are | 691 | /* clear edge sensitive interrupts before handler(s) are |
1077 | called so that we don't miss any interrupt occurred while | 692 | called so that we don't miss any interrupt occurred while |
1078 | executing them */ | 693 | executing them */ |
1079 | _enable_gpio_irqbank(bank, isr_saved & ~level_mask, 0); | 694 | _disable_gpio_irqbank(bank, isr_saved & ~level_mask); |
1080 | _clear_gpio_irqbank(bank, isr_saved & ~level_mask); | 695 | _clear_gpio_irqbank(bank, isr_saved & ~level_mask); |
1081 | _enable_gpio_irqbank(bank, isr_saved & ~level_mask, 1); | 696 | _enable_gpio_irqbank(bank, isr_saved & ~level_mask); |
1082 | 697 | ||
1083 | /* if there is only edge sensitive GPIO pin interrupts | 698 | /* if there is only edge sensitive GPIO pin interrupts |
1084 | configured, we could unmask GPIO bank interrupt immediately */ | 699 | configured, we could unmask GPIO bank interrupt immediately */ |
@@ -1094,7 +709,7 @@ static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc) | |||
1094 | 709 | ||
1095 | gpio_irq = bank->virtual_irq_start; | 710 | gpio_irq = bank->virtual_irq_start; |
1096 | for (; isr != 0; isr >>= 1, gpio_irq++) { | 711 | for (; isr != 0; isr >>= 1, gpio_irq++) { |
1097 | gpio_index = get_gpio_index(irq_to_gpio(gpio_irq)); | 712 | gpio_index = GPIO_INDEX(bank, irq_to_gpio(gpio_irq)); |
1098 | 713 | ||
1099 | if (!(isr & 1)) | 714 | if (!(isr & 1)) |
1100 | continue; | 715 | continue; |
@@ -1150,7 +765,7 @@ static void gpio_mask_irq(struct irq_data *d) | |||
1150 | 765 | ||
1151 | spin_lock_irqsave(&bank->lock, flags); | 766 | spin_lock_irqsave(&bank->lock, flags); |
1152 | _set_gpio_irqenable(bank, gpio, 0); | 767 | _set_gpio_irqenable(bank, gpio, 0); |
1153 | _set_gpio_triggering(bank, get_gpio_index(gpio), IRQ_TYPE_NONE); | 768 | _set_gpio_triggering(bank, GPIO_INDEX(bank, gpio), IRQ_TYPE_NONE); |
1154 | spin_unlock_irqrestore(&bank->lock, flags); | 769 | spin_unlock_irqrestore(&bank->lock, flags); |
1155 | } | 770 | } |
1156 | 771 | ||
@@ -1158,13 +773,13 @@ static void gpio_unmask_irq(struct irq_data *d) | |||
1158 | { | 773 | { |
1159 | unsigned int gpio = d->irq - IH_GPIO_BASE; | 774 | unsigned int gpio = d->irq - IH_GPIO_BASE; |
1160 | struct gpio_bank *bank = irq_data_get_irq_chip_data(d); | 775 | struct gpio_bank *bank = irq_data_get_irq_chip_data(d); |
1161 | unsigned int irq_mask = 1 << get_gpio_index(gpio); | 776 | unsigned int irq_mask = GPIO_BIT(bank, gpio); |
1162 | u32 trigger = irqd_get_trigger_type(d); | 777 | u32 trigger = irqd_get_trigger_type(d); |
1163 | unsigned long flags; | 778 | unsigned long flags; |
1164 | 779 | ||
1165 | spin_lock_irqsave(&bank->lock, flags); | 780 | spin_lock_irqsave(&bank->lock, flags); |
1166 | if (trigger) | 781 | if (trigger) |
1167 | _set_gpio_triggering(bank, get_gpio_index(gpio), trigger); | 782 | _set_gpio_triggering(bank, GPIO_INDEX(bank, gpio), trigger); |
1168 | 783 | ||
1169 | /* For level-triggered GPIOs, the clearing must be done after | 784 | /* For level-triggered GPIOs, the clearing must be done after |
1170 | * the HW source is cleared, thus after the handler has run */ | 785 | * the HW source is cleared, thus after the handler has run */ |
@@ -1191,45 +806,8 @@ static struct irq_chip gpio_irq_chip = { | |||
1191 | 806 | ||
1192 | #ifdef CONFIG_ARCH_OMAP1 | 807 | #ifdef CONFIG_ARCH_OMAP1 |
1193 | 808 | ||
1194 | /* MPUIO uses the always-on 32k clock */ | ||
1195 | |||
1196 | static void mpuio_ack_irq(struct irq_data *d) | ||
1197 | { | ||
1198 | /* The ISR is reset automatically, so do nothing here. */ | ||
1199 | } | ||
1200 | |||
1201 | static void mpuio_mask_irq(struct irq_data *d) | ||
1202 | { | ||
1203 | unsigned int gpio = OMAP_MPUIO(d->irq - IH_MPUIO_BASE); | ||
1204 | struct gpio_bank *bank = irq_data_get_irq_chip_data(d); | ||
1205 | |||
1206 | _set_gpio_irqenable(bank, gpio, 0); | ||
1207 | } | ||
1208 | |||
1209 | static void mpuio_unmask_irq(struct irq_data *d) | ||
1210 | { | ||
1211 | unsigned int gpio = OMAP_MPUIO(d->irq - IH_MPUIO_BASE); | ||
1212 | struct gpio_bank *bank = irq_data_get_irq_chip_data(d); | ||
1213 | |||
1214 | _set_gpio_irqenable(bank, gpio, 1); | ||
1215 | } | ||
1216 | |||
1217 | static struct irq_chip mpuio_irq_chip = { | ||
1218 | .name = "MPUIO", | ||
1219 | .irq_ack = mpuio_ack_irq, | ||
1220 | .irq_mask = mpuio_mask_irq, | ||
1221 | .irq_unmask = mpuio_unmask_irq, | ||
1222 | .irq_set_type = gpio_irq_type, | ||
1223 | #ifdef CONFIG_ARCH_OMAP16XX | ||
1224 | /* REVISIT: assuming only 16xx supports MPUIO wake events */ | ||
1225 | .irq_set_wake = gpio_wake_enable, | ||
1226 | #endif | ||
1227 | }; | ||
1228 | |||
1229 | |||
1230 | #define bank_is_mpuio(bank) ((bank)->method == METHOD_MPUIO) | 809 | #define bank_is_mpuio(bank) ((bank)->method == METHOD_MPUIO) |
1231 | 810 | ||
1232 | |||
1233 | #ifdef CONFIG_ARCH_OMAP16XX | 811 | #ifdef CONFIG_ARCH_OMAP16XX |
1234 | 812 | ||
1235 | #include <linux/platform_device.h> | 813 | #include <linux/platform_device.h> |
@@ -1289,7 +867,7 @@ static struct platform_device omap_mpuio_device = { | |||
1289 | 867 | ||
1290 | static inline void mpuio_init(void) | 868 | static inline void mpuio_init(void) |
1291 | { | 869 | { |
1292 | struct gpio_bank *bank = get_gpio_bank(OMAP_MPUIO(0)); | 870 | struct gpio_bank *bank = &gpio_bank[0]; |
1293 | platform_set_drvdata(&omap_mpuio_device, bank); | 871 | platform_set_drvdata(&omap_mpuio_device, bank); |
1294 | 872 | ||
1295 | if (platform_driver_register(&omap_mpuio_driver) == 0) | 873 | if (platform_driver_register(&omap_mpuio_driver) == 0) |
@@ -1302,8 +880,6 @@ static inline void mpuio_init(void) {} | |||
1302 | 880 | ||
1303 | #else | 881 | #else |
1304 | 882 | ||
1305 | extern struct irq_chip mpuio_irq_chip; | ||
1306 | |||
1307 | #define bank_is_mpuio(bank) 0 | 883 | #define bank_is_mpuio(bank) 0 |
1308 | static inline void mpuio_init(void) {} | 884 | static inline void mpuio_init(void) {} |
1309 | 885 | ||
@@ -1329,31 +905,8 @@ static int gpio_input(struct gpio_chip *chip, unsigned offset) | |||
1329 | 905 | ||
1330 | static int gpio_is_input(struct gpio_bank *bank, int mask) | 906 | static int gpio_is_input(struct gpio_bank *bank, int mask) |
1331 | { | 907 | { |
1332 | void __iomem *reg = bank->base; | 908 | void __iomem *reg = bank->base + bank->regs->direction; |
1333 | 909 | ||
1334 | switch (bank->method) { | ||
1335 | case METHOD_MPUIO: | ||
1336 | reg += OMAP_MPUIO_IO_CNTL / bank->stride; | ||
1337 | break; | ||
1338 | case METHOD_GPIO_1510: | ||
1339 | reg += OMAP1510_GPIO_DIR_CONTROL; | ||
1340 | break; | ||
1341 | case METHOD_GPIO_1610: | ||
1342 | reg += OMAP1610_GPIO_DIRECTION; | ||
1343 | break; | ||
1344 | case METHOD_GPIO_7XX: | ||
1345 | reg += OMAP7XX_GPIO_DIR_CONTROL; | ||
1346 | break; | ||
1347 | case METHOD_GPIO_24XX: | ||
1348 | reg += OMAP24XX_GPIO_OE; | ||
1349 | break; | ||
1350 | case METHOD_GPIO_44XX: | ||
1351 | reg += OMAP4_GPIO_OE; | ||
1352 | break; | ||
1353 | default: | ||
1354 | WARN_ONCE(1, "gpio_is_input: incorrect OMAP GPIO method"); | ||
1355 | return -EINVAL; | ||
1356 | } | ||
1357 | return __raw_readl(reg) & mask; | 910 | return __raw_readl(reg) & mask; |
1358 | } | 911 | } |
1359 | 912 | ||
@@ -1365,9 +918,9 @@ static int gpio_get(struct gpio_chip *chip, unsigned offset) | |||
1365 | u32 mask; | 918 | u32 mask; |
1366 | 919 | ||
1367 | gpio = chip->base + offset; | 920 | gpio = chip->base + offset; |
1368 | bank = get_gpio_bank(gpio); | 921 | bank = container_of(chip, struct gpio_bank, chip); |
1369 | reg = bank->base; | 922 | reg = bank->base; |
1370 | mask = 1 << get_gpio_index(gpio); | 923 | mask = GPIO_BIT(bank, gpio); |
1371 | 924 | ||
1372 | if (gpio_is_input(bank, mask)) | 925 | if (gpio_is_input(bank, mask)) |
1373 | return _get_gpio_datain(bank, gpio); | 926 | return _get_gpio_datain(bank, gpio); |
@@ -1382,7 +935,7 @@ static int gpio_output(struct gpio_chip *chip, unsigned offset, int value) | |||
1382 | 935 | ||
1383 | bank = container_of(chip, struct gpio_bank, chip); | 936 | bank = container_of(chip, struct gpio_bank, chip); |
1384 | spin_lock_irqsave(&bank->lock, flags); | 937 | spin_lock_irqsave(&bank->lock, flags); |
1385 | _set_gpio_dataout(bank, offset, value); | 938 | bank->set_dataout(bank, offset, value); |
1386 | _set_gpio_direction(bank, offset, 0); | 939 | _set_gpio_direction(bank, offset, 0); |
1387 | spin_unlock_irqrestore(&bank->lock, flags); | 940 | spin_unlock_irqrestore(&bank->lock, flags); |
1388 | return 0; | 941 | return 0; |
@@ -1416,7 +969,7 @@ static void gpio_set(struct gpio_chip *chip, unsigned offset, int value) | |||
1416 | 969 | ||
1417 | bank = container_of(chip, struct gpio_bank, chip); | 970 | bank = container_of(chip, struct gpio_bank, chip); |
1418 | spin_lock_irqsave(&bank->lock, flags); | 971 | spin_lock_irqsave(&bank->lock, flags); |
1419 | _set_gpio_dataout(bank, offset, value); | 972 | bank->set_dataout(bank, offset, value); |
1420 | spin_unlock_irqrestore(&bank->lock, flags); | 973 | spin_unlock_irqrestore(&bank->lock, flags); |
1421 | } | 974 | } |
1422 | 975 | ||
@@ -1432,19 +985,17 @@ static int gpio_2irq(struct gpio_chip *chip, unsigned offset) | |||
1432 | 985 | ||
1433 | static void __init omap_gpio_show_rev(struct gpio_bank *bank) | 986 | static void __init omap_gpio_show_rev(struct gpio_bank *bank) |
1434 | { | 987 | { |
988 | static bool called; | ||
1435 | u32 rev; | 989 | u32 rev; |
1436 | 990 | ||
1437 | if (cpu_is_omap16xx() && !(bank->method != METHOD_MPUIO)) | 991 | if (called || bank->regs->revision == USHRT_MAX) |
1438 | rev = __raw_readw(bank->base + OMAP1610_GPIO_REVISION); | ||
1439 | else if (cpu_is_omap24xx() || cpu_is_omap34xx()) | ||
1440 | rev = __raw_readl(bank->base + OMAP24XX_GPIO_REVISION); | ||
1441 | else if (cpu_is_omap44xx()) | ||
1442 | rev = __raw_readl(bank->base + OMAP4_GPIO_REVISION); | ||
1443 | else | ||
1444 | return; | 992 | return; |
1445 | 993 | ||
1446 | printk(KERN_INFO "OMAP GPIO hardware version %d.%d\n", | 994 | rev = __raw_readw(bank->base + bank->regs->revision); |
995 | pr_info("OMAP GPIO hardware version %d.%d\n", | ||
1447 | (rev >> 4) & 0x0f, rev & 0x0f); | 996 | (rev >> 4) & 0x0f, rev & 0x0f); |
997 | |||
998 | called = true; | ||
1448 | } | 999 | } |
1449 | 1000 | ||
1450 | /* This lock class tells lockdep that GPIO irqs are in a different | 1001 | /* This lock class tells lockdep that GPIO irqs are in a different |
@@ -1526,6 +1077,30 @@ static void omap_gpio_mod_init(struct gpio_bank *bank, int id) | |||
1526 | } | 1077 | } |
1527 | } | 1078 | } |
1528 | 1079 | ||
1080 | static __init void | ||
1081 | omap_mpuio_alloc_gc(struct gpio_bank *bank, unsigned int irq_start, | ||
1082 | unsigned int num) | ||
1083 | { | ||
1084 | struct irq_chip_generic *gc; | ||
1085 | struct irq_chip_type *ct; | ||
1086 | |||
1087 | gc = irq_alloc_generic_chip("MPUIO", 1, irq_start, bank->base, | ||
1088 | handle_simple_irq); | ||
1089 | ct = gc->chip_types; | ||
1090 | |||
1091 | /* NOTE: No ack required, reading IRQ status clears it. */ | ||
1092 | ct->chip.irq_mask = irq_gc_mask_set_bit; | ||
1093 | ct->chip.irq_unmask = irq_gc_mask_clr_bit; | ||
1094 | ct->chip.irq_set_type = gpio_irq_type; | ||
1095 | /* REVISIT: assuming only 16xx supports MPUIO wake events */ | ||
1096 | if (cpu_is_omap16xx()) | ||
1097 | ct->chip.irq_set_wake = gpio_wake_enable, | ||
1098 | |||
1099 | ct->regs.mask = OMAP_MPUIO_GPIO_INT / bank->stride; | ||
1100 | irq_setup_generic_chip(gc, IRQ_MSK(num), IRQ_GC_INIT_MASK_CACHE, | ||
1101 | IRQ_NOREQUEST | IRQ_NOPROBE, 0); | ||
1102 | } | ||
1103 | |||
1529 | static void __devinit omap_gpio_chip_init(struct gpio_bank *bank) | 1104 | static void __devinit omap_gpio_chip_init(struct gpio_bank *bank) |
1530 | { | 1105 | { |
1531 | int j; | 1106 | int j; |
@@ -1553,22 +1128,23 @@ static void __devinit omap_gpio_chip_init(struct gpio_bank *bank) | |||
1553 | } else { | 1128 | } else { |
1554 | bank->chip.label = "gpio"; | 1129 | bank->chip.label = "gpio"; |
1555 | bank->chip.base = gpio; | 1130 | bank->chip.base = gpio; |
1556 | gpio += bank_width; | 1131 | gpio += bank->width; |
1557 | } | 1132 | } |
1558 | bank->chip.ngpio = bank_width; | 1133 | bank->chip.ngpio = bank->width; |
1559 | 1134 | ||
1560 | gpiochip_add(&bank->chip); | 1135 | gpiochip_add(&bank->chip); |
1561 | 1136 | ||
1562 | for (j = bank->virtual_irq_start; | 1137 | for (j = bank->virtual_irq_start; |
1563 | j < bank->virtual_irq_start + bank_width; j++) { | 1138 | j < bank->virtual_irq_start + bank->width; j++) { |
1564 | irq_set_lockdep_class(j, &gpio_lock_class); | 1139 | irq_set_lockdep_class(j, &gpio_lock_class); |
1565 | irq_set_chip_data(j, bank); | 1140 | irq_set_chip_data(j, bank); |
1566 | if (bank_is_mpuio(bank)) | 1141 | if (bank_is_mpuio(bank)) { |
1567 | irq_set_chip(j, &mpuio_irq_chip); | 1142 | omap_mpuio_alloc_gc(bank, j, bank->width); |
1568 | else | 1143 | } else { |
1569 | irq_set_chip(j, &gpio_irq_chip); | 1144 | irq_set_chip(j, &gpio_irq_chip); |
1570 | irq_set_handler(j, handle_simple_irq); | 1145 | irq_set_handler(j, handle_simple_irq); |
1571 | set_irq_flags(j, IRQF_VALID); | 1146 | set_irq_flags(j, IRQF_VALID); |
1147 | } | ||
1572 | } | 1148 | } |
1573 | irq_set_chained_handler(bank->irq, gpio_irq_handler); | 1149 | irq_set_chained_handler(bank->irq, gpio_irq_handler); |
1574 | irq_set_handler_data(bank->irq, bank); | 1150 | irq_set_handler_data(bank->irq, bank); |
@@ -1610,7 +1186,14 @@ static int __devinit omap_gpio_probe(struct platform_device *pdev) | |||
1610 | bank->dev = &pdev->dev; | 1186 | bank->dev = &pdev->dev; |
1611 | bank->dbck_flag = pdata->dbck_flag; | 1187 | bank->dbck_flag = pdata->dbck_flag; |
1612 | bank->stride = pdata->bank_stride; | 1188 | bank->stride = pdata->bank_stride; |
1613 | bank_width = pdata->bank_width; | 1189 | bank->width = pdata->bank_width; |
1190 | |||
1191 | bank->regs = pdata->regs; | ||
1192 | |||
1193 | if (bank->regs->set_dataout && bank->regs->clr_dataout) | ||
1194 | bank->set_dataout = _set_gpio_dataout_reg; | ||
1195 | else | ||
1196 | bank->set_dataout = _set_gpio_dataout_mask; | ||
1614 | 1197 | ||
1615 | spin_lock_init(&bank->lock); | 1198 | spin_lock_init(&bank->lock); |
1616 | 1199 | ||
diff --git a/drivers/gpio/pca953x.c b/drivers/gpio/gpio-pca953x.c index 0451d7ac94ac..c43b8ff626a7 100644 --- a/drivers/gpio/pca953x.c +++ b/drivers/gpio/gpio-pca953x.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * pca953x.c - 4/8/16 bit I/O ports | 2 | * PCA953x 4/8/16 bit I/O ports |
3 | * | 3 | * |
4 | * Copyright (C) 2005 Ben Gardner <bgardner@wabtec.com> | 4 | * Copyright (C) 2005 Ben Gardner <bgardner@wabtec.com> |
5 | * Copyright (C) 2007 Marvell International Ltd. | 5 | * Copyright (C) 2007 Marvell International Ltd. |
@@ -21,7 +21,6 @@ | |||
21 | #include <linux/slab.h> | 21 | #include <linux/slab.h> |
22 | #ifdef CONFIG_OF_GPIO | 22 | #ifdef CONFIG_OF_GPIO |
23 | #include <linux/of_platform.h> | 23 | #include <linux/of_platform.h> |
24 | #include <linux/of_gpio.h> | ||
25 | #endif | 24 | #endif |
26 | 25 | ||
27 | #define PCA953X_INPUT 0 | 26 | #define PCA953X_INPUT 0 |
@@ -85,7 +84,6 @@ struct pca953x_chip { | |||
85 | #endif | 84 | #endif |
86 | 85 | ||
87 | struct i2c_client *client; | 86 | struct i2c_client *client; |
88 | struct pca953x_platform_data *dyn_pdata; | ||
89 | struct gpio_chip gpio_chip; | 87 | struct gpio_chip gpio_chip; |
90 | const char *const *names; | 88 | const char *const *names; |
91 | int chip_type; | 89 | int chip_type; |
@@ -437,7 +435,7 @@ static irqreturn_t pca953x_irq_handler(int irq, void *devid) | |||
437 | 435 | ||
438 | do { | 436 | do { |
439 | level = __ffs(pending); | 437 | level = __ffs(pending); |
440 | generic_handle_irq(level + chip->irq_base); | 438 | handle_nested_irq(level + chip->irq_base); |
441 | 439 | ||
442 | pending &= ~(1 << level); | 440 | pending &= ~(1 << level); |
443 | } while (pending); | 441 | } while (pending); |
@@ -446,13 +444,13 @@ static irqreturn_t pca953x_irq_handler(int irq, void *devid) | |||
446 | } | 444 | } |
447 | 445 | ||
448 | static int pca953x_irq_setup(struct pca953x_chip *chip, | 446 | static int pca953x_irq_setup(struct pca953x_chip *chip, |
449 | const struct i2c_device_id *id) | 447 | const struct i2c_device_id *id, |
448 | int irq_base) | ||
450 | { | 449 | { |
451 | struct i2c_client *client = chip->client; | 450 | struct i2c_client *client = chip->client; |
452 | struct pca953x_platform_data *pdata = client->dev.platform_data; | ||
453 | int ret, offset = 0; | 451 | int ret, offset = 0; |
454 | 452 | ||
455 | if (pdata->irq_base != -1 | 453 | if (irq_base != -1 |
456 | && (id->driver_data & PCA_INT)) { | 454 | && (id->driver_data & PCA_INT)) { |
457 | int lvl; | 455 | int lvl; |
458 | 456 | ||
@@ -474,15 +472,19 @@ static int pca953x_irq_setup(struct pca953x_chip *chip, | |||
474 | * this purpose. | 472 | * this purpose. |
475 | */ | 473 | */ |
476 | chip->irq_stat &= chip->reg_direction; | 474 | chip->irq_stat &= chip->reg_direction; |
477 | chip->irq_base = pdata->irq_base; | ||
478 | mutex_init(&chip->irq_lock); | 475 | mutex_init(&chip->irq_lock); |
479 | 476 | ||
477 | chip->irq_base = irq_alloc_descs(-1, irq_base, chip->gpio_chip.ngpio, -1); | ||
478 | if (chip->irq_base < 0) | ||
479 | goto out_failed; | ||
480 | |||
480 | for (lvl = 0; lvl < chip->gpio_chip.ngpio; lvl++) { | 481 | for (lvl = 0; lvl < chip->gpio_chip.ngpio; lvl++) { |
481 | int irq = lvl + chip->irq_base; | 482 | int irq = lvl + chip->irq_base; |
482 | 483 | ||
484 | irq_clear_status_flags(irq, IRQ_NOREQUEST); | ||
483 | irq_set_chip_data(irq, chip); | 485 | irq_set_chip_data(irq, chip); |
484 | irq_set_chip_and_handler(irq, &pca953x_irq_chip, | 486 | irq_set_chip(irq, &pca953x_irq_chip); |
485 | handle_simple_irq); | 487 | irq_set_nested_thread(irq, true); |
486 | #ifdef CONFIG_ARM | 488 | #ifdef CONFIG_ARM |
487 | set_irq_flags(irq, IRQF_VALID); | 489 | set_irq_flags(irq, IRQF_VALID); |
488 | #else | 490 | #else |
@@ -493,8 +495,7 @@ static int pca953x_irq_setup(struct pca953x_chip *chip, | |||
493 | ret = request_threaded_irq(client->irq, | 495 | ret = request_threaded_irq(client->irq, |
494 | NULL, | 496 | NULL, |
495 | pca953x_irq_handler, | 497 | pca953x_irq_handler, |
496 | IRQF_TRIGGER_RISING | | 498 | IRQF_TRIGGER_LOW | IRQF_ONESHOT, |
497 | IRQF_TRIGGER_FALLING | IRQF_ONESHOT, | ||
498 | dev_name(&client->dev), chip); | 499 | dev_name(&client->dev), chip); |
499 | if (ret) { | 500 | if (ret) { |
500 | dev_err(&client->dev, "failed to request irq %d\n", | 501 | dev_err(&client->dev, "failed to request irq %d\n", |
@@ -514,17 +515,19 @@ out_failed: | |||
514 | 515 | ||
515 | static void pca953x_irq_teardown(struct pca953x_chip *chip) | 516 | static void pca953x_irq_teardown(struct pca953x_chip *chip) |
516 | { | 517 | { |
517 | if (chip->irq_base != -1) | 518 | if (chip->irq_base != -1) { |
519 | irq_free_descs(chip->irq_base, chip->gpio_chip.ngpio); | ||
518 | free_irq(chip->client->irq, chip); | 520 | free_irq(chip->client->irq, chip); |
521 | } | ||
519 | } | 522 | } |
520 | #else /* CONFIG_GPIO_PCA953X_IRQ */ | 523 | #else /* CONFIG_GPIO_PCA953X_IRQ */ |
521 | static int pca953x_irq_setup(struct pca953x_chip *chip, | 524 | static int pca953x_irq_setup(struct pca953x_chip *chip, |
522 | const struct i2c_device_id *id) | 525 | const struct i2c_device_id *id, |
526 | int irq_base) | ||
523 | { | 527 | { |
524 | struct i2c_client *client = chip->client; | 528 | struct i2c_client *client = chip->client; |
525 | struct pca953x_platform_data *pdata = client->dev.platform_data; | ||
526 | 529 | ||
527 | if (pdata->irq_base != -1 && (id->driver_data & PCA_INT)) | 530 | if (irq_base != -1 && (id->driver_data & PCA_INT)) |
528 | dev_warn(&client->dev, "interrupt support not compiled in\n"); | 531 | dev_warn(&client->dev, "interrupt support not compiled in\n"); |
529 | 532 | ||
530 | return 0; | 533 | return 0; |
@@ -541,46 +544,39 @@ static void pca953x_irq_teardown(struct pca953x_chip *chip) | |||
541 | #ifdef CONFIG_OF_GPIO | 544 | #ifdef CONFIG_OF_GPIO |
542 | /* | 545 | /* |
543 | * Translate OpenFirmware node properties into platform_data | 546 | * Translate OpenFirmware node properties into platform_data |
547 | * WARNING: This is DEPRECATED and will be removed eventually! | ||
544 | */ | 548 | */ |
545 | static struct pca953x_platform_data * | 549 | void |
546 | pca953x_get_alt_pdata(struct i2c_client *client) | 550 | pca953x_get_alt_pdata(struct i2c_client *client, int *gpio_base, int *invert) |
547 | { | 551 | { |
548 | struct pca953x_platform_data *pdata; | ||
549 | struct device_node *node; | 552 | struct device_node *node; |
550 | const __be32 *val; | 553 | const __be32 *val; |
551 | int size; | 554 | int size; |
552 | 555 | ||
553 | node = client->dev.of_node; | 556 | node = client->dev.of_node; |
554 | if (node == NULL) | 557 | if (node == NULL) |
555 | return NULL; | 558 | return; |
556 | |||
557 | pdata = kzalloc(sizeof(struct pca953x_platform_data), GFP_KERNEL); | ||
558 | if (pdata == NULL) { | ||
559 | dev_err(&client->dev, "Unable to allocate platform_data\n"); | ||
560 | return NULL; | ||
561 | } | ||
562 | 559 | ||
563 | pdata->gpio_base = -1; | 560 | *gpio_base = -1; |
564 | val = of_get_property(node, "linux,gpio-base", &size); | 561 | val = of_get_property(node, "linux,gpio-base", &size); |
562 | WARN(val, "%s: device-tree property 'linux,gpio-base' is deprecated!", __func__); | ||
565 | if (val) { | 563 | if (val) { |
566 | if (size != sizeof(*val)) | 564 | if (size != sizeof(*val)) |
567 | dev_warn(&client->dev, "%s: wrong linux,gpio-base\n", | 565 | dev_warn(&client->dev, "%s: wrong linux,gpio-base\n", |
568 | node->full_name); | 566 | node->full_name); |
569 | else | 567 | else |
570 | pdata->gpio_base = be32_to_cpup(val); | 568 | *gpio_base = be32_to_cpup(val); |
571 | } | 569 | } |
572 | 570 | ||
573 | val = of_get_property(node, "polarity", NULL); | 571 | val = of_get_property(node, "polarity", NULL); |
572 | WARN(val, "%s: device-tree property 'polarity' is deprecated!", __func__); | ||
574 | if (val) | 573 | if (val) |
575 | pdata->invert = *val; | 574 | *invert = *val; |
576 | |||
577 | return pdata; | ||
578 | } | 575 | } |
579 | #else | 576 | #else |
580 | static struct pca953x_platform_data * | 577 | void |
581 | pca953x_get_alt_pdata(struct i2c_client *client) | 578 | pca953x_get_alt_pdata(struct i2c_client *client, int *gpio_base, int *invert) |
582 | { | 579 | { |
583 | return NULL; | ||
584 | } | 580 | } |
585 | #endif | 581 | #endif |
586 | 582 | ||
@@ -642,6 +638,7 @@ static int __devinit pca953x_probe(struct i2c_client *client, | |||
642 | { | 638 | { |
643 | struct pca953x_platform_data *pdata; | 639 | struct pca953x_platform_data *pdata; |
644 | struct pca953x_chip *chip; | 640 | struct pca953x_chip *chip; |
641 | int irq_base=0, invert=0; | ||
645 | int ret = 0; | 642 | int ret = 0; |
646 | 643 | ||
647 | chip = kzalloc(sizeof(struct pca953x_chip), GFP_KERNEL); | 644 | chip = kzalloc(sizeof(struct pca953x_chip), GFP_KERNEL); |
@@ -649,26 +646,22 @@ static int __devinit pca953x_probe(struct i2c_client *client, | |||
649 | return -ENOMEM; | 646 | return -ENOMEM; |
650 | 647 | ||
651 | pdata = client->dev.platform_data; | 648 | pdata = client->dev.platform_data; |
652 | if (pdata == NULL) { | 649 | if (pdata) { |
653 | pdata = pca953x_get_alt_pdata(client); | 650 | irq_base = pdata->irq_base; |
654 | /* | 651 | chip->gpio_start = pdata->gpio_base; |
655 | * Unlike normal platform_data, this is allocated | 652 | invert = pdata->invert; |
656 | * dynamically and must be freed in the driver | 653 | chip->names = pdata->names; |
657 | */ | 654 | } else { |
658 | chip->dyn_pdata = pdata; | 655 | pca953x_get_alt_pdata(client, &chip->gpio_start, &invert); |
659 | } | 656 | #ifdef CONFIG_OF_GPIO |
660 | 657 | /* If I2C node has no interrupts property, disable GPIO interrupts */ | |
661 | if (pdata == NULL) { | 658 | if (of_find_property(client->dev.of_node, "interrupts", NULL) == NULL) |
662 | dev_dbg(&client->dev, "no platform data\n"); | 659 | irq_base = -1; |
663 | ret = -EINVAL; | 660 | #endif |
664 | goto out_failed; | ||
665 | } | 661 | } |
666 | 662 | ||
667 | chip->client = client; | 663 | chip->client = client; |
668 | 664 | ||
669 | chip->gpio_start = pdata->gpio_base; | ||
670 | |||
671 | chip->names = pdata->names; | ||
672 | chip->chip_type = id->driver_data & (PCA953X_TYPE | PCA957X_TYPE); | 665 | chip->chip_type = id->driver_data & (PCA953X_TYPE | PCA957X_TYPE); |
673 | 666 | ||
674 | mutex_init(&chip->i2c_lock); | 667 | mutex_init(&chip->i2c_lock); |
@@ -679,13 +672,13 @@ static int __devinit pca953x_probe(struct i2c_client *client, | |||
679 | pca953x_setup_gpio(chip, id->driver_data & PCA_GPIO_MASK); | 672 | pca953x_setup_gpio(chip, id->driver_data & PCA_GPIO_MASK); |
680 | 673 | ||
681 | if (chip->chip_type == PCA953X_TYPE) | 674 | if (chip->chip_type == PCA953X_TYPE) |
682 | device_pca953x_init(chip, pdata->invert); | 675 | device_pca953x_init(chip, invert); |
683 | else if (chip->chip_type == PCA957X_TYPE) | 676 | else if (chip->chip_type == PCA957X_TYPE) |
684 | device_pca957x_init(chip, pdata->invert); | 677 | device_pca957x_init(chip, invert); |
685 | else | 678 | else |
686 | goto out_failed; | 679 | goto out_failed; |
687 | 680 | ||
688 | ret = pca953x_irq_setup(chip, id); | 681 | ret = pca953x_irq_setup(chip, id, irq_base); |
689 | if (ret) | 682 | if (ret) |
690 | goto out_failed; | 683 | goto out_failed; |
691 | 684 | ||
@@ -693,7 +686,7 @@ static int __devinit pca953x_probe(struct i2c_client *client, | |||
693 | if (ret) | 686 | if (ret) |
694 | goto out_failed_irq; | 687 | goto out_failed_irq; |
695 | 688 | ||
696 | if (pdata->setup) { | 689 | if (pdata && pdata->setup) { |
697 | ret = pdata->setup(client, chip->gpio_chip.base, | 690 | ret = pdata->setup(client, chip->gpio_chip.base, |
698 | chip->gpio_chip.ngpio, pdata->context); | 691 | chip->gpio_chip.ngpio, pdata->context); |
699 | if (ret < 0) | 692 | if (ret < 0) |
@@ -706,7 +699,6 @@ static int __devinit pca953x_probe(struct i2c_client *client, | |||
706 | out_failed_irq: | 699 | out_failed_irq: |
707 | pca953x_irq_teardown(chip); | 700 | pca953x_irq_teardown(chip); |
708 | out_failed: | 701 | out_failed: |
709 | kfree(chip->dyn_pdata); | ||
710 | kfree(chip); | 702 | kfree(chip); |
711 | return ret; | 703 | return ret; |
712 | } | 704 | } |
@@ -717,7 +709,7 @@ static int pca953x_remove(struct i2c_client *client) | |||
717 | struct pca953x_chip *chip = i2c_get_clientdata(client); | 709 | struct pca953x_chip *chip = i2c_get_clientdata(client); |
718 | int ret = 0; | 710 | int ret = 0; |
719 | 711 | ||
720 | if (pdata->teardown) { | 712 | if (pdata && pdata->teardown) { |
721 | ret = pdata->teardown(client, chip->gpio_chip.base, | 713 | ret = pdata->teardown(client, chip->gpio_chip.base, |
722 | chip->gpio_chip.ngpio, pdata->context); | 714 | chip->gpio_chip.ngpio, pdata->context); |
723 | if (ret < 0) { | 715 | if (ret < 0) { |
@@ -735,7 +727,6 @@ static int pca953x_remove(struct i2c_client *client) | |||
735 | } | 727 | } |
736 | 728 | ||
737 | pca953x_irq_teardown(chip); | 729 | pca953x_irq_teardown(chip); |
738 | kfree(chip->dyn_pdata); | ||
739 | kfree(chip); | 730 | kfree(chip); |
740 | return 0; | 731 | return 0; |
741 | } | 732 | } |
diff --git a/drivers/gpio/pcf857x.c b/drivers/gpio/gpio-pcf857x.c index 879b473aab5a..7369fdda92b0 100644 --- a/drivers/gpio/pcf857x.c +++ b/drivers/gpio/gpio-pcf857x.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * pcf857x - driver for pcf857x, pca857x, and pca967x I2C GPIO expanders | 2 | * Driver for pcf857x, pca857x, and pca967x I2C GPIO expanders |
3 | * | 3 | * |
4 | * Copyright (C) 2007 David Brownell | 4 | * Copyright (C) 2007 David Brownell |
5 | * | 5 | * |
diff --git a/drivers/gpio/pch_gpio.c b/drivers/gpio/gpio-pch.c index 36919e77c495..36919e77c495 100644 --- a/drivers/gpio/pch_gpio.c +++ b/drivers/gpio/gpio-pch.c | |||
diff --git a/drivers/gpio/pl061.c b/drivers/gpio/gpio-pl061.c index 6fcb28cdd862..2c5a18f32bf3 100644 --- a/drivers/gpio/pl061.c +++ b/drivers/gpio/gpio-pl061.c | |||
@@ -1,7 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * linux/drivers/gpio/pl061.c | 2 | * Copyright (C) 2008, 2009 Provigent Ltd. |
3 | * | ||
4 | * Copyright (C) 2008, 2009 Provigent Ltd. | ||
5 | * | 3 | * |
6 | * This program is free software; you can redistribute it and/or modify | 4 | * This program is free software; you can redistribute it and/or modify |
7 | * it under the terms of the GNU General Public License version 2 as | 5 | * it under the terms of the GNU General Public License version 2 as |
diff --git a/drivers/gpio/gpio-plat-samsung.c b/drivers/gpio/gpio-plat-samsung.c index ea37c0461788..ef67f1952a72 100644 --- a/drivers/gpio/gpio-plat-samsung.c +++ b/drivers/gpio/gpio-plat-samsung.c | |||
@@ -1,5 +1,4 @@ | |||
1 | /* arch/arm/plat-samsung/gpiolib.c | 1 | /* |
2 | * | ||
3 | * Copyright 2008 Openmoko, Inc. | 2 | * Copyright 2008 Openmoko, Inc. |
4 | * Copyright 2008 Simtec Electronics | 3 | * Copyright 2008 Simtec Electronics |
5 | * Ben Dooks <ben@simtec.co.uk> | 4 | * Ben Dooks <ben@simtec.co.uk> |
diff --git a/drivers/gpio/rdc321x-gpio.c b/drivers/gpio/gpio-rdc321x.c index 2762698e0204..2762698e0204 100644 --- a/drivers/gpio/rdc321x-gpio.c +++ b/drivers/gpio/gpio-rdc321x.c | |||
diff --git a/drivers/gpio/gpio-s5pc100.c b/drivers/gpio/gpio-s5pc100.c index 2842394b28b5..7f87b0c76e0b 100644 --- a/drivers/gpio/gpio-s5pc100.c +++ b/drivers/gpio/gpio-s5pc100.c | |||
@@ -1,4 +1,5 @@ | |||
1 | /* linux/arch/arm/mach-s5pc100/gpiolib.c | 1 | /* |
2 | * S5PC100 - GPIOlib support | ||
2 | * | 3 | * |
3 | * Copyright (c) 2010 Samsung Electronics Co., Ltd. | 4 | * Copyright (c) 2010 Samsung Electronics Co., Ltd. |
4 | * http://www.samsung.com | 5 | * http://www.samsung.com |
@@ -6,8 +7,6 @@ | |||
6 | * Copyright 2009 Samsung Electronics Co | 7 | * Copyright 2009 Samsung Electronics Co |
7 | * Kyungmin Park <kyungmin.park@samsung.com> | 8 | * Kyungmin Park <kyungmin.park@samsung.com> |
8 | * | 9 | * |
9 | * S5PC100 - GPIOlib support | ||
10 | * | ||
11 | * This program is free software; you can redistribute it and/or modify | 10 | * This program is free software; you can redistribute it and/or modify |
12 | * it under the terms of the GNU General Public License version 2 as | 11 | * it under the terms of the GNU General Public License version 2 as |
13 | * published by the Free Software Foundation. | 12 | * published by the Free Software Foundation. |
diff --git a/drivers/gpio/gpio-s5pv210.c b/drivers/gpio/gpio-s5pv210.c index 1ba20a703e05..eb12f1602de9 100644 --- a/drivers/gpio/gpio-s5pv210.c +++ b/drivers/gpio/gpio-s5pv210.c | |||
@@ -1,10 +1,9 @@ | |||
1 | /* linux/arch/arm/mach-s5pv210/gpiolib.c | 1 | /* |
2 | * S5PV210 - GPIOlib support | ||
2 | * | 3 | * |
3 | * Copyright (c) 2010 Samsung Electronics Co., Ltd. | 4 | * Copyright (c) 2010 Samsung Electronics Co., Ltd. |
4 | * http://www.samsung.com/ | 5 | * http://www.samsung.com/ |
5 | * | 6 | * |
6 | * S5PV210 - GPIOlib support | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | 7 | * This program is free software; you can redistribute it and/or modify |
9 | * it under the terms of the GNU General Public License version 2 as | 8 | * it under the terms of the GNU General Public License version 2 as |
10 | * published by the Free Software Foundation. | 9 | * published by the Free Software Foundation. |
diff --git a/drivers/gpio/sch_gpio.c b/drivers/gpio/gpio-sch.c index 56060421cdff..163515845494 100644 --- a/drivers/gpio/sch_gpio.c +++ b/drivers/gpio/gpio-sch.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * sch_gpio.c - GPIO interface for Intel Poulsbo SCH | 2 | * GPIO interface for Intel Poulsbo SCH |
3 | * | 3 | * |
4 | * Copyright (c) 2010 CompuLab Ltd | 4 | * Copyright (c) 2010 CompuLab Ltd |
5 | * Author: Denis Turischev <denis@compulab.co.il> | 5 | * Author: Denis Turischev <denis@compulab.co.il> |
diff --git a/drivers/gpio/stmpe-gpio.c b/drivers/gpio/gpio-stmpe.c index 4c980b573328..4c980b573328 100644 --- a/drivers/gpio/stmpe-gpio.c +++ b/drivers/gpio/gpio-stmpe.c | |||
diff --git a/drivers/gpio/sx150x.c b/drivers/gpio/gpio-sx150x.c index a4f73534394e..a4f73534394e 100644 --- a/drivers/gpio/sx150x.c +++ b/drivers/gpio/gpio-sx150x.c | |||
diff --git a/drivers/gpio/tc3589x-gpio.c b/drivers/gpio/gpio-tc3589x.c index 2a82e8999a42..2a82e8999a42 100644 --- a/drivers/gpio/tc3589x-gpio.c +++ b/drivers/gpio/gpio-tc3589x.c | |||
diff --git a/arch/arm/mach-tegra/gpio.c b/drivers/gpio/gpio-tegra.c index 919d63837736..747eb40e8afe 100644 --- a/arch/arm/mach-tegra/gpio.c +++ b/drivers/gpio/gpio-tegra.c | |||
@@ -23,6 +23,7 @@ | |||
23 | 23 | ||
24 | #include <linux/io.h> | 24 | #include <linux/io.h> |
25 | #include <linux/gpio.h> | 25 | #include <linux/gpio.h> |
26 | #include <linux/of.h> | ||
26 | 27 | ||
27 | #include <asm/mach/irq.h> | 28 | #include <asm/mach/irq.h> |
28 | 29 | ||
@@ -340,6 +341,15 @@ static int __init tegra_gpio_init(void) | |||
340 | } | 341 | } |
341 | } | 342 | } |
342 | 343 | ||
344 | #ifdef CONFIG_OF_GPIO | ||
345 | /* | ||
346 | * This isn't ideal, but it gets things hooked up until this | ||
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 | |||
343 | gpiochip_add(&tegra_gpio_chip); | 353 | gpiochip_add(&tegra_gpio_chip); |
344 | 354 | ||
345 | for (i = INT_GPIO_BASE; i < (INT_GPIO_BASE + TEGRA_NR_GPIOS); i++) { | 355 | for (i = INT_GPIO_BASE; i < (INT_GPIO_BASE + TEGRA_NR_GPIOS); i++) { |
diff --git a/drivers/gpio/timbgpio.c b/drivers/gpio/gpio-timberdale.c index 0265872e57d1..c593bd46bfb6 100644 --- a/drivers/gpio/timbgpio.c +++ b/drivers/gpio/gpio-timberdale.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * timbgpio.c timberdale FPGA GPIO driver | 2 | * Timberdale FPGA GPIO driver |
3 | * Copyright (c) 2009 Intel Corporation | 3 | * Copyright (c) 2009 Intel Corporation |
4 | * | 4 | * |
5 | * This program is free software; you can redistribute it and/or modify | 5 | * This program is free software; you can redistribute it and/or modify |
diff --git a/drivers/gpio/tps65910-gpio.c b/drivers/gpio/gpio-tps65910.c index 15097ca616d6..b9c1c297669e 100644 --- a/drivers/gpio/tps65910-gpio.c +++ b/drivers/gpio/gpio-tps65910.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * tps65910-gpio.c -- TI TPS6591x | 2 | * TI TPS6591x GPIO driver |
3 | * | 3 | * |
4 | * Copyright 2010 Texas Instruments Inc. | 4 | * Copyright 2010 Texas Instruments Inc. |
5 | * | 5 | * |
diff --git a/drivers/gpio/twl4030-gpio.c b/drivers/gpio/gpio-twl4030.c index 57635ac35a73..b8b4f228757c 100644 --- a/drivers/gpio/twl4030-gpio.c +++ b/drivers/gpio/gpio-twl4030.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * twl4030_gpio.c -- access to GPIOs on TWL4030/TPS659x0 chips | 2 | * Access to GPIOs on TWL4030/TPS659x0 chips |
3 | * | 3 | * |
4 | * Copyright (C) 2006-2007 Texas Instruments, Inc. | 4 | * Copyright (C) 2006-2007 Texas Instruments, Inc. |
5 | * Copyright (C) 2006 MontaVista Software, Inc. | 5 | * Copyright (C) 2006 MontaVista Software, Inc. |
diff --git a/drivers/gpio/gpio-u300.c b/drivers/gpio/gpio-u300.c index d92790140fe5..fd2dfeeefdf3 100644 --- a/drivers/gpio/gpio-u300.c +++ b/drivers/gpio/gpio-u300.c | |||
@@ -1,11 +1,8 @@ | |||
1 | /* | 1 | /* |
2 | * | 2 | * U300 GPIO module. |
3 | * arch/arm/mach-u300/gpio.c | ||
4 | * | ||
5 | * | 3 | * |
6 | * Copyright (C) 2007-2009 ST-Ericsson AB | 4 | * Copyright (C) 2007-2009 ST-Ericsson AB |
7 | * License terms: GNU General Public License (GPL) version 2 | 5 | * License terms: GNU General Public License (GPL) version 2 |
8 | * U300 GPIO module. | ||
9 | * This can driver either of the two basic GPIO cores | 6 | * This can driver either of the two basic GPIO cores |
10 | * available in the U300 platforms: | 7 | * available in the U300 platforms: |
11 | * COH 901 335 - Used in DB3150 (U300 1.0) and DB3200 (U330 1.0) | 8 | * COH 901 335 - Used in DB3150 (U300 1.0) and DB3200 (U330 1.0) |
diff --git a/drivers/gpio/ucb1400_gpio.c b/drivers/gpio/gpio-ucb1400.c index 50e6bd1392ce..50e6bd1392ce 100644 --- a/drivers/gpio/ucb1400_gpio.c +++ b/drivers/gpio/gpio-ucb1400.c | |||
diff --git a/drivers/gpio/vr41xx_giu.c b/drivers/gpio/gpio-vr41xx.c index a365be040b36..98723cb9ac68 100644 --- a/drivers/gpio/vr41xx_giu.c +++ b/drivers/gpio/gpio-vr41xx.c | |||
@@ -518,7 +518,7 @@ static int __devinit giu_probe(struct platform_device *pdev) | |||
518 | if (!res) | 518 | if (!res) |
519 | return -EBUSY; | 519 | return -EBUSY; |
520 | 520 | ||
521 | giu_base = ioremap(res->start, res->end - res->start + 1); | 521 | giu_base = ioremap(res->start, resource_size(res)); |
522 | if (!giu_base) | 522 | if (!giu_base) |
523 | return -ENOMEM; | 523 | return -ENOMEM; |
524 | 524 | ||
diff --git a/drivers/gpio/vx855_gpio.c b/drivers/gpio/gpio-vx855.c index ef5aabd8b8b7..ef5aabd8b8b7 100644 --- a/drivers/gpio/vx855_gpio.c +++ b/drivers/gpio/gpio-vx855.c | |||
diff --git a/drivers/gpio/wm831x-gpio.c b/drivers/gpio/gpio-wm831x.c index 2bcfb0be09ff..deb949e75ec1 100644 --- a/drivers/gpio/wm831x-gpio.c +++ b/drivers/gpio/gpio-wm831x.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * wm831x-gpio.c -- gpiolib support for Wolfson WM831x PMICs | 2 | * gpiolib support for Wolfson WM831x PMICs |
3 | * | 3 | * |
4 | * Copyright 2009 Wolfson Microelectronics PLC. | 4 | * Copyright 2009 Wolfson Microelectronics PLC. |
5 | * | 5 | * |
diff --git a/drivers/gpio/wm8350-gpiolib.c b/drivers/gpio/gpio-wm8350.c index 359999290f55..a06af5154838 100644 --- a/drivers/gpio/wm8350-gpiolib.c +++ b/drivers/gpio/gpio-wm8350.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * wm835x-gpiolib.c -- gpiolib support for Wolfson WM835x PMICs | 2 | * gpiolib support for Wolfson WM835x PMICs |
3 | * | 3 | * |
4 | * Copyright 2009 Wolfson Microelectronics PLC. | 4 | * Copyright 2009 Wolfson Microelectronics PLC. |
5 | * | 5 | * |
diff --git a/drivers/gpio/wm8994-gpio.c b/drivers/gpio/gpio-wm8994.c index c822baacd8fc..96198f3fab73 100644 --- a/drivers/gpio/wm8994-gpio.c +++ b/drivers/gpio/gpio-wm8994.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * wm8994-gpio.c -- gpiolib support for Wolfson WM8994 | 2 | * gpiolib support for Wolfson WM8994 |
3 | * | 3 | * |
4 | * Copyright 2009 Wolfson Microelectronics PLC. | 4 | * Copyright 2009 Wolfson Microelectronics PLC. |
5 | * | 5 | * |
diff --git a/drivers/gpio/xilinx_gpio.c b/drivers/gpio/gpio-xilinx.c index 846fbd5e31bf..846fbd5e31bf 100644 --- a/drivers/gpio/xilinx_gpio.c +++ b/drivers/gpio/gpio-xilinx.c | |||
diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig index 713d43b4e563..6c21c2986ca1 100644 --- a/drivers/leds/Kconfig +++ b/drivers/leds/Kconfig | |||
@@ -92,7 +92,7 @@ config LEDS_NET48XX | |||
92 | config LEDS_NET5501 | 92 | config LEDS_NET5501 |
93 | tristate "LED Support for Soekris net5501 series Error LED" | 93 | tristate "LED Support for Soekris net5501 series Error LED" |
94 | depends on LEDS_TRIGGERS | 94 | depends on LEDS_TRIGGERS |
95 | depends on X86 && LEDS_GPIO_PLATFORM && GPIO_CS5535 | 95 | depends on X86 && GPIO_CS5535 |
96 | select LEDS_TRIGGER_DEFAULT_ON | 96 | select LEDS_TRIGGER_DEFAULT_ON |
97 | default n | 97 | default n |
98 | help | 98 | help |
@@ -182,23 +182,6 @@ config LEDS_GPIO | |||
182 | defined as platform devices and/or OpenFirmware platform devices. | 182 | defined as platform devices and/or OpenFirmware platform devices. |
183 | The code to use these bindings can be selected below. | 183 | The code to use these bindings can be selected below. |
184 | 184 | ||
185 | config LEDS_GPIO_PLATFORM | ||
186 | bool "Platform device bindings for GPIO LEDs" | ||
187 | depends on LEDS_GPIO | ||
188 | default y | ||
189 | help | ||
190 | Let the leds-gpio driver drive LEDs which have been defined as | ||
191 | platform devices. If you don't know what this means, say yes. | ||
192 | |||
193 | config LEDS_GPIO_OF | ||
194 | bool "OpenFirmware platform device bindings for GPIO LEDs" | ||
195 | depends on LEDS_GPIO && OF_DEVICE | ||
196 | default y | ||
197 | help | ||
198 | Let the leds-gpio driver drive LEDs which have been defined as | ||
199 | of_platform devices. For instance, LEDs which are listed in a "dts" | ||
200 | file. | ||
201 | |||
202 | config LEDS_LP3944 | 185 | config LEDS_LP3944 |
203 | tristate "LED Support for N.S. LP3944 (Fun Light) I2C chip" | 186 | tristate "LED Support for N.S. LP3944 (Fun Light) I2C chip" |
204 | depends on LEDS_CLASS | 187 | depends on LEDS_CLASS |
diff --git a/drivers/leds/leds-gpio.c b/drivers/leds/leds-gpio.c index b0480c8fbcbf..3d8bc327a68d 100644 --- a/drivers/leds/leds-gpio.c +++ b/drivers/leds/leds-gpio.c | |||
@@ -165,7 +165,7 @@ static inline int sizeof_gpio_leds_priv(int num_leds) | |||
165 | } | 165 | } |
166 | 166 | ||
167 | /* Code to create from OpenFirmware platform devices */ | 167 | /* Code to create from OpenFirmware platform devices */ |
168 | #ifdef CONFIG_LEDS_GPIO_OF | 168 | #ifdef CONFIG_OF_GPIO |
169 | static struct gpio_leds_priv * __devinit gpio_leds_create_of(struct platform_device *pdev) | 169 | static struct gpio_leds_priv * __devinit gpio_leds_create_of(struct platform_device *pdev) |
170 | { | 170 | { |
171 | struct device_node *np = pdev->dev.of_node, *child; | 171 | struct device_node *np = pdev->dev.of_node, *child; |
@@ -223,13 +223,13 @@ static const struct of_device_id of_gpio_leds_match[] = { | |||
223 | { .compatible = "gpio-leds", }, | 223 | { .compatible = "gpio-leds", }, |
224 | {}, | 224 | {}, |
225 | }; | 225 | }; |
226 | #else | 226 | #else /* CONFIG_OF_GPIO */ |
227 | static struct gpio_leds_priv * __devinit gpio_leds_create_of(struct platform_device *pdev) | 227 | static struct gpio_leds_priv * __devinit gpio_leds_create_of(struct platform_device *pdev) |
228 | { | 228 | { |
229 | return NULL; | 229 | return NULL; |
230 | } | 230 | } |
231 | #define of_gpio_leds_match NULL | 231 | #define of_gpio_leds_match NULL |
232 | #endif | 232 | #endif /* CONFIG_OF_GPIO */ |
233 | 233 | ||
234 | 234 | ||
235 | static int __devinit gpio_led_probe(struct platform_device *pdev) | 235 | static int __devinit gpio_led_probe(struct platform_device *pdev) |
diff --git a/drivers/of/gpio.c b/drivers/of/gpio.c index 905960338fb2..3007662ac614 100644 --- a/drivers/of/gpio.c +++ b/drivers/of/gpio.c | |||
@@ -21,8 +21,9 @@ | |||
21 | #include <linux/slab.h> | 21 | #include <linux/slab.h> |
22 | 22 | ||
23 | /** | 23 | /** |
24 | * of_get_gpio_flags - Get a GPIO number and flags to use with GPIO API | 24 | * of_get_named_gpio_flags() - Get a GPIO number and flags to use with GPIO API |
25 | * @np: device node to get GPIO from | 25 | * @np: device node to get GPIO from |
26 | * @propname: property name containing gpio specifier(s) | ||
26 | * @index: index of the GPIO | 27 | * @index: index of the GPIO |
27 | * @flags: a flags pointer to fill in | 28 | * @flags: a flags pointer to fill in |
28 | * | 29 | * |
@@ -30,8 +31,8 @@ | |||
30 | * value on the error condition. If @flags is not NULL the function also fills | 31 | * value on the error condition. If @flags is not NULL the function also fills |
31 | * in flags for the GPIO. | 32 | * in flags for the GPIO. |
32 | */ | 33 | */ |
33 | int of_get_gpio_flags(struct device_node *np, int index, | 34 | int of_get_named_gpio_flags(struct device_node *np, const char *propname, |
34 | enum of_gpio_flags *flags) | 35 | int index, enum of_gpio_flags *flags) |
35 | { | 36 | { |
36 | int ret; | 37 | int ret; |
37 | struct device_node *gpio_np; | 38 | struct device_node *gpio_np; |
@@ -40,7 +41,7 @@ int of_get_gpio_flags(struct device_node *np, int index, | |||
40 | const void *gpio_spec; | 41 | const void *gpio_spec; |
41 | const __be32 *gpio_cells; | 42 | const __be32 *gpio_cells; |
42 | 43 | ||
43 | ret = of_parse_phandles_with_args(np, "gpios", "#gpio-cells", index, | 44 | ret = of_parse_phandles_with_args(np, propname, "#gpio-cells", index, |
44 | &gpio_np, &gpio_spec); | 45 | &gpio_np, &gpio_spec); |
45 | if (ret) { | 46 | if (ret) { |
46 | pr_debug("%s: can't parse gpios property\n", __func__); | 47 | pr_debug("%s: can't parse gpios property\n", __func__); |
@@ -79,7 +80,7 @@ err0: | |||
79 | pr_debug("%s exited with status %d\n", __func__, ret); | 80 | pr_debug("%s exited with status %d\n", __func__, ret); |
80 | return ret; | 81 | return ret; |
81 | } | 82 | } |
82 | EXPORT_SYMBOL(of_get_gpio_flags); | 83 | EXPORT_SYMBOL(of_get_named_gpio_flags); |
83 | 84 | ||
84 | /** | 85 | /** |
85 | * of_gpio_count - Count GPIOs for a device | 86 | * of_gpio_count - Count GPIOs for a device |
diff --git a/include/linux/of_gpio.h b/include/linux/of_gpio.h index 6598c04dab01..aec8025c786a 100644 --- a/include/linux/of_gpio.h +++ b/include/linux/of_gpio.h | |||
@@ -46,8 +46,9 @@ static inline struct of_mm_gpio_chip *to_of_mm_gpio_chip(struct gpio_chip *gc) | |||
46 | return container_of(gc, struct of_mm_gpio_chip, gc); | 46 | return container_of(gc, struct of_mm_gpio_chip, gc); |
47 | } | 47 | } |
48 | 48 | ||
49 | extern int of_get_gpio_flags(struct device_node *np, int index, | 49 | extern int of_get_named_gpio_flags(struct device_node *np, |
50 | enum of_gpio_flags *flags); | 50 | const char *list_name, int index, enum of_gpio_flags *flags); |
51 | |||
51 | extern unsigned int of_gpio_count(struct device_node *np); | 52 | extern unsigned int of_gpio_count(struct device_node *np); |
52 | 53 | ||
53 | extern int of_mm_gpiochip_add(struct device_node *np, | 54 | extern int of_mm_gpiochip_add(struct device_node *np, |
@@ -60,8 +61,8 @@ extern struct gpio_chip *of_node_to_gpiochip(struct device_node *np); | |||
60 | #else /* CONFIG_OF_GPIO */ | 61 | #else /* CONFIG_OF_GPIO */ |
61 | 62 | ||
62 | /* Drivers may not strictly depend on the GPIO support, so let them link. */ | 63 | /* Drivers may not strictly depend on the GPIO support, so let them link. */ |
63 | static inline int of_get_gpio_flags(struct device_node *np, int index, | 64 | static inline int of_get_named_gpio_flags(struct device_node *np, |
64 | enum of_gpio_flags *flags) | 65 | const char *list_name, int index, enum of_gpio_flags *flags) |
65 | { | 66 | { |
66 | return -ENOSYS; | 67 | return -ENOSYS; |
67 | } | 68 | } |
@@ -77,7 +78,38 @@ static inline void of_gpiochip_remove(struct gpio_chip *gc) { } | |||
77 | #endif /* CONFIG_OF_GPIO */ | 78 | #endif /* CONFIG_OF_GPIO */ |
78 | 79 | ||
79 | /** | 80 | /** |
80 | * of_get_gpio - Get a GPIO number to use with GPIO API | 81 | * of_get_gpio_flags() - Get a GPIO number and flags to use with GPIO API |
82 | * @np: device node to get GPIO from | ||
83 | * @index: index of the GPIO | ||
84 | * @flags: a flags pointer to fill in | ||
85 | * | ||
86 | * Returns GPIO number to use with Linux generic GPIO API, or one of the errno | ||
87 | * value on the error condition. If @flags is not NULL the function also fills | ||
88 | * in flags for the GPIO. | ||
89 | */ | ||
90 | static inline int of_get_gpio_flags(struct device_node *np, int index, | ||
91 | enum of_gpio_flags *flags) | ||
92 | { | ||
93 | return of_get_named_gpio_flags(np, "gpios", index, flags); | ||
94 | } | ||
95 | |||
96 | /** | ||
97 | * of_get_named_gpio() - Get a GPIO number to use with GPIO API | ||
98 | * @np: device node to get GPIO from | ||
99 | * @propname: Name of property containing gpio specifier(s) | ||
100 | * @index: index of the GPIO | ||
101 | * | ||
102 | * Returns GPIO number to use with Linux generic GPIO API, or one of the errno | ||
103 | * value on the error condition. | ||
104 | */ | ||
105 | static inline int of_get_named_gpio(struct device_node *np, | ||
106 | const char *propname, int index) | ||
107 | { | ||
108 | return of_get_named_gpio_flags(np, propname, index, NULL); | ||
109 | } | ||
110 | |||
111 | /** | ||
112 | * of_get_gpio() - Get a GPIO number to use with GPIO API | ||
81 | * @np: device node to get GPIO from | 113 | * @np: device node to get GPIO from |
82 | * @index: index of the GPIO | 114 | * @index: index of the GPIO |
83 | * | 115 | * |
diff --git a/include/linux/spi/74x164.h b/include/linux/spi/74x164.h index d85c52f294a0..0aa6acc73317 100644 --- a/include/linux/spi/74x164.h +++ b/include/linux/spi/74x164.h | |||
@@ -1,8 +1,6 @@ | |||
1 | #ifndef LINUX_SPI_74X164_H | 1 | #ifndef LINUX_SPI_74X164_H |
2 | #define LINUX_SPI_74X164_H | 2 | #define LINUX_SPI_74X164_H |
3 | 3 | ||
4 | #define GEN_74X164_DRIVER_NAME "74x164" | ||
5 | |||
6 | struct gen_74x164_chip_platform_data { | 4 | struct gen_74x164_chip_platform_data { |
7 | /* number assigned to the first GPIO */ | 5 | /* number assigned to the first GPIO */ |
8 | unsigned base; | 6 | unsigned base; |
diff --git a/include/linux/spi/mcp23s08.h b/include/linux/spi/mcp23s08.h index c42cff8ca191..2d676d5aaa89 100644 --- a/include/linux/spi/mcp23s08.h +++ b/include/linux/spi/mcp23s08.h | |||
@@ -22,13 +22,4 @@ struct mcp23s08_platform_data { | |||
22 | * base to base+15 (or base+31 for s17 variant). | 22 | * base to base+15 (or base+31 for s17 variant). |
23 | */ | 23 | */ |
24 | unsigned base; | 24 | unsigned base; |
25 | |||
26 | void *context; /* param to setup/teardown */ | ||
27 | |||
28 | int (*setup)(struct spi_device *spi, | ||
29 | int gpio, unsigned ngpio, | ||
30 | void *context); | ||
31 | int (*teardown)(struct spi_device *spi, | ||
32 | int gpio, unsigned ngpio, | ||
33 | void *context); | ||
34 | }; | 25 | }; |