Commit 0dc17d142c8d52cbcc829c09b433cbad20325998

Authored by Linus Torvalds

Merge tag 'gpio-v3.19-5' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-gpio

Pull gpio fixes from Linus Walleij:
 "Yet more GPIO fixes for the v3.19 series.

  There is a high bug-spot activity in GPIO this merge window, much due
  to Johan Hovolds spearheading into actually exercising the removal
  path for GPIO chips, something that was never really exercised before.

  The other two fixes are augmenting erroneous behaviours in two
  specific drivers for minor systems.

  Summary from signed tag:

   - Two fixes stabilizing that which was never stable before: removal
     of GPIO chips, now let's stop leaking memory.
   - Make sure OMAP IRQs are usable when the irqchip API is used
     orthogonally to the gpiochip API.
   - Provide a default GPIO base for the mcp23s08 driver"

* tag 'gpio-v3.19-5' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-gpio:
  gpio: sysfs: fix memory leak in gpiod_sysfs_set_active_low
  gpio: sysfs: fix memory leak in gpiod_export_link
  gpio: mcp23s08: handle default gpio base
  gpio: omap: Fix bad device access with setup_irq()

Showing 3 changed files Side-by-side Diff

drivers/gpio/gpio-mcp23s08.c
... ... @@ -801,9 +801,11 @@
801 801 client->irq = irq_of_parse_and_map(client->dev.of_node, 0);
802 802 } else {
803 803 pdata = dev_get_platdata(&client->dev);
804   - if (!pdata || !gpio_is_valid(pdata->base)) {
805   - dev_dbg(&client->dev, "invalid platform data\n");
806   - return -EINVAL;
  804 + if (!pdata) {
  805 + pdata = devm_kzalloc(&client->dev,
  806 + sizeof(struct mcp23s08_platform_data),
  807 + GFP_KERNEL);
  808 + pdata->base = -1;
807 809 }
808 810 }
809 811  
... ... @@ -924,10 +926,11 @@
924 926 } else {
925 927 type = spi_get_device_id(spi)->driver_data;
926 928 pdata = dev_get_platdata(&spi->dev);
927   - if (!pdata || !gpio_is_valid(pdata->base)) {
928   - dev_dbg(&spi->dev,
929   - "invalid or missing platform data\n");
930   - return -EINVAL;
  929 + if (!pdata) {
  930 + pdata = devm_kzalloc(&spi->dev,
  931 + sizeof(struct mcp23s08_platform_data),
  932 + GFP_KERNEL);
  933 + pdata->base = -1;
931 934 }
932 935  
933 936 for (addr = 0; addr < ARRAY_SIZE(pdata->chip); addr++) {
drivers/gpio/gpio-omap.c
... ... @@ -88,6 +88,8 @@
88 88 #define BANK_USED(bank) (bank->mod_usage || bank->irq_usage)
89 89 #define LINE_USED(line, offset) (line & (BIT(offset)))
90 90  
  91 +static void omap_gpio_unmask_irq(struct irq_data *d);
  92 +
91 93 static int omap_irq_to_gpio(struct gpio_bank *bank, unsigned int gpio_irq)
92 94 {
93 95 return bank->chip.base + gpio_irq;
... ... @@ -477,6 +479,16 @@
477 479 return readl_relaxed(reg) & mask;
478 480 }
479 481  
  482 +static void omap_gpio_init_irq(struct gpio_bank *bank, unsigned gpio,
  483 + unsigned offset)
  484 +{
  485 + if (!LINE_USED(bank->mod_usage, offset)) {
  486 + omap_enable_gpio_module(bank, offset);
  487 + omap_set_gpio_direction(bank, offset, 1);
  488 + }
  489 + bank->irq_usage |= BIT(GPIO_INDEX(bank, gpio));
  490 +}
  491 +
480 492 static int omap_gpio_irq_type(struct irq_data *d, unsigned type)
481 493 {
482 494 struct gpio_bank *bank = omap_irq_data_get_bank(d);
483 495  
... ... @@ -506,15 +518,11 @@
506 518 spin_lock_irqsave(&bank->lock, flags);
507 519 offset = GPIO_INDEX(bank, gpio);
508 520 retval = omap_set_gpio_triggering(bank, offset, type);
509   - if (!LINE_USED(bank->mod_usage, offset)) {
510   - omap_enable_gpio_module(bank, offset);
511   - omap_set_gpio_direction(bank, offset, 1);
512   - } else if (!omap_gpio_is_input(bank, BIT(offset))) {
  521 + omap_gpio_init_irq(bank, gpio, offset);
  522 + if (!omap_gpio_is_input(bank, BIT(offset))) {
513 523 spin_unlock_irqrestore(&bank->lock, flags);
514 524 return -EINVAL;
515 525 }
516   -
517   - bank->irq_usage |= BIT(GPIO_INDEX(bank, gpio));
518 526 spin_unlock_irqrestore(&bank->lock, flags);
519 527  
520 528 if (type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_LEVEL_HIGH))
... ... @@ -792,6 +800,24 @@
792 800 pm_runtime_put(bank->dev);
793 801 }
794 802  
  803 +static unsigned int omap_gpio_irq_startup(struct irq_data *d)
  804 +{
  805 + struct gpio_bank *bank = omap_irq_data_get_bank(d);
  806 + unsigned int gpio = omap_irq_to_gpio(bank, d->hwirq);
  807 + unsigned long flags;
  808 + unsigned offset = GPIO_INDEX(bank, gpio);
  809 +
  810 + if (!BANK_USED(bank))
  811 + pm_runtime_get_sync(bank->dev);
  812 +
  813 + spin_lock_irqsave(&bank->lock, flags);
  814 + omap_gpio_init_irq(bank, gpio, offset);
  815 + spin_unlock_irqrestore(&bank->lock, flags);
  816 + omap_gpio_unmask_irq(d);
  817 +
  818 + return 0;
  819 +}
  820 +
795 821 static void omap_gpio_irq_shutdown(struct irq_data *d)
796 822 {
797 823 struct gpio_bank *bank = omap_irq_data_get_bank(d);
... ... @@ -1181,6 +1207,7 @@
1181 1207 if (!irqc)
1182 1208 return -ENOMEM;
1183 1209  
  1210 + irqc->irq_startup = omap_gpio_irq_startup,
1184 1211 irqc->irq_shutdown = omap_gpio_irq_shutdown,
1185 1212 irqc->irq_ack = omap_gpio_ack_irq,
1186 1213 irqc->irq_mask = omap_gpio_mask_irq,
drivers/gpio/gpiolib-sysfs.c
... ... @@ -648,6 +648,7 @@
648 648 if (tdev != NULL) {
649 649 status = sysfs_create_link(&dev->kobj, &tdev->kobj,
650 650 name);
  651 + put_device(tdev);
651 652 } else {
652 653 status = -ENODEV;
653 654 }
... ... @@ -695,7 +696,7 @@
695 696 }
696 697  
697 698 status = sysfs_set_active_low(desc, dev, value);
698   -
  699 + put_device(dev);
699 700 unlock:
700 701 mutex_unlock(&sysfs_lock);
701 702