summaryrefslogtreecommitdiffstats
path: root/drivers/gpio
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpio')
-rw-r--r--drivers/gpio/Kconfig15
-rw-r--r--drivers/gpio/Makefile2
-rw-r--r--drivers/gpio/gpio-ab8500.c520
-rw-r--r--drivers/gpio/gpio-mvebu.c18
-rw-r--r--drivers/gpio/gpio-mxs.c9
-rw-r--r--drivers/gpio/gpio-palmas.c184
-rw-r--r--drivers/gpio/gpio-samsung.c7
-rw-r--r--drivers/gpio/gpio-spear-spics.c8
-rw-r--r--drivers/gpio/gpio-stp-xway.c9
-rw-r--r--drivers/gpio/gpio-tegra.c9
-rw-r--r--drivers/gpio/gpiolib-of.c37
-rw-r--r--drivers/gpio/gpiolib.c2
12 files changed, 223 insertions, 597 deletions
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index ab97eb80537..93aaadf99f2 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -69,7 +69,7 @@ config DEBUG_GPIO
config GPIO_SYSFS
bool "/sys/class/gpio/... (sysfs interface)"
- depends on SYSFS && EXPERIMENTAL
+ depends on SYSFS
help
Say Y here to add a sysfs interface for GPIOs.
@@ -280,7 +280,7 @@ config GPIO_ICH
config GPIO_VX855
tristate "VIA VX855/VX875 GPIO"
- depends on PCI
+ depends on PCI && GENERIC_HARDIRQS
select MFD_CORE
select MFD_VX855
help
@@ -610,7 +610,7 @@ config GPIO_TIMBERDALE
config GPIO_RDC321X
tristate "RDC R-321x GPIO support"
- depends on PCI
+ depends on PCI && GENERIC_HARDIRQS
select MFD_CORE
select MFD_RDC321X
help
@@ -668,11 +668,12 @@ config GPIO_JANZ_TTL
This driver provides support for driving the pins in output
mode only. Input mode is not supported.
-config GPIO_AB8500
- bool "ST-Ericsson AB8500 Mixed Signal Circuit gpio functions"
- depends on AB8500_CORE && BROKEN
+config GPIO_PALMAS
+ bool "TI PALMAS series PMICs GPIO"
+ depends on MFD_PALMAS
help
- Select this to enable the AB8500 IC GPIO driver
+ Select this option to enable GPIO driver for the TI PALMAS
+ series chip family.
config GPIO_TPS6586X
bool "TPS6586X GPIO"
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index 4398034db4a..22e07bc9fcb 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -11,7 +11,6 @@ obj-$(CONFIG_GPIO_ACPI) += gpiolib-acpi.o
obj-$(CONFIG_GPIO_GENERIC) += gpio-generic.o
obj-$(CONFIG_GPIO_74X164) += gpio-74x164.o
-obj-$(CONFIG_GPIO_AB8500) += gpio-ab8500.o
obj-$(CONFIG_GPIO_ADNP) += gpio-adnp.o
obj-$(CONFIG_GPIO_ADP5520) += gpio-adp5520.o
obj-$(CONFIG_GPIO_ADP5588) += gpio-adp5588.o
@@ -71,6 +70,7 @@ obj-$(CONFIG_GPIO_TC3589X) += gpio-tc3589x.o
obj-$(CONFIG_ARCH_TEGRA) += gpio-tegra.o
obj-$(CONFIG_GPIO_TIMBERDALE) += gpio-timberdale.o
obj-$(CONFIG_ARCH_DAVINCI_TNETV107X) += gpio-tnetv107x.o
+obj-$(CONFIG_GPIO_PALMAS) += gpio-palmas.o
obj-$(CONFIG_GPIO_TPS6586X) += gpio-tps6586x.o
obj-$(CONFIG_GPIO_TPS65910) += gpio-tps65910.o
obj-$(CONFIG_GPIO_TPS65912) += gpio-tps65912.o
diff --git a/drivers/gpio/gpio-ab8500.c b/drivers/gpio/gpio-ab8500.c
deleted file mode 100644
index 983ad425f0a..00000000000
--- a/drivers/gpio/gpio-ab8500.c
+++ /dev/null
@@ -1,520 +0,0 @@
-/*
- * Copyright (C) ST-Ericsson SA 2011
- *
- * Author: BIBEK BASU <bibek.basu@stericsson.com>
- * License terms: GNU General Public License (GPL) version 2
- *
- * 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 <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/slab.h>
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/err.h>
-#include <linux/platform_device.h>
-#include <linux/gpio.h>
-#include <linux/irq.h>
-#include <linux/interrupt.h>
-#include <linux/mfd/ab8500.h>
-#include <linux/mfd/abx500.h>
-#include <linux/mfd/ab8500/gpio.h>
-
-/*
- * GPIO registers offset
- * Bank: 0x10
- */
-#define AB8500_GPIO_SEL1_REG 0x00
-#define AB8500_GPIO_SEL2_REG 0x01
-#define AB8500_GPIO_SEL3_REG 0x02
-#define AB8500_GPIO_SEL4_REG 0x03
-#define AB8500_GPIO_SEL5_REG 0x04
-#define AB8500_GPIO_SEL6_REG 0x05
-
-#define AB8500_GPIO_DIR1_REG 0x10
-#define AB8500_GPIO_DIR2_REG 0x11
-#define AB8500_GPIO_DIR3_REG 0x12
-#define AB8500_GPIO_DIR4_REG 0x13
-#define AB8500_GPIO_DIR5_REG 0x14
-#define AB8500_GPIO_DIR6_REG 0x15
-
-#define AB8500_GPIO_OUT1_REG 0x20
-#define AB8500_GPIO_OUT2_REG 0x21
-#define AB8500_GPIO_OUT3_REG 0x22
-#define AB8500_GPIO_OUT4_REG 0x23
-#define AB8500_GPIO_OUT5_REG 0x24
-#define AB8500_GPIO_OUT6_REG 0x25
-
-#define AB8500_GPIO_PUD1_REG 0x30
-#define AB8500_GPIO_PUD2_REG 0x31
-#define AB8500_GPIO_PUD3_REG 0x32
-#define AB8500_GPIO_PUD4_REG 0x33
-#define AB8500_GPIO_PUD5_REG 0x34
-#define AB8500_GPIO_PUD6_REG 0x35
-
-#define AB8500_GPIO_IN1_REG 0x40
-#define AB8500_GPIO_IN2_REG 0x41
-#define AB8500_GPIO_IN3_REG 0x42
-#define AB8500_GPIO_IN4_REG 0x43
-#define AB8500_GPIO_IN5_REG 0x44
-#define AB8500_GPIO_IN6_REG 0x45
-#define AB8500_GPIO_ALTFUN_REG 0x45
-#define ALTFUN_REG_INDEX 6
-#define AB8500_NUM_GPIO 42
-#define AB8500_NUM_VIR_GPIO_IRQ 16
-
-enum ab8500_gpio_action {
- NONE,
- STARTUP,
- SHUTDOWN,
- MASK,
- UNMASK
-};
-
-struct ab8500_gpio {
- struct gpio_chip chip;
- struct ab8500 *parent;
- struct device *dev;
- struct mutex lock;
- u32 irq_base;
- enum ab8500_gpio_action irq_action;
- u16 rising;
- u16 falling;
-};
-/**
- * to_ab8500_gpio() - get the pointer to ab8500_gpio
- * @chip: Member of the structure ab8500_gpio
- */
-static inline struct ab8500_gpio *to_ab8500_gpio(struct gpio_chip *chip)
-{
- return container_of(chip, struct ab8500_gpio, chip);
-}
-
-static int ab8500_gpio_set_bits(struct gpio_chip *chip, u8 reg,
- unsigned offset, int val)
-{
- struct ab8500_gpio *ab8500_gpio = to_ab8500_gpio(chip);
- u8 pos = offset % 8;
- int ret;
-
- reg = reg + (offset / 8);
- ret = abx500_mask_and_set_register_interruptible(ab8500_gpio->dev,
- AB8500_MISC, reg, 1 << pos, val << pos);
- if (ret < 0)
- dev_err(ab8500_gpio->dev, "%s write failed\n", __func__);
- return ret;
-}
-/**
- * ab8500_gpio_get() - Get the particular GPIO value
- * @chip: Gpio device
- * @offset: GPIO number to read
- */
-static int ab8500_gpio_get(struct gpio_chip *chip, unsigned offset)
-{
- struct ab8500_gpio *ab8500_gpio = to_ab8500_gpio(chip);
- u8 mask = 1 << (offset % 8);
- u8 reg = AB8500_GPIO_OUT1_REG + (offset / 8);
- int ret;
- u8 data;
- ret = abx500_get_register_interruptible(ab8500_gpio->dev, AB8500_MISC,
- reg, &data);
- if (ret < 0) {
- dev_err(ab8500_gpio->dev, "%s read failed\n", __func__);
- return ret;
- }
- return (data & mask) >> (offset % 8);
-}
-
-static void ab8500_gpio_set(struct gpio_chip *chip, unsigned offset, int val)
-{
- struct ab8500_gpio *ab8500_gpio = to_ab8500_gpio(chip);
- int ret;
- /* Write the data */
- ret = ab8500_gpio_set_bits(chip, AB8500_GPIO_OUT1_REG, offset, 1);
- if (ret < 0)
- dev_err(ab8500_gpio->dev, "%s write failed\n", __func__);
-}
-
-static int ab8500_gpio_direction_output(struct gpio_chip *chip, unsigned offset,
- int val)
-{
- int ret;
- /* set direction as output */
- ret = ab8500_gpio_set_bits(chip, AB8500_GPIO_DIR1_REG, offset, 1);
- if (ret < 0)
- return ret;
- /* disable pull down */
- ret = ab8500_gpio_set_bits(chip, AB8500_GPIO_PUD1_REG, offset, 1);
- if (ret < 0)
- return ret;
- /* set the output as 1 or 0 */
- return ab8500_gpio_set_bits(chip, AB8500_GPIO_OUT1_REG, offset, val);
-
-}
-
-static int ab8500_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
-{
- /* set the register as input */
- return ab8500_gpio_set_bits(chip, AB8500_GPIO_DIR1_REG, offset, 0);
-}
-
-static int ab8500_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
-{
- /*
- * Only some GPIOs are interrupt capable, and they are
- * organized in discontiguous clusters:
- *
- * GPIO6 to GPIO13
- * GPIO24 and GPIO25
- * GPIO36 to GPIO41
- */
- static struct ab8500_gpio_irq_cluster {
- int start;
- int end;
- } clusters[] = {
- {.start = 6, .end = 13},
- {.start = 24, .end = 25},
- {.start = 36, .end = 41},
- };
- struct ab8500_gpio *ab8500_gpio = to_ab8500_gpio(chip);
- int base = ab8500_gpio->irq_base;
- int i;
-
- for (i = 0; i < ARRAY_SIZE(clusters); i++) {
- struct ab8500_gpio_irq_cluster *cluster = &clusters[i];
-
- if (offset >= cluster->start && offset <= cluster->end)
- return base + offset - cluster->start;
-
- /* Advance by the number of gpios in this cluster */
- base += cluster->end - cluster->start + 1;
- }
-
- return -EINVAL;
-}
-
-static struct gpio_chip ab8500gpio_chip = {
- .label = "ab8500_gpio",
- .owner = THIS_MODULE,
- .direction_input = ab8500_gpio_direction_input,
- .get = ab8500_gpio_get,
- .direction_output = ab8500_gpio_direction_output,
- .set = ab8500_gpio_set,
- .to_irq = ab8500_gpio_to_irq,
-};
-
-static unsigned int irq_to_rising(unsigned int irq)
-{
- struct ab8500_gpio *ab8500_gpio = get_irq_chip_data(irq);
- int offset = irq - ab8500_gpio->irq_base;
- int new_irq = offset + AB8500_INT_GPIO6R
- + ab8500_gpio->parent->irq_base;
- return new_irq;
-}
-
-static unsigned int irq_to_falling(unsigned int irq)
-{
- struct ab8500_gpio *ab8500_gpio = get_irq_chip_data(irq);
- int offset = irq - ab8500_gpio->irq_base;
- int new_irq = offset + AB8500_INT_GPIO6F
- + ab8500_gpio->parent->irq_base;
- return new_irq;
-
-}
-
-static unsigned int rising_to_irq(unsigned int irq, void *dev)
-{
- struct ab8500_gpio *ab8500_gpio = dev;
- int offset = irq - AB8500_INT_GPIO6R
- - ab8500_gpio->parent->irq_base ;
- int new_irq = offset + ab8500_gpio->irq_base;
- return new_irq;
-}
-
-static unsigned int falling_to_irq(unsigned int irq, void *dev)
-{
- struct ab8500_gpio *ab8500_gpio = dev;
- int offset = irq - AB8500_INT_GPIO6F
- - ab8500_gpio->parent->irq_base ;
- int new_irq = offset + ab8500_gpio->irq_base;
- return new_irq;
-
-}
-
-/*
- * IRQ handler
- */
-
-static irqreturn_t handle_rising(int irq, void *dev)
-{
-
- handle_nested_irq(rising_to_irq(irq , dev));
- return IRQ_HANDLED;
-}
-
-static irqreturn_t handle_falling(int irq, void *dev)
-{
-
- handle_nested_irq(falling_to_irq(irq, dev));
- return IRQ_HANDLED;
-}
-
-static void ab8500_gpio_irq_lock(unsigned int irq)
-{
- struct ab8500_gpio *ab8500_gpio = get_irq_chip_data(irq);
- mutex_lock(&ab8500_gpio->lock);
-}
-
-static void ab8500_gpio_irq_sync_unlock(unsigned int irq)
-{
- struct ab8500_gpio *ab8500_gpio = get_irq_chip_data(irq);
- int offset = irq - ab8500_gpio->irq_base;
- bool rising = ab8500_gpio->rising & BIT(offset);
- bool falling = ab8500_gpio->falling & BIT(offset);
- int ret;
-
- switch (ab8500_gpio->irq_action) {
- case STARTUP:
- if (rising)
- ret = request_threaded_irq(irq_to_rising(irq),
- NULL, handle_rising,
- IRQF_TRIGGER_RISING,
- "ab8500-gpio-r", ab8500_gpio);
- if (falling)
- ret = request_threaded_irq(irq_to_falling(irq),
- NULL, handle_falling,
- IRQF_TRIGGER_FALLING,
- "ab8500-gpio-f", ab8500_gpio);
- break;
- case SHUTDOWN:
- if (rising)
- free_irq(irq_to_rising(irq), ab8500_gpio);
- if (falling)
- free_irq(irq_to_falling(irq), ab8500_gpio);
- break;
- case MASK:
- if (rising)
- disable_irq(irq_to_rising(irq));
- if (falling)
- disable_irq(irq_to_falling(irq));
- break;
- case UNMASK:
- if (rising)
- enable_irq(irq_to_rising(irq));
- if (falling)
- enable_irq(irq_to_falling(irq));
- break;
- case NONE:
- break;
- }
- ab8500_gpio->irq_action = NONE;
- ab8500_gpio->rising &= ~(BIT(offset));
- ab8500_gpio->falling &= ~(BIT(offset));
- mutex_unlock(&ab8500_gpio->lock);
-}
-
-
-static void ab8500_gpio_irq_mask(unsigned int irq)
-{
- struct ab8500_gpio *ab8500_gpio = get_irq_chip_data(irq);
- ab8500_gpio->irq_action = MASK;
-}
-
-static void ab8500_gpio_irq_unmask(unsigned int irq)
-{
- struct ab8500_gpio *ab8500_gpio = get_irq_chip_data(irq);
- ab8500_gpio->irq_action = UNMASK;
-}
-
-static int ab8500_gpio_irq_set_type(unsigned int irq, unsigned int type)
-{
- struct ab8500_gpio *ab8500_gpio = get_irq_chip_data(irq);
- int offset = irq - ab8500_gpio->irq_base;
-
- if (type == IRQ_TYPE_EDGE_BOTH) {
- ab8500_gpio->rising = BIT(offset);
- ab8500_gpio->falling = BIT(offset);
- } else if (type == IRQ_TYPE_EDGE_RISING) {
- ab8500_gpio->rising = BIT(offset);
- } else {
- ab8500_gpio->falling = BIT(offset);
- }
- return 0;
-}
-
-unsigned int ab8500_gpio_irq_startup(unsigned int irq)
-{
- struct ab8500_gpio *ab8500_gpio = get_irq_chip_data(irq);
- ab8500_gpio->irq_action = STARTUP;
- return 0;
-}
-
-void ab8500_gpio_irq_shutdown(unsigned int irq)
-{
- struct ab8500_gpio *ab8500_gpio = get_irq_chip_data(irq);
- ab8500_gpio->irq_action = SHUTDOWN;
-}
-
-static struct irq_chip ab8500_gpio_irq_chip = {
- .name = "ab8500-gpio",
- .startup = ab8500_gpio_irq_startup,
- .shutdown = ab8500_gpio_irq_shutdown,
- .bus_lock = ab8500_gpio_irq_lock,
- .bus_sync_unlock = ab8500_gpio_irq_sync_unlock,
- .mask = ab8500_gpio_irq_mask,
- .unmask = ab8500_gpio_irq_unmask,
- .set_type = ab8500_gpio_irq_set_type,
-};
-
-static int ab8500_gpio_irq_init(struct ab8500_gpio *ab8500_gpio)
-{
- u32 base = ab8500_gpio->irq_base;
- int irq;
-
- for (irq = base; irq < base + AB8500_NUM_VIR_GPIO_IRQ ; irq++) {
- set_irq_chip_data(irq, ab8500_gpio);
- set_irq_chip_and_handler(irq, &ab8500_gpio_irq_chip,
- handle_simple_irq);
- set_irq_nested_thread(irq, 1);
-#ifdef CONFIG_ARM
- set_irq_flags(irq, IRQF_VALID);
-#else
- set_irq_noprobe(irq);
-#endif
- }
-
- return 0;
-}
-
-static void ab8500_gpio_irq_remove(struct ab8500_gpio *ab8500_gpio)
-{
- int base = ab8500_gpio->irq_base;
- int irq;
-
- for (irq = base; irq < base + AB8500_NUM_VIR_GPIO_IRQ; irq++) {
-#ifdef CONFIG_ARM
- set_irq_flags(irq, 0);
-#endif
- set_irq_chip_and_handler(irq, NULL, NULL);
- set_irq_chip_data(irq, NULL);
- }
-}
-
-static int ab8500_gpio_probe(struct platform_device *pdev)
-{
- struct ab8500_platform_data *ab8500_pdata =
- dev_get_platdata(pdev->dev.parent);
- struct ab8500_gpio_platform_data *pdata;
- struct ab8500_gpio *ab8500_gpio;
- int ret;
- int i;
-
- pdata = ab8500_pdata->gpio;
- if (!pdata) {
- dev_err(&pdev->dev, "gpio platform data missing\n");
- return -ENODEV;
- }
-
- ab8500_gpio = kzalloc(sizeof(struct ab8500_gpio), GFP_KERNEL);
- if (ab8500_gpio == NULL) {
- dev_err(&pdev->dev, "failed to allocate memory\n");
- return -ENOMEM;
- }
- ab8500_gpio->dev = &pdev->dev;
- ab8500_gpio->parent = dev_get_drvdata(pdev->dev.parent);
- ab8500_gpio->chip = ab8500gpio_chip;
- ab8500_gpio->chip.ngpio = AB8500_NUM_GPIO;
- ab8500_gpio->chip.dev = &pdev->dev;
- ab8500_gpio->chip.base = pdata->gpio_base;
- ab8500_gpio->irq_base = pdata->irq_base;
- /* initialize the lock */
- mutex_init(&ab8500_gpio->lock);
- /*
- * AB8500 core will handle and clear the IRQ
- * configre GPIO based on config-reg value.
- * These values are for selecting the PINs as
- * GPIO or alternate function
- */
- for (i = AB8500_GPIO_SEL1_REG; i <= AB8500_GPIO_SEL6_REG; i++) {
- ret = abx500_set_register_interruptible(ab8500_gpio->dev,
- AB8500_MISC, i,
- pdata->config_reg[i]);
- if (ret < 0)
- goto out_free;
- }
- ret = abx500_set_register_interruptible(ab8500_gpio->dev, AB8500_MISC,
- AB8500_GPIO_ALTFUN_REG,
- pdata->config_reg[ALTFUN_REG_INDEX]);
- if (ret < 0)
- goto out_free;
-
- ret = ab8500_gpio_irq_init(ab8500_gpio);
- if (ret)
- goto out_free;
- ret = gpiochip_add(&ab8500_gpio->chip);
- if (ret) {
- dev_err(&pdev->dev, "unable to add gpiochip: %d\n",
- ret);
- goto out_rem_irq;
- }
- platform_set_drvdata(pdev, ab8500_gpio);
- return 0;
-
-out_rem_irq:
- ab8500_gpio_irq_remove(ab8500_gpio);
-out_free:
- mutex_destroy(&ab8500_gpio->lock);
- kfree(ab8500_gpio);
- return ret;
-}
-
-/*
- * ab8500_gpio_remove() - remove Ab8500-gpio driver
- * @pdev : Platform device registered
- */
-static int ab8500_gpio_remove(struct platform_device *pdev)
-{
- struct ab8500_gpio *ab8500_gpio = platform_get_drvdata(pdev);
- int ret;
-
- ret = gpiochip_remove(&ab8500_gpio->chip);
- if (ret < 0) {
- dev_err(ab8500_gpio->dev, "unable to remove gpiochip: %d\n",
- ret);
- return ret;
- }
-
- platform_set_drvdata(pdev, NULL);
- mutex_destroy(&ab8500_gpio->lock);
- kfree(ab8500_gpio);
-
- return 0;
-}
-
-static struct platform_driver ab8500_gpio_driver = {
- .driver = {
- .name = "ab8500-gpio",
- .owner = THIS_MODULE,
- },
- .probe = ab8500_gpio_probe,
- .remove = ab8500_gpio_remove,
-};
-
-static int __init ab8500_gpio_init(void)
-{
- return platform_driver_register(&ab8500_gpio_driver);
-}
-arch_initcall(ab8500_gpio_init);
-
-static void __exit ab8500_gpio_exit(void)
-{
- platform_driver_unregister(&ab8500_gpio_driver);
-}
-module_exit(ab8500_gpio_exit);
-
-MODULE_AUTHOR("BIBEK BASU <bibek.basu@stericsson.com>");
-MODULE_DESCRIPTION("Driver allows to use AB8500 unused pins to be used as GPIO");
-MODULE_ALIAS("platform:ab8500-gpio");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/gpio/gpio-mvebu.c b/drivers/gpio/gpio-mvebu.c
index 6819d63cb16..7472182967c 100644
--- a/drivers/gpio/gpio-mvebu.c
+++ b/drivers/gpio/gpio-mvebu.c
@@ -33,6 +33,7 @@
* interrupts.
*/
+#include <linux/err.h>
#include <linux/module.h>
#include <linux/gpio.h>
#include <linux/irq.h>
@@ -544,11 +545,9 @@ static int mvebu_gpio_probe(struct platform_device *pdev)
mvchip->chip.of_node = np;
spin_lock_init(&mvchip->lock);
- mvchip->membase = devm_request_and_ioremap(&pdev->dev, res);
- if (! mvchip->membase) {
- dev_err(&pdev->dev, "Cannot ioremap\n");
- return -ENOMEM;
- }
+ mvchip->membase = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(mvchip->membase))
+ return PTR_ERR(mvchip->membase);
/* The Armada XP has a second range of registers for the
* per-CPU registers */
@@ -559,11 +558,10 @@ static int mvebu_gpio_probe(struct platform_device *pdev)
return -ENODEV;
}
- mvchip->percpu_membase = devm_request_and_ioremap(&pdev->dev, res);
- if (! mvchip->percpu_membase) {
- dev_err(&pdev->dev, "Cannot ioremap\n");
- return -ENOMEM;
- }
+ mvchip->percpu_membase = devm_ioremap_resource(&pdev->dev,
+ res);
+ if (IS_ERR(mvchip->percpu_membase))
+ return PTR_ERR(mvchip->percpu_membase);
}
/*
diff --git a/drivers/gpio/gpio-mxs.c b/drivers/gpio/gpio-mxs.c
index 859b6fabc7b..25000b0f845 100644
--- a/drivers/gpio/gpio-mxs.c
+++ b/drivers/gpio/gpio-mxs.c
@@ -20,6 +20,7 @@
* MA 02110-1301, USA.
*/
+#include <linux/err.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/io.h>
@@ -284,12 +285,14 @@ static int mxs_gpio_probe(struct platform_device *pdev)
parent = of_get_parent(np);
base = of_iomap(parent, 0);
of_node_put(parent);
+ if (!base)
+ return -EADDRNOTAVAIL;
} else {
iores = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- base = devm_request_and_ioremap(&pdev->dev, iores);
+ base = devm_ioremap_resource(&pdev->dev, iores);
+ if (IS_ERR(base))
+ return PTR_ERR(base);
}
- if (!base)
- return -EADDRNOTAVAIL;
}
port->base = base;
diff --git a/drivers/gpio/gpio-palmas.c b/drivers/gpio/gpio-palmas.c
new file mode 100644
index 00000000000..e3a4e56f5a4
--- /dev/null
+++ b/drivers/gpio/gpio-palmas.c
@@ -0,0 +1,184 @@
+/*
+ * TI Palma series PMIC's GPIO driver.
+ *
+ * Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved.
+ *
+ * Author: Laxman Dewangan <ldewangan@nvidia.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/gpio.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/mfd/palmas.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+
+struct palmas_gpio {
+ struct gpio_chip gpio_chip;
+ struct palmas *palmas;
+};
+
+static inline struct palmas_gpio *to_palmas_gpio(struct gpio_chip *chip)
+{
+ return container_of(chip, struct palmas_gpio, gpio_chip);
+}
+
+static int palmas_gpio_get(struct gpio_chip *gc, unsigned offset)
+{
+ struct palmas_gpio *pg = to_palmas_gpio(gc);
+ struct palmas *palmas = pg->palmas;
+ unsigned int val;
+ int ret;
+
+ ret = palmas_read(palmas, PALMAS_GPIO_BASE, PALMAS_GPIO_DATA_IN, &val);
+ if (ret < 0) {
+ dev_err(gc->dev, "GPIO_DATA_IN read failed, err = %d\n", ret);
+ return ret;
+ }
+ return !!(val & BIT(offset));
+}
+
+static void palmas_gpio_set(struct gpio_chip *gc, unsigned offset,
+ int value)
+{
+ struct palmas_gpio *pg = to_palmas_gpio(gc);
+ struct palmas *palmas = pg->palmas;
+ int ret;
+
+ if (value)
+ ret = palmas_write(palmas, PALMAS_GPIO_BASE,
+ PALMAS_GPIO_SET_DATA_OUT, BIT(offset));
+ else
+ ret = palmas_write(palmas, PALMAS_GPIO_BASE,
+ PALMAS_GPIO_CLEAR_DATA_OUT, BIT(offset));
+ if (ret < 0)
+ dev_err(gc->dev, "%s write failed, err = %d\n",
+ (value) ? "GPIO_SET_DATA_OUT" : "GPIO_CLEAR_DATA_OUT",
+ ret);
+}
+
+static int palmas_gpio_output(struct gpio_chip *gc, unsigned offset,
+ int value)
+{
+ struct palmas_gpio *pg = to_palmas_gpio(gc);
+ struct palmas *palmas = pg->palmas;
+ int ret;
+
+ /* Set the initial value */
+ palmas_gpio_set(gc, offset, value);
+
+ ret = palmas_update_bits(palmas, PALMAS_GPIO_BASE,
+ PALMAS_GPIO_DATA_DIR, BIT(offset), BIT(offset));
+ if (ret < 0)
+ dev_err(gc->dev, "GPIO_DATA_DIR write failed, err = %d\n", ret);
+ return ret;
+}
+
+static int palmas_gpio_input(struct gpio_chip *gc, unsigned offset)
+{
+ struct palmas_gpio *pg = to_palmas_gpio(gc);
+ struct palmas *palmas = pg->palmas;
+ int ret;
+
+ ret = palmas_update_bits(palmas, PALMAS_GPIO_BASE,
+ PALMAS_GPIO_DATA_DIR, BIT(offset), 0);
+ if (ret < 0)
+ dev_err(gc->dev, "GPIO_DATA_DIR write failed, err = %d\n", ret);
+ return ret;
+}
+
+static int palmas_gpio_to_irq(struct gpio_chip *gc, unsigned offset)
+{
+ struct palmas_gpio *pg = to_palmas_gpio(gc);
+ struct palmas *palmas = pg->palmas;
+
+ return palmas_irq_get_virq(palmas, PALMAS_GPIO_0_IRQ + offset);
+}
+
+static int palmas_gpio_probe(struct platform_device *pdev)
+{
+ struct palmas *palmas = dev_get_drvdata(pdev->dev.parent);
+ struct palmas_platform_data *palmas_pdata;
+ struct palmas_gpio *palmas_gpio;
+ int ret;
+
+ palmas_gpio = devm_kzalloc(&pdev->dev,
+ sizeof(*palmas_gpio), GFP_KERNEL);
+ if (!palmas_gpio) {
+ dev_err(&pdev->dev, "Could not allocate palmas_gpio\n");
+ return -ENOMEM;
+ }
+
+ palmas_gpio->palmas = palmas;
+ palmas_gpio->gpio_chip.owner = THIS_MODULE;
+ palmas_gpio->gpio_chip.label = dev_name(&pdev->dev);
+ palmas_gpio->gpio_chip.ngpio = 8;
+ palmas_gpio->gpio_chip.can_sleep = 1;
+ palmas_gpio->gpio_chip.direction_input = palmas_gpio_input;
+ palmas_gpio->gpio_chip.direction_output = palmas_gpio_output;
+ palmas_gpio->gpio_chip.to_irq = palmas_gpio_to_irq;
+ palmas_gpio->gpio_chip.set = palmas_gpio_set;
+ palmas_gpio->gpio_chip.get = palmas_gpio_get;
+ palmas_gpio->gpio_chip.dev = &pdev->dev;
+#ifdef CONFIG_OF_GPIO
+ palmas_gpio->gpio_chip.of_node = palmas->dev->of_node;
+#endif
+ palmas_pdata = dev_get_platdata(palmas->dev);
+ if (palmas_pdata && palmas_pdata->gpio_base)
+ palmas_gpio->gpio_chip.base = palmas_pdata->gpio_base;
+ else
+ palmas_gpio->gpio_chip.base = -1;
+
+ ret = gpiochip_add(&palmas_gpio->gpio_chip);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "Could not register gpiochip, %d\n", ret);
+ return ret;
+ }
+
+ platform_set_drvdata(pdev, palmas_gpio);
+ return ret;
+}
+
+static int palmas_gpio_remove(struct platform_device *pdev)
+{
+ struct palmas_gpio *palmas_gpio = platform_get_drvdata(pdev);
+
+ return gpiochip_remove(&palmas_gpio->gpio_chip);
+}
+
+static struct platform_driver palmas_gpio_driver = {
+ .driver.name = "palmas-gpio",
+ .driver.owner = THIS_MODULE,
+ .probe = palmas_gpio_probe,
+ .remove = palmas_gpio_remove,
+};
+
+static int __init palmas_gpio_init(void)
+{
+ return platform_driver_register(&palmas_gpio_driver);
+}
+subsys_initcall(palmas_gpio_init);
+
+static void __exit palmas_gpio_exit(void)
+{
+ platform_driver_unregister(&palmas_gpio_driver);
+}
+module_exit(palmas_gpio_exit);
+
+MODULE_ALIAS("platform:palmas-gpio");
+MODULE_AUTHOR("Laxman Dewangan <ldewangan@nvidia.com>");
+MODULE_DESCRIPTION("GPIO driver for TI Palmas series PMICs");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/gpio/gpio-samsung.c b/drivers/gpio/gpio-samsung.c
index 76be7eed79d..b3643ff007e 100644
--- a/drivers/gpio/gpio-samsung.c
+++ b/drivers/gpio/gpio-samsung.c
@@ -38,7 +38,6 @@
#include <plat/gpio-core.h>
#include <plat/gpio-cfg.h>
#include <plat/gpio-cfg-helpers.h>
-#include <plat/gpio-fns.h>
#include <plat/pm.h>
int samsung_gpio_setpull_updown(struct samsung_gpio_chip *chip,
@@ -3023,9 +3022,9 @@ static __init int samsung_gpiolib_init(void)
*/
struct device_node *pctrl_np;
static const struct of_device_id exynos_pinctrl_ids[] = {
- { .compatible = "samsung,pinctrl-exynos4210", },
- { .compatible = "samsung,pinctrl-exynos4x12", },
- { .compatible = "samsung,pinctrl-exynos5440", },
+ { .compatible = "samsung,exynos4210-pinctrl", },
+ { .compatible = "samsung,exynos4x12-pinctrl", },
+ { .compatible = "samsung,exynos5440-pinctrl", },
};
for_each_matching_node(pctrl_np, exynos_pinctrl_ids)
if (pctrl_np && of_device_is_available(pctrl_np))
diff --git a/drivers/gpio/gpio-spear-spics.c b/drivers/gpio/gpio-spear-spics.c
index 5f45fc4ed5d..7a4bf7c0d98 100644
--- a/drivers/gpio/gpio-spear-spics.c
+++ b/drivers/gpio/gpio-spear-spics.c
@@ -140,11 +140,9 @@ static int spics_gpio_probe(struct platform_device *pdev)
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;
- }
+ spics->base = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(spics->base))
+ return PTR_ERR(spics->base);
if (of_property_read_u32(np, "st-spics,peripcfg-reg",
&spics->perip_cfg))
diff --git a/drivers/gpio/gpio-stp-xway.c b/drivers/gpio/gpio-stp-xway.c
index 85841ee70b1..c20e0515121 100644
--- a/drivers/gpio/gpio-stp-xway.c
+++ b/drivers/gpio/gpio-stp-xway.c
@@ -214,11 +214,10 @@ static int xway_stp_probe(struct platform_device *pdev)
if (!chip)
return -ENOMEM;
- chip->virt = devm_request_and_ioremap(&pdev->dev, res);
- if (!chip->virt) {
- dev_err(&pdev->dev, "failed to remap STP memory\n");
- return -ENOMEM;
- }
+ chip->virt = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(chip->virt))
+ return PTR_ERR(chip->virt);
+
chip->gc.dev = &pdev->dev;
chip->gc.label = "stp-xway";
chip->gc.direction_output = xway_stp_dir_out;
diff --git a/drivers/gpio/gpio-tegra.c b/drivers/gpio/gpio-tegra.c
index 63cb643d4b5..414ad912232 100644
--- a/drivers/gpio/gpio-tegra.c
+++ b/drivers/gpio/gpio-tegra.c
@@ -17,6 +17,7 @@
*
*/
+#include <linux/err.h>
#include <linux/init.h>
#include <linux/irq.h>
#include <linux/interrupt.h>
@@ -450,11 +451,9 @@ static int tegra_gpio_probe(struct platform_device *pdev)
return -ENODEV;
}
- regs = devm_request_and_ioremap(&pdev->dev, res);
- if (!regs) {
- dev_err(&pdev->dev, "Couldn't ioremap regs\n");
- return -ENODEV;
- }
+ regs = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(regs))
+ return PTR_ERR(regs);
for (i = 0; i < tegra_gpio_bank_count; i++) {
for (j = 0; j < 4; j++) {
diff --git a/drivers/gpio/gpiolib-of.c b/drivers/gpio/gpiolib-of.c
index d542a141811..a71a54a3e3f 100644
--- a/drivers/gpio/gpiolib-of.c
+++ b/drivers/gpio/gpiolib-of.c
@@ -89,41 +89,6 @@ int of_get_named_gpio_flags(struct device_node *np, const char *propname,
EXPORT_SYMBOL(of_get_named_gpio_flags);
/**
- * of_gpio_named_count - Count GPIOs for a device
- * @np: device node to count GPIOs for
- * @propname: property name containing gpio specifier(s)
- *
- * The function returns the count of GPIOs specified for a node.
- *
- * Note that the empty GPIO specifiers counts too. For example,
- *
- * gpios = <0
- * &pio1 1 2
- * 0
- * &pio2 3 4>;
- *
- * defines four GPIOs (so this function will return 4), two of which
- * are not specified.
- */
-unsigned int of_gpio_named_count(struct device_node *np, const char* propname)
-{
- unsigned int cnt = 0;
-
- do {
- int ret;
-
- ret = of_parse_phandle_with_args(np, propname, "#gpio-cells",
- cnt, NULL);
- /* A hole in the gpios = <> counts anyway. */
- if (ret < 0 && ret != -EEXIST)
- break;
- } while (++cnt);
-
- return cnt;
-}
-EXPORT_SYMBOL(of_gpio_named_count);
-
-/**
* of_gpio_simple_xlate - translate gpio_spec to the GPIO number and flags
* @gc: pointer to the gpio_chip structure
* @np: device node of the GPIO chip
@@ -250,7 +215,7 @@ static void of_gpiochip_add_pin_range(struct gpio_chip *chip)
* on the same GPIO chip.
*/
ret = gpiochip_add_pin_range(chip,
- pinctrl_dev_get_name(pctldev),
+ pinctrl_dev_get_devname(pctldev),
0, /* offset in gpiochip */
pinspec.args[0],
pinspec.args[1]);
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
index 4b3f388bcc6..4828fe7c66c 100644
--- a/drivers/gpio/gpiolib.c
+++ b/drivers/gpio/gpiolib.c
@@ -830,7 +830,7 @@ int gpio_export(unsigned gpio, bool direction_may_change)
}
EXPORT_SYMBOL_GPL(gpio_export);
-static int match_export(struct device *dev, void *data)
+static int match_export(struct device *dev, const void *data)
{
return dev_get_drvdata(dev) == data;
}