Skip to content

Commit 41c64bb

Browse files
committed
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
2 parents a8a0811 + d2d05c6 commit 41c64bb

File tree

4 files changed

+36
-46
lines changed

4 files changed

+36
-46
lines changed

drivers/gpio/gpio-omap.c

Lines changed: 9 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1054,38 +1054,8 @@ static void omap_gpio_mod_init(struct gpio_bank *bank)
10541054
dev_err(bank->dev, "Could not get gpio dbck\n");
10551055
}
10561056

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-
10861057
static int omap_gpio_chip_init(struct gpio_bank *bank, struct irq_chip *irqc)
10871058
{
1088-
int j;
10891059
static int gpio;
10901060
int irq_base = 0;
10911061
int ret;
@@ -1132,6 +1102,15 @@ static int omap_gpio_chip_init(struct gpio_bank *bank, struct irq_chip *irqc)
11321102
}
11331103
#endif
11341104

1105+
/* MPUIO is a bit different, reading IRQ status clears it */
1106+
if (bank->is_mpuio) {
1107+
irqc->irq_ack = dummy_irq_chip.irq_ack;
1108+
irqc->irq_mask = irq_gc_mask_set_bit;
1109+
irqc->irq_unmask = irq_gc_mask_clr_bit;
1110+
if (!bank->regs->wkup_en)
1111+
irqc->irq_set_wake = NULL;
1112+
}
1113+
11351114
ret = gpiochip_irqchip_add(&bank->chip, irqc,
11361115
irq_base, omap_gpio_irq_handler,
11371116
IRQ_TYPE_NONE);
@@ -1145,15 +1124,6 @@ static int omap_gpio_chip_init(struct gpio_bank *bank, struct irq_chip *irqc)
11451124
gpiochip_set_chained_irqchip(&bank->chip, irqc,
11461125
bank->irq, omap_gpio_irq_handler);
11471126

1148-
for (j = 0; j < bank->width; j++) {
1149-
int irq = irq_find_mapping(bank->chip.irqdomain, j);
1150-
if (bank->is_mpuio) {
1151-
omap_mpuio_alloc_gc(bank, irq, bank->width);
1152-
irq_set_chip_and_handler(irq, NULL, NULL);
1153-
set_irq_flags(irq, 0);
1154-
}
1155-
}
1156-
11571127
return 0;
11581128
}
11591129

drivers/gpio/gpiolib-acpi.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -550,7 +550,7 @@ acpi_gpio_adr_space_handler(u32 function, acpi_physical_address address,
550550

551551
length = min(agpio->pin_table_length, (u16)(pin_index + bits));
552552
for (i = pin_index; i < length; ++i) {
553-
unsigned pin = agpio->pin_table[i];
553+
int pin = agpio->pin_table[i];
554554
struct acpi_gpio_connection *conn;
555555
struct gpio_desc *desc;
556556
bool found;

drivers/gpio/gpiolib-sysfs.c

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -551,6 +551,7 @@ static struct class gpio_class = {
551551
*/
552552
int gpiod_export(struct gpio_desc *desc, bool direction_may_change)
553553
{
554+
struct gpio_chip *chip;
554555
unsigned long flags;
555556
int status;
556557
const char *ioname = NULL;
@@ -568,8 +569,16 @@ int gpiod_export(struct gpio_desc *desc, bool direction_may_change)
568569
return -EINVAL;
569570
}
570571

572+
chip = desc->chip;
573+
571574
mutex_lock(&sysfs_lock);
572575

576+
/* check if chip is being removed */
577+
if (!chip || !chip->exported) {
578+
status = -ENODEV;
579+
goto fail_unlock;
580+
}
581+
573582
spin_lock_irqsave(&gpio_lock, flags);
574583
if (!test_bit(FLAG_REQUESTED, &desc->flags) ||
575584
test_bit(FLAG_EXPORT, &desc->flags)) {
@@ -783,12 +792,15 @@ void gpiochip_unexport(struct gpio_chip *chip)
783792
{
784793
int status;
785794
struct device *dev;
795+
struct gpio_desc *desc;
796+
unsigned int i;
786797

787798
mutex_lock(&sysfs_lock);
788799
dev = class_find_device(&gpio_class, NULL, chip, match_export);
789800
if (dev) {
790801
put_device(dev);
791802
device_unregister(dev);
803+
/* prevent further gpiod exports */
792804
chip->exported = false;
793805
status = 0;
794806
} else
@@ -797,6 +809,13 @@ void gpiochip_unexport(struct gpio_chip *chip)
797809

798810
if (status)
799811
chip_dbg(chip, "%s: status %d\n", __func__, status);
812+
813+
/* unregister gpiod class devices owned by sysfs */
814+
for (i = 0; i < chip->ngpio; i++) {
815+
desc = &chip->desc[i];
816+
if (test_and_clear_bit(FLAG_SYSFS, &desc->flags))
817+
gpiod_free(desc);
818+
}
800819
}
801820

802821
static int __init gpiolib_sysfs_init(void)

drivers/pinctrl/qcom/pinctrl-spmi-gpio.c

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -418,7 +418,7 @@ static int pmic_gpio_config_set(struct pinctrl_dev *pctldev, unsigned int pin,
418418
return ret;
419419

420420
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;
422422

423423
ret = pmic_gpio_write(state, pad, PMIC_GPIO_REG_DIG_OUT_CTL, val);
424424
if (ret < 0)
@@ -467,12 +467,13 @@ static void pmic_gpio_config_dbg_show(struct pinctrl_dev *pctldev,
467467
seq_puts(s, " ---");
468468
} else {
469469

470-
if (!pad->input_enabled) {
470+
if (pad->input_enabled) {
471471
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;
476477
}
477478

478479
seq_printf(s, " %-4s", pad->output_enabled ? "out" : "in");

0 commit comments

Comments
 (0)