diff options
-rw-r--r-- | drivers/gpio/gpio-pca953x.c | 77 |
1 files changed, 28 insertions, 49 deletions
diff --git a/drivers/gpio/gpio-pca953x.c b/drivers/gpio/gpio-pca953x.c index 5e4d3f23156a..e6805b97d047 100644 --- a/drivers/gpio/gpio-pca953x.c +++ b/drivers/gpio/gpio-pca953x.c | |||
@@ -85,7 +85,6 @@ struct pca953x_chip { | |||
85 | #endif | 85 | #endif |
86 | 86 | ||
87 | struct i2c_client *client; | 87 | struct i2c_client *client; |
88 | struct pca953x_platform_data *dyn_pdata; | ||
89 | struct gpio_chip gpio_chip; | 88 | struct gpio_chip gpio_chip; |
90 | const char *const *names; | 89 | const char *const *names; |
91 | int chip_type; | 90 | int chip_type; |
@@ -446,13 +445,13 @@ static irqreturn_t pca953x_irq_handler(int irq, void *devid) | |||
446 | } | 445 | } |
447 | 446 | ||
448 | static int pca953x_irq_setup(struct pca953x_chip *chip, | 447 | static int pca953x_irq_setup(struct pca953x_chip *chip, |
449 | const struct i2c_device_id *id) | 448 | const struct i2c_device_id *id, |
449 | int irq_base) | ||
450 | { | 450 | { |
451 | struct i2c_client *client = chip->client; | 451 | struct i2c_client *client = chip->client; |
452 | struct pca953x_platform_data *pdata = client->dev.platform_data; | ||
453 | int ret, offset = 0; | 452 | int ret, offset = 0; |
454 | 453 | ||
455 | if (pdata->irq_base != -1 | 454 | if (irq_base != -1 |
456 | && (id->driver_data & PCA_INT)) { | 455 | && (id->driver_data & PCA_INT)) { |
457 | int lvl; | 456 | int lvl; |
458 | 457 | ||
@@ -476,7 +475,7 @@ static int pca953x_irq_setup(struct pca953x_chip *chip, | |||
476 | chip->irq_stat &= chip->reg_direction; | 475 | chip->irq_stat &= chip->reg_direction; |
477 | mutex_init(&chip->irq_lock); | 476 | mutex_init(&chip->irq_lock); |
478 | 477 | ||
479 | chip->irq_base = irq_alloc_descs(-1, pdata->irq_base, chip->gpio_chip.ngpio, -1); | 478 | chip->irq_base = irq_alloc_descs(-1, irq_base, chip->gpio_chip.ngpio, -1); |
480 | if (chip->irq_base < 0) | 479 | if (chip->irq_base < 0) |
481 | goto out_failed; | 480 | goto out_failed; |
482 | 481 | ||
@@ -524,12 +523,12 @@ static void pca953x_irq_teardown(struct pca953x_chip *chip) | |||
524 | } | 523 | } |
525 | #else /* CONFIG_GPIO_PCA953X_IRQ */ | 524 | #else /* CONFIG_GPIO_PCA953X_IRQ */ |
526 | static int pca953x_irq_setup(struct pca953x_chip *chip, | 525 | static int pca953x_irq_setup(struct pca953x_chip *chip, |
527 | const struct i2c_device_id *id) | 526 | const struct i2c_device_id *id, |
527 | int irq_base) | ||
528 | { | 528 | { |
529 | struct i2c_client *client = chip->client; | 529 | struct i2c_client *client = chip->client; |
530 | struct pca953x_platform_data *pdata = client->dev.platform_data; | ||
531 | 530 | ||
532 | if (pdata->irq_base != -1 && (id->driver_data & PCA_INT)) | 531 | if (irq_base != -1 && (id->driver_data & PCA_INT)) |
533 | dev_warn(&client->dev, "interrupt support not compiled in\n"); | 532 | dev_warn(&client->dev, "interrupt support not compiled in\n"); |
534 | 533 | ||
535 | return 0; | 534 | return 0; |
@@ -547,45 +546,35 @@ static void pca953x_irq_teardown(struct pca953x_chip *chip) | |||
547 | /* | 546 | /* |
548 | * Translate OpenFirmware node properties into platform_data | 547 | * Translate OpenFirmware node properties into platform_data |
549 | */ | 548 | */ |
550 | static struct pca953x_platform_data * | 549 | void |
551 | pca953x_get_alt_pdata(struct i2c_client *client) | 550 | pca953x_get_alt_pdata(struct i2c_client *client, int *gpio_base, int *invert) |
552 | { | 551 | { |
553 | struct pca953x_platform_data *pdata; | ||
554 | struct device_node *node; | 552 | struct device_node *node; |
555 | const __be32 *val; | 553 | const __be32 *val; |
556 | int size; | 554 | int size; |
557 | 555 | ||
558 | node = client->dev.of_node; | 556 | node = client->dev.of_node; |
559 | if (node == NULL) | 557 | if (node == NULL) |
560 | return NULL; | 558 | return; |
561 | 559 | ||
562 | pdata = kzalloc(sizeof(struct pca953x_platform_data), GFP_KERNEL); | 560 | *gpio_base = -1; |
563 | if (pdata == NULL) { | ||
564 | dev_err(&client->dev, "Unable to allocate platform_data\n"); | ||
565 | return NULL; | ||
566 | } | ||
567 | |||
568 | pdata->gpio_base = -1; | ||
569 | val = of_get_property(node, "linux,gpio-base", &size); | 561 | val = of_get_property(node, "linux,gpio-base", &size); |
570 | if (val) { | 562 | if (val) { |
571 | if (size != sizeof(*val)) | 563 | if (size != sizeof(*val)) |
572 | dev_warn(&client->dev, "%s: wrong linux,gpio-base\n", | 564 | dev_warn(&client->dev, "%s: wrong linux,gpio-base\n", |
573 | node->full_name); | 565 | node->full_name); |
574 | else | 566 | else |
575 | pdata->gpio_base = be32_to_cpup(val); | 567 | *gpio_base = be32_to_cpup(val); |
576 | } | 568 | } |
577 | 569 | ||
578 | val = of_get_property(node, "polarity", NULL); | 570 | val = of_get_property(node, "polarity", NULL); |
579 | if (val) | 571 | if (val) |
580 | pdata->invert = *val; | 572 | *invert = *val; |
581 | |||
582 | return pdata; | ||
583 | } | 573 | } |
584 | #else | 574 | #else |
585 | static struct pca953x_platform_data * | 575 | void |
586 | pca953x_get_alt_pdata(struct i2c_client *client) | 576 | pca953x_get_alt_pdata(struct i2c_client *client, int *gpio_base, int *invert) |
587 | { | 577 | { |
588 | return NULL; | ||
589 | } | 578 | } |
590 | #endif | 579 | #endif |
591 | 580 | ||
@@ -647,6 +636,7 @@ static int __devinit pca953x_probe(struct i2c_client *client, | |||
647 | { | 636 | { |
648 | struct pca953x_platform_data *pdata; | 637 | struct pca953x_platform_data *pdata; |
649 | struct pca953x_chip *chip; | 638 | struct pca953x_chip *chip; |
639 | int irq_base=-1, invert=0; | ||
650 | int ret = 0; | 640 | int ret = 0; |
651 | 641 | ||
652 | chip = kzalloc(sizeof(struct pca953x_chip), GFP_KERNEL); | 642 | chip = kzalloc(sizeof(struct pca953x_chip), GFP_KERNEL); |
@@ -654,26 +644,17 @@ static int __devinit pca953x_probe(struct i2c_client *client, | |||
654 | return -ENOMEM; | 644 | return -ENOMEM; |
655 | 645 | ||
656 | pdata = client->dev.platform_data; | 646 | pdata = client->dev.platform_data; |
657 | if (pdata == NULL) { | 647 | if (pdata) { |
658 | pdata = pca953x_get_alt_pdata(client); | 648 | irq_base = pdata->irq_base; |
659 | /* | 649 | chip->gpio_start = pdata->gpio_base; |
660 | * Unlike normal platform_data, this is allocated | 650 | invert = pdata->invert; |
661 | * dynamically and must be freed in the driver | 651 | chip->names = pdata->names; |
662 | */ | 652 | } else { |
663 | chip->dyn_pdata = pdata; | 653 | pca953x_get_alt_pdata(client, &chip->gpio_start, &invert); |
664 | } | ||
665 | |||
666 | if (pdata == NULL) { | ||
667 | dev_dbg(&client->dev, "no platform data\n"); | ||
668 | ret = -EINVAL; | ||
669 | goto out_failed; | ||
670 | } | 654 | } |
671 | 655 | ||
672 | chip->client = client; | 656 | chip->client = client; |
673 | 657 | ||
674 | chip->gpio_start = pdata->gpio_base; | ||
675 | |||
676 | chip->names = pdata->names; | ||
677 | chip->chip_type = id->driver_data & (PCA953X_TYPE | PCA957X_TYPE); | 658 | chip->chip_type = id->driver_data & (PCA953X_TYPE | PCA957X_TYPE); |
678 | 659 | ||
679 | mutex_init(&chip->i2c_lock); | 660 | mutex_init(&chip->i2c_lock); |
@@ -684,13 +665,13 @@ static int __devinit pca953x_probe(struct i2c_client *client, | |||
684 | pca953x_setup_gpio(chip, id->driver_data & PCA_GPIO_MASK); | 665 | pca953x_setup_gpio(chip, id->driver_data & PCA_GPIO_MASK); |
685 | 666 | ||
686 | if (chip->chip_type == PCA953X_TYPE) | 667 | if (chip->chip_type == PCA953X_TYPE) |
687 | device_pca953x_init(chip, pdata->invert); | 668 | device_pca953x_init(chip, invert); |
688 | else if (chip->chip_type == PCA957X_TYPE) | 669 | else if (chip->chip_type == PCA957X_TYPE) |
689 | device_pca957x_init(chip, pdata->invert); | 670 | device_pca957x_init(chip, invert); |
690 | else | 671 | else |
691 | goto out_failed; | 672 | goto out_failed; |
692 | 673 | ||
693 | ret = pca953x_irq_setup(chip, id); | 674 | ret = pca953x_irq_setup(chip, id, irq_base); |
694 | if (ret) | 675 | if (ret) |
695 | goto out_failed; | 676 | goto out_failed; |
696 | 677 | ||
@@ -698,7 +679,7 @@ static int __devinit pca953x_probe(struct i2c_client *client, | |||
698 | if (ret) | 679 | if (ret) |
699 | goto out_failed_irq; | 680 | goto out_failed_irq; |
700 | 681 | ||
701 | if (pdata->setup) { | 682 | if (pdata && pdata->setup) { |
702 | ret = pdata->setup(client, chip->gpio_chip.base, | 683 | ret = pdata->setup(client, chip->gpio_chip.base, |
703 | chip->gpio_chip.ngpio, pdata->context); | 684 | chip->gpio_chip.ngpio, pdata->context); |
704 | if (ret < 0) | 685 | if (ret < 0) |
@@ -711,7 +692,6 @@ static int __devinit pca953x_probe(struct i2c_client *client, | |||
711 | out_failed_irq: | 692 | out_failed_irq: |
712 | pca953x_irq_teardown(chip); | 693 | pca953x_irq_teardown(chip); |
713 | out_failed: | 694 | out_failed: |
714 | kfree(chip->dyn_pdata); | ||
715 | kfree(chip); | 695 | kfree(chip); |
716 | return ret; | 696 | return ret; |
717 | } | 697 | } |
@@ -722,7 +702,7 @@ static int pca953x_remove(struct i2c_client *client) | |||
722 | struct pca953x_chip *chip = i2c_get_clientdata(client); | 702 | struct pca953x_chip *chip = i2c_get_clientdata(client); |
723 | int ret = 0; | 703 | int ret = 0; |
724 | 704 | ||
725 | if (pdata->teardown) { | 705 | if (pdata && pdata->teardown) { |
726 | ret = pdata->teardown(client, chip->gpio_chip.base, | 706 | ret = pdata->teardown(client, chip->gpio_chip.base, |
727 | chip->gpio_chip.ngpio, pdata->context); | 707 | chip->gpio_chip.ngpio, pdata->context); |
728 | if (ret < 0) { | 708 | if (ret < 0) { |
@@ -740,7 +720,6 @@ static int pca953x_remove(struct i2c_client *client) | |||
740 | } | 720 | } |
741 | 721 | ||
742 | pca953x_irq_teardown(chip); | 722 | pca953x_irq_teardown(chip); |
743 | kfree(chip->dyn_pdata); | ||
744 | kfree(chip); | 723 | kfree(chip); |
745 | return 0; | 724 | return 0; |
746 | } | 725 | } |