diff options
author | David Daney <ddaney@caviumnetworks.com> | 2010-07-23 13:43:47 -0400 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2010-08-05 08:26:10 -0400 |
commit | 3508920f5811fcb8bdbf02943eb5ed531834bbc4 (patch) | |
tree | 20e03cb5fb1d982990760bccdbccde4736e14d85 /arch/mips/cavium-octeon/octeon-irq.c | |
parent | 5aae1fd4d41ea69da845e11d4766ab61666494ed (diff) |
MIPS: Octeon: Fix fixup_irqs for HOTPLUG_CPU
The original version went behind the back of everything, leaving
things in an inconsistent state.
Now we use the irq_set_affinity() to do the work for us. This has the
advantage that the IRQ core's view of the affinity stays consistent.
Signed-off-by: David Daney <ddaney@caviumnetworks.com>
To: linux-mips@linux-mips.org
Patchwork: https://patchwork.linux-mips.org/patch/1486/
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Diffstat (limited to 'arch/mips/cavium-octeon/octeon-irq.c')
-rw-r--r-- | arch/mips/cavium-octeon/octeon-irq.c | 108 |
1 files changed, 69 insertions, 39 deletions
diff --git a/arch/mips/cavium-octeon/octeon-irq.c b/arch/mips/cavium-octeon/octeon-irq.c index 8fb9fb667779..ce7500cdf5b7 100644 --- a/arch/mips/cavium-octeon/octeon-irq.c +++ b/arch/mips/cavium-octeon/octeon-irq.c | |||
@@ -788,54 +788,84 @@ asmlinkage void plat_irq_dispatch(void) | |||
788 | } | 788 | } |
789 | 789 | ||
790 | #ifdef CONFIG_HOTPLUG_CPU | 790 | #ifdef CONFIG_HOTPLUG_CPU |
791 | static int is_irq_enabled_on_cpu(unsigned int irq, unsigned int cpu) | ||
792 | { | ||
793 | unsigned int isset; | ||
794 | int coreid = octeon_coreid_for_cpu(cpu); | ||
795 | int bit = (irq < OCTEON_IRQ_WDOG0) ? | ||
796 | irq - OCTEON_IRQ_WORKQ0 : irq - OCTEON_IRQ_WDOG0; | ||
797 | if (irq < 64) { | ||
798 | isset = (cvmx_read_csr(CVMX_CIU_INTX_EN0(coreid * 2)) & | ||
799 | (1ull << bit)) >> bit; | ||
800 | } else { | ||
801 | isset = (cvmx_read_csr(CVMX_CIU_INTX_EN1(coreid * 2 + 1)) & | ||
802 | (1ull << bit)) >> bit; | ||
803 | } | ||
804 | return isset; | ||
805 | } | ||
806 | 791 | ||
807 | void fixup_irqs(void) | 792 | void fixup_irqs(void) |
808 | { | 793 | { |
809 | int irq; | 794 | int irq; |
795 | struct irq_desc *desc; | ||
796 | cpumask_t new_affinity; | ||
797 | unsigned long flags; | ||
798 | int do_set_affinity; | ||
799 | int cpu; | ||
800 | |||
801 | cpu = smp_processor_id(); | ||
810 | 802 | ||
811 | for (irq = OCTEON_IRQ_SW0; irq <= OCTEON_IRQ_TIMER; irq++) | 803 | for (irq = OCTEON_IRQ_SW0; irq <= OCTEON_IRQ_TIMER; irq++) |
812 | octeon_irq_core_disable_local(irq); | 804 | octeon_irq_core_disable_local(irq); |
813 | 805 | ||
814 | for (irq = OCTEON_IRQ_WORKQ0; irq <= OCTEON_IRQ_GPIO15; irq++) { | 806 | for (irq = OCTEON_IRQ_WORKQ0; irq < OCTEON_IRQ_LAST; irq++) { |
815 | if (is_irq_enabled_on_cpu(irq, smp_processor_id())) { | 807 | desc = irq_to_desc(irq); |
816 | /* ciu irq migrates to next cpu */ | 808 | switch (irq) { |
817 | octeon_irq_chip_ciu0.disable(irq); | 809 | case OCTEON_IRQ_MBOX0: |
818 | octeon_irq_ciu0_set_affinity(irq, &cpu_online_map); | 810 | case OCTEON_IRQ_MBOX1: |
819 | } | 811 | /* The eoi function will disable them on this CPU. */ |
820 | } | 812 | desc->chip->eoi(irq); |
813 | break; | ||
814 | case OCTEON_IRQ_WDOG0: | ||
815 | case OCTEON_IRQ_WDOG1: | ||
816 | case OCTEON_IRQ_WDOG2: | ||
817 | case OCTEON_IRQ_WDOG3: | ||
818 | case OCTEON_IRQ_WDOG4: | ||
819 | case OCTEON_IRQ_WDOG5: | ||
820 | case OCTEON_IRQ_WDOG6: | ||
821 | case OCTEON_IRQ_WDOG7: | ||
822 | case OCTEON_IRQ_WDOG8: | ||
823 | case OCTEON_IRQ_WDOG9: | ||
824 | case OCTEON_IRQ_WDOG10: | ||
825 | case OCTEON_IRQ_WDOG11: | ||
826 | case OCTEON_IRQ_WDOG12: | ||
827 | case OCTEON_IRQ_WDOG13: | ||
828 | case OCTEON_IRQ_WDOG14: | ||
829 | case OCTEON_IRQ_WDOG15: | ||
830 | /* | ||
831 | * These have special per CPU semantics and | ||
832 | * are handled in the watchdog driver. | ||
833 | */ | ||
834 | break; | ||
835 | default: | ||
836 | raw_spin_lock_irqsave(&desc->lock, flags); | ||
837 | /* | ||
838 | * If this irq has an action, it is in use and | ||
839 | * must be migrated if it has affinity to this | ||
840 | * cpu. | ||
841 | */ | ||
842 | if (desc->action && cpumask_test_cpu(cpu, desc->affinity)) { | ||
843 | if (cpumask_weight(desc->affinity) > 1) { | ||
844 | /* | ||
845 | * It has multi CPU affinity, | ||
846 | * just remove this CPU from | ||
847 | * the affinity set. | ||
848 | */ | ||
849 | cpumask_copy(&new_affinity, desc->affinity); | ||
850 | cpumask_clear_cpu(cpu, &new_affinity); | ||
851 | } else { | ||
852 | /* | ||
853 | * Otherwise, put it on lowest | ||
854 | * numbered online CPU. | ||
855 | */ | ||
856 | cpumask_clear(&new_affinity); | ||
857 | cpumask_set_cpu(cpumask_first(cpu_online_mask), &new_affinity); | ||
858 | } | ||
859 | do_set_affinity = 1; | ||
860 | } else { | ||
861 | do_set_affinity = 0; | ||
862 | } | ||
863 | raw_spin_unlock_irqrestore(&desc->lock, flags); | ||
821 | 864 | ||
822 | #if 0 | 865 | if (do_set_affinity) |
823 | for (irq = OCTEON_IRQ_MBOX0; irq <= OCTEON_IRQ_MBOX1; irq++) | 866 | irq_set_affinity(irq, &new_affinity); |
824 | octeon_irq_mailbox_mask(irq); | ||
825 | #endif | ||
826 | for (irq = OCTEON_IRQ_UART0; irq <= OCTEON_IRQ_BOOTDMA; irq++) { | ||
827 | if (is_irq_enabled_on_cpu(irq, smp_processor_id())) { | ||
828 | /* ciu irq migrates to next cpu */ | ||
829 | octeon_irq_chip_ciu0.disable(irq); | ||
830 | octeon_irq_ciu0_set_affinity(irq, &cpu_online_map); | ||
831 | } | ||
832 | } | ||
833 | 867 | ||
834 | for (irq = OCTEON_IRQ_UART2; irq <= OCTEON_IRQ_RESERVED135; irq++) { | 868 | break; |
835 | if (is_irq_enabled_on_cpu(irq, smp_processor_id())) { | ||
836 | /* ciu irq migrates to next cpu */ | ||
837 | octeon_irq_chip_ciu1.disable(irq); | ||
838 | octeon_irq_ciu1_set_affinity(irq, &cpu_online_map); | ||
839 | } | 869 | } |
840 | } | 870 | } |
841 | } | 871 | } |