add minor code cleanup and a core reset for internal sb devices that need it
authorFelix Fietkau <nbd@openwrt.org>
Sun, 18 Dec 2005 06:14:57 +0000 (06:14 +0000)
committerFelix Fietkau <nbd@openwrt.org>
Sun, 18 Dec 2005 06:14:57 +0000 (06:14 +0000)
SVN-Revision: 2718

openwrt/target/linux/linux-2.6/patches/brcm/001-bcm947xx.patch

index 686f2d2af2291b012e06aae67ce0ffcf3ea4bd98..b945e4372177ba425549e9191cbea8b376b7f122 100644 (file)
@@ -11221,8 +11221,8 @@ diff -urN linux.old/arch/mips/bcm947xx/irq.c linux.dev/arch/mips/bcm947xx/irq.c
 +}
 diff -urN linux.old/arch/mips/bcm947xx/pci.c linux.dev/arch/mips/bcm947xx/pci.c
 --- linux.old/arch/mips/bcm947xx/pci.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux.dev/arch/mips/bcm947xx/pci.c 2005-12-18 04:44:18.736590500 +0100
-@@ -0,0 +1,91 @@
++++ linux.dev/arch/mips/bcm947xx/pci.c 2005-12-18 07:01:36.731635000 +0100
+@@ -0,0 +1,215 @@
 +#include <linux/kernel.h>
 +#include <linux/init.h>
 +#include <linux/pci.h>
@@ -11237,8 +11237,11 @@ diff -urN linux.old/arch/mips/bcm947xx/pci.c linux.dev/arch/mips/bcm947xx/pci.c
 +#include <sbmips.h>
 +#include <sbconfig.h>
 +#include <sbpci.h>
++#include <bcmdevs.h>
++#include <pcicfg.h>
 +
 +extern sb_t *sbh;
++extern spinlock_t sbh_lock;
 +
 +
 +static int
@@ -11246,7 +11249,12 @@ diff -urN linux.old/arch/mips/bcm947xx/pci.c linux.dev/arch/mips/bcm947xx/pci.c
 +                              int reg, int size, u32 *val)
 +{
 +      int ret;
++      unsigned long flags;
++      
++      spin_lock_irqsave(&sbh_lock, flags);
 +      ret = sbpci_read_config(sbh, bus->number, PCI_SLOT(devfn), PCI_FUNC(devfn), reg, val, size);
++      spin_unlock_irqrestore(&sbh_lock, flags);
++
 +      return ret ? PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL;
 +}
 +
@@ -11255,7 +11263,12 @@ diff -urN linux.old/arch/mips/bcm947xx/pci.c linux.dev/arch/mips/bcm947xx/pci.c
 +                              int reg, int size, u32 val)
 +{
 +      int ret;
++      unsigned long flags;
++      
++      spin_lock_irqsave(&sbh_lock, flags);
 +      ret = sbpci_write_config(sbh, bus->number, PCI_SLOT(devfn), PCI_FUNC(devfn), reg, &val, size);
++      spin_unlock_irqrestore(&sbh_lock, flags);
++
 +      return ret ? PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL;
 +}
 +
@@ -11308,12 +11321,123 @@ diff -urN linux.old/arch/mips/bcm947xx/pci.c linux.dev/arch/mips/bcm947xx/pci.c
 +
 +void bcm47xx_pci_init(void)
 +{
++      unsigned long flags;
++      
++      spin_lock_irqsave(&sbh_lock, flags);
 +      sbpci_init(sbh);
++      spin_unlock_irqrestore(&sbh_lock, flags);
++
 +      set_io_port_base((unsigned long) ioremap_nocache(SB_PCI_MEM, 0x04000000));
 +
 +      register_pci_controller(&bcm47xx_sb_pci_controller);
 +      register_pci_controller(&bcm47xx_ext_pci_controller);
 +}
