Merge SSB driver from tree at bu3sch.de, pulled 24/6
authorPeter Denison <openwrt@marshadder.org>
Mon, 25 Jun 2007 19:51:09 +0000 (19:51 +0000)
committerPeter Denison <openwrt@marshadder.org>
Mon, 25 Jun 2007 19:51:09 +0000 (19:51 +0000)
SVN-Revision: 7732

target/linux/brcm47xx-2.6/files/drivers/ssb/driver_chipcommon.c
target/linux/brcm47xx-2.6/files/drivers/ssb/main.c
target/linux/brcm47xx-2.6/files/drivers/ssb/pci.c
target/linux/brcm47xx-2.6/files/drivers/ssb/pcmcia.c
target/linux/brcm47xx-2.6/files/drivers/ssb/scan.c
target/linux/brcm47xx-2.6/files/drivers/ssb/ssb_private.h
target/linux/brcm47xx-2.6/files/include/linux/ssb/ssb.h
target/linux/brcm47xx-2.6/files/include/linux/ssb/ssb_regs.h
target/linux/brcm47xx-2.6/patches-2.6.22/210-ssb_merge.patch
target/linux/brcm47xx-2.6/patches-2.6.22/230-ssb_arch_setup.patch [new file with mode: 0644]

index 8e511c7..a283de9 100644 (file)
@@ -293,15 +293,15 @@ void ssb_chipco_timing_init(struct ssb_chipcommon *cc,
 
        /* set register for external IO to control LED. */
        chipco_write32(cc, SSB_CHIPCO_PROG_CFG, 0x11);
 
        /* set register for external IO to control LED. */
        chipco_write32(cc, SSB_CHIPCO_PROG_CFG, 0x11);
-       tmp = ceildiv(10, ns) << SSB_PROG_WCNT_3_SHIFT;         /* Waitcount-3 = 10ns */
-       tmp |= ceildiv(40, ns) << SSB_PROG_WCNT_1_SHIFT;        /* Waitcount-1 = 40ns */
-       tmp |= ceildiv(240, ns);                                /* Waitcount-0 = 240ns */
+       tmp = DIV_ROUND_UP(10, ns) << SSB_PROG_WCNT_3_SHIFT;            /* Waitcount-3 = 10ns */
+       tmp |= DIV_ROUND_UP(40, ns) << SSB_PROG_WCNT_1_SHIFT;   /* Waitcount-1 = 40ns */
+       tmp |= DIV_ROUND_UP(240, ns);                           /* Waitcount-0 = 240ns */
        chipco_write32(cc, SSB_CHIPCO_PROG_WAITCNT, tmp);       /* 0x01020a0c for a 100Mhz clock */
 
        /* Set timing for the flash */
        chipco_write32(cc, SSB_CHIPCO_PROG_WAITCNT, tmp);       /* 0x01020a0c for a 100Mhz clock */
 
        /* Set timing for the flash */
-       tmp = ceildiv(10, ns) << SSB_FLASH_WCNT_3_SHIFT;        /* Waitcount-3 = 10nS */
-       tmp |= ceildiv(10, ns) << SSB_FLASH_WCNT_1_SHIFT;       /* Waitcount-1 = 10nS */
-       tmp |= ceildiv(120, ns);                                /* Waitcount-0 = 120nS */
+       tmp = DIV_ROUND_UP(10, ns) << SSB_FLASH_WCNT_3_SHIFT;   /* Waitcount-3 = 10nS */
+       tmp |= DIV_ROUND_UP(10, ns) << SSB_FLASH_WCNT_1_SHIFT;  /* Waitcount-1 = 10nS */
+       tmp |= DIV_ROUND_UP(120, ns);                           /* Waitcount-0 = 120nS */
        if ((bus->chip_id == 0x5365) ||
            (dev->id.revision < 9))
                chipco_write32(cc, SSB_CHIPCO_FLASH_WAITCNT, tmp);
        if ((bus->chip_id == 0x5365) ||
            (dev->id.revision < 9))
                chipco_write32(cc, SSB_CHIPCO_FLASH_WAITCNT, tmp);
@@ -312,10 +312,10 @@ void ssb_chipco_timing_init(struct ssb_chipcommon *cc,
 
        if (bus->chip_id == 0x5350) {
                /* Enable EXTIF */
 
        if (bus->chip_id == 0x5350) {
                /* Enable EXTIF */
-               tmp = ceildiv(10, ns) << SSB_PROG_WCNT_3_SHIFT;   /* Waitcount-3 = 10ns */
-               tmp |= ceildiv(20, ns) << SSB_PROG_WCNT_2_SHIFT;  /* Waitcount-2 = 20ns */
-               tmp |= ceildiv(100, ns) << SSB_PROG_WCNT_1_SHIFT; /* Waitcount-1 = 100ns */
-               tmp |= ceildiv(120, ns);                          /* Waitcount-0 = 120ns */
+               tmp = DIV_ROUND_UP(10, ns) << SSB_PROG_WCNT_3_SHIFT;      /* Waitcount-3 = 10ns */
+               tmp |= DIV_ROUND_UP(20, ns) << SSB_PROG_WCNT_2_SHIFT;  /* Waitcount-2 = 20ns */
+               tmp |= DIV_ROUND_UP(100, ns) << SSB_PROG_WCNT_1_SHIFT; /* Waitcount-1 = 100ns */
+               tmp |= DIV_ROUND_UP(120, ns);                     /* Waitcount-0 = 120ns */
                chipco_write32(cc, SSB_CHIPCO_PROG_WAITCNT, tmp); /* 0x01020a0c for a 100Mhz clock */
        }
 }
                chipco_write32(cc, SSB_CHIPCO_PROG_WAITCNT, tmp); /* 0x01020a0c for a 100Mhz clock */
        }
 }
index a2d2231..a892f1d 100644 (file)
@@ -32,7 +32,7 @@ MODULE_LICENSE("GPL");
 
 static LIST_HEAD(attach_queue);
 static LIST_HEAD(buses);
 
 static LIST_HEAD(attach_queue);
 static LIST_HEAD(buses);
-static int nr_buses;
+static unsigned int next_busnumber;
 static DEFINE_MUTEX(buses_mutex);
 
 static void ssb_buses_lock(void);
 static DEFINE_MUTEX(buses_mutex);
 
 static void ssb_buses_lock(void);
