diff options
author | Stephen Rothwell <sfr@canb.auug.org.au> | 2017-04-07 15:43:50 +1000 |
---|---|---|
committer | Stephen Rothwell <sfr@canb.auug.org.au> | 2017-04-07 15:43:50 +1000 |
commit | b14336e53800f0b26c1afb55893881024620f469 (patch) | |
tree | cf8659a917bc10bed091534488340e86f8f32752 /drivers/gpio | |
parent | 3f46c4d48565b9816b71e61dc42386324380df90 (diff) | |
parent | d85f6bb3075983993e5523dc9938f202d90e6c5c (diff) | |
download | linux-next-b14336e53800f0b26c1afb55893881024620f469.tar.gz |
Merge remote-tracking branch 'gpio/for-next'
Diffstat (limited to 'drivers/gpio')
38 files changed, 815 insertions, 566 deletions
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index 05043071fc98..63ceed246b6f 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -204,14 +204,15 @@ config GPIO_GE_FPGA and write pin state) for GPIO implemented in a number of GE single board computers. -config GPIO_GEMINI - bool "Gemini GPIO" - depends on ARCH_GEMINI +config GPIO_FTGPIO010 + bool "Faraday FTGPIO010 GPIO" depends on OF_GPIO select GPIO_GENERIC select GPIOLIB_IRQCHIP + default (ARCH_GEMINI || ARCH_MOXART) help - Support for common GPIOs found in Cortina systems Gemini platforms. + Support for common GPIOs from the Faraday FTGPIO010 IP core, found in + Cortina systems Gemini platforms, Moxa ART and others. config GPIO_GENERIC_PLATFORM tristate "Generic memory-mapped GPIO controller support (MMIO platform device)" @@ -308,14 +309,6 @@ config GPIO_MOCKUP tools/testing/selftests/gpio/gpio-mockup.sh. Reference the usage in it. -config GPIO_MOXART - bool "MOXART GPIO support" - depends on ARCH_MOXART || COMPILE_TEST - select GPIO_GENERIC - help - Select this option to enable GPIO driver for - MOXA ART SoC devices. - config GPIO_MPC5200 def_bool y depends on PPC_MPC52xx @@ -387,6 +380,12 @@ config GPIO_RCAR help Say yes here to support GPIO on Renesas R-Car SoCs. +config GPIO_REG + bool + help + A 32-bit single register GPIO fixed in/out implementation. This + can be used to represent any register as a set of GPIO signals. + config GPIO_SPEAR_SPICS bool "ST SPEAr13xx SPI Chip Select as GPIO support" depends on PLAT_SPEAR @@ -505,7 +504,7 @@ config GPIO_XILINX config GPIO_XLP tristate "Netlogic XLP GPIO support" - depends on OF_GPIO && (CPU_XLP || ARCH_VULCAN || COMPILE_TEST) + depends on OF_GPIO && (CPU_XLP || ARCH_VULCAN || ARCH_THUNDER2 || COMPILE_TEST) select GPIOLIB_IRQCHIP help This driver provides support for GPIO interface on Netlogic XLP MIPS64 @@ -557,7 +556,7 @@ menu "Port-mapped I/O GPIO drivers" config GPIO_104_DIO_48E tristate "ACCES 104-DIO-48E GPIO support" - depends on ISA_BUS_API + depends on PC104 && ISA_BUS_API select GPIOLIB_IRQCHIP help Enables GPIO support for the ACCES 104-DIO-48E series (104-DIO-48E, @@ -567,7 +566,7 @@ config GPIO_104_DIO_48E config GPIO_104_IDIO_16 tristate "ACCES 104-IDIO-16 GPIO support" - depends on ISA_BUS_API + depends on PC104 && ISA_BUS_API select GPIOLIB_IRQCHIP help Enables GPIO support for the ACCES 104-IDIO-16 family (104-IDIO-16, @@ -578,7 +577,7 @@ config GPIO_104_IDIO_16 config GPIO_104_IDI_48 tristate "ACCES 104-IDI-48 GPIO support" - depends on ISA_BUS_API + depends on PC104 && ISA_BUS_API select GPIOLIB_IRQCHIP help Enables GPIO support for the ACCES 104-IDI-48 family (104-IDI-48A, @@ -598,7 +597,7 @@ config GPIO_F7188X config GPIO_GPIO_MM tristate "Diamond Systems GPIO-MM GPIO support" - depends on ISA_BUS_API + depends on PC104 && ISA_BUS_API help Enables GPIO support for the Diamond Systems GPIO-MM and GPIO-MM-12. diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile index becb96c724fe..095598e856ca 100644 --- a/drivers/gpio/Makefile +++ b/drivers/gpio/Makefile @@ -48,8 +48,8 @@ obj-$(CONFIG_GPIO_EP93XX) += gpio-ep93xx.o obj-$(CONFIG_GPIO_ETRAXFS) += gpio-etraxfs.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_GE_FPGA) += gpio-ge.o -obj-$(CONFIG_GPIO_GEMINI) += gpio-gemini.o obj-$(CONFIG_GPIO_GPIO_MM) += gpio-gpio-mm.o obj-$(CONFIG_GPIO_GRGPIO) += gpio-grgpio.o obj-$(CONFIG_HTC_EGPIO) += gpio-htc-egpio.o @@ -80,7 +80,6 @@ obj-$(CONFIG_GPIO_MCP23S08) += gpio-mcp23s08.o obj-$(CONFIG_GPIO_ML_IOH) += gpio-ml-ioh.o obj-$(CONFIG_GPIO_MM_LANTIQ) += gpio-mm-lantiq.o obj-$(CONFIG_GPIO_MOCKUP) += gpio-mockup.o -obj-$(CONFIG_GPIO_MOXART) += gpio-moxart.o obj-$(CONFIG_GPIO_MPC5200) += gpio-mpc5200.o obj-$(CONFIG_GPIO_MPC8XXX) += gpio-mpc8xxx.o obj-$(CONFIG_GPIO_MSIC) += gpio-msic.o @@ -99,6 +98,7 @@ obj-$(CONFIG_GPIO_PXA) += gpio-pxa.o obj-$(CONFIG_GPIO_RC5T583) += gpio-rc5t583.o obj-$(CONFIG_GPIO_RDC321X) += gpio-rdc321x.o obj-$(CONFIG_GPIO_RCAR) += gpio-rcar.o +obj-$(CONFIG_GPIO_REG) += gpio-reg.o obj-$(CONFIG_ARCH_SA1100) += gpio-sa1100.o obj-$(CONFIG_GPIO_SCH) += gpio-sch.o obj-$(CONFIG_GPIO_SCH311X) += gpio-sch311x.o diff --git a/drivers/gpio/devres.c b/drivers/gpio/devres.c index 7031eea165c9..a75511d1ea5d 100644 --- a/drivers/gpio/devres.c +++ b/drivers/gpio/devres.c @@ -136,7 +136,7 @@ EXPORT_SYMBOL(devm_gpiod_get_index); * GPIO descriptors returned from this function are automatically disposed on * driver detach. * - * On successfull request the GPIO pin is configured in accordance with + * On successful request the GPIO pin is configured in accordance with * provided @flags. */ struct gpio_desc *devm_fwnode_get_index_gpiod_from_child(struct device *dev, diff --git a/drivers/gpio/gpio-104-dio-48e.c b/drivers/gpio/gpio-104-dio-48e.c index 17bd2ab4ebe2..61b50c40b87b 100644 --- a/drivers/gpio/gpio-104-dio-48e.c +++ b/drivers/gpio/gpio-104-dio-48e.c @@ -55,7 +55,7 @@ struct dio48e_gpio { unsigned char io_state[6]; unsigned char out_state[6]; unsigned char control[2]; - spinlock_t lock; + raw_spinlock_t lock; unsigned base; unsigned char irq_mask; }; @@ -78,7 +78,7 @@ static int dio48e_gpio_direction_input(struct gpio_chip *chip, unsigned offset) unsigned long flags; unsigned control; - spin_lock_irqsave(&dio48egpio->lock, flags); + raw_spin_lock_irqsave(&dio48egpio->lock, flags); /* Check if configuring Port C */ if (io_port == 2 || io_port == 5) { @@ -103,7 +103,7 @@ static int dio48e_gpio_direction_input(struct gpio_chip *chip, unsigned offset) control &= ~BIT(7); outb(control, control_addr); - spin_unlock_irqrestore(&dio48egpio->lock, flags); + raw_spin_unlock_irqrestore(&dio48egpio->lock, flags); return 0; } @@ -120,7 +120,7 @@ static int dio48e_gpio_direction_output(struct gpio_chip *chip, unsigned offset, unsigned long flags; unsigned control; - spin_lock_irqsave(&dio48egpio->lock, flags); + raw_spin_lock_irqsave(&dio48egpio->lock, flags); /* Check if configuring Port C */ if (io_port == 2 || io_port == 5) { @@ -153,7 +153,7 @@ static int dio48e_gpio_direction_output(struct gpio_chip *chip, unsigned offset, control &= ~BIT(7); outb(control, control_addr); - spin_unlock_irqrestore(&dio48egpio->lock, flags); + raw_spin_unlock_irqrestore(&dio48egpio->lock, flags); return 0; } @@ -167,17 +167,17 @@ static int dio48e_gpio_get(struct gpio_chip *chip, unsigned offset) unsigned long flags; unsigned port_state; - spin_lock_irqsave(&dio48egpio->lock, flags); + raw_spin_lock_irqsave(&dio48egpio->lock, flags); /* ensure that GPIO is set for input */ if (!(dio48egpio->io_state[port] & mask)) { - spin_unlock_irqrestore(&dio48egpio->lock, flags); + raw_spin_unlock_irqrestore(&dio48egpio->lock, flags); return -EINVAL; } port_state = inb(dio48egpio->base + in_port); - spin_unlock_irqrestore(&dio48egpio->lock, flags); + raw_spin_unlock_irqrestore(&dio48egpio->lock, flags); return !!(port_state & mask); } @@ -190,7 +190,7 @@ static void dio48e_gpio_set(struct gpio_chip *chip, unsigned offset, int value) const unsigned out_port = (port > 2) ? port + 1 : port; unsigned long flags; - spin_lock_irqsave(&dio48egpio->lock, flags); + raw_spin_lock_irqsave(&dio48egpio->lock, flags); if (value) dio48egpio->out_state[port] |= mask; @@ -199,7 +199,7 @@ static void dio48e_gpio_set(struct gpio_chip *chip, unsigned offset, int value) outb(dio48egpio->out_state[port], dio48egpio->base + out_port); - spin_unlock_irqrestore(&dio48egpio->lock, flags); + raw_spin_unlock_irqrestore(&dio48egpio->lock, flags); } static void dio48e_gpio_set_multiple(struct gpio_chip *chip, @@ -225,14 +225,14 @@ static void dio48e_gpio_set_multiple(struct gpio_chip *chip, out_port = (port > 2) ? port + 1 : port; bitmask = mask[BIT_WORD(i)] & bits[BIT_WORD(i)]; - spin_lock_irqsave(&dio48egpio->lock, flags); + raw_spin_lock_irqsave(&dio48egpio->lock, flags); /* update output state data and set device gpio register */ dio48egpio->out_state[port] &= ~mask[BIT_WORD(i)]; dio48egpio->out_state[port] |= bitmask; outb(dio48egpio->out_state[port], dio48egpio->base + out_port); - spin_unlock_irqrestore(&dio48egpio->lock, flags); + raw_spin_unlock_irqrestore(&dio48egpio->lock, flags); /* prepare for next gpio register set */ mask[BIT_WORD(i)] >>= gpio_reg_size; @@ -255,7 +255,7 @@ static void dio48e_irq_mask(struct irq_data *data) if (offset != 19 && offset != 43) return; - spin_lock_irqsave(&dio48egpio->lock, flags); + raw_spin_lock_irqsave(&dio48egpio->lock, flags); if (offset == 19) dio48egpio->irq_mask &= ~BIT(0); @@ -266,7 +266,7 @@ static void dio48e_irq_mask(struct irq_data *data) /* disable interrupts */ inb(dio48egpio->base + 0xB); - spin_unlock_irqrestore(&dio48egpio->lock, flags); + raw_spin_unlock_irqrestore(&dio48egpio->lock, flags); } static void dio48e_irq_unmask(struct irq_data *data) @@ -280,7 +280,7 @@ static void dio48e_irq_unmask(struct irq_data *data) if (offset != 19 && offset != 43) return; - spin_lock_irqsave(&dio48egpio->lock, flags); + raw_spin_lock_irqsave(&dio48egpio->lock, flags); if (!dio48egpio->irq_mask) { /* enable interrupts */ @@ -293,7 +293,7 @@ static void dio48e_irq_unmask(struct irq_data *data) else dio48egpio->irq_mask |= BIT(1); - spin_unlock_irqrestore(&dio48egpio->lock, flags); + raw_spin_unlock_irqrestore(&dio48egpio->lock, flags); } static int dio48e_irq_set_type(struct irq_data *data, unsigned flow_type) @@ -329,11 +329,11 @@ static irqreturn_t dio48e_irq_handler(int irq, void *dev_id) generic_handle_irq(irq_find_mapping(chip->irqdomain, 19 + gpio*24)); - spin_lock(&dio48egpio->lock); + raw_spin_lock(&dio48egpio->lock); outb(0x00, dio48egpio->base + 0xF); - spin_unlock(&dio48egpio->lock); + raw_spin_unlock(&dio48egpio->lock); return IRQ_HANDLED; } @@ -388,7 +388,7 @@ static int dio48e_probe(struct device *dev, unsigned int id) dio48egpio->chip.set_multiple = dio48e_gpio_set_multiple; dio48egpio->base = base[id]; - spin_lock_init(&dio48egpio->lock); + raw_spin_lock_init(&dio48egpio->lock); err = devm_gpiochip_add_data(dev, &dio48egpio->chip, dio48egpio); if (err) { diff --git a/drivers/gpio/gpio-104-idi-48.c b/drivers/gpio/gpio-104-idi-48.c index 568375a7ebc2..337c048168d8 100644 --- a/drivers/gpio/gpio-104-idi-48.c +++ b/drivers/gpio/gpio-104-idi-48.c @@ -51,7 +51,7 @@ MODULE_PARM_DESC(irq, "ACCES 104-IDI-48 interrupt line numbers"); */ struct idi_48_gpio { struct gpio_chip chip; - spinlock_t lock; + raw_spinlock_t lock; spinlock_t ack_lock; unsigned char irq_mask[6]; unsigned base; @@ -112,11 +112,12 @@ static void idi_48_irq_mask(struct irq_data *data) if (!idi48gpio->irq_mask[boundary]) { idi48gpio->cos_enb &= ~BIT(boundary); - spin_lock_irqsave(&idi48gpio->lock, flags); + raw_spin_lock_irqsave(&idi48gpio->lock, flags); outb(idi48gpio->cos_enb, idi48gpio->base + 7); - spin_unlock_irqrestore(&idi48gpio->lock, flags); + raw_spin_unlock_irqrestore(&idi48gpio->lock, + flags); } return; @@ -145,11 +146,12 @@ static void idi_48_irq_unmask(struct irq_data *data) if (!prev_irq_mask) { idi48gpio->cos_enb |= BIT(boundary); - spin_lock_irqsave(&idi48gpio->lock, flags); + raw_spin_lock_irqsave(&idi48gpio->lock, flags); outb(idi48gpio->cos_enb, idi48gpio->base + 7); - spin_unlock_irqrestore(&idi48gpio->lock, flags); + raw_spin_unlock_irqrestore(&idi48gpio->lock, + flags); } return; @@ -186,11 +188,11 @@ static irqreturn_t idi_48_irq_handler(int irq, void *dev_id) spin_lock(&idi48gpio->ack_lock); - spin_lock(&idi48gpio->lock); + raw_spin_lock(&idi48gpio->lock); cos_status = inb(idi48gpio->base + 7); - spin_unlock(&idi48gpio->lock); + raw_spin_unlock(&idi48gpio->lock); /* IRQ Status (bit 6) is active low (0 = IRQ generated by device) */ if (cos_status & BIT(6)) { @@ -256,7 +258,7 @@ static int idi_48_probe(struct device *dev, unsigned int id) idi48gpio->chip.get = idi_48_gpio_get; idi48gpio->base = base[id]; - spin_lock_init(&idi48gpio->lock); + raw_spin_lock_init(&idi48gpio->lock); spin_lock_init(&idi48gpio->ack_lock); err = devm_gpiochip_add_data(dev, &idi48gpio->chip, idi48gpio); diff --git a/drivers/gpio/gpio-104-idio-16.c b/drivers/gpio/gpio-104-idio-16.c index 7053cf736648..5281e1cedb01 100644 --- a/drivers/gpio/gpio-104-idio-16.c +++ b/drivers/gpio/gpio-104-idio-16.c @@ -50,7 +50,7 @@ MODULE_PARM_DESC(irq, "ACCES 104-IDIO-16 interrupt line numbers"); */ struct idio_16_gpio { struct gpio_chip chip; - spinlock_t lock; + raw_spinlock_t lock; unsigned long irq_mask; unsigned base; unsigned out_state; @@ -99,7 +99,7 @@ static void idio_16_gpio_set(struct gpio_chip *chip, unsigned offset, int value) if (offset > 15) return; - spin_lock_irqsave(&idio16gpio->lock, flags); + raw_spin_lock_irqsave(&idio16gpio->lock, flags); if (value) idio16gpio->out_state |= mask; @@ -111,7 +111,7 @@ static void idio_16_gpio_set(struct gpio_chip *chip, unsigned offset, int value) else outb(idio16gpio->out_state, idio16gpio->base); - spin_unlock_irqrestore(&idio16gpio->lock, flags); + raw_spin_unlock_irqrestore(&idio16gpio->lock, flags); } static void idio_16_gpio_set_multiple(struct gpio_chip *chip, @@ -120,7 +120,7 @@ static void idio_16_gpio_set_multiple(struct gpio_chip *chip, struct idio_16_gpio *const idio16gpio = gpiochip_get_data(chip); unsigned long flags; - spin_lock_irqsave(&idio16gpio->lock, flags); + raw_spin_lock_irqsave(&idio16gpio->lock, flags); idio16gpio->out_state &= ~*mask; idio16gpio->out_state |= *mask & *bits; @@ -130,7 +130,7 @@ static void idio_16_gpio_set_multiple(struct gpio_chip *chip, if ((*mask >> 8) & 0xFF) outb(idio16gpio->out_state >> 8, idio16gpio->base + 4); - spin_unlock_irqrestore(&idio16gpio->lock, flags); + raw_spin_unlock_irqrestore(&idio16gpio->lock, flags); } static void idio_16_irq_ack(struct irq_data *data) @@ -147,11 +147,11 @@ static void idio_16_irq_mask(struct irq_data *data) idio16gpio->irq_mask &= ~mask; if (!idio16gpio->irq_mask) { - spin_lock_irqsave(&idio16gpio->lock, flags); + raw_spin_lock_irqsave(&idio16gpio->lock, flags); outb(0, idio16gpio->base + 2); - spin_unlock_irqrestore(&idio16gpio->lock, flags); + raw_spin_unlock_irqrestore(&idio16gpio->lock, flags); } } @@ -166,11 +166,11 @@ static void idio_16_irq_unmask(struct irq_data *data) idio16gpio->irq_mask |= mask; if (!prev_irq_mask) { - spin_lock_irqsave(&idio16gpio->lock, flags); + raw_spin_lock_irqsave(&idio16gpio->lock, flags); inb(idio16gpio->base + 2); - spin_unlock_irqrestore(&idio16gpio->lock, flags); + raw_spin_unlock_irqrestore(&idio16gpio->lock, flags); } } @@ -201,11 +201,11 @@ static irqreturn_t idio_16_irq_handler(int irq, void *dev_id) for_each_set_bit(gpio, &idio16gpio->irq_mask, chip->ngpio) generic_handle_irq(irq_find_mapping(chip->irqdomain, gpio)); - spin_lock(&idio16gpio->lock); + raw_spin_lock(&idio16gpio->lock); outb(0, idio16gpio->base + 1); - spin_unlock(&idio16gpio->lock); + raw_spin_unlock(&idio16gpio->lock); return IRQ_HANDLED; } @@ -249,7 +249,7 @@ static int idio_16_probe(struct device *dev, unsigned int id) idio16gpio->base = base[id]; idio16gpio->out_state = 0xFFFF; - spin_lock_init(&idio16gpio->lock); + raw_spin_lock_init(&idio16gpio->lock); err = devm_gpiochip_add_data(dev, &idio16gpio->chip, idio16gpio); if (err) { diff --git a/drivers/gpio/gpio-altera.c b/drivers/gpio/gpio-altera.c index 3fe6a21e05a5..17485dc20384 100644 --- a/drivers/gpio/gpio-altera.c +++ b/drivers/gpio/gpio-altera.c @@ -38,7 +38,7 @@ */ struct altera_gpio_chip { struct of_mm_gpio_chip mmchip; - spinlock_t gpio_lock; + raw_spinlock_t gpio_lock; int interrupt_trigger; int mapped_irq; }; @@ -53,12 +53,12 @@ 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; - spin_lock_irqsave(&altera_gc->gpio_lock, flags); + raw_spin_lock_irqsave(&altera_gc->gpio_lock, flags); intmask = readl(mm_gc->regs + ALTERA_GPIO_IRQ_MASK); /* Set ALTERA_GPIO_IRQ_MASK bit to unmask */ intmask |= BIT(irqd_to_hwirq(d)); writel(intmask, mm_gc->regs + ALTERA_GPIO_IRQ_MASK); - spin_unlock_irqrestore(&altera_gc->gpio_lock, flags); + raw_spin_unlock_irqrestore(&altera_gc->gpio_lock, flags); } static void altera_gpio_irq_mask(struct irq_data *d) @@ -71,12 +71,12 @@ static void altera_gpio_irq_mask(struct irq_data *d) altera_gc = gpiochip_get_data(irq_data_get_irq_chip_data(d)); mm_gc = &altera_gc->mmchip; - spin_lock_irqsave(&altera_gc->gpio_lock, flags); + raw_spin_lock_irqsave(&altera_gc->gpio_lock, flags); intmask = readl(mm_gc->regs + ALTERA_GPIO_IRQ_MASK); /* Clear ALTERA_GPIO_IRQ_MASK bit to mask */ intmask &= ~BIT(irqd_to_hwirq(d)); writel(intmask, mm_gc->regs + ALTERA_GPIO_IRQ_MASK); - spin_unlock_irqrestore(&altera_gc->gpio_lock, flags); + raw_spin_unlock_irqrestore(&altera_gc->gpio_lock, flags); } /** @@ -140,14 +140,14 @@ static void altera_gpio_set(struct gpio_chip *gc, unsigned offset, int value) mm_gc = to_of_mm_gpio_chip(gc); chip = gpiochip_get_data(gc); - spin_lock_irqsave(&chip->gpio_lock, flags); + raw_spin_lock_irqsave(&chip->gpio_lock, flags); data_reg = readl(mm_gc->regs + ALTERA_GPIO_DATA); if (value) data_reg |= BIT(offset); else data_reg &= ~BIT(offset); writel(data_reg, mm_gc->regs + ALTERA_GPIO_DATA); - spin_unlock_irqrestore(&chip->gpio_lock, flags); + raw_spin_unlock_irqrestore(&chip->gpio_lock, flags); } static int altera_gpio_direction_input(struct gpio_chip *gc, unsigned offset) @@ -160,12 +160,12 @@ static int altera_gpio_direction_input(struct gpio_chip *gc, unsigned offset) mm_gc = to_of_mm_gpio_chip(gc); chip = gpiochip_get_data(gc); - spin_lock_irqsave(&chip->gpio_lock, flags); + raw_spin_lock_irqsave(&chip->gpio_lock, flags); /* Set pin as input, assumes software controlled IP */ gpio_ddr = readl(mm_gc->regs + ALTERA_GPIO_DIR); gpio_ddr &= ~BIT(offset); writel(gpio_ddr, mm_gc->regs + ALTERA_GPIO_DIR); - spin_unlock_irqrestore(&chip->gpio_lock, flags); + raw_spin_unlock_irqrestore(&chip->gpio_lock, flags); return 0; } @@ -181,7 +181,7 @@ static int altera_gpio_direction_output(struct gpio_chip *gc, mm_gc = to_of_mm_gpio_chip(gc); chip = gpiochip_get_data(gc); - spin_lock_irqsave(&chip->gpio_lock, flags); + raw_spin_lock_irqsave(&chip->gpio_lock, flags); /* Sets the GPIO value */ data_reg = readl(mm_gc->regs + ALTERA_GPIO_DATA); if (value) @@ -194,7 +194,7 @@ static int altera_gpio_direction_output(struct gpio_chip *gc, gpio_ddr = readl(mm_gc->regs + ALTERA_GPIO_DIR); gpio_ddr |= BIT(offset); writel(gpio_ddr, mm_gc->regs + ALTERA_GPIO_DIR); - spin_unlock_irqrestore(&chip->gpio_lock, flags); + raw_spin_unlock_irqrestore(&chip->gpio_lock, flags); return 0; } @@ -262,7 +262,7 @@ static int altera_gpio_probe(struct platform_device *pdev) if (!altera_gc) return -ENOMEM; - spin_lock_init(&altera_gc->gpio_lock); + raw_spin_lock_init(&altera_gc->gpio_lock); if (of_property_read_u32(node, "altr,ngpio", ®)) /* By default assume maximum ngpio */ diff --git a/drivers/gpio/gpio-ath79.c b/drivers/gpio/gpio-ath79.c index dc37dbe4b46d..f33d4a5fe671 100644 --- a/drivers/gpio/gpio-ath79.c +++ b/drivers/gpio/gpio-ath79.c @@ -32,7 +32,7 @@ struct ath79_gpio_ctrl { struct gpio_chip gc; void __iomem *base; - spinlock_t lock; + raw_spinlock_t lock; unsigned long both_edges; }; @@ -74,9 +74,9 @@ static void ath79_gpio_irq_unmask(struct irq_data *data) u32 mask = BIT(irqd_to_hwirq(data)); unsigned long flags; - spin_lock_irqsave(&ctrl->lock, flags); + raw_spin_lock_irqsave(&ctrl->lock, flags); ath79_gpio_update_bits(ctrl, AR71XX_GPIO_REG_INT_MASK, mask, mask); - spin_unlock_irqrestore(&ctrl->lock, flags); + raw_spin_unlock_irqrestore(&ctrl->lock, flags); } static void ath79_gpio_irq_mask(struct irq_data *data) @@ -85,9 +85,9 @@ static void ath79_gpio_irq_mask(struct irq_data *data) u32 mask = BIT(irqd_to_hwirq(data)); unsigned long flags; - spin_lock_irqsave(&ctrl->lock, flags); + raw_spin_lock_irqsave(&ctrl->lock, flags); ath79_gpio_update_bits(ctrl, AR71XX_GPIO_REG_INT_MASK, mask, 0); - spin_unlock_irqrestore(&ctrl->lock, flags); + raw_spin_unlock_irqrestore(&ctrl->lock, flags); } static void ath79_gpio_irq_enable(struct irq_data *data) @@ -96,10 +96,10 @@ static void ath79_gpio_irq_enable(struct irq_data *data) u32 mask = BIT(irqd_to_hwirq(data)); unsigned long flags; - spin_lock_irqsave(&ctrl->lock, flags); + raw_spin_lock_irqsave(&ctrl->lock, flags); ath79_gpio_update_bits(ctrl, AR71XX_GPIO_REG_INT_ENABLE, mask, mask); ath79_gpio_update_bits(ctrl, AR71XX_GPIO_REG_INT_MASK, mask, mask); - spin_unlock_irqrestore(&ctrl->lock, flags); + raw_spin_unlock_irqrestore(&ctrl->lock, flags); } static void ath79_gpio_irq_disable(struct irq_data *data) @@ -108,10 +108,10 @@ static void ath79_gpio_irq_disable(struct irq_data *data) u32 mask = BIT(irqd_to_hwirq(data)); unsigned long flags; - spin_lock_irqsave(&ctrl->lock, flags); + raw_spin_lock_irqsave(&ctrl->lock, flags); ath79_gpio_update_bits(ctrl, AR71XX_GPIO_REG_INT_MASK, mask, 0); ath79_gpio_update_bits(ctrl, AR71XX_GPIO_REG_INT_ENABLE, mask, 0); - spin_unlock_irqrestore(&ctrl->lock, flags); + raw_spin_unlock_irqrestore(&ctrl->lock, flags); } static int ath79_gpio_irq_set_type(struct irq_data *data, @@ -140,7 +140,7 @@ static int ath79_gpio_irq_set_type(struct irq_data *data, return -EINVAL; } - spin_lock_irqsave(&ctrl->lock, flags); + raw_spin_lock_irqsave(&ctrl->lock, flags); if (flow_type == IRQ_TYPE_EDGE_BOTH) { ctrl->both_edges |= mask; @@ -165,7 +165,7 @@ static int ath79_gpio_irq_set_type(struct irq_data *data, ath79_gpio_update_bits( ctrl, AR71XX_GPIO_REG_INT_ENABLE, mask, mask); - spin_unlock_irqrestore(&ctrl->lock, flags); + raw_spin_unlock_irqrestore(&ctrl->lock, flags); return 0; } @@ -191,7 +191,7 @@ static void ath79_gpio_irq_handler(struct irq_desc *desc) chained_irq_enter(irqchip, desc); - spin_lock_irqsave(&ctrl->lock, flags); + raw_spin_lock_irqsave(&ctrl->lock, flags); pending = ath79_gpio_read(ctrl, AR71XX_GPIO_REG_INT_PENDING); @@ -203,7 +203,7 @@ static void ath79_gpio_irq_handler(struct irq_desc *desc) both_edges, ~state); } - spin_unlock_irqrestore(&ctrl->lock, flags); + raw_spin_unlock_irqrestore(&ctrl->lock, flags); if (pending) { for_each_set_bit(irq, &pending, gc->ngpio) @@ -262,7 +262,7 @@ static int ath79_gpio_probe(struct platform_device *pdev) if (!ctrl->base) return -ENOMEM; - spin_lock_init(&ctrl->lock); + raw_spin_lock_init(&ctrl->lock); err = bgpio_init(&ctrl->gc, &pdev->dev, 4, ctrl->base + AR71XX_GPIO_REG_IN, ctrl->base + AR71XX_GPIO_REG_SET, diff --git a/drivers/gpio/gpio-bcm-kona.c b/drivers/gpio/gpio-bcm-kona.c index 41d0ac142580..dfcf56ee3c61 100644 --- a/drivers/gpio/gpio-bcm-kona.c +++ b/drivers/gpio/gpio-bcm-kona.c @@ -67,7 +67,7 @@ struct bcm_kona_gpio { void __iomem *reg_base; int num_bank; - spinlock_t lock; + raw_spinlock_t lock; struct gpio_chip gpio_chip; struct irq_domain *irq_domain; struct bcm_kona_gpio_bank *banks; @@ -95,13 +95,13 @@ static void bcm_kona_gpio_lock_gpio(struct bcm_kona_gpio *kona_gpio, unsigned long flags; int bank_id = GPIO_BANK(gpio); - spin_lock_irqsave(&kona_gpio->lock, flags); + raw_spin_lock_irqsave(&kona_gpio->lock, flags); val = readl(kona_gpio->reg_base + GPIO_PWD_STATUS(bank_id)); val |= BIT(gpio); bcm_kona_gpio_write_lock_regs(kona_gpio->reg_base, bank_id, val); - spin_unlock_irqrestore(&kona_gpio->lock, flags); + raw_spin_unlock_irqrestore(&kona_gpio->lock, flags); } static void bcm_kona_gpio_unlock_gpio(struct bcm_kona_gpio *kona_gpio, @@ -111,13 +111,13 @@ static void bcm_kona_gpio_unlock_gpio(struct bcm_kona_gpio *kona_gpio, unsigned long flags; int bank_id = GPIO_BANK(gpio); - spin_lock_irqsave(&kona_gpio->lock, flags); + raw_spin_lock_irqsave(&kona_gpio->lock, flags); val = readl(kona_gpio->reg_base + GPIO_PWD_STATUS(bank_id)); val &= ~BIT(gpio); bcm_kona_gpio_write_lock_regs(kona_gpio->reg_base, bank_id, val); - spin_unlock_irqrestore(&kona_gpio->lock, flags); + raw_spin_unlock_irqrestore(&kona_gpio->lock, flags); } static int bcm_kona_gpio_get_dir(struct gpio_chip *chip, unsigned gpio) @@ -141,7 +141,7 @@ static void bcm_kona_gpio_set(struct gpio_chip *chip, unsigned gpio, int value) kona_gpio = gpiochip_get_data(chip); reg_base = kona_gpio->reg_base; - spin_lock_irqsave(&kona_gpio->lock, flags); + raw_spin_lock_irqsave(&kona_gpio->lock, flags); /* this function only applies to output pin */ if (bcm_kona_gpio_get_dir(chip, gpio) == GPIOF_DIR_IN) @@ -154,7 +154,7 @@ static void bcm_kona_gpio_set(struct gpio_chip *chip, unsigned gpio, int value) writel(val, reg_base + reg_offset); out: - spin_unlock_irqrestore(&kona_gpio->lock, flags); + raw_spin_unlock_irqrestore(&kona_gpio->lock, flags); } static int bcm_kona_gpio_get(struct gpio_chip *chip, unsigned gpio) @@ -168,7 +168,7 @@ static int bcm_kona_gpio_get(struct gpio_chip *chip, unsigned gpio) kona_gpio = gpiochip_get_data(chip); reg_base = kona_gpio->reg_base; - spin_lock_irqsave(&kona_gpio->lock, flags); + raw_spin_lock_irqsave(&kona_gpio->lock, flags); if (bcm_kona_gpio_get_dir(chip, gpio) == GPIOF_DIR_IN) reg_offset = GPIO_IN_STATUS(bank_id); @@ -178,7 +178,7 @@ static int bcm_kona_gpio_get(struct gpio_chip *chip, unsigned gpio) /* read the GPIO bank status */ val = readl(reg_base + reg_offset); - spin_unlock_irqrestore(&kona_gpio->lock, flags); + raw_spin_unlock_irqrestore(&kona_gpio->lock, flags); /* return the specified bit status */ return !!(val & BIT(bit)); @@ -208,14 +208,14 @@ static int bcm_kona_gpio_direction_input(struct gpio_chip *chip, unsigned gpio) kona_gpio = gpiochip_get_data(chip); reg_base = kona_gpio->reg_base; - spin_lock_irqsave(&kona_gpio->lock, flags); + raw_spin_lock_irqsave(&kona_gpio->lock, flags); val = readl(reg_base + GPIO_CONTROL(gpio)); val &= ~GPIO_GPCTR0_IOTR_MASK; val |= GPIO_GPCTR0_IOTR_CMD_INPUT; writel(val, reg_base + GPIO_CONTROL(gpio)); - spin_unlock_irqrestore(&kona_gpio->lock, flags); + raw_spin_unlock_irqrestore(&kona_gpio->lock, flags); return 0; } @@ -232,7 +232,7 @@ static int bcm_kona_gpio_direction_output(struct gpio_chip *chip, kona_gpio = gpiochip_get_data(chip); reg_base = kona_gpio->reg_base; - spin_lock_irqsave(&kona_gpio->lock, flags); + raw_spin_lock_irqsave(&kona_gpio->lock, flags); val = readl(reg_base + GPIO_CONTROL(gpio)); val &= ~GPIO_GPCTR0_IOTR_MASK; @@ -244,7 +244,7 @@ static int bcm_kona_gpio_direction_output(struct gpio_chip *chip, val |= BIT(bit); writel(val, reg_base + reg_offset); - spin_unlock_irqrestore(&kona_gpio->lock, flags); + raw_spin_unlock_irqrestore(&kona_gpio->lock, flags); return 0; } @@ -288,7 +288,7 @@ static int bcm_kona_gpio_set_debounce(struct gpio_chip *chip, unsigned gpio, } /* spin lock for read-modify-write of the GPIO register */ - spin_lock_irqsave(&kona_gpio->lock, flags); + raw_spin_lock_irqsave(&kona_gpio->lock, flags); val = readl(reg_base + GPIO_CONTROL(gpio)); val &= ~GPIO_GPCTR0_DBR_MASK; @@ -303,7 +303,7 @@ static int bcm_kona_gpio_set_debounce(struct gpio_chip *chip, unsigned gpio, writel(val, reg_base + GPIO_CONTROL(gpio)); - spin_unlock_irqrestore(&kona_gpio->lock, flags); + raw_spin_unlock_irqrestore(&kona_gpio->lock, flags); return 0; } @@ -347,13 +347,13 @@ static void bcm_kona_gpio_irq_ack(struct irq_data *d) kona_gpio = irq_data_get_irq_chip_data(d); reg_base = kona_gpio->reg_base; - spin_lock_irqsave(&kona_gpio->lock, flags); + raw_spin_lock_irqsave(&kona_gpio->lock, flags); val = readl(reg_base + GPIO_INT_STATUS(bank_id)); val |= BIT(bit); writel(val, reg_base + GPIO_INT_STATUS(bank_id)); - spin_unlock_irqrestore(&kona_gpio->lock, flags); + raw_spin_unlock_irqrestore(&kona_gpio->lock, flags); } static void bcm_kona_gpio_irq_mask(struct irq_data *d) @@ -368,13 +368,13 @@ static void bcm_kona_gpio_irq_mask(struct irq_data *d) kona_gpio = irq_data_get_irq_chip_data(d); reg_base = kona_gpio->reg_base; - spin_lock_irqsave(&kona_gpio->lock, flags); + raw_spin_lock_irqsave(&kona_gpio->lock, flags); val = readl(reg_base + GPIO_INT_MASK(bank_id)); val |= BIT(bit); writel(val, reg_base + GPIO_INT_MASK(bank_id)); - spin_unlock_irqrestore(&kona_gpio->lock, flags); + raw_spin_unlock_irqrestore(&kona_gpio->lock, flags); } static void bcm_kona_gpio_irq_unmask(struct irq_data *d) @@ -389,13 +389,13 @@ static void bcm_kona_gpio_irq_unmask(struct irq_data *d) kona_gpio = irq_data_get_irq_chip_data(d); reg_base = kona_gpio->reg_base; - spin_lock_irqsave(&kona_gpio->lock, flags); + raw_spin_lock_irqsave(&kona_gpio->lock, flags); val = readl(reg_base + GPIO_INT_MSKCLR(bank_id)); val |= BIT(bit); writel(val, reg_base + GPIO_INT_MSKCLR(bank_id)); - spin_unlock_irqrestore(&kona_gpio->lock, flags); + raw_spin_unlock_irqrestore(&kona_gpio->lock, flags); } static int bcm_kona_gpio_irq_set_type(struct irq_data *d, unsigned int type) @@ -431,14 +431,14 @@ static int bcm_kona_gpio_irq_set_type(struct irq_data *d, unsigned int type) return -EINVAL; } - spin_lock_irqsave(&kona_gpio->lock, flags); + raw_spin_lock_irqsave(&kona_gpio->lock, flags); val = readl(reg_base + GPIO_CONTROL(gpio)); val &= ~GPIO_GPCTR0_ITR_MASK; val |= lvl_type << GPIO_GPCTR0_ITR_SHIFT; writel(val, reg_base + GPIO_CONTROL(gpio)); - spin_unlock_irqrestore(&kona_gpio->lock, flags); + raw_spin_unlock_irqrestore(&kona_gpio->lock, flags); return 0; } @@ -655,7 +655,7 @@ static int bcm_kona_gpio_probe(struct platform_device *pdev) bank); } - spin_lock_init(&kona_gpio->lock); + raw_spin_lock_init(&kona_gpio->lock); return 0; diff --git a/drivers/gpio/gpio-davinci.c b/drivers/gpio/gpio-davinci.c index 72f49d1e110d..ac173575d3f6 100644 --- a/drivers/gpio/gpio-davinci.c +++ b/drivers/gpio/gpio-davinci.c @@ -483,7 +483,7 @@ static int davinci_gpio_irq_setup(struct platform_device *pdev) clk_prepare_enable(clk); if (!pdata->gpio_unbanked) { - irq = irq_alloc_descs(-1, 0, ngpio, 0); + irq = devm_irq_alloc_descs(dev, -1, 0, ngpio, 0); if (irq < 0) { dev_err(dev, "Couldn't allocate IRQ numbers\n"); return irq; diff --git a/drivers/gpio/gpio-dwapb.c b/drivers/gpio/gpio-dwapb.c index 9c15ee4ef4e9..53ade0b69f49 100644 --- a/drivers/gpio/gpio-dwapb.c +++ b/drivers/gpio/gpio-dwapb.c @@ -21,6 +21,7 @@ #include <linux/module.h> #include <linux/of.h> #include <linux/of_address.h> +#include <linux/of_device.h> #include <linux/of_irq.h> #include <linux/platform_device.h> #include <linux/property.h> @@ -55,6 +56,14 @@ #define GPIO_SWPORT_DR_SIZE (GPIO_SWPORTB_DR - GPIO_SWPORTA_DR) #define GPIO_SWPORT_DDR_SIZE (GPIO_SWPORTB_DDR - GPIO_SWPORTA_DDR) +#define GPIO_REG_OFFSET_V2 1 + +#define GPIO_INTMASK_V2 0x44 +#define GPIO_INTTYPE_LEVEL_V2 0x34 +#define GPIO_INT_POLARITY_V2 0x38 +#define GPIO_INTSTATUS_V2 0x3c +#define GPIO_PORTA_EOI_V2 0x40 + struct dwapb_gpio; #ifdef CONFIG_PM_SLEEP @@ -87,14 +96,41 @@ struct dwapb_gpio { struct dwapb_gpio_port *ports; unsigned int nr_ports; struct irq_domain *domain; + unsigned int flags; }; +static inline u32 gpio_reg_v2_convert(unsigned int offset) +{ + switch (offset) { + case GPIO_INTMASK: + return GPIO_INTMASK_V2; + case GPIO_INTTYPE_LEVEL: + return GPIO_INTTYPE_LEVEL_V2; + case GPIO_INT_POLARITY: + return GPIO_INT_POLARITY_V2; + case GPIO_INTSTATUS: + return GPIO_INTSTATUS_V2; + case GPIO_PORTA_EOI: + return GPIO_PORTA_EOI_V2; + } + + return offset; +} + +static inline u32 gpio_reg_convert(struct dwapb_gpio *gpio, unsigned int offset) +{ + if (gpio->flags & GPIO_REG_OFFSET_V2) + return gpio_reg_v2_convert(offset); + + return offset; +} + static inline u32 dwapb_read(struct dwapb_gpio *gpio, unsigned int offset) { struct gpio_chip *gc = &gpio->ports[0].gc; void __iomem *reg_base = gpio->regs; - return gc->read_reg(reg_base + offset); + return gc->read_reg(reg_base + gpio_reg_convert(gpio, offset)); } static inline void dwapb_write(struct dwapb_gpio *gpio, unsigned int offset, @@ -103,7 +139,7 @@ static inline void dwapb_write(struct dwapb_gpio *gpio, unsigned int offset, struct gpio_chip *gc = &gpio->ports[0].gc; void __iomem *reg_base = gpio->regs; - gc->write_reg(reg_base + offset, val); + gc->write_reg(reg_base + gpio_reg_convert(gpio, offset), val); } static int dwapb_gpio_to_irq(struct gpio_chip *gc, unsigned offset) @@ -348,8 +384,8 @@ static void dwapb_configure_irqs(struct dwapb_gpio *gpio, ct->chip.irq_disable = dwapb_irq_disable; ct->chip.irq_request_resources = dwapb_irq_reqres; ct->chip.irq_release_resources = dwapb_irq_relres; - ct->regs.ack = GPIO_PORTA_EOI; - ct->regs.mask = GPIO_INTMASK; + ct->regs.ack = gpio_reg_convert(gpio, GPIO_PORTA_EOI); + ct->regs.mask = gpio_reg_convert(gpio, GPIO_INTMASK); ct->type = IRQ_TYPE_LEVEL_MASK; } @@ -532,6 +568,21 @@ dwapb_gpio_get_pdata(struct device *dev) return pdata; } +static const struct of_device_id dwapb_of_match[] = { + { .compatible = "snps,dw-apb-gpio", .data = (void *)0}, + { .compatible = "apm,xgene-gpio-v2", .data = (void *)GPIO_REG_OFFSET_V2}, + { /* Sentinel */ } +}; +MODULE_DEVICE_TABLE(of, dwapb_of_match); + +static const struct acpi_device_id dwapb_acpi_match[] = { + {"HISI0181", 0}, + {"APMC0D07", 0}, + {"APMC0D81", GPIO_REG_OFFSET_V2}, + { } +}; +MODULE_DEVICE_TABLE(acpi, dwapb_acpi_match); + static int dwapb_gpio_probe(struct platform_device *pdev) { unsigned int i; @@ -567,6 +618,25 @@ static int dwapb_gpio_probe(struct platform_device *pdev) if (IS_ERR(gpio->regs)) return PTR_ERR(gpio->regs); + gpio->flags = 0; + if (dev->of_node) { + const struct of_device_id *of_devid; + + of_devid = of_match_device(dwapb_of_match, dev); + if (of_devid) { + if (of_devid->data) + gpio->flags = (uintptr_t)of_devid->data; + } + } else if (has_acpi_companion(dev)) { + const struct acpi_device_id *acpi_id; + + acpi_id = acpi_match_device(dwapb_acpi_match, dev); + if (acpi_id) { + if (acpi_id->driver_data) + gpio->flags = acpi_id->driver_data; + } + } + for (i = 0; i < gpio->nr_ports; i++) { err = dwapb_gpio_add_port(gpio, &pdata->properties[i], i); if (err) @@ -593,19 +663,6 @@ static int dwapb_gpio_remove(struct platform_device *pdev) return 0; } -static const struct of_device_id dwapb_of_match[] = { - { .compatible = "snps,dw-apb-gpio" }, - { /* Sentinel */ } -}; -MODULE_DEVICE_TABLE(of, dwapb_of_match); - -static const struct acpi_device_id dwapb_acpi_match[] = { - {"HISI0181", 0}, - {"APMC0D07", 0}, - { } -}; -MODULE_DEVICE_TABLE(acpi, dwapb_acpi_match); - #ifdef CONFIG_PM_SLEEP static int dwapb_gpio_suspend(struct device *dev) { diff --git a/drivers/gpio/gpio-etraxfs.c b/drivers/gpio/gpio-etraxfs.c index a254d5b07b94..14c6aac26780 100644 --- a/drivers/gpio/gpio-etraxfs.c +++ b/drivers/gpio/gpio-etraxfs.c @@ -54,7 +54,7 @@ struct etraxfs_gpio_info; struct etraxfs_gpio_block { - spinlock_t lock; + raw_spinlock_t lock; u32 mask; u32 cfg; u32 pins; @@ -233,10 +233,10 @@ static void etraxfs_gpio_irq_mask(struct irq_data *d) struct etraxfs_gpio_block *block = chip->block; unsigned int grpirq = etraxfs_gpio_to_group_irq(d->hwirq); - spin_lock(&block->lock); + raw_spin_lock(&block->lock); block->mask &= ~BIT(grpirq); writel(block->mask, block->regs + block->info->rw_intr_mask); - spin_unlock(&block->lock); + raw_spin_unlock(&block->lock); } static void etraxfs_gpio_irq_unmask(struct irq_data *d) @@ -246,10 +246,10 @@ static void etraxfs_gpio_irq_unmask(struct irq_data *d) struct etraxfs_gpio_block *block = chip->block; unsigned int grpirq = etraxfs_gpio_to_group_irq(d->hwirq); - spin_lock(&block->lock); + raw_spin_lock(&block->lock); block->mask |= BIT(grpirq); writel(block->mask, block->regs + block->info->rw_intr_mask); - spin_unlock(&block->lock); + raw_spin_unlock(&block->lock); } static int etraxfs_gpio_irq_set_type(struct irq_data *d, u32 type) @@ -280,11 +280,11 @@ static int etraxfs_gpio_irq_set_type(struct irq_data *d, u32 type) return -EINVAL; } - spin_lock(&block->lock); + raw_spin_lock(&block->lock); block->cfg &= ~(0x7 << (grpirq * 3)); block->cfg |= (cfg << (grpirq * 3)); writel(block->cfg, block->regs + block->info->rw_intr_cfg); - spin_unlock(&block->lock); + raw_spin_unlock(&block->lock); return 0; } @@ -297,7 +297,7 @@ static int etraxfs_gpio_irq_request_resources(struct irq_data *d) unsigned int grpirq = etraxfs_gpio_to_group_irq(d->hwirq); int ret = -EBUSY; - spin_lock(&block->lock); + raw_spin_lock(&block->lock); if (block->group[grpirq]) goto out; @@ -316,7 +316,7 @@ static int etraxfs_gpio_irq_request_resources(struct irq_data *d) } out: - spin_unlock(&block->lock); + raw_spin_unlock(&block->lock); return ret; } @@ -327,10 +327,10 @@ static void etraxfs_gpio_irq_release_resources(struct irq_data *d) struct etraxfs_gpio_block *block = chip->block; unsigned int grpirq = etraxfs_gpio_to_group_irq(d->hwirq); - spin_lock(&block->lock); + raw_spin_lock(&block->lock); block->group[grpirq] = 0; gpiochip_unlock_as_irq(&chip->gc, d->hwirq); - spin_unlock(&block->lock); + raw_spin_unlock(&block->lock); } static struct irq_chip etraxfs_gpio_irq_chip = { @@ -391,7 +391,7 @@ static int etraxfs_gpio_probe(struct platform_device *pdev) if (!block) return -ENOMEM; - spin_lock_init(&block->lock); + raw_spin_lock_init(&block->lock); block->regs = regs; block->info = info; diff --git a/drivers/gpio/gpio-exar.c b/drivers/gpio/gpio-exar.c index 05c8946d6446..081076771217 100644 --- a/drivers/gpio/gpio-exar.c +++ b/drivers/gpio/gpio-exar.c @@ -59,17 +59,6 @@ static int exar_set_direction(struct gpio_chip *chip, int direction, return 0; } -static int exar_direction_output(struct gpio_chip *chip, unsigned int offset, - int value) -{ - return exar_set_direction(chip, 0, offset); -} - -static int exar_direction_input(struct gpio_chip *chip, unsigned int offset) -{ - return exar_set_direction(chip, 1, offset); -} - static int exar_get(struct gpio_chip *chip, unsigned int reg) { struct exar_gpio_chip *exar_gpio = gpiochip_get_data(chip); @@ -116,6 +105,18 @@ static void exar_set_value(struct gpio_chip *chip, unsigned int offset, exar_update(chip, addr, value, offset % 8); } +static int exar_direction_output(struct gpio_chip *chip, unsigned int offset, + int value) +{ + exar_set_value(chip, offset, value); + return exar_set_direction(chip, 0, offset); +} + +static int exar_direction_input(struct gpio_chip *chip, unsigned int offset) +{ + return exar_set_direction(chip, 1, offset); +} + static int gpio_exar_probe(struct platform_device *pdev) { struct pci_dev *pcidev = platform_get_drvdata(pdev); diff --git a/drivers/gpio/gpio-gemini.c b/drivers/gpio/gpio-ftgpio010.c index 962485163b7f..e9386f8b67f5 100644 --- a/drivers/gpio/gpio-gemini.c +++ b/drivers/gpio/gpio-ftgpio010.c @@ -1,5 +1,5 @@ /* - * Gemini gpiochip and interrupt routines + * Faraday Technolog FTGPIO010 gpiochip and interrupt routines * Copyright (C) 2017 Linus Walleij <linus.walleij@linaro.org> * * Based on arch/arm/mach-gemini/gpio.c: @@ -35,28 +35,28 @@ #define GPIO_DEBOUNCE_PRESCALE 0x44 /** - * struct gemini_gpio - Gemini GPIO state container + * struct ftgpio_gpio - Gemini GPIO state container * @dev: containing device for this instance * @gc: gpiochip for this instance */ -struct gemini_gpio { +struct ftgpio_gpio { struct device *dev; struct gpio_chip gc; void __iomem *base; }; -static void gemini_gpio_ack_irq(struct irq_data *d) +static void ftgpio_gpio_ack_irq(struct irq_data *d) { struct gpio_chip *gc = irq_data_get_irq_chip_data(d); - struct gemini_gpio *g = gpiochip_get_data(gc); + struct ftgpio_gpio *g = gpiochip_get_data(gc); writel(BIT(irqd_to_hwirq(d)), g->base + GPIO_INT_CLR); } -static void gemini_gpio_mask_irq(struct irq_data *d) +static void ftgpio_gpio_mask_irq(struct irq_data *d) { struct gpio_chip *gc = irq_data_get_irq_chip_data(d); - struct gemini_gpio *g = gpiochip_get_data(gc); + struct ftgpio_gpio *g = gpiochip_get_data(gc); u32 val; val = readl(g->base + GPIO_INT_EN); @@ -64,10 +64,10 @@ static void gemini_gpio_mask_irq(struct irq_data *d) writel(val, g->base + GPIO_INT_EN); } -static void gemini_gpio_unmask_irq(struct irq_data *d) +static void ftgpio_gpio_unmask_irq(struct irq_data *d) { struct gpio_chip *gc = irq_data_get_irq_chip_data(d); - struct gemini_gpio *g = gpiochip_get_data(gc); + struct ftgpio_gpio *g = gpiochip_get_data(gc); u32 val; val = readl(g->base + GPIO_INT_EN); @@ -75,10 +75,10 @@ static void gemini_gpio_unmask_irq(struct irq_data *d) writel(val, g->base + GPIO_INT_EN); } -static int gemini_gpio_set_irq_type(struct irq_data *d, unsigned int type) +static int ftgpio_gpio_set_irq_type(struct irq_data *d, unsigned int type) { struct gpio_chip *gc = irq_data_get_irq_chip_data(d); - struct gemini_gpio *g = gpiochip_get_data(gc); + struct ftgpio_gpio *g = gpiochip_get_data(gc); u32 mask = BIT(irqd_to_hwirq(d)); u32 reg_both, reg_level, reg_type; @@ -123,23 +123,23 @@ static int gemini_gpio_set_irq_type(struct irq_data *d, unsigned int type) writel(reg_level, g->base + GPIO_INT_LEVEL); writel(reg_both, g->base + GPIO_INT_BOTH_EDGE); - gemini_gpio_ack_irq(d); + ftgpio_gpio_ack_irq(d); return 0; } -static struct irq_chip gemini_gpio_irqchip = { - .name = "GPIO", - .irq_ack = gemini_gpio_ack_irq, - .irq_mask = gemini_gpio_mask_irq, - .irq_unmask = gemini_gpio_unmask_irq, - .irq_set_type = gemini_gpio_set_irq_type, +static struct irq_chip ftgpio_gpio_irqchip = { + .name = "FTGPIO010", + .irq_ack = ftgpio_gpio_ack_irq, + .irq_mask = ftgpio_gpio_mask_irq, + .irq_unmask = ftgpio_gpio_unmask_irq, + .irq_set_type = ftgpio_gpio_set_irq_type, }; -static void gemini_gpio_irq_handler(struct irq_desc *desc) +static void ftgpio_gpio_irq_handler(struct irq_desc *desc) { struct gpio_chip *gc = irq_desc_get_handler_data(desc); - struct gemini_gpio *g = gpiochip_get_data(gc); + struct ftgpio_gpio *g = gpiochip_get_data(gc); struct irq_chip *irqchip = irq_desc_get_chip(desc); int offset; unsigned long stat; @@ -155,11 +155,11 @@ static void gemini_gpio_irq_handler(struct irq_desc *desc) chained_irq_exit(irqchip, desc); } -static int gemini_gpio_probe(struct platform_device *pdev) +static int ftgpio_gpio_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct resource *res; - struct gemini_gpio *g; + struct ftgpio_gpio *g; int irq; int ret; @@ -189,7 +189,7 @@ static int gemini_gpio_probe(struct platform_device *pdev) dev_err(dev, "unable to init generic GPIO\n"); return ret; } - g->gc.label = "Gemini"; + g->gc.label = "FTGPIO010"; g->gc.base = -1; g->gc.parent = dev; g->gc.owner = THIS_MODULE; @@ -204,33 +204,39 @@ static int gemini_gpio_probe(struct platform_device *pdev) writel(0x0, g->base + GPIO_INT_MASK); writel(~0x0, g->base + GPIO_INT_CLR); - ret = gpiochip_irqchip_add(&g->gc, &gemini_gpio_irqchip, + ret = gpiochip_irqchip_add(&g->gc, &ftgpio_gpio_irqchip, 0, handle_bad_irq, IRQ_TYPE_NONE); if (ret) { dev_info(dev, "could not add irqchip\n"); return ret; } - gpiochip_set_chained_irqchip(&g->gc, &gemini_gpio_irqchip, - irq, gemini_gpio_irq_handler); + gpiochip_set_chained_irqchip(&g->gc, &ftgpio_gpio_irqchip, + irq, ftgpio_gpio_irq_handler); - dev_info(dev, "Gemini GPIO @%p registered\n", g->base); + dev_info(dev, "FTGPIO010 @%p registered\n", g->base); return 0; } -static const struct of_device_id gemini_gpio_of_match[] = { +static const struct of_device_id ftgpio_gpio_of_match[] = { { .compatible = "cortina,gemini-gpio", }, + { + .compatible = "moxa,moxart-gpio", + }, + { + .compatible = "faraday,ftgpio010", + }, {}, }; -static struct platform_driver gemini_gpio_driver = { +static struct platform_driver ftgpio_gpio_driver = { .driver = { - .name = "gemini-gpio", - .of_match_table = of_match_ptr(gemini_gpio_of_match), + .name = "ftgpio010-gpio", + .of_match_table = of_match_ptr(ftgpio_gpio_of_match), }, - .probe = gemini_gpio_probe, + .probe = ftgpio_gpio_probe, }; -builtin_platform_driver(gemini_gpio_driver); +builtin_platform_driver(ftgpio_gpio_driver); diff --git a/drivers/gpio/gpio-merrifield.c b/drivers/gpio/gpio-merrifield.c index f40088d268c1..9dbdc3672f5e 100644 --- a/drivers/gpio/gpio-merrifield.c +++ b/drivers/gpio/gpio-merrifield.c @@ -166,7 +166,7 @@ static int mrfld_gpio_get_direction(struct gpio_chip *chip, unsigned int offset) { void __iomem *gpdr = gpio_reg(chip, offset, GPDR); - return (readl(gpdr) & BIT(offset % 32)) ? GPIOF_DIR_OUT : GPIOF_DIR_IN; + return !(readl(gpdr) & BIT(offset % 32)); } static int mrfld_gpio_set_debounce(struct gpio_chip *chip, unsigned int offset, diff --git a/drivers/gpio/gpio-ml-ioh.c b/drivers/gpio/gpio-ml-ioh.c index 796a5a4bc4f5..78896a869fd9 100644 --- a/drivers/gpio/gpio-ml-ioh.c +++ b/drivers/gpio/gpio-ml-ioh.c @@ -459,41 +459,31 @@ static int ioh_gpio_probe(struct pci_dev *pdev, chip = chip_save; for (j = 0; j < 8; j++, chip++) { - irq_base = irq_alloc_descs(-1, IOH_IRQ_BASE, num_ports[j], - NUMA_NO_NODE); + irq_base = devm_irq_alloc_descs(&pdev->dev, -1, IOH_IRQ_BASE, + num_ports[j], NUMA_NO_NODE); if (irq_base < 0) { dev_warn(&pdev->dev, "ml_ioh_gpio: Failed to get IRQ base num\n"); - chip->irq_base = -1; ret = irq_base; - goto err_irq_alloc_descs; + goto err_gpiochip_add; } chip->irq_base = irq_base; ioh_gpio_alloc_generic_chip(chip, irq_base, num_ports[j]); } chip = chip_save; - ret = request_irq(pdev->irq, ioh_gpio_handler, - IRQF_SHARED, KBUILD_MODNAME, chip); + ret = devm_request_irq(&pdev->dev, pdev->irq, ioh_gpio_handler, + IRQF_SHARED, KBUILD_MODNAME, chip); if (ret != 0) { dev_err(&pdev->dev, "%s request_irq failed\n", __func__); - goto err_request_irq; + goto err_gpiochip_add; } pci_set_drvdata(pdev, chip); return 0; -err_request_irq: - chip = chip_save; -err_irq_alloc_descs: - while (--j >= 0) { - chip--; - irq_free_descs(chip->irq_base, num_ports[j]); - } - - chip = chip_save; err_gpiochip_add: while (--i >= 0) { chip--; @@ -524,12 +514,8 @@ static void ioh_gpio_remove(struct pci_dev *pdev) chip_save = chip; - free_irq(pdev->irq, chip); - - for (i = 0; i < 8; i++, chip++) { - irq_free_descs(chip->irq_base, num_ports[i]); + for (i = 0; i < 8; i++, chip++) gpiochip_remove(&chip->gpio); - } chip = chip_save; pci_iounmap(pdev, chip->base); diff --git a/drivers/gpio/gpio-mmio.c b/drivers/gpio/gpio-mmio.c index d7d03ad052d0..f7da40e46c55 100644 --- a/drivers/gpio/gpio-mmio.c +++ b/drivers/gpio/gpio-mmio.c @@ -575,6 +575,7 @@ static void __iomem *bgpio_map(struct platform_device *pdev, static const struct of_device_id bgpio_of_match[] = { { .compatible = "brcm,bcm6345-gpio" }, { .compatible = "wd,mbl-gpio" }, + { .compatible = "ni,169445-nand-gpio" }, { } }; MODULE_DEVICE_TABLE(of, bgpio_of_match); diff --git a/drivers/gpio/gpio-mockup.c b/drivers/gpio/gpio-mockup.c index d99338689213..c6dadac70593 100644 --- a/drivers/gpio/gpio-mockup.c +++ b/drivers/gpio/gpio-mockup.c @@ -169,7 +169,7 @@ static int gpio_mockup_irqchip_setup(struct device *dev, struct gpio_chip *gc = &chip->gc; int irq_base, i; - irq_base = irq_alloc_descs(-1, 0, gc->ngpio, 0); + irq_base = devm_irq_alloc_descs(dev, -1, 0, gc->ngpio, 0); if (irq_base < 0) return irq_base; @@ -372,25 +372,11 @@ static int gpio_mockup_probe(struct platform_device *pdev) return 0; } -static int gpio_mockup_remove(struct platform_device *pdev) -{ - struct gpio_mockup_chip *chips; - int i; - - chips = platform_get_drvdata(pdev); - - for (i = 0; i < gpio_mockup_params_nr >> 1; i++) - irq_free_descs(chips[i].gc.irq_base, chips[i].gc.ngpio); - - return 0; -} - static struct platform_driver gpio_mockup_driver = { .driver = { .name = GPIO_MOCKUP_NAME, }, .probe = gpio_mockup_probe, - .remove = gpio_mockup_remove, }; static struct platform_device *pdev; diff --git a/drivers/gpio/gpio-moxart.c b/drivers/gpio/gpio-moxart.c deleted file mode 100644 index d58d38906ba6..000000000000 --- a/drivers/gpio/gpio-moxart.c +++ /dev/null @@ -1,84 +0,0 @@ -/* - * MOXA ART SoCs GPIO driver. - * - * Copyright (C) 2013 Jonas Jensen - * - * Jonas Jensen <jonas.jensen@gmail.com> - * - * This file is licensed under the terms of the GNU General Public - * License version 2. This program is licensed "as is" without any - * warranty of any kind, whether express or implied. - */ - -#include <linux/err.h> -#include <linux/init.h> -#include <linux/irq.h> -#include <linux/io.h> -#include <linux/platform_device.h> -#include <linux/of_address.h> -#include <linux/of_gpio.h> -#include <linux/pinctrl/consumer.h> -#include <linux/delay.h> -#include <linux/timer.h> -#include <linux/bitops.h> -#include <linux/gpio/driver.h> - -#define GPIO_DATA_OUT 0x00 -#define GPIO_DATA_IN 0x04 -#define GPIO_PIN_DIRECTION 0x08 - -static int moxart_gpio_probe(struct platform_device *pdev) -{ - struct device *dev = &pdev->dev; - struct resource *res; - struct gpio_chip *gc; - void __iomem *base; - int ret; - - gc = devm_kzalloc(dev, sizeof(*gc), GFP_KERNEL); - if (!gc) - return -ENOMEM; - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - base = devm_ioremap_resource(dev, res); - if (IS_ERR(base)) - return PTR_ERR(base); - - ret = bgpio_init(gc, dev, 4, base + GPIO_DATA_IN, - base + GPIO_DATA_OUT, NULL, - base + GPIO_PIN_DIRECTION, NULL, - BGPIOF_READ_OUTPUT_REG_SET); - if (ret) { - dev_err(&pdev->dev, "bgpio_init failed\n"); - return ret; - } - - gc->label = "moxart-gpio"; - gc->request = gpiochip_generic_request; - gc->free = gpiochip_generic_free; - gc->base = 0; - gc->owner = THIS_MODULE; - - ret = devm_gpiochip_add_data(dev, gc, NULL); - if (ret) { - dev_err(dev, "%s: gpiochip_add failed\n", - dev->of_node->full_name); - return ret; - } - - return ret; -} - -static const struct of_device_id moxart_gpio_match[] = { - { .compatible = "moxa,moxart-gpio" }, - { } -}; - -static struct platform_driver moxart_gpio_driver = { - .driver = { - .name = "moxart-gpio", - .of_match_table = moxart_gpio_match, - }, - .probe = moxart_gpio_probe, -}; -builtin_platform_driver(moxart_gpio_driver); diff --git a/drivers/gpio/gpio-mvebu.c b/drivers/gpio/gpio-mvebu.c index a649556ac3ca..fae4db684398 100644 --- a/drivers/gpio/gpio-mvebu.c +++ b/drivers/gpio/gpio-mvebu.c @@ -45,6 +45,7 @@ #include <linux/clk.h> #include <linux/pinctrl/consumer.h> #include <linux/irqchip/chained_irq.h> +#include <linux/bitops.h> /* * GPIO unit register offsets. @@ -62,9 +63,11 @@ #define GPIO_EDGE_MASK_MV78200_OFF(cpu) ((cpu) ? 0x30 : 0x18) #define GPIO_LEVEL_MASK_MV78200_OFF(cpu) ((cpu) ? 0x34 : 0x1C) -/* The Armada XP has per-CPU registers for interrupt cause, interrupt +/* + * The Armada XP has per-CPU registers for interrupt cause, interrupt * mask and interrupt level mask. Those are relative to the - * percpu_membase. */ + * percpu_membase. + */ #define GPIO_EDGE_CAUSE_ARMADAXP_OFF(cpu) ((cpu) * 0x4) #define GPIO_EDGE_MASK_ARMADAXP_OFF(cpu) (0x10 + (cpu) * 0x4) #define GPIO_LEVEL_MASK_ARMADAXP_OFF(cpu) (0x20 + (cpu) * 0x4) @@ -85,47 +88,44 @@ struct mvebu_gpio_chip { int soc_variant; /* Used to preserve GPIO registers across suspend/resume */ - u32 out_reg; - u32 io_conf_reg; - u32 blink_en_reg; - u32 in_pol_reg; - u32 edge_mask_regs[4]; - u32 level_mask_regs[4]; + u32 out_reg; + u32 io_conf_reg; + u32 blink_en_reg; + u32 in_pol_reg; + u32 edge_mask_regs[4]; + u32 level_mask_regs[4]; }; /* * Functions returning addresses of individual registers for a given * GPIO controller. */ -static inline void __iomem *mvebu_gpioreg_out(struct mvebu_gpio_chip *mvchip) +static void __iomem *mvebu_gpioreg_out(struct mvebu_gpio_chip *mvchip) { return mvchip->membase + GPIO_OUT_OFF; } -static inline void __iomem *mvebu_gpioreg_blink(struct mvebu_gpio_chip *mvchip) +static void __iomem *mvebu_gpioreg_blink(struct mvebu_gpio_chip *mvchip) { return mvchip->membase + GPIO_BLINK_EN_OFF; } -static inline void __iomem * -mvebu_gpioreg_io_conf(struct mvebu_gpio_chip *mvchip) +static void __iomem *mvebu_gpioreg_io_conf(struct mvebu_gpio_chip *mvchip) { return mvchip->membase + GPIO_IO_CONF_OFF; } -static inline void __iomem *mvebu_gpioreg_in_pol(struct mvebu_gpio_chip *mvchip) +static void __iomem *mvebu_gpioreg_in_pol(struct mvebu_gpio_chip *mvchip) { return mvchip->membase + GPIO_IN_POL_OFF; } -static inline void __iomem * -mvebu_gpioreg_data_in(struct mvebu_gpio_chip *mvchip) +static void __iomem *mvebu_gpioreg_data_in(struct mvebu_gpio_chip *mvchip) { return mvchip->membase + GPIO_DATA_IN_OFF; } -static inline void __iomem * -mvebu_gpioreg_edge_cause(struct mvebu_gpio_chip *mvchip) +static void __iomem *mvebu_gpioreg_edge_cause(struct mvebu_gpio_chip *mvchip) { int cpu; @@ -142,8 +142,7 @@ mvebu_gpioreg_edge_cause(struct mvebu_gpio_chip *mvchip) } } -static inline void __iomem * -mvebu_gpioreg_edge_mask(struct mvebu_gpio_chip *mvchip) +static void __iomem *mvebu_gpioreg_edge_mask(struct mvebu_gpio_chip *mvchip) { int cpu; @@ -184,8 +183,7 @@ static void __iomem *mvebu_gpioreg_level_mask(struct mvebu_gpio_chip *mvchip) /* * Functions implementing the gpio_chip methods */ - -static void mvebu_gpio_set(struct gpio_chip *chip, unsigned pin, int value) +static void mvebu_gpio_set(struct gpio_chip *chip, unsigned int pin, int value) { struct mvebu_gpio_chip *mvchip = gpiochip_get_data(chip); unsigned long flags; @@ -194,19 +192,19 @@ static void mvebu_gpio_set(struct gpio_chip *chip, unsigned pin, int value) spin_lock_irqsave(&mvchip->lock, flags); u = readl_relaxed(mvebu_gpioreg_out(mvchip)); if (value) - u |= 1 << pin; + u |= BIT(pin); else - u &= ~(1 << pin); + u &= ~BIT(pin); writel_relaxed(u, mvebu_gpioreg_out(mvchip)); spin_unlock_irqrestore(&mvchip->lock, flags); } -static int mvebu_gpio_get(struct gpio_chip *chip, unsigned pin) +static int mvebu_gpio_get(struct gpio_chip *chip, unsigned int pin) { struct mvebu_gpio_chip *mvchip = gpiochip_get_data(chip); u32 u; - if (readl_relaxed(mvebu_gpioreg_io_conf(mvchip)) & (1 << pin)) { + if (readl_relaxed(mvebu_gpioreg_io_conf(mvchip)) & BIT(pin)) { u = readl_relaxed(mvebu_gpioreg_data_in(mvchip)) ^ readl_relaxed(mvebu_gpioreg_in_pol(mvchip)); } else { @@ -216,7 +214,8 @@ static int mvebu_gpio_get(struct gpio_chip *chip, unsigned pin) return (u >> pin) & 1; } -static void mvebu_gpio_blink(struct gpio_chip *chip, unsigned pin, int value) +static void mvebu_gpio_blink(struct gpio_chip *chip, unsigned int pin, + int value) { struct mvebu_gpio_chip *mvchip = gpiochip_get_data(chip); unsigned long flags; @@ -225,36 +224,38 @@ static void mvebu_gpio_blink(struct gpio_chip *chip, unsigned pin, int value) spin_lock_irqsave(&mvchip->lock, flags); u = readl_relaxed(mvebu_gpioreg_blink(mvchip)); if (value) - u |= 1 << pin; + u |= BIT(pin); else - u &= ~(1 << pin); + u &= ~BIT(pin); writel_relaxed(u, mvebu_gpioreg_blink(mvchip)); spin_unlock_irqrestore(&mvchip->lock, flags); } -static int mvebu_gpio_direction_input(struct gpio_chip *chip, unsigned pin) +static int mvebu_gpio_direction_input(struct gpio_chip *chip, unsigned int pin) { struct mvebu_gpio_chip *mvchip = gpiochip_get_data(chip); unsigned long flags; int ret; u32 u; - /* Check with the pinctrl driver whether this pin is usable as - * an input GPIO */ + /* + * Check with the pinctrl driver whether this pin is usable as + * an input GPIO + */ ret = pinctrl_gpio_direction_input(chip->base + pin); if (ret) return ret; spin_lock_irqsave(&mvchip->lock, flags); u = readl_relaxed(mvebu_gpioreg_io_conf(mvchip)); - u |= 1 << pin; + u |= BIT(pin); writel_relaxed(u, mvebu_gpioreg_io_conf(mvchip)); spin_unlock_irqrestore(&mvchip->lock, flags); return 0; } -static int mvebu_gpio_direction_output(struct gpio_chip *chip, unsigned pin, +static int mvebu_gpio_direction_output(struct gpio_chip *chip, unsigned int pin, int value) { struct mvebu_gpio_chip *mvchip = gpiochip_get_data(chip); @@ -262,8 +263,10 @@ static int mvebu_gpio_direction_output(struct gpio_chip *chip, unsigned pin, int ret; u32 u; - /* Check with the pinctrl driver whether this pin is usable as - * an output GPIO */ + /* + * Check with the pinctrl driver whether this pin is usable as + * an output GPIO + */ ret = pinctrl_gpio_direction_output(chip->base + pin); if (ret) return ret; @@ -273,16 +276,17 @@ static int mvebu_gpio_direction_output(struct gpio_chip *chip, unsigned pin, spin_lock_irqsave(&mvchip->lock, flags); u = readl_relaxed(mvebu_gpioreg_io_conf(mvchip)); - u &= ~(1 << pin); + u &= ~BIT(pin); writel_relaxed(u, mvebu_gpioreg_io_conf(mvchip)); spin_unlock_irqrestore(&mvchip->lock, flags); return 0; } -static int mvebu_gpio_to_irq(struct gpio_chip *chip, unsigned pin) +static int mvebu_gpio_to_irq(struct gpio_chip *chip, unsigned int pin) { struct mvebu_gpio_chip *mvchip = gpiochip_get_data(chip); + return irq_create_mapping(mvchip->domain, pin); } @@ -389,7 +393,7 @@ static int mvebu_gpio_irq_set_type(struct irq_data *d, unsigned int type) pin = d->hwirq; - u = readl_relaxed(mvebu_gpioreg_io_conf(mvchip)) & (1 << pin); + u = readl_relaxed(mvebu_gpioreg_io_conf(mvchip)) & BIT(pin); if (!u) return -EINVAL; @@ -409,13 +413,13 @@ static int mvebu_gpio_irq_set_type(struct irq_data *d, unsigned int type) case IRQ_TYPE_EDGE_RISING: case IRQ_TYPE_LEVEL_HIGH: u = readl_relaxed(mvebu_gpioreg_in_pol(mvchip)); - u &= ~(1 << pin); + u &= ~BIT(pin); writel_relaxed(u, mvebu_gpioreg_in_pol(mvchip)); break; case IRQ_TYPE_EDGE_FALLING: case IRQ_TYPE_LEVEL_LOW: u = readl_relaxed(mvebu_gpioreg_in_pol(mvchip)); - u |= 1 << pin; + u |= BIT(pin); writel_relaxed(u, mvebu_gpioreg_in_pol(mvchip)); break; case IRQ_TYPE_EDGE_BOTH: { @@ -428,10 +432,10 @@ static int mvebu_gpio_irq_set_type(struct irq_data *d, unsigned int type) * set initial polarity based on current input level */ u = readl_relaxed(mvebu_gpioreg_in_pol(mvchip)); - if (v & (1 << pin)) - u |= 1 << pin; /* falling */ + if (v & BIT(pin)) + u |= BIT(pin); /* falling */ else - u &= ~(1 << pin); /* rising */ + u &= ~BIT(pin); /* rising */ writel_relaxed(u, mvebu_gpioreg_in_pol(mvchip)); break; } @@ -461,7 +465,7 @@ static void mvebu_gpio_irq_handler(struct irq_desc *desc) irq = irq_find_mapping(mvchip->domain, i); - if (!(cause & (1 << i))) + if (!(cause & BIT(i))) continue; type = irq_get_trigger_type(irq); @@ -470,7 +474,7 @@ static void mvebu_gpio_irq_handler(struct irq_desc *desc) u32 polarity; polarity = readl_relaxed(mvebu_gpioreg_in_pol(mvchip)); - polarity ^= 1 << i; + polarity ^= BIT(i); writel_relaxed(polarity, mvebu_gpioreg_in_pol(mvchip)); } @@ -507,7 +511,7 @@ static void mvebu_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip) if (!label) continue; - msk = 1 << i; + msk = BIT(i); is_out = !(io_conf & msk); seq_printf(s, " gpio-%-3d (%-20.20s)", chip->base + i, label); @@ -712,8 +716,10 @@ static int mvebu_gpio_probe(struct platform_device *pdev) if (IS_ERR(mvchip->membase)) return PTR_ERR(mvchip->membase); - /* The Armada XP has a second range of registers for the - * per-CPU registers */ + /* + * The Armada XP has a second range of registers for the + * per-CPU registers + */ if (soc_variant == MVEBU_GPIO_SOC_VARIANT_ARMADAXP) { res = platform_get_resource(pdev, IORESOURCE_MEM, 1); mvchip->percpu_membase = devm_ioremap_resource(&pdev->dev, @@ -780,7 +786,8 @@ static int mvebu_gpio_probe(struct platform_device *pdev) goto err_domain; } - /* NOTE: The common accessors cannot be used because of the percpu + /* + * NOTE: The common accessors cannot be used because of the percpu * access to the mask registers */ gc = irq_get_domain_generic_chip(mvchip->domain, 0); @@ -801,7 +808,8 @@ static int mvebu_gpio_probe(struct platform_device *pdev) ct->handler = handle_edge_irq; ct->chip.name = mvchip->chip.label; - /* Setup the interrupt handlers. Each chip can have up to 4 + /* + * Setup the interrupt handlers. Each chip can have up to 4 * interrupt handlers, with each handler dealing with 8 GPIO * pins. */ diff --git a/drivers/gpio/gpio-mxc.c b/drivers/gpio/gpio-mxc.c index c1a1e00b8cb0..3abea3f0b307 100644 --- a/drivers/gpio/gpio-mxc.c +++ b/drivers/gpio/gpio-mxc.c @@ -471,7 +471,7 @@ static int mxc_gpio_probe(struct platform_device *pdev) if (err) goto out_bgio; - irq_base = irq_alloc_descs(-1, 0, 32, numa_node_id()); + irq_base = devm_irq_alloc_descs(&pdev->dev, -1, 0, 32, numa_node_id()); if (irq_base < 0) { err = irq_base; goto out_bgio; @@ -481,7 +481,7 @@ static int mxc_gpio_probe(struct platform_device *pdev) &irq_domain_simple_ops, NULL); if (!port->domain) { err = -ENODEV; - goto out_irqdesc_free; + goto out_bgio; } /* gpio-mxc can be a generic irq chip */ @@ -495,8 +495,6 @@ static int mxc_gpio_probe(struct platform_device *pdev) out_irqdomain_remove: irq_domain_remove(port->domain); -out_irqdesc_free: - irq_free_descs(irq_base, 32); out_bgio: dev_info(&pdev->dev, "%s failed with errno %d\n", __func__, err); return err; diff --git a/drivers/gpio/gpio-mxs.c b/drivers/gpio/gpio-mxs.c index 2292742eac8f..6ae583f36733 100644 --- a/drivers/gpio/gpio-mxs.c +++ b/drivers/gpio/gpio-mxs.c @@ -328,7 +328,7 @@ static int mxs_gpio_probe(struct platform_device *pdev) /* clear address has to be used to clear IRQSTAT bits */ writel(~0U, port->base + PINCTRL_IRQSTAT(port) + MXS_CLR); - irq_base = irq_alloc_descs(-1, 0, 32, numa_node_id()); + irq_base = devm_irq_alloc_descs(&pdev->dev, -1, 0, 32, numa_node_id()); if (irq_base < 0) { err = irq_base; goto out_iounmap; @@ -338,7 +338,7 @@ static int mxs_gpio_probe(struct platform_device *pdev) &irq_domain_simple_ops, NULL); if (!port->domain) { err = -ENODEV; - goto out_irqdesc_free; + goto out_iounmap; } /* gpio-mxs can be a generic irq chip */ @@ -370,8 +370,6 @@ static int mxs_gpio_probe(struct platform_device *pdev) out_irqdomain_remove: irq_domain_remove(port->domain); -out_irqdesc_free: - irq_free_descs(irq_base, 32); out_iounmap: iounmap(port->base); return err; diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c index efc85a279d54..5d6a5744352f 100644 --- a/drivers/gpio/gpio-omap.c +++ b/drivers/gpio/gpio-omap.c @@ -1085,7 +1085,8 @@ static int omap_gpio_chip_init(struct gpio_bank *bank, struct irq_chip *irqc) * REVISIT: Once we have OMAP1 supporting SPARSE_IRQ, we can drop * irq_alloc_descs() since a base IRQ offset will no longer be needed. */ - irq_base = irq_alloc_descs(-1, 0, bank->width, 0); + irq_base = devm_irq_alloc_descs(bank->chip.parent, + -1, 0, bank->width, 0); if (irq_base < 0) { dev_err(bank->chip.parent, "Couldn't allocate IRQ numbers\n"); return -ENODEV; diff --git a/drivers/gpio/gpio-pca953x.c b/drivers/gpio/gpio-pca953x.c index d44232aadb6c..b9373785ccf5 100644 --- a/drivers/gpio/gpio-pca953x.c +++ b/drivers/gpio/gpio-pca953x.c @@ -11,18 +11,19 @@ * the Free Software Foundation; version 2 of the License. */ -#include <linux/module.h> -#include <linux/init.h> +#include <linux/acpi.h> #include <linux/gpio.h> #include <linux/gpio/consumer.h> -#include <linux/interrupt.h> #include <linux/i2c.h> +#include <linux/init.h> +#include <linux/interrupt.h> +#include <linux/module.h> +#include <linux/of_platform.h> #include <linux/platform_data/pca953x.h> +#include <linux/regulator/consumer.h> #include <linux/slab.h> + #include <asm/unaligned.h> -#include <linux/of_platform.h> -#include <linux/acpi.h> -#include <linux/regulator/consumer.h> #define PCA953X_INPUT 0 #define PCA953X_OUTPUT 1 @@ -363,6 +364,21 @@ exit: mutex_unlock(&chip->i2c_lock); } +static int pca953x_gpio_get_direction(struct gpio_chip *gc, unsigned off) +{ + struct pca953x_chip *chip = gpiochip_get_data(gc); + u32 reg_val; + int ret; + + mutex_lock(&chip->i2c_lock); + ret = pca953x_read_single(chip, chip->regs->direction, ®_val, off); + mutex_unlock(&chip->i2c_lock); + if (ret < 0) + return ret; + + return !!(reg_val & (1u << (off % BANK_SZ))); +} + static void pca953x_gpio_set_multiple(struct gpio_chip *gc, unsigned long *mask, unsigned long *bits) { @@ -408,6 +424,7 @@ static void pca953x_setup_gpio(struct pca953x_chip *chip, int gpios) gc->direction_output = pca953x_gpio_direction_output; gc->get = pca953x_gpio_get_value; gc->set = pca953x_gpio_set_value; + gc->get_direction = pca953x_gpio_get_direction; gc->set_multiple = pca953x_gpio_set_multiple; gc->can_sleep = true; @@ -760,7 +777,13 @@ static int pca953x_probe(struct i2c_client *client, chip->gpio_start = -1; irq_base = 0; - /* See if we need to de-assert a reset pin */ + /* + * See if we need to de-assert a reset pin. + * + * There is no known ACPI-enabled platforms that are + * using "reset" GPIO. Otherwise any of those platform + * must use _DSD method with corresponding property. + */ reset_gpio = devm_gpiod_get_optional(&client->dev, "reset", GPIOD_OUT_LOW); if (IS_ERR(reset_gpio)) diff --git a/drivers/gpio/gpio-pch.c b/drivers/gpio/gpio-pch.c index 7c7135da5d4a..71bc6da11337 100644 --- a/drivers/gpio/gpio-pch.c +++ b/drivers/gpio/gpio-pch.c @@ -403,7 +403,8 @@ static int pch_gpio_probe(struct pci_dev *pdev, goto err_gpiochip_add; } - irq_base = irq_alloc_descs(-1, 0, gpio_pins[chip->ioh], NUMA_NO_NODE); + irq_base = devm_irq_alloc_descs(&pdev->dev, -1, 0, + gpio_pins[chip->ioh], NUMA_NO_NODE); if (irq_base < 0) { dev_warn(&pdev->dev, "PCH gpio: Failed to get IRQ base num\n"); chip->irq_base = -1; @@ -416,8 +417,8 @@ static int pch_gpio_probe(struct pci_dev *pdev, iowrite32(msk, &chip->reg->imask); iowrite32(msk, &chip->reg->ien); - ret = request_irq(pdev->irq, pch_gpio_handler, - IRQF_SHARED, KBUILD_MODNAME, chip); + ret = devm_request_irq(&pdev->dev, pdev->irq, pch_gpio_handler, + IRQF_SHARED, KBUILD_MODNAME, chip); if (ret != 0) { dev_err(&pdev->dev, "%s request_irq failed\n", __func__); @@ -430,7 +431,6 @@ end: return 0; err_request_irq: - irq_free_descs(irq_base, gpio_pins[chip->ioh]); gpiochip_remove(&chip->gpio); err_gpiochip_add: @@ -452,12 +452,6 @@ static void pch_gpio_remove(struct pci_dev *pdev) { struct pch_gpio *chip = pci_get_drvdata(pdev); - if (chip->irq_base != -1) { - free_irq(pdev->irq, chip); - - irq_free_descs(chip->irq_base, gpio_pins[chip->ioh]); - } - gpiochip_remove(&chip->gpio); pci_iounmap(pdev, chip->base); pci_release_regions(pdev); diff --git a/drivers/gpio/gpio-pci-idio-16.c b/drivers/gpio/gpio-pci-idio-16.c index 269ab628634b..7de4f6a2cb49 100644 --- a/drivers/gpio/gpio-pci-idio-16.c +++ b/drivers/gpio/gpio-pci-idio-16.c @@ -59,7 +59,7 @@ struct idio_16_gpio_reg { */ struct idio_16_gpio { struct gpio_chip chip; - spinlock_t lock; + raw_spinlock_t lock; struct idio_16_gpio_reg __iomem *reg; unsigned long irq_mask; }; @@ -121,7 +121,7 @@ static void idio_16_gpio_set(struct gpio_chip *chip, unsigned int offset, } else base = &idio16gpio->reg->out0_7; - spin_lock_irqsave(&idio16gpio->lock, flags); + raw_spin_lock_irqsave(&idio16gpio->lock, flags); if (value) out_state = ioread8(base) | mask; @@ -130,7 +130,7 @@ static void idio_16_gpio_set(struct gpio_chip *chip, unsigned int offset, iowrite8(out_state, base); - spin_unlock_irqrestore(&idio16gpio->lock, flags); + raw_spin_unlock_irqrestore(&idio16gpio->lock, flags); } static void idio_16_gpio_set_multiple(struct gpio_chip *chip, @@ -140,7 +140,7 @@ static void idio_16_gpio_set_multiple(struct gpio_chip *chip, unsigned long flags; unsigned int out_state; - spin_lock_irqsave(&idio16gpio->lock, flags); + raw_spin_lock_irqsave(&idio16gpio->lock, flags); /* process output lines 0-7 */ if (*mask & 0xFF) { @@ -160,7 +160,7 @@ static void idio_16_gpio_set_multiple(struct gpio_chip *chip, iowrite8(out_state, &idio16gpio->reg->out8_15); } - spin_unlock_irqrestore(&idio16gpio->lock, flags); + raw_spin_unlock_irqrestore(&idio16gpio->lock, flags); } static void idio_16_irq_ack(struct irq_data *data) @@ -177,11 +177,11 @@ static void idio_16_irq_mask(struct irq_data *data) idio16gpio->irq_mask &= ~mask; if (!idio16gpio->irq_mask) { - spin_lock_irqsave(&idio16gpio->lock, flags); + raw_spin_lock_irqsave(&idio16gpio->lock, flags); iowrite8(0, &idio16gpio->reg->irq_ctl); - spin_unlock_irqrestore(&idio16gpio->lock, flags); + raw_spin_unlock_irqrestore(&idio16gpio->lock, flags); } } @@ -196,11 +196,11 @@ static void idio_16_irq_unmask(struct irq_data *data) idio16gpio->irq_mask |= mask; if (!prev_irq_mask) { - spin_lock_irqsave(&idio16gpio->lock, flags); + raw_spin_lock_irqsave(&idio16gpio->lock, flags); ioread8(&idio16gpio->reg->irq_ctl); - spin_unlock_irqrestore(&idio16gpio->lock, flags); + raw_spin_unlock_irqrestore(&idio16gpio->lock, flags); } } @@ -229,11 +229,11 @@ static irqreturn_t idio_16_irq_handler(int irq, void *dev_id) struct gpio_chip *const chip = &idio16gpio->chip; int gpio; - spin_lock(&idio16gpio->lock); + raw_spin_lock(&idio16gpio->lock); irq_status = ioread8(&idio16gpio->reg->irq_status); - spin_unlock(&idio16gpio->lock); + raw_spin_unlock(&idio16gpio->lock); /* Make sure our device generated IRQ */ if (!(irq_status & 0x3) || !(irq_status & 0x4)) @@ -242,12 +242,12 @@ static irqreturn_t idio_16_irq_handler(int irq, void *dev_id) for_each_set_bit(gpio, &idio16gpio->irq_mask, chip->ngpio) generic_handle_irq(irq_find_mapping(chip->irqdomain, gpio)); - spin_lock(&idio16gpio->lock); + raw_spin_lock(&idio16gpio->lock); /* Clear interrupt */ iowrite8(0, &idio16gpio->reg->in0_7); - spin_unlock(&idio16gpio->lock); + raw_spin_unlock(&idio16gpio->lock); return IRQ_HANDLED; } @@ -302,7 +302,7 @@ static int idio_16_probe(struct pci_dev *pdev, const struct pci_device_id *id) idio16gpio->chip.set = idio_16_gpio_set; idio16gpio->chip.set_multiple = idio_16_gpio_set_multiple; - spin_lock_init(&idio16gpio->lock); + raw_spin_lock_init(&idio16gpio->lock); err = devm_gpiochip_add_data(dev, &idio16gpio->chip, idio16gpio); if (err) { diff --git a/drivers/gpio/gpio-pl061.c b/drivers/gpio/gpio-pl061.c index 0a6bfd2b06e5..3d3d6b6645a7 100644 --- a/drivers/gpio/gpio-pl061.c +++ b/drivers/gpio/gpio-pl061.c @@ -50,7 +50,7 @@ struct pl061_context_save_regs { #endif struct pl061 { - spinlock_t lock; + raw_spinlock_t lock; void __iomem *base; struct gpio_chip gc; @@ -74,11 +74,11 @@ static int pl061_direction_input(struct gpio_chip *gc, unsigned offset) unsigned long flags; unsigned char gpiodir; - spin_lock_irqsave(&pl061->lock, flags); + raw_spin_lock_irqsave(&pl061->lock, flags); gpiodir = readb(pl061->base + GPIODIR); gpiodir &= ~(BIT(offset)); writeb(gpiodir, pl061->base + GPIODIR); - spin_unlock_irqrestore(&pl061->lock, flags); + raw_spin_unlock_irqrestore(&pl061->lock, flags); return 0; } @@ -90,7 +90,7 @@ static int pl061_direction_output(struct gpio_chip *gc, unsigned offset, unsigned long flags; unsigned char gpiodir; - spin_lock_irqsave(&pl061->lock, flags); + raw_spin_lock_irqsave(&pl061->lock, flags); writeb(!!value << offset, pl061->base + (BIT(offset + 2))); gpiodir = readb(pl061->base + GPIODIR); gpiodir |= BIT(offset); @@ -101,7 +101,7 @@ static int pl061_direction_output(struct gpio_chip *gc, unsigned offset, * a gpio pin before configuring it in OUT mode. */ writeb(!!value << offset, pl061->base + (BIT(offset + 2))); - spin_unlock_irqrestore(&pl061->lock, flags); + raw_spin_unlock_irqrestore(&pl061->lock, flags); return 0; } @@ -143,7 +143,7 @@ static int pl061_irq_type(struct irq_data *d, unsigned trigger) } - spin_lock_irqsave(&pl061->lock, flags); + raw_spin_lock_irqsave(&pl061->lock, flags); gpioiev = readb(pl061->base + GPIOIEV); gpiois = readb(pl061->base + GPIOIS); @@ -203,7 +203,7 @@ static int pl061_irq_type(struct irq_data *d, unsigned trigger) writeb(gpioibe, pl061->base + GPIOIBE); writeb(gpioiev, pl061->base + GPIOIEV); - spin_unlock_irqrestore(&pl061->lock, flags); + raw_spin_unlock_irqrestore(&pl061->lock, flags); return 0; } @@ -235,10 +235,10 @@ static void pl061_irq_mask(struct irq_data *d) u8 mask = BIT(irqd_to_hwirq(d) % PL061_GPIO_NR); u8 gpioie; - spin_lock(&pl061->lock); + raw_spin_lock(&pl061->lock); gpioie = readb(pl061->base + GPIOIE) & ~mask; writeb(gpioie, pl061->base + GPIOIE); - spin_unlock(&pl061->lock); + raw_spin_unlock(&pl061->lock); } static void pl061_irq_unmask(struct irq_data *d) @@ -248,10 +248,10 @@ static void pl061_irq_unmask(struct irq_data *d) u8 mask = BIT(irqd_to_hwirq(d) % PL061_GPIO_NR); u8 gpioie; - spin_lock(&pl061->lock); + raw_spin_lock(&pl061->lock); gpioie = readb(pl061->base + GPIOIE) | mask; writeb(gpioie, pl061->base + GPIOIE); - spin_unlock(&pl061->lock); + raw_spin_unlock(&pl061->lock); } /** @@ -268,9 +268,9 @@ static void pl061_irq_ack(struct irq_data *d) struct pl061 *pl061 = gpiochip_get_data(gc); u8 mask = BIT(irqd_to_hwirq(d) % PL061_GPIO_NR); - spin_lock(&pl061->lock); + raw_spin_lock(&pl061->lock); writeb(mask, pl061->base + GPIOIC); - spin_unlock(&pl061->lock); + raw_spin_unlock(&pl061->lock); } static int pl061_irq_set_wake(struct irq_data *d, unsigned int state) @@ -304,7 +304,7 @@ static int pl061_probe(struct amba_device *adev, const struct amba_id *id) if (IS_ERR(pl061->base)) return PTR_ERR(pl061->base); - spin_lock_init(&pl061->lock); + raw_spin_lock_init(&pl061->lock); if (of_property_read_bool(dev->of_node, "gpio-ranges")) { pl061->gc.request = gpiochip_generic_request; pl061->gc.free = gpiochip_generic_free; diff --git a/drivers/gpio/gpio-pxa.c b/drivers/gpio/gpio-pxa.c index 76ac906b4d78..832f3e46ba9f 100644 --- a/drivers/gpio/gpio-pxa.c +++ b/drivers/gpio/gpio-pxa.c @@ -601,7 +601,7 @@ static int pxa_gpio_probe_dt(struct platform_device *pdev, nr_gpios = gpio_id->gpio_nums; pxa_last_gpio = nr_gpios - 1; - irq_base = irq_alloc_descs(-1, 0, nr_gpios, 0); + irq_base = devm_irq_alloc_descs(&pdev->dev, -1, 0, nr_gpios, 0); if (irq_base < 0) { dev_err(&pdev->dev, "Failed to allocate IRQ numbers\n"); return irq_base; diff --git a/drivers/gpio/gpio-reg.c b/drivers/gpio/gpio-reg.c new file mode 100644 index 000000000000..e85903eddc68 --- /dev/null +++ b/drivers/gpio/gpio-reg.c @@ -0,0 +1,185 @@ +/* + * gpio-reg: single register individually fixed-direction GPIOs + * + * Copyright (C) 2016 Russell King + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + */ +#include <linux/gpio/driver.h> +#include <linux/gpio/gpio-reg.h> +#include <linux/io.h> +#include <linux/slab.h> +#include <linux/spinlock.h> + +struct gpio_reg { + struct gpio_chip gc; + spinlock_t lock; + u32 direction; + u32 out; + void __iomem *reg; + struct irq_domain *irqdomain; + const int *irqs; +}; + +#define to_gpio_reg(x) container_of(x, struct gpio_reg, gc) + +static int gpio_reg_get_direction(struct gpio_chip *gc, unsigned offset) +{ + struct gpio_reg *r = to_gpio_reg(gc); + + return r->direction & BIT(offset) ? 1 : 0; +} + +static int gpio_reg_direction_output(struct gpio_chip *gc, unsigned offset, + int value) +{ + struct gpio_reg *r = to_gpio_reg(gc); + + if (r->direction & BIT(offset)) + return -ENOTSUPP; + + gc->set(gc, offset, value); + return 0; +} + +static int gpio_reg_direction_input(struct gpio_chip *gc, unsigned offset) +{ + struct gpio_reg *r = to_gpio_reg(gc); + + return r->direction & BIT(offset) ? 0 : -ENOTSUPP; +} + +static void gpio_reg_set(struct gpio_chip *gc, unsigned offset, int value) +{ + struct gpio_reg *r = to_gpio_reg(gc); + unsigned long flags; + u32 val, mask = BIT(offset); + + spin_lock_irqsave(&r->lock, flags); + val = r->out; + if (value) + val |= mask; + else + val &= ~mask; + r->out = val; + writel_relaxed(val, r->reg); + spin_unlock_irqrestore(&r->lock, flags); +} + +static int gpio_reg_get(struct gpio_chip *gc, unsigned offset) +{ + struct gpio_reg *r = to_gpio_reg(gc); + u32 val, mask = BIT(offset); + + if (r->direction & mask) { + /* + * double-read the value, some registers latch after the + * first read. + */ + readl_relaxed(r->reg); + val = readl_relaxed(r->reg); + } else { + val = r->out; + } + return !!(val & mask); +} + +static void gpio_reg_set_multiple(struct gpio_chip *gc, unsigned long *mask, + unsigned long *bits) +{ + struct gpio_reg *r = to_gpio_reg(gc); + unsigned long flags; + + spin_lock_irqsave(&r->lock, flags); + r->out = (r->out & ~*mask) | (*bits & *mask); + writel_relaxed(r->out, r->reg); + spin_unlock_irqrestore(&r->lock, flags); +} + +static int gpio_reg_to_irq(struct gpio_chip *gc, unsigned offset) +{ + struct gpio_reg *r = to_gpio_reg(gc); + int irq = r->irqs[offset]; + + if (irq >= 0 && r->irqdomain) + irq = irq_find_mapping(r->irqdomain, irq); + + return irq; +} + +/** + * gpio_reg_init - add a fixed in/out register as gpio + * @dev: optional struct device associated with this register + * @base: start gpio number, or -1 to allocate + * @num: number of GPIOs, maximum 32 + * @label: GPIO chip label + * @direction: bitmask of fixed direction, one per GPIO signal, 1 = in + * @def_out: initial GPIO output value + * @names: array of %num strings describing each GPIO signal or %NULL + * @irqdom: irq domain or %NULL + * @irqs: array of %num ints describing the interrupt mapping for each + * GPIO signal, or %NULL. If @irqdom is %NULL, then this + * describes the Linux interrupt number, otherwise it describes + * the hardware interrupt number in the specified irq domain. + * + * Add a single-register GPIO device containing up to 32 GPIO signals, + * where each GPIO has a fixed input or output configuration. Only + * input GPIOs are assumed to be readable from the register, and only + * then after a double-read. Output values are assumed not to be + * readable. + */ +struct gpio_chip *gpio_reg_init(struct device *dev, void __iomem *reg, + int base, int num, const char *label, u32 direction, u32 def_out, + const char *const *names, struct irq_domain *irqdom, const int *irqs) +{ + struct gpio_reg *r; + int ret; + + if (dev) + r = devm_kzalloc(dev, sizeof(*r), GFP_KERNEL); + else + r = kzalloc(sizeof(*r), GFP_KERNEL); + + if (!r) + return ERR_PTR(-ENOMEM); + + spin_lock_init(&r->lock); + + r->gc.label = label; + r->gc.get_direction = gpio_reg_get_direction; + r->gc.direction_input = gpio_reg_direction_input; + r->gc.direction_output = gpio_reg_direction_output; + r->gc.set = gpio_reg_set; + r->gc.get = gpio_reg_get; + r->gc.set_multiple = gpio_reg_set_multiple; + if (irqs) + r->gc.to_irq = gpio_reg_to_irq; + r->gc.base = base; + r->gc.ngpio = num; + r->gc.names = names; + r->direction = direction; + r->out = def_out; + r->reg = reg; + r->irqs = irqs; + + if (dev) + ret = devm_gpiochip_add_data(dev, &r->gc, r); + else + ret = gpiochip_add_data(&r->gc, r); + + return ret ? ERR_PTR(ret) : &r->gc; +} + +int gpio_reg_resume(struct gpio_chip *gc) +{ + struct gpio_reg *r = to_gpio_reg(gc); + unsigned long flags; + + spin_lock_irqsave(&r->lock, flags); + writel_relaxed(r->out, r->reg); + spin_unlock_irqrestore(&r->lock, flags); + + return 0; +} diff --git a/drivers/gpio/gpio-sa1100.c b/drivers/gpio/gpio-sa1100.c index 8d8ee0ebf14c..249f433aa62d 100644 --- a/drivers/gpio/gpio-sa1100.c +++ b/drivers/gpio/gpio-sa1100.c @@ -12,57 +12,97 @@ #include <linux/module.h> #include <linux/io.h> #include <linux/syscore_ops.h> +#include <soc/sa1100/pwer.h> #include <mach/hardware.h> #include <mach/irqs.h> +struct sa1100_gpio_chip { + struct gpio_chip chip; + void __iomem *membase; + int irqbase; + u32 irqmask; + u32 irqrising; + u32 irqfalling; + u32 irqwake; +}; + +#define sa1100_gpio_chip(x) container_of(x, struct sa1100_gpio_chip, chip) + +enum { + R_GPLR = 0x00, + R_GPDR = 0x04, + R_GPSR = 0x08, + R_GPCR = 0x0c, + R_GRER = 0x10, + R_GFER = 0x14, + R_GEDR = 0x18, + R_GAFR = 0x1c, +}; + static int sa1100_gpio_get(struct gpio_chip *chip, unsigned offset) { - return !!(GPLR & GPIO_GPIO(offset)); + return readl_relaxed(sa1100_gpio_chip(chip)->membase + R_GPLR) & + BIT(offset); } static void sa1100_gpio_set(struct gpio_chip *chip, unsigned offset, int value) { - if (value) - GPSR = GPIO_GPIO(offset); - else - GPCR = GPIO_GPIO(offset); + int reg = value ? R_GPSR : R_GPCR; + + writel_relaxed(BIT(offset), sa1100_gpio_chip(chip)->membase + reg); +} + +static int sa1100_get_direction(struct gpio_chip *chip, unsigned offset) +{ + void __iomem *gpdr = sa1100_gpio_chip(chip)->membase + R_GPDR; + + return !(readl_relaxed(gpdr) & BIT(offset)); } static int sa1100_direction_input(struct gpio_chip *chip, unsigned offset) { + void __iomem *gpdr = sa1100_gpio_chip(chip)->membase + R_GPDR; unsigned long flags; local_irq_save(flags); - GPDR &= ~GPIO_GPIO(offset); + writel_relaxed(readl_relaxed(gpdr) & ~BIT(offset), gpdr); local_irq_restore(flags); + return 0; } static int sa1100_direction_output(struct gpio_chip *chip, unsigned offset, int value) { + void __iomem *gpdr = sa1100_gpio_chip(chip)->membase + R_GPDR; unsigned long flags; local_irq_save(flags); sa1100_gpio_set(chip, offset, value); - GPDR |= GPIO_GPIO(offset); + writel_relaxed(readl_relaxed(gpdr) | BIT(offset), gpdr); local_irq_restore(flags); + return 0; } static int sa1100_to_irq(struct gpio_chip *chip, unsigned offset) { - return IRQ_GPIO0 + offset; + return sa1100_gpio_chip(chip)->irqbase + offset; } -static struct gpio_chip sa1100_gpio_chip = { - .label = "gpio", - .direction_input = sa1100_direction_input, - .direction_output = sa1100_direction_output, - .set = sa1100_gpio_set, - .get = sa1100_gpio_get, - .to_irq = sa1100_to_irq, - .base = 0, - .ngpio = GPIO_MAX + 1, +static struct sa1100_gpio_chip sa1100_gpio_chip = { + .chip = { + .label = "gpio", + .get_direction = sa1100_get_direction, + .direction_input = sa1100_direction_input, + .direction_output = sa1100_direction_output, + .set = sa1100_gpio_set, + .get = sa1100_gpio_get, + .to_irq = sa1100_to_irq, + .base = 0, + .ngpio = GPIO_MAX + 1, + }, + .membase = (void *)&GPLR, + .irqbase = IRQ_GPIO0, }; /* @@ -70,33 +110,39 @@ static struct gpio_chip sa1100_gpio_chip = { * IRQs are generated on Falling-Edge, Rising-Edge, or both. * Use this instead of directly setting GRER/GFER. */ -static int GPIO_IRQ_rising_edge; -static int GPIO_IRQ_falling_edge; -static int GPIO_IRQ_mask; +static void sa1100_update_edge_regs(struct sa1100_gpio_chip *sgc) +{ + void *base = sgc->membase; + u32 grer, gfer; + + grer = sgc->irqrising & sgc->irqmask; + gfer = sgc->irqfalling & sgc->irqmask; + + writel_relaxed(grer, base + R_GRER); + writel_relaxed(gfer, base + R_GFER); +} static int sa1100_gpio_type(struct irq_data *d, unsigned int type) { - unsigned int mask; - - mask = BIT(d->hwirq); + struct sa1100_gpio_chip *sgc = irq_data_get_irq_chip_data(d); + unsigned int mask = BIT(d->hwirq); if (type == IRQ_TYPE_PROBE) { - if ((GPIO_IRQ_rising_edge | GPIO_IRQ_falling_edge) & mask) + if ((sgc->irqrising | sgc->irqfalling) & mask) return 0; type = IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING; } if (type & IRQ_TYPE_EDGE_RISING) - GPIO_IRQ_rising_edge |= mask; + sgc->irqrising |= mask; else - GPIO_IRQ_rising_edge &= ~mask; + sgc->irqrising &= ~mask; if (type & IRQ_TYPE_EDGE_FALLING) - GPIO_IRQ_falling_edge |= mask; + sgc->irqfalling |= mask; else - GPIO_IRQ_falling_edge &= ~mask; + sgc->irqfalling &= ~mask; - GRER = GPIO_IRQ_rising_edge & GPIO_IRQ_mask; - GFER = GPIO_IRQ_falling_edge & GPIO_IRQ_mask; + sa1100_update_edge_regs(sgc); return 0; } @@ -106,36 +152,42 @@ static int sa1100_gpio_type(struct irq_data *d, unsigned int type) */ static void sa1100_gpio_ack(struct irq_data *d) { - GEDR = BIT(d->hwirq); + struct sa1100_gpio_chip *sgc = irq_data_get_irq_chip_data(d); + + writel_relaxed(BIT(d->hwirq), sgc->membase + R_GEDR); } static void sa1100_gpio_mask(struct irq_data *d) { + struct sa1100_gpio_chip *sgc = irq_data_get_irq_chip_data(d); unsigned int mask = BIT(d->hwirq); - GPIO_IRQ_mask &= ~mask; + sgc->irqmask &= ~mask; - GRER &= ~mask; - GFER &= ~mask; + sa1100_update_edge_regs(sgc); } static void sa1100_gpio_unmask(struct irq_data *d) { + struct sa1100_gpio_chip *sgc = irq_data_get_irq_chip_data(d); unsigned int mask = BIT(d->hwirq); - GPIO_IRQ_mask |= mask; + sgc->irqmask |= mask; - GRER = GPIO_IRQ_rising_edge & GPIO_IRQ_mask; - GFER = GPIO_IRQ_falling_edge & GPIO_IRQ_mask; + sa1100_update_edge_regs(sgc); } static int sa1100_gpio_wake(struct irq_data *d, unsigned int on) { - if (on) - PWER |= BIT(d->hwirq); - else - PWER &= ~BIT(d->hwirq); - return 0; + struct sa1100_gpio_chip *sgc = irq_data_get_irq_chip_data(d); + int ret = sa11x0_gpio_set_wake(d->hwirq, on); + if (!ret) { + if (on) + sgc->irqwake |= BIT(d->hwirq); + else + sgc->irqwake &= ~BIT(d->hwirq); + } + return ret; } /* @@ -153,8 +205,10 @@ static struct irq_chip sa1100_gpio_irq_chip = { static int sa1100_gpio_irqdomain_map(struct irq_domain *d, unsigned int irq, irq_hw_number_t hwirq) { - irq_set_chip_and_handler(irq, &sa1100_gpio_irq_chip, - handle_edge_irq); + struct sa1100_gpio_chip *sgc = d->host_data; + + irq_set_chip_data(irq, sgc); + irq_set_chip_and_handler(irq, &sa1100_gpio_irq_chip, handle_edge_irq); irq_set_probe(irq); return 0; @@ -174,17 +228,19 @@ static struct irq_domain *sa1100_gpio_irqdomain; */ static void sa1100_gpio_handler(struct irq_desc *desc) { + struct sa1100_gpio_chip *sgc = irq_desc_get_handler_data(desc); unsigned int irq, mask; + void __iomem *gedr = sgc->membase + R_GEDR; - mask = GEDR; + mask = readl_relaxed(gedr); do { /* * clear down all currently active IRQ sources. * We will be processing them all. */ - GEDR = mask; + writel_relaxed(mask, gedr); - irq = IRQ_GPIO0; + irq = sgc->irqbase; do { if (mask & 1) generic_handle_irq(irq); @@ -192,30 +248,32 @@ static void sa1100_gpio_handler(struct irq_desc *desc) irq++; } while (mask); - mask = GEDR; + mask = readl_relaxed(gedr); } while (mask); } static int sa1100_gpio_suspend(void) { + struct sa1100_gpio_chip *sgc = &sa1100_gpio_chip; + /* * Set the appropriate edges for wakeup. */ - GRER = PWER & GPIO_IRQ_rising_edge; - GFER = PWER & GPIO_IRQ_falling_edge; + writel_relaxed(sgc->irqwake & sgc->irqrising, sgc->membase + R_GRER); + writel_relaxed(sgc->irqwake & sgc->irqfalling, sgc->membase + R_GFER); /* * Clear any pending GPIO interrupts. */ - GEDR = GEDR; + writel_relaxed(readl_relaxed(sgc->membase + R_GEDR), + sgc->membase + R_GEDR); return 0; } static void sa1100_gpio_resume(void) { - GRER = GPIO_IRQ_rising_edge & GPIO_IRQ_mask; - GFER = GPIO_IRQ_falling_edge & GPIO_IRQ_mask; + sa1100_update_edge_regs(&sa1100_gpio_chip); } static struct syscore_ops sa1100_gpio_syscore_ops = { @@ -231,36 +289,40 @@ static int __init sa1100_gpio_init_devicefs(void) device_initcall(sa1100_gpio_init_devicefs); +static const int sa1100_gpio_irqs[] __initconst = { + /* Install handlers for GPIO 0-10 edge detect interrupts */ + IRQ_GPIO0_SC, + IRQ_GPIO1_SC, + IRQ_GPIO2_SC, + IRQ_GPIO3_SC, + IRQ_GPIO4_SC, + IRQ_GPIO5_SC, + IRQ_GPIO6_SC, + IRQ_GPIO7_SC, + IRQ_GPIO8_SC, + IRQ_GPIO9_SC, + IRQ_GPIO10_SC, + /* Install handler for GPIO 11-27 edge detect interrupts */ + IRQ_GPIO11_27, +}; + void __init sa1100_init_gpio(void) { + struct sa1100_gpio_chip *sgc = &sa1100_gpio_chip; + int i; + /* clear all GPIO edge detects */ - GFER = 0; - GRER = 0; - GEDR = -1; + writel_relaxed(0, sgc->membase + R_GFER); + writel_relaxed(0, sgc->membase + R_GRER); + writel_relaxed(-1, sgc->membase + R_GEDR); - gpiochip_add_data(&sa1100_gpio_chip, NULL); + gpiochip_add_data(&sa1100_gpio_chip.chip, NULL); sa1100_gpio_irqdomain = irq_domain_add_simple(NULL, 28, IRQ_GPIO0, - &sa1100_gpio_irqdomain_ops, NULL); - - /* - * Install handlers for GPIO 0-10 edge detect interrupts - */ - irq_set_chained_handler(IRQ_GPIO0_SC, sa1100_gpio_handler); - irq_set_chained_handler(IRQ_GPIO1_SC, sa1100_gpio_handler); - irq_set_chained_handler(IRQ_GPIO2_SC, sa1100_gpio_handler); - irq_set_chained_handler(IRQ_GPIO3_SC, sa1100_gpio_handler); - irq_set_chained_handler(IRQ_GPIO4_SC, sa1100_gpio_handler); - irq_set_chained_handler(IRQ_GPIO5_SC, sa1100_gpio_handler); - irq_set_chained_handler(IRQ_GPIO6_SC, sa1100_gpio_handler); - irq_set_chained_handler(IRQ_GPIO7_SC, sa1100_gpio_handler); - irq_set_chained_handler(IRQ_GPIO8_SC, sa1100_gpio_handler); - irq_set_chained_handler(IRQ_GPIO9_SC, sa1100_gpio_handler); - irq_set_chained_handler(IRQ_GPIO10_SC, sa1100_gpio_handler); - /* - * Install handler for GPIO 11-27 edge detect interrupts - */ - irq_set_chained_handler(IRQ_GPIO11_27, sa1100_gpio_handler); + &sa1100_gpio_irqdomain_ops, sgc); + for (i = 0; i < ARRAY_SIZE(sa1100_gpio_irqs); i++) + irq_set_chained_handler_and_data(sa1100_gpio_irqs[i], + sa1100_gpio_handler, sgc); } diff --git a/drivers/gpio/gpio-sodaville.c b/drivers/gpio/gpio-sodaville.c index 7da9e6c4546a..f60da83349ef 100644 --- a/drivers/gpio/gpio-sodaville.c +++ b/drivers/gpio/gpio-sodaville.c @@ -135,7 +135,8 @@ static int sdv_register_irqsupport(struct sdv_gpio_chip_data *sd, struct irq_chip_type *ct; int ret; - sd->irq_base = irq_alloc_descs(-1, 0, SDV_NUM_PUB_GPIOS, -1); + sd->irq_base = devm_irq_alloc_descs(&pdev->dev, -1, 0, + SDV_NUM_PUB_GPIOS, -1); if (sd->irq_base < 0) return sd->irq_base; @@ -143,10 +144,11 @@ static int sdv_register_irqsupport(struct sdv_gpio_chip_data *sd, writel(0, sd->gpio_pub_base + GPIO_INT); writel((1 << 11) - 1, sd->gpio_pub_base + GPSTR); - ret = request_irq(pdev->irq, sdv_gpio_pub_irq_handler, IRQF_SHARED, - "sdv_gpio", sd); + ret = devm_request_irq(&pdev->dev, pdev->irq, + sdv_gpio_pub_irq_handler, IRQF_SHARED, + "sdv_gpio", sd); if (ret) - goto out_free_desc; + return ret; /* * This gpio irq controller latches level irqs. Testing shows that if @@ -155,10 +157,8 @@ static int sdv_register_irqsupport(struct sdv_gpio_chip_data *sd, */ sd->gc = irq_alloc_generic_chip("sdv-gpio", 1, sd->irq_base, sd->gpio_pub_base, handle_fasteoi_irq); - if (!sd->gc) { - ret = -ENOMEM; - goto out_free_irq; - } + if (!sd->gc) + return -ENOMEM; sd->gc->private = sd; ct = sd->gc->chip_types; @@ -176,16 +176,10 @@ static int sdv_register_irqsupport(struct sdv_gpio_chip_data *sd, sd->id = irq_domain_add_legacy(pdev->dev.of_node, SDV_NUM_PUB_GPIOS, sd->irq_base, 0, &irq_domain_sdv_ops, sd); - if (!sd->id) { - ret = -ENODEV; - goto out_free_irq; - } + if (!sd->id) + return -ENODEV; + return 0; -out_free_irq: - free_irq(pdev->irq, sd); -out_free_desc: - irq_free_descs(sd->irq_base, SDV_NUM_PUB_GPIOS); - return ret; } static int sdv_gpio_probe(struct pci_dev *pdev, diff --git a/drivers/gpio/gpio-sta2x11.c b/drivers/gpio/gpio-sta2x11.c index 853ca23cad88..39df0620fa38 100644 --- a/drivers/gpio/gpio-sta2x11.c +++ b/drivers/gpio/gpio-sta2x11.c @@ -392,7 +392,8 @@ static int gsta_probe(struct platform_device *dev) gsta_set_config(chip, i, gpio_pdata->pinconfig[i]); /* 384 was used in previous code: be compatible for other drivers */ - err = irq_alloc_descs(-1, 384, GSTA_NR_GPIO, NUMA_NO_NODE); + err = devm_irq_alloc_descs(&dev->dev, -1, 384, + GSTA_NR_GPIO, NUMA_NO_NODE); if (err < 0) { dev_warn(&dev->dev, "sta2x11 gpio: Can't get irq base (%i)\n", -err); @@ -401,29 +402,23 @@ static int gsta_probe(struct platform_device *dev) chip->irq_base = err; gsta_alloc_irq_chip(chip); - err = request_irq(pdev->irq, gsta_gpio_handler, - IRQF_SHARED, KBUILD_MODNAME, chip); + err = devm_request_irq(&dev->dev, pdev->irq, gsta_gpio_handler, + IRQF_SHARED, KBUILD_MODNAME, chip); if (err < 0) { dev_err(&dev->dev, "sta2x11 gpio: Can't request irq (%i)\n", -err); - goto err_free_descs; + return err; } err = devm_gpiochip_add_data(&dev->dev, &chip->gpio, chip); if (err < 0) { dev_err(&dev->dev, "sta2x11 gpio: Can't register (%i)\n", -err); - goto err_free_irq; + return err; } platform_set_drvdata(dev, chip); return 0; - -err_free_irq: - free_irq(pdev->irq, chip); -err_free_descs: - irq_free_descs(chip->irq_base, GSTA_NR_GPIO); - return err; } static struct platform_driver sta2x11_gpio_platform_driver = { diff --git a/drivers/gpio/gpio-twl4030.c b/drivers/gpio/gpio-twl4030.c index dfcfbba74416..24f388ed46d4 100644 --- a/drivers/gpio/gpio-twl4030.c +++ b/drivers/gpio/gpio-twl4030.c @@ -485,7 +485,8 @@ static int gpio_twl4030_probe(struct platform_device *pdev) goto no_irqs; } - irq_base = irq_alloc_descs(-1, 0, TWL4030_GPIO_MAX, 0); + irq_base = devm_irq_alloc_descs(&pdev->dev, -1, + 0, TWL4030_GPIO_MAX, 0); if (irq_base < 0) { dev_err(&pdev->dev, "Failed to alloc irq_descs\n"); return irq_base; diff --git a/drivers/gpio/gpio-ws16c48.c b/drivers/gpio/gpio-ws16c48.c index 901b5ccb032d..87d63695dfcf 100644 --- a/drivers/gpio/gpio-ws16c48.c +++ b/drivers/gpio/gpio-ws16c48.c @@ -51,7 +51,7 @@ struct ws16c48_gpio { struct gpio_chip chip; unsigned char io_state[6]; unsigned char out_state[6]; - spinlock_t lock; + raw_spinlock_t lock; unsigned long irq_mask; unsigned long flow_mask; unsigned base; @@ -73,13 +73,13 @@ static int ws16c48_gpio_direction_input(struct gpio_chip *chip, unsigned offset) const unsigned mask = BIT(offset % 8); unsigned long flags; - spin_lock_irqsave(&ws16c48gpio->lock, flags); + raw_spin_lock_irqsave(&ws16c48gpio->lock, flags); ws16c48gpio->io_state[port] |= mask; ws16c48gpio->out_state[port] &= ~mask; outb(ws16c48gpio->out_state[port], ws16c48gpio->base + port); - spin_unlock_irqrestore(&ws16c48gpio->lock, flags); + raw_spin_unlock_irqrestore(&ws16c48gpio->lock, flags); return 0; } @@ -92,7 +92,7 @@ static int ws16c48_gpio_direction_output(struct gpio_chip *chip, const unsigned mask = BIT(offset % 8); unsigned long flags; - spin_lock_irqsave(&ws16c48gpio->lock, flags); + raw_spin_lock_irqsave(&ws16c48gpio->lock, flags); ws16c48gpio->io_state[port] &= ~mask; if (value) @@ -101,7 +101,7 @@ static int ws16c48_gpio_direction_output(struct gpio_chip *chip, ws16c48gpio->out_state[port] &= ~mask; outb(ws16c48gpio->out_state[port], ws16c48gpio->base + port); - spin_unlock_irqrestore(&ws16c48gpio->lock, flags); + raw_spin_unlock_irqrestore(&ws16c48gpio->lock, flags); return 0; } @@ -114,17 +114,17 @@ static int ws16c48_gpio_get(struct gpio_chip *chip, unsigned offset) unsigned long flags; unsigned port_state; - spin_lock_irqsave(&ws16c48gpio->lock, flags); + raw_spin_lock_irqsave(&ws16c48gpio->lock, flags); /* ensure that GPIO is set for input */ if (!(ws16c48gpio->io_state[port] & mask)) { - spin_unlock_irqrestore(&ws16c48gpio->lock, flags); + raw_spin_unlock_irqrestore(&ws16c48gpio->lock, flags); return -EINVAL; } port_state = inb(ws16c48gpio->base + port); - spin_unlock_irqrestore(&ws16c48gpio->lock, flags); + raw_spin_unlock_irqrestore(&ws16c48gpio->lock, flags); return !!(port_state & mask); } @@ -136,11 +136,11 @@ static void ws16c48_gpio_set(struct gpio_chip *chip, unsigned offset, int value) const unsigned mask = BIT(offset % 8); unsigned long flags; - spin_lock_irqsave(&ws16c48gpio->lock, flags); + raw_spin_lock_irqsave(&ws16c48gpio->lock, flags); /* ensure that GPIO is set for output */ if (ws16c48gpio->io_state[port] & mask) { - spin_unlock_irqrestore(&ws16c48gpio->lock, flags); + raw_spin_unlock_irqrestore(&ws16c48gpio->lock, flags); return; } @@ -150,7 +150,7 @@ static void ws16c48_gpio_set(struct gpio_chip *chip, unsigned offset, int value) ws16c48gpio->out_state[port] &= ~mask; outb(ws16c48gpio->out_state[port], ws16c48gpio->base + port); - spin_unlock_irqrestore(&ws16c48gpio->lock, flags); + raw_spin_unlock_irqrestore(&ws16c48gpio->lock, flags); } static void ws16c48_gpio_set_multiple(struct gpio_chip *chip, @@ -178,14 +178,14 @@ static void ws16c48_gpio_set_multiple(struct gpio_chip *chip, iomask = mask[BIT_WORD(i)] & ~ws16c48gpio->io_state[port]; bitmask = iomask & bits[BIT_WORD(i)]; - spin_lock_irqsave(&ws16c48gpio->lock, flags); + raw_spin_lock_irqsave(&ws16c48gpio->lock, flags); /* update output state data and set device gpio register */ ws16c48gpio->out_state[port] &= ~iomask; ws16c48gpio->out_state[port] |= bitmask; outb(ws16c48gpio->out_state[port], ws16c48gpio->base + port); - spin_unlock_irqrestore(&ws16c48gpio->lock, flags); + raw_spin_unlock_irqrestore(&ws16c48gpio->lock, flags); /* prepare for next gpio register set */ mask[BIT_WORD(i)] >>= gpio_reg_size; @@ -207,7 +207,7 @@ static void ws16c48_irq_ack(struct irq_data *data) if (port > 2) return; - spin_lock_irqsave(&ws16c48gpio->lock, flags); + raw_spin_lock_irqsave(&ws16c48gpio->lock, flags); port_state = ws16c48gpio->irq_mask >> (8*port); @@ -216,7 +216,7 @@ static void ws16c48_irq_ack(struct irq_data *data) outb(port_state | mask, ws16c48gpio->base + 8 + port); outb(0xC0, ws16c48gpio->base + 7); - spin_unlock_irqrestore(&ws16c48gpio->lock, flags); + raw_spin_unlock_irqrestore(&ws16c48gpio->lock, flags); } static void ws16c48_irq_mask(struct irq_data *data) @@ -232,7 +232,7 @@ static void ws16c48_irq_mask(struct irq_data *data) if (port > 2) return; - spin_lock_irqsave(&ws16c48gpio->lock, flags); + raw_spin_lock_irqsave(&ws16c48gpio->lock, flags); ws16c48gpio->irq_mask &= ~mask; @@ -240,7 +240,7 @@ static void ws16c48_irq_mask(struct irq_data *data) outb(ws16c48gpio->irq_mask >> (8*port), ws16c48gpio->base + 8 + port); outb(0xC0, ws16c48gpio->base + 7); - spin_unlock_irqrestore(&ws16c48gpio->lock, flags); + raw_spin_unlock_irqrestore(&ws16c48gpio->lock, flags); } static void ws16c48_irq_unmask(struct irq_data *data) @@ -256,7 +256,7 @@ static void ws16c48_irq_unmask(struct irq_data *data) if (port > 2) return; - spin_lock_irqsave(&ws16c48gpio->lock, flags); + raw_spin_lock_irqsave(&ws16c48gpio->lock, flags); ws16c48gpio->irq_mask |= mask; @@ -264,7 +264,7 @@ static void ws16c48_irq_unmask(struct irq_data *data) outb(ws16c48gpio->irq_mask >> (8*port), ws16c48gpio->base + 8 + port); outb(0xC0, ws16c48gpio->base + 7); - spin_unlock_irqrestore(&ws16c48gpio->lock, flags); + raw_spin_unlock_irqrestore(&ws16c48gpio->lock, flags); } static int ws16c48_irq_set_type(struct irq_data *data, unsigned flow_type) @@ -280,7 +280,7 @@ static int ws16c48_irq_set_type(struct irq_data *data, unsigned flow_type) if (port > 2) return -EINVAL; - spin_lock_irqsave(&ws16c48gpio->lock, flags); + raw_spin_lock_irqsave(&ws16c48gpio->lock, flags); switch (flow_type) { case IRQ_TYPE_NONE: @@ -292,7 +292,7 @@ static int ws16c48_irq_set_type(struct irq_data *data, unsigned flow_type) ws16c48gpio->flow_mask &= ~mask; break; default: - spin_unlock_irqrestore(&ws16c48gpio->lock, flags); + raw_spin_unlock_irqrestore(&ws16c48gpio->lock, flags); return -EINVAL; } @@ -300,7 +300,7 @@ static int ws16c48_irq_set_type(struct irq_data *data, unsigned flow_type) outb(ws16c48gpio->flow_mask >> (8*port), ws16c48gpio->base + 8 + port); outb(0xC0, ws16c48gpio->base + 7); - spin_unlock_irqrestore(&ws16c48gpio->lock, flags); + raw_spin_unlock_irqrestore(&ws16c48gpio->lock, flags); return 0; } @@ -387,7 +387,7 @@ static int ws16c48_probe(struct device *dev, unsigned int id) ws16c48gpio->chip.set_multiple = ws16c48_gpio_set_multiple; ws16c48gpio->base = base[id]; - spin_lock_init(&ws16c48gpio->lock); + raw_spin_lock_init(&ws16c48gpio->lock); err = devm_gpiochip_add_data(dev, &ws16c48gpio->chip, ws16c48gpio); if (err) { diff --git a/drivers/gpio/gpio-xlp.c b/drivers/gpio/gpio-xlp.c index 4620d050e5a8..d857e1d8e731 100644 --- a/drivers/gpio/gpio-xlp.c +++ b/drivers/gpio/gpio-xlp.c @@ -404,7 +404,9 @@ static int xlp_gpio_probe(struct platform_device *pdev) /* XLP(MIPS) has fixed range for GPIO IRQs, Vulcan(ARM64) does not */ if (soc_type != GPIO_VARIANT_VULCAN) { - irq_base = irq_alloc_descs(-1, XLP_GPIO_IRQ_BASE, gc->ngpio, 0); + irq_base = devm_irq_alloc_descs(&pdev->dev, -1, + XLP_GPIO_IRQ_BASE, + gc->ngpio, 0); if (irq_base < 0) { dev_err(&pdev->dev, "Failed to allocate IRQ numbers\n"); return irq_base; @@ -415,7 +417,7 @@ static int xlp_gpio_probe(struct platform_device *pdev) err = gpiochip_add_data(gc, priv); if (err < 0) - goto out_free_desc; + return err; err = gpiochip_irqchip_add(gc, &xlp_gpio_irq_chip, irq_base, handle_level_irq, IRQ_TYPE_NONE); @@ -433,14 +435,13 @@ static int xlp_gpio_probe(struct platform_device *pdev) out_gpio_remove: gpiochip_remove(gc); -out_free_desc: - irq_free_descs(irq_base, gc->ngpio); return err; } #ifdef CONFIG_ACPI static const struct acpi_device_id xlp_gpio_acpi_match[] = { { "BRCM9006", GPIO_VARIANT_VULCAN }, + { "CAV9006", GPIO_VARIANT_VULCAN }, {}, }; MODULE_DEVICE_TABLE(acpi, xlp_gpio_acpi_match); diff --git a/drivers/gpio/gpio-zx.c b/drivers/gpio/gpio-zx.c index 93de8be0d885..be3a87da8438 100644 --- a/drivers/gpio/gpio-zx.c +++ b/drivers/gpio/gpio-zx.c @@ -41,7 +41,7 @@ #define ZX_GPIO_NR 16 struct zx_gpio { - spinlock_t lock; + raw_spinlock_t lock; void __iomem *base; struct gpio_chip gc; @@ -56,11 +56,11 @@ static int zx_direction_input(struct gpio_chip *gc, unsigned offset) if (offset >= gc->ngpio) return -EINVAL; - spin_lock_irqsave(&chip->lock, flags); + raw_spin_lock_irqsave(&chip->lock, flags); gpiodir = readw_relaxed(chip->base + ZX_GPIO_DIR); gpiodir &= ~BIT(offset); writew_relaxed(gpiodir, chip->base + ZX_GPIO_DIR); - spin_unlock_irqrestore(&chip->lock, flags); + raw_spin_unlock_irqrestore(&chip->lock, flags); return 0; } @@ -75,7 +75,7 @@ static int zx_direction_output(struct gpio_chip *gc, unsigned offset, if (offset >= gc->ngpio) return -EINVAL; - spin_lock_irqsave(&chip->lock, flags); + raw_spin_lock_irqsave(&chip->lock, flags); gpiodir = readw_relaxed(chip->base + ZX_GPIO_DIR); gpiodir |= BIT(offset); writew_relaxed(gpiodir, chip->base + ZX_GPIO_DIR); @@ -84,7 +84,7 @@ static int zx_direction_output(struct gpio_chip *gc, unsigned offset, writew_relaxed(BIT(offset), chip->base + ZX_GPIO_DO1); else writew_relaxed(BIT(offset), chip->base + ZX_GPIO_DO0); - spin_unlock_irqrestore(&chip->lock, flags); + raw_spin_unlock_irqrestore(&chip->lock, flags); return 0; } @@ -118,7 +118,7 @@ static int zx_irq_type(struct irq_data *d, unsigned trigger) if (offset < 0 || offset >= ZX_GPIO_NR) return -EINVAL; - spin_lock_irqsave(&chip->lock, flags); + raw_spin_lock_irqsave(&chip->lock, flags); gpioiev = readw_relaxed(chip->base + ZX_GPIO_IV); gpiois = readw_relaxed(chip->base + ZX_GPIO_IVE); @@ -151,7 +151,7 @@ static int zx_irq_type(struct irq_data *d, unsigned trigger) writew_relaxed(gpioi_epos, chip->base + ZX_GPIO_IEP); writew_relaxed(gpioi_eneg, chip->base + ZX_GPIO_IEN); writew_relaxed(gpioiev, chip->base + ZX_GPIO_IV); - spin_unlock_irqrestore(&chip->lock, flags); + raw_spin_unlock_irqrestore(&chip->lock, flags); return 0; } @@ -184,12 +184,12 @@ static void zx_irq_mask(struct irq_data *d) u16 mask = BIT(irqd_to_hwirq(d) % ZX_GPIO_NR); u16 gpioie; - spin_lock(&chip->lock); + raw_spin_lock(&chip->lock); gpioie = readw_relaxed(chip->base + ZX_GPIO_IM) | mask; writew_relaxed(gpioie, chip->base + ZX_GPIO_IM); gpioie = readw_relaxed(chip->base + ZX_GPIO_IE) & ~mask; writew_relaxed(gpioie, chip->base + ZX_GPIO_IE); - spin_unlock(&chip->lock); + raw_spin_unlock(&chip->lock); } static void zx_irq_unmask(struct irq_data *d) @@ -199,12 +199,12 @@ static void zx_irq_unmask(struct irq_data *d) u16 mask = BIT(irqd_to_hwirq(d) % ZX_GPIO_NR); u16 gpioie; - spin_lock(&chip->lock); + raw_spin_lock(&chip->lock); gpioie = readw_relaxed(chip->base + ZX_GPIO_IM) & ~mask; writew_relaxed(gpioie, chip->base + ZX_GPIO_IM); gpioie = readw_relaxed(chip->base + ZX_GPIO_IE) | mask; writew_relaxed(gpioie, chip->base + ZX_GPIO_IE); - spin_unlock(&chip->lock); + raw_spin_unlock(&chip->lock); } static struct irq_chip zx_irqchip = { @@ -230,7 +230,7 @@ static int zx_gpio_probe(struct platform_device *pdev) if (IS_ERR(chip->base)) return PTR_ERR(chip->base); - spin_lock_init(&chip->lock); + raw_spin_lock_init(&chip->lock); if (of_property_read_bool(dev->of_node, "gpio-ranges")) { chip->gc.request = gpiochip_generic_request; chip->gc.free = gpiochip_generic_free; diff --git a/drivers/gpio/gpiolib-acpi.c b/drivers/gpio/gpiolib-acpi.c index 2bd683e2be02..2185232da823 100644 --- a/drivers/gpio/gpiolib-acpi.c +++ b/drivers/gpio/gpiolib-acpi.c @@ -368,6 +368,37 @@ int acpi_dev_add_driver_gpios(struct acpi_device *adev, } EXPORT_SYMBOL_GPL(acpi_dev_add_driver_gpios); +static void devm_acpi_dev_release_driver_gpios(struct device *dev, void *res) +{ + acpi_dev_remove_driver_gpios(ACPI_COMPANION(dev)); +} + +int devm_acpi_dev_add_driver_gpios(struct device *dev, + const struct acpi_gpio_mapping *gpios) +{ + void *res; + int ret; + + res = devres_alloc(devm_acpi_dev_release_driver_gpios, 0, GFP_KERNEL); + if (!res) + return -ENOMEM; + + ret = acpi_dev_add_driver_gpios(ACPI_COMPANION(dev), gpios); + if (ret) { + devres_free(res); + return ret; + } + devres_add(dev, res); + return 0; +} +EXPORT_SYMBOL_GPL(devm_acpi_dev_add_driver_gpios); + +void devm_acpi_dev_remove_driver_gpios(struct device *dev) +{ + WARN_ON(devres_release(dev, devm_acpi_dev_release_driver_gpios, NULL, NULL)); +} +EXPORT_SYMBOL_GPL(devm_acpi_dev_remove_driver_gpios); + static bool acpi_get_driver_gpio_data(struct acpi_device *adev, const char *name, int index, struct acpi_reference_args *args) @@ -661,20 +692,24 @@ int acpi_dev_gpio_irq_get(struct acpi_device *adev, int index) { int idx, i; unsigned int irq_flags; - int ret = -ENOENT; for (i = 0, idx = 0; idx <= index; i++) { struct acpi_gpio_info info; struct gpio_desc *desc; desc = acpi_get_gpiod_by_index(adev, NULL, i, &info); - if (IS_ERR(desc)) { - ret = PTR_ERR(desc); - break; - } + + /* Ignore -EPROBE_DEFER, it only matters if idx matches */ + if (IS_ERR(desc) && PTR_ERR(desc) != -EPROBE_DEFER) + return PTR_ERR(desc); + if (info.gpioint && idx++ == index) { - int irq = gpiod_to_irq(desc); + int irq; + if (IS_ERR(desc)) + return PTR_ERR(desc); + + irq = gpiod_to_irq(desc); if (irq < 0) return irq; @@ -690,7 +725,7 @@ int acpi_dev_gpio_irq_get(struct acpi_device *adev, int index) } } - return ret; + return -ENOENT; } EXPORT_SYMBOL_GPL(acpi_dev_gpio_irq_get); @@ -1075,7 +1110,7 @@ int acpi_gpio_count(struct device *dev, const char *con_id) break; } } - if (count >= 0) + if (count > 0) break; } @@ -1091,7 +1126,7 @@ int acpi_gpio_count(struct device *dev, const char *con_id) if (crs_count > 0) count = crs_count; } - return count; + return count ? count : -ENOENT; } struct acpi_crs_lookup { diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index 3ce2a27ee78f..4aa1e78f0f0b 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -3115,10 +3115,10 @@ static int dt_gpio_count(struct device *dev, const char *con_id) gpio_suffixes[i]); ret = of_gpio_named_count(dev->of_node, propname); - if (ret >= 0) + if (ret > 0) break; } - return ret; + return ret ? ret : -ENOENT; } static int platform_gpio_count(struct device *dev, const char *con_id) @@ -3319,7 +3319,7 @@ EXPORT_SYMBOL_GPL(gpiod_get_index); * underlying firmware interface and then makes sure that the GPIO * descriptor is requested before it is returned to the caller. * - * On successfull request the GPIO pin is configured in accordance with + * On successful request the GPIO pin is configured in accordance with * provided @dflags. * * In case of error an ERR_PTR() is returned. |