/* * Move the interrupt to the other TP, to balance load (if affinity permits) */ static void flip_tp(int irq) { #ifdef CONFIG_SMP int tp = smp_processor_id(); unsigned long local_lev1, remote_lev1; unsigned long mask = 1 << ((irq - 1) & 0x1f); if(tp == 0) { local_lev1 = TP0_BASE; remote_lev1 = TP1_BASE; } else { local_lev1 = TP1_BASE; remote_lev1 = TP0_BASE; } if(cpumask_test_cpu(tp ^ 1, irq_desc[irq].affinity)) { next_cpu[irq] = tp ^ 1; if(irq >= 1 && irq <= 32) { L1_WR_W0(local_lev1, MASK_SET, mask); L1_WR_W0(remote_lev1, MASK_CLEAR, mask); } if(irq >= 33 && irq <= 64) { L1_WR_W1(local_lev1, MASK_SET, mask); L1_WR_W1(remote_lev1, MASK_CLEAR, mask); } if(irq >= 65 && irq <= 96) { L1_WR_W2(local_lev1, MASK_SET, mask); L1_WR_W2(remote_lev1, MASK_CLEAR, mask); } } #endif /* CONFIG_SMP */ }
void brcm_irq_standby_exit(void) { /* restore the saved L1 state */ L1_WR_W0(TP0_BASE, MASK_SET, 0xffffffff); L1_WR_W0(TP0_BASE, MASK_CLEAR, ~brcm_irq_state[0]); L1_WR_W1(TP0_BASE, MASK_SET, 0xffffffff); L1_WR_W1(TP0_BASE, MASK_CLEAR, ~brcm_irq_state[1]); L1_WR_W2(TP0_BASE, MASK_SET, 0xffffffff); L1_WR_W2(TP0_BASE, MASK_CLEAR, ~brcm_irq_state[2]); }
static int brcm_intc_set_affinity(unsigned int irq, const struct cpumask *dest) { unsigned int shift; unsigned long flags; local_irq_save(flags); if (irq > 0 && irq <= 32) { shift = irq - 1; if(cpu_isset(0, *dest)) { L1_WR_W0(TP1_BASE, MASK_SET, (1UL << shift)); L1_WR_W0(TP0_BASE, MASK_CLEAR, (1UL << shift)); next_cpu[irq] = 0; } else { L1_WR_W0(TP0_BASE, MASK_SET, (1UL << shift)); L1_WR_W0(TP1_BASE, MASK_CLEAR, (1UL << shift)); next_cpu[irq] = 1; } } else if (irq > 32 && irq <= 64) { shift = irq - 32 - 1; next_cpu[irq] = 0; if(cpu_isset(0, *dest)) { L1_WR_W1(TP1_BASE, MASK_SET, (1UL << shift)); L1_WR_W1(TP0_BASE, MASK_CLEAR, (1UL << shift)); next_cpu[irq] = 0; } else { L1_WR_W1(TP0_BASE, MASK_SET, (1UL << shift)); L1_WR_W1(TP1_BASE, MASK_CLEAR, (1UL << shift)); next_cpu[irq] = 1; } } else if (irq > 64 && irq <= 96) { shift = irq - 64 - 1; next_cpu[irq] = 0; if(cpu_isset(0, *dest)) { L1_WR_W2(TP1_BASE, MASK_SET, (1UL << shift)); L1_WR_W2(TP0_BASE, MASK_CLEAR, (1UL << shift)); next_cpu[irq] = 0; } else { L1_WR_W2(TP0_BASE, MASK_SET, (1UL << shift)); L1_WR_W2(TP1_BASE, MASK_CLEAR, (1UL << shift)); next_cpu[irq] = 1; } } local_irq_restore(flags); return 0; }
void brcm_irq_standby_enter(int wake_irq) { /* save the current state, then mask everything */ brcm_irq_state[0] = L1_RD_W0(TP0_BASE, MASK_STATUS); L1_WR_W0(TP0_BASE, MASK_SET, 0xffffffff); brcm_irq_state[1] = L1_RD_W1(TP0_BASE, MASK_STATUS); L1_WR_W1(TP0_BASE, MASK_SET, 0xffffffff); brcm_irq_state[2] = L1_RD_W2(TP0_BASE, MASK_STATUS); L1_WR_W2(TP0_BASE, MASK_SET, 0xffffffff); /* unmask the wakeup IRQ */ if (wake_irq > 0 && wake_irq <= 32) L1_WR_W0(TP0_BASE, MASK_CLEAR, 1 << (wake_irq - 1)); else if (wake_irq > 32 && wake_irq <= 64) L1_WR_W1(TP0_BASE, MASK_CLEAR, 1 << (wake_irq - 33)); else if (wake_irq > 64 && wake_irq <= 96) L1_WR_W2(TP0_BASE, MASK_CLEAR, 1 << (wake_irq - 65)); }
static void brcm_intc_enable(unsigned int irq) { unsigned int shift; unsigned long base = NEXT_CPU(irq) ? TP1_BASE : TP0_BASE; if (irq > 0 && irq <= 32) { shift = irq - 1; L1_WR_W0(base, MASK_CLEAR, (1UL << shift)); } else if (irq > 32 && irq <= 32+32) { shift = irq - 32 - 1; L1_WR_W1(base, MASK_CLEAR, (1UL << shift)); } else if (irq > 64 && irq <= 32+32+32) { shift = irq - 64 - 1; L1_WR_W2(base, MASK_CLEAR, (1UL << shift)); } else BUG(); }