@@ -365,7 +365,7 @@ static int ssb_devices_register(struct ssb_bus *bus)
                dev->release = ssb_release_dev;
                dev->bus = &ssb_bustype;
                snprintf(dev->bus_id, sizeof(dev->bus_id),
                dev->release = ssb_release_dev;
                dev->bus = &ssb_bustype;
                snprintf(dev->bus_id, sizeof(dev->bus_id),
-                        "ssb%d:%d", bus->busnumber, dev_idx);
+                        "ssb%u:%d", bus->busnumber, dev_idx);
 
                switch (bus->bustype) {
                case SSB_BUSTYPE_PCI:
 
                switch (bus->bustype) {
                case SSB_BUSTYPE_PCI:
@@ -435,17 +435,6 @@ static int ssb_attach_queued_buses(void)
        return err;
 }
 
        return err;
 }
 
-static void ssb_get_boardtype(struct ssb_bus *bus)
-{//FIXME for pcmcia?
-       if (bus->bustype != SSB_BUSTYPE_PCI) {
-               /* Must set board_vendor, board_type and board_rev
-                * before calling ssb_bus_*_register() */
-               assert(bus->board_vendor && bus->board_type);
-               return;
-       }
-       ssb_pci_get_boardtype(bus);
-}
-
 static u16 ssb_ssb_read16(struct ssb_device *dev, u16 offset)
 {
        struct ssb_bus *bus = dev->bus;
 static u16 ssb_ssb_read16(struct ssb_device *dev, u16 offset)
 {
        struct ssb_bus *bus = dev->bus;
@@ -485,7 +474,26 @@ static const struct ssb_bus_ops ssb_ssb_ops = {
        .write32        = ssb_ssb_write32,
 };
 
        .write32        = ssb_ssb_write32,
 };
 
+static int ssb_fetch_invariants(struct ssb_bus *bus,
+                               int (*get_invariants)(struct ssb_bus *bus,
+                                                     struct ssb_init_invariants *iv))
+{
+       struct ssb_init_invariants iv;
+       int err;
+
+       memset(&iv, 0, sizeof(iv));
+       err = get_invariants(bus, &iv);
+       if (err)
+               goto out;
+       memcpy(&bus->boardinfo, &iv.boardinfo, sizeof(iv.boardinfo));
+       memcpy(&bus->sprom, &iv.sprom, sizeof(iv.sprom));
+out:
+       return err;
+}
+
 static int ssb_bus_register(struct ssb_bus *bus,
 static int ssb_bus_register(struct ssb_bus *bus,
+                           int (*get_invariants)(struct ssb_bus *bus,
+                                                 struct ssb_init_invariants *iv),
                            unsigned long baseaddr)
 {
        int err;
                            unsigned long baseaddr)
 {
        int err;
@@ -493,13 +501,12 @@ static int ssb_bus_register(struct ssb_bus *bus,
        spin_lock_init(&bus->bar_lock);
        INIT_LIST_HEAD(&bus->list);
 
        spin_lock_init(&bus->bar_lock);
        INIT_LIST_HEAD(&bus->list);
 
-       ssb_get_boardtype(bus);
        /* Powerup the bus */
        err = ssb_pci_xtal(bus, SSB_GPIO_XTAL | SSB_GPIO_PLL, 1);
        if (err)
                goto out;
        ssb_buses_lock();
        /* Powerup the bus */
        err = ssb_pci_xtal(bus, SSB_GPIO_XTAL | SSB_GPIO_PLL, 1);
        if (err)
                goto out;
        ssb_buses_lock();
-       bus->busnumber = nr_buses;
+       bus->busnumber = next_busnumber;
        /* Scan for devices (cores) */
        err = ssb_bus_scan(bus, baseaddr);
        if (err)
        /* Scan for devices (cores) */
        err = ssb_bus_scan(bus, baseaddr);
        if (err)
@@ -517,6 +524,9 @@ static int ssb_bus_register(struct ssb_bus *bus,
        /* Initialize basic system devices (if available) */
        ssb_chipcommon_init(&bus->chipco);
        ssb_mipscore_init(&bus->mipscore);
        /* Initialize basic system devices (if available) */
        ssb_chipcommon_init(&bus->chipco);
        ssb_mipscore_init(&bus->mipscore);
+       err = ssb_fetch_invariants(bus, get_invariants);
+       if (err)
+               goto err_pcmcia_exit;
 
        /* Queue it for attach */
        list_add_tail(&bus->list, &attach_queue);
 
        /* Queue it for attach */
        list_add_tail(&bus->list, &attach_queue);
@@ -526,7 +536,7 @@ static int ssb_bus_register(struct ssb_bus *bus,
                if (err)
                        goto err_dequeue;
        }
                if (err)
                        goto err_dequeue;
        }
-       nr_buses++;
+       next_busnumber++;
        ssb_buses_unlock();
 
 out:
        ssb_buses_unlock();
 
 out:
@@ -534,7 +544,7 @@ out:
 
 err_dequeue:
        list_del(&bus->list);
 
 err_dequeue:
        list_del(&bus->list);
-/* err_pcmcia_exit: */
+err_pcmcia_exit:
 /*     ssb_pcmcia_exit(bus); */
 err_pci_exit:
        ssb_pci_exit(bus);
 /*     ssb_pcmcia_exit(bus); */
 err_pci_exit:
        ssb_pci_exit(bus);
@@ -556,7 +566,7 @@ int ssb_bus_pcibus_register(struct ssb_bus *bus,
        bus->host_pci = host_pci;
        bus->ops = &ssb_pci_ops;
 
        bus->host_pci = host_pci;
        bus->ops = &ssb_pci_ops;
 
-       err = ssb_bus_register(bus, 0);
+       err = ssb_bus_register(bus, ssb_pci_get_invariants, 0);
        if (!err) {
                ssb_printk(KERN_INFO PFX "Sonics Silicon Backplane found on "
                           "PCI device %s\n", host_pci->dev.bus_id);
        if (!err) {
                ssb_printk(KERN_INFO PFX "Sonics Silicon Backplane found on "
                           "PCI device %s\n", host_pci->dev.bus_id);
@@ -570,17 +580,15 @@ EXPORT_SYMBOL(ssb_bus_pcibus_register);
 #ifdef CONFIG_SSB_PCMCIAHOST
 int ssb_bus_pcmciabus_register(struct ssb_bus *bus,
                               struct pcmcia_device *pcmcia_dev,
 #ifdef CONFIG_SSB_PCMCIAHOST
 int ssb_bus_pcmciabus_register(struct ssb_bus *bus,
                               struct pcmcia_device *pcmcia_dev,
-                              unsigned long baseaddr,
-                              void (*fill_sprom)(struct ssb_sprom *sprom))
+                              unsigned long baseaddr)
 {
        int err;
 
        bus->bustype = SSB_BUSTYPE_PCMCIA;
        bus->host_pcmcia = pcmcia_dev;
        bus->ops = &ssb_pcmcia_ops;
 {
        int err;
 
        bus->bustype = SSB_BUSTYPE_PCMCIA;
        bus->host_pcmcia = pcmcia_dev;
        bus->ops = &ssb_pcmcia_ops;
-       fill_sprom(&bus->sprom);
 
 
-       err = ssb_bus_register(bus, baseaddr);
+       err = ssb_bus_register(bus, ssb_pcmcia_get_invariants, baseaddr);
        if (!err) {
                ssb_printk(KERN_INFO PFX "Sonics Silicon Backplane found on "
                           "PCMCIA device %s\n", pcmcia_dev->devname);
        if (!err) {
                ssb_printk(KERN_INFO PFX "Sonics Silicon Backplane found on "
                           "PCMCIA device %s\n", pcmcia_dev->devname);
@@ -593,15 +601,15 @@ EXPORT_SYMBOL(ssb_bus_pcmciabus_register);
 
 int ssb_bus_ssbbus_register(struct ssb_bus *bus,
                            unsigned long baseaddr,
 
 int ssb_bus_ssbbus_register(struct ssb_bus *bus,
                            unsigned long baseaddr,
-                           void (*fill_sprom)(struct ssb_sprom *sprom))
+                           int (*get_invariants)(struct ssb_bus *bus,
+                                                 struct ssb_init_invariants *iv))
 {
        int err;
 
        bus->bustype = SSB_BUSTYPE_SSB;
        bus->ops = &ssb_ssb_ops;
 {
        int err;
 
        bus->bustype = SSB_BUSTYPE_SSB;
        bus->ops = &ssb_ssb_ops;
-       fill_sprom(&bus->sprom);
 
 
-       err = ssb_bus_register(bus, baseaddr);
+       err = ssb_bus_register(bus, get_invariants, baseaddr);
        if (!err) {
                ssb_printk(KERN_INFO PFX "Sonics Silicon Backplane found at "
                           "address 0x%08lX\n", baseaddr);
        if (!err) {
                ssb_printk(KERN_INFO PFX "Sonics Silicon Backplane found at "
                           "address 0x%08lX\n", baseaddr);
index fcd8e87..f9dc28f 100644 (file)
@@ -330,12 +330,12 @@ static void sprom_extract_r1(struct ssb_sprom_r1 *out, const u16 *in)
        SPEX(gpio2, SSB_SPROM1_GPIOB, SSB_SPROM1_GPIOB_P2, 0);
        SPEX(gpio3, SSB_SPROM1_GPIOB, SSB_SPROM1_GPIOB_P3,
             SSB_SPROM1_GPIOB_P3_SHIFT);
        SPEX(gpio2, SSB_SPROM1_GPIOB, SSB_SPROM1_GPIOB_P2, 0);
        SPEX(gpio3, SSB_SPROM1_GPIOB, SSB_SPROM1_GPIOB_P3,
             SSB_SPROM1_GPIOB_P3_SHIFT);
-       SPEX(maxpwr_a, SSB_SPROM1_MAXPWR, SSB_SPROM1_MAXPWR_A, 0);
-       SPEX(maxpwr_bg, SSB_SPROM1_MAXPWR, SSB_SPROM1_MAXPWR_BG,
-            SSB_SPROM1_MAXPWR_BG_SHIFT);
-       SPEX(itssi_a, SSB_SPROM1_ITSSI, SSB_SPROM1_ITSSI_A, 0);
-       SPEX(itssi_bg, SSB_SPROM1_ITSSI, SSB_SPROM1_ITSSI_BG,
-            SSB_SPROM1_ITSSI_BG_SHIFT);
+       SPEX(maxpwr_a, SSB_SPROM1_MAXPWR, SSB_SPROM1_MAXPWR_A,
+            SSB_SPROM1_MAXPWR_A_SHIFT);
+       SPEX(maxpwr_bg, SSB_SPROM1_MAXPWR, SSB_SPROM1_MAXPWR_BG, 0);
+       SPEX(itssi_a, SSB_SPROM1_ITSSI, SSB_SPROM1_ITSSI_A,
+            SSB_SPROM1_ITSSI_A_SHIFT);
+       SPEX(itssi_bg, SSB_SPROM1_ITSSI, SSB_SPROM1_ITSSI_BG, 0);
        SPEX(boardflags_lo, SSB_SPROM1_BFLLO, 0xFFFF, 0);
        SPEX(antenna_gain_a, SSB_SPROM1_AGAIN, SSB_SPROM1_AGAIN_A, 0);
        SPEX(antenna_gain_bg, SSB_SPROM1_AGAIN, SSB_SPROM1_AGAIN_BG,
        SPEX(boardflags_lo, SSB_SPROM1_BFLLO, 0xFFFF, 0);
        SPEX(antenna_gain_a, SSB_SPROM1_AGAIN, SSB_SPROM1_AGAIN_A, 0);
        SPEX(antenna_gain_bg, SSB_SPROM1_AGAIN, SSB_SPROM1_AGAIN_BG,
@@ -407,7 +407,8 @@ static void sprom_extract_r3(struct ssb_sprom_r3 *out, const u16 *in)
        out->ofdmgpo |= (in[SPOFF(SSB_SPROM3_OFDMGPO) + 1] & 0x00FF) << 8;
 }
 
        out->ofdmgpo |= (in[SPOFF(SSB_SPROM3_OFDMGPO) + 1] & 0x00FF) << 8;
 }
 
-static int sprom_extract(struct ssb_sprom *out, const u16 *in)
+static int sprom_extract(struct ssb_bus *bus,
+                        struct ssb_sprom *out, const u16 *in)
 {
        memset(out, 0, sizeof(*out));
 
 {
        memset(out, 0, sizeof(*out));
 
@@ -415,16 +416,23 @@ static int sprom_extract(struct ssb_sprom *out, const u16 *in)
        SPEX(crc, SSB_SPROM_REVISION, SSB_SPROM_REVISION_CRC,
             SSB_SPROM_REVISION_CRC_SHIFT);
 
        SPEX(crc, SSB_SPROM_REVISION, SSB_SPROM_REVISION_CRC,
             SSB_SPROM_REVISION_CRC_SHIFT);
 
-       if (out->revision == 0)
-               goto unsupported;
-       if (out->revision >= 1 && out->revision <= 3)
+       if ((bus->chip_id & 0xFF00) == 0x4400) {
+               /* Workaround: The BCM44XX chip has a stupid revision
+                * number stored in the SPROM.
+                * Always extract r1. */
                sprom_extract_r1(&out->r1, in);
                sprom_extract_r1(&out->r1, in);
-       if (out->revision >= 2 && out->revision <= 3)
-               sprom_extract_r2(&out->r2, in);
-       if (out->revision == 3)
-               sprom_extract_r3(&out->r3, in);
-       if (out->revision >= 4)
-               goto unsupported;
+       } else {
+               if (out->revision == 0)
+                       goto unsupported;
+               if (out->revision >= 1 && out->revision <= 3)
+                       sprom_extract_r1(&out->r1, in);
+               if (out->revision >= 2 && out->revision <= 3)
+                       sprom_extract_r2(&out->r2, in);
+               if (out->revision == 3)
+                       sprom_extract_r3(&out->r3, in);
+               if (out->revision >= 4)
+                       goto unsupported;
+       }
 
        return 0;
 unsupported:
 
        return 0;
 unsupported:
@@ -434,13 +442,12 @@ unsupported:
        return 0;
 }
 
        return 0;
 }
 
-int ssb_pci_sprom_get(struct ssb_bus *bus)
+static int ssb_pci_sprom_get(struct ssb_bus *bus,
+                            struct ssb_sprom *sprom)
 {
        int err = -ENOMEM;
        u16 *buf;
 
 {
        int err = -ENOMEM;
        u16 *buf;
 
-       assert(bus->bustype == SSB_BUSTYPE_PCI);
-
        buf = kcalloc(SSB_SPROMSIZE_WORDS, sizeof(u16), GFP_KERNEL);
        if (!buf)
                goto out;
        buf = kcalloc(SSB_SPROMSIZE_WORDS, sizeof(u16), GFP_KERNEL);
        if (!buf)
                goto out;
@@ -450,21 +457,36 @@ int ssb_pci_sprom_get(struct ssb_bus *bus)
                ssb_printk(KERN_WARNING PFX
                           "WARNING: Invalid SPROM CRC (corrupt SPROM)\n");
        }
                ssb_printk(KERN_WARNING PFX
                           "WARNING: Invalid SPROM CRC (corrupt SPROM)\n");
        }
-       err = sprom_extract(&bus->sprom, buf);
+       err = sprom_extract(bus, sprom, buf);
 
        kfree(buf);
 out:
        return err;
 }
 
 
        kfree(buf);
 out:
        return err;
 }
 
-void ssb_pci_get_boardtype(struct ssb_bus *bus)
+static void ssb_pci_get_boardinfo(struct ssb_bus *bus,
+                                 struct ssb_boardinfo *bi)
 {
        pci_read_config_word(bus->host_pci, PCI_SUBSYSTEM_VENDOR_ID,
 {
        pci_read_config_word(bus->host_pci, PCI_SUBSYSTEM_VENDOR_ID,
-                            &bus->board_vendor);
+                            &bi->vendor);
        pci_read_config_word(bus->host_pci, PCI_SUBSYSTEM_ID,
        pci_read_config_word(bus->host_pci, PCI_SUBSYSTEM_ID,
-                            &bus->board_type);
+                            &bi->type);
        pci_read_config_word(bus->host_pci, PCI_REVISION_ID,
        pci_read_config_word(bus->host_pci, PCI_REVISION_ID,
-                            &bus->board_rev);
+                            &bi->rev);
+}
+
+int ssb_pci_get_invariants(struct ssb_bus *bus,
+                          struct ssb_init_invariants *iv)
+{
+       int err;
+
+       err = ssb_pci_sprom_get(bus, &iv->sprom);
+       if (err)
+               goto out;
+       ssb_pci_get_boardinfo(bus, &iv->boardinfo);
+
+out:
+       return err;
 }
 
 static u16 ssb_pci_read16(struct ssb_device *dev, u16 offset)
 }
 
 static u16 ssb_pci_read16(struct ssb_device *dev, u16 offset)
@@ -660,13 +682,7 @@ int ssb_pci_init(struct ssb_bus *bus)
        err = device_create_file(&pdev->dev, &dev_attr_ssb_sprom);
        if (err)
                goto out;
        err = device_create_file(&pdev->dev, &dev_attr_ssb_sprom);
        if (err)
                goto out;
-       err = ssb_pci_sprom_get(bus);
-       if (err)
-               goto err_remove_sprom_file;
 
 out:
        return err;
 
 out:
        return err;
-err_remove_sprom_file:
-       device_remove_file(&pdev->dev, &dev_attr_ssb_sprom);
-       return err;
 }
 }
index 60cf5ad..b908563 100644 (file)
@@ -222,6 +222,13 @@ const struct ssb_bus_ops ssb_pcmcia_ops = {
        .write32        = ssb_pcmcia_write32,
 };
 
        .write32        = ssb_pcmcia_write32,
 };
 
+int ssb_pcmcia_get_invariants(struct ssb_bus *bus,
+                             struct ssb_init_invariants *iv)
+{
+       //TODO
+       return 0;
+}
+
 int ssb_pcmcia_init(struct ssb_bus *bus)
 {
        conf_reg_t reg;
 int ssb_pcmcia_init(struct ssb_bus *bus)
 {
        conf_reg_t reg;
index feaf1e5..b5d909c 100644 (file)
@@ -202,7 +202,11 @@ void ssb_iounmap(struct ssb_bus *bus)
                iounmap(bus->mmio);
                break;
        case SSB_BUSTYPE_PCI:
                iounmap(bus->mmio);
                break;
        case SSB_BUSTYPE_PCI:
+#ifdef CONFIG_SSB_PCIHOST
                pci_iounmap(bus->host_pci, bus->mmio);
                pci_iounmap(bus->host_pci, bus->mmio);
+#else
+               assert(0); /* Can't reach this code. */
+#endif
                break;
        }
        bus->mmio = NULL;
                break;
        }
        bus->mmio = NULL;
@@ -222,7 +226,11 @@ static void __iomem * ssb_ioremap(struct ssb_bus *bus,
                mmio = ioremap(baseaddr, SSB_CORE_SIZE);
                break;
        case SSB_BUSTYPE_PCI:
                mmio = ioremap(baseaddr, SSB_CORE_SIZE);
                break;
        case SSB_BUSTYPE_PCI:
+#ifdef CONFIG_SSB_PCIHOST
                mmio = pci_iomap(bus->host_pci, 0, ~0UL);
                mmio = pci_iomap(bus->host_pci, 0, ~0UL);
+#else
+               assert(0); /* Can't reach this code. */
+#endif
                break;
        }
 
                break;
        }
 
index ae1fc06..d00d186 100644 (file)
@@ -51,8 +51,8 @@ extern int ssb_pci_switch_coreidx(struct ssb_bus *bus,
                                  u8 coreidx);
 extern int ssb_pci_xtal(struct ssb_bus *bus, u32 what,
                        int turn_on);
                                  u8 coreidx);
 extern int ssb_pci_xtal(struct ssb_bus *bus, u32 what,
                        int turn_on);
-extern int ssb_pci_sprom_get(struct ssb_bus *bus);
-extern void ssb_pci_get_boardtype(struct ssb_bus *bus);
+extern int ssb_pci_get_invariants(struct ssb_bus *bus,
+                                 struct ssb_init_invariants *iv);
 extern void ssb_pci_exit(struct ssb_bus *bus);
 extern int ssb_pci_init(struct ssb_bus *bus);
 extern const struct ssb_bus_ops ssb_pci_ops;
 extern void ssb_pci_exit(struct ssb_bus *bus);
 extern int ssb_pci_init(struct ssb_bus *bus);
 extern const struct ssb_bus_ops ssb_pci_ops;
@@ -74,13 +74,6 @@ static inline int ssb_pci_xtal(struct ssb_bus *bus, u32 what,
 {
        return 0;
 }
 {
        return 0;
 }
-static inline int ssb_pci_sprom_get(struct ssb_bus *bus)
-{
-       return 0;
-}
-static inline void ssb_pci_get_boardtype(struct ssb_bus *bus)
-{
-}
 static inline void ssb_pci_exit(struct ssb_bus *bus)
 {
 }
 static inline void ssb_pci_exit(struct ssb_bus *bus)
 {
 }
@@ -99,6 +92,8 @@ extern int ssb_pcmcia_switch_coreidx(struct ssb_bus *bus,
                                     u8 coreidx);
 extern int ssb_pcmcia_switch_segment(struct ssb_bus *bus,
                                     u8 seg);
                                     u8 coreidx);
 extern int ssb_pcmcia_switch_segment(struct ssb_bus *bus,
                                     u8 seg);
+extern int ssb_pcmcia_get_invariants(struct ssb_bus *bus,
+                                    struct ssb_init_invariants *iv);
 extern int ssb_pcmcia_init(struct ssb_bus *bus);
 extern const struct ssb_bus_ops ssb_pcmcia_ops;
 #else /* CONFIG_SSB_PCMCIAHOST */
 extern int ssb_pcmcia_init(struct ssb_bus *bus);
 extern const struct ssb_bus_ops ssb_pcmcia_ops;
 #else /* CONFIG_SSB_PCMCIAHOST */
@@ -139,13 +134,4 @@ extern int ssb_devices_thaw(struct ssb_bus *bus);
 extern struct ssb_bus * ssb_pci_dev_to_bus(struct pci_dev *pdev);
 #endif /* CONFIG_SSB_PCIHOST */
 
 extern struct ssb_bus * ssb_pci_dev_to_bus(struct pci_dev *pdev);
 #endif /* CONFIG_SSB_PCIHOST */
 
-
-/* Ceiling division helper. Divides x by y. */
-static inline
-unsigned long ceildiv(unsigned long x, unsigned long y)
-{
-       return ((x + (y - 1)) / y);
-}
-
-
 #endif /* LINUX_SSB_PRIVATE_H_ */
 #endif /* LINUX_SSB_PRIVATE_H_ */
index 1ed3cbc..a3d1f51 100644 (file)
@@ -100,6 +100,13 @@ struct ssb_sprom {
        };
 };
 
        };
 };
 
+/* Information about the PCB the circuitry is soldered on. */
+struct ssb_boardinfo {
+       u16 vendor;
+       u16 type;
+       u16 rev;
+};
+
 
 struct ssb_device;
 /* Lowlevel read/write operations on the device MMIO.
 
 struct ssb_device;
 /* Lowlevel read/write operations on the device MMIO.
@@ -292,19 +299,11 @@ struct ssb_bus {
        struct mutex pci_sprom_mutex;
 #endif
 
        struct mutex pci_sprom_mutex;
 #endif
 
-       /* ID information about the PCB. */
-       u16 board_vendor;
-       u16 board_type;
-       u16 board_rev;
        /* ID information about the Chip. */
        u16 chip_id;
        u16 chip_rev;
        u8 chip_package;
 
        /* ID information about the Chip. */
        u16 chip_id;
        u16 chip_rev;
        u8 chip_package;
 
-       /* Contents of the SPROM.
-        * If there is no sprom (not on PCI-bus), this is emulated. */
-       struct ssb_sprom sprom;
-
        /* List of devices (cores) on the backplane. */
        struct ssb_device devices[SSB_MAX_NR_CORES];
        u8 nr_devices;
        /* List of devices (cores) on the backplane. */
        struct ssb_device devices[SSB_MAX_NR_CORES];
        u8 nr_devices;
@@ -313,7 +312,7 @@ struct ssb_bus {
        u8 suspend_cnt;
 
        /* Software ID number for this bus. */
        u8 suspend_cnt;
 
        /* Software ID number for this bus. */
-       int busnumber;
+       unsigned int busnumber;
 
        /* The ChipCommon device (if available). */
        struct ssb_chipcommon chipco;
 
        /* The ChipCommon device (if available). */
        struct ssb_chipcommon chipco;
@@ -324,13 +323,34 @@ struct ssb_bus {
        /* The EXTif-core device (if available). */
        struct ssb_extif extif;
 
        /* The EXTif-core device (if available). */
        struct ssb_extif extif;
 
+       /* The following structure elements are not available in early
+        * SSB initialization. Though, they are available for regular
+        * registered drivers at any stage. So be careful when
+        * using them in the ssb core code. */
+
+       /* ID information about the PCB. */
+       struct ssb_boardinfo boardinfo;
+       /* Contents of the SPROM. */
+       struct ssb_sprom sprom;
+
        /* Internal. */
        struct list_head list;
 };
 
        /* Internal. */
        struct list_head list;
 };
 
+/* The initialization-invariants. */
+struct ssb_init_invariants {
+       struct ssb_boardinfo boardinfo;
+       struct ssb_sprom sprom;
+};
+
+/* Register a SSB system bus. get_invariants() is called after the
+ * basic system devices are initialized.
+ * The invariants are usually fetched from some NVRAM.
+ * Put the invariants into the struct pointed to by iv. */
 extern int ssb_bus_ssbbus_register(struct ssb_bus *bus,
                                   unsigned long baseaddr,
 extern int ssb_bus_ssbbus_register(struct ssb_bus *bus,
                                   unsigned long baseaddr,
-                                  void (*fill_sprom)(struct ssb_sprom *sprom));
+                                  int (*get_invariants)(struct ssb_bus *bus,
+                                                        struct ssb_init_invariants *iv));
 #ifdef CONFIG_SSB_PCIHOST
 extern int ssb_bus_pcibus_register(struct ssb_bus *bus,
                                   struct pci_dev *host_pci);
 #ifdef CONFIG_SSB_PCIHOST
 extern int ssb_bus_pcibus_register(struct ssb_bus *bus,
                                   struct pci_dev *host_pci);
@@ -338,8 +358,7 @@ extern int ssb_bus_pcibus_register(struct ssb_bus *bus,
 #ifdef CONFIG_SSB_PCMCIAHOST
 extern int ssb_bus_pcmciabus_register(struct ssb_bus *bus,
                                      struct pcmcia_device *pcmcia_dev,
 #ifdef CONFIG_SSB_PCMCIAHOST
 extern int ssb_bus_pcmciabus_register(struct ssb_bus *bus,
                                      struct pcmcia_device *pcmcia_dev,
-                                     unsigned long baseaddr,
-                                     void (*fill_sprom)(struct ssb_sprom *sprom));
+                                     unsigned long baseaddr);
 #endif /* CONFIG_SSB_PCMCIAHOST */
 
 extern void ssb_bus_unregister(struct ssb_bus *bus);
 #endif /* CONFIG_SSB_PCMCIAHOST */
 
 extern void ssb_bus_unregister(struct ssb_bus *bus);
index e1c7ff7..1fa4bf8 100644 (file)
 #define  SSB_SPROM1_GPIOB_P3           0xFF00  /* Pin 3 */
 #define  SSB_SPROM1_GPIOB_P3_SHIFT     8
 #define SSB_SPROM1_MAXPWR              0x1068  /* Power Amplifier Max Power */
 #define  SSB_SPROM1_GPIOB_P3           0xFF00  /* Pin 3 */
 #define  SSB_SPROM1_GPIOB_P3_SHIFT     8
 #define SSB_SPROM1_MAXPWR              0x1068  /* Power Amplifier Max Power */
-#define  SSB_SPROM1_MAXPWR_A           0x00FF  /* A-PHY (in dBm Q5.2) */
-#define  SSB_SPROM1_MAXPWR_BG          0xFF00  /* B-PHY and G-PHY (in dBm Q5.2) */
-#define  SSB_SPROM1_MAXPWR_BG_SHIFT    8
+#define  SSB_SPROM1_MAXPWR_BG          0x00FF  /* B-PHY and G-PHY (in dBm Q5.2) */
+#define  SSB_SPROM1_MAXPWR_A           0xFF00  /* A-PHY (in dBm Q5.2) */
+#define  SSB_SPROM1_MAXPWR_A_SHIFT     8
 #define SSB_SPROM1_PA1B0               0x106A
 #define SSB_SPROM1_PA1B1               0x106C
 #define SSB_SPROM1_PA1B2               0x106E
 #define SSB_SPROM1_ITSSI               0x1070  /* Idle TSSI Target */
 #define SSB_SPROM1_PA1B0               0x106A
 #define SSB_SPROM1_PA1B1               0x106C
 #define SSB_SPROM1_PA1B2               0x106E
 #define SSB_SPROM1_ITSSI               0x1070  /* Idle TSSI Target */
-#define  SSB_SPROM1_ITSSI_A            0x00FF  /* A-PHY */
-#define  SSB_SPROM1_ITSSI_BG           0xFF00  /* B-PHY and G-PHY */
-#define  SSB_SPROM1_ITSSI_BG_SHIFT     8
+#define  SSB_SPROM1_ITSSI_BG           0x00FF  /* B-PHY and G-PHY*/
+#define  SSB_SPROM1_ITSSI_A            0xFF00  /* A-PHY */
+#define  SSB_SPROM1_ITSSI_A_SHIFT      8
 #define SSB_SPROM1_BFLLO               0x1072  /* Boardflags (low 16 bits) */
 #define SSB_SPROM1_AGAIN               0x1074  /* Antenna Gain (in dBm Q5.2) */
 #define  SSB_SPROM1_AGAIN_A            0x00FF  /* A-PHY */
 #define SSB_SPROM1_BFLLO               0x1072  /* Boardflags (low 16 bits) */
 #define SSB_SPROM1_AGAIN               0x1074  /* Antenna Gain (in dBm Q5.2) */
 #define  SSB_SPROM1_AGAIN_A            0x00FF  /* A-PHY */
index 21986b3..fbf22cb 100644 (file)
@@ -1,7 +1,7 @@
-Index: linux-2.6.22-rc4/drivers/ssb/driver_chipcommon.c
+Index: linux-2.6.22-rc5/drivers/ssb/driver_chipcommon.c
 ===================================================================
 ===================================================================
---- linux-2.6.22-rc4.orig/drivers/ssb/driver_chipcommon.c      2007-06-10 21:32:11.000000000 +0100
-+++ linux-2.6.22-rc4/drivers/ssb/driver_chipcommon.c   2007-06-10 21:33:25.000000000 +0100
+--- linux-2.6.22-rc5.orig/drivers/ssb/driver_chipcommon.c      2007-06-21 23:04:38.000000000 +0100
++++ linux-2.6.22-rc5/drivers/ssb/driver_chipcommon.c   2007-06-24 20:07:15.000000000 +0100
 @@ -264,6 +264,31 @@
        ssb_chipco_set_clockmode(cc, SSB_CLKMODE_FAST);
  }
 @@ -264,6 +264,31 @@
        ssb_chipco_set_clockmode(cc, SSB_CLKMODE_FAST);
  }
@@ -48,10 +48,10 @@ Index: linux-2.6.22-rc4/drivers/ssb/driver_chipcommon.c
 +      return 0;
 +}
 +EXPORT_SYMBOL(ssb_chipco_watchdog);
 +      return 0;
 +}
 +EXPORT_SYMBOL(ssb_chipco_watchdog);
-Index: linux-2.6.22-rc4/drivers/ssb/driver_mipscore.c
+Index: linux-2.6.22-rc5/drivers/ssb/driver_mipscore.c
 ===================================================================
 ===================================================================
---- linux-2.6.22-rc4.orig/drivers/ssb/driver_mipscore.c        2007-06-10 21:32:11.000000000 +0100
-+++ linux-2.6.22-rc4/drivers/ssb/driver_mipscore.c     2007-06-10 21:33:25.000000000 +0100
+--- linux-2.6.22-rc5.orig/drivers/ssb/driver_mipscore.c        2007-06-10 16:44:31.000000000 +0100
++++ linux-2.6.22-rc5/drivers/ssb/driver_mipscore.c     2007-06-24 20:48:52.000000000 +0100
 @@ -4,6 +4,7 @@
   *
   * Copyright 2005, Broadcom Corporation
 @@ -4,6 +4,7 @@
   *
   * Copyright 2005, Broadcom Corporation
@@ -116,16 +116,16 @@ Index: linux-2.6.22-rc4/drivers/ssb/driver_mipscore.c
 +      extif_write32(extif, SSB_EXTIF_PROG_CFG, SSB_EXTCFG_EN);
 +
 +      /* Set timing for the flash */
 +      extif_write32(extif, SSB_EXTIF_PROG_CFG, SSB_EXTCFG_EN);
 +
 +      /* Set timing for the flash */
-+      tmp  = ceildiv(10, ns) << SSB_PROG_WCNT_3_SHIFT;
-+      tmp |= ceildiv(40, ns) << SSB_PROG_WCNT_1_SHIFT;
-+      tmp |= ceildiv(120, ns);
++      tmp  = DIV_ROUND_UP(10, ns) << SSB_PROG_WCNT_3_SHIFT;
++      tmp |= DIV_ROUND_UP(40, ns) << SSB_PROG_WCNT_1_SHIFT;
++      tmp |= DIV_ROUND_UP(120, ns);
 +      extif_write32(extif, SSB_EXTIF_PROG_WAITCNT, tmp);
 +
 +      /* Set programmable interface timing for external uart */
 +      extif_write32(extif, SSB_EXTIF_PROG_WAITCNT, tmp);
 +
 +      /* Set programmable interface timing for external uart */
-+      tmp  = ceildiv(10, ns) << SSB_PROG_WCNT_3_SHIFT;
-+      tmp |= ceildiv(20, ns) << SSB_PROG_WCNT_2_SHIFT;
-+      tmp |= ceildiv(100, ns) << SSB_PROG_WCNT_1_SHIFT;
-+      tmp |= ceildiv(120, ns);
++      tmp  = DIV_ROUND_UP(10, ns) << SSB_PROG_WCNT_3_SHIFT;
++      tmp |= DIV_ROUND_UP(20, ns) << SSB_PROG_WCNT_2_SHIFT;
++      tmp |= DIV_ROUND_UP(100, ns) << SSB_PROG_WCNT_1_SHIFT;
++      tmp |= DIV_ROUND_UP(120, ns);
 +      extif_write32(extif, SSB_EXTIF_PROG_WAITCNT, tmp);
 +}
  
 +      extif_write32(extif, SSB_EXTIF_PROG_WAITCNT, tmp);
 +}
  
