LKML Archive on lore.kernel.org
help / color / mirror / Atom feed
* alpha 2.4.11-pre3: fix pc164 srm interrupts
@ 2001-10-05  1:25 Richard Henderson
  0 siblings, 0 replies; only message in thread
From: Richard Henderson @ 2001-10-05  1:25 UTC (permalink / raw)
  To: torvalds, alan; +Cc: linux-kernel

>From Jay Estabrook:

(1) The PC164 broken interupt mask hack was only applied to the MILO
    interrupt handler, and not the SRM interrupt handler.

(2) SRM sometimes mis-identifies a PC164 as an EB164, which results
    in our interrupt fixes not being installed.  Fix this by noticing
    that an EB164 is never an EV56.


r~



diff -rup 2.4.10-dist/arch/alpha/kernel/setup.c 2.4.10/arch/alpha/kernel/setup.c
--- 2.4.10-dist/arch/alpha/kernel/setup.c	Sun Aug 12 10:38:47 2001
+++ 2.4.10/arch/alpha/kernel/setup.c	Thu Oct  4 16:05:16 2001
@@ -85,7 +93,7 @@ unsigned char aux_device_present = 0xaa;
 
 static struct alpha_machine_vector *get_sysvec(long, long, long);
 static struct alpha_machine_vector *get_sysvec_byname(const char *);
-static void get_sysnames(long, long, char **, char **);
+static void get_sysnames(long, long, long, char **, char **);
 
 static char command_line[COMMAND_LINE_SIZE];
 char saved_command_line[COMMAND_LINE_SIZE];
@@ -537,14 +545,14 @@ setup_arch(char **cmdline_p)
 	/*
 	 * Indentify and reconfigure for the current system.
 	 */
+	cpu = (struct percpu_struct*)((char*)hwrpb + hwrpb->processor_offset);
+
 	get_sysnames(hwrpb->sys_type, hwrpb->sys_variation,
-		     &type_name, &var_name);
+		     cpu->type, &type_name, &var_name);
 	if (*var_name == '0')
 		var_name = "";
 
 	if (!vec) {
-		cpu = (struct percpu_struct*)
-			((char*)hwrpb + hwrpb->processor_offset);
 		vec = get_sysvec(hwrpb->sys_type, hwrpb->sys_variation,
 				 cpu->type);
 	}
