diff options
Diffstat (limited to 'drivers/gpio')
-rw-r--r-- | drivers/gpio/Kconfig | 18 | ||||
-rw-r--r-- | drivers/gpio/Makefile | 2 | ||||
-rw-r--r-- | drivers/gpio/gpio-eic-sprd.c | 23 | ||||
-rw-r--r-- | drivers/gpio/gpio-ep93xx.c | 38 | ||||
-rw-r--r-- | drivers/gpio/gpio-iop.c | 59 | ||||
-rw-r--r-- | drivers/gpio/gpio-mxc.c | 16 | ||||
-rw-r--r-- | drivers/gpio/gpio-pca953x.c | 3 | ||||
-rw-r--r-- | drivers/gpio/gpio-pmic-eic-sprd.c | 29 | ||||
-rw-r--r-- | drivers/gpio/gpio-sifive.c | 1 | ||||
-rw-r--r-- | drivers/gpio/gpio-sim.c | 2 | ||||
-rw-r--r-- | drivers/gpio/gpio-sprd.c | 9 | ||||
-rw-r--r-- | drivers/gpio/gpio-ucb1400.c | 85 | ||||
-rw-r--r-- | drivers/gpio/gpio-vf610.c | 41 | ||||
-rw-r--r-- | drivers/gpio/gpiolib-acpi.c | 32 | ||||
-rw-r--r-- | drivers/gpio/gpiolib-acpi.h | 1 | ||||
-rw-r--r-- | drivers/gpio/gpiolib.c | 2 |
16 files changed, 133 insertions, 228 deletions
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index ec7cfd4f52b1..c85726a6831f 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -354,16 +354,6 @@ config GPIO_IMX_SCU def_bool y depends on IMX_SCU -config GPIO_IOP - tristate "Intel IOP GPIO" - depends on ARCH_IOP32X || COMPILE_TEST - select GPIO_GENERIC - help - Say yes here to support the GPIO functionality of a number of Intel - IOP32X or IOP33X series of chips. - - If unsure, say N. - config GPIO_IXP4XX bool "Intel IXP4xx GPIO" depends on ARCH_IXP4XX @@ -1438,13 +1428,6 @@ config GPIO_TWL6040 Say yes here to access the GPO signals of twl6040 audio chip from Texas Instruments. -config GPIO_UCB1400 - tristate "Philips UCB1400 GPIO" - depends on UCB1400_CORE - help - This enables support for the Philips UCB1400 GPIO pins. - The UCB1400 is an AC97 audio codec. - config GPIO_WHISKEY_COVE tristate "GPIO support for Whiskey Cove PMIC" depends on (X86 || COMPILE_TEST) && INTEL_SOC_PMIC_BXTWC @@ -1531,6 +1514,7 @@ config GPIO_MLXBF2 tristate "Mellanox BlueField 2 SoC GPIO" depends on (MELLANOX_PLATFORM && ARM64 && ACPI) || (64BIT && COMPILE_TEST) select GPIO_GENERIC + select GPIOLIB_IRQCHIP help Say Y here if you want GPIO support on Mellanox BlueField 2 SoC. diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile index 010587025fc8..c048ba003367 100644 --- a/drivers/gpio/Makefile +++ b/drivers/gpio/Makefile @@ -72,7 +72,6 @@ obj-$(CONFIG_GPIO_ICH) += gpio-ich.o obj-$(CONFIG_GPIO_IDIO_16) += gpio-idio-16.o obj-$(CONFIG_GPIO_IDT3243X) += gpio-idt3243x.o obj-$(CONFIG_GPIO_IMX_SCU) += gpio-imx-scu.o -obj-$(CONFIG_GPIO_IOP) += gpio-iop.o obj-$(CONFIG_GPIO_IT87) += gpio-it87.o obj-$(CONFIG_GPIO_IXP4XX) += gpio-ixp4xx.o obj-$(CONFIG_GPIO_JANZ_TTL) += gpio-janz-ttl.o @@ -166,7 +165,6 @@ obj-$(CONFIG_GPIO_TS4900) += gpio-ts4900.o obj-$(CONFIG_GPIO_TS5500) += gpio-ts5500.o obj-$(CONFIG_GPIO_TWL4030) += gpio-twl4030.o obj-$(CONFIG_GPIO_TWL6040) += gpio-twl6040.o -obj-$(CONFIG_GPIO_UCB1400) += gpio-ucb1400.o obj-$(CONFIG_GPIO_UNIPHIER) += gpio-uniphier.o obj-$(CONFIG_GPIO_VF610) += gpio-vf610.o obj-$(CONFIG_GPIO_VIPERBOARD) += gpio-viperboard.o diff --git a/drivers/gpio/gpio-eic-sprd.c b/drivers/gpio/gpio-eic-sprd.c index 8d722e026e9c..84352a6f4973 100644 --- a/drivers/gpio/gpio-eic-sprd.c +++ b/drivers/gpio/gpio-eic-sprd.c @@ -91,7 +91,6 @@ enum sprd_eic_type { struct sprd_eic { struct gpio_chip chip; - struct irq_chip intc; void __iomem *base[SPRD_EIC_MAX_BANK]; enum sprd_eic_type type; spinlock_t lock; @@ -255,6 +254,8 @@ static void sprd_eic_irq_mask(struct irq_data *data) default: dev_err(chip->parent, "Unsupported EIC type.\n"); } + + gpiochip_disable_irq(chip, offset); } static void sprd_eic_irq_unmask(struct irq_data *data) @@ -263,6 +264,8 @@ static void sprd_eic_irq_unmask(struct irq_data *data) struct sprd_eic *sprd_eic = gpiochip_get_data(chip); u32 offset = irqd_to_hwirq(data); + gpiochip_enable_irq(chip, offset); + switch (sprd_eic->type) { case SPRD_EIC_DEBOUNCE: sprd_eic_update(chip, offset, SPRD_EIC_DBNC_IE, 1); @@ -564,6 +567,15 @@ static void sprd_eic_irq_handler(struct irq_desc *desc) chained_irq_exit(ic, desc); } +static const struct irq_chip sprd_eic_irq = { + .name = "sprd-eic", + .irq_ack = sprd_eic_irq_ack, + .irq_mask = sprd_eic_irq_mask, + .irq_unmask = sprd_eic_irq_unmask, + .irq_set_type = sprd_eic_irq_set_type, + .flags = IRQCHIP_SKIP_SET_WAKE | IRQCHIP_IMMUTABLE, + GPIOCHIP_IRQ_RESOURCE_HELPERS, +}; static int sprd_eic_probe(struct platform_device *pdev) { const struct sprd_eic_variant_data *pdata; @@ -626,15 +638,8 @@ static int sprd_eic_probe(struct platform_device *pdev) break; } - sprd_eic->intc.name = dev_name(&pdev->dev); - sprd_eic->intc.irq_ack = sprd_eic_irq_ack; - sprd_eic->intc.irq_mask = sprd_eic_irq_mask; - sprd_eic->intc.irq_unmask = sprd_eic_irq_unmask; - sprd_eic->intc.irq_set_type = sprd_eic_irq_set_type; - sprd_eic->intc.flags = IRQCHIP_SKIP_SET_WAKE; - irq = &sprd_eic->chip.irq; - irq->chip = &sprd_eic->intc; + gpio_irq_chip_set_chip(irq, &sprd_eic_irq); irq->handler = handle_bad_irq; irq->default_type = IRQ_TYPE_NONE; irq->parent_handler = sprd_eic_irq_handler; diff --git a/drivers/gpio/gpio-ep93xx.c b/drivers/gpio/gpio-ep93xx.c index 2e1779709113..6cedf46efec6 100644 --- a/drivers/gpio/gpio-ep93xx.c +++ b/drivers/gpio/gpio-ep93xx.c @@ -17,6 +17,7 @@ #include <linux/slab.h> #include <linux/gpio/driver.h> #include <linux/bitops.h> +#include <linux/seq_file.h> #define EP93XX_GPIO_F_INT_STATUS 0x5c #define EP93XX_GPIO_A_INT_STATUS 0xa0 @@ -40,7 +41,6 @@ #define EP93XX_GPIO_F_IRQ_BASE 80 struct ep93xx_gpio_irq_chip { - struct irq_chip ic; u8 irq_offset; u8 int_unmasked; u8 int_enabled; @@ -148,7 +148,7 @@ static void ep93xx_gpio_f_irq_handler(struct irq_desc *desc) */ struct irq_chip *irqchip = irq_desc_get_chip(desc); unsigned int irq = irq_desc_get_irq(desc); - int port_f_idx = ((irq + 1) & 7) ^ 4; /* {19..22,47..50} -> {0..7} */ + int port_f_idx = (irq & 7) ^ 4; /* {20..23,48..51} -> {0..7} */ int gpio_irq = EP93XX_GPIO_F_IRQ_BASE + port_f_idx; chained_irq_enter(irqchip, desc); @@ -185,6 +185,7 @@ static void ep93xx_gpio_irq_mask_ack(struct irq_data *d) ep93xx_gpio_update_int_params(epg, eic); writeb(port_mask, epg->base + eic->irq_offset + EP93XX_INT_EOI_OFFSET); + gpiochip_disable_irq(gc, irqd_to_hwirq(d)); } static void ep93xx_gpio_irq_mask(struct irq_data *d) @@ -195,6 +196,7 @@ static void ep93xx_gpio_irq_mask(struct irq_data *d) eic->int_unmasked &= ~BIT(d->irq & 7); ep93xx_gpio_update_int_params(epg, eic); + gpiochip_disable_irq(gc, irqd_to_hwirq(d)); } static void ep93xx_gpio_irq_unmask(struct irq_data *d) @@ -203,6 +205,7 @@ static void ep93xx_gpio_irq_unmask(struct irq_data *d) struct ep93xx_gpio_irq_chip *eic = to_ep93xx_gpio_irq_chip(gc); struct ep93xx_gpio *epg = gpiochip_get_data(gc); + gpiochip_enable_irq(gc, irqd_to_hwirq(d)); eic->int_unmasked |= BIT(d->irq & 7); ep93xx_gpio_update_int_params(epg, eic); } @@ -320,15 +323,25 @@ static int ep93xx_gpio_set_config(struct gpio_chip *gc, unsigned offset, return 0; } -static void ep93xx_init_irq_chip(struct device *dev, struct irq_chip *ic) +static void ep93xx_irq_print_chip(struct irq_data *data, struct seq_file *p) { - ic->irq_ack = ep93xx_gpio_irq_ack; - ic->irq_mask_ack = ep93xx_gpio_irq_mask_ack; - ic->irq_mask = ep93xx_gpio_irq_mask; - ic->irq_unmask = ep93xx_gpio_irq_unmask; - ic->irq_set_type = ep93xx_gpio_irq_type; + struct gpio_chip *gc = irq_data_get_irq_chip_data(data); + + seq_printf(p, dev_name(gc->parent)); } +static const struct irq_chip gpio_eic_irq_chip = { + .name = "ep93xx-gpio-eic", + .irq_ack = ep93xx_gpio_irq_ack, + .irq_mask = ep93xx_gpio_irq_mask, + .irq_unmask = ep93xx_gpio_irq_unmask, + .irq_mask_ack = ep93xx_gpio_irq_mask_ack, + .irq_set_type = ep93xx_gpio_irq_type, + .irq_print_chip = ep93xx_irq_print_chip, + .flags = IRQCHIP_IMMUTABLE, + GPIOCHIP_IRQ_RESOURCE_HELPERS, +}; + static int ep93xx_gpio_add_bank(struct ep93xx_gpio_chip *egc, struct platform_device *pdev, struct ep93xx_gpio *epg, @@ -350,8 +363,6 @@ static int ep93xx_gpio_add_bank(struct ep93xx_gpio_chip *egc, girq = &gc->irq; if (bank->has_irq || bank->has_hierarchical_irq) { - struct irq_chip *ic; - gc->set_config = ep93xx_gpio_set_config; egc->eic = devm_kcalloc(dev, 1, sizeof(*egc->eic), @@ -359,12 +370,7 @@ static int ep93xx_gpio_add_bank(struct ep93xx_gpio_chip *egc, if (!egc->eic) return -ENOMEM; egc->eic->irq_offset = bank->irq; - ic = &egc->eic->ic; - ic->name = devm_kasprintf(dev, GFP_KERNEL, "gpio-irq-%s", bank->label); - if (!ic->name) - return -ENOMEM; - ep93xx_init_irq_chip(dev, ic); - girq->chip = ic; + gpio_irq_chip_set_chip(girq, &gpio_eic_irq_chip); } if (bank->has_irq) { diff --git a/drivers/gpio/gpio-iop.c b/drivers/gpio/gpio-iop.c deleted file mode 100644 index 7390b5ca09e3..000000000000 --- a/drivers/gpio/gpio-iop.c +++ /dev/null @@ -1,59 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * arch/arm/plat-iop/gpio.c - * GPIO handling for Intel IOP3xx processors. - * - * Copyright (C) 2006 Lennert Buytenhek <buytenh@wantstofly.org> - */ - -#include <linux/err.h> -#include <linux/module.h> -#include <linux/gpio/driver.h> -#include <linux/platform_device.h> - -#define IOP3XX_GPOE 0x0000 -#define IOP3XX_GPID 0x0004 -#define IOP3XX_GPOD 0x0008 - -static int iop3xx_gpio_probe(struct platform_device *pdev) -{ - struct gpio_chip *gc; - void __iomem *base; - int err; - - gc = devm_kzalloc(&pdev->dev, sizeof(*gc), GFP_KERNEL); - if (!gc) - return -ENOMEM; - - base = devm_platform_ioremap_resource(pdev, 0); - if (IS_ERR(base)) - return PTR_ERR(base); - - err = bgpio_init(gc, &pdev->dev, 1, base + IOP3XX_GPID, - base + IOP3XX_GPOD, NULL, NULL, base + IOP3XX_GPOE, 0); - if (err) - return err; - - gc->base = 0; - gc->owner = THIS_MODULE; - gc->label = "gpio-iop"; - - return devm_gpiochip_add_data(&pdev->dev, gc, NULL); -} - -static struct platform_driver iop3xx_gpio_driver = { - .driver = { - .name = "gpio-iop", - }, - .probe = iop3xx_gpio_probe, -}; - -static int __init iop3xx_gpio_init(void) -{ - return platform_driver_register(&iop3xx_gpio_driver); -} -arch_initcall(iop3xx_gpio_init); - -MODULE_DESCRIPTION("GPIO handling for Intel IOP3xx processors"); -MODULE_AUTHOR("Lennert Buytenhek <buytenh@wantstofly.org>"); -MODULE_LICENSE("GPL"); diff --git a/drivers/gpio/gpio-mxc.c b/drivers/gpio/gpio-mxc.c index d5626c572d24..9d0cec4b82a3 100644 --- a/drivers/gpio/gpio-mxc.c +++ b/drivers/gpio/gpio-mxc.c @@ -18,6 +18,7 @@ #include <linux/module.h> #include <linux/platform_device.h> #include <linux/slab.h> +#include <linux/spinlock.h> #include <linux/syscore_ops.h> #include <linux/gpio/driver.h> #include <linux/of.h> @@ -159,6 +160,7 @@ static int gpio_set_irq_type(struct irq_data *d, u32 type) { struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); struct mxc_gpio_port *port = gc->private; + unsigned long flags; u32 bit, val; u32 gpio_idx = d->hwirq; int edge; @@ -197,6 +199,8 @@ static int gpio_set_irq_type(struct irq_data *d, u32 type) return -EINVAL; } + raw_spin_lock_irqsave(&port->gc.bgpio_lock, flags); + if (GPIO_EDGE_SEL >= 0) { val = readl(port->base + GPIO_EDGE_SEL); if (edge == GPIO_INT_BOTH_EDGES) @@ -217,15 +221,20 @@ static int gpio_set_irq_type(struct irq_data *d, u32 type) writel(1 << gpio_idx, port->base + GPIO_ISR); port->pad_type[gpio_idx] = type; - return 0; + raw_spin_unlock_irqrestore(&port->gc.bgpio_lock, flags); + + return port->gc.direction_input(&port->gc, gpio_idx); } static void mxc_flip_edge(struct mxc_gpio_port *port, u32 gpio) { void __iomem *reg = port->base; + unsigned long flags; u32 bit, val; int edge; + raw_spin_lock_irqsave(&port->gc.bgpio_lock, flags); + reg += GPIO_ICR1 + ((gpio & 0x10) >> 2); /* lower or upper register */ bit = gpio & 0xf; val = readl(reg); @@ -240,9 +249,12 @@ static void mxc_flip_edge(struct mxc_gpio_port *port, u32 gpio) } else { pr_err("mxc: invalid configuration for GPIO %d: %x\n", gpio, edge); - return; + goto unlock; } writel(val | (edge << (bit << 1)), reg); + +unlock: + raw_spin_unlock_irqrestore(&port->gc.bgpio_lock, flags); } /* handle 32 interrupts in one status register */ diff --git a/drivers/gpio/gpio-pca953x.c b/drivers/gpio/gpio-pca953x.c index a59d61cd44b2..5299e5bb76d6 100644 --- a/drivers/gpio/gpio-pca953x.c +++ b/drivers/gpio/gpio-pca953x.c @@ -474,6 +474,9 @@ static u8 pcal6534_recalc_addr(struct pca953x_chip *chip, int reg, int off) case PCAL6524_DEBOUNCE: pinctrl = ((reg & PCAL_PINCTRL_MASK) >> 1) + 0x1c; break; + default: + pinctrl = 0; + break; } return pinctrl + addr + (off / BANK_SZ); diff --git a/drivers/gpio/gpio-pmic-eic-sprd.c b/drivers/gpio/gpio-pmic-eic-sprd.c index e518490c4b68..c3e4d90f6b18 100644 --- a/drivers/gpio/gpio-pmic-eic-sprd.c +++ b/drivers/gpio/gpio-pmic-eic-sprd.c @@ -47,7 +47,6 @@ enum { /** * struct sprd_pmic_eic - PMIC EIC controller * @chip: the gpio_chip structure. - * @intc: the irq_chip structure. * @map: the regmap from the parent device. * @offset: the EIC controller's offset address of the PMIC. * @reg: the array to cache the EIC registers. @@ -56,7 +55,6 @@ enum { */ struct sprd_pmic_eic { struct gpio_chip chip; - struct irq_chip intc; struct regmap *map; u32 offset; u8 reg[CACHE_NR_REGS]; @@ -151,15 +149,21 @@ static void sprd_pmic_eic_irq_mask(struct irq_data *data) { struct gpio_chip *chip = irq_data_get_irq_chip_data(data); struct sprd_pmic_eic *pmic_eic = gpiochip_get_data(chip); + u32 offset = irqd_to_hwirq(data); pmic_eic->reg[REG_IE] = 0; pmic_eic->reg[REG_TRIG] = 0; + + gpiochip_disable_irq(chip, offset); } static void sprd_pmic_eic_irq_unmask(struct irq_data *data) { struct gpio_chip *chip = irq_data_get_irq_chip_data(data); struct sprd_pmic_eic *pmic_eic = gpiochip_get_data(chip); + u32 offset = irqd_to_hwirq(data); + + gpiochip_enable_irq(chip, offset); pmic_eic->reg[REG_IE] = 1; pmic_eic->reg[REG_TRIG] = 1; @@ -292,6 +296,17 @@ static irqreturn_t sprd_pmic_eic_irq_handler(int irq, void *data) return IRQ_HANDLED; } +static const struct irq_chip pmic_eic_irq_chip = { + .name = "sprd-pmic-eic", + .irq_mask = sprd_pmic_eic_irq_mask, + .irq_unmask = sprd_pmic_eic_irq_unmask, + .irq_set_type = sprd_pmic_eic_irq_set_type, + .irq_bus_lock = sprd_pmic_eic_bus_lock, + .irq_bus_sync_unlock = sprd_pmic_eic_bus_sync_unlock, + .flags = IRQCHIP_SKIP_SET_WAKE | IRQCHIP_IMMUTABLE, + GPIOCHIP_IRQ_RESOURCE_HELPERS, +}; + static int sprd_pmic_eic_probe(struct platform_device *pdev) { struct gpio_irq_chip *irq; @@ -338,16 +353,8 @@ static int sprd_pmic_eic_probe(struct platform_device *pdev) pmic_eic->chip.set = sprd_pmic_eic_set; pmic_eic->chip.get = sprd_pmic_eic_get; - pmic_eic->intc.name = dev_name(&pdev->dev); - pmic_eic->intc.irq_mask = sprd_pmic_eic_irq_mask; - pmic_eic->intc.irq_unmask = sprd_pmic_eic_irq_unmask; - pmic_eic->intc.irq_set_type = sprd_pmic_eic_irq_set_type; - pmic_eic->intc.irq_bus_lock = sprd_pmic_eic_bus_lock; - pmic_eic->intc.irq_bus_sync_unlock = sprd_pmic_eic_bus_sync_unlock; - pmic_eic->intc.flags = IRQCHIP_SKIP_SET_WAKE; - irq = &pmic_eic->chip.irq; - irq->chip = &pmic_eic->intc; + gpio_irq_chip_set_chip(irq, &pmic_eic_irq_chip); irq->threaded = true; ret = devm_gpiochip_add_data(&pdev->dev, &pmic_eic->chip, pmic_eic); diff --git a/drivers/gpio/gpio-sifive.c b/drivers/gpio/gpio-sifive.c index 238f3210970c..bc5660f61c57 100644 --- a/drivers/gpio/gpio-sifive.c +++ b/drivers/gpio/gpio-sifive.c @@ -215,6 +215,7 @@ static int sifive_gpio_probe(struct platform_device *pdev) return -ENODEV; } parent = irq_find_host(irq_parent); + of_node_put(irq_parent); if (!parent) { dev_err(dev, "no IRQ parent domain\n"); return -ENODEV; diff --git a/drivers/gpio/gpio-sim.c b/drivers/gpio/gpio-sim.c index 60514bc5454f..9e3893b19e4f 100644 --- a/drivers/gpio/gpio-sim.c +++ b/drivers/gpio/gpio-sim.c @@ -736,7 +736,7 @@ static void gpio_sim_remove_hogs(struct gpio_sim_device *dev) gpiod_remove_hogs(dev->hogs); - for (hog = dev->hogs; !hog->chip_label; hog++) { + for (hog = dev->hogs; hog->chip_label; hog++) { kfree(hog->chip_label); kfree(hog->line_name); } diff --git a/drivers/gpio/gpio-sprd.c b/drivers/gpio/gpio-sprd.c index 9bff63990eee..072b4e653216 100644 --- a/drivers/gpio/gpio-sprd.c +++ b/drivers/gpio/gpio-sprd.c @@ -120,6 +120,7 @@ static void sprd_gpio_irq_mask(struct irq_data *data) u32 offset = irqd_to_hwirq(data); sprd_gpio_update(chip, offset, SPRD_GPIO_IE, 0); + gpiochip_disable_irq(chip, offset); } static void sprd_gpio_irq_ack(struct irq_data *data) @@ -136,6 +137,7 @@ static void sprd_gpio_irq_unmask(struct irq_data *data) u32 offset = irqd_to_hwirq(data); sprd_gpio_update(chip, offset, SPRD_GPIO_IE, 1); + gpiochip_enable_irq(chip, offset); } static int sprd_gpio_irq_set_type(struct irq_data *data, @@ -205,13 +207,14 @@ static void sprd_gpio_irq_handler(struct irq_desc *desc) chained_irq_exit(ic, desc); } -static struct irq_chip sprd_gpio_irqchip = { +static const struct irq_chip sprd_gpio_irqchip = { .name = "sprd-gpio", .irq_ack = sprd_gpio_irq_ack, .irq_mask = sprd_gpio_irq_mask, .irq_unmask = sprd_gpio_irq_unmask, .irq_set_type = sprd_gpio_irq_set_type, - .flags = IRQCHIP_SKIP_SET_WAKE, + .flags = IRQCHIP_SKIP_SET_WAKE | IRQCHIP_IMMUTABLE, + GPIOCHIP_IRQ_RESOURCE_HELPERS, }; static int sprd_gpio_probe(struct platform_device *pdev) @@ -245,7 +248,7 @@ static int sprd_gpio_probe(struct platform_device *pdev) sprd_gpio->chip.direction_output = sprd_gpio_direction_output; irq = &sprd_gpio->chip.irq; - irq->chip = &sprd_gpio_irqchip; + gpio_irq_chip_set_chip(irq, &sprd_gpio_irqchip); irq->handler = handle_bad_irq; irq->default_type = IRQ_TYPE_NONE; irq->parent_handler = sprd_gpio_irq_handler; diff --git a/drivers/gpio/gpio-ucb1400.c b/drivers/gpio/gpio-ucb1400.c deleted file mode 100644 index 676adf1f198a..000000000000 --- a/drivers/gpio/gpio-ucb1400.c +++ /dev/null @@ -1,85 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Philips UCB1400 GPIO driver - * - * Author: Marek Vasut <marek.vasut@gmail.com> - */ - -#include <linux/module.h> -#include <linux/ucb1400.h> -#include <linux/gpio/driver.h> - -static int ucb1400_gpio_dir_in(struct gpio_chip *gc, unsigned off) -{ - struct ucb1400_gpio *gpio; - gpio = gpiochip_get_data(gc); - ucb1400_gpio_set_direction(gpio->ac97, off, 0); - return 0; -} - -static int ucb1400_gpio_dir_out(struct gpio_chip *gc, unsigned off, int val) -{ - struct ucb1400_gpio *gpio; - gpio = gpiochip_get_data(gc); - ucb1400_gpio_set_direction(gpio->ac97, off, 1); - ucb1400_gpio_set_value(gpio->ac97, off, val); - return 0; -} - -static int ucb1400_gpio_get(struct gpio_chip *gc, unsigned off) -{ - struct ucb1400_gpio *gpio; - - gpio = gpiochip_get_data(gc); - return !!ucb1400_gpio_get_value(gpio->ac97, off); -} - -static void ucb1400_gpio_set(struct gpio_chip *gc, unsigned off, int val) -{ - struct ucb1400_gpio *gpio; - gpio = gpiochip_get_data(gc); - ucb1400_gpio_set_value(gpio->ac97, off, val); -} - -static int ucb1400_gpio_probe(struct platform_device *dev) -{ - struct ucb1400_gpio *ucb = dev_get_platdata(&dev->dev); - int err = 0; - - if (!(ucb && ucb->gpio_offset)) { - err = -EINVAL; - goto err; - } - - platform_set_drvdata(dev, ucb); - - ucb->gc.label = "ucb1400_gpio"; - ucb->gc.base = ucb->gpio_offset; - ucb->gc.ngpio = 10; - ucb->gc.owner = THIS_MODULE; - - ucb->gc.direction_input = ucb1400_gpio_dir_in; - ucb->gc.direction_output = ucb1400_gpio_dir_out; - ucb->gc.get = ucb1400_gpio_get; - ucb->gc.set = ucb1400_gpio_set; - ucb->gc.can_sleep = true; - - err = devm_gpiochip_add_data(&dev->dev, &ucb->gc, ucb); - -err: - return err; - -} - -static struct platform_driver ucb1400_gpio_driver = { - .probe = ucb1400_gpio_probe, - .driver = { - .name = "ucb1400_gpio" - }, -}; - -module_platform_driver(ucb1400_gpio_driver); - -MODULE_DESCRIPTION("Philips UCB1400 GPIO driver"); -MODULE_LICENSE("GPL"); -MODULE_ALIAS("platform:ucb1400_gpio"); diff --git a/drivers/gpio/gpio-vf610.c b/drivers/gpio/gpio-vf610.c index 9db42f6a2043..9033db00c360 100644 --- a/drivers/gpio/gpio-vf610.c +++ b/drivers/gpio/gpio-vf610.c @@ -30,7 +30,6 @@ struct fsl_gpio_soc_data { struct vf610_gpio_port { struct gpio_chip gc; - struct irq_chip ic; void __iomem *base; void __iomem *gpio_base; const struct fsl_gpio_soc_data *sdata; @@ -207,20 +206,24 @@ static int vf610_gpio_irq_set_type(struct irq_data *d, u32 type) static void vf610_gpio_irq_mask(struct irq_data *d) { - struct vf610_gpio_port *port = - gpiochip_get_data(irq_data_get_irq_chip_data(d)); - void __iomem *pcr_base = port->base + PORT_PCR(d->hwirq); + struct gpio_chip *gc = irq_data_get_irq_chip_data(d); + struct vf610_gpio_port *port = gpiochip_get_data(gc); + irq_hw_number_t gpio_num = irqd_to_hwirq(d); + void __iomem *pcr_base = port->base + PORT_PCR(gpio_num); vf610_gpio_writel(0, pcr_base); + gpiochip_disable_irq(gc, gpio_num); } static void vf610_gpio_irq_unmask(struct irq_data *d) { - struct vf610_gpio_port *port = - gpiochip_get_data(irq_data_get_irq_chip_data(d)); - void __iomem *pcr_base = port->base + PORT_PCR(d->hwirq); + struct gpio_chip *gc = irq_data_get_irq_chip_data(d); + struct vf610_gpio_port *port = gpiochip_get_data(gc); + irq_hw_number_t gpio_num = irqd_to_hwirq(d); + void __iomem *pcr_base = port->base + PORT_PCR(gpio_num); - vf610_gpio_writel(port->irqc[d->hwirq] << PORT_PCR_IRQC_OFFSET, + gpiochip_enable_irq(gc, gpio_num); + vf610_gpio_writel(port->irqc[gpio_num] << PORT_PCR_IRQC_OFFSET, pcr_base); } @@ -237,6 +240,17 @@ static int vf610_gpio_irq_set_wake(struct irq_data *d, u32 enable) return 0; } +static const struct irq_chip vf610_irqchip = { + .name = "gpio-vf610", + .irq_ack = vf610_gpio_irq_ack, + .irq_mask = vf610_gpio_irq_mask, + .irq_unmask = vf610_gpio_irq_unmask, + .irq_set_type = vf610_gpio_irq_set_type, + .irq_set_wake = vf610_gpio_irq_set_wake, + .flags = IRQCHIP_IMMUTABLE, + GPIOCHIP_IRQ_RESOURCE_HELPERS, +}; + static void vf610_gpio_disable_clk(void *data) { clk_disable_unprepare(data); @@ -249,7 +263,6 @@ static int vf610_gpio_probe(struct platform_device *pdev) struct vf610_gpio_port *port; struct gpio_chip *gc; struct gpio_irq_chip *girq; - struct irq_chip *ic; int i; int ret; @@ -315,14 +328,6 @@ static int vf610_gpio_probe(struct platform_device *pdev) gc->direction_output = vf610_gpio_direction_output; gc->set = vf610_gpio_set; - ic = &port->ic; - ic->name = "gpio-vf610"; - ic->irq_ack = vf610_gpio_irq_ack; - ic->irq_mask = vf610_gpio_irq_mask; - ic->irq_unmask = vf610_gpio_irq_unmask; - ic->irq_set_type = vf610_gpio_irq_set_type; - ic->irq_set_wake = vf610_gpio_irq_set_wake; - /* Mask all GPIO interrupts */ for (i = 0; i < gc->ngpio; i++) vf610_gpio_writel(0, port->base + PORT_PCR(i)); @@ -331,7 +336,7 @@ static int vf610_gpio_probe(struct platform_device *pdev) vf610_gpio_writel(~0, port->base + PORT_ISFR); girq = &gc->irq; - girq->chip = ic; + gpio_irq_chip_set_chip(girq, &vf610_irqchip); girq->parent_handler = vf610_gpio_irq_handler; girq->num_parents = 1; girq->parents = devm_kcalloc(&pdev->dev, 1, diff --git a/drivers/gpio/gpiolib-acpi.c b/drivers/gpio/gpiolib-acpi.c index bed0380c5136..34ff048e70d0 100644 --- a/drivers/gpio/gpiolib-acpi.c +++ b/drivers/gpio/gpiolib-acpi.c @@ -385,7 +385,7 @@ err: } static bool acpi_gpio_irq_is_wake(struct device *parent, - struct acpi_resource_gpio *agpio) + const struct acpi_resource_gpio *agpio) { unsigned int pin = agpio->pin_table[0]; @@ -778,7 +778,7 @@ static int acpi_populate_gpio_lookup(struct acpi_resource *ares, void *data) lookup->info.pin_config = agpio->pin_config; lookup->info.debounce = agpio->debounce_timeout; lookup->info.gpioint = gpioint; - lookup->info.wake_capable = agpio->wake_capable == ACPI_WAKE_CAPABLE; + lookup->info.wake_capable = acpi_gpio_irq_is_wake(&lookup->info.adev->dev, agpio); /* * Polarity and triggering are only specified for GpioInt @@ -1104,7 +1104,8 @@ int acpi_dev_gpio_irq_wake_get_by(struct acpi_device *adev, const char *name, in dev_dbg(&adev->dev, "IRQ %d already in use\n", irq); } - if (wake_capable) + /* avoid suspend issues with GPIOs when systems are using S3 */ + if (wake_capable && acpi_gbl_FADT.flags & ACPI_FADT_LOW_POWER_S0) *wake_capable = info.wake_capable; return irq; @@ -1623,6 +1624,31 @@ static const struct dmi_system_id gpiolib_acpi_quirks[] __initconst = { .ignore_interrupt = "AMDI0030:00@18", }, }, + { + /* + * Spurious wakeups from TP_ATTN# pin + * Found in BIOS 1.7.8 + * https://gitlab.freedesktop.org/drm/amd/-/issues/1722#note_1720627 + */ + .matches = { + DMI_MATCH(DMI_BOARD_NAME, "NL5xRU"), + }, + .driver_data = &(struct acpi_gpiolib_dmi_quirk) { + .ignore_wake = "ELAN0415:00@9", + }, + }, + { + /* + * Spurious wakeups from TP_ATTN# pin + * Found in BIOS 1.7.7 + */ + .matches = { + DMI_MATCH(DMI_BOARD_NAME, "NH5xAx"), + }, + .driver_data = &(struct acpi_gpiolib_dmi_quirk) { + .ignore_wake = "SYNA1202:00@16", + }, + }, {} /* Terminating entry */ }; diff --git a/drivers/gpio/gpiolib-acpi.h b/drivers/gpio/gpiolib-acpi.h index 9475f99a9694..5a08693b8fb1 100644 --- a/drivers/gpio/gpiolib-acpi.h +++ b/drivers/gpio/gpiolib-acpi.h @@ -14,7 +14,6 @@ #include <linux/gpio/consumer.h> -struct acpi_device; struct device; struct fwnode_handle; diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index 5a66d9616d7c..939c776b9488 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -3905,8 +3905,8 @@ static struct gpio_desc *gpiod_find_and_request(struct device *consumer, const char *label, bool platform_lookup_allowed) { + unsigned long lookupflags = GPIO_LOOKUP_FLAGS_DEFAULT; struct gpio_desc *desc = ERR_PTR(-ENOENT); - unsigned long lookupflags; int ret; if (!IS_ERR_OR_NULL(fwnode)) |