@@ -217,10 +217,10 @@ Index: linux-2.6.22-rc4/drivers/ssb/driver_mipscore.c
  }
 +
 +EXPORT_SYMBOL(ssb_mips_irq);
  }
 +
 +EXPORT_SYMBOL(ssb_mips_irq);
-Index: linux-2.6.22-rc4/drivers/ssb/driver_pcicore.c
+Index: linux-2.6.22-rc5/drivers/ssb/driver_pcicore.c
 ===================================================================
 ===================================================================
---- linux-2.6.22-rc4.orig/drivers/ssb/driver_pcicore.c 2007-06-10 21:32:11.000000000 +0100
-+++ linux-2.6.22-rc4/drivers/ssb/driver_pcicore.c      2007-06-10 21:33:25.000000000 +0100
+--- linux-2.6.22-rc5.orig/drivers/ssb/driver_pcicore.c 2007-06-10 16:44:31.000000000 +0100
++++ linux-2.6.22-rc5/drivers/ssb/driver_pcicore.c      2007-06-24 20:07:15.000000000 +0100
 @@ -93,6 +93,9 @@
  
        /* Enable PCI bridge BAR1 prefetch and burst */
 @@ -93,6 +93,9 @@
  
        /* Enable PCI bridge BAR1 prefetch and burst */
