diff options
Diffstat (limited to 'drivers/gpio')
64 files changed, 2428 insertions, 876 deletions
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index 13be729710f2..5521f060d58e 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -3,14 +3,6 @@ # GPIO infrastructure and drivers # -config ARCH_HAVE_CUSTOM_GPIO_H - bool - help - Selecting this config option from the architecture Kconfig allows - the architecture to provide a custom asm/gpio.h implementation - overriding the default implementations. New uses of this are - strongly discouraged. - menuconfig GPIOLIB bool "GPIO Support" help @@ -47,6 +39,14 @@ config GPIOLIB_IRQCHIP select IRQ_DOMAIN bool +config OF_GPIO_MM_GPIOCHIP + bool + help + This adds support for the legacy 'struct of_mm_gpio_chip' interface + from PowerPC. Existing drivers using this interface need to select + this symbol, but new drivers should use the generic gpio-regmap + infrastructure instead. + config DEBUG_GPIO bool "Debug GPIO calls" depends on DEBUG_KERNEL @@ -100,7 +100,7 @@ config GPIO_GENERIC tristate config GPIO_REGMAP - depends on REGMAP + select REGMAP tristate # put drivers in the right section, in alphabetical order @@ -139,6 +139,7 @@ config GPIO_ALTERA tristate "Altera GPIO" depends on OF_GPIO select GPIOLIB_IRQCHIP + select OF_GPIO_MM_GPIOCHIP help Say Y or M here to build support for the Altera PIO device. @@ -380,6 +381,18 @@ config GPIO_LOONGSON help Driver for GPIO functionality on Loongson-2F/3A/3B processors. +config GPIO_LOONGSON_64BIT + tristate "Loongson 64 bit GPIO support" + depends on LOONGARCH || COMPILE_TEST + depends on OF_GPIO + select GPIO_GENERIC + help + Say yes here to support the GPIO functionality of a number of + Loongson series of chips. The Loongson GPIO controller supports + up to 60 GPIOS in total, 4 of which are dedicated GPIO pins, and + the remaining 56 are reused with other functions, with edge or + level triggered interrupts. + config GPIO_LPC18XX tristate "NXP LPC18XX/43XX GPIO support" default y if ARCH_LPC18XX @@ -411,6 +424,7 @@ config GPIO_MENZ127 config GPIO_MM_LANTIQ bool "Lantiq Memory mapped GPIOs" depends on LANTIQ && SOC_XWAY + select OF_GPIO_MM_GPIOCHIP help This enables support for memory mapped GPIOs on the External Bus Unit (EBU) found on Lantiq SoCs. The GPIOs are output only as they are @@ -419,6 +433,7 @@ config GPIO_MM_LANTIQ config GPIO_MPC5200 def_bool y depends on PPC_MPC52xx + select OF_GPIO_MM_GPIOCHIP config GPIO_MPC8XXX bool "MPC512x/MPC8xxx/QorIQ GPIO support" @@ -485,14 +500,6 @@ config GPIO_PL061 help Say yes here to support the PrimeCell PL061 GPIO device. -config GPIO_PMIC_EIC_SPRD - tristate "Spreadtrum PMIC EIC support" - depends on MFD_SC27XX_PMIC || COMPILE_TEST - depends on OF_GPIO - select GPIOLIB_IRQCHIP - help - Say yes here to support Spreadtrum PMIC EIC device. - config GPIO_PXA bool "PXA GPIO support" depends on ARCH_PXA || ARCH_MMP || COMPILE_TEST @@ -616,6 +623,17 @@ config GPIO_SYSCON help Say yes here to support GPIO functionality though SYSCON driver. +config GPIO_TANGIER + tristate + select GPIOLIB_IRQCHIP + help + GPIO support for Intel Tangier and compatible platforms. + Currently supported: + - Elkhart Lake + - Merrifield + + If built as a module its name will be gpio-tangier. + config GPIO_TB10X bool select GPIO_GENERIC @@ -1000,6 +1018,16 @@ config GPIO_ADNP enough to represent all pins, but the driver will assume a register layout for 64 pins (8 registers). +config GPIO_FXL6408 + tristate "FXL6408 I2C GPIO expander" + select GPIO_REGMAP + select REGMAP_I2C + help + GPIO driver for Fairchild Semiconductor FXL6408 GPIO expander. + + To compile this driver as a module, choose M here: the module will + be called gpio-fxl6408. + config GPIO_GW_PLD tristate "Gateworks PLD GPIO Expander" depends on OF_GPIO @@ -1235,6 +1263,17 @@ config HTC_EGPIO several HTC phones. It provides basic support for input pins, output pins, and IRQs. +config GPIO_ELKHARTLAKE + tristate "Intel Elkhart Lake PSE GPIO support" + depends on X86 || COMPILE_TEST + select GPIO_TANGIER + help + Select this option to enable GPIO support for Intel Elkhart Lake + PSE GPIO IP. + + To compile this driver as a module, choose M here: the module will + be called gpio-elkhartlake. + config GPIO_JANZ_TTL tristate "Janz VMOD-TTL Digital IO Module" depends on MFD_JANZ_CMODIO @@ -1253,6 +1292,18 @@ config GPIO_KEMPLD This driver can also be built as a module. If so, the module will be called gpio-kempld. +config GPIO_LJCA + tristate "INTEL La Jolla Cove Adapter GPIO support" + depends on MFD_LJCA + select GPIOLIB_IRQCHIP + default MFD_LJCA + help + Select this option to enable GPIO driver for the INTEL + La Jolla Cove Adapter (LJCA) board. + + This driver can also be built as a module. If so, the module + will be called gpio-ljca. + config GPIO_LP3943 tristate "TI/National Semiconductor LP3943 GPIO expander" depends on MFD_LP3943 @@ -1311,6 +1362,14 @@ config GPIO_PALMAS Select this option to enable GPIO driver for the TI PALMAS series chip family. +config GPIO_PMIC_EIC_SPRD + tristate "Spreadtrum PMIC EIC support" + depends on MFD_SC27XX_PMIC || COMPILE_TEST + depends on OF_GPIO + select GPIOLIB_IRQCHIP + help + Say yes here to support Spreadtrum PMIC EIC device. + config GPIO_RC5T583 bool "RICOH RC5T583 GPIO" depends on MFD_RC5T583 @@ -1505,7 +1564,7 @@ config GPIO_BT8XX config GPIO_MERRIFIELD tristate "Intel Merrifield GPIO support" depends on X86_INTEL_MID - select GPIOLIB_IRQCHIP + select GPIO_TANGIER help Say Y here to support Intel Merrifield GPIO. diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile index c048ba003367..20036af3acb1 100644 --- a/drivers/gpio/Makefile +++ b/drivers/gpio/Makefile @@ -54,12 +54,14 @@ obj-$(CONFIG_GPIO_DAVINCI) += gpio-davinci.o obj-$(CONFIG_GPIO_DLN2) += gpio-dln2.o obj-$(CONFIG_GPIO_DWAPB) += gpio-dwapb.o obj-$(CONFIG_GPIO_EIC_SPRD) += gpio-eic-sprd.o +obj-$(CONFIG_GPIO_ELKHARTLAKE) += gpio-elkhartlake.o obj-$(CONFIG_GPIO_EM) += gpio-em.o obj-$(CONFIG_GPIO_EN7523) += gpio-en7523.o obj-$(CONFIG_GPIO_EP93XX) += gpio-ep93xx.o obj-$(CONFIG_GPIO_EXAR) += gpio-exar.o obj-$(CONFIG_GPIO_F7188X) += gpio-f7188x.o obj-$(CONFIG_GPIO_FTGPIO010) += gpio-ftgpio010.o +obj-$(CONFIG_GPIO_FXL6408) += gpio-fxl6408.o obj-$(CONFIG_GPIO_GE_FPGA) += gpio-ge.o obj-$(CONFIG_GPIO_GPIO_MM) += gpio-gpio-mm.o obj-$(CONFIG_GPIO_GRGPIO) += gpio-grgpio.o @@ -77,9 +79,11 @@ obj-$(CONFIG_GPIO_IXP4XX) += gpio-ixp4xx.o obj-$(CONFIG_GPIO_JANZ_TTL) += gpio-janz-ttl.o obj-$(CONFIG_GPIO_KEMPLD) += gpio-kempld.o obj-$(CONFIG_GPIO_LATCH) += gpio-latch.o +obj-$(CONFIG_GPIO_LJCA) += gpio-ljca.o obj-$(CONFIG_GPIO_LOGICVC) += gpio-logicvc.o obj-$(CONFIG_GPIO_LOONGSON1) += gpio-loongson1.o obj-$(CONFIG_GPIO_LOONGSON) += gpio-loongson.o +obj-$(CONFIG_GPIO_LOONGSON_64BIT) += gpio-loongson-64bit.o obj-$(CONFIG_GPIO_LP3943) += gpio-lp3943.o obj-$(CONFIG_GPIO_LP873X) += gpio-lp873x.o obj-$(CONFIG_GPIO_LP87565) += gpio-lp87565.o @@ -145,6 +149,7 @@ obj-$(CONFIG_GPIO_SPRD) += gpio-sprd.o obj-$(CONFIG_GPIO_STMPE) += gpio-stmpe.o obj-$(CONFIG_GPIO_STP_XWAY) += gpio-stp-xway.o obj-$(CONFIG_GPIO_SYSCON) += gpio-syscon.o +obj-$(CONFIG_GPIO_TANGIER) += gpio-tangier.o obj-$(CONFIG_GPIO_TB10X) += gpio-tb10x.o obj-$(CONFIG_GPIO_TC3589X) += gpio-tc3589x.o obj-$(CONFIG_GPIO_TEGRA186) += gpio-tegra186.o diff --git a/drivers/gpio/TODO b/drivers/gpio/TODO index 68ada1066941..189c3abe7e79 100644 --- a/drivers/gpio/TODO +++ b/drivers/gpio/TODO @@ -59,11 +59,6 @@ the device tree back-end. It is legacy and should not be used in new code. Work items: -- Get rid of struct of_mm_gpio_chip altogether: use the generic MMIO - GPIO for all current users (see below). Delete struct of_mm_gpio_chip, - to_of_mm_gpio_chip(), of_mm_gpiochip_add_data(), of_mm_gpiochip_remove() - from the kernel. - - Change all consumer drivers that #include <linux/of_gpio.h> to #include <linux/gpio/consumer.h> and stop doing custom parsing of the GPIO lines from the device tree. This can be tricky and often ivolves @@ -81,6 +76,16 @@ Work items: uses <linux/gpio/consumer.h> or <linux/gpio/driver.h> instead. +Get rid of <linux/gpio/legacy-of-mm-gpiochip.h> + +Work items: + +- Get rid of struct of_mm_gpio_chip altogether: use the generic MMIO + GPIO for all current users (see below). Delete struct of_mm_gpio_chip, + to_of_mm_gpio_chip(), of_mm_gpiochip_add_data(), of_mm_gpiochip_remove(), + CONFIG_OF_GPIO_MM_GPIOCHIP from the kernel. + + Get rid of <linux/gpio.h> This legacy header is a one stop shop for anything GPIO is closely tied diff --git a/drivers/gpio/gpio-104-dio-48e.c b/drivers/gpio/gpio-104-dio-48e.c index a3846faf3780..f2253fd5ab4b 100644 --- a/drivers/gpio/gpio-104-dio-48e.c +++ b/drivers/gpio/gpio-104-dio-48e.c @@ -86,6 +86,7 @@ static const struct regmap_config dio48e_regmap_config = { .volatile_table = &dio48e_volatile_table, .precious_table = &dio48e_precious_table, .cache_type = REGCACHE_FLAT, + .use_raw_spinlock = true, }; /* only bit 3 on each respective Port C supports interrupts */ @@ -106,7 +107,6 @@ static int dio48e_handle_mask_sync(struct regmap *const map, const int index, { unsigned int *const irq_mask = irq_drv_data; const unsigned int prev_mask = *irq_mask; - const unsigned int all_masked = GENMASK(1, 0); int err; unsigned int val; @@ -118,7 +118,7 @@ static int dio48e_handle_mask_sync(struct regmap *const map, const int index, *irq_mask = mask_buf; /* if all previously masked, enable interrupts when unmasking */ - if (prev_mask == all_masked) { + if (prev_mask == mask_buf_def) { err = regmap_write(map, DIO48E_CLEAR_INTERRUPT, 0x00); if (err) return err; @@ -126,7 +126,7 @@ static int dio48e_handle_mask_sync(struct regmap *const map, const int index, } /* if all are currently masked, disable interrupts */ - if (mask_buf == all_masked) + if (mask_buf == mask_buf_def) return regmap_read(map, DIO48E_DISABLE_INTERRUPT, &val); return 0; @@ -195,13 +195,9 @@ static int dio48e_probe(struct device *dev, unsigned int id) return -ENOMEM; chip->name = name; - /* No IRQ status register so use CLEAR_INTERRUPT register instead */ - chip->status_base = DIO48E_CLEAR_INTERRUPT; chip->mask_base = DIO48E_ENABLE_INTERRUPT; chip->ack_base = DIO48E_CLEAR_INTERRUPT; - /* CLEAR_INTERRUPT doubles as status register so we need it cleared */ - chip->clear_ack = true; - chip->status_invert = true; + chip->no_status = true; chip->num_regs = 1; chip->irqs = dio48e_regmap_irqs; chip->num_irqs = ARRAY_SIZE(dio48e_regmap_irqs); diff --git a/drivers/gpio/gpio-104-idi-48.c b/drivers/gpio/gpio-104-idi-48.c index ca2175b84e24..ba73ee9c0c29 100644 --- a/drivers/gpio/gpio-104-idi-48.c +++ b/drivers/gpio/gpio-104-idi-48.c @@ -81,6 +81,7 @@ static const struct regmap_config idi48_regmap_config = { .wr_table = &idi_48_wr_table, .rd_table = &idi_48_rd_table, .precious_table = &idi_48_precious_table, + .use_raw_spinlock = true, }; #define IDI48_NGPIO 48 diff --git a/drivers/gpio/gpio-adnp.c b/drivers/gpio/gpio-adnp.c index a6439e3daff0..9b01c391efce 100644 --- a/drivers/gpio/gpio-adnp.c +++ b/drivers/gpio/gpio-adnp.c @@ -307,6 +307,7 @@ static void adnp_irq_mask(struct irq_data *d) unsigned int pos = d->hwirq & 7; adnp->irq_enable[reg] &= ~BIT(pos); + gpiochip_disable_irq(gc, irqd_to_hwirq(d)); } static void adnp_irq_unmask(struct irq_data *d) @@ -316,6 +317,7 @@ static void adnp_irq_unmask(struct irq_data *d) unsigned int reg = d->hwirq >> adnp->reg_shift; unsigned int pos = d->hwirq & 7; + gpiochip_enable_irq(gc, irqd_to_hwirq(d)); adnp->irq_enable[reg] |= BIT(pos); } @@ -372,13 +374,15 @@ static void adnp_irq_bus_unlock(struct irq_data *d) mutex_unlock(&adnp->irq_lock); } -static struct irq_chip adnp_irq_chip = { +static const struct irq_chip adnp_irq_chip = { .name = "gpio-adnp", .irq_mask = adnp_irq_mask, .irq_unmask = adnp_irq_unmask, .irq_set_type = adnp_irq_set_type, .irq_bus_lock = adnp_irq_bus_lock, .irq_bus_sync_unlock = adnp_irq_bus_unlock, + .flags = IRQCHIP_IMMUTABLE, + GPIOCHIP_IRQ_RESOURCE_HELPERS, }; static int adnp_irq_setup(struct adnp *adnp) @@ -469,7 +473,8 @@ static int adnp_gpio_setup(struct adnp *adnp, unsigned int num_gpios, return err; girq = &chip->irq; - girq->chip = &adnp_irq_chip; + gpio_irq_chip_set_chip(girq, &adnp_irq_chip); + /* This will let us handle the parent IRQ in the driver */ girq->parent_handler = NULL; girq->num_parents = 0; diff --git a/drivers/gpio/gpio-aggregator.c b/drivers/gpio/gpio-aggregator.c index 6d17d262ad91..20a686f12df7 100644 --- a/drivers/gpio/gpio-aggregator.c +++ b/drivers/gpio/gpio-aggregator.c @@ -10,19 +10,20 @@ #include <linux/bitmap.h> #include <linux/bitops.h> #include <linux/ctype.h> -#include <linux/gpio.h> -#include <linux/gpio/consumer.h> -#include <linux/gpio/driver.h> -#include <linux/gpio/machine.h> #include <linux/idr.h> #include <linux/kernel.h> #include <linux/module.h> #include <linux/mutex.h> #include <linux/overflow.h> #include <linux/platform_device.h> +#include <linux/slab.h> #include <linux/spinlock.h> #include <linux/string.h> +#include <linux/gpio/consumer.h> +#include <linux/gpio/driver.h> +#include <linux/gpio/machine.h> + #define AGGREGATOR_MAX_GPIOS 512 /* diff --git a/drivers/gpio/gpio-altera.c b/drivers/gpio/gpio-altera.c index b59fae993626..54d7c450c596 100644 --- a/drivers/gpio/gpio-altera.c +++ b/drivers/gpio/gpio-altera.c @@ -7,7 +7,7 @@ #include <linux/io.h> #include <linux/module.h> #include <linux/gpio/driver.h> -#include <linux/of_gpio.h> /* For of_mm_gpio_chip */ +#include <linux/gpio/legacy-of-mm-gpiochip.h> #include <linux/platform_device.h> #define ALTERA_GPIO_MAX_NGPIO 32 @@ -24,14 +24,12 @@ * @interrupt_trigger : specifies the hardware configured IRQ trigger type * (rising, falling, both, high) * @mapped_irq : kernel mapped irq number. -* @irq_chip : IRQ chip configuration */ struct altera_gpio_chip { struct of_mm_gpio_chip mmchip; raw_spinlock_t gpio_lock; int interrupt_trigger; int mapped_irq; - struct irq_chip irq_chip; }; static void altera_gpio_irq_unmask(struct irq_data *d) @@ -43,6 +41,7 @@ static void altera_gpio_irq_unmask(struct irq_data *d) altera_gc = gpiochip_get_data(irq_data_get_irq_chip_data(d)); mm_gc = &altera_gc->mmchip; + gpiochip_enable_irq(&mm_gc->gc, irqd_to_hwirq(d)); raw_spin_lock_irqsave(&altera_gc->gpio_lock, flags); intmask = readl(mm_gc->regs + ALTERA_GPIO_IRQ_MASK); @@ -68,6 +67,7 @@ static void altera_gpio_irq_mask(struct irq_data *d) intmask &= ~BIT(irqd_to_hwirq(d)); writel(intmask, mm_gc->regs + ALTERA_GPIO_IRQ_MASK); raw_spin_unlock_irqrestore(&altera_gc->gpio_lock, flags); + gpiochip_disable_irq(&mm_gc->gc, irqd_to_hwirq(d)); } /* @@ -233,6 +233,17 @@ static void altera_gpio_irq_leveL_high_handler(struct irq_desc *desc) chained_irq_exit(chip, desc); } +static const struct irq_chip altera_gpio_irq_chip = { + .name = "altera-gpio", + .irq_mask = alt |