++
++int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
++{
++      u8 irq;
++      
++      if (dev->bus->number == 1)
++              return 2;
++
++      pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &irq);
++      return irq + 2;
++}
++
++u32 pci_iobase = 0x100;
++u32 pci_membase = SB_PCI_DMA;
++
++static void bcm47xx_fixup_device(struct pci_dev *d)
++{
++      struct resource *res;
++      int pos, size;
++      u32 *base;
++
++      if (d->bus->number == 0)
++              return;
++      
++      printk("PCI: Fixing up device %s\n", pci_name(d));
++
++      /* Fix up resource bases */
++      for (pos = 0; pos < 6; pos++) {
++              res = &d->resource[pos];
++              base = ((res->flags & IORESOURCE_IO) ? &pci_iobase : &pci_membase);
++              if (res->end) {
++                      size = res->end - res->start + 1;
++                      if (*base & (size - 1))
++                              *base = (*base + size) & ~(size - 1);
++                      res->start = *base;
++                      res->end = res->start + size - 1;
++                      *base += size;
++                      pci_write_config_dword(d, PCI_BASE_ADDRESS_0 + (pos << 2), res->start);
++              }
++              /* Fix up PCI bridge BAR0 only */
++              if (d->bus->number == 1 && PCI_SLOT(d->devfn) == 0)
++                      break;
++      }
++      /* Fix up interrupt lines */
++      if (pci_find_device(VENDOR_BROADCOM, SB_PCI, NULL))
++              d->irq = (pci_find_device(VENDOR_BROADCOM, SB_PCI, NULL))->irq;
++      pci_write_config_byte(d, PCI_INTERRUPT_LINE, d->irq);
++}
++
++
++static void bcm47xx_fixup_bridge(struct pci_dev *dev)
++{
++      if (dev->bus->number != 1 || PCI_SLOT(dev->devfn) != 0)
++              return;
++      
++      printk("PCI: fixing up bridge\n");
++
++      /* Enable PCI bridge bus mastering and memory space */
++      pci_set_master(dev);
++      pcibios_enable_device(dev, ~0);
++      
++      /* Enable PCI bridge BAR1 prefetch and burst */
++      pci_write_config_dword(dev, PCI_BAR1_CONTROL, 3);
++}
++
++/* Do platform specific device initialization at pci_enable_device() time */
++int pcibios_plat_dev_init(struct pci_dev *dev)
++{
++      uint coreidx;
++      unsigned long flags;
++      
++      bcm47xx_fixup_device(dev);
++
++      /* These cores come out of reset enabled */
++      if ((dev->bus->number != 0) ||
++              (dev->device == SB_MIPS) ||
++              (dev->device == SB_MIPS33) ||
++              (dev->device == SB_EXTIF) ||
++              (dev->device == SB_CC))
++              return 0;
++
++      /* Do a core reset */
++      spin_lock_irqsave(&sbh_lock, flags);
++      coreidx = sb_coreidx(sbh);
++      if (sb_setcoreidx(sbh, PCI_SLOT(dev->devfn)) && (sb_coreid(sbh) == SB_USB)) {
++              /* 
++               * The USB core requires a special bit to be set during core
++               * reset to enable host (OHCI) mode. Resetting the SB core in
++               * pcibios_enable_device() is a hack for compatibility with
++               * vanilla usb-ohci so that it does not have to know about
++               * SB. A driver that wants to use the USB core in device mode
++               * should know about SB and should reset the bit back to 0
++               * after calling pcibios_enable_device().
++               */
++              sb_core_disable(sbh, sb_coreflags(sbh, 0, 0));
++              sb_core_reset(sbh, 1 << 29);
++      } else {
++              sb_core_reset(sbh, 0);
++      }
++      sb_setcoreidx(sbh, coreidx);
++      spin_unlock_irqrestore(&sbh_lock, flags);
++      
++      return 0;
++}
++
++DECLARE_PCI_FIXUP_EARLY(PCI_ANY_ID, PCI_ANY_ID, bcm47xx_fixup_bridge);
 diff -urN linux.old/arch/mips/bcm947xx/prom.c linux.dev/arch/mips/bcm947xx/prom.c
 --- linux.old/arch/mips/bcm947xx/prom.c        1970-01-01 01:00:00.000000000 +0100
 +++ linux.dev/arch/mips/bcm947xx/prom.c        2005-12-15 12:57:27.877187750 +0100
@@ -11379,8 +11503,8 @@ diff -urN linux.old/arch/mips/bcm947xx/prom.c linux.dev/arch/mips/bcm947xx/prom.
 +}
 diff -urN linux.old/arch/mips/bcm947xx/setup.c linux.dev/arch/mips/bcm947xx/setup.c
 --- linux.old/arch/mips/bcm947xx/setup.c       1970-01-01 01:00:00.000000000 +0100