@@ -266,10 +266,10 @@ Index: linux-2.6.22-rc4/drivers/ssb/driver_pcicore.c
        register_pci_controller(&ssb_pcicore_controller);
  }
  
        register_pci_controller(&ssb_pcicore_controller);
  }
  
-Index: linux-2.6.22-rc4/include/linux/ssb/ssb_driver_chipcommon.h
+Index: linux-2.6.22-rc5/include/linux/ssb/ssb_driver_chipcommon.h
 ===================================================================
 ===================================================================
---- linux-2.6.22-rc4.orig/include/linux/ssb/ssb_driver_chipcommon.h    2007-06-10 21:32:11.000000000 +0100
-+++ linux-2.6.22-rc4/include/linux/ssb/ssb_driver_chipcommon.h 2007-06-10 21:33:25.000000000 +0100
+--- linux-2.6.22-rc5.orig/include/linux/ssb/ssb_driver_chipcommon.h    2007-06-10 16:44:47.000000000 +0100
++++ linux-2.6.22-rc5/include/linux/ssb/ssb_driver_chipcommon.h 2007-06-24 20:07:15.000000000 +0100
 @@ -364,6 +364,8 @@
  extern void ssb_chipco_suspend(struct ssb_chipcommon *cc, pm_message_t state);
  extern void ssb_chipco_resume(struct ssb_chipcommon *cc);
 @@ -364,6 +364,8 @@
  extern void ssb_chipco_suspend(struct ssb_chipcommon *cc, pm_message_t state);
  extern void ssb_chipco_resume(struct ssb_chipcommon *cc);
