diff options
Diffstat (limited to 'drivers')
48 files changed, 1110 insertions, 620 deletions
diff --git a/drivers/bcma/driver_gpio.c b/drivers/bcma/driver_gpio.c index 57ce5fe65364..706b9ae0dcfb 100644 --- a/drivers/bcma/driver_gpio.c +++ b/drivers/bcma/driver_gpio.c | |||
@@ -255,5 +255,6 @@ int bcma_gpio_init(struct bcma_drv_cc *cc) | |||
255 | int bcma_gpio_unregister(struct bcma_drv_cc *cc) | 255 | int bcma_gpio_unregister(struct bcma_drv_cc *cc) |
256 | { | 256 | { |
257 | bcma_gpio_irq_domain_exit(cc); | 257 | bcma_gpio_irq_domain_exit(cc); |
258 | return gpiochip_remove(&cc->gpio); | 258 | gpiochip_remove(&cc->gpio); |
259 | return 0; | ||
259 | } | 260 | } |
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index 9de1515e5808..0959ca9b6b27 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig | |||
@@ -136,7 +136,6 @@ config GPIO_DWAPB | |||
136 | tristate "Synopsys DesignWare APB GPIO driver" | 136 | tristate "Synopsys DesignWare APB GPIO driver" |
137 | select GPIO_GENERIC | 137 | select GPIO_GENERIC |
138 | select GENERIC_IRQ_CHIP | 138 | select GENERIC_IRQ_CHIP |
139 | depends on OF_GPIO | ||
140 | help | 139 | help |
141 | Say Y or M here to build support for the Synopsys DesignWare APB | 140 | Say Y or M here to build support for the Synopsys DesignWare APB |
142 | GPIO block. | 141 | GPIO block. |
@@ -334,6 +333,15 @@ config GPIO_TZ1090_PDC | |||
334 | help | 333 | help |
335 | Say yes here to support Toumaz Xenif TZ1090 PDC GPIOs. | 334 | Say yes here to support Toumaz Xenif TZ1090 PDC GPIOs. |
336 | 335 | ||
336 | config GPIO_XGENE | ||
337 | bool "APM X-Gene GPIO controller support" | ||
338 | depends on ARM64 && OF_GPIO | ||
339 | help | ||
340 | This driver is to support the GPIO block within the APM X-Gene SoC | ||
341 | platform's generic flash controller. The GPIO pins are muxed with | ||
342 | the generic flash controller's address and data pins. Say yes | ||
343 | here to enable the GFC GPIO functionality. | ||
344 | |||
337 | config GPIO_XILINX | 345 | config GPIO_XILINX |
338 | bool "Xilinx GPIO support" | 346 | bool "Xilinx GPIO support" |
339 | depends on PPC_OF || MICROBLAZE || ARCH_ZYNQ | 347 | depends on PPC_OF || MICROBLAZE || ARCH_ZYNQ |
@@ -681,6 +689,7 @@ config GPIO_ADP5588_IRQ | |||
681 | config GPIO_ADNP | 689 | config GPIO_ADNP |
682 | tristate "Avionic Design N-bit GPIO expander" | 690 | tristate "Avionic Design N-bit GPIO expander" |
683 | depends on I2C && OF_GPIO | 691 | depends on I2C && OF_GPIO |
692 | select GPIOLIB_IRQCHIP | ||
684 | help | 693 | help |
685 | This option enables support for N GPIOs found on Avionic Design | 694 | This option enables support for N GPIOs found on Avionic Design |
686 | I2C GPIO expanders. The register space will be extended by powers | 695 | I2C GPIO expanders. The register space will be extended by powers |
@@ -796,7 +805,6 @@ config GPIO_MAX7301 | |||
796 | 805 | ||
797 | config GPIO_MCP23S08 | 806 | config GPIO_MCP23S08 |
798 | tristate "Microchip MCP23xxx I/O expander" | 807 | tristate "Microchip MCP23xxx I/O expander" |
799 | depends on OF_GPIO | ||
800 | depends on (SPI_MASTER && !I2C) || I2C | 808 | depends on (SPI_MASTER && !I2C) || I2C |
801 | help | 809 | help |
802 | SPI/I2C driver for Microchip MCP23S08/MCP23S17/MCP23008/MCP23017 | 810 | SPI/I2C driver for Microchip MCP23S08/MCP23S17/MCP23008/MCP23017 |
@@ -880,7 +888,7 @@ config GPIO_MSIC | |||
880 | 888 | ||
881 | config GPIO_BCM_KONA | 889 | config GPIO_BCM_KONA |
882 | bool "Broadcom Kona GPIO" | 890 | bool "Broadcom Kona GPIO" |
883 | depends on OF_GPIO | 891 | depends on OF_GPIO && (ARCH_BCM_MOBILE || COMPILE_TEST) |
884 | help | 892 | help |
885 | Turn on GPIO support for Broadcom "Kona" chips. | 893 | Turn on GPIO support for Broadcom "Kona" chips. |
886 | 894 | ||
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile index 5d024e396622..e5d346cf3b6e 100644 --- a/drivers/gpio/Makefile +++ b/drivers/gpio/Makefile | |||
@@ -101,6 +101,7 @@ obj-$(CONFIG_GPIO_VX855) += gpio-vx855.o | |||
101 | obj-$(CONFIG_GPIO_WM831X) += gpio-wm831x.o | 101 | obj-$(CONFIG_GPIO_WM831X) += gpio-wm831x.o |
102 | obj-$(CONFIG_GPIO_WM8350) += gpio-wm8350.o | 102 | obj-$(CONFIG_GPIO_WM8350) += gpio-wm8350.o |
103 | obj-$(CONFIG_GPIO_WM8994) += gpio-wm8994.o | 103 | obj-$(CONFIG_GPIO_WM8994) += gpio-wm8994.o |
104 | obj-$(CONFIG_GPIO_XGENE) += gpio-xgene.o | ||
104 | obj-$(CONFIG_GPIO_XILINX) += gpio-xilinx.o | 105 | obj-$(CONFIG_GPIO_XILINX) += gpio-xilinx.o |
105 | obj-$(CONFIG_GPIO_XTENSA) += gpio-xtensa.o | 106 | obj-$(CONFIG_GPIO_XTENSA) += gpio-xtensa.o |
106 | obj-$(CONFIG_GPIO_ZEVIO) += gpio-zevio.o | 107 | obj-$(CONFIG_GPIO_ZEVIO) += gpio-zevio.o |
diff --git a/drivers/gpio/gpio-adnp.c b/drivers/gpio/gpio-adnp.c index 416b2200d4f1..d3d0a90fe542 100644 --- a/drivers/gpio/gpio-adnp.c +++ b/drivers/gpio/gpio-adnp.c | |||
@@ -6,10 +6,9 @@ | |||
6 | * published by the Free Software Foundation. | 6 | * published by the Free Software Foundation. |
7 | */ | 7 | */ |
8 | 8 | ||
9 | #include <linux/gpio.h> | 9 | #include <linux/gpio/driver.h> |
10 | #include <linux/i2c.h> | 10 | #include <linux/i2c.h> |
11 | #include <linux/interrupt.h> | 11 | #include <linux/interrupt.h> |
12 | #include <linux/irqdomain.h> | ||
13 | #include <linux/module.h> | 12 | #include <linux/module.h> |
14 | #include <linux/of_irq.h> | 13 | #include <linux/of_irq.h> |
15 | #include <linux/seq_file.h> | 14 | #include <linux/seq_file.h> |
@@ -27,8 +26,6 @@ struct adnp { | |||
27 | unsigned int reg_shift; | 26 | unsigned int reg_shift; |
28 | 27 | ||
29 | struct mutex i2c_lock; | 28 | struct mutex i2c_lock; |
30 | |||
31 | struct irq_domain *domain; | ||
32 | struct mutex irq_lock; | 29 | struct mutex irq_lock; |
33 | 30 | ||
34 | u8 *irq_enable; | 31 | u8 *irq_enable; |
@@ -253,6 +250,7 @@ static void adnp_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip) | |||
253 | static int adnp_gpio_setup(struct adnp *adnp, unsigned int num_gpios) | 250 | static int adnp_gpio_setup(struct adnp *adnp, unsigned int num_gpios) |
254 | { | 251 | { |
255 | struct gpio_chip *chip = &adnp->gpio; | 252 | struct gpio_chip *chip = &adnp->gpio; |
253 | int err; | ||
256 | 254 | ||
257 | adnp->reg_shift = get_count_order(num_gpios) - 3; | 255 | adnp->reg_shift = get_count_order(num_gpios) - 3; |
258 | 256 | ||
@@ -272,6 +270,10 @@ static int adnp_gpio_setup(struct adnp *adnp, unsigned int num_gpios) | |||
272 | chip->of_node = chip->dev->of_node; | 270 | chip->of_node = chip->dev->of_node; |
273 | chip->owner = THIS_MODULE; | 271 | chip->owner = THIS_MODULE; |
274 | 272 | ||
273 | err = gpiochip_add(chip); | ||
274 | if (err) | ||
275 | return err; | ||
276 | |||
275 | return 0; | 277 | return 0; |
276 | } | 278 | } |
277 | 279 | ||
@@ -326,7 +328,8 @@ static irqreturn_t adnp_irq(int irq, void *data) | |||
326 | 328 | ||
327 | for_each_set_bit(bit, &pending, 8) { | 329 | for_each_set_bit(bit, &pending, 8) { |
328 | unsigned int child_irq; | 330 | unsigned int child_irq; |
329 | child_irq = irq_find_mapping(adnp->domain, base + bit); | 331 | child_irq = irq_find_mapping(adnp->gpio.irqdomain, |
332 | base + bit); | ||
330 | handle_nested_irq(child_irq); | 333 | handle_nested_irq(child_irq); |
331 | } | 334 | } |
332 | } | 335 | } |
@@ -334,35 +337,32 @@ static irqreturn_t adnp_irq(int irq, void *data) | |||
334 | return IRQ_HANDLED; | 337 | return IRQ_HANDLED; |
335 | } | 338 | } |
336 | 339 | ||
337 | static int adnp_gpio_to_irq(struct gpio_chip *chip, unsigned offset) | 340 | static void adnp_irq_mask(struct irq_data *d) |
338 | { | ||
339 | struct adnp *adnp = to_adnp(chip); | ||
340 | return irq_create_mapping(adnp->domain, offset); | ||
341 | } | ||
342 | |||
343 | static void adnp_irq_mask(struct irq_data *data) | ||
344 | { | 341 | { |
345 | struct adnp *adnp = irq_data_get_irq_chip_data(data); | 342 | struct gpio_chip *gc = irq_data_get_irq_chip_data(d); |
346 | unsigned int reg = data->hwirq >> adnp->reg_shift; | 343 | struct adnp *adnp = to_adnp(gc); |
347 | unsigned int pos = data->hwirq & 7; | 344 | unsigned int reg = d->hwirq >> adnp->reg_shift; |
345 | unsigned int pos = d->hwirq & 7; | ||
348 | 346 | ||
349 | adnp->irq_enable[reg] &= ~BIT(pos); | 347 | adnp->irq_enable[reg] &= ~BIT(pos); |
350 | } | 348 | } |
351 | 349 | ||
352 | static void adnp_irq_unmask(struct irq_data *data) | 350 | static void adnp_irq_unmask(struct irq_data *d) |
353 | { | 351 | { |
354 | struct adnp *adnp = irq_data_get_irq_chip_data(data); | 352 | struct gpio_chip *gc = irq_data_get_irq_chip_data(d); |
355 | unsigned int reg = data->hwirq >> adnp->reg_shift; | 353 | struct adnp *adnp = to_adnp(gc); |
356 | unsigned int pos = data->hwirq & 7; | 354 | unsigned int reg = d->hwirq >> adnp->reg_shift; |
355 | unsigned int pos = d->hwirq & 7; | ||
357 | 356 | ||
358 | adnp->irq_enable[reg] |= BIT(pos); | 357 | adnp->irq_enable[reg] |= BIT(pos); |
359 | } | 358 | } |
360 | 359 | ||
361 | static int adnp_irq_set_type(struct irq_data *data, unsigned int type) | 360 | static int adnp_irq_set_type(struct irq_data *d, unsigned int type) |
362 | { | 361 | { |
363 | struct adnp *adnp = irq_data_get_irq_chip_data(data); | 362 | struct gpio_chip *gc = irq_data_get_irq_chip_data(d); |
364 | unsigned int reg = data->hwirq >> adnp->reg_shift; | 363 | struct adnp *adnp = to_adnp(gc); |
365 | unsigned int pos = data->hwirq & 7; | 364 | unsigned int reg = d->hwirq >> adnp->reg_shift; |
365 | unsigned int pos = d->hwirq & 7; | ||
366 | 366 | ||
367 | if (type & IRQ_TYPE_EDGE_RISING) | 367 | if (type & IRQ_TYPE_EDGE_RISING) |
368 | adnp->irq_rise[reg] |= BIT(pos); | 368 | adnp->irq_rise[reg] |= BIT(pos); |
@@ -387,16 +387,18 @@ static int adnp_irq_set_type(struct irq_data *data, unsigned int type) | |||
387 | return 0; | 387 | return 0; |
388 | } | 388 | } |
389 | 389 | ||
390 | static void adnp_irq_bus_lock(struct irq_data *data) | 390 | static void adnp_irq_bus_lock(struct irq_data *d) |
391 | { | 391 | { |
392 | struct adnp *adnp = irq_data_get_irq_chip_data(data); | 392 | struct gpio_chip *gc = irq_data_get_irq_chip_data(d); |
393 | struct adnp *adnp = to_adnp(gc); | ||
393 | 394 | ||
394 | mutex_lock(&adnp->irq_lock); | 395 | mutex_lock(&adnp->irq_lock); |
395 | } | 396 | } |
396 | 397 | ||
397 | static void adnp_irq_bus_unlock(struct irq_data *data) | 398 | static void adnp_irq_bus_unlock(struct irq_data *d) |
398 | { | 399 | { |
399 | struct adnp *adnp = irq_data_get_irq_chip_data(data); | 400 | struct gpio_chip *gc = irq_data_get_irq_chip_data(d); |
401 | struct adnp *adnp = to_adnp(gc); | ||
400 | unsigned int num_regs = 1 << adnp->reg_shift, i; | 402 | unsigned int num_regs = 1 << adnp->reg_shift, i; |
401 | 403 | ||
402 | mutex_lock(&adnp->i2c_lock); | 404 | mutex_lock(&adnp->i2c_lock); |
@@ -408,26 +410,6 @@ static void adnp_irq_bus_unlock(struct irq_data *data) | |||
408 | mutex_unlock(&adnp->irq_lock); | 410 | mutex_unlock(&adnp->irq_lock); |
409 | } | 411 | } |
410 | 412 | ||
411 | static int adnp_irq_reqres(struct irq_data *data) | ||
412 | { | ||
413 | struct adnp *adnp = irq_data_get_irq_chip_data(data); | ||
414 | |||
415 | if (gpio_lock_as_irq(&adnp->gpio, data->hwirq)) { | ||
416 | dev_err(adnp->gpio.dev, | ||
417 | "unable to lock HW IRQ %lu for IRQ\n", | ||
418 | data->hwirq); | ||
419 | return -EINVAL; | ||
420 | } | ||
421 | return 0; | ||
422 | } | ||
423 | |||
424 | static void adnp_irq_relres(struct irq_data *data) | ||
425 | { | ||
426 | struct adnp *adnp = irq_data_get_irq_chip_data(data); | ||
427 | |||
428 | gpio_unlock_as_irq(&adnp->gpio, data->hwirq); | ||
429 | } | ||
430 | |||
431 | static struct irq_chip adnp_irq_chip = { | 413 | static struct irq_chip adnp_irq_chip = { |
432 | .name = "gpio-adnp", | 414 | .name = "gpio-adnp", |
433 | .irq_mask = adnp_irq_mask, | 415 | .irq_mask = adnp_irq_mask, |
@@ -435,29 +417,6 @@ static struct irq_chip adnp_irq_chip = { | |||
435 | .irq_set_type = adnp_irq_set_type, | 417 | .irq_set_type = adnp_irq_set_type, |
436 | .irq_bus_lock = adnp_irq_bus_lock, | 418 | .irq_bus_lock = adnp_irq_bus_lock, |
437 | .irq_bus_sync_unlock = adnp_irq_bus_unlock, | 419 | .irq_bus_sync_unlock = adnp_irq_bus_unlock, |
438 | .irq_request_resources = adnp_irq_reqres, | ||
439 | .irq_release_resources = adnp_irq_relres, | ||
440 | }; | ||
441 | |||
442 | static int adnp_irq_map(struct irq_domain *domain, unsigned int irq, | ||
443 | irq_hw_number_t hwirq) | ||
444 | { | ||
445 | irq_set_chip_data(irq, domain->host_data); | ||
446 | irq_set_chip(irq, &adnp_irq_chip); | ||
447 | irq_set_nested_thread(irq, true); | ||
448 | |||
449 | #ifdef CONFIG_ARM | ||
450 | set_irq_flags(irq, IRQF_VALID); | ||
451 | #else | ||
452 | irq_set_noprobe(irq); | ||
453 | #endif | ||
454 | |||
455 | return 0; | ||
456 | } | ||
457 | |||
458 | static const struct irq_domain_ops adnp_irq_domain_ops = { | ||
459 | .map = adnp_irq_map, | ||
460 | .xlate = irq_domain_xlate_twocell, | ||
461 | }; | 420 | }; |
462 | 421 | ||
463 | static int adnp_irq_setup(struct adnp *adnp) | 422 | static int adnp_irq_setup(struct adnp *adnp) |
@@ -503,35 +462,28 @@ static int adnp_irq_setup(struct adnp *adnp) | |||
503 | adnp->irq_enable[i] = 0x00; | 462 | adnp->irq_enable[i] = 0x00; |
504 | } | 463 | } |
505 | 464 | ||
506 | adnp->domain = irq_domain_add_linear(chip->of_node, chip->ngpio, | 465 | err = devm_request_threaded_irq(chip->dev, adnp->client->irq, |
507 | &adnp_irq_domain_ops, adnp); | 466 | NULL, adnp_irq, |
508 | 467 | IRQF_TRIGGER_RISING | IRQF_ONESHOT, | |
509 | err = request_threaded_irq(adnp->client->irq, NULL, adnp_irq, | 468 | dev_name(chip->dev), adnp); |
510 | IRQF_TRIGGER_RISING | IRQF_ONESHOT, | ||
511 | dev_name(chip->dev), adnp); | ||
512 | if (err != 0) { | 469 | if (err != 0) { |
513 | dev_err(chip->dev, "can't request IRQ#%d: %d\n", | 470 | dev_err(chip->dev, "can't request IRQ#%d: %d\n", |
514 | adnp->client->irq, err); | 471 | adnp->client->irq, err); |
515 | return err; | 472 | return err; |
516 | } | 473 | } |
517 | 474 | ||
518 | chip->to_irq = adnp_gpio_to_irq; | 475 | err = gpiochip_irqchip_add(chip, |
519 | return 0; | 476 | &adnp_irq_chip, |
520 | } | 477 | 0, |
521 | 478 | handle_simple_irq, | |
522 | static void adnp_irq_teardown(struct adnp *adnp) | 479 | IRQ_TYPE_NONE); |
523 | { | 480 | if (err) { |
524 | unsigned int irq, i; | 481 | dev_err(chip->dev, |
525 | 482 | "could not connect irqchip to gpiochip\n"); | |
526 | free_irq(adnp->client->irq, adnp); | 483 | return err; |
527 | |||
528 | for (i = 0; i < adnp->gpio.ngpio; i++) { | ||
529 | irq = irq_find_mapping(adnp->domain, i); | ||
530 | if (irq > 0) | ||
531 | irq_dispose_mapping(irq); | ||
532 | } | 484 | } |
533 | 485 | ||
534 | irq_domain_remove(adnp->domain); | 486 | return 0; |
535 | } | 487 | } |
536 | 488 | ||
537 | static int adnp_i2c_probe(struct i2c_client *client, | 489 | static int adnp_i2c_probe(struct i2c_client *client, |
@@ -558,38 +510,25 @@ static int adnp_i2c_probe(struct i2c_client *client, | |||
558 | adnp->client = client; | 510 | adnp->client = client; |
559 | 511 | ||
560 | err = adnp_gpio_setup(adnp, num_gpios); | 512 | err = adnp_gpio_setup(adnp, num_gpios); |
561 | if (err < 0) | 513 | if (err) |
562 | return err; | 514 | return err; |
563 | 515 | ||
564 | if (of_find_property(np, "interrupt-controller", NULL)) { | 516 | if (of_find_property(np, "interrupt-controller", NULL)) { |
565 | err = adnp_irq_setup(adnp); | 517 | err = adnp_irq_setup(adnp); |
566 | if (err < 0) | 518 | if (err) |
567 | goto teardown; | 519 | return err; |
568 | } | 520 | } |
569 | 521 | ||
570 | err = gpiochip_add(&adnp->gpio); | ||
571 | if (err < 0) | ||
572 | goto teardown; | ||
573 | |||
574 | i2c_set_clientdata(client, adnp); | 522 | i2c_set_clientdata(client, adnp); |
575 | return 0; | ||
576 | 523 | ||
577 | teardown: | 524 | return 0; |
578 | if (of_find_property(np, "interrupt-controller", NULL)) | ||
579 | adnp_irq_teardown(adnp); | ||
580 | |||
581 | return err; | ||
582 | } | 525 | } |
583 | 526 | ||
584 | static int adnp_i2c_remove(struct i2c_client *client) | 527 | static int adnp_i2c_remove(struct i2c_client *client) |
585 | { | 528 | { |
586 | struct adnp *adnp = i2c_get_clientdata(client); | 529 | struct adnp *adnp = i2c_get_clientdata(client); |
587 | struct device_node *np = client->dev.of_node; | ||
588 | 530 | ||
589 | gpiochip_remove(&adnp->gpio); | 531 | gpiochip_remove(&adnp->gpio); |
590 | if (of_find_property(np, "interrupt-controller", NULL)) | ||
591 | adnp_irq_teardown(adnp); | ||
592 | |||
593 | return 0; | 532 | return 0; |
594 | } | 533 | } |
595 | 534 | ||
diff --git a/drivers/gpio/gpio-bcm-kona.c b/drivers/gpio/gpio-bcm-kona.c index 3f6b33ce9bd4..de0801e9767a 100644 --- a/drivers/gpio/gpio-bcm-kona.c +++ b/drivers/gpio/gpio-bcm-kona.c | |||
@@ -496,7 +496,7 @@ static struct irq_chip bcm_gpio_irq_chip = { | |||
496 | .irq_release_resources = bcm_kona_gpio_irq_relres, | 496 | .irq_release_resources = bcm_kona_gpio_irq_relres, |
497 | }; | 497 | }; |
498 | 498 | ||
499 | static struct __initconst of_device_id bcm_kona_gpio_of_match[] = { | 499 | static struct of_device_id const bcm_kona_gpio_of_match[] = { |
500 | { .compatible = "brcm,kona-gpio" }, | 500 | { .compatible = "brcm,kona-gpio" }, |
501 | {} | 501 | {} |
502 | }; | 502 | }; |
diff --git a/drivers/gpio/gpio-crystalcove.c b/drivers/gpio/gpio-crystalcove.c index 934462f5bd22..bbfe7f508502 100644 --- a/drivers/gpio/gpio-crystalcove.c +++ b/drivers/gpio/gpio-crystalcove.c | |||
@@ -24,6 +24,7 @@ | |||
24 | #include <linux/mfd/intel_soc_pmic.h> | 24 | #include <linux/mfd/intel_soc_pmic.h> |
25 | 25 | ||
26 | #define CRYSTALCOVE_GPIO_NUM 16 | 26 | #define CRYSTALCOVE_GPIO_NUM 16 |
27 | #define CRYSTALCOVE_VGPIO_NUM 94 | ||
27 | 28 | ||
28 | #define UPDATE_IRQ_TYPE BIT(0) | 29 | #define UPDATE_IRQ_TYPE BIT(0) |
29 | #define UPDATE_IRQ_MASK BIT(1) | 30 | #define UPDATE_IRQ_MASK BIT(1) |
@@ -130,6 +131,9 @@ static int crystalcove_gpio_dir_in(struct gpio_chip *chip, unsigned gpio) | |||
130 | { | 131 | { |
131 | struct crystalcove_gpio *cg = to_cg(chip); | 132 | struct crystalcove_gpio *cg = to_cg(chip); |
132 | 133 | ||
134 | if (gpio > CRYSTALCOVE_VGPIO_NUM) | ||
135 | return 0; | ||
136 | |||
133 | return regmap_write(cg->regmap, to_reg(gpio, CTRL_OUT), | 137 | return regmap_write(cg->regmap, to_reg(gpio, CTRL_OUT), |
134 | CTLO_INPUT_SET); | 138 | CTLO_INPUT_SET); |
135 | } | 139 | } |
@@ -139,6 +143,9 @@ static int crystalcove_gpio_dir_out(struct gpio_chip *chip, unsigned gpio, | |||
139 | { | 143 | { |
140 | struct crystalcove_gpio *cg = to_cg(chip); | 144 | struct crystalcove_gpio *cg = to_cg(chip); |
141 | 145 | ||
146 | if (gpio > CRYSTALCOVE_VGPIO_NUM) | ||
147 | return 0; | ||
148 | |||
142 | return regmap_write(cg->regmap, to_reg(gpio, CTRL_OUT), | 149 | return regmap_write(cg->regmap, to_reg(gpio, CTRL_OUT), |
143 | CTLO_OUTPUT_SET | value); | 150 | CTLO_OUTPUT_SET | value); |
144 | } | 151 | } |
@@ -149,6 +156,9 @@ static int crystalcove_gpio_get(struct gpio_chip *chip, unsigned gpio) | |||
149 | int ret; | 156 | int ret; |
150 | unsigned int val; | 157 | unsigned int val; |
151 | 158 | ||
159 | if (gpio > CRYSTALCOVE_VGPIO_NUM) | ||
160 | return 0; | ||
161 | |||
152 | ret = regmap_read(cg->regmap, to_reg(gpio, CTRL_IN), &val); | 162 | ret = regmap_read(cg->regmap, to_reg(gpio, CTRL_IN), &val); |
153 | if (ret) | 163 | if (ret) |
154 | return ret; | 164 | return ret; |
@@ -161,6 +171,9 @@ static void crystalcove_gpio_set(struct gpio_chip *chip, | |||
161 | { | 171 | { |
162 | struct crystalcove_gpio *cg = to_cg(chip); | 172 | struct crystalcove_gpio *cg = to_cg(chip); |
163 | 173 | ||
174 | if (gpio > CRYSTALCOVE_VGPIO_NUM) | ||
175 | return; | ||
176 | |||
164 | if (value) | 177 | if (value) |
165 | regmap_update_bits(cg->regmap, to_reg(gpio, CTRL_OUT), 1, 1); | 178 | regmap_update_bits(cg->regmap, to_reg(gpio, CTRL_OUT), 1, 1); |
166 | else | 179 | else |
@@ -256,7 +269,7 @@ static irqreturn_t crystalcove_gpio_irq_handler(int irq, void *data) | |||
256 | 269 | ||
257 | pending = p0 | p1 << 8; | 270 | pending = p0 | p1 << 8; |
258 | 271 | ||
259 | for (gpio = 0; gpio < cg->chip.ngpio; gpio++) { | 272 | for (gpio = 0; gpio < CRYSTALCOVE_GPIO_NUM; gpio++) { |
260 | if (pending & BIT(gpio)) { | 273 | if (pending & BIT(gpio)) { |
261 | virq = irq_find_mapping(cg->chip.irqdomain, gpio); | 274 | virq = irq_find_mapping(cg->chip.irqdomain, gpio); |
262 | generic_handle_irq(virq); | 275 | generic_handle_irq(virq); |
@@ -273,7 +286,7 @@ static void crystalcove_gpio_dbg_show(struct seq_file *s, | |||
273 | int gpio, offset; | 286 | int gpio, offset; |
274 | unsigned int ctlo, ctli, mirqs0, mirqsx, irq; | 287 | unsigned int ctlo, ctli, mirqs0, mirqsx, irq; |
275 | 288 | ||
276 | for (gpio = 0; gpio < cg->chip.ngpio; gpio++) { | 289 | for (gpio = 0; gpio < CRYSTALCOVE_GPIO_NUM; gpio++) { |
277 | regmap_read(cg->regmap, to_reg(gpio, CTRL_OUT), &ctlo); | 290 | regmap_read(cg->regmap, to_reg(gpio, CTRL_OUT), &ctlo); |
278 | regmap_read(cg->regmap, to_reg(gpio, CTRL_IN), &ctli); | 291 | regmap_read(cg->regmap, to_reg(gpio, CTRL_IN), &ctli); |
279 | regmap_read(cg->regmap, gpio < 8 ? MGPIO0IRQS0 : MGPIO1IRQS0, | 292 | regmap_read(cg->regmap, gpio < 8 ? MGPIO0IRQS0 : MGPIO1IRQS0, |
@@ -320,7 +333,7 @@ static int crystalcove_gpio_probe(struct platform_device *pdev) | |||
320 | cg->chip.get = crystalcove_gpio_get; | 333 | cg->chip.get = crystalcove_gpio_get; |
321 | cg->chip.set = crystalcove_gpio_set; | 334 | cg->chip.set = crystalcove_gpio_set; |
322 | cg->chip.base = -1; | 335 | cg->chip.base = -1; |
323 | cg->chip.ngpio = CRYSTALCOVE_GPIO_NUM; | 336 | cg->chip.ngpio = CRYSTALCOVE_VGPIO_NUM; |
324 | cg->chip.can_sleep = true; | 337 | cg->chip.can_sleep = true; |
325 | cg->chip.dev = dev; | 338 | cg->chip.dev = dev; |
326 | cg->chip.dbg_show = crystalcove_gpio_dbg_show; | 339 | cg->chip.dbg_show = crystalcove_gpio_dbg_show; |
@@ -346,7 +359,7 @@ static int crystalcove_gpio_probe(struct platform_device *pdev) | |||
346 | return 0; | 359 | return 0; |
347 | 360 | ||
348 | out_remove_gpio: | 361 | out_remove_gpio: |
349 | WARN_ON(gpiochip_remove(&cg->chip)); | 362 | gpiochip_remove(&cg->chip); |
350 | return retval; | 363 | return retval; |
351 | } | 364 | } |
352 | 365 | ||
@@ -354,14 +367,11 @@ static int crystalcove_gpio_remove(struct platform_device *pdev) | |||
354 | { | 367 | { |
355 | struct crystalcove_gpio *cg = platform_get_drvdata(pdev); | 368 | struct crystalcove_gpio *cg = platform_get_drvdata(pdev); |
356 | int irq = platform_get_irq(pdev, 0); | 369 | int irq = platform_get_irq(pdev, 0); |
357 | int err; | ||
358 | |||
359 | err = gpiochip_remove(&cg->chip); | ||
360 | 370 | ||
371 | gpiochip_remove(&cg->chip); | ||
361 | if (irq >= 0) | 372 | if (irq >= 0) |
362 | free_irq(irq, cg); | 373 | free_irq(irq, cg); |
363 | 374 | return 0; | |
364 | return err; | ||
365 | } | 375 | } |
366 | 376 | ||
367 | static struct platform_driver crystalcove_gpio_driver = { | 377 | static struct platform_driver crystalcove_gpio_driver = { |
diff --git a/drivers/gpio/gpio-cs5535.c b/drivers/gpio/gpio-cs5535.c index 92ec58fa9236..668127fe90ef 100644 --- a/drivers/gpio/gpio-cs5535.c +++ b/drivers/gpio/gpio-cs5535.c | |||
@@ -201,7 +201,8 @@ EXPORT_SYMBOL_GPL(cs5535_gpio_setup_event); | |||
201 | 201 | ||
202 | static int chip_gpio_request(struct gpio_chip *c, unsigned offset) | 202 | static int chip_gpio_request(struct gpio_chip *c, unsigned offset) |
203 | { | 203 | { |
204 | struct cs5535_gpio_chip *chip = (struct cs5535_gpio_chip *) c; | 204 | struct cs5535_gpio_chip *chip = |
205 | container_of(c, struct cs5535_gpio_chip, chip); | ||
205 | unsigned long flags; | 206 | unsigned long flags; |
206 | 207 | ||
207 | spin_lock_irqsave(&chip->lock, flags); | 208 | spin_lock_irqsave(&chip->lock, flags); |
@@ -241,7 +242,8 @@ static void chip_gpio_set(struct gpio_chip *chip, unsigned offset, int val) | |||
241 | 242 | ||
242 | static int chip_direction_input(struct gpio_chip *c, unsigned offset) | 243 | static int chip_direction_input(struct gpio_chip *c, unsigned offset) |
243 | { | 244 | { |
244 | struct cs5535_gpio_chip *chip = (struct cs5535_gpio_chip *) c; | 245 | struct cs5535_gpio_chip *chip = |
246 | container_of(c, struct cs5535_gpio_chip, chip); | ||
245 | unsigned long flags; | 247 | unsigned long flags; |
246 | 248 | ||
247 | spin_lock_irqsave(&chip->lock, flags); | 249 | spin_lock_irqsave(&chip->lock, flags); |
@@ -254,7 +256,8 @@ static int chip_direction_input(struct gpio_chip *c, unsigned offset) | |||
254 | 256 | ||
255 | static int chip_direction_output(struct gpio_chip *c, unsigned offset, int val) | 257 | static int chip_direction_output(struct gpio_chip *c, unsigned offset, int val) |
256 | { | 258 | { |
257 | struct cs5535_gpio_chip *chip = (struct cs5535_gpio_chip *) c; | 259 | struct cs5535_gpio_chip *chip = |
260 | container_of(c, struct cs5535_gpio_chip, chip); | ||
258 | unsigned long flags; | 261 | unsigned long flags; |
259 | 262 | ||
260 | spin_lock_irqsave(&chip->lock, flags); | 263 | spin_lock_irqsave(&chip->lock, flags); |
diff --git a/drivers/gpio/gpio-dwapb.c b/drivers/gpio/gpio-dwapb.c index d6618a6e2399..b43cd84b61f1 100644 --- a/drivers/gpio/gpio-dwapb.c +++ b/drivers/gpio/gpio-dwapb.c | |||
@@ -21,6 +21,8 @@ | |||
21 | #include <linux/of_irq.h> | 21 | #include <linux/of_irq.h> |
22 | #include <linux/platform_device.h> | 22 | #include <linux/platform_device.h> |
23 | #include <linux/spinlock.h> | 23 | #include <linux/spinlock.h> |
24 | #include <linux/platform_data/gpio-dwapb.h> | ||
25 | #include <linux/slab.h> | ||
24 | 26 | ||
25 | #define GPIO_SWPORTA_DR 0x00 | 27 | #define GPIO_SWPORTA_DR 0x00 |
26 | #define GPIO_SWPORTA_DDR 0x04 | 28 | #define GPIO_SWPORTA_DDR 0x04 |
@@ -35,6 +37,7 @@ | |||
35 | #define GPIO_INTTYPE_LEVEL 0x38 | 37 | #define GPIO_INTTYPE_LEVEL 0x38 |
36 | #define GPIO_INT_POLARITY 0x3c | 38 | #define GPIO_INT_POLARITY 0x3c |
37 | #define GPIO_INTSTATUS 0x40 | 39 | #define GPIO_INTSTATUS 0x40 |
40 | #define GPIO_PORTA_DEBOUNCE 0x48 | ||
38 | #define GPIO_PORTA_EOI 0x4c | 41 | #define GPIO_PORTA_EOI 0x4c |
39 | #define GPIO_EXT_PORTA 0x50 | 42 | #define GPIO_EXT_PORTA 0x50 |
40 | #define GPIO_EXT_PORTB 0x54 | 43 | #define GPIO_EXT_PORTB 0x54 |
@@ -48,10 +51,28 @@ | |||
48 | 51 | ||
49 | struct dwapb_gpio; | 52 | struct dwapb_gpio; |
50 | 53 | ||
54 | #ifdef CONFIG_PM_SLEEP | ||
55 | /* Store GPIO context across system-wide suspend/resume transitions */ | ||
56 | struct dwapb_context { | ||
57 | u32 data; | ||
58 | u32 dir; | ||
59 | u32 ext; | ||
60 | u32 int_en; | ||
61 | u32 int_mask; | ||
62 | u32 int_type; | ||
63 | u32 int_pol; | ||
64 | u32 int_deb; | ||
65 | }; | ||
66 | #endif | ||
67 | |||
51 | struct dwapb_gpio_port { | 68 | struct dwapb_gpio_port { |
52 | struct bgpio_chip bgc; | 69 | struct bgpio_chip bgc; |
53 | bool is_registered; | 70 | bool is_registered; |
54 | struct dwapb_gpio *gpio; | 71 | struct dwapb_gpio *gpio; |
72 | #ifdef CONFIG_PM_SLEEP | ||
73 | struct dwapb_context *ctx; | ||
74 | #endif | ||
75 | unsigned int idx; | ||
55 | }; | 76 | }; |
56 | 77 | ||
57 | struct dwapb_gpio { | 78 | struct dwapb_gpio { |
@@ -62,11 +83,33 @@ struct dwapb_gpio { | |||
62 | struct irq_domain *domain; | 83 | struct irq_domain *domain; |
63 | }; | 84 | }; |
64 | 85 | ||
86 | static inline struct dwapb_gpio_port * | ||
87 | to_dwapb_gpio_port(struct bgpio_chip *bgc) | ||
88 | { | ||
89 | return container_of(bgc, struct dwapb_gpio_port, bgc); | ||
90 | } | ||
91 | |||
92 | static inline u32 dwapb_read(struct dwapb_gpio *gpio, unsigned int offset) | ||
93 | { | ||
94 | struct bgpio_chip *bgc = &gpio->ports[0].bgc; | ||
95 | void __iomem *reg_base = gpio->regs; | ||
96 | |||
97 | return bgc->read_reg(reg_base + offset); | ||
98 | } | ||
99 | |||
100 | static inline void dwapb_write(struct dwapb_gpio *gpio, unsigned int offset, | ||
101 | u32 val) | ||
102 | { | ||
103 | struct bgpio_chip *bgc = &gpio->ports[0].bgc; | ||
104 | void __iomem *reg_base = gpio->regs; | ||
105 | |||
106 | bgc->write_reg(reg_base + offset, val); | ||
107 | } | ||
108 | |||
65 | static int dwapb_gpio_to_irq(struct gpio_chip *gc, unsigned offset) | 109 | static int dwapb_gpio_to_irq(struct gpio_chip *gc, unsigned offset) |
66 | { | 110 | { |
67 | struct bgpio_chip *bgc = to_bgpio_chip(gc); | 111 | struct bgpio_chip *bgc = to_bgpio_chip(gc); |
68 | struct dwapb_gpio_port *port = container_of(bgc, struct | 112 | struct dwapb_gpio_port *port = to_dwapb_gpio_port(bgc); |
69 | dwapb_gpio_port, bgc); | ||
70 | struct dwapb_gpio *gpio = port->gpio; | 113 | struct dwapb_gpio *gpio = port->gpio; |
71 | 114 | ||
72 | return irq_find_mapping(gpio->domain, offset); | 115 | return irq_find_mapping(gpio->domain, offset); |
@@ -74,21 +117,20 @@ static int dwapb_gpio_to_irq(struct gpio_chip *gc, unsigned offset) | |||
74 | 117 | ||
75 | static void dwapb_toggle_trigger(struct dwapb_gpio *gpio, unsigned int offs) | 118 | static void dwapb_toggle_trigger(struct dwapb_gpio *gpio, unsigned int offs) |
76 | { | 119 | { |
77 | u32 v = readl(gpio->regs + GPIO_INT_POLARITY); | 120 | u32 v = dwapb_read(gpio, GPIO_INT_POLARITY); |
78 | 121 | ||
79 | if (gpio_get_value(gpio->ports[0].bgc.gc.base + offs)) | 122 | if (gpio_get_value(gpio->ports[0].bgc.gc.base + offs)) |
80 | v &= ~BIT(offs); | 123 | v &= ~BIT(offs); |
81 | else | 124 | else |
82 | v |= BIT(offs); | 125 | v |= BIT(offs); |
83 | 126 | ||
84 | writel(v, gpio->regs + GPIO_INT_POLARITY); | 127 | dwapb_write(gpio, GPIO_INT_POLARITY, v); |
85 | } | 128 | } |
86 | 129 | ||
87 | static void dwapb_irq_handler(u32 irq, struct irq_desc *desc) | 130 | static u32 dwapb_do_irq(struct dwapb_gpio *gpio) |
88 | { | 131 | { |
89 | struct dwapb_gpio *gpio = irq_get_handler_data(irq); | ||
90 | struct irq_chip *chip = irq_desc_get_chip(desc); | ||
91 | u32 irq_status = readl_relaxed(gpio->regs + GPIO_INTSTATUS); | 132 | u32 irq_status = readl_relaxed(gpio->regs + GPIO_INTSTATUS); |
133 | u32 ret = irq_status; | ||
92 | 134 | ||
93 | while (irq_status) { | 135 | while (irq_status) { |
94 | int hwirq = fls(irq_status) - 1; | 136 | int hwirq = fls(irq_status) - 1; |
@@ -102,6 +144,16 @@ static void dwapb_irq_handler(u32 irq, struct irq_desc *desc) | |||
102 | dwapb_toggle_trigger(gpio, hwirq); | 144 | dwapb_toggle_trigger(gpio, hwirq); |
103 | } | 145 | } |
104 | 146 | ||
147 | return ret; | ||
148 | } | ||
149 | |||
150 | static void dwapb_irq_handler(u32 irq, struct irq_desc *desc) | ||
151 | { | ||
152 | struct dwapb_gpio *gpio = irq_get_handler_data(irq); | ||
153 | struct irq_chip *chip = irq_desc_get_chip(desc); | ||
154 | |||
155 | dwapb_do_irq(gpio); | ||
156 | |||
105 | if (chip->irq_eoi) | 157 | if (chip->irq_eoi) |
106 | chip->irq_eoi(irq_desc_get_irq_data(desc)); | 158 | chip->irq_eoi(irq_desc_get_irq_data(desc)); |
107 | } | 159 | } |
@@ -115,9 +167,9 @@ static void dwapb_irq_enable(struct irq_data *d) | |||
115 | u32 val; | 167 | u32 val; |
116 | 168 | ||
117 | spin_lock_irqsave(&bgc->lock, flags); | 169 | spin_lock_irqsave(&bgc->lock, flags); |
118 | val = readl(gpio->regs + GPIO_INTEN); | 170 | val = dwapb_read(gpio, GPIO_INTEN); |
119 | val |= BIT(d->hwirq); | 171 | val |= BIT(d->hwirq); |
120 | writel(val, gpio->regs + GPIO_INTEN); | 172 | dwapb_write(gpio, GPIO_INTEN, val); |
121 | spin_unlock_irqrestore(&bgc->lock, flags); | 173 | spin_unlock_irqrestore(&bgc->lock, flags); |
122 | } | 174 | } |
123 | 175 | ||
@@ -130,9 +182,9 @@ static void dwapb_irq_disable(struct irq_data *d) | |||
130 | u32 val; | 182 | u32 val; |
131 | 183 | ||
132 | spin_lock_irqsave(&bgc->lock, flags); | 184 | spin_lock_irqsave(&bgc->lock, flags); |
133 | val = readl(gpio->regs + GPIO_INTEN); | 185 | val = dwapb_read(gpio, GPIO_INTEN); |
134 | val &= ~BIT(d->hwirq); | 186 | val &= ~BIT(d->hwirq); |
135 | writel(val, gpio->regs + GPIO_INTEN); | 187 | dwapb_write(gpio, GPIO_INTEN, val); |
136 | spin_unlock_irqrestore(&bgc->lock, flags); | 188 | spin_unlock_irqrestore(&bgc->lock, flags); |
137 | } | 189 | } |
138 | 190 | ||
@@ -172,8 +224,8 @@ static int dwapb_irq_set_type(struct irq_data *d, u32 type) | |||
172 | return -EINVAL; | 224 | return -EINVAL; |
173 | 225 | ||
174 | spin_lock_irqsave(&bgc->lock, flags); | 226 | spin_lock_irqsave(&bgc->lock, flags); |
175 | level = readl(gpio->regs + GPIO_INTTYPE_LEVEL); | 227 | level = dwapb_read(gpio, GPIO_INTTYPE_LEVEL); |
176 | polarity = readl(gpio->regs + GPIO_INT_POLARITY); | 228 | polarity = dwapb_read(gpio, GPIO_INT_POLARITY); |
177 | 229 | ||
178 | switch (type) { | 230 | switch (type) { |
179 | case IRQ_TYPE_EDGE_BOTH: | 231 | case IRQ_TYPE_EDGE_BOTH: |
@@ -200,29 +252,55 @@ static int dwapb_irq_set_type(struct irq_data *d, u32 type) | |||
200 | 252 | ||
201 | irq_setup_alt_chip(d, type); | 253 | irq_setup_alt_chip(d, type); |
202 | 254 | ||
203 | writel(level, gpio->regs + GPIO_INTTYPE_LEVEL); | 255 | dwapb_write(gpio, GPIO_INTTYPE_LEVEL, level); |
204 | writel(polarity, gpio->regs + GPIO_INT_POLARITY); | 256 | dwapb_write(gpio, GPIO_INT_POLARITY, polarity); |
257 | spin_unlock_irqrestore(&bgc->lock, flags); | ||
258 | |||
259 | return 0; | ||
260 | } | ||
261 | |||
262 | static int dwapb_gpio_set_debounce(struct gpio_chip *gc, | ||
263 | unsigned offset, unsigned debounce) | ||
264 | { | ||
265 | struct bgpio_chip *bgc = to_bgpio_chip(gc); | ||
266 | struct dwapb_gpio_port *port = to_dwapb_gpio_port(bgc); | ||
267 | struct dwapb_gpio *gpio = port->gpio; | ||
268 | unsigned long flags, val_deb; | ||
269 | unsigned long mask = bgc->pin2mask(bgc, offset); | ||
270 | |||
271 | spin_lock_irqsave(&bgc->lock, flags); | ||
272 | |||
273 | val_deb = dwapb_read(gpio, GPIO_PORTA_DEBOUNCE); | ||
274 | if (debounce) | ||
275 | dwapb_write(gpio, GPIO_PORTA_DEBOUNCE, val_deb | mask); | ||
276 | else | ||
277 | dwapb_write(gpio, GPIO_PORTA_DEBOUNCE, val_deb & ~mask); | ||
278 | |||
205 | spin_unlock_irqrestore(&bgc->lock, flags); | 279 | spin_unlock_irqrestore(&bgc->lock, flags); |
206 | 280 | ||
207 | return 0; | 281 | return 0; |
208 | } | 282 | } |
209 | 283 | ||
284 | static irqreturn_t dwapb_irq_handler_mfd(int irq, void *dev_id) | ||
285 | { | ||
286 | u32 worked; | ||
287 | struct dwapb_gpio *gpio = dev_id; | ||
288 | |||
289 | worked = dwapb_do_irq(gpio); | ||
290 | |||
291 | return worked ? IRQ_HANDLED : IRQ_NONE; | ||
292 | } | ||
293 | |||
210 | static void dwapb_configure_irqs(struct dwapb_gpio *gpio, | 294 | static void dwapb_configure_irqs(struct dwapb_gpio *gpio, |
211 | struct dwapb_gpio_port *port) | 295 | struct dwapb_gpio_port *port, |
296 | struct dwapb_port_property *pp) | ||
212 | { | 297 | { |
213 | struct gpio_chip *gc = &port->bgc.gc; | 298 | struct gpio_chip *gc = &port->bgc.gc; |
214 | struct device_node *node = gc->of_node; | 299 | struct device_node *node = pp->node; |
215 | struct irq_chip_generic *irq_gc; | 300 | struct irq_chip_generic *irq_gc = NULL; |
216 | unsigned int hwirq, ngpio = gc->ngpio; | 301 | unsigned int hwirq, ngpio = gc->ngpio; |
217 | struct irq_chip_type *ct; | 302 | struct irq_chip_type *ct; |
218 | int err, irq, i; | 303 | int err, i; |
219 | |||
220 | irq = irq_of_parse_and_map(node, 0); | ||
221 | if (!irq) { | ||
222 | dev_warn(gpio->dev, "no irq for bank %s\n", | ||
223 | port->bgc.gc.of_node->full_name); | ||
224 | return; | ||
225 | } | ||
226 | 304 | ||
227 | gpio->domain = irq_domain_add_linear(node, ngpio, | 305 | gpio->domain = irq_domain_add_linear(node, ngpio, |
228 | &irq_generic_chip_ops, gpio); | 306 | &irq_generic_chip_ops, gpio); |
@@ -269,8 +347,24 @@ static void dwapb_configure_irqs(struct dwapb_gpio *gpio, | |||
269 | irq_gc->chip_types[1].type = IRQ_TYPE_EDGE_BOTH; | 347 | irq_gc->chip_types[1].type = IRQ_TYPE_EDGE_BOTH; |
270 | irq_gc->chip_types[1].handler = handle_edge_irq; | 348 | irq_gc->chip_types[1].handler = handle_edge_irq; |
271 | 349 | ||
272 | irq_set_chained_handler(irq, dwapb_irq_handler); | 350 | if (!pp->irq_shared) { |
273 | irq_set_handler_data(irq, gpio); | 351 | irq_set_chained_handler(pp->irq, dwapb_irq_handler); |
352 | irq_set_handler_data(pp->irq, gpio); | ||
353 | } else { | ||
354 | /* | ||
355 | * Request a shared IRQ since where MFD would have devices | ||
356 | * using the same irq pin | ||
357 | */ | ||
358 | err = devm_request_irq(gpio->dev, pp->irq, | ||
359 | dwapb_irq_handler_mfd, | ||
360 | IRQF_SHARED, "gpio-dwapb-mfd", gpio); | ||
361 | if (err) { | ||
362 | dev_err(gpio->dev, "error requesting IRQ\n"); | ||
363 | irq_domain_remove(gpio->domain); | ||
364 | gpio->domain = NULL; | ||
365 | return; | ||
366 | } | ||
367 | } | ||
274 | 368 | ||
275 | for (hwirq = 0 ; hwirq < ngpio ; hwirq++) | 369 | for (hwirq = 0 ; hwirq < ngpio ; hwirq++) |
276 | irq_create_mapping(gpio->domain, hwirq); | 370 | irq_create_mapping(gpio->domain, hwirq); |
@@ -296,57 +390,53 @@ static void dwapb_irq_teardown(struct dwapb_gpio *gpio) | |||
296 | } | 390 | } |
297 | 391 | ||
298 | static int dwapb_gpio_add_port(struct dwapb_gpio *gpio, | 392 | static int dwapb_gpio_add_port(struct dwapb_gpio *gpio, |
299 | struct device_node *port_np, | 393 | struct dwapb_port_property *pp, |
300 | unsigned int offs) | 394 | unsigned int offs) |
301 | { | 395 | { |
302 | struct dwapb_gpio_port *port; | 396 | struct dwapb_gpio_port *port; |
303 | u32 port_idx, ngpio; | ||
304 | void __iomem *dat, *set, *dirout; | 397 | void __iomem *dat, *set, *dirout; |
305 | int err; | 398 | int err; |
306 | 399 | ||
307 | if (of_property_read_u32(port_np, "reg", &port_idx) || | ||
308 | port_idx >= DWAPB_MAX_PORTS) { | ||
309 | dev_err(gpio->dev, "missing/invalid port index for %s\n", | ||
310 | port_np->full_name); | ||
311 | return -EINVAL; | ||
312 | } | ||
313 | |||
314 | port = &gpio->ports[offs]; | 400 | port = &gpio->ports[offs]; |
315 | port->gpio = gpio; | 401 | port->gpio = gpio; |
402 | port->idx = pp->idx; | ||
316 | 403 | ||
317 | if (of_property_read_u32(port_np, "snps,nr-gpios", &ngpio)) { | 404 | #ifdef CONFIG_PM_SLEEP |
318 | dev_info(gpio->dev, "failed to get number of gpios for %s\n", | 405 | port->ctx = devm_kzalloc(gpio->dev, sizeof(*port->ctx), GFP_KERNEL); |
319 | port_np->full_name); | 406 | if (!port->ctx) |
320 | ngpio = 32; | 407 | return -ENOMEM; |
321 | } | 408 | #endif |
322 | 409 | ||
323 | dat = gpio->regs + GPIO_EXT_PORTA + (port_idx * GPIO_EXT_PORT_SIZE); | 410 | dat = gpio->regs + GPIO_EXT_PORTA + (pp->idx * GPIO_EXT_PORT_SIZE); |
324 | set = gpio->regs + GPIO_SWPORTA_DR + (port_idx * GPIO_SWPORT_DR_SIZE); | 411 | set = gpio->regs + GPIO_SWPORTA_DR + (pp->idx * GPIO_SWPORT_DR_SIZE); |
325 | dirout = gpio->regs + GPIO_SWPORTA_DDR + | 412 | dirout = gpio->regs + GPIO_SWPORTA_DDR + |
326 | (port_idx * GPIO_SWPORT_DDR_SIZE); | 413 | (pp->idx * GPIO_SWPORT_DDR_SIZE); |
327 | 414 | ||
328 | err = bgpio_init(&port->bgc, gpio->dev, 4, dat, set, NULL, dirout, | 415 | err = bgpio_init(&port->bgc, gpio->dev, 4, dat, set, NULL, dirout, |
329 | NULL, false); | 416 | NULL, false); |
330 | if (err) { | 417 | if (err) { |
331 | dev_err(gpio->dev, "failed to init gpio chip for %s\n", | 418 | dev_err(gpio->dev, "failed to init gpio chip for %s\n", |
332 | port_np->full_name); | 419 | pp->name); |
333 | return err; | 420 | return err; |
334 | } | 421 | } |
335 | 422 | ||
336 | port->bgc.gc.ngpio = ngpio; | 423 | #ifdef CONFIG_OF_GPIO |
337 | port->bgc.gc.of_node = port_np; | 424 | port->bgc.gc.of_node = pp->node; |
425 | #endif | ||
426 | port->bgc.gc.ngpio = pp->ngpio; | ||
427 | port->bgc.gc.base = pp->gpio_base; | ||
338 | 428 | ||
339 | /* | 429 | /* Only port A support debounce */ |
340 | * Only port A can provide interrupts in all configurations of the IP. | 430 | if (pp->idx == 0) |
341 | */ | 431 | port->bgc.gc.set_debounce = dwapb_gpio_set_debounce; |
342 | if (port_idx == 0 && | 432 | |
343 | of_property_read_bool(port_np, "interrupt-controller")) | 433 | if (pp->irq) |
344 | dwapb_configure_irqs(gpio, port); | 434 | dwapb_configure_irqs(gpio, port, pp); |
345 | 435 | ||
346 | err = gpiochip_add(&port->bgc.gc); | 436 | err = gpiochip_add(&port->bgc.gc); |
347 | if (err) | 437 | if (err) |
348 | dev_err(gpio->dev, "failed to register gpiochip for %s\n", | 438 | dev_err(gpio->dev, "failed to register gpiochip for %s\n", |
349 | port_np->full_name); | 439 | pp->name); |
350 | else | 440 | else |
351 | port->is_registered = true; | 441 | port->is_registered = true; |
352 | 442 | ||
@@ -362,25 +452,116 @@ static void dwapb_gpio_unregister(struct dwapb_gpio *gpio) | |||
362 | gpiochip_remove(&gpio->ports[m].bgc.gc); | 452 | gpiochip_remove(&gpio->ports[m].bgc.gc); |
363 | } | 453 | } |
364 | 454 | ||
455 | static struct dwapb_platform_data * | ||
456 | dwapb_gpio_get_pdata_of(struct device *dev) | ||
457 | { | ||
458 | struct device_node *node, *port_np; | ||
459 | struct dwapb_platform_data *pdata; | ||
460 | struct dwapb_port_property *pp; | ||
461 | int nports; | ||
462 | int i; | ||
463 | |||
464 | node = dev->of_node; | ||
465 | if (!IS_ENABLED(CONFIG_OF_GPIO) || !node) | ||
466 | return ERR_PTR(-ENODEV); | ||
467 | |||
468 | nports = of_get_child_count(node); | ||
469 | if (nports == 0) | ||
470 | return ERR_PTR(-ENODEV); | ||
471 | |||
472 | pdata = kzalloc(sizeof(*pdata), GFP_KERNEL); | ||
473 | if (!pdata) | ||
474 | return ERR_PTR(-ENOMEM); | ||
475 | |||
476 | pdata->properties = kcalloc(nports, sizeof(*pp), GFP_KERNEL); | ||
477 | if (!pdata->properties) { | ||
478 | kfree(pdata); | ||
479 | return ERR_PTR(-ENOMEM); | ||
480 | } | ||
481 | |||
482 | pdata->nports = nports; | ||
483 | |||
484 | i = 0; | ||
485 | for_each_child_of_node(node, port_np) { | ||
486 | pp = &pdata->properties[i++]; | ||
487 | pp->node = port_np; | ||
488 | |||
489 | if (of_property_read_u32(port_np, "reg", &pp->idx) || | ||
490 | pp->idx >= DWAPB_MAX_PORTS) { | ||
491 | dev_err(dev, "missing/invalid port index for %s\n", | ||
492 | port_np->full_name); | ||
493 | kfree(pdata->properties); | ||
494 | kfree(pdata); | ||
495 | return ERR_PTR(-EINVAL); | ||
496 | } | ||
497 | |||
498 | if (of_property_read_u32(port_np, "snps,nr-gpios", | ||
499 | &pp->ngpio)) { | ||
500 | dev_info(dev, "failed to get number of gpios for %s\n", | ||
501 | port_np->full_name); | ||
502 | pp->ngpio = 32; | ||
503 | } | ||
504 | |||
505 | /* | ||
506 | * Only port A can provide interrupts in all configurations of | ||
507 | * the IP. | ||
508 | */ | ||
509 | if (pp->idx == 0 && | ||
510 | of_property_read_bool(port_np, "interrupt-controller")) { | ||
511 | pp->irq = irq_of_parse_and_map(port_np, 0); | ||
512 | if (!pp->irq) { | ||
513 | dev_warn(dev, "no irq for bank %s\n", | ||
514 | port_np->full_name); | ||
515 | } | ||
516 | } | ||
517 | |||
518 | pp->irq_shared = false; | ||
519 | pp->gpio_base = -1; | ||
520 | pp->name = port_np->full_name; | ||
521 | } | ||
522 | |||
523 | return pdata; | ||
524 | } | ||
525 | |||
526 | static inline void dwapb_free_pdata_of(struct dwapb_platform_data *pdata) | ||
527 | { | ||
528 | if (!IS_ENABLED(CONFIG_OF_GPIO) || !pdata) | ||
529 | return; | ||
530 | |||
531 | kfree(pdata->properties); | ||
532 | kfree(pdata); | ||
533 | } | ||
534 | |||
365 | static int dwapb_gpio_probe(struct platform_device *pdev) | 535 | static int dwapb_gpio_probe(struct platform_device *pdev) |
366 | { | 536 | { |
537 | unsigned int i; | ||
367 | struct resource *res; | 538 | struct resource *res; |
368 | struct dwapb_gpio *gpio; | 539 | struct dwapb_gpio *gpio; |
369 | struct device_node *np; | ||
370 | int err; | 540 | int err; |
371 | unsigned int offs = 0; | 541 | struct device *dev = &pdev->dev; |
542 | struct dwapb_platform_data *pdata = dev_get_platdata(dev); | ||
543 | bool is_pdata_alloc = !pdata; | ||
544 | |||
545 | if (is_pdata_alloc) { | ||
546 | pdata = dwapb_gpio_get_pdata_of(dev); | ||
547 | if (IS_ERR(pdata)) | ||
548 | return PTR_ERR(pdata); | ||
549 | } | ||
372 | 550 | ||
373 | gpio = devm_kzalloc(&pdev->dev, sizeof(*gpio), GFP_KERNEL); | 551 | if (!pdata->nports) { |
374 | if (!gpio) | 552 | err = -ENODEV; |
375 | return -ENOMEM; | 553 | goto out_err; |
376 | gpio->dev = &pdev->dev; | 554 | } |
377 | 555 | ||
378 | gpio->nr_ports = of_get_child_count(pdev->dev.of_node); | 556 | gpio = devm_kzalloc(&pdev->dev, sizeof(*gpio), GFP_KERNEL); |
379 | if (!gpio->nr_ports) { | 557 | if (!gpio) { |
380 | err = -EINVAL; | 558 | err = -ENOMEM; |
381 | goto out_err; | 559 | goto out_err; |
382 | } | 560 | } |
383 | gpio->ports = devm_kzalloc(&pdev->dev, gpio->nr_ports * | 561 | gpio->dev = &pdev->dev; |
562 | gpio->nr_ports = pdata->nports; | ||
563 | |||
564 | gpio->ports = devm_kcalloc(&pdev->dev, gpio->nr_ports, | ||
384 | sizeof(*gpio->ports), GFP_KERNEL); | 565 | sizeof(*gpio->ports), GFP_KERNEL); |
385 | if (!gpio->ports) { | 566 | if (!gpio->ports) { |
386 | err = -ENOMEM; | 567 | err = -ENOMEM; |
@@ -394,20 +575,23 @@ static int dwapb_gpio_probe(struct platform_device *pdev) | |||
394 | goto out_err; | 575 | goto out_err; |
395 | } | 576 | } |
396 | 577 | ||
397 | for_each_child_of_node(pdev->dev.of_node, np) { | 578 | for (i = 0; i < gpio->nr_ports; i++) { |
398 | err = dwapb_gpio_add_port(gpio, np, offs++); | 579 | err = dwapb_gpio_add_port(gpio, &pdata->properties[i], i); |
399 | if (err) | 580 | if (err) |
400 | goto out_unregister; | 581 | goto out_unregister; |
401 | } | 582 | } |
402 | platform_set_drvdata(pdev, gpio); | 583 | platform_set_drvdata(pdev, gpio); |
403 | 584 | ||
404 | return 0; | 585 | goto out_err; |
405 | 586 | ||
406 | out_unregister: | 587 | out_unregister: |
407 | dwapb_gpio_unregister(gpio); | 588 | dwapb_gpio_unregister(gpio); |
408 | dwapb_irq_teardown(gpio); | 589 | dwapb_irq_teardown(gpio); |
409 | 590 | ||
410 | out_err: | 591 | out_err: |
592 | if (is_pdata_alloc) | ||
593 | dwapb_free_pdata_of(pdata); | ||
594 | |||
411 | return err; | 595 | return err; |
412 | } | 596 | } |
413 | 597 | ||
@@ -427,10 +611,100 @@ static const struct of_device_id dwapb_of_match[] = { | |||
427 | }; | 611 | }; |
428 | MODULE_DEVICE_TABLE(of, dwapb_of_match); | 612 | MODULE_DEVICE_TABLE(of, dwapb_of_match); |
429 | 613 | ||
614 | #ifdef CONFIG_PM_SLEEP | ||
615 | static int dwapb_gpio_suspend(struct device *dev) | ||
616 | { | ||
617 | struct platform_device *pdev = to_platform_device(dev); | ||
618 | struct dwapb_gpio *gpio = platform_get_drvdata(pdev); | ||
619 | struct bgpio_chip *bgc = &gpio->ports[0].bgc; | ||
620 | unsigned long flags; | ||
621 | int i; | ||
622 | |||
623 | spin_lock_irqsave(&bgc->lock, flags); | ||
624 | for (i = 0; i < gpio->nr_ports; i++) { | ||
625 | unsigned int offset; | ||
626 | unsigned int idx = gpio->ports[i].idx; | ||
627 | struct dwapb_context *ctx = gpio->ports[i].ctx; | ||
628 | |||
629 | BUG_ON(!ctx); | ||
630 | |||
631 | offset = GPIO_SWPORTA_DDR + idx * GPIO_SWPORT_DDR_SIZE; | ||
632 | ctx->dir = dwapb_read(gpio, offset); | ||
633 | |||
634 | offset = GPIO_SWPORTA_DR + idx * GPIO_SWPORT_DR_SIZE; | ||
635 | ctx->data = dwapb_read(gpio, offset); | ||
636 | |||
637 | offset = GPIO_EXT_PORTA + idx * GPIO_EXT_PORT_SIZE; | ||
638 | ctx->ext = dwapb_read(gpio, offset); | ||
639 | |||
640 | /* Only port A can provide interrupts */ | ||
641 | if (idx == 0) { | ||
642 | ctx->int_mask = dwapb_read(gpio, GPIO_INTMASK); | ||
643 | ctx->int_en = dwapb_read(gpio, GPIO_INTEN); | ||
644 | ctx->int_pol = dwapb_read(gpio, GPIO_INT_POLARITY); | ||
645 | ctx->int_type = dwapb_read(gpio, GPIO_INTTYPE_LEVEL); | ||
646 | ctx->int_deb = dwapb_read(gpio, GPIO_PORTA_DEBOUNCE); | ||
647 | |||
648 | /* Mask out interrupts */ | ||
649 | dwapb_write(gpio, GPIO_INTMASK, 0xffffffff); | ||
650 | } | ||
651 | } | ||
652 | spin_unlock_irqrestore(&bgc->lock, flags); | ||
653 | |||
654 | return 0; | ||
655 | } | ||
656 | |||
657 | static int dwapb_gpio_resume(struct device *dev) | ||
658 | { | ||
659 | struct platform_device *pdev = to_platform_device(dev); | ||
660 | struct dwapb_gpio *gpio = platform_get_drvdata(pdev); | ||
661 | struct bgpio_chip *bgc = &gpio->ports[0].bgc; | ||
662 | unsigned long flags; | ||
663 | int i; | ||
664 | |||
665 | spin_lock_irqsave(&bgc->lock, flags); | ||
666 | for (i = 0; i < gpio->nr_ports; i++) { | ||
667 | unsigned int offset; | ||
668 | unsigned int idx = gpio->ports[i].idx; | ||
669 | struct dwapb_context *ctx = gpio->ports[i].ctx; | ||
670 | |||
671 | BUG_ON(!ctx); | ||
672 | |||
673 | offset = GPIO_SWPORTA_DR + idx * GPIO_SWPORT_DR_SIZE; | ||
674 | dwapb_write(gpio, offset, ctx->data); | ||
675 | |||
676 | offset = GPIO_SWPORTA_DDR + idx * GPIO_SWPORT_DDR_SIZE; | ||
677 | dwapb_write(gpio, offset, ctx->dir); | ||
678 | |||
679 | offset = GPIO_EXT_PORTA + idx * GPIO_EXT_PORT_SIZE; | ||
680 | dwapb_write(gpio, offset, ctx->ext); | ||
681 | |||
682 | /* Only port A can provide interrupts */ | ||
683 | if (idx == 0) { | ||
684 | dwapb_write(gpio, GPIO_INTTYPE_LEVEL, ctx->int_type); | ||
685 | dwapb_write(gpio, GPIO_INT_POLARITY, ctx->int_pol); | ||
686 | dwapb_write(gpio, GPIO_PORTA_DEBOUNCE, ctx->int_deb); | ||
687 | dwapb_write(gpio, GPIO_INTEN, ctx->int_en); | ||
688 | dwapb_write(gpio, GPIO_INTMASK, ctx->int_mask); | ||
689 | |||
690 | /* Clear out spurious interrupts */ | ||
691 | dwapb_write(gpio, GPIO_PORTA_EOI, 0xffffffff); | ||
692 | } | ||
693 | } | ||
694 | spin_unlock_irqrestore(&bgc->lock, flags); | ||
695 | |||
696 | return 0; | ||
697 | } | ||
698 | #endif | ||
699 | |||
700 | static SIMPLE_DEV_PM_OPS(dwapb_gpio_pm_ops, dwapb_gpio_suspend, | ||
701 | dwapb_gpio_resume); | ||
702 | |||
430 | static struct platform_driver dwapb_gpio_driver = { | 703 | static struct platform_driver dwapb_gpio_driver = { |
431 | .driver = { | 704 | .driver = { |
432 | .name = "gpio-dwapb", | 705 | .name = "gpio-dwapb", |
433 | .owner = THIS_MODULE, | 706 | .owner = THIS_MODULE, |
707 | .pm = &dwapb_gpio_pm_ops, | ||
434 | .of_match_table = of_match_ptr(dwapb_of_match), | 708 | .of_match_table = of_match_ptr(dwapb_of_match), |
435 | }, | 709 | }, |
436 | .probe = dwapb_gpio_probe, | 710 | .probe = dwapb_gpio_probe, |
diff --git a/drivers/gpio/gpio-ks8695.c b/drivers/gpio/gpio-ks8695.c index 464a83de0d6a..cc09b237e88c 100644 --- a/drivers/gpio/gpio-ks8695.c +++ b/drivers/gpio/gpio-ks8695.c | |||
@@ -265,29 +265,27 @@ static int ks8695_gpio_show(struct seq_file *s, void *unused) | |||
265 | seq_printf(s, "EXT%i ", i); | 265 | seq_printf(s, "EXT%i ", i); |
266 | 266 | ||
267 | switch ((ctrl & intmask[i]) >> (4 * i)) { | 267 | switch ((ctrl & intmask[i]) >> (4 * i)) { |
268 | case IOPC_TM_LOW: | 268 | case IOPC_TM_LOW: |
269 | seq_printf(s, "(Low)"); break; | 269 | seq_printf(s, "(Low)"); break; |
270 | case IOPC_TM_HIGH: | 270 | case IOPC_TM_HIGH: |
271 | seq_printf(s, "(High)"); break; | 271 | seq_printf(s, "(High)"); break; |
272 | case IOPC_TM_RISING: | 272 | case IOPC_TM_RISING: |
273 | seq_printf(s, "(Rising)"); break; | 273 | seq_printf(s, "(Rising)"); break; |
274 | case IOPC_TM_FALLING: | 274 | case IOPC_TM_FALLING: |
275 | seq_printf(s, "(Falling)"); break; | 275 | seq_printf(s, "(Falling)"); break; |
276 | case IOPC_TM_EDGE: | 276 | case IOPC_TM_EDGE: |
277 | seq_printf(s, "(Edges)"); break; | 277 | seq_printf(s, "(Edges)"); break; |
278 | } | 278 | } |
279 | } | 279 | } else |
280 | else | ||
281 | seq_printf(s, "GPIO\t"); | 280 | seq_printf(s, "GPIO\t"); |
282 | } | 281 | } else if (i <= KS8695_GPIO_5) { |
283 | else if (i <= KS8695_GPIO_5) { | ||
284 | if (ctrl & enable[i]) | 282 | if (ctrl & enable[i]) |
285 | seq_printf(s, "TOUT%i\t", i - KS8695_GPIO_4); | 283 | seq_printf(s, "TOUT%i\t", i - KS8695_GPIO_4); |
286 | else | 284 | else |
287 | seq_printf(s, "GPIO\t"); | 285 | seq_printf(s, "GPIO\t"); |
288 | } | 286 | } else { |
289 | else | ||
290 | seq_printf(s, "GPIO\t"); | 287 | seq_printf(s, "GPIO\t"); |
288 | } | ||
291 | 289 | ||
292 | seq_printf(s, "\t"); | 290 | seq_printf(s, "\t"); |
293 | 291 | ||
diff --git a/drivers/gpio/gpio-mcp23s08.c b/drivers/gpio/gpio-mcp23s08.c index 6f183d9b487e..8488e2fd307c 100644 --- a/drivers/gpio/gpio-mcp23s08.c +++ b/drivers/gpio/gpio-mcp23s08.c | |||
@@ -479,7 +479,7 @@ static int mcp23s08_irq_setup(struct mcp23s08 *mcp) | |||
479 | 479 | ||
480 | mutex_init(&mcp->irq_lock); | 480 | mutex_init(&mcp->irq_lock); |
481 | 481 | ||
482 | mcp->irq_domain = irq_domain_add_linear(chip->of_node, chip->ngpio, | 482 | mcp->irq_domain = irq_domain_add_linear(chip->dev->of_node, chip->ngpio, |
483 | &irq_domain_simple_ops, mcp); | 483 | &irq_domain_simple_ops, mcp); |
484 | if (!mcp->irq_domain) | 484 | if (!mcp->irq_domain) |
485 | return -ENODEV; | 485 | return -ENODEV; |
@@ -581,7 +581,7 @@ done: | |||
581 | 581 | ||
582 | static int mcp23s08_probe_one(struct mcp23s08 *mcp, struct device *dev, | 582 | static int mcp23s08_probe_one(struct mcp23s08 *mcp, struct device *dev, |
583 | void *data, unsigned addr, unsigned type, | 583 | void *data, unsigned addr, unsigned type, |
584 | unsigned base, unsigned pullups) | 584 | struct mcp23s08_platform_data *pdata, int cs) |
585 | { | 585 | { |
586 | int status; | 586 | int status; |
587 | bool mirror = false; | 587 | bool mirror = false; |
@@ -635,7 +635,7 @@ static int mcp23s08_probe_one(struct mcp23s08 *mcp, struct device *dev, | |||
635 | return -EINVAL; | 635 | return -EINVAL; |
636 | } | 636 | } |
637 | 637 | ||
638 | mcp->chip.base = base; | 638 | mcp->chip.base = pdata->base; |
639 | mcp->chip.can_sleep = true; | 639 | mcp->chip.can_sleep = true; |
640 | mcp->chip.dev = dev; | 640 | mcp->chip.dev = dev; |
641 | mcp->chip.owner = THIS_MODULE; | 641 | mcp->chip.owner = THIS_MODULE; |
@@ -648,11 +648,9 @@ static int mcp23s08_probe_one(struct mcp23s08 *mcp, struct device *dev, | |||
648 | if (status < 0) | 648 | if (status < 0) |
649 | goto fail; | 649 | goto fail; |
650 | 650 | ||
651 | mcp->irq_controller = of_property_read_bool(mcp->chip.of_node, | 651 | mcp->irq_controller = pdata->irq_controller; |
652 | "interrupt-controller"); | ||
653 | if (mcp->irq && mcp->irq_controller && (type == MCP_TYPE_017)) | 652 | if (mcp->irq && mcp->irq_controller && (type == MCP_TYPE_017)) |
654 | mirror = of_property_read_bool(mcp->chip.of_node, | 653 | mirror = pdata->mirror; |
655 | "microchip,irq-mirror"); | ||
656 | 654 | ||
657 | if ((status & IOCON_SEQOP) || !(status & IOCON_HAEN) || mirror) { | 655 | if ((status & IOCON_SEQOP) || !(status & IOCON_HAEN) || mirror) { |
658 | /* mcp23s17 has IOCON twice, make sure they are in sync */ | 656 | /* mcp23s17 has IOCON twice, make sure they are in sync */ |
@@ -668,7 +666,7 @@ static int mcp23s08_probe_one(struct mcp23s08 *mcp, struct device *dev, | |||
668 | } | 666 | } |
669 | 667 | ||
670 | /* configure ~100K pullups */ | 668 | /* configure ~100K pullups */ |
671 | status = mcp->ops->write(mcp, MCP_GPPU, pullups); | 669 | status = mcp->ops->write(mcp, MCP_GPPU, pdata->chip[cs].pullups); |
672 | if (status < 0) | 670 | if (status < 0) |
673 | goto fail; | 671 | goto fail; |
674 | 672 | ||
@@ -768,25 +766,29 @@ MODULE_DEVICE_TABLE(of, mcp23s08_i2c_of_match); | |||
768 | static int mcp230xx_probe(struct i2c_client *client, | 766 | static int mcp230xx_probe(struct i2c_client *client, |
769 | const struct i2c_device_id *id) | 767 | const struct i2c_device_id *id) |
770 | { | 768 | { |
771 | struct mcp23s08_platform_data *pdata; | 769 | struct mcp23s08_platform_data *pdata, local_pdata; |
772 | struct mcp23s08 *mcp; | 770 | struct mcp23s08 *mcp; |
773 | int status, base, pullups; | 771 | int status; |
774 | const struct of_device_id *match; | 772 | const struct of_device_id *match; |
775 | 773 | ||
776 | match = of_match_device(of_match_ptr(mcp23s08_i2c_of_match), | 774 | match = of_match_device(of_match_ptr(mcp23s08_i2c_of_match), |
777 | &client->dev); | 775 | &client->dev); |
778 | pdata = dev_get_platdata(&client->dev); | 776 | if (match) { |
779 | if (match || !pdata) { | 777 | pdata = &local_pdata; |
780 | base = -1; | 778 | pdata->base = -1; |
781 | pullups = 0; | 779 | pdata->chip[0].pullups = 0; |
780 | pdata->irq_controller = of_property_read_bool( | ||
781 | client->dev.of_node, | ||
782 | "interrupt-controller"); | ||
783 | pdata->mirror = of_property_read_bool(client->dev.of_node, | ||
784 | "microchip,irq-mirror"); | ||
782 | client->irq = irq_of_parse_and_map(client->dev.of_node, 0); | 785 | client->irq = irq_of_parse_and_map(client->dev.of_node, 0); |
783 | } else { | 786 | } else { |
784 | if (!gpio_is_valid(pdata->base)) { | 787 | pdata = dev_get_platdata(&client->dev); |
788 | if (!pdata || !gpio_is_valid(pdata->base)) { | ||
785 | dev_dbg(&client->dev, "invalid platform data\n"); | 789 | dev_dbg(&client->dev, "invalid platform data\n"); |
786 | return -EINVAL; | 790 | return -EINVAL; |
787 | } | 791 | } |
788 | base = pdata->base; | ||
789 | pullups = pdata->chip[0].pullups; | ||
790 | } | 792 | } |
791 | 793 | ||
792 | mcp = kzalloc(sizeof(*mcp), GFP_KERNEL); | 794 | mcp = kzalloc(sizeof(*mcp), GFP_KERNEL); |
@@ -795,7 +797,7 @@ static int mcp230xx_probe(struct i2c_client *client, | |||
795 | 797 | ||
796 | mcp->irq = client->irq; | 798 | mcp->irq = client->irq; |
797 | status = mcp23s08_probe_one(mcp, &client->dev, client, client->addr, | 799 | status = mcp23s08_probe_one(mcp, &client->dev, client, client->addr, |
798 | id->driver_data, base, pullups); | 800 | id->driver_data, pdata, 0); |
799 | if (status) | 801 | if (status) |
800 | goto fail; | 802 | goto fail; |
801 | 803 | ||
@@ -863,14 +865,12 @@ static void mcp23s08_i2c_exit(void) { } | |||
863 | 865 | ||
864 | static int mcp23s08_probe(struct spi_device *spi) | 866 | static int mcp23s08_probe(struct spi_device *spi) |
865 | { | 867 | { |
866 | struct mcp23s08_platform_data *pdata; | 868 | struct mcp23s08_platform_data *pdata, local_pdata; |
867 | unsigned addr; | 869 | unsigned addr; |
868 | int chips = 0; | 870 | int chips = 0; |
869 | struct mcp23s08_driver_data *data; | 871 | struct mcp23s08_driver_data *data; |
870 | int status, type; | 872 | int status, type; |
871 | unsigned base = -1, | 873 | unsigned ngpio = 0; |
872 | ngpio = 0, | ||
873 | pullups[ARRAY_SIZE(pdata->chip)]; | ||
874 | const struct of_device_id *match; | 874 | const struct of_device_id *match; |
875 | u32 spi_present_mask = 0; | 875 | u32 spi_present_mask = 0; |
876 | 876 | ||
@@ -893,11 +893,18 @@ static int mcp23s08_probe(struct spi_device *spi) | |||
893 | return -ENODEV; | 893 | return -ENODEV; |
894 | } | 894 | } |
895 | 895 | ||
896 | pdata = &local_pdata; | ||
897 | pdata->base = -1; | ||
896 | for (addr = 0; addr < ARRAY_SIZE(pdata->chip); addr++) { | 898 | for (addr = 0; addr < ARRAY_SIZE(pdata->chip); addr++) { |
897 | pullups[addr] = 0; | 899 | pdata->chip[addr].pullups = 0; |
898 | if (spi_present_mask & (1 << addr)) | 900 | if (spi_present_mask & (1 << addr)) |
899 | chips++; | 901 | chips++; |
900 | } | 902 | } |
903 | pdata->irq_controller = of_property_read_bool( | ||
904 | spi->dev.of_node, | ||
905 | "interrupt-controller"); | ||
906 | pdata->mirror = of_property_read_bool(spi->dev.of_node, | ||
907 | "microchip,irq-mirror"); | ||
901 | } else { | 908 | } else { |
902 | type = spi_get_device_id(spi)->driver_data; | 909 | type = spi_get_device_id(spi)->driver_data; |
903 | pdata = dev_get_platdata(&spi->dev); | 910 | pdata = dev_get_platdata(&spi->dev); |
@@ -917,10 +924,7 @@ static int mcp23s08_probe(struct spi_device *spi) | |||
917 | return -EINVAL; | 924 | return -EINVAL; |
918 | } | 925 | } |
919 | spi_present_mask |= 1 << addr; | 926 | spi_present_mask |= 1 << addr; |
920 | pullups[addr] = pdata->chip[addr].pullups; | ||
921 | } | 927 | } |
922 | |||
923 | base = pdata->base; | ||
924 | } | 928 | } |
925 | 929 | ||
926 | if (!chips) | 930 | if (!chips) |
@@ -938,13 +942,13 @@ static int mcp23s08_probe(struct spi_device *spi) | |||
938 | chips--; | 942 | chips--; |
939 | data->mcp[addr] = &data->chip[chips]; | 943 | data->mcp[addr] = &data->chip[chips]; |
940 | status = mcp23s08_probe_one(data->mcp[addr], &spi->dev, spi, | 944 | status = mcp23s08_probe_one(data->mcp[addr], &spi->dev, spi, |
941 | 0x40 | (addr << 1), type, base, | 945 | 0x40 | (addr << 1), type, pdata, |
942 | pullups[addr]); | 946 | addr); |
943 | if (status < 0) | 947 | if (status < 0) |
944 | goto fail; | 948 | goto fail; |
945 | 949 | ||
946 | if (base != -1) | 950 | if (pdata->base != -1) |
947 | base += (type == MCP_TYPE_S17) ? 16 : 8; | 951 | pdata->base += (type == MCP_TYPE_S17) ? 16 : 8; |
948 | ngpio += (type == MCP_TYPE_S17) ? 16 : 8; | 952 | ngpio += (type == MCP_TYPE_S17) ? 16 : 8; |
949 | } | 953 | } |
950 | data->ngpio = ngpio; | 954 | data->ngpio = ngpio; |
diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c index 174932165fcb..415682f69214 100644 --- a/drivers/gpio/gpio-omap.c +++ b/drivers/gpio/gpio-omap.c | |||
@@ -857,16 +857,6 @@ static void omap_gpio_unmask_irq(struct irq_data *d) | |||
857 | spin_unlock_irqrestore(&bank->lock, flags); | 857 | spin_unlock_irqrestore(&bank->lock, flags); |
858 | } | 858 | } |
859 | 859 | ||
860 | static struct irq_chip gpio_irq_chip = { | ||
861 | .name = "GPIO", | ||
862 | .irq_shutdown = omap_gpio_irq_shutdown, | ||
863 | .irq_ack = omap_gpio_ack_irq, | ||
864 | .irq_mask = omap_gpio_mask_irq, | ||
865 | .irq_unmask = omap_gpio_unmask_irq, | ||
866 | .irq_set_type = omap_gpio_irq_type, | ||
867 | .irq_set_wake = omap_gpio_wake_enable, | ||
868 | }; | ||
869 | |||
870 | /*---------------------------------------------------------------------*/ | 860 | /*---------------------------------------------------------------------*/ |
871 | 861 | ||
872 | static int omap_mpuio_suspend_noirq(struct device *dev) | 862 | static int omap_mpuio_suspend_noirq(struct device *dev) |
@@ -1088,7 +1078,7 @@ omap_mpuio_alloc_gc(struct gpio_bank *bank, unsigned int irq_start, | |||
1088 | IRQ_NOREQUEST | IRQ_NOPROBE, 0); | 1078 | IRQ_NOREQUEST | IRQ_NOPROBE, 0); |
1089 | } | 1079 | } |
1090 | 1080 | ||
1091 | static int omap_gpio_chip_init(struct gpio_bank *bank) | 1081 | static int omap_gpio_chip_init(struct gpio_bank *bank, struct irq_chip *irqc) |
1092 | { | 1082 | { |
1093 | int j; | 1083 | int j; |
1094 | static int gpio; | 1084 | static int gpio; |
@@ -1137,17 +1127,17 @@ static int omap_gpio_chip_init(struct gpio_bank *bank) | |||
1137 | } | 1127 | } |
1138 | #endif | 1128 | #endif |
1139 | 1129 | ||
1140 | ret = gpiochip_irqchip_add(&bank->chip, &gpio_irq_chip, | 1130 | ret = gpiochip_irqchip_add(&bank->chip, irqc, |
1141 | irq_base, omap_gpio_irq_handler, | 1131 | irq_base, omap_gpio_irq_handler, |
1142 | IRQ_TYPE_NONE); | 1132 | IRQ_TYPE_NONE); |
1143 | 1133 | ||
1144 | if (ret) { | 1134 | if (ret) { |
1145 | dev_err(bank->dev, "Couldn't add irqchip to gpiochip %d\n", ret); | 1135 | dev_err(bank->dev, "Couldn't add irqchip to gpiochip %d\n", ret); |
1146 | ret = gpiochip_remove(&bank->chip); | 1136 | gpiochip_remove(&bank->chip); |
1147 | return -ENODEV; | 1137 | return -ENODEV; |
1148 | } | 1138 | } |
1149 | 1139 | ||
1150 | gpiochip_set_chained_irqchip(&bank->chip, &gpio_irq_chip, | 1140 | gpiochip_set_chained_irqchip(&bank->chip, irqc, |
1151 | bank->irq, omap_gpio_irq_handler); | 1141 | bank->irq, omap_gpio_irq_handler); |
1152 | 1142 | ||
1153 | for (j = 0; j < bank->width; j++) { | 1143 | for (j = 0; j < bank->width; j++) { |
@@ -1172,6 +1162,7 @@ static int omap_gpio_probe(struct platform_device *pdev) | |||
1172 | const struct omap_gpio_platform_data *pdata; | 1162 | const struct omap_gpio_platform_data *pdata; |
1173 | struct resource *res; | 1163 | struct resource *res; |
1174 | struct gpio_bank *bank; | 1164 | struct gpio_bank *bank; |
1165 | struct irq_chip *irqc; | ||
1175 | int ret; | 1166 | int ret; |
1176 | 1167 | ||
1177 | match = of_match_device(of_match_ptr(omap_gpio_match), dev); | 1168 | match = of_match_device(of_match_ptr(omap_gpio_match), dev); |
@@ -1186,6 +1177,18 @@ static int omap_gpio_probe(struct platform_device *pdev) | |||
1186 | return -ENOMEM; | 1177 | return -ENOMEM; |
1187 | } | 1178 | } |
1188 | 1179 | ||
1180 | irqc = devm_kzalloc(dev, sizeof(*irqc), GFP_KERNEL); | ||
1181 | if (!irqc) | ||
1182 | return -ENOMEM; | ||
1183 | |||
1184 | irqc->irq_shutdown = omap_gpio_irq_shutdown, | ||
1185 | irqc->irq_ack = omap_gpio_ack_irq, | ||
1186 | irqc->irq_mask = omap_gpio_mask_irq, | ||
1187 | irqc->irq_unmask = omap_gpio_unmask_irq, | ||
1188 | irqc->irq_set_type = omap_gpio_irq_type, | ||
1189 | irqc->irq_set_wake = omap_gpio_wake_enable, | ||
1190 | irqc->name = dev_name(&pdev->dev); | ||
1191 | |||
1189 | res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); | 1192 | res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); |
1190 | if (unlikely(!res)) { | 1193 | if (unlikely(!res)) { |
1191 | dev_err(dev, "Invalid IRQ resource\n"); | 1194 | dev_err(dev, "Invalid IRQ resource\n"); |
@@ -1241,7 +1244,7 @@ static int omap_gpio_probe(struct platform_device *pdev) | |||
1241 | 1244 | ||
1242 | omap_gpio_mod_init(bank); | 1245 | omap_gpio_mod_init(bank); |
1243 | 1246 | ||
1244 | ret = omap_gpio_chip_init(bank); | 1247 | ret = omap_gpio_chip_init(bank, irqc); |
1245 | if (ret) | 1248 | if (ret) |
1246 | return ret; | 1249 | return ret; |
1247 | 1250 | ||
diff --git a/drivers/gpio/gpio-pca953x.c b/drivers/gpio/gpio-pca953x.c index f9961eea2120..e2da64abbccd 100644 --- a/drivers/gpio/gpio-pca953x.c +++ b/drivers/gpio/gpio-pca953x.c | |||
@@ -520,7 +520,7 @@ static int pca953x_irq_setup(struct pca953x_chip *chip, | |||
520 | struct i2c_client *client = chip->client; | 520 | struct i2c_client *client = chip->client; |
521 | int ret, i, offset = 0; | 521 | int ret, i, offset = 0; |
522 | 522 | ||
523 | if (irq_base != -1 | 523 | if (client->irq && irq_base != -1 |
524 | && (id->driver_data & PCA_INT)) { | 524 | && (id->driver_data & PCA_INT)) { |
525 | 525 | ||
526 | switch (chip->chip_type) { | 526 | switch (chip->chip_type) { |
@@ -586,50 +586,6 @@ static int pca953x_irq_setup(struct pca953x_chip *chip, | |||
586 | } | 586 | } |
587 | #endif | 587 | #endif |
588 | 588 | ||
589 | /* | ||
590 | * Handlers for alternative sources of platform_data | ||
591 | */ | ||
592 | #ifdef CONFIG_OF_GPIO | ||
593 | /* | ||
594 | * Translate OpenFirmware node properties into platform_data | ||
595 | * WARNING: This is DEPRECATED and will be removed eventually! | ||
596 | */ | ||
597 | static void | ||
598 | pca953x_get_alt_pdata(struct i2c_client *client, int *gpio_base, u32 *invert) | ||
599 | { | ||
600 | struct device_node *node; | ||
601 | const __be32 *val; | ||
602 | int size; | ||
603 | |||
604 | *gpio_base = -1; | ||
605 | |||
606 | node = client->dev.of_node; | ||
607 | if (node == NULL) | ||
608 | return; | ||
609 | |||
610 | val = of_get_property(node, "linux,gpio-base", &size); | ||
611 | WARN(val, "%s: device-tree property 'linux,gpio-base' is deprecated!", __func__); | ||
612 | if (val) { | ||
613 | if (size != sizeof(*val)) | ||
614 | dev_warn(&client->dev, "%s: wrong linux,gpio-base\n", | ||
615 | node->full_name); | ||
616 | else | ||
617 | *gpio_base = be32_to_cpup(val); | ||
618 | } | ||
619 | |||
620 | val = of_get_property(node, "polarity", NULL); | ||
621 | WARN(val, "%s: device-tree property 'polarity' is deprecated!", __func__); | ||
622 | if (val) | ||
623 | *invert = *val; | ||
624 | } | ||
625 | #else | ||
626 | static void | ||
627 | pca953x_get_alt_pdata(struct i2c_client *client, int *gpio_base, u32 *invert) | ||
628 | { | ||
629 | *gpio_base = -1; | ||
630 | } | ||
631 | #endif | ||
632 | |||
633 | static int device_pca953x_init(struct pca953x_chip *chip, u32 invert) | 589 | static int device_pca953x_init(struct pca953x_chip *chip, u32 invert) |
634 | { | 590 | { |
635 | int ret; | 591 | int ret; |
@@ -704,12 +660,8 @@ static int pca953x_probe(struct i2c_client *client, | |||
704 | invert = pdata->invert; | 660 | invert = pdata->invert; |
705 | chip->names = pdata->names; | 661 | chip->names = pdata->names; |
706 | } else { | 662 | } else { |
707 | pca953x_get_alt_pdata(client, &chip->gpio_start, &invert); | 663 | chip->gpio_start = -1; |
708 | #ifdef CONFIG_OF_GPIO | 664 | irq_base = 0; |
709 | /* If I2C node has no interrupts property, disable GPIO interrupts */ | ||
710 | if (of_find_property(client->dev.of_node, "interrupts", NULL) == NULL) | ||
711 | irq_base = -1; | ||
712 | #endif | ||
713 | } | 665 | } |
714 | 666 | ||
715 | chip->client = client; | 667 | chip->client = client; |
diff --git a/drivers/gpio/gpio-pch.c b/drivers/gpio/gpio-pch.c index e0ac549dccb5..2d9a950ca2d4 100644 --- a/drivers/gpio/gpio-pch.c +++ b/drivers/gpio/gpio-pch.c | |||
@@ -171,6 +171,7 @@ static int pch_gpio_direction_input(struct gpio_chip *gpio, unsigned nr) | |||
171 | return 0; | 171 | return 0; |
172 | } | 172 | } |
173 | 173 | ||
174 | #ifdef CONFIG_PM | ||
174 | /* | 175 | /* |
175 | * Save register configuration and disable interrupts. | 176 | * Save register configuration and disable interrupts. |
176 | */ | 177 | */ |
@@ -206,6 +207,7 @@ static void pch_gpio_restore_reg_conf(struct pch_gpio *chip) | |||
206 | iowrite32(chip->pch_gpio_reg.gpio_use_sel_reg, | 207 | iowrite32(chip->pch_gpio_reg.gpio_use_sel_reg, |
207 | &chip->reg->gpio_use_sel); | 208 | &chip->reg->gpio_use_sel); |
208 | } | 209 | } |
210 | #endif | ||
209 | 211 | ||
210 | static int pch_gpio_to_irq(struct gpio_chip *gpio, unsigned offset) | 212 | static int pch_gpio_to_irq(struct gpio_chip *gpio, unsigned offset) |
211 | { | 213 | { |
diff --git a/drivers/gpio/gpio-samsung.c b/drivers/gpio/gpio-samsung.c index 3810da47043f..7c288ba4dc87 100644 --- a/drivers/gpio/gpio-samsung.c +++ b/drivers/gpio/gpio-samsung.c | |||
@@ -1309,56 +1309,6 @@ samsung_gpio_pull_t s3c_gpio_getpull(unsigned int pin) | |||
1309 | } | 1309 | } |
1310 | EXPORT_SYMBOL(s3c_gpio_getpull); | 1310 | EXPORT_SYMBOL(s3c_gpio_getpull); |
1311 | 1311 | ||
1312 | #ifdef CONFIG_S5P_GPIO_DRVSTR | ||
1313 | s5p_gpio_drvstr_t s5p_gpio_get_drvstr(unsigned int pin) | ||
1314 | { | ||
1315 | struct samsung_gpio_chip *chip = samsung_gpiolib_getchip(pin); | ||
1316 | unsigned int off; | ||
1317 | void __iomem *reg; | ||
1318 | int shift; | ||
1319 | u32 drvstr; | ||
1320 | |||
1321 | if (!chip) | ||
1322 | return -EINVAL; | ||
1323 | |||
1324 | off = pin - chip->chip.base; | ||
1325 | shift = off * 2; | ||
1326 | reg = chip->base + 0x0C; | ||
1327 | |||
1328 | drvstr = __raw_readl(reg); | ||
1329 | drvstr = drvstr >> shift; | ||
1330 | drvstr &= 0x3; | ||
1331 | |||
1332 | return (__force s5p_gpio_drvstr_t)drvstr; | ||
1333 | } | ||
1334 | EXPORT_SYMBOL(s5p_gpio_get_drvstr); | ||
1335 | |||
1336 | int s5p_gpio_set_drvstr(unsigned int pin, s5p_gpio_drvstr_t drvstr) | ||
1337 | { | ||
1338 | struct samsung_gpio_chip *chip = samsung_gpiolib_getchip(pin); | ||
1339 | unsigned int off; | ||
1340 | void __iomem *reg; | ||
1341 | int shift; | ||
1342 | u32 tmp; | ||
1343 | |||
1344 | if (!chip) | ||
1345 | return -EINVAL; | ||
1346 | |||
1347 | off = pin - chip->chip.base; | ||
1348 | shift = off * 2; | ||
1349 | reg = chip->base + 0x0C; | ||
1350 | |||
1351 | tmp = __raw_readl(reg); | ||
1352 | tmp &= ~(0x3 << shift); | ||
1353 | tmp |= drvstr << shift; | ||
1354 | |||
1355 | __raw_writel(tmp, reg); | ||
1356 | |||
1357 | return 0; | ||
1358 | } | ||
1359 | EXPORT_SYMBOL(s5p_gpio_set_drvstr); | ||
1360 | #endif /* CONFIG_S5P_GPIO_DRVSTR */ | ||
1361 | |||
1362 | #ifdef CONFIG_PLAT_S3C24XX | 1312 | #ifdef CONFIG_PLAT_S3C24XX |
1363 | unsigned int s3c2410_modify_misccr(unsigned int clear, unsigned int change) | 1313 | unsigned int s3c2410_modify_misccr(unsigned int clear, unsigned int change) |
1364 | { | 1314 | { |
diff --git a/drivers/gpio/gpio-stmpe.c b/drivers/gpio/gpio-stmpe.c index 845025a57240..85c5b1974294 100644 --- a/drivers/gpio/gpio-stmpe.c +++ b/drivers/gpio/gpio-stmpe.c | |||
@@ -13,6 +13,7 @@ | |||
13 | #include <linux/interrupt.h> | 13 | #include <linux/interrupt.h> |
14 | #include <linux/of.h> | 14 | #include <linux/of.h> |
15 | #include <linux/mfd/stmpe.h> | 15 | #include <linux/mfd/stmpe.h> |
16 | #include <linux/seq_file.h> | ||
16 | 17 | ||
17 | /* | 18 | /* |
18 | * These registers are modified under the irq bus lock and cached to avoid | 19 | * These registers are modified under the irq bus lock and cached to avoid |
@@ -127,19 +128,19 @@ static int stmpe_gpio_irq_set_type(struct irq_data *d, unsigned int type) | |||
127 | int regoffset = offset / 8; | 128 | int regoffset = offset / 8; |
128 | int mask = 1 << (offset % 8); | 129 | int mask = 1 << (offset % 8); |
129 | 130 | ||
130 | if (type == IRQ_TYPE_LEVEL_LOW || type == IRQ_TYPE_LEVEL_HIGH) | 131 | if (type & IRQ_TYPE_LEVEL_LOW || type & IRQ_TYPE_LEVEL_HIGH) |
131 | return -EINVAL; | 132 | return -EINVAL; |
132 | 133 | ||
133 | /* STMPE801 doesn't have RE and FE registers */ | 134 | /* STMPE801 doesn't have RE and FE registers */ |
134 | if (stmpe_gpio->stmpe->partnum == STMPE801) | 135 | if (stmpe_gpio->stmpe->partnum == STMPE801) |
135 | return 0; | 136 | return 0; |
136 | 137 | ||
137 | if (type == IRQ_TYPE_EDGE_RISING) | 138 | if (type & IRQ_TYPE_EDGE_RISING) |
138 | stmpe_gpio->regs[REG_RE][regoffset] |= mask; | 139 | stmpe_gpio->regs[REG_RE][regoffset] |= mask; |
139 | else | 140 | else |
140 | stmpe_gpio->regs[REG_RE][regoffset] &= ~mask; | 141 | stmpe_gpio->regs[REG_RE][regoffset] &= ~mask; |
141 | 142 | ||
142 | if (type == IRQ_TYPE_EDGE_FALLING) | 143 | if (type & IRQ_TYPE_EDGE_FALLING) |
143 | stmpe_gpio->regs[REG_FE][regoffset] |= mask; | 144 | stmpe_gpio->regs[REG_FE][regoffset] |= mask; |
144 | else | 145 | else |
145 | stmpe_gpio->regs[REG_FE][regoffset] &= ~mask; | 146 | stmpe_gpio->regs[REG_FE][regoffset] &= ~mask; |
@@ -211,6 +212,77 @@ static void stmpe_gpio_irq_unmask(struct irq_data *d) | |||
211 | stmpe_gpio->regs[REG_IE][regoffset] |= mask; | 212 | stmpe_gpio->regs[REG_IE][regoffset] |= mask; |
212 | } | 213 | } |
213 | 214 | ||
215 | static void stmpe_dbg_show_one(struct seq_file *s, | ||
216 | struct gpio_chip *gc, | ||
217 | unsigned offset, unsigned gpio) | ||
218 | { | ||
219 | struct stmpe_gpio *stmpe_gpio = to_stmpe_gpio(gc); | ||
220 | struct stmpe *stmpe = stmpe_gpio->stmpe; | ||
221 | const char *label = gpiochip_is_requested(gc, offset); | ||
222 | int num_banks = DIV_ROUND_UP(stmpe->num_gpios, 8); | ||
223 | bool val = !!stmpe_gpio_get(gc, offset); | ||
224 | u8 dir_reg = stmpe->regs[STMPE_IDX_GPDR_LSB] - (offset / 8); | ||
225 | u8 mask = 1 << (offset % 8); | ||
226 | int ret; | ||
227 | u8 dir; | ||
228 | |||
229 | ret = stmpe_reg_read(stmpe, dir_reg); | ||
230 | if (ret < 0) | ||
231 | return; | ||
232 | dir = !!(ret & mask); | ||
233 | |||
234 | if (dir) { | ||
235 | seq_printf(s, " gpio-%-3d (%-20.20s) out %s", | ||
236 | gpio, label ?: "(none)", | ||
237 | val ? "hi" : "lo"); | ||
238 | } else { | ||
239 | u8 edge_det_reg = stmpe->regs[STMPE_IDX_GPEDR_MSB] + num_banks - 1 - (offset / 8); | ||
240 | u8 rise_reg = stmpe->regs[STMPE_IDX_GPRER_LSB] - (offset / 8); | ||
241 | u8 fall_reg = stmpe->regs[STMPE_IDX_GPFER_LSB] - (offset / 8); | ||
242 | u8 irqen_reg = stmpe->regs[STMPE_IDX_IEGPIOR_LSB] - (offset / 8); | ||
243 | bool edge_det; | ||
244 | bool rise; | ||
245 | bool fall; | ||
246 | bool irqen; | ||
247 | |||
248 | ret = stmpe_reg_read(stmpe, edge_det_reg); | ||
249 | if (ret < 0) | ||
250 | return; | ||
251 | edge_det = !!(ret & mask); | ||
252 | ret = stmpe_reg_read(stmpe, rise_reg); | ||
253 | if (ret < 0) | ||
254 | return; | ||
255 | rise = !!(ret & mask); | ||
256 | ret = stmpe_reg_read(stmpe, fall_reg); | ||
257 | if (ret < 0) | ||
258 | return; | ||
259 | fall = !!(ret & mask); | ||
260 | ret = stmpe_reg_read(stmpe, irqen_reg); | ||
261 | if (ret < 0) | ||
262 | return; | ||
263 | irqen = !!(ret & mask); | ||
264 | |||
265 | seq_printf(s, " gpio-%-3d (%-20.20s) in %s %s %s%s%s", | ||
266 | gpio, label ?: "(none)", | ||
267 | val ? "hi" : "lo", | ||
268 | edge_det ? "edge-asserted" : "edge-inactive", | ||
269 | irqen ? "IRQ-enabled" : "", | ||
270 | rise ? " rising-edge-detection" : "", | ||
271 | fall ? " falling-edge-detection" : ""); | ||
272 | } | ||
273 | } | ||
274 | |||
275 | static void stmpe_dbg_show(struct seq_file *s, struct gpio_chip *gc) | ||
276 | { | ||
277 | unsigned i; | ||
278 | unsigned gpio = gc->base; | ||
279 | |||
280 | for (i = 0; i < gc->ngpio; i++, gpio++) { | ||
281 | stmpe_dbg_show_one(s, gc, i, gpio); | ||
282 | seq_printf(s, "\n"); | ||
283 | } | ||
284 | } | ||
285 | |||
214 | static struct irq_chip stmpe_gpio_irq_chip = { | 286 | static struct irq_chip stmpe_gpio_irq_chip = { |
215 | .name = "stmpe-gpio", | 287 | .name = "stmpe-gpio", |
216 | .irq_bus_lock = stmpe_gpio_irq_lock, | 288 | .irq_bus_lock = stmpe_gpio_irq_lock, |
@@ -293,6 +365,9 @@ static int stmpe_gpio_probe(struct platform_device *pdev) | |||
293 | #endif | 365 | #endif |
294 | stmpe_gpio->chip.base = -1; | 366 | stmpe_gpio->chip.base = -1; |
295 | 367 | ||
368 | if (IS_ENABLED(CONFIG_DEBUG_FS)) | ||
369 | stmpe_gpio->chip.dbg_show = stmpe_dbg_show; | ||
370 | |||
296 | if (pdata) | 371 | if (pdata) |
297 | stmpe_gpio->norequest_mask = pdata->norequest_mask; | 372 | stmpe_gpio->norequest_mask = pdata->norequest_mask; |
298 | else if (np) | 373 | else if (np) |
@@ -308,6 +383,12 @@ static int stmpe_gpio_probe(struct platform_device *pdev) | |||
308 | if (ret) | 383 | if (ret) |
309 | goto out_free; | 384 | goto out_free; |
310 | 385 | ||
386 | ret = gpiochip_add(&stmpe_gpio->chip); | ||
387 | if (ret) { | ||
388 | dev_err(&pdev->dev, "unable to add gpiochip: %d\n", ret); | ||
389 | goto out_disable; | ||
390 | } | ||
391 | |||
311 | if (irq > 0) { | 392 | if (irq > 0) { |
312 | ret = devm_request_threaded_irq(&pdev->dev, irq, NULL, | 393 | ret = devm_request_threaded_irq(&pdev->dev, irq, NULL, |
313 | stmpe_gpio_irq, IRQF_ONESHOT, | 394 | stmpe_gpio_irq, IRQF_ONESHOT, |
@@ -324,14 +405,13 @@ static int stmpe_gpio_probe(struct platform_device *pdev) | |||
324 | if (ret) { | 405 | if (ret) { |
325 | dev_err(&pdev->dev, | 406 | dev_err(&pdev->dev, |
326 | "could not connect irqchip to gpiochip\n"); | 407 | "could not connect irqchip to gpiochip\n"); |
327 | return ret; | 408 | goto out_disable; |
328 | } | 409 | } |
329 | } | ||
330 | 410 | ||
331 | ret = gpiochip_add(&stmpe_gpio->chip); | 411 | gpiochip_set_chained_irqchip(&stmpe_gpio->chip, |
332 | if (ret) { | 412 | &stmpe_gpio_irq_chip, |
333 | dev_err(&pdev->dev, "unable to add gpiochip: %d\n", ret); | 413 | irq, |
334 | goto out_disable; | 414 | NULL); |
335 | } | 415 | } |
336 | 416 | ||
337 | if (pdata && pdata->setup) | 417 | if (pdata && pdata->setup) |
@@ -343,6 +423,7 @@ static int stmpe_gpio_probe(struct platform_device *pdev) | |||
343 | 423 | ||
344 | out_disable: | 424 | out_disable: |
345 | stmpe_disable(stmpe, STMPE_BLOCK_GPIO); | 425 | stmpe_disable(stmpe, STMPE_BLOCK_GPIO); |
426 | gpiochip_remove(&stmpe_gpio->chip); | ||
346 | out_free: | 427 | out_free: |
347 | kfree(stmpe_gpio); | 428 | kfree(stmpe_gpio); |
348 | return ret; | 429 | return ret; |
diff --git a/drivers/gpio/gpio-stp-xway.c b/drivers/gpio/gpio-stp-xway.c index 04882a911b65..7e359b7cce1b 100644 --- a/drivers/gpio/gpio-stp-xway.c +++ b/drivers/gpio/gpio-stp-xway.c | |||
@@ -292,7 +292,7 @@ static struct platform_driver xway_stp_driver = { | |||
292 | }, | 292 | }, |
293 | }; | 293 | }; |
294 | 294 | ||
295 | int __init xway_stp_init(void) | 295 | static int __init xway_stp_init(void) |
296 | { | 296 | { |
297 | return platform_driver_register(&xway_stp_driver); | 297 | return platform_driver_register(&xway_stp_driver); |
298 | } | 298 | } |
diff --git a/drivers/gpio/gpio-syscon.c b/drivers/gpio/gpio-syscon.c index 30884fbc750d..e82fde4b6898 100644 --- a/drivers/gpio/gpio-syscon.c +++ b/drivers/gpio/gpio-syscon.c | |||
@@ -37,6 +37,8 @@ | |||
37 | * dat_bit_offset: Offset (in bits) to the first GPIO bit. | 37 | * dat_bit_offset: Offset (in bits) to the first GPIO bit. |
38 | * dir_bit_offset: Optional offset (in bits) to the first bit to switch | 38 | * dir_bit_offset: Optional offset (in bits) to the first bit to switch |
39 | * GPIO direction (Used with GPIO_SYSCON_FEAT_DIR flag). | 39 | * GPIO direction (Used with GPIO_SYSCON_FEAT_DIR flag). |
40 | * set: HW specific callback to assigns output value | ||
41 | * for signal "offset" | ||
40 | */ | 42 | */ |
41 | 43 | ||
42 | struct syscon_gpio_data { | 44 | struct syscon_gpio_data { |
@@ -45,12 +47,16 @@ struct syscon_gpio_data { | |||
45 | unsigned int bit_count; | 47 | unsigned int bit_count; |
46 | unsigned int dat_bit_offset; | 48 | unsigned int dat_bit_offset; |
47 | unsigned int dir_bit_offset; | 49 | unsigned int dir_bit_offset; |
50 | void (*set)(struct gpio_chip *chip, | ||
51 | unsigned offset, int value); | ||
48 | }; | 52 | }; |
49 | 53 | ||
50 | struct syscon_gpio_priv { | 54 | struct syscon_gpio_priv { |
51 | struct gpio_chip chip; | 55 | struct gpio_chip chip; |
52 | struct regmap *syscon; | 56 | struct regmap *syscon; |
53 | const struct syscon_gpio_data *data; | 57 | const struct syscon_gpio_data *data; |
58 | u32 dreg_offset; | ||
59 | u32 dir_reg_offset; | ||
54 | }; | 60 | }; |
55 | 61 | ||
56 | static inline struct syscon_gpio_priv *to_syscon_gpio(struct gpio_chip *chip) | 62 | static inline struct syscon_gpio_priv *to_syscon_gpio(struct gpio_chip *chip) |
@@ -61,9 +67,11 @@ static inline struct syscon_gpio_priv *to_syscon_gpio(struct gpio_chip *chip) | |||
61 | static int syscon_gpio_get(struct gpio_chip *chip, unsigned offset) | 67 | static int syscon_gpio_get(struct gpio_chip *chip, unsigned offset) |
62 | { | 68 | { |
63 | struct syscon_gpio_priv *priv = to_syscon_gpio(chip); | 69 | struct syscon_gpio_priv *priv = to_syscon_gpio(chip); |
64 | unsigned int val, offs = priv->data->dat_bit_offset + offset; | 70 | unsigned int val, offs; |
65 | int ret; | 71 | int ret; |
66 | 72 | ||
73 | offs = priv->dreg_offset + priv->data->dat_bit_offset + offset; | ||
74 | |||
67 | ret = regmap_read(priv->syscon, | 75 | ret = regmap_read(priv->syscon, |
68 | (offs / SYSCON_REG_BITS) * SYSCON_REG_SIZE, &val); | 76 | (offs / SYSCON_REG_BITS) * SYSCON_REG_SIZE, &val); |
69 | if (ret) | 77 | if (ret) |
@@ -75,7 +83,9 @@ static int syscon_gpio_get(struct gpio_chip *chip, unsigned offset) | |||
75 | static void syscon_gpio_set(struct gpio_chip *chip, unsigned offset, int val) | 83 | static void syscon_gpio_set(struct gpio_chip *chip, unsigned offset, int val) |
76 | { | 84 | { |
77 | struct syscon_gpio_priv *priv = to_syscon_gpio(chip); | 85 | struct syscon_gpio_priv *priv = to_syscon_gpio(chip); |
78 | unsigned int offs = priv->data->dat_bit_offset + offset; | 86 | unsigned int offs; |
87 | |||
88 | offs = priv->dreg_offset + priv->data->dat_bit_offset + offset; | ||
79 | 89 | ||
80 | regmap_update_bits(priv->syscon, | 90 | regmap_update_bits(priv->syscon, |
81 | (offs / SYSCON_REG_BITS) * SYSCON_REG_SIZE, | 91 | (offs / SYSCON_REG_BITS) * SYSCON_REG_SIZE, |
@@ -88,7 +98,10 @@ static int syscon_gpio_dir_in(struct gpio_chip *chip, unsigned offset) | |||
88 | struct syscon_gpio_priv *priv = to_syscon_gpio(chip); | 98 | struct syscon_gpio_priv *priv = to_syscon_gpio(chip); |
89 | 99 | ||
90 | if (priv->data->flags & GPIO_SYSCON_FEAT_DIR) { | 100 | if (priv->data->flags & GPIO_SYSCON_FEAT_DIR) { |
91 | unsigned int offs = priv->data->dir_bit_offset + offset; | 101 | unsigned int offs; |
102 | |||
103 | offs = priv->dir_reg_offset + | ||
104 | priv->data->dir_bit_offset + offset; | ||
92 | 105 | ||
93 | regmap_update_bits(priv->syscon, | 106 | regmap_update_bits(priv->syscon, |
94 | (offs / SYSCON_REG_BITS) * SYSCON_REG_SIZE, | 107 | (offs / SYSCON_REG_BITS) * SYSCON_REG_SIZE, |
@@ -103,7 +116,10 @@ static int syscon_gpio_dir_out(struct gpio_chip *chip, unsigned offset, int val) | |||
103 | struct syscon_gpio_priv *priv = to_syscon_gpio(chip); | 116 | struct syscon_gpio_priv *priv = to_syscon_gpio(chip); |
104 | 117 | ||
105 | if (priv->data->flags & GPIO_SYSCON_FEAT_DIR) { | 118 | if (priv->data->flags & GPIO_SYSCON_FEAT_DIR) { |
106 | unsigned int offs = priv->data->dir_bit_offset + offset; | 119 | unsigned int offs; |
120 | |||
121 | offs = priv->dir_reg_offset + | ||
122 | priv->data->dir_bit_offset + offset; | ||
107 | 123 | ||
108 | regmap_update_bits(priv->syscon, | 124 | regmap_update_bits(priv->syscon, |
109 | (offs / SYSCON_REG_BITS) * SYSCON_REG_SIZE, | 125 | (offs / SYSCON_REG_BITS) * SYSCON_REG_SIZE, |
@@ -111,7 +127,7 @@ static int syscon_gpio_dir_out(struct gpio_chip *chip, unsigned offset, int val) | |||
111 | BIT(offs % SYSCON_REG_BITS)); | 127 | BIT(offs % SYSCON_REG_BITS)); |
112 | } | 128 | } |
113 | 129 | ||
114 | syscon_gpio_set(chip, offset, val); | 130 | priv->data->set(chip, offset, val); |
115 | 131 | ||
116 | return 0; | 132 | return 0; |
117 | } | 133 | } |
@@ -124,11 +140,46 @@ static const struct syscon_gpio_data clps711x_mctrl_gpio = { | |||
124 | .dat_bit_offset = 0x40 * 8 + 8, | 140 | .dat_bit_offset = 0x40 * 8 + 8, |
125 | }; | 141 | }; |
126 | 142 | ||
143 | #define KEYSTONE_LOCK_BIT BIT(0) | ||
144 | |||
145 | static void keystone_gpio_set(struct gpio_chip *chip, unsigned offset, int val) | ||
146 | { | ||
147 | struct syscon_gpio_priv *priv = to_syscon_gpio(chip); | ||
148 | unsigned int offs; | ||
149 | int ret; | ||
150 | |||
151 | offs = priv->dreg_offset + priv->data->dat_bit_offset + offset; | ||
152 | |||
153 | if (!val) | ||
154 | return; | ||
155 | |||
156 | ret = regmap_update_bits( | ||
157 | priv->syscon, | ||
158 | (offs / SYSCON_REG_BITS) * SYSCON_REG_SIZE, | ||
159 | BIT(offs % SYSCON_REG_BITS) | KEYSTONE_LOCK_BIT, | ||
160 | BIT(offs % SYSCON_REG_BITS) | KEYSTONE_LOCK_BIT); | ||
161 | if (ret < 0) | ||
162 | dev_err(chip->dev, "gpio write failed ret(%d)\n", ret); | ||
163 | } | ||
164 | |||
165 | static const struct syscon_gpio_data keystone_dsp_gpio = { | ||
166 | /* ARM Keystone 2 */ | ||
167 | .compatible = NULL, | ||
168 | .flags = GPIO_SYSCON_FEAT_OUT, | ||
169 | .bit_count = 28, | ||
170 | .dat_bit_offset = 4, | ||
171 | .set = keystone_gpio_set, | ||
172 | }; | ||
173 | |||
127 | static const struct of_device_id syscon_gpio_ids[] = { | 174 | static const struct of_device_id syscon_gpio_ids[] = { |
128 | { | 175 | { |
129 | .compatible = "cirrus,clps711x-mctrl-gpio", | 176 | .compatible = "cirrus,clps711x-mctrl-gpio", |
130 | .data = &clps711x_mctrl_gpio, | 177 | .data = &clps711x_mctrl_gpio, |
131 | }, | 178 | }, |
179 | { | ||
180 | .compatible = "ti,keystone-dsp-gpio", | ||
181 | .data = &keystone_dsp_gpio, | ||
182 | }, | ||
132 | { } | 183 | { } |
133 | }; | 184 | }; |
134 | MODULE_DEVICE_TABLE(of, syscon_gpio_ids); | 185 | MODULE_DEVICE_TABLE(of, syscon_gpio_ids); |
@@ -138,6 +189,8 @@ static int syscon_gpio_probe(struct platform_device *pdev) | |||
138 | struct device *dev = &pdev->dev; | 189 | struct device *dev = &pdev->dev; |
139 | const struct of_device_id *of_id = of_match_device(syscon_gpio_ids, dev); | 190 | const struct of_device_id *of_id = of_match_device(syscon_gpio_ids, dev); |
140 | struct syscon_gpio_priv *priv; | 191 | struct syscon_gpio_priv *priv; |
192 | struct device_node *np = dev->of_node; | ||
193 | int ret; | ||
141 | 194 | ||
142 | priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); | 195 | priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); |
143 | if (!priv) | 196 | if (!priv) |
@@ -145,10 +198,31 @@ static int syscon_gpio_probe(struct platform_device *pdev) | |||
145 | 198 | ||
146 | priv->data = of_id->data; | 199 | priv->data = of_id->data; |
147 | 200 | ||
148 | priv->syscon = | 201 | if (priv->data->compatible) { |
149 | syscon_regmap_lookup_by_compatible(priv->data->compatible); | 202 | priv->syscon = syscon_regmap_lookup_by_compatible( |
150 | if (IS_ERR(priv->syscon)) | 203 | priv->data->compatible); |
151 | return PTR_ERR(priv->syscon); | 204 | if (IS_ERR(priv->syscon)) |
205 | return PTR_ERR(priv->syscon); | ||
206 | } else { | ||
207 | priv->syscon = | ||
208 | syscon_regmap_lookup_by_phandle(np, "gpio,syscon-dev"); | ||
209 | if (IS_ERR(priv->syscon)) | ||
210 | return PTR_ERR(priv->syscon); | ||
211 | |||
212 | ret = of_property_read_u32_index(np, "gpio,syscon-dev", 1, | ||
213 | &priv->dreg_offset); | ||
214 | if (ret) | ||
215 | dev_err(dev, "can't read the data register offset!\n"); | ||
216 | |||
217 | priv->dreg_offset <<= 3; | ||
218 | |||
219 | ret = of_property_read_u32_index(np, "gpio,syscon-dev", 2, | ||
220 | &priv->dir_reg_offset); | ||
221 | if (ret) | ||
222 | dev_err(dev, "can't read the dir register offset!\n"); | ||
223 | |||
224 | priv->dir_reg_offset <<= 3; | ||
225 | } | ||
152 | 226 | ||
153 | priv->chip.dev = dev; | 227 | priv->chip.dev = dev; |
154 | priv->chip.owner = THIS_MODULE; | 228 | priv->chip.owner = THIS_MODULE; |
@@ -159,7 +233,7 @@ static int syscon_gpio_probe(struct platform_device *pdev) | |||
159 | if (priv->data->flags & GPIO_SYSCON_FEAT_IN) | 233 | if (priv->data->flags & GPIO_SYSCON_FEAT_IN) |
160 | priv->chip.direction_input = syscon_gpio_dir_in; | 234 | priv->chip.direction_input = syscon_gpio_dir_in; |
161 | if (priv->data->flags & GPIO_SYSCON_FEAT_OUT) { | 235 | if (priv->data->flags & GPIO_SYSCON_FEAT_OUT) { |
162 | priv->chip.set = syscon_gpio_set; | 236 | priv->chip.set = priv->data->set ? : syscon_gpio_set; |
163 | priv->chip.direction_output = syscon_gpio_dir_out; | 237 | priv->chip.direction_output = syscon_gpio_dir_out; |
164 | } | 238 | } |
165 | 239 | ||
diff --git a/drivers/gpio/gpio-tc3589x.c b/drivers/gpio/gpio-tc3589x.c index 7324869c38e0..ae0f6466eb09 100644 --- a/drivers/gpio/gpio-tc3589x.c +++ b/drivers/gpio/gpio-tc3589x.c | |||
@@ -300,6 +300,11 @@ static int tc3589x_gpio_probe(struct platform_device *pdev) | |||
300 | return ret; | 300 | return ret; |
301 | } | 301 | } |
302 | 302 | ||
303 | gpiochip_set_chained_irqchip(&tc3589x_gpio->chip, | ||
304 | &tc3589x_gpio_irq_chip, | ||
305 | irq, | ||
306 | NULL); | ||
307 | |||
303 | if (pdata && pdata->setup) | 308 | if (pdata && pdata->setup) |
304 | pdata->setup(tc3589x, tc3589x_gpio->chip.base); | 309 | pdata->setup(tc3589x, tc3589x_gpio->chip.base); |
305 | 310 | ||
diff --git a/drivers/gpio/gpio-xgene.c b/drivers/gpio/gpio-xgene.c new file mode 100644 index 000000000000..7d489221dc1f --- /dev/null +++ b/drivers/gpio/gpio-xgene.c | |||
@@ -0,0 +1,244 @@ | |||
1 | /* | ||
2 | * AppliedMicro X-Gene SoC GPIO Driver | ||
3 | * | ||
4 | * Copyright (c) 2014, Applied Micro Circuits Corporation | ||
5 | * Author: Feng Kan <fkan@apm.com>. | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License version 2 as | ||
9 | * published by the Free Software Foundation. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
18 | */ | ||
19 | |||
20 | #include <linux/module.h> | ||
21 | #include <linux/kernel.h> | ||
22 | #include <linux/init.h> | ||
23 | #include <linux/io.h> | ||
24 | #include <linux/spinlock.h> | ||
25 | #include <linux/platform_device.h> | ||
26 | #include <linux/gpio/driver.h> | ||
27 | #include <linux/types.h> | ||
28 | #include <linux/bitops.h> | ||
29 | |||
30 | #define GPIO_SET_DR_OFFSET 0x0C | ||
31 | #define GPIO_DATA_OFFSET 0x14 | ||
32 | #define GPIO_BANK_STRIDE 0x0C | ||
33 | |||
34 | #define XGENE_GPIOS_PER_BANK 16 | ||
35 | #define XGENE_MAX_GPIO_BANKS 3 | ||
36 | #define XGENE_MAX_GPIOS (XGENE_GPIOS_PER_BANK * XGENE_MAX_GPIO_BANKS) | ||
37 | |||
38 | #define GPIO_BIT_OFFSET(x) (x % XGENE_GPIOS_PER_BANK) | ||
39 | #define GPIO_BANK_OFFSET(x) ((x / XGENE_GPIOS_PER_BANK) * GPIO_BANK_STRIDE) | ||
40 | |||
41 | struct xgene_gpio { | ||
42 | struct gpio_chip chip; | ||
43 | void __iomem *base; | ||
44 | spinlock_t lock; | ||
45 | #ifdef CONFIG_PM | ||
46 | u32 set_dr_val[XGENE_MAX_GPIO_BANKS]; | ||
47 | #endif | ||
48 | }; | ||
49 | |||
50 | static inline struct xgene_gpio *to_xgene_gpio(struct gpio_chip *chip) | ||
51 | { | ||
52 | return container_of(chip, struct xgene_gpio, chip); | ||
53 | } | ||
54 | |||
55 | static int xgene_gpio_get(struct gpio_chip *gc, unsigned int offset) | ||
56 | { | ||
57 | struct xgene_gpio *chip = to_xgene_gpio(gc); | ||
58 | unsigned long bank_offset; | ||
59 | u32 bit_offset; | ||
60 | |||
61 | bank_offset = GPIO_DATA_OFFSET + GPIO_BANK_OFFSET(offset); | ||
62 | bit_offset = GPIO_BIT_OFFSET(offset); | ||
63 | return !!(ioread32(chip->base + bank_offset) & BIT(bit_offset)); | ||
64 | } | ||
65 | |||
66 | static void __xgene_gpio_set(struct gpio_chip *gc, unsigned int offset, int val) | ||
67 | { | ||
68 | struct xgene_gpio *chip = to_xgene_gpio(gc); | ||
69 | unsigned long bank_offset; | ||
70 | u32 setval, bit_offset; | ||
71 | |||
72 | bank_offset = GPIO_SET_DR_OFFSET + GPIO_BANK_OFFSET(offset); | ||
73 | bit_offset = GPIO_BIT_OFFSET(offset) + XGENE_GPIOS_PER_BANK; | ||
74 | |||
75 | setval = ioread32(chip->base + bank_offset); | ||
76 | if (val) | ||
77 | setval |= BIT(bit_offset); | ||
78 | else | ||
79 | setval &= ~BIT(bit_offset); | ||
80 | iowrite32(setval, chip->base + bank_offset); | ||
81 | } | ||
82 | |||
83 | static void xgene_gpio_set(struct gpio_chip *gc, unsigned int offset, int val) | ||
84 | { | ||
85 | struct xgene_gpio *chip = to_xgene_gpio(gc); | ||
86 | unsigned long flags; | ||
87 | |||
88 | spin_lock_irqsave(&chip->lock, flags); | ||
89 | __xgene_gpio_set(gc, offset, val); | ||
90 | spin_unlock_irqrestore(&chip->lock, flags); | ||
91 | } | ||
92 | |||
93 | static int xgene_gpio_dir_in(struct gpio_chip *gc, unsigned int offset) | ||
94 | { | ||
95 | struct xgene_gpio *chip = to_xgene_gpio(gc); | ||
96 | unsigned long flags, bank_offset; | ||
97 | u32 dirval, bit_offset; | ||
98 | |||
99 | bank_offset = GPIO_SET_DR_OFFSET + GPIO_BANK_OFFSET(offset); | ||
100 | bit_offset = GPIO_BIT_OFFSET(offset); | ||
101 | |||
102 | spin_lock_irqsave(&chip->lock, flags); | ||
103 | |||
104 | dirval = ioread32(chip->base + bank_offset); | ||
105 | dirval |= BIT(bit_offset); | ||
106 | iowrite32(dirval, chip->base + bank_offset); | ||
107 | |||
108 | spin_unlock_irqrestore(&chip->lock, flags); | ||
109 | |||
110 | return 0; | ||
111 | } | ||
112 | |||
113 | static int xgene_gpio_dir_out(struct gpio_chip *gc, | ||
114 | unsigned int offset, int val) | ||
115 | { | ||
116 | struct xgene_gpio *chip = to_xgene_gpio(gc); | ||
117 | unsigned long flags, bank_offset; | ||
118 | u32 dirval, bit_offset; | ||
119 | |||
120 | bank_offset = GPIO_SET_DR_OFFSET + GPIO_BANK_OFFSET(offset); | ||
121 | bit_offset = GPIO_BIT_OFFSET(offset); | ||
122 | |||
123 | spin_lock_irqsave(&chip->lock, flags); | ||
124 | |||
125 | dirval = ioread32(chip->base + bank_offset); | ||
126 | dirval &= ~BIT(bit_offset); | ||
127 | iowrite32(dirval, chip->base + bank_offset); | ||
128 | __xgene_gpio_set(gc, offset, val); | ||
129 | |||
130 | spin_unlock_irqrestore(&chip->lock, flags); | ||
131 | |||
132 | return 0; | ||
133 | } | ||
134 | |||
135 | #ifdef CONFIG_PM | ||
136 | static int xgene_gpio_suspend(struct device *dev) | ||
137 | { | ||
138 | struct xgene_gpio *gpio = dev_get_drvdata(dev); | ||
139 | unsigned long bank_offset; | ||
140 | unsigned int bank; | ||
141 | |||
142 | for (bank = 0; bank < XGENE_MAX_GPIO_BANKS; bank++) { | ||
143 | bank_offset = GPIO_SET_DR_OFFSET + bank * GPIO_BANK_STRIDE; | ||
144 | gpio->set_dr_val[bank] = ioread32(gpio->base + bank_offset); | ||
145 | } | ||
146 | return 0; | ||
147 | } | ||
148 | |||
149 | static int xgene_gpio_resume(struct device *dev) | ||
150 | { | ||
151 | struct xgene_gpio *gpio = dev_get_drvdata(dev); | ||
152 | unsigned long bank_offset; | ||
153 | unsigned int bank; | ||
154 | |||
155 | for (bank = 0; bank < XGENE_MAX_GPIO_BANKS; bank++) { | ||
156 | bank_offset = GPIO_SET_DR_OFFSET + bank * GPIO_BANK_STRIDE; | ||
157 | iowrite32(gpio->set_dr_val[bank], gpio->base + bank_offset); | ||
158 | } | ||
159 | return 0; | ||
160 | } | ||
161 | |||
162 | static SIMPLE_DEV_PM_OPS(xgene_gpio_pm, xgene_gpio_suspend, xgene_gpio_resume); | ||
163 | #define XGENE_GPIO_PM_OPS (&xgene_gpio_pm) | ||
164 | #else | ||
165 | #define XGENE_GPIO_PM_OPS NULL | ||
166 | #endif | ||
167 | |||
168 | static int xgene_gpio_probe(struct platform_device *pdev) | ||
169 | { | ||
170 | struct resource *res; | ||
171 | struct xgene_gpio *gpio; | ||
172 | int err = 0; | ||
173 | |||
174 | gpio = devm_kzalloc(&pdev->dev, sizeof(*gpio), GFP_KERNEL); | ||
175 | if (!gpio) { | ||
176 | err = -ENOMEM; | ||
177 | goto err; | ||
178 | } | ||
179 | |||
180 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
181 | gpio->base = devm_ioremap_nocache(&pdev->dev, res->start, | ||
182 | resource_size(res)); | ||
183 | if (!gpio->base) { | ||
184 | err = -ENOMEM; | ||
185 | goto err; | ||
186 | } | ||
187 | |||
188 | gpio->chip.ngpio = XGENE_MAX_GPIOS; | ||
189 | |||
190 | spin_lock_init(&gpio->lock); | ||
191 | gpio->chip.dev = &pdev->dev; | ||
192 | gpio->chip.direction_input = xgene_gpio_dir_in; | ||
193 | gpio->chip.direction_output = xgene_gpio_dir_out; | ||
194 | gpio->chip.get = xgene_gpio_get; | ||
195 | gpio->chip.set = xgene_gpio_set; | ||
196 | gpio->chip.label = dev_name(&pdev->dev); | ||
197 | gpio->chip.base = -1; | ||
198 | |||
199 | platform_set_drvdata(pdev, gpio); | ||
200 | |||
201 | err = gpiochip_add(&gpio->chip); | ||
202 | if (err) { | ||
203 | dev_err(&pdev->dev, | ||
204 | "failed to register gpiochip.\n"); | ||
205 | goto err; | ||
206 | } | ||
207 | |||
208 | dev_info(&pdev->dev, "X-Gene GPIO driver registered.\n"); | ||
209 | return 0; | ||
210 | err: | ||
211 | dev_err(&pdev->dev, "X-Gene GPIO driver registration failed.\n"); | ||
212 | return err; | ||
213 | } | ||
214 | |||
215 | static int xgene_gpio_remove(struct platform_device *pdev) | ||
216 | { | ||
217 | struct xgene_gpio *gpio = platform_get_drvdata(pdev); | ||
218 | |||
219 | gpiochip_remove(&gpio->chip); | ||
220 | return 0; | ||
221 | } | ||
222 | |||
223 | static const struct of_device_id xgene_gpio_of_match[] = { | ||
224 | { .compatible = "apm,xgene-gpio", }, | ||
225 | {}, | ||
226 | }; | ||
227 | MODULE_DEVICE_TABLE(of, xgene_gpio_of_match); | ||
228 | |||
229 | static struct platform_driver xgene_gpio_driver = { | ||
230 | .driver = { | ||
231 | .name = "xgene-gpio", | ||
232 | .owner = THIS_MODULE, | ||
233 | .of_match_table = xgene_gpio_of_match, | ||
234 | .pm = XGENE_GPIO_PM_OPS, | ||
235 | }, | ||
236 | .probe = xgene_gpio_probe, | ||
237 | .remove = xgene_gpio_remove, | ||
238 | }; | ||
239 | |||
240 | module_platform_driver(xgene_gpio_driver); | ||
241 | |||
242 | MODULE_AUTHOR("Feng Kan <fkan@apm.com>"); | ||
243 | MODULE_DESCRIPTION("APM X-Gene GPIO driver"); | ||
244 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/gpio/gpio-xilinx.c b/drivers/gpio/gpio-xilinx.c index 12481867daf1..ba18b06c9a21 100644 --- a/drivers/gpio/gpio-xilinx.c +++ b/drivers/gpio/gpio-xilinx.c | |||
@@ -197,6 +197,7 @@ static int xgpio_of_probe(struct device_node *np) | |||
197 | struct xgpio_instance *chip; | 197 | struct xgpio_instance *chip; |
198 | int status = 0; | 198 | int status = 0; |
199 | const u32 *tree_info; | 199 | const u32 *tree_info; |
200 | u32 ngpio; | ||
200 | 201 | ||
201 | chip = kzalloc(sizeof(*chip), GFP_KERNEL); | 202 | chip = kzalloc(sizeof(*chip), GFP_KERNEL); |
202 | if (!chip) | 203 | if (!chip) |
@@ -211,12 +212,13 @@ static int xgpio_of_probe(struct device_node *np) | |||
211 | /* Update GPIO direction shadow register with default value */ | 212 | /* Update GPIO direction shadow register with default value */ |
212 | of_property_read_u32(np, "xlnx,tri-default", &chip->gpio_dir); | 213 | of_property_read_u32(np, "xlnx,tri-default", &chip->gpio_dir); |
213 | 214 | ||
214 | /* By default assume full GPIO controller */ | 215 | /* |
215 | chip->mmchip.gc.ngpio = 32; | 216 | * Check device node and parent device node for device width |
216 | 217 | * and assume default width of 32 | |
217 | /* Check device node and parent device node for device width */ | 218 | */ |
218 | of_property_read_u32(np, "xlnx,gpio-width", | 219 | if (of_property_read_u32(np, "xlnx,gpio-width", &ngpio)) |
219 | (u32 *)&chip->mmchip.gc.ngpio); | 220 | ngpio = 32; |
221 | chip->mmchip.gc.ngpio = (u16)ngpio; | ||
220 | 222 | ||
221 | spin_lock_init(&chip->gpio_lock); | 223 | spin_lock_init(&chip->gpio_lock); |
222 | 224 | ||
@@ -258,12 +260,13 @@ static int xgpio_of_probe(struct device_node *np) | |||
258 | /* Update GPIO direction shadow register with default value */ | 260 | /* Update GPIO direction shadow register with default value */ |
259 | of_property_read_u32(np, "xlnx,tri-default-2", &chip->gpio_dir); | 261 | of_property_read_u32(np, "xlnx,tri-default-2", &chip->gpio_dir); |
260 | 262 | ||
261 | /* By default assume full GPIO controller */ | 263 | /* |
262 | chip->mmchip.gc.ngpio = 32; | 264 | * Check device node and parent device node for device width |
263 | 265 | * and assume default width of 32 | |
264 | /* Check device node and parent device node for device width */ | 266 | */ |
265 | of_property_read_u32(np, "xlnx,gpio2-width", | 267 | if (of_property_read_u32(np, "xlnx,gpio2-width", &ngpio)) |
266 | (u32 *)&chip->mmchip.gc.ngpio); | 268 | ngpio = 32; |
269 | chip->mmchip.gc.ngpio = (u16)ngpio; | ||
267 | 270 | ||
268 | spin_lock_init(&chip->gpio_lock); | 271 | spin_lock_init(&chip->gpio_lock); |
269 | 272 | ||
diff --git a/drivers/gpio/gpio-zynq.c b/drivers/gpio/gpio-zynq.c index 31ad5df5dbc9..74cd480bf8de 100644 --- a/drivers/gpio/gpio-zynq.c +++ b/drivers/gpio/gpio-zynq.c | |||
@@ -88,16 +88,17 @@ | |||
88 | * @chip: instance of the gpio_chip | 88 | * @chip: instance of the gpio_chip |
89 | * @base_addr: base address of the GPIO device | 89 | * @base_addr: base address of the GPIO device |
90 | * @clk: clock resource for this controller | 90 | * @clk: clock resource for this controller |
91 | * @irq: interrupt for the GPIO device | ||
91 | */ | 92 | */ |
92 | struct zynq_gpio { | 93 | struct zynq_gpio { |
93 | struct gpio_chip chip; | 94 | struct gpio_chip chip; |
94 | void __iomem *base_addr; | 95 | void __iomem *base_addr; |
95 | struct clk *clk; | 96 | struct clk *clk; |
97 | int irq; | ||
96 | }; | 98 | }; |
97 | 99 | ||
98 | static struct irq_chip zynq_gpio_level_irqchip; | 100 | static struct irq_chip zynq_gpio_level_irqchip; |
99 | static struct irq_chip zynq_gpio_edge_irqchip; | 101 | static struct irq_chip zynq_gpio_edge_irqchip; |
100 | |||
101 | /** | 102 | /** |
102 | * zynq_gpio_get_bank_pin - Get the bank number and pin number within that bank | 103 | * zynq_gpio_get_bank_pin - Get the bank number and pin number within that bank |
103 | * for a given pin in the GPIO device | 104 | * for a given pin in the GPIO device |
@@ -138,6 +139,13 @@ static inline void zynq_gpio_get_bank_pin(unsigned int pin_num, | |||
138 | } | 139 | } |
139 | } | 140 | } |
140 | 141 | ||
142 | static const unsigned int zynq_gpio_bank_offset[] = { | ||
143 | ZYNQ_GPIO_BANK0_PIN_MIN, | ||
144 | ZYNQ_GPIO_BANK1_PIN_MIN, | ||
145 | ZYNQ_GPIO_BANK2_PIN_MIN, | ||
146 | ZYNQ_GPIO_BANK3_PIN_MIN, | ||
147 | }; | ||
148 | |||
141 | /** | 149 | /** |
142 | * zynq_gpio_get_value - Get the state of the specified pin of GPIO device | 150 | * zynq_gpio_get_value - Get the state of the specified pin of GPIO device |
143 | * @chip: gpio_chip instance to be worked on | 151 | * @chip: gpio_chip instance to be worked on |
@@ -427,10 +435,9 @@ static int zynq_gpio_set_irq_type(struct irq_data *irq_data, unsigned int type) | |||
427 | 435 | ||
428 | static int zynq_gpio_set_wake(struct irq_data *data, unsigned int on) | 436 | static int zynq_gpio_set_wake(struct irq_data *data, unsigned int on) |
429 | { | 437 | { |
430 | if (on) | 438 | struct zynq_gpio *gpio = irq_data_get_irq_chip_data(data); |
431 | zynq_gpio_irq_unmask(data); | 439 | |
432 | else | 440 | irq_set_irq_wake(gpio->irq, on); |
433 | zynq_gpio_irq_mask(data); | ||
434 | 441 | ||
435 | return 0; | 442 | return 0; |
436 | } | 443 | } |
@@ -444,7 +451,8 @@ static struct irq_chip zynq_gpio_level_irqchip = { | |||
444 | .irq_unmask = zynq_gpio_irq_unmask, | 451 | .irq_unmask = zynq_gpio_irq_unmask, |
445 | .irq_set_type = zynq_gpio_set_irq_type, | 452 | .irq_set_type = zynq_gpio_set_irq_type, |
446 | .irq_set_wake = zynq_gpio_set_wake, | 453 | .irq_set_wake = zynq_gpio_set_wake, |
447 | .flags = IRQCHIP_EOI_THREADED | IRQCHIP_EOI_IF_HANDLED, | 454 | .flags = IRQCHIP_EOI_THREADED | IRQCHIP_EOI_IF_HANDLED | |
455 | IRQCHIP_MASK_ON_SUSPEND, | ||
448 | }; | 456 | }; |
449 | 457 | ||
450 | static struct irq_chip zynq_gpio_edge_irqchip = { | 458 | static struct irq_chip zynq_gpio_edge_irqchip = { |
@@ -455,8 +463,28 @@ static struct irq_chip zynq_gpio_edge_irqchip = { | |||
455 | .irq_unmask = zynq_gpio_irq_unmask, | 463 | .irq_unmask = zynq_gpio_irq_unmask, |
456 | .irq_set_type = zynq_gpio_set_irq_type, | 464 | .irq_set_type = zynq_gpio_set_irq_type, |
457 | .irq_set_wake = zynq_gpio_set_wake, | 465 | .irq_set_wake = zynq_gpio_set_wake, |
466 | .flags = IRQCHIP_MASK_ON_SUSPEND, | ||
458 | }; | 467 | }; |
459 | 468 | ||
469 | static void zynq_gpio_handle_bank_irq(struct zynq_gpio *gpio, | ||
470 | unsigned int bank_num, | ||
471 | unsigned long pending) | ||
472 | { | ||
473 | unsigned int bank_offset = zynq_gpio_bank_offset[bank_num]; | ||
474 | struct irq_domain *irqdomain = gpio->chip.irqdomain; | ||
475 | int offset; | ||
476 | |||
477 | if (!pending) | ||
478 | return; | ||
479 | |||
480 | for_each_set_bit(offset, &pending, 32) { | ||
481 | unsigned int gpio_irq; | ||
482 | |||
483 | gpio_irq = irq_find_mapping(irqdomain, offset + bank_offset); | ||
484 | generic_handle_irq(gpio_irq); | ||
485 | } | ||
486 | } | ||
487 | |||
460 | /** | 488 | /** |
461 | * zynq_gpio_irqhandler - IRQ handler for the gpio banks of a gpio device | 489 | * zynq_gpio_irqhandler - IRQ handler for the gpio banks of a gpio device |
462 | * @irq: irq number of the gpio bank where interrupt has occurred | 490 | * @irq: irq number of the gpio bank where interrupt has occurred |
@@ -482,18 +510,7 @@ static void zynq_gpio_irqhandler(unsigned int irq, struct irq_desc *desc) | |||
482 | ZYNQ_GPIO_INTSTS_OFFSET(bank_num)); | 510 | ZYNQ_GPIO_INTSTS_OFFSET(bank_num)); |
483 | int_enb = readl_relaxed(gpio->base_addr + | 511 | int_enb = readl_relaxed(gpio->base_addr + |
484 | ZYNQ_GPIO_INTMASK_OFFSET(bank_num)); | 512 | ZYNQ_GPIO_INTMASK_OFFSET(bank_num)); |
485 | int_sts &= ~int_enb; | 513 | zynq_gpio_handle_bank_irq(gpio, bank_num, int_sts & ~int_enb); |
486 | if (int_sts) { | ||
487 | int offset; | ||
488 | unsigned long pending = int_sts; | ||
489 | |||
490 | for_each_set_bit(offset, &pending, 32) { | ||
491 | unsigned int gpio_irq = | ||
492 | irq_find_mapping(gpio->chip.irqdomain, | ||
493 | offset); | ||
494 | generic_handle_irq(gpio_irq); | ||
495 | } | ||
496 | } | ||
497 | } | 514 | } |
498 | 515 | ||
499 | chained_irq_exit(irqchip, desc); | 516 | chained_irq_exit(irqchip, desc); |
@@ -501,7 +518,11 @@ static void zynq_gpio_irqhandler(unsigned int irq, struct irq_desc *desc) | |||
501 | 518 | ||
502 | static int __maybe_unused zynq_gpio_suspend(struct device *dev) | 519 | static int __maybe_unused zynq_gpio_suspend(struct device *dev) |
503 | { | 520 | { |
504 | if (!device_may_wakeup(dev)) | 521 | struct platform_device *pdev = to_platform_device(dev); |
522 | int irq = platform_get_irq(pdev, 0); | ||
523 | struct irq_data *data = irq_get_irq_data(irq); | ||
524 | |||
525 | if (!irqd_is_wakeup_set(data)) | ||
505 | return pm_runtime_force_suspend(dev); | 526 | return pm_runtime_force_suspend(dev); |
506 | 527 | ||
507 | return 0; | 528 | return 0; |
@@ -509,7 +530,11 @@ static int __maybe_unused zynq_gpio_suspend(struct device *dev) | |||
509 | 530 | ||
510 | static int __maybe_unused zynq_gpio_resume(struct device *dev) | 531 | static int __maybe_unused zynq_gpio_resume(struct device *dev) |
511 | { | 532 | { |
512 | if (!device_may_wakeup(dev)) | 533 | struct platform_device *pdev = to_platform_device(dev); |
534 | int irq = platform_get_irq(pdev, 0); | ||
535 | struct irq_data *data = irq_get_irq_data(irq); | ||
536 | |||
537 | if (!irqd_is_wakeup_set(data)) | ||
513 | return pm_runtime_force_resume(dev); | 538 | return pm_runtime_force_resume(dev); |
514 | 539 | ||
515 | return 0; | 540 | return 0; |
@@ -570,7 +595,7 @@ static const struct dev_pm_ops zynq_gpio_dev_pm_ops = { | |||
570 | */ | 595 | */ |
571 | static int zynq_gpio_probe(struct platform_device *pdev) | 596 | static int zynq_gpio_probe(struct platform_device *pdev) |
572 | { | 597 | { |
573 | int ret, bank_num, irq; | 598 | int ret, bank_num; |
574 | struct zynq_gpio *gpio; | 599 | struct zynq_gpio *gpio; |
575 | struct gpio_chip *chip; | 600 | struct gpio_chip *chip; |
576 | struct resource *res; | 601 | struct resource *res; |
@@ -586,10 +611,10 @@ static int zynq_gpio_probe(struct platform_device *pdev) | |||
586 | if (IS_ERR(gpio->base_addr)) | 611 | if (IS_ERR(gpio->base_addr)) |
587 | return PTR_ERR(gpio->base_addr); | 612 | return PTR_ERR(gpio->base_addr); |
588 | 613 | ||
589 | irq = platform_get_irq(pdev, 0); | 614 | gpio->irq = platform_get_irq(pdev, 0); |
590 | if (irq < 0) { | 615 | if (gpio->irq < 0) { |
591 | dev_err(&pdev->dev, "invalid IRQ\n"); | 616 | dev_err(&pdev->dev, "invalid IRQ\n"); |
592 | return irq; | 617 | return gpio->irq; |
593 | } | 618 | } |
594 | 619 | ||
595 | /* configure the gpio chip */ | 620 | /* configure the gpio chip */ |
@@ -637,19 +662,16 @@ static int zynq_gpio_probe(struct platform_device *pdev) | |||
637 | goto err_rm_gpiochip; | 662 | goto err_rm_gpiochip; |
638 | } | 663 | } |
639 | 664 | ||
640 | gpiochip_set_chained_irqchip(chip, &zynq_gpio_edge_irqchip, irq, | 665 | gpiochip_set_chained_irqchip(chip, &zynq_gpio_edge_irqchip, gpio->irq, |
641 | zynq_gpio_irqhandler); | 666 | zynq_gpio_irqhandler); |
642 | 667 | ||
643 | pm_runtime_set_active(&pdev->dev); | 668 | pm_runtime_set_active(&pdev->dev); |
644 | pm_runtime_enable(&pdev->dev); | 669 | pm_runtime_enable(&pdev->dev); |
645 | 670 | ||
646 | device_set_wakeup_capable(&pdev->dev, 1); | ||
647 | |||
648 | return 0; | 671 | return 0; |
649 | 672 | ||
650 | err_rm_gpiochip: | 673 | err_rm_gpiochip: |
651 | if (gpiochip_remove(chip)) | 674 | gpiochip_remove(chip); |
652 | dev_err(&pdev->dev, "Failed to remove gpio chip\n"); | ||
653 | err_disable_clk: | 675 | err_disable_clk: |
654 | clk_disable_unprepare(gpio->clk); | 676 | clk_disable_unprepare(gpio->clk); |
655 | 677 | ||
@@ -664,16 +686,10 @@ err_disable_clk: | |||
664 | */ | 686 | */ |
665 | static int zynq_gpio_remove(struct platform_device *pdev) | 687 | static int zynq_gpio_remove(struct platform_device *pdev) |
666 | { | 688 | { |
667 | int ret; | ||
668 | struct zynq_gpio *gpio = platform_get_drvdata(pdev); | 689 | struct zynq_gpio *gpio = platform_get_drvdata(pdev); |
669 | 690 | ||
670 | pm_runtime_get_sync(&pdev->dev); | 691 | pm_runtime_get_sync(&pdev->dev); |
671 | 692 | gpiochip_remove(&gpio->chip); | |
672 | ret = gpiochip_remove(&gpio->chip); | ||
673 | if (ret) { | ||
674 | dev_err(&pdev->dev, "Failed to remove gpio chip\n"); | ||
675 | return ret; | ||
676 | } | ||
677 | clk_disable_unprepare(gpio->clk); | 693 | clk_disable_unprepare(gpio->clk); |
678 | device_set_wakeup_capable(&pdev->dev, 0); | 694 | device_set_wakeup_capable(&pdev->dev, 0); |
679 | return 0; | 695 | return 0; |
@@ -688,7 +704,6 @@ MODULE_DEVICE_TABLE(of, zynq_gpio_of_match); | |||
688 | static struct platform_driver zynq_gpio_driver = { | 704 | static struct platform_driver zynq_gpio_driver = { |
689 | .driver = { | 705 | .driver = { |
690 | .name = DRIVER_NAME, | 706 | .name = DRIVER_NAME, |
691 | .owner = THIS_MODULE, | ||
692 | .pm = &zynq_gpio_dev_pm_ops, | 707 | .pm = &zynq_gpio_dev_pm_ops, |
693 | .of_match_table = zynq_gpio_of_match, | 708 | .of_match_table = zynq_gpio_of_match, |
694 | }, | 709 | }, |
diff --git a/drivers/gpio/gpiolib-acpi.c b/drivers/gpio/gpiolib-acpi.c index 687476fb39e3..05c6275da224 100644 --- a/drivers/gpio/gpiolib-acpi.c +++ b/drivers/gpio/gpiolib-acpi.c | |||
@@ -25,10 +25,12 @@ struct acpi_gpio_event { | |||
25 | acpi_handle handle; | 25 | acpi_handle handle; |
26 | unsigned int pin; | 26 | unsigned int pin; |
27 | unsigned int irq; | 27 | unsigned int irq; |
28 | struct gpio_desc *desc; | ||
28 | }; | 29 | }; |
29 | 30 | ||
30 | struct acpi_gpio_connection { | 31 | struct acpi_gpio_connection { |
31 | struct list_head node; | 32 | struct list_head node; |
33 | unsigned int pin; | ||
32 | struct gpio_desc *desc; | 34 | struct gpio_desc *desc; |
33 | }; | 35 | }; |
34 | 36 | ||
@@ -143,14 +145,8 @@ static acpi_status acpi_gpiochip_request_interrupt(struct acpi_resource *ares, | |||
143 | if (!handler) | 145 | if (!handler) |
144 | return AE_BAD_PARAMETER; | 146 | return AE_BAD_PARAMETER; |
145 | 147 | ||
146 | desc = gpiochip_get_desc(chip, pin); | 148 | desc = gpiochip_request_own_desc(chip, pin, "ACPI:Event"); |
147 | if (IS_ERR(desc)) { | 149 | if (IS_ERR(desc)) { |
148 | dev_err(chip->dev, "Failed to get GPIO descriptor\n"); | ||
149 | return AE_ERROR; | ||
150 | } | ||
151 | |||
152 | ret = gpiochip_request_own_desc(desc, "ACPI:Event"); | ||
153 | if (ret) { | ||
154 | dev_err(chip->dev, "Failed to request GPIO\n"); | 150 | dev_err(chip->dev, "Failed to request GPIO\n"); |
155 | return AE_ERROR; | 151 | return AE_ERROR; |
156 | } | 152 | } |
@@ -197,6 +193,7 @@ static acpi_status acpi_gpiochip_request_interrupt(struct acpi_resource *ares, | |||
197 | event->handle = evt_handle; | 193 | event->handle = evt_handle; |
198 | event->irq = irq; | 194 | event->irq = irq; |
199 | event->pin = pin; | 195 | event->pin = pin; |
196 | event->desc = desc; | ||
200 | 197 | ||
201 | ret = request_threaded_irq(event->irq, NULL, handler, irqflags, | 198 | ret = request_threaded_irq(event->irq, NULL, handler, irqflags, |
202 | "ACPI:Event", event); | 199 | "ACPI:Event", event); |
@@ -280,7 +277,7 @@ void acpi_gpiochip_free_interrupts(struct gpio_chip *chip) | |||
280 | struct gpio_desc *desc; | 277 | struct gpio_desc *desc; |
281 | 278 | ||
282 | free_irq(event->irq, event); | 279 | free_irq(event->irq, event); |
283 | desc = gpiochip_get_desc(chip, event->pin); | 280 | desc = event->desc; |
284 | if (WARN_ON(IS_ERR(desc))) | 281 | if (WARN_ON(IS_ERR(desc))) |
285 | continue; | 282 | continue; |
286 | gpio_unlock_as_irq(chip, event->pin); | 283 | gpio_unlock_as_irq(chip, event->pin); |
@@ -409,26 +406,20 @@ acpi_gpio_adr_space_handler(u32 function, acpi_physical_address address, | |||
409 | struct gpio_desc *desc; | 406 | struct gpio_desc *desc; |
410 | bool found; | 407 | bool found; |
411 | 408 | ||
412 | desc = gpiochip_get_desc(chip, pin); | ||
413 | if (IS_ERR(desc)) { | ||
414 | status = AE_ERROR; | ||
415 | goto out; | ||
416 | } | ||
417 | |||
418 | mutex_lock(&achip->conn_lock); | 409 | mutex_lock(&achip->conn_lock); |
419 | 410 | ||
420 | found = false; | 411 | found = false; |
421 | list_for_each_entry(conn, &achip->conns, node) { | 412 | list_for_each_entry(conn, &achip->conns, node) { |
422 | if (conn->desc == desc) { | 413 | if (conn->pin == pin) { |
423 | found = true; | 414 | found = true; |
415 | desc = conn->desc; | ||
424 | break; | 416 | break; |
425 | } | 417 | } |
426 | } | 418 | } |
427 | if (!found) { | 419 | if (!found) { |
428 | int ret; | 420 | desc = gpiochip_request_own_desc(chip, pin, |
429 | 421 | "ACPI:OpRegion"); | |
430 | ret = gpiochip_request_own_desc(desc, "ACPI:OpRegion"); | 422 | if (IS_ERR(desc)) { |
431 | if (ret) { | ||
432 | status = AE_ERROR; | 423 | status = AE_ERROR; |
433 | mutex_unlock(&achip->conn_lock); | 424 | mutex_unlock(&achip->conn_lock); |
434 | goto out; | 425 | goto out; |
@@ -465,6 +456,7 @@ acpi_gpio_adr_space_handler(u32 function, acpi_physical_address address, | |||
465 | goto out; | 456 | goto out; |
466 | } | 457 | } |
467 | 458 | ||
459 | conn->pin = pin; | ||
468 | conn->desc = desc; | 460 | conn->desc = desc; |
469 | list_add_tail(&conn->node, &achip->conns); | 461 | list_add_tail(&conn->node, &achip->conns); |
470 | } | 462 | } |
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index c68d037de656..e8e98ca25ec7 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c | |||
@@ -308,10 +308,9 @@ static void gpiochip_irqchip_remove(struct gpio_chip *gpiochip); | |||
308 | * | 308 | * |
309 | * A gpio_chip with any GPIOs still requested may not be removed. | 309 | * A gpio_chip with any GPIOs still requested may not be removed. |
310 | */ | 310 | */ |
311 | int gpiochip_remove(struct gpio_chip *chip) | 311 | void gpiochip_remove(struct gpio_chip *chip) |
312 | { | 312 | { |
313 | unsigned long flags; | 313 | unsigned long flags; |
314 | int status = 0; | ||
315 | unsigned id; | 314 | unsigned id; |
316 | 315 | ||
317 | acpi_gpiochip_remove(chip); | 316 | acpi_gpiochip_remove(chip); |
@@ -323,24 +322,15 @@ int gpiochip_remove(struct gpio_chip *chip) | |||
323 | of_gpiochip_remove(chip); | 322 | of_gpiochip_remove(chip); |
324 | 323 | ||
325 | for (id = 0; id < chip->ngpio; id++) { | 324 | for (id = 0; id < chip->ngpio; id++) { |
326 | if (test_bit(FLAG_REQUESTED, &chip->desc[id].flags)) { | 325 | if (test_bit(FLAG_REQUESTED, &chip->desc[id].flags)) |
327 | status = -EBUSY; | 326 | dev_crit(chip->dev, "REMOVING GPIOCHIP WITH GPIOS STILL REQUESTED\n"); |
328 | break; | ||
329 | } | ||
330 | } | ||
331 | if (status == 0) { | ||
332 | for (id = 0; id < chip->ngpio; id++) | ||
333 | chip->desc[id].chip = NULL; | ||
334 | |||
335 | list_del(&chip->list); | ||
336 | } | 327 | } |
328 | for (id = 0; id < chip->ngpio; id++) | ||
329 | chip->desc[id].chip = NULL; | ||
337 | 330 | ||
331 | list_del(&chip->list); | ||
338 | spin_unlock_irqrestore(&gpio_lock, flags); | 332 | spin_unlock_irqrestore(&gpio_lock, flags); |
339 | 333 | gpiochip_unexport(chip); | |
340 | if (status == 0) | ||
341 | gpiochip_unexport(chip); | ||
342 | |||
343 | return status; | ||
344 | } | 334 | } |
345 | EXPORT_SYMBOL_GPL(gpiochip_remove); | 335 | EXPORT_SYMBOL_GPL(gpiochip_remove); |
346 | 336 | ||
@@ -395,30 +385,47 @@ static struct gpio_chip *find_chip_by_name(const char *name) | |||
395 | */ | 385 | */ |
396 | 386 | ||
397 | /** | 387 | /** |
398 | * gpiochip_add_chained_irqchip() - adds a chained irqchip to a gpiochip | 388 | * gpiochip_set_chained_irqchip() - sets a chained irqchip to a gpiochip |
399 | * @gpiochip: the gpiochip to add the irqchip to | 389 | * @gpiochip: the gpiochip to set the irqchip chain to |
400 | * @irqchip: the irqchip to add to the gpiochip | 390 | * @irqchip: the irqchip to chain to the gpiochip |
401 | * @parent_irq: the irq number corresponding to the parent IRQ for this | 391 | * @parent_irq: the irq number corresponding to the parent IRQ for this |
402 | * chained irqchip | 392 | * chained irqchip |
403 | * @parent_handler: the parent interrupt handler for the accumulated IRQ | 393 | * @parent_handler: the parent interrupt handler for the accumulated IRQ |
404 | * coming out of the gpiochip | 394 | * coming out of the gpiochip. If the interrupt is nested rather than |
395 | * cascaded, pass NULL in this handler argument | ||
405 | */ | 396 | */ |
406 | void gpiochip_set_chained_irqchip(struct gpio_chip *gpiochip, | 397 | void gpiochip_set_chained_irqchip(struct gpio_chip *gpiochip, |
407 | struct irq_chip *irqchip, | 398 | struct irq_chip *irqchip, |
408 | int parent_irq, | 399 | int parent_irq, |
409 | irq_flow_handler_t parent_handler) | 400 | irq_flow_handler_t parent_handler) |
410 | { | 401 | { |
411 | if (gpiochip->can_sleep) { | 402 | unsigned int offset; |
412 | chip_err(gpiochip, "you cannot have chained interrupts on a chip that may sleep\n"); | 403 | |
404 | if (!gpiochip->irqdomain) { | ||
405 | chip_err(gpiochip, "called %s before setting up irqchip\n", | ||
406 | __func__); | ||
413 | return; | 407 | return; |
414 | } | 408 | } |
415 | 409 | ||
416 | /* | 410 | if (parent_handler) { |
417 | * The parent irqchip is already using the chip_data for this | 411 | if (gpiochip->can_sleep) { |
418 | * irqchip, so our callbacks simply use the handler_data. | 412 | chip_err(gpiochip, |
419 | */ | 413 | "you cannot have chained interrupts on a " |
420 | irq_set_handler_data(parent_irq, gpiochip); | 414 | "chip that may sleep\n"); |
421 | irq_set_chained_handler(parent_irq, parent_handler); | 415 | return; |
416 | } | ||
417 | /* | ||
418 | * The parent irqchip is already using the chip_data for this | ||
419 | * irqchip, so our callbacks simply use the handler_data. | ||
420 | */ | ||
421 | irq_set_handler_data(parent_irq, gpiochip); | ||
422 | irq_set_chained_handler(parent_irq, parent_handler); | ||
423 | } | ||
424 | |||
425 | /* Set the parent IRQ for all affected IRQs */ | ||
426 | for (offset = 0; offset < gpiochip->ngpio; offset++) | ||
427 | irq_set_parent(irq_find_mapping(gpiochip->irqdomain, offset), | ||
428 | parent_irq); | ||
422 | } | 429 | } |
423 | EXPORT_SYMBOL_GPL(gpiochip_set_chained_irqchip); | 430 | EXPORT_SYMBOL_GPL(gpiochip_set_chained_irqchip); |
424 | 431 | ||
@@ -447,7 +454,7 @@ static int gpiochip_irq_map(struct irq_domain *d, unsigned int irq, | |||
447 | irq_set_lockdep_class(irq, &gpiochip_irq_lock_class); | 454 | irq_set_lockdep_class(irq, &gpiochip_irq_lock_class); |
448 | irq_set_chip_and_handler(irq, chip->irqchip, chip->irq_handler); | 455 | irq_set_chip_and_handler(irq, chip->irqchip, chip->irq_handler); |
449 | /* Chips that can sleep need nested thread handlers */ | 456 | /* Chips that can sleep need nested thread handlers */ |
450 | if (chip->can_sleep) | 457 | if (chip->can_sleep && !chip->irq_not_threaded) |
451 | irq_set_nested_thread(irq, 1); | 458 | irq_set_nested_thread(irq, 1); |
452 | #ifdef CONFIG_ARM | 459 | #ifdef CONFIG_ARM |
453 | set_irq_flags(irq, IRQF_VALID); | 460 | set_irq_flags(irq, IRQF_VALID); |
@@ -524,7 +531,8 @@ static void gpiochip_irqchip_remove(struct gpio_chip *gpiochip) | |||
524 | /* Remove all IRQ mappings and delete the domain */ | 531 | /* Remove all IRQ mappings and delete the domain */ |
525 | if (gpiochip->irqdomain) { | 532 | if (gpiochip->irqdomain) { |
526 | for (offset = 0; offset < gpiochip->ngpio; offset++) | 533 | for (offset = 0; offset < gpiochip->ngpio; offset++) |
527 | irq_dispose_mapping(gpiochip->irq_base + offset); | 534 | irq_dispose_mapping( |
535 | irq_find_mapping(gpiochip->irqdomain, offset)); | ||
528 | irq_domain_remove(gpiochip->irqdomain); | 536 | irq_domain_remove(gpiochip->irqdomain); |
529 | } | 537 | } |
530 | 538 | ||
@@ -895,12 +903,22 @@ EXPORT_SYMBOL_GPL(gpiochip_is_requested); | |||
895 | * allows the GPIO chip module to be unloaded as needed (we assume that the | 903 | * allows the GPIO chip module to be unloaded as needed (we assume that the |
896 | * GPIO chip driver handles freeing the GPIOs it has requested). | 904 | * GPIO chip driver handles freeing the GPIOs it has requested). |
897 | */ | 905 | */ |
898 | int gpiochip_request_own_desc(struct gpio_desc *desc, const char *label) | 906 | struct gpio_desc *gpiochip_request_own_desc(struct gpio_chip *chip, u16 hwnum, |
907 | const char *label) | ||
899 | { | 908 | { |
900 | if (!desc || !desc->chip) | 909 | struct gpio_desc *desc = gpiochip_get_desc(chip, hwnum); |
901 | return -EINVAL; | 910 | int err; |
902 | 911 | ||
903 | return __gpiod_request(desc, label); | 912 | if (IS_ERR(desc)) { |
913 | chip_err(chip, "failed to get GPIO descriptor\n"); | ||
914 | return desc; | ||
915 | } | ||
916 | |||
917 | err = __gpiod_request(desc, label); | ||
918 | if (err < 0) | ||
919 | return ERR_PTR(err); | ||
920 | |||
921 | return desc; | ||
904 | } | 922 | } |
905 | EXPORT_SYMBOL_GPL(gpiochip_request_own_desc); | 923 | EXPORT_SYMBOL_GPL(gpiochip_request_own_desc); |
906 | 924 | ||
@@ -1652,7 +1670,7 @@ struct gpio_desc *__must_check __gpiod_get_index(struct device *dev, | |||
1652 | * a result. In that case, use platform lookup as a fallback. | 1670 | * a result. In that case, use platform lookup as a fallback. |
1653 | */ | 1671 | */ |
1654 | if (!desc || desc == ERR_PTR(-ENOENT)) { | 1672 | if (!desc || desc == ERR_PTR(-ENOENT)) { |
1655 | dev_dbg(dev, "using lookup tables for GPIO lookup"); | 1673 | dev_dbg(dev, "using lookup tables for GPIO lookup\n"); |
1656 | desc = gpiod_find(dev, con_id, idx, &lookupflags); | 1674 | desc = gpiod_find(dev, con_id, idx, &lookupflags); |
1657 | } | 1675 | } |
1658 | 1676 | ||
diff --git a/drivers/hid/hid-cp2112.c b/drivers/hid/hid-cp2112.c index a822db5a8338..3318de690e00 100644 --- a/drivers/hid/hid-cp2112.c +++ b/drivers/hid/hid-cp2112.c | |||
@@ -1069,8 +1069,7 @@ static int cp2112_probe(struct hid_device *hdev, const struct hid_device_id *id) | |||
1069 | return ret; | 1069 | return ret; |
1070 | 1070 | ||
1071 | err_gpiochip_remove: | 1071 | err_gpiochip_remove: |
1072 | if (gpiochip_remove(&dev->gc) < 0) | 1072 | gpiochip_remove(&dev->gc); |
1073 | hid_err(hdev, "error removing gpio chip\n"); | ||
1074 | err_free_i2c: | 1073 | err_free_i2c: |
1075 | i2c_del_adapter(&dev->adap); | 1074 | i2c_del_adapter(&dev->adap); |
1076 | err_free_dev: | 1075 | err_free_dev: |
@@ -1089,8 +1088,7 @@ static void cp2112_remove(struct hid_device *hdev) | |||
1089 | struct cp2112_device *dev = hid_get_drvdata(hdev); | 1088 | struct cp2112_device *dev = hid_get_drvdata(hdev); |
1090 | 1089 | ||
1091 | sysfs_remove_group(&hdev->dev.kobj, &cp2112_attr_group); | 1090 | sysfs_remove_group(&hdev->dev.kobj, &cp2112_attr_group); |
1092 | if (gpiochip_remove(&dev->gc)) | 1091 | gpiochip_remove(&dev->gc); |
1093 | hid_err(hdev, "unable to remove gpio chip\n"); | ||
1094 | i2c_del_adapter(&dev->adap); | 1092 | i2c_del_adapter(&dev->adap); |
1095 | /* i2c_del_adapter has finished removing all i2c devices from our | 1093 | /* i2c_del_adapter has finished removing all i2c devices from our |
1096 | * adapter. Well behaved devices should no longer call our cp2112_xfer | 1094 | * adapter. Well behaved devices should no longer call our cp2112_xfer |
diff --git a/drivers/input/keyboard/adp5588-keys.c b/drivers/input/keyboard/adp5588-keys.c index 5ef7fcf0e250..b97ed443e0a4 100644 --- a/drivers/input/keyboard/adp5588-keys.c +++ b/drivers/input/keyboard/adp5588-keys.c | |||
@@ -251,9 +251,7 @@ static void adp5588_gpio_remove(struct adp5588_kpad *kpad) | |||
251 | dev_warn(dev, "teardown failed %d\n", error); | 251 | dev_warn(dev, "teardown failed %d\n", error); |
252 | } | 252 | } |
253 | 253 | ||
254 | error = gpiochip_remove(&kpad->gc); | 254 | gpiochip_remove(&kpad->gc); |
255 | if (error) | ||
256 | dev_warn(dev, "gpiochip_remove failed %d\n", error); | ||
257 | } | 255 | } |
258 | #else | 256 | #else |
259 | static inline int adp5588_gpio_add(struct adp5588_kpad *kpad) | 257 | static inline int adp5588_gpio_add(struct adp5588_kpad *kpad) |
diff --git a/drivers/input/keyboard/adp5589-keys.c b/drivers/input/keyboard/adp5589-keys.c index 6329549bf6ad..a45267729dfc 100644 --- a/drivers/input/keyboard/adp5589-keys.c +++ b/drivers/input/keyboard/adp5589-keys.c | |||
@@ -567,9 +567,7 @@ static void adp5589_gpio_remove(struct adp5589_kpad *kpad) | |||
567 | dev_warn(dev, "teardown failed %d\n", error); | 567 | dev_warn(dev, "teardown failed %d\n", error); |
568 | } | 568 | } |
569 | 569 | ||
570 | error = gpiochip_remove(&kpad->gc); | 570 | gpiochip_remove(&kpad->gc); |
571 | if (error) | ||
572 | dev_warn(dev, "gpiochip_remove failed %d\n", error); | ||
573 | } | 571 | } |
574 | #else | 572 | #else |
575 | static inline int adp5589_gpio_add(struct adp5589_kpad *kpad) | 573 | static inline int adp5589_gpio_add(struct adp5589_kpad *kpad) |
diff --git a/drivers/input/touchscreen/ad7879.c b/drivers/input/touchscreen/ad7879.c index fce590677b7b..1eb9d3c20886 100644 --- a/drivers/input/touchscreen/ad7879.c +++ b/drivers/input/touchscreen/ad7879.c | |||
@@ -470,14 +470,10 @@ static int ad7879_gpio_add(struct ad7879 *ts, | |||
470 | static void ad7879_gpio_remove(struct ad7879 *ts) | 470 | static void ad7879_gpio_remove(struct ad7879 *ts) |
471 | { | 471 | { |
472 | const struct ad7879_platform_data *pdata = dev_get_platdata(ts->dev); | 472 | const struct ad7879_platform_data *pdata = dev_get_platdata(ts->dev); |
473 | int ret; | ||
474 | 473 | ||
475 | if (pdata->gpio_export) { | 474 | if (pdata->gpio_export) |
476 | ret = gpiochip_remove(&ts->gc); | 475 | gpiochip_remove(&ts->gc); |
477 | if (ret) | 476 | |
478 | dev_err(ts->dev, "failed to remove gpio %d\n", | ||
479 | ts->gc.base); | ||
480 | } | ||
481 | } | 477 | } |
482 | #else | 478 | #else |
483 | static inline int ad7879_gpio_add(struct ad7879 *ts, | 479 | static inline int ad7879_gpio_add(struct ad7879 *ts, |
diff --git a/drivers/leds/leds-pca9532.c b/drivers/leds/leds-pca9532.c index 4a0e786b7832..5a6363d161a2 100644 --- a/drivers/leds/leds-pca9532.c +++ b/drivers/leds/leds-pca9532.c | |||
@@ -319,14 +319,8 @@ static int pca9532_destroy_devices(struct pca9532_data *data, int n_devs) | |||
319 | } | 319 | } |
320 | 320 | ||
321 | #ifdef CONFIG_LEDS_PCA9532_GPIO | 321 | #ifdef CONFIG_LEDS_PCA9532_GPIO |
322 | if (data->gpio.dev) { | 322 | if (data->gpio.dev) |
323 | int err = gpiochip_remove(&data->gpio); | 323 | gpiochip_remove(&data->gpio); |
324 | if (err) { | ||
325 | dev_err(&data->client->dev, "%s failed, %d\n", | ||
326 | "gpiochip_remove()", err); | ||
327 | return err; | ||
328 | } | ||
329 | } | ||
330 | #endif | 324 | #endif |
331 | 325 | ||
332 | return 0; | 326 | return 0; |
diff --git a/drivers/leds/leds-tca6507.c b/drivers/leds/leds-tca6507.c index 3d9e267a56c4..20fa8e77f186 100644 --- a/drivers/leds/leds-tca6507.c +++ b/drivers/leds/leds-tca6507.c | |||
@@ -667,11 +667,8 @@ static int tca6507_probe_gpios(struct i2c_client *client, | |||
667 | 667 | ||
668 | static void tca6507_remove_gpio(struct tca6507_chip *tca) | 668 | static void tca6507_remove_gpio(struct tca6507_chip *tca) |
669 | { | 669 | { |
670 | if (tca->gpio.ngpio) { | 670 | if (tca->gpio.ngpio) |
671 | int err = gpiochip_remove(&tca->gpio); | 671 | gpiochip_remove(&tca->gpio); |
672 | dev_err(&tca->client->dev, "%s failed, %d\n", | ||
673 | "gpiochip_remove()", err); | ||
674 | } | ||
675 | } | 672 | } |
676 | #else /* CONFIG_GPIOLIB */ | 673 | #else /* CONFIG_GPIOLIB */ |
677 | static int tca6507_probe_gpios(struct i2c_client *client, | 674 | static int tca6507_probe_gpios(struct i2c_client *client, |
diff --git a/drivers/media/dvb-frontends/cxd2820r_core.c b/drivers/media/dvb-frontends/cxd2820r_core.c index 03930d5e9fea..51ef89312615 100644 --- a/drivers/media/dvb-frontends/cxd2820r_core.c +++ b/drivers/media/dvb-frontends/cxd2820r_core.c | |||
@@ -584,18 +584,14 @@ static int cxd2820r_get_frontend_algo(struct dvb_frontend *fe) | |||
584 | static void cxd2820r_release(struct dvb_frontend *fe) | 584 | static void cxd2820r_release(struct dvb_frontend *fe) |
585 | { | 585 | { |
586 | struct cxd2820r_priv *priv = fe->demodulator_priv; | 586 | struct cxd2820r_priv *priv = fe->demodulator_priv; |
587 | int uninitialized_var(ret); /* silence compiler warning */ | ||
588 | 587 | ||
589 | dev_dbg(&priv->i2c->dev, "%s\n", __func__); | 588 | dev_dbg(&priv->i2c->dev, "%s\n", __func__); |
590 | 589 | ||
591 | #ifdef CONFIG_GPIOLIB | 590 | #ifdef CONFIG_GPIOLIB |
592 | /* remove GPIOs */ | 591 | /* remove GPIOs */ |
593 | if (priv->gpio_chip.label) { | 592 | if (priv->gpio_chip.label) |
594 | ret = gpiochip_remove(&priv->gpio_chip); | 593 | gpiochip_remove(&priv->gpio_chip); |
595 | if (ret) | 594 | |
596 | dev_err(&priv->i2c->dev, "%s: gpiochip_remove() " \ | ||
597 | "failed=%d\n", KBUILD_MODNAME, ret); | ||
598 | } | ||
599 | #endif | 595 | #endif |
600 | kfree(priv); | 596 | kfree(priv); |
601 | return; | 597 | return; |
diff --git a/drivers/mfd/asic3.c b/drivers/mfd/asic3.c index 9fc4186d4132..977bd3a3eed0 100644 --- a/drivers/mfd/asic3.c +++ b/drivers/mfd/asic3.c | |||
@@ -605,7 +605,8 @@ static int asic3_gpio_remove(struct platform_device *pdev) | |||
605 | { | 605 | { |
606 | struct asic3 *asic = platform_get_drvdata(pdev); | 606 | struct asic3 *asic = platform_get_drvdata(pdev); |
607 | 607 | ||
608 | return gpiochip_remove(&asic->gpio); | 608 | gpiochip_remove(&asic->gpio); |
609 | return 0; | ||
609 | } | 610 | } |
610 | 611 | ||
611 | static void asic3_clk_enable(struct asic3 *asic, struct asic3_clk *clk) | 612 | static void asic3_clk_enable(struct asic3 *asic, struct asic3_clk *clk) |
diff --git a/drivers/mfd/htc-i2cpld.c b/drivers/mfd/htc-i2cpld.c index 6bdb78c2ac77..adbbce0ff630 100644 --- a/drivers/mfd/htc-i2cpld.c +++ b/drivers/mfd/htc-i2cpld.c | |||
@@ -481,15 +481,9 @@ static int htcpld_register_chip_gpio( | |||
481 | 481 | ||
482 | ret = gpiochip_add(&(chip->chip_in)); | 482 | ret = gpiochip_add(&(chip->chip_in)); |
483 | if (ret) { | 483 | if (ret) { |
484 | int error; | ||
485 | |||
486 | dev_warn(dev, "Unable to register input GPIOs for 0x%x: %d\n", | 484 | dev_warn(dev, "Unable to register input GPIOs for 0x%x: %d\n", |
487 | plat_chip_data->addr, ret); | 485 | plat_chip_data->addr, ret); |
488 | 486 | gpiochip_remove(&(chip->chip_out)); | |
489 | error = gpiochip_remove(&(chip->chip_out)); | ||
490 | if (error) | ||
491 | dev_warn(dev, "Error while trying to unregister gpio chip: %d\n", error); | ||
492 | |||
493 | return ret; | 487 | return ret; |
494 | } | 488 | } |
495 | 489 | ||
diff --git a/drivers/mfd/sm501.c b/drivers/mfd/sm501.c index 81e6d0932bf0..02027b7f1223 100644 --- a/drivers/mfd/sm501.c +++ b/drivers/mfd/sm501.c | |||
@@ -1047,7 +1047,6 @@ static int sm501_register_gpio(struct sm501_devdata *sm) | |||
1047 | struct sm501_gpio *gpio = &sm->gpio; | 1047 | struct sm501_gpio *gpio = &sm->gpio; |
1048 | resource_size_t iobase = sm->io_res->start + SM501_GPIO; | 1048 | resource_size_t iobase = sm->io_res->start + SM501_GPIO; |
1049 | int ret; | 1049 | int ret; |
1050 | int tmp; | ||
1051 | 1050 | ||
1052 | dev_dbg(sm->dev, "registering gpio block %08llx\n", | 1051 | dev_dbg(sm->dev, "registering gpio block %08llx\n", |
1053 | (unsigned long long)iobase); | 1052 | (unsigned long long)iobase); |
@@ -1086,11 +1085,7 @@ static int sm501_register_gpio(struct sm501_devdata *sm) | |||
1086 | return 0; | 1085 | return 0; |
1087 | 1086 | ||
1088 | err_low_chip: | 1087 | err_low_chip: |
1089 | tmp = gpiochip_remove(&gpio->low.gpio); | 1088 | gpiochip_remove(&gpio->low.gpio); |
1090 | if (tmp) { | ||
1091 | dev_err(sm->dev, "cannot remove low chip, cannot tidy up\n"); | ||
1092 | return ret; | ||
1093 | } | ||
1094 | 1089 | ||
1095 | err_mapped: | 1090 | err_mapped: |
1096 | iounmap(gpio->regs); | 1091 | iounmap(gpio->regs); |
@@ -1105,18 +1100,12 @@ static int sm501_register_gpio(struct sm501_devdata *sm) | |||
1105 | static void sm501_gpio_remove(struct sm501_devdata *sm) | 1100 | static void sm501_gpio_remove(struct sm501_devdata *sm) |
1106 | { | 1101 | { |
1107 | struct sm501_gpio *gpio = &sm->gpio; | 1102 | struct sm501_gpio *gpio = &sm->gpio; |
1108 | int ret; | ||
1109 | 1103 | ||
1110 | if (!sm->gpio.registered) | 1104 | if (!sm->gpio.registered) |
1111 | return; | 1105 | return; |
1112 | 1106 | ||
1113 | ret = gpiochip_remove(&gpio->low.gpio); | 1107 | gpiochip_remove(&gpio->low.gpio); |
1114 | if (ret) | 1108 | gpiochip_remove(&gpio->high.gpio); |
1115 | dev_err(sm->dev, "cannot remove low chip, cannot tidy up\n"); | ||
1116 | |||
1117 | ret = gpiochip_remove(&gpio->high.gpio); | ||
1118 | if (ret) | ||
1119 | dev_err(sm->dev, "cannot remove high chip, cannot tidy up\n"); | ||
1120 | 1109 | ||
1121 | iounmap(gpio->regs); | 1110 | iounmap(gpio->regs); |
1122 | release_resource(gpio->regs_res); | 1111 | release_resource(gpio->regs_res); |
diff --git a/drivers/mfd/tc6393xb.c b/drivers/mfd/tc6393xb.c index 11c19e538551..4fac16bcd732 100644 --- a/drivers/mfd/tc6393xb.c +++ b/drivers/mfd/tc6393xb.c | |||
@@ -607,7 +607,7 @@ static int tc6393xb_probe(struct platform_device *dev) | |||
607 | struct tc6393xb_platform_data *tcpd = dev_get_platdata(&dev->dev); | 607 | struct tc6393xb_platform_data *tcpd = dev_get_platdata(&dev->dev); |
608 | struct tc6393xb *tc6393xb; | 608 | struct tc6393xb *tc6393xb; |
609 | struct resource *iomem, *rscr; | 609 | struct resource *iomem, *rscr; |
610 | int ret, temp; | 610 | int ret; |
611 | 611 | ||
612 | iomem = platform_get_resource(dev, IORESOURCE_MEM, 0); | 612 | iomem = platform_get_resource(dev, IORESOURCE_MEM, 0); |
613 | if (!iomem) | 613 | if (!iomem) |
@@ -714,7 +714,7 @@ err_setup: | |||
714 | 714 | ||
715 | err_gpio_add: | 715 | err_gpio_add: |
716 | if (tc6393xb->gpio.base != -1) | 716 | if (tc6393xb->gpio.base != -1) |
717 | temp = gpiochip_remove(&tc6393xb->gpio); | 717 | gpiochip_remove(&tc6393xb->gpio); |
718 | tcpd->disable(dev); | 718 | tcpd->disable(dev); |
719 | err_enable: | 719 | err_enable: |
720 | clk_disable(tc6393xb->clk); | 720 | clk_disable(tc6393xb->clk); |
@@ -744,13 +744,8 @@ static int tc6393xb_remove(struct platform_device *dev) | |||
744 | 744 | ||
745 | tc6393xb_detach_irq(dev); | 745 | tc6393xb_detach_irq(dev); |
746 | 746 | ||
747 | if (tc6393xb->gpio.base != -1) { | 747 | if (tc6393xb->gpio.base != -1) |
748 | ret = gpiochip_remove(&tc6393xb->gpio); | 748 | gpiochip_remove(&tc6393xb->gpio); |
749 | if (ret) { | ||
750 | dev_err(&dev->dev, "Can't remove gpio chip: %d\n", ret); | ||
751 | return ret; | ||
752 | } | ||
753 | } | ||
754 | 749 | ||
755 | ret = tcpd->disable(dev); | 750 | ret = tcpd->disable(dev); |
756 | clk_disable(tc6393xb->clk); | 751 | clk_disable(tc6393xb->clk); |
diff --git a/drivers/mfd/ucb1x00-core.c b/drivers/mfd/ucb1x00-core.c index 153d595afaac..58ea9fdd3a15 100644 --- a/drivers/mfd/ucb1x00-core.c +++ b/drivers/mfd/ucb1x00-core.c | |||
@@ -621,7 +621,6 @@ static void ucb1x00_remove(struct mcp *mcp) | |||
621 | struct ucb1x00_plat_data *pdata = mcp->attached_device.platform_data; | 621 | struct ucb1x00_plat_data *pdata = mcp->attached_device.platform_data; |
622 | struct ucb1x00 *ucb = mcp_get_drvdata(mcp); | 622 | struct ucb1x00 *ucb = mcp_get_drvdata(mcp); |
623 | struct list_head *l, *n; | 623 | struct list_head *l, *n; |
624 | int ret; | ||
625 | 624 | ||
626 | mutex_lock(&ucb1x00_mutex); | 625 | mutex_lock(&ucb1x00_mutex); |
627 | list_del(&ucb->node); | 626 | list_del(&ucb->node); |
@@ -631,11 +630,8 @@ static void ucb1x00_remove(struct mcp *mcp) | |||
631 | } | 630 | } |
632 | mutex_unlock(&ucb1x00_mutex); | 631 | mutex_unlock(&ucb1x00_mutex); |
633 | 632 | ||
634 | if (ucb->gpio.base != -1) { | 633 | if (ucb->gpio.base != -1) |
635 | ret = gpiochip_remove(&ucb->gpio); | 634 | gpiochip_remove(&ucb->gpio); |
636 | if (ret) | ||
637 | dev_err(&ucb->dev, "Can't remove gpio chip: %d\n", ret); | ||
638 | } | ||
639 | 635 | ||
640 | irq_set_chained_handler(ucb->irq, NULL); | 636 | irq_set_chained_handler(ucb->irq, NULL); |
641 | irq_free_descs(ucb->irq_base, 16); | 637 | irq_free_descs(ucb->irq_base, 16); |
diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig index 64d06b52f98a..c6a66de6ed72 100644 --- a/drivers/pinctrl/Kconfig +++ b/drivers/pinctrl/Kconfig | |||
@@ -86,7 +86,7 @@ config PINCTRL_BCM2835 | |||
86 | 86 | ||
87 | config PINCTRL_BCM281XX | 87 | config PINCTRL_BCM281XX |
88 | bool "Broadcom BCM281xx pinctrl driver" | 88 | bool "Broadcom BCM281xx pinctrl driver" |
89 | depends on OF | 89 | depends on OF && (ARCH_BCM_MOBILE || COMPILE_TEST) |
90 | select PINMUX | 90 | select PINMUX |
91 | select PINCONF | 91 | select PINCONF |
92 | select GENERIC_PINCONF | 92 | select GENERIC_PINCONF |
diff --git a/drivers/pinctrl/nomadik/pinctrl-abx500.c b/drivers/pinctrl/nomadik/pinctrl-abx500.c index 47f493149863..228972827132 100644 --- a/drivers/pinctrl/nomadik/pinctrl-abx500.c +++ b/drivers/pinctrl/nomadik/pinctrl-abx500.c | |||
@@ -1174,7 +1174,7 @@ static int abx500_gpio_probe(struct platform_device *pdev) | |||
1174 | const struct of_device_id *match; | 1174 | const struct of_device_id *match; |
1175 | struct abx500_pinctrl *pct; | 1175 | struct abx500_pinctrl *pct; |
1176 | unsigned int id = -1; | 1176 | unsigned int id = -1; |
1177 | int ret, err; | 1177 | int ret; |
1178 | int i; | 1178 | int i; |
1179 | 1179 | ||
1180 | if (!np) { | 1180 | if (!np) { |
@@ -1266,10 +1266,7 @@ static int abx500_gpio_probe(struct platform_device *pdev) | |||
1266 | return 0; | 1266 | return 0; |
1267 | 1267 | ||
1268 | out_rem_chip: | 1268 | out_rem_chip: |
1269 | err = gpiochip_remove(&pct->chip); | 1269 | gpiochip_remove(&pct->chip); |
1270 | if (err) | ||
1271 | dev_info(&pdev->dev, "failed to remove gpiochip\n"); | ||
1272 | |||
1273 | return ret; | 1270 | return ret; |
1274 | } | 1271 | } |
1275 | 1272 | ||
@@ -1280,15 +1277,8 @@ out_rem_chip: | |||
1280 | static int abx500_gpio_remove(struct platform_device *pdev) | 1277 | static int abx500_gpio_remove(struct platform_device *pdev) |
1281 | { | 1278 | { |
1282 | struct abx500_pinctrl *pct = platform_get_drvdata(pdev); | 1279 | struct abx500_pinctrl *pct = platform_get_drvdata(pdev); |
1283 | int ret; | ||
1284 | |||
1285 | ret = gpiochip_remove(&pct->chip); | ||
1286 | if (ret < 0) { | ||
1287 | dev_err(pct->dev, "unable to remove gpiochip: %d\n", | ||
1288 | ret); | ||
1289 | return ret; | ||
1290 | } | ||
1291 | 1280 | ||
1281 | gpiochip_remove(&pct->chip); | ||
1292 | return 0; | 1282 | return 0; |
1293 | } | 1283 | } |
1294 | 1284 | ||
diff --git a/drivers/pinctrl/nomadik/pinctrl-nomadik.c b/drivers/pinctrl/nomadik/pinctrl-nomadik.c index 3c29d9187146..746db6acf648 100644 --- a/drivers/pinctrl/nomadik/pinctrl-nomadik.c +++ b/drivers/pinctrl/nomadik/pinctrl-nomadik.c | |||
@@ -1276,7 +1276,7 @@ static int nmk_gpio_probe(struct platform_device *dev) | |||
1276 | IRQ_TYPE_EDGE_FALLING); | 1276 | IRQ_TYPE_EDGE_FALLING); |
1277 | if (ret) { | 1277 | if (ret) { |
1278 | dev_err(&dev->dev, "could not add irqchip\n"); | 1278 | dev_err(&dev->dev, "could not add irqchip\n"); |
1279 | ret = gpiochip_remove(&nmk_chip->chip); | 1279 | gpiochip_remove(&nmk_chip->chip); |
1280 | return -ENODEV; | 1280 | return -ENODEV; |
1281 | } | 1281 | } |
1282 | /* Then register the chain on the parent IRQ */ | 1282 | /* Then register the chain on the parent IRQ */ |
diff --git a/drivers/pinctrl/qcom/pinctrl-msm.c b/drivers/pinctrl/qcom/pinctrl-msm.c index d30dddd21323..e730935fa457 100644 --- a/drivers/pinctrl/qcom/pinctrl-msm.c +++ b/drivers/pinctrl/qcom/pinctrl-msm.c | |||
@@ -936,14 +936,8 @@ EXPORT_SYMBOL(msm_pinctrl_probe); | |||
936 | int msm_pinctrl_remove(struct platform_device *pdev) | 936 | int msm_pinctrl_remove(struct platform_device *pdev) |
937 | { | 937 | { |
938 | struct msm_pinctrl *pctrl = platform_get_drvdata(pdev); | 938 | struct msm_pinctrl *pctrl = platform_get_drvdata(pdev); |
939 | int ret; | ||
940 | |||
941 | ret = gpiochip_remove(&pctrl->chip); | ||
942 | if (ret) { | ||
943 | dev_err(&pdev->dev, "Failed to remove gpiochip\n"); | ||
944 | return ret; | ||
945 | } | ||
946 | 939 | ||
940 | gpiochip_remove(&pctrl->chip); | ||
947 | pinctrl_unregister(pctrl->pctrl); | 941 | pinctrl_unregister(pctrl->pctrl); |
948 | 942 | ||
949 | unregister_restart_handler(&pctrl->restart_nb); | 943 | unregister_restart_handler(&pctrl->restart_nb); |
diff --git a/drivers/pinctrl/samsung/pinctrl-exynos5440.c b/drivers/pinctrl/samsung/pinctrl-exynos5440.c index b995ec2c5d16..88acfc0efd54 100644 --- a/drivers/pinctrl/samsung/pinctrl-exynos5440.c +++ b/drivers/pinctrl/samsung/pinctrl-exynos5440.c | |||
@@ -874,11 +874,7 @@ static int exynos5440_gpiolib_register(struct platform_device *pdev, | |||
874 | static int exynos5440_gpiolib_unregister(struct platform_device *pdev, | 874 | static int exynos5440_gpiolib_unregister(struct platform_device *pdev, |
875 | struct exynos5440_pinctrl_priv_data *priv) | 875 | struct exynos5440_pinctrl_priv_data *priv) |
876 | { | 876 | { |
877 | int ret = gpiochip_remove(priv->gc); | 877 | gpiochip_remove(priv->gc); |
878 | if (ret) { | ||
879 | dev_err(&pdev->dev, "gpio chip remove failed\n"); | ||
880 | return ret; | ||
881 | } | ||
882 | return 0; | 878 | return 0; |
883 | } | 879 | } |
884 | 880 | ||
diff --git a/drivers/pinctrl/samsung/pinctrl-samsung.c b/drivers/pinctrl/samsung/pinctrl-samsung.c index 4a47691c32b1..2d37c8f49f3c 100644 --- a/drivers/pinctrl/samsung/pinctrl-samsung.c +++ b/drivers/pinctrl/samsung/pinctrl-samsung.c | |||
@@ -946,9 +946,7 @@ static int samsung_gpiolib_register(struct platform_device *pdev, | |||
946 | 946 | ||
947 | fail: | 947 | fail: |
948 | for (--i, --bank; i >= 0; --i, --bank) | 948 | for (--i, --bank; i >= 0; --i, --bank) |
949 | if (gpiochip_remove(&bank->gpio_chip)) | 949 | gpiochip_remove(&bank->gpio_chip); |
950 | dev_err(&pdev->dev, "gpio chip %s remove failed\n", | ||
951 | bank->gpio_chip.label); | ||
952 | return ret; | 950 | return ret; |
953 | } | 951 | } |
954 | 952 | ||
@@ -958,16 +956,11 @@ static int samsung_gpiolib_unregister(struct platform_device *pdev, | |||
958 | { | 956 | { |
959 | struct samsung_pin_ctrl *ctrl = drvdata->ctrl; | 957 | struct samsung_pin_ctrl *ctrl = drvdata->ctrl; |
960 | struct samsung_pin_bank *bank = ctrl->pin_banks; | 958 | struct samsung_pin_bank *bank = ctrl->pin_banks; |
961 | int ret = 0; | ||
962 | int i; | 959 | int i; |
963 | 960 | ||
964 | for (i = 0; !ret && i < ctrl->nr_banks; ++i, ++bank) | 961 | for (i = 0; i < ctrl->nr_banks; ++i, ++bank) |
965 | ret = gpiochip_remove(&bank->gpio_chip); | 962 | gpiochip_remove(&bank->gpio_chip); |
966 | 963 | return 0; | |
967 | if (ret) | ||
968 | dev_err(&pdev->dev, "gpio chip remove failed\n"); | ||
969 | |||
970 | return ret; | ||
971 | } | 964 | } |
972 | 965 | ||
973 | static const struct of_device_id samsung_pinctrl_dt_match[]; | 966 | static const struct of_device_id samsung_pinctrl_dt_match[]; |
diff --git a/drivers/pinctrl/sirf/pinctrl-sirf.c b/drivers/pinctrl/sirf/pinctrl-sirf.c index b713bd59ffbb..4c831fdfcc2f 100644 --- a/drivers/pinctrl/sirf/pinctrl-sirf.c +++ b/drivers/pinctrl/sirf/pinctrl-sirf.c | |||
@@ -891,8 +891,7 @@ static int sirfsoc_gpio_probe(struct device_node *np) | |||
891 | 891 | ||
892 | out_no_range: | 892 | out_no_range: |
893 | out_banks: | 893 | out_banks: |
894 | if (gpiochip_remove(&sgpio->chip.gc)) | 894 | gpiochip_remove(&sgpio->chip.gc); |
895 | dev_err(&pdev->dev, "could not remove gpio chip\n"); | ||
896 | out: | 895 | out: |
897 | iounmap(regs); | 896 | iounmap(regs); |
898 | return err; | 897 | return err; |
diff --git a/drivers/platform/x86/intel_pmic_gpio.c b/drivers/platform/x86/intel_pmic_gpio.c index 40929e4f7ad7..04fed00b88e9 100644 --- a/drivers/platform/x86/intel_pmic_gpio.c +++ b/drivers/platform/x86/intel_pmic_gpio.c | |||
@@ -301,8 +301,7 @@ static int platform_pmic_gpio_probe(struct platform_device *pdev) | |||
301 | return 0; | 301 | return 0; |
302 | 302 | ||
303 | fail_request_irq: | 303 | fail_request_irq: |
304 | if (gpiochip_remove(&pg->chip)) | 304 | gpiochip_remove(&pg->chip); |
305 | pr_err("gpiochip_remove failed\n"); | ||
306 | err: | 305 | err: |
307 | iounmap(pg->gpiointr); | 306 | iounmap(pg->gpiointr); |
308 | err2: | 307 | err2: |
diff --git a/drivers/ssb/driver_gpio.c b/drivers/ssb/driver_gpio.c index ba350d2035c0..f92e266d48f8 100644 --- a/drivers/ssb/driver_gpio.c +++ b/drivers/ssb/driver_gpio.c | |||
@@ -475,7 +475,8 @@ int ssb_gpio_unregister(struct ssb_bus *bus) | |||
475 | { | 475 | { |
476 | if (ssb_chipco_available(&bus->chipco) || | 476 | if (ssb_chipco_available(&bus->chipco) || |
477 | ssb_extif_available(&bus->extif)) { | 477 | ssb_extif_available(&bus->extif)) { |
478 | return gpiochip_remove(&bus->gpio); | 478 | gpiochip_remove(&bus->gpio); |
479 | return 0; | ||
479 | } else { | 480 | } else { |
480 | SSB_WARN_ON(1); | 481 | SSB_WARN_ON(1); |
481 | } | 482 | } |
diff --git a/drivers/staging/vme/devices/vme_pio2_gpio.c b/drivers/staging/vme/devices/vme_pio2_gpio.c index d8a118d39566..c64776f71809 100644 --- a/drivers/staging/vme/devices/vme_pio2_gpio.c +++ b/drivers/staging/vme/devices/vme_pio2_gpio.c | |||
@@ -221,9 +221,7 @@ void pio2_gpio_exit(struct pio2_card *card) | |||
221 | { | 221 | { |
222 | const char *label = card->gc.label; | 222 | const char *label = card->gc.label; |
223 | 223 | ||
224 | if (gpiochip_remove(&(card->gc))) | 224 | gpiochip_remove(&(card->gc)); |
225 | dev_err(&card->vdev->dev, "Failed to remove GPIO\n"); | ||
226 | |||
227 | kfree(label); | 225 | kfree(label); |
228 | } | 226 | } |
229 | 227 | ||
diff --git a/drivers/tty/serial/max310x.c b/drivers/tty/serial/max310x.c index 82573dc4d8cf..0041a64cc86e 100644 --- a/drivers/tty/serial/max310x.c +++ b/drivers/tty/serial/max310x.c | |||
@@ -1248,7 +1248,7 @@ static int max310x_probe(struct device *dev, struct max310x_devtype *devtype, | |||
1248 | mutex_destroy(&s->mutex); | 1248 | mutex_destroy(&s->mutex); |
1249 | 1249 | ||
1250 | #ifdef CONFIG_GPIOLIB | 1250 | #ifdef CONFIG_GPIOLIB |
1251 | WARN_ON(gpiochip_remove(&s->gpio)); | 1251 | gpiochip_remove(&s->gpio); |
1252 | 1252 | ||
1253 | out_uart: | 1253 | out_uart: |
1254 | #endif | 1254 | #endif |
@@ -1263,12 +1263,10 @@ out_clk: | |||
1263 | static int max310x_remove(struct device *dev) | 1263 | static int max310x_remove(struct device *dev) |
1264 | { | 1264 | { |
1265 | struct max310x_port *s = dev_get_drvdata(dev); | 1265 | struct max310x_port *s = dev_get_drvdata(dev); |
1266 | int i, ret = 0; | 1266 | int i; |
1267 | 1267 | ||
1268 | #ifdef CONFIG_GPIOLIB | 1268 | #ifdef CONFIG_GPIOLIB |
1269 | ret = gpiochip_remove(&s->gpio); | 1269 | gpiochip_remove(&s->gpio); |
1270 | if (ret) | ||
1271 | return ret; | ||
1272 | #endif | 1270 | #endif |
1273 | 1271 | ||
1274 | for (i = 0; i < s->uart.nr; i++) { | 1272 | for (i = 0; i < s->uart.nr; i++) { |
@@ -1282,7 +1280,7 @@ static int max310x_remove(struct device *dev) | |||
1282 | uart_unregister_driver(&s->uart); | 1280 | uart_unregister_driver(&s->uart); |
1283 | clk_disable_unprepare(s->clk); | 1281 | clk_disable_unprepare(s->clk); |
1284 | 1282 | ||
1285 | return ret; | 1283 | return 0; |
1286 | } | 1284 | } |
1287 | 1285 | ||
1288 | static const struct of_device_id __maybe_unused max310x_dt_ids[] = { | 1286 | static const struct of_device_id __maybe_unused max310x_dt_ids[] = { |
diff --git a/drivers/tty/serial/sc16is7xx.c b/drivers/tty/serial/sc16is7xx.c index 3284c31085a7..6246820d7f05 100644 --- a/drivers/tty/serial/sc16is7xx.c +++ b/drivers/tty/serial/sc16is7xx.c | |||
@@ -1157,7 +1157,7 @@ static int sc16is7xx_probe(struct device *dev, | |||
1157 | 1157 | ||
1158 | #ifdef CONFIG_GPIOLIB | 1158 | #ifdef CONFIG_GPIOLIB |
1159 | if (devtype->nr_gpio) | 1159 | if (devtype->nr_gpio) |
1160 | WARN_ON(gpiochip_remove(&s->gpio)); | 1160 | gpiochip_remove(&s->gpio); |
1161 | 1161 | ||
1162 | out_uart: | 1162 | out_uart: |
1163 | #endif | 1163 | #endif |
@@ -1173,14 +1173,11 @@ out_clk: | |||
1173 | static int sc16is7xx_remove(struct device *dev) | 1173 | static int sc16is7xx_remove(struct device *dev) |
1174 | { | 1174 | { |
1175 | struct sc16is7xx_port *s = dev_get_drvdata(dev); | 1175 | struct sc16is7xx_port *s = dev_get_drvdata(dev); |
1176 | int i, ret = 0; | 1176 | int i; |
1177 | 1177 | ||
1178 | #ifdef CONFIG_GPIOLIB | 1178 | #ifdef CONFIG_GPIOLIB |
1179 | if (s->devtype->nr_gpio) { | 1179 | if (s->devtype->nr_gpio) |
1180 | ret = gpiochip_remove(&s->gpio); | 1180 | gpiochip_remove(&s->gpio); |
1181 | if (ret) | ||
1182 | return ret; | ||
1183 | } | ||
1184 | #endif | 1181 | #endif |
1185 | 1182 | ||
1186 | for (i = 0; i < s->uart.nr; i++) { | 1183 | for (i = 0; i < s->uart.nr; i++) { |
@@ -1195,7 +1192,7 @@ static int sc16is7xx_remove(struct device *dev) | |||
1195 | if (!IS_ERR(s->clk)) | 1192 | if (!IS_ERR(s->clk)) |
1196 | clk_disable_unprepare(s->clk); | 1193 | clk_disable_unprepare(s->clk); |
1197 | 1194 | ||
1198 | return ret; | 1195 | return 0; |
1199 | } | 1196 | } |
1200 | 1197 | ||
1201 | static const struct of_device_id __maybe_unused sc16is7xx_dt_ids[] = { | 1198 | static const struct of_device_id __maybe_unused sc16is7xx_dt_ids[] = { |
diff --git a/drivers/video/fbdev/via/via-gpio.c b/drivers/video/fbdev/via/via-gpio.c index e408679081ab..6f433b8cee12 100644 --- a/drivers/video/fbdev/via/via-gpio.c +++ b/drivers/video/fbdev/via/via-gpio.c | |||
@@ -270,7 +270,7 @@ static int viafb_gpio_probe(struct platform_device *platdev) | |||
270 | static int viafb_gpio_remove(struct platform_device *platdev) | 270 | static int viafb_gpio_remove(struct platform_device *platdev) |
271 | { | 271 | { |
272 | unsigned long flags; | 272 | unsigned long flags; |
273 | int ret = 0, i; | 273 | int i; |
274 | 274 | ||
275 | #ifdef CONFIG_PM | 275 | #ifdef CONFIG_PM |
276 | viafb_pm_unregister(&viafb_gpio_pm_hooks); | 276 | viafb_pm_unregister(&viafb_gpio_pm_hooks); |
@@ -280,11 +280,7 @@ static int viafb_gpio_remove(struct platform_device *platdev) | |||
280 | * Get unregistered. | 280 | * Get unregistered. |
281 | */ | 281 | */ |
282 | if (viafb_gpio_config.gpio_chip.ngpio > 0) { | 282 | if (viafb_gpio_config.gpio_chip.ngpio > 0) { |
283 | ret = gpiochip_remove(&viafb_gpio_config.gpio_chip); | 283 | gpiochip_remove(&viafb_gpio_config.gpio_chip); |
284 | if (ret) { /* Somebody still using it? */ | ||
285 | printk(KERN_ERR "Viafb: GPIO remove failed\n"); | ||
286 | return ret; | ||
287 | } | ||
288 | } | 284 | } |
289 | /* | 285 | /* |
290 | * Disable the ports. | 286 | * Disable the ports. |
@@ -294,7 +290,7 @@ static int viafb_gpio_remove(struct platform_device *platdev) | |||
294 | viafb_gpio_disable(viafb_gpio_config.active_gpios[i]); | 290 | viafb_gpio_disable(viafb_gpio_config.active_gpios[i]); |
295 | viafb_gpio_config.gpio_chip.ngpio = 0; | 291 | viafb_gpio_config.gpio_chip.ngpio = 0; |
296 | spin_unlock_irqrestore(&viafb_gpio_config.vdev->reg_lock, flags); | 292 | spin_unlock_irqrestore(&viafb_gpio_config.vdev->reg_lock, flags); |
297 | return ret; | 293 | return 0; |
298 | } | 294 | } |
299 | 295 | ||
300 | static struct platform_driver via_gpio_driver = { | 296 | static struct platform_driver via_gpio_driver = { |