-+++ linux.dev/arch/mips/bcm947xx/setup.c       2005-12-18 04:58:53.946564750 +0100
-@@ -0,0 +1,155 @@
++++ linux.dev/arch/mips/bcm947xx/setup.c       2005-12-18 06:34:52.106215250 +0100
+@@ -0,0 +1,157 @@
 +/*
 + *  Copyright (C) 2004 Florian Schirmer (jolt@tuxbox.org)
 + *  Copyright (C) 2005 Waldemar Brodkorb <wbx@openwrt.org>
@@ -11431,6 +11555,7 @@ diff -urN linux.old/arch/mips/bcm947xx/setup.c linux.dev/arch/mips/bcm947xx/setu
 +extern void bcm47xx_time_init(void);
 +extern void bcm47xx_timer_setup(struct irqaction *irq);
 +void *sbh;
++spinlock_t sbh_lock = SPIN_LOCK_UNLOCKED;
 +int boardflags;
 +
 +static int ser_line = 0;
@@ -11535,6 +11660,7 @@ diff -urN linux.old/arch/mips/bcm947xx/setup.c linux.dev/arch/mips/bcm947xx/setu
 +}
 +
 +EXPORT_SYMBOL(sbh);
++EXPORT_SYMBOL(sbh_lock);
 +EXPORT_SYMBOL(boardflags);
 diff -urN linux.old/arch/mips/bcm947xx/time.c linux.dev/arch/mips/bcm947xx/time.c
 --- linux.old/arch/mips/bcm947xx/time.c        1970-01-01 01:00:00.000000000 +0100
@@ -11683,99 +11809,6 @@ diff -urN linux.old/arch/mips/mm/tlbex.c linux.dev/arch/mips/mm/tlbex.c
                tlbw(p);
                break;
  
-diff -urN linux.old/arch/mips/pci/Makefile linux.dev/arch/mips/pci/Makefile
---- linux.old/arch/mips/pci/Makefile   2005-12-15 13:26:49.814003000 +0100
-+++ linux.dev/arch/mips/pci/Makefile   2005-12-15 14:27:26.439319250 +0100
-@@ -18,6 +18,7 @@
- obj-$(CONFIG_MIPS_TX3927)     += ops-tx3927.o
- obj-$(CONFIG_PCI_VR41XX)      += ops-vr41xx.o pci-vr41xx.o
- obj-$(CONFIG_NEC_CMBVR4133)   += fixup-vr4133.o
-+obj-$(CONFIG_BCM947XX)                += fixup-bcm47xx.o
- #
- # These are still pretty much in the old state, watch, go blind.
-diff -urN linux.old/arch/mips/pci/fixup-bcm47xx.c linux.dev/arch/mips/pci/fixup-bcm47xx.c
---- linux.old/arch/mips/pci/fixup-bcm47xx.c    1970-01-01 01:00:00.000000000 +0100
-+++ linux.dev/arch/mips/pci/fixup-bcm47xx.c    2005-12-18 04:42:58.079549750 +0100
-@@ -0,0 +1,78 @@
-+#include <linux/init.h>
-+#include <linux/pci.h>
-+#include <typedefs.h>
-+#include <sbconfig.h>
-+#include <bcmdevs.h>
-+#include <pcicfg.h>
-+
-+int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
-+{
-+      u8 irq;
-+      
-+      if (dev->bus->number == 1)
-+              return 2;
-+
-+      pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &irq);
-+      return irq + 2;
-+}
-+
-+u32 pci_iobase = 0x100;
-+u32 pci_membase = SB_PCI_DMA;
-+
-+static void bcm47xx_fixup_device(struct pci_dev *d)
-+{
-+      struct resource *res;
-+      int pos, size;
-+      u32 *base;
-+
-+      if (d->bus->number == 0)
-+              return;
-+      
-+      printk("PCI: Fixing up device %s\n", pci_name(d));
-+
-+      /* Fix up resource bases */
-+      for (pos = 0; pos < 6; pos++) {
-+              res = &d->resource[pos];
-+              base = ((res->flags & IORESOURCE_IO) ? &pci_iobase : &pci_membase);
-+              if (res->end) {
-+                      size = res->end - res->start + 1;
-+                      if (*base & (size - 1))
-+                              *base = (*base + size) & ~(size - 1);
-+                      res->start = *base;
-+                      res->end = res->start + size - 1;
-+                      *base += size;
-+                      pci_write_config_dword(d, PCI_BASE_ADDRESS_0 + (pos << 2), res->start);
-+              }
-+              /* Fix up PCI bridge BAR0 only */
-+              if (d->bus->number == 1 && PCI_SLOT(d->devfn) == 0)
-+                      break;
-+      }
-+      /* Fix up interrupt lines */
-+      if (pci_find_device(VENDOR_BROADCOM, SB_PCI, NULL))
-+              d->irq = (pci_find_device(VENDOR_BROADCOM, SB_PCI, NULL))->irq;
-+      pci_write_config_byte(d, PCI_INTERRUPT_LINE, d->irq);
-+}
-+
-+static void bcm47xx_fixup_bridge(struct pci_dev *dev)
-+{
-+      if (dev->bus->number != 1 || PCI_SLOT(dev->devfn) != 0)
-+              return;
-+      
-+      printk("PCI: fixing up bridge\n");
-+
-+      /* Enable PCI bridge bus mastering and memory space */
-+      pci_set_master(dev);
-+      pcibios_enable_device(dev, ~0);
-+      
-+      /* Enable PCI bridge BAR1 prefetch and burst */
-+      pci_write_config_dword(dev, PCI_BAR1_CONTROL, 3);
-+}
-+
-+/* Do platform specific device initialization at pci_enable_device() time */
-+int pcibios_plat_dev_init(struct pci_dev *dev)
-+{
-+      bcm47xx_fixup_device(dev);
-+      return 0;
-+}
-+
-+DECLARE_PCI_FIXUP_EARLY(PCI_ANY_ID, PCI_ANY_ID, bcm47xx_fixup_bridge);
 diff -urN linux.old/include/asm-mips/bootinfo.h linux.dev/include/asm-mips/bootinfo.h
 --- linux.old/include/asm-mips/bootinfo.h      2005-12-15 13:26:49.818001250 +0100
 +++ linux.dev/include/asm-mips/bootinfo.h      2005-12-15 12:57:27.969147500 +0100