fedora core 6 1.2949 + vserver 2.2.0
[linux-2.6.git] / arch / arm / kernel / bios32.c
index 1442861..240c448 100644 (file)
@@ -5,7 +5,6 @@
  *
  *  Bits taken from various places.
  */
-#include <linux/config.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/pci.h>
@@ -17,6 +16,7 @@
 #include <asm/mach/pci.h>
 
 static int debug_pci;
+static int use_firmware;
 
 /*
  * We can't use pci_find_device() here since we are
@@ -128,12 +128,14 @@ static void __devinit pci_fixup_83c553(struct pci_dev *dev)
        pci_write_config_word(dev, 0x44, 0xb000);
        outb(0x08, 0x4d1);
 }
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_WINBOND, PCI_DEVICE_ID_WINBOND_83C553, pci_fixup_83c553);
 
 static void __devinit pci_fixup_unassign(struct pci_dev *dev)
 {
        dev->resource[0].end -= dev->resource[0].start;
        dev->resource[0].start = 0;
 }
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_WINBOND2, PCI_DEVICE_ID_WINBOND2_89C940F, pci_fixup_unassign);
 
 /*
  * Prevent the PCI layer from seeing the resources allocated to this device
@@ -154,6 +156,32 @@ static void __devinit pci_fixup_dec21285(struct pci_dev *dev)
                }
        }
 }
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_21285, pci_fixup_dec21285);
+
+/*
+ * Same as above. The PrPMC800 carrier board for the PrPMC1100 
+ * card maps the host-bridge @ 00:01:00 for some reason and it
+ * ends up getting scanned. Note that we only want to do this
+ * fixup when we find the IXP4xx on a PrPMC system, which is why
+ * we check the machine type. We could be running on a board
+ * with an IXP4xx target device and we don't want to kill the
+ * resources in that case.
+ */
+static void __devinit pci_fixup_prpmc1100(struct pci_dev *dev)
+{
+       int i;
+
+       if (machine_is_prpmc1100()) {
+               dev->class &= 0xff;
+               dev->class |= PCI_CLASS_BRIDGE_HOST << 8;
+               for (i = 0; i < PCI_NUM_RESOURCES; i++) {
+                       dev->resource[i].start = 0;
+                       dev->resource[i].end   = 0;
+                       dev->resource[i].flags = 0;
+               }
+       }
+}
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IXP4XX, pci_fixup_prpmc1100);
 
 /*
  * PCI IDE controllers use non-standard I/O port decoding, respect it.
@@ -174,6 +202,7 @@ static void __devinit pci_fixup_ide_bases(struct pci_dev *dev)
                }
        }
 }
+DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, pci_fixup_ide_bases);
 
 /*
  * Put the DEC21142 to sleep
@@ -182,6 +211,7 @@ static void __devinit pci_fixup_dec21142(struct pci_dev *dev)
 {
        pci_write_config_dword(dev, 0x40, 0x80000000);
 }
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_21142, pci_fixup_dec21142);
 
 /*
  * The CY82C693 needs some rather major fixups to ensure that it does
@@ -247,34 +277,7 @@ static void __devinit pci_fixup_cy82c693(struct pci_dev *dev)
                pci_write_config_byte(dev, 0x45, 0x03);
        }
 }
-
-struct pci_fixup pcibios_fixups[] = {
-       {
-               PCI_FIXUP_HEADER,
-               PCI_VENDOR_ID_CONTAQ,   PCI_DEVICE_ID_CONTAQ_82C693,
-               pci_fixup_cy82c693
-       }, {
-               PCI_FIXUP_HEADER,
-               PCI_VENDOR_ID_DEC,      PCI_DEVICE_ID_DEC_21142,
-               pci_fixup_dec21142
-       }, {
-               PCI_FIXUP_HEADER,
-               PCI_VENDOR_ID_DEC,      PCI_DEVICE_ID_DEC_21285,
-               pci_fixup_dec21285
-       }, {
-               PCI_FIXUP_HEADER,
-               PCI_VENDOR_ID_WINBOND,  PCI_DEVICE_ID_WINBOND_83C553,
-               pci_fixup_83c553
-       }, {
-               PCI_FIXUP_HEADER,
-               PCI_VENDOR_ID_WINBOND2, PCI_DEVICE_ID_WINBOND2_89C940F,
-               pci_fixup_unassign
-       }, {
-               PCI_FIXUP_HEADER,
-               PCI_ANY_ID,             PCI_ANY_ID,
-               pci_fixup_ide_bases
-       }, { 0 }
-};
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_CONTAQ, PCI_DEVICE_ID_CONTAQ_82C693, pci_fixup_cy82c693);
 
 void __devinit pcibios_update_irq(struct pci_dev *dev, int irq)
 {
@@ -300,7 +303,7 @@ static inline int pdev_bad_for_parity(struct pci_dev *dev)
 static void __devinit
 pdev_fixup_device_resources(struct pci_sys_data *root, struct pci_dev *dev)
 {
-       unsigned long offset;
+       resource_size_t offset;
        int i;
 
        for (i = 0; i < PCI_NUM_RESOURCES; i++) {
@@ -367,17 +370,6 @@ void __devinit pcibios_fixup_bus(struct pci_bus *bus)
                        features &= ~(PCI_COMMAND_SERR | PCI_COMMAND_PARITY);
 
                switch (dev->class >> 8) {
-#if defined(CONFIG_ISA) || defined(CONFIG_EISA)
-               case PCI_CLASS_BRIDGE_ISA:
-               case PCI_CLASS_BRIDGE_EISA:
-                       /*
-                        * If this device is an ISA bridge, set isa_bridge
-                        * to point at this device.  We will then go looking
-                        * for things like keyboard, etc.
-                        */
-                       isa_bridge = dev;
-                       break;
-#endif
                case PCI_CLASS_BRIDGE_PCI:
                        pci_read_config_word(dev, PCI_BRIDGE_CONTROL, &status);
                        status |= PCI_BRIDGE_CTL_PARITY|PCI_BRIDGE_CTL_MASTER_ABORT;
