1 Index: linux-2.6.23.16/drivers/ssb/Kconfig
2 ===================================================================
3 --- linux-2.6.23.16.orig/drivers/ssb/Kconfig 2008-02-20 18:32:01.000000000 +0100
4 +++ linux-2.6.23.16/drivers/ssb/Kconfig 2008-02-20 18:32:31.000000000 +0100
5 @@ -120,4 +120,13 @@ config SSB_DRIVER_EXTIF
9 +config SSB_DRIVER_GIGE
10 + bool "SSB Broadcom Gigabit Ethernet driver (EXPERIMENTAL)"
11 + depends on SSB_PCIHOST_POSSIBLE && SSB_EMBEDDED && MIPS && EXPERIMENTAL
13 + Driver the the Sonics Silicon Backplane attached
14 + Broadcom Gigabit Ethernet.
19 Index: linux-2.6.23.16/drivers/ssb/Makefile
20 ===================================================================
21 --- linux-2.6.23.16.orig/drivers/ssb/Makefile 2008-02-20 18:32:01.000000000 +0100
22 +++ linux-2.6.23.16/drivers/ssb/Makefile 2008-02-20 18:32:31.000000000 +0100
23 @@ -11,6 +11,7 @@ ssb-y += driver_chipcommon.o
24 ssb-$(CONFIG_SSB_DRIVER_MIPS) += driver_mipscore.o
25 ssb-$(CONFIG_SSB_DRIVER_EXTIF) += driver_extif.o
26 ssb-$(CONFIG_SSB_DRIVER_PCICORE) += driver_pcicore.o
27 +ssb-$(CONFIG_SSB_DRIVER_GIGE) += driver_gige.o
29 # b43 pci-ssb-bridge driver
30 # Not strictly a part of SSB, but kept here for convenience
31 Index: linux-2.6.23.16/drivers/ssb/driver_gige.c
32 ===================================================================
33 --- /dev/null 1970-01-01 00:00:00.000000000 +0000
34 +++ linux-2.6.23.16/drivers/ssb/driver_gige.c 2008-02-20 18:32:31.000000000 +0100
37 + * Sonics Silicon Backplane
38 + * Broadcom Gigabit Ethernet core driver
40 + * Copyright 2008, Broadcom Corporation
41 + * Copyright 2008, Michael Buesch <mb@bu3sch.de>
43 + * Licensed under the GNU/GPL. See COPYING for details.
46 +#include <linux/ssb/ssb.h>
47 +#include <linux/pci.h>
48 +#include <linux/pci_regs.h>
49 +#include <linux/ssb/ssb_driver_gige.h>
52 +MODULE_DESCRIPTION("SSB Broadcom Gigabit Ethernet driver");
53 +MODULE_AUTHOR("Michael Buesch");
54 +MODULE_LICENSE("GPL");
57 +static const struct ssb_device_id ssb_gige_tbl[] = {
58 + SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_ETHERNET_GBIT, SSB_ANY_REV),
61 +MODULE_DEVICE_TABLE(ssb, ssb_gige_tbl);
64 +static inline u8 gige_read8(struct ssb_gige *dev, u16 offset)
66 + return ssb_read8(dev->dev, offset);
69 +static inline u16 gige_read16(struct ssb_gige *dev, u16 offset)
71 + return ssb_read16(dev->dev, offset);
74 +static inline u32 gige_read32(struct ssb_gige *dev, u16 offset)
76 + return ssb_read32(dev->dev, offset);
79 +static inline void gige_write8(struct ssb_gige *dev,
80 + u16 offset, u8 value)
82 + ssb_write8(dev->dev, offset, value);
85 +static inline void gige_write16(struct ssb_gige *dev,
86 + u16 offset, u16 value)
88 + ssb_write16(dev->dev, offset, value);
91 +static inline void gige_write32(struct ssb_gige *dev,
92 + u16 offset, u32 value)
94 + ssb_write32(dev->dev, offset, value);
98 +u8 gige_pcicfg_read8(struct ssb_gige *dev, unsigned int offset)
100 + BUG_ON(offset >= 256);
101 + return gige_read8(dev, SSB_GIGE_PCICFG + offset);
105 +u16 gige_pcicfg_read16(struct ssb_gige *dev, unsigned int offset)
107 + BUG_ON(offset >= 256);
108 + return gige_read16(dev, SSB_GIGE_PCICFG + offset);
112 +u32 gige_pcicfg_read32(struct ssb_gige *dev, unsigned int offset)
114 + BUG_ON(offset >= 256);
115 + return gige_read32(dev, SSB_GIGE_PCICFG + offset);
119 +void gige_pcicfg_write8(struct ssb_gige *dev,
120 + unsigned int offset, u8 value)
122 + BUG_ON(offset >= 256);
123 + gige_write8(dev, SSB_GIGE_PCICFG + offset, value);
127 +void gige_pcicfg_write16(struct ssb_gige *dev,
128 + unsigned int offset, u16 value)
130 + BUG_ON(offset >= 256);
131 + gige_write16(dev, SSB_GIGE_PCICFG + offset, value);
135 +void gige_pcicfg_write32(struct ssb_gige *dev,
136 + unsigned int offset, u32 value)
138 + BUG_ON(offset >= 256);
139 + gige_write32(dev, SSB_GIGE_PCICFG + offset, value);
142 +static int ssb_gige_pci_read_config(struct pci_bus *bus, unsigned int devfn,
143 + int reg, int size, u32 *val)
145 + struct ssb_gige *dev = container_of(bus->ops, struct ssb_gige, pci_ops);
146 + unsigned long flags;
148 + if ((PCI_SLOT(devfn) > 0) || (PCI_FUNC(devfn) > 0))
149 + return PCIBIOS_DEVICE_NOT_FOUND;
151 + return PCIBIOS_DEVICE_NOT_FOUND;
153 + spin_lock_irqsave(&dev->lock, flags);
156 + *val = gige_pcicfg_read8(dev, reg);
159 + *val = gige_pcicfg_read16(dev, reg);
162 + *val = gige_pcicfg_read32(dev, reg);
167 + spin_unlock_irqrestore(&dev->lock, flags);
169 + return PCIBIOS_SUCCESSFUL;
172 +static int ssb_gige_pci_write_config(struct pci_bus *bus, unsigned int devfn,
173 + int reg, int size, u32 val)
175 + struct ssb_gige *dev = container_of(bus->ops, struct ssb_gige, pci_ops);
176 + unsigned long flags;
178 + if ((PCI_SLOT(devfn) > 0) || (PCI_FUNC(devfn) > 0))
179 + return PCIBIOS_DEVICE_NOT_FOUND;
181 + return PCIBIOS_DEVICE_NOT_FOUND;
183 + spin_lock_irqsave(&dev->lock, flags);
186 + gige_pcicfg_write8(dev, reg, val);
189 + gige_pcicfg_write16(dev, reg, val);
192 + gige_pcicfg_write32(dev, reg, val);
197 + spin_unlock_irqrestore(&dev->lock, flags);
199 + return PCIBIOS_SUCCESSFUL;
202 +static int ssb_gige_probe(struct ssb_device *sdev, const struct ssb_device_id *id)
204 + struct ssb_gige *dev;
207 + dev = kzalloc(sizeof(*dev), GFP_KERNEL);
212 + spin_lock_init(&dev->lock);
213 + dev->pci_controller.pci_ops = &dev->pci_ops;
214 + dev->pci_controller.io_resource = &dev->io_resource;
215 + dev->pci_controller.mem_resource = &dev->mem_resource;
216 + dev->pci_controller.mem_offset = 0x24000000;
217 + dev->pci_controller.io_map_base = 0x800;
218 + dev->pci_ops.read = ssb_gige_pci_read_config;
219 + dev->pci_ops.write = ssb_gige_pci_write_config;
221 + dev->io_resource.name = "SSB GIGE I/O";
222 + dev->io_resource.start = 0x800;
223 + dev->io_resource.end = 0x8FF;
224 + dev->io_resource.flags = IORESOURCE_IO | IORESOURCE_PCI_FIXED;
226 + if (!ssb_device_is_enabled(sdev))
227 + ssb_device_enable(sdev, 0);
229 + /* Setup BAR0. This is a 64k MMIO region. */
230 + base = ssb_admatch_base(ssb_read32(sdev, SSB_ADMATCH1));
231 + gige_pcicfg_write32(dev, PCI_BASE_ADDRESS_0, base);
232 + gige_pcicfg_write32(dev, PCI_BASE_ADDRESS_1, 0);
234 + dev->mem_resource.name = "SSB GIGE memory";
235 + dev->mem_resource.start = base;
236 + dev->mem_resource.end = base + SSB_CORE_SIZE - 1;
237 + dev->mem_resource.flags = IORESOURCE_MEM | IORESOURCE_PCI_FIXED;
239 + /* Enable the memory region. */
240 + gige_pcicfg_write16(dev, PCI_COMMAND,
241 + gige_pcicfg_read16(dev, PCI_COMMAND)
242 + | PCI_COMMAND_MEMORY);
244 + /* Write flushing is controlled by the Flush Status Control register.
245 + * We want to flush every register write with a timeout and we want
246 + * to disable the IRQ mask while flushing to avoid concurrency.
247 + * Note that automatic write flushing does _not_ work from
248 + * an IRQ handler. The driver must flush manually by reading a register.
250 + gige_write32(dev, SSB_GIGE_SHIM_FLUSHSTAT, 0x00000068);
254 + ssb_set_drvdata(sdev, dev);
255 + register_pci_controller(&dev->pci_controller);
260 +int ssb_gige_pcibios_plat_dev_init(struct ssb_device *sdev,
261 + struct pci_dev *pdev)
263 + struct ssb_gige *dev = ssb_get_drvdata(sdev);
264 + struct resource *res;
266 + if (pdev->bus->ops != &dev->pci_ops) {
267 + /* The PCI device is not on this SSB GigE bridge device. */
271 + /* Fixup the PCI resources. */
272 + res = &(pdev->resource[0]);
273 + res->flags = IORESOURCE_MEM | IORESOURCE_PCI_FIXED;
274 + res->name = dev->mem_resource.name;
275 + res->start = dev->mem_resource.start;
276 + res->end = dev->mem_resource.end;
281 +int ssb_gige_map_irq(struct ssb_device *sdev,
282 + const struct pci_dev *pdev)
284 + struct ssb_gige *dev = ssb_get_drvdata(sdev);
286 + if (pdev->bus->ops != &dev->pci_ops) {
287 + /* The PCI device is not on this SSB GigE bridge device. */
291 + return ssb_mips_irq(sdev) + 2;
294 +static struct ssb_driver ssb_gige_driver = {
295 + .name = "BCM-GigE",
296 + .id_table = ssb_gige_tbl,
297 + .probe = ssb_gige_probe,
300 +int ssb_gige_init(void)
302 + return ssb_driver_register(&ssb_gige_driver);
304 Index: linux-2.6.23.16/include/linux/ssb/ssb_driver_gige.h
305 ===================================================================
306 --- /dev/null 1970-01-01 00:00:00.000000000 +0000
307 +++ linux-2.6.23.16/include/linux/ssb/ssb_driver_gige.h 2008-02-20 18:32:31.000000000 +0100
309 +#ifndef LINUX_SSB_DRIVER_GIGE_H_
310 +#define LINUX_SSB_DRIVER_GIGE_H_
312 +#include <linux/pci.h>
313 +#include <linux/spinlock.h>
315 +#ifdef CONFIG_SSB_DRIVER_GIGE
317 +#define SSB_GIGE_PCIIO 0x0000 /* PCI I/O Registers (1024 bytes) */
318 +#define SSB_GIGE_RESERVED 0x0400 /* Reserved (1024 bytes) */
319 +#define SSB_GIGE_PCICFG 0x0800 /* PCI config space (256 bytes) */
320 +#define SSB_GIGE_SHIM_FLUSHSTAT 0x0C00 /* PCI to OCP: Flush status control (32bit) */
321 +#define SSB_GIGE_SHIM_FLUSHRDA 0x0C04 /* PCI to OCP: Flush read address (32bit) */
322 +#define SSB_GIGE_SHIM_FLUSHTO 0x0C08 /* PCI to OCP: Flush timeout counter (32bit) */
323 +#define SSB_GIGE_SHIM_BARRIER 0x0C0C /* PCI to OCP: Barrier register (32bit) */
324 +#define SSB_GIGE_SHIM_MAOCPSI 0x0C10 /* PCI to OCP: MaocpSI Control (32bit) */
325 +#define SSB_GIGE_SHIM_SIOCPMA 0x0C14 /* PCI to OCP: SiocpMa Control (32bit) */
328 + struct ssb_device *dev;
332 + /* The PCI controller device. */
333 + struct pci_controller pci_controller;
334 + struct pci_ops pci_ops;
335 + struct resource mem_resource;
336 + struct resource io_resource;
339 +extern int ssb_gige_pcibios_plat_dev_init(struct ssb_device *sdev,
340 + struct pci_dev *pdev);
341 +extern int ssb_gige_map_irq(struct ssb_device *sdev,
342 + const struct pci_dev *pdev);
344 +/* The GigE driver is not a standalone module, because we don't have support
345 + * for unregistering the driver. So we could not unload the module anyway. */
346 +extern int ssb_gige_init(void);
347 +static inline void ssb_gige_exit(void)
349 + /* Currently we can not unregister the GigE driver,
350 + * because we can not unregister the PCI bridge. */
355 +#else /* CONFIG_SSB_DRIVER_GIGE */
356 +/* Gigabit Ethernet driver disabled */
359 +static inline int ssb_gige_pcibios_plat_dev_init(struct ssb_device *sdev,
360 + struct pci_dev *pdev)
364 +static inline int ssb_gige_map_irq(struct ssb_device *sdev,
365 + const struct pci_dev *pdev)
369 +static inline int ssb_gige_init(void)
373 +static inline void ssb_gige_exit(void)
377 +#endif /* CONFIG_SSB_DRIVER_GIGE */
378 +#endif /* LINUX_SSB_DRIVER_GIGE_H_ */
379 Index: linux-2.6.23.16/drivers/ssb/driver_pcicore.c
380 ===================================================================
381 --- linux-2.6.23.16.orig/drivers/ssb/driver_pcicore.c 2008-02-20 18:32:01.000000000 +0100
382 +++ linux-2.6.23.16/drivers/ssb/driver_pcicore.c 2008-02-20 18:32:31.000000000 +0100
383 @@ -60,74 +60,6 @@ static DEFINE_SPINLOCK(cfgspace_lock);
384 /* Core to access the external PCI config space. Can only have one. */
385 static struct ssb_pcicore *extpci_core;
387 -static u32 ssb_pcicore_pcibus_iobase = 0x100;
388 -static u32 ssb_pcicore_pcibus_membase = SSB_PCI_DMA;
390 -int pcibios_plat_dev_init(struct pci_dev *d)
392 - struct resource *res;
396 - ssb_printk(KERN_INFO "PCI: Fixing up device %s\n",
399 - /* Fix up resource bases */
400 - for (pos = 0; pos < 6; pos++) {
401 - res = &d->resource[pos];
402 - if (res->flags & IORESOURCE_IO)
403 - base = &ssb_pcicore_pcibus_iobase;
405 - base = &ssb_pcicore_pcibus_membase;
406 - res->flags |= IORESOURCE_PCI_FIXED;
408 - size = res->end - res->start + 1;
409 - if (*base & (size - 1))
410 - *base = (*base + size) & ~(size - 1);
411 - res->start = *base;
412 - res->end = res->start + size - 1;
414 - pci_write_config_dword(d, PCI_BASE_ADDRESS_0 + (pos << 2), res->start);
416 - /* Fix up PCI bridge BAR0 only */
417 - if (d->bus->number == 0 && PCI_SLOT(d->devfn) == 0)
420 - /* Fix up interrupt lines */
421 - d->irq = ssb_mips_irq(extpci_core->dev) + 2;
422 - pci_write_config_byte(d, PCI_INTERRUPT_LINE, d->irq);
427 -static void __init ssb_fixup_pcibridge(struct pci_dev *dev)
431 - if (dev->bus->number != 0 || PCI_SLOT(dev->devfn) != 0)
434 - ssb_printk(KERN_INFO "PCI: Fixing up bridge %s\n", pci_name(dev));
436 - /* Enable PCI bridge bus mastering and memory space */
437 - pci_set_master(dev);
438 - pcibios_enable_device(dev, ~0);
440 - /* Enable PCI bridge BAR1 prefetch and burst */
441 - pci_write_config_dword(dev, SSB_BAR1_CONTROL, 3);
443 - /* Make sure our latency is high enough to handle the devices behind us */
445 - ssb_printk(KERN_INFO "PCI: Fixing latency timer of device %s to %u\n",
446 - pci_name(dev), lat);
447 - pci_write_config_byte(dev, PCI_LATENCY_TIMER, lat);
449 -DECLARE_PCI_FIXUP_EARLY(PCI_ANY_ID, PCI_ANY_ID, ssb_fixup_pcibridge);
451 -int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
453 - return ssb_mips_irq(extpci_core->dev) + 2;
456 static u32 get_cfgspace_addr(struct ssb_pcicore *pc,
457 unsigned int bus, unsigned int dev,
458 @@ -317,6 +249,92 @@ static struct pci_controller ssb_pcicore
459 .mem_offset = 0x24000000,
462 +static u32 ssb_pcicore_pcibus_iobase = 0x100;
463 +static u32 ssb_pcicore_pcibus_membase = SSB_PCI_DMA;
465 +/* This function is called when doing a pci_enable_device().
466 + * We must first check if the device is a device on the PCI-core bridge. */
467 +int ssb_pcicore_plat_dev_init(struct pci_dev *d)
469 + struct resource *res;
473 + if (d->bus->ops != &ssb_pcicore_pciops) {
474 + /* This is not a device on the PCI-core bridge. */
478 + ssb_printk(KERN_INFO "PCI: Fixing up device %s\n",
481 + /* Fix up resource bases */
482 + for (pos = 0; pos < 6; pos++) {
483 + res = &d->resource[pos];
484 + if (res->flags & IORESOURCE_IO)
485 + base = &ssb_pcicore_pcibus_iobase;
487 + base = &ssb_pcicore_pcibus_membase;
488 + res->flags |= IORESOURCE_PCI_FIXED;
490 + size = res->end - res->start + 1;
491 + if (*base & (size - 1))
492 + *base = (*base + size) & ~(size - 1);
493 + res->start = *base;
494 + res->end = res->start + size - 1;
496 + pci_write_config_dword(d, PCI_BASE_ADDRESS_0 + (pos << 2), res->start);
498 + /* Fix up PCI bridge BAR0 only */
499 + if (d->bus->number == 0 && PCI_SLOT(d->devfn) == 0)
502 + /* Fix up interrupt lines */
503 + d->irq = ssb_mips_irq(extpci_core->dev) + 2;
504 + pci_write_config_byte(d, PCI_INTERRUPT_LINE, d->irq);
509 +/* Early PCI fixup for a device on the PCI-core bridge. */
510 +static void ssb_pcicore_fixup_pcibridge(struct pci_dev *dev)
514 + if (dev->bus->ops != &ssb_pcicore_pciops) {
515 + /* This is not a device on the PCI-core bridge. */
518 + if (dev->bus->number != 0 || PCI_SLOT(dev->devfn) != 0)
521 + ssb_printk(KERN_INFO "PCI: Fixing up bridge %s\n", pci_name(dev));
523 + /* Enable PCI bridge bus mastering and memory space */
524 + pci_set_master(dev);
525 + pcibios_enable_device(dev, ~0);
527 + /* Enable PCI bridge BAR1 prefetch and burst */
528 + pci_write_config_dword(dev, SSB_BAR1_CONTROL, 3);
530 + /* Make sure our latency is high enough to handle the devices behind us */
532 + ssb_printk(KERN_INFO "PCI: Fixing latency timer of device %s to %u\n",
533 + pci_name(dev), lat);
534 + pci_write_config_byte(dev, PCI_LATENCY_TIMER, lat);
536 +DECLARE_PCI_FIXUP_EARLY(PCI_ANY_ID, PCI_ANY_ID, ssb_pcicore_fixup_pcibridge);
538 +/* PCI device IRQ mapping. */
539 +int ssb_pcicore_pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
541 + if (dev->bus->ops != &ssb_pcicore_pciops) {
542 + /* This is not a device on the PCI-core bridge. */
545 + return ssb_mips_irq(extpci_core->dev) + 2;
548 static void ssb_pcicore_init_hostmode(struct ssb_pcicore *pc)
551 Index: linux-2.6.23.16/drivers/ssb/embedded.c
552 ===================================================================
553 --- linux-2.6.23.16.orig/drivers/ssb/embedded.c 2008-02-20 18:32:01.000000000 +0100
554 +++ linux-2.6.23.16/drivers/ssb/embedded.c 2008-02-20 18:32:31.000000000 +0100
557 #include <linux/ssb/ssb.h>
558 #include <linux/ssb/ssb_embedded.h>
559 +#include <linux/ssb/ssb_driver_pci.h>
560 +#include <linux/ssb/ssb_driver_gige.h>
561 +#include <linux/pci.h>
563 #include "ssb_private.h"
565 @@ -130,3 +133,90 @@ u32 ssb_gpio_polarity(struct ssb_bus *bu
568 EXPORT_SYMBOL(ssb_gpio_polarity);
570 +#ifdef CONFIG_SSB_DRIVER_GIGE
571 +static int gige_pci_init_callback(struct ssb_bus *bus, unsigned long data)
573 + struct pci_dev *pdev = (struct pci_dev *)data;
574 + struct ssb_device *dev;
578 + for (i = 0; i < bus->nr_devices; i++) {
579 + dev = &(bus->devices[i]);
580 + if (dev->id.coreid != SSB_DEV_ETHERNET_GBIT)
583 + !dev->dev->driver ||
584 + !device_is_registered(dev->dev))
586 + res = ssb_gige_pcibios_plat_dev_init(dev, pdev);
593 +#endif /* CONFIG_SSB_DRIVER_GIGE */
595 +int ssb_pcibios_plat_dev_init(struct pci_dev *dev)
599 + err = ssb_pcicore_plat_dev_init(dev);
602 +#ifdef CONFIG_SSB_DRIVER_GIGE
603 + err = ssb_for_each_bus_call((unsigned long)dev, gige_pci_init_callback);
607 + /* This is not a PCI device on any SSB device. */
612 +#ifdef CONFIG_SSB_DRIVER_GIGE
613 +static int gige_map_irq_callback(struct ssb_bus *bus, unsigned long data)
615 + const struct pci_dev *pdev = (const struct pci_dev *)data;
616 + struct ssb_device *dev;
620 + for (i = 0; i < bus->nr_devices; i++) {
621 + dev = &(bus->devices[i]);
622 + if (dev->id.coreid != SSB_DEV_ETHERNET_GBIT)
625 + !dev->dev->driver ||
626 + !device_is_registered(dev->dev))
628 + res = ssb_gige_map_irq(dev, pdev);
635 +#endif /* CONFIG_SSB_DRIVER_GIGE */
637 +int ssb_pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
641 + /* Check if this PCI device is a device on a SSB bus or device
642 + * and return the IRQ number for it. */
644 + res = ssb_pcicore_pcibios_map_irq(dev, slot, pin);
647 +#ifdef CONFIG_SSB_DRIVER_GIGE
648 + res = ssb_for_each_bus_call((unsigned long)dev, gige_map_irq_callback);
652 + /* This is not a PCI device on any SSB device. */
656 Index: linux-2.6.23.16/include/linux/ssb/ssb.h
657 ===================================================================
658 --- linux-2.6.23.16.orig/include/linux/ssb/ssb.h 2008-02-20 18:32:01.000000000 +0100
659 +++ linux-2.6.23.16/include/linux/ssb/ssb.h 2008-02-20 18:32:31.000000000 +0100
660 @@ -422,5 +422,12 @@ extern int ssb_bus_powerup(struct ssb_bu
661 extern u32 ssb_admatch_base(u32 adm);
662 extern u32 ssb_admatch_size(u32 adm);
664 +/* PCI device mapping and fixup routines.
665 + * Called from the architecture pcibios init code.
666 + * These are only available on SSB_EMBEDDED configurations. */
667 +#ifdef CONFIG_SSB_EMBEDDED
668 +int ssb_pcibios_plat_dev_init(struct pci_dev *dev);
669 +int ssb_pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin);
670 +#endif /* CONFIG_SSB_EMBEDDED */
672 #endif /* LINUX_SSB_H_ */
673 Index: linux-2.6.23.16/include/linux/ssb/ssb_driver_pci.h
674 ===================================================================
675 --- linux-2.6.23.16.orig/include/linux/ssb/ssb_driver_pci.h 2008-02-20 18:32:01.000000000 +0100
676 +++ linux-2.6.23.16/include/linux/ssb/ssb_driver_pci.h 2008-02-20 18:32:31.000000000 +0100
678 #ifndef LINUX_SSB_PCICORE_H_
679 #define LINUX_SSB_PCICORE_H_
681 +#include <linux/types.h>
686 #ifdef CONFIG_SSB_DRIVER_PCICORE
688 /* PCI core registers. */
689 @@ -88,6 +93,9 @@ extern void ssb_pcicore_init(struct ssb_
690 extern int ssb_pcicore_dev_irqvecs_enable(struct ssb_pcicore *pc,
691 struct ssb_device *dev);
693 +int ssb_pcicore_plat_dev_init(struct pci_dev *d);
694 +int ssb_pcicore_pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin);
697 #else /* CONFIG_SSB_DRIVER_PCICORE */
699 @@ -107,5 +115,16 @@ int ssb_pcicore_dev_irqvecs_enable(struc
704 +int ssb_pcicore_plat_dev_init(struct pci_dev *d)
709 +int ssb_pcicore_pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
714 #endif /* CONFIG_SSB_DRIVER_PCICORE */
715 #endif /* LINUX_SSB_PCICORE_H_ */
716 Index: linux-2.6.23.16/drivers/ssb/main.c
717 ===================================================================
718 --- linux-2.6.23.16.orig/drivers/ssb/main.c 2008-02-20 18:32:01.000000000 +0100
719 +++ linux-2.6.23.16/drivers/ssb/main.c 2008-02-20 18:32:31.000000000 +0100
721 #include <linux/io.h>
722 #include <linux/ssb/ssb.h>
723 #include <linux/ssb/ssb_regs.h>
724 +#include <linux/ssb/ssb_driver_gige.h>
725 #include <linux/dma-mapping.h>
726 #include <linux/pci.h>
728 @@ -68,6 +69,25 @@ found:
730 #endif /* CONFIG_SSB_PCIHOST */
732 +int ssb_for_each_bus_call(unsigned long data,
733 + int (*func)(struct ssb_bus *bus, unsigned long data))
735 + struct ssb_bus *bus;
739 + list_for_each_entry(bus, &buses, list) {
740 + res = func(bus, data);
742 + ssb_buses_unlock();
746 + ssb_buses_unlock();
751 static struct ssb_device *ssb_device_get(struct ssb_device *dev)
754 @@ -1175,7 +1195,14 @@ static int __init ssb_modinit(void)
755 err = b43_pci_ssb_bridge_init();
757 ssb_printk(KERN_ERR "Broadcom 43xx PCI-SSB-bridge "
758 - "initialization failed");
759 + "initialization failed\n");
760 + /* don't fail SSB init because of this */
763 + err = ssb_gige_init();
765 + ssb_printk(KERN_ERR "SSB Broadcom Gigabit Ethernet "
766 + "driver initialization failed\n");
767 /* don't fail SSB init because of this */
770 @@ -1189,6 +1216,7 @@ fs_initcall(ssb_modinit);
772 static void __exit ssb_modexit(void)
775 b43_pci_ssb_bridge_exit();
776 bus_unregister(&ssb_bustype);
778 Index: linux-2.6.23.16/drivers/ssb/ssb_private.h
779 ===================================================================
780 --- linux-2.6.23.16.orig/drivers/ssb/ssb_private.h 2008-02-20 18:32:01.000000000 +0100
781 +++ linux-2.6.23.16/drivers/ssb/ssb_private.h 2008-02-20 18:32:31.000000000 +0100
782 @@ -118,6 +118,8 @@ extern u32 ssb_calc_clock_rate(u32 pllty
783 extern int ssb_devices_freeze(struct ssb_bus *bus);
784 extern int ssb_devices_thaw(struct ssb_bus *bus);
785 extern struct ssb_bus *ssb_pci_dev_to_bus(struct pci_dev *pdev);
786 +int ssb_for_each_bus_call(unsigned long data,
787 + int (*func)(struct ssb_bus *bus, unsigned long data));
789 /* b43_pci_bridge.c */
790 #ifdef CONFIG_SSB_PCIHOST