diff options
Diffstat (limited to 'arch/x86/pci/mmconfig_64.c')
-rw-r--r-- | arch/x86/pci/mmconfig_64.c | 38 |
1 files changed, 26 insertions, 12 deletions
diff --git a/arch/x86/pci/mmconfig_64.c b/arch/x86/pci/mmconfig_64.c index acc48c5b6863..ebefea5107a7 100644 --- a/arch/x86/pci/mmconfig_64.c +++ b/arch/x86/pci/mmconfig_64.c | |||
@@ -95,7 +95,7 @@ static const struct pci_raw_ops pci_mmcfg = { | |||
95 | .write = pci_mmcfg_write, | 95 | .write = pci_mmcfg_write, |
96 | }; | 96 | }; |
97 | 97 | ||
98 | static void __iomem * __init mcfg_ioremap(struct pci_mmcfg_region *cfg) | 98 | static void __iomem * __devinit mcfg_ioremap(struct pci_mmcfg_region *cfg) |
99 | { | 99 | { |
100 | void __iomem *addr; | 100 | void __iomem *addr; |
101 | u64 start, size; | 101 | u64 start, size; |
@@ -114,16 +114,14 @@ int __init pci_mmcfg_arch_init(void) | |||
114 | { | 114 | { |
115 | struct pci_mmcfg_region *cfg; | 115 | struct pci_mmcfg_region *cfg; |
116 | 116 | ||
117 | list_for_each_entry(cfg, &pci_mmcfg_list, list) { | 117 | list_for_each_entry(cfg, &pci_mmcfg_list, list) |
118 | cfg->virt = mcfg_ioremap(cfg); | 118 | if (pci_mmcfg_arch_map(cfg)) { |
119 | if (!cfg->virt) { | ||
120 | printk(KERN_ERR PREFIX "can't map MMCONFIG at %pR\n", | ||
121 | &cfg->res); | ||
122 | pci_mmcfg_arch_free(); | 119 | pci_mmcfg_arch_free(); |
123 | return 0; | 120 | return 0; |
124 | } | 121 | } |
125 | } | 122 | |
126 | raw_pci_ext_ops = &pci_mmcfg; | 123 | raw_pci_ext_ops = &pci_mmcfg; |
124 | |||
127 | return 1; | 125 | return 1; |
128 | } | 126 | } |
129 | 127 | ||
@@ -131,10 +129,26 @@ void __init pci_mmcfg_arch_free(void) | |||
131 | { | 129 | { |
132 | struct pci_mmcfg_region *cfg; | 130 | struct pci_mmcfg_region *cfg; |
133 | 131 | ||
134 | list_for_each_entry(cfg, &pci_mmcfg_list, list) { | 132 | list_for_each_entry(cfg, &pci_mmcfg_list, list) |
135 | if (cfg->virt) { | 133 | pci_mmcfg_arch_unmap(cfg); |
136 | iounmap(cfg->virt + PCI_MMCFG_BUS_OFFSET(cfg->start_bus)); | 134 | } |
137 | cfg->virt = NULL; | 135 | |
138 | } | 136 | int __devinit pci_mmcfg_arch_map(struct pci_mmcfg_region *cfg) |
137 | { | ||
138 | cfg->virt = mcfg_ioremap(cfg); | ||
139 | if (!cfg->virt) { | ||
140 | printk(KERN_ERR PREFIX "can't map MMCONFIG at %pR\n", | ||
141 | &cfg->res); | ||
142 | return -ENOMEM; | ||
143 | } | ||
144 | |||
145 | return 0; | ||
146 | } | ||
147 | |||
148 | void pci_mmcfg_arch_unmap(struct pci_mmcfg_region *cfg) | ||
149 | { | ||
150 | if (cfg && cfg->virt) { | ||
151 | iounmap(cfg->virt + PCI_MMCFG_BUS_OFFSET(cfg->start_bus)); | ||
152 | cfg->virt = NULL; | ||
139 | } | 153 | } |
140 | } | 154 | } |