@@ -801,6 +809,8 @@ get_sysvec(long type, long variation, lo
 		/* Member ID is a bit-field. */
 		long member = (variation >> 10) & 0x3f;
 
+		cpu &= 0xffffffff; /* make it usable */
+
 		switch (type) {
 		case ST_DEC_ALCOR:
 			if (member < N(alcor_indices))
@@ -809,6 +819,10 @@ get_sysvec(long type, long variation, lo
 		case ST_DEC_EB164:
 			if (member < N(eb164_indices))
 				vec = eb164_vecs[eb164_indices[member]];
+			/* PC164 may show as EB164 variation with EV56 CPU,
+			   but, since no true EB164 had anything but EV5... */
+			if (vec == &eb164_mv && cpu == EV56_CPU)
+				vec = &pc164_mv;
 			break;
 		case ST_DEC_EB64P:
 			if (member < N(eb64p_indices))
@@ -827,21 +841,18 @@ get_sysvec(long type, long variation, lo
 				vec = tsunami_vecs[tsunami_indices[member]];
 			break;
 		case ST_DEC_1000:
-			cpu &= 0xffffffff;
 			if (cpu == EV5_CPU || cpu == EV56_CPU)
 				vec = &mikasa_primo_mv;
 			else
 				vec = &mikasa_mv;
 			break;
 		case ST_DEC_NORITAKE:
-			cpu &= 0xffffffff;
 			if (cpu == EV5_CPU || cpu == EV56_CPU)
 				vec = &noritake_primo_mv;
 			else
 				vec = &noritake_mv;
 			break;
 		case ST_DEC_2100_A500:
-			cpu &= 0xffffffff;
 			if (cpu == EV5_CPU || cpu == EV56_CPU)
 				vec = &sable_gamma_mv;
 			else
@@ -905,7 +916,7 @@ get_sysvec_byname(const char *name)
 }
 
 static void
-get_sysnames(long type, long variation,
+get_sysnames(long type, long variation, long cpu,
 	     char **type_name, char **variation_name)
 {
 	long member;
@@ -938,12 +949,18 @@ get_sysnames(long type, long variation,
 
 	member = (variation >> 10) & 0x3f; /* member ID is a bit-field */
 
+	cpu &= 0xffffffff; /* make it usable */
+
 	switch (type) { /* select by family */
 	default: /* default to variation "0" for now */
 		break;
 	case ST_DEC_EB164:
 		if (member < N(eb164_indices))
 			*variation_name = eb164_names[eb164_indices[member]];
+		/* PC164 may show as EB164 variation, but with EV56 CPU,
+		   so, since no true EB164 had anything but EV5... */
+		if (eb164_indices[member] == 0 && cpu == EV56_CPU)
+			*variation_name = eb164_names[1]; /* make it PC164 */
 		break;
 	case ST_DEC_ALCOR:
 		if (member < N(alcor_indices))
@@ -1054,7 +1071,7 @@ int get_cpuinfo(char *buffer)
 		cpu_name = cpu_names[cpu_index];
 
 	get_sysnames(hwrpb->sys_type, hwrpb->sys_variation,
-		     &systype_name, &sysvariation_name);
+		     cpu->type, &systype_name, &sysvariation_name);
 
 	nr_processors = get_nr_processors(cpu, hwrpb->nr_processors);
 
diff -rup 2.4.10-dist/arch/alpha/kernel/sys_cabriolet.c 2.4.10/arch/alpha/kernel/sys_cabriolet.c
--- 2.4.10-dist/arch/alpha/kernel/sys_cabriolet.c	Wed Jan 24 15:16:23 2001
+++ 2.4.10/arch/alpha/kernel/sys_cabriolet.c	Thu Oct  4 16:09:03 2001
@@ -106,12 +106,12 @@ cabriolet_device_interrupt(unsigned long
 }
 
 static void __init
-cabriolet_init_irq(void)
+common_init_irq(void (*srm_dev_int)(unsigned long v, struct pt_regs *r))
 {
 	init_i8259a_irqs();
 
 	if (alpha_using_srm) {
-		alpha_mv.device_interrupt = srm_device_interrupt;
+		alpha_mv.device_interrupt = srm_dev_int;
 		init_srm_irqs(35, 0);
 	}
 	else {
@@ -131,29 +131,47 @@ cabriolet_init_irq(void)
 	setup_irq(16+4, &isa_cascade_irqaction);
 }
 
+static void __init
+cabriolet_init_irq(void)
+{
+	common_init_irq(srm_device_interrupt);
+}
+
 #if defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_PC164)
+/* In theory, the PC164 has the same interrupt hardware as the other
+   Cabriolet based systems.  However, something got screwed up late
+   in the development cycle which broke the interrupt masking hardware.
+   Repeat, it is not possible to mask and ack interrupts.  At all.
+
+   In an attempt to work around this, while processing interrupts,
+   we do not allow the IPL to drop below what it is currently.  This
+   prevents the possibility of recursion.  
+
+   ??? Another option might be to force all PCI devices to use edge
+   triggered rather than level triggered interrupts.  That might be
+   too invasive though.  */
+
 static void
-pc164_device_interrupt(unsigned long v, struct pt_regs *r)
+pc164_srm_device_interrupt(unsigned long v, struct pt_regs *r)
 {
-	/* In theory, the PC164 has the same interrupt hardware as
-	   the other Cabriolet based systems.  However, something 
-	   got screwed up late in the development cycle which broke
-	   the interrupt masking hardware.  Repeat, it is not 
-	   possible to mask and ack interrupts.  At all.
-
-	   In an attempt to work around this, while processing 
-	   interrupts, we do not allow the IPL to drop below what
-	   it is currently.  This prevents the possibility of
-	   recursion.  
-
-	   ??? Another option might be to force all PCI devices
-	   to use edge triggered rather than level triggered
-	   interrupts.  That might be too invasive though.  */
+	__min_ipl = getipl();
+	srm_device_interrupt(v, r);
+	__min_ipl = 0;
+}
 
+static void
+pc164_device_interrupt(unsigned long v, struct pt_regs *r)
+{
 	__min_ipl = getipl();
 	cabriolet_device_interrupt(v, r);
 	__min_ipl = 0;
 }
+
+static void __init
+pc164_init_irq(void)
+{
+	common_init_irq(pc164_srm_device_interrupt);
+}
 #endif
 
 /*
@@ -419,7 +437,7 @@ struct alpha_machine_vector pc164_mv __i
 	device_interrupt:	pc164_device_interrupt,
 
 	init_arch:		cia_init_arch,
-	init_irq:		cabriolet_init_irq,
+	init_irq:		pc164_init_irq,
 	init_rtc:		common_init_rtc,
 	init_pci:		alphapc164_init_pci,
 	pci_map_irq:		alphapc164_map_irq,

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2001-10-05  1:26 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2001-10-05  1:25 alpha 2.4.11-pre3: fix pc164 srm interrupts Richard Henderson

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).