aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpio/basic_mmio_gpio.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpio/basic_mmio_gpio.c')
-rw-r--r--drivers/gpio/basic_mmio_gpio.c517
1 files changed, 384 insertions, 133 deletions
diff --git a/drivers/gpio/basic_mmio_gpio.c b/drivers/gpio/basic_mmio_gpio.c
index 3addea65894e..8152e9f516b0 100644
--- a/drivers/gpio/basic_mmio_gpio.c
+++ b/drivers/gpio/basic_mmio_gpio.c
@@ -45,6 +45,7 @@ o ` ~~~~\___/~~~~ ` controller in FPGA is ,.`
45 */ 45 */
46 46
47#include <linux/init.h> 47#include <linux/init.h>
48#include <linux/err.h>
48#include <linux/bug.h> 49#include <linux/bug.h>
49#include <linux/kernel.h> 50#include <linux/kernel.h>
50#include <linux/module.h> 51#include <linux/module.h>
@@ -61,102 +62,101 @@ o ` ~~~~\___/~~~~ ` controller in FPGA is ,.`
61#include <linux/mod_devicetable.h> 62#include <linux/mod_devicetable.h>
62#include <linux/basic_mmio_gpio.h> 63#include <linux/basic_mmio_gpio.h>
63 64
64struct bgpio_chip { 65static void bgpio_write8(void __iomem *reg, unsigned long data)
65 struct gpio_chip gc; 66{
66 void __iomem *reg_dat; 67 writeb(data, reg);
67 void __iomem *reg_set; 68}
68 void __iomem *reg_clr;
69
70 /* Number of bits (GPIOs): <register width> * 8. */
71 int bits;
72
73 /*
74 * Some GPIO controllers work with the big-endian bits notation,
75 * e.g. in a 8-bits register, GPIO7 is the least significant bit.
76 */
77 int big_endian_bits;
78
79 /*
80 * Used to lock bgpio_chip->data. Also, this is needed to keep
81 * shadowed and real data registers writes together.
82 */
83 spinlock_t lock;
84
85 /* Shadowed data register to clear/set bits safely. */
86 unsigned long data;
87};
88 69
89static struct bgpio_chip *to_bgpio_chip(struct gpio_chip *gc) 70static unsigned long bgpio_read8(void __iomem *reg)
90{ 71{
91 return container_of(gc, struct bgpio_chip, gc); 72 return readb(reg);
92} 73}
93 74
94static unsigned long bgpio_in(struct bgpio_chip *bgc) 75static void bgpio_write16(void __iomem *reg, unsigned long data)
95{ 76{
96 switch (bgc->bits) { 77 writew(data, reg);
97 case 8:
98 return __raw_readb(bgc->reg_dat);
99 case 16:
100 return __raw_readw(bgc->reg_dat);
101 case 32:
102 return __raw_readl(bgc->reg_dat);
103#if BITS_PER_LONG >= 64
104 case 64:
105 return __raw_readq(bgc->reg_dat);
106#endif
107 }
108 return -EINVAL;
109} 78}
110 79
111static void bgpio_out(struct bgpio_chip *bgc, void __iomem *reg, 80static unsigned long bgpio_read16(void __iomem *reg)
112 unsigned long data)
113{ 81{
114 switch (bgc->bits) { 82 return readw(reg);
115 case 8: 83}
116 __raw_writeb(data, reg); 84
117 return; 85static void bgpio_write32(void __iomem *reg, unsigned long data)
118 case 16: 86{
119 __raw_writew(data, reg); 87 writel(data, reg);
120 return; 88}
121 case 32: 89
122 __raw_writel(data, reg); 90static unsigned long bgpio_read32(void __iomem *reg)
123 return; 91{
92 return readl(reg);
93}
94
124#if BITS_PER_LONG >= 64 95#if BITS_PER_LONG >= 64
125 case 64: 96static void bgpio_write64(void __iomem *reg, unsigned long data)
126 __raw_writeq(data, reg); 97{
127 return; 98 writeq(data, reg);
128#endif
129 }
130} 99}
131 100
101static unsigned long bgpio_read64(void __iomem *reg)
102{
103 return readq(reg);
104}
105#endif /* BITS_PER_LONG >= 64 */
106
132static unsigned long bgpio_pin2mask(struct bgpio_chip *bgc, unsigned int pin) 107static unsigned long bgpio_pin2mask(struct bgpio_chip *bgc, unsigned int pin)
133{ 108{
134 if (bgc->big_endian_bits) 109 return 1 << pin;
135 return 1 << (bgc->bits - 1 - pin); 110}
136 else 111
137 return 1 << pin; 112static unsigned long bgpio_pin2mask_be(struct bgpio_chip *bgc,
113 unsigned int pin)
114{
115 return 1 << (bgc->bits - 1 - pin);
138} 116}
139 117
140static int bgpio_get(struct gpio_chip *gc, unsigned int gpio) 118static int bgpio_get(struct gpio_chip *gc, unsigned int gpio)
141{ 119{
142 struct bgpio_chip *bgc = to_bgpio_chip(gc); 120 struct bgpio_chip *bgc = to_bgpio_chip(gc);
143 121
144 return bgpio_in(bgc) & bgpio_pin2mask(bgc, gpio); 122 return bgc->read_reg(bgc->reg_dat) & bgc->pin2mask(bgc, gpio);
145} 123}
146 124
147static void bgpio_set(struct gpio_chip *gc, unsigned int gpio, int val) 125static void bgpio_set(struct gpio_chip *gc, unsigned int gpio, int val)
148{ 126{
149 struct bgpio_chip *bgc = to_bgpio_chip(gc); 127 struct bgpio_chip *bgc = to_bgpio_chip(gc);
150 unsigned long mask = bgpio_pin2mask(bgc, gpio); 128 unsigned long mask = bgc->pin2mask(bgc, gpio);
151 unsigned long flags; 129 unsigned long flags;
152 130
153 if (bgc->reg_set) { 131 spin_lock_irqsave(&bgc->lock, flags);
154 if (val) 132
155 bgpio_out(bgc, bgc->reg_set, mask); 133 if (val)
156 else 134 bgc->data |= mask;
157 bgpio_out(bgc, bgc->reg_clr, mask); 135 else
158 return; 136 bgc->data &= ~mask;
159 } 137
138 bgc->write_reg(bgc->reg_dat, bgc->data);
139
140 spin_unlock_irqrestore(&bgc->lock, flags);
141}
142
143static void bgpio_set_with_clear(struct gpio_chip *gc, unsigned int gpio,
144 int val)
145{
146 struct bgpio_chip *bgc = to_bgpio_chip(gc);
147 unsigned long mask = bgc->pin2mask(bgc, gpio);
148
149 if (val)
150 bgc->write_reg(bgc->reg_set, mask);
151 else
152 bgc->write_reg(bgc->reg_clr, mask);
153}
154
155static void bgpio_set_set(struct gpio_chip *gc, unsigned int gpio, int val)
156{
157 struct bgpio_chip *bgc = to_bgpio_chip(gc);
158 unsigned long mask = bgc->pin2mask(bgc, gpio);
159 unsigned long flags;
160 160
161 spin_lock_irqsave(&bgc->lock, flags); 161 spin_lock_irqsave(&bgc->lock, flags);
162 162
@@ -165,103 +165,352 @@ static void bgpio_set(struct gpio_chip *gc, unsigned int gpio, int val)
165 else 165 else
166 bgc->data &= ~mask; 166 bgc->data &= ~mask;
167 167
168 bgpio_out(bgc, bgc->reg_dat, bgc->data); 168 bgc->write_reg(bgc->reg_set, bgc->data);
169 169
170 spin_unlock_irqrestore(&bgc->lock, flags); 170 spin_unlock_irqrestore(&bgc->lock, flags);
171} 171}
172 172
173static int bgpio_simple_dir_in(struct gpio_chip *gc, unsigned int gpio)
174{
175 return 0;
176}
177
178static int bgpio_simple_dir_out(struct gpio_chip *gc, unsigned int gpio,
179 int val)
180{
181 gc->set(gc, gpio, val);
182
183 return 0;
184}
185
173static int bgpio_dir_in(struct gpio_chip *gc, unsigned int gpio) 186static int bgpio_dir_in(struct gpio_chip *gc, unsigned int gpio)
174{ 187{
188 struct bgpio_chip *bgc = to_bgpio_chip(gc);
189 unsigned long flags;
190
191 spin_lock_irqsave(&bgc->lock, flags);
192
193 bgc->dir &= ~bgc->pin2mask(bgc, gpio);
194 bgc->write_reg(bgc->reg_dir, bgc->dir);
195
196 spin_unlock_irqrestore(&bgc->lock, flags);
197
175 return 0; 198 return 0;
176} 199}
177 200
178static int bgpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val) 201static int bgpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val)
179{ 202{
180 bgpio_set(gc, gpio, val); 203 struct bgpio_chip *bgc = to_bgpio_chip(gc);
204 unsigned long flags;
205
206 gc->set(gc, gpio, val);
207
208 spin_lock_irqsave(&bgc->lock, flags);
209
210 bgc->dir |= bgc->pin2mask(bgc, gpio);
211 bgc->write_reg(bgc->reg_dir, bgc->dir);
212
213 spin_unlock_irqrestore(&bgc->lock, flags);
214
181 return 0; 215 return 0;
182} 216}
183 217
184static int __devinit bgpio_probe(struct platform_device *pdev) 218static int bgpio_dir_in_inv(struct gpio_chip *gc, unsigned int gpio)
185{ 219{
186 const struct platform_device_id *platid = platform_get_device_id(pdev); 220 struct bgpio_chip *bgc = to_bgpio_chip(gc);
187 struct device *dev = &pdev->dev; 221 unsigned long flags;
188 struct bgpio_pdata *pdata = dev_get_platdata(dev);
189 struct bgpio_chip *bgc;
190 struct resource *res_dat;
191 struct resource *res_set;
192 struct resource *res_clr;
193 resource_size_t dat_sz;
194 int bits;
195 int ret;
196 222
197 res_dat = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dat"); 223 spin_lock_irqsave(&bgc->lock, flags);
198 if (!res_dat)
199 return -EINVAL;
200 224
201 dat_sz = resource_size(res_dat); 225 bgc->dir |= bgc->pin2mask(bgc, gpio);
202 if (!is_power_of_2(dat_sz)) 226 bgc->write_reg(bgc->reg_dir, bgc->dir);
203 return -EINVAL; 227
228 spin_unlock_irqrestore(&bgc->lock, flags);
229
230 return 0;
231}
204 232
205 bits = dat_sz * 8; 233static int bgpio_dir_out_inv(struct gpio_chip *gc, unsigned int gpio, int val)
206 if (bits > BITS_PER_LONG) 234{
235 struct bgpio_chip *bgc = to_bgpio_chip(gc);
236 unsigned long flags;
237
238 gc->set(gc, gpio, val);
239
240 spin_lock_irqsave(&bgc->lock, flags);
241
242 bgc->dir &= ~bgc->pin2mask(bgc, gpio);
243 bgc->write_reg(bgc->reg_dir, bgc->dir);
244
245 spin_unlock_irqrestore(&bgc->lock, flags);
246
247 return 0;
248}
249
250static int bgpio_setup_accessors(struct device *dev,
251 struct bgpio_chip *bgc,
252 bool be)
253{
254
255 switch (bgc->bits) {
256 case 8:
257 bgc->read_reg = bgpio_read8;
258 bgc->write_reg = bgpio_write8;
259 break;
260 case 16:
261 bgc->read_reg = bgpio_read16;
262 bgc->write_reg = bgpio_write16;
263 break;
264 case 32:
265 bgc->read_reg = bgpio_read32;
266 bgc->write_reg = bgpio_write32;
267 break;
268#if BITS_PER_LONG >= 64
269 case 64:
270 bgc->read_reg = bgpio_read64;
271 bgc->write_reg = bgpio_write64;
272 break;
273#endif /* BITS_PER_LONG >= 64 */
274 default:
275 dev_err(dev, "unsupported data width %u bits\n", bgc->bits);
207 return -EINVAL; 276 return -EINVAL;
277 }
208 278
209 bgc = devm_kzalloc(dev, sizeof(*bgc), GFP_KERNEL); 279 bgc->pin2mask = be ? bgpio_pin2mask_be : bgpio_pin2mask;
210 if (!bgc) 280
211 return -ENOMEM; 281 return 0;
282}
283
284/*
285 * Create the device and allocate the resources. For setting GPIO's there are
286 * three supported configurations:
287 *
288 * - single input/output register resource (named "dat").
289 * - set/clear pair (named "set" and "clr").
290 * - single output register resource and single input resource ("set" and
291 * dat").
292 *
293 * For the single output register, this drives a 1 by setting a bit and a zero
294 * by clearing a bit. For the set clr pair, this drives a 1 by setting a bit
295 * in the set register and clears it by setting a bit in the clear register.
296 * The configuration is detected by which resources are present.
297 *
298 * For setting the GPIO direction, there are three supported configurations:
299 *
300 * - simple bidirection GPIO that requires no configuration.
301 * - an output direction register (named "dirout") where a 1 bit
302 * indicates the GPIO is an output.
303 * - an input direction register (named "dirin") where a 1 bit indicates
304 * the GPIO is an input.
305 */
306static int bgpio_setup_io(struct bgpio_chip *bgc,
307 void __iomem *dat,
308 void __iomem *set,
309 void __iomem *clr)
310{
212 311
213 bgc->reg_dat = devm_ioremap(dev, res_dat->start, dat_sz); 312 bgc->reg_dat = dat;
214 if (!bgc->reg_dat) 313 if (!bgc->reg_dat)
215 return -ENOMEM; 314 return -EINVAL;
315
316 if (set && clr) {
317 bgc->reg_set = set;
318 bgc->reg_clr = clr;
319 bgc->gc.set = bgpio_set_with_clear;
320 } else if (set && !clr) {
321 bgc->reg_set = set;
322 bgc->gc.set = bgpio_set_set;
323 } else {
324 bgc->gc.set = bgpio_set;
325 }
326
327 bgc->gc.get = bgpio_get;
328
329 return 0;
330}
216 331
217 res_set = platform_get_resource_byname(pdev, IORESOURCE_MEM, "set"); 332static int bgpio_setup_direction(struct bgpio_chip *bgc,
218 res_clr = platform_get_resource_byname(pdev, IORESOURCE_MEM, "clr"); 333 void __iomem *dirout,
219 if (res_set && res_clr) { 334 void __iomem *dirin)
220 if (resource_size(res_set) != resource_size(res_clr) || 335{
221 resource_size(res_set) != dat_sz) 336 if (dirout && dirin) {
222 return -EINVAL;
223
224 bgc->reg_set = devm_ioremap(dev, res_set->start, dat_sz);
225 bgc->reg_clr = devm_ioremap(dev, res_clr->start, dat_sz);
226 if (!bgc->reg_set || !bgc->reg_clr)
227 return -ENOMEM;
228 } else if (res_set || res_clr) {
229 return -EINVAL; 337 return -EINVAL;
338 } else if (dirout) {
339 bgc->reg_dir = dirout;
340 bgc->gc.direction_output = bgpio_dir_out;
341 bgc->gc.direction_input = bgpio_dir_in;
342 } else if (dirin) {
343 bgc->reg_dir = dirin;
344 bgc->gc.direction_output = bgpio_dir_out_inv;
345 bgc->gc.direction_input = bgpio_dir_in_inv;
346 } else {
347 bgc->gc.direction_output = bgpio_simple_dir_out;
348 bgc->gc.direction_input = bgpio_simple_dir_in;
230 } 349 }
231 350
232 spin_lock_init(&bgc->lock); 351 return 0;
352}
233 353
234 bgc->bits = bits; 354int __devexit bgpio_remove(struct bgpio_chip *bgc)
235 bgc->big_endian_bits = !strcmp(platid->name, "basic-mmio-gpio-be"); 355{
236 bgc->data = bgpio_in(bgc); 356 int err = gpiochip_remove(&bgc->gc);
237 357
238 bgc->gc.ngpio = bits; 358 kfree(bgc);
239 bgc->gc.direction_input = bgpio_dir_in; 359
240 bgc->gc.direction_output = bgpio_dir_out; 360 return err;
241 bgc->gc.get = bgpio_get; 361}
242 bgc->gc.set = bgpio_set; 362EXPORT_SYMBOL_GPL(bgpio_remove);
363
364int __devinit bgpio_init(struct bgpio_chip *bgc,
365 struct device *dev,
366 unsigned long sz,
367 void __iomem *dat,
368 void __iomem *set,
369 void __iomem *clr,
370 void __iomem *dirout,
371 void __iomem *dirin,
372 bool big_endian)
373{
374 int ret;
375
376 if (!is_power_of_2(sz))
377 return -EINVAL;
378
379 bgc->bits = sz * 8;
380 if (bgc->bits > BITS_PER_LONG)
381 return -EINVAL;
382
383 spin_lock_init(&bgc->lock);
243 bgc->gc.dev = dev; 384 bgc->gc.dev = dev;
244 bgc->gc.label = dev_name(dev); 385 bgc->gc.label = dev_name(dev);
386 bgc->gc.base = -1;
387 bgc->gc.ngpio = bgc->bits;
245 388
246 if (pdata) 389 ret = bgpio_setup_io(bgc, dat, set, clr);
247 bgc->gc.base = pdata->base; 390 if (ret)
248 else 391 return ret;
249 bgc->gc.base = -1;
250 392
251 dev_set_drvdata(dev, bgc); 393 ret = bgpio_setup_accessors(dev, bgc, big_endian);
394 if (ret)
395 return ret;
252 396
253 ret = gpiochip_add(&bgc->gc); 397 ret = bgpio_setup_direction(bgc, dirout, dirin);
254 if (ret) 398 if (ret)
255 dev_err(dev, "gpiochip_add() failed: %d\n", ret); 399 return ret;
400
401 bgc->data = bgc->read_reg(bgc->reg_dat);
256 402
257 return ret; 403 return ret;
258} 404}
405EXPORT_SYMBOL_GPL(bgpio_init);
406
407#ifdef CONFIG_GPIO_BASIC_MMIO
259 408
260static int __devexit bgpio_remove(struct platform_device *pdev) 409static void __iomem *bgpio_map(struct platform_device *pdev,
410 const char *name,
411 resource_size_t sane_sz,
412 int *err)
261{ 413{
262 struct bgpio_chip *bgc = dev_get_drvdata(&pdev->dev); 414 struct device *dev = &pdev->dev;
415 struct resource *r;
416 resource_size_t start;
417 resource_size_t sz;
418 void __iomem *ret;
419
420 *err = 0;
421
422 r = platform_get_resource_byname(pdev, IORESOURCE_MEM, name);
423 if (!r)
424 return NULL;
263 425
264 return gpiochip_remove(&bgc->gc); 426 sz = resource_size(r);
427 if (sz != sane_sz) {
428 *err = -EINVAL;
429 return NULL;
430 }
431
432 start = r->start;
433 if (!devm_request_mem_region(dev, start, sz, r->name)) {
434 *err = -EBUSY;
435 return NULL;
436 }
437
438 ret = devm_ioremap(dev, start, sz);
439 if (!ret) {
440 *err = -ENOMEM;
441 return NULL;
442 }
443
444 return ret;
445}
446
447static int __devinit bgpio_pdev_probe(struct platform_device *pdev)
448{
449 struct device *dev = &pdev->dev;
450 struct resource *r;
451 void __iomem *dat;
452 void __iomem *set;
453 void __iomem *clr;
454 void __iomem *dirout;
455 void __iomem *dirin;
456 unsigned long sz;
457 bool be;
458 int err;
459 struct bgpio_chip *bgc;
460 struct bgpio_pdata *pdata = dev_get_platdata(dev);
461
462 r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dat");
463 if (!r)
464 return -EINVAL;
465
466 sz = resource_size(r);
467
468 dat = bgpio_map(pdev, "dat", sz, &err);
469 if (!dat)
470 return err ? err : -EINVAL;
471
472 set = bgpio_map(pdev, "set", sz, &err);
473 if (err)
474 return err;
475
476 clr = bgpio_map(pdev, "clr", sz, &err);
477 if (err)
478 return err;
479
480 dirout = bgpio_map(pdev, "dirout", sz, &err);
481 if (err)
482 return err;
483
484 dirin = bgpio_map(pdev, "dirin", sz, &err);
485 if (err)
486 return err;
487
488 be = !strcmp(platform_get_device_id(pdev)->name, "basic-mmio-gpio-be");
489
490 bgc = devm_kzalloc(&pdev->dev, sizeof(*bgc), GFP_KERNEL);
491 if (!bgc)
492 return -ENOMEM;
493
494 err = bgpio_init(bgc, dev, sz, dat, set, clr, dirout, dirin, be);
495 if (err)
496 return err;
497
498 if (pdata) {
499 bgc->gc.base = pdata->base;
500 if (pdata->ngpio > 0)
501 bgc->gc.ngpio = pdata->ngpio;
502 }
503
504 platform_set_drvdata(pdev, bgc);
505
506 return gpiochip_add(&bgc->gc);
507}
508
509static int __devexit bgpio_pdev_remove(struct platform_device *pdev)
510{
511 struct bgpio_chip *bgc = platform_get_drvdata(pdev);
512
513 return bgpio_remove(bgc);
265} 514}
266 515
267static const struct platform_device_id bgpio_id_table[] = { 516static const struct platform_device_id bgpio_id_table[] = {
@@ -276,21 +525,23 @@ static struct platform_driver bgpio_driver = {
276 .name = "basic-mmio-gpio", 525 .name = "basic-mmio-gpio",
277 }, 526 },
278 .id_table = bgpio_id_table, 527 .id_table = bgpio_id_table,
279 .probe = bgpio_probe, 528 .probe = bgpio_pdev_probe,
280 .remove = __devexit_p(bgpio_remove), 529 .remove = __devexit_p(bgpio_pdev_remove),
281}; 530};
282 531
283static int __init bgpio_init(void) 532static int __init bgpio_platform_init(void)
284{ 533{
285 return platform_driver_register(&bgpio_driver); 534 return platform_driver_register(&bgpio_driver);
286} 535}
287module_init(bgpio_init); 536module_init(bgpio_platform_init);
288 537
289static void __exit bgpio_exit(void) 538static void __exit bgpio_platform_exit(void)
290{ 539{
291 platform_driver_unregister(&bgpio_driver); 540 platform_driver_unregister(&bgpio_driver);
292} 541}
293module_exit(bgpio_exit); 542module_exit(bgpio_platform_exit);
543
544#endif /* CONFIG_GPIO_BASIC_MMIO */
294 545
295MODULE_DESCRIPTION("Driver for basic memory-mapped GPIO controllers"); 546MODULE_DESCRIPTION("Driver for basic memory-mapped GPIO controllers");
296MODULE_AUTHOR("Anton Vorontsov <cbouatmailru@gmail.com>"); 547MODULE_AUTHOR("Anton Vorontsov <cbouatmailru@gmail.com>");