diff options
author | Jon Hunter <jonathanh@nvidia.com> | 2016-05-10 11:14:43 -0400 |
---|---|---|
committer | Marc Zyngier <marc.zyngier@arm.com> | 2016-05-11 05:12:43 -0400 |
commit | 6e5b5924d9a897062527b6fc9b06f31f7bfd5744 (patch) | |
tree | d15998d2162addf6a9c49d0f656637356e487fb9 | |
parent | dc9722cc57eba336038b2ade111436656c5a87d0 (diff) |
irqchip/gic: Pass GIC pointer to save/restore functions
Instead of passing the GIC index to the save/restore functions pass a
pointer to the GIC chip data. This will allow these save/restore
functions to be re-used by a platform driver where the GIC chip data
structure is allocated dynamically and so there is no applicable index
for identifying the GIC.
Signed-off-by: Jon Hunter <jonathanh@nvidia.com>
Acked-by: Marc Zyngier <marc.zyngier@arm.com>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
-rw-r--r-- | drivers/irqchip/irq-gic.c | 74 |
1 files changed, 39 insertions, 35 deletions
diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c index 7cf138286442..d75aa1a8d6da 100644 --- a/drivers/irqchip/irq-gic.c +++ b/drivers/irqchip/irq-gic.c | |||
@@ -529,34 +529,35 @@ int gic_cpu_if_down(unsigned int gic_nr) | |||
529 | * this function, no interrupts will be delivered by the GIC, and another | 529 | * this function, no interrupts will be delivered by the GIC, and another |
530 | * platform-specific wakeup source must be enabled. | 530 | * platform-specific wakeup source must be enabled. |
531 | */ | 531 | */ |
532 | static void gic_dist_save(unsigned int gic_nr) | 532 | static void gic_dist_save(struct gic_chip_data *gic) |
533 | { | 533 | { |
534 | unsigned int gic_irqs; | 534 | unsigned int gic_irqs; |
535 | void __iomem *dist_base; | 535 | void __iomem *dist_base; |
536 | int i; | 536 | int i; |
537 | 537 | ||
538 | BUG_ON(gic_nr >= CONFIG_ARM_GIC_MAX_NR); | 538 | if (WARN_ON(!gic)) |
539 | return; | ||
539 | 540 | ||
540 | gic_irqs = gic_data[gic_nr].gic_irqs; | 541 | gic_irqs = gic->gic_irqs; |
541 | dist_base = gic_data_dist_base(&gic_data[gic_nr]); | 542 | dist_base = gic_data_dist_base(gic); |
542 | 543 | ||
543 | if (!dist_base) | 544 | if (!dist_base) |
544 | return; | 545 | return; |
545 | 546 | ||
546 | for (i = 0; i < DIV_ROUND_UP(gic_irqs, 16); i++) | 547 | for (i = 0; i < DIV_ROUND_UP(gic_irqs, 16); i++) |
547 | gic_data[gic_nr].saved_spi_conf[i] = | 548 | gic->saved_spi_conf[i] = |
548 | readl_relaxed(dist_base + GIC_DIST_CONFIG + i * 4); | 549 | readl_relaxed(dist_base + GIC_DIST_CONFIG + i * 4); |
549 | 550 | ||
550 | for (i = 0; i < DIV_ROUND_UP(gic_irqs, 4); i++) | 551 | for (i = 0; i < DIV_ROUND_UP(gic_irqs, 4); i++) |
551 | gic_data[gic_nr].saved_spi_target[i] = | 552 | gic->saved_spi_target[i] = |
552 | readl_relaxed(dist_base + GIC_DIST_TARGET + i * 4); | 553 | readl_relaxed(dist_base + GIC_DIST_TARGET + i * 4); |
553 | 554 | ||
554 | for (i = 0; i < DIV_ROUND_UP(gic_irqs, 32); i++) | 555 | for (i = 0; i < DIV_ROUND_UP(gic_irqs, 32); i++) |
555 | gic_data[gic_nr].saved_spi_enable[i] = | 556 | gic->saved_spi_enable[i] = |
556 | readl_relaxed(dist_base + GIC_DIST_ENABLE_SET + i * 4); | 557 | readl_relaxed(dist_base + GIC_DIST_ENABLE_SET + i * 4); |
557 | 558 | ||
558 | for (i = 0; i < DIV_ROUND_UP(gic_irqs, 32); i++) | 559 | for (i = 0; i < DIV_ROUND_UP(gic_irqs, 32); i++) |
559 | gic_data[gic_nr].saved_spi_active[i] = | 560 | gic->saved_spi_active[i] = |
560 | readl_relaxed(dist_base + GIC_DIST_ACTIVE_SET + i * 4); | 561 | readl_relaxed(dist_base + GIC_DIST_ACTIVE_SET + i * 4); |
561 | } | 562 | } |
562 | 563 | ||
@@ -567,16 +568,17 @@ static void gic_dist_save(unsigned int gic_nr) | |||
567 | * handled normally, but any edge interrupts that occured will not be seen by | 568 | * handled normally, but any edge interrupts that occured will not be seen by |
568 | * the GIC and need to be handled by the platform-specific wakeup source. | 569 | * the GIC and need to be handled by the platform-specific wakeup source. |
569 | */ | 570 | */ |
570 | static void gic_dist_restore(unsigned int gic_nr) | 571 | static void gic_dist_restore(struct gic_chip_data *gic) |
571 | { | 572 | { |
572 | unsigned int gic_irqs; | 573 | unsigned int gic_irqs; |
573 | unsigned int i; | 574 | unsigned int i; |
574 | void __iomem *dist_base; | 575 | void __iomem *dist_base; |
575 | 576 | ||
576 | BUG_ON(gic_nr >= CONFIG_ARM_GIC_MAX_NR); | 577 | if (WARN_ON(!gic)) |
578 | return; | ||
577 | 579 | ||
578 | gic_irqs = gic_data[gic_nr].gic_irqs; | 580 | gic_irqs = gic->gic_irqs; |
579 | dist_base = gic_data_dist_base(&gic_data[gic_nr]); | 581 | dist_base = gic_data_dist_base(gic); |
580 | 582 | ||
581 | if (!dist_base) | 583 | if (!dist_base) |
582 | return; | 584 | return; |
@@ -584,7 +586,7 @@ static void gic_dist_restore(unsigned int gic_nr) | |||
584 | writel_relaxed(GICD_DISABLE, dist_base + GIC_DIST_CTRL); | 586 | writel_relaxed(GICD_DISABLE, dist_base + GIC_DIST_CTRL); |
585 | 587 | ||
586 | for (i = 0; i < DIV_ROUND_UP(gic_irqs, 16); i++) | 588 | for (i = 0; i < DIV_ROUND_UP(gic_irqs, 16); i++) |
587 | writel_relaxed(gic_data[gic_nr].saved_spi_conf[i], | 589 | writel_relaxed(gic->saved_spi_conf[i], |
588 | dist_base + GIC_DIST_CONFIG + i * 4); | 590 | dist_base + GIC_DIST_CONFIG + i * 4); |
589 | 591 | ||
590 | for (i = 0; i < DIV_ROUND_UP(gic_irqs, 4); i++) | 592 | for (i = 0; i < DIV_ROUND_UP(gic_irqs, 4); i++) |
@@ -592,85 +594,87 @@ static void gic_dist_restore(unsigned int gic_nr) | |||
592 | dist_base + GIC_DIST_PRI + i * 4); | 594 | dist_base + GIC_DIST_PRI + i * 4); |
593 | 595 | ||
594 | for (i = 0; i < DIV_ROUND_UP(gic_irqs, 4); i++) | 596 | for (i = 0; i < DIV_ROUND_UP(gic_irqs, 4); i++) |
595 | writel_relaxed(gic_data[gic_nr].saved_spi_target[i], | 597 | writel_relaxed(gic->saved_spi_target[i], |
596 | dist_base + GIC_DIST_TARGET + i * 4); | 598 | dist_base + GIC_DIST_TARGET + i * 4); |
597 | 599 | ||
598 | for (i = 0; i < DIV_ROUND_UP(gic_irqs, 32); i++) { | 600 | for (i = 0; i < DIV_ROUND_UP(gic_irqs, 32); i++) { |
599 | writel_relaxed(GICD_INT_EN_CLR_X32, | 601 | writel_relaxed(GICD_INT_EN_CLR_X32, |
600 | dist_base + GIC_DIST_ENABLE_CLEAR + i * 4); | 602 | dist_base + GIC_DIST_ENABLE_CLEAR + i * 4); |
601 | writel_relaxed(gic_data[gic_nr].saved_spi_enable[i], | 603 | writel_relaxed(gic->saved_spi_enable[i], |
602 | dist_base + GIC_DIST_ENABLE_SET + i * 4); | 604 | dist_base + GIC_DIST_ENABLE_SET + i * 4); |
603 | } | 605 | } |
604 | 606 | ||
605 | for (i = 0; i < DIV_ROUND_UP(gic_irqs, 32); i++) { | 607 | for (i = 0; i < DIV_ROUND_UP(gic_irqs, 32); i++) { |
606 | writel_relaxed(GICD_INT_EN_CLR_X32, | 608 | writel_relaxed(GICD_INT_EN_CLR_X32, |
607 | dist_base + GIC_DIST_ACTIVE_CLEAR + i * 4); | 609 | dist_base + GIC_DIST_ACTIVE_CLEAR + i * 4); |
608 | writel_relaxed(gic_data[gic_nr].saved_spi_active[i], | 610 | writel_relaxed(gic->saved_spi_active[i], |
609 | dist_base + GIC_DIST_ACTIVE_SET + i * 4); | 611 | dist_base + GIC_DIST_ACTIVE_SET + i * 4); |
610 | } | 612 | } |
611 | 613 | ||
612 | writel_relaxed(GICD_ENABLE, dist_base + GIC_DIST_CTRL); | 614 | writel_relaxed(GICD_ENABLE, dist_base + GIC_DIST_CTRL); |
613 | } | 615 | } |
614 | 616 | ||
615 | static void gic_cpu_save(unsigned int gic_nr) | 617 | static void gic_cpu_save(struct gic_chip_data *gic) |
616 | { | 618 | { |
617 | int i; | 619 | int i; |
618 | u32 *ptr; | 620 | u32 *ptr; |
619 | void __iomem *dist_base; | 621 | void __iomem *dist_base; |
620 | void __iomem *cpu_base; | 622 | void __iomem *cpu_base; |
621 | 623 | ||
622 | BUG_ON(gic_nr >= CONFIG_ARM_GIC_MAX_NR); | 624 | if (WARN_ON(!gic)) |
625 | return; | ||
623 | 626 | ||
624 | dist_base = gic_data_dist_base(&gic_data[gic_nr]); | 627 | dist_base = gic_data_dist_base(gic); |
625 | cpu_base = gic_data_cpu_base(&gic_data[gic_nr]); | 628 | cpu_base = gic_data_cpu_base(gic); |
626 | 629 | ||
627 | if (!dist_base || !cpu_base) | 630 | if (!dist_base || !cpu_base) |
628 | return; | 631 | return; |
629 | 632 | ||
630 | ptr = raw_cpu_ptr(gic_data[gic_nr].saved_ppi_enable); | 633 | ptr = raw_cpu_ptr(gic->saved_ppi_enable); |
631 | for (i = 0; i < DIV_ROUND_UP(32, 32); i++) | 634 | for (i = 0; i < DIV_ROUND_UP(32, 32); i++) |
632 | ptr[i] = readl_relaxed(dist_base + GIC_DIST_ENABLE_SET + i * 4); | 635 | ptr[i] = readl_relaxed(dist_base + GIC_DIST_ENABLE_SET + i * 4); |
633 | 636 | ||
634 | ptr = raw_cpu_ptr(gic_data[gic_nr].saved_ppi_active); | 637 | ptr = raw_cpu_ptr(gic->saved_ppi_active); |
635 | for (i = 0; i < DIV_ROUND_UP(32, 32); i++) | 638 | for (i = 0; i < DIV_ROUND_UP(32, 32); i++) |
636 | ptr[i] = readl_relaxed(dist_base + GIC_DIST_ACTIVE_SET + i * 4); | 639 | ptr[i] = readl_relaxed(dist_base + GIC_DIST_ACTIVE_SET + i * 4); |
637 | 640 | ||
638 | ptr = raw_cpu_ptr(gic_data[gic_nr].saved_ppi_conf); | 641 | ptr = raw_cpu_ptr(gic->saved_ppi_conf); |
639 | for (i = 0; i < DIV_ROUND_UP(32, 16); i++) | 642 | for (i = 0; i < DIV_ROUND_UP(32, 16); i++) |
640 | ptr[i] = readl_relaxed(dist_base + GIC_DIST_CONFIG + i * 4); | 643 | ptr[i] = readl_relaxed(dist_base + GIC_DIST_CONFIG + i * 4); |
641 | 644 | ||
642 | } | 645 | } |
643 | 646 | ||
644 | static void gic_cpu_restore(unsigned int gic_nr) | 647 | static void gic_cpu_restore(struct gic_chip_data *gic) |
645 | { | 648 | { |
646 | int i; | 649 | int i; |
647 | u32 *ptr; | 650 | u32 *ptr; |
648 | void __iomem *dist_base; | 651 | void __iomem *dist_base; |
649 | void __iomem *cpu_base; | 652 | void __iomem *cpu_base; |
650 | 653 | ||
651 | BUG_ON(gic_nr >= CONFIG_ARM_GIC_MAX_NR); | 654 | if (WARN_ON(!gic)) |
655 | return; | ||
652 | 656 | ||
653 | dist_base = gic_data_dist_base(&gic_data[gic_nr]); | 657 | dist_base = gic_data_dist_base(gic); |
654 | cpu_base = gic_data_cpu_base(&gic_data[gic_nr]); | 658 | cpu_base = gic_data_cpu_base(gic); |
655 | 659 | ||
656 | if (!dist_base || !cpu_base) | 660 | if (!dist_base || !cpu_base) |
657 | return; | 661 | return; |
658 | 662 | ||
659 | ptr = raw_cpu_ptr(gic_data[gic_nr].saved_ppi_enable); | 663 | ptr = raw_cpu_ptr(gic->saved_ppi_enable); |
660 | for (i = 0; i < DIV_ROUND_UP(32, 32); i++) { | 664 | for (i = 0; i < DIV_ROUND_UP(32, 32); i++) { |
661 | writel_relaxed(GICD_INT_EN_CLR_X32, | 665 | writel_relaxed(GICD_INT_EN_CLR_X32, |
662 | dist_base + GIC_DIST_ENABLE_CLEAR + i * 4); | 666 | dist_base + GIC_DIST_ENABLE_CLEAR + i * 4); |
663 | writel_relaxed(ptr[i], dist_base + GIC_DIST_ENABLE_SET + i * 4); | 667 | writel_relaxed(ptr[i], dist_base + GIC_DIST_ENABLE_SET + i * 4); |
664 | } | 668 | } |
665 | 669 | ||
666 | ptr = raw_cpu_ptr(gic_data[gic_nr].saved_ppi_active); | 670 | ptr = raw_cpu_ptr(gic->saved_ppi_active); |
667 | for (i = 0; i < DIV_ROUND_UP(32, 32); i++) { | 671 | for (i = 0; i < DIV_ROUND_UP(32, 32); i++) { |
668 | writel_relaxed(GICD_INT_EN_CLR_X32, | 672 | writel_relaxed(GICD_INT_EN_CLR_X32, |
669 | dist_base + GIC_DIST_ACTIVE_CLEAR + i * 4); | 673 | dist_base + GIC_DIST_ACTIVE_CLEAR + i * 4); |
670 | writel_relaxed(ptr[i], dist_base + GIC_DIST_ACTIVE_SET + i * 4); | 674 | writel_relaxed(ptr[i], dist_base + GIC_DIST_ACTIVE_SET + i * 4); |
671 | } | 675 | } |
672 | 676 | ||
673 | ptr = raw_cpu_ptr(gic_data[gic_nr].saved_ppi_conf); | 677 | ptr = raw_cpu_ptr(gic->saved_ppi_conf); |
674 | for (i = 0; i < DIV_ROUND_UP(32, 16); i++) | 678 | for (i = 0; i < DIV_ROUND_UP(32, 16); i++) |
675 | writel_relaxed(ptr[i], dist_base + GIC_DIST_CONFIG + i * 4); | 679 | writel_relaxed(ptr[i], dist_base + GIC_DIST_CONFIG + i * 4); |
676 | 680 | ||
@@ -679,7 +683,7 @@ static void gic_cpu_restore(unsigned int gic_nr) | |||
679 | dist_base + GIC_DIST_PRI + i * 4); | 683 | dist_base + GIC_DIST_PRI + i * 4); |
680 | 684 | ||
681 | writel_relaxed(GICC_INT_PRI_THRESHOLD, cpu_base + GIC_CPU_PRIMASK); | 685 | writel_relaxed(GICC_INT_PRI_THRESHOLD, cpu_base + GIC_CPU_PRIMASK); |
682 | gic_cpu_if_up(&gic_data[gic_nr]); | 686 | gic_cpu_if_up(gic); |
683 | } | 687 | } |
684 | 688 | ||
685 | static int gic_notifier(struct notifier_block *self, unsigned long cmd, void *v) | 689 | static int gic_notifier(struct notifier_block *self, unsigned long cmd, void *v) |
@@ -694,18 +698,18 @@ static int gic_notifier(struct notifier_block *self, unsigned long cmd, void *v) | |||
694 | #endif | 698 | #endif |
695 | switch (cmd) { | 699 | switch (cmd) { |
696 | case CPU_PM_ENTER: | 700 | case CPU_PM_ENTER: |
697 | gic_cpu_save(i); | 701 | gic_cpu_save(&gic_data[i]); |
698 | break; | 702 | break; |
699 | case CPU_PM_ENTER_FAILED: | 703 | case CPU_PM_ENTER_FAILED: |
700 | case CPU_PM_EXIT: | 704 | case CPU_PM_EXIT: |
701 | gic_cpu_restore(i); | 705 | gic_cpu_restore(&gic_data[i]); |
702 | break; | 706 | break; |
703 | case CPU_CLUSTER_PM_ENTER: | 707 | case CPU_CLUSTER_PM_ENTER: |
704 | gic_dist_save(i); | 708 | gic_dist_save(&gic_data[i]); |
705 | break; | 709 | break; |
706 | case CPU_CLUSTER_PM_ENTER_FAILED: | 710 | case CPU_CLUSTER_PM_ENTER_FAILED: |
707 | case CPU_CLUSTER_PM_EXIT: | 711 | case CPU_CLUSTER_PM_EXIT: |
708 | gic_dist_restore(i); | 712 | gic_dist_restore(&gic_data[i]); |
709 | break; | 713 | break; |
710 | } | 714 | } |
711 | } | 715 | } |