diff options
author | Kukjin Kim <kgene.kim@samsung.com> | 2012-11-18 20:03:02 -0500 |
---|---|---|
committer | Kukjin Kim <kgene.kim@samsung.com> | 2012-11-18 20:03:02 -0500 |
commit | bdd45eaa7b1ca218dc972a4beeab12698823b4bc (patch) | |
tree | 9d4de30138f40236bc91cff2e6f40309914bcfdb | |
parent | ba51bdd306a21ab0fabbea3a92541af0ee9fb8f6 (diff) | |
parent | 6edc794a5ff245faf60488d32e9fdbeb0aad2223 (diff) |
Merge branch 'next/pinctrl-samsung' into next/dt-exynos4x12
-rw-r--r-- | Documentation/devicetree/bindings/pinctrl/samsung-pinctrl.txt | 119 | ||||
-rw-r--r-- | arch/arm/boot/dts/exynos4210-pinctrl.dtsi | 278 | ||||
-rw-r--r-- | arch/arm/boot/dts/exynos4210.dtsi | 241 | ||||
-rw-r--r-- | drivers/pinctrl/pinctrl-exynos.c | 477 | ||||
-rw-r--r-- | drivers/pinctrl/pinctrl-exynos.h | 170 | ||||
-rw-r--r-- | drivers/pinctrl/pinctrl-samsung.c | 205 | ||||
-rw-r--r-- | drivers/pinctrl/pinctrl-samsung.h | 30 |
7 files changed, 855 insertions, 665 deletions
diff --git a/Documentation/devicetree/bindings/pinctrl/samsung-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/samsung-pinctrl.txt index 03dee50532f5..e97a27856b21 100644 --- a/Documentation/devicetree/bindings/pinctrl/samsung-pinctrl.txt +++ b/Documentation/devicetree/bindings/pinctrl/samsung-pinctrl.txt | |||
@@ -8,13 +8,20 @@ on-chip controllers onto these pads. | |||
8 | Required Properties: | 8 | Required Properties: |
9 | - compatible: should be one of the following. | 9 | - compatible: should be one of the following. |
10 | - "samsung,pinctrl-exynos4210": for Exynos4210 compatible pin-controller. | 10 | - "samsung,pinctrl-exynos4210": for Exynos4210 compatible pin-controller. |
11 | - "samsung,pinctrl-exynos4x12": for Exynos4x12 compatible pin-controller. | ||
11 | - "samsung,pinctrl-exynos5250": for Exynos5250 compatible pin-controller. | 12 | - "samsung,pinctrl-exynos5250": for Exynos5250 compatible pin-controller. |
12 | 13 | ||
13 | - reg: Base address of the pin controller hardware module and length of | 14 | - reg: Base address of the pin controller hardware module and length of |
14 | the address space it occupies. | 15 | the address space it occupies. |
15 | 16 | ||
16 | - interrupts: interrupt specifier for the controller. The format and value of | 17 | - Pin banks as child nodes: Pin banks of the controller are represented by child |
17 | the interrupt specifier depends on the interrupt parent for the controller. | 18 | nodes of the controller node. Bank name is taken from name of the node. Each |
19 | bank node must contain following properties: | ||
20 | |||
21 | - gpio-controller: identifies the node as a gpio controller and pin bank. | ||
22 | - #gpio-cells: number of cells in GPIO specifier. Since the generic GPIO | ||
23 | binding is used, the amount of cells must be specified as 2. See generic | ||
24 | GPIO binding documentation for description of particular cells. | ||
18 | 25 | ||
19 | - Pin mux/config groups as child nodes: The pin mux (selecting pin function | 26 | - Pin mux/config groups as child nodes: The pin mux (selecting pin function |
20 | mode) and pin config (pull up/down, driver strength) settings are represented | 27 | mode) and pin config (pull up/down, driver strength) settings are represented |
@@ -72,16 +79,24 @@ used as system wakeup events. | |||
72 | A. External GPIO Interrupts: For supporting external gpio interrupts, the | 79 | A. External GPIO Interrupts: For supporting external gpio interrupts, the |
73 | following properties should be specified in the pin-controller device node. | 80 | following properties should be specified in the pin-controller device node. |
74 | 81 | ||
75 | - interrupt-controller: identifies the controller node as interrupt-parent. | 82 | - interrupt-parent: phandle of the interrupt parent to which the external |
76 | - #interrupt-cells: the value of this property should be 2. | 83 | GPIO interrupts are forwarded to. |
77 | - First Cell: represents the external gpio interrupt number local to the | 84 | - interrupts: interrupt specifier for the controller. The format and value of |
78 | external gpio interrupt space of the controller. | 85 | the interrupt specifier depends on the interrupt parent for the controller. |
79 | - Second Cell: flags to identify the type of the interrupt | 86 | |
80 | - 1 = rising edge triggered | 87 | In addition, following properties must be present in node of every bank |
81 | - 2 = falling edge triggered | 88 | of pins supporting GPIO interrupts: |
82 | - 3 = rising and falling edge triggered | 89 | |
83 | - 4 = high level triggered | 90 | - interrupt-controller: identifies the controller node as interrupt-parent. |
84 | - 8 = low level triggered | 91 | - #interrupt-cells: the value of this property should be 2. |
92 | - First Cell: represents the external gpio interrupt number local to the | ||
93 | external gpio interrupt space of the controller. | ||
94 | - Second Cell: flags to identify the type of the interrupt | ||
95 | - 1 = rising edge triggered | ||
96 | - 2 = falling edge triggered | ||
97 | - 3 = rising and falling edge triggered | ||
98 | - 4 = high level triggered | ||
99 | - 8 = low level triggered | ||
85 | 100 | ||
86 | B. External Wakeup Interrupts: For supporting external wakeup interrupts, a | 101 | B. External Wakeup Interrupts: For supporting external wakeup interrupts, a |
87 | child node representing the external wakeup interrupt controller should be | 102 | child node representing the external wakeup interrupt controller should be |
@@ -94,6 +109,11 @@ B. External Wakeup Interrupts: For supporting external wakeup interrupts, a | |||
94 | found on Samsung Exynos4210 SoC. | 109 | found on Samsung Exynos4210 SoC. |
95 | - interrupt-parent: phandle of the interrupt parent to which the external | 110 | - interrupt-parent: phandle of the interrupt parent to which the external |
96 | wakeup interrupts are forwarded to. | 111 | wakeup interrupts are forwarded to. |
112 | - interrupts: interrupt used by multiplexed wakeup interrupts. | ||
113 | |||
114 | In addition, following properties must be present in node of every bank | ||
115 | of pins supporting wake-up interrupts: | ||
116 | |||
97 | - interrupt-controller: identifies the node as interrupt-parent. | 117 | - interrupt-controller: identifies the node as interrupt-parent. |
98 | - #interrupt-cells: the value of this property should be 2 | 118 | - #interrupt-cells: the value of this property should be 2 |
99 | - First Cell: represents the external wakeup interrupt number local to | 119 | - First Cell: represents the external wakeup interrupt number local to |
@@ -105,11 +125,63 @@ B. External Wakeup Interrupts: For supporting external wakeup interrupts, a | |||
105 | - 4 = high level triggered | 125 | - 4 = high level triggered |
106 | - 8 = low level triggered | 126 | - 8 = low level triggered |
107 | 127 | ||
128 | Node of every bank of pins supporting direct wake-up interrupts (without | ||
129 | multiplexing) must contain following properties: | ||
130 | |||
131 | - interrupt-parent: phandle of the interrupt parent to which the external | ||
132 | wakeup interrupts are forwarded to. | ||
133 | - interrupts: interrupts of the interrupt parent which are used for external | ||
134 | wakeup interrupts from pins of the bank, must contain interrupts for all | ||
135 | pins of the bank. | ||
136 | |||
108 | Aliases: | 137 | Aliases: |
109 | 138 | ||
110 | All the pin controller nodes should be represented in the aliases node using | 139 | All the pin controller nodes should be represented in the aliases node using |
111 | the following format 'pinctrl{n}' where n is a unique number for the alias. | 140 | the following format 'pinctrl{n}' where n is a unique number for the alias. |
112 | 141 | ||
142 | Example: A pin-controller node with pin banks: | ||
143 | |||
144 | pinctrl_0: pinctrl@11400000 { | ||
145 | compatible = "samsung,pinctrl-exynos4210"; | ||
146 | reg = <0x11400000 0x1000>; | ||
147 | interrupts = <0 47 0>; | ||
148 | |||
149 | /* ... */ | ||
150 | |||
151 | /* Pin bank without external interrupts */ | ||
152 | gpy0: gpy0 { | ||
153 | gpio-controller; | ||
154 | #gpio-cells = <2>; | ||
155 | }; | ||
156 | |||
157 | /* ... */ | ||
158 | |||
159 | /* Pin bank with external GPIO or muxed wake-up interrupts */ | ||
160 | gpj0: gpj0 { | ||
161 | gpio-controller; | ||
162 | #gpio-cells = <2>; | ||
163 | |||
164 | interrupt-controller; | ||
165 | #interrupt-cells = <2>; | ||
166 | }; | ||
167 | |||
168 | /* ... */ | ||
169 | |||
170 | /* Pin bank with external direct wake-up interrupts */ | ||
171 | gpx0: gpx0 { | ||
172 | gpio-controller; | ||
173 | #gpio-cells = <2>; | ||
174 | |||
175 | interrupt-controller; | ||
176 | interrupt-parent = <&gic>; | ||
177 | interrupts = <0 16 0>, <0 17 0>, <0 18 0>, <0 19 0>, | ||
178 | <0 20 0>, <0 21 0>, <0 22 0>, <0 23 0>; | ||
179 | #interrupt-cells = <2>; | ||
180 | }; | ||
181 | |||
182 | /* ... */ | ||
183 | }; | ||
184 | |||
113 | Example 1: A pin-controller node with pin groups. | 185 | Example 1: A pin-controller node with pin groups. |
114 | 186 | ||
115 | pinctrl_0: pinctrl@11400000 { | 187 | pinctrl_0: pinctrl@11400000 { |
@@ -117,6 +189,8 @@ Example 1: A pin-controller node with pin groups. | |||
117 | reg = <0x11400000 0x1000>; | 189 | reg = <0x11400000 0x1000>; |
118 | interrupts = <0 47 0>; | 190 | interrupts = <0 47 0>; |
119 | 191 | ||
192 | /* ... */ | ||
193 | |||
120 | uart0_data: uart0-data { | 194 | uart0_data: uart0-data { |
121 | samsung,pins = "gpa0-0", "gpa0-1"; | 195 | samsung,pins = "gpa0-0", "gpa0-1"; |
122 | samsung,pin-function = <2>; | 196 | samsung,pin-function = <2>; |
@@ -158,20 +232,14 @@ Example 2: A pin-controller node with external wakeup interrupt controller node. | |||
158 | pinctrl_1: pinctrl@11000000 { | 232 | pinctrl_1: pinctrl@11000000 { |
159 | compatible = "samsung,pinctrl-exynos4210"; | 233 | compatible = "samsung,pinctrl-exynos4210"; |
160 | reg = <0x11000000 0x1000>; | 234 | reg = <0x11000000 0x1000>; |
161 | interrupts = <0 46 0>; | 235 | interrupts = <0 46 0> |
162 | interrupt-controller; | ||
163 | #interrupt-cells = <2>; | ||
164 | 236 | ||
165 | wakup_eint: wakeup-interrupt-controller { | 237 | /* ... */ |
238 | |||
239 | wakeup-interrupt-controller { | ||
166 | compatible = "samsung,exynos4210-wakeup-eint"; | 240 | compatible = "samsung,exynos4210-wakeup-eint"; |
167 | interrupt-parent = <&gic>; | 241 | interrupt-parent = <&gic>; |
168 | interrupt-controller; | 242 | interrupts = <0 32 0>; |
169 | #interrupt-cells = <2>; | ||
170 | interrupts = <0 16 0>, <0 17 0>, <0 18 0>, <0 19 0>, | ||
171 | <0 20 0>, <0 21 0>, <0 22 0>, <0 23 0>, | ||
172 | <0 24 0>, <0 25 0>, <0 26 0>, <0 27 0>, | ||
173 | <0 28 0>, <0 29 0>, <0 30 0>, <0 31 0>, | ||
174 | <0 32 0>; | ||
175 | }; | 243 | }; |
176 | }; | 244 | }; |
177 | 245 | ||
@@ -190,7 +258,8 @@ Example 4: Set up the default pin state for uart controller. | |||
190 | 258 | ||
191 | static int s3c24xx_serial_probe(struct platform_device *pdev) { | 259 | static int s3c24xx_serial_probe(struct platform_device *pdev) { |
192 | struct pinctrl *pinctrl; | 260 | struct pinctrl *pinctrl; |
193 | ... | 261 | |
194 | ... | 262 | /* ... */ |
263 | |||
195 | pinctrl = devm_pinctrl_get_select_default(&pdev->dev); | 264 | pinctrl = devm_pinctrl_get_select_default(&pdev->dev); |
196 | } | 265 | } |
diff --git a/arch/arm/boot/dts/exynos4210-pinctrl.dtsi b/arch/arm/boot/dts/exynos4210-pinctrl.dtsi index b12cf272ad0d..6a4a1a04221c 100644 --- a/arch/arm/boot/dts/exynos4210-pinctrl.dtsi +++ b/arch/arm/boot/dts/exynos4210-pinctrl.dtsi | |||
@@ -16,6 +16,134 @@ | |||
16 | 16 | ||
17 | / { | 17 | / { |
18 | pinctrl@11400000 { | 18 | pinctrl@11400000 { |
19 | gpa0: gpa0 { | ||
20 | gpio-controller; | ||
21 | #gpio-cells = <2>; | ||
22 | |||
23 | interrupt-controller; | ||
24 | #interrupt-cells = <2>; | ||
25 | }; | ||
26 | |||
27 | gpa1: gpa1 { | ||
28 | gpio-controller; | ||
29 | #gpio-cells = <2>; | ||
30 | |||
31 | interrupt-controller; | ||
32 | #interrupt-cells = <2>; | ||
33 | }; | ||
34 | |||
35 | gpb: gpb { | ||
36 | gpio-controller; | ||
37 | #gpio-cells = <2>; | ||
38 | |||
39 | interrupt-controller; | ||
40 | #interrupt-cells = <2>; | ||
41 | }; | ||
42 | |||
43 | gpc0: gpc0 { | ||
44 | gpio-controller; | ||
45 | #gpio-cells = <2>; | ||
46 | |||
47 | interrupt-controller; | ||
48 | #interrupt-cells = <2>; | ||
49 | }; | ||
50 | |||
51 | gpc1: gpc1 { | ||
52 | gpio-controller; | ||
53 | #gpio-cells = <2>; | ||
54 | |||
55 | interrupt-controller; | ||
56 | #interrupt-cells = <2>; | ||
57 | }; | ||
58 | |||
59 | gpd0: gpd0 { | ||
60 | gpio-controller; | ||
61 | #gpio-cells = <2>; | ||
62 | |||
63 | interrupt-controller; | ||
64 | #interrupt-cells = <2>; | ||
65 | }; | ||
66 | |||
67 | gpd1: gpd1 { | ||
68 | gpio-controller; | ||
69 | #gpio-cells = <2>; | ||
70 | |||
71 | interrupt-controller; | ||
72 | #interrupt-cells = <2>; | ||
73 | }; | ||
74 | |||
75 | gpe0: gpe0 { | ||
76 | gpio-controller; | ||
77 | #gpio-cells = <2>; | ||
78 | |||
79 | interrupt-controller; | ||
80 | #interrupt-cells = <2>; | ||
81 | }; | ||
82 | |||
83 | gpe1: gpe1 { | ||
84 | gpio-controller; | ||
85 | #gpio-cells = <2>; | ||
86 | |||
87 | interrupt-controller; | ||
88 | #interrupt-cells = <2>; | ||
89 | }; | ||
90 | |||
91 | gpe2: gpe2 { | ||
92 | gpio-controller; | ||
93 | #gpio-cells = <2>; | ||
94 | |||
95 | interrupt-controller; | ||
96 | #interrupt-cells = <2>; | ||
97 | }; | ||
98 | |||
99 | gpe3: gpe3 { | ||
100 | gpio-controller; | ||
101 | #gpio-cells = <2>; | ||
102 | |||
103 | interrupt-controller; | ||
104 | #interrupt-cells = <2>; | ||
105 | }; | ||
106 | |||
107 | gpe4: gpe4 { | ||
108 | gpio-controller; | ||
109 | #gpio-cells = <2>; | ||
110 | |||
111 | interrupt-controller; | ||
112 | #interrupt-cells = <2>; | ||
113 | }; | ||
114 | |||
115 | gpf0: gpf0 { | ||
116 | gpio-controller; | ||
117 | #gpio-cells = <2>; | ||
118 | |||
119 | interrupt-controller; | ||
120 | #interrupt-cells = <2>; | ||
121 | }; | ||
122 | |||
123 | gpf1: gpf1 { | ||
124 | gpio-controller; | ||
125 | #gpio-cells = <2>; | ||
126 | |||
127 | interrupt-controller; | ||
128 | #interrupt-cells = <2>; | ||
129 | }; | ||
130 | |||
131 | gpf2: gpf2 { | ||
132 | gpio-controller; | ||
133 | #gpio-cells = <2>; | ||
134 | |||
135 | interrupt-controller; | ||
136 | #interrupt-cells = <2>; | ||
137 | }; | ||
138 | |||
139 | gpf3: gpf3 { | ||
140 | gpio-controller; | ||
141 | #gpio-cells = <2>; | ||
142 | |||
143 | interrupt-controller; | ||
144 | #interrupt-cells = <2>; | ||
145 | }; | ||
146 | |||
19 | uart0_data: uart0-data { | 147 | uart0_data: uart0-data { |
20 | samsung,pins = "gpa0-0", "gpa0-1"; | 148 | samsung,pins = "gpa0-0", "gpa0-1"; |
21 | samsung,pin-function = <0x2>; | 149 | samsung,pin-function = <0x2>; |
@@ -205,6 +333,151 @@ | |||
205 | }; | 333 | }; |
206 | 334 | ||
207 | pinctrl@11000000 { | 335 | pinctrl@11000000 { |
336 | gpj0: gpj0 { | ||
337 | gpio-controller; | ||
338 | #gpio-cells = <2>; | ||
339 | |||
340 | interrupt-controller; | ||
341 | #interrupt-cells = <2>; | ||
342 | }; | ||
343 | |||
344 | gpj1: gpj1 { | ||
345 | gpio-controller; | ||
346 | #gpio-cells = <2>; | ||
347 | |||
348 | interrupt-controller; | ||
349 | #interrupt-cells = <2>; | ||
350 | }; | ||
351 | |||
352 | gpk0: gpk0 { | ||
353 | gpio-controller; | ||
354 | #gpio-cells = <2>; | ||
355 | |||
356 | interrupt-controller; | ||
357 | #interrupt-cells = <2>; | ||
358 | }; | ||
359 | |||
360 | gpk1: gpk1 { | ||
361 | gpio-controller; | ||
362 | #gpio-cells = <2>; | ||
363 | |||
364 | interrupt-controller; | ||
365 | #interrupt-cells = <2>; | ||
366 | }; | ||
367 | |||
368 | gpk2: gpk2 { | ||
369 | gpio-controller; | ||
370 | #gpio-cells = <2>; | ||
371 | |||
372 | interrupt-controller; | ||
373 | #interrupt-cells = <2>; | ||
374 | }; | ||
375 | |||
376 | gpk3: gpk3 { | ||
377 | gpio-controller; | ||
378 | #gpio-cells = <2>; | ||
379 | |||
380 | interrupt-controller; | ||
381 | #interrupt-cells = <2>; | ||
382 | }; | ||
383 | |||
384 | gpl0: gpl0 { | ||
385 | gpio-controller; | ||
386 | #gpio-cells = <2>; | ||
387 | |||
388 | interrupt-controller; | ||
389 | #interrupt-cells = <2>; | ||
390 | }; | ||
391 | |||
392 | gpl1: gpl1 { | ||
393 | gpio-controller; | ||
394 | #gpio-cells = <2>; | ||
395 | |||
396 | interrupt-controller; | ||
397 | #interrupt-cells = <2>; | ||
398 | }; | ||
399 | |||
400 | gpl2: gpl2 { | ||
401 | gpio-controller; | ||
402 | #gpio-cells = <2>; | ||
403 | |||
404 | interrupt-controller; | ||
405 | #interrupt-cells = <2>; | ||
406 | }; | ||
407 | |||
408 | gpy0: gpy0 { | ||
409 | gpio-controller; | ||
410 | #gpio-cells = <2>; | ||
411 | }; | ||
412 | |||
413 | gpy1: gpy1 { | ||
414 | gpio-controller; | ||
415 | #gpio-cells = <2>; | ||
416 | }; | ||
417 | |||
418 | gpy2: gpy2 { | ||
419 | gpio-controller; | ||
420 | #gpio-cells = <2>; | ||
421 | }; | ||
422 | |||
423 | gpy3: gpy3 { | ||
424 | gpio-controller; | ||
425 | #gpio-cells = <2>; | ||
426 | }; | ||
427 | |||
428 | gpy4: gpy4 { | ||
429 | gpio-controller; | ||
430 | #gpio-cells = <2>; | ||
431 | }; | ||
432 | |||
433 | gpy5: gpy5 { | ||
434 | gpio-controller; | ||
435 | #gpio-cells = <2>; | ||
436 | }; | ||
437 | |||
438 | gpy6: gpy6 { | ||
439 | gpio-controller; | ||
440 | #gpio-cells = <2>; | ||
441 | }; | ||
442 | |||
443 | gpx0: gpx0 { | ||
444 | gpio-controller; | ||
445 | #gpio-cells = <2>; | ||
446 | |||
447 | interrupt-controller; | ||
448 | interrupt-parent = <&gic>; | ||
449 | interrupts = <0 16 0>, <0 17 0>, <0 18 0>, <0 19 0>, | ||
450 | <0 20 0>, <0 21 0>, <0 22 0>, <0 23 0>; | ||
451 | #interrupt-cells = <2>; | ||
452 | }; | ||
453 | |||
454 | gpx1: gpx1 { | ||
455 | gpio-controller; | ||
456 | #gpio-cells = <2>; | ||
457 | |||
458 | interrupt-controller; | ||
459 | interrupt-parent = <&gic>; | ||
460 | interrupts = <0 24 0>, <0 25 0>, <0 26 0>, <0 27 0>, | ||
461 | <0 28 0>, <0 29 0>, <0 30 0>, <0 31 0>; | ||
462 | #interrupt-cells = <2>; | ||
463 | }; | ||
464 | |||
465 | gpx2: gpx2 { | ||
466 | gpio-controller; | ||
467 | #gpio-cells = <2>; | ||
468 | |||
469 | interrupt-controller; | ||
470 | #interrupt-cells = <2>; | ||
471 | }; | ||
472 | |||
473 | gpx3: gpx3 { | ||
474 | gpio-controller; | ||
475 | #gpio-cells = <2>; | ||
476 | |||
477 | interrupt-controller; | ||
478 | #interrupt-cells = <2>; | ||
479 | }; | ||
480 | |||
208 | sd0_clk: sd0-clk { | 481 | sd0_clk: sd0-clk { |
209 | samsung,pins = "gpk0-0"; | 482 | samsung,pins = "gpk0-0"; |
210 | samsung,pin-function = <2>; | 483 | samsung,pin-function = <2>; |
@@ -438,6 +711,11 @@ | |||
438 | }; | 711 | }; |
439 | 712 | ||
440 | pinctrl@03860000 { | 713 | pinctrl@03860000 { |
714 | gpz: gpz { | ||
715 | gpio-controller; | ||
716 | #gpio-cells = <2>; | ||
717 | }; | ||
718 | |||
441 | i2s0_bus: i2s0-bus { | 719 | i2s0_bus: i2s0-bus { |
442 | samsung,pins = "gpz-0", "gpz-1", "gpz-2", "gpz-3", | 720 | samsung,pins = "gpz-0", "gpz-1", "gpz-2", "gpz-3", |
443 | "gpz-4", "gpz-5", "gpz-6"; | 721 | "gpz-4", "gpz-5", "gpz-6"; |
diff --git a/arch/arm/boot/dts/exynos4210.dtsi b/arch/arm/boot/dts/exynos4210.dtsi index 214c557eda7f..d877dbe7ac0e 100644 --- a/arch/arm/boot/dts/exynos4210.dtsi +++ b/arch/arm/boot/dts/exynos4210.dtsi | |||
@@ -46,27 +46,17 @@ | |||
46 | compatible = "samsung,pinctrl-exynos4210"; | 46 | compatible = "samsung,pinctrl-exynos4210"; |
47 | reg = <0x11400000 0x1000>; | 47 | reg = <0x11400000 0x1000>; |
48 | interrupts = <0 47 0>; | 48 | interrupts = <0 47 0>; |
49 | interrupt-controller; | ||
50 | #interrupt-cells = <2>; | ||
51 | }; | 49 | }; |
52 | 50 | ||
53 | pinctrl_1: pinctrl@11000000 { | 51 | pinctrl_1: pinctrl@11000000 { |
54 | compatible = "samsung,pinctrl-exynos4210"; | 52 | compatible = "samsung,pinctrl-exynos4210"; |
55 | reg = <0x11000000 0x1000>; | 53 | reg = <0x11000000 0x1000>; |
56 | interrupts = <0 46 0>; | 54 | interrupts = <0 46 0>; |
57 | interrupt-controller; | ||
58 | #interrupt-cells = <2>; | ||
59 | 55 | ||
60 | wakup_eint: wakeup-interrupt-controller { | 56 | wakup_eint: wakeup-interrupt-controller { |
61 | compatible = "samsung,exynos4210-wakeup-eint"; | 57 | compatible = "samsung,exynos4210-wakeup-eint"; |
62 | interrupt-parent = <&gic>; | 58 | interrupt-parent = <&gic>; |
63 | interrupt-controller; | 59 | interrupts = <0 32 0>; |
64 | #interrupt-cells = <2>; | ||
65 | interrupts = <0 16 0>, <0 17 0>, <0 18 0>, <0 19 0>, | ||
66 | <0 20 0>, <0 21 0>, <0 22 0>, <0 23 0>, | ||
67 | <0 24 0>, <0 25 0>, <0 26 0>, <0 27 0>, | ||
68 | <0 28 0>, <0 29 0>, <0 30 0>, <0 31 0>, | ||
69 | <0 32 0>; | ||
70 | }; | 60 | }; |
71 | }; | 61 | }; |
72 | 62 | ||
@@ -74,233 +64,4 @@ | |||
74 | compatible = "samsung,pinctrl-exynos4210"; | 64 | compatible = "samsung,pinctrl-exynos4210"; |
75 | reg = <0x03860000 0x1000>; | 65 | reg = <0x03860000 0x1000>; |
76 | }; | 66 | }; |
77 | |||
78 | gpio-controllers { | ||
79 | #address-cells = <1>; | ||
80 | #size-cells = <1>; | ||
81 | gpio-controller; | ||
82 | ranges; | ||
83 | |||
84 | gpa0: gpio-controller@11400000 { | ||
85 | compatible = "samsung,exynos4-gpio"; | ||
86 | reg = <0x11400000 0x20>; | ||
87 | #gpio-cells = <4>; | ||
88 | }; | ||
89 | |||
90 | gpa1: gpio-controller@11400020 { | ||
91 | compatible = "samsung,exynos4-gpio"; | ||
92 | reg = <0x11400020 0x20>; | ||
93 | #gpio-cells = <4>; | ||
94 | }; | ||
95 | |||
96 | gpb: gpio-controller@11400040 { | ||
97 | compatible = "samsung,exynos4-gpio"; | ||
98 | reg = <0x11400040 0x20>; | ||
99 | #gpio-cells = <4>; | ||
100 | }; | ||
101 | |||
102 | gpc0: gpio-controller@11400060 { | ||
103 | compatible = "samsung,exynos4-gpio"; | ||
104 | reg = <0x11400060 0x20>; | ||
105 | #gpio-cells = <4>; | ||
106 | }; | ||
107 | |||
108 | gpc1: gpio-controller@11400080 { | ||
109 | compatible = "samsung,exynos4-gpio"; | ||
110 | reg = <0x11400080 0x20>; | ||
111 | #gpio-cells = <4>; | ||
112 | }; | ||
113 | |||
114 | gpd0: gpio-controller@114000A0 { | ||
115 | compatible = "samsung,exynos4-gpio"; | ||
116 | reg = <0x114000A0 0x20>; | ||
117 | #gpio-cells = <4>; | ||
118 | }; | ||
119 | |||
120 | gpd1: gpio-controller@114000C0 { | ||
121 | compatible = "samsung,exynos4-gpio"; | ||
122 | reg = <0x114000C0 0x20>; | ||
123 | #gpio-cells = <4>; | ||
124 | }; | ||
125 | |||
126 | gpe0: gpio-controller@114000E0 { | ||
127 | compatible = "samsung,exynos4-gpio"; | ||
128 | reg = <0x114000E0 0x20>; | ||
129 | #gpio-cells = <4>; | ||
130 | }; | ||
131 | |||
132 | gpe1: gpio-controller@11400100 { | ||
133 | compatible = "samsung,exynos4-gpio"; | ||
134 | reg = <0x11400100 0x20>; | ||
135 | #gpio-cells = <4>; | ||
136 | }; | ||
137 | |||
138 | gpe2: gpio-controller@11400120 { | ||
139 | compatible = "samsung,exynos4-gpio"; | ||
140 | reg = <0x11400120 0x20>; | ||
141 | #gpio-cells = <4>; | ||
142 | }; | ||
143 | |||
144 | gpe3: gpio-controller@11400140 { | ||
145 | compatible = "samsung,exynos4-gpio"; | ||
146 | reg = <0x11400140 0x20>; | ||
147 | #gpio-cells = <4>; | ||
148 | }; | ||
149 | |||
150 | gpe4: gpio-controller@11400160 { | ||
151 | compatible = "samsung,exynos4-gpio"; | ||
152 | reg = <0x11400160 0x20>; | ||
153 | #gpio-cells = <4>; | ||
154 | }; | ||
155 | |||
156 | gpf0: gpio-controller@11400180 { | ||
157 | compatible = "samsung,exynos4-gpio"; | ||
158 | reg = <0x11400180 0x20>; | ||
159 | #gpio-cells = <4>; | ||
160 | }; | ||
161 | |||
162 | gpf1: gpio-controller@114001A0 { | ||
163 | compatible = "samsung,exynos4-gpio"; | ||
164 | reg = <0x114001A0 0x20>; | ||
165 | #gpio-cells = <4>; | ||
166 | }; | ||
167 | |||
168 | gpf2: gpio-controller@114001C0 { | ||
169 | compatible = "samsung,exynos4-gpio"; | ||
170 | reg = <0x114001C0 0x20>; | ||
171 | #gpio-cells = <4>; | ||
172 | }; | ||
173 | |||
174 | gpf3: gpio-controller@114001E0 { | ||
175 | compatible = "samsung,exynos4-gpio"; | ||
176 | reg = <0x114001E0 0x20>; | ||
177 | #gpio-cells = <4>; | ||
178 | }; | ||
179 | |||
180 | gpj0: gpio-controller@11000000 { | ||
181 | compatible = "samsung,exynos4-gpio"; | ||
182 | reg = <0x11000000 0x20>; | ||
183 | #gpio-cells = <4>; | ||
184 | }; | ||
185 | |||
186 | gpj1: gpio-controller@11000020 { | ||
187 | compatible = "samsung,exynos4-gpio"; | ||
188 | reg = <0x11000020 0x20>; | ||
189 | #gpio-cells = <4>; | ||
190 | }; | ||
191 | |||
192 | gpk0: gpio-controller@11000040 { | ||
193 | compatible = "samsung,exynos4-gpio"; | ||
194 | reg = <0x11000040 0x20>; | ||
195 | #gpio-cells = <4>; | ||
196 | }; | ||
197 | |||
198 | gpk1: gpio-controller@11000060 { | ||
199 | compatible = "samsung,exynos4-gpio"; | ||
200 | reg = <0x11000060 0x20>; | ||
201 | #gpio-cells = <4>; | ||
202 | }; | ||
203 | |||
204 | gpk2: gpio-controller@11000080 { | ||
205 | compatible = "samsung,exynos4-gpio"; | ||
206 | reg = <0x11000080 0x20>; | ||
207 | #gpio-cells = <4>; | ||
208 | }; | ||
209 | |||
210 | gpk3: gpio-controller@110000A0 { | ||
211 | compatible = "samsung,exynos4-gpio"; | ||
212 | reg = <0x110000A0 0x20>; | ||
213 | #gpio-cells = <4>; | ||
214 | }; | ||
215 | |||
216 | gpl0: gpio-controller@110000C0 { | ||
217 | compatible = "samsung,exynos4-gpio"; | ||
218 | reg = <0x110000C0 0x20>; | ||
219 | #gpio-cells = <4>; | ||
220 | }; | ||
221 | |||
222 | gpl1: gpio-controller@110000E0 { | ||
223 | compatible = "samsung,exynos4-gpio"; | ||
224 | reg = <0x110000E0 0x20>; | ||
225 | #gpio-cells = <4>; | ||
226 | }; | ||
227 | |||
228 | gpl2: gpio-controller@11000100 { | ||
229 | compatible = "samsung,exynos4-gpio"; | ||
230 | reg = <0x11000100 0x20>; | ||
231 | #gpio-cells = <4>; | ||
232 | }; | ||
233 | |||
234 | gpy0: gpio-controller@11000120 { | ||
235 | compatible = "samsung,exynos4-gpio"; | ||
236 | reg = <0x11000120 0x20>; | ||
237 | #gpio-cells = <4>; | ||
238 | }; | ||
239 | |||
240 | gpy1: gpio-controller@11000140 { | ||
241 | compatible = "samsung,exynos4-gpio"; | ||
242 | reg = <0x11000140 0x20>; | ||
243 | #gpio-cells = <4>; | ||
244 | }; | ||
245 | |||
246 | gpy2: gpio-controller@11000160 { | ||
247 | compatible = "samsung,exynos4-gpio"; | ||
248 | reg = <0x11000160 0x20>; | ||
249 | #gpio-cells = <4>; | ||
250 | }; | ||
251 | |||
252 | gpy3: gpio-controller@11000180 { | ||
253 | compatible = "samsung,exynos4-gpio"; | ||
254 | reg = <0x11000180 0x20>; | ||
255 | #gpio-cells = <4>; | ||
256 | }; | ||
257 | |||
258 | gpy4: gpio-controller@110001A0 { | ||
259 | compatible = "samsung,exynos4-gpio"; | ||
260 | reg = <0x110001A0 0x20>; | ||
261 | #gpio-cells = <4>; | ||
262 | }; | ||
263 | |||
264 | gpy5: gpio-controller@110001C0 { | ||
265 | compatible = "samsung,exynos4-gpio"; | ||
266 | reg = <0x110001C0 0x20>; | ||
267 | #gpio-cells = <4>; | ||
268 | }; | ||
269 | |||
270 | gpy6: gpio-controller@110001E0 { | ||
271 | compatible = "samsung,exynos4-gpio"; | ||
272 | reg = <0x110001E0 0x20>; | ||
273 | #gpio-cells = <4>; | ||
274 | }; | ||
275 | |||
276 | gpx0: gpio-controller@11000C00 { | ||
277 | compatible = "samsung,exynos4-gpio"; | ||
278 | reg = <0x11000C00 0x20>; | ||
279 | #gpio-cells = <4>; | ||
280 | }; | ||
281 | |||
282 | gpx1: gpio-controller@11000C20 { | ||
283 | compatible = "samsung,exynos4-gpio"; | ||
284 | reg = <0x11000C20 0x20>; | ||
285 | #gpio-cells = <4>; | ||
286 | }; | ||
287 | |||
288 | gpx2: gpio-controller@11000C40 { | ||
289 | compatible = "samsung,exynos4-gpio"; | ||
290 | reg = <0x11000C40 0x20>; | ||
291 | #gpio-cells = <4>; | ||
292 | }; | ||
293 | |||
294 | gpx3: gpio-controller@11000C60 { | ||
295 | compatible = "samsung,exynos4-gpio"; | ||
296 | reg = <0x11000C60 0x20>; | ||
297 | #gpio-cells = <4>; | ||
298 | }; | ||
299 | |||
300 | gpz: gpio-controller@03860000 { | ||
301 | compatible = "samsung,exynos4-gpio"; | ||
302 | reg = <0x03860000 0x20>; | ||
303 | #gpio-cells = <4>; | ||
304 | }; | ||
305 | }; | ||
306 | }; | 67 | }; |
diff --git a/drivers/pinctrl/pinctrl-exynos.c b/drivers/pinctrl/pinctrl-exynos.c index 21362f48d370..19fab68a9fbf 100644 --- a/drivers/pinctrl/pinctrl-exynos.c +++ b/drivers/pinctrl/pinctrl-exynos.c | |||
@@ -40,46 +40,46 @@ static const struct of_device_id exynos_wkup_irq_ids[] = { | |||
40 | 40 | ||
41 | static void exynos_gpio_irq_unmask(struct irq_data *irqd) | 41 | static void exynos_gpio_irq_unmask(struct irq_data *irqd) |
42 | { | 42 | { |
43 | struct samsung_pinctrl_drv_data *d = irqd->domain->host_data; | 43 | struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd); |
44 | struct exynos_geint_data *edata = irq_data_get_irq_handler_data(irqd); | 44 | struct samsung_pinctrl_drv_data *d = bank->drvdata; |
45 | unsigned long reg_mask = d->ctrl->geint_mask + edata->eint_offset; | 45 | unsigned long reg_mask = d->ctrl->geint_mask + bank->eint_offset; |
46 | unsigned long mask; | 46 | unsigned long mask; |
47 | 47 | ||
48 | mask = readl(d->virt_base + reg_mask); | 48 | mask = readl(d->virt_base + reg_mask); |
49 | mask &= ~(1 << edata->pin); | 49 | mask &= ~(1 << irqd->hwirq); |
50 | writel(mask, d->virt_base + reg_mask); | 50 | writel(mask, d->virt_base + reg_mask); |
51 | } | 51 | } |
52 | 52 | ||
53 | static void exynos_gpio_irq_mask(struct irq_data *irqd) | 53 | static void exynos_gpio_irq_mask(struct irq_data *irqd) |
54 | { | 54 | { |
55 | struct samsung_pinctrl_drv_data *d = irqd->domain->host_data; | 55 | struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd); |
56 | struct exynos_geint_data *edata = irq_data_get_irq_handler_data(irqd); | 56 | struct samsung_pinctrl_drv_data *d = bank->drvdata; |
57 | unsigned long reg_mask = d->ctrl->geint_mask + edata->eint_offset; | 57 | unsigned long reg_mask = d->ctrl->geint_mask + bank->eint_offset; |
58 | unsigned long mask; | 58 | unsigned long mask; |
59 | 59 | ||
60 | mask = readl(d->virt_base + reg_mask); | 60 | mask = readl(d->virt_base + reg_mask); |
61 | mask |= 1 << edata->pin; | 61 | mask |= 1 << irqd->hwirq; |
62 | writel(mask, d->virt_base + reg_mask); | 62 | writel(mask, d->virt_base + reg_mask); |
63 | } | 63 | } |
64 | 64 | ||
65 | static void exynos_gpio_irq_ack(struct irq_data *irqd) | 65 | static void exynos_gpio_irq_ack(struct irq_data *irqd) |
66 | { | 66 | { |
67 | struct samsung_pinctrl_drv_data *d = irqd->domain->host_data; | 67 | struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd); |
68 | struct exynos_geint_data *edata = irq_data_get_irq_handler_data(irqd); | 68 | struct samsung_pinctrl_drv_data *d = bank->drvdata; |
69 | unsigned long reg_pend = d->ctrl->geint_pend + edata->eint_offset; | 69 | unsigned long reg_pend = d->ctrl->geint_pend + bank->eint_offset; |
70 | 70 | ||
71 | writel(1 << edata->pin, d->virt_base + reg_pend); | 71 | writel(1 << irqd->hwirq, d->virt_base + reg_pend); |
72 | } | 72 | } |
73 | 73 | ||
74 | static int exynos_gpio_irq_set_type(struct irq_data *irqd, unsigned int type) | 74 | static int exynos_gpio_irq_set_type(struct irq_data *irqd, unsigned int type) |
75 | { | 75 | { |
76 | struct samsung_pinctrl_drv_data *d = irqd->domain->host_data; | 76 | struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd); |
77 | struct samsung_pinctrl_drv_data *d = bank->drvdata; | ||
77 | struct samsung_pin_ctrl *ctrl = d->ctrl; | 78 | struct samsung_pin_ctrl *ctrl = d->ctrl; |
78 | struct exynos_geint_data *edata = irq_data_get_irq_handler_data(irqd); | 79 | unsigned int pin = irqd->hwirq; |
79 | struct samsung_pin_bank *bank = edata->bank; | 80 | unsigned int shift = EXYNOS_EINT_CON_LEN * pin; |
80 | unsigned int shift = EXYNOS_EINT_CON_LEN * edata->pin; | ||
81 | unsigned int con, trig_type; | 81 | unsigned int con, trig_type; |
82 | unsigned long reg_con = ctrl->geint_con + edata->eint_offset; | 82 | unsigned long reg_con = ctrl->geint_con + bank->eint_offset; |
83 | unsigned int mask; | 83 | unsigned int mask; |
84 | 84 | ||
85 | switch (type) { | 85 | switch (type) { |
@@ -114,7 +114,7 @@ static int exynos_gpio_irq_set_type(struct irq_data *irqd, unsigned int type) | |||
114 | writel(con, d->virt_base + reg_con); | 114 | writel(con, d->virt_base + reg_con); |
115 | 115 | ||
116 | reg_con = bank->pctl_offset; | 116 | reg_con = bank->pctl_offset; |
117 | shift = edata->pin * bank->func_width; | 117 | shift = pin * bank->func_width; |
118 | mask = (1 << bank->func_width) - 1; | 118 | mask = (1 << bank->func_width) - 1; |
119 | 119 | ||
120 | con = readl(d->virt_base + reg_con); | 120 | con = readl(d->virt_base + reg_con); |
@@ -136,82 +136,23 @@ static struct irq_chip exynos_gpio_irq_chip = { | |||
136 | .irq_set_type = exynos_gpio_irq_set_type, | 136 | .irq_set_type = exynos_gpio_irq_set_type, |
137 | }; | 137 | }; |
138 | 138 | ||
139 | /* | ||
140 | * given a controller-local external gpio interrupt number, prepare the handler | ||
141 | * data for it. | ||
142 | */ | ||
143 | static struct exynos_geint_data *exynos_get_eint_data(irq_hw_number_t hw, | ||
144 | struct samsung_pinctrl_drv_data *d) | ||
145 | { | ||
146 | struct samsung_pin_bank *bank = d->ctrl->pin_banks; | ||
147 | struct exynos_geint_data *eint_data; | ||
148 | unsigned int nr_banks = d->ctrl->nr_banks, idx; | ||
149 | unsigned int irq_base = 0, eint_offset = 0; | ||
150 | |||
151 | if (hw >= d->ctrl->nr_gint) { | ||
152 | dev_err(d->dev, "unsupported ext-gpio interrupt\n"); | ||
153 | return NULL; | ||
154 | } | ||
155 | |||
156 | for (idx = 0; idx < nr_banks; idx++, bank++) { | ||
157 | if (bank->eint_type != EINT_TYPE_GPIO) | ||
158 | continue; | ||
159 | if ((hw >= irq_base) && (hw < (irq_base + bank->nr_pins))) | ||
160 | break; | ||
161 | irq_base += bank->nr_pins; | ||
162 | eint_offset += 4; | ||
163 | } | ||
164 | |||
165 | if (idx == nr_banks) { | ||
166 | dev_err(d->dev, "pin bank not found for ext-gpio interrupt\n"); | ||
167 | return NULL; | ||
168 | } | ||
169 | |||
170 | eint_data = devm_kzalloc(d->dev, sizeof(*eint_data), GFP_KERNEL); | ||
171 | if (!eint_data) { | ||
172 | dev_err(d->dev, "no memory for eint-gpio data\n"); | ||
173 | return NULL; | ||
174 | } | ||
175 | |||
176 | eint_data->bank = bank; | ||
177 | eint_data->pin = hw - irq_base; | ||
178 | eint_data->eint_offset = eint_offset; | ||
179 | return eint_data; | ||
180 | } | ||
181 | |||
182 | static int exynos_gpio_irq_map(struct irq_domain *h, unsigned int virq, | 139 | static int exynos_gpio_irq_map(struct irq_domain *h, unsigned int virq, |
183 | irq_hw_number_t hw) | 140 | irq_hw_number_t hw) |
184 | { | 141 | { |
185 | struct samsung_pinctrl_drv_data *d = h->host_data; | 142 | struct samsung_pin_bank *b = h->host_data; |
186 | struct exynos_geint_data *eint_data; | ||
187 | |||
188 | eint_data = exynos_get_eint_data(hw, d); | ||
189 | if (!eint_data) | ||
190 | return -EINVAL; | ||
191 | 143 | ||
192 | irq_set_handler_data(virq, eint_data); | 144 | irq_set_chip_data(virq, b); |
193 | irq_set_chip_data(virq, h->host_data); | ||
194 | irq_set_chip_and_handler(virq, &exynos_gpio_irq_chip, | 145 | irq_set_chip_and_handler(virq, &exynos_gpio_irq_chip, |
195 | handle_level_irq); | 146 | handle_level_irq); |
196 | set_irq_flags(virq, IRQF_VALID); | 147 | set_irq_flags(virq, IRQF_VALID); |
197 | return 0; | 148 | return 0; |
198 | } | 149 | } |
199 | 150 | ||
200 | static void exynos_gpio_irq_unmap(struct irq_domain *h, unsigned int virq) | ||
201 | { | ||
202 | struct samsung_pinctrl_drv_data *d = h->host_data; | ||
203 | struct exynos_geint_data *eint_data; | ||
204 | |||
205 | eint_data = irq_get_handler_data(virq); | ||
206 | devm_kfree(d->dev, eint_data); | ||
207 | } | ||
208 | |||
209 | /* | 151 | /* |
210 | * irq domain callbacks for external gpio interrupt controller. | 152 | * irq domain callbacks for external gpio interrupt controller. |
211 | */ | 153 | */ |
212 | static const struct irq_domain_ops exynos_gpio_irqd_ops = { | 154 | static const struct irq_domain_ops exynos_gpio_irqd_ops = { |
213 | .map = exynos_gpio_irq_map, | 155 | .map = exynos_gpio_irq_map, |
214 | .unmap = exynos_gpio_irq_unmap, | ||
215 | .xlate = irq_domain_xlate_twocell, | 156 | .xlate = irq_domain_xlate_twocell, |
216 | }; | 157 | }; |
217 | 158 | ||
@@ -230,7 +171,7 @@ static irqreturn_t exynos_eint_gpio_irq(int irq, void *data) | |||
230 | return IRQ_HANDLED; | 171 | return IRQ_HANDLED; |
231 | bank += (group - 1); | 172 | bank += (group - 1); |
232 | 173 | ||
233 | virq = irq_linear_revmap(d->gpio_irqd, bank->irq_base + pin); | 174 | virq = irq_linear_revmap(bank->irq_domain, pin); |
234 | if (!virq) | 175 | if (!virq) |
235 | return IRQ_NONE; | 176 | return IRQ_NONE; |
236 | generic_handle_irq(virq); | 177 | generic_handle_irq(virq); |
@@ -243,8 +184,10 @@ static irqreturn_t exynos_eint_gpio_irq(int irq, void *data) | |||
243 | */ | 184 | */ |
244 | static int exynos_eint_gpio_init(struct samsung_pinctrl_drv_data *d) | 185 | static int exynos_eint_gpio_init(struct samsung_pinctrl_drv_data *d) |
245 | { | 186 | { |
187 | struct samsung_pin_bank *bank; | ||
246 | struct device *dev = d->dev; | 188 | struct device *dev = d->dev; |
247 | unsigned int ret; | 189 | unsigned int ret; |
190 | unsigned int i; | ||
248 | 191 | ||
249 | if (!d->irq) { | 192 | if (!d->irq) { |
250 | dev_err(dev, "irq number not available\n"); | 193 | dev_err(dev, "irq number not available\n"); |
@@ -258,11 +201,16 @@ static int exynos_eint_gpio_init(struct samsung_pinctrl_drv_data *d) | |||
258 | return -ENXIO; | 201 | return -ENXIO; |
259 | } | 202 | } |
260 | 203 | ||
261 | d->gpio_irqd = irq_domain_add_linear(dev->of_node, d->ctrl->nr_gint, | 204 | bank = d->ctrl->pin_banks; |
262 | &exynos_gpio_irqd_ops, d); | 205 | for (i = 0; i < d->ctrl->nr_banks; ++i, ++bank) { |
263 | if (!d->gpio_irqd) { | 206 | if (bank->eint_type != EINT_TYPE_GPIO) |
264 | dev_err(dev, "gpio irq domain allocation failed\n"); | 207 | continue; |
265 | return -ENXIO; | 208 | bank->irq_domain = irq_domain_add_linear(bank->of_node, |
209 | bank->nr_pins, &exynos_gpio_irqd_ops, bank); | ||
210 | if (!bank->irq_domain) { | ||
211 | dev_err(dev, "gpio irq domain add failed\n"); | ||
212 | return -ENXIO; | ||
213 | } | ||
266 | } | 214 | } |
267 | 215 | ||
268 | return 0; | 216 | return 0; |
@@ -270,48 +218,46 @@ static int exynos_eint_gpio_init(struct samsung_pinctrl_drv_data *d) | |||
270 | 218 | ||
271 | static void exynos_wkup_irq_unmask(struct irq_data *irqd) | 219 | static void exynos_wkup_irq_unmask(struct irq_data *irqd) |
272 | { | 220 | { |
273 | struct samsung_pinctrl_drv_data *d = irq_data_get_irq_chip_data(irqd); | 221 | struct samsung_pin_bank *b = irq_data_get_irq_chip_data(irqd); |
274 | unsigned int bank = irqd->hwirq / EXYNOS_EINT_MAX_PER_BANK; | 222 | struct samsung_pinctrl_drv_data *d = b->drvdata; |
275 | unsigned int pin = irqd->hwirq & (EXYNOS_EINT_MAX_PER_BANK - 1); | 223 | unsigned long reg_mask = d->ctrl->weint_mask + b->eint_offset; |
276 | unsigned long reg_mask = d->ctrl->weint_mask + (bank << 2); | ||
277 | unsigned long mask; | 224 | unsigned long mask; |
278 | 225 | ||
279 | mask = readl(d->virt_base + reg_mask); | 226 | mask = readl(d->virt_base + reg_mask); |
280 | mask &= ~(1 << pin); | 227 | mask &= ~(1 << irqd->hwirq); |
281 | writel(mask, d->virt_base + reg_mask); | 228 | writel(mask, d->virt_base + reg_mask); |
282 | } | 229 | } |
283 | 230 | ||
284 | static void exynos_wkup_irq_mask(struct irq_data *irqd) | 231 | static void exynos_wkup_irq_mask(struct irq_data *irqd) |
285 | { | 232 | { |
286 | struct samsung_pinctrl_drv_data *d = irq_data_get_irq_chip_data(irqd); | 233 | struct samsung_pin_bank *b = irq_data_get_irq_chip_data(irqd); |
287 | unsigned int bank = irqd->hwirq / EXYNOS_EINT_MAX_PER_BANK; | 234 | struct samsung_pinctrl_drv_data *d = b->drvdata; |
288 | unsigned int pin = irqd->hwirq & (EXYNOS_EINT_MAX_PER_BANK - 1); | 235 | unsigned long reg_mask = d->ctrl->weint_mask + b->eint_offset; |
289 | unsigned long reg_mask = d->ctrl->weint_mask + (bank << 2); | ||
290 | unsigned long mask; | 236 | unsigned long mask; |
291 | 237 | ||
292 | mask = readl(d->virt_base + reg_mask); | 238 | mask = readl(d->virt_base + reg_mask); |
293 | mask |= 1 << pin; | 239 | mask |= 1 << irqd->hwirq; |
294 | writel(mask, d->virt_base + reg_mask); | 240 | writel(mask, d->virt_base + reg_mask); |
295 | } | 241 | } |
296 | 242 | ||
297 | static void exynos_wkup_irq_ack(struct irq_data *irqd) | 243 | static void exynos_wkup_irq_ack(struct irq_data *irqd) |
298 | { | 244 | { |
299 | struct samsung_pinctrl_drv_data *d = irq_data_get_irq_chip_data(irqd); | 245 | struct samsung_pin_bank *b = irq_data_get_irq_chip_data(irqd); |
300 | unsigned int bank = irqd->hwirq / EXYNOS_EINT_MAX_PER_BANK; | 246 | struct samsung_pinctrl_drv_data *d = b->drvdata; |
301 | unsigned int pin = irqd->hwirq & (EXYNOS_EINT_MAX_PER_BANK - 1); | 247 | unsigned long pend = d->ctrl->weint_pend + b->eint_offset; |
302 | unsigned long pend = d->ctrl->weint_pend + (bank << 2); | ||
303 | 248 | ||
304 | writel(1 << pin, d->virt_base + pend); | 249 | writel(1 << irqd->hwirq, d->virt_base + pend); |
305 | } | 250 | } |
306 | 251 | ||
307 | static int exynos_wkup_irq_set_type(struct irq_data *irqd, unsigned int type) | 252 | static int exynos_wkup_irq_set_type(struct irq_data *irqd, unsigned int type) |
308 | { | 253 | { |
309 | struct samsung_pinctrl_drv_data *d = irq_data_get_irq_chip_data(irqd); | 254 | struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd); |
310 | unsigned int bank = irqd->hwirq / EXYNOS_EINT_MAX_PER_BANK; | 255 | struct samsung_pinctrl_drv_data *d = bank->drvdata; |
311 | unsigned int pin = irqd->hwirq & (EXYNOS_EINT_MAX_PER_BANK - 1); | 256 | unsigned int pin = irqd->hwirq; |
312 | unsigned long reg_con = d->ctrl->weint_con + (bank << 2); | 257 | unsigned long reg_con = d->ctrl->weint_con + bank->eint_offset; |
313 | unsigned long shift = EXYNOS_EINT_CON_LEN * pin; | 258 | unsigned long shift = EXYNOS_EINT_CON_LEN * pin; |
314 | unsigned long con, trig_type; | 259 | unsigned long con, trig_type; |
260 | unsigned int mask; | ||
315 | 261 | ||
316 | switch (type) { | 262 | switch (type) { |
317 | case IRQ_TYPE_EDGE_RISING: | 263 | case IRQ_TYPE_EDGE_RISING: |
@@ -343,6 +289,16 @@ static int exynos_wkup_irq_set_type(struct irq_data *irqd, unsigned int type) | |||
343 | con &= ~(EXYNOS_EINT_CON_MASK << shift); | 289 | con &= ~(EXYNOS_EINT_CON_MASK << shift); |
344 | con |= trig_type << shift; | 290 | con |= trig_type << shift; |
345 | writel(con, d->virt_base + reg_con); | 291 | writel(con, d->virt_base + reg_con); |
292 | |||
293 | reg_con = bank->pctl_offset; | ||
294 | shift = pin * bank->func_width; | ||
295 | mask = (1 << bank->func_width) - 1; | ||
296 | |||
297 | con = readl(d->virt_base + reg_con); | ||
298 | con &= ~(mask << shift); | ||
299 | con |= EXYNOS_EINT_FUNC << shift; | ||
300 | writel(con, d->virt_base + reg_con); | ||
301 | |||
346 | return 0; | 302 | return 0; |
347 | } | 303 | } |
348 | 304 | ||
@@ -361,6 +317,7 @@ static struct irq_chip exynos_wkup_irq_chip = { | |||
361 | static void exynos_irq_eint0_15(unsigned int irq, struct irq_desc *desc) | 317 | static void exynos_irq_eint0_15(unsigned int irq, struct irq_desc *desc) |
362 | { | 318 | { |
363 | struct exynos_weint_data *eintd = irq_get_handler_data(irq); | 319 | struct exynos_weint_data *eintd = irq_get_handler_data(irq); |
320 | struct samsung_pin_bank *bank = eintd->bank; | ||
364 | struct irq_chip *chip = irq_get_chip(irq); | 321 | struct irq_chip *chip = irq_get_chip(irq); |
365 | int eint_irq; | 322 | int eint_irq; |
366 | 323 | ||
@@ -370,20 +327,20 @@ static void exynos_irq_eint0_15(unsigned int irq, struct irq_desc *desc) | |||
370 | if (chip->irq_ack) | 327 | if (chip->irq_ack) |
371 | chip->irq_ack(&desc->irq_data); | 328 | chip->irq_ack(&desc->irq_data); |
372 | 329 | ||
373 | eint_irq = irq_linear_revmap(eintd->domain, eintd->irq); | 330 | eint_irq = irq_linear_revmap(bank->irq_domain, eintd->irq); |
374 | generic_handle_irq(eint_irq); | 331 | generic_handle_irq(eint_irq); |
375 | chip->irq_unmask(&desc->irq_data); | 332 | chip->irq_unmask(&desc->irq_data); |
376 | chained_irq_exit(chip, desc); | 333 | chained_irq_exit(chip, desc); |
377 | } | 334 | } |
378 | 335 | ||
379 | static inline void exynos_irq_demux_eint(int irq_base, unsigned long pend, | 336 | static inline void exynos_irq_demux_eint(unsigned long pend, |
380 | struct irq_domain *domain) | 337 | struct irq_domain *domain) |
381 | { | 338 | { |
382 | unsigned int irq; | 339 | unsigned int irq; |
383 | 340 | ||
384 | while (pend) { | 341 | while (pend) { |
385 | irq = fls(pend) - 1; | 342 | irq = fls(pend) - 1; |
386 | generic_handle_irq(irq_find_mapping(domain, irq_base + irq)); | 343 | generic_handle_irq(irq_find_mapping(domain, irq)); |
387 | pend &= ~(1 << irq); | 344 | pend &= ~(1 << irq); |
388 | } | 345 | } |
389 | } | 346 | } |
@@ -392,18 +349,22 @@ static inline void exynos_irq_demux_eint(int irq_base, unsigned long pend, | |||
392 | static void exynos_irq_demux_eint16_31(unsigned int irq, struct irq_desc *desc) | 349 | static void exynos_irq_demux_eint16_31(unsigned int irq, struct irq_desc *desc) |
393 | { | 350 | { |
394 | struct irq_chip *chip = irq_get_chip(irq); | 351 | struct irq_chip *chip = irq_get_chip(irq); |
395 | struct exynos_weint_data *eintd = irq_get_handler_data(irq); | 352 | struct exynos_muxed_weint_data *eintd = irq_get_handler_data(irq); |
396 | struct samsung_pinctrl_drv_data *d = eintd->domain->host_data; | 353 | struct samsung_pinctrl_drv_data *d = eintd->banks[0]->drvdata; |
354 | struct samsung_pin_ctrl *ctrl = d->ctrl; | ||
397 | unsigned long pend; | 355 | unsigned long pend; |
398 | unsigned long mask; | 356 | unsigned long mask; |
357 | int i; | ||
399 | 358 | ||
400 | chained_irq_enter(chip, desc); | 359 | chained_irq_enter(chip, desc); |
401 | pend = readl(d->virt_base + d->ctrl->weint_pend + 0x8); | 360 | |
402 | mask = readl(d->virt_base + d->ctrl->weint_mask + 0x8); | 361 | for (i = 0; i < eintd->nr_banks; ++i) { |
403 | exynos_irq_demux_eint(16, pend & ~mask, eintd->domain); | 362 | struct samsung_pin_bank *b = eintd->banks[i]; |
404 | pend = readl(d->virt_base + d->ctrl->weint_pend + 0xC); | 363 | pend = readl(d->virt_base + ctrl->weint_pend + b->eint_offset); |
405 | mask = readl(d->virt_base + d->ctrl->weint_mask + 0xC); | 364 | mask = readl(d->virt_base + ctrl->weint_mask + b->eint_offset); |
406 | exynos_irq_demux_eint(24, pend & ~mask, eintd->domain); | 365 | exynos_irq_demux_eint(pend & ~mask, b->irq_domain); |
366 | } | ||
367 | |||
407 | chained_irq_exit(chip, desc); | 368 | chained_irq_exit(chip, desc); |
408 | } | 369 | } |
409 | 370 | ||
@@ -433,7 +394,11 @@ static int exynos_eint_wkup_init(struct samsung_pinctrl_drv_data *d) | |||
433 | struct device *dev = d->dev; | 394 | struct device *dev = d->dev; |
434 | struct device_node *wkup_np = NULL; | 395 | struct device_node *wkup_np = NULL; |
435 | struct device_node *np; | 396 | struct device_node *np; |
397 | struct samsung_pin_bank *bank; | ||
436 | struct exynos_weint_data *weint_data; | 398 | struct exynos_weint_data *weint_data; |
399 | struct exynos_muxed_weint_data *muxed_data; | ||
400 | unsigned int muxed_banks = 0; | ||
401 | unsigned int i; | ||
437 | int idx, irq; | 402 | int idx, irq; |
438 | 403 | ||
439 | for_each_child_of_node(dev->of_node, np) { | 404 | for_each_child_of_node(dev->of_node, np) { |
@@ -445,90 +410,124 @@ static int exynos_eint_wkup_init(struct samsung_pinctrl_drv_data *d) | |||
445 | if (!wkup_np) | 410 | if (!wkup_np) |
446 | return -ENODEV; | 411 | return -ENODEV; |
447 | 412 | ||
448 | d->wkup_irqd = irq_domain_add_linear(wkup_np, d->ctrl->nr_wint, | 413 | bank = d->ctrl->pin_banks; |
449 | &exynos_wkup_irqd_ops, d); | 414 | for (i = 0; i < d->ctrl->nr_banks; ++i, ++bank) { |
450 | if (!d->wkup_irqd) { | 415 | if (bank->eint_type != EINT_TYPE_WKUP) |
451 | dev_err(dev, "wakeup irq domain allocation failed\n"); | 416 | continue; |
452 | return -ENXIO; | ||
453 | } | ||
454 | 417 | ||
455 | weint_data = devm_kzalloc(dev, sizeof(*weint_data) * 17, GFP_KERNEL); | 418 | bank->irq_domain = irq_domain_add_linear(bank->of_node, |
456 | if (!weint_data) { | 419 | bank->nr_pins, &exynos_wkup_irqd_ops, bank); |
457 | dev_err(dev, "could not allocate memory for weint_data\n"); | 420 | if (!bank->irq_domain) { |
458 | return -ENOMEM; | 421 | dev_err(dev, "wkup irq domain add failed\n"); |
459 | } | 422 | return -ENXIO; |
423 | } | ||
460 | 424 | ||
461 | irq = irq_of_parse_and_map(wkup_np, 16); | 425 | if (!of_find_property(bank->of_node, "interrupts", NULL)) { |
462 | if (irq) { | 426 | bank->eint_type = EINT_TYPE_WKUP_MUX; |
463 | weint_data[16].domain = d->wkup_irqd; | 427 | ++muxed_banks; |
464 | irq_set_chained_handler(irq, exynos_irq_demux_eint16_31); | 428 | continue; |
465 | irq_set_handler_data(irq, &weint_data[16]); | 429 | } |
466 | } else { | ||
467 | dev_err(dev, "irq number for EINT16-32 not found\n"); | ||
468 | } | ||
469 | 430 | ||
470 | for (idx = 0; idx < 16; idx++) { | 431 | weint_data = devm_kzalloc(dev, bank->nr_pins |
471 | weint_data[idx].domain = d->wkup_irqd; | 432 | * sizeof(*weint_data), GFP_KERNEL); |
472 | weint_data[idx].irq = idx; | 433 | if (!weint_data) { |
434 | dev_err(dev, "could not allocate memory for weint_data\n"); | ||
435 | return -ENOMEM; | ||
436 | } | ||
473 | 437 | ||
474 | irq = irq_of_parse_and_map(wkup_np, idx); | 438 | for (idx = 0; idx < bank->nr_pins; ++idx) { |
475 | if (irq) { | 439 | irq = irq_of_parse_and_map(bank->of_node, idx); |
440 | if (!irq) { | ||
441 | dev_err(dev, "irq number for eint-%s-%d not found\n", | ||
442 | bank->name, idx); | ||
443 | continue; | ||
444 | } | ||
445 | weint_data[idx].irq = idx; | ||
446 | weint_data[idx].bank = bank; | ||
476 | irq_set_handler_data(irq, &weint_data[idx]); | 447 | irq_set_handler_data(irq, &weint_data[idx]); |
477 | irq_set_chained_handler(irq, exynos_irq_eint0_15); | 448 | irq_set_chained_handler(irq, exynos_irq_eint0_15); |
478 | } else { | ||
479 | dev_err(dev, "irq number for eint-%x not found\n", idx); | ||
480 | } | 449 | } |
481 | } | 450 | } |
451 | |||
452 | if (!muxed_banks) | ||
453 | return 0; | ||
454 | |||
455 | irq = irq_of_parse_and_map(wkup_np, 0); | ||
456 | if (!irq) { | ||
457 | dev_err(dev, "irq number for muxed EINTs not found\n"); | ||
458 | return 0; | ||
459 | } | ||
460 | |||
461 | muxed_data = devm_kzalloc(dev, sizeof(*muxed_data) | ||
462 | + muxed_banks*sizeof(struct samsung_pin_bank *), GFP_KERNEL); | ||
463 | if (!muxed_data) { | ||
464 | dev_err(dev, "could not allocate memory for muxed_data\n"); | ||
465 | return -ENOMEM; | ||
466 | } | ||
467 | |||
468 | irq_set_chained_handler(irq, exynos_irq_demux_eint16_31); | ||
469 | irq_set_handler_data(irq, muxed_data); | ||
470 | |||
471 | bank = d->ctrl->pin_banks; | ||
472 | idx = 0; | ||
473 | for (i = 0; i < d->ctrl->nr_banks; ++i, ++bank) { | ||
474 | if (bank->eint_type != EINT_TYPE_WKUP_MUX) | ||
475 | continue; | ||
476 | |||
477 | muxed_data->banks[idx++] = bank; | ||
478 | } | ||
479 | muxed_data->nr_banks = muxed_banks; | ||
480 | |||
482 | return 0; | 481 | return 0; |
483 | } | 482 | } |
484 | 483 | ||
485 | /* pin banks of exynos4210 pin-controller 0 */ | 484 | /* pin banks of exynos4210 pin-controller 0 */ |
486 | static struct samsung_pin_bank exynos4210_pin_banks0[] = { | 485 | static struct samsung_pin_bank exynos4210_pin_banks0[] = { |
487 | EXYNOS_PIN_BANK_EINTG(0x000, EXYNOS4210_GPIO_A0, "gpa0"), | 486 | EXYNOS_PIN_BANK_EINTG(8, 0x000, "gpa0", 0x00), |
488 | EXYNOS_PIN_BANK_EINTG(0x020, EXYNOS4210_GPIO_A1, "gpa1"), | 487 | EXYNOS_PIN_BANK_EINTG(6, 0x020, "gpa1", 0x04), |
489 | EXYNOS_PIN_BANK_EINTG(0x040, EXYNOS4210_GPIO_B, "gpb"), | 488 | EXYNOS_PIN_BANK_EINTG(8, 0x040, "gpb", 0x08), |
490 | EXYNOS_PIN_BANK_EINTG(0x060, EXYNOS4210_GPIO_C0, "gpc0"), | 489 | EXYNOS_PIN_BANK_EINTG(5, 0x060, "gpc0", 0x0c), |
491 | EXYNOS_PIN_BANK_EINTG(0x080, EXYNOS4210_GPIO_C1, "gpc1"), | 490 | EXYNOS_PIN_BANK_EINTG(5, 0x080, "gpc1", 0x10), |
492 | EXYNOS_PIN_BANK_EINTG(0x0A0, EXYNOS4210_GPIO_D0, "gpd0"), | 491 | EXYNOS_PIN_BANK_EINTG(4, 0x0A0, "gpd0", 0x14), |
493 | EXYNOS_PIN_BANK_EINTG(0x0C0, EXYNOS4210_GPIO_D1, "gpd1"), | 492 | EXYNOS_PIN_BANK_EINTG(4, 0x0C0, "gpd1", 0x18), |
494 | EXYNOS_PIN_BANK_EINTG(0x0E0, EXYNOS4210_GPIO_E0, "gpe0"), | 493 | EXYNOS_PIN_BANK_EINTG(5, 0x0E0, "gpe0", 0x1c), |
495 | EXYNOS_PIN_BANK_EINTG(0x100, EXYNOS4210_GPIO_E1, "gpe1"), | 494 | EXYNOS_PIN_BANK_EINTG(8, 0x100, "gpe1", 0x20), |
496 | EXYNOS_PIN_BANK_EINTG(0x120, EXYNOS4210_GPIO_E2, "gpe2"), | 495 | EXYNOS_PIN_BANK_EINTG(6, 0x120, "gpe2", 0x24), |
497 | EXYNOS_PIN_BANK_EINTG(0x140, EXYNOS4210_GPIO_E3, "gpe3"), | 496 | EXYNOS_PIN_BANK_EINTG(8, 0x140, "gpe3", 0x28), |
498 | EXYNOS_PIN_BANK_EINTG(0x160, EXYNOS4210_GPIO_E4, "gpe4"), | 497 | EXYNOS_PIN_BANK_EINTG(8, 0x160, "gpe4", 0x2c), |
499 | EXYNOS_PIN_BANK_EINTG(0x180, EXYNOS4210_GPIO_F0, "gpf0"), | 498 | EXYNOS_PIN_BANK_EINTG(8, 0x180, "gpf0", 0x30), |
500 | EXYNOS_PIN_BANK_EINTG(0x1A0, EXYNOS4210_GPIO_F1, "gpf1"), | 499 | EXYNOS_PIN_BANK_EINTG(8, 0x1A0, "gpf1", 0x34), |
501 | EXYNOS_PIN_BANK_EINTG(0x1C0, EXYNOS4210_GPIO_F2, "gpf2"), | 500 | EXYNOS_PIN_BANK_EINTG(8, 0x1C0, "gpf2", 0x38), |
502 | EXYNOS_PIN_BANK_EINTG(0x1E0, EXYNOS4210_GPIO_F3, "gpf3"), | 501 | EXYNOS_PIN_BANK_EINTG(6, 0x1E0, "gpf3", 0x3c), |
503 | }; | 502 | }; |
504 | 503 | ||
505 | /* pin banks of exynos4210 pin-controller 1 */ | 504 | /* pin banks of exynos4210 pin-controller 1 */ |
506 | static struct samsung_pin_bank exynos4210_pin_banks1[] = { | 505 | static struct samsung_pin_bank exynos4210_pin_banks1[] = { |
507 | EXYNOS_PIN_BANK_EINTG(0x000, EXYNOS4210_GPIO_J0, "gpj0"), | 506 | EXYNOS_PIN_BANK_EINTG(8, 0x000, "gpj0", 0x00), |
508 | EXYNOS_PIN_BANK_EINTG(0x020, EXYNOS4210_GPIO_J1, "gpj1"), | 507 | EXYNOS_PIN_BANK_EINTG(5, 0x020, "gpj1", 0x04), |
509 | EXYNOS_PIN_BANK_EINTG(0x040, EXYNOS4210_GPIO_K0, "gpk0"), | 508 | EXYNOS_PIN_BANK_EINTG(7, 0x040, "gpk0", 0x08), |
510 | EXYNOS_PIN_BANK_EINTG(0x060, EXYNOS4210_GPIO_K1, "gpk1"), | 509 | EXYNOS_PIN_BANK_EINTG(7, 0x060, "gpk1", 0x0c), |
511 | EXYNOS_PIN_BANK_EINTG(0x080, EXYNOS4210_GPIO_K2, "gpk2"), | 510 | EXYNOS_PIN_BANK_EINTG(7, 0x080, "gpk2", 0x10), |
512 | EXYNOS_PIN_BANK_EINTG(0x0A0, EXYNOS4210_GPIO_K3, "gpk3"), | 511 | EXYNOS_PIN_BANK_EINTG(7, 0x0A0, "gpk3", 0x14), |
513 | EXYNOS_PIN_BANK_EINTG(0x0C0, EXYNOS4210_GPIO_L0, "gpl0"), | 512 | EXYNOS_PIN_BANK_EINTG(8, 0x0C0, "gpl0", 0x18), |
514 | EXYNOS_PIN_BANK_EINTG(0x0E0, EXYNOS4210_GPIO_L1, "gpl1"), | 513 | EXYNOS_PIN_BANK_EINTG(3, 0x0E0, "gpl1", 0x1c), |
515 | EXYNOS_PIN_BANK_EINTG(0x100, EXYNOS4210_GPIO_L2, "gpl2"), | 514 | EXYNOS_PIN_BANK_EINTG(8, 0x100, "gpl2", 0x20), |
516 | EXYNOS_PIN_BANK_EINTN(0x120, EXYNOS4210_GPIO_Y0, "gpy0"), | 515 | EXYNOS_PIN_BANK_EINTN(6, 0x120, "gpy0"), |
517 | EXYNOS_PIN_BANK_EINTN(0x140, EXYNOS4210_GPIO_Y1, "gpy1"), | 516 | EXYNOS_PIN_BANK_EINTN(4, 0x140, "gpy1"), |
518 | EXYNOS_PIN_BANK_EINTN(0x160, EXYNOS4210_GPIO_Y2, "gpy2"), | 517 | EXYNOS_PIN_BANK_EINTN(6, 0x160, "gpy2"), |
519 | EXYNOS_PIN_BANK_EINTN(0x180, EXYNOS4210_GPIO_Y3, "gpy3"), | 518 | EXYNOS_PIN_BANK_EINTN(8, 0x180, "gpy3"), |
520 | EXYNOS_PIN_BANK_EINTN(0x1A0, EXYNOS4210_GPIO_Y4, "gpy4"), | 519 | EXYNOS_PIN_BANK_EINTN(8, 0x1A0, "gpy4"), |
521 | EXYNOS_PIN_BANK_EINTN(0x1C0, EXYNOS4210_GPIO_Y5, "gpy5"), | 520 | EXYNOS_PIN_BANK_EINTN(8, 0x1C0, "gpy5"), |
522 | EXYNOS_PIN_BANK_EINTN(0x1E0, EXYNOS4210_GPIO_Y6, "gpy6"), | 521 | EXYNOS_PIN_BANK_EINTN(8, 0x1E0, "gpy6"), |
523 | EXYNOS_PIN_BANK_EINTN(0xC00, EXYNOS4210_GPIO_X0, "gpx0"), | 522 | EXYNOS_PIN_BANK_EINTW(8, 0xC00, "gpx0", 0x00), |
524 | EXYNOS_PIN_BANK_EINTN(0xC20, EXYNOS4210_GPIO_X1, "gpx1"), | 523 | EXYNOS_PIN_BANK_EINTW(8, 0xC20, "gpx1", 0x04), |
525 | EXYNOS_PIN_BANK_EINTN(0xC40, EXYNOS4210_GPIO_X2, "gpx2"), | 524 | EXYNOS_PIN_BANK_EINTW(8, 0xC40, "gpx2", 0x08), |
526 | EXYNOS_PIN_BANK_EINTN(0xC60, EXYNOS4210_GPIO_X3, "gpx3"), | 525 | EXYNOS_PIN_BANK_EINTW(8, 0xC60, "gpx3", 0x0c), |
527 | }; | 526 | }; |
528 | 527 | ||
529 | /* pin banks of exynos4210 pin-controller 2 */ | 528 | /* pin banks of exynos4210 pin-controller 2 */ |
530 | static struct samsung_pin_bank exynos4210_pin_banks2[] = { | 529 | static struct samsung_pin_bank exynos4210_pin_banks2[] = { |
531 | EXYNOS_PIN_BANK_EINTN(0x000, EXYNOS4210_GPIO_Z, "gpz"), | 530 | EXYNOS_PIN_BANK_EINTN(7, 0x000, "gpz"), |
532 | }; | 531 | }; |
533 | 532 | ||
534 | /* | 533 | /* |
@@ -540,9 +539,6 @@ struct samsung_pin_ctrl exynos4210_pin_ctrl[] = { | |||
540 | /* pin-controller instance 0 data */ | 539 | /* pin-controller instance 0 data */ |
541 | .pin_banks = exynos4210_pin_banks0, | 540 | .pin_banks = exynos4210_pin_banks0, |
542 | .nr_banks = ARRAY_SIZE(exynos4210_pin_banks0), | 541 | .nr_banks = ARRAY_SIZE(exynos4210_pin_banks0), |
543 | .base = EXYNOS4210_GPIO_A0_START, | ||
544 | .nr_pins = EXYNOS4210_GPIOA_NR_PINS, | ||
545 | .nr_gint = EXYNOS4210_GPIOA_NR_GINT, | ||
546 | .geint_con = EXYNOS_GPIO_ECON_OFFSET, | 542 | .geint_con = EXYNOS_GPIO_ECON_OFFSET, |
547 | .geint_mask = EXYNOS_GPIO_EMASK_OFFSET, | 543 | .geint_mask = EXYNOS_GPIO_EMASK_OFFSET, |
548 | .geint_pend = EXYNOS_GPIO_EPEND_OFFSET, | 544 | .geint_pend = EXYNOS_GPIO_EPEND_OFFSET, |
@@ -553,10 +549,6 @@ struct samsung_pin_ctrl exynos4210_pin_ctrl[] = { | |||
553 | /* pin-controller instance 1 data */ | 549 | /* pin-controller instance 1 data */ |
554 | .pin_banks = exynos4210_pin_banks1, | 550 | .pin_banks = exynos4210_pin_banks1, |
555 | .nr_banks = ARRAY_SIZE(exynos4210_pin_banks1), | 551 | .nr_banks = ARRAY_SIZE(exynos4210_pin_banks1), |
556 | .base = EXYNOS4210_GPIOA_NR_PINS, | ||
557 | .nr_pins = EXYNOS4210_GPIOB_NR_PINS, | ||
558 | .nr_gint = EXYNOS4210_GPIOB_NR_GINT, | ||
559 | .nr_wint = 32, | ||
560 | .geint_con = EXYNOS_GPIO_ECON_OFFSET, | 552 | .geint_con = EXYNOS_GPIO_ECON_OFFSET, |
561 | .geint_mask = EXYNOS_GPIO_EMASK_OFFSET, | 553 | .geint_mask = EXYNOS_GPIO_EMASK_OFFSET, |
562 | .geint_pend = EXYNOS_GPIO_EPEND_OFFSET, | 554 | .geint_pend = EXYNOS_GPIO_EPEND_OFFSET, |
@@ -571,9 +563,116 @@ struct samsung_pin_ctrl exynos4210_pin_ctrl[] = { | |||
571 | /* pin-controller instance 2 data */ | 563 | /* pin-controller instance 2 data */ |
572 | .pin_banks = exynos4210_pin_banks2, | 564 | .pin_banks = exynos4210_pin_banks2, |
573 | .nr_banks = ARRAY_SIZE(exynos4210_pin_banks2), | 565 | .nr_banks = ARRAY_SIZE(exynos4210_pin_banks2), |
574 | .base = EXYNOS4210_GPIOA_NR_PINS + | ||
575 | EXYNOS4210_GPIOB_NR_PINS, | ||
576 | .nr_pins = EXYNOS4210_GPIOC_NR_PINS, | ||
577 | .label = "exynos4210-gpio-ctrl2", | 566 | .label = "exynos4210-gpio-ctrl2", |
578 | }, | 567 | }, |
579 | }; | 568 | }; |
569 | |||
570 | /* pin banks of exynos4x12 pin-controller 0 */ | ||
571 | static struct samsung_pin_bank exynos4x12_pin_banks0[] = { | ||
572 | EXYNOS_PIN_BANK_EINTG(8, 0x000, "gpa0", 0x00), | ||
573 | EXYNOS_PIN_BANK_EINTG(6, 0x020, "gpa1", 0x04), | ||
574 | EXYNOS_PIN_BANK_EINTG(8, 0x040, "gpb", 0x08), | ||
575 | EXYNOS_PIN_BANK_EINTG(5, 0x060, "gpc0", 0x0c), | ||
576 | EXYNOS_PIN_BANK_EINTG(5, 0x080, "gpc1", 0x10), | ||
577 | EXYNOS_PIN_BANK_EINTG(4, 0x0A0, "gpd0", 0x14), | ||
578 | EXYNOS_PIN_BANK_EINTG(4, 0x0C0, "gpd1", 0x18), | ||
579 | EXYNOS_PIN_BANK_EINTG(8, 0x180, "gpf0", 0x30), | ||
580 | EXYNOS_PIN_BANK_EINTG(8, 0x1A0, "gpf1", 0x34), | ||
581 | EXYNOS_PIN_BANK_EINTG(8, 0x1C0, "gpf2", 0x38), | ||
582 | EXYNOS_PIN_BANK_EINTG(6, 0x1E0, "gpf3", 0x3c), | ||
583 | EXYNOS_PIN_BANK_EINTG(8, 0x240, "gpj0", 0x40), | ||
584 | EXYNOS_PIN_BANK_EINTG(5, 0x260, "gpj1", 0x44), | ||
585 | }; | ||
586 | |||
587 | /* pin banks of exynos4x12 pin-controller 1 */ | ||
588 | static struct samsung_pin_bank exynos4x12_pin_banks1[] = { | ||
589 | EXYNOS_PIN_BANK_EINTG(7, 0x040, "gpk0", 0x08), | ||
590 | EXYNOS_PIN_BANK_EINTG(7, 0x060, "gpk1", 0x0c), | ||
591 | EXYNOS_PIN_BANK_EINTG(7, 0x080, "gpk2", 0x10), | ||
592 | EXYNOS_PIN_BANK_EINTG(7, 0x0A0, "gpk3", 0x14), | ||
593 | EXYNOS_PIN_BANK_EINTG(7, 0x0C0, "gpl0", 0x18), | ||
594 | EXYNOS_PIN_BANK_EINTG(2, 0x0E0, "gpl1", 0x1c), | ||
595 | EXYNOS_PIN_BANK_EINTG(8, 0x100, "gpl2", 0x20), | ||
596 | EXYNOS_PIN_BANK_EINTG(8, 0x260, "gpm0", 0x24), | ||
597 | EXYNOS_PIN_BANK_EINTG(7, 0x280, "gpm1", 0x28), | ||
598 | EXYNOS_PIN_BANK_EINTG(5, 0x2A0, "gpm2", 0x2c), | ||
599 | EXYNOS_PIN_BANK_EINTG(8, 0x2C0, "gpm3", 0x30), | ||
600 | EXYNOS_PIN_BANK_EINTG(8, 0x2E0, "gpm4", 0x34), | ||
601 | EXYNOS_PIN_BANK_EINTN(6, 0x120, "gpy0"), | ||
602 | EXYNOS_PIN_BANK_EINTN(4, 0x140, "gpy1"), | ||
603 | EXYNOS_PIN_BANK_EINTN(6, 0x160, "gpy2"), | ||
604 | EXYNOS_PIN_BANK_EINTN(8, 0x180, "gpy3"), | ||
605 | EXYNOS_PIN_BANK_EINTN(8, 0x1A0, "gpy4"), | ||
606 | EXYNOS_PIN_BANK_EINTN(8, 0x1C0, "gpy5"), | ||
607 | EXYNOS_PIN_BANK_EINTN(8, 0x1E0, "gpy6"), | ||
608 | EXYNOS_PIN_BANK_EINTW(8, 0xC00, "gpx0", 0x00), | ||
609 | EXYNOS_PIN_BANK_EINTW(8, 0xC20, "gpx1", 0x04), | ||
610 | EXYNOS_PIN_BANK_EINTW(8, 0xC40, "gpx2", 0x08), | ||
611 | EXYNOS_PIN_BANK_EINTW(8, 0xC60, "gpx3", 0x0c), | ||
612 | }; | ||
613 | |||
614 | /* pin banks of exynos4x12 pin-controller 2 */ | ||
615 | static struct samsung_pin_bank exynos4x12_pin_banks2[] = { | ||
616 | EXYNOS_PIN_BANK_EINTG(7, 0x000, "gpz", 0x00), | ||
617 | }; | ||
618 | |||
619 | /* pin banks of exynos4x12 pin-controller 3 */ | ||
620 | static struct samsung_pin_bank exynos4x12_pin_banks3[] = { | ||
621 | EXYNOS_PIN_BANK_EINTG(8, 0x000, "gpv0", 0x00), | ||
622 | EXYNOS_PIN_BANK_EINTG(8, 0x020, "gpv1", 0x04), | ||
623 | EXYNOS_PIN_BANK_EINTG(8, 0x040, "gpv2", 0x08), | ||
624 | EXYNOS_PIN_BANK_EINTG(8, 0x060, "gpv3", 0x0c), | ||
625 | EXYNOS_PIN_BANK_EINTG(2, 0x080, "gpv4", 0x10), | ||
626 | }; | ||
627 | |||
628 | /* | ||
629 | * Samsung pinctrl driver data for Exynos4x12 SoC. Exynos4x12 SoC includes | ||
630 | * four gpio/pin-mux/pinconfig controllers. | ||
631 | */ | ||
632 | struct samsung_pin_ctrl exynos4x12_pin_ctrl[] = { | ||
633 | { | ||
634 | /* pin-controller instance 0 data */ | ||
635 | .pin_banks = exynos4x12_pin_banks0, | ||
636 | .nr_banks = ARRAY_SIZE(exynos4x12_pin_banks0), | ||
637 | .geint_con = EXYNOS_GPIO_ECON_OFFSET, | ||
638 | .geint_mask = EXYNOS_GPIO_EMASK_OFFSET, | ||
639 | .geint_pend = EXYNOS_GPIO_EPEND_OFFSET, | ||
640 | .svc = EXYNOS_SVC_OFFSET, | ||
641 | .eint_gpio_init = exynos_eint_gpio_init, | ||
642 | .label = "exynos4x12-gpio-ctrl0", | ||
643 | }, { | ||
644 | /* pin-controller instance 1 data */ | ||
645 | .pin_banks = exynos4x12_pin_banks1, | ||
646 | .nr_banks = ARRAY_SIZE(exynos4x12_pin_banks1), | ||
647 | .geint_con = EXYNOS_GPIO_ECON_OFFSET, | ||
648 | .geint_mask = EXYNOS_GPIO_EMASK_OFFSET, | ||
649 | .geint_pend = EXYNOS_GPIO_EPEND_OFFSET, | ||
650 | .weint_con = EXYNOS_WKUP_ECON_OFFSET, | ||
651 | .weint_mask = EXYNOS_WKUP_EMASK_OFFSET, | ||
652 | .weint_pend = EXYNOS_WKUP_EPEND_OFFSET, | ||
653 | .svc = EXYNOS_SVC_OFFSET, | ||
654 | .eint_gpio_init = exynos_eint_gpio_init, | ||
655 | .eint_wkup_init = exynos_eint_wkup_init, | ||
656 | .label = "exynos4x12-gpio-ctrl1", | ||
657 | }, { | ||
658 | /* pin-controller instance 2 data */ | ||
659 | .pin_banks = exynos4x12_pin_banks2, | ||
660 | .nr_banks = ARRAY_SIZE(exynos4x12_pin_banks2), | ||
661 | .geint_con = EXYNOS_GPIO_ECON_OFFSET, | ||
662 | .geint_mask = EXYNOS_GPIO_EMASK_OFFSET, | ||
663 | .geint_pend = EXYNOS_GPIO_EPEND_OFFSET, | ||
664 | .svc = EXYNOS_SVC_OFFSET, | ||
665 | .eint_gpio_init = exynos_eint_gpio_init, | ||
666 | .label = "exynos4x12-gpio-ctrl2", | ||
667 | }, { | ||
668 | /* pin-controller instance 3 data */ | ||
669 | .pin_banks = exynos4x12_pin_banks3, | ||
670 | .nr_banks = ARRAY_SIZE(exynos4x12_pin_banks3), | ||
671 | .geint_con = EXYNOS_GPIO_ECON_OFFSET, | ||
672 | .geint_mask = EXYNOS_GPIO_EMASK_OFFSET, | ||
673 | .geint_pend = EXYNOS_GPIO_EPEND_OFFSET, | ||
674 | .svc = EXYNOS_SVC_OFFSET, | ||
675 | .eint_gpio_init = exynos_eint_gpio_init, | ||
676 | .label = "exynos4x12-gpio-ctrl3", | ||
677 | }, | ||
678 | }; | ||
diff --git a/drivers/pinctrl/pinctrl-exynos.h b/drivers/pinctrl/pinctrl-exynos.h index 31d0a06174e4..0a708890d8b4 100644 --- a/drivers/pinctrl/pinctrl-exynos.h +++ b/drivers/pinctrl/pinctrl-exynos.h | |||
@@ -17,125 +17,6 @@ | |||
17 | * (at your option) any later version. | 17 | * (at your option) any later version. |
18 | */ | 18 | */ |
19 | 19 | ||
20 | #define EXYNOS_GPIO_START(__gpio) ((__gpio##_START) + (__gpio##_NR)) | ||
21 | |||
22 | #define EXYNOS4210_GPIO_A0_NR (8) | ||
23 | #define EXYNOS4210_GPIO_A1_NR (6) | ||
24 | #define EXYNOS4210_GPIO_B_NR (8) | ||
25 | #define EXYNOS4210_GPIO_C0_NR (5) | ||
26 | #define EXYNOS4210_GPIO_C1_NR (5) | ||
27 | #define EXYNOS4210_GPIO_D0_NR (4) | ||
28 | #define EXYNOS4210_GPIO_D1_NR (4) | ||
29 | #define EXYNOS4210_GPIO_E0_NR (5) | ||
30 | #define EXYNOS4210_GPIO_E1_NR (8) | ||
31 | #define EXYNOS4210_GPIO_E2_NR (6) | ||
32 | #define EXYNOS4210_GPIO_E3_NR (8) | ||
33 | #define EXYNOS4210_GPIO_E4_NR (8) | ||
34 | #define EXYNOS4210_GPIO_F0_NR (8) | ||
35 | #define EXYNOS4210_GPIO_F1_NR (8) | ||
36 | #define EXYNOS4210_GPIO_F2_NR (8) | ||
37 | #define EXYNOS4210_GPIO_F3_NR (6) | ||
38 | #define EXYNOS4210_GPIO_J0_NR (8) | ||
39 | #define EXYNOS4210_GPIO_J1_NR (5) | ||
40 | #define EXYNOS4210_GPIO_K0_NR (7) | ||
41 | #define EXYNOS4210_GPIO_K1_NR (7) | ||
42 | #define EXYNOS4210_GPIO_K2_NR (7) | ||
43 | #define EXYNOS4210_GPIO_K3_NR (7) | ||
44 | #define EXYNOS4210_GPIO_L0_NR (8) | ||
45 | #define EXYNOS4210_GPIO_L1_NR (3) | ||
46 | #define EXYNOS4210_GPIO_L2_NR (8) | ||
47 | #define EXYNOS4210_GPIO_Y0_NR (6) | ||
48 | #define EXYNOS4210_GPIO_Y1_NR (4) | ||
49 | #define EXYNOS4210_GPIO_Y2_NR (6) | ||
50 | #define EXYNOS4210_GPIO_Y3_NR (8) | ||
51 | #define EXYNOS4210_GPIO_Y4_NR (8) | ||
52 | #define EXYNOS4210_GPIO_Y5_NR (8) | ||
53 | #define EXYNOS4210_GPIO_Y6_NR (8) | ||
54 | #define EXYNOS4210_GPIO_X0_NR (8) | ||
55 | #define EXYNOS4210_GPIO_X1_NR (8) | ||
56 | #define EXYNOS4210_GPIO_X2_NR (8) | ||
57 | #define EXYNOS4210_GPIO_X3_NR (8) | ||
58 | #define EXYNOS4210_GPIO_Z_NR (7) | ||
59 | |||
60 | enum exynos4210_gpio_xa_start { | ||
61 | EXYNOS4210_GPIO_A0_START = 0, | ||
62 | EXYNOS4210_GPIO_A1_START = EXYNOS_GPIO_START(EXYNOS4210_GPIO_A0), | ||
63 | EXYNOS4210_GPIO_B_START = EXYNOS_GPIO_START(EXYNOS4210_GPIO_A1), | ||
64 | EXYNOS4210_GPIO_C0_START = EXYNOS_GPIO_START(EXYNOS4210_GPIO_B), | ||
65 | EXYNOS4210_GPIO_C1_START = EXYNOS_GPIO_START(EXYNOS4210_GPIO_C0), | ||
66 | EXYNOS4210_GPIO_D0_START = EXYNOS_GPIO_START(EXYNOS4210_GPIO_C1), | ||
67 | EXYNOS4210_GPIO_D1_START = EXYNOS_GPIO_START(EXYNOS4210_GPIO_D0), | ||
68 | EXYNOS4210_GPIO_E0_START = EXYNOS_GPIO_START(EXYNOS4210_GPIO_D1), | ||
69 | EXYNOS4210_GPIO_E1_START = EXYNOS_GPIO_START(EXYNOS4210_GPIO_E0), | ||
70 | EXYNOS4210_GPIO_E2_START = EXYNOS_GPIO_START(EXYNOS4210_GPIO_E1), | ||
71 | EXYNOS4210_GPIO_E3_START = EXYNOS_GPIO_START(EXYNOS4210_GPIO_E2), | ||
72 | EXYNOS4210_GPIO_E4_START = EXYNOS_GPIO_START(EXYNOS4210_GPIO_E3), | ||
73 | EXYNOS4210_GPIO_F0_START = EXYNOS_GPIO_START(EXYNOS4210_GPIO_E4), | ||
74 | EXYNOS4210_GPIO_F1_START = EXYNOS_GPIO_START(EXYNOS4210_GPIO_F0), | ||
75 | EXYNOS4210_GPIO_F2_START = EXYNOS_GPIO_START(EXYNOS4210_GPIO_F1), | ||
76 | EXYNOS4210_GPIO_F3_START = EXYNOS_GPIO_START(EXYNOS4210_GPIO_F2), | ||
77 | }; | ||
78 | |||
79 | enum exynos4210_gpio_xb_start { | ||
80 | EXYNOS4210_GPIO_J0_START = 0, | ||
81 | EXYNOS4210_GPIO_J1_START = EXYNOS_GPIO_START(EXYNOS4210_GPIO_J0), | ||
82 | EXYNOS4210_GPIO_K0_START = EXYNOS_GPIO_START(EXYNOS4210_GPIO_J1), | ||
83 | EXYNOS4210_GPIO_K1_START = EXYNOS_GPIO_START(EXYNOS4210_GPIO_K0), | ||
84 | EXYNOS4210_GPIO_K2_START = EXYNOS_GPIO_START(EXYNOS4210_GPIO_K1), | ||
85 | EXYNOS4210_GPIO_K3_START = EXYNOS_GPIO_START(EXYNOS4210_GPIO_K2), | ||
86 | EXYNOS4210_GPIO_L0_START = EXYNOS_GPIO_START(EXYNOS4210_GPIO_K3), | ||
87 | EXYNOS4210_GPIO_L1_START = EXYNOS_GPIO_START(EXYNOS4210_GPIO_L0), | ||
88 | EXYNOS4210_GPIO_L2_START = EXYNOS_GPIO_START(EXYNOS4210_GPIO_L1), | ||
89 | EXYNOS4210_GPIO_Y0_START = EXYNOS_GPIO_START(EXYNOS4210_GPIO_L2), | ||
90 | EXYNOS4210_GPIO_Y1_START = EXYNOS_GPIO_START(EXYNOS4210_GPIO_Y0), | ||
91 | EXYNOS4210_GPIO_Y2_START = EXYNOS_GPIO_START(EXYNOS4210_GPIO_Y1), | ||
92 | EXYNOS4210_GPIO_Y3_START = EXYNOS_GPIO_START(EXYNOS4210_GPIO_Y2), | ||
93 | EXYNOS4210_GPIO_Y4_START = EXYNOS_GPIO_START(EXYNOS4210_GPIO_Y3), | ||
94 | EXYNOS4210_GPIO_Y5_START = EXYNOS_GPIO_START(EXYNOS4210_GPIO_Y4), | ||
95 | EXYNOS4210_GPIO_Y6_START = EXYNOS_GPIO_START(EXYNOS4210_GPIO_Y5), | ||
96 | EXYNOS4210_GPIO_X0_START = EXYNOS_GPIO_START(EXYNOS4210_GPIO_Y6), | ||
97 | EXYNOS4210_GPIO_X1_START = EXYNOS_GPIO_START(EXYNOS4210_GPIO_X0), | ||
98 | EXYNOS4210_GPIO_X2_START = EXYNOS_GPIO_START(EXYNOS4210_GPIO_X1), | ||
99 | EXYNOS4210_GPIO_X3_START = EXYNOS_GPIO_START(EXYNOS4210_GPIO_X2), | ||
100 | }; | ||
101 | |||
102 | enum exynos4210_gpio_xc_start { | ||
103 | EXYNOS4210_GPIO_Z_START = 0, | ||
104 | }; | ||
105 | |||
106 | #define EXYNOS4210_GPIO_A0_IRQ EXYNOS4210_GPIO_A0_START | ||
107 | #define EXYNOS4210_GPIO_A1_IRQ EXYNOS4210_GPIO_A1_START | ||
108 | #define EXYNOS4210_GPIO_B_IRQ EXYNOS4210_GPIO_B_START | ||
109 | #define EXYNOS4210_GPIO_C0_IRQ EXYNOS4210_GPIO_C0_START | ||
110 | #define EXYNOS4210_GPIO_C1_IRQ EXYNOS4210_GPIO_C1_START | ||
111 | #define EXYNOS4210_GPIO_D0_IRQ EXYNOS4210_GPIO_D0_START | ||
112 | #define EXYNOS4210_GPIO_D1_IRQ EXYNOS4210_GPIO_D1_START | ||
113 | #define EXYNOS4210_GPIO_E0_IRQ EXYNOS4210_GPIO_E0_START | ||
114 | #define EXYNOS4210_GPIO_E1_IRQ EXYNOS4210_GPIO_E1_START | ||
115 | #define EXYNOS4210_GPIO_E2_IRQ EXYNOS4210_GPIO_E2_START | ||
116 | #define EXYNOS4210_GPIO_E3_IRQ EXYNOS4210_GPIO_E3_START | ||
117 | #define EXYNOS4210_GPIO_E4_IRQ EXYNOS4210_GPIO_E4_START | ||
118 | #define EXYNOS4210_GPIO_F0_IRQ EXYNOS4210_GPIO_F0_START | ||
119 | #define EXYNOS4210_GPIO_F1_IRQ EXYNOS4210_GPIO_F1_START | ||
120 | #define EXYNOS4210_GPIO_F2_IRQ EXYNOS4210_GPIO_F2_START | ||
121 | #define EXYNOS4210_GPIO_F3_IRQ EXYNOS4210_GPIO_F3_START | ||
122 | #define EXYNOS4210_GPIO_J0_IRQ EXYNOS4210_GPIO_J0_START | ||
123 | #define EXYNOS4210_GPIO_J1_IRQ EXYNOS4210_GPIO_J1_START | ||
124 | #define EXYNOS4210_GPIO_K0_IRQ EXYNOS4210_GPIO_K0_START | ||
125 | #define EXYNOS4210_GPIO_K1_IRQ EXYNOS4210_GPIO_K1_START | ||
126 | #define EXYNOS4210_GPIO_K2_IRQ EXYNOS4210_GPIO_K2_START | ||
127 | #define EXYNOS4210_GPIO_K3_IRQ EXYNOS4210_GPIO_K3_START | ||
128 | #define EXYNOS4210_GPIO_L0_IRQ EXYNOS4210_GPIO_L0_START | ||
129 | #define EXYNOS4210_GPIO_L1_IRQ EXYNOS4210_GPIO_L1_START | ||
130 | #define EXYNOS4210_GPIO_L2_IRQ EXYNOS4210_GPIO_L2_START | ||
131 | #define EXYNOS4210_GPIO_Z_IRQ EXYNOS4210_GPIO_Z_START | ||
132 | |||
133 | #define EXYNOS4210_GPIOA_NR_PINS EXYNOS_GPIO_START(EXYNOS4210_GPIO_F3) | ||
134 | #define EXYNOS4210_GPIOA_NR_GINT EXYNOS_GPIO_START(EXYNOS4210_GPIO_F3) | ||
135 | #define EXYNOS4210_GPIOB_NR_PINS EXYNOS_GPIO_START(EXYNOS4210_GPIO_X3) | ||
136 | #define EXYNOS4210_GPIOB_NR_GINT EXYNOS_GPIO_START(EXYNOS4210_GPIO_L2) | ||
137 | #define EXYNOS4210_GPIOC_NR_PINS EXYNOS_GPIO_START(EXYNOS4210_GPIO_Z) | ||
138 | |||
139 | /* External GPIO and wakeup interrupt related definitions */ | 20 | /* External GPIO and wakeup interrupt related definitions */ |
140 | #define EXYNOS_GPIO_ECON_OFFSET 0x700 | 21 | #define EXYNOS_GPIO_ECON_OFFSET 0x700 |
141 | #define EXYNOS_GPIO_EMASK_OFFSET 0x900 | 22 | #define EXYNOS_GPIO_EMASK_OFFSET 0x900 |
@@ -165,11 +46,10 @@ enum exynos4210_gpio_xc_start { | |||
165 | #define EXYNOS_EINT_MAX_PER_BANK 8 | 46 | #define EXYNOS_EINT_MAX_PER_BANK 8 |
166 | #define EXYNOS_EINT_NR_WKUP_EINT | 47 | #define EXYNOS_EINT_NR_WKUP_EINT |
167 | 48 | ||
168 | #define EXYNOS_PIN_BANK_EINTN(reg, __gpio, id) \ | 49 | #define EXYNOS_PIN_BANK_EINTN(pins, reg, id) \ |
169 | { \ | 50 | { \ |
170 | .pctl_offset = reg, \ | 51 | .pctl_offset = reg, \ |
171 | .pin_base = (__gpio##_START), \ | 52 | .nr_pins = pins, \ |
172 | .nr_pins = (__gpio##_NR), \ | ||
173 | .func_width = 4, \ | 53 | .func_width = 4, \ |
174 | .pud_width = 2, \ | 54 | .pud_width = 2, \ |
175 | .drv_width = 2, \ | 55 | .drv_width = 2, \ |
@@ -179,40 +59,50 @@ enum exynos4210_gpio_xc_start { | |||
179 | .name = id \ | 59 | .name = id \ |
180 | } | 60 | } |
181 | 61 | ||
182 | #define EXYNOS_PIN_BANK_EINTG(reg, __gpio, id) \ | 62 | #define EXYNOS_PIN_BANK_EINTG(pins, reg, id, offs) \ |
183 | { \ | 63 | { \ |
184 | .pctl_offset = reg, \ | 64 | .pctl_offset = reg, \ |
185 | .pin_base = (__gpio##_START), \ | 65 | .nr_pins = pins, \ |
186 | .nr_pins = (__gpio##_NR), \ | ||
187 | .func_width = 4, \ | 66 | .func_width = 4, \ |
188 | .pud_width = 2, \ | 67 | .pud_width = 2, \ |
189 | .drv_width = 2, \ | 68 | .drv_width = 2, \ |
190 | .conpdn_width = 2, \ | 69 | .conpdn_width = 2, \ |
191 | .pudpdn_width = 2, \ | 70 | .pudpdn_width = 2, \ |
192 | .eint_type = EINT_TYPE_GPIO, \ | 71 | .eint_type = EINT_TYPE_GPIO, \ |
193 | .irq_base = (__gpio##_IRQ), \ | 72 | .eint_offset = offs, \ |
194 | .name = id \ | 73 | .name = id \ |
195 | } | 74 | } |
196 | 75 | ||
197 | /** | 76 | #define EXYNOS_PIN_BANK_EINTW(pins, reg, id, offs) \ |
198 | * struct exynos_geint_data: gpio eint specific data for irq_chip callbacks. | 77 | { \ |
199 | * @bank: pin bank from which this gpio interrupt originates. | 78 | .pctl_offset = reg, \ |
200 | * @pin: pin number within the bank. | 79 | .nr_pins = pins, \ |
201 | * @eint_offset: offset to be added to the con/pend/mask register bank base. | 80 | .func_width = 4, \ |
202 | */ | 81 | .pud_width = 2, \ |
203 | struct exynos_geint_data { | 82 | .drv_width = 2, \ |
204 | struct samsung_pin_bank *bank; | 83 | .eint_type = EINT_TYPE_WKUP, \ |
205 | u32 pin; | 84 | .eint_offset = offs, \ |
206 | u32 eint_offset; | 85 | .name = id \ |
207 | }; | 86 | } |
208 | 87 | ||
209 | /** | 88 | /** |
210 | * struct exynos_weint_data: irq specific data for all the wakeup interrupts | 89 | * struct exynos_weint_data: irq specific data for all the wakeup interrupts |
211 | * generated by the external wakeup interrupt controller. | 90 | * generated by the external wakeup interrupt controller. |
212 | * @domain: irq domain representing the external wakeup interrupts | ||
213 | * @irq: interrupt number within the domain. | 91 | * @irq: interrupt number within the domain. |
92 | * @bank: bank responsible for this interrupt | ||
214 | */ | 93 | */ |
215 | struct exynos_weint_data { | 94 | struct exynos_weint_data { |
216 | struct irq_domain *domain; | 95 | unsigned int irq; |
217 | u32 irq; | 96 | struct samsung_pin_bank *bank; |
97 | }; | ||
98 | |||
99 | /** | ||
100 | * struct exynos_muxed_weint_data: irq specific data for muxed wakeup interrupts | ||
101 | * generated by the external wakeup interrupt controller. | ||
102 | * @nr_banks: count of banks being part of the mux | ||
103 | * @banks: array of banks being part of the mux | ||
104 | */ | ||
105 | struct exynos_muxed_weint_data { | ||
106 | unsigned int nr_banks; | ||
107 | struct samsung_pin_bank *banks[]; | ||
218 | }; | 108 | }; |
diff --git a/drivers/pinctrl/pinctrl-samsung.c b/drivers/pinctrl/pinctrl-samsung.c index 861cd5f04d5e..81c9896d4f64 100644 --- a/drivers/pinctrl/pinctrl-samsung.c +++ b/drivers/pinctrl/pinctrl-samsung.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include <linux/slab.h> | 26 | #include <linux/slab.h> |
27 | #include <linux/err.h> | 27 | #include <linux/err.h> |
28 | #include <linux/gpio.h> | 28 | #include <linux/gpio.h> |
29 | #include <linux/irqdomain.h> | ||
29 | 30 | ||
30 | #include "core.h" | 31 | #include "core.h" |
31 | #include "pinctrl-samsung.h" | 32 | #include "pinctrl-samsung.h" |
@@ -46,6 +47,13 @@ struct pin_config { | |||
46 | { "samsung,pin-pud-pdn", PINCFG_TYPE_PUD_PDN }, | 47 | { "samsung,pin-pud-pdn", PINCFG_TYPE_PUD_PDN }, |
47 | }; | 48 | }; |
48 | 49 | ||
50 | static unsigned int pin_base = 0; | ||
51 | |||
52 | static inline struct samsung_pin_bank *gc_to_pin_bank(struct gpio_chip *gc) | ||
53 | { | ||
54 | return container_of(gc, struct samsung_pin_bank, gpio_chip); | ||
55 | } | ||
56 | |||
49 | /* check if the selector is a valid pin group selector */ | 57 | /* check if the selector is a valid pin group selector */ |
50 | static int samsung_get_group_count(struct pinctrl_dev *pctldev) | 58 | static int samsung_get_group_count(struct pinctrl_dev *pctldev) |
51 | { | 59 | { |
@@ -250,14 +258,12 @@ static int samsung_pinmux_get_groups(struct pinctrl_dev *pctldev, | |||
250 | * given a pin number that is local to a pin controller, find out the pin bank | 258 | * given a pin number that is local to a pin controller, find out the pin bank |
251 | * and the register base of the pin bank. | 259 | * and the register base of the pin bank. |
252 | */ | 260 | */ |
253 | static void pin_to_reg_bank(struct gpio_chip *gc, unsigned pin, | 261 | static void pin_to_reg_bank(struct samsung_pinctrl_drv_data *drvdata, |
254 | void __iomem **reg, u32 *offset, | 262 | unsigned pin, void __iomem **reg, u32 *offset, |
255 | struct samsung_pin_bank **bank) | 263 | struct samsung_pin_bank **bank) |
256 | { | 264 | { |
257 | struct samsung_pinctrl_drv_data *drvdata; | ||
258 | struct samsung_pin_bank *b; | 265 | struct samsung_pin_bank *b; |
259 | 266 | ||
260 | drvdata = dev_get_drvdata(gc->dev); | ||
261 | b = drvdata->ctrl->pin_banks; | 267 | b = drvdata->ctrl->pin_banks; |
262 | 268 | ||
263 | while ((pin >= b->pin_base) && | 269 | while ((pin >= b->pin_base) && |
@@ -292,7 +298,7 @@ static void samsung_pinmux_setup(struct pinctrl_dev *pctldev, unsigned selector, | |||
292 | * pin function number in the config register. | 298 | * pin function number in the config register. |
293 | */ | 299 | */ |
294 | for (cnt = 0; cnt < drvdata->pin_groups[group].num_pins; cnt++) { | 300 | for (cnt = 0; cnt < drvdata->pin_groups[group].num_pins; cnt++) { |
295 | pin_to_reg_bank(drvdata->gc, pins[cnt] - drvdata->ctrl->base, | 301 | pin_to_reg_bank(drvdata, pins[cnt] - drvdata->ctrl->base, |
296 | ®, &pin_offset, &bank); | 302 | ®, &pin_offset, &bank); |
297 | mask = (1 << bank->func_width) - 1; | 303 | mask = (1 << bank->func_width) - 1; |
298 | shift = pin_offset * bank->func_width; | 304 | shift = pin_offset * bank->func_width; |
@@ -329,10 +335,16 @@ static int samsung_pinmux_gpio_set_direction(struct pinctrl_dev *pctldev, | |||
329 | struct pinctrl_gpio_range *range, unsigned offset, bool input) | 335 | struct pinctrl_gpio_range *range, unsigned offset, bool input) |
330 | { | 336 | { |
331 | struct samsung_pin_bank *bank; | 337 | struct samsung_pin_bank *bank; |
338 | struct samsung_pinctrl_drv_data *drvdata; | ||
332 | void __iomem *reg; | 339 | void __iomem *reg; |
333 | u32 data, pin_offset, mask, shift; | 340 | u32 data, pin_offset, mask, shift; |
334 | 341 | ||
335 | pin_to_reg_bank(range->gc, offset, ®, &pin_offset, &bank); | 342 | bank = gc_to_pin_bank(range->gc); |
343 | drvdata = pinctrl_dev_get_drvdata(pctldev); | ||
344 | |||
345 | pin_offset = offset - bank->pin_base; | ||
346 | reg = drvdata->virt_base + bank->pctl_offset; | ||
347 | |||
336 | mask = (1 << bank->func_width) - 1; | 348 | mask = (1 << bank->func_width) - 1; |
337 | shift = pin_offset * bank->func_width; | 349 | shift = pin_offset * bank->func_width; |
338 | 350 | ||
@@ -366,7 +378,7 @@ static int samsung_pinconf_rw(struct pinctrl_dev *pctldev, unsigned int pin, | |||
366 | u32 cfg_value, cfg_reg; | 378 | u32 cfg_value, cfg_reg; |
367 | 379 | ||
368 | drvdata = pinctrl_dev_get_drvdata(pctldev); | 380 | drvdata = pinctrl_dev_get_drvdata(pctldev); |
369 | pin_to_reg_bank(drvdata->gc, pin - drvdata->ctrl->base, ®_base, | 381 | pin_to_reg_bank(drvdata, pin - drvdata->ctrl->base, ®_base, |
370 | &pin_offset, &bank); | 382 | &pin_offset, &bank); |
371 | 383 | ||
372 | switch (cfg_type) { | 384 | switch (cfg_type) { |
@@ -391,6 +403,9 @@ static int samsung_pinconf_rw(struct pinctrl_dev *pctldev, unsigned int pin, | |||
391 | return -EINVAL; | 403 | return -EINVAL; |
392 | } | 404 | } |
393 | 405 | ||
406 | if (!width) | ||
407 | return -EINVAL; | ||
408 | |||
394 | mask = (1 << width) - 1; | 409 | mask = (1 << width) - 1; |
395 | shift = pin_offset * width; | 410 | shift = pin_offset * width; |
396 | data = readl(reg_base + cfg_reg); | 411 | data = readl(reg_base + cfg_reg); |
@@ -463,14 +478,16 @@ static struct pinconf_ops samsung_pinconf_ops = { | |||
463 | /* gpiolib gpio_set callback function */ | 478 | /* gpiolib gpio_set callback function */ |
464 | static void samsung_gpio_set(struct gpio_chip *gc, unsigned offset, int value) | 479 | static void samsung_gpio_set(struct gpio_chip *gc, unsigned offset, int value) |
465 | { | 480 | { |
481 | struct samsung_pin_bank *bank = gc_to_pin_bank(gc); | ||
466 | void __iomem *reg; | 482 | void __iomem *reg; |
467 | u32 pin_offset, data; | 483 | u32 data; |
484 | |||
485 | reg = bank->drvdata->virt_base + bank->pctl_offset; | ||
468 | 486 | ||
469 | pin_to_reg_bank(gc, offset, ®, &pin_offset, NULL); | ||
470 | data = readl(reg + DAT_REG); | 487 | data = readl(reg + DAT_REG); |
471 | data &= ~(1 << pin_offset); | 488 | data &= ~(1 << offset); |
472 | if (value) | 489 | if (value) |
473 | data |= 1 << pin_offset; | 490 | data |= 1 << offset; |
474 | writel(data, reg + DAT_REG); | 491 | writel(data, reg + DAT_REG); |
475 | } | 492 | } |
476 | 493 | ||
@@ -478,11 +495,13 @@ static void samsung_gpio_set(struct gpio_chip *gc, unsigned offset, int value) | |||
478 | static int samsung_gpio_get(struct gpio_chip *gc, unsigned offset) | 495 | static int samsung_gpio_get(struct gpio_chip *gc, unsigned offset) |
479 | { | 496 | { |
480 | void __iomem *reg; | 497 | void __iomem *reg; |
481 | u32 pin_offset, data; | 498 | u32 data; |
499 | struct samsung_pin_bank *bank = gc_to_pin_bank(gc); | ||
500 | |||
501 | reg = bank->drvdata->virt_base + bank->pctl_offset; | ||
482 | 502 | ||
483 | pin_to_reg_bank(gc, offset, ®, &pin_offset, NULL); | ||
484 | data = readl(reg + DAT_REG); | 503 | data = readl(reg + DAT_REG); |
485 | data >>= pin_offset; | 504 | data >>= offset; |
486 | data &= 1; | 505 | data &= 1; |
487 | return data; | 506 | return data; |
488 | } | 507 | } |
@@ -510,6 +529,23 @@ static int samsung_gpio_direction_output(struct gpio_chip *gc, unsigned offset, | |||
510 | } | 529 | } |
511 | 530 | ||
512 | /* | 531 | /* |
532 | * gpiolib gpio_to_irq callback function. Creates a mapping between a GPIO pin | ||
533 | * and a virtual IRQ, if not already present. | ||
534 | */ | ||
535 | static int samsung_gpio_to_irq(struct gpio_chip *gc, unsigned offset) | ||
536 | { | ||
537 | struct samsung_pin_bank *bank = gc_to_pin_bank(gc); | ||
538 | unsigned int virq; | ||
539 | |||
540 | if (!bank->irq_domain) | ||
541 | return -ENXIO; | ||
542 | |||
543 | virq = irq_create_mapping(bank->irq_domain, offset); | ||
544 | |||
545 | return (virq) ? : -ENXIO; | ||
546 | } | ||
547 | |||
548 | /* | ||
513 | * Parse the pin names listed in the 'samsung,pins' property and convert it | 549 | * Parse the pin names listed in the 'samsung,pins' property and convert it |
514 | * into a list of gpio numbers are create a pin group from it. | 550 | * into a list of gpio numbers are create a pin group from it. |
515 | */ | 551 | */ |
@@ -597,7 +633,7 @@ static int __devinit samsung_pinctrl_parse_dt(struct platform_device *pdev, | |||
597 | */ | 633 | */ |
598 | for_each_child_of_node(dev_np, cfg_np) { | 634 | for_each_child_of_node(dev_np, cfg_np) { |
599 | u32 function; | 635 | u32 function; |
600 | if (of_find_property(cfg_np, "interrupt-controller", NULL)) | 636 | if (!of_find_property(cfg_np, "samsung,pins", NULL)) |
601 | continue; | 637 | continue; |
602 | 638 | ||
603 | ret = samsung_pinctrl_parse_dt_pins(pdev, cfg_np, | 639 | ret = samsung_pinctrl_parse_dt_pins(pdev, cfg_np, |
@@ -712,12 +748,16 @@ static int __devinit samsung_pinctrl_register(struct platform_device *pdev, | |||
712 | return -EINVAL; | 748 | return -EINVAL; |
713 | } | 749 | } |
714 | 750 | ||
715 | drvdata->grange.name = "samsung-pctrl-gpio-range"; | 751 | for (bank = 0; bank < drvdata->ctrl->nr_banks; ++bank) { |
716 | drvdata->grange.id = 0; | 752 | pin_bank = &drvdata->ctrl->pin_banks[bank]; |
717 | drvdata->grange.base = drvdata->ctrl->base; | 753 | pin_bank->grange.name = pin_bank->name; |
718 | drvdata->grange.npins = drvdata->ctrl->nr_pins; | 754 | pin_bank->grange.id = bank; |
719 | drvdata->grange.gc = drvdata->gc; | 755 | pin_bank->grange.pin_base = pin_bank->pin_base; |
720 | pinctrl_add_gpio_range(drvdata->pctl_dev, &drvdata->grange); | 756 | pin_bank->grange.base = pin_bank->gpio_chip.base; |
757 | pin_bank->grange.npins = pin_bank->gpio_chip.ngpio; | ||
758 | pin_bank->grange.gc = &pin_bank->gpio_chip; | ||
759 | pinctrl_add_gpio_range(drvdata->pctl_dev, &pin_bank->grange); | ||
760 | } | ||
721 | 761 | ||
722 | ret = samsung_pinctrl_parse_dt(pdev, drvdata); | 762 | ret = samsung_pinctrl_parse_dt(pdev, drvdata); |
723 | if (ret) { | 763 | if (ret) { |
@@ -728,68 +768,117 @@ static int __devinit samsung_pinctrl_register(struct platform_device *pdev, | |||
728 | return 0; | 768 | return 0; |
729 | } | 769 | } |
730 | 770 | ||
771 | static const struct gpio_chip samsung_gpiolib_chip = { | ||
772 | .set = samsung_gpio_set, | ||
773 | .get = samsung_gpio_get, | ||
774 | .direction_input = samsung_gpio_direction_input, | ||
775 | .direction_output = samsung_gpio_direction_output, | ||
776 | .to_irq = samsung_gpio_to_irq, | ||
777 | .owner = THIS_MODULE, | ||
778 | }; | ||
779 | |||
731 | /* register the gpiolib interface with the gpiolib subsystem */ | 780 | /* register the gpiolib interface with the gpiolib subsystem */ |
732 | static int __devinit samsung_gpiolib_register(struct platform_device *pdev, | 781 | static int __devinit samsung_gpiolib_register(struct platform_device *pdev, |
733 | struct samsung_pinctrl_drv_data *drvdata) | 782 | struct samsung_pinctrl_drv_data *drvdata) |
734 | { | 783 | { |
784 | struct samsung_pin_ctrl *ctrl = drvdata->ctrl; | ||
785 | struct samsung_pin_bank *bank = ctrl->pin_banks; | ||
735 | struct gpio_chip *gc; | 786 | struct gpio_chip *gc; |
736 | int ret; | 787 | int ret; |
737 | 788 | int i; | |
738 | gc = devm_kzalloc(&pdev->dev, sizeof(*gc), GFP_KERNEL); | 789 | |
739 | if (!gc) { | 790 | for (i = 0; i < ctrl->nr_banks; ++i, ++bank) { |
740 | dev_err(&pdev->dev, "mem alloc for gpio_chip failed\n"); | 791 | bank->gpio_chip = samsung_gpiolib_chip; |
741 | return -ENOMEM; | 792 | |
742 | } | 793 | gc = &bank->gpio_chip; |
743 | 794 | gc->base = ctrl->base + bank->pin_base; | |
744 | drvdata->gc = gc; | 795 | gc->ngpio = bank->nr_pins; |
745 | gc->base = drvdata->ctrl->base; | 796 | gc->dev = &pdev->dev; |
746 | gc->ngpio = drvdata->ctrl->nr_pins; | 797 | gc->of_node = bank->of_node; |
747 | gc->dev = &pdev->dev; | 798 | gc->label = bank->name; |
748 | gc->set = samsung_gpio_set; | 799 | |
749 | gc->get = samsung_gpio_get; | 800 | ret = gpiochip_add(gc); |
750 | gc->direction_input = samsung_gpio_direction_input; | 801 | if (ret) { |
751 | gc->direction_output = samsung_gpio_direction_output; | 802 | dev_err(&pdev->dev, "failed to register gpio_chip %s, error code: %d\n", |
752 | gc->label = drvdata->ctrl->label; | 803 | gc->label, ret); |
753 | gc->owner = THIS_MODULE; | 804 | goto fail; |
754 | ret = gpiochip_add(gc); | 805 | } |
755 | if (ret) { | ||
756 | dev_err(&pdev->dev, "failed to register gpio_chip %s, error " | ||
757 | "code: %d\n", gc->label, ret); | ||
758 | return ret; | ||
759 | } | 806 | } |
760 | 807 | ||
761 | return 0; | 808 | return 0; |
809 | |||
810 | fail: | ||
811 | for (--i, --bank; i >= 0; --i, --bank) | ||
812 | if (gpiochip_remove(&bank->gpio_chip)) | ||
813 | dev_err(&pdev->dev, "gpio chip %s remove failed\n", | ||
814 | bank->gpio_chip.label); | ||
815 | return ret; | ||
762 | } | 816 | } |
763 | 817 | ||
764 | /* unregister the gpiolib interface with the gpiolib subsystem */ | 818 | /* unregister the gpiolib interface with the gpiolib subsystem */ |
765 | static int __devinit samsung_gpiolib_unregister(struct platform_device *pdev, | 819 | static int __devinit samsung_gpiolib_unregister(struct platform_device *pdev, |
766 | struct samsung_pinctrl_drv_data *drvdata) | 820 | struct samsung_pinctrl_drv_data *drvdata) |
767 | { | 821 | { |
768 | int ret = gpiochip_remove(drvdata->gc); | 822 | struct samsung_pin_ctrl *ctrl = drvdata->ctrl; |
769 | if (ret) { | 823 | struct samsung_pin_bank *bank = ctrl->pin_banks; |
824 | int ret = 0; | ||
825 | int i; | ||
826 | |||
827 | for (i = 0; !ret && i < ctrl->nr_banks; ++i, ++bank) | ||
828 | ret = gpiochip_remove(&bank->gpio_chip); | ||
829 | |||
830 | if (ret) | ||
770 | dev_err(&pdev->dev, "gpio chip remove failed\n"); | 831 | dev_err(&pdev->dev, "gpio chip remove failed\n"); |
771 | return ret; | 832 | |
772 | } | 833 | return ret; |
773 | return 0; | ||
774 | } | 834 | } |
775 | 835 | ||
776 | static const struct of_device_id samsung_pinctrl_dt_match[]; | 836 | static const struct of_device_id samsung_pinctrl_dt_match[]; |
777 | 837 | ||
778 | /* retrieve the soc specific data */ | 838 | /* retrieve the soc specific data */ |
779 | static struct samsung_pin_ctrl *samsung_pinctrl_get_soc_data( | 839 | static struct samsung_pin_ctrl *samsung_pinctrl_get_soc_data( |
840 | struct samsung_pinctrl_drv_data *d, | ||
780 | struct platform_device *pdev) | 841 | struct platform_device *pdev) |
781 | { | 842 | { |
782 | int id; | 843 | int id; |
783 | const struct of_device_id *match; | 844 | const struct of_device_id *match; |
784 | const struct device_node *node = pdev->dev.of_node; | 845 | struct device_node *node = pdev->dev.of_node; |
846 | struct device_node *np; | ||
847 | struct samsung_pin_ctrl *ctrl; | ||
848 | struct samsung_pin_bank *bank; | ||
849 | int i; | ||
785 | 850 | ||
786 | id = of_alias_get_id(pdev->dev.of_node, "pinctrl"); | 851 | id = of_alias_get_id(node, "pinctrl"); |
787 | if (id < 0) { | 852 | if (id < 0) { |
788 | dev_err(&pdev->dev, "failed to get alias id\n"); | 853 | dev_err(&pdev->dev, "failed to get alias id\n"); |
789 | return NULL; | 854 | return NULL; |
790 | } | 855 | } |
791 | match = of_match_node(samsung_pinctrl_dt_match, node); | 856 | match = of_match_node(samsung_pinctrl_dt_match, node); |
792 | return (struct samsung_pin_ctrl *)match->data + id; | 857 | ctrl = (struct samsung_pin_ctrl *)match->data + id; |
858 | |||
859 | bank = ctrl->pin_banks; | ||
860 | for (i = 0; i < ctrl->nr_banks; ++i, ++bank) { | ||
861 | bank->drvdata = d; | ||
862 | bank->pin_base = ctrl->nr_pins; | ||
863 | ctrl->nr_pins += bank->nr_pins; | ||
864 | } | ||
865 | |||
866 | for_each_child_of_node(node, np) { | ||
867 | if (!of_find_property(np, "gpio-controller", NULL)) | ||
868 | continue; | ||
869 | bank = ctrl->pin_banks; | ||
870 | for (i = 0; i < ctrl->nr_banks; ++i, ++bank) { | ||
871 | if (!strcmp(bank->name, np->name)) { | ||
872 | bank->of_node = np; | ||
873 | break; | ||
874 | } | ||
875 | } | ||
876 | } | ||
877 | |||
878 | ctrl->base = pin_base; | ||
879 | pin_base += ctrl->nr_pins; | ||
880 | |||
881 | return ctrl; | ||
793 | } | 882 | } |
794 | 883 | ||
795 | static int __devinit samsung_pinctrl_probe(struct platform_device *pdev) | 884 | static int __devinit samsung_pinctrl_probe(struct platform_device *pdev) |
@@ -805,18 +894,18 @@ static int __devinit samsung_pinctrl_probe(struct platform_device *pdev) | |||
805 | return -ENODEV; | 894 | return -ENODEV; |
806 | } | 895 | } |
807 | 896 | ||
808 | ctrl = samsung_pinctrl_get_soc_data(pdev); | ||
809 | if (!ctrl) { | ||
810 | dev_err(&pdev->dev, "driver data not available\n"); | ||
811 | return -EINVAL; | ||
812 | } | ||
813 | |||
814 | drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL); | 897 | drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL); |
815 | if (!drvdata) { | 898 | if (!drvdata) { |
816 | dev_err(dev, "failed to allocate memory for driver's " | 899 | dev_err(dev, "failed to allocate memory for driver's " |
817 | "private data\n"); | 900 | "private data\n"); |
818 | return -ENOMEM; | 901 | return -ENOMEM; |
819 | } | 902 | } |
903 | |||
904 | ctrl = samsung_pinctrl_get_soc_data(drvdata, pdev); | ||
905 | if (!ctrl) { | ||
906 | dev_err(&pdev->dev, "driver data not available\n"); | ||
907 | return -EINVAL; | ||
908 | } | ||
820 | drvdata->ctrl = ctrl; | 909 | drvdata->ctrl = ctrl; |
821 | drvdata->dev = dev; | 910 | drvdata->dev = dev; |
822 | 911 | ||
@@ -858,6 +947,8 @@ static int __devinit samsung_pinctrl_probe(struct platform_device *pdev) | |||
858 | static const struct of_device_id samsung_pinctrl_dt_match[] = { | 947 | static const struct of_device_id samsung_pinctrl_dt_match[] = { |
859 | { .compatible = "samsung,pinctrl-exynos4210", | 948 | { .compatible = "samsung,pinctrl-exynos4210", |
860 | .data = (void *)exynos4210_pin_ctrl }, | 949 | .data = (void *)exynos4210_pin_ctrl }, |
950 | { .compatible = "samsung,pinctrl-exynos4x12", | ||
951 | .data = (void *)exynos4x12_pin_ctrl }, | ||
861 | {}, | 952 | {}, |
862 | }; | 953 | }; |
863 | MODULE_DEVICE_TABLE(of, samsung_pinctrl_dt_match); | 954 | MODULE_DEVICE_TABLE(of, samsung_pinctrl_dt_match); |
diff --git a/drivers/pinctrl/pinctrl-samsung.h b/drivers/pinctrl/pinctrl-samsung.h index b8956934cda6..5addfd16e3cc 100644 --- a/drivers/pinctrl/pinctrl-samsung.h +++ b/drivers/pinctrl/pinctrl-samsung.h | |||
@@ -23,6 +23,8 @@ | |||
23 | #include <linux/pinctrl/consumer.h> | 23 | #include <linux/pinctrl/consumer.h> |
24 | #include <linux/pinctrl/machine.h> | 24 | #include <linux/pinctrl/machine.h> |
25 | 25 | ||
26 | #include <linux/gpio.h> | ||
27 | |||
26 | /* register offsets within a pin bank */ | 28 | /* register offsets within a pin bank */ |
27 | #define DAT_REG 0x4 | 29 | #define DAT_REG 0x4 |
28 | #define PUD_REG 0x8 | 30 | #define PUD_REG 0x8 |
@@ -64,6 +66,7 @@ enum pincfg_type { | |||
64 | * @EINT_TYPE_NONE: bank does not support external interrupts | 66 | * @EINT_TYPE_NONE: bank does not support external interrupts |
65 | * @EINT_TYPE_GPIO: bank supportes external gpio interrupts | 67 | * @EINT_TYPE_GPIO: bank supportes external gpio interrupts |
66 | * @EINT_TYPE_WKUP: bank supportes external wakeup interrupts | 68 | * @EINT_TYPE_WKUP: bank supportes external wakeup interrupts |
69 | * @EINT_TYPE_WKUP_MUX: bank supports multiplexed external wakeup interrupts | ||
67 | * | 70 | * |
68 | * Samsung GPIO controller groups all the available pins into banks. The pins | 71 | * Samsung GPIO controller groups all the available pins into banks. The pins |
69 | * in a pin bank can support external gpio interrupts or external wakeup | 72 | * in a pin bank can support external gpio interrupts or external wakeup |
@@ -76,6 +79,7 @@ enum eint_type { | |||
76 | EINT_TYPE_NONE, | 79 | EINT_TYPE_NONE, |
77 | EINT_TYPE_GPIO, | 80 | EINT_TYPE_GPIO, |
78 | EINT_TYPE_WKUP, | 81 | EINT_TYPE_WKUP, |
82 | EINT_TYPE_WKUP_MUX, | ||
79 | }; | 83 | }; |
80 | 84 | ||
81 | /* maximum length of a pin in pin descriptor (example: "gpa0-0") */ | 85 | /* maximum length of a pin in pin descriptor (example: "gpa0-0") */ |
@@ -109,8 +113,12 @@ struct samsung_pinctrl_drv_data; | |||
109 | * @conpdn_width: width of the sleep mode function selector bin field. | 113 | * @conpdn_width: width of the sleep mode function selector bin field. |
110 | * @pudpdn_width: width of the sleep mode pull up/down selector bit field. | 114 | * @pudpdn_width: width of the sleep mode pull up/down selector bit field. |
111 | * @eint_type: type of the external interrupt supported by the bank. | 115 | * @eint_type: type of the external interrupt supported by the bank. |
112 | * @irq_base: starting controller local irq number of the bank. | ||
113 | * @name: name to be prefixed for each pin in this pin bank. | 116 | * @name: name to be prefixed for each pin in this pin bank. |
117 | * @of_node: OF node of the bank. | ||
118 | * @drvdata: link to controller driver data | ||
119 | * @irq_domain: IRQ domain of the bank. | ||
120 | * @gpio_chip: GPIO chip of the bank. | ||
121 | * @grange: linux gpio pin range supported by this bank. | ||
114 | */ | 122 | */ |
115 | struct samsung_pin_bank { | 123 | struct samsung_pin_bank { |
116 | u32 pctl_offset; | 124 | u32 pctl_offset; |
@@ -122,8 +130,13 @@ struct samsung_pin_bank { | |||
122 | u8 conpdn_width; | 130 | u8 conpdn_width; |
123 | u8 pudpdn_width; | 131 | u8 pudpdn_width; |
124 | enum eint_type eint_type; | 132 | enum eint_type eint_type; |
125 | u32 irq_base; | 133 | u32 eint_offset; |
126 | char *name; | 134 | char *name; |
135 | struct device_node *of_node; | ||
136 | struct samsung_pinctrl_drv_data *drvdata; | ||
137 | struct irq_domain *irq_domain; | ||
138 | struct gpio_chip gpio_chip; | ||
139 | struct pinctrl_gpio_range grange; | ||
127 | }; | 140 | }; |
128 | 141 | ||
129 | /** | 142 | /** |
@@ -132,8 +145,6 @@ struct samsung_pin_bank { | |||
132 | * @nr_banks: number of pin banks. | 145 | * @nr_banks: number of pin banks. |
133 | * @base: starting system wide pin number. | 146 | * @base: starting system wide pin number. |
134 | * @nr_pins: number of pins supported by the controller. | 147 | * @nr_pins: number of pins supported by the controller. |
135 | * @nr_gint: number of external gpio interrupts supported. | ||
136 | * @nr_wint: number of external wakeup interrupts supported. | ||
137 | * @geint_con: offset of the ext-gpio controller registers. | 148 | * @geint_con: offset of the ext-gpio controller registers. |
138 | * @geint_mask: offset of the ext-gpio interrupt mask registers. | 149 | * @geint_mask: offset of the ext-gpio interrupt mask registers. |
139 | * @geint_pend: offset of the ext-gpio interrupt pending registers. | 150 | * @geint_pend: offset of the ext-gpio interrupt pending registers. |
@@ -153,8 +164,6 @@ struct samsung_pin_ctrl { | |||
153 | 164 | ||
154 | u32 base; | 165 | u32 base; |
155 | u32 nr_pins; | 166 | u32 nr_pins; |
156 | u32 nr_gint; | ||
157 | u32 nr_wint; | ||
158 | 167 | ||
159 | u32 geint_con; | 168 | u32 geint_con; |
160 | u32 geint_mask; | 169 | u32 geint_mask; |
@@ -183,8 +192,6 @@ struct samsung_pin_ctrl { | |||
183 | * @nr_groups: number of such pin groups. | 192 | * @nr_groups: number of such pin groups. |
184 | * @pmx_functions: list of pin functions available to the driver. | 193 | * @pmx_functions: list of pin functions available to the driver. |
185 | * @nr_function: number of such pin functions. | 194 | * @nr_function: number of such pin functions. |
186 | * @gc: gpio_chip instance registered with gpiolib. | ||
187 | * @grange: linux gpio pin range supported by this controller. | ||
188 | */ | 195 | */ |
189 | struct samsung_pinctrl_drv_data { | 196 | struct samsung_pinctrl_drv_data { |
190 | void __iomem *virt_base; | 197 | void __iomem *virt_base; |
@@ -199,12 +206,6 @@ struct samsung_pinctrl_drv_data { | |||
199 | unsigned int nr_groups; | 206 | unsigned int nr_groups; |
200 | const struct samsung_pmx_func *pmx_functions; | 207 | const struct samsung_pmx_func *pmx_functions; |
201 | unsigned int nr_functions; | 208 | unsigned int nr_functions; |
202 | |||
203 | struct irq_domain *gpio_irqd; | ||
204 | struct irq_domain *wkup_irqd; | ||
205 | |||
206 | struct gpio_chip *gc; | ||
207 | struct pinctrl_gpio_range grange; | ||
208 | }; | 209 | }; |
209 | 210 | ||
210 | /** | 211 | /** |
@@ -235,5 +236,6 @@ struct samsung_pmx_func { | |||
235 | 236 | ||
236 | /* list of all exported SoC specific data */ | 237 | /* list of all exported SoC specific data */ |
237 | extern struct samsung_pin_ctrl exynos4210_pin_ctrl[]; | 238 | extern struct samsung_pin_ctrl exynos4210_pin_ctrl[]; |
239 | extern struct samsung_pin_ctrl exynos4x12_pin_ctrl[]; | ||
238 | 240 | ||
239 | #endif /* __PINCTRL_SAMSUNG_H */ | 241 | #endif /* __PINCTRL_SAMSUNG_H */ |