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 352879c1b86b..bae53831c06b 100644 --- a/arch/sh/Kconfig +++ b/arch/sh/Kconfig | |||
@@ -826,11 +826,15 @@ config MAPLE | |||
826 | config PCI | 826 | config PCI |
827 | bool "PCI support" | 827 | bool "PCI support" |
828 | depends on SYS_SUPPORTS_PCI | 828 | depends on SYS_SUPPORTS_PCI |
829 | select PCI_DOMAINS | ||
829 | help | 830 | help |
830 | Find out whether you have a PCI motherboard. PCI is the name of a | 831 | Find out whether you have a PCI motherboard. PCI is the name of a |
831 | bus system, i.e. the way the CPU talks to the other stuff inside | 832 | bus system, i.e. the way the CPU talks to the other stuff inside |
832 | your box. If you have PCI, say Y, otherwise N. | 833 | your box. If you have PCI, say Y, otherwise N. |
833 | 834 | ||
835 | config PCI_DOMAINS | ||
836 | bool | ||
837 | |||
834 | source "drivers/pci/pcie/Kconfig" | 838 | source "drivers/pci/pcie/Kconfig" |
835 | 839 | ||
836 | source "drivers/pci/Kconfig" | 840 | source "drivers/pci/Kconfig" |
diff --git a/arch/sh/drivers/pci/pci.c b/arch/sh/drivers/pci/pci.c index 82e59bc6210e..45a15cab01df 100644 --- a/arch/sh/drivers/pci/pci.c +++ b/arch/sh/drivers/pci/pci.c | |||
@@ -33,15 +33,22 @@ static int pci_initialized; | |||
33 | static void __devinit pcibios_scanbus(struct pci_channel *hose) | 33 | static void __devinit pcibios_scanbus(struct pci_channel *hose) |
34 | { | 34 | { |
35 | static int next_busno; | 35 | static int next_busno; |
36 | static int need_domain_info; | ||
36 | struct pci_bus *bus; | 37 | struct pci_bus *bus; |
37 | 38 | ||
38 | bus = pci_scan_bus(next_busno, hose->pci_ops, hose); | 39 | bus = pci_scan_bus(next_busno, hose->pci_ops, hose); |
40 | hose->bus = bus; | ||
41 | |||
42 | need_domain_info = need_domain_info || hose->index; | ||
43 | hose->need_domain_info = need_domain_info; | ||
39 | if (bus) { | 44 | if (bus) { |
40 | next_busno = bus->subordinate + 1; | 45 | next_busno = bus->subordinate + 1; |
41 | /* Don't allow 8-bit bus number overflow inside the hose - | 46 | /* Don't allow 8-bit bus number overflow inside the hose - |
42 | reserve some space for bridges. */ | 47 | reserve some space for bridges. */ |
43 | if (next_busno > 224) | 48 | if (next_busno > 224) { |
44 | next_busno = 0; | 49 | next_busno = 0; |
50 | need_domain_info = 1; | ||
51 | } | ||
45 | 52 | ||
46 | pci_bus_size_bridges(bus); | 53 | pci_bus_size_bridges(bus); |
47 | pci_bus_assign_resources(bus); | 54 | pci_bus_assign_resources(bus); |
@@ -307,9 +314,15 @@ static void __iomem *ioport_map_pci(struct pci_dev *dev, | |||
307 | { | 314 | { |
308 | struct pci_channel *chan = dev->sysdata; | 315 | struct pci_channel *chan = dev->sysdata; |
309 | 316 | ||
310 | if (!chan->io_map_base) | 317 | if (unlikely(!chan->io_map_base)) { |
311 | chan->io_map_base = generic_io_base; | 318 | chan->io_map_base = generic_io_base; |
312 | 319 | ||
320 | if (pci_domains_supported) | ||
321 | panic("To avoid data corruption io_map_base MUST be " | ||
322 | "set with multiple PCI domains."); | ||
323 | } | ||
324 | |||
325 | |||
313 | return (void __iomem *)(chan->io_map_base + port); | 326 | return (void __iomem *)(chan->io_map_base + port); |
314 | } | 327 | } |
315 | 328 | ||
diff --git a/arch/sh/include/asm/pci.h b/arch/sh/include/asm/pci.h index f362d8a045e7..d124a009889f 100644 --- a/arch/sh/include/asm/pci.h +++ b/arch/sh/include/asm/pci.h | |||
@@ -15,6 +15,7 @@ | |||
15 | */ | 15 | */ |
16 | struct pci_channel { | 16 | struct pci_channel { |
17 | struct pci_channel *next; | 17 | struct pci_channel *next; |
18 | struct pci_bus *bus; | ||
18 | 19 | ||
19 | struct pci_ops *pci_ops; | 20 | struct pci_ops *pci_ops; |
20 | struct resource *io_resource; | 21 | struct resource *io_resource; |
@@ -24,8 +25,10 @@ struct pci_channel { | |||
24 | unsigned long mem_offset; | 25 | unsigned long mem_offset; |
25 | 26 | ||
26 | unsigned long reg_base; | 27 | unsigned long reg_base; |
27 | |||
28 | unsigned long io_map_base; | 28 | unsigned long io_map_base; |
29 | |||
30 | unsigned int index; | ||
31 | unsigned int need_domain_info; | ||
29 | }; | 32 | }; |
30 | 33 | ||
31 | extern void register_pci_controller(struct pci_channel *hose); | 34 | extern void register_pci_controller(struct pci_channel *hose); |
@@ -108,6 +111,14 @@ extern void pcibios_resource_to_bus(struct pci_dev *dev, | |||
108 | extern void pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res, | 111 | extern void pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res, |
109 | struct pci_bus_region *region); | 112 | struct pci_bus_region *region); |
110 | 113 | ||
114 | #define pci_domain_nr(bus) ((struct pci_channel *)(bus)->sysdata)->index | ||
115 | |||
116 | static inline int pci_proc_domain(struct pci_bus *bus) | ||
117 | { | ||
118 | struct pci_channel *hose = bus->sysdata; | ||
119 | return hose->need_domain_info; | ||
120 | } | ||
121 | |||
111 | /* Chances are this interrupt is wired PC-style ... */ | 122 | /* Chances are this interrupt is wired PC-style ... */ |
112 | static inline int pci_get_legacy_ide_irq(struct pci_dev *dev, int channel) | 123 | static inline int pci_get_legacy_ide_irq(struct pci_dev *dev, int channel) |
113 | { | 124 | { |