diff options
author | Bjorn Helgaas <bjorn.helgaas@hp.com> | 2009-11-13 19:35:04 -0500 |
---|---|---|
committer | Jesse Barnes <jbarnes@virtuousgeek.org> | 2009-11-24 18:30:36 -0500 |
commit | f6e1d8cc38b3776038fb15d3acc82ed8bb552f82 (patch) | |
tree | d6ff3745b8f3843bad4cf284e653e38ba3b0a693 /arch | |
parent | 8c57786ad3d921713c7ad8e44132aa537a1d0fec (diff) |
x86/PCI: MMCONFIG: add lookup function
This patch factors out the search for an MMCONFIG region, which was
previously implemented in both mmconfig_32 and mmconfig_64. No functional
change.
Reviewed-by: Yinghai Lu <yinghai@kernel.org>
Signed-off-by: Bjorn Helgaas <bjorn.helgaas@hp.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/x86/include/asm/pci_x86.h | 1 | ||||
-rw-r--r-- | arch/x86/pci/mmconfig-shared.c | 12 | ||||
-rw-r--r-- | arch/x86/pci/mmconfig_32.c | 11 | ||||
-rw-r--r-- | arch/x86/pci/mmconfig_64.c | 23 |
4 files changed, 20 insertions, 27 deletions
diff --git a/arch/x86/include/asm/pci_x86.h b/arch/x86/include/asm/pci_x86.h index 0b7c316a70c3..b4bf9a942ed0 100644 --- a/arch/x86/include/asm/pci_x86.h +++ b/arch/x86/include/asm/pci_x86.h | |||
@@ -134,6 +134,7 @@ struct pci_mmcfg_region { | |||
134 | 134 | ||
135 | extern int __init pci_mmcfg_arch_init(void); | 135 | extern int __init pci_mmcfg_arch_init(void); |
136 | extern void __init pci_mmcfg_arch_free(void); | 136 | extern void __init pci_mmcfg_arch_free(void); |
137 | extern struct pci_mmcfg_region *pci_mmconfig_lookup(int segment, int bus); | ||
137 | 138 | ||
138 | extern struct list_head pci_mmcfg_list; | 139 | extern struct list_head pci_mmcfg_list; |
139 | 140 | ||
diff --git a/arch/x86/pci/mmconfig-shared.c b/arch/x86/pci/mmconfig-shared.c index 71d69b88fa33..b19d1e54201e 100644 --- a/arch/x86/pci/mmconfig-shared.c +++ b/arch/x86/pci/mmconfig-shared.c | |||
@@ -97,6 +97,18 @@ static __init struct pci_mmcfg_region *pci_mmconfig_add(int segment, int start, | |||
97 | return new; | 97 | return new; |
98 | } | 98 | } |
99 | 99 | ||
100 | struct pci_mmcfg_region *pci_mmconfig_lookup(int segment, int bus) | ||
101 | { | ||
102 | struct pci_mmcfg_region *cfg; | ||
103 | |||
104 | list_for_each_entry(cfg, &pci_mmcfg_list, list) | ||
105 | if (cfg->segment == segment && | ||
106 | cfg->start_bus <= bus && bus <= cfg->end_bus) | ||
107 | return cfg; | ||
108 | |||
109 | return NULL; | ||
110 | } | ||
111 | |||
100 | static const char __init *pci_mmcfg_e7520(void) | 112 | static const char __init *pci_mmcfg_e7520(void) |
101 | { | 113 | { |
102 | u32 win; | 114 | u32 win; |
diff --git a/arch/x86/pci/mmconfig_32.c b/arch/x86/pci/mmconfig_32.c index c04523e09649..90d5fd476ed4 100644 --- a/arch/x86/pci/mmconfig_32.c +++ b/arch/x86/pci/mmconfig_32.c | |||
@@ -27,15 +27,10 @@ static int mmcfg_last_accessed_cpu; | |||
27 | */ | 27 | */ |
28 | static u32 get_base_addr(unsigned int seg, int bus, unsigned devfn) | 28 | static u32 get_base_addr(unsigned int seg, int bus, unsigned devfn) |
29 | { | 29 | { |
30 | struct pci_mmcfg_region *cfg; | 30 | struct pci_mmcfg_region *cfg = pci_mmconfig_lookup(seg, bus); |
31 | 31 | ||
32 | list_for_each_entry(cfg, &pci_mmcfg_list, list) | 32 | if (cfg) |
33 | if (cfg->segment == seg && | 33 | return cfg->address; |
34 | (cfg->start_bus <= bus) && | ||
35 | (cfg->end_bus >= bus)) | ||
36 | return cfg->address; | ||
37 | |||
38 | /* Fall back to type 0 */ | ||
39 | return 0; | 34 | return 0; |
40 | } | 35 | } |
41 | 36 | ||
diff --git a/arch/x86/pci/mmconfig_64.c b/arch/x86/pci/mmconfig_64.c index cfa6cdb6d262..e783841bd1d7 100644 --- a/arch/x86/pci/mmconfig_64.c +++ b/arch/x86/pci/mmconfig_64.c | |||
@@ -14,28 +14,13 @@ | |||
14 | 14 | ||
15 | #define PREFIX "PCI: " | 15 | #define PREFIX "PCI: " |
16 | 16 | ||
17 | static char __iomem *get_virt(unsigned int seg, unsigned bus) | ||
18 | { | ||
19 | struct pci_mmcfg_region *cfg; | ||
20 | |||
21 | list_for_each_entry(cfg, &pci_mmcfg_list, list) | ||
22 | if (cfg->segment == seg && | ||
23 | (cfg->start_bus <= bus) && | ||
24 | (cfg->end_bus >= bus)) | ||
25 | return cfg->virt; | ||
26 | |||
27 | /* Fall back to type 0 */ | ||
28 | return NULL; | ||
29 | } | ||
30 | |||
31 | static char __iomem *pci_dev_base(unsigned int seg, unsigned int bus, unsigned int devfn) | 17 | static char __iomem *pci_dev_base(unsigned int seg, unsigned int bus, unsigned int devfn) |
32 | { | 18 | { |
33 | char __iomem *addr; | 19 | struct pci_mmcfg_region *cfg = pci_mmconfig_lookup(seg, bus); |
34 | 20 | ||
35 | addr = get_virt(seg, bus); | 21 | if (cfg && cfg->virt) |
36 | if (!addr) | 22 | return cfg->virt + (PCI_MMCFG_BUS_OFFSET(bus) | (devfn << 12)); |
37 | return NULL; | 23 | return NULL; |
38 | return addr + (PCI_MMCFG_BUS_OFFSET(bus) | (devfn << 12)); | ||
39 | } | 24 | } |
40 | 25 | ||
41 | static int pci_mmcfg_read(unsigned int seg, unsigned int bus, | 26 | static int pci_mmcfg_read(unsigned int seg, unsigned int bus, |