summaryrefslogtreecommitdiffstats
path: root/arch/sparc/kernel/irq.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/sparc/kernel/irq.c')
-rw-r--r--arch/sparc/kernel/irq.c153
1 files changed, 35 insertions, 118 deletions
diff --git a/arch/sparc/kernel/irq.c b/arch/sparc/kernel/irq.c
index b22f008a1..08c0be5c6 100644
--- a/arch/sparc/kernel/irq.c
+++ b/arch/sparc/kernel/irq.c
@@ -1,4 +1,4 @@
-/* $Id: irq.c,v 1.75 1997/05/08 20:57:37 davem Exp $
+/* $Id: irq.c,v 1.77 1997/11/19 15:33:05 jj Exp $
* arch/sparc/kernel/irq.c: Interrupt request handling routines. On the
* Sparc the IRQ's are basically 'cast in stone'
* and you are supposed to probe the prom's device
@@ -41,10 +41,6 @@
#include <asm/hardirq.h>
#include <asm/softirq.h>
-#ifdef __SMP_PROF__
-extern volatile unsigned long smp_local_timer_ticks[1+NR_CPUS];
-#endif
-
/*
* Dave Redman (djhr@tadpole.co.uk)
*
@@ -101,10 +97,10 @@ void (*set_irq_udt)(int);
*
*/
#define MAX_STATIC_ALLOC 4
-static struct irqaction static_irqaction[MAX_STATIC_ALLOC];
-static int static_irq_count = 0;
+struct irqaction static_irqaction[MAX_STATIC_ALLOC];
+int static_irq_count = 0;
-static struct irqaction *irq_action[NR_IRQS+1] = {
+struct irqaction *irq_action[NR_IRQS+1] = {
NULL, NULL, NULL, NULL, NULL, NULL , NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL , NULL, NULL
};
@@ -114,6 +110,11 @@ int get_irq_list(char *buf)
int i, len = 0;
struct irqaction * action;
+ if (sparc_cpu_model == sun4d) {
+ extern int sun4d_get_irq_list(char *);
+
+ return sun4d_get_irq_list(buf);
+ }
for (i = 0 ; i < (NR_IRQS+1) ; i++) {
action = *(i + irq_action);
if (!action)
@@ -132,109 +133,6 @@ int get_irq_list(char *buf)
return len;
}
-#ifdef __SMP_PROF__
-
-static unsigned int int_count[NR_CPUS][NR_IRQS] = {{0},};
-
-extern unsigned int prof_multiplier[NR_CPUS];
-extern unsigned int prof_counter[NR_CPUS];
-
-int get_smp_prof_list(char *buf) {
- int i,j, len = 0;
- struct irqaction * action;
- unsigned long sum_spins = 0;
- unsigned long sum_spins_syscall = 0;
- unsigned long sum_spins_sys_idle = 0;
- unsigned long sum_smp_idle_count = 0;
- unsigned long sum_local_timer_ticks = 0;
-
- for (i=0;i<smp_num_cpus;i++) {
- int cpunum = cpu_logical_map[i];
- sum_spins+=smp_spins[cpunum];
- sum_spins_syscall+=smp_spins_syscall[cpunum];
- sum_spins_sys_idle+=smp_spins_sys_idle[cpunum];
- sum_smp_idle_count+=smp_idle_count[cpunum];
- sum_local_timer_ticks+=smp_local_timer_ticks[cpunum];
- }
-
- len += sprintf(buf+len,"CPUS: %10i \n", smp_num_cpus);
- len += sprintf(buf+len," SUM ");
- for (i=0;i<smp_num_cpus;i++)
- len += sprintf(buf+len," P%1d ",cpu_logical_map[i]);
- len += sprintf(buf+len,"\n");
- for (i = 0 ; i < NR_IRQS ; i++) {
- action = *(i + irq_action);
- if (!action || !action->handler)
- continue;
- len += sprintf(buf+len, "%3d: %10d ",
- i, kstat.interrupts[i]);
- for (j=0;j<smp_num_cpus;j++)
- len+=sprintf(buf+len, "%10d ",
- int_count[cpu_logical_map[j]][i]);
- len += sprintf(buf+len, "%c %s",
- (action->flags & SA_INTERRUPT) ? '+' : ' ',
- action->name);
- for (action=action->next; action; action = action->next) {
- len += sprintf(buf+len, ",%s %s",
- (action->flags & SA_INTERRUPT) ? " +" : "",
- action->name);
- }
- len += sprintf(buf+len, "\n");
- }
- len+=sprintf(buf+len, "LCK: %10lu",
- sum_spins);
-
- for (i=0;i<smp_num_cpus;i++)
- len+=sprintf(buf+len," %10lu",smp_spins[cpu_logical_map[i]]);
-
- len +=sprintf(buf+len," spins from int\n");
-
- len+=sprintf(buf+len, "LCK: %10lu",
- sum_spins_syscall);
-
- for (i=0;i<smp_num_cpus;i++)
- len+=sprintf(buf+len," %10lu",smp_spins_syscall[cpu_logical_map[i]]);
-
- len +=sprintf(buf+len," spins from syscall\n");
-
- len+=sprintf(buf+len, "LCK: %10lu",
- sum_spins_sys_idle);
-
- for (i=0;i<smp_num_cpus;i++)
- len+=sprintf(buf+len," %10lu",smp_spins_sys_idle[cpu_logical_map[i]]);
-
- len +=sprintf(buf+len," spins from sysidle\n");
- len+=sprintf(buf+len,"IDLE %10lu",sum_smp_idle_count);
-
- for (i=0;i<smp_num_cpus;i++)
- len+=sprintf(buf+len," %10lu",smp_idle_count[cpu_logical_map[i]]);
-
- len +=sprintf(buf+len," idle ticks\n");
-
- len+=sprintf(buf+len,"TICK %10lu",sum_local_timer_ticks);
- for (i=0;i<smp_num_cpus;i++)
- len+=sprintf(buf+len," %10lu",smp_local_timer_ticks[cpu_logical_map[i]]);
-
- len +=sprintf(buf+len," local APIC timer ticks\n");
-
- len+=sprintf(buf+len,"MULT: ");
- for (i=0;i<smp_num_cpus;i++)
- len+=sprintf(buf+len," %10u",prof_multiplier[cpu_logical_map[i]]);
- len +=sprintf(buf+len," profiling multiplier\n");
-
- len+=sprintf(buf+len,"COUNT: ");
- for (i=0;i<smp_num_cpus;i++)
- len+=sprintf(buf+len," %10u",prof_counter[cpu_logical_map[i]]);
-
- len +=sprintf(buf+len," profiling counter\n");
-
- len+=sprintf(buf+len, "IPI: %10lu received\n",
- ipi_count);
-
- return len;
-}
-#endif
-
void free_irq(unsigned int irq, void *dev_id)
{
struct irqaction * action;
@@ -242,6 +140,11 @@ void free_irq(unsigned int irq, void *dev_id)
unsigned long flags;
unsigned int cpu_irq;
+ if (sparc_cpu_model == sun4d) {
+ extern void sun4d_free_irq(unsigned int, void *);
+
+ return sun4d_free_irq(irq, dev_id);
+ }
cpu_irq = irq & NR_IRQS;
action = *(cpu_irq + irq_action);
if (cpu_irq > 14) { /* 14 irq levels on the sparc */
@@ -531,29 +434,28 @@ void unexpected_irq(int irq, void *dev_id, struct pt_regs * regs)
void handler_irq(int irq, struct pt_regs * regs)
{
struct irqaction * action;
- unsigned int cpu_irq = irq & NR_IRQS;
int cpu = smp_processor_id();
#ifdef __SMP__
extern void smp_irq_rotate(int cpu);
#endif
- disable_pil_irq(cpu_irq);
+ disable_pil_irq(irq);
#ifdef __SMP__
/* Only rotate on lower priority IRQ's (scsi, ethernet, etc.). */
if(irq < 10)
smp_irq_rotate(cpu);
#endif
- irq_enter(cpu, cpu_irq, regs);
- action = *(cpu_irq + irq_action);
- kstat.interrupts[cpu_irq]++;
+ irq_enter(cpu, irq, regs);
+ action = *(irq + irq_action);
+ kstat.interrupts[irq]++;
do {
if (!action || !action->handler)
unexpected_irq(irq, 0, regs);
action->handler(irq, action->dev_id, regs);
action = action->next;
} while (action);
- irq_exit(cpu, cpu_irq);
- enable_pil_irq(cpu_irq);
+ irq_exit(cpu, irq);
+ enable_pil_irq(irq);
}
#ifdef CONFIG_BLK_DEV_FD
@@ -669,12 +571,22 @@ int request_irq(unsigned int irq,
unsigned long flags;
unsigned int cpu_irq;
+ if (sparc_cpu_model == sun4d) {
+ extern int sun4d_request_irq(unsigned int,
+ void (*)(int, void *, struct pt_regs *),
+ unsigned long, const char *, void *);
+ return sun4d_request_irq(irq, handler, irqflags, devname, dev_id);
+ }
cpu_irq = irq & NR_IRQS;
if(cpu_irq > 14)
return -EINVAL;
if (!handler)
return -EINVAL;
+
+ if (irqflags & SA_DCOOKIE)
+ dev_id = ((struct devid_cookie *)dev_id)->real_dev_id;
+
action = *(cpu_irq + irq_action);
if (action) {
if ((action->flags & SA_SHIRQ) && (irqflags & SA_SHIRQ)) {
@@ -751,6 +663,7 @@ __initfunc(void init_IRQ(void))
{
extern void sun4c_init_IRQ( void );
extern void sun4m_init_IRQ( void );
+ extern void sun4d_init_IRQ( void );
switch(sparc_cpu_model) {
case sun4c:
@@ -760,6 +673,10 @@ __initfunc(void init_IRQ(void))
case sun4m:
sun4m_init_IRQ();
break;
+
+ case sun4d:
+ sun4d_init_IRQ();
+ break;
case ap1000:
#if CONFIG_AP1000