summaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorKanoj Sarcar <kanoj@engr.sgi.com>2000-04-17 13:09:10 +0000
committerKanoj Sarcar <kanoj@engr.sgi.com>2000-04-17 13:09:10 +0000
commit716ec6321bcc060b053d8c27325ba84377259d9f (patch)
treeb5f3e7d24920815881e33e99b51f5d60d5089e5a /arch
parent89d9bdb7a9e158b8d6b5d0f2e89bee6e92be382b (diff)
More intercpu interrupt work: we now have a low level inter cpu intr
handler.
Diffstat (limited to 'arch')
-rw-r--r--arch/mips64/sgi-ip27/ip27-init.c4
-rw-r--r--arch/mips64/sgi-ip27/ip27-irq.c64
2 files changed, 42 insertions, 26 deletions
diff --git a/arch/mips64/sgi-ip27/ip27-init.c b/arch/mips64/sgi-ip27/ip27-init.c
index 3a5fbd0f0..d08bbc9fe 100644
--- a/arch/mips64/sgi-ip27/ip27-init.c
+++ b/arch/mips64/sgi-ip27/ip27-init.c
@@ -323,7 +323,8 @@ void per_cpu_init(void)
set_cp0_status(ST0_IM, 0);
per_hub_init(cnode);
cpu_time_init();
- install_cpuintr(cpu);
+ if (smp_processor_id()) /* master can't do this early, no kmalloc */
+ install_cpuintr(cpu);
#if 0
install_tlbintr(cpu);
#endif
@@ -395,6 +396,7 @@ void allowboot(void)
sn_mp_setup();
/* Master has already done per_cpu_init() */
+ install_cpuintr(getcpuid());
#if 0
bte_lateinit();
ecc_init();
diff --git a/arch/mips64/sgi-ip27/ip27-irq.c b/arch/mips64/sgi-ip27/ip27-irq.c
index 630f79b88..d58e0c6c9 100644
--- a/arch/mips64/sgi-ip27/ip27-irq.c
+++ b/arch/mips64/sgi-ip27/ip27-irq.c
@@ -56,6 +56,8 @@ irq_cpustat_t irq_stat [NR_CPUS];
extern asmlinkage void ip27_irq(void);
int (*irq_cannonicalize)(int irq);
+int intr_connect_level(cpuid_t cpu, int bit);
+int intr_disconnect_level(cpuid_t cpu, int bit);
unsigned int local_bh_count[NR_CPUS];
unsigned int local_irq_count[NR_CPUS];
@@ -63,8 +65,7 @@ unsigned long spurious_count = 0;
/*
* we need to map irq's up to at least bit 7 of the INT_MASK0_A register
- * since bits 0-6 are pre-allocated for other purposes. 7,8,9 are taken
- * for intercpu and msc intrs.
+ * since bits 0-6 are pre-allocated for other purposes.
*/
#define IRQ_TO_SWLEVEL(i) i + 7
#define SWLEVEL_TO_IRQ(s) s - 7
@@ -187,7 +188,6 @@ void ip27_do_irq(struct pt_regs *regs)
static unsigned int bridge_startup(unsigned int irq)
{
bridge_t *bridge = (bridge_t *) 0x9200000008000000;
- bridgereg_t br;
int pin, swlevel;
/* FIIIIIXME ... Temporary kludge. This knows how interrupts are
@@ -198,24 +198,18 @@ static unsigned int bridge_startup(unsigned int irq)
case IOC3_ETH_INT: pin = 2; break;
case SCSI1_INT: pin = 1; break;
case SCSI0_INT: pin = 0; break;
- default: panic("bridge_startup: whoops?");
+ case SWLEVEL_TO_IRQ(CPU_ACTION_A):
+ case SWLEVEL_TO_IRQ(CPU_ACTION_B):
+ return;
+ default: panic("bridge_startup: whoops? %d\n", irq);
}
/*
* "map" irq to a swlevel greater than 6 since the first 6 bits
* of INT_PEND0 are taken
*/
-#if 0
- /* Get this to work */
- intr_connect_level(smp_processor_id(), swlevel);
-#else
swlevel = IRQ_TO_SWLEVEL(irq);
- br = LOCAL_HUB_L(PI_INT_MASK0_A);
- LOCAL_HUB_S(PI_INT_MASK0_A, br | (1 << swlevel));
- LOCAL_HUB_L(PI_INT_MASK0_A); /* Flush */
- cpu_data[smp_processor_id()].p_intmasks.intpend0_masks[0] |=
- (1 << swlevel);
-#endif
+ intr_connect_level(smp_processor_id(), swlevel);
bridge->b_int_addr[pin].addr = 0x20000 | swlevel;
bridge->b_int_enable |= (1 << pin);
@@ -254,7 +248,6 @@ static unsigned int bridge_startup(unsigned int irq)
static unsigned int bridge_shutdown(unsigned int irq)
{
bridge_t *bridge = (bridge_t *) 0x9200000008000000;
- bridgereg_t br;
int pin, swlevel;
/* FIIIIIXME ... Temporary kludge. This knows how interrupts are
@@ -272,17 +265,8 @@ static unsigned int bridge_shutdown(unsigned int irq)
* map irq to a swlevel greater than 6 since the first 6 bits
* of INT_PEND0 are taken
*/
-#if 0
- /* Get this to work */
- intr_disconnect_level(smp_processor_id(), swlevel);
-#else
swlevel = IRQ_TO_SWLEVEL(irq);
- br = LOCAL_HUB_L(PI_INT_MASK0_A);
- LOCAL_HUB_S(PI_INT_MASK0_A, br & ~(1 << swlevel));
- LOCAL_HUB_L(PI_INT_MASK0_A); /* Flush */
- cpu_data[smp_processor_id()].p_intmasks.intpend0_masks[0] &=
- ~(1 << swlevel);
-#endif
+ intr_disconnect_level(smp_processor_id(), swlevel);
bridge->b_int_enable &= ~(1 << pin);
bridge->b_widget.w_tflush; /* Flush */
@@ -671,11 +655,41 @@ int intr_connect_level(cpuid_t cpu, int bit)
return(0);
}
+int intr_disconnect_level(cpuid_t cpu, int bit)
+{
+ int ip;
+ int slice = cputoslice(cpu);
+ volatile hubreg_t *mask_reg;
+ hubreg_t *intpend_masks;
+ nasid_t nasid = COMPACT_TO_NASID_NODEID(cputocnode(cpu));
+
+ (void)intr_get_ptrs(cpu, bit, &bit, &intpend_masks, &ip);
+ intpend_masks[0] &= ~(1ULL << (u64)bit);
+ if (ip == 0) {
+ mask_reg = REMOTE_HUB_ADDR(nasid, PI_INT_MASK0_A +
+ PI_INT_MASK_OFFSET * slice);
+ } else {
+ mask_reg = REMOTE_HUB_ADDR(nasid, PI_INT_MASK1_A +
+ PI_INT_MASK_OFFSET * slice);
+ }
+ HUB_S(mask_reg, intpend_masks[0]);
+ return(0);
+}
+
+
+void handle_cpuintr(int irq, void *dev_id, struct pt_regs *regs)
+{
+ printk("HANDLE_CPUINTR: cpu%d irq%d\n", smp_processor_id(), irq);
+}
+
void install_cpuintr(cpuid_t cpu)
{
int intr_bit = CPU_ACTION_A + cputoslice(cpu);
intr_connect_level(cpu, intr_bit);
+ if (request_irq(SWLEVEL_TO_IRQ(intr_bit), handle_cpuintr, 0,
+ "intercpu", 0))
+ panic("intercpu intr unconnectible\n");
}
void install_tlbintr(cpuid_t cpu)