patch-2.4.1 linux/arch/ppc/kernel/prom.c

Next file: linux/arch/ppc/kernel/setup.c
Previous file: linux/arch/ppc/kernel/process.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.4.0/linux/arch/ppc/kernel/prom.c linux/arch/ppc/kernel/prom.c
@@ -28,10 +28,11 @@
 #include <asm/smp.h>
 #include <asm/bootx.h>
 #include <asm/system.h>
-#include <asm/gemini.h>
 #include <asm/mmu.h>
 #include <asm/pgtable.h>
 #include <asm/bitops.h>
+/* for openpic_to_irq */
+#include "open_pic.h"
 
 #ifdef CONFIG_FB
 #include <asm/linux_logo.h>
@@ -95,26 +96,28 @@
 #define FB_MAX	8
 #endif
 char *prom_display_paths[FB_MAX] __initdata = { 0, };
-unsigned int prom_num_displays = 0;
-char *of_stdout_device = 0;
-
-prom_entry prom = 0;
-ihandle prom_chosen = 0, prom_stdout = 0, prom_disp_node = 0;
+unsigned int prom_num_displays __initdata = 0;
+char *of_stdout_device __initdata = 0;
+ihandle prom_disp_node __initdata = 0;
+
+prom_entry prom __initdata = 0;
+ihandle prom_chosen __initdata = 0;
+ihandle prom_stdout __initdata = 0;
 
 extern char *klimit;
-char *bootpath = 0;
-char *bootdevice = 0;
+char *bootpath;
+char *bootdevice;
 
-unsigned int rtas_data = 0;   /* physical pointer */
-unsigned int rtas_entry = 0;  /* physical pointer */
-unsigned int rtas_size = 0;
-unsigned int old_rtas = 0;
+unsigned int rtas_data;   /* physical pointer */
+unsigned int rtas_entry;  /* physical pointer */
+unsigned int rtas_size;
+unsigned int old_rtas;
 
 /* Set for a newworld machine */
-int use_of_interrupt_tree = 0;
-int pmac_newworld = 0;
+int use_of_interrupt_tree;
+int pmac_newworld;
 
-static struct device_node *allnodes = 0;
+static struct device_node *allnodes;
 
 #ifdef CONFIG_BOOTX_TEXT
 
@@ -134,13 +137,12 @@
 static void draw_byte_16(unsigned char *bits, unsigned long *base, int rb);
 static void draw_byte_8(unsigned char *bits, unsigned long *base, int rb);
 
-/* We want those in data, not BSS */
-static long				g_loc_X = 0;
-static long				g_loc_Y = 0;
-static long				g_max_loc_X = 0;
-static long				g_max_loc_Y = 0;
+static int g_loc_X;
+static int g_loc_Y;
+static int g_max_loc_X;
+static int g_max_loc_Y;
 
-unsigned long disp_BAT[2] = {0, 0};
+unsigned long disp_BAT[2] __initdata = {0, 0};
 
 #define cmapsz	(16*256)
 
@@ -173,10 +175,10 @@
 void phys_call_rtas(int, int, int, ...);
 
 extern char cmd_line[512];	/* XXX */
-boot_infos_t *boot_infos = 0;	/* init it so it's in data segment not bss */
+boot_infos_t *boot_infos;
 #ifdef CONFIG_BOOTX_TEXT
-boot_infos_t *disp_bi = 0;
-boot_infos_t fake_bi = {0,};
+boot_infos_t *disp_bi;
+boot_infos_t fake_bi;
 #endif
 unsigned long dev_tree_size;
 
@@ -195,10 +197,6 @@
  * OF calls should be done within prom_init(), and prom_init()
  * and all routines called within it must be careful to relocate
  * references as necessary.
- *
- * Note that the bss is cleared *after* prom_init runs, so we have
- * to make sure that any static or extern variables it accesses
- * are put in the data segment.
  */
 #define PTRRELOC(x)	((typeof(x))((unsigned long)(x) + offset))
 #define PTRUNRELOC(x)	((typeof(x))((unsigned long)(x) - offset))
@@ -618,6 +616,11 @@
 	char *p, *d;
 	int prom_version = 0;
  	unsigned long phys;
