From 8944df726c7d2916764d18be8e944bd7ea3f2f51 Mon Sep 17 00:00:00 2001 From: Tobias Klauser Date: Fri, 5 Oct 2012 11:45:28 +0200 Subject: gpio/gpio-pl061: Covert to use devm_* functions Use the devm_* family of functions during probe to reduce the error handling code footprint. Signed-off-by: Tobias Klauser Signed-off-by: Linus Walleij --- drivers/gpio/gpio-pl061.c | 59 ++++++++++++++++++----------------------------- 1 file changed, 22 insertions(+), 37 deletions(-) (limited to 'drivers/gpio') diff --git a/drivers/gpio/gpio-pl061.c b/drivers/gpio/gpio-pl061.c index b4b5da4..31d9c9e 100644 --- a/drivers/gpio/gpio-pl061.c +++ b/drivers/gpio/gpio-pl061.c @@ -216,39 +216,34 @@ static void __init pl061_init_gc(struct pl061_gpio *chip, int irq_base) IRQ_GC_INIT_NESTED_LOCK, IRQ_NOREQUEST, 0); } -static int pl061_probe(struct amba_device *dev, const struct amba_id *id) +static int pl061_probe(struct amba_device *adev, const struct amba_id *id) { - struct pl061_platform_data *pdata; + struct device *dev = &adev->dev; + struct pl061_platform_data *pdata = dev->platform_data; struct pl061_gpio *chip; int ret, irq, i; - chip = kzalloc(sizeof(*chip), GFP_KERNEL); + chip = devm_kzalloc(dev, sizeof(*chip), GFP_KERNEL); if (chip == NULL) return -ENOMEM; - pdata = dev->dev.platform_data; if (pdata) { chip->gc.base = pdata->gpio_base; chip->irq_base = pdata->irq_base; - } else if (dev->dev.of_node) { + } else if (adev->dev.of_node) { chip->gc.base = -1; chip->irq_base = 0; - } else { - ret = -ENODEV; - goto free_mem; - } + } else + return -ENODEV; - if (!request_mem_region(dev->res.start, - resource_size(&dev->res), "pl061")) { - ret = -EBUSY; - goto free_mem; - } + if (!devm_request_mem_region(dev, adev->res.start, + resource_size(&adev->res), "pl061")) + return -EBUSY; - chip->base = ioremap(dev->res.start, resource_size(&dev->res)); - if (chip->base == NULL) { - ret = -ENOMEM; - goto release_region; - } + chip->base = devm_ioremap(dev, adev->res.start, + resource_size(&adev->res)); + if (chip->base == NULL) + return -ENOMEM; spin_lock_init(&chip->lock); @@ -258,13 +253,13 @@ static int pl061_probe(struct amba_device *dev, const struct amba_id *id) chip->gc.set = pl061_set_value; chip->gc.to_irq = pl061_to_irq; chip->gc.ngpio = PL061_GPIO_NR; - chip->gc.label = dev_name(&dev->dev); - chip->gc.dev = &dev->dev; + chip->gc.label = dev_name(dev); + chip->gc.dev = dev; chip->gc.owner = THIS_MODULE; ret = gpiochip_add(&chip->gc); if (ret) - goto iounmap; + return ret; /* * irq_chip support @@ -276,11 +271,10 @@ static int pl061_probe(struct amba_device *dev, const struct amba_id *id) pl061_init_gc(chip, chip->irq_base); writeb(0, chip->base + GPIOIE); /* disable irqs */ - irq = dev->irq[0]; - if (irq < 0) { - ret = -ENODEV; - goto iounmap; - } + irq = adev->irq[0]; + if (irq < 0) + return -ENODEV; + irq_set_chained_handler(irq, pl061_irq_handler); irq_set_handler_data(irq, chip); @@ -294,18 +288,9 @@ static int pl061_probe(struct amba_device *dev, const struct amba_id *id) } } - amba_set_drvdata(dev, chip); + amba_set_drvdata(adev, chip); return 0; - -iounmap: - iounmap(chip->base); -release_region: - release_mem_region(dev->res.start, resource_size(&dev->res)); -free_mem: - kfree(chip); - - return ret; } #ifdef CONFIG_PM -- cgit v1.1 From 086d585f13542de205c25fd225a37aa0cadc3be0 Mon Sep 17 00:00:00 2001 From: Tobias Klauser Date: Fri, 5 Oct 2012 11:37:38 +0200 Subject: gpio/gpio-omap: Use existing pointer to struct device A pointer to "pdev->dev" is already stored in "dev", so use it in devm_kzalloc. Signed-off-by: Tobias Klauser Acked-by: Kevin Hilman Signed-off-by: Linus Walleij --- drivers/gpio/gpio-omap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpio') diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c index 94cbc84..eb73dee 100644 --- a/drivers/gpio/gpio-omap.c +++ b/drivers/gpio/gpio-omap.c @@ -1070,7 +1070,7 @@ static int __devinit omap_gpio_probe(struct platform_device *pdev) if (!pdata) return -EINVAL; - bank = devm_kzalloc(&pdev->dev, sizeof(struct gpio_bank), GFP_KERNEL); + bank = devm_kzalloc(dev, sizeof(struct gpio_bank), GFP_KERNEL); if (!bank) { dev_err(dev, "Memory alloc failed\n"); return -ENOMEM; -- cgit v1.1 From 04ed4279715f685857b8d5b84a48bf7bd43a36c5 Mon Sep 17 00:00:00 2001 From: Ashish Jangam Date: Fri, 14 Sep 2012 19:00:16 +0530 Subject: DA9055 GPIO driver This is the GPIO patch for the DA9055 PMIC. This patch has got dependency on the DA9055 MFD core. This patch is functionally tested on SMDK6410 board. Signed-off-by: David Dajun Chen Signed-off-by: Ashish Jangam Signed-off-by: Linus Walleij --- drivers/gpio/Kconfig | 11 +++ drivers/gpio/Makefile | 1 + drivers/gpio/gpio-da9055.c | 204 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 216 insertions(+) create mode 100644 drivers/gpio/gpio-da9055.c (limited to 'drivers/gpio') diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index d055cee..150eeb7 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -86,6 +86,17 @@ config GPIO_DA9052 help Say yes here to enable the GPIO driver for the DA9052 chip. +config GPIO_DA9055 + tristate "Dialog Semiconductor DA9055 GPIO" + depends on MFD_DA9055 + help + Say yes here to enable the GPIO driver for the DA9055 chip. + + The Dialog DA9055 PMIC chip has 3 GPIO pins that can be + be controller by this driver. + + If driver is built as a module it will be called gpio-da9055. + config GPIO_MAX730X tristate diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile index 9aeed67..e6f8e37 100644 --- a/drivers/gpio/Makefile +++ b/drivers/gpio/Makefile @@ -18,6 +18,7 @@ obj-$(CONFIG_GPIO_ARIZONA) += gpio-arizona.o obj-$(CONFIG_GPIO_BT8XX) += gpio-bt8xx.o obj-$(CONFIG_GPIO_CS5535) += gpio-cs5535.o obj-$(CONFIG_GPIO_DA9052) += gpio-da9052.o +obj-$(CONFIG_GPIO_DA9055) += gpio-da9055.o obj-$(CONFIG_ARCH_DAVINCI) += gpio-davinci.o obj-$(CONFIG_GPIO_EM) += gpio-em.o obj-$(CONFIG_GPIO_EP93XX) += gpio-ep93xx.o diff --git a/drivers/gpio/gpio-da9055.c b/drivers/gpio/gpio-da9055.c new file mode 100644 index 0000000..55d83c7 --- /dev/null +++ b/drivers/gpio/gpio-da9055.c @@ -0,0 +1,204 @@ +/* + * GPIO Driver for Dialog DA9055 PMICs. + * + * Copyright(c) 2012 Dialog Semiconductor Ltd. + * + * Author: David Dajun Chen + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + */ +#include +#include +#include + +#include +#include +#include + +#define DA9055_VDD_IO 0x0 +#define DA9055_PUSH_PULL 0x3 +#define DA9055_ACT_LOW 0x0 +#define DA9055_GPI 0x1 +#define DA9055_PORT_MASK 0x3 +#define DA9055_PORT_SHIFT(offset) (4 * (offset % 2)) + +#define DA9055_INPUT DA9055_GPI +#define DA9055_OUTPUT DA9055_PUSH_PULL +#define DA9055_IRQ_GPI0 3 + +struct da9055_gpio { + struct da9055 *da9055; + struct gpio_chip gp; +}; + +static inline struct da9055_gpio *to_da9055_gpio(struct gpio_chip *chip) +{ + return container_of(chip, struct da9055_gpio, gp); +} + +static int da9055_gpio_get(struct gpio_chip *gc, unsigned offset) +{ + struct da9055_gpio *gpio = to_da9055_gpio(gc); + int gpio_direction = 0; + int ret; + + /* Get GPIO direction */ + ret = da9055_reg_read(gpio->da9055, (offset >> 1) + DA9055_REG_GPIO0_1); + if (ret < 0) + return ret; + + gpio_direction = ret & (DA9055_PORT_MASK) << DA9055_PORT_SHIFT(offset); + gpio_direction >>= DA9055_PORT_SHIFT(offset); + switch (gpio_direction) { + case DA9055_INPUT: + ret = da9055_reg_read(gpio->da9055, DA9055_REG_STATUS_B); + if (ret < 0) + return ret; + break; + case DA9055_OUTPUT: + ret = da9055_reg_read(gpio->da9055, DA9055_REG_GPIO_MODE0_2); + if (ret < 0) + return ret; + } + + return ret & (1 << offset); + +} + +static void da9055_gpio_set(struct gpio_chip *gc, unsigned offset, int value) +{ + struct da9055_gpio *gpio = to_da9055_gpio(gc); + + da9055_reg_update(gpio->da9055, + DA9055_REG_GPIO_MODE0_2, + 1 << offset, + value << offset); +} + +static int da9055_gpio_direction_input(struct gpio_chip *gc, unsigned offset) +{ + struct da9055_gpio *gpio = to_da9055_gpio(gc); + unsigned char reg_byte; + + reg_byte = (DA9055_ACT_LOW | DA9055_GPI) + << DA9055_PORT_SHIFT(offset); + + return da9055_reg_update(gpio->da9055, (offset >> 1) + + DA9055_REG_GPIO0_1, + DA9055_PORT_MASK << + DA9055_PORT_SHIFT(offset), + reg_byte); +} + +static int da9055_gpio_direction_output(struct gpio_chip *gc, + unsigned offset, int value) +{ + struct da9055_gpio *gpio = to_da9055_gpio(gc); + unsigned char reg_byte; + int ret; + + reg_byte = (DA9055_VDD_IO | DA9055_PUSH_PULL) + << DA9055_PORT_SHIFT(offset); + + ret = da9055_reg_update(gpio->da9055, (offset >> 1) + + DA9055_REG_GPIO0_1, + DA9055_PORT_MASK << + DA9055_PORT_SHIFT(offset), + reg_byte); + if (ret < 0) + return ret; + + da9055_gpio_set(gc, offset, value); + + return 0; +} + +static int da9055_gpio_to_irq(struct gpio_chip *gc, u32 offset) +{ + struct da9055_gpio *gpio = to_da9055_gpio(gc); + struct da9055 *da9055 = gpio->da9055; + + return regmap_irq_get_virq(da9055->irq_data, + DA9055_IRQ_GPI0 + offset); +} + +static struct gpio_chip reference_gp __devinitdata = { + .label = "da9055-gpio", + .owner = THIS_MODULE, + .get = da9055_gpio_get, + .set = da9055_gpio_set, + .direction_input = da9055_gpio_direction_input, + .direction_output = da9055_gpio_direction_output, + .to_irq = da9055_gpio_to_irq, + .can_sleep = 1, + .ngpio = 3, + .base = -1, +}; + +static int __devinit da9055_gpio_probe(struct platform_device *pdev) +{ + struct da9055_gpio *gpio; + struct da9055_pdata *pdata; + int ret; + + gpio = devm_kzalloc(&pdev->dev, sizeof(*gpio), GFP_KERNEL); + if (gpio == NULL) + return -ENOMEM; + + gpio->da9055 = dev_get_drvdata(pdev->dev.parent); + pdata = gpio->da9055->dev->platform_data; + + gpio->gp = reference_gp; + if (pdata && pdata->gpio_base) + gpio->gp.base = pdata->gpio_base; + + ret = gpiochip_add(&gpio->gp); + if (ret < 0) { + dev_err(&pdev->dev, "Could not register gpiochip, %d\n", ret); + goto err_mem; + } + + platform_set_drvdata(pdev, gpio); + + return 0; + +err_mem: + return ret; +} + +static int __devexit da9055_gpio_remove(struct platform_device *pdev) +{ + struct da9055_gpio *gpio = platform_get_drvdata(pdev); + + return gpiochip_remove(&gpio->gp); +} + +static struct platform_driver da9055_gpio_driver = { + .probe = da9055_gpio_probe, + .remove = __devexit_p(da9055_gpio_remove), + .driver = { + .name = "da9055-gpio", + .owner = THIS_MODULE, + }, +}; + +static int __init da9055_gpio_init(void) +{ + return platform_driver_register(&da9055_gpio_driver); +} +subsys_initcall(da9055_gpio_init); + +static void __exit da9055_gpio_exit(void) +{ + platform_driver_unregister(&da9055_gpio_driver); +} +module_exit(da9055_gpio_exit); + +MODULE_AUTHOR("David Dajun Chen "); +MODULE_DESCRIPTION("DA9055 GPIO Device Driver"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:da9055-gpio"); -- cgit v1.1 From a3b8d4a513574e6adf76bcacad21c95ee6b8ce4b Mon Sep 17 00:00:00 2001 From: Alexander Shiyan Date: Tue, 9 Oct 2012 20:05:56 +0400 Subject: GPIO: Add support for GPIO on CLPS711X-target platform The CLPS711X CPUs provide some GPIOs for use in the system. This driver provides support for these via gpiolib. Due to platform limitations, driver does not support interrupts, only inputs and outputs. Signed-off-by: Alexander Shiyan Acked-by: Russell King Signed-off-by: Linus Walleij --- drivers/gpio/Kconfig | 4 ++ drivers/gpio/Makefile | 1 + drivers/gpio/gpio-clps711x.c | 163 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 168 insertions(+) create mode 100644 drivers/gpio/gpio-clps711x.c (limited to 'drivers/gpio') diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index 150eeb7..9e3fb34 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -102,6 +102,10 @@ config GPIO_MAX730X comment "Memory mapped GPIO drivers:" +config GPIO_CLPS711X + def_bool y + depends on ARCH_CLPS711X + config GPIO_GENERIC_PLATFORM tristate "Generic memory-mapped GPIO controller support (MMIO platform device)" select GPIO_GENERIC diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile index e6f8e37..1c1b63f 100644 --- a/drivers/gpio/Makefile +++ b/drivers/gpio/Makefile @@ -16,6 +16,7 @@ obj-$(CONFIG_GPIO_ADP5588) += gpio-adp5588.o obj-$(CONFIG_GPIO_AMD8111) += gpio-amd8111.o obj-$(CONFIG_GPIO_ARIZONA) += gpio-arizona.o obj-$(CONFIG_GPIO_BT8XX) += gpio-bt8xx.o +obj-$(CONFIG_GPIO_CLPS711X) += gpio-clps711x.o obj-$(CONFIG_GPIO_CS5535) += gpio-cs5535.o obj-$(CONFIG_GPIO_DA9052) += gpio-da9052.o obj-$(CONFIG_GPIO_DA9055) += gpio-da9055.o diff --git a/drivers/gpio/gpio-clps711x.c b/drivers/gpio/gpio-clps711x.c new file mode 100644 index 0000000..ea21822 --- /dev/null +++ b/drivers/gpio/gpio-clps711x.c @@ -0,0 +1,163 @@ +/* + * CLPS711X GPIO driver + * + * Copyright (C) 2012 Alexander Shiyan + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#include +#include +#include +#include +#include +#include + +#include + +#define CLPS711X_GPIO_PORTS 5 +#define CLPS711X_GPIO_NAME "gpio-clps711x" + +struct clps711x_gpio { + struct gpio_chip chip[CLPS711X_GPIO_PORTS]; + spinlock_t lock; +}; + +static void __iomem *clps711x_ports[] = { + CLPS711X_VIRT_BASE + PADR, + CLPS711X_VIRT_BASE + PBDR, + CLPS711X_VIRT_BASE + PCDR, + CLPS711X_VIRT_BASE + PDDR, + CLPS711X_VIRT_BASE + PEDR, +}; + +static void __iomem *clps711x_pdirs[] = { + CLPS711X_VIRT_BASE + PADDR, + CLPS711X_VIRT_BASE + PBDDR, + CLPS711X_VIRT_BASE + PCDDR, + CLPS711X_VIRT_BASE + PDDDR, + CLPS711X_VIRT_BASE + PEDDR, +}; + +#define clps711x_port(x) clps711x_ports[x->base / 8] +#define clps711x_pdir(x) clps711x_pdirs[x->base / 8] + +static int gpio_clps711x_get(struct gpio_chip *chip, unsigned offset) +{ + return !!readb(clps711x_port(chip)) & (1 << offset); +} + +static void gpio_clps711x_set(struct gpio_chip *chip, unsigned offset, + int value) +{ + int tmp; + unsigned long flags; + struct clps711x_gpio *gpio = dev_get_drvdata(chip->dev); + + spin_lock_irqsave(&gpio->lock, flags); + tmp = readb(clps711x_port(chip)) & ~(1 << offset); + if (value) + tmp |= 1 << offset; + writeb(tmp, clps711x_port(chip)); + spin_unlock_irqrestore(&gpio->lock, flags); +} + +static int gpio_clps711x_direction_in(struct gpio_chip *chip, unsigned offset) +{ + int tmp; + unsigned long flags; + struct clps711x_gpio *gpio = dev_get_drvdata(chip->dev); + + spin_lock_irqsave(&gpio->lock, flags); + tmp = readb(clps711x_pdir(chip)) & ~(1 << offset); + writeb(tmp, clps711x_pdir(chip)); + spin_unlock_irqrestore(&gpio->lock, flags); + + return 0; +} + +static int gpio_clps711x_direction_out(struct gpio_chip *chip, unsigned offset, + int value) +{ + int tmp; + unsigned long flags; + struct clps711x_gpio *gpio = dev_get_drvdata(chip->dev); + + spin_lock_irqsave(&gpio->lock, flags); + tmp = readb(clps711x_pdir(chip)) | (1 << offset); + writeb(tmp, clps711x_pdir(chip)); + tmp = readb(clps711x_port(chip)) & ~(1 << offset); + if (value) + tmp |= 1 << offset; + writeb(tmp, clps711x_port(chip)); + spin_unlock_irqrestore(&gpio->lock, flags); + + return 0; +} + +struct clps711x_gpio_port { + char *name; + int nr; +}; + +static const struct clps711x_gpio_port clps711x_gpio_ports[] __initconst = { + { "PORTA", 8, }, + { "PORTB", 8, }, + { "PORTC", 8, }, + { "PORTD", 8, }, + { "PORTE", 3, }, +}; + +static int __init gpio_clps711x_init(void) +{ + int i; + struct platform_device *pdev; + struct clps711x_gpio *gpio; + + pdev = platform_device_alloc(CLPS711X_GPIO_NAME, 0); + if (!pdev) { + pr_err("Cannot create platform device: %s\n", + CLPS711X_GPIO_NAME); + return -ENOMEM; + } + + platform_device_add(pdev); + + gpio = devm_kzalloc(&pdev->dev, sizeof(struct clps711x_gpio), + GFP_KERNEL); + if (!gpio) { + dev_err(&pdev->dev, "GPIO allocating memory error\n"); + platform_device_del(pdev); + platform_device_put(pdev); + return -ENOMEM; + } + + platform_set_drvdata(pdev, gpio); + + spin_lock_init(&gpio->lock); + + for (i = 0; i < CLPS711X_GPIO_PORTS; i++) { + gpio->chip[i].owner = THIS_MODULE; + gpio->chip[i].dev = &pdev->dev; + gpio->chip[i].label = clps711x_gpio_ports[i].name; + gpio->chip[i].base = i * 8; + gpio->chip[i].ngpio = clps711x_gpio_ports[i].nr; + gpio->chip[i].direction_input = gpio_clps711x_direction_in; + gpio->chip[i].get = gpio_clps711x_get; + gpio->chip[i].direction_output = gpio_clps711x_direction_out; + gpio->chip[i].set = gpio_clps711x_set; + WARN_ON(gpiochip_add(&gpio->chip[i])); + } + + dev_info(&pdev->dev, "GPIO driver initialized\n"); + + return 0; +} +arch_initcall(gpio_clps711x_init); + +MODULE_LICENSE("GPL v2"); +MODULE_AUTHOR("Alexander Shiyan "); +MODULE_DESCRIPTION("CLPS711X GPIO driver"); -- cgit v1.1 From 67a0d4993d85ee2f42c9909127794553df69dd59 Mon Sep 17 00:00:00 2001 From: Tony Prisk Date: Thu, 18 Oct 2012 07:18:13 +1300 Subject: GPIO: vt8500: Add extended gpio bank for WM8505/WM8650 These SoC's have an extended bank of GPIO's seperate to the main GPIO block. This patch adds the additional 5 GPIO's located in this block which control I2C and PWMOUT. Signed-off-by: Tony Prisk Signed-off-by: Linus Walleij --- drivers/gpio/gpio-vt8500.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers/gpio') diff --git a/drivers/gpio/gpio-vt8500.c b/drivers/gpio/gpio-vt8500.c index bcd8e4a..9ed2a2b 100644 --- a/drivers/gpio/gpio-vt8500.c +++ b/drivers/gpio/gpio-vt8500.c @@ -96,6 +96,7 @@ static struct vt8500_gpio_data wm8505_data = { VT8500_BANK(0x5C, 0x84, 0xAC, 0xD4, 12), VT8500_BANK(0x60, 0x88, 0xB0, 0xD8, 16), VT8500_BANK(0x64, 0x8C, 0xB4, 0xDC, 22), + VT8500_BANK(0x500, 0x504, 0x508, 0x50C, 6), }, }; @@ -115,6 +116,7 @@ static struct vt8500_gpio_data wm8650_data = { VT8500_BANK(0x58, 0x98, 0xD8, 0x18, 32), VT8500_BANK(0x5C, 0x9C, 0xDC, 0x1C, 32), VT8500_BANK(0x7C, 0xBC, 0xFC, 0x3C, 32), + VT8500_BANK(0x500, 0x504, 0x508, 0x50C, 6), }, }; -- cgit v1.1 From fc4e2514995d9cd7f3e1a67098ce65d72acf8ec7 Mon Sep 17 00:00:00 2001 From: Ryan Mallon Date: Mon, 22 Oct 2012 11:39:12 +1100 Subject: gpiolib: Refactor gpio_export The gpio_export function uses nested if statements and the status variable to handle the failure cases. This makes the function logic difficult to follow. Refactor the code to abort immediately on failure using goto. This makes the code slightly longer, but significantly reduces the nesting and number of split lines and makes the code easier to read. Signed-off-by: Ryan Mallon Signed-off-by: Linus Walleij --- drivers/gpio/gpiolib.c | 85 +++++++++++++++++++++++++++----------------------- 1 file changed, 46 insertions(+), 39 deletions(-) (limited to 'drivers/gpio') diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index 5d6c71e..d5f9742 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -702,8 +702,9 @@ int gpio_export(unsigned gpio, bool direction_may_change) { unsigned long flags; struct gpio_desc *desc; - int status = -EINVAL; + int status; const char *ioname = NULL; + struct device *dev; /* can't export until sysfs is available ... */ if (!gpio_class.p) { @@ -711,59 +712,65 @@ int gpio_export(unsigned gpio, bool direction_may_change) return -ENOENT; } - if (!gpio_is_valid(gpio)) - goto done; + if (!gpio_is_valid(gpio)) { + pr_debug("%s: gpio %d is not valid\n", __func__, gpio); + return -EINVAL; + } mutex_lock(&sysfs_lock); spin_lock_irqsave(&gpio_lock, flags); desc = &gpio_desc[gpio]; - if (test_bit(FLAG_REQUESTED, &desc->flags) - && !test_bit(FLAG_EXPORT, &desc->flags)) { - status = 0; - if (!desc->chip->direction_input - || !desc->chip->direction_output) - direction_may_change = false; + if (!test_bit(FLAG_REQUESTED, &desc->flags) || + test_bit(FLAG_EXPORT, &desc->flags)) { + spin_unlock_irqrestore(&gpio_lock, flags); + pr_debug("%s: gpio %d unavailable (requested=%d, exported=%d)\n", + __func__, gpio, + test_bit(FLAG_REQUESTED, &desc->flags), + test_bit(FLAG_EXPORT, &desc->flags)); + return -EPERM; } + + if (!desc->chip->direction_input || !desc->chip->direction_output) + direction_may_change = false; spin_unlock_irqrestore(&gpio_lock, flags); if (desc->chip->names && desc->chip->names[gpio - desc->chip->base]) ioname = desc->chip->names[gpio - desc->chip->base]; - if (status == 0) { - struct device *dev; - - dev = device_create(&gpio_class, desc->chip->dev, MKDEV(0, 0), - desc, ioname ? ioname : "gpio%u", gpio); - if (!IS_ERR(dev)) { - status = sysfs_create_group(&dev->kobj, - &gpio_attr_group); - - if (!status && direction_may_change) - status = device_create_file(dev, - &dev_attr_direction); - - if (!status && gpio_to_irq(gpio) >= 0 - && (direction_may_change - || !test_bit(FLAG_IS_OUT, - &desc->flags))) - status = device_create_file(dev, - &dev_attr_edge); - - if (status != 0) - device_unregister(dev); - } else - status = PTR_ERR(dev); - if (status == 0) - set_bit(FLAG_EXPORT, &desc->flags); + dev = device_create(&gpio_class, desc->chip->dev, MKDEV(0, 0), + desc, ioname ? ioname : "gpio%u", gpio); + if (IS_ERR(dev)) { + status = PTR_ERR(dev); + goto fail_unlock; } - mutex_unlock(&sysfs_lock); - -done: + status = sysfs_create_group(&dev->kobj, &gpio_attr_group); if (status) - pr_debug("%s: gpio%d status %d\n", __func__, gpio, status); + goto fail_unregister_device; + + if (direction_may_change) { + status = device_create_file(dev, &dev_attr_direction); + if (status) + goto fail_unregister_device; + } + if (gpio_to_irq(gpio) >= 0 && (direction_may_change || + !test_bit(FLAG_IS_OUT, &desc->flags))) { + status = device_create_file(dev, &dev_attr_edge); + if (status) + goto fail_unregister_device; + } + + set_bit(FLAG_EXPORT, &desc->flags); + mutex_unlock(&sysfs_lock); + return 0; + +fail_unregister_device: + device_unregister(dev); +fail_unlock: + mutex_unlock(&sysfs_lock); + pr_debug("%s: gpio%d status %d\n", __func__, gpio, status); return status; } EXPORT_SYMBOL_GPL(gpio_export); -- cgit v1.1 From 41b3996e3b6825bd3a0624d62fde53fbad092ed0 Mon Sep 17 00:00:00 2001 From: Alexander Shiyan Date: Wed, 24 Oct 2012 10:58:57 +0400 Subject: GPIO: clps711x: Fix return value for gpio_clps711x_get Signed-off-by: Alexander Shiyan Signed-off-by: Linus Walleij --- drivers/gpio/gpio-clps711x.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpio') diff --git a/drivers/gpio/gpio-clps711x.c b/drivers/gpio/gpio-clps711x.c index ea21822..0753b3a 100644 --- a/drivers/gpio/gpio-clps711x.c +++ b/drivers/gpio/gpio-clps711x.c @@ -47,7 +47,7 @@ static void __iomem *clps711x_pdirs[] = { static int gpio_clps711x_get(struct gpio_chip *chip, unsigned offset) { - return !!readb(clps711x_port(chip)) & (1 << offset); + return !!(readb(clps711x_port(chip)) & (1 << offset)); } static void gpio_clps711x_set(struct gpio_chip *chip, unsigned offset, -- cgit v1.1 From d6a2fa0424aefe97289aa561444ec3ae09bdbba0 Mon Sep 17 00:00:00 2001 From: Alexander Shiyan Date: Wed, 24 Oct 2012 12:34:46 +0400 Subject: GPIO: clps711x: Fix direction logic for PORTD PORTD have different direction logic, i.e. "0" is output and "1" is input. This patch fix this issue. Signed-off-by: Alexander Shiyan Signed-off-by: Linus Walleij --- drivers/gpio/gpio-clps711x.c | 65 ++++++++++++++++++++++++++++++++++---------- 1 file changed, 51 insertions(+), 14 deletions(-) (limited to 'drivers/gpio') diff --git a/drivers/gpio/gpio-clps711x.c b/drivers/gpio/gpio-clps711x.c index 0753b3a..ad181db 100644 --- a/drivers/gpio/gpio-clps711x.c +++ b/drivers/gpio/gpio-clps711x.c @@ -65,7 +65,7 @@ static void gpio_clps711x_set(struct gpio_chip *chip, unsigned offset, spin_unlock_irqrestore(&gpio->lock, flags); } -static int gpio_clps711x_direction_in(struct gpio_chip *chip, unsigned offset) +static int gpio_clps711x_dir_in(struct gpio_chip *chip, unsigned offset) { int tmp; unsigned long flags; @@ -79,8 +79,8 @@ static int gpio_clps711x_direction_in(struct gpio_chip *chip, unsigned offset) return 0; } -static int gpio_clps711x_direction_out(struct gpio_chip *chip, unsigned offset, - int value) +static int gpio_clps711x_dir_out(struct gpio_chip *chip, unsigned offset, + int value) { int tmp; unsigned long flags; @@ -98,17 +98,49 @@ static int gpio_clps711x_direction_out(struct gpio_chip *chip, unsigned offset, return 0; } -struct clps711x_gpio_port { +static int gpio_clps711x_dir_in_inv(struct gpio_chip *chip, unsigned offset) +{ + int tmp; + unsigned long flags; + struct clps711x_gpio *gpio = dev_get_drvdata(chip->dev); + + spin_lock_irqsave(&gpio->lock, flags); + tmp = readb(clps711x_pdir(chip)) | (1 << offset); + writeb(tmp, clps711x_pdir(chip)); + spin_unlock_irqrestore(&gpio->lock, flags); + + return 0; +} + +static int gpio_clps711x_dir_out_inv(struct gpio_chip *chip, unsigned offset, + int value) +{ + int tmp; + unsigned long flags; + struct clps711x_gpio *gpio = dev_get_drvdata(chip->dev); + + spin_lock_irqsave(&gpio->lock, flags); + tmp = readb(clps711x_pdir(chip)) & ~(1 << offset); + writeb(tmp, clps711x_pdir(chip)); + tmp = readb(clps711x_port(chip)) & ~(1 << offset); + if (value) + tmp |= 1 << offset; + writeb(tmp, clps711x_port(chip)); + spin_unlock_irqrestore(&gpio->lock, flags); + + return 0; +} + +static struct { char *name; int nr; -}; - -static const struct clps711x_gpio_port clps711x_gpio_ports[] __initconst = { - { "PORTA", 8, }, - { "PORTB", 8, }, - { "PORTC", 8, }, - { "PORTD", 8, }, - { "PORTE", 3, }, + int inv_dir; +} clps711x_gpio_ports[] __initconst = { + { "PORTA", 8, 0, }, + { "PORTB", 8, 0, }, + { "PORTC", 8, 0, }, + { "PORTD", 8, 1, }, + { "PORTE", 3, 0, }, }; static int __init gpio_clps711x_init(void) @@ -145,10 +177,15 @@ static int __init gpio_clps711x_init(void) gpio->chip[i].label = clps711x_gpio_ports[i].name; gpio->chip[i].base = i * 8; gpio->chip[i].ngpio = clps711x_gpio_ports[i].nr; - gpio->chip[i].direction_input = gpio_clps711x_direction_in; gpio->chip[i].get = gpio_clps711x_get; - gpio->chip[i].direction_output = gpio_clps711x_direction_out; gpio->chip[i].set = gpio_clps711x_set; + if (!clps711x_gpio_ports[i].inv_dir) { + gpio->chip[i].direction_input = gpio_clps711x_dir_in; + gpio->chip[i].direction_output = gpio_clps711x_dir_out; + } else { + gpio->chip[i].direction_input = gpio_clps711x_dir_in_inv; + gpio->chip[i].direction_output = gpio_clps711x_dir_out_inv; + } WARN_ON(gpiochip_add(&gpio->chip[i])); } -- cgit v1.1 From 80b0a6029272247f19146bf8f88e5d4bba94cba5 Mon Sep 17 00:00:00 2001 From: Mathias Nyman Date: Wed, 24 Oct 2012 17:25:27 +0300 Subject: gpiolib: add gpio get direction callback support Add .get_direction callback to gpio_chip. This allows gpiolib to check the current direction of a gpio. Used to show the correct gpio direction in sysfs and debug entries. If callback is not set then gpiolib will work as previously; e.g. guessing everything is input until a direction is set. Signed-off-by: Mathias Nyman Signed-off-by: Linus Walleij --- drivers/gpio/gpiolib.c | 38 +++++++++++++++++++++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) (limited to 'drivers/gpio') diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index d5f9742..e468eed 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -191,6 +191,32 @@ err: return ret; } +/* caller ensures gpio is valid and requested, chip->get_direction may sleep */ +static int gpio_get_direction(unsigned gpio) +{ + struct gpio_chip *chip; + struct gpio_desc *desc = &gpio_desc[gpio]; + int status = -EINVAL; + + chip = gpio_to_chip(gpio); + gpio -= chip->base; + + if (!chip->get_direction) + return status; + + status = chip->get_direction(chip, gpio); + if (status > 0) { + /* GPIOF_DIR_IN, or other positive */ + status = 1; + clear_bit(FLAG_IS_OUT, &desc->flags); + } + if (status == 0) { + /* GPIOF_DIR_OUT */ + set_bit(FLAG_IS_OUT, &desc->flags); + } + return status; +} + #ifdef CONFIG_GPIO_SYSFS /* lock protects against unexport_gpio() being called while @@ -223,6 +249,7 @@ static ssize_t gpio_direction_show(struct device *dev, struct device_attribute *attr, char *buf) { const struct gpio_desc *desc = dev_get_drvdata(dev); + unsigned gpio = desc - gpio_desc; ssize_t status; mutex_lock(&sysfs_lock); @@ -230,6 +257,7 @@ static ssize_t gpio_direction_show(struct device *dev, if (!test_bit(FLAG_EXPORT, &desc->flags)) status = -EIO; else + gpio_get_direction(gpio); status = sprintf(buf, "%s\n", test_bit(FLAG_IS_OUT, &desc->flags) ? "out" : "in"); @@ -1080,6 +1108,7 @@ int gpiochip_add(struct gpio_chip *chip) * inputs (often with pullups enabled) so power * usage is minimized. Linux code should set the * gpio direction first thing; but until it does, + * and in case chip->get_direction is not set, * we may expose the wrong direction in sysfs. */ gpio_desc[id].flags = !chip->direction_input @@ -1231,9 +1260,15 @@ int gpio_request(unsigned gpio, const char *label) desc_set_label(desc, NULL); module_put(chip->owner); clear_bit(FLAG_REQUESTED, &desc->flags); + goto done; } } - + if (chip->get_direction) { + /* chip->get_direction may sleep */ + spin_unlock_irqrestore(&gpio_lock, flags); + gpio_get_direction(gpio); + spin_lock_irqsave(&gpio_lock, flags); + } done: if (status) pr_debug("gpio_request: gpio-%d (%s) status %d\n", @@ -1769,6 +1804,7 @@ static void gpiolib_dbg_show(struct seq_file *s, struct gpio_chip *chip) if (!test_bit(FLAG_REQUESTED, &gdesc->flags)) continue; + gpio_get_direction(gpio); is_out = test_bit(FLAG_IS_OUT, &gdesc->flags); seq_printf(s, " gpio-%-3d (%-20.20s) %s %s", gpio, gdesc->label, -- cgit v1.1 From 529f2ad5e374f61987a8312603963c61d75a890a Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Fri, 26 Oct 2012 09:59:43 +0300 Subject: gpiolib: unlock on error in gpio_export() We need to unlock here before returning. Signed-off-by: Dan Carpenter Signed-off-by: Linus Walleij --- drivers/gpio/gpiolib.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers/gpio') diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index e468eed..fd2b71c 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -756,7 +756,8 @@ int gpio_export(unsigned gpio, bool direction_may_change) __func__, gpio, test_bit(FLAG_REQUESTED, &desc->flags), test_bit(FLAG_EXPORT, &desc->flags)); - return -EPERM; + status = -EPERM; + goto fail_unlock; } if (!desc->chip->direction_input || !desc->chip->direction_output) -- cgit v1.1 From d0235677311cbd404a3dcd3c0f24bf15dd24dd36 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Tue, 16 Oct 2012 21:00:09 +0200 Subject: gpio/tegra: convert to use linear irqdomain The Tegra driver tries to do the work of irq_domain_add_linear() by reserving a bunch of descriptors somewhere and keeping track of the base offset, then calling irq_domain_add_legacy(). Let's stop doing that and simply use the linear IRQ domain. For this to work: use irq_create_mapping() in the IRQ iterator so that the descriptors get allocated here. Cc: Rob Herring Cc: Grant Likely Tested-by: Stephen Warren Acked-by: Stephen Warren Signed-off-by: Linus Walleij --- drivers/gpio/gpio-tegra.c | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) (limited to 'drivers/gpio') diff --git a/drivers/gpio/gpio-tegra.c b/drivers/gpio/gpio-tegra.c index d982593..c7c175a 100644 --- a/drivers/gpio/gpio-tegra.c +++ b/drivers/gpio/gpio-tegra.c @@ -380,7 +380,6 @@ static int __devinit tegra_gpio_probe(struct platform_device *pdev) { const struct of_device_id *match; struct tegra_gpio_soc_config *config; - int irq_base; struct resource *res; struct tegra_gpio_bank *bank; int gpio; @@ -417,14 +416,11 @@ static int __devinit tegra_gpio_probe(struct platform_device *pdev) return -ENODEV; } - irq_base = irq_alloc_descs(-1, 0, tegra_gpio_chip.ngpio, 0); - if (irq_base < 0) { - dev_err(&pdev->dev, "Couldn't allocate IRQ numbers\n"); - return -ENODEV; - } - irq_domain = irq_domain_add_legacy(pdev->dev.of_node, - tegra_gpio_chip.ngpio, irq_base, 0, + irq_domain = irq_domain_add_linear(pdev->dev.of_node, + tegra_gpio_chip.ngpio, &irq_domain_simple_ops, NULL); + if (!irq_domain) + return -ENODEV; for (i = 0; i < tegra_gpio_bank_count; i++) { res = platform_get_resource(pdev, IORESOURCE_IRQ, i); @@ -464,7 +460,7 @@ static int __devinit tegra_gpio_probe(struct platform_device *pdev) gpiochip_add(&tegra_gpio_chip); for (gpio = 0; gpio < tegra_gpio_chip.ngpio; gpio++) { - int irq = irq_find_mapping(irq_domain, gpio); + int irq = irq_create_mapping(irq_domain, gpio); /* No validity check; all Tegra GPIOs are valid IRQs */ bank = &tegra_gpio_banks[GPIO_BANK(gpio)]; -- cgit v1.1 From ce931f571b6dcf8534e8740e8cd16565cf362536 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Tue, 16 Oct 2012 20:21:04 +0200 Subject: gpio/mvebu: convert to use irq_domain_add_simple() The MVEBU driver probably just wants a few IRQs. Using the simple domain has the upside of allocating IRQ descriptors if need be, especially in a SPARSE_IRQ environment. Cc: Rob Herring Cc: Grant Likely Cc: Thomas Petazzoni Cc: Sebastian Hesselbarth Cc: Andrew Lunn Signed-off-by: Linus Walleij --- drivers/gpio/gpio-mvebu.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/gpio') diff --git a/drivers/gpio/gpio-mvebu.c b/drivers/gpio/gpio-mvebu.c index 902af43..e0bde06 100644 --- a/drivers/gpio/gpio-mvebu.c +++ b/drivers/gpio/gpio-mvebu.c @@ -645,8 +645,8 @@ static int __devinit mvebu_gpio_probe(struct platform_device *pdev) IRQ_NOREQUEST, IRQ_LEVEL | IRQ_NOPROBE); /* Setup irq domain on top of the generic chip. */ - mvchip->domain = irq_domain_add_legacy(np, mvchip->chip.ngpio, - mvchip->irqbase, 0, + mvchip->domain = irq_domain_add_simple(np, mvchip->chip.ngpio, + mvchip->irqbase, &irq_domain_simple_ops, mvchip); if (!mvchip->domain) { -- cgit v1.1 From 7385500a49b769c95438c111aff92110b06ff751 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Tue, 16 Oct 2012 20:15:02 +0200 Subject: gpio/em: convert to linear IRQ domain The code in the em driver seems to want to try to do the job of the linear IRQ domain (allocate descriptors and grab a virtual range). So why not just use the linear IRQ domain? The code is now cut down so we don't need isolated functions for this. Also note that we use irq_create_mapping() to make sure descriptors are allocated for these IRQs. Also fixed the FIXME to remove the domain after use. Cc: Grant Likely Cc: Magnus Damm Signed-off-by: Linus Walleij --- drivers/gpio/gpio-em.c | 46 +++++++--------------------------------------- 1 file changed, 7 insertions(+), 39 deletions(-) (limited to 'drivers/gpio') diff --git a/drivers/gpio/gpio-em.c b/drivers/gpio/gpio-em.c index efb4c2d..88bdfe3 100644 --- a/drivers/gpio/gpio-em.c +++ b/drivers/gpio/gpio-em.c @@ -35,7 +35,6 @@ struct em_gio_priv { void __iomem *base0; void __iomem *base1; - unsigned int irq_base; spinlock_t sense_lock; struct platform_device *pdev; struct gpio_chip gpio_chip; @@ -214,7 +213,7 @@ static int em_gio_direction_output(struct gpio_chip *chip, unsigned offset, static int em_gio_to_irq(struct gpio_chip *chip, unsigned offset) { - return irq_find_mapping(gpio_to_priv(chip)->irq_domain, offset); + return irq_create_mapping(gpio_to_priv(chip)->irq_domain, offset); } static int em_gio_irq_domain_map(struct irq_domain *h, unsigned int virq, @@ -234,40 +233,6 @@ static struct irq_domain_ops em_gio_irq_domain_ops = { .map = em_gio_irq_domain_map, }; -static int __devinit em_gio_irq_domain_init(struct em_gio_priv *p) -{ - struct platform_device *pdev = p->pdev; - struct gpio_em_config *pdata = pdev->dev.platform_data; - - p->irq_base = irq_alloc_descs(pdata->irq_base, 0, - pdata->number_of_pins, numa_node_id()); - if (p->irq_base < 0) { - dev_err(&pdev->dev, "cannot get irq_desc\n"); - return p->irq_base; - } - pr_debug("gio: hw base = %d, nr = %d, sw base = %d\n", - pdata->gpio_base, pdata->number_of_pins, p->irq_base); - - p->irq_domain = irq_domain_add_legacy(pdev->dev.of_node, - pdata->number_of_pins, - p->irq_base, 0, - &em_gio_irq_domain_ops, p); - if (!p->irq_domain) { - irq_free_descs(p->irq_base, pdata->number_of_pins); - return -ENXIO; - } - - return 0; -} - -static void em_gio_irq_domain_cleanup(struct em_gio_priv *p) -{ - struct gpio_em_config *pdata = p->pdev->dev.platform_data; - - irq_free_descs(p->irq_base, pdata->number_of_pins); - /* FIXME: irq domain wants to be freed! */ -} - static int __devinit em_gio_probe(struct platform_device *pdev) { struct gpio_em_config *pdata = pdev->dev.platform_data; @@ -334,8 +299,11 @@ static int __devinit em_gio_probe(struct platform_device *pdev) irq_chip->irq_set_type = em_gio_irq_set_type; irq_chip->flags = IRQCHIP_SKIP_SET_WAKE; - ret = em_gio_irq_domain_init(p); - if (ret) { + p->irq_domain = irq_domain_add_linear(pdev->dev.of_node, + pdata->number_of_pins, + &em_gio_irq_domain_ops, p); + if (!p->irq_domain) + err = -ENXIO; dev_err(&pdev->dev, "cannot initialize irq domain\n"); goto err3; } @@ -364,7 +332,7 @@ err6: err5: free_irq(irq[0]->start, pdev); err4: - em_gio_irq_domain_cleanup(p); + irq_domain_remove(p->irq_domain); err3: iounmap(p->base1); err2: -- cgit v1.1 From a362605b341d95e7209ead8052363cb28dda1c44 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Tue, 16 Oct 2012 19:43:53 +0200 Subject: gpio/tc3589x: convert to use the simple irqdomain The special checks for whether we have a base IRQ offset or not is surplus if we use the simple IRQ domain. The IRQ offset zero will be interpreted as a linear domain case. Plus this makes sure we allocate descriptors where need be, or warn if they are preallocated with SPARSE_IRQ. Cc: Grant Likely Cc: Rob Herring Cc: Lee Jones Signed-off-by: Linus Walleij --- drivers/gpio/gpio-tc3589x.c | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) (limited to 'drivers/gpio') diff --git a/drivers/gpio/gpio-tc3589x.c b/drivers/gpio/gpio-tc3589x.c index 1e48317..8c8447c 100644 --- a/drivers/gpio/gpio-tc3589x.c +++ b/drivers/gpio/gpio-tc3589x.c @@ -292,17 +292,15 @@ static int tc3589x_gpio_irq_init(struct tc3589x_gpio *tc3589x_gpio, { int base = tc3589x_gpio->irq_base; - if (base) { - tc3589x_gpio->domain = irq_domain_add_legacy( - NULL, tc3589x_gpio->chip.ngpio, base, - 0, &tc3589x_irq_ops, tc3589x_gpio); - } - else { - tc3589x_gpio->domain = irq_domain_add_linear( - np, tc3589x_gpio->chip.ngpio, - &tc3589x_irq_ops, tc3589x_gpio); - } - + /* + * If this results in a linear domain, irq_create_mapping() will + * take care of allocating IRQ descriptors at runtime. When a base + * is provided, the IRQ descriptors will be allocated when the + * domain is instantiated. + */ + tc3589x_gpio->domain = irq_domain_add_simple(np, + tc3589x_gpio->chip.ngpio, base, &tc3589x_irq_ops, + tc3589x_gpio); if (!tc3589x_gpio->domain) { dev_err(tc3589x_gpio->dev, "Failed to create irqdomain\n"); return -ENOSYS; -- cgit v1.1 From 2cad6a8a4c31175578943f087e1dbef9f52e6ec3 Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Fri, 26 Oct 2012 23:15:05 +0800 Subject: GPIO: clps711x: use platform_device_unregister in gpio_clps711x_init() platform_device_unregister() only calls platform_device_del() and platform_device_put(), thus use platform_device_unregister() to simplify the code. Also the documents in platform.c shows that platform_device_del and platform_device_put must _only_ be externally called in error cases. All other usage is a bug. dpatch engine is used to auto generate this patch. (https://github.com/weiyj/dpatch) Signed-off-by: Wei Yongjun Signed-off-by: Linus Walleij --- drivers/gpio/gpio-clps711x.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers/gpio') diff --git a/drivers/gpio/gpio-clps711x.c b/drivers/gpio/gpio-clps711x.c index ad181db..ce63b75 100644 --- a/drivers/gpio/gpio-clps711x.c +++ b/drivers/gpio/gpio-clps711x.c @@ -162,8 +162,7 @@ static int __init gpio_clps711x_init(void) GFP_KERNEL); if (!gpio) { dev_err(&pdev->dev, "GPIO allocating memory error\n"); - platform_device_del(pdev); - platform_device_put(pdev); + platform_device_unregister(pdev); return -ENOMEM; } -- cgit v1.1 From 1631081993b1e6a6d668b3eb089904b88f0efc2b Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Wed, 31 Oct 2012 17:03:33 +0800 Subject: gpio: em: Fix build errors Fix below build errors: CC [M] drivers/gpio/gpio-em.o drivers/gpio/gpio-em.c: In function 'em_gio_probe': drivers/gpio/gpio-em.c:306: error: 'err' undeclared (first use in this function) drivers/gpio/gpio-em.c:306: error: (Each undeclared identifier is reported only once drivers/gpio/gpio-em.c:306: error: for each function it appears in.) drivers/gpio/gpio-em.c:308: error: label 'err3' used but not defined drivers/gpio/gpio-em.c:279: error: label 'err2' used but not defined drivers/gpio/gpio-em.c:265: error: label 'err1' used but not defined drivers/gpio/gpio-em.c:250: error: label 'err0' used but not defined drivers/gpio/gpio-em.c:309: warning: no return statement in function returning non-void drivers/gpio/gpio-em.c: At top level: drivers/gpio/gpio-em.c:311: error: expected identifier or '(' before 'if' drivers/gpio/gpio-em.c:317: error: expected identifier or '(' before 'if' drivers/gpio/gpio-em.c:323: warning: data definition has no type or storage class drivers/gpio/gpio-em.c:323: warning: type defaults to 'int' in declaration of 'ret' drivers/gpio/gpio-em.c:323: error: 'gpio_chip' undeclared here (not in a function) drivers/gpio/gpio-em.c:323: error: initializer element is not constant drivers/gpio/gpio-em.c:324: error: expected identifier or '(' before 'if' drivers/gpio/gpio-em.c:328: error: expected identifier or '(' before 'return' drivers/gpio/gpio-em.c:330: error: expected '=', ',', ';', 'asm' or '__attribute__' before ':' token drivers/gpio/gpio-em.c:332: error: expected '=', ',', ';', 'asm' or '__attribute__' before ':' token drivers/gpio/gpio-em.c:334: error: expected '=', ',', ';', 'asm' or '__attribute__' before ':' token drivers/gpio/gpio-em.c:336: error: expected '=', ',', ';', 'asm' or '__attribute__' before ':' token drivers/gpio/gpio-em.c:338: error: expected '=', ',', ';', 'asm' or '__attribute__' before ':' token drivers/gpio/gpio-em.c:340: error: expected '=', ',', ';', 'asm' or '__attribute__' before ':' token drivers/gpio/gpio-em.c:342: error: expected '=', ',', ';', 'asm' or '__attribute__' before ':' token drivers/gpio/gpio-em.c:344: error: expected identifier or '(' before '}' token drivers/gpio/gpio-em.c: In function 'em_gio_remove': drivers/gpio/gpio-em.c:361: error: implicit declaration of function 'em_gio_irq_domain_cleanup' make[2]: *** [drivers/gpio/gpio-em.o] Error 1 make[1]: *** [drivers/gpio] Error 2 make: *** [drivers] Error 2 Signed-off-by: Axel Lin Signed-off-by: Linus Walleij --- drivers/gpio/gpio-em.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/gpio') diff --git a/drivers/gpio/gpio-em.c b/drivers/gpio/gpio-em.c index 88bdfe3..b007063 100644 --- a/drivers/gpio/gpio-em.c +++ b/drivers/gpio/gpio-em.c @@ -302,8 +302,8 @@ static int __devinit em_gio_probe(struct platform_device *pdev) p->irq_domain = irq_domain_add_linear(pdev->dev.of_node, pdata->number_of_pins, &em_gio_irq_domain_ops, p); - if (!p->irq_domain) - err = -ENXIO; + if (!p->irq_domain) { + ret = -ENXIO; dev_err(&pdev->dev, "cannot initialize irq domain\n"); goto err3; } @@ -358,7 +358,7 @@ static int __devexit em_gio_remove(struct platform_device *pdev) free_irq(irq[1]->start, pdev); free_irq(irq[0]->start, pdev); - em_gio_irq_domain_cleanup(p); + irq_domain_remove(p->irq_domain); iounmap(p->base1); iounmap(p->base0); kfree(p); -- cgit v1.1 From 5c868fc629b0e645a68aec3a6834d965e71531f4 Mon Sep 17 00:00:00 2001 From: Alexander Stein Date: Fri, 2 Nov 2012 16:02:25 +0100 Subject: gpio-pch: Set parent dev for gpio chip This will show the gpio chip as a child node under /sys/bus/pci/devices/xxxx:xx:xx.x/ Signed-off-by: Alexander Stein Signed-off-by: Linus Walleij --- drivers/gpio/gpio-pch.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/gpio') diff --git a/drivers/gpio/gpio-pch.c b/drivers/gpio/gpio-pch.c index 4ad0c4f..e3a14fe 100644 --- a/drivers/gpio/gpio-pch.c +++ b/drivers/gpio/gpio-pch.c @@ -215,6 +215,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->owner = THIS_MODULE; gpio->direction_input = pch_gpio_direction_input; gpio->get = pch_gpio_get; -- cgit v1.1 From 8939ddc76a2f3399be98a60246ae0b365442f008 Mon Sep 17 00:00:00 2001 From: Laxman Dewangan Date: Wed, 7 Nov 2012 20:31:32 +0530 Subject: gpio: tegra: fix suspend/resume apis Following are changes done to fix the suspend/resume functionality of tegra gpio driver: - Protect suspend/resume callbacks with CONFIG_PM_SLEEP because CONFIG_PM doesn't actually enable any of the PM callbacks, it only allows to enable CONFIG_PM_SLEEP and CONFIG_PM_RUNTIME. This means if CONFIG_PM is used to protect system sleep callbacks then it may end up unreferenced if only runtime PM is enabled. - Fix the suspend/resume APIs declaration as per callback prototype. Signed-off-by: Laxman Dewangan Acked-by: Stephen Warren Signed-off-by: Linus Walleij --- drivers/gpio/gpio-tegra.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) (limited to 'drivers/gpio') diff --git a/drivers/gpio/gpio-tegra.c b/drivers/gpio/gpio-tegra.c index c7c175a..da32754 100644 --- a/drivers/gpio/gpio-tegra.c +++ b/drivers/gpio/gpio-tegra.c @@ -27,6 +27,7 @@ #include #include #include +#include #include @@ -64,7 +65,7 @@ struct tegra_gpio_bank { int bank; int irq; spinlock_t lvl_lock[4]; -#ifdef CONFIG_PM +#ifdef CONFIG_PM_SLEEP u32 cnf[4]; u32 out[4]; u32 oe[4]; @@ -285,8 +286,8 @@ static void tegra_gpio_irq_handler(unsigned int irq, struct irq_desc *desc) } -#ifdef CONFIG_PM -void tegra_gpio_resume(void) +#ifdef CONFIG_PM_SLEEP +static int tegra_gpio_resume(struct device *dev) { unsigned long flags; int b; @@ -308,9 +309,10 @@ void tegra_gpio_resume(void) } local_irq_restore(flags); + return 0; } -void tegra_gpio_suspend(void) +static int tegra_gpio_suspend(struct device *dev) { unsigned long flags; int b; @@ -330,6 +332,7 @@ void tegra_gpio_suspend(void) } } local_irq_restore(flags); + return 0; } static int tegra_gpio_wake_enable(struct irq_data *d, unsigned int enable) @@ -345,11 +348,15 @@ static struct irq_chip tegra_gpio_irq_chip = { .irq_mask = tegra_gpio_irq_mask, .irq_unmask = tegra_gpio_irq_unmask, .irq_set_type = tegra_gpio_irq_set_type, -#ifdef CONFIG_PM +#ifdef CONFIG_PM_SLEEP .irq_set_wake = tegra_gpio_wake_enable, #endif }; +static const struct dev_pm_ops tegra_gpio_pm_ops = { + SET_SYSTEM_SLEEP_PM_OPS(tegra_gpio_suspend, tegra_gpio_resume) +}; + struct tegra_gpio_soc_config { u32 bank_stride; u32 upper_offset; @@ -489,6 +496,7 @@ static struct platform_driver tegra_gpio_driver = { .driver = { .name = "tegra-gpio", .owner = THIS_MODULE, + .pm = &tegra_gpio_pm_ops, .of_match_table = tegra_gpio_of_match, }, .probe = tegra_gpio_probe, -- cgit v1.1 From 924a09873c658a23e416258c6f81348cba2cfe87 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Thu, 8 Nov 2012 10:45:24 +0800 Subject: gpio: tegra: Staticize non-exported symbols Both tegra_gpio_request() and tegra_gpio_free() are not referenced outside of this file, make them static. Signed-off-by: Axel Lin Acked-by: Stephen Warren Signed-off-by: Linus Walleij --- drivers/gpio/gpio-tegra.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/gpio') diff --git a/drivers/gpio/gpio-tegra.c b/drivers/gpio/gpio-tegra.c index da32754..5ad4ceb 100644 --- a/drivers/gpio/gpio-tegra.c +++ b/drivers/gpio/gpio-tegra.c @@ -118,12 +118,12 @@ static void tegra_gpio_disable(int gpio) } EXPORT_SYMBOL_GPL(tegra_gpio_disable); -int tegra_gpio_request(struct gpio_chip *chip, unsigned offset) +static int tegra_gpio_request(struct gpio_chip *chip, unsigned offset) { return pinctrl_request_gpio(offset); } -void tegra_gpio_free(struct gpio_chip *chip, unsigned offset) +static void tegra_gpio_free(struct gpio_chip *chip, unsigned offset) { pinctrl_free_gpio(offset); tegra_gpio_disable(offset); -- cgit v1.1 From 65b6ca466748a8e0a906e40a470e1582bc565d79 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Thu, 8 Nov 2012 10:47:02 +0800 Subject: gpio: tegra: Drop exporting static functions Both tegra_gpio_enable() and tegra_gpio_disable() are static functions, it does not make sense to export them. Signed-off-by: Axel Lin Acked-by: Stephen Warren Signed-off-by: Linus Walleij --- drivers/gpio/gpio-tegra.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers/gpio') diff --git a/drivers/gpio/gpio-tegra.c b/drivers/gpio/gpio-tegra.c index 5ad4ceb..cfd9b72 100644 --- a/drivers/gpio/gpio-tegra.c +++ b/drivers/gpio/gpio-tegra.c @@ -110,13 +110,11 @@ static void tegra_gpio_enable(int gpio) { tegra_gpio_mask_write(GPIO_MSK_CNF(gpio), gpio, 1); } -EXPORT_SYMBOL_GPL(tegra_gpio_enable); static void tegra_gpio_disable(int gpio) { tegra_gpio_mask_write(GPIO_MSK_CNF(gpio), gpio, 0); } -EXPORT_SYMBOL_GPL(tegra_gpio_disable); static int tegra_gpio_request(struct gpio_chip *chip, unsigned offset) { -- cgit v1.1 From 3764bdde1dc2fe53a87db1777440c2532cfccd58 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Thu, 8 Nov 2012 10:27:29 +0800 Subject: gpio: mvebu: Set free callback for gpio_chip We call pinctrl_request_gpio() in request callback, thus we need to call pinctrl_free_gpio() in free callback. Both mvebu_gpio_request() and mvebu_gpio_free() are not referenced outside of this file, make them static. Signed-off-by: Axel Lin Acked-by: Thomas Petazzoni Signed-off-by: Linus Walleij --- drivers/gpio/gpio-mvebu.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers/gpio') diff --git a/drivers/gpio/gpio-mvebu.c b/drivers/gpio/gpio-mvebu.c index e0bde06..8b30657 100644 --- a/drivers/gpio/gpio-mvebu.c +++ b/drivers/gpio/gpio-mvebu.c @@ -163,12 +163,12 @@ static void __iomem *mvebu_gpioreg_level_mask(struct mvebu_gpio_chip *mvchip) * Functions implementing the gpio_chip methods */ -int mvebu_gpio_request(struct gpio_chip *chip, unsigned pin) +static int mvebu_gpio_request(struct gpio_chip *chip, unsigned pin) { return pinctrl_request_gpio(chip->base + pin); } -void mvebu_gpio_free(struct gpio_chip *chip, unsigned pin) +static void mvebu_gpio_free(struct gpio_chip *chip, unsigned pin) { pinctrl_free_gpio(chip->base + pin); } @@ -518,6 +518,7 @@ static int __devinit mvebu_gpio_probe(struct platform_device *pdev) mvchip->chip.label = dev_name(&pdev->dev); mvchip->chip.dev = &pdev->dev; mvchip->chip.request = mvebu_gpio_request; + mvchip->chip.free = mvebu_gpio_free; mvchip->chip.direction_input = mvebu_gpio_direction_input; mvchip->chip.get = mvebu_gpio_get; mvchip->chip.direction_output = mvebu_gpio_direction_output; -- cgit v1.1 From f23f1516b6757c326cc638bed8c402c77e2a596e Mon Sep 17 00:00:00 2001 From: Shiraz Hashim Date: Sat, 27 Oct 2012 15:21:36 +0530 Subject: gpiolib: provide provision to register pin ranges pinctrl subsystem needs gpio chip base to prepare set of gpio pin ranges, which a given pinctrl driver can handle. This is important to handle pinctrl gpio request calls in order to program a given pin properly for gpio operation. As gpio base is allocated dynamically during gpiochip registration, presently there exists no clean way to pass this information to the pinctrl subsystem. After few discussions from [1], it was concluded that may be gpio controller reporting the pin range it supports, is a better way than pinctrl subsystem directly registering it. [1] http://comments.gmane.org/gmane.linux.ports.arm.kernel/184816 Cc: Grant Likely Signed-off-by: Viresh Kumar Signed-off-by: Shiraz Hashim [Edited documentation a bit] Signed-off-by: Linus Walleij --- drivers/gpio/gpiolib-of.c | 56 +++++++++++++++++++++++++++++++++++++++++++++++ drivers/gpio/gpiolib.c | 43 ++++++++++++++++++++++++++++++++++++ 2 files changed, 99 insertions(+) (limited to 'drivers/gpio') diff --git a/drivers/gpio/gpiolib-of.c b/drivers/gpio/gpiolib-of.c index f1a4599..a5b90c8 100644 --- a/drivers/gpio/gpiolib-of.c +++ b/drivers/gpio/gpiolib-of.c @@ -19,6 +19,7 @@ #include #include #include +#include #include /* Private data structure for of_gpiochip_find_and_xlate */ @@ -216,6 +217,58 @@ err0: } EXPORT_SYMBOL(of_mm_gpiochip_add); +#ifdef CONFIG_PINCTRL +void of_gpiochip_add_pin_range(struct gpio_chip *chip) +{ + struct device_node *np = chip->of_node; + struct gpio_pin_range *pin_range; + struct of_phandle_args pinspec; + int index = 0, ret; + + if (!np) + return; + + do { + ret = of_parse_phandle_with_args(np, "gpio-ranges", + "#gpio-range-cells", index, &pinspec); + if (ret) + break; + + pin_range = devm_kzalloc(chip->dev, sizeof(*pin_range), + GFP_KERNEL); + if (!pin_range) { + pr_err("%s: GPIO chip: failed to allocate pin ranges\n", + chip->label); + break; + } + + pin_range->range.name = chip->label; + pin_range->range.base = chip->base; + pin_range->range.pin_base = pinspec.args[0]; + pin_range->range.npins = pinspec.args[1]; + pin_range->pctldev = of_pinctrl_add_gpio_range(pinspec.np, + &pin_range->range); + + list_add_tail(&pin_range->node, &chip->pin_ranges); + + } while (index++); +} + +void of_gpiochip_remove_pin_range(struct gpio_chip *chip) +{ + struct gpio_pin_range *pin_range, *tmp; + + list_for_each_entry_safe(pin_range, tmp, &chip->pin_ranges, node) { + list_del(&pin_range->node); + pinctrl_remove_gpio_range(pin_range->pctldev, + &pin_range->range); + } +} +#else +void of_gpiochip_add_pin_range(struct gpio_chip *chip) {} +void of_gpiochip_remove_pin_range(struct gpio_chip *chip) {} +#endif + void of_gpiochip_add(struct gpio_chip *chip) { if ((!chip->of_node) && (chip->dev)) @@ -229,11 +282,14 @@ void of_gpiochip_add(struct gpio_chip *chip) chip->of_xlate = of_gpio_simple_xlate; } + of_gpiochip_add_pin_range(chip); of_node_get(chip->of_node); } void of_gpiochip_remove(struct gpio_chip *chip) { + of_gpiochip_remove_pin_range(chip); + if (chip->of_node) of_node_put(chip->of_node); } diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index 1c8d9e3..f0b07bbf 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -1083,6 +1083,10 @@ int gpiochip_add(struct gpio_chip *chip) } } +#ifdef CONFIG_PINCTRL + INIT_LIST_HEAD(&chip->pin_ranges); +#endif + of_gpiochip_add(chip); unlock: @@ -1180,6 +1184,45 @@ struct gpio_chip *gpiochip_find(void *data, } EXPORT_SYMBOL_GPL(gpiochip_find); +#ifdef CONFIG_PINCTRL +void gpiochip_add_pin_range(struct gpio_chip *chip, const char *pinctl_name, + unsigned int pin_base, unsigned int npins) +{ + struct gpio_pin_range *pin_range; + + pin_range = devm_kzalloc(chip->dev, sizeof(*pin_range), GFP_KERNEL); + if (!pin_range) { + pr_err("%s: GPIO chip: failed to allocate pin ranges\n", + chip->label); + return; + } + + pin_range->range.name = chip->label; + pin_range->range.base = chip->base; + pin_range->range.pin_base = pin_base; + pin_range->range.npins = npins; + pin_range->pctldev = find_pinctrl_and_add_gpio_range(pinctl_name, + &pin_range->range); + + list_add_tail(&pin_range->node, &chip->pin_ranges); +} + +void gpiochip_remove_pin_ranges(struct gpio_chip *chip) +{ + struct gpio_pin_range *pin_range, *tmp; + + list_for_each_entry_safe(pin_range, tmp, &chip->pin_ranges, node) { + list_del(&pin_range->node); + pinctrl_remove_gpio_range(pin_range->pctldev, + &pin_range->range); + } +} +#else +void gpiochip_add_pin_range(struct gpio_chip *chip, const char *pinctl_name, + unsigned int pin_base, unsigned int npins) {} +void gpiochip_remove_pin_ranges(struct gpio_chip *chip) {} +#endif + /* These "optional" allocation calls help prevent drivers from stomping * on each other, and help provide better diagnostics in debugfs. * They're called even less than the "set direction" calls. -- cgit v1.1 From 165adc9c1734a3f3bdbc6dc7c7a29bbefb424006 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Tue, 6 Nov 2012 14:49:39 +0100 Subject: gpiolib: fix up function prototypes etc Commit 69e1601bca88809dc118abd1becb02c15a02ec71 "gpiolib: provide provision to register pin ranges" Got most of it's function prototypes wrong, so fix this up by: - Moving the void declarations into static inlines in (previously the actual prototypes were declared here...) - Declare the gpiochip_add_pin_range() and gpiochip_remove_pin_ranges() functions in together with the pin range struct declaration itself. - Actually only implement these very functions in gpiolib.c if CONFIG_PINCTRL is set. - Additionally export the symbols since modules will need to be able to do this. Reviewed-by: Stephen Warren Signed-off-by: Linus Walleij --- drivers/gpio/gpiolib.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers/gpio') diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index f0b07bbf..1e1a7ca 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -1185,6 +1185,7 @@ struct gpio_chip *gpiochip_find(void *data, EXPORT_SYMBOL_GPL(gpiochip_find); #ifdef CONFIG_PINCTRL + void gpiochip_add_pin_range(struct gpio_chip *chip, const char *pinctl_name, unsigned int pin_base, unsigned int npins) { @@ -1206,6 +1207,7 @@ void gpiochip_add_pin_range(struct gpio_chip *chip, const char *pinctl_name, list_add_tail(&pin_range->node, &chip->pin_ranges); } +EXPORT_SYMBOL_GPL(gpiochip_add_pin_range); void gpiochip_remove_pin_ranges(struct gpio_chip *chip) { @@ -1217,11 +1219,9 @@ void gpiochip_remove_pin_ranges(struct gpio_chip *chip) &pin_range->range); } } -#else -void gpiochip_add_pin_range(struct gpio_chip *chip, const char *pinctl_name, - unsigned int pin_base, unsigned int npins) {} -void gpiochip_remove_pin_ranges(struct gpio_chip *chip) {} -#endif +EXPORT_SYMBOL_GPL(gpiochip_remove_pin_ranges); + +#endif /* CONFIG_PINCTRL */ /* These "optional" allocation calls help prevent drivers from stomping * on each other, and help provide better diagnostics in debugfs. -- cgit v1.1 From 167c1af9443757bb9d27ceff8ba4304302cb0651 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Tue, 6 Nov 2012 14:58:55 +0100 Subject: gpiolib-of: staticize the pin range calls Commit 69e1601bca88809dc118abd1becb02c15a02ec71 "gpiolib: provide provision to register pin ranges" Declared the of_gpiochip_[add|remove]_pin_range() global while they should be static as they are only ever used in this file. Let's convert them to static. Reviewed-by: Stephen Warren Reviewed-by: Viresh Kumar Signed-off-by: Linus Walleij --- drivers/gpio/gpiolib-of.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers/gpio') diff --git a/drivers/gpio/gpiolib-of.c b/drivers/gpio/gpiolib-of.c index a5b90c8..220caa5 100644 --- a/drivers/gpio/gpiolib-of.c +++ b/drivers/gpio/gpiolib-of.c @@ -218,7 +218,7 @@ err0: EXPORT_SYMBOL(of_mm_gpiochip_add); #ifdef CONFIG_PINCTRL -void of_gpiochip_add_pin_range(struct gpio_chip *chip) +static void of_gpiochip_add_pin_range(struct gpio_chip *chip) { struct device_node *np = chip->of_node; struct gpio_pin_range *pin_range; @@ -254,7 +254,7 @@ void of_gpiochip_add_pin_range(struct gpio_chip *chip) } while (index++); } -void of_gpiochip_remove_pin_range(struct gpio_chip *chip) +static void of_gpiochip_remove_pin_range(struct gpio_chip *chip) { struct gpio_pin_range *pin_range, *tmp; @@ -265,8 +265,8 @@ void of_gpiochip_remove_pin_range(struct gpio_chip *chip) } } #else -void of_gpiochip_add_pin_range(struct gpio_chip *chip) {} -void of_gpiochip_remove_pin_range(struct gpio_chip *chip) {} +static void of_gpiochip_add_pin_range(struct gpio_chip *chip) {} +static void of_gpiochip_remove_pin_range(struct gpio_chip *chip) {} #endif void of_gpiochip_add(struct gpio_chip *chip) -- cgit v1.1 From e93fa3f24353e45b189bae656ba000d0533777a3 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Tue, 6 Nov 2012 15:03:47 +0100 Subject: gpiolib: remove duplicate pin range code Commit 69e1601bca88809dc118abd1becb02c15a02ec71 "gpiolib: provide provision to register pin ranges" Introduced both of_gpiochip_remove_pin_range() and gpiochip_remove_pin_ranges(). But the contents are exactly the same so remove the OF one and rely on the range deletion in the core. Reviewed-by: Stephen Warren Reviewed-by: Viresh Kumar Signed-off-by: Linus Walleij --- drivers/gpio/gpiolib-of.c | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) (limited to 'drivers/gpio') diff --git a/drivers/gpio/gpiolib-of.c b/drivers/gpio/gpiolib-of.c index 220caa5..67403e4 100644 --- a/drivers/gpio/gpiolib-of.c +++ b/drivers/gpio/gpiolib-of.c @@ -254,19 +254,8 @@ static void of_gpiochip_add_pin_range(struct gpio_chip *chip) } while (index++); } -static void of_gpiochip_remove_pin_range(struct gpio_chip *chip) -{ - struct gpio_pin_range *pin_range, *tmp; - - list_for_each_entry_safe(pin_range, tmp, &chip->pin_ranges, node) { - list_del(&pin_range->node); - pinctrl_remove_gpio_range(pin_range->pctldev, - &pin_range->range); - } -} #else static void of_gpiochip_add_pin_range(struct gpio_chip *chip) {} -static void of_gpiochip_remove_pin_range(struct gpio_chip *chip) {} #endif void of_gpiochip_add(struct gpio_chip *chip) @@ -288,7 +277,7 @@ void of_gpiochip_add(struct gpio_chip *chip) void of_gpiochip_remove(struct gpio_chip *chip) { - of_gpiochip_remove_pin_range(chip); + gpiochip_remove_pin_ranges(chip); if (chip->of_node) of_node_put(chip->of_node); -- cgit v1.1 From 9ef0d6f7628bdcb5cc3c11623930f2527a3881a0 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Tue, 6 Nov 2012 15:15:44 +0100 Subject: gpiolib: call pin removal in chip removal function This makes us call gpiochio_remove_pin_ranges() in the gpiochip_remove() function, so we get rid of ranges when freeing the chip. Reviewed-by: Stephen Warren Reviewed-by: Viresh Kumar Signed-off-by: Linus Walleij --- drivers/gpio/gpiolib.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/gpio') diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index 1e1a7ca..bcf9b99 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -1127,6 +1127,7 @@ int gpiochip_remove(struct gpio_chip *chip) spin_lock_irqsave(&gpio_lock, flags); + gpiochip_remove_pin_ranges(chip); of_gpiochip_remove(chip); for (id = chip->base; id < chip->base + chip->ngpio; id++) { -- cgit v1.1 From 1e63d7b9363f0c57d00991f9f2e0af374dfc591a Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Tue, 6 Nov 2012 16:03:35 +0100 Subject: gpiolib: separation of pin concerns The fact that of_gpiochip_add_pin_range() and gpiochip_add_pin_range() share too much code is fragile and will invariably mean that bugs need to be fixed in two places instead of one. So separate the concerns of gpiolib.c and gpiolib-of.c and have the latter call the former as back-end. This is necessary also when going forward with other device descriptions such as ACPI. This is done by: - Adding a return code to gpiochip_add_pin_range() so we can reliably check whether this succeeds. - Get rid of the custom of_pinctrl_add_gpio_range() from pinctrl. Instead create of_pinctrl_get() to just retrive the pin controller per se from an OF node. This composite function was just begging to be deleted, it was way to purpose-specific. - Use pinctrl_dev_get_name() to get the name of the retrieved pin controller and use that to call back into the generic gpiochip_add_pin_range(). Now the pin range is only allocated and tied to a pin controller from the core implementation in gpiolib.c. Signed-off-by: Linus Walleij --- drivers/gpio/gpiolib-of.c | 23 +++++++++-------------- drivers/gpio/gpiolib.c | 8 +++++--- 2 files changed, 14 insertions(+), 17 deletions(-) (limited to 'drivers/gpio') diff --git a/drivers/gpio/gpiolib-of.c b/drivers/gpio/gpiolib-of.c index 67403e4..a40cd84 100644 --- a/drivers/gpio/gpiolib-of.c +++ b/drivers/gpio/gpiolib-of.c @@ -221,8 +221,8 @@ EXPORT_SYMBOL(of_mm_gpiochip_add); static void of_gpiochip_add_pin_range(struct gpio_chip *chip) { struct device_node *np = chip->of_node; - struct gpio_pin_range *pin_range; struct of_phandle_args pinspec; + struct pinctrl_dev *pctldev; int index = 0, ret; if (!np) @@ -234,22 +234,17 @@ static void of_gpiochip_add_pin_range(struct gpio_chip *chip) if (ret) break; - pin_range = devm_kzalloc(chip->dev, sizeof(*pin_range), - GFP_KERNEL); - if (!pin_range) { - pr_err("%s: GPIO chip: failed to allocate pin ranges\n", - chip->label); + pctldev = of_pinctrl_get(pinspec.np); + if (!pctldev) break; - } - pin_range->range.name = chip->label; - pin_range->range.base = chip->base; - pin_range->range.pin_base = pinspec.args[0]; - pin_range->range.npins = pinspec.args[1]; - pin_range->pctldev = of_pinctrl_add_gpio_range(pinspec.np, - &pin_range->range); + ret = gpiochip_add_pin_range(chip, + pinctrl_dev_get_name(pctldev), + pinspec.args[0], + pinspec.args[1]); - list_add_tail(&pin_range->node, &chip->pin_ranges); + if (ret) + break; } while (index++); } diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index bcf9b99..c5f6500 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -1187,8 +1187,8 @@ EXPORT_SYMBOL_GPL(gpiochip_find); #ifdef CONFIG_PINCTRL -void gpiochip_add_pin_range(struct gpio_chip *chip, const char *pinctl_name, - unsigned int pin_base, unsigned int npins) +int gpiochip_add_pin_range(struct gpio_chip *chip, const char *pinctl_name, + unsigned int pin_base, unsigned int npins) { struct gpio_pin_range *pin_range; @@ -1196,7 +1196,7 @@ void gpiochip_add_pin_range(struct gpio_chip *chip, const char *pinctl_name, if (!pin_range) { pr_err("%s: GPIO chip: failed to allocate pin ranges\n", chip->label); - return; + return -ENOMEM; } pin_range->range.name = chip->label; @@ -1207,6 +1207,8 @@ void gpiochip_add_pin_range(struct gpio_chip *chip, const char *pinctl_name, &pin_range->range); list_add_tail(&pin_range->node, &chip->pin_ranges); + + return 0; } EXPORT_SYMBOL_GPL(gpiochip_add_pin_range); -- cgit v1.1 From 55ecd26373bc995c279a5d988ee36c2767e4f3ca Mon Sep 17 00:00:00 2001 From: Maxime Ripard Date: Thu, 8 Nov 2012 18:01:51 +0100 Subject: gpio: pca953x: Register an IRQ domain The PCA953x used to register no IRQ domain, which made it impossible to use it as an interrupt-parent from the device tree. Signed-off-by: Maxime Ripard Signed-off-by: Linus Walleij --- drivers/gpio/gpio-pca953x.c | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) (limited to 'drivers/gpio') diff --git a/drivers/gpio/gpio-pca953x.c b/drivers/gpio/gpio-pca953x.c index 9c693ae..5ba7e60 100644 --- a/drivers/gpio/gpio-pca953x.c +++ b/drivers/gpio/gpio-pca953x.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -83,6 +84,7 @@ struct pca953x_chip { u32 irq_trig_raise; u32 irq_trig_fall; int irq_base; + struct irq_domain *domain; #endif struct i2c_client *client; @@ -333,14 +335,14 @@ static void pca953x_irq_mask(struct irq_data *d) { struct pca953x_chip *chip = irq_data_get_irq_chip_data(d); - chip->irq_mask &= ~(1 << (d->irq - chip->irq_base)); + chip->irq_mask &= ~(1 << d->hwirq); } static void pca953x_irq_unmask(struct irq_data *d) { struct pca953x_chip *chip = irq_data_get_irq_chip_data(d); - chip->irq_mask |= 1 << (d->irq - chip->irq_base); + chip->irq_mask |= 1 << d->hwirq; } static void pca953x_irq_bus_lock(struct irq_data *d) @@ -372,8 +374,7 @@ static void pca953x_irq_bus_sync_unlock(struct irq_data *d) static int pca953x_irq_set_type(struct irq_data *d, unsigned int type) { struct pca953x_chip *chip = irq_data_get_irq_chip_data(d); - u32 level = d->irq - chip->irq_base; - u32 mask = 1 << level; + u32 mask = 1 << d->hwirq; if (!(type & IRQ_TYPE_EDGE_BOTH)) { dev_err(&chip->client->dev, "irq %d: unsupported type %d\n", @@ -454,7 +455,7 @@ static irqreturn_t pca953x_irq_handler(int irq, void *devid) do { level = __ffs(pending); - handle_nested_irq(level + chip->irq_base); + handle_nested_irq(irq_find_mapping(chip->domain, level)); pending &= ~(1 << level); } while (pending); @@ -499,6 +500,17 @@ static int pca953x_irq_setup(struct pca953x_chip *chip, if (chip->irq_base < 0) goto out_failed; + chip->domain = irq_domain_add_legacy(client->dev.of_node, + chip->gpio_chip.ngpio, + chip->irq_base, + 0, + &irq_domain_simple_ops, + NULL); + if (!chip->domain) { + ret = -ENODEV; + goto out_irqdesc_free; + } + for (lvl = 0; lvl < chip->gpio_chip.ngpio; lvl++) { int irq = lvl + chip->irq_base; @@ -521,7 +533,7 @@ static int pca953x_irq_setup(struct pca953x_chip *chip, if (ret) { dev_err(&client->dev, "failed to request irq %d\n", client->irq); - goto out_failed; + goto out_irqdesc_free; } chip->gpio_chip.to_irq = pca953x_gpio_to_irq; @@ -529,6 +541,8 @@ static int pca953x_irq_setup(struct pca953x_chip *chip, return 0; +out_irqdesc_free: + irq_free_descs(chip->irq_base, chip->gpio_chip.ngpio); out_failed: chip->irq_base = -1; return ret; -- cgit v1.1 From ed32620ea72889c8a9dda278a960bce01136d9a4 Mon Sep 17 00:00:00 2001 From: Maxime Ripard Date: Thu, 8 Nov 2012 18:01:52 +0100 Subject: gpio: pca953x: Add compatible strings to gpio-pca953x driver Even though the device tree binding code was already written, the compatible strings were not yet in the driver. Signed-off-by: Maxime Ripard Signed-off-by: Linus Walleij --- drivers/gpio/gpio-pca953x.c | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) (limited to 'drivers/gpio') diff --git a/drivers/gpio/gpio-pca953x.c b/drivers/gpio/gpio-pca953x.c index 5ba7e60..0c5eaf5 100644 --- a/drivers/gpio/gpio-pca953x.c +++ b/drivers/gpio/gpio-pca953x.c @@ -765,9 +765,38 @@ static int pca953x_remove(struct i2c_client *client) return 0; } +static const struct of_device_id pca953x_dt_ids[] = { + { .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 = "maxim,max7310", }, + { .compatible = "maxim,max7312", }, + { .compatible = "maxim,max7313", }, + { .compatible = "maxim,max7315", }, + + { .compatible = "ti,pca6107", }, + { .compatible = "ti,tca6408", }, + { .compatible = "ti,tca6416", }, + { .compatible = "ti,tca6424", }, + { } +}; + +MODULE_DEVICE_TABLE(of, pca953x_dt_ids); + static struct i2c_driver pca953x_driver = { .driver = { .name = "pca953x", + .of_match_table = pca953x_dt_ids, }, .probe = pca953x_probe, .remove = pca953x_remove, -- cgit v1.1 From 195812e4b6a631e8eaad4046bf6890db4328ea1f Mon Sep 17 00:00:00 2001 From: Laxman Dewangan Date: Fri, 9 Nov 2012 11:34:20 +0530 Subject: gpio: tegra: read output value when gpio is set in direction_out Read the output value when gpio is set for the output mode for gpio_get_value(). Reading input value in direction out does not give correct value. Signed-off-by: Laxman Dewangan Acked-by: Stephen Warren Signed-off-by: Linus Walleij --- drivers/gpio/gpio-tegra.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers/gpio') diff --git a/drivers/gpio/gpio-tegra.c b/drivers/gpio/gpio-tegra.c index cfd9b72..5389be8 100644 --- a/drivers/gpio/gpio-tegra.c +++ b/drivers/gpio/gpio-tegra.c @@ -134,6 +134,11 @@ static void tegra_gpio_set(struct gpio_chip *chip, unsigned offset, int value) static int tegra_gpio_get(struct gpio_chip *chip, unsigned offset) { + /* If gpio is in output mode then read from the out value */ + if ((tegra_gpio_readl(GPIO_OE(offset)) >> GPIO_BIT(offset)) & 1) + return (tegra_gpio_readl(GPIO_OUT(offset)) >> + GPIO_BIT(offset)) & 0x1; + return (tegra_gpio_readl(GPIO_IN(offset)) >> GPIO_BIT(offset)) & 0x1; } -- cgit v1.1 From 9859eb99e9212339e2009b98c396b08260276edf Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Tue, 13 Nov 2012 10:35:13 +0100 Subject: gpio: twl4030: Use only TWL4030_MODULE_LED for LED configuration Avoid using the TWL4030_MODULE_PWMA/B as module ID. The LEDEN, PWMA ON/OFF and PWMB ON/OFF registers are in a continuous range starting from LED base. This is going to be helpful for further cleanup in the twl stack. No functional changes. Signed-off-by: Peter Ujfalusi Signed-off-by: Linus Walleij --- drivers/gpio/gpio-twl4030.c | 35 ++++++++++++++++++----------------- 1 file changed, 18 insertions(+), 17 deletions(-) (limited to 'drivers/gpio') diff --git a/drivers/gpio/gpio-twl4030.c b/drivers/gpio/gpio-twl4030.c index c5f8ca2..d2138b0f 100644 --- a/drivers/gpio/gpio-twl4030.c +++ b/drivers/gpio/gpio-twl4030.c @@ -88,11 +88,15 @@ static inline int gpio_twl4030_write(u8 address, u8 data) /*----------------------------------------------------------------------*/ /* - * LED register offsets (use TWL4030_MODULE_{LED,PWMA,PWMB})) + * LED register offsets from TWL_MODULE_LED base * PWMs A and B are dedicated to LEDs A and B, respectively. */ -#define TWL4030_LED_LEDEN 0x0 +#define TWL4030_LED_LEDEN_REG 0x00 +#define TWL4030_PWMAON_REG 0x01 +#define TWL4030_PWMAOFF_REG 0x02 +#define TWL4030_PWMBON_REG 0x03 +#define TWL4030_PWMBOFF_REG 0x04 /* LEDEN bits */ #define LEDEN_LEDAON BIT(0) @@ -104,9 +108,6 @@ static inline int gpio_twl4030_write(u8 address, u8 data) #define LEDEN_PWM_LENGTHA BIT(6) #define LEDEN_PWM_LENGTHB BIT(7) -#define TWL4030_PWMx_PWMxON 0x0 -#define TWL4030_PWMx_PWMxOFF 0x1 - #define PWMxON_LENGTH BIT(7) /*----------------------------------------------------------------------*/ @@ -145,7 +146,7 @@ static void twl4030_led_set_value(int led, int value) else cached_leden |= mask; status = twl_i2c_write_u8(TWL4030_MODULE_LED, cached_leden, - TWL4030_LED_LEDEN); + TWL4030_LED_LEDEN_REG); mutex_unlock(&gpio_lock); } @@ -216,33 +217,33 @@ static int twl_request(struct gpio_chip *chip, unsigned offset) if (offset >= TWL4030_GPIO_MAX) { u8 ledclr_mask = LEDEN_LEDAON | LEDEN_LEDAEXT | LEDEN_LEDAPWM | LEDEN_PWM_LENGTHA; - u8 module = TWL4030_MODULE_PWMA; + u8 reg = TWL4030_PWMAON_REG; offset -= TWL4030_GPIO_MAX; if (offset) { ledclr_mask <<= 1; - module = TWL4030_MODULE_PWMB; + reg = TWL4030_PWMBON_REG; } /* initialize PWM to always-drive */ - status = twl_i2c_write_u8(module, 0x7f, - TWL4030_PWMx_PWMxOFF); + /* Configure PWM OFF register first */ + status = twl_i2c_write_u8(TWL4030_MODULE_LED, 0x7f, reg + 1); if (status < 0) goto done; - status = twl_i2c_write_u8(module, 0x7f, - TWL4030_PWMx_PWMxON); + + /* Followed by PWM ON register */ + status = twl_i2c_write_u8(TWL4030_MODULE_LED, 0x7f, reg); if (status < 0) goto done; /* init LED to not-driven (high) */ - module = TWL4030_MODULE_LED; - status = twl_i2c_read_u8(module, &cached_leden, - TWL4030_LED_LEDEN); + status = twl_i2c_read_u8(TWL4030_MODULE_LED, &cached_leden, + TWL4030_LED_LEDEN_REG); if (status < 0) goto done; cached_leden &= ~ledclr_mask; - status = twl_i2c_write_u8(module, cached_leden, - TWL4030_LED_LEDEN); + status = twl_i2c_write_u8(TWL4030_MODULE_LED, cached_leden, + TWL4030_LED_LEDEN_REG); if (status < 0) goto done; -- cgit v1.1 From 8754fccbae661a0020923cffd63e21de36d51e2e Mon Sep 17 00:00:00 2001 From: Roland Stigge Date: Thu, 15 Nov 2012 14:59:40 +0100 Subject: gpio: gpio-max710x: Support device tree probing For probing via device tree, we need to support the case without platform_data. In this case, chip.base is set to -1 for automatic numbering. Signed-off-by: Roland Stigge Acked-by: Wolfram Sang Signed-off-by: Linus Walleij --- drivers/gpio/gpio-max730x.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'drivers/gpio') diff --git a/drivers/gpio/gpio-max730x.c b/drivers/gpio/gpio-max730x.c index 05e2dac..c4bf86a 100644 --- a/drivers/gpio/gpio-max730x.c +++ b/drivers/gpio/gpio-max730x.c @@ -167,10 +167,6 @@ int __devinit __max730x_probe(struct max7301 *ts) int i, ret; pdata = dev->platform_data; - if (!pdata || !pdata->base) { - dev_err(dev, "incorrect or missing platform data\n"); - return -EINVAL; - } mutex_init(&ts->lock); dev_set_drvdata(dev, ts); @@ -178,7 +174,12 @@ int __devinit __max730x_probe(struct max7301 *ts) /* Power up the chip and disable IRQ output */ ts->write(dev, 0x04, 0x01); - ts->input_pullup_active = pdata->input_pullup_active; + if (pdata) { + ts->input_pullup_active = pdata->input_pullup_active; + ts->chip.base = pdata->base; + } else { + ts->chip.base = -1; + } ts->chip.label = dev->driver->name; ts->chip.direction_input = max7301_direction_input; @@ -186,7 +187,6 @@ int __devinit __max730x_probe(struct max7301 *ts) ts->chip.direction_output = max7301_direction_output; ts->chip.set = max7301_set; - ts->chip.base = pdata->base; ts->chip.ngpio = PIN_NUMBER; ts->chip.can_sleep = 1; ts->chip.dev = dev; -- cgit v1.1 From e91337609afdfaa1936c91b519ba7d7e426814cc Mon Sep 17 00:00:00 2001 From: Jamie Lentin Date: Sun, 28 Oct 2012 12:23:24 +0000 Subject: mvebu-gpio: Disable blinking when enabling a GPIO for output The plat-orion GPIO driver would disable any pin blinking whenever using a pin for output. Do the same here, as a blinking LED will continue to blink regardless of what the GPIO pin level is. Signed-off-by: Jamie Lentin Acked-by: Thomas Petazzoni Signed-off-by: Linus Walleij --- drivers/gpio/gpio-mvebu.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) (limited to 'drivers/gpio') diff --git a/drivers/gpio/gpio-mvebu.c b/drivers/gpio/gpio-mvebu.c index cf7afb9..be65c04 100644 --- a/drivers/gpio/gpio-mvebu.c +++ b/drivers/gpio/gpio-mvebu.c @@ -92,6 +92,11 @@ static inline void __iomem *mvebu_gpioreg_out(struct mvebu_gpio_chip *mvchip) return mvchip->membase + GPIO_OUT_OFF; } +static inline void __iomem *mvebu_gpioreg_blink(struct mvebu_gpio_chip *mvchip) +{ + return mvchip->membase + GPIO_BLINK_EN_OFF; +} + static inline void __iomem *mvebu_gpioreg_io_conf(struct mvebu_gpio_chip *mvchip) { return mvchip->membase + GPIO_IO_CONF_OFF; @@ -206,6 +211,23 @@ static int mvebu_gpio_get(struct gpio_chip *chip, unsigned pin) return (u >> pin) & 1; } +static void mvebu_gpio_blink(struct gpio_chip *chip, unsigned pin, int value) +{ + struct mvebu_gpio_chip *mvchip = + container_of(chip, struct mvebu_gpio_chip, chip); + unsigned long flags; + u32 u; + + spin_lock_irqsave(&mvchip->lock, flags); + u = readl_relaxed(mvebu_gpioreg_blink(mvchip)); + if (value) + u |= 1 << pin; + else + u &= ~(1 << pin); + writel_relaxed(u, mvebu_gpioreg_blink(mvchip)); + spin_unlock_irqrestore(&mvchip->lock, flags); +} + static int mvebu_gpio_direction_input(struct gpio_chip *chip, unsigned pin) { struct mvebu_gpio_chip *mvchip = @@ -244,6 +266,7 @@ static int mvebu_gpio_direction_output(struct gpio_chip *chip, unsigned pin, if (ret) return ret; + mvebu_gpio_blink(chip, pin, 0); mvebu_gpio_set(chip, pin, value); spin_lock_irqsave(&mvchip->lock, flags); -- cgit v1.1 From cb144fe8e0e70ccb12e93c9c9f010a25b3f2a158 Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Thu, 1 Nov 2012 11:22:11 +0100 Subject: gpio: adnp: Depend on OF_GPIO instead of OF The driver accesses the of_node field of struct gpio_chip, which is only available if OF_GPIO is selected. This solves a build issue on SPARC which conflicts with OF_GPIO and therefore does not provide this field. Signed-off-by: Thierry Reding Signed-off-by: Linus Walleij --- drivers/gpio/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpio') diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index f11d8e3..47150f5 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -466,7 +466,7 @@ config GPIO_ADP5588_IRQ config GPIO_ADNP tristate "Avionic Design N-bit GPIO expander" - depends on I2C && OF + depends on I2C && OF_GPIO help This option enables support for N GPIOs found on Avionic Design I2C GPIO expanders. The register space will be extended by powers -- cgit v1.1 From cbf24fad8e6e97b7cd7dd1099f5b801689dc234a Mon Sep 17 00:00:00 2001 From: "Daniel M. Weeks" Date: Tue, 6 Nov 2012 23:51:05 -0500 Subject: gpio-mcp23s08: Build I2C support even when CONFIG_I2C=m The driver has both SPI and I2C pieces. The appropriate pieces are built based on whether SPI and/or I2C is/are enabled. However, it was only checking if I2C was built-in, never if it was built as a module. This patch checks for either since building both this driver and I2C as modules is possible. Signed-off-by: Daniel M. Weeks Signed-off-by: Linus Walleij --- drivers/gpio/gpio-mcp23s08.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/gpio') diff --git a/drivers/gpio/gpio-mcp23s08.c b/drivers/gpio/gpio-mcp23s08.c index 0f42518..ce1c847 100644 --- a/drivers/gpio/gpio-mcp23s08.c +++ b/drivers/gpio/gpio-mcp23s08.c @@ -77,7 +77,7 @@ struct mcp23s08_driver_data { /*----------------------------------------------------------------------*/ -#ifdef CONFIG_I2C +#if IS_ENABLED(CONFIG_I2C) static int mcp23008_read(struct mcp23s08 *mcp, unsigned reg) { @@ -399,7 +399,7 @@ static int mcp23s08_probe_one(struct mcp23s08 *mcp, struct device *dev, break; #endif /* CONFIG_SPI_MASTER */ -#ifdef CONFIG_I2C +#if IS_ENABLED(CONFIG_I2C) case MCP_TYPE_008: mcp->ops = &mcp23008_ops; mcp->chip.ngpio = 8; @@ -473,7 +473,7 @@ fail: /*----------------------------------------------------------------------*/ -#ifdef CONFIG_I2C +#if IS_ENABLED(CONFIG_I2C) static int __devinit mcp230xx_probe(struct i2c_client *client, const struct i2c_device_id *id) -- cgit v1.1 From b53bc2819a71099ecfc3d61ba0796b3dcc6be321 Mon Sep 17 00:00:00 2001 From: Shiraz Hashim Date: Fri, 16 Nov 2012 10:45:25 +0530 Subject: gpio: SPEAr: add spi chipselect control driver SPEAr platform provides a provision to control chipselects of ARM PL022 Prime Cell spi controller through its system registers, which otherwise remains under PL022 control which some protocols do not want. This commit intends to provide the spi chipselect control in software over gpiolib interface. spi chip drivers can use the exported gpiolib interface to define their chipselect through DT or platform data. Cc: Grant Likely Signed-off-by: Shiraz Hashim Reviewed-by: Vipin Kumar Acked-by: Arnd Bergmann Signed-off-by: Viresh Kumar Signed-off-by: Linus Walleij --- drivers/gpio/Kconfig | 7 ++ drivers/gpio/Makefile | 1 + drivers/gpio/gpio-spear-spics.c | 217 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 225 insertions(+) create mode 100644 drivers/gpio/gpio-spear-spics.c (limited to 'drivers/gpio') diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index 9e3fb34..4f592c6 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -196,6 +196,13 @@ config GPIO_PXA help Say yes here to support the PXA GPIO device +config GPIO_SPEAR_SPICS + bool "ST SPEAr13xx SPI Chip Select as GPIO support" + depends on PLAT_SPEAR + select GENERIC_IRQ_CHIP + help + Say yes here to support ST SPEAr SPI Chip Select as GPIO device + config GPIO_STA2X11 bool "STA2x11/ConneXt GPIO support" depends on MFD_STA2X11 diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile index 1c1b63f..a268d99 100644 --- a/drivers/gpio/Makefile +++ b/drivers/gpio/Makefile @@ -59,6 +59,7 @@ obj-$(CONFIG_PLAT_SAMSUNG) += gpio-samsung.o obj-$(CONFIG_ARCH_SA1100) += gpio-sa1100.o obj-$(CONFIG_GPIO_SCH) += gpio-sch.o obj-$(CONFIG_GPIO_SODAVILLE) += gpio-sodaville.o +obj-$(CONFIG_GPIO_SPEAR_SPICS) += gpio-spear-spics.o obj-$(CONFIG_GPIO_STA2X11) += gpio-sta2x11.o obj-$(CONFIG_GPIO_STMPE) += gpio-stmpe.o obj-$(CONFIG_GPIO_STP_XWAY) += gpio-stp-xway.o diff --git a/drivers/gpio/gpio-spear-spics.c b/drivers/gpio/gpio-spear-spics.c new file mode 100644 index 0000000..5f45fc4 --- /dev/null +++ b/drivers/gpio/gpio-spear-spics.c @@ -0,0 +1,217 @@ +/* + * SPEAr platform SPI chipselect abstraction over gpiolib + * + * Copyright (C) 2012 ST Microelectronics + * Shiraz Hashim + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ + +#include +#include +#include +#include +#include +#include +#include + +/* maximum chipselects */ +#define NUM_OF_GPIO 4 + +/* + * Provision is available on some SPEAr SoCs to control ARM PL022 spi cs + * through system registers. This register lies outside spi (pl022) + * address space into system registers. + * + * It provides control for spi chip select lines so that any chipselect + * (out of 4 possible chipselects in pl022) can be made low to select + * the particular slave. + */ + +/** + * struct spear_spics - represents spi chip select control + * @base: base address + * @perip_cfg: configuration register + * @sw_enable_bit: bit to enable s/w control over chipselects + * @cs_value_bit: bit to program high or low chipselect + * @cs_enable_mask: mask to select bits required to select chipselect + * @cs_enable_shift: bit pos of cs_enable_mask + * @use_count: use count of a spi controller cs lines + * @last_off: stores last offset caller of set_value() + * @chip: gpio_chip abstraction + */ +struct spear_spics { + void __iomem *base; + u32 perip_cfg; + u32 sw_enable_bit; + u32 cs_value_bit; + u32 cs_enable_mask; + u32 cs_enable_shift; + unsigned long use_count; + int last_off; + struct gpio_chip chip; +}; + +/* gpio framework specific routines */ +static int spics_get_value(struct gpio_chip *chip, unsigned offset) +{ + return -ENXIO; +} + +static void spics_set_value(struct gpio_chip *chip, unsigned offset, int value) +{ + struct spear_spics *spics = container_of(chip, struct spear_spics, + chip); + u32 tmp; + + /* select chip select from register */ + tmp = readl_relaxed(spics->base + spics->perip_cfg); + if (spics->last_off != offset) { + spics->last_off = offset; + tmp &= ~(spics->cs_enable_mask << spics->cs_enable_shift); + tmp |= offset << spics->cs_enable_shift; + } + + /* toggle chip select line */ + tmp &= ~(0x1 << spics->cs_value_bit); + tmp |= value << spics->cs_value_bit; + writel_relaxed(tmp, spics->base + spics->perip_cfg); +} + +static int spics_direction_input(struct gpio_chip *chip, unsigned offset) +{ + return -ENXIO; +} + +static int spics_direction_output(struct gpio_chip *chip, unsigned offset, + int value) +{ + spics_set_value(chip, offset, value); + return 0; +} + +static int spics_request(struct gpio_chip *chip, unsigned offset) +{ + struct spear_spics *spics = container_of(chip, struct spear_spics, + chip); + u32 tmp; + + if (!spics->use_count++) { + tmp = readl_relaxed(spics->base + spics->perip_cfg); + tmp |= 0x1 << spics->sw_enable_bit; + tmp |= 0x1 << spics->cs_value_bit; + writel_relaxed(tmp, spics->base + spics->perip_cfg); + } + + return 0; +} + +static void spics_free(struct gpio_chip *chip, unsigned offset) +{ + struct spear_spics *spics = container_of(chip, struct spear_spics, + chip); + u32 tmp; + + if (!--spics->use_count) { + tmp = readl_relaxed(spics->base + spics->perip_cfg); + tmp &= ~(0x1 << spics->sw_enable_bit); + writel_relaxed(tmp, spics->base + spics->perip_cfg); + } +} + +static int spics_gpio_probe(struct platform_device *pdev) +{ + struct device_node *np = pdev->dev.of_node; + struct spear_spics *spics; + struct resource *res; + int ret; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) { + dev_err(&pdev->dev, "invalid IORESOURCE_MEM\n"); + return -EBUSY; + } + + spics = devm_kzalloc(&pdev->dev, sizeof(*spics), GFP_KERNEL); + if (!spics) { + dev_err(&pdev->dev, "memory allocation fail\n"); + return -ENOMEM; + } + + spics->base = devm_request_and_ioremap(&pdev->dev, res); + if (!spics->base) { + dev_err(&pdev->dev, "request and ioremap fail\n"); + return -ENOMEM; + } + + if (of_property_read_u32(np, "st-spics,peripcfg-reg", + &spics->perip_cfg)) + goto err_dt_data; + if (of_property_read_u32(np, "st-spics,sw-enable-bit", + &spics->sw_enable_bit)) + goto err_dt_data; + if (of_property_read_u32(np, "st-spics,cs-value-bit", + &spics->cs_value_bit)) + goto err_dt_data; + if (of_property_read_u32(np, "st-spics,cs-enable-mask", + &spics->cs_enable_mask)) + goto err_dt_data; + if (of_property_read_u32(np, "st-spics,cs-enable-shift", + &spics->cs_enable_shift)) + goto err_dt_data; + + platform_set_drvdata(pdev, spics); + + spics->chip.ngpio = NUM_OF_GPIO; + spics->chip.base = -1; + spics->chip.request = spics_request; + spics->chip.free = spics_free; + spics->chip.direction_input = spics_direction_input; + spics->chip.direction_output = spics_direction_output; + 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.owner = THIS_MODULE; + spics->last_off = -1; + + ret = gpiochip_add(&spics->chip); + if (ret) { + dev_err(&pdev->dev, "unable to add gpio chip\n"); + return ret; + } + + dev_info(&pdev->dev, "spear spics registered\n"); + return 0; + +err_dt_data: + dev_err(&pdev->dev, "DT probe failed\n"); + return -EINVAL; +} + +static const struct of_device_id spics_gpio_of_match[] = { + { .compatible = "st,spear-spics-gpio" }, + {} +}; +MODULE_DEVICE_TABLE(of, spics_gpio_of_match); + +static struct platform_driver spics_gpio_driver = { + .probe = spics_gpio_probe, + .driver = { + .owner = THIS_MODULE, + .name = "spear-spics-gpio", + .of_match_table = spics_gpio_of_match, + }, +}; + +static int __init spics_gpio_init(void) +{ + return platform_driver_register(&spics_gpio_driver); +} +subsys_initcall(spics_gpio_init); + +MODULE_AUTHOR("Shiraz Hashim "); +MODULE_DESCRIPTION("ST Microlectronics SPEAr SPI Chip Select Abstraction"); +MODULE_LICENSE("GPL"); -- cgit v1.1 From 3f0f8670608766ef26a178d4e80cad3ce030fecc Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Tue, 20 Nov 2012 12:40:15 +0100 Subject: gpiolib: let gpiochip_add_pin_range() specify offset Like with commit 3c739ad0df5eb41cd7adad879eda6aa09879eb76 it is not always enough to specify all the pins of a gpio_chip from offset zero to be added to a pin map range, since the mapping from GPIO to pin controller may not be linear at all, but need to be broken into a few consecutive sub-ranges or 1-pin entries for complicated cases. The ranges may also be sparse. This alters the signature of the function to accept offsets into both the GPIO-chip local pinspace and the pin controller local pinspace. Reviewed-by: Stephen Warren Reviewed-by: Viresh Kumar Signed-off-by: Linus Walleij --- drivers/gpio/gpiolib-of.c | 12 ++++++++++++ drivers/gpio/gpiolib.c | 32 +++++++++++++++++++++++++++++--- 2 files changed, 41 insertions(+), 3 deletions(-) (limited to 'drivers/gpio') diff --git a/drivers/gpio/gpiolib-of.c b/drivers/gpio/gpiolib-of.c index a40cd84..d542a14 100644 --- a/drivers/gpio/gpiolib-of.c +++ b/drivers/gpio/gpiolib-of.c @@ -238,8 +238,20 @@ static void of_gpiochip_add_pin_range(struct gpio_chip *chip) if (!pctldev) break; + /* + * This assumes that the n GPIO pins are consecutive in the + * GPIO number space, and that the pins are also consecutive + * in their local number space. Currently it is not possible + * to add different ranges for one and the same GPIO chip, + * as the code assumes that we have one consecutive range + * on both, mapping 1-to-1. + * + * TODO: make the OF bindings handle multiple sparse ranges + * on the same GPIO chip. + */ ret = gpiochip_add_pin_range(chip, pinctrl_dev_get_name(pctldev), + 0, /* offset in gpiochip */ pinspec.args[0], pinspec.args[1]); diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index c5f6500..6d13bea 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -1187,24 +1187,45 @@ EXPORT_SYMBOL_GPL(gpiochip_find); #ifdef CONFIG_PINCTRL +/** + * gpiochip_add_pin_range() - add a range for GPIO <-> pin mapping + * @chip: the gpiochip to add the range for + * @pinctrl_name: the dev_name() of the pin controller to map to + * @offset: the start offset in the current gpio_chip number space + * @pin_base: the start offset in the pin controller number space + * @npins: the number of pins from the offset of each pin space (GPIO and + * pin controller) to accumulate in this range + */ int gpiochip_add_pin_range(struct gpio_chip *chip, const char *pinctl_name, - unsigned int pin_base, unsigned int npins) + unsigned int offset, unsigned int pin_base, + unsigned int npins) { struct gpio_pin_range *pin_range; - pin_range = devm_kzalloc(chip->dev, sizeof(*pin_range), GFP_KERNEL); + pin_range = kzalloc(sizeof(*pin_range), GFP_KERNEL); if (!pin_range) { pr_err("%s: GPIO chip: failed to allocate pin ranges\n", chip->label); return -ENOMEM; } + /* Use local offset as range ID */ + pin_range->range.id = offset; + pin_range->range.gc = chip; pin_range->range.name = chip->label; - pin_range->range.base = chip->base; + pin_range->range.base = chip->base + offset; pin_range->range.pin_base = pin_base; pin_range->range.npins = npins; pin_range->pctldev = find_pinctrl_and_add_gpio_range(pinctl_name, &pin_range->range); + if (!pin_range->pctldev) { + pr_err("%s: GPIO chip: could not create pin range\n", + chip->label); + kfree(pin_range); + } + pr_debug("%s: GPIO chip: created GPIO range %d->%d ==> PIN %d->%d\n", + chip->label, offset, offset + npins - 1, + pin_base, pin_base + npins - 1); list_add_tail(&pin_range->node, &chip->pin_ranges); @@ -1212,6 +1233,10 @@ int gpiochip_add_pin_range(struct gpio_chip *chip, const char *pinctl_name, } EXPORT_SYMBOL_GPL(gpiochip_add_pin_range); +/** + * gpiochip_remove_pin_ranges() - remove all the GPIO <-> pin mappings + * @chip: the chip to remove all the mappings for + */ void gpiochip_remove_pin_ranges(struct gpio_chip *chip) { struct gpio_pin_range *pin_range, *tmp; @@ -1220,6 +1245,7 @@ void gpiochip_remove_pin_ranges(struct gpio_chip *chip) list_del(&pin_range->node); pinctrl_remove_gpio_range(pin_range->pctldev, &pin_range->range); + kfree(pin_range); } } EXPORT_SYMBOL_GPL(gpiochip_remove_pin_ranges); -- cgit v1.1 From 192c369c6165dff233f22aa70209a92b030d233d Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Tue, 20 Nov 2012 14:03:37 +0100 Subject: gpiolib: rename find_pinctrl_* Rename the function find_pinctrl_and_add_gpio_range() to pinctrl_find_and_add_gpio_range() so as to be consistent with the rest of the functions. Reviewed-by: Stephen Warren Reviewed-by: Viresh Kumar Signed-off-by: Linus Walleij --- drivers/gpio/gpiolib.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpio') diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index 6d13bea..a59d13d 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -1216,7 +1216,7 @@ int gpiochip_add_pin_range(struct gpio_chip *chip, const char *pinctl_name, pin_range->range.base = chip->base + offset; pin_range->range.pin_base = pin_base; pin_range->range.npins = npins; - pin_range->pctldev = find_pinctrl_and_add_gpio_range(pinctl_name, + pin_range->pctldev = pinctrl_find_and_add_gpio_range(pinctl_name, &pin_range->range); if (!pin_range->pctldev) { pr_err("%s: GPIO chip: could not create pin range\n", -- cgit v1.1 From 8f23ca1a73a096f21e6618d8e23df613daa5e532 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Tue, 20 Nov 2012 14:56:25 +0100 Subject: gpiolib: return any error code from range creation If we try to create a range for a certain GPIO chip and the target pin controller is not yet available it may return a probe deferral error code, so handle this all the way our by checking the error code. Reviewed-by: Stephen Warren Reviewed-by: Viresh Kumar Signed-off-by: Linus Walleij --- drivers/gpio/gpiolib.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers/gpio') diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index a59d13d..317ff04 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -1218,10 +1218,11 @@ int gpiochip_add_pin_range(struct gpio_chip *chip, const char *pinctl_name, pin_range->range.npins = npins; pin_range->pctldev = pinctrl_find_and_add_gpio_range(pinctl_name, &pin_range->range); - if (!pin_range->pctldev) { + if (IS_ERR(pin_range->pctldev)) { pr_err("%s: GPIO chip: could not create pin range\n", chip->label); kfree(pin_range); + return PTR_ERR(pin_range->pctldev); } pr_debug("%s: GPIO chip: created GPIO range %d->%d ==> PIN %d->%d\n", chip->label, offset, offset + npins - 1, -- cgit v1.1 From 316511c0134acec8f4ea730bd1897c7a1124a7c1 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Wed, 21 Nov 2012 08:48:09 +0100 Subject: gpiolib: rename pin range arguments To be crystal clear on what the arguments mean in this funtion dealing with both GPIO and PIN ranges with confusing naming, we now have gpio_offset and pin_offset and we are on the clear that these are offsets into the specific GPIO and pin controller respectively. The GPIO chip itself will of course keep track of the base offset into the global GPIO number space. Reviewed-by: Viresh Kumar Signed-off-by: Linus Walleij --- drivers/gpio/gpiolib.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) (limited to 'drivers/gpio') diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index 317ff04..26e27c1 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -1191,13 +1191,13 @@ EXPORT_SYMBOL_GPL(gpiochip_find); * gpiochip_add_pin_range() - add a range for GPIO <-> pin mapping * @chip: the gpiochip to add the range for * @pinctrl_name: the dev_name() of the pin controller to map to - * @offset: the start offset in the current gpio_chip number space - * @pin_base: the start offset in the pin controller number space + * @gpio_offset: the start offset in the current gpio_chip number space + * @pin_offset: the start offset in the pin controller number space * @npins: the number of pins from the offset of each pin space (GPIO and * pin controller) to accumulate in this range */ int gpiochip_add_pin_range(struct gpio_chip *chip, const char *pinctl_name, - unsigned int offset, unsigned int pin_base, + unsigned int gpio_offset, unsigned int pin_offset, unsigned int npins) { struct gpio_pin_range *pin_range; @@ -1210,11 +1210,11 @@ int gpiochip_add_pin_range(struct gpio_chip *chip, const char *pinctl_name, } /* Use local offset as range ID */ - pin_range->range.id = offset; + pin_range->range.id = gpio_offset; pin_range->range.gc = chip; pin_range->range.name = chip->label; - pin_range->range.base = chip->base + offset; - pin_range->range.pin_base = pin_base; + pin_range->range.base = chip->base + gpio_offset; + pin_range->range.pin_base = pin_offset; pin_range->range.npins = npins; pin_range->pctldev = pinctrl_find_and_add_gpio_range(pinctl_name, &pin_range->range); @@ -1224,9 +1224,10 @@ int gpiochip_add_pin_range(struct gpio_chip *chip, const char *pinctl_name, kfree(pin_range); return PTR_ERR(pin_range->pctldev); } - pr_debug("%s: GPIO chip: created GPIO range %d->%d ==> PIN %d->%d\n", - chip->label, offset, offset + npins - 1, - pin_base, pin_base + npins - 1); + pr_debug("GPIO chip %s: created GPIO range %d->%d ==> %s PIN %d->%d\n", + chip->label, gpio_offset, gpio_offset + npins - 1, + pinctl_name, + pin_offset, pin_offset + npins - 1); list_add_tail(&pin_range->node, &chip->pin_ranges); -- cgit v1.1 From b4d4b1f087b9d4d730eb70f24032395d7cd7e591 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Wed, 21 Nov 2012 14:33:56 +0800 Subject: gpiolib: Fix use after free in gpiochip_add_pin_range This is introduced by commit 9ab6e988 "gpiolib: return any error code from range creation". Signed-off-by: Axel Lin Signed-off-by: Linus Walleij --- drivers/gpio/gpiolib.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers/gpio') diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index 26e27c1..58b9838 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -1201,6 +1201,7 @@ int gpiochip_add_pin_range(struct gpio_chip *chip, const char *pinctl_name, unsigned int npins) { struct gpio_pin_range *pin_range; + int ret; pin_range = kzalloc(sizeof(*pin_range), GFP_KERNEL); if (!pin_range) { @@ -1219,10 +1220,11 @@ int gpiochip_add_pin_range(struct gpio_chip *chip, const char *pinctl_name, pin_range->pctldev = pinctrl_find_and_add_gpio_range(pinctl_name, &pin_range->range); if (IS_ERR(pin_range->pctldev)) { + ret = PTR_ERR(pin_range->pctldev); pr_err("%s: GPIO chip: could not create pin range\n", chip->label); kfree(pin_range); - return PTR_ERR(pin_range->pctldev); + return ret; } pr_debug("GPIO chip %s: created GPIO range %d->%d ==> %s PIN %d->%d\n", chip->label, gpio_offset, gpio_offset + npins - 1, -- cgit v1.1 From 8283c4ff57bdf3c1d8985c86e4ef44e1bb70f1f6 Mon Sep 17 00:00:00 2001 From: Bill Pemberton Date: Mon, 19 Nov 2012 13:20:08 -0500 Subject: gpio: remove use of __devexit_p CONFIG_HOTPLUG is going away as an option so __devexit_p is no longer needed. Signed-off-by: Bill Pemberton Cc: Grant Likely Cc: Peter Tyser Acked-by: Linus Walleij Acked-by: Mark Brown Signed-off-by: Greg Kroah-Hartman --- drivers/gpio/gpio-74x164.c | 2 +- drivers/gpio/gpio-ab8500.c | 2 +- drivers/gpio/gpio-adnp.c | 2 +- drivers/gpio/gpio-adp5520.c | 2 +- drivers/gpio/gpio-adp5588.c | 2 +- drivers/gpio/gpio-arizona.c | 2 +- drivers/gpio/gpio-cs5535.c | 2 +- drivers/gpio/gpio-da9052.c | 2 +- drivers/gpio/gpio-em.c | 2 +- drivers/gpio/gpio-generic.c | 2 +- drivers/gpio/gpio-ich.c | 2 +- drivers/gpio/gpio-janz-ttl.c | 2 +- drivers/gpio/gpio-langwell.c | 2 +- drivers/gpio/gpio-max7300.c | 2 +- drivers/gpio/gpio-max7301.c | 2 +- drivers/gpio/gpio-max732x.c | 2 +- drivers/gpio/gpio-mc33880.c | 2 +- drivers/gpio/gpio-mcp23s08.c | 2 +- drivers/gpio/gpio-ml-ioh.c | 2 +- drivers/gpio/gpio-msm-v2.c | 2 +- drivers/gpio/gpio-pch.c | 2 +- drivers/gpio/gpio-rc5t583.c | 2 +- drivers/gpio/gpio-rdc321x.c | 2 +- drivers/gpio/gpio-sch.c | 2 +- drivers/gpio/gpio-stmpe.c | 2 +- drivers/gpio/gpio-sx150x.c | 2 +- drivers/gpio/gpio-tc3589x.c | 2 +- drivers/gpio/gpio-tps6586x.c | 2 +- drivers/gpio/gpio-tps65910.c | 2 +- drivers/gpio/gpio-tps65912.c | 2 +- drivers/gpio/gpio-vr41xx.c | 2 +- drivers/gpio/gpio-vx855.c | 2 +- drivers/gpio/gpio-wm831x.c | 2 +- drivers/gpio/gpio-wm8350.c | 2 +- drivers/gpio/gpio-wm8994.c | 2 +- 35 files changed, 35 insertions(+), 35 deletions(-) (limited to 'drivers/gpio') diff --git a/drivers/gpio/gpio-74x164.c b/drivers/gpio/gpio-74x164.c index f05e542..ee1cb30 100644 --- a/drivers/gpio/gpio-74x164.c +++ b/drivers/gpio/gpio-74x164.c @@ -215,7 +215,7 @@ static struct spi_driver gen_74x164_driver = { .of_match_table = of_match_ptr(gen_74x164_dt_ids), }, .probe = gen_74x164_probe, - .remove = __devexit_p(gen_74x164_remove), + .remove = gen_74x164_remove, }; module_spi_driver(gen_74x164_driver); diff --git a/drivers/gpio/gpio-ab8500.c b/drivers/gpio/gpio-ab8500.c index 050c05d..48c3bab 100644 --- a/drivers/gpio/gpio-ab8500.c +++ b/drivers/gpio/gpio-ab8500.c @@ -499,7 +499,7 @@ static struct platform_driver ab8500_gpio_driver = { .owner = THIS_MODULE, }, .probe = ab8500_gpio_probe, - .remove = __devexit_p(ab8500_gpio_remove), + .remove = ab8500_gpio_remove, }; static int __init ab8500_gpio_init(void) diff --git a/drivers/gpio/gpio-adnp.c b/drivers/gpio/gpio-adnp.c index 3df8833..9796b9c 100644 --- a/drivers/gpio/gpio-adnp.c +++ b/drivers/gpio/gpio-adnp.c @@ -601,7 +601,7 @@ static struct i2c_driver adnp_i2c_driver = { .of_match_table = of_match_ptr(adnp_of_match), }, .probe = adnp_i2c_probe, - .remove = __devexit_p(adnp_i2c_remove), + .remove = adnp_i2c_remove, .id_table = adnp_i2c_id, }; module_i2c_driver(adnp_i2c_driver); diff --git a/drivers/gpio/gpio-adp5520.c b/drivers/gpio/gpio-adp5520.c index 2f263cc..fc01e6d 100644 --- a/drivers/gpio/gpio-adp5520.c +++ b/drivers/gpio/gpio-adp5520.c @@ -190,7 +190,7 @@ static struct platform_driver adp5520_gpio_driver = { .owner = THIS_MODULE, }, .probe = adp5520_gpio_probe, - .remove = __devexit_p(adp5520_gpio_remove), + .remove = adp5520_gpio_remove, }; module_platform_driver(adp5520_gpio_driver); diff --git a/drivers/gpio/gpio-adp5588.c b/drivers/gpio/gpio-adp5588.c index eeedad4..f762269 100644 --- a/drivers/gpio/gpio-adp5588.c +++ b/drivers/gpio/gpio-adp5588.c @@ -479,7 +479,7 @@ static struct i2c_driver adp5588_gpio_driver = { .name = DRV_NAME, }, .probe = adp5588_gpio_probe, - .remove = __devexit_p(adp5588_gpio_remove), + .remove = adp5588_gpio_remove, .id_table = adp5588_gpio_id, }; diff --git a/drivers/gpio/gpio-arizona.c b/drivers/gpio/gpio-arizona.c index 8740d2e..a406573 100644 --- a/drivers/gpio/gpio-arizona.c +++ b/drivers/gpio/gpio-arizona.c @@ -152,7 +152,7 @@ static struct platform_driver arizona_gpio_driver = { .driver.name = "arizona-gpio", .driver.owner = THIS_MODULE, .probe = arizona_gpio_probe, - .remove = __devexit_p(arizona_gpio_remove), + .remove = arizona_gpio_remove, }; module_platform_driver(arizona_gpio_driver); diff --git a/drivers/gpio/gpio-cs5535.c b/drivers/gpio/gpio-cs5535.c index 19eda1b..00f98f9 100644 --- a/drivers/gpio/gpio-cs5535.c +++ b/drivers/gpio/gpio-cs5535.c @@ -378,7 +378,7 @@ static struct platform_driver cs5535_gpio_driver = { .owner = THIS_MODULE, }, .probe = cs5535_gpio_probe, - .remove = __devexit_p(cs5535_gpio_remove), + .remove = cs5535_gpio_remove, }; module_platform_driver(cs5535_gpio_driver); diff --git a/drivers/gpio/gpio-da9052.c b/drivers/gpio/gpio-da9052.c index 24b8c29..9f5824d 100644 --- a/drivers/gpio/gpio-da9052.c +++ b/drivers/gpio/gpio-da9052.c @@ -238,7 +238,7 @@ static int __devexit da9052_gpio_remove(struct platform_device *pdev) static struct platform_driver da9052_gpio_driver = { .probe = da9052_gpio_probe, - .remove = __devexit_p(da9052_gpio_remove), + .remove = da9052_gpio_remove, .driver = { .name = "da9052-gpio", .owner = THIS_MODULE, diff --git a/drivers/gpio/gpio-em.c b/drivers/gpio/gpio-em.c index efb4c2d..e246165 100644 --- a/drivers/gpio/gpio-em.c +++ b/drivers/gpio/gpio-em.c @@ -399,7 +399,7 @@ static int __devexit em_gio_remove(struct platform_device *pdev) static struct platform_driver em_gio_device_driver = { .probe = em_gio_probe, - .remove = __devexit_p(em_gio_remove), + .remove = em_gio_remove, .driver = { .name = "em_gio", } diff --git a/drivers/gpio/gpio-generic.c b/drivers/gpio/gpio-generic.c index 82e2e4f..983f0f2 100644 --- a/drivers/gpio/gpio-generic.c +++ b/drivers/gpio/gpio-generic.c @@ -527,7 +527,7 @@ static struct platform_driver bgpio_driver = { }, .id_table = bgpio_id_table, .probe = bgpio_pdev_probe, - .remove = __devexit_p(bgpio_pdev_remove), + .remove = bgpio_pdev_remove, }; module_platform_driver(bgpio_driver); diff --git a/drivers/gpio/gpio-ich.c b/drivers/gpio/gpio-ich.c index d4d6179..c230263 100644 --- a/drivers/gpio/gpio-ich.c +++ b/drivers/gpio/gpio-ich.c @@ -467,7 +467,7 @@ static struct platform_driver ichx_gpio_driver = { .name = DRV_NAME, }, .probe = ichx_gpio_probe, - .remove = __devexit_p(ichx_gpio_remove), + .remove = ichx_gpio_remove, }; module_platform_driver(ichx_gpio_driver); diff --git a/drivers/gpio/gpio-janz-ttl.c b/drivers/gpio/gpio-janz-ttl.c index f2f000d..365dd04 100644 --- a/drivers/gpio/gpio-janz-ttl.c +++ b/drivers/gpio/gpio-janz-ttl.c @@ -234,7 +234,7 @@ static struct platform_driver ttl_driver = { .owner = THIS_MODULE, }, .probe = ttl_probe, - .remove = __devexit_p(ttl_remove), + .remove = ttl_remove, }; module_platform_driver(ttl_driver); diff --git a/drivers/gpio/gpio-langwell.c b/drivers/gpio/gpio-langwell.c index 202a992..b815896 100644 --- a/drivers/gpio/gpio-langwell.c +++ b/drivers/gpio/gpio-langwell.c @@ -499,7 +499,7 @@ static int __devexit wp_gpio_remove(struct platform_device *pdev) static struct platform_driver wp_gpio_driver = { .probe = wp_gpio_probe, - .remove = __devexit_p(wp_gpio_remove), + .remove = wp_gpio_remove, .driver = { .name = "wp_gpio", .owner = THIS_MODULE, diff --git a/drivers/gpio/gpio-max7300.c b/drivers/gpio/gpio-max7300.c index a5ca0ab..869235f 100644 --- a/drivers/gpio/gpio-max7300.c +++ b/drivers/gpio/gpio-max7300.c @@ -72,7 +72,7 @@ static struct i2c_driver max7300_driver = { .owner = THIS_MODULE, }, .probe = max7300_probe, - .remove = __devexit_p(max7300_remove), + .remove = max7300_remove, .id_table = max7300_id, }; diff --git a/drivers/gpio/gpio-max7301.c b/drivers/gpio/gpio-max7301.c index 741acfc..31bf49d 100644 --- a/drivers/gpio/gpio-max7301.c +++ b/drivers/gpio/gpio-max7301.c @@ -92,7 +92,7 @@ static struct spi_driver max7301_driver = { .owner = THIS_MODULE, }, .probe = max7301_probe, - .remove = __devexit_p(max7301_remove), + .remove = max7301_remove, .id_table = max7301_id, }; diff --git a/drivers/gpio/gpio-max732x.c b/drivers/gpio/gpio-max732x.c index 9504120..67ef5ea 100644 --- a/drivers/gpio/gpio-max732x.c +++ b/drivers/gpio/gpio-max732x.c @@ -690,7 +690,7 @@ static struct i2c_driver max732x_driver = { .owner = THIS_MODULE, }, .probe = max732x_probe, - .remove = __devexit_p(max732x_remove), + .remove = max732x_remove, .id_table = max732x_id, }; diff --git a/drivers/gpio/gpio-mc33880.c b/drivers/gpio/gpio-mc33880.c index 2de57ce..c6572e1 100644 --- a/drivers/gpio/gpio-mc33880.c +++ b/drivers/gpio/gpio-mc33880.c @@ -175,7 +175,7 @@ static struct spi_driver mc33880_driver = { .owner = THIS_MODULE, }, .probe = mc33880_probe, - .remove = __devexit_p(mc33880_remove), + .remove = mc33880_remove, }; static int __init mc33880_init(void) diff --git a/drivers/gpio/gpio-mcp23s08.c b/drivers/gpio/gpio-mcp23s08.c index 0f42518..47b6002 100644 --- a/drivers/gpio/gpio-mcp23s08.c +++ b/drivers/gpio/gpio-mcp23s08.c @@ -533,7 +533,7 @@ static struct i2c_driver mcp230xx_driver = { .owner = THIS_MODULE, }, .probe = mcp230xx_probe, - .remove = __devexit_p(mcp230xx_remove), + .remove = mcp230xx_remove, .id_table = mcp230xx_id, }; diff --git a/drivers/gpio/gpio-ml-ioh.c b/drivers/gpio/gpio-ml-ioh.c index 6a29ee1..c824b5d 100644 --- a/drivers/gpio/gpio-ml-ioh.c +++ b/drivers/gpio/gpio-ml-ioh.c @@ -606,7 +606,7 @@ static struct pci_driver ioh_gpio_driver = { .name = "ml_ioh_gpio", .id_table = ioh_gpio_pcidev_id, .probe = ioh_gpio_probe, - .remove = __devexit_p(ioh_gpio_remove), + .remove = ioh_gpio_remove, .suspend = ioh_gpio_suspend, .resume = ioh_gpio_resume }; diff --git a/drivers/gpio/gpio-msm-v2.c b/drivers/gpio/gpio-msm-v2.c index 38305be..26f5122 100644 --- a/drivers/gpio/gpio-msm-v2.c +++ b/drivers/gpio/gpio-msm-v2.c @@ -390,7 +390,7 @@ static int __devexit msm_gpio_remove(struct platform_device *dev) static struct platform_driver msm_gpio_driver = { .probe = msm_gpio_probe, - .remove = __devexit_p(msm_gpio_remove), + .remove = msm_gpio_remove, .driver = { .name = "msmgpio", .owner = THIS_MODULE, diff --git a/drivers/gpio/gpio-pch.c b/drivers/gpio/gpio-pch.c index 4ad0c4f..d693560 100644 --- a/drivers/gpio/gpio-pch.c +++ b/drivers/gpio/gpio-pch.c @@ -531,7 +531,7 @@ static struct pci_driver pch_gpio_driver = { .name = "pch_gpio", .id_table = pch_gpio_pcidev_id, .probe = pch_gpio_probe, - .remove = __devexit_p(pch_gpio_remove), + .remove = pch_gpio_remove, .suspend = pch_gpio_suspend, .resume = pch_gpio_resume }; diff --git a/drivers/gpio/gpio-rc5t583.c b/drivers/gpio/gpio-rc5t583.c index 08428bf..2931514 100644 --- a/drivers/gpio/gpio-rc5t583.c +++ b/drivers/gpio/gpio-rc5t583.c @@ -159,7 +159,7 @@ static struct platform_driver rc5t583_gpio_driver = { .owner = THIS_MODULE, }, .probe = rc5t583_gpio_probe, - .remove = __devexit_p(rc5t583_gpio_remove), + .remove = rc5t583_gpio_remove, }; static int __init rc5t583_gpio_init(void) diff --git a/drivers/gpio/gpio-rdc321x.c b/drivers/gpio/gpio-rdc321x.c index b62d443..17b971b 100644 --- a/drivers/gpio/gpio-rdc321x.c +++ b/drivers/gpio/gpio-rdc321x.c @@ -225,7 +225,7 @@ static struct platform_driver rdc321x_gpio_driver = { .driver.name = "rdc321x-gpio", .driver.owner = THIS_MODULE, .probe = rdc321x_gpio_probe, - .remove = __devexit_p(rdc321x_gpio_remove), + .remove = rdc321x_gpio_remove, }; module_platform_driver(rdc321x_gpio_driver); diff --git a/drivers/gpio/gpio-sch.c b/drivers/gpio/gpio-sch.c index 8707d45..ed54425 100644 --- a/drivers/gpio/gpio-sch.c +++ b/drivers/gpio/gpio-sch.c @@ -303,7 +303,7 @@ static struct platform_driver sch_gpio_driver = { .owner = THIS_MODULE, }, .probe = sch_gpio_probe, - .remove = __devexit_p(sch_gpio_remove), + .remove = sch_gpio_remove, }; module_platform_driver(sch_gpio_driver); diff --git a/drivers/gpio/gpio-stmpe.c b/drivers/gpio/gpio-stmpe.c index dce3472..821392d 100644 --- a/drivers/gpio/gpio-stmpe.c +++ b/drivers/gpio/gpio-stmpe.c @@ -412,7 +412,7 @@ static struct platform_driver stmpe_gpio_driver = { .driver.name = "stmpe-gpio", .driver.owner = THIS_MODULE, .probe = stmpe_gpio_probe, - .remove = __devexit_p(stmpe_gpio_remove), + .remove = stmpe_gpio_remove, }; static int __init stmpe_gpio_init(void) diff --git a/drivers/gpio/gpio-sx150x.c b/drivers/gpio/gpio-sx150x.c index eb3e215..0e1472d 100644 --- a/drivers/gpio/gpio-sx150x.c +++ b/drivers/gpio/gpio-sx150x.c @@ -646,7 +646,7 @@ static struct i2c_driver sx150x_driver = { .owner = THIS_MODULE }, .probe = sx150x_probe, - .remove = __devexit_p(sx150x_remove), + .remove = sx150x_remove, .id_table = sx150x_id, }; diff --git a/drivers/gpio/gpio-tc3589x.c b/drivers/gpio/gpio-tc3589x.c index 1e48317..debe67e 100644 --- a/drivers/gpio/gpio-tc3589x.c +++ b/drivers/gpio/gpio-tc3589x.c @@ -419,7 +419,7 @@ static struct platform_driver tc3589x_gpio_driver = { .driver.name = "tc3589x-gpio", .driver.owner = THIS_MODULE, .probe = tc3589x_gpio_probe, - .remove = __devexit_p(tc3589x_gpio_remove), + .remove = tc3589x_gpio_remove, }; static int __init tc3589x_gpio_init(void) diff --git a/drivers/gpio/gpio-tps6586x.c b/drivers/gpio/gpio-tps6586x.c index 2526b3b..d048ea8 100644 --- a/drivers/gpio/gpio-tps6586x.c +++ b/drivers/gpio/gpio-tps6586x.c @@ -137,7 +137,7 @@ static struct platform_driver tps6586x_gpio_driver = { .driver.name = "tps6586x-gpio", .driver.owner = THIS_MODULE, .probe = tps6586x_gpio_probe, - .remove = __devexit_p(tps6586x_gpio_remove), + .remove = tps6586x_gpio_remove, }; static int __init tps6586x_gpio_init(void) diff --git a/drivers/gpio/gpio-tps65910.c b/drivers/gpio/gpio-tps65910.c index 11f29c8..cf4e327 100644 --- a/drivers/gpio/gpio-tps65910.c +++ b/drivers/gpio/gpio-tps65910.c @@ -199,7 +199,7 @@ static struct platform_driver tps65910_gpio_driver = { .driver.name = "tps65910-gpio", .driver.owner = THIS_MODULE, .probe = tps65910_gpio_probe, - .remove = __devexit_p(tps65910_gpio_remove), + .remove = tps65910_gpio_remove, }; static int __init tps65910_gpio_init(void) diff --git a/drivers/gpio/gpio-tps65912.c b/drivers/gpio/gpio-tps65912.c index 99106d1..55c1d35 100644 --- a/drivers/gpio/gpio-tps65912.c +++ b/drivers/gpio/gpio-tps65912.c @@ -126,7 +126,7 @@ static struct platform_driver tps65912_gpio_driver = { .owner = THIS_MODULE, }, .probe = tps65912_gpio_probe, - .remove = __devexit_p(tps65912_gpio_remove), + .remove = tps65912_gpio_remove, }; static int __init tps65912_gpio_init(void) diff --git a/drivers/gpio/gpio-vr41xx.c b/drivers/gpio/gpio-vr41xx.c index 82d5c20..54d6e9a 100644 --- a/drivers/gpio/gpio-vr41xx.c +++ b/drivers/gpio/gpio-vr41xx.c @@ -564,7 +564,7 @@ static int __devexit giu_remove(struct platform_device *pdev) static struct platform_driver giu_device_driver = { .probe = giu_probe, - .remove = __devexit_p(giu_remove), + .remove = giu_remove, .driver = { .name = "GIU", .owner = THIS_MODULE, diff --git a/drivers/gpio/gpio-vx855.c b/drivers/gpio/gpio-vx855.c index 76ebfe5..43fcc42 100644 --- a/drivers/gpio/gpio-vx855.c +++ b/drivers/gpio/gpio-vx855.c @@ -312,7 +312,7 @@ static struct platform_driver vx855gpio_driver = { .owner = THIS_MODULE, }, .probe = vx855gpio_probe, - .remove = __devexit_p(vx855gpio_remove), + .remove = vx855gpio_remove, }; module_platform_driver(vx855gpio_driver); diff --git a/drivers/gpio/gpio-wm831x.c b/drivers/gpio/gpio-wm831x.c index b6eda35..273d541 100644 --- a/drivers/gpio/gpio-wm831x.c +++ b/drivers/gpio/gpio-wm831x.c @@ -286,7 +286,7 @@ static struct platform_driver wm831x_gpio_driver = { .driver.name = "wm831x-gpio", .driver.owner = THIS_MODULE, .probe = wm831x_gpio_probe, - .remove = __devexit_p(wm831x_gpio_remove), + .remove = wm831x_gpio_remove, }; static int __init wm831x_gpio_init(void) diff --git a/drivers/gpio/gpio-wm8350.c b/drivers/gpio/gpio-wm8350.c index fb42938..348a7d9 100644 --- a/drivers/gpio/gpio-wm8350.c +++ b/drivers/gpio/gpio-wm8350.c @@ -152,7 +152,7 @@ static struct platform_driver wm8350_gpio_driver = { .driver.name = "wm8350-gpio", .driver.owner = THIS_MODULE, .probe = wm8350_gpio_probe, - .remove = __devexit_p(wm8350_gpio_remove), + .remove = wm8350_gpio_remove, }; static int __init wm8350_gpio_init(void) diff --git a/drivers/gpio/gpio-wm8994.c b/drivers/gpio/gpio-wm8994.c index 1c764e7..59f0944 100644 --- a/drivers/gpio/gpio-wm8994.c +++ b/drivers/gpio/gpio-wm8994.c @@ -292,7 +292,7 @@ static struct platform_driver wm8994_gpio_driver = { .driver.name = "wm8994-gpio", .driver.owner = THIS_MODULE, .probe = wm8994_gpio_probe, - .remove = __devexit_p(wm8994_gpio_remove), + .remove = wm8994_gpio_remove, }; static int __init wm8994_gpio_init(void) -- cgit v1.1 From 3836309d93462bbf34851c078be6e5e77d888e3d Mon Sep 17 00:00:00 2001 From: Bill Pemberton Date: Mon, 19 Nov 2012 13:22:34 -0500 Subject: gpio: remove use of __devinit CONFIG_HOTPLUG is going away as an option so __devinit is no longer needed. Signed-off-by: Bill Pemberton Cc: Grant Likely Cc: Peter Tyser Cc: Santosh Shilimkar Cc: Kevin Hilman Acked-by: Linus Walleij Acked-by: Mark Brown Signed-off-by: Greg Kroah-Hartman --- drivers/gpio/gpio-74x164.c | 2 +- drivers/gpio/gpio-ab8500.c | 2 +- drivers/gpio/gpio-adnp.c | 2 +- drivers/gpio/gpio-adp5520.c | 2 +- drivers/gpio/gpio-adp5588.c | 2 +- drivers/gpio/gpio-arizona.c | 2 +- drivers/gpio/gpio-cs5535.c | 2 +- drivers/gpio/gpio-da9052.c | 2 +- drivers/gpio/gpio-em.c | 2 +- drivers/gpio/gpio-ep93xx.c | 2 +- drivers/gpio/gpio-generic.c | 2 +- drivers/gpio/gpio-ich.c | 6 +++--- drivers/gpio/gpio-janz-ttl.c | 6 +++--- drivers/gpio/gpio-langwell.c | 4 ++-- drivers/gpio/gpio-lpc32xx.c | 2 +- drivers/gpio/gpio-max7300.c | 2 +- drivers/gpio/gpio-max7301.c | 2 +- drivers/gpio/gpio-max730x.c | 2 +- drivers/gpio/gpio-max732x.c | 4 ++-- drivers/gpio/gpio-mc33880.c | 2 +- drivers/gpio/gpio-mcp23s08.c | 2 +- drivers/gpio/gpio-ml-ioh.c | 4 ++-- drivers/gpio/gpio-mpc5200.c | 4 ++-- drivers/gpio/gpio-msic.c | 2 +- drivers/gpio/gpio-msm-v2.c | 2 +- drivers/gpio/gpio-mvebu.c | 2 +- drivers/gpio/gpio-mxc.c | 4 ++-- drivers/gpio/gpio-mxs.c | 2 +- drivers/gpio/gpio-omap.c | 6 +++--- drivers/gpio/gpio-pca953x.c | 6 +++--- drivers/gpio/gpio-pch.c | 4 ++-- drivers/gpio/gpio-pxa.c | 6 +++--- drivers/gpio/gpio-rc5t583.c | 2 +- drivers/gpio/gpio-rdc321x.c | 2 +- drivers/gpio/gpio-sch.c | 2 +- drivers/gpio/gpio-sodaville.c | 4 ++-- drivers/gpio/gpio-sta2x11.c | 4 ++-- drivers/gpio/gpio-stmpe.c | 4 ++-- drivers/gpio/gpio-stp-xway.c | 2 +- drivers/gpio/gpio-sx150x.c | 2 +- drivers/gpio/gpio-tc3589x.c | 2 +- drivers/gpio/gpio-tegra.c | 2 +- drivers/gpio/gpio-timberdale.c | 2 +- drivers/gpio/gpio-tps6586x.c | 2 +- drivers/gpio/gpio-tps65910.c | 2 +- drivers/gpio/gpio-tps65912.c | 2 +- drivers/gpio/gpio-twl4030.c | 6 +++--- drivers/gpio/gpio-twl6040.c | 2 +- drivers/gpio/gpio-vr41xx.c | 2 +- drivers/gpio/gpio-vt8500.c | 2 +- drivers/gpio/gpio-vx855.c | 2 +- drivers/gpio/gpio-wm831x.c | 2 +- drivers/gpio/gpio-wm8350.c | 2 +- drivers/gpio/gpio-wm8994.c | 2 +- drivers/gpio/gpio-xilinx.c | 2 +- 55 files changed, 76 insertions(+), 76 deletions(-) (limited to 'drivers/gpio') diff --git a/drivers/gpio/gpio-74x164.c b/drivers/gpio/gpio-74x164.c index ee1cb30..2e6df41 100644 --- a/drivers/gpio/gpio-74x164.c +++ b/drivers/gpio/gpio-74x164.c @@ -105,7 +105,7 @@ static int gen_74x164_direction_output(struct gpio_chip *gc, return 0; } -static int __devinit gen_74x164_probe(struct spi_device *spi) +static int gen_74x164_probe(struct spi_device *spi) { struct gen_74x164_chip *chip; struct gen_74x164_chip_platform_data *pdata; diff --git a/drivers/gpio/gpio-ab8500.c b/drivers/gpio/gpio-ab8500.c index 48c3bab..0a636de 100644 --- a/drivers/gpio/gpio-ab8500.c +++ b/drivers/gpio/gpio-ab8500.c @@ -402,7 +402,7 @@ static void ab8500_gpio_irq_remove(struct ab8500_gpio *ab8500_gpio) } } -static int __devinit ab8500_gpio_probe(struct platform_device *pdev) +static int ab8500_gpio_probe(struct platform_device *pdev) { struct ab8500_platform_data *ab8500_pdata = dev_get_platdata(pdev->dev.parent); diff --git a/drivers/gpio/gpio-adnp.c b/drivers/gpio/gpio-adnp.c index 9796b9c..9f23684 100644 --- a/drivers/gpio/gpio-adnp.c +++ b/drivers/gpio/gpio-adnp.c @@ -516,7 +516,7 @@ static void adnp_irq_teardown(struct adnp *adnp) irq_domain_remove(adnp->domain); } -static __devinit int adnp_i2c_probe(struct i2c_client *client, +static int adnp_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct device_node *np = client->dev.of_node; diff --git a/drivers/gpio/gpio-adp5520.c b/drivers/gpio/gpio-adp5520.c index fc01e6d..b9fac75 100644 --- a/drivers/gpio/gpio-adp5520.c +++ b/drivers/gpio/gpio-adp5520.c @@ -87,7 +87,7 @@ static int adp5520_gpio_direction_output(struct gpio_chip *chip, return ret; } -static int __devinit adp5520_gpio_probe(struct platform_device *pdev) +static int adp5520_gpio_probe(struct platform_device *pdev) { struct adp5520_gpio_platform_data *pdata = pdev->dev.platform_data; struct adp5520_gpio *dev; diff --git a/drivers/gpio/gpio-adp5588.c b/drivers/gpio/gpio-adp5588.c index f762269..27001ec 100644 --- a/drivers/gpio/gpio-adp5588.c +++ b/drivers/gpio/gpio-adp5588.c @@ -346,7 +346,7 @@ static void adp5588_irq_teardown(struct adp5588_gpio *dev) } #endif /* CONFIG_GPIO_ADP5588_IRQ */ -static int __devinit adp5588_gpio_probe(struct i2c_client *client, +static int adp5588_gpio_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct adp5588_gpio_platform_data *pdata = client->dev.platform_data; diff --git a/drivers/gpio/gpio-arizona.c b/drivers/gpio/gpio-arizona.c index a406573..0a76fb0 100644 --- a/drivers/gpio/gpio-arizona.c +++ b/drivers/gpio/gpio-arizona.c @@ -94,7 +94,7 @@ static struct gpio_chip template_chip = { .can_sleep = 1, }; -static int __devinit arizona_gpio_probe(struct platform_device *pdev) +static int arizona_gpio_probe(struct platform_device *pdev) { struct arizona *arizona = dev_get_drvdata(pdev->dev.parent); struct arizona_pdata *pdata = arizona->dev->platform_data; diff --git a/drivers/gpio/gpio-cs5535.c b/drivers/gpio/gpio-cs5535.c index 00f98f9..d4a6d82 100644 --- a/drivers/gpio/gpio-cs5535.c +++ b/drivers/gpio/gpio-cs5535.c @@ -300,7 +300,7 @@ static struct cs5535_gpio_chip cs5535_gpio_chip = { }, }; -static int __devinit cs5535_gpio_probe(struct platform_device *pdev) +static int cs5535_gpio_probe(struct platform_device *pdev) { struct resource *res; int err = -EIO; diff --git a/drivers/gpio/gpio-da9052.c b/drivers/gpio/gpio-da9052.c index 9f5824d..5d2bc81 100644 --- a/drivers/gpio/gpio-da9052.c +++ b/drivers/gpio/gpio-da9052.c @@ -201,7 +201,7 @@ static struct gpio_chip reference_gp __devinitdata = { .base = -1, }; -static int __devinit da9052_gpio_probe(struct platform_device *pdev) +static int da9052_gpio_probe(struct platform_device *pdev) { struct da9052_gpio *gpio; struct da9052_pdata *pdata; diff --git a/drivers/gpio/gpio-em.c b/drivers/gpio/gpio-em.c index e246165..6253a05 100644 --- a/drivers/gpio/gpio-em.c +++ b/drivers/gpio/gpio-em.c @@ -268,7 +268,7 @@ static void em_gio_irq_domain_cleanup(struct em_gio_priv *p) /* FIXME: irq domain wants to be freed! */ } -static int __devinit em_gio_probe(struct platform_device *pdev) +static int em_gio_probe(struct platform_device *pdev) { struct gpio_em_config *pdata = pdev->dev.platform_data; struct em_gio_priv *p; diff --git a/drivers/gpio/gpio-ep93xx.c b/drivers/gpio/gpio-ep93xx.c index 9fe5b8fe..56b98ee 100644 --- a/drivers/gpio/gpio-ep93xx.c +++ b/drivers/gpio/gpio-ep93xx.c @@ -340,7 +340,7 @@ static int ep93xx_gpio_add_bank(struct bgpio_chip *bgc, struct device *dev, return gpiochip_add(&bgc->gc); } -static int __devinit ep93xx_gpio_probe(struct platform_device *pdev) +static int ep93xx_gpio_probe(struct platform_device *pdev) { struct ep93xx_gpio *ep93xx_gpio; struct resource *res; diff --git a/drivers/gpio/gpio-generic.c b/drivers/gpio/gpio-generic.c index 983f0f2..be37596 100644 --- a/drivers/gpio/gpio-generic.c +++ b/drivers/gpio/gpio-generic.c @@ -444,7 +444,7 @@ static void __iomem *bgpio_map(struct platform_device *pdev, return ret; } -static int __devinit bgpio_pdev_probe(struct platform_device *pdev) +static int bgpio_pdev_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct resource *r; diff --git a/drivers/gpio/gpio-ich.c b/drivers/gpio/gpio-ich.c index c230263..3ff9ff6 100644 --- a/drivers/gpio/gpio-ich.c +++ b/drivers/gpio/gpio-ich.c @@ -238,7 +238,7 @@ static void ichx_gpio_set(struct gpio_chip *chip, unsigned nr, int val) ichx_write_bit(GPIO_LVL, nr, val, 0); } -static void __devinit ichx_gpiolib_setup(struct gpio_chip *chip) +static void ichx_gpiolib_setup(struct gpio_chip *chip) { chip->owner = THIS_MODULE; chip->label = DRV_NAME; @@ -313,7 +313,7 @@ static struct ichx_desc intel5_desc = { .ngpio = 76, }; -static int __devinit ichx_gpio_request_regions(struct resource *res_base, +static int ichx_gpio_request_regions(struct resource *res_base, const char *name, u8 use_gpio) { int i; @@ -353,7 +353,7 @@ static void ichx_gpio_release_regions(struct resource *res_base, u8 use_gpio) } } -static int __devinit ichx_gpio_probe(struct platform_device *pdev) +static int ichx_gpio_probe(struct platform_device *pdev) { struct resource *res_base, *res_pm; int err; diff --git a/drivers/gpio/gpio-janz-ttl.c b/drivers/gpio/gpio-janz-ttl.c index 365dd04..cd28270 100644 --- a/drivers/gpio/gpio-janz-ttl.c +++ b/drivers/gpio/gpio-janz-ttl.c @@ -108,13 +108,13 @@ static void ttl_set_value(struct gpio_chip *gpio, unsigned offset, int value) spin_unlock(&mod->lock); } -static void __devinit ttl_write_reg(struct ttl_module *mod, u8 reg, u16 val) +static void ttl_write_reg(struct ttl_module *mod, u8 reg, u16 val) { iowrite16be(reg, &mod->regs->control); iowrite16be(val, &mod->regs->control); } -static void __devinit ttl_setup_device(struct ttl_module *mod) +static void ttl_setup_device(struct ttl_module *mod) { /* reset the device to a known state */ iowrite16be(0x0000, &mod->regs->control); @@ -140,7 +140,7 @@ static void __devinit ttl_setup_device(struct ttl_module *mod) ttl_write_reg(mod, MASTER_CONF_CTL, CONF_PAE | CONF_PBE | CONF_PCE); } -static int __devinit ttl_probe(struct platform_device *pdev) +static int ttl_probe(struct platform_device *pdev) { struct janz_platform_data *pdata; struct device *dev = &pdev->dev; diff --git a/drivers/gpio/gpio-langwell.c b/drivers/gpio/gpio-langwell.c index b815896..a3bf90d 100644 --- a/drivers/gpio/gpio-langwell.c +++ b/drivers/gpio/gpio-langwell.c @@ -332,7 +332,7 @@ static const struct dev_pm_ops lnw_gpio_pm_ops = { .runtime_idle = lnw_gpio_runtime_idle, }; -static int __devinit lnw_gpio_probe(struct pci_dev *pdev, +static int lnw_gpio_probe(struct pci_dev *pdev, const struct pci_device_id *id) { void *base; @@ -435,7 +435,7 @@ static struct pci_driver lnw_gpio_driver = { }; -static int __devinit wp_gpio_probe(struct platform_device *pdev) +static int wp_gpio_probe(struct platform_device *pdev) { struct lnw_gpio *lnw; struct gpio_chip *gc; diff --git a/drivers/gpio/gpio-lpc32xx.c b/drivers/gpio/gpio-lpc32xx.c index 3644e0d..9f676f4 100644 --- a/drivers/gpio/gpio-lpc32xx.c +++ b/drivers/gpio/gpio-lpc32xx.c @@ -542,7 +542,7 @@ static int lpc32xx_of_xlate(struct gpio_chip *gc, return gpiospec->args[1]; } -static int __devinit lpc32xx_gpio_probe(struct platform_device *pdev) +static int lpc32xx_gpio_probe(struct platform_device *pdev) { int i; diff --git a/drivers/gpio/gpio-max7300.c b/drivers/gpio/gpio-max7300.c index 869235f..5c92414 100644 --- a/drivers/gpio/gpio-max7300.c +++ b/drivers/gpio/gpio-max7300.c @@ -31,7 +31,7 @@ static int max7300_i2c_read(struct device *dev, unsigned int reg) return i2c_smbus_read_byte_data(client, reg); } -static int __devinit max7300_probe(struct i2c_client *client, +static int max7300_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct max7301 *ts; diff --git a/drivers/gpio/gpio-max7301.c b/drivers/gpio/gpio-max7301.c index 31bf49d..cf5d5b3 100644 --- a/drivers/gpio/gpio-max7301.c +++ b/drivers/gpio/gpio-max7301.c @@ -50,7 +50,7 @@ static int max7301_spi_read(struct device *dev, unsigned int reg) return word & 0xff; } -static int __devinit max7301_probe(struct spi_device *spi) +static int max7301_probe(struct spi_device *spi) { struct max7301 *ts; int ret; diff --git a/drivers/gpio/gpio-max730x.c b/drivers/gpio/gpio-max730x.c index 05e2dac..91b4f45 100644 --- a/drivers/gpio/gpio-max730x.c +++ b/drivers/gpio/gpio-max730x.c @@ -160,7 +160,7 @@ static void max7301_set(struct gpio_chip *chip, unsigned offset, int value) mutex_unlock(&ts->lock); } -int __devinit __max730x_probe(struct max7301 *ts) +int __max730x_probe(struct max7301 *ts) { struct device *dev = ts->dev; struct max7301_platform_data *pdata; diff --git a/drivers/gpio/gpio-max732x.c b/drivers/gpio/gpio-max732x.c index 67ef5ea..5edd2cb3 100644 --- a/drivers/gpio/gpio-max732x.c +++ b/drivers/gpio/gpio-max732x.c @@ -526,7 +526,7 @@ static void max732x_irq_teardown(struct max732x_chip *chip) } #endif -static int __devinit max732x_setup_gpio(struct max732x_chip *chip, +static int max732x_setup_gpio(struct max732x_chip *chip, const struct i2c_device_id *id, unsigned gpio_start) { @@ -574,7 +574,7 @@ static int __devinit max732x_setup_gpio(struct max732x_chip *chip, return port; } -static int __devinit max732x_probe(struct i2c_client *client, +static int max732x_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct max732x_platform_data *pdata; diff --git a/drivers/gpio/gpio-mc33880.c b/drivers/gpio/gpio-mc33880.c index c6572e1..79fc430 100644 --- a/drivers/gpio/gpio-mc33880.c +++ b/drivers/gpio/gpio-mc33880.c @@ -80,7 +80,7 @@ static void mc33880_set(struct gpio_chip *chip, unsigned offset, int value) mutex_unlock(&mc->lock); } -static int __devinit mc33880_probe(struct spi_device *spi) +static int mc33880_probe(struct spi_device *spi) { struct mc33880 *mc; struct mc33880_platform_data *pdata; diff --git a/drivers/gpio/gpio-mcp23s08.c b/drivers/gpio/gpio-mcp23s08.c index 47b6002..45079ae 100644 --- a/drivers/gpio/gpio-mcp23s08.c +++ b/drivers/gpio/gpio-mcp23s08.c @@ -475,7 +475,7 @@ fail: #ifdef CONFIG_I2C -static int __devinit mcp230xx_probe(struct i2c_client *client, +static int mcp230xx_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct mcp23s08_platform_data *pdata; diff --git a/drivers/gpio/gpio-ml-ioh.c b/drivers/gpio/gpio-ml-ioh.c index c824b5d..934b9bc 100644 --- a/drivers/gpio/gpio-ml-ioh.c +++ b/drivers/gpio/gpio-ml-ioh.c @@ -385,7 +385,7 @@ static irqreturn_t ioh_gpio_handler(int irq, void *dev_id) return ret; } -static __devinit void ioh_gpio_alloc_generic_chip(struct ioh_gpio *chip, +static void ioh_gpio_alloc_generic_chip(struct ioh_gpio *chip, unsigned int irq_start, unsigned int num) { struct irq_chip_generic *gc; @@ -406,7 +406,7 @@ static __devinit void ioh_gpio_alloc_generic_chip(struct ioh_gpio *chip, IRQ_NOREQUEST | IRQ_NOPROBE, 0); } -static int __devinit ioh_gpio_probe(struct pci_dev *pdev, +static int ioh_gpio_probe(struct pci_dev *pdev, const struct pci_device_id *id) { int ret; diff --git a/drivers/gpio/gpio-mpc5200.c b/drivers/gpio/gpio-mpc5200.c index 2c7cef3..42647f2 100644 --- a/drivers/gpio/gpio-mpc5200.c +++ b/drivers/gpio/gpio-mpc5200.c @@ -148,7 +148,7 @@ mpc52xx_wkup_gpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val) return 0; } -static int __devinit mpc52xx_wkup_gpiochip_probe(struct platform_device *ofdev) +static int mpc52xx_wkup_gpiochip_probe(struct platform_device *ofdev) { struct mpc52xx_gpiochip *chip; struct mpc52xx_gpio_wkup __iomem *regs; @@ -308,7 +308,7 @@ mpc52xx_simple_gpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val) return 0; } -static int __devinit mpc52xx_simple_gpiochip_probe(struct platform_device *ofdev) +static int mpc52xx_simple_gpiochip_probe(struct platform_device *ofdev) { struct mpc52xx_gpiochip *chip; struct gpio_chip *gc; diff --git a/drivers/gpio/gpio-msic.c b/drivers/gpio/gpio-msic.c index b389862..27ea7b9 100644 --- a/drivers/gpio/gpio-msic.c +++ b/drivers/gpio/gpio-msic.c @@ -256,7 +256,7 @@ static void msic_gpio_irq_handler(unsigned irq, struct irq_desc *desc) chip->irq_eoi(data); } -static int __devinit platform_msic_gpio_probe(struct platform_device *pdev) +static int platform_msic_gpio_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct intel_msic_gpio_pdata *pdata = dev->platform_data; diff --git a/drivers/gpio/gpio-msm-v2.c b/drivers/gpio/gpio-msm-v2.c index 26f5122..5451bec 100644 --- a/drivers/gpio/gpio-msm-v2.c +++ b/drivers/gpio/gpio-msm-v2.c @@ -352,7 +352,7 @@ static struct irq_chip msm_gpio_irq_chip = { .irq_set_wake = msm_gpio_irq_set_wake, }; -static int __devinit msm_gpio_probe(struct platform_device *dev) +static int msm_gpio_probe(struct platform_device *dev) { int i, irq, ret; diff --git a/drivers/gpio/gpio-mvebu.c b/drivers/gpio/gpio-mvebu.c index cf7afb9..88ad416 100644 --- a/drivers/gpio/gpio-mvebu.c +++ b/drivers/gpio/gpio-mvebu.c @@ -478,7 +478,7 @@ static struct of_device_id mvebu_gpio_of_match[] __devinitdata = { }; MODULE_DEVICE_TABLE(of, mvebu_gpio_of_match); -static int __devinit mvebu_gpio_probe(struct platform_device *pdev) +static int mvebu_gpio_probe(struct platform_device *pdev) { struct mvebu_gpio_chip *mvchip; const struct of_device_id *match; diff --git a/drivers/gpio/gpio-mxc.c b/drivers/gpio/gpio-mxc.c index 80f44bb..7877335c 100644 --- a/drivers/gpio/gpio-mxc.c +++ b/drivers/gpio/gpio-mxc.c @@ -356,7 +356,7 @@ static void __init mxc_gpio_init_gc(struct mxc_gpio_port *port, int irq_base) IRQ_NOREQUEST, 0); } -static void __devinit mxc_gpio_get_hw(struct platform_device *pdev) +static void mxc_gpio_get_hw(struct platform_device *pdev) { const struct of_device_id *of_id = of_match_device(mxc_gpio_dt_ids, &pdev->dev); @@ -395,7 +395,7 @@ static int mxc_gpio_to_irq(struct gpio_chip *gc, unsigned offset) return irq_find_mapping(port->domain, offset); } -static int __devinit mxc_gpio_probe(struct platform_device *pdev) +static int mxc_gpio_probe(struct platform_device *pdev) { struct device_node *np = pdev->dev.of_node; struct mxc_gpio_port *port; diff --git a/drivers/gpio/gpio-mxs.c b/drivers/gpio/gpio-mxs.c index 796fb13..fa2a63c 100644 --- a/drivers/gpio/gpio-mxs.c +++ b/drivers/gpio/gpio-mxs.c @@ -214,7 +214,7 @@ static const struct of_device_id mxs_gpio_dt_ids[] = { }; MODULE_DEVICE_TABLE(of, mxs_gpio_dt_ids); -static int __devinit mxs_gpio_probe(struct platform_device *pdev) +static int mxs_gpio_probe(struct platform_device *pdev) { const struct of_device_id *of_id = of_match_device(mxs_gpio_dt_ids, &pdev->dev); diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c index d335af1..148a4f2 100644 --- a/drivers/gpio/gpio-omap.c +++ b/drivers/gpio/gpio-omap.c @@ -1012,7 +1012,7 @@ static void omap_gpio_mod_init(struct gpio_bank *bank) dev_err(bank->dev, "Could not get gpio dbck\n"); } -static __devinit void +static void omap_mpuio_alloc_gc(struct gpio_bank *bank, unsigned int irq_start, unsigned int num) { @@ -1041,7 +1041,7 @@ omap_mpuio_alloc_gc(struct gpio_bank *bank, unsigned int irq_start, IRQ_NOREQUEST | IRQ_NOPROBE, 0); } -static void __devinit omap_gpio_chip_init(struct gpio_bank *bank) +static void omap_gpio_chip_init(struct gpio_bank *bank) { int j; static int gpio; @@ -1089,7 +1089,7 @@ static void __devinit omap_gpio_chip_init(struct gpio_bank *bank) static const struct of_device_id omap_gpio_match[]; -static int __devinit omap_gpio_probe(struct platform_device *pdev) +static int omap_gpio_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct device_node *node = dev->of_node; diff --git a/drivers/gpio/gpio-pca953x.c b/drivers/gpio/gpio-pca953x.c index 9c693ae..fff7c2b 100644 --- a/drivers/gpio/gpio-pca953x.c +++ b/drivers/gpio/gpio-pca953x.c @@ -602,7 +602,7 @@ pca953x_get_alt_pdata(struct i2c_client *client, int *gpio_base, u32 *invert) } #endif -static int __devinit device_pca953x_init(struct pca953x_chip *chip, u32 invert) +static int device_pca953x_init(struct pca953x_chip *chip, u32 invert) { int ret; @@ -621,7 +621,7 @@ out: return ret; } -static int __devinit device_pca957x_init(struct pca953x_chip *chip, u32 invert) +static int device_pca957x_init(struct pca953x_chip *chip, u32 invert) { int ret; u32 val = 0; @@ -652,7 +652,7 @@ out: return ret; } -static int __devinit pca953x_probe(struct i2c_client *client, +static int pca953x_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct pca953x_platform_data *pdata; diff --git a/drivers/gpio/gpio-pch.c b/drivers/gpio/gpio-pch.c index d693560..09568a4 100644 --- a/drivers/gpio/gpio-pch.c +++ b/drivers/gpio/gpio-pch.c @@ -325,7 +325,7 @@ static irqreturn_t pch_gpio_handler(int irq, void *dev_id) return ret; } -static __devinit void pch_gpio_alloc_generic_chip(struct pch_gpio *chip, +static void pch_gpio_alloc_generic_chip(struct pch_gpio *chip, unsigned int irq_start, unsigned int num) { struct irq_chip_generic *gc; @@ -345,7 +345,7 @@ static __devinit void pch_gpio_alloc_generic_chip(struct pch_gpio *chip, IRQ_NOREQUEST | IRQ_NOPROBE, 0); } -static int __devinit pch_gpio_probe(struct pci_dev *pdev, +static int pch_gpio_probe(struct pci_dev *pdev, const struct pci_device_id *id) { s32 ret; diff --git a/drivers/gpio/gpio-pxa.c b/drivers/gpio/gpio-pxa.c index 98d52cb..3e35243 100644 --- a/drivers/gpio/gpio-pxa.c +++ b/drivers/gpio/gpio-pxa.c @@ -250,7 +250,7 @@ static int pxa_gpio_of_xlate(struct gpio_chip *gc, } #endif -static int __devinit pxa_init_gpio_chip(int gpio_end, +static int pxa_init_gpio_chip(int gpio_end, int (*set_wake)(unsigned int, unsigned int)) { int i, gpio, nbanks = gpio_to_bank(gpio_end) + 1; @@ -490,7 +490,7 @@ const struct irq_domain_ops pxa_irq_domain_ops = { .xlate = irq_domain_xlate_twocell, }; -static int __devinit pxa_gpio_probe_dt(struct platform_device *pdev) +static int pxa_gpio_probe_dt(struct platform_device *pdev) { int ret, nr_banks, nr_gpios; struct device_node *prev, *next, *np = pdev->dev.of_node; @@ -537,7 +537,7 @@ err: #define pxa_gpio_probe_dt(pdev) (-1) #endif -static int __devinit pxa_gpio_probe(struct platform_device *pdev) +static int pxa_gpio_probe(struct platform_device *pdev) { struct pxa_gpio_chip *c; struct resource *res; diff --git a/drivers/gpio/gpio-rc5t583.c b/drivers/gpio/gpio-rc5t583.c index 2931514..59ee5de 100644 --- a/drivers/gpio/gpio-rc5t583.c +++ b/drivers/gpio/gpio-rc5t583.c @@ -111,7 +111,7 @@ static void rc5t583_gpio_free(struct gpio_chip *gc, unsigned offset) rc5t583_set_bits(parent, RC5T583_GPIO_PGSEL, BIT(offset)); } -static int __devinit rc5t583_gpio_probe(struct platform_device *pdev) +static int rc5t583_gpio_probe(struct platform_device *pdev) { struct rc5t583 *rc5t583 = dev_get_drvdata(pdev->dev.parent); struct rc5t583_platform_data *pdata = dev_get_platdata(rc5t583->dev); diff --git a/drivers/gpio/gpio-rdc321x.c b/drivers/gpio/gpio-rdc321x.c index 17b971b..dd3b49f 100644 --- a/drivers/gpio/gpio-rdc321x.c +++ b/drivers/gpio/gpio-rdc321x.c @@ -128,7 +128,7 @@ static int rdc_gpio_direction_input(struct gpio_chip *chip, unsigned gpio) /* * Cache the initial value of both GPIO data registers */ -static int __devinit rdc321x_gpio_probe(struct platform_device *pdev) +static int rdc321x_gpio_probe(struct platform_device *pdev) { int err; struct resource *r; diff --git a/drivers/gpio/gpio-sch.c b/drivers/gpio/gpio-sch.c index ed54425..4498855 100644 --- a/drivers/gpio/gpio-sch.c +++ b/drivers/gpio/gpio-sch.c @@ -185,7 +185,7 @@ static struct gpio_chip sch_gpio_resume = { .set = sch_gpio_resume_set, }; -static int __devinit sch_gpio_probe(struct platform_device *pdev) +static int sch_gpio_probe(struct platform_device *pdev) { struct resource *res; int err, id; diff --git a/drivers/gpio/gpio-sodaville.c b/drivers/gpio/gpio-sodaville.c index e25f731..88f374a 100644 --- a/drivers/gpio/gpio-sodaville.c +++ b/drivers/gpio/gpio-sodaville.c @@ -129,7 +129,7 @@ static struct irq_domain_ops irq_domain_sdv_ops = { .xlate = sdv_xlate, }; -static __devinit int sdv_register_irqsupport(struct sdv_gpio_chip_data *sd, +static int sdv_register_irqsupport(struct sdv_gpio_chip_data *sd, struct pci_dev *pdev) { struct irq_chip_type *ct; @@ -186,7 +186,7 @@ out_free_desc: return ret; } -static int __devinit sdv_gpio_probe(struct pci_dev *pdev, +static int sdv_gpio_probe(struct pci_dev *pdev, const struct pci_device_id *pci_id) { struct sdv_gpio_chip_data *sd; diff --git a/drivers/gpio/gpio-sta2x11.c b/drivers/gpio/gpio-sta2x11.c index 6064fb3..5585425 100644 --- a/drivers/gpio/gpio-sta2x11.c +++ b/drivers/gpio/gpio-sta2x11.c @@ -320,7 +320,7 @@ static irqreturn_t gsta_gpio_handler(int irq, void *dev_id) return ret; } -static __devinit void gsta_alloc_irq_chip(struct gsta_gpio *chip) +static void gsta_alloc_irq_chip(struct gsta_gpio *chip) { struct irq_chip_generic *gc; struct irq_chip_type *ct; @@ -353,7 +353,7 @@ static __devinit void gsta_alloc_irq_chip(struct gsta_gpio *chip) } /* The platform device used here is instantiated by the MFD device */ -static int __devinit gsta_probe(struct platform_device *dev) +static int gsta_probe(struct platform_device *dev) { int i, err; struct pci_dev *pdev; diff --git a/drivers/gpio/gpio-stmpe.c b/drivers/gpio/gpio-stmpe.c index 821392d..72cf618 100644 --- a/drivers/gpio/gpio-stmpe.c +++ b/drivers/gpio/gpio-stmpe.c @@ -267,7 +267,7 @@ static irqreturn_t stmpe_gpio_irq(int irq, void *dev) return IRQ_HANDLED; } -static int __devinit stmpe_gpio_irq_init(struct stmpe_gpio *stmpe_gpio) +static int stmpe_gpio_irq_init(struct stmpe_gpio *stmpe_gpio) { int base = stmpe_gpio->irq_base; int irq; @@ -301,7 +301,7 @@ static void stmpe_gpio_irq_remove(struct stmpe_gpio *stmpe_gpio) } } -static int __devinit stmpe_gpio_probe(struct platform_device *pdev) +static int stmpe_gpio_probe(struct platform_device *pdev) { struct stmpe *stmpe = dev_get_drvdata(pdev->dev.parent); struct stmpe_gpio_platform_data *pdata; diff --git a/drivers/gpio/gpio-stp-xway.c b/drivers/gpio/gpio-stp-xway.c index 8bead0b..85841ee7 100644 --- a/drivers/gpio/gpio-stp-xway.c +++ b/drivers/gpio/gpio-stp-xway.c @@ -197,7 +197,7 @@ static int xway_stp_hw_init(struct xway_stp *chip) return 0; } -static int __devinit xway_stp_probe(struct platform_device *pdev) +static int xway_stp_probe(struct platform_device *pdev) { struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); const __be32 *shadow, *groups, *dsl, *phy; diff --git a/drivers/gpio/gpio-sx150x.c b/drivers/gpio/gpio-sx150x.c index 0e1472d..9c93308 100644 --- a/drivers/gpio/gpio-sx150x.c +++ b/drivers/gpio/gpio-sx150x.c @@ -575,7 +575,7 @@ static void sx150x_remove_irq_chip(struct sx150x_chip *chip) } } -static int __devinit sx150x_probe(struct i2c_client *client, +static int sx150x_probe(struct i2c_client *client, const struct i2c_device_id *id) { static const u32 i2c_funcs = I2C_FUNC_SMBUS_BYTE_DATA | diff --git a/drivers/gpio/gpio-tc3589x.c b/drivers/gpio/gpio-tc3589x.c index debe67e..d69d7c8 100644 --- a/drivers/gpio/gpio-tc3589x.c +++ b/drivers/gpio/gpio-tc3589x.c @@ -311,7 +311,7 @@ static int tc3589x_gpio_irq_init(struct tc3589x_gpio *tc3589x_gpio, return 0; } -static int __devinit tc3589x_gpio_probe(struct platform_device *pdev) +static int tc3589x_gpio_probe(struct platform_device *pdev) { struct tc3589x *tc3589x = dev_get_drvdata(pdev->dev.parent); struct tc3589x_gpio_platform_data *pdata; diff --git a/drivers/gpio/gpio-tegra.c b/drivers/gpio/gpio-tegra.c index d982593..45105a2 100644 --- a/drivers/gpio/gpio-tegra.c +++ b/drivers/gpio/gpio-tegra.c @@ -376,7 +376,7 @@ static struct of_device_id tegra_gpio_of_match[] __devinitdata = { */ static struct lock_class_key gpio_lock_class; -static int __devinit tegra_gpio_probe(struct platform_device *pdev) +static int tegra_gpio_probe(struct platform_device *pdev) { const struct of_device_id *match; struct tegra_gpio_soc_config *config; diff --git a/drivers/gpio/gpio-timberdale.c b/drivers/gpio/gpio-timberdale.c index 1a3e2b9..728d6e7 100644 --- a/drivers/gpio/gpio-timberdale.c +++ b/drivers/gpio/gpio-timberdale.c @@ -222,7 +222,7 @@ static struct irq_chip timbgpio_irqchip = { .irq_set_type = timbgpio_irq_type, }; -static int __devinit timbgpio_probe(struct platform_device *pdev) +static int timbgpio_probe(struct platform_device *pdev) { int err, i; struct gpio_chip *gc; diff --git a/drivers/gpio/gpio-tps6586x.c b/drivers/gpio/gpio-tps6586x.c index d048ea8..b0b2ee0 100644 --- a/drivers/gpio/gpio-tps6586x.c +++ b/drivers/gpio/gpio-tps6586x.c @@ -80,7 +80,7 @@ static int tps6586x_gpio_output(struct gpio_chip *gc, unsigned offset, val, mask); } -static int __devinit tps6586x_gpio_probe(struct platform_device *pdev) +static int tps6586x_gpio_probe(struct platform_device *pdev) { struct tps6586x_platform_data *pdata; struct tps6586x_gpio *tps6586x_gpio; diff --git a/drivers/gpio/gpio-tps65910.c b/drivers/gpio/gpio-tps65910.c index cf4e327..635352c 100644 --- a/drivers/gpio/gpio-tps65910.c +++ b/drivers/gpio/gpio-tps65910.c @@ -113,7 +113,7 @@ static struct tps65910_board *tps65910_parse_dt_for_gpio(struct device *dev, } #endif -static int __devinit tps65910_gpio_probe(struct platform_device *pdev) +static int tps65910_gpio_probe(struct platform_device *pdev) { struct tps65910 *tps65910 = dev_get_drvdata(pdev->dev.parent); struct tps65910_board *pdata = dev_get_platdata(tps65910->dev); diff --git a/drivers/gpio/gpio-tps65912.c b/drivers/gpio/gpio-tps65912.c index 55c1d35..c0623b8 100644 --- a/drivers/gpio/gpio-tps65912.c +++ b/drivers/gpio/gpio-tps65912.c @@ -84,7 +84,7 @@ static struct gpio_chip template_chip = { .base = -1, }; -static int __devinit tps65912_gpio_probe(struct platform_device *pdev) +static int tps65912_gpio_probe(struct platform_device *pdev) { struct tps65912 *tps65912 = dev_get_drvdata(pdev->dev.parent); struct tps65912_board *pdata = tps65912->dev->platform_data; diff --git a/drivers/gpio/gpio-twl4030.c b/drivers/gpio/gpio-twl4030.c index c5f8ca2..648e560 100644 --- a/drivers/gpio/gpio-twl4030.c +++ b/drivers/gpio/gpio-twl4030.c @@ -352,7 +352,7 @@ static struct gpio_chip twl_gpiochip = { /*----------------------------------------------------------------------*/ -static int __devinit gpio_twl4030_pulls(u32 ups, u32 downs) +static int gpio_twl4030_pulls(u32 ups, u32 downs) { u8 message[6]; unsigned i, gpio_bit; @@ -377,7 +377,7 @@ static int __devinit gpio_twl4030_pulls(u32 ups, u32 downs) REG_GPIOPUPDCTR1, 5); } -static int __devinit gpio_twl4030_debounce(u32 debounce, u8 mmc_cd) +static int gpio_twl4030_debounce(u32 debounce, u8 mmc_cd) { u8 message[4]; @@ -419,7 +419,7 @@ static struct twl4030_gpio_platform_data *of_gpio_twl4030(struct device *dev) return omap_twl_info; } -static int __devinit gpio_twl4030_probe(struct platform_device *pdev) +static int gpio_twl4030_probe(struct platform_device *pdev) { struct twl4030_gpio_platform_data *pdata = pdev->dev.platform_data; struct device_node *node = pdev->dev.of_node; diff --git a/drivers/gpio/gpio-twl6040.c b/drivers/gpio/gpio-twl6040.c index dd58e8b..2962b84 100644 --- a/drivers/gpio/gpio-twl6040.c +++ b/drivers/gpio/gpio-twl6040.c @@ -82,7 +82,7 @@ static struct gpio_chip twl6040gpo_chip = { /*----------------------------------------------------------------------*/ -static int __devinit gpo_twl6040_probe(struct platform_device *pdev) +static int gpo_twl6040_probe(struct platform_device *pdev) { struct twl6040_gpo_data *pdata = pdev->dev.platform_data; struct device *twl6040_core_dev = pdev->dev.parent; diff --git a/drivers/gpio/gpio-vr41xx.c b/drivers/gpio/gpio-vr41xx.c index 54d6e9a..c13920b 100644 --- a/drivers/gpio/gpio-vr41xx.c +++ b/drivers/gpio/gpio-vr41xx.c @@ -490,7 +490,7 @@ static struct gpio_chip vr41xx_gpio_chip = { .to_irq = vr41xx_gpio_to_irq, }; -static int __devinit giu_probe(struct platform_device *pdev) +static int giu_probe(struct platform_device *pdev) { struct resource *res; unsigned int trigger, i, pin; diff --git a/drivers/gpio/gpio-vt8500.c b/drivers/gpio/gpio-vt8500.c index bcd8e4a..579f264 100644 --- a/drivers/gpio/gpio-vt8500.c +++ b/drivers/gpio/gpio-vt8500.c @@ -269,7 +269,7 @@ static struct of_device_id vt8500_gpio_dt_ids[] = { { /* Sentinel */ }, }; -static int __devinit vt8500_gpio_probe(struct platform_device *pdev) +static int vt8500_gpio_probe(struct platform_device *pdev) { void __iomem *gpio_base; struct device_node *np; diff --git a/drivers/gpio/gpio-vx855.c b/drivers/gpio/gpio-vx855.c index 43fcc42..90dd23b 100644 --- a/drivers/gpio/gpio-vx855.c +++ b/drivers/gpio/gpio-vx855.c @@ -219,7 +219,7 @@ static void vx855gpio_gpio_setup(struct vx855_gpio *vg) } /* This platform device is ordinarily registered by the vx855 mfd driver */ -static __devinit int vx855gpio_probe(struct platform_device *pdev) +static int vx855gpio_probe(struct platform_device *pdev) { struct resource *res_gpi; struct resource *res_gpo; diff --git a/drivers/gpio/gpio-wm831x.c b/drivers/gpio/gpio-wm831x.c index 273d541..8182145 100644 --- a/drivers/gpio/gpio-wm831x.c +++ b/drivers/gpio/gpio-wm831x.c @@ -243,7 +243,7 @@ static struct gpio_chip template_chip = { .can_sleep = 1, }; -static int __devinit wm831x_gpio_probe(struct platform_device *pdev) +static int wm831x_gpio_probe(struct platform_device *pdev) { struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent); struct wm831x_pdata *pdata = wm831x->dev->platform_data; diff --git a/drivers/gpio/gpio-wm8350.c b/drivers/gpio/gpio-wm8350.c index 348a7d9..2b99fc3 100644 --- a/drivers/gpio/gpio-wm8350.c +++ b/drivers/gpio/gpio-wm8350.c @@ -109,7 +109,7 @@ static struct gpio_chip template_chip = { .can_sleep = 1, }; -static int __devinit wm8350_gpio_probe(struct platform_device *pdev) +static int wm8350_gpio_probe(struct platform_device *pdev) { struct wm8350 *wm8350 = dev_get_drvdata(pdev->dev.parent); struct wm8350_platform_data *pdata = wm8350->dev->platform_data; diff --git a/drivers/gpio/gpio-wm8994.c b/drivers/gpio/gpio-wm8994.c index 59f0944..fc39178 100644 --- a/drivers/gpio/gpio-wm8994.c +++ b/drivers/gpio/gpio-wm8994.c @@ -245,7 +245,7 @@ static struct gpio_chip template_chip = { .can_sleep = 1, }; -static int __devinit wm8994_gpio_probe(struct platform_device *pdev) +static int wm8994_gpio_probe(struct platform_device *pdev) { struct wm8994 *wm8994 = dev_get_drvdata(pdev->dev.parent); struct wm8994_pdata *pdata = wm8994->dev->platform_data; diff --git a/drivers/gpio/gpio-xilinx.c b/drivers/gpio/gpio-xilinx.c index 79b0fe8..5a35138 100644 --- a/drivers/gpio/gpio-xilinx.c +++ b/drivers/gpio/gpio-xilinx.c @@ -159,7 +159,7 @@ static void xgpio_save_regs(struct of_mm_gpio_chip *mm_gc) * driver data structure. It returns 0, if the driver is bound to the GPIO * device, or a negative value if there is an error. */ -static int __devinit xgpio_of_probe(struct device_node *np) +static int xgpio_of_probe(struct device_node *np) { struct xgpio_instance *chip; int status = 0; -- cgit v1.1 From aeca8ad1f0613a76a8f5fed174810fab9bc424cf Mon Sep 17 00:00:00 2001 From: Bill Pemberton Date: Mon, 19 Nov 2012 13:24:14 -0500 Subject: gpio: remove use of __devinitdata CONFIG_HOTPLUG is going away as an option so __devinitdata is no longer needed. Signed-off-by: Bill Pemberton Cc: Grant Likely Acked-by: Linus Walleij Signed-off-by: Greg Kroah-Hartman --- drivers/gpio/gpio-da9052.c | 2 +- drivers/gpio/gpio-lpc32xx.c | 2 +- drivers/gpio/gpio-mvebu.c | 2 +- drivers/gpio/gpio-tegra.c | 2 +- drivers/gpio/gpio-xilinx.c | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers/gpio') diff --git a/drivers/gpio/gpio-da9052.c b/drivers/gpio/gpio-da9052.c index 5d2bc81..2139825 100644 --- a/drivers/gpio/gpio-da9052.c +++ b/drivers/gpio/gpio-da9052.c @@ -188,7 +188,7 @@ static int da9052_gpio_to_irq(struct gpio_chip *gc, u32 offset) return da9052->irq_base + DA9052_IRQ_GPI0 + offset; } -static struct gpio_chip reference_gp __devinitdata = { +static struct gpio_chip reference_gp = { .label = "da9052-gpio", .owner = THIS_MODULE, .get = da9052_gpio_get, diff --git a/drivers/gpio/gpio-lpc32xx.c b/drivers/gpio/gpio-lpc32xx.c index 9f676f4..36d7dee 100644 --- a/drivers/gpio/gpio-lpc32xx.c +++ b/drivers/gpio/gpio-lpc32xx.c @@ -559,7 +559,7 @@ static int lpc32xx_gpio_probe(struct platform_device *pdev) } #ifdef CONFIG_OF -static struct of_device_id lpc32xx_gpio_of_match[] __devinitdata = { +static struct of_device_id lpc32xx_gpio_of_match[] = { { .compatible = "nxp,lpc3220-gpio", }, { }, }; diff --git a/drivers/gpio/gpio-mvebu.c b/drivers/gpio/gpio-mvebu.c index 88ad416..f2a04ba 100644 --- a/drivers/gpio/gpio-mvebu.c +++ b/drivers/gpio/gpio-mvebu.c @@ -459,7 +459,7 @@ static struct platform_device_id mvebu_gpio_ids[] = { }; MODULE_DEVICE_TABLE(platform, mvebu_gpio_ids); -static struct of_device_id mvebu_gpio_of_match[] __devinitdata = { +static struct of_device_id mvebu_gpio_of_match[] = { { .compatible = "marvell,orion-gpio", .data = (void*) MVEBU_GPIO_SOC_VARIANT_ORION, diff --git a/drivers/gpio/gpio-tegra.c b/drivers/gpio/gpio-tegra.c index 45105a2..4cd3e1d 100644 --- a/drivers/gpio/gpio-tegra.c +++ b/drivers/gpio/gpio-tegra.c @@ -365,7 +365,7 @@ static struct tegra_gpio_soc_config tegra30_gpio_config = { .upper_offset = 0x80, }; -static struct of_device_id tegra_gpio_of_match[] __devinitdata = { +static struct of_device_id tegra_gpio_of_match[] = { { .compatible = "nvidia,tegra30-gpio", .data = &tegra30_gpio_config }, { .compatible = "nvidia,tegra20-gpio", .data = &tegra20_gpio_config }, { }, diff --git a/drivers/gpio/gpio-xilinx.c b/drivers/gpio/gpio-xilinx.c index 5a35138..9ae7aa8 100644 --- a/drivers/gpio/gpio-xilinx.c +++ b/drivers/gpio/gpio-xilinx.c @@ -209,7 +209,7 @@ static int xgpio_of_probe(struct device_node *np) return 0; } -static struct of_device_id xgpio_of_match[] __devinitdata = { +static struct of_device_id xgpio_of_match[] = { { .compatible = "xlnx,xps-gpio-1.00.a", }, { /* end of list */ }, }; -- cgit v1.1 From b5ba78de76b0a39cfcf08dec78e90b737e995965 Mon Sep 17 00:00:00 2001 From: Bill Pemberton Date: Mon, 19 Nov 2012 13:25:05 -0500 Subject: gpio: remove use of __devinitconst CONFIG_HOTPLUG is going away as an option so __devinitconst is no longer needed. Signed-off-by: Bill Pemberton Cc: Grant Likely Acked-by: Linus Walleij Signed-off-by: Greg Kroah-Hartman --- drivers/gpio/gpio-adnp.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/gpio') diff --git a/drivers/gpio/gpio-adnp.c b/drivers/gpio/gpio-adnp.c index 9f23684..2a34204 100644 --- a/drivers/gpio/gpio-adnp.c +++ b/drivers/gpio/gpio-adnp.c @@ -582,13 +582,13 @@ static __devexit int adnp_i2c_remove(struct i2c_client *client) return 0; } -static const struct i2c_device_id adnp_i2c_id[] __devinitconst = { +static const struct i2c_device_id adnp_i2c_id[] = { { "gpio-adnp" }, { }, }; MODULE_DEVICE_TABLE(i2c, adnp_i2c_id); -static const struct of_device_id adnp_of_match[] __devinitconst = { +static const struct of_device_id adnp_of_match[] = { { .compatible = "ad,gpio-adnp", }, { }, }; -- cgit v1.1 From 206210ce68c1feb1d9d05839ceacc97ad1b0b324 Mon Sep 17 00:00:00 2001 From: Bill Pemberton Date: Mon, 19 Nov 2012 13:25:50 -0500 Subject: gpio: remove use of __devexit CONFIG_HOTPLUG is going away as an option so __devexit is no longer needed. Signed-off-by: Bill Pemberton Cc: Grant Likely Acked-by: Linus Walleij Cc: Peter Tyser Acked-by: Mark Brown Signed-off-by: Greg Kroah-Hartman --- drivers/gpio/gpio-74x164.c | 2 +- drivers/gpio/gpio-ab8500.c | 2 +- drivers/gpio/gpio-adnp.c | 2 +- drivers/gpio/gpio-adp5520.c | 2 +- drivers/gpio/gpio-adp5588.c | 2 +- drivers/gpio/gpio-arizona.c | 2 +- drivers/gpio/gpio-cs5535.c | 2 +- drivers/gpio/gpio-da9052.c | 2 +- drivers/gpio/gpio-em.c | 2 +- drivers/gpio/gpio-generic.c | 2 +- drivers/gpio/gpio-ich.c | 2 +- drivers/gpio/gpio-janz-ttl.c | 2 +- drivers/gpio/gpio-langwell.c | 2 +- drivers/gpio/gpio-max7300.c | 2 +- drivers/gpio/gpio-max7301.c | 2 +- drivers/gpio/gpio-max730x.c | 2 +- drivers/gpio/gpio-max732x.c | 2 +- drivers/gpio/gpio-mc33880.c | 2 +- drivers/gpio/gpio-mcp23s08.c | 2 +- drivers/gpio/gpio-ml-ioh.c | 2 +- drivers/gpio/gpio-msm-v2.c | 2 +- drivers/gpio/gpio-pch.c | 2 +- drivers/gpio/gpio-rc5t583.c | 2 +- drivers/gpio/gpio-rdc321x.c | 2 +- drivers/gpio/gpio-sch.c | 2 +- drivers/gpio/gpio-stmpe.c | 2 +- drivers/gpio/gpio-sx150x.c | 2 +- drivers/gpio/gpio-tc3589x.c | 2 +- drivers/gpio/gpio-timberdale.c | 2 +- drivers/gpio/gpio-tps6586x.c | 2 +- drivers/gpio/gpio-tps65910.c | 2 +- drivers/gpio/gpio-tps65912.c | 2 +- drivers/gpio/gpio-twl4030.c | 2 +- drivers/gpio/gpio-twl6040.c | 2 +- drivers/gpio/gpio-vr41xx.c | 2 +- drivers/gpio/gpio-vx855.c | 2 +- drivers/gpio/gpio-wm831x.c | 2 +- drivers/gpio/gpio-wm8350.c | 2 +- drivers/gpio/gpio-wm8994.c | 2 +- 39 files changed, 39 insertions(+), 39 deletions(-) (limited to 'drivers/gpio') diff --git a/drivers/gpio/gpio-74x164.c b/drivers/gpio/gpio-74x164.c index 2e6df41..464be96 100644 --- a/drivers/gpio/gpio-74x164.c +++ b/drivers/gpio/gpio-74x164.c @@ -181,7 +181,7 @@ exit_destroy: return ret; } -static int __devexit gen_74x164_remove(struct spi_device *spi) +static int gen_74x164_remove(struct spi_device *spi) { struct gen_74x164_chip *chip; int ret; diff --git a/drivers/gpio/gpio-ab8500.c b/drivers/gpio/gpio-ab8500.c index 0a636de..983ad42 100644 --- a/drivers/gpio/gpio-ab8500.c +++ b/drivers/gpio/gpio-ab8500.c @@ -474,7 +474,7 @@ out_free: * ab8500_gpio_remove() - remove Ab8500-gpio driver * @pdev : Platform device registered */ -static int __devexit ab8500_gpio_remove(struct platform_device *pdev) +static int ab8500_gpio_remove(struct platform_device *pdev) { struct ab8500_gpio *ab8500_gpio = platform_get_drvdata(pdev); int ret; diff --git a/drivers/gpio/gpio-adnp.c b/drivers/gpio/gpio-adnp.c index 2a34204..e60567f 100644 --- a/drivers/gpio/gpio-adnp.c +++ b/drivers/gpio/gpio-adnp.c @@ -563,7 +563,7 @@ teardown: return err; } -static __devexit int adnp_i2c_remove(struct i2c_client *client) +static int adnp_i2c_remove(struct i2c_client *client) { struct adnp *adnp = i2c_get_clientdata(client); struct device_node *np = client->dev.of_node; diff --git a/drivers/gpio/gpio-adp5520.c b/drivers/gpio/gpio-adp5520.c index b9fac75..8afa95f 100644 --- a/drivers/gpio/gpio-adp5520.c +++ b/drivers/gpio/gpio-adp5520.c @@ -167,7 +167,7 @@ err: return ret; } -static int __devexit adp5520_gpio_remove(struct platform_device *pdev) +static int adp5520_gpio_remove(struct platform_device *pdev) { struct adp5520_gpio *dev; int ret; diff --git a/drivers/gpio/gpio-adp5588.c b/drivers/gpio/gpio-adp5588.c index 27001ec..2ba5698 100644 --- a/drivers/gpio/gpio-adp5588.c +++ b/drivers/gpio/gpio-adp5588.c @@ -438,7 +438,7 @@ err: return ret; } -static int __devexit adp5588_gpio_remove(struct i2c_client *client) +static int adp5588_gpio_remove(struct i2c_client *client) { struct adp5588_gpio_platform_data *pdata = client->dev.platform_data; struct adp5588_gpio *dev = i2c_get_clientdata(client); diff --git a/drivers/gpio/gpio-arizona.c b/drivers/gpio/gpio-arizona.c index 0a76fb0..0ea853f 100644 --- a/drivers/gpio/gpio-arizona.c +++ b/drivers/gpio/gpio-arizona.c @@ -141,7 +141,7 @@ err: return ret; } -static int __devexit arizona_gpio_remove(struct platform_device *pdev) +static int arizona_gpio_remove(struct platform_device *pdev) { struct arizona_gpio *arizona_gpio = platform_get_drvdata(pdev); diff --git a/drivers/gpio/gpio-cs5535.c b/drivers/gpio/gpio-cs5535.c index d4a6d82..c0a3aeb 100644 --- a/drivers/gpio/gpio-cs5535.c +++ b/drivers/gpio/gpio-cs5535.c @@ -355,7 +355,7 @@ done: return err; } -static int __devexit cs5535_gpio_remove(struct platform_device *pdev) +static int cs5535_gpio_remove(struct platform_device *pdev) { struct resource *r; int err; diff --git a/drivers/gpio/gpio-da9052.c b/drivers/gpio/gpio-da9052.c index 2139825..a05aacd 100644 --- a/drivers/gpio/gpio-da9052.c +++ b/drivers/gpio/gpio-da9052.c @@ -229,7 +229,7 @@ static int da9052_gpio_probe(struct platform_device *pdev) return 0; } -static int __devexit da9052_gpio_remove(struct platform_device *pdev) +static int da9052_gpio_remove(struct platform_device *pdev) { struct da9052_gpio *gpio = platform_get_drvdata(pdev); diff --git a/drivers/gpio/gpio-em.c b/drivers/gpio/gpio-em.c index 6253a05..320a718 100644 --- a/drivers/gpio/gpio-em.c +++ b/drivers/gpio/gpio-em.c @@ -375,7 +375,7 @@ err0: return ret; } -static int __devexit em_gio_remove(struct platform_device *pdev) +static int em_gio_remove(struct platform_device *pdev) { struct em_gio_priv *p = platform_get_drvdata(pdev); struct resource *irq[2]; diff --git a/drivers/gpio/gpio-generic.c b/drivers/gpio/gpio-generic.c index be37596..05fcc0f 100644 --- a/drivers/gpio/gpio-generic.c +++ b/drivers/gpio/gpio-generic.c @@ -507,7 +507,7 @@ static int bgpio_pdev_probe(struct platform_device *pdev) return gpiochip_add(&bgc->gc); } -static int __devexit bgpio_pdev_remove(struct platform_device *pdev) +static int bgpio_pdev_remove(struct platform_device *pdev) { struct bgpio_chip *bgc = platform_get_drvdata(pdev); diff --git a/drivers/gpio/gpio-ich.c b/drivers/gpio/gpio-ich.c index 3ff9ff6..6cc87ac 100644 --- a/drivers/gpio/gpio-ich.c +++ b/drivers/gpio/gpio-ich.c @@ -442,7 +442,7 @@ add_err: return err; } -static int __devexit ichx_gpio_remove(struct platform_device *pdev) +static int ichx_gpio_remove(struct platform_device *pdev) { int err; diff --git a/drivers/gpio/gpio-janz-ttl.c b/drivers/gpio/gpio-janz-ttl.c index cd28270..7d0a041 100644 --- a/drivers/gpio/gpio-janz-ttl.c +++ b/drivers/gpio/gpio-janz-ttl.c @@ -211,7 +211,7 @@ out_return: return ret; } -static int __devexit ttl_remove(struct platform_device *pdev) +static int ttl_remove(struct platform_device *pdev) { struct ttl_module *mod = platform_get_drvdata(pdev); struct device *dev = &pdev->dev; diff --git a/drivers/gpio/gpio-langwell.c b/drivers/gpio/gpio-langwell.c index a3bf90d..e77b2b3 100644 --- a/drivers/gpio/gpio-langwell.c +++ b/drivers/gpio/gpio-langwell.c @@ -484,7 +484,7 @@ err_kmalloc: return retval; } -static int __devexit wp_gpio_remove(struct platform_device *pdev) +static int wp_gpio_remove(struct platform_device *pdev) { struct lnw_gpio *lnw = platform_get_drvdata(pdev); int err; diff --git a/drivers/gpio/gpio-max7300.c b/drivers/gpio/gpio-max7300.c index 5c92414..4b6b9a0 100644 --- a/drivers/gpio/gpio-max7300.c +++ b/drivers/gpio/gpio-max7300.c @@ -55,7 +55,7 @@ static int max7300_probe(struct i2c_client *client, return ret; } -static int __devexit max7300_remove(struct i2c_client *client) +static int max7300_remove(struct i2c_client *client) { return __max730x_remove(&client->dev); } diff --git a/drivers/gpio/gpio-max7301.c b/drivers/gpio/gpio-max7301.c index cf5d5b3..c6c535c 100644 --- a/drivers/gpio/gpio-max7301.c +++ b/drivers/gpio/gpio-max7301.c @@ -75,7 +75,7 @@ static int max7301_probe(struct spi_device *spi) return ret; } -static int __devexit max7301_remove(struct spi_device *spi) +static int max7301_remove(struct spi_device *spi) { return __max730x_remove(&spi->dev); } diff --git a/drivers/gpio/gpio-max730x.c b/drivers/gpio/gpio-max730x.c index 91b4f45..22b7582 100644 --- a/drivers/gpio/gpio-max730x.c +++ b/drivers/gpio/gpio-max730x.c @@ -226,7 +226,7 @@ exit_destroy: } EXPORT_SYMBOL_GPL(__max730x_probe); -int __devexit __max730x_remove(struct device *dev) +int __max730x_remove(struct device *dev) { struct max7301 *ts = dev_get_drvdata(dev); int ret; diff --git a/drivers/gpio/gpio-max732x.c b/drivers/gpio/gpio-max732x.c index 5edd2cb3..1e0467c 100644 --- a/drivers/gpio/gpio-max732x.c +++ b/drivers/gpio/gpio-max732x.c @@ -651,7 +651,7 @@ out_failed: return ret; } -static int __devexit max732x_remove(struct i2c_client *client) +static int max732x_remove(struct i2c_client *client) { struct max732x_platform_data *pdata = client->dev.platform_data; struct max732x_chip *chip = i2c_get_clientdata(client); diff --git a/drivers/gpio/gpio-mc33880.c b/drivers/gpio/gpio-mc33880.c index 79fc430..6a8fdc2 100644 --- a/drivers/gpio/gpio-mc33880.c +++ b/drivers/gpio/gpio-mc33880.c @@ -147,7 +147,7 @@ exit_destroy: return ret; } -static int __devexit mc33880_remove(struct spi_device *spi) +static int mc33880_remove(struct spi_device *spi) { struct mc33880 *mc; int ret; diff --git a/drivers/gpio/gpio-mcp23s08.c b/drivers/gpio/gpio-mcp23s08.c index 45079ae..ce620f1 100644 --- a/drivers/gpio/gpio-mcp23s08.c +++ b/drivers/gpio/gpio-mcp23s08.c @@ -508,7 +508,7 @@ fail: return status; } -static int __devexit mcp230xx_remove(struct i2c_client *client) +static int mcp230xx_remove(struct i2c_client *client) { struct mcp23s08 *mcp = i2c_get_clientdata(client); int status; diff --git a/drivers/gpio/gpio-ml-ioh.c b/drivers/gpio/gpio-ml-ioh.c index 934b9bc..b733665 100644 --- a/drivers/gpio/gpio-ml-ioh.c +++ b/drivers/gpio/gpio-ml-ioh.c @@ -517,7 +517,7 @@ err_pci_enable: return ret; } -static void __devexit ioh_gpio_remove(struct pci_dev *pdev) +static void ioh_gpio_remove(struct pci_dev *pdev) { int err; int i; diff --git a/drivers/gpio/gpio-msm-v2.c b/drivers/gpio/gpio-msm-v2.c index 5451bec..55a7e77 100644 --- a/drivers/gpio/gpio-msm-v2.c +++ b/drivers/gpio/gpio-msm-v2.c @@ -376,7 +376,7 @@ static int msm_gpio_probe(struct platform_device *dev) return 0; } -static int __devexit msm_gpio_remove(struct platform_device *dev) +static int msm_gpio_remove(struct platform_device *dev) { int ret = gpiochip_remove(&msm_gpio.gpio_chip); diff --git a/drivers/gpio/gpio-pch.c b/drivers/gpio/gpio-pch.c index 09568a4..bb2b66b 100644 --- a/drivers/gpio/gpio-pch.c +++ b/drivers/gpio/gpio-pch.c @@ -442,7 +442,7 @@ err_pci_enable: return ret; } -static void __devexit pch_gpio_remove(struct pci_dev *pdev) +static void pch_gpio_remove(struct pci_dev *pdev) { int err; struct pch_gpio *chip = pci_get_drvdata(pdev); diff --git a/drivers/gpio/gpio-rc5t583.c b/drivers/gpio/gpio-rc5t583.c index 59ee5de..e63d6a3 100644 --- a/drivers/gpio/gpio-rc5t583.c +++ b/drivers/gpio/gpio-rc5t583.c @@ -146,7 +146,7 @@ static int rc5t583_gpio_probe(struct platform_device *pdev) return gpiochip_add(&rc5t583_gpio->gpio_chip); } -static int __devexit rc5t583_gpio_remove(struct platform_device *pdev) +static int rc5t583_gpio_remove(struct platform_device *pdev) { struct rc5t583_gpio *rc5t583_gpio = platform_get_drvdata(pdev); diff --git a/drivers/gpio/gpio-rdc321x.c b/drivers/gpio/gpio-rdc321x.c index dd3b49f..1bf55f6 100644 --- a/drivers/gpio/gpio-rdc321x.c +++ b/drivers/gpio/gpio-rdc321x.c @@ -206,7 +206,7 @@ out_free: return err; } -static int __devexit rdc321x_gpio_remove(struct platform_device *pdev) +static int rdc321x_gpio_remove(struct platform_device *pdev) { int ret; struct rdc321x_gpio *rdc321x_gpio_dev = platform_get_drvdata(pdev); diff --git a/drivers/gpio/gpio-sch.c b/drivers/gpio/gpio-sch.c index 4498855..edae963 100644 --- a/drivers/gpio/gpio-sch.c +++ b/drivers/gpio/gpio-sch.c @@ -271,7 +271,7 @@ err_sch_gpio_core: return err; } -static int __devexit sch_gpio_remove(struct platform_device *pdev) +static int sch_gpio_remove(struct platform_device *pdev) { struct resource *res; if (gpio_ba) { diff --git a/drivers/gpio/gpio-stmpe.c b/drivers/gpio/gpio-stmpe.c index 72cf618..6dff78b 100644 --- a/drivers/gpio/gpio-stmpe.c +++ b/drivers/gpio/gpio-stmpe.c @@ -378,7 +378,7 @@ out_free: return ret; } -static int __devexit stmpe_gpio_remove(struct platform_device *pdev) +static int stmpe_gpio_remove(struct platform_device *pdev) { struct stmpe_gpio *stmpe_gpio = platform_get_drvdata(pdev); struct stmpe *stmpe = stmpe_gpio->stmpe; diff --git a/drivers/gpio/gpio-sx150x.c b/drivers/gpio/gpio-sx150x.c index 9c93308..796b6c4 100644 --- a/drivers/gpio/gpio-sx150x.c +++ b/drivers/gpio/gpio-sx150x.c @@ -622,7 +622,7 @@ probe_fail_pre_gpiochip_add: return rc; } -static int __devexit sx150x_remove(struct i2c_client *client) +static int sx150x_remove(struct i2c_client *client) { struct sx150x_chip *chip; int rc; diff --git a/drivers/gpio/gpio-tc3589x.c b/drivers/gpio/gpio-tc3589x.c index d69d7c8..839f449 100644 --- a/drivers/gpio/gpio-tc3589x.c +++ b/drivers/gpio/gpio-tc3589x.c @@ -389,7 +389,7 @@ out_free: return ret; } -static int __devexit tc3589x_gpio_remove(struct platform_device *pdev) +static int tc3589x_gpio_remove(struct platform_device *pdev) { struct tc3589x_gpio *tc3589x_gpio = platform_get_drvdata(pdev); struct tc3589x *tc3589x = tc3589x_gpio->tc3589x; diff --git a/drivers/gpio/gpio-timberdale.c b/drivers/gpio/gpio-timberdale.c index 728d6e7..702cca9 100644 --- a/drivers/gpio/gpio-timberdale.c +++ b/drivers/gpio/gpio-timberdale.c @@ -316,7 +316,7 @@ err_mem: return err; } -static int __devexit timbgpio_remove(struct platform_device *pdev) +static int timbgpio_remove(struct platform_device *pdev) { int err; struct timbgpio_platform_data *pdata = pdev->dev.platform_data; diff --git a/drivers/gpio/gpio-tps6586x.c b/drivers/gpio/gpio-tps6586x.c index b0b2ee0..c1b82da 100644 --- a/drivers/gpio/gpio-tps6586x.c +++ b/drivers/gpio/gpio-tps6586x.c @@ -126,7 +126,7 @@ static int tps6586x_gpio_probe(struct platform_device *pdev) return ret; } -static int __devexit tps6586x_gpio_remove(struct platform_device *pdev) +static int tps6586x_gpio_remove(struct platform_device *pdev) { struct tps6586x_gpio *tps6586x_gpio = platform_get_drvdata(pdev); diff --git a/drivers/gpio/gpio-tps65910.c b/drivers/gpio/gpio-tps65910.c index 635352c..5083825 100644 --- a/drivers/gpio/gpio-tps65910.c +++ b/drivers/gpio/gpio-tps65910.c @@ -188,7 +188,7 @@ skip_init: return ret; } -static int __devexit tps65910_gpio_remove(struct platform_device *pdev) +static int tps65910_gpio_remove(struct platform_device *pdev) { struct tps65910_gpio *tps65910_gpio = platform_get_drvdata(pdev); diff --git a/drivers/gpio/gpio-tps65912.c b/drivers/gpio/gpio-tps65912.c index c0623b8..30a5844 100644 --- a/drivers/gpio/gpio-tps65912.c +++ b/drivers/gpio/gpio-tps65912.c @@ -113,7 +113,7 @@ static int tps65912_gpio_probe(struct platform_device *pdev) return ret; } -static int __devexit tps65912_gpio_remove(struct platform_device *pdev) +static int tps65912_gpio_remove(struct platform_device *pdev) { struct tps65912_gpio_data *tps65912_gpio = platform_get_drvdata(pdev); diff --git a/drivers/gpio/gpio-twl4030.c b/drivers/gpio/gpio-twl4030.c index 648e560..8beae66 100644 --- a/drivers/gpio/gpio-twl4030.c +++ b/drivers/gpio/gpio-twl4030.c @@ -505,7 +505,7 @@ out: return ret; } -/* Cannot use __devexit as gpio_twl4030_probe() calls us */ +/* Cannot use as gpio_twl4030_probe() calls us */ static int gpio_twl4030_remove(struct platform_device *pdev) { struct twl4030_gpio_platform_data *pdata = pdev->dev.platform_data; diff --git a/drivers/gpio/gpio-twl6040.c b/drivers/gpio/gpio-twl6040.c index 2962b84..0be82c6 100644 --- a/drivers/gpio/gpio-twl6040.c +++ b/drivers/gpio/gpio-twl6040.c @@ -113,7 +113,7 @@ static int gpo_twl6040_probe(struct platform_device *pdev) return ret; } -static int __devexit gpo_twl6040_remove(struct platform_device *pdev) +static int gpo_twl6040_remove(struct platform_device *pdev) { return gpiochip_remove(&twl6040gpo_chip); } diff --git a/drivers/gpio/gpio-vr41xx.c b/drivers/gpio/gpio-vr41xx.c index c13920b..9902732 100644 --- a/drivers/gpio/gpio-vr41xx.c +++ b/drivers/gpio/gpio-vr41xx.c @@ -552,7 +552,7 @@ static int giu_probe(struct platform_device *pdev) return cascade_irq(irq, giu_get_irq); } -static int __devexit giu_remove(struct platform_device *pdev) +static int giu_remove(struct platform_device *pdev) { if (giu_base) { iounmap(giu_base); diff --git a/drivers/gpio/gpio-vx855.c b/drivers/gpio/gpio-vx855.c index 90dd23b..2b7252c 100644 --- a/drivers/gpio/gpio-vx855.c +++ b/drivers/gpio/gpio-vx855.c @@ -284,7 +284,7 @@ out_release: return ret; } -static int __devexit vx855gpio_remove(struct platform_device *pdev) +static int vx855gpio_remove(struct platform_device *pdev) { struct vx855_gpio *vg = platform_get_drvdata(pdev); struct resource *res; diff --git a/drivers/gpio/gpio-wm831x.c b/drivers/gpio/gpio-wm831x.c index 8182145..2a743e1 100644 --- a/drivers/gpio/gpio-wm831x.c +++ b/drivers/gpio/gpio-wm831x.c @@ -275,7 +275,7 @@ static int wm831x_gpio_probe(struct platform_device *pdev) return ret; } -static int __devexit wm831x_gpio_remove(struct platform_device *pdev) +static int wm831x_gpio_remove(struct platform_device *pdev) { struct wm831x_gpio *wm831x_gpio = platform_get_drvdata(pdev); diff --git a/drivers/gpio/gpio-wm8350.c b/drivers/gpio/gpio-wm8350.c index 2b99fc3..0b598cf 100644 --- a/drivers/gpio/gpio-wm8350.c +++ b/drivers/gpio/gpio-wm8350.c @@ -141,7 +141,7 @@ static int wm8350_gpio_probe(struct platform_device *pdev) return ret; } -static int __devexit wm8350_gpio_remove(struct platform_device *pdev) +static int wm8350_gpio_remove(struct platform_device *pdev) { struct wm8350_gpio_data *wm8350_gpio = platform_get_drvdata(pdev); diff --git a/drivers/gpio/gpio-wm8994.c b/drivers/gpio/gpio-wm8994.c index fc39178..ae409fd 100644 --- a/drivers/gpio/gpio-wm8994.c +++ b/drivers/gpio/gpio-wm8994.c @@ -281,7 +281,7 @@ err: return ret; } -static int __devexit wm8994_gpio_remove(struct platform_device *pdev) +static int wm8994_gpio_remove(struct platform_device *pdev) { struct wm8994_gpio *wm8994_gpio = platform_get_drvdata(pdev); -- cgit v1.1 From 835c192f3612639702d716024c1a5b66445dd860 Mon Sep 17 00:00:00 2001 From: Baruch Siach Date: Thu, 22 Nov 2012 11:46:14 +0200 Subject: gpio/pl061: remove old comment Since 3ab524754 (gpio: pl061: convert to use generic irq chip) we only have one spinlock in struct pl061_gpio. Cc: Rob Herring Signed-off-by: Baruch Siach Acked-by: Linus Walleij Signed-off-by: Grant Likely --- drivers/gpio/gpio-pl061.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) (limited to 'drivers/gpio') diff --git a/drivers/gpio/gpio-pl061.c b/drivers/gpio/gpio-pl061.c index 31d9c9e..c1720de 100644 --- a/drivers/gpio/gpio-pl061.c +++ b/drivers/gpio/gpio-pl061.c @@ -48,12 +48,7 @@ struct pl061_context_save_regs { #endif struct pl061_gpio { - /* Each of the two spinlocks protects a different set of hardware - * regiters and data structurs. This decouples the code of the IRQ from - * the GPIO code. This also makes the case of a GPIO routine call from - * the IRQ code simpler. - */ - spinlock_t lock; /* GPIO registers */ + spinlock_t lock; void __iomem *base; int irq_base; -- cgit v1.1 From e29482e8487954c87dc7b4fdbc53574bf1d4cce2 Mon Sep 17 00:00:00 2001 From: Mathias Nyman Date: Fri, 30 Nov 2012 12:37:36 +0100 Subject: gpio / ACPI: add ACPI support Add support for translating ACPI GPIO pin numbers to Linux GPIO API pins. Needs a gpio controller driver with the acpi handler hook set. Drivers can use acpi_get_gpio() to translate ACPI5 GpioIO and GpioInt resources to Linux GPIO's. Signed-off-by: Mathias Nyman Signed-off-by: Mika Westerberg Acked-by: Grant Likely Signed-off-by: Rafael J. Wysocki --- drivers/gpio/Kconfig | 4 ++++ drivers/gpio/Makefile | 1 + drivers/gpio/gpiolib-acpi.c | 54 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 59 insertions(+) create mode 100644 drivers/gpio/gpiolib-acpi.c (limited to 'drivers/gpio') diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index f11d8e3..5c9b384 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -49,6 +49,10 @@ config OF_GPIO def_bool y depends on OF +config GPIO_ACPI + def_bool y + depends on ACPI + config DEBUG_GPIO bool "Debug GPIO calls" depends on DEBUG_KERNEL diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile index 9aeed67..420dbac 100644 --- a/drivers/gpio/Makefile +++ b/drivers/gpio/Makefile @@ -4,6 +4,7 @@ ccflags-$(CONFIG_DEBUG_GPIO) += -DDEBUG obj-$(CONFIG_GPIOLIB) += gpiolib.o devres.o obj-$(CONFIG_OF_GPIO) += gpiolib-of.o +obj-$(CONFIG_GPIO_ACPI) += gpiolib-acpi.o # Device drivers. Generally keep list sorted alphabetically obj-$(CONFIG_GPIO_GENERIC) += gpio-generic.o diff --git a/drivers/gpio/gpiolib-acpi.c b/drivers/gpio/gpiolib-acpi.c new file mode 100644 index 0000000..cbad6e9 --- /dev/null +++ b/drivers/gpio/gpiolib-acpi.c @@ -0,0 +1,54 @@ +/* + * ACPI helpers for GPIO API + * + * Copyright (C) 2012, Intel Corporation + * Authors: Mathias Nyman + * Mika Westerberg + * + * 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. + */ + +#include +#include +#include +#include +#include + +static int acpi_gpiochip_find(struct gpio_chip *gc, void *data) +{ + if (!gc->dev) + return false; + + return ACPI_HANDLE(gc->dev) == data; +} + +/** + * acpi_get_gpio() - Translate ACPI GPIO pin to GPIO number usable with GPIO API + * @path: ACPI GPIO controller full path name, (e.g. "\\_SB.GPO1") + * @pin: ACPI GPIO pin number (0-based, controller-relative) + * + * Returns GPIO number to use with Linux generic GPIO API, or errno error value + */ + +int acpi_get_gpio(char *path, int pin) +{ + struct gpio_chip *chip; + acpi_handle handle; + acpi_status status; + + status = acpi_get_handle(NULL, path, &handle); + if (ACPI_FAILURE(status)) + return -ENODEV; + + chip = gpiochip_find(handle, acpi_gpiochip_find); + if (!chip) + return -ENODEV; + + if (!gpio_is_valid(chip->base + pin)) + return -EINVAL; + + return chip->base + pin; +} +EXPORT_SYMBOL_GPL(acpi_get_gpio); -- cgit v1.1 From 8618b3b47c4590baf4ef3f241616914f4bb2a8a6 Mon Sep 17 00:00:00 2001 From: Alessandro Rubini Date: Fri, 23 Nov 2012 16:08:24 +0100 Subject: gpio: pl061 depends on ARM Commit dece904d (gpio: pl061: use chained_irq_* functions in irq handler) introduced chained_irq_enter/exit, which is only available for arch/arm and the driver won't compile elsewhere. The dependency is thus made explicit, because AMBA is used in the x86 world by a PCI-to-AMBA bridge, to be submitted. Signed-off-by: Alessandro Rubini Acked-by: Giancarlo Asnaghi Reviewed-by: Viresh Kumar Signed-off-by: Linus Walleij --- drivers/gpio/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpio') diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index 4f592c6..46e96f3 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -185,7 +185,7 @@ config GPIO_MXS config GPIO_PL061 bool "PrimeCell PL061 GPIO support" - depends on ARM_AMBA + depends on ARM && ARM_AMBA select GENERIC_IRQ_CHIP help Say yes here to support the PrimeCell PL061 GPIO device -- cgit v1.1 From 86605cfe8c7c166999bc7476b17940c68bf2f8b7 Mon Sep 17 00:00:00 2001 From: Vipul Kumar Samar Date: Mon, 26 Nov 2012 17:06:51 +0530 Subject: gpio: stmpe: Add DT support for stmpe gpio This patch allows the STMPE GPIO driver to be successfully probed and initialised when Device Tree support is enabled. Bindings are mentioned in Documentation too. Acked-by: Lee Jones Signed-off-by: Vipul Kumar Samar Signed-off-by: Viresh Kumar Signed-off-by: Linus Walleij --- drivers/gpio/gpio-stmpe.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'drivers/gpio') diff --git a/drivers/gpio/gpio-stmpe.c b/drivers/gpio/gpio-stmpe.c index dce3472..522c90e 100644 --- a/drivers/gpio/gpio-stmpe.c +++ b/drivers/gpio/gpio-stmpe.c @@ -12,6 +12,7 @@ #include #include #include +#include #include /* @@ -304,6 +305,7 @@ static void stmpe_gpio_irq_remove(struct stmpe_gpio *stmpe_gpio) static int __devinit stmpe_gpio_probe(struct platform_device *pdev) { struct stmpe *stmpe = dev_get_drvdata(pdev->dev.parent); + struct device_node *np = pdev->dev.of_node; struct stmpe_gpio_platform_data *pdata; struct stmpe_gpio *stmpe_gpio; int ret; @@ -321,13 +323,17 @@ static int __devinit stmpe_gpio_probe(struct platform_device *pdev) stmpe_gpio->dev = &pdev->dev; stmpe_gpio->stmpe = stmpe; - stmpe_gpio->norequest_mask = pdata ? pdata->norequest_mask : 0; - stmpe_gpio->chip = template_chip; stmpe_gpio->chip.ngpio = stmpe->num_gpios; stmpe_gpio->chip.dev = &pdev->dev; stmpe_gpio->chip.base = pdata ? pdata->gpio_base : -1; + if (pdata) + stmpe_gpio->norequest_mask = pdata->norequest_mask; + else if (np) + of_property_read_u32(np, "st,norequest-mask", + &stmpe_gpio->norequest_mask); + if (irq >= 0) stmpe_gpio->irq_base = stmpe->irq_base + STMPE_INT_GPIO(0); else -- cgit v1.1 From 805f864ebefc39065b6b0cf2548f13c2fbf888d9 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Thu, 6 Dec 2012 01:10:28 -0800 Subject: gpio: pcf857x: use client->irq for gpio_to_irq() 6e20a0a429bd4dc07d6de16d9c247270e04e4aa0 (gpio: pcf857x: enable gpio_to_irq() support) added gpio_to_irq() support on pcf857x driver, but it used pdata->irq. This patch modifies driver to use client->irq instead of it. It modifies kzm9g board platform settings, and device probe information too. This patch is tested on kzm9g board Reported-by: Christian Engelmayer Acked-by: Simon Horman Signed-off-by: Kuninori Morimoto Signed-off-by: Linus Walleij --- drivers/gpio/gpio-pcf857x.c | 29 +++++++++++------------------ 1 file changed, 11 insertions(+), 18 deletions(-) (limited to 'drivers/gpio') diff --git a/drivers/gpio/gpio-pcf857x.c b/drivers/gpio/gpio-pcf857x.c index 16af35c..a19b745 100644 --- a/drivers/gpio/gpio-pcf857x.c +++ b/drivers/gpio/gpio-pcf857x.c @@ -223,11 +223,11 @@ static void pcf857x_irq_domain_cleanup(struct pcf857x *gpio) static int pcf857x_irq_domain_init(struct pcf857x *gpio, struct pcf857x_platform_data *pdata, - struct device *dev) + struct i2c_client *client) { int status; - gpio->irq_domain = irq_domain_add_linear(dev->of_node, + gpio->irq_domain = irq_domain_add_linear(client->dev.of_node, gpio->chip.ngpio, &pcf857x_irq_domain_ops, NULL); @@ -235,15 +235,15 @@ static int pcf857x_irq_domain_init(struct pcf857x *gpio, goto fail; /* enable real irq */ - status = request_irq(pdata->irq, pcf857x_irq_demux, 0, - dev_name(dev), gpio); + status = request_irq(client->irq, pcf857x_irq_demux, 0, + dev_name(&client->dev), gpio); if (status) goto fail; /* enable gpio_to_irq() */ INIT_WORK(&gpio->work, pcf857x_irq_demux_work); gpio->chip.to_irq = pcf857x_to_irq; - gpio->irq = pdata->irq; + gpio->irq = client->irq; return 0; @@ -285,8 +285,8 @@ static int pcf857x_probe(struct i2c_client *client, gpio->chip.ngpio = id->driver_data; /* enable gpio_to_irq() if platform has settings */ - if (pdata && pdata->irq) { - status = pcf857x_irq_domain_init(gpio, pdata, &client->dev); + if (pdata && client->irq) { + status = pcf857x_irq_domain_init(gpio, pdata, client); if (status < 0) { dev_err(&client->dev, "irq_domain init failed\n"); goto fail; @@ -368,15 +368,6 @@ static int pcf857x_probe(struct i2c_client *client, if (status < 0) goto fail; - /* NOTE: these chips can issue "some pin-changed" IRQs, which we - * don't yet even try to use. Among other issues, the relevant - * genirq state isn't available to modular drivers; and most irq - * methods can't be called from sleeping contexts. - */ - - dev_info(&client->dev, "%s\n", - client->irq ? " (irq ignored)" : ""); - /* Let platform code set up the GPIOs and their users. * Now is the first time anyone could use them. */ @@ -388,13 +379,15 @@ static int pcf857x_probe(struct i2c_client *client, dev_warn(&client->dev, "setup --> %d\n", status); } + dev_info(&client->dev, "probed\n"); + return 0; fail: dev_dbg(&client->dev, "probe error %d for '%s'\n", status, client->name); - if (pdata && pdata->irq) + if (pdata && client->irq) pcf857x_irq_domain_cleanup(gpio); kfree(gpio); @@ -418,7 +411,7 @@ static int pcf857x_remove(struct i2c_client *client) } } - if (pdata && pdata->irq) + if (pdata && client->irq) pcf857x_irq_domain_cleanup(gpio); status = gpiochip_remove(&gpio->chip); -- cgit v1.1 From 759f5f3752e03f15727688b5288e360ef90c1306 Mon Sep 17 00:00:00 2001 From: Vivien Didelot Date: Fri, 7 Dec 2012 21:36:34 -0500 Subject: gpio: add TS-5500 DIO blocks support Technologic Systems TS-5500 provides digital I/O lines exposed through pin blocks. On this platform, there are three of them, named DIO1, DIO2 and LCD port, that may be used as a DIO block. The TS-5500 pin blocks are described in the product's wiki: http://wiki.embeddedarm.com/wiki/TS-5500#Digital_I.2FO This driver is not limited to the TS-5500 blocks. It can be extended to support similar boards pin blocks, such as on the TS-5600. This patch is the V2 of the previous https://lkml.org/lkml/2012/9/25/671 with corrections suggested by Linus Walleij. Signed-off-by: Vivien Didelot Signed-off-by: Jerome Oufella Signed-off-by: Linus Walleij --- drivers/gpio/Kconfig | 8 + drivers/gpio/Makefile | 1 + drivers/gpio/gpio-ts5500.c | 466 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 475 insertions(+) create mode 100644 drivers/gpio/gpio-ts5500.c (limited to 'drivers/gpio') diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index 46e96f3..39d9323 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -211,6 +211,14 @@ config GPIO_STA2X11 Say yes here to support the STA2x11/ConneXt GPIO device. The GPIO module has 128 GPIO pins with alternate functions. +config GPIO_TS5500 + tristate "TS-5500 DIO blocks and compatibles" + help + This driver supports Digital I/O exposed by pin blocks found on some + Technologic Systems platforms. It includes, but is not limited to, 3 + blocks of the TS-5500: DIO1, DIO2 and the LCD port, and the TS-5600 + LCD port. + config GPIO_VT8500 bool "VIA/Wondermedia SoC GPIO Support" depends on ARCH_VT8500 diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile index a268d99..a41c250 100644 --- a/drivers/gpio/Makefile +++ b/drivers/gpio/Makefile @@ -71,6 +71,7 @@ obj-$(CONFIG_ARCH_DAVINCI_TNETV107X) += gpio-tnetv107x.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_TS5500) += gpio-ts5500.o obj-$(CONFIG_GPIO_TWL4030) += gpio-twl4030.o obj-$(CONFIG_GPIO_TWL6040) += gpio-twl6040.o obj-$(CONFIG_GPIO_UCB1400) += gpio-ucb1400.o diff --git a/drivers/gpio/gpio-ts5500.c b/drivers/gpio/gpio-ts5500.c new file mode 100644 index 0000000..0634cee --- /dev/null +++ b/drivers/gpio/gpio-ts5500.c @@ -0,0 +1,466 @@ +/* + * Digital I/O driver for Technologic Systems TS-5500 + * + * Copyright (c) 2012 Savoir-faire Linux Inc. + * Vivien Didelot + * + * Technologic Systems platforms have pin blocks, exposing several Digital + * Input/Output lines (DIO). This driver aims to support single pin blocks. + * In that sense, the support is not limited to the TS-5500 blocks. + * Actually, the following platforms have DIO support: + * + * TS-5500: + * Documentation: http://wiki.embeddedarm.com/wiki/TS-5500 + * Blocks: DIO1, DIO2 and LCD port. + * + * TS-5600: + * Documentation: http://wiki.embeddedarm.com/wiki/TS-5600 + * Blocks: LCD port (identical to TS-5500 LCD). + * + * 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. + */ + +#include +#include +#include +#include +#include +#include +#include + +/* List of supported Technologic Systems platforms DIO blocks */ +enum ts5500_blocks { TS5500_DIO1, TS5500_DIO2, TS5500_LCD, TS5600_LCD }; + +struct ts5500_priv { + const struct ts5500_dio *pinout; + struct gpio_chip gpio_chip; + spinlock_t lock; + bool strap; + u8 hwirq; +}; + +/* + * Hex 7D is used to control several blocks (e.g. DIO2 and LCD port). + * This flag ensures that the region has been requested by this driver. + */ +static bool hex7d_reserved; + +/* + * This structure is used to describe capabilities of DIO lines, + * such as available directions and connected interrupt (if any). + */ +struct ts5500_dio { + const u8 value_addr; + const u8 value_mask; + const u8 control_addr; + const u8 control_mask; + const bool no_input; + const bool no_output; + const u8 irq; +}; + +#define TS5500_DIO_IN_OUT(vaddr, vbit, caddr, cbit) \ + { \ + .value_addr = vaddr, \ + .value_mask = BIT(vbit), \ + .control_addr = caddr, \ + .control_mask = BIT(cbit), \ + } + +#define TS5500_DIO_IN(addr, bit) \ + { \ + .value_addr = addr, \ + .value_mask = BIT(bit), \ + .no_output = true, \ + } + +#define TS5500_DIO_IN_IRQ(addr, bit, _irq) \ + { \ + .value_addr = addr, \ + .value_mask = BIT(bit), \ + .no_output = true, \ + .irq = _irq, \ + } + +#define TS5500_DIO_OUT(addr, bit) \ + { \ + .value_addr = addr, \ + .value_mask = BIT(bit), \ + .no_input = true, \ + } + +/* + * Input/Output DIO lines are programmed in groups of 4. Their values are + * available through 4 consecutive bits in a value port, whereas the direction + * of these 4 lines is driven by only 1 bit in a control port. + */ +#define TS5500_DIO_GROUP(vaddr, vbitfrom, caddr, cbit) \ + TS5500_DIO_IN_OUT(vaddr, vbitfrom + 0, caddr, cbit), \ + TS5500_DIO_IN_OUT(vaddr, vbitfrom + 1, caddr, cbit), \ + TS5500_DIO_IN_OUT(vaddr, vbitfrom + 2, caddr, cbit), \ + TS5500_DIO_IN_OUT(vaddr, vbitfrom + 3, caddr, cbit) + +/* + * TS-5500 DIO1 block + * + * value control dir hw + * addr bit addr bit in out irq name pin offset + * + * 0x7b 0 0x7a 0 x x DIO1_0 1 0 + * 0x7b 1 0x7a 0 x x DIO1_1 3 1 + * 0x7b 2 0x7a 0 x x DIO1_2 5 2 + * 0x7b 3 0x7a 0 x x DIO1_3 7 3 + * 0x7b 4 0x7a 1 x x DIO1_4 9 4 + * 0x7b 5 0x7a 1 x x DIO1_5 11 5 + * 0x7b 6 0x7a 1 x x DIO1_6 13 6 + * 0x7b 7 0x7a 1 x x DIO1_7 15 7 + * 0x7c 0 0x7a 5 x x DIO1_8 4 8 + * 0x7c 1 0x7a 5 x x DIO1_9 6 9 + * 0x7c 2 0x7a 5 x x DIO1_10 8 10 + * 0x7c 3 0x7a 5 x x DIO1_11 10 11 + * 0x7c 4 x DIO1_12 12 12 + * 0x7c 5 x 7 DIO1_13 14 13 + */ +static const struct ts5500_dio ts5500_dio1[] = { + TS5500_DIO_GROUP(0x7b, 0, 0x7a, 0), + TS5500_DIO_GROUP(0x7b, 4, 0x7a, 1), + TS5500_DIO_GROUP(0x7c, 0, 0x7a, 5), + TS5500_DIO_IN(0x7c, 4), + TS5500_DIO_IN_IRQ(0x7c, 5, 7), +}; + +/* + * TS-5500 DIO2 block + * + * value control dir hw + * addr bit addr bit in out irq name pin offset + * + * 0x7e 0 0x7d 0 x x DIO2_0 1 0 + * 0x7e 1 0x7d 0 x x DIO2_1 3 1 + * 0x7e 2 0x7d 0 x x DIO2_2 5 2 + * 0x7e 3 0x7d 0 x x DIO2_3 7 3 + * 0x7e 4 0x7d 1 x x DIO2_4 9 4 + * 0x7e 5 0x7d 1 x x DIO2_5 11 5 + * 0x7e 6 0x7d 1 x x DIO2_6 13 6 + * 0x7e 7 0x7d 1 x x DIO2_7 15 7 + * 0x7f 0 0x7d 5 x x DIO2_8 4 8 + * 0x7f 1 0x7d 5 x x DIO2_9 6 9 + * 0x7f 2 0x7d 5 x x DIO2_10 8 10 + * 0x7f 3 0x7d 5 x x DIO2_11 10 11 + * 0x7f 4 x 6 DIO2_13 14 12 + */ +static const struct ts5500_dio ts5500_dio2[] = { + TS5500_DIO_GROUP(0x7e, 0, 0x7d, 0), + TS5500_DIO_GROUP(0x7e, 4, 0x7d, 1), + TS5500_DIO_GROUP(0x7f, 0, 0x7d, 5), + TS5500_DIO_IN_IRQ(0x7f, 4, 6), +}; + +/* + * TS-5500 LCD port used as DIO block + * TS-5600 LCD port is identical + * + * value control dir hw + * addr bit addr bit in out irq name pin offset + * + * 0x72 0 0x7d 2 x x LCD_0 8 0 + * 0x72 1 0x7d 2 x x LCD_1 7 1 + * 0x72 2 0x7d 2 x x LCD_2 10 2 + * 0x72 3 0x7d 2 x x LCD_3 9 3 + * 0x72 4 0x7d 3 x x LCD_4 12 4 + * 0x72 5 0x7d 3 x x LCD_5 11 5 + * 0x72 6 0x7d 3 x x LCD_6 14 6 + * 0x72 7 0x7d 3 x x LCD_7 13 7 + * 0x73 0 x LCD_EN 5 8 + * 0x73 6 x LCD_WR 6 9 + * 0x73 7 x 1 LCD_RS 3 10 + */ +static const struct ts5500_dio ts5500_lcd[] = { + TS5500_DIO_GROUP(0x72, 0, 0x7d, 2), + TS5500_DIO_GROUP(0x72, 4, 0x7d, 3), + TS5500_DIO_OUT(0x73, 0), + TS5500_DIO_IN(0x73, 6), + TS5500_DIO_IN_IRQ(0x73, 7, 1), +}; + +static inline struct ts5500_priv *ts5500_gc_to_priv(struct gpio_chip *chip) +{ + return container_of(chip, struct ts5500_priv, gpio_chip); +} + +static inline void ts5500_set_mask(u8 mask, u8 addr) +{ + u8 val = inb(addr); + val |= mask; + outb(val, addr); +} + +static inline void ts5500_clear_mask(u8 mask, u8 addr) +{ + u8 val = inb(addr); + val &= ~mask; + outb(val, addr); +} + +static int ts5500_gpio_input(struct gpio_chip *chip, unsigned offset) +{ + struct ts5500_priv *priv = ts5500_gc_to_priv(chip); + const struct ts5500_dio line = priv->pinout[offset]; + unsigned long flags; + + if (line.no_input) + return -ENXIO; + + if (line.no_output) + return 0; + + spin_lock_irqsave(&priv->lock, flags); + ts5500_clear_mask(line.control_mask, line.control_addr); + spin_unlock_irqrestore(&priv->lock, flags); + + return 0; +} + +static int ts5500_gpio_get(struct gpio_chip *chip, unsigned offset) +{ + struct ts5500_priv *priv = ts5500_gc_to_priv(chip); + const struct ts5500_dio line = priv->pinout[offset]; + + return !!(inb(line.value_addr) & line.value_mask); +} + +static int ts5500_gpio_output(struct gpio_chip *chip, unsigned offset, int val) +{ + struct ts5500_priv *priv = ts5500_gc_to_priv(chip); + const struct ts5500_dio line = priv->pinout[offset]; + unsigned long flags; + + if (line.no_output) + return -ENXIO; + + spin_lock_irqsave(&priv->lock, flags); + if (!line.no_input) + ts5500_set_mask(line.control_mask, line.control_addr); + + if (val) + ts5500_set_mask(line.value_mask, line.value_addr); + else + ts5500_clear_mask(line.value_mask, line.value_addr); + spin_unlock_irqrestore(&priv->lock, flags); + + return 0; +} + +static void ts5500_gpio_set(struct gpio_chip *chip, unsigned offset, int val) +{ + struct ts5500_priv *priv = ts5500_gc_to_priv(chip); + const struct ts5500_dio line = priv->pinout[offset]; + unsigned long flags; + + spin_lock_irqsave(&priv->lock, flags); + if (val) + ts5500_set_mask(line.value_mask, line.value_addr); + else + ts5500_clear_mask(line.value_mask, line.value_addr); + spin_unlock_irqrestore(&priv->lock, flags); +} + +static int ts5500_gpio_to_irq(struct gpio_chip *chip, unsigned offset) +{ + struct ts5500_priv *priv = ts5500_gc_to_priv(chip); + const struct ts5500_dio *block = priv->pinout; + const struct ts5500_dio line = block[offset]; + + /* Only one pin is connected to an interrupt */ + if (line.irq) + return line.irq; + + /* As this pin is input-only, we may strap it to another in/out pin */ + if (priv->strap) + return priv->hwirq; + + return -ENXIO; +} + +static int ts5500_enable_irq(struct ts5500_priv *priv) +{ + int ret = 0; + unsigned long flags; + + spin_lock_irqsave(&priv->lock, flags); + if (priv->hwirq == 7) + ts5500_set_mask(BIT(7), 0x7a); /* DIO1_13 on IRQ7 */ + else if (priv->hwirq == 6) + ts5500_set_mask(BIT(7), 0x7d); /* DIO2_13 on IRQ6 */ + else if (priv->hwirq == 1) + ts5500_set_mask(BIT(6), 0x7d); /* LCD_RS on IRQ1 */ + else + ret = -EINVAL; + spin_unlock_irqrestore(&priv->lock, flags); + + return ret; +} + +static void ts5500_disable_irq(struct ts5500_priv *priv) +{ + unsigned long flags; + + spin_lock_irqsave(&priv->lock, flags); + if (priv->hwirq == 7) + ts5500_clear_mask(BIT(7), 0x7a); /* DIO1_13 on IRQ7 */ + else if (priv->hwirq == 6) + ts5500_clear_mask(BIT(7), 0x7d); /* DIO2_13 on IRQ6 */ + 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); + spin_unlock_irqrestore(&priv->lock, flags); +} + +static int __devinit ts5500_dio_probe(struct platform_device *pdev) +{ + enum ts5500_blocks block = platform_get_device_id(pdev)->driver_data; + struct ts5500_dio_platform_data *pdata = pdev->dev.platform_data; + struct device *dev = &pdev->dev; + const char *name = dev_name(dev); + struct ts5500_priv *priv; + struct resource *res; + unsigned long flags; + int ret; + + res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); + if (!res) { + dev_err(dev, "missing IRQ resource\n"); + return -EINVAL; + } + + priv = devm_kzalloc(dev, sizeof(struct ts5500_priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + platform_set_drvdata(pdev, priv); + priv->hwirq = res->start; + spin_lock_init(&priv->lock); + + priv->gpio_chip.owner = THIS_MODULE; + priv->gpio_chip.label = name; + priv->gpio_chip.dev = dev; + priv->gpio_chip.direction_input = ts5500_gpio_input; + priv->gpio_chip.direction_output = ts5500_gpio_output; + priv->gpio_chip.get = ts5500_gpio_get; + priv->gpio_chip.set = ts5500_gpio_set; + priv->gpio_chip.to_irq = ts5500_gpio_to_irq; + priv->gpio_chip.base = -1; + if (pdata) { + priv->gpio_chip.base = pdata->base; + priv->strap = pdata->strap; + } + + switch (block) { + case TS5500_DIO1: + priv->pinout = ts5500_dio1; + priv->gpio_chip.ngpio = ARRAY_SIZE(ts5500_dio1); + + if (!devm_request_region(dev, 0x7a, 3, name)) { + dev_err(dev, "failed to request %s ports\n", name); + return -EBUSY; + } + break; + case TS5500_DIO2: + priv->pinout = ts5500_dio2; + priv->gpio_chip.ngpio = ARRAY_SIZE(ts5500_dio2); + + if (!devm_request_region(dev, 0x7e, 2, name)) { + dev_err(dev, "failed to request %s ports\n", name); + return -EBUSY; + } + + if (hex7d_reserved) + break; + + if (!devm_request_region(dev, 0x7d, 1, name)) { + dev_err(dev, "failed to request %s 7D\n", name); + return -EBUSY; + } + + hex7d_reserved = true; + break; + case TS5500_LCD: + case TS5600_LCD: + priv->pinout = ts5500_lcd; + priv->gpio_chip.ngpio = ARRAY_SIZE(ts5500_lcd); + + if (!devm_request_region(dev, 0x72, 2, name)) { + dev_err(dev, "failed to request %s ports\n", name); + return -EBUSY; + } + + if (!hex7d_reserved) { + if (!devm_request_region(dev, 0x7d, 1, name)) { + dev_err(dev, "failed to request %s 7D\n", name); + return -EBUSY; + } + + hex7d_reserved = true; + } + + /* Ensure usage of LCD port as DIO */ + spin_lock_irqsave(&priv->lock, flags); + ts5500_clear_mask(BIT(4), 0x7d); + spin_unlock_irqrestore(&priv->lock, flags); + break; + } + + ret = gpiochip_add(&priv->gpio_chip); + if (ret) { + dev_err(dev, "failed to register the gpio chip\n"); + return ret; + } + + ret = ts5500_enable_irq(priv); + if (ret) { + dev_err(dev, "invalid interrupt %d\n", priv->hwirq); + goto cleanup; + } + + return 0; +cleanup: + if (gpiochip_remove(&priv->gpio_chip)) + dev_err(dev, "failed to remove gpio chip\n"); + return ret; +} + +static int __devexit ts5500_dio_remove(struct platform_device *pdev) +{ + struct ts5500_priv *priv = platform_get_drvdata(pdev); + + ts5500_disable_irq(priv); + return gpiochip_remove(&priv->gpio_chip); +} + +static struct platform_device_id ts5500_dio_ids[] = { + { "ts5500-dio1", TS5500_DIO1 }, + { "ts5500-dio2", TS5500_DIO2 }, + { "ts5500-dio-lcd", TS5500_LCD }, + { "ts5600-dio-lcd", TS5600_LCD }, + { } +}; +MODULE_DEVICE_TABLE(platform, ts5500_dio_ids); + +static struct platform_driver ts5500_dio_driver = { + .driver = { + .name = "ts5500-dio", + .owner = THIS_MODULE, + }, + .probe = ts5500_dio_probe, + .remove = __devexit_p(ts5500_dio_remove), + .id_table = ts5500_dio_ids, +}; + +module_platform_driver(ts5500_dio_driver); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Savoir-faire Linux Inc. "); +MODULE_DESCRIPTION("Technologic Systems TS-5500 Digital I/O driver"); -- cgit v1.1 From fc13d5a5b17c657b7682c145d367dcb859c507d9 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Mon, 10 Dec 2012 10:07:54 +0000 Subject: gpio: Provide the STMPE GPIO driver with its own IRQ Domain The STMPE GPIO driver can be used as an IRQ controller by some related devices. Here we provide it with its very own IRQ Domain so that IRQs can be issued dynamically. This will stand the driver in good stead when it is enabled for Device Tree, as this it a prerequisite. Cc: Grant Likely Reviewed-by: Viresh Kumar Signed-off-by: Lee Jones Signed-off-by: Linus Walleij --- drivers/gpio/gpio-stmpe.c | 78 ++++++++++++++++++++++++++++------------------- 1 file changed, 47 insertions(+), 31 deletions(-) (limited to 'drivers/gpio') diff --git a/drivers/gpio/gpio-stmpe.c b/drivers/gpio/gpio-stmpe.c index 522c90e..3e1d398 100644 --- a/drivers/gpio/gpio-stmpe.c +++ b/drivers/gpio/gpio-stmpe.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -29,6 +30,7 @@ struct stmpe_gpio { struct stmpe *stmpe; struct device *dev; struct mutex irq_lock; + struct irq_domain *domain; int irq_base; unsigned norequest_mask; @@ -104,7 +106,7 @@ static int stmpe_gpio_to_irq(struct gpio_chip *chip, unsigned offset) { struct stmpe_gpio *stmpe_gpio = to_stmpe_gpio(chip); - return stmpe_gpio->irq_base + offset; + return irq_create_mapping(stmpe_gpio->domain, offset); } static int stmpe_gpio_request(struct gpio_chip *chip, unsigned offset) @@ -133,7 +135,7 @@ static struct gpio_chip template_chip = { static int stmpe_gpio_irq_set_type(struct irq_data *d, unsigned int type) { struct stmpe_gpio *stmpe_gpio = irq_data_get_irq_chip_data(d); - int offset = d->irq - stmpe_gpio->irq_base; + int offset = d->hwirq; int regoffset = offset / 8; int mask = 1 << (offset % 8); @@ -200,7 +202,7 @@ static void stmpe_gpio_irq_sync_unlock(struct irq_data *d) static void stmpe_gpio_irq_mask(struct irq_data *d) { struct stmpe_gpio *stmpe_gpio = irq_data_get_irq_chip_data(d); - int offset = d->irq - stmpe_gpio->irq_base; + int offset = d->hwirq; int regoffset = offset / 8; int mask = 1 << (offset % 8); @@ -210,7 +212,7 @@ static void stmpe_gpio_irq_mask(struct irq_data *d) static void stmpe_gpio_irq_unmask(struct irq_data *d) { struct stmpe_gpio *stmpe_gpio = irq_data_get_irq_chip_data(d); - int offset = d->irq - stmpe_gpio->irq_base; + int offset = d->hwirq; int regoffset = offset / 8; int mask = 1 << (offset % 8); @@ -252,8 +254,9 @@ static irqreturn_t stmpe_gpio_irq(int irq, void *dev) while (stat) { int bit = __ffs(stat); int line = bank * 8 + bit; + int virq = irq_find_mapping(stmpe_gpio->domain, line); - handle_nested_irq(stmpe_gpio->irq_base + line); + handle_nested_irq(virq); stat &= ~(1 << bit); } @@ -268,38 +271,55 @@ static irqreturn_t stmpe_gpio_irq(int irq, void *dev) return IRQ_HANDLED; } -static int __devinit stmpe_gpio_irq_init(struct stmpe_gpio *stmpe_gpio) +int stmpe_gpio_irq_map(struct irq_domain *d, unsigned int virq, + irq_hw_number_t hwirq) { - int base = stmpe_gpio->irq_base; - int irq; + struct stmpe_gpio *stmpe_gpio = d->host_data; + + if (!stmpe_gpio) + return -EINVAL; - for (irq = base; irq < base + stmpe_gpio->chip.ngpio; irq++) { - irq_set_chip_data(irq, stmpe_gpio); - irq_set_chip_and_handler(irq, &stmpe_gpio_irq_chip, - handle_simple_irq); - irq_set_nested_thread(irq, 1); + irq_set_chip_data(hwirq, stmpe_gpio); + irq_set_chip_and_handler(hwirq, &stmpe_gpio_irq_chip, + handle_simple_irq); + irq_set_nested_thread(hwirq, 1); #ifdef CONFIG_ARM - set_irq_flags(irq, IRQF_VALID); + set_irq_flags(hwirq, IRQF_VALID); #else - irq_set_noprobe(irq); + irq_set_noprobe(hwirq); #endif - } return 0; } -static void stmpe_gpio_irq_remove(struct stmpe_gpio *stmpe_gpio) +void stmpe_gpio_irq_unmap(struct irq_domain *d, unsigned int virq) { - int base = stmpe_gpio->irq_base; - int irq; - - for (irq = base; irq < base + stmpe_gpio->chip.ngpio; irq++) { #ifdef CONFIG_ARM - set_irq_flags(irq, 0); + set_irq_flags(virq, 0); #endif - irq_set_chip_and_handler(irq, NULL, NULL); - irq_set_chip_data(irq, NULL); + irq_set_chip_and_handler(virq, NULL, NULL); + irq_set_chip_data(virq, NULL); +} + +static const struct irq_domain_ops stmpe_gpio_irq_simple_ops = { + .unmap = stmpe_gpio_irq_unmap, + .map = stmpe_gpio_irq_map, + .xlate = irq_domain_xlate_twocell, +}; + +static int __devinit stmpe_gpio_irq_init(struct stmpe_gpio *stmpe_gpio) +{ + int base = stmpe_gpio->irq_base; + + stmpe_gpio->domain = irq_domain_add_simple(NULL, + stmpe_gpio->chip.ngpio, base, + &stmpe_gpio_irq_simple_ops, stmpe_gpio); + if (!stmpe_gpio->domain) { + dev_err(stmpe_gpio->dev, "failed to create irqdomain\n"); + return -ENOSYS; } + + return 0; } static int __devinit stmpe_gpio_probe(struct platform_device *pdev) @@ -354,7 +374,7 @@ static int __devinit stmpe_gpio_probe(struct platform_device *pdev) IRQF_ONESHOT, "stmpe-gpio", stmpe_gpio); if (ret) { dev_err(&pdev->dev, "unable to get irq: %d\n", ret); - goto out_removeirq; + goto out_disable; } } @@ -374,9 +394,6 @@ static int __devinit stmpe_gpio_probe(struct platform_device *pdev) out_freeirq: if (irq >= 0) free_irq(irq, stmpe_gpio); -out_removeirq: - if (irq >= 0) - stmpe_gpio_irq_remove(stmpe_gpio); out_disable: stmpe_disable(stmpe, STMPE_BLOCK_GPIO); out_free: @@ -404,10 +421,9 @@ static int __devexit stmpe_gpio_remove(struct platform_device *pdev) stmpe_disable(stmpe, STMPE_BLOCK_GPIO); - if (irq >= 0) { + if (irq >= 0) free_irq(irq, stmpe_gpio); - stmpe_gpio_irq_remove(stmpe_gpio); - } + platform_set_drvdata(pdev, NULL); kfree(stmpe_gpio); -- cgit v1.1