aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/cavium-octeon/octeon-irq.c
diff options
context:
space:
mode:
authorDavid Daney <ddaney@caviumnetworks.com>2010-07-23 13:43:47 -0400
committerRalf Baechle <ralf@linux-mips.org>2010-08-05 08:26:10 -0400
commit3508920f5811fcb8bdbf02943eb5ed531834bbc4 (patch)
tree20e03cb5fb1d982990760bccdbccde4736e14d85 /arch/mips/cavium-octeon/octeon-irq.c
parent5aae1fd4d41ea69da845e11d4766ab61666494ed (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.c108
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
791static 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
807void fixup_irqs(void) 792void 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}