+	extern char __bss_start, _end;
+
+	/* First zero the BSS -- use memset, some arches don't have
+	 * caches on yet */
+	memset_io(PTRRELOC(&__bss_start),0 , &_end - &__bss_start);
 
  	/* Default */
  	phys = offset + KERNELBASE;
@@ -948,34 +951,6 @@
 		if ((int) call_prom(RELOC("package-to-path"), 3, 1,
 				    node, path, 255) < 0)
 			continue;
-		prom_print(RELOC("opening display "));
-		prom_print(path);
-		ih = call_prom(RELOC("open"), 1, 1, path);
-		if (ih == 0 || ih == (ihandle) -1) {
-			prom_print(RELOC("... failed\n"));
-			continue;
-		}
-		prom_print(RELOC("... ok\n"));
-
-		if (RELOC(prom_disp_node) == 0)
-			RELOC(prom_disp_node) = node;
-			
-		/* Setup a useable color table when the appropriate
-		 * method is available. Should update this to set-colors */
-		for (i = 0; i < 32; i++)
-			if (prom_set_color(ih, i, RELOC(default_colors)[i*3],
-					   RELOC(default_colors)[i*3+1],
-					   RELOC(default_colors)[i*3+2]) != 0)
-				break;
-
-#ifdef CONFIG_FB
-		for (i = 0; i < LINUX_LOGO_COLORS; i++)
-			if (prom_set_color(ih, i + 32,
-					   RELOC(linux_logo_red)[i],
-					   RELOC(linux_logo_green)[i],
-					   RELOC(linux_logo_blue)[i]) != 0)
-				break;
-#endif /* CONFIG_FB */
 
 		/*
 		 * If this display is the device that OF is using for stdout,
@@ -990,9 +965,44 @@
 					= RELOC(prom_display_paths[i-1]);
 		}
 		RELOC(prom_display_paths[i]) = PTRUNRELOC(path);
+		if (i == 0)
+			RELOC(prom_disp_node) = node;
 		if (RELOC(prom_num_displays) >= FB_MAX)
 			break;
 	}
+
+	/*
+	 * Open the first display and set its colormap.
+	 */
+	if (RELOC(prom_num_displays) > 0) {
+		path = PTRRELOC(RELOC(prom_display_paths[0]));
+		prom_print(RELOC("opening display "));
+		prom_print(path);
+		ih = call_prom(RELOC("open"), 1, 1, path);
+		if (ih == 0 || ih == (ihandle) -1) {
+			prom_print(RELOC("... failed\n"));
+		} else {
+			prom_print(RELOC("... ok\n"));
+
+			/* Setup a useable color table when the appropriate
+			 * method is available. Should update this to set-colors */
+			for (i = 0; i < 32; i++)
+				if (prom_set_color(ih, i, RELOC(default_colors)[i*3],
+						   RELOC(default_colors)[i*3+1],
+						   RELOC(default_colors)[i*3+2]) != 0)
+					break;
+
+#ifdef CONFIG_FB
+			for (i = 0; i < LINUX_LOGO_COLORS; i++)
+				if (prom_set_color(ih, i + 32,
+						   RELOC(linux_logo_red)[i],
+						   RELOC(linux_logo_green)[i],
+						   RELOC(linux_logo_blue)[i]) != 0)
+					break;
+#endif /* CONFIG_FB */
+		}
+	}
+
 	return ALIGN(mem);
 }
 
@@ -1277,7 +1287,7 @@
 	if (!strcmp(np->name, "display"))
 		np->name = get_property(np, "compatible", 0);
 
-	if (!strcmp(np->name, "device-tree"))
+	if (np->parent == NULL)
 		ifunc = interpret_root_props;
 	else if (np->type == 0)
 		ifunc = NULL;
@@ -1370,7 +1380,7 @@
 		    np->intrs[i].line = *interrupts++;
 		    if (cvt_irq)
 			np->intrs[i].line = openpic_to_irq(np->intrs[i].line);
-		    np->intrs[i].sense = 0;
+		    np->intrs[i].sense = 1;
 		    if (isize > 1)
 		        np->intrs[i].sense = *interrupts++;
 		    for (j=2; j<isize; j++)
