[SPARC64]: Convert sun4v virtual-device layer to in-kernel PROM device tree.
David S. Miller [Thu, 22 Jun 2006 05:56:20 +0000 (22:56 -0700)]
Signed-off-by: David S. Miller <davem@davemloft.net>

arch/sparc64/kernel/devices.c
drivers/serial/sunhv.c
include/asm-sparc64/vdev.h

index 0dd95ae..136f872 100644 (file)
@@ -33,7 +33,7 @@ extern void cpu_probe(void);
 extern void central_probe(void);
 
 u32 sun4v_vdev_devhandle;
-int sun4v_vdev_root;
+struct device_node *sun4v_vdev_root;
 
 struct vdev_intmap {
        unsigned int phys;
@@ -50,102 +50,68 @@ struct vdev_intmask {
 
 static struct vdev_intmap *vdev_intmap;
 static int vdev_num_intmap;
-static struct vdev_intmask vdev_intmask;
+static struct vdev_intmask *vdev_intmask;
 
 static void __init sun4v_virtual_device_probe(void)
 {
-       struct linux_prom64_registers regs;
-       struct vdev_intmap *ip;
-       int node, sz, err;
+       struct linux_prom64_registers *regs;
+       struct property *prop;
+       struct device_node *dp;
+       int sz;
 
        if (tlb_type != hypervisor)
                return;
 
-       node = prom_getchild(prom_root_node);
-       node = prom_searchsiblings(node, "virtual-devices");
-       if (!node) {
+       dp = of_find_node_by_name(NULL, "virtual-devices");
+       if (!dp) {
                prom_printf("SUN4V: Fatal error, no virtual-devices node.\n");
                prom_halt();
        }
 
-       sun4v_vdev_root = node;
+       sun4v_vdev_root = dp;
 
-       prom_getproperty(node, "reg", (char *)&regs, sizeof(regs));
-       sun4v_vdev_devhandle = (regs.phys_addr >> 32UL) & 0x0fffffff;
+       prop = of_find_property(dp, "reg", NULL);
+       regs = prop->value;
+       sun4v_vdev_devhandle = (regs[0].phys_addr >> 32UL) & 0x0fffffff;
 
-       sz = prom_getproplen(node, "interrupt-map");
-       if (sz <= 0) {
-               prom_printf("SUN4V: Error, no vdev interrupt-map.\n");
-               prom_halt();
-       }
-
-       if ((sz % sizeof(*ip)) != 0) {
-               prom_printf("SUN4V: Bogus interrupt-map property size %d\n",
-                           sz);
-               prom_halt();
-       }
-
-       vdev_intmap = ip = alloc_bootmem_low_pages(sz);
-       if (!vdev_intmap) {
-               prom_printf("SUN4V: Error, cannot allocate vdev_intmap.\n");
-               prom_halt();
-       }
-
-       err = prom_getproperty(node, "interrupt-map", (char *) ip, sz);
-       if (err == -1) {
-               prom_printf("SUN4V: Fatal error, no vdev interrupt-map.\n");
-               prom_halt();
-       }
-       if (err != sz) {
-               prom_printf("SUN4V: Inconsistent interrupt-map size, "
-                           "proplen(%d) vs getprop(%d).\n", sz,err);
-               prom_halt();
-       }
-
-       vdev_num_intmap = err / sizeof(*ip);
+       prop = of_find_property(dp, "interrupt-map", &sz);
+       vdev_intmap = prop->value;
+       vdev_num_intmap = sz / sizeof(struct vdev_intmap);
 
-       err = prom_getproperty(node, "interrupt-map-mask",
-                              (char *) &vdev_intmask,
-                              sizeof(vdev_intmask));
-       if (err <= 0) {
-               prom_printf("SUN4V: Fatal error, no vdev "
-                           "interrupt-map-mask.\n");
-               prom_halt();
-       }
-       if (err % sizeof(vdev_intmask)) {
-               prom_printf("SUN4V: Bogus interrupt-map-mask "
-                           "property size %d\n", err);
-               prom_halt();
-       }
+       prop = of_find_property(dp, "interrupt-map-mask", NULL);
+       vdev_intmask = prop->value;
 
-       printk("SUN4V: virtual-devices devhandle[%x]\n",
-              sun4v_vdev_devhandle);
+       printk("%s: Virtual Device Bus devhandle[%x]\n",
+              dp->full_name, sun4v_vdev_devhandle);
 }
 
-unsigned int sun4v_vdev_device_interrupt(unsigned int dev_node)
+unsigned int sun4v_vdev_device_interrupt(struct device_node *dev_node)
 {
+       struct property *prop;
        unsigned int irq, reg;
-       int err, i;
+       int i;
 
-       err = prom_getproperty(dev_node, "interrupts",
-                              (char *) &irq, sizeof(irq));
-       if (err <= 0) {
+       prop = of_find_property(dev_node, "interrupts", NULL);
+       if (!prop) {
                printk("VDEV: Cannot get \"interrupts\" "
-                      "property for OBP node %x\n", dev_node);
+                      "property for OBP node %s\n",
+                      dev_node->full_name);
                return 0;
        }
+       irq = *(unsigned int *) prop->value;
 
-       err = prom_getproperty(dev_node, "reg",
-                              (char *) &reg, sizeof(reg));
-       if (err <= 0) {
+       prop = of_find_property(dev_node, "reg", NULL);
+       if (!prop) {
                printk("VDEV: Cannot get \"reg\" "
-                      "property for OBP node %x\n", dev_node);
+                      "property for OBP node %s\n",
+                      dev_node->full_name);
                return 0;
        }
+       reg = *(unsigned int *) prop->value;
 
        for (i = 0; i < vdev_num_intmap; i++) {
-               if (vdev_intmap[i].phys == (reg & vdev_intmask.phys) &&
-                   vdev_intmap[i].irq == (irq & vdev_intmask.interrupt)) {
+               if (vdev_intmap[i].phys == (reg & vdev_intmask->phys) &&
+                   vdev_intmap[i].irq == (irq & vdev_intmask->interrupt)) {
                        irq = vdev_intmap[i].cinterrupt;
                        break;
                }
@@ -153,7 +119,7 @@ unsigned int sun4v_vdev_device_interrupt(unsigned int dev_node)
 
        if (i == vdev_num_intmap) {
                printk("VDEV: No matching interrupt map entry "
-                      "for OBP node %x\n", dev_node);
+                      "for OBP node %s\n", dev_node->full_name);
                return 0;
        }
 
index f137804..ba22e25 100644 (file)
@@ -427,31 +427,32 @@ static int __init hv_console_compatible(char *buf, int len)
 
 static unsigned int __init get_interrupt(void)
 {
-       const char *cons_str = "console";
-       const char *compat_str = "compatible";
-       int node = prom_getchild(sun4v_vdev_root);
-       char buf[64];
-       int err, len;
-
-       node = prom_searchsiblings(node, cons_str);
-       if (!node)
-               return 0;
+       struct device_node *dev_node;
 
-       len = prom_getproplen(node, compat_str);
-       if (len == 0 || len == -1)
-               return 0;
+       dev_node = sun4v_vdev_root->child;
+       while (dev_node != NULL) {
+               struct property *prop;
 
-       err = prom_getproperty(node, compat_str, buf, 64);
-       if (err == -1)
-               return 0;
+               if (strcmp(dev_node->name, "console"))
+                       goto next_sibling;
+
+               prop = of_find_property(dev_node, "compatible", NULL);
+               if (!prop)
+                       goto next_sibling;
 
-       if (!hv_console_compatible(buf, len))
+               if (hv_console_compatible(prop->value, prop->length))
+                       break;
+
+       next_sibling:
+               dev_node = dev_node->sibling;
+       }
+       if (!dev_node)
                return 0;
 
        /* Ok, the this is the OBP node for the sun4v hypervisor
         * console device.  Decode the interrupt.
         */
-       return sun4v_vdev_device_interrupt(node);
+       return sun4v_vdev_device_interrupt(dev_node);
 }
 
 static int __init sunhv_init(void)
index 996e6be..25637c5 100644 (file)
@@ -7,10 +7,11 @@
 #define _SPARC64_VDEV_H
 
 #include <linux/types.h>
+#include <asm/prom.h>
 
 extern u32 sun4v_vdev_devhandle;
-extern int sun4v_vdev_root;
+extern struct device_node *sun4v_vdev_root;
 
-extern unsigned int sun4v_vdev_device_interrupt(unsigned int);
+extern unsigned int sun4v_vdev_device_interrupt(struct device_node *dev_node);
 
 #endif /* !(_SPARC64_VDEV_H) */