Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'gpio-v4.1-2' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-gpio

Pull GPIO fixes from Linus Walleij:
"Here is a bunch of GPIO fixes that I collected since -rc1, nothing
controversial, nothing special:

- fix a memory leak for GPIO hotplug.

- fix a signedness bug in the ACPI GPIO pin validation.

- driver fixes: Qualcomm SPMI and OMAP MPUIO IRQ issues"

* tag 'gpio-v4.1-2' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-gpio:
gpio: omap: Fix regression for MPUIO interrupts
gpio: sysfs: fix memory leaks and device hotplug
pinctrl: qcom-spmi-gpio: Fix input value report
pinctrl: qcom-spmi-gpio: Fix output type configuration
gpiolib: change gpio pin from unsigned to signed in acpi callback

+36 -46
+9 -39
drivers/gpio/gpio-omap.c
··· 1054 1054 dev_err(bank->dev, "Could not get gpio dbck\n"); 1055 1055 } 1056 1056 1057 - static void 1058 - omap_mpuio_alloc_gc(struct gpio_bank *bank, unsigned int irq_start, 1059 - unsigned int num) 1060 - { 1061 - struct irq_chip_generic *gc; 1062 - struct irq_chip_type *ct; 1063 - 1064 - gc = irq_alloc_generic_chip("MPUIO", 1, irq_start, bank->base, 1065 - handle_simple_irq); 1066 - if (!gc) { 1067 - dev_err(bank->dev, "Memory alloc failed for gc\n"); 1068 - return; 1069 - } 1070 - 1071 - ct = gc->chip_types; 1072 - 1073 - /* NOTE: No ack required, reading IRQ status clears it. */ 1074 - ct->chip.irq_mask = irq_gc_mask_set_bit; 1075 - ct->chip.irq_unmask = irq_gc_mask_clr_bit; 1076 - ct->chip.irq_set_type = omap_gpio_irq_type; 1077 - 1078 - if (bank->regs->wkup_en) 1079 - ct->chip.irq_set_wake = omap_gpio_wake_enable; 1080 - 1081 - ct->regs.mask = OMAP_MPUIO_GPIO_INT / bank->stride; 1082 - irq_setup_generic_chip(gc, IRQ_MSK(num), IRQ_GC_INIT_MASK_CACHE, 1083 - IRQ_NOREQUEST | IRQ_NOPROBE, 0); 1084 - } 1085 - 1086 1057 static int omap_gpio_chip_init(struct gpio_bank *bank, struct irq_chip *irqc) 1087 1058 { 1088 - int j; 1089 1059 static int gpio; 1090 1060 int irq_base = 0; 1091 1061 int ret; ··· 1102 1132 } 1103 1133 #endif 1104 1134 1135 + /* MPUIO is a bit different, reading IRQ status clears it */ 1136 + if (bank->is_mpuio) { 1137 + irqc->irq_ack = dummy_irq_chip.irq_ack; 1138 + irqc->irq_mask = irq_gc_mask_set_bit; 1139 + irqc->irq_unmask = irq_gc_mask_clr_bit; 1140 + if (!bank->regs->wkup_en) 1141 + irqc->irq_set_wake = NULL; 1142 + } 1143 + 1105 1144 ret = gpiochip_irqchip_add(&bank->chip, irqc, 1106 1145 irq_base, omap_gpio_irq_handler, 1107 1146 IRQ_TYPE_NONE); ··· 1123 1144 1124 1145 gpiochip_set_chained_irqchip(&bank->chip, irqc, 1125 1146 bank->irq, omap_gpio_irq_handler); 1126 - 1127 - for (j = 0; j < bank->width; j++) { 1128 - int irq = irq_find_mapping(bank->chip.irqdomain, j); 1129 - if (bank->is_mpuio) { 1130 - omap_mpuio_alloc_gc(bank, irq, bank->width); 1131 - irq_set_chip_and_handler(irq, NULL, NULL); 1132 - set_irq_flags(irq, 0); 1133 - } 1134 - } 1135 1147 1136 1148 return 0; 1137 1149 }
+1 -1
drivers/gpio/gpiolib-acpi.c
··· 550 550 551 551 length = min(agpio->pin_table_length, (u16)(pin_index + bits)); 552 552 for (i = pin_index; i < length; ++i) { 553 - unsigned pin = agpio->pin_table[i]; 553 + int pin = agpio->pin_table[i]; 554 554 struct acpi_gpio_connection *conn; 555 555 struct gpio_desc *desc; 556 556 bool found;
+19
drivers/gpio/gpiolib-sysfs.c
··· 551 551 */ 552 552 int gpiod_export(struct gpio_desc *desc, bool direction_may_change) 553 553 { 554 + struct gpio_chip *chip; 554 555 unsigned long flags; 555 556 int status; 556 557 const char *ioname = NULL; ··· 569 568 return -EINVAL; 570 569 } 571 570 571 + chip = desc->chip; 572 + 572 573 mutex_lock(&sysfs_lock); 574 + 575 + /* check if chip is being removed */ 576 + if (!chip || !chip->exported) { 577 + status = -ENODEV; 578 + goto fail_unlock; 579 + } 573 580 574 581 spin_lock_irqsave(&gpio_lock, flags); 575 582 if (!test_bit(FLAG_REQUESTED, &desc->flags) || ··· 792 783 { 793 784 int status; 794 785 struct device *dev; 786 + struct gpio_desc *desc; 787 + unsigned int i; 795 788 796 789 mutex_lock(&sysfs_lock); 797 790 dev = class_find_device(&gpio_class, NULL, chip, match_export); 798 791 if (dev) { 799 792 put_device(dev); 800 793 device_unregister(dev); 794 + /* prevent further gpiod exports */ 801 795 chip->exported = false; 802 796 status = 0; 803 797 } else ··· 809 797 810 798 if (status) 811 799 chip_dbg(chip, "%s: status %d\n", __func__, status); 800 + 801 + /* unregister gpiod class devices owned by sysfs */ 802 + for (i = 0; i < chip->ngpio; i++) { 803 + desc = &chip->desc[i]; 804 + if (test_and_clear_bit(FLAG_SYSFS, &desc->flags)) 805 + gpiod_free(desc); 806 + } 812 807 } 813 808 814 809 static int __init gpiolib_sysfs_init(void)
+7 -6
drivers/pinctrl/qcom/pinctrl-spmi-gpio.c
··· 418 418 return ret; 419 419 420 420 val = pad->buffer_type << PMIC_GPIO_REG_OUT_TYPE_SHIFT; 421 - val = pad->strength << PMIC_GPIO_REG_OUT_STRENGTH_SHIFT; 421 + val |= pad->strength << PMIC_GPIO_REG_OUT_STRENGTH_SHIFT; 422 422 423 423 ret = pmic_gpio_write(state, pad, PMIC_GPIO_REG_DIG_OUT_CTL, val); 424 424 if (ret < 0) ··· 467 467 seq_puts(s, " ---"); 468 468 } else { 469 469 470 - if (!pad->input_enabled) { 470 + if (pad->input_enabled) { 471 471 ret = pmic_gpio_read(state, pad, PMIC_MPP_REG_RT_STS); 472 - if (!ret) { 473 - ret &= PMIC_MPP_REG_RT_STS_VAL_MASK; 474 - pad->out_value = ret; 475 - } 472 + if (ret < 0) 473 + return; 474 + 475 + ret &= PMIC_MPP_REG_RT_STS_VAL_MASK; 476 + pad->out_value = ret; 476 477 } 477 478 478 479 seq_printf(s, " %-4s", pad->output_enabled ? "out" : "in");