@@ -326,10 +326,10 @@ Index: linux-2.6.22-rc4/include/linux/ssb/ssb_driver_chipcommon.h
  #ifdef CONFIG_SSB_SERIAL
  extern int ssb_chipco_serial_init(struct ssb_chipcommon *cc,
                                  struct ssb_serial_port *ports);
  #ifdef CONFIG_SSB_SERIAL
  extern int ssb_chipco_serial_init(struct ssb_chipcommon *cc,
                                  struct ssb_serial_port *ports);
-Index: linux-2.6.22-rc4/include/linux/ssb/ssb_driver_extif.h
+Index: linux-2.6.22-rc5/include/linux/ssb/ssb_driver_extif.h
 ===================================================================
 ===================================================================
---- linux-2.6.22-rc4.orig/include/linux/ssb/ssb_driver_extif.h 2007-06-10 21:32:11.000000000 +0100
-+++ linux-2.6.22-rc4/include/linux/ssb/ssb_driver_extif.h      2007-06-10 21:33:25.000000000 +0100
+--- linux-2.6.22-rc5.orig/include/linux/ssb/ssb_driver_extif.h 2007-06-10 16:44:47.000000000 +0100
++++ linux-2.6.22-rc5/include/linux/ssb/ssb_driver_extif.h      2007-06-24 20:07:15.000000000 +0100
 @@ -158,6 +158,36 @@
  /* watchdog */
  #define SSB_EXTIF_WATCHDOG_CLK                48000000        /* Hz */
 @@ -158,6 +158,36 @@
  /* watchdog */
  #define SSB_EXTIF_WATCHDOG_CLK                48000000        /* Hz */
