aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/pci/mmconfig_64.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86/pci/mmconfig_64.c')
-rw-r--r--arch/x86/pci/mmconfig_64.c38
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
98static void __iomem * __init mcfg_ioremap(struct pci_mmcfg_region *cfg) 98static 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 } 136int __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
148void 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}