aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpio
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpio')
-rw-r--r--drivers/gpio/gpio-stmpe.c41
-rw-r--r--drivers/gpio/gpio-twl4030.c111
2 files changed, 92 insertions, 60 deletions
diff --git a/drivers/gpio/gpio-stmpe.c b/drivers/gpio/gpio-stmpe.c
index 87a68a896abf..094c5c4fd7f2 100644
--- a/drivers/gpio/gpio-stmpe.c
+++ b/drivers/gpio/gpio-stmpe.c
@@ -307,13 +307,11 @@ static int __devinit stmpe_gpio_probe(struct platform_device *pdev)
307 struct stmpe_gpio_platform_data *pdata; 307 struct stmpe_gpio_platform_data *pdata;
308 struct stmpe_gpio *stmpe_gpio; 308 struct stmpe_gpio *stmpe_gpio;
309 int ret; 309 int ret;
310 int irq; 310 int irq = 0;
311 311
312 pdata = stmpe->pdata->gpio; 312 pdata = stmpe->pdata->gpio;
313 313
314 irq = platform_get_irq(pdev, 0); 314 irq = platform_get_irq(pdev, 0);
315 if (irq < 0)
316 return irq;
317 315
318 stmpe_gpio = kzalloc(sizeof(struct stmpe_gpio), GFP_KERNEL); 316 stmpe_gpio = kzalloc(sizeof(struct stmpe_gpio), GFP_KERNEL);
319 if (!stmpe_gpio) 317 if (!stmpe_gpio)
@@ -330,21 +328,28 @@ static int __devinit stmpe_gpio_probe(struct platform_device *pdev)
330 stmpe_gpio->chip.dev = &pdev->dev; 328 stmpe_gpio->chip.dev = &pdev->dev;
331 stmpe_gpio->chip.base = pdata ? pdata->gpio_base : -1; 329 stmpe_gpio->chip.base = pdata ? pdata->gpio_base : -1;
332 330
333 stmpe_gpio->irq_base = stmpe->irq_base + STMPE_INT_GPIO(0); 331 if (irq >= 0)
332 stmpe_gpio->irq_base = stmpe->irq_base + STMPE_INT_GPIO(0);
333 else
334 dev_info(&pdev->dev,
335 "device configured in no-irq mode; "
336 "irqs are not available\n");
334 337
335 ret = stmpe_enable(stmpe, STMPE_BLOCK_GPIO); 338 ret = stmpe_enable(stmpe, STMPE_BLOCK_GPIO);
336 if (ret) 339 if (ret)
337 goto out_free; 340 goto out_free;
338 341
339 ret = stmpe_gpio_irq_init(stmpe_gpio); 342 if (irq >= 0) {
340 if (ret) 343 ret = stmpe_gpio_irq_init(stmpe_gpio);
341 goto out_disable; 344 if (ret)
345 goto out_disable;
342 346
343 ret = request_threaded_irq(irq, NULL, stmpe_gpio_irq, IRQF_ONESHOT, 347 ret = request_threaded_irq(irq, NULL, stmpe_gpio_irq,
344 "stmpe-gpio", stmpe_gpio); 348 IRQF_ONESHOT, "stmpe-gpio", stmpe_gpio);
345 if (ret) { 349 if (ret) {
346 dev_err(&pdev->dev, "unable to get irq: %d\n", ret); 350 dev_err(&pdev->dev, "unable to get irq: %d\n", ret);
347 goto out_removeirq; 351 goto out_removeirq;
352 }
348 } 353 }
349 354
350 ret = gpiochip_add(&stmpe_gpio->chip); 355 ret = gpiochip_add(&stmpe_gpio->chip);
@@ -361,9 +366,11 @@ static int __devinit stmpe_gpio_probe(struct platform_device *pdev)
361 return 0; 366 return 0;
362 367
363out_freeirq: 368out_freeirq:
364 free_irq(irq, stmpe_gpio); 369 if (irq >= 0)
370 free_irq(irq, stmpe_gpio);
365out_removeirq: 371out_removeirq:
366 stmpe_gpio_irq_remove(stmpe_gpio); 372 if (irq >= 0)
373 stmpe_gpio_irq_remove(stmpe_gpio);
367out_disable: 374out_disable:
368 stmpe_disable(stmpe, STMPE_BLOCK_GPIO); 375 stmpe_disable(stmpe, STMPE_BLOCK_GPIO);
369out_free: 376out_free:
@@ -391,8 +398,10 @@ static int __devexit stmpe_gpio_remove(struct platform_device *pdev)
391 398
392 stmpe_disable(stmpe, STMPE_BLOCK_GPIO); 399 stmpe_disable(stmpe, STMPE_BLOCK_GPIO);
393 400
394 free_irq(irq, stmpe_gpio); 401 if (irq >= 0) {
395 stmpe_gpio_irq_remove(stmpe_gpio); 402 free_irq(irq, stmpe_gpio);
403 stmpe_gpio_irq_remove(stmpe_gpio);
404 }
396 platform_set_drvdata(pdev, NULL); 405 platform_set_drvdata(pdev, NULL);
397 kfree(stmpe_gpio); 406 kfree(stmpe_gpio);
398 407
diff --git a/drivers/gpio/gpio-twl4030.c b/drivers/gpio/gpio-twl4030.c
index b8b4f228757c..94256fe7bf36 100644
--- a/drivers/gpio/gpio-twl4030.c
+++ b/drivers/gpio/gpio-twl4030.c
@@ -32,6 +32,8 @@
32#include <linux/irq.h> 32#include <linux/irq.h>
33#include <linux/gpio.h> 33#include <linux/gpio.h>
34#include <linux/platform_device.h> 34#include <linux/platform_device.h>
35#include <linux/of.h>
36#include <linux/irqdomain.h>
35 37
36#include <linux/i2c/twl.h> 38#include <linux/i2c/twl.h>
37 39
@@ -256,7 +258,8 @@ static int twl_request(struct gpio_chip *chip, unsigned offset)
256 * and vMMC2 power supplies based on card presence. 258 * and vMMC2 power supplies based on card presence.
257 */ 259 */
258 pdata = chip->dev->platform_data; 260 pdata = chip->dev->platform_data;
259 value |= pdata->mmc_cd & 0x03; 261 if (pdata)
262 value |= pdata->mmc_cd & 0x03;
260 263
261 status = gpio_twl4030_write(REG_GPIO_CTRL, value); 264 status = gpio_twl4030_write(REG_GPIO_CTRL, value);
262 } 265 }
@@ -395,59 +398,70 @@ static int gpio_twl4030_remove(struct platform_device *pdev);
395static int __devinit gpio_twl4030_probe(struct platform_device *pdev) 398static int __devinit gpio_twl4030_probe(struct platform_device *pdev)
396{ 399{
397 struct twl4030_gpio_platform_data *pdata = pdev->dev.platform_data; 400 struct twl4030_gpio_platform_data *pdata = pdev->dev.platform_data;
398 int ret; 401 struct device_node *node = pdev->dev.of_node;
402 int ret, irq_base;
399 403
400 /* maybe setup IRQs */ 404 /* maybe setup IRQs */
401 if (pdata->irq_base) { 405 if (is_module()) {
402 if (is_module()) { 406 dev_err(&pdev->dev, "can't dispatch IRQs from modules\n");
403 dev_err(&pdev->dev, 407 goto no_irqs;
404 "can't dispatch IRQs from modules\n"); 408 }
405 goto no_irqs; 409
406 } 410 irq_base = irq_alloc_descs(-1, 0, TWL4030_GPIO_MAX, 0);
407 ret = twl4030_sih_setup(TWL4030_MODULE_GPIO); 411 if (irq_base < 0) {
408 if (ret < 0) 412 dev_err(&pdev->dev, "Failed to alloc irq_descs\n");
409 return ret; 413 return irq_base;
410 WARN_ON(ret != pdata->irq_base);
411 twl4030_gpio_irq_base = ret;
412 } 414 }
413 415
416 irq_domain_add_legacy(node, TWL4030_GPIO_MAX, irq_base, 0,
417 &irq_domain_simple_ops, NULL);
418
419 ret = twl4030_sih_setup(&pdev->dev, TWL4030_MODULE_GPIO, irq_base);
420 if (ret < 0)
421 return ret;
422
423 twl4030_gpio_irq_base = irq_base;
424
414no_irqs: 425no_irqs:
415 /* 426 twl_gpiochip.base = -1;
416 * NOTE: boards may waste power if they don't set pullups
417 * and pulldowns correctly ... default for non-ULPI pins is
418 * pulldown, and some other pins may have external pullups
419 * or pulldowns. Careful!
420 */
421 ret = gpio_twl4030_pulls(pdata->pullups, pdata->pulldowns);
422 if (ret)
423 dev_dbg(&pdev->dev, "pullups %.05x %.05x --> %d\n",
424 pdata->pullups, pdata->pulldowns,
425 ret);
426
427 ret = gpio_twl4030_debounce(pdata->debounce, pdata->mmc_cd);
428 if (ret)
429 dev_dbg(&pdev->dev, "debounce %.03x %.01x --> %d\n",
430 pdata->debounce, pdata->mmc_cd,
431 ret);
432
433 twl_gpiochip.base = pdata->gpio_base;
434 twl_gpiochip.ngpio = TWL4030_GPIO_MAX; 427 twl_gpiochip.ngpio = TWL4030_GPIO_MAX;
435 twl_gpiochip.dev = &pdev->dev; 428 twl_gpiochip.dev = &pdev->dev;
436 429
437 /* NOTE: we assume VIBRA_CTL.VIBRA_EN, in MODULE_AUDIO_VOICE, 430 if (pdata) {
438 * is (still) clear if use_leds is set. 431 twl_gpiochip.base = pdata->gpio_base;
439 */ 432
440 if (pdata->use_leds) 433 /*
441 twl_gpiochip.ngpio += 2; 434 * NOTE: boards may waste power if they don't set pullups
435 * and pulldowns correctly ... default for non-ULPI pins is
436 * pulldown, and some other pins may have external pullups
437 * or pulldowns. Careful!
438 */
439 ret = gpio_twl4030_pulls(pdata->pullups, pdata->pulldowns);
440 if (ret)
441 dev_dbg(&pdev->dev, "pullups %.05x %.05x --> %d\n",
442 pdata->pullups, pdata->pulldowns,
443 ret);
444
445 ret = gpio_twl4030_debounce(pdata->debounce, pdata->mmc_cd);
446 if (ret)
447 dev_dbg(&pdev->dev, "debounce %.03x %.01x --> %d\n",
448 pdata->debounce, pdata->mmc_cd,
449 ret);
450
451 /*
452 * NOTE: we assume VIBRA_CTL.VIBRA_EN, in MODULE_AUDIO_VOICE,
453 * is (still) clear if use_leds is set.
454 */
455 if (pdata->use_leds)
456 twl_gpiochip.ngpio += 2;
457 }
442 458
443 ret = gpiochip_add(&twl_gpiochip); 459 ret = gpiochip_add(&twl_gpiochip);
444 if (ret < 0) { 460 if (ret < 0) {
445 dev_err(&pdev->dev, 461 dev_err(&pdev->dev, "could not register gpiochip, %d\n", ret);
446 "could not register gpiochip, %d\n",
447 ret);
448 twl_gpiochip.ngpio = 0; 462 twl_gpiochip.ngpio = 0;
449 gpio_twl4030_remove(pdev); 463 gpio_twl4030_remove(pdev);
450 } else if (pdata->setup) { 464 } else if (pdata && pdata->setup) {
451 int status; 465 int status;
452 466
453 status = pdata->setup(&pdev->dev, 467 status = pdata->setup(&pdev->dev,
@@ -465,7 +479,7 @@ static int gpio_twl4030_remove(struct platform_device *pdev)
465 struct twl4030_gpio_platform_data *pdata = pdev->dev.platform_data; 479 struct twl4030_gpio_platform_data *pdata = pdev->dev.platform_data;
466 int status; 480 int status;
467 481
468 if (pdata->teardown) { 482 if (pdata && pdata->teardown) {
469 status = pdata->teardown(&pdev->dev, 483 status = pdata->teardown(&pdev->dev,
470 pdata->gpio_base, TWL4030_GPIO_MAX); 484 pdata->gpio_base, TWL4030_GPIO_MAX);
471 if (status) { 485 if (status) {
@@ -486,12 +500,21 @@ static int gpio_twl4030_remove(struct platform_device *pdev)
486 return -EIO; 500 return -EIO;
487} 501}
488 502
503static const struct of_device_id twl_gpio_match[] = {
504 { .compatible = "ti,twl4030-gpio", },
505 { },
506};
507MODULE_DEVICE_TABLE(of, twl_gpio_match);
508
489/* Note: this hardware lives inside an I2C-based multi-function device. */ 509/* Note: this hardware lives inside an I2C-based multi-function device. */
490MODULE_ALIAS("platform:twl4030_gpio"); 510MODULE_ALIAS("platform:twl4030_gpio");
491 511
492static struct platform_driver gpio_twl4030_driver = { 512static struct platform_driver gpio_twl4030_driver = {
493 .driver.name = "twl4030_gpio", 513 .driver = {
494 .driver.owner = THIS_MODULE, 514 .name = "twl4030_gpio",
515 .owner = THIS_MODULE,
516 .of_match_table = of_match_ptr(twl_gpio_match),
517 },
495 .probe = gpio_twl4030_probe, 518 .probe = gpio_twl4030_probe,
496 .remove = gpio_twl4030_remove, 519 .remove = gpio_twl4030_remove,
497}; 520};