diff options
author | Linus Walleij <linus.walleij@linaro.org> | 2016-02-22 13:47:49 +0100 |
---|---|---|
committer | Linus Walleij <linus.walleij@linaro.org> | 2016-02-22 13:47:49 +0100 |
commit | 3cf42efc3479806bc5db5176fd440d23bb73854b (patch) | |
tree | a6a0a57cbe89a4f779625f8ce6e8ebc7ea49f2c0 /drivers | |
parent | 6ec9249a83b00a754af435ed57ad02ffed105d93 (diff) | |
parent | 9d8cc89c316d9cc8ff269068ac8f904f13b5a70d (diff) |
Merge branch 'devel' into for-next
Diffstat (limited to 'drivers')
41 files changed, 2821 insertions, 657 deletions
diff --git a/drivers/ata/pata_at91.c b/drivers/ata/pata_at91.c index ace0a4de3449..9f27b14009f9 100644 --- a/drivers/ata/pata_at91.c +++ b/drivers/ata/pata_at91.c @@ -30,8 +30,7 @@ #include <linux/ata_platform.h> #include <linux/platform_data/atmel.h> #include <linux/regmap.h> - -#include <asm/gpio.h> +#include <linux/gpio.h> #define DRV_NAME "pata_at91" #define DRV_VERSION "0.3" diff --git a/drivers/ata/pata_bf54x.c b/drivers/ata/pata_bf54x.c index dd7410019d15..ec748d31928d 100644 --- a/drivers/ata/pata_bf54x.c +++ b/drivers/ata/pata_bf54x.c @@ -36,8 +36,8 @@ #include <scsi/scsi_host.h> #include <linux/libata.h> #include <linux/platform_device.h> +#include <linux/gpio.h> #include <asm/dma.h> -#include <asm/gpio.h> #include <asm/portmux.h> #define DRV_NAME "pata-bf54x" diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index c88dd24a4b1f..ad226485a8e4 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -126,6 +126,16 @@ config GPIO_AMDPT driver for GPIO functionality on Promontory IOHub Require ACPI ASL code to enumerate as a platform device. +config GPIO_ATH79 + tristate "Atheros AR71XX/AR724X/AR913X GPIO support" + default y if ATH79 + depends on ATH79 || COMPILE_TEST + select GPIO_GENERIC + select GPIOLIB_IRQCHIP + help + Select this option to enable GPIO driver for + Atheros AR71XX/AR724X/AR913X SoC devices. + config GPIO_BCM_KONA bool "Broadcom Kona GPIO" depends on OF_GPIO && (ARCH_BCM_MOBILE || COMPILE_TEST) @@ -281,12 +291,14 @@ config GPIO_MPC5200 depends on PPC_MPC52xx config GPIO_MPC8XXX - bool "MPC512x/MPC8xxx GPIO support" + bool "MPC512x/MPC8xxx/QorIQ GPIO support" depends on PPC_MPC512x || PPC_MPC831x || PPC_MPC834x || PPC_MPC837x || \ - FSL_SOC_BOOKE || PPC_86xx + FSL_SOC_BOOKE || PPC_86xx || ARCH_LAYERSCAPE || ARM || \ + COMPILE_TEST + select GPIO_GENERIC help Say Y here if you're going to use hardware that connects to the - MPC512x/831x/834x/837x/8572/8610 GPIOs. + MPC512x/831x/834x/837x/8572/8610/QorIQ GPIOs. config GPIO_MVEBU def_bool y @@ -380,6 +392,13 @@ config GPIO_TB10X select GENERIC_IRQ_CHIP select OF_GPIO +config GPIO_TS4800 + tristate "TS-4800 DIO blocks and compatibles" + depends on OF_GPIO + select GPIO_GENERIC + help + This driver support TS-4800 FPGA GPIO controllers. + config GPIO_TZ1090 bool "Toumaz Xenif TZ1090 GPIO support" depends on SOC_TZ1090 @@ -487,6 +506,15 @@ endmenu menu "Port-mapped I/O GPIO drivers" depends on X86 # Unconditional I/O space access +config GPIO_104_DIO_48E + tristate "ACCES 104-DIO-48E GPIO support" + select GPIOLIB_IRQCHIP + help + Enables GPIO support for the ACCES 104-DIO-48E family. The base port + address for the device may be configured via the dio_48e_base module + parameter. The interrupt line number for the device may be configured + via the dio_48e_irq module parameter. + config GPIO_104_IDIO_16 tristate "ACCES 104-IDIO-16 GPIO support" select GPIOLIB_IRQCHIP @@ -506,10 +534,10 @@ config GPIO_104_IDI_48 via the idi_48_irq module parameter. config GPIO_F7188X - tristate "F71869, F71869A, F71882FG and F71889F GPIO support" + tristate "F71869, F71869A, F71882FG, F71889F and F81866 GPIO support" help This option enables support for GPIOs found on Fintek Super-I/O - chips F71869, F71869A, F71882FG and F71889F. + chips F71869, F71869A, F71882FG, F71889F and F81866. To compile this driver as a module, choose M here: the module will be called f7188x-gpio. @@ -570,6 +598,15 @@ config GPIO_TS5500 blocks of the TS-5500: DIO1, DIO2 and the LCD port, and the TS-5600 LCD port. +config GPIO_WS16C48 + tristate "WinSystems WS16C48 GPIO support" + select GPIOLIB_IRQCHIP + help + Enables GPIO support for the WinSystems WS16C48. The base port address + for the device may be configured via the ws16c48_base module + parameter. The interrupt line number for the device may be configured + via the ws16c48_irq module parameter. + endmenu menu "I2C GPIO expanders" @@ -702,6 +739,14 @@ config GPIO_SX150X 8 bits: sx1508q 16 bits: sx1509q +config GPIO_TPIC2810 + tristate "TPIC2810 8-Bit I2C GPO expander" + help + Say yes here to enable the GPO driver for the TI TPIC2810 chip. + + To compile this driver as a module, choose M here: the module will + be called gpio-tpic2810. + endmenu menu "MFD GPIO expanders" @@ -844,6 +889,13 @@ config GPIO_TIMBERDALE ---help--- Add support for the GPIO IP in the timberdale FPGA. +config GPIO_TPS65218 + tristate "TPS65218 GPIO" + depends on MFD_TPS65218 + help + Select this option to enable GPIO driver for the TPS65218 + chip family. + config GPIO_TPS6586X bool "TPS6586X GPIO" depends on MFD_TPS6586X @@ -1011,6 +1063,12 @@ config GPIO_MC33880 SPI driver for Freescale MC33880 high-side/low-side switch. This provides GPIO interface supporting inputs and outputs. +config GPIO_PISOSR + tristate "Generic parallel-in/serial-out shift register" + help + GPIO driver for SPI compatible parallel-in/serial-out shift + registers. These are input only devices. + endmenu menu "SPI or I2C GPIO expanders" diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile index ece7d7cbdc80..f1d3d823d1bc 100644 --- a/drivers/gpio/Makefile +++ b/drivers/gpio/Makefile @@ -12,6 +12,7 @@ obj-$(CONFIG_GPIO_ACPI) += gpiolib-acpi.o # Device drivers. Generally keep list sorted alphabetically obj-$(CONFIG_GPIO_GENERIC) += gpio-generic.o +obj-$(CONFIG_GPIO_104_DIO_48E) += gpio-104-dio-48e.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 @@ -23,7 +24,7 @@ obj-$(CONFIG_GPIO_ALTERA) += gpio-altera.o obj-$(CONFIG_GPIO_AMD8111) += gpio-amd8111.o obj-$(CONFIG_GPIO_AMDPT) += gpio-amdpt.o obj-$(CONFIG_GPIO_ARIZONA) += gpio-arizona.o -obj-$(CONFIG_ATH79) += gpio-ath79.o +obj-$(CONFIG_GPIO_ATH79) += gpio-ath79.o obj-$(CONFIG_GPIO_BCM_KONA) += gpio-bcm-kona.o obj-$(CONFIG_GPIO_BRCMSTB) += gpio-brcmstb.o obj-$(CONFIG_GPIO_BT8XX) += gpio-bt8xx.o @@ -75,6 +76,7 @@ obj-$(CONFIG_GPIO_OMAP) += gpio-omap.o obj-$(CONFIG_GPIO_PCA953X) += gpio-pca953x.o obj-$(CONFIG_GPIO_PCF857X) += gpio-pcf857x.o obj-$(CONFIG_GPIO_PCH) += gpio-pch.o +obj-$(CONFIG_GPIO_PISOSR) += gpio-pisosr.o obj-$(CONFIG_GPIO_PL061) += gpio-pl061.o obj-$(CONFIG_GPIO_PXA) += gpio-pxa.o obj-$(CONFIG_GPIO_RC5T583) += gpio-rc5t583.o @@ -95,9 +97,12 @@ obj-$(CONFIG_GPIO_TC3589X) += gpio-tc3589x.o obj-$(CONFIG_ARCH_TEGRA) += gpio-tegra.o obj-$(CONFIG_GPIO_TIMBERDALE) += gpio-timberdale.o obj-$(CONFIG_GPIO_PALMAS) += gpio-palmas.o +obj-$(CONFIG_GPIO_TPIC2810) += gpio-tpic2810.o +obj-$(CONFIG_GPIO_TPS65218) += gpio-tps65218.o obj-$(CONFIG_GPIO_TPS6586X) += gpio-tps6586x.o obj-$(CONFIG_GPIO_TPS65910) += gpio-tps65910.o obj-$(CONFIG_GPIO_TPS65912) += gpio-tps65912.o +obj-$(CONFIG_GPIO_TS4800) += gpio-ts4800.o obj-$(CONFIG_GPIO_TS5500) += gpio-ts5500.o obj-$(CONFIG_GPIO_TWL4030) += gpio-twl4030.o obj-$(CONFIG_GPIO_TWL6040) += gpio-twl6040.o @@ -111,6 +116,7 @@ obj-$(CONFIG_GPIO_VX855) += gpio-vx855.o obj-$(CONFIG_GPIO_WM831X) += gpio-wm831x.o obj-$(CONFIG_GPIO_WM8350) += gpio-wm8350.o obj-$(CONFIG_GPIO_WM8994) += gpio-wm8994.o +obj-$(CONFIG_GPIO_WS16C48) += gpio-ws16c48.o obj-$(CONFIG_GPIO_XGENE) += gpio-xgene.o obj-$(CONFIG_GPIO_XGENE_SB) += gpio-xgene-sb.o obj-$(CONFIG_GPIO_XILINX) += gpio-xilinx.o diff --git a/drivers/gpio/gpio-104-dio-48e.c b/drivers/gpio/gpio-104-dio-48e.c new file mode 100644 index 000000000000..448a903089ef --- /dev/null +++ b/drivers/gpio/gpio-104-dio-48e.c @@ -0,0 +1,430 @@ +/* + * GPIO driver for the ACCES 104-DIO-48E + * Copyright (C) 2016 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 dio_48e_base; +module_param(dio_48e_base, uint, 0); +MODULE_PARM_DESC(dio_48e_base, "ACCES 104-DIO-48E base address"); +static unsigned dio_48e_irq; +module_param(dio_48e_irq, uint, 0); +MODULE_PARM_DESC(dio_48e_irq, "ACCES 104-DIO-48E interrupt line number"); + +/** + * struct dio48e_gpio - GPIO device private data structure + * @chip: instance of the gpio_chip + * @io_state: bit I/O state (whether bit is set to input or output) + * @out_state: output bits state + * @control: Control registers state + * @lock: synchronization lock to prevent I/O race conditions + * @base: base port address of the GPIO device + * @irq: Interrupt line number + * @irq_mask: I/O bits affected by interrupts + */ +struct dio48e_gpio { + struct gpio_chip chip; + unsigned char io_state[6]; + unsigned char out_state[6]; + unsigned char control[2]; + spinlock_t lock; + unsigned base; + unsigned irq; + unsigned char irq_mask; +}; + +static int dio48e_gpio_get_direction(struct gpio_chip *chip, unsigned offset) +{ + struct dio48e_gpio *const dio48egpio = gpiochip_get_data(chip); + const unsigned port = offset / 8; + const unsigned mask = BIT(offset % 8); + + return !!(dio48egpio->io_state[port] & mask); +} + +static int dio48e_gpio_direction_input(struct gpio_chip *chip, unsigned offset) +{ + struct dio48e_gpio *const dio48egpio = gpiochip_get_data(chip); + const unsigned io_port = offset / 8; + const unsigned control_port = io_port / 2; + const unsigned control_addr = dio48egpio->base + 3 + control_port*4; + unsigned long flags; + unsigned control; + + spin_lock_irqsave(&dio48egpio->lock, flags); + + /* Check if configuring Port C */ + if (io_port == 2 || io_port == 5) { + /* Port C can be configured by nibble */ + if (offset % 8 > 3) { + dio48egpio->io_state[io_port] |= 0xF0; + dio48egpio->control[control_port] |= BIT(3); + } else { + dio48egpio->io_state[io_port] |= 0x0F; + dio48egpio->control[control_port] |= BIT(0); + } + } else { + dio48egpio->io_state[io_port] |= 0xFF; + if (io_port == 0 || io_port == 3) + dio48egpio->control[control_port] |= BIT(4); + else + dio48egpio->control[control_port] |= BIT(1); + } + + control = BIT(7) | dio48egpio->control[control_port]; + outb(control, control_addr); + control &= ~BIT(7); + outb(control, control_addr); + + spin_unlock_irqrestore(&dio48egpio->lock, flags); + + return 0; +} + +static int dio48e_gpio_direction_output(struct gpio_chip *chip, unsigned offset, + int value) +{ + struct dio48e_gpio *const dio48egpio = gpiochip_get_data(chip); + const unsigned io_port = offset / 8; + const unsigned control_port = io_port / 2; + const unsigned mask = BIT(offset % 8); + const unsigned control_addr = dio48egpio->base + 3 + control_port*4; + const unsigned out_port = (io_port > 2) ? io_port + 1 : io_port; + unsigned long flags; + unsigned control; + + spin_lock_irqsave(&dio48egpio->lock, flags); + + /* Check if configuring Port C */ + if (io_port == 2 || io_port == 5) { + /* Port C can be configured by nibble */ + if (offset % 8 > 3) { + dio48egpio->io_state[io_port] &= 0x0F; + dio48egpio->control[control_port] &= ~BIT(3); + } else { + dio48egpio->io_state[io_port] &= 0xF0; + dio48egpio->control[control_port] &= ~BIT(0); + } + } else { + dio48egpio->io_state[io_port] &= 0x00; + if (io_port == 0 || io_port == 3) + dio48egpio->control[control_port] &= ~BIT(4); + else + dio48egpio->control[control_port] &= ~BIT(1); + } + + if (value) + dio48egpio->out_state[io_port] |= mask; + else + dio48egpio->out_state[io_port] &= ~mask; + + control = BIT(7) | dio48egpio->control[control_port]; + outb(control, control_addr); + + outb(dio48egpio->out_state[io_port], dio48egpio->base + out_port); + + control &= ~BIT(7); + outb(control, control_addr); + + spin_unlock_irqrestore(&dio48egpio->lock, flags); + + return 0; +} + +static int dio48e_gpio_get(struct gpio_chip *chip, unsigned offset) +{ + struct dio48e_gpio *const dio48egpio = gpiochip_get_data(chip); + const unsigned port = offset / 8; + const unsigned mask = BIT(offset % 8); + const unsigned in_port = (port > 2) ? port + 1 : port; + unsigned long flags; + unsigned port_state; + + spin_lock_irqsave(&dio48egpio->lock, flags); + + /* ensure that GPIO is set for input */ + if (!(dio48egpio->io_state[port] & mask)) { + spin_unlock_irqrestore(&dio48egpio->lock, flags); + return -EINVAL; + } + + port_state = inb(dio48egpio->base + in_port); + + spin_unlock_irqrestore(&dio48egpio->lock, flags); + + return !!(port_state & mask); +} + +static void dio48e_gpio_set(struct gpio_chip *chip, unsigned offset, int value) +{ + struct dio48e_gpio *const dio48egpio = gpiochip_get_data(chip); + const unsigned port = offset / 8; + const unsigned mask = BIT(offset % 8); + const unsigned out_port = (port > 2) ? port + 1 : port; + unsigned long flags; + + spin_lock_irqsave(&dio48egpio->lock, flags); + + if (value) + dio48egpio->out_state[port] |= mask; + else + dio48egpio->out_state[port] &= ~mask; + + outb(dio48egpio->out_state[port], dio48egpio->base + out_port); + + spin_unlock_irqrestore(&dio48egpio->lock, flags); +} + +static void dio48e_irq_ack(struct irq_data *data) +{ +} + +static void dio48e_irq_mask(struct irq_data *data) +{ + struct gpio_chip *chip = irq_data_get_irq_chip_data(data); + struct dio48e_gpio *const dio48egpio = gpiochip_get_data(chip); + const unsigned long offset = irqd_to_hwirq(data); + unsigned long flags; + + /* only bit 3 on each respective Port C supports interrupts */ + if (offset != 19 && offset != 43) + return; + + spin_lock_irqsave(&dio48egpio->lock, flags); + + if (offset == 19) + dio48egpio->irq_mask &= ~BIT(0); + else + dio48egpio->irq_mask &= ~BIT(1); + + if (!dio48egpio->irq_mask) + /* disable interrupts */ + inb(dio48egpio->base + 0xB); + + spin_unlock_irqrestore(&dio48egpio->lock, flags); +} + +static void dio48e_irq_unmask(struct irq_data *data) +{ + struct gpio_chip *chip = irq_data_get_irq_chip_data(data); + struct dio48e_gpio *const dio48egpio = gpiochip_get_data(chip); + const unsigned long offset = irqd_to_hwirq(data); + unsigned long flags; + + /* only bit 3 on each respective Port C supports interrupts */ + if (offset != 19 && offset != 43) + return; + + spin_lock_irqsave(&dio48egpio->lock, flags); + + if (!dio48egpio->irq_mask) { + /* enable interrupts */ + outb(0x00, dio48egpio->base + 0xF); + outb(0x00, dio48egpio->base + 0xB); + } + + if (offset == 19) + dio48egpio->irq_mask |= BIT(0); + else + dio48egpio->irq_mask |= BIT(1); + + spin_unlock_irqrestore(&dio48egpio->lock, flags); +} + +static int dio48e_irq_set_type(struct irq_data *data, unsigned flow_type) +{ + const unsigned long offset = irqd_to_hwirq(data); + + /* only bit 3 on each respective Port C supports interrupts */ + if (offset != 19 && offset != 43) + return -EINVAL; + + if (flow_type != IRQ_TYPE_NONE && flow_type != IRQ_TYPE_EDGE_RISING) + return -EINVAL; + + return 0; +} + +static struct irq_chip dio48e_irqchip = { + .name = "104-dio-48e", + .irq_ack = dio48e_irq_ack, + .irq_mask = dio48e_irq_mask, + .irq_unmask = dio48e_irq_unmask, + .irq_set_type = dio48e_irq_set_type +}; + +static irqreturn_t dio48e_irq_handler(int irq, void *dev_id) +{ + struct dio48e_gpio *const dio48egpio = dev_id; + struct gpio_chip *const chip = &dio48egpio->chip; + const unsigned long irq_mask = dio48egpio->irq_mask; + unsigned long gpio; + + for_each_set_bit(gpio, &irq_mask, 2) + generic_handle_irq(irq_find_mapping(chip->irqdomain, + 19 + gpio*24)); + + spin_lock(&dio48egpio->lock); + + outb(0x00, dio48egpio->base + 0xF); + + spin_unlock(&dio48egpio->lock); + + return IRQ_HANDLED; +} + +static int __init dio48e_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct dio48e_gpio *dio48egpio; + const unsigned base = dio_48e_base; + const unsigned extent = 16; + const char *const name = dev_name(dev); + int err; + const unsigned irq = dio_48e_irq; + + dio48egpio = devm_kzalloc(dev, sizeof(*dio48egpio), GFP_KERNEL); + if (!dio48egpio) + return -ENOMEM; + + if (!devm_request_region(dev, base, extent, name)) { + dev_err(dev, "Unable to lock port addresses (0x%X-0x%X)\n", + base, base + extent); + return -EBUSY; + } + + dio48egpio->chip.label = name; + dio48egpio->chip.parent = dev; + dio48egpio->chip.owner = THIS_MODULE; + dio48egpio->chip.base = -1; + dio48egpio->chip.ngpio = 48; + dio48egpio->chip.get_direction = dio48e_gpio_get_direction; + dio48egpio->chip.direction_input = dio48e_gpio_direction_input; + dio48egpio->chip.direction_output = dio48e_gpio_direction_output; + dio48egpio->chip.get = dio48e_gpio_get; + dio48egpio->chip.set = dio48e_gpio_set; + dio48egpio->base = base; + dio48egpio->irq = irq; + + spin_lock_init(&dio48egpio->lock); + + dev_set_drvdata(dev, dio48egpio); + + err = gpiochip_add_data(&dio48egpio->chip, dio48egpio); + if (err) { + dev_err(dev, "GPIO registering failed (%d)\n", err); + return err; + } + + /* initialize all GPIO as output */ + outb(0x80, base + 3); + outb(0x00, base); + outb(0x00, base + 1); + outb(0x00, base + 2); + outb(0x00, base + 3); + outb(0x80, base + 7); + outb(0x00, base + 4); + outb(0x00, base + 5); + outb(0x00, base + 6); + outb(0x00, base + 7); + + /* disable IRQ by default */ + inb(base + 0xB); + + err = gpiochip_irqchip_add(&dio48egpio->chip, &dio48e_irqchip, 0, + handle_edge_irq, IRQ_TYPE_NONE); + if (err) { + dev_err(dev, "Could not add irqchip (%d)\n", err); + goto err_gpiochip_remove; + } + + err = request_irq(irq, dio48e_irq_handler, 0, name, dio48egpio); + if (err) { + dev_err(dev, "IRQ handler registering failed (%d)\n", err); + goto err_gpiochip_remove; + } + + return 0; + +err_gpiochip_remove: + gpiochip_remove(&dio48egpio->chip); + return err; +} + +static int dio48e_remove(struct platform_device *pdev) +{ + struct dio48e_gpio *const dio48egpio = platform_get_drvdata(pdev); + + free_irq(dio48egpio->irq, dio48egpio); + gpiochip_remove(&dio48egpio->chip); + + return 0; +} + +static struct platform_device *dio48e_device; + +static struct platform_driver dio48e_driver = { + .driver = { + .name = "104-dio-48e" + }, + .remove = dio48e_remove +}; + +static void __exit dio48e_exit(void) +{ + platform_device_unregister(dio48e_device); + platform_driver_unregister(&dio48e_driver); +} + +static int __init dio48e_init(void) +{ + int err; + + dio48e_device = platform_device_alloc(dio48e_driver.driver.name, -1); + if (!dio48e_device) + return -ENOMEM; + + err = platform_device_add(dio48e_device); + if (err) + goto err_platform_device; + + err = platform_driver_probe(&dio48e_driver, dio48e_probe); + if (err) + goto err_platform_driver; + + return 0; + +err_platform_driver: + platform_device_del(dio48e_device); +err_platform_device: + platform_device_put(dio48e_device); + return err; +} + +module_init(dio48e_init); +module_exit(dio48e_exit); + +MODULE_AUTHOR("William Breathitt Gray <vilhelm.gray@gmail.com>"); +MODULE_DESCRIPTION("ACCES 104-DIO-48E GPIO driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/gpio/gpio-104-idi-48.c b/drivers/gpio/gpio-104-idi-48.c index 52eed328ce99..e37cd4cdda35 100644 --- a/drivers/gpio/gpio-104-idi-48.c +++ b/drivers/gpio/gpio-104-idi-48.c @@ -39,7 +39,6 @@ MODULE_PARM_DESC(idi_48_irq, "ACCES 104-IDI-48 interrupt line number"); * @ack_lock: synchronization lock to prevent IRQ handler 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 */ @@ -49,7 +48,6 @@ struct idi_48_gpio { spinlock_t ack_lock; unsigned char irq_mask[6]; unsigned base; - unsigned extent; unsigned irq; unsigned char cos_enb; }; @@ -227,11 +225,10 @@ static int __init idi_48_probe(struct platform_device *pdev) 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; + if (!devm_request_region(dev, base, extent, name)) { + dev_err(dev, "Unable to lock port addresses (0x%X-0x%X)\n", + base, base + extent); + return -EBUSY; } idi48gpio->chip.label = name; @@ -243,7 +240,6 @@ static int __init idi_48_probe(struct platform_device *pdev) 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); @@ -253,7 +249,7 @@ static int __init idi_48_probe(struct platform_device *pdev) err = gpiochip_add_data(&idi48gpio->chip, idi48gpio); if (err) { dev_err(dev, "GPIO registering failed (%d)\n", err); - goto err_gpio_register; + return err; } /* Disable IRQ by default */ @@ -264,23 +260,20 @@ static int __init idi_48_probe(struct platform_device *pdev) handle_edge_irq, IRQ_TYPE_NONE); if (err) { dev_err(dev, "Could not add irqchip (%d)\n", err); - goto err_gpiochip_irqchip_add; + goto err_gpiochip_remove; } - err = request_irq(irq, idi_48_irq_handler, 0, name, idi48gpio); + err = request_irq(irq, idi_48_irq_handler, IRQF_SHARED, name, + idi48gpio); if (err) { dev_err(dev, "IRQ handler registering failed (%d)\n", err); - goto err_request_irq; + goto err_gpiochip_remove; } return 0; -err_request_irq: -err_gpiochip_irqchip_add: +err_gpiochip_remove: gpiochip_remove(&idi48gpio->chip); -err_gpio_register: - release_region(base, extent); -err_lock_io_port: return err; } @@ -290,7 +283,6 @@ static int idi_48_remove(struct platform_device *pdev) free_irq(idi48gpio->irq, idi48gpio); gpiochip_remove(&idi48gpio->chip); - release_region(idi48gpio->base, idi48gpio->extent); return 0; } @@ -340,4 +332,4 @@ 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"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/gpio/gpio-104-idio-16.c b/drivers/gpio/gpio-104-idio-16.c index 4d69b50b2d84..ecc85fe9323d 100644 --- a/drivers/gpio/gpio-104-idio-16.c +++ b/drivers/gpio/gpio-104-idio-16.c @@ -38,7 +38,6 @@ MODULE_PARM_DESC(idio_16_irq, "ACCES 104-IDIO-16 interrupt line number"); * @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 */ @@ -47,7 +46,6 @@ struct idio_16_gpio { spinlock_t lock; unsigned long irq_mask; unsigned base; - unsigned extent; unsigned irq; unsigned out_state; }; @@ -201,11 +199,10 @@ static int __init idio_16_probe(struct platform_device *pdev) if (!idio16gpio) 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; + if (!devm_request_region(dev, base, extent, name)) { |