* irq/gpio-immutable: : . : First try at preventing the GPIO subsystem from abusing irq_chip : data structures. The general idea is to have an irq_chip flag : to tell the GPIO subsystem that these structures are immutable, : and to convert drivers one by one. : . Documentation: Update the recommended pattern for GPIO irqchips gpio: Update TODO to mention immutable irq_chip structures pinctrl: amd: Make the irqchip immutable pinctrl: msmgpio: Make the irqchip immutable pinctrl: apple-gpio: Make the irqchip immutable gpio: pl061: Make the irqchip immutable gpio: tegra186: Make the irqchip immutable gpio: Add helpers to ease the transition towards immutable irq_chip gpio: Expose the gpiochip_irq_re[ql]res helpers gpio: Don't fiddle with irqchips marked as immutable
Unified · Split
| @@ -417,30 +417,66 @@ struct gpio_irq_chip inside struct gpio_chip before adding the gpio_chip. · 416 unmodified lines | |||
| 417 | If you do this, the additional irq_chip will be set up by gpiolib at the | 417 | If you do this, the additional irq_chip will be set up by gpiolib at the |
| 418 | same time as setting up the rest of the GPIO functionality. The following | 418 | same time as setting up the rest of the GPIO functionality. The following |
| 419 | is a typical example of a chained cascaded interrupt handler using | 419 | is a typical example of a chained cascaded interrupt handler using |
| 420 | the gpio_irq_chip: | 420 | the gpio_irq_chip. Note how the mask/unmask (or disable/enable) functions |
| 421 | call into the core gpiolib code: | ||
| 421 | 422 | ||
| 422 | .. code-block:: c | 423 | .. code-block:: c |
| 423 | 424 | ||
| 424 | /* Typical state container with dynamic irqchip */ | 425 | /* Typical state container */ |
| 425 | struct my_gpio { | 426 | struct my_gpio { |
| 426 | struct gpio_chip gc; | 427 | struct gpio_chip gc; |
| 427 | struct irq_chip irq; | 428 | }; |
| 429 | |||
| 430 | static void my_gpio_mask_irq(struct irq_data *d) | ||
| 431 | { | ||
| 432 | struct gpio_chip *gc = irq_desc_get_handler_data(d); | ||
| 433 | |||
| 434 | /* | ||
| 435 | * Perform any necessary action to mask the interrupt, | ||
| 436 | * and then call into the core code to synchronise the | ||
| 437 | * state. | ||
| 438 | */ | ||
| 439 | |||
| 440 | gpiochip_disable_irq(gc, d->hwirq); | ||
| 441 | } | ||
| 442 | |||
| 443 | static void my_gpio_unmask_irq(struct irq_data *d) | ||
| 444 | { | ||
| 445 | struct gpio_chip *gc = irq_desc_get_handler_data(d); | ||
| 446 | |||
| 447 | gpiochip_enable_irq(gc, d->hwirq); | ||
| 448 | |||
| 449 | /* | ||
| 450 | * Perform any necessary action to unmask the interrupt, | ||
| 451 | * after having called into the core code to synchronise | ||
| 452 | * the state. | ||
| 453 | */ | ||
| 454 | } | ||
| 455 | |||
| 456 | /* | ||
| 457 | * Statically populate the irqchip. Note that it is made const | ||
| 458 | * (further indicated by the IRQCHIP_IMMUTABLE flag), and that | ||
| 459 | * the GPIOCHIP_IRQ_RESOURCE_HELPER macro adds some extra | ||
| 460 | * callbacks to the structure. | ||
| 461 | */ | ||
| 462 | static const struct irq_chip my_gpio_irq_chip = { | ||
| 463 | .name = "my_gpio_irq", | ||
| 464 | .irq_ack = my_gpio_ack_irq, | ||
| 465 | .irq_mask = my_gpio_mask_irq, | ||
| 466 | .irq_unmask = my_gpio_unmask_irq, | ||
| 467 | .irq_set_type = my_gpio_set_irq_type, | ||
| 468 | .flags = IRQCHIP_IMMUTABLE, | ||
| 469 | /* Provide the gpio resource callbacks */ | ||
| 470 | GPIOCHIP_IRQ_RESOURCE_HELPERS, | ||
| 428 | }; | 471 | }; |
| 429 | 472 | ||
| 430 | int irq; /* from platform etc */ | 473 | int irq; /* from platform etc */ |
| 431 | struct my_gpio *g; | 474 | struct my_gpio *g; |
| 432 | struct gpio_irq_chip *girq; | 475 | struct gpio_irq_chip *girq; |
| 433 | 476 | ||
| 434 | /* Set up the irqchip dynamically */ | ||
| 435 | g->irq.name = "my_gpio_irq"; | ||
| 436 | g->irq.irq_ack = my_gpio_ack_irq; | ||
| 437 | g->irq.irq_mask = my_gpio_mask_irq; | ||
| 438 | g->irq.irq_unmask = my_gpio_unmask_irq; | ||
| 439 | g->irq.irq_set_type = my_gpio_set_irq_type; | ||
| 440 | |||
| 441 | /* Get a pointer to the gpio_irq_chip */ | 477 | /* Get a pointer to the gpio_irq_chip */ |
| 442 | girq = &g->gc.irq; | 478 | girq = &g->gc.irq; |
| 443 | girq->chip = &g->irq; | 479 | gpio_irq_chip_set_chip(girq, &my_gpio_irq_chip); |
| 444 | girq->parent_handler = ftgpio_gpio_irq_handler; | 480 | girq->parent_handler = ftgpio_gpio_irq_handler; |
| 445 | girq->num_parents = 1; | 481 | girq->num_parents = 1; |
| 446 | girq->parents = devm_kcalloc(dev, 1, sizeof(*girq->parents), | 482 | girq->parents = devm_kcalloc(dev, 1, sizeof(*girq->parents), |
| @@ -458,23 +494,58 @@ the interrupt separately and go with it: · 11 unmodified lines | |||
| 458 | 494 | ||
| 459 | .. code-block:: c | 495 | .. code-block:: c |
| 460 | 496 | ||
| 461 | /* Typical state container with dynamic irqchip */ | 497 | /* Typical state container */ |
| 462 | struct my_gpio { | 498 | struct my_gpio { |
| 463 | struct gpio_chip gc; | 499 | struct gpio_chip gc; |
| 464 | struct irq_chip irq; | 500 | }; |
| 501 | |||
| 502 | static void my_gpio_mask_irq(struct irq_data *d) | ||
| 503 | { | ||
| 504 | struct gpio_chip *gc = irq_desc_get_handler_data(d); | ||
| 505 | |||
| 506 | /* | ||
| 507 | * Perform any necessary action to mask the interrupt, | ||
| 508 | * and then call into the core code to synchronise the | ||
| 509 | * state. | ||
| 510 | */ | ||
| 511 | |||
| 512 | gpiochip_disable_irq(gc, d->hwirq); | ||
| 513 | } | ||
| 514 | |||
| 515 | static void my_gpio_unmask_irq(struct irq_data *d) | ||
| 516 | { | ||
| 517 | struct gpio_chip *gc = irq_desc_get_handler_data(d); | ||
| 518 | |||
| 519 | gpiochip_enable_irq(gc, d->hwirq); | ||
| 520 | |||
| 521 | /* | ||
| 522 | * Perform any necessary action to unmask the interrupt, | ||
| 523 | * after having called into the core code to synchronise | ||
| 524 | * the state. | ||
| 525 | */ | ||
| 526 | } | ||
| 527 | |||
| 528 | /* | ||
| 529 | * Statically populate the irqchip. Note that it is made const | ||
| 530 | * (further indicated by the IRQCHIP_IMMUTABLE flag), and that | ||
| 531 | * the GPIOCHIP_IRQ_RESOURCE_HELPER macro adds some extra | ||
| 532 | * callbacks to the structure. | ||
| 533 | */ | ||
| 534 | static const struct irq_chip my_gpio_irq_chip = { | ||
| 535 | .name = "my_gpio_irq", | ||
| 536 | .irq_ack = my_gpio_ack_irq, | ||
| 537 | .irq_mask = my_gpio_mask_irq, | ||
| 538 | .irq_unmask = my_gpio_unmask_irq, | ||
| 539 | .irq_set_type = my_gpio_set_irq_type, | ||
| 540 | .flags = IRQCHIP_IMMUTABLE, | ||
| 541 | /* Provide the gpio resource callbacks */ | ||
| 542 | GPIOCHIP_IRQ_RESOURCE_HELPERS, | ||
| 465 | }; | 543 | }; |
| 466 | 544 | ||
| 467 | int irq; /* from platform etc */ | 545 | int irq; /* from platform etc */ |
| 468 | struct my_gpio *g; | 546 | struct my_gpio *g; |
| 469 | struct gpio_irq_chip *girq; | 547 | struct gpio_irq_chip *girq; |
| 470 | 548 | ||
| 471 | /* Set up the irqchip dynamically */ | ||
| 472 | g->irq.name = "my_gpio_irq"; | ||
| 473 | g->irq.irq_ack = my_gpio_ack_irq; | ||
| 474 | g->irq.irq_mask = my_gpio_mask_irq; | ||
| 475 | g->irq.irq_unmask = my_gpio_unmask_irq; | ||
| 476 | g->irq.irq_set_type = my_gpio_set_irq_type; | ||
| 477 | |||
| 478 | ret = devm_request_threaded_irq(dev, irq, NULL, | 549 | ret = devm_request_threaded_irq(dev, irq, NULL, |
| 479 | irq_thread_fn, IRQF_ONESHOT, "my-chip", g); | 550 | irq_thread_fn, IRQF_ONESHOT, "my-chip", g); |
| 480 | if (ret < 0) | 551 | if (ret < 0) |
| @@ -482,7 +553,7 @@ the interrupt separately and go with it: · 1 unmodified line | |||
| 482 | 553 | ||
| 483 | /* Get a pointer to the gpio_irq_chip */ | 554 | /* Get a pointer to the gpio_irq_chip */ |
| 484 | girq = &g->gc.irq; | 555 | girq = &g->gc.irq; |
| 485 | girq->chip = &g->irq; | 556 | gpio_irq_chip_set_chip(girq, &my_gpio_irq_chip); |
| 486 | /* This will let us handle the parent IRQ in the driver */ | 557 | /* This will let us handle the parent IRQ in the driver */ |
| 487 | girq->parent_handler = NULL; | 558 | girq->parent_handler = NULL; |
| 488 | girq->num_parents = 0; | 559 | girq->num_parents = 0; |
| @@ -500,24 +571,61 @@ In this case the typical set-up will look like this: · 11 unmodified lines | |||
| 500 | /* Typical state container with dynamic irqchip */ | 571 | /* Typical state container with dynamic irqchip */ |
| 501 | struct my_gpio { | 572 | struct my_gpio { |
| 502 | struct gpio_chip gc; | 573 | struct gpio_chip gc; |
| 503 | struct irq_chip irq; | ||
| 504 | struct fwnode_handle *fwnode; | 574 | struct fwnode_handle *fwnode; |
| 505 | }; | 575 | }; |
| 506 | 576 | ||
| 507 | int irq; /* from platform etc */ | 577 | static void my_gpio_mask_irq(struct irq_data *d) |
| 578 | { | ||
| 579 | struct gpio_chip *gc = irq_desc_get_handler_data(d); | ||
| 580 | |||
| 581 | /* | ||
| 582 | * Perform any necessary action to mask the interrupt, | ||
| 583 | * and then call into the core code to synchronise the | ||
| 584 | * state. | ||
| 585 | */ | ||
| 586 | |||
| 587 | gpiochip_disable_irq(gc, d->hwirq); | ||
| 588 | irq_mask_mask_parent(d); | ||
| 589 | } | ||
| 590 | |||
| 591 | static void my_gpio_unmask_irq(struct irq_data *d) | ||
| 592 | { | ||
| 593 | struct gpio_chip *gc = irq_desc_get_handler_data(d); | ||
| 594 | |||
| 595 | gpiochip_enable_irq(gc, d->hwirq); | ||
| 596 | |||
| 597 | /* | ||
| 598 | * Perform any necessary action to unmask the interrupt, | ||
| 599 | * after having called into the core code to synchronise | ||
| 600 | * the state. | ||
| 601 | */ | ||
| 602 | |||
| 603 | irq_mask_unmask_parent(d); | ||
| 604 | } | ||
| 605 | |||
| 606 | /* | ||
| 607 | * Statically populate the irqchip. Note that it is made const | ||
| 608 | * (further indicated by the IRQCHIP_IMMUTABLE flag), and that | ||
| 609 | * the GPIOCHIP_IRQ_RESOURCE_HELPER macro adds some extra | ||
| 610 | * callbacks to the structure. | ||
| 611 | */ | ||
| 612 | static const struct irq_chip my_gpio_irq_chip = { | ||
| 613 | .name = "my_gpio_irq", | ||
| 614 | .irq_ack = my_gpio_ack_irq, | ||
| 615 | .irq_mask = my_gpio_mask_irq, | ||
| 616 | .irq_unmask = my_gpio_unmask_irq, | ||
| 617 | .irq_set_type = my_gpio_set_irq_type, | ||
| 618 | .flags = IRQCHIP_IMMUTABLE, | ||
| 619 | /* Provide the gpio resource callbacks */ | ||
| 620 | GPIOCHIP_IRQ_RESOURCE_HELPERS, | ||
| 621 | }; | ||
| 622 | |||
| 508 | struct my_gpio *g; | 623 | struct my_gpio *g; |
| 509 | struct gpio_irq_chip *girq; | 624 | struct gpio_irq_chip *girq; |
| 510 | 625 | ||
| 511 | /* Set up the irqchip dynamically */ | ||
| 512 | g->irq.name = "my_gpio_irq"; | ||
| 513 | g->irq.irq_ack = my_gpio_ack_irq; | ||
| 514 | g->irq.irq_mask = my_gpio_mask_irq; | ||
| 515 | g->irq.irq_unmask = my_gpio_unmask_irq; | ||
| 516 | g->irq.irq_set_type = my_gpio_set_irq_type; | ||
| 517 | |||
| 518 | /* Get a pointer to the gpio_irq_chip */ | 626 | /* Get a pointer to the gpio_irq_chip */ |
| 519 | girq = &g->gc.irq; | 627 | girq = &g->gc.irq; |
| 520 | girq->chip = &g->irq; | 628 | gpio_irq_chip_set_chip(girq, &my_gpio_irq_chip); |
| 521 | girq->default_type = IRQ_TYPE_NONE; | 629 | girq->default_type = IRQ_TYPE_NONE; |
| 522 | girq->handler = handle_bad_irq; | 630 | girq->handler = handle_bad_irq; |
| 523 | girq->fwnode = g->fwnode; | 631 | girq->fwnode = g->fwnode; |
| @@ -605,8 +713,9 @@ When implementing an irqchip inside a GPIO driver, these two functions should · 81 unmodified lines | |||
| 605 | typically be called in the .irq_disable() and .irq_enable() callbacks from the | 713 | typically be called in the .irq_disable() and .irq_enable() callbacks from the |
| 606 | irqchip. | 714 | irqchip. |
| 607 | 715 | ||
| 608 | When using the gpiolib irqchip helpers, these callbacks are automatically | 716 | When IRQCHIP_IMMUTABLE is not advertised by the irqchip, these callbacks |
| 609 | assigned. | 717 | are automatically assigned. This behaviour is deprecated and on its way |
| 718 | to be removed from the kernel. | ||
| 610 | 719 | ||
| 611 | 720 | ||
| 612 | Real-Time compliance for GPIO IRQ chips | 721 | Real-Time compliance for GPIO IRQ chips |
| @@ -178,3 +178,22 @@ discussed but the idea is to provide a low-level access point · 177 unmodified lines | |||
| 178 | for debugging and hacking and to expose all lines without the | 178 | for debugging and hacking and to expose all lines without the |
| 179 | need of any exporting. Also provide ample ammunition to shoot | 179 | need of any exporting. Also provide ample ammunition to shoot |
| 180 | oneself in the foot, because this is debugfs after all. | 180 | oneself in the foot, because this is debugfs after all. |
| 181 | |||
| 182 | |||
| 183 | Moving over to immutable irq_chip structures | ||
| 184 | |||
| 185 | Most of the gpio chips implementing interrupt support rely on gpiolib | ||
| 186 | intercepting some of the irq_chip callbacks, preventing the structures | ||
| 187 | from being made read-only and forcing duplication of structures that | ||
| 188 | should otherwise be unique. | ||
| 189 | |||
| 190 | The solution is to call into the gpiolib code when needed (resource | ||
| 191 | management, enable/disable or unmask/mask callbacks), and to let the | ||
| 192 | core code know about that by exposing a flag (IRQCHIP_IMMUTABLE) in | ||
| 193 | the irq_chip structure. The irq_chip structure can then be made unique | ||
| 194 | and const. | ||
| 195 | |||
| 196 | A small number of drivers have been converted (pl061, tegra186, msm, | ||
| 197 | amd, apple), and can be used as examples of how to proceed with this | ||
| 198 | conversion. Note that drivers using the generic irqchip framework | ||
| 199 | cannot be converted yet, but watch this space! | ||
| @@ -52,7 +52,6 @@ struct pl061 { · 51 unmodified lines | |||
| 52 | 52 | ||
| 53 | void __iomem *base; | 53 | void __iomem *base; |
| 54 | struct gpio_chip gc; | 54 | struct gpio_chip gc; |
| 55 | struct irq_chip irq_chip; | ||
| 56 | int parent_irq; | 55 | int parent_irq; |
| 57 | 56 | ||
| 58 | #ifdef CONFIG_PM | 57 | #ifdef CONFIG_PM |
| @@ -241,6 +240,8 @@ static void pl061_irq_mask(struct irq_data *d) · 182 unmodified lines | |||
| 241 | gpioie = readb(pl061->base + GPIOIE) & ~mask; | 240 | gpioie = readb(pl061->base + GPIOIE) & ~mask; |
| 242 | writeb(gpioie, pl061->base + GPIOIE); | 241 | writeb(gpioie, pl061->base + GPIOIE); |
| 243 | raw_spin_unlock(&pl061->lock); | 242 | raw_spin_unlock(&pl061->lock); |
| 243 | |||
| 244 | gpiochip_disable_irq(gc, d->hwirq); | ||
| 244 | } | 245 | } |
| 245 | 246 | ||
| 246 | static void pl061_irq_unmask(struct irq_data *d) | 247 | static void pl061_irq_unmask(struct irq_data *d) |
| @@ -250,6 +251,8 @@ static void pl061_irq_unmask(struct irq_data *d) · 3 unmodified lines | |||
| 250 | u8 mask = BIT(irqd_to_hwirq(d) % PL061_GPIO_NR); | 251 | u8 mask = BIT(irqd_to_hwirq(d) % PL061_GPIO_NR); |
| 251 | u8 gpioie; | 252 | u8 gpioie; |
| 252 | 253 | ||
| 254 | gpiochip_enable_irq(gc, d->hwirq); | ||
| 255 | |||
| 253 | raw_spin_lock(&pl061->lock); | 256 | raw_spin_lock(&pl061->lock); |
| 254 | gpioie = readb(pl061->base + GPIOIE) | mask; | 257 | gpioie = readb(pl061->base + GPIOIE) | mask; |
| 255 | writeb(gpioie, pl061->base + GPIOIE); | 258 | writeb(gpioie, pl061->base + GPIOIE); |
| @@ -283,6 +286,24 @@ static int pl061_irq_set_wake(struct irq_data *d, unsigned int state) · 27 unmodified lines | |||
| 283 | return irq_set_irq_wake(pl061->parent_irq, state); | 286 | return irq_set_irq_wake(pl061->parent_irq, state); |
| 284 | } | 287 | } |
| 285 | 288 | ||
| 289 | static void pl061_irq_print_chip(struct irq_data *data, struct seq_file *p) | ||
| 290 | { | ||
| 291 | struct gpio_chip *gc = irq_data_get_irq_chip_data(data); | ||
| 292 | |||
| 293 | seq_printf(p, dev_name(gc->parent)); | ||
| 294 | } | ||
| 295 | |||
| 296 | static const struct irq_chip pl061_irq_chip = { | ||
| 297 | .irq_ack = pl061_irq_ack, | ||
| 298 | .irq_mask = pl061_irq_mask, | ||
| 299 | .irq_unmask = pl061_irq_unmask, | ||
| 300 | .irq_set_type = pl061_irq_type, | ||
| 301 | .irq_set_wake = pl061_irq_set_wake, | ||
| 302 | .irq_print_chip = pl061_irq_print_chip, | ||
| 303 | .flags = IRQCHIP_IMMUTABLE, | ||
| 304 | GPIOCHIP_IRQ_RESOURCE_HELPERS, | ||
| 305 | }; | ||
| 306 | |||
| 286 | static int pl061_probe(struct amba_device *adev, const struct amba_id *id) | 307 | static int pl061_probe(struct amba_device *adev, const struct amba_id *id) |
| 287 | { | 308 | { |
| 288 | struct device *dev = &adev->dev; | 309 | struct device *dev = &adev->dev; |
| @@ -315,13 +336,6 @@ static int pl061_probe(struct amba_device *adev, const struct amba_id *id) · 26 unmodified lines | |||
| 315 | /* | 336 | /* |
| 316 | * irq_chip support | 337 | * irq_chip support |
| 317 | */ | 338 | */ |
| 318 | pl061->irq_chip.name = dev_name(dev); | ||
| 319 | pl061->irq_chip.irq_ack = pl061_irq_ack; | ||
| 320 | pl061->irq_chip.irq_mask = pl061_irq_mask; | ||
| 321 | pl061->irq_chip.irq_unmask = pl061_irq_unmask; | ||
| 322 | pl061->irq_chip.irq_set_type = pl061_irq_type; | ||
| 323 | pl061->irq_chip.irq_set_wake = pl061_irq_set_wake; | ||
| 324 | |||
| 325 | writeb(0, pl061->base + GPIOIE); /* disable irqs */ | 339 | writeb(0, pl061->base + GPIOIE); /* disable irqs */ |
| 326 | irq = adev->irq[0]; | 340 | irq = adev->irq[0]; |
| 327 | if (!irq) | 341 | if (!irq) |
| @@ -329,7 +343,7 @@ static int pl061_probe(struct amba_device *adev, const struct amba_id *id) · 1 unmodified line | |||
| 329 | pl061->parent_irq = irq; | 343 | pl061->parent_irq = irq; |
| 330 | 344 | ||
| 331 | girq = &pl061->gc.irq; | 345 | girq = &pl061->gc.irq; |
| 332 | girq->chip = &pl061->irq_chip; | 346 | gpio_irq_chip_set_chip(girq, &pl061_irq_chip); |
| 333 | girq->parent_handler = pl061_irq_handler; | 347 | girq->parent_handler = pl061_irq_handler; |
| 334 | girq->num_parents = 1; | 348 | girq->num_parents = 1; |
| 335 | girq->parents = devm_kcalloc(dev, 1, sizeof(*girq->parents), | 349 | girq->parents = devm_kcalloc(dev, 1, sizeof(*girq->parents), |
| @@ -80,7 +80,6 @@ struct tegra_gpio_soc { · 79 unmodified lines | |||
| 80 | 80 | ||
| 81 | struct tegra_gpio { | 81 | struct tegra_gpio { |
| 82 | struct gpio_chip gpio; | 82 | struct gpio_chip gpio; |
| 83 | struct irq_chip intc; | ||
| 84 | unsigned int num_irq; | 83 | unsigned int num_irq; |
| 85 | unsigned int *irq; | 84 | unsigned int *irq; |
| 86 | 85 | ||
| @@ -372,6 +371,8 @@ static void tegra186_irq_mask(struct irq_data *data) · 285 unmodified lines | |||
| 372 | value = readl(base + TEGRA186_GPIO_ENABLE_CONFIG); | 371 | value = readl(base + TEGRA186_GPIO_ENABLE_CONFIG); |
| 373 | value &= ~TEGRA186_GPIO_ENABLE_CONFIG_INTERRUPT; | 372 | value &= ~TEGRA186_GPIO_ENABLE_CONFIG_INTERRUPT; |
| 374 | writel(value, base + TEGRA186_GPIO_ENABLE_CONFIG); | 373 | writel(value, base + TEGRA186_GPIO_ENABLE_CONFIG); |
| 374 | |||
| 375 | gpiochip_disable_irq(&gpio->gpio, data->hwirq); | ||
| 375 | } | 376 | } |
| 376 | 377 | ||
| 377 | static void tegra186_irq_unmask(struct irq_data *data) | 378 | static void tegra186_irq_unmask(struct irq_data *data) |
| @@ -385,6 +386,8 @@ static void tegra186_irq_unmask(struct irq_data *data) · 7 unmodified lines | |||
| 385 | if (WARN_ON(base == NULL)) | 386 | if (WARN_ON(base == NULL)) |
| 386 | return; | 387 | return; |
| 387 | 388 | ||
| 389 | gpiochip_enable_irq(&gpio->gpio, data->hwirq); | ||
| 390 | |||
| 388 | value = readl(base + TEGRA186_GPIO_ENABLE_CONFIG); | 391 | value = readl(base + TEGRA186_GPIO_ENABLE_CONFIG); |
| 389 | value |= TEGRA186_GPIO_ENABLE_CONFIG_INTERRUPT; | 392 | value |= TEGRA186_GPIO_ENABLE_CONFIG_INTERRUPT; |
| 390 | writel(value, base + TEGRA186_GPIO_ENABLE_CONFIG); | 393 | writel(value, base + TEGRA186_GPIO_ENABLE_CONFIG); |
| @@ -456,6 +459,24 @@ static int tegra186_irq_set_wake(struct irq_data *data, unsigned int on) · 65 unmodified lines | |||
| 456 | return 0; | 459 | return 0; |
| 457 | } | 460 | } |
| 458 | 461 | ||
| 462 | static void tegra186_irq_print_chip(struct irq_data *data, struct seq_file *p) | ||
| 463 | { | ||
| 464 | struct gpio_chip *gc = irq_data_get_irq_chip_data(data); | ||
| 465 | |||
| 466 | seq_printf(p, dev_name(gc->parent)); | ||
| 467 | } | ||
| 468 | |||
| 469 | static const struct irq_chip tegra186_gpio_irq_chip = { | ||
| 470 | .irq_ack = tegra186_irq_ack, | ||
| 471 | .irq_mask = tegra186_irq_mask, | ||
| 472 | .irq_unmask = tegra186_irq_unmask, | ||
| 473 | .irq_set_type = tegra186_irq_set_type, | ||
| 474 | .irq_set_wake = tegra186_irq_set_wake, | ||
| 475 | .irq_print_chip = tegra186_irq_print_chip, | ||
| 476 | .flags = IRQCHIP_IMMUTABLE, | ||
| 477 | GPIOCHIP_IRQ_RESOURCE_HELPERS, | ||
| 478 | }; | ||
| 479 | |||
| 459 | static void tegra186_gpio_irq(struct irq_desc *desc) | 480 | static void tegra186_gpio_irq(struct irq_desc *desc) |
| 460 | { | 481 | { |
| 461 | struct tegra_gpio *gpio = irq_desc_get_handler_data(desc); | 482 | struct tegra_gpio *gpio = irq_desc_get_handler_data(desc); |
| @@ -760,15 +781,8 @@ static int tegra186_gpio_probe(struct platform_device *pdev) · 298 unmodified lines | |||
| 760 | gpio->gpio.of_xlate = tegra186_gpio_of_xlate; | 781 | gpio->gpio.of_xlate = tegra186_gpio_of_xlate; |
| 761 | #endif /* CONFIG_OF_GPIO */ | 782 | #endif /* CONFIG_OF_GPIO */ |
| 762 | 783 | ||
| 763 | gpio->intc.name = dev_name(&pdev->dev); | ||
| 764 | gpio->intc.irq_ack = tegra186_irq_ack; | ||
| 765 | gpio->intc.irq_mask = tegra186_irq_mask; | ||
| 766 | gpio->intc.irq_unmask = tegra186_irq_unmask; | ||
| 767 | gpio->intc.irq_set_type = tegra186_irq_set_type; | ||
| 768 | gpio->intc.irq_set_wake = tegra186_irq_set_wake; | ||
| 769 | |||
| 770 | irq = &gpio->gpio.irq; | 784 | irq = &gpio->gpio.irq; |
| 771 | irq->chip = &gpio->intc; | 785 | gpio_irq_chip_set_chip(irq, &tegra186_gpio_irq_chip); |
| 772 | irq->fwnode = of_node_to_fwnode(pdev->dev.of_node); | 786 | irq->fwnode = of_node_to_fwnode(pdev->dev.of_node); |
| 773 | irq->child_to_parent_hwirq = tegra186_gpio_child_to_parent_hwirq; | 787 | irq->child_to_parent_hwirq = tegra186_gpio_child_to_parent_hwirq; |
| 774 | irq->populate_parent_alloc_arg = tegra186_gpio_populate_parent_fwspec; | 788 | irq->populate_parent_alloc_arg = tegra186_gpio_populate_parent_fwspec; |
| @@ -1433,19 +1433,21 @@ static int gpiochip_to_irq(struct gpio_chip *gc, unsigned int offset) · 1432 unmodified lines | |||
| 1433 | return irq_create_mapping(domain, offset); | 1433 | return irq_create_mapping(domain, offset); |
| 1434 | } | 1434 | } |
| 1435 | 1435 | ||
| 1436 | static int gpiochip_irq_reqres(struct irq_data *d) | 1436 | int gpiochip_irq_reqres(struct irq_data *d) |
| 1437 | { | 1437 | { |
| 1438 | struct gpio_chip *gc = irq_data_get_irq_chip_data(d); | 1438 | struct gpio_chip *gc = irq_data_get_irq_chip_data(d); |
| 1439 | 1439 | ||
| 1440 | return gpiochip_reqres_irq(gc, d->hwirq); | 1440 | return gpiochip_reqres_irq(gc, d->hwirq); |
| 1441 | } | 1441 | } |
| 1442 | EXPORT_SYMBOL(gpiochip_irq_reqres); | ||
| 1442 | 1443 | ||
| 1443 | static void gpiochip_irq_relres(struct irq_data *d) | 1444 | void gpiochip_irq_relres(struct irq_data *d) |
| 1444 | { | 1445 | { |
| 1445 | struct gpio_chip *gc = irq_data_get_irq_chip_data(d); | 1446 | struct gpio_chip *gc = irq_data_get_irq_chip_data(d); |
| 1446 | 1447 | ||
| 1447 | gpiochip_relres_irq(gc, d->hwirq); | 1448 | gpiochip_relres_irq(gc, d->hwirq); |
| 1448 | } | 1449 | } |
| 1450 | EXPORT_SYMBOL(gpiochip_irq_relres); | ||
| 1449 | 1451 | ||
| 1450 | static void gpiochip_irq_mask(struct irq_data *d) | 1452 | static void gpiochip_irq_mask(struct irq_data *d) |
| 1451 | { | 1453 | { |
| @@ -1485,6 +1487,11 @@ static void gpiochip_set_irq_hooks(struct gpio_chip *gc) · 33 unmodified lines | |||
| 1485 | { | 1487 | { |
| 1486 | struct irq_chip *irqchip = gc->irq.chip; | 1488 | struct irq_chip *irqchip = gc->irq.chip; |
| 1487 | 1489 | ||
| 1490 | if (irqchip->flags & IRQCHIP_IMMUTABLE) | ||
| 1491 | return; | ||
| 1492 | |||
| 1493 | chip_warn(gc, "not an immutable chip, please consider fixing it!\n"); | ||
| 1494 | |||
| 1488 | if (!irqchip->irq_request_resources && | 1495 | if (!irqchip->irq_request_resources && |
| 1489 | !irqchip->irq_release_resources) { | 1496 | !irqchip->irq_release_resources) { |
| 1490 | irqchip->irq_request_resources = gpiochip_irq_reqres; | 1497 | irqchip->irq_request_resources = gpiochip_irq_reqres; |
| @@ -1652,7 +1659,7 @@ static void gpiochip_irqchip_remove(struct gpio_chip *gc) · 161 unmodified lines | |||
| 1652 | irq_domain_remove(gc->irq.domain); | 1659 | irq_domain_remove(gc->irq.domain); |
| 1653 | } | 1660 | } |
| 1654 | 1661 | ||
| 1655 | if (irqchip) { | 1662 | if (irqchip && !(irqchip->flags & IRQCHIP_IMMUTABLE)) { |
| 1656 | if (irqchip->irq_request_resources == gpiochip_irq_reqres) { | 1663 | if (irqchip->irq_request_resources == gpiochip_irq_reqres) { |
| 1657 | irqchip->irq_request_resources = NULL; | 1664 | irqchip->irq_request_resources = NULL; |
| 1658 | irqchip->irq_release_resources = NULL; | 1665 | irqchip->irq_release_resources = NULL; |
| @@ -387,6 +387,8 @@ static void amd_gpio_irq_enable(struct irq_data *d) · 386 unmodified lines | |||
| 387 | struct gpio_chip *gc = irq_data_get_irq_chip_data(d); | 387 | struct gpio_chip *gc = irq_data_get_irq_chip_data(d); |
| 388 | struct amd_gpio *gpio_dev = gpiochip_get_data(gc); | 388 | struct amd_gpio *gpio_dev = gpiochip_get_data(gc); |
| 389 | 389 | ||
| 390 | gpiochip_enable_irq(gc, d->hwirq); | ||
| 391 | |||
| 390 | raw_spin_lock_irqsave(&gpio_dev->lock, flags); | 392 | raw_spin_lock_irqsave(&gpio_dev->lock, flags); |
| 391 | pin_reg = readl(gpio_dev->base + (d->hwirq)*4); | 393 | pin_reg = readl(gpio_dev->base + (d->hwirq)*4); |
| 392 | pin_reg |= BIT(INTERRUPT_ENABLE_OFF); | 394 | pin_reg |= BIT(INTERRUPT_ENABLE_OFF); |
| @@ -408,6 +410,8 @@ static void amd_gpio_irq_disable(struct irq_data *d) · 15 unmodified lines | |||
| 408 | pin_reg &= ~BIT(INTERRUPT_MASK_OFF); | 410 | pin_reg &= ~BIT(INTERRUPT_MASK_OFF); |
| 409 | writel(pin_reg, gpio_dev->base + (d->hwirq)*4); | 411 | writel(pin_reg, gpio_dev->base + (d->hwirq)*4); |
| 410 | raw_spin_unlock_irqrestore(&gpio_dev->lock, flags); | 412 | raw_spin_unlock_irqrestore(&gpio_dev->lock, flags); |
| 413 | |||
| 414 | gpiochip_disable_irq(gc, d->hwirq); | ||
| 411 | } | 415 | } |
| 412 | 416 | ||
| 413 | static void amd_gpio_irq_mask(struct irq_data *d) | 417 | static void amd_gpio_irq_mask(struct irq_data *d) |
| @@ -577,7 +581,7 @@ static void amd_irq_ack(struct irq_data *d) · 163 unmodified lines | |||
| 577 | */ | 581 | */ |
| 578 | } | 582 | } |
| 579 | 583 | ||
| 580 | static struct irq_chip amd_gpio_irqchip = { | 584 | static const struct irq_chip amd_gpio_irqchip = { |
| 581 | .name = "amd_gpio", | 585 | .name = "amd_gpio", |
| 582 | .irq_ack = amd_irq_ack, | 586 | .irq_ack = amd_irq_ack, |
| 583 | .irq_enable = amd_gpio_irq_enable, | 587 | .irq_enable = amd_gpio_irq_enable, |
| @@ -593,7 +597,8 @@ static struct irq_chip amd_gpio_irqchip = { · 9 unmodified lines | |||
| 593 | * the wake event. Otherwise the wake event will never clear and | 597 | * the wake event. Otherwise the wake event will never clear and |
| 594 | * prevent the system from suspending. | 598 | * prevent the system from suspending. |
| 595 | */ | 599 | */ |
| 596 | .flags = IRQCHIP_ENABLE_WAKEUP_ON_SUSPEND, | 600 | .flags = IRQCHIP_ENABLE_WAKEUP_ON_SUSPEND | IRQCHIP_IMMUTABLE, |
| 601 | GPIOCHIP_IRQ_RESOURCE_HELPERS, | ||
| 597 | }; | 602 | }; |
| 598 | 603 | ||
| 599 | #define PIN_IRQ_PENDING (BIT(INTERRUPT_STS_OFF) | BIT(WAKE_STS_OFF)) | 604 | #define PIN_IRQ_PENDING (BIT(INTERRUPT_STS_OFF) | BIT(WAKE_STS_OFF)) |
| @@ -1026,7 +1031,7 @@ static int amd_gpio_probe(struct platform_device *pdev) · 426 unmodified lines | |||
| 1026 | amd_gpio_irq_init(gpio_dev); | 1031 | amd_gpio_irq_init(gpio_dev); |
| 1027 | 1032 | ||
| 1028 | girq = &gpio_dev->gc.irq; | 1033 | girq = &gpio_dev->gc.irq; |
| 1029 | girq->chip = &amd_gpio_irqchip; | 1034 | gpio_irq_chip_set_chip(girq, &amd_gpio_irqchip); |
| 1030 | /* This will let us handle the parent IRQ in the driver */ | 1035 | /* This will let us handle the parent IRQ in the driver */ |
| 1031 | girq->parent_handler = NULL; | 1036 | girq->parent_handler = NULL; |
| 1032 | girq->num_parents = 0; | 1037 | girq->num_parents = 0; |
| @@ -36,7 +36,6 @@ struct apple_gpio_pinctrl { · 35 unmodified lines | |||
| 36 | 36 | ||
| 37 | struct pinctrl_desc pinctrl_desc; | 37 | struct pinctrl_desc pinctrl_desc; |
| 38 | struct gpio_chip gpio_chip; | 38 | struct gpio_chip gpio_chip; |
| 39 | struct irq_chip irq_chip; | ||
| 40 | u8 irqgrps[]; | 39 | u8 irqgrps[]; |
| 41 | }; | 40 | }; |
| 42 | 41 | ||
| @@ -275,17 +274,21 @@ static unsigned int apple_gpio_irq_type(unsigned int type) · 232 unmodified lines | |||
| 275 | 274 | ||
| 276 | static void apple_gpio_irq_mask(struct irq_data *data) | 275 | static void apple_gpio_irq_mask(struct irq_data *data) |
| 277 | { | 276 | { |
| 278 | struct apple_gpio_pinctrl *pctl = gpiochip_get_data(irq_data_get_irq_chip_data(data)); | 277 | struct gpio_chip *gc = irq_data_get_irq_chip_data(data); |
| 278 | struct apple_gpio_pinctrl *pctl = gpiochip_get_data(gc); | ||
| 279 | 279 | ||
| 280 | apple_gpio_set_reg(pctl, data->hwirq, REG_GPIOx_MODE, | 280 | apple_gpio_set_reg(pctl, data->hwirq, REG_GPIOx_MODE, |
| 281 | FIELD_PREP(REG_GPIOx_MODE, REG_GPIOx_IN_IRQ_OFF)); | 281 | FIELD_PREP(REG_GPIOx_MODE, REG_GPIOx_IN_IRQ_OFF)); |
| 282 | gpiochip_disable_irq(gc, data->hwirq); | ||
| 282 | } | 283 | } |
| 283 | 284 | ||
| 284 | static void apple_gpio_irq_unmask(struct irq_data *data) | 285 | static void apple_gpio_irq_unmask(struct irq_data *data) |
| 285 | { | 286 | { |
| 286 | struct apple_gpio_pinctrl *pctl = gpiochip_get_data(irq_data_get_irq_chip_data(data)); | 287 | struct gpio_chip *gc = irq_data_get_irq_chip_data(data); |
| 288 | struct apple_gpio_pinctrl *pctl = gpiochip_get_data(gc); | ||
| 287 | unsigned int irqtype = apple_gpio_irq_type(irqd_get_trigger_type(data)); | 289 | unsigned int irqtype = apple_gpio_irq_type(irqd_get_trigger_type(data)); |
| 288 | 290 | ||
| 291 | gpiochip_enable_irq(gc, data->hwirq); | ||
| 289 | apple_gpio_set_reg(pctl, data->hwirq, REG_GPIOx_MODE, | 292 | apple_gpio_set_reg(pctl, data->hwirq, REG_GPIOx_MODE, |
| 290 | FIELD_PREP(REG_GPIOx_MODE, irqtype)); | 293 | FIELD_PREP(REG_GPIOx_MODE, irqtype)); |
| 291 | } | 294 | } |
| @@ -343,13 +346,15 @@ static void apple_gpio_irq_handler(struct irq_desc *desc) · 51 unmodified lines | |||
| 343 | chained_irq_exit(chip, desc); | 346 | chained_irq_exit(chip, desc); |
| 344 | } | 347 | } |
| 345 | 348 | ||
| 346 | static struct irq_chip apple_gpio_irqchip = { | 349 | static const struct irq_chip apple_gpio_irqchip = { |
| 347 | .name = "Apple-GPIO", | 350 | .name = "Apple-GPIO", |
| 348 | .irq_startup = apple_gpio_irq_startup, | 351 | .irq_startup = apple_gpio_irq_startup, |
| 349 | .irq_ack = apple_gpio_irq_ack, | 352 | .irq_ack = apple_gpio_irq_ack, |
| 350 | .irq_mask = apple_gpio_irq_mask, | 353 | .irq_mask = apple_gpio_irq_mask, |
| 351 | .irq_unmask = apple_gpio_irq_unmask, | 354 | .irq_unmask = apple_gpio_irq_unmask, |
| 352 | .irq_set_type = apple_gpio_irq_set_type, | 355 | .irq_set_type = apple_gpio_irq_set_type, |
| 356 | .flags = IRQCHIP_IMMUTABLE, | ||
| 357 | GPIOCHIP_IRQ_RESOURCE_HELPERS, | ||
| 353 | }; | 358 | }; |
| 354 | 359 | ||
| 355 | /* Probe & register */ | 360 | /* Probe & register */ |
| @@ -360,8 +365,6 @@ static int apple_gpio_register(struct apple_gpio_pinctrl *pctl) · 4 unmodified lines | |||
| 360 | void **irq_data = NULL; | 365 | void **irq_data = NULL; |
| 361 | int ret; | 366 | int ret; |
| 362 | 367 | ||
| 363 | pctl->irq_chip = apple_gpio_irqchip; | ||
| 364 | |||
| 365 | pctl->gpio_chip.label = dev_name(pctl->dev); | 368 | pctl->gpio_chip.label = dev_name(pctl->dev); |
| 366 | pctl->gpio_chip.request = gpiochip_generic_request; | 369 | pctl->gpio_chip.request = gpiochip_generic_request; |
| 367 | pctl->gpio_chip.free = gpiochip_generic_free; | 370 | pctl->gpio_chip.free = gpiochip_generic_free; |
| @@ -377,7 +380,7 @@ static int apple_gpio_register(struct apple_gpio_pinctrl *pctl) · 9 unmodified lines | |||
| 377 | if (girq->num_parents) { | 380 | if (girq->num_parents) { |
| 378 | int i; | 381 | int i; |
| 379 | 382 | ||
| 380 | girq->chip = &pctl->irq_chip; | 383 | gpio_irq_chip_set_chip(girq, &apple_gpio_irqchip); |
| 381 | girq->parent_handler = apple_gpio_irq_handler; | 384 | girq->parent_handler = apple_gpio_irq_handler; |
| 382 | 385 | ||
| 383 | girq->parents = kmalloc_array(girq->num_parents, | 386 | girq->parents = kmalloc_array(girq->num_parents, |
| @@ -42,7 +42,6 @@ · 41 unmodified lines | |||
| 42 | * @chip: gpiochip handle. | 42 | * @chip: gpiochip handle. |
| 43 | * @desc: pin controller descriptor | 43 | * @desc: pin controller descriptor |
| 44 | * @restart_nb: restart notifier block. | 44 | * @restart_nb: restart notifier block. |
| 45 | * @irq_chip: irq chip information | ||
| 46 | * @irq: parent irq for the TLMM irq_chip. | 45 | * @irq: parent irq for the TLMM irq_chip. |
| 47 | * @intr_target_use_scm: route irq to application cpu using scm calls | 46 | * @intr_target_use_scm: route irq to application cpu using scm calls |
| 48 | * @lock: Spinlock to protect register resources as well | 47 | * @lock: Spinlock to protect register resources as well |
| @@ -63,7 +62,6 @@ struct msm_pinctrl { · 14 unmodified lines | |||
| 63 | struct pinctrl_desc desc; | 62 | struct pinctrl_desc desc; |
| 64 | struct notifier_block restart_nb; | 63 | struct notifier_block restart_nb; |
| 65 | 64 | ||
| 66 | struct irq_chip irq_chip; | ||
| 67 | int irq; | 65 | int irq; |
| 68 | 66 | ||
| 69 | bool intr_target_use_scm; | 67 | bool intr_target_use_scm; |
| @@ -868,6 +866,8 @@ static void msm_gpio_irq_enable(struct irq_data *d) · 798 unmodified lines | |||
| 868 | struct gpio_chip *gc = irq_data_get_irq_chip_data(d); | 866 | struct gpio_chip *gc = irq_data_get_irq_chip_data(d); |
| 869 | struct msm_pinctrl *pctrl = gpiochip_get_data(gc); | 867 | struct msm_pinctrl *pctrl = gpiochip_get_data(gc); |
| 870 | 868 | ||
| 869 | gpiochip_enable_irq(gc, d->hwirq); | ||
| 870 | |||
| 871 | if (d->parent_data) | 871 | if (d->parent_data) |
| 872 | irq_chip_enable_parent(d); | 872 | irq_chip_enable_parent(d); |
| 873 | 873 | ||
| @@ -885,6 +885,8 @@ static void msm_gpio_irq_disable(struct irq_data *d) · 11 unmodified lines | |||
| 885 | 885 | ||
| 886 | if (!test_bit(d->hwirq, pctrl->skip_wake_irqs)) | 886 | if (!test_bit(d->hwirq, pctrl->skip_wake_irqs)) |
| 887 | msm_gpio_irq_mask(d); | 887 | msm_gpio_irq_mask(d); |
| 888 | |||
| 889 | gpiochip_disable_irq(gc, d->hwirq); | ||
| 888 | } | 890 | } |
| 889 | 891 | ||
| 890 | /** | 892 | /** |
| @@ -958,6 +960,14 @@ static void msm_gpio_irq_ack(struct irq_data *d) · 67 unmodified lines | |||
| 958 | raw_spin_unlock_irqrestore(&pctrl->lock, flags); | 960 | raw_spin_unlock_irqrestore(&pctrl->lock, flags); |
| 959 | } | 961 | } |
| 960 | 962 | ||
| 963 | static void msm_gpio_irq_eoi(struct irq_data *d) | ||
| 964 | { | ||
| 965 | d = d->parent_data; | ||
| 966 | |||
| 967 | if (d) | ||
| 968 | d->chip->irq_eoi(d); | ||
| 969 | } | ||
| 970 | |||
| 961 | static bool msm_gpio_needs_dual_edge_parent_workaround(struct irq_data *d, | 971 | static bool msm_gpio_needs_dual_edge_parent_workaround(struct irq_data *d, |
| 962 | unsigned int type) | 972 | unsigned int type) |
| 963 | { | 973 | { |
| @@ -1255,6 +1265,26 @@ static bool msm_gpio_needs_valid_mask(struct msm_pinctrl *pctrl) · 291 unmodified lines | |||
| 1255 | return device_property_count_u16(pctrl->dev, "gpios") > 0; | 1265 | return device_property_count_u16(pctrl->dev, "gpios") > 0; |
| 1256 | } | 1266 | } |
| 1257 | 1267 | ||
| 1268 | static const struct irq_chip msm_gpio_irq_chip = { | ||
| 1269 | .name = "msmgpio", | ||
| 1270 | .irq_enable = msm_gpio_irq_enable, | ||
| 1271 | .irq_disable = msm_gpio_irq_disable, | ||
| 1272 | .irq_mask = msm_gpio_irq_mask, | ||
| 1273 | .irq_unmask = msm_gpio_irq_unmask, | ||
| 1274 | .irq_ack = msm_gpio_irq_ack, | ||
| 1275 | .irq_eoi = msm_gpio_irq_eoi, | ||
| 1276 | .irq_set_type = msm_gpio_irq_set_type, | ||
| 1277 | .irq_set_wake = msm_gpio_irq_set_wake, | ||
| 1278 | .irq_request_resources = msm_gpio_irq_reqres, | ||
| 1279 | .irq_release_resources = msm_gpio_irq_relres, | ||
| 1280 | .irq_set_affinity = msm_gpio_irq_set_affinity, | ||
| 1281 | .irq_set_vcpu_affinity = msm_gpio_irq_set_vcpu_affinity, | ||
| 1282 | .flags = (IRQCHIP_MASK_ON_SUSPEND | | ||
| 1283 | IRQCHIP_SET_TYPE_MASKED | | ||
| 1284 | IRQCHIP_ENABLE_WAKEUP_ON_SUSPEND | | ||
| 1285 | IRQCHIP_IMMUTABLE), | ||
| 1286 | }; | ||
| 1287 | |||
| 1258 | static int msm_gpio_init(struct msm_pinctrl *pctrl) | 1288 | static int msm_gpio_init(struct msm_pinctrl *pctrl) |
| 1259 | { | 1289 | { |
| 1260 | struct gpio_chip *chip; | 1290 | struct gpio_chip *chip; |
| @@ -1276,22 +1306,6 @@ static int msm_gpio_init(struct msm_pinctrl *pctrl) · 15 unmodified lines | |||
| 1276 | if (msm_gpio_needs_valid_mask(pctrl)) | 1306 | if (msm_gpio_needs_valid_mask(pctrl)) |
| 1277 | chip->init_valid_mask = msm_gpio_init_valid_mask; | 1307 | chip->init_valid_mask = msm_gpio_init_valid_mask; |
| 1278 | 1308 | ||
| 1279 | pctrl->irq_chip.name = "msmgpio"; | ||
| 1280 | pctrl->irq_chip.irq_enable = msm_gpio_irq_enable; | ||
| 1281 | pctrl->irq_chip.irq_disable = msm_gpio_irq_disable; | ||
| 1282 | pctrl->irq_chip.irq_mask = msm_gpio_irq_mask; | ||
| 1283 | pctrl->irq_chip.irq_unmask = msm_gpio_irq_unmask; | ||
| 1284 | pctrl->irq_chip.irq_ack = msm_gpio_irq_ack; | ||
| 1285 | pctrl->irq_chip.irq_set_type = msm_gpio_irq_set_type; | ||
| 1286 | pctrl->irq_chip.irq_set_wake = msm_gpio_irq_set_wake; | ||
| 1287 | pctrl->irq_chip.irq_request_resources = msm_gpio_irq_reqres; | ||
| 1288 | pctrl->irq_chip.irq_release_resources = msm_gpio_irq_relres; | ||
| 1289 | pctrl->irq_chip.irq_set_affinity = msm_gpio_irq_set_affinity; | ||
| 1290 | pctrl->irq_chip.irq_set_vcpu_affinity = msm_gpio_irq_set_vcpu_affinity; | ||
| 1291 | pctrl->irq_chip.flags = IRQCHIP_MASK_ON_SUSPEND | | ||
| 1292 | IRQCHIP_SET_TYPE_MASKED | | ||
| 1293 | IRQCHIP_ENABLE_WAKEUP_ON_SUSPEND; | ||
| 1294 | |||
| 1295 | np = of_parse_phandle(pctrl->dev->of_node, "wakeup-parent", 0); | 1309 | np = of_parse_phandle(pctrl->dev->of_node, "wakeup-parent", 0); |
| 1296 | if (np) { | 1310 | if (np) { |
| 1297 | chip->irq.parent_domain = irq_find_matching_host(np, | 1311 | chip->irq.parent_domain = irq_find_matching_host(np, |
| @@ -1300,7 +1314,6 @@ static int msm_gpio_init(struct msm_pinctrl *pctrl) · 2 unmodified lines | |||
| 1300 | if (!chip->irq.parent_domain) | 1314 | if (!chip->irq.parent_domain) |
| 1301 | return -EPROBE_DEFER; | 1315 | return -EPROBE_DEFER; |
| 1302 | chip->irq.child_to_parent_hwirq = msm_gpio_wakeirq; | 1316 | chip->irq.child_to_parent_hwirq = msm_gpio_wakeirq; |
| 1303 | pctrl->irq_chip.irq_eoi = irq_chip_eoi_parent; | ||
| 1304 | /* | 1317 | /* |
| 1305 | * Let's skip handling the GPIOs, if the parent irqchip | 1318 | * Let's skip handling the GPIOs, if the parent irqchip |
| 1306 | * is handling the direct connect IRQ of the GPIO. | 1319 | * is handling the direct connect IRQ of the GPIO. |
| @@ -1313,7 +1326,7 @@ static int msm_gpio_init(struct msm_pinctrl *pctrl) · 6 unmodified lines | |||
| 1313 | } | 1326 | } |
| 1314 | 1327 | ||
| 1315 | girq = &chip->irq; | 1328 | girq = &chip->irq; |
| 1316 | girq->chip = &pctrl->irq_chip; | 1329 | gpio_irq_chip_set_chip(girq, &msm_gpio_irq_chip); |
| 1317 | girq->parent_handler = msm_gpio_irq_handler; | 1330 | girq->parent_handler = msm_gpio_irq_handler; |
| 1318 | girq->fwnode = pctrl->dev->fwnode; | 1331 | girq->fwnode = pctrl->dev->fwnode; |
| 1319 | girq->num_parents = 1; | 1332 | girq->num_parents = 1; |
| @@ -588,6 +588,22 @@ void gpiochip_relres_irq(struct gpio_chip *gc, unsigned int offset); · 587 unmodified lines | |||
| 588 | void gpiochip_disable_irq(struct gpio_chip *gc, unsigned int offset); | 588 | void gpiochip_disable_irq(struct gpio_chip *gc, unsigned int offset); |
| 589 | void gpiochip_enable_irq(struct gpio_chip *gc, unsigned int offset); | 589 | void gpiochip_enable_irq(struct gpio_chip *gc, unsigned int offset); |
| 590 | 590 | ||
| 591 | /* irq_data versions of the above */ | ||
| 592 | int gpiochip_irq_reqres(struct irq_data *data); | ||
| 593 | void gpiochip_irq_relres(struct irq_data *data); | ||
| 594 | |||
| 595 | /* Paste this in your irq_chip structure */ | ||
| 596 | #define GPIOCHIP_IRQ_RESOURCE_HELPERS \ | ||
| 597 | .irq_request_resources = gpiochip_irq_reqres, \ | ||
| 598 | .irq_release_resources = gpiochip_irq_relres | ||
| 599 | |||
| 600 | static inline void gpio_irq_chip_set_chip(struct gpio_irq_chip *girq, | ||
| 601 | const struct irq_chip *chip) | ||
| 602 | { | ||
| 603 | /* Yes, dropping const is ugly, but it isn't like we have a choice */ | ||
| 604 | girq->chip = (struct irq_chip *)chip; | ||
| 605 | } | ||
| 606 | |||
| 591 | /* Line status inquiry for drivers */ | 607 | /* Line status inquiry for drivers */ |
| 592 | bool gpiochip_line_is_open_drain(struct gpio_chip *gc, unsigned int offset); | 608 | bool gpiochip_line_is_open_drain(struct gpio_chip *gc, unsigned int offset); |
| 593 | bool gpiochip_line_is_open_source(struct gpio_chip *gc, unsigned int offset); | 609 | bool gpiochip_line_is_open_source(struct gpio_chip *gc, unsigned int offset); |
| @@ -569,6 +569,7 @@ struct irq_chip { · 568 unmodified lines | |||
| 569 | * IRQCHIP_ENABLE_WAKEUP_ON_SUSPEND: Invokes __enable_irq()/__disable_irq() for wake irqs | 569 | * IRQCHIP_ENABLE_WAKEUP_ON_SUSPEND: Invokes __enable_irq()/__disable_irq() for wake irqs |
| 570 | * in the suspend path if they are in disabled state | 570 | * in the suspend path if they are in disabled state |
| 571 | * IRQCHIP_AFFINITY_PRE_STARTUP: Default affinity update before startup | 571 | * IRQCHIP_AFFINITY_PRE_STARTUP: Default affinity update before startup |
| 572 | * IRQCHIP_IMMUTABLE: Don't ever change anything in this chip | ||
| 572 | */ | 573 | */ |
| 573 | enum { | 574 | enum { |
| 574 | IRQCHIP_SET_TYPE_MASKED = (1 << 0), | 575 | IRQCHIP_SET_TYPE_MASKED = (1 << 0), |
| @@ -582,6 +583,7 @@ enum { · 7 unmodified lines | |||
| 582 | IRQCHIP_SUPPORTS_NMI = (1 << 8), | 583 | IRQCHIP_SUPPORTS_NMI = (1 << 8), |
| 583 | IRQCHIP_ENABLE_WAKEUP_ON_SUSPEND = (1 << 9), | 584 | IRQCHIP_ENABLE_WAKEUP_ON_SUSPEND = (1 << 9), |
| 584 | IRQCHIP_AFFINITY_PRE_STARTUP = (1 << 10), | 585 | IRQCHIP_AFFINITY_PRE_STARTUP = (1 << 10), |
| 586 | IRQCHIP_IMMUTABLE = (1 << 11), | ||
| 585 | }; | 587 | }; |
| 586 | 588 | ||
| 587 | #include <linux/irqdesc.h> | 589 | #include <linux/irqdesc.h> |
| @@ -58,6 +58,7 @@ static const struct irq_bit_descr irqchip_flags[] = { · 57 unmodified lines | |||
| 58 | BIT_MASK_DESCR(IRQCHIP_SUPPORTS_LEVEL_MSI), | 58 | BIT_MASK_DESCR(IRQCHIP_SUPPORTS_LEVEL_MSI), |
| 59 | BIT_MASK_DESCR(IRQCHIP_SUPPORTS_NMI), | 59 | BIT_MASK_DESCR(IRQCHIP_SUPPORTS_NMI), |
| 60 | BIT_MASK_DESCR(IRQCHIP_ENABLE_WAKEUP_ON_SUSPEND), | 60 | BIT_MASK_DESCR(IRQCHIP_ENABLE_WAKEUP_ON_SUSPEND), |
| 61 | BIT_MASK_DESCR(IRQCHIP_IMMUTABLE), | ||
| 61 | }; | 62 | }; |
| 62 | 63 | ||
| 63 | static void | 64 | static void |