@@ -1540,7 +1550,7 @@
 		for (i = 0; (ml -= cell_size) >= 0; ++i) {
 			if (imp->addr.a_hi == devfn) {
 				np->intrs[np->n_intrs].line = imp->intr;
-				np->intrs[np->n_intrs].sense = 0; /* FIXME */
+				np->intrs[np->n_intrs].sense = 1; /* FIXME */
 				++np->n_intrs;
 			}
 			imp = (struct pci_intr_map *)(((unsigned int)imp)
@@ -1561,7 +1571,7 @@
 		mem_start += np->n_intrs * sizeof(struct interrupt_info);
 		for (i = 0; i < np->n_intrs; ++i) {
 			np->intrs[i].line = *ip++;
-			np->intrs[i].sense = 0;
+			np->intrs[i].sense = 1;
 		}
 	}
 
@@ -1614,7 +1624,7 @@
 		mem_start += np->n_intrs * sizeof(struct interrupt_info);
 		for (i = 0; i < np->n_intrs; ++i) {
 			np->intrs[i].line = *ip++;
-			np->intrs[i].sense = 0;
+			np->intrs[i].sense = 1;
 		}
 	}
 
@@ -1675,7 +1685,7 @@
 				if (keylargo)
 					np->intrs[i].sense = *ip++;
 				else
-					np->intrs[i].sense = 0;
+					np->intrs[i].sense = 1;
 			}
 		} else {
 			/* CHRP machines */
@@ -1771,7 +1781,7 @@
 		mem_start += np->n_intrs * sizeof(struct interrupt_info);
 		for (i = 0; i < np->n_intrs; ++i) {
 			np->intrs[i].line = *ip++;
-			np->intrs[i].sense = 0;
+			np->intrs[i].sense = 1;
 		}
 	}
 
@@ -1779,6 +1789,30 @@
 }
 
 /*
+ * Work out the sense (active-low level / active-high edge)
+ * of each interrupt from the device tree.
+ */
+void __init
+prom_get_irq_senses(unsigned char *senses, int off, int max)
+{
+	struct device_node *np;
+	int i, j;
+
+	/* default to level-triggered */
+	memset(senses, 1, max - off);
+	if (!use_of_interrupt_tree)
+		return;
+
+	for (np = allnodes; np != 0; np = np->allnext) {
+		for (j = 0; j < np->n_intrs; j++) {
+			i = np->intrs[j].line;
+			if (i >= off && i < max)
+				senses[i-off] = np->intrs[j].sense;
+		}
+	}
+}
+
+/*
  * Construct and return a list of the device_nodes with a given name.
  */
 __openfirmware
@@ -1818,39 +1852,6 @@
 	return head;
 }
 
-/* Finds a device node given its PCI bus number, device number
- * and function number
- */
-__openfirmware
-struct device_node *
-find_pci_device_OFnode(unsigned char bus, unsigned char dev_fn)
-{
-	struct device_node* np;
-	unsigned int *reg;
-	int l;
-	
-	for (np = allnodes; np != 0; np = np->allnext) {
-		int in_macio = 0;
-		struct device_node* parent = np->parent;
-		while(parent) {
-			char *pname = (char *)get_property(parent, "name", &l);
-			if (pname && strcmp(pname, "mac-io") == 0) {
-				in_macio = 1;
-				break;
-			}
-			parent = parent->parent;
-		}
-		if (in_macio)
-			continue;
-		reg = (unsigned int *) get_property(np, "reg", &l);
-		if (reg == 0 || l < sizeof(struct reg_property))
-			continue;
-		if (((reg[0] >> 8) & 0xff) == dev_fn && ((reg[0] >> 16) & 0xff) == bus)
-			break;
-	}
-	return np;
-}
-
 /*
  * Returns all nodes linked together
  */
@@ -1981,6 +1982,21 @@
 			return pp->value;
 		}
 	return 0;
+}
+
+/*
+ * Add a property to a node
+ */
+__openfirmware
+void
+prom_add_property(struct device_node* np, struct property* prop)
+{
+	struct property **next = &np->properties;
+
+	prop->next = NULL;	
+	while (*next)
+		next = &(*next)->next;
+	*next = prop;
 }
 
 #if 0

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)