[SPARC]: Fix bus_id[] string overflow.
[safe/jmp/linux-2.6] / arch / sparc64 / kernel / ebus.c
index 919a91d..35bf895 100644 (file)
@@ -5,7 +5,6 @@
  * Copyright (C) 1999  David S. Miller (davem@redhat.com)
  */
 
-#include <linux/config.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/types.h>
@@ -20,6 +19,8 @@
 #include <asm/pbm.h>
 #include <asm/ebus.h>
 #include <asm/oplib.h>
+#include <asm/prom.h>
+#include <asm/of_device.h>
 #include <asm/bpp.h>
 #include <asm/irq.h>
 
@@ -78,7 +79,7 @@ static void __ebus_dma_reset(struct ebus_dma_info *p, int no_drain)
        }
 }
 
-static irqreturn_t ebus_dma_irq(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t ebus_dma_irq(int irq, void *dev_id)
 {
        struct ebus_dma_info *p = dev_id;
        unsigned long flags;
@@ -139,7 +140,7 @@ int ebus_dma_irq_enable(struct ebus_dma_info *p, int on)
 
        if (on) {
                if (p->flags & EBUS_DMA_FLAG_USE_EBDMA_HANDLER) {
-                       if (request_irq(p->irq, ebus_dma_irq, SA_SHIRQ, p->name, p))
+                       if (request_irq(p->irq, ebus_dma_irq, IRQF_SHARED, p->name, p))
                                return -EBUSY;
                }
 
@@ -269,10 +270,6 @@ EXPORT_SYMBOL(ebus_dma_enable);
 
 struct linux_ebus *ebus_chain = NULL;
 
-#ifdef CONFIG_SUN_AUXIO
-extern void auxio_probe(void);
-#endif
-
 static inline void *ebus_alloc(size_t size)
 {
        void *mem;
@@ -283,73 +280,12 @@ static inline void *ebus_alloc(size_t size)
        return mem;
 }
 
-static void __init ebus_ranges_init(struct linux_ebus *ebus)
-{
-       struct linux_prom_ebus_ranges *rngs;
-       int len;
-
-       ebus->num_ebus_ranges = 0;
-       rngs = of_get_property(ebus->prom_node, "ranges", &len);
-       if (rngs) {
-               memcpy(ebus->ebus_ranges, rngs, len);
-               ebus->num_ebus_ranges =
-                       (len / sizeof(struct linux_prom_ebus_ranges));
-       }
-}
-
-static void __init ebus_intmap_init(struct linux_ebus *ebus)
-{
-       struct linux_prom_ebus_intmap *imap;
-       struct linux_prom_ebus_intmask *imask;
-       int len;
-
-       ebus->num_ebus_intmap = 0;
-       imap = of_get_property(ebus->prom_node, "interrupt-map", &len);
-       if (!imap)
-               return;
-
-       memcpy(ebus->ebus_intmap, imap, len);
-       ebus->num_ebus_intmap = (len / sizeof(struct linux_prom_ebus_intmap));
-
-       imask = of_get_property(ebus->prom_node, "interrupt-map-mask", &len);
-       if (!imask) {
-               prom_printf("EBUS: can't get interrupt-map-mask\n");
-               prom_halt();
-       }
-       memcpy(&ebus->ebus_intmask, imask, sizeof(ebus->ebus_intmask));
-}
-
-int __init 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 0;
-
-       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 0;
-               }
-       }
-       return -1;
-}
-
-void __init fill_ebus_child(struct device_node *dp,
-                           struct linux_prom_registers *preg,
-                           struct linux_ebus_child *dev,
-                           int non_standard_regs)
+static void __init fill_ebus_child(struct device_node *dp,
+                                  struct linux_ebus_child *dev,
+                                  int non_standard_regs)
 {
+       struct of_device *op;
        int *regs;
-       int *irqs;
        int i, len;
 
        dev->prom_node = dp;
@@ -386,12 +322,16 @@ void __init fill_ebus_child(struct device_node *dp,
                }
        }
 
-       for (i = 0; i < PROMINTR_MAX; i++)
-               dev->irqs[i] = PCI_IRQ_NONE;
-
-       irqs = of_get_property(dp, "interrupts", &len);
-       if (!irqs) {
+       op = of_find_device_by_node(dp);
+       if (!op) {
                dev->num_irqs = 0;
+       } else {
+               dev->num_irqs = op->num_irqs;
+               for (i = 0; i < dev->num_irqs; i++)
+                       dev->irqs[i] = op->irqs[i];
+       }
+
+       if (!dev->num_irqs) {
                /*
                 * Oh, well, some PROMs don't export interrupts
                 * property to children of EBus devices...
@@ -407,23 +347,6 @@ void __init fill_ebus_child(struct device_node *dp,
                                dev->irqs[0] = dev->parent->irqs[1];
                        }
                }
-       } else {
-               dev->num_irqs = len / sizeof(irqs[0]);
-               for (i = 0; i < dev->num_irqs; i++) {
-                       struct pci_pbm_info *pbm = dev->bus->parent;
-                       struct pci_controller_info *p = pbm->parent;
-
-                       if (ebus_intmap_match(dev->bus, preg, &irqs[i]) != -1) {
-                               dev->irqs[i] = p->irq_build(pbm,
-                                                           dev->bus->self,
-                                                           irqs[i]);
-                       } else {
-                               /* If we get a bogus interrupt property, just
-                                * record the raw value instead of punting.
-                                */
-                               dev->irqs[i] = irqs[i];
-                       }
-               }
        }
 }
 
@@ -435,73 +358,43 @@ static int __init child_regs_nonstandard(struct linux_ebus_device *dev)
        return 0;
 }
 
