diff options
Diffstat (limited to 'drivers/gpio')
33 files changed, 3442 insertions, 1755 deletions
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index e03653d69357..c4067d0141f7 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig | |||
| @@ -2,6 +2,14 @@ | |||
| 2 | # GPIO infrastructure and drivers | 2 | # GPIO infrastructure and drivers |
| 3 | # | 3 | # |
| 4 | 4 | ||
| 5 | config ARCH_HAVE_CUSTOM_GPIO_H | ||
| 6 | bool | ||
| 7 | help | ||
| 8 | Selecting this config option from the architecture Kconfig allows | ||
| 9 | the architecture to provide a custom asm/gpio.h implementation | ||
| 10 | overriding the default implementations. New uses of this are | ||
| 11 | strongly discouraged. | ||
| 12 | |||
| 5 | config ARCH_WANT_OPTIONAL_GPIOLIB | 13 | config ARCH_WANT_OPTIONAL_GPIOLIB |
| 6 | bool | 14 | bool |
| 7 | help | 15 | help |
| @@ -37,6 +45,10 @@ menuconfig GPIOLIB | |||
| 37 | 45 | ||
| 38 | if GPIOLIB | 46 | if GPIOLIB |
| 39 | 47 | ||
| 48 | config OF_GPIO | ||
| 49 | def_bool y | ||
| 50 | depends on OF && !SPARC | ||
| 51 | |||
| 40 | config DEBUG_GPIO | 52 | config DEBUG_GPIO |
| 41 | bool "Debug GPIO calls" | 53 | bool "Debug GPIO calls" |
| 42 | depends on DEBUG_KERNEL | 54 | depends on DEBUG_KERNEL |
| @@ -91,11 +103,25 @@ config GPIO_IT8761E | |||
| 91 | help | 103 | help |
| 92 | Say yes here to support GPIO functionality of IT8761E super I/O chip. | 104 | Say yes here to support GPIO functionality of IT8761E super I/O chip. |
| 93 | 105 | ||
| 106 | config GPIO_EM | ||
| 107 | tristate "Emma Mobile GPIO" | ||
| 108 | depends on ARM | ||
| 109 | help | ||
| 110 | Say yes here to support GPIO on Renesas Emma Mobile SoCs. | ||
| 111 | |||
| 94 | config GPIO_EP93XX | 112 | config GPIO_EP93XX |
| 95 | def_bool y | 113 | def_bool y |
| 96 | depends on ARCH_EP93XX | 114 | depends on ARCH_EP93XX |
| 97 | select GPIO_GENERIC | 115 | select GPIO_GENERIC |
| 98 | 116 | ||
| 117 | config GPIO_MM_LANTIQ | ||
| 118 | bool "Lantiq Memory mapped GPIOs" | ||
| 119 | depends on LANTIQ && SOC_XWAY | ||
| 120 | help | ||
| 121 | This enables support for memory mapped GPIOs on the External Bus Unit | ||
| 122 | (EBU) found on Lantiq SoCs. The gpios are output only as they are | ||
| 123 | created by attaching a 16bit latch to the bus. | ||
| 124 | |||
| 99 | config GPIO_MPC5200 | 125 | config GPIO_MPC5200 |
| 100 | def_bool y | 126 | def_bool y |
| 101 | depends on PPC_MPC52xx | 127 | depends on PPC_MPC52xx |
| @@ -149,6 +175,14 @@ config GPIO_PXA | |||
| 149 | help | 175 | help |
| 150 | Say yes here to support the PXA GPIO device | 176 | Say yes here to support the PXA GPIO device |
| 151 | 177 | ||
| 178 | config GPIO_STA2X11 | ||
| 179 | bool "STA2x11/ConneXt GPIO support" | ||
| 180 | depends on MFD_STA2X11 | ||
| 181 | select GENERIC_IRQ_CHIP | ||
| 182 | help | ||
| 183 | Say yes here to support the STA2x11/ConneXt GPIO device. | ||
| 184 | The GPIO module has 128 GPIO pins with alternate functions. | ||
| 185 | |||
| 152 | config GPIO_XILINX | 186 | config GPIO_XILINX |
| 153 | bool "Xilinx GPIO support" | 187 | bool "Xilinx GPIO support" |
| 154 | depends on PPC_OF || MICROBLAZE | 188 | depends on PPC_OF || MICROBLAZE |
| @@ -162,13 +196,13 @@ config GPIO_VR41XX | |||
| 162 | Say yes here to support the NEC VR4100 series General-purpose I/O Uint | 196 | Say yes here to support the NEC VR4100 series General-purpose I/O Uint |
| 163 | 197 | ||
| 164 | config GPIO_SCH | 198 | config GPIO_SCH |
| 165 | tristate "Intel SCH/TunnelCreek GPIO" | 199 | tristate "Intel SCH/TunnelCreek/Centerton GPIO" |
| 166 | depends on PCI && X86 | 200 | depends on PCI && X86 |
| 167 | select MFD_CORE | 201 | select MFD_CORE |
| 168 | select LPC_SCH | 202 | select LPC_SCH |
| 169 | help | 203 | help |
| 170 | Say yes here to support GPIO interface on Intel Poulsbo SCH | 204 | Say yes here to support GPIO interface on Intel Poulsbo SCH, |
| 171 | or Intel Tunnel Creek processor. | 205 | Intel Tunnel Creek processor or Intel Centerton processor. |
| 172 | The Intel SCH contains a total of 14 GPIO pins. Ten GPIOs are | 206 | The Intel SCH contains a total of 14 GPIO pins. Ten GPIOs are |
| 173 | powered by the core power rail and are turned off during sleep | 207 | powered by the core power rail and are turned off during sleep |
| 174 | modes (S3 and higher). The remaining four GPIOs are powered by | 208 | modes (S3 and higher). The remaining four GPIOs are powered by |
| @@ -177,6 +211,22 @@ config GPIO_SCH | |||
| 177 | system from the Suspend-to-RAM state. | 211 | system from the Suspend-to-RAM state. |
| 178 | The Intel Tunnel Creek processor has 5 GPIOs powered by the | 212 | The Intel Tunnel Creek processor has 5 GPIOs powered by the |
| 179 | core power rail and 9 from suspend power supply. | 213 | core power rail and 9 from suspend power supply. |
| 214 | The Intel Centerton processor has a total of 30 GPIO pins. | ||
| 215 | Twenty-one are powered by the core power rail and 9 from the | ||
| 216 | suspend power supply. | ||
| 217 | |||
| 218 | config GPIO_ICH | ||
| 219 | tristate "Intel ICH GPIO" | ||
| 220 | depends on PCI && X86 | ||
| 221 | select MFD_CORE | ||
| 222 | select LPC_ICH | ||
| 223 | help | ||
| 224 | Say yes here to support the GPIO functionality of a number of Intel | ||
| 225 | ICH-based chipsets. Currently supported devices: ICH6, ICH7, ICH8 | ||
| 226 | ICH9, ICH10, Series 5/3400 (eg Ibex Peak), Series 6/C200 (eg | ||
| 227 | Cougar Point), NM10 (Tiger Point), and 3100 (Whitmore Lake). | ||
| 228 | |||
| 229 | If unsure, say N. | ||
| 180 | 230 | ||
| 181 | config GPIO_VX855 | 231 | config GPIO_VX855 |
| 182 | tristate "VIA VX855/VX875 GPIO" | 232 | tristate "VIA VX855/VX875 GPIO" |
| @@ -243,7 +293,7 @@ config GPIO_MC9S08DZ60 | |||
| 243 | Select this to enable the MC9S08DZ60 GPIO driver | 293 | Select this to enable the MC9S08DZ60 GPIO driver |
| 244 | 294 | ||
| 245 | config GPIO_PCA953X | 295 | config GPIO_PCA953X |
| 246 | tristate "PCA953x, PCA955x, TCA64xx, and MAX7310 I/O ports" | 296 | tristate "PCA953x, PCA955x, PCA957x, TCA64xx, and MAX7310 I/O ports" |
| 247 | depends on I2C | 297 | depends on I2C |
| 248 | help | 298 | help |
| 249 | Say yes here to provide access to several register-oriented | 299 | Say yes here to provide access to several register-oriented |
| @@ -252,10 +302,11 @@ config GPIO_PCA953X | |||
| 252 | 302 | ||
| 253 | 4 bits: pca9536, pca9537 | 303 | 4 bits: pca9536, pca9537 |
| 254 | 304 | ||
| 255 | 8 bits: max7310, pca9534, pca9538, pca9554, pca9557, | 305 | 8 bits: max7310, max7315, pca6107, pca9534, pca9538, pca9554, |
| 256 | tca6408 | 306 | pca9556, pca9557, pca9574, tca6408 |
| 257 | 307 | ||
| 258 | 16 bits: pca9535, pca9539, pca9555, tca6416 | 308 | 16 bits: max7312, max7313, pca9535, pca9539, pca9555, pca9575, |
| 309 | tca6416 | ||
| 259 | 310 | ||
| 260 | config GPIO_PCA953X_IRQ | 311 | config GPIO_PCA953X_IRQ |
| 261 | bool "Interrupt controller support for PCA953x" | 312 | bool "Interrupt controller support for PCA953x" |
| @@ -288,6 +339,15 @@ config GPIO_PCF857X | |||
| 288 | This driver provides an in-kernel interface to those GPIOs using | 339 | This driver provides an in-kernel interface to those GPIOs using |
| 289 | platform-neutral GPIO calls. | 340 | platform-neutral GPIO calls. |
| 290 | 341 | ||
| 342 | config GPIO_RC5T583 | ||
| 343 | bool "RICOH RC5T583 GPIO" | ||
| 344 | depends on MFD_RC5T583 | ||
| 345 | help | ||
| 346 | Select this option to enable GPIO driver for the Ricoh RC5T583 | ||
| 347 | chip family. | ||
| 348 | This driver provides the support for driving/reading the gpio pins | ||
| 349 | of RC5T583 device through standard gpio library. | ||
| 350 | |||
| 291 | config GPIO_SX150X | 351 | config GPIO_SX150X |
| 292 | bool "Semtech SX150x I2C GPIO expander" | 352 | bool "Semtech SX150x I2C GPIO expander" |
| 293 | depends on I2C=y | 353 | depends on I2C=y |
| @@ -306,6 +366,16 @@ config GPIO_STMPE | |||
| 306 | This enables support for the GPIOs found on the STMPE I/O | 366 | This enables support for the GPIOs found on the STMPE I/O |
| 307 | Expanders. | 367 | Expanders. |
| 308 | 368 | ||
| 369 | config GPIO_STP_XWAY | ||
| 370 | bool "XWAY STP GPIOs" | ||
| 371 | depends on SOC_XWAY | ||
| 372 | help | ||
| 373 | This enables support for the Serial To Parallel (STP) unit found on | ||
| 374 | XWAY SoC. The STP allows the SoC to drive a shift registers cascade, | ||
| 375 | that can be up to 24 bit. This peripheral is aimed at driving leds. | ||
| 376 | Some of the gpios/leds can be auto updated by the soc with dsl and | ||
| 377 | phy status. | ||
| 378 | |||
| 309 | config GPIO_TC3589X | 379 | config GPIO_TC3589X |
| 310 | bool "TC3589X GPIOs" | 380 | bool "TC3589X GPIOs" |
| 311 | depends on MFD_TC3589X | 381 | depends on MFD_TC3589X |
| @@ -399,6 +469,7 @@ config GPIO_BT8XX | |||
| 399 | config GPIO_LANGWELL | 469 | config GPIO_LANGWELL |
| 400 | bool "Intel Langwell/Penwell GPIO support" | 470 | bool "Intel Langwell/Penwell GPIO support" |
| 401 | depends on PCI && X86 | 471 | depends on PCI && X86 |
| 472 | select IRQ_DOMAIN | ||
| 402 | help | 473 | help |
| 403 | Say Y here to support Intel Langwell/Penwell GPIO. | 474 | Say Y here to support Intel Langwell/Penwell GPIO. |
| 404 | 475 | ||
| @@ -514,4 +585,12 @@ config GPIO_TPS65910 | |||
| 514 | help | 585 | help |
| 515 | Select this option to enable GPIO driver for the TPS65910 | 586 | Select this option to enable GPIO driver for the TPS65910 |
| 516 | chip family. | 587 | chip family. |
| 588 | |||
| 589 | config GPIO_MSIC | ||
| 590 | bool "Intel MSIC mixed signal gpio support" | ||
| 591 | depends on MFD_INTEL_MSIC | ||
| 592 | help | ||
| 593 | Enable support for GPIO on intel MSIC controllers found in | ||
| 594 | intel MID devices | ||
| 595 | |||
| 517 | endif | 596 | endif |
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile index 007f54bd0081..0f55662002c3 100644 --- a/drivers/gpio/Makefile +++ b/drivers/gpio/Makefile | |||
| @@ -3,6 +3,7 @@ | |||
| 3 | ccflags-$(CONFIG_DEBUG_GPIO) += -DDEBUG | 3 | ccflags-$(CONFIG_DEBUG_GPIO) += -DDEBUG |
| 4 | 4 | ||
| 5 | obj-$(CONFIG_GPIOLIB) += gpiolib.o devres.o | 5 | obj-$(CONFIG_GPIOLIB) += gpiolib.o devres.o |
| 6 | obj-$(CONFIG_OF_GPIO) += gpiolib-of.o | ||
| 6 | 7 | ||
| 7 | # Device drivers. Generally keep list sorted alphabetically | 8 | # Device drivers. Generally keep list sorted alphabetically |
| 8 | obj-$(CONFIG_GPIO_GENERIC) += gpio-generic.o | 9 | obj-$(CONFIG_GPIO_GENERIC) += gpio-generic.o |
| @@ -15,8 +16,10 @@ obj-$(CONFIG_GPIO_BT8XX) += gpio-bt8xx.o | |||
| 15 | obj-$(CONFIG_GPIO_CS5535) += gpio-cs5535.o | 16 | obj-$(CONFIG_GPIO_CS5535) += gpio-cs5535.o |
| 16 | obj-$(CONFIG_GPIO_DA9052) += gpio-da9052.o | 17 | obj-$(CONFIG_GPIO_DA9052) += gpio-da9052.o |
| 17 | obj-$(CONFIG_ARCH_DAVINCI) += gpio-davinci.o | 18 | obj-$(CONFIG_ARCH_DAVINCI) += gpio-davinci.o |
| 19 | obj-$(CONFIG_GPIO_EM) += gpio-em.o | ||
| 18 | obj-$(CONFIG_GPIO_EP93XX) += gpio-ep93xx.o | 20 | obj-$(CONFIG_GPIO_EP93XX) += gpio-ep93xx.o |
| 19 | obj-$(CONFIG_GPIO_GE_FPGA) += gpio-ge.o | 21 | obj-$(CONFIG_GPIO_GE_FPGA) += gpio-ge.o |
| 22 | obj-$(CONFIG_GPIO_ICH) += gpio-ich.o | ||
| 20 | obj-$(CONFIG_GPIO_IT8761E) += gpio-it8761e.o | 23 | obj-$(CONFIG_GPIO_IT8761E) += gpio-it8761e.o |
| 21 | obj-$(CONFIG_GPIO_JANZ_TTL) += gpio-janz-ttl.o | 24 | obj-$(CONFIG_GPIO_JANZ_TTL) += gpio-janz-ttl.o |
| 22 | obj-$(CONFIG_ARCH_KS8695) += gpio-ks8695.o | 25 | obj-$(CONFIG_ARCH_KS8695) += gpio-ks8695.o |
| @@ -30,25 +33,29 @@ obj-$(CONFIG_GPIO_MC33880) += gpio-mc33880.o | |||
| 30 | obj-$(CONFIG_GPIO_MC9S08DZ60) += gpio-mc9s08dz60.o | 33 | obj-$(CONFIG_GPIO_MC9S08DZ60) += gpio-mc9s08dz60.o |
| 31 | obj-$(CONFIG_GPIO_MCP23S08) += gpio-mcp23s08.o | 34 | obj-$(CONFIG_GPIO_MCP23S08) += gpio-mcp23s08.o |
| 32 | obj-$(CONFIG_GPIO_ML_IOH) += gpio-ml-ioh.o | 35 | obj-$(CONFIG_GPIO_ML_IOH) += gpio-ml-ioh.o |
| 36 | obj-$(CONFIG_GPIO_MM_LANTIQ) += gpio-mm-lantiq.o | ||
| 33 | obj-$(CONFIG_GPIO_MPC5200) += gpio-mpc5200.o | 37 | obj-$(CONFIG_GPIO_MPC5200) += gpio-mpc5200.o |
| 34 | obj-$(CONFIG_GPIO_MPC8XXX) += gpio-mpc8xxx.o | 38 | obj-$(CONFIG_GPIO_MPC8XXX) += gpio-mpc8xxx.o |
| 39 | obj-$(CONFIG_GPIO_MSIC) += gpio-msic.o | ||
| 35 | obj-$(CONFIG_GPIO_MSM_V1) += gpio-msm-v1.o | 40 | obj-$(CONFIG_GPIO_MSM_V1) += gpio-msm-v1.o |
| 36 | obj-$(CONFIG_GPIO_MSM_V2) += gpio-msm-v2.o | 41 | obj-$(CONFIG_GPIO_MSM_V2) += gpio-msm-v2.o |
| 37 | obj-$(CONFIG_GPIO_MXC) += gpio-mxc.o | 42 | obj-$(CONFIG_GPIO_MXC) += gpio-mxc.o |
| 38 | obj-$(CONFIG_GPIO_MXS) += gpio-mxs.o | 43 | obj-$(CONFIG_GPIO_MXS) += gpio-mxs.o |
| 39 | obj-$(CONFIG_PLAT_NOMADIK) += gpio-nomadik.o | ||
| 40 | obj-$(CONFIG_ARCH_OMAP) += gpio-omap.o | 44 | obj-$(CONFIG_ARCH_OMAP) += gpio-omap.o |
| 41 | obj-$(CONFIG_GPIO_PCA953X) += gpio-pca953x.o | 45 | obj-$(CONFIG_GPIO_PCA953X) += gpio-pca953x.o |
| 42 | obj-$(CONFIG_GPIO_PCF857X) += gpio-pcf857x.o | 46 | obj-$(CONFIG_GPIO_PCF857X) += gpio-pcf857x.o |
| 43 | obj-$(CONFIG_GPIO_PCH) += gpio-pch.o | 47 | obj-$(CONFIG_GPIO_PCH) += gpio-pch.o |
| 44 | obj-$(CONFIG_GPIO_PL061) += gpio-pl061.o | 48 | obj-$(CONFIG_GPIO_PL061) += gpio-pl061.o |
| 45 | obj-$(CONFIG_GPIO_PXA) += gpio-pxa.o | 49 | obj-$(CONFIG_GPIO_PXA) += gpio-pxa.o |
| 50 | obj-$(CONFIG_GPIO_RC5T583) += gpio-rc5t583.o | ||
| 46 | obj-$(CONFIG_GPIO_RDC321X) += gpio-rdc321x.o | 51 | obj-$(CONFIG_GPIO_RDC321X) += gpio-rdc321x.o |
| 47 | obj-$(CONFIG_PLAT_SAMSUNG) += gpio-samsung.o | 52 | obj-$(CONFIG_PLAT_SAMSUNG) += gpio-samsung.o |
| 48 | obj-$(CONFIG_ARCH_SA1100) += gpio-sa1100.o | 53 | obj-$(CONFIG_ARCH_SA1100) += gpio-sa1100.o |
| 49 | obj-$(CONFIG_GPIO_SCH) += gpio-sch.o | 54 | obj-$(CONFIG_GPIO_SCH) += gpio-sch.o |
| 50 | obj-$(CONFIG_GPIO_SODAVILLE) += gpio-sodaville.o | 55 | obj-$(CONFIG_GPIO_SODAVILLE) += gpio-sodaville.o |
| 56 | obj-$(CONFIG_GPIO_STA2X11) += gpio-sta2x11.o | ||
| 51 | obj-$(CONFIG_GPIO_STMPE) += gpio-stmpe.o | 57 | obj-$(CONFIG_GPIO_STMPE) += gpio-stmpe.o |
| 58 | obj-$(CONFIG_GPIO_STP_XWAY) += gpio-stp-xway.o | ||
| 52 | obj-$(CONFIG_GPIO_SX150X) += gpio-sx150x.o | 59 | obj-$(CONFIG_GPIO_SX150X) += gpio-sx150x.o |
| 53 | obj-$(CONFIG_GPIO_TC3589X) += gpio-tc3589x.o | 60 | obj-$(CONFIG_GPIO_TC3589X) += gpio-tc3589x.o |
| 54 | obj-$(CONFIG_ARCH_TEGRA) += gpio-tegra.o | 61 | obj-$(CONFIG_ARCH_TEGRA) += gpio-tegra.o |
diff --git a/drivers/gpio/devres.c b/drivers/gpio/devres.c index 3dd29399cef5..9e9947cb86a3 100644 --- a/drivers/gpio/devres.c +++ b/drivers/gpio/devres.c | |||
| @@ -71,6 +71,35 @@ int devm_gpio_request(struct device *dev, unsigned gpio, const char *label) | |||
| 71 | EXPORT_SYMBOL(devm_gpio_request); | 71 | EXPORT_SYMBOL(devm_gpio_request); |
| 72 | 72 | ||
| 73 | /** | 73 | /** |
| 74 | * devm_gpio_request_one - request a single GPIO with initial setup | ||
| 75 | * @dev: device to request for | ||
| 76 | * @gpio: the GPIO number | ||
| 77 | * @flags: GPIO configuration as specified by GPIOF_* | ||
| 78 | * @label: a literal description string of this GPIO | ||
| 79 | */ | ||
| 80 | int devm_gpio_request_one(struct device *dev, unsigned gpio, | ||
| 81 | unsigned long flags, const char *label) | ||
| 82 | { | ||
| 83 | unsigned *dr; | ||
| 84 | int rc; | ||
| 85 | |||
| 86 | dr = devres_alloc(devm_gpio_release, sizeof(unsigned), GFP_KERNEL); | ||
| 87 | if (!dr) | ||
| 88 | return -ENOMEM; | ||
| 89 | |||
| 90 | rc = gpio_request_one(gpio, flags, label); | ||
| 91 | if (rc) { | ||
| 92 | devres_free(dr); | ||
| 93 | return rc; | ||
| 94 | } | ||
| 95 | |||
| 96 | *dr = gpio; | ||
| 97 | devres_add(dev, dr); | ||
| 98 | |||
| 99 | return 0; | ||
| 100 | } | ||
| 101 | |||
| 102 | /** | ||
| 74 | * devm_gpio_free - free an interrupt | 103 | * devm_gpio_free - free an interrupt |
| 75 | * @dev: device to free gpio for | 104 | * @dev: device to free gpio for |
| 76 | * @gpio: gpio to free | 105 | * @gpio: gpio to free |
| @@ -83,8 +112,7 @@ EXPORT_SYMBOL(devm_gpio_request); | |||
| 83 | void devm_gpio_free(struct device *dev, unsigned int gpio) | 112 | void devm_gpio_free(struct device *dev, unsigned int gpio) |
| 84 | { | 113 | { |
| 85 | 114 | ||
| 86 | WARN_ON(devres_destroy(dev, devm_gpio_release, devm_gpio_match, | 115 | WARN_ON(devres_release(dev, devm_gpio_release, devm_gpio_match, |
| 87 | &gpio)); | 116 | &gpio)); |
| 88 | gpio_free(gpio); | ||
| 89 | } | 117 | } |
| 90 | EXPORT_SYMBOL(devm_gpio_free); | 118 | EXPORT_SYMBOL(devm_gpio_free); |
diff --git a/drivers/gpio/gpio-bt8xx.c b/drivers/gpio/gpio-bt8xx.c index 5ca4098ba092..e4cc7eb69bb2 100644 --- a/drivers/gpio/gpio-bt8xx.c +++ b/drivers/gpio/gpio-bt8xx.c | |||
| @@ -328,17 +328,7 @@ static struct pci_driver bt8xxgpio_pci_driver = { | |||
| 328 | .resume = bt8xxgpio_resume, | 328 | .resume = bt8xxgpio_resume, |
| 329 | }; | 329 | }; |
| 330 | 330 | ||
| 331 | static int __init bt8xxgpio_init(void) | 331 | module_pci_driver(bt8xxgpio_pci_driver); |
| 332 | { | ||
| 333 | return pci_register_driver(&bt8xxgpio_pci_driver); | ||
| 334 | } | ||
| 335 | module_init(bt8xxgpio_init) | ||
| 336 | |||
| 337 | static void __exit bt8xxgpio_exit(void) | ||
| 338 | { | ||
| 339 | pci_unregister_driver(&bt8xxgpio_pci_driver); | ||
| 340 | } | ||
| 341 | module_exit(bt8xxgpio_exit) | ||
| 342 | 332 | ||
| 343 | MODULE_LICENSE("GPL"); | 333 | MODULE_LICENSE("GPL"); |
| 344 | MODULE_AUTHOR("Michael Buesch"); | 334 | MODULE_AUTHOR("Michael Buesch"); |
diff --git a/drivers/gpio/gpio-em.c b/drivers/gpio/gpio-em.c new file mode 100644 index 000000000000..150d9768811d --- /dev/null +++ b/drivers/gpio/gpio-em.c | |||
| @@ -0,0 +1,418 @@ | |||
| 1 | /* | ||
| 2 | * Emma Mobile GPIO Support - GIO | ||
| 3 | * | ||
| 4 | * Copyright (C) 2012 Magnus Damm | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or modify | ||
| 7 | * it under the terms of the GNU General Public License as published by | ||
| 8 | * the Free Software Foundation; either version 2 of the License | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program; if not, write to the Free Software | ||
| 17 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
| 18 | */ | ||
| 19 | |||
| 20 | #include <linux/init.h> | ||
| 21 | #include <linux/platform_device.h> | ||
| 22 | #include <linux/spinlock.h> | ||
| 23 | #include <linux/interrupt.h> | ||
| 24 | #include <linux/ioport.h> | ||
| 25 | #include <linux/io.h> | ||
| 26 | #include <linux/irq.h> | ||
| 27 | #include <linux/irqdomain.h> | ||
| 28 | #include <linux/bitops.h> | ||
| 29 | #include <linux/err.h> | ||
| 30 | #include <linux/gpio.h> | ||
| 31 | #include <linux/slab.h> | ||
| 32 | #include <linux/module.h> | ||
| 33 | #include <linux/platform_data/gpio-em.h> | ||
| 34 | |||
| 35 | struct em_gio_priv { | ||
| 36 | void __iomem *base0; | ||
| 37 | void __iomem *base1; | ||
| 38 | unsigned int irq_base; | ||
| 39 | spinlock_t sense_lock; | ||
| 40 | struct platform_device *pdev; | ||
| 41 | struct gpio_chip gpio_chip; | ||
| 42 | struct irq_chip irq_chip; | ||
| 43 | struct irq_domain *irq_domain; | ||
| 44 | }; | ||
| 45 | |||
| 46 | #define GIO_E1 0x00 | ||
| 47 | #define GIO_E0 0x04 | ||
| 48 | #define GIO_EM 0x04 | ||
| 49 | #define GIO_OL 0x08 | ||
| 50 | #define GIO_OH 0x0c | ||
| 51 | #define GIO_I 0x10 | ||
| 52 | #define GIO_IIA 0x14 | ||
| 53 | #define GIO_IEN 0x18 | ||
| 54 | #define GIO_IDS 0x1c | ||
| 55 | #define GIO_IIM 0x1c | ||
| 56 | #define GIO_RAW 0x20 | ||
| 57 | #define GIO_MST 0x24 | ||
| 58 | #define GIO_IIR 0x28 | ||
| 59 | |||
| 60 | #define GIO_IDT0 0x40 | ||
| 61 | #define GIO_IDT1 0x44 | ||
| 62 | #define GIO_IDT2 0x48 | ||
| 63 | #define GIO_IDT3 0x4c | ||
| 64 | #define GIO_RAWBL 0x50 | ||
| 65 | #define GIO_RAWBH 0x54 | ||
| 66 | #define GIO_IRBL 0x58 | ||
| 67 | #define GIO_IRBH 0x5c | ||
| 68 | |||
| 69 | #define GIO_IDT(n) (GIO_IDT0 + ((n) * 4)) | ||
| 70 | |||
| 71 | static inline unsigned long em_gio_read(struct em_gio_priv *p, int offs) | ||
| 72 | { | ||
| 73 | if (offs < GIO_IDT0) | ||
| 74 | return ioread32(p->base0 + offs); | ||
| 75 | else | ||
| 76 | return ioread32(p->base1 + (offs - GIO_IDT0)); | ||
| 77 | } | ||
| 78 | |||
| 79 | static inline void em_gio_write(struct em_gio_priv *p, int offs, | ||
| 80 | unsigned long value) | ||
| 81 | { | ||
| 82 | if (offs < GIO_IDT0) | ||
| 83 | iowrite32(value, p->base0 + offs); | ||
| 84 | else | ||
| 85 | iowrite32(value, p->base1 + (offs - GIO_IDT0)); | ||
| 86 | } | ||
| 87 | |||
| 88 | static inline struct em_gio_priv *irq_to_priv(struct irq_data *d) | ||
| 89 | { | ||
| 90 | struct irq_chip *chip = irq_data_get_irq_chip(d); | ||
| 91 | return container_of(chip, struct em_gio_priv, irq_chip); | ||
| 92 | } | ||
| 93 | |||
| 94 | static void em_gio_irq_disable(struct irq_data *d) | ||
| 95 | { | ||
| 96 | struct em_gio_priv *p = irq_to_priv(d); | ||
| 97 | |||
| 98 | em_gio_write(p, GIO_IDS, BIT(irqd_to_hwirq(d))); | ||
| 99 | } | ||
| 100 | |||
| 101 | static void em_gio_irq_enable(struct irq_data *d) | ||
| 102 | { | ||
| 103 | struct em_gio_priv *p = irq_to_priv(d); | ||
| 104 | |||
| 105 | em_gio_write(p, GIO_IEN, BIT(irqd_to_hwirq(d))); | ||
| 106 | } | ||
| 107 | |||
| 108 | #define GIO_ASYNC(x) (x + 8) | ||
| 109 | |||
| 110 | static unsigned char em_gio_sense_table[IRQ_TYPE_SENSE_MASK + 1] = { | ||
| 111 | [IRQ_TYPE_EDGE_RISING] = GIO_ASYNC(0x00), | ||
| 112 | [IRQ_TYPE_EDGE_FALLING] = GIO_ASYNC(0x01), | ||
| 113 | [IRQ_TYPE_LEVEL_HIGH] = GIO_ASYNC(0x02), | ||
| 114 | [IRQ_TYPE_LEVEL_LOW] = GIO_ASYNC(0x03), | ||
| 115 | [IRQ_TYPE_EDGE_BOTH] = GIO_ASYNC(0x04), | ||
| 116 | }; | ||
| 117 | |||
| 118 | static int em_gio_irq_set_type(struct irq_data *d, unsigned int type) | ||
| 119 | { | ||
| 120 | unsigned char value = em_gio_sense_table[type & IRQ_TYPE_SENSE_MASK]; | ||
| 121 | struct em_gio_priv *p = irq_to_priv(d); | ||
| 122 | unsigned int reg, offset, shift; | ||
| 123 | unsigned long flags; | ||
| 124 | unsigned long tmp; | ||
| 125 | |||
| 126 | if (!value) | ||
| 127 | return -EINVAL; | ||
| 128 | |||
| 129 | offset = irqd_to_hwirq(d); | ||
| 130 | |||
| 131 | pr_debug("gio: sense irq = %d, mode = %d\n", offset, value); | ||
| 132 | |||
| 133 | /* 8 x 4 bit fields in 4 IDT registers */ | ||
| 134 | reg = GIO_IDT(offset >> 3); | ||
| 135 | shift = (offset & 0x07) << 4; | ||
| 136 | |||
| 137 | spin_lock_irqsave(&p->sense_lock, flags); | ||
| 138 | |||
| 139 | /* disable the interrupt in IIA */ | ||
| 140 | tmp = em_gio_read(p, GIO_IIA); | ||
| 141 | tmp &= ~BIT(offset); | ||
| 142 | em_gio_write(p, GIO_IIA, tmp); | ||
| 143 | |||
| 144 | /* change the sense setting in IDT */ | ||
| 145 | tmp = em_gio_read(p, reg); | ||
| 146 | tmp &= ~(0xf << shift); | ||
| 147 | tmp |= value << shift; | ||
| 148 | em_gio_write(p, reg, tmp); | ||
| 149 | |||
| 150 | /* clear pending interrupts */ | ||
| 151 | em_gio_write(p, GIO_IIR, BIT(offset)); | ||
| 152 | |||
| 153 | /* enable the interrupt in IIA */ | ||
| 154 | tmp = em_gio_read(p, GIO_IIA); | ||
| 155 | tmp |= BIT(offset); | ||
| 156 | em_gio_write(p, GIO_IIA, tmp); | ||
| 157 | |||
| 158 | spin_unlock_irqrestore(&p->sense_lock, flags); | ||
| 159 | |||
| 160 | return 0; | ||
| 161 | } | ||
| 162 | |||
| 163 | static irqreturn_t em_gio_irq_handler(int irq, void *dev_id) | ||
| 164 | { | ||
| 165 | struct em_gio_priv *p = dev_id; | ||
| 166 | unsigned long pending; | ||
| 167 | unsigned int offset, irqs_handled = 0; | ||
| 168 | |||
| 169 | while ((pending = em_gio_read(p, GIO_MST))) { | ||
| 170 | offset = __ffs(pending); | ||
| 171 | em_gio_write(p, GIO_IIR, BIT(offset)); | ||
| 172 | generic_handle_irq(irq_find_mapping(p->irq_domain, offset)); | ||
| 173 | irqs_handled++; | ||
| 174 | } | ||
| 175 | |||
| 176 | return irqs_handled ? IRQ_HANDLED : IRQ_NONE; | ||
| 177 | } | ||
| 178 | |||
| 179 | static inline struct em_gio_priv *gpio_to_priv(struct gpio_chip *chip) | ||
| 180 | { | ||
| 181 | return container_of(chip, struct em_gio_priv, gpio_chip); | ||
| 182 | } | ||
| 183 | |||
| 184 | static int em_gio_direction_input(struct gpio_chip *chip, unsigned offset) | ||
| 185 | { | ||
| 186 | em_gio_write(gpio_to_priv(chip), GIO_E0, BIT(offset)); | ||
| 187 | return 0; | ||
| 188 | } | ||
| 189 | |||
| 190 | static int em_gio_get(struct gpio_chip *chip, unsigned offset) | ||
| 191 | { | ||
| 192 | return (int)(em_gio_read(gpio_to_priv(chip), GIO_I) & BIT(offset)); | ||
| 193 | } | ||
| 194 | |||
| 195 | static void __em_gio_set(struct gpio_chip *chip, unsigned int reg, | ||
| 196 | unsigned shift, int value) | ||
| 197 | { | ||
| 198 | /* upper 16 bits contains mask and lower 16 actual value */ | ||
| 199 | em_gio_write(gpio_to_priv(chip), reg, | ||
| 200 | (1 << (shift + 16)) | (value << shift)); | ||
| 201 | } | ||
| 202 | |||
| 203 | static void em_gio_set(struct gpio_chip *chip, unsigned offset, int value) | ||
| 204 | { | ||
| 205 | /* output is split into two registers */ | ||
| 206 | if (offset < 16) | ||
| 207 | __em_gio_set(chip, GIO_OL, offset, value); | ||
| 208 | else | ||
| 209 | __em_gio_set(chip, GIO_OH, offset - 16, value); | ||
| 210 | } | ||
| 211 | |||
| 212 | static int em_gio_direction_output(struct gpio_chip *chip, unsigned offset, | ||
| 213 | int value) | ||
| 214 | { | ||
| 215 | /* write GPIO value to output before selecting output mode of pin */ | ||
| 216 | em_gio_set(chip, offset, value); | ||
| 217 | em_gio_write(gpio_to_priv(chip), GIO_E1, BIT(offset)); | ||
| 218 | return 0; | ||
| 219 | } | ||
| 220 | |||
| 221 | static int em_gio_to_irq(struct gpio_chip *chip, unsigned offset) | ||
| 222 | { | ||
| 223 | return irq_find_mapping(gpio_to_priv(chip)->irq_domain, offset); | ||
| 224 | } | ||
| 225 | |||
| 226 | static int em_gio_irq_domain_map(struct irq_domain *h, unsigned int virq, | ||
| 227 | irq_hw_number_t hw) | ||
| 228 | { | ||
| 229 | struct em_gio_priv *p = h->host_data; | ||
| 230 | |||
| 231 | pr_debug("gio: map hw irq = %d, virq = %d\n", (int)hw, virq); | ||
| 232 | |||
| 233 | irq_set_chip_data(virq, h->host_data); | ||
| 234 | irq_set_chip_and_handler(virq, &p->irq_chip, handle_level_irq); | ||
| 235 | set_irq_flags(virq, IRQF_VALID); /* kill me now */ | ||
| 236 | return 0; | ||
| 237 | } | ||
| 238 | |||
| 239 | static struct irq_domain_ops em_gio_irq_domain_ops = { | ||
| 240 | .map = em_gio_irq_domain_map, | ||
| 241 | }; | ||
| 242 | |||
| 243 | static int __devinit em_gio_irq_domain_init(struct em_gio_priv *p) | ||
| 244 | { | ||
| 245 | struct platform_device *pdev = p->pdev; | ||
| 246 | struct gpio_em_config *pdata = pdev->dev.platform_data; | ||
| 247 | |||
| 248 | p->irq_base = irq_alloc_descs(pdata->irq_base, 0, | ||
| 249 | pdata->number_of_pins, numa_node_id()); | ||
| 250 | if (IS_ERR_VALUE(p->irq_base)) { | ||
| 251 | dev_err(&pdev->dev, "cannot get irq_desc\n"); | ||
| 252 | return -ENXIO; | ||
| 253 | } | ||
| 254 | pr_debug("gio: hw base = %d, nr = %d, sw base = %d\n", | ||
| 255 | pdata->gpio_base, pdata->number_of_pins, p->irq_base); | ||
| 256 | |||
| 257 | p->irq_domain = irq_domain_add_legacy(pdev->dev.of_node, | ||
| 258 | pdata->number_of_pins, | ||
| 259 | p->irq_base, 0, | ||
| 260 | &em_gio_irq_domain_ops, p); | ||
| 261 | if (!p->irq_domain) { | ||
| 262 | irq_free_descs(p->irq_base, pdata->number_of_pins); | ||
| 263 | return -ENXIO; | ||
| 264 | } | ||
| 265 | |||
| 266 | return 0; | ||
| 267 | } | ||
| 268 | |||
| 269 | static void __devexit em_gio_irq_domain_cleanup(struct em_gio_priv *p) | ||
| 270 | { | ||
| 271 | struct gpio_em_config *pdata = p->pdev->dev.platform_data; | ||
| 272 | |||
| 273 | irq_free_descs(p->irq_base, pdata->number_of_pins); | ||
| 274 | /* FIXME: irq domain wants to be freed! */ | ||
| 275 | } | ||
| 276 | |||
| 277 | static int __devinit em_gio_probe(struct platform_device *pdev) | ||
| 278 | { | ||
| 279 | struct gpio_em_config *pdata = pdev->dev.platform_data; | ||
| 280 | struct em_gio_priv *p; | ||
| 281 | struct resource *io[2], *irq[2]; | ||
| 282 | struct gpio_chip *gpio_chip; | ||
| 283 | struct irq_chip *irq_chip; | ||
| 284 | const char *name = dev_name(&pdev->dev); | ||
| 285 | int ret; | ||
| 286 | |||
| 287 | p = kzalloc(sizeof(*p), GFP_KERNEL); | ||
| 288 | if (!p) { | ||
| 289 | dev_err(&pdev->dev, "failed to allocate driver data\n"); | ||
| 290 | ret = -ENOMEM; | ||
| 291 | goto err0; | ||
| 292 | } | ||
| 293 | |||
| 294 | p->pdev = pdev; | ||
| 295 | platform_set_drvdata(pdev, p); | ||
| 296 | spin_lock_init(&p->sense_lock); | ||
| 297 | |||
| 298 | io[0] = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
| 299 | io[1] = platform_get_resource(pdev, IORESOURCE_MEM, 1); | ||
| 300 | irq[0] = platform_get_resource(pdev, IORESOURCE_IRQ, 0); | ||
| 301 | irq[1] = platform_get_resource(pdev, IORESOURCE_IRQ, 1); | ||
| 302 | |||
| 303 | if (!io[0] || !io[1] || !irq[0] || !irq[1] || !pdata) { | ||
| 304 | dev_err(&pdev->dev, "missing IRQ, IOMEM or configuration\n"); | ||
| 305 | ret = -EINVAL; | ||
| 306 | goto err1; | ||
| 307 | } | ||
| 308 | |||
| 309 | p->base0 = ioremap_nocache(io[0]->start, resource_size(io[0])); | ||
| 310 | if (!p->base0) { | ||
| 311 | dev_err(&pdev->dev, "failed to remap low I/O memory\n"); | ||
| 312 | ret = -ENXIO; | ||
| 313 | goto err1; | ||
| 314 | } | ||
| 315 | |||
| 316 | p->base1 = ioremap_nocache(io[1]->start, resource_size(io[1])); | ||
| 317 | if (!p->base1) { | ||
| 318 | dev_err(&pdev->dev, "failed to remap high I/O memory\n"); | ||
| 319 | ret = -ENXIO; | ||
| 320 | goto err2; | ||
| 321 | } | ||
| 322 | |||
| 323 | gpio_chip = &p->gpio_chip; | ||
| 324 | gpio_chip->direction_input = em_gio_direction_input; | ||
| 325 | gpio_chip->get = em_gio_get; | ||
| 326 | gpio_chip->direction_output = em_gio_direction_output; | ||
| 327 | gpio_chip->set = em_gio_set; | ||
| 328 | gpio_chip->to_irq = em_gio_to_irq; | ||
| 329 | gpio_chip->label = name; | ||
| 330 | gpio_chip->owner = THIS_MODULE; | ||
| 331 | gpio_chip->base = pdata->gpio_base; | ||
| 332 | gpio_chip->ngpio = pdata->number_of_pins; | ||
| 333 | |||
| 334 | irq_chip = &p->irq_chip; | ||
| 335 | irq_chip->name = name; | ||
| 336 | irq_chip->irq_mask = em_gio_irq_disable; | ||
| 337 | irq_chip->irq_unmask = em_gio_irq_enable; | ||
| 338 | irq_chip->irq_enable = em_gio_irq_enable; | ||
| 339 | irq_chip->irq_disable = em_gio_irq_disable; | ||
| 340 | irq_chip->irq_set_type = em_gio_irq_set_type; | ||
| 341 | irq_chip->flags = IRQCHIP_SKIP_SET_WAKE; | ||
| 342 | |||
| 343 | ret = em_gio_irq_domain_init(p); | ||
| 344 | if (ret) { | ||
| 345 | dev_err(&pdev->dev, "cannot initialize irq domain\n"); | ||
| 346 | goto err3; | ||
| 347 | } | ||
| 348 | |||
| 349 | if (request_irq(irq[0]->start, em_gio_irq_handler, 0, name, p)) { | ||
| 350 | dev_err(&pdev->dev, "failed to request low IRQ\n"); | ||
| 351 | ret = -ENOENT; | ||
| 352 | goto err4; | ||
| 353 | } | ||
| 354 | |||
| 355 | if (request_irq(irq[1]->start, em_gio_irq_handler, 0, name, p)) { | ||
| 356 | dev_err(&pdev->dev, "failed to request high IRQ\n"); | ||
| 357 | ret = -ENOENT; | ||
| 358 | goto err5; | ||
| 359 | } | ||
| 360 | |||
| 361 | ret = gpiochip_add(gpio_chip); | ||
| 362 | if (ret) { | ||
| 363 | dev_err(&pdev->dev, "failed to add GPIO controller\n"); | ||
| 364 | goto err6; | ||
| 365 | } | ||
| 366 | return 0; | ||
| 367 | |||
| 368 | err6: | ||
| 369 | free_irq(irq[1]->start, pdev); | ||
| 370 | err5: | ||
| 371 | free_irq(irq[0]->start, pdev); | ||
| 372 | err4: | ||
| 373 | em_gio_irq_domain_cleanup(p); | ||
| 374 | err3: | ||
| 375 | iounmap(p->base1); | ||
| 376 | err2: | ||
| 377 | iounmap(p->base0); | ||
| 378 | err1: | ||
| 379 | kfree(p); | ||
| 380 | err0: | ||
| 381 | return ret; | ||
| 382 | } | ||
| 383 | |||
| 384 | static int __devexit em_gio_remove(struct platform_device *pdev) | ||
| 385 | { | ||
| 386 | struct em_gio_priv *p = platform_get_drvdata(pdev); | ||
| 387 | struct resource *irq[2]; | ||
| 388 | int ret; | ||
| 389 | |||
| 390 | ret = gpiochip_remove(&p->gpio_chip); | ||
| 391 | if (ret) | ||
| 392 | return ret; | ||
| 393 | |||
| 394 | irq[0] = platform_get_resource(pdev, IORESOURCE_IRQ, 0); | ||
| 395 | irq[1] = platform_get_resource(pdev, IORESOURCE_IRQ, 1); | ||
| 396 | |||
| 397 | free_irq(irq[1]->start, pdev); | ||
| 398 | free_irq(irq[0]->start, pdev); | ||
| 399 | em_gio_irq_domain_cleanup(p); | ||
| 400 | iounmap(p->base1); | ||
| 401 | iounmap(p->base0); | ||
| 402 | kfree(p); | ||
| 403 | return 0; | ||
| 404 | } | ||
| 405 | |||
| 406 | static struct platform_driver em_gio_device_driver = { | ||
| 407 | .probe = em_gio_probe, | ||
| 408 | .remove = __devexit_p(em_gio_remove), | ||
| 409 | .driver = { | ||
| 410 | .name = "em_gio", | ||
| 411 | } | ||
| 412 | }; | ||
| 413 | |||
| 414 | module_platform_driver(em_gio_device_driver); | ||
| 415 | |||
| 416 | MODULE_AUTHOR("Magnus Damm"); | ||
| 417 | MODULE_DESCRIPTION("Renesas Emma Mobile GIO Driver"); | ||
| 418 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/gpio/gpio-ep93xx.c b/drivers/gpio/gpio-ep93xx.c index 776b772523e5..9fe5b8fe9be8 100644 --- a/drivers/gpio/gpio-ep93xx.c +++ b/drivers/gpio/gpio-ep93xx.c | |||
| @@ -325,7 +325,7 @@ static int ep93xx_gpio_add_bank(struct bgpio_chip *bgc, struct device *dev, | |||
| 325 | void __iomem *dir = mmio_base + bank->dir; | 325 | void __iomem *dir = mmio_base + bank->dir; |
| 326 | int err; | 326 | int err; |
| 327 | 327 | ||
| 328 | err = bgpio_init(bgc, dev, 1, data, NULL, NULL, dir, NULL, false); | 328 | err = bgpio_init(bgc, dev, 1, data, NULL, NULL, dir, NULL, 0); |
| 329 | if (err) | 329 | if (err) |
| 330 | return err; | 330 | return err; |
| 331 | 331 | ||
diff --git a/drivers/gpio/gpio-generic.c b/drivers/gpio/gpio-generic.c index e38dd0c31973..82e2e4fe599e 100644 --- a/drivers/gpio/gpio-generic.c +++ b/drivers/gpio/gpio-generic.c | |||
| @@ -364,7 +364,7 @@ EXPORT_SYMBOL_GPL(bgpio_remove); | |||
| 364 | int bgpio_init(struct bgpio_chip *bgc, struct device *dev, | 364 | int bgpio_init(struct bgpio_chip *bgc, struct device *dev, |
| 365 | unsigned long sz, void __iomem *dat, void __iomem *set, | 365 | unsigned long sz, void __iomem *dat, void __iomem *set, |
| 366 | void __iomem *clr, void __iomem *dirout, void __iomem *dirin, | 366 | void __iomem *clr, void __iomem *dirout, void __iomem *dirin, |
| 367 | bool big_endian) | 367 | unsigned long flags) |
| 368 | { | 368 | { |
| 369 | int ret; | 369 | int ret; |
| 370 | 370 | ||
| @@ -385,7 +385,7 @@ int bgpio_init(struct bgpio_chip *bgc, struct device *dev, | |||
| 385 | if (ret) | 385 | if (ret) |
| 386 | return ret; | 386 | return ret; |
| 387 | 387 | ||
| 388 | ret = bgpio_setup_accessors(dev, bgc, big_endian); | 388 | ret = bgpio_setup_accessors(dev, bgc, flags & BGPIOF_BIG_ENDIAN); |
| 389 | if (ret) | 389 | if (ret) |
| 390 | return ret; | 390 | return ret; |
| 391 | 391 | ||
| @@ -394,6 +394,11 @@ int bgpio_init(struct bgpio_chip *bgc, struct device *dev, | |||
| 394 | return ret; | 394 | return ret; |
| 395 | 395 | ||
| 396 | bgc->data = bgc->read_reg(bgc->reg_dat); | 396 | bgc->data = bgc->read_reg(bgc->reg_dat); |
| 397 | if (bgc->gc.set == bgpio_set_set && | ||
| 398 | !(flags & BGPIOF_UNREADABLE_REG_SET)) | ||
| 399 | bgc->data = bgc->read_reg(bgc->reg_set); | ||
| 400 | if (bgc->reg_dir && !(flags & BGPIOF_UNREADABLE_REG_DIR)) | ||
| 401 | bgc->dir = bgc->read_reg(bgc->reg_dir); | ||
| 397 | 402 | ||
| 398 | return ret; | 403 | return ret; |
| 399 | } | 404 | } |
| @@ -449,7 +454,7 @@ static int __devinit bgpio_pdev_probe(struct platform_device *pdev) | |||
| 449 | void __iomem *dirout; | 454 | void __iomem *dirout; |
| 450 | void __iomem *dirin; | 455 | void __iomem *dirin; |
| 451 | unsigned long sz; | 456 | unsigned long sz; |
| 452 | bool be; | 457 | unsigned long flags = 0; |
| 453 | int err; | 458 | int err; |
| 454 | struct bgpio_chip *bgc; | 459 | struct bgpio_chip *bgc; |
| 455 | struct bgpio_pdata *pdata = dev_get_platdata(dev); | 460 | struct bgpio_pdata *pdata = dev_get_platdata(dev); |
| @@ -480,13 +485,14 @@ static int __devinit bgpio_pdev_probe(struct platform_device *pdev) | |||
| 480 | if (err) | 485 | if (err) |
| 481 | return err; | 486 | return err; |
| 482 | 487 | ||
| 483 | be = !strcmp(platform_get_device_id(pdev)->name, "basic-mmio-gpio-be"); | 488 | if (!strcmp(platform_get_device_id(pdev)->name, "basic-mmio-gpio-be")) |
| 489 | flags |= BGPIOF_BIG_ENDIAN; | ||
| 484 | 490 | ||
| 485 | bgc = devm_kzalloc(&pdev->dev, sizeof(*bgc), GFP_KERNEL); | 491 | bgc = devm_kzalloc(&pdev->dev, sizeof(*bgc), GFP_KERNEL); |
| 486 | if (!bgc) | 492 | if (!bgc) |
| 487 | return -ENOMEM; | 493 | return -ENOMEM; |
| 488 | 494 | ||
| 489 | err = bgpio_init(bgc, dev, sz, dat, set, clr, dirout, dirin, be); | 495 | err = bgpio_init(bgc, dev, sz, dat, set, clr, dirout, dirin, flags); |
| 490 | if (err) | 496 | if (err) |
| 491 | return err; | 497 | return err; |
| 492 | 498 | ||
diff --git a/drivers/gpio/gpio-ich.c b/drivers/gpio/gpio-ich.c new file mode 100644 index 000000000000..b7c06517403d --- /dev/null +++ b/drivers/gpio/gpio-ich.c | |||
| @@ -0,0 +1,419 @@ | |||
| 1 | /* | ||
| 2 | * Intel ICH6-10, Series 5 and 6 GPIO driver | ||
| 3 | * | ||
| 4 | * Copyright (C) 2010 Extreme Engineering Solutions. | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or modify | ||
| 7 | * it under the terms of the GNU General Public License as published by | ||
| 8 | * the Free Software Foundation; either version 2 of the License, or | ||
| 9 | * (at your option) any later version. | ||
| 10 | * | ||
| 11 | * This program is distributed in the hope that it will be useful, | ||
| 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 14 | * GNU General Public License for more details. | ||
| 15 | * | ||
| 16 | * You should have received a copy of the GNU General Public License | ||
| 17 | * along with this program; if not, write to the Free Software | ||
| 18 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
| 19 | */ | ||
| 20 | |||
| 21 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
| 22 | |||
| 23 | #include <linux/module.h> | ||
| 24 | #include <linux/pci.h> | ||
| 25 | #include <linux/gpio.h> | ||
| 26 | #include <linux/platform_device.h> | ||
| 27 | #include <linux/mfd/lpc_ich.h> | ||
| 28 | |||
| 29 | #define DRV_NAME "gpio_ich" | ||
| 30 | |||
| 31 | /* | ||
| 32 | * GPIO register offsets in GPIO I/O space. | ||
| 33 | * Each chunk of 32 GPIOs is manipulated via its own USE_SELx, IO_SELx, and | ||
| 34 | * LVLx registers. Logic in the read/write functions takes a register and | ||
| 35 | * an absolute bit number and determines the proper register offset and bit | ||
| 36 | * number in that register. For example, to read the value of GPIO bit 50 | ||
| 37 | * the code would access offset ichx_regs[2(=GPIO_LVL)][1(=50/32)], | ||
| 38 | * bit 18 (50%32). | ||
| 39 | */ | ||
| 40 | enum GPIO_REG { | ||
| 41 | GPIO_USE_SEL = 0, | ||
| 42 | GPIO_IO_SEL, | ||
| 43 | GPIO_LVL, | ||
| 44 | }; | ||
| 45 | |||
| 46 | static const u8 ichx_regs[3][3] = { | ||
| 47 | {0x00, 0x30, 0x40}, /* USE_SEL[1-3] offsets */ | ||
| 48 | {0x04, 0x34, 0x44}, /* IO_SEL[1-3] offsets */ | ||
| 49 | {0x0c, 0x38, 0x48}, /* LVL[1-3] offsets */ | ||
| 50 | }; | ||
| 51 | |||
| 52 | #define ICHX_WRITE(val, reg, base_res) outl(val, (reg) + (base_res)->start) | ||
| 53 | #define ICHX_READ(reg, base_res) inl((reg) + (base_res)->start) | ||
| 54 | |||
| 55 | struct ichx_desc { | ||
| 56 | /* Max GPIO pins the chipset can have */ | ||
| 57 | uint ngpio; | ||
| 58 | |||
| 59 | /* Whether the chipset has GPIO in GPE0_STS in the PM IO region */ | ||
| 60 | bool uses_gpe0; | ||
| 61 | |||
| 62 | /* USE_SEL is bogus on some chipsets, eg 3100 */ | ||
| 63 | u32 use_sel_ignore[3]; | ||
| 64 | |||
| 65 | /* Some chipsets have quirks, let these use their own request/get */ | ||
| 66 | int (*request)(struct gpio_chip *chip, unsigned offset); | ||
| 67 | int (*get)(struct gpio_chip *chip, unsigned offset); | ||
| 68 | }; | ||
| 69 | |||
| 70 | static struct { | ||
| 71 | spinlock_t lock; | ||
| 72 | struct platform_device *dev; | ||
| 73 | struct gpio_chip chip; | ||
| 74 | struct resource *gpio_base; /* GPIO IO base */ | ||
| 75 | struct resource *pm_base; /* Power Mangagment IO base */ | ||
| 76 | struct ichx_desc *desc; /* Pointer to chipset-specific description */ | ||
| 77 | u32 orig_gpio_ctrl; /* Orig CTRL value, used to restore on exit */ | ||
| 78 | } ichx_priv; | ||
| 79 | |||
| 80 | static int modparam_gpiobase = -1; /* dynamic */ | ||
| 81 | module_param_named(gpiobase, modparam_gpiobase, int, 0444); | ||
| 82 | MODULE_PARM_DESC(gpiobase, "The GPIO number base. -1 means dynamic, " | ||
| 83 | "which is the default."); | ||
| 84 | |||
| 85 | static int ichx_write_bit(int reg, unsigned nr, int val, int verify) | ||
| 86 | { | ||
| 87 | unsigned long flags; | ||
| 88 | u32 data, tmp; | ||
| 89 | int reg_nr = nr / 32; | ||
| 90 | int bit = nr & 0x1f; | ||
| 91 | int ret = 0; | ||
| 92 | |||
| 93 | spin_lock_irqsave(&ichx_priv.lock, flags); | ||
| 94 | |||
| 95 | data = ICHX_READ(ichx_regs[reg][reg_nr], ichx_priv.gpio_base); | ||
| 96 | if (val) | ||
| 97 | data |= 1 << bit; | ||
| 98 | else | ||
| 99 | data &= ~(1 << bit); | ||
| 100 | ICHX_WRITE(data, ichx_regs[reg][reg_nr], ichx_priv.gpio_base); | ||
| 101 | tmp = ICHX_READ(ichx_regs[reg][reg_nr], ichx_priv.gpio_base); | ||
| 102 | if (verify && data != tmp) | ||
| 103 | ret = -EPERM; | ||
| 104 | |||
| 105 | spin_unlock_irqrestore(&ichx_priv.lock, flags); | ||
| 106 | |||
| 107 | return ret; | ||
| 108 | } | ||
| 109 | |||
| 110 | static int ichx_read_bit(int reg, unsigned nr) | ||
| 111 | { | ||
| 112 | unsigned long flags; | ||
| 113 | u32 data; | ||
| 114 | int reg_nr = nr / 32; | ||
| 115 | int bit = nr & 0x1f; | ||
| 116 | |||
| 117 | spin_lock_irqsave(&ichx_priv.lock, flags); | ||
| 118 | |||
| 119 | data = ICHX_READ(ichx_regs[reg][reg_nr], ichx_priv.gpio_base); | ||
| 120 | |||
| 121 | spin_unlock_irqrestore(&ichx_priv.lock, flags); | ||
| 122 | |||
| 123 | return data & (1 << bit) ? 1 : 0; | ||
| 124 | } | ||
| 125 | |||
| 126 | static int ichx_gpio_direction_input(struct gpio_chip *gpio, unsigned nr) | ||
| 127 | { | ||
| 128 | /* | ||
| 129 | * Try setting pin as an input and verify it worked since many pins | ||
| 130 | * are output-only. | ||
| 131 | */ | ||
| 132 | if (ichx_write_bit(GPIO_IO_SEL, nr, 1, 1)) | ||
| 133 | return -EINVAL; | ||
| 134 | |||
| 135 | return 0; | ||
| 136 | } | ||
| 137 | |||
| 138 | static int ichx_gpio_direction_output(struct gpio_chip *gpio, unsigned nr, | ||
| 139 | int val) | ||
| 140 | { | ||
| 141 | /* Set GPIO output value. */ | ||
| 142 | ichx_write_bit(GPIO_LVL, nr, val, 0); | ||
| 143 | |||
| 144 | /* | ||
| 145 | * Try setting pin as an output and verify it worked since many pins | ||
| 146 | * are input-only. | ||
| 147 | */ | ||
| 148 | if (ichx_write_bit(GPIO_IO_SEL, nr, 0, 1)) | ||
| 149 | return -EINVAL; | ||
| 150 | |||
| 151 | return 0; | ||
| 152 | } | ||
| 153 | |||
| 154 | static int ichx_gpio_get(struct gpio_chip *chip, unsigned nr) | ||
| 155 | { | ||
| 156 | return ichx_read_bit(GPIO_LVL, nr); | ||
| 157 | } | ||
| 158 | |||
| 159 | static int ich6_gpio_get(struct gpio_chip *chip, unsigned nr) | ||
| 160 | { | ||
| 161 | unsigned long flags; | ||
| 162 | u32 data; | ||
| 163 | |||
| 164 | /* | ||
| 165 | * GPI 0 - 15 need to be read from the power management registers on | ||
| 166 | * a ICH6/3100 bridge. | ||
| 167 | */ | ||
| 168 | if (nr < 16) { | ||
| 169 | if (!ichx_priv.pm_base) | ||
| 170 | return -ENXIO; | ||
| 171 | |||
| 172 | spin_lock_irqsave(&ichx_priv.lock, flags); | ||
| 173 | |||
| 174 | /* GPI 0 - 15 are latched, write 1 to clear*/ | ||
| 175 | ICHX_WRITE(1 << (16 + nr), 0, ichx_priv.pm_base); | ||
| 176 | data = ICHX_READ(0, ichx_priv.pm_base); | ||
| 177 | |||
| 178 | spin_unlock_irqrestore(&ichx_priv.lock, flags); | ||
| 179 | |||
| 180 | return (data >> 16) & (1 << nr) ? 1 : 0; | ||
| 181 | } else { | ||
| 182 | return ichx_gpio_get(chip, nr); | ||
| 183 | } | ||
| 184 | } | ||
| 185 | |||
| 186 | static int ichx_gpio_request(struct gpio_chip *chip, unsigned nr) | ||
| 187 | { | ||
| 188 | /* | ||
| 189 | * Note we assume the BIOS properly set a bridge's USE value. Some | ||
| 190 | * chips (eg Intel 3100) have bogus USE values though, so first see if | ||
| 191 | * the chipset's USE value can be trusted for this specific bit. | ||
| 192 | * If it can't be trusted, assume that the pin can be used as a GPIO. | ||
| 193 | */ | ||
| 194 | if (ichx_priv.desc->use_sel_ignore[nr / 32] & (1 << (nr & 0x1f))) | ||
| 195 | return 1; | ||
| 196 | |||
| 197 | return ichx_read_bit(GPIO_USE_SEL, nr) ? 0 : -ENODEV; | ||
| 198 | } | ||
| 199 | |||
| 200 | static int ich6_gpio_request(struct gpio_chip *chip, unsigned nr) | ||
| 201 | { | ||
| 202 | /* | ||
| 203 | * Fixups for bits 16 and 17 are necessary on the Intel ICH6/3100 | ||
| 204 | * bridge as they are controlled by USE register bits 0 and 1. See | ||
| 205 | * "Table 704 GPIO_USE_SEL1 register" in the i3100 datasheet for | ||
| 206 | * additional info. | ||
| 207 | */ | ||
| 208 | if (nr == 16 || nr == 17) | ||
| 209 | nr -= 16; | ||
| 210 | |||
| 211 | return ichx_gpio_request(chip, nr); | ||
| 212 | } | ||
| 213 | |||
| 214 | static void ichx_gpio_set(struct gpio_chip *chip, unsigned nr, int val) | ||
| 215 | { | ||
| 216 | ichx_write_bit(GPIO_LVL, nr, val, 0); | ||
| 217 | } | ||
| 218 | |||
| 219 | static void __devinit ichx_gpiolib_setup(struct gpio_chip *chip) | ||
| 220 | { | ||
| 221 | chip->owner = THIS_MODULE; | ||
| 222 | chip->label = DRV_NAME; | ||
| 223 | chip->dev = &ichx_priv.dev->dev; | ||
| 224 | |||
| 225 | /* Allow chip-specific overrides of request()/get() */ | ||
| 226 | chip->request = ichx_priv.desc->request ? | ||
| 227 | ichx_priv.desc->request : ichx_gpio_request; | ||
| 228 | chip->get = ichx_priv.desc->get ? | ||
| 229 | ichx_priv.desc->get : ichx_gpio_get; | ||
| 230 | |||
| 231 | chip->set = ichx_gpio_set; | ||
| 232 | chip->direction_input = ichx_gpio_direction_input; | ||
| 233 | chip->direction_output = ichx_gpio_direction_output; | ||
| 234 | chip->base = modparam_gpiobase; | ||
| 235 | chip->ngpio = ichx_priv.desc->ngpio; | ||
| 236 | chip->can_sleep = 0; | ||
| 237 | chip->dbg_show = NULL; | ||
| 238 | } | ||
| 239 | |||
| 240 | /* ICH6-based, 631xesb-based */ | ||
| 241 | static struct ichx_desc ich6_desc = { | ||
| 242 | /* Bridges using the ICH6 controller need fixups for GPIO 0 - 17 */ | ||
| 243 | .request = ich6_gpio_request, | ||
| 244 | .get = ich6_gpio_get, | ||
| 245 | |||
| 246 | /* GPIO 0-15 are read in the GPE0_STS PM register */ | ||
| 247 | .uses_gpe0 = true, | ||
| 248 | |||
| 249 | .ngpio = 50, | ||
| 250 | }; | ||
| 251 | |||
| 252 | /* Intel 3100 */ | ||
| 253 | static struct ichx_desc i3100_desc = { | ||
| 254 | /* | ||
| 255 | * Bits 16,17, 20 of USE_SEL and bit 16 of USE_SEL2 always read 0 on | ||
| 256 | * the Intel 3100. See "Table 712. GPIO Summary Table" of 3100 | ||
| 257 | * Datasheet for more info. | ||
| 258 | */ | ||
| 259 | .use_sel_ignore = {0x00130000, 0x00010000, 0x0}, | ||
| 260 | |||
| 261 | /* The 3100 needs fixups for GPIO 0 - 17 */ | ||
| 262 | .request = ich6_gpio_request, | ||
| 263 | .get = ich6_gpio_get, | ||
| 264 | |||
| 265 | /* GPIO 0-15 are read in the GPE0_STS PM register */ | ||
| 266 | .uses_gpe0 = true, | ||
| 267 | |||
| 268 | .ngpio = 50, | ||
| 269 | }; | ||
| 270 | |||
| 271 | /* ICH7 and ICH8-based */ | ||
| 272 | static struct ichx_desc ich7_desc = { | ||
| 273 | .ngpio = 50, | ||
| 274 | }; | ||
| 275 | |||
| 276 | /* ICH9-based */ | ||
| 277 | static struct ichx_desc ich9_desc = { | ||
| 278 | .ngpio = 61, | ||
| 279 | }; | ||
| 280 | |||
| 281 | /* ICH10-based - Consumer/corporate versions have different amount of GPIO */ | ||
| 282 | static struct ichx_desc ich10_cons_desc = { | ||
| 283 | .ngpio = 61, | ||
| 284 | }; | ||
| 285 | static struct ichx_desc ich10_corp_desc = { | ||
| 286 | .ngpio = 72, | ||
| 287 | }; | ||
| 288 | |||
| 289 | /* Intel 5 series, 6 series, 3400 series, and C200 series */ | ||
| 290 | static struct ichx_desc intel5_desc = { | ||
| 291 | .ngpio = 76, | ||
| 292 | }; | ||
| 293 | |||
| 294 | static int __devinit ichx_gpio_probe(struct platform_device *pdev) | ||
| 295 | { | ||
| 296 | struct resource *res_base, *res_pm; | ||
| 297 | int err; | ||
| 298 | struct lpc_ich_info *ich_info = pdev->dev.platform_data; | ||
| 299 | |||
| 300 | if (!ich_info) | ||
| 301 | return -ENODEV; | ||
| 302 | |||
| 303 | ichx_priv.dev = pdev; | ||
| 304 | |||
| 305 | switch (ich_info->gpio_version) { | ||
| 306 | case ICH_I3100_GPIO: | ||
| 307 | ichx_priv.desc = &i3100_desc; | ||
| 308 | break; | ||
| 309 | case ICH_V5_GPIO: | ||
| 310 | ichx_priv.desc = &intel5_desc; | ||
| 311 | break; | ||
| 312 | case ICH_V6_GPIO: | ||
| 313 | ichx_priv.desc = &ich6_desc; | ||
| 314 | break; | ||
| 315 | case ICH_V7_GPIO: | ||
| 316 | ichx_priv.desc = &ich7_desc; | ||
| 317 | break; | ||
| 318 | case ICH_V9_GPIO: | ||
| 319 | ichx_priv.desc = &ich9_desc; | ||
| 320 | break; | ||
| 321 | case ICH_V10CORP_GPIO: | ||
| 322 | ichx_priv.desc = &ich10_corp_desc; | ||
| 323 | break; | ||
| 324 | case ICH_V10CONS_GPIO: | ||
| 325 | ichx_priv.desc = &ich10_cons_desc; | ||
| 326 | break; | ||
| 327 | default: | ||
| 328 | return -ENODEV; | ||
| 329 | } | ||
| 330 | |||
| 331 | res_base = platform_get_resource(pdev, IORESOURCE_IO, ICH_RES_GPIO); | ||
| 332 | if (!res_base || !res_base->start || !res_base->end) | ||
| 333 | return -ENODEV; | ||
| 334 | |||
| 335 | if (!request_region(res_base->start, resource_size(res_base), | ||
| 336 | pdev->name)) | ||
| 337 | return -EBUSY; | ||
| 338 | |||
| 339 | ichx_priv.gpio_base = res_base; | ||
| 340 | |||
| 341 | /* | ||
| 342 | * If necessary, determine the I/O address of ACPI/power management | ||
| 343 | * registers which are needed to read the the GPE0 register for GPI pins | ||
| 344 | * 0 - 15 on some chipsets. | ||
| 345 | */ | ||
| 346 | if (!ichx_priv.desc->uses_gpe0) | ||
| 347 | goto init; | ||
| 348 | |||
| 349 | res_pm = platform_get_resource(pdev, IORESOURCE_IO, ICH_RES_GPE0); | ||
| 350 | if (!res_pm) { | ||
| 351 | pr_warn("ACPI BAR is unavailable, GPI 0 - 15 unavailable\n"); | ||
| 352 | goto init; | ||
| 353 | } | ||
| 354 | |||
| 355 | if (!request_region(res_pm->start, resource_size(res_pm), | ||
| 356 | pdev->name)) { | ||
| 357 | pr_warn("ACPI BAR is busy, GPI 0 - 15 unavailable\n"); | ||
| 358 | goto init; | ||
| 359 | } | ||
| 360 | |||
| 361 | ichx_priv.pm_base = res_pm; | ||
| 362 | |||
| 363 | init: | ||
| 364 | ichx_gpiolib_setup(&ichx_priv.chip); | ||
| 365 | err = gpiochip_add(&ichx_priv.chip); | ||
| 366 | if (err) { | ||
| 367 | pr_err("Failed to register GPIOs\n"); | ||
| 368 | goto add_err; | ||
| 369 | } | ||
| 370 | |||
| 371 | pr_info("GPIO from %d to %d on %s\n", ichx_priv.chip.base, | ||
| 372 | ichx_priv.chip.base + ichx_priv.chip.ngpio - 1, DRV_NAME); | ||
| 373 | |||
| 374 | return 0; | ||
| 375 | |||
| 376 | add_err: | ||
| 377 | release_region(ichx_priv.gpio_base->start, | ||
| 378 | resource_size(ichx_priv.gpio_base)); | ||
| 379 | if (ichx_priv.pm_base) | ||
| 380 | release_region(ichx_priv.pm_base->start, | ||
| 381 | resource_size(ichx_priv.pm_base)); | ||
| 382 | return err; | ||
| 383 | } | ||
| 384 | |||
| 385 | static int __devexit ichx_gpio_remove(struct platform_device *pdev) | ||
| 386 | { | ||
| 387 | int err; | ||
| 388 | |||
| 389 | err = gpiochip_remove(&ichx_priv.chip); | ||
| 390 | if (err) { | ||
| 391 | dev_err(&pdev->dev, "%s failed, %d\n", | ||
| 392 | "gpiochip_remove()", err); | ||
| 393 | return err; | ||
| 394 | } | ||
| 395 | |||
| 396 | release_region(ichx_priv.gpio_base->start, | ||
| 397 | resource_size(ichx_priv.gpio_base)); | ||
| 398 | if (ichx_priv.pm_base) | ||
| 399 | release_region(ichx_priv.pm_base->start, | ||
| 400 | resource_size(ichx_priv.pm_base)); | ||
| 401 | |||
| 402 | return 0; | ||
| 403 | } | ||
| 404 | |||
| 405 | static struct platform_driver ichx_gpio_driver = { | ||
| 406 | .driver = { | ||
| 407 | .owner = THIS_MODULE, | ||
| 408 | .name = DRV_NAME, | ||
| 409 | }, | ||
| 410 | .probe = ichx_gpio_probe, | ||
| 411 | .remove = __devexit_p(ichx_gpio_remove), | ||
| 412 | }; | ||
| 413 | |||
| 414 | module_platform_driver(ichx_gpio_driver); | ||
| 415 | |||
| 416 | MODULE_AUTHOR("Peter Tyser <ptyser@xes-inc.com>"); | ||
| 417 | MODULE_DESCRIPTION("GPIO interface for Intel ICH series"); | ||
| 418 | MODULE_LICENSE("GPL"); | ||
| 419 | MODULE_ALIAS("platform:"DRV_NAME); | ||
diff --git a/drivers/gpio/gpio-langwell.c b/drivers/gpio/gpio-langwell.c index 00692e89ef87..a1c8754f52cf 100644 --- a/drivers/gpio/gpio-langwell.c +++ b/drivers/gpio/gpio-langwell.c | |||
| @@ -36,6 +36,7 @@ | |||
| 36 | #include <linux/gpio.h> | 36 | #include <linux/gpio.h> |
| 37 | #include <linux/slab.h> | 37 | #include <linux/slab.h> |
| 38 | #include <linux/pm_runtime.h> | 38 | #include <linux/pm_runtime.h> |
| 39 | #include <linux/irqdomain.h> | ||
| 39 | 40 | ||
| 40 | /* | 41 | /* |
| 41 | * Langwell chip has 64 pins and thus there are 2 32bit registers to control | 42 | * Langwell chip has 64 pins and thus there are 2 32bit registers to control |
| @@ -66,8 +67,8 @@ struct lnw_gpio { | |||
| 66 | struct gpio_chip chip; | 67 | struct gpio_chip chip; |
| 67 | void *reg_base; | 68 | void *reg_base; |
| 68 | spinlock_t lock; | 69 | spinlock_t lock; |
| 69 | unsigned irq_base; | ||
| 70 | struct pci_dev *pdev; | 70 | struct pci_dev *pdev; |
| 71 | struct irq_domain *domain; | ||
| 71 | }; | 72 | }; |
| 72 | 73 | ||
| 73 | static void __iomem *gpio_reg(struct gpio_chip *chip, unsigned offset, | 74 | static void __iomem *gpio_reg(struct gpio_chip *chip, unsigned offset, |
| @@ -176,13 +177,13 @@ static int lnw_gpio_direction_output(struct gpio_chip *chip, | |||
| 176 | static int lnw_gpio_to_irq(struct gpio_chip *chip, unsigned offset) | 177 | static int lnw_gpio_to_irq(struct gpio_chip *chip, unsigned offset) |
| 177 | { | 178 | { |
| 178 | struct lnw_gpio *lnw = container_of(chip, struct lnw_gpio, chip); | 179 | struct lnw_gpio *lnw = container_of(chip, struct lnw_gpio, chip); |
| 179 | return lnw->irq_base + offset; | 180 | return irq_create_mapping(lnw->domain, offset); |
| 180 | } | 181 | } |
| 181 | 182 | ||
| 182 | static int lnw_irq_type(struct irq_data *d, unsigned type) | 183 | static int lnw_irq_type(struct irq_data *d, unsigned type) |
| 183 | { | 184 | { |
| 184 | struct lnw_gpio *lnw = irq_data_get_irq_chip_data(d); | 185 | struct lnw_gpio *lnw = irq_data_get_irq_chip_data(d); |
| 185 | u32 gpio = d->irq - lnw->irq_base; | 186 | u32 gpio = irqd_to_hwirq(d); |
| 186 | unsigned long flags; | 187 | unsigned long flags; |
| 187 | u32 value; | 188 | u32 value; |
| 188 | void __iomem *grer = gpio_reg(&lnw->chip, gpio, GRER); | 189 | void __iomem *grer = gpio_reg(&lnw->chip, gpio, GRER); |
| @@ -249,20 +250,55 @@ static void lnw_irq_handler(unsigned irq, struct irq_desc *desc) | |||
| 249 | /* check GPIO controller to check which pin triggered the interrupt */ | 250 | /* check GPIO controller to check which pin triggered the interrupt */ |
| 250 | for (base = 0; base < lnw->chip.ngpio; base += 32) { | 251 | for (base = 0; base < lnw->chip.ngpio; base += 32) { |
| 251 | gedr = gpio_reg(&lnw->chip, base, GEDR); | 252 | gedr = gpio_reg(&lnw->chip, base, GEDR); |
| 252 | pending = readl(gedr); | 253 | while ((pending = readl(gedr))) { |
| 253 | while (pending) { | ||
| 254 | gpio = __ffs(pending); | 254 | gpio = __ffs(pending); |
| 255 | mask = BIT(gpio); | 255 | mask = BIT(gpio); |
| 256 | pending &= ~mask; | ||
| 257 | /* Clear before handling so we can't lose an edge */ | 256 | /* Clear before handling so we can't lose an edge */ |
| 258 | writel(mask, gedr); | 257 | writel(mask, gedr); |
| 259 | generic_handle_irq(lnw->irq_base + base + gpio); | 258 | generic_handle_irq(irq_find_mapping(lnw->domain, |
| 259 | base + gpio)); | ||
| 260 | } | 260 | } |
| 261 | } | 261 | } |
| 262 | 262 | ||
| 263 | chip->irq_eoi(data); | 263 | chip->irq_eoi(data); |
| 264 | } | 264 | } |
| 265 | 265 | ||
| 266 | static void lnw_irq_init_hw(struct lnw_gpio *lnw) | ||
| 267 | { | ||
| 268 | void __iomem *reg; | ||
| 269 | unsigned base; | ||
| 270 | |||
| 271 | for (base = 0; base < lnw->chip.ngpio; base += 32) { | ||
| 272 | /* Clear the rising-edge detect register */ | ||
| 273 | reg = gpio_reg(&lnw->chip, base, GRER); | ||
| 274 | writel(0, reg); | ||
| 275 | /* Clear the falling-edge detect register */ | ||
| 276 | reg = gpio_reg(&lnw->chip, base, GFER); | ||
| 277 | writel(0, reg); | ||
| 278 | /* Clear the edge detect status register */ | ||
| 279 | reg = gpio_reg(&lnw->chip, base, GEDR); | ||
| 280 | writel(~0, reg); | ||
| 281 | } | ||
| 282 | } | ||
| 283 | |||
| 284 | static int lnw_gpio_irq_map(struct irq_domain *d, unsigned int virq, | ||
| 285 | irq_hw_number_t hw) | ||
| 286 | { | ||
| 287 | struct lnw_gpio *lnw = d->host_data; | ||
| 288 | |||
| 289 | irq_set_chip_and_handler_name(virq, &lnw_irqchip, handle_simple_irq, | ||
| 290 | "demux"); | ||
| 291 | irq_set_chip_data(virq, lnw); | ||
| 292 | irq_set_irq_type(virq, IRQ_TYPE_NONE); | ||
| 293 | |||
| 294 | return 0; | ||
| 295 | } | ||
| 296 | |||
| 297 | static const struct irq_domain_ops lnw_gpio_irq_ops = { | ||
| 298 | .map = lnw_gpio_irq_map, | ||
| 299 | .xlate = irq_domain_xlate_twocell, | ||
| 300 | }; | ||
| 301 | |||
| 266 | #ifdef CONFIG_PM | 302 | #ifdef CONFIG_PM |
| 267 | static int lnw_gpio_runtime_resume(struct device *dev) | 303 | static int lnw_gpio_runtime_resume(struct device *dev) |
| 268 | { | 304 | { |
| @@ -300,23 +336,22 @@ static int __devinit lnw_gpio_probe(struct pci_dev *pdev, | |||
| 300 | const struct pci_device_id *id) | 336 | const struct pci_device_id *id) |
| 301 | { | 337 | { |
| 302 | void *base; | 338 | void *base; |
| 303 | int i; | ||
| 304 | resource_size_t start, len; | 339 | resource_size_t start, len; |
| 305 | struct lnw_gpio *lnw; | 340 | struct lnw_gpio *lnw; |
| 306 | u32 irq_base; | ||
| 307 | u32 gpio_base; | 341 | u32 gpio_base; |
| 308 | int retval = 0; | 342 | int retval = 0; |
| 343 | int ngpio = id->driver_data; | ||
| 309 | 344 | ||
| 310 | retval = pci_enable_device(pdev); | 345 | retval = pci_enable_device(pdev); |
| 311 | if (retval) | 346 | if (retval) |
| 312 | goto done; | 347 | return retval; |
| 313 | 348 | ||
| 314 | retval = pci_request_regions(pdev, "langwell_gpio"); | 349 | retval = pci_request_regions(pdev, "langwell_gpio"); |
| 315 | if (retval) { | 350 | if (retval) { |
| 316 | dev_err(&pdev->dev, "error requesting resources\n"); | 351 | dev_err(&pdev->dev, "error requesting resources\n"); |
| 317 | goto err2; | 352 | goto err2; |
| 318 | } | 353 | } |
| 319 | /* get the irq_base from bar1 */ | 354 | /* get the gpio_base from bar1 */ |
| 320 | start = pci_resource_start(pdev, 1); | 355 | start = pci_resource_start(pdev, 1); |
| 321 | len = pci_resource_len(pdev, 1); | 356 | len = pci_resource_len(pdev, 1); |
| 322 | base = ioremap_nocache(start, len); | 357 | base = ioremap_nocache(start, len); |
| @@ -324,28 +359,32 @@ static int __devinit lnw_gpio_probe(struct pci_dev *pdev, | |||
| 324 | dev_err(&pdev->dev, "error mapping bar1\n"); | 359 | dev_err(&pdev->dev, "error mapping bar1\n"); |
| 325 | goto err3; | 360 | goto err3; |
| 326 | } | 361 | } |
| 327 | irq_base = *(u32 *)base; | ||
| 328 | gpio_base = *((u32 *)base + 1); | 362 | gpio_base = *((u32 *)base + 1); |
| 329 | /* release the IO mapping, since we already get the info from bar1 */ | 363 | /* release the IO mapping, since we already get the info from bar1 */ |
| 330 | iounmap(base); | 364 | iounmap(base); |
| 331 | /* get the register base from bar0 */ | 365 | /* get the register base from bar0 */ |
| 332 | start = pci_resource_start(pdev, 0); | 366 | start = pci_resource_start(pdev, 0); |
| 333 | len = pci_resource_len(pdev, 0); | 367 | len = pci_resource_len(pdev, 0); |
| 334 | base = ioremap_nocache(start, len); | 368 | base = devm_ioremap_nocache(&pdev->dev, start, len); |
| 335 | if (!base) { | 369 | if (!base) { |
| 336 | dev_err(&pdev->dev, "error mapping bar0\n"); | 370 | dev_err(&pdev->dev, "error mapping bar0\n"); |
| 337 | retval = -EFAULT; | 371 | retval = -EFAULT; |
| 338 | goto err3; | 372 | goto err3; |
| 339 | } | 373 | } |
| 340 | 374 | ||
| 341 | lnw = kzalloc(sizeof(struct lnw_gpio), GFP_KERNEL); | 375 | lnw = devm_kzalloc(&pdev->dev, sizeof(struct lnw_gpio), GFP_KERNEL); |
| 342 | if (!lnw) { | 376 | if (!lnw) { |
| 343 | dev_err(&pdev->dev, "can't allocate langwell_gpio chip data\n"); | 377 | dev_err(&pdev->dev, "can't allocate langwell_gpio chip data\n"); |
| 344 | retval = -ENOMEM; | 378 | retval = -ENOMEM; |
| 345 | goto err4; | 379 | goto err3; |
| 346 | } | 380 | } |
| 381 | |||
| 382 | lnw->domain = irq_domain_add_linear(pdev->dev.of_node, ngpio, | ||
| 383 | &lnw_gpio_irq_ops, lnw); | ||
| 384 | if (!lnw->domain) | ||
| 385 | goto err3; | ||
| 386 | |||
| 347 | lnw->reg_base = base; | 387 | lnw->reg_base = base; |
| 348 | lnw->irq_base = irq_base; | ||
| 349 | lnw->chip.label = dev_name(&pdev->dev); | 388 | lnw->chip.label = dev_name(&pdev->dev); |
| 350 | lnw->chip.request = lnw_gpio_request; | 389 | lnw->chip.request = lnw_gpio_request; |
| 351 | lnw->chip.direction_input = lnw_gpio_direction_input; | 390 | lnw->chip.direction_input = lnw_gpio_direction_input; |
| @@ -354,38 +393,32 @@ static int __devinit lnw_gpio_probe(struct pci_dev *pdev, | |||
| 354 | lnw->chip.set = lnw_gpio_set; | 393 | lnw->chip.set = lnw_gpio_set; |
| 355 | lnw->chip.to_irq = lnw_gpio_to_irq; | 394 | lnw->chip.to_irq = lnw_gpio_to_irq; |
| 356 | lnw->chip.base = gpio_base; | 395 | lnw->chip.base = gpio_base; |
| 357 | lnw->chip.ngpio = id->driver_data; | 396 | lnw->chip.ngpio = ngpio; |
| 358 | lnw->chip.can_sleep = 0; | 397 | lnw->chip.can_sleep = 0; |
| 359 | lnw->pdev = pdev; | 398 | lnw->pdev = pdev; |
| 360 | pci_set_drvdata(pdev, lnw); | 399 | pci_set_drvdata(pdev, lnw); |
| 361 | retval = gpiochip_add(&lnw->chip); | 400 | retval = gpiochip_add(&lnw->chip); |
| 362 | if (retval) { | 401 | if (retval) { |
| 363 | dev_err(&pdev->dev, "langwell gpiochip_add error %d\n", retval); | 402 | dev_err(&pdev->dev, "langwell gpiochip_add error %d\n", retval); |
| 364 | goto err5; | 403 | goto err3; |
| 365 | } | 404 | } |
| 405 | |||
| 406 | lnw_irq_init_hw(lnw); | ||
| 407 | |||
| 366 | irq_set_handler_data(pdev->irq, lnw); | 408 | irq_set_handler_data(pdev->irq, lnw); |
| 367 | irq_set_chained_handler(pdev->irq, lnw_irq_handler); | 409 | irq_set_chained_handler(pdev->irq, lnw_irq_handler); |
| 368 | for (i = 0; i < lnw->chip.ngpio; i++) { | ||
| 369 | irq_set_chip_and_handler_name(i + lnw->irq_base, &lnw_irqchip, | ||
| 370 | handle_simple_irq, "demux"); | ||
| 371 | irq_set_chip_data(i + lnw->irq_base, lnw); | ||
| 372 | } | ||
| 373 | 410 | ||
| 374 | spin_lock_init(&lnw->lock); | 411 | spin_lock_init(&lnw->lock); |
| 375 | 412 | ||
| 376 | pm_runtime_put_noidle(&pdev->dev); | 413 | pm_runtime_put_noidle(&pdev->dev); |
| 377 | pm_runtime_allow(&pdev->dev); | 414 | pm_runtime_allow(&pdev->dev); |
| 378 | 415 | ||
| 379 | goto done; | 416 | return 0; |
| 380 | err5: | 417 | |
| 381 | kfree(lnw); | ||
| 382 | err4: | ||
| 383 | iounmap(base); | ||
| 384 | err3: | 418 | err3: |
| 385 | pci_release_regions(pdev); | 419 | pci_release_regions(pdev); |
| 386 | err2: | 420 | err2: |
| 387 | pci_disable_device(pdev); | 421 | pci_disable_device(pdev); |
| 388 | done: | ||
| 389 | return retval; | 422 | return retval; |
| 390 | } | 423 | } |
| 391 | 424 | ||
diff --git a/drivers/gpio/gpio-lpc32xx.c b/drivers/gpio/gpio-lpc32xx.c index 61c2d08d37b6..c2199beca98a 100644 --- a/drivers/gpio/gpio-lpc32xx.c +++ b/drivers/gpio/gpio-lpc32xx.c | |||
| @@ -21,6 +21,9 @@ | |||
| 21 | #include <linux/io.h> | 21 | #include <linux/io.h> |
| 22 | #include <linux/errno.h> | 22 | #include <linux/errno.h> |
| 23 | #include <linux/gpio.h> | 23 | #include <linux/gpio.h> |
| 24 | #include <linux/of_gpio.h> | ||
| 25 | #include <linux/platform_device.h> | ||
| 26 | #include <linux/module.h> | ||
| 24 | 27 | ||
| 25 | #include <mach/hardware.h> | 28 | #include <mach/hardware.h> |
| 26 | #include <mach/platform.h> | 29 | #include <mach/platform.h> |
| @@ -454,10 +457,57 @@ static struct lpc32xx_gpio_chip lpc32xx_gpiochip[] = { | |||
| 454 | }, | 457 | }, |
| 455 | }; | 458 | }; |
| 456 | 459 | ||
| 460 | /* Empty now, can be removed later when mach-lpc32xx is finally switched over | ||
| 461 | * to DT support | ||
| 462 | */ | ||
| 457 | void __init lpc32xx_gpio_init(void) | 463 | void __init lpc32xx_gpio_init(void) |
| 458 | { | 464 | { |
| 465 | } | ||
| 466 | |||
| 467 | static int lpc32xx_of_xlate(struct gpio_chip *gc, | ||
| 468 | const struct of_phandle_args *gpiospec, u32 *flags) | ||
| 469 | { | ||
| 470 | /* Is this the correct bank? */ | ||
| 471 | u32 bank = gpiospec->args[0]; | ||
| 472 | if ((bank > ARRAY_SIZE(lpc32xx_gpiochip) || | ||
| 473 | (gc != &lpc32xx_gpiochip[bank].chip))) | ||
| 474 | return -EINVAL; | ||
| 475 | |||
| 476 | if (flags) | ||
| 477 | *flags = gpiospec->args[2]; | ||
| 478 | return gpiospec->args[1]; | ||
| 479 | } | ||
| 480 | |||
| 481 | static int __devinit lpc32xx_gpio_probe(struct platform_device *pdev) | ||
| 482 | { | ||
| 459 | int i; | 483 | int i; |
| 460 | 484 | ||
| 461 | for (i = 0; i < ARRAY_SIZE(lpc32xx_gpiochip); i++) | 485 | for (i = 0; i < ARRAY_SIZE(lpc32xx_gpiochip); i++) { |
| 486 | if (pdev->dev.of_node) { | ||
| 487 | lpc32xx_gpiochip[i].chip.of_xlate = lpc32xx_of_xlate; | ||
| 488 | lpc32xx_gpiochip[i].chip.of_gpio_n_cells = 3; | ||
| 489 | lpc32xx_gpiochip[i].chip.of_node = pdev->dev.of_node; | ||
| 490 | } | ||
| 462 | gpiochip_add(&lpc32xx_gpiochip[i].chip); | 491 | gpiochip_add(&lpc32xx_gpiochip[i].chip); |
| 492 | } | ||
| 493 | |||
| 494 | return 0; | ||
| 463 | } | 495 | } |
| 496 | |||
| 497 | #ifdef CONFIG_OF | ||
| 498 | static struct of_device_id lpc32xx_gpio_of_match[] __devinitdata = { | ||
| 499 | { .compatible = "nxp,lpc3220-gpio", }, | ||
| 500 | { }, | ||
| 501 | }; | ||
| 502 | #endif | ||
| 503 | |||
| 504 | static struct platform_driver lpc32xx_gpio_driver = { | ||
| 505 | .driver = { | ||
| 506 | .name = "lpc32xx-gpio", | ||
| 507 | .owner = THIS_MODULE, | ||
| 508 | .of_match_table = of_match_ptr(lpc32xx_gpio_of_match), | ||
| 509 | }, | ||
| 510 | .probe = lpc32xx_gpio_probe, | ||
| 511 | }; | ||
| 512 | |||
| 513 | module_platform_driver(lpc32xx_gpio_driver); | ||
diff --git a/drivers/gpio/gpio-mcp23s08.c b/drivers/gpio/gpio-mcp23s08.c index c5d83a8a91c2..0f425189de11 100644 --- a/drivers/gpio/gpio-mcp23s08.c +++ b/drivers/gpio/gpio-mcp23s08.c | |||
| @@ -353,7 +353,7 @@ static void mcp23s08_dbg_show(struct seq_file *s, struct gpio_chip *chip) | |||
| 353 | chip->base + t, bank, t, label, | 353 | chip->base + t, bank, t, label, |
| 354 | (mcp->cache[MCP_IODIR] & mask) ? "in " : "out", | 354 | (mcp->cache[MCP_IODIR] & mask) ? "in " : "out", |
| 355 | (mcp->cache[MCP_GPIO] & mask) ? "hi" : "lo", | 355 | (mcp->cache[MCP_GPIO] & mask) ? "hi" : "lo", |
| 356 | (mcp->cache[MCP_GPPU] & mask) ? " " : "up"); | 356 | (mcp->cache[MCP_GPPU] & mask) ? "up" : " "); |
| 357 | /* NOTE: ignoring the irq-related registers */ | 357 | /* NOTE: ignoring the irq-related registers */ |
| 358 | seq_printf(s, "\n"); | 358 | seq_printf(s, "\n"); |
| 359 | } | 359 | } |
diff --git a/drivers/gpio/gpio-ml-ioh.c b/drivers/gpio/gpio-ml-ioh.c index f0febe5b8221..db01f151d41c 100644 --- a/drivers/gpio/gpio-ml-ioh.c +++ b/drivers/gpio/gpio-ml-ioh.c | |||
| @@ -611,17 +611,7 @@ static struct pci_driver ioh_gpio_driver = { | |||
| 611 | .resume = ioh_gpio_resume | 611 | .resume = ioh_gpio_resume |
| 612 | }; | 612 | }; |
| 613 | 613 | ||
| 614 | static int __init ioh_gpio_pci_init(void) | 614 | module_pci_driver(ioh_gpio_driver); |
| 615 | { | ||
| 616 | return pci_register_driver(&ioh_gpio_driver); | ||
| 617 | } | ||
| 618 | module_init(ioh_gpio_pci_init); | ||
| 619 | |||
| 620 | static void __exit ioh_gpio_pci_exit(void) | ||
| 621 | { | ||
| 622 | pci_unregister_driver(&ioh_gpio_driver); | ||
| 623 | } | ||
| 624 | module_exit(ioh_gpio_pci_exit); | ||
| 625 | 615 | ||
| 626 | MODULE_DESCRIPTION("OKI SEMICONDUCTOR ML-IOH series GPIO Driver"); | 616 | MODULE_DESCRIPTION("OKI SEMICONDUCTOR ML-IOH series GPIO Driver"); |
| 627 | MODULE_LICENSE("GPL"); | 617 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/gpio/gpio-mm-lantiq.c b/drivers/gpio/gpio-mm-lantiq.c new file mode 100644 index 000000000000..2983dfbd0668 --- /dev/null +++ b/drivers/gpio/gpio-mm-lantiq.c | |||
| @@ -0,0 +1,158 @@ | |||
| 1 | /* | ||
| 2 | * This program is free software; you can redistribute it and/or modify it | ||
| 3 | * under the terms of the GNU General Public License version 2 as published | ||
| 4 | * by the Free Software Foundation. | ||
| 5 | * | ||
| 6 | * Copyright (C) 2012 John Crispin <blogic@openwrt.org> | ||
| 7 | */ | ||
| 8 | |||
| 9 | #include <linux/init.h> | ||
| 10 | #include <linux/module.h> | ||
| 11 | #include <linux/types.h> | ||
| 12 | #include <linux/platform_device.h> | ||
| 13 | #include <linux/mutex.h> | ||
| 14 | #include <linux/gpio.h> | ||
| 15 | #include <linux/of.h> | ||
| 16 | #include <linux/of_gpio.h> | ||
| 17 | #include <linux/io.h> | ||
| 18 | #include <linux/slab.h> | ||
| 19 | |||
| 20 | #include <lantiq_soc.h> | ||
| 21 | |||
| 22 | /* | ||
| 23 | * By attaching hardware latches to the EBU it is possible to create output | ||
| 24 | * only gpios. This driver configures a special memory address, which when | ||
| 25 | * written to outputs 16 bit to the latches. | ||
| 26 | */ | ||
| 27 | |||
| 28 | #define LTQ_EBU_BUSCON 0x1e7ff /* 16 bit access, slowest timing */ | ||
| 29 | #define LTQ_EBU_WP 0x80000000 /* write protect bit */ | ||
| 30 | |||
| 31 | struct ltq_mm { | ||
| 32 | struct of_mm_gpio_chip mmchip; | ||
| 33 | u16 shadow; /* shadow the latches state */ | ||
| 34 | }; | ||
| 35 | |||
| 36 | /** | ||
| 37 | * ltq_mm_apply() - write the shadow value to the ebu address. | ||
| 38 | * @chip: Pointer to our private data structure. | ||
| 39 | * | ||
| 40 | * Write the shadow value to the EBU to set the gpios. We need to set the | ||
| 41 | * global EBU lock to make sure that PCI/MTD dont break. | ||
| 42 | */ | ||
| 43 | static void ltq_mm_apply(struct ltq_mm *chip) | ||
| 44 | { | ||
| 45 | unsigned long flags; | ||
| 46 | |||
| 47 | spin_lock_irqsave(&ebu_lock, flags); | ||
| 48 | ltq_ebu_w32(LTQ_EBU_BUSCON, LTQ_EBU_BUSCON1); | ||
| 49 | __raw_writew(chip->shadow, chip->mmchip.regs); | ||
| 50 | ltq_ebu_w32(LTQ_EBU_BUSCON | LTQ_EBU_WP, LTQ_EBU_BUSCON1); | ||
| 51 | spin_unlock_irqrestore(&ebu_lock, flags); | ||
| 52 | } | ||
| 53 | |||
| 54 | /** | ||
| 55 | * ltq_mm_set() - gpio_chip->set - set gpios. | ||
| 56 | * @gc: Pointer to gpio_chip device structure. | ||
| 57 | * @gpio: GPIO signal number. | ||
| 58 | * @val: Value to be written to specified signal. | ||
| 59 | * | ||
| 60 | * Set the shadow value and call ltq_mm_apply. | ||
| 61 | */ | ||
| 62 | static void ltq_mm_set(struct gpio_chip *gc, unsigned offset, int value) | ||
| 63 | { | ||
| 64 | struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc); | ||
| 65 | struct ltq_mm *chip = | ||
| 66 | container_of(mm_gc, struct ltq_mm, mmchip); | ||
| 67 | |||
| 68 | if (value) | ||
| 69 | chip->shadow |= (1 << offset); | ||
| 70 | else | ||
| 71 | chip->shadow &= ~(1 << offset); | ||
| 72 | ltq_mm_apply(chip); | ||
| 73 | } | ||
| 74 | |||
| 75 | /** | ||
| 76 | * ltq_mm_dir_out() - gpio_chip->dir_out - set gpio direction. | ||
| 77 | * @gc: Pointer to gpio_chip device structure. | ||
| 78 | * @gpio: GPIO signal number. | ||
| 79 | * @val: Value to be written to specified signal. | ||
| 80 | * | ||
| 81 | * Same as ltq_mm_set, always returns 0. | ||
| 82 | */ | ||
| 83 | static int ltq_mm_dir_out(struct gpio_chip *gc, unsigned offset, int value) | ||
| 84 | { | ||
| 85 | ltq_mm_set(gc, offset, value); | ||
| 86 | |||
| 87 | return 0; | ||
| 88 | } | ||
| 89 | |||
| 90 | /** | ||
| 91 | * ltq_mm_save_regs() - Set initial values of GPIO pins | ||
| 92 | * @mm_gc: pointer to memory mapped GPIO chip structure | ||
| 93 | */ | ||
| 94 | static void ltq_mm_save_regs(struct of_mm_gpio_chip *mm_gc) | ||
| 95 | { | ||
| 96 | struct ltq_mm *chip = | ||
| 97 | container_of(mm_gc, struct ltq_mm, mmchip); | ||
| 98 | |||
| 99 | /* tell the ebu controller which memory address we will be using */ | ||
| 100 | ltq_ebu_w32(CPHYSADDR(chip->mmchip.regs) | 0x1, LTQ_EBU_ADDRSEL1); | ||
| 101 | |||
| 102 | ltq_mm_apply(chip); | ||
| 103 | } | ||
| 104 | |||
| 105 | static int ltq_mm_probe(struct platform_device *pdev) | ||
| 106 | { | ||
| 107 | struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
| 108 | struct ltq_mm *chip; | ||
| 109 | const __be32 *shadow; | ||
| 110 | int ret = 0; | ||
| 111 | |||
| 112 | if (!res) { | ||
| 113 | dev_err(&pdev->dev, "failed to get memory resource\n"); | ||
| 114 | return -ENOENT; | ||
| 115 | } | ||
| 116 | |||
| 117 | chip = kzalloc(sizeof(*chip), GFP_KERNEL); | ||
| 118 | if (!chip) | ||
| 119 | return -ENOMEM; | ||
| 120 | |||
| 121 | chip->mmchip.gc.ngpio = 16; | ||
| 122 | chip->mmchip.gc.label = "gpio-mm-ltq"; | ||
| 123 | chip->mmchip.gc.direction_output = ltq_mm_dir_out; | ||
| 124 | chip->mmchip.gc.set = ltq_mm_set; | ||
| 125 | chip->mmchip.save_regs = ltq_mm_save_regs; | ||
| 126 | |||
| 127 | /* store the shadow value if one was passed by the devicetree */ | ||
| 128 | shadow = of_get_property(pdev->dev.of_node, "lantiq,shadow", NULL); | ||
| 129 | if (shadow) | ||
| 130 | chip->shadow = be32_to_cpu(*shadow); | ||
| 131 | |||
| 132 | ret = of_mm_gpiochip_add(pdev->dev.of_node, &chip->mmchip); | ||
| 133 | if (ret) | ||
| 134 | kfree(chip); | ||
| 135 | return ret; | ||
| 136 | } | ||
| 137 | |||
| 138 | static const struct of_device_id ltq_mm_match[] = { | ||
| 139 | { .compatible = "lantiq,gpio-mm" }, | ||
| 140 | {}, | ||
| 141 | }; | ||
| 142 | MODULE_DEVICE_TABLE(of, ltq_mm_match); | ||
| 143 | |||
| 144 | static struct platform_driver ltq_mm_driver = { | ||
| 145 | .probe = ltq_mm_probe, | ||
| 146 | .driver = { | ||
| 147 | .name = "gpio-mm-ltq", | ||
| 148 | .owner = THIS_MODULE, | ||
| 149 | .of_match_table = ltq_mm_match, | ||
| 150 | }, | ||
| 151 | }; | ||
| 152 | |||
| 153 | static int __init ltq_mm_init(void) | ||
| 154 | { | ||
| 155 | return platform_driver_register(<q_mm_driver); | ||
| 156 | } | ||
| 157 | |||
| 158 | subsys_initcall(ltq_mm_init); | ||
diff --git a/drivers/gpio/gpio-mpc8xxx.c b/drivers/gpio/gpio-mpc8xxx.c index e6568c19c939..5a1817eedd1b 100644 --- a/drivers/gpio/gpio-mpc8xxx.c +++ b/drivers/gpio/gpio-mpc8xxx.c | |||
| @@ -163,7 +163,8 @@ static void mpc8xxx_gpio_irq_cascade(unsigned int irq, struct irq_desc *desc) | |||
| 163 | if (mask) | 163 | if (mask) |
| 164 | generic_handle_irq(irq_linear_revmap(mpc8xxx_gc->irq, | 164 | generic_handle_irq(irq_linear_revmap(mpc8xxx_gc->irq, |
| 165 | 32 - ffs(mask))); | 165 | 32 - ffs(mask))); |
| 166 | chip->irq_eoi(&desc->irq_data); | 166 | if (chip->irq_eoi) |
| 167 | chip->irq_eoi(&desc->irq_data); | ||
| 167 | } | 168 | } |
| 168 | 169 | ||
| 169 | static void mpc8xxx_irq_unmask(struct irq_data *d) | 170 | static void mpc8xxx_irq_unmask(struct irq_data *d) |
diff --git a/drivers/gpio/gpio-msic.c b/drivers/gpio/gpio-msic.c new file mode 100644 index 000000000000..71a838f44501 --- /dev/null +++ b/drivers/gpio/gpio-msic.c | |||
| @@ -0,0 +1,339 @@ | |||
| 1 | /* | ||
| 2 | * Intel Medfield MSIC GPIO driver> | ||
| 3 | * Copyright (c) 2011, Intel Corporation. | ||
| 4 | * | ||
| 5 | * Author: Mathias Nyman <mathias.nyman@linux.intel.com> | ||
| 6 | * Based on intel_pmic_gpio.c | ||
| 7 | * | ||
| 8 | * This program is free software; you can redistribute it and/or modify it | ||
| 9 | * under the terms and conditions of the GNU General Public License, | ||
| 10 | * version 2, as published by the Free Software Foundation. | ||
| 11 | * | ||
| 12 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
| 13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
| 15 | * more details. | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU General Public License along with | ||
| 18 | * this program; if not, write to the Free Software Foundation, Inc., | ||
| 19 | * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 20 | * | ||
| 21 | */ | ||
| 22 | |||
| 23 | #include <linux/module.h> | ||
| 24 | #include <linux/kernel.h> | ||
| 25 | #include <linux/slab.h> | ||
| 26 | #include <linux/interrupt.h> | ||
| 27 | #include <linux/init.h> | ||
| 28 | #include <linux/gpio.h> | ||
| 29 | #include <linux/platform_device.h> | ||
| 30 | #include <linux/mfd/intel_msic.h> | ||
| 31 | |||
| 32 | /* the offset for the mapping of global gpio pin to irq */ | ||
| 33 | #define MSIC_GPIO_IRQ_OFFSET 0x100 | ||
| 34 | |||
| 35 | #define MSIC_GPIO_DIR_IN 0 | ||
| 36 | #define MSIC_GPIO_DIR_OUT BIT(5) | ||
| 37 | #define MSIC_GPIO_TRIG_FALL BIT(1) | ||
| 38 | #define MSIC_GPIO_TRIG_RISE BIT(2) | ||
| 39 | |||
| 40 | /* masks for msic gpio output GPIOxxxxCTLO registers */ | ||
| 41 | #define MSIC_GPIO_DIR_MASK BIT(5) | ||
| 42 | #define MSIC_GPIO_DRV_MASK BIT(4) | ||
| 43 | #define MSIC_GPIO_REN_MASK BIT(3) | ||
| 44 | #define MSIC_GPIO_RVAL_MASK (BIT(2) | BIT(1)) | ||
| 45 | #define MSIC_GPIO_DOUT_MASK BIT(0) | ||
| 46 | |||
| 47 | /* masks for msic gpio input GPIOxxxxCTLI registers */ | ||
| 48 | #define MSIC_GPIO_GLBYP_MASK BIT(5) | ||
| 49 | #define MSIC_GPIO_DBNC_MASK (BIT(4) | BIT(3)) | ||
| 50 | #define MSIC_GPIO_INTCNT_MASK (BIT(2) | BIT(1)) | ||
| 51 | #define MSIC_GPIO_DIN_MASK BIT(0) | ||
| 52 | |||
| 53 | #define MSIC_NUM_GPIO 24 | ||
| 54 | |||
| 55 | struct msic_gpio { | ||
| 56 | struct platform_device *pdev; | ||
| 57 | struct mutex buslock; | ||
| 58 | struct gpio_chip chip; | ||
| 59 | int irq; | ||
| 60 | unsigned irq_base; | ||
| 61 | unsigned long trig_change_mask; | ||
| 62 | unsigned trig_type; | ||
| 63 | }; | ||
| 64 | |||
| 65 | /* | ||
| 66 | * MSIC has 24 gpios, 16 low voltage (1.2-1.8v) and 8 high voltage (3v). | ||
| 67 | * Both the high and low voltage gpios are divided in two banks. | ||
| 68 | * GPIOs are numbered with GPIO0LV0 as gpio_base in the following order: | ||
| 69 | * GPIO0LV0..GPIO0LV7: low voltage, bank 0, gpio_base | ||
| 70 | * GPIO1LV0..GPIO1LV7: low voltage, bank 1, gpio_base + 8 | ||
| 71 | * GPIO0HV0..GPIO0HV3: high voltage, bank 0, gpio_base + 16 | ||
| 72 | * GPIO1HV0..GPIO1HV3: high voltage, bank 1, gpio_base + 20 | ||
| 73 | */ | ||
| 74 | |||
| 75 | static int msic_gpio_to_ireg(unsigned offset) | ||
| 76 | { | ||
| 77 | if (offset >= MSIC_NUM_GPIO) | ||
| 78 | return -EINVAL; | ||
| 79 | |||
| 80 | if (offset < 8) | ||
| 81 | return INTEL_MSIC_GPIO0LV0CTLI - offset; | ||
| 82 | if (offset < 16) | ||
| 83 | return INTEL_MSIC_GPIO1LV0CTLI - offset + 8; | ||
| 84 | if (offset < 20) | ||
| 85 | return INTEL_MSIC_GPIO0HV0CTLI - offset + 16; | ||
| 86 | |||
| 87 | return INTEL_MSIC_GPIO1HV0CTLI - offset + 20; | ||
| 88 | } | ||
| 89 | |||
| 90 | static int msic_gpio_to_oreg(unsigned offset) | ||
| 91 | { | ||
| 92 | if (offset >= MSIC_NUM_GPIO) | ||
| 93 | return -EINVAL; | ||
| 94 | |||
| 95 | if (offset < 8) | ||
| 96 | return INTEL_MSIC_GPIO0LV0CTLO - offset; | ||
| 97 | if (offset < 16) | ||
| 98 | return INTEL_MSIC_GPIO1LV0CTLO - offset + 8; | ||
| 99 | if (offset < 20) | ||
| 100 | return INTEL_MSIC_GPIO0HV0CTLO - offset + 16; | ||
| 101 | |||
| 102 | return INTEL_MSIC_GPIO1HV0CTLO + offset + 20; | ||
| 103 | } | ||
| 104 | |||
| 105 | static int msic_gpio_direction_input(struct gpio_chip *chip, unsigned offset) | ||
| 106 | { | ||
| 107 | int reg; | ||
| 108 | |||
| 109 | reg = msic_gpio_to_oreg(offset); | ||
| 110 | if (reg < 0) | ||
| 111 | return reg; | ||
| 112 | |||
| 113 | return intel_msic_reg_update(reg, MSIC_GPIO_DIR_IN, MSIC_GPIO_DIR_MASK); | ||
| 114 | } | ||
| 115 | |||
| 116 | static int msic_gpio_direction_output(struct gpio_chip *chip, | ||
| 117 | unsigned offset, int value) | ||
| 118 | { | ||
| 119 | int reg; | ||
| 120 | unsigned mask; | ||
| 121 | |||
| 122 | value = (!!value) | MSIC_GPIO_DIR_OUT; | ||
| 123 | mask = MSIC_GPIO_DIR_MASK | MSIC_GPIO_DOUT_MASK; | ||
| 124 | |||
| 125 | reg = msic_gpio_to_oreg(offset); | ||
| 126 | if (reg < 0) | ||
| 127 | return reg; | ||
| 128 | |||
| 129 | return intel_msic_reg_update(reg, value, mask); | ||
| 130 | } | ||
| 131 | |||
| 132 | static int msic_gpio_get(struct gpio_chip *chip, unsigned offset) | ||
| 133 | { | ||
| 134 | u8 r; | ||
| 135 | int ret; | ||
| 136 | int reg; | ||
| 137 | |||
| 138 | reg = msic_gpio_to_ireg(offset); | ||
| 139 | if (reg < 0) | ||
| 140 | return reg; | ||
| 141 | |||
| 142 | ret = intel_msic_reg_read(reg, &r); | ||
| 143 | if (ret < 0) | ||
| 144 | return ret; | ||
| 145 | |||
| 146 | return r & MSIC_GPIO_DIN_MASK; | ||
| 147 | } | ||
| 148 | |||
| 149 | static void msic_gpio_set(struct gpio_chip *chip, unsigned offset, int value) | ||
| 150 | { | ||
| 151 | int reg; | ||
| 152 | |||
| 153 | reg = msic_gpio_to_oreg(offset); | ||
| 154 | if (reg < 0) | ||
| 155 | return; | ||
| 156 | |||
| 157 | intel_msic_reg_update(reg, !!value , MSIC_GPIO_DOUT_MASK); | ||
| 158 | } | ||
| 159 | |||
| 160 | /* | ||
| 161 | * This is called from genirq with mg->buslock locked and | ||
| 162 | * irq_desc->lock held. We can not access the scu bus here, so we | ||
| 163 | * store the change and update in the bus_sync_unlock() function below | ||
| 164 | */ | ||
| 165 | static int msic_irq_type(struct irq_data *data, unsigned type) | ||
| 166 | { | ||
| 167 | struct msic_gpio *mg = irq_data_get_irq_chip_data(data); | ||
| 168 | u32 gpio = data->irq - mg->irq_base; | ||
| 169 | |||
| 170 | if (gpio >= mg->chip.ngpio) | ||
| 171 | return -EINVAL; | ||
| 172 | |||
| 173 | /* mark for which gpio the trigger changed, protected by buslock */ | ||
| 174 | mg->trig_change_mask |= (1 << gpio); | ||
| 175 | mg->trig_type = type; | ||
| 176 | |||
| 177 | return 0; | ||
| 178 | } | ||
| 179 | |||
| 180 | static int msic_gpio_to_irq(struct gpio_chip *chip, unsigned offset) | ||
| 181 | { | ||
| 182 | struct msic_gpio *mg = container_of(chip, struct msic_gpio, chip); | ||
| 183 | return mg->irq_base + offset; | ||
| 184 | } | ||
| 185 | |||
| 186 | static void msic_bus_lock(struct irq_data *data) | ||
| 187 | { | ||
| 188 | struct msic_gpio *mg = irq_data_get_irq_chip_data(data); | ||
| 189 | mutex_lock(&mg->buslock); | ||
| 190 | } | ||
| 191 | |||
| 192 | static void msic_bus_sync_unlock(struct irq_data *data) | ||
| 193 | { | ||
| 194 | struct msic_gpio *mg = irq_data_get_irq_chip_data(data); | ||
| 195 | int offset; | ||
| 196 | int reg; | ||
| 197 | u8 trig = 0; | ||
| 198 | |||
| 199 | /* We can only get one change at a time as the buslock covers the | ||
| 200 | entire transaction. The irq_desc->lock is dropped before we are | ||
| 201 | called but that is fine */ | ||
| 202 | if (mg->trig_change_mask) { | ||
| 203 | offset = __ffs(mg->trig_change_mask); | ||
| 204 | |||
| 205 | reg = msic_gpio_to_ireg(offset); | ||
| 206 | if (reg < 0) | ||
| 207 | goto out; | ||
| 208 | |||
| 209 | if (mg->trig_type & IRQ_TYPE_EDGE_RISING) | ||
| 210 | trig |= MSIC_GPIO_TRIG_RISE; | ||
| 211 | if (mg->trig_type & IRQ_TYPE_EDGE_FALLING) | ||
| 212 | trig |= MSIC_GPIO_TRIG_FALL; | ||
| 213 | |||
| 214 | intel_msic_reg_update(reg, trig, MSIC_GPIO_INTCNT_MASK); | ||
| 215 | mg->trig_change_mask = 0; | ||
| 216 | } | ||
| 217 | out: | ||
| 218 | mutex_unlock(&mg->buslock); | ||
| 219 | } | ||
| 220 | |||
| 221 | /* Firmware does all the masking and unmasking for us, no masking here. */ | ||
| 222 | static void msic_irq_unmask(struct irq_data *data) { } | ||
| 223 | |||
| 224 | static void msic_irq_mask(struct irq_data *data) { } | ||
| 225 | |||
| 226 | static struct irq_chip msic_irqchip = { | ||
| 227 | .name = "MSIC-GPIO", | ||
| 228 | .irq_mask = msic_irq_mask, | ||
| 229 | .irq_unmask = msic_irq_unmask, | ||
| 230 | .irq_set_type = msic_irq_type, | ||
| 231 | .irq_bus_lock = msic_bus_lock, | ||
| 232 | .irq_bus_sync_unlock = msic_bus_sync_unlock, | ||
| 233 | }; | ||
| 234 | |||
| 235 | static void msic_gpio_irq_handler(unsigned irq, struct irq_desc *desc) | ||
| 236 | { | ||
| 237 | struct irq_data *data = irq_desc_get_irq_data(desc); | ||
| 238 | struct msic_gpio *mg = irq_data_get_irq_handler_data(data); | ||
| 239 | struct irq_chip *chip = irq_data_get_irq_chip(data); | ||
| 240 | struct intel_msic *msic = pdev_to_intel_msic(mg->pdev); | ||
| 241 | int i; | ||
| 242 | int bitnr; | ||
| 243 | u8 pin; | ||
| 244 | unsigned long pending = 0; | ||
| 245 | |||
| 246 | for (i = 0; i < (mg->chip.ngpio / BITS_PER_BYTE); i++) { | ||
| 247 | intel_msic_irq_read(msic, INTEL_MSIC_GPIO0LVIRQ + i, &pin); | ||
| 248 | pending = pin; | ||
| 249 | |||
| 250 | if (pending) { | ||
| 251 | for_each_set_bit(bitnr, &pending, BITS_PER_BYTE) | ||
| 252 | generic_handle_irq(mg->irq_base + | ||
| 253 | (i * BITS_PER_BYTE) + bitnr); | ||
| 254 | } | ||
| 255 | } | ||
| 256 | chip->irq_eoi(data); | ||
| 257 | } | ||
| 258 | |||
| 259 | static int __devinit platform_msic_gpio_probe(struct platform_device *pdev) | ||
| 260 | { | ||
| 261 | struct device *dev = &pdev->dev; | ||
| 262 | struct intel_msic_gpio_pdata *pdata = dev->platform_data; | ||
| 263 | struct msic_gpio *mg; | ||
| 264 | int irq = platform_get_irq(pdev, 0); | ||
| 265 | int retval; | ||
| 266 | int i; | ||
| 267 | |||
| 268 | if (irq < 0) { | ||
| 269 | dev_err(dev, "no IRQ line\n"); | ||
| 270 | return -EINVAL; | ||
| 271 | } | ||
| 272 | |||
| 273 | if (!pdata || !pdata->gpio_base) { | ||
| 274 | dev_err(dev, "incorrect or missing platform data\n"); | ||
| 275 | return -EINVAL; | ||
| 276 | } | ||
| 277 | |||
| 278 | mg = kzalloc(sizeof(*mg), GFP_KERNEL); | ||
| 279 | if (!mg) | ||
| 280 | return -ENOMEM; | ||
| 281 | |||
| 282 | dev_set_drvdata(dev, mg); | ||
| 283 | |||
| 284 | mg->pdev = pdev; | ||
| 285 | mg->irq = irq; | ||
| 286 | mg->irq_base = pdata->gpio_base + MSIC_GPIO_IRQ_OFFSET; | ||
| 287 | mg->chip.label = "msic_gpio"; | ||
| 288 | mg->chip.direction_input = msic_gpio_direction_input; | ||
| 289 | mg->chip.direction_output = msic_gpio_direction_output; | ||
| 290 | mg->chip.get = msic_gpio_get; | ||
| 291 | mg->chip.set = msic_gpio_set; | ||
| 292 | mg->chip.to_irq = msic_gpio_to_irq; | ||
| 293 | mg->chip.base = pdata->gpio_base; | ||
| 294 | mg->chip.ngpio = MSIC_NUM_GPIO; | ||
| 295 | mg->chip.can_sleep = 1; | ||
| 296 | mg->chip.dev = dev; | ||
| 297 | |||
| 298 | mutex_init(&mg->buslock); | ||
| 299 | |||
| 300 | retval = gpiochip_add(&mg->chip); | ||
| 301 | if (retval) { | ||
| 302 | dev_err(dev, "Adding MSIC gpio chip failed\n"); | ||
| 303 | goto err; | ||
| 304 | } | ||
| 305 | |||
| 306 | for (i = 0; i < mg->chip.ngpio; i++) { | ||
| 307 | irq_set_chip_data(i + mg->irq_base, mg); | ||
| 308 | irq_set_chip_and_handler_name(i + mg->irq_base, | ||
| 309 | &msic_irqchip, | ||
| 310 | handle_simple_irq, | ||
| 311 | "demux"); | ||
| 312 | } | ||
| 313 | irq_set_chained_handler(mg->irq, msic_gpio_irq_handler); | ||
| 314 | irq_set_handler_data(mg->irq, mg); | ||
| 315 | |||
| 316 | return 0; | ||
| 317 | err: | ||
| 318 | kfree(mg); | ||
| 319 | return retval; | ||
| 320 | } | ||
| 321 | |||
| 322 | static struct platform_driver platform_msic_gpio_driver = { | ||
| 323 | .driver = { | ||
| 324 | .name = "msic_gpio", | ||
| 325 | .owner = THIS_MODULE, | ||
| 326 | }, | ||
| 327 | .probe = platform_msic_gpio_probe, | ||
| 328 | }; | ||
| 329 | |||
| 330 | static int __init platform_msic_gpio_init(void) | ||
| 331 | { | ||
| 332 | return platform_driver_register(&platform_msic_gpio_driver); | ||
| 333 | } | ||
| 334 | |||
| 335 | subsys_initcall(platform_msic_gpio_init); | ||
| 336 | |||
| 337 | MODULE_AUTHOR("Mathias Nyman <mathias.nyman@linux.intel.com>"); | ||
| 338 | MODULE_DESCRIPTION("Intel Medfield MSIC GPIO driver"); | ||
| 339 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/gpio/gpio-mxc.c b/drivers/gpio/gpio-mxc.c index e79147634573..c337143b18f8 100644 --- a/drivers/gpio/gpio-mxc.c +++ b/drivers/gpio/gpio-mxc.c | |||
| @@ -417,7 +417,7 @@ static int __devinit mxc_gpio_probe(struct platform_device *pdev) | |||
| 417 | err = bgpio_init(&port->bgc, &pdev->dev, 4, | 417 | err = bgpio_init(&port->bgc, &pdev->dev, 4, |
| 418 | port->base + GPIO_PSR, | 418 | port->base + GPIO_PSR, |
| 419 | port->base + GPIO_DR, NULL, | 419 | port->base + GPIO_DR, NULL, |
| 420 | port->base + GPIO_GDIR, NULL, false); | 420 | port->base + GPIO_GDIR, NULL, 0); |
| 421 | if (err) | 421 | if (err) |
| 422 | goto out_iounmap; | 422 | goto out_iounmap; |
| 423 | 423 | ||
diff --git a/drivers/gpio/gpio-mxs.c b/drivers/gpio/gpio-mxs.c index 385c58e8405b..39e495669961 100644 --- a/drivers/gpio/gpio-mxs.c +++ b/drivers/gpio/gpio-mxs.c | |||
| @@ -25,23 +25,25 @@ | |||
| 25 | #include <linux/io.h> | 25 | #include <linux/io.h> |
| 26 | #include <linux/irq.h> | 26 | #include <linux/irq.h> |
| 27 | #include <linux/gpio.h> | 27 | #include <linux/gpio.h> |
| 28 | #include <linux/of.h> | ||
| 29 | #include <linux/of_address.h> | ||
| 30 | #include <linux/of_device.h> | ||
| 28 | #include <linux/platform_device.h> | 31 | #include <linux/platform_device.h> |
| 29 | #include <linux/slab.h> | 32 | #include <linux/slab.h> |
| 30 | #include <linux/basic_mmio_gpio.h> | 33 | #include <linux/basic_mmio_gpio.h> |
| 31 | #include <linux/module.h> | 34 | #include <linux/module.h> |
| 32 | #include <mach/mxs.h> | ||
| 33 | 35 | ||
| 34 | #define MXS_SET 0x4 | 36 | #define MXS_SET 0x4 |
| 35 | #define MXS_CLR 0x8 | 37 | #define MXS_CLR 0x8 |
| 36 | 38 | ||
| 37 | #define PINCTRL_DOUT(n) ((cpu_is_mx23() ? 0x0500 : 0x0700) + (n) * 0x10) | 39 | #define PINCTRL_DOUT(p) ((is_imx23_gpio(p) ? 0x0500 : 0x0700) + (p->id) * 0x10) |
| 38 | #define PINCTRL_DIN(n) ((cpu_is_mx23() ? 0x0600 : 0x0900) + (n) * 0x10) | 40 | #define PINCTRL_DIN(p) ((is_imx23_gpio(p) ? 0x0600 : 0x0900) + (p->id) * 0x10) |
| 39 | #define PINCTRL_DOE(n) ((cpu_is_mx23() ? 0x0700 : 0x0b00) + (n) * 0x10) | 41 | #define PINCTRL_DOE(p) ((is_imx23_gpio(p) ? 0x0700 : 0x0b00) + (p->id) * 0x10) |
| 40 | #define PINCTRL_PIN2IRQ(n) ((cpu_is_mx23() ? 0x0800 : 0x1000) + (n) * 0x10) | 42 | #define PINCTRL_PIN2IRQ(p) ((is_imx23_gpio(p) ? 0x0800 : 0x1000) + (p->id) * 0x10) |
| 41 | #define PINCTRL_IRQEN(n) ((cpu_is_mx23() ? 0x0900 : 0x1100) + (n) * 0x10) | 43 | #define PINCTRL_IRQEN(p) ((is_imx23_gpio(p) ? 0x0900 : 0x1100) + (p->id) * 0x10) |
| 42 | #define PINCTRL_IRQLEV(n) ((cpu_is_mx23() ? 0x0a00 : 0x1200) + (n) * 0x10) | 44 | #define PINCTRL_IRQLEV(p) ((is_imx23_gpio(p) ? 0x0a00 : 0x1200) + (p->id) * 0x10) |
| 43 | #define PINCTRL_IRQPOL(n) ((cpu_is_mx23() ? 0x0b00 : 0x1300) + (n) * 0x10) | 45 | #define PINCTRL_IRQPOL(p) ((is_imx23_gpio(p) ? 0x0b00 : 0x1300) + (p->id) * 0x10) |
| 44 | #define PINCTRL_IRQSTAT(n) ((cpu_is_mx23() ? 0x0c00 : 0x1400) + (n) * 0x10) | 46 | #define PINCTRL_IRQSTAT(p) ((is_imx23_gpio(p) ? 0x0c00 : 0x1400) + (p->id) * 0x10) |
| 45 | 47 | ||
| 46 | #define GPIO_INT_FALL_EDGE 0x0 | 48 | #define GPIO_INT_FALL_EDGE 0x0 |
| 47 | #define GPIO_INT_LOW_LEV 0x1 | 49 | #define GPIO_INT_LOW_LEV 0x1 |
| @@ -52,14 +54,30 @@ | |||
| 52 | 54 | ||
| 53 | #define irq_to_gpio(irq) ((irq) - MXS_GPIO_IRQ_START) | 55 | #define irq_to_gpio(irq) ((irq) - MXS_GPIO_IRQ_START) |
| 54 | 56 | ||
| 57 | enum mxs_gpio_id { | ||
| 58 | IMX23_GPIO, | ||
| 59 | IMX28_GPIO, | ||
| 60 | }; | ||
| 61 | |||
| 55 | struct mxs_gpio_port { | 62 | struct mxs_gpio_port { |
| 56 | void __iomem *base; | 63 | void __iomem *base; |
| 57 | int id; | 64 | int id; |
| 58 | int irq; | 65 | int irq; |
| 59 | int virtual_irq_start; | 66 | int virtual_irq_start; |
| 60 | struct bgpio_chip bgc; | 67 | struct bgpio_chip bgc; |
| 68 | enum mxs_gpio_id devid; | ||
| 61 | }; | 69 | }; |
| 62 | 70 | ||
| 71 | static inline int is_imx23_gpio(struct mxs_gpio_port *port) | ||
| 72 | { | ||
| 73 | return port->devid == IMX23_GPIO; | ||
| 74 | } | ||
| 75 | |||
| 76 | static inline int is_imx28_gpio(struct mxs_gpio_port *port) | ||
| 77 | { | ||
| 78 | return port->devid == IMX28_GPIO; | ||
| 79 | } | ||
| 80 | |||
| 63 | /* Note: This driver assumes 32 GPIOs are handled in one register */ | 81 | /* Note: This driver assumes 32 GPIOs are handled in one register */ |
| 64 | 82 | ||
| 65 | static int mxs_gpio_set_irq_type(struct irq_data *d, unsigned int type) | 83 | static int mxs_gpio_set_irq_type(struct irq_data *d, unsigned int type) |
| @@ -89,21 +107,21 @@ static int mxs_gpio_set_irq_type(struct irq_data *d, unsigned int type) | |||
| 89 | } | 107 | } |
| 90 | 108 | ||
| 91 | /* set level or edge */ | 109 | /* set level or edge */ |
| 92 | pin_addr = port->base + PINCTRL_IRQLEV(port->id); | 110 | pin_addr = port->base + PINCTRL_IRQLEV(port); |
| 93 | if (edge & GPIO_INT_LEV_MASK) | 111 | if (edge & GPIO_INT_LEV_MASK) |
| 94 | writel(pin_mask, pin_addr + MXS_SET); | 112 | writel(pin_mask, pin_addr + MXS_SET); |
| 95 | else | 113 | else |
| 96 | writel(pin_mask, pin_addr + MXS_CLR); | 114 | writel(pin_mask, pin_addr + MXS_CLR); |
| 97 | 115 | ||
| 98 | /* set polarity */ | 116 | /* set polarity */ |
| 99 | pin_addr = port->base + PINCTRL_IRQPOL(port->id); | 117 | pin_addr = port->base + PINCTRL_IRQPOL(port); |
| 100 | if (edge & GPIO_INT_POL_MASK) | 118 | if (edge & GPIO_INT_POL_MASK) |
| 101 | writel(pin_mask, pin_addr + MXS_SET); | 119 | writel(pin_mask, pin_addr + MXS_SET); |
| 102 | else | 120 | else |
| 103 | writel(pin_mask, pin_addr + MXS_CLR); | 121 | writel(pin_mask, pin_addr + MXS_CLR); |
| 104 | 122 | ||
| 105 | writel(1 << (gpio & 0x1f), | 123 | writel(1 << (gpio & 0x1f), |
| 106 | port->base + PINCTRL_IRQSTAT(port->id) + MXS_CLR); | 124 | port->base + PINCTRL_IRQSTAT(port) + MXS_CLR); |
| 107 | 125 | ||
| 108 | return 0; | 126 | return 0; |
| 109 | } | 127 | } |
| @@ -117,8 +135,8 @@ static void mxs_gpio_irq_handler(u32 irq, struct irq_desc *desc) | |||
| 117 | 135 | ||
| 118 | desc->irq_data.chip->irq_ack(&desc->irq_data); | 136 | desc->irq_data.chip->irq_ack(&desc->irq_data); |
| 119 | 137 | ||
| 120 | irq_stat = readl(port->base + PINCTRL_IRQSTAT(port->id)) & | 138 | irq_stat = readl(port->base + PINCTRL_IRQSTAT(port)) & |
| 121 | readl(port->base + PINCTRL_IRQEN(port->id)); | 139 | readl(port->base + PINCTRL_IRQEN(port)); |
| 122 | 140 | ||
| 123 | while (irq_stat != 0) { | 141 | while (irq_stat != 0) { |
| 124 | int irqoffset = fls(irq_stat) - 1; | 142 | int irqoffset = fls(irq_stat) - 1; |
| @@ -164,8 +182,8 @@ static void __init mxs_gpio_init_gc(struct mxs_gpio_port *port) | |||
| 164 | ct->chip.irq_unmask = irq_gc_mask_set_bit; | 182 | ct->chip.irq_unmask = irq_gc_mask_set_bit; |
| 165 | ct->chip.irq_set_type = mxs_gpio_set_irq_type; | 183 | ct->chip.irq_set_type = mxs_gpio_set_irq_type; |
| 166 | ct->chip.irq_set_wake = mxs_gpio_set_wake_irq; | 184 | ct->chip.irq_set_wake = mxs_gpio_set_wake_irq; |
| 167 | ct->regs.ack = PINCTRL_IRQSTAT(port->id) + MXS_CLR; | 185 | ct->regs.ack = PINCTRL_IRQSTAT(port) + MXS_CLR; |
| 168 | ct->regs.mask = PINCTRL_IRQEN(port->id); | 186 | ct->regs.mask = PINCTRL_IRQEN(port); |
| 169 | 187 | ||
| 170 | irq_setup_generic_chip(gc, IRQ_MSK(32), 0, IRQ_NOREQUEST, 0); | 188 | irq_setup_generic_chip(gc, IRQ_MSK(32), 0, IRQ_NOREQUEST, 0); |
| 171 | } | 189 | } |
| @@ -179,60 +197,83 @@ static int mxs_gpio_to_irq(struct gpio_chip *gc, unsigned offset) | |||
| 179 | return port->virtual_irq_start + offset; | 197 | return port->virtual_irq_start + offset; |
| 180 | } | 198 | } |
| 181 | 199 | ||
| 200 | static struct platform_device_id mxs_gpio_ids[] = { | ||
| 201 | { | ||
| 202 | .name = "imx23-gpio", | ||
| 203 | .driver_data = IMX23_GPIO, | ||
| 204 | }, { | ||
| 205 | .name = "imx28-gpio", | ||
| 206 | .driver_data = IMX28_GPIO, | ||
| 207 | }, { | ||
| 208 | /* sentinel */ | ||
| 209 | } | ||
| 210 | }; | ||
| 211 | MODULE_DEVICE_TABLE(platform, mxs_gpio_ids); | ||
| 212 | |||
| 213 | static const struct of_device_id mxs_gpio_dt_ids[] = { | ||
| 214 | { .compatible = "fsl,imx23-gpio", .data = (void *) IMX23_GPIO, }, | ||
| 215 | { .compatible = "fsl,imx28-gpio", .data = (void *) IMX28_GPIO, }, | ||
| 216 | { /* sentinel */ } | ||
| 217 | }; | ||
| 218 | MODULE_DEVICE_TABLE(of, mxs_gpio_dt_ids); | ||
| 219 | |||
| 182 | static int __devinit mxs_gpio_probe(struct platform_device *pdev) | 220 | static int __devinit mxs_gpio_probe(struct platform_device *pdev) |
| 183 | { | 221 | { |
| 222 | const struct of_device_id *of_id = | ||
| 223 | of_match_device(mxs_gpio_dt_ids, &pdev->dev); | ||
| 224 | struct device_node *np = pdev->dev.of_node; | ||
| 225 | struct device_node *parent; | ||
| 184 | static void __iomem *base; | 226 | static void __iomem *base; |
| 185 | struct mxs_gpio_port *port; | 227 | struct mxs_gpio_port *port; |
| 186 | struct resource *iores = NULL; | 228 | struct resource *iores = NULL; |
| 187 | int err; | 229 | int err; |
| 188 | 230 | ||
| 189 | port = kzalloc(sizeof(struct mxs_gpio_port), GFP_KERNEL); | 231 | port = devm_kzalloc(&pdev->dev, sizeof(*port), GFP_KERNEL); |
| 190 | if (!port) | 232 | if (!port) |
| 191 | return -ENOMEM; | 233 | return -ENOMEM; |
| 192 | 234 | ||
| 193 | port->id = pdev->id; | 235 | if (np) { |
| 236 | port->id = of_alias_get_id(np, "gpio"); | ||
| 237 | if (port->id < 0) | ||
| 238 | return port->id; | ||
| 239 | port->devid = (enum mxs_gpio_id) of_id->data; | ||
| 240 | } else { | ||
| 241 | port->id = pdev->id; | ||
| 242 | port->devid = pdev->id_entry->driver_data; | ||
| 243 | } | ||
| 194 | port->virtual_irq_start = MXS_GPIO_IRQ_START + port->id * 32; | 244 | port->virtual_irq_start = MXS_GPIO_IRQ_START + port->id * 32; |
| 195 | 245 | ||
| 246 | port->irq = platform_get_irq(pdev, 0); | ||
| 247 | if (port->irq < 0) | ||
| 248 | return port->irq; | ||
| 249 | |||
| 196 | /* | 250 | /* |
| 197 | * map memory region only once, as all the gpio ports | 251 | * map memory region only once, as all the gpio ports |
| 198 | * share the same one | 252 | * share the same one |
| 199 | */ | 253 | */ |
| 200 | if (!base) { | 254 | if (!base) { |
| 201 | iores = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 255 | if (np) { |
| 202 | if (!iores) { | 256 | parent = of_get_parent(np); |
| 203 | err = -ENODEV; | 257 | base = of_iomap(parent, 0); |
| 204 | goto out_kfree; | 258 | of_node_put(parent); |
| 205 | } | 259 | } else { |
| 206 | 260 | iores = platform_get_resource(pdev, IORESOURCE_MEM, 0); | |
| 207 | if (!request_mem_region(iores->start, resource_size(iores), | 261 | base = devm_request_and_ioremap(&pdev->dev, iores); |
| 208 | pdev->name)) { | ||
| 209 | err = -EBUSY; | ||
| 210 | goto out_kfree; | ||
| 211 | } | ||
| 212 | |||
| 213 | base = ioremap(iores->start, resource_size(iores)); | ||
| 214 | if (!base) { | ||
| 215 | err = -ENOMEM; | ||
| 216 | goto out_release_mem; | ||
| 217 | } | 262 | } |
| 263 | if (!base) | ||
| 264 | return -EADDRNOTAVAIL; | ||
| 218 | } | 265 | } |
| 219 | port->base = base; | 266 | port->base = base; |
| 220 | 267 | ||
| 221 | port->irq = platform_get_irq(pdev, 0); | ||
| 222 | if (port->irq < 0) { | ||
| 223 | err = -EINVAL; | ||
| 224 | goto out_iounmap; | ||
| 225 | } | ||
| 226 | |||
| 227 | /* | 268 | /* |
| 228 | * select the pin interrupt functionality but initially | 269 | * select the pin interrupt functionality but initially |
| 229 | * disable the interrupts | 270 | * disable the interrupts |
| 230 | */ | 271 | */ |
| 231 | writel(~0U, port->base + PINCTRL_PIN2IRQ(port->id)); | 272 | writel(~0U, port->base + PINCTRL_PIN2IRQ(port)); |
| 232 | writel(0, port->base + PINCTRL_IRQEN(port->id)); | 273 | writel(0, port->base + PINCTRL_IRQEN(port)); |
| 233 | 274 | ||
| 234 | /* clear address has to be used to clear IRQSTAT bits */ | 275 | /* clear address has to be used to clear IRQSTAT bits */ |
| 235 | writel(~0U, port->base + PINCTRL_IRQSTAT(port->id) + MXS_CLR); | 276 | writel(~0U, port->base + PINCTRL_IRQSTAT(port) + MXS_CLR); |
| 236 | 277 | ||
| 237 | /* gpio-mxs can be a generic irq chip */ | 278 | /* gpio-mxs can be a generic irq chip */ |
| 238 | mxs_gpio_init_gc(port); | 279 | mxs_gpio_init_gc(port); |
| @@ -242,41 +283,32 @@ static int __devinit mxs_gpio_probe(struct platform_device *pdev) | |||
| 242 | irq_set_handler_data(port->irq, port); | 283 | irq_set_handler_data(port->irq, port); |
| 243 | 284 | ||
| 244 | err = bgpio_init(&port->bgc, &pdev->dev, 4, | 285 | err = bgpio_init(&port->bgc, &pdev->dev, 4, |
| 245 | port->base + PINCTRL_DIN(port->id), | 286 | port->base + PINCTRL_DIN(port), |
| 246 | port->base + PINCTRL_DOUT(port->id), NULL, | 287 | port->base + PINCTRL_DOUT(port), NULL, |
| 247 | port->base + PINCTRL_DOE(port->id), NULL, false); | 288 | port->base + PINCTRL_DOE(port), NULL, 0); |
| 248 | if (err) | 289 | if (err) |
| 249 | goto out_iounmap; | 290 | return err; |
| 250 | 291 | ||
| 251 | port->bgc.gc.to_irq = mxs_gpio_to_irq; | 292 | port->bgc.gc.to_irq = mxs_gpio_to_irq; |
| 252 | port->bgc.gc.base = port->id * 32; | 293 | port->bgc.gc.base = port->id * 32; |
| 253 | 294 | ||
| 254 | err = gpiochip_add(&port->bgc.gc); | 295 | err = gpiochip_add(&port->bgc.gc); |
| 255 | if (err) | 296 | if (err) { |
| 256 | goto out_bgpio_remove; | 297 | bgpio_remove(&port->bgc); |
| 298 | return err; | ||
| 299 | } | ||
| 257 | 300 | ||
| 258 | return 0; | 301 | return 0; |
| 259 | |||
| 260 | out_bgpio_remove: | ||
| 261 | bgpio_remove(&port->bgc); | ||
| 262 | out_iounmap: | ||
| 263 | if (iores) | ||
| 264 | iounmap(port->base); | ||
| 265 | out_release_mem: | ||
| 266 | if (iores) | ||
| 267 | release_mem_region(iores->start, resource_size(iores)); | ||
| 268 | out_kfree: | ||
| 269 | kfree(port); | ||
| 270 | dev_info(&pdev->dev, "%s failed with errno %d\n", __func__, err); | ||
| 271 | return err; | ||
| 272 | } | 302 | } |
| 273 | 303 | ||
| 274 | static struct platform_driver mxs_gpio_driver = { | 304 | static struct platform_driver mxs_gpio_driver = { |
| 275 | .driver = { | 305 | .driver = { |
| 276 | .name = "gpio-mxs", | 306 | .name = "gpio-mxs", |
| 277 | .owner = THIS_MODULE, | 307 | .owner = THIS_MODULE, |
| 308 | .of_match_table = mxs_gpio_dt_ids, | ||
| 278 | }, | 309 | }, |
| 279 | .probe = mxs_gpio_probe, | 310 | .probe = mxs_gpio_probe, |
| 311 | .id_table = mxs_gpio_ids, | ||
| 280 | }; | 312 | }; |
| 281 | 313 | ||
| 282 | static int __init mxs_gpio_init(void) | 314 | static int __init mxs_gpio_init(void) |
diff --git a/drivers/gpio/gpio-nomadik.c b/drivers/gpio/gpio-nomadik.c deleted file mode 100644 index 839624f9fe6a..000000000000 --- a/drivers/gpio/gpio-nomadik.c +++ /dev/null | |||
| @@ -1,1187 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * Generic GPIO driver for logic cells found in the Nomadik SoC | ||
| 3 | * | ||
| 4 | * Copyright (C) 2008,2009 STMicroelectronics | ||
| 5 | * Copyright (C) 2009 Alessandro Rubini <rubini@unipv.it> | ||
| 6 | * Rewritten based on work by Prafulla WADASKAR <prafulla.wadaskar@st.com> | ||
| 7 | * Copyright (C) 2011 Linus Walleij <linus.walleij@linaro.org> | ||
| 8 | * | ||
| 9 | * This program is free software; you can redistribute it and/or modify | ||
| 10 | * it under the terms of the GNU General Public License version 2 as | ||
| 11 | * published by the Free Software Foundation. | ||
| 12 | */ | ||
| 13 | #include <linux/kernel.h> | ||
| 14 | #include <linux/module.h> | ||
| 15 | #include <linux/init.h> | ||
| 16 | #include <linux/device.h> | ||
| 17 | #include <linux/platform_device.h> | ||
| 18 | #include <linux/io.h> | ||
| 19 | #include <linux/clk.h> | ||
| 20 | #include <linux/err.h> | ||
| 21 | #include <linux/gpio.h> | ||
| 22 | #include <linux/spinlock.h> | ||
| 23 | #include <linux/interrupt.h> | ||
| 24 | #include <linux/irq.h> | ||
| 25 | #include <linux/slab.h> | ||
| 26 | |||
| 27 | #include <asm/mach/irq.h> | ||
| 28 | |||
| 29 | #include <plat/pincfg.h> | ||
| 30 | #include <plat/gpio-nomadik.h> | ||
| 31 | #include <mach/hardware.h> | ||
| 32 | #include <asm/gpio.h> | ||
| 33 | |||
| 34 | /* | ||
| 35 | * The GPIO module in the Nomadik family of Systems-on-Chip is an | ||
| 36 | * AMBA device, managing 32 pins and alternate functions. The logic block | ||
| 37 | * is currently used in the Nomadik and ux500. | ||
| 38 | * | ||
| 39 | * Symbols in this file are called "nmk_gpio" for "nomadik gpio" | ||
| 40 | */ | ||
| 41 | |||
| 42 | #define NMK_GPIO_PER_CHIP 32 | ||
| 43 | |||
| 44 | struct nmk_gpio_chip { | ||
| 45 | struct gpio_chip chip; | ||
| 46 | void __iomem *addr; | ||
| 47 | struct clk *clk; | ||
| 48 | unsigned int bank; | ||
| 49 | unsigned int parent_irq; | ||
| 50 | int secondary_parent_irq; | ||
| 51 | u32 (*get_secondary_status)(unsigned int bank); | ||
| 52 | void (*set_ioforce)(bool enable); | ||
| 53 | spinlock_t lock; | ||
| 54 | bool sleepmode; | ||
| 55 | /* Keep track of configured edges */ | ||
| 56 | u32 edge_rising; | ||
| 57 | u32 edge_falling; | ||
| 58 | u32 real_wake; | ||
| 59 | u32 rwimsc; | ||
| 60 | u32 fwimsc; | ||
| 61 | u32 slpm; | ||
| 62 | u32 pull_up; | ||
| 63 | }; | ||
| 64 | |||
| 65 | static struct nmk_gpio_chip * | ||
| 66 | nmk_gpio_chips[DIV_ROUND_UP(ARCH_NR_GPIOS, NMK_GPIO_PER_CHIP)]; | ||
| 67 | |||
| 68 | static DEFINE_SPINLOCK(nmk_gpio_slpm_lock); | ||
| 69 | |||
| 70 | #define NUM_BANKS ARRAY_SIZE(nmk_gpio_chips) | ||
| 71 | |||
| 72 | static void __nmk_gpio_set_mode(struct nmk_gpio_chip *nmk_chip, | ||
| 73 | unsigned offset, int gpio_mode) | ||
| 74 | { | ||
| 75 | u32 bit = 1 << offset; | ||
| 76 | u32 afunc, bfunc; | ||
| 77 | |||
| 78 | afunc = readl(nmk_chip->addr + NMK_GPIO_AFSLA) & ~bit; | ||
| 79 | bfunc = readl(nmk_chip->addr + NMK_GPIO_AFSLB) & ~bit; | ||
| 80 | if (gpio_mode & NMK_GPIO_ALT_A) | ||
| 81 | afunc |= bit; | ||
| 82 | if (gpio_mode & NMK_GPIO_ALT_B) | ||
| 83 | bfunc |= bit; | ||
| 84 | writel(afunc, nmk_chip->addr + NMK_GPIO_AFSLA); | ||
| 85 | writel(bfunc, nmk_chip->addr + NMK_GPIO_AFSLB); | ||
| 86 | } | ||
| 87 | |||
| 88 | static void __nmk_gpio_set_slpm(struct nmk_gpio_chip *nmk_chip, | ||
| 89 | unsigned offset, enum nmk_gpio_slpm mode) | ||
| 90 | { | ||
| 91 | u32 bit = 1 << offset; | ||
| 92 | u32 slpm; | ||
| 93 | |||
| 94 | slpm = readl(nmk_chip->addr + NMK_GPIO_SLPC); | ||
| 95 | if (mode == NMK_GPIO_SLPM_NOCHANGE) | ||
| 96 | slpm |= bit; | ||
| 97 | else | ||
| 98 | slpm &= ~bit; | ||
| 99 | writel(slpm, nmk_chip->addr + NMK_GPIO_SLPC); | ||
| 100 | } | ||
| 101 | |||
| 102 | static void __nmk_gpio_set_pull(struct nmk_gpio_chip *nmk_chip, | ||
| 103 | unsigned offset, enum nmk_gpio_pull pull) | ||
| 104 | { | ||
| 105 | u32 bit = 1 << offset; | ||
| 106 | u32 pdis; | ||
| 107 | |||
| 108 | pdis = readl(nmk_chip->addr + NMK_GPIO_PDIS); | ||
| 109 | if (pull == NMK_GPIO_PULL_NONE) { | ||
| 110 | pdis |= bit; | ||
| 111 | nmk_chip->pull_up &= ~bit; | ||
| 112 | } else { | ||
| 113 | pdis &= ~bit; | ||
| 114 | } | ||
| 115 | |||
| 116 | writel(pdis, nmk_chip->addr + NMK_GPIO_PDIS); | ||
| 117 | |||
| 118 | if (pull == NMK_GPIO_PULL_UP) { | ||
| 119 | nmk_chip->pull_up |= bit; | ||
| 120 | writel(bit, nmk_chip->addr + NMK_GPIO_DATS); | ||
| 121 | } else if (pull == NMK_GPIO_PULL_DOWN) { | ||
| 122 | nmk_chip->pull_up &= ~bit; | ||
| 123 | writel(bit, nmk_chip->addr + NMK_GPIO_DATC); | ||
| 124 | } | ||
| 125 | } | ||
| 126 | |||
| 127 | static void __nmk_gpio_make_input(struct nmk_gpio_chip *nmk_chip, | ||
| 128 | unsigned offset) | ||
| 129 | { | ||
| 130 | writel(1 << offset, nmk_chip->addr + NMK_GPIO_DIRC); | ||
| 131 | } | ||
| 132 | |||
| 133 | static void __nmk_gpio_set_output(struct nmk_gpio_chip *nmk_chip, | ||
| 134 | unsigned offset, int val) | ||
| 135 | { | ||
| 136 | if (val) | ||
| 137 | writel(1 << offset, nmk_chip->addr + NMK_GPIO_DATS); | ||
| 138 | else | ||
| 139 | writel(1 << offset, nmk_chip->addr + NMK_GPIO_DATC); | ||
| 140 | } | ||
| 141 | |||
| 142 | static void __nmk_gpio_make_output(struct nmk_gpio_chip *nmk_chip, | ||
| 143 | unsigned offset, int val) | ||
| 144 | { | ||
| 145 | writel(1 << offset, nmk_chip->addr + NMK_GPIO_DIRS); | ||
| 146 | __nmk_gpio_set_output(nmk_chip, offset, val); | ||
| 147 | } | ||
| 148 | |||
| 149 | static void __nmk_gpio_set_mode_safe(struct nmk_gpio_chip *nmk_chip, | ||
| 150 | unsigned offset, int gpio_mode, | ||
| 151 | bool glitch) | ||
| 152 | { | ||
| 153 | u32 rwimsc = readl(nmk_chip->addr + NMK_GPIO_RWIMSC); | ||
| 154 | u32 fwimsc = readl(nmk_chip->addr + NMK_GPIO_FWIMSC); | ||
| 155 | |||
| 156 | if (glitch && nmk_chip->set_ioforce) { | ||
| 157 | u32 bit = BIT(offset); | ||
| 158 | |||
| 159 | /* Prevent spurious wakeups */ | ||
| 160 | writel(rwimsc & ~bit, nmk_chip->addr + NMK_GPIO_RWIMSC); | ||
| 161 | writel(fwimsc & ~bit, nmk_chip->addr + NMK_GPIO_FWIMSC); | ||
| 162 | |||
| 163 | nmk_chip->set_ioforce(true); | ||
| 164 | } | ||
| 165 | |||
| 166 | __nmk_gpio_set_mode(nmk_chip, offset, gpio_mode); | ||
| 167 | |||
| 168 | if (glitch && nmk_chip->set_ioforce) { | ||
| 169 | nmk_chip->set_ioforce(false); | ||
| 170 | |||
| 171 | writel(rwimsc, nmk_chip->addr + NMK_GPIO_RWIMSC); | ||
| 172 | writel(fwimsc, nmk_chip->addr + NMK_GPIO_FWIMSC); | ||
| 173 | } | ||
| 174 | } | ||
| 175 | |||
| 176 | static void __nmk_config_pin(struct nmk_gpio_chip *nmk_chip, unsigned offset, | ||
| 177 | pin_cfg_t cfg, bool sleep, unsigned int *slpmregs) | ||
| 178 | { | ||
| 179 | static const char *afnames[] = { | ||
| 180 | [NMK_GPIO_ALT_GPIO] = "GPIO", | ||
| 181 | [NMK_GPIO_ALT_A] = "A", | ||
| 182 | [NMK_GPIO_ALT_B] = "B", | ||
| 183 | [NMK_GPIO_ALT_C] = "C" | ||
| 184 | }; | ||
| 185 | static const char *pullnames[] = { | ||
| 186 | [NMK_GPIO_PULL_NONE] = "none", | ||
| 187 | [NMK_GPIO_PULL_UP] = "up", | ||
| 188 | [NMK_GPIO_PULL_DOWN] = "down", | ||
| 189 | [3] /* illegal */ = "??" | ||
| 190 | }; | ||
| 191 | static const char *slpmnames[] = { | ||
| 192 | [NMK_GPIO_SLPM_INPUT] = "input/wakeup", | ||
| 193 | [NMK_GPIO_SLPM_NOCHANGE] = "no-change/no-wakeup", | ||
| 194 | }; | ||
| 195 | |||
| 196 | int pin = PIN_NUM(cfg); | ||
| 197 | int pull = PIN_PULL(cfg); | ||
| 198 | int af = PIN_ALT(cfg); | ||
| 199 | int slpm = PIN_SLPM(cfg); | ||
| 200 | int output = PIN_DIR(cfg); | ||
| 201 | int val = PIN_VAL(cfg); | ||
| 202 | bool glitch = af == NMK_GPIO_ALT_C; | ||
| 203 | |||
| 204 | dev_dbg(nmk_chip->chip.dev, "pin %d [%#lx]: af %s, pull %s, slpm %s (%s%s)\n", | ||
| 205 | pin, cfg, afnames[af], pullnames[pull], slpmnames[slpm], | ||
| 206 | output ? "output " : "input", | ||
| 207 | output ? (val ? "high" : "low") : ""); | ||
| 208 | |||
| 209 | if (sleep) { | ||
| 210 | int slpm_pull = PIN_SLPM_PULL(cfg); | ||
| 211 | int slpm_output = PIN_SLPM_DIR(cfg); | ||
| 212 | int slpm_val = PIN_SLPM_VAL(cfg); | ||
| 213 | |||
| 214 | af = NMK_GPIO_ALT_GPIO; | ||
| 215 | |||
| 216 | /* | ||
| 217 | * The SLPM_* values are normal values + 1 to allow zero to | ||
| 218 | * mean "same as normal". | ||
| 219 | */ | ||
| 220 | if (slpm_pull) | ||
| 221 | pull = slpm_pull - 1; | ||
| 222 | if (slpm_output) | ||
| 223 | output = slpm_output - 1; | ||
| 224 | if (slpm_val) | ||
| 225 | val = slpm_val - 1; | ||
| 226 | |||
| 227 | dev_dbg(nmk_chip->chip.dev, "pin %d: sleep pull %s, dir %s, val %s\n", | ||
| 228 | pin, | ||
| 229 | slpm_pull ? pullnames[pull] : "same", | ||
| 230 | slpm_output ? (output ? "output" : "input") : "same", | ||
| 231 | slpm_val ? (val ? "high" : "low") : "same"); | ||
| 232 | } | ||
| 233 | |||
| 234 | if (output) | ||
| 235 | __nmk_gpio_make_output(nmk_chip, offset, val); | ||
| 236 | else { | ||
| 237 | __nmk_gpio_make_input(nmk_chip, offset); | ||
| 238 | __nmk_gpio_set_pull(nmk_chip, offset, pull); | ||
| 239 | } | ||
| 240 | |||
| 241 | /* | ||
| 242 | * If we've backed up the SLPM registers (glitch workaround), modify | ||
| 243 | * the backups since they will be restored. | ||
| 244 | */ | ||
| 245 | if (slpmregs) { | ||
| 246 | if (slpm == NMK_GPIO_SLPM_NOCHANGE) | ||
| 247 | slpmregs[nmk_chip->bank] |= BIT(offset); | ||
| 248 | else | ||
| 249 | slpmregs[nmk_chip->bank] &= ~BIT(offset); | ||
| 250 | } else | ||
| 251 | __nmk_gpio_set_slpm(nmk_chip, offset, slpm); | ||
| 252 | |||
| 253 | __nmk_gpio_set_mode_safe(nmk_chip, offset, af, glitch); | ||
| 254 | } | ||
| 255 | |||
| 256 | /* | ||
| 257 | * Safe sequence used to switch IOs between GPIO and Alternate-C mode: | ||
| 258 | * - Save SLPM registers | ||
| 259 | * - Set SLPM=0 for the IOs you want to switch and others to 1 | ||
| 260 | * - Configure the GPIO registers for the IOs that are being switched | ||
| 261 | * - Set IOFORCE=1 | ||
| 262 | * - Modify the AFLSA/B registers for the IOs that are being switched | ||
| 263 | * - Set IOFORCE=0 | ||
| 264 | * - Restore SLPM registers | ||
| 265 | * - Any spurious wake up event during switch sequence to be ignored and | ||
| 266 | * cleared | ||
| 267 | */ | ||
| 268 | static void nmk_gpio_glitch_slpm_init(unsigned int *slpm) | ||
| 269 | { | ||
| 270 | int i; | ||
| 271 | |||
| 272 | for (i = 0; i < NUM_BANKS; i++) { | ||
| 273 | struct nmk_gpio_chip *chip = nmk_gpio_chips[i]; | ||
| 274 | unsigned int temp = slpm[i]; | ||
| 275 | |||
| 276 | if (!chip) | ||
| 277 | break; | ||
| 278 | |||
| 279 | clk_enable(chip->clk); | ||
| 280 | |||
| 281 | slpm[i] = readl(chip->addr + NMK_GPIO_SLPC); | ||
| 282 | writel(temp, chip->addr + NMK_GPIO_SLPC); | ||
| 283 | } | ||
| 284 | } | ||
| 285 | |||
| 286 | static void nmk_gpio_glitch_slpm_restore(unsigned int *slpm) | ||
| 287 | { | ||
| 288 | int i; | ||
| 289 | |||
| 290 | for (i = 0; i < NUM_BANKS; i++) { | ||
| 291 | struct nmk_gpio_chip *chip = nmk_gpio_chips[i]; | ||
| 292 | |||
| 293 | if (!chip) | ||
| 294 | break; | ||
| 295 | |||
| 296 | writel(slpm[i], chip->addr + NMK_GPIO_SLPC); | ||
| 297 | |||
| 298 | clk_disable(chip->clk); | ||
| 299 | } | ||
| 300 | } | ||
| 301 | |||
| 302 | static int __nmk_config_pins(pin_cfg_t *cfgs, int num, bool sleep) | ||
| 303 | { | ||
| 304 | static unsigned int slpm[NUM_BANKS]; | ||
| 305 | unsigned long flags; | ||
| 306 | bool glitch = false; | ||
| 307 | int ret = 0; | ||
| 308 | int i; | ||
| 309 | |||
| 310 | for (i = 0; i < num; i++) { | ||
| 311 | if (PIN_ALT(cfgs[i]) == NMK_GPIO_ALT_C) { | ||
| 312 | glitch = true; | ||
| 313 | break; | ||
| 314 | } | ||
| 315 | } | ||
| 316 | |||
| 317 | spin_lock_irqsave(&nmk_gpio_slpm_lock, flags); | ||
| 318 | |||
| 319 | if (glitch) { | ||
| 320 | memset(slpm, 0xff, sizeof(slpm)); | ||
| 321 | |||
| 322 | for (i = 0; i < num; i++) { | ||
| 323 | int pin = PIN_NUM(cfgs[i]); | ||
| 324 | int offset = pin % NMK_GPIO_PER_CHIP; | ||
| 325 | |||
| 326 | if (PIN_ALT(cfgs[i]) == NMK_GPIO_ALT_C) | ||
| 327 | slpm[pin / NMK_GPIO_PER_CHIP] &= ~BIT(offset); | ||
| 328 | } | ||
| 329 | |||
| 330 | nmk_gpio_glitch_slpm_init(slpm); | ||
| 331 | } | ||
| 332 | |||
| 333 | for (i = 0; i < num; i++) { | ||
| 334 | struct nmk_gpio_chip *nmk_chip; | ||
| 335 | int pin = PIN_NUM(cfgs[i]); | ||
| 336 | |||
| 337 | nmk_chip = irq_get_chip_data(NOMADIK_GPIO_TO_IRQ(pin)); | ||
| 338 | if (!nmk_chip) { | ||
| 339 | ret = -EINVAL; | ||
| 340 | break; | ||
| 341 | } | ||
| 342 | |||
| 343 | clk_enable(nmk_chip->clk); | ||
| 344 | spin_lock(&nmk_chip->lock); | ||
| 345 | __nmk_config_pin(nmk_chip, pin - nmk_chip->chip.base, | ||
| 346 | cfgs[i], sleep, glitch ? slpm : NULL); | ||
| 347 | spin_unlock(&nmk_chip->lock); | ||
| 348 | clk_disable(nmk_chip->clk); | ||
| 349 | } | ||
| 350 | |||
| 351 | if (glitch) | ||
| 352 | nmk_gpio_glitch_slpm_restore(slpm); | ||
| 353 | |||
| 354 | spin_unlock_irqrestore(&nmk_gpio_slpm_lock, flags); | ||
| 355 | |||
| 356 | return ret; | ||
| 357 | } | ||
| 358 | |||
| 359 | /** | ||
| 360 | * nmk_config_pin - configure a pin's mux attributes | ||
| 361 | * @cfg: pin confguration | ||
| 362 | * | ||
| 363 | * Configures a pin's mode (alternate function or GPIO), its pull up status, | ||
| 364 | * and its sleep mode based on the specified configuration. The @cfg is | ||
| 365 | * usually one of the SoC specific macros defined in mach/<soc>-pins.h. These | ||
| 366 | * are constructed using, and can be further enhanced with, the macros in | ||
| 367 | * plat/pincfg.h. | ||
| 368 | * | ||
| 369 | * If a pin's mode is set to GPIO, it is configured as an input to avoid | ||
| 370 | * side-effects. The gpio can be manipulated later using standard GPIO API | ||
| 371 | * calls. | ||
| 372 | */ | ||
| 373 | int nmk_config_pin(pin_cfg_t cfg, bool sleep) | ||
| 374 | { | ||
| 375 | return __nmk_config_pins(&cfg, 1, sleep); | ||
| 376 | } | ||
| 377 | EXPORT_SYMBOL(nmk_config_pin); | ||
| 378 | |||
| 379 | /** | ||
| 380 | * nmk_config_pins - configure several pins at once | ||
| 381 | * @cfgs: array of pin configurations | ||
| 382 | * @num: number of elments in the array | ||
| 383 | * | ||
| 384 | * Configures several pins using nmk_config_pin(). Refer to that function for | ||
| 385 | * further information. | ||
| 386 | */ | ||
| 387 | int nmk_config_pins(pin_cfg_t *cfgs, int num) | ||
| 388 | { | ||
| 389 | return __nmk_config_pins(cfgs, num, false); | ||
| 390 | } | ||
| 391 | EXPORT_SYMBOL(nmk_config_pins); | ||
| 392 | |||
| 393 | int nmk_config_pins_sleep(pin_cfg_t *cfgs, int num) | ||
| 394 | { | ||
| 395 | return __nmk_config_pins(cfgs, num, true); | ||
| 396 | } | ||
| 397 | EXPORT_SYMBOL(nmk_config_pins_sleep); | ||
| 398 | |||
| 399 | /** | ||
| 400 | * nmk_gpio_set_slpm() - configure the sleep mode of a pin | ||
| 401 | * @gpio: pin number | ||
| 402 | * @mode: NMK_GPIO_SLPM_INPUT or NMK_GPIO_SLPM_NOCHANGE, | ||
| 403 | * | ||
| 404 | * This register is actually in the pinmux layer, not the GPIO block itself. | ||
| 405 | * The GPIO1B_SLPM register defines the GPIO mode when SLEEP/DEEP-SLEEP | ||
| 406 | * mode is entered (i.e. when signal IOFORCE is HIGH by the platform code). | ||
| 407 | * Each GPIO can be configured to be forced into GPIO mode when IOFORCE is | ||
| 408 | * HIGH, overriding the normal setting defined by GPIO_AFSELx registers. | ||
| 409 | * When IOFORCE returns LOW (by software, after SLEEP/DEEP-SLEEP exit), | ||
| 410 | * the GPIOs return to the normal setting defined by GPIO_AFSELx registers. | ||
| 411 | * | ||
| 412 | * If @mode is NMK_GPIO_SLPM_INPUT, the corresponding GPIO is switched to GPIO | ||
| 413 | * mode when signal IOFORCE is HIGH (i.e. when SLEEP/DEEP-SLEEP mode is | ||
| 414 | * entered) regardless of the altfunction selected. Also wake-up detection is | ||
| 415 | * ENABLED. | ||
| 416 | * | ||
| 417 | * If @mode is NMK_GPIO_SLPM_NOCHANGE, the corresponding GPIO remains | ||
| 418 | * controlled by NMK_GPIO_DATC, NMK_GPIO_DATS, NMK_GPIO_DIR, NMK_GPIO_PDIS | ||
| 419 | * (for altfunction GPIO) or respective on-chip peripherals (for other | ||
| 420 | * altfuncs) when IOFORCE is HIGH. Also wake-up detection DISABLED. | ||
| 421 | * | ||
| 422 | * Note that enable_irq_wake() will automatically enable wakeup detection. | ||
| 423 | */ | ||
| 424 | int nmk_gpio_set_slpm(int gpio, enum nmk_gpio_slpm mode) | ||
| 425 | { | ||
| 426 | struct nmk_gpio_chip *nmk_chip; | ||
| 427 | unsigned long flags; | ||
| 428 | |||
| 429 | nmk_chip = irq_get_chip_data(NOMADIK_GPIO_TO_IRQ(gpio)); | ||
| 430 | if (!nmk_chip) | ||
| 431 | return -EINVAL; | ||
| 432 | |||
| 433 | clk_enable(nmk_chip->clk); | ||
| 434 | spin_lock_irqsave(&nmk_gpio_slpm_lock, flags); | ||
| 435 | spin_lock(&nmk_chip->lock); | ||
| 436 | |||
| 437 | __nmk_gpio_set_slpm(nmk_chip, gpio - nmk_chip->chip.base, mode); | ||
| 438 | |||
| 439 | spin_unlock(&nmk_chip->lock); | ||
| 440 | spin_unlock_irqrestore(&nmk_gpio_slpm_lock, flags); | ||
| 441 | clk_disable(nmk_chip->clk); | ||
| 442 | |||
| 443 | return 0; | ||
| 444 | } | ||
| 445 | |||
| 446 | /** | ||
| 447 | * nmk_gpio_set_pull() - enable/disable pull up/down on a gpio | ||
| 448 | * @gpio: pin number | ||
| 449 | * @pull: one of NMK_GPIO_PULL_DOWN, NMK_GPIO_PULL_UP, and NMK_GPIO_PULL_NONE | ||
| 450 | * | ||
| 451 | * Enables/disables pull up/down on a specified pin. This only takes effect if | ||
| 452 | * the pin is configured as an input (either explicitly or by the alternate | ||
| 453 | * function). | ||
| 454 | * | ||
| 455 | * NOTE: If enabling the pull up/down, the caller must ensure that the GPIO is | ||
| 456 | * configured as an input. Otherwise, due to the way the controller registers | ||
| 457 | * work, this function will change the value output on the pin. | ||
| 458 | */ | ||
| 459 | int nmk_gpio_set_pull(int gpio, enum nmk_gpio_pull pull) | ||
| 460 | { | ||
| 461 | struct nmk_gpio_chip *nmk_chip; | ||
| 462 | unsigned long flags; | ||
| 463 | |||
| 464 | nmk_chip = irq_get_chip_data(NOMADIK_GPIO_TO_IRQ(gpio)); | ||
| 465 | if (!nmk_chip) | ||
| 466 | return -EINVAL; | ||
| 467 | |||
| 468 | clk_enable(nmk_chip->clk); | ||
| 469 | spin_lock_irqsave(&nmk_chip->lock, flags); | ||
| 470 | __nmk_gpio_set_pull(nmk_chip, gpio - nmk_chip->chip.base, pull); | ||
| 471 | spin_unlock_irqrestore(&nmk_chip->lock, flags); | ||
| 472 | clk_disable(nmk_chip->clk); | ||
| 473 | |||
| 474 | return 0; | ||
| 475 | } | ||
| 476 | |||
| 477 | /* Mode functions */ | ||
| 478 | /** | ||
| 479 | * nmk_gpio_set_mode() - set the mux mode of a gpio pin | ||
| 480 | * @gpio: pin number | ||
| 481 | * @gpio_mode: one of NMK_GPIO_ALT_GPIO, NMK_GPIO_ALT_A, | ||
| 482 | * NMK_GPIO_ALT_B, and NMK_GPIO_ALT_C | ||
| 483 | * | ||
| 484 | * Sets the mode of the specified pin to one of the alternate functions or | ||
| 485 | * plain GPIO. | ||
| 486 | */ | ||
| 487 | int nmk_gpio_set_mode(int gpio, int gpio_mode) | ||
| 488 | { | ||
| 489 | struct nmk_gpio_chip *nmk_chip; | ||
| 490 | unsigned long flags; | ||
| 491 | |||
| 492 | nmk_chip = irq_get_chip_data(NOMADIK_GPIO_TO_IRQ(gpio)); | ||
| 493 | if (!nmk_chip) | ||
| 494 | return -EINVAL; | ||
| 495 | |||
| 496 | clk_enable(nmk_chip->clk); | ||
| 497 | spin_lock_irqsave(&nmk_chip->lock, flags); | ||
| 498 | __nmk_gpio_set_mode(nmk_chip, gpio - nmk_chip->chip.base, gpio_mode); | ||
| 499 | spin_unlock_irqrestore(&nmk_chip->lock, flags); | ||
| 500 | clk_disable(nmk_chip->clk); | ||
| 501 | |||
| 502 | return 0; | ||
| 503 | } | ||
| 504 | EXPORT_SYMBOL(nmk_gpio_set_mode); | ||
| 505 | |||
| 506 | int nmk_gpio_get_mode(int gpio) | ||
| 507 | { | ||
| 508 | struct nmk_gpio_chip *nmk_chip; | ||
| 509 | u32 afunc, bfunc, bit; | ||
| 510 | |||
| 511 | nmk_chip = irq_get_chip_data(NOMADIK_GPIO_TO_IRQ(gpio)); | ||
| 512 | if (!nmk_chip) | ||
| 513 | return -EINVAL; | ||
| 514 | |||
| 515 | bit = 1 << (gpio - nmk_chip->chip.base); | ||
| 516 | |||
| 517 | clk_enable(nmk_chip->clk); | ||
| 518 | |||
| 519 | afunc = readl(nmk_chip->addr + NMK_GPIO_AFSLA) & bit; | ||
| 520 | bfunc = readl(nmk_chip->addr + NMK_GPIO_AFSLB) & bit; | ||
| 521 | |||
| 522 | clk_disable(nmk_chip->clk); | ||
| 523 | |||
| 524 | return (afunc ? NMK_GPIO_ALT_A : 0) | (bfunc ? NMK_GPIO_ALT_B : 0); | ||
| 525 | } | ||
| 526 | EXPORT_SYMBOL(nmk_gpio_get_mode); | ||
| 527 | |||
| 528 | |||
| 529 | /* IRQ functions */ | ||
| 530 | static inline int nmk_gpio_get_bitmask(int gpio) | ||
| 531 | { | ||
| 532 | return 1 << (gpio % 32); | ||
| 533 | } | ||
| 534 | |||
| 535 | static void nmk_gpio_irq_ack(struct irq_data *d) | ||
| 536 | { | ||
| 537 | int gpio; | ||
| 538 | struct nmk_gpio_chip *nmk_chip; | ||
| 539 | |||
| 540 | gpio = NOMADIK_IRQ_TO_GPIO(d->irq); | ||
| 541 | nmk_chip = irq_data_get_irq_chip_data(d); | ||
| 542 | if (!nmk_chip) | ||
| 543 | return; | ||
| 544 | |||
| 545 | clk_enable(nmk_chip->clk); | ||
| 546 | writel(nmk_gpio_get_bitmask(gpio), nmk_chip->addr + NMK_GPIO_IC); | ||
| 547 | clk_disable(nmk_chip->clk); | ||
| 548 | } | ||
| 549 | |||
| 550 | enum nmk_gpio_irq_type { | ||
| 551 | NORMAL, | ||
| 552 | WAKE, | ||
| 553 | }; | ||
| 554 | |||
| 555 | static void __nmk_gpio_irq_modify(struct nmk_gpio_chip *nmk_chip, | ||
| 556 | int gpio, enum nmk_gpio_irq_type which, | ||
| 557 | bool enable) | ||
| 558 | { | ||
| 559 | u32 rimsc = which == WAKE ? NMK_GPIO_RWIMSC : NMK_GPIO_RIMSC; | ||
| 560 | u32 fimsc = which == WAKE ? NMK_GPIO_FWIMSC : NMK_GPIO_FIMSC; | ||
| 561 | u32 bitmask = nmk_gpio_get_bitmask(gpio); | ||
| 562 | u32 reg; | ||
| 563 | |||
| 564 | /* we must individually set/clear the two edges */ | ||
| 565 | if (nmk_chip->edge_rising & bitmask) { | ||
| 566 | reg = readl(nmk_chip->addr + rimsc); | ||
| 567 | if (enable) | ||
| 568 | reg |= bitmask; | ||
| 569 | else | ||
| 570 | reg &= ~bitmask; | ||
| 571 | writel(reg, nmk_chip->addr + rimsc); | ||
| 572 | } | ||
| 573 | if (nmk_chip->edge_falling & bitmask) { | ||
| 574 | reg = readl(nmk_chip->addr + fimsc); | ||
| 575 | if (enable) | ||
| 576 | reg |= bitmask; | ||
| 577 | else | ||
| 578 | reg &= ~bitmask; | ||
| 579 | writel(reg, nmk_chip->addr + fimsc); | ||
| 580 | } | ||
| 581 | } | ||
| 582 | |||
| 583 | static void __nmk_gpio_set_wake(struct nmk_gpio_chip *nmk_chip, | ||
| 584 | int gpio, bool on) | ||
| 585 | { | ||
| 586 | if (nmk_chip->sleepmode) { | ||
| 587 | __nmk_gpio_set_slpm(nmk_chip, gpio - nmk_chip->chip.base, | ||
| 588 | on ? NMK_GPIO_SLPM_WAKEUP_ENABLE | ||
| 589 | : NMK_GPIO_SLPM_WAKEUP_DISABLE); | ||
| 590 | } | ||
| 591 | |||
| 592 | __nmk_gpio_irq_modify(nmk_chip, gpio, WAKE, on); | ||
| 593 | } | ||
| 594 | |||
| 595 | static int nmk_gpio_irq_maskunmask(struct irq_data *d, bool enable) | ||
| 596 | { | ||
| 597 | int gpio; | ||
| 598 | struct nmk_gpio_chip *nmk_chip; | ||
| 599 | unsigned long flags; | ||
| 600 | u32 bitmask; | ||
| 601 | |||
| 602 | gpio = NOMADIK_IRQ_TO_GPIO(d->irq); | ||
| 603 | nmk_chip = irq_data_get_irq_chip_data(d); | ||
| 604 | bitmask = nmk_gpio_get_bitmask(gpio); | ||
| 605 | if (!nmk_chip) | ||
| 606 | return -EINVAL; | ||
| 607 | |||
| 608 | clk_enable(nmk_chip->clk); | ||
| 609 | spin_lock_irqsave(&nmk_gpio_slpm_lock, flags); | ||
| 610 | spin_lock(&nmk_chip->lock); | ||
| 611 | |||
| 612 | __nmk_gpio_irq_modify(nmk_chip, gpio, NORMAL, enable); | ||
| 613 | |||
| 614 | if (!(nmk_chip->real_wake & bitmask)) | ||
| 615 | __nmk_gpio_set_wake(nmk_chip, gpio, enable); | ||
| 616 | |||
| 617 | spin_unlock(&nmk_chip->lock); | ||
| 618 | spin_unlock_irqrestore(&nmk_gpio_slpm_lock, flags); | ||
| 619 | clk_disable(nmk_chip->clk); | ||
| 620 | |||
| 621 | return 0; | ||
| 622 | } | ||
| 623 | |||
| 624 | static void nmk_gpio_irq_mask(struct irq_data *d) | ||
| 625 | { | ||
| 626 | nmk_gpio_irq_maskunmask(d, false); | ||
| 627 | } | ||
| 628 | |||
| 629 | static void nmk_gpio_irq_unmask(struct irq_data *d) | ||
| 630 | { | ||
| 631 | nmk_gpio_irq_maskunmask(d, true); | ||
| 632 | } | ||
| 633 | |||
| 634 | static int nmk_gpio_irq_set_wake(struct irq_data *d, unsigned int on) | ||
| 635 | { | ||
| 636 | struct nmk_gpio_chip *nmk_chip; | ||
| 637 | unsigned long flags; | ||
| 638 | u32 bitmask; | ||
| 639 | int gpio; | ||
| 640 | |||
| 641 | gpio = NOMADIK_IRQ_TO_GPIO(d->irq); | ||
| 642 | nmk_chip = irq_data_get_irq_chip_data(d); | ||
| 643 | if (!nmk_chip) | ||
| 644 | return -EINVAL; | ||
| 645 | bitmask = nmk_gpio_get_bitmask(gpio); | ||
| 646 | |||
| 647 | clk_enable(nmk_chip->clk); | ||
| 648 | spin_lock_irqsave(&nmk_gpio_slpm_lock, flags); | ||
| 649 | spin_lock(&nmk_chip->lock); | ||
| 650 | |||
| 651 | if (irqd_irq_disabled(d)) | ||
| 652 | __nmk_gpio_set_wake(nmk_chip, gpio, on); | ||
| 653 | |||
| 654 | if (on) | ||
| 655 | nmk_chip->real_wake |= bitmask; | ||
| 656 | else | ||
| 657 | nmk_chip->real_wake &= ~bitmask; | ||
| 658 | |||
| 659 | spin_unlock(&nmk_chip->lock); | ||
| 660 | spin_unlock_irqrestore(&nmk_gpio_slpm_lock, flags); | ||
| 661 | clk_disable(nmk_chip->clk); | ||
| 662 | |||
| 663 | return 0; | ||
| 664 | } | ||
| 665 | |||
| 666 | static int nmk_gpio_irq_set_type(struct irq_data *d, unsigned int type) | ||
| 667 | { | ||
| 668 | bool enabled = !irqd_irq_disabled(d); | ||
| 669 | bool wake = irqd_is_wakeup_set(d); | ||
| 670 | int gpio; | ||
| 671 | struct nmk_gpio_chip *nmk_chip; | ||
| 672 | unsigned long flags; | ||
| 673 | u32 bitmask; | ||
| 674 | |||
| 675 | gpio = NOMADIK_IRQ_TO_GPIO(d->irq); | ||
| 676 | nmk_chip = irq_data_get_irq_chip_data(d); | ||
| 677 | bitmask = nmk_gpio_get_bitmask(gpio); | ||
| 678 | if (!nmk_chip) | ||
| 679 | return -EINVAL; | ||
| 680 | |||
| 681 | if (type & IRQ_TYPE_LEVEL_HIGH) | ||
| 682 | return -EINVAL; | ||
| 683 | if (type & IRQ_TYPE_LEVEL_LOW) | ||
| 684 | return -EINVAL; | ||
| 685 | |||
| 686 | clk_enable(nmk_chip->clk); | ||
| 687 | spin_lock_irqsave(&nmk_chip->lock, flags); | ||
| 688 | |||
| 689 | if (enabled) | ||
| 690 | __nmk_gpio_irq_modify(nmk_chip, gpio, NORMAL, false); | ||
| 691 | |||
| 692 | if (enabled || wake) | ||
| 693 | __nmk_gpio_irq_modify(nmk_chip, gpio, WAKE, false); | ||
| 694 | |||
| 695 | nmk_chip->edge_rising &= ~bitmask; | ||
| 696 | if (type & IRQ_TYPE_EDGE_RISING) | ||
| 697 | nmk_chip->edge_rising |= bitmask; | ||
| 698 | |||
| 699 | nmk_chip->edge_falling &= ~bitmask; | ||
| 700 | if (type & IRQ_TYPE_EDGE_FALLING) | ||
| 701 | nmk_chip->edge_falling |= bitmask; | ||
| 702 | |||
| 703 | if (enabled) | ||
| 704 | __nmk_gpio_irq_modify(nmk_chip, gpio, NORMAL, true); | ||
| 705 | |||
| 706 | if (enabled || wake) | ||
| 707 | __nmk_gpio_irq_modify(nmk_chip, gpio, WAKE, true); | ||
| 708 | |||
| 709 | spin_unlock_irqrestore(&nmk_chip->lock, flags); | ||
| 710 | clk_disable(nmk_chip->clk); | ||
| 711 | |||
| 712 | return 0; | ||
| 713 | } | ||
| 714 | |||
| 715 | static unsigned int nmk_gpio_irq_startup(struct irq_data *d) | ||
| 716 | { | ||
| 717 | struct nmk_gpio_chip *nmk_chip = irq_data_get_irq_chip_data(d); | ||
| 718 | |||
| 719 | clk_enable(nmk_chip->clk); | ||
| 720 | nmk_gpio_irq_unmask(d); | ||
| 721 | return 0; | ||
| 722 | } | ||
| 723 | |||
| 724 | static void nmk_gpio_irq_shutdown(struct irq_data *d) | ||
| 725 | { | ||
| 726 | struct nmk_gpio_chip *nmk_chip = irq_data_get_irq_chip_data(d); | ||
| 727 | |||
| 728 | nmk_gpio_irq_mask(d); | ||
| 729 | clk_disable(nmk_chip->clk); | ||
| 730 | } | ||
| 731 | |||
| 732 | static struct irq_chip nmk_gpio_irq_chip = { | ||
| 733 | .name = "Nomadik-GPIO", | ||
| 734 | .irq_ack = nmk_gpio_irq_ack, | ||
| 735 | .irq_mask = nmk_gpio_irq_mask, | ||
| 736 | .irq_unmask = nmk_gpio_irq_unmask, | ||
| 737 | .irq_set_type = nmk_gpio_irq_set_type, | ||
| 738 | .irq_set_wake = nmk_gpio_irq_set_wake, | ||
| 739 | .irq_startup = nmk_gpio_irq_startup, | ||
| 740 | .irq_shutdown = nmk_gpio_irq_shutdown, | ||
| 741 | }; | ||
| 742 | |||
| 743 | static void __nmk_gpio_irq_handler(unsigned int irq, struct irq_desc *desc, | ||
| 744 | u32 status) | ||
| 745 | { | ||
| 746 | struct nmk_gpio_chip *nmk_chip; | ||
| 747 | struct irq_chip *host_chip = irq_get_chip(irq); | ||
| 748 | unsigned int first_irq; | ||
| 749 | |||
| 750 | chained_irq_enter(host_chip, desc); | ||
| 751 | |||
| 752 | nmk_chip = irq_get_handler_data(irq); | ||
| 753 | first_irq = NOMADIK_GPIO_TO_IRQ(nmk_chip->chip.base); | ||
| 754 | while (status) { | ||
| 755 | int bit = __ffs(status); | ||
| 756 | |||
| 757 | generic_handle_irq(first_irq + bit); | ||
| 758 | status &= ~BIT(bit); | ||
| 759 | } | ||
| 760 | |||
| 761 | chained_irq_exit(host_chip, desc); | ||
| 762 | } | ||
| 763 | |||
| 764 | static void nmk_gpio_irq_handler(unsigned int irq, struct irq_desc *desc) | ||
| 765 | { | ||
| 766 | struct nmk_gpio_chip *nmk_chip = irq_get_handler_data(irq); | ||
| 767 | u32 status; | ||
| 768 | |||
| 769 | clk_enable(nmk_chip->clk); | ||
| 770 | status = readl(nmk_chip->addr + NMK_GPIO_IS); | ||
| 771 | clk_disable(nmk_chip->clk); | ||
| 772 | |||
| 773 | __nmk_gpio_irq_handler(irq, desc, status); | ||
| 774 | } | ||
| 775 | |||
| 776 | static void nmk_gpio_secondary_irq_handler(unsigned int irq, | ||
| 777 | struct irq_desc *desc) | ||
| 778 | { | ||
| 779 | struct nmk_gpio_chip *nmk_chip = irq_get_handler_data(irq); | ||
| 780 | u32 status = nmk_chip->get_secondary_status(nmk_chip->bank); | ||
| 781 | |||
| 782 | __nmk_gpio_irq_handler(irq, desc, status); | ||
| 783 | } | ||
| 784 | |||
| 785 | static int nmk_gpio_init_irq(struct nmk_gpio_chip *nmk_chip) | ||
| 786 | { | ||
| 787 | unsigned int first_irq; | ||
| 788 | int i; | ||
| 789 | |||
| 790 | first_irq = NOMADIK_GPIO_TO_IRQ(nmk_chip->chip.base); | ||
| 791 | for (i = first_irq; i < first_irq + nmk_chip->chip.ngpio; i++) { | ||
| 792 | irq_set_chip_and_handler(i, &nmk_gpio_irq_chip, | ||
| 793 | handle_edge_irq); | ||
| 794 | set_irq_flags(i, IRQF_VALID); | ||
| 795 | irq_set_chip_data(i, nmk_chip); | ||
| 796 | irq_set_irq_type(i, IRQ_TYPE_EDGE_FALLING); | ||
| 797 | } | ||
| 798 | |||
| 799 | irq_set_chained_handler(nmk_chip->parent_irq, nmk_gpio_irq_handler); | ||
| 800 | irq_set_handler_data(nmk_chip->parent_irq, nmk_chip); | ||
| 801 | |||
| 802 | if (nmk_chip->secondary_parent_irq >= 0) { | ||
| 803 | irq_set_chained_handler(nmk_chip->secondary_parent_irq, | ||
| 804 | nmk_gpio_secondary_irq_handler); | ||
| 805 | irq_set_handler_data(nmk_chip->secondary_parent_irq, nmk_chip); | ||
| 806 | } | ||
| 807 | |||
| 808 | return 0; | ||
| 809 | } | ||
| 810 | |||
| 811 | /* I/O Functions */ | ||
| 812 | static int nmk_gpio_make_input(struct gpio_chip *chip, unsigned offset) | ||
| 813 | { | ||
| 814 | struct nmk_gpio_chip *nmk_chip = | ||
| 815 | container_of(chip, struct nmk_gpio_chip, chip); | ||
| 816 | |||
| 817 | clk_enable(nmk_chip->clk); | ||
| 818 | |||
| 819 | writel(1 << offset, nmk_chip->addr + NMK_GPIO_DIRC); | ||
| 820 | |||
| 821 | clk_disable(nmk_chip->clk); | ||
| 822 | |||
| 823 | return 0; | ||
| 824 | } | ||
| 825 | |||
| 826 | static int nmk_gpio_get_input(struct gpio_chip *chip, unsigned offset) | ||
| 827 | { | ||
| 828 | struct nmk_gpio_chip *nmk_chip = | ||
| 829 | container_of(chip, struct nmk_gpio_chip, chip); | ||
| 830 | u32 bit = 1 << offset; | ||
| 831 | int value; | ||
| 832 | |||
| 833 | clk_enable(nmk_chip->clk); | ||
| 834 | |||
| 835 | value = (readl(nmk_chip->addr + NMK_GPIO_DAT) & bit) != 0; | ||
| 836 | |||
| 837 | clk_disable(nmk_chip->clk); | ||
| 838 | |||
| 839 | return value; | ||
| 840 | } | ||
| 841 | |||
| 842 | static void nmk_gpio_set_output(struct gpio_chip *chip, unsigned offset, | ||
| 843 | int val) | ||
| 844 | { | ||
| 845 | struct nmk_gpio_chip *nmk_chip = | ||
| 846 | container_of(chip, struct nmk_gpio_chip, chip); | ||
| 847 | |||
| 848 | clk_enable(nmk_chip->clk); | ||
| 849 | |||
| 850 | __nmk_gpio_set_output(nmk_chip, offset, val); | ||
| 851 | |||
| 852 | clk_disable(nmk_chip->clk); | ||
| 853 | } | ||
| 854 | |||
| 855 | static int nmk_gpio_make_output(struct gpio_chip *chip, unsigned offset, | ||
| 856 | int val) | ||
| 857 | { | ||
| 858 | struct nmk_gpio_chip *nmk_chip = | ||
| 859 | container_of(chip, struct nmk_gpio_chip, chip); | ||
| 860 | |||
| 861 | clk_enable(nmk_chip->clk); | ||
| 862 | |||
| 863 | __nmk_gpio_make_output(nmk_chip, offset, val); | ||
| 864 | |||
| 865 | clk_disable(nmk_chip->clk); | ||
| 866 | |||
| 867 | return 0; | ||
| 868 | } | ||
| 869 | |||
| 870 | static int nmk_gpio_to_irq(struct gpio_chip *chip, unsigned offset) | ||
| 871 | { | ||
| 872 | struct nmk_gpio_chip *nmk_chip = | ||
| 873 | container_of(chip, struct nmk_gpio_chip, chip); | ||
| 874 | |||
| 875 | return NOMADIK_GPIO_TO_IRQ(nmk_chip->chip.base) + offset; | ||
| 876 | } | ||
| 877 | |||
| 878 | #ifdef CONFIG_DEBUG_FS | ||
| 879 | |||
| 880 | #include <linux/seq_file.h> | ||
| 881 | |||
| 882 | static void nmk_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip) | ||
| 883 | { | ||
| 884 | int mode; | ||
| 885 | unsigned i; | ||
| 886 | unsigned gpio = chip->base; | ||
| 887 | int is_out; | ||
| 888 | struct nmk_gpio_chip *nmk_chip = | ||
| 889 | container_of(chip, struct nmk_gpio_chip, chip); | ||
| 890 | const char *modes[] = { | ||
| 891 | [NMK_GPIO_ALT_GPIO] = "gpio", | ||
| 892 | [NMK_GPIO_ALT_A] = "altA", | ||
| 893 | [NMK_GPIO_ALT_B] = "altB", | ||
| 894 | [NMK_GPIO_ALT_C] = "altC", | ||
| 895 | }; | ||
| 896 | |||
| 897 | clk_enable(nmk_chip->clk); | ||
| 898 | |||
| 899 | for (i = 0; i < chip->ngpio; i++, gpio++) { | ||
| 900 | const char *label = gpiochip_is_requested(chip, i); | ||
| 901 | bool pull; | ||
| 902 | u32 bit = 1 << i; | ||
| 903 | |||
| 904 | is_out = readl(nmk_chip->addr + NMK_GPIO_DIR) & bit; | ||
| 905 | pull = !(readl(nmk_chip->addr + NMK_GPIO_PDIS) & bit); | ||
| 906 | mode = nmk_gpio_get_mode(gpio); | ||
| 907 | seq_printf(s, " gpio-%-3d (%-20.20s) %s %s %s %s", | ||
| 908 | gpio, label ?: "(none)", | ||
| 909 | is_out ? "out" : "in ", | ||
| 910 | chip->get | ||
| 911 | ? (chip->get(chip, i) ? "hi" : "lo") | ||
| 912 | : "? ", | ||
| 913 | (mode < 0) ? "unknown" : modes[mode], | ||
| 914 | pull ? "pull" : "none"); | ||
| 915 | |||
| 916 | if (label && !is_out) { | ||
| 917 | int irq = gpio_to_irq(gpio); | ||
| 918 | struct irq_desc *desc = irq_to_desc(irq); | ||
| 919 | |||
| 920 | /* This races with request_irq(), set_irq_type(), | ||
| 921 | * and set_irq_wake() ... but those are "rare". | ||
| 922 | */ | ||
| 923 | if (irq >= 0 && desc->action) { | ||
| 924 | char *trigger; | ||
| 925 | u32 bitmask = nmk_gpio_get_bitmask(gpio); | ||
| 926 | |||
| 927 | if (nmk_chip->edge_rising & bitmask) | ||
| 928 | trigger = "edge-rising"; | ||
| 929 | else if (nmk_chip->edge_falling & bitmask) | ||
| 930 | trigger = "edge-falling"; | ||
| 931 | else | ||
| 932 | trigger = "edge-undefined"; | ||
| 933 | |||
| 934 | seq_printf(s, " irq-%d %s%s", | ||
| 935 | irq, trigger, | ||
| 936 | irqd_is_wakeup_set(&desc->irq_data) | ||
| 937 | ? " wakeup" : ""); | ||
| 938 | } | ||
| 939 | } | ||
| 940 | |||
| 941 | seq_printf(s, "\n"); | ||
| 942 | } | ||
| 943 | |||
| 944 | clk_disable(nmk_chip->clk); | ||
| 945 | } | ||
| 946 | |||
| 947 | #else | ||
| 948 | #define nmk_gpio_dbg_show NULL | ||
| 949 | #endif | ||
| 950 | |||
| 951 | /* This structure is replicated for each GPIO block allocated at probe time */ | ||
| 952 | static struct gpio_chip nmk_gpio_template = { | ||
| 953 | .direction_input = nmk_gpio_make_input, | ||
| 954 | .get = nmk_gpio_get_input, | ||
| 955 | .direction_output = nmk_gpio_make_output, | ||
| 956 | .set = nmk_gpio_set_output, | ||
| 957 | .to_irq = nmk_gpio_to_irq, | ||
| 958 | .dbg_show = nmk_gpio_dbg_show, | ||
| 959 | .can_sleep = 0, | ||
| 960 | }; | ||
| 961 | |||
| 962 | void nmk_gpio_clocks_enable(void) | ||
| 963 | { | ||
| 964 | int i; | ||
| 965 | |||
| 966 | for (i = 0; i < NUM_BANKS; i++) { | ||
| 967 | struct nmk_gpio_chip *chip = nmk_gpio_chips[i]; | ||
| 968 | |||
| 969 | if (!chip) | ||
| 970 | continue; | ||
| 971 | |||
| 972 | clk_enable(chip->clk); | ||
| 973 | } | ||
| 974 | } | ||
| 975 | |||
| 976 | void nmk_gpio_clocks_disable(void) | ||
| 977 | { | ||
| 978 | int i; | ||
| 979 | |||
| 980 | for (i = 0; i < NUM_BANKS; i++) { | ||
| 981 | struct nmk_gpio_chip *chip = nmk_gpio_chips[i]; | ||
| 982 | |||
| 983 | if (!chip) | ||
| 984 | continue; | ||
| 985 | |||
| 986 | clk_disable(chip->clk); | ||
| 987 | } | ||
| 988 | } | ||
| 989 | |||
| 990 | /* | ||
| 991 | * Called from the suspend/resume path to only keep the real wakeup interrupts | ||
| 992 | * (those that have had set_irq_wake() called on them) as wakeup interrupts, | ||
| 993 | * and not the rest of the interrupts which we needed to have as wakeups for | ||
| 994 | * cpuidle. | ||
| 995 | * | ||
| 996 | * PM ops are not used since this needs to be done at the end, after all the | ||
| 997 | * other drivers are done with their suspend callbacks. | ||
| 998 | */ | ||
| 999 | void nmk_gpio_wakeups_suspend(void) | ||
| 1000 | { | ||
| 1001 | int i; | ||
| 1002 | |||
| 1003 | for (i = 0; i < NUM_BANKS; i++) { | ||
| 1004 | struct nmk_gpio_chip *chip = nmk_gpio_chips[i]; | ||
| 1005 | |||
| 1006 | if (!chip) | ||
| 1007 | break; | ||
| 1008 | |||
| 1009 | clk_enable(chip->clk); | ||
| 1010 | |||
| 1011 | chip->rwimsc = readl(chip->addr + NMK_GPIO_RWIMSC); | ||
| 1012 | chip->fwimsc = readl(chip->addr + NMK_GPIO_FWIMSC); | ||
| 1013 | |||
| 1014 | writel(chip->rwimsc & chip->real_wake, | ||
| 1015 | chip->addr + NMK_GPIO_RWIMSC); | ||
| 1016 | writel(chip->fwimsc & chip->real_wake, | ||
| 1017 | chip->addr + NMK_GPIO_FWIMSC); | ||
| 1018 | |||
| 1019 | if (chip->sleepmode) { | ||
| 1020 | chip->slpm = readl(chip->addr + NMK_GPIO_SLPC); | ||
| 1021 | |||
| 1022 | /* 0 -> wakeup enable */ | ||
| 1023 | writel(~chip->real_wake, chip->addr + NMK_GPIO_SLPC); | ||
| 1024 | } | ||
| 1025 | |||
| 1026 | clk_disable(chip->clk); | ||
| 1027 | } | ||
| 1028 | } | ||
| 1029 | |||
| 1030 | void nmk_gpio_wakeups_resume(void) | ||
| 1031 | { | ||
| 1032 | int i; | ||
| 1033 | |||
| 1034 | for (i = 0; i < NUM_BANKS; i++) { | ||
| 1035 | struct nmk_gpio_chip *chip = nmk_gpio_chips[i]; | ||
| 1036 | |||
| 1037 | if (!chip) | ||
| 1038 | break; | ||
| 1039 | |||
| 1040 | clk_enable(chip->clk); | ||
| 1041 | |||
| 1042 | writel(chip->rwimsc, chip->addr + NMK_GPIO_RWIMSC); | ||
| 1043 | writel(chip->fwimsc, chip->addr + NMK_GPIO_FWIMSC); | ||
| 1044 | |||
| 1045 | if (chip->sleepmode) | ||
| 1046 | writel(chip->slpm, chip->addr + NMK_GPIO_SLPC); | ||
| 1047 | |||
| 1048 | clk_disable(chip->clk); | ||
| 1049 | } | ||
| 1050 | } | ||
| 1051 | |||
| 1052 | /* | ||
| 1053 | * Read the pull up/pull down status. | ||
| 1054 | * A bit set in 'pull_up' means that pull up | ||
| 1055 | * is selected if pull is enabled in PDIS register. | ||
| 1056 | * Note: only pull up/down set via this driver can | ||
| 1057 | * be detected due to HW limitations. | ||
| 1058 | */ | ||
| 1059 | void nmk_gpio_read_pull(int gpio_bank, u32 *pull_up) | ||
| 1060 | { | ||
| 1061 | if (gpio_bank < NUM_BANKS) { | ||
| 1062 | struct nmk_gpio_chip *chip = nmk_gpio_chips[gpio_bank]; | ||
| 1063 | |||
| 1064 | if (!chip) | ||
| 1065 | return; | ||
| 1066 | |||
| 1067 | *pull_up = chip->pull_up; | ||
| 1068 | } | ||
| 1069 | } | ||
| 1070 | |||
| 1071 | static int __devinit nmk_gpio_probe(struct platform_device *dev) | ||
| 1072 | { | ||
| 1073 | struct nmk_gpio_platform_data *pdata = dev->dev.platform_data; | ||
| 1074 | struct nmk_gpio_chip *nmk_chip; | ||
| 1075 | struct gpio_chip *chip; | ||
| 1076 | struct resource *res; | ||
| 1077 | struct clk *clk; | ||
| 1078 | int secondary_irq; | ||
| 1079 | int irq; | ||
| 1080 | int ret; | ||
| 1081 | |||
| 1082 | if (!pdata) | ||
| 1083 | return -ENODEV; | ||
| 1084 | |||
| 1085 | res = platform_get_resource(dev, IORESOURCE_MEM, 0); | ||
| 1086 | if (!res) { | ||
| 1087 | ret = -ENOENT; | ||
| 1088 | goto out; | ||
| 1089 | } | ||
| 1090 | |||
| 1091 | irq = platform_get_irq(dev, 0); | ||
| 1092 | if (irq < 0) { | ||
| 1093 | ret = irq; | ||
| 1094 | goto out; | ||
| 1095 | } | ||
| 1096 | |||
| 1097 | secondary_irq = platform_get_irq(dev, 1); | ||
| 1098 | if (secondary_irq >= 0 && !pdata->get_secondary_status) { | ||
| 1099 | ret = -EINVAL; | ||
| 1100 | goto out; | ||
| 1101 | } | ||
| 1102 | |||
| 1103 | if (request_mem_region(res->start, resource_size(res), | ||
| 1104 | dev_name(&dev->dev)) == NULL) { | ||
| 1105 | ret = -EBUSY; | ||
| 1106 | goto out; | ||
| 1107 | } | ||
| 1108 | |||
| 1109 | clk = clk_get(&dev->dev, NULL); | ||
| 1110 | if (IS_ERR(clk)) { | ||
| 1111 | ret = PTR_ERR(clk); | ||
| 1112 | goto out_release; | ||
| 1113 | } | ||
| 1114 | |||
| 1115 | nmk_chip = kzalloc(sizeof(*nmk_chip), GFP_KERNEL); | ||
| 1116 | if (!nmk_chip) { | ||
| 1117 | ret = -ENOMEM; | ||
| 1118 | goto out_clk; | ||
| 1119 | } | ||
| 1120 | /* | ||
| 1121 | * The virt address in nmk_chip->addr is in the nomadik register space, | ||
| 1122 | * so we can simply convert the resource address, without remapping | ||
| 1123 | */ | ||
| 1124 | nmk_chip->bank = dev->id; | ||
| 1125 | nmk_chip->clk = clk; | ||
| 1126 | nmk_chip->addr = io_p2v(res->start); | ||
| 1127 | nmk_chip->chip = nmk_gpio_template; | ||
| 1128 | nmk_chip->parent_irq = irq; | ||
| 1129 | nmk_chip->secondary_parent_irq = secondary_irq; | ||
| 1130 | nmk_chip->get_secondary_status = pdata->get_secondary_status; | ||
| 1131 | nmk_chip->set_ioforce = pdata->set_ioforce; | ||
| 1132 | nmk_chip->sleepmode = pdata->supports_sleepmode; | ||
| 1133 | spin_lock_init(&nmk_chip->lock); | ||
| 1134 | |||
| 1135 | chip = &nmk_chip->chip; | ||
| 1136 | chip->base = pdata->first_gpio; | ||
| 1137 | chip->ngpio = pdata->num_gpio; | ||
| 1138 | chip->label = pdata->name ?: dev_name(&dev->dev); | ||
| 1139 | chip->dev = &dev->dev; | ||
| 1140 | chip->owner = THIS_MODULE; | ||
| 1141 | |||
| 1142 | ret = gpiochip_add(&nmk_chip->chip); | ||
| 1143 | if (ret) | ||
| 1144 | goto out_free; | ||
| 1145 | |||
| 1146 | BUG_ON(nmk_chip->bank >= ARRAY_SIZE(nmk_gpio_chips)); | ||
| 1147 | |||
| 1148 | nmk_gpio_chips[nmk_chip->bank] = nmk_chip; | ||
| 1149 | platform_set_drvdata(dev, nmk_chip); | ||
| 1150 | |||
| 1151 | nmk_gpio_init_irq(nmk_chip); | ||
| 1152 | |||
| 1153 | dev_info(&dev->dev, "at address %p\n", | ||
| 1154 | nmk_chip->addr); | ||
| 1155 | return 0; | ||
| 1156 | |||
| 1157 | out_free: | ||
| 1158 | kfree(nmk_chip); | ||
| 1159 | out_clk: | ||
| 1160 | clk_disable(clk); | ||
| 1161 | clk_put(clk); | ||
| 1162 | out_release: | ||
| 1163 | release_mem_region(res->start, resource_size(res)); | ||
| 1164 | out: | ||
| 1165 | dev_err(&dev->dev, "Failure %i for GPIO %i-%i\n", ret, | ||
| 1166 | pdata->first_gpio, pdata->first_gpio+31); | ||
| 1167 | return ret; | ||
| 1168 | } | ||
| 1169 | |||
| 1170 | static struct platform_driver nmk_gpio_driver = { | ||
| 1171 | .driver = { | ||
| 1172 | .owner = THIS_MODULE, | ||
| 1173 | .name = "gpio", | ||
| 1174 | }, | ||
| 1175 | .probe = nmk_gpio_probe, | ||
| 1176 | }; | ||
| 1177 | |||
| 1178 | static int __init nmk_gpio_init(void) | ||
| 1179 | { | ||
| 1180 | return platform_driver_register(&nmk_gpio_driver); | ||
| 1181 | } | ||
| 1182 | |||
| 1183 | core_initcall(nmk_gpio_init); | ||
| 1184 | |||
| 1185 | MODULE_AUTHOR("Prafulla WADASKAR and Alessandro Rubini"); | ||
| 1186 | MODULE_DESCRIPTION("Nomadik GPIO Driver"); | ||
| 1187 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c index 1adc2ec1e383..c4ed1722734c 100644 --- a/drivers/gpio/gpio-omap.c +++ b/drivers/gpio/gpio-omap.c | |||
| @@ -57,14 +57,10 @@ struct gpio_bank { | |||
| 57 | u16 irq; | 57 | u16 irq; |
| 58 | int irq_base; | 58 | int irq_base; |
| 59 | struct irq_domain *domain; | 59 | struct irq_domain *domain; |
| 60 | u32 suspend_wakeup; | ||
| 61 | u32 saved_wakeup; | ||
| 62 | u32 non_wakeup_gpios; | 60 | u32 non_wakeup_gpios; |
| 63 | u32 enabled_non_wakeup_gpios; | 61 | u32 enabled_non_wakeup_gpios; |
| 64 | struct gpio_regs context; | 62 | struct gpio_regs context; |
| 65 | u32 saved_datain; | 63 | u32 saved_datain; |
| 66 | u32 saved_fallingdetect; | ||
| 67 | u32 saved_risingdetect; | ||
| 68 | u32 level_mask; | 64 | u32 level_mask; |
| 69 | u32 toggle_mask; | 65 | u32 toggle_mask; |
| 70 | spinlock_t lock; | 66 | spinlock_t lock; |
| @@ -516,11 +512,11 @@ static int _set_gpio_wakeup(struct gpio_bank *bank, int gpio, int enable) | |||
| 516 | 512 | ||
| 517 | spin_lock_irqsave(&bank->lock, flags); | 513 | spin_lock_irqsave(&bank->lock, flags); |
| 518 | if (enable) | 514 | if (enable) |
| 519 | bank->suspend_wakeup |= gpio_bit; | 515 | bank->context.wake_en |= gpio_bit; |
| 520 | else | 516 | else |
| 521 | bank->suspend_wakeup &= ~gpio_bit; | 517 | bank->context.wake_en &= ~gpio_bit; |
| 522 | 518 | ||
| 523 | __raw_writel(bank->suspend_wakeup, bank->base + bank->regs->wkup_en); | 519 | __raw_writel(bank->context.wake_en, bank->base + bank->regs->wkup_en); |
| 524 | spin_unlock_irqrestore(&bank->lock, flags); | 520 | spin_unlock_irqrestore(&bank->lock, flags); |
| 525 | 521 | ||
| 526 | return 0; | 522 | return 0; |
| @@ -640,7 +636,6 @@ static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc) | |||
| 640 | u32 isr; | 636 | u32 isr; |
| 641 | unsigned int gpio_irq, gpio_index; | 637 | unsigned int gpio_irq, gpio_index; |
| 642 | struct gpio_bank *bank; | 638 | struct gpio_bank *bank; |
| 643 | u32 retrigger = 0; | ||
| 644 | int unmasked = 0; | 639 | int unmasked = 0; |
| 645 | struct irq_chip *chip = irq_desc_get_chip(desc); | 640 | struct irq_chip *chip = irq_desc_get_chip(desc); |
| 646 | 641 | ||
| @@ -677,8 +672,6 @@ static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc) | |||
| 677 | chained_irq_exit(chip, desc); | 672 | chained_irq_exit(chip, desc); |
| 678 | } | 673 | } |
| 679 | 674 | ||
| 680 | isr |= retrigger; | ||
| 681 | retrigger = 0; | ||
| 682 | if (!isr) | 675 | if (!isr) |
| 683 | break; | 676 | break; |
| 684 | 677 | ||
| @@ -789,8 +782,7 @@ static int omap_mpuio_suspend_noirq(struct device *dev) | |||
| 789 | unsigned long flags; | 782 | unsigned long flags; |
| 790 | 783 | ||
| 791 | spin_lock_irqsave(&bank->lock, flags); | 784 | spin_lock_irqsave(&bank->lock, flags); |
| 792 | bank->saved_wakeup = __raw_readl(mask_reg); | 785 | __raw_writel(0xffff & ~bank->context.wake_en, mask_reg); |
| 793 | __raw_writel(0xffff & ~bank->suspend_wakeup, mask_reg); | ||
| 794 | spin_unlock_irqrestore(&bank->lock, flags); | 786 | spin_unlock_irqrestore(&bank->lock, flags); |
| 795 | 787 | ||
| 796 | return 0; | 788 | return 0; |
| @@ -805,7 +797,7 @@ static int omap_mpuio_resume_noirq(struct device *dev) | |||
| 805 | unsigned long flags; | 797 | unsigned long flags; |
| 806 | 798 | ||
| 807 | spin_lock_irqsave(&bank->lock, flags); | 799 | spin_lock_irqsave(&bank->lock, flags); |
| 808 | __raw_writel(bank->saved_wakeup, mask_reg); | 800 | __raw_writel(bank->context.wake_en, mask_reg); |
| 809 | spin_unlock_irqrestore(&bank->lock, flags); | 801 | spin_unlock_irqrestore(&bank->lock, flags); |
| 810 | 802 | ||
| 811 | return 0; | 803 | return 0; |
| @@ -965,18 +957,15 @@ static void omap_gpio_mod_init(struct gpio_bank *bank) | |||
| 965 | } | 957 | } |
| 966 | 958 | ||
| 967 | _gpio_rmw(base, bank->regs->irqenable, l, bank->regs->irqenable_inv); | 959 | _gpio_rmw(base, bank->regs->irqenable, l, bank->regs->irqenable_inv); |
| 968 | _gpio_rmw(base, bank->regs->irqstatus, l, | 960 | _gpio_rmw(base, bank->regs->irqstatus, l, !bank->regs->irqenable_inv); |
| 969 | bank->regs->irqenable_inv == false); | ||
| 970 | _gpio_rmw(base, bank->regs->irqenable, l, bank->regs->debounce_en != 0); | ||
| 971 | _gpio_rmw(base, bank->regs->irqenable, l, bank->regs->ctrl != 0); | ||
| 972 | if (bank->regs->debounce_en) | 961 | if (bank->regs->debounce_en) |
| 973 | _gpio_rmw(base, bank->regs->debounce_en, 0, 1); | 962 | __raw_writel(0, base + bank->regs->debounce_en); |
| 974 | 963 | ||
| 975 | /* Save OE default value (0xffffffff) in the context */ | 964 | /* Save OE default value (0xffffffff) in the context */ |
| 976 | bank->context.oe = __raw_readl(bank->base + bank->regs->direction); | 965 | bank->context.oe = __raw_readl(bank->base + bank->regs->direction); |
| 977 | /* Initialize interface clk ungated, module enabled */ | 966 | /* Initialize interface clk ungated, module enabled */ |
| 978 | if (bank->regs->ctrl) | 967 | if (bank->regs->ctrl) |
| 979 | _gpio_rmw(base, bank->regs->ctrl, 0, 1); | 968 | __raw_writel(0, base + bank->regs->ctrl); |
| 980 | } | 969 | } |
| 981 | 970 | ||
| 982 | static __devinit void | 971 | static __devinit void |
| @@ -1155,54 +1144,6 @@ static int __devinit omap_gpio_probe(struct platform_device *pdev) | |||
| 1155 | 1144 | ||
| 1156 | #ifdef CONFIG_ARCH_OMAP2PLUS | 1145 | #ifdef CONFIG_ARCH_OMAP2PLUS |
| 1157 | 1146 | ||
| 1158 | #if defined(CONFIG_PM_SLEEP) | ||
| 1159 | static int omap_gpio_suspend(struct device *dev) | ||
| 1160 | { | ||
| 1161 | struct platform_device *pdev = to_platform_device(dev); | ||
| 1162 | struct gpio_bank *bank = platform_get_drvdata(pdev); | ||
| 1163 | void __iomem *base = bank->base; | ||
| 1164 | void __iomem *wakeup_enable; | ||
| 1165 | unsigned long flags; | ||
| 1166 | |||
| 1167 | if (!bank->mod_usage || !bank->loses_context) | ||
| 1168 | return 0; | ||
| 1169 | |||
| 1170 | if (!bank->regs->wkup_en || !bank->suspend_wakeup) | ||
| 1171 | return 0; | ||
| 1172 | |||
| 1173 | wakeup_enable = bank->base + bank->regs->wkup_en; | ||
| 1174 | |||
| 1175 | spin_lock_irqsave(&bank->lock, flags); | ||
| 1176 | bank->saved_wakeup = __raw_readl(wakeup_enable); | ||
| 1177 | _gpio_rmw(base, bank->regs->wkup_en, 0xffffffff, 0); | ||
| 1178 | _gpio_rmw(base, bank->regs->wkup_en, bank->suspend_wakeup, 1); | ||
| 1179 | spin_unlock_irqrestore(&bank->lock, flags); | ||
| 1180 | |||
| 1181 | return 0; | ||
| 1182 | } | ||
| 1183 | |||
| 1184 | static int omap_gpio_resume(struct device *dev) | ||
| 1185 | { | ||
| 1186 | struct platform_device *pdev = to_platform_device(dev); | ||
| 1187 | struct gpio_bank *bank = platform_get_drvdata(pdev); | ||
| 1188 | void __iomem *base = bank->base; | ||
| 1189 | unsigned long flags; | ||
| 1190 | |||
| 1191 | if (!bank->mod_usage || !bank->loses_context) | ||
| 1192 | return 0; | ||
| 1193 | |||
| 1194 | if (!bank->regs->wkup_en || !bank->saved_wakeup) | ||
| 1195 | return 0; | ||
| 1196 | |||
| 1197 | spin_lock_irqsave(&bank->lock, flags); | ||
| 1198 | _gpio_rmw(base, bank->regs->wkup_en, 0xffffffff, 0); | ||
| 1199 | _gpio_rmw(base, bank->regs->wkup_en, bank->saved_wakeup, 1); | ||
| 1200 | spin_unlock_irqrestore(&bank->lock, flags); | ||
| 1201 | |||
| 1202 | return 0; | ||
| 1203 | } | ||
| 1204 | #endif /* CONFIG_PM_SLEEP */ | ||
| 1205 | |||
| 1206 | #if defined(CONFIG_PM_RUNTIME) | 1147 | #if defined(CONFIG_PM_RUNTIME) |
| 1207 | static void omap_gpio_restore_context(struct gpio_bank *bank); | 1148 | static void omap_gpio_restore_context(struct gpio_bank *bank); |
| 1208 | 1149 | ||
| @@ -1236,6 +1177,9 @@ static int omap_gpio_runtime_suspend(struct device *dev) | |||
| 1236 | __raw_writel(wake_hi | bank->context.risingdetect, | 1177 | __raw_writel(wake_hi | bank->context.risingdetect, |
| 1237 | bank->base + bank->regs->risingdetect); | 1178 | bank->base + bank->regs->risingdetect); |
| 1238 | 1179 | ||
| 1180 | if (!bank->enabled_non_wakeup_gpios) | ||
| 1181 | goto update_gpio_context_count; | ||
| 1182 | |||
| 1239 | if (bank->power_mode != OFF_MODE) { | 1183 | if (bank->power_mode != OFF_MODE) { |
| 1240 | bank->power_mode = 0; | 1184 | bank->power_mode = 0; |
| 1241 | goto update_gpio_context_count; | 1185 | goto update_gpio_context_count; |
| @@ -1247,11 +1191,9 @@ static int omap_gpio_runtime_suspend(struct device *dev) | |||
| 1247 | */ | 1191 | */ |
| 1248 | bank->saved_datain = __raw_readl(bank->base + | 1192 | bank->saved_datain = __raw_readl(bank->base + |
| 1249 | bank->regs->datain); | 1193 | bank->regs->datain); |
| 1250 | l1 = __raw_readl(bank->base + bank->regs->fallingdetect); | 1194 | l1 = bank->context.fallingdetect; |
| 1251 | l2 = __raw_readl(bank->base + bank->regs->risingdetect); | 1195 | l2 = bank->context.risingdetect; |
| 1252 | 1196 | ||
| 1253 | bank->saved_fallingdetect = l1; | ||
| 1254 | bank->saved_risingdetect = l2; | ||
| 1255 | l1 &= ~bank->enabled_non_wakeup_gpios; | 1197 | l1 &= ~bank->enabled_non_wakeup_gpios; |
| 1256 | l2 &= ~bank->enabled_non_wakeup_gpios; | 1198 | l2 &= ~bank->enabled_non_wakeup_gpios; |
| 1257 | 1199 | ||
| @@ -1293,16 +1235,10 @@ static int omap_gpio_runtime_resume(struct device *dev) | |||
| 1293 | __raw_writel(bank->context.risingdetect, | 1235 | __raw_writel(bank->context.risingdetect, |
| 1294 | bank->base + bank->regs->risingdetect); | 1236 | bank->base + bank->regs->risingdetect); |
| 1295 | 1237 | ||
| 1296 | if (!bank->workaround_enabled) { | ||
| 1297 | spin_unlock_irqrestore(&bank->lock, flags); | ||
| 1298 | return 0; | ||
| 1299 | } | ||
| 1300 | |||
| 1301 | if (bank->get_context_loss_count) { | 1238 | if (bank->get_context_loss_count) { |
| 1302 | context_lost_cnt_after = | 1239 | context_lost_cnt_after = |
| 1303 | bank->get_context_loss_count(bank->dev); | 1240 | bank->get_context_loss_count(bank->dev); |
| 1304 | if (context_lost_cnt_after != bank->context_loss_count || | 1241 | if (context_lost_cnt_after != bank->context_loss_count) { |
| 1305 | !context_lost_cnt_after) { | ||
| 1306 | omap_gpio_restore_context(bank); | 1242 | omap_gpio_restore_context(bank); |
| 1307 | } else { | 1243 | } else { |
| 1308 | spin_unlock_irqrestore(&bank->lock, flags); | 1244 | spin_unlock_irqrestore(&bank->lock, flags); |
| @@ -1310,9 +1246,14 @@ static int omap_gpio_runtime_resume(struct device *dev) | |||
| 1310 | } | 1246 | } |
| 1311 | } | 1247 | } |
| 1312 | 1248 | ||
| 1313 | __raw_writel(bank->saved_fallingdetect, | 1249 | if (!bank->workaround_enabled) { |
| 1250 | spin_unlock_irqrestore(&bank->lock, flags); | ||
| 1251 | return 0; | ||
| 1252 | } | ||
| 1253 | |||
| 1254 | __raw_writel(bank->context.fallingdetect, | ||
| 1314 | bank->base + bank->regs->fallingdetect); | 1255 | bank->base + bank->regs->fallingdetect); |
| 1315 | __raw_writel(bank->saved_risingdetect, | 1256 | __raw_writel(bank->context.risingdetect, |
| 1316 | bank->base + bank->regs->risingdetect); | 1257 | bank->base + bank->regs->risingdetect); |
| 1317 | l = __raw_readl(bank->base + bank->regs->datain); | 1258 | l = __raw_readl(bank->base + bank->regs->datain); |
| 1318 | 1259 | ||
| @@ -1329,14 +1270,15 @@ static int omap_gpio_runtime_resume(struct device *dev) | |||
| 1329 | * No need to generate IRQs for the rising edge for gpio IRQs | 1270 | * No need to generate IRQs for the rising edge for gpio IRQs |
| 1330 | * configured with falling edge only; and vice versa. | 1271 | * configured with falling edge only; and vice versa. |
| 1331 | */ | 1272 | */ |
| 1332 | gen0 = l & bank->saved_fallingdetect; | 1273 | gen0 = l & bank->context.fallingdetect; |
| 1333 | gen0 &= bank->saved_datain; | 1274 | gen0 &= bank->saved_datain; |
| 1334 | 1275 | ||
| 1335 | gen1 = l & bank->saved_risingdetect; | 1276 | gen1 = l & bank->context.risingdetect; |
| 1336 | gen1 &= ~(bank->saved_datain); | 1277 | gen1 &= ~(bank->saved_datain); |
| 1337 | 1278 | ||
| 1338 | /* FIXME: Consider GPIO IRQs with level detections properly! */ | 1279 | /* FIXME: Consider GPIO IRQs with level detections properly! */ |
| 1339 | gen = l & (~(bank->saved_fallingdetect) & ~(bank->saved_risingdetect)); | 1280 | gen = l & (~(bank->context.fallingdetect) & |
| 1281 | ~(bank->context.risingdetect)); | ||
| 1340 | /* Consider all GPIO IRQs needed to be updated */ | 1282 | /* Consider all GPIO IRQs needed to be updated */ |
| 1341 | gen |= gen0 | gen1; | 1283 | gen |= gen0 | gen1; |
| 1342 | 1284 | ||
| @@ -1346,14 +1288,14 @@ static int omap_gpio_runtime_resume(struct device *dev) | |||
| 1346 | old0 = __raw_readl(bank->base + bank->regs->leveldetect0); | 1288 | old0 = __raw_readl(bank->base + bank->regs->leveldetect0); |
| 1347 | old1 = __raw_readl(bank->base + bank->regs->leveldetect1); | 1289 | old1 = __raw_readl(bank->base + bank->regs->leveldetect1); |
| 1348 | 1290 | ||
| 1349 | if (cpu_is_omap24xx() || cpu_is_omap34xx()) { | 1291 | if (!bank->regs->irqstatus_raw0) { |
| 1350 | __raw_writel(old0 | gen, bank->base + | 1292 | __raw_writel(old0 | gen, bank->base + |
| 1351 | bank->regs->leveldetect0); | 1293 | bank->regs->leveldetect0); |
| 1352 | __raw_writel(old1 | gen, bank->base + | 1294 | __raw_writel(old1 | gen, bank->base + |
| 1353 | bank->regs->leveldetect1); | 1295 | bank->regs->leveldetect1); |
| 1354 | } | 1296 | } |
| 1355 | 1297 | ||
| 1356 | if (cpu_is_omap44xx()) { | 1298 | if (bank->regs->irqstatus_raw0) { |
| 1357 | __raw_writel(old0 | l, bank->base + | 1299 | __raw_writel(old0 | l, bank->base + |
| 1358 | bank->regs->leveldetect0); | 1300 | bank->regs->leveldetect0); |
| 1359 | __raw_writel(old1 | l, bank->base + | 1301 | __raw_writel(old1 | l, bank->base + |
| @@ -1432,14 +1374,11 @@ static void omap_gpio_restore_context(struct gpio_bank *bank) | |||
| 1432 | } | 1374 | } |
| 1433 | #endif /* CONFIG_PM_RUNTIME */ | 1375 | #endif /* CONFIG_PM_RUNTIME */ |
| 1434 | #else | 1376 | #else |
| 1435 | #define omap_gpio_suspend NULL | ||
| 1436 | #define omap_gpio_resume NULL | ||
| 1437 | #define omap_gpio_runtime_suspend NULL | 1377 | #define omap_gpio_runtime_suspend NULL |
| 1438 | #define omap_gpio_runtime_resume NULL | 1378 | #define omap_gpio_runtime_resume NULL |
| 1439 | #endif | 1379 | #endif |
| 1440 | 1380 | ||
| 1441 | static const struct dev_pm_ops gpio_pm_ops = { | 1381 | static const struct dev_pm_ops gpio_pm_ops = { |
| 1442 | SET_SYSTEM_SLEEP_PM_OPS(omap_gpio_suspend, omap_gpio_resume) | ||
| 1443 | SET_RUNTIME_PM_OPS(omap_gpio_runtime_suspend, omap_gpio_runtime_resume, | 1382 | SET_RUNTIME_PM_OPS(omap_gpio_runtime_suspend, omap_gpio_runtime_resume, |
| 1444 | NULL) | 1383 | NULL) |
| 1445 | }; | 1384 | }; |
diff --git a/drivers/gpio/gpio-pca953x.c b/drivers/gpio/gpio-pca953x.c index d3f3e8f54561..1c313c710be3 100644 --- a/drivers/gpio/gpio-pca953x.c +++ b/drivers/gpio/gpio-pca953x.c | |||
| @@ -28,6 +28,8 @@ | |||
| 28 | #define PCA953X_INVERT 2 | 28 | #define PCA953X_INVERT 2 |
| 29 | #define PCA953X_DIRECTION 3 | 29 | #define PCA953X_DIRECTION 3 |
| 30 | 30 | ||
| 31 | #define REG_ADDR_AI 0x80 | ||
| 32 | |||
| 31 | #define PCA957X_IN 0 | 33 | #define PCA957X_IN 0 |
| 32 | #define PCA957X_INVRT 1 | 34 | #define PCA957X_INVRT 1 |
| 33 | #define PCA957X_BKEN 2 | 35 | #define PCA957X_BKEN 2 |
| @@ -63,15 +65,15 @@ static const struct i2c_device_id pca953x_id[] = { | |||
| 63 | { "pca6107", 8 | PCA953X_TYPE | PCA_INT, }, | 65 | { "pca6107", 8 | PCA953X_TYPE | PCA_INT, }, |
| 64 | { "tca6408", 8 | PCA953X_TYPE | PCA_INT, }, | 66 | { "tca6408", 8 | PCA953X_TYPE | PCA_INT, }, |
| 65 | { "tca6416", 16 | PCA953X_TYPE | PCA_INT, }, | 67 | { "tca6416", 16 | PCA953X_TYPE | PCA_INT, }, |
| 66 | /* NYET: { "tca6424", 24, }, */ | 68 | { "tca6424", 24 | PCA953X_TYPE | PCA_INT, }, |
| 67 | { } | 69 | { } |
| 68 | }; | 70 | }; |
| 69 | MODULE_DEVICE_TABLE(i2c, pca953x_id); | 71 | MODULE_DEVICE_TABLE(i2c, pca953x_id); |
| 70 | 72 | ||
| 71 | struct pca953x_chip { | 73 | struct pca953x_chip { |
| 72 | unsigned gpio_start; | 74 | unsigned gpio_start; |
| 73 | uint16_t reg_output; | 75 | u32 reg_output; |
| 74 | uint16_t reg_direction; | 76 | u32 reg_direction; |
| 75 | struct mutex i2c_lock; | 77 | struct mutex i2c_lock; |
| 76 | 78 | ||
| 77 | #ifdef CONFIG_GPIO_PCA953X_IRQ | 79 | #ifdef CONFIG_GPIO_PCA953X_IRQ |
| @@ -89,12 +91,20 @@ struct pca953x_chip { | |||
| 89 | int chip_type; | 91 | int chip_type; |
| 90 | }; | 92 | }; |
| 91 | 93 | ||
| 92 | static int pca953x_write_reg(struct pca953x_chip *chip, int reg, uint16_t val) | 94 | static int pca953x_write_reg(struct pca953x_chip *chip, int reg, u32 val) |
| 93 | { | 95 | { |
| 94 | int ret = 0; | 96 | int ret = 0; |
| 95 | 97 | ||
| 96 | if (chip->gpio_chip.ngpio <= 8) | 98 | if (chip->gpio_chip.ngpio <= 8) |
| 97 | 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) { | ||
| 101 | ret = i2c_smbus_write_word_data(chip->client, | ||
| 102 | (reg << 2) | REG_ADDR_AI, | ||
| 103 | val & 0xffff); | ||
| 104 | ret = i2c_smbus_write_byte_data(chip->client, | ||
| 105 | (reg << 2) + 2, | ||
| 106 | (val & 0xff0000) >> 16); | ||
| 107 | } | ||
| 98 | else { | 108 | else { |
| 99 | switch (chip->chip_type) { | 109 | switch (chip->chip_type) { |
| 100 | case PCA953X_TYPE: | 110 | case PCA953X_TYPE: |
| @@ -121,12 +131,17 @@ static int pca953x_write_reg(struct pca953x_chip *chip, int reg, uint16_t val) | |||
| 121 | return 0; | 131 | return 0; |
| 122 | } | 132 | } |
| 123 | 133 | ||
| 124 | static int pca953x_read_reg(struct pca953x_chip *chip, int reg, uint16_t *val) | 134 | static int pca953x_read_reg(struct pca953x_chip *chip, int reg, u32 *val) |
| 125 | { | 135 | { |
| 126 | int ret; | 136 | int ret; |
| 127 | 137 | ||
| 128 | if (chip->gpio_chip.ngpio <= 8) | 138 | if (chip->gpio_chip.ngpio <= 8) |
| 129 | ret = i2c_smbus_read_byte_data(chip->client, reg); | 139 | ret = i2c_smbus_read_byte_data(chip->client, reg); |
| 140 | else if (chip->gpio_chip.ngpio == 24) { | ||
| 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 | } | ||
| 130 | else | 145 | else |
| 131 | ret = i2c_smbus_read_word_data(chip->client, reg << 1); | 146 | ret = i2c_smbus_read_word_data(chip->client, reg << 1); |
| 132 | 147 | ||
| @@ -135,14 +150,14 @@ static int pca953x_read_reg(struct pca953x_chip *chip, int reg, uint16_t *val) | |||
| 135 | return ret; | 150 | return ret; |
| 136 | } | 151 | } |
| 137 | 152 | ||
| 138 | *val = (uint16_t)ret; | 153 | *val = (u32)ret; |
| 139 | return 0; | 154 | return 0; |
| 140 | } | 155 | } |
| 141 | 156 | ||
| 142 | static int pca953x_gpio_direction_input(struct gpio_chip *gc, unsigned off) | 157 | static int pca953x_gpio_direction_input(struct gpio_chip *gc, unsigned off) |
| 143 | { | 158 | { |
| 144 | struct pca953x_chip *chip; | 159 | struct pca953x_chip *chip; |
| 145 | uint16_t reg_val; | 160 | uint reg_val; |
| 146 | int ret, offset = 0; | 161 | int ret, offset = 0; |
| 147 | 162 | ||
| 148 | chip = container_of(gc, struct pca953x_chip, gpio_chip); | 163 | chip = container_of(gc, struct pca953x_chip, gpio_chip); |
| @@ -173,7 +188,7 @@ static int pca953x_gpio_direction_output(struct gpio_chip *gc, | |||
| 173 | unsigned off, int val) | 188 | unsigned off, int val) |
| 174 | { | 189 | { |
| 175 | struct pca953x_chip *chip; | 190 | struct pca953x_chip *chip; |
| 176 | uint16_t reg_val; | 191 | uint reg_val; |
| 177 | int ret, offset = 0; | 192 | int ret, offset = 0; |
| 178 | 193 | ||
| 179 | chip = container_of(gc, struct pca953x_chip, gpio_chip); | 194 | chip = container_of(gc, struct pca953x_chip, gpio_chip); |
| @@ -223,7 +238,7 @@ exit: | |||
| 223 | static int pca953x_gpio_get_value(struct gpio_chip *gc, unsigned off) | 238 | static int pca953x_gpio_get_value(struct gpio_chip *gc, unsigned off) |
| 224 | { | 239 | { |
| 225 | struct pca953x_chip *chip; | 240 | struct pca953x_chip *chip; |
| 226 | uint16_t reg_val; | 241 | u32 reg_val; |
| 227 | int ret, offset = 0; | 242 | int ret, offset = 0; |
| 228 | 243 | ||
| 229 | chip = container_of(gc, struct pca953x_chip, gpio_chip); | 244 | chip = container_of(gc, struct pca953x_chip, gpio_chip); |
| @@ -253,7 +268,7 @@ static int pca953x_gpio_get_value(struct gpio_chip *gc, unsigned off) | |||
| 253 | static void pca953x_gpio_set_value(struct gpio_chip *gc, unsigned off, int val) | 268 | static void pca953x_gpio_set_value(struct gpio_chip *gc, unsigned off, int val) |
| 254 | { | 269 | { |
| 255 | struct pca953x_chip *chip; | 270 | struct pca953x_chip *chip; |
| 256 | uint16_t reg_val; | 271 | u32 reg_val; |
| 257 | int ret, offset = 0; | 272 | int ret, offset = 0; |
| 258 | 273 | ||
| 259 | chip = container_of(gc, struct pca953x_chip, gpio_chip); | 274 | chip = container_of(gc, struct pca953x_chip, gpio_chip); |
| @@ -386,7 +401,7 @@ static struct irq_chip pca953x_irq_chip = { | |||
| 386 | 401 | ||
| 387 | static uint16_t pca953x_irq_pending(struct pca953x_chip *chip) | 402 | static uint16_t pca953x_irq_pending(struct pca953x_chip *chip) |
| 388 | { | 403 | { |
| 389 | uint16_t cur_stat; | 404 | u32 cur_stat; |
| 390 | uint16_t old_stat; | 405 | uint16_t old_stat; |
| 391 | uint16_t pending; | 406 | uint16_t pending; |
| 392 | uint16_t trigger; | 407 | uint16_t trigger; |
| @@ -449,6 +464,7 @@ static int pca953x_irq_setup(struct pca953x_chip *chip, | |||
| 449 | { | 464 | { |
| 450 | struct i2c_client *client = chip->client; | 465 | struct i2c_client *client = chip->client; |
| 451 | int ret, offset = 0; | 466 | int ret, offset = 0; |
| 467 | u32 temporary; | ||
| 452 | 468 | ||
| 453 | if (irq_base != -1 | 469 | if (irq_base != -1 |
| 454 | && (id->driver_data & PCA_INT)) { | 470 | && (id->driver_data & PCA_INT)) { |
| @@ -462,7 +478,8 @@ static int pca953x_irq_setup(struct pca953x_chip *chip, | |||
| 462 | offset = PCA957X_IN; | 478 | offset = PCA957X_IN; |
| 463 | break; | 479 | break; |
| 464 | } | 480 | } |
| 465 | ret = pca953x_read_reg(chip, offset, &chip->irq_stat); | 481 | ret = pca953x_read_reg(chip, offset, &temporary); |
| 482 | chip->irq_stat = temporary; | ||
| 466 | if (ret) | 483 | if (ret) |
| 467 | goto out_failed; | 484 | goto out_failed; |
| 468 | 485 | ||
| @@ -603,7 +620,7 @@ out: | |||
| 603 | static int __devinit device_pca957x_init(struct pca953x_chip *chip, int invert) | 620 | static int __devinit device_pca957x_init(struct pca953x_chip *chip, int invert) |
| 604 | { | 621 | { |
| 605 | int ret; | 622 | int ret; |
| 606 | uint16_t val = 0; | 623 | u32 val = 0; |
| 607 | 624 | ||
| 608 | /* Let every port in proper state, that could save power */ | 625 | /* Let every port in proper state, that could save power */ |
| 609 | pca953x_write_reg(chip, PCA957X_PUPD, 0x0); | 626 | pca953x_write_reg(chip, PCA957X_PUPD, 0x0); |
diff --git a/drivers/gpio/gpio-pch.c b/drivers/gpio/gpio-pch.c index e8729cc2ba2b..139ad3e20011 100644 --- a/drivers/gpio/gpio-pch.c +++ b/drivers/gpio/gpio-pch.c | |||
| @@ -230,16 +230,12 @@ static void pch_gpio_setup(struct pch_gpio *chip) | |||
| 230 | 230 | ||
| 231 | static int pch_irq_type(struct irq_data *d, unsigned int type) | 231 | static int pch_irq_type(struct irq_data *d, unsigned int type) |
| 232 | { | 232 | { |
| 233 | u32 im; | ||
| 234 | u32 __iomem *im_reg; | ||
| 235 | u32 ien; | ||
| 236 | u32 im_pos; | ||
| 237 | int ch; | ||
| 238 | unsigned long flags; | ||
| 239 | u32 val; | ||
| 240 | int irq = d->irq; | ||
| 241 | struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); | 233 | struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); |
| 242 | struct pch_gpio *chip = gc->private; | 234 | struct pch_gpio *chip = gc->private; |
| 235 | u32 im, im_pos, val; | ||
| 236 | u32 __iomem *im_reg; | ||
| 237 | unsigned long flags; | ||
| 238 | int ch, irq = d->irq; | ||
| 243 | 239 | ||
| 244 | ch = irq - chip->irq_base; | 240 | ch = irq - chip->irq_base; |
| 245 | if (irq <= chip->irq_base + 7) { | 241 | if (irq <= chip->irq_base + 7) { |
| @@ -270,30 +266,22 @@ static int pch_irq_type(struct irq_data *d, unsigned int type) | |||
| 270 | case IRQ_TYPE_LEVEL_LOW: | 266 | case IRQ_TYPE_LEVEL_LOW: |
| 271 | val = PCH_LEVEL_L; | 267 | val = PCH_LEVEL_L; |
| 272 | break; | 268 | break; |
| 273 | case IRQ_TYPE_PROBE: | ||
| 274 | goto end; | ||
| 275 | default: | 269 | default: |
| 276 | dev_warn(chip->dev, "%s: unknown type(%dd)", | 270 | goto unlock; |
| 277 | __func__, type); | ||
| 278 | goto end; | ||
| 279 | } | 271 | } |
| 280 | 272 | ||
| 281 | /* Set interrupt mode */ | 273 | /* Set interrupt mode */ |
| 282 | im = ioread32(im_reg) & ~(PCH_IM_MASK << (im_pos * 4)); | 274 | im = ioread32(im_reg) & ~(PCH_IM_MASK << (im_pos * 4)); |
| 283 | iowrite32(im | (val << (im_pos * 4)), im_reg); | 275 | iowrite32(im | (val << (im_pos * 4)), im_reg); |
| 284 | 276 | ||
| 285 | /* iclr */ | 277 | /* And the handler */ |
| 286 | iowrite32(BIT(ch), &chip->reg->iclr); | 278 | if (type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_LEVEL_HIGH)) |
| 279 | __irq_set_handler_locked(d->irq, handle_level_irq); | ||
| 280 | else if (type & (IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING)) | ||
| 281 | __irq_set_handler_locked(d->irq, handle_edge_irq); | ||
| 287 | 282 | ||
| 288 | /* IMASKCLR */ | 283 | unlock: |
| 289 | iowrite32(BIT(ch), &chip->reg->imaskclr); | ||
| 290 | |||
| 291 | /* Enable interrupt */ | ||
| 292 | ien = ioread32(&chip->reg->ien); | ||
| 293 | iowrite32(ien | BIT(ch), &chip->reg->ien); | ||
| 294 | end: | ||
| 295 | spin_unlock_irqrestore(&chip->spinlock, flags); | 284 | spin_unlock_irqrestore(&chip->spinlock, flags); |
| 296 | |||
| 297 | return 0; | 285 | return 0; |
| 298 | } | 286 | } |
| 299 | 287 | ||
| @@ -313,18 +301,24 @@ static void pch_irq_mask(struct irq_data *d) | |||
| 313 | iowrite32(1 << (d->irq - chip->irq_base), &chip->reg->imask); | 301 | iowrite32(1 << (d->irq - chip->irq_base), &chip->reg->imask); |
| 314 | } | 302 | } |
| 315 | 303 | ||
| 304 | static void pch_irq_ack(struct irq_data *d) | ||
| 305 | { | ||
| 306 | struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); | ||
| 307 | struct pch_gpio *chip = gc->private; | ||
| 308 | |||
| 309 | iowrite32(1 << (d->irq - chip->irq_base), &chip->reg->iclr); | ||
| 310 | } | ||
| 311 | |||
| 316 | static irqreturn_t pch_gpio_handler(int irq, void *dev_id) | 312 | static irqreturn_t pch_gpio_handler(int irq, void *dev_id) |
| 317 | { | 313 | { |
| 318 | struct pch_gpio *chip = dev_id; | 314 | struct pch_gpio *chip = dev_id; |
| 319 | u32 reg_val = ioread32(&chip->reg->istatus); | 315 | u32 reg_val = ioread32(&chip->reg->istatus); |
| 320 | int i; | 316 | int i, ret = IRQ_NONE; |
| 321 | int ret = IRQ_NONE; | ||
| 322 | 317 | ||
| 323 | for (i = 0; i < gpio_pins[chip->ioh]; i++) { | 318 | for (i = 0; i < gpio_pins[chip->ioh]; i++) { |
| 324 | if (reg_val & BIT(i)) { | 319 | if (reg_val & BIT(i)) { |
| 325 | dev_dbg(chip->dev, "%s:[%d]:irq=%d status=0x%x\n", | 320 | dev_dbg(chip->dev, "%s:[%d]:irq=%d status=0x%x\n", |
| 326 | __func__, i, irq, reg_val); | 321 | __func__, i, irq, reg_val); |
| 327 | iowrite32(BIT(i), &chip->reg->iclr); | ||
| 328 | generic_handle_irq(chip->irq_base + i); | 322 | generic_handle_irq(chip->irq_base + i); |
| 329 | ret = IRQ_HANDLED; | 323 | ret = IRQ_HANDLED; |
| 330 | } | 324 | } |
| @@ -343,6 +337,7 @@ static __devinit void pch_gpio_alloc_generic_chip(struct pch_gpio *chip, | |||
| 343 | gc->private = chip; | 337 | gc->private = chip; |
| 344 | ct = gc->chip_types; | 338 | ct = gc->chip_types; |
| 345 | 339 | ||
| 340 | ct->chip.irq_ack = pch_irq_ack; | ||
| 346 | ct->chip.irq_mask = pch_irq_mask; | 341 | ct->chip.irq_mask = pch_irq_mask; |
| 347 | ct->chip.irq_unmask = pch_irq_unmask; | 342 | ct->chip.irq_unmask = pch_irq_unmask; |
| 348 | ct->chip.irq_set_type = pch_irq_type; | 343 | ct->chip.irq_set_type = pch_irq_type; |
| @@ -357,6 +352,7 @@ static int __devinit pch_gpio_probe(struct pci_dev *pdev, | |||
| 357 | s32 ret; | 352 | s32 ret; |
| 358 | struct pch_gpio *chip; | 353 | struct pch_gpio *chip; |
| 359 | int irq_base; | 354 | int irq_base; |
| 355 | u32 msk; | ||
| 360 | 356 | ||
| 361 | chip = kzalloc(sizeof(*chip), GFP_KERNEL); | 357 | chip = kzalloc(sizeof(*chip), GFP_KERNEL); |
| 362 | if (chip == NULL) | 358 | if (chip == NULL) |
| @@ -408,8 +404,13 @@ static int __devinit pch_gpio_probe(struct pci_dev *pdev, | |||
| 408 | } | 404 | } |
| 409 | chip->irq_base = irq_base; | 405 | chip->irq_base = irq_base; |
| 410 | 406 | ||
| 407 | /* Mask all interrupts, but enable them */ | ||
| 408 | msk = (1 << gpio_pins[chip->ioh]) - 1; | ||
| 409 | iowrite32(msk, &chip->reg->imask); | ||
| 410 | iowrite32(msk, &chip->reg->ien); | ||
| 411 | |||
| 411 | ret = request_irq(pdev->irq, pch_gpio_handler, | 412 | ret = request_irq(pdev->irq, pch_gpio_handler, |
| 412 | IRQF_SHARED, KBUILD_MODNAME, chip); | 413 | IRQF_SHARED, KBUILD_MODNAME, chip); |
| 413 | if (ret != 0) { | 414 | if (ret != 0) { |
| 414 | dev_err(&pdev->dev, | 415 | dev_err(&pdev->dev, |
| 415 | "%s request_irq failed\n", __func__); | 416 | "%s request_irq failed\n", __func__); |
| @@ -418,8 +419,6 @@ static int __devinit pch_gpio_probe(struct pci_dev *pdev, | |||
| 418 | 419 | ||
| 419 | pch_gpio_alloc_generic_chip(chip, irq_base, gpio_pins[chip->ioh]); | 420 | pch_gpio_alloc_generic_chip(chip, irq_base, gpio_pins[chip->ioh]); |
| 420 | 421 | ||
| 421 | /* Initialize interrupt ien register */ | ||
| 422 | iowrite32(0, &chip->reg->ien); | ||
| 423 | end: | 422 | end: |
| 424 | return 0; | 423 | return 0; |
| 425 | 424 | ||
| @@ -539,17 +538,7 @@ static struct pci_driver pch_gpio_driver = { | |||
| 539 | .resume = pch_gpio_resume | 538 | .resume = pch_gpio_resume |
| 540 | }; | 539 | }; |
| 541 | 540 | ||
| 542 | static int __init pch_gpio_pci_init(void) | 541 | module_pci_driver(pch_gpio_driver); |
| 543 | { | ||
| 544 | return pci_register_driver(&pch_gpio_driver); | ||
| 545 | } | ||
| 546 | module_init(pch_gpio_pci_init); | ||
| 547 | |||
| 548 | static void __exit pch_gpio_pci_exit(void) | ||
| 549 | { | ||
| 550 | pci_unregister_driver(&pch_gpio_driver); | ||
| 551 | } | ||
| 552 | module_exit(pch_gpio_pci_exit); | ||
| 553 | 542 | ||
| 554 | MODULE_DESCRIPTION("PCH GPIO PCI Driver"); | 543 | MODULE_DESCRIPTION("PCH GPIO PCI Driver"); |
| 555 | MODULE_LICENSE("GPL"); | 544 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/gpio/gpio-pxa.c b/drivers/gpio/gpio-pxa.c index fc3ace3fd4cb..58a6a63a6ece 100644 --- a/drivers/gpio/gpio-pxa.c +++ b/drivers/gpio/gpio-pxa.c | |||
| @@ -11,13 +11,17 @@ | |||
| 11 | * it under the terms of the GNU General Public License version 2 as | 11 | * it under the terms of the GNU General Public License version 2 as |
| 12 | * published by the Free Software Foundation. | 12 | * published by the Free Software Foundation. |
| 13 | */ | 13 | */ |
| 14 | #include <linux/module.h> | ||
| 14 | #include <linux/clk.h> | 15 | #include <linux/clk.h> |
| 15 | #include <linux/err.h> | 16 | #include <linux/err.h> |
| 16 | #include <linux/gpio.h> | 17 | #include <linux/gpio.h> |
| 17 | #include <linux/gpio-pxa.h> | 18 | #include <linux/gpio-pxa.h> |
| 18 | #include <linux/init.h> | 19 | #include <linux/init.h> |
| 19 | #include <linux/irq.h> | 20 | #include <linux/irq.h> |
| 21 | #include <linux/irqdomain.h> | ||
| 20 | #include <linux/io.h> | 22 | #include <linux/io.h> |
| 23 | #include <linux/of.h> | ||
| 24 | #include <linux/of_device.h> | ||
| 21 | #include <linux/platform_device.h> | 25 | #include <linux/platform_device.h> |
| 22 | #include <linux/syscore_ops.h> | 26 | #include <linux/syscore_ops.h> |
| 23 | #include <linux/slab.h> | 27 | #include <linux/slab.h> |
| @@ -56,6 +60,10 @@ | |||
| 56 | 60 | ||
| 57 | int pxa_last_gpio; | 61 | int pxa_last_gpio; |
| 58 | 62 | ||
| 63 | #ifdef CONFIG_OF | ||
| 64 | static struct irq_domain *domain; | ||
| 65 | #endif | ||
| 66 | |||
| 59 | struct pxa_gpio_chip { | 67 | struct pxa_gpio_chip { |
| 60 | struct gpio_chip chip; | 68 | struct gpio_chip chip; |
| 61 | void __iomem *regbase; | 69 | void __iomem *regbase; |
| @@ -81,7 +89,6 @@ enum { | |||
| 81 | PXA3XX_GPIO, | 89 | PXA3XX_GPIO, |
| 82 | PXA93X_GPIO, | 90 | PXA93X_GPIO, |
| 83 | MMP_GPIO = 0x10, | 91 | MMP_GPIO = 0x10, |
| 84 | MMP2_GPIO, | ||
| 85 | }; | 92 | }; |
| 86 | 93 | ||
| 87 | static DEFINE_SPINLOCK(gpio_lock); | 94 | static DEFINE_SPINLOCK(gpio_lock); |
| @@ -475,22 +482,92 @@ static int pxa_gpio_nums(void) | |||
| 475 | gpio_type = MMP_GPIO; | 482 | gpio_type = MMP_GPIO; |
| 476 | } else if (cpu_is_mmp2()) { | 483 | } else if (cpu_is_mmp2()) { |
| 477 | count = 191; | 484 | count = 191; |
| 478 | gpio_type = MMP2_GPIO; | 485 | gpio_type = MMP_GPIO; |
| 479 | } | 486 | } |
| 480 | #endif /* CONFIG_ARCH_MMP */ | 487 | #endif /* CONFIG_ARCH_MMP */ |
| 481 | return count; | 488 | return count; |
| 482 | } | 489 | } |
| 483 | 490 | ||
| 491 | static struct of_device_id pxa_gpio_dt_ids[] = { | ||
| 492 | { .compatible = "mrvl,pxa-gpio" }, | ||
| 493 | { .compatible = "mrvl,mmp-gpio", .data = (void *)MMP_GPIO }, | ||
| 494 | {} | ||
| 495 | }; | ||
| 496 | |||
| 497 | static int pxa_irq_domain_map(struct irq_domain *d, unsigned int irq, | ||
| 498 | irq_hw_number_t hw) | ||
| 499 | { | ||
| 500 | irq_set_chip_and_handler(irq, &pxa_muxed_gpio_chip, | ||
| 501 | handle_edge_irq); | ||
| 502 | set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); | ||
| 503 | return 0; | ||
| 504 | } | ||
| 505 | |||
| 506 | const struct irq_domain_ops pxa_irq_domain_ops = { | ||
| 507 | .map = pxa_irq_domain_map, | ||
| 508 | }; | ||
| 509 | |||
| 510 | #ifdef CONFIG_OF | ||
| 511 | static int __devinit pxa_gpio_probe_dt(struct platform_device *pdev) | ||
| 512 | { | ||
| 513 | int ret, nr_banks, nr_gpios, irq_base; | ||
| 514 | struct device_node *prev, *next, *np = pdev->dev.of_node; | ||
| 515 | const struct of_device_id *of_id = | ||
| 516 | of_match_device(pxa_gpio_dt_ids, &pdev->dev); | ||
| 517 | |||
| 518 | if (!of_id) { | ||
| 519 | dev_err(&pdev->dev, "Failed to find gpio controller\n"); | ||
| 520 | return -EFAULT; | ||
| 521 | } | ||
| 522 | gpio_type = (int)of_id->data; | ||
| 523 | |||
| 524 | next = of_get_next_child(np, NULL); | ||
| 525 | prev = next; | ||
| 526 | if (!next) { | ||
| 527 | dev_err(&pdev->dev, "Failed to find child gpio node\n"); | ||
| 528 | ret = -EINVAL; | ||
| 529 | goto err; | ||
| 530 | } | ||
| 531 | for (nr_banks = 1; ; nr_banks++) { | ||
| 532 | next = of_get_next_child(np, prev); | ||
| 533 | if (!next) | ||
| 534 | break; | ||
| 535 | prev = next; | ||
| 536 | } | ||
| 537 | of_node_put(prev); | ||
| 538 | nr_gpios = nr_banks << 5; | ||
| 539 | pxa_last_gpio = nr_gpios - 1; | ||
| 540 | |||
| 541 | irq_base = irq_alloc_descs(-1, 0, nr_gpios, 0); | ||
| 542 | if (irq_base < 0) { | ||
| 543 | dev_err(&pdev->dev, "Failed to allocate IRQ numbers\n"); | ||
| 544 | goto err; | ||
| 545 | } | ||
| 546 | domain = irq_domain_add_legacy(np, nr_gpios, irq_base, 0, | ||
| 547 | &pxa_irq_domain_ops, NULL); | ||
| 548 | return 0; | ||
| 549 | err: | ||
| 550 | iounmap(gpio_reg_base); | ||
| 551 | return ret; | ||
| 552 | } | ||
| 553 | #else | ||
| 554 | #define pxa_gpio_probe_dt(pdev) (-1) | ||
| 555 | #endif | ||
| 556 | |||
| 484 | static int __devinit pxa_gpio_probe(struct platform_device *pdev) | 557 | static int __devinit pxa_gpio_probe(struct platform_device *pdev) |
| 485 | { | 558 | { |
| 486 | struct pxa_gpio_chip *c; | 559 | struct pxa_gpio_chip *c; |
| 487 | struct resource *res; | 560 | struct resource *res; |
| 488 | struct clk *clk; | 561 | struct clk *clk; |
| 489 | struct pxa_gpio_platform_data *info; | 562 | struct pxa_gpio_platform_data *info; |
| 490 | int gpio, irq, ret; | 563 | int gpio, irq, ret, use_of = 0; |
| 491 | int irq0 = 0, irq1 = 0, irq_mux, gpio_offset = 0; | 564 | int irq0 = 0, irq1 = 0, irq_mux, gpio_offset = 0; |
| 492 | 565 | ||
| 493 | pxa_last_gpio = pxa_gpio_nums(); | 566 | ret = pxa_gpio_probe_dt(pdev); |
| 567 | if (ret < 0) | ||
| 568 | pxa_last_gpio = pxa_gpio_nums(); | ||
| 569 | else | ||
| 570 | use_of = 1; | ||
| 494 | if (!pxa_last_gpio) | 571 | if (!pxa_last_gpio) |
| 495 | return -EINVAL; | 572 | return -EINVAL; |
| 496 | 573 | ||
| @@ -545,25 +622,27 @@ static int __devinit pxa_gpio_probe(struct platform_device *pdev) | |||
| 545 | writel_relaxed(~0, c->regbase + ED_MASK_OFFSET); | 622 | writel_relaxed(~0, c->regbase + ED_MASK_OFFSET); |
| 546 | } | 623 | } |
| 547 | 624 | ||
| 625 | if (!use_of) { | ||
| 548 | #ifdef CONFIG_ARCH_PXA | 626 | #ifdef CONFIG_ARCH_PXA |
| 549 | irq = gpio_to_irq(0); | 627 | irq = gpio_to_irq(0); |
| 550 | irq_set_chip_and_handler(irq, &pxa_muxed_gpio_chip, | 628 | irq_set_chip_and_handler(irq, &pxa_muxed_gpio_chip, |
| 551 | handle_edge_irq); | 629 | handle_edge_irq); |
| 552 | set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); | 630 | set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); |
| 553 | irq_set_chained_handler(IRQ_GPIO0, pxa_gpio_demux_handler); | 631 | irq_set_chained_handler(IRQ_GPIO0, pxa_gpio_demux_handler); |
| 554 | |||
| 555 | irq = gpio_to_irq(1); | ||
| 556 | irq_set_chip_and_handler(irq, &pxa_muxed_gpio_chip, | ||
| 557 | handle_edge_irq); | ||
| 558 | set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); | ||
| 559 | irq_set_chained_handler(IRQ_GPIO1, pxa_gpio_demux_handler); | ||
| 560 | #endif | ||
| 561 | 632 | ||
| 562 | for (irq = gpio_to_irq(gpio_offset); | 633 | irq = gpio_to_irq(1); |
| 563 | irq <= gpio_to_irq(pxa_last_gpio); irq++) { | ||
| 564 | irq_set_chip_and_handler(irq, &pxa_muxed_gpio_chip, | 634 | irq_set_chip_and_handler(irq, &pxa_muxed_gpio_chip, |
| 565 | handle_edge_irq); | 635 | handle_edge_irq); |
| 566 | set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); | 636 | set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); |
| 637 | irq_set_chained_handler(IRQ_GPIO1, pxa_gpio_demux_handler); | ||
| 638 | #endif | ||
| 639 | |||
| 640 | for (irq = gpio_to_irq(gpio_offset); | ||
| 641 | irq <= gpio_to_irq(pxa_last_gpio); irq++) { | ||
| 642 | irq_set_chip_and_handler(irq, &pxa_muxed_gpio_chip, | ||
| 643 | handle_edge_irq); | ||
| 644 | set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); | ||
| 645 | } | ||
| 567 | } | 646 | } |
| 568 | 647 | ||
| 569 | irq_set_chained_handler(irq_mux, pxa_gpio_demux_handler); | 648 | irq_set_chained_handler(irq_mux, pxa_gpio_demux_handler); |
| @@ -574,6 +653,7 @@ static struct platform_driver pxa_gpio_driver = { | |||
| 574 | .probe = pxa_gpio_probe, | 653 | .probe = pxa_gpio_probe, |
| 575 | .driver = { | 654 | .driver = { |
| 576 | .name = "pxa-gpio", | 655 | .name = "pxa-gpio", |
| 656 | .of_match_table = pxa_gpio_dt_ids, | ||
| 577 | }, | 657 | }, |
| 578 | }; | 658 | }; |
| 579 | 659 | ||
diff --git a/drivers/gpio/gpio-rc5t583.c b/drivers/gpio/gpio-rc5t583.c new file mode 100644 index 000000000000..08428bf17718 --- /dev/null +++ b/drivers/gpio/gpio-rc5t583.c | |||
| @@ -0,0 +1,180 @@ | |||
| 1 | /* | ||
| 2 | * GPIO driver for RICOH583 power management chip. | ||
| 3 | * | ||
| 4 | * Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved. | ||
| 5 | * Author: Laxman dewangan <ldewangan@nvidia.com> | ||
| 6 | * | ||
| 7 | * Based on code | ||
| 8 | * Copyright (C) 2011 RICOH COMPANY,LTD | ||
| 9 | * | ||
| 10 | * This program is free software; you can redistribute it and/or modify it | ||
| 11 | * under the terms and conditions of the GNU General Public License, | ||
| 12 | * version 2, as published by the Free Software Foundation. | ||
| 13 | * | ||
| 14 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
| 15 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 16 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
| 17 | * more details. | ||
| 18 | * | ||
| 19 | * You should have received a copy of the GNU General Public License | ||
| 20 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 21 | * | ||
| 22 | */ | ||
| 23 | #include <linux/init.h> | ||
| 24 | #include <linux/kernel.h> | ||
| 25 | #include <linux/slab.h> | ||
| 26 | #include <linux/module.h> | ||
| 27 | #include <linux/platform_device.h> | ||
| 28 | #include <linux/device.h> | ||
| 29 | #include <linux/gpio.h> | ||
| 30 | #include <linux/mfd/rc5t583.h> | ||
| 31 | |||
| 32 | struct rc5t583_gpio { | ||
| 33 | struct gpio_chip gpio_chip; | ||
| 34 | struct rc5t583 *rc5t583; | ||
| 35 | }; | ||
| 36 | |||
| 37 | static inline struct rc5t583_gpio *to_rc5t583_gpio(struct gpio_chip *chip) | ||
| 38 | { | ||
| 39 | return container_of(chip, struct rc5t583_gpio, gpio_chip); | ||
| 40 | } | ||
| 41 | |||
| 42 | static int rc5t583_gpio_get(struct gpio_chip *gc, unsigned int offset) | ||
| 43 | { | ||
| 44 | struct rc5t583_gpio *rc5t583_gpio = to_rc5t583_gpio(gc); | ||
| 45 | struct device *parent = rc5t583_gpio->rc5t583->dev; | ||
| 46 | uint8_t val = 0; | ||
| 47 | int ret; | ||
| 48 | |||
| 49 | ret = rc5t583_read(parent, RC5T583_GPIO_MON_IOIN, &val); | ||
| 50 | if (ret < 0) | ||
| 51 | return ret; | ||
| 52 | |||
| 53 | return !!(val & BIT(offset)); | ||
| 54 | } | ||
| 55 | |||
| 56 | static void rc5t583_gpio_set(struct gpio_chip *gc, unsigned int offset, int val) | ||
| 57 | { | ||
| 58 | struct rc5t583_gpio *rc5t583_gpio = to_rc5t583_gpio(gc); | ||
| 59 | struct device *parent = rc5t583_gpio->rc5t583->dev; | ||
| 60 | if (val) | ||
| 61 | rc5t583_set_bits(parent, RC5T583_GPIO_IOOUT, BIT(offset)); | ||
| 62 | else | ||
| 63 | rc5t583_clear_bits(parent, RC5T583_GPIO_IOOUT, BIT(offset)); | ||
| 64 | } | ||
| 65 | |||
| 66 | static int rc5t583_gpio_dir_input(struct gpio_chip *gc, unsigned int offset) | ||
| 67 | { | ||
| 68 | struct rc5t583_gpio *rc5t583_gpio = to_rc5t583_gpio(gc); | ||
| 69 | struct device *parent = rc5t583_gpio->rc5t583->dev; | ||
| 70 | int ret; | ||
| 71 | |||
| 72 | ret = rc5t583_clear_bits(parent, RC5T583_GPIO_IOSEL, BIT(offset)); | ||
| 73 | if (ret < 0) | ||
| 74 | return ret; | ||
| 75 | |||
| 76 | /* Set pin to gpio mode */ | ||
| 77 | return rc5t583_clear_bits(parent, RC5T583_GPIO_PGSEL, BIT(offset)); | ||
| 78 | } | ||
| 79 | |||
| 80 | static int rc5t583_gpio_dir_output(struct gpio_chip *gc, unsigned offset, | ||
| 81 | int value) | ||
| 82 | { | ||
| 83 | struct rc5t583_gpio *rc5t583_gpio = to_rc5t583_gpio(gc); | ||
| 84 | struct device *parent = rc5t583_gpio->rc5t583->dev; | ||
| 85 | int ret; | ||
| 86 | |||
| 87 | rc5t583_gpio_set(gc, offset, value); | ||
| 88 | ret = rc5t583_set_bits(parent, RC5T583_GPIO_IOSEL, BIT(offset)); | ||
| 89 | if (ret < 0) | ||
| 90 | return ret; | ||
| 91 | |||
| 92 | /* Set pin to gpio mode */ | ||
| 93 | return rc5t583_clear_bits(parent, RC5T583_GPIO_PGSEL, BIT(offset)); | ||
| 94 | } | ||
| 95 | |||
| 96 | static int rc5t583_gpio_to_irq(struct gpio_chip *gc, unsigned offset) | ||
| 97 | { | ||
| 98 | struct rc5t583_gpio *rc5t583_gpio = to_rc5t583_gpio(gc); | ||
| 99 | |||
| 100 | if ((offset >= 0) && (offset < 8)) | ||
| 101 | return rc5t583_gpio->rc5t583->irq_base + | ||
| 102 | RC5T583_IRQ_GPIO0 + offset; | ||
| 103 | return -EINVAL; | ||
| 104 | } | ||
| 105 | |||
| 106 | static void rc5t583_gpio_free(struct gpio_chip *gc, unsigned offset) | ||
| 107 | { | ||
| 108 | struct rc5t583_gpio *rc5t583_gpio = to_rc5t583_gpio(gc); | ||
| 109 | struct device *parent = rc5t583_gpio->rc5t583->dev; | ||
| 110 | |||
| 111 | rc5t583_set_bits(parent, RC5T583_GPIO_PGSEL, BIT(offset)); | ||
| 112 | } | ||
| 113 | |||
| 114 | static int __devinit rc5t583_gpio_probe(struct platform_device *pdev) | ||
| 115 | { | ||
| 116 | struct rc5t583 *rc5t583 = dev_get_drvdata(pdev->dev.parent); | ||
| 117 | struct rc5t583_platform_data *pdata = dev_get_platdata(rc5t583->dev); | ||
| 118 | struct rc5t583_gpio *rc5t583_gpio; | ||
| 119 | |||
| 120 | rc5t583_gpio = devm_kzalloc(&pdev->dev, sizeof(*rc5t583_gpio), | ||
| 121 | GFP_KERNEL); | ||
| 122 | if (!rc5t583_gpio) { | ||
| 123 | dev_warn(&pdev->dev, "Mem allocation for rc5t583_gpio failed"); | ||
| 124 | return -ENOMEM; | ||
| 125 | } | ||
| 126 | |||
| 127 | rc5t583_gpio->gpio_chip.label = "gpio-rc5t583", | ||
| 128 | rc5t583_gpio->gpio_chip.owner = THIS_MODULE, | ||
| 129 | rc5t583_gpio->gpio_chip.free = rc5t583_gpio_free, | ||
| 130 | rc5t583_gpio->gpio_chip.direction_input = rc5t583_gpio_dir_input, | ||
| 131 | rc5t583_gpio->gpio_chip.direction_output = rc5t583_gpio_dir_output, | ||
| 132 | rc5t583_gpio->gpio_chip.set = rc5t583_gpio_set, | ||
| 133 | rc5t583_gpio->gpio_chip.get = rc5t583_gpio_get, | ||
| 134 | rc5t583_gpio->gpio_chip.to_irq = rc5t583_gpio_to_irq, | ||
| 135 | rc5t583_gpio->gpio_chip.ngpio = RC5T583_MAX_GPIO, | ||
| 136 | rc5t583_gpio->gpio_chip.can_sleep = 1, | ||
| 137 | rc5t583_gpio->gpio_chip.dev = &pdev->dev; | ||
| 138 | rc5t583_gpio->gpio_chip.base = -1; | ||
| 139 | rc5t583_gpio->rc5t583 = rc5t583; | ||
| 140 | |||
| 141 | if (pdata && pdata->gpio_base) | ||
| 142 | rc5t583_gpio->gpio_chip.base = pdata->gpio_base; | ||
| 143 | |||
| 144 | platform_set_drvdata(pdev, rc5t583_gpio); | ||
| 145 | |||
| 146 | return gpiochip_add(&rc5t583_gpio->gpio_chip); | ||
| 147 | } | ||
| 148 | |||
| 149 | static int __devexit rc5t583_gpio_remove(struct platform_device *pdev) | ||
| 150 | { | ||
| 151 | struct rc5t583_gpio *rc5t583_gpio = platform_get_drvdata(pdev); | ||
| 152 | |||
| 153 | return gpiochip_remove(&rc5t583_gpio->gpio_chip); | ||
| 154 | } | ||
| 155 | |||
| 156 | static struct platform_driver rc5t583_gpio_driver = { | ||
| 157 | .driver = { | ||
| 158 | .name = "rc5t583-gpio", | ||
| 159 | .owner = THIS_MODULE, | ||
| 160 | }, | ||
| 161 | .probe = rc5t583_gpio_probe, | ||
| 162 | .remove = __devexit_p(rc5t583_gpio_remove), | ||
| 163 | }; | ||
| 164 | |||
| 165 | static int __init rc5t583_gpio_init(void) | ||
| 166 | { | ||
| 167 | return platform_driver_register(&rc5t583_gpio_driver); | ||
| 168 | } | ||
| 169 | subsys_initcall(rc5t583_gpio_init); | ||
| 170 | |||
| 171 | static void __exit rc5t583_gpio_exit(void) | ||
| 172 | { | ||
| 173 | platform_driver_unregister(&rc5t583_gpio_driver); | ||
| 174 | } | ||
| 175 | module_exit(rc5t583_gpio_exit); | ||
| 176 | |||
| 177 | MODULE_AUTHOR("Laxman Dewangan <ldewangan@nvidia.com>"); | ||
| 178 | MODULE_DESCRIPTION("GPIO interface for RC5T583"); | ||
| 179 | MODULE_LICENSE("GPL v2"); | ||
| 180 | MODULE_ALIAS("platform:rc5t583-gpio"); | ||
diff --git a/drivers/gpio/gpio-samsung.c b/drivers/gpio/gpio-samsung.c index 19d6fc0229c3..7bb00448e13d 100644 --- a/drivers/gpio/gpio-samsung.c +++ b/drivers/gpio/gpio-samsung.c | |||
| @@ -452,12 +452,14 @@ static struct samsung_gpio_cfg s3c24xx_gpiocfg_banka = { | |||
| 452 | }; | 452 | }; |
| 453 | #endif | 453 | #endif |
| 454 | 454 | ||
| 455 | #if defined(CONFIG_ARCH_EXYNOS4) || defined(CONFIG_ARCH_EXYNOS5) | ||
| 455 | static struct samsung_gpio_cfg exynos_gpio_cfg = { | 456 | static struct samsung_gpio_cfg exynos_gpio_cfg = { |
| 456 | .set_pull = exynos_gpio_setpull, | 457 | .set_pull = exynos_gpio_setpull, |
| 457 | .get_pull = exynos_gpio_getpull, | 458 | .get_pull = exynos_gpio_getpull, |
| 458 | .set_config = samsung_gpio_setcfg_4bit, | 459 | .set_config = samsung_gpio_setcfg_4bit, |
| 459 | .get_config = samsung_gpio_getcfg_4bit, | 460 | .get_config = samsung_gpio_getcfg_4bit, |
| 460 | }; | 461 | }; |
| 462 | #endif | ||
| 461 | 463 | ||
| 462 | #if defined(CONFIG_CPU_S5P6440) || defined(CONFIG_CPU_S5P6450) | 464 | #if defined(CONFIG_CPU_S5P6440) || defined(CONFIG_CPU_S5P6450) |
| 463 | static struct samsung_gpio_cfg s5p64x0_gpio_cfg_rbank = { | 465 | static struct samsung_gpio_cfg s5p64x0_gpio_cfg_rbank = { |
| @@ -2123,8 +2125,8 @@ static struct samsung_gpio_chip s5pv210_gpios_4bit[] = { | |||
| 2123 | * uses the above macro and depends on the banks being listed in order here. | 2125 | * uses the above macro and depends on the banks being listed in order here. |
| 2124 | */ | 2126 | */ |
| 2125 | 2127 | ||
| 2126 | static struct samsung_gpio_chip exynos4_gpios_1[] = { | ||
| 2127 | #ifdef CONFIG_ARCH_EXYNOS4 | 2128 | #ifdef CONFIG_ARCH_EXYNOS4 |
| 2129 | static struct samsung_gpio_chip exynos4_gpios_1[] = { | ||
| 2128 | { | 2130 | { |
| 2129 | .chip = { | 2131 | .chip = { |
| 2130 | .base = EXYNOS4_GPA0(0), | 2132 | .base = EXYNOS4_GPA0(0), |
| @@ -2222,11 +2224,11 @@ static struct samsung_gpio_chip exynos4_gpios_1[] = { | |||
| 2222 | .label = "GPF3", | 2224 | .label = "GPF3", |
| 2223 | }, | 2225 | }, |
| 2224 | }, | 2226 | }, |
| 2225 | #endif | ||
| 2226 | }; | 2227 | }; |
| 2228 | #endif | ||
| 2227 | 2229 | ||
| 2228 | static struct samsung_gpio_chip exynos4_gpios_2[] = { | ||
| 2229 | #ifdef CONFIG_ARCH_EXYNOS4 | 2230 | #ifdef CONFIG_ARCH_EXYNOS4 |
| 2231 | static struct samsung_gpio_chip exynos4_gpios_2[] = { | ||
| 2230 | { | 2232 | { |
| 2231 | .chip = { | 2233 | .chip = { |
| 2232 | .base = EXYNOS4_GPJ0(0), | 2234 | .base = EXYNOS4_GPJ0(0), |
| @@ -2367,11 +2369,11 @@ static struct samsung_gpio_chip exynos4_gpios_2[] = { | |||
| 2367 | .to_irq = samsung_gpiolib_to_irq, | 2369 | .to_irq = samsung_gpiolib_to_irq, |
| 2368 | }, | 2370 | }, |
| 2369 | }, | 2371 | }, |
| 2370 | #endif | ||
| 2371 | }; | 2372 | }; |
| 2373 | #endif | ||
| 2372 | 2374 | ||
| 2373 | static struct samsung_gpio_chip exynos4_gpios_3[] = { | ||
| 2374 | #ifdef CONFIG_ARCH_EXYNOS4 | 2375 | #ifdef CONFIG_ARCH_EXYNOS4 |
| 2376 | static struct samsung_gpio_chip exynos4_gpios_3[] = { | ||
| 2375 | { | 2377 | { |
| 2376 | .chip = { | 2378 | .chip = { |
| 2377 | .base = EXYNOS4_GPZ(0), | 2379 | .base = EXYNOS4_GPZ(0), |
| @@ -2379,8 +2381,8 @@ static struct samsung_gpio_chip exynos4_gpios_3[] = { | |||
| 2379 | .label = "GPZ", | 2381 | .label = "GPZ", |
| 2380 | }, | 2382 | }, |
| 2381 | }, | 2383 | }, |
| 2382 | #endif | ||
| 2383 | }; | 2384 | }; |
| 2385 | #endif | ||
| 2384 | 2386 | ||
| 2385 | #ifdef CONFIG_ARCH_EXYNOS5 | 2387 | #ifdef CONFIG_ARCH_EXYNOS5 |
| 2386 | static struct samsung_gpio_chip exynos5_gpios_1[] = { | 2388 | static struct samsung_gpio_chip exynos5_gpios_1[] = { |
| @@ -2452,6 +2454,12 @@ static struct samsung_gpio_chip exynos5_gpios_1[] = { | |||
| 2452 | }, | 2454 | }, |
| 2453 | }, { | 2455 | }, { |
| 2454 | .chip = { | 2456 | .chip = { |
| 2457 | .base = EXYNOS5_GPC4(0), | ||
| 2458 | .ngpio = EXYNOS5_GPIO_C4_NR, | ||
| 2459 | .label = "GPC4", | ||
| 2460 | }, | ||
| 2461 | }, { | ||
| 2462 | .chip = { | ||
| 2455 | .base = EXYNOS5_GPD0(0), | 2463 | .base = EXYNOS5_GPD0(0), |
| 2456 | .ngpio = EXYNOS5_GPIO_D0_NR, | 2464 | .ngpio = EXYNOS5_GPIO_D0_NR, |
| 2457 | .label = "GPD0", | 2465 | .label = "GPD0", |
| @@ -2714,12 +2722,227 @@ static __init void exynos_gpiolib_attach_ofnode(struct samsung_gpio_chip *chip, | |||
| 2714 | } | 2722 | } |
| 2715 | #endif /* defined(CONFIG_ARCH_EXYNOS) && defined(CONFIG_OF) */ | 2723 | #endif /* defined(CONFIG_ARCH_EXYNOS) && defined(CONFIG_OF) */ |
| 2716 | 2724 | ||
| 2725 | static __init void exynos4_gpiolib_init(void) | ||
| 2726 | { | ||
| 2727 | #ifdef CONFIG_CPU_EXYNOS4210 | ||
| 2728 | struct samsung_gpio_chip *chip; | ||
| 2729 | int i, nr_chips; | ||
| 2730 | void __iomem *gpio_base1, *gpio_base2, *gpio_base3; | ||
| 2731 | int group = 0; | ||
| 2732 | void __iomem *gpx_base; | ||
| 2733 | |||
| 2734 | /* gpio part1 */ | ||
| 2735 | gpio_base1 = ioremap(EXYNOS4_PA_GPIO1, SZ_4K); | ||
| 2736 | if (gpio_base1 == NULL) { | ||
| 2737 | pr_err("unable to ioremap for gpio_base1\n"); | ||
| 2738 | goto err_ioremap1; | ||
| 2739 | } | ||
| 2740 | |||
| 2741 | chip = exynos4_gpios_1; | ||
| 2742 | nr_chips = ARRAY_SIZE(exynos4_gpios_1); | ||
| 2743 | |||
| 2744 | for (i = 0; i < nr_chips; i++, chip++) { | ||
| 2745 | if (!chip->config) { | ||
| 2746 | chip->config = &exynos_gpio_cfg; | ||
| 2747 | chip->group = group++; | ||
| 2748 | } | ||
| 2749 | exynos_gpiolib_attach_ofnode(chip, | ||
| 2750 | EXYNOS4_PA_GPIO1, i * 0x20); | ||
| 2751 | } | ||
| 2752 | samsung_gpiolib_add_4bit_chips(exynos4_gpios_1, | ||
| 2753 | nr_chips, gpio_base1); | ||
| 2754 | |||
| 2755 | /* gpio part2 */ | ||
| 2756 | gpio_base2 = ioremap(EXYNOS4_PA_GPIO2, SZ_4K); | ||
| 2757 | if (gpio_base2 == NULL) { | ||
| 2758 | pr_err("unable to ioremap for gpio_base2\n"); | ||
| 2759 | goto err_ioremap2; | ||
| 2760 | } | ||
| 2761 | |||
| 2762 | /* need to set base address for gpx */ | ||
| 2763 | chip = &exynos4_gpios_2[16]; | ||
| 2764 | gpx_base = gpio_base2 + 0xC00; | ||
| 2765 | for (i = 0; i < 4; i++, chip++, gpx_base += 0x20) | ||
| 2766 | chip->base = gpx_base; | ||
| 2767 | |||
| 2768 | chip = exynos4_gpios_2; | ||
| 2769 | nr_chips = ARRAY_SIZE(exynos4_gpios_2); | ||
| 2770 | |||
| 2771 | for (i = 0; i < nr_chips; i++, chip++) { | ||
| 2772 | if (!chip->config) { | ||
| 2773 | chip->config = &exynos_gpio_cfg; | ||
| 2774 | chip->group = group++; | ||
| 2775 | } | ||
| 2776 | exynos_gpiolib_attach_ofnode(chip, | ||
| 2777 | EXYNOS4_PA_GPIO2, i * 0x20); | ||
| 2778 | } | ||
| 2779 | samsung_gpiolib_add_4bit_chips(exynos4_gpios_2, | ||
| 2780 | nr_chips, gpio_base2); | ||
| 2781 | |||
| 2782 | /* gpio part3 */ | ||
| 2783 | gpio_base3 = ioremap(EXYNOS4_PA_GPIO3, SZ_256); | ||
| 2784 | if (gpio_base3 == NULL) { | ||
| 2785 | pr_err("unable to ioremap for gpio_base3\n"); | ||
| 2786 | goto err_ioremap3; | ||
| 2787 | } | ||
| 2788 | |||
| 2789 | chip = exynos4_gpios_3; | ||
| 2790 | nr_chips = ARRAY_SIZE(exynos4_gpios_3); | ||
| 2791 | |||
| 2792 | for (i = 0; i < nr_chips; i++, chip++) { | ||
| 2793 | if (!chip->config) { | ||
| 2794 | chip->config = &exynos_gpio_cfg; | ||
| 2795 | chip->group = group++; | ||
| 2796 | } | ||
| 2797 | exynos_gpiolib_attach_ofnode(chip, | ||
| 2798 | EXYNOS4_PA_GPIO3, i * 0x20); | ||
| 2799 | } | ||
| 2800 | samsung_gpiolib_add_4bit_chips(exynos4_gpios_3, | ||
| 2801 | nr_chips, gpio_base3); | ||
| 2802 | |||
| 2803 | #if defined(CONFIG_CPU_EXYNOS4210) && defined(CONFIG_S5P_GPIO_INT) | ||
| 2804 | s5p_register_gpioint_bank(IRQ_GPIO_XA, 0, IRQ_GPIO1_NR_GROUPS); | ||
| 2805 | s5p_register_gpioint_bank(IRQ_GPIO_XB, IRQ_GPIO1_NR_GROUPS, IRQ_GPIO2_NR_GROUPS); | ||
| 2806 | #endif | ||
| 2807 | |||
| 2808 | return; | ||
| 2809 | |||
| 2810 | err_ioremap3: | ||
| 2811 | iounmap(gpio_base2); | ||
| 2812 | err_ioremap2: | ||
| 2813 | iounmap(gpio_base1); | ||
| 2814 | err_ioremap1: | ||
| 2815 | return; | ||
| 2816 | #endif /* CONFIG_CPU_EXYNOS4210 */ | ||
| 2817 | } | ||
| 2818 | |||
| 2819 | static __init void exynos5_gpiolib_init(void) | ||
| 2820 | { | ||
| 2821 | #ifdef CONFIG_SOC_EXYNOS5250 | ||
| 2822 | struct samsung_gpio_chip *chip; | ||
| 2823 | int i, nr_chips; | ||
| 2824 | void __iomem *gpio_base1, *gpio_base2, *gpio_base3, *gpio_base4; | ||
| 2825 | int group = 0; | ||
| 2826 | void __iomem *gpx_base; | ||
| 2827 | |||
| 2828 | /* gpio part1 */ | ||
| 2829 | gpio_base1 = ioremap(EXYNOS5_PA_GPIO1, SZ_4K); | ||
| 2830 | if (gpio_base1 == NULL) { | ||
| 2831 | pr_err("unable to ioremap for gpio_base1\n"); | ||
| 2832 | goto err_ioremap1; | ||
| 2833 | } | ||
| 2834 | |||
| 2835 | /* need to set base address for gpc4 */ | ||
| 2836 | exonys5_gpios_1[11].base = gpio_base1 + 0x2E0; | ||
| 2837 | |||
| 2838 | /* need to set base address for gpx */ | ||
| 2839 | chip = &exynos5_gpios_1[21]; | ||
| 2840 | gpx_base = gpio_base1 + 0xC00; | ||
| 2841 | for (i = 0; i < 4; i++, chip++, gpx_base += 0x20) | ||
| 2842 | chip->base = gpx_base; | ||
| 2843 | |||
| 2844 | chip = exynos5_gpios_1; | ||
| 2845 | nr_chips = ARRAY_SIZE(exynos5_gpios_1); | ||
| 2846 | |||
| 2847 | for (i = 0; i < nr_chips; i++, chip++) { | ||
| 2848 | if (!chip->config) { | ||
| 2849 | chip->config = &exynos_gpio_cfg; | ||
| 2850 | chip->group = group++; | ||
| 2851 | } | ||
| 2852 | exynos_gpiolib_attach_ofnode(chip, | ||
| 2853 | EXYNOS5_PA_GPIO1, i * 0x20); | ||
| 2854 | } | ||
| 2855 | samsung_gpiolib_add_4bit_chips(exynos5_gpios_1, | ||
| 2856 | nr_chips, gpio_base1); | ||
| 2857 | |||
| 2858 | /* gpio part2 */ | ||
| 2859 | gpio_base2 = ioremap(EXYNOS5_PA_GPIO2, SZ_4K); | ||
| 2860 | if (gpio_base2 == NULL) { | ||
| 2861 | pr_err("unable to ioremap for gpio_base2\n"); | ||
| 2862 | goto err_ioremap2; | ||
| 2863 | } | ||
| 2864 | |||
| 2865 | chip = exynos5_gpios_2; | ||
| 2866 | nr_chips = ARRAY_SIZE(exynos5_gpios_2); | ||
| 2867 | |||
| 2868 | for (i = 0; i < nr_chips; i++, chip++) { | ||
| 2869 | if (!chip->config) { | ||
| 2870 | chip->config = &exynos_gpio_cfg; | ||
| 2871 | chip->group = group++; | ||
| 2872 | } | ||
| 2873 | exynos_gpiolib_attach_ofnode(chip, | ||
| 2874 | EXYNOS5_PA_GPIO2, i * 0x20); | ||
| 2875 | } | ||
| 2876 | samsung_gpiolib_add_4bit_chips(exynos5_gpios_2, | ||
| 2877 | nr_chips, gpio_base2); | ||
| 2878 | |||
| 2879 | /* gpio part3 */ | ||
| 2880 | gpio_base3 = ioremap(EXYNOS5_PA_GPIO3, SZ_4K); | ||
| 2881 | if (gpio_base3 == NULL) { | ||
| 2882 | pr_err("unable to ioremap for gpio_base3\n"); | ||
| 2883 | goto err_ioremap3; | ||
| 2884 | } | ||
| 2885 | |||
| 2886 | /* need to set base address for gpv */ | ||
| 2887 | exynos5_gpios_3[0].base = gpio_base3; | ||
| 2888 | exynos5_gpios_3[1].base = gpio_base3 + 0x20; | ||
| 2889 | exynos5_gpios_3[2].base = gpio_base3 + 0x60; | ||
| 2890 | exynos5_gpios_3[3].base = gpio_base3 + 0x80; | ||
| 2891 | exynos5_gpios_3[4].base = gpio_base3 + 0xC0; | ||
| 2892 | |||
| 2893 | chip = exynos5_gpios_3; | ||
| 2894 | nr_chips = ARRAY_SIZE(exynos5_gpios_3); | ||
| 2895 | |||
| 2896 | for (i = 0; i < nr_chips; i++, chip++) { | ||
| 2897 | if (!chip->config) { | ||
| 2898 | chip->config = &exynos_gpio_cfg; | ||
| 2899 | chip->group = group++; | ||
| 2900 | } | ||
| 2901 | exynos_gpiolib_attach_ofnode(chip, | ||
| 2902 | EXYNOS5_PA_GPIO3, i * 0x20); | ||
| 2903 | } | ||
| 2904 | samsung_gpiolib_add_4bit_chips(exynos5_gpios_3, | ||
| 2905 | nr_chips, gpio_base3); | ||
| 2906 | |||
| 2907 | /* gpio part4 */ | ||
| 2908 | gpio_base4 = ioremap(EXYNOS5_PA_GPIO4, SZ_4K); | ||
| 2909 | if (gpio_base4 == NULL) { | ||
| 2910 | pr_err("unable to ioremap for gpio_base4\n"); | ||
| 2911 | goto err_ioremap4; | ||
| 2912 | } | ||
| 2913 | |||
| 2914 | chip = exynos5_gpios_4; | ||
| 2915 | nr_chips = ARRAY_SIZE(exynos5_gpios_4); | ||
| 2916 | |||
| 2917 | for (i = 0; i < nr_chips; i++, chip++) { | ||
| 2918 | if (!chip->config) { | ||
| 2919 | chip->config = &exynos_gpio_cfg; | ||
| 2920 | chip->group = group++; | ||
| 2921 | } | ||
| 2922 | exynos_gpiolib_attach_ofnode(chip, | ||
| 2923 | EXYNOS5_PA_GPIO4, i * 0x20); | ||
| 2924 | } | ||
| 2925 | samsung_gpiolib_add_4bit_chips(exynos5_gpios_4, | ||
| 2926 | nr_chips, gpio_base4); | ||
| 2927 | return; | ||
| 2928 | |||
| 2929 | err_ioremap4: | ||
| 2930 | iounmap(gpio_base3); | ||
| 2931 | err_ioremap3: | ||
| 2932 | iounmap(gpio_base2); | ||
| 2933 | err_ioremap2: | ||
| 2934 | iounmap(gpio_base1); | ||
| 2935 | err_ioremap1: | ||
| 2936 | return; | ||
| 2937 | |||
| 2938 | #endif /* CONFIG_SOC_EXYNOS5250 */ | ||
| 2939 | } | ||
| 2940 | |||
| 2717 | /* TODO: cleanup soc_is_* */ | 2941 | /* TODO: cleanup soc_is_* */ |
| 2718 | static __init int samsung_gpiolib_init(void) | 2942 | static __init int samsung_gpiolib_init(void) |
| 2719 | { | 2943 | { |
| 2720 | struct samsung_gpio_chip *chip; | 2944 | struct samsung_gpio_chip *chip; |
| 2721 | int i, nr_chips; | 2945 | int i, nr_chips; |
| 2722 | void __iomem *gpio_base1, *gpio_base2, *gpio_base3, *gpio_base4; | ||
| 2723 | int group = 0; | 2946 | int group = 0; |
| 2724 | 2947 | ||
| 2725 | samsung_gpiolib_set_cfg(samsung_gpio_cfgs, ARRAY_SIZE(samsung_gpio_cfgs)); | 2948 | samsung_gpiolib_set_cfg(samsung_gpio_cfgs, ARRAY_SIZE(samsung_gpio_cfgs)); |
| @@ -2785,200 +3008,15 @@ static __init int samsung_gpiolib_init(void) | |||
| 2785 | s5p_register_gpioint_bank(IRQ_GPIOINT, 0, S5P_GPIOINT_GROUP_MAXNR); | 3008 | s5p_register_gpioint_bank(IRQ_GPIOINT, 0, S5P_GPIOINT_GROUP_MAXNR); |
| 2786 | #endif | 3009 | #endif |
| 2787 | } else if (soc_is_exynos4210()) { | 3010 | } else if (soc_is_exynos4210()) { |
| 2788 | #ifdef CONFIG_CPU_EXYNOS4210 | 3011 | exynos4_gpiolib_init(); |
| 2789 | void __iomem *gpx_base; | ||
| 2790 | |||
| 2791 | /* gpio part1 */ | ||
| 2792 | gpio_base1 = ioremap(EXYNOS4_PA_GPIO1, SZ_4K); | ||
| 2793 | if (gpio_base1 == NULL) { | ||
| 2794 | pr_err("unable to ioremap for gpio_base1\n"); | ||
| 2795 | goto err_ioremap1; | ||
| 2796 | } | ||
| 2797 | |||
| 2798 | chip = exynos4_gpios_1; | ||
| 2799 | nr_chips = ARRAY_SIZE(exynos4_gpios_1); | ||
| 2800 | |||
| 2801 | for (i = 0; i < nr_chips; i++, chip++) { | ||
| 2802 | if (!chip->config) { | ||
| 2803 | chip->config = &exynos_gpio_cfg; | ||
| 2804 | chip->group = group++; | ||
| 2805 | } | ||
| 2806 | exynos_gpiolib_attach_ofnode(chip, | ||
| 2807 | EXYNOS4_PA_GPIO1, i * 0x20); | ||
| 2808 | } | ||
| 2809 | samsung_gpiolib_add_4bit_chips(exynos4_gpios_1, | ||
| 2810 | nr_chips, gpio_base1); | ||
| 2811 | |||
| 2812 | /* gpio part2 */ | ||
| 2813 | gpio_base2 = ioremap(EXYNOS4_PA_GPIO2, SZ_4K); | ||
| 2814 | if (gpio_base2 == NULL) { | ||
| 2815 | pr_err("unable to ioremap for gpio_base2\n"); | ||
| 2816 | goto err_ioremap2; | ||
| 2817 | } | ||
| 2818 | |||
| 2819 | /* need to set base address for gpx */ | ||
| 2820 | chip = &exynos4_gpios_2[16]; | ||
| 2821 | gpx_base = gpio_base2 + 0xC00; | ||
| 2822 | for (i = 0; i < 4; i++, chip++, gpx_base += 0x20) | ||
| 2823 | chip->base = gpx_base; | ||
| 2824 | |||
| 2825 | chip = exynos4_gpios_2; | ||
| 2826 | nr_chips = ARRAY_SIZE(exynos4_gpios_2); | ||
| 2827 | |||
| 2828 | for (i = 0; i < nr_chips; i++, chip++) { | ||
| 2829 | if (!chip->config) { | ||
| 2830 | chip->config = &exynos_gpio_cfg; | ||
| 2831 | chip->group = group++; | ||
| 2832 | } | ||
| 2833 | exynos_gpiolib_attach_ofnode(chip, | ||
| 2834 | EXYNOS4_PA_GPIO2, i * 0x20); | ||
| 2835 | } | ||
| 2836 | samsung_gpiolib_add_4bit_chips(exynos4_gpios_2, | ||
| 2837 | nr_chips, gpio_base2); | ||
| 2838 | |||
| 2839 | /* gpio part3 */ | ||
| 2840 | gpio_base3 = ioremap(EXYNOS4_PA_GPIO3, SZ_256); | ||
| 2841 | if (gpio_base3 == NULL) { | ||
| 2842 | pr_err("unable to ioremap for gpio_base3\n"); | ||
| 2843 | goto err_ioremap3; | ||
| 2844 | } | ||
| 2845 | |||
| 2846 | chip = exynos4_gpios_3; | ||
| 2847 | nr_chips = ARRAY_SIZE(exynos4_gpios_3); | ||
| 2848 | |||
| 2849 | for (i = 0; i < nr_chips; i++, chip++) { | ||
| 2850 | if (!chip->config) { | ||
| 2851 | chip->config = &exynos_gpio_cfg; | ||
| 2852 | chip->group = group++; | ||
| 2853 | } | ||
| 2854 | exynos_gpiolib_attach_ofnode(chip, | ||
| 2855 | EXYNOS4_PA_GPIO3, i * 0x20); | ||
| 2856 | } | ||
| 2857 | samsung_gpiolib_add_4bit_chips(exynos4_gpios_3, | ||
| 2858 | nr_chips, gpio_base3); | ||
| 2859 | |||
| 2860 | #if defined(CONFIG_CPU_EXYNOS4210) && defined(CONFIG_S5P_GPIO_INT) | ||
| 2861 | s5p_register_gpioint_bank(IRQ_GPIO_XA, 0, IRQ_GPIO1_NR_GROUPS); | ||
| 2862 | s5p_register_gpioint_bank(IRQ_GPIO_XB, IRQ_GPIO1_NR_GROUPS, IRQ_GPIO2_NR_GROUPS); | ||
| 2863 | #endif | ||
| 2864 | |||
| 2865 | #endif /* CONFIG_CPU_EXYNOS4210 */ | ||
| 2866 | } else if (soc_is_exynos5250()) { | 3012 | } else if (soc_is_exynos5250()) { |
| 2867 | #ifdef CONFIG_SOC_EXYNOS5250 | 3013 | exynos5_gpiolib_init(); |
| 2868 | void __iomem *gpx_base; | ||
| 2869 | |||
| 2870 | /* gpio part1 */ | ||
| 2871 | gpio_base1 = ioremap(EXYNOS5_PA_GPIO1, SZ_4K); | ||
| 2872 | if (gpio_base1 == NULL) { | ||
| 2873 | pr_err("unable to ioremap for gpio_base1\n"); | ||
| 2874 | goto err_ioremap1; | ||
| 2875 | } | ||
| 2876 | |||
| 2877 | /* need to set base address for gpx */ | ||
| 2878 | chip = &exynos5_gpios_1[20]; | ||
| 2879 | gpx_base = gpio_base1 + 0xC00; | ||
| 2880 | for (i = 0; i < 4; i++, chip++, gpx_base += 0x20) | ||
| 2881 | chip->base = gpx_base; | ||
| 2882 | |||
| 2883 | chip = exynos5_gpios_1; | ||
| 2884 | nr_chips = ARRAY_SIZE(exynos5_gpios_1); | ||
| 2885 | |||
| 2886 | for (i = 0; i < nr_chips; i++, chip++) { | ||
| 2887 | if (!chip->config) { | ||
| 2888 | chip->config = &exynos_gpio_cfg; | ||
| 2889 | chip->group = group++; | ||
| 2890 | } | ||
| 2891 | exynos_gpiolib_attach_ofnode(chip, | ||
| 2892 | EXYNOS5_PA_GPIO1, i * 0x20); | ||
| 2893 | } | ||
| 2894 | samsung_gpiolib_add_4bit_chips(exynos5_gpios_1, | ||
| 2895 | nr_chips, gpio_base1); | ||
| 2896 | |||
| 2897 | /* gpio part2 */ | ||
| 2898 | gpio_base2 = ioremap(EXYNOS5_PA_GPIO2, SZ_4K); | ||
| 2899 | if (gpio_base2 == NULL) { | ||
| 2900 | pr_err("unable to ioremap for gpio_base2\n"); | ||
| 2901 | goto err_ioremap2; | ||
| 2902 | } | ||
| 2903 | |||
| 2904 | chip = exynos5_gpios_2; | ||
| 2905 | nr_chips = ARRAY_SIZE(exynos5_gpios_2); | ||
| 2906 | |||
| 2907 | for (i = 0; i < nr_chips; i++, chip++) { | ||
| 2908 | if (!chip->config) { | ||
| 2909 | chip->config = &exynos_gpio_cfg; | ||
| 2910 | chip->group = group++; | ||
| 2911 | } | ||
| 2912 | exynos_gpiolib_attach_ofnode(chip, | ||
| 2913 | EXYNOS5_PA_GPIO2, i * 0x20); | ||
| 2914 | } | ||
| 2915 | samsung_gpiolib_add_4bit_chips(exynos5_gpios_2, | ||
| 2916 | nr_chips, gpio_base2); | ||
| 2917 | |||
| 2918 | /* gpio part3 */ | ||
| 2919 | gpio_base3 = ioremap(EXYNOS5_PA_GPIO3, SZ_4K); | ||
| 2920 | if (gpio_base3 == NULL) { | ||
| 2921 | pr_err("unable to ioremap for gpio_base3\n"); | ||
| 2922 | goto err_ioremap3; | ||
| 2923 | } | ||
| 2924 | |||
| 2925 | /* need to set base address for gpv */ | ||
| 2926 | exynos5_gpios_3[0].base = gpio_base3; | ||
| 2927 | exynos5_gpios_3[1].base = gpio_base3 + 0x20; | ||
| 2928 | exynos5_gpios_3[2].base = gpio_base3 + 0x60; | ||
| 2929 | exynos5_gpios_3[3].base = gpio_base3 + 0x80; | ||
| 2930 | exynos5_gpios_3[4].base = gpio_base3 + 0xC0; | ||
| 2931 | |||
| 2932 | chip = exynos5_gpios_3; | ||
| 2933 | nr_chips = ARRAY_SIZE(exynos5_gpios_3); | ||
| 2934 | |||
| 2935 | for (i = 0; i < nr_chips; i++, chip++) { | ||
| 2936 | if (!chip->config) { | ||
| 2937 | chip->config = &exynos_gpio_cfg; | ||
| 2938 | chip->group = group++; | ||
| 2939 | } | ||
| 2940 | exynos_gpiolib_attach_ofnode(chip, | ||
| 2941 | EXYNOS5_PA_GPIO3, i * 0x20); | ||
| 2942 | } | ||
| 2943 | samsung_gpiolib_add_4bit_chips(exynos5_gpios_3, | ||
| 2944 | nr_chips, gpio_base3); | ||
| 2945 | |||
| 2946 | /* gpio part4 */ | ||
| 2947 | gpio_base4 = ioremap(EXYNOS5_PA_GPIO4, SZ_4K); | ||
| 2948 | if (gpio_base4 == NULL) { | ||
| 2949 | pr_err("unable to ioremap for gpio_base4\n"); | ||
| 2950 | goto err_ioremap4; | ||
| 2951 | } | ||
| 2952 | |||
| 2953 | chip = exynos5_gpios_4; | ||
| 2954 | nr_chips = ARRAY_SIZE(exynos5_gpios_4); | ||
| 2955 | |||
| 2956 | for (i = 0; i < nr_chips; i++, chip++) { | ||
| 2957 | if (!chip->config) { | ||
| 2958 | chip->config = &exynos_gpio_cfg; | ||
| 2959 | chip->group = group++; | ||
| 2960 | } | ||
| 2961 | exynos_gpiolib_attach_ofnode(chip, | ||
| 2962 | EXYNOS5_PA_GPIO4, i * 0x20); | ||
| 2963 | } | ||
| 2964 | samsung_gpiolib_add_4bit_chips(exynos5_gpios_4, | ||
| 2965 | nr_chips, gpio_base4); | ||
| 2966 | #endif /* CONFIG_SOC_EXYNOS5250 */ | ||
| 2967 | } else { | 3014 | } else { |
| 2968 | WARN(1, "Unknown SoC in gpio-samsung, no GPIOs added\n"); | 3015 | WARN(1, "Unknown SoC in gpio-samsung, no GPIOs added\n"); |
| 2969 | return -ENODEV; | 3016 | return -ENODEV; |
| 2970 | } | 3017 | } |
| 2971 | 3018 | ||
| 2972 | return 0; | 3019 | return 0; |
| 2973 | |||
| 2974 | err_ioremap4: | ||
| 2975 | iounmap(gpio_base3); | ||
| 2976 | err_ioremap3: | ||
| 2977 | iounmap(gpio_base2); | ||
| 2978 | err_ioremap2: | ||
| 2979 | iounmap(gpio_base1); | ||
| 2980 | err_ioremap1: | ||
| 2981 | return -ENOMEM; | ||
| 2982 | } | 3020 | } |
| 2983 | core_initcall(samsung_gpiolib_init); | 3021 | core_initcall(samsung_gpiolib_init); |
| 2984 | 3022 | ||
diff --git a/drivers/gpio/gpio-sch.c b/drivers/gpio/gpio-sch.c index 8cadf4d683a8..424dce8e3f30 100644 --- a/drivers/gpio/gpio-sch.c +++ b/drivers/gpio/gpio-sch.c | |||
| @@ -232,6 +232,14 @@ static int __devinit sch_gpio_probe(struct platform_device *pdev) | |||
| 232 | sch_gpio_resume.ngpio = 9; | 232 | sch_gpio_resume.ngpio = 9; |
| 233 | break; | 233 | break; |
| 234 | 234 | ||
| 235 | case PCI_DEVICE_ID_INTEL_CENTERTON_ILB: | ||
| 236 | sch_gpio_core.base = 0; | ||
| 237 | sch_gpio_core.ngpio = 21; | ||
| 238 | |||
| 239 | sch_gpio_resume.base = 21; | ||
| 240 | sch_gpio_resume.ngpio = 9; | ||
| 241 | break; | ||
| 242 | |||
| 235 | default: | 243 | default: |
| 236 | return -ENODEV; | 244 | return -ENODEV; |
| 237 | } | 245 | } |
diff --git a/drivers/gpio/gpio-sodaville.c b/drivers/gpio/gpio-sodaville.c index 031e5d24837d..9d9891f7a607 100644 --- a/drivers/gpio/gpio-sodaville.c +++ b/drivers/gpio/gpio-sodaville.c | |||
| @@ -224,7 +224,7 @@ static int __devinit sdv_gpio_probe(struct pci_dev *pdev, | |||
| 224 | 224 | ||
| 225 | ret = bgpio_init(&sd->bgpio, &pdev->dev, 4, | 225 | ret = bgpio_init(&sd->bgpio, &pdev->dev, 4, |
| 226 | sd->gpio_pub_base + GPINR, sd->gpio_pub_base + GPOUTR, | 226 | sd->gpio_pub_base + GPINR, sd->gpio_pub_base + GPOUTR, |
| 227 | NULL, sd->gpio_pub_base + GPOER, NULL, false); | 227 | NULL, sd->gpio_pub_base + GPOER, NULL, 0); |
| 228 | if (ret) | 228 | if (ret) |
| 229 | goto unmap; | 229 | goto unmap; |
| 230 | sd->bgpio.gc.ngpio = SDV_NUM_PUB_GPIOS; | 230 | sd->bgpio.gc.ngpio = SDV_NUM_PUB_GPIOS; |
| @@ -282,17 +282,7 @@ static struct pci_driver sdv_gpio_driver = { | |||
| 282 | .remove = sdv_gpio_remove, | 282 | .remove = sdv_gpio_remove, |
| 283 | }; | 283 | }; |
| 284 | 284 | ||
| 285 | static int __init sdv_gpio_init(void) | 285 | module_pci_driver(sdv_gpio_driver); |
| 286 | { | ||
| 287 | return pci_register_driver(&sdv_gpio_driver); | ||
| 288 | } | ||
| 289 | module_init(sdv_gpio_init); | ||
| 290 | |||
| 291 | static void __exit sdv_gpio_exit(void) | ||
| 292 | { | ||
| 293 | pci_unregister_driver(&sdv_gpio_driver); | ||
| 294 | } | ||
| 295 | module_exit(sdv_gpio_exit); | ||
| 296 | 286 | ||
| 297 | MODULE_AUTHOR("Hans J. Koch <hjk@linutronix.de>"); | 287 | MODULE_AUTHOR("Hans J. Koch <hjk@linutronix.de>"); |
| 298 | MODULE_DESCRIPTION("GPIO interface for Intel Sodaville SoCs"); | 288 | MODULE_DESCRIPTION("GPIO interface for Intel Sodaville SoCs"); |
diff --git a/drivers/gpio/gpio-sta2x11.c b/drivers/gpio/gpio-sta2x11.c new file mode 100644 index 000000000000..38416be8ba11 --- /dev/null +++ b/drivers/gpio/gpio-sta2x11.c | |||
| @@ -0,0 +1,435 @@ | |||
| 1 | /* | ||
| 2 | * STMicroelectronics ConneXt (STA2X11) GPIO driver | ||
| 3 | * | ||
| 4 | * Copyright 2012 ST Microelectronics (Alessandro Rubini) | ||
| 5 | * Based on gpio-ml-ioh.c, Copyright 2010 OKI Semiconductors Ltd. | ||
| 6 | * Also based on previous sta2x11 work, Copyright 2011 Wind River Systems, Inc. | ||
| 7 | * | ||
| 8 | * This program is free software; you can redistribute it and/or modify | ||
| 9 | * it under the terms of the GNU General Public License version 2 as | ||
| 10 | * published by the Free Software Foundation. | ||
| 11 | * | ||
| 12 | * This program is distributed in the hope that it will be useful, | ||
| 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | ||
| 15 | * See the GNU General Public License for more details. | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU General Public License | ||
| 18 | * along with this program; if not, write to the Free Software | ||
| 19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
| 20 | * | ||
| 21 | */ | ||
| 22 | |||
| 23 | #include <linux/module.h> | ||
| 24 | #include <linux/kernel.h> | ||
| 25 | #include <linux/slab.h> | ||
| 26 | #include <linux/gpio.h> | ||
| 27 | #include <linux/interrupt.h> | ||
| 28 | #include <linux/irq.h> | ||
| 29 | #include <linux/pci.h> | ||
| 30 | #include <linux/platform_device.h> | ||
| 31 | #include <linux/mfd/sta2x11-mfd.h> | ||
| 32 | |||
| 33 | struct gsta_regs { | ||
| 34 | u32 dat; /* 0x00 */ | ||
| 35 | u32 dats; | ||
| 36 | u32 datc; | ||
| 37 | u32 pdis; | ||
| 38 | u32 dir; /* 0x10 */ | ||
| 39 | u32 dirs; | ||
| 40 | u32 dirc; | ||
| 41 | u32 unused_1c; | ||
| 42 | u32 afsela; /* 0x20 */ | ||
| 43 | u32 unused_24[7]; | ||
| 44 | u32 rimsc; /* 0x40 */ | ||
| 45 | u32 fimsc; | ||
| 46 | u32 is; | ||
| 47 | u32 ic; | ||
| 48 | }; | ||
| 49 | |||
| 50 | struct gsta_gpio { | ||
| 51 | spinlock_t lock; | ||
| 52 | struct device *dev; | ||
| 53 | void __iomem *reg_base; | ||
| 54 | struct gsta_regs __iomem *regs[GSTA_NR_BLOCKS]; | ||
| 55 | struct gpio_chip gpio; | ||
| 56 | int irq_base; | ||
| 57 | /* FIXME: save the whole config here (AF, ...) */ | ||
| 58 | unsigned irq_type[GSTA_NR_GPIO]; | ||
| 59 | }; | ||
| 60 | |||
| 61 | static inline struct gsta_regs __iomem *__regs(struct gsta_gpio *chip, int nr) | ||
| 62 | { | ||
| 63 | return chip->regs[nr / GSTA_GPIO_PER_BLOCK]; | ||
| 64 | } | ||
| 65 | |||
| 66 | static inline u32 __bit(int nr) | ||
| 67 | { | ||
| 68 | return 1U << (nr % GSTA_GPIO_PER_BLOCK); | ||
| 69 | } | ||
| 70 | |||
| 71 | /* | ||
| 72 | * gpio methods | ||
| 73 | */ | ||
| 74 | |||
| 75 | static void gsta_gpio_set(struct gpio_chip *gpio, unsigned nr, int val) | ||
| 76 | { | ||
| 77 | struct gsta_gpio *chip = container_of(gpio, struct gsta_gpio, gpio); | ||
| 78 | struct gsta_regs __iomem *regs = __regs(chip, nr); | ||
| 79 | u32 bit = __bit(nr); | ||
| 80 | |||
| 81 | if (val) | ||
| 82 | writel(bit, ®s->dats); | ||
| 83 | else | ||
| 84 | writel(bit, ®s->datc); | ||
| 85 | } | ||
| 86 | |||
| 87 | static int gsta_gpio_get(struct gpio_chip *gpio, unsigned nr) | ||
| 88 | { | ||
| 89 | struct gsta_gpio *chip = container_of(gpio, struct gsta_gpio, gpio); | ||
| 90 | struct gsta_regs __iomem *regs = __regs(chip, nr); | ||
| 91 | u32 bit = __bit(nr); | ||
| 92 | |||
| 93 | return readl(®s->dat) & bit; | ||
| 94 | } | ||
| 95 | |||
| 96 | static int gsta_gpio_direction_output(struct gpio_chip *gpio, unsigned nr, | ||
| 97 | int val) | ||
| 98 | { | ||
| 99 | struct gsta_gpio *chip = container_of(gpio, struct gsta_gpio, gpio); | ||
| 100 | struct gsta_regs __iomem *regs = __regs(chip, nr); | ||
| 101 | u32 bit = __bit(nr); | ||
| 102 | |||
| 103 | writel(bit, ®s->dirs); | ||
| 104 | /* Data register after direction, otherwise pullup/down is selected */ | ||
| 105 | if (val) | ||
| 106 | writel(bit, ®s->dats); | ||
| 107 | else | ||
| 108 | writel(bit, ®s->datc); | ||
| 109 | return 0; | ||
| 110 | } | ||
| 111 | |||
| 112 | static int gsta_gpio_direction_input(struct gpio_chip *gpio, unsigned nr) | ||
| 113 | { | ||
| 114 | struct gsta_gpio *chip = container_of(gpio, struct gsta_gpio, gpio); | ||
| 115 | struct gsta_regs __iomem *regs = __regs(chip, nr); | ||
| 116 | u32 bit = __bit(nr); | ||
| 117 | |||
| 118 | writel(bit, ®s->dirc); | ||
| 119 | return 0; | ||
| 120 | } | ||
| 121 | |||
| 122 | static int gsta_gpio_to_irq(struct gpio_chip *gpio, unsigned offset) | ||
| 123 | { | ||
| 124 | struct gsta_gpio *chip = container_of(gpio, struct gsta_gpio, gpio); | ||
| 125 | return chip->irq_base + offset; | ||
| 126 | } | ||
| 127 | |||
| 128 | static void gsta_gpio_setup(struct gsta_gpio *chip) /* called from probe */ | ||
| 129 | { | ||
| 130 | struct gpio_chip *gpio = &chip->gpio; | ||
| 131 | |||
| 132 | /* | ||
| 133 | * ARCH_NR_GPIOS is currently 256 and dynamic allocation starts | ||
| 134 | * from the end. However, for compatibility, we need the first | ||
| 135 | * ConneXt device to start from gpio 0: it's the main chipset | ||
| 136 | * on most boards so documents and drivers assume gpio0..gpio127 | ||
| 137 | */ | ||
| 138 | static int gpio_base; | ||
| 139 | |||
| 140 | gpio->label = dev_name(chip->dev); | ||
| 141 | gpio->owner = THIS_MODULE; | ||
| 142 | gpio->direction_input = gsta_gpio_direction_input; | ||
| 143 | gpio->get = gsta_gpio_get; | ||
| 144 | gpio->direction_output = gsta_gpio_direction_output; | ||
| 145 | gpio->set = gsta_gpio_set; | ||
| 146 | gpio->dbg_show = NULL; | ||
| 147 | gpio->base = gpio_base; | ||
| 148 | gpio->ngpio = GSTA_NR_GPIO; | ||
| 149 | gpio->can_sleep = 0; | ||
| 150 | gpio->to_irq = gsta_gpio_to_irq; | ||
| 151 | |||
| 152 | /* | ||
| 153 | * After the first device, turn to dynamic gpio numbers. | ||
| 154 | * For example, with ARCH_NR_GPIOS = 256 we can fit two cards | ||
| 155 | */ | ||
| 156 | if (!gpio_base) | ||
| 157 | gpio_base = -1; | ||
| 158 | } | ||
| 159 | |||
| 160 | /* | ||
| 161 | * Special method: alternate functions and pullup/pulldown. This is only | ||
| 162 | * invoked on startup to configure gpio's according to platform data. | ||
| 163 | * FIXME : this functionality shall be managed (and exported to other drivers) | ||
| 164 | * via the pin control subsystem. | ||
| 165 | */ | ||
| 166 | static void gsta_set_config(struct gsta_gpio *chip, int nr, unsigned cfg) | ||
| 167 | { | ||
| 168 | struct gsta_regs __iomem *regs = __regs(chip, nr); | ||
| 169 | unsigned long flags; | ||
| 170 | u32 bit = __bit(nr); | ||
| 171 | u32 val; | ||
| 172 | int err = 0; | ||
| 173 | |||
| 174 | pr_info("%s: %p %i %i\n", __func__, chip, nr, cfg); | ||
| 175 | |||
| 176 | if (cfg == PINMUX_TYPE_NONE) | ||
| 177 | return; | ||
| 178 | |||
| 179 | /* Alternate function or not? */ | ||
| 180 | spin_lock_irqsave(&chip->lock, flags); | ||
| 181 | val = readl(®s->afsela); | ||
| 182 | if (cfg == PINMUX_TYPE_FUNCTION) | ||
| 183 | val |= bit; | ||
| 184 | else | ||
| 185 | val &= ~bit; | ||
| 186 | writel(val | bit, ®s->afsela); | ||
| 187 | if (cfg == PINMUX_TYPE_FUNCTION) { | ||
| 188 | spin_unlock_irqrestore(&chip->lock, flags); | ||
| 189 | return; | ||
| 190 | } | ||
| 191 | |||
| 192 | /* not alternate function: set details */ | ||
| 193 | switch (cfg) { | ||
| 194 | case PINMUX_TYPE_OUTPUT_LOW: | ||
| 195 | writel(bit, ®s->dirs); | ||
| 196 | writel(bit, ®s->datc); | ||
| 197 | break; | ||
| 198 | case PINMUX_TYPE_OUTPUT_HIGH: | ||
| 199 | writel(bit, ®s->dirs); | ||
| 200 | writel(bit, ®s->dats); | ||
| 201 | break; | ||
| 202 | case PINMUX_TYPE_INPUT: | ||
| 203 | writel(bit, ®s->dirc); | ||
| 204 | val = readl(®s->pdis) | bit; | ||
| 205 | writel(val, ®s->pdis); | ||
| 206 | break; | ||
| 207 | case PINMUX_TYPE_INPUT_PULLUP: | ||
| 208 | writel(bit, ®s->dirc); | ||
| 209 | val = readl(®s->pdis) & ~bit; | ||
| 210 | writel(val, ®s->pdis); | ||
| 211 | writel(bit, ®s->dats); | ||
| 212 | break; | ||
| 213 | case PINMUX_TYPE_INPUT_PULLDOWN: | ||
| 214 | writel(bit, ®s->dirc); | ||
| 215 | val = readl(®s->pdis) & ~bit; | ||
| 216 | writel(val, ®s->pdis); | ||
| 217 | writel(bit, ®s->datc); | ||
| 218 | break; | ||
| 219 | default: | ||
| 220 | err = 1; | ||
| 221 | } | ||
| 222 | spin_unlock_irqrestore(&chip->lock, flags); | ||
| 223 | if (err) | ||
| 224 | pr_err("%s: chip %p, pin %i, cfg %i is invalid\n", | ||
| 225 | __func__, chip, nr, cfg); | ||
| 226 | } | ||
| 227 | |||
| 228 | /* | ||
| 229 | * Irq methods | ||
| 230 | */ | ||
| 231 | |||
| 232 | static void gsta_irq_disable(struct irq_data *data) | ||
| 233 | { | ||
| 234 | struct irq_chip_generic *gc = irq_data_get_irq_chip_data(data); | ||
| 235 | struct gsta_gpio *chip = gc->private; | ||
| 236 | int nr = data->irq - chip->irq_base; | ||
| 237 | struct gsta_regs __iomem *regs = __regs(chip, nr); | ||
| 238 | u32 bit = __bit(nr); | ||
| 239 | u32 val; | ||
| 240 | unsigned long flags; | ||
| 241 | |||
| 242 | spin_lock_irqsave(&chip->lock, flags); | ||
| 243 | if (chip->irq_type[nr] & IRQ_TYPE_EDGE_RISING) { | ||
| 244 | val = readl(®s->rimsc) & ~bit; | ||
| 245 | writel(val, ®s->rimsc); | ||
| 246 | } | ||
| 247 | if (chip->irq_type[nr] & IRQ_TYPE_EDGE_FALLING) { | ||
| 248 | val = readl(®s->fimsc) & ~bit; | ||
| 249 | writel(val, ®s->fimsc); | ||
| 250 | } | ||
| 251 | spin_unlock_irqrestore(&chip->lock, flags); | ||
| 252 | return; | ||
| 253 | } | ||
| 254 | |||
| 255 | static void gsta_irq_enable(struct irq_data *data) | ||
| 256 | { | ||
| 257 | struct irq_chip_generic *gc = irq_data_get_irq_chip_data(data); | ||
| 258 | struct gsta_gpio *chip = gc->private; | ||
| 259 | int nr = data->irq - chip->irq_base; | ||
| 260 | struct gsta_regs __iomem *regs = __regs(chip, nr); | ||
| 261 | u32 bit = __bit(nr); | ||
| 262 | u32 val; | ||
| 263 | int type; | ||
| 264 | unsigned long flags; | ||
| 265 | |||
| 266 | type = chip->irq_type[nr]; | ||
| 267 | |||
| 268 | spin_lock_irqsave(&chip->lock, flags); | ||
| 269 | val = readl(®s->rimsc); | ||
| 270 | if (type & IRQ_TYPE_EDGE_RISING) | ||
| 271 | writel(val | bit, ®s->rimsc); | ||
| 272 | else | ||
| 273 | writel(val & ~bit, ®s->rimsc); | ||
| 274 | val = readl(®s->rimsc); | ||
| 275 | if (type & IRQ_TYPE_EDGE_FALLING) | ||
| 276 | writel(val | bit, ®s->fimsc); | ||
| 277 | else | ||
| 278 | writel(val & ~bit, ®s->fimsc); | ||
| 279 | spin_unlock_irqrestore(&chip->lock, flags); | ||
| 280 | return; | ||
| 281 | } | ||
| 282 | |||
| 283 | static int gsta_irq_type(struct irq_data *d, unsigned int type) | ||
| 284 | { | ||
| 285 | struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); | ||
| 286 | struct gsta_gpio *chip = gc->private; | ||
| 287 | int nr = d->irq - chip->irq_base; | ||
| 288 | |||
| 289 | /* We only support edge interrupts */ | ||
| 290 | if (!(type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING))) { | ||
| 291 | pr_debug("%s: unsupported type 0x%x\n", __func__, type); | ||
| 292 | return -EINVAL; | ||
| 293 | } | ||
| 294 | |||
| 295 | chip->irq_type[nr] = type; /* used for enable/disable */ | ||
| 296 | |||
| 297 | gsta_irq_enable(d); | ||
| 298 | return 0; | ||
| 299 | } | ||
| 300 | |||
| 301 | static irqreturn_t gsta_gpio_handler(int irq, void *dev_id) | ||
| 302 | { | ||
| 303 | struct gsta_gpio *chip = dev_id; | ||
| 304 | struct gsta_regs __iomem *regs; | ||
| 305 | u32 is; | ||
| 306 | int i, nr, base; | ||
| 307 | irqreturn_t ret = IRQ_NONE; | ||
| 308 | |||
| 309 | for (i = 0; i < GSTA_NR_BLOCKS; i++) { | ||
| 310 | regs = chip->regs[i]; | ||
| 311 | base = chip->irq_base + i * GSTA_GPIO_PER_BLOCK; | ||
| 312 | while ((is = readl(®s->is))) { | ||
| 313 | nr = __ffs(is); | ||
| 314 | irq = base + nr; | ||
| 315 | generic_handle_irq(irq); | ||
| 316 | writel(1 << nr, ®s->ic); | ||
| 317 | ret = IRQ_HANDLED; | ||
| 318 | } | ||
| 319 | } | ||
| 320 | return ret; | ||
| 321 | } | ||
| 322 | |||
| 323 | static __devinit void gsta_alloc_irq_chip(struct gsta_gpio *chip) | ||
| 324 | { | ||
| 325 | struct irq_chip_generic *gc; | ||
| 326 | struct irq_chip_type *ct; | ||
| 327 | |||
| 328 | gc = irq_alloc_generic_chip(KBUILD_MODNAME, 1, chip->irq_base, | ||
| 329 | chip->reg_base, handle_simple_irq); | ||
| 330 | gc->private = chip; | ||
| 331 | ct = gc->chip_types; | ||
| 332 | |||
| 333 | ct->chip.irq_set_type = gsta_irq_type; | ||
| 334 | ct->chip.irq_disable = gsta_irq_disable; | ||
| 335 | ct->chip.irq_enable = gsta_irq_enable; | ||
| 336 | |||
| 337 | /* FIXME: this makes at most 32 interrupts. Request 0 by now */ | ||
| 338 | irq_setup_generic_chip(gc, 0 /* IRQ_MSK(GSTA_GPIO_PER_BLOCK) */, 0, | ||
| 339 | IRQ_NOREQUEST | IRQ_NOPROBE, 0); | ||
| 340 | |||
| 341 | /* Set up all all 128 interrupts: code from setup_generic_chip */ | ||
| 342 | { | ||
| 343 | struct irq_chip_type *ct = gc->chip_types; | ||
| 344 | int i, j; | ||
| 345 | for (j = 0; j < GSTA_NR_GPIO; j++) { | ||
| 346 | i = chip->irq_base + j; | ||
| 347 | irq_set_chip_and_handler(i, &ct->chip, ct->handler); | ||
| 348 | irq_set_chip_data(i, gc); | ||
| 349 | irq_modify_status(i, IRQ_NOREQUEST | IRQ_NOPROBE, 0); | ||
| 350 | } | ||
| 351 | gc->irq_cnt = i - gc->irq_base; | ||
| 352 | } | ||
| 353 | } | ||
| 354 | |||
| 355 | /* The platform device used here is instantiated by the MFD device */ | ||
| 356 | static int __devinit gsta_probe(struct platform_device *dev) | ||
| 357 | { | ||
| 358 | int i, err; | ||
| 359 | struct pci_dev *pdev; | ||
| 360 | struct sta2x11_gpio_pdata *gpio_pdata; | ||
| 361 | struct gsta_gpio *chip; | ||
| 362 | struct resource *res; | ||
| 363 | |||
| 364 | pdev = *(struct pci_dev **)(dev->dev.platform_data); | ||
| 365 | gpio_pdata = dev_get_platdata(&pdev->dev); | ||
| 366 | |||
| 367 | if (gpio_pdata == NULL) | ||
| 368 | dev_err(&dev->dev, "no gpio config\n"); | ||
| 369 | pr_debug("gpio config: %p\n", gpio_pdata); | ||
| 370 | |||
| 371 | res = platform_get_resource(dev, IORESOURCE_MEM, 0); | ||
| 372 | |||
| 373 | chip = devm_kzalloc(&dev->dev, sizeof(*chip), GFP_KERNEL); | ||
| 374 | chip->dev = &dev->dev; | ||
| 375 | chip->reg_base = devm_request_and_ioremap(&dev->dev, res); | ||
| 376 | |||
| 377 | for (i = 0; i < GSTA_NR_BLOCKS; i++) { | ||
| 378 | chip->regs[i] = chip->reg_base + i * 4096; | ||
| 379 | /* disable all irqs */ | ||
| 380 | writel(0, &chip->regs[i]->rimsc); | ||
| 381 | writel(0, &chip->regs[i]->fimsc); | ||
| 382 | writel(~0, &chip->regs[i]->ic); | ||
| 383 | } | ||
| 384 | spin_lock_init(&chip->lock); | ||
| 385 | gsta_gpio_setup(chip); | ||
| 386 | for (i = 0; i < GSTA_NR_GPIO; i++) | ||
| 387 | gsta_set_config(chip, i, gpio_pdata->pinconfig[i]); | ||
| 388 | |||
| 389 | /* 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 | if (err < 0) { | ||
| 392 | dev_warn(&dev->dev, "sta2x11 gpio: Can't get irq base (%i)\n", | ||
| 393 | -err); | ||
| 394 | return err; | ||
| 395 | } | ||
| 396 | chip->irq_base = err; | ||
| 397 | gsta_alloc_irq_chip(chip); | ||
| 398 | |||
| 399 | err = request_irq(pdev->irq, gsta_gpio_handler, | ||
| 400 | IRQF_SHARED, KBUILD_MODNAME, chip); | ||
| 401 | if (err < 0) { | ||
| 402 | dev_err(&dev->dev, "sta2x11 gpio: Can't request irq (%i)\n", | ||
| 403 | -err); | ||
| 404 | goto err_free_descs; | ||
| 405 | } | ||
| 406 | |||
| 407 | err = gpiochip_add(&chip->gpio); | ||
| 408 | if (err < 0) { | ||
| 409 | dev_err(&dev->dev, "sta2x11 gpio: Can't register (%i)\n", | ||
| 410 | -err); | ||
| 411 | goto err_free_irq; | ||
| 412 | } | ||
| 413 | |||
| 414 | platform_set_drvdata(dev, chip); | ||
| 415 | return 0; | ||
| 416 | |||
| 417 | err_free_irq: | ||
| 418 | free_irq(pdev->irq, chip); | ||
| 419 | err_free_descs: | ||
| 420 | irq_free_descs(chip->irq_base, GSTA_NR_GPIO); | ||
| 421 | return err; | ||
| 422 | } | ||
| 423 | |||
| 424 | static struct platform_driver sta2x11_gpio_platform_driver = { | ||
| 425 | .driver = { | ||
| 426 | .name = "sta2x11-gpio", | ||
| 427 | .owner = THIS_MODULE, | ||
| 428 | }, | ||
| 429 | .probe = gsta_probe, | ||
| 430 | }; | ||
| 431 | |||
| 432 | module_platform_driver(sta2x11_gpio_platform_driver); | ||
| 433 | |||
| 434 | MODULE_LICENSE("GPL v2"); | ||
| 435 | MODULE_DESCRIPTION("sta2x11_gpio GPIO driver"); | ||
diff --git a/drivers/gpio/gpio-stp-xway.c b/drivers/gpio/gpio-stp-xway.c new file mode 100644 index 000000000000..e35096bf3cfb --- /dev/null +++ b/drivers/gpio/gpio-stp-xway.c | |||
| @@ -0,0 +1,301 @@ | |||
| 1 | /* | ||
| 2 | * This program is free software; you can redistribute it and/or modify it | ||
| 3 | * under the terms of the GNU General Public License version 2 as published | ||
| 4 | * by the Free Software Foundation. | ||
| 5 | * | ||
| 6 | * Copyright (C) 2012 John Crispin <blogic@openwrt.org> | ||
| 7 | * | ||
| 8 | */ | ||
| 9 | |||
| 10 | #include <linux/slab.h> | ||
| 11 | #include <linux/init.h> | ||
| 12 | #include <linux/module.h> | ||
| 13 | #include <linux/types.h> | ||
| 14 | #include <linux/of_platform.h> | ||
| 15 | #include <linux/mutex.h> | ||
| 16 | #include <linux/gpio.h> | ||
| 17 | #include <linux/io.h> | ||
| 18 | #include <linux/of_gpio.h> | ||
| 19 | #include <linux/clk.h> | ||
| 20 | #include <linux/err.h> | ||
| 21 | |||
| 22 | #include <lantiq_soc.h> | ||
| 23 | |||
| 24 | /* | ||
| 25 | * The Serial To Parallel (STP) is found on MIPS based Lantiq socs. It is a | ||
| 26 | * peripheral controller used to drive external shift register cascades. At most | ||
| 27 | * 3 groups of 8 bits can be driven. The hardware is able to allow the DSL modem | ||
| 28 | * to drive the 2 LSBs of the cascade automatically. | ||
| 29 | */ | ||
| 30 | |||
| 31 | /* control register 0 */ | ||
| 32 | #define XWAY_STP_CON0 0x00 | ||
| 33 | /* control register 1 */ | ||
| 34 | #define XWAY_STP_CON1 0x04 | ||
| 35 | /* data register 0 */ | ||
| 36 | #define XWAY_STP_CPU0 0x08 | ||
| 37 | /* data register 1 */ | ||
| 38 | #define XWAY_STP_CPU1 0x0C | ||
| 39 | /* access register */ | ||
| 40 | #define XWAY_STP_AR 0x10 | ||
| 41 | |||
| 42 | /* software or hardware update select bit */ | ||
| 43 | #define XWAY_STP_CON_SWU BIT(31) | ||
| 44 | |||
| 45 | /* automatic update rates */ | ||
| 46 | #define XWAY_STP_2HZ 0 | ||
| 47 | #define XWAY_STP_4HZ BIT(23) | ||
| 48 | #define XWAY_STP_8HZ BIT(24) | ||
| 49 | #define XWAY_STP_10HZ (BIT(24) | BIT(23)) | ||
| 50 | #define XWAY_STP_SPEED_MASK (0xf << 23) | ||
| 51 | |||
| 52 | /* clock source for automatic update */ | ||
| 53 | #define XWAY_STP_UPD_FPI BIT(31) | ||
| 54 | #define XWAY_STP_UPD_MASK (BIT(31) | BIT(30)) | ||
| 55 | |||
| 56 | /* let the adsl core drive the 2 LSBs */ | ||
| 57 | #define XWAY_STP_ADSL_SHIFT 24 | ||
| 58 | #define XWAY_STP_ADSL_MASK 0x3 | ||
| 59 | |||
| 60 | /* 2 groups of 3 bits can be driven by the phys */ | ||
| 61 | #define XWAY_STP_PHY_MASK 0x3 | ||
| 62 | #define XWAY_STP_PHY1_SHIFT 27 | ||
| 63 | #define XWAY_STP_PHY2_SHIFT 15 | ||
| 64 | |||
| 65 | /* STP has 3 groups of 8 bits */ | ||
| 66 | #define XWAY_STP_GROUP0 BIT(0) | ||
| 67 | #define XWAY_STP_GROUP1 BIT(1) | ||
| 68 | #define XWAY_STP_GROUP2 BIT(2) | ||
| 69 | #define XWAY_STP_GROUP_MASK (0x7) | ||
| 70 | |||
| 71 | /* Edge configuration bits */ | ||
| 72 | #define XWAY_STP_FALLING BIT(26) | ||
| 73 | #define XWAY_STP_EDGE_MASK BIT(26) | ||
| 74 | |||
| 75 | #define xway_stp_r32(m, reg) __raw_readl(m + reg) | ||
| 76 | #define xway_stp_w32(m, val, reg) __raw_writel(val, m + reg) | ||
| 77 | #define xway_stp_w32_mask(m, clear, set, reg) \ | ||
| 78 | ltq_w32((ltq_r32(m + reg) & ~(clear)) | (set), \ | ||
| 79 | m + reg) | ||
| 80 | |||
| 81 | struct xway_stp { | ||
| 82 | struct gpio_chip gc; | ||
| 83 | void __iomem *virt; | ||
| 84 | u32 edge; /* rising or falling edge triggered shift register */ | ||
| 85 | u16 shadow; /* shadow the shift registers state */ | ||
| 86 | u8 groups; /* we can drive 1-3 groups of 8bit each */ | ||
| 87 | u8 dsl; /* the 2 LSBs can be driven by the dsl core */ | ||
| 88 | u8 phy1; /* 3 bits can be driven by phy1 */ | ||
| 89 | u8 phy2; /* 3 bits can be driven by phy2 */ | ||
| 90 | u8 reserved; /* mask out the hw driven bits in gpio_request */ | ||
| 91 | }; | ||
| 92 | |||
| 93 | /** | ||
| 94 | * xway_stp_set() - gpio_chip->set - set gpios. | ||
| 95 | * @gc: Pointer to gpio_chip device structure. | ||
| 96 | * @gpio: GPIO signal number. | ||
| 97 | * @val: Value to be written to specified signal. | ||
| 98 | * | ||
| 99 | * Set the shadow value and call ltq_ebu_apply. | ||
| 100 | */ | ||
| 101 | static void xway_stp_set(struct gpio_chip *gc, unsigned gpio, int val) | ||
| 102 | { | ||
| 103 | struct xway_stp *chip = | ||
| 104 | container_of(gc, struct xway_stp, gc); | ||
| 105 | |||
| 106 | if (val) | ||
| 107 | chip->shadow |= BIT(gpio); | ||
| 108 | else | ||
| 109 | chip->shadow &= ~BIT(gpio); | ||
| 110 | xway_stp_w32(chip->virt, chip->shadow, XWAY_STP_CPU0); | ||
| 111 | xway_stp_w32_mask(chip->virt, 0, XWAY_STP_CON_SWU, XWAY_STP_CON0); | ||
| 112 | } | ||
| 113 | |||
| 114 | /** | ||
| 115 | * xway_stp_dir_out() - gpio_chip->dir_out - set gpio direction. | ||
| 116 | * @gc: Pointer to gpio_chip device structure. | ||
| 117 | * @gpio: GPIO signal number. | ||
| 118 | * @val: Value to be written to specified signal. | ||
| 119 | * | ||
| 120 | * Same as xway_stp_set, always returns 0. | ||
| 121 | */ | ||
| 122 | static int xway_stp_dir_out(struct gpio_chip *gc, unsigned gpio, int val) | ||
| 123 | { | ||
| 124 | xway_stp_set(gc, gpio, val); | ||
| 125 | |||
| 126 | return 0; | ||
| 127 | } | ||
| 128 | |||
| 129 | /** | ||
| 130 | * xway_stp_request() - gpio_chip->request | ||
| 131 | * @gc: Pointer to gpio_chip device structure. | ||
| 132 | * @gpio: GPIO signal number. | ||
| 133 | * | ||
| 134 | * We mask out the HW driven pins | ||
| 135 | */ | ||
| 136 | static int xway_stp_request(struct gpio_chip *gc, unsigned gpio) | ||
| 137 | { | ||
| 138 | struct xway_stp *chip = | ||
| 139 | container_of(gc, struct xway_stp, gc); | ||
| 140 | |||
| 141 | if ((gpio < 8) && (chip->reserved & BIT(gpio))) { | ||
| 142 | dev_err(gc->dev, "GPIO %d is driven by hardware\n", gpio); | ||
| 143 | return -ENODEV; | ||
| 144 | } | ||
| 145 | |||
| 146 | return 0; | ||
| 147 | } | ||
| 148 | |||
| 149 | /** | ||
| 150 | * xway_stp_hw_init() - Configure the STP unit and enable the clock gate | ||
| 151 | * @virt: pointer to the remapped register range | ||
| 152 | */ | ||
| 153 | static int xway_stp_hw_init(struct xway_stp *chip) | ||
| 154 | { | ||
| 155 | /* sane defaults */ | ||
| 156 | xway_stp_w32(chip->virt, 0, XWAY_STP_AR); | ||
| 157 | xway_stp_w32(chip->virt, 0, XWAY_STP_CPU0); | ||
| 158 | xway_stp_w32(chip->virt, 0, XWAY_STP_CPU1); | ||
| 159 | xway_stp_w32(chip->virt, XWAY_STP_CON_SWU, XWAY_STP_CON0); | ||
| 160 | xway_stp_w32(chip->virt, 0, XWAY_STP_CON1); | ||
| 161 | |||
| 162 | /* apply edge trigger settings for the shift register */ | ||
| 163 | xway_stp_w32_mask(chip->virt, XWAY_STP_EDGE_MASK, | ||
| 164 | chip->edge, XWAY_STP_CON0); | ||
| 165 | |||
| 166 | /* apply led group settings */ | ||
| 167 | xway_stp_w32_mask(chip->virt, XWAY_STP_GROUP_MASK, | ||
| 168 | chip->groups, XWAY_STP_CON1); | ||
| 169 | |||
| 170 | /* tell the hardware which pins are controlled by the dsl modem */ | ||
| 171 | xway_stp_w32_mask(chip->virt, | ||
| 172 | XWAY_STP_ADSL_MASK << XWAY_STP_ADSL_SHIFT, | ||
| 173 | chip->dsl << XWAY_STP_ADSL_SHIFT, | ||
| 174 | XWAY_STP_CON0); | ||
| 175 | |||
| 176 | /* tell the hardware which pins are controlled by the phys */ | ||
| 177 | xway_stp_w32_mask(chip->virt, | ||
| 178 | XWAY_STP_PHY_MASK << XWAY_STP_PHY1_SHIFT, | ||
| 179 | chip->phy1 << XWAY_STP_PHY1_SHIFT, | ||
| 180 | XWAY_STP_CON0); | ||
| 181 | xway_stp_w32_mask(chip->virt, | ||
| 182 | XWAY_STP_PHY_MASK << XWAY_STP_PHY2_SHIFT, | ||
| 183 | chip->phy2 << XWAY_STP_PHY2_SHIFT, | ||
| 184 | XWAY_STP_CON1); | ||
| 185 | |||
| 186 | /* mask out the hw driven bits in gpio_request */ | ||
| 187 | chip->reserved = (chip->phy2 << 5) | (chip->phy1 << 2) | chip->dsl; | ||
| 188 | |||
| 189 | /* | ||
| 190 | * if we have pins that are driven by hw, we need to tell the stp what | ||
| 191 | * clock to use as a timer. | ||
| 192 | */ | ||
| 193 | if (chip->reserved) | ||
| 194 | xway_stp_w32_mask(chip->virt, XWAY_STP_UPD_MASK, | ||
| 195 | XWAY_STP_UPD_FPI, XWAY_STP_CON1); | ||
| 196 | |||
| 197 | return 0; | ||
| 198 | } | ||
| 199 | |||
| 200 | static int __devinit xway_stp_probe(struct platform_device *pdev) | ||
| 201 | { | ||
| 202 | struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
| 203 | const __be32 *shadow, *groups, *dsl, *phy; | ||
| 204 | struct xway_stp *chip; | ||
| 205 | struct clk *clk; | ||
| 206 | int ret = 0; | ||
| 207 | |||
| 208 | if (!res) { | ||
| 209 | dev_err(&pdev->dev, "failed to request STP resource\n"); | ||
| 210 | return -ENOENT; | ||
| 211 | } | ||
| 212 | |||
| 213 | chip = devm_kzalloc(&pdev->dev, sizeof(*chip), GFP_KERNEL); | ||
| 214 | if (!chip) | ||
| 215 | return -ENOMEM; | ||
| 216 | |||
| 217 | chip->virt = devm_request_and_ioremap(&pdev->dev, res); | ||
| 218 | if (!chip->virt) { | ||
| 219 | dev_err(&pdev->dev, "failed to remap STP memory\n"); | ||
| 220 | return -ENOMEM; | ||
| 221 | } | ||
| 222 | chip->gc.dev = &pdev->dev; | ||
| 223 | chip->gc.label = "stp-xway"; | ||
| 224 | chip->gc.direction_output = xway_stp_dir_out; | ||
| 225 | chip->gc.set = xway_stp_set; | ||
| 226 | chip->gc.request = xway_stp_request; | ||
| 227 | chip->gc.base = -1; | ||
| 228 | chip->gc.owner = THIS_MODULE; | ||
| 229 | |||
| 230 | /* store the shadow value if one was passed by the devicetree */ | ||
| 231 | shadow = of_get_property(pdev->dev.of_node, "lantiq,shadow", NULL); | ||
| 232 | if (shadow) | ||
| 233 | chip->shadow = be32_to_cpu(*shadow); | ||
| 234 | |||
| 235 | /* find out which gpio groups should be enabled */ | ||
| 236 | groups = of_get_property(pdev->dev.of_node, "lantiq,groups", NULL); | ||
| 237 | if (groups) | ||
| 238 | chip->groups = be32_to_cpu(*groups) & XWAY_STP_GROUP_MASK; | ||
| 239 | else | ||
| 240 | chip->groups = XWAY_STP_GROUP0; | ||
| 241 | chip->gc.ngpio = fls(chip->groups) * 8; | ||
| 242 | |||
| 243 | /* find out which gpios are controlled by the dsl core */ | ||
| 244 | dsl = of_get_property(pdev->dev.of_node, "lantiq,dsl", NULL); | ||
| 245 | if (dsl) | ||
| 246 | chip->dsl = be32_to_cpu(*dsl) & XWAY_STP_ADSL_MASK; | ||
| 247 | |||
| 248 | /* find out which gpios are controlled by the phys */ | ||
| 249 | if (of_machine_is_compatible("lantiq,ar9") || | ||
| 250 | of_machine_is_compatible("lantiq,gr9") || | ||
| 251 | of_machine_is_compatible("lantiq,vr9")) { | ||
| 252 | phy = of_get_property(pdev->dev.of_node, "lantiq,phy1", NULL); | ||
| 253 | if (phy) | ||
| 254 | chip->phy1 = be32_to_cpu(*phy) & XWAY_STP_PHY_MASK; | ||
| 255 | phy = of_get_property(pdev->dev.of_node, "lantiq,phy2", NULL); | ||
| 256 | if (phy) | ||
| 257 | chip->phy2 = be32_to_cpu(*phy) & XWAY_STP_PHY_MASK; | ||
| 258 | } | ||
| 259 | |||
| 260 | /* check which edge trigger we should use, default to a falling edge */ | ||
| 261 | if (!of_find_property(pdev->dev.of_node, "lantiq,rising", NULL)) | ||
| 262 | chip->edge = XWAY_STP_FALLING; | ||
| 263 | |||
| 264 | clk = clk_get(&pdev->dev, NULL); | ||
| 265 | if (IS_ERR(clk)) { | ||
| 266 | dev_err(&pdev->dev, "Failed to get clock\n"); | ||
| 267 | return PTR_ERR(clk); | ||
| 268 | } | ||
| 269 | clk_enable(clk); | ||
| 270 | |||
| 271 | ret = xway_stp_hw_init(chip); | ||
| 272 | if (!ret) | ||
| 273 | ret = gpiochip_add(&chip->gc); | ||
| 274 | |||
| 275 | if (!ret) | ||
| 276 | dev_info(&pdev->dev, "Init done\n"); | ||
| 277 | |||
| 278 | return ret; | ||
| 279 | } | ||
| 280 | |||
| 281 | static const struct of_device_id xway_stp_match[] = { | ||
| 282 | { .compatible = "lantiq,gpio-stp-xway" }, | ||
| 283 | {}, | ||
| 284 | }; | ||
| 285 | MODULE_DEVICE_TABLE(of, xway_stp_match); | ||
| 286 | |||
| 287 | static struct platform_driver xway_stp_driver = { | ||
| 288 | .probe = xway_stp_probe, | ||
| 289 | .driver = { | ||
| 290 | .name = "gpio-stp-xway", | ||
| 291 | .owner = THIS_MODULE, | ||
| 292 | .of_match_table = xway_stp_match, | ||
| 293 | }, | ||
| 294 | }; | ||
| 295 | |||
| 296 | int __init xway_stp_init(void) | ||
| 297 | { | ||
| 298 | return platform_driver_register(&xway_stp_driver); | ||
| 299 | } | ||
| 300 | |||
| 301 | subsys_initcall(xway_stp_init); | ||
diff --git a/drivers/gpio/gpio-tegra.c b/drivers/gpio/gpio-tegra.c index 12f349b3830d..dc5184d57892 100644 --- a/drivers/gpio/gpio-tegra.c +++ b/drivers/gpio/gpio-tegra.c | |||
| @@ -26,10 +26,10 @@ | |||
| 26 | #include <linux/platform_device.h> | 26 | #include <linux/platform_device.h> |
| 27 | #include <linux/module.h> | 27 | #include <linux/module.h> |
| 28 | #include <linux/irqdomain.h> | 28 | #include <linux/irqdomain.h> |
| 29 | #include <linux/pinctrl/consumer.h> | ||
| 29 | 30 | ||
| 30 | #include <asm/mach/irq.h> | 31 | #include <asm/mach/irq.h> |
| 31 | 32 | ||
| 32 | #include <mach/gpio-tegra.h> | ||
| 33 | #include <mach/iomap.h> | 33 | #include <mach/iomap.h> |
| 34 | #include <mach/suspend.h> | 34 | #include <mach/suspend.h> |
| 35 | 35 | ||
| @@ -108,18 +108,29 @@ static void tegra_gpio_mask_write(u32 reg, int gpio, int value) | |||
| 108 | tegra_gpio_writel(val, reg); | 108 | tegra_gpio_writel(val, reg); |
| 109 | } | 109 | } |
| 110 | 110 | ||
| 111 | void tegra_gpio_enable(int gpio) | 111 | static void tegra_gpio_enable(int gpio) |
| 112 | { | 112 | { |
| 113 | tegra_gpio_mask_write(GPIO_MSK_CNF(gpio), gpio, 1); | 113 | tegra_gpio_mask_write(GPIO_MSK_CNF(gpio), gpio, 1); |
| 114 | } | 114 | } |
| 115 | EXPORT_SYMBOL_GPL(tegra_gpio_enable); | 115 | EXPORT_SYMBOL_GPL(tegra_gpio_enable); |
| 116 | 116 | ||
| 117 | void tegra_gpio_disable(int gpio) | 117 | static void tegra_gpio_disable(int gpio) |
| 118 | { | 118 | { |
| 119 | tegra_gpio_mask_write(GPIO_MSK_CNF(gpio), gpio, 0); | 119 | tegra_gpio_mask_write(GPIO_MSK_CNF(gpio), gpio, 0); |
| 120 | } | 120 | } |
| 121 | EXPORT_SYMBOL_GPL(tegra_gpio_disable); | 121 | EXPORT_SYMBOL_GPL(tegra_gpio_disable); |
| 122 | 122 | ||
| 123 | int tegra_gpio_request(struct gpio_chip *chip, unsigned offset) | ||
| 124 | { | ||
| 125 | return pinctrl_request_gpio(offset); | ||
| 126 | } | ||
| 127 | |||
| 128 | void tegra_gpio_free(struct gpio_chip *chip, unsigned offset) | ||
| 129 | { | ||
| 130 | pinctrl_free_gpio(offset); | ||
| 131 | tegra_gpio_disable(offset); | ||
| 132 | } | ||
| 133 | |||
| 123 | static void tegra_gpio_set(struct gpio_chip *chip, unsigned offset, int value) | 134 | static void tegra_gpio_set(struct gpio_chip *chip, unsigned offset, int value) |
| 124 | { | 135 | { |
| 125 | tegra_gpio_mask_write(GPIO_MSK_OUT(offset), offset, value); | 136 | tegra_gpio_mask_write(GPIO_MSK_OUT(offset), offset, value); |
| @@ -133,6 +144,7 @@ static int tegra_gpio_get(struct gpio_chip *chip, unsigned offset) | |||
| 133 | static int tegra_gpio_direction_input(struct gpio_chip *chip, unsigned offset) | 144 | static int tegra_gpio_direction_input(struct gpio_chip *chip, unsigned offset) |
| 134 | { | 145 | { |
| 135 | tegra_gpio_mask_write(GPIO_MSK_OE(offset), offset, 0); | 146 | tegra_gpio_mask_write(GPIO_MSK_OE(offset), offset, 0); |
| 147 | tegra_gpio_enable(offset); | ||
| 136 | return 0; | 148 | return 0; |
| 137 | } | 149 | } |
| 138 | 150 | ||
| @@ -141,6 +153,7 @@ static int tegra_gpio_direction_output(struct gpio_chip *chip, unsigned offset, | |||
| 141 | { | 153 | { |
| 142 | tegra_gpio_set(chip, offset, value); | 154 | tegra_gpio_set(chip, offset, value); |
| 143 | tegra_gpio_mask_write(GPIO_MSK_OE(offset), offset, 1); | 155 | tegra_gpio_mask_write(GPIO_MSK_OE(offset), offset, 1); |
| 156 | tegra_gpio_enable(offset); | ||
| 144 | return 0; | 157 | return 0; |
| 145 | } | 158 | } |
| 146 | 159 | ||
| @@ -151,13 +164,14 @@ static int tegra_gpio_to_irq(struct gpio_chip *chip, unsigned offset) | |||
| 151 | 164 | ||
| 152 | static struct gpio_chip tegra_gpio_chip = { | 165 | static struct gpio_chip tegra_gpio_chip = { |
| 153 | .label = "tegra-gpio", | 166 | .label = "tegra-gpio", |
| 167 | .request = tegra_gpio_request, | ||
| 168 | .free = tegra_gpio_free, | ||
| 154 | .direction_input = tegra_gpio_direction_input, | 169 | .direction_input = tegra_gpio_direction_input, |
| 155 | .get = tegra_gpio_get, | 170 | .get = tegra_gpio_get, |
| 156 | .direction_output = tegra_gpio_direction_output, | 171 | .direction_output = tegra_gpio_direction_output, |
| 157 | .set = tegra_gpio_set, | 172 | .set = tegra_gpio_set, |
| 158 | .to_irq = tegra_gpio_to_irq, | 173 | .to_irq = tegra_gpio_to_irq, |
| 159 | .base = 0, | 174 | .base = 0, |
| 160 | .ngpio = TEGRA_NR_GPIOS, | ||
| 161 | }; | 175 | }; |
| 162 | 176 | ||
| 163 | static void tegra_gpio_irq_ack(struct irq_data *d) | 177 | static void tegra_gpio_irq_ack(struct irq_data *d) |
| @@ -224,6 +238,9 @@ static int tegra_gpio_irq_set_type(struct irq_data *d, unsigned int type) | |||
| 224 | 238 | ||
| 225 | spin_unlock_irqrestore(&bank->lvl_lock[port], flags); | 239 | spin_unlock_irqrestore(&bank->lvl_lock[port], flags); |
| 226 | 240 | ||
| 241 | tegra_gpio_mask_write(GPIO_MSK_OE(gpio), gpio, 0); | ||
| 242 | tegra_gpio_enable(gpio); | ||
| 243 | |||
| 227 | if (type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_LEVEL_HIGH)) | 244 | if (type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_LEVEL_HIGH)) |
| 228 | __irq_set_handler_locked(d->irq, handle_level_irq); | 245 | __irq_set_handler_locked(d->irq, handle_level_irq); |
| 229 | else if (type & (IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING)) | 246 | else if (type & (IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING)) |
| @@ -490,20 +507,6 @@ static int __init tegra_gpio_init(void) | |||
| 490 | } | 507 | } |
| 491 | postcore_initcall(tegra_gpio_init); | 508 | postcore_initcall(tegra_gpio_init); |
| 492 | 509 | ||
| 493 | void tegra_gpio_config(struct tegra_gpio_table *table, int num) | ||
| 494 | { | ||
| 495 | int i; | ||
| 496 | |||
| 497 | for (i = 0; i < num; i++) { | ||
| 498 | int gpio = table[i].gpio; | ||
| 499 | |||
| 500 | if (table[i].enable) | ||
| 501 | tegra_gpio_enable(gpio); | ||
| 502 | else | ||
| 503 | tegra_gpio_disable(gpio); | ||
| 504 | } | ||
| 505 | } | ||
| 506 | |||
| 507 | #ifdef CONFIG_DEBUG_FS | 510 | #ifdef CONFIG_DEBUG_FS |
| 508 | 511 | ||
| 509 | #include <linux/debugfs.h> | 512 | #include <linux/debugfs.h> |
diff --git a/drivers/gpio/gpio-tps65910.c b/drivers/gpio/gpio-tps65910.c index 7eef648a3351..c1ad2884f2ed 100644 --- a/drivers/gpio/gpio-tps65910.c +++ b/drivers/gpio/gpio-tps65910.c | |||
| @@ -18,14 +18,27 @@ | |||
| 18 | #include <linux/errno.h> | 18 | #include <linux/errno.h> |
| 19 | #include <linux/gpio.h> | 19 | #include <linux/gpio.h> |
| 20 | #include <linux/i2c.h> | 20 | #include <linux/i2c.h> |
| 21 | #include <linux/platform_device.h> | ||
| 21 | #include <linux/mfd/tps65910.h> | 22 | #include <linux/mfd/tps65910.h> |
| 23 | #include <linux/of_device.h> | ||
| 24 | |||
| 25 | struct tps65910_gpio { | ||
| 26 | struct gpio_chip gpio_chip; | ||
| 27 | struct tps65910 *tps65910; | ||
| 28 | }; | ||
| 29 | |||
| 30 | static inline struct tps65910_gpio *to_tps65910_gpio(struct gpio_chip *chip) | ||
| 31 | { | ||
| 32 | return container_of(chip, struct tps65910_gpio, gpio_chip); | ||
| 33 | } | ||
| 22 | 34 | ||
| 23 | static int tps65910_gpio_get(struct gpio_chip *gc, unsigned offset) | 35 | static int tps65910_gpio_get(struct gpio_chip *gc, unsigned offset) |
| 24 | { | 36 | { |
| 25 | struct tps65910 *tps65910 = container_of(gc, struct tps65910, gpio); | 37 | struct tps65910_gpio *tps65910_gpio = to_tps65910_gpio(gc); |
| 26 | uint8_t val; | 38 | struct tps65910 *tps65910 = tps65910_gpio->tps65910; |
| 39 | unsigned int val; | ||
| 27 | 40 | ||
| 28 | tps65910->read(tps65910, TPS65910_GPIO0 + offset, 1, &val); | 41 | tps65910_reg_read(tps65910, TPS65910_GPIO0 + offset, &val); |
| 29 | 42 | ||
| 30 | if (val & GPIO_STS_MASK) | 43 | if (val & GPIO_STS_MASK) |
| 31 | return 1; | 44 | return 1; |
| @@ -36,83 +49,170 @@ static int tps65910_gpio_get(struct gpio_chip *gc, unsigned offset) | |||
| 36 | static void tps65910_gpio_set(struct gpio_chip *gc, unsigned offset, | 49 | static void tps65910_gpio_set(struct gpio_chip *gc, unsigned offset, |
| 37 | int value) | 50 | int value) |
| 38 | { | 51 | { |
| 39 | struct tps65910 *tps65910 = container_of(gc, struct tps65910, gpio); | 52 | struct tps65910_gpio *tps65910_gpio = to_tps65910_gpio(gc); |
| 53 | struct tps65910 *tps65910 = tps65910_gpio->tps65910; | ||
| 40 | 54 | ||
| 41 | if (value) | 55 | if (value) |
| 42 | tps65910_set_bits(tps65910, TPS65910_GPIO0 + offset, | 56 | tps65910_reg_set_bits(tps65910, TPS65910_GPIO0 + offset, |
| 43 | GPIO_SET_MASK); | 57 | GPIO_SET_MASK); |
| 44 | else | 58 | else |
| 45 | tps65910_clear_bits(tps65910, TPS65910_GPIO0 + offset, | 59 | tps65910_reg_clear_bits(tps65910, TPS65910_GPIO0 + offset, |
| 46 | GPIO_SET_MASK); | 60 | GPIO_SET_MASK); |
| 47 | } | 61 | } |
| 48 | 62 | ||
| 49 | static int tps65910_gpio_output(struct gpio_chip *gc, unsigned offset, | 63 | static int tps65910_gpio_output(struct gpio_chip *gc, unsigned offset, |
| 50 | int value) | 64 | int value) |
| 51 | { | 65 | { |
| 52 | struct tps65910 *tps65910 = container_of(gc, struct tps65910, gpio); | 66 | struct tps65910_gpio *tps65910_gpio = to_tps65910_gpio(gc); |
| 67 | struct tps65910 *tps65910 = tps65910_gpio->tps65910; | ||
| 53 | 68 | ||
| 54 | /* Set the initial value */ | 69 | /* Set the initial value */ |
| 55 | tps65910_gpio_set(gc, offset, value); | 70 | tps65910_gpio_set(gc, offset, value); |
| 56 | 71 | ||
| 57 | return tps65910_set_bits(tps65910, TPS65910_GPIO0 + offset, | 72 | return tps65910_reg_set_bits(tps65910, TPS65910_GPIO0 + offset, |
| 58 | GPIO_CFG_MASK); | 73 | GPIO_CFG_MASK); |
| 59 | } | 74 | } |
| 60 | 75 | ||
| 61 | static int tps65910_gpio_input(struct gpio_chip *gc, unsigned offset) | 76 | static int tps65910_gpio_input(struct gpio_chip *gc, unsigned offset) |
| 62 | { | 77 | { |
| 63 | struct tps65910 *tps65910 = container_of(gc, struct tps65910, gpio); | 78 | struct tps65910_gpio *tps65910_gpio = to_tps65910_gpio(gc); |
| 79 | struct tps65910 *tps65910 = tps65910_gpio->tps65910; | ||
| 64 | 80 | ||
| 65 | return tps65910_clear_bits(tps65910, TPS65910_GPIO0 + offset, | 81 | return tps65910_reg_clear_bits(tps65910, TPS65910_GPIO0 + offset, |
| 66 | GPIO_CFG_MASK); | 82 | GPIO_CFG_MASK); |
| 67 | } | 83 | } |
| 68 | 84 | ||
| 69 | void tps65910_gpio_init(struct tps65910 *tps65910, int gpio_base) | 85 | #ifdef CONFIG_OF |
| 86 | static struct tps65910_board *tps65910_parse_dt_for_gpio(struct device *dev, | ||
| 87 | struct tps65910 *tps65910, int chip_ngpio) | ||
| 70 | { | 88 | { |
| 89 | struct tps65910_board *tps65910_board = tps65910->of_plat_data; | ||
| 90 | unsigned int prop_array[TPS6591X_MAX_NUM_GPIO]; | ||
| 91 | int ngpio = min(chip_ngpio, TPS6591X_MAX_NUM_GPIO); | ||
| 71 | int ret; | 92 | int ret; |
| 72 | struct tps65910_board *board_data; | 93 | int idx; |
| 94 | |||
| 95 | tps65910_board->gpio_base = -1; | ||
| 96 | ret = of_property_read_u32_array(tps65910->dev->of_node, | ||
| 97 | "ti,en-gpio-sleep", prop_array, ngpio); | ||
| 98 | if (ret < 0) { | ||
| 99 | dev_dbg(dev, "ti,en-gpio-sleep not specified\n"); | ||
| 100 | return tps65910_board; | ||
| 101 | } | ||
| 73 | 102 | ||
| 74 | if (!gpio_base) | 103 | for (idx = 0; idx < ngpio; idx++) |
| 75 | return; | 104 | tps65910_board->en_gpio_sleep[idx] = (prop_array[idx] != 0); |
| 76 | 105 | ||
| 77 | tps65910->gpio.owner = THIS_MODULE; | 106 | return tps65910_board; |
| 78 | tps65910->gpio.label = tps65910->i2c_client->name; | 107 | } |
| 79 | tps65910->gpio.dev = tps65910->dev; | 108 | #else |
| 80 | tps65910->gpio.base = gpio_base; | 109 | static struct tps65910_board *tps65910_parse_dt_for_gpio(struct device *dev, |
| 110 | struct tps65910 *tps65910, int chip_ngpio) | ||
| 111 | { | ||
| 112 | return NULL; | ||
| 113 | } | ||
| 114 | #endif | ||
| 115 | |||
| 116 | static int __devinit tps65910_gpio_probe(struct platform_device *pdev) | ||
| 117 | { | ||
| 118 | struct tps65910 *tps65910 = dev_get_drvdata(pdev->dev.parent); | ||
| 119 | struct tps65910_board *pdata = dev_get_platdata(tps65910->dev); | ||
| 120 | struct tps65910_gpio *tps65910_gpio; | ||
| 121 | int ret; | ||
| 122 | int i; | ||
| 123 | |||
| 124 | tps65910_gpio = devm_kzalloc(&pdev->dev, | ||
| 125 | sizeof(*tps65910_gpio), GFP_KERNEL); | ||
| 126 | if (!tps65910_gpio) { | ||
| 127 | dev_err(&pdev->dev, "Could not allocate tps65910_gpio\n"); | ||
| 128 | return -ENOMEM; | ||
| 129 | } | ||
| 130 | |||
| 131 | tps65910_gpio->tps65910 = tps65910; | ||
| 132 | |||
| 133 | tps65910_gpio->gpio_chip.owner = THIS_MODULE; | ||
| 134 | tps65910_gpio->gpio_chip.label = tps65910->i2c_client->name; | ||
| 81 | 135 | ||
| 82 | switch(tps65910_chip_id(tps65910)) { | 136 | switch(tps65910_chip_id(tps65910)) { |
| 83 | case TPS65910: | 137 | case TPS65910: |
| 84 | tps65910->gpio.ngpio = TPS65910_NUM_GPIO; | 138 | tps65910_gpio->gpio_chip.ngpio = TPS65910_NUM_GPIO; |
| 85 | break; | 139 | break; |
| 86 | case TPS65911: | 140 | case TPS65911: |
| 87 | tps65910->gpio.ngpio = TPS65911_NUM_GPIO; | 141 | tps65910_gpio->gpio_chip.ngpio = TPS65911_NUM_GPIO; |
| 88 | break; | 142 | break; |
| 89 | default: | 143 | default: |
| 90 | return; | 144 | return -EINVAL; |
| 145 | } | ||
| 146 | tps65910_gpio->gpio_chip.can_sleep = 1; | ||
| 147 | tps65910_gpio->gpio_chip.direction_input = tps65910_gpio_input; | ||
| 148 | tps65910_gpio->gpio_chip.direction_output = tps65910_gpio_output; | ||
| 149 | tps65910_gpio->gpio_chip.set = tps65910_gpio_set; | ||
| 150 | tps65910_gpio->gpio_chip.get = tps65910_gpio_get; | ||
| 151 | tps65910_gpio->gpio_chip.dev = &pdev->dev; | ||
| 152 | if (pdata && pdata->gpio_base) | ||
| 153 | tps65910_gpio->gpio_chip.base = pdata->gpio_base; | ||
| 154 | else | ||
| 155 | tps65910_gpio->gpio_chip.base = -1; | ||
| 156 | |||
| 157 | if (!pdata && tps65910->dev->of_node) | ||
| 158 | pdata = tps65910_parse_dt_for_gpio(&pdev->dev, tps65910, | ||
| 159 | tps65910_gpio->gpio_chip.ngpio); | ||
| 160 | |||
| 161 | if (!pdata) | ||
| 162 | goto skip_init; | ||
| 163 | |||
| 164 | /* Configure sleep control for gpios if provided */ | ||
| 165 | for (i = 0; i < tps65910_gpio->gpio_chip.ngpio; ++i) { | ||
| 166 | if (!pdata->en_gpio_sleep[i]) | ||
| 167 | continue; | ||
| 168 | |||
| 169 | ret = tps65910_reg_set_bits(tps65910, | ||
| 170 | TPS65910_GPIO0 + i, GPIO_SLEEP_MASK); | ||
| 171 | if (ret < 0) | ||
| 172 | dev_warn(tps65910->dev, | ||
| 173 | "GPIO Sleep setting failed with err %d\n", ret); | ||
| 91 | } | 174 | } |
| 92 | tps65910->gpio.can_sleep = 1; | 175 | |
| 93 | 176 | skip_init: | |
| 94 | tps65910->gpio.direction_input = tps65910_gpio_input; | 177 | ret = gpiochip_add(&tps65910_gpio->gpio_chip); |
| 95 | tps65910->gpio.direction_output = tps65910_gpio_output; | 178 | if (ret < 0) { |
| 96 | tps65910->gpio.set = tps65910_gpio_set; | 179 | dev_err(&pdev->dev, "Could not register gpiochip, %d\n", ret); |
| 97 | tps65910->gpio.get = tps65910_gpio_get; | 180 | return ret; |
| 98 | |||
| 99 | /* Configure sleep control for gpios */ | ||
| 100 | board_data = dev_get_platdata(tps65910->dev); | ||
| 101 | if (board_data) { | ||
| 102 | int i; | ||
| 103 | for (i = 0; i < tps65910->gpio.ngpio; ++i) { | ||
| 104 | if (board_data->en_gpio_sleep[i]) { | ||
| 105 | ret = tps65910_set_bits(tps65910, | ||
| 106 | TPS65910_GPIO0 + i, GPIO_SLEEP_MASK); | ||
| 107 | if (ret < 0) | ||
| 108 | dev_warn(tps65910->dev, | ||
| 109 | "GPIO Sleep setting failed\n"); | ||
| 110 | } | ||
| 111 | } | ||
| 112 | } | 181 | } |
| 113 | 182 | ||
| 114 | ret = gpiochip_add(&tps65910->gpio); | 183 | platform_set_drvdata(pdev, tps65910_gpio); |
| 184 | |||
| 185 | return ret; | ||
| 186 | } | ||
| 187 | |||
| 188 | static int __devexit tps65910_gpio_remove(struct platform_device *pdev) | ||
| 189 | { | ||
| 190 | struct tps65910_gpio *tps65910_gpio = platform_get_drvdata(pdev); | ||
| 115 | 191 | ||
| 116 | if (ret) | 192 | return gpiochip_remove(&tps65910_gpio->gpio_chip); |
| 117 | dev_warn(tps65910->dev, "GPIO registration failed: %d\n", ret); | ||
| 118 | } | 193 | } |
| 194 | |||
| 195 | static struct platform_driver tps65910_gpio_driver = { | ||
| 196 | .driver.name = "tps65910-gpio", | ||
| 197 | .driver.owner = THIS_MODULE, | ||
| 198 | .probe = tps65910_gpio_probe, | ||
| 199 | .remove = __devexit_p(tps65910_gpio_remove), | ||
| 200 | }; | ||
| 201 | |||
| 202 | static int __init tps65910_gpio_init(void) | ||
| 203 | { | ||
| 204 | return platform_driver_register(&tps65910_gpio_driver); | ||
| 205 | } | ||
| 206 | subsys_initcall(tps65910_gpio_init); | ||
| 207 | |||
| 208 | static void __exit tps65910_gpio_exit(void) | ||
| 209 | { | ||
| 210 | platform_driver_unregister(&tps65910_gpio_driver); | ||
| 211 | } | ||
| 212 | module_exit(tps65910_gpio_exit); | ||
| 213 | |||
| 214 | MODULE_AUTHOR("Graeme Gregory <gg@slimlogic.co.uk>"); | ||
| 215 | MODULE_AUTHOR("Jorge Eduardo Candelaria jedu@slimlogic.co.uk>"); | ||
| 216 | MODULE_DESCRIPTION("GPIO interface for TPS65910/TPS6511 PMICs"); | ||
| 217 | MODULE_LICENSE("GPL v2"); | ||
| 218 | MODULE_ALIAS("platform:tps65910-gpio"); | ||
diff --git a/drivers/gpio/gpio-wm831x.c b/drivers/gpio/gpio-wm831x.c index deb949e75ec1..e56a2165641c 100644 --- a/drivers/gpio/gpio-wm831x.c +++ b/drivers/gpio/gpio-wm831x.c | |||
| @@ -102,10 +102,8 @@ static int wm831x_gpio_to_irq(struct gpio_chip *chip, unsigned offset) | |||
| 102 | struct wm831x_gpio *wm831x_gpio = to_wm831x_gpio(chip); | 102 | struct wm831x_gpio *wm831x_gpio = to_wm831x_gpio(chip); |
| 103 | struct wm831x *wm831x = wm831x_gpio->wm831x; | 103 | struct wm831x *wm831x = wm831x_gpio->wm831x; |
| 104 | 104 | ||
| 105 | if (!wm831x->irq_base) | 105 | return irq_create_mapping(wm831x->irq_domain, |
| 106 | return -EINVAL; | 106 | WM831X_IRQ_GPIO_1 + offset); |
| 107 | |||
| 108 | return wm831x->irq_base + WM831X_IRQ_GPIO_1 + offset; | ||
| 109 | } | 107 | } |
| 110 | 108 | ||
| 111 | static int wm831x_gpio_set_debounce(struct gpio_chip *chip, unsigned offset, | 109 | static int wm831x_gpio_set_debounce(struct gpio_chip *chip, unsigned offset, |
diff --git a/drivers/gpio/gpiolib-of.c b/drivers/gpio/gpiolib-of.c new file mode 100644 index 000000000000..d18068a9f3ec --- /dev/null +++ b/drivers/gpio/gpiolib-of.c | |||
| @@ -0,0 +1,236 @@ | |||
| 1 | /* | ||
| 2 | * OF helpers for the GPIO API | ||
| 3 | * | ||
| 4 | * Copyright (c) 2007-2008 MontaVista Software, Inc. | ||
| 5 | * | ||
| 6 | * Author: Anton Vorontsov <avorontsov@ru.mvista.com> | ||
| 7 | * | ||
| 8 | * This program is free software; you can redistribute it and/or modify | ||
| 9 | * it under the terms of the GNU General Public License as published by | ||
| 10 | * the Free Software Foundation; either version 2 of the License, or | ||
| 11 | * (at your option) any later version. | ||
| 12 | */ | ||
| 13 | |||
| 14 | #include <linux/device.h> | ||
| 15 | #include <linux/errno.h> | ||
| 16 | #include <linux/module.h> | ||
| 17 | #include <linux/io.h> | ||
| 18 | #include <linux/gpio.h> | ||
| 19 | #include <linux/of.h> | ||
| 20 | #include <linux/of_address.h> | ||
| 21 | #include <linux/of_gpio.h> | ||
| 22 | #include <linux/slab.h> | ||
| 23 | |||
| 24 | /* Private data structure for of_gpiochip_is_match */ | ||
| 25 | struct gg_data { | ||
| 26 | enum of_gpio_flags *flags; | ||
| 27 | struct of_phandle_args gpiospec; | ||
| 28 | |||
| 29 | int out_gpio; | ||
| 30 | }; | ||
| 31 | |||
| 32 | /* Private function for resolving node pointer to gpio_chip */ | ||
| 33 | static int of_gpiochip_find_and_xlate(struct gpio_chip *gc, void *data) | ||
| 34 | { | ||
| 35 | struct gg_data *gg_data = data; | ||
| 36 | int ret; | ||
| 37 | |||
| 38 | if ((gc->of_node != gg_data->gpiospec.np) || | ||
| 39 | (gc->of_gpio_n_cells != gg_data->gpiospec.args_count) || | ||
| 40 | (!gc->of_xlate)) | ||
| 41 | return false; | ||
| 42 | |||
| 43 | ret = gc->of_xlate(gc, &gg_data->gpiospec, gg_data->flags); | ||
| 44 | if (ret < 0) | ||
| 45 | return false; | ||
| 46 | |||
| 47 | gg_data->out_gpio = ret + gc->base; | ||
| 48 | return true; | ||
| 49 | } | ||
| 50 | |||
| 51 | /** | ||
| 52 | * of_get_named_gpio_flags() - Get a GPIO number and flags to use with GPIO API | ||
| 53 | * @np: device node to get GPIO from | ||
| 54 | * @propname: property name containing gpio specifier(s) | ||
| 55 | * @index: index of the GPIO | ||
| 56 | * @flags: a flags pointer to fill in | ||
| 57 | * | ||
| 58 | * Returns GPIO number to use with Linux generic GPIO API, or one of the errno | ||
| 59 | * value on the error condition. If @flags is not NULL the function also fills | ||
| 60 | * in flags for the GPIO. | ||
| 61 | */ | ||
| 62 | int of_get_named_gpio_flags(struct device_node *np, const char *propname, | ||
| 63 | int index, enum of_gpio_flags *flags) | ||
| 64 | { | ||
| 65 | struct gg_data gg_data = { .flags = flags, .out_gpio = -ENODEV }; | ||
| 66 | int ret; | ||
| 67 | |||
| 68 | /* .of_xlate might decide to not fill in the flags, so clear it. */ | ||
| 69 | if (flags) | ||
| 70 | *flags = 0; | ||
| 71 | |||
| 72 | ret = of_parse_phandle_with_args(np, propname, "#gpio-cells", index, | ||
| 73 | &gg_data.gpiospec); | ||
| 74 | if (ret) { | ||
| 75 | pr_debug("%s: can't parse gpios property\n", __func__); | ||
| 76 | return -EINVAL; | ||
| 77 | } | ||
| 78 | |||
| 79 | gpiochip_find(&gg_data, of_gpiochip_find_and_xlate); | ||
| 80 | |||
| 81 | of_node_put(gg_data.gpiospec.np); | ||
| 82 | pr_debug("%s exited with status %d\n", __func__, ret); | ||
| 83 | return gg_data.out_gpio; | ||
| 84 | } | ||
| 85 | EXPORT_SYMBOL(of_get_named_gpio_flags); | ||
| 86 | |||
| 87 | /** | ||
| 88 | * of_gpio_named_count - Count GPIOs for a device | ||
| 89 | * @np: device node to count GPIOs for | ||
| 90 | * @propname: property name containing gpio specifier(s) | ||
| 91 | * | ||
| 92 | * The function returns the count of GPIOs specified for a node. | ||
| 93 | * | ||
| 94 | * Note that the empty GPIO specifiers counts too. For example, | ||
| 95 | * | ||
| 96 | * gpios = <0 | ||
| 97 | * &pio1 1 2 | ||
| 98 | * 0 | ||
| 99 | * &pio2 3 4>; | ||
| 100 | * | ||
| 101 | * defines four GPIOs (so this function will return 4), two of which | ||
| 102 | * are not specified. | ||
| 103 | */ | ||
| 104 | unsigned int of_gpio_named_count(struct device_node *np, const char* propname) | ||
| 105 | { | ||
| 106 | unsigned int cnt = 0; | ||
| 107 | |||
| 108 | do { | ||
| 109 | int ret; | ||
| 110 | |||
| 111 | ret = of_parse_phandle_with_args(np, propname, "#gpio-cells", | ||
| 112 | cnt, NULL); | ||
| 113 | /* A hole in the gpios = <> counts anyway. */ | ||
| 114 | if (ret < 0 && ret != -EEXIST) | ||
| 115 | break; | ||
| 116 | } while (++cnt); | ||
| 117 | |||
| 118 | return cnt; | ||
| 119 | } | ||
| 120 | EXPORT_SYMBOL(of_gpio_named_count); | ||
| 121 | |||
| 122 | /** | ||
| 123 | * of_gpio_simple_xlate - translate gpio_spec to the GPIO number and flags | ||
| 124 | * @gc: pointer to the gpio_chip structure | ||
| 125 | * @np: device node of the GPIO chip | ||
| 126 | * @gpio_spec: gpio specifier as found in the device tree | ||
| 127 | * @flags: a flags pointer to fill in | ||
| 128 | * | ||
| 129 | * This is simple translation function, suitable for the most 1:1 mapped | ||
| 130 | * gpio chips. This function performs only one sanity check: whether gpio | ||
| 131 | * is less than ngpios (that is specified in the gpio_chip). | ||
| 132 | */ | ||
| 133 | int of_gpio_simple_xlate(struct gpio_chip *gc, | ||
| 134 | const struct of_phandle_args *gpiospec, u32 *flags) | ||
| 135 | { | ||
| 136 | /* | ||
| 137 | * We're discouraging gpio_cells < 2, since that way you'll have to | ||
| 138 | * write your own xlate function (that will have to retrive the GPIO | ||
| 139 | * number and the flags from a single gpio cell -- this is possible, | ||
| 140 | * but not recommended). | ||
| 141 | */ | ||
| 142 | if (gc->of_gpio_n_cells < 2) { | ||
| 143 | WARN_ON(1); | ||
| 144 | return -EINVAL; | ||
| 145 | } | ||
| 146 | |||
| 147 | if (WARN_ON(gpiospec->args_count < gc->of_gpio_n_cells)) | ||
| 148 | return -EINVAL; | ||
| 149 | |||
| 150 | if (gpiospec->args[0] >= gc->ngpio) | ||
| 151 | return -EINVAL; | ||
| 152 | |||
| 153 | if (flags) | ||
| 154 | *flags = gpiospec->args[1]; | ||
| 155 | |||
| 156 | return gpiospec->args[0]; | ||
| 157 | } | ||
| 158 | EXPORT_SYMBOL(of_gpio_simple_xlate); | ||
| 159 | |||
| 160 | /** | ||
| 161 | * of_mm_gpiochip_add - Add memory mapped GPIO chip (bank) | ||
| 162 | * @np: device node of the GPIO chip | ||
| 163 | * @mm_gc: pointer to the of_mm_gpio_chip allocated structure | ||
| 164 | * | ||
| 165 | * To use this function you should allocate and fill mm_gc with: | ||
| 166 | * | ||
| 167 | * 1) In the gpio_chip structure: | ||
| 168 | * - all the callbacks | ||
| 169 | * - of_gpio_n_cells | ||
| 170 | * - of_xlate callback (optional) | ||
| 171 | * | ||
| 172 | * 3) In the of_mm_gpio_chip structure: | ||
| 173 | * - save_regs callback (optional) | ||
| 174 | * | ||
| 175 | * If succeeded, this function will map bank's memory and will | ||
| 176 | * do all necessary work for you. Then you'll able to use .regs | ||
| 177 | * to manage GPIOs from the callbacks. | ||
| 178 | */ | ||
| 179 | int of_mm_gpiochip_add(struct device_node *np, | ||
| 180 | struct of_mm_gpio_chip *mm_gc) | ||
| 181 | { | ||
| 182 | int ret = -ENOMEM; | ||
| 183 | struct gpio_chip *gc = &mm_gc->gc; | ||
| 184 | |||
| 185 | gc->label = kstrdup(np->full_name, GFP_KERNEL); | ||
| 186 | if (!gc->label) | ||
| 187 | goto err0; | ||
| 188 | |||
| 189 | mm_gc->regs = of_iomap(np, 0); | ||
| 190 | if (!mm_gc->regs) | ||
| 191 | goto err1; | ||
| 192 | |||
| 193 | gc->base = -1; | ||
| 194 | |||
| 195 | if (mm_gc->save_regs) | ||
| 196 | mm_gc->save_regs(mm_gc); | ||
| 197 | |||
| 198 | mm_gc->gc.of_node = np; | ||
| 199 | |||
| 200 | ret = gpiochip_add(gc); | ||
| 201 | if (ret) | ||
| 202 | goto err2; | ||
| 203 | |||
| 204 | return 0; | ||
| 205 | err2: | ||
| 206 | iounmap(mm_gc->regs); | ||
| 207 | err1: | ||
| 208 | kfree(gc->label); | ||
| 209 | err0: | ||
| 210 | pr_err("%s: GPIO chip registration failed with status %d\n", | ||
| 211 | np->full_name, ret); | ||
| 212 | return ret; | ||
| 213 | } | ||
| 214 | EXPORT_SYMBOL(of_mm_gpiochip_add); | ||
| 215 | |||
| 216 | void of_gpiochip_add(struct gpio_chip *chip) | ||
| 217 | { | ||
| 218 | if ((!chip->of_node) && (chip->dev)) | ||
| 219 | chip->of_node = chip->dev->of_node; | ||
| 220 | |||
| 221 | if (!chip->of_node) | ||
| 222 | return; | ||
| 223 | |||
| 224 | if (!chip->of_xlate) { | ||
| 225 | chip->of_gpio_n_cells = 2; | ||
| 226 | chip->of_xlate = of_gpio_simple_xlate; | ||
| 227 | } | ||
| 228 | |||
| 229 | of_node_get(chip->of_node); | ||
| 230 | } | ||
| 231 | |||
| 232 | void of_gpiochip_remove(struct gpio_chip *chip) | ||
| 233 | { | ||
| 234 | if (chip->of_node) | ||
| 235 | of_node_put(chip->of_node); | ||
| 236 | } | ||
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index 5a75510d66bb..120b2a0e3167 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c | |||
| @@ -1093,7 +1093,7 @@ unlock: | |||
| 1093 | if (status) | 1093 | if (status) |
| 1094 | goto fail; | 1094 | goto fail; |
| 1095 | 1095 | ||
| 1096 | pr_info("gpiochip_add: registered GPIOs %d to %d on device: %s\n", | 1096 | pr_debug("gpiochip_add: registered GPIOs %d to %d on device: %s\n", |
| 1097 | chip->base, chip->base + chip->ngpio - 1, | 1097 | chip->base, chip->base + chip->ngpio - 1, |
| 1098 | chip->label ? : "generic"); | 1098 | chip->label ? : "generic"); |
| 1099 | 1099 | ||
| @@ -1154,9 +1154,9 @@ EXPORT_SYMBOL_GPL(gpiochip_remove); | |||
| 1154 | * non-zero, this function will return to the caller and not iterate over any | 1154 | * non-zero, this function will return to the caller and not iterate over any |
| 1155 | * more gpio_chips. | 1155 | * more gpio_chips. |
| 1156 | */ | 1156 | */ |
| 1157 | struct gpio_chip *gpiochip_find(const void *data, | 1157 | struct gpio_chip *gpiochip_find(void *data, |
| 1158 | int (*match)(struct gpio_chip *chip, | 1158 | int (*match)(struct gpio_chip *chip, |
| 1159 | const void *data)) | 1159 | void *data)) |
| 1160 | { | 1160 | { |
| 1161 | struct gpio_chip *chip = NULL; | 1161 | struct gpio_chip *chip = NULL; |
| 1162 | unsigned long flags; | 1162 | unsigned long flags; |
| @@ -1302,8 +1302,18 @@ int gpio_request_one(unsigned gpio, unsigned long flags, const char *label) | |||
| 1302 | (flags & GPIOF_INIT_HIGH) ? 1 : 0); | 1302 | (flags & GPIOF_INIT_HIGH) ? 1 : 0); |
| 1303 | 1303 | ||
| 1304 | if (err) | 1304 | if (err) |
| 1305 | gpio_free(gpio); | 1305 | goto free_gpio; |
| 1306 | |||
| 1307 | if (flags & GPIOF_EXPORT) { | ||
| 1308 | err = gpio_export(gpio, flags & GPIOF_EXPORT_CHANGEABLE); | ||
| 1309 | if (err) | ||
| 1310 | goto free_gpio; | ||
| 1311 | } | ||
| 1312 | |||
| 1313 | return 0; | ||
| 1306 | 1314 | ||
| 1315 | free_gpio: | ||
| 1316 | gpio_free(gpio); | ||
| 1307 | return err; | 1317 | return err; |
| 1308 | } | 1318 | } |
| 1309 | EXPORT_SYMBOL_GPL(gpio_request_one); | 1319 | EXPORT_SYMBOL_GPL(gpio_request_one); |
