diff options
Diffstat (limited to 'drivers/gpio')
| -rw-r--r-- | drivers/gpio/Kconfig | 27 | ||||
| -rw-r--r-- | drivers/gpio/Makefile | 3 | ||||
| -rw-r--r-- | drivers/gpio/devres.c | 1 | ||||
| -rw-r--r-- | drivers/gpio/gpio-amd8111.c | 246 | ||||
| -rw-r--r-- | drivers/gpio/gpio-arizona.c | 163 | ||||
| -rw-r--r-- | drivers/gpio/gpio-lpc32xx.c | 74 | ||||
| -rw-r--r-- | drivers/gpio/gpio-mxc.c | 131 | ||||
| -rw-r--r-- | drivers/gpio/gpio-omap.c | 24 | ||||
| -rw-r--r-- | drivers/gpio/gpio-pca953x.c | 67 | ||||
| -rw-r--r-- | drivers/gpio/gpio-pcf857x.c | 93 | ||||
| -rw-r--r-- | drivers/gpio/gpio-samsung.c | 5 | ||||
| -rw-r--r-- | drivers/gpio/gpio-sta2x11.c | 5 | ||||
| -rw-r--r-- | drivers/gpio/gpio-tps6586x.c | 158 | ||||
| -rw-r--r-- | drivers/gpio/gpio-tps65910.c | 3 | ||||
| -rw-r--r-- | drivers/gpio/gpio-wm8994.c | 22 | ||||
| -rw-r--r-- | drivers/gpio/gpiolib-of.c | 9 | ||||
| -rw-r--r-- | drivers/gpio/gpiolib.c | 2 |
17 files changed, 865 insertions, 168 deletions
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index c4067d0141f7..b16c8a72a2e2 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig | |||
| @@ -136,7 +136,7 @@ config GPIO_MPC8XXX | |||
| 136 | 136 | ||
| 137 | config GPIO_MSM_V1 | 137 | config GPIO_MSM_V1 |
| 138 | tristate "Qualcomm MSM GPIO v1" | 138 | tristate "Qualcomm MSM GPIO v1" |
| 139 | depends on GPIOLIB && ARCH_MSM | 139 | depends on GPIOLIB && ARCH_MSM && (ARCH_MSM7X00A || ARCH_MSM7X30 || ARCH_QSD8X50) |
| 140 | help | 140 | help |
| 141 | Say yes here to support the GPIO interface on ARM v6 based | 141 | Say yes here to support the GPIO interface on ARM v6 based |
| 142 | Qualcomm MSM chips. Most of the pins on the MSM can be | 142 | Qualcomm MSM chips. Most of the pins on the MSM can be |
| @@ -253,6 +253,12 @@ config GPIO_GE_FPGA | |||
| 253 | 253 | ||
| 254 | comment "I2C GPIO expanders:" | 254 | comment "I2C GPIO expanders:" |
| 255 | 255 | ||
| 256 | config GPIO_ARIZONA | ||
| 257 | tristate "Wolfson Microelectronics Arizona class devices" | ||
| 258 | depends on MFD_ARIZONA | ||
| 259 | help | ||
| 260 | Support for GPIOs on Wolfson Arizona class devices. | ||
| 261 | |||
| 256 | config GPIO_MAX7300 | 262 | config GPIO_MAX7300 |
| 257 | tristate "Maxim MAX7300 GPIO expander" | 263 | tristate "Maxim MAX7300 GPIO expander" |
| 258 | depends on I2C | 264 | depends on I2C |
| @@ -466,6 +472,18 @@ config GPIO_BT8XX | |||
| 466 | 472 | ||
| 467 | If unsure, say N. | 473 | If unsure, say N. |
| 468 | 474 | ||
| 475 | config GPIO_AMD8111 | ||
| 476 | tristate "AMD 8111 GPIO driver" | ||
| 477 | depends on PCI | ||
| 478 | help | ||
| 479 | The AMD 8111 south bridge contains 32 GPIO pins which can be used. | ||
| 480 | |||
| 481 | Note, that usually system firmware/ACPI handles GPIO pins on their | ||
| 482 | own and users might easily break their systems with uncarefull usage | ||
| 483 | of this driver! | ||
| 484 | |||
| 485 | If unsure, say N | ||
| 486 | |||
| 469 | config GPIO_LANGWELL | 487 | config GPIO_LANGWELL |
| 470 | bool "Intel Langwell/Penwell GPIO support" | 488 | bool "Intel Langwell/Penwell GPIO support" |
| 471 | depends on PCI && X86 | 489 | depends on PCI && X86 |
| @@ -579,6 +597,13 @@ config GPIO_AB8500 | |||
| 579 | help | 597 | help |
| 580 | Select this to enable the AB8500 IC GPIO driver | 598 | Select this to enable the AB8500 IC GPIO driver |
| 581 | 599 | ||
| 600 | config GPIO_TPS6586X | ||
| 601 | bool "TPS6586X GPIO" | ||
| 602 | depends on MFD_TPS6586X | ||
| 603 | help | ||
| 604 | Select this option to enable GPIO driver for the TPS6586X | ||
| 605 | chip family. | ||
| 606 | |||
| 582 | config GPIO_TPS65910 | 607 | config GPIO_TPS65910 |
| 583 | bool "TPS65910 GPIO" | 608 | bool "TPS65910 GPIO" |
| 584 | depends on MFD_TPS65910 | 609 | depends on MFD_TPS65910 |
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile index 0f55662002c3..153caceeb053 100644 --- a/drivers/gpio/Makefile +++ b/drivers/gpio/Makefile | |||
| @@ -12,6 +12,8 @@ obj-$(CONFIG_GPIO_74X164) += gpio-74x164.o | |||
| 12 | obj-$(CONFIG_GPIO_AB8500) += gpio-ab8500.o | 12 | obj-$(CONFIG_GPIO_AB8500) += gpio-ab8500.o |
| 13 | obj-$(CONFIG_GPIO_ADP5520) += gpio-adp5520.o | 13 | obj-$(CONFIG_GPIO_ADP5520) += gpio-adp5520.o |
| 14 | obj-$(CONFIG_GPIO_ADP5588) += gpio-adp5588.o | 14 | obj-$(CONFIG_GPIO_ADP5588) += gpio-adp5588.o |
| 15 | obj-$(CONFIG_GPIO_AMD8111) += gpio-amd8111.o | ||
| 16 | obj-$(CONFIG_GPIO_ARIZONA) += gpio-arizona.o | ||
| 15 | obj-$(CONFIG_GPIO_BT8XX) += gpio-bt8xx.o | 17 | obj-$(CONFIG_GPIO_BT8XX) += gpio-bt8xx.o |
| 16 | obj-$(CONFIG_GPIO_CS5535) += gpio-cs5535.o | 18 | obj-$(CONFIG_GPIO_CS5535) += gpio-cs5535.o |
| 17 | obj-$(CONFIG_GPIO_DA9052) += gpio-da9052.o | 19 | obj-$(CONFIG_GPIO_DA9052) += gpio-da9052.o |
| @@ -61,6 +63,7 @@ obj-$(CONFIG_GPIO_TC3589X) += gpio-tc3589x.o | |||
| 61 | obj-$(CONFIG_ARCH_TEGRA) += gpio-tegra.o | 63 | obj-$(CONFIG_ARCH_TEGRA) += gpio-tegra.o |
| 62 | obj-$(CONFIG_GPIO_TIMBERDALE) += gpio-timberdale.o | 64 | obj-$(CONFIG_GPIO_TIMBERDALE) += gpio-timberdale.o |
| 63 | obj-$(CONFIG_ARCH_DAVINCI_TNETV107X) += gpio-tnetv107x.o | 65 | obj-$(CONFIG_ARCH_DAVINCI_TNETV107X) += gpio-tnetv107x.o |
| 66 | obj-$(CONFIG_GPIO_TPS6586X) += gpio-tps6586x.o | ||
| 64 | obj-$(CONFIG_GPIO_TPS65910) += gpio-tps65910.o | 67 | obj-$(CONFIG_GPIO_TPS65910) += gpio-tps65910.o |
| 65 | obj-$(CONFIG_GPIO_TPS65912) += gpio-tps65912.o | 68 | obj-$(CONFIG_GPIO_TPS65912) += gpio-tps65912.o |
| 66 | obj-$(CONFIG_GPIO_TWL4030) += gpio-twl4030.o | 69 | obj-$(CONFIG_GPIO_TWL4030) += gpio-twl4030.o |
diff --git a/drivers/gpio/devres.c b/drivers/gpio/devres.c index 9e9947cb86a3..1077754f8289 100644 --- a/drivers/gpio/devres.c +++ b/drivers/gpio/devres.c | |||
| @@ -98,6 +98,7 @@ int devm_gpio_request_one(struct device *dev, unsigned gpio, | |||
| 98 | 98 | ||
| 99 | return 0; | 99 | return 0; |
| 100 | } | 100 | } |
| 101 | EXPORT_SYMBOL(devm_gpio_request_one); | ||
| 101 | 102 | ||
| 102 | /** | 103 | /** |
| 103 | * devm_gpio_free - free an interrupt | 104 | * devm_gpio_free - free an interrupt |
diff --git a/drivers/gpio/gpio-amd8111.c b/drivers/gpio/gpio-amd8111.c new file mode 100644 index 000000000000..710fafcdd1b1 --- /dev/null +++ b/drivers/gpio/gpio-amd8111.c | |||
| @@ -0,0 +1,246 @@ | |||
| 1 | /* | ||
| 2 | * GPIO driver for AMD 8111 south bridges | ||
| 3 | * | ||
| 4 | * Copyright (c) 2012 Dmitry Eremin-Solenikov | ||
| 5 | * | ||
| 6 | * Based on the AMD RNG driver: | ||
| 7 | * Copyright 2005 (c) MontaVista Software, Inc. | ||
| 8 | * with the majority of the code coming from: | ||
| 9 | * | ||
| 10 | * Hardware driver for the Intel/AMD/VIA Random Number Generators (RNG) | ||
| 11 | * (c) Copyright 2003 Red Hat Inc <jgarzik@redhat.com> | ||
| 12 | * | ||
| 13 | * derived from | ||
| 14 | * | ||
| 15 | * Hardware driver for the AMD 768 Random Number Generator (RNG) | ||
| 16 | * (c) Copyright 2001 Red Hat Inc | ||
| 17 | * | ||
| 18 | * derived from | ||
| 19 | * | ||
| 20 | * Hardware driver for Intel i810 Random Number Generator (RNG) | ||
| 21 | * Copyright 2000,2001 Jeff Garzik <jgarzik@pobox.com> | ||
| 22 | * Copyright 2000,2001 Philipp Rumpf <prumpf@mandrakesoft.com> | ||
| 23 | * | ||
| 24 | * This file is licensed under the terms of the GNU General Public | ||
| 25 | * License version 2. This program is licensed "as is" without any | ||
| 26 | * warranty of any kind, whether express or implied. | ||
| 27 | */ | ||
| 28 | #include <linux/module.h> | ||
| 29 | #include <linux/kernel.h> | ||
| 30 | #include <linux/gpio.h> | ||
| 31 | #include <linux/pci.h> | ||
| 32 | #include <linux/spinlock.h> | ||
| 33 | |||
| 34 | #define PMBASE_OFFSET 0xb0 | ||
| 35 | #define PMBASE_SIZE 0x30 | ||
| 36 | |||
| 37 | #define AMD_REG_GPIO(i) (0x10 + (i)) | ||
| 38 | |||
| 39 | #define AMD_GPIO_LTCH_STS 0x40 /* Latch status, w1 */ | ||
| 40 | #define AMD_GPIO_RTIN 0x20 /* Real Time in, ro */ | ||
| 41 | #define AMD_GPIO_DEBOUNCE 0x10 /* Debounce, rw */ | ||
| 42 | #define AMD_GPIO_MODE_MASK 0x0c /* Pin Mode Select, rw */ | ||
| 43 | #define AMD_GPIO_MODE_IN 0x00 | ||
| 44 | #define AMD_GPIO_MODE_OUT 0x04 | ||
| 45 | /* Enable alternative (e.g. clkout, IRQ, etc) function of the pin */ | ||
| 46 | #define AMD_GPIO_MODE_ALTFN 0x08 /* Or 0x09 */ | ||
| 47 | #define AMD_GPIO_X_MASK 0x03 /* In/Out specific, rw */ | ||
| 48 | #define AMD_GPIO_X_IN_ACTIVEHI 0x01 /* Active High */ | ||
| 49 | #define AMD_GPIO_X_IN_LATCH 0x02 /* Latched version is selected */ | ||
| 50 | #define AMD_GPIO_X_OUT_LOW 0x00 | ||
| 51 | #define AMD_GPIO_X_OUT_HI 0x01 | ||
| 52 | #define AMD_GPIO_X_OUT_CLK0 0x02 | ||
| 53 | #define AMD_GPIO_X_OUT_CLK1 0x03 | ||
| 54 | |||
| 55 | /* | ||
| 56 | * Data for PCI driver interface | ||
| 57 | * | ||
| 58 | * This data only exists for exporting the supported | ||
| 59 | * PCI ids via MODULE_DEVICE_TABLE. We do not actually | ||
| 60 | * register a pci_driver, because someone else might one day | ||
| 61 | * want to register another driver on the same PCI id. | ||
| 62 | */ | ||
| 63 | static DEFINE_PCI_DEVICE_TABLE(pci_tbl) = { | ||
| 64 | { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8111_SMBUS), 0 }, | ||
| 65 | { 0, }, /* terminate list */ | ||
| 66 | }; | ||
| 67 | MODULE_DEVICE_TABLE(pci, pci_tbl); | ||
| 68 | |||
| 69 | struct amd_gpio { | ||
| 70 | struct gpio_chip chip; | ||
| 71 | u32 pmbase; | ||
| 72 | void __iomem *pm; | ||
| 73 | struct pci_dev *pdev; | ||
| 74 | spinlock_t lock; /* guards hw registers and orig table */ | ||
| 75 | u8 orig[32]; | ||
| 76 | }; | ||
| 77 | |||
| 78 | #define to_agp(chip) container_of(chip, struct amd_gpio, chip) | ||
| 79 | |||
| 80 | static int amd_gpio_request(struct gpio_chip *chip, unsigned offset) | ||
| 81 | { | ||
| 82 | struct amd_gpio *agp = to_agp(chip); | ||
| 83 | |||
| 84 | agp->orig[offset] = ioread8(agp->pm + AMD_REG_GPIO(offset)) & | ||
| 85 | (AMD_GPIO_DEBOUNCE | AMD_GPIO_MODE_MASK | AMD_GPIO_X_MASK); | ||
| 86 | |||
| 87 | dev_dbg(&agp->pdev->dev, "Requested gpio %d, data %x\n", offset, agp->orig[offset]); | ||
| 88 | |||
| 89 | return 0; | ||
| 90 | } | ||
| 91 | |||
| 92 | static void amd_gpio_free(struct gpio_chip *chip, unsigned offset) | ||
| 93 | { | ||
| 94 | struct amd_gpio *agp = to_agp(chip); | ||
| 95 | |||
| 96 | dev_dbg(&agp->pdev->dev, "Freed gpio %d, data %x\n", offset, agp->orig[offset]); | ||
| 97 | |||
| 98 | iowrite8(agp->orig[offset], agp->pm + AMD_REG_GPIO(offset)); | ||
| 99 | } | ||
| 100 | |||
| 101 | static void amd_gpio_set(struct gpio_chip *chip, unsigned offset, int value) | ||
| 102 | { | ||
| 103 | struct amd_gpio *agp = to_agp(chip); | ||
| 104 | u8 temp; | ||
| 105 | unsigned long flags; | ||
| 106 | |||
| 107 | spin_lock_irqsave(&agp->lock, flags); | ||
| 108 | temp = ioread8(agp->pm + AMD_REG_GPIO(offset)); | ||
| 109 | temp = (temp & AMD_GPIO_DEBOUNCE) | AMD_GPIO_MODE_OUT | (value ? AMD_GPIO_X_OUT_HI : AMD_GPIO_X_OUT_LOW); | ||
| 110 | iowrite8(temp, agp->pm + AMD_REG_GPIO(offset)); | ||
| 111 | spin_unlock_irqrestore(&agp->lock, flags); | ||
| 112 | |||
| 113 | dev_dbg(&agp->pdev->dev, "Setting gpio %d, value %d, reg=%02x\n", offset, !!value, temp); | ||
| 114 | } | ||
| 115 | |||
| 116 | static int amd_gpio_get(struct gpio_chip *chip, unsigned offset) | ||
| 117 | { | ||
| 118 | struct amd_gpio *agp = to_agp(chip); | ||
| 119 | u8 temp; | ||
| 120 | |||
| 121 | temp = ioread8(agp->pm + AMD_REG_GPIO(offset)); | ||
| 122 | |||
| 123 | dev_dbg(&agp->pdev->dev, "Getting gpio %d, reg=%02x\n", offset, temp); | ||
| 124 | |||
| 125 | return (temp & AMD_GPIO_RTIN) ? 1 : 0; | ||
| 126 | } | ||
| 127 | |||
| 128 | static int amd_gpio_dirout(struct gpio_chip *chip, unsigned offset, int value) | ||
| 129 | { | ||
| 130 | struct amd_gpio *agp = to_agp(chip); | ||
| 131 | u8 temp; | ||
| 132 | unsigned long flags; | ||
| 133 | |||
| 134 | spin_lock_irqsave(&agp->lock, flags); | ||
| 135 | temp = ioread8(agp->pm + AMD_REG_GPIO(offset)); | ||
| 136 | temp = (temp & AMD_GPIO_DEBOUNCE) | AMD_GPIO_MODE_OUT | (value ? AMD_GPIO_X_OUT_HI : AMD_GPIO_X_OUT_LOW); | ||
| 137 | iowrite8(temp, agp->pm + AMD_REG_GPIO(offset)); | ||
| 138 | spin_unlock_irqrestore(&agp->lock, flags); | ||
| 139 | |||
| 140 | dev_dbg(&agp->pdev->dev, "Dirout gpio %d, value %d, reg=%02x\n", offset, !!value, temp); | ||
| 141 | |||
| 142 | return 0; | ||
| 143 | } | ||
| 144 | |||
| 145 | static int amd_gpio_dirin(struct gpio_chip *chip, unsigned offset) | ||
| 146 | { | ||
| 147 | struct amd_gpio *agp = to_agp(chip); | ||
| 148 | u8 temp; | ||
| 149 | unsigned long flags; | ||
| 150 | |||
| 151 | spin_lock_irqsave(&agp->lock, flags); | ||
| 152 | temp = ioread8(agp->pm + AMD_REG_GPIO(offset)); | ||
| 153 | temp = (temp & AMD_GPIO_DEBOUNCE) | AMD_GPIO_MODE_IN; | ||
| 154 | iowrite8(temp, agp->pm + AMD_REG_GPIO(offset)); | ||
| 155 | spin_unlock_irqrestore(&agp->lock, flags); | ||
| 156 | |||
| 157 | dev_dbg(&agp->pdev->dev, "Dirin gpio %d, reg=%02x\n", offset, temp); | ||
| 158 | |||
| 159 | return 0; | ||
| 160 | } | ||
| 161 | |||
| 162 | static struct amd_gpio gp = { | ||
| 163 | .chip = { | ||
| 164 | .label = "AMD GPIO", | ||
| 165 | .owner = THIS_MODULE, | ||
| 166 | .base = -1, | ||
| 167 | .ngpio = 32, | ||
| 168 | .request = amd_gpio_request, | ||
| 169 | .free = amd_gpio_free, | ||
| 170 | .set = amd_gpio_set, | ||
| 171 | .get = amd_gpio_get, | ||
| 172 | .direction_output = amd_gpio_dirout, | ||
| 173 | .direction_input = amd_gpio_dirin, | ||
| 174 | }, | ||
| 175 | }; | ||
| 176 | |||
| 177 | static int __init amd_gpio_init(void) | ||
| 178 | { | ||
| 179 | int err = -ENODEV; | ||
| 180 | struct pci_dev *pdev = NULL; | ||
| 181 | const struct pci_device_id *ent; | ||
| 182 | |||
| 183 | |||
| 184 | /* We look for our device - AMD South Bridge | ||
| 185 | * I don't know about a system with two such bridges, | ||
| 186 | * so we can assume that there is max. one device. | ||
| 187 | * | ||
| 188 | * We can't use plain pci_driver mechanism, | ||
| 189 | * as the device is really a multiple function device, | ||
| 190 | * main driver that binds to the pci_device is an smbus | ||
| 191 | * driver and have to find & bind to the device this way. | ||
| 192 | */ | ||
| 193 | for_each_pci_dev(pdev) { | ||
| 194 | ent = pci_match_id(pci_tbl, pdev); | ||
| 195 | if (ent) | ||
| 196 | goto found; | ||
| 197 | } | ||
| 198 | /* Device not found. */ | ||
| 199 | goto out; | ||
| 200 | |||
| 201 | found: | ||
| 202 | err = pci_read_config_dword(pdev, 0x58, &gp.pmbase); | ||
| 203 | if (err) | ||
| 204 | goto out; | ||
| 205 | err = -EIO; | ||
| 206 | gp.pmbase &= 0x0000FF00; | ||
| 207 | if (gp.pmbase == 0) | ||
| 208 | goto out; | ||
| 209 | if (!request_region(gp.pmbase + PMBASE_OFFSET, PMBASE_SIZE, "AMD GPIO")) { | ||
| 210 | dev_err(&pdev->dev, "AMD GPIO region 0x%x already in use!\n", | ||
| 211 | gp.pmbase + PMBASE_OFFSET); | ||
| 212 | err = -EBUSY; | ||
| 213 | goto out; | ||
| 214 | } | ||
| 215 | gp.pm = ioport_map(gp.pmbase + PMBASE_OFFSET, PMBASE_SIZE); | ||
| 216 | gp.pdev = pdev; | ||
| 217 | gp.chip.dev = &pdev->dev; | ||
| 218 | |||
| 219 | spin_lock_init(&gp.lock); | ||
| 220 | |||
| 221 | printk(KERN_INFO "AMD-8111 GPIO detected\n"); | ||
| 222 | err = gpiochip_add(&gp.chip); | ||
| 223 | if (err) { | ||
| 224 | printk(KERN_ERR "GPIO registering failed (%d)\n", | ||
| 225 | err); | ||
| 226 | release_region(gp.pmbase + PMBASE_OFFSET, PMBASE_SIZE); | ||
| 227 | goto out; | ||
| 228 | } | ||
| 229 | out: | ||
| 230 | return err; | ||
| 231 | } | ||
| 232 | |||
| 233 | static void __exit amd_gpio_exit(void) | ||
| 234 | { | ||
| 235 | int err = gpiochip_remove(&gp.chip); | ||
| 236 | WARN_ON(err); | ||
| 237 | ioport_unmap(gp.pm); | ||
| 238 | release_region(gp.pmbase + PMBASE_OFFSET, PMBASE_SIZE); | ||
| 239 | } | ||
| 240 | |||
| 241 | module_init(amd_gpio_init); | ||
| 242 | module_exit(amd_gpio_exit); | ||
| 243 | |||
| 244 | MODULE_AUTHOR("The Linux Kernel team"); | ||
| 245 | MODULE_DESCRIPTION("GPIO driver for AMD chipsets"); | ||
| 246 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/gpio/gpio-arizona.c b/drivers/gpio/gpio-arizona.c new file mode 100644 index 000000000000..8740d2eb06f8 --- /dev/null +++ b/drivers/gpio/gpio-arizona.c | |||
| @@ -0,0 +1,163 @@ | |||
| 1 | /* | ||
| 2 | * gpiolib support for Wolfson Arizona class devices | ||
| 3 | * | ||
| 4 | * Copyright 2012 Wolfson Microelectronics PLC. | ||
| 5 | * | ||
| 6 | * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> | ||
| 7 | * | ||
| 8 | * This program is free software; you can redistribute it and/or modify it | ||
| 9 | * under the terms of the GNU General Public License as published by the | ||
| 10 | * Free Software Foundation; either version 2 of the License, or (at your | ||
| 11 | * option) any later version. | ||
| 12 | * | ||
| 13 | */ | ||
| 14 | |||
| 15 | #include <linux/kernel.h> | ||
| 16 | #include <linux/slab.h> | ||
| 17 | #include <linux/module.h> | ||
| 18 | #include <linux/gpio.h> | ||
| 19 | #include <linux/platform_device.h> | ||
| 20 | #include <linux/seq_file.h> | ||
| 21 | |||
| 22 | #include <linux/mfd/arizona/core.h> | ||
| 23 | #include <linux/mfd/arizona/pdata.h> | ||
| 24 | #include <linux/mfd/arizona/registers.h> | ||
| 25 | |||
| 26 | struct arizona_gpio { | ||
| 27 | struct arizona *arizona; | ||
| 28 | struct gpio_chip gpio_chip; | ||
| 29 | }; | ||
| 30 | |||
| 31 | static inline struct arizona_gpio *to_arizona_gpio(struct gpio_chip *chip) | ||
| 32 | { | ||
| 33 | return container_of(chip, struct arizona_gpio, gpio_chip); | ||
| 34 | } | ||
| 35 | |||
| 36 | static int arizona_gpio_direction_in(struct gpio_chip *chip, unsigned offset) | ||
| 37 | { | ||
| 38 | struct arizona_gpio *arizona_gpio = to_arizona_gpio(chip); | ||
| 39 | struct arizona *arizona = arizona_gpio->arizona; | ||
| 40 | |||
| 41 | return regmap_update_bits(arizona->regmap, ARIZONA_GPIO1_CTRL + offset, | ||
| 42 | ARIZONA_GPN_DIR, ARIZONA_GPN_DIR); | ||
| 43 | } | ||
| 44 | |||
| 45 | static int arizona_gpio_get(struct gpio_chip *chip, unsigned offset) | ||
| 46 | { | ||
| 47 | struct arizona_gpio *arizona_gpio = to_arizona_gpio(chip); | ||
| 48 | struct arizona *arizona = arizona_gpio->arizona; | ||
| 49 | unsigned int val; | ||
| 50 | int ret; | ||
| 51 | |||
| 52 | ret = regmap_read(arizona->regmap, ARIZONA_GPIO1_CTRL + offset, &val); | ||
| 53 | if (ret < 0) | ||
| 54 | return ret; | ||
| 55 | |||
| 56 | if (val & ARIZONA_GPN_LVL) | ||
| 57 | return 1; | ||
| 58 | else | ||
| 59 | return 0; | ||
| 60 | } | ||
| 61 | |||
| 62 | static int arizona_gpio_direction_out(struct gpio_chip *chip, | ||
| 63 | unsigned offset, int value) | ||
| 64 | { | ||
| 65 | struct arizona_gpio *arizona_gpio = to_arizona_gpio(chip); | ||
| 66 | struct arizona *arizona = arizona_gpio->arizona; | ||
| 67 | |||
| 68 | if (value) | ||
| 69 | value = ARIZONA_GPN_LVL; | ||
| 70 | |||
| 71 | return regmap_update_bits(arizona->regmap, ARIZONA_GPIO1_CTRL + offset, | ||
| 72 | ARIZONA_GPN_DIR | ARIZONA_GPN_LVL, value); | ||
| 73 | } | ||
| 74 | |||
| 75 | static void arizona_gpio_set(struct gpio_chip *chip, unsigned offset, int value) | ||
| 76 | { | ||
| 77 | struct arizona_gpio *arizona_gpio = to_arizona_gpio(chip); | ||
| 78 | struct arizona *arizona = arizona_gpio->arizona; | ||
| 79 | |||
| 80 | if (value) | ||
| 81 | value = ARIZONA_GPN_LVL; | ||
| 82 | |||
| 83 | regmap_update_bits(arizona->regmap, ARIZONA_GPIO1_CTRL + offset, | ||
| 84 | ARIZONA_GPN_LVL, value); | ||
| 85 | } | ||
| 86 | |||
| 87 | static struct gpio_chip template_chip = { | ||
| 88 | .label = "arizona", | ||
| 89 | .owner = THIS_MODULE, | ||
| 90 | .direction_input = arizona_gpio_direction_in, | ||
| 91 | .get = arizona_gpio_get, | ||
| 92 | .direction_output = arizona_gpio_direction_out, | ||
| 93 | .set = arizona_gpio_set, | ||
| 94 | .can_sleep = 1, | ||
| 95 | }; | ||
| 96 | |||
| 97 | static int __devinit arizona_gpio_probe(struct platform_device *pdev) | ||
| 98 | { | ||
| 99 | struct arizona *arizona = dev_get_drvdata(pdev->dev.parent); | ||
| 100 | struct arizona_pdata *pdata = arizona->dev->platform_data; | ||
| 101 | struct arizona_gpio *arizona_gpio; | ||
| 102 | int ret; | ||
| 103 | |||
| 104 | arizona_gpio = devm_kzalloc(&pdev->dev, sizeof(*arizona_gpio), | ||
| 105 | GFP_KERNEL); | ||
| 106 | if (arizona_gpio == NULL) | ||
| 107 | return -ENOMEM; | ||
| 108 | |||
| 109 | arizona_gpio->arizona = arizona; | ||
| 110 | arizona_gpio->gpio_chip = template_chip; | ||
| 111 | arizona_gpio->gpio_chip.dev = &pdev->dev; | ||
| 112 | |||
| 113 | switch (arizona->type) { | ||
| 114 | case WM5102: | ||
| 115 | case WM5110: | ||
| 116 | arizona_gpio->gpio_chip.ngpio = 5; | ||
| 117 | break; | ||
| 118 | default: | ||
| 119 | dev_err(&pdev->dev, "Unknown chip variant %d\n", | ||
| 120 | arizona->type); | ||
| 121 | return -EINVAL; | ||
| 122 | } | ||
| 123 | |||
| 124 | if (pdata && pdata->gpio_base) | ||
| 125 | arizona_gpio->gpio_chip.base = pdata->gpio_base; | ||
| 126 | else | ||
| 127 | arizona_gpio->gpio_chip.base = -1; | ||
| 128 | |||
| 129 | ret = gpiochip_add(&arizona_gpio->gpio_chip); | ||
| 130 | if (ret < 0) { | ||
| 131 | dev_err(&pdev->dev, "Could not register gpiochip, %d\n", | ||
| 132 | ret); | ||
| 133 | goto err; | ||
| 134 | } | ||
| 135 | |||
| 136 | platform_set_drvdata(pdev, arizona_gpio); | ||
| 137 | |||
| 138 | return ret; | ||
| 139 | |||
| 140 | err: | ||
| 141 | return ret; | ||
| 142 | } | ||
| 143 | |||
| 144 | static int __devexit arizona_gpio_remove(struct platform_device *pdev) | ||
| 145 | { | ||
| 146 | struct arizona_gpio *arizona_gpio = platform_get_drvdata(pdev); | ||
| 147 | |||
| 148 | return gpiochip_remove(&arizona_gpio->gpio_chip); | ||
| 149 | } | ||
| 150 | |||
| 151 | static struct platform_driver arizona_gpio_driver = { | ||
| 152 | .driver.name = "arizona-gpio", | ||
| 153 | .driver.owner = THIS_MODULE, | ||
| 154 | .probe = arizona_gpio_probe, | ||
| 155 | .remove = __devexit_p(arizona_gpio_remove), | ||
| 156 | }; | ||
| 157 | |||
| 158 | module_platform_driver(arizona_gpio_driver); | ||
| 159 | |||
| 160 | MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>"); | ||
| 161 | MODULE_DESCRIPTION("GPIO interface for Arizona devices"); | ||
| 162 | MODULE_LICENSE("GPL"); | ||
| 163 | MODULE_ALIAS("platform:arizona-gpio"); | ||
diff --git a/drivers/gpio/gpio-lpc32xx.c b/drivers/gpio/gpio-lpc32xx.c index c2199beca98a..8a420f13905e 100644 --- a/drivers/gpio/gpio-lpc32xx.c +++ b/drivers/gpio/gpio-lpc32xx.c | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * arch/arm/mach-lpc32xx/gpiolib.c | 2 | * GPIO driver for LPC32xx SoC |
| 3 | * | 3 | * |
| 4 | * Author: Kevin Wells <kevin.wells@nxp.com> | 4 | * Author: Kevin Wells <kevin.wells@nxp.com> |
| 5 | * | 5 | * |
| @@ -28,6 +28,7 @@ | |||
| 28 | #include <mach/hardware.h> | 28 | #include <mach/hardware.h> |
| 29 | #include <mach/platform.h> | 29 | #include <mach/platform.h> |
| 30 | #include <mach/gpio-lpc32xx.h> | 30 | #include <mach/gpio-lpc32xx.h> |
| 31 | #include <mach/irqs.h> | ||
| 31 | 32 | ||
| 32 | #define LPC32XX_GPIO_P3_INP_STATE _GPREG(0x000) | 33 | #define LPC32XX_GPIO_P3_INP_STATE _GPREG(0x000) |
| 33 | #define LPC32XX_GPIO_P3_OUTP_SET _GPREG(0x004) | 34 | #define LPC32XX_GPIO_P3_OUTP_SET _GPREG(0x004) |
| @@ -367,6 +368,66 @@ static int lpc32xx_gpio_request(struct gpio_chip *chip, unsigned pin) | |||
| 367 | return -EINVAL; | 368 | return -EINVAL; |
| 368 | } | 369 | } |
| 369 | 370 | ||
| 371 | static int lpc32xx_gpio_to_irq_p01(struct gpio_chip *chip, unsigned offset) | ||
| 372 | { | ||
| 373 | return IRQ_LPC32XX_P0_P1_IRQ; | ||
| 374 | } | ||
| 375 | |||
| 376 | static const char lpc32xx_gpio_to_irq_gpio_p3_table[] = { | ||
| 377 | IRQ_LPC32XX_GPIO_00, | ||
| 378 | IRQ_LPC32XX_GPIO_01, | ||
| 379 | IRQ_LPC32XX_GPIO_02, | ||
| 380 | IRQ_LPC32XX_GPIO_03, | ||
| 381 | IRQ_LPC32XX_GPIO_04, | ||
| 382 | IRQ_LPC32XX_GPIO_05, | ||
| 383 | }; | ||
| 384 | |||
| 385 | static int lpc32xx_gpio_to_irq_gpio_p3(struct gpio_chip *chip, unsigned offset) | ||
| 386 | { | ||
| 387 | if (offset < ARRAY_SIZE(lpc32xx_gpio_to_irq_gpio_p3_table)) | ||
| 388 | return lpc32xx_gpio_to_irq_gpio_p3_table[offset]; | ||
| 389 | return -ENXIO; | ||
| 390 | } | ||
| 391 | |||
| 392 | static const char lpc32xx_gpio_to_irq_gpi_p3_table[] = { | ||
| 393 | IRQ_LPC32XX_GPI_00, | ||
| 394 | IRQ_LPC32XX_GPI_01, | ||
| 395 | IRQ_LPC32XX_GPI_02, | ||
| 396 | IRQ_LPC32XX_GPI_03, | ||
| 397 | IRQ_LPC32XX_GPI_04, | ||
| 398 | IRQ_LPC32XX_GPI_05, | ||
| 399 | IRQ_LPC32XX_GPI_06, | ||
| 400 | IRQ_LPC32XX_GPI_07, | ||
| 401 | IRQ_LPC32XX_GPI_08, | ||
| 402 | IRQ_LPC32XX_GPI_09, | ||
| 403 | -ENXIO, /* 10 */ | ||
| 404 | -ENXIO, /* 11 */ | ||
| 405 | -ENXIO, /* 12 */ | ||
| 406 | -ENXIO, /* 13 */ | ||
| 407 | -ENXIO, /* 14 */ | ||
| 408 | -ENXIO, /* 15 */ | ||
| 409 | -ENXIO, /* 16 */ | ||
| 410 | -ENXIO, /* 17 */ | ||
| 411 | -ENXIO, /* 18 */ | ||
| 412 | IRQ_LPC32XX_GPI_19, | ||
| 413 | -ENXIO, /* 20 */ | ||
| 414 | -ENXIO, /* 21 */ | ||
| 415 | -ENXIO, /* 22 */ | ||
| 416 | -ENXIO, /* 23 */ | ||
| 417 | -ENXIO, /* 24 */ | ||
| 418 | -ENXIO, /* 25 */ | ||
| 419 | -ENXIO, /* 26 */ | ||
| 420 | -ENXIO, /* 27 */ | ||
| 421 | IRQ_LPC32XX_GPI_28, | ||
| 422 | }; | ||
| 423 | |||
| 424 | static int lpc32xx_gpio_to_irq_gpi_p3(struct gpio_chip *chip, unsigned offset) | ||
| 425 | { | ||
| 426 | if (offset < ARRAY_SIZE(lpc32xx_gpio_to_irq_gpi_p3_table)) | ||
| 427 | return lpc32xx_gpio_to_irq_gpi_p3_table[offset]; | ||
| 428 | return -ENXIO; | ||
| 429 | } | ||
| 430 | |||
| 370 | static struct lpc32xx_gpio_chip lpc32xx_gpiochip[] = { | 431 | static struct lpc32xx_gpio_chip lpc32xx_gpiochip[] = { |
| 371 | { | 432 | { |
| 372 | .chip = { | 433 | .chip = { |
| @@ -376,6 +437,7 @@ static struct lpc32xx_gpio_chip lpc32xx_gpiochip[] = { | |||
| 376 | .direction_output = lpc32xx_gpio_dir_output_p012, | 437 | .direction_output = lpc32xx_gpio_dir_output_p012, |
| 377 | .set = lpc32xx_gpio_set_value_p012, | 438 | .set = lpc32xx_gpio_set_value_p012, |
| 378 | .request = lpc32xx_gpio_request, | 439 | .request = lpc32xx_gpio_request, |
| 440 | .to_irq = lpc32xx_gpio_to_irq_p01, | ||
| 379 | .base = LPC32XX_GPIO_P0_GRP, | 441 | .base = LPC32XX_GPIO_P0_GRP, |
| 380 | .ngpio = LPC32XX_GPIO_P0_MAX, | 442 | .ngpio = LPC32XX_GPIO_P0_MAX, |
| 381 | .names = gpio_p0_names, | 443 | .names = gpio_p0_names, |
| @@ -391,6 +453,7 @@ static struct lpc32xx_gpio_chip lpc32xx_gpiochip[] = { | |||
| 391 | .direction_output = lpc32xx_gpio_dir_output_p012, | 453 | .direction_output = lpc32xx_gpio_dir_output_p012, |
| 392 | .set = lpc32xx_gpio_set_value_p012, | 454 | .set = lpc32xx_gpio_set_value_p012, |
| 393 | .request = lpc32xx_gpio_request, | 455 | .request = lpc32xx_gpio_request, |
| 456 | .to_irq = lpc32xx_gpio_to_irq_p01, | ||
| 394 | .base = LPC32XX_GPIO_P1_GRP, | 457 | .base = LPC32XX_GPIO_P1_GRP, |
| 395 | .ngpio = LPC32XX_GPIO_P1_MAX, | 458 | .ngpio = LPC32XX_GPIO_P1_MAX, |
| 396 | .names = gpio_p1_names, | 459 | .names = gpio_p1_names, |
| @@ -421,6 +484,7 @@ static struct lpc32xx_gpio_chip lpc32xx_gpiochip[] = { | |||
| 421 | .direction_output = lpc32xx_gpio_dir_output_p3, | 484 | .direction_output = lpc32xx_gpio_dir_output_p3, |
| 422 | .set = lpc32xx_gpio_set_value_p3, | 485 | .set = lpc32xx_gpio_set_value_p3, |
| 423 | .request = lpc32xx_gpio_request, | 486 | .request = lpc32xx_gpio_request, |
| 487 | .to_irq = lpc32xx_gpio_to_irq_gpio_p3, | ||
| 424 | .base = LPC32XX_GPIO_P3_GRP, | 488 | .base = LPC32XX_GPIO_P3_GRP, |
| 425 | .ngpio = LPC32XX_GPIO_P3_MAX, | 489 | .ngpio = LPC32XX_GPIO_P3_MAX, |
| 426 | .names = gpio_p3_names, | 490 | .names = gpio_p3_names, |
| @@ -434,6 +498,7 @@ static struct lpc32xx_gpio_chip lpc32xx_gpiochip[] = { | |||
| 434 | .direction_input = lpc32xx_gpio_dir_in_always, | 498 | .direction_input = lpc32xx_gpio_dir_in_always, |
| 435 | .get = lpc32xx_gpi_get_value, | 499 | .get = lpc32xx_gpi_get_value, |
| 436 | .request = lpc32xx_gpio_request, | 500 | .request = lpc32xx_gpio_request, |
| 501 | .to_irq = lpc32xx_gpio_to_irq_gpi_p3, | ||
| 437 | .base = LPC32XX_GPI_P3_GRP, | 502 | .base = LPC32XX_GPI_P3_GRP, |
| 438 | .ngpio = LPC32XX_GPI_P3_MAX, | 503 | .ngpio = LPC32XX_GPI_P3_MAX, |
| 439 | .names = gpi_p3_names, | 504 | .names = gpi_p3_names, |
| @@ -457,13 +522,6 @@ static struct lpc32xx_gpio_chip lpc32xx_gpiochip[] = { | |||
| 457 | }, | 522 | }, |
| 458 | }; | 523 | }; |
| 459 | 524 | ||
| 460 | /* Empty now, can be removed later when mach-lpc32xx is finally switched over | ||
| 461 | * to DT support | ||
| 462 | */ | ||
| 463 | void __init lpc32xx_gpio_init(void) | ||
| 464 | { | ||
| 465 | } | ||
| 466 | |||
| 467 | static int lpc32xx_of_xlate(struct gpio_chip *gc, | 525 | static int lpc32xx_of_xlate(struct gpio_chip *gc, |
| 468 | const struct of_phandle_args *gpiospec, u32 *flags) | 526 | const struct of_phandle_args *gpiospec, u32 *flags) |
| 469 | { | 527 | { |
diff --git a/drivers/gpio/gpio-mxc.c b/drivers/gpio/gpio-mxc.c index c337143b18f8..4db460b6ecf7 100644 --- a/drivers/gpio/gpio-mxc.c +++ b/drivers/gpio/gpio-mxc.c | |||
| @@ -23,6 +23,7 @@ | |||
| 23 | #include <linux/interrupt.h> | 23 | #include <linux/interrupt.h> |
| 24 | #include <linux/io.h> | 24 | #include <linux/io.h> |
| 25 | #include <linux/irq.h> | 25 | #include <linux/irq.h> |
| 26 | #include <linux/irqdomain.h> | ||
| 26 | #include <linux/gpio.h> | 27 | #include <linux/gpio.h> |
| 27 | #include <linux/platform_device.h> | 28 | #include <linux/platform_device.h> |
| 28 | #include <linux/slab.h> | 29 | #include <linux/slab.h> |
| @@ -33,12 +34,11 @@ | |||
| 33 | #include <asm-generic/bug.h> | 34 | #include <asm-generic/bug.h> |
| 34 | #include <asm/mach/irq.h> | 35 | #include <asm/mach/irq.h> |
| 35 | 36 | ||
| 36 | #define irq_to_gpio(irq) ((irq) - MXC_GPIO_IRQ_START) | ||
| 37 | |||
| 38 | enum mxc_gpio_hwtype { | 37 | enum mxc_gpio_hwtype { |
| 39 | IMX1_GPIO, /* runs on i.mx1 */ | 38 | IMX1_GPIO, /* runs on i.mx1 */ |
| 40 | IMX21_GPIO, /* runs on i.mx21 and i.mx27 */ | 39 | IMX21_GPIO, /* runs on i.mx21 and i.mx27 */ |
| 41 | IMX31_GPIO, /* runs on all other i.mx */ | 40 | IMX31_GPIO, /* runs on i.mx31 */ |
| 41 | IMX35_GPIO, /* runs on all other i.mx */ | ||
| 42 | }; | 42 | }; |
| 43 | 43 | ||
| 44 | /* device type dependent stuff */ | 44 | /* device type dependent stuff */ |
| @@ -50,6 +50,7 @@ struct mxc_gpio_hwdata { | |||
| 50 | unsigned icr2_reg; | 50 | unsigned icr2_reg; |
| 51 | unsigned imr_reg; | 51 | unsigned imr_reg; |
| 52 | unsigned isr_reg; | 52 | unsigned isr_reg; |
| 53 | int edge_sel_reg; | ||
| 53 | unsigned low_level; | 54 | unsigned low_level; |
| 54 | unsigned high_level; | 55 | unsigned high_level; |
| 55 | unsigned rise_edge; | 56 | unsigned rise_edge; |
| @@ -61,7 +62,7 @@ struct mxc_gpio_port { | |||
| 61 | void __iomem *base; | 62 | void __iomem *base; |
| 62 | int irq; | 63 | int irq; |
| 63 | int irq_high; | 64 | int irq_high; |
| 64 | int virtual_irq_start; | 65 | struct irq_domain *domain; |
| 65 | struct bgpio_chip bgc; | 66 | struct bgpio_chip bgc; |
| 66 | u32 both_edges; | 67 | u32 both_edges; |
| 67 | }; | 68 | }; |
| @@ -74,6 +75,7 @@ static struct mxc_gpio_hwdata imx1_imx21_gpio_hwdata = { | |||
| 74 | .icr2_reg = 0x2c, | 75 | .icr2_reg = 0x2c, |
| 75 | .imr_reg = 0x30, | 76 | .imr_reg = 0x30, |
| 76 | .isr_reg = 0x34, | 77 | .isr_reg = 0x34, |
| 78 | .edge_sel_reg = -EINVAL, | ||
| 77 | .low_level = 0x03, | 79 | .low_level = 0x03, |
| 78 | .high_level = 0x02, | 80 | .high_level = 0x02, |
| 79 | .rise_edge = 0x00, | 81 | .rise_edge = 0x00, |
| @@ -88,6 +90,22 @@ static struct mxc_gpio_hwdata imx31_gpio_hwdata = { | |||
| 88 | .icr2_reg = 0x10, | 90 | .icr2_reg = 0x10, |
| 89 | .imr_reg = 0x14, | 91 | .imr_reg = 0x14, |
| 90 | .isr_reg = 0x18, | 92 | .isr_reg = 0x18, |
| 93 | .edge_sel_reg = -EINVAL, | ||
| 94 | .low_level = 0x00, | ||
| 95 | .high_level = 0x01, | ||
| 96 | .rise_edge = 0x02, | ||
| 97 | .fall_edge = 0x03, | ||
| 98 | }; | ||
| 99 | |||
| 100 | static struct mxc_gpio_hwdata imx35_gpio_hwdata = { | ||
| 101 | .dr_reg = 0x00, | ||
| 102 | .gdir_reg = 0x04, | ||
| 103 | .psr_reg = 0x08, | ||
| 104 | .icr1_reg = 0x0c, | ||
| 105 | .icr2_reg = 0x10, | ||
| 106 | .imr_reg = 0x14, | ||
| 107 | .isr_reg = 0x18, | ||
| 108 | .edge_sel_reg = 0x1c, | ||
| 91 | .low_level = 0x00, | 109 | .low_level = 0x00, |
| 92 | .high_level = 0x01, | 110 | .high_level = 0x01, |
| 93 | .rise_edge = 0x02, | 111 | .rise_edge = 0x02, |
| @@ -104,12 +122,13 @@ static struct mxc_gpio_hwdata *mxc_gpio_hwdata; | |||
| 104 | #define GPIO_ICR2 (mxc_gpio_hwdata->icr2_reg) | 122 | #define GPIO_ICR2 (mxc_gpio_hwdata->icr2_reg) |
| 105 | #define GPIO_IMR (mxc_gpio_hwdata->imr_reg) | 123 | #define GPIO_IMR (mxc_gpio_hwdata->imr_reg) |
| 106 | #define GPIO_ISR (mxc_gpio_hwdata->isr_reg) | 124 | #define GPIO_ISR (mxc_gpio_hwdata->isr_reg) |
| 125 | #define GPIO_EDGE_SEL (mxc_gpio_hwdata->edge_sel_reg) | ||
| 107 | 126 | ||
| 108 | #define GPIO_INT_LOW_LEV (mxc_gpio_hwdata->low_level) | 127 | #define GPIO_INT_LOW_LEV (mxc_gpio_hwdata->low_level) |
| 109 | #define GPIO_INT_HIGH_LEV (mxc_gpio_hwdata->high_level) | 128 | #define GPIO_INT_HIGH_LEV (mxc_gpio_hwdata->high_level) |
| 110 | #define GPIO_INT_RISE_EDGE (mxc_gpio_hwdata->rise_edge) | 129 | #define GPIO_INT_RISE_EDGE (mxc_gpio_hwdata->rise_edge) |
| 111 | #define GPIO_INT_FALL_EDGE (mxc_gpio_hwdata->fall_edge) | 130 | #define GPIO_INT_FALL_EDGE (mxc_gpio_hwdata->fall_edge) |
| 112 | #define GPIO_INT_NONE 0x4 | 131 | #define GPIO_INT_BOTH_EDGES 0x4 |
| 113 | 132 | ||
| 114 | static struct platform_device_id mxc_gpio_devtype[] = { | 133 | static struct platform_device_id mxc_gpio_devtype[] = { |
| 115 | { | 134 | { |
| @@ -122,6 +141,9 @@ static struct platform_device_id mxc_gpio_devtype[] = { | |||
| 122 | .name = "imx31-gpio", | 141 | .name = "imx31-gpio", |
| 123 | .driver_data = IMX31_GPIO, | 142 | .driver_data = IMX31_GPIO, |
| 124 | }, { | 143 | }, { |
| 144 | .name = "imx35-gpio", | ||
| 145 | .driver_data = IMX35_GPIO, | ||
| 146 | }, { | ||
| 125 | /* sentinel */ | 147 | /* sentinel */ |
| 126 | } | 148 | } |
| 127 | }; | 149 | }; |
| @@ -130,6 +152,7 @@ static const struct of_device_id mxc_gpio_dt_ids[] = { | |||
| 130 | { .compatible = "fsl,imx1-gpio", .data = &mxc_gpio_devtype[IMX1_GPIO], }, | 152 | { .compatible = "fsl,imx1-gpio", .data = &mxc_gpio_devtype[IMX1_GPIO], }, |
| 131 | { .compatible = "fsl,imx21-gpio", .data = &mxc_gpio_devtype[IMX21_GPIO], }, | 153 | { .compatible = "fsl,imx21-gpio", .data = &mxc_gpio_devtype[IMX21_GPIO], }, |
| 132 | { .compatible = "fsl,imx31-gpio", .data = &mxc_gpio_devtype[IMX31_GPIO], }, | 154 | { .compatible = "fsl,imx31-gpio", .data = &mxc_gpio_devtype[IMX31_GPIO], }, |
| 155 | { .compatible = "fsl,imx35-gpio", .data = &mxc_gpio_devtype[IMX35_GPIO], }, | ||
| 133 | { /* sentinel */ } | 156 | { /* sentinel */ } |
| 134 | }; | 157 | }; |
| 135 | 158 | ||
| @@ -144,14 +167,15 @@ static LIST_HEAD(mxc_gpio_ports); | |||
| 144 | 167 | ||
| 145 | static int gpio_set_irq_type(struct irq_data *d, u32 type) | 168 | static int gpio_set_irq_type(struct irq_data *d, u32 type) |
| 146 | { | 169 | { |
| 147 | u32 gpio = irq_to_gpio(d->irq); | ||
| 148 | struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); | 170 | struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); |
| 149 | struct mxc_gpio_port *port = gc->private; | 171 | struct mxc_gpio_port *port = gc->private; |
| 150 | u32 bit, val; | 172 | u32 bit, val; |
| 173 | u32 gpio_idx = d->hwirq; | ||
| 174 | u32 gpio = port->bgc.gc.base + gpio_idx; | ||
| 151 | int edge; | 175 | int edge; |
| 152 | void __iomem *reg = port->base; | 176 | void __iomem *reg = port->base; |
| 153 | 177 | ||
| 154 | port->both_edges &= ~(1 << (gpio & 31)); | 178 | port->both_edges &= ~(1 << gpio_idx); |
| 155 | switch (type) { | 179 | switch (type) { |
| 156 | case IRQ_TYPE_EDGE_RISING: | 180 | case IRQ_TYPE_EDGE_RISING: |
| 157 | edge = GPIO_INT_RISE_EDGE; | 181 | edge = GPIO_INT_RISE_EDGE; |
| @@ -160,15 +184,19 @@ static int gpio_set_irq_type(struct irq_data *d, u32 type) | |||
| 160 | edge = GPIO_INT_FALL_EDGE; | 184 | edge = GPIO_INT_FALL_EDGE; |
| 161 | break; | 185 | break; |
| 162 | case IRQ_TYPE_EDGE_BOTH: | 186 | case IRQ_TYPE_EDGE_BOTH: |
| 163 | val = gpio_get_value(gpio); | 187 | if (GPIO_EDGE_SEL >= 0) { |
| 164 | if (val) { | 188 | edge = GPIO_INT_BOTH_EDGES; |
| 165 | edge = GPIO_INT_LOW_LEV; | ||
| 166 | pr_debug("mxc: set GPIO %d to low trigger\n", gpio); | ||
| 167 | } else { | 189 | } else { |
| 168 | edge = GPIO_INT_HIGH_LEV; | 190 | val = gpio_get_value(gpio); |
| 169 | pr_debug("mxc: set GPIO %d to high trigger\n", gpio); | 191 | if (val) { |
| 192 | edge = GPIO_INT_LOW_LEV; | ||
| 193 | pr_debug("mxc: set GPIO %d to low trigger\n", gpio); | ||
| 194 | } else { | ||
| 195 | edge = GPIO_INT_HIGH_LEV; | ||
| 196 | pr_debug("mxc: set GPIO %d to high trigger\n", gpio); | ||
| 197 | } | ||
| 198 | port->both_edges |= 1 << gpio_idx; | ||
| 170 | } | 199 | } |
| 171 | port->both_edges |= 1 << (gpio & 31); | ||
| 172 | break; | 200 | break; |
| 173 | case IRQ_TYPE_LEVEL_LOW: | 201 | case IRQ_TYPE_LEVEL_LOW: |
| 174 | edge = GPIO_INT_LOW_LEV; | 202 | edge = GPIO_INT_LOW_LEV; |
| @@ -180,11 +208,24 @@ static int gpio_set_irq_type(struct irq_data *d, u32 type) | |||
| 180 | return -EINVAL; | 208 | return -EINVAL; |
| 181 | } | 209 | } |
| 182 | 210 | ||
| 183 | reg += GPIO_ICR1 + ((gpio & 0x10) >> 2); /* lower or upper register */ | 211 | if (GPIO_EDGE_SEL >= 0) { |
| 184 | bit = gpio & 0xf; | 212 | val = readl(port->base + GPIO_EDGE_SEL); |
| 185 | val = readl(reg) & ~(0x3 << (bit << 1)); | 213 | if (edge == GPIO_INT_BOTH_EDGES) |
| 186 | writel(val | (edge << (bit << 1)), reg); | 214 | writel(val | (1 << gpio_idx), |
| 187 | writel(1 << (gpio & 0x1f), port->base + GPIO_ISR); | 215 | port->base + GPIO_EDGE_SEL); |
| 216 | else | ||
| 217 | writel(val & ~(1 << gpio_idx), | ||
| 218 | port->base + GPIO_EDGE_SEL); | ||
| 219 | } | ||
| 220 | |||
| 221 | if (edge != GPIO_INT_BOTH_EDGES) { | ||
| 222 | reg += GPIO_ICR1 + ((gpio_idx & 0x10) >> 2); /* lower or upper register */ | ||
| 223 | bit = gpio_idx & 0xf; | ||
| 224 | val = readl(reg) & ~(0x3 << (bit << 1)); | ||
| 225 | writel(val | (edge << (bit << 1)), reg); | ||
| 226 | } | ||
| 227 | |||
| 228 | writel(1 << gpio_idx, port->base + GPIO_ISR); | ||
| 188 | 229 | ||
| 189 | return 0; | 230 | return 0; |
| 190 | } | 231 | } |
| @@ -217,15 +258,13 @@ static void mxc_flip_edge(struct mxc_gpio_port *port, u32 gpio) | |||
| 217 | /* handle 32 interrupts in one status register */ | 258 | /* handle 32 interrupts in one status register */ |
| 218 | static void mxc_gpio_irq_handler(struct mxc_gpio_port *port, u32 irq_stat) | 259 | static void mxc_gpio_irq_handler(struct mxc_gpio_port *port, u32 irq_stat) |
| 219 | { | 260 | { |
| 220 | u32 gpio_irq_no_base = port->virtual_irq_start; | ||
| 221 | |||
| 222 | while (irq_stat != 0) { | 261 | while (irq_stat != 0) { |
| 223 | int irqoffset = fls(irq_stat) - 1; | 262 | int irqoffset = fls(irq_stat) - 1; |
| 224 | 263 | ||
| 225 | if (port->both_edges & (1 << irqoffset)) | 264 | if (port->both_edges & (1 << irqoffset)) |
| 226 | mxc_flip_edge(port, irqoffset); | 265 | mxc_flip_edge(port, irqoffset); |
| 227 | 266 | ||
| 228 | generic_handle_irq(gpio_irq_no_base + irqoffset); | 267 | generic_handle_irq(irq_find_mapping(port->domain, irqoffset)); |
| 229 | 268 | ||
| 230 | irq_stat &= ~(1 << irqoffset); | 269 | irq_stat &= ~(1 << irqoffset); |
| 231 | } | 270 | } |
| @@ -276,10 +315,9 @@ static void mx2_gpio_irq_handler(u32 irq, struct irq_desc *desc) | |||
| 276 | */ | 315 | */ |
| 277 | static int gpio_set_wake_irq(struct irq_data *d, u32 enable) | 316 | static int gpio_set_wake_irq(struct irq_data *d, u32 enable) |
| 278 | { | 317 | { |
| 279 | u32 gpio = irq_to_gpio(d->irq); | ||
| 280 | u32 gpio_idx = gpio & 0x1F; | ||
| 281 | struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); | 318 | struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); |
| 282 | struct mxc_gpio_port *port = gc->private; | 319 | struct mxc_gpio_port *port = gc->private; |
| 320 | u32 gpio_idx = d->hwirq; | ||
| 283 | 321 | ||
| 284 | if (enable) { | 322 | if (enable) { |
| 285 | if (port->irq_high && (gpio_idx >= 16)) | 323 | if (port->irq_high && (gpio_idx >= 16)) |
| @@ -296,12 +334,12 @@ static int gpio_set_wake_irq(struct irq_data *d, u32 enable) | |||
| 296 | return 0; | 334 | return 0; |
| 297 | } | 335 | } |
| 298 | 336 | ||
| 299 | static void __init mxc_gpio_init_gc(struct mxc_gpio_port *port) | 337 | static void __init mxc_gpio_init_gc(struct mxc_gpio_port *port, int irq_base) |
| 300 | { | 338 | { |
| 301 | struct irq_chip_generic *gc; | 339 | struct irq_chip_generic *gc; |
| 302 | struct irq_chip_type *ct; | 340 | struct irq_chip_type *ct; |
| 303 | 341 | ||
| 304 | gc = irq_alloc_generic_chip("gpio-mxc", 1, port->virtual_irq_start, | 342 | gc = irq_alloc_generic_chip("gpio-mxc", 1, irq_base, |
| 305 | port->base, handle_level_irq); | 343 | port->base, handle_level_irq); |
| 306 | gc->private = port; | 344 | gc->private = port; |
| 307 | 345 | ||
| @@ -338,7 +376,9 @@ static void __devinit mxc_gpio_get_hw(struct platform_device *pdev) | |||
| 338 | return; | 376 | return; |
| 339 | } | 377 | } |
| 340 | 378 | ||
| 341 | if (hwtype == IMX31_GPIO) | 379 | if (hwtype == IMX35_GPIO) |
| 380 | mxc_gpio_hwdata = &imx35_gpio_hwdata; | ||
| 381 | else if (hwtype == IMX31_GPIO) | ||
| 342 | mxc_gpio_hwdata = &imx31_gpio_hwdata; | 382 | mxc_gpio_hwdata = &imx31_gpio_hwdata; |
| 343 | else | 383 | else |
| 344 | mxc_gpio_hwdata = &imx1_imx21_gpio_hwdata; | 384 | mxc_gpio_hwdata = &imx1_imx21_gpio_hwdata; |
| @@ -352,7 +392,7 @@ static int mxc_gpio_to_irq(struct gpio_chip *gc, unsigned offset) | |||
| 352 | struct mxc_gpio_port *port = | 392 | struct mxc_gpio_port *port = |
| 353 | container_of(bgc, struct mxc_gpio_port, bgc); | 393 | container_of(bgc, struct mxc_gpio_port, bgc); |
| 354 | 394 | ||
| 355 | return port->virtual_irq_start + offset; | 395 | return irq_find_mapping(port->domain, offset); |
| 356 | } | 396 | } |
| 357 | 397 | ||
| 358 | static int __devinit mxc_gpio_probe(struct platform_device *pdev) | 398 | static int __devinit mxc_gpio_probe(struct platform_device *pdev) |
| @@ -360,6 +400,7 @@ static int __devinit mxc_gpio_probe(struct platform_device *pdev) | |||
| 360 | struct device_node *np = pdev->dev.of_node; | 400 | struct device_node *np = pdev->dev.of_node; |
| 361 | struct mxc_gpio_port *port; | 401 | struct mxc_gpio_port *port; |
| 362 | struct resource *iores; | 402 | struct resource *iores; |
| 403 | int irq_base; | ||
| 363 | int err; | 404 | int err; |
| 364 | 405 | ||
| 365 | mxc_gpio_get_hw(pdev); | 406 | mxc_gpio_get_hw(pdev); |
| @@ -398,10 +439,12 @@ static int __devinit mxc_gpio_probe(struct platform_device *pdev) | |||
| 398 | writel(~0, port->base + GPIO_ISR); | 439 | writel(~0, port->base + GPIO_ISR); |
| 399 | 440 | ||
| 400 | if (mxc_gpio_hwtype == IMX21_GPIO) { | 441 | if (mxc_gpio_hwtype == IMX21_GPIO) { |
| 401 | /* setup one handler for all GPIO interrupts */ | 442 | /* |
| 402 | if (pdev->id == 0) | 443 | * Setup one handler for all GPIO interrupts. Actually setting |
| 403 | irq_set_chained_handler(port->irq, | 444 | * the handler is needed only once, but doing it for every port |
| 404 | mx2_gpio_irq_handler); | 445 | * is more robust and easier. |
| 446 | */ | ||
| 447 | irq_set_chained_handler(port->irq, mx2_gpio_irq_handler); | ||
| 405 | } else { | 448 | } else { |
| 406 | /* setup one handler for each entry */ | 449 | /* setup one handler for each entry */ |
| 407 | irq_set_chained_handler(port->irq, mx3_gpio_irq_handler); | 450 | irq_set_chained_handler(port->irq, mx3_gpio_irq_handler); |
| @@ -430,20 +473,30 @@ static int __devinit mxc_gpio_probe(struct platform_device *pdev) | |||
| 430 | if (err) | 473 | if (err) |
| 431 | goto out_bgpio_remove; | 474 | goto out_bgpio_remove; |
| 432 | 475 | ||
| 433 | /* | 476 | irq_base = irq_alloc_descs(-1, 0, 32, numa_node_id()); |
| 434 | * In dt case, we use gpio number range dynamically | 477 | if (irq_base < 0) { |
| 435 | * allocated by gpio core. | 478 | err = irq_base; |
| 436 | */ | 479 | goto out_gpiochip_remove; |
| 437 | port->virtual_irq_start = MXC_GPIO_IRQ_START + (np ? port->bgc.gc.base : | 480 | } |
| 438 | pdev->id * 32); | 481 | |
| 482 | port->domain = irq_domain_add_legacy(np, 32, irq_base, 0, | ||
| 483 | &irq_domain_simple_ops, NULL); | ||
| 484 | if (!port->domain) { | ||
| 485 | err = -ENODEV; | ||
| 486 | goto out_irqdesc_free; | ||
| 487 | } | ||
| 439 | 488 | ||
| 440 | /* gpio-mxc can be a generic irq chip */ | 489 | /* gpio-mxc can be a generic irq chip */ |
| 441 | mxc_gpio_init_gc(port); | 490 | mxc_gpio_init_gc(port, irq_base); |
| 442 | 491 | ||
| 443 | list_add_tail(&port->node, &mxc_gpio_ports); | 492 | list_add_tail(&port->node, &mxc_gpio_ports); |
| 444 | 493 | ||
| 445 | return 0; | 494 | return 0; |
| 446 | 495 | ||
| 496 | out_irqdesc_free: | ||
| 497 | irq_free_descs(irq_base, 32); | ||
| 498 | out_gpiochip_remove: | ||
| 499 | WARN_ON(gpiochip_remove(&port->bgc.gc) < 0); | ||
| 447 | out_bgpio_remove: | 500 | out_bgpio_remove: |
| 448 | bgpio_remove(&port->bgc); | 501 | bgpio_remove(&port->bgc); |
| 449 | out_iounmap: | 502 | out_iounmap: |
diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c index c4ed1722734c..e6efd77668f0 100644 --- a/drivers/gpio/gpio-omap.c +++ b/drivers/gpio/gpio-omap.c | |||
| @@ -174,12 +174,22 @@ static inline void _gpio_dbck_enable(struct gpio_bank *bank) | |||
| 174 | if (bank->dbck_enable_mask && !bank->dbck_enabled) { | 174 | if (bank->dbck_enable_mask && !bank->dbck_enabled) { |
| 175 | clk_enable(bank->dbck); | 175 | clk_enable(bank->dbck); |
| 176 | bank->dbck_enabled = true; | 176 | bank->dbck_enabled = true; |
| 177 | |||
| 178 | __raw_writel(bank->dbck_enable_mask, | ||
| 179 | bank->base + bank->regs->debounce_en); | ||
| 177 | } | 180 | } |
| 178 | } | 181 | } |
| 179 | 182 | ||
| 180 | static inline void _gpio_dbck_disable(struct gpio_bank *bank) | 183 | static inline void _gpio_dbck_disable(struct gpio_bank *bank) |
| 181 | { | 184 | { |
| 182 | if (bank->dbck_enable_mask && bank->dbck_enabled) { | 185 | if (bank->dbck_enable_mask && bank->dbck_enabled) { |
| 186 | /* | ||
| 187 | * Disable debounce before cutting it's clock. If debounce is | ||
| 188 | * enabled but the clock is not, GPIO module seems to be unable | ||
| 189 | * to detect events and generate interrupts at least on OMAP3. | ||
| 190 | */ | ||
| 191 | __raw_writel(0, bank->base + bank->regs->debounce_en); | ||
| 192 | |||
| 183 | clk_disable(bank->dbck); | 193 | clk_disable(bank->dbck); |
| 184 | bank->dbck_enabled = false; | 194 | bank->dbck_enabled = false; |
| 185 | } | 195 | } |
| @@ -889,12 +899,6 @@ static int gpio_debounce(struct gpio_chip *chip, unsigned offset, | |||
| 889 | 899 | ||
| 890 | bank = container_of(chip, struct gpio_bank, chip); | 900 | bank = container_of(chip, struct gpio_bank, chip); |
| 891 | 901 | ||
| 892 | if (!bank->dbck) { | ||
| 893 | bank->dbck = clk_get(bank->dev, "dbclk"); | ||
| 894 | if (IS_ERR(bank->dbck)) | ||
| 895 | dev_err(bank->dev, "Could not get gpio dbck\n"); | ||
| 896 | } | ||
| 897 | |||
| 898 | spin_lock_irqsave(&bank->lock, flags); | 902 | spin_lock_irqsave(&bank->lock, flags); |
| 899 | _set_gpio_debounce(bank, offset, debounce); | 903 | _set_gpio_debounce(bank, offset, debounce); |
| 900 | spin_unlock_irqrestore(&bank->lock, flags); | 904 | spin_unlock_irqrestore(&bank->lock, flags); |
| @@ -966,6 +970,10 @@ static void omap_gpio_mod_init(struct gpio_bank *bank) | |||
| 966 | /* Initialize interface clk ungated, module enabled */ | 970 | /* Initialize interface clk ungated, module enabled */ |
| 967 | if (bank->regs->ctrl) | 971 | if (bank->regs->ctrl) |
| 968 | __raw_writel(0, base + bank->regs->ctrl); | 972 | __raw_writel(0, base + bank->regs->ctrl); |
| 973 | |||
| 974 | bank->dbck = clk_get(bank->dev, "dbclk"); | ||
| 975 | if (IS_ERR(bank->dbck)) | ||
| 976 | dev_err(bank->dev, "Could not get gpio dbck\n"); | ||
| 969 | } | 977 | } |
| 970 | 978 | ||
| 971 | static __devinit void | 979 | static __devinit void |
| @@ -1081,7 +1089,6 @@ static int __devinit omap_gpio_probe(struct platform_device *pdev) | |||
| 1081 | bank->is_mpuio = pdata->is_mpuio; | 1089 | bank->is_mpuio = pdata->is_mpuio; |
| 1082 | bank->non_wakeup_gpios = pdata->non_wakeup_gpios; | 1090 | bank->non_wakeup_gpios = pdata->non_wakeup_gpios; |
| 1083 | bank->loses_context = pdata->loses_context; | 1091 | bank->loses_context = pdata->loses_context; |
| 1084 | bank->get_context_loss_count = pdata->get_context_loss_count; | ||
| 1085 | bank->regs = pdata->regs; | 1092 | bank->regs = pdata->regs; |
| 1086 | #ifdef CONFIG_OF_GPIO | 1093 | #ifdef CONFIG_OF_GPIO |
| 1087 | bank->chip.of_node = of_node_get(node); | 1094 | bank->chip.of_node = of_node_get(node); |
| @@ -1135,6 +1142,9 @@ static int __devinit omap_gpio_probe(struct platform_device *pdev) | |||
| 1135 | omap_gpio_chip_init(bank); | 1142 | omap_gpio_chip_init(bank); |
| 1136 | omap_gpio_show_rev(bank); | 1143 | omap_gpio_show_rev(bank); |
| 1137 | 1144 | ||
| 1145 | if (bank->loses_context) | ||
| 1146 | bank->get_context_loss_count = pdata->get_context_loss_count; | ||
| 1147 | |||
| 1138 | pm_runtime_put(bank->dev); | 1148 | pm_runtime_put(bank->dev); |
| 1139 | 1149 | ||
| 1140 | list_add_tail(&bank->node, &omap_gpio_list); | 1150 | list_add_tail(&bank->node, &omap_gpio_list); |
diff --git a/drivers/gpio/gpio-pca953x.c b/drivers/gpio/gpio-pca953x.c index 1c313c710be3..9c693ae17956 100644 --- a/drivers/gpio/gpio-pca953x.c +++ b/drivers/gpio/gpio-pca953x.c | |||
| @@ -78,10 +78,10 @@ struct pca953x_chip { | |||
| 78 | 78 | ||
| 79 | #ifdef CONFIG_GPIO_PCA953X_IRQ | 79 | #ifdef CONFIG_GPIO_PCA953X_IRQ |
| 80 | struct mutex irq_lock; | 80 | struct mutex irq_lock; |
| 81 | uint16_t irq_mask; | 81 | u32 irq_mask; |
| 82 | uint16_t irq_stat; | 82 | u32 irq_stat; |
| 83 | uint16_t irq_trig_raise; | 83 | u32 irq_trig_raise; |
| 84 | uint16_t irq_trig_fall; | 84 | u32 irq_trig_fall; |
| 85 | int irq_base; | 85 | int irq_base; |
| 86 | #endif | 86 | #endif |
| 87 | 87 | ||
| @@ -98,12 +98,11 @@ static int pca953x_write_reg(struct pca953x_chip *chip, int reg, u32 val) | |||
| 98 | if (chip->gpio_chip.ngpio <= 8) | 98 | if (chip->gpio_chip.ngpio <= 8) |
| 99 | ret = i2c_smbus_write_byte_data(chip->client, reg, val); | 99 | ret = i2c_smbus_write_byte_data(chip->client, reg, val); |
| 100 | else if (chip->gpio_chip.ngpio == 24) { | 100 | else if (chip->gpio_chip.ngpio == 24) { |
| 101 | ret = i2c_smbus_write_word_data(chip->client, | 101 | cpu_to_le32s(&val); |
| 102 | ret = i2c_smbus_write_i2c_block_data(chip->client, | ||
| 102 | (reg << 2) | REG_ADDR_AI, | 103 | (reg << 2) | REG_ADDR_AI, |
| 103 | val & 0xffff); | 104 | 3, |
| 104 | ret = i2c_smbus_write_byte_data(chip->client, | 105 | (u8 *) &val); |
| 105 | (reg << 2) + 2, | ||
| 106 | (val & 0xff0000) >> 16); | ||
| 107 | } | 106 | } |
| 108 | else { | 107 | else { |
| 109 | switch (chip->chip_type) { | 108 | switch (chip->chip_type) { |
| @@ -135,22 +134,27 @@ static int pca953x_read_reg(struct pca953x_chip *chip, int reg, u32 *val) | |||
| 135 | { | 134 | { |
| 136 | int ret; | 135 | int ret; |
| 137 | 136 | ||
| 138 | if (chip->gpio_chip.ngpio <= 8) | 137 | if (chip->gpio_chip.ngpio <= 8) { |
| 139 | ret = i2c_smbus_read_byte_data(chip->client, reg); | 138 | ret = i2c_smbus_read_byte_data(chip->client, reg); |
| 140 | else if (chip->gpio_chip.ngpio == 24) { | 139 | *val = ret; |
| 141 | ret = i2c_smbus_read_word_data(chip->client, reg << 2); | ||
| 142 | ret |= (i2c_smbus_read_byte_data(chip->client, | ||
| 143 | (reg << 2) + 2)<<16); | ||
| 144 | } | 140 | } |
| 145 | else | 141 | else if (chip->gpio_chip.ngpio == 24) { |
| 142 | *val = 0; | ||
| 143 | ret = i2c_smbus_read_i2c_block_data(chip->client, | ||
| 144 | (reg << 2) | REG_ADDR_AI, | ||
| 145 | 3, | ||
| 146 | (u8 *) val); | ||
| 147 | le32_to_cpus(val); | ||
| 148 | } else { | ||
| 146 | ret = i2c_smbus_read_word_data(chip->client, reg << 1); | 149 | ret = i2c_smbus_read_word_data(chip->client, reg << 1); |
| 150 | *val = ret; | ||
| 151 | } | ||
| 147 | 152 | ||
| 148 | if (ret < 0) { | 153 | if (ret < 0) { |
| 149 | dev_err(&chip->client->dev, "failed reading register\n"); | 154 | dev_err(&chip->client->dev, "failed reading register\n"); |
| 150 | return ret; | 155 | return ret; |
| 151 | } | 156 | } |
| 152 | 157 | ||
| 153 | *val = (u32)ret; | ||
| 154 | return 0; | 158 | return 0; |
| 155 | } | 159 | } |
| 156 | 160 | ||
| @@ -349,8 +353,8 @@ static void pca953x_irq_bus_lock(struct irq_data *d) | |||
| 349 | static void pca953x_irq_bus_sync_unlock(struct irq_data *d) | 353 | static void pca953x_irq_bus_sync_unlock(struct irq_data *d) |
| 350 | { | 354 | { |
| 351 | struct pca953x_chip *chip = irq_data_get_irq_chip_data(d); | 355 | struct pca953x_chip *chip = irq_data_get_irq_chip_data(d); |
| 352 | uint16_t new_irqs; | 356 | u32 new_irqs; |
| 353 | uint16_t level; | 357 | u32 level; |
| 354 | 358 | ||
| 355 | /* Look for any newly setup interrupt */ | 359 | /* Look for any newly setup interrupt */ |
| 356 | new_irqs = chip->irq_trig_fall | chip->irq_trig_raise; | 360 | new_irqs = chip->irq_trig_fall | chip->irq_trig_raise; |
| @@ -368,8 +372,8 @@ static void pca953x_irq_bus_sync_unlock(struct irq_data *d) | |||
| 368 | static int pca953x_irq_set_type(struct irq_data *d, unsigned int type) | 372 | static int pca953x_irq_set_type(struct irq_data *d, unsigned int type) |
| 369 | { | 373 | { |
| 370 | struct pca953x_chip *chip = irq_data_get_irq_chip_data(d); | 374 | struct pca953x_chip *chip = irq_data_get_irq_chip_data(d); |
| 371 | uint16_t level = d->irq - chip->irq_base; | 375 | u32 level = d->irq - chip->irq_base; |
| 372 | uint16_t mask = 1 << level; | 376 | u32 mask = 1 << level; |
| 373 | 377 | ||
| 374 | if (!(type & IRQ_TYPE_EDGE_BOTH)) { | 378 | if (!(type & IRQ_TYPE_EDGE_BOTH)) { |
| 375 | dev_err(&chip->client->dev, "irq %d: unsupported type %d\n", | 379 | dev_err(&chip->client->dev, "irq %d: unsupported type %d\n", |
| @@ -399,12 +403,12 @@ static struct irq_chip pca953x_irq_chip = { | |||
| 399 | .irq_set_type = pca953x_irq_set_type, | 403 | .irq_set_type = pca953x_irq_set_type, |
| 400 | }; | 404 | }; |
| 401 | 405 | ||
| 402 | static uint16_t pca953x_irq_pending(struct pca953x_chip *chip) | 406 | static u32 pca953x_irq_pending(struct pca953x_chip *chip) |
| 403 | { | 407 | { |
| 404 | u32 cur_stat; | 408 | u32 cur_stat; |
| 405 | uint16_t old_stat; | 409 | u32 old_stat; |
| 406 | uint16_t pending; | 410 | u32 pending; |
| 407 | uint16_t trigger; | 411 | u32 trigger; |
| 408 | int ret, offset = 0; | 412 | int ret, offset = 0; |
| 409 | 413 | ||
| 410 | switch (chip->chip_type) { | 414 | switch (chip->chip_type) { |
| @@ -440,8 +444,8 @@ static uint16_t pca953x_irq_pending(struct pca953x_chip *chip) | |||
| 440 | static irqreturn_t pca953x_irq_handler(int irq, void *devid) | 444 | static irqreturn_t pca953x_irq_handler(int irq, void *devid) |
| 441 | { | 445 | { |
| 442 | struct pca953x_chip *chip = devid; | 446 | struct pca953x_chip *chip = devid; |
| 443 | uint16_t pending; | 447 | u32 pending; |
| 444 | uint16_t level; | 448 | u32 level; |
| 445 | 449 | ||
| 446 | pending = pca953x_irq_pending(chip); | 450 | pending = pca953x_irq_pending(chip); |
| 447 | 451 | ||
| @@ -564,7 +568,7 @@ static void pca953x_irq_teardown(struct pca953x_chip *chip) | |||
| 564 | * WARNING: This is DEPRECATED and will be removed eventually! | 568 | * WARNING: This is DEPRECATED and will be removed eventually! |
| 565 | */ | 569 | */ |
| 566 | static void | 570 | static void |
| 567 | pca953x_get_alt_pdata(struct i2c_client *client, int *gpio_base, int *invert) | 571 | pca953x_get_alt_pdata(struct i2c_client *client, int *gpio_base, u32 *invert) |
| 568 | { | 572 | { |
| 569 | struct device_node *node; | 573 | struct device_node *node; |
| 570 | const __be32 *val; | 574 | const __be32 *val; |
| @@ -592,13 +596,13 @@ pca953x_get_alt_pdata(struct i2c_client *client, int *gpio_base, int *invert) | |||
| 592 | } | 596 | } |
| 593 | #else | 597 | #else |
| 594 | static void | 598 | static void |
| 595 | pca953x_get_alt_pdata(struct i2c_client *client, int *gpio_base, int *invert) | 599 | pca953x_get_alt_pdata(struct i2c_client *client, int *gpio_base, u32 *invert) |
| 596 | { | 600 | { |
| 597 | *gpio_base = -1; | 601 | *gpio_base = -1; |
| 598 | } | 602 | } |
| 599 | #endif | 603 | #endif |
| 600 | 604 | ||
| 601 | static int __devinit device_pca953x_init(struct pca953x_chip *chip, int invert) | 605 | static int __devinit device_pca953x_init(struct pca953x_chip *chip, u32 invert) |
| 602 | { | 606 | { |
| 603 | int ret; | 607 | int ret; |
| 604 | 608 | ||
| @@ -617,7 +621,7 @@ out: | |||
| 617 | return ret; | 621 | return ret; |
| 618 | } | 622 | } |
| 619 | 623 | ||
| 620 | static int __devinit device_pca957x_init(struct pca953x_chip *chip, int invert) | 624 | static int __devinit device_pca957x_init(struct pca953x_chip *chip, u32 invert) |
| 621 | { | 625 | { |
| 622 | int ret; | 626 | int ret; |
| 623 | u32 val = 0; | 627 | u32 val = 0; |
| @@ -653,8 +657,9 @@ static int __devinit pca953x_probe(struct i2c_client *client, | |||
| 653 | { | 657 | { |
| 654 | struct pca953x_platform_data *pdata; | 658 | struct pca953x_platform_data *pdata; |
| 655 | struct pca953x_chip *chip; | 659 | struct pca953x_chip *chip; |
| 656 | int irq_base=0, invert=0; | 660 | int irq_base = 0; |
| 657 | int ret; | 661 | int ret; |
| 662 | u32 invert = 0; | ||
| 658 | 663 | ||
| 659 | chip = kzalloc(sizeof(struct pca953x_chip), GFP_KERNEL); | 664 | chip = kzalloc(sizeof(struct pca953x_chip), GFP_KERNEL); |
| 660 | if (chip == NULL) | 665 | if (chip == NULL) |
diff --git a/drivers/gpio/gpio-pcf857x.c b/drivers/gpio/gpio-pcf857x.c index 2d1de9e7e9bd..076e236d0da7 100644 --- a/drivers/gpio/gpio-pcf857x.c +++ b/drivers/gpio/gpio-pcf857x.c | |||
| @@ -61,61 +61,28 @@ struct pcf857x { | |||
| 61 | struct i2c_client *client; | 61 | struct i2c_client *client; |
| 62 | struct mutex lock; /* protect 'out' */ | 62 | struct mutex lock; /* protect 'out' */ |
| 63 | unsigned out; /* software latch */ | 63 | unsigned out; /* software latch */ |
| 64 | |||
| 65 | int (*write)(struct i2c_client *client, unsigned data); | ||
| 66 | int (*read)(struct i2c_client *client); | ||
| 64 | }; | 67 | }; |
| 65 | 68 | ||
| 66 | /*-------------------------------------------------------------------------*/ | 69 | /*-------------------------------------------------------------------------*/ |
| 67 | 70 | ||
| 68 | /* Talk to 8-bit I/O expander */ | 71 | /* Talk to 8-bit I/O expander */ |
| 69 | 72 | ||
| 70 | static int pcf857x_input8(struct gpio_chip *chip, unsigned offset) | 73 | static int i2c_write_le8(struct i2c_client *client, unsigned data) |
| 71 | { | ||
| 72 | struct pcf857x *gpio = container_of(chip, struct pcf857x, chip); | ||
| 73 | int status; | ||
| 74 | |||
| 75 | mutex_lock(&gpio->lock); | ||
| 76 | gpio->out |= (1 << offset); | ||
| 77 | status = i2c_smbus_write_byte(gpio->client, gpio->out); | ||
| 78 | mutex_unlock(&gpio->lock); | ||
| 79 | |||
| 80 | return status; | ||
| 81 | } | ||
| 82 | |||
| 83 | static int pcf857x_get8(struct gpio_chip *chip, unsigned offset) | ||
| 84 | { | ||
| 85 | struct pcf857x *gpio = container_of(chip, struct pcf857x, chip); | ||
| 86 | s32 value; | ||
| 87 | |||
| 88 | value = i2c_smbus_read_byte(gpio->client); | ||
| 89 | return (value < 0) ? 0 : (value & (1 << offset)); | ||
| 90 | } | ||
| 91 | |||
| 92 | static int pcf857x_output8(struct gpio_chip *chip, unsigned offset, int value) | ||
| 93 | { | 74 | { |
| 94 | struct pcf857x *gpio = container_of(chip, struct pcf857x, chip); | 75 | return i2c_smbus_write_byte(client, data); |
| 95 | unsigned bit = 1 << offset; | ||
| 96 | int status; | ||
| 97 | |||
| 98 | mutex_lock(&gpio->lock); | ||
| 99 | if (value) | ||
| 100 | gpio->out |= bit; | ||
| 101 | else | ||
| 102 | gpio->out &= ~bit; | ||
| 103 | status = i2c_smbus_write_byte(gpio->client, gpio->out); | ||
| 104 | mutex_unlock(&gpio->lock); | ||
| 105 | |||
| 106 | return status; | ||
| 107 | } | 76 | } |
| 108 | 77 | ||
| 109 | static void pcf857x_set8(struct gpio_chip *chip, unsigned offset, int value) | 78 | static int i2c_read_le8(struct i2c_client *client) |
| 110 | { | 79 | { |
| 111 | pcf857x_output8(chip, offset, value); | 80 | return (int)i2c_smbus_read_byte(client); |
| 112 | } | 81 | } |
| 113 | 82 | ||
| 114 | /*-------------------------------------------------------------------------*/ | ||
| 115 | |||
| 116 | /* Talk to 16-bit I/O expander */ | 83 | /* Talk to 16-bit I/O expander */ |
| 117 | 84 | ||
| 118 | static int i2c_write_le16(struct i2c_client *client, u16 word) | 85 | static int i2c_write_le16(struct i2c_client *client, unsigned word) |
| 119 | { | 86 | { |
| 120 | u8 buf[2] = { word & 0xff, word >> 8, }; | 87 | u8 buf[2] = { word & 0xff, word >> 8, }; |
| 121 | int status; | 88 | int status; |
| @@ -135,29 +102,31 @@ static int i2c_read_le16(struct i2c_client *client) | |||
| 135 | return (buf[1] << 8) | buf[0]; | 102 | return (buf[1] << 8) | buf[0]; |
| 136 | } | 103 | } |
| 137 | 104 | ||
| 138 | static int pcf857x_input16(struct gpio_chip *chip, unsigned offset) | 105 | /*-------------------------------------------------------------------------*/ |
| 106 | |||
| 107 | static int pcf857x_input(struct gpio_chip *chip, unsigned offset) | ||
| 139 | { | 108 | { |
| 140 | struct pcf857x *gpio = container_of(chip, struct pcf857x, chip); | 109 | struct pcf857x *gpio = container_of(chip, struct pcf857x, chip); |
| 141 | int status; | 110 | int status; |
| 142 | 111 | ||
| 143 | mutex_lock(&gpio->lock); | 112 | mutex_lock(&gpio->lock); |
| 144 | gpio->out |= (1 << offset); | 113 | gpio->out |= (1 << offset); |
| 145 | status = i2c_write_le16(gpio->client, gpio->out); | 114 | status = gpio->write(gpio->client, gpio->out); |
| 146 | mutex_unlock(&gpio->lock); | 115 | mutex_unlock(&gpio->lock); |
| 147 | 116 | ||
| 148 | return status; | 117 | return status; |
| 149 | } | 118 | } |
| 150 | 119 | ||
| 151 | static int pcf857x_get16(struct gpio_chip *chip, unsigned offset) | 120 | static int pcf857x_get(struct gpio_chip *chip, unsigned offset) |
| 152 | { | 121 | { |
| 153 | struct pcf857x *gpio = container_of(chip, struct pcf857x, chip); | 122 | struct pcf857x *gpio = container_of(chip, struct pcf857x, chip); |
| 154 | int value; | 123 | int value; |
| 155 | 124 | ||
| 156 | value = i2c_read_le16(gpio->client); | 125 | value = gpio->read(gpio->client); |
| 157 | return (value < 0) ? 0 : (value & (1 << offset)); | 126 | return (value < 0) ? 0 : (value & (1 << offset)); |
| 158 | } | 127 | } |
| 159 | 128 | ||
| 160 | static int pcf857x_output16(struct gpio_chip *chip, unsigned offset, int value) | 129 | static int pcf857x_output(struct gpio_chip *chip, unsigned offset, int value) |
| 161 | { | 130 | { |
| 162 | struct pcf857x *gpio = container_of(chip, struct pcf857x, chip); | 131 | struct pcf857x *gpio = container_of(chip, struct pcf857x, chip); |
| 163 | unsigned bit = 1 << offset; | 132 | unsigned bit = 1 << offset; |
| @@ -168,15 +137,15 @@ static int pcf857x_output16(struct gpio_chip *chip, unsigned offset, int value) | |||
| 168 | gpio->out |= bit; | 137 | gpio->out |= bit; |
| 169 | else | 138 | else |
| 170 | gpio->out &= ~bit; | 139 | gpio->out &= ~bit; |
| 171 | status = i2c_write_le16(gpio->client, gpio->out); | 140 | status = gpio->write(gpio->client, gpio->out); |
| 172 | mutex_unlock(&gpio->lock); | 141 | mutex_unlock(&gpio->lock); |
| 173 | 142 | ||
| 174 | return status; | 143 | return status; |
| 175 | } | 144 | } |
| 176 | 145 | ||
| 177 | static void pcf857x_set16(struct gpio_chip *chip, unsigned offset, int value) | 146 | static void pcf857x_set(struct gpio_chip *chip, unsigned offset, int value) |
| 178 | { | 147 | { |
| 179 | pcf857x_output16(chip, offset, value); | 148 | pcf857x_output(chip, offset, value); |
| 180 | } | 149 | } |
| 181 | 150 | ||
| 182 | /*-------------------------------------------------------------------------*/ | 151 | /*-------------------------------------------------------------------------*/ |
| @@ -200,10 +169,15 @@ static int pcf857x_probe(struct i2c_client *client, | |||
| 200 | 169 | ||
| 201 | mutex_init(&gpio->lock); | 170 | mutex_init(&gpio->lock); |
| 202 | 171 | ||
| 203 | gpio->chip.base = pdata ? pdata->gpio_base : -1; | 172 | gpio->chip.base = pdata ? pdata->gpio_base : -1; |
| 204 | gpio->chip.can_sleep = 1; | 173 | gpio->chip.can_sleep = 1; |
| 205 | gpio->chip.dev = &client->dev; | 174 | gpio->chip.dev = &client->dev; |
| 206 | gpio->chip.owner = THIS_MODULE; | 175 | gpio->chip.owner = THIS_MODULE; |
| 176 | gpio->chip.get = pcf857x_get; | ||
| 177 | gpio->chip.set = pcf857x_set; | ||
| 178 | gpio->chip.direction_input = pcf857x_input; | ||
| 179 | gpio->chip.direction_output = pcf857x_output; | ||
| 180 | gpio->chip.ngpio = id->driver_data; | ||
| 207 | 181 | ||
| 208 | /* NOTE: the OnSemi jlc1562b is also largely compatible with | 182 | /* NOTE: the OnSemi jlc1562b is also largely compatible with |
| 209 | * these parts, notably for output. It has a low-resolution | 183 | * these parts, notably for output. It has a low-resolution |
| @@ -216,12 +190,9 @@ static int pcf857x_probe(struct i2c_client *client, | |||
| 216 | * | 190 | * |
| 217 | * NOTE: we don't distinguish here between *4 and *4a parts. | 191 | * NOTE: we don't distinguish here between *4 and *4a parts. |
| 218 | */ | 192 | */ |
| 219 | gpio->chip.ngpio = id->driver_data; | ||
| 220 | if (gpio->chip.ngpio == 8) { | 193 | if (gpio->chip.ngpio == 8) { |
| 221 | gpio->chip.direction_input = pcf857x_input8; | 194 | gpio->write = i2c_write_le8; |
| 222 | gpio->chip.get = pcf857x_get8; | 195 | gpio->read = i2c_read_le8; |
| 223 | gpio->chip.direction_output = pcf857x_output8; | ||
| 224 | gpio->chip.set = pcf857x_set8; | ||
| 225 | 196 | ||
| 226 | if (!i2c_check_functionality(client->adapter, | 197 | if (!i2c_check_functionality(client->adapter, |
| 227 | I2C_FUNC_SMBUS_BYTE)) | 198 | I2C_FUNC_SMBUS_BYTE)) |
| @@ -238,10 +209,8 @@ static int pcf857x_probe(struct i2c_client *client, | |||
| 238 | * NOTE: we don't distinguish here between '75 and '75c parts. | 209 | * NOTE: we don't distinguish here between '75 and '75c parts. |
| 239 | */ | 210 | */ |
| 240 | } else if (gpio->chip.ngpio == 16) { | 211 | } else if (gpio->chip.ngpio == 16) { |
| 241 | gpio->chip.direction_input = pcf857x_input16; | 212 | gpio->write = i2c_write_le16; |
| 242 | gpio->chip.get = pcf857x_get16; | 213 | gpio->read = i2c_read_le16; |
| 243 | gpio->chip.direction_output = pcf857x_output16; | ||
| 244 | gpio->chip.set = pcf857x_set16; | ||
| 245 | 214 | ||
| 246 | if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) | 215 | if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) |
| 247 | status = -EIO; | 216 | status = -EIO; |
diff --git a/drivers/gpio/gpio-samsung.c b/drivers/gpio/gpio-samsung.c index b6453d0e44ad..92f7b2bb79d4 100644 --- a/drivers/gpio/gpio-samsung.c +++ b/drivers/gpio/gpio-samsung.c | |||
| @@ -2681,11 +2681,14 @@ static int exynos_gpio_xlate(struct gpio_chip *gc, | |||
| 2681 | 2681 | ||
| 2682 | if (s3c_gpio_cfgpin(pin, S3C_GPIO_SFN(gpiospec->args[1]))) | 2682 | if (s3c_gpio_cfgpin(pin, S3C_GPIO_SFN(gpiospec->args[1]))) |
| 2683 | pr_warn("gpio_xlate: failed to set pin function\n"); | 2683 | pr_warn("gpio_xlate: failed to set pin function\n"); |
| 2684 | if (s3c_gpio_setpull(pin, gpiospec->args[2])) | 2684 | if (s3c_gpio_setpull(pin, gpiospec->args[2] & 0xffff)) |
| 2685 | pr_warn("gpio_xlate: failed to set pin pull up/down\n"); | 2685 | pr_warn("gpio_xlate: failed to set pin pull up/down\n"); |
| 2686 | if (s5p_gpio_set_drvstr(pin, gpiospec->args[3])) | 2686 | if (s5p_gpio_set_drvstr(pin, gpiospec->args[3])) |
| 2687 | pr_warn("gpio_xlate: failed to set pin drive strength\n"); | 2687 | pr_warn("gpio_xlate: failed to set pin drive strength\n"); |
| 2688 | 2688 | ||
| 2689 | if (flags) | ||
| 2690 | *flags = gpiospec->args[2] >> 16; | ||
| 2691 | |||
| 2689 | return gpiospec->args[0]; | 2692 | return gpiospec->args[0]; |
| 2690 | } | 2693 | } |
| 2691 | 2694 | ||
diff --git a/drivers/gpio/gpio-sta2x11.c b/drivers/gpio/gpio-sta2x11.c index 38416be8ba11..6064fb376e11 100644 --- a/drivers/gpio/gpio-sta2x11.c +++ b/drivers/gpio/gpio-sta2x11.c | |||
| @@ -383,8 +383,9 @@ static int __devinit gsta_probe(struct platform_device *dev) | |||
| 383 | } | 383 | } |
| 384 | spin_lock_init(&chip->lock); | 384 | spin_lock_init(&chip->lock); |
| 385 | gsta_gpio_setup(chip); | 385 | gsta_gpio_setup(chip); |
| 386 | for (i = 0; i < GSTA_NR_GPIO; i++) | 386 | if (gpio_pdata) |
| 387 | gsta_set_config(chip, i, gpio_pdata->pinconfig[i]); | 387 | for (i = 0; i < GSTA_NR_GPIO; i++) |
| 388 | gsta_set_config(chip, i, gpio_pdata->pinconfig[i]); | ||
| 388 | 389 | ||
| 389 | /* 384 was used in previous code: be compatible for other drivers */ | 390 | /* 384 was used in previous code: be compatible for other drivers */ |
| 390 | err = irq_alloc_descs(-1, 384, GSTA_NR_GPIO, NUMA_NO_NODE); | 391 | err = irq_alloc_descs(-1, 384, GSTA_NR_GPIO, NUMA_NO_NODE); |
diff --git a/drivers/gpio/gpio-tps6586x.c b/drivers/gpio/gpio-tps6586x.c new file mode 100644 index 000000000000..2526b3bb0fae --- /dev/null +++ b/drivers/gpio/gpio-tps6586x.c | |||
| @@ -0,0 +1,158 @@ | |||
| 1 | /* | ||
| 2 | * TI TPS6586x GPIO driver | ||
| 3 | * | ||
| 4 | * Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved. | ||
| 5 | * Author: Laxman dewangan <ldewangan@nvidia.com> | ||
| 6 | * | ||
| 7 | * Based on tps6586x.c | ||
| 8 | * Copyright (c) 2010 CompuLab Ltd. | ||
| 9 | * Mike Rapoport <mike@compulab.co.il> | ||
| 10 | * | ||
| 11 | * This program is free software; you can redistribute it and/or modify it | ||
| 12 | * under the terms and conditions of the GNU General Public License, | ||
| 13 | * version 2, as published by the Free Software Foundation. | ||
| 14 | * | ||
| 15 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
| 16 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 17 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
| 18 | * more details. | ||
| 19 | * | ||
| 20 | * You should have received a copy of the GNU General Public License | ||
| 21 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 22 | */ | ||
| 23 | |||
| 24 | #include <linux/errno.h> | ||
| 25 | #include <linux/gpio.h> | ||
| 26 | #include <linux/kernel.h> | ||
| 27 | #include <linux/module.h> | ||
| 28 | #include <linux/mfd/tps6586x.h> | ||
| 29 | #include <linux/of_device.h> | ||
| 30 | #include <linux/platform_device.h> | ||
| 31 | |||
| 32 | /* GPIO control registers */ | ||
| 33 | #define TPS6586X_GPIOSET1 0x5d | ||
| 34 | #define TPS6586X_GPIOSET2 0x5e | ||
| 35 | |||
| 36 | struct tps6586x_gpio { | ||
| 37 | struct gpio_chip gpio_chip; | ||
| 38 | struct device *parent; | ||
| 39 | }; | ||
| 40 | |||
| 41 | static inline struct tps6586x_gpio *to_tps6586x_gpio(struct gpio_chip *chip) | ||
| 42 | { | ||
| 43 | return container_of(chip, struct tps6586x_gpio, gpio_chip); | ||
| 44 | } | ||
| 45 | |||
| 46 | static int tps6586x_gpio_get(struct gpio_chip *gc, unsigned offset) | ||
| 47 | { | ||
| 48 | struct tps6586x_gpio *tps6586x_gpio = to_tps6586x_gpio(gc); | ||
| 49 | uint8_t val; | ||
| 50 | int ret; | ||
| 51 | |||
| 52 | ret = tps6586x_read(tps6586x_gpio->parent, TPS6586X_GPIOSET2, &val); | ||
| 53 | if (ret) | ||
| 54 | return ret; | ||
| 55 | |||
| 56 | return !!(val & (1 << offset)); | ||
| 57 | } | ||
| 58 | |||
| 59 | static void tps6586x_gpio_set(struct gpio_chip *gc, unsigned offset, | ||
| 60 | int value) | ||
| 61 | { | ||
| 62 | struct tps6586x_gpio *tps6586x_gpio = to_tps6586x_gpio(gc); | ||
| 63 | |||
| 64 | tps6586x_update(tps6586x_gpio->parent, TPS6586X_GPIOSET2, | ||
| 65 | value << offset, 1 << offset); | ||
| 66 | } | ||
| 67 | |||
| 68 | static int tps6586x_gpio_output(struct gpio_chip *gc, unsigned offset, | ||
| 69 | int value) | ||
| 70 | { | ||
| 71 | struct tps6586x_gpio *tps6586x_gpio = to_tps6586x_gpio(gc); | ||
| 72 | uint8_t val, mask; | ||
| 73 | |||
| 74 | tps6586x_gpio_set(gc, offset, value); | ||
| 75 | |||
| 76 | val = 0x1 << (offset * 2); | ||
| 77 | mask = 0x3 << (offset * 2); | ||
| 78 | |||
| 79 | return tps6586x_update(tps6586x_gpio->parent, TPS6586X_GPIOSET1, | ||
| 80 | val, mask); | ||
| 81 | } | ||
| 82 | |||
| 83 | static int __devinit tps6586x_gpio_probe(struct platform_device *pdev) | ||
| 84 | { | ||
| 85 | struct tps6586x_platform_data *pdata; | ||
| 86 | struct tps6586x_gpio *tps6586x_gpio; | ||
| 87 | int ret; | ||
| 88 | |||
| 89 | pdata = dev_get_platdata(pdev->dev.parent); | ||
| 90 | tps6586x_gpio = devm_kzalloc(&pdev->dev, | ||
| 91 | sizeof(*tps6586x_gpio), GFP_KERNEL); | ||
| 92 | if (!tps6586x_gpio) { | ||
| 93 | dev_err(&pdev->dev, "Could not allocate tps6586x_gpio\n"); | ||
| 94 | return -ENOMEM; | ||
| 95 | } | ||
| 96 | |||
| 97 | tps6586x_gpio->parent = pdev->dev.parent; | ||
| 98 | |||
| 99 | tps6586x_gpio->gpio_chip.owner = THIS_MODULE; | ||
| 100 | tps6586x_gpio->gpio_chip.label = pdev->name; | ||
| 101 | tps6586x_gpio->gpio_chip.dev = &pdev->dev; | ||
| 102 | tps6586x_gpio->gpio_chip.ngpio = 4; | ||
| 103 | tps6586x_gpio->gpio_chip.can_sleep = 1; | ||
| 104 | |||
| 105 | /* FIXME: add handling of GPIOs as dedicated inputs */ | ||
| 106 | tps6586x_gpio->gpio_chip.direction_output = tps6586x_gpio_output; | ||
| 107 | tps6586x_gpio->gpio_chip.set = tps6586x_gpio_set; | ||
| 108 | tps6586x_gpio->gpio_chip.get = tps6586x_gpio_get; | ||
| 109 | |||
| 110 | #ifdef CONFIG_OF_GPIO | ||
| 111 | tps6586x_gpio->gpio_chip.of_node = pdev->dev.parent->of_node; | ||
| 112 | #endif | ||
| 113 | if (pdata && pdata->gpio_base) | ||
| 114 | tps6586x_gpio->gpio_chip.base = pdata->gpio_base; | ||
| 115 | else | ||
| 116 | tps6586x_gpio->gpio_chip.base = -1; | ||
| 117 | |||
| 118 | ret = gpiochip_add(&tps6586x_gpio->gpio_chip); | ||
| 119 | if (ret < 0) { | ||
| 120 | dev_err(&pdev->dev, "Could not register gpiochip, %d\n", ret); | ||
| 121 | return ret; | ||
| 122 | } | ||
| 123 | |||
| 124 | platform_set_drvdata(pdev, tps6586x_gpio); | ||
| 125 | |||
| 126 | return ret; | ||
| 127 | } | ||
| 128 | |||
| 129 | static int __devexit tps6586x_gpio_remove(struct platform_device *pdev) | ||
| 130 | { | ||
| 131 | struct tps6586x_gpio *tps6586x_gpio = platform_get_drvdata(pdev); | ||
| 132 | |||
| 133 | return gpiochip_remove(&tps6586x_gpio->gpio_chip); | ||
| 134 | } | ||
| 135 | |||
| 136 | static struct platform_driver tps6586x_gpio_driver = { | ||
| 137 | .driver.name = "tps6586x-gpio", | ||
| 138 | .driver.owner = THIS_MODULE, | ||
| 139 | .probe = tps6586x_gpio_probe, | ||
| 140 | .remove = __devexit_p(tps6586x_gpio_remove), | ||
| 141 | }; | ||
| 142 | |||
| 143 | static int __init tps6586x_gpio_init(void) | ||
| 144 | { | ||
| 145 | return platform_driver_register(&tps6586x_gpio_driver); | ||
| 146 | } | ||
| 147 | subsys_initcall(tps6586x_gpio_init); | ||
| 148 | |||
| 149 | static void __exit tps6586x_gpio_exit(void) | ||
| 150 | { | ||
| 151 | platform_driver_unregister(&tps6586x_gpio_driver); | ||
| 152 | } | ||
| 153 | module_exit(tps6586x_gpio_exit); | ||
| 154 | |||
| 155 | MODULE_ALIAS("platform:tps6586x-gpio"); | ||
| 156 | MODULE_DESCRIPTION("GPIO interface for TPS6586X PMIC"); | ||
| 157 | MODULE_AUTHOR("Laxman Dewangan <ldewangan@nvidia.com>"); | ||
| 158 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/gpio/gpio-tps65910.c b/drivers/gpio/gpio-tps65910.c index c1ad2884f2ed..11f29c82253c 100644 --- a/drivers/gpio/gpio-tps65910.c +++ b/drivers/gpio/gpio-tps65910.c | |||
| @@ -149,6 +149,9 @@ static int __devinit tps65910_gpio_probe(struct platform_device *pdev) | |||
| 149 | tps65910_gpio->gpio_chip.set = tps65910_gpio_set; | 149 | tps65910_gpio->gpio_chip.set = tps65910_gpio_set; |
| 150 | tps65910_gpio->gpio_chip.get = tps65910_gpio_get; | 150 | tps65910_gpio->gpio_chip.get = tps65910_gpio_get; |
| 151 | tps65910_gpio->gpio_chip.dev = &pdev->dev; | 151 | tps65910_gpio->gpio_chip.dev = &pdev->dev; |
| 152 | #ifdef CONFIG_OF_GPIO | ||
| 153 | tps65910_gpio->gpio_chip.of_node = tps65910->dev->of_node; | ||
| 154 | #endif | ||
| 152 | if (pdata && pdata->gpio_base) | 155 | if (pdata && pdata->gpio_base) |
| 153 | tps65910_gpio->gpio_chip.base = pdata->gpio_base; | 156 | tps65910_gpio->gpio_chip.base = pdata->gpio_base; |
| 154 | else | 157 | else |
diff --git a/drivers/gpio/gpio-wm8994.c b/drivers/gpio/gpio-wm8994.c index 92ea5350dfe9..1c764e779d80 100644 --- a/drivers/gpio/gpio-wm8994.c +++ b/drivers/gpio/gpio-wm8994.c | |||
| @@ -19,6 +19,7 @@ | |||
| 19 | #include <linux/mfd/core.h> | 19 | #include <linux/mfd/core.h> |
| 20 | #include <linux/platform_device.h> | 20 | #include <linux/platform_device.h> |
| 21 | #include <linux/seq_file.h> | 21 | #include <linux/seq_file.h> |
| 22 | #include <linux/regmap.h> | ||
| 22 | 23 | ||
| 23 | #include <linux/mfd/wm8994/core.h> | 24 | #include <linux/mfd/wm8994/core.h> |
| 24 | #include <linux/mfd/wm8994/pdata.h> | 25 | #include <linux/mfd/wm8994/pdata.h> |
| @@ -89,8 +90,11 @@ static int wm8994_gpio_direction_out(struct gpio_chip *chip, | |||
| 89 | struct wm8994_gpio *wm8994_gpio = to_wm8994_gpio(chip); | 90 | struct wm8994_gpio *wm8994_gpio = to_wm8994_gpio(chip); |
| 90 | struct wm8994 *wm8994 = wm8994_gpio->wm8994; | 91 | struct wm8994 *wm8994 = wm8994_gpio->wm8994; |
| 91 | 92 | ||
| 93 | if (value) | ||
| 94 | value = WM8994_GPN_LVL; | ||
| 95 | |||
| 92 | return wm8994_set_bits(wm8994, WM8994_GPIO_1 + offset, | 96 | return wm8994_set_bits(wm8994, WM8994_GPIO_1 + offset, |
| 93 | WM8994_GPN_DIR, 0); | 97 | WM8994_GPN_DIR | WM8994_GPN_LVL, value); |
| 94 | } | 98 | } |
| 95 | 99 | ||
| 96 | static void wm8994_gpio_set(struct gpio_chip *chip, unsigned offset, int value) | 100 | static void wm8994_gpio_set(struct gpio_chip *chip, unsigned offset, int value) |
| @@ -109,10 +113,7 @@ static int wm8994_gpio_to_irq(struct gpio_chip *chip, unsigned offset) | |||
| 109 | struct wm8994_gpio *wm8994_gpio = to_wm8994_gpio(chip); | 113 | struct wm8994_gpio *wm8994_gpio = to_wm8994_gpio(chip); |
| 110 | struct wm8994 *wm8994 = wm8994_gpio->wm8994; | 114 | struct wm8994 *wm8994 = wm8994_gpio->wm8994; |
| 111 | 115 | ||
| 112 | if (!wm8994->irq_base) | 116 | return regmap_irq_get_virq(wm8994->irq_data, offset); |
| 113 | return -EINVAL; | ||
| 114 | |||
| 115 | return wm8994->irq_base + offset; | ||
| 116 | } | 117 | } |
| 117 | 118 | ||
| 118 | 119 | ||
| @@ -251,7 +252,8 @@ static int __devinit wm8994_gpio_probe(struct platform_device *pdev) | |||
| 251 | struct wm8994_gpio *wm8994_gpio; | 252 | struct wm8994_gpio *wm8994_gpio; |
| 252 | int ret; | 253 | int ret; |
| 253 | 254 | ||
| 254 | wm8994_gpio = kzalloc(sizeof(*wm8994_gpio), GFP_KERNEL); | 255 | wm8994_gpio = devm_kzalloc(&pdev->dev, sizeof(*wm8994_gpio), |
| 256 | GFP_KERNEL); | ||
| 255 | if (wm8994_gpio == NULL) | 257 | if (wm8994_gpio == NULL) |
| 256 | return -ENOMEM; | 258 | return -ENOMEM; |
| 257 | 259 | ||
| @@ -276,20 +278,14 @@ static int __devinit wm8994_gpio_probe(struct platform_device *pdev) | |||
| 276 | return ret; | 278 | return ret; |
| 277 | 279 | ||
| 278 | err: | 280 | err: |
| 279 | kfree(wm8994_gpio); | ||
| 280 | return ret; | 281 | return ret; |
| 281 | } | 282 | } |
| 282 | 283 | ||
| 283 | static int __devexit wm8994_gpio_remove(struct platform_device *pdev) | 284 | static int __devexit wm8994_gpio_remove(struct platform_device *pdev) |
| 284 | { | 285 | { |
| 285 | struct wm8994_gpio *wm8994_gpio = platform_get_drvdata(pdev); | 286 | struct wm8994_gpio *wm8994_gpio = platform_get_drvdata(pdev); |
| 286 | int ret; | ||
| 287 | |||
| 288 | ret = gpiochip_remove(&wm8994_gpio->gpio_chip); | ||
| 289 | if (ret == 0) | ||
| 290 | kfree(wm8994_gpio); | ||
| 291 | 287 | ||
| 292 | return ret; | 288 | return gpiochip_remove(&wm8994_gpio->gpio_chip); |
| 293 | } | 289 | } |
| 294 | 290 | ||
| 295 | static struct platform_driver wm8994_gpio_driver = { | 291 | static struct platform_driver wm8994_gpio_driver = { |
diff --git a/drivers/gpio/gpiolib-of.c b/drivers/gpio/gpiolib-of.c index d18068a9f3ec..a18c4aa68b1e 100644 --- a/drivers/gpio/gpiolib-of.c +++ b/drivers/gpio/gpiolib-of.c | |||
| @@ -21,7 +21,7 @@ | |||
| 21 | #include <linux/of_gpio.h> | 21 | #include <linux/of_gpio.h> |
| 22 | #include <linux/slab.h> | 22 | #include <linux/slab.h> |
| 23 | 23 | ||
| 24 | /* Private data structure for of_gpiochip_is_match */ | 24 | /* Private data structure for of_gpiochip_find_and_xlate */ |
| 25 | struct gg_data { | 25 | struct gg_data { |
| 26 | enum of_gpio_flags *flags; | 26 | enum of_gpio_flags *flags; |
| 27 | struct of_phandle_args gpiospec; | 27 | struct of_phandle_args gpiospec; |
| @@ -62,7 +62,10 @@ static int of_gpiochip_find_and_xlate(struct gpio_chip *gc, void *data) | |||
| 62 | int of_get_named_gpio_flags(struct device_node *np, const char *propname, | 62 | int of_get_named_gpio_flags(struct device_node *np, const char *propname, |
| 63 | int index, enum of_gpio_flags *flags) | 63 | int index, enum of_gpio_flags *flags) |
| 64 | { | 64 | { |
| 65 | struct gg_data gg_data = { .flags = flags, .out_gpio = -ENODEV }; | 65 | /* Return -EPROBE_DEFER to support probe() functions to be called |
| 66 | * later when the GPIO actually becomes available | ||
| 67 | */ | ||
| 68 | struct gg_data gg_data = { .flags = flags, .out_gpio = -EPROBE_DEFER }; | ||
| 66 | int ret; | 69 | int ret; |
| 67 | 70 | ||
| 68 | /* .of_xlate might decide to not fill in the flags, so clear it. */ | 71 | /* .of_xlate might decide to not fill in the flags, so clear it. */ |
| @@ -73,7 +76,7 @@ int of_get_named_gpio_flags(struct device_node *np, const char *propname, | |||
| 73 | &gg_data.gpiospec); | 76 | &gg_data.gpiospec); |
| 74 | if (ret) { | 77 | if (ret) { |
| 75 | pr_debug("%s: can't parse gpios property\n", __func__); | 78 | pr_debug("%s: can't parse gpios property\n", __func__); |
| 76 | return -EINVAL; | 79 | return ret; |
| 77 | } | 80 | } |
| 78 | 81 | ||
| 79 | gpiochip_find(&gg_data, of_gpiochip_find_and_xlate); | 82 | gpiochip_find(&gg_data, of_gpiochip_find_and_xlate); |
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index 120b2a0e3167..de0213c9d11c 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c | |||
| @@ -1186,7 +1186,7 @@ int gpio_request(unsigned gpio, const char *label) | |||
| 1186 | { | 1186 | { |
| 1187 | struct gpio_desc *desc; | 1187 | struct gpio_desc *desc; |
| 1188 | struct gpio_chip *chip; | 1188 | struct gpio_chip *chip; |
| 1189 | int status = -EINVAL; | 1189 | int status = -EPROBE_DEFER; |
| 1190 | unsigned long flags; | 1190 | unsigned long flags; |
| 1191 | 1191 | ||
| 1192 | spin_lock_irqsave(&gpio_lock, flags); | 1192 | spin_lock_irqsave(&gpio_lock, flags); |
