diff options
Diffstat (limited to 'drivers/gpio')
81 files changed, 1178 insertions, 533 deletions
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index b18bea08ff25..b60f40a423f3 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -496,8 +496,21 @@ menu "Port-mapped I/O GPIO drivers" config GPIO_104_IDIO_16 tristate "ACCES 104-IDIO-16 GPIO support" + select GPIOLIB_IRQCHIP + help + Enables GPIO support for the ACCES 104-IDIO-16 family. The base port + address for the device may be set via the idio_16_base module + parameter. The interrupt line number for the device may be set via the + idio_16_irq module parameter. + +config GPIO_104_IDI_48 + tristate "ACCES 104-IDI-48 GPIO support" + select GPIOLIB_IRQCHIP help - Enables GPIO support for the ACCES 104-IDIO-16 family. + Enables GPIO support for the ACCES 104-IDI-48 family. The base port + address for the device may be configured via the idi_48_base module + parameter. The interrupt line number for the device may be configured + via the idi_48_irq module parameter. config GPIO_F7188X tristate "F71869, F71869A, F71882FG and F71889F GPIO support" @@ -907,7 +920,6 @@ menu "PCI GPIO expanders" config GPIO_AMD8111 tristate "AMD 8111 GPIO driver" - depends on PCI help The AMD 8111 south bridge contains 32 GPIO pins which can be used. @@ -919,7 +931,7 @@ config GPIO_AMD8111 config GPIO_BT8XX tristate "BT8XX GPIO abuser" - depends on PCI && VIDEO_BT848=n + depends on VIDEO_BT848=n help The BT8xx frame grabber chip has 24 GPIO pins that can be abused as a cheap PCI GPIO card. @@ -935,14 +947,13 @@ config GPIO_BT8XX config GPIO_INTEL_MID bool "Intel Mid GPIO support" - depends on PCI && X86 + depends on X86 select GPIOLIB_IRQCHIP help Say Y here to support Intel Mid GPIO. config GPIO_ML_IOH tristate "OKI SEMICONDUCTOR ML7213 IOH GPIO support" - depends on PCI select GENERIC_IRQ_CHIP help ML7213 is companion chip for Intel Atom E6xx series. @@ -952,7 +963,7 @@ config GPIO_ML_IOH config GPIO_PCH tristate "Intel EG20T PCH/LAPIS Semiconductor IOH(ML7223/ML7831) GPIO" - depends on PCI && (X86_32 || COMPILE_TEST) + depends on X86_32 || MIPS || COMPILE_TEST select GENERIC_IRQ_CHIP help This driver is for PCH(Platform controller Hub) GPIO of Intel Topcliff @@ -968,7 +979,6 @@ config GPIO_PCH config GPIO_RDC321X tristate "RDC R-321x GPIO support" - depends on PCI select MFD_CORE select MFD_RDC321X help @@ -977,7 +987,7 @@ config GPIO_RDC321X config GPIO_SODAVILLE bool "Intel Sodaville GPIO support" - depends on X86 && PCI && OF + depends on X86 && OF select GPIO_GENERIC select GENERIC_IRQ_CHIP help @@ -1028,7 +1038,7 @@ menu "USB GPIO expanders" config GPIO_VIPERBOARD tristate "Viperboard GPIO a & b support" - depends on MFD_VIPERBOARD && USB + depends on MFD_VIPERBOARD help Say yes here to access the GPIO signals of Nano River Technologies Viperboard. There are two GPIO chips on the diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile index 986dbd838cea..548e9b5718ee 100644 --- a/drivers/gpio/Makefile +++ b/drivers/gpio/Makefile @@ -13,6 +13,7 @@ obj-$(CONFIG_GPIO_ACPI) += gpiolib-acpi.o obj-$(CONFIG_GPIO_GENERIC) += gpio-generic.o obj-$(CONFIG_GPIO_104_IDIO_16) += gpio-104-idio-16.o +obj-$(CONFIG_GPIO_104_IDI_48) += gpio-104-idi-48.o obj-$(CONFIG_GPIO_74X164) += gpio-74x164.o obj-$(CONFIG_GPIO_74XX_MMIO) += gpio-74xx-mmio.o obj-$(CONFIG_GPIO_ADNP) += gpio-adnp.o diff --git a/drivers/gpio/gpio-104-idi-48.c b/drivers/gpio/gpio-104-idi-48.c new file mode 100644 index 000000000000..b5c693409a58 --- /dev/null +++ b/drivers/gpio/gpio-104-idi-48.c @@ -0,0 +1,349 @@ +/* + * GPIO driver for the ACCES 104-IDI-48 family + * Copyright (C) 2015 William Breathitt Gray + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License, version 2, as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + */ +#include <linux/bitops.h> +#include <linux/device.h> +#include <linux/errno.h> +#include <linux/gpio/driver.h> +#include <linux/io.h> +#include <linux/ioport.h> +#include <linux/interrupt.h> +#include <linux/irqdesc.h> +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/moduleparam.h> +#include <linux/platform_device.h> +#include <linux/spinlock.h> + +static unsigned idi_48_base; +module_param(idi_48_base, uint, 0); +MODULE_PARM_DESC(idi_48_base, "ACCES 104-IDI-48 base address"); +static unsigned idi_48_irq; +module_param(idi_48_irq, uint, 0); +MODULE_PARM_DESC(idi_48_irq, "ACCES 104-IDI-48 interrupt line number"); + +/** + * struct idi_48_gpio - GPIO device private data structure + * @chip: instance of the gpio_chip + * @lock: synchronization lock to prevent I/O race conditions + * @irq_mask: input bits affected by interrupts + * @base: base port address of the GPIO device + * @extent: extent of port address region of the GPIO device + * @irq: Interrupt line number + * @cos_enb: Change-Of-State IRQ enable boundaries mask + */ +struct idi_48_gpio { + struct gpio_chip chip; + spinlock_t lock; + unsigned char irq_mask[6]; + unsigned base; + unsigned extent; + unsigned irq; + unsigned char cos_enb; +}; + +static int idi_48_gpio_get_direction(struct gpio_chip *chip, unsigned offset) +{ + return 1; +} + +static int idi_48_gpio_direction_input(struct gpio_chip *chip, unsigned offset) +{ + return 0; +} + +static struct idi_48_gpio *to_idi48gpio(struct gpio_chip *gc) +{ + return container_of(gc, struct idi_48_gpio, chip); +} + +static int idi_48_gpio_get(struct gpio_chip *chip, unsigned offset) +{ + struct idi_48_gpio *const idi48gpio = to_idi48gpio(chip); + unsigned i; + const unsigned register_offset[6] = { 0, 1, 2, 4, 5, 6 }; + unsigned base_offset; + unsigned mask; + + for (i = 0; i < 48; i += 8) + if (offset < i + 8) { + base_offset = register_offset[i / 8]; + mask = BIT(offset - i); + + return !!(inb(idi48gpio->base + base_offset) & mask); + } + + /* The following line should never execute since offset < 48 */ + return 0; +} + +static void idi_48_irq_ack(struct irq_data *data) +{ + struct gpio_chip *chip = irq_data_get_irq_chip_data(data); + struct idi_48_gpio *const idi48gpio = to_idi48gpio(chip); + unsigned long flags; + + spin_lock_irqsave(&idi48gpio->lock, flags); + + inb(idi48gpio->base + 7); + + spin_unlock_irqrestore(&idi48gpio->lock, flags); +} + +static void idi_48_irq_mask(struct irq_data *data) +{ + struct gpio_chip *chip = irq_data_get_irq_chip_data(data); + struct idi_48_gpio *const idi48gpio = to_idi48gpio(chip); + const unsigned offset = irqd_to_hwirq(data); + unsigned i; + unsigned mask; + unsigned boundary; + unsigned long flags; + + for (i = 0; i < 48; i += 8) + if (offset < i + 8) { + mask = BIT(offset - i); + boundary = i / 8; + + idi48gpio->irq_mask[boundary] &= ~mask; + + if (!idi48gpio->irq_mask[boundary]) { + idi48gpio->cos_enb &= ~BIT(boundary); + + spin_lock_irqsave(&idi48gpio->lock, flags); + + outb(idi48gpio->cos_enb, idi48gpio->base + 7); + + spin_unlock_irqrestore(&idi48gpio->lock, flags); + } + + return; + } +} + +static void idi_48_irq_unmask(struct irq_data *data) +{ + struct gpio_chip *chip = irq_data_get_irq_chip_data(data); + struct idi_48_gpio *const idi48gpio = to_idi48gpio(chip); + const unsigned offset = irqd_to_hwirq(data); + unsigned i; + unsigned mask; + unsigned boundary; + unsigned prev_irq_mask; + unsigned long flags; + + for (i = 0; i < 48; i += 8) + if (offset < i + 8) { + mask = BIT(offset - i); + boundary = i / 8; + prev_irq_mask = idi48gpio->irq_mask[boundary]; + + idi48gpio->irq_mask[boundary] |= mask; + + if (!prev_irq_mask) { + idi48gpio->cos_enb |= BIT(boundary); + + spin_lock_irqsave(&idi48gpio->lock, flags); + + outb(idi48gpio->cos_enb, idi48gpio->base + 7); + + spin_unlock_irqrestore(&idi48gpio->lock, flags); + } + + return; + } +} + +static int idi_48_irq_set_type(struct irq_data *data, unsigned flow_type) +{ + /* The only valid irq types are none and both-edges */ + if (flow_type != IRQ_TYPE_NONE && + (flow_type & IRQ_TYPE_EDGE_BOTH) != IRQ_TYPE_EDGE_BOTH) + return -EINVAL; + + return 0; +} + +static struct irq_chip idi_48_irqchip = { + .name = "104-idi-48", + .irq_ack = idi_48_irq_ack, + .irq_mask = idi_48_irq_mask, + .irq_unmask = idi_48_irq_unmask, + .irq_set_type = idi_48_irq_set_type +}; + +static irqreturn_t idi_48_irq_handler(int irq, void *dev_id) +{ + struct idi_48_gpio *const idi48gpio = dev_id; + unsigned long cos_status; + unsigned long boundary; + unsigned long irq_mask; + unsigned long bit_num; + unsigned long gpio; + struct gpio_chip *const chip = &idi48gpio->chip; + + spin_lock(&idi48gpio->lock); + + cos_status = inb(idi48gpio->base + 7); + + spin_unlock(&idi48gpio->lock); + + /* IRQ Status (bit 6) is active low (0 = IRQ generated by device) */ + if (cos_status & BIT(6)) + return IRQ_NONE; + + /* Bit 0-5 indicate which Change-Of-State boundary triggered the IRQ */ + cos_status &= 0x3F; + + for_each_set_bit(boundary, &cos_status, 6) { + irq_mask = idi48gpio->irq_mask[boundary]; + + for_each_set_bit(bit_num, &irq_mask, 8) { + gpio = bit_num + boundary * 8; + + generic_handle_irq(irq_find_mapping(chip->irqdomain, + gpio)); + } + } + + return IRQ_HANDLED; +} + +static int __init idi_48_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct idi_48_gpio *idi48gpio; + const unsigned base = idi_48_base; + const unsigned extent = 8; + const char *const name = dev_name(dev); + int err; + const unsigned irq = idi_48_irq; + + idi48gpio = devm_kzalloc(dev, sizeof(*idi48gpio), GFP_KERNEL); + if (!idi48gpio) + return -ENOMEM; + + if (!request_region(base, extent, name)) { + dev_err(dev, "Unable to lock %s port addresses (0x%X-0x%X)\n", + name, base, base + extent); + err = -EBUSY; + goto err_lock_io_port; + } + + idi48gpio->chip.label = name; + idi48gpio->chip.parent = dev; + idi48gpio->chip.owner = THIS_MODULE; + idi48gpio->chip.base = -1; + idi48gpio->chip.ngpio = 48; + idi48gpio->chip.get_direction = idi_48_gpio_get_direction; + idi48gpio->chip.direction_input = idi_48_gpio_direction_input; + idi48gpio->chip.get = idi_48_gpio_get; + idi48gpio->base = base; + idi48gpio->extent = extent; + idi48gpio->irq = irq; + + spin_lock_init(&idi48gpio->lock); + + dev_set_drvdata(dev, idi48gpio); + + err = gpiochip_add(&idi48gpio->chip); + if (err) { + dev_err(dev, "GPIO registering failed (%d)\n", err); + goto err_gpio_register; + } + + /* Disable IRQ by default */ + outb(0, base + 7); + inb(base + 7); + + err = gpiochip_irqchip_add(&idi48gpio->chip, &idi_48_irqchip, 0, + handle_edge_irq, IRQ_TYPE_NONE); + if (err) { + dev_err(dev, "Could not add irqchip (%d)\n", err); + goto err_gpiochip_irqchip_add; + } + + err = request_irq(irq, idi_48_irq_handler, 0, name, idi48gpio); + if (err) { + dev_err(dev, "IRQ handler registering failed (%d)\n", err); + goto err_request_irq; + } + + return 0; + +err_request_irq: +err_gpiochip_irqchip_add: + gpiochip_remove(&idi48gpio->chip); +err_gpio_register: + release_region(base, extent); +err_lock_io_port: + return err; +} + +static int idi_48_remove(struct platform_device *pdev) +{ + struct idi_48_gpio *const idi48gpio = platform_get_drvdata(pdev); + + free_irq(idi48gpio->irq, idi48gpio); + gpiochip_remove(&idi48gpio->chip); + release_region(idi48gpio->base, idi48gpio->extent); + + return 0; +} + +static struct platform_device *idi_48_device; + +static struct platform_driver idi_48_driver = { + .driver = { + .name = "104-idi-48" + }, + .remove = idi_48_remove +}; + +static void __exit idi_48_exit(void) +{ + platform_device_unregister(idi_48_device); + platform_driver_unregister(&idi_48_driver); +} + +static int __init idi_48_init(void) +{ + int err; + + idi_48_device = platform_device_alloc(idi_48_driver.driver.name, -1); + if (!idi_48_device) + return -ENOMEM; + + err = platform_device_add(idi_48_device); + if (err) + goto err_platform_device; + + err = platform_driver_probe(&idi_48_driver, idi_48_probe); + if (err) + goto err_platform_driver; + + return 0; + +err_platform_driver: + platform_device_del(idi_48_device); +err_platform_device: + platform_device_put(idi_48_device); + return err; +} + +module_init(idi_48_init); +module_exit(idi_48_exit); + +MODULE_AUTHOR("William Breathitt Gray <vilhelm.gray@gmail.com>"); +MODULE_DESCRIPTION("ACCES 104-IDI-48 GPIO driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/gpio/gpio-104-idio-16.c b/drivers/gpio/gpio-104-idio-16.c index 5400d7d4d8fd..91c8b5b17f64 100644 --- a/drivers/gpio/gpio-104-idio-16.c +++ b/drivers/gpio/gpio-104-idio-16.c @@ -11,11 +11,14 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. */ +#include <linux/bitops.h> #include <linux/device.h> #include <linux/errno.h> #include <linux/gpio/driver.h> #include <linux/io.h> #include <linux/ioport.h> +#include <linux/interrupt.h> +#include <linux/irqdesc.h> #include <linux/kernel.h> #include <linux/module.h> #include <linux/moduleparam.h> @@ -25,20 +28,27 @@ static unsigned idio_16_base; module_param(idio_16_base, uint, 0); MODULE_PARM_DESC(idio_16_base, "ACCES 104-IDIO-16 base address"); +static unsigned idio_16_irq; +module_param(idio_16_irq, uint, 0); +MODULE_PARM_DESC(idio_16_irq, "ACCES 104-IDIO-16 interrupt line number"); /** * struct idio_16_gpio - GPIO device private data structure * @chip: instance of the gpio_chip - * @lock: synchronization lock to prevent gpio_set race conditions + * @lock: synchronization lock to prevent I/O race conditions + * @irq_mask: I/O bits affected by interrupts * @base: base port address of the GPIO device * @extent: extent of port address region of the GPIO device + * @irq: Interrupt line number * @out_state: output bits state */ struct idio_16_gpio { struct gpio_chip chip; spinlock_t lock; + unsigned long irq_mask; unsigned base; unsigned extent; + unsigned irq; unsigned out_state; }; @@ -70,21 +80,21 @@ static struct idio_16_gpio *to_idio16gpio(struct gpio_chip *gc) static int idio_16_gpio_get(struct gpio_chip *chip, unsigned offset) { struct idio_16_gpio *const idio16gpio = to_idio16gpio(chip); - const unsigned BIT_MASK = 1U << (offset-16); + const unsigned mask = BIT(offset-16); if (offset < 16) return -EINVAL; if (offset < 24) - return !!(inb(idio16gpio->base + 1) & BIT_MASK); + return !!(inb(idio16gpio->base + 1) & mask); - return !!(inb(idio16gpio->base + 5) & (BIT_MASK>>8)); + return !!(inb(idio16gpio->base + 5) & (mask>>8)); } static void idio_16_gpio_set(struct gpio_chip *chip, unsigned offset, int value) { struct idio_16_gpio *const idio16gpio = to_idio16gpio(chip); - const unsigned BIT_MASK = 1U << offset; + const unsigned mask = BIT(offset); unsigned long flags; if (offset > 15) @@ -93,9 +103,9 @@ static void idio_16_gpio_set(struct gpio_chip *chip, unsigned offset, int value) spin_lock_irqsave(&idio16gpio->lock, flags); if (value) - idio16gpio->out_state |= BIT_MASK; + idio16gpio->out_state |= mask; else - idio16gpio->out_state &= ~BIT_MASK; + idio16gpio->out_state &= ~mask; if (offset > 7) outb(idio16gpio->out_state >> 8, idio16gpio->base + 4); @@ -105,29 +115,106 @@ static void idio_16_gpio_set(struct gpio_chip *chip, unsigned offset, int value) spin_unlock_irqrestore(&idio16gpio->lock, flags); } +static void idio_16_irq_ack(struct irq_data *data) +{ +} + +static void idio_16_irq_mask(struct irq_data *data) +{ + struct gpio_chip *chip = irq_data_get_irq_chip_data(data); + struct idio_16_gpio *const idio16gpio = to_idio16gpio(chip); + const unsigned long mask = BIT(irqd_to_hwirq(data)); + unsigned long flags; + + idio16gpio->irq_mask &= ~mask; + + if (!idio16gpio->irq_mask) { + spin_lock_irqsave(&idio16gpio->lock, flags); + + outb(0, idio16gpio->base + 2); + + spin_unlock_irqrestore(&idio16gpio->lock, flags); + } +} + +static void idio_16_irq_unmask(struct irq_data *data) +{ + struct gpio_chip *chip = irq_data_get_irq_chip_data(data); + struct idio_16_gpio *const idio16gpio = to_idio16gpio(chip); + const unsigned long mask = BIT(irqd_to_hwirq(data)); + const unsigned long prev_irq_mask = idio16gpio->irq_mask; + unsigned long flags; + + idio16gpio->irq_mask |= mask; + + if (!prev_irq_mask) { + spin_lock_irqsave(&idio16gpio->lock, flags); + + inb(idio16gpio->base + 2); + + spin_unlock_irqrestore(&idio16gpio->lock, flags); + } +} + +static int idio_16_irq_set_type(struct irq_data *data, unsigned flow_type) +{ + /* The only valid irq types are none and both-edges */ + if (flow_type != IRQ_TYPE_NONE && + (flow_type & IRQ_TYPE_EDGE_BOTH) != IRQ_TYPE_EDGE_BOTH) + return -EINVAL; + + return 0; +} + +static struct irq_chip idio_16_irqchip = { + .name = "104-idio-16", + .irq_ack = idio_16_irq_ack, + .irq_mask = idio_16_irq_mask, + .irq_unmask = idio_16_irq_unmask, + .irq_set_type = idio_16_irq_set_type +}; + +static irqreturn_t idio_16_irq_handler(int irq, void *dev_id) +{ + struct idio_16_gpio *const idio16gpio = dev_id; + struct gpio_chip *const chip = &idio16gpio->chip; + int gpio; + + for_each_set_bit(gpio, &idio16gpio->irq_mask, chip->ngpio) + generic_handle_irq(irq_find_mapping(chip->irqdomain, gpio)); + + spin_lock(&idio16gpio->lock); + + outb(0, idio16gpio->base + 1); + + spin_unlock(&idio16gpio->lock); + + return IRQ_HANDLED; +} + static int __init idio_16_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct idio_16_gpio *idio16gpio; + const unsigned base = idio_16_base; + const unsigned extent = 8; + const char *const name = dev_name(dev); int err; - - const unsigned BASE = idio_16_base; - const unsigned EXTENT = 8; - const char *const NAME = dev_name(dev); + const unsigned irq = idio_16_irq; idio16gpio = devm_kzalloc(dev, sizeof(*idio16gpio), GFP_KERNEL); if (!idio16gpio) return -ENOMEM; - if (!request_region(BASE, EXTENT, NAME)) { + if (!request_region(base, extent, name)) { dev_err(dev, "Unable to lock %s port addresses (0x%X-0x%X)\n", - NAME, BASE, BASE + EXTENT); + name, base, base + extent); err = -EBUSY; goto err_lock_io_port; } - idio16gpio->chip.label = NAME; - idio16gpio->chip.dev = dev; + idio16gpio->chip.label = name; + idio16gpio->chip.parent = dev; idio16gpio->chip.owner = THIS_MODULE; idio16gpio->chip.base = -1; idio16gpio->chip.ngpio = 32; @@ -136,8 +223,9 @@ static int __init idio_16_probe(struct platform_device *pdev) idio16gpio->chip.direction_output = idio_16_gpio_direction_output; idio16gpio->chip.get = idio_16_gpio_get; idio16gpio->chip.set = idio_16_gpio_set; - idio16gpio->base = BASE; - idio16gpio->extent = EXTENT; + idio16gpio->base = base; + idio16gpio->extent = extent; + idio16gpio->irq = irq; idio16gpio->out_state = 0xFFFF; spin_lock_init(&idio16gpio->lock); @@ -150,10 +238,30 @@ static int __init idio_16_probe(struct platform_device *pdev) goto err_gpio_register; } + /* Disable IRQ by default */ + outb(0, base + 2); + outb(0, base + 1); + + err = gpiochip_irqchip_add(&idio16gpio->chip, &idio_16_irqchip, 0, + handle_edge_irq, IRQ_TYPE_NONE); + if (err) { + dev_err(dev, "Could not add irqchip (%d)\n", err); + goto err_gpiochip_irqchip_add; + } + + err = request_irq(irq, idio_16_irq_handler, 0, name, idio16gpio); + if (err) { + dev_err(dev, "IRQ handler registering failed (%d)\n", err); + goto err_request_irq; + } + return 0; +err_request_irq: +err_gpiochip_irqchip_add: + gpiochip_remove(&idio16gpio->chip); err_gpio_register: - release_region(BASE, EXTENT); + release_region(base, extent); err_lock_io_port: return err; } @@ -162,6 +270,7 @@ static int idio_16_remove(struct platform_device *pdev) { struct idio_16_gpio *const idio16gpio = platform_get_drvdata(pdev); + free_irq(idio16gpio->irq, idio16gpio); gpiochip_remove(&idio16gpio->chip); release_region(idio16gpio->base, idio16gpio->extent); diff --git a/drivers/gpio/gpio-74x164.c b/drivers/gpio/gpio-74x164.c index 60172f835d15..54a4147fba52 100644 --- a/drivers/gpio/gpio-74x164.c +++ b/drivers/gpio/gpio-74x164.c @@ -20,10 +20,17 @@ #define GEN_74X164_NUMBER_GPIOS 8 struct gen_74x164_chip { - u8 *buffer; struct gpio_chip gpio_chip; struct mutex lock; u32 registers; + /* + * Since the registers are chained, every byte sent will make + * the previous byte shift to the next register in the + * chain. Thus, the first byte sent will end up in the last + * register at the end of the transfer. So, to have a logical + * numbering, store the bytes in reverse order. + */ + u8 buffer[0]; }; static struct gen_74x164_chip *gpio_to_74x164_chip(struct gpio_chip *gc) @@ -33,43 +40,19 @@ static struct gen_74x164_chip *gpio_to_74x164_chip(struct gpio_chip *gc) static int __gen_74x164_write_config(struct gen_74x164_chip *chip) { - struct spi_device *spi = to_spi_device(chip->gpio_chip.dev); - struct spi_message message; - struct spi_transfer *msg_buf; - int i, ret = 0; - - msg_buf = kzalloc(chip->registers * sizeof(struct spi_transfer), - GFP_KERNEL); - if (!msg_buf) - return -ENOMEM; - - spi_message_init(&message); - - /* - * Since the registers are chained, every byte sent will make - * the previous byte shift to the next register in the - * chain. Thus, the first byte send will end up in the last - * register at the end of the transfer. So, to have a logical - * numbering, send the bytes in reverse order so that the last - * byte of the buffer will end up in the last register. - */ - for (i = chip->registers - 1; i >= 0; i--) { - msg_buf[i].tx_buf = chip->buffer + i; - msg_buf[i].len = sizeof(u8); - spi_message_add_tail(msg_buf + i, &message); - } - - ret = spi_sync(spi, &message); + struct spi_transfer xfer = { + .tx_buf = chip->buffer, + .len = chip->registers, + }; - kfree(msg_buf); - - return ret; + return spi_sync_transfer(to_spi_device(chip->gpio_chip.parent), + &xfer, 1); } static int gen_74x164_get_value(struct gpio_chip *gc, unsigned offset) { struct gen_74x164_chip *chip = gpio_to_74x164_chip(gc); - u8 bank = offset / 8; + u8 bank = chip->registers - 1 - offset / 8; u8 pin = offset % 8; int ret; @@ -84,7 +67,7 @@ static void gen_74x164_set_value(struct gpio_chip *gc, unsigned offset, int val) { struct gen_74x164_chip *chip = gpio_to_74x164_chip(gc); - u8 bank = offset / 8; + u8 bank = chip->registers - 1 - offset / 8; u8 pin = offset % 8; mutex_lock(&chip->lock); @@ -107,6 +90,7 @@ static int gen_74x164_direction_output(struct gpio_chip *gc, static int gen_74x164_probe(struct spi_device *spi) { struct gen_74x164_chip *chip; + u32 nregs; int ret; /* @@ -118,7 +102,14 @@ static int gen_74x164_probe(struct spi_device *spi) if (ret < 0) return ret; - chip = devm_kzalloc(&spi->dev, sizeof(*chip), GFP_KERNEL); + if (of_property_read_u32(spi->dev.of_node, "registers-number", + &nregs)) { + dev_err(&spi->dev, + "Missing registers-number property in the DT.\n"); + return -EINVAL; + } + + chip = devm_kzalloc(&spi->dev, sizeof(*chip) + nregs, GFP_KERNEL); if (!chip) return -ENOMEM; @@ -130,20 +121,11 @@ static int gen_74x164_probe(struct spi_device *spi) chip->gpio_chip.set = gen_74x164_set_value; chip->gpio_chip.base = -1; - if (of_property_read_u32(spi->dev.of_node, "registers-number", - &chip->registers)) { - dev_err(&spi->dev, - "Missing registers-number property in the DT.\n"); - return -EINVAL; - } - + chip->registers = nregs; chip->gpio_chip.ngpio = GEN_74X164_NUMBER_GPIOS * chip->registers; - chip->buffer = devm_kzalloc(&spi->dev, chip->registers, GFP_KERNEL); - if (!chip->buffer) - return -ENOMEM; chip->gpio_chip.can_sleep = true; - chip->gpio_chip.dev = &spi->dev; + chip->gpio_chip.parent = &spi->dev; chip->gpio_chip.owner = THIS_MODULE; mutex_init(&chip->lock); diff --git a/drivers/gpio/gpio-adnp.c b/drivers/gpio/gpio-adnp.c index d3d0a90fe542..b8a1ac133390 100644 --- a/drivers/gpio/gpio-adnp.c +++ b/drivers/gpio/gpio-adnp.c @@ -47,7 +47,7 @@ static int adnp_read(struct adnp *adnp, unsigned offset, uint8_t *value) err = i2c_smbus_read_byte_data(adnp->client, offset); if (err < 0) { - dev_err(adnp->gpio.dev, "%s failed: %d\n", + dev_err(adnp->gpio.parent, "%s failed: %d\n", "i2c_smbus_read_byte_data()", err); return err; } @@ -62,7 +62,7 @@ static int adnp_write(struct adnp *adnp, unsigned offset, uint8_t value) err = i2c_smbus_write_byte_data(adnp->client, offset, value); if (err < 0) { - dev_err(adnp->gpio.dev, "%s failed: %d\n", + dev_err(adnp->gpio.parent, "%s failed: %d\n", "i2c_smbus_write_byte_data()", err); return err; } @@ -266,8 +266,8 @@ static int adnp_gpio_setup(struct adnp *adnp, unsigned int num_gpios) chip->base = -1; chip->ngpio = num_gpios; chip->label = adnp->client->name; - chip->dev = &adnp->client->dev; - chip->of_node = chip->dev->of_node; + chip->parent = &adnp->client->dev; + chip->of_node = chip->parent->of_node; chip->owner = THIS_MODULE; err = gpiochip_add(chip); @@ -435,7 +435,8 @@ static int adnp_irq_setup(struct adnp *adnp) * is chosen to match the register layout of the hardware in that * each segment contains the corresponding bits for all interrupts. */ - adnp->irq_enable = devm_kzalloc(chip->dev, num_regs * 6, GFP_KERNEL); + adnp->irq_enable = devm_kzalloc(chip->parent, num_regs * 6, + GFP_KERNEL); if (!adnp->irq_enable) return -ENOMEM; @@ -462,12 +463,12 @@ static int adnp_irq_setup(struct adnp *adnp) adnp->irq_enable[i] = 0x00; } - err = devm_request_threaded_irq(chip->dev, adnp->client->irq, + err = devm_request_threaded_irq(chip->parent, adnp->client->irq, NULL, adnp_irq, IRQF_TRIGGER_RISING | IRQF_ONESHOT, - dev_name(chip->dev), adnp); + dev_name(chip->parent), adnp); if (err != 0) { - dev_err(chip->dev, "can't request IRQ#%d: %d\n", + dev_err(chip->parent, "can't request IRQ#%d: %d\n", adnp->client->irq, err); return err; } @@ -478,7 +479,7 @@ static int adnp_irq_setup(struct adnp *adnp) handle_simple_irq, IRQ_TYPE_NONE); if (err) { - dev_err(chip->dev, + dev_err(chip->parent, "could not connect irqchip to gpiochip\n"); return err; } @@ -547,7 +548,6 @@ MODULE_DEVICE_TABLE(of, adnp_of_match); static struct i2c_driver adnp_i2c_driver = { .driver = { .name = "gpio-adnp", - .owner = THIS_MODULE, .of_match_table = adnp_of_match, }, .probe = adnp_i2c_probe, diff --git a/drivers/gpio/gpio-altera.c b/drivers/gpio/gpio-altera.c index 3e6661bab54a..84a20af01a9a 100644 --- a/drivers/gpio/gpio-altera.c +++ b/drivers/gpio/gpio-altera.c @@ -290,7 +290,7 @@ static int altera_gpio_probe(struct platform_device *pdev) altera_gc->mmchip.gc.get = altera_gpio_get; altera_gc->mmchip.gc.set = altera_gpio_set; altera_gc->mmchip.gc.owner = THIS_MODULE; - altera_gc->mmchip.gc.dev = &pdev->dev; + altera_gc->mmchip.gc.parent = &pdev->dev; ret = of_mm_gpiochip_add(node, &altera_gc->mmchip); if (ret) { diff --git a/drivers/gpio/gpio-amd8111.c b/drivers/gpio/gpio-amd8111.c index d00d81928fe8..5c378e9f53a0 100644 --- a/drivers/gpio/gpio-amd8111.c +++ b/drivers/gpio/gpio-amd8111.c @@ -220,7 +220,7 @@ found: goto out; } gp.pdev = pdev; - gp.chip.dev = &pdev->dev; + gp.chip.parent = &pdev->dev; spin_lock_init(&gp.lock); diff --git a/drivers/gpio/gpio-amdpt.c b/drivers/gpio/gpio-amdpt.c index cbbb966d4fc0..f842ccc45e64 100644 --- a/drivers/gpio/gpio-amdpt.c +++ b/drivers/gpio/gpio-amdpt.c @@ -39,14 +39,14 @@ static int pt_gpio_request(struct gpio_chip *gc, unsigned offset) unsigned long flags; u32 using_pins; - dev_dbg(gc->dev, "pt_gpio_request offset=%x\n", offset); + dev_dbg(gc->parent, "pt_gpio_request offset=%x\n", offset); spin_lock_irqsave(&pt_gpio->lock, flags); using_pins = readl(pt_gpio->reg_base + PT_SYNC_REG); if (using_pins & BIT(offset)) { - dev_warn(gc->dev, "PT GPIO pin %x reconfigured\n", - offset); + dev_warn(gc->parent, "PT GPIO pin %x reconfigured\n", + offset); spin_unlock_irqrestore(&pt_gpio->lock, flags); return -EINVAL; } @@ -72,7 +72,7 @@ static void pt_gpio_free(struct gpio_chip *gc, unsigned offset) spin_unlock_irqrestore(&pt_gpio->lock, flags); - dev_dbg(gc->dev, "pt_gpio_free offset=%x\n", offset); + dev_dbg(gc->parent, "pt_gpio_free offset=%x\n", offset); } static void pt_gpio_set_value(struct gpio_chip *gc, unsigned offset, int value) @@ -81,7 +81,7 @@ static void pt_gpio_set_value(struct gpio_chip *gc, unsigned offset, int value) unsigned long flags; u32 data; - dev_dbg(gc->dev, "pt_gpio_set_value offset=%x, value=%x\n", + dev_dbg(gc->parent, "pt_gpio_set_value offset=%x, value=%x\n", offset, value); spin_lock_irqsave(&pt_gpio->lock, flags); @@ -116,7 +116,7 @@ static int pt_gpio_get_value(struct gpio_chip *gc, unsigned offset) data >>= offset; data &= 1; - dev_dbg(gc->dev, "pt_gpio_get_value offset=%x, value=%x\n", + dev_dbg(gc->parent, "pt_gpio_get_value offset=%x, value=%x\n", offset, data); return data; @@ -128,7 +128,7 @@ static int pt_gpio_direction_input(struct gpio_chip *gc, unsigned offset) unsigned long flags; u32 data; - dev_dbg(gc->dev, "pt_gpio_dirction_input offset=%x\n", offset); + dev_dbg(gc->parent, "pt_gpio_dirction_input offset=%x\n", offset); spin_lock_irqsave(&pt_gpio->lock, flags); @@ -148,7 +148,7 @@ static int pt_gpio_direction_output(struct gpio_chip *gc, unsigned long flags; u32 data; - dev_dbg(gc->dev, "pt_gpio_direction_output offset=%x, value=%x\n", + dev_dbg(gc->parent, "pt_gpio_direction_output offset=%x, value=%x\n", offset, value); spin_lock_irqsave(&pt_gpio->lock, flags); @@ -202,7 +202,7 @@ static int pt_gpio_probe(struct platform_device *pdev) pt_gpio->gc.label = pdev->name; pt_gpio->gc.owner = THIS_MODULE; - pt_gpio->gc.dev = dev; + pt_gpio->gc.parent = dev; pt_gpio->gc.request = pt_gpio_request; pt_gpio->gc.free = pt_gpio_free; pt_gpio->gc.direction_input = pt_gpio_direction_input; diff --git a/drivers/gpio/gpio-arizona.c b/drivers/gpio/gpio-arizona.c index ca002739616a..412d131b513d 100644 --- a/drivers/gpio/gpio-arizona.c +++ b/drivers/gpio/gpio-arizona.c @@ -108,7 +108,7 @@ static int arizona_gpio_probe(struct platform_device *pdev) arizona_gpio->arizona = arizona; arizona_gpio->gpio_chip = template_chip; - arizona_gpio->gpio_chip.dev = &pdev->dev; + arizona_gpio->gpio_chip.parent = &pdev->dev; #ifdef CONFIG_OF_GPIO arizona_gpio->gpio_chip.of_node = arizona->dev->of_node; #endif diff --git a/drivers/gpio/gpio-ath79.c b/drivers/gpio/gpio-ath79.c index 5eaea8b812cf..6e678121ab12 100644 --- a/drivers/gpio/gpio-ath79.c +++ b/drivers/gpio/gpio-ath79.c @@ -138,7 +138,7 @@ static const struct of_device_id ath79_gpio_of_match[] = { static int ath79_gpio_probe(struct platform_device *pdev) { - struct ath79_gpio_platform_data *pdata = pdev->dev.platform_data; + struct ath79_gpio_platform_data *pdata = dev_get_platdata(&pdev->dev); struct device_node *np = pdev->dev.of_node; struct ath79_gpio_ctrl *ctrl; struct resource *res; @@ -177,7 +177,7 @@ static int ath79_gpio_probe(struct platform_device *pdev) spin_lock_init(&ctrl->lock); memcpy(&ctrl->chip, &ath79_gpio_chip, sizeof(ctrl->chip)); - ctrl->chip.dev = &pdev->dev; + ctrl->chip.parent = &pdev->dev; ctrl->chip.ngpio = ath79_gpio_count; if (oe_inverted) { ctrl->chip.direction_input = ar934x_gpio_direction_input; diff --git a/drivers/gpio/gpio-bcm-kona.c b/drivers/gpio/gpio-bcm-kona.c index 33a1f9779b86..21c3280d66e1 100644 --- a/drivers/gpio/gpio-bcm-kona.c +++ b/drivers/gpio/gpio-bcm-kona.c @@ -273,7 +273,7 @@ static int bcm_kona_gpio_set_debounce(struct gpio_chip *chip, unsigned gpio, reg_base = kona_gpio->reg_base; /* debounce must be 1-128ms (or 0) */ if ((debounce > 0 && debounce < 1000) || debounce > 128000) { - dev_err(chip->dev, "Debounce value %u not in range\n", + dev_err(chip->parent, "Debounce value %u not in range\n", debounce); return -EINVAL; } @@ -416,7 +416,7 @@ static int bcm_kona_gpio_irq_set_type(struct irq_data *d, unsigned int type) case IRQ_TYPE_LEVEL_LOW: /* BCM GPIO doesn't support level triggering */ default: - dev_err(kona_gpio->gpio_chip.dev, + dev_err(kona_gpio->gpio_chip.parent, "Invalid BCM GPIO irq type 0x%x\n", type); return -EINVAL; } @@ -477,7 +477,7 @@ static int bcm_kona_gpio_irq_reqres(struct irq_data *d) struct bcm_kona_gpio *kona_gpio = irq_data_get_irq_chip_data(d); if (gpiochip_lock_as_irq(&kona_gpio->gpio_chip, d->hwirq)) { - dev_err(kona_gpio->gpio_chip.dev, + dev_err(kona_gpio->gpio_chip.parent, "unable to lock HW IRQ %lu for IRQ\n", d->hwirq); return -EINVAL; diff --git a/drivers/gpio/gpio-crystalcove.c b/drivers/gpio/gpio-crystalcove.c index fddd204dc9b6..141093a8cd3f 100644 --- a/drivers/gpio/gpio-crystalcove.c +++ b/drivers/gpio/gpio-crystalcove.c @@ -341,7 +341,7 @@ static int crystalcove_gpio_probe(struct platform_device *pdev) cg->chip.base = -1; cg->chip.ngpio = CRYSTALCOVE_VGPIO_NUM; cg->chip.can_sleep = true; - cg->chip.dev = dev; + cg->chip.parent = dev; cg->chip.dbg_show = crystalcove_gpio_dbg_show; cg->regmap = pmic->regmap; diff --git a/drivers/gpio/gpio-davinci.c b/drivers/gpio/gpio-davinci.c index 5e715388803d..65ebaef935e1 100644 --- a/drivers/gpio/gpio-davinci.c +++ b/drivers/gpio/gpio-davinci.c @@ -149,7 +149,7 @@ davinci_gpio_get_pdata(struct platform_device *pdev) u32 val; if (!IS_ENABLED(CONFIG_OF) || !pdev->dev.of_node) - return pdev->dev.platform_data; + return dev_get_platdata(&pdev->dev); pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); if (!pdata) @@ -179,8 +179,8 @@ static int davinci_gpio_of_xlate(struct gpio_chip *gc, const struct of_phandle_args *gpiospec, u32 *flags) { - struct davinci_gpio_controller *chips = dev_get_drvdata(gc->dev); - struct davinci_gpio_platform_data *pdata = dev_get_platdata(gc->dev); + struct davinci_gpio_controller *chips = dev_get_drvdata(gc->parent); + struct davinci_gpio_platform_data *pdata = dev_get_platdata(gc->parent); if (gpiospec->args[0] > pdata->ngpio) return -EINVAL; @@ -254,7 +254,7 @@ static int davinci_gpio_probe(struct platform_device *pdev) #ifdef CONFIG_OF_GPIO chips[i].chip.of_gpio_n_cells = 2; chips[i].chip.of_xlate = davinci_gpio_of_xlate; - chips[i].chip.dev = dev; + chips[i].chip.parent = dev; chips[i].chip.of_node = dev->of_node; #endif spin_lock_init(&chips[i].lock); diff --git a/drivers/gpio/gpio-dln2.c b/drivers/gpio/gpio-dln2.c index 6685712c15cf..e541af03dd45 100644 --- a/drivers/gpio/gpio-dln2.c +++ b/drivers/gpio/gpio-dln2.c @@ -377,7 +377,7 @@ static void dln2_irq_bus_unlock(struct irq_data *irqd) ret = dln2_gpio_set_event_cfg(dln2, pin, type, 0); if (ret) - dev_err(dln2->gpio.dev, "failed to set event\n"); + dev_err(dln2->gpio.parent, "failed to set event\n"); } mutex_unlock(&dln2->irq_lock); @@ -406,19 +406,19 @@ static void dln2_gpio_event(struct platform_device *pdev, u16 echo, struct dln2_gpio *dln2 = platform_get_drvdata(pdev); if (len < sizeof(*event)) { - dev_err(dln2->gpio.dev, "short event message\n"); + dev_err(dln2->gpio.parent, "short event message\n"); return; } pin = le16_to_cpu(event->pin); if (pin >= dln2->gpio.ngpio) { - dev_err(dln2->gpio.dev, "out of bounds pin %d\n", pin); + dev_err(dln2->gpio.parent, "out of bounds pin %d\n", pin); return; } irq = irq_find_mapping(dln2->gpio.irqdomain, pin); if (!irq) { - dev_err(dln2->gpio.dev, "pin %d not mapped to IRQ\n", pin); + dev_err(dln2->gpio.parent, "pin %d not mapped to IRQ\n", pin); return; } @@ -462,7 +462,7 @@ static int dln2_gpio_probe(struct platform_device *pdev) dln2->pdev = pdev; dln2->gpio.label = "dln2"; - dln2->gpio.dev = dev; + dln2->gpio.parent = dev; dln2->gpio.owner = THIS_MODULE; dln2->gpio.base = -1; dln2->gpio.ngpio = pins; diff --git a/drivers/gpio/gpio-em.c b/drivers/gpio/gpio-em.c index 6bca1e125e12..c3ca2b1c1dfe 100644 --- a/drivers/gpio/gpio-em.c +++ b/drivers/gpio/gpio-em.c @@ -103,7 +103,7 @@ static int em_gio_irq_reqres(struct irq_data *d) struct em_gio_priv *p = irq_data_get_irq_chip_data(d); if (gpiochip_lock_as_irq(&p->gpio_chip, irqd_to_hwirq(d))) { - dev_err(p->gpio_chip.dev, + dev_err(p->gpio_chip.parent, "unable to lock HW IRQ %lu for IRQ\n", irqd_to_hwirq(d)); return -EINVAL; @@ -332,7 +332,7 @@ static int em_gio_probe(struct platform_device *pdev) gpio_chip->request = em_gio_request; gpio_chip->free = em_gio_free; gpio_chip->label = name; - gpio_chip->dev = &pdev->dev; + gpio_chip->parent = &pdev->dev; gpio_chip->owner = THIS_MODULE; gpio_chip->base = -1; gpio_chip->ngpio = ngpios; diff --git a/drivers/gpio/gpio-f7188x.c b/drivers/gpio/gpio-f7188x.c index 5e3c4fa67d82..2be7337cf4ae 100644 --- a/drivers/gpio/gpio-f7188x.c +++ b/drivers/gpio/gpio-f7188x.c @@ -298,7 +298,7 @@ static int f7188x_gpio_probe(struct platform_device *pdev) { int err; int i; - struct f7188x_sio *sio = pdev->dev.platform_data; + struct f7188x_sio *sio = dev_get_platdata(&pdev->dev); struct f7188x_gpio_data *data; data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL); @@ -333,7 +333,7 @@ static int f7188x_gpio_probe(struct platform_device *pdev) for (i = 0; i < data->nr_bank; i++) { struct f7188x_gpio_bank *bank = &data->bank[i]; - bank->chip.dev = &pdev->dev; + bank->chip.parent = &pdev->dev; bank->data = data; err = gpiochip_add(&bank->chip); diff --git a/drivers/gpio/gpio-generic.c b/drivers/gpio/gpio-generic.c index 88ae70ddb127..ea581dc23d44 100644 --- a/drivers/gpio/gpio-generic.c +++ b/drivers/gpio/gpio-generic.c @@ -545,7 +545,7 @@ int bgpio_init(struct bgpio_chip *bgc, struct device *dev, return -EINVAL; spin_lock_init(&bgc->lock); - bgc->gc.dev = dev; + bgc->gc.parent = dev; bgc->gc.label = dev_name(dev); bgc->gc.base = -1; bgc->gc.ngpio = bgc->bits; diff --git a/drivers/gpio/gpio-ich.c b/drivers/gpio/gpio-ich.c index 4ba7ed502131..8623d12e23c1 100644 --- a/drivers/gpio/gpio-ich.c +++ b/drivers/gpio/gpio-ich.c @@ -282,7 +282,7 @@ static void ichx_gpiolib_setup(struct gpio_chip *chip) { chip->owner = THIS_MODULE; chip->label = DRV_NAME; - chip->dev = &ichx_priv.dev->dev; + chip->parent = &ichx_priv.dev->dev; /* Allow chip-specific overrides of request()/get() */ chip->request = ichx_priv.desc->request ? diff --git a/drivers/gpio/gpio-intel-mid.c b/drivers/gpio/gpio-intel-mid.c index 70097472b02c..1c46a7ef2680 100644 --- a/drivers/gpio/gpio-intel-mid.c +++ b/drivers/gpio/gpio-intel-mid.c @@ -392,7 +392,7 @@ static int intel_gpio_probe(struct pci_dev *pdev, priv->reg_base = pcim_iomap_table(pdev)[0]; priv->chip.label = dev_name(&pdev->dev); - priv->chip.dev = &pdev->dev; + priv->chip.parent = &pdev->dev; priv->chip.request = intel_gpio_request; priv->chip.direction_input = intel_gpio_direction_input; priv->chip.direction_output = intel_gpio_direction_output; diff --git a/drivers/gpio/gpio-janz-ttl.c b/drivers/gpio/gpio-janz-ttl.c index 3a1664335f5e..e5f85cab0100 100644 --- a/drivers/gpio/gpio-janz-ttl.c +++ b/drivers/gpio/gpio-janz-ttl.c @@ -59,7 +59,7 @@ struct ttl_module { static int ttl_get_value(struct gpio_chip *gpio, unsigned offset) { - struct ttl_module *mod = dev_get_drvdata(gpio->dev); + struct ttl_module *mod = dev_get_drvdata(gpio->parent); u8 *shadow; int ret; @@ -81,7 +81,7 @@ static int ttl_get_value(struct gpio_chip *gpio, unsigned offset) static void ttl_set_value(struct gpio_chip *gpio, unsigned offset, int value) { - struct ttl_module *mod = dev_get_drvdata(gpio->dev); + struct ttl_module *mod = dev_get_drvdata(gpio->parent); void __iomem *port; u8 *shadow; @@ -172,7 +172,7 @@ static int ttl_probe(struct platform_device *pdev) /* Initialize the GPIO data structures */ gpio = &mod->gpio; - gpio->dev = &pdev->dev; + gpio->parent = &pdev->dev; gpio->label = pdev->name; gpio->get = ttl_get_value; gpio->set = ttl_set_value; diff --git a/drivers/gpio/gpio-kempld.c b/drivers/gpio/gpio-kempld.c index 83f281dda1e0..35dd1e0af364 100644 --- a/drivers/gpio/gpio-kempld.c +++ b/drivers/gpio/gpio-kempld.c @@ -166,7 +166,7 @@ static int kempld_gpio_probe(struct platform_device *pdev) chip = &gpio->chip; chip->label = "gpio-kempld"; chip->owner = THIS_MODULE; - chip->dev = dev; + chip->parent = dev; chip->can_sleep = true; if (pdata && pdata->gpio_base) chip->base = pdata->gpio_base; diff --git a/drivers/gpio/gpio-lp3943.c b/drivers/gpio/gpio-lp3943.c index cfc5b12b43ad..f979c3be217f 100644 --- a/drivers/gpio/gpio-lp3943.c +++ b/drivers/gpio/gpio-lp3943.c @@ -205,7 +205,7 @@ static int lp3943_gpio_probe(struct platform_device *pdev) lp3943_gpio->lp3943 = lp3943; lp3943_gpio->chip = lp3943_gpio_chip; - lp3943_gpio->chip.dev = &pdev->dev; + lp3943_gpio->chip.parent = &pdev->dev; platform_set_drvdata(pdev, lp3943_gpio); diff --git a/drivers/gpio/gpio-lpc18xx.c b/drivers/gpio/gpio-lpc18xx.c index e39dcb0af8ae..b01fbc9db7cd 100644 --- a/drivers/gpio/gpio-lpc18xx.c +++ b/drivers/gpio/gpio-lpc18xx.c @@ -127,7 +127,7 @@ static int lpc18xx_gpio_probe(struct platform_device *pdev) spin_lock_init(&gc->lock); - gc->gpio.dev = &pdev->dev; + gc->gpio.parent = &pdev->dev; ret = gpiochip_add(&gc->gpio); if (ret) { diff --git a/drivers/gpio/gpio-lynxpoint.c b/drivers/gpio/gpio-lynxpoint.c index 127c37b380ae..6a48ffd6e0db 100644 --- a/drivers/gpio/gpio-lynxpoint.c +++ b/drivers/gpio/gpio-lynxpoint.c @@ -368,7 +368,7 @@ static int lp_gpio_probe(struct platform_device *pdev) gc->base = -1; gc->ngpio = LP_NUM_GPIO; gc->can_sleep = false; - gc->dev = dev; + gc->parent = dev; ret = gpiochip_add(gc); if (ret) { diff --git a/drivers/gpio/gpio-max7300.c b/drivers/gpio/gpio-max7300.c index 0cc2c279ab5c..1ae9ba851c9a 100644 --- a/drivers/gpio/gpio-max7300.c +++ b/drivers/gpio/gpio-max7300.c @@ -65,7 +65,6 @@ MODULE_DEVICE_TABLE(i2c, max7300_id); static struct i2c_driver max7300_driver = { .driver = { .name = "max7300", - .owner = THIS_MODULE, }, .probe = max7300_probe, .remove = max7300_remove, diff --git a/drivers/gpio/gpio-max730x.c b/drivers/gpio/gpio-max730x.c index 0f57d2d248ec..5d6a723cb414 100644 --- a/drivers/gpio/gpio-max730x.c +++ b/drivers/gpio/gpio-max730x.c @@ -189,7 +189,7 @@ int __max730x_probe(struct max7301 *ts) ts->chip.ngpio = PIN_NUMBER; ts->chip.can_sleep = true; - ts->chip.dev = dev; + ts->chip.parent = dev; ts->chip.owner = THIS_MODULE; /* diff --git a/drivers/gpio/gpio-max732x.c b/drivers/gpio/gpio-max732x.c index 8c5252c6c327..a1094984b666 100644 --- a/drivers/gpio/gpio-max732x.c +++ b/drivers/gpio/gpio-max732x.c @@ -603,7 +603,7 @@ static int max732x_setup_gpio(struct max732x_chip *chip, gc->base = gpio_start; gc->ngpio = port; gc->label = chip->client->name; - gc->dev = &chip->client->dev; + gc->parent = &chip->client->dev; gc->owner = THIS_MODULE; return port; @@ -649,7 +649,7 @@ static int max732x_probe(struct i2c_client *client, chip->client = client; nr_port = max732x_setup_gpio(chip, id, pdata->gpio_base); - chip->gpio_chip.dev = &client->dev; + chip->gpio_chip.parent = &client->dev; addr_a = (client->addr & 0x0f) | 0x60; addr_b = (client->addr & 0x0f) | 0x50; @@ -749,7 +749,6 @@ static int max732x_remove(struct i2c_client *client) static struct i2c_driver max732x_driver = { .driver = { .name = "max732x", - .owner = THIS_MODULE, .of_match_table = of_match_ptr(max732x_of_table), }, .probe = max732x_probe, diff --git a/drivers/gpio/gpio-mb86s7x.c b/drivers/gpio/gpio-mb86s7x.c index ee93c0ab0a59..93d61a5be0d4 100644 --- a/drivers/gpio/gpio-mb86s7x.c +++ b/drivers/gpio/gpio-mb86s7x.c @@ -187,7 +187,7 @@ static int mb86s70_gpio_probe(struct platform_device *pdev) gchip->gc.label = dev_name(&pdev->dev); gchip->gc.ngpio = 32; gchip->gc.owner = THIS_MODULE; - gchip->gc.dev = &pdev->dev; + gchip->gc.parent = &pdev->dev; gchip->gc.base = -1; platform_set_drvdata(pdev, gchip); diff --git a/drivers/gpio/gpio-mc33880.c b/drivers/gpio/gpio-mc33880.c index 2853731db5bc..b46b9e522e8c 100644 --- a/drivers/gpio/gpio-mc33880.c +++ b/drivers/gpio/gpio-mc33880.c @@ -116,7 +116,7 @@ static int mc33880_probe(struct spi_device *spi) mc->chip.base = pdata->base; mc->chip.ngpio = PIN_NUMBER; mc->chip.can_sleep = true; - mc->chip.dev = &spi->dev; + mc->chip.parent = &spi->dev; mc->chip.owner = THIS_MODULE; mc->port_config = 0x00; diff --git a/drivers/gpio/gpio-mc9s08dz60.c b/drivers/gpio/gpio-mc9s08dz60.c index d62b4f8182bf..45f176018378 100644 --- a/drivers/gpio/gpio-mc9s08dz60.c +++ b/drivers/gpio/gpio-mc9s08dz60.c @@ -99,7 +99,7 @@ static int mc9s08dz60_probe(struct i2c_client *client, mc9s->chip.label = client->name; mc9s->chip.base = -1; - mc9s->chip.dev = &client->dev; + mc9s->chip.parent = &client->dev; mc9s->chip.owner = THIS_MODULE; mc9s->chip.ngpio = GPIO_NUM; mc9s->chip.can_sleep = true; @@ -131,7 +131,6 @@ MODULE_DEVICE_TABLE(i2c, mc9s08dz60_id); static struct i2c_driver mc9s08dz60_i2c_driver = { .driver = { - .owner = THIS_MODULE, .name = "mc9s08dz60", }, .probe = mc9s08dz60_probe, diff --git a/drivers/gpio/gpio-mcp23s08.c b/drivers/gpio/gpio-mcp23s08.c index 4a41694919da..13cace0ca6f7 100644 --- a/drivers/gpio/gpio-mcp23s08.c +++ b/drivers/gpio/gpio-mcp23s08.c @@ -446,7 +446,7 @@ static int mcp23s08_irq_reqres(struct irq_data *data) struct mcp23s08 *mcp = irq_data_get_irq_chip_data(data); if (gpiochip_lock_as_irq(&mcp->chip, data->hwirq)) { - dev_err(mcp->chip.dev, + dev_err(mcp->chip.parent, "unable to lock HW IRQ %lu for IRQ usage\n", data->hwirq); return -EINVAL; @@ -481,7 +481,8 @@ static int mcp23s08_irq_setup(struct mcp23s08 *mcp) mutex_init(&mcp->irq_lock); - mcp->irq_domain = irq_domain_add_linear(chip->dev->of_node, chip->ngpio, + mcp->irq_domain = irq_domain_add_linear(chip->parent->of_node, + chip->ngpio, &irq_domain_simple_ops, mcp); if (!mcp->irq_domain) return -ENODEV; @@ -491,10 +492,11 @@ static int mcp23s08_irq_setup(struct mcp23s08 *mcp) else irqflags |= IRQF_TRIGGER_LOW; - err = devm_request_threaded_irq(chip->dev, mcp->irq, NULL, mcp23s08_irq, - irqflags, dev_name(chip->dev), mcp); + err = devm_request_threaded_irq(chip->parent, mcp->irq, NULL, + mcp23s08_irq, + irqflags, dev_name(chip->parent), mcp); if (err != 0) { - dev_err(chip->dev, "unable to request IRQ#%d: %d\n", + dev_err(chip->parent, "unable to request IRQ#%d: %d\n", mcp->irq, err); return err; } @@ -638,7 +640,7 @@ static int mcp23s08_probe_one(struct mcp23s08 *mcp, struct device *dev, mcp->chip.base = pdata->base; mcp->chip.can_sleep = true; - mcp->chip.dev = dev; + mcp->chip.parent = dev; mcp->chip.owner = THIS_MODULE; /* verify MCP_IOCON.SEQOP = 0, so sequential reads work, @@ -652,7 +654,7 @@ static int mcp23s08_probe_one(struct mcp23s08 *mcp, struct device *dev, mcp->irq_controller = pdata->irq_controller; if (mcp->irq && mcp->irq_controller) { mcp->irq_active_high = - of_property_read_bool(mcp->chip.dev->of_node, + of_property_read_bool(mcp->chip.parent->of_node, "microchip,irq-active-high"); if (type == MCP_TYPE_017) diff --git a/drivers/gpio/gpio-moxart.c b/drivers/gpio/gpio-moxart.c index d3355a6dc9b1..8942f4909a31 100644 --- a/drivers/gpio/gpio-moxart.c +++ b/drivers/gpio/gpio-moxart.c @@ -61,7 +61,7 @@ static int moxart_gpio_probe(struct platform_device *pdev) bgc->data = bgc->read_reg(bgc->reg_set); bgc->gc.base = 0; bgc->gc.ngpio = 32; - bgc->gc.dev = dev; + bgc->gc.parent = dev; bgc->gc.owner = THIS_MODULE; ret = gpiochip_add(&bgc->gc); diff --git a/drivers/gpio/gpio-mpc5200.c b/drivers/gpio/gpio-mpc5200.c index 4c542153e923..044bbbb747f2 100644 --- a/drivers/gpio/gpio-mpc5200.c +++ b/drivers/gpio/gpio-mpc5200.c @@ -360,15 +360,14 @@ static struct platform_driver mpc52xx_simple_gpiochip_driver = { .remove = mpc52xx_gpiochip_remove, }; +static struct platform_driver * const drivers[] = { + &mpc52xx_wkup_gpiochip_driver, + &mpc52xx_simple_gpiochip_driver, +}; + static int __init mpc52xx_gpio_init(void) { - if (platform_driver_register(&mpc52xx_wkup_gpiochip_driver)) - printk(KERN_ERR "Unable to register wakeup GPIO driver\n"); - - if (platform_driver_register(&mpc52xx_simple_gpiochip_driver)) - printk(KERN_ERR "Unable to register simple GPIO driver\n"); - - return 0; + return platform_register_drivers(drivers, ARRAY_SIZE(drivers)); } /* Make sure we get initialised before anyone else tries to use us */ @@ -376,9 +375,7 @@ subsys_initcall(mpc52xx_gpio_init); static void __exit mpc52xx_gpio_exit(void) { - platform_driver_unregister(&mpc52xx_wkup_gpiochip_driver); - - platform_driver_unregister(&mpc52xx_simple_gpiochip_driver); + platform_unregister_drivers(drivers, ARRAY_SIZE(drivers)); } module_exit(mpc52xx_gpio_exit); diff --git a/drivers/gpio/gpio-msic.c b/drivers/gpio/gpio-msic.c index 22523aae8abe..fe9ef2bc981a 100644 --- a/drivers/gpio/gpio-msic.c +++ b/drivers/gpio/gpio-msic.c @@ -293,7 +293,7 @@ static int platform_msic_gpio_probe(struct platform_device *pdev) mg->chip.base = pdata->gpio_base; mg->chip.ngpio = MSIC_NUM_GPIO; mg->chip.can_sleep = true; - mg->chip.dev = dev; + mg->chip.parent = dev; mutex_init(&mg->buslock); diff --git a/drivers/gpio/gpio-mvebu.c b/drivers/gpio/gpio-mvebu.c index d428b97876c5..6acedf4e9b1c 100644 --- a/drivers/gpio/gpio-mvebu.c +++ b/drivers/gpio/gpio-mvebu.c @@ -698,7 +698,7 @@ static int mvebu_gpio_probe(struct platform_device *pdev) mvchip->soc_variant = soc_variant; mvchip->chip.label = dev_name(&pdev->dev); - mvchip->chip.dev = &pdev->dev; + mvchip->chip.parent = &pdev->dev; mvchip->chip.request = gpiochip_generic_request; mvchip->chip.free = gpiochip_generic_free; mvchip->chip.direction_input = mvebu_gpio_direction_input; diff --git a/drivers/gpio/gpio-octeon.c b/drivers/gpio/gpio-octeon.c index 62ae251d4490..afbb2417dfbc 100644 --- a/drivers/gpio/gpio-octeon.c +++ b/drivers/gpio/gpio-octeon.c @@ -108,7 +108,7 @@ static int octeon_gpio_probe(struct platform_device *pdev) pdev->dev.platform_data = chip; chip->label = "octeon-gpio"; - chip->dev = &pdev->dev; + chip->parent = &pdev->dev; chip->owner = THIS_MODULE; chip->base = 0; chip->can_sleep = false; @@ -128,7 +128,7 @@ out: static int octeon_gpio_remove(struct platform_device *pdev) { - struct gpio_chip *chip = pdev->dev.platform_data; + struct gpio_chip *chip = dev_get_platdata(&pdev->dev); gpiochip_remove(chip); return 0; } diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c index f7fbb46d5d79..e183351d047c 100644 --- a/drivers/gpio/gpio-omap.c +++ b/drivers/gpio/gpio-omap.c @@ -1090,7 +1090,7 @@ static int omap_gpio_chip_init(struct gpio_bank *bank, struct irq_chip *irqc) if (bank->is_mpuio) { bank->chip.label = "mpuio"; if (bank->regs->wkup_en) - bank->chip.dev = &omap_mpuio_device.dev; + bank->chip.parent = &omap_mpuio_device.dev; bank->chip.base = OMAP_MPUIO(0); } else { bank->chip.label = "gpio"; @@ -1197,7 +1197,7 @@ static int omap_gpio_probe(struct platform_device *pdev) } bank->dev = dev; - bank->chip.dev = dev; + bank->chip.parent = dev; bank->chip.owner = THIS_MODULE; bank->dbck_flag = pdata->dbck_flag; bank->stride = pdata->bank_stride; diff --git a/drivers/gpio/gpio-palmas.c b/drivers/gpio/gpio-palmas.c index 52b447c071cb..ddd1a00c839d 100644 --- a/drivers/gpio/gpio-palmas.c +++ b/drivers/gpio/gpio-palmas.c @@ -54,7 +54,7 @@ static int palmas_gpio_get(struct gpio_chip *gc, unsigned offset) ret = palmas_read(palmas, PALMAS_GPIO_BASE, reg, &val); if (ret < 0) { - dev_err(gc->dev, "Reg 0x%02x read failed, %d\n", reg, ret); + dev_err(gc->parent, "Reg 0x%02x read failed, %d\n", reg, ret); return ret; } @@ -65,7 +65,7 @@ static int palmas_gpio_get(struct gpio_chip *gc, unsigned offset) ret = palmas_read(palmas, PALMAS_GPIO_BASE, reg, &val); if (ret < 0) { - dev_err(gc->dev, "Reg 0x%02x read failed, %d\n", reg, ret); + dev_err(gc->parent, "Reg 0x%02x read failed, %d\n", reg, ret); return ret; } return !!(val & BIT(offset)); @@ -90,7 +90,7 @@ static void palmas_gpio_set(struct gpio_chip *gc, unsigned offset, ret = palmas_write(palmas, PALMAS_GPIO_BASE, reg, BIT(offset)); if (ret < 0) - dev_err(gc->dev, "Reg 0x%02x write failed, %d\n", reg, ret); + dev_err(gc->parent, "Reg 0x%02x write failed, %d\n", reg, ret); } static int palmas_gpio_output(struct gpio_chip *gc, unsigned offset, @@ -111,7 +111,8 @@ static int palmas_gpio_output(struct gpio_chip *gc, unsigned offset, ret = palmas_update_bits(palmas, PALMAS_GPIO_BASE, reg, BIT(offset), BIT(offset)); if (ret < 0) - dev_err(gc->dev, "Reg 0x%02x update failed, %d\n", reg, ret); + dev_err(gc->parent, "Reg 0x%02x update failed, %d\n", reg, + ret); return ret; } @@ -128,7 +129,8 @@ static int palmas_gpio_input(struct gpio_chip *gc, unsigned offset) ret = palmas_update_bits(palmas, PALMAS_GPIO_BASE, reg, BIT(offset), 0); if (ret < 0) - dev_err(gc->dev, "Reg 0x%02x update failed, %d\n", reg, ret); + dev_err(gc->parent, "Reg 0x%02x update failed, %d\n", reg, + ret); return ret; } @@ -188,7 +190,7 @@ static int palmas_gpio_probe(struct platform_device *pdev) palmas_gpio->gpio_chip.to_irq = palmas_gpio_to_irq; palmas_gpio->gpio_chip.set = palmas_gpio_set; palmas_gpio->gpio_chip.get = palmas_gpio_get; - palmas_gpio->gpio_chip.dev = &pdev->dev; + palmas_gpio->gpio_chip.parent = &pdev->dev; #ifdef CONFIG_OF_GPIO palmas_gpio->gpio_chip.of_node = pdev->dev.of_node; #endif diff --git a/drivers/gpio/gpio-pca953x.c b/drivers/gpio/gpio-pca953x.c index 2d4892cc70fb..be3e3b903ff0 100644 --- a/drivers/gpio/gpio-pca953x.c +++ b/drivers/gpio/gpio-pca953x.c @@ -18,9 +18,7 @@ #include <linux/i2c.h> #include <linux/platform_data/pca953x.h> #include <linux/slab.h> -#ifdef CONFIG_OF_GPIO #include <linux/of_platform.h> -#endif #include <linux/acpi.h> #define PCA953X_INPUT 0 @@ -352,6 +350,43 @@ exit: mutex_unlock(&chip->i2c_lock); } + +static void pca953x_gpio_set_multiple(struct gpio_chip *gc, + unsigned long *mask, unsigned long *bits) +{ + struct pca953x_chip *chip = to_pca(gc); + u8 reg_val[MAX_BANK]; + int ret, offset = 0; + int bank_shift = fls((chip->gpio_chip.ngpio - 1) / BANK_SZ); + int bank; + + switch (chip->chip_type) { + case PCA953X_TYPE: + offset = PCA953X_OUTPUT; + break; + case PCA957X_TYPE: + offset = PCA957X_OUT; + break; + } + + memcpy(reg_val, chip->reg_output, NBANK(chip)); + mutex_lock(&chip->i2c_lock); + for(bank=0; bank<NBANK(chip); bank++) { + unsigned bankmask = mask[bank/4] >> ((bank % 4) * 8); + if(bankmask) { + unsigned bankval = bits[bank/4] >> ((bank % 4) * 8); + reg_val[bank] = (reg_val[bank] & ~bankmask) | bankval; + } + } + ret = i2c_smbus_write_i2c_block_data(chip->client, offset << bank_shift, NBANK(chip), reg_val); + if (ret) + goto exit; + + memcpy(chip->reg_output, reg_val, NBANK(chip)); +exit: + mutex_unlock(&chip->i2c_lock); +} + static void pca953x_setup_gpio(struct pca953x_chip *chip, int gpios) { struct gpio_chip *gc; @@ -362,12 +397,13 @@ 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->set_multiple = pca953x_gpio_set_multiple; gc->can_sleep = true; gc->base = chip->gpio_start; gc->ngpio = gpios; gc->label = chip->client->name; - gc->dev = &chip->client->dev; + gc->parent = &chip->client->dev; gc->owner = THIS_MODULE; gc->names = chip->names; } @@ -660,6 +696,8 @@ out: return ret; } +static const struct of_device_id pca953x_dt_ids[]; + static int pca953x_probe(struct i2c_client *client, const struct i2c_device_id *id) { @@ -691,12 +729,18 @@ static int pca953x_probe(struct i2c_client *client, chip->driver_data = id->driver_data; } else { const struct acpi_device_id *id; + const struct of_device_id *match; - id = acpi_match_device(pca953x_acpi_ids, &client->dev); - if (!id) - return -ENODEV; + match = of_match_device(pca953x_dt_ids, &client->dev); + if (match) { + chip->driver_data = (int)(uintptr_t)match->data; + } else { + id = acpi_match_device(pca953x_acpi_ids, &client->dev); + if (!id) + return -ENODEV; - chip->driver_data = id->driver_data; + chip->driver_data = id->driver_data; + } } chip->chip_type = PCA_CHIP_TYPE(chip->driver_data); @@ -755,33 +799,39 @@ static int pca953x_remove(struct i2c_client *client) return 0; } +/* convenience to stop overlong match-table lines */ +#define OF_953X(__nrgpio, __int) (void *)(__nrgpio | PCA953X_TYPE | __int) +#define OF_957X(__nrgpio, __int) (void *)(__nrgpio | PCA957X_TYPE | __int) + static const struct of_device_id pca953x_dt_ids[] = { - { .compatible = "nxp,pca9505", }, - { .compatible = "nxp,pca9534", }, - { .compatible = "nxp,pca9535", }, - { .compatible = "nxp,pca9536", }, - { .compatible = "nxp,pca9537", }, - { .compatible = "nxp,pca9538", }, - { .compatible = "nxp,pca9539", }, - { .compatible = "nxp,pca9554", }, - { .compatible = "nxp,pca9555", }, - { .compatible = "nxp,pca9556", }, - { .compatible = "nxp,pca9557", }, - { .compatible = "nxp,pca9574", }, - { .compatible = "nxp,pca9575", }, - { .compatible = "nxp,pca9698", }, - - { .compatible = "maxim,max7310", }, - { .compatible = "maxim,max7312", }, - { .compatible = "maxim,max7313", }, - { .compatible = "maxim,max7315", }, - - { .compatible = "ti,pca6107", }, - { .compatible = "ti,tca6408", }, - { .compatible = "ti,tca6416", }, - { .compatible = "ti,tca6424", }, - - { .compatible = "exar,xra1202", }, + { .compatible = "nxp,pca9505", .data = OF_953X(40, PCA_INT), }, + { .compatible = "nxp,pca9534", .data = OF_953X( 8, PCA_INT), }, + { .compatible = "nxp,pca9535", .data = OF_953X(16, PCA_INT), }, + { .compatible = "nxp,pca9536", .data = OF_953X( 4, 0), }, + { .compatible = "nxp,pca9537", .data = OF_953X( 4, PCA_INT), }, + { .compatible = "nxp,pca9538", .data = OF_953X( 8, PCA_INT), }, + { .compatible = "nxp,pca9539", .data = OF_953X(16, PCA_INT), }, + { .compatible = "nxp,pca9554", .data = OF_953X( 8, PCA_INT), }, + { .compatible = "nxp,pca9555", .data = OF_953X(16, PCA_INT), }, + { .compatible = "nxp,pca9556", .data = OF_953X( 8, 0), }, + { .compatible = "nxp,pca9557", .data = OF_953X( 8, 0), }, + { .compatible = "nxp,pca9574", .data = OF_957X( 8, PCA_INT), }, + { .compatible = "nxp,pca9575", .data = OF_957X(16, PCA_INT), }, + { .compatible = "nxp,pca9698", .data = OF_953X(40, 0), }, + + { .compatible = "maxim,max7310", .data = OF_953X( 8, 0), }, + { .compatible = "maxim,max7312", .data = OF_953X(16, PCA_INT), }, + { .compatible = "maxim,max7313", .data = OF_953X(16, PCA_INT), }, + { .compatible = "maxim,max7315", .data = OF_953X( 8, PCA_INT), }, + + { .compatible = "ti,pca6107", .data = OF_953X( 8, PCA_INT), }, + { .compatible = "ti,tca6408", .data = OF_953X( 8, PCA_INT), }, + { .compatible = "ti,tca6416", .data = OF_953X(16, PCA_INT), }, + { .compatible = "ti,tca6424", .data = OF_953X(24, PCA_INT), }, + + { .compatible = "onsemi,pca9654", .data = OF_953X( 8, PCA_INT), }, + + { .compatible = "exar,xra1202", .data = OF_953X( 8, 0), }, { } }; diff --git a/drivers/gpio/gpio-pcf857x.c b/drivers/gpio/gpio-pcf857x.c index 1d4d9bc8b69d..bf511c0efa48 100644 --- a/drivers/gpio/gpio-pcf857x.c +++ b/drivers/gpio/gpio-pcf857x.c @@ -293,7 +293,7 @@ static int pcf857x_probe(struct i2c_client *client, gpio->chip.base = pdata ? pdata->gpio_base : -1; gpio->chip.can_sleep = true; - gpio->chip.dev = &client->dev; + gpio->chip.parent = &client->dev; gpio->chip.owner = THIS_MODULE; gpio->chip.get = pcf857x_get; gpio->chip.set = pcf857x_set; @@ -447,7 +447,6 @@ static int pcf857x_remove(struct i2c_client *client) static struct i2c_driver pcf857x_driver = { .driver = { .name = "pcf857x", - .owner = THIS_MODULE, .of_match_table = of_match_ptr(pcf857x_of_table), }, .probe = pcf857x_probe, diff --git a/drivers/gpio/gpio-pch.c b/drivers/gpio/gpio-pch.c index 34ed176df15a..af0715f8524b 100644 --- a/drivers/gpio/gpio-pch.c +++ b/drivers/gpio/gpio-pch.c @@ -220,7 +220,7 @@ static void pch_gpio_setup(struct pch_gpio *chip) struct gpio_chip *gpio = &chip->gpio; gpio->label = dev_name(chip->dev); - gpio->dev = chip->dev; + gpio->parent = chip->dev; gpio->owner = THIS_MODULE; gpio->direction_input = pch_gpio_direction_input; gpio->get = pch_gpio_get; @@ -394,6 +394,9 @@ static int pch_gpio_probe(struct pci_dev *pdev, pci_set_drvdata(pdev, chip); spin_lock_init(&chip->spinlock); pch_gpio_setup(chip); +#ifdef CONFIG_OF_GPIO + chip->gpio.of_node = pdev->dev.of_node; +#endif ret = gpiochip_add(&chip->gpio); if (ret) { dev_err(&pdev->dev, "PCH gpio: Failed to register GPIO\n"); diff --git a/drivers/gpio/gpio-pl061.c b/drivers/gpio/gpio-pl061.c index 4d4b37676702..f937bc7e42dd 100644 --- a/drivers/gpio/gpio-pl061.c +++ b/drivers/gpio/gpio-pl061.c @@ -14,6 +14,7 @@ #include <linux/module.h> #include <linux/io.h> #include <linux/ioport.h> +#include <linux/interrupt.h> #include <linux/irq.h> #include <linux/irqchip/chained_irq.h> #include <linux/bitops.h> @@ -131,7 +132,7 @@ static int pl061_irq_type(struct irq_data *d, unsigned trigger) if ((trigger & (IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW)) && (trigger & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING))) { - dev_err(gc->dev, + dev_err(gc->parent, "trying to configure line %d for both level and edge " "detection, choose one!\n", offset); @@ -158,7 +159,7 @@ static int pl061_irq_type(struct irq_data *d, unsigned trigger) else gpioiev &= ~bit; irq_set_handler_locked(d, handle_level_irq); - dev_dbg(gc->dev, "line %d: IRQ on %s level\n", + dev_dbg(gc->parent, "line %d: IRQ on %s level\n", offset, polarity ? "HIGH" : "LOW"); } else if ((trigger & IRQ_TYPE_EDGE_BOTH) == IRQ_TYPE_EDGE_BOTH) { @@ -167,7 +168,7 @@ static int pl061_irq_type(struct irq_data *d, unsigned trigger) /* Select both edges, setting this makes GPIOEV be ignored */ gpioibe |= bit; irq_set_handler_locked(d, handle_edge_irq); - dev_dbg(gc->dev, "line %d: IRQ on both edges\n", offset); + dev_dbg(gc->parent, "line %d: IRQ on both edges\n", offset); } else if ((trigger & IRQ_TYPE_EDGE_RISING) || (trigger & IRQ_TYPE_EDGE_FALLING)) { bool rising = trigger & IRQ_TYPE_EDGE_RISING; @@ -182,7 +183,7 @@ static int pl061_irq_type(struct irq_data *d, unsigned trigger) else gpioiev &= ~bit; irq_set_handler_locked(d, handle_edge_irq); - dev_dbg(gc->dev, "line %d: IRQ on %s edge\n", + dev_dbg(gc->parent, "line %d: IRQ on %s edge\n", offset, rising ? "RISING" : "FALLING"); } else { @@ -191,7 +192,7 @@ static int pl061_irq_type(struct irq_data *d, unsigned trigger) gpioibe &= ~bit; gpioiev &= ~bit; irq_set_handler_locked(d, handle_bad_irq); - dev_warn(gc->dev, "no trigger selected for line %d\n", + dev_warn(gc->parent, "no trigger selected for line %d\n", offset); } @@ -269,12 +270,20 @@ static void pl061_irq_ack(struct irq_data *d) spin_unlock(&chip->lock); } +static int pl061_irq_set_wake(struct irq_data *d, unsigned int state) +{ + struct gpio_chip *gc = irq_data_get_irq_chip_data(d); + + return irq_set_irq_wake(gc->irq_parent, state); +} + static struct irq_chip pl061_irqchip = { .name = "pl061", .irq_ack = pl061_irq_ack, .irq_mask = pl061_irq_mask, .irq_unmask = pl061_irq_unmask, .irq_set_type = pl061_irq_type, + .irq_set_wake = pl061_irq_set_wake, }; static int pl061_probe(struct amba_device *adev, const struct amba_id *id) @@ -316,7 +325,7 @@ static int pl061_probe(struct amba_device *adev, const struct amba_id *id) chip->gc.set = pl061_set_value; chip->gc.ngpio = PL061_GPIO_NR; chip->gc.label = dev_name(dev); - chip->gc.dev = dev; + chip->gc.parent = dev; chip->gc.owner = THIS_MODULE; ret = gpiochip_add(&chip->gc); diff --git a/drivers/gpio/gpio-pxa.c b/drivers/gpio/gpio-pxa.c index df2ce550f309..eacb4b9b2677 100644 --- a/drivers/gpio/gpio-pxa.c +++ b/drivers/gpio/gpio-pxa.c @@ -24,6 +24,7 @@ #include <linux/io.h> #include <linux/of.h> #include <linux/of_device.h> +#include <linux/pinctrl/consumer.h> #include <linux/platform_device.h> #include <linux/syscore_ops.h> #include <linux/slab.h> @@ -64,20 +65,11 @@ int pxa_last_gpio; static int irq_base; -#ifdef CONFIG_OF -static struct irq_domain *domain; -static struct device_node *pxa_gpio_of_node; -#endif - -struct pxa_gpio_chip { - struct gpio_chip chip; +struct pxa_gpio_bank { void __iomem *regbase; - char label[10]; - unsigned long irq_mask; unsigned long irq_edge_rise; unsigned long irq_edge_fall; - int (*set_wake)(unsigned int gpio, unsigned int on); #ifdef CONFIG_PM unsigned long saved_gplr; @@ -87,6 +79,17 @@ struct pxa_gpio_chip { #endif }; +struct pxa_gpio_chip { + struct device *dev; + struct gpio_chip chip; + struct pxa_gpio_bank *banks; + struct irq_domain *irqdomain; + + int irq0; + int irq1; + int (*set_wake)(unsigned int gpio, unsigned int on); +}; + enum pxa_gpio_type { PXA25X_GPIO = 0, PXA26X_GPIO, @@ -104,9 +107,8 @@ struct pxa_gpio_id { }; static DEFINE_SPINLOCK(gpio_lock); -static struct pxa_gpio_chip *pxa_gpio_chips; +static struct pxa_gpio_chip *pxa_gpio_chip; static enum pxa_gpio_type gpio_type; -static void __iomem *gpio_reg_base; static struct pxa_gpio_id pxa25x_id = { .type = PXA25X_GPIO, @@ -148,17 +150,27 @@ static struct pxa_gpio_id pxa1928_id = { .gpio_nums = 224, }; -#define for_each_gpio_chip(i, c) \ - for (i = 0, c = &pxa_gpio_chips[0]; i <= pxa_last_gpio; i += 32, c++) +#define for_each_gpio_bank(i, b, pc) \ + for (i = 0, b = pc->banks; i <= pxa_last_gpio; i += 32, b++) + +static inline struct pxa_gpio_chip *chip_to_pxachip(struct gpio_chip *c) +{ + struct pxa_gpio_chip *pxa_chip = + container_of(c, struct pxa_gpio_chip, chip); -static inline void __iomem *gpio_chip_base(struct gpio_chip *c) + return pxa_chip; +} +static inline void __iomem *gpio_bank_base(struct gpio_chip *c, int gpio) { - return container_of(c, struct pxa_gpio_chip, chip)->regbase; + struct pxa_gpio_bank *bank = chip_to_pxachip(c)->banks + (gpio / 32); + + return bank->regbase; } -static inline struct pxa_gpio_chip *gpio_to_pxachip(unsigned gpio) +static inline struct pxa_gpio_bank *gpio_to_pxabank(struct gpio_chip *c, + unsigned gpio) { - return &pxa_gpio_chips[gpio_to_bank(gpio)]; + return chip_to_pxachip(c)->banks + gpio / 32; } static inline int gpio_is_pxa_type(int type) @@ -187,15 +199,13 @@ static inline int __gpio_is_inverted(int gpio) * is attributed as "occupied" here (I know this terminology isn't * accurate, you are welcome to propose a better one :-) */ -static inline int __gpio_is_occupied(unsigned gpio) +static inline int __gpio_is_occupied(struct pxa_gpio_chip *pchip, unsigned gpio) { - struct pxa_gpio_chip *pxachip; void __iomem *base; unsigned long gafr = 0, gpdr = 0; int ret, af = 0, dir = 0; - pxachip = gpio_to_pxachip(gpio); - base = gpio_chip_base(&pxachip->chip); + base = gpio_bank_base(&pchip->chip, gpio); gpdr = readl_relaxed(base + GPDR_OFFSET); switch (gpio_type) { @@ -218,21 +228,35 @@ static inline int __gpio_is_occupied(unsigned gpio) return ret; } -static int pxa_gpio_to_irq(struct gpio_chip *chip, unsigned offset) +int pxa_irq_to_gpio(int irq) { - return chip->base + offset + irq_base; + struct pxa_gpio_chip *pchip = pxa_gpio_chip; + int irq_gpio0; + + irq_gpio0 = irq_find_mapping(pchip->irqdomain, 0); + if (irq_gpio0 > 0) + return irq - irq_gpio0; + + return irq_gpio0; } -int pxa_irq_to_gpio(int irq) +static int pxa_gpio_to_irq(struct gpio_chip *chip, unsigned offset) { - return irq - irq_base; + struct pxa_gpio_chip *pchip = chip_to_pxachip(chip); + + return irq_find_mapping(pchip->irqdomain, offset); } static int pxa_gpio_direction_input(struct gpio_chip *chip, unsigned offset) { - void __iomem *base = gpio_chip_base(chip); - uint32_t value, mask = 1 << offset; + void __iomem *base = gpio_bank_base(chip, offset); + uint32_t value, mask = GPIO_bit(offset); unsigned long flags; + int ret; + + ret = pinctrl_gpio_direction_input(chip->base + offset); + if (!ret) + return 0; spin_lock_irqsave(&gpio_lock, flags); @@ -250,12 +274,17 @@ static int pxa_gpio_direction_input(struct gpio_chip *chip, unsigned offset) static int pxa_gpio_direction_output(struct gpio_chip *chip, unsigned offset, int value) { - void __iomem *base = gpio_chip_base(chip); - uint32_t tmp, mask = 1 << offset; + void __iomem *base = gpio_bank_base(chip, offset); + uint32_t tmp, mask = GPIO_bit(offset); unsigned long flags; + int ret; writel_relaxed(mask, base + (value ? GPSR_OFFSET : GPCR_OFFSET)); + ret = pinctrl_gpio_direction_output(chip->base + offset); + if (!ret) + return 0; + spin_lock_irqsave(&gpio_lock, flags); tmp = readl_relaxed(base + GPDR_OFFSET); @@ -271,14 +300,18 @@ static int pxa_gpio_direction_output(struct gpio_chip *chip, static int pxa_gpio_get(struct gpio_chip *chip, unsigned offset) { - u32 gplr = readl_relaxed(gpio_chip_base(chip) + GPLR_OFFSET); - return !!(gplr & (1 << offset)); + void __iomem *base = gpio_bank_base(chip, offset); + u32 gplr = readl_relaxed(base + GPLR_OFFSET); + + return !!(gplr & GPIO_bit(offset)); } static void pxa_gpio_set(struct gpio_chip *chip, unsigned offset, int value) { - writel_relaxed(1 << offset, gpio_chip_base(chip) + - (value ? GPSR_OFFSET : GPCR_OFFSET)); + void __iomem *base = gpio_bank_base(chip, offset); + + writel_relaxed(GPIO_bit(offset), + base + (value ? GPSR_OFFSET : GPCR_OFFSET)); } #ifdef CONFIG_OF_GPIO @@ -289,61 +322,61 @@ static int pxa_gpio_of_xlate(struct gpio_chip *gc, if (gpiospec->args[0] > pxa_last_gpio) return -EINVAL; - if (gc != &pxa_gpio_chips[gpiospec->args[0] / 32].chip) - return -EINVAL; - if (flags) *flags = gpiospec->args[1]; - return gpiospec->args[0] % 32; + return gpiospec->args[0]; } #endif -static int pxa_init_gpio_chip(int gpio_end, - int (*set_wake)(unsigned int, unsigned int)) +static int pxa_gpio_request(struct gpio_chip *chip, unsigned int offset) { - int i, gpio, nbanks = gpio_to_bank(gpio_end) + 1; - struct pxa_gpio_chip *chips; - - chips = kzalloc(nbanks * sizeof(struct pxa_gpio_chip), GFP_KERNEL); - if (chips == NULL) { - pr_err("%s: failed to allocate GPIO chips\n", __func__); - return -ENOMEM; - } + return pinctrl_request_gpio(chip->base + offset); +} - for (i = 0, gpio = 0; i < nbanks; i++, gpio += 32) { - struct gpio_chip *c = &chips[i].chip; +static void pxa_gpio_free(struct gpio_chip *chip, unsigned int offset) +{ + pinctrl_free_gpio(chip->base + offset); +} - sprintf(chips[i].label, "gpio-%d", i); - chips[i].regbase = gpio_reg_base + BANK_OFF(i); - chips[i].set_wake = set_wake; +static int pxa_init_gpio_chip(struct pxa_gpio_chip *pchip, int ngpio, + struct device_node *np, void __iomem *regbase) +{ + int i, gpio, nbanks = DIV_ROUND_UP(ngpio, 32); + struct pxa_gpio_bank *bank; - c->base = gpio; - c->label = chips[i].label; + pchip->banks = devm_kcalloc(pchip->dev, nbanks, sizeof(*pchip->banks), + GFP_KERNEL); + if (!pchip->banks) + return -ENOMEM; - c->direction_input = pxa_gpio_direction_input; - c->direction_output = pxa_gpio_direction_output; - c->get = pxa_gpio_get; - c->set = pxa_gpio_set; - c->to_irq = pxa_gpio_to_irq; + pchip->chip.label = "gpio-pxa"; + pchip->chip.direction_input = pxa_gpio_direction_input; + pchip->chip.direction_output = pxa_gpio_direction_output; + pchip->chip.get = pxa_gpio_get; + pchip->chip.set = pxa_gpio_set; + pchip->chip.to_irq = pxa_gpio_to_irq; + pchip->chip.ngpio = ngpio; + pchip->chip.request = pxa_gpio_request; + pchip->chip.free = pxa_gpio_free; #ifdef CONFIG_OF_GPIO - c->of_node = pxa_gpio_of_node; - c->of_xlate = pxa_gpio_of_xlate; - c->of_gpio_n_cells = 2; + pchip->chip.of_node = np; + pchip->chip.of_xlate = pxa_gpio_of_xlate; + pchip->chip.of_gpio_n_cells = 2; #endif - /* number of GPIOs on last bank may be less than 32 */ - c->ngpio = (gpio + 31 > gpio_end) ? (gpio_end - gpio + 1) : 32; - gpiochip_add(c); + for (i = 0, gpio = 0; i < nbanks; i++, gpio += 32) { + bank = pchip->banks + i; + bank->regbase = regbase + BANK_OFF(i); } - pxa_gpio_chips = chips; - return 0; + + return gpiochip_add(&pchip->chip); } /* Update only those GRERx and GFERx edge detection register bits if those * bits are set in c->irq_mask */ -static inline void update_edge_detect(struct pxa_gpio_chip *c) +static inline void update_edge_detect(struct pxa_gpio_bank *c) { uint32_t grer, gfer; @@ -357,12 +390,11 @@ static inline void update_edge_detect(struct pxa_gpio_chip *c) static int pxa_gpio_irq_type(struct irq_data *d, unsigned int type) { - struct pxa_gpio_chip *c; - int gpio = pxa_irq_to_gpio(d->irq); + struct pxa_gpio_chip *pchip = irq_data_get_irq_chip_data(d); + unsigned int gpio = irqd_to_hwirq(d); + struct pxa_gpio_bank *c = gpio_to_pxabank(&pchip->chip, gpio); unsigned long gpdr, mask = GPIO_bit(gpio); - c = gpio_to_pxachip(gpio); - if (type == IRQ_TYPE_PROBE) { /* Don't mess with enabled GPIOs using preconfigured edges or * GPIOs set to alternate function or to output during probe @@ -370,7 +402,7 @@ static int pxa_gpio_irq_type(struct irq_data *d, unsigned int type) if ((c->irq_edge_rise | c->irq_edge_fall) & GPIO_bit(gpio)) return 0; - if (__gpio_is_occupied(gpio)) + if (__gpio_is_occupied(pchip, gpio)) return 0; type = IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING; @@ -401,20 +433,16 @@ static int pxa_gpio_irq_type(struct irq_data *d, unsigned int type) return 0; } -static void pxa_gpio_demux_handler(struct irq_desc *desc) +static irqreturn_t pxa_gpio_demux_handler(int in_irq, void *d) { - struct pxa_gpio_chip *c; - int loop, gpio, gpio_base, n; + int loop, gpio, n, handled = 0; unsigned long gedr; - struct irq_chip *chip = irq_desc_get_chip(desc); - - chained_irq_enter(chip, desc); + struct pxa_gpio_chip *pchip = d; + struct pxa_gpio_bank *c; do { loop = 0; - for_each_gpio_chip(gpio, c) { - gpio_base = c->chip.base; - + for_each_gpio_bank(gpio, c, pchip) { gedr = readl_relaxed(c->regbase + GEDR_OFFSET); gedr = gedr & c->irq_mask; writel_relaxed(gedr, c->regbase + GEDR_OFFSET); @@ -422,51 +450,71 @@ static void pxa_gpio_demux_handler(struct irq_desc *desc) for_each_set_bit(n, &gedr, BITS_PER_LONG) { loop = 1; - generic_handle_irq(gpio_to_irq(gpio_base + n)); + generic_handle_irq(gpio_to_irq(gpio + n)); } } + handled += loop; } while (loop); - chained_irq_exit(chip, desc); + return handled ? IRQ_HANDLED : IRQ_NONE; +} + +static irqreturn_t pxa_gpio_direct_handler(int in_irq, void *d) +{ + struct pxa_gpio_chip *pchip = d; + + if (in_irq == pchip->irq0) { + generic_handle_irq(gpio_to_irq(0)); + } else if (in_irq == pchip->irq1) { + generic_handle_irq(gpio_to_irq(1)); + } else { + pr_err("%s() unknown irq %d\n", __func__, in_irq); + return IRQ_NONE; + } + return IRQ_HANDLED; } static void pxa_ack_muxed_gpio(struct irq_data *d) { - int gpio = pxa_irq_to_gpio(d->irq); - struct pxa_gpio_chip *c = gpio_to_pxachip(gpio); + struct pxa_gpio_chip *pchip = irq_data_get_irq_chip_data(d); + unsigned int gpio = irqd_to_hwirq(d); + void __iomem *base = gpio_bank_base(&pchip->chip, gpio); - writel_relaxed(GPIO_bit(gpio), c->regbase + GEDR_OFFSET); + writel_relaxed(GPIO_bit(gpio), base + GEDR_OFFSET); } static void pxa_mask_muxed_gpio(struct irq_data *d) { - int gpio = pxa_irq_to_gpio(d->irq); - struct pxa_gpio_chip *c = gpio_to_pxachip(gpio); + struct pxa_gpio_chip *pchip = irq_data_get_irq_chip_data(d); + unsigned int gpio = irqd_to_hwirq(d); + struct pxa_gpio_bank *b = gpio_to_pxabank(&pchip->chip, gpio); + void __iomem *base = gpio_bank_base(&pchip->chip, gpio); uint32_t grer, gfer; - c->irq_mask &= ~GPIO_bit(gpio); + b->irq_mask &= ~GPIO_bit(gpio); - grer = readl_relaxed(c->regbase + GRER_OFFSET) & ~GPIO_bit(gpio); - gfer = readl_relaxed(c->regbase + GFER_OFFSET) & ~GPIO_bit(gpio); - writel_relaxed(grer, c->regbase + GRER_OFFSET); - writel_relaxed(gfer, c->regbase + GFER_OFFSET); + grer = readl_relaxed(base + GRER_OFFSET) & ~GPIO_bit(gpio); + gfer = readl_relaxed(base + GFER_OFFSET) & ~GPIO_bit(gpio); + writel_relaxed(grer, base + GRER_OFFSET); + writel_relaxed(gfer, base + GFER_OFFSET); } static int pxa_gpio_set_wake(struct irq_data *d, unsigned int on) { - int gpio = pxa_irq_to_gpio(d->irq); - struct pxa_gpio_chip *c = gpio_to_pxachip(gpio); + struct pxa_gpio_chip *pchip = irq_data_get_irq_chip_data(d); + unsigned int gpio = irqd_to_hwirq(d); - if (c->set_wake) - return c->set_wake(gpio, on); + if (pchip->set_wake) + return pchip->set_wake(gpio, on); else return 0; } static void pxa_unmask_muxed_gpio(struct irq_data *d) { - int gpio = pxa_irq_to_gpio(d->irq); - struct pxa_gpio_chip *c = gpio_to_pxachip(gpio); + struct pxa_gpio_chip *pchip = irq_data_get_irq_chip_data(d); + unsigned int gpio = irqd_to_hwirq(d); + struct pxa_gpio_bank *c = gpio_to_pxabank(&pchip->chip, gpio); c->irq_mask |= GPIO_bit(gpio); update_edge_detect(c); @@ -524,6 +572,7 @@ static int pxa_irq_domain_map(struct irq_domain *d, unsigned int irq, { irq_set_chip_and_handler(irq, &pxa_muxed_gpio_chip, handle_edge_irq); + irq_set_chip_data(irq, d->host_data); irq_set_noprobe(irq); return 0; } @@ -533,10 +582,10 @@ const struct irq_domain_ops pxa_irq_domain_ops = { .xlate = irq_domain_xlate_twocell, }; -static int pxa_gpio_probe_dt(struct platform_device *pdev) +static int pxa_gpio_probe_dt(struct platform_device *pdev, + struct pxa_gpio_chip *pchip) { - int ret = 0, nr_gpios; - struct device_node *np = pdev->dev.of_node; + int nr_gpios; const struct of_device_id *of_id = of_match_device(pxa_gpio_dt_ids, &pdev->dev); const struct pxa_gpio_id *gpio_id; @@ -554,57 +603,64 @@ static int pxa_gpio_probe_dt(struct platform_device *pdev) irq_base = irq_alloc_descs(-1, 0, nr_gpios, 0); if (irq_base < 0) { dev_err(&pdev->dev, "Failed to allocate IRQ numbers\n"); - ret = irq_base; - goto err; + return irq_base; } - domain = irq_domain_add_legacy(np, nr_gpios, irq_base, 0, - &pxa_irq_domain_ops, NULL); - pxa_gpio_of_node = np; - return 0; -err: - iounmap(gpio_reg_base); - return ret; + return irq_base; } #else -#define pxa_gpio_probe_dt(pdev) (-1) +#define pxa_gpio_probe_dt(pdev, pchip) (-1) #endif static int pxa_gpio_probe(struct platform_device *pdev) { - struct pxa_gpio_chip *c; + struct pxa_gpio_chip *pchip; + struct pxa_gpio_bank *c; struct resource *res; struct clk *clk; struct pxa_gpio_platform_data *info; - int gpio, irq, ret, use_of = 0; + void __iomem *gpio_reg_base; + int gpio, ret; int irq0 = 0, irq1 = 0, irq_mux, gpio_offset = 0; + pchip = devm_kzalloc(&pdev->dev, sizeof(*pchip), GFP_KERNEL); + if (!pchip) + return -ENOMEM; + pchip->dev = &pdev->dev; + info = dev_get_platdata(&pdev->dev); if (info) { irq_base = info->irq_base; if (irq_base <= 0) return -EINVAL; pxa_last_gpio = pxa_gpio_nums(pdev); + pchip->set_wake = info->gpio_set_wake; } else { - irq_base = 0; - use_of = 1; - ret = pxa_gpio_probe_dt(pdev); - if (ret < 0) + irq_base = pxa_gpio_probe_dt(pdev, pchip); + if (irq_base < 0) return -EINVAL; } if (!pxa_last_gpio) return -EINVAL; + pchip->irqdomain = irq_domain_add_legacy(pdev->dev.of_node, + pxa_last_gpio + 1, irq_base, + 0, &pxa_irq_domain_ops, pchip); + if (IS_ERR(pchip->irqdomain)) + return PTR_ERR(pchip->irqdomain); + irq0 = platform_get_irq_byname(pdev, "gpio0"); irq1 = platform_get_irq_byname(pdev, "gpio1"); irq_mux = platform_get_irq_byname(pdev, "gpio_mux"); if ((irq0 > 0 && irq1 <= 0) || (irq0 <= 0 && irq1 > 0) || (irq_mux <= 0)) return -EINVAL; + + pchip->irq0 = irq0; + pchip->irq1 = irq1; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) - return -EINVAL; - gpio_reg_base = ioremap(res->start, resource_size(res)); + gpio_reg_base = devm_ioremap(&pdev->dev, res->start, + resource_size(res)); if (!gpio_reg_base) return -EINVAL; @@ -615,21 +671,24 @@ static int pxa_gpio_probe(struct platform_device *pdev) if (IS_ERR(clk)) { dev_err(&pdev->dev, "Error %ld to get gpio clock\n", PTR_ERR(clk)); - iounmap(gpio_reg_base); return PTR_ERR(clk); } ret = clk_prepare_enable(clk); if (ret) { clk_put(clk); - iounmap(gpio_reg_base); return ret; } /* Initialize GPIO chips */ - pxa_init_gpio_chip(pxa_last_gpio, info ? info->gpio_set_wake : NULL); + ret = pxa_init_gpio_chip(pchip, pxa_last_gpio + 1, pdev->dev.of_node, + gpio_reg_base); + if (ret) { + clk_put(clk); + return ret; + } /* clear all GPIO edge detects */ - for_each_gpio_chip(gpio, c) { + for_each_gpio_bank(gpio, c, pchip) { writel_relaxed(0, c->regbase + GFER_OFFSET); writel_relaxed(0, c->regbase + GRER_OFFSET); writel_relaxed(~0, c->regbase + GEDR_OFFSET); @@ -638,34 +697,31 @@ static int pxa_gpio_probe(struct platform_device *pdev) writel_relaxed(~0, c->regbase + ED_MASK_OFFSET); } - if (!use_of) { - if (irq0 > 0) { - irq = gpio_to_irq(0); - irq_set_chip_and_handler(irq, &pxa_muxed_gpio_chip, - handle_edge_irq); - irq_clear_status_flags(irq, IRQ_NOREQUEST | IRQ_NOPROBE); - } - if (irq1 > 0) { - irq = gpio_to_irq(1); - irq_set_chip_and_handler(irq, &pxa_muxed_gpio_chip, - handle_edge_irq); - irq_clear_status_flags(irq, IRQ_NOREQUEST | IRQ_NOPROBE); - } - - for (irq = gpio_to_irq(gpio_offset); - irq <= gpio_to_irq(pxa_last_gpio); irq++) { - irq_set_chip_and_handler(irq, &pxa_muxed_gpio_chip, - handle_edge_irq); - irq_clear_status_flags(irq, IRQ_NOREQUEST | IRQ_NOPROBE); - } + if (irq0 > 0) { + ret = devm_request_irq(&pdev->dev, + irq0, pxa_gpio_direct_handler, 0, + "gpio-0", pchip); + if (ret) + dev_err(&pdev->dev, "request of gpio0 irq failed: %d\n", + ret); } + if (irq1 > 0) { + ret = devm_request_irq(&pdev->dev, + irq1, pxa_gpio_direct_handler, 0, + "gpio-1", pchip); + if (ret) + dev_err(&pdev->dev, "request of gpio1 irq failed: %d\n", + ret); + } + ret = devm_request_irq(&pdev->dev, + irq_mux, pxa_gpio_demux_handler, 0, + "gpio-mux", pchip); + if (ret) + dev_err(&pdev->dev, "request of gpio-mux irq failed: %d\n", + ret); - if (irq0 > 0) - irq_set_chained_handler(irq0, pxa_gpio_demux_handler); - if (irq1 > 0) - irq_set_chained_handler(irq1, pxa_gpio_demux_handler); + pxa_gpio_chip = pchip; - irq_set_chained_handler(irq_mux, pxa_gpio_demux_handler); return 0; } @@ -690,19 +746,32 @@ static struct platform_driver pxa_gpio_driver = { .id_table = gpio_id_table, }; -static int __init pxa_gpio_init(void) +static int __init pxa_gpio_legacy_init(void) { + if (of_have_populated_dt()) + return 0; + return platform_driver_register(&pxa_gpio_driver); } -postcore_initcall(pxa_gpio_init); +postcore_initcall(pxa_gpio_legacy_init); + +static int __init pxa_gpio_dt_init(void) +{ + if (of_have_populated_dt()) + return platform_driver_register(&pxa_gpio_driver); + + return 0; +} +device_initcall(pxa_gpio_dt_init); #ifdef CONFIG_PM static int pxa_gpio_suspend(void) { - struct pxa_gpio_chip *c; + struct pxa_gpio_chip *pchip = pxa_gpio_chip; + struct pxa_gpio_bank *c; int gpio; - for_each_gpio_chip(gpio, c) { + for_each_gpio_bank(gpio, c, pchip) { c->saved_gplr = readl_relaxed(c->regbase + GPLR_OFFSET); c->saved_gpdr = readl_relaxed(c->regbase + GPDR_OFFSET); c->saved_grer = readl_relaxed(c->regbase + GRER_OFFSET); @@ -716,10 +785,11 @@ static int pxa_gpio_suspend(void) static void pxa_gpio_resume(void) { - struct pxa_gpio_chip *c; + struct pxa_gpio_chip *pchip = pxa_gpio_chip; + struct pxa_gpio_bank *c; int gpio; - for_each_gpio_chip(gpio, c) { + for_each_gpio_bank(gpio, c, pchip) { /* restore level with set/clear */ writel_relaxed(c->saved_gplr, c->regbase + GPSR_OFFSET); writel_relaxed(~c->saved_gplr, c->regbase + GPCR_OFFSET); diff --git a/drivers/gpio/gpio-rc5t583.c b/drivers/gpio/gpio-rc5t583.c index 6eabf239676b..f26d9f7d8cdd 100644 --- a/drivers/gpio/gpio-rc5t583.c +++ b/drivers/gpio/gpio-rc5t583.c @@ -132,7 +132,7 @@ static int rc5t583_gpio_probe(struct platform_device *pdev) rc5t583_gpio->gpio_chip.to_irq = rc5t583_gpio_to_irq, rc5t583_gpio->gpio_chip.ngpio = RC5T583_MAX_GPIO, rc5t583_gpio->gpio_chip.can_sleep = true, - rc5t583_gpio->gpio_chip.dev = &pdev->dev; + rc5t583_gpio->gpio_chip.parent = &pdev->dev; rc5t583_gpio->gpio_chip.base = -1; rc5t583_gpio->rc5t583 = rc5t583; diff --git a/drivers/gpio/gpio-rcar.c b/drivers/gpio/gpio-rcar.c index 2a8122444614..624a435e6988 100644 --- a/drivers/gpio/gpio-rcar.c +++ b/drivers/gpio/gpio-rcar.c @@ -25,7 +25,6 @@ #include <linux/module.h> #include <linux/of.h> #include <linux/pinctrl/consumer.h> -#include <linux/platform_data/gpio-rcar.h> #include <linux/platform_device.h> #include <linux/pm_runtime.h> #include <linux/spinlock.h> @@ -34,12 +33,13 @@ struct gpio_rcar_priv { void __iomem *base; spinlock_t lock; - struct gpio_rcar_config config; struct platform_device *pdev; struct gpio_chip gpio_chip; struct irq_chip irq_chip; - unsigned int irq_parent; struct clk *clk; + unsigned int irq_parent; + bool has_both_edge_trigger; + bool needs_clk; }; #define IOINTSEL 0x00 /* General IO/Interrupt Switching Register */ @@ -121,7 +121,7 @@ static void gpio_rcar_config_interrupt_input_mode(struct gpio_rcar_priv *p, gpio_rcar_modify_bit(p, EDGLEVEL, hwirq, !level_trigger); /* Select one edge or both edges in BOTHEDGE */ - if (p->config.has_both_edge_trigger) + if (p->has_both_edge_trigger) gpio_rcar_modify_bit(p, BOTHEDGE, hwirq, both); /* Select "Interrupt Input Mode" in IOINTSEL */ @@ -161,7 +161,7 @@ static int gpio_rcar_irq_set_type(struct irq_data *d, unsigned int type) false); break; case IRQ_TYPE_EDGE_BOTH: - if (!p->config.has_both_edge_trigger) + if (!p->has_both_edge_trigger) return -EINVAL; gpio_rcar_config_interrupt_input_mode(p, hwirq, true, false, true); @@ -318,14 +318,17 @@ static int gpio_rcar_direction_output(struct gpio_chip *chip, unsigned offset, struct gpio_rcar_info { bool has_both_edge_trigger; + bool needs_clk; }; static const struct gpio_rcar_info gpio_rcar_info_gen1 = { .has_both_edge_trigger = false, + .needs_clk = false, }; static const struct gpio_rcar_info gpio_rcar_info_gen2 = { .has_both_edge_trigger = true, + .needs_clk = true, }; static const struct of_device_id gpio_rcar_of_table[] = { @@ -355,39 +358,30 @@ static const struct of_device_id gpio_rcar_of_table[] = { MODULE_DEVICE_TABLE(of, gpio_rcar_of_table); -static int gpio_rcar_parse_pdata(struct gpio_rcar_priv *p) +static int gpio_rcar_parse_dt(struct gpio_rcar_priv *p, unsigned int *npins) { - struct gpio_rcar_config *pdata = dev_get_platdata(&p->pdev->dev); struct device_node *np = p->pdev->dev.of_node; + const struct of_device_id *match; + const struct gpio_rcar_info *info; struct of_phandle_args args; int ret; - if (pdata) { - p->config = *pdata; - } else if (IS_ENABLED(CONFIG_OF) && np) { - const struct of_device_id *match; - const struct gpio_rcar_info *info; - - match = of_match_node(gpio_rcar_of_table, np); - if (!match) - return -EINVAL; + match = of_match_node(gpio_rcar_of_table, np); + if (!match) + return -EINVAL; - info = match->data; + info = match->data; - ret = of_parse_phandle_with_fixed_args(np, "gpio-ranges", 3, 0, - &args); - p->config.number_of_pins = ret == 0 ? args.args[2] - : RCAR_MAX_GPIO_PER_BANK; - p->config.gpio_base = -1; - p->config.has_both_edge_trigger = info->has_both_edge_trigger; - } + ret = of_parse_phandle_with_fixed_args(np, "gpio-ranges", 3, 0, &args); + *npins = ret == 0 ? args.args[2] : RCAR_MAX_GPIO_PER_BANK; + p->has_both_edge_trigger = info->has_both_edge_trigger; + p->needs_clk = info->needs_clk; - if (p->config.number_of_pins == 0 || - p->config.number_of_pins > RCAR_MAX_GPIO_PER_BANK) { + if (*npins == 0 || *npins > RCAR_MAX_GPIO_PER_BANK) { dev_warn(&p->pdev->dev, - "Invalid number of gpio lines %u, using %u\n", - p->config.number_of_pins, RCAR_MAX_GPIO_PER_BANK); - p->config.number_of_pins = RCAR_MAX_GPIO_PER_BANK; + "Invalid number of gpio lines %u, using %u\n", *npins, + RCAR_MAX_GPIO_PER_BANK); + *npins = RCAR_MAX_GPIO_PER_BANK; } return 0; @@ -401,6 +395,7 @@ static int gpio_rcar_probe(struct platform_device *pdev) struct irq_chip *irq_chip; struct device *dev = &pdev->dev; const char *name = dev_name(dev); + unsigned int npins; int ret; p = devm_kzalloc(dev, sizeof(*p), GFP_KERNEL); @@ -410,8 +405,8 @@ static int gpio_rcar_probe(struct platform_device *pdev) p->pdev = pdev; spin_lock_init(&p->lock); - /* Get device configuration from DT node or platform data. */ - ret = gpio_rcar_parse_pdata(p); + /* Get device configuration from DT node */ + ret = gpio_rcar_parse_dt(p, &npins); if (ret < 0) return ret; @@ -419,7 +414,11 @@ static int gpio_rcar_probe(struct platform_device *pdev) p->clk = devm_clk_get(dev, NULL); if (IS_ERR(p->clk)) { - dev_warn(dev, "unable to get clock\n"); + if (p->needs_clk) { + dev_err(dev, "unable to get clock\n"); + ret = PTR_ERR(p->clk); + goto err0; + } p->clk = NULL; } @@ -449,10 +448,10 @@ static int gpio_rcar_probe(struct platform_device *pdev) gpio_chip->direction_output = gpio_rcar_direction_output; gpio_chip->set = gpio_rcar_set; gpio_chip->label = name; - gpio_chip->dev = dev; + gpio_chip->parent = dev; gpio_chip->owner = THIS_MODULE; - gpio_chip->base = p->config.gpio_base; - gpio_chip->ngpio = p->config.number_of_pins; + gpio_chip->base = -1; + gpio_chip->ngpio = npins; irq_chip = &p->irq_chip; irq_chip->name = name; @@ -468,8 +467,8 @@ static int gpio_rcar_probe(struct platform_device *pdev) goto err0; } - ret = gpiochip_irqchip_add(gpio_chip, irq_chip, p->config.irq_base, - handle_level_irq, IRQ_TYPE_NONE); + ret = gpiochip_irqchip_add(gpio_chip, irq_chip, 0, handle_level_irq, + IRQ_TYPE_NONE); if (ret) { dev_err(dev, "cannot add irqchip\n"); goto err1; @@ -483,22 +482,7 @@ static int gpio_rcar_probe(struct platform_device *pdev) goto err1; } - dev_info(dev, "driving %d GPIOs\n", p->config.number_of_pins); - - /* warn in case of mismatch if irq base is specified */ - if (p->config.irq_base) { - ret = irq_find_mapping(gpio_chip->irqdomain, 0); - if (p->config.irq_base != ret) - dev_warn(dev, "irq base mismatch (%u/%u)\n", - p->config.irq_base, ret); - } - - if (p->config.pctl_name) { - ret = gpiochip_add_pin_range(gpio_chip, p->config.pctl_name, 0, - gpio_chip->base, gpio_chip->ngpio); - if (ret < 0) - dev_warn(dev, "failed to add pin range\n"); - } + dev_info(dev, "driving %d GPIOs\n", npins); return 0; diff --git a/drivers/gpio/gpio-sch.c b/drivers/gpio/gpio-sch.c index b72906f5b999..a8a333ade9aa 100644 --- a/drivers/gpio/gpio-sch.c +++ b/drivers/gpio/gpio-sch.c @@ -171,7 +171,7 @@ static int sch_gpio_probe(struct platform_device *pdev) sch->iobase = res->start; sch->chip = sch_gpio_chip; sch->chip.label = dev_name(&pdev->dev); - sch->chip.dev = &pdev->dev; + sch->chip.parent = &pdev->dev; switch (pdev->id) { case PCI_DEVICE_ID_INTEL_SCH_LPC: diff --git a/drivers/gpio/gpio-sch311x.c b/drivers/gpio/gpio-sch311x.c index 0cb11413e814..b454792de778 100644 --- a/drivers/gpio/gpio-sch311x.c +++ b/drivers/gpio/gpio-sch311x.c @@ -149,7 +149,7 @@ static int sch311x_gpio_request(struct gpio_chip *chip, unsigned offset) if (!request_region(block->runtime_reg + block->config_regs[offset], 1, DRV_NAME)) { - dev_err(chip->dev, "Failed to request region 0x%04x.\n", + dev_err(chip->parent, "Failed to request region 0x%04x.\n", block->runtime_reg + block->config_regs[offset]); return -EBUSY; } @@ -229,7 +229,7 @@ static int sch311x_gpio_direction_out(struct gpio_chip *chip, unsigned offset, static int sch311x_gpio_probe(struct platform_device *pdev) { - struct sch311x_pdev_data *pdata = pdev->dev.platform_data; + struct sch311x_pdev_data *pdata = dev_get_platdata(&pdev->dev); struct sch311x_gpio_priv *priv; struct sch311x_gpio_block *block; int err, i; @@ -261,7 +261,7 @@ static int sch311x_gpio_probe(struct platform_device *pdev) block->chip.get = sch311x_gpio_get; block->chip.set = sch311x_gpio_set; block->chip.ngpio = 8; - block->chip.dev = &pdev->dev; + block->chip.parent = &pdev->dev; block->chip.base = sch311x_gpio_blocks[i].base; block->config_regs = sch311x_gpio_blocks[i].config_regs; block->data_reg = sch311x_gpio_blocks[i].data_reg; @@ -289,7 +289,7 @@ exit_err: static int sch311x_gpio_remove(struct platform_device *pdev) { - struct sch311x_pdev_data *pdata = pdev->dev.platform_data; + struct sch311x_pdev_data *pdata = dev_get_platdata(&pdev->dev); struct sch311x_gpio_priv *priv = platform_get_drvdata(pdev); int i; diff --git a/drivers/gpio/gpio-spear-spics.c b/drivers/gpio/gpio-spear-spics.c index 69ffca5b073b..bd436b7f86e1 100644 --- a/drivers/gpio/gpio-spear-spics.c +++ b/drivers/gpio/gpio-spear-spics.c @@ -164,7 +164,7 @@ static int spics_gpio_probe(struct platform_device *pdev) spics->chip.get = spics_get_value; spics->chip.set = spics_set_value; spics->chip.label = dev_name(&pdev->dev); - spics->chip.dev = &pdev->dev; + spics->chip.parent = &pdev->dev; spics->chip.owner = THIS_MODULE; spics->last_off = -1; diff --git a/drivers/gpio/gpio-stmpe.c b/drivers/gpio/gpio-stmpe.c index dabfb99dddef..9e471979aa9e 100644 --- a/drivers/gpio/gpio-stmpe.c +++ b/drivers/gpio/gpio-stmpe.c @@ -356,7 +356,7 @@ static int stmpe_gpio_probe(struct platform_device *pdev) stmpe_gpio->stmpe = stmpe; stmpe_gpio->chip = template_chip; stmpe_gpio->chip.ngpio = stmpe->num_gpios; - stmpe_gpio->chip.dev = &pdev->dev; + stmpe_gpio->chip.parent = &pdev->dev; stmpe_gpio->chip.of_node = np; stmpe_gpio->chip.base = -1; diff --git a/drivers/gpio/gpio-stp-xway.c b/drivers/gpio/gpio-stp-xway.c index 81bdbe7ba2a4..c250f21b9e40 100644 --- a/drivers/gpio/gpio-stp-xway.c +++ b/drivers/gpio/gpio-stp-xway.c @@ -139,7 +139,7 @@ static int xway_stp_request(struct gpio_chip *gc, unsigned gpio) container_of(gc, struct xway_stp, gc); if ((gpio < 8) && (chip->reserved & BIT(gpio))) { - dev_err(gc->dev, "GPIO %d is driven by hardware\n", gpio); + dev_err(gc->parent, "GPIO %d is driven by hardware\n", gpio); return -ENODEV; } @@ -214,7 +214,7 @@ static int xway_stp_probe(struct platform_device *pdev) if (IS_ERR(chip->virt)) return PTR_ERR(chip->virt); - chip->gc.dev = &pdev->dev; + chip->gc.parent = &pdev->dev; chip->gc.label = "stp-xway"; chip->gc.direction_output = xway_stp_dir_out; chip->gc.set = xway_stp_set; diff --git a/drivers/gpio/gpio-sx150x.c b/drivers/gpio/gpio-sx150x.c index 76f920173a2f..cf12d8e3ce3e 100644 --- a/drivers/gpio/gpio-sx150x.c +++ b/drivers/gpio/gpio-sx150x.c @@ -473,7 +473,7 @@ static void sx150x_init_chip(struct sx150x_chip *chip, chip->client = client; chip->dev_cfg = &sx150x_devices[driver_data]; - chip->gpio_chip.dev = &client->dev; + chip->gpio_chip.parent = &client->dev; chip->gpio_chip.label = client->name; chip->gpio_chip.direction_input = sx150x_gpio_direction_input; chip->gpio_chip.direction_output = sx150x_gpio_direction_output; @@ -680,7 +680,6 @@ static int sx150x_remove(struct i2c_client *client) static struct i2c_driver sx150x_driver = { .driver = { .name = "sx150x", - .owner = THIS_MODULE, .of_match_table = of_match_ptr(sx150x_of_match), }, .probe = sx150x_probe, diff --git a/drivers/gpio/gpio-syscon.c b/drivers/gpio/gpio-syscon.c index 7b25fdf64802..333d5af4abd1 100644 --- a/drivers/gpio/gpio-syscon.c +++ b/drivers/gpio/gpio-syscon.c @@ -159,7 +159,7 @@ static void keystone_gpio_set(struct gpio_chip *chip, unsigned offset, int val) BIT(offs % SYSCON_REG_BITS) | KEYSTONE_LOCK_BIT, BIT(offs % SYSCON_REG_BITS) | KEYSTONE_LOCK_BIT); if (ret < 0) - dev_err(chip->dev, "gpio write failed ret(%d)\n", ret); + dev_err(chip->parent, "gpio write failed ret(%d)\n", ret); } static const struct syscon_gpio_data keystone_dsp_gpio = { @@ -228,7 +228,7 @@ static int syscon_gpio_probe(struct platform_device *pdev) priv->dir_reg_offset <<= 3; } - priv->chip.dev = dev; + priv->chip.parent = dev; priv->chip.owner = THIS_MODULE; priv->chip.label = dev_name(dev); priv->chip.base = -1; diff --git a/drivers/gpio/gpio-tb10x.c b/drivers/gpio/gpio-tb10x.c index 4356e6c20fc5..1a7c3efae5d8 100644 --- a/drivers/gpio/gpio-tb10x.c +++ b/drivers/gpio/gpio-tb10x.c @@ -197,7 +197,7 @@ static int tb10x_gpio_probe(struct platform_device *pdev) return PTR_ERR(tb10x_gpio->base); tb10x_gpio->gc.label = of_node_full_name(dn); - tb10x_gpio->gc.dev = &pdev->dev; + tb10x_gpio->gc.parent = &pdev->dev; tb10x_gpio->gc.owner = THIS_MODULE; tb10x_gpio->gc.direction_input = tb10x_gpio_direction_in; tb10x_gpio->gc.get = tb10x_gpio_get; diff --git a/drivers/gpio/gpio-tc3589x.c b/drivers/gpio/gpio-tc3589x.c index d1d585ddb9ab..7c1537ed6dff 100644 --- a/drivers/gpio/gpio-tc3589x.c +++ b/drivers/gpio/gpio-tc3589x.c @@ -258,7 +258,7 @@ static int tc3589x_gpio_probe(struct platform_device *pdev) tc3589x_gpio->chip = template_chip; tc3589x_gpio->chip.ngpio = tc3589x->num_gpio; - tc3589x_gpio->chip.dev = &pdev->dev; + tc3589x_gpio->chip.parent = &pdev->dev; tc3589x_gpio->chip.base = -1; tc3589x_gpio->chip.of_node = np; diff --git a/drivers/gpio/gpio-timberdale.c b/drivers/gpio/gpio-timberdale.c index 30653e6319e9..dda8f21811eb 100644 --- a/drivers/gpio/gpio-timberdale.c +++ b/drivers/gpio/gpio-timberdale.c @@ -268,7 +268,7 @@ static int timbgpio_probe(struct platform_device *pdev) gc->label = dev_name(&pdev->dev); gc->owner = THIS_MODULE; - gc->dev = &pdev->dev; + gc->parent = &pdev->dev; gc->direction_input = timbgpio_gpio_direction_input; gc->get = timbgpio_gpio_get; gc->direction_output = timbgpio_gpio_direction_output; diff --git a/drivers/gpio/gpio-tps6586x.c b/drivers/gpio/gpio-tps6586x.c index 9c9238e838a9..89b2249100b0 100644 --- a/drivers/gpio/gpio-tps6586x.c +++ b/drivers/gpio/gpio-tps6586x.c @@ -104,7 +104,7 @@ static int tps6586x_gpio_probe(struct platform_device *pdev) tps6586x_gpio->gpio_chip.owner = THIS_MODULE; tps6586x_gpio->gpio_chip.label = pdev->name; - tps6586x_gpio->gpio_chip.dev = &pdev->dev; + tps6586x_gpio->gpio_chip.parent = &pdev->dev; tps6586x_gpio->gpio_chip.ngpio = 4; tps6586x_gpio->gpio_chip.can_sleep = true; diff --git a/drivers/gpio/gpio-tps65910.c b/drivers/gpio/gpio-tps65910.c index 88f1f5ff4e96..83894c0387fb 100644 --- a/drivers/gpio/gpio-tps65910.c +++ b/drivers/gpio/gpio-tps65910.c @@ -146,7 +146,7 @@ static int tps65910_gpio_probe(struct platform_device *pdev) tps65910_gpio->gpio_chip.direction_output = tps65910_gpio_output; tps65910_gpio->gpio_chip.set = tps65910_gpio_set; tps65910_gpio->gpio_chip.get = tps65910_gpio_get; - tps65910_gpio->gpio_chip.dev = &pdev->dev; + tps65910_gpio->gpio_chip.parent = &pdev->dev; #ifdef CONFIG_OF_GPIO tps65910_gpio->gpio_chip.of_node = tps65910->dev->of_node; #endif diff --git a/drivers/gpio/gpio-tps65912.c b/drivers/gpio/gpio-tps65912.c index 9cdbc0c9cb2d..0f073ffa74cf 100644 --- a/drivers/gpio/gpio-tps65912.c +++ b/drivers/gpio/gpio-tps65912.c @@ -104,7 +104,7 @@ static int tps65912_gpio_probe(struct platform_device *pdev) tps65912_gpio->tps65912 = tps65912; tps65912_gpio->gpio_chip = template_chip; - tps65912_gpio->gpio_chip.dev = &pdev->dev; + tps65912_gpio->gpio_chip.parent = &pdev->dev; if (pdata && pdata->gpio_base) tps65912_gpio->gpio_chip.base = pdata->gpio_base; diff --git a/drivers/gpio/gpio-ts5500.c b/drivers/gpio/gpio-ts5500.c index b29a102d136b..aafe7910e030 100644 --- a/drivers/gpio/gpio-ts5500.c +++ b/drivers/gpio/gpio-ts5500.c @@ -315,7 +315,8 @@ static void ts5500_disable_irq(struct ts5500_priv *priv) else if (priv->hwirq == 1) ts5500_clear_mask(BIT(6), 0x7d); /* LCD_RS on IRQ1 */ else - dev_err(priv->gpio_chip.dev, "invalid hwirq %d\n", priv->hwirq); + dev_err(priv->gpio_chip.parent, "invalid hwirq %d\n", + priv->hwirq); spin_unlock_irqrestore(&priv->lock, flags); } @@ -346,7 +347,7 @@ static int ts5500_dio_probe(struct platform_device *pdev) priv->gpio_chip.owner = THIS_MODULE; priv->gpio_chip.label = name; - priv->gpio_chip.dev = dev; + priv->gpio_chip.parent = dev; priv->gpio_chip.direction_input = ts5500_gpio_input; priv->gpio_chip.direction_output = ts5500_gpio_output; priv->gpio_chip.get = ts5500_gpio_get; diff --git a/drivers/gpio/gpio-twl4030.c b/drivers/gpio/gpio-twl4030.c index 9e1dbb9877c1..14f40bf64e34 100644 --- a/drivers/gpio/gpio-twl4030.c +++ b/drivers/gpio/gpio-twl4030.c @@ -256,7 +256,7 @@ static int twl_request(struct gpio_chip *chip, unsigned offset) /* optionally have the first two GPIOs switch vMMC1 * and vMMC2 power supplies based on card presence. */ - pdata = dev_get_platdata(chip->dev); + pdata = dev_get_platdata(chip->parent); if (pdata) value |= pdata->mmc_cd & 0x03; @@ -509,7 +509,7 @@ no_irqs: priv->gpio_chip = template_chip; priv->gpio_chip.base = -1; priv->gpio_chip.ngpio = TWL4030_GPIO_MAX; - priv->gpio_chip.dev = &pdev->dev; + priv->gpio_chip.parent = &pdev->dev; mutex_init(&priv->mutex); diff --git a/drivers/gpio/gpio-twl6040.c b/drivers/gpio/gpio-twl6040.c index c946e7eef3ee..2da7c5f70034 100644 --- a/drivers/gpio/gpio-twl6040.c +++ b/drivers/gpio/gpio-twl6040.c @@ -36,7 +36,7 @@ static struct gpio_chip twl6040gpo_chip; static int twl6040gpo_get(struct gpio_chip *chip, unsigned offset) { - struct twl6040 *twl6040 = dev_get_drvdata(chip->dev->parent); + struct twl6040 *twl6040 = dev_get_drvdata(chip->parent->parent); int ret = 0; ret = twl6040_reg_read(twl6040, TWL6040_REG_GPOCTL); @@ -55,7 +55,7 @@ static int twl6040gpo_direction_out(struct gpio_chip *chip, unsigned offset, static void twl6040gpo_set(struct gpio_chip *chip, unsigned offset, int value) { - struct twl6040 *twl6040 = dev_get_drvdata(chip->dev->parent); + struct twl6040 *twl6040 = dev_get_drvdata(chip->parent->parent); int ret; u8 gpoctl; @@ -95,7 +95,7 @@ static int gpo_twl6040_probe(struct platform_device *pdev) else twl6040gpo_chip.ngpio = 1; /* twl6041 have 1 GPO */ - twl6040gpo_chip.dev = &pdev->dev; + twl6040gpo_chip.parent = &pdev->dev; #ifdef CONFIG_OF_GPIO twl6040gpo_chip.of_node = twl6040_core_dev->of_node; #endif diff --git a/drivers/gpio/gpio-tz1090-pdc.c b/drivers/gpio/gpio-tz1090-pdc.c index 3623d009d808..0a01c8736aff 100644 --- a/drivers/gpio/gpio-tz1090-pdc.c +++ b/drivers/gpio/gpio-tz1090-pdc.c @@ -188,7 +188,7 @@ static int tz1090_pdc_gpio_probe(struct platform_device *pdev) /* Set up GPIO chip */ priv->chip.label = "tz1090-pdc-gpio"; - priv->chip.dev = &pdev->dev; + priv->chip.parent = &pdev->dev; priv->chip.direction_input = tz1090_pdc_gpio_direction_input; priv->chip.direction_output = tz1090_pdc_gpio_direction_output; priv->chip.get = tz1090_pdc_gpio_get; diff --git a/drivers/gpio/gpio-tz1090.c b/drivers/gpio/gpio-tz1090.c index 87bb1b1eee8d..79ef6e1ce568 100644 --- a/drivers/gpio/gpio-tz1090.c +++ b/drivers/gpio/gpio-tz1090.c @@ -425,7 +425,7 @@ static int tz1090_gpio_bank_probe(struct tz1090_gpio_bank_info *info) snprintf(bank->label, sizeof(bank->label), "tz1090-gpio-%u", info->index); bank->chip.label = bank->label; - bank->chip.dev = dev; + bank->chip.parent = dev; bank->chip.direction_input = tz1090_gpio_direction_input; bank->chip.direction_output = tz1090_gpio_direction_output; bank->chip.get = tz1090_gpio_get; diff --git a/drivers/gpio/gpio-vf610.c b/drivers/gpio/gpio-vf610.c index 87b950cec6ec..9031e60c815c 100644 --- a/drivers/gpio/gpio-vf610.c +++ b/drivers/gpio/gpio-vf610.c @@ -249,7 +249,7 @@ static int vf610_gpio_probe(struct platform_device *pdev) gc = &port->gc; gc->of_node = np; - gc->dev = dev; + gc->parent = dev; gc->label = "vf610-gpio"; gc->ngpio = VF610_GPIO_PER_PORT; gc->base = of_alias_get_id(np, "gpio") * VF610_GPIO_PER_PORT; diff --git a/drivers/gpio/gpio-viperboard.c b/drivers/gpio/gpio-viperboard.c index e2a11f27807f..26e7edb74f42 100644 --- a/drivers/gpio/gpio-viperboard.c +++ b/drivers/gpio/gpio-viperboard.c @@ -173,7 +173,7 @@ static void vprbrd_gpioa_set(struct gpio_chip *chip, mutex_unlock(&vb->lock); if (ret != sizeof(struct vprbrd_gpioa_msg)) - dev_err(chip->dev, "usb error setting pin value\n"); + dev_err(chip->parent, "usb error setting pin value\n"); } } @@ -345,7 +345,7 @@ static void vprbrd_gpiob_set(struct gpio_chip *chip, mutex_unlock(&vb->lock); if (ret != sizeof(struct vprbrd_gpiob_msg)) - dev_err(chip->dev, "usb error setting pin value\n"); + dev_err(chip->parent, "usb error setting pin value\n"); } } @@ -366,7 +366,7 @@ static int vprbrd_gpiob_direction_input(struct gpio_chip *chip, mutex_unlock(&vb->lock); if (ret) - dev_err(chip->dev, "usb error setting pin to input\n"); + dev_err(chip->parent, "usb error setting pin to input\n"); return ret; } @@ -385,7 +385,7 @@ static int vprbrd_gpiob_direction_output(struct gpio_chip *chip, ret = vprbrd_gpiob_setdir(vb, offset, 1); if (ret) - dev_err(chip->dev, "usb error setting pin to output\n"); + dev_err(chip->parent, "usb error setting pin to output\n"); mutex_unlock(&vb->lock); @@ -409,7 +409,7 @@ static int vprbrd_gpio_probe(struct platform_device *pdev) vb_gpio->vb = vb; /* registering gpio a */ vb_gpio->gpioa.label = "viperboard gpio a"; - vb_gpio->gpioa.dev = &pdev->dev; + vb_gpio->gpioa.parent = &pdev->dev; vb_gpio->gpioa.owner = THIS_MODULE; vb_gpio->gpioa.base = -1; vb_gpio->gpioa.ngpio = 16; @@ -420,13 +420,13 @@ static int vprbrd_gpio_probe(struct platform_device *pdev) vb_gpio->gpioa.direction_output = vprbrd_gpioa_direction_output; ret = gpiochip_add(&vb_gpio->gpioa); if (ret < 0) { - dev_err(vb_gpio->gpioa.dev, "could not add gpio a"); + dev_err(vb_gpio->gpioa.parent, "could not add gpio a"); goto err_gpioa; } /* registering gpio b */ vb_gpio->gpiob.label = "viperboard gpio b"; - vb_gpio->gpiob.dev = &pdev->dev; + vb_gpio->gpiob.parent = &pdev->dev; vb_gpio->gpiob.owner = THIS_MODULE; vb_gpio->gpiob.base = -1; vb_gpio->gpiob.ngpio = 16; @@ -437,7 +437,7 @@ static int vprbrd_gpio_probe(struct platform_device *pdev) vb_gpio->gpiob.direction_output = vprbrd_gpiob_direction_output; ret = gpiochip_add(&vb_gpio->gpiob); if (ret < 0) { - dev_err(vb_gpio->gpiob.dev, "could not add gpio b"); + dev_err(vb_gpio->gpiob.parent, "could not add gpio b"); goto err_gpiob; } diff --git a/drivers/gpio/gpio-vr41xx.c b/drivers/gpio/gpio-vr41xx.c index c1caa459c02d..1947531b7cf5 100644 --- a/drivers/gpio/gpio-vr41xx.c +++ b/drivers/gpio/gpio-vr41xx.c @@ -139,7 +139,7 @@ static void unmask_giuint_low(struct irq_data *d) static unsigned int startup_giuint(struct irq_data *data) { if (gpiochip_lock_as_irq(&vr41xx_gpio_chip, data->hwirq)) - dev_err(vr41xx_gpio_chip.dev, + dev_err(vr41xx_gpio_chip.parent, "unable to lock HW IRQ %lu for IRQ\n", data->hwirq); /* Satisfy the .enable semantics by unmasking the line */ @@ -542,7 +542,7 @@ static int giu_probe(struct platform_device *pdev) if (!giu_base) return -ENOMEM; - vr41xx_gpio_chip.dev = &pdev->dev; + vr41xx_gpio_chip.parent = &pdev->dev; ret = gpiochip_add(&vr41xx_gpio_chip); if (!ret) { diff --git a/drivers/gpio/gpio-wm831x.c b/drivers/gpio/gpio-wm831x.c index 58ce75c188b7..2e73e4b52c69 100644 --- a/drivers/gpio/gpio-wm831x.c +++ b/drivers/gpio/gpio-wm831x.c @@ -258,7 +258,7 @@ static int wm831x_gpio_probe(struct platform_device *pdev) wm831x_gpio->wm831x = wm831x; wm831x_gpio->gpio_chip = template_chip; wm831x_gpio->gpio_chip.ngpio = wm831x->num_gpio; - wm831x_gpio->gpio_chip.dev = &pdev->dev; + wm831x_gpio->gpio_chip.parent = &pdev->dev; if (pdata && pdata->gpio_base) wm831x_gpio->gpio_chip.base = pdata->gpio_base; else diff --git a/drivers/gpio/gpio-wm8350.c b/drivers/gpio/gpio-wm8350.c index 060b89303bb6..1e3d8da61ff3 100644 --- a/drivers/gpio/gpio-wm8350.c +++ b/drivers/gpio/gpio-wm8350.c @@ -124,7 +124,7 @@ static int wm8350_gpio_probe(struct platform_device *pdev) wm8350_gpio->wm8350 = wm8350; wm8350_gpio->gpio_chip = template_chip; wm8350_gpio->gpio_chip.ngpio = 13; - wm8350_gpio->gpio_chip.dev = &pdev->dev; + wm8350_gpio->gpio_chip.parent = &pdev->dev; if (pdata && pdata->gpio_base) wm8350_gpio->gpio_chip.base = pdata->gpio_base; else diff --git a/drivers/gpio/gpio-wm8994.c b/drivers/gpio/gpio-wm8994.c index 6f5e42db4b9e..de73c80163c1 100644 --- a/drivers/gpio/gpio-wm8994.c +++ b/drivers/gpio/gpio-wm8994.c @@ -260,7 +260,7 @@ static int wm8994_gpio_probe(struct platform_device *pdev) wm8994_gpio->wm8994 = wm8994; wm8994_gpio->gpio_chip = template_chip; wm8994_gpio->gpio_chip.ngpio = WM8994_GPIO_MAX; - wm8994_gpio->gpio_chip.dev = &pdev->dev; + wm8994_gpio->gpio_chip.parent = &pdev->dev; if (pdata && pdata->gpio_base) wm8994_gpio->gpio_chip.base = pdata->gpio_base; else diff --git a/drivers/gpio/gpio-xgene.c b/drivers/gpio/gpio-xgene.c index 18a8182d4fec..b8ceb71885f6 100644 --- a/drivers/gpio/gpio-xgene.c +++ b/drivers/gpio/gpio-xgene.c @@ -188,7 +188,7 @@ static int xgene_gpio_probe(struct platform_device *pdev) gpio->chip.ngpio = XGENE_MAX_GPIOS; spin_lock_init(&gpio->lock); - gpio->chip.dev = &pdev->dev; + gpio->chip.parent = &pdev->dev; gpio->chip.direction_input = xgene_gpio_dir_in; gpio->chip.direction_output = xgene_gpio_dir_out; gpio->chip.get = xgene_gpio_get; diff --git a/drivers/gpio/gpio-xilinx.c b/drivers/gpio/gpio-xilinx.c index d5284dfe01fe..5c2971e1cb08 100644 --- a/drivers/gpio/gpio-xilinx.c +++ b/drivers/gpio/gpio-xilinx.c @@ -305,7 +305,7 @@ static int xgpio_probe(struct platform_device *pdev) } chip->mmchip.gc.ngpio = chip->gpio_width[0] + chip->gpio_width[1]; - chip->mmchip.gc.dev = &pdev->dev; + chip->mmchip.gc.parent = &pdev->dev; chip->mmchip.gc.direction_input = xgpio_dir_in; chip->mmchip.gc.direction_output = xgpio_dir_out; chip->mmchip.gc.get = xgpio_get; diff --git a/drivers/gpio/gpio-xlp.c b/drivers/gpio/gpio-xlp.c index bc06a2cd2c1d..3f31aac2ba3c 100644 --- a/drivers/gpio/gpio-xlp.c +++ b/drivers/gpio/gpio-xlp.c @@ -373,7 +373,7 @@ static int xlp_gpio_probe(struct platform_device *pdev) gc->owner = THIS_MODULE; gc->label = dev_name(&pdev->dev); gc->base = 0; - gc->dev = &pdev->dev; + gc->parent = &pdev->dev; gc->ngpio = ngpio; gc->of_node = pdev->dev.of_node; gc->direction_output = xlp_gpio_dir_output; diff --git a/drivers/gpio/gpio-zevio.c b/drivers/gpio/gpio-zevio.c index 6f02d7c4cc57..65b61dcc6268 100644 --- a/drivers/gpio/gpio-zevio.c +++ b/drivers/gpio/gpio-zevio.c @@ -185,7 +185,7 @@ static int zevio_gpio_probe(struct platform_device *pdev) /* Copy our reference */ controller->chip.gc = zevio_gpio_chip; - controller->chip.gc.dev = &pdev->dev; + controller->chip.gc.parent = &pdev->dev; status = of_mm_gpiochip_add(pdev->dev.of_node, &(controller->chip)); if (status) { @@ -199,7 +199,7 @@ static int zevio_gpio_probe(struct platform_device *pdev) for (i = 0; i < controller->chip.gc.ngpio; i += 8) zevio_gpio_port_set(controller, i, ZEVIO_GPIO_INT_MASK, 0xFF); - dev_dbg(controller->chip.gc.dev, "ZEVIO GPIO controller set up!\n"); + dev_dbg(controller->chip.gc.parent, "ZEVIO GPIO controller set up!\n"); return 0; } diff --git a/drivers/gpio/gpio-zx.c b/drivers/gpio/gpio-zx.c index 1dcf7a66dd36..ab2e54fa46cf 100644 --- a/drivers/gpio/gpio-zx.c +++ b/drivers/gpio/gpio-zx.c @@ -245,7 +245,7 @@ static int zx_gpio_probe(struct platform_device *pdev) chip->gc.base = ZX_GPIO_NR * id; chip->gc.ngpio = ZX_GPIO_NR; chip->gc.label = dev_name(dev); - chip->gc.dev = dev; + chip->gc.parent = dev; chip->gc.owner = THIS_MODULE; ret = gpiochip_add(&chip->gc); diff --git a/drivers/gpio/gpio-zynq.c b/drivers/gpio/gpio-zynq.c index 8abeacac5885..ba1150744b61 100644 --- a/drivers/gpio/gpio-zynq.c +++ b/drivers/gpio/gpio-zynq.c @@ -592,7 +592,7 @@ static int zynq_gpio_request(struct gpio_chip *chip, unsigned offset) { int ret; - ret = pm_runtime_get_sync(chip->dev); + ret = pm_runtime_get_sync(chip->parent); /* * If the device is already active pm_runtime_get() will return 1 on @@ -603,7 +603,7 @@ static int zynq_gpio_request(struct gpio_chip *chip, unsigned offset) static void zynq_gpio_free(struct gpio_chip *chip, unsigned offset) { - pm_runtime_put(chip->dev); + pm_runtime_put(chip->parent); } static const struct dev_pm_ops zynq_gpio_dev_pm_ops = { @@ -698,7 +698,7 @@ static int zynq_gpio_probe(struct platform_device *pdev) chip = &gpio->chip; chip->label = gpio->p_data->label; chip->owner = THIS_MODULE; - chip->dev = &pdev->dev; + chip->parent = &pdev->dev; chip->get = zynq_gpio_get_value; chip->set = zynq_gpio_set_value; chip->request = zynq_gpio_request; @@ -708,23 +708,23 @@ static int zynq_gpio_probe(struct platform_device *pdev) chip->base = -1; chip->ngpio = gpio->p_data->ngpio; - /* Enable GPIO clock */ + /* Retrieve GPIO clock */ gpio->clk = devm_clk_get(&pdev->dev, NULL); if (IS_ERR(gpio->clk)) { dev_err(&pdev->dev, "input clock not found.\n"); return PTR_ERR(gpio->clk); } - ret = clk_prepare_enable(gpio->clk); - if (ret) { - dev_err(&pdev->dev, "Unable to enable clock.\n"); + + pm_runtime_enable(&pdev->dev); + ret = pm_runtime_get_sync(&pdev->dev); + if (ret < 0) return ret; - } /* report a bug if gpio chip registration fails */ ret = gpiochip_add(chip); if (ret) { dev_err(&pdev->dev, "Failed to add gpio chip\n"); - goto err_disable_clk; + goto err_pm_put; } /* disable interrupts for all banks */ @@ -742,15 +742,14 @@ static int zynq_gpio_probe(struct platform_device *pdev) gpiochip_set_chained_irqchip(chip, &zynq_gpio_edge_irqchip, gpio->irq, zynq_gpio_irqhandler); - pm_runtime_set_active(&pdev->dev); - pm_runtime_enable(&pdev->dev); + pm_runtime_put(&pdev->dev); return 0; err_rm_gpiochip: gpiochip_remove(chip); -err_disable_clk: - clk_disable_unprepare(gpio->clk); +err_pm_put: + pm_runtime_put(&pdev->dev); return ret; } diff --git a/drivers/gpio/gpiolib-acpi.c b/drivers/gpio/gpiolib-acpi.c index 16a7b6816744..07e571a1a377 100644 --- a/drivers/gpio/gpiolib-acpi.c +++ b/drivers/gpio/gpiolib-acpi.c @@ -51,10 +51,10 @@ struct acpi_gpio_chip { static int acpi_gpiochip_find(struct gpio_chip *gc, void *data) { - if (!gc->dev) + if (!gc->parent) return false; - return ACPI_HANDLE(gc->dev) == data; + return ACPI_HANDLE(gc->parent) == data; } #ifdef CONFIG_PINCTRL @@ -184,7 +184,7 @@ static acpi_status acpi_gpiochip_request_interrupt(struct acpi_resource *ares, if (agpio->connection_type != ACPI_RESOURCE_GPIO_TYPE_INT) return AE_OK; - handle = ACPI_HANDLE(chip->dev); + handle = ACPI_HANDLE(chip->parent); pin = agpio->pin_table[0]; if (pin <= 255) { @@ -208,7 +208,7 @@ static acpi_status acpi_gpiochip_request_interrupt(struct acpi_resource *ares, desc = gpiochip_request_own_desc(chip, pin, "ACPI:Event"); if (IS_ERR(desc)) { - dev_err(chip->dev, "Failed to request GPIO\n"); + dev_err(chip->parent, "Failed to request GPIO\n"); return AE_ERROR; } @@ -216,13 +216,13 @@ static acpi_status acpi_gpiochip_request_interrupt(struct acpi_resource *ares, ret = gpiochip_lock_as_irq(chip, pin); if (ret) { - dev_err(chip->dev, "Failed to lock GPIO as interrupt\n"); + dev_err(chip->parent, "Failed to lock GPIO as interrupt\n"); goto fail_free_desc; } irq = gpiod_to_irq(desc); if (irq < 0) { - dev_err(chip->dev, "Failed to translate GPIO to IRQ\n"); + dev_err(chip->parent, "Failed to translate GPIO to IRQ\n"); goto fail_unlock_irq; } @@ -259,7 +259,8 @@ static acpi_status acpi_gpiochip_request_interrupt(struct acpi_resource *ares, ret = request_threaded_irq(event->irq, NULL, handler, irqflags, "ACPI:Event", event); if (ret) { - dev_err(chip->dev, "Failed to setup interrupt handler for %d\n", + dev_err(chip->parent, + "Failed to setup interrupt handler for %d\n", event->irq); goto fail_free_event; } @@ -293,10 +294,10 @@ void acpi_gpiochip_request_interrupts(struct gpio_chip *chip) acpi_handle handle; acpi_status status; - if (!chip->dev || !chip->to_irq) + if (!chip->parent || !chip->to_irq) return; - handle = ACPI_HANDLE(chip->dev); + handle = ACPI_HANDLE(chip->parent); if (!handle) return; @@ -323,10 +324,10 @@ void acpi_gpiochip_free_interrupts(struct gpio_chip *chip) acpi_handle handle; acpi_status status; - if (!chip->dev || !chip->to_irq) + if (!chip->parent || !chip->to_irq) return; - handle = ACPI_HANDLE(chip->dev); + handle = ACPI_HANDLE(chip->parent); if (!handle) return; @@ -748,7 +749,7 @@ out: static void acpi_gpiochip_request_regions(struct acpi_gpio_chip *achip) { struct gpio_chip *chip = achip->chip; - acpi_handle handle = ACPI_HANDLE(chip->dev); + acpi_handle handle = ACPI_HANDLE(chip->parent); acpi_status status; INIT_LIST_HEAD(&achip->conns); @@ -757,20 +758,22 @@ static void acpi_gpiochip_request_regions(struct acpi_gpio_chip *achip) acpi_gpio_adr_space_handler, NULL, achip); if (ACPI_FAILURE(status)) - dev_err(chip->dev, "Failed to install GPIO OpRegion handler\n"); + dev_err(chip->parent, + "Failed to install GPIO OpRegion handler\n"); } static void acpi_gpiochip_free_regions(struct acpi_gpio_chip *achip) { struct gpio_chip *chip = achip->chip; - acpi_handle handle = ACPI_HANDLE(chip->dev); + acpi_handle handle = ACPI_HANDLE(chip->parent); struct acpi_gpio_connection *conn, *tmp; acpi_status status; status = acpi_remove_address_space_handler(handle, ACPI_ADR_SPACE_GPIO, acpi_gpio_adr_space_handler); if (ACPI_FAILURE(status)) { - dev_err(chip->dev, "Failed to remove GPIO OpRegion handler\n"); + dev_err(chip->parent, + "Failed to remove GPIO OpRegion handler\n"); return; } @@ -787,16 +790,16 @@ void acpi_gpiochip_add(struct gpio_chip *chip) acpi_handle handle; acpi_status status; - if (!chip || !chip->dev) + if (!chip || !chip->parent) return; - handle = ACPI_HANDLE(chip->dev); + handle = ACPI_HANDLE(chip->parent); if (!handle) return; acpi_gpio = kzalloc(sizeof(*acpi_gpio), GFP_KERNEL); if (!acpi_gpio) { - dev_err(chip->dev, + dev_err(chip->parent, "Failed to allocate memory for ACPI GPIO chip\n"); return; } @@ -806,7 +809,7 @@ void acpi_gpiochip_add(struct gpio_chip *chip) status = acpi_attach_data(handle, acpi_gpio_chip_dh, acpi_gpio); if (ACPI_FAILURE(status)) { - dev_err(chip->dev, "Failed to attach ACPI GPIO chip\n"); + dev_err(chip->parent, "Failed to attach ACPI GPIO chip\n"); kfree(acpi_gpio); return; } @@ -820,16 +823,16 @@ void acpi_gpiochip_remove(struct gpio_chip *chip) acpi_handle handle; acpi_status status; - if (!chip || !chip->dev) + if (!chip || !chip->parent) return; - handle = ACPI_HANDLE(chip->dev); + handle = ACPI_HANDLE(chip->parent); if (!handle) return; status = acpi_get_data(handle, acpi_gpio_chip_dh, (void **)&acpi_gpio); if (ACPI_FAILURE(status)) { - dev_warn(chip->dev, "Failed to retrieve ACPI GPIO chip\n"); + dev_warn(chip->parent, "Failed to retrieve ACPI GPIO chip\n"); return; } @@ -922,3 +925,46 @@ int acpi_gpio_count(struct device *dev, const char *con_id) } return count; } + +struct acpi_crs_lookup { + struct list_head node; + struct acpi_device *adev; + const char *con_id; +}; + +static DEFINE_MUTEX(acpi_crs_lookup_lock); +static LIST_HEAD(acpi_crs_lookup_list); + +bool acpi_can_fallback_to_crs(struct acpi_device *adev, const char *con_id) +{ + struct acpi_crs_lookup *l, *lookup = NULL; + + /* Never allow fallback if the device has properties */ + if (adev->data.properties || adev->driver_gpios) + return false; + + mutex_lock(&acpi_crs_lookup_lock); + + list_for_each_entry(l, &acpi_crs_lookup_list, node) { + if (l->adev == adev) { + lookup = l; + break; + } + } + + if (!lookup) { + lookup = kmalloc(sizeof(*lookup), GFP_KERNEL); + if (lookup) { + lookup->adev = adev; + lookup->con_id = con_id; + list_add_tail(&lookup->node, &acpi_crs_lookup_list); + } + } + + mutex_unlock(&acpi_crs_lookup_lock); + + return lookup && + ((!lookup->con_id && !con_id) || + (lookup->con_id && con_id && + strcmp(lookup->con_id, con_id) == 0)); +} diff --git a/drivers/gpio/gpiolib-of.c b/drivers/gpio/gpiolib-of.c index 5fe34a9df3e6..6ed465ea2e12 100644 --- a/drivers/gpio/gpiolib-of.c +++ b/drivers/gpio/gpiolib-of.c @@ -423,8 +423,8 @@ int of_gpiochip_add(struct gpio_chip *chip) { int status; - if ((!chip->of_node) && (chip->dev)) - chip->of_node = chip->dev->of_node; + if ((!chip->of_node) && (chip->parent)) + chip->of_node = chip->parent->of_node; if (!chip->of_node) return 0; diff --git a/drivers/gpio/gpiolib-sysfs.c b/drivers/gpio/gpiolib-sysfs.c index b57ed8e55ab5..405dfcaadc4c 100644 --- a/drivers/gpio/gpiolib-sysfs.c +++ b/drivers/gpio/gpiolib-sysfs.c @@ -605,7 +605,7 @@ int gpiod_export(struct gpio_desc *desc, bool direction_may_change) if (chip->names && chip->names[offset]) ioname = chip->names[offset]; - dev = device_create_with_groups(&gpio_class, chip->dev, + dev = device_create_with_groups(&gpio_class, chip->parent, MKDEV(0, 0), data, gpio_groups, ioname ? ioname : "gpio%u", desc_to_gpio(desc)); @@ -730,7 +730,8 @@ int gpiochip_sysfs_register(struct gpio_chip *chip) return 0; /* use chip->base for the ID; it's already known to be unique */ - dev = device_create_with_groups(&gpio_class, chip->dev, MKDEV(0, 0), + dev = device_create_with_groups(&gpio_class, chip->parent, + MKDEV(0, 0), chip, gpiochip_groups, "gpiochip%d", chip->base); if (IS_ERR(dev)) diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index 4e4c3083ae56..d72ac1fdcd98 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -182,7 +182,7 @@ EXPORT_SYMBOL_GPL(gpiod_get_direction); /* * Add a new chip to the global chips list, keeping the list of chips sorted - * by base order. + * by range(means [base, base + ngpio - 1]) order. * * Return -EBUSY if the new chip overlaps with some other chip's integer * space. @@ -190,31 +190,48 @@ EXPORT_SYMBOL_GPL(gpiod_get_direction); static int gpiochip_add_to_list(struct gpio_chip *chip) { struct list_head *pos; - struct gpio_chip *_chip; - int err = 0; + struct gpio_chip *iterator; + struct gpio_chip *previous = NULL; - /* find where to insert our chip */ - list_for_each(pos, &gpio_chips) { - _chip = list_entry(pos, struct gpio_chip, list); - /* shall we insert before _chip? */ - if (_chip->base >= chip->base + chip->ngpio) - break; + if (list_empty(&gpio_chips)) { + pos = gpio_chips.next; + goto found; } - /* are we stepping on the chip right before? */ - if (pos != &gpio_chips && pos->prev != &gpio_chips) { - _chip = list_entry(pos->prev, struct gpio_chip, list); - if (_chip->base + _chip->ngpio > chip->base) { - dev_err(chip->dev, - "GPIO integer space overlap, cannot add chip\n"); - err = -EBUSY; + list_for_each(pos, &gpio_chips) { + iterator = list_entry(pos, struct gpio_chip, list); + if (iterator->base >= chip->base + chip->ngpio) { + /* + * Iterator is the first GPIO chip so there is no + * previous one + */ + if (previous == NULL) { + goto found; + } else { + /* + * We found a valid range(means + * [base, base + ngpio - 1]) between previous + * and iterator chip. + */ + if (previous->base + previous->ngpio + <= chip->base) + goto found; + } } + previous = iterator; } - if (!err) - list_add_tail(&chip->list, pos); + /* We are beyond the last chip in the list */ + if (iterator->base + iterator->ngpio <= chip->base) + goto found; + + dev_err(chip->parent, + "GPIO integer space overlap, cannot add chip\n"); + return -EBUSY; - return err; +found: + list_add_tail(&chip->list, pos); + return 0; } /** @@ -252,7 +269,7 @@ static struct gpio_desc *gpio_name_to_desc(const char * const name) * Takes the names from gc->names and checks if they are all unique. If they * are, they are assigned to their gpio descriptors. * - * Returns -EEXIST if one of the names is already used for a different GPIO. + * Warning if one of the names is already used for a different GPIO. */ static int gpiochip_set_desc_names(struct gpio_chip *gc) { @@ -267,7 +284,7 @@ static int gpiochip_set_desc_names(struct gpio_chip *gc) gpio = gpio_name_to_desc(gc->names[i]); if (gpio) - dev_warn(gc->dev, "Detected name collision for " + dev_warn(gc->parent, "Detected name collision for " "GPIO name '%s'\n", gc->names[i]); } @@ -289,7 +306,7 @@ static int gpiochip_set_desc_names(struct gpio_chip *gc) * different chip. Otherwise it returns zero as a success code. * * When gpiochip_add() is called very early during boot, so that GPIOs - * can be freely used, the chip->dev device must be registered before + * can be freely used, the chip->parent device must be registered before * the gpio framework's arch_initcall(). Otherwise sysfs initialization * for GPIOs will fail rudely. * @@ -308,6 +325,11 @@ int gpiochip_add(struct gpio_chip *chip) if (!descs) return -ENOMEM; + if (chip->ngpio == 0) { + chip_err(chip, "tried to insert a GPIO chip with zero lines\n"); + return -EINVAL; + } + spin_lock_irqsave(&gpio_lock, flags); if (base < 0) { @@ -348,8 +370,8 @@ int gpiochip_add(struct gpio_chip *chip) INIT_LIST_HEAD(&chip->pin_ranges); #endif - if (!chip->owner && chip->dev && chip->dev->driver) - chip->owner = chip->dev->driver->owner; + if (!chip->owner && chip->parent && chip->parent->driver) + chip->owner = chip->parent->driver->owner; status = gpiochip_set_desc_names(chip); if (status) @@ -424,7 +446,8 @@ void gpiochip_remove(struct gpio_chip *chip) spin_unlock_irqrestore(&gpio_lock, flags); if (requested) - dev_crit(chip->dev, "REMOVING GPIOCHIP WITH GPIOS STILL REQUESTED\n"); + dev_crit(chip->parent, + "REMOVING GPIOCHIP WITH GPIOS STILL REQUESTED\n"); kfree(chip->desc); chip->desc = NULL; @@ -683,15 +706,16 @@ int _gpiochip_irqchip_add(struct gpio_chip *gpiochip, if (!gpiochip || !irqchip) return -EINVAL; - if (!gpiochip->dev) { + if (!gpiochip->parent) { pr_err("missing gpiochip .dev parent pointer\n"); return -EINVAL; } - of_node = gpiochip->dev->of_node; + of_node = gpiochip->parent->of_node; #ifdef CONFIG_OF_GPIO /* * If the gpiochip has an assigned OF node this takes precedence - * FIXME: get rid of this and use gpiochip->dev->of_node everywhere + * FIXME: get rid of this and use gpiochip->parent->of_node + * everywhere */ if (gpiochip->of_node) of_node = gpiochip->of_node; @@ -1874,6 +1898,9 @@ static struct gpio_desc *acpi_find_gpio(struct device *dev, const char *con_id, /* Then from plain _CRS GPIOs */ if (IS_ERR(desc)) { + if (!acpi_can_fallback_to_crs(adev, con_id)) + return ERR_PTR(-ENOENT); + desc = acpi_get_gpiod_by_index(adev, NULL, idx, &info); if (IS_ERR(desc)) return desc; @@ -2509,7 +2536,7 @@ static int gpiolib_seq_show(struct seq_file *s, void *v) seq_printf(s, "%sGPIOs %d-%d", (char *)s->private, chip->base, chip->base + chip->ngpio - 1); - dev = chip->dev; + dev = chip->parent; if (dev) seq_printf(s, ", %s/%s", dev->bus ? dev->bus->name : "no-bus", dev_name(dev)); diff --git a/drivers/gpio/gpiolib.h b/drivers/gpio/gpiolib.h index 98ab08c0aa2d..0a7c02d76909 100644 --- a/drivers/gpio/gpiolib.h +++ b/drivers/gpio/gpiolib.h @@ -16,7 +16,7 @@ #include <linux/device.h> enum of_gpio_flags; - +enum gpiod_flags; struct acpi_device; /** @@ -47,6 +47,8 @@ struct gpio_desc *acpi_node_get_gpiod(struct fwnode_handle *fwnode, struct acpi_gpio_info *info); int acpi_gpio_count(struct device *dev, const char *con_id); + +bool acpi_can_fallback_to_crs(struct acpi_device *adev, const char *con_id); #else static inline void acpi_gpiochip_add(struct gpio_chip *chip) { } static inline void acpi_gpiochip_remove(struct gpio_chip *chip) { } @@ -73,6 +75,12 @@ static inline int acpi_gpio_count(struct device *dev, const char *con_id) { return -ENODEV; } + +static inline bool acpi_can_fallback_to_crs(struct acpi_device *adev, + const char *con_id) +{ + return false; +} #endif struct gpio_desc *of_get_named_gpiod_flags(struct device_node *np, |