]>
Commit | Line | Data |
---|---|---|
1 | /* | |
2 | * Generic driver for memory-mapped GPIO controllers. | |
3 | * | |
4 | * Copyright 2008 MontaVista Software, Inc. | |
5 | * Copyright 2008,2010 Anton Vorontsov <cbouatmailru@gmail.com> | |
6 | * | |
7 | * This program is free software; you can redistribute it and/or modify it | |
8 | * under the terms of the GNU General Public License as published by the | |
9 | * Free Software Foundation; either version 2 of the License, or (at your | |
10 | * option) any later version. | |
11 | * | |
12 | * ....``.```~~~~````.`.`.`.`.```````'',,,.........`````......`....... | |
13 | * ...`` ```````.. | |
14 | * ..The simplest form of a GPIO controller that the driver supports is`` | |
15 | * `.just a single "data" register, where GPIO state can be read and/or ` | |
16 | * `,..written. ,,..``~~~~ .....``.`.`.~~.```.`.........``````.``````` | |
17 | * ````````` | |
18 | ___ | |
19 | _/~~|___/~| . ```~~~~~~ ___/___\___ ,~.`.`.`.`````.~~...,,,,... | |
20 | __________|~$@~~~ %~ /o*o*o*o*o*o\ .. Implementing such a GPIO . | |
21 | o ` ~~~~\___/~~~~ ` controller in FPGA is ,.` | |
22 | `....trivial..'~`.```.``` | |
23 | * ``````` | |
24 | * .```````~~~~`..`.``.``. | |
25 | * . The driver supports `... ,..```.`~~~```````````````....````.``,, | |
26 | * . big-endian notation, just`. .. A bit more sophisticated controllers , | |
27 | * . register the device with -be`. .with a pair of set/clear-bit registers , | |
28 | * `.. suffix. ```~~`````....`.` . affecting the data register and the .` | |
29 | * ``.`.``...``` ```.. output pins are also supported.` | |
30 | * ^^ `````.`````````.,``~``~``~~`````` | |
31 | * . ^^ | |
32 | * ,..`.`.`...````````````......`.`.`.`.`.`..`.`.`.. | |
33 | * .. The expectation is that in at least some cases . ,-~~~-, | |
34 | * .this will be used with roll-your-own ASIC/FPGA .` \ / | |
35 | * .logic in Verilog or VHDL. ~~~`````````..`````~~` \ / | |
36 | * ..````````......``````````` \o_ | |
37 | * | | |
38 | * ^^ / \ | |
39 | * | |
40 | * ...`````~~`.....``.`..........``````.`.``.```........``. | |
41 | * ` 8, 16, 32 and 64 bits registers are supported, and``. | |
42 | * . the number of GPIOs is determined by the width of ~ | |
43 | * .. the registers. ,............```.`.`..`.`.~~~.`.`.`~ | |
44 | * `.......````.``` | |
45 | */ | |
46 | ||
47 | #include <linux/init.h> | |
48 | #include <linux/err.h> | |
49 | #include <linux/bug.h> | |
50 | #include <linux/kernel.h> | |
51 | #include <linux/module.h> | |
52 | #include <linux/spinlock.h> | |
53 | #include <linux/compiler.h> | |
54 | #include <linux/types.h> | |
55 | #include <linux/errno.h> | |
56 | #include <linux/log2.h> | |
57 | #include <linux/ioport.h> | |
58 | #include <linux/io.h> | |
59 | #include <linux/gpio/driver.h> | |
60 | #include <linux/slab.h> | |
61 | #include <linux/bitops.h> | |
62 | #include <linux/platform_device.h> | |
63 | #include <linux/mod_devicetable.h> | |
64 | #include <linux/of.h> | |
65 | #include <linux/of_device.h> | |
66 | ||
67 | static void bgpio_write8(void __iomem *reg, unsigned long data) | |
68 | { | |
69 | writeb(data, reg); | |
70 | } | |
71 | ||
72 | static unsigned long bgpio_read8(void __iomem *reg) | |
73 | { | |
74 | return readb(reg); | |
75 | } | |
76 | ||
77 | static void bgpio_write16(void __iomem *reg, unsigned long data) | |
78 | { | |
79 | writew(data, reg); | |
80 | } | |
81 | ||
82 | static unsigned long bgpio_read16(void __iomem *reg) | |
83 | { | |
84 | return readw(reg); | |
85 | } | |
86 | ||
87 | static void bgpio_write32(void __iomem *reg, unsigned long data) | |
88 | { | |
89 | writel(data, reg); | |
90 | } | |
91 | ||
92 | static unsigned long bgpio_read32(void __iomem *reg) | |
93 | { | |
94 | return readl(reg); | |
95 | } | |
96 | ||
97 | #if BITS_PER_LONG >= 64 | |
98 | static void bgpio_write64(void __iomem *reg, unsigned long data) | |
99 | { | |
100 | writeq(data, reg); | |
101 | } | |
102 | ||
103 | static unsigned long bgpio_read64(void __iomem *reg) | |
104 | { | |
105 | return readq(reg); | |
106 | } | |
107 | #endif /* BITS_PER_LONG >= 64 */ | |
108 | ||
109 | static void bgpio_write16be(void __iomem *reg, unsigned long data) | |
110 | { | |
111 | iowrite16be(data, reg); | |
112 | } | |
113 | ||
114 | static unsigned long bgpio_read16be(void __iomem *reg) | |
115 | { | |
116 | return ioread16be(reg); | |
117 | } | |
118 | ||
119 | static void bgpio_write32be(void __iomem *reg, unsigned long data) | |
120 | { | |
121 | iowrite32be(data, reg); | |
122 | } | |
123 | ||
124 | static unsigned long bgpio_read32be(void __iomem *reg) | |
125 | { | |
126 | return ioread32be(reg); | |
127 | } | |
128 | ||
129 | static unsigned long bgpio_pin2mask(struct gpio_chip *gc, unsigned int pin) | |
130 | { | |
131 | return BIT(pin); | |
132 | } | |
133 | ||
134 | static unsigned long bgpio_pin2mask_be(struct gpio_chip *gc, | |
135 | unsigned int pin) | |
136 | { | |
137 | return BIT(gc->bgpio_bits - 1 - pin); | |
138 | } | |
139 | ||
140 | static int bgpio_get_set(struct gpio_chip *gc, unsigned int gpio) | |
141 | { | |
142 | unsigned long pinmask = gc->pin2mask(gc, gpio); | |
143 | ||
144 | if (gc->bgpio_dir & pinmask) | |
145 | return !!(gc->read_reg(gc->reg_set) & pinmask); | |
146 | else | |
147 | return !!(gc->read_reg(gc->reg_dat) & pinmask); | |
148 | } | |
149 | ||
150 | static int bgpio_get(struct gpio_chip *gc, unsigned int gpio) | |
151 | { | |
152 | return !!(gc->read_reg(gc->reg_dat) & gc->pin2mask(gc, gpio)); | |
153 | } | |
154 | ||
155 | static void bgpio_set_none(struct gpio_chip *gc, unsigned int gpio, int val) | |
156 | { | |
157 | } | |
158 | ||
159 | static void bgpio_set(struct gpio_chip *gc, unsigned int gpio, int val) | |
160 | { | |
161 | unsigned long mask = gc->pin2mask(gc, gpio); | |
162 | unsigned long flags; | |
163 | ||
164 | spin_lock_irqsave(&gc->bgpio_lock, flags); | |
165 | ||
166 | if (val) | |
167 | gc->bgpio_data |= mask; | |
168 | else | |
169 | gc->bgpio_data &= ~mask; | |
170 | ||
171 | gc->write_reg(gc->reg_dat, gc->bgpio_data); | |
172 | ||
173 | spin_unlock_irqrestore(&gc->bgpio_lock, flags); | |
174 | } | |
175 | ||
176 | static void bgpio_set_with_clear(struct gpio_chip *gc, unsigned int gpio, | |
177 | int val) | |
178 | { | |
179 | unsigned long mask = gc->pin2mask(gc, gpio); | |
180 | ||
181 | if (val) | |
182 | gc->write_reg(gc->reg_set, mask); | |
183 | else | |
184 | gc->write_reg(gc->reg_clr, mask); | |
185 | } | |
186 | ||
187 | static void bgpio_set_set(struct gpio_chip *gc, unsigned int gpio, int val) | |
188 | { | |
189 | unsigned long mask = gc->pin2mask(gc, gpio); | |
190 | unsigned long flags; | |
191 | ||
192 | spin_lock_irqsave(&gc->bgpio_lock, flags); | |
193 | ||
194 | if (val) | |
195 | gc->bgpio_data |= mask; | |
196 | else | |
197 | gc->bgpio_data &= ~mask; | |
198 | ||
199 | gc->write_reg(gc->reg_set, gc->bgpio_data); | |
200 | ||
201 | spin_unlock_irqrestore(&gc->bgpio_lock, flags); | |
202 | } | |
203 | ||
204 | static void bgpio_multiple_get_masks(struct gpio_chip *gc, | |
205 | unsigned long *mask, unsigned long *bits, | |
206 | unsigned long *set_mask, | |
207 | unsigned long *clear_mask) | |
208 | { | |
209 | int i; | |
210 | ||
211 | *set_mask = 0; | |
212 | *clear_mask = 0; | |
213 | ||
214 | for (i = 0; i < gc->bgpio_bits; i++) { | |
215 | if (*mask == 0) | |
216 | break; | |
217 | if (__test_and_clear_bit(i, mask)) { | |
218 | if (test_bit(i, bits)) | |
219 | *set_mask |= gc->pin2mask(gc, i); | |
220 | else | |
221 | *clear_mask |= gc->pin2mask(gc, i); | |
222 | } | |
223 | } | |
224 | } | |
225 | ||
226 | static void bgpio_set_multiple_single_reg(struct gpio_chip *gc, | |
227 | unsigned long *mask, | |
228 | unsigned long *bits, | |
229 | void __iomem *reg) | |
230 | { | |
231 | unsigned long flags; | |
232 | unsigned long set_mask, clear_mask; | |
233 | ||
234 | spin_lock_irqsave(&gc->bgpio_lock, flags); | |
235 | ||
236 | bgpio_multiple_get_masks(gc, mask, bits, &set_mask, &clear_mask); | |
237 | ||
238 | gc->bgpio_data |= set_mask; | |
239 | gc->bgpio_data &= ~clear_mask; | |
240 | ||
241 | gc->write_reg(reg, gc->bgpio_data); | |
242 | ||
243 | spin_unlock_irqrestore(&gc->bgpio_lock, flags); | |
244 | } | |
245 | ||
246 | static void bgpio_set_multiple(struct gpio_chip *gc, unsigned long *mask, | |
247 | unsigned long *bits) | |
248 | { | |
249 | bgpio_set_multiple_single_reg(gc, mask, bits, gc->reg_dat); | |
250 | } | |
251 | ||
252 | static void bgpio_set_multiple_set(struct gpio_chip *gc, unsigned long *mask, | |
253 | unsigned long *bits) | |
254 | { | |
255 | bgpio_set_multiple_single_reg(gc, mask, bits, gc->reg_set); | |
256 | } | |
257 | ||
258 | static void bgpio_set_multiple_with_clear(struct gpio_chip *gc, | |
259 | unsigned long *mask, | |
260 | unsigned long *bits) | |
261 | { | |
262 | unsigned long set_mask, clear_mask; | |
263 | ||
264 | bgpio_multiple_get_masks(gc, mask, bits, &set_mask, &clear_mask); | |
265 | ||
266 | if (set_mask) | |
267 | gc->write_reg(gc->reg_set, set_mask); | |
268 | if (clear_mask) | |
269 | gc->write_reg(gc->reg_clr, clear_mask); | |
270 | } | |
271 | ||
272 | static int bgpio_simple_dir_in(struct gpio_chip *gc, unsigned int gpio) | |
273 | { | |
274 | return 0; | |
275 | } | |
276 | ||
277 | static int bgpio_dir_out_err(struct gpio_chip *gc, unsigned int gpio, | |
278 | int val) | |
279 | { | |
280 | return -EINVAL; | |
281 | } | |
282 | ||
283 | static int bgpio_simple_dir_out(struct gpio_chip *gc, unsigned int gpio, | |
284 | int val) | |
285 | { | |
286 | gc->set(gc, gpio, val); | |
287 | ||
288 | return 0; | |
289 | } | |
290 | ||
291 | static int bgpio_dir_in(struct gpio_chip *gc, unsigned int gpio) | |
292 | { | |
293 | unsigned long flags; | |
294 | ||
295 | spin_lock_irqsave(&gc->bgpio_lock, flags); | |
296 | ||
297 | gc->bgpio_dir &= ~gc->pin2mask(gc, gpio); | |
298 | gc->write_reg(gc->reg_dir, gc->bgpio_dir); | |
299 | ||
300 | spin_unlock_irqrestore(&gc->bgpio_lock, flags); | |
301 | ||
302 | return 0; | |
303 | } | |
304 | ||
305 | static int bgpio_get_dir(struct gpio_chip *gc, unsigned int gpio) | |
306 | { | |
307 | /* Return 0 if output, 1 of input */ | |
308 | return !(gc->read_reg(gc->reg_dir) & gc->pin2mask(gc, gpio)); | |
309 | } | |
310 | ||
311 | static int bgpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val) | |
312 | { | |
313 | unsigned long flags; | |
314 | ||
315 | gc->set(gc, gpio, val); | |
316 | ||
317 | spin_lock_irqsave(&gc->bgpio_lock, flags); | |
318 | ||
319 | gc->bgpio_dir |= gc->pin2mask(gc, gpio); | |
320 | gc->write_reg(gc->reg_dir, gc->bgpio_dir); | |
321 | ||
322 | spin_unlock_irqrestore(&gc->bgpio_lock, flags); | |
323 | ||
324 | return 0; | |
325 | } | |
326 | ||
327 | static int bgpio_dir_in_inv(struct gpio_chip *gc, unsigned int gpio) | |
328 | { | |
329 | unsigned long flags; | |
330 | ||
331 | spin_lock_irqsave(&gc->bgpio_lock, flags); | |
332 | ||
333 | gc->bgpio_dir |= gc->pin2mask(gc, gpio); | |
334 | gc->write_reg(gc->reg_dir, gc->bgpio_dir); | |
335 | ||
336 | spin_unlock_irqrestore(&gc->bgpio_lock, flags); | |
337 | ||
338 | return 0; | |
339 | } | |
340 | ||
341 | static int bgpio_dir_out_inv(struct gpio_chip *gc, unsigned int gpio, int val) | |
342 | { | |
343 | unsigned long flags; | |
344 | ||
345 | gc->set(gc, gpio, val); | |
346 | ||
347 | spin_lock_irqsave(&gc->bgpio_lock, flags); | |
348 | ||
349 | gc->bgpio_dir &= ~gc->pin2mask(gc, gpio); | |
350 | gc->write_reg(gc->reg_dir, gc->bgpio_dir); | |
351 | ||
352 | spin_unlock_irqrestore(&gc->bgpio_lock, flags); | |
353 | ||
354 | return 0; | |
355 | } | |
356 | ||
357 | static int bgpio_get_dir_inv(struct gpio_chip *gc, unsigned int gpio) | |
358 | { | |
359 | /* Return 0 if output, 1 if input */ | |
360 | return !!(gc->read_reg(gc->reg_dir) & gc->pin2mask(gc, gpio)); | |
361 | } | |
362 | ||
363 | static int bgpio_setup_accessors(struct device *dev, | |
364 | struct gpio_chip *gc, | |
365 | bool bit_be, | |
366 | bool byte_be) | |
367 | { | |
368 | ||
369 | switch (gc->bgpio_bits) { | |
370 | case 8: | |
371 | gc->read_reg = bgpio_read8; | |
372 | gc->write_reg = bgpio_write8; | |
373 | break; | |
374 | case 16: | |
375 | if (byte_be) { | |
376 | gc->read_reg = bgpio_read16be; | |
377 | gc->write_reg = bgpio_write16be; | |
378 | } else { | |
379 | gc->read_reg = bgpio_read16; | |
380 | gc->write_reg = bgpio_write16; | |
381 | } | |
382 | break; | |
383 | case 32: | |
384 | if (byte_be) { | |
385 | gc->read_reg = bgpio_read32be; | |
386 | gc->write_reg = bgpio_write32be; | |
387 | } else { | |
388 | gc->read_reg = bgpio_read32; | |
389 | gc->write_reg = bgpio_write32; | |
390 | } | |
391 | break; | |
392 | #if BITS_PER_LONG >= 64 | |
393 | case 64: | |
394 | if (byte_be) { | |
395 | dev_err(dev, | |
396 | "64 bit big endian byte order unsupported\n"); | |
397 | return -EINVAL; | |
398 | } else { | |
399 | gc->read_reg = bgpio_read64; | |
400 | gc->write_reg = bgpio_write64; | |
401 | } | |
402 | break; | |
403 | #endif /* BITS_PER_LONG >= 64 */ | |
404 | default: | |
405 | dev_err(dev, "unsupported data width %u bits\n", gc->bgpio_bits); | |
406 | return -EINVAL; | |
407 | } | |
408 | ||
409 | gc->pin2mask = bit_be ? bgpio_pin2mask_be : bgpio_pin2mask; | |
410 | ||
411 | return 0; | |
412 | } | |
413 | ||
414 | /* | |
415 | * Create the device and allocate the resources. For setting GPIO's there are | |
416 | * three supported configurations: | |
417 | * | |
418 | * - single input/output register resource (named "dat"). | |
419 | * - set/clear pair (named "set" and "clr"). | |
420 | * - single output register resource and single input resource ("set" and | |
421 | * dat"). | |
422 | * | |
423 | * For the single output register, this drives a 1 by setting a bit and a zero | |
424 | * by clearing a bit. For the set clr pair, this drives a 1 by setting a bit | |
425 | * in the set register and clears it by setting a bit in the clear register. | |
426 | * The configuration is detected by which resources are present. | |
427 | * | |
428 | * For setting the GPIO direction, there are three supported configurations: | |
429 | * | |
430 | * - simple bidirection GPIO that requires no configuration. | |
431 | * - an output direction register (named "dirout") where a 1 bit | |
432 | * indicates the GPIO is an output. | |
433 | * - an input direction register (named "dirin") where a 1 bit indicates | |
434 | * the GPIO is an input. | |
435 | */ | |
436 | static int bgpio_setup_io(struct gpio_chip *gc, | |
437 | void __iomem *dat, | |
438 | void __iomem *set, | |
439 | void __iomem *clr, | |
440 | unsigned long flags) | |
441 | { | |
442 | ||
443 | gc->reg_dat = dat; | |
444 | if (!gc->reg_dat) | |
445 | return -EINVAL; | |
446 | ||
447 | if (set && clr) { | |
448 | gc->reg_set = set; | |
449 | gc->reg_clr = clr; | |
450 | gc->set = bgpio_set_with_clear; | |
451 | gc->set_multiple = bgpio_set_multiple_with_clear; | |
452 | } else if (set && !clr) { | |
453 | gc->reg_set = set; | |
454 | gc->set = bgpio_set_set; | |
455 | gc->set_multiple = bgpio_set_multiple_set; | |
456 | } else if (flags & BGPIOF_NO_OUTPUT) { | |
457 | gc->set = bgpio_set_none; | |
458 | gc->set_multiple = NULL; | |
459 | } else { | |
460 | gc->set = bgpio_set; | |
461 | gc->set_multiple = bgpio_set_multiple; | |
462 | } | |
463 | ||
464 | if (!(flags & BGPIOF_UNREADABLE_REG_SET) && | |
465 | (flags & BGPIOF_READ_OUTPUT_REG_SET)) | |
466 | gc->get = bgpio_get_set; | |
467 | else | |
468 | gc->get = bgpio_get; | |
469 | ||
470 | return 0; | |
471 | } | |
472 | ||
473 | static int bgpio_setup_direction(struct gpio_chip *gc, | |
474 | void __iomem *dirout, | |
475 | void __iomem *dirin, | |
476 | unsigned long flags) | |
477 | { | |
478 | if (dirout && dirin) { | |
479 | return -EINVAL; | |
480 | } else if (dirout) { | |
481 | gc->reg_dir = dirout; | |
482 | gc->direction_output = bgpio_dir_out; | |
483 | gc->direction_input = bgpio_dir_in; | |
484 | gc->get_direction = bgpio_get_dir; | |
485 | } else if (dirin) { | |
486 | gc->reg_dir = dirin; | |
487 | gc->direction_output = bgpio_dir_out_inv; | |
488 | gc->direction_input = bgpio_dir_in_inv; | |
489 | gc->get_direction = bgpio_get_dir_inv; | |
490 | } else { | |
491 | if (flags & BGPIOF_NO_OUTPUT) | |
492 | gc->direction_output = bgpio_dir_out_err; | |
493 | else | |
494 | gc->direction_output = bgpio_simple_dir_out; | |
495 | gc->direction_input = bgpio_simple_dir_in; | |
496 | } | |
497 | ||
498 | return 0; | |
499 | } | |
500 | ||
501 | static int bgpio_request(struct gpio_chip *chip, unsigned gpio_pin) | |
502 | { | |
503 | if (gpio_pin < chip->ngpio) | |
504 | return 0; | |
505 | ||
506 | return -EINVAL; | |
507 | } | |
508 | ||
509 | int bgpio_init(struct gpio_chip *gc, struct device *dev, | |
510 | unsigned long sz, void __iomem *dat, void __iomem *set, | |
511 | void __iomem *clr, void __iomem *dirout, void __iomem *dirin, | |
512 | unsigned long flags) | |
513 | { | |
514 | int ret; | |
515 | ||
516 | if (!is_power_of_2(sz)) | |
517 | return -EINVAL; | |
518 | ||
519 | gc->bgpio_bits = sz * 8; | |
520 | if (gc->bgpio_bits > BITS_PER_LONG) | |
521 | return -EINVAL; | |
522 | ||
523 | spin_lock_init(&gc->bgpio_lock); | |
524 | gc->parent = dev; | |
525 | gc->label = dev_name(dev); | |
526 | gc->base = -1; | |
527 | gc->ngpio = gc->bgpio_bits; | |
528 | gc->request = bgpio_request; | |
529 | ||
530 | ret = bgpio_setup_io(gc, dat, set, clr, flags); | |
531 | if (ret) | |
532 | return ret; | |
533 | ||
534 | ret = bgpio_setup_accessors(dev, gc, flags & BGPIOF_BIG_ENDIAN, | |
535 | flags & BGPIOF_BIG_ENDIAN_BYTE_ORDER); | |
536 | if (ret) | |
537 | return ret; | |
538 | ||
539 | ret = bgpio_setup_direction(gc, dirout, dirin, flags); | |
540 | if (ret) | |
541 | return ret; | |
542 | ||
543 | gc->bgpio_data = gc->read_reg(gc->reg_dat); | |
544 | if (gc->set == bgpio_set_set && | |
545 | !(flags & BGPIOF_UNREADABLE_REG_SET)) | |
546 | gc->bgpio_data = gc->read_reg(gc->reg_set); | |
547 | if (gc->reg_dir && !(flags & BGPIOF_UNREADABLE_REG_DIR)) | |
548 | gc->bgpio_dir = gc->read_reg(gc->reg_dir); | |
549 | ||
550 | return ret; | |
551 | } | |
552 | EXPORT_SYMBOL_GPL(bgpio_init); | |
553 | ||
554 | #if IS_ENABLED(CONFIG_GPIO_GENERIC_PLATFORM) | |
555 | ||
556 | static void __iomem *bgpio_map(struct platform_device *pdev, | |
557 | const char *name, | |
558 | resource_size_t sane_sz) | |
559 | { | |
560 | struct resource *r; | |
561 | resource_size_t sz; | |
562 | ||
563 | r = platform_get_resource_byname(pdev, IORESOURCE_MEM, name); | |
564 | if (!r) | |
565 | return NULL; | |
566 | ||
567 | sz = resource_size(r); | |
568 | if (sz != sane_sz) | |
569 | return IOMEM_ERR_PTR(-EINVAL); | |
570 | ||
571 | return devm_ioremap_resource(&pdev->dev, r); | |
572 | } | |
573 | ||
574 | #ifdef CONFIG_OF | |
575 | static const struct of_device_id bgpio_of_match[] = { | |
576 | { .compatible = "brcm,bcm6345-gpio" }, | |
577 | { .compatible = "wd,mbl-gpio" }, | |
578 | { } | |
579 | }; | |
580 | MODULE_DEVICE_TABLE(of, bgpio_of_match); | |
581 | ||
582 | static struct bgpio_pdata *bgpio_parse_dt(struct platform_device *pdev, | |
583 | unsigned long *flags) | |
584 | { | |
585 | struct bgpio_pdata *pdata; | |
586 | ||
587 | if (!of_match_device(bgpio_of_match, &pdev->dev)) | |
588 | return NULL; | |
589 | ||
590 | pdata = devm_kzalloc(&pdev->dev, sizeof(struct bgpio_pdata), | |
591 | GFP_KERNEL); | |
592 | if (!pdata) | |
593 | return ERR_PTR(-ENOMEM); | |
594 | ||
595 | pdata->base = -1; | |
596 | ||
597 | if (of_device_is_big_endian(pdev->dev.of_node)) | |
598 | *flags |= BGPIOF_BIG_ENDIAN_BYTE_ORDER; | |
599 | ||
600 | if (of_property_read_bool(pdev->dev.of_node, "no-output")) | |
601 | *flags |= BGPIOF_NO_OUTPUT; | |
602 | ||
603 | return pdata; | |
604 | } | |
605 | #else | |
606 | static struct bgpio_pdata *bgpio_parse_dt(struct platform_device *pdev, | |
607 | unsigned long *flags) | |
608 | { | |
609 | return NULL; | |
610 | } | |
611 | #endif /* CONFIG_OF */ | |
612 | ||
613 | static int bgpio_pdev_probe(struct platform_device *pdev) | |
614 | { | |
615 | struct device *dev = &pdev->dev; | |
616 | struct resource *r; | |
617 | void __iomem *dat; | |
618 | void __iomem *set; | |
619 | void __iomem *clr; | |
620 | void __iomem *dirout; | |
621 | void __iomem *dirin; | |
622 | unsigned long sz; | |
623 | unsigned long flags = 0; | |
624 | int err; | |
625 | struct gpio_chip *gc; | |
626 | struct bgpio_pdata *pdata; | |
627 | ||
628 | pdata = bgpio_parse_dt(pdev, &flags); | |
629 | if (IS_ERR(pdata)) | |
630 | return PTR_ERR(pdata); | |
631 | ||
632 | if (!pdata) { | |
633 | pdata = dev_get_platdata(dev); | |
634 | flags = pdev->id_entry->driver_data; | |
635 | } | |
636 | ||
637 | r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dat"); | |
638 | if (!r) | |
639 | return -EINVAL; | |
640 | ||
641 | sz = resource_size(r); | |
642 | ||
643 | dat = bgpio_map(pdev, "dat", sz); | |
644 | if (IS_ERR(dat)) | |
645 | return PTR_ERR(dat); | |
646 | ||
647 | set = bgpio_map(pdev, "set", sz); | |
648 | if (IS_ERR(set)) | |
649 | return PTR_ERR(set); | |
650 | ||
651 | clr = bgpio_map(pdev, "clr", sz); | |
652 | if (IS_ERR(clr)) | |
653 | return PTR_ERR(clr); | |
654 | ||
655 | dirout = bgpio_map(pdev, "dirout", sz); | |
656 | if (IS_ERR(dirout)) | |
657 | return PTR_ERR(dirout); | |
658 | ||
659 | dirin = bgpio_map(pdev, "dirin", sz); | |
660 | if (IS_ERR(dirin)) | |
661 | return PTR_ERR(dirin); | |
662 | ||
663 | gc = devm_kzalloc(&pdev->dev, sizeof(*gc), GFP_KERNEL); | |
664 | if (!gc) | |
665 | return -ENOMEM; | |
666 | ||
667 | err = bgpio_init(gc, dev, sz, dat, set, clr, dirout, dirin, flags); | |
668 | if (err) | |
669 | return err; | |
670 | ||
671 | if (pdata) { | |
672 | if (pdata->label) | |
673 | gc->label = pdata->label; | |
674 | gc->base = pdata->base; | |
675 | if (pdata->ngpio > 0) | |
676 | gc->ngpio = pdata->ngpio; | |
677 | } | |
678 | ||
679 | platform_set_drvdata(pdev, gc); | |
680 | ||
681 | return devm_gpiochip_add_data(&pdev->dev, gc, NULL); | |
682 | } | |
683 | ||
684 | static const struct platform_device_id bgpio_id_table[] = { | |
685 | { | |
686 | .name = "basic-mmio-gpio", | |
687 | .driver_data = 0, | |
688 | }, { | |
689 | .name = "basic-mmio-gpio-be", | |
690 | .driver_data = BGPIOF_BIG_ENDIAN, | |
691 | }, | |
692 | { } | |
693 | }; | |
694 | MODULE_DEVICE_TABLE(platform, bgpio_id_table); | |
695 | ||
696 | static struct platform_driver bgpio_driver = { | |
697 | .driver = { | |
698 | .name = "basic-mmio-gpio", | |
699 | .of_match_table = of_match_ptr(bgpio_of_match), | |
700 | }, | |
701 | .id_table = bgpio_id_table, | |
702 | .probe = bgpio_pdev_probe, | |
703 | }; | |
704 | ||
705 | module_platform_driver(bgpio_driver); | |
706 | ||
707 | #endif /* CONFIG_GPIO_GENERIC_PLATFORM */ | |
708 | ||
709 | MODULE_DESCRIPTION("Driver for basic memory-mapped GPIO controllers"); | |
710 | MODULE_AUTHOR("Anton Vorontsov <cbouatmailru@gmail.com>"); | |
711 | MODULE_LICENSE("GPL"); |