@@ -367,10 +367,10 @@ Index: linux-2.6.22-rc4/include/linux/ssb/ssb_driver_extif.h
  
  #endif /* __KERNEL__ */
  #endif /* LINUX_SSB_EXTIFCORE_H_ */
  
  #endif /* __KERNEL__ */
  #endif /* LINUX_SSB_EXTIFCORE_H_ */
-Index: linux-2.6.22-rc4/include/linux/ssb/ssb_driver_mips.h
+Index: linux-2.6.22-rc5/include/linux/ssb/ssb_driver_mips.h
 ===================================================================
 ===================================================================
---- linux-2.6.22-rc4.orig/include/linux/ssb/ssb_driver_mips.h  2007-06-10 21:32:11.000000000 +0100
-+++ linux-2.6.22-rc4/include/linux/ssb/ssb_driver_mips.h       2007-06-10 21:33:25.000000000 +0100
+--- linux-2.6.22-rc5.orig/include/linux/ssb/ssb_driver_mips.h  2007-06-10 16:44:47.000000000 +0100
++++ linux-2.6.22-rc5/include/linux/ssb/ssb_driver_mips.h       2007-06-24 20:07:15.000000000 +0100
 @@ -22,11 +22,13 @@
        int nr_serial_ports;
        struct ssb_serial_port serial_ports[4];
 @@ -22,11 +22,13 @@
        int nr_serial_ports;
        struct ssb_serial_port serial_ports[4];