-void __init fill_ebus_device(struct device_node *dp, struct linux_ebus_device *dev)
+static void __init fill_ebus_device(struct device_node *dp, struct linux_ebus_device *dev)
 {
-       struct linux_prom_registers *regs;
        struct linux_ebus_child *child;
-       int *irqs;
-       int i, n, len;
+       struct of_device *op;
+       int i, len;
 
        dev->prom_node = dp;
 
        printk(" [%s", dp->name);
 
-       regs = of_get_property(dp, "reg", &len);
-       if (!regs) {
+       op = of_find_device_by_node(dp);
+       if (!op) {
                dev->num_addrs = 0;
-               goto probe_interrupts;
-       }
+               dev->num_irqs = 0;
+       } else {
+               (void) of_get_property(dp, "reg", &len);
+               dev->num_addrs = len / sizeof(struct linux_prom_registers);
 
-       if (len % sizeof(struct linux_prom_registers)) {
-               prom_printf("UGH: proplen for %s was %d, need multiple of %d\n",
-                           dev->prom_node->name, len,
-                           (int)sizeof(struct linux_prom_registers));
-               prom_halt();
-       }
-       dev->num_addrs = len / sizeof(struct linux_prom_registers);
-
-       for (i = 0; i < dev->num_addrs; i++) {
-               /* XXX Learn how to interpret ebus ranges... -DaveM */
-               if (regs[i].which_io >= 0x10)
-                       n = (regs[i].which_io - 0x10) >> 2;
-               else
-                       n = regs[i].which_io;
-
-               dev->resource[i].start  = dev->bus->self->resource[n].start;
-               dev->resource[i].start += (unsigned long)regs[i].phys_addr;
-               dev->resource[i].end    =
-                       (dev->resource[i].start + (unsigned long)regs[i].reg_size - 1UL);
-               dev->resource[i].flags  = IORESOURCE_MEM;
-               dev->resource[i].name   = dev->prom_node->name;
-               request_resource(&dev->bus->self->resource[n],
-                                &dev->resource[i]);
+               for (i = 0; i < dev->num_addrs; i++)
+                       memcpy(&dev->resource[i],
+                              &op->resource[i],
+                              sizeof(struct resource));
+
+               dev->num_irqs = op->num_irqs;
+               for (i = 0; i < dev->num_irqs; i++)
+                       dev->irqs[i] = op->irqs[i];
        }
 
-probe_interrupts:
-       for (i = 0; i < PROMINTR_MAX; i++)
-               dev->irqs[i] = PCI_IRQ_NONE;
+       dev->ofdev.node = dp;
+       dev->ofdev.dev.parent = &dev->bus->ofdev.dev;
+       dev->ofdev.dev.bus = &ebus_bus_type;
+       sprintf(dev->ofdev.dev.bus_id, "ebus[%08x]", dp->node);
 
-       irqs = of_get_property(dp, "interrupts", &len);
-       if (!irqs) {
-               dev->num_irqs = 0;
-       } else {
-               dev->num_irqs = len / sizeof(irqs[0]);
-               for (i = 0; i < dev->num_irqs; i++) {
-                       struct pci_pbm_info *pbm = dev->bus->parent;
-                       struct pci_controller_info *p = pbm->parent;
-
-                       if (ebus_intmap_match(dev->bus, &regs[0], &irqs[i]) != -1) {
-                               dev->irqs[i] = p->irq_build(pbm,
-                                                           dev->bus->self,
-                                                           irqs[i]);
-                       } else {
-                               /* If we get a bogus interrupt property, just
-                                * record the raw value instead of punting.
-                                */
-                               dev->irqs[i] = irqs[i];
-                       }
-               }
-       }
+       /* Register with core */
+       if (of_device_register(&dev->ofdev) != 0)
+               printk(KERN_DEBUG "ebus: device registration error for %s!\n",
+                      dp->path_component_name);
 
        dp = dp->child;
        if (dp) {
@@ -512,7 +405,7 @@ probe_interrupts:
                child->next = NULL;
                child->parent = dev;
                child->bus = dev->bus;
-               fill_ebus_child(dp, regs, child,
+               fill_ebus_child(dp, child,
                                child_regs_nonstandard(dev));
 
                while ((dp = dp->sibling) != NULL) {
@@ -522,7 +415,7 @@ probe_interrupts:
                        child->next = NULL;
                        child->parent = dev;
                        child->bus = dev->bus;
-                       fill_ebus_child(dp, regs, child,
+                       fill_ebus_child(dp, child,
                                        child_regs_nonstandard(dev));
                }
        }
@@ -598,8 +491,16 @@ void __init ebus_init(void)
                ebus->self = pdev;
                ebus->parent = pbm = cookie->pbm;
 
-               ebus_ranges_init(ebus);
-               ebus_intmap_init(ebus);
+               ebus->ofdev.node = dp;
+               ebus->ofdev.dev.parent = &pdev->dev;
+               ebus->ofdev.dev.bus = &ebus_bus_type;
+               sprintf(ebus->ofdev.dev.bus_id, "ebus%d", num_ebus);
+
+               /* Register with core */
+               if (of_device_register(&ebus->ofdev) != 0)
+                       printk(KERN_DEBUG "ebus: device registration error for %s!\n",
+                              dp->path_component_name);
+
 
                child = dp->child;
                if (!child)
@@ -640,8 +541,4 @@ void __init ebus_init(void)
                ++num_ebus;
        }
        pci_dev_put(pdev); /* XXX for the case, when ebusnd is 0, is it OK? */
-
-#ifdef CONFIG_SUN_AUXIO
-       auxio_probe();
-#endif
 }