@@ -443,9 +435,26 @@ pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region,
        region->end   = res->end - offset;
 }
 
+void __devinit
+pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res,
+                       struct pci_bus_region *region)
+{
+       struct pci_sys_data *root = dev->sysdata;
+       unsigned long offset = 0;
+
+       if (res->flags & IORESOURCE_IO)
+               offset = root->io_offset;
+       if (res->flags & IORESOURCE_MEM)
+               offset = root->mem_offset;
+
+       res->start = region->start + offset;
+       res->end   = region->end + offset;
+}
+
 #ifdef CONFIG_HOTPLUG
 EXPORT_SYMBOL(pcibios_fixup_bus);
 EXPORT_SYMBOL(pcibios_resource_to_bus);
+EXPORT_SYMBOL(pcibios_bus_to_resource);
 #endif
 
 /*
@@ -519,12 +528,10 @@ static void __init pcibios_init_hw(struct hw_pci *hw)
        int nr, busnr;
 
        for (nr = busnr = 0; nr < hw->nr_controllers; nr++) {
-               sys = kmalloc(sizeof(struct pci_sys_data), GFP_KERNEL);
+               sys = kzalloc(sizeof(struct pci_sys_data), GFP_KERNEL);
                if (!sys)
                        panic("PCI: unable to allocate sys data!");
 
-               memset(sys, 0, sizeof(struct pci_sys_data));
-
                sys->hw      = hw;
                sys->busnr   = busnr;
                sys->swizzle = hw->swizzle;
@@ -568,15 +575,17 @@ void __init pci_common_init(struct hw_pci *hw)
        list_for_each_entry(sys, &hw->buses, node) {
                struct pci_bus *bus = sys->bus;
 
-               /*
-                * Size the bridge windows.
-                */
-               pci_bus_size_bridges(bus);
+               if (!use_firmware) {
+                       /*
+                        * Size the bridge windows.
+                        */
+                       pci_bus_size_bridges(bus);
 
-               /*
-                * Assign resources.
-                */
-               pci_bus_assign_resources(bus);
+                       /*
+                        * Assign resources.
+                        */
+                       pci_bus_assign_resources(bus);
+               }
 
                /*
                 * Tell drivers about devices found.
@@ -590,6 +599,9 @@ char * __init pcibios_setup(char *str)
        if (!strcmp(str, "debug")) {
                debug_pci = 1;
                return NULL;
+       } else if (!strcmp(str, "firmware")) {
+               use_firmware = 1;
+               return NULL;
        }
        return str;
 }
@@ -610,9 +622,9 @@ char * __init pcibios_setup(char *str)
  * which might be mirrored at 0x0100-0x03ff..
  */
 void pcibios_align_resource(void *data, struct resource *res,
-                           unsigned long size, unsigned long align)
+                           resource_size_t size, resource_size_t align)
 {
-       unsigned long start = res->start;
+       resource_size_t start = res->start;
 
        if (res->flags & IORESOURCE_IO && start & 0x300)
                start = (start + 0x3ff) & ~0x3ff;
@@ -672,16 +684,15 @@ int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma,
        if (mmap_state == pci_mmap_io) {
                return -EINVAL;
        } else {
-               phys = root->mem_offset + (vma->vm_pgoff << PAGE_SHIFT);
+               phys = vma->vm_pgoff + (root->mem_offset >> PAGE_SHIFT);
        }
 
        /*
         * Mark this as IO
         */
-       vma->vm_flags |= VM_SHM | VM_LOCKED | VM_IO;
        vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
 
-       if (remap_page_range(vma, vma->vm_start, phys,
+       if (remap_pfn_range(vma, vma->vm_start, phys,
                             vma->vm_end - vma->vm_start,
                             vma->vm_page_prot))
                return -EAGAIN;