@@ -385,11 +385,11 @@ Index: linux-2.6.22-rc4/include/linux/ssb/ssb_driver_mips.h
  
  extern unsigned int ssb_mips_irq(struct ssb_device *dev);
  
  
  extern unsigned int ssb_mips_irq(struct ssb_device *dev);
  
-Index: linux-2.6.22-rc4/include/linux/ssb/ssb.h
+Index: linux-2.6.22-rc5/include/linux/ssb/ssb.h
 ===================================================================
 ===================================================================
---- linux-2.6.22-rc4.orig/include/linux/ssb/ssb.h      2007-06-10 21:32:11.000000000 +0100
-+++ linux-2.6.22-rc4/include/linux/ssb/ssb.h   2007-06-10 21:33:25.000000000 +0100
-@@ -263,6 +263,12 @@
+--- linux-2.6.22-rc5.orig/include/linux/ssb/ssb.h      2007-06-24 19:49:56.000000000 +0100
++++ linux-2.6.22-rc5/include/linux/ssb/ssb.h   2007-06-24 20:07:15.000000000 +0100
+@@ -270,6 +270,12 @@
  #define SSB_CHIPPACK_BCM4712M 2       /* Medium 225pin 4712 */
  #define SSB_CHIPPACK_BCM4712L 0       /* Large 340pin 4712 */
  
  #define SSB_CHIPPACK_BCM4712M 2       /* Medium 225pin 4712 */
  #define SSB_CHIPPACK_BCM4712L 0       /* Large 340pin 4712 */
  
