diff options
-rw-r--r-- | arch/sh/Kconfig | 4 | ||||
-rw-r--r-- | arch/sh/drivers/pci/pci.c | 17 | ||||
-rw-r--r-- | arch/sh/include/asm/pci.h | 13 |
3 files changed, 31 insertions, 3 deletions
diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig index 352879c..bae5383 100644 --- a/arch/sh/Kconfig +++ b/arch/sh/Kconfig @@ -826,11 +826,15 @@ config MAPLE config PCI bool "PCI support" depends on SYS_SUPPORTS_PCI + select PCI_DOMAINS help Find out whether you have a PCI motherboard. PCI is the name of a bus system, i.e. the way the CPU talks to the other stuff inside your box. If you have PCI, say Y, otherwise N. +config PCI_DOMAINS + bool + source "drivers/pci/pcie/Kconfig" source "drivers/pci/Kconfig" diff --git a/arch/sh/drivers/pci/pci.c b/arch/sh/drivers/pci/pci.c index 82e59bc..45a15ca 100644 --- a/arch/sh/drivers/pci/pci.c +++ b/arch/sh/drivers/pci/pci.c @@ -33,15 +33,22 @@ static int pci_initialized; static void __devinit pcibios_scanbus(struct pci_channel *hose) { static int next_busno; + static int need_domain_info; struct pci_bus *bus; bus = pci_scan_bus(next_busno, hose->pci_ops, hose); + hose->bus = bus; + + need_domain_info = need_domain_info || hose->index; + hose->need_domain_info = need_domain_info; if (bus) { next_busno = bus->subordinate + 1; /* Don't allow 8-bit bus number overflow inside the hose - reserve some space for bridges. */ - if (next_busno > 224) + if (next_busno > 224) { next_busno = 0; + need_domain_info = 1; + } pci_bus_size_bridges(bus); pci_bus_assign_resources(bus); @@ -307,9 +314,15 @@ static void __iomem *ioport_map_pci(struct pci_dev *dev, { struct pci_channel *chan = dev->sysdata; - if (!chan->io_map_base) + if (unlikely(!chan->io_map_base)) { chan->io_map_base = generic_io_base; + if (pci_domains_supported) + panic("To avoid data corruption io_map_base MUST be " + "set with multiple PCI domains."); + } + + return (void __iomem *)(chan->io_map_base + port); } diff --git a/arch/sh/include/asm/pci.h b/arch/sh/include/asm/pci.h index f362d8a..d124a00 100644 --- a/arch/sh/include/asm/pci.h +++ b/arch/sh/include/asm/pci.h @@ -15,6 +15,7 @@ */ struct pci_channel { struct pci_channel *next; + struct pci_bus *bus; struct pci_ops *pci_ops; struct resource *io_resource; @@ -24,8 +25,10 @@ struct pci_channel { unsigned long mem_offset; unsigned long reg_base; - unsigned long io_map_base; + + unsigned int index; + unsigned int need_domain_info; }; extern void register_pci_controller(struct pci_channel *hose); @@ -108,6 +111,14 @@ extern void pcibios_resource_to_bus(struct pci_dev *dev, extern void pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res, struct pci_bus_region *region); +#define pci_domain_nr(bus) ((struct pci_channel *)(bus)->sysdata)->index + +static inline int pci_proc_domain(struct pci_bus *bus) +{ + struct pci_channel *hose = bus->sysdata; + return hose->need_domain_info; +} + /* Chances are this interrupt is wired PC-style ... */ static inline int pci_get_legacy_ide_irq(struct pci_dev *dev, int channel) { |