diff options
author | Arnd Bergmann <arnd@arndb.de> | 2012-03-02 08:22:28 -0500 |
---|---|---|
committer | Arnd Bergmann <arnd@arndb.de> | 2012-03-02 08:22:28 -0500 |
commit | 48b3b08e00012382cb52099e509b529305ae0a00 (patch) | |
tree | 0b5ff03c195707e3e545731121bc4537a3b42ac4 | |
parent | 6e1d521b9d1201214ec4a67a7e4360232be5f963 (diff) | |
parent | f75622f4679479d352d2fa83e0d84c6c13cfcb5f (diff) |
Merge branch 'at91-3.4-cleanup2+DT' of git://github.com/at91linux/linux-at91 into next/dt
* 'at91-3.4-cleanup2+DT' of git://github.com/at91linux/linux-at91: (22 commits)
ARM: at91: at91sam9x5cm/dt: add leds support
ARM: at91: usb_a9g20/dt: add gpio-keys support
ARM: at91: at91sam9m10g45ek/dt: add gpio-keys support
ARM: at91: at91sam9m10g45ek/dt: add leds support
ARM: at91: usb_a9g20/dt: add leds support
ARM: at91/pio: add new PIO3 features
ARM: at91: add sam9_smc.o to at91sam9x5 build
ARM: at91/tc/clocksource: Add 32 bit variant to Timer Counter
ARM: at91/tc: add device tree support to atmel_tclib
ARM: at91/tclib: take iomem size from resource
ARM: at91/pit: add traces in case of error
ARM: at91: pit add DT support
ARM: at91: AIC and GPIO IRQ device tree initialization
ARM: at91/board-dt: remove AIC irq domain from board file
ARM: at91/gpio: remove the static specification of gpio_chip.base
ARM: at91/gpio: add .to_irq gpio_chip handler
ARM: at91/gpio: non-DT builds do not have gpio_chip.of_node field
ARM: at91/gpio: add irqdomain and DT support
ARM: at91/gpio: change comments and one variable name
ARM/USB: at91/ohci-at91: remove the use of irq_to_gpio
...
28 files changed, 1286 insertions, 204 deletions
diff --git a/Documentation/devicetree/bindings/arm/atmel-aic.txt b/Documentation/devicetree/bindings/arm/atmel-aic.txt new file mode 100644 index 000000000000..aabca4f83402 --- /dev/null +++ b/Documentation/devicetree/bindings/arm/atmel-aic.txt | |||
@@ -0,0 +1,38 @@ | |||
1 | * Advanced Interrupt Controller (AIC) | ||
2 | |||
3 | Required properties: | ||
4 | - compatible: Should be "atmel,<chip>-aic" | ||
5 | - interrupt-controller: Identifies the node as an interrupt controller. | ||
6 | - interrupt-parent: For single AIC system, it is an empty property. | ||
7 | - #interrupt-cells: The number of cells to define the interrupts. It sould be 2. | ||
8 | The first cell is the IRQ number (aka "Peripheral IDentifier" on datasheet). | ||
9 | The second cell is used to specify flags: | ||
10 | bits[3:0] trigger type and level flags: | ||
11 | 1 = low-to-high edge triggered. | ||
12 | 2 = high-to-low edge triggered. | ||
13 | 4 = active high level-sensitive. | ||
14 | 8 = active low level-sensitive. | ||
15 | Valid combinations are 1, 2, 3, 4, 8. | ||
16 | Default flag for internal sources should be set to 4 (active high). | ||
17 | - reg: Should contain AIC registers location and length | ||
18 | |||
19 | Examples: | ||
20 | /* | ||
21 | * AIC | ||
22 | */ | ||
23 | aic: interrupt-controller@fffff000 { | ||
24 | compatible = "atmel,at91rm9200-aic"; | ||
25 | interrupt-controller; | ||
26 | interrupt-parent; | ||
27 | #interrupt-cells = <2>; | ||
28 | reg = <0xfffff000 0x200>; | ||
29 | }; | ||
30 | |||
31 | /* | ||
32 | * An interrupt generating device that is wired to an AIC. | ||
33 | */ | ||
34 | dma: dma-controller@ffffec00 { | ||
35 | compatible = "atmel,at91sam9g45-dma"; | ||
36 | reg = <0xffffec00 0x200>; | ||
37 | interrupts = <21 4>; | ||
38 | }; | ||
diff --git a/Documentation/devicetree/bindings/arm/atmel-at91.txt b/Documentation/devicetree/bindings/arm/atmel-at91.txt new file mode 100644 index 000000000000..1aeaf6f2a1ba --- /dev/null +++ b/Documentation/devicetree/bindings/arm/atmel-at91.txt | |||
@@ -0,0 +1,32 @@ | |||
1 | Atmel AT91 device tree bindings. | ||
2 | ================================ | ||
3 | |||
4 | PIT Timer required properties: | ||
5 | - compatible: Should be "atmel,at91sam9260-pit" | ||
6 | - reg: Should contain registers location and length | ||
7 | - interrupts: Should contain interrupt for the PIT which is the IRQ line | ||
8 | shared across all System Controller members. | ||
9 | |||
10 | TC/TCLIB Timer required properties: | ||
11 | - compatible: Should be "atmel,<chip>-pit". | ||
12 | <chip> can be "at91rm9200" or "at91sam9x5" | ||
13 | - reg: Should contain registers location and length | ||
14 | - interrupts: Should contain all interrupts for the TC block | ||
15 | Note that you can specify several interrupt cells if the TC | ||
16 | block has one interrupt per channel. | ||
17 | |||
18 | Examples: | ||
19 | |||
20 | One interrupt per TC block: | ||
21 | tcb0: timer@fff7c000 { | ||
22 | compatible = "atmel,at91rm9200-tcb"; | ||
23 | reg = <0xfff7c000 0x100>; | ||
24 | interrupts = <18 4>; | ||
25 | }; | ||
26 | |||
27 | One interrupt per TC channel in a TC block: | ||
28 | tcb1: timer@fffdc000 { | ||
29 | compatible = "atmel,at91rm9200-tcb"; | ||
30 | reg = <0xfffdc000 0x100>; | ||
31 | interrupts = <26 4 27 4 28 4>; | ||
32 | }; | ||
diff --git a/Documentation/devicetree/bindings/gpio/gpio_atmel.txt b/Documentation/devicetree/bindings/gpio/gpio_atmel.txt new file mode 100644 index 000000000000..66efc804806a --- /dev/null +++ b/Documentation/devicetree/bindings/gpio/gpio_atmel.txt | |||
@@ -0,0 +1,20 @@ | |||
1 | * Atmel GPIO controller (PIO) | ||
2 | |||
3 | Required properties: | ||
4 | - compatible: "atmel,<chip>-gpio", where <chip> is at91rm9200 or at91sam9x5. | ||
5 | - reg: Should contain GPIO controller registers location and length | ||
6 | - interrupts: Should be the port interrupt shared by all the pins. | ||
7 | - #gpio-cells: Should be two. The first cell is the pin number and | ||
8 | the second cell is used to specify optional parameters (currently | ||
9 | unused). | ||
10 | - gpio-controller: Marks the device node as a GPIO controller. | ||
11 | |||
12 | Example: | ||
13 | pioA: gpio@fffff200 { | ||
14 | compatible = "atmel,at91rm9200-gpio"; | ||
15 | reg = <0xfffff200 0x100>; | ||
16 | interrupts = <2 4>; | ||
17 | #gpio-cells = <2>; | ||
18 | gpio-controller; | ||
19 | }; | ||
20 | |||
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 92c9c79c140c..cabd8f556a1f 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig | |||
@@ -322,6 +322,7 @@ config ARCH_AT91 | |||
322 | select ARCH_REQUIRE_GPIOLIB | 322 | select ARCH_REQUIRE_GPIOLIB |
323 | select HAVE_CLK | 323 | select HAVE_CLK |
324 | select CLKDEV_LOOKUP | 324 | select CLKDEV_LOOKUP |
325 | select IRQ_DOMAIN | ||
325 | help | 326 | help |
326 | This enables support for systems based on the Atmel AT91RM9200, | 327 | This enables support for systems based on the Atmel AT91RM9200, |
327 | AT91SAM9 processors. | 328 | AT91SAM9 processors. |
diff --git a/arch/arm/boot/dts/at91sam9g20.dtsi b/arch/arm/boot/dts/at91sam9g20.dtsi index 07603b8c9503..a100db03ec90 100644 --- a/arch/arm/boot/dts/at91sam9g20.dtsi +++ b/arch/arm/boot/dts/at91sam9g20.dtsi | |||
@@ -23,6 +23,11 @@ | |||
23 | serial4 = &usart3; | 23 | serial4 = &usart3; |
24 | serial5 = &usart4; | 24 | serial5 = &usart4; |
25 | serial6 = &usart5; | 25 | serial6 = &usart5; |
26 | gpio0 = &pioA; | ||
27 | gpio1 = &pioB; | ||
28 | gpio2 = &pioC; | ||
29 | tcb0 = &tcb0; | ||
30 | tcb1 = &tcb1; | ||
26 | }; | 31 | }; |
27 | cpus { | 32 | cpus { |
28 | cpu@0 { | 33 | cpu@0 { |
@@ -47,24 +52,69 @@ | |||
47 | ranges; | 52 | ranges; |
48 | 53 | ||
49 | aic: interrupt-controller@fffff000 { | 54 | aic: interrupt-controller@fffff000 { |
50 | #interrupt-cells = <1>; | 55 | #interrupt-cells = <2>; |
51 | compatible = "atmel,at91rm9200-aic"; | 56 | compatible = "atmel,at91rm9200-aic"; |
52 | interrupt-controller; | 57 | interrupt-controller; |
53 | interrupt-parent; | 58 | interrupt-parent; |
54 | reg = <0xfffff000 0x200>; | 59 | reg = <0xfffff000 0x200>; |
55 | }; | 60 | }; |
56 | 61 | ||
62 | pit: timer@fffffd30 { | ||
63 | compatible = "atmel,at91sam9260-pit"; | ||
64 | reg = <0xfffffd30 0xf>; | ||
65 | interrupts = <1 4>; | ||
66 | }; | ||
67 | |||
68 | tcb0: timer@fffa0000 { | ||
69 | compatible = "atmel,at91rm9200-tcb"; | ||
70 | reg = <0xfffa0000 0x100>; | ||
71 | interrupts = <17 4 18 4 19 4>; | ||
72 | }; | ||
73 | |||
74 | tcb1: timer@fffdc000 { | ||
75 | compatible = "atmel,at91rm9200-tcb"; | ||
76 | reg = <0xfffdc000 0x100>; | ||
77 | interrupts = <26 4 27 4 28 4>; | ||
78 | }; | ||
79 | |||
80 | pioA: gpio@fffff400 { | ||
81 | compatible = "atmel,at91rm9200-gpio"; | ||
82 | reg = <0xfffff400 0x100>; | ||
83 | interrupts = <2 4>; | ||
84 | #gpio-cells = <2>; | ||
85 | gpio-controller; | ||
86 | interrupt-controller; | ||
87 | }; | ||
88 | |||
89 | pioB: gpio@fffff600 { | ||
90 | compatible = "atmel,at91rm9200-gpio"; | ||
91 | reg = <0xfffff600 0x100>; | ||
92 | interrupts = <3 4>; | ||
93 | #gpio-cells = <2>; | ||
94 | gpio-controller; | ||
95 | interrupt-controller; | ||
96 | }; | ||
97 | |||
98 | pioC: gpio@fffff800 { | ||
99 | compatible = "atmel,at91rm9200-gpio"; | ||
100 | reg = <0xfffff800 0x100>; | ||
101 | interrupts = <4 4>; | ||
102 | #gpio-cells = <2>; | ||
103 | gpio-controller; | ||
104 | interrupt-controller; | ||
105 | }; | ||
106 | |||
57 | dbgu: serial@fffff200 { | 107 | dbgu: serial@fffff200 { |
58 | compatible = "atmel,at91sam9260-usart"; | 108 | compatible = "atmel,at91sam9260-usart"; |
59 | reg = <0xfffff200 0x200>; | 109 | reg = <0xfffff200 0x200>; |
60 | interrupts = <1>; | 110 | interrupts = <1 4>; |
61 | status = "disabled"; | 111 | status = "disabled"; |
62 | }; | 112 | }; |
63 | 113 | ||
64 | usart0: serial@fffb0000 { | 114 | usart0: serial@fffb0000 { |
65 | compatible = "atmel,at91sam9260-usart"; | 115 | compatible = "atmel,at91sam9260-usart"; |
66 | reg = <0xfffb0000 0x200>; | 116 | reg = <0xfffb0000 0x200>; |
67 | interrupts = <6>; | 117 | interrupts = <6 4>; |
68 | atmel,use-dma-rx; | 118 | atmel,use-dma-rx; |
69 | atmel,use-dma-tx; | 119 | atmel,use-dma-tx; |
70 | status = "disabled"; | 120 | status = "disabled"; |
@@ -73,7 +123,7 @@ | |||
73 | usart1: serial@fffb4000 { | 123 | usart1: serial@fffb4000 { |
74 | compatible = "atmel,at91sam9260-usart"; | 124 | compatible = "atmel,at91sam9260-usart"; |
75 | reg = <0xfffb4000 0x200>; | 125 | reg = <0xfffb4000 0x200>; |
76 | interrupts = <7>; | 126 | interrupts = <7 4>; |
77 | atmel,use-dma-rx; | 127 | atmel,use-dma-rx; |
78 | atmel,use-dma-tx; | 128 | atmel,use-dma-tx; |
79 | status = "disabled"; | 129 | status = "disabled"; |
@@ -82,7 +132,7 @@ | |||
82 | usart2: serial@fffb8000 { | 132 | usart2: serial@fffb8000 { |
83 | compatible = "atmel,at91sam9260-usart"; | 133 | compatible = "atmel,at91sam9260-usart"; |
84 | reg = <0xfffb8000 0x200>; | 134 | reg = <0xfffb8000 0x200>; |
85 | interrupts = <8>; | 135 | interrupts = <8 4>; |
86 | atmel,use-dma-rx; | 136 | atmel,use-dma-rx; |
87 | atmel,use-dma-tx; | 137 | atmel,use-dma-tx; |
88 | status = "disabled"; | 138 | status = "disabled"; |
@@ -91,7 +141,7 @@ | |||
91 | usart3: serial@fffd0000 { | 141 | usart3: serial@fffd0000 { |
92 | compatible = "atmel,at91sam9260-usart"; | 142 | compatible = "atmel,at91sam9260-usart"; |
93 | reg = <0xfffd0000 0x200>; | 143 | reg = <0xfffd0000 0x200>; |
94 | interrupts = <23>; | 144 | interrupts = <23 4>; |
95 | atmel,use-dma-rx; | 145 | atmel,use-dma-rx; |
96 | atmel,use-dma-tx; | 146 | atmel,use-dma-tx; |
97 | status = "disabled"; | 147 | status = "disabled"; |
@@ -100,7 +150,7 @@ | |||
100 | usart4: serial@fffd4000 { | 150 | usart4: serial@fffd4000 { |
101 | compatible = "atmel,at91sam9260-usart"; | 151 | compatible = "atmel,at91sam9260-usart"; |
102 | reg = <0xfffd4000 0x200>; | 152 | reg = <0xfffd4000 0x200>; |
103 | interrupts = <24>; | 153 | interrupts = <24 4>; |
104 | atmel,use-dma-rx; | 154 | atmel,use-dma-rx; |
105 | atmel,use-dma-tx; | 155 | atmel,use-dma-tx; |
106 | status = "disabled"; | 156 | status = "disabled"; |
@@ -109,7 +159,7 @@ | |||
109 | usart5: serial@fffd8000 { | 159 | usart5: serial@fffd8000 { |
110 | compatible = "atmel,at91sam9260-usart"; | 160 | compatible = "atmel,at91sam9260-usart"; |
111 | reg = <0xfffd8000 0x200>; | 161 | reg = <0xfffd8000 0x200>; |
112 | interrupts = <25>; | 162 | interrupts = <25 4>; |
113 | atmel,use-dma-rx; | 163 | atmel,use-dma-rx; |
114 | atmel,use-dma-tx; | 164 | atmel,use-dma-tx; |
115 | status = "disabled"; | 165 | status = "disabled"; |
@@ -118,7 +168,7 @@ | |||
118 | macb0: ethernet@fffc4000 { | 168 | macb0: ethernet@fffc4000 { |
119 | compatible = "cdns,at32ap7000-macb", "cdns,macb"; | 169 | compatible = "cdns,at32ap7000-macb", "cdns,macb"; |
120 | reg = <0xfffc4000 0x100>; | 170 | reg = <0xfffc4000 0x100>; |
121 | interrupts = <21>; | 171 | interrupts = <21 4>; |
122 | status = "disabled"; | 172 | status = "disabled"; |
123 | }; | 173 | }; |
124 | }; | 174 | }; |
diff --git a/arch/arm/boot/dts/at91sam9g45.dtsi b/arch/arm/boot/dts/at91sam9g45.dtsi index fffa005300a4..f779667159b1 100644 --- a/arch/arm/boot/dts/at91sam9g45.dtsi +++ b/arch/arm/boot/dts/at91sam9g45.dtsi | |||
@@ -22,6 +22,13 @@ | |||
22 | serial2 = &usart1; | 22 | serial2 = &usart1; |
23 | serial3 = &usart2; | 23 | serial3 = &usart2; |
24 | serial4 = &usart3; | 24 | serial4 = &usart3; |
25 | gpio0 = &pioA; | ||
26 | gpio1 = &pioB; | ||
27 | gpio2 = &pioC; | ||
28 | gpio3 = &pioD; | ||
29 | gpio4 = &pioE; | ||
30 | tcb0 = &tcb0; | ||
31 | tcb1 = &tcb1; | ||
25 | }; | 32 | }; |
26 | cpus { | 33 | cpus { |
27 | cpu@0 { | 34 | cpu@0 { |
@@ -46,30 +53,94 @@ | |||
46 | ranges; | 53 | ranges; |
47 | 54 | ||
48 | aic: interrupt-controller@fffff000 { | 55 | aic: interrupt-controller@fffff000 { |
49 | #interrupt-cells = <1>; | 56 | #interrupt-cells = <2>; |
50 | compatible = "atmel,at91rm9200-aic"; | 57 | compatible = "atmel,at91rm9200-aic"; |
51 | interrupt-controller; | 58 | interrupt-controller; |
52 | interrupt-parent; | 59 | interrupt-parent; |
53 | reg = <0xfffff000 0x200>; | 60 | reg = <0xfffff000 0x200>; |
54 | }; | 61 | }; |
55 | 62 | ||
63 | pit: timer@fffffd30 { | ||
64 | compatible = "atmel,at91sam9260-pit"; | ||
65 | reg = <0xfffffd30 0xf>; | ||
66 | interrupts = <1 4>; | ||
67 | }; | ||
68 | |||
69 | |||
70 | tcb0: timer@fff7c000 { | ||
71 | compatible = "atmel,at91rm9200-tcb"; | ||
72 | reg = <0xfff7c000 0x100>; | ||
73 | interrupts = <18 4>; | ||
74 | }; | ||
75 | |||
76 | tcb1: timer@fffd4000 { | ||
77 | compatible = "atmel,at91rm9200-tcb"; | ||
78 | reg = <0xfffd4000 0x100>; | ||
79 | interrupts = <18 4>; | ||
80 | }; | ||
81 | |||
56 | dma: dma-controller@ffffec00 { | 82 | dma: dma-controller@ffffec00 { |
57 | compatible = "atmel,at91sam9g45-dma"; | 83 | compatible = "atmel,at91sam9g45-dma"; |
58 | reg = <0xffffec00 0x200>; | 84 | reg = <0xffffec00 0x200>; |
59 | interrupts = <21>; | 85 | interrupts = <21 4>; |
86 | }; | ||
87 | |||
88 | pioA: gpio@fffff200 { | ||
89 | compatible = "atmel,at91rm9200-gpio"; | ||
90 | reg = <0xfffff200 0x100>; | ||
91 | interrupts = <2 4>; | ||
92 | #gpio-cells = <2>; | ||
93 | gpio-controller; | ||
94 | interrupt-controller; | ||
95 | }; | ||
96 | |||
97 | pioB: gpio@fffff400 { | ||
98 | compatible = "atmel,at91rm9200-gpio"; | ||
99 | reg = <0xfffff400 0x100>; | ||
100 | interrupts = <3 4>; | ||
101 | #gpio-cells = <2>; | ||
102 | gpio-controller; | ||
103 | interrupt-controller; | ||
104 | }; | ||
105 | |||
106 | pioC: gpio@fffff600 { | ||
107 | compatible = "atmel,at91rm9200-gpio"; | ||
108 | reg = <0xfffff600 0x100>; | ||
109 | interrupts = <4 4>; | ||
110 | #gpio-cells = <2>; | ||
111 | gpio-controller; | ||
112 | interrupt-controller; | ||
113 | }; | ||
114 | |||
115 | pioD: gpio@fffff800 { | ||
116 | compatible = "atmel,at91rm9200-gpio"; | ||
117 | reg = <0xfffff800 0x100>; | ||
118 | interrupts = <5 4>; | ||
119 | #gpio-cells = <2>; | ||
120 | gpio-controller; | ||
121 | interrupt-controller; | ||
122 | }; | ||
123 | |||
124 | pioE: gpio@fffffa00 { | ||
125 | compatible = "atmel,at91rm9200-gpio"; | ||
126 | reg = <0xfffffa00 0x100>; | ||
127 | interrupts = <5 4>; | ||
128 | #gpio-cells = <2>; | ||
129 | gpio-controller; | ||
130 | interrupt-controller; | ||
60 | }; | 131 | }; |
61 | 132 | ||
62 | dbgu: serial@ffffee00 { | 133 | dbgu: serial@ffffee00 { |
63 | compatible = "atmel,at91sam9260-usart"; | 134 | compatible = "atmel,at91sam9260-usart"; |
64 | reg = <0xffffee00 0x200>; | 135 | reg = <0xffffee00 0x200>; |
65 | interrupts = <1>; | 136 | interrupts = <1 4>; |
66 | status = "disabled"; | 137 | status = "disabled"; |
67 | }; | 138 | }; |
68 | 139 | ||
69 | usart0: serial@fff8c000 { | 140 | usart0: serial@fff8c000 { |
70 | compatible = "atmel,at91sam9260-usart"; | 141 | compatible = "atmel,at91sam9260-usart"; |
71 | reg = <0xfff8c000 0x200>; | 142 | reg = <0xfff8c000 0x200>; |
72 | interrupts = <7>; | 143 | interrupts = <7 4>; |
73 | atmel,use-dma-rx; | 144 | atmel,use-dma-rx; |
74 | atmel,use-dma-tx; | 145 | atmel,use-dma-tx; |
75 | status = "disabled"; | 146 | status = "disabled"; |
@@ -78,7 +149,7 @@ | |||
78 | usart1: serial@fff90000 { | 149 | usart1: serial@fff90000 { |
79 | compatible = "atmel,at91sam9260-usart"; | 150 | compatible = "atmel,at91sam9260-usart"; |
80 | reg = <0xfff90000 0x200>; | 151 | reg = <0xfff90000 0x200>; |
81 | interrupts = <8>; | 152 | interrupts = <8 4>; |
82 | atmel,use-dma-rx; | 153 | atmel,use-dma-rx; |
83 | atmel,use-dma-tx; | 154 | atmel,use-dma-tx; |
84 | status = "disabled"; | 155 | status = "disabled"; |
@@ -87,7 +158,7 @@ | |||
87 | usart2: serial@fff94000 { | 158 | usart2: serial@fff94000 { |
88 | compatible = "atmel,at91sam9260-usart"; | 159 | compatible = "atmel,at91sam9260-usart"; |
89 | reg = <0xfff94000 0x200>; | 160 | reg = <0xfff94000 0x200>; |
90 | interrupts = <9>; | 161 | interrupts = <9 4>; |
91 | atmel,use-dma-rx; | 162 | atmel,use-dma-rx; |
92 | atmel,use-dma-tx; | 163 | atmel,use-dma-tx; |
93 | status = "disabled"; | 164 | status = "disabled"; |
@@ -96,7 +167,7 @@ | |||
96 | usart3: serial@fff98000 { | 167 | usart3: serial@fff98000 { |
97 | compatible = "atmel,at91sam9260-usart"; | 168 | compatible = "atmel,at91sam9260-usart"; |
98 | reg = <0xfff98000 0x200>; | 169 | reg = <0xfff98000 0x200>; |
99 | interrupts = <10>; | 170 | interrupts = <10 4>; |
100 | atmel,use-dma-rx; | 171 | atmel,use-dma-rx; |
101 | atmel,use-dma-tx; | 172 | atmel,use-dma-tx; |
102 | status = "disabled"; | 173 | status = "disabled"; |
@@ -105,7 +176,7 @@ | |||
105 | macb0: ethernet@fffbc000 { | 176 | macb0: ethernet@fffbc000 { |
106 | compatible = "cdns,at32ap7000-macb", "cdns,macb"; | 177 | compatible = "cdns,at32ap7000-macb", "cdns,macb"; |
107 | reg = <0xfffbc000 0x100>; | 178 | reg = <0xfffbc000 0x100>; |
108 | interrupts = <25>; | 179 | interrupts = <25 4>; |
109 | status = "disabled"; | 180 | status = "disabled"; |
110 | }; | 181 | }; |
111 | }; | 182 | }; |
diff --git a/arch/arm/boot/dts/at91sam9m10g45ek.dts b/arch/arm/boot/dts/at91sam9m10g45ek.dts index a387e7704ce1..15e25f903cad 100644 --- a/arch/arm/boot/dts/at91sam9m10g45ek.dts +++ b/arch/arm/boot/dts/at91sam9m10g45ek.dts | |||
@@ -37,4 +37,76 @@ | |||
37 | }; | 37 | }; |
38 | }; | 38 | }; |
39 | }; | 39 | }; |
40 | |||
41 | leds { | ||
42 | compatible = "gpio-leds"; | ||
43 | |||
44 | d8 { | ||
45 | label = "d8"; | ||
46 | gpios = <&pioD 30 0>; | ||
47 | linux,default-trigger = "heartbeat"; | ||
48 | }; | ||
49 | |||
50 | d6 { | ||
51 | label = "d6"; | ||
52 | gpios = <&pioD 0 1>; | ||
53 | linux,default-trigger = "nand-disk"; | ||
54 | }; | ||
55 | |||
56 | d7 { | ||
57 | label = "d7"; | ||
58 | gpios = <&pioD 31 1>; | ||
59 | linux,default-trigger = "mmc0"; | ||
60 | }; | ||
61 | }; | ||
62 | |||
63 | gpio_keys { | ||
64 | compatible = "gpio-keys"; | ||
65 | #address-cells = <1>; | ||
66 | #size-cells = <0>; | ||
67 | |||
68 | left_click { | ||
69 | label = "left_click"; | ||
70 | gpios = <&pioB 6 1>; | ||
71 | linux,code = <272>; | ||
72 | gpio-key,wakeup; | ||
73 | }; | ||
74 | |||
75 | right_click { | ||
76 | label = "right_click"; | ||
77 | gpios = <&pioB 7 1>; | ||
78 | linux,code = <273>; | ||
79 | gpio-key,wakeup; | ||
80 | }; | ||
81 | |||
82 | left { | ||
83 | label = "Joystick Left"; | ||
84 | gpios = <&pioB 14 1>; | ||
85 | linux,code = <105>; | ||
86 | }; | ||
87 | |||
88 | right { | ||
89 | label = "Joystick Right"; | ||
90 | gpios = <&pioB 15 1>; | ||
91 | linux,code = <106>; | ||
92 | }; | ||
93 | |||
94 | up { | ||
95 | label = "Joystick Up"; | ||
96 | gpios = <&pioB 16 1>; | ||
97 | linux,code = <103>; | ||
98 | }; | ||
99 | |||
100 | down { | ||
101 | label = "Joystick Down"; | ||
102 | gpios = <&pioB 17 1>; | ||
103 | linux,code = <108>; | ||
104 | }; | ||
105 | |||
106 | enter { | ||
107 | label = "Joystick Press"; | ||
108 | gpios = <&pioB 18 1>; | ||
109 | linux,code = <28>; | ||
110 | }; | ||
111 | }; | ||
40 | }; | 112 | }; |
diff --git a/arch/arm/boot/dts/at91sam9x5.dtsi b/arch/arm/boot/dts/at91sam9x5.dtsi index e91391f50730..a02e636d8a57 100644 --- a/arch/arm/boot/dts/at91sam9x5.dtsi +++ b/arch/arm/boot/dts/at91sam9x5.dtsi | |||
@@ -89,35 +89,39 @@ | |||
89 | }; | 89 | }; |
90 | 90 | ||
91 | pioA: gpio@fffff400 { | 91 | pioA: gpio@fffff400 { |
92 | compatible = "atmel,at91rm9200-gpio"; | 92 | compatible = "atmel,at91sam9x5-gpio", "atmel,at91rm9200-gpio"; |
93 | reg = <0xfffff400 0x100>; | 93 | reg = <0xfffff400 0x100>; |
94 | interrupts = <2 4>; | 94 | interrupts = <2 4>; |
95 | #gpio-cells = <2>; | 95 | #gpio-cells = <2>; |
96 | gpio-controller; | 96 | gpio-controller; |
97 | interrupt-controller; | ||
97 | }; | 98 | }; |
98 | 99 | ||
99 | pioB: gpio@fffff600 { | 100 | pioB: gpio@fffff600 { |
100 | compatible = "atmel,at91rm9200-gpio"; | 101 | compatible = "atmel,at91sam9x5-gpio", "atmel,at91rm9200-gpio"; |
101 | reg = <0xfffff600 0x100>; | 102 | reg = <0xfffff600 0x100>; |
102 | interrupts = <2 4>; | 103 | interrupts = <2 4>; |
103 | #gpio-cells = <2>; | 104 | #gpio-cells = <2>; |
104 | gpio-controller; | 105 | gpio-controller; |
106 | interrupt-controller; | ||
105 | }; | 107 | }; |
106 | 108 | ||
107 | pioC: gpio@fffff800 { | 109 | pioC: gpio@fffff800 { |
108 | compatible = "atmel,at91rm9200-gpio"; | 110 | compatible = "atmel,at91sam9x5-gpio", "atmel,at91rm9200-gpio"; |
109 | reg = <0xfffff800 0x100>; | 111 | reg = <0xfffff800 0x100>; |
110 | interrupts = <3 4>; | 112 | interrupts = <3 4>; |
111 | #gpio-cells = <2>; | 113 | #gpio-cells = <2>; |
112 | gpio-controller; | 114 | gpio-controller; |
115 | interrupt-controller; | ||
113 | }; | 116 | }; |
114 | 117 | ||
115 | pioD: gpio@fffffa00 { | 118 | pioD: gpio@fffffa00 { |
116 | compatible = "atmel,at91rm9200-gpio"; | 119 | compatible = "atmel,at91sam9x5-gpio", "atmel,at91rm9200-gpio"; |
117 | reg = <0xfffffa00 0x100>; | 120 | reg = <0xfffffa00 0x100>; |
118 | interrupts = <3 4>; | 121 | interrupts = <3 4>; |
119 | #gpio-cells = <2>; | 122 | #gpio-cells = <2>; |
120 | gpio-controller; | 123 | gpio-controller; |
124 | interrupt-controller; | ||
121 | }; | 125 | }; |
122 | 126 | ||
123 | dbgu: serial@fffff200 { | 127 | dbgu: serial@fffff200 { |
diff --git a/arch/arm/boot/dts/at91sam9x5cm.dtsi b/arch/arm/boot/dts/at91sam9x5cm.dtsi index 4ab5a77f4afc..64ae3e890259 100644 --- a/arch/arm/boot/dts/at91sam9x5cm.dtsi +++ b/arch/arm/boot/dts/at91sam9x5cm.dtsi | |||
@@ -11,4 +11,19 @@ | |||
11 | memory@20000000 { | 11 | memory@20000000 { |
12 | reg = <0x20000000 0x8000000>; | 12 | reg = <0x20000000 0x8000000>; |
13 | }; | 13 | }; |
14 | |||
15 | leds { | ||
16 | compatible = "gpio-leds"; | ||
17 | |||
18 | pb18 { | ||
19 | label = "pb18"; | ||
20 | gpios = <&pioB 18 1>; | ||
21 | linux,default-trigger = "heartbeat"; | ||
22 | }; | ||
23 | |||
24 | pd21 { | ||
25 | label = "pd21"; | ||
26 | gpios = <&pioD 21 0>; | ||
27 | }; | ||
28 | }; | ||
14 | }; | 29 | }; |
diff --git a/arch/arm/boot/dts/usb_a9g20.dts b/arch/arm/boot/dts/usb_a9g20.dts index f04b535477f5..d74545a2a77c 100644 --- a/arch/arm/boot/dts/usb_a9g20.dts +++ b/arch/arm/boot/dts/usb_a9g20.dts | |||
@@ -32,4 +32,27 @@ | |||
32 | }; | 32 | }; |
33 | }; | 33 | }; |
34 | }; | 34 | }; |
35 | |||
36 | leds { | ||
37 | compatible = "gpio-leds"; | ||
38 | |||
39 | user_led { | ||
40 | label = "user_led"; | ||
41 | gpios = <&pioB 21 1>; | ||
42 | linux,default-trigger = "heartbeat"; | ||
43 | }; | ||
44 | }; | ||
45 | |||
46 | gpio_keys { | ||
47 | compatible = "gpio-keys"; | ||
48 | #address-cells = <1>; | ||
49 | #size-cells = <0>; | ||
50 | |||
51 | user_pb { | ||
52 | label = "user_pb"; | ||
53 | gpios = <&pioB 10 1>; | ||
54 | linux,code = <28>; | ||
55 | gpio-key,wakeup; | ||
56 | }; | ||
57 | }; | ||
35 | }; | 58 | }; |
diff --git a/arch/arm/mach-at91/Makefile b/arch/arm/mach-at91/Makefile index 1b6518518d99..8512e53bed93 100644 --- a/arch/arm/mach-at91/Makefile +++ b/arch/arm/mach-at91/Makefile | |||
@@ -20,7 +20,7 @@ obj-$(CONFIG_ARCH_AT91SAM9263) += at91sam9263.o at91sam926x_time.o at91sam9263_d | |||
20 | obj-$(CONFIG_ARCH_AT91SAM9RL) += at91sam9rl.o at91sam926x_time.o at91sam9rl_devices.o sam9_smc.o | 20 | obj-$(CONFIG_ARCH_AT91SAM9RL) += at91sam9rl.o at91sam926x_time.o at91sam9rl_devices.o sam9_smc.o |
21 | obj-$(CONFIG_ARCH_AT91SAM9G20) += at91sam9260.o at91sam926x_time.o at91sam9260_devices.o sam9_smc.o | 21 | obj-$(CONFIG_ARCH_AT91SAM9G20) += at91sam9260.o at91sam926x_time.o at91sam9260_devices.o sam9_smc.o |
22 | obj-$(CONFIG_ARCH_AT91SAM9G45) += at91sam9g45.o at91sam926x_time.o at91sam9g45_devices.o sam9_smc.o | 22 | obj-$(CONFIG_ARCH_AT91SAM9G45) += at91sam9g45.o at91sam926x_time.o at91sam9g45_devices.o sam9_smc.o |
23 | obj-$(CONFIG_ARCH_AT91SAM9X5) += at91sam9x5.o at91sam926x_time.o | 23 | obj-$(CONFIG_ARCH_AT91SAM9X5) += at91sam9x5.o at91sam926x_time.o sam9_smc.o |
24 | obj-$(CONFIG_ARCH_AT91X40) += at91x40.o at91x40_time.o | 24 | obj-$(CONFIG_ARCH_AT91X40) += at91x40.o at91x40_time.o |
25 | 25 | ||
26 | # AT91RM9200 board-specific support | 26 | # AT91RM9200 board-specific support |
diff --git a/arch/arm/mach-at91/at91sam9260.c b/arch/arm/mach-at91/at91sam9260.c index 4ade265be805..14b5a9c9a514 100644 --- a/arch/arm/mach-at91/at91sam9260.c +++ b/arch/arm/mach-at91/at91sam9260.c | |||
@@ -209,6 +209,13 @@ static struct clk_lookup periph_clocks_lookups[] = { | |||
209 | CLKDEV_CON_DEV_ID("usart", "fffd0000.serial", &usart3_clk), | 209 | CLKDEV_CON_DEV_ID("usart", "fffd0000.serial", &usart3_clk), |
210 | CLKDEV_CON_DEV_ID("usart", "fffd4000.serial", &usart4_clk), | 210 | CLKDEV_CON_DEV_ID("usart", "fffd4000.serial", &usart4_clk), |
211 | CLKDEV_CON_DEV_ID("usart", "fffd8000.serial", &usart5_clk), | 211 | CLKDEV_CON_DEV_ID("usart", "fffd8000.serial", &usart5_clk), |
212 | /* more tc lookup table for DT entries */ | ||
213 | CLKDEV_CON_DEV_ID("t0_clk", "fffa0000.timer", &tc0_clk), | ||
214 | CLKDEV_CON_DEV_ID("t1_clk", "fffa0000.timer", &tc1_clk), | ||
215 | CLKDEV_CON_DEV_ID("t2_clk", "fffa0000.timer", &tc2_clk), | ||
216 | CLKDEV_CON_DEV_ID("t0_clk", "fffdc000.timer", &tc3_clk), | ||
217 | CLKDEV_CON_DEV_ID("t1_clk", "fffdc000.timer", &tc4_clk), | ||
218 | CLKDEV_CON_DEV_ID("t2_clk", "fffdc000.timer", &tc5_clk), | ||
212 | /* fake hclk clock */ | 219 | /* fake hclk clock */ |
213 | CLKDEV_CON_DEV_ID("hclk", "at91_ohci", &ohci_clk), | 220 | CLKDEV_CON_DEV_ID("hclk", "at91_ohci", &ohci_clk), |
214 | CLKDEV_CON_ID("pioA", &pioA_clk), | 221 | CLKDEV_CON_ID("pioA", &pioA_clk), |
diff --git a/arch/arm/mach-at91/at91sam9260_devices.c b/arch/arm/mach-at91/at91sam9260_devices.c index 40f6aeaea043..7e5651ee9f85 100644 --- a/arch/arm/mach-at91/at91sam9260_devices.c +++ b/arch/arm/mach-at91/at91sam9260_devices.c | |||
@@ -642,7 +642,7 @@ void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices) | |||
642 | static struct resource tcb0_resources[] = { | 642 | static struct resource tcb0_resources[] = { |
643 | [0] = { | 643 | [0] = { |
644 | .start = AT91SAM9260_BASE_TCB0, | 644 | .start = AT91SAM9260_BASE_TCB0, |
645 | .end = AT91SAM9260_BASE_TCB0 + SZ_16K - 1, | 645 | .end = AT91SAM9260_BASE_TCB0 + SZ_256 - 1, |
646 | .flags = IORESOURCE_MEM, | 646 | .flags = IORESOURCE_MEM, |
647 | }, | 647 | }, |
648 | [1] = { | 648 | [1] = { |
@@ -672,7 +672,7 @@ static struct platform_device at91sam9260_tcb0_device = { | |||
672 | static struct resource tcb1_resources[] = { | 672 | static struct resource tcb1_resources[] = { |
673 | [0] = { | 673 | [0] = { |
674 | .start = AT91SAM9260_BASE_TCB1, | 674 | .start = AT91SAM9260_BASE_TCB1, |
675 | .end = AT91SAM9260_BASE_TCB1 + SZ_16K - 1, | 675 | .end = AT91SAM9260_BASE_TCB1 + SZ_256 - 1, |
676 | .flags = IORESOURCE_MEM, | 676 | .flags = IORESOURCE_MEM, |
677 | }, | 677 | }, |
678 | [1] = { | 678 | [1] = { |
@@ -699,8 +699,25 @@ static struct platform_device at91sam9260_tcb1_device = { | |||
699 | .num_resources = ARRAY_SIZE(tcb1_resources), | 699 | .num_resources = ARRAY_SIZE(tcb1_resources), |
700 | }; | 700 | }; |
701 | 701 | ||
702 | #if defined(CONFIG_OF) | ||
703 | static struct of_device_id tcb_ids[] = { | ||
704 | { .compatible = "atmel,at91rm9200-tcb" }, | ||
705 | { /*sentinel*/ } | ||
706 | }; | ||
707 | #endif | ||
708 | |||
702 | static void __init at91_add_device_tc(void) | 709 | static void __init at91_add_device_tc(void) |
703 | { | 710 | { |
711 | #if defined(CONFIG_OF) | ||
712 | struct device_node *np; | ||
713 | |||
714 | np = of_find_matching_node(NULL, tcb_ids); | ||
715 | if (np) { | ||
716 | of_node_put(np); | ||
717 | return; | ||
718 | } | ||
719 | #endif | ||
720 | |||
704 | platform_device_register(&at91sam9260_tcb0_device); | 721 | platform_device_register(&at91sam9260_tcb0_device); |
705 | platform_device_register(&at91sam9260_tcb1_device); | 722 | platform_device_register(&at91sam9260_tcb1_device); |
706 | } | 723 | } |
diff --git a/arch/arm/mach-at91/at91sam926x_time.c b/arch/arm/mach-at91/at91sam926x_time.c index d89ead740a99..a94758b42737 100644 --- a/arch/arm/mach-at91/at91sam926x_time.c +++ b/arch/arm/mach-at91/at91sam926x_time.c | |||
@@ -14,6 +14,9 @@ | |||
14 | #include <linux/kernel.h> | 14 | #include <linux/kernel.h> |
15 | #include <linux/clk.h> | 15 | #include <linux/clk.h> |
16 | #include <linux/clockchips.h> | 16 | #include <linux/clockchips.h> |
17 | #include <linux/of.h> | ||
18 | #include <linux/of_address.h> | ||
19 | #include <linux/of_irq.h> | ||
17 | 20 | ||
18 | #include <asm/mach/time.h> | 21 | #include <asm/mach/time.h> |
19 | 22 | ||
@@ -133,7 +136,8 @@ static irqreturn_t at91sam926x_pit_interrupt(int irq, void *dev_id) | |||
133 | static struct irqaction at91sam926x_pit_irq = { | 136 | static struct irqaction at91sam926x_pit_irq = { |
134 | .name = "at91_tick", | 137 | .name = "at91_tick", |
135 | .flags = IRQF_SHARED | IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, | 138 | .flags = IRQF_SHARED | IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, |
136 | .handler = at91sam926x_pit_interrupt | 139 | .handler = at91sam926x_pit_interrupt, |
140 | .irq = AT91_ID_SYS, | ||
137 | }; | 141 | }; |
138 | 142 | ||
139 | static void at91sam926x_pit_reset(void) | 143 | static void at91sam926x_pit_reset(void) |
@@ -149,6 +153,51 @@ static void at91sam926x_pit_reset(void) | |||
149 | pit_write(AT91_PIT_MR, (pit_cycle - 1) | AT91_PIT_PITEN); | 153 | pit_write(AT91_PIT_MR, (pit_cycle - 1) | AT91_PIT_PITEN); |
150 | } | 154 | } |
151 | 155 | ||
156 | #ifdef CONFIG_OF | ||
157 | static struct of_device_id pit_timer_ids[] = { | ||
158 | { .compatible = "atmel,at91sam9260-pit" }, | ||
159 | { /* sentinel */ } | ||
160 | }; | ||
161 | |||
162 | static int __init of_at91sam926x_pit_init(void) | ||
163 | { | ||
164 | struct device_node *np; | ||
165 | int ret; | ||
166 | |||
167 | np = of_find_matching_node(NULL, pit_timer_ids); | ||
168 | if (!np) | ||
169 | goto err; | ||
170 | |||
171 | pit_base_addr = of_iomap(np, 0); | ||
172 | if (!pit_base_addr) | ||
173 | goto node_err; | ||
174 | |||
175 | /* Get the interrupts property */ | ||
176 | ret = irq_of_parse_and_map(np, 0); | ||
177 | if (!ret) { | ||
178 | pr_crit("AT91: PIT: Unable to get IRQ from DT\n"); | ||
179 | goto ioremap_err; | ||
180 | } | ||
181 | at91sam926x_pit_irq.irq = ret; | ||
182 | |||
183 | of_node_put(np); | ||
184 | |||
185 | return 0; | ||
186 | |||
187 | ioremap_err: | ||
188 | iounmap(pit_base_addr); | ||
189 | node_err: | ||
190 | of_node_put(np); | ||
191 | err: | ||
192 | return -EINVAL; | ||
193 | } | ||
194 | #else | ||
195 | static int __init of_at91sam926x_pit_init(void) | ||
196 | { | ||
197 | return -EINVAL; | ||
198 | } | ||
199 | #endif | ||
200 | |||
152 | /* | 201 | /* |
153 | * Set up both clocksource and clockevent support. | 202 | * Set up both clocksource and clockevent support. |
154 | */ | 203 | */ |
@@ -156,6 +205,10 @@ static void __init at91sam926x_pit_init(void) | |||
156 | { | 205 | { |
157 | unsigned long pit_rate; | 206 | unsigned long pit_rate; |
158 | unsigned bits; | 207 | unsigned bits; |
208 | int ret; | ||
209 | |||
210 | /* For device tree enabled device: initialize here */ | ||
211 | of_at91sam926x_pit_init(); | ||
159 | 212 | ||
160 | /* | 213 | /* |
161 | * Use our actual MCK to figure out how many MCK/16 ticks per | 214 | * Use our actual MCK to figure out how many MCK/16 ticks per |
@@ -177,7 +230,9 @@ static void __init at91sam926x_pit_init(void) | |||
177 | clocksource_register_hz(&pit_clk, pit_rate); | 230 | clocksource_register_hz(&pit_clk, pit_rate); |
178 | 231 | ||
179 | /* Set up irq handler */ | 232 | /* Set up irq handler */ |
180 | setup_irq(AT91_ID_SYS, &at91sam926x_pit_irq); | 233 | ret = setup_irq(at91sam926x_pit_irq.irq, &at91sam926x_pit_irq); |
234 | if (ret) | ||
235 | pr_crit("AT91: PIT: Unable to setup IRQ\n"); | ||
181 | 236 | ||
182 | /* Set up and register clockevents */ | 237 | /* Set up and register clockevents */ |
183 | pit_clkevt.mult = div_sc(pit_rate, NSEC_PER_SEC, pit_clkevt.shift); | 238 | pit_clkevt.mult = div_sc(pit_rate, NSEC_PER_SEC, pit_clkevt.shift); |
@@ -193,6 +248,15 @@ static void at91sam926x_pit_suspend(void) | |||
193 | 248 | ||
194 | void __init at91sam926x_ioremap_pit(u32 addr) | 249 | void __init at91sam926x_ioremap_pit(u32 addr) |
195 | { | 250 | { |
251 | #if defined(CONFIG_OF) | ||
252 | struct device_node *np = | ||
253 | of_find_matching_node(NULL, pit_timer_ids); | ||
254 | |||
255 | if (np) { | ||
256 | of_node_put(np); | ||
257 | return; | ||
258 | } | ||
259 | #endif | ||
196 | pit_base_addr = ioremap(addr, 16); | 260 | pit_base_addr = ioremap(addr, 16); |
197 | 261 | ||
198 | if (!pit_base_addr) | 262 | if (!pit_base_addr) |
diff --git a/arch/arm/mach-at91/at91sam9g45.c b/arch/arm/mach-at91/at91sam9g45.c index a41622ea61b8..0014573dfe17 100644 --- a/arch/arm/mach-at91/at91sam9g45.c +++ b/arch/arm/mach-at91/at91sam9g45.c | |||
@@ -229,6 +229,9 @@ static struct clk_lookup periph_clocks_lookups[] = { | |||
229 | CLKDEV_CON_DEV_ID("usart", "fff90000.serial", &usart1_clk), | 229 | CLKDEV_CON_DEV_ID("usart", "fff90000.serial", &usart1_clk), |
230 | CLKDEV_CON_DEV_ID("usart", "fff94000.serial", &usart2_clk), | 230 | CLKDEV_CON_DEV_ID("usart", "fff94000.serial", &usart2_clk), |
231 | CLKDEV_CON_DEV_ID("usart", "fff98000.serial", &usart3_clk), | 231 | CLKDEV_CON_DEV_ID("usart", "fff98000.serial", &usart3_clk), |
232 | /* more tc lookup table for DT entries */ | ||
233 | CLKDEV_CON_DEV_ID("t0_clk", "fff7c000.timer", &tcb0_clk), | ||
234 | CLKDEV_CON_DEV_ID("t0_clk", "fffd4000.timer", &tcb0_clk), | ||
232 | /* fake hclk clock */ | 235 | /* fake hclk clock */ |
233 | CLKDEV_CON_DEV_ID("hclk", "at91_ohci", &uhphs_clk), | 236 | CLKDEV_CON_DEV_ID("hclk", "at91_ohci", &uhphs_clk), |
234 | CLKDEV_CON_ID("pioA", &pioA_clk), | 237 | CLKDEV_CON_ID("pioA", &pioA_clk), |
diff --git a/arch/arm/mach-at91/at91sam9g45_devices.c b/arch/arm/mach-at91/at91sam9g45_devices.c index 410829532aab..4320b2096789 100644 --- a/arch/arm/mach-at91/at91sam9g45_devices.c +++ b/arch/arm/mach-at91/at91sam9g45_devices.c | |||
@@ -1052,7 +1052,7 @@ void __init at91_add_device_lcdc(struct atmel_lcdfb_info *data) {} | |||
1052 | static struct resource tcb0_resources[] = { | 1052 | static struct resource tcb0_resources[] = { |
1053 | [0] = { | 1053 | [0] = { |
1054 | .start = AT91SAM9G45_BASE_TCB0, | 1054 | .start = AT91SAM9G45_BASE_TCB0, |
1055 | .end = AT91SAM9G45_BASE_TCB0 + SZ_16K - 1, | 1055 | .end = AT91SAM9G45_BASE_TCB0 + SZ_256 - 1, |
1056 | .flags = IORESOURCE_MEM, | 1056 | .flags = IORESOURCE_MEM, |
1057 | }, | 1057 | }, |
1058 | [1] = { | 1058 | [1] = { |
@@ -1073,7 +1073,7 @@ static struct platform_device at91sam9g45_tcb0_device = { | |||
1073 | static struct resource tcb1_resources[] = { | 1073 | static struct resource tcb1_resources[] = { |
1074 | [0] = { | 1074 | [0] = { |
1075 | .start = AT91SAM9G45_BASE_TCB1, | 1075 | .start = AT91SAM9G45_BASE_TCB1, |
1076 | .end = AT91SAM9G45_BASE_TCB1 + SZ_16K - 1, | 1076 | .end = AT91SAM9G45_BASE_TCB1 + SZ_256 - 1, |
1077 | .flags = IORESOURCE_MEM, | 1077 | .flags = IORESOURCE_MEM, |
1078 | }, | 1078 | }, |
1079 | [1] = { | 1079 | [1] = { |
@@ -1090,8 +1090,25 @@ static struct platform_device at91sam9g45_tcb1_device = { | |||
1090 | .num_resources = ARRAY_SIZE(tcb1_resources), | 1090 | .num_resources = ARRAY_SIZE(tcb1_resources), |
1091 | }; | 1091 | }; |
1092 | 1092 | ||
1093 | #if defined(CONFIG_OF) | ||
1094 | static struct of_device_id tcb_ids[] = { | ||
1095 | { .compatible = "atmel,at91rm9200-tcb" }, | ||
1096 | { /*sentinel*/ } | ||
1097 | }; | ||
1098 | #endif | ||
1099 | |||
1093 | static void __init at91_add_device_tc(void) | 1100 | static void __init at91_add_device_tc(void) |
1094 | { | 1101 | { |
1102 | #if defined(CONFIG_OF) | ||
1103 | struct device_node *np; | ||
1104 | |||
1105 | np = of_find_matching_node(NULL, tcb_ids); | ||
1106 | if (np) { | ||
1107 | of_node_put(np); | ||
1108 | return; | ||
1109 | } | ||
1110 | #endif | ||
1111 | |||
1095 | platform_device_register(&at91sam9g45_tcb0_device); | 1112 | platform_device_register(&at91sam9g45_tcb0_device); |
1096 | platform_device_register(&at91sam9g45_tcb1_device); | 1113 | platform_device_register(&at91sam9g45_tcb1_device); |
1097 | } | 1114 | } |
diff --git a/arch/arm/mach-at91/at91sam9x5.c b/arch/arm/mach-at91/at91sam9x5.c index d17d4262665b..a34d96afa746 100644 --- a/arch/arm/mach-at91/at91sam9x5.c +++ b/arch/arm/mach-at91/at91sam9x5.c | |||
@@ -301,8 +301,6 @@ static void __init at91sam9x5_map_io(void) | |||
301 | 301 | ||
302 | static void __init at91sam9x5_ioremap_registers(void) | 302 | static void __init at91sam9x5_ioremap_registers(void) |
303 | { | 303 | { |
304 | if (of_at91sam926x_pit_init() < 0) | ||
305 | panic("Impossible to find PIT\n"); | ||
306 | at91_ioremap_ramc(0, AT91SAM9X5_BASE_DDRSDRC0, 512); | 304 | at91_ioremap_ramc(0, AT91SAM9X5_BASE_DDRSDRC0, 512); |
307 | } | 305 | } |
308 | 306 | ||
diff --git a/arch/arm/mach-at91/board-dt.c b/arch/arm/mach-at91/board-dt.c index 08c8ad8609b7..583b72472ad9 100644 --- a/arch/arm/mach-at91/board-dt.c +++ b/arch/arm/mach-at91/board-dt.c | |||
@@ -15,7 +15,7 @@ | |||
15 | #include <linux/init.h> | 15 | #include <linux/init.h> |
16 | #include <linux/module.h> | 16 | #include <linux/module.h> |
17 | #include <linux/gpio.h> | 17 | #include <linux/gpio.h> |
18 | #include <linux/irqdomain.h> | 18 | #include <linux/of.h> |
19 | #include <linux/of_irq.h> | 19 | #include <linux/of_irq.h> |
20 | #include <linux/of_platform.h> | 20 | #include <linux/of_platform.h> |
21 | 21 | ||
@@ -82,15 +82,17 @@ static void __init ek_add_device_nand(void) | |||
82 | at91_add_device_nand(&ek_nand_data); | 82 | at91_add_device_nand(&ek_nand_data); |
83 | } | 83 | } |
84 | 84 | ||
85 | static const struct of_device_id aic_of_match[] __initconst = { | 85 | static const struct of_device_id irq_of_match[] __initconst = { |
86 | { .compatible = "atmel,at91rm9200-aic", }, | 86 | |
87 | {}, | 87 | { .compatible = "atmel,at91rm9200-aic", .data = at91_aic_of_init }, |
88 | { .compatible = "atmel,at91rm9200-gpio", .data = at91_gpio_of_irq_setup }, | ||
89 | { .compatible = "atmel,at91sam9x5-gpio", .data = at91_gpio_of_irq_setup }, | ||
90 | { /*sentinel*/ } | ||
88 | }; | 91 | }; |
89 | 92 | ||
90 | static void __init at91_dt_init_irq(void) | 93 | static void __init at91_dt_init_irq(void) |
91 | { | 94 | { |
92 | irq_domain_generate_simple(aic_of_match, 0xfffff000, 0); | 95 | of_irq_init(irq_of_match); |
93 | at91_init_irq_default(); | ||
94 | } | 96 | } |
95 | 97 | ||
96 | static void __init at91_dt_device_init(void) | 98 | static void __init at91_dt_device_init(void) |
diff --git a/arch/arm/mach-at91/board-snapper9260.c b/arch/arm/mach-at91/board-snapper9260.c index 4770db08e5a6..3c2e3fcc310c 100644 --- a/arch/arm/mach-at91/board-snapper9260.c +++ b/arch/arm/mach-at91/board-snapper9260.c | |||
@@ -145,11 +145,11 @@ static struct i2c_board_info __initdata snapper9260_i2c_devices[] = { | |||
145 | /* Audio codec */ | 145 | /* Audio codec */ |
146 | I2C_BOARD_INFO("tlv320aic23", 0x1a), | 146 | I2C_BOARD_INFO("tlv320aic23", 0x1a), |
147 | }, | 147 | }, |
148 | { | 148 | }; |
149 | |||
150 | static struct i2c_board_info __initdata snapper9260_i2c_isl1208 = { | ||
149 | /* RTC */ | 151 | /* RTC */ |
150 | I2C_BOARD_INFO("isl1208", 0x6f), | 152 | I2C_BOARD_INFO("isl1208", 0x6f), |
151 | .irq = gpio_to_irq(AT91_PIN_PA31), | ||
152 | }, | ||
153 | }; | 153 | }; |
154 | 154 | ||
155 | static void __init snapper9260_add_device_nand(void) | 155 | static void __init snapper9260_add_device_nand(void) |
@@ -163,6 +163,10 @@ static void __init snapper9260_board_init(void) | |||
163 | { | 163 | { |
164 | at91_add_device_i2c(snapper9260_i2c_devices, | 164 | at91_add_device_i2c(snapper9260_i2c_devices, |
165 | ARRAY_SIZE(snapper9260_i2c_devices)); | 165 | ARRAY_SIZE(snapper9260_i2c_devices)); |
166 | |||
167 | snapper9260_i2c_isl1208.irq = gpio_to_irq(AT91_PIN_PA31); | ||
168 | i2c_register_board_info(0, &snapper9260_i2c_isl1208, 1); | ||
169 | |||
166 | at91_add_device_serial(); | 170 | at91_add_device_serial(); |
167 | at91_add_device_usbh(&snapper9260_usbh_data); | 171 | at91_add_device_usbh(&snapper9260_usbh_data); |
168 | at91_add_device_udc(&snapper9260_udc_data); | 172 | at91_add_device_udc(&snapper9260_udc_data); |
diff --git a/arch/arm/mach-at91/generic.h b/arch/arm/mach-at91/generic.h index 4cad85e57470..459f01a4a546 100644 --- a/arch/arm/mach-at91/generic.h +++ b/arch/arm/mach-at91/generic.h | |||
@@ -9,6 +9,7 @@ | |||
9 | */ | 9 | */ |
10 | 10 | ||
11 | #include <linux/clkdev.h> | 11 | #include <linux/clkdev.h> |
12 | #include <linux/of.h> | ||
12 | 13 | ||
13 | /* Map io */ | 14 | /* Map io */ |
14 | extern void __init at91_map_io(void); | 15 | extern void __init at91_map_io(void); |
@@ -25,6 +26,9 @@ extern void __init at91_init_irq_default(void); | |||
25 | extern void __init at91_init_interrupts(unsigned int priority[]); | 26 | extern void __init at91_init_interrupts(unsigned int priority[]); |
26 | extern void __init at91x40_init_interrupts(unsigned int priority[]); | 27 | extern void __init at91x40_init_interrupts(unsigned int priority[]); |
27 | extern void __init at91_aic_init(unsigned int priority[]); | 28 | extern void __init at91_aic_init(unsigned int priority[]); |
29 | extern int __init at91_aic_of_init(struct device_node *node, | ||
30 | struct device_node *parent); | ||
31 | |||
28 | 32 | ||
29 | /* Timer */ | 33 | /* Timer */ |
30 | struct sys_timer; | 34 | struct sys_timer; |
@@ -84,5 +88,7 @@ struct at91_gpio_bank { | |||
84 | }; | 88 | }; |
85 | extern void __init at91_gpio_init(struct at91_gpio_bank *, int nr_banks); | 89 | extern void __init at91_gpio_init(struct at91_gpio_bank *, int nr_banks); |
86 | extern void __init at91_gpio_irq_setup(void); | 90 | extern void __init at91_gpio_irq_setup(void); |
91 | extern int __init at91_gpio_of_irq_setup(struct device_node *node, | ||
92 | struct device_node *parent); | ||
87 | 93 | ||
88 | extern int at91_extern_irq; | 94 | extern int at91_extern_irq; |
diff --git a/arch/arm/mach-at91/gpio.c b/arch/arm/mach-at91/gpio.c index 74d6783eeabb..325837a264c9 100644 --- a/arch/arm/mach-at91/gpio.c +++ b/arch/arm/mach-at91/gpio.c | |||
@@ -11,6 +11,7 @@ | |||
11 | 11 | ||
12 | #include <linux/clk.h> | 12 | #include <linux/clk.h> |
13 | #include <linux/errno.h> | 13 | #include <linux/errno.h> |
14 | #include <linux/device.h> | ||
14 | #include <linux/gpio.h> | 15 | #include <linux/gpio.h> |
15 | #include <linux/interrupt.h> | 16 | #include <linux/interrupt.h> |
16 | #include <linux/irq.h> | 17 | #include <linux/irq.h> |
@@ -20,6 +21,10 @@ | |||
20 | #include <linux/list.h> | 21 | #include <linux/list.h> |
21 | #include <linux/module.h> | 22 | #include <linux/module.h> |
22 | #include <linux/io.h> | 23 | #include <linux/io.h> |
24 | #include <linux/irqdomain.h> | ||
25 | #include <linux/of_address.h> | ||
26 | #include <linux/of_irq.h> | ||
27 | #include <linux/of_gpio.h> | ||
23 | 28 | ||
24 | #include <mach/hardware.h> | 29 | #include <mach/hardware.h> |
25 | #include <mach/at91_pio.h> | 30 | #include <mach/at91_pio.h> |
@@ -29,9 +34,12 @@ | |||
29 | struct at91_gpio_chip { | 34 | struct at91_gpio_chip { |
30 | struct gpio_chip chip; | 35 | struct gpio_chip chip; |
31 | struct at91_gpio_chip *next; /* Bank sharing same clock */ | 36 | struct at91_gpio_chip *next; /* Bank sharing same clock */ |
32 | int id; /* ID of register bank */ | 37 | int pioc_hwirq; /* PIO bank interrupt identifier on AIC */ |
33 | void __iomem *regbase; /* Base of register bank */ | 38 | int pioc_virq; /* PIO bank Linux virtual interrupt */ |
39 | int pioc_idx; /* PIO bank index */ | ||
40 | void __iomem *regbase; /* PIO bank virtual address */ | ||
34 | struct clk *clock; /* associated clock */ | 41 | struct clk *clock; /* associated clock */ |
42 | struct irq_domain *domain; /* associated irq domain */ | ||
35 | }; | 43 | }; |
36 | 44 | ||
37 | #define to_at91_gpio_chip(c) container_of(c, struct at91_gpio_chip, chip) | 45 | #define to_at91_gpio_chip(c) container_of(c, struct at91_gpio_chip, chip) |
@@ -43,8 +51,9 @@ static int at91_gpiolib_direction_output(struct gpio_chip *chip, | |||
43 | unsigned offset, int val); | 51 | unsigned offset, int val); |
44 | static int at91_gpiolib_direction_input(struct gpio_chip *chip, | 52 | static int at91_gpiolib_direction_input(struct gpio_chip *chip, |
45 | unsigned offset); | 53 | unsigned offset); |
54 | static int at91_gpiolib_to_irq(struct gpio_chip *chip, unsigned offset); | ||
46 | 55 | ||
47 | #define AT91_GPIO_CHIP(name, base_gpio, nr_gpio) \ | 56 | #define AT91_GPIO_CHIP(name, nr_gpio) \ |
48 | { \ | 57 | { \ |
49 | .chip = { \ | 58 | .chip = { \ |
50 | .label = name, \ | 59 | .label = name, \ |
@@ -53,20 +62,28 @@ static int at91_gpiolib_direction_input(struct gpio_chip *chip, | |||
53 | .get = at91_gpiolib_get, \ | 62 | .get = at91_gpiolib_get, \ |
54 | .set = at91_gpiolib_set, \ | 63 | .set = at91_gpiolib_set, \ |
55 | .dbg_show = at91_gpiolib_dbg_show, \ | 64 | .dbg_show = at91_gpiolib_dbg_show, \ |
56 | .base = base_gpio, \ | 65 | .to_irq = at91_gpiolib_to_irq, \ |
57 | .ngpio = nr_gpio, \ | 66 | .ngpio = nr_gpio, \ |
58 | }, \ | 67 | }, \ |
59 | } | 68 | } |
60 | 69 | ||
61 | static struct at91_gpio_chip gpio_chip[] = { | 70 | static struct at91_gpio_chip gpio_chip[] = { |
62 | AT91_GPIO_CHIP("pioA", 0x00, 32), | 71 | AT91_GPIO_CHIP("pioA", 32), |
63 | AT91_GPIO_CHIP("pioB", 0x20, 32), | 72 | AT91_GPIO_CHIP("pioB", 32), |
64 | AT91_GPIO_CHIP("pioC", 0x40, 32), | 73 | AT91_GPIO_CHIP("pioC", 32), |
65 | AT91_GPIO_CHIP("pioD", 0x60, 32), | 74 | AT91_GPIO_CHIP("pioD", 32), |
66 | AT91_GPIO_CHIP("pioE", 0x80, 32), | 75 | AT91_GPIO_CHIP("pioE", 32), |
67 | }; | 76 | }; |
68 | 77 | ||
69 | static int gpio_banks; | 78 | static int gpio_banks; |
79 | static unsigned long at91_gpio_caps; | ||
80 | |||
81 | /* All PIO controllers support PIO3 features */ | ||
82 | #define AT91_GPIO_CAP_PIO3 (1 << 0) | ||
83 | |||
84 | #define has_pio3() (at91_gpio_caps & AT91_GPIO_CAP_PIO3) | ||
85 | |||
86 | /*--------------------------------------------------------------------------*/ | ||
70 | 87 | ||
71 | static inline void __iomem *pin_to_controller(unsigned pin) | 88 | static inline void __iomem *pin_to_controller(unsigned pin) |
72 | { | 89 | { |
@@ -83,6 +100,25 @@ static inline unsigned pin_to_mask(unsigned pin) | |||
83 | } | 100 | } |
84 | 101 | ||
85 | 102 | ||
103 | static char peripheral_function(void __iomem *pio, unsigned mask) | ||
104 | { | ||
105 | char ret = 'X'; | ||
106 | u8 select; | ||
107 | |||
108 | if (pio) { | ||
109 | if (has_pio3()) { | ||
110 | select = !!(__raw_readl(pio + PIO_ABCDSR1) & mask); | ||
111 | select |= (!!(__raw_readl(pio + PIO_ABCDSR2) & mask) << 1); | ||
112 | ret = 'A' + select; | ||
113 | } else { | ||
114 | ret = __raw_readl(pio + PIO_ABSR) & mask ? | ||
115 | 'B' : 'A'; | ||
116 | } | ||
117 | } | ||
118 | |||
119 | return ret; | ||
120 | } | ||
121 | |||
86 | /*--------------------------------------------------------------------------*/ | 122 | /*--------------------------------------------------------------------------*/ |
87 | 123 | ||
88 | /* Not all hardware capabilities are exposed through these calls; they | 124 | /* Not all hardware capabilities are exposed through these calls; they |
@@ -130,7 +166,14 @@ int __init_or_module at91_set_A_periph(unsigned pin, int use_pullup) | |||
130 | 166 | ||
131 | __raw_writel(mask, pio + PIO_IDR); | 167 | __raw_writel(mask, pio + PIO_IDR); |
132 | __raw_writel(mask, pio + (use_pullup ? PIO_PUER : PIO_PUDR)); | 168 | __raw_writel(mask, pio + (use_pullup ? PIO_PUER : PIO_PUDR)); |
133 | __raw_writel(mask, pio + PIO_ASR); | 169 | if (has_pio3()) { |
170 | __raw_writel(__raw_readl(pio + PIO_ABCDSR1) & ~mask, | ||
171 | pio + PIO_ABCDSR1); | ||
172 | __raw_writel(__raw_readl(pio + PIO_ABCDSR2) & ~mask, | ||
173 | pio + PIO_ABCDSR2); | ||
174 | } else { | ||
175 | __raw_writel(mask, pio + PIO_ASR); | ||
176 | } | ||
134 | __raw_writel(mask, pio + PIO_PDR); | 177 | __raw_writel(mask, pio + PIO_PDR); |
135 | return 0; | 178 | return 0; |
136 | } | 179 | } |
@@ -150,7 +193,14 @@ int __init_or_module at91_set_B_periph(unsigned pin, int use_pullup) | |||
150 | 193 | ||
151 | __raw_writel(mask, pio + PIO_IDR); | 194 | __raw_writel(mask, pio + PIO_IDR); |
152 | __raw_writel(mask, pio + (use_pullup ? PIO_PUER : PIO_PUDR)); | 195 | __raw_writel(mask, pio + (use_pullup ? PIO_PUER : PIO_PUDR)); |
153 | __raw_writel(mask, pio + PIO_BSR); | 196 | if (has_pio3()) { |
197 | __raw_writel(__raw_readl(pio + PIO_ABCDSR1) | mask, | ||
198 | pio + PIO_ABCDSR1); | ||
199 | __raw_writel(__raw_readl(pio + PIO_ABCDSR2) & ~mask, | ||
200 | pio + PIO_ABCDSR2); | ||
201 | } else { | ||
202 | __raw_writel(mask, pio + PIO_BSR); | ||
203 | } | ||
154 | __raw_writel(mask, pio + PIO_PDR); | 204 | __raw_writel(mask, pio + PIO_PDR); |
155 | return 0; | 205 | return 0; |
156 | } | 206 | } |
@@ -158,8 +208,50 @@ EXPORT_SYMBOL(at91_set_B_periph); | |||
158 | 208 | ||
159 | 209 | ||
160 | /* | 210 | /* |
161 | * mux the pin to the gpio controller (instead of "A" or "B" peripheral), and | 211 | * mux the pin to the "C" internal peripheral role. |
162 | * configure it for an input. | 212 | */ |
213 | int __init_or_module at91_set_C_periph(unsigned pin, int use_pullup) | ||
214 | { | ||
215 | void __iomem *pio = pin_to_controller(pin); | ||
216 | unsigned mask = pin_to_mask(pin); | ||
217 | |||
218 | if (!pio || !has_pio3()) | ||
219 | return -EINVAL; | ||
220 | |||
221 | __raw_writel(mask, pio + PIO_IDR); | ||
222 | __raw_writel(mask, pio + (use_pullup ? PIO_PUER : PIO_PUDR)); | ||
223 | __raw_writel(__raw_readl(pio + PIO_ABCDSR1) & ~mask, pio + PIO_ABCDSR1); | ||
224 | __raw_writel(__raw_readl(pio + PIO_ABCDSR2) | mask, pio + PIO_ABCDSR2); | ||
225 | __raw_writel(mask, pio + PIO_PDR); | ||
226 | return 0; | ||
227 | } | ||
228 | EXPORT_SYMBOL(at91_set_C_periph); | ||
229 | |||
230 | |||
231 | /* | ||
232 | * mux the pin to the "D" internal peripheral role. | ||
233 | */ | ||
234 | int __init_or_module at91_set_D_periph(unsigned pin, int use_pullup) | ||
235 | { | ||
236 | void __iomem *pio = pin_to_controller(pin); | ||
237 | unsigned mask = pin_to_mask(pin); | ||
238 | |||
239 | if (!pio || !has_pio3()) | ||
240 | return -EINVAL; | ||
241 | |||
242 | __raw_writel(mask, pio + PIO_IDR); | ||
243 | __raw_writel(mask, pio + (use_pullup ? PIO_PUER : PIO_PUDR)); | ||
244 | __raw_writel(__raw_readl(pio + PIO_ABCDSR1) | mask, pio + PIO_ABCDSR1); | ||
245 | __raw_writel(__raw_readl(pio + PIO_ABCDSR2) | mask, pio + PIO_ABCDSR2); | ||
246 | __raw_writel(mask, pio + PIO_PDR); | ||
247 | return 0; | ||
248 | } | ||
249 | EXPORT_SYMBOL(at91_set_D_periph); | ||
250 | |||
251 | |||
252 | /* | ||
253 | * mux the pin to the gpio controller (instead of "A", "B", "C" | ||
254 | * or "D" peripheral), and configure it for an input. | ||
163 | */ | 255 | */ |
164 | int __init_or_module at91_set_gpio_input(unsigned pin, int use_pullup) | 256 | int __init_or_module at91_set_gpio_input(unsigned pin, int use_pullup) |
165 | { | 257 | { |
@@ -179,8 +271,8 @@ EXPORT_SYMBOL(at91_set_gpio_input); | |||
179 | 271 | ||
180 | 272 | ||
181 | /* | 273 | /* |
182 | * mux the pin to the gpio controller (instead of "A" or "B" peripheral), | 274 | * mux the pin to the gpio controller (instead of "A", "B", "C" |
183 | * and configure it for an output. | 275 | * or "D" peripheral), and configure it for an output. |
184 | */ | 276 | */ |
185 | int __init_or_module at91_set_gpio_output(unsigned pin, int value) | 277 | int __init_or_module at91_set_gpio_output(unsigned pin, int value) |
186 | { | 278 | { |
@@ -210,12 +302,37 @@ int __init_or_module at91_set_deglitch(unsigned pin, int is_on) | |||
210 | 302 | ||
211 | if (!pio) | 303 | if (!pio) |
212 | return -EINVAL; | 304 | return -EINVAL; |
305 | |||
306 | if (has_pio3() && is_on) | ||
307 | __raw_writel(mask, pio + PIO_IFSCDR); | ||
213 | __raw_writel(mask, pio + (is_on ? PIO_IFER : PIO_IFDR)); | 308 | __raw_writel(mask, pio + (is_on ? PIO_IFER : PIO_IFDR)); |
214 | return 0; | 309 | return 0; |
215 | } | 310 | } |
216 | EXPORT_SYMBOL(at91_set_deglitch); | 311 | EXPORT_SYMBOL(at91_set_deglitch); |
217 | 312 | ||
218 | /* | 313 | /* |
314 | * enable/disable the debounce filter; | ||
315 | */ | ||
316 | int __init_or_module at91_set_debounce(unsigned pin, int is_on, int div) | ||
317 | { | ||
318 | void __iomem *pio = pin_to_controller(pin); | ||
319 | unsigned mask = pin_to_mask(pin); | ||
320 | |||
321 | if (!pio || !has_pio3()) | ||
322 | return -EINVAL; | ||
323 | |||
324 | if (is_on) { | ||
325 | __raw_writel(mask, pio + PIO_IFSCER); | ||
326 | __raw_writel(div & PIO_SCDR_DIV, pio + PIO_SCDR); | ||
327 | __raw_writel(mask, pio + PIO_IFER); | ||
328 | } else { | ||
329 | __raw_writel(mask, pio + PIO_IFDR); | ||
330 | } | ||
331 | return 0; | ||
332 | } | ||
333 | EXPORT_SYMBOL(at91_set_debounce); | ||
334 | |||
335 | /* | ||
219 | * enable/disable the multi-driver; This is only valid for output and | 336 | * enable/disable the multi-driver; This is only valid for output and |
220 | * allows the output pin to run as an open collector output. | 337 | * allows the output pin to run as an open collector output. |
221 | */ | 338 | */ |
@@ -233,6 +350,41 @@ int __init_or_module at91_set_multi_drive(unsigned pin, int is_on) | |||
233 | EXPORT_SYMBOL(at91_set_multi_drive); | 350 | EXPORT_SYMBOL(at91_set_multi_drive); |
234 | 351 | ||
235 | /* | 352 | /* |
353 | * enable/disable the pull-down. | ||
354 | * If pull-up already enabled while calling the function, we disable it. | ||
355 | */ | ||
356 | int __init_or_module at91_set_pulldown(unsigned pin, int is_on) | ||
357 | { | ||
358 | void __iomem *pio = pin_to_controller(pin); | ||
359 | unsigned mask = pin_to_mask(pin); | ||
360 | |||
361 | if (!pio || !has_pio3()) | ||
362 | return -EINVAL; | ||
363 | |||
364 | /* Disable pull-up anyway */ | ||
365 | __raw_writel(mask, pio + PIO_PUDR); | ||
366 | __raw_writel(mask, pio + (is_on ? PIO_PPDER : PIO_PPDDR)); | ||
367 | return 0; | ||
368 | } | ||
369 | EXPORT_SYMBOL(at91_set_pulldown); | ||
370 | |||
371 | /* | ||
372 | * disable Schmitt trigger | ||
373 | */ | ||
374 | int __init_or_module at91_disable_schmitt_trig(unsigned pin) | ||
375 | { | ||
376 | void __iomem *pio = pin_to_controller(pin); | ||
377 | unsigned mask = pin_to_mask(pin); | ||
378 | |||
379 | if (!pio || !has_pio3()) | ||
380 | return -EINVAL; | ||
381 | |||
382 | __raw_writel(__raw_readl(pio + PIO_SCHMITT) | mask, pio + PIO_SCHMITT); | ||
383 | return 0; | ||
384 | } | ||
385 | EXPORT_SYMBOL(at91_disable_schmitt_trig); | ||
386 | |||
387 | /* | ||
236 | * assuming the pin is muxed as a gpio output, set its value. | 388 | * assuming the pin is muxed as a gpio output, set its value. |
237 | */ | 389 | */ |
238 | int at91_set_gpio_value(unsigned pin, int value) | 390 | int at91_set_gpio_value(unsigned pin, int value) |
@@ -273,9 +425,9 @@ static u32 backups[MAX_GPIO_BANKS]; | |||
273 | 425 | ||
274 | static int gpio_irq_set_wake(struct irq_data *d, unsigned state) | 426 | static int gpio_irq_set_wake(struct irq_data *d, unsigned state) |
275 | { | 427 | { |
276 | unsigned pin = irq_to_gpio(d->irq); | 428 | struct at91_gpio_chip *at91_gpio = irq_data_get_irq_chip_data(d); |
277 | unsigned mask = pin_to_mask(pin); | 429 | unsigned mask = 1 << d->hwirq; |
278 | unsigned bank = pin / 32; | 430 | unsigned bank = at91_gpio->pioc_idx; |
279 | 431 | ||
280 | if (unlikely(bank >= MAX_GPIO_BANKS)) | 432 | if (unlikely(bank >= MAX_GPIO_BANKS)) |
281 | return -EINVAL; | 433 | return -EINVAL; |
@@ -285,7 +437,7 @@ static int gpio_irq_set_wake(struct irq_data *d, unsigned state) | |||
285 | else | 437 | else |
286 | wakeups[bank] &= ~mask; | 438 | wakeups[bank] &= ~mask; |
287 | 439 | ||
288 | irq_set_irq_wake(gpio_chip[bank].id, state); | 440 | irq_set_irq_wake(at91_gpio->pioc_virq, state); |
289 | 441 | ||
290 | return 0; | 442 | return 0; |
291 | } | 443 | } |
@@ -301,9 +453,10 @@ void at91_gpio_suspend(void) | |||
301 | __raw_writel(backups[i], pio + PIO_IDR); | 453 | __raw_writel(backups[i], pio + PIO_IDR); |
302 | __raw_writel(wakeups[i], pio + PIO_IER); | 454 | __raw_writel(wakeups[i], pio + PIO_IER); |
303 | 455 | ||
304 | if (!wakeups[i]) | 456 | if (!wakeups[i]) { |
457 | clk_unprepare(gpio_chip[i].clock); | ||
305 | clk_disable(gpio_chip[i].clock); | 458 | clk_disable(gpio_chip[i].clock); |
306 | else { | 459 | } else { |
307 | #ifdef CONFIG_PM_DEBUG | 460 | #ifdef CONFIG_PM_DEBUG |
308 | printk(KERN_DEBUG "GPIO-%c may wake for %08x\n", 'A'+i, wakeups[i]); | 461 | printk(KERN_DEBUG "GPIO-%c may wake for %08x\n", 'A'+i, wakeups[i]); |
309 | #endif | 462 | #endif |
@@ -318,8 +471,10 @@ void at91_gpio_resume(void) | |||
318 | for (i = 0; i < gpio_banks; i++) { | 471 | for (i = 0; i < gpio_banks; i++) { |
319 | void __iomem *pio = gpio_chip[i].regbase; | 472 | void __iomem *pio = gpio_chip[i].regbase; |
320 | 473 | ||
321 | if (!wakeups[i]) | 474 | if (!wakeups[i]) { |
322 | clk_enable(gpio_chip[i].clock); | 475 | if (clk_prepare(gpio_chip[i].clock) == 0) |
476 | clk_enable(gpio_chip[i].clock); | ||
477 | } | ||
323 | 478 | ||
324 | __raw_writel(wakeups[i], pio + PIO_IDR); | 479 | __raw_writel(wakeups[i], pio + PIO_IDR); |
325 | __raw_writel(backups[i], pio + PIO_IER); | 480 | __raw_writel(backups[i], pio + PIO_IER); |
@@ -335,7 +490,10 @@ void at91_gpio_resume(void) | |||
335 | * To use any AT91_PIN_* as an externally triggered IRQ, first call | 490 | * To use any AT91_PIN_* as an externally triggered IRQ, first call |
336 | * at91_set_gpio_input() then maybe enable its glitch filter. | 491 | * at91_set_gpio_input() then maybe enable its glitch filter. |
337 | * Then just request_irq() with the pin ID; it works like any ARM IRQ | 492 | * Then just request_irq() with the pin ID; it works like any ARM IRQ |
338 | * handler, though it always triggers on rising and falling edges. | 493 | * handler. |
494 | * First implementation always triggers on rising and falling edges | ||
495 | * whereas the newer PIO3 can be additionally configured to trigger on | ||
496 | * level, edge with any polarity. | ||
339 | * | 497 | * |
340 | * Alternatively, certain pins may be used directly as IRQ0..IRQ6 after | 498 | * Alternatively, certain pins may be used directly as IRQ0..IRQ6 after |
341 | * configuring them with at91_set_a_periph() or at91_set_b_periph(). | 499 | * configuring them with at91_set_a_periph() or at91_set_b_periph(). |
@@ -344,9 +502,9 @@ void at91_gpio_resume(void) | |||
344 | 502 | ||
345 | static void gpio_irq_mask(struct irq_data *d) | 503 | static void gpio_irq_mask(struct irq_data *d) |
346 | { | 504 | { |
347 | unsigned pin = irq_to_gpio(d->irq); | 505 | struct at91_gpio_chip *at91_gpio = irq_data_get_irq_chip_data(d); |
348 | void __iomem *pio = pin_to_controller(pin); | 506 | void __iomem *pio = at91_gpio->regbase; |
349 | unsigned mask = pin_to_mask(pin); | 507 | unsigned mask = 1 << d->hwirq; |
350 | 508 | ||
351 | if (pio) | 509 | if (pio) |
352 | __raw_writel(mask, pio + PIO_IDR); | 510 | __raw_writel(mask, pio + PIO_IDR); |
@@ -354,9 +512,9 @@ static void gpio_irq_mask(struct irq_data *d) | |||
354 | 512 | ||
355 | static void gpio_irq_unmask(struct irq_data *d) | 513 | static void gpio_irq_unmask(struct irq_data *d) |
356 | { | 514 | { |
357 | unsigned pin = irq_to_gpio(d->irq); | 515 | struct at91_gpio_chip *at91_gpio = irq_data_get_irq_chip_data(d); |
358 | void __iomem *pio = pin_to_controller(pin); | 516 | void __iomem *pio = at91_gpio->regbase; |
359 | unsigned mask = pin_to_mask(pin); | 517 | unsigned mask = 1 << d->hwirq; |
360 | 518 | ||
361 | if (pio) | 519 | if (pio) |
362 | __raw_writel(mask, pio + PIO_IER); | 520 | __raw_writel(mask, pio + PIO_IER); |
@@ -373,23 +531,66 @@ static int gpio_irq_type(struct irq_data *d, unsigned type) | |||
373 | } | 531 | } |
374 | } | 532 | } |
375 | 533 | ||
534 | /* Alternate irq type for PIO3 support */ | ||
535 | static int alt_gpio_irq_type(struct irq_data *d, unsigned type) | ||
536 | { | ||
537 | struct at91_gpio_chip *at91_gpio = irq_data_get_irq_chip_data(d); | ||
538 | void __iomem *pio = at91_gpio->regbase; | ||
539 | unsigned mask = 1 << d->hwirq; | ||
540 | |||
541 | switch (type) { | ||
542 | case IRQ_TYPE_EDGE_RISING: | ||
543 | __raw_writel(mask, pio + PIO_ESR); | ||
544 | __raw_writel(mask, pio + PIO_REHLSR); | ||
545 | break; | ||
546 | case IRQ_TYPE_EDGE_FALLING: | ||
547 | __raw_writel(mask, pio + PIO_ESR); | ||
548 | __raw_writel(mask, pio + PIO_FELLSR); | ||
549 | break; | ||
550 | case IRQ_TYPE_LEVEL_LOW: | ||
551 | __raw_writel(mask, pio + PIO_LSR); | ||
552 | __raw_writel(mask, pio + PIO_FELLSR); | ||
553 | break; | ||
554 | case IRQ_TYPE_LEVEL_HIGH: | ||
555 | __raw_writel(mask, pio + PIO_LSR); | ||
556 | __raw_writel(mask, pio + PIO_REHLSR); | ||
557 | break; | ||
558 | case IRQ_TYPE_EDGE_BOTH: | ||
559 | /* | ||
560 | * disable additional interrupt modes: | ||
561 | * fall back to default behavior | ||
562 | */ | ||
563 | __raw_writel(mask, pio + PIO_AIMDR); | ||
564 | return 0; | ||
565 | case IRQ_TYPE_NONE: | ||
566 | default: | ||
567 | pr_warn("AT91: No type for irq %d\n", gpio_to_irq(d->irq)); | ||
568 | return -EINVAL; | ||
569 | } | ||
570 | |||
571 | /* enable additional interrupt modes */ | ||
572 | __raw_writel(mask, pio + PIO_AIMER); | ||
573 | |||
574 | return 0; | ||
575 | } | ||
576 | |||
376 | static struct irq_chip gpio_irqchip = { | 577 | static struct irq_chip gpio_irqchip = { |
377 | .name = "GPIO", | 578 | .name = "GPIO", |
378 | .irq_disable = gpio_irq_mask, | 579 | .irq_disable = gpio_irq_mask, |
379 | .irq_mask = gpio_irq_mask, | 580 | .irq_mask = gpio_irq_mask, |
380 | .irq_unmask = gpio_irq_unmask, | 581 | .irq_unmask = gpio_irq_unmask, |
381 | .irq_set_type = gpio_irq_type, | 582 | /* .irq_set_type is set dynamically */ |
382 | .irq_set_wake = gpio_irq_set_wake, | 583 | .irq_set_wake = gpio_irq_set_wake, |
383 | }; | 584 | }; |
384 | 585 | ||
385 | static void gpio_irq_handler(unsigned irq, struct irq_desc *desc) | 586 | static void gpio_irq_handler(unsigned irq, struct irq_desc *desc) |
386 | { | 587 | { |
387 | unsigned irq_pin; | ||
388 | struct irq_data *idata = irq_desc_get_irq_data(desc); | 588 | struct irq_data *idata = irq_desc_get_irq_data(desc); |
389 | struct irq_chip *chip = irq_data_get_irq_chip(idata); | 589 | struct irq_chip *chip = irq_data_get_irq_chip(idata); |
390 | struct at91_gpio_chip *at91_gpio = irq_data_get_irq_chip_data(idata); | 590 | struct at91_gpio_chip *at91_gpio = irq_data_get_irq_chip_data(idata); |
391 | void __iomem *pio = at91_gpio->regbase; | 591 | void __iomem *pio = at91_gpio->regbase; |
392 | u32 isr; | 592 | unsigned long isr; |
593 | int n; | ||
393 | 594 | ||
394 | /* temporarily mask (level sensitive) parent IRQ */ | 595 | /* temporarily mask (level sensitive) parent IRQ */ |
395 | chip->irq_ack(idata); | 596 | chip->irq_ack(idata); |
@@ -407,13 +608,10 @@ static void gpio_irq_handler(unsigned irq, struct irq_desc *desc) | |||
407 | continue; | 608 | continue; |
408 | } | 609 | } |
409 | 610 | ||
410 | irq_pin = gpio_to_irq(at91_gpio->chip.base); | 611 | n = find_first_bit(&isr, BITS_PER_LONG); |
411 | 612 | while (n < BITS_PER_LONG) { | |
412 | while (isr) { | 613 | generic_handle_irq(irq_find_mapping(at91_gpio->domain, n)); |
413 | if (isr & 1) | 614 | n = find_next_bit(&isr, BITS_PER_LONG, n + 1); |
414 | generic_handle_irq(irq_pin); | ||
415 | irq_pin++; | ||
416 | isr >>= 1; | ||
417 | } | 615 | } |
418 | } | 616 | } |
419 | chip->irq_unmask(idata); | 617 | chip->irq_unmask(idata); |
@@ -424,6 +622,33 @@ static void gpio_irq_handler(unsigned irq, struct irq_desc *desc) | |||
424 | 622 | ||
425 | #ifdef CONFIG_DEBUG_FS | 623 | #ifdef CONFIG_DEBUG_FS |
426 | 624 | ||
625 | static void gpio_printf(struct seq_file *s, void __iomem *pio, unsigned mask) | ||
626 | { | ||
627 | char *trigger = NULL; | ||
628 | char *polarity = NULL; | ||
629 | |||
630 | if (__raw_readl(pio + PIO_IMR) & mask) { | ||
631 | if (!has_pio3() || !(__raw_readl(pio + PIO_AIMMR) & mask )) { | ||
632 | trigger = "edge"; | ||
633 | polarity = "both"; | ||
634 | } else { | ||
635 | if (__raw_readl(pio + PIO_ELSR) & mask) { | ||
636 | trigger = "level"; | ||
637 | polarity = __raw_readl(pio + PIO_FRLHSR) & mask ? | ||
638 | "high" : "low"; | ||
639 | } else { | ||
640 | trigger = "edge"; | ||
641 | polarity = __raw_readl(pio + PIO_FRLHSR) & mask ? | ||
642 | "rising" : "falling"; | ||
643 | } | ||
644 | } | ||
645 | seq_printf(s, "IRQ:%s-%s\t", trigger, polarity); | ||
646 | } else { | ||
647 | seq_printf(s, "GPIO:%s\t\t", | ||
648 | __raw_readl(pio + PIO_PDSR) & mask ? "1" : "0"); | ||
649 | } | ||
650 | } | ||
651 | |||
427 | static int at91_gpio_show(struct seq_file *s, void *unused) | 652 | static int at91_gpio_show(struct seq_file *s, void *unused) |
428 | { | 653 | { |
429 | int bank, j; | 654 | int bank, j; |
@@ -431,7 +656,7 @@ static int at91_gpio_show(struct seq_file *s, void *unused) | |||
431 | /* print heading */ | 656 | /* print heading */ |
432 | seq_printf(s, "Pin\t"); | 657 | seq_printf(s, "Pin\t"); |
433 | for (bank = 0; bank < gpio_banks; bank++) { | 658 | for (bank = 0; bank < gpio_banks; bank++) { |
434 | seq_printf(s, "PIO%c\t", 'A' + bank); | 659 | seq_printf(s, "PIO%c\t\t", 'A' + bank); |
435 | }; | 660 | }; |
436 | seq_printf(s, "\n\n"); | 661 | seq_printf(s, "\n\n"); |
437 | 662 | ||
@@ -445,11 +670,10 @@ static int at91_gpio_show(struct seq_file *s, void *unused) | |||
445 | unsigned mask = pin_to_mask(pin); | 670 | unsigned mask = pin_to_mask(pin); |
446 | 671 | ||
447 | if (__raw_readl(pio + PIO_PSR) & mask) | 672 | if (__raw_readl(pio + PIO_PSR) & mask) |
448 | seq_printf(s, "GPIO:%s", __raw_readl(pio + PIO_PDSR) & mask ? "1" : "0"); | 673 | gpio_printf(s, pio, mask); |
449 | else | 674 | else |
450 | seq_printf(s, "%s", __raw_readl(pio + PIO_ABSR) & mask ? "B" : "A"); | 675 | seq_printf(s, "%c\t\t", |
451 | 676 | peripheral_function(pio, mask)); | |
452 | seq_printf(s, "\t"); | ||
453 | } | 677 | } |
454 | 678 | ||
455 | seq_printf(s, "\n"); | 679 | seq_printf(s, "\n"); |
@@ -488,46 +712,152 @@ postcore_initcall(at91_gpio_debugfs_init); | |||
488 | */ | 712 | */ |
489 | static struct lock_class_key gpio_lock_class; | 713 | static struct lock_class_key gpio_lock_class; |
490 | 714 | ||
715 | #if defined(CONFIG_OF) | ||
716 | static int at91_gpio_irq_map(struct irq_domain *h, unsigned int virq, | ||
717 | irq_hw_number_t hw) | ||
718 | { | ||
719 | struct at91_gpio_chip *at91_gpio = h->host_data; | ||
720 | |||
721 | irq_set_lockdep_class(virq, &gpio_lock_class); | ||
722 | |||
723 | /* | ||
724 | * Can use the "simple" and not "edge" handler since it's | ||
725 | * shorter, and the AIC handles interrupts sanely. | ||
726 | */ | ||
727 | irq_set_chip_and_handler(virq, &gpio_irqchip, | ||
728 | handle_simple_irq); | ||
729 | set_irq_flags(virq, IRQF_VALID); | ||
730 | irq_set_chip_data(virq, at91_gpio); | ||
731 | |||
732 | return 0; | ||
733 | } | ||
734 | |||
735 | static struct irq_domain_ops at91_gpio_ops = { | ||
736 | .map = at91_gpio_irq_map, | ||
737 | .xlate = irq_domain_xlate_twocell, | ||
738 | }; | ||
739 | |||
740 | int __init at91_gpio_of_irq_setup(struct device_node *node, | ||
741 | struct device_node *parent) | ||
742 | { | ||
743 | struct at91_gpio_chip *prev = NULL; | ||
744 | int alias_idx = of_alias_get_id(node, "gpio"); | ||
745 | struct at91_gpio_chip *at91_gpio = &gpio_chip[alias_idx]; | ||
746 | |||
747 | /* Setup proper .irq_set_type function */ | ||
748 | if (has_pio3()) | ||
749 | gpio_irqchip.irq_set_type = alt_gpio_irq_type; | ||
750 | else | ||
751 | gpio_irqchip.irq_set_type = gpio_irq_type; | ||
752 | |||
753 | /* Disable irqs of this PIO controller */ | ||
754 | __raw_writel(~0, at91_gpio->regbase + PIO_IDR); | ||
755 | |||
756 | /* Setup irq domain */ | ||
757 | at91_gpio->domain = irq_domain_add_linear(node, at91_gpio->chip.ngpio, | ||
758 | &at91_gpio_ops, at91_gpio); | ||
759 | if (!at91_gpio->domain) | ||
760 | panic("at91_gpio.%d: couldn't allocate irq domain (DT).\n", | ||
761 | at91_gpio->pioc_idx); | ||
762 | |||
763 | /* Setup chained handler */ | ||
764 | if (at91_gpio->pioc_idx) | ||
765 | prev = &gpio_chip[at91_gpio->pioc_idx - 1]; | ||
766 | |||
767 | /* The toplevel handler handles one bank of GPIOs, except | ||
768 | * on some SoC it can handles up to three... | ||
769 | * We only set up the handler for the first of the list. | ||
770 | */ | ||
771 | if (prev && prev->next == at91_gpio) | ||
772 | return 0; | ||
773 | |||
774 | at91_gpio->pioc_virq = irq_create_mapping(irq_find_host(parent), | ||
775 | at91_gpio->pioc_hwirq); | ||
776 | irq_set_chip_data(at91_gpio->pioc_virq, at91_gpio); | ||
777 | irq_set_chained_handler(at91_gpio->pioc_virq, gpio_irq_handler); | ||
778 | |||
779 | return 0; | ||
780 | } | ||
781 | #else | ||
782 | int __init at91_gpio_of_irq_setup(struct device_node *node, | ||
783 | struct device_node *parent) | ||
784 | { | ||
785 | return -EINVAL; | ||
786 | } | ||
787 | #endif | ||
788 | |||
789 | /* | ||
790 | * irqdomain initialization: pile up irqdomains on top of AIC range | ||
791 | */ | ||
792 | static void __init at91_gpio_irqdomain(struct at91_gpio_chip *at91_gpio) | ||
793 | { | ||
794 | int irq_base; | ||
795 | |||
796 | irq_base = irq_alloc_descs(-1, 0, at91_gpio->chip.ngpio, 0); | ||
797 | if (irq_base < 0) | ||
798 | panic("at91_gpio.%d: error %d: couldn't allocate IRQ numbers.\n", | ||
799 | at91_gpio->pioc_idx, irq_base); | ||
800 | at91_gpio->domain = irq_domain_add_legacy(NULL, at91_gpio->chip.ngpio, | ||
801 | irq_base, 0, | ||
802 | &irq_domain_simple_ops, NULL); | ||
803 | if (!at91_gpio->domain) | ||
804 | panic("at91_gpio.%d: couldn't allocate irq domain.\n", | ||
805 | at91_gpio->pioc_idx); | ||
806 | } | ||
807 | |||
491 | /* | 808 | /* |
492 | * Called from the processor-specific init to enable GPIO interrupt support. | 809 | * Called from the processor-specific init to enable GPIO interrupt support. |
493 | */ | 810 | */ |
494 | void __init at91_gpio_irq_setup(void) | 811 | void __init at91_gpio_irq_setup(void) |
495 | { | 812 | { |
496 | unsigned pioc, irq = gpio_to_irq(0); | 813 | unsigned pioc; |
814 | int gpio_irqnbr = 0; | ||
497 | struct at91_gpio_chip *this, *prev; | 815 | struct at91_gpio_chip *this, *prev; |
498 | 816 | ||
817 | /* Setup proper .irq_set_type function */ | ||
818 | if (has_pio3()) | ||
819 | gpio_irqchip.irq_set_type = alt_gpio_irq_type; | ||
820 | else | ||
821 | gpio_irqchip.irq_set_type = gpio_irq_type; | ||
822 | |||
499 | for (pioc = 0, this = gpio_chip, prev = NULL; | 823 | for (pioc = 0, this = gpio_chip, prev = NULL; |
500 | pioc++ < gpio_banks; | 824 | pioc++ < gpio_banks; |
501 | prev = this, this++) { | 825 | prev = this, this++) { |
502 | unsigned id = this->id; | 826 | int offset; |
503 | unsigned i; | ||
504 | 827 | ||
505 | __raw_writel(~0, this->regbase + PIO_IDR); | 828 | __raw_writel(~0, this->regbase + PIO_IDR); |
506 | 829 | ||
507 | for (i = 0, irq = gpio_to_irq(this->chip.base); i < 32; | 830 | /* setup irq domain for this GPIO controller */ |
508 | i++, irq++) { | 831 | at91_gpio_irqdomain(this); |
509 | irq_set_lockdep_class(irq, &gpio_lock_class); | 832 | |
833 | for (offset = 0; offset < this->chip.ngpio; offset++) { | ||
834 | unsigned int virq = irq_find_mapping(this->domain, offset); | ||
835 | irq_set_lockdep_class(virq, &gpio_lock_class); | ||
510 | 836 | ||
511 | /* | 837 | /* |
512 | * Can use the "simple" and not "edge" handler since it's | 838 | * Can use the "simple" and not "edge" handler since it's |
513 | * shorter, and the AIC handles interrupts sanely. | 839 | * shorter, and the AIC handles interrupts sanely. |
514 | */ | 840 | */ |
515 | irq_set_chip_and_handler(irq, &gpio_irqchip, | 841 | irq_set_chip_and_handler(virq, &gpio_irqchip, |
516 | handle_simple_irq); | 842 | handle_simple_irq); |
517 | set_irq_flags(irq, IRQF_VALID); | 843 | set_irq_flags(virq, IRQF_VALID); |
844 | irq_set_chip_data(virq, this); | ||
845 | |||
846 | gpio_irqnbr++; | ||
518 | } | 847 | } |
519 | 848 | ||
520 | /* The toplevel handler handles one bank of GPIOs, except | 849 | /* The toplevel handler handles one bank of GPIOs, except |
521 | * AT91SAM9263_ID_PIOCDE handles three... PIOC is first in | 850 | * on some SoC it can handles up to three... |
522 | * the list, so we only set up that handler. | 851 | * We only set up the handler for the first of the list. |
523 | */ | 852 | */ |
524 | if (prev && prev->next == this) | 853 | if (prev && prev->next == this) |
525 | continue; | 854 | continue; |
526 | 855 | ||
527 | irq_set_chip_data(id, this); | 856 | this->pioc_virq = irq_create_mapping(NULL, this->pioc_hwirq); |
528 | irq_set_chained_handler(id, gpio_irq_handler); | 857 | irq_set_chip_data(this->pioc_virq, this); |
858 | irq_set_chained_handler(this->pioc_virq, gpio_irq_handler); | ||
529 | } | 859 | } |
530 | pr_info("AT91: %d gpio irqs in %d banks\n", irq - gpio_to_irq(0), gpio_banks); | 860 | pr_info("AT91: %d gpio irqs in %d banks\n", gpio_irqnbr, gpio_banks); |
531 | } | 861 | } |
532 | 862 | ||
533 | /* gpiolib support */ | 863 | /* gpiolib support */ |
@@ -593,48 +923,175 @@ static void at91_gpiolib_dbg_show(struct seq_file *s, struct gpio_chip *chip) | |||
593 | at91_get_gpio_value(pin) ? | 923 | at91_get_gpio_value(pin) ? |
594 | "set" : "clear"); | 924 | "set" : "clear"); |
595 | else | 925 | else |
596 | seq_printf(s, "[periph %s]\n", | 926 | seq_printf(s, "[periph %c]\n", |
597 | __raw_readl(pio + PIO_ABSR) & | 927 | peripheral_function(pio, mask)); |
598 | mask ? "B" : "A"); | ||
599 | } | 928 | } |
600 | } | 929 | } |
601 | } | 930 | } |
602 | 931 | ||
932 | static int at91_gpiolib_to_irq(struct gpio_chip *chip, unsigned offset) | ||
933 | { | ||
934 | struct at91_gpio_chip *at91_gpio = to_at91_gpio_chip(chip); | ||
935 | int virq; | ||
936 | |||
937 | if (offset < chip->ngpio) | ||
938 | virq = irq_create_mapping(at91_gpio->domain, offset); | ||
939 | else | ||
940 | virq = -ENXIO; | ||
941 | |||
942 | dev_dbg(chip->dev, "%s: request IRQ for GPIO %d, return %d\n", | ||
943 | chip->label, offset + chip->base, virq); | ||
944 | return virq; | ||
945 | } | ||
946 | |||
947 | static int __init at91_gpio_setup_clk(int idx) | ||
948 | { | ||
949 | struct at91_gpio_chip *at91_gpio = &gpio_chip[idx]; | ||
950 | |||
951 | /* retreive PIO controller's clock */ | ||
952 | at91_gpio->clock = clk_get_sys(NULL, at91_gpio->chip.label); | ||
953 | if (IS_ERR(at91_gpio->clock)) { | ||
954 | pr_err("at91_gpio.%d, failed to get clock, ignoring.\n", idx); | ||
955 | goto err; | ||
956 | } | ||
957 | |||
958 | if (clk_prepare(at91_gpio->clock)) | ||
959 | goto clk_prep_err; | ||
960 | |||
961 | /* enable PIO controller's clock */ | ||
962 | if (clk_enable(at91_gpio->clock)) { | ||
963 | pr_err("at91_gpio.%d, failed to enable clock, ignoring.\n", idx); | ||
964 | goto clk_err; | ||
965 | } | ||
966 | |||
967 | return 0; | ||
968 | |||
969 | clk_err: | ||
970 | clk_unprepare(at91_gpio->clock); | ||
971 | clk_prep_err: | ||
972 | clk_put(at91_gpio->clock); | ||
973 | err: | ||
974 | return -EINVAL; | ||
975 | } | ||
976 | |||
977 | #ifdef CONFIG_OF_GPIO | ||
978 | static void __init of_at91_gpio_init_one(struct device_node *np) | ||
979 | { | ||
980 | int alias_idx; | ||
981 | struct at91_gpio_chip *at91_gpio; | ||
982 | |||
983 | if (!np) | ||
984 | return; | ||
985 | |||
986 | alias_idx = of_alias_get_id(np, "gpio"); | ||
987 | if (alias_idx >= MAX_GPIO_BANKS) { | ||
988 | pr_err("at91_gpio, failed alias idx(%d) > MAX_GPIO_BANKS(%d), ignoring.\n", | ||
989 | alias_idx, MAX_GPIO_BANKS); | ||
990 | return; | ||
991 | } | ||
992 | |||
993 | at91_gpio = &gpio_chip[alias_idx]; | ||
994 | at91_gpio->chip.base = alias_idx * at91_gpio->chip.ngpio; | ||
995 | |||
996 | at91_gpio->regbase = of_iomap(np, 0); | ||
997 | if (!at91_gpio->regbase) { | ||
998 | pr_err("at91_gpio.%d, failed to map registers, ignoring.\n", | ||
999 | alias_idx); | ||
1000 | return; | ||
1001 | } | ||
1002 | |||
1003 | /* Get the interrupts property */ | ||
1004 | if (of_property_read_u32(np, "interrupts", &at91_gpio->pioc_hwirq)) { | ||
1005 | pr_err("at91_gpio.%d, failed to get interrupts property, ignoring.\n", | ||
1006 | alias_idx); | ||
1007 | goto ioremap_err; | ||
1008 | } | ||
1009 | |||
1010 | /* Get capabilities from compatibility property */ | ||
1011 | if (of_device_is_compatible(np, "atmel,at91sam9x5-gpio")) | ||
1012 | at91_gpio_caps |= AT91_GPIO_CAP_PIO3; | ||
1013 | |||
1014 | /* Setup clock */ | ||
1015 | if (at91_gpio_setup_clk(alias_idx)) | ||
1016 | goto ioremap_err; | ||
1017 | |||
1018 | at91_gpio->chip.of_node = np; | ||
1019 | gpio_banks = max(gpio_banks, alias_idx + 1); | ||
1020 | at91_gpio->pioc_idx = alias_idx; | ||
1021 | return; | ||
1022 | |||
1023 | ioremap_err: | ||
1024 | iounmap(at91_gpio->regbase); | ||
1025 | } | ||
1026 | |||
1027 | static int __init of_at91_gpio_init(void) | ||
1028 | { | ||
1029 | struct device_node *np = NULL; | ||
1030 | |||
1031 | /* | ||
1032 | * This isn't ideal, but it gets things hooked up until this | ||
1033 | * driver is converted into a platform_device | ||
1034 | */ | ||
1035 | for_each_compatible_node(np, NULL, "atmel,at91rm9200-gpio") | ||
1036 | of_at91_gpio_init_one(np); | ||
1037 | |||
1038 | return gpio_banks > 0 ? 0 : -EINVAL; | ||
1039 | } | ||
1040 | #else | ||
1041 | static int __init of_at91_gpio_init(void) | ||
1042 | { | ||
1043 | return -EINVAL; | ||
1044 | } | ||
1045 | #endif | ||
1046 | |||
1047 | static void __init at91_gpio_init_one(int idx, u32 regbase, int pioc_hwirq) | ||
1048 | { | ||
1049 | struct at91_gpio_chip *at91_gpio = &gpio_chip[idx]; | ||
1050 | |||
1051 | at91_gpio->chip.base = idx * at91_gpio->chip.ngpio; | ||
1052 | at91_gpio->pioc_hwirq = pioc_hwirq; | ||
1053 | at91_gpio->pioc_idx = idx; | ||
1054 | |||
1055 | at91_gpio->regbase = ioremap(regbase, 512); | ||
1056 | if (!at91_gpio->regbase) { | ||
1057 | pr_err("at91_gpio.%d, failed to map registers, ignoring.\n", idx); | ||
1058 | return; | ||
1059 | } | ||
1060 | |||
1061 | if (at91_gpio_setup_clk(idx)) | ||
1062 | goto ioremap_err; | ||
1063 | |||
1064 | gpio_banks = max(gpio_banks, idx + 1); | ||
1065 | return; | ||
1066 | |||
1067 | ioremap_err: | ||
1068 | iounmap(at91_gpio->regbase); | ||
1069 | } | ||
1070 | |||
603 | /* | 1071 | /* |
604 | * Called from the processor-specific init to enable GPIO pin support. | 1072 | * Called from the processor-specific init to enable GPIO pin support. |
605 | */ | 1073 | */ |
606 | void __init at91_gpio_init(struct at91_gpio_bank *data, int nr_banks) | 1074 | void __init at91_gpio_init(struct at91_gpio_bank *data, int nr_banks) |
607 | { | 1075 | { |
608 | unsigned i; | 1076 | unsigned i; |
609 | struct at91_gpio_chip *at91_gpio, *last = NULL; | 1077 | struct at91_gpio_chip *at91_gpio, *last = NULL; |
610 | 1078 | ||
611 | BUG_ON(nr_banks > MAX_GPIO_BANKS); | 1079 | BUG_ON(nr_banks > MAX_GPIO_BANKS); |
612 | 1080 | ||
613 | gpio_banks = nr_banks; | 1081 | if (of_at91_gpio_init() < 0) { |
1082 | /* No GPIO controller found in device tree */ | ||
1083 | for (i = 0; i < nr_banks; i++) | ||
1084 | at91_gpio_init_one(i, data[i].regbase, data[i].id); | ||
1085 | } | ||
614 | 1086 | ||
615 | for (i = 0; i < nr_banks; i++) { | 1087 | for (i = 0; i < gpio_banks; i++) { |
616 | at91_gpio = &gpio_chip[i]; | 1088 | at91_gpio = &gpio_chip[i]; |
617 | 1089 | ||
618 | at91_gpio->id = data[i].id; | 1090 | /* |
619 | at91_gpio->chip.base = i * 32; | 1091 | * GPIO controller are grouped on some SoC: |
620 | 1092 | * PIOC, PIOD and PIOE can share the same IRQ line | |
621 | at91_gpio->regbase = ioremap(data[i].regbase, 512); | 1093 | */ |
622 | if (!at91_gpio->regbase) { | 1094 | if (last && last->pioc_hwirq == at91_gpio->pioc_hwirq) |
623 | pr_err("at91_gpio.%d, failed to map registers, ignoring.\n", i); | ||
624 | continue; | ||
625 | } | ||
626 | |||
627 | at91_gpio->clock = clk_get_sys(NULL, at91_gpio->chip.label); | ||
628 | if (!at91_gpio->clock) { | ||
629 | pr_err("at91_gpio.%d, failed to get clock, ignoring.\n", i); | ||
630 | continue; | ||
631 | } | ||
632 | |||
633 | /* enable PIO controller's clock */ | ||
634 | clk_enable(at91_gpio->clock); | ||
635 | |||
636 | /* AT91SAM9263_ID_PIOCDE groups PIOC, PIOD, PIOE */ | ||
637 | if (last && last->id == at91_gpio->id) | ||
638 | last->next = at91_gpio; | 1095 | last->next = at91_gpio; |
639 | last = at91_gpio; | 1096 | last = at91_gpio; |
640 | 1097 | ||
diff --git a/arch/arm/mach-at91/include/mach/at91_pio.h b/arch/arm/mach-at91/include/mach/at91_pio.h index c6a31bf8a5c6..732b11c37f1a 100644 --- a/arch/arm/mach-at91/include/mach/at91_pio.h +++ b/arch/arm/mach-at91/include/mach/at91_pio.h | |||
@@ -40,10 +40,35 @@ | |||
40 | #define PIO_PUER 0x64 /* Pull-up Enable Register */ | 40 | #define PIO_PUER 0x64 /* Pull-up Enable Register */ |
41 | #define PIO_PUSR 0x68 /* Pull-up Status Register */ | 41 | #define PIO_PUSR 0x68 /* Pull-up Status Register */ |
42 | #define PIO_ASR 0x70 /* Peripheral A Select Register */ | 42 | #define PIO_ASR 0x70 /* Peripheral A Select Register */ |
43 | #define PIO_ABCDSR1 0x70 /* Peripheral ABCD Select Register 1 [some sam9 only] */ | ||
43 | #define PIO_BSR 0x74 /* Peripheral B Select Register */ | 44 | #define PIO_BSR 0x74 /* Peripheral B Select Register */ |
45 | #define PIO_ABCDSR2 0x74 /* Peripheral ABCD Select Register 2 [some sam9 only] */ | ||
44 | #define PIO_ABSR 0x78 /* AB Status Register */ | 46 | #define PIO_ABSR 0x78 /* AB Status Register */ |
47 | #define PIO_IFSCDR 0x80 /* Input Filter Slow Clock Disable Register */ | ||
48 | #define PIO_IFSCER 0x84 /* Input Filter Slow Clock Enable Register */ | ||
49 | #define PIO_IFSCSR 0x88 /* Input Filter Slow Clock Status Register */ | ||
50 | #define PIO_SCDR 0x8c /* Slow Clock Divider Debouncing Register */ | ||
51 | #define PIO_SCDR_DIV (0x3fff << 0) /* Slow Clock Divider Mask */ | ||
52 | #define PIO_PPDDR 0x90 /* Pad Pull-down Disable Register */ | ||
53 | #define PIO_PPDER 0x94 /* Pad Pull-down Enable Register */ | ||
54 | #define PIO_PPDSR 0x98 /* Pad Pull-down Status Register */ | ||
45 | #define PIO_OWER 0xa0 /* Output Write Enable Register */ | 55 | #define PIO_OWER 0xa0 /* Output Write Enable Register */ |
46 | #define PIO_OWDR 0xa4 /* Output Write Disable Register */ | 56 | #define PIO_OWDR 0xa4 /* Output Write Disable Register */ |
47 | #define PIO_OWSR 0xa8 /* Output Write Status Register */ | 57 | #define PIO_OWSR 0xa8 /* Output Write Status Register */ |
58 | #define PIO_AIMER 0xb0 /* Additional Interrupt Modes Enable Register */ | ||
59 | #define PIO_AIMDR 0xb4 /* Additional Interrupt Modes Disable Register */ | ||
60 | #define PIO_AIMMR 0xb8 /* Additional Interrupt Modes Mask Register */ | ||
61 | #define PIO_ESR 0xc0 /* Edge Select Register */ | ||
62 | #define PIO_LSR 0xc4 /* Level Select Register */ | ||
63 | #define PIO_ELSR 0xc8 /* Edge/Level Status Register */ | ||
64 | #define PIO_FELLSR 0xd0 /* Falling Edge/Low Level Select Register */ | ||
65 | #define PIO_REHLSR 0xd4 /* Rising Edge/ High Level Select Register */ | ||
66 | #define PIO_FRLHSR 0xd8 /* Fall/Rise - Low/High Status Register */ | ||
67 | #define PIO_SCHMITT 0x100 /* Schmitt Trigger Register */ | ||
68 | |||
69 | #define ABCDSR_PERIPH_A 0x0 | ||
70 | #define ABCDSR_PERIPH_B 0x1 | ||
71 | #define ABCDSR_PERIPH_C 0x2 | ||
72 | #define ABCDSR_PERIPH_D 0x3 | ||
48 | 73 | ||
49 | #endif | 74 | #endif |
diff --git a/arch/arm/mach-at91/include/mach/gpio.h b/arch/arm/mach-at91/include/mach/gpio.h index e3fd225121c7..eed465ab0dd7 100644 --- a/arch/arm/mach-at91/include/mach/gpio.h +++ b/arch/arm/mach-at91/include/mach/gpio.h | |||
@@ -191,10 +191,15 @@ | |||
191 | extern int __init_or_module at91_set_GPIO_periph(unsigned pin, int use_pullup); | 191 | extern int __init_or_module at91_set_GPIO_periph(unsigned pin, int use_pullup); |
192 | extern int __init_or_module at91_set_A_periph(unsigned pin, int use_pullup); | 192 | extern int __init_or_module at91_set_A_periph(unsigned pin, int use_pullup); |
193 | extern int __init_or_module at91_set_B_periph(unsigned pin, int use_pullup); | 193 | extern int __init_or_module at91_set_B_periph(unsigned pin, int use_pullup); |
194 | extern int __init_or_module at91_set_C_periph(unsigned pin, int use_pullup); | ||
195 | extern int __init_or_module at91_set_D_periph(unsigned pin, int use_pullup); | ||
194 | extern int __init_or_module at91_set_gpio_input(unsigned pin, int use_pullup); | 196 | extern int __init_or_module at91_set_gpio_input(unsigned pin, int use_pullup); |
195 | extern int __init_or_module at91_set_gpio_output(unsigned pin, int value); | 197 | extern int __init_or_module at91_set_gpio_output(unsigned pin, int value); |
196 | extern int __init_or_module at91_set_deglitch(unsigned pin, int is_on); | 198 | extern int __init_or_module at91_set_deglitch(unsigned pin, int is_on); |
199 | extern int __init_or_module at91_set_debounce(unsigned pin, int is_on, int div); | ||
197 | extern int __init_or_module at91_set_multi_drive(unsigned pin, int is_on); | 200 | extern int __init_or_module at91_set_multi_drive(unsigned pin, int is_on); |
201 | extern int __init_or_module at91_set_pulldown(unsigned pin, int is_on); | ||
202 | extern int __init_or_module at91_disable_schmitt_trig(unsigned pin); | ||
198 | 203 | ||
199 | /* callable at any time */ | 204 | /* callable at any time */ |
200 | extern int at91_set_gpio_value(unsigned pin, int value); | 205 | extern int at91_set_gpio_value(unsigned pin, int value); |
@@ -204,18 +209,6 @@ extern int at91_get_gpio_value(unsigned pin); | |||
204 | extern void at91_gpio_suspend(void); | 209 | extern void at91_gpio_suspend(void); |
205 | extern void at91_gpio_resume(void); | 210 | extern void at91_gpio_resume(void); |
206 | 211 | ||
207 | /*-------------------------------------------------------------------------*/ | ||
208 | |||
209 | /* wrappers for "new style" GPIO calls. the old AT91-specific ones should | ||
210 | * eventually be removed (along with this errno.h inclusion), and the | ||
211 | * gpio request/free calls should probably be implemented. | ||
212 | */ | ||
213 | |||
214 | #include <asm/errno.h> | ||
215 | |||
216 | #define gpio_to_irq(gpio) (gpio + NR_AIC_IRQS) | ||
217 | #define irq_to_gpio(irq) (irq - NR_AIC_IRQS) | ||
218 | |||
219 | #endif /* __ASSEMBLY__ */ | 212 | #endif /* __ASSEMBLY__ */ |
220 | 213 | ||
221 | #endif | 214 | #endif |
diff --git a/arch/arm/mach-at91/irq.c b/arch/arm/mach-at91/irq.c index be6b639ecd7b..cfcfcbe36269 100644 --- a/arch/arm/mach-at91/irq.c +++ b/arch/arm/mach-at91/irq.c | |||
@@ -24,6 +24,12 @@ | |||
24 | #include <linux/module.h> | 24 | #include <linux/module.h> |
25 | #include <linux/mm.h> | 25 | #include <linux/mm.h> |
26 | #include <linux/types.h> | 26 | #include <linux/types.h> |
27 | #include <linux/irq.h> | ||
28 | #include <linux/of.h> | ||
29 | #include <linux/of_address.h> | ||
30 | #include <linux/of_irq.h> | ||
31 | #include <linux/irqdomain.h> | ||
32 | #include <linux/err.h> | ||
27 | 33 | ||
28 | #include <mach/hardware.h> | 34 | #include <mach/hardware.h> |
29 | #include <asm/irq.h> | 35 | #include <asm/irq.h> |
@@ -34,22 +40,24 @@ | |||
34 | #include <asm/mach/map.h> | 40 | #include <asm/mach/map.h> |
35 | 41 | ||
36 | void __iomem *at91_aic_base; | 42 | void __iomem *at91_aic_base; |
43 | static struct irq_domain *at91_aic_domain; | ||
44 | static struct device_node *at91_aic_np; | ||
37 | 45 | ||
38 | static void at91_aic_mask_irq(struct irq_data *d) | 46 | static void at91_aic_mask_irq(struct irq_data *d) |
39 | { | 47 | { |
40 | /* Disable interrupt on AIC */ | 48 | /* Disable interrupt on AIC */ |
41 | at91_aic_write(AT91_AIC_IDCR, 1 << d->irq); | 49 | at91_aic_write(AT91_AIC_IDCR, 1 << d->hwirq); |
42 | } | 50 | } |
43 | 51 | ||
44 | static void at91_aic_unmask_irq(struct irq_data *d) | 52 | static void at91_aic_unmask_irq(struct irq_data *d) |
45 | { | 53 | { |
46 | /* Enable interrupt on AIC */ | 54 | /* Enable interrupt on AIC */ |
47 | at91_aic_write(AT91_AIC_IECR, 1 << d->irq); | 55 | at91_aic_write(AT91_AIC_IECR, 1 << d->hwirq); |
48 | } | 56 | } |
49 | 57 | ||
50 | unsigned int at91_extern_irq; | 58 | unsigned int at91_extern_irq; |
51 | 59 | ||
52 | #define is_extern_irq(irq) ((1 << (irq)) & at91_extern_irq) | 60 | #define is_extern_irq(hwirq) ((1 << (hwirq)) & at91_extern_irq) |
53 | 61 | ||
54 | static int at91_aic_set_type(struct irq_data *d, unsigned type) | 62 | static int at91_aic_set_type(struct irq_data *d, unsigned type) |
55 | { | 63 | { |
@@ -63,13 +71,13 @@ static int at91_aic_set_type(struct irq_data *d, unsigned type) | |||
63 | srctype = AT91_AIC_SRCTYPE_RISING; | 71 | srctype = AT91_AIC_SRCTYPE_RISING; |
64 | break; | 72 | break; |
65 | case IRQ_TYPE_LEVEL_LOW: | 73 | case IRQ_TYPE_LEVEL_LOW: |
66 | if ((d->irq == AT91_ID_FIQ) || is_extern_irq(d->irq)) /* only supported on external interrupts */ | 74 | if ((d->hwirq == AT91_ID_FIQ) || is_extern_irq(d->hwirq)) /* only supported on external interrupts */ |
67 | srctype = AT91_AIC_SRCTYPE_LOW; | 75 | srctype = AT91_AIC_SRCTYPE_LOW; |
68 | else | 76 | else |
69 | return -EINVAL; | 77 | return -EINVAL; |
70 | break; | 78 | break; |
71 | case IRQ_TYPE_EDGE_FALLING: | 79 | case IRQ_TYPE_EDGE_FALLING: |
72 | if ((d->irq == AT91_ID_FIQ) || is_extern_irq(d->irq)) /* only supported on external interrupts */ | 80 | if ((d->hwirq == AT91_ID_FIQ) || is_extern_irq(d->hwirq)) /* only supported on external interrupts */ |
73 | srctype = AT91_AIC_SRCTYPE_FALLING; | 81 | srctype = AT91_AIC_SRCTYPE_FALLING; |
74 | else | 82 | else |
75 | return -EINVAL; | 83 | return -EINVAL; |
@@ -78,8 +86,8 @@ static int at91_aic_set_type(struct irq_data *d, unsigned type) | |||
78 | return -EINVAL; | 86 | return -EINVAL; |
79 | } | 87 | } |
80 | 88 | ||
81 | smr = at91_aic_read(AT91_AIC_SMR(d->irq)) & ~AT91_AIC_SRCTYPE; | 89 | smr = at91_aic_read(AT91_AIC_SMR(d->hwirq)) & ~AT91_AIC_SRCTYPE; |
82 | at91_aic_write(AT91_AIC_SMR(d->irq), smr | srctype); | 90 | at91_aic_write(AT91_AIC_SMR(d->hwirq), smr | srctype); |
83 | return 0; | 91 | return 0; |
84 | } | 92 | } |
85 | 93 | ||
@@ -90,13 +98,13 @@ static u32 backups; | |||
90 | 98 | ||
91 | static int at91_aic_set_wake(struct irq_data *d, unsigned value) | 99 | static int at91_aic_set_wake(struct irq_data *d, unsigned value) |
92 | { | 100 | { |
93 | if (unlikely(d->irq >= 32)) | 101 | if (unlikely(d->hwirq >= NR_AIC_IRQS)) |
94 | return -EINVAL; | 102 | return -EINVAL; |
95 | 103 | ||
96 | if (value) | 104 | if (value) |
97 | wakeups |= (1 << d->irq); | 105 | wakeups |= (1 << d->hwirq); |
98 | else | 106 | else |
99 | wakeups &= ~(1 << d->irq); | 107 | wakeups &= ~(1 << d->hwirq); |
100 | 108 | ||
101 | return 0; | 109 | return 0; |
102 | } | 110 | } |
@@ -127,46 +135,112 @@ static struct irq_chip at91_aic_chip = { | |||
127 | .irq_set_wake = at91_aic_set_wake, | 135 | .irq_set_wake = at91_aic_set_wake, |
128 | }; | 136 | }; |
129 | 137 | ||
138 | static void __init at91_aic_hw_init(unsigned int spu_vector) | ||
139 | { | ||
140 | int i; | ||
141 | |||
142 | /* | ||
143 | * Perform 8 End Of Interrupt Command to make sure AIC | ||
144 | * will not Lock out nIRQ | ||
145 | */ | ||
146 | for (i = 0; i < 8; i++) | ||
147 | at91_aic_write(AT91_AIC_EOICR, 0); | ||
148 | |||
149 | /* | ||
150 | * Spurious Interrupt ID in Spurious Vector Register. | ||
151 | * When there is no current interrupt, the IRQ Vector Register | ||
152 | * reads the value stored in AIC_SPU | ||
153 | */ | ||
154 | at91_aic_write(AT91_AIC_SPU, spu_vector); | ||
155 | |||
156 | /* No debugging in AIC: Debug (Protect) Control Register */ | ||
157 | at91_aic_write(AT91_AIC_DCR, 0); | ||
158 | |||
159 | /* Disable and clear all interrupts initially */ | ||
160 | at91_aic_write(AT91_AIC_IDCR, 0xFFFFFFFF); | ||
161 | at91_aic_write(AT91_AIC_ICCR, 0xFFFFFFFF); | ||
162 | } | ||
163 | |||
164 | #if defined(CONFIG_OF) | ||
165 | static int at91_aic_irq_map(struct irq_domain *h, unsigned int virq, | ||
166 | irq_hw_number_t hw) | ||
167 | { | ||
168 | /* Put virq number in Source Vector Register */ | ||
169 | at91_aic_write(AT91_AIC_SVR(hw), virq); | ||
170 | |||
171 | /* Active Low interrupt, without priority */ | ||
172 | at91_aic_write(AT91_AIC_SMR(hw), AT91_AIC_SRCTYPE_LOW); | ||
173 | |||
174 | irq_set_chip_and_handler(virq, &at91_aic_chip, handle_level_irq); | ||
175 | set_irq_flags(virq, IRQF_VALID | IRQF_PROBE); | ||
176 | |||
177 | return 0; | ||
178 | } | ||
179 | |||
180 | static struct irq_domain_ops at91_aic_irq_ops = { | ||
181 | .map = at91_aic_irq_map, | ||
182 | .xlate = irq_domain_xlate_twocell, | ||
183 | }; | ||
184 | |||
185 | int __init at91_aic_of_init(struct device_node *node, | ||
186 | struct device_node *parent) | ||
187 | { | ||
188 | at91_aic_base = of_iomap(node, 0); | ||
189 | at91_aic_np = node; | ||
190 | |||
191 | at91_aic_domain = irq_domain_add_linear(at91_aic_np, NR_AIC_IRQS, | ||
192 | &at91_aic_irq_ops, NULL); | ||
193 | if (!at91_aic_domain) | ||
194 | panic("Unable to add AIC irq domain (DT)\n"); | ||
195 | |||
196 | irq_set_default_host(at91_aic_domain); | ||
197 | |||
198 | at91_aic_hw_init(NR_AIC_IRQS); | ||
199 | |||
200 | return 0; | ||
201 | } | ||
202 | #endif | ||
203 | |||
130 | /* | 204 | /* |
131 | * Initialize the AIC interrupt controller. | 205 | * Initialize the AIC interrupt controller. |
132 | */ | 206 | */ |
133 | void __init at91_aic_init(unsigned int priority[NR_AIC_IRQS]) | 207 | void __init at91_aic_init(unsigned int priority[NR_AIC_IRQS]) |
134 | { | 208 | { |
135 | unsigned int i; | 209 | unsigned int i; |
210 | int irq_base; | ||
136 | 211 | ||
137 | at91_aic_base = ioremap(AT91_AIC, 512); | 212 | at91_aic_base = ioremap(AT91_AIC, 512); |
138 | |||
139 | if (!at91_aic_base) | 213 | if (!at91_aic_base) |
140 | panic("Impossible to ioremap AT91_AIC\n"); | 214 | panic("Unable to ioremap AIC registers\n"); |
215 | |||
216 | /* Add irq domain for AIC */ | ||
217 | irq_base = irq_alloc_descs(-1, 0, NR_AIC_IRQS, 0); | ||
218 | if (irq_base < 0) { | ||
219 | WARN(1, "Cannot allocate irq_descs, assuming pre-allocated\n"); | ||
220 | irq_base = 0; | ||
221 | } | ||
222 | at91_aic_domain = irq_domain_add_legacy(at91_aic_np, NR_AIC_IRQS, | ||
223 | irq_base, 0, | ||
224 | &irq_domain_simple_ops, NULL); | ||
225 | |||
226 | if (!at91_aic_domain) | ||
227 | panic("Unable to add AIC irq domain\n"); | ||
228 | |||
229 | irq_set_default_host(at91_aic_domain); | ||
141 | 230 | ||
142 | /* | 231 | /* |
143 | * The IVR is used by macro get_irqnr_and_base to read and verify. | 232 | * The IVR is used by macro get_irqnr_and_base to read and verify. |
144 | * The irq number is NR_AIC_IRQS when a spurious interrupt has occurred. | 233 | * The irq number is NR_AIC_IRQS when a spurious interrupt has occurred. |
145 | */ | 234 | */ |
146 | for (i = 0; i < NR_AIC_IRQS; i++) { | 235 | for (i = 0; i < NR_AIC_IRQS; i++) { |
147 | /* Put irq number in Source Vector Register: */ | 236 | /* Put hardware irq number in Source Vector Register: */ |
148 | at91_aic_write(AT91_AIC_SVR(i), i); | 237 | at91_aic_write(AT91_AIC_SVR(i), i); |
149 | /* Active Low interrupt, with the specified priority */ | 238 | /* Active Low interrupt, with the specified priority */ |
150 | at91_aic_write(AT91_AIC_SMR(i), AT91_AIC_SRCTYPE_LOW | priority[i]); | 239 | at91_aic_write(AT91_AIC_SMR(i), AT91_AIC_SRCTYPE_LOW | priority[i]); |
151 | 240 | ||
152 | irq_set_chip_and_handler(i, &at91_aic_chip, handle_level_irq); | 241 | irq_set_chip_and_handler(i, &at91_aic_chip, handle_level_irq); |
153 | set_irq_flags(i, IRQF_VALID | IRQF_PROBE); | 242 | set_irq_flags(i, IRQF_VALID | IRQF_PROBE); |
154 | |||
155 | /* Perform 8 End Of Interrupt Command to make sure AIC will not Lock out nIRQ */ | ||
156 | if (i < 8) | ||
157 | at91_aic_write(AT91_AIC_EOICR, 0); | ||
158 | } | 243 | } |
159 | 244 | ||
160 | /* | 245 | at91_aic_hw_init(NR_AIC_IRQS); |
161 | * Spurious Interrupt ID in Spurious Vector Register is NR_AIC_IRQS | ||
162 | * When there is no current interrupt, the IRQ Vector Register reads the value stored in AIC_SPU | ||
163 | */ | ||
164 | at91_aic_write(AT91_AIC_SPU, NR_AIC_IRQS); | ||
165 | |||
166 | /* No debugging in AIC: Debug (Protect) Control Register */ | ||
167 | at91_aic_write(AT91_AIC_DCR, 0); | ||
168 | |||
169 | /* Disable and clear all interrupts initially */ | ||
170 | at91_aic_write(AT91_AIC_IDCR, 0xFFFFFFFF); | ||
171 | at91_aic_write(AT91_AIC_ICCR, 0xFFFFFFFF); | ||
172 | } | 246 | } |
diff --git a/drivers/clocksource/tcb_clksrc.c b/drivers/clocksource/tcb_clksrc.c index 55d0f95f82f9..32cb929b8eb6 100644 --- a/drivers/clocksource/tcb_clksrc.c +++ b/drivers/clocksource/tcb_clksrc.c | |||
@@ -19,6 +19,8 @@ | |||
19 | * - Two channels combine to create a free-running 32 bit counter | 19 | * - Two channels combine to create a free-running 32 bit counter |
20 | * with a base rate of 5+ MHz, packaged as a clocksource (with | 20 | * with a base rate of 5+ MHz, packaged as a clocksource (with |
21 | * resolution better than 200 nsec). | 21 | * resolution better than 200 nsec). |
22 | * - Some chips support 32 bit counter. A single channel is used for | ||
23 | * this 32 bit free-running counter. the second channel is not used. | ||
22 | * | 24 | * |
23 | * - The third channel may be used to provide a 16-bit clockevent | 25 | * - The third channel may be used to provide a 16-bit clockevent |
24 | * source, used in either periodic or oneshot mode. This runs | 26 | * source, used in either periodic or oneshot mode. This runs |
@@ -54,6 +56,11 @@ static cycle_t tc_get_cycles(struct clocksource *cs) | |||
54 | return (upper << 16) | lower; | 56 | return (upper << 16) | lower; |
55 | } | 57 | } |
56 | 58 | ||
59 | static cycle_t tc_get_cycles32(struct clocksource *cs) | ||
60 | { | ||
61 | return __raw_readl(tcaddr + ATMEL_TC_REG(0, CV)); | ||
62 | } | ||
63 | |||
57 | static struct clocksource clksrc = { | 64 | static struct clocksource clksrc = { |
58 | .name = "tcb_clksrc", | 65 | .name = "tcb_clksrc", |
59 | .rating = 200, | 66 | .rating = 200, |
@@ -209,6 +216,48 @@ static void __init setup_clkevents(struct atmel_tc *tc, int clk32k_divisor_idx) | |||
209 | 216 | ||
210 | #endif | 217 | #endif |
211 | 218 | ||
219 | static void __init tcb_setup_dual_chan(struct atmel_tc *tc, int mck_divisor_idx) | ||
220 | { | ||
221 | /* channel 0: waveform mode, input mclk/8, clock TIOA0 on overflow */ | ||
222 | __raw_writel(mck_divisor_idx /* likely divide-by-8 */ | ||
223 | | ATMEL_TC_WAVE | ||
224 | | ATMEL_TC_WAVESEL_UP /* free-run */ | ||
225 | | ATMEL_TC_ACPA_SET /* TIOA0 rises at 0 */ | ||
226 | | ATMEL_TC_ACPC_CLEAR, /* (duty cycle 50%) */ | ||
227 | tcaddr + ATMEL_TC_REG(0, CMR)); | ||
228 | __raw_writel(0x0000, tcaddr + ATMEL_TC_REG(0, RA)); | ||
229 | __raw_writel(0x8000, tcaddr + ATMEL_TC_REG(0, RC)); | ||
230 | __raw_writel(0xff, tcaddr + ATMEL_TC_REG(0, IDR)); /* no irqs */ | ||
231 | __raw_writel(ATMEL_TC_CLKEN, tcaddr + ATMEL_TC_REG(0, CCR)); | ||
232 | |||
233 | /* channel 1: waveform mode, input TIOA0 */ | ||
234 | __raw_writel(ATMEL_TC_XC1 /* input: TIOA0 */ | ||
235 | | ATMEL_TC_WAVE | ||
236 | | ATMEL_TC_WAVESEL_UP, /* free-run */ | ||
237 | tcaddr + ATMEL_TC_REG(1, CMR)); | ||
238 | __raw_writel(0xff, tcaddr + ATMEL_TC_REG(1, IDR)); /* no irqs */ | ||
239 | __raw_writel(ATMEL_TC_CLKEN, tcaddr + ATMEL_TC_REG(1, CCR)); | ||
240 | |||
241 | /* chain channel 0 to channel 1*/ | ||
242 | __raw_writel(ATMEL_TC_TC1XC1S_TIOA0, tcaddr + ATMEL_TC_BMR); | ||
243 | /* then reset all the timers */ | ||
244 | __raw_writel(ATMEL_TC_SYNC, tcaddr + ATMEL_TC_BCR); | ||
245 | } | ||
246 | |||
247 | static void __init tcb_setup_single_chan(struct atmel_tc *tc, int mck_divisor_idx) | ||
248 | { | ||
249 | /* channel 0: waveform mode, input mclk/8 */ | ||
250 | __raw_writel(mck_divisor_idx /* likely divide-by-8 */ | ||
251 | | ATMEL_TC_WAVE | ||
252 | | ATMEL_TC_WAVESEL_UP, /* free-run */ | ||
253 | tcaddr + ATMEL_TC_REG(0, CMR)); | ||
254 | __raw_writel(0xff, tcaddr + ATMEL_TC_REG(0, IDR)); /* no irqs */ | ||
255 | __raw_writel(ATMEL_TC_CLKEN, tcaddr + ATMEL_TC_REG(0, CCR)); | ||
256 | |||
257 | /* then reset all the timers */ | ||
258 | __raw_writel(ATMEL_TC_SYNC, tcaddr + ATMEL_TC_BCR); | ||
259 | } | ||
260 | |||
212 | static int __init tcb_clksrc_init(void) | 261 | static int __init tcb_clksrc_init(void) |
213 | { | 262 | { |
214 | static char bootinfo[] __initdata | 263 | static char bootinfo[] __initdata |
@@ -260,34 +309,19 @@ static int __init tcb_clksrc_init(void) | |||
260 | divided_rate / 1000000, | 309 | divided_rate / 1000000, |
261 | ((divided_rate + 500000) % 1000000) / 1000); | 310 | ((divided_rate + 500000) % 1000000) / 1000); |
262 | 311 | ||
263 | /* tclib will give us three clocks no matter what the | 312 | if (tc->tcb_config && tc->tcb_config->counter_width == 32) { |
264 | * underlying platform supports. | 313 | /* use apropriate function to read 32 bit counter */ |
265 | */ | 314 | clksrc.read = tc_get_cycles32; |
266 | clk_enable(tc->clk[1]); | 315 | /* setup ony channel 0 */ |
267 | 316 | tcb_setup_single_chan(tc, best_divisor_idx); | |
268 | /* channel 0: waveform mode, input mclk/8, clock TIOA0 on overflow */ | 317 | } else { |
269 | __raw_writel(best_divisor_idx /* likely divide-by-8 */ | 318 | /* tclib will give us three clocks no matter what the |
270 | | ATMEL_TC_WAVE | 319 | * underlying platform supports. |
271 | | ATMEL_TC_WAVESEL_UP /* free-run */ | 320 | */ |
272 | | ATMEL_TC_ACPA_SET /* TIOA0 rises at 0 */ | 321 | clk_enable(tc->clk[1]); |
273 | | ATMEL_TC_ACPC_CLEAR, /* (duty cycle 50%) */ | 322 | /* setup both channel 0 & 1 */ |
274 | tcaddr + ATMEL_TC_REG(0, CMR)); | 323 | tcb_setup_dual_chan(tc, best_divisor_idx); |
275 | __raw_writel(0x0000, tcaddr + ATMEL_TC_REG(0, RA)); | 324 | } |
276 | __raw_writel(0x8000, tcaddr + ATMEL_TC_REG(0, RC)); | ||
277 | __raw_writel(0xff, tcaddr + ATMEL_TC_REG(0, IDR)); /* no irqs */ | ||
278 | __raw_writel(ATMEL_TC_CLKEN, tcaddr + ATMEL_TC_REG(0, CCR)); | ||
279 | |||
280 | /* channel 1: waveform mode, input TIOA0 */ | ||
281 | __raw_writel(ATMEL_TC_XC1 /* input: TIOA0 */ | ||
282 | | ATMEL_TC_WAVE | ||
283 | | ATMEL_TC_WAVESEL_UP, /* free-run */ | ||
284 | tcaddr + ATMEL_TC_REG(1, CMR)); | ||
285 | __raw_writel(0xff, tcaddr + ATMEL_TC_REG(1, IDR)); /* no irqs */ | ||
286 | __raw_writel(ATMEL_TC_CLKEN, tcaddr + ATMEL_TC_REG(1, CCR)); | ||
287 | |||
288 | /* chain channel 0 to channel 1, then reset all the timers */ | ||
289 | __raw_writel(ATMEL_TC_TC1XC1S_TIOA0, tcaddr + ATMEL_TC_BMR); | ||
290 | __raw_writel(ATMEL_TC_SYNC, tcaddr + ATMEL_TC_BCR); | ||
291 | 325 | ||
292 | /* and away we go! */ | 326 | /* and away we go! */ |
293 | clocksource_register_hz(&clksrc, divided_rate); | 327 | clocksource_register_hz(&clksrc, divided_rate); |
diff --git a/drivers/misc/atmel_tclib.c b/drivers/misc/atmel_tclib.c index 4bcfc3759734..c8d8e38d0d8a 100644 --- a/drivers/misc/atmel_tclib.c +++ b/drivers/misc/atmel_tclib.c | |||
@@ -6,12 +6,10 @@ | |||
6 | #include <linux/ioport.h> | 6 | #include <linux/ioport.h> |
7 | #include <linux/kernel.h> | 7 | #include <linux/kernel.h> |
8 | #include <linux/platform_device.h> | 8 | #include <linux/platform_device.h> |
9 | #include <linux/module.h> | ||
9 | #include <linux/slab.h> | 10 | #include <linux/slab.h> |
10 | #include <linux/export.h> | 11 | #include <linux/export.h> |
11 | 12 | #include <linux/of.h> | |
12 | /* Number of bytes to reserve for the iomem resource */ | ||
13 | #define ATMEL_TC_IOMEM_SIZE 256 | ||
14 | |||
15 | 13 | ||
16 | /* | 14 | /* |
17 | * This is a thin library to solve the problem of how to portably allocate | 15 | * This is a thin library to solve the problem of how to portably allocate |
@@ -48,10 +46,17 @@ struct atmel_tc *atmel_tc_alloc(unsigned block, const char *name) | |||
48 | struct atmel_tc *tc; | 46 | struct atmel_tc *tc; |
49 | struct platform_device *pdev = NULL; | 47 | struct platform_device *pdev = NULL; |
50 | struct resource *r; | 48 | struct resource *r; |
49 | size_t size; | ||
51 | 50 | ||
52 | spin_lock(&tc_list_lock); | 51 | spin_lock(&tc_list_lock); |
53 | list_for_each_entry(tc, &tc_list, node) { | 52 | list_for_each_entry(tc, &tc_list, node) { |
54 | if (tc->pdev->id == block) { | 53 | if (tc->pdev->dev.of_node) { |
54 | if (of_alias_get_id(tc->pdev->dev.of_node, "tcb") | ||
55 | == block) { | ||
56 | pdev = tc->pdev; | ||
57 | break; | ||
58 | } | ||
59 | } else if (tc->pdev->id == block) { | ||
55 | pdev = tc->pdev; | 60 | pdev = tc->pdev; |
56 | break; | 61 | break; |
57 | } | 62 | } |
@@ -61,11 +66,15 @@ struct atmel_tc *atmel_tc_alloc(unsigned block, const char *name) | |||
61 | goto fail; | 66 | goto fail; |
62 | 67 | ||
63 | r = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 68 | r = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
64 | r = request_mem_region(r->start, ATMEL_TC_IOMEM_SIZE, name); | ||
65 | if (!r) | 69 | if (!r) |
66 | goto fail; | 70 | goto fail; |
67 | 71 | ||
68 | tc->regs = ioremap(r->start, ATMEL_TC_IOMEM_SIZE); | 72 | size = resource_size(r); |
73 | r = request_mem_region(r->start, size, name); | ||
74 | if (!r) | ||
75 | goto fail; | ||
76 | |||
77 | tc->regs = ioremap(r->start, size); | ||
69 | if (!tc->regs) | 78 | if (!tc->regs) |
70 | goto fail_ioremap; | 79 | goto fail_ioremap; |
71 | 80 | ||
@@ -76,7 +85,7 @@ out: | |||
76 | return tc; | 85 | return tc; |
77 | 86 | ||
78 | fail_ioremap: | 87 | fail_ioremap: |
79 | release_mem_region(r->start, ATMEL_TC_IOMEM_SIZE); | 88 | release_mem_region(r->start, size); |
80 | fail: | 89 | fail: |
81 | tc = NULL; | 90 | tc = NULL; |
82 | goto out; | 91 | goto out; |
@@ -96,7 +105,7 @@ void atmel_tc_free(struct atmel_tc *tc) | |||
96 | spin_lock(&tc_list_lock); | 105 | spin_lock(&tc_list_lock); |
97 | if (tc->regs) { | 106 | if (tc->regs) { |
98 | iounmap(tc->regs); | 107 | iounmap(tc->regs); |
99 | release_mem_region(tc->iomem->start, ATMEL_TC_IOMEM_SIZE); | 108 | release_mem_region(tc->iomem->start, resource_size(tc->iomem)); |
100 | tc->regs = NULL; | 109 | tc->regs = NULL; |
101 | tc->iomem = NULL; | 110 | tc->iomem = NULL; |
102 | } | 111 | } |
@@ -104,6 +113,30 @@ void atmel_tc_free(struct atmel_tc *tc) | |||
104 | } | 113 | } |
105 | EXPORT_SYMBOL_GPL(atmel_tc_free); | 114 | EXPORT_SYMBOL_GPL(atmel_tc_free); |
106 | 115 | ||
116 | #if defined(CONFIG_OF) | ||
117 | static struct atmel_tcb_config tcb_rm9200_config = { | ||
118 | .counter_width = 16, | ||
119 | }; | ||
120 | |||
121 | static struct atmel_tcb_config tcb_sam9x5_config = { | ||
122 | .counter_width = 32, | ||
123 | }; | ||
124 | |||
125 | static const struct of_device_id atmel_tcb_dt_ids[] = { | ||
126 | { | ||
127 | .compatible = "atmel,at91rm9200-tcb", | ||
128 | .data = &tcb_rm9200_config, | ||
129 | }, { | ||
130 | .compatible = "atmel,at91sam9x5-tcb", | ||
131 | .data = &tcb_sam9x5_config, | ||
132 | }, { | ||
133 | /* sentinel */ | ||
134 | } | ||
135 | }; | ||
136 | |||
137 | MODULE_DEVICE_TABLE(of, atmel_tcb_dt_ids); | ||
138 | #endif | ||
139 | |||
107 | static int __init tc_probe(struct platform_device *pdev) | 140 | static int __init tc_probe(struct platform_device *pdev) |
108 | { | 141 | { |
109 | struct atmel_tc *tc; | 142 | struct atmel_tc *tc; |
@@ -129,6 +162,14 @@ static int __init tc_probe(struct platform_device *pdev) | |||
129 | return -EINVAL; | 162 | return -EINVAL; |
130 | } | 163 | } |
131 | 164 | ||
165 | /* Now take SoC information if available */ | ||
166 | if (pdev->dev.of_node) { | ||
167 | const struct of_device_id *match; | ||
168 | match = of_match_node(atmel_tcb_dt_ids, pdev->dev.of_node); | ||
169 | if (match) | ||
170 | tc->tcb_config = match->data; | ||
171 | } | ||
172 | |||
132 | tc->clk[0] = clk; | 173 | tc->clk[0] = clk; |
133 | tc->clk[1] = clk_get(&pdev->dev, "t1_clk"); | 174 | tc->clk[1] = clk_get(&pdev->dev, "t1_clk"); |
134 | if (IS_ERR(tc->clk[1])) | 175 | if (IS_ERR(tc->clk[1])) |
@@ -153,7 +194,10 @@ static int __init tc_probe(struct platform_device *pdev) | |||
153 | } | 194 | } |
154 | 195 | ||
155 | static struct platform_driver tc_driver = { | 196 | static struct platform_driver tc_driver = { |
156 | .driver.name = "atmel_tcb", | 197 | .driver = { |
198 | .name = "atmel_tcb", | ||
199 | .of_match_table = of_match_ptr(atmel_tcb_dt_ids), | ||
200 | }, | ||
157 | }; | 201 | }; |
158 | 202 | ||
159 | static int __init tc_init(void) | 203 | static int __init tc_init(void) |
diff --git a/drivers/usb/host/ohci-at91.c b/drivers/usb/host/ohci-at91.c index 77afabc77f9b..8e855eb0bf89 100644 --- a/drivers/usb/host/ohci-at91.c +++ b/drivers/usb/host/ohci-at91.c | |||
@@ -448,10 +448,11 @@ static irqreturn_t ohci_hcd_at91_overcurrent_irq(int irq, void *data) | |||
448 | 448 | ||
449 | /* From the GPIO notifying the over-current situation, find | 449 | /* From the GPIO notifying the over-current situation, find |
450 | * out the corresponding port */ | 450 | * out the corresponding port */ |
451 | gpio = irq_to_gpio(irq); | ||
452 | for (port = 0; port < ARRAY_SIZE(pdata->overcurrent_pin); port++) { | 451 | for (port = 0; port < ARRAY_SIZE(pdata->overcurrent_pin); port++) { |
453 | if (pdata->overcurrent_pin[port] == gpio) | 452 | if (gpio_to_irq(pdata->overcurrent_pin[port]) == irq) { |
453 | gpio = pdata->overcurrent_pin[port]; | ||
454 | break; | 454 | break; |
455 | } | ||
455 | } | 456 | } |
456 | 457 | ||
457 | if (port == ARRAY_SIZE(pdata->overcurrent_pin)) { | 458 | if (port == ARRAY_SIZE(pdata->overcurrent_pin)) { |
diff --git a/include/linux/atmel_tc.h b/include/linux/atmel_tc.h index 53ba65e30caa..1d14b1dc1aee 100644 --- a/include/linux/atmel_tc.h +++ b/include/linux/atmel_tc.h | |||
@@ -34,10 +34,19 @@ | |||
34 | struct clk; | 34 | struct clk; |
35 | 35 | ||
36 | /** | 36 | /** |
37 | * struct atmel_tcb_config - SoC data for a Timer/Counter Block | ||
38 | * @counter_width: size in bits of a timer counter register | ||
39 | */ | ||
40 | struct atmel_tcb_config { | ||
41 | size_t counter_width; | ||
42 | }; | ||
43 | |||
44 | /** | ||
37 | * struct atmel_tc - information about a Timer/Counter Block | 45 | * struct atmel_tc - information about a Timer/Counter Block |
38 | * @pdev: physical device | 46 | * @pdev: physical device |
39 | * @iomem: resource associated with the I/O register | 47 | * @iomem: resource associated with the I/O register |
40 | * @regs: mapping through which the I/O registers can be accessed | 48 | * @regs: mapping through which the I/O registers can be accessed |
49 | * @tcb_config: configuration data from SoC | ||
41 | * @irq: irq for each of the three channels | 50 | * @irq: irq for each of the three channels |
42 | * @clk: internal clock source for each of the three channels | 51 | * @clk: internal clock source for each of the three channels |
43 | * @node: list node, for tclib internal use | 52 | * @node: list node, for tclib internal use |
@@ -54,6 +63,7 @@ struct atmel_tc { | |||
54 | struct platform_device *pdev; | 63 | struct platform_device *pdev; |
55 | struct resource *iomem; | 64 | struct resource *iomem; |
56 | void __iomem *regs; | 65 | void __iomem *regs; |
66 | struct atmel_tcb_config *tcb_config; | ||
57 | int irq[3]; | 67 | int irq[3]; |
58 | struct clk *clk[3]; | 68 | struct clk *clk[3]; |
59 | struct list_head node; | 69 | struct list_head node; |