*
* Bits taken from various places.
*/
-#include <linux/config.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/pci.h>
#include <asm/mach/pci.h>
static int debug_pci;
+static int use_firmware;
/*
* We can't use pci_find_device() here since we are
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
}
}
}
+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.
}
}
}
+DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, pci_fixup_ide_bases);
/*
* Put the DEC21142 to sleep
{
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
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)
{
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++) {
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;
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
/*
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;
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.
if (!strcmp(str, "debug")) {
debug_pci = 1;
return NULL;
+ } else if (!strcmp(str, "firmware")) {
+ use_firmware = 1;
+ return NULL;
}
return 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;
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;