|
@@ -269,15 +269,23 @@ static void __devinit pci_read_bridge_io(struct pci_bus *child)
|
|
{
|
|
{
|
|
struct pci_dev *dev = child->self;
|
|
struct pci_dev *dev = child->self;
|
|
u8 io_base_lo, io_limit_lo;
|
|
u8 io_base_lo, io_limit_lo;
|
|
- unsigned long base, limit;
|
|
|
|
|
|
+ unsigned long io_mask, io_granularity, base, limit;
|
|
struct pci_bus_region region;
|
|
struct pci_bus_region region;
|
|
- struct resource *res, res2;
|
|
|
|
|
|
+ struct resource *res;
|
|
|
|
+
|
|
|
|
+ io_mask = PCI_IO_RANGE_MASK;
|
|
|
|
+ io_granularity = 0x1000;
|
|
|
|
+ if (dev->io_window_1k) {
|
|
|
|
+ /* Support 1K I/O space granularity */
|
|
|
|
+ io_mask = PCI_IO_1K_RANGE_MASK;
|
|
|
|
+ io_granularity = 0x400;
|
|
|
|
+ }
|
|
|
|
|
|
res = child->resource[0];
|
|
res = child->resource[0];
|
|
pci_read_config_byte(dev, PCI_IO_BASE, &io_base_lo);
|
|
pci_read_config_byte(dev, PCI_IO_BASE, &io_base_lo);
|
|
pci_read_config_byte(dev, PCI_IO_LIMIT, &io_limit_lo);
|
|
pci_read_config_byte(dev, PCI_IO_LIMIT, &io_limit_lo);
|
|
- base = (io_base_lo & PCI_IO_RANGE_MASK) << 8;
|
|
|
|
- limit = (io_limit_lo & PCI_IO_RANGE_MASK) << 8;
|
|
|
|
|
|
+ base = (io_base_lo & io_mask) << 8;
|
|
|
|
+ limit = (io_limit_lo & io_mask) << 8;
|
|
|
|
|
|
if ((io_base_lo & PCI_IO_RANGE_TYPE_MASK) == PCI_IO_RANGE_TYPE_32) {
|
|
if ((io_base_lo & PCI_IO_RANGE_TYPE_MASK) == PCI_IO_RANGE_TYPE_32) {
|
|
u16 io_base_hi, io_limit_hi;
|
|
u16 io_base_hi, io_limit_hi;
|
|
@@ -289,14 +297,9 @@ static void __devinit pci_read_bridge_io(struct pci_bus *child)
|
|
|
|
|
|
if (base <= limit) {
|
|
if (base <= limit) {
|
|
res->flags = (io_base_lo & PCI_IO_RANGE_TYPE_MASK) | IORESOURCE_IO;
|
|
res->flags = (io_base_lo & PCI_IO_RANGE_TYPE_MASK) | IORESOURCE_IO;
|
|
- res2.flags = res->flags;
|
|
|
|
region.start = base;
|
|
region.start = base;
|
|
- region.end = limit + 0xfff;
|
|
|
|
- pcibios_bus_to_resource(dev, &res2, ®ion);
|
|
|
|
- if (!res->start)
|
|
|
|
- res->start = res2.start;
|
|
|
|
- if (!res->end)
|
|
|
|
- res->end = res2.end;
|
|
|
|
|
|
+ region.end = limit + io_granularity - 1;
|
|
|
|
+ pcibios_bus_to_resource(dev, res, ®ion);
|
|
dev_printk(KERN_DEBUG, &dev->dev, " bridge window %pR\n", res);
|
|
dev_printk(KERN_DEBUG, &dev->dev, " bridge window %pR\n", res);
|
|
}
|
|
}
|
|
}
|
|
}
|