@@ -402,7 +402,7 @@ Index: linux-2.6.22-rc4/include/linux/ssb/ssb.h
  #include <linux/ssb/ssb_driver_chipcommon.h>
  #include <linux/ssb/ssb_driver_mips.h>
  #include <linux/ssb/ssb_driver_extif.h>
  #include <linux/ssb/ssb_driver_chipcommon.h>
  #include <linux/ssb/ssb_driver_mips.h>
  #include <linux/ssb/ssb_driver_extif.h>
-@@ -369,6 +375,16 @@
+@@ -388,6 +394,16 @@
        dev->ops->write32(dev, offset, value);
  }
  
        dev->ops->write32(dev, offset, value);
  }
  
diff --git a/target/linux/brcm47xx-2.6/patches-2.6.22/230-ssb_arch_setup.patch b/target/linux/brcm47xx-2.6/patches-2.6.22/230-ssb_arch_setup.patch
new file mode 100644 (file)
index 0000000..8e97364
--- /dev/null
@@ -0,0 +1,33 @@
+Index: linux-2.6.22-rc5/arch/mips/bcm947xx/setup.c
+===================================================================
+--- linux-2.6.22-rc5.orig/arch/mips/bcm947xx/setup.c   2007-06-24 19:51:21.000000000 +0100
++++ linux-2.6.22-rc5/arch/mips/bcm947xx/setup.c        2007-06-24 20:26:12.000000000 +0100
+@@ -107,13 +107,27 @@
+               sprom->r1.et1phyaddr = simple_strtoul(s, NULL, 10);
+ }
++static int bcm47xx_get_invariants(struct ssb_bus *bus, struct ssb_init_invariants *iv)
++{
++      char *s;
++      
++      // TODO
++      //iv->boardinfo.vendor = 
++      if ((s = nvram_get("boardtype")))
++              iv->boardinfo.type = (u16)simple_strtoul(s, NULL, 0);
++      if ((s = nvram_get("boardrev")))
++              iv->boardinfo.rev = (u16)simple_strtoul(s, NULL, 0);
++      bcm47xx_fill_sprom(&iv->sprom);
++      return 0;
++}
++
+ void __init plat_mem_setup(void)
+ {
+       int i, err;
+       char *s;
+       struct ssb_mipscore *mcore;
+-      err = ssb_bus_ssbbus_register(&ssb, SSB_ENUM_BASE, bcm47xx_fill_sprom);
++      err = ssb_bus_ssbbus_register(&ssb, SSB_ENUM_BASE, bcm47xx_get_invariants);
+       if (err) {
+               const char *msg = "Failed to initialize SSB bus (err %d)\n";
+               cfe_printk(msg, err); /* Make sure the message gets out of the box. */