diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2020-01-29 18:51:36 +0100 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2020-01-29 18:51:36 +0100 |
commit | 6ba3d7066c71d2103da255df19eb613d299bab15 (patch) | |
tree | 43f2bccb85638b7e6f7fde6a5ca7ae6a4e718c35 /drivers/gpio | |
parent | Merge tag 'gpio-v5.6-1' of git://git.kernel.org/pub/scm/linux/kernel/git/linu... (diff) | |
parent | pinctrl: madera: Remove extra blank line (diff) | |
download | linux-6ba3d7066c71d2103da255df19eb613d299bab15.tar.xz linux-6ba3d7066c71d2103da255df19eb613d299bab15.zip |
Merge tag 'pinctrl-v5.6-1' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-pinctrl
Pull pin control updates from Linus Walleij:
"This is the bulk of pin control changes, nothing too exciting about
this.
Some changes hit arch/sh and arch/arm but are well isolated and
acknowledged by the respective arch maintainers.
Core changes:
- Dropped the chained IRQ setup callback into GPIOLIB as we got rid
of the last users of that in this changeset.
New drivers:
- New driver for Ingenic X1830.
- New driver for Freescale i.MX8MP.
Driver enhancements:
- Fix all remaining Intel drivers to pass their IRQ chips along with
the GPIO chips.
- Intel Baytrail allocates its irqchip dynamically.
- Intel Lynxpoint is thoroughly rewritten and modernized.
- Aspeed AST2600 pin muxing and configuration is much improved.
- Qualcomm SC7180 functions are updated and wakeup interrupt map is
provided.
- A whole slew of Renesas SH-PFC cleanups and improvements.
- Fix up the Intel DT bindings to use the generic YAML DT bindings
schema (a first user of this)"
* tag 'pinctrl-v5.6-1' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-pinctrl: (99 commits)
pinctrl: madera: Remove extra blank line
pinctrl: qcom: Don't lock around irq_set_irq_wake()
pinctrl: mvebu: armada-37xx: use use platform api
gpio: Drop the chained IRQ handler assign function
pinctrl: freescale: Add i.MX8MP pinctrl driver support
dt-bindings: imx: Add pinctrl binding doc for i.MX8MP
pinctrl: tigerlake: Tiger Lake uses _HID enumeration
pinctrl: sunrisepoint: Add Coffee Lake-S ACPI ID
pinctrl: iproc: Use platform_get_irq_optional() to avoid error message
pinctrl: dt-bindings: Fix some errors in the lgm and pinmux schema
pinctrl: intel: Pass irqchip when adding gpiochip
pinctrl: intel: Add GPIO <-> pin mapping ranges via callback
pinctrl: baytrail: Replace WARN with dev_info_once when setting direct-irq pin to output
pinctrl: baytrail: Do not clear IRQ flags on direct-irq enabled pins
pinctrl: sunrisepoint: Add missing Interrupt Status register offset
pinctrl: sh-pfc: Split R-Car H3 support in two independent drivers
pinctrl: artpec6: fix __iomem on reg in set
pinctrl: ingenic: Use devm_platform_ioremap_resource()
pinctrl: ingenic: Factorize irq_set_type function
pinctrl: ingenic: Remove duplicated ingenic_chip_info structures
...
Diffstat (limited to 'drivers/gpio')
-rw-r--r-- | drivers/gpio/Kconfig | 8 | ||||
-rw-r--r-- | drivers/gpio/Makefile | 1 | ||||
-rw-r--r-- | drivers/gpio/gpio-lynxpoint.c | 471 | ||||
-rw-r--r-- | drivers/gpio/gpio-mt7621.c | 3 | ||||
-rw-r--r-- | drivers/gpio/gpio-xgs-iproc.c | 3 | ||||
-rw-r--r-- | drivers/gpio/gpiolib.c | 25 |
6 files changed, 3 insertions, 508 deletions
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index 081776b91e5a..b585f2ef6dd9 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -341,14 +341,6 @@ config GPIO_LPC32XX Select this option to enable GPIO driver for NXP LPC32XX devices. -config GPIO_LYNXPOINT - tristate "Intel Lynxpoint GPIO support" - depends on ACPI && X86 - select GPIOLIB_IRQCHIP - help - driver for GPIO functionality on Intel Lynxpoint PCH chipset - Requires ACPI device enumeration code to set up a platform device. - config GPIO_MB86S7X tristate "GPIO support for Fujitsu MB86S7x Platforms" help diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile index af158b7e1a43..76ff2a5feaba 100644 --- a/drivers/gpio/Makefile +++ b/drivers/gpio/Makefile @@ -77,7 +77,6 @@ obj-$(CONFIG_GPIO_LP873X) += gpio-lp873x.o obj-$(CONFIG_GPIO_LP87565) += gpio-lp87565.o obj-$(CONFIG_GPIO_LPC18XX) += gpio-lpc18xx.o obj-$(CONFIG_GPIO_LPC32XX) += gpio-lpc32xx.o -obj-$(CONFIG_GPIO_LYNXPOINT) += gpio-lynxpoint.o obj-$(CONFIG_GPIO_MADERA) += gpio-madera.o obj-$(CONFIG_GPIO_MAX3191X) += gpio-max3191x.o obj-$(CONFIG_GPIO_MAX7300) += gpio-max7300.o diff --git a/drivers/gpio/gpio-lynxpoint.c b/drivers/gpio/gpio-lynxpoint.c deleted file mode 100644 index 490ce7bae25e..000000000000 --- a/drivers/gpio/gpio-lynxpoint.c +++ /dev/null @@ -1,471 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * GPIO controller driver for Intel Lynxpoint PCH chipset> - * Copyright (c) 2012, Intel Corporation. - * - * Author: Mathias Nyman <mathias.nyman@linux.intel.com> - */ - -#include <linux/acpi.h> -#include <linux/bitops.h> -#include <linux/gpio/driver.h> -#include <linux/interrupt.h> -#include <linux/io.h> -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/platform_device.h> -#include <linux/pm_runtime.h> -#include <linux/slab.h> -#include <linux/types.h> - -/* LynxPoint chipset has support for 94 gpio pins */ - -#define LP_NUM_GPIO 94 - -/* Bitmapped register offsets */ -#define LP_ACPI_OWNED 0x00 /* Bitmap, set by bios, 0: pin reserved for ACPI */ -#define LP_GC 0x7C /* set APIC IRQ to IRQ14 or IRQ15 for all pins */ -#define LP_INT_STAT 0x80 -#define LP_INT_ENABLE 0x90 - -/* Each pin has two 32 bit config registers, starting at 0x100 */ -#define LP_CONFIG1 0x100 -#define LP_CONFIG2 0x104 - -/* LP_CONFIG1 reg bits */ -#define OUT_LVL_BIT BIT(31) -#define IN_LVL_BIT BIT(30) -#define TRIG_SEL_BIT BIT(4) /* 0: Edge, 1: Level */ -#define INT_INV_BIT BIT(3) /* Invert interrupt triggering */ -#define DIR_BIT BIT(2) /* 0: Output, 1: Input */ -#define USE_SEL_BIT BIT(0) /* 0: Native, 1: GPIO */ - -/* LP_CONFIG2 reg bits */ -#define GPINDIS_BIT BIT(2) /* disable input sensing */ -#define GPIWP_BIT (BIT(0) | BIT(1)) /* weak pull options */ - -struct lp_gpio { - struct gpio_chip chip; - struct platform_device *pdev; - spinlock_t lock; - unsigned long reg_base; -}; - -/* - * Lynxpoint gpios are controlled through both bitmapped registers and - * per gpio specific registers. The bitmapped registers are in chunks of - * 3 x 32bit registers to cover all 94 gpios - * - * per gpio specific registers consist of two 32bit registers per gpio - * (LP_CONFIG1 and LP_CONFIG2), with 94 gpios there's a total of - * 188 config registers. - * - * A simplified view of the register layout look like this: - * - * LP_ACPI_OWNED[31:0] gpio ownerships for gpios 0-31 (bitmapped registers) - * LP_ACPI_OWNED[63:32] gpio ownerships for gpios 32-63 - * LP_ACPI_OWNED[94:64] gpio ownerships for gpios 63-94 - * ... - * LP_INT_ENABLE[31:0] ... - * LP_INT_ENABLE[63:31] ... - * LP_INT_ENABLE[94:64] ... - * LP0_CONFIG1 (gpio 0) config1 reg for gpio 0 (per gpio registers) - * LP0_CONFIG2 (gpio 0) config2 reg for gpio 0 - * LP1_CONFIG1 (gpio 1) config1 reg for gpio 1 - * LP1_CONFIG2 (gpio 1) config2 reg for gpio 1 - * LP2_CONFIG1 (gpio 2) ... - * LP2_CONFIG2 (gpio 2) ... - * ... - * LP94_CONFIG1 (gpio 94) ... - * LP94_CONFIG2 (gpio 94) ... - */ - -static unsigned long lp_gpio_reg(struct gpio_chip *chip, unsigned offset, - int reg) -{ - struct lp_gpio *lg = gpiochip_get_data(chip); - int reg_offset; - - if (reg == LP_CONFIG1 || reg == LP_CONFIG2) - /* per gpio specific config registers */ - reg_offset = offset * 8; - else - /* bitmapped registers */ - reg_offset = (offset / 32) * 4; - - return lg->reg_base + reg + reg_offset; -} - -static int lp_gpio_request(struct gpio_chip *chip, unsigned offset) -{ - struct lp_gpio *lg = gpiochip_get_data(chip); - unsigned long reg = lp_gpio_reg(chip, offset, LP_CONFIG1); - unsigned long conf2 = lp_gpio_reg(chip, offset, LP_CONFIG2); - unsigned long acpi_use = lp_gpio_reg(chip, offset, LP_ACPI_OWNED); - - pm_runtime_get(&lg->pdev->dev); /* should we put if failed */ - - /* Fail if BIOS reserved pin for ACPI use */ - if (!(inl(acpi_use) & BIT(offset % 32))) { - dev_err(&lg->pdev->dev, "gpio %d reserved for ACPI\n", offset); - return -EBUSY; - } - /* Fail if pin is in alternate function mode (not GPIO mode) */ - if (!(inl(reg) & USE_SEL_BIT)) - return -ENODEV; - - /* enable input sensing */ - outl(inl(conf2) & ~GPINDIS_BIT, conf2); - - - return 0; -} - -static void lp_gpio_free(struct gpio_chip *chip, unsigned offset) -{ - struct lp_gpio *lg = gpiochip_get_data(chip); - unsigned long conf2 = lp_gpio_reg(chip, offset, LP_CONFIG2); - - /* disable input sensing */ - outl(inl(conf2) | GPINDIS_BIT, conf2); - - pm_runtime_put(&lg->pdev->dev); -} - -static int lp_irq_type(struct irq_data *d, unsigned type) -{ - struct gpio_chip *gc = irq_data_get_irq_chip_data(d); - struct lp_gpio *lg = gpiochip_get_data(gc); - u32 hwirq = irqd_to_hwirq(d); - unsigned long flags; - u32 value; - unsigned long reg = lp_gpio_reg(&lg->chip, hwirq, LP_CONFIG1); - - if (hwirq >= lg->chip.ngpio) - return -EINVAL; - - spin_lock_irqsave(&lg->lock, flags); - value = inl(reg); - - /* set both TRIG_SEL and INV bits to 0 for rising edge */ - if (type & IRQ_TYPE_EDGE_RISING) - value &= ~(TRIG_SEL_BIT | INT_INV_BIT); - - /* TRIG_SEL bit 0, INV bit 1 for falling edge */ - if (type & IRQ_TYPE_EDGE_FALLING) - value = (value | INT_INV_BIT) & ~TRIG_SEL_BIT; - - /* TRIG_SEL bit 1, INV bit 0 for level low */ - if (type & IRQ_TYPE_LEVEL_LOW) - value = (value | TRIG_SEL_BIT) & ~INT_INV_BIT; - - /* TRIG_SEL bit 1, INV bit 1 for level high */ - if (type & IRQ_TYPE_LEVEL_HIGH) - value |= TRIG_SEL_BIT | INT_INV_BIT; - - outl(value, reg); - - if (type & IRQ_TYPE_EDGE_BOTH) - irq_set_handler_locked(d, handle_edge_irq); - else if (type & IRQ_TYPE_LEVEL_MASK) - irq_set_handler_locked(d, handle_level_irq); - - spin_unlock_irqrestore(&lg->lock, flags); - - return 0; -} - -static int lp_gpio_get(struct gpio_chip *chip, unsigned offset) -{ - unsigned long reg = lp_gpio_reg(chip, offset, LP_CONFIG1); - return !!(inl(reg) & IN_LVL_BIT); -} - -static void lp_gpio_set(struct gpio_chip *chip, unsigned offset, int value) -{ - struct lp_gpio *lg = gpiochip_get_data(chip); - unsigned long reg = lp_gpio_reg(chip, offset, LP_CONFIG1); - unsigned long flags; - - spin_lock_irqsave(&lg->lock, flags); - - if (value) - outl(inl(reg) | OUT_LVL_BIT, reg); - else - outl(inl(reg) & ~OUT_LVL_BIT, reg); - - spin_unlock_irqrestore(&lg->lock, flags); -} - -static int lp_gpio_direction_input(struct gpio_chip *chip, unsigned offset) -{ - struct lp_gpio *lg = gpiochip_get_data(chip); - unsigned long reg = lp_gpio_reg(chip, offset, LP_CONFIG1); - unsigned long flags; - - spin_lock_irqsave(&lg->lock, flags); - outl(inl(reg) | DIR_BIT, reg); - spin_unlock_irqrestore(&lg->lock, flags); - - return 0; -} - -static int lp_gpio_direction_output(struct gpio_chip *chip, - unsigned offset, int value) -{ - struct lp_gpio *lg = gpiochip_get_data(chip); - unsigned long reg = lp_gpio_reg(chip, offset, LP_CONFIG1); - unsigned long flags; - - lp_gpio_set(chip, offset, value); - - spin_lock_irqsave(&lg->lock, flags); - outl(inl(reg) & ~DIR_BIT, reg); - spin_unlock_irqrestore(&lg->lock, flags); - - return 0; -} - -static void lp_gpio_irq_handler(struct irq_desc *desc) -{ - struct irq_data *data = irq_desc_get_irq_data(desc); - struct gpio_chip *gc = irq_desc_get_handler_data(desc); - struct lp_gpio *lg = gpiochip_get_data(gc); - struct irq_chip *chip = irq_data_get_irq_chip(data); - unsigned long reg, ena, pending; - u32 base, pin; - - /* check from GPIO controller which pin triggered the interrupt */ - for (base = 0; base < lg->chip.ngpio; base += 32) { - reg = lp_gpio_reg(&lg->chip, base, LP_INT_STAT); - ena = lp_gpio_reg(&lg->chip, base, LP_INT_ENABLE); - - /* Only interrupts that are enabled */ - pending = inl(reg) & inl(ena); - - for_each_set_bit(pin, &pending, 32) { - unsigned irq; - - /* Clear before handling so we don't lose an edge */ - outl(BIT(pin), reg); - - irq = irq_find_mapping(lg->chip.irq.domain, base + pin); - generic_handle_irq(irq); - } - } - chip->irq_eoi(data); -} - -static void lp_irq_unmask(struct irq_data *d) -{ -} - -static void lp_irq_mask(struct irq_data *d) -{ -} - -static void lp_irq_enable(struct irq_data *d) -{ - struct gpio_chip *gc = irq_data_get_irq_chip_data(d); - struct lp_gpio *lg = gpiochip_get_data(gc); - u32 hwirq = irqd_to_hwirq(d); - unsigned long reg = lp_gpio_reg(&lg->chip, hwirq, LP_INT_ENABLE); - unsigned long flags; - - spin_lock_irqsave(&lg->lock, flags); - outl(inl(reg) | BIT(hwirq % 32), reg); - spin_unlock_irqrestore(&lg->lock, flags); -} - -static void lp_irq_disable(struct irq_data *d) -{ - struct gpio_chip *gc = irq_data_get_irq_chip_data(d); - struct lp_gpio *lg = gpiochip_get_data(gc); - u32 hwirq = irqd_to_hwirq(d); - unsigned long reg = lp_gpio_reg(&lg->chip, hwirq, LP_INT_ENABLE); - unsigned long flags; - - spin_lock_irqsave(&lg->lock, flags); - outl(inl(reg) & ~BIT(hwirq % 32), reg); - spin_unlock_irqrestore(&lg->lock, flags); -} - -static struct irq_chip lp_irqchip = { - .name = "LP-GPIO", - .irq_mask = lp_irq_mask, - .irq_unmask = lp_irq_unmask, - .irq_enable = lp_irq_enable, - .irq_disable = lp_irq_disable, - .irq_set_type = lp_irq_type, - .flags = IRQCHIP_SKIP_SET_WAKE, -}; - -static int lp_gpio_irq_init_hw(struct gpio_chip *chip) -{ - struct lp_gpio *lg = gpiochip_get_data(chip); - unsigned long reg; - unsigned base; - - for (base = 0; base < lg->chip.ngpio; base += 32) { - /* disable gpio pin interrupts */ - reg = lp_gpio_reg(&lg->chip, base, LP_INT_ENABLE); - outl(0, reg); - /* Clear interrupt status register */ - reg = lp_gpio_reg(&lg->chip, base, LP_INT_STAT); - outl(0xffffffff, reg); - } - - return 0; -} - -static int lp_gpio_probe(struct platform_device *pdev) -{ - struct lp_gpio *lg; - struct gpio_chip *gc; - struct resource *io_rc, *irq_rc; - struct device *dev = &pdev->dev; - unsigned long reg_len; - int ret = -ENODEV; - - lg = devm_kzalloc(dev, sizeof(struct lp_gpio), GFP_KERNEL); - if (!lg) - return -ENOMEM; - - lg->pdev = pdev; - platform_set_drvdata(pdev, lg); - - io_rc = platform_get_resource(pdev, IORESOURCE_IO, 0); - irq_rc = platform_get_resource(pdev, IORESOURCE_IRQ, 0); - - if (!io_rc) { - dev_err(dev, "missing IO resources\n"); - return -EINVAL; - } - - lg->reg_base = io_rc->start; - reg_len = resource_size(io_rc); - - if (!devm_request_region(dev, lg->reg_base, reg_len, "lp-gpio")) { - dev_err(dev, "failed requesting IO region 0x%x\n", - (unsigned int)lg->reg_base); - return -EBUSY; - } - - spin_lock_init(&lg->lock); - - gc = &lg->chip; - gc->label = dev_name(dev); - gc->owner = THIS_MODULE; - gc->request = lp_gpio_request; - gc->free = lp_gpio_free; - gc->direction_input = lp_gpio_direction_input; - gc->direction_output = lp_gpio_direction_output; - gc->get = lp_gpio_get; - gc->set = lp_gpio_set; - gc->base = -1; - gc->ngpio = LP_NUM_GPIO; - gc->can_sleep = false; - gc->parent = dev; - - /* set up interrupts */ - if (irq_rc && irq_rc->start) { - struct gpio_irq_chip *girq; - - girq = &gc->irq; - girq->chip = &lp_irqchip; - girq->init_hw = lp_gpio_irq_init_hw; - girq->parent_handler = lp_gpio_irq_handler; - girq->num_parents = 1; - girq->parents = devm_kcalloc(&pdev->dev, girq->num_parents, - sizeof(*girq->parents), - GFP_KERNEL); - if (!girq->parents) - return -ENOMEM; - girq->parents[0] = (unsigned)irq_rc->start; - girq->default_type = IRQ_TYPE_NONE; - girq->handler = handle_bad_irq; - } - - ret = devm_gpiochip_add_data(dev, gc, lg); - if (ret) { - dev_err(dev, "failed adding lp-gpio chip\n"); - return ret; - } - - pm_runtime_enable(dev); - - return 0; -} - -static int lp_gpio_runtime_suspend(struct device *dev) -{ - return 0; -} - -static int lp_gpio_runtime_resume(struct device *dev) -{ - return 0; -} - -static int lp_gpio_resume(struct device *dev) -{ - struct lp_gpio *lg = dev_get_drvdata(dev); - unsigned long reg; - int i; - - /* on some hardware suspend clears input sensing, re-enable it here */ - for (i = 0; i < lg->chip.ngpio; i++) { - if (gpiochip_is_requested(&lg->chip, i) != NULL) { - reg = lp_gpio_reg(&lg->chip, i, LP_CONFIG2); - outl(inl(reg) & ~GPINDIS_BIT, reg); - } - } - return 0; -} - -static const struct dev_pm_ops lp_gpio_pm_ops = { - .runtime_suspend = lp_gpio_runtime_suspend, - .runtime_resume = lp_gpio_runtime_resume, - .resume = lp_gpio_resume, -}; - -static const struct acpi_device_id lynxpoint_gpio_acpi_match[] = { - { "INT33C7", 0 }, - { "INT3437", 0 }, - { } -}; -MODULE_DEVICE_TABLE(acpi, lynxpoint_gpio_acpi_match); - -static int lp_gpio_remove(struct platform_device *pdev) -{ - pm_runtime_disable(&pdev->dev); - return 0; -} - -static struct platform_driver lp_gpio_driver = { - .probe = lp_gpio_probe, - .remove = lp_gpio_remove, - .driver = { - .name = "lp_gpio", - .pm = &lp_gpio_pm_ops, - .acpi_match_table = ACPI_PTR(lynxpoint_gpio_acpi_match), - }, -}; - -static int __init lp_gpio_init(void) -{ - return platform_driver_register(&lp_gpio_driver); -} - -static void __exit lp_gpio_exit(void) -{ - platform_driver_unregister(&lp_gpio_driver); -} - -subsys_initcall(lp_gpio_init); -module_exit(lp_gpio_exit); - -MODULE_AUTHOR("Mathias Nyman (Intel)"); -MODULE_DESCRIPTION("GPIO interface for Intel Lynxpoint"); -MODULE_LICENSE("GPL v2"); -MODULE_ALIAS("platform:lp_gpio"); diff --git a/drivers/gpio/gpio-mt7621.c b/drivers/gpio/gpio-mt7621.c index d1d785f983a7..b992321bb852 100644 --- a/drivers/gpio/gpio-mt7621.c +++ b/drivers/gpio/gpio-mt7621.c @@ -253,8 +253,7 @@ mediatek_gpio_bank_probe(struct device *dev, /* * Directly request the irq here instead of passing - * a flow-handler to gpiochip_set_chained_irqchip, - * because the irq is shared. + * a flow-handler because the irq is shared. */ ret = devm_request_irq(dev, mtk->gpio_irq, mediatek_gpio_irq_handler, IRQF_SHARED, diff --git a/drivers/gpio/gpio-xgs-iproc.c b/drivers/gpio/gpio-xgs-iproc.c index b21c2e436b61..ad5489a65d54 100644 --- a/drivers/gpio/gpio-xgs-iproc.c +++ b/drivers/gpio/gpio-xgs-iproc.c @@ -251,8 +251,7 @@ static int iproc_gpio_probe(struct platform_device *pdev) /* * Directly request the irq here instead of passing - * a flow-handler to gpiochip_set_chained_irqchip, - * because the irq is shared. + * a flow-handler because the irq is shared. */ ret = devm_request_irq(dev, irq, iproc_gpio_irq_handler, IRQF_SHARED, chip->gc.label, &chip->gc); diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index 9d9ba56cb73d..99ac27a72e28 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -1800,7 +1800,7 @@ EXPORT_SYMBOL_GPL(gpiochip_irqchip_irq_valid); * gpiochip_set_cascaded_irqchip() - connects a cascaded irqchip to a gpiochip * @gc: the gpiochip to set the irqchip chain to * @parent_irq: the irq number corresponding to the parent IRQ for this - * chained irqchip + * cascaded irqchip * @parent_handler: the parent interrupt handler for the accumulated IRQ * coming out of the gpiochip. If the interrupt is nested rather than * cascaded, pass NULL in this handler argument @@ -1843,29 +1843,6 @@ static void gpiochip_set_cascaded_irqchip(struct gpio_chip *gc, } /** - * gpiochip_set_chained_irqchip() - connects a chained irqchip to a gpiochip - * @gpiochip: the gpiochip to set the irqchip chain to - * @irqchip: the irqchip to chain to the gpiochip - * @parent_irq: the irq number corresponding to the parent IRQ for this - * chained irqchip - * @parent_handler: the parent interrupt handler for the accumulated IRQ - * coming out of the gpiochip. - */ -void gpiochip_set_chained_irqchip(struct gpio_chip *gpiochip, - struct irq_chip *irqchip, - unsigned int parent_irq, - irq_flow_handler_t parent_handler) -{ - if (gpiochip->irq.threaded) { - chip_err(gpiochip, "tried to chain a threaded gpiochip\n"); - return; - } - - gpiochip_set_cascaded_irqchip(gpiochip, parent_irq, parent_handler); -} -EXPORT_SYMBOL_GPL(gpiochip_set_chained_irqchip); - -/** * gpiochip_set_nested_irqchip() - connects a nested irqchip to a gpiochip * @gpiochip: the gpiochip to set the irqchip nested handler to * @irqchip: the irqchip to nest to the gpiochip |