patch-2.1.97 linux/arch/sparc64/kernel/ebus.c

Next file: linux/arch/sparc64/kernel/head.S
Previous file: linux/arch/sparc64/kernel/dtlb_prot.S
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.1.96/linux/arch/sparc64/kernel/ebus.c linux/arch/sparc64/kernel/ebus.c
@@ -1,4 +1,4 @@
-/* $Id: ebus.c,v 1.17 1998/01/10 18:26:13 ecd Exp $
+/* $Id: ebus.c,v 1.23 1998/03/29 16:27:24 ecd Exp $
  * ebus.c: PCI to EBus bridge device.
  *
  * Copyright (C) 1997  Eddie C. Dost  (ecd@skynet.be)
@@ -29,14 +29,12 @@
 struct linux_ebus *ebus_chain = 0;
 
 extern void prom_ebus_ranges_init(struct linux_ebus *);
+extern void prom_ebus_intmap_init(struct linux_ebus *);
 extern unsigned long pci_console_init(unsigned long memory_start);
 
 #ifdef CONFIG_SUN_OPENPROMIO
 extern int openprom_init(void);
 #endif
-#ifdef CONFIG_SUN_MOSTEK_RTC
-extern int rtc_init(void);
-#endif
 #ifdef CONFIG_SPARCAUDIO
 extern int sparcaudio_init(void);
 #endif
@@ -46,6 +44,9 @@
 #ifdef CONFIG_OBP_FLASH
 extern int flash_init(void);
 #endif
+#ifdef CONFIG_ENVCTRL
+extern int envctrl_init(void);
+#endif
 
 extern unsigned int psycho_irq_build(struct linux_pbm_info *pbm,
 				     unsigned int full_ino);
@@ -62,7 +63,35 @@
 	return mem;
 }
 
-__initfunc(void fill_ebus_child(int node, struct linux_ebus_child *dev))
+__initfunc(void ebus_intmap_match(struct linux_ebus *ebus,
+				  struct linux_prom_registers *reg,
+				  int *interrupt))
+{
+	unsigned int hi, lo, irq;
+	int i;
+
+	if (!ebus->num_ebus_intmap)
+		return;
+
+	hi = reg->which_io & ebus->ebus_intmask.phys_hi;
+	lo = reg->phys_addr & ebus->ebus_intmask.phys_lo;
+	irq = *interrupt & ebus->ebus_intmask.interrupt;
+	for (i = 0; i < ebus->num_ebus_intmap; i++) {
+		if ((ebus->ebus_intmap[i].phys_hi == hi) &&
+		    (ebus->ebus_intmap[i].phys_lo == lo) &&
+		    (ebus->ebus_intmap[i].interrupt == irq)) {
+			*interrupt = ebus->ebus_intmap[i].cinterrupt;
+			return;
+		}
+	}
+
+	prom_printf("ebus: IRQ [%08x.%08x.%08x] not found in interrupt-map\n",
+		    reg->which_io, reg->phys_addr, *interrupt);
+	prom_halt();
+}
+
+__initfunc(void fill_ebus_child(int node, struct linux_prom_registers *preg,
+				struct linux_ebus_child *dev))
 {
 	int regs[PROMREG_MAX];
 	int irqs[PROMREG_MAX];
@@ -90,8 +119,10 @@
 		dev->num_irqs = 0;
 	} else {
 		dev->num_irqs = len / sizeof(irqs[0]);
-		for (i = 0; i < dev->num_irqs; i++)
+		for (i = 0; i < dev->num_irqs; i++) {
+			ebus_intmap_match(dev->bus, preg, &irqs[i]);
 			dev->irqs[i] = psycho_irq_build(dev->bus->parent, irqs[i]);
+		}
 	}
 
 #ifdef DEBUG_FILL_EBUS_DEV
@@ -108,7 +139,8 @@
 #endif
 }
 
-__initfunc(unsigned long fill_ebus_device(int node, struct linux_ebus_device *dev,
+__initfunc(unsigned long fill_ebus_device(int node,
+					  struct linux_ebus_device *dev,
 					  unsigned long memory_start))
 {
 	struct linux_prom_registers regs[PROMREG_MAX];
@@ -142,8 +174,10 @@
 		dev->num_irqs = 0;
 	} else {
 		dev->num_irqs = len / sizeof(irqs[0]);
-		for (i = 0; i < dev->num_irqs; i++)
+		for (i = 0; i < dev->num_irqs; i++) {
+			ebus_intmap_match(dev->bus, &regs[0], &irqs[i]);
 			dev->irqs[i] = psycho_irq_build(dev->bus->parent, irqs[i]);
+		}
 	}
 
 #ifdef DEBUG_FILL_EBUS_DEV
@@ -166,7 +200,7 @@
 		child->next = 0;
 		child->parent = dev;
 		child->bus = dev->bus;
-		fill_ebus_child(node, child);
+		fill_ebus_child(node, &regs[0], child);
 
 		while ((node = prom_getsibling(node))) {
 			child->next = (struct linux_ebus_child *)
@@ -176,13 +210,16 @@
 			child->next = 0;
 			child->parent = dev;
 			child->bus = dev->bus;
-			fill_ebus_child(node, child);
+			fill_ebus_child(node, &regs[0], child);
 		}
 	}
 
 	return memory_start;
 }
 
+extern void sun4u_start_timers(void);
+extern void clock_probe(void);
+
 __initfunc(unsigned long ebus_init(unsigned long memory_start,
 				   unsigned long memory_end))
 {
@@ -199,14 +236,10 @@
 	int reg, rng, nreg;
 	int num_ebus = 0;
 
-	if (!pcibios_present())
+	if (!pci_present())
 		return memory_start;
 
-	for (pdev = pci_devices; pdev; pdev = pdev->next) {
-		if ((pdev->vendor == PCI_VENDOR_ID_SUN) &&
-		    (pdev->device == PCI_DEVICE_ID_SUN_EBUS))
-			break;
-	}
+	pdev = pci_find_device(PCI_VENDOR_ID_SUN, PCI_DEVICE_ID_SUN_EBUS, 0);
 	if (!pdev) {
 		printk("ebus: No EBus's found.\n");
 #ifdef PROM_DEBUG
@@ -236,11 +269,9 @@
 		ebus->parent = pbm = cookie->pbm;
 
 		/* Enable BUS Master. */
