These are some GPIO fixes for the v4.1 series:
- 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. -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQIcBAABAgAGBQJVTGkQAAoJEEEQszewGV1zDjcQAJLc5C0k53nc4oxA91B1Ldpn QbwKLCVrX7ex4zye4Qisw0vqPB1yZJD9yfuerNYQUJpoXFwHLGKr3925Q5NUCsRz 7d1zFfgfw+hdHXAZv02uOmZ+xx7E1tDl95CBU0GpkFo8yJ6gms+X5TonqWRLAwP4 2vIYjZdQLFpLI73lQ5eR3jYcMlrwCgGnPYeG5gR5Fp1dUmrpaZckhidoj7j1bxNk mCrv+xoGguIv/t9sUNXSusD4j1Rr0G/YX2RxbrWjTTSCCyuIV/b4MmwuTuD853sl I2AGiftGZOuDbaBuPRMa3371QXI2ZY7I27lUvvx2aEVKNkuxgFzqX0GSd1FUFdRc GZdLBVsiV1FZtXJ6rte5z18w7I+vn77GgyNQTs/0w6YS8ofWHeR2MQCF95g4uJhT YSo0/3O2bJxEoyQ1t2NQISSdG2/1BMxsOFejMITqxLgGYUYqL0D739aatiq53HCt vlmn7npUvik1r804Tun/isqkv8IRXHf3Dhy31mPFmlYRIR4sm9vuEk2SWoWcadDi BH+ej6YmYloklKwoj2yiC7MtOl4N+hPvLDZmZvich16eJc0BI1Wu9QfTTJ+pH895 R5twBPioRmE67Mg+edMCrsmDv6a8ECaUnf/ODLg0qYHreE9MplSi98JJw+lfTAxb DWLng7tcgp8SV+6gW5pc =xfL0 -----END PGP SIGNATURE----- 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
This commit is contained in:
commit
41c64bb19c
@ -1054,38 +1054,8 @@ static void omap_gpio_mod_init(struct gpio_bank *bank)
|
||||
dev_err(bank->dev, "Could not get gpio dbck\n");
|
||||
}
|
||||
|
||||
static void
|
||||
omap_mpuio_alloc_gc(struct gpio_bank *bank, unsigned int irq_start,
|
||||
unsigned int num)
|
||||
{
|
||||
struct irq_chip_generic *gc;
|
||||
struct irq_chip_type *ct;
|
||||
|
||||
gc = irq_alloc_generic_chip("MPUIO", 1, irq_start, bank->base,
|
||||
handle_simple_irq);
|
||||
if (!gc) {
|
||||
dev_err(bank->dev, "Memory alloc failed for gc\n");
|
||||
return;
|
||||
}
|
||||
|
||||
ct = gc->chip_types;
|
||||
|
||||
/* NOTE: No ack required, reading IRQ status clears it. */
|
||||
ct->chip.irq_mask = irq_gc_mask_set_bit;
|
||||
ct->chip.irq_unmask = irq_gc_mask_clr_bit;
|
||||
ct->chip.irq_set_type = omap_gpio_irq_type;
|
||||
|
||||
if (bank->regs->wkup_en)
|
||||
ct->chip.irq_set_wake = omap_gpio_wake_enable;
|
||||
|
||||
ct->regs.mask = OMAP_MPUIO_GPIO_INT / bank->stride;
|
||||
irq_setup_generic_chip(gc, IRQ_MSK(num), IRQ_GC_INIT_MASK_CACHE,
|
||||
IRQ_NOREQUEST | IRQ_NOPROBE, 0);
|
||||
}
|
||||
|
||||
static int omap_gpio_chip_init(struct gpio_bank *bank, struct irq_chip *irqc)
|
||||
{
|
||||
int j;
|
||||
static int gpio;
|
||||
int irq_base = 0;
|
||||
int ret;
|
||||
@ -1132,6 +1102,15 @@ static int omap_gpio_chip_init(struct gpio_bank *bank, struct irq_chip *irqc)
|
||||
}
|
||||
#endif
|
||||
|
||||
/* MPUIO is a bit different, reading IRQ status clears it */
|
||||
if (bank->is_mpuio) {
|
||||
irqc->irq_ack = dummy_irq_chip.irq_ack;
|
||||
irqc->irq_mask = irq_gc_mask_set_bit;
|
||||
irqc->irq_unmask = irq_gc_mask_clr_bit;
|
||||
if (!bank->regs->wkup_en)
|
||||
irqc->irq_set_wake = NULL;
|
||||
}
|
||||
|
||||
ret = gpiochip_irqchip_add(&bank->chip, irqc,
|
||||
irq_base, omap_gpio_irq_handler,
|
||||
IRQ_TYPE_NONE);
|
||||
@ -1145,15 +1124,6 @@ static int omap_gpio_chip_init(struct gpio_bank *bank, struct irq_chip *irqc)
|
||||
gpiochip_set_chained_irqchip(&bank->chip, irqc,
|
||||
bank->irq, omap_gpio_irq_handler);
|
||||
|
||||
for (j = 0; j < bank->width; j++) {
|
||||
int irq = irq_find_mapping(bank->chip.irqdomain, j);
|
||||
if (bank->is_mpuio) {
|
||||
omap_mpuio_alloc_gc(bank, irq, bank->width);
|
||||
irq_set_chip_and_handler(irq, NULL, NULL);
|
||||
set_irq_flags(irq, 0);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -550,7 +550,7 @@ acpi_gpio_adr_space_handler(u32 function, acpi_physical_address address,
|
||||
|
||||
length = min(agpio->pin_table_length, (u16)(pin_index + bits));
|
||||
for (i = pin_index; i < length; ++i) {
|
||||
unsigned pin = agpio->pin_table[i];
|
||||
int pin = agpio->pin_table[i];
|
||||
struct acpi_gpio_connection *conn;
|
||||
struct gpio_desc *desc;
|
||||
bool found;
|
||||
|
@ -551,6 +551,7 @@ static struct class gpio_class = {
|
||||
*/
|
||||
int gpiod_export(struct gpio_desc *desc, bool direction_may_change)
|
||||
{
|
||||
struct gpio_chip *chip;
|
||||
unsigned long flags;
|
||||
int status;
|
||||
const char *ioname = NULL;
|
||||
@ -568,8 +569,16 @@ int gpiod_export(struct gpio_desc *desc, bool direction_may_change)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
chip = desc->chip;
|
||||
|
||||
mutex_lock(&sysfs_lock);
|
||||
|
||||
/* check if chip is being removed */
|
||||
if (!chip || !chip->exported) {
|
||||
status = -ENODEV;
|
||||
goto fail_unlock;
|
||||
}
|
||||
|
||||
spin_lock_irqsave(&gpio_lock, flags);
|
||||
if (!test_bit(FLAG_REQUESTED, &desc->flags) ||
|
||||
test_bit(FLAG_EXPORT, &desc->flags)) {
|
||||
@ -783,12 +792,15 @@ void gpiochip_unexport(struct gpio_chip *chip)
|
||||
{
|
||||
int status;
|
||||
struct device *dev;
|
||||
struct gpio_desc *desc;
|
||||
unsigned int i;
|
||||
|
||||
mutex_lock(&sysfs_lock);
|
||||
dev = class_find_device(&gpio_class, NULL, chip, match_export);
|
||||
if (dev) {
|
||||
put_device(dev);
|
||||
device_unregister(dev);
|
||||
/* prevent further gpiod exports */
|
||||
chip->exported = false;
|
||||
status = 0;
|
||||
} else
|
||||
@ -797,6 +809,13 @@ void gpiochip_unexport(struct gpio_chip *chip)
|
||||
|
||||
if (status)
|
||||
chip_dbg(chip, "%s: status %d\n", __func__, status);
|
||||
|
||||
/* unregister gpiod class devices owned by sysfs */
|
||||
for (i = 0; i < chip->ngpio; i++) {
|
||||
desc = &chip->desc[i];
|
||||
if (test_and_clear_bit(FLAG_SYSFS, &desc->flags))
|
||||
gpiod_free(desc);
|
||||
}
|
||||
}
|
||||
|
||||
static int __init gpiolib_sysfs_init(void)
|
||||
|
@ -418,7 +418,7 @@ static int pmic_gpio_config_set(struct pinctrl_dev *pctldev, unsigned int pin,
|
||||
return ret;
|
||||
|
||||
val = pad->buffer_type << PMIC_GPIO_REG_OUT_TYPE_SHIFT;
|
||||
val = pad->strength << PMIC_GPIO_REG_OUT_STRENGTH_SHIFT;
|
||||
val |= pad->strength << PMIC_GPIO_REG_OUT_STRENGTH_SHIFT;
|
||||
|
||||
ret = pmic_gpio_write(state, pad, PMIC_GPIO_REG_DIG_OUT_CTL, val);
|
||||
if (ret < 0)
|
||||
@ -467,12 +467,13 @@ static void pmic_gpio_config_dbg_show(struct pinctrl_dev *pctldev,
|
||||
seq_puts(s, " ---");
|
||||
} else {
|
||||
|
||||
if (!pad->input_enabled) {
|
||||
if (pad->input_enabled) {
|
||||
ret = pmic_gpio_read(state, pad, PMIC_MPP_REG_RT_STS);
|
||||
if (!ret) {
|
||||
ret &= PMIC_MPP_REG_RT_STS_VAL_MASK;
|
||||
pad->out_value = ret;
|
||||
}
|
||||
if (ret < 0)
|
||||
return;
|
||||
|
||||
ret &= PMIC_MPP_REG_RT_STS_VAL_MASK;
|
||||
pad->out_value = ret;
|
||||
}
|
||||
|
||||
seq_printf(s, " %-4s", pad->output_enabled ? "out" : "in");
|
||||
|
Loading…
Reference in New Issue
Block a user