diff options
| -rw-r--r-- | arch/mips/pci/fixup-cobalt.c | 61 | ||||
| -rw-r--r-- | arch/mips/pci/pci.c | 2 |
2 files changed, 61 insertions, 2 deletions
diff --git a/arch/mips/pci/fixup-cobalt.c b/arch/mips/pci/fixup-cobalt.c index 9553b14002dd..acacd1407c63 100644 --- a/arch/mips/pci/fixup-cobalt.c +++ b/arch/mips/pci/fixup-cobalt.c | |||
| @@ -51,6 +51,67 @@ static void qube_raq_galileo_early_fixup(struct pci_dev *dev) | |||
| 51 | DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_MARVELL, PCI_DEVICE_ID_MARVELL_GT64111, | 51 | DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_MARVELL, PCI_DEVICE_ID_MARVELL_GT64111, |
| 52 | qube_raq_galileo_early_fixup); | 52 | qube_raq_galileo_early_fixup); |
| 53 | 53 | ||
| 54 | static void __devinit cobalt_legacy_ide_resource_fixup(struct pci_dev *dev, | ||
| 55 | struct resource *res) | ||
| 56 | { | ||
| 57 | struct pci_controller *hose = (struct pci_controller *)dev->sysdata; | ||
| 58 | unsigned long offset = hose->io_offset; | ||
| 59 | struct resource orig = *res; | ||
| 60 | |||
| 61 | if (!(res->flags & IORESOURCE_IO) || | ||
| 62 | !(res->flags & IORESOURCE_PCI_FIXED)) | ||
| 63 | return; | ||
| 64 | |||
| 65 | res->start -= offset; | ||
| 66 | res->end -= offset; | ||
| 67 | dev_printk(KERN_DEBUG, &dev->dev, "converted legacy %pR to bus %pR\n", | ||
| 68 | &orig, res); | ||
| 69 | } | ||
| 70 | |||
| 71 | static void __devinit cobalt_legacy_ide_fixup(struct pci_dev *dev) | ||
| 72 | { | ||
| 73 | u32 class; | ||
| 74 | u8 progif; | ||
| 75 | |||
| 76 | /* | ||
| 77 | * If the IDE controller is in legacy mode, pci_setup_device() fills in | ||
| 78 | * the resources with the legacy addresses that normally appear on the | ||
| 79 | * PCI bus, just as if we had read them from a BAR. | ||
| 80 | * | ||
| 81 | * However, with the GT-64111, those legacy addresses, e.g., 0x1f0, | ||
| 82 | * will never appear on the PCI bus because it converts memory accesses | ||
| 83 | * in the PCI I/O region (which is never at address zero) into I/O port | ||
| 84 | * accesses with no address translation. | ||
| 85 | * | ||
| 86 | * For example, if GT_DEF_PCI0_IO_BASE is 0x10000000, a load or store | ||
| 87 | * to physical address 0x100001f0 will become a PCI access to I/O port | ||
| 88 | * 0x100001f0. There's no way to generate an access to I/O port 0x1f0, | ||
| 89 | * but the VT82C586 IDE controller does respond at 0x100001f0 because | ||
| 90 | * it only decodes the low 24 bits of the address. | ||
| 91 | * | ||
| 92 | * When this quirk runs, the pci_dev resources should contain bus | ||
| 93 | * addresses, not Linux I/O port numbers, so convert legacy addresses | ||
| 94 | * like 0x1f0 to bus addresses like 0x100001f0. Later, we'll convert | ||
| 95 | * them back with pcibios_fixup_bus() or pcibios_bus_to_resource(). | ||
| 96 | */ | ||
| 97 | class = dev->class >> 8; | ||
| 98 | if (class != PCI_CLASS_STORAGE_IDE) | ||
| 99 | return; | ||
| 100 | |||
| 101 | pci_read_config_byte(dev, PCI_CLASS_PROG, &progif); | ||
| 102 | if ((progif & 1) == 0) { | ||
| 103 | cobalt_legacy_ide_resource_fixup(dev, &dev->resource[0]); | ||
| 104 | cobalt_legacy_ide_resource_fixup(dev, &dev->resource[1]); | ||
| 105 | } | ||
| 106 | if ((progif & 4) == 0) { | ||
| 107 | cobalt_legacy_ide_resource_fixup(dev, &dev->resource[2]); | ||
| 108 | cobalt_legacy_ide_resource_fixup(dev, &dev->resource[3]); | ||
| 109 | } | ||
| 110 | } | ||
| 111 | |||
| 112 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_1, | ||
| 113 | cobalt_legacy_ide_fixup); | ||
| 114 | |||
| 54 | static void qube_raq_via_bmIDE_fixup(struct pci_dev *dev) | 115 | static void qube_raq_via_bmIDE_fixup(struct pci_dev *dev) |
| 55 | { | 116 | { |
| 56 | unsigned short cfgword; | 117 | unsigned short cfgword; |
diff --git a/arch/mips/pci/pci.c b/arch/mips/pci/pci.c index f87f5e188fa6..38bc28005b4a 100644 --- a/arch/mips/pci/pci.c +++ b/arch/mips/pci/pci.c | |||
| @@ -251,8 +251,6 @@ static void pcibios_fixup_device_resources(struct pci_dev *dev, | |||
| 251 | for (i = 0; i < PCI_NUM_RESOURCES; i++) { | 251 | for (i = 0; i < PCI_NUM_RESOURCES; i++) { |
| 252 | if (!dev->resource[i].start) | 252 | if (!dev->resource[i].start) |
| 253 | continue; | 253 | continue; |
| 254 | if (dev->resource[i].flags & IORESOURCE_PCI_FIXED) | ||
| 255 | continue; | ||
| 256 | if (dev->resource[i].flags & IORESOURCE_IO) | 254 | if (dev->resource[i].flags & IORESOURCE_IO) |
| 257 | offset = hose->io_offset; | 255 | offset = hose->io_offset; |
| 258 | else if (dev->resource[i].flags & IORESOURCE_MEM) | 256 | else if (dev->resource[i].flags & IORESOURCE_MEM) |