-		pcibios_read_config_word(pdev->bus->number, pdev->devfn,
-					 PCI_COMMAND, &pci_command);
+		pci_read_config_word(pdev, PCI_COMMAND, &pci_command);
 		pci_command |= PCI_COMMAND_MASTER;
-		pcibios_write_config_word(pdev->bus->number, pdev->devfn,
-					  PCI_COMMAND, pci_command);
+		pci_write_config_word(pdev, PCI_COMMAND, pci_command);
 
 		len = prom_getproperty(ebusnd, "reg", (void *)regs,
 				       sizeof(regs));
@@ -285,6 +316,7 @@
 #endif
 
 		prom_ebus_ranges_init(ebus);
+		prom_ebus_intmap_init(ebus);
 
 		nd = prom_getchild(ebusnd);
 		if (!nd)
@@ -312,11 +344,8 @@
 		}
 
 	next_ebus:
-		for (pdev = pdev->next; pdev; pdev = pdev->next) {
-			if ((pdev->vendor == PCI_VENDOR_ID_SUN) &&
-			    (pdev->device == PCI_DEVICE_ID_SUN_EBUS))
-				break;
-		}
+		pdev = pci_find_device(PCI_VENDOR_ID_SUN,
+				       PCI_DEVICE_ID_SUN_EBUS, pdev);
 		if (!pdev)
 			break;
 
@@ -335,9 +364,6 @@
 #ifdef CONFIG_SUN_OPENPROMIO
 	openprom_init();
 #endif
-#ifdef CONFIG_SUN_MOSTEK_RTC
-	rtc_init();
-#endif
 #ifdef CONFIG_SPARCAUDIO
 	sparcaudio_init();
 #endif
@@ -345,20 +371,15 @@
 	bpp_init();
 #endif
 #ifdef CONFIG_SUN_AUXIO
-	if (sparc_cpu_model == sun4u)
-		auxio_probe();
+	auxio_probe();
+#endif
+#ifdef CONFIG_ENVCTRL
+	envctrl_init();
 #endif
 #ifdef CONFIG_OBP_FLASH
 	flash_init();
 #endif
-#ifdef __sparc_v9__
-	if (sparc_cpu_model == sun4u) {
-		extern void sun4u_start_timers(void);
-		extern void clock_probe(void);
-
-		sun4u_start_timers();
-		clock_probe();
-	}
-#endif
+	sun4u_start_timers();
+	clock_probe();
 	return memory_start;
 }

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov