diff options
author | Simon Arlott <simon@fire.lp0.eu> | 2012-09-28 00:10:11 -0400 |
---|---|---|
committer | Linus Walleij <linus.walleij@linaro.org> | 2012-10-01 02:05:22 -0400 |
commit | e1b2dc70cd5b00e17c703163a463d82354b1cc76 (patch) | |
tree | fc013a598baa611ba6651b760f8a03347b2d6e47 /drivers/pinctrl | |
parent | b0e181d0944e858ae0cacf808752e791894c5651 (diff) |
pinctrl: add bcm2835 driver
The BCM2835 GPIO module is a combined GPIO controller, (GPIO) interrupt
controller, and pinmux/control device.
Original driver by Simon Arlott.
Rewrite including GPIO chip device by Chris Boot.
Upstreaming changes by Stephen Warren:
* Wrote DT binding documentation.
* Changed brcm,function to an integer to more directly match the
datasheet, and to match brcm,pins being an integer.
* Implemented pull-up/down pin config.
* Removed read-only DT property and related code. The restriction this
implemented are driven by the board, not the GPIO HW block, so don't
really make sense of a HW block binding, were in general incomplete
(since they could only know about the few pins hard-coded into the
Raspberry Pi B board design and not the uncommitted GPIOS), and are
better represented simply by not writing incorrect data into pin
configuration nodes.
* Don't set GPIO_IN function select in gpio_request_enable() to avoid
glitches; defer this to gpio_set_direction(). Consequently, removed
empty bcm2835_pmx_gpio_request_enable().
* Simplified enabled_irq_map[]; make it explicitly 1 entry per bank.
* Lifted use of enabled_irq_map[] outside the per-interrupt loop in
IRQ handler, thus fixing an issue where the code was indexing into
enabled_irq_map[] by intra-bank GPIO ID, not global GPIO ID.
* Removed locking in IRQ handler, since all other code uses
spin_lock_irqsave() and so guarantees it doesn't run concurrently
with the handler.
* Moved duplicated BUILD_BUG_ON()s into probe(). Also check size of
bcm2835_gpio_pins[].
* Remove range-checking from bcm2835_pctl_get_groups_count() since we've
decided to trust the pinctrl core.
* Made bcm2835_pmx_gpio_disable_free() call bcm2835_pinctrl_fsel_set()
directly for simplicity.
* Fixed body of dt_free_map() to match latest dt_node_to_map().
* Removed GPIO ownership check from bcm2835_pmx_enable() since the pinctrl
core owns doing this.
* Made irq_chip and pinctrl_gpio_range .name == MODULE_NAME so it's more
descriptive.
* Simplified remove(); removed call to non-existent
pinctrl_remove_gpio_range(), remove early return on error.
* Don't force gpiochip's base to 0. Set gpio_range.base to gpiochip's
base GPIO number.
* Error-handling cleanups in probe().
* Switched to module_platform_driver() rather than open-coding.
* Made pin, group, and function names lower-case.
* s/broadcom/brcm/ in DT property names.
* s/2708/2835/.
* Fixed a couple minor checkpatch warnings, and other minor cleanup.
Signed-off-by: Simon Arlott <simon@fire.lp0.eu>
Signed-off-by: Chris Boot <bootc@bootc.net>
Signed-off-by: Stephen Warren <swarren@wwwdotorg.org>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Diffstat (limited to 'drivers/pinctrl')
-rw-r--r-- | drivers/pinctrl/Kconfig | 5 | ||||
-rw-r--r-- | drivers/pinctrl/Makefile | 1 | ||||
-rw-r--r-- | drivers/pinctrl/pinctrl-bcm2835.c | 1075 |
3 files changed, 1081 insertions, 0 deletions
diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig index 73aafd96271f..0cf12896a6f2 100644 --- a/drivers/pinctrl/Kconfig +++ b/drivers/pinctrl/Kconfig | |||
@@ -26,6 +26,11 @@ config DEBUG_PINCTRL | |||
26 | help | 26 | help |
27 | Say Y here to add some extra checks and diagnostics to PINCTRL calls. | 27 | Say Y here to add some extra checks and diagnostics to PINCTRL calls. |
28 | 28 | ||
29 | config PINCTRL_BCM2835 | ||
30 | bool | ||
31 | select PINMUX | ||
32 | select PINCONF | ||
33 | |||
29 | config PINCTRL_IMX | 34 | config PINCTRL_IMX |
30 | bool | 35 | bool |
31 | select PINMUX | 36 | select PINMUX |
diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile index cda3984951e2..84952a2db83c 100644 --- a/drivers/pinctrl/Makefile +++ b/drivers/pinctrl/Makefile | |||
@@ -9,6 +9,7 @@ ifeq ($(CONFIG_OF),y) | |||
9 | obj-$(CONFIG_PINCTRL) += devicetree.o | 9 | obj-$(CONFIG_PINCTRL) += devicetree.o |
10 | endif | 10 | endif |
11 | obj-$(CONFIG_GENERIC_PINCONF) += pinconf-generic.o | 11 | obj-$(CONFIG_GENERIC_PINCONF) += pinconf-generic.o |
12 | obj-$(CONFIG_PINCTRL_BCM2835) += pinctrl-bcm2835.o | ||
12 | obj-$(CONFIG_PINCTRL_IMX) += pinctrl-imx.o | 13 | obj-$(CONFIG_PINCTRL_IMX) += pinctrl-imx.o |
13 | obj-$(CONFIG_PINCTRL_IMX35) += pinctrl-imx35.o | 14 | obj-$(CONFIG_PINCTRL_IMX35) += pinctrl-imx35.o |
14 | obj-$(CONFIG_PINCTRL_IMX51) += pinctrl-imx51.o | 15 | obj-$(CONFIG_PINCTRL_IMX51) += pinctrl-imx51.o |
diff --git a/drivers/pinctrl/pinctrl-bcm2835.c b/drivers/pinctrl/pinctrl-bcm2835.c new file mode 100644 index 000000000000..a4adee633fa9 --- /dev/null +++ b/drivers/pinctrl/pinctrl-bcm2835.c | |||
@@ -0,0 +1,1075 @@ | |||
1 | /* | ||
2 | * Driver for Broadcom BCM2835 GPIO unit (pinctrl + GPIO) | ||
3 | * | ||
4 | * Copyright (C) 2012 Chris Boot, Simon Arlott, Stephen Warren | ||
5 | * | ||
6 | * This driver is inspired by: | ||
7 | * pinctrl-nomadik.c, please see original file for copyright information | ||
8 | * pinctrl-tegra.c, please see original file for copyright information | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License as published by | ||
12 | * the Free Software Foundation; either version 2 of the License, or | ||
13 | * (at your option) any later version. | ||
14 | * | ||
15 | * This program is distributed in the hope that it will be useful, | ||
16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
18 | * GNU General Public License for more details. | ||
19 | */ | ||
20 | |||
21 | #include <linux/bitmap.h> | ||
22 | #include <linux/bug.h> | ||
23 | #include <linux/delay.h> | ||
24 | #include <linux/device.h> | ||
25 | #include <linux/err.h> | ||
26 | #include <linux/gpio.h> | ||
27 | #include <linux/interrupt.h> | ||
28 | #include <linux/io.h> | ||
29 | #include <linux/irq.h> | ||
30 | #include <linux/irqdesc.h> | ||
31 | #include <linux/irqdomain.h> | ||
32 | #include <linux/irq.h> | ||
33 | #include <linux/module.h> | ||
34 | #include <linux/of_address.h> | ||
35 | #include <linux/of.h> | ||
36 | #include <linux/of_irq.h> | ||
37 | #include <linux/pinctrl/consumer.h> | ||
38 | #include <linux/pinctrl/machine.h> | ||
39 | #include <linux/pinctrl/pinconf.h> | ||
40 | #include <linux/pinctrl/pinctrl.h> | ||
41 | #include <linux/pinctrl/pinmux.h> | ||
42 | #include <linux/platform_device.h> | ||
43 | #include <linux/seq_file.h> | ||
44 | #include <linux/slab.h> | ||
45 | #include <linux/spinlock.h> | ||
46 | #include <linux/types.h> | ||
47 | |||
48 | #define MODULE_NAME "pinctrl-bcm2835" | ||
49 | #define BCM2835_NUM_GPIOS 54 | ||
50 | #define BCM2835_NUM_BANKS 2 | ||
51 | |||
52 | #define BCM2835_PIN_BITMAP_SZ \ | ||
53 | DIV_ROUND_UP(BCM2835_NUM_GPIOS, sizeof(unsigned long) * 8) | ||
54 | |||
55 | /* GPIO register offsets */ | ||
56 | #define GPFSEL0 0x0 /* Function Select */ | ||
57 | #define GPSET0 0x1c /* Pin Output Set */ | ||
58 | #define GPCLR0 0x28 /* Pin Output Clear */ | ||
59 | #define GPLEV0 0x34 /* Pin Level */ | ||
60 | #define GPEDS0 0x40 /* Pin Event Detect Status */ | ||
61 | #define GPREN0 0x4c /* Pin Rising Edge Detect Enable */ | ||
62 | #define GPFEN0 0x58 /* Pin Falling Edge Detect Enable */ | ||
63 | #define GPHEN0 0x64 /* Pin High Detect Enable */ | ||
64 | #define GPLEN0 0x70 /* Pin Low Detect Enable */ | ||
65 | #define GPAREN0 0x7c /* Pin Async Rising Edge Detect */ | ||
66 | #define GPAFEN0 0x88 /* Pin Async Falling Edge Detect */ | ||
67 | #define GPPUD 0x94 /* Pin Pull-up/down Enable */ | ||
68 | #define GPPUDCLK0 0x98 /* Pin Pull-up/down Enable Clock */ | ||
69 | |||
70 | #define FSEL_REG(p) (GPFSEL0 + (((p) / 10) * 4)) | ||
71 | #define FSEL_SHIFT(p) (((p) % 10) * 3) | ||
72 | #define GPIO_REG_OFFSET(p) ((p) / 32) | ||
73 | #define GPIO_REG_SHIFT(p) ((p) % 32) | ||
74 | |||
75 | enum bcm2835_pinconf_param { | ||
76 | /* argument: bcm2835_pinconf_pull */ | ||
77 | BCM2835_PINCONF_PARAM_PULL, | ||
78 | }; | ||
79 | |||
80 | enum bcm2835_pinconf_pull { | ||
81 | BCM2835_PINCONFIG_PULL_NONE, | ||
82 | BCM2835_PINCONFIG_PULL_DOWN, | ||
83 | BCM2835_PINCONFIG_PULL_UP, | ||
84 | }; | ||
85 | |||
86 | #define BCM2835_PINCONF_PACK(_param_, _arg_) ((_param_) << 16 | (_arg_)) | ||
87 | #define BCM2835_PINCONF_UNPACK_PARAM(_conf_) ((_conf_) >> 16) | ||
88 | #define BCM2835_PINCONF_UNPACK_ARG(_conf_) ((_conf_) & 0xffff) | ||
89 | |||
90 | struct bcm2835_gpio_irqdata { | ||
91 | struct bcm2835_pinctrl *pc; | ||
92 | int bank; | ||
93 | }; | ||
94 | |||
95 | struct bcm2835_pinctrl { | ||
96 | struct device *dev; | ||
97 | void __iomem *base; | ||
98 | int irq[BCM2835_NUM_BANKS]; | ||
99 | |||
100 | /* note: locking assumes each bank will have its own unsigned long */ | ||
101 | unsigned long enabled_irq_map[BCM2835_NUM_BANKS]; | ||
102 | unsigned int irq_type[BCM2835_NUM_GPIOS]; | ||
103 | |||
104 | struct pinctrl_dev *pctl_dev; | ||
105 | struct irq_domain *irq_domain; | ||
106 | struct gpio_chip gpio_chip; | ||
107 | struct pinctrl_gpio_range gpio_range; | ||
108 | |||
109 | struct bcm2835_gpio_irqdata irq_data[BCM2835_NUM_BANKS]; | ||
110 | spinlock_t irq_lock[BCM2835_NUM_BANKS]; | ||
111 | }; | ||
112 | |||
113 | static struct lock_class_key gpio_lock_class; | ||
114 | |||
115 | /* pins are just named GPIO0..GPIO53 */ | ||
116 | #define BCM2835_GPIO_PIN(a) PINCTRL_PIN(a, "gpio" #a) | ||
117 | struct pinctrl_pin_desc bcm2835_gpio_pins[] = { | ||
118 | BCM2835_GPIO_PIN(0), | ||
119 | BCM2835_GPIO_PIN(1), | ||
120 | BCM2835_GPIO_PIN(2), | ||
121 | BCM2835_GPIO_PIN(3), | ||
122 | BCM2835_GPIO_PIN(4), | ||
123 | BCM2835_GPIO_PIN(5), | ||
124 | BCM2835_GPIO_PIN(6), | ||
125 | BCM2835_GPIO_PIN(7), | ||
126 | BCM2835_GPIO_PIN(8), | ||
127 | BCM2835_GPIO_PIN(9), | ||
128 | BCM2835_GPIO_PIN(10), | ||
129 | BCM2835_GPIO_PIN(11), | ||
130 | BCM2835_GPIO_PIN(12), | ||
131 | BCM2835_GPIO_PIN(13), | ||
132 | BCM2835_GPIO_PIN(14), | ||
133 | BCM2835_GPIO_PIN(15), | ||
134 | BCM2835_GPIO_PIN(16), | ||
135 | BCM2835_GPIO_PIN(17), | ||
136 | BCM2835_GPIO_PIN(18), | ||
137 | BCM2835_GPIO_PIN(19), | ||
138 | BCM2835_GPIO_PIN(20), | ||
139 | BCM2835_GPIO_PIN(21), | ||
140 | BCM2835_GPIO_PIN(22), | ||
141 | BCM2835_GPIO_PIN(23), | ||
142 | BCM2835_GPIO_PIN(24), | ||
143 | BCM2835_GPIO_PIN(25), | ||
144 | BCM2835_GPIO_PIN(26), | ||
145 | BCM2835_GPIO_PIN(27), | ||
146 | BCM2835_GPIO_PIN(28), | ||
147 | BCM2835_GPIO_PIN(29), | ||
148 | BCM2835_GPIO_PIN(30), | ||
149 | BCM2835_GPIO_PIN(31), | ||
150 | BCM2835_GPIO_PIN(32), | ||
151 | BCM2835_GPIO_PIN(33), | ||
152 | BCM2835_GPIO_PIN(34), | ||
153 | BCM2835_GPIO_PIN(35), | ||
154 | BCM2835_GPIO_PIN(36), | ||
155 | BCM2835_GPIO_PIN(37), | ||
156 | BCM2835_GPIO_PIN(38), | ||
157 | BCM2835_GPIO_PIN(39), | ||
158 | BCM2835_GPIO_PIN(40), | ||
159 | BCM2835_GPIO_PIN(41), | ||
160 | BCM2835_GPIO_PIN(42), | ||
161 | BCM2835_GPIO_PIN(43), | ||
162 | BCM2835_GPIO_PIN(44), | ||
163 | BCM2835_GPIO_PIN(45), | ||
164 | BCM2835_GPIO_PIN(46), | ||
165 | BCM2835_GPIO_PIN(47), | ||
166 | BCM2835_GPIO_PIN(48), | ||
167 | BCM2835_GPIO_PIN(49), | ||
168 | BCM2835_GPIO_PIN(50), | ||
169 | BCM2835_GPIO_PIN(51), | ||
170 | BCM2835_GPIO_PIN(52), | ||
171 | BCM2835_GPIO_PIN(53), | ||
172 | }; | ||
173 | |||
174 | /* one pin per group */ | ||
175 | static const char * const bcm2835_gpio_groups[] = { | ||
176 | "gpio0", | ||
177 | "gpio1", | ||
178 | "gpio2", | ||
179 | "gpio3", | ||
180 | "gpio4", | ||
181 | "gpio5", | ||
182 | "gpio6", | ||
183 | "gpio7", | ||
184 | "gpio8", | ||
185 | "gpio9", | ||
186 | "gpio10", | ||
187 | "gpio11", | ||
188 | "gpio12", | ||
189 | "gpio13", | ||
190 | "gpio14", | ||
191 | "gpio15", | ||
192 | "gpio16", | ||
193 | "gpio17", | ||
194 | "gpio18", | ||
195 | "gpio19", | ||
196 | "gpio20", | ||
197 | "gpio21", | ||
198 | "gpio22", | ||
199 | "gpio23", | ||
200 | "gpio24", | ||
201 | "gpio25", | ||
202 | "gpio26", | ||
203 | "gpio27", | ||
204 | "gpio28", | ||
205 | "gpio29", | ||
206 | "gpio30", | ||
207 | "gpio31", | ||
208 | "gpio32", | ||
209 | "gpio33", | ||
210 | "gpio34", | ||
211 | "gpio35", | ||
212 | "gpio36", | ||
213 | "gpio37", | ||
214 | "gpio38", | ||
215 | "gpio39", | ||
216 | "gpio40", | ||
217 | "gpio41", | ||
218 | "gpio42", | ||
219 | "gpio43", | ||
220 | "gpio44", | ||
221 | "gpio45", | ||
222 | "gpio46", | ||
223 | "gpio47", | ||
224 | "gpio48", | ||
225 | "gpio49", | ||
226 | "gpio50", | ||
227 | "gpio51", | ||
228 | "gpio52", | ||
229 | "gpio53", | ||
230 | }; | ||
231 | |||
232 | enum bcm2835_fsel { | ||
233 | BCM2835_FSEL_GPIO_IN = 0, | ||
234 | BCM2835_FSEL_GPIO_OUT = 1, | ||
235 | BCM2835_FSEL_ALT0 = 4, | ||
236 | BCM2835_FSEL_ALT1 = 5, | ||
237 | BCM2835_FSEL_ALT2 = 6, | ||
238 | BCM2835_FSEL_ALT3 = 7, | ||
239 | BCM2835_FSEL_ALT4 = 3, | ||
240 | BCM2835_FSEL_ALT5 = 2, | ||
241 | BCM2835_FSEL_COUNT = 8, | ||
242 | BCM2835_FSEL_MASK = 0x7, | ||
243 | }; | ||
244 | |||
245 | static const char * const bcm2835_functions[BCM2835_FSEL_COUNT] = { | ||
246 | [BCM2835_FSEL_GPIO_IN] = "gpio_in", | ||
247 | [BCM2835_FSEL_GPIO_OUT] = "gpio_out", | ||
248 | [BCM2835_FSEL_ALT0] = "alt0", | ||
249 | [BCM2835_FSEL_ALT1] = "alt1", | ||
250 | [BCM2835_FSEL_ALT2] = "alt2", | ||
251 | [BCM2835_FSEL_ALT3] = "alt3", | ||
252 | [BCM2835_FSEL_ALT4] = "alt4", | ||
253 | [BCM2835_FSEL_ALT5] = "alt5", | ||
254 | }; | ||
255 | |||
256 | static const char * const irq_type_names[] = { | ||
257 | [IRQ_TYPE_NONE] = "none", | ||
258 | [IRQ_TYPE_EDGE_RISING] = "edge-rising", | ||
259 | [IRQ_TYPE_EDGE_FALLING] = "edge-falling", | ||
260 | [IRQ_TYPE_EDGE_BOTH] = "edge-both", | ||
261 | [IRQ_TYPE_LEVEL_HIGH] = "level-high", | ||
262 | [IRQ_TYPE_LEVEL_LOW] = "level-low", | ||
263 | }; | ||
264 | |||
265 | static inline u32 bcm2835_gpio_rd(struct bcm2835_pinctrl *pc, unsigned reg) | ||
266 | { | ||
267 | return readl(pc->base + reg); | ||
268 | } | ||
269 | |||
270 | static inline void bcm2835_gpio_wr(struct bcm2835_pinctrl *pc, unsigned reg, | ||
271 | u32 val) | ||
272 | { | ||
273 | writel(val, pc->base + reg); | ||
274 | } | ||
275 | |||
276 | static inline int bcm2835_gpio_get_bit(struct bcm2835_pinctrl *pc, unsigned reg, | ||
277 | unsigned bit) | ||
278 | { | ||
279 | reg += GPIO_REG_OFFSET(bit) * 4; | ||
280 | return (bcm2835_gpio_rd(pc, reg) >> GPIO_REG_SHIFT(bit)) & 1; | ||
281 | } | ||
282 | |||
283 | /* note NOT a read/modify/write cycle */ | ||
284 | static inline void bcm2835_gpio_set_bit(struct bcm2835_pinctrl *pc, | ||
285 | unsigned reg, unsigned bit) | ||
286 | { | ||
287 | reg += GPIO_REG_OFFSET(bit) * 4; | ||
288 | bcm2835_gpio_wr(pc, reg, BIT(GPIO_REG_SHIFT(bit))); | ||
289 | } | ||
290 | |||
291 | static inline enum bcm2835_fsel bcm2835_pinctrl_fsel_get( | ||
292 | struct bcm2835_pinctrl *pc, unsigned pin) | ||
293 | { | ||
294 | u32 val = bcm2835_gpio_rd(pc, FSEL_REG(pin)); | ||
295 | enum bcm2835_fsel status = (val >> FSEL_SHIFT(pin)) & BCM2835_FSEL_MASK; | ||
296 | |||
297 | dev_dbg(pc->dev, "get %08x (%u => %s)\n", val, pin, | ||
298 | bcm2835_functions[status]); | ||
299 | |||
300 | return status; | ||
301 | } | ||
302 | |||
303 | static inline void bcm2835_pinctrl_fsel_set( | ||
304 | struct bcm2835_pinctrl *pc, unsigned pin, | ||
305 | enum bcm2835_fsel fsel) | ||
306 | { | ||
307 | u32 val = bcm2835_gpio_rd(pc, FSEL_REG(pin)); | ||
308 | enum bcm2835_fsel cur = (val >> FSEL_SHIFT(pin)) & BCM2835_FSEL_MASK; | ||
309 | |||
310 | dev_dbg(pc->dev, "read %08x (%u => %s)\n", val, pin, | ||
311 | bcm2835_functions[cur]); | ||
312 | |||
313 | if (cur == fsel) | ||
314 | return; | ||
315 | |||
316 | if (cur != BCM2835_FSEL_GPIO_IN && fsel != BCM2835_FSEL_GPIO_IN) { | ||
317 | /* always transition through GPIO_IN */ | ||
318 | val &= ~(BCM2835_FSEL_MASK << FSEL_SHIFT(pin)); | ||
319 | val |= BCM2835_FSEL_GPIO_IN << FSEL_SHIFT(pin); | ||
320 | |||
321 | dev_dbg(pc->dev, "trans %08x (%u <= %s)\n", val, pin, | ||
322 | bcm2835_functions[BCM2835_FSEL_GPIO_IN]); | ||
323 | bcm2835_gpio_wr(pc, FSEL_REG(pin), val); | ||
324 | } | ||
325 | |||
326 | val &= ~(BCM2835_FSEL_MASK << FSEL_SHIFT(pin)); | ||
327 | val |= fsel << FSEL_SHIFT(pin); | ||
328 | |||
329 | dev_dbg(pc->dev, "write %08x (%u <= %s)\n", val, pin, | ||
330 | bcm2835_functions[fsel]); | ||
331 | bcm2835_gpio_wr(pc, FSEL_REG(pin), val); | ||
332 | } | ||
333 | |||
334 | static int bcm2835_gpio_request(struct gpio_chip *chip, unsigned offset) | ||
335 | { | ||
336 | return pinctrl_request_gpio(chip->base + offset); | ||
337 | } | ||
338 | |||
339 | static void bcm2835_gpio_free(struct gpio_chip *chip, unsigned offset) | ||
340 | { | ||
341 | pinctrl_free_gpio(chip->base + offset); | ||
342 | } | ||
343 | |||
344 | static int bcm2835_gpio_direction_input(struct gpio_chip *chip, unsigned offset) | ||
345 | { | ||
346 | return pinctrl_gpio_direction_input(chip->base + offset); | ||
347 | } | ||
348 | |||
349 | static int bcm2835_gpio_get(struct gpio_chip *chip, unsigned offset) | ||
350 | { | ||
351 | struct bcm2835_pinctrl *pc = dev_get_drvdata(chip->dev); | ||
352 | |||
353 | return bcm2835_gpio_get_bit(pc, GPLEV0, offset); | ||
354 | } | ||
355 | |||
356 | static int bcm2835_gpio_direction_output(struct gpio_chip *chip, | ||
357 | unsigned offset, int value) | ||
358 | { | ||
359 | return pinctrl_gpio_direction_output(chip->base + offset); | ||
360 | } | ||
361 | |||
362 | static void bcm2835_gpio_set(struct gpio_chip *chip, unsigned offset, int value) | ||
363 | { | ||
364 | struct bcm2835_pinctrl *pc = dev_get_drvdata(chip->dev); | ||
365 | |||
366 | bcm2835_gpio_set_bit(pc, value ? GPSET0 : GPCLR0, offset); | ||
367 | } | ||
368 | |||
369 | static int bcm2835_gpio_to_irq(struct gpio_chip *chip, unsigned offset) | ||
370 | { | ||
371 | struct bcm2835_pinctrl *pc = dev_get_drvdata(chip->dev); | ||
372 | |||
373 | return irq_linear_revmap(pc->irq_domain, offset); | ||
374 | } | ||
375 | |||
376 | static struct gpio_chip bcm2835_gpio_chip __devinitconst = { | ||
377 | .label = MODULE_NAME, | ||
378 | .owner = THIS_MODULE, | ||
379 | .request = bcm2835_gpio_request, | ||
380 | .free = bcm2835_gpio_free, | ||
381 | .direction_input = bcm2835_gpio_direction_input, | ||
382 | .direction_output = bcm2835_gpio_direction_output, | ||
383 | .get = bcm2835_gpio_get, | ||
384 | .set = bcm2835_gpio_set, | ||
385 | .to_irq = bcm2835_gpio_to_irq, | ||
386 | .base = -1, | ||
387 | .ngpio = BCM2835_NUM_GPIOS, | ||
388 | .can_sleep = 0, | ||
389 | }; | ||
390 | |||
391 | static irqreturn_t bcm2835_gpio_irq_handler(int irq, void *dev_id) | ||
392 | { | ||
393 | struct bcm2835_gpio_irqdata *irqdata = dev_id; | ||
394 | struct bcm2835_pinctrl *pc = irqdata->pc; | ||
395 | int bank = irqdata->bank; | ||
396 | unsigned long events; | ||
397 | unsigned offset; | ||
398 | unsigned gpio; | ||
399 | unsigned int type; | ||
400 | |||
401 | events = bcm2835_gpio_rd(pc, GPEDS0 + bank * 4); | ||
402 | events &= pc->enabled_irq_map[bank]; | ||
403 | for_each_set_bit(offset, &events, 32) { | ||
404 | gpio = (32 * bank) + offset; | ||
405 | type = pc->irq_type[gpio]; | ||
406 | |||
407 | /* ack edge triggered IRQs immediately */ | ||
408 | if (!(type & IRQ_TYPE_LEVEL_MASK)) | ||
409 | bcm2835_gpio_set_bit(pc, GPEDS0, gpio); | ||
410 | |||
411 | generic_handle_irq(irq_linear_revmap(pc->irq_domain, gpio)); | ||
412 | |||
413 | /* ack level triggered IRQ after handling them */ | ||
414 | if (type & IRQ_TYPE_LEVEL_MASK) | ||
415 | bcm2835_gpio_set_bit(pc, GPEDS0, gpio); | ||
416 | } | ||
417 | return events ? IRQ_HANDLED : IRQ_NONE; | ||
418 | } | ||
419 | |||
420 | static inline void __bcm2835_gpio_irq_config(struct bcm2835_pinctrl *pc, | ||
421 | unsigned reg, unsigned offset, bool enable) | ||
422 | { | ||
423 | u32 value; | ||
424 | reg += GPIO_REG_OFFSET(offset) * 4; | ||
425 | value = bcm2835_gpio_rd(pc, reg); | ||
426 | if (enable) | ||
427 | value |= BIT(GPIO_REG_SHIFT(offset)); | ||
428 | else | ||
429 | value &= ~(BIT(GPIO_REG_SHIFT(offset))); | ||
430 | bcm2835_gpio_wr(pc, reg, value); | ||
431 | } | ||
432 | |||
433 | /* fast path for IRQ handler */ | ||
434 | static void bcm2835_gpio_irq_config(struct bcm2835_pinctrl *pc, | ||
435 | unsigned offset, bool enable) | ||
436 | { | ||
437 | switch (pc->irq_type[offset]) { | ||
438 | case IRQ_TYPE_EDGE_RISING: | ||
439 | __bcm2835_gpio_irq_config(pc, GPREN0, offset, enable); | ||
440 | break; | ||
441 | |||
442 | case IRQ_TYPE_EDGE_FALLING: | ||
443 | __bcm2835_gpio_irq_config(pc, GPFEN0, offset, enable); | ||
444 | break; | ||
445 | |||
446 | case IRQ_TYPE_EDGE_BOTH: | ||
447 | __bcm2835_gpio_irq_config(pc, GPREN0, offset, enable); | ||
448 | __bcm2835_gpio_irq_config(pc, GPFEN0, offset, enable); | ||
449 | break; | ||
450 | |||
451 | case IRQ_TYPE_LEVEL_HIGH: | ||
452 | __bcm2835_gpio_irq_config(pc, GPHEN0, offset, enable); | ||
453 | break; | ||
454 | |||
455 | case IRQ_TYPE_LEVEL_LOW: | ||
456 | __bcm2835_gpio_irq_config(pc, GPLEN0, offset, enable); | ||
457 | break; | ||
458 | } | ||
459 | } | ||
460 | |||
461 | static void bcm2835_gpio_irq_enable(struct irq_data *data) | ||
462 | { | ||
463 | struct bcm2835_pinctrl *pc = irq_data_get_irq_chip_data(data); | ||
464 | unsigned gpio = irqd_to_hwirq(data); | ||
465 | unsigned offset = GPIO_REG_SHIFT(gpio); | ||
466 | unsigned bank = GPIO_REG_OFFSET(gpio); | ||
467 | unsigned long flags; | ||
468 | |||
469 | spin_lock_irqsave(&pc->irq_lock[bank], flags); | ||
470 | set_bit(offset, &pc->enabled_irq_map[bank]); | ||
471 | bcm2835_gpio_irq_config(pc, gpio, true); | ||
472 | spin_unlock_irqrestore(&pc->irq_lock[bank], flags); | ||
473 | } | ||
474 | |||
475 | static void bcm2835_gpio_irq_disable(struct irq_data *data) | ||
476 | { | ||
477 | struct bcm2835_pinctrl *pc = irq_data_get_irq_chip_data(data); | ||
478 | unsigned gpio = irqd_to_hwirq(data); | ||
479 | unsigned offset = GPIO_REG_SHIFT(gpio); | ||
480 | unsigned bank = GPIO_REG_OFFSET(gpio); | ||
481 | unsigned long flags; | ||
482 | |||
483 | spin_lock_irqsave(&pc->irq_lock[bank], flags); | ||
484 | bcm2835_gpio_irq_config(pc, gpio, false); | ||
485 | clear_bit(offset, &pc->enabled_irq_map[bank]); | ||
486 | spin_unlock_irqrestore(&pc->irq_lock[bank], flags); | ||
487 | } | ||
488 | |||
489 | static int __bcm2835_gpio_irq_set_type_disabled(struct bcm2835_pinctrl *pc, | ||
490 | unsigned offset, unsigned int type) | ||
491 | { | ||
492 | switch (type) { | ||
493 | case IRQ_TYPE_NONE: | ||
494 | case IRQ_TYPE_EDGE_RISING: | ||
495 | case IRQ_TYPE_EDGE_FALLING: | ||
496 | case IRQ_TYPE_EDGE_BOTH: | ||
497 | case IRQ_TYPE_LEVEL_HIGH: | ||
498 | case IRQ_TYPE_LEVEL_LOW: | ||
499 | pc->irq_type[offset] = type; | ||
500 | break; | ||
501 | |||
502 | default: | ||
503 | return -EINVAL; | ||
504 | } | ||
505 | return 0; | ||
506 | } | ||
507 | |||
508 | /* slower path for reconfiguring IRQ type */ | ||
509 | static int __bcm2835_gpio_irq_set_type_enabled(struct bcm2835_pinctrl *pc, | ||
510 | unsigned offset, unsigned int type) | ||
511 | { | ||
512 | switch (type) { | ||
513 | case IRQ_TYPE_NONE: | ||
514 | if (pc->irq_type[offset] != type) { | ||
515 | bcm2835_gpio_irq_config(pc, offset, false); | ||
516 | pc->irq_type[offset] = type; | ||
517 | } | ||
518 | break; | ||
519 | |||
520 | case IRQ_TYPE_EDGE_RISING: | ||
521 | if (pc->irq_type[offset] == IRQ_TYPE_EDGE_BOTH) { | ||
522 | /* RISING already enabled, disable FALLING */ | ||
523 | pc->irq_type[offset] = IRQ_TYPE_EDGE_FALLING; | ||
524 | bcm2835_gpio_irq_config(pc, offset, false); | ||
525 | pc->irq_type[offset] = type; | ||
526 | } else if (pc->irq_type[offset] != type) { | ||
527 | bcm2835_gpio_irq_config(pc, offset, false); | ||
528 | pc->irq_type[offset] = type; | ||
529 | bcm2835_gpio_irq_config(pc, offset, true); | ||
530 | } | ||
531 | break; | ||
532 | |||
533 | case IRQ_TYPE_EDGE_FALLING: | ||
534 | if (pc->irq_type[offset] == IRQ_TYPE_EDGE_BOTH) { | ||
535 | /* FALLING already enabled, disable RISING */ | ||
536 | pc->irq_type[offset] = IRQ_TYPE_EDGE_RISING; | ||
537 | bcm2835_gpio_irq_config(pc, offset, false); | ||
538 | pc->irq_type[offset] = type; | ||
539 | } else if (pc->irq_type[offset] != type) { | ||
540 | bcm2835_gpio_irq_config(pc, offset, false); | ||
541 | pc->irq_type[offset] = type; | ||
542 | bcm2835_gpio_irq_config(pc, offset, true); | ||
543 | } | ||
544 | break; | ||
545 | |||
546 | case IRQ_TYPE_EDGE_BOTH: | ||
547 | if (pc->irq_type[offset] == IRQ_TYPE_EDGE_RISING) { | ||
548 | /* RISING already enabled, enable FALLING too */ | ||
549 | pc->irq_type[offset] = IRQ_TYPE_EDGE_FALLING; | ||
550 | bcm2835_gpio_irq_config(pc, offset, true); | ||
551 | pc->irq_type[offset] = type; | ||
552 | } else if (pc->irq_type[offset] == IRQ_TYPE_EDGE_FALLING) { | ||
553 | /* FALLING already enabled, enable RISING too */ | ||
554 | pc->irq_type[offset] = IRQ_TYPE_EDGE_RISING; | ||
555 | bcm2835_gpio_irq_config(pc, offset, true); | ||
556 | pc->irq_type[offset] = type; | ||
557 | } else if (pc->irq_type[offset] != type) { | ||
558 | bcm2835_gpio_irq_config(pc, offset, false); | ||
559 | pc->irq_type[offset] = type; | ||
560 | bcm2835_gpio_irq_config(pc, offset, true); | ||
561 | } | ||
562 | break; | ||
563 | |||
564 | case IRQ_TYPE_LEVEL_HIGH: | ||
565 | case IRQ_TYPE_LEVEL_LOW: | ||
566 | if (pc->irq_type[offset] != type) { | ||
567 | bcm2835_gpio_irq_config(pc, offset, false); | ||
568 | pc->irq_type[offset] = type; | ||
569 | bcm2835_gpio_irq_config(pc, offset, true); | ||
570 | } | ||
571 | break; | ||
572 | |||
573 | default: | ||
574 | return -EINVAL; | ||
575 | } | ||
576 | return 0; | ||
577 | } | ||
578 | |||
579 | static int bcm2835_gpio_irq_set_type(struct irq_data *data, unsigned int type) | ||
580 | { | ||
581 | struct bcm2835_pinctrl *pc = irq_data_get_irq_chip_data(data); | ||
582 | unsigned gpio = irqd_to_hwirq(data); | ||
583 | unsigned offset = GPIO_REG_SHIFT(gpio); | ||
584 | unsigned bank = GPIO_REG_OFFSET(gpio); | ||
585 | unsigned long flags; | ||
586 | int ret; | ||
587 | |||
588 | spin_lock_irqsave(&pc->irq_lock[bank], flags); | ||
589 | |||
590 | if (test_bit(offset, &pc->enabled_irq_map[bank])) | ||
591 | ret = __bcm2835_gpio_irq_set_type_enabled(pc, gpio, type); | ||
592 | else | ||
593 | ret = __bcm2835_gpio_irq_set_type_disabled(pc, gpio, type); | ||
594 | |||
595 | spin_unlock_irqrestore(&pc->irq_lock[bank], flags); | ||
596 | |||
597 | return ret; | ||
598 | } | ||
599 | |||
600 | static struct irq_chip bcm2835_gpio_irq_chip = { | ||
601 | .name = MODULE_NAME, | ||
602 | .irq_enable = bcm2835_gpio_irq_enable, | ||
603 | .irq_disable = bcm2835_gpio_irq_disable, | ||
604 | .irq_set_type = bcm2835_gpio_irq_set_type, | ||
605 | }; | ||
606 | |||
607 | static int bcm2835_pctl_get_groups_count(struct pinctrl_dev *pctldev) | ||
608 | { | ||
609 | return ARRAY_SIZE(bcm2835_gpio_groups); | ||
610 | } | ||
611 | |||
612 | static const char *bcm2835_pctl_get_group_name(struct pinctrl_dev *pctldev, | ||
613 | unsigned selector) | ||
614 | { | ||
615 | return bcm2835_gpio_groups[selector]; | ||
616 | } | ||
617 | |||
618 | static int bcm2835_pctl_get_group_pins(struct pinctrl_dev *pctldev, | ||
619 | unsigned selector, | ||
620 | const unsigned **pins, | ||
621 | unsigned *num_pins) | ||
622 | { | ||
623 | *pins = &bcm2835_gpio_pins[selector].number; | ||
624 | *num_pins = 1; | ||
625 | |||
626 | return 0; | ||
627 | } | ||
628 | |||
629 | static void bcm2835_pctl_pin_dbg_show(struct pinctrl_dev *pctldev, | ||
630 | struct seq_file *s, | ||
631 | unsigned offset) | ||
632 | { | ||
633 | struct bcm2835_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev); | ||
634 | enum bcm2835_fsel fsel = bcm2835_pinctrl_fsel_get(pc, offset); | ||
635 | const char *fname = bcm2835_functions[fsel]; | ||
636 | int value = bcm2835_gpio_get_bit(pc, GPLEV0, offset); | ||
637 | int irq = irq_find_mapping(pc->irq_domain, offset); | ||
638 | |||
639 | seq_printf(s, "function %s in %s; irq %d (%s)", | ||
640 | fname, value ? "hi" : "lo", | ||
641 | irq, irq_type_names[pc->irq_type[offset]]); | ||
642 | } | ||
643 | |||
644 | static void bcm2835_pctl_dt_free_map(struct pinctrl_dev *pctldev, | ||
645 | struct pinctrl_map *maps, unsigned num_maps) | ||
646 | { | ||
647 | int i; | ||
648 | |||
649 | for (i = 0; i < num_maps; i++) | ||
650 | if (maps[i].type == PIN_MAP_TYPE_CONFIGS_PIN) | ||
651 | kfree(maps[i].data.configs.configs); | ||
652 | |||
653 | kfree(maps); | ||
654 | } | ||
655 | |||
656 | static int bcm2835_pctl_dt_node_to_map_func(struct bcm2835_pinctrl *pc, | ||
657 | struct device_node *np, u32 pin, u32 fnum, | ||
658 | struct pinctrl_map **maps) | ||
659 | { | ||
660 | struct pinctrl_map *map = *maps; | ||
661 | |||
662 | if (fnum >= ARRAY_SIZE(bcm2835_functions)) { | ||
663 | dev_err(pc->dev, "%s: invalid brcm,function %d\n", | ||
664 | of_node_full_name(np), fnum); | ||
665 | return -EINVAL; | ||
666 | } | ||
667 | |||
668 | map->type = PIN_MAP_TYPE_MUX_GROUP; | ||
669 | map->data.mux.group = bcm2835_gpio_groups[pin]; | ||
670 | map->data.mux.function = bcm2835_functions[fnum]; | ||
671 | (*maps)++; | ||
672 | |||
673 | return 0; | ||
674 | } | ||
675 | |||
676 | static int bcm2835_pctl_dt_node_to_map_pull(struct bcm2835_pinctrl *pc, | ||
677 | struct device_node *np, u32 pin, u32 pull, | ||
678 | struct pinctrl_map **maps) | ||
679 | { | ||
680 | struct pinctrl_map *map = *maps; | ||
681 | unsigned long *configs; | ||
682 | |||
683 | if (pull > 2) { | ||
684 | dev_err(pc->dev, "%s: invalid brcm,pull %d\n", | ||
685 | of_node_full_name(np), pull); | ||
686 | return -EINVAL; | ||
687 | } | ||
688 | |||
689 | configs = kzalloc(sizeof(*configs), GFP_KERNEL); | ||
690 | if (!configs) | ||
691 | return -ENOMEM; | ||
692 | configs[0] = BCM2835_PINCONF_PACK(BCM2835_PINCONF_PARAM_PULL, pull); | ||
693 | |||
694 | map->type = PIN_MAP_TYPE_CONFIGS_PIN; | ||
695 | map->data.configs.group_or_pin = bcm2835_gpio_pins[pin].name; | ||
696 | map->data.configs.configs = configs; | ||
697 | map->data.configs.num_configs = 1; | ||
698 | (*maps)++; | ||
699 | |||
700 | return 0; | ||
701 | } | ||
702 | |||
703 | static inline u32 prop_u32(struct property *p, int i) | ||
704 | { | ||
705 | return be32_to_cpup(((__be32 *)p->value) + i); | ||
706 | } | ||
707 | |||
708 | static int bcm2835_pctl_dt_node_to_map(struct pinctrl_dev *pctldev, | ||
709 | struct device_node *np, | ||
710 | struct pinctrl_map **map, unsigned *num_maps) | ||
711 | { | ||
712 | struct bcm2835_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev); | ||
713 | struct property *pins, *funcs, *pulls; | ||
714 | int num_pins, num_funcs, num_pulls, maps_per_pin; | ||
715 | struct pinctrl_map *maps, *cur_map; | ||
716 | int i, err; | ||
717 | u32 pin, func, pull; | ||
718 | |||
719 | pins = of_find_property(np, "brcm,pins", NULL); | ||
720 | if (!pins) { | ||
721 | dev_err(pc->dev, "%s: missing brcm,pins property\n", | ||
722 | of_node_full_name(np)); | ||
723 | return -EINVAL; | ||
724 | } | ||
725 | |||
726 | funcs = of_find_property(np, "brcm,function", NULL); | ||
727 | pulls = of_find_property(np, "brcm,pull", NULL); | ||
728 | |||
729 | if (!funcs && !pulls) { | ||
730 | dev_err(pc->dev, | ||
731 | "%s: neither brcm,function nor brcm,pull specified\n", | ||
732 | of_node_full_name(np)); | ||
733 | return -EINVAL; | ||
734 | } | ||
735 | |||
736 | num_pins = pins->length / 4; | ||
737 | num_funcs = funcs ? (funcs->length / 4) : 0; | ||
738 | num_pulls = pulls ? (pulls->length / 4) : 0; | ||
739 | |||
740 | if (num_funcs > 1 && num_funcs != num_pins) { | ||
741 | dev_err(pc->dev, | ||
742 | "%s: brcm,function must have 1 or %d entries\n", | ||
743 | of_node_full_name(np), num_pins); | ||
744 | return -EINVAL; | ||
745 | } | ||
746 | |||
747 | if (num_pulls > 1 && num_pulls != num_pins) { | ||
748 | dev_err(pc->dev, | ||
749 | "%s: brcm,pull must have 1 or %d entries\n", | ||
750 | of_node_full_name(np), num_pins); | ||
751 | return -EINVAL; | ||
752 | } | ||
753 | |||
754 | maps_per_pin = 0; | ||
755 | if (num_funcs) | ||
756 | maps_per_pin++; | ||
757 | if (num_pulls) | ||
758 | maps_per_pin++; | ||
759 | cur_map = maps = kzalloc(num_pins * maps_per_pin * sizeof(*maps), | ||
760 | GFP_KERNEL); | ||
761 | if (!maps) | ||
762 | return -ENOMEM; | ||
763 | |||
764 | for (i = 0; i < num_pins; i++) { | ||
765 | pin = prop_u32(pins, i); | ||
766 | if (pin >= ARRAY_SIZE(bcm2835_gpio_pins)) { | ||
767 | dev_err(pc->dev, "%s: invalid brcm,pins value %d\n", | ||
768 | of_node_full_name(np), pin); | ||
769 | err = -EINVAL; | ||
770 | goto out; | ||
771 | } | ||
772 | |||
773 | if (num_funcs) { | ||
774 | func = prop_u32(funcs, (num_funcs > 1) ? i : 0); | ||
775 | err = bcm2835_pctl_dt_node_to_map_func(pc, np, pin, | ||
776 | func, &cur_map); | ||
777 | if (err) | ||
778 | goto out; | ||
779 | } | ||
780 | if (num_pulls) { | ||
781 | pull = prop_u32(pulls, (num_pulls > 1) ? i : 0); | ||
782 | err = bcm2835_pctl_dt_node_to_map_pull(pc, np, pin, | ||
783 | pull, &cur_map); | ||
784 | if (err) | ||
785 | goto out; | ||
786 | } | ||
787 | } | ||
788 | |||
789 | *map = maps; | ||
790 | *num_maps = num_pins * maps_per_pin; | ||
791 | |||
792 | return 0; | ||
793 | |||
794 | out: | ||
795 | kfree(maps); | ||
796 | return err; | ||
797 | } | ||
798 | |||
799 | static struct pinctrl_ops bcm2835_pctl_ops = { | ||
800 | .get_groups_count = bcm2835_pctl_get_groups_count, | ||
801 | .get_group_name = bcm2835_pctl_get_group_name, | ||
802 | .get_group_pins = bcm2835_pctl_get_group_pins, | ||
803 | .pin_dbg_show = bcm2835_pctl_pin_dbg_show, | ||
804 | .dt_node_to_map = bcm2835_pctl_dt_node_to_map, | ||
805 | .dt_free_map = bcm2835_pctl_dt_free_map, | ||
806 | }; | ||
807 | |||
808 | static int bcm2835_pmx_get_functions_count(struct pinctrl_dev *pctldev) | ||
809 | { | ||
810 | return BCM2835_FSEL_COUNT; | ||
811 | } | ||
812 | |||
813 | static const char *bcm2835_pmx_get_function_name(struct pinctrl_dev *pctldev, | ||
814 | unsigned selector) | ||
815 | { | ||
816 | return bcm2835_functions[selector]; | ||
817 | } | ||
818 | |||
819 | static int bcm2835_pmx_get_function_groups(struct pinctrl_dev *pctldev, | ||
820 | unsigned selector, | ||
821 | const char * const **groups, | ||
822 | unsigned * const num_groups) | ||
823 | { | ||
824 | /* every pin can do every function */ | ||
825 | *groups = bcm2835_gpio_groups; | ||
826 | *num_groups = ARRAY_SIZE(bcm2835_gpio_groups); | ||
827 | |||
828 | return 0; | ||
829 | } | ||
830 | |||
831 | static int bcm2835_pmx_enable(struct pinctrl_dev *pctldev, | ||
832 | unsigned func_selector, | ||
833 | unsigned group_selector) | ||
834 | { | ||
835 | struct bcm2835_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev); | ||
836 | |||
837 | bcm2835_pinctrl_fsel_set(pc, group_selector, func_selector); | ||
838 | |||
839 | return 0; | ||
840 | } | ||
841 | |||
842 | static void bcm2835_pmx_disable(struct pinctrl_dev *pctldev, | ||
843 | unsigned func_selector, | ||
844 | unsigned group_selector) | ||
845 | { | ||
846 | struct bcm2835_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev); | ||
847 | |||
848 | /* disable by setting to GPIO_IN */ | ||
849 | bcm2835_pinctrl_fsel_set(pc, group_selector, BCM2835_FSEL_GPIO_IN); | ||
850 | } | ||
851 | |||
852 | static void bcm2835_pmx_gpio_disable_free(struct pinctrl_dev *pctldev, | ||
853 | struct pinctrl_gpio_range *range, | ||
854 | unsigned offset) | ||
855 | { | ||
856 | struct bcm2835_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev); | ||
857 | |||
858 | /* disable by setting to GPIO_IN */ | ||
859 | bcm2835_pinctrl_fsel_set(pc, offset, BCM2835_FSEL_GPIO_IN); | ||
860 | } | ||
861 | |||
862 | static int bcm2835_pmx_gpio_set_direction(struct pinctrl_dev *pctldev, | ||
863 | struct pinctrl_gpio_range *range, | ||
864 | unsigned offset, | ||
865 | bool input) | ||
866 | { | ||
867 | struct bcm2835_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev); | ||
868 | enum bcm2835_fsel fsel = input ? | ||
869 | BCM2835_FSEL_GPIO_IN : BCM2835_FSEL_GPIO_OUT; | ||
870 | |||
871 | bcm2835_pinctrl_fsel_set(pc, offset, fsel); | ||
872 | |||
873 | return 0; | ||
874 | } | ||
875 | |||
876 | static struct pinmux_ops bcm2835_pmx_ops = { | ||
877 | .get_functions_count = bcm2835_pmx_get_functions_count, | ||
878 | .get_function_name = bcm2835_pmx_get_function_name, | ||
879 | .get_function_groups = bcm2835_pmx_get_function_groups, | ||
880 | .enable = bcm2835_pmx_enable, | ||
881 | .disable = bcm2835_pmx_disable, | ||
882 | .gpio_disable_free = bcm2835_pmx_gpio_disable_free, | ||
883 | .gpio_set_direction = bcm2835_pmx_gpio_set_direction, | ||
884 | }; | ||
885 | |||
886 | static int bcm2835_pinconf_get(struct pinctrl_dev *pctldev, | ||
887 | unsigned pin, unsigned long *config) | ||
888 | { | ||
889 | /* No way to read back config in HW */ | ||
890 | return -ENOTSUPP; | ||
891 | } | ||
892 | |||
893 | static int bcm2835_pinconf_set(struct pinctrl_dev *pctldev, | ||
894 | unsigned pin, unsigned long config) | ||
895 | { | ||
896 | struct bcm2835_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev); | ||
897 | enum bcm2835_pinconf_param param = BCM2835_PINCONF_UNPACK_PARAM(config); | ||
898 | u16 arg = BCM2835_PINCONF_UNPACK_ARG(config); | ||
899 | u32 off, bit; | ||
900 | |||
901 | if (param != BCM2835_PINCONF_PARAM_PULL) | ||
902 | return -EINVAL; | ||
903 | |||
904 | off = GPIO_REG_OFFSET(pin); | ||
905 | bit = GPIO_REG_SHIFT(pin); | ||
906 | |||
907 | bcm2835_gpio_wr(pc, GPPUD, arg & 3); | ||
908 | /* | ||
909 | * Docs say to wait 150 cycles, but not of what. We assume a | ||
910 | * 1 MHz clock here, which is pretty slow... | ||
911 | */ | ||
912 | udelay(150); | ||
913 | bcm2835_gpio_wr(pc, GPPUDCLK0 + (off * 4), BIT(bit)); | ||
914 | udelay(150); | ||
915 | bcm2835_gpio_wr(pc, GPPUDCLK0 + (off * 4), 0); | ||
916 | |||
917 | return 0; | ||
918 | } | ||
919 | |||
920 | struct pinconf_ops bcm2835_pinconf_ops = { | ||
921 | .pin_config_get = bcm2835_pinconf_get, | ||
922 | .pin_config_set = bcm2835_pinconf_set, | ||
923 | }; | ||
924 | |||
925 | static struct pinctrl_desc bcm2835_pinctrl_desc = { | ||
926 | .name = MODULE_NAME, | ||
927 | .pins = bcm2835_gpio_pins, | ||
928 | .npins = ARRAY_SIZE(bcm2835_gpio_pins), | ||
929 | .pctlops = &bcm2835_pctl_ops, | ||
930 | .pmxops = &bcm2835_pmx_ops, | ||
931 | .confops = &bcm2835_pinconf_ops, | ||
932 | .owner = THIS_MODULE, | ||
933 | }; | ||
934 | |||
935 | static struct pinctrl_gpio_range bcm2835_pinctrl_gpio_range __devinitconst = { | ||
936 | .name = MODULE_NAME, | ||
937 | .npins = BCM2835_NUM_GPIOS, | ||
938 | }; | ||
939 | |||
940 | static int __devinit bcm2835_pinctrl_probe(struct platform_device *pdev) | ||
941 | { | ||
942 | struct device *dev = &pdev->dev; | ||
943 | struct device_node *np = dev->of_node; | ||
944 | struct bcm2835_pinctrl *pc; | ||
945 | struct resource iomem; | ||
946 | int err, i; | ||
947 | BUILD_BUG_ON(ARRAY_SIZE(bcm2835_gpio_pins) != BCM2835_NUM_GPIOS); | ||
948 | BUILD_BUG_ON(ARRAY_SIZE(bcm2835_gpio_groups) != BCM2835_NUM_GPIOS); | ||
949 | |||
950 | pc = devm_kzalloc(dev, sizeof(*pc), GFP_KERNEL); | ||
951 | if (!pc) | ||
952 | return -ENOMEM; | ||
953 | |||
954 | platform_set_drvdata(pdev, pc); | ||
955 | pc->dev = dev; | ||
956 | |||
957 | err = of_address_to_resource(np, 0, &iomem); | ||
958 | if (err) { | ||
959 | dev_err(dev, "could not get IO memory\n"); | ||
960 | return err; | ||
961 | } | ||
962 | |||
963 | pc->base = devm_request_and_ioremap(&pdev->dev, &iomem); | ||
964 | if (!pc->base) | ||
965 | return -EADDRNOTAVAIL; | ||
966 | |||
967 | pc->gpio_chip = bcm2835_gpio_chip; | ||
968 | pc->gpio_chip.dev = dev; | ||
969 | pc->gpio_chip.of_node = np; | ||
970 | |||
971 | pc->irq_domain = irq_domain_add_linear(np, BCM2835_NUM_GPIOS, | ||
972 | &irq_domain_simple_ops, NULL); | ||
973 | if (!pc->irq_domain) { | ||
974 | dev_err(dev, "could not create IRQ domain\n"); | ||
975 | return -ENOMEM; | ||
976 | } | ||
977 | |||
978 | for (i = 0; i < BCM2835_NUM_GPIOS; i++) { | ||
979 | int irq = irq_create_mapping(pc->irq_domain, i); | ||
980 | irq_set_lockdep_class(irq, &gpio_lock_class); | ||
981 | irq_set_chip_and_handler(irq, &bcm2835_gpio_irq_chip, | ||
982 | handle_simple_irq); | ||
983 | irq_set_chip_data(irq, pc); | ||
984 | set_irq_flags(irq, IRQF_VALID); | ||
985 | } | ||
986 | |||
987 | for (i = 0; i < BCM2835_NUM_BANKS; i++) { | ||
988 | unsigned long events; | ||
989 | unsigned offset; | ||
990 | int len; | ||
991 | char *name; | ||
992 | |||
993 | /* clear event detection flags */ | ||
994 | bcm2835_gpio_wr(pc, GPREN0 + i * 4, 0); | ||
995 | bcm2835_gpio_wr(pc, GPFEN0 + i * 4, 0); | ||
996 | bcm2835_gpio_wr(pc, GPHEN0 + i * 4, 0); | ||
997 | bcm2835_gpio_wr(pc, GPLEN0 + i * 4, 0); | ||
998 | bcm2835_gpio_wr(pc, GPAREN0 + i * 4, 0); | ||
999 | bcm2835_gpio_wr(pc, GPAFEN0 + i * 4, 0); | ||
1000 | |||
1001 | /* clear all the events */ | ||
1002 | events = bcm2835_gpio_rd(pc, GPEDS0 + i * 4); | ||
1003 | for_each_set_bit(offset, &events, 32) | ||
1004 | bcm2835_gpio_wr(pc, GPEDS0 + i * 4, BIT(offset)); | ||
1005 | |||
1006 | pc->irq[i] = irq_of_parse_and_map(np, i); | ||
1007 | pc->irq_data[i].pc = pc; | ||
1008 | pc->irq_data[i].bank = i; | ||
1009 | spin_lock_init(&pc->irq_lock[i]); | ||
1010 | |||
1011 | len = strlen(dev_name(pc->dev)) + 16; | ||
1012 | name = devm_kzalloc(pc->dev, len, GFP_KERNEL); | ||
1013 | if (!name) | ||
1014 | return -ENOMEM; | ||
1015 | snprintf(name, len, "%s:bank%d", dev_name(pc->dev), i); | ||
1016 | |||
1017 | err = devm_request_irq(dev, pc->irq[i], | ||
1018 | bcm2835_gpio_irq_handler, IRQF_SHARED, | ||
1019 | name, &pc->irq_data[i]); | ||
1020 | if (err) { | ||
1021 | dev_err(dev, "unable to request IRQ %d\n", pc->irq[i]); | ||
1022 | return err; | ||
1023 | } | ||
1024 | } | ||
1025 | |||
1026 | err = gpiochip_add(&pc->gpio_chip); | ||
1027 | if (err) { | ||
1028 | dev_err(dev, "could not add GPIO chip\n"); | ||
1029 | return err; | ||
1030 | } | ||
1031 | |||
1032 | pc->pctl_dev = pinctrl_register(&bcm2835_pinctrl_desc, dev, pc); | ||
1033 | if (!pc->pctl_dev) { | ||
1034 | gpiochip_remove(&pc->gpio_chip); | ||
1035 | return PTR_ERR(pc->pctl_dev); | ||
1036 | } | ||
1037 | |||
1038 | pc->gpio_range = bcm2835_pinctrl_gpio_range; | ||
1039 | pc->gpio_range.base = pc->gpio_chip.base; | ||
1040 | pc->gpio_range.gc = &pc->gpio_chip; | ||
1041 | pinctrl_add_gpio_range(pc->pctl_dev, &pc->gpio_range); | ||
1042 | |||
1043 | return 0; | ||
1044 | } | ||
1045 | |||
1046 | static int __devexit bcm2835_pinctrl_remove(struct platform_device *pdev) | ||
1047 | { | ||
1048 | struct bcm2835_pinctrl *pc = platform_get_drvdata(pdev); | ||
1049 | |||
1050 | pinctrl_unregister(pc->pctl_dev); | ||
1051 | gpiochip_remove(&pc->gpio_chip); | ||
1052 | |||
1053 | return 0; | ||
1054 | } | ||
1055 | |||
1056 | static struct of_device_id bcm2835_pinctrl_match[] __devinitconst = { | ||
1057 | { .compatible = "brcm,bcm2835-gpio" }, | ||
1058 | {} | ||
1059 | }; | ||
1060 | MODULE_DEVICE_TABLE(of, bcm2835_pinctrl_match); | ||
1061 | |||
1062 | static struct platform_driver bcm2835_pinctrl_driver = { | ||
1063 | .probe = bcm2835_pinctrl_probe, | ||
1064 | .remove = bcm2835_pinctrl_remove, | ||
1065 | .driver = { | ||
1066 | .name = MODULE_NAME, | ||
1067 | .owner = THIS_MODULE, | ||
1068 | .of_match_table = bcm2835_pinctrl_match, | ||
1069 | }, | ||
1070 | }; | ||
1071 | module_platform_driver(bcm2835_pinctrl_driver); | ||
1072 | |||
1073 | MODULE_AUTHOR("Chris Boot, Simon Arlott, Stephen Warren"); | ||
1074 | MODULE_DESCRIPTION("BCM2835 Pin control driver"); | ||
1075 | MODULE_LICENSE("GPL"); | ||