Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
at v3.13-rc8 573 lines 14 kB view raw
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 . 21o ` ~~~~\___/~~~~ ` 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.h> 60#include <linux/slab.h> 61#include <linux/platform_device.h> 62#include <linux/mod_devicetable.h> 63#include <linux/basic_mmio_gpio.h> 64 65static void bgpio_write8(void __iomem *reg, unsigned long data) 66{ 67 writeb(data, reg); 68} 69 70static unsigned long bgpio_read8(void __iomem *reg) 71{ 72 return readb(reg); 73} 74 75static void bgpio_write16(void __iomem *reg, unsigned long data) 76{ 77 writew(data, reg); 78} 79 80static unsigned long bgpio_read16(void __iomem *reg) 81{ 82 return readw(reg); 83} 84 85static void bgpio_write32(void __iomem *reg, unsigned long data) 86{ 87 writel(data, reg); 88} 89 90static unsigned long bgpio_read32(void __iomem *reg) 91{ 92 return readl(reg); 93} 94 95#if BITS_PER_LONG >= 64 96static void bgpio_write64(void __iomem *reg, unsigned long data) 97{ 98 writeq(data, reg); 99} 100 101static unsigned long bgpio_read64(void __iomem *reg) 102{ 103 return readq(reg); 104} 105#endif /* BITS_PER_LONG >= 64 */ 106 107static void bgpio_write16be(void __iomem *reg, unsigned long data) 108{ 109 iowrite16be(data, reg); 110} 111 112static unsigned long bgpio_read16be(void __iomem *reg) 113{ 114 return ioread16be(reg); 115} 116 117static void bgpio_write32be(void __iomem *reg, unsigned long data) 118{ 119 iowrite32be(data, reg); 120} 121 122static unsigned long bgpio_read32be(void __iomem *reg) 123{ 124 return ioread32be(reg); 125} 126 127static unsigned long bgpio_pin2mask(struct bgpio_chip *bgc, unsigned int pin) 128{ 129 return 1 << pin; 130} 131 132static unsigned long bgpio_pin2mask_be(struct bgpio_chip *bgc, 133 unsigned int pin) 134{ 135 return 1 << (bgc->bits - 1 - pin); 136} 137 138static int bgpio_get(struct gpio_chip *gc, unsigned int gpio) 139{ 140 struct bgpio_chip *bgc = to_bgpio_chip(gc); 141 142 return bgc->read_reg(bgc->reg_dat) & bgc->pin2mask(bgc, gpio); 143} 144 145static void bgpio_set(struct gpio_chip *gc, unsigned int gpio, int val) 146{ 147 struct bgpio_chip *bgc = to_bgpio_chip(gc); 148 unsigned long mask = bgc->pin2mask(bgc, gpio); 149 unsigned long flags; 150 151 spin_lock_irqsave(&bgc->lock, flags); 152 153 if (val) 154 bgc->data |= mask; 155 else 156 bgc->data &= ~mask; 157 158 bgc->write_reg(bgc->reg_dat, bgc->data); 159 160 spin_unlock_irqrestore(&bgc->lock, flags); 161} 162 163static void bgpio_set_with_clear(struct gpio_chip *gc, unsigned int gpio, 164 int val) 165{ 166 struct bgpio_chip *bgc = to_bgpio_chip(gc); 167 unsigned long mask = bgc->pin2mask(bgc, gpio); 168 169 if (val) 170 bgc->write_reg(bgc->reg_set, mask); 171 else 172 bgc->write_reg(bgc->reg_clr, mask); 173} 174 175static void bgpio_set_set(struct gpio_chip *gc, unsigned int gpio, int val) 176{ 177 struct bgpio_chip *bgc = to_bgpio_chip(gc); 178 unsigned long mask = bgc->pin2mask(bgc, gpio); 179 unsigned long flags; 180 181 spin_lock_irqsave(&bgc->lock, flags); 182 183 if (val) 184 bgc->data |= mask; 185 else 186 bgc->data &= ~mask; 187 188 bgc->write_reg(bgc->reg_set, bgc->data); 189 190 spin_unlock_irqrestore(&bgc->lock, flags); 191} 192 193static int bgpio_simple_dir_in(struct gpio_chip *gc, unsigned int gpio) 194{ 195 return 0; 196} 197 198static int bgpio_simple_dir_out(struct gpio_chip *gc, unsigned int gpio, 199 int val) 200{ 201 gc->set(gc, gpio, val); 202 203 return 0; 204} 205 206static int bgpio_dir_in(struct gpio_chip *gc, unsigned int gpio) 207{ 208 struct bgpio_chip *bgc = to_bgpio_chip(gc); 209 unsigned long flags; 210 211 spin_lock_irqsave(&bgc->lock, flags); 212 213 bgc->dir &= ~bgc->pin2mask(bgc, gpio); 214 bgc->write_reg(bgc->reg_dir, bgc->dir); 215 216 spin_unlock_irqrestore(&bgc->lock, flags); 217 218 return 0; 219} 220 221static int bgpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val) 222{ 223 struct bgpio_chip *bgc = to_bgpio_chip(gc); 224 unsigned long flags; 225 226 gc->set(gc, gpio, val); 227 228 spin_lock_irqsave(&bgc->lock, flags); 229 230 bgc->dir |= bgc->pin2mask(bgc, gpio); 231 bgc->write_reg(bgc->reg_dir, bgc->dir); 232 233 spin_unlock_irqrestore(&bgc->lock, flags); 234 235 return 0; 236} 237 238static int bgpio_dir_in_inv(struct gpio_chip *gc, unsigned int gpio) 239{ 240 struct bgpio_chip *bgc = to_bgpio_chip(gc); 241 unsigned long flags; 242 243 spin_lock_irqsave(&bgc->lock, flags); 244 245 bgc->dir |= bgc->pin2mask(bgc, gpio); 246 bgc->write_reg(bgc->reg_dir, bgc->dir); 247 248 spin_unlock_irqrestore(&bgc->lock, flags); 249 250 return 0; 251} 252 253static int bgpio_dir_out_inv(struct gpio_chip *gc, unsigned int gpio, int val) 254{ 255 struct bgpio_chip *bgc = to_bgpio_chip(gc); 256 unsigned long flags; 257 258 gc->set(gc, gpio, val); 259 260 spin_lock_irqsave(&bgc->lock, flags); 261 262 bgc->dir &= ~bgc->pin2mask(bgc, gpio); 263 bgc->write_reg(bgc->reg_dir, bgc->dir); 264 265 spin_unlock_irqrestore(&bgc->lock, flags); 266 267 return 0; 268} 269 270static int bgpio_setup_accessors(struct device *dev, 271 struct bgpio_chip *bgc, 272 bool bit_be, 273 bool byte_be) 274{ 275 276 switch (bgc->bits) { 277 case 8: 278 bgc->read_reg = bgpio_read8; 279 bgc->write_reg = bgpio_write8; 280 break; 281 case 16: 282 if (byte_be) { 283 bgc->read_reg = bgpio_read16be; 284 bgc->write_reg = bgpio_write16be; 285 } else { 286 bgc->read_reg = bgpio_read16; 287 bgc->write_reg = bgpio_write16; 288 } 289 break; 290 case 32: 291 if (byte_be) { 292 bgc->read_reg = bgpio_read32be; 293 bgc->write_reg = bgpio_write32be; 294 } else { 295 bgc->read_reg = bgpio_read32; 296 bgc->write_reg = bgpio_write32; 297 } 298 break; 299#if BITS_PER_LONG >= 64 300 case 64: 301 if (byte_be) { 302 dev_err(dev, 303 "64 bit big endian byte order unsupported\n"); 304 return -EINVAL; 305 } else { 306 bgc->read_reg = bgpio_read64; 307 bgc->write_reg = bgpio_write64; 308 } 309 break; 310#endif /* BITS_PER_LONG >= 64 */ 311 default: 312 dev_err(dev, "unsupported data width %u bits\n", bgc->bits); 313 return -EINVAL; 314 } 315 316 bgc->pin2mask = bit_be ? bgpio_pin2mask_be : bgpio_pin2mask; 317 318 return 0; 319} 320 321/* 322 * Create the device and allocate the resources. For setting GPIO's there are 323 * three supported configurations: 324 * 325 * - single input/output register resource (named "dat"). 326 * - set/clear pair (named "set" and "clr"). 327 * - single output register resource and single input resource ("set" and 328 * dat"). 329 * 330 * For the single output register, this drives a 1 by setting a bit and a zero 331 * by clearing a bit. For the set clr pair, this drives a 1 by setting a bit 332 * in the set register and clears it by setting a bit in the clear register. 333 * The configuration is detected by which resources are present. 334 * 335 * For setting the GPIO direction, there are three supported configurations: 336 * 337 * - simple bidirection GPIO that requires no configuration. 338 * - an output direction register (named "dirout") where a 1 bit 339 * indicates the GPIO is an output. 340 * - an input direction register (named "dirin") where a 1 bit indicates 341 * the GPIO is an input. 342 */ 343static int bgpio_setup_io(struct bgpio_chip *bgc, 344 void __iomem *dat, 345 void __iomem *set, 346 void __iomem *clr) 347{ 348 349 bgc->reg_dat = dat; 350 if (!bgc->reg_dat) 351 return -EINVAL; 352 353 if (set && clr) { 354 bgc->reg_set = set; 355 bgc->reg_clr = clr; 356 bgc->gc.set = bgpio_set_with_clear; 357 } else if (set && !clr) { 358 bgc->reg_set = set; 359 bgc->gc.set = bgpio_set_set; 360 } else { 361 bgc->gc.set = bgpio_set; 362 } 363 364 bgc->gc.get = bgpio_get; 365 366 return 0; 367} 368 369static int bgpio_setup_direction(struct bgpio_chip *bgc, 370 void __iomem *dirout, 371 void __iomem *dirin) 372{ 373 if (dirout && dirin) { 374 return -EINVAL; 375 } else if (dirout) { 376 bgc->reg_dir = dirout; 377 bgc->gc.direction_output = bgpio_dir_out; 378 bgc->gc.direction_input = bgpio_dir_in; 379 } else if (dirin) { 380 bgc->reg_dir = dirin; 381 bgc->gc.direction_output = bgpio_dir_out_inv; 382 bgc->gc.direction_input = bgpio_dir_in_inv; 383 } else { 384 bgc->gc.direction_output = bgpio_simple_dir_out; 385 bgc->gc.direction_input = bgpio_simple_dir_in; 386 } 387 388 return 0; 389} 390 391int bgpio_remove(struct bgpio_chip *bgc) 392{ 393 return gpiochip_remove(&bgc->gc); 394} 395EXPORT_SYMBOL_GPL(bgpio_remove); 396 397int bgpio_init(struct bgpio_chip *bgc, struct device *dev, 398 unsigned long sz, void __iomem *dat, void __iomem *set, 399 void __iomem *clr, void __iomem *dirout, void __iomem *dirin, 400 unsigned long flags) 401{ 402 int ret; 403 404 if (!is_power_of_2(sz)) 405 return -EINVAL; 406 407 bgc->bits = sz * 8; 408 if (bgc->bits > BITS_PER_LONG) 409 return -EINVAL; 410 411 spin_lock_init(&bgc->lock); 412 bgc->gc.dev = dev; 413 bgc->gc.label = dev_name(dev); 414 bgc->gc.base = -1; 415 bgc->gc.ngpio = bgc->bits; 416 417 ret = bgpio_setup_io(bgc, dat, set, clr); 418 if (ret) 419 return ret; 420 421 ret = bgpio_setup_accessors(dev, bgc, flags & BGPIOF_BIG_ENDIAN, 422 flags & BGPIOF_BIG_ENDIAN_BYTE_ORDER); 423 if (ret) 424 return ret; 425 426 ret = bgpio_setup_direction(bgc, dirout, dirin); 427 if (ret) 428 return ret; 429 430 bgc->data = bgc->read_reg(bgc->reg_dat); 431 if (bgc->gc.set == bgpio_set_set && 432 !(flags & BGPIOF_UNREADABLE_REG_SET)) 433 bgc->data = bgc->read_reg(bgc->reg_set); 434 if (bgc->reg_dir && !(flags & BGPIOF_UNREADABLE_REG_DIR)) 435 bgc->dir = bgc->read_reg(bgc->reg_dir); 436 437 return ret; 438} 439EXPORT_SYMBOL_GPL(bgpio_init); 440 441#ifdef CONFIG_GPIO_GENERIC_PLATFORM 442 443static void __iomem *bgpio_map(struct platform_device *pdev, 444 const char *name, 445 resource_size_t sane_sz, 446 int *err) 447{ 448 struct device *dev = &pdev->dev; 449 struct resource *r; 450 resource_size_t start; 451 resource_size_t sz; 452 void __iomem *ret; 453 454 *err = 0; 455 456 r = platform_get_resource_byname(pdev, IORESOURCE_MEM, name); 457 if (!r) 458 return NULL; 459 460 sz = resource_size(r); 461 if (sz != sane_sz) { 462 *err = -EINVAL; 463 return NULL; 464 } 465 466 start = r->start; 467 if (!devm_request_mem_region(dev, start, sz, r->name)) { 468 *err = -EBUSY; 469 return NULL; 470 } 471 472 ret = devm_ioremap(dev, start, sz); 473 if (!ret) { 474 *err = -ENOMEM; 475 return NULL; 476 } 477 478 return ret; 479} 480 481static int bgpio_pdev_probe(struct platform_device *pdev) 482{ 483 struct device *dev = &pdev->dev; 484 struct resource *r; 485 void __iomem *dat; 486 void __iomem *set; 487 void __iomem *clr; 488 void __iomem *dirout; 489 void __iomem *dirin; 490 unsigned long sz; 491 unsigned long flags = 0; 492 int err; 493 struct bgpio_chip *bgc; 494 struct bgpio_pdata *pdata = dev_get_platdata(dev); 495 496 r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dat"); 497 if (!r) 498 return -EINVAL; 499 500 sz = resource_size(r); 501 502 dat = bgpio_map(pdev, "dat", sz, &err); 503 if (!dat) 504 return err ? err : -EINVAL; 505 506 set = bgpio_map(pdev, "set", sz, &err); 507 if (err) 508 return err; 509 510 clr = bgpio_map(pdev, "clr", sz, &err); 511 if (err) 512 return err; 513 514 dirout = bgpio_map(pdev, "dirout", sz, &err); 515 if (err) 516 return err; 517 518 dirin = bgpio_map(pdev, "dirin", sz, &err); 519 if (err) 520 return err; 521 522 if (!strcmp(platform_get_device_id(pdev)->name, "basic-mmio-gpio-be")) 523 flags |= BGPIOF_BIG_ENDIAN; 524 525 bgc = devm_kzalloc(&pdev->dev, sizeof(*bgc), GFP_KERNEL); 526 if (!bgc) 527 return -ENOMEM; 528 529 err = bgpio_init(bgc, dev, sz, dat, set, clr, dirout, dirin, flags); 530 if (err) 531 return err; 532 533 if (pdata) { 534 bgc->gc.base = pdata->base; 535 if (pdata->ngpio > 0) 536 bgc->gc.ngpio = pdata->ngpio; 537 } 538 539 platform_set_drvdata(pdev, bgc); 540 541 return gpiochip_add(&bgc->gc); 542} 543 544static int bgpio_pdev_remove(struct platform_device *pdev) 545{ 546 struct bgpio_chip *bgc = platform_get_drvdata(pdev); 547 548 return bgpio_remove(bgc); 549} 550 551static const struct platform_device_id bgpio_id_table[] = { 552 { "basic-mmio-gpio", }, 553 { "basic-mmio-gpio-be", }, 554 {}, 555}; 556MODULE_DEVICE_TABLE(platform, bgpio_id_table); 557 558static struct platform_driver bgpio_driver = { 559 .driver = { 560 .name = "basic-mmio-gpio", 561 }, 562 .id_table = bgpio_id_table, 563 .probe = bgpio_pdev_probe, 564 .remove = bgpio_pdev_remove, 565}; 566 567module_platform_driver(bgpio_driver); 568 569#endif /* CONFIG_GPIO_GENERIC_PLATFORM */ 570 571MODULE_DESCRIPTION("Driver for basic memory-mapped GPIO controllers"); 572MODULE_AUTHOR("Anton Vorontsov <cbouatmailru@gmail.com>"); 573MODULE_LICENSE("GPL");