diff options
Diffstat (limited to 'drivers/gpio')
68 files changed, 2351 insertions, 455 deletions
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index 47150f5ded04..682de754d63f 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig | |||
@@ -49,6 +49,10 @@ config OF_GPIO | |||
49 | def_bool y | 49 | def_bool y |
50 | depends on OF | 50 | depends on OF |
51 | 51 | ||
52 | config GPIO_ACPI | ||
53 | def_bool y | ||
54 | depends on ACPI | ||
55 | |||
52 | config DEBUG_GPIO | 56 | config DEBUG_GPIO |
53 | bool "Debug GPIO calls" | 57 | bool "Debug GPIO calls" |
54 | depends on DEBUG_KERNEL | 58 | depends on DEBUG_KERNEL |
@@ -86,11 +90,26 @@ config GPIO_DA9052 | |||
86 | help | 90 | help |
87 | Say yes here to enable the GPIO driver for the DA9052 chip. | 91 | Say yes here to enable the GPIO driver for the DA9052 chip. |
88 | 92 | ||
93 | config GPIO_DA9055 | ||
94 | tristate "Dialog Semiconductor DA9055 GPIO" | ||
95 | depends on MFD_DA9055 | ||
96 | help | ||
97 | Say yes here to enable the GPIO driver for the DA9055 chip. | ||
98 | |||
99 | The Dialog DA9055 PMIC chip has 3 GPIO pins that can be | ||
100 | be controller by this driver. | ||
101 | |||
102 | If driver is built as a module it will be called gpio-da9055. | ||
103 | |||
89 | config GPIO_MAX730X | 104 | config GPIO_MAX730X |
90 | tristate | 105 | tristate |
91 | 106 | ||
92 | comment "Memory mapped GPIO drivers:" | 107 | comment "Memory mapped GPIO drivers:" |
93 | 108 | ||
109 | config GPIO_CLPS711X | ||
110 | def_bool y | ||
111 | depends on ARCH_CLPS711X | ||
112 | |||
94 | config GPIO_GENERIC_PLATFORM | 113 | config GPIO_GENERIC_PLATFORM |
95 | tristate "Generic memory-mapped GPIO controller support (MMIO platform device)" | 114 | tristate "Generic memory-mapped GPIO controller support (MMIO platform device)" |
96 | select GPIO_GENERIC | 115 | select GPIO_GENERIC |
@@ -152,7 +171,8 @@ config GPIO_MSM_V2 | |||
152 | 171 | ||
153 | config GPIO_MVEBU | 172 | config GPIO_MVEBU |
154 | def_bool y | 173 | def_bool y |
155 | depends on ARCH_MVEBU | 174 | depends on PLAT_ORION |
175 | depends on OF | ||
156 | select GPIO_GENERIC | 176 | select GPIO_GENERIC |
157 | select GENERIC_IRQ_CHIP | 177 | select GENERIC_IRQ_CHIP |
158 | 178 | ||
@@ -170,7 +190,7 @@ config GPIO_MXS | |||
170 | 190 | ||
171 | config GPIO_PL061 | 191 | config GPIO_PL061 |
172 | bool "PrimeCell PL061 GPIO support" | 192 | bool "PrimeCell PL061 GPIO support" |
173 | depends on ARM_AMBA | 193 | depends on ARM && ARM_AMBA |
174 | select GENERIC_IRQ_CHIP | 194 | select GENERIC_IRQ_CHIP |
175 | help | 195 | help |
176 | Say yes here to support the PrimeCell PL061 GPIO device | 196 | Say yes here to support the PrimeCell PL061 GPIO device |
@@ -181,6 +201,13 @@ config GPIO_PXA | |||
181 | help | 201 | help |
182 | Say yes here to support the PXA GPIO device | 202 | Say yes here to support the PXA GPIO device |
183 | 203 | ||
204 | config GPIO_SPEAR_SPICS | ||
205 | bool "ST SPEAr13xx SPI Chip Select as GPIO support" | ||
206 | depends on PLAT_SPEAR | ||
207 | select GENERIC_IRQ_CHIP | ||
208 | help | ||
209 | Say yes here to support ST SPEAr SPI Chip Select as GPIO device | ||
210 | |||
184 | config GPIO_STA2X11 | 211 | config GPIO_STA2X11 |
185 | bool "STA2x11/ConneXt GPIO support" | 212 | bool "STA2x11/ConneXt GPIO support" |
186 | depends on MFD_STA2X11 | 213 | depends on MFD_STA2X11 |
@@ -189,6 +216,14 @@ config GPIO_STA2X11 | |||
189 | Say yes here to support the STA2x11/ConneXt GPIO device. | 216 | Say yes here to support the STA2x11/ConneXt GPIO device. |
190 | The GPIO module has 128 GPIO pins with alternate functions. | 217 | The GPIO module has 128 GPIO pins with alternate functions. |
191 | 218 | ||
219 | config GPIO_TS5500 | ||
220 | tristate "TS-5500 DIO blocks and compatibles" | ||
221 | help | ||
222 | This driver supports Digital I/O exposed by pin blocks found on some | ||
223 | Technologic Systems platforms. It includes, but is not limited to, 3 | ||
224 | blocks of the TS-5500: DIO1, DIO2 and the LCD port, and the TS-5600 | ||
225 | LCD port. | ||
226 | |||
192 | config GPIO_VT8500 | 227 | config GPIO_VT8500 |
193 | bool "VIA/Wondermedia SoC GPIO Support" | 228 | bool "VIA/Wondermedia SoC GPIO Support" |
194 | depends on ARCH_VT8500 | 229 | depends on ARCH_VT8500 |
@@ -470,7 +505,7 @@ config GPIO_ADNP | |||
470 | help | 505 | help |
471 | This option enables support for N GPIOs found on Avionic Design | 506 | This option enables support for N GPIOs found on Avionic Design |
472 | I2C GPIO expanders. The register space will be extended by powers | 507 | I2C GPIO expanders. The register space will be extended by powers |
473 | of two, so the controller will need to accomodate for that. For | 508 | of two, so the controller will need to accommodate for that. For |
474 | example: if a controller provides 48 pins, 6 registers will be | 509 | example: if a controller provides 48 pins, 6 registers will be |
475 | enough to represent all pins, but the driver will assume a | 510 | enough to represent all pins, but the driver will assume a |
476 | register layout for 64 pins (8 registers). | 511 | register layout for 64 pins (8 registers). |
@@ -649,4 +684,17 @@ config GPIO_MSIC | |||
649 | Enable support for GPIO on intel MSIC controllers found in | 684 | Enable support for GPIO on intel MSIC controllers found in |
650 | intel MID devices | 685 | intel MID devices |
651 | 686 | ||
687 | comment "USB GPIO expanders:" | ||
688 | |||
689 | config GPIO_VIPERBOARD | ||
690 | tristate "Viperboard GPIO a & b support" | ||
691 | depends on MFD_VIPERBOARD && USB | ||
692 | help | ||
693 | Say yes here to access the GPIO signals of Nano River | ||
694 | Technologies Viperboard. There are two GPIO chips on the | ||
695 | board: gpioa and gpiob. | ||
696 | See viperboard API specification and Nano | ||
697 | River Tech's viperboard.h for detailed meaning | ||
698 | of the module parameters. | ||
699 | |||
652 | endif | 700 | endif |
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile index 9aeed6707326..c5aebd008dde 100644 --- a/drivers/gpio/Makefile +++ b/drivers/gpio/Makefile | |||
@@ -4,6 +4,7 @@ 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 | obj-$(CONFIG_OF_GPIO) += gpiolib-of.o |
7 | obj-$(CONFIG_GPIO_ACPI) += gpiolib-acpi.o | ||
7 | 8 | ||
8 | # Device drivers. Generally keep list sorted alphabetically | 9 | # Device drivers. Generally keep list sorted alphabetically |
9 | obj-$(CONFIG_GPIO_GENERIC) += gpio-generic.o | 10 | obj-$(CONFIG_GPIO_GENERIC) += gpio-generic.o |
@@ -16,8 +17,10 @@ obj-$(CONFIG_GPIO_ADP5588) += gpio-adp5588.o | |||
16 | obj-$(CONFIG_GPIO_AMD8111) += gpio-amd8111.o | 17 | obj-$(CONFIG_GPIO_AMD8111) += gpio-amd8111.o |
17 | obj-$(CONFIG_GPIO_ARIZONA) += gpio-arizona.o | 18 | obj-$(CONFIG_GPIO_ARIZONA) += gpio-arizona.o |
18 | obj-$(CONFIG_GPIO_BT8XX) += gpio-bt8xx.o | 19 | obj-$(CONFIG_GPIO_BT8XX) += gpio-bt8xx.o |
20 | obj-$(CONFIG_GPIO_CLPS711X) += gpio-clps711x.o | ||
19 | obj-$(CONFIG_GPIO_CS5535) += gpio-cs5535.o | 21 | obj-$(CONFIG_GPIO_CS5535) += gpio-cs5535.o |
20 | obj-$(CONFIG_GPIO_DA9052) += gpio-da9052.o | 22 | obj-$(CONFIG_GPIO_DA9052) += gpio-da9052.o |
23 | obj-$(CONFIG_GPIO_DA9055) += gpio-da9055.o | ||
21 | obj-$(CONFIG_ARCH_DAVINCI) += gpio-davinci.o | 24 | obj-$(CONFIG_ARCH_DAVINCI) += gpio-davinci.o |
22 | obj-$(CONFIG_GPIO_EM) += gpio-em.o | 25 | obj-$(CONFIG_GPIO_EM) += gpio-em.o |
23 | obj-$(CONFIG_GPIO_EP93XX) += gpio-ep93xx.o | 26 | obj-$(CONFIG_GPIO_EP93XX) += gpio-ep93xx.o |
@@ -57,6 +60,7 @@ obj-$(CONFIG_PLAT_SAMSUNG) += gpio-samsung.o | |||
57 | obj-$(CONFIG_ARCH_SA1100) += gpio-sa1100.o | 60 | obj-$(CONFIG_ARCH_SA1100) += gpio-sa1100.o |
58 | obj-$(CONFIG_GPIO_SCH) += gpio-sch.o | 61 | obj-$(CONFIG_GPIO_SCH) += gpio-sch.o |
59 | obj-$(CONFIG_GPIO_SODAVILLE) += gpio-sodaville.o | 62 | obj-$(CONFIG_GPIO_SODAVILLE) += gpio-sodaville.o |
63 | obj-$(CONFIG_GPIO_SPEAR_SPICS) += gpio-spear-spics.o | ||
60 | obj-$(CONFIG_GPIO_STA2X11) += gpio-sta2x11.o | 64 | obj-$(CONFIG_GPIO_STA2X11) += gpio-sta2x11.o |
61 | obj-$(CONFIG_GPIO_STMPE) += gpio-stmpe.o | 65 | obj-$(CONFIG_GPIO_STMPE) += gpio-stmpe.o |
62 | obj-$(CONFIG_GPIO_STP_XWAY) += gpio-stp-xway.o | 66 | obj-$(CONFIG_GPIO_STP_XWAY) += gpio-stp-xway.o |
@@ -68,9 +72,11 @@ obj-$(CONFIG_ARCH_DAVINCI_TNETV107X) += gpio-tnetv107x.o | |||
68 | obj-$(CONFIG_GPIO_TPS6586X) += gpio-tps6586x.o | 72 | obj-$(CONFIG_GPIO_TPS6586X) += gpio-tps6586x.o |
69 | obj-$(CONFIG_GPIO_TPS65910) += gpio-tps65910.o | 73 | obj-$(CONFIG_GPIO_TPS65910) += gpio-tps65910.o |
70 | obj-$(CONFIG_GPIO_TPS65912) += gpio-tps65912.o | 74 | obj-$(CONFIG_GPIO_TPS65912) += gpio-tps65912.o |
75 | obj-$(CONFIG_GPIO_TS5500) += gpio-ts5500.o | ||
71 | obj-$(CONFIG_GPIO_TWL4030) += gpio-twl4030.o | 76 | obj-$(CONFIG_GPIO_TWL4030) += gpio-twl4030.o |
72 | obj-$(CONFIG_GPIO_TWL6040) += gpio-twl6040.o | 77 | obj-$(CONFIG_GPIO_TWL6040) += gpio-twl6040.o |
73 | obj-$(CONFIG_GPIO_UCB1400) += gpio-ucb1400.o | 78 | obj-$(CONFIG_GPIO_UCB1400) += gpio-ucb1400.o |
79 | obj-$(CONFIG_GPIO_VIPERBOARD) += gpio-viperboard.o | ||
74 | obj-$(CONFIG_GPIO_VR41XX) += gpio-vr41xx.o | 80 | obj-$(CONFIG_GPIO_VR41XX) += gpio-vr41xx.o |
75 | obj-$(CONFIG_GPIO_VT8500) += gpio-vt8500.o | 81 | obj-$(CONFIG_GPIO_VT8500) += gpio-vt8500.o |
76 | obj-$(CONFIG_GPIO_VX855) += gpio-vx855.o | 82 | obj-$(CONFIG_GPIO_VX855) += gpio-vx855.o |
diff --git a/drivers/gpio/gpio-74x164.c b/drivers/gpio/gpio-74x164.c index f05e54258ffb..464be961f605 100644 --- a/drivers/gpio/gpio-74x164.c +++ b/drivers/gpio/gpio-74x164.c | |||
@@ -105,7 +105,7 @@ static int gen_74x164_direction_output(struct gpio_chip *gc, | |||
105 | return 0; | 105 | return 0; |
106 | } | 106 | } |
107 | 107 | ||
108 | static int __devinit gen_74x164_probe(struct spi_device *spi) | 108 | static int gen_74x164_probe(struct spi_device *spi) |
109 | { | 109 | { |
110 | struct gen_74x164_chip *chip; | 110 | struct gen_74x164_chip *chip; |
111 | struct gen_74x164_chip_platform_data *pdata; | 111 | struct gen_74x164_chip_platform_data *pdata; |
@@ -181,7 +181,7 @@ exit_destroy: | |||
181 | return ret; | 181 | return ret; |
182 | } | 182 | } |
183 | 183 | ||
184 | static int __devexit gen_74x164_remove(struct spi_device *spi) | 184 | static int gen_74x164_remove(struct spi_device *spi) |
185 | { | 185 | { |
186 | struct gen_74x164_chip *chip; | 186 | struct gen_74x164_chip *chip; |
187 | int ret; | 187 | int ret; |
@@ -215,7 +215,7 @@ static struct spi_driver gen_74x164_driver = { | |||
215 | .of_match_table = of_match_ptr(gen_74x164_dt_ids), | 215 | .of_match_table = of_match_ptr(gen_74x164_dt_ids), |
216 | }, | 216 | }, |
217 | .probe = gen_74x164_probe, | 217 | .probe = gen_74x164_probe, |
218 | .remove = __devexit_p(gen_74x164_remove), | 218 | .remove = gen_74x164_remove, |
219 | }; | 219 | }; |
220 | module_spi_driver(gen_74x164_driver); | 220 | module_spi_driver(gen_74x164_driver); |
221 | 221 | ||
diff --git a/drivers/gpio/gpio-ab8500.c b/drivers/gpio/gpio-ab8500.c index 050c05d91896..983ad425f0ac 100644 --- a/drivers/gpio/gpio-ab8500.c +++ b/drivers/gpio/gpio-ab8500.c | |||
@@ -402,7 +402,7 @@ static void ab8500_gpio_irq_remove(struct ab8500_gpio *ab8500_gpio) | |||
402 | } | 402 | } |
403 | } | 403 | } |
404 | 404 | ||
405 | static int __devinit ab8500_gpio_probe(struct platform_device *pdev) | 405 | static int ab8500_gpio_probe(struct platform_device *pdev) |
406 | { | 406 | { |
407 | struct ab8500_platform_data *ab8500_pdata = | 407 | struct ab8500_platform_data *ab8500_pdata = |
408 | dev_get_platdata(pdev->dev.parent); | 408 | dev_get_platdata(pdev->dev.parent); |
@@ -474,7 +474,7 @@ out_free: | |||
474 | * ab8500_gpio_remove() - remove Ab8500-gpio driver | 474 | * ab8500_gpio_remove() - remove Ab8500-gpio driver |
475 | * @pdev : Platform device registered | 475 | * @pdev : Platform device registered |
476 | */ | 476 | */ |
477 | static int __devexit ab8500_gpio_remove(struct platform_device *pdev) | 477 | static int ab8500_gpio_remove(struct platform_device *pdev) |
478 | { | 478 | { |
479 | struct ab8500_gpio *ab8500_gpio = platform_get_drvdata(pdev); | 479 | struct ab8500_gpio *ab8500_gpio = platform_get_drvdata(pdev); |
480 | int ret; | 480 | int ret; |
@@ -499,7 +499,7 @@ static struct platform_driver ab8500_gpio_driver = { | |||
499 | .owner = THIS_MODULE, | 499 | .owner = THIS_MODULE, |
500 | }, | 500 | }, |
501 | .probe = ab8500_gpio_probe, | 501 | .probe = ab8500_gpio_probe, |
502 | .remove = __devexit_p(ab8500_gpio_remove), | 502 | .remove = ab8500_gpio_remove, |
503 | }; | 503 | }; |
504 | 504 | ||
505 | static int __init ab8500_gpio_init(void) | 505 | static int __init ab8500_gpio_init(void) |
diff --git a/drivers/gpio/gpio-adnp.c b/drivers/gpio/gpio-adnp.c index 3df88336415e..e60567fc5073 100644 --- a/drivers/gpio/gpio-adnp.c +++ b/drivers/gpio/gpio-adnp.c | |||
@@ -516,7 +516,7 @@ static void adnp_irq_teardown(struct adnp *adnp) | |||
516 | irq_domain_remove(adnp->domain); | 516 | irq_domain_remove(adnp->domain); |
517 | } | 517 | } |
518 | 518 | ||
519 | static __devinit int adnp_i2c_probe(struct i2c_client *client, | 519 | static int adnp_i2c_probe(struct i2c_client *client, |
520 | const struct i2c_device_id *id) | 520 | const struct i2c_device_id *id) |
521 | { | 521 | { |
522 | struct device_node *np = client->dev.of_node; | 522 | struct device_node *np = client->dev.of_node; |
@@ -563,7 +563,7 @@ teardown: | |||
563 | return err; | 563 | return err; |
564 | } | 564 | } |
565 | 565 | ||
566 | static __devexit int adnp_i2c_remove(struct i2c_client *client) | 566 | static int adnp_i2c_remove(struct i2c_client *client) |
567 | { | 567 | { |
568 | struct adnp *adnp = i2c_get_clientdata(client); | 568 | struct adnp *adnp = i2c_get_clientdata(client); |
569 | struct device_node *np = client->dev.of_node; | 569 | struct device_node *np = client->dev.of_node; |
@@ -582,13 +582,13 @@ static __devexit int adnp_i2c_remove(struct i2c_client *client) | |||
582 | return 0; | 582 | return 0; |
583 | } | 583 | } |
584 | 584 | ||
585 | static const struct i2c_device_id adnp_i2c_id[] __devinitconst = { | 585 | static const struct i2c_device_id adnp_i2c_id[] = { |
586 | { "gpio-adnp" }, | 586 | { "gpio-adnp" }, |
587 | { }, | 587 | { }, |
588 | }; | 588 | }; |
589 | MODULE_DEVICE_TABLE(i2c, adnp_i2c_id); | 589 | MODULE_DEVICE_TABLE(i2c, adnp_i2c_id); |
590 | 590 | ||
591 | static const struct of_device_id adnp_of_match[] __devinitconst = { | 591 | static const struct of_device_id adnp_of_match[] = { |
592 | { .compatible = "ad,gpio-adnp", }, | 592 | { .compatible = "ad,gpio-adnp", }, |
593 | { }, | 593 | { }, |
594 | }; | 594 | }; |
@@ -601,7 +601,7 @@ static struct i2c_driver adnp_i2c_driver = { | |||
601 | .of_match_table = of_match_ptr(adnp_of_match), | 601 | .of_match_table = of_match_ptr(adnp_of_match), |
602 | }, | 602 | }, |
603 | .probe = adnp_i2c_probe, | 603 | .probe = adnp_i2c_probe, |
604 | .remove = __devexit_p(adnp_i2c_remove), | 604 | .remove = adnp_i2c_remove, |
605 | .id_table = adnp_i2c_id, | 605 | .id_table = adnp_i2c_id, |
606 | }; | 606 | }; |
607 | module_i2c_driver(adnp_i2c_driver); | 607 | module_i2c_driver(adnp_i2c_driver); |
diff --git a/drivers/gpio/gpio-adp5520.c b/drivers/gpio/gpio-adp5520.c index 2f263cc32561..8afa95f831b1 100644 --- a/drivers/gpio/gpio-adp5520.c +++ b/drivers/gpio/gpio-adp5520.c | |||
@@ -87,7 +87,7 @@ static int adp5520_gpio_direction_output(struct gpio_chip *chip, | |||
87 | return ret; | 87 | return ret; |
88 | } | 88 | } |
89 | 89 | ||
90 | static int __devinit adp5520_gpio_probe(struct platform_device *pdev) | 90 | static int adp5520_gpio_probe(struct platform_device *pdev) |
91 | { | 91 | { |
92 | struct adp5520_gpio_platform_data *pdata = pdev->dev.platform_data; | 92 | struct adp5520_gpio_platform_data *pdata = pdev->dev.platform_data; |
93 | struct adp5520_gpio *dev; | 93 | struct adp5520_gpio *dev; |
@@ -167,7 +167,7 @@ err: | |||
167 | return ret; | 167 | return ret; |
168 | } | 168 | } |
169 | 169 | ||
170 | static int __devexit adp5520_gpio_remove(struct platform_device *pdev) | 170 | static int adp5520_gpio_remove(struct platform_device *pdev) |
171 | { | 171 | { |
172 | struct adp5520_gpio *dev; | 172 | struct adp5520_gpio *dev; |
173 | int ret; | 173 | int ret; |
@@ -190,7 +190,7 @@ static struct platform_driver adp5520_gpio_driver = { | |||
190 | .owner = THIS_MODULE, | 190 | .owner = THIS_MODULE, |
191 | }, | 191 | }, |
192 | .probe = adp5520_gpio_probe, | 192 | .probe = adp5520_gpio_probe, |
193 | .remove = __devexit_p(adp5520_gpio_remove), | 193 | .remove = adp5520_gpio_remove, |
194 | }; | 194 | }; |
195 | 195 | ||
196 | module_platform_driver(adp5520_gpio_driver); | 196 | module_platform_driver(adp5520_gpio_driver); |
diff --git a/drivers/gpio/gpio-adp5588.c b/drivers/gpio/gpio-adp5588.c index eeedad42913e..2ba56987db04 100644 --- a/drivers/gpio/gpio-adp5588.c +++ b/drivers/gpio/gpio-adp5588.c | |||
@@ -346,7 +346,7 @@ static void adp5588_irq_teardown(struct adp5588_gpio *dev) | |||
346 | } | 346 | } |
347 | #endif /* CONFIG_GPIO_ADP5588_IRQ */ | 347 | #endif /* CONFIG_GPIO_ADP5588_IRQ */ |
348 | 348 | ||
349 | static int __devinit adp5588_gpio_probe(struct i2c_client *client, | 349 | static int adp5588_gpio_probe(struct i2c_client *client, |
350 | const struct i2c_device_id *id) | 350 | const struct i2c_device_id *id) |
351 | { | 351 | { |
352 | struct adp5588_gpio_platform_data *pdata = client->dev.platform_data; | 352 | struct adp5588_gpio_platform_data *pdata = client->dev.platform_data; |
@@ -438,7 +438,7 @@ err: | |||
438 | return ret; | 438 | return ret; |
439 | } | 439 | } |
440 | 440 | ||
441 | static int __devexit adp5588_gpio_remove(struct i2c_client *client) | 441 | static int adp5588_gpio_remove(struct i2c_client *client) |
442 | { | 442 | { |
443 | struct adp5588_gpio_platform_data *pdata = client->dev.platform_data; | 443 | struct adp5588_gpio_platform_data *pdata = client->dev.platform_data; |
444 | struct adp5588_gpio *dev = i2c_get_clientdata(client); | 444 | struct adp5588_gpio *dev = i2c_get_clientdata(client); |
@@ -479,7 +479,7 @@ static struct i2c_driver adp5588_gpio_driver = { | |||
479 | .name = DRV_NAME, | 479 | .name = DRV_NAME, |
480 | }, | 480 | }, |
481 | .probe = adp5588_gpio_probe, | 481 | .probe = adp5588_gpio_probe, |
482 | .remove = __devexit_p(adp5588_gpio_remove), | 482 | .remove = adp5588_gpio_remove, |
483 | .id_table = adp5588_gpio_id, | 483 | .id_table = adp5588_gpio_id, |
484 | }; | 484 | }; |
485 | 485 | ||
diff --git a/drivers/gpio/gpio-arizona.c b/drivers/gpio/gpio-arizona.c index 8740d2eb06f8..0ea853f68db2 100644 --- a/drivers/gpio/gpio-arizona.c +++ b/drivers/gpio/gpio-arizona.c | |||
@@ -94,7 +94,7 @@ static struct gpio_chip template_chip = { | |||
94 | .can_sleep = 1, | 94 | .can_sleep = 1, |
95 | }; | 95 | }; |
96 | 96 | ||
97 | static int __devinit arizona_gpio_probe(struct platform_device *pdev) | 97 | static int arizona_gpio_probe(struct platform_device *pdev) |
98 | { | 98 | { |
99 | struct arizona *arizona = dev_get_drvdata(pdev->dev.parent); | 99 | struct arizona *arizona = dev_get_drvdata(pdev->dev.parent); |
100 | struct arizona_pdata *pdata = arizona->dev->platform_data; | 100 | struct arizona_pdata *pdata = arizona->dev->platform_data; |
@@ -141,7 +141,7 @@ err: | |||
141 | return ret; | 141 | return ret; |
142 | } | 142 | } |
143 | 143 | ||
144 | static int __devexit arizona_gpio_remove(struct platform_device *pdev) | 144 | static int arizona_gpio_remove(struct platform_device *pdev) |
145 | { | 145 | { |
146 | struct arizona_gpio *arizona_gpio = platform_get_drvdata(pdev); | 146 | struct arizona_gpio *arizona_gpio = platform_get_drvdata(pdev); |
147 | 147 | ||
@@ -152,7 +152,7 @@ static struct platform_driver arizona_gpio_driver = { | |||
152 | .driver.name = "arizona-gpio", | 152 | .driver.name = "arizona-gpio", |
153 | .driver.owner = THIS_MODULE, | 153 | .driver.owner = THIS_MODULE, |
154 | .probe = arizona_gpio_probe, | 154 | .probe = arizona_gpio_probe, |
155 | .remove = __devexit_p(arizona_gpio_remove), | 155 | .remove = arizona_gpio_remove, |
156 | }; | 156 | }; |
157 | 157 | ||
158 | module_platform_driver(arizona_gpio_driver); | 158 | module_platform_driver(arizona_gpio_driver); |
diff --git a/drivers/gpio/gpio-clps711x.c b/drivers/gpio/gpio-clps711x.c new file mode 100644 index 000000000000..ce63b75b13f5 --- /dev/null +++ b/drivers/gpio/gpio-clps711x.c | |||
@@ -0,0 +1,199 @@ | |||
1 | /* | ||
2 | * CLPS711X GPIO driver | ||
3 | * | ||
4 | * Copyright (C) 2012 Alexander Shiyan <shc_work@mail.ru> | ||
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 | |||
12 | #include <linux/io.h> | ||
13 | #include <linux/slab.h> | ||
14 | #include <linux/gpio.h> | ||
15 | #include <linux/module.h> | ||
16 | #include <linux/spinlock.h> | ||
17 | #include <linux/platform_device.h> | ||
18 | |||
19 | #include <mach/hardware.h> | ||
20 | |||
21 | #define CLPS711X_GPIO_PORTS 5 | ||
22 | #define CLPS711X_GPIO_NAME "gpio-clps711x" | ||
23 | |||
24 | struct clps711x_gpio { | ||
25 | struct gpio_chip chip[CLPS711X_GPIO_PORTS]; | ||
26 | spinlock_t lock; | ||
27 | }; | ||
28 | |||
29 | static void __iomem *clps711x_ports[] = { | ||
30 | CLPS711X_VIRT_BASE + PADR, | ||
31 | CLPS711X_VIRT_BASE + PBDR, | ||
32 | CLPS711X_VIRT_BASE + PCDR, | ||
33 | CLPS711X_VIRT_BASE + PDDR, | ||
34 | CLPS711X_VIRT_BASE + PEDR, | ||
35 | }; | ||
36 | |||
37 | static void __iomem *clps711x_pdirs[] = { | ||
38 | CLPS711X_VIRT_BASE + PADDR, | ||
39 | CLPS711X_VIRT_BASE + PBDDR, | ||
40 | CLPS711X_VIRT_BASE + PCDDR, | ||
41 | CLPS711X_VIRT_BASE + PDDDR, | ||
42 | CLPS711X_VIRT_BASE + PEDDR, | ||
43 | }; | ||
44 | |||
45 | #define clps711x_port(x) clps711x_ports[x->base / 8] | ||
46 | #define clps711x_pdir(x) clps711x_pdirs[x->base / 8] | ||
47 | |||
48 | static int gpio_clps711x_get(struct gpio_chip *chip, unsigned offset) | ||
49 | { | ||
50 | return !!(readb(clps711x_port(chip)) & (1 << offset)); | ||
51 | } | ||
52 | |||
53 | static void gpio_clps711x_set(struct gpio_chip *chip, unsigned offset, | ||
54 | int value) | ||
55 | { | ||
56 | int tmp; | ||
57 | unsigned long flags; | ||
58 | struct clps711x_gpio *gpio = dev_get_drvdata(chip->dev); | ||
59 | |||
60 | spin_lock_irqsave(&gpio->lock, flags); | ||
61 | tmp = readb(clps711x_port(chip)) & ~(1 << offset); | ||
62 | if (value) | ||
63 | tmp |= 1 << offset; | ||
64 | writeb(tmp, clps711x_port(chip)); | ||
65 | spin_unlock_irqrestore(&gpio->lock, flags); | ||
66 | } | ||
67 | |||
68 | static int gpio_clps711x_dir_in(struct gpio_chip *chip, unsigned offset) | ||
69 | { | ||
70 | int tmp; | ||
71 | unsigned long flags; | ||
72 | struct clps711x_gpio *gpio = dev_get_drvdata(chip->dev); | ||
73 | |||
74 | spin_lock_irqsave(&gpio->lock, flags); | ||
75 | tmp = readb(clps711x_pdir(chip)) & ~(1 << offset); | ||
76 | writeb(tmp, clps711x_pdir(chip)); | ||
77 | spin_unlock_irqrestore(&gpio->lock, flags); | ||
78 | |||
79 | return 0; | ||
80 | } | ||
81 | |||
82 | static int gpio_clps711x_dir_out(struct gpio_chip *chip, unsigned offset, | ||
83 | int value) | ||
84 | { | ||
85 | int tmp; | ||
86 | unsigned long flags; | ||
87 | struct clps711x_gpio *gpio = dev_get_drvdata(chip->dev); | ||
88 | |||
89 | spin_lock_irqsave(&gpio->lock, flags); | ||
90 | tmp = readb(clps711x_pdir(chip)) | (1 << offset); | ||
91 | writeb(tmp, clps711x_pdir(chip)); | ||
92 | tmp = readb(clps711x_port(chip)) & ~(1 << offset); | ||
93 | if (value) | ||
94 | tmp |= 1 << offset; | ||
95 | writeb(tmp, clps711x_port(chip)); | ||
96 | spin_unlock_irqrestore(&gpio->lock, flags); | ||
97 | |||
98 | return 0; | ||
99 | } | ||
100 | |||
101 | static int gpio_clps711x_dir_in_inv(struct gpio_chip *chip, unsigned offset) | ||
102 | { | ||
103 | int tmp; | ||
104 | unsigned long flags; | ||
105 | struct clps711x_gpio *gpio = dev_get_drvdata(chip->dev); | ||
106 | |||
107 | spin_lock_irqsave(&gpio->lock, flags); | ||
108 | tmp = readb(clps711x_pdir(chip)) | (1 << offset); | ||
109 | writeb(tmp, clps711x_pdir(chip)); | ||
110 | spin_unlock_irqrestore(&gpio->lock, flags); | ||
111 | |||
112 | return 0; | ||
113 | } | ||
114 | |||
115 | static int gpio_clps711x_dir_out_inv(struct gpio_chip *chip, unsigned offset, | ||
116 | int value) | ||
117 | { | ||
118 | int tmp; | ||
119 | unsigned long flags; | ||
120 | struct clps711x_gpio *gpio = dev_get_drvdata(chip->dev); | ||
121 | |||
122 | spin_lock_irqsave(&gpio->lock, flags); | ||
123 | tmp = readb(clps711x_pdir(chip)) & ~(1 << offset); | ||
124 | writeb(tmp, clps711x_pdir(chip)); | ||
125 | tmp = readb(clps711x_port(chip)) & ~(1 << offset); | ||
126 | if (value) | ||
127 | tmp |= 1 << offset; | ||
128 | writeb(tmp, clps711x_port(chip)); | ||
129 | spin_unlock_irqrestore(&gpio->lock, flags); | ||
130 | |||
131 | return 0; | ||
132 | } | ||
133 | |||
134 | static struct { | ||
135 | char *name; | ||
136 | int nr; | ||
137 | int inv_dir; | ||
138 | } clps711x_gpio_ports[] __initconst = { | ||
139 | { "PORTA", 8, 0, }, | ||
140 | { "PORTB", 8, 0, }, | ||
141 | { "PORTC", 8, 0, }, | ||
142 | { "PORTD", 8, 1, }, | ||
143 | { "PORTE", 3, 0, }, | ||
144 | }; | ||
145 | |||
146 | static int __init gpio_clps711x_init(void) | ||
147 | { | ||
148 | int i; | ||
149 | struct platform_device *pdev; | ||
150 | struct clps711x_gpio *gpio; | ||
151 | |||
152 | pdev = platform_device_alloc(CLPS711X_GPIO_NAME, 0); | ||
153 | if (!pdev) { | ||
154 | pr_err("Cannot create platform device: %s\n", | ||
155 | CLPS711X_GPIO_NAME); | ||
156 | return -ENOMEM; | ||
157 | } | ||
158 | |||
159 | platform_device_add(pdev); | ||
160 | |||
161 | gpio = devm_kzalloc(&pdev->dev, sizeof(struct clps711x_gpio), | ||
162 | GFP_KERNEL); | ||
163 | if (!gpio) { | ||
164 | dev_err(&pdev->dev, "GPIO allocating memory error\n"); | ||
165 | platform_device_unregister(pdev); | ||
166 | return -ENOMEM; | ||
167 | } | ||
168 | |||
169 | platform_set_drvdata(pdev, gpio); | ||
170 | |||
171 | spin_lock_init(&gpio->lock); | ||
172 | |||
173 | for (i = 0; i < CLPS711X_GPIO_PORTS; i++) { | ||
174 | gpio->chip[i].owner = THIS_MODULE; | ||
175 | gpio->chip[i].dev = &pdev->dev; | ||
176 | gpio->chip[i].label = clps711x_gpio_ports[i].name; | ||
177 | gpio->chip[i].base = i * 8; | ||
178 | gpio->chip[i].ngpio = clps711x_gpio_ports[i].nr; | ||
179 | gpio->chip[i].get = gpio_clps711x_get; | ||
180 | gpio->chip[i].set = gpio_clps711x_set; | ||
181 | if (!clps711x_gpio_ports[i].inv_dir) { | ||
182 | gpio->chip[i].direction_input = gpio_clps711x_dir_in; | ||
183 | gpio->chip[i].direction_output = gpio_clps711x_dir_out; | ||
184 | } else { | ||
185 | gpio->chip[i].direction_input = gpio_clps711x_dir_in_inv; | ||
186 | gpio->chip[i].direction_output = gpio_clps711x_dir_out_inv; | ||
187 | } | ||
188 | WARN_ON(gpiochip_add(&gpio->chip[i])); | ||
189 | } | ||
190 | |||
191 | dev_info(&pdev->dev, "GPIO driver initialized\n"); | ||
192 | |||
193 | return 0; | ||
194 | } | ||
195 | arch_initcall(gpio_clps711x_init); | ||
196 | |||
197 | MODULE_LICENSE("GPL v2"); | ||
198 | MODULE_AUTHOR("Alexander Shiyan <shc_work@mail.ru>"); | ||
199 | MODULE_DESCRIPTION("CLPS711X GPIO driver"); | ||
diff --git a/drivers/gpio/gpio-cs5535.c b/drivers/gpio/gpio-cs5535.c index 19eda1bbe343..c0a3aeba6f21 100644 --- a/drivers/gpio/gpio-cs5535.c +++ b/drivers/gpio/gpio-cs5535.c | |||
@@ -300,7 +300,7 @@ static struct cs5535_gpio_chip cs5535_gpio_chip = { | |||
300 | }, | 300 | }, |
301 | }; | 301 | }; |
302 | 302 | ||
303 | static int __devinit cs5535_gpio_probe(struct platform_device *pdev) | 303 | static int cs5535_gpio_probe(struct platform_device *pdev) |
304 | { | 304 | { |
305 | struct resource *res; | 305 | struct resource *res; |
306 | int err = -EIO; | 306 | int err = -EIO; |
@@ -355,7 +355,7 @@ done: | |||
355 | return err; | 355 | return err; |
356 | } | 356 | } |
357 | 357 | ||
358 | static int __devexit cs5535_gpio_remove(struct platform_device *pdev) | 358 | static int cs5535_gpio_remove(struct platform_device *pdev) |
359 | { | 359 | { |
360 | struct resource *r; | 360 | struct resource *r; |
361 | int err; | 361 | int err; |
@@ -378,7 +378,7 @@ static struct platform_driver cs5535_gpio_driver = { | |||
378 | .owner = THIS_MODULE, | 378 | .owner = THIS_MODULE, |
379 | }, | 379 | }, |
380 | .probe = cs5535_gpio_probe, | 380 | .probe = cs5535_gpio_probe, |
381 | .remove = __devexit_p(cs5535_gpio_remove), | 381 | .remove = cs5535_gpio_remove, |
382 | }; | 382 | }; |
383 | 383 | ||
384 | module_platform_driver(cs5535_gpio_driver); | 384 | module_platform_driver(cs5535_gpio_driver); |
diff --git a/drivers/gpio/gpio-da9052.c b/drivers/gpio/gpio-da9052.c index 24b8c2974047..29b11e9b6a78 100644 --- a/drivers/gpio/gpio-da9052.c +++ b/drivers/gpio/gpio-da9052.c | |||
@@ -185,10 +185,14 @@ static int da9052_gpio_to_irq(struct gpio_chip *gc, u32 offset) | |||
185 | struct da9052_gpio *gpio = to_da9052_gpio(gc); | 185 | struct da9052_gpio *gpio = to_da9052_gpio(gc); |
186 | struct da9052 *da9052 = gpio->da9052; | 186 | struct da9052 *da9052 = gpio->da9052; |
187 | 187 | ||
188 | return da9052->irq_base + DA9052_IRQ_GPI0 + offset; | 188 | int irq; |
189 | |||
190 | irq = regmap_irq_get_virq(da9052->irq_data, DA9052_IRQ_GPI0 + offset); | ||
191 | |||
192 | return irq; | ||
189 | } | 193 | } |
190 | 194 | ||
191 | static struct gpio_chip reference_gp __devinitdata = { | 195 | static struct gpio_chip reference_gp = { |
192 | .label = "da9052-gpio", | 196 | .label = "da9052-gpio", |
193 | .owner = THIS_MODULE, | 197 | .owner = THIS_MODULE, |
194 | .get = da9052_gpio_get, | 198 | .get = da9052_gpio_get, |
@@ -201,7 +205,7 @@ static struct gpio_chip reference_gp __devinitdata = { | |||
201 | .base = -1, | 205 | .base = -1, |
202 | }; | 206 | }; |
203 | 207 | ||
204 | static int __devinit da9052_gpio_probe(struct platform_device *pdev) | 208 | static int da9052_gpio_probe(struct platform_device *pdev) |
205 | { | 209 | { |
206 | struct da9052_gpio *gpio; | 210 | struct da9052_gpio *gpio; |
207 | struct da9052_pdata *pdata; | 211 | struct da9052_pdata *pdata; |
@@ -229,7 +233,7 @@ static int __devinit da9052_gpio_probe(struct platform_device *pdev) | |||
229 | return 0; | 233 | return 0; |
230 | } | 234 | } |
231 | 235 | ||
232 | static int __devexit da9052_gpio_remove(struct platform_device *pdev) | 236 | static int da9052_gpio_remove(struct platform_device *pdev) |
233 | { | 237 | { |
234 | struct da9052_gpio *gpio = platform_get_drvdata(pdev); | 238 | struct da9052_gpio *gpio = platform_get_drvdata(pdev); |
235 | 239 | ||
@@ -238,7 +242,7 @@ static int __devexit da9052_gpio_remove(struct platform_device *pdev) | |||
238 | 242 | ||
239 | static struct platform_driver da9052_gpio_driver = { | 243 | static struct platform_driver da9052_gpio_driver = { |
240 | .probe = da9052_gpio_probe, | 244 | .probe = da9052_gpio_probe, |
241 | .remove = __devexit_p(da9052_gpio_remove), | 245 | .remove = da9052_gpio_remove, |
242 | .driver = { | 246 | .driver = { |
243 | .name = "da9052-gpio", | 247 | .name = "da9052-gpio", |
244 | .owner = THIS_MODULE, | 248 | .owner = THIS_MODULE, |
diff --git a/drivers/gpio/gpio-da9055.c b/drivers/gpio/gpio-da9055.c new file mode 100644 index 000000000000..55d83c7d9c7f --- /dev/null +++ b/drivers/gpio/gpio-da9055.c | |||
@@ -0,0 +1,204 @@ | |||
1 | /* | ||
2 | * GPIO Driver for Dialog DA9055 PMICs. | ||
3 | * | ||
4 | * Copyright(c) 2012 Dialog Semiconductor Ltd. | ||
5 | * | ||
6 | * Author: David Dajun Chen <dchen@diasemi.com> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify it | ||
9 | * under the terms of the GNU General Public License as published by the | ||
10 | * Free Software Foundation; either version 2 of the License, or (at your | ||
11 | * option) any later version. | ||
12 | * | ||
13 | */ | ||
14 | #include <linux/module.h> | ||
15 | #include <linux/platform_device.h> | ||
16 | #include <linux/gpio.h> | ||
17 | |||
18 | #include <linux/mfd/da9055/core.h> | ||
19 | #include <linux/mfd/da9055/reg.h> | ||
20 | #include <linux/mfd/da9055/pdata.h> | ||
21 | |||
22 | #define DA9055_VDD_IO 0x0 | ||
23 | #define DA9055_PUSH_PULL 0x3 | ||
24 | #define DA9055_ACT_LOW 0x0 | ||
25 | #define DA9055_GPI 0x1 | ||
26 | #define DA9055_PORT_MASK 0x3 | ||
27 | #define DA9055_PORT_SHIFT(offset) (4 * (offset % 2)) | ||
28 | |||
29 | #define DA9055_INPUT DA9055_GPI | ||
30 | #define DA9055_OUTPUT DA9055_PUSH_PULL | ||
31 | #define DA9055_IRQ_GPI0 3 | ||
32 | |||
33 | struct da9055_gpio { | ||
34 | struct da9055 *da9055; | ||
35 | struct gpio_chip gp; | ||
36 | }; | ||
37 | |||
38 | static inline struct da9055_gpio *to_da9055_gpio(struct gpio_chip *chip) | ||
39 | { | ||
40 | return container_of(chip, struct da9055_gpio, gp); | ||
41 | } | ||
42 | |||
43 | static int da9055_gpio_get(struct gpio_chip *gc, unsigned offset) | ||
44 | { | ||
45 | struct da9055_gpio *gpio = to_da9055_gpio(gc); | ||
46 | int gpio_direction = 0; | ||
47 | int ret; | ||
48 | |||
49 | /* Get GPIO direction */ | ||
50 | ret = da9055_reg_read(gpio->da9055, (offset >> 1) + DA9055_REG_GPIO0_1); | ||
51 | if (ret < 0) | ||
52 | return ret; | ||
53 | |||
54 | gpio_direction = ret & (DA9055_PORT_MASK) << DA9055_PORT_SHIFT(offset); | ||
55 | gpio_direction >>= DA9055_PORT_SHIFT(offset); | ||
56 | switch (gpio_direction) { | ||
57 | case DA9055_INPUT: | ||
58 | ret = da9055_reg_read(gpio->da9055, DA9055_REG_STATUS_B); | ||
59 | if (ret < 0) | ||
60 | return ret; | ||
61 | break; | ||
62 | case DA9055_OUTPUT: | ||
63 | ret = da9055_reg_read(gpio->da9055, DA9055_REG_GPIO_MODE0_2); | ||
64 | if (ret < 0) | ||
65 | return ret; | ||
66 | } | ||
67 | |||
68 | return ret & (1 << offset); | ||
69 | |||
70 | } | ||
71 | |||
72 | static void da9055_gpio_set(struct gpio_chip *gc, unsigned offset, int value) | ||
73 | { | ||
74 | struct da9055_gpio *gpio = to_da9055_gpio(gc); | ||
75 | |||
76 | da9055_reg_update(gpio->da9055, | ||
77 | DA9055_REG_GPIO_MODE0_2, | ||
78 | 1 << offset, | ||
79 | value << offset); | ||
80 | } | ||
81 | |||
82 | static int da9055_gpio_direction_input(struct gpio_chip *gc, unsigned offset) | ||
83 | { | ||
84 | struct da9055_gpio *gpio = to_da9055_gpio(gc); | ||
85 | unsigned char reg_byte; | ||
86 | |||
87 | reg_byte = (DA9055_ACT_LOW | DA9055_GPI) | ||
88 | << DA9055_PORT_SHIFT(offset); | ||
89 | |||
90 | return da9055_reg_update(gpio->da9055, (offset >> 1) + | ||
91 | DA9055_REG_GPIO0_1, | ||
92 | DA9055_PORT_MASK << | ||
93 | DA9055_PORT_SHIFT(offset), | ||
94 | reg_byte); | ||
95 | } | ||
96 | |||
97 | static int da9055_gpio_direction_output(struct gpio_chip *gc, | ||
98 | unsigned offset, int value) | ||
99 | { | ||
100 | struct da9055_gpio *gpio = to_da9055_gpio(gc); | ||
101 | unsigned char reg_byte; | ||
102 | int ret; | ||
103 | |||
104 | reg_byte = (DA9055_VDD_IO | DA9055_PUSH_PULL) | ||
105 | << DA9055_PORT_SHIFT(offset); | ||
106 | |||
107 | ret = da9055_reg_update(gpio->da9055, (offset >> 1) + | ||
108 | DA9055_REG_GPIO0_1, | ||
109 | DA9055_PORT_MASK << | ||
110 | DA9055_PORT_SHIFT(offset), | ||
111 | reg_byte); | ||
112 | if (ret < 0) | ||
113 | return ret; | ||
114 | |||
115 | da9055_gpio_set(gc, offset, value); | ||
116 | |||
117 | return 0; | ||
118 | } | ||
119 | |||
120 | static int da9055_gpio_to_irq(struct gpio_chip *gc, u32 offset) | ||
121 | { | ||
122 | struct da9055_gpio *gpio = to_da9055_gpio(gc); | ||
123 | struct da9055 *da9055 = gpio->da9055; | ||
124 | |||
125 | return regmap_irq_get_virq(da9055->irq_data, | ||
126 | DA9055_IRQ_GPI0 + offset); | ||
127 | } | ||
128 | |||
129 | static struct gpio_chip reference_gp __devinitdata = { | ||
130 | .label = "da9055-gpio", | ||
131 | .owner = THIS_MODULE, | ||
132 | .get = da9055_gpio_get, | ||
133 | .set = da9055_gpio_set, | ||
134 | .direction_input = da9055_gpio_direction_input, | ||
135 | .direction_output = da9055_gpio_direction_output, | ||
136 | .to_irq = da9055_gpio_to_irq, | ||
137 | .can_sleep = 1, | ||
138 | .ngpio = 3, | ||
139 | .base = -1, | ||
140 | }; | ||
141 | |||
142 | static int __devinit da9055_gpio_probe(struct platform_device *pdev) | ||
143 | { | ||
144 | struct da9055_gpio *gpio; | ||
145 | struct da9055_pdata *pdata; | ||
146 | int ret; | ||
147 | |||
148 | gpio = devm_kzalloc(&pdev->dev, sizeof(*gpio), GFP_KERNEL); | ||
149 | if (gpio == NULL) | ||
150 | return -ENOMEM; | ||
151 | |||
152 | gpio->da9055 = dev_get_drvdata(pdev->dev.parent); | ||
153 | pdata = gpio->da9055->dev->platform_data; | ||
154 | |||
155 | gpio->gp = reference_gp; | ||
156 | if (pdata && pdata->gpio_base) | ||
157 | gpio->gp.base = pdata->gpio_base; | ||
158 | |||
159 | ret = gpiochip_add(&gpio->gp); | ||
160 | if (ret < 0) { | ||
161 | dev_err(&pdev->dev, "Could not register gpiochip, %d\n", ret); | ||
162 | goto err_mem; | ||
163 | } | ||
164 | |||
165 | platform_set_drvdata(pdev, gpio); | ||
166 | |||
167 | return 0; | ||
168 | |||
169 | err_mem: | ||
170 | return ret; | ||
171 | } | ||
172 | |||
173 | static int __devexit da9055_gpio_remove(struct platform_device *pdev) | ||
174 | { | ||
175 | struct da9055_gpio *gpio = platform_get_drvdata(pdev); | ||
176 | |||
177 | return gpiochip_remove(&gpio->gp); | ||
178 | } | ||
179 | |||
180 | static struct platform_driver da9055_gpio_driver = { | ||
181 | .probe = da9055_gpio_probe, | ||
182 | .remove = __devexit_p(da9055_gpio_remove), | ||
183 | .driver = { | ||
184 | .name = "da9055-gpio", | ||
185 | .owner = THIS_MODULE, | ||
186 | }, | ||
187 | }; | ||
188 | |||
189 | static int __init da9055_gpio_init(void) | ||
190 | { | ||
191 | return platform_driver_register(&da9055_gpio_driver); | ||
192 | } | ||
193 | subsys_initcall(da9055_gpio_init); | ||
194 | |||
195 | static void __exit da9055_gpio_exit(void) | ||
196 | { | ||
197 | platform_driver_unregister(&da9055_gpio_driver); | ||
198 | } | ||
199 | module_exit(da9055_gpio_exit); | ||
200 | |||
201 | MODULE_AUTHOR("David Dajun Chen <dchen@diasemi.com>"); | ||
202 | MODULE_DESCRIPTION("DA9055 GPIO Device Driver"); | ||
203 | MODULE_LICENSE("GPL"); | ||
204 | MODULE_ALIAS("platform:da9055-gpio"); | ||
diff --git a/drivers/gpio/gpio-em.c b/drivers/gpio/gpio-em.c index efb4c2d0d132..bdc8302e711a 100644 --- a/drivers/gpio/gpio-em.c +++ b/drivers/gpio/gpio-em.c | |||
@@ -35,7 +35,6 @@ | |||
35 | struct em_gio_priv { | 35 | struct em_gio_priv { |
36 | void __iomem *base0; | 36 | void __iomem *base0; |
37 | void __iomem *base1; | 37 | void __iomem *base1; |
38 | unsigned int irq_base; | ||
39 | spinlock_t sense_lock; | 38 | spinlock_t sense_lock; |
40 | struct platform_device *pdev; | 39 | struct platform_device *pdev; |
41 | struct gpio_chip gpio_chip; | 40 | struct gpio_chip gpio_chip; |
@@ -214,7 +213,7 @@ static int em_gio_direction_output(struct gpio_chip *chip, unsigned offset, | |||
214 | 213 | ||
215 | static int em_gio_to_irq(struct gpio_chip *chip, unsigned offset) | 214 | static int em_gio_to_irq(struct gpio_chip *chip, unsigned offset) |
216 | { | 215 | { |
217 | return irq_find_mapping(gpio_to_priv(chip)->irq_domain, offset); | 216 | return irq_create_mapping(gpio_to_priv(chip)->irq_domain, offset); |
218 | } | 217 | } |
219 | 218 | ||
220 | static int em_gio_irq_domain_map(struct irq_domain *h, unsigned int virq, | 219 | static int em_gio_irq_domain_map(struct irq_domain *h, unsigned int virq, |
@@ -234,41 +233,7 @@ static struct irq_domain_ops em_gio_irq_domain_ops = { | |||
234 | .map = em_gio_irq_domain_map, | 233 | .map = em_gio_irq_domain_map, |
235 | }; | 234 | }; |
236 | 235 | ||
237 | static int __devinit em_gio_irq_domain_init(struct em_gio_priv *p) | 236 | static int em_gio_probe(struct platform_device *pdev) |
238 | { | ||
239 | struct platform_device *pdev = p->pdev; | ||
240 | struct gpio_em_config *pdata = pdev->dev.platform_data; | ||
241 | |||
242 | p->irq_base = irq_alloc_descs(pdata->irq_base, 0, | ||
243 | pdata->number_of_pins, numa_node_id()); | ||
244 | if (p->irq_base < 0) { | ||
245 | dev_err(&pdev->dev, "cannot get irq_desc\n"); | ||
246 | return p->irq_base; | ||
247 | } | ||
248 | pr_debug("gio: hw base = %d, nr = %d, sw base = %d\n", | ||
249 | pdata->gpio_base, pdata->number_of_pins, p->irq_base); | ||
250 | |||
251 | p->irq_domain = irq_domain_add_legacy(pdev->dev.of_node, | ||
252 | pdata->number_of_pins, | ||
253 | p->irq_base, 0, | ||
254 | &em_gio_irq_domain_ops, p); | ||
255 | if (!p->irq_domain) { | ||
256 | irq_free_descs(p->irq_base, pdata->number_of_pins); | ||
257 | return -ENXIO; | ||
258 | } | ||
259 | |||
260 | return 0; | ||
261 | } | ||
262 | |||
263 | static void em_gio_irq_domain_cleanup(struct em_gio_priv *p) | ||
264 | { | ||
265 | struct gpio_em_config *pdata = p->pdev->dev.platform_data; | ||
266 | |||
267 | irq_free_descs(p->irq_base, pdata->number_of_pins); | ||
268 | /* FIXME: irq domain wants to be freed! */ | ||
269 | } | ||
270 | |||
271 | static int __devinit em_gio_probe(struct platform_device *pdev) | ||
272 | { | 237 | { |
273 | struct gpio_em_config *pdata = pdev->dev.platform_data; | 238 | struct gpio_em_config *pdata = pdev->dev.platform_data; |
274 | struct em_gio_priv *p; | 239 | struct em_gio_priv *p; |
@@ -334,8 +299,11 @@ static int __devinit em_gio_probe(struct platform_device *pdev) | |||
334 | irq_chip->irq_set_type = em_gio_irq_set_type; | 299 | irq_chip->irq_set_type = em_gio_irq_set_type; |
335 | irq_chip->flags = IRQCHIP_SKIP_SET_WAKE; | 300 | irq_chip->flags = IRQCHIP_SKIP_SET_WAKE; |
336 | 301 | ||
337 | ret = em_gio_irq_domain_init(p); | 302 | p->irq_domain = irq_domain_add_linear(pdev->dev.of_node, |
338 | if (ret) { | 303 | pdata->number_of_pins, |
304 | &em_gio_irq_domain_ops, p); | ||
305 | if (!p->irq_domain) { | ||
306 | ret = -ENXIO; | ||
339 | dev_err(&pdev->dev, "cannot initialize irq domain\n"); | 307 | dev_err(&pdev->dev, "cannot initialize irq domain\n"); |
340 | goto err3; | 308 | goto err3; |
341 | } | 309 | } |
@@ -364,7 +332,7 @@ err6: | |||
364 | err5: | 332 | err5: |
365 | free_irq(irq[0]->start, pdev); | 333 | free_irq(irq[0]->start, pdev); |
366 | err4: | 334 | err4: |
367 | em_gio_irq_domain_cleanup(p); | 335 | irq_domain_remove(p->irq_domain); |
368 | err3: | 336 | err3: |
369 | iounmap(p->base1); | 337 | iounmap(p->base1); |
370 | err2: | 338 | err2: |
@@ -375,7 +343,7 @@ err0: | |||
375 | return ret; | 343 | return ret; |
376 | } | 344 | } |
377 | 345 | ||
378 | static int __devexit em_gio_remove(struct platform_device *pdev) | 346 | static int em_gio_remove(struct platform_device *pdev) |
379 | { | 347 | { |
380 | struct em_gio_priv *p = platform_get_drvdata(pdev); | 348 | struct em_gio_priv *p = platform_get_drvdata(pdev); |
381 | struct resource *irq[2]; | 349 | struct resource *irq[2]; |
@@ -390,7 +358,7 @@ static int __devexit em_gio_remove(struct platform_device *pdev) | |||
390 | 358 | ||
391 | free_irq(irq[1]->start, pdev); | 359 | free_irq(irq[1]->start, pdev); |
392 | free_irq(irq[0]->start, pdev); | 360 | free_irq(irq[0]->start, pdev); |
393 | em_gio_irq_domain_cleanup(p); | 361 | irq_domain_remove(p->irq_domain); |
394 | iounmap(p->base1); | 362 | iounmap(p->base1); |
395 | iounmap(p->base0); | 363 | iounmap(p->base0); |
396 | kfree(p); | 364 | kfree(p); |
@@ -399,7 +367,7 @@ static int __devexit em_gio_remove(struct platform_device *pdev) | |||
399 | 367 | ||
400 | static struct platform_driver em_gio_device_driver = { | 368 | static struct platform_driver em_gio_device_driver = { |
401 | .probe = em_gio_probe, | 369 | .probe = em_gio_probe, |
402 | .remove = __devexit_p(em_gio_remove), | 370 | .remove = em_gio_remove, |
403 | .driver = { | 371 | .driver = { |
404 | .name = "em_gio", | 372 | .name = "em_gio", |
405 | } | 373 | } |
diff --git a/drivers/gpio/gpio-ep93xx.c b/drivers/gpio/gpio-ep93xx.c index 9fe5b8fe9be8..56b98eebe1fc 100644 --- a/drivers/gpio/gpio-ep93xx.c +++ b/drivers/gpio/gpio-ep93xx.c | |||
@@ -340,7 +340,7 @@ static int ep93xx_gpio_add_bank(struct bgpio_chip *bgc, struct device *dev, | |||
340 | return gpiochip_add(&bgc->gc); | 340 | return gpiochip_add(&bgc->gc); |
341 | } | 341 | } |
342 | 342 | ||
343 | static int __devinit ep93xx_gpio_probe(struct platform_device *pdev) | 343 | static int ep93xx_gpio_probe(struct platform_device *pdev) |
344 | { | 344 | { |
345 | struct ep93xx_gpio *ep93xx_gpio; | 345 | struct ep93xx_gpio *ep93xx_gpio; |
346 | struct resource *res; | 346 | struct resource *res; |
diff --git a/drivers/gpio/gpio-generic.c b/drivers/gpio/gpio-generic.c index 82e2e4fe599e..05fcc0f247ca 100644 --- a/drivers/gpio/gpio-generic.c +++ b/drivers/gpio/gpio-generic.c | |||
@@ -444,7 +444,7 @@ static void __iomem *bgpio_map(struct platform_device *pdev, | |||
444 | return ret; | 444 | return ret; |
445 | } | 445 | } |
446 | 446 | ||
447 | static int __devinit bgpio_pdev_probe(struct platform_device *pdev) | 447 | static int bgpio_pdev_probe(struct platform_device *pdev) |
448 | { | 448 | { |
449 | struct device *dev = &pdev->dev; | 449 | struct device *dev = &pdev->dev; |
450 | struct resource *r; | 450 | struct resource *r; |
@@ -507,7 +507,7 @@ static int __devinit bgpio_pdev_probe(struct platform_device *pdev) | |||
507 | return gpiochip_add(&bgc->gc); | 507 | return gpiochip_add(&bgc->gc); |
508 | } | 508 | } |
509 | 509 | ||
510 | static int __devexit bgpio_pdev_remove(struct platform_device *pdev) | 510 | static int bgpio_pdev_remove(struct platform_device *pdev) |
511 | { | 511 | { |
512 | struct bgpio_chip *bgc = platform_get_drvdata(pdev); | 512 | struct bgpio_chip *bgc = platform_get_drvdata(pdev); |
513 | 513 | ||
@@ -527,7 +527,7 @@ static struct platform_driver bgpio_driver = { | |||
527 | }, | 527 | }, |
528 | .id_table = bgpio_id_table, | 528 | .id_table = bgpio_id_table, |
529 | .probe = bgpio_pdev_probe, | 529 | .probe = bgpio_pdev_probe, |
530 | .remove = __devexit_p(bgpio_pdev_remove), | 530 | .remove = bgpio_pdev_remove, |
531 | }; | 531 | }; |
532 | 532 | ||
533 | module_platform_driver(bgpio_driver); | 533 | module_platform_driver(bgpio_driver); |
diff --git a/drivers/gpio/gpio-ich.c b/drivers/gpio/gpio-ich.c index d4d617966696..6f2306db8591 100644 --- a/drivers/gpio/gpio-ich.c +++ b/drivers/gpio/gpio-ich.c | |||
@@ -238,7 +238,7 @@ static void ichx_gpio_set(struct gpio_chip *chip, unsigned nr, int val) | |||
238 | ichx_write_bit(GPIO_LVL, nr, val, 0); | 238 | ichx_write_bit(GPIO_LVL, nr, val, 0); |
239 | } | 239 | } |
240 | 240 | ||
241 | static void __devinit ichx_gpiolib_setup(struct gpio_chip *chip) | 241 | static void ichx_gpiolib_setup(struct gpio_chip *chip) |
242 | { | 242 | { |
243 | chip->owner = THIS_MODULE; | 243 | chip->owner = THIS_MODULE; |
244 | chip->label = DRV_NAME; | 244 | chip->label = DRV_NAME; |
@@ -313,7 +313,7 @@ static struct ichx_desc intel5_desc = { | |||
313 | .ngpio = 76, | 313 | .ngpio = 76, |
314 | }; | 314 | }; |
315 | 315 | ||
316 | static int __devinit ichx_gpio_request_regions(struct resource *res_base, | 316 | static int ichx_gpio_request_regions(struct resource *res_base, |
317 | const char *name, u8 use_gpio) | 317 | const char *name, u8 use_gpio) |
318 | { | 318 | { |
319 | int i; | 319 | int i; |
@@ -353,7 +353,7 @@ static void ichx_gpio_release_regions(struct resource *res_base, u8 use_gpio) | |||
353 | } | 353 | } |
354 | } | 354 | } |
355 | 355 | ||
356 | static int __devinit ichx_gpio_probe(struct platform_device *pdev) | 356 | static int ichx_gpio_probe(struct platform_device *pdev) |
357 | { | 357 | { |
358 | struct resource *res_base, *res_pm; | 358 | struct resource *res_base, *res_pm; |
359 | int err; | 359 | int err; |
@@ -390,6 +390,7 @@ static int __devinit ichx_gpio_probe(struct platform_device *pdev) | |||
390 | return -ENODEV; | 390 | return -ENODEV; |
391 | } | 391 | } |
392 | 392 | ||
393 | spin_lock_init(&ichx_priv.lock); | ||
393 | res_base = platform_get_resource(pdev, IORESOURCE_IO, ICH_RES_GPIO); | 394 | res_base = platform_get_resource(pdev, IORESOURCE_IO, ICH_RES_GPIO); |
394 | ichx_priv.use_gpio = ich_info->use_gpio; | 395 | ichx_priv.use_gpio = ich_info->use_gpio; |
395 | err = ichx_gpio_request_regions(res_base, pdev->name, | 396 | err = ichx_gpio_request_regions(res_base, pdev->name, |
@@ -442,7 +443,7 @@ add_err: | |||
442 | return err; | 443 | return err; |
443 | } | 444 | } |
444 | 445 | ||
445 | static int __devexit ichx_gpio_remove(struct platform_device *pdev) | 446 | static int ichx_gpio_remove(struct platform_device *pdev) |
446 | { | 447 | { |
447 | int err; | 448 | int err; |
448 | 449 | ||
@@ -467,7 +468,7 @@ static struct platform_driver ichx_gpio_driver = { | |||
467 | .name = DRV_NAME, | 468 | .name = DRV_NAME, |
468 | }, | 469 | }, |
469 | .probe = ichx_gpio_probe, | 470 | .probe = ichx_gpio_probe, |
470 | .remove = __devexit_p(ichx_gpio_remove), | 471 | .remove = ichx_gpio_remove, |
471 | }; | 472 | }; |
472 | 473 | ||
473 | module_platform_driver(ichx_gpio_driver); | 474 | module_platform_driver(ichx_gpio_driver); |
diff --git a/drivers/gpio/gpio-janz-ttl.c b/drivers/gpio/gpio-janz-ttl.c index f2f000dd70b3..7d0a04169a35 100644 --- a/drivers/gpio/gpio-janz-ttl.c +++ b/drivers/gpio/gpio-janz-ttl.c | |||
@@ -108,13 +108,13 @@ static void ttl_set_value(struct gpio_chip *gpio, unsigned offset, int value) | |||
108 | spin_unlock(&mod->lock); | 108 | spin_unlock(&mod->lock); |
109 | } | 109 | } |
110 | 110 | ||
111 | static void __devinit ttl_write_reg(struct ttl_module *mod, u8 reg, u16 val) | 111 | static void ttl_write_reg(struct ttl_module *mod, u8 reg, u16 val) |
112 | { | 112 | { |
113 | iowrite16be(reg, &mod->regs->control); | 113 | iowrite16be(reg, &mod->regs->control); |
114 | iowrite16be(val, &mod->regs->control); | 114 | iowrite16be(val, &mod->regs->control); |
115 | } | 115 | } |
116 | 116 | ||
117 | static void __devinit ttl_setup_device(struct ttl_module *mod) | 117 | static void ttl_setup_device(struct ttl_module *mod) |
118 | { | 118 | { |
119 | /* reset the device to a known state */ | 119 | /* reset the device to a known state */ |
120 | iowrite16be(0x0000, &mod->regs->control); | 120 | iowrite16be(0x0000, &mod->regs->control); |
@@ -140,7 +140,7 @@ static void __devinit ttl_setup_device(struct ttl_module *mod) | |||
140 | ttl_write_reg(mod, MASTER_CONF_CTL, CONF_PAE | CONF_PBE | CONF_PCE); | 140 | ttl_write_reg(mod, MASTER_CONF_CTL, CONF_PAE | CONF_PBE | CONF_PCE); |
141 | } | 141 | } |
142 | 142 | ||
143 | static int __devinit ttl_probe(struct platform_device *pdev) | 143 | static int ttl_probe(struct platform_device *pdev) |
144 | { | 144 | { |
145 | struct janz_platform_data *pdata; | 145 | struct janz_platform_data *pdata; |
146 | struct device *dev = &pdev->dev; | 146 | struct device *dev = &pdev->dev; |
@@ -211,7 +211,7 @@ out_return: | |||
211 | return ret; | 211 | return ret; |
212 | } | 212 | } |
213 | 213 | ||
214 | static int __devexit ttl_remove(struct platform_device *pdev) | 214 | static int ttl_remove(struct platform_device *pdev) |
215 | { | 215 | { |
216 | struct ttl_module *mod = platform_get_drvdata(pdev); | 216 | struct ttl_module *mod = platform_get_drvdata(pdev); |
217 | struct device *dev = &pdev->dev; | 217 | struct device *dev = &pdev->dev; |
@@ -234,7 +234,7 @@ static struct platform_driver ttl_driver = { | |||
234 | .owner = THIS_MODULE, | 234 | .owner = THIS_MODULE, |
235 | }, | 235 | }, |
236 | .probe = ttl_probe, | 236 | .probe = ttl_probe, |
237 | .remove = __devexit_p(ttl_remove), | 237 | .remove = ttl_remove, |
238 | }; | 238 | }; |
239 | 239 | ||
240 | module_platform_driver(ttl_driver); | 240 | module_platform_driver(ttl_driver); |
diff --git a/drivers/gpio/gpio-langwell.c b/drivers/gpio/gpio-langwell.c index 202a99207b7d..e77b2b3e94af 100644 --- a/drivers/gpio/gpio-langwell.c +++ b/drivers/gpio/gpio-langwell.c | |||
@@ -332,7 +332,7 @@ static const struct dev_pm_ops lnw_gpio_pm_ops = { | |||
332 | .runtime_idle = lnw_gpio_runtime_idle, | 332 | .runtime_idle = lnw_gpio_runtime_idle, |
333 | }; | 333 | }; |
334 | 334 | ||
335 | static int __devinit lnw_gpio_probe(struct pci_dev *pdev, | 335 | static int lnw_gpio_probe(struct pci_dev *pdev, |
336 | const struct pci_device_id *id) | 336 | const struct pci_device_id *id) |
337 | { | 337 | { |
338 | void *base; | 338 | void *base; |
@@ -435,7 +435,7 @@ static struct pci_driver lnw_gpio_driver = { | |||
435 | }; | 435 | }; |
436 | 436 | ||
437 | 437 | ||
438 | static int __devinit wp_gpio_probe(struct platform_device *pdev) | 438 | static int wp_gpio_probe(struct platform_device *pdev) |
439 | { | 439 | { |
440 | struct lnw_gpio *lnw; | 440 | struct lnw_gpio *lnw; |
441 | struct gpio_chip *gc; | 441 | struct gpio_chip *gc; |
@@ -484,7 +484,7 @@ err_kmalloc: | |||
484 | return retval; | 484 | return retval; |
485 | } | 485 | } |
486 | 486 | ||
487 | static int __devexit wp_gpio_remove(struct platform_device *pdev) | 487 | static int wp_gpio_remove(struct platform_device *pdev) |
488 | { | 488 | { |
489 | struct lnw_gpio *lnw = platform_get_drvdata(pdev); | 489 | struct lnw_gpio *lnw = platform_get_drvdata(pdev); |
490 | int err; | 490 | int err; |
@@ -499,7 +499,7 @@ static int __devexit wp_gpio_remove(struct platform_device *pdev) | |||
499 | 499 | ||
500 | static struct platform_driver wp_gpio_driver = { | 500 | static struct platform_driver wp_gpio_driver = { |
501 | .probe = wp_gpio_probe, | 501 | .probe = wp_gpio_probe, |
502 | .remove = __devexit_p(wp_gpio_remove), | 502 | .remove = wp_gpio_remove, |
503 | .driver = { | 503 | .driver = { |
504 | .name = "wp_gpio", | 504 | .name = "wp_gpio", |
505 | .owner = THIS_MODULE, | 505 | .owner = THIS_MODULE, |
diff --git a/drivers/gpio/gpio-lpc32xx.c b/drivers/gpio/gpio-lpc32xx.c index 3644e0dcb3dd..36d7dee07b28 100644 --- a/drivers/gpio/gpio-lpc32xx.c +++ b/drivers/gpio/gpio-lpc32xx.c | |||
@@ -542,7 +542,7 @@ static int lpc32xx_of_xlate(struct gpio_chip *gc, | |||
542 | return gpiospec->args[1]; | 542 | return gpiospec->args[1]; |
543 | } | 543 | } |
544 | 544 | ||
545 | static int __devinit lpc32xx_gpio_probe(struct platform_device *pdev) | 545 | static int lpc32xx_gpio_probe(struct platform_device *pdev) |
546 | { | 546 | { |
547 | int i; | 547 | int i; |
548 | 548 | ||
@@ -559,7 +559,7 @@ static int __devinit lpc32xx_gpio_probe(struct platform_device *pdev) | |||
559 | } | 559 | } |
560 | 560 | ||
561 | #ifdef CONFIG_OF | 561 | #ifdef CONFIG_OF |
562 | static struct of_device_id lpc32xx_gpio_of_match[] __devinitdata = { | 562 | static struct of_device_id lpc32xx_gpio_of_match[] = { |
563 | { .compatible = "nxp,lpc3220-gpio", }, | 563 | { .compatible = "nxp,lpc3220-gpio", }, |
564 | { }, | 564 | { }, |
565 | }; | 565 | }; |
diff --git a/drivers/gpio/gpio-max7300.c b/drivers/gpio/gpio-max7300.c index a5ca0ab1b372..4b6b9a04e326 100644 --- a/drivers/gpio/gpio-max7300.c +++ b/drivers/gpio/gpio-max7300.c | |||
@@ -31,7 +31,7 @@ static int max7300_i2c_read(struct device *dev, unsigned int reg) | |||
31 | return i2c_smbus_read_byte_data(client, reg); | 31 | return i2c_smbus_read_byte_data(client, reg); |
32 | } | 32 | } |
33 | 33 | ||
34 | static int __devinit max7300_probe(struct i2c_client *client, | 34 | static int max7300_probe(struct i2c_client *client, |
35 | const struct i2c_device_id *id) | 35 | const struct i2c_device_id *id) |
36 | { | 36 | { |
37 | struct max7301 *ts; | 37 | struct max7301 *ts; |
@@ -55,7 +55,7 @@ static int __devinit max7300_probe(struct i2c_client *client, | |||
55 | return ret; | 55 | return ret; |
56 | } | 56 | } |
57 | 57 | ||
58 | static int __devexit max7300_remove(struct i2c_client *client) | 58 | static int max7300_remove(struct i2c_client *client) |
59 | { | 59 | { |
60 | return __max730x_remove(&client->dev); | 60 | return __max730x_remove(&client->dev); |
61 | } | 61 | } |
@@ -72,7 +72,7 @@ static struct i2c_driver max7300_driver = { | |||
72 | .owner = THIS_MODULE, | 72 | .owner = THIS_MODULE, |
73 | }, | 73 | }, |
74 | .probe = max7300_probe, | 74 | .probe = max7300_probe, |
75 | .remove = __devexit_p(max7300_remove), | 75 | .remove = max7300_remove, |
76 | .id_table = max7300_id, | 76 | .id_table = max7300_id, |
77 | }; | 77 | }; |
78 | 78 | ||
diff --git a/drivers/gpio/gpio-max7301.c b/drivers/gpio/gpio-max7301.c index 741acfcbe761..c6c535c1310e 100644 --- a/drivers/gpio/gpio-max7301.c +++ b/drivers/gpio/gpio-max7301.c | |||
@@ -50,7 +50,7 @@ static int max7301_spi_read(struct device *dev, unsigned int reg) | |||
50 | return word & 0xff; | 50 | return word & 0xff; |
51 | } | 51 | } |
52 | 52 | ||
53 | static int __devinit max7301_probe(struct spi_device *spi) | 53 | static int max7301_probe(struct spi_device *spi) |
54 | { | 54 | { |
55 | struct max7301 *ts; | 55 | struct max7301 *ts; |
56 | int ret; | 56 | int ret; |
@@ -75,7 +75,7 @@ static int __devinit max7301_probe(struct spi_device *spi) | |||
75 | return ret; | 75 | return ret; |
76 | } | 76 | } |
77 | 77 | ||
78 | static int __devexit max7301_remove(struct spi_device *spi) | 78 | static int max7301_remove(struct spi_device *spi) |
79 | { | 79 | { |
80 | return __max730x_remove(&spi->dev); | 80 | return __max730x_remove(&spi->dev); |
81 | } | 81 | } |
@@ -92,7 +92,7 @@ static struct spi_driver max7301_driver = { | |||
92 | .owner = THIS_MODULE, | 92 | .owner = THIS_MODULE, |
93 | }, | 93 | }, |
94 | .probe = max7301_probe, | 94 | .probe = max7301_probe, |
95 | .remove = __devexit_p(max7301_remove), | 95 | .remove = max7301_remove, |
96 | .id_table = max7301_id, | 96 | .id_table = max7301_id, |
97 | }; | 97 | }; |
98 | 98 | ||
diff --git a/drivers/gpio/gpio-max730x.c b/drivers/gpio/gpio-max730x.c index 05e2dac60b3b..00092342b84c 100644 --- a/drivers/gpio/gpio-max730x.c +++ b/drivers/gpio/gpio-max730x.c | |||
@@ -160,17 +160,13 @@ static void max7301_set(struct gpio_chip *chip, unsigned offset, int value) | |||
160 | mutex_unlock(&ts->lock); | 160 | mutex_unlock(&ts->lock); |
161 | } | 161 | } |
162 | 162 | ||
163 | int __devinit __max730x_probe(struct max7301 *ts) | 163 | int __max730x_probe(struct max7301 *ts) |
164 | { | 164 | { |
165 | struct device *dev = ts->dev; | 165 | struct device *dev = ts->dev; |
166 | struct max7301_platform_data *pdata; | 166 | struct max7301_platform_data *pdata; |
167 | int i, ret; | 167 | int i, ret; |
168 | 168 | ||
169 | pdata = dev->platform_data; | 169 | pdata = dev->platform_data; |
170 | if (!pdata || !pdata->base) { | ||
171 | dev_err(dev, "incorrect or missing platform data\n"); | ||
172 | return -EINVAL; | ||
173 | } | ||
174 | 170 | ||
175 | mutex_init(&ts->lock); | 171 | mutex_init(&ts->lock); |
176 | dev_set_drvdata(dev, ts); | 172 | dev_set_drvdata(dev, ts); |
@@ -178,7 +174,12 @@ int __devinit __max730x_probe(struct max7301 *ts) | |||
178 | /* Power up the chip and disable IRQ output */ | 174 | /* Power up the chip and disable IRQ output */ |
179 | ts->write(dev, 0x04, 0x01); | 175 | ts->write(dev, 0x04, 0x01); |
180 | 176 | ||
181 | ts->input_pullup_active = pdata->input_pullup_active; | 177 | if (pdata) { |
178 | ts->input_pullup_active = pdata->input_pullup_active; | ||
179 | ts->chip.base = pdata->base; | ||
180 | } else { | ||
181 | ts->chip.base = -1; | ||
182 | } | ||
182 | ts->chip.label = dev->driver->name; | 183 | ts->chip.label = dev->driver->name; |
183 | 184 | ||
184 | ts->chip.direction_input = max7301_direction_input; | 185 | ts->chip.direction_input = max7301_direction_input; |
@@ -186,7 +187,6 @@ int __devinit __max730x_probe(struct max7301 *ts) | |||
186 | ts->chip.direction_output = max7301_direction_output; | 187 | ts->chip.direction_output = max7301_direction_output; |
187 | ts->chip.set = max7301_set; | 188 | ts->chip.set = max7301_set; |
188 | 189 | ||
189 | ts->chip.base = pdata->base; | ||
190 | ts->chip.ngpio = PIN_NUMBER; | 190 | ts->chip.ngpio = PIN_NUMBER; |
191 | ts->chip.can_sleep = 1; | 191 | ts->chip.can_sleep = 1; |
192 | ts->chip.dev = dev; | 192 | ts->chip.dev = dev; |
@@ -226,7 +226,7 @@ exit_destroy: | |||
226 | } | 226 | } |
227 | EXPORT_SYMBOL_GPL(__max730x_probe); | 227 | EXPORT_SYMBOL_GPL(__max730x_probe); |
228 | 228 | ||
229 | int __devexit __max730x_remove(struct device *dev) | 229 | int __max730x_remove(struct device *dev) |
230 | { | 230 | { |
231 | struct max7301 *ts = dev_get_drvdata(dev); | 231 | struct max7301 *ts = dev_get_drvdata(dev); |
232 | int ret; | 232 | int ret; |
diff --git a/drivers/gpio/gpio-max732x.c b/drivers/gpio/gpio-max732x.c index 9504120812a5..1e0467ce4c37 100644 --- a/drivers/gpio/gpio-max732x.c +++ b/drivers/gpio/gpio-max732x.c | |||
@@ -526,7 +526,7 @@ static void max732x_irq_teardown(struct max732x_chip *chip) | |||
526 | } | 526 | } |
527 | #endif | 527 | #endif |
528 | 528 | ||
529 | static int __devinit max732x_setup_gpio(struct max732x_chip *chip, | 529 | static int max732x_setup_gpio(struct max732x_chip *chip, |
530 | const struct i2c_device_id *id, | 530 | const struct i2c_device_id *id, |
531 | unsigned gpio_start) | 531 | unsigned gpio_start) |
532 | { | 532 | { |
@@ -574,7 +574,7 @@ static int __devinit max732x_setup_gpio(struct max732x_chip *chip, | |||
574 | return port; | 574 | return port; |
575 | } | 575 | } |
576 | 576 | ||
577 | static int __devinit max732x_probe(struct i2c_client *client, | 577 | static int max732x_probe(struct i2c_client *client, |
578 | const struct i2c_device_id *id) | 578 | const struct i2c_device_id *id) |
579 | { | 579 | { |
580 | struct max732x_platform_data *pdata; | 580 | struct max732x_platform_data *pdata; |
@@ -651,7 +651,7 @@ out_failed: | |||
651 | return ret; | 651 | return ret; |
652 | } | 652 | } |
653 | 653 | ||
654 | static int __devexit max732x_remove(struct i2c_client *client) | 654 | static int max732x_remove(struct i2c_client *client) |
655 | { | 655 | { |
656 | struct max732x_platform_data *pdata = client->dev.platform_data; | 656 | struct max732x_platform_data *pdata = client->dev.platform_data; |
657 | struct max732x_chip *chip = i2c_get_clientdata(client); | 657 | struct max732x_chip *chip = i2c_get_clientdata(client); |
@@ -690,7 +690,7 @@ static struct i2c_driver max732x_driver = { | |||
690 | .owner = THIS_MODULE, | 690 | .owner = THIS_MODULE, |
691 | }, | 691 | }, |
692 | .probe = max732x_probe, | 692 | .probe = max732x_probe, |
693 | .remove = __devexit_p(max732x_remove), | 693 | .remove = max732x_remove, |
694 | .id_table = max732x_id, | 694 | .id_table = max732x_id, |
695 | }; | 695 | }; |
696 | 696 | ||
diff --git a/drivers/gpio/gpio-mc33880.c b/drivers/gpio/gpio-mc33880.c index 2de57ce5feb6..6a8fdc26ae6a 100644 --- a/drivers/gpio/gpio-mc33880.c +++ b/drivers/gpio/gpio-mc33880.c | |||
@@ -80,7 +80,7 @@ static void mc33880_set(struct gpio_chip *chip, unsigned offset, int value) | |||
80 | mutex_unlock(&mc->lock); | 80 | mutex_unlock(&mc->lock); |
81 | } | 81 | } |
82 | 82 | ||
83 | static int __devinit mc33880_probe(struct spi_device *spi) | 83 | static int mc33880_probe(struct spi_device *spi) |
84 | { | 84 | { |
85 | struct mc33880 *mc; | 85 | struct mc33880 *mc; |
86 | struct mc33880_platform_data *pdata; | 86 | struct mc33880_platform_data *pdata; |
@@ -147,7 +147,7 @@ exit_destroy: | |||
147 | return ret; | 147 | return ret; |
148 | } | 148 | } |
149 | 149 | ||
150 | static int __devexit mc33880_remove(struct spi_device *spi) | 150 | static int mc33880_remove(struct spi_device *spi) |
151 | { | 151 | { |
152 | struct mc33880 *mc; | 152 | struct mc33880 *mc; |
153 | int ret; | 153 | int ret; |
@@ -175,7 +175,7 @@ static struct spi_driver mc33880_driver = { | |||
175 | .owner = THIS_MODULE, | 175 | .owner = THIS_MODULE, |
176 | }, | 176 | }, |
177 | .probe = mc33880_probe, | 177 | .probe = mc33880_probe, |
178 | .remove = __devexit_p(mc33880_remove), | 178 | .remove = mc33880_remove, |
179 | }; | 179 | }; |
180 | 180 | ||
181 | static int __init mc33880_init(void) | 181 | static int __init mc33880_init(void) |
diff --git a/drivers/gpio/gpio-mcp23s08.c b/drivers/gpio/gpio-mcp23s08.c index ce1c84760076..3cea0ea79e80 100644 --- a/drivers/gpio/gpio-mcp23s08.c +++ b/drivers/gpio/gpio-mcp23s08.c | |||
@@ -475,7 +475,7 @@ fail: | |||
475 | 475 | ||
476 | #if IS_ENABLED(CONFIG_I2C) | 476 | #if IS_ENABLED(CONFIG_I2C) |
477 | 477 | ||
478 | static int __devinit mcp230xx_probe(struct i2c_client *client, | 478 | static int mcp230xx_probe(struct i2c_client *client, |
479 | const struct i2c_device_id *id) | 479 | const struct i2c_device_id *id) |
480 | { | 480 | { |
481 | struct mcp23s08_platform_data *pdata; | 481 | struct mcp23s08_platform_data *pdata; |
@@ -508,7 +508,7 @@ fail: | |||
508 | return status; | 508 | return status; |
509 | } | 509 | } |
510 | 510 | ||
511 | static int __devexit mcp230xx_remove(struct i2c_client *client) | 511 | static int mcp230xx_remove(struct i2c_client *client) |
512 | { | 512 | { |
513 | struct mcp23s08 *mcp = i2c_get_clientdata(client); | 513 | struct mcp23s08 *mcp = i2c_get_clientdata(client); |
514 | int status; | 514 | int status; |
@@ -533,7 +533,7 @@ static struct i2c_driver mcp230xx_driver = { | |||
533 | .owner = THIS_MODULE, | 533 | .owner = THIS_MODULE, |
534 | }, | 534 | }, |
535 | .probe = mcp230xx_probe, | 535 | .probe = mcp230xx_probe, |
536 | .remove = __devexit_p(mcp230xx_remove), | 536 | .remove = mcp230xx_remove, |
537 | .id_table = mcp230xx_id, | 537 | .id_table = mcp230xx_id, |
538 | }; | 538 | }; |
539 | 539 | ||
diff --git a/drivers/gpio/gpio-ml-ioh.c b/drivers/gpio/gpio-ml-ioh.c index 6a29ee1847be..b73366523fae 100644 --- a/drivers/gpio/gpio-ml-ioh.c +++ b/drivers/gpio/gpio-ml-ioh.c | |||
@@ -385,7 +385,7 @@ static irqreturn_t ioh_gpio_handler(int irq, void *dev_id) | |||
385 | return ret; | 385 | return ret; |
386 | } | 386 | } |
387 | 387 | ||
388 | static __devinit void ioh_gpio_alloc_generic_chip(struct ioh_gpio *chip, | 388 | static void ioh_gpio_alloc_generic_chip(struct ioh_gpio *chip, |
389 | unsigned int irq_start, unsigned int num) | 389 | unsigned int irq_start, unsigned int num) |
390 | { | 390 | { |
391 | struct irq_chip_generic *gc; | 391 | struct irq_chip_generic *gc; |
@@ -406,7 +406,7 @@ static __devinit void ioh_gpio_alloc_generic_chip(struct ioh_gpio *chip, | |||
406 | IRQ_NOREQUEST | IRQ_NOPROBE, 0); | 406 | IRQ_NOREQUEST | IRQ_NOPROBE, 0); |
407 | } | 407 | } |
408 | 408 | ||
409 | static int __devinit ioh_gpio_probe(struct pci_dev *pdev, | 409 | static int ioh_gpio_probe(struct pci_dev *pdev, |
410 | const struct pci_device_id *id) | 410 | const struct pci_device_id *id) |
411 | { | 411 | { |
412 | int ret; | 412 | int ret; |
@@ -517,7 +517,7 @@ err_pci_enable: | |||
517 | return ret; | 517 | return ret; |
518 | } | 518 | } |
519 | 519 | ||
520 | static void __devexit ioh_gpio_remove(struct pci_dev *pdev) | 520 | static void ioh_gpio_remove(struct pci_dev *pdev) |
521 | { | 521 | { |
522 | int err; | 522 | int err; |
523 | int i; | 523 | int i; |
@@ -606,7 +606,7 @@ static struct pci_driver ioh_gpio_driver = { | |||
606 | .name = "ml_ioh_gpio", | 606 | .name = "ml_ioh_gpio", |
607 | .id_table = ioh_gpio_pcidev_id, | 607 | .id_table = ioh_gpio_pcidev_id, |
608 | .probe = ioh_gpio_probe, | 608 | .probe = ioh_gpio_probe, |
609 | .remove = __devexit_p(ioh_gpio_remove), | 609 | .remove = ioh_gpio_remove, |
610 | .suspend = ioh_gpio_suspend, | 610 | .suspend = ioh_gpio_suspend, |
611 | .resume = ioh_gpio_resume | 611 | .resume = ioh_gpio_resume |
612 | }; | 612 | }; |
diff --git a/drivers/gpio/gpio-mpc5200.c b/drivers/gpio/gpio-mpc5200.c index 2c7cef367fc0..42647f26c9e0 100644 --- a/drivers/gpio/gpio-mpc5200.c +++ b/drivers/gpio/gpio-mpc5200.c | |||
@@ -148,7 +148,7 @@ mpc52xx_wkup_gpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val) | |||
148 | return 0; | 148 | return 0; |
149 | } | 149 | } |
150 | 150 | ||
151 | static int __devinit mpc52xx_wkup_gpiochip_probe(struct platform_device *ofdev) | 151 | static int mpc52xx_wkup_gpiochip_probe(struct platform_device *ofdev) |
152 | { | 152 | { |
153 | struct mpc52xx_gpiochip *chip; | 153 | struct mpc52xx_gpiochip *chip; |
154 | struct mpc52xx_gpio_wkup __iomem *regs; | 154 | struct mpc52xx_gpio_wkup __iomem *regs; |
@@ -308,7 +308,7 @@ mpc52xx_simple_gpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val) | |||
308 | return 0; | 308 | return 0; |
309 | } | 309 | } |
310 | 310 | ||
311 | static int __devinit mpc52xx_simple_gpiochip_probe(struct platform_device *ofdev) | 311 | static int mpc52xx_simple_gpiochip_probe(struct platform_device *ofdev) |
312 | { | 312 | { |
313 | struct mpc52xx_gpiochip *chip; | 313 | struct mpc52xx_gpiochip *chip; |
314 | struct gpio_chip *gc; | 314 | struct gpio_chip *gc; |
diff --git a/drivers/gpio/gpio-msic.c b/drivers/gpio/gpio-msic.c index b38986285868..27ea7b9257ff 100644 --- a/drivers/gpio/gpio-msic.c +++ b/drivers/gpio/gpio-msic.c | |||
@@ -256,7 +256,7 @@ static void msic_gpio_irq_handler(unsigned irq, struct irq_desc *desc) | |||
256 | chip->irq_eoi(data); | 256 | chip->irq_eoi(data); |
257 | } | 257 | } |
258 | 258 | ||
259 | static int __devinit platform_msic_gpio_probe(struct platform_device *pdev) | 259 | static int platform_msic_gpio_probe(struct platform_device *pdev) |
260 | { | 260 | { |
261 | struct device *dev = &pdev->dev; | 261 | struct device *dev = &pdev->dev; |
262 | struct intel_msic_gpio_pdata *pdata = dev->platform_data; | 262 | struct intel_msic_gpio_pdata *pdata = dev->platform_data; |
diff --git a/drivers/gpio/gpio-msm-v2.c b/drivers/gpio/gpio-msm-v2.c index 38305beb4375..55a7e7769af6 100644 --- a/drivers/gpio/gpio-msm-v2.c +++ b/drivers/gpio/gpio-msm-v2.c | |||
@@ -352,7 +352,7 @@ static struct irq_chip msm_gpio_irq_chip = { | |||
352 | .irq_set_wake = msm_gpio_irq_set_wake, | 352 | .irq_set_wake = msm_gpio_irq_set_wake, |
353 | }; | 353 | }; |
354 | 354 | ||
355 | static int __devinit msm_gpio_probe(struct platform_device *dev) | 355 | static int msm_gpio_probe(struct platform_device *dev) |
356 | { | 356 | { |
357 | int i, irq, ret; | 357 | int i, irq, ret; |
358 | 358 | ||
@@ -376,7 +376,7 @@ static int __devinit msm_gpio_probe(struct platform_device *dev) | |||
376 | return 0; | 376 | return 0; |
377 | } | 377 | } |
378 | 378 | ||
379 | static int __devexit msm_gpio_remove(struct platform_device *dev) | 379 | static int msm_gpio_remove(struct platform_device *dev) |
380 | { | 380 | { |
381 | int ret = gpiochip_remove(&msm_gpio.gpio_chip); | 381 | int ret = gpiochip_remove(&msm_gpio.gpio_chip); |
382 | 382 | ||
@@ -390,7 +390,7 @@ static int __devexit msm_gpio_remove(struct platform_device *dev) | |||
390 | 390 | ||
391 | static struct platform_driver msm_gpio_driver = { | 391 | static struct platform_driver msm_gpio_driver = { |
392 | .probe = msm_gpio_probe, | 392 | .probe = msm_gpio_probe, |
393 | .remove = __devexit_p(msm_gpio_remove), | 393 | .remove = msm_gpio_remove, |
394 | .driver = { | 394 | .driver = { |
395 | .name = "msmgpio", | 395 | .name = "msmgpio", |
396 | .owner = THIS_MODULE, | 396 | .owner = THIS_MODULE, |
diff --git a/drivers/gpio/gpio-mvebu.c b/drivers/gpio/gpio-mvebu.c index be65c0451ad5..7d9bd94be8d2 100644 --- a/drivers/gpio/gpio-mvebu.c +++ b/drivers/gpio/gpio-mvebu.c | |||
@@ -41,7 +41,6 @@ | |||
41 | #include <linux/io.h> | 41 | #include <linux/io.h> |
42 | #include <linux/of_irq.h> | 42 | #include <linux/of_irq.h> |
43 | #include <linux/of_device.h> | 43 | #include <linux/of_device.h> |
44 | #include <linux/platform_device.h> | ||
45 | #include <linux/pinctrl/consumer.h> | 44 | #include <linux/pinctrl/consumer.h> |
46 | 45 | ||
47 | /* | 46 | /* |
@@ -168,12 +167,12 @@ static void __iomem *mvebu_gpioreg_level_mask(struct mvebu_gpio_chip *mvchip) | |||
168 | * Functions implementing the gpio_chip methods | 167 | * Functions implementing the gpio_chip methods |
169 | */ | 168 | */ |
170 | 169 | ||
171 | int mvebu_gpio_request(struct gpio_chip *chip, unsigned pin) | 170 | static int mvebu_gpio_request(struct gpio_chip *chip, unsigned pin) |
172 | { | 171 | { |
173 | return pinctrl_request_gpio(chip->base + pin); | 172 | return pinctrl_request_gpio(chip->base + pin); |
174 | } | 173 | } |
175 | 174 | ||
176 | void mvebu_gpio_free(struct gpio_chip *chip, unsigned pin) | 175 | static void mvebu_gpio_free(struct gpio_chip *chip, unsigned pin) |
177 | { | 176 | { |
178 | pinctrl_free_gpio(chip->base + pin); | 177 | pinctrl_free_gpio(chip->base + pin); |
179 | } | 178 | } |
@@ -469,20 +468,7 @@ static void mvebu_gpio_irq_handler(unsigned int irq, struct irq_desc *desc) | |||
469 | } | 468 | } |
470 | } | 469 | } |
471 | 470 | ||
472 | static struct platform_device_id mvebu_gpio_ids[] = { | 471 | static struct of_device_id mvebu_gpio_of_match[] = { |
473 | { | ||
474 | .name = "orion-gpio", | ||
475 | }, { | ||
476 | .name = "mv78200-gpio", | ||
477 | }, { | ||
478 | .name = "armadaxp-gpio", | ||
479 | }, { | ||
480 | /* sentinel */ | ||
481 | }, | ||
482 | }; | ||
483 | MODULE_DEVICE_TABLE(platform, mvebu_gpio_ids); | ||
484 | |||
485 | static struct of_device_id mvebu_gpio_of_match[] __devinitdata = { | ||
486 | { | 472 | { |
487 | .compatible = "marvell,orion-gpio", | 473 | .compatible = "marvell,orion-gpio", |
488 | .data = (void*) MVEBU_GPIO_SOC_VARIANT_ORION, | 474 | .data = (void*) MVEBU_GPIO_SOC_VARIANT_ORION, |
@@ -501,7 +487,7 @@ static struct of_device_id mvebu_gpio_of_match[] __devinitdata = { | |||
501 | }; | 487 | }; |
502 | MODULE_DEVICE_TABLE(of, mvebu_gpio_of_match); | 488 | MODULE_DEVICE_TABLE(of, mvebu_gpio_of_match); |
503 | 489 | ||
504 | static int __devinit mvebu_gpio_probe(struct platform_device *pdev) | 490 | static int mvebu_gpio_probe(struct platform_device *pdev) |
505 | { | 491 | { |
506 | struct mvebu_gpio_chip *mvchip; | 492 | struct mvebu_gpio_chip *mvchip; |
507 | const struct of_device_id *match; | 493 | const struct of_device_id *match; |
@@ -546,6 +532,7 @@ static int __devinit mvebu_gpio_probe(struct platform_device *pdev) | |||
546 | mvchip->chip.label = dev_name(&pdev->dev); | 532 | mvchip->chip.label = dev_name(&pdev->dev); |
547 | mvchip->chip.dev = &pdev->dev; | 533 | mvchip->chip.dev = &pdev->dev; |
548 | mvchip->chip.request = mvebu_gpio_request; | 534 | mvchip->chip.request = mvebu_gpio_request; |
535 | mvchip->chip.free = mvebu_gpio_free; | ||
549 | mvchip->chip.direction_input = mvebu_gpio_direction_input; | 536 | mvchip->chip.direction_input = mvebu_gpio_direction_input; |
550 | mvchip->chip.get = mvebu_gpio_get; | 537 | mvchip->chip.get = mvebu_gpio_get; |
551 | mvchip->chip.direction_output = mvebu_gpio_direction_output; | 538 | mvchip->chip.direction_output = mvebu_gpio_direction_output; |
@@ -554,9 +541,7 @@ static int __devinit mvebu_gpio_probe(struct platform_device *pdev) | |||
554 | mvchip->chip.base = id * MVEBU_MAX_GPIO_PER_BANK; | 541 | mvchip->chip.base = id * MVEBU_MAX_GPIO_PER_BANK; |
555 | mvchip->chip.ngpio = ngpios; | 542 | mvchip->chip.ngpio = ngpios; |
556 | mvchip->chip.can_sleep = 0; | 543 | mvchip->chip.can_sleep = 0; |
557 | #ifdef CONFIG_OF | ||
558 | mvchip->chip.of_node = np; | 544 | mvchip->chip.of_node = np; |
559 | #endif | ||
560 | 545 | ||
561 | spin_lock_init(&mvchip->lock); | 546 | spin_lock_init(&mvchip->lock); |
562 | mvchip->membase = devm_request_and_ioremap(&pdev->dev, res); | 547 | mvchip->membase = devm_request_and_ioremap(&pdev->dev, res); |
@@ -673,8 +658,8 @@ static int __devinit mvebu_gpio_probe(struct platform_device *pdev) | |||
673 | IRQ_NOREQUEST, IRQ_LEVEL | IRQ_NOPROBE); | 658 | IRQ_NOREQUEST, IRQ_LEVEL | IRQ_NOPROBE); |
674 | 659 | ||
675 | /* Setup irq domain on top of the generic chip. */ | 660 | /* Setup irq domain on top of the generic chip. */ |
676 | mvchip->domain = irq_domain_add_legacy(np, mvchip->chip.ngpio, | 661 | mvchip->domain = irq_domain_add_simple(np, mvchip->chip.ngpio, |
677 | mvchip->irqbase, 0, | 662 | mvchip->irqbase, |
678 | &irq_domain_simple_ops, | 663 | &irq_domain_simple_ops, |
679 | mvchip); | 664 | mvchip); |
680 | if (!mvchip->domain) { | 665 | if (!mvchip->domain) { |
@@ -697,7 +682,6 @@ static struct platform_driver mvebu_gpio_driver = { | |||
697 | .of_match_table = mvebu_gpio_of_match, | 682 | .of_match_table = mvebu_gpio_of_match, |
698 | }, | 683 | }, |
699 | .probe = mvebu_gpio_probe, | 684 | .probe = mvebu_gpio_probe, |
700 | .id_table = mvebu_gpio_ids, | ||
701 | }; | 685 | }; |
702 | 686 | ||
703 | static int __init mvebu_gpio_init(void) | 687 | static int __init mvebu_gpio_init(void) |
diff --git a/drivers/gpio/gpio-mxc.c b/drivers/gpio/gpio-mxc.c index 80f44bb64a87..7877335c4cc8 100644 --- a/drivers/gpio/gpio-mxc.c +++ b/drivers/gpio/gpio-mxc.c | |||
@@ -356,7 +356,7 @@ static void __init mxc_gpio_init_gc(struct mxc_gpio_port *port, int irq_base) | |||
356 | IRQ_NOREQUEST, 0); | 356 | IRQ_NOREQUEST, 0); |
357 | } | 357 | } |
358 | 358 | ||
359 | static void __devinit mxc_gpio_get_hw(struct platform_device *pdev) | 359 | static void mxc_gpio_get_hw(struct platform_device *pdev) |
360 | { | 360 | { |
361 | const struct of_device_id *of_id = | 361 | const struct of_device_id *of_id = |
362 | of_match_device(mxc_gpio_dt_ids, &pdev->dev); | 362 | of_match_device(mxc_gpio_dt_ids, &pdev->dev); |
@@ -395,7 +395,7 @@ static int mxc_gpio_to_irq(struct gpio_chip *gc, unsigned offset) | |||
395 | return irq_find_mapping(port->domain, offset); | 395 | return irq_find_mapping(port->domain, offset); |
396 | } | 396 | } |
397 | 397 | ||
398 | static int __devinit mxc_gpio_probe(struct platform_device *pdev) | 398 | static int mxc_gpio_probe(struct platform_device *pdev) |
399 | { | 399 | { |
400 | struct device_node *np = pdev->dev.of_node; | 400 | struct device_node *np = pdev->dev.of_node; |
401 | struct mxc_gpio_port *port; | 401 | struct mxc_gpio_port *port; |
diff --git a/drivers/gpio/gpio-mxs.c b/drivers/gpio/gpio-mxs.c index 796fb13e4815..fa2a63cad32e 100644 --- a/drivers/gpio/gpio-mxs.c +++ b/drivers/gpio/gpio-mxs.c | |||
@@ -214,7 +214,7 @@ static const struct of_device_id mxs_gpio_dt_ids[] = { | |||
214 | }; | 214 | }; |
215 | MODULE_DEVICE_TABLE(of, mxs_gpio_dt_ids); | 215 | MODULE_DEVICE_TABLE(of, mxs_gpio_dt_ids); |
216 | 216 | ||
217 | static int __devinit mxs_gpio_probe(struct platform_device *pdev) | 217 | static int mxs_gpio_probe(struct platform_device *pdev) |
218 | { | 218 | { |
219 | const struct of_device_id *of_id = | 219 | const struct of_device_id *of_id = |
220 | of_match_device(mxs_gpio_dt_ids, &pdev->dev); | 220 | of_match_device(mxs_gpio_dt_ids, &pdev->dev); |
diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c index d335af1d4d85..f1fbedb2a6f9 100644 --- a/drivers/gpio/gpio-omap.c +++ b/drivers/gpio/gpio-omap.c | |||
@@ -1012,7 +1012,7 @@ static void omap_gpio_mod_init(struct gpio_bank *bank) | |||
1012 | dev_err(bank->dev, "Could not get gpio dbck\n"); | 1012 | dev_err(bank->dev, "Could not get gpio dbck\n"); |
1013 | } | 1013 | } |
1014 | 1014 | ||
1015 | static __devinit void | 1015 | static void |
1016 | omap_mpuio_alloc_gc(struct gpio_bank *bank, unsigned int irq_start, | 1016 | omap_mpuio_alloc_gc(struct gpio_bank *bank, unsigned int irq_start, |
1017 | unsigned int num) | 1017 | unsigned int num) |
1018 | { | 1018 | { |
@@ -1041,7 +1041,7 @@ omap_mpuio_alloc_gc(struct gpio_bank *bank, unsigned int irq_start, | |||
1041 | IRQ_NOREQUEST | IRQ_NOPROBE, 0); | 1041 | IRQ_NOREQUEST | IRQ_NOPROBE, 0); |
1042 | } | 1042 | } |
1043 | 1043 | ||
1044 | static void __devinit omap_gpio_chip_init(struct gpio_bank *bank) | 1044 | static void omap_gpio_chip_init(struct gpio_bank *bank) |
1045 | { | 1045 | { |
1046 | int j; | 1046 | int j; |
1047 | static int gpio; | 1047 | static int gpio; |
@@ -1089,7 +1089,7 @@ static void __devinit omap_gpio_chip_init(struct gpio_bank *bank) | |||
1089 | 1089 | ||
1090 | static const struct of_device_id omap_gpio_match[]; | 1090 | static const struct of_device_id omap_gpio_match[]; |
1091 | 1091 | ||
1092 | static int __devinit omap_gpio_probe(struct platform_device *pdev) | 1092 | static int omap_gpio_probe(struct platform_device *pdev) |
1093 | { | 1093 | { |
1094 | struct device *dev = &pdev->dev; | 1094 | struct device *dev = &pdev->dev; |
1095 | struct device_node *node = dev->of_node; | 1095 | struct device_node *node = dev->of_node; |
@@ -1105,7 +1105,7 @@ static int __devinit omap_gpio_probe(struct platform_device *pdev) | |||
1105 | if (!pdata) | 1105 | if (!pdata) |
1106 | return -EINVAL; | 1106 | return -EINVAL; |
1107 | 1107 | ||
1108 | bank = devm_kzalloc(&pdev->dev, sizeof(struct gpio_bank), GFP_KERNEL); | 1108 | bank = devm_kzalloc(dev, sizeof(struct gpio_bank), GFP_KERNEL); |
1109 | if (!bank) { | 1109 | if (!bank) { |
1110 | dev_err(dev, "Memory alloc failed\n"); | 1110 | dev_err(dev, "Memory alloc failed\n"); |
1111 | return -ENOMEM; | 1111 | return -ENOMEM; |
diff --git a/drivers/gpio/gpio-pca953x.c b/drivers/gpio/gpio-pca953x.c index 9c693ae17956..cc102d25ee24 100644 --- a/drivers/gpio/gpio-pca953x.c +++ b/drivers/gpio/gpio-pca953x.c | |||
@@ -16,6 +16,7 @@ | |||
16 | #include <linux/gpio.h> | 16 | #include <linux/gpio.h> |
17 | #include <linux/interrupt.h> | 17 | #include <linux/interrupt.h> |
18 | #include <linux/irq.h> | 18 | #include <linux/irq.h> |
19 | #include <linux/irqdomain.h> | ||
19 | #include <linux/i2c.h> | 20 | #include <linux/i2c.h> |
20 | #include <linux/i2c/pca953x.h> | 21 | #include <linux/i2c/pca953x.h> |
21 | #include <linux/slab.h> | 22 | #include <linux/slab.h> |
@@ -83,6 +84,7 @@ struct pca953x_chip { | |||
83 | u32 irq_trig_raise; | 84 | u32 irq_trig_raise; |
84 | u32 irq_trig_fall; | 85 | u32 irq_trig_fall; |
85 | int irq_base; | 86 | int irq_base; |
87 | struct irq_domain *domain; | ||
86 | #endif | 88 | #endif |
87 | 89 | ||
88 | struct i2c_client *client; | 90 | struct i2c_client *client; |
@@ -333,14 +335,14 @@ static void pca953x_irq_mask(struct irq_data *d) | |||
333 | { | 335 | { |
334 | struct pca953x_chip *chip = irq_data_get_irq_chip_data(d); | 336 | struct pca953x_chip *chip = irq_data_get_irq_chip_data(d); |
335 | 337 | ||
336 | chip->irq_mask &= ~(1 << (d->irq - chip->irq_base)); | 338 | chip->irq_mask &= ~(1 << d->hwirq); |
337 | } | 339 | } |
338 | 340 | ||
339 | static void pca953x_irq_unmask(struct irq_data *d) | 341 | static void pca953x_irq_unmask(struct irq_data *d) |
340 | { | 342 | { |
341 | struct pca953x_chip *chip = irq_data_get_irq_chip_data(d); | 343 | struct pca953x_chip *chip = irq_data_get_irq_chip_data(d); |
342 | 344 | ||
343 | chip->irq_mask |= 1 << (d->irq - chip->irq_base); | 345 | chip->irq_mask |= 1 << d->hwirq; |
344 | } | 346 | } |
345 | 347 | ||
346 | static void pca953x_irq_bus_lock(struct irq_data *d) | 348 | static void pca953x_irq_bus_lock(struct irq_data *d) |
@@ -372,8 +374,7 @@ static void pca953x_irq_bus_sync_unlock(struct irq_data *d) | |||
372 | static int pca953x_irq_set_type(struct irq_data *d, unsigned int type) | 374 | static int pca953x_irq_set_type(struct irq_data *d, unsigned int type) |
373 | { | 375 | { |
374 | struct pca953x_chip *chip = irq_data_get_irq_chip_data(d); | 376 | struct pca953x_chip *chip = irq_data_get_irq_chip_data(d); |
375 | u32 level = d->irq - chip->irq_base; | 377 | u32 mask = 1 << d->hwirq; |
376 | u32 mask = 1 << level; | ||
377 | 378 | ||
378 | if (!(type & IRQ_TYPE_EDGE_BOTH)) { | 379 | if (!(type & IRQ_TYPE_EDGE_BOTH)) { |
379 | dev_err(&chip->client->dev, "irq %d: unsupported type %d\n", | 380 | dev_err(&chip->client->dev, "irq %d: unsupported type %d\n", |
@@ -454,7 +455,7 @@ static irqreturn_t pca953x_irq_handler(int irq, void *devid) | |||
454 | 455 | ||
455 | do { | 456 | do { |
456 | level = __ffs(pending); | 457 | level = __ffs(pending); |
457 | handle_nested_irq(level + chip->irq_base); | 458 | handle_nested_irq(irq_find_mapping(chip->domain, level)); |
458 | 459 | ||
459 | pending &= ~(1 << level); | 460 | pending &= ~(1 << level); |
460 | } while (pending); | 461 | } while (pending); |
@@ -499,6 +500,17 @@ static int pca953x_irq_setup(struct pca953x_chip *chip, | |||
499 | if (chip->irq_base < 0) | 500 | if (chip->irq_base < 0) |
500 | goto out_failed; | 501 | goto out_failed; |
501 | 502 | ||
503 | chip->domain = irq_domain_add_legacy(client->dev.of_node, | ||
504 | chip->gpio_chip.ngpio, | ||
505 | chip->irq_base, | ||
506 | 0, | ||
507 | &irq_domain_simple_ops, | ||
508 | NULL); | ||
509 | if (!chip->domain) { | ||
510 | ret = -ENODEV; | ||
511 | goto out_irqdesc_free; | ||
512 | } | ||
513 | |||
502 | for (lvl = 0; lvl < chip->gpio_chip.ngpio; lvl++) { | 514 | for (lvl = 0; lvl < chip->gpio_chip.ngpio; lvl++) { |
503 | int irq = lvl + chip->irq_base; | 515 | int irq = lvl + chip->irq_base; |
504 | 516 | ||
@@ -521,7 +533,7 @@ static int pca953x_irq_setup(struct pca953x_chip *chip, | |||
521 | if (ret) { | 533 | if (ret) { |
522 | dev_err(&client->dev, "failed to request irq %d\n", | 534 | dev_err(&client->dev, "failed to request irq %d\n", |
523 | client->irq); | 535 | client->irq); |
524 | goto out_failed; | 536 | goto out_irqdesc_free; |
525 | } | 537 | } |
526 | 538 | ||
527 | chip->gpio_chip.to_irq = pca953x_gpio_to_irq; | 539 | chip->gpio_chip.to_irq = pca953x_gpio_to_irq; |
@@ -529,6 +541,8 @@ static int pca953x_irq_setup(struct pca953x_chip *chip, | |||
529 | 541 | ||
530 | return 0; | 542 | return 0; |
531 | 543 | ||
544 | out_irqdesc_free: | ||
545 | irq_free_descs(chip->irq_base, chip->gpio_chip.ngpio); | ||
532 | out_failed: | 546 | out_failed: |
533 | chip->irq_base = -1; | 547 | chip->irq_base = -1; |
534 | return ret; | 548 | return ret; |
@@ -602,7 +616,7 @@ pca953x_get_alt_pdata(struct i2c_client *client, int *gpio_base, u32 *invert) | |||
602 | } | 616 | } |
603 | #endif | 617 | #endif |
604 | 618 | ||
605 | static int __devinit device_pca953x_init(struct pca953x_chip *chip, u32 invert) | 619 | static int device_pca953x_init(struct pca953x_chip *chip, u32 invert) |
606 | { | 620 | { |
607 | int ret; | 621 | int ret; |
608 | 622 | ||
@@ -621,7 +635,7 @@ out: | |||
621 | return ret; | 635 | return ret; |
622 | } | 636 | } |
623 | 637 | ||
624 | static int __devinit device_pca957x_init(struct pca953x_chip *chip, u32 invert) | 638 | static int device_pca957x_init(struct pca953x_chip *chip, u32 invert) |
625 | { | 639 | { |
626 | int ret; | 640 | int ret; |
627 | u32 val = 0; | 641 | u32 val = 0; |
@@ -652,7 +666,7 @@ out: | |||
652 | return ret; | 666 | return ret; |
653 | } | 667 | } |
654 | 668 | ||
655 | static int __devinit pca953x_probe(struct i2c_client *client, | 669 | static int pca953x_probe(struct i2c_client *client, |
656 | const struct i2c_device_id *id) | 670 | const struct i2c_device_id *id) |
657 | { | 671 | { |
658 | struct pca953x_platform_data *pdata; | 672 | struct pca953x_platform_data *pdata; |
@@ -751,9 +765,38 @@ static int pca953x_remove(struct i2c_client *client) | |||
751 | return 0; | 765 | return 0; |
752 | } | 766 | } |
753 | 767 | ||
768 | static const struct of_device_id pca953x_dt_ids[] = { | ||
769 | { .compatible = "nxp,pca9534", }, | ||
770 | { .compatible = "nxp,pca9535", }, | ||
771 | { .compatible = "nxp,pca9536", }, | ||
772 | { .compatible = "nxp,pca9537", }, | ||
773 | { .compatible = "nxp,pca9538", }, | ||
774 | { .compatible = "nxp,pca9539", }, | ||
775 | { .compatible = "nxp,pca9554", }, | ||
776 | { .compatible = "nxp,pca9555", }, | ||
777 | { .compatible = "nxp,pca9556", }, | ||
778 | { .compatible = "nxp,pca9557", }, | ||
779 | { .compatible = "nxp,pca9574", }, | ||
780 | { .compatible = "nxp,pca9575", }, | ||
781 | |||
782 | { .compatible = "maxim,max7310", }, | ||
783 | { .compatible = "maxim,max7312", }, | ||
784 | { .compatible = "maxim,max7313", }, | ||
785 | { .compatible = "maxim,max7315", }, | ||
786 | |||
787 | { .compatible = "ti,pca6107", }, | ||
788 | { .compatible = "ti,tca6408", }, | ||
789 | { .compatible = "ti,tca6416", }, | ||
790 | { .compatible = "ti,tca6424", }, | ||
791 | { } | ||
792 | }; | ||
793 | |||
794 | MODULE_DEVICE_TABLE(of, pca953x_dt_ids); | ||
795 | |||
754 | static struct i2c_driver pca953x_driver = { | 796 | static struct i2c_driver pca953x_driver = { |
755 | .driver = { | 797 | .driver = { |
756 | .name = "pca953x", | 798 | .name = "pca953x", |
799 | .of_match_table = pca953x_dt_ids, | ||
757 | }, | 800 | }, |
758 | .probe = pca953x_probe, | 801 | .probe = pca953x_probe, |
759 | .remove = pca953x_remove, | 802 | .remove = pca953x_remove, |
diff --git a/drivers/gpio/gpio-pcf857x.c b/drivers/gpio/gpio-pcf857x.c index 16af35cd2b10..a19b7457a726 100644 --- a/drivers/gpio/gpio-pcf857x.c +++ b/drivers/gpio/gpio-pcf857x.c | |||
@@ -223,11 +223,11 @@ static void pcf857x_irq_domain_cleanup(struct pcf857x *gpio) | |||
223 | 223 | ||
224 | static int pcf857x_irq_domain_init(struct pcf857x *gpio, | 224 | static int pcf857x_irq_domain_init(struct pcf857x *gpio, |
225 | struct pcf857x_platform_data *pdata, | 225 | struct pcf857x_platform_data *pdata, |
226 | struct device *dev) | 226 | struct i2c_client *client) |
227 | { | 227 | { |
228 | int status; | 228 | int status; |
229 | 229 | ||
230 | gpio->irq_domain = irq_domain_add_linear(dev->of_node, | 230 | gpio->irq_domain = irq_domain_add_linear(client->dev.of_node, |
231 | gpio->chip.ngpio, | 231 | gpio->chip.ngpio, |
232 | &pcf857x_irq_domain_ops, | 232 | &pcf857x_irq_domain_ops, |
233 | NULL); | 233 | NULL); |
@@ -235,15 +235,15 @@ static int pcf857x_irq_domain_init(struct pcf857x *gpio, | |||
235 | goto fail; | 235 | goto fail; |
236 | 236 | ||
237 | /* enable real irq */ | 237 | /* enable real irq */ |
238 | status = request_irq(pdata->irq, pcf857x_irq_demux, 0, | 238 | status = request_irq(client->irq, pcf857x_irq_demux, 0, |
239 | dev_name(dev), gpio); | 239 | dev_name(&client->dev), gpio); |
240 | if (status) | 240 | if (status) |
241 | goto fail; | 241 | goto fail; |
242 | 242 | ||
243 | /* enable gpio_to_irq() */ | 243 | /* enable gpio_to_irq() */ |
244 | INIT_WORK(&gpio->work, pcf857x_irq_demux_work); | 244 | INIT_WORK(&gpio->work, pcf857x_irq_demux_work); |
245 | gpio->chip.to_irq = pcf857x_to_irq; | 245 | gpio->chip.to_irq = pcf857x_to_irq; |
246 | gpio->irq = pdata->irq; | 246 | gpio->irq = client->irq; |
247 | 247 | ||
248 | return 0; | 248 | return 0; |
249 | 249 | ||
@@ -285,8 +285,8 @@ static int pcf857x_probe(struct i2c_client *client, | |||
285 | gpio->chip.ngpio = id->driver_data; | 285 | gpio->chip.ngpio = id->driver_data; |
286 | 286 | ||
287 | /* enable gpio_to_irq() if platform has settings */ | 287 | /* enable gpio_to_irq() if platform has settings */ |
288 | if (pdata && pdata->irq) { | 288 | if (pdata && client->irq) { |
289 | status = pcf857x_irq_domain_init(gpio, pdata, &client->dev); | 289 | status = pcf857x_irq_domain_init(gpio, pdata, client); |
290 | if (status < 0) { | 290 | if (status < 0) { |
291 | dev_err(&client->dev, "irq_domain init failed\n"); | 291 | dev_err(&client->dev, "irq_domain init failed\n"); |
292 | goto fail; | 292 | goto fail; |
@@ -368,15 +368,6 @@ static int pcf857x_probe(struct i2c_client *client, | |||
368 | if (status < 0) | 368 | if (status < 0) |
369 | goto fail; | 369 | goto fail; |
370 | 370 | ||
371 | /* NOTE: these chips can issue "some pin-changed" IRQs, which we | ||
372 | * don't yet even try to use. Among other issues, the relevant | ||
373 | * genirq state isn't available to modular drivers; and most irq | ||
374 | * methods can't be called from sleeping contexts. | ||
375 | */ | ||
376 | |||
377 | dev_info(&client->dev, "%s\n", | ||
378 | client->irq ? " (irq ignored)" : ""); | ||
379 | |||
380 | /* Let platform code set up the GPIOs and their users. | 371 | /* Let platform code set up the GPIOs and their users. |
381 | * Now is the first time anyone could use them. | 372 | * Now is the first time anyone could use them. |
382 | */ | 373 | */ |
@@ -388,13 +379,15 @@ static int pcf857x_probe(struct i2c_client *client, | |||
388 | dev_warn(&client->dev, "setup --> %d\n", status); | 379 | dev_warn(&client->dev, "setup --> %d\n", status); |
389 | } | 380 | } |
390 | 381 | ||
382 | dev_info(&client->dev, "probed\n"); | ||
383 | |||
391 | return 0; | 384 | return 0; |
392 | 385 | ||
393 | fail: | 386 | fail: |
394 | dev_dbg(&client->dev, "probe error %d for '%s'\n", | 387 | dev_dbg(&client->dev, "probe error %d for '%s'\n", |
395 | status, client->name); | 388 | status, client->name); |
396 | 389 | ||
397 | if (pdata && pdata->irq) | 390 | if (pdata && client->irq) |
398 | pcf857x_irq_domain_cleanup(gpio); | 391 | pcf857x_irq_domain_cleanup(gpio); |
399 | 392 | ||
400 | kfree(gpio); | 393 | kfree(gpio); |
@@ -418,7 +411,7 @@ static int pcf857x_remove(struct i2c_client *client) | |||
418 | } | 411 | } |
419 | } | 412 | } |
420 | 413 | ||
421 | if (pdata && pdata->irq) | 414 | if (pdata && client->irq) |
422 | pcf857x_irq_domain_cleanup(gpio); | 415 | pcf857x_irq_domain_cleanup(gpio); |
423 | 416 | ||
424 | status = gpiochip_remove(&gpio->chip); | 417 | status = gpiochip_remove(&gpio->chip); |
diff --git a/drivers/gpio/gpio-pch.c b/drivers/gpio/gpio-pch.c index 4ad0c4f9171c..cdf599687cf7 100644 --- a/drivers/gpio/gpio-pch.c +++ b/drivers/gpio/gpio-pch.c | |||
@@ -215,6 +215,7 @@ static void pch_gpio_setup(struct pch_gpio *chip) | |||
215 | struct gpio_chip *gpio = &chip->gpio; | 215 | struct gpio_chip *gpio = &chip->gpio; |
216 | 216 | ||
217 | gpio->label = dev_name(chip->dev); | 217 | gpio->label = dev_name(chip->dev); |
218 | gpio->dev = chip->dev; | ||
218 | gpio->owner = THIS_MODULE; | 219 | gpio->owner = THIS_MODULE; |
219 | gpio->direction_input = pch_gpio_direction_input; | 220 | gpio->direction_input = pch_gpio_direction_input; |
220 | gpio->get = pch_gpio_get; | 221 | gpio->get = pch_gpio_get; |
@@ -325,7 +326,7 @@ static irqreturn_t pch_gpio_handler(int irq, void *dev_id) | |||
325 | return ret; | 326 | return ret; |
326 | } | 327 | } |
327 | 328 | ||
328 | static __devinit void pch_gpio_alloc_generic_chip(struct pch_gpio *chip, | 329 | static void pch_gpio_alloc_generic_chip(struct pch_gpio *chip, |
329 | unsigned int irq_start, unsigned int num) | 330 | unsigned int irq_start, unsigned int num) |
330 | { | 331 | { |
331 | struct irq_chip_generic *gc; | 332 | struct irq_chip_generic *gc; |
@@ -345,7 +346,7 @@ static __devinit void pch_gpio_alloc_generic_chip(struct pch_gpio *chip, | |||
345 | IRQ_NOREQUEST | IRQ_NOPROBE, 0); | 346 | IRQ_NOREQUEST | IRQ_NOPROBE, 0); |
346 | } | 347 | } |
347 | 348 | ||
348 | static int __devinit pch_gpio_probe(struct pci_dev *pdev, | 349 | static int pch_gpio_probe(struct pci_dev *pdev, |
349 | const struct pci_device_id *id) | 350 | const struct pci_device_id *id) |
350 | { | 351 | { |
351 | s32 ret; | 352 | s32 ret; |
@@ -442,7 +443,7 @@ err_pci_enable: | |||
442 | return ret; | 443 | return ret; |
443 | } | 444 | } |
444 | 445 | ||
445 | static void __devexit pch_gpio_remove(struct pci_dev *pdev) | 446 | static void pch_gpio_remove(struct pci_dev *pdev) |
446 | { | 447 | { |
447 | int err; | 448 | int err; |
448 | struct pch_gpio *chip = pci_get_drvdata(pdev); | 449 | struct pch_gpio *chip = pci_get_drvdata(pdev); |
@@ -531,7 +532,7 @@ static struct pci_driver pch_gpio_driver = { | |||
531 | .name = "pch_gpio", | 532 | .name = "pch_gpio", |
532 | .id_table = pch_gpio_pcidev_id, | 533 | .id_table = pch_gpio_pcidev_id, |
533 | .probe = pch_gpio_probe, | 534 | .probe = pch_gpio_probe, |
534 | .remove = __devexit_p(pch_gpio_remove), | 535 | .remove = pch_gpio_remove, |
535 | .suspend = pch_gpio_suspend, | 536 | .suspend = pch_gpio_suspend, |
536 | .resume = pch_gpio_resume | 537 | .resume = pch_gpio_resume |
537 | }; | 538 | }; |
diff --git a/drivers/gpio/gpio-pl061.c b/drivers/gpio/gpio-pl061.c index b4b5da4fd2cc..c1720de18a4f 100644 --- a/drivers/gpio/gpio-pl061.c +++ b/drivers/gpio/gpio-pl061.c | |||
@@ -48,12 +48,7 @@ struct pl061_context_save_regs { | |||
48 | #endif | 48 | #endif |
49 | 49 | ||
50 | struct pl061_gpio { | 50 | struct pl061_gpio { |
51 | /* Each of the two spinlocks protects a different set of hardware | 51 | spinlock_t lock; |
52 | * regiters and data structurs. This decouples the code of the IRQ from | ||
53 | * the GPIO code. This also makes the case of a GPIO routine call from | ||
54 | * the IRQ code simpler. | ||
55 | */ | ||
56 | spinlock_t lock; /* GPIO registers */ | ||
57 | 52 | ||
58 | void __iomem *base; | 53 | void __iomem *base; |
59 | int irq_base; | 54 | int irq_base; |
@@ -216,39 +211,34 @@ static void __init pl061_init_gc(struct pl061_gpio *chip, int irq_base) | |||
216 | IRQ_GC_INIT_NESTED_LOCK, IRQ_NOREQUEST, 0); | 211 | IRQ_GC_INIT_NESTED_LOCK, IRQ_NOREQUEST, 0); |
217 | } | 212 | } |
218 | 213 | ||
219 | static int pl061_probe(struct amba_device *dev, const struct amba_id *id) | 214 | static int pl061_probe(struct amba_device *adev, const struct amba_id *id) |
220 | { | 215 | { |
221 | struct pl061_platform_data *pdata; | 216 | struct device *dev = &adev->dev; |
217 | struct pl061_platform_data *pdata = dev->platform_data; | ||
222 | struct pl061_gpio *chip; | 218 | struct pl061_gpio *chip; |
223 | int ret, irq, i; | 219 | int ret, irq, i; |
224 | 220 | ||
225 | chip = kzalloc(sizeof(*chip), GFP_KERNEL); | 221 | chip = devm_kzalloc(dev, sizeof(*chip), GFP_KERNEL); |
226 | if (chip == NULL) | 222 | if (chip == NULL) |
227 | return -ENOMEM; | 223 | return -ENOMEM; |
228 | 224 | ||
229 | pdata = dev->dev.platform_data; | ||
230 | if (pdata) { | 225 | if (pdata) { |
231 | chip->gc.base = pdata->gpio_base; | 226 | chip->gc.base = pdata->gpio_base; |
232 | chip->irq_base = pdata->irq_base; | 227 | chip->irq_base = pdata->irq_base; |
233 | } else if (dev->dev.of_node) { | 228 | } else if (adev->dev.of_node) { |
234 | chip->gc.base = -1; | 229 | chip->gc.base = -1; |
235 | chip->irq_base = 0; | 230 | chip->irq_base = 0; |
236 | } else { | 231 | } else |
237 | ret = -ENODEV; | 232 | return -ENODEV; |
238 | goto free_mem; | ||
239 | } | ||
240 | 233 | ||
241 | if (!request_mem_region(dev->res.start, | 234 | if (!devm_request_mem_region(dev, adev->res.start, |
242 | resource_size(&dev->res), "pl061")) { | 235 | resource_size(&adev->res), "pl061")) |
243 | ret = -EBUSY; | 236 | return -EBUSY; |
244 | goto free_mem; | ||
245 | } | ||
246 | 237 | ||
247 | chip->base = ioremap(dev->res.start, resource_size(&dev->res)); | 238 | chip->base = devm_ioremap(dev, adev->res.start, |
248 | if (chip->base == NULL) { | 239 | resource_size(&adev->res)); |
249 | ret = -ENOMEM; | 240 | if (chip->base == NULL) |
250 | goto release_region; | 241 | return -ENOMEM; |
251 | } | ||
252 | 242 | ||
253 | spin_lock_init(&chip->lock); | 243 | spin_lock_init(&chip->lock); |
254 | 244 | ||
@@ -258,13 +248,13 @@ static int pl061_probe(struct amba_device *dev, const struct amba_id *id) | |||
258 | chip->gc.set = pl061_set_value; | 248 | chip->gc.set = pl061_set_value; |
259 | chip->gc.to_irq = pl061_to_irq; | 249 | chip->gc.to_irq = pl061_to_irq; |
260 | chip->gc.ngpio = PL061_GPIO_NR; | 250 | chip->gc.ngpio = PL061_GPIO_NR; |
261 | chip->gc.label = dev_name(&dev->dev); | 251 | chip->gc.label = dev_name(dev); |
262 | chip->gc.dev = &dev->dev; | 252 | chip->gc.dev = dev; |
263 | chip->gc.owner = THIS_MODULE; | 253 | chip->gc.owner = THIS_MODULE; |
264 | 254 | ||
265 | ret = gpiochip_add(&chip->gc); | 255 | ret = gpiochip_add(&chip->gc); |
266 | if (ret) | 256 | if (ret) |
267 | goto iounmap; | 257 | return ret; |
268 | 258 | ||
269 | /* | 259 | /* |
270 | * irq_chip support | 260 | * irq_chip support |
@@ -276,11 +266,10 @@ static int pl061_probe(struct amba_device *dev, const struct amba_id *id) | |||
276 | pl061_init_gc(chip, chip->irq_base); | 266 | pl061_init_gc(chip, chip->irq_base); |
277 | 267 | ||
278 | writeb(0, chip->base + GPIOIE); /* disable irqs */ | 268 | writeb(0, chip->base + GPIOIE); /* disable irqs */ |
279 | irq = dev->irq[0]; | 269 | irq = adev->irq[0]; |
280 | if (irq < 0) { | 270 | if (irq < 0) |
281 | ret = -ENODEV; | 271 | return -ENODEV; |
282 | goto iounmap; | 272 | |
283 | } | ||
284 | irq_set_chained_handler(irq, pl061_irq_handler); | 273 | irq_set_chained_handler(irq, pl061_irq_handler); |
285 | irq_set_handler_data(irq, chip); | 274 | irq_set_handler_data(irq, chip); |
286 | 275 | ||
@@ -294,18 +283,9 @@ static int pl061_probe(struct amba_device *dev, const struct amba_id *id) | |||
294 | } | 283 | } |
295 | } | 284 | } |
296 | 285 | ||
297 | amba_set_drvdata(dev, chip); | 286 | amba_set_drvdata(adev, chip); |
298 | 287 | ||
299 | return 0; | 288 | return 0; |
300 | |||
301 | iounmap: | ||
302 | iounmap(chip->base); | ||
303 | release_region: | ||
304 | release_mem_region(dev->res.start, resource_size(&dev->res)); | ||
305 | free_mem: | ||
306 | kfree(chip); | ||
307 | |||
308 | return ret; | ||
309 | } | 289 | } |
310 | 290 | ||
311 | #ifdef CONFIG_PM | 291 | #ifdef CONFIG_PM |
diff --git a/drivers/gpio/gpio-pxa.c b/drivers/gpio/gpio-pxa.c index 98d52cb3fd1a..8325f580c0f1 100644 --- a/drivers/gpio/gpio-pxa.c +++ b/drivers/gpio/gpio-pxa.c | |||
@@ -250,7 +250,7 @@ static int pxa_gpio_of_xlate(struct gpio_chip *gc, | |||
250 | } | 250 | } |
251 | #endif | 251 | #endif |
252 | 252 | ||
253 | static int __devinit pxa_init_gpio_chip(int gpio_end, | 253 | static int pxa_init_gpio_chip(int gpio_end, |
254 | int (*set_wake)(unsigned int, unsigned int)) | 254 | int (*set_wake)(unsigned int, unsigned int)) |
255 | { | 255 | { |
256 | int i, gpio, nbanks = gpio_to_bank(gpio_end) + 1; | 256 | int i, gpio, nbanks = gpio_to_bank(gpio_end) + 1; |
@@ -448,7 +448,7 @@ static int pxa_gpio_nums(void) | |||
448 | } else if (cpu_is_pxa27x()) { | 448 | } else if (cpu_is_pxa27x()) { |
449 | count = 120; | 449 | count = 120; |
450 | gpio_type = PXA27X_GPIO; | 450 | gpio_type = PXA27X_GPIO; |
451 | } else if (cpu_is_pxa93x() || cpu_is_pxa95x()) { | 451 | } else if (cpu_is_pxa93x()) { |
452 | count = 191; | 452 | count = 191; |
453 | gpio_type = PXA93X_GPIO; | 453 | gpio_type = PXA93X_GPIO; |
454 | } else if (cpu_is_pxa3xx()) { | 454 | } else if (cpu_is_pxa3xx()) { |
@@ -490,7 +490,7 @@ const struct irq_domain_ops pxa_irq_domain_ops = { | |||
490 | .xlate = irq_domain_xlate_twocell, | 490 | .xlate = irq_domain_xlate_twocell, |
491 | }; | 491 | }; |
492 | 492 | ||
493 | static int __devinit pxa_gpio_probe_dt(struct platform_device *pdev) | 493 | static int pxa_gpio_probe_dt(struct platform_device *pdev) |
494 | { | 494 | { |
495 | int ret, nr_banks, nr_gpios; | 495 | int ret, nr_banks, nr_gpios; |
496 | struct device_node *prev, *next, *np = pdev->dev.of_node; | 496 | struct device_node *prev, *next, *np = pdev->dev.of_node; |
@@ -537,7 +537,7 @@ err: | |||
537 | #define pxa_gpio_probe_dt(pdev) (-1) | 537 | #define pxa_gpio_probe_dt(pdev) (-1) |
538 | #endif | 538 | #endif |
539 | 539 | ||
540 | static int __devinit pxa_gpio_probe(struct platform_device *pdev) | 540 | static int pxa_gpio_probe(struct platform_device *pdev) |
541 | { | 541 | { |
542 | struct pxa_gpio_chip *c; | 542 | struct pxa_gpio_chip *c; |
543 | struct resource *res; | 543 | struct resource *res; |
diff --git a/drivers/gpio/gpio-rc5t583.c b/drivers/gpio/gpio-rc5t583.c index 08428bf17718..e63d6a397e17 100644 --- a/drivers/gpio/gpio-rc5t583.c +++ b/drivers/gpio/gpio-rc5t583.c | |||
@@ -111,7 +111,7 @@ static void rc5t583_gpio_free(struct gpio_chip *gc, unsigned offset) | |||
111 | rc5t583_set_bits(parent, RC5T583_GPIO_PGSEL, BIT(offset)); | 111 | rc5t583_set_bits(parent, RC5T583_GPIO_PGSEL, BIT(offset)); |
112 | } | 112 | } |
113 | 113 | ||
114 | static int __devinit rc5t583_gpio_probe(struct platform_device *pdev) | 114 | static int rc5t583_gpio_probe(struct platform_device *pdev) |
115 | { | 115 | { |
116 | struct rc5t583 *rc5t583 = dev_get_drvdata(pdev->dev.parent); | 116 | struct rc5t583 *rc5t583 = dev_get_drvdata(pdev->dev.parent); |
117 | struct rc5t583_platform_data *pdata = dev_get_platdata(rc5t583->dev); | 117 | struct rc5t583_platform_data *pdata = dev_get_platdata(rc5t583->dev); |
@@ -146,7 +146,7 @@ static int __devinit rc5t583_gpio_probe(struct platform_device *pdev) | |||
146 | return gpiochip_add(&rc5t583_gpio->gpio_chip); | 146 | return gpiochip_add(&rc5t583_gpio->gpio_chip); |
147 | } | 147 | } |
148 | 148 | ||
149 | static int __devexit rc5t583_gpio_remove(struct platform_device *pdev) | 149 | static int rc5t583_gpio_remove(struct platform_device *pdev) |
150 | { | 150 | { |
151 | struct rc5t583_gpio *rc5t583_gpio = platform_get_drvdata(pdev); | 151 | struct rc5t583_gpio *rc5t583_gpio = platform_get_drvdata(pdev); |
152 | 152 | ||
@@ -159,7 +159,7 @@ static struct platform_driver rc5t583_gpio_driver = { | |||
159 | .owner = THIS_MODULE, | 159 | .owner = THIS_MODULE, |
160 | }, | 160 | }, |
161 | .probe = rc5t583_gpio_probe, | 161 | .probe = rc5t583_gpio_probe, |
162 | .remove = __devexit_p(rc5t583_gpio_remove), | 162 | .remove = rc5t583_gpio_remove, |
163 | }; | 163 | }; |
164 | 164 | ||
165 | static int __init rc5t583_gpio_init(void) | 165 | static int __init rc5t583_gpio_init(void) |
diff --git a/drivers/gpio/gpio-rdc321x.c b/drivers/gpio/gpio-rdc321x.c index b62d443e9a59..1bf55f67f7a5 100644 --- a/drivers/gpio/gpio-rdc321x.c +++ b/drivers/gpio/gpio-rdc321x.c | |||
@@ -128,7 +128,7 @@ static int rdc_gpio_direction_input(struct gpio_chip *chip, unsigned gpio) | |||
128 | /* | 128 | /* |
129 | * Cache the initial value of both GPIO data registers | 129 | * Cache the initial value of both GPIO data registers |
130 | */ | 130 | */ |
131 | static int __devinit rdc321x_gpio_probe(struct platform_device *pdev) | 131 | static int rdc321x_gpio_probe(struct platform_device *pdev) |
132 | { | 132 | { |
133 | int err; | 133 | int err; |
134 | struct resource *r; | 134 | struct resource *r; |
@@ -206,7 +206,7 @@ out_free: | |||
206 | return err; | 206 | return err; |
207 | } | 207 | } |
208 | 208 | ||
209 | static int __devexit rdc321x_gpio_remove(struct platform_device *pdev) | 209 | static int rdc321x_gpio_remove(struct platform_device *pdev) |
210 | { | 210 | { |
211 | int ret; | 211 | int ret; |
212 | struct rdc321x_gpio *rdc321x_gpio_dev = platform_get_drvdata(pdev); | 212 | struct rdc321x_gpio *rdc321x_gpio_dev = platform_get_drvdata(pdev); |
@@ -225,7 +225,7 @@ static struct platform_driver rdc321x_gpio_driver = { | |||
225 | .driver.name = "rdc321x-gpio", | 225 | .driver.name = "rdc321x-gpio", |
226 | .driver.owner = THIS_MODULE, | 226 | .driver.owner = THIS_MODULE, |
227 | .probe = rdc321x_gpio_probe, | 227 | .probe = rdc321x_gpio_probe, |
228 | .remove = __devexit_p(rdc321x_gpio_remove), | 228 | .remove = rdc321x_gpio_remove, |
229 | }; | 229 | }; |
230 | 230 | ||
231 | module_platform_driver(rdc321x_gpio_driver); | 231 | module_platform_driver(rdc321x_gpio_driver); |
diff --git a/drivers/gpio/gpio-samsung.c b/drivers/gpio/gpio-samsung.c index a006f0db15af..01f7fe955590 100644 --- a/drivers/gpio/gpio-samsung.c +++ b/drivers/gpio/gpio-samsung.c | |||
@@ -42,12 +42,6 @@ | |||
42 | #include <plat/gpio-fns.h> | 42 | #include <plat/gpio-fns.h> |
43 | #include <plat/pm.h> | 43 | #include <plat/pm.h> |
44 | 44 | ||
45 | #ifndef DEBUG_GPIO | ||
46 | #define gpio_dbg(x...) do { } while (0) | ||
47 | #else | ||
48 | #define gpio_dbg(x...) printk(KERN_DEBUG x) | ||
49 | #endif | ||
50 | |||
51 | int samsung_gpio_setpull_updown(struct samsung_gpio_chip *chip, | 45 | int samsung_gpio_setpull_updown(struct samsung_gpio_chip *chip, |
52 | unsigned int off, samsung_gpio_pull_t pull) | 46 | unsigned int off, samsung_gpio_pull_t pull) |
53 | { | 47 | { |
@@ -596,10 +590,13 @@ static int samsung_gpiolib_4bit_input(struct gpio_chip *chip, | |||
596 | unsigned long con; | 590 | unsigned long con; |
597 | 591 | ||
598 | con = __raw_readl(base + GPIOCON_OFF); | 592 | con = __raw_readl(base + GPIOCON_OFF); |
599 | con &= ~(0xf << con_4bit_shift(offset)); | 593 | if (ourchip->bitmap_gpio_int & BIT(offset)) |
594 | con |= 0xf << con_4bit_shift(offset); | ||
595 | else | ||
596 | con &= ~(0xf << con_4bit_shift(offset)); | ||
600 | __raw_writel(con, base + GPIOCON_OFF); | 597 | __raw_writel(con, base + GPIOCON_OFF); |
601 | 598 | ||
602 | gpio_dbg("%s: %p: CON now %08lx\n", __func__, base, con); | 599 | pr_debug("%s: %p: CON now %08lx\n", __func__, base, con); |
603 | 600 | ||
604 | return 0; | 601 | return 0; |
605 | } | 602 | } |
@@ -627,7 +624,7 @@ static int samsung_gpiolib_4bit_output(struct gpio_chip *chip, | |||
627 | __raw_writel(con, base + GPIOCON_OFF); | 624 | __raw_writel(con, base + GPIOCON_OFF); |
628 | __raw_writel(dat, base + GPIODAT_OFF); | 625 | __raw_writel(dat, base + GPIODAT_OFF); |
629 | 626 | ||
630 | gpio_dbg("%s: %p: CON %08lx, DAT %08lx\n", __func__, base, con, dat); | 627 | pr_debug("%s: %p: CON %08lx, DAT %08lx\n", __func__, base, con, dat); |
631 | 628 | ||
632 | return 0; | 629 | return 0; |
633 | } | 630 | } |
@@ -671,7 +668,7 @@ static int samsung_gpiolib_4bit2_input(struct gpio_chip *chip, | |||
671 | con &= ~(0xf << con_4bit_shift(offset)); | 668 | con &= ~(0xf << con_4bit_shift(offset)); |
672 | __raw_writel(con, regcon); | 669 | __raw_writel(con, regcon); |
673 | 670 | ||
674 | gpio_dbg("%s: %p: CON %08lx\n", __func__, base, con); | 671 | pr_debug("%s: %p: CON %08lx\n", __func__, base, con); |
675 | 672 | ||
676 | return 0; | 673 | return 0; |
677 | } | 674 | } |
@@ -706,7 +703,7 @@ static int samsung_gpiolib_4bit2_output(struct gpio_chip *chip, | |||
706 | __raw_writel(con, regcon); | 703 | __raw_writel(con, regcon); |
707 | __raw_writel(dat, base + GPIODAT_OFF); | 704 | __raw_writel(dat, base + GPIODAT_OFF); |
708 | 705 | ||
709 | gpio_dbg("%s: %p: CON %08lx, DAT %08lx\n", __func__, base, con, dat); | 706 | pr_debug("%s: %p: CON %08lx, DAT %08lx\n", __func__, base, con, dat); |
710 | 707 | ||
711 | return 0; | 708 | return 0; |
712 | } | 709 | } |
@@ -926,10 +923,10 @@ static void __init samsung_gpiolib_add(struct samsung_gpio_chip *chip) | |||
926 | #ifdef CONFIG_PM | 923 | #ifdef CONFIG_PM |
927 | if (chip->pm != NULL) { | 924 | if (chip->pm != NULL) { |
928 | if (!chip->pm->save || !chip->pm->resume) | 925 | if (!chip->pm->save || !chip->pm->resume) |
929 | printk(KERN_ERR "gpio: %s has missing PM functions\n", | 926 | pr_err("gpio: %s has missing PM functions\n", |
930 | gc->label); | 927 | gc->label); |
931 | } else | 928 | } else |
932 | printk(KERN_ERR "gpio: %s has no PM function\n", gc->label); | 929 | pr_err("gpio: %s has no PM function\n", gc->label); |
933 | #endif | 930 | #endif |
934 | 931 | ||
935 | /* gpiochip_add() prints own failure message on error. */ | 932 | /* gpiochip_add() prints own failure message on error. */ |
@@ -1081,6 +1078,8 @@ static void __init samsung_gpiolib_add_4bit_chips(struct samsung_gpio_chip *chip | |||
1081 | if ((base != NULL) && (chip->base == NULL)) | 1078 | if ((base != NULL) && (chip->base == NULL)) |
1082 | chip->base = base + ((i) * 0x20); | 1079 | chip->base = base + ((i) * 0x20); |
1083 | 1080 | ||
1081 | chip->bitmap_gpio_int = 0; | ||
1082 | |||
1084 | samsung_gpiolib_add(chip); | 1083 | samsung_gpiolib_add(chip); |
1085 | } | 1084 | } |
1086 | } | 1085 | } |
@@ -2797,27 +2796,6 @@ static __init void exynos4_gpiolib_init(void) | |||
2797 | int group = 0; | 2796 | int group = 0; |
2798 | void __iomem *gpx_base; | 2797 | void __iomem *gpx_base; |
2799 | 2798 | ||
2800 | #ifdef CONFIG_PINCTRL_SAMSUNG | ||
2801 | /* | ||
2802 | * This gpio driver includes support for device tree support and | ||
2803 | * there are platforms using it. In order to maintain | ||
2804 | * compatibility with those platforms, and to allow non-dt | ||
2805 | * Exynos4210 platforms to use this gpiolib support, a check | ||
2806 | * is added to find out if there is a active pin-controller | ||
2807 | * driver support available. If it is available, this gpiolib | ||
2808 | * support is ignored and the gpiolib support available in | ||
2809 | * pin-controller driver is used. This is a temporary check and | ||
2810 | * will go away when all of the Exynos4210 platforms have | ||
2811 | * switched to using device tree and the pin-ctrl driver. | ||
2812 | */ | ||
2813 | struct device_node *pctrl_np; | ||
2814 | const char *pctrl_compat = "samsung,pinctrl-exynos4210"; | ||
2815 | pctrl_np = of_find_compatible_node(NULL, NULL, pctrl_compat); | ||
2816 | if (pctrl_np) | ||
2817 | if (of_device_is_available(pctrl_np)) | ||
2818 | return; | ||
2819 | #endif | ||
2820 | |||
2821 | /* gpio part1 */ | 2799 | /* gpio part1 */ |
2822 | gpio_base1 = ioremap(EXYNOS4_PA_GPIO1, SZ_4K); | 2800 | gpio_base1 = ioremap(EXYNOS4_PA_GPIO1, SZ_4K); |
2823 | if (gpio_base1 == NULL) { | 2801 | if (gpio_base1 == NULL) { |
@@ -3032,6 +3010,28 @@ static __init int samsung_gpiolib_init(void) | |||
3032 | int i, nr_chips; | 3010 | int i, nr_chips; |
3033 | int group = 0; | 3011 | int group = 0; |
3034 | 3012 | ||
3013 | #ifdef CONFIG_PINCTRL_SAMSUNG | ||
3014 | /* | ||
3015 | * This gpio driver includes support for device tree support and there | ||
3016 | * are platforms using it. In order to maintain compatibility with those | ||
3017 | * platforms, and to allow non-dt Exynos4210 platforms to use this | ||
3018 | * gpiolib support, a check is added to find out if there is a active | ||
3019 | * pin-controller driver support available. If it is available, this | ||
3020 | * gpiolib support is ignored and the gpiolib support available in | ||
3021 | * pin-controller driver is used. This is a temporary check and will go | ||
3022 | * away when all of the Exynos4210 platforms have switched to using | ||
3023 | * device tree and the pin-ctrl driver. | ||
3024 | */ | ||
3025 | struct device_node *pctrl_np; | ||
3026 | static const struct of_device_id exynos_pinctrl_ids[] = { | ||
3027 | { .compatible = "samsung,pinctrl-exynos4210", }, | ||
3028 | { .compatible = "samsung,pinctrl-exynos4x12", }, | ||
3029 | }; | ||
3030 | for_each_matching_node(pctrl_np, exynos_pinctrl_ids) | ||
3031 | if (pctrl_np && of_device_is_available(pctrl_np)) | ||
3032 | return -ENODEV; | ||
3033 | #endif | ||
3034 | |||
3035 | samsung_gpiolib_set_cfg(samsung_gpio_cfgs, ARRAY_SIZE(samsung_gpio_cfgs)); | 3035 | samsung_gpiolib_set_cfg(samsung_gpio_cfgs, ARRAY_SIZE(samsung_gpio_cfgs)); |
3036 | 3036 | ||
3037 | if (soc_is_s3c24xx()) { | 3037 | if (soc_is_s3c24xx()) { |
diff --git a/drivers/gpio/gpio-sch.c b/drivers/gpio/gpio-sch.c index 8707d4572a06..edae963f4625 100644 --- a/drivers/gpio/gpio-sch.c +++ b/drivers/gpio/gpio-sch.c | |||
@@ -185,7 +185,7 @@ static struct gpio_chip sch_gpio_resume = { | |||
185 | .set = sch_gpio_resume_set, | 185 | .set = sch_gpio_resume_set, |
186 | }; | 186 | }; |
187 | 187 | ||
188 | static int __devinit sch_gpio_probe(struct platform_device *pdev) | 188 | static int sch_gpio_probe(struct platform_device *pdev) |
189 | { | 189 | { |
190 | struct resource *res; | 190 | struct resource *res; |
191 | int err, id; | 191 | int err, id; |
@@ -271,7 +271,7 @@ err_sch_gpio_core: | |||
271 | return err; | 271 | return err; |
272 | } | 272 | } |
273 | 273 | ||
274 | static int __devexit sch_gpio_remove(struct platform_device *pdev) | 274 | static int sch_gpio_remove(struct platform_device *pdev) |
275 | { | 275 | { |
276 | struct resource *res; | 276 | struct resource *res; |
277 | if (gpio_ba) { | 277 | if (gpio_ba) { |
@@ -303,7 +303,7 @@ static struct platform_driver sch_gpio_driver = { | |||
303 | .owner = THIS_MODULE, | 303 | .owner = THIS_MODULE, |
304 | }, | 304 | }, |
305 | .probe = sch_gpio_probe, | 305 | .probe = sch_gpio_probe, |
306 | .remove = __devexit_p(sch_gpio_remove), | 306 | .remove = sch_gpio_remove, |
307 | }; | 307 | }; |
308 | 308 | ||
309 | module_platform_driver(sch_gpio_driver); | 309 | module_platform_driver(sch_gpio_driver); |
diff --git a/drivers/gpio/gpio-sodaville.c b/drivers/gpio/gpio-sodaville.c index e25f73130b40..88f374ac7753 100644 --- a/drivers/gpio/gpio-sodaville.c +++ b/drivers/gpio/gpio-sodaville.c | |||
@@ -129,7 +129,7 @@ static struct irq_domain_ops irq_domain_sdv_ops = { | |||
129 | .xlate = sdv_xlate, | 129 | .xlate = sdv_xlate, |
130 | }; | 130 | }; |
131 | 131 | ||
132 | static __devinit int sdv_register_irqsupport(struct sdv_gpio_chip_data *sd, | 132 | static int sdv_register_irqsupport(struct sdv_gpio_chip_data *sd, |
133 | struct pci_dev *pdev) | 133 | struct pci_dev *pdev) |
134 | { | 134 | { |
135 | struct irq_chip_type *ct; | 135 | struct irq_chip_type *ct; |
@@ -186,7 +186,7 @@ out_free_desc: | |||
186 | return ret; | 186 | return ret; |
187 | } | 187 | } |
188 | 188 | ||
189 | static int __devinit sdv_gpio_probe(struct pci_dev *pdev, | 189 | static int sdv_gpio_probe(struct pci_dev *pdev, |
190 | const struct pci_device_id *pci_id) | 190 | const struct pci_device_id *pci_id) |
191 | { | 191 | { |
192 | struct sdv_gpio_chip_data *sd; | 192 | struct sdv_gpio_chip_data *sd; |
diff --git a/drivers/gpio/gpio-spear-spics.c b/drivers/gpio/gpio-spear-spics.c new file mode 100644 index 000000000000..5f45fc4ed5d1 --- /dev/null +++ b/drivers/gpio/gpio-spear-spics.c | |||
@@ -0,0 +1,217 @@ | |||
1 | /* | ||
2 | * SPEAr platform SPI chipselect abstraction over gpiolib | ||
3 | * | ||
4 | * Copyright (C) 2012 ST Microelectronics | ||
5 | * Shiraz Hashim <shiraz.hashim@st.com> | ||
6 | * | ||
7 | * This file is licensed under the terms of the GNU General Public | ||
8 | * License version 2. This program is licensed "as is" without any | ||
9 | * warranty of any kind, whether express or implied. | ||
10 | */ | ||
11 | |||
12 | #include <linux/err.h> | ||
13 | #include <linux/gpio.h> | ||
14 | #include <linux/io.h> | ||
15 | #include <linux/module.h> | ||
16 | #include <linux/of.h> | ||
17 | #include <linux/platform_device.h> | ||
18 | #include <linux/types.h> | ||
19 | |||
20 | /* maximum chipselects */ | ||
21 | #define NUM_OF_GPIO 4 | ||
22 | |||
23 | /* | ||
24 | * Provision is available on some SPEAr SoCs to control ARM PL022 spi cs | ||
25 | * through system registers. This register lies outside spi (pl022) | ||
26 | * address space into system registers. | ||
27 | * | ||
28 | * It provides control for spi chip select lines so that any chipselect | ||
29 | * (out of 4 possible chipselects in pl022) can be made low to select | ||
30 | * the particular slave. | ||
31 | */ | ||
32 | |||
33 | /** | ||
34 | * struct spear_spics - represents spi chip select control | ||
35 | * @base: base address | ||
36 | * @perip_cfg: configuration register | ||
37 | * @sw_enable_bit: bit to enable s/w control over chipselects | ||
38 | * @cs_value_bit: bit to program high or low chipselect | ||
39 | * @cs_enable_mask: mask to select bits required to select chipselect | ||
40 | * @cs_enable_shift: bit pos of cs_enable_mask | ||
41 | * @use_count: use count of a spi controller cs lines | ||
42 | * @last_off: stores last offset caller of set_value() | ||
43 | * @chip: gpio_chip abstraction | ||
44 | */ | ||
45 | struct spear_spics { | ||
46 | void __iomem *base; | ||
47 | u32 perip_cfg; | ||
48 | u32 sw_enable_bit; | ||
49 | u32 cs_value_bit; | ||
50 | u32 cs_enable_mask; | ||
51 | u32 cs_enable_shift; | ||
52 | unsigned long use_count; | ||
53 | int last_off; | ||
54 | struct gpio_chip chip; | ||
55 | }; | ||
56 | |||
57 | /* gpio framework specific routines */ | ||
58 | static int spics_get_value(struct gpio_chip *chip, unsigned offset) | ||
59 | { | ||
60 | return -ENXIO; | ||
61 | } | ||
62 | |||
63 | static void spics_set_value(struct gpio_chip *chip, unsigned offset, int value) | ||
64 | { | ||
65 | struct spear_spics *spics = container_of(chip, struct spear_spics, | ||
66 | chip); | ||
67 | u32 tmp; | ||
68 | |||
69 | /* select chip select from register */ | ||
70 | tmp = readl_relaxed(spics->base + spics->perip_cfg); | ||
71 | if (spics->last_off != offset) { | ||
72 | spics->last_off = offset; | ||
73 | tmp &= ~(spics->cs_enable_mask << spics->cs_enable_shift); | ||
74 | tmp |= offset << spics->cs_enable_shift; | ||
75 | } | ||
76 | |||
77 | /* toggle chip select line */ | ||
78 | tmp &= ~(0x1 << spics->cs_value_bit); | ||
79 | tmp |= value << spics->cs_value_bit; | ||
80 | writel_relaxed(tmp, spics->base + spics->perip_cfg); | ||
81 | } | ||
82 | |||
83 | static int spics_direction_input(struct gpio_chip *chip, unsigned offset) | ||
84 | { | ||
85 | return -ENXIO; | ||
86 | } | ||
87 | |||
88 | static int spics_direction_output(struct gpio_chip *chip, unsigned offset, | ||
89 | int value) | ||
90 | { | ||
91 | spics_set_value(chip, offset, value); | ||
92 | return 0; | ||
93 | } | ||
94 | |||
95 | static int spics_request(struct gpio_chip *chip, unsigned offset) | ||
96 | { | ||
97 | struct spear_spics *spics = container_of(chip, struct spear_spics, | ||
98 | chip); | ||
99 | u32 tmp; | ||
100 | |||
101 | if (!spics->use_count++) { | ||
102 | tmp = readl_relaxed(spics->base + spics->perip_cfg); | ||
103 | tmp |= 0x1 << spics->sw_enable_bit; | ||
104 | tmp |= 0x1 << spics->cs_value_bit; | ||
105 | writel_relaxed(tmp, spics->base + spics->perip_cfg); | ||
106 | } | ||
107 | |||
108 | return 0; | ||
109 | } | ||
110 | |||
111 | static void spics_free(struct gpio_chip *chip, unsigned offset) | ||
112 | { | ||
113 | struct spear_spics *spics = container_of(chip, struct spear_spics, | ||
114 | chip); | ||
115 | u32 tmp; | ||
116 | |||
117 | if (!--spics->use_count) { | ||
118 | tmp = readl_relaxed(spics->base + spics->perip_cfg); | ||
119 | tmp &= ~(0x1 << spics->sw_enable_bit); | ||
120 | writel_relaxed(tmp, spics->base + spics->perip_cfg); | ||
121 | } | ||
122 | } | ||
123 | |||
124 | static int spics_gpio_probe(struct platform_device *pdev) | ||
125 | { | ||
126 | struct device_node *np = pdev->dev.of_node; | ||
127 | struct spear_spics *spics; | ||
128 | struct resource *res; | ||
129 | int ret; | ||
130 | |||
131 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
132 | if (!res) { | ||
133 | dev_err(&pdev->dev, "invalid IORESOURCE_MEM\n"); | ||
134 | return -EBUSY; | ||
135 | } | ||
136 | |||
137 | spics = devm_kzalloc(&pdev->dev, sizeof(*spics), GFP_KERNEL); | ||
138 | if (!spics) { | ||
139 | dev_err(&pdev->dev, "memory allocation fail\n"); | ||
140 | return -ENOMEM; | ||
141 | } | ||
142 | |||
143 | spics->base = devm_request_and_ioremap(&pdev->dev, res); | ||
144 | if (!spics->base) { | ||
145 | dev_err(&pdev->dev, "request and ioremap fail\n"); | ||
146 | return -ENOMEM; | ||
147 | } | ||
148 | |||
149 | if (of_property_read_u32(np, "st-spics,peripcfg-reg", | ||
150 | &spics->perip_cfg)) | ||
151 | goto err_dt_data; | ||
152 | if (of_property_read_u32(np, "st-spics,sw-enable-bit", | ||
153 | &spics->sw_enable_bit)) | ||
154 | goto err_dt_data; | ||
155 | if (of_property_read_u32(np, "st-spics,cs-value-bit", | ||
156 | &spics->cs_value_bit)) | ||
157 | goto err_dt_data; | ||
158 | if (of_property_read_u32(np, "st-spics,cs-enable-mask", | ||
159 | &spics->cs_enable_mask)) | ||
160 | goto err_dt_data; | ||
161 | if (of_property_read_u32(np, "st-spics,cs-enable-shift", | ||
162 | &spics->cs_enable_shift)) | ||
163 | goto err_dt_data; | ||
164 | |||
165 | platform_set_drvdata(pdev, spics); | ||
166 | |||
167 | spics->chip.ngpio = NUM_OF_GPIO; | ||
168 | spics->chip.base = -1; | ||
169 | spics->chip.request = spics_request; | ||
170 | spics->chip.free = spics_free; | ||
171 | spics->chip.direction_input = spics_direction_input; | ||
172 | spics->chip.direction_output = spics_direction_output; | ||
173 | spics->chip.get = spics_get_value; | ||
174 | spics->chip.set = spics_set_value; | ||
175 | spics->chip.label = dev_name(&pdev->dev); | ||
176 | spics->chip.dev = &pdev->dev; | ||
177 | spics->chip.owner = THIS_MODULE; | ||
178 | spics->last_off = -1; | ||
179 | |||
180 | ret = gpiochip_add(&spics->chip); | ||
181 | if (ret) { | ||
182 | dev_err(&pdev->dev, "unable to add gpio chip\n"); | ||
183 | return ret; | ||
184 | } | ||
185 | |||
186 | dev_info(&pdev->dev, "spear spics registered\n"); | ||
187 | return 0; | ||
188 | |||
189 | err_dt_data: | ||
190 | dev_err(&pdev->dev, "DT probe failed\n"); | ||
191 | return -EINVAL; | ||
192 | } | ||
193 | |||
194 | static const struct of_device_id spics_gpio_of_match[] = { | ||
195 | { .compatible = "st,spear-spics-gpio" }, | ||
196 | {} | ||
197 | }; | ||
198 | MODULE_DEVICE_TABLE(of, spics_gpio_of_match); | ||
199 | |||
200 | static struct platform_driver spics_gpio_driver = { | ||
201 | .probe = spics_gpio_probe, | ||
202 | .driver = { | ||
203 | .owner = THIS_MODULE, | ||
204 | .name = "spear-spics-gpio", | ||
205 | .of_match_table = spics_gpio_of_match, | ||
206 | }, | ||
207 | }; | ||
208 | |||
209 | static int __init spics_gpio_init(void) | ||
210 | { | ||
211 | return platform_driver_register(&spics_gpio_driver); | ||
212 | } | ||
213 | subsys_initcall(spics_gpio_init); | ||
214 | |||
215 | MODULE_AUTHOR("Shiraz Hashim <shiraz.hashim@st.com>"); | ||
216 | MODULE_DESCRIPTION("ST Microlectronics SPEAr SPI Chip Select Abstraction"); | ||
217 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/gpio/gpio-sta2x11.c b/drivers/gpio/gpio-sta2x11.c index 6064fb376e11..558542552aae 100644 --- a/drivers/gpio/gpio-sta2x11.c +++ b/drivers/gpio/gpio-sta2x11.c | |||
@@ -320,7 +320,7 @@ static irqreturn_t gsta_gpio_handler(int irq, void *dev_id) | |||
320 | return ret; | 320 | return ret; |
321 | } | 321 | } |
322 | 322 | ||
323 | static __devinit void gsta_alloc_irq_chip(struct gsta_gpio *chip) | 323 | static void gsta_alloc_irq_chip(struct gsta_gpio *chip) |
324 | { | 324 | { |
325 | struct irq_chip_generic *gc; | 325 | struct irq_chip_generic *gc; |
326 | struct irq_chip_type *ct; | 326 | struct irq_chip_type *ct; |
@@ -353,7 +353,7 @@ static __devinit void gsta_alloc_irq_chip(struct gsta_gpio *chip) | |||
353 | } | 353 | } |
354 | 354 | ||
355 | /* The platform device used here is instantiated by the MFD device */ | 355 | /* The platform device used here is instantiated by the MFD device */ |
356 | static int __devinit gsta_probe(struct platform_device *dev) | 356 | static int gsta_probe(struct platform_device *dev) |
357 | { | 357 | { |
358 | int i, err; | 358 | int i, err; |
359 | struct pci_dev *pdev; | 359 | struct pci_dev *pdev; |
diff --git a/drivers/gpio/gpio-stmpe.c b/drivers/gpio/gpio-stmpe.c index dce34727bbf8..770476a9da87 100644 --- a/drivers/gpio/gpio-stmpe.c +++ b/drivers/gpio/gpio-stmpe.c | |||
@@ -11,7 +11,9 @@ | |||
11 | #include <linux/slab.h> | 11 | #include <linux/slab.h> |
12 | #include <linux/gpio.h> | 12 | #include <linux/gpio.h> |
13 | #include <linux/irq.h> | 13 | #include <linux/irq.h> |
14 | #include <linux/irqdomain.h> | ||
14 | #include <linux/interrupt.h> | 15 | #include <linux/interrupt.h> |
16 | #include <linux/of.h> | ||
15 | #include <linux/mfd/stmpe.h> | 17 | #include <linux/mfd/stmpe.h> |
16 | 18 | ||
17 | /* | 19 | /* |
@@ -28,6 +30,7 @@ struct stmpe_gpio { | |||
28 | struct stmpe *stmpe; | 30 | struct stmpe *stmpe; |
29 | struct device *dev; | 31 | struct device *dev; |
30 | struct mutex irq_lock; | 32 | struct mutex irq_lock; |
33 | struct irq_domain *domain; | ||
31 | 34 | ||
32 | int irq_base; | 35 | int irq_base; |
33 | unsigned norequest_mask; | 36 | unsigned norequest_mask; |
@@ -103,7 +106,7 @@ static int stmpe_gpio_to_irq(struct gpio_chip *chip, unsigned offset) | |||
103 | { | 106 | { |
104 | struct stmpe_gpio *stmpe_gpio = to_stmpe_gpio(chip); | 107 | struct stmpe_gpio *stmpe_gpio = to_stmpe_gpio(chip); |
105 | 108 | ||
106 | return stmpe_gpio->irq_base + offset; | 109 | return irq_create_mapping(stmpe_gpio->domain, offset); |
107 | } | 110 | } |
108 | 111 | ||
109 | static int stmpe_gpio_request(struct gpio_chip *chip, unsigned offset) | 112 | static int stmpe_gpio_request(struct gpio_chip *chip, unsigned offset) |
@@ -132,7 +135,7 @@ static struct gpio_chip template_chip = { | |||
132 | static int stmpe_gpio_irq_set_type(struct irq_data *d, unsigned int type) | 135 | static int stmpe_gpio_irq_set_type(struct irq_data *d, unsigned int type) |
133 | { | 136 | { |
134 | struct stmpe_gpio *stmpe_gpio = irq_data_get_irq_chip_data(d); | 137 | struct stmpe_gpio *stmpe_gpio = irq_data_get_irq_chip_data(d); |
135 | int offset = d->irq - stmpe_gpio->irq_base; | 138 | int offset = d->hwirq; |
136 | int regoffset = offset / 8; | 139 | int regoffset = offset / 8; |
137 | int mask = 1 << (offset % 8); | 140 | int mask = 1 << (offset % 8); |
138 | 141 | ||
@@ -199,7 +202,7 @@ static void stmpe_gpio_irq_sync_unlock(struct irq_data *d) | |||
199 | static void stmpe_gpio_irq_mask(struct irq_data *d) | 202 | static void stmpe_gpio_irq_mask(struct irq_data *d) |
200 | { | 203 | { |
201 | struct stmpe_gpio *stmpe_gpio = irq_data_get_irq_chip_data(d); | 204 | struct stmpe_gpio *stmpe_gpio = irq_data_get_irq_chip_data(d); |
202 | int offset = d->irq - stmpe_gpio->irq_base; | 205 | int offset = d->hwirq; |
203 | int regoffset = offset / 8; | 206 | int regoffset = offset / 8; |
204 | int mask = 1 << (offset % 8); | 207 | int mask = 1 << (offset % 8); |
205 | 208 | ||
@@ -209,7 +212,7 @@ static void stmpe_gpio_irq_mask(struct irq_data *d) | |||
209 | static void stmpe_gpio_irq_unmask(struct irq_data *d) | 212 | static void stmpe_gpio_irq_unmask(struct irq_data *d) |
210 | { | 213 | { |
211 | struct stmpe_gpio *stmpe_gpio = irq_data_get_irq_chip_data(d); | 214 | struct stmpe_gpio *stmpe_gpio = irq_data_get_irq_chip_data(d); |
212 | int offset = d->irq - stmpe_gpio->irq_base; | 215 | int offset = d->hwirq; |
213 | int regoffset = offset / 8; | 216 | int regoffset = offset / 8; |
214 | int mask = 1 << (offset % 8); | 217 | int mask = 1 << (offset % 8); |
215 | 218 | ||
@@ -251,8 +254,9 @@ static irqreturn_t stmpe_gpio_irq(int irq, void *dev) | |||
251 | while (stat) { | 254 | while (stat) { |
252 | int bit = __ffs(stat); | 255 | int bit = __ffs(stat); |
253 | int line = bank * 8 + bit; | 256 | int line = bank * 8 + bit; |
257 | int virq = irq_find_mapping(stmpe_gpio->domain, line); | ||
254 | 258 | ||
255 | handle_nested_irq(stmpe_gpio->irq_base + line); | 259 | handle_nested_irq(virq); |
256 | stat &= ~(1 << bit); | 260 | stat &= ~(1 << bit); |
257 | } | 261 | } |
258 | 262 | ||
@@ -267,43 +271,61 @@ static irqreturn_t stmpe_gpio_irq(int irq, void *dev) | |||
267 | return IRQ_HANDLED; | 271 | return IRQ_HANDLED; |
268 | } | 272 | } |
269 | 273 | ||
270 | static int __devinit stmpe_gpio_irq_init(struct stmpe_gpio *stmpe_gpio) | 274 | int stmpe_gpio_irq_map(struct irq_domain *d, unsigned int virq, |
275 | irq_hw_number_t hwirq) | ||
271 | { | 276 | { |
272 | int base = stmpe_gpio->irq_base; | 277 | struct stmpe_gpio *stmpe_gpio = d->host_data; |
273 | int irq; | 278 | |
279 | if (!stmpe_gpio) | ||
280 | return -EINVAL; | ||
274 | 281 | ||
275 | for (irq = base; irq < base + stmpe_gpio->chip.ngpio; irq++) { | 282 | irq_set_chip_data(hwirq, stmpe_gpio); |
276 | irq_set_chip_data(irq, stmpe_gpio); | 283 | irq_set_chip_and_handler(hwirq, &stmpe_gpio_irq_chip, |
277 | irq_set_chip_and_handler(irq, &stmpe_gpio_irq_chip, | 284 | handle_simple_irq); |
278 | handle_simple_irq); | 285 | irq_set_nested_thread(hwirq, 1); |
279 | irq_set_nested_thread(irq, 1); | ||
280 | #ifdef CONFIG_ARM | 286 | #ifdef CONFIG_ARM |
281 | set_irq_flags(irq, IRQF_VALID); | 287 | set_irq_flags(hwirq, IRQF_VALID); |
282 | #else | 288 | #else |
283 | irq_set_noprobe(irq); | 289 | irq_set_noprobe(hwirq); |
284 | #endif | 290 | #endif |
285 | } | ||
286 | 291 | ||
287 | return 0; | 292 | return 0; |
288 | } | 293 | } |
289 | 294 | ||
290 | static void stmpe_gpio_irq_remove(struct stmpe_gpio *stmpe_gpio) | 295 | void stmpe_gpio_irq_unmap(struct irq_domain *d, unsigned int virq) |
291 | { | 296 | { |
292 | int base = stmpe_gpio->irq_base; | ||
293 | int irq; | ||
294 | |||
295 | for (irq = base; irq < base + stmpe_gpio->chip.ngpio; irq++) { | ||
296 | #ifdef CONFIG_ARM | 297 | #ifdef CONFIG_ARM |
297 | set_irq_flags(irq, 0); | 298 | set_irq_flags(virq, 0); |
298 | #endif | 299 | #endif |
299 | irq_set_chip_and_handler(irq, NULL, NULL); | 300 | irq_set_chip_and_handler(virq, NULL, NULL); |
300 | irq_set_chip_data(irq, NULL); | 301 | irq_set_chip_data(virq, NULL); |
302 | } | ||
303 | |||
304 | static const struct irq_domain_ops stmpe_gpio_irq_simple_ops = { | ||
305 | .unmap = stmpe_gpio_irq_unmap, | ||
306 | .map = stmpe_gpio_irq_map, | ||
307 | .xlate = irq_domain_xlate_twocell, | ||
308 | }; | ||
309 | |||
310 | static int stmpe_gpio_irq_init(struct stmpe_gpio *stmpe_gpio) | ||
311 | { | ||
312 | int base = stmpe_gpio->irq_base; | ||
313 | |||
314 | stmpe_gpio->domain = irq_domain_add_simple(NULL, | ||
315 | stmpe_gpio->chip.ngpio, base, | ||
316 | &stmpe_gpio_irq_simple_ops, stmpe_gpio); | ||
317 | if (!stmpe_gpio->domain) { | ||
318 | dev_err(stmpe_gpio->dev, "failed to create irqdomain\n"); | ||
319 | return -ENOSYS; | ||
301 | } | 320 | } |
321 | |||
322 | return 0; | ||
302 | } | 323 | } |
303 | 324 | ||
304 | static int __devinit stmpe_gpio_probe(struct platform_device *pdev) | 325 | static int stmpe_gpio_probe(struct platform_device *pdev) |
305 | { | 326 | { |
306 | struct stmpe *stmpe = dev_get_drvdata(pdev->dev.parent); | 327 | struct stmpe *stmpe = dev_get_drvdata(pdev->dev.parent); |
328 | struct device_node *np = pdev->dev.of_node; | ||
307 | struct stmpe_gpio_platform_data *pdata; | 329 | struct stmpe_gpio_platform_data *pdata; |
308 | struct stmpe_gpio *stmpe_gpio; | 330 | struct stmpe_gpio *stmpe_gpio; |
309 | int ret; | 331 | int ret; |
@@ -321,13 +343,17 @@ static int __devinit stmpe_gpio_probe(struct platform_device *pdev) | |||
321 | 343 | ||
322 | stmpe_gpio->dev = &pdev->dev; | 344 | stmpe_gpio->dev = &pdev->dev; |
323 | stmpe_gpio->stmpe = stmpe; | 345 | stmpe_gpio->stmpe = stmpe; |
324 | stmpe_gpio->norequest_mask = pdata ? pdata->norequest_mask : 0; | ||
325 | |||
326 | stmpe_gpio->chip = template_chip; | 346 | stmpe_gpio->chip = template_chip; |
327 | stmpe_gpio->chip.ngpio = stmpe->num_gpios; | 347 | stmpe_gpio->chip.ngpio = stmpe->num_gpios; |
328 | stmpe_gpio->chip.dev = &pdev->dev; | 348 | stmpe_gpio->chip.dev = &pdev->dev; |
329 | stmpe_gpio->chip.base = pdata ? pdata->gpio_base : -1; | 349 | stmpe_gpio->chip.base = pdata ? pdata->gpio_base : -1; |
330 | 350 | ||
351 | if (pdata) | ||
352 | stmpe_gpio->norequest_mask = pdata->norequest_mask; | ||
353 | else if (np) | ||
354 | of_property_read_u32(np, "st,norequest-mask", | ||
355 | &stmpe_gpio->norequest_mask); | ||
356 | |||
331 | if (irq >= 0) | 357 | if (irq >= 0) |
332 | stmpe_gpio->irq_base = stmpe->irq_base + STMPE_INT_GPIO(0); | 358 | stmpe_gpio->irq_base = stmpe->irq_base + STMPE_INT_GPIO(0); |
333 | else | 359 | else |
@@ -348,7 +374,7 @@ static int __devinit stmpe_gpio_probe(struct platform_device *pdev) | |||
348 | IRQF_ONESHOT, "stmpe-gpio", stmpe_gpio); | 374 | IRQF_ONESHOT, "stmpe-gpio", stmpe_gpio); |
349 | if (ret) { | 375 | if (ret) { |
350 | dev_err(&pdev->dev, "unable to get irq: %d\n", ret); | 376 | dev_err(&pdev->dev, "unable to get irq: %d\n", ret); |
351 | goto out_removeirq; | 377 | goto out_disable; |
352 | } | 378 | } |
353 | } | 379 | } |
354 | 380 | ||
@@ -368,9 +394,6 @@ static int __devinit stmpe_gpio_probe(struct platform_device *pdev) | |||
368 | out_freeirq: | 394 | out_freeirq: |
369 | if (irq >= 0) | 395 | if (irq >= 0) |
370 | free_irq(irq, stmpe_gpio); | 396 | free_irq(irq, stmpe_gpio); |
371 | out_removeirq: | ||
372 | if (irq >= 0) | ||
373 | stmpe_gpio_irq_remove(stmpe_gpio); | ||
374 | out_disable: | 397 | out_disable: |
375 | stmpe_disable(stmpe, STMPE_BLOCK_GPIO); | 398 | stmpe_disable(stmpe, STMPE_BLOCK_GPIO); |
376 | out_free: | 399 | out_free: |
@@ -378,7 +401,7 @@ out_free: | |||
378 | return ret; | 401 | return ret; |
379 | } | 402 | } |
380 | 403 | ||
381 | static int __devexit stmpe_gpio_remove(struct platform_device *pdev) | 404 | static int stmpe_gpio_remove(struct platform_device *pdev) |
382 | { | 405 | { |
383 | struct stmpe_gpio *stmpe_gpio = platform_get_drvdata(pdev); | 406 | struct stmpe_gpio *stmpe_gpio = platform_get_drvdata(pdev); |
384 | struct stmpe *stmpe = stmpe_gpio->stmpe; | 407 | struct stmpe *stmpe = stmpe_gpio->stmpe; |
@@ -398,10 +421,9 @@ static int __devexit stmpe_gpio_remove(struct platform_device *pdev) | |||
398 | 421 | ||
399 | stmpe_disable(stmpe, STMPE_BLOCK_GPIO); | 422 | stmpe_disable(stmpe, STMPE_BLOCK_GPIO); |
400 | 423 | ||
401 | if (irq >= 0) { | 424 | if (irq >= 0) |
402 | free_irq(irq, stmpe_gpio); | 425 | free_irq(irq, stmpe_gpio); |
403 | stmpe_gpio_irq_remove(stmpe_gpio); | 426 | |
404 | } | ||
405 | platform_set_drvdata(pdev, NULL); | 427 | platform_set_drvdata(pdev, NULL); |
406 | kfree(stmpe_gpio); | 428 | kfree(stmpe_gpio); |
407 | 429 | ||
@@ -412,7 +434,7 @@ static struct platform_driver stmpe_gpio_driver = { | |||
412 | .driver.name = "stmpe-gpio", | 434 | .driver.name = "stmpe-gpio", |
413 | .driver.owner = THIS_MODULE, | 435 | .driver.owner = THIS_MODULE, |
414 | .probe = stmpe_gpio_probe, | 436 | .probe = stmpe_gpio_probe, |
415 | .remove = __devexit_p(stmpe_gpio_remove), | 437 | .remove = stmpe_gpio_remove, |
416 | }; | 438 | }; |
417 | 439 | ||
418 | static int __init stmpe_gpio_init(void) | 440 | static int __init stmpe_gpio_init(void) |
diff --git a/drivers/gpio/gpio-stp-xway.c b/drivers/gpio/gpio-stp-xway.c index 8bead0bb6459..85841ee70b17 100644 --- a/drivers/gpio/gpio-stp-xway.c +++ b/drivers/gpio/gpio-stp-xway.c | |||
@@ -197,7 +197,7 @@ static int xway_stp_hw_init(struct xway_stp *chip) | |||
197 | return 0; | 197 | return 0; |
198 | } | 198 | } |
199 | 199 | ||
200 | static int __devinit xway_stp_probe(struct platform_device *pdev) | 200 | static int xway_stp_probe(struct platform_device *pdev) |
201 | { | 201 | { |
202 | struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 202 | struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
203 | const __be32 *shadow, *groups, *dsl, *phy; | 203 | const __be32 *shadow, *groups, *dsl, *phy; |
diff --git a/drivers/gpio/gpio-sx150x.c b/drivers/gpio/gpio-sx150x.c index eb3e215d2396..796b6c42fa70 100644 --- a/drivers/gpio/gpio-sx150x.c +++ b/drivers/gpio/gpio-sx150x.c | |||
@@ -575,7 +575,7 @@ static void sx150x_remove_irq_chip(struct sx150x_chip *chip) | |||
575 | } | 575 | } |
576 | } | 576 | } |
577 | 577 | ||
578 | static int __devinit sx150x_probe(struct i2c_client *client, | 578 | static int sx150x_probe(struct i2c_client *client, |
579 | const struct i2c_device_id *id) | 579 | const struct i2c_device_id *id) |
580 | { | 580 | { |
581 | static const u32 i2c_funcs = I2C_FUNC_SMBUS_BYTE_DATA | | 581 | static const u32 i2c_funcs = I2C_FUNC_SMBUS_BYTE_DATA | |
@@ -622,7 +622,7 @@ probe_fail_pre_gpiochip_add: | |||
622 | return rc; | 622 | return rc; |
623 | } | 623 | } |
624 | 624 | ||
625 | static int __devexit sx150x_remove(struct i2c_client *client) | 625 | static int sx150x_remove(struct i2c_client *client) |
626 | { | 626 | { |
627 | struct sx150x_chip *chip; | 627 | struct sx150x_chip *chip; |
628 | int rc; | 628 | int rc; |
@@ -646,7 +646,7 @@ static struct i2c_driver sx150x_driver = { | |||
646 | .owner = THIS_MODULE | 646 | .owner = THIS_MODULE |
647 | }, | 647 | }, |
648 | .probe = sx150x_probe, | 648 | .probe = sx150x_probe, |
649 | .remove = __devexit_p(sx150x_remove), | 649 | .remove = sx150x_remove, |
650 | .id_table = sx150x_id, | 650 | .id_table = sx150x_id, |
651 | }; | 651 | }; |
652 | 652 | ||
diff --git a/drivers/gpio/gpio-tc3589x.c b/drivers/gpio/gpio-tc3589x.c index 1e48317e70fb..c0595bbf3268 100644 --- a/drivers/gpio/gpio-tc3589x.c +++ b/drivers/gpio/gpio-tc3589x.c | |||
@@ -292,17 +292,15 @@ static int tc3589x_gpio_irq_init(struct tc3589x_gpio *tc3589x_gpio, | |||
292 | { | 292 | { |
293 | int base = tc3589x_gpio->irq_base; | 293 | int base = tc3589x_gpio->irq_base; |
294 | 294 | ||
295 | if (base) { | 295 | /* |
296 | tc3589x_gpio->domain = irq_domain_add_legacy( | 296 | * If this results in a linear domain, irq_create_mapping() will |
297 | NULL, tc3589x_gpio->chip.ngpio, base, | 297 | * take care of allocating IRQ descriptors at runtime. When a base |
298 | 0, &tc3589x_irq_ops, tc3589x_gpio); | 298 | * is provided, the IRQ descriptors will be allocated when the |
299 | } | 299 | * domain is instantiated. |
300 | else { | 300 | */ |
301 | tc3589x_gpio->domain = irq_domain_add_linear( | 301 | tc3589x_gpio->domain = irq_domain_add_simple(np, |
302 | np, tc3589x_gpio->chip.ngpio, | 302 | tc3589x_gpio->chip.ngpio, base, &tc3589x_irq_ops, |
303 | &tc3589x_irq_ops, tc3589x_gpio); | 303 | tc3589x_gpio); |
304 | } | ||
305 | |||
306 | if (!tc3589x_gpio->domain) { | 304 | if (!tc3589x_gpio->domain) { |
307 | dev_err(tc3589x_gpio->dev, "Failed to create irqdomain\n"); | 305 | dev_err(tc3589x_gpio->dev, "Failed to create irqdomain\n"); |
308 | return -ENOSYS; | 306 | return -ENOSYS; |
@@ -311,7 +309,7 @@ static int tc3589x_gpio_irq_init(struct tc3589x_gpio *tc3589x_gpio, | |||
311 | return 0; | 309 | return 0; |
312 | } | 310 | } |
313 | 311 | ||
314 | static int __devinit tc3589x_gpio_probe(struct platform_device *pdev) | 312 | static int tc3589x_gpio_probe(struct platform_device *pdev) |
315 | { | 313 | { |
316 | struct tc3589x *tc3589x = dev_get_drvdata(pdev->dev.parent); | 314 | struct tc3589x *tc3589x = dev_get_drvdata(pdev->dev.parent); |
317 | struct tc3589x_gpio_platform_data *pdata; | 315 | struct tc3589x_gpio_platform_data *pdata; |
@@ -389,7 +387,7 @@ out_free: | |||
389 | return ret; | 387 | return ret; |
390 | } | 388 | } |
391 | 389 | ||
392 | static int __devexit tc3589x_gpio_remove(struct platform_device *pdev) | 390 | static int tc3589x_gpio_remove(struct platform_device *pdev) |
393 | { | 391 | { |
394 | struct tc3589x_gpio *tc3589x_gpio = platform_get_drvdata(pdev); | 392 | struct tc3589x_gpio *tc3589x_gpio = platform_get_drvdata(pdev); |
395 | struct tc3589x *tc3589x = tc3589x_gpio->tc3589x; | 393 | struct tc3589x *tc3589x = tc3589x_gpio->tc3589x; |
@@ -419,7 +417,7 @@ static struct platform_driver tc3589x_gpio_driver = { | |||
419 | .driver.name = "tc3589x-gpio", | 417 | .driver.name = "tc3589x-gpio", |
420 | .driver.owner = THIS_MODULE, | 418 | .driver.owner = THIS_MODULE, |
421 | .probe = tc3589x_gpio_probe, | 419 | .probe = tc3589x_gpio_probe, |
422 | .remove = __devexit_p(tc3589x_gpio_remove), | 420 | .remove = tc3589x_gpio_remove, |
423 | }; | 421 | }; |
424 | 422 | ||
425 | static int __init tc3589x_gpio_init(void) | 423 | static int __init tc3589x_gpio_init(void) |
diff --git a/drivers/gpio/gpio-tegra.c b/drivers/gpio/gpio-tegra.c index d982593d7563..63cb643d4b5a 100644 --- a/drivers/gpio/gpio-tegra.c +++ b/drivers/gpio/gpio-tegra.c | |||
@@ -27,6 +27,7 @@ | |||
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 | #include <linux/pinctrl/consumer.h> |
30 | #include <linux/pm.h> | ||
30 | 31 | ||
31 | #include <asm/mach/irq.h> | 32 | #include <asm/mach/irq.h> |
32 | 33 | ||
@@ -64,7 +65,7 @@ struct tegra_gpio_bank { | |||
64 | int bank; | 65 | int bank; |
65 | int irq; | 66 | int irq; |
66 | spinlock_t lvl_lock[4]; | 67 | spinlock_t lvl_lock[4]; |
67 | #ifdef CONFIG_PM | 68 | #ifdef CONFIG_PM_SLEEP |
68 | u32 cnf[4]; | 69 | u32 cnf[4]; |
69 | u32 out[4]; | 70 | u32 out[4]; |
70 | u32 oe[4]; | 71 | u32 oe[4]; |
@@ -109,20 +110,18 @@ static void tegra_gpio_enable(int gpio) | |||
109 | { | 110 | { |
110 | tegra_gpio_mask_write(GPIO_MSK_CNF(gpio), gpio, 1); | 111 | tegra_gpio_mask_write(GPIO_MSK_CNF(gpio), gpio, 1); |
111 | } | 112 | } |
112 | EXPORT_SYMBOL_GPL(tegra_gpio_enable); | ||
113 | 113 | ||
114 | static void tegra_gpio_disable(int gpio) | 114 | static void tegra_gpio_disable(int gpio) |
115 | { | 115 | { |
116 | tegra_gpio_mask_write(GPIO_MSK_CNF(gpio), gpio, 0); | 116 | tegra_gpio_mask_write(GPIO_MSK_CNF(gpio), gpio, 0); |
117 | } | 117 | } |
118 | EXPORT_SYMBOL_GPL(tegra_gpio_disable); | ||
119 | 118 | ||
120 | int tegra_gpio_request(struct gpio_chip *chip, unsigned offset) | 119 | static int tegra_gpio_request(struct gpio_chip *chip, unsigned offset) |
121 | { | 120 | { |
122 | return pinctrl_request_gpio(offset); | 121 | return pinctrl_request_gpio(offset); |
123 | } | 122 | } |
124 | 123 | ||
125 | void tegra_gpio_free(struct gpio_chip *chip, unsigned offset) | 124 | static void tegra_gpio_free(struct gpio_chip *chip, unsigned offset) |
126 | { | 125 | { |
127 | pinctrl_free_gpio(offset); | 126 | pinctrl_free_gpio(offset); |
128 | tegra_gpio_disable(offset); | 127 | tegra_gpio_disable(offset); |
@@ -135,6 +134,11 @@ static void tegra_gpio_set(struct gpio_chip *chip, unsigned offset, int value) | |||
135 | 134 | ||
136 | static int tegra_gpio_get(struct gpio_chip *chip, unsigned offset) | 135 | static int tegra_gpio_get(struct gpio_chip *chip, unsigned offset) |
137 | { | 136 | { |
137 | /* If gpio is in output mode then read from the out value */ | ||
138 | if ((tegra_gpio_readl(GPIO_OE(offset)) >> GPIO_BIT(offset)) & 1) | ||
139 | return (tegra_gpio_readl(GPIO_OUT(offset)) >> | ||
140 | GPIO_BIT(offset)) & 0x1; | ||
141 | |||
138 | return (tegra_gpio_readl(GPIO_IN(offset)) >> GPIO_BIT(offset)) & 0x1; | 142 | return (tegra_gpio_readl(GPIO_IN(offset)) >> GPIO_BIT(offset)) & 0x1; |
139 | } | 143 | } |
140 | 144 | ||
@@ -285,8 +289,8 @@ static void tegra_gpio_irq_handler(unsigned int irq, struct irq_desc *desc) | |||
285 | 289 | ||
286 | } | 290 | } |
287 | 291 | ||
288 | #ifdef CONFIG_PM | 292 | #ifdef CONFIG_PM_SLEEP |
289 | void tegra_gpio_resume(void) | 293 | static int tegra_gpio_resume(struct device *dev) |
290 | { | 294 | { |
291 | unsigned long flags; | 295 | unsigned long flags; |
292 | int b; | 296 | int b; |
@@ -308,9 +312,10 @@ void tegra_gpio_resume(void) | |||
308 | } | 312 | } |
309 | 313 | ||
310 | local_irq_restore(flags); | 314 | local_irq_restore(flags); |
315 | return 0; | ||
311 | } | 316 | } |
312 | 317 | ||
313 | void tegra_gpio_suspend(void) | 318 | static int tegra_gpio_suspend(struct device *dev) |
314 | { | 319 | { |
315 | unsigned long flags; | 320 | unsigned long flags; |
316 | int b; | 321 | int b; |
@@ -330,6 +335,7 @@ void tegra_gpio_suspend(void) | |||
330 | } | 335 | } |
331 | } | 336 | } |
332 | local_irq_restore(flags); | 337 | local_irq_restore(flags); |
338 | return 0; | ||
333 | } | 339 | } |
334 | 340 | ||
335 | static int tegra_gpio_wake_enable(struct irq_data *d, unsigned int enable) | 341 | static int tegra_gpio_wake_enable(struct irq_data *d, unsigned int enable) |
@@ -345,11 +351,15 @@ static struct irq_chip tegra_gpio_irq_chip = { | |||
345 | .irq_mask = tegra_gpio_irq_mask, | 351 | .irq_mask = tegra_gpio_irq_mask, |
346 | .irq_unmask = tegra_gpio_irq_unmask, | 352 | .irq_unmask = tegra_gpio_irq_unmask, |
347 | .irq_set_type = tegra_gpio_irq_set_type, | 353 | .irq_set_type = tegra_gpio_irq_set_type, |
348 | #ifdef CONFIG_PM | 354 | #ifdef CONFIG_PM_SLEEP |
349 | .irq_set_wake = tegra_gpio_wake_enable, | 355 | .irq_set_wake = tegra_gpio_wake_enable, |
350 | #endif | 356 | #endif |
351 | }; | 357 | }; |
352 | 358 | ||
359 | static const struct dev_pm_ops tegra_gpio_pm_ops = { | ||
360 | SET_SYSTEM_SLEEP_PM_OPS(tegra_gpio_suspend, tegra_gpio_resume) | ||
361 | }; | ||
362 | |||
353 | struct tegra_gpio_soc_config { | 363 | struct tegra_gpio_soc_config { |
354 | u32 bank_stride; | 364 | u32 bank_stride; |
355 | u32 upper_offset; | 365 | u32 upper_offset; |
@@ -365,7 +375,7 @@ static struct tegra_gpio_soc_config tegra30_gpio_config = { | |||
365 | .upper_offset = 0x80, | 375 | .upper_offset = 0x80, |
366 | }; | 376 | }; |
367 | 377 | ||
368 | static struct of_device_id tegra_gpio_of_match[] __devinitdata = { | 378 | static struct of_device_id tegra_gpio_of_match[] = { |
369 | { .compatible = "nvidia,tegra30-gpio", .data = &tegra30_gpio_config }, | 379 | { .compatible = "nvidia,tegra30-gpio", .data = &tegra30_gpio_config }, |
370 | { .compatible = "nvidia,tegra20-gpio", .data = &tegra20_gpio_config }, | 380 | { .compatible = "nvidia,tegra20-gpio", .data = &tegra20_gpio_config }, |
371 | { }, | 381 | { }, |
@@ -376,11 +386,10 @@ static struct of_device_id tegra_gpio_of_match[] __devinitdata = { | |||
376 | */ | 386 | */ |
377 | static struct lock_class_key gpio_lock_class; | 387 | static struct lock_class_key gpio_lock_class; |
378 | 388 | ||
379 | static int __devinit tegra_gpio_probe(struct platform_device *pdev) | 389 | static int tegra_gpio_probe(struct platform_device *pdev) |
380 | { | 390 | { |
381 | const struct of_device_id *match; | 391 | const struct of_device_id *match; |
382 | struct tegra_gpio_soc_config *config; | 392 | struct tegra_gpio_soc_config *config; |
383 | int irq_base; | ||
384 | struct resource *res; | 393 | struct resource *res; |
385 | struct tegra_gpio_bank *bank; | 394 | struct tegra_gpio_bank *bank; |
386 | int gpio; | 395 | int gpio; |
@@ -417,14 +426,11 @@ static int __devinit tegra_gpio_probe(struct platform_device *pdev) | |||
417 | return -ENODEV; | 426 | return -ENODEV; |
418 | } | 427 | } |
419 | 428 | ||
420 | irq_base = irq_alloc_descs(-1, 0, tegra_gpio_chip.ngpio, 0); | 429 | irq_domain = irq_domain_add_linear(pdev->dev.of_node, |
421 | if (irq_base < 0) { | 430 | tegra_gpio_chip.ngpio, |
422 | dev_err(&pdev->dev, "Couldn't allocate IRQ numbers\n"); | ||
423 | return -ENODEV; | ||
424 | } | ||
425 | irq_domain = irq_domain_add_legacy(pdev->dev.of_node, | ||
426 | tegra_gpio_chip.ngpio, irq_base, 0, | ||
427 | &irq_domain_simple_ops, NULL); | 431 | &irq_domain_simple_ops, NULL); |
432 | if (!irq_domain) | ||
433 | return -ENODEV; | ||
428 | 434 | ||
429 | for (i = 0; i < tegra_gpio_bank_count; i++) { | 435 | for (i = 0; i < tegra_gpio_bank_count; i++) { |
430 | res = platform_get_resource(pdev, IORESOURCE_IRQ, i); | 436 | res = platform_get_resource(pdev, IORESOURCE_IRQ, i); |
@@ -464,7 +470,7 @@ static int __devinit tegra_gpio_probe(struct platform_device *pdev) | |||
464 | gpiochip_add(&tegra_gpio_chip); | 470 | gpiochip_add(&tegra_gpio_chip); |
465 | 471 | ||
466 | for (gpio = 0; gpio < tegra_gpio_chip.ngpio; gpio++) { | 472 | for (gpio = 0; gpio < tegra_gpio_chip.ngpio; gpio++) { |
467 | int irq = irq_find_mapping(irq_domain, gpio); | 473 | int irq = irq_create_mapping(irq_domain, gpio); |
468 | /* No validity check; all Tegra GPIOs are valid IRQs */ | 474 | /* No validity check; all Tegra GPIOs are valid IRQs */ |
469 | 475 | ||
470 | bank = &tegra_gpio_banks[GPIO_BANK(gpio)]; | 476 | bank = &tegra_gpio_banks[GPIO_BANK(gpio)]; |
@@ -493,6 +499,7 @@ static struct platform_driver tegra_gpio_driver = { | |||
493 | .driver = { | 499 | .driver = { |
494 | .name = "tegra-gpio", | 500 | .name = "tegra-gpio", |
495 | .owner = THIS_MODULE, | 501 | .owner = THIS_MODULE, |
502 | .pm = &tegra_gpio_pm_ops, | ||
496 | .of_match_table = tegra_gpio_of_match, | 503 | .of_match_table = tegra_gpio_of_match, |
497 | }, | 504 | }, |
498 | .probe = tegra_gpio_probe, | 505 | .probe = tegra_gpio_probe, |
diff --git a/drivers/gpio/gpio-timberdale.c b/drivers/gpio/gpio-timberdale.c index 1a3e2b9b4772..702cca9284f1 100644 --- a/drivers/gpio/gpio-timberdale.c +++ b/drivers/gpio/gpio-timberdale.c | |||
@@ -222,7 +222,7 @@ static struct irq_chip timbgpio_irqchip = { | |||
222 | .irq_set_type = timbgpio_irq_type, | 222 | .irq_set_type = timbgpio_irq_type, |
223 | }; | 223 | }; |
224 | 224 | ||
225 | static int __devinit timbgpio_probe(struct platform_device *pdev) | 225 | static int timbgpio_probe(struct platform_device *pdev) |
226 | { | 226 | { |
227 | int err, i; | 227 | int err, i; |
228 | struct gpio_chip *gc; | 228 | struct gpio_chip *gc; |
@@ -316,7 +316,7 @@ err_mem: | |||
316 | return err; | 316 | return err; |
317 | } | 317 | } |
318 | 318 | ||
319 | static int __devexit timbgpio_remove(struct platform_device *pdev) | 319 | static int timbgpio_remove(struct platform_device *pdev) |
320 | { | 320 | { |
321 | int err; | 321 | int err; |
322 | struct timbgpio_platform_data *pdata = pdev->dev.platform_data; | 322 | struct timbgpio_platform_data *pdata = pdev->dev.platform_data; |
diff --git a/drivers/gpio/gpio-tps6586x.c b/drivers/gpio/gpio-tps6586x.c index 2526b3bb0fae..29e8e750bd49 100644 --- a/drivers/gpio/gpio-tps6586x.c +++ b/drivers/gpio/gpio-tps6586x.c | |||
@@ -80,7 +80,15 @@ static int tps6586x_gpio_output(struct gpio_chip *gc, unsigned offset, | |||
80 | val, mask); | 80 | val, mask); |
81 | } | 81 | } |
82 | 82 | ||
83 | static int __devinit tps6586x_gpio_probe(struct platform_device *pdev) | 83 | static int tps6586x_gpio_to_irq(struct gpio_chip *gc, unsigned offset) |
84 | { | ||
85 | struct tps6586x_gpio *tps6586x_gpio = to_tps6586x_gpio(gc); | ||
86 | |||
87 | return tps6586x_irq_get_virq(tps6586x_gpio->parent, | ||
88 | TPS6586X_INT_PLDO_0 + offset); | ||
89 | } | ||
90 | |||
91 | static int tps6586x_gpio_probe(struct platform_device *pdev) | ||
84 | { | 92 | { |
85 | struct tps6586x_platform_data *pdata; | 93 | struct tps6586x_platform_data *pdata; |
86 | struct tps6586x_gpio *tps6586x_gpio; | 94 | struct tps6586x_gpio *tps6586x_gpio; |
@@ -106,6 +114,7 @@ static int __devinit tps6586x_gpio_probe(struct platform_device *pdev) | |||
106 | tps6586x_gpio->gpio_chip.direction_output = tps6586x_gpio_output; | 114 | tps6586x_gpio->gpio_chip.direction_output = tps6586x_gpio_output; |
107 | tps6586x_gpio->gpio_chip.set = tps6586x_gpio_set; | 115 | tps6586x_gpio->gpio_chip.set = tps6586x_gpio_set; |
108 | tps6586x_gpio->gpio_chip.get = tps6586x_gpio_get; | 116 | tps6586x_gpio->gpio_chip.get = tps6586x_gpio_get; |
117 | tps6586x_gpio->gpio_chip.to_irq = tps6586x_gpio_to_irq; | ||
109 | 118 | ||
110 | #ifdef CONFIG_OF_GPIO | 119 | #ifdef CONFIG_OF_GPIO |
111 | tps6586x_gpio->gpio_chip.of_node = pdev->dev.parent->of_node; | 120 | tps6586x_gpio->gpio_chip.of_node = pdev->dev.parent->of_node; |
@@ -126,7 +135,7 @@ static int __devinit tps6586x_gpio_probe(struct platform_device *pdev) | |||
126 | return ret; | 135 | return ret; |
127 | } | 136 | } |
128 | 137 | ||
129 | static int __devexit tps6586x_gpio_remove(struct platform_device *pdev) | 138 | static int tps6586x_gpio_remove(struct platform_device *pdev) |
130 | { | 139 | { |
131 | struct tps6586x_gpio *tps6586x_gpio = platform_get_drvdata(pdev); | 140 | struct tps6586x_gpio *tps6586x_gpio = platform_get_drvdata(pdev); |
132 | 141 | ||
@@ -137,7 +146,7 @@ static struct platform_driver tps6586x_gpio_driver = { | |||
137 | .driver.name = "tps6586x-gpio", | 146 | .driver.name = "tps6586x-gpio", |
138 | .driver.owner = THIS_MODULE, | 147 | .driver.owner = THIS_MODULE, |
139 | .probe = tps6586x_gpio_probe, | 148 | .probe = tps6586x_gpio_probe, |
140 | .remove = __devexit_p(tps6586x_gpio_remove), | 149 | .remove = tps6586x_gpio_remove, |
141 | }; | 150 | }; |
142 | 151 | ||
143 | static int __init tps6586x_gpio_init(void) | 152 | static int __init tps6586x_gpio_init(void) |
diff --git a/drivers/gpio/gpio-tps65910.c b/drivers/gpio/gpio-tps65910.c index 11f29c82253c..5083825a0348 100644 --- a/drivers/gpio/gpio-tps65910.c +++ b/drivers/gpio/gpio-tps65910.c | |||
@@ -113,7 +113,7 @@ static struct tps65910_board *tps65910_parse_dt_for_gpio(struct device *dev, | |||
113 | } | 113 | } |
114 | #endif | 114 | #endif |
115 | 115 | ||
116 | static int __devinit tps65910_gpio_probe(struct platform_device *pdev) | 116 | static int tps65910_gpio_probe(struct platform_device *pdev) |
117 | { | 117 | { |
118 | struct tps65910 *tps65910 = dev_get_drvdata(pdev->dev.parent); | 118 | struct tps65910 *tps65910 = dev_get_drvdata(pdev->dev.parent); |
119 | struct tps65910_board *pdata = dev_get_platdata(tps65910->dev); | 119 | struct tps65910_board *pdata = dev_get_platdata(tps65910->dev); |
@@ -188,7 +188,7 @@ skip_init: | |||
188 | return ret; | 188 | return ret; |
189 | } | 189 | } |
190 | 190 | ||
191 | static int __devexit tps65910_gpio_remove(struct platform_device *pdev) | 191 | static int tps65910_gpio_remove(struct platform_device *pdev) |
192 | { | 192 | { |
193 | struct tps65910_gpio *tps65910_gpio = platform_get_drvdata(pdev); | 193 | struct tps65910_gpio *tps65910_gpio = platform_get_drvdata(pdev); |
194 | 194 | ||
@@ -199,7 +199,7 @@ static struct platform_driver tps65910_gpio_driver = { | |||
199 | .driver.name = "tps65910-gpio", | 199 | .driver.name = "tps65910-gpio", |
200 | .driver.owner = THIS_MODULE, | 200 | .driver.owner = THIS_MODULE, |
201 | .probe = tps65910_gpio_probe, | 201 | .probe = tps65910_gpio_probe, |
202 | .remove = __devexit_p(tps65910_gpio_remove), | 202 | .remove = tps65910_gpio_remove, |
203 | }; | 203 | }; |
204 | 204 | ||
205 | static int __init tps65910_gpio_init(void) | 205 | static int __init tps65910_gpio_init(void) |
diff --git a/drivers/gpio/gpio-tps65912.c b/drivers/gpio/gpio-tps65912.c index 99106d1e2e55..30a5844a7dca 100644 --- a/drivers/gpio/gpio-tps65912.c +++ b/drivers/gpio/gpio-tps65912.c | |||
@@ -84,7 +84,7 @@ static struct gpio_chip template_chip = { | |||
84 | .base = -1, | 84 | .base = -1, |
85 | }; | 85 | }; |
86 | 86 | ||
87 | static int __devinit tps65912_gpio_probe(struct platform_device *pdev) | 87 | static int tps65912_gpio_probe(struct platform_device *pdev) |
88 | { | 88 | { |
89 | struct tps65912 *tps65912 = dev_get_drvdata(pdev->dev.parent); | 89 | struct tps65912 *tps65912 = dev_get_drvdata(pdev->dev.parent); |
90 | struct tps65912_board *pdata = tps65912->dev->platform_data; | 90 | struct tps65912_board *pdata = tps65912->dev->platform_data; |
@@ -113,7 +113,7 @@ static int __devinit tps65912_gpio_probe(struct platform_device *pdev) | |||
113 | return ret; | 113 | return ret; |
114 | } | 114 | } |
115 | 115 | ||
116 | static int __devexit tps65912_gpio_remove(struct platform_device *pdev) | 116 | static int tps65912_gpio_remove(struct platform_device *pdev) |
117 | { | 117 | { |
118 | struct tps65912_gpio_data *tps65912_gpio = platform_get_drvdata(pdev); | 118 | struct tps65912_gpio_data *tps65912_gpio = platform_get_drvdata(pdev); |
119 | 119 | ||
@@ -126,7 +126,7 @@ static struct platform_driver tps65912_gpio_driver = { | |||
126 | .owner = THIS_MODULE, | 126 | .owner = THIS_MODULE, |
127 | }, | 127 | }, |
128 | .probe = tps65912_gpio_probe, | 128 | .probe = tps65912_gpio_probe, |
129 | .remove = __devexit_p(tps65912_gpio_remove), | 129 | .remove = tps65912_gpio_remove, |
130 | }; | 130 | }; |
131 | 131 | ||
132 | static int __init tps65912_gpio_init(void) | 132 | static int __init tps65912_gpio_init(void) |
diff --git a/drivers/gpio/gpio-ts5500.c b/drivers/gpio/gpio-ts5500.c new file mode 100644 index 000000000000..0634ceea3c24 --- /dev/null +++ b/drivers/gpio/gpio-ts5500.c | |||
@@ -0,0 +1,466 @@ | |||
1 | /* | ||
2 | * Digital I/O driver for Technologic Systems TS-5500 | ||
3 | * | ||
4 | * Copyright (c) 2012 Savoir-faire Linux Inc. | ||
5 | * Vivien Didelot <vivien.didelot@savoirfairelinux.com> | ||
6 | * | ||
7 | * Technologic Systems platforms have pin blocks, exposing several Digital | ||
8 | * Input/Output lines (DIO). This driver aims to support single pin blocks. | ||
9 | * In that sense, the support is not limited to the TS-5500 blocks. | ||
10 | * Actually, the following platforms have DIO support: | ||
11 | * | ||
12 | * TS-5500: | ||
13 | * Documentation: http://wiki.embeddedarm.com/wiki/TS-5500 | ||
14 | * Blocks: DIO1, DIO2 and LCD port. | ||
15 | * | ||
16 | * TS-5600: | ||
17 | * Documentation: http://wiki.embeddedarm.com/wiki/TS-5600 | ||
18 | * Blocks: LCD port (identical to TS-5500 LCD). | ||
19 | * | ||
20 | * This program is free software; you can redistribute it and/or modify | ||
21 | * it under the terms of the GNU General Public License version 2 as | ||
22 | * published by the Free Software Foundation. | ||
23 | */ | ||
24 | |||
25 | #include <linux/bitops.h> | ||
26 | #include <linux/gpio.h> | ||
27 | #include <linux/io.h> | ||
28 | #include <linux/module.h> | ||
29 | #include <linux/platform_data/gpio-ts5500.h> | ||
30 | #include <linux/platform_device.h> | ||
31 | #include <linux/slab.h> | ||
32 | |||
33 | /* List of supported Technologic Systems platforms DIO blocks */ | ||
34 | enum ts5500_blocks { TS5500_DIO1, TS5500_DIO2, TS5500_LCD, TS5600_LCD }; | ||
35 | |||
36 | struct ts5500_priv { | ||
37 | const struct ts5500_dio *pinout; | ||
38 | struct gpio_chip gpio_chip; | ||
39 | spinlock_t lock; | ||
40 | bool strap; | ||
41 | u8 hwirq; | ||
42 | }; | ||
43 | |||
44 | /* | ||
45 | * Hex 7D is used to control several blocks (e.g. DIO2 and LCD port). | ||
46 | * This flag ensures that the region has been requested by this driver. | ||
47 | */ | ||
48 | static bool hex7d_reserved; | ||
49 | |||
50 | /* | ||
51 | * This structure is used to describe capabilities of DIO lines, | ||
52 | * such as available directions and connected interrupt (if any). | ||
53 | */ | ||
54 | struct ts5500_dio { | ||
55 | const u8 value_addr; | ||
56 | const u8 value_mask; | ||
57 | const u8 control_addr; | ||
58 | const u8 control_mask; | ||
59 | const bool no_input; | ||
60 | const bool no_output; | ||
61 | const u8 irq; | ||
62 | }; | ||
63 | |||
64 | #define TS5500_DIO_IN_OUT(vaddr, vbit, caddr, cbit) \ | ||
65 | { \ | ||
66 | .value_addr = vaddr, \ | ||
67 | .value_mask = BIT(vbit), \ | ||
68 | .control_addr = caddr, \ | ||
69 | .control_mask = BIT(cbit), \ | ||
70 | } | ||
71 | |||
72 | #define TS5500_DIO_IN(addr, bit) \ | ||
73 | { \ | ||
74 | .value_addr = addr, \ | ||
75 | .value_mask = BIT(bit), \ | ||
76 | .no_output = true, \ | ||
77 | } | ||
78 | |||
79 | #define TS5500_DIO_IN_IRQ(addr, bit, _irq) \ | ||
80 | { \ | ||
81 | .value_addr = addr, \ | ||
82 | .value_mask = BIT(bit), \ | ||
83 | .no_output = true, \ | ||
84 | .irq = _irq, \ | ||
85 | } | ||
86 | |||
87 | #define TS5500_DIO_OUT(addr, bit) \ | ||
88 | { \ | ||
89 | .value_addr = addr, \ | ||
90 | .value_mask = BIT(bit), \ | ||
91 | .no_input = true, \ | ||
92 | } | ||
93 | |||
94 | /* | ||
95 | * Input/Output DIO lines are programmed in groups of 4. Their values are | ||
96 | * available through 4 consecutive bits in a value port, whereas the direction | ||
97 | * of these 4 lines is driven by only 1 bit in a control port. | ||
98 | */ | ||
99 | #define TS5500_DIO_GROUP(vaddr, vbitfrom, caddr, cbit) \ | ||
100 | TS5500_DIO_IN_OUT(vaddr, vbitfrom + 0, caddr, cbit), \ | ||
101 | TS5500_DIO_IN_OUT(vaddr, vbitfrom + 1, caddr, cbit), \ | ||
102 | TS5500_DIO_IN_OUT(vaddr, vbitfrom + 2, caddr, cbit), \ | ||
103 | TS5500_DIO_IN_OUT(vaddr, vbitfrom + 3, caddr, cbit) | ||
104 | |||
105 | /* | ||
106 | * TS-5500 DIO1 block | ||
107 | * | ||
108 | * value control dir hw | ||
109 | * addr bit addr bit in out irq name pin offset | ||
110 | * | ||
111 | * 0x7b 0 0x7a 0 x x DIO1_0 1 0 | ||
112 | * 0x7b 1 0x7a 0 x x DIO1_1 3 1 | ||
113 | * 0x7b 2 0x7a 0 x x DIO1_2 5 2 | ||
114 | * 0x7b 3 0x7a 0 x x DIO1_3 7 3 | ||
115 | * 0x7b 4 0x7a 1 x x DIO1_4 9 4 | ||
116 | * 0x7b 5 0x7a 1 x x DIO1_5 11 5 | ||
117 | * 0x7b 6 0x7a 1 x x DIO1_6 13 6 | ||
118 | * 0x7b 7 0x7a 1 x x DIO1_7 15 7 | ||
119 | * 0x7c 0 0x7a 5 x x DIO1_8 4 8 | ||
120 | * 0x7c 1 0x7a 5 x x DIO1_9 6 9 | ||
121 | * 0x7c 2 0x7a 5 x x DIO1_10 8 10 | ||
122 | * 0x7c 3 0x7a 5 x x DIO1_11 10 11 | ||
123 | * 0x7c 4 x DIO1_12 12 12 | ||
124 | * 0x7c 5 x 7 DIO1_13 14 13 | ||
125 | */ | ||
126 | static const struct ts5500_dio ts5500_dio1[] = { | ||
127 | TS5500_DIO_GROUP(0x7b, 0, 0x7a, 0), | ||
128 | TS5500_DIO_GROUP(0x7b, 4, 0x7a, 1), | ||
129 | TS5500_DIO_GROUP(0x7c, 0, 0x7a, 5), | ||
130 | TS5500_DIO_IN(0x7c, 4), | ||
131 | TS5500_DIO_IN_IRQ(0x7c, 5, 7), | ||
132 | }; | ||
133 | |||
134 | /* | ||
135 | * TS-5500 DIO2 block | ||
136 | * | ||
137 | * value control dir hw | ||
138 | * addr bit addr bit in out irq name pin offset | ||
139 | * | ||
140 | * 0x7e 0 0x7d 0 x x DIO2_0 1 0 | ||
141 | * 0x7e 1 0x7d 0 x x DIO2_1 3 1 | ||
142 | * 0x7e 2 0x7d 0 x x DIO2_2 5 2 | ||
143 | * 0x7e 3 0x7d 0 x x DIO2_3 7 3 | ||
144 | * 0x7e 4 0x7d 1 x x DIO2_4 9 4 | ||
145 | * 0x7e 5 0x7d 1 x x DIO2_5 11 5 | ||
146 | * 0x7e 6 0x7d 1 x x DIO2_6 13 6 | ||
147 | * 0x7e 7 0x7d 1 x x DIO2_7 15 7 | ||
148 | * 0x7f 0 0x7d 5 x x DIO2_8 4 8 | ||
149 | * 0x7f 1 0x7d 5 x x DIO2_9 6 9 | ||
150 | * 0x7f 2 0x7d 5 x x DIO2_10 8 10 | ||
151 | * 0x7f 3 0x7d 5 x x DIO2_11 10 11 | ||
152 | * 0x7f 4 x 6 DIO2_13 14 12 | ||
153 | */ | ||
154 | static const struct ts5500_dio ts5500_dio2[] = { | ||
155 | TS5500_DIO_GROUP(0x7e, 0, 0x7d, 0), | ||
156 | TS5500_DIO_GROUP(0x7e, 4, 0x7d, 1), | ||
157 | TS5500_DIO_GROUP(0x7f, 0, 0x7d, 5), | ||
158 | TS5500_DIO_IN_IRQ(0x7f, 4, 6), | ||
159 | }; | ||
160 | |||
161 | /* | ||
162 | * TS-5500 LCD port used as DIO block | ||
163 | * TS-5600 LCD port is identical | ||
164 | * | ||
165 | * value control dir hw | ||
166 | * addr bit addr bit in out irq name pin offset | ||
167 | * | ||
168 | * 0x72 0 0x7d 2 x x LCD_0 8 0 | ||
169 | * 0x72 1 0x7d 2 x x LCD_1 7 1 | ||
170 | * 0x72 2 0x7d 2 x x LCD_2 10 2 | ||
171 | * 0x72 3 0x7d 2 x x LCD_3 9 3 | ||
172 | * 0x72 4 0x7d 3 x x LCD_4 12 4 | ||
173 | * 0x72 5 0x7d 3 x x LCD_5 11 5 | ||
174 | * 0x72 6 0x7d 3 x x LCD_6 14 6 | ||
175 | * 0x72 7 0x7d 3 x x LCD_7 13 7 | ||
176 | * 0x73 0 x LCD_EN 5 8 | ||
177 | * 0x73 6 x LCD_WR 6 9 | ||
178 | * 0x73 7 x 1 LCD_RS 3 10 | ||
179 | */ | ||
180 | static const struct ts5500_dio ts5500_lcd[] = { | ||
181 | TS5500_DIO_GROUP(0x72, 0, 0x7d, 2), | ||
182 | TS5500_DIO_GROUP(0x72, 4, 0x7d, 3), | ||
183 | TS5500_DIO_OUT(0x73, 0), | ||
184 | TS5500_DIO_IN(0x73, 6), | ||
185 | TS5500_DIO_IN_IRQ(0x73, 7, 1), | ||
186 | }; | ||
187 | |||
188 | static inline struct ts5500_priv *ts5500_gc_to_priv(struct gpio_chip *chip) | ||
189 | { | ||
190 | return container_of(chip, struct ts5500_priv, gpio_chip); | ||
191 | } | ||
192 | |||
193 | static inline void ts5500_set_mask(u8 mask, u8 addr) | ||
194 | { | ||
195 | u8 val = inb(addr); | ||
196 | val |= mask; | ||
197 | outb(val, addr); | ||
198 | } | ||
199 | |||
200 | static inline void ts5500_clear_mask(u8 mask, u8 addr) | ||
201 | { | ||
202 | u8 val = inb(addr); | ||
203 | val &= ~mask; | ||
204 | outb(val, addr); | ||
205 | } | ||
206 | |||
207 | static int ts5500_gpio_input(struct gpio_chip *chip, unsigned offset) | ||
208 | { | ||
209 | struct ts5500_priv *priv = ts5500_gc_to_priv(chip); | ||
210 | const struct ts5500_dio line = priv->pinout[offset]; | ||
211 | unsigned long flags; | ||
212 | |||
213 | if (line.no_input) | ||
214 | return -ENXIO; | ||
215 | |||
216 | if (line.no_output) | ||
217 | return 0; | ||
218 | |||
219 | spin_lock_irqsave(&priv->lock, flags); | ||
220 | ts5500_clear_mask(line.control_mask, line.control_addr); | ||
221 | spin_unlock_irqrestore(&priv->lock, flags); | ||
222 | |||
223 | return 0; | ||
224 | } | ||
225 | |||
226 | static int ts5500_gpio_get(struct gpio_chip *chip, unsigned offset) | ||
227 | { | ||
228 | struct ts5500_priv *priv = ts5500_gc_to_priv(chip); | ||
229 | const struct ts5500_dio line = priv->pinout[offset]; | ||
230 | |||
231 | return !!(inb(line.value_addr) & line.value_mask); | ||
232 | } | ||
233 | |||
234 | static int ts5500_gpio_output(struct gpio_chip *chip, unsigned offset, int val) | ||
235 | { | ||
236 | struct ts5500_priv *priv = ts5500_gc_to_priv(chip); | ||
237 | const struct ts5500_dio line = priv->pinout[offset]; | ||
238 | unsigned long flags; | ||
239 | |||
240 | if (line.no_output) | ||
241 | return -ENXIO; | ||
242 | |||
243 | spin_lock_irqsave(&priv->lock, flags); | ||
244 | if (!line.no_input) | ||
245 | ts5500_set_mask(line.control_mask, line.control_addr); | ||
246 | |||
247 | if (val) | ||
248 | ts5500_set_mask(line.value_mask, line.value_addr); | ||
249 | else | ||
250 | ts5500_clear_mask(line.value_mask, line.value_addr); | ||
251 | spin_unlock_irqrestore(&priv->lock, flags); | ||
252 | |||
253 | return 0; | ||
254 | } | ||
255 | |||
256 | static void ts5500_gpio_set(struct gpio_chip *chip, unsigned offset, int val) | ||
257 | { | ||
258 | struct ts5500_priv *priv = ts5500_gc_to_priv(chip); | ||
259 | const struct ts5500_dio line = priv->pinout[offset]; | ||
260 | unsigned long flags; | ||
261 | |||
262 | spin_lock_irqsave(&priv->lock, flags); | ||
263 | if (val) | ||
264 | ts5500_set_mask(line.value_mask, line.value_addr); | ||
265 | else | ||
266 | ts5500_clear_mask(line.value_mask, line.value_addr); | ||
267 | spin_unlock_irqrestore(&priv->lock, flags); | ||
268 | } | ||
269 | |||
270 | static int ts5500_gpio_to_irq(struct gpio_chip *chip, unsigned offset) | ||
271 | { | ||
272 | struct ts5500_priv *priv = ts5500_gc_to_priv(chip); | ||
273 | const struct ts5500_dio *block = priv->pinout; | ||
274 | const struct ts5500_dio line = block[offset]; | ||
275 | |||
276 | /* Only one pin is connected to an interrupt */ | ||
277 | if (line.irq) | ||
278 | return line.irq; | ||
279 | |||
280 | /* As this pin is input-only, we may strap it to another in/out pin */ | ||
281 | if (priv->strap) | ||
282 | return priv->hwirq; | ||
283 | |||
284 | return -ENXIO; | ||
285 | } | ||
286 | |||
287 | static int ts5500_enable_irq(struct ts5500_priv *priv) | ||
288 | { | ||
289 | int ret = 0; | ||
290 | unsigned long flags; | ||
291 | |||
292 | spin_lock_irqsave(&priv->lock, flags); | ||
293 | if (priv->hwirq == 7) | ||
294 | ts5500_set_mask(BIT(7), 0x7a); /* DIO1_13 on IRQ7 */ | ||
295 | else if (priv->hwirq == 6) | ||
296 | ts5500_set_mask(BIT(7), 0x7d); /* DIO2_13 on IRQ6 */ | ||
297 | else if (priv->hwirq == 1) | ||
298 | ts5500_set_mask(BIT(6), 0x7d); /* LCD_RS on IRQ1 */ | ||
299 | else | ||
300 | ret = -EINVAL; | ||
301 | spin_unlock_irqrestore(&priv->lock, flags); | ||
302 | |||
303 | return ret; | ||
304 | } | ||
305 | |||
306 | static void ts5500_disable_irq(struct ts5500_priv *priv) | ||
307 | { | ||
308 | unsigned long flags; | ||
309 | |||
310 | spin_lock_irqsave(&priv->lock, flags); | ||
311 | if (priv->hwirq == 7) | ||
312 | ts5500_clear_mask(BIT(7), 0x7a); /* DIO1_13 on IRQ7 */ | ||
313 | else if (priv->hwirq == 6) | ||
314 | ts5500_clear_mask(BIT(7), 0x7d); /* DIO2_13 on IRQ6 */ | ||
315 | else if (priv->hwirq == 1) | ||
316 | ts5500_clear_mask(BIT(6), 0x7d); /* LCD_RS on IRQ1 */ | ||
317 | else | ||
318 | dev_err(priv->gpio_chip.dev, "invalid hwirq %d\n", priv->hwirq); | ||
319 | spin_unlock_irqrestore(&priv->lock, flags); | ||
320 | } | ||
321 | |||
322 | static int __devinit ts5500_dio_probe(struct platform_device *pdev) | ||
323 | { | ||
324 | enum ts5500_blocks block = platform_get_device_id(pdev)->driver_data; | ||
325 | struct ts5500_dio_platform_data *pdata = pdev->dev.platform_data; | ||
326 | struct device *dev = &pdev->dev; | ||
327 | const char *name = dev_name(dev); | ||
328 | struct ts5500_priv *priv; | ||
329 | struct resource *res; | ||
330 | unsigned long flags; | ||
331 | int ret; | ||
332 | |||
333 | res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); | ||
334 | if (!res) { | ||
335 | dev_err(dev, "missing IRQ resource\n"); | ||
336 | return -EINVAL; | ||
337 | } | ||
338 | |||
339 | priv = devm_kzalloc(dev, sizeof(struct ts5500_priv), GFP_KERNEL); | ||
340 | if (!priv) | ||
341 | return -ENOMEM; | ||
342 | |||
343 | platform_set_drvdata(pdev, priv); | ||
344 | priv->hwirq = res->start; | ||
345 | spin_lock_init(&priv->lock); | ||
346 | |||
347 | priv->gpio_chip.owner = THIS_MODULE; | ||
348 | priv->gpio_chip.label = name; | ||
349 | priv->gpio_chip.dev = dev; | ||
350 | priv->gpio_chip.direction_input = ts5500_gpio_input; | ||
351 | priv->gpio_chip.direction_output = ts5500_gpio_output; | ||
352 | priv->gpio_chip.get = ts5500_gpio_get; | ||
353 | priv->gpio_chip.set = ts5500_gpio_set; | ||
354 | priv->gpio_chip.to_irq = ts5500_gpio_to_irq; | ||
355 | priv->gpio_chip.base = -1; | ||
356 | if (pdata) { | ||
357 | priv->gpio_chip.base = pdata->base; | ||
358 | priv->strap = pdata->strap; | ||
359 | } | ||
360 | |||
361 | switch (block) { | ||
362 | case TS5500_DIO1: | ||
363 | priv->pinout = ts5500_dio1; | ||
364 | priv->gpio_chip.ngpio = ARRAY_SIZE(ts5500_dio1); | ||
365 | |||
366 | if (!devm_request_region(dev, 0x7a, 3, name)) { | ||
367 | dev_err(dev, "failed to request %s ports\n", name); | ||
368 | return -EBUSY; | ||
369 | } | ||
370 | break; | ||
371 | case TS5500_DIO2: | ||
372 | priv->pinout = ts5500_dio2; | ||
373 | priv->gpio_chip.ngpio = ARRAY_SIZE(ts5500_dio2); | ||
374 | |||
375 | if (!devm_request_region(dev, 0x7e, 2, name)) { | ||
376 | dev_err(dev, "failed to request %s ports\n", name); | ||
377 | return -EBUSY; | ||
378 | } | ||
379 | |||
380 | if (hex7d_reserved) | ||
381 | break; | ||
382 | |||
383 | if (!devm_request_region(dev, 0x7d, 1, name)) { | ||
384 | dev_err(dev, "failed to request %s 7D\n", name); | ||
385 | return -EBUSY; | ||
386 | } | ||
387 | |||
388 | hex7d_reserved = true; | ||
389 | break; | ||
390 | case TS5500_LCD: | ||
391 | case TS5600_LCD: | ||
392 | priv->pinout = ts5500_lcd; | ||
393 | priv->gpio_chip.ngpio = ARRAY_SIZE(ts5500_lcd); | ||
394 | |||
395 | if (!devm_request_region(dev, 0x72, 2, name)) { | ||
396 | dev_err(dev, "failed to request %s ports\n", name); | ||
397 | return -EBUSY; | ||
398 | } | ||
399 | |||
400 | if (!hex7d_reserved) { | ||
401 | if (!devm_request_region(dev, 0x7d, 1, name)) { | ||
402 | dev_err(dev, "failed to request %s 7D\n", name); | ||
403 | return -EBUSY; | ||
404 | } | ||
405 | |||
406 | hex7d_reserved = true; | ||
407 | } | ||
408 | |||
409 | /* Ensure usage of LCD port as DIO */ | ||
410 | spin_lock_irqsave(&priv->lock, flags); | ||
411 | ts5500_clear_mask(BIT(4), 0x7d); | ||
412 | spin_unlock_irqrestore(&priv->lock, flags); | ||
413 | break; | ||
414 | } | ||
415 | |||
416 | ret = gpiochip_add(&priv->gpio_chip); | ||
417 | if (ret) { | ||
418 | dev_err(dev, "failed to register the gpio chip\n"); | ||
419 | return ret; | ||
420 | } | ||
421 | |||
422 | ret = ts5500_enable_irq(priv); | ||
423 | if (ret) { | ||
424 | dev_err(dev, "invalid interrupt %d\n", priv->hwirq); | ||
425 | goto cleanup; | ||
426 | } | ||
427 | |||
428 | return 0; | ||
429 | cleanup: | ||
430 | if (gpiochip_remove(&priv->gpio_chip)) | ||
431 | dev_err(dev, "failed to remove gpio chip\n"); | ||
432 | return ret; | ||
433 | } | ||
434 | |||
435 | static int __devexit ts5500_dio_remove(struct platform_device *pdev) | ||
436 | { | ||
437 | struct ts5500_priv *priv = platform_get_drvdata(pdev); | ||
438 | |||
439 | ts5500_disable_irq(priv); | ||
440 | return gpiochip_remove(&priv->gpio_chip); | ||
441 | } | ||
442 | |||
443 | static struct platform_device_id ts5500_dio_ids[] = { | ||
444 | { "ts5500-dio1", TS5500_DIO1 }, | ||
445 | { "ts5500-dio2", TS5500_DIO2 }, | ||
446 | { "ts5500-dio-lcd", TS5500_LCD }, | ||
447 | { "ts5600-dio-lcd", TS5600_LCD }, | ||
448 | { } | ||
449 | }; | ||
450 | MODULE_DEVICE_TABLE(platform, ts5500_dio_ids); | ||
451 | |||
452 | static struct platform_driver ts5500_dio_driver = { | ||
453 | .driver = { | ||
454 | .name = "ts5500-dio", | ||
455 | .owner = THIS_MODULE, | ||
456 | }, | ||
457 | .probe = ts5500_dio_probe, | ||
458 | .remove = __devexit_p(ts5500_dio_remove), | ||
459 | .id_table = ts5500_dio_ids, | ||
460 | }; | ||
461 | |||
462 | module_platform_driver(ts5500_dio_driver); | ||
463 | |||
464 | MODULE_LICENSE("GPL"); | ||
465 | MODULE_AUTHOR("Savoir-faire Linux Inc. <kernel@savoirfairelinux.com>"); | ||
466 | MODULE_DESCRIPTION("Technologic Systems TS-5500 Digital I/O driver"); | ||
diff --git a/drivers/gpio/gpio-twl4030.c b/drivers/gpio/gpio-twl4030.c index c5f8ca233e1f..9572aa137e6f 100644 --- a/drivers/gpio/gpio-twl4030.c +++ b/drivers/gpio/gpio-twl4030.c | |||
@@ -88,11 +88,15 @@ static inline int gpio_twl4030_write(u8 address, u8 data) | |||
88 | /*----------------------------------------------------------------------*/ | 88 | /*----------------------------------------------------------------------*/ |
89 | 89 | ||
90 | /* | 90 | /* |
91 | * LED register offsets (use TWL4030_MODULE_{LED,PWMA,PWMB})) | 91 | * LED register offsets from TWL_MODULE_LED base |
92 | * PWMs A and B are dedicated to LEDs A and B, respectively. | 92 | * PWMs A and B are dedicated to LEDs A and B, respectively. |
93 | */ | 93 | */ |
94 | 94 | ||
95 | #define TWL4030_LED_LEDEN 0x0 | 95 | #define TWL4030_LED_LEDEN_REG 0x00 |
96 | #define TWL4030_PWMAON_REG 0x01 | ||
97 | #define TWL4030_PWMAOFF_REG 0x02 | ||
98 | #define TWL4030_PWMBON_REG 0x03 | ||
99 | #define TWL4030_PWMBOFF_REG 0x04 | ||
96 | 100 | ||
97 | /* LEDEN bits */ | 101 | /* LEDEN bits */ |
98 | #define LEDEN_LEDAON BIT(0) | 102 | #define LEDEN_LEDAON BIT(0) |
@@ -104,9 +108,6 @@ static inline int gpio_twl4030_write(u8 address, u8 data) | |||
104 | #define LEDEN_PWM_LENGTHA BIT(6) | 108 | #define LEDEN_PWM_LENGTHA BIT(6) |
105 | #define LEDEN_PWM_LENGTHB BIT(7) | 109 | #define LEDEN_PWM_LENGTHB BIT(7) |
106 | 110 | ||
107 | #define TWL4030_PWMx_PWMxON 0x0 | ||
108 | #define TWL4030_PWMx_PWMxOFF 0x1 | ||
109 | |||
110 | #define PWMxON_LENGTH BIT(7) | 111 | #define PWMxON_LENGTH BIT(7) |
111 | 112 | ||
112 | /*----------------------------------------------------------------------*/ | 113 | /*----------------------------------------------------------------------*/ |
@@ -145,7 +146,7 @@ static void twl4030_led_set_value(int led, int value) | |||
145 | else | 146 | else |
146 | cached_leden |= mask; | 147 | cached_leden |= mask; |
147 | status = twl_i2c_write_u8(TWL4030_MODULE_LED, cached_leden, | 148 | status = twl_i2c_write_u8(TWL4030_MODULE_LED, cached_leden, |
148 | TWL4030_LED_LEDEN); | 149 | TWL4030_LED_LEDEN_REG); |
149 | mutex_unlock(&gpio_lock); | 150 | mutex_unlock(&gpio_lock); |
150 | } | 151 | } |
151 | 152 | ||
@@ -216,33 +217,33 @@ static int twl_request(struct gpio_chip *chip, unsigned offset) | |||
216 | if (offset >= TWL4030_GPIO_MAX) { | 217 | if (offset >= TWL4030_GPIO_MAX) { |
217 | u8 ledclr_mask = LEDEN_LEDAON | LEDEN_LEDAEXT | 218 | u8 ledclr_mask = LEDEN_LEDAON | LEDEN_LEDAEXT |
218 | | LEDEN_LEDAPWM | LEDEN_PWM_LENGTHA; | 219 | | LEDEN_LEDAPWM | LEDEN_PWM_LENGTHA; |
219 | u8 module = TWL4030_MODULE_PWMA; | 220 | u8 reg = TWL4030_PWMAON_REG; |
220 | 221 | ||
221 | offset -= TWL4030_GPIO_MAX; | 222 | offset -= TWL4030_GPIO_MAX; |
222 | if (offset) { | 223 | if (offset) { |
223 | ledclr_mask <<= 1; | 224 | ledclr_mask <<= 1; |
224 | module = TWL4030_MODULE_PWMB; | 225 | reg = TWL4030_PWMBON_REG; |
225 | } | 226 | } |
226 | 227 | ||
227 | /* initialize PWM to always-drive */ | 228 | /* initialize PWM to always-drive */ |
228 | status = twl_i2c_write_u8(module, 0x7f, | 229 | /* Configure PWM OFF register first */ |
229 | TWL4030_PWMx_PWMxOFF); | 230 | status = twl_i2c_write_u8(TWL4030_MODULE_LED, 0x7f, reg + 1); |
230 | if (status < 0) | 231 | if (status < 0) |
231 | goto done; | 232 | goto done; |
232 | status = twl_i2c_write_u8(module, 0x7f, | 233 | |
233 | TWL4030_PWMx_PWMxON); | 234 | /* Followed by PWM ON register */ |
235 | status = twl_i2c_write_u8(TWL4030_MODULE_LED, 0x7f, reg); | ||
234 | if (status < 0) | 236 | if (status < 0) |
235 | goto done; | 237 | goto done; |
236 | 238 | ||
237 | /* init LED to not-driven (high) */ | 239 | /* init LED to not-driven (high) */ |
238 | module = TWL4030_MODULE_LED; | 240 | status = twl_i2c_read_u8(TWL4030_MODULE_LED, &cached_leden, |
239 | status = twl_i2c_read_u8(module, &cached_leden, | 241 | TWL4030_LED_LEDEN_REG); |
240 | TWL4030_LED_LEDEN); | ||
241 | if (status < 0) | 242 | if (status < 0) |
242 | goto done; | 243 | goto done; |
243 | cached_leden &= ~ledclr_mask; | 244 | cached_leden &= ~ledclr_mask; |
244 | status = twl_i2c_write_u8(module, cached_leden, | 245 | status = twl_i2c_write_u8(TWL4030_MODULE_LED, cached_leden, |
245 | TWL4030_LED_LEDEN); | 246 | TWL4030_LED_LEDEN_REG); |
246 | if (status < 0) | 247 | if (status < 0) |
247 | goto done; | 248 | goto done; |
248 | 249 | ||
@@ -352,15 +353,15 @@ static struct gpio_chip twl_gpiochip = { | |||
352 | 353 | ||
353 | /*----------------------------------------------------------------------*/ | 354 | /*----------------------------------------------------------------------*/ |
354 | 355 | ||
355 | static int __devinit gpio_twl4030_pulls(u32 ups, u32 downs) | 356 | static int gpio_twl4030_pulls(u32 ups, u32 downs) |
356 | { | 357 | { |
357 | u8 message[6]; | 358 | u8 message[5]; |
358 | unsigned i, gpio_bit; | 359 | unsigned i, gpio_bit; |
359 | 360 | ||
360 | /* For most pins, a pulldown was enabled by default. | 361 | /* For most pins, a pulldown was enabled by default. |
361 | * We should have data that's specific to this board. | 362 | * We should have data that's specific to this board. |
362 | */ | 363 | */ |
363 | for (gpio_bit = 1, i = 1; i < 6; i++) { | 364 | for (gpio_bit = 1, i = 0; i < 5; i++) { |
364 | u8 bit_mask; | 365 | u8 bit_mask; |
365 | unsigned j; | 366 | unsigned j; |
366 | 367 | ||
@@ -377,18 +378,18 @@ static int __devinit gpio_twl4030_pulls(u32 ups, u32 downs) | |||
377 | REG_GPIOPUPDCTR1, 5); | 378 | REG_GPIOPUPDCTR1, 5); |
378 | } | 379 | } |
379 | 380 | ||
380 | static int __devinit gpio_twl4030_debounce(u32 debounce, u8 mmc_cd) | 381 | static int gpio_twl4030_debounce(u32 debounce, u8 mmc_cd) |
381 | { | 382 | { |
382 | u8 message[4]; | 383 | u8 message[3]; |
383 | 384 | ||
384 | /* 30 msec of debouncing is always used for MMC card detect, | 385 | /* 30 msec of debouncing is always used for MMC card detect, |
385 | * and is optional for everything else. | 386 | * and is optional for everything else. |
386 | */ | 387 | */ |
387 | message[1] = (debounce & 0xff) | (mmc_cd & 0x03); | 388 | message[0] = (debounce & 0xff) | (mmc_cd & 0x03); |
388 | debounce >>= 8; | 389 | debounce >>= 8; |
389 | message[2] = (debounce & 0xff); | 390 | message[1] = (debounce & 0xff); |
390 | debounce >>= 8; | 391 | debounce >>= 8; |
391 | message[3] = (debounce & 0x03); | 392 | message[2] = (debounce & 0x03); |
392 | 393 | ||
393 | return twl_i2c_write(TWL4030_MODULE_GPIO, message, | 394 | return twl_i2c_write(TWL4030_MODULE_GPIO, message, |
394 | REG_GPIO_DEBEN1, 3); | 395 | REG_GPIO_DEBEN1, 3); |
@@ -419,7 +420,7 @@ static struct twl4030_gpio_platform_data *of_gpio_twl4030(struct device *dev) | |||
419 | return omap_twl_info; | 420 | return omap_twl_info; |
420 | } | 421 | } |
421 | 422 | ||
422 | static int __devinit gpio_twl4030_probe(struct platform_device *pdev) | 423 | static int gpio_twl4030_probe(struct platform_device *pdev) |
423 | { | 424 | { |
424 | struct twl4030_gpio_platform_data *pdata = pdev->dev.platform_data; | 425 | struct twl4030_gpio_platform_data *pdata = pdev->dev.platform_data; |
425 | struct device_node *node = pdev->dev.of_node; | 426 | struct device_node *node = pdev->dev.of_node; |
@@ -505,7 +506,7 @@ out: | |||
505 | return ret; | 506 | return ret; |
506 | } | 507 | } |
507 | 508 | ||
508 | /* Cannot use __devexit as gpio_twl4030_probe() calls us */ | 509 | /* Cannot use as gpio_twl4030_probe() calls us */ |
509 | static int gpio_twl4030_remove(struct platform_device *pdev) | 510 | static int gpio_twl4030_remove(struct platform_device *pdev) |
510 | { | 511 | { |
511 | struct twl4030_gpio_platform_data *pdata = pdev->dev.platform_data; | 512 | struct twl4030_gpio_platform_data *pdata = pdev->dev.platform_data; |
diff --git a/drivers/gpio/gpio-twl6040.c b/drivers/gpio/gpio-twl6040.c index dd58e8b25043..0be82c6dd796 100644 --- a/drivers/gpio/gpio-twl6040.c +++ b/drivers/gpio/gpio-twl6040.c | |||
@@ -82,7 +82,7 @@ static struct gpio_chip twl6040gpo_chip = { | |||
82 | 82 | ||
83 | /*----------------------------------------------------------------------*/ | 83 | /*----------------------------------------------------------------------*/ |
84 | 84 | ||
85 | static int __devinit gpo_twl6040_probe(struct platform_device *pdev) | 85 | static int gpo_twl6040_probe(struct platform_device *pdev) |
86 | { | 86 | { |
87 | struct twl6040_gpo_data *pdata = pdev->dev.platform_data; | 87 | struct twl6040_gpo_data *pdata = pdev->dev.platform_data; |
88 | struct device *twl6040_core_dev = pdev->dev.parent; | 88 | struct device *twl6040_core_dev = pdev->dev.parent; |
@@ -113,7 +113,7 @@ static int __devinit gpo_twl6040_probe(struct platform_device *pdev) | |||
113 | return ret; | 113 | return ret; |
114 | } | 114 | } |
115 | 115 | ||
116 | static int __devexit gpo_twl6040_remove(struct platform_device *pdev) | 116 | static int gpo_twl6040_remove(struct platform_device *pdev) |
117 | { | 117 | { |
118 | return gpiochip_remove(&twl6040gpo_chip); | 118 | return gpiochip_remove(&twl6040gpo_chip); |
119 | } | 119 | } |
diff --git a/drivers/gpio/gpio-viperboard.c b/drivers/gpio/gpio-viperboard.c new file mode 100644 index 000000000000..13772996cf24 --- /dev/null +++ b/drivers/gpio/gpio-viperboard.c | |||
@@ -0,0 +1,517 @@ | |||
1 | /* | ||
2 | * Nano River Technologies viperboard GPIO lib driver | ||
3 | * | ||
4 | * (C) 2012 by Lemonage GmbH | ||
5 | * Author: Lars Poeschel <poeschel@lemonage.de> | ||
6 | * All rights reserved. | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify it | ||
9 | * under the terms of the GNU General Public License as published by the | ||
10 | * Free Software Foundation; either version 2 of the License, or (at your | ||
11 | * option) any later version. | ||
12 | * | ||
13 | */ | ||
14 | |||
15 | #include <linux/kernel.h> | ||
16 | #include <linux/errno.h> | ||
17 | #include <linux/module.h> | ||
18 | #include <linux/slab.h> | ||
19 | #include <linux/types.h> | ||
20 | #include <linux/mutex.h> | ||
21 | #include <linux/platform_device.h> | ||
22 | |||
23 | #include <linux/usb.h> | ||
24 | #include <linux/gpio.h> | ||
25 | |||
26 | #include <linux/mfd/viperboard.h> | ||
27 | |||
28 | #define VPRBRD_GPIOA_CLK_1MHZ 0 | ||
29 | #define VPRBRD_GPIOA_CLK_100KHZ 1 | ||
30 | #define VPRBRD_GPIOA_CLK_10KHZ 2 | ||
31 | #define VPRBRD_GPIOA_CLK_1KHZ 3 | ||
32 | #define VPRBRD_GPIOA_CLK_100HZ 4 | ||
33 | #define VPRBRD_GPIOA_CLK_10HZ 5 | ||
34 | |||
35 | #define VPRBRD_GPIOA_FREQ_DEFAULT 1000 | ||
36 | |||
37 | #define VPRBRD_GPIOA_CMD_CONT 0x00 | ||
38 | #define VPRBRD_GPIOA_CMD_PULSE 0x01 | ||
39 | #define VPRBRD_GPIOA_CMD_PWM 0x02 | ||
40 | #define VPRBRD_GPIOA_CMD_SETOUT 0x03 | ||
41 | #define VPRBRD_GPIOA_CMD_SETIN 0x04 | ||
42 | #define VPRBRD_GPIOA_CMD_SETINT 0x05 | ||
43 | #define VPRBRD_GPIOA_CMD_GETIN 0x06 | ||
44 | |||
45 | #define VPRBRD_GPIOB_CMD_SETDIR 0x00 | ||
46 | #define VPRBRD_GPIOB_CMD_SETVAL 0x01 | ||
47 | |||
48 | struct vprbrd_gpioa_msg { | ||
49 | u8 cmd; | ||
50 | u8 clk; | ||
51 | u8 offset; | ||
52 | u8 t1; | ||
53 | u8 t2; | ||
54 | u8 invert; | ||
55 | u8 pwmlevel; | ||
56 | u8 outval; | ||
57 | u8 risefall; | ||
58 | u8 answer; | ||
59 | u8 __fill; | ||
60 | } __packed; | ||
61 | |||
62 | struct vprbrd_gpiob_msg { | ||
63 | u8 cmd; | ||
64 | u16 val; | ||
65 | u16 mask; | ||
66 | } __packed; | ||
67 | |||
68 | struct vprbrd_gpio { | ||
69 | struct gpio_chip gpioa; /* gpio a related things */ | ||
70 | u32 gpioa_out; | ||
71 | u32 gpioa_val; | ||
72 | struct gpio_chip gpiob; /* gpio b related things */ | ||
73 | u32 gpiob_out; | ||
74 | u32 gpiob_val; | ||
75 | struct vprbrd *vb; | ||
76 | }; | ||
77 | |||
78 | /* gpioa sampling clock module parameter */ | ||
79 | static unsigned char gpioa_clk; | ||
80 | static unsigned int gpioa_freq = VPRBRD_GPIOA_FREQ_DEFAULT; | ||
81 | module_param(gpioa_freq, uint, 0); | ||
82 | MODULE_PARM_DESC(gpioa_freq, | ||
83 | "gpio-a sampling freq in Hz (default is 1000Hz) valid values: 10, 100, 1000, 10000, 100000, 1000000"); | ||
84 | |||
85 | /* ----- begin of gipo a chip -------------------------------------------- */ | ||
86 | |||
87 | static int vprbrd_gpioa_get(struct gpio_chip *chip, | ||
88 | unsigned offset) | ||
89 | { | ||
90 | int ret, answer, error = 0; | ||
91 | struct vprbrd_gpio *gpio = | ||
92 | container_of(chip, struct vprbrd_gpio, gpioa); | ||
93 | struct vprbrd *vb = gpio->vb; | ||
94 | struct vprbrd_gpioa_msg *gamsg = (struct vprbrd_gpioa_msg *)vb->buf; | ||
95 | |||
96 | /* if io is set to output, just return the saved value */ | ||
97 | if (gpio->gpioa_out & (1 << offset)) | ||
98 | return gpio->gpioa_val & (1 << offset); | ||
99 | |||
100 | mutex_lock(&vb->lock); | ||
101 | |||
102 | gamsg->cmd = VPRBRD_GPIOA_CMD_GETIN; | ||
103 | gamsg->clk = 0x00; | ||
104 | gamsg->offset = offset; | ||
105 | gamsg->t1 = 0x00; | ||
106 | gamsg->t2 = 0x00; | ||
107 | gamsg->invert = 0x00; | ||
108 | gamsg->pwmlevel = 0x00; | ||
109 | gamsg->outval = 0x00; | ||
110 | gamsg->risefall = 0x00; | ||
111 | gamsg->answer = 0x00; | ||
112 | gamsg->__fill = 0x00; | ||
113 | |||
114 | ret = usb_control_msg(vb->usb_dev, usb_sndctrlpipe(vb->usb_dev, 0), | ||
115 | VPRBRD_USB_REQUEST_GPIOA, VPRBRD_USB_TYPE_OUT, 0x0000, | ||
116 | 0x0000, gamsg, sizeof(struct vprbrd_gpioa_msg), | ||
117 | VPRBRD_USB_TIMEOUT_MS); | ||
118 | if (ret != sizeof(struct vprbrd_gpioa_msg)) | ||
119 | error = -EREMOTEIO; | ||
120 | |||
121 | ret = usb_control_msg(vb->usb_dev, usb_rcvctrlpipe(vb->usb_dev, 0), | ||
122 | VPRBRD_USB_REQUEST_GPIOA, VPRBRD_USB_TYPE_IN, 0x0000, | ||
123 | 0x0000, gamsg, sizeof(struct vprbrd_gpioa_msg), | ||
124 | VPRBRD_USB_TIMEOUT_MS); | ||
125 | answer = gamsg->answer & 0x01; | ||
126 | |||
127 | mutex_unlock(&vb->lock); | ||
128 | |||
129 | if (ret != sizeof(struct vprbrd_gpioa_msg)) | ||
130 | error = -EREMOTEIO; | ||
131 | |||
132 | if (error) | ||
133 | return error; | ||
134 | |||
135 | return answer; | ||
136 | } | ||
137 | |||
138 | static void vprbrd_gpioa_set(struct gpio_chip *chip, | ||
139 | unsigned offset, int value) | ||
140 | { | ||
141 | int ret; | ||
142 | struct vprbrd_gpio *gpio = | ||
143 | container_of(chip, struct vprbrd_gpio, gpioa); | ||
144 | struct vprbrd *vb = gpio->vb; | ||
145 | struct vprbrd_gpioa_msg *gamsg = (struct vprbrd_gpioa_msg *)vb->buf; | ||
146 | |||
147 | if (gpio->gpioa_out & (1 << offset)) { | ||
148 | if (value) | ||
149 | gpio->gpioa_val |= (1 << offset); | ||
150 | else | ||
151 | gpio->gpioa_val &= ~(1 << offset); | ||
152 | |||
153 | mutex_lock(&vb->lock); | ||
154 | |||
155 | gamsg->cmd = VPRBRD_GPIOA_CMD_SETOUT; | ||
156 | gamsg->clk = 0x00; | ||
157 | gamsg->offset = offset; | ||
158 | gamsg->t1 = 0x00; | ||
159 | gamsg->t2 = 0x00; | ||
160 | gamsg->invert = 0x00; | ||
161 | gamsg->pwmlevel = 0x00; | ||
162 | gamsg->outval = value; | ||
163 | gamsg->risefall = 0x00; | ||
164 | gamsg->answer = 0x00; | ||
165 | gamsg->__fill = 0x00; | ||
166 | |||
167 | ret = usb_control_msg(vb->usb_dev, | ||
168 | usb_sndctrlpipe(vb->usb_dev, 0), | ||
169 | VPRBRD_USB_REQUEST_GPIOA, VPRBRD_USB_TYPE_OUT, | ||
170 | 0x0000, 0x0000, gamsg, | ||
171 | sizeof(struct vprbrd_gpioa_msg), VPRBRD_USB_TIMEOUT_MS); | ||
172 | |||
173 | mutex_unlock(&vb->lock); | ||
174 | |||
175 | if (ret != sizeof(struct vprbrd_gpioa_msg)) | ||
176 | dev_err(chip->dev, "usb error setting pin value\n"); | ||
177 | } | ||
178 | } | ||
179 | |||
180 | static int vprbrd_gpioa_direction_input(struct gpio_chip *chip, | ||
181 | unsigned offset) | ||
182 | { | ||
183 | int ret; | ||
184 | struct vprbrd_gpio *gpio = | ||
185 | container_of(chip, struct vprbrd_gpio, gpioa); | ||
186 | struct vprbrd *vb = gpio->vb; | ||
187 | struct vprbrd_gpioa_msg *gamsg = (struct vprbrd_gpioa_msg *)vb->buf; | ||
188 | |||
189 | gpio->gpioa_out &= ~(1 << offset); | ||
190 | |||
191 | mutex_lock(&vb->lock); | ||
192 | |||
193 | gamsg->cmd = VPRBRD_GPIOA_CMD_SETIN; | ||
194 | gamsg->clk = gpioa_clk; | ||
195 | gamsg->offset = offset; | ||
196 | gamsg->t1 = 0x00; | ||
197 | gamsg->t2 = 0x00; | ||
198 | gamsg->invert = 0x00; | ||
199 | gamsg->pwmlevel = 0x00; | ||
200 | gamsg->outval = 0x00; | ||
201 | gamsg->risefall = 0x00; | ||
202 | gamsg->answer = 0x00; | ||
203 | gamsg->__fill = 0x00; | ||
204 | |||
205 | ret = usb_control_msg(vb->usb_dev, usb_sndctrlpipe(vb->usb_dev, 0), | ||
206 | VPRBRD_USB_REQUEST_GPIOA, VPRBRD_USB_TYPE_OUT, 0x0000, | ||
207 | 0x0000, gamsg, sizeof(struct vprbrd_gpioa_msg), | ||
208 | VPRBRD_USB_TIMEOUT_MS); | ||
209 | |||
210 | mutex_unlock(&vb->lock); | ||
211 | |||
212 | if (ret != sizeof(struct vprbrd_gpioa_msg)) | ||
213 | return -EREMOTEIO; | ||
214 | |||
215 | return 0; | ||
216 | } | ||
217 | |||
218 | static int vprbrd_gpioa_direction_output(struct gpio_chip *chip, | ||
219 | unsigned offset, int value) | ||
220 | { | ||
221 | int ret; | ||
222 | struct vprbrd_gpio *gpio = | ||
223 | container_of(chip, struct vprbrd_gpio, gpioa); | ||
224 | struct vprbrd *vb = gpio->vb; | ||
225 | struct vprbrd_gpioa_msg *gamsg = (struct vprbrd_gpioa_msg *)vb->buf; | ||
226 | |||
227 | gpio->gpioa_out |= (1 << offset); | ||
228 | if (value) | ||
229 | gpio->gpioa_val |= (1 << offset); | ||
230 | else | ||
231 | gpio->gpioa_val &= ~(1 << offset); | ||
232 | |||
233 | mutex_lock(&vb->lock); | ||
234 | |||
235 | gamsg->cmd = VPRBRD_GPIOA_CMD_SETOUT; | ||
236 | gamsg->clk = 0x00; | ||
237 | gamsg->offset = offset; | ||
238 | gamsg->t1 = 0x00; | ||
239 | gamsg->t2 = 0x00; | ||
240 | gamsg->invert = 0x00; | ||
241 | gamsg->pwmlevel = 0x00; | ||
242 | gamsg->outval = value; | ||
243 | gamsg->risefall = 0x00; | ||
244 | gamsg->answer = 0x00; | ||
245 | gamsg->__fill = 0x00; | ||
246 | |||
247 | ret = usb_control_msg(vb->usb_dev, usb_sndctrlpipe(vb->usb_dev, 0), | ||
248 | VPRBRD_USB_REQUEST_GPIOA, VPRBRD_USB_TYPE_OUT, 0x0000, | ||
249 | 0x0000, gamsg, sizeof(struct vprbrd_gpioa_msg), | ||
250 | VPRBRD_USB_TIMEOUT_MS); | ||
251 | |||
252 | mutex_unlock(&vb->lock); | ||
253 | |||
254 | if (ret != sizeof(struct vprbrd_gpioa_msg)) | ||
255 | return -EREMOTEIO; | ||
256 | |||
257 | return 0; | ||
258 | } | ||
259 | |||
260 | /* ----- end of gpio a chip ---------------------------------------------- */ | ||
261 | |||
262 | /* ----- begin of gipo b chip -------------------------------------------- */ | ||
263 | |||
264 | static int vprbrd_gpiob_setdir(struct vprbrd *vb, unsigned offset, | ||
265 | unsigned dir) | ||
266 | { | ||
267 | struct vprbrd_gpiob_msg *gbmsg = (struct vprbrd_gpiob_msg *)vb->buf; | ||
268 | int ret; | ||
269 | |||
270 | gbmsg->cmd = VPRBRD_GPIOB_CMD_SETDIR; | ||
271 | gbmsg->val = cpu_to_be16(dir << offset); | ||
272 | gbmsg->mask = cpu_to_be16(0x0001 << offset); | ||
273 | |||
274 | ret = usb_control_msg(vb->usb_dev, usb_sndctrlpipe(vb->usb_dev, 0), | ||
275 | VPRBRD_USB_REQUEST_GPIOB, VPRBRD_USB_TYPE_OUT, 0x0000, | ||
276 | 0x0000, gbmsg, sizeof(struct vprbrd_gpiob_msg), | ||
277 | VPRBRD_USB_TIMEOUT_MS); | ||
278 | |||
279 | if (ret != sizeof(struct vprbrd_gpiob_msg)) | ||
280 | return -EREMOTEIO; | ||
281 | |||
282 | return 0; | ||
283 | } | ||
284 | |||
285 | static int vprbrd_gpiob_get(struct gpio_chip *chip, | ||
286 | unsigned offset) | ||
287 | { | ||
288 | int ret; | ||
289 | u16 val; | ||
290 | struct vprbrd_gpio *gpio = | ||
291 | container_of(chip, struct vprbrd_gpio, gpiob); | ||
292 | struct vprbrd *vb = gpio->vb; | ||
293 | struct vprbrd_gpiob_msg *gbmsg = (struct vprbrd_gpiob_msg *)vb->buf; | ||
294 | |||
295 | /* if io is set to output, just return the saved value */ | ||
296 | if (gpio->gpiob_out & (1 << offset)) | ||
297 | return gpio->gpiob_val & (1 << offset); | ||
298 | |||
299 | mutex_lock(&vb->lock); | ||
300 | |||
301 | ret = usb_control_msg(vb->usb_dev, usb_rcvctrlpipe(vb->usb_dev, 0), | ||
302 | VPRBRD_USB_REQUEST_GPIOB, VPRBRD_USB_TYPE_IN, 0x0000, | ||
303 | 0x0000, gbmsg, sizeof(struct vprbrd_gpiob_msg), | ||
304 | VPRBRD_USB_TIMEOUT_MS); | ||
305 | val = gbmsg->val; | ||
306 | |||
307 | mutex_unlock(&vb->lock); | ||
308 | |||
309 | if (ret != sizeof(struct vprbrd_gpiob_msg)) | ||
310 | return ret; | ||
311 | |||
312 | /* cache the read values */ | ||
313 | gpio->gpiob_val = be16_to_cpu(val); | ||
314 | |||
315 | return (gpio->gpiob_val >> offset) & 0x1; | ||
316 | } | ||
317 | |||
318 | static void vprbrd_gpiob_set(struct gpio_chip *chip, | ||
319 | unsigned offset, int value) | ||
320 | { | ||
321 | int ret; | ||
322 | struct vprbrd_gpio *gpio = | ||
323 | container_of(chip, struct vprbrd_gpio, gpiob); | ||
324 | struct vprbrd *vb = gpio->vb; | ||
325 | struct vprbrd_gpiob_msg *gbmsg = (struct vprbrd_gpiob_msg *)vb->buf; | ||
326 | |||
327 | if (gpio->gpiob_out & (1 << offset)) { | ||
328 | if (value) | ||
329 | gpio->gpiob_val |= (1 << offset); | ||
330 | else | ||
331 | gpio->gpiob_val &= ~(1 << offset); | ||
332 | |||
333 | mutex_lock(&vb->lock); | ||
334 | |||
335 | gbmsg->cmd = VPRBRD_GPIOB_CMD_SETVAL; | ||
336 | gbmsg->val = cpu_to_be16(value << offset); | ||
337 | gbmsg->mask = cpu_to_be16(0x0001 << offset); | ||
338 | |||
339 | ret = usb_control_msg(vb->usb_dev, | ||
340 | usb_sndctrlpipe(vb->usb_dev, 0), | ||
341 | VPRBRD_USB_REQUEST_GPIOB, VPRBRD_USB_TYPE_OUT, | ||
342 | 0x0000, 0x0000, gbmsg, | ||
343 | sizeof(struct vprbrd_gpiob_msg), VPRBRD_USB_TIMEOUT_MS); | ||
344 | |||
345 | mutex_unlock(&vb->lock); | ||
346 | |||
347 | if (ret != sizeof(struct vprbrd_gpiob_msg)) | ||
348 | dev_err(chip->dev, "usb error setting pin value\n"); | ||
349 | } | ||
350 | } | ||
351 | |||
352 | static int vprbrd_gpiob_direction_input(struct gpio_chip *chip, | ||
353 | unsigned offset) | ||
354 | { | ||
355 | int ret; | ||
356 | struct vprbrd_gpio *gpio = | ||
357 | container_of(chip, struct vprbrd_gpio, gpiob); | ||
358 | struct vprbrd *vb = gpio->vb; | ||
359 | |||
360 | gpio->gpiob_out &= ~(1 << offset); | ||
361 | |||
362 | mutex_lock(&vb->lock); | ||
363 | |||
364 | ret = vprbrd_gpiob_setdir(vb, offset, 0); | ||
365 | |||
366 | mutex_unlock(&vb->lock); | ||
367 | |||
368 | if (ret) | ||
369 | dev_err(chip->dev, "usb error setting pin to input\n"); | ||
370 | |||
371 | return ret; | ||
372 | } | ||
373 | |||
374 | static int vprbrd_gpiob_direction_output(struct gpio_chip *chip, | ||
375 | unsigned offset, int value) | ||
376 | { | ||
377 | int ret; | ||
378 | struct vprbrd_gpio *gpio = | ||
379 | container_of(chip, struct vprbrd_gpio, gpiob); | ||
380 | struct vprbrd *vb = gpio->vb; | ||
381 | |||
382 | gpio->gpiob_out |= (1 << offset); | ||
383 | if (value) | ||
384 | gpio->gpiob_val |= (1 << offset); | ||
385 | else | ||
386 | gpio->gpiob_val &= ~(1 << offset); | ||
387 | |||
388 | mutex_lock(&vb->lock); | ||
389 | |||
390 | ret = vprbrd_gpiob_setdir(vb, offset, 1); | ||
391 | if (ret) | ||
392 | dev_err(chip->dev, "usb error setting pin to output\n"); | ||
393 | |||
394 | mutex_unlock(&vb->lock); | ||
395 | |||
396 | vprbrd_gpiob_set(chip, offset, value); | ||
397 | |||
398 | return ret; | ||
399 | } | ||
400 | |||
401 | /* ----- end of gpio b chip ---------------------------------------------- */ | ||
402 | |||
403 | static int __devinit vprbrd_gpio_probe(struct platform_device *pdev) | ||
404 | { | ||
405 | struct vprbrd *vb = dev_get_drvdata(pdev->dev.parent); | ||
406 | struct vprbrd_gpio *vb_gpio; | ||
407 | int ret; | ||
408 | |||
409 | vb_gpio = devm_kzalloc(&pdev->dev, sizeof(*vb_gpio), GFP_KERNEL); | ||
410 | if (vb_gpio == NULL) | ||
411 | return -ENOMEM; | ||
412 | |||
413 | vb_gpio->vb = vb; | ||
414 | /* registering gpio a */ | ||
415 | vb_gpio->gpioa.label = "viperboard gpio a"; | ||
416 | vb_gpio->gpioa.dev = &pdev->dev; | ||
417 | vb_gpio->gpioa.owner = THIS_MODULE; | ||
418 | vb_gpio->gpioa.base = -1; | ||
419 | vb_gpio->gpioa.ngpio = 16; | ||
420 | vb_gpio->gpioa.can_sleep = 1; | ||
421 | vb_gpio->gpioa.set = vprbrd_gpioa_set; | ||
422 | vb_gpio->gpioa.get = vprbrd_gpioa_get; | ||
423 | vb_gpio->gpioa.direction_input = vprbrd_gpioa_direction_input; | ||
424 | vb_gpio->gpioa.direction_output = vprbrd_gpioa_direction_output; | ||
425 | ret = gpiochip_add(&vb_gpio->gpioa); | ||
426 | if (ret < 0) { | ||
427 | dev_err(vb_gpio->gpioa.dev, "could not add gpio a"); | ||
428 | goto err_gpioa; | ||
429 | } | ||
430 | |||
431 | /* registering gpio b */ | ||
432 | vb_gpio->gpiob.label = "viperboard gpio b"; | ||
433 | vb_gpio->gpiob.dev = &pdev->dev; | ||
434 | vb_gpio->gpiob.owner = THIS_MODULE; | ||
435 | vb_gpio->gpiob.base = -1; | ||
436 | vb_gpio->gpiob.ngpio = 16; | ||
437 | vb_gpio->gpiob.can_sleep = 1; | ||
438 | vb_gpio->gpiob.set = vprbrd_gpiob_set; | ||
439 | vb_gpio->gpiob.get = vprbrd_gpiob_get; | ||
440 | vb_gpio->gpiob.direction_input = vprbrd_gpiob_direction_input; | ||
441 | vb_gpio->gpiob.direction_output = vprbrd_gpiob_direction_output; | ||
442 | ret = gpiochip_add(&vb_gpio->gpiob); | ||
443 | if (ret < 0) { | ||
444 | dev_err(vb_gpio->gpiob.dev, "could not add gpio b"); | ||
445 | goto err_gpiob; | ||
446 | } | ||
447 | |||
448 | platform_set_drvdata(pdev, vb_gpio); | ||
449 | |||
450 | return ret; | ||
451 | |||
452 | err_gpiob: | ||
453 | ret = gpiochip_remove(&vb_gpio->gpioa); | ||
454 | |||
455 | err_gpioa: | ||
456 | return ret; | ||
457 | } | ||
458 | |||
459 | static int __devexit vprbrd_gpio_remove(struct platform_device *pdev) | ||
460 | { | ||
461 | struct vprbrd_gpio *vb_gpio = platform_get_drvdata(pdev); | ||
462 | int ret; | ||
463 | |||
464 | ret = gpiochip_remove(&vb_gpio->gpiob); | ||
465 | if (ret == 0) | ||
466 | ret = gpiochip_remove(&vb_gpio->gpioa); | ||
467 | |||
468 | return ret; | ||
469 | } | ||
470 | |||
471 | static struct platform_driver vprbrd_gpio_driver = { | ||
472 | .driver.name = "viperboard-gpio", | ||
473 | .driver.owner = THIS_MODULE, | ||
474 | .probe = vprbrd_gpio_probe, | ||
475 | .remove = __devexit_p(vprbrd_gpio_remove), | ||
476 | }; | ||
477 | |||
478 | static int __init vprbrd_gpio_init(void) | ||
479 | { | ||
480 | switch (gpioa_freq) { | ||
481 | case 1000000: | ||
482 | gpioa_clk = VPRBRD_GPIOA_CLK_1MHZ; | ||
483 | break; | ||
484 | case 100000: | ||
485 | gpioa_clk = VPRBRD_GPIOA_CLK_100KHZ; | ||
486 | break; | ||
487 | case 10000: | ||
488 | gpioa_clk = VPRBRD_GPIOA_CLK_10KHZ; | ||
489 | break; | ||
490 | case 1000: | ||
491 | gpioa_clk = VPRBRD_GPIOA_CLK_1KHZ; | ||
492 | break; | ||
493 | case 100: | ||
494 | gpioa_clk = VPRBRD_GPIOA_CLK_100HZ; | ||
495 | break; | ||
496 | case 10: | ||
497 | gpioa_clk = VPRBRD_GPIOA_CLK_10HZ; | ||
498 | break; | ||
499 | default: | ||
500 | pr_warn("invalid gpioa_freq (%d)\n", gpioa_freq); | ||
501 | gpioa_clk = VPRBRD_GPIOA_CLK_1KHZ; | ||
502 | } | ||
503 | |||
504 | return platform_driver_register(&vprbrd_gpio_driver); | ||
505 | } | ||
506 | subsys_initcall(vprbrd_gpio_init); | ||
507 | |||
508 | static void __exit vprbrd_gpio_exit(void) | ||
509 | { | ||
510 | platform_driver_unregister(&vprbrd_gpio_driver); | ||
511 | } | ||
512 | module_exit(vprbrd_gpio_exit); | ||
513 | |||
514 | MODULE_AUTHOR("Lars Poeschel <poeschel@lemonage.de>"); | ||
515 | MODULE_DESCRIPTION("GPIO driver for Nano River Techs Viperboard"); | ||
516 | MODULE_LICENSE("GPL"); | ||
517 | MODULE_ALIAS("platform:viperboard-gpio"); | ||
diff --git a/drivers/gpio/gpio-vr41xx.c b/drivers/gpio/gpio-vr41xx.c index 82d5c20ad3cb..9902732a382d 100644 --- a/drivers/gpio/gpio-vr41xx.c +++ b/drivers/gpio/gpio-vr41xx.c | |||
@@ -490,7 +490,7 @@ static struct gpio_chip vr41xx_gpio_chip = { | |||
490 | .to_irq = vr41xx_gpio_to_irq, | 490 | .to_irq = vr41xx_gpio_to_irq, |
491 | }; | 491 | }; |
492 | 492 | ||
493 | static int __devinit giu_probe(struct platform_device *pdev) | 493 | static int giu_probe(struct platform_device *pdev) |
494 | { | 494 | { |
495 | struct resource *res; | 495 | struct resource *res; |
496 | unsigned int trigger, i, pin; | 496 | unsigned int trigger, i, pin; |
@@ -552,7 +552,7 @@ static int __devinit giu_probe(struct platform_device *pdev) | |||
552 | return cascade_irq(irq, giu_get_irq); | 552 | return cascade_irq(irq, giu_get_irq); |
553 | } | 553 | } |
554 | 554 | ||
555 | static int __devexit giu_remove(struct platform_device *pdev) | 555 | static int giu_remove(struct platform_device *pdev) |
556 | { | 556 | { |
557 | if (giu_base) { | 557 | if (giu_base) { |
558 | iounmap(giu_base); | 558 | iounmap(giu_base); |
@@ -564,7 +564,7 @@ static int __devexit giu_remove(struct platform_device *pdev) | |||
564 | 564 | ||
565 | static struct platform_driver giu_device_driver = { | 565 | static struct platform_driver giu_device_driver = { |
566 | .probe = giu_probe, | 566 | .probe = giu_probe, |
567 | .remove = __devexit_p(giu_remove), | 567 | .remove = giu_remove, |
568 | .driver = { | 568 | .driver = { |
569 | .name = "GIU", | 569 | .name = "GIU", |
570 | .owner = THIS_MODULE, | 570 | .owner = THIS_MODULE, |
diff --git a/drivers/gpio/gpio-vt8500.c b/drivers/gpio/gpio-vt8500.c index bcd8e4aa7c7d..b53320a16fc8 100644 --- a/drivers/gpio/gpio-vt8500.c +++ b/drivers/gpio/gpio-vt8500.c | |||
@@ -96,6 +96,7 @@ static struct vt8500_gpio_data wm8505_data = { | |||
96 | VT8500_BANK(0x5C, 0x84, 0xAC, 0xD4, 12), | 96 | VT8500_BANK(0x5C, 0x84, 0xAC, 0xD4, 12), |
97 | VT8500_BANK(0x60, 0x88, 0xB0, 0xD8, 16), | 97 | VT8500_BANK(0x60, 0x88, 0xB0, 0xD8, 16), |
98 | VT8500_BANK(0x64, 0x8C, 0xB4, 0xDC, 22), | 98 | VT8500_BANK(0x64, 0x8C, 0xB4, 0xDC, 22), |
99 | VT8500_BANK(0x500, 0x504, 0x508, 0x50C, 6), | ||
99 | }, | 100 | }, |
100 | }; | 101 | }; |
101 | 102 | ||
@@ -115,6 +116,7 @@ static struct vt8500_gpio_data wm8650_data = { | |||
115 | VT8500_BANK(0x58, 0x98, 0xD8, 0x18, 32), | 116 | VT8500_BANK(0x58, 0x98, 0xD8, 0x18, 32), |
116 | VT8500_BANK(0x5C, 0x9C, 0xDC, 0x1C, 32), | 117 | VT8500_BANK(0x5C, 0x9C, 0xDC, 0x1C, 32), |
117 | VT8500_BANK(0x7C, 0xBC, 0xFC, 0x3C, 32), | 118 | VT8500_BANK(0x7C, 0xBC, 0xFC, 0x3C, 32), |
119 | VT8500_BANK(0x500, 0x504, 0x508, 0x50C, 6), | ||
118 | }, | 120 | }, |
119 | }; | 121 | }; |
120 | 122 | ||
@@ -269,7 +271,7 @@ static struct of_device_id vt8500_gpio_dt_ids[] = { | |||
269 | { /* Sentinel */ }, | 271 | { /* Sentinel */ }, |
270 | }; | 272 | }; |
271 | 273 | ||
272 | static int __devinit vt8500_gpio_probe(struct platform_device *pdev) | 274 | static int vt8500_gpio_probe(struct platform_device *pdev) |
273 | { | 275 | { |
274 | void __iomem *gpio_base; | 276 | void __iomem *gpio_base; |
275 | struct device_node *np; | 277 | struct device_node *np; |
diff --git a/drivers/gpio/gpio-vx855.c b/drivers/gpio/gpio-vx855.c index 76ebfe5ff702..2b7252cb2427 100644 --- a/drivers/gpio/gpio-vx855.c +++ b/drivers/gpio/gpio-vx855.c | |||
@@ -219,7 +219,7 @@ static void vx855gpio_gpio_setup(struct vx855_gpio *vg) | |||
219 | } | 219 | } |
220 | 220 | ||
221 | /* This platform device is ordinarily registered by the vx855 mfd driver */ | 221 | /* This platform device is ordinarily registered by the vx855 mfd driver */ |
222 | static __devinit int vx855gpio_probe(struct platform_device *pdev) | 222 | static int vx855gpio_probe(struct platform_device *pdev) |
223 | { | 223 | { |
224 | struct resource *res_gpi; | 224 | struct resource *res_gpi; |
225 | struct resource *res_gpo; | 225 | struct resource *res_gpo; |
@@ -284,7 +284,7 @@ out_release: | |||
284 | return ret; | 284 | return ret; |
285 | } | 285 | } |
286 | 286 | ||
287 | static int __devexit vx855gpio_remove(struct platform_device *pdev) | 287 | static int vx855gpio_remove(struct platform_device *pdev) |
288 | { | 288 | { |
289 | struct vx855_gpio *vg = platform_get_drvdata(pdev); | 289 | struct vx855_gpio *vg = platform_get_drvdata(pdev); |
290 | struct resource *res; | 290 | struct resource *res; |
@@ -312,7 +312,7 @@ static struct platform_driver vx855gpio_driver = { | |||
312 | .owner = THIS_MODULE, | 312 | .owner = THIS_MODULE, |
313 | }, | 313 | }, |
314 | .probe = vx855gpio_probe, | 314 | .probe = vx855gpio_probe, |
315 | .remove = __devexit_p(vx855gpio_remove), | 315 | .remove = vx855gpio_remove, |
316 | }; | 316 | }; |
317 | 317 | ||
318 | module_platform_driver(vx855gpio_driver); | 318 | module_platform_driver(vx855gpio_driver); |
diff --git a/drivers/gpio/gpio-wm831x.c b/drivers/gpio/gpio-wm831x.c index b6eda35089d5..2a743e10ecb6 100644 --- a/drivers/gpio/gpio-wm831x.c +++ b/drivers/gpio/gpio-wm831x.c | |||
@@ -243,7 +243,7 @@ static struct gpio_chip template_chip = { | |||
243 | .can_sleep = 1, | 243 | .can_sleep = 1, |
244 | }; | 244 | }; |
245 | 245 | ||
246 | static int __devinit wm831x_gpio_probe(struct platform_device *pdev) | 246 | static int wm831x_gpio_probe(struct platform_device *pdev) |
247 | { | 247 | { |
248 | struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent); | 248 | struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent); |
249 | struct wm831x_pdata *pdata = wm831x->dev->platform_data; | 249 | struct wm831x_pdata *pdata = wm831x->dev->platform_data; |
@@ -275,7 +275,7 @@ static int __devinit wm831x_gpio_probe(struct platform_device *pdev) | |||
275 | return ret; | 275 | return ret; |
276 | } | 276 | } |
277 | 277 | ||
278 | static int __devexit wm831x_gpio_remove(struct platform_device *pdev) | 278 | static int wm831x_gpio_remove(struct platform_device *pdev) |
279 | { | 279 | { |
280 | struct wm831x_gpio *wm831x_gpio = platform_get_drvdata(pdev); | 280 | struct wm831x_gpio *wm831x_gpio = platform_get_drvdata(pdev); |
281 | 281 | ||
@@ -286,7 +286,7 @@ static struct platform_driver wm831x_gpio_driver = { | |||
286 | .driver.name = "wm831x-gpio", | 286 | .driver.name = "wm831x-gpio", |
287 | .driver.owner = THIS_MODULE, | 287 | .driver.owner = THIS_MODULE, |
288 | .probe = wm831x_gpio_probe, | 288 | .probe = wm831x_gpio_probe, |
289 | .remove = __devexit_p(wm831x_gpio_remove), | 289 | .remove = wm831x_gpio_remove, |
290 | }; | 290 | }; |
291 | 291 | ||
292 | static int __init wm831x_gpio_init(void) | 292 | static int __init wm831x_gpio_init(void) |
diff --git a/drivers/gpio/gpio-wm8350.c b/drivers/gpio/gpio-wm8350.c index fb4293889392..0b598cf3df9d 100644 --- a/drivers/gpio/gpio-wm8350.c +++ b/drivers/gpio/gpio-wm8350.c | |||
@@ -109,7 +109,7 @@ static struct gpio_chip template_chip = { | |||
109 | .can_sleep = 1, | 109 | .can_sleep = 1, |
110 | }; | 110 | }; |
111 | 111 | ||
112 | static int __devinit wm8350_gpio_probe(struct platform_device *pdev) | 112 | static int wm8350_gpio_probe(struct platform_device *pdev) |
113 | { | 113 | { |
114 | struct wm8350 *wm8350 = dev_get_drvdata(pdev->dev.parent); | 114 | struct wm8350 *wm8350 = dev_get_drvdata(pdev->dev.parent); |
115 | struct wm8350_platform_data *pdata = wm8350->dev->platform_data; | 115 | struct wm8350_platform_data *pdata = wm8350->dev->platform_data; |
@@ -141,7 +141,7 @@ static int __devinit wm8350_gpio_probe(struct platform_device *pdev) | |||
141 | return ret; | 141 | return ret; |
142 | } | 142 | } |
143 | 143 | ||
144 | static int __devexit wm8350_gpio_remove(struct platform_device *pdev) | 144 | static int wm8350_gpio_remove(struct platform_device *pdev) |
145 | { | 145 | { |
146 | struct wm8350_gpio_data *wm8350_gpio = platform_get_drvdata(pdev); | 146 | struct wm8350_gpio_data *wm8350_gpio = platform_get_drvdata(pdev); |
147 | 147 | ||
@@ -152,7 +152,7 @@ static struct platform_driver wm8350_gpio_driver = { | |||
152 | .driver.name = "wm8350-gpio", | 152 | .driver.name = "wm8350-gpio", |
153 | .driver.owner = THIS_MODULE, | 153 | .driver.owner = THIS_MODULE, |
154 | .probe = wm8350_gpio_probe, | 154 | .probe = wm8350_gpio_probe, |
155 | .remove = __devexit_p(wm8350_gpio_remove), | 155 | .remove = wm8350_gpio_remove, |
156 | }; | 156 | }; |
157 | 157 | ||
158 | static int __init wm8350_gpio_init(void) | 158 | static int __init wm8350_gpio_init(void) |
diff --git a/drivers/gpio/gpio-wm8994.c b/drivers/gpio/gpio-wm8994.c index 1c764e779d80..ae409fd94af7 100644 --- a/drivers/gpio/gpio-wm8994.c +++ b/drivers/gpio/gpio-wm8994.c | |||
@@ -245,7 +245,7 @@ static struct gpio_chip template_chip = { | |||
245 | .can_sleep = 1, | 245 | .can_sleep = 1, |
246 | }; | 246 | }; |
247 | 247 | ||
248 | static int __devinit wm8994_gpio_probe(struct platform_device *pdev) | 248 | static int wm8994_gpio_probe(struct platform_device *pdev) |
249 | { | 249 | { |
250 | struct wm8994 *wm8994 = dev_get_drvdata(pdev->dev.parent); | 250 | struct wm8994 *wm8994 = dev_get_drvdata(pdev->dev.parent); |
251 | struct wm8994_pdata *pdata = wm8994->dev->platform_data; | 251 | struct wm8994_pdata *pdata = wm8994->dev->platform_data; |
@@ -281,7 +281,7 @@ err: | |||
281 | return ret; | 281 | return ret; |
282 | } | 282 | } |
283 | 283 | ||
284 | static int __devexit wm8994_gpio_remove(struct platform_device *pdev) | 284 | static int wm8994_gpio_remove(struct platform_device *pdev) |
285 | { | 285 | { |
286 | struct wm8994_gpio *wm8994_gpio = platform_get_drvdata(pdev); | 286 | struct wm8994_gpio *wm8994_gpio = platform_get_drvdata(pdev); |
287 | 287 | ||
@@ -292,7 +292,7 @@ static struct platform_driver wm8994_gpio_driver = { | |||
292 | .driver.name = "wm8994-gpio", | 292 | .driver.name = "wm8994-gpio", |
293 | .driver.owner = THIS_MODULE, | 293 | .driver.owner = THIS_MODULE, |
294 | .probe = wm8994_gpio_probe, | 294 | .probe = wm8994_gpio_probe, |
295 | .remove = __devexit_p(wm8994_gpio_remove), | 295 | .remove = wm8994_gpio_remove, |
296 | }; | 296 | }; |
297 | 297 | ||
298 | static int __init wm8994_gpio_init(void) | 298 | static int __init wm8994_gpio_init(void) |
diff --git a/drivers/gpio/gpio-xilinx.c b/drivers/gpio/gpio-xilinx.c index 79b0fe8a7253..9ae7aa8ca48a 100644 --- a/drivers/gpio/gpio-xilinx.c +++ b/drivers/gpio/gpio-xilinx.c | |||
@@ -159,7 +159,7 @@ static void xgpio_save_regs(struct of_mm_gpio_chip *mm_gc) | |||
159 | * driver data structure. It returns 0, if the driver is bound to the GPIO | 159 | * driver data structure. It returns 0, if the driver is bound to the GPIO |
160 | * device, or a negative value if there is an error. | 160 | * device, or a negative value if there is an error. |
161 | */ | 161 | */ |
162 | static int __devinit xgpio_of_probe(struct device_node *np) | 162 | static int xgpio_of_probe(struct device_node *np) |
163 | { | 163 | { |
164 | struct xgpio_instance *chip; | 164 | struct xgpio_instance *chip; |
165 | int status = 0; | 165 | int status = 0; |
@@ -209,7 +209,7 @@ static int __devinit xgpio_of_probe(struct device_node *np) | |||
209 | return 0; | 209 | return 0; |
210 | } | 210 | } |
211 | 211 | ||
212 | static struct of_device_id xgpio_of_match[] __devinitdata = { | 212 | static struct of_device_id xgpio_of_match[] = { |
213 | { .compatible = "xlnx,xps-gpio-1.00.a", }, | 213 | { .compatible = "xlnx,xps-gpio-1.00.a", }, |
214 | { /* end of list */ }, | 214 | { /* end of list */ }, |
215 | }; | 215 | }; |
diff --git a/drivers/gpio/gpiolib-acpi.c b/drivers/gpio/gpiolib-acpi.c new file mode 100644 index 000000000000..cbad6e908d30 --- /dev/null +++ b/drivers/gpio/gpiolib-acpi.c | |||
@@ -0,0 +1,54 @@ | |||
1 | /* | ||
2 | * ACPI helpers for GPIO API | ||
3 | * | ||
4 | * Copyright (C) 2012, Intel Corporation | ||
5 | * Authors: Mathias Nyman <mathias.nyman@linux.intel.com> | ||
6 | * Mika Westerberg <mika.westerberg@linux.intel.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 version 2 as | ||
10 | * published by the Free Software Foundation. | ||
11 | */ | ||
12 | |||
13 | #include <linux/errno.h> | ||
14 | #include <linux/gpio.h> | ||
15 | #include <linux/export.h> | ||
16 | #include <linux/acpi_gpio.h> | ||
17 | #include <linux/acpi.h> | ||
18 | |||
19 | static int acpi_gpiochip_find(struct gpio_chip *gc, void *data) | ||
20 | { | ||
21 | if (!gc->dev) | ||
22 | return false; | ||
23 | |||
24 | return ACPI_HANDLE(gc->dev) == data; | ||
25 | } | ||
26 | |||
27 | /** | ||
28 | * acpi_get_gpio() - Translate ACPI GPIO pin to GPIO number usable with GPIO API | ||
29 | * @path: ACPI GPIO controller full path name, (e.g. "\\_SB.GPO1") | ||
30 | * @pin: ACPI GPIO pin number (0-based, controller-relative) | ||
31 | * | ||
32 | * Returns GPIO number to use with Linux generic GPIO API, or errno error value | ||
33 | */ | ||
34 | |||
35 | int acpi_get_gpio(char *path, int pin) | ||
36 | { | ||
37 | struct gpio_chip *chip; | ||
38 | acpi_handle handle; | ||
39 | acpi_status status; | ||
40 | |||
41 | status = acpi_get_handle(NULL, path, &handle); | ||
42 | if (ACPI_FAILURE(status)) | ||
43 | return -ENODEV; | ||
44 | |||
45 | chip = gpiochip_find(handle, acpi_gpiochip_find); | ||
46 | if (!chip) | ||
47 | return -ENODEV; | ||
48 | |||
49 | if (!gpio_is_valid(chip->base + pin)) | ||
50 | return -EINVAL; | ||
51 | |||
52 | return chip->base + pin; | ||
53 | } | ||
54 | EXPORT_SYMBOL_GPL(acpi_get_gpio); | ||
diff --git a/drivers/gpio/gpiolib-of.c b/drivers/gpio/gpiolib-of.c index f1a45997aea8..d542a141811a 100644 --- a/drivers/gpio/gpiolib-of.c +++ b/drivers/gpio/gpiolib-of.c | |||
@@ -19,6 +19,7 @@ | |||
19 | #include <linux/of.h> | 19 | #include <linux/of.h> |
20 | #include <linux/of_address.h> | 20 | #include <linux/of_address.h> |
21 | #include <linux/of_gpio.h> | 21 | #include <linux/of_gpio.h> |
22 | #include <linux/pinctrl/pinctrl.h> | ||
22 | #include <linux/slab.h> | 23 | #include <linux/slab.h> |
23 | 24 | ||
24 | /* Private data structure for of_gpiochip_find_and_xlate */ | 25 | /* Private data structure for of_gpiochip_find_and_xlate */ |
@@ -216,6 +217,54 @@ err0: | |||
216 | } | 217 | } |
217 | EXPORT_SYMBOL(of_mm_gpiochip_add); | 218 | EXPORT_SYMBOL(of_mm_gpiochip_add); |
218 | 219 | ||
220 | #ifdef CONFIG_PINCTRL | ||
221 | static void of_gpiochip_add_pin_range(struct gpio_chip *chip) | ||
222 | { | ||
223 | struct device_node *np = chip->of_node; | ||
224 | struct of_phandle_args pinspec; | ||
225 | struct pinctrl_dev *pctldev; | ||
226 | int index = 0, ret; | ||
227 | |||
228 | if (!np) | ||
229 | return; | ||
230 | |||
231 | do { | ||
232 | ret = of_parse_phandle_with_args(np, "gpio-ranges", | ||
233 | "#gpio-range-cells", index, &pinspec); | ||
234 | if (ret) | ||
235 | break; | ||
236 | |||
237 | pctldev = of_pinctrl_get(pinspec.np); | ||
238 | if (!pctldev) | ||
239 | break; | ||
240 | |||
241 | /* | ||
242 | * This assumes that the n GPIO pins are consecutive in the | ||
243 | * GPIO number space, and that the pins are also consecutive | ||
244 | * in their local number space. Currently it is not possible | ||
245 | * to add different ranges for one and the same GPIO chip, | ||
246 | * as the code assumes that we have one consecutive range | ||
247 | * on both, mapping 1-to-1. | ||
248 | * | ||
249 | * TODO: make the OF bindings handle multiple sparse ranges | ||
250 | * on the same GPIO chip. | ||
251 | */ | ||
252 | ret = gpiochip_add_pin_range(chip, | ||
253 | pinctrl_dev_get_name(pctldev), | ||
254 | 0, /* offset in gpiochip */ | ||
255 | pinspec.args[0], | ||
256 | pinspec.args[1]); | ||
257 | |||
258 | if (ret) | ||
259 | break; | ||
260 | |||
261 | } while (index++); | ||
262 | } | ||
263 | |||
264 | #else | ||
265 | static void of_gpiochip_add_pin_range(struct gpio_chip *chip) {} | ||
266 | #endif | ||
267 | |||
219 | void of_gpiochip_add(struct gpio_chip *chip) | 268 | void of_gpiochip_add(struct gpio_chip *chip) |
220 | { | 269 | { |
221 | if ((!chip->of_node) && (chip->dev)) | 270 | if ((!chip->of_node) && (chip->dev)) |
@@ -229,11 +278,14 @@ void of_gpiochip_add(struct gpio_chip *chip) | |||
229 | chip->of_xlate = of_gpio_simple_xlate; | 278 | chip->of_xlate = of_gpio_simple_xlate; |
230 | } | 279 | } |
231 | 280 | ||
281 | of_gpiochip_add_pin_range(chip); | ||
232 | of_node_get(chip->of_node); | 282 | of_node_get(chip->of_node); |
233 | } | 283 | } |
234 | 284 | ||
235 | void of_gpiochip_remove(struct gpio_chip *chip) | 285 | void of_gpiochip_remove(struct gpio_chip *chip) |
236 | { | 286 | { |
287 | gpiochip_remove_pin_ranges(chip); | ||
288 | |||
237 | if (chip->of_node) | 289 | if (chip->of_node) |
238 | of_node_put(chip->of_node); | 290 | of_node_put(chip->of_node); |
239 | } | 291 | } |
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index 1c8d9e3380e1..199fca15f270 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c | |||
@@ -191,6 +191,32 @@ err: | |||
191 | return ret; | 191 | return ret; |
192 | } | 192 | } |
193 | 193 | ||
194 | /* caller ensures gpio is valid and requested, chip->get_direction may sleep */ | ||
195 | static int gpio_get_direction(unsigned gpio) | ||
196 | { | ||
197 | struct gpio_chip *chip; | ||
198 | struct gpio_desc *desc = &gpio_desc[gpio]; | ||
199 | int status = -EINVAL; | ||
200 | |||
201 | chip = gpio_to_chip(gpio); | ||
202 | gpio -= chip->base; | ||
203 | |||
204 | if (!chip->get_direction) | ||
205 | return status; | ||
206 | |||
207 | status = chip->get_direction(chip, gpio); | ||
208 | if (status > 0) { | ||
209 | /* GPIOF_DIR_IN, or other positive */ | ||
210 | status = 1; | ||
211 | clear_bit(FLAG_IS_OUT, &desc->flags); | ||
212 | } | ||
213 | if (status == 0) { | ||
214 | /* GPIOF_DIR_OUT */ | ||
215 | set_bit(FLAG_IS_OUT, &desc->flags); | ||
216 | } | ||
217 | return status; | ||
218 | } | ||
219 | |||
194 | #ifdef CONFIG_GPIO_SYSFS | 220 | #ifdef CONFIG_GPIO_SYSFS |
195 | 221 | ||
196 | /* lock protects against unexport_gpio() being called while | 222 | /* lock protects against unexport_gpio() being called while |
@@ -223,6 +249,7 @@ static ssize_t gpio_direction_show(struct device *dev, | |||
223 | struct device_attribute *attr, char *buf) | 249 | struct device_attribute *attr, char *buf) |
224 | { | 250 | { |
225 | const struct gpio_desc *desc = dev_get_drvdata(dev); | 251 | const struct gpio_desc *desc = dev_get_drvdata(dev); |
252 | unsigned gpio = desc - gpio_desc; | ||
226 | ssize_t status; | 253 | ssize_t status; |
227 | 254 | ||
228 | mutex_lock(&sysfs_lock); | 255 | mutex_lock(&sysfs_lock); |
@@ -230,6 +257,7 @@ static ssize_t gpio_direction_show(struct device *dev, | |||
230 | if (!test_bit(FLAG_EXPORT, &desc->flags)) | 257 | if (!test_bit(FLAG_EXPORT, &desc->flags)) |
231 | status = -EIO; | 258 | status = -EIO; |
232 | else | 259 | else |
260 | gpio_get_direction(gpio); | ||
233 | status = sprintf(buf, "%s\n", | 261 | status = sprintf(buf, "%s\n", |
234 | test_bit(FLAG_IS_OUT, &desc->flags) | 262 | test_bit(FLAG_IS_OUT, &desc->flags) |
235 | ? "out" : "in"); | 263 | ? "out" : "in"); |
@@ -704,8 +732,9 @@ int gpio_export(unsigned gpio, bool direction_may_change) | |||
704 | { | 732 | { |
705 | unsigned long flags; | 733 | unsigned long flags; |
706 | struct gpio_desc *desc; | 734 | struct gpio_desc *desc; |
707 | int status = -EINVAL; | 735 | int status; |
708 | const char *ioname = NULL; | 736 | const char *ioname = NULL; |
737 | struct device *dev; | ||
709 | 738 | ||
710 | /* can't export until sysfs is available ... */ | 739 | /* can't export until sysfs is available ... */ |
711 | if (!gpio_class.p) { | 740 | if (!gpio_class.p) { |
@@ -713,59 +742,66 @@ int gpio_export(unsigned gpio, bool direction_may_change) | |||
713 | return -ENOENT; | 742 | return -ENOENT; |
714 | } | 743 | } |
715 | 744 | ||
716 | if (!gpio_is_valid(gpio)) | 745 | if (!gpio_is_valid(gpio)) { |
717 | goto done; | 746 | pr_debug("%s: gpio %d is not valid\n", __func__, gpio); |
747 | return -EINVAL; | ||
748 | } | ||
718 | 749 | ||
719 | mutex_lock(&sysfs_lock); | 750 | mutex_lock(&sysfs_lock); |
720 | 751 | ||
721 | spin_lock_irqsave(&gpio_lock, flags); | 752 | spin_lock_irqsave(&gpio_lock, flags); |
722 | desc = &gpio_desc[gpio]; | 753 | desc = &gpio_desc[gpio]; |
723 | if (test_bit(FLAG_REQUESTED, &desc->flags) | 754 | if (!test_bit(FLAG_REQUESTED, &desc->flags) || |
724 | && !test_bit(FLAG_EXPORT, &desc->flags)) { | 755 | test_bit(FLAG_EXPORT, &desc->flags)) { |
725 | status = 0; | 756 | spin_unlock_irqrestore(&gpio_lock, flags); |
726 | if (!desc->chip->direction_input | 757 | pr_debug("%s: gpio %d unavailable (requested=%d, exported=%d)\n", |
727 | || !desc->chip->direction_output) | 758 | __func__, gpio, |
728 | direction_may_change = false; | 759 | test_bit(FLAG_REQUESTED, &desc->flags), |
760 | test_bit(FLAG_EXPORT, &desc->flags)); | ||
761 | status = -EPERM; | ||
762 | goto fail_unlock; | ||
729 | } | 763 | } |
764 | |||
765 | if (!desc->chip->direction_input || !desc->chip->direction_output) | ||
766 | direction_may_change = false; | ||
730 | spin_unlock_irqrestore(&gpio_lock, flags); | 767 | spin_unlock_irqrestore(&gpio_lock, flags); |
731 | 768 | ||
732 | if (desc->chip->names && desc->chip->names[gpio - desc->chip->base]) | 769 | if (desc->chip->names && desc->chip->names[gpio - desc->chip->base]) |
733 | ioname = desc->chip->names[gpio - desc->chip->base]; | 770 | ioname = desc->chip->names[gpio - desc->chip->base]; |
734 | 771 | ||
735 | if (status == 0) { | 772 | dev = device_create(&gpio_class, desc->chip->dev, MKDEV(0, 0), |
736 | struct device *dev; | 773 | desc, ioname ? ioname : "gpio%u", gpio); |
737 | 774 | if (IS_ERR(dev)) { | |
738 | dev = device_create(&gpio_class, desc->chip->dev, MKDEV(0, 0), | 775 | status = PTR_ERR(dev); |
739 | desc, ioname ? ioname : "gpio%u", gpio); | 776 | goto fail_unlock; |
740 | if (!IS_ERR(dev)) { | ||
741 | status = sysfs_create_group(&dev->kobj, | ||
742 | &gpio_attr_group); | ||
743 | |||
744 | if (!status && direction_may_change) | ||
745 | status = device_create_file(dev, | ||
746 | &dev_attr_direction); | ||
747 | |||
748 | if (!status && gpio_to_irq(gpio) >= 0 | ||
749 | && (direction_may_change | ||
750 | || !test_bit(FLAG_IS_OUT, | ||
751 | &desc->flags))) | ||
752 | status = device_create_file(dev, | ||
753 | &dev_attr_edge); | ||
754 | |||
755 | if (status != 0) | ||
756 | device_unregister(dev); | ||
757 | } else | ||
758 | status = PTR_ERR(dev); | ||
759 | if (status == 0) | ||
760 | set_bit(FLAG_EXPORT, &desc->flags); | ||
761 | } | 777 | } |
762 | 778 | ||
763 | mutex_unlock(&sysfs_lock); | 779 | status = sysfs_create_group(&dev->kobj, &gpio_attr_group); |
764 | |||
765 | done: | ||
766 | if (status) | 780 | if (status) |
767 | pr_debug("%s: gpio%d status %d\n", __func__, gpio, status); | 781 | goto fail_unregister_device; |
782 | |||
783 | if (direction_may_change) { | ||
784 | status = device_create_file(dev, &dev_attr_direction); | ||
785 | if (status) | ||
786 | goto fail_unregister_device; | ||
787 | } | ||
788 | |||
789 | if (gpio_to_irq(gpio) >= 0 && (direction_may_change || | ||
790 | !test_bit(FLAG_IS_OUT, &desc->flags))) { | ||
791 | status = device_create_file(dev, &dev_attr_edge); | ||
792 | if (status) | ||
793 | goto fail_unregister_device; | ||
794 | } | ||
795 | |||
796 | set_bit(FLAG_EXPORT, &desc->flags); | ||
797 | mutex_unlock(&sysfs_lock); | ||
798 | return 0; | ||
768 | 799 | ||
800 | fail_unregister_device: | ||
801 | device_unregister(dev); | ||
802 | fail_unlock: | ||
803 | mutex_unlock(&sysfs_lock); | ||
804 | pr_debug("%s: gpio%d status %d\n", __func__, gpio, status); | ||
769 | return status; | 805 | return status; |
770 | } | 806 | } |
771 | EXPORT_SYMBOL_GPL(gpio_export); | 807 | EXPORT_SYMBOL_GPL(gpio_export); |
@@ -1075,6 +1111,7 @@ int gpiochip_add(struct gpio_chip *chip) | |||
1075 | * inputs (often with pullups enabled) so power | 1111 | * inputs (often with pullups enabled) so power |
1076 | * usage is minimized. Linux code should set the | 1112 | * usage is minimized. Linux code should set the |
1077 | * gpio direction first thing; but until it does, | 1113 | * gpio direction first thing; but until it does, |
1114 | * and in case chip->get_direction is not set, | ||
1078 | * we may expose the wrong direction in sysfs. | 1115 | * we may expose the wrong direction in sysfs. |
1079 | */ | 1116 | */ |
1080 | gpio_desc[id].flags = !chip->direction_input | 1117 | gpio_desc[id].flags = !chip->direction_input |
@@ -1083,6 +1120,10 @@ int gpiochip_add(struct gpio_chip *chip) | |||
1083 | } | 1120 | } |
1084 | } | 1121 | } |
1085 | 1122 | ||
1123 | #ifdef CONFIG_PINCTRL | ||
1124 | INIT_LIST_HEAD(&chip->pin_ranges); | ||
1125 | #endif | ||
1126 | |||
1086 | of_gpiochip_add(chip); | 1127 | of_gpiochip_add(chip); |
1087 | 1128 | ||
1088 | unlock: | 1129 | unlock: |
@@ -1123,6 +1164,7 @@ int gpiochip_remove(struct gpio_chip *chip) | |||
1123 | 1164 | ||
1124 | spin_lock_irqsave(&gpio_lock, flags); | 1165 | spin_lock_irqsave(&gpio_lock, flags); |
1125 | 1166 | ||
1167 | gpiochip_remove_pin_ranges(chip); | ||
1126 | of_gpiochip_remove(chip); | 1168 | of_gpiochip_remove(chip); |
1127 | 1169 | ||
1128 | for (id = chip->base; id < chip->base + chip->ngpio; id++) { | 1170 | for (id = chip->base; id < chip->base + chip->ngpio; id++) { |
@@ -1180,6 +1222,77 @@ struct gpio_chip *gpiochip_find(void *data, | |||
1180 | } | 1222 | } |
1181 | EXPORT_SYMBOL_GPL(gpiochip_find); | 1223 | EXPORT_SYMBOL_GPL(gpiochip_find); |
1182 | 1224 | ||
1225 | #ifdef CONFIG_PINCTRL | ||
1226 | |||
1227 | /** | ||
1228 | * gpiochip_add_pin_range() - add a range for GPIO <-> pin mapping | ||
1229 | * @chip: the gpiochip to add the range for | ||
1230 | * @pinctrl_name: the dev_name() of the pin controller to map to | ||
1231 | * @gpio_offset: the start offset in the current gpio_chip number space | ||
1232 | * @pin_offset: the start offset in the pin controller number space | ||
1233 | * @npins: the number of pins from the offset of each pin space (GPIO and | ||
1234 | * pin controller) to accumulate in this range | ||
1235 | */ | ||
1236 | int gpiochip_add_pin_range(struct gpio_chip *chip, const char *pinctl_name, | ||
1237 | unsigned int gpio_offset, unsigned int pin_offset, | ||
1238 | unsigned int npins) | ||
1239 | { | ||
1240 | struct gpio_pin_range *pin_range; | ||
1241 | int ret; | ||
1242 | |||
1243 | pin_range = kzalloc(sizeof(*pin_range), GFP_KERNEL); | ||
1244 | if (!pin_range) { | ||
1245 | pr_err("%s: GPIO chip: failed to allocate pin ranges\n", | ||
1246 | chip->label); | ||
1247 | return -ENOMEM; | ||
1248 | } | ||
1249 | |||
1250 | /* Use local offset as range ID */ | ||
1251 | pin_range->range.id = gpio_offset; | ||
1252 | pin_range->range.gc = chip; | ||
1253 | pin_range->range.name = chip->label; | ||
1254 | pin_range->range.base = chip->base + gpio_offset; | ||
1255 | pin_range->range.pin_base = pin_offset; | ||
1256 | pin_range->range.npins = npins; | ||
1257 | pin_range->pctldev = pinctrl_find_and_add_gpio_range(pinctl_name, | ||
1258 | &pin_range->range); | ||
1259 | if (IS_ERR(pin_range->pctldev)) { | ||
1260 | ret = PTR_ERR(pin_range->pctldev); | ||
1261 | pr_err("%s: GPIO chip: could not create pin range\n", | ||
1262 | chip->label); | ||
1263 | kfree(pin_range); | ||
1264 | return ret; | ||
1265 | } | ||
1266 | pr_debug("GPIO chip %s: created GPIO range %d->%d ==> %s PIN %d->%d\n", | ||
1267 | chip->label, gpio_offset, gpio_offset + npins - 1, | ||
1268 | pinctl_name, | ||
1269 | pin_offset, pin_offset + npins - 1); | ||
1270 | |||
1271 | list_add_tail(&pin_range->node, &chip->pin_ranges); | ||
1272 | |||
1273 | return 0; | ||
1274 | } | ||
1275 | EXPORT_SYMBOL_GPL(gpiochip_add_pin_range); | ||
1276 | |||
1277 | /** | ||
1278 | * gpiochip_remove_pin_ranges() - remove all the GPIO <-> pin mappings | ||
1279 | * @chip: the chip to remove all the mappings for | ||
1280 | */ | ||
1281 | void gpiochip_remove_pin_ranges(struct gpio_chip *chip) | ||
1282 | { | ||
1283 | struct gpio_pin_range *pin_range, *tmp; | ||
1284 | |||
1285 | list_for_each_entry_safe(pin_range, tmp, &chip->pin_ranges, node) { | ||
1286 | list_del(&pin_range->node); | ||
1287 | pinctrl_remove_gpio_range(pin_range->pctldev, | ||
1288 | &pin_range->range); | ||
1289 | kfree(pin_range); | ||
1290 | } | ||
1291 | } | ||
1292 | EXPORT_SYMBOL_GPL(gpiochip_remove_pin_ranges); | ||
1293 | |||
1294 | #endif /* CONFIG_PINCTRL */ | ||
1295 | |||
1183 | /* These "optional" allocation calls help prevent drivers from stomping | 1296 | /* These "optional" allocation calls help prevent drivers from stomping |
1184 | * on each other, and help provide better diagnostics in debugfs. | 1297 | * on each other, and help provide better diagnostics in debugfs. |
1185 | * They're called even less than the "set direction" calls. | 1298 | * They're called even less than the "set direction" calls. |
@@ -1228,9 +1341,15 @@ int gpio_request(unsigned gpio, const char *label) | |||
1228 | desc_set_label(desc, NULL); | 1341 | desc_set_label(desc, NULL); |
1229 | module_put(chip->owner); | 1342 | module_put(chip->owner); |
1230 | clear_bit(FLAG_REQUESTED, &desc->flags); | 1343 | clear_bit(FLAG_REQUESTED, &desc->flags); |
1344 | goto done; | ||
1231 | } | 1345 | } |
1232 | } | 1346 | } |
1233 | 1347 | if (chip->get_direction) { | |
1348 | /* chip->get_direction may sleep */ | ||
1349 | spin_unlock_irqrestore(&gpio_lock, flags); | ||
1350 | gpio_get_direction(gpio); | ||
1351 | spin_lock_irqsave(&gpio_lock, flags); | ||
1352 | } | ||
1234 | done: | 1353 | done: |
1235 | if (status) | 1354 | if (status) |
1236 | pr_debug("gpio_request: gpio-%d (%s) status %d\n", | 1355 | pr_debug("gpio_request: gpio-%d (%s) status %d\n", |
@@ -1766,6 +1885,7 @@ static void gpiolib_dbg_show(struct seq_file *s, struct gpio_chip *chip) | |||
1766 | if (!test_bit(FLAG_REQUESTED, &gdesc->flags)) | 1885 | if (!test_bit(FLAG_REQUESTED, &gdesc->flags)) |
1767 | continue; | 1886 | continue; |
1768 | 1887 | ||
1888 | gpio_get_direction(gpio); | ||
1769 | is_out = test_bit(FLAG_IS_OUT, &gdesc->flags); | 1889 | is_out = test_bit(FLAG_IS_OUT, &gdesc->flags); |
1770 | seq_printf(s, " gpio-%-3d (%-20.20s) %s %s", | 1890 | seq_printf(s, " gpio-%-3d (%-20.20s) %s %s", |
1771 | gpio, gdesc->label, | 1891 | gpio, gdesc->label, |