Commit 9cf0105da5a315677d8f91043fb87fdade0d8b39
Committed by
Bjorn Helgaas
1 parent
376f70acfe
Exists in
smarc-l5.0.0_1.0.0-ga
and in
5 other branches
x86/PCI: introduce pci_mmcfg_arch_map()/pci_mmcfg_arch_unmap()
Introduce pci_mmcfg_arch_map()/pci_mmcfg_arch_unmap(), which will be used when supporting PCI root bridge hotplug. Reviewed-by: Yinghai Lu <yinghai@kernel.org> Signed-off-by: Jiang Liu <liuj97@gmail.com> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Showing 3 changed files with 43 additions and 12 deletions Side-by-side Diff
arch/x86/include/asm/pci_x86.h
... | ... | @@ -135,6 +135,8 @@ |
135 | 135 | |
136 | 136 | extern int __init pci_mmcfg_arch_init(void); |
137 | 137 | extern void __init pci_mmcfg_arch_free(void); |
138 | +extern int __devinit pci_mmcfg_arch_map(struct pci_mmcfg_region *cfg); | |
139 | +extern void pci_mmcfg_arch_unmap(struct pci_mmcfg_region *cfg); | |
138 | 140 | extern struct pci_mmcfg_region *pci_mmconfig_lookup(int segment, int bus); |
139 | 141 | |
140 | 142 | extern struct list_head pci_mmcfg_list; |
arch/x86/pci/mmconfig_32.c
... | ... | @@ -141,4 +141,19 @@ |
141 | 141 | void __init pci_mmcfg_arch_free(void) |
142 | 142 | { |
143 | 143 | } |
144 | + | |
145 | +int __devinit pci_mmcfg_arch_map(struct pci_mmcfg_region *cfg) | |
146 | +{ | |
147 | + return 0; | |
148 | +} | |
149 | + | |
150 | +void pci_mmcfg_arch_unmap(struct pci_mmcfg_region *cfg) | |
151 | +{ | |
152 | + unsigned long flags; | |
153 | + | |
154 | + /* Invalidate the cached mmcfg map entry. */ | |
155 | + raw_spin_lock_irqsave(&pci_config_lock, flags); | |
156 | + mmcfg_last_accessed_device = 0; | |
157 | + raw_spin_unlock_irqrestore(&pci_config_lock, flags); | |
158 | +} |
arch/x86/pci/mmconfig_64.c
... | ... | @@ -95,7 +95,7 @@ |
95 | 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 | 100 | void __iomem *addr; |
101 | 101 | u64 start, size; |
102 | 102 | |
103 | 103 | |
... | ... | @@ -114,16 +114,14 @@ |
114 | 114 | { |
115 | 115 | struct pci_mmcfg_region *cfg; |
116 | 116 | |
117 | - list_for_each_entry(cfg, &pci_mmcfg_list, list) { | |
118 | - cfg->virt = mcfg_ioremap(cfg); | |
119 | - if (!cfg->virt) { | |
120 | - printk(KERN_ERR PREFIX "can't map MMCONFIG at %pR\n", | |
121 | - &cfg->res); | |
117 | + list_for_each_entry(cfg, &pci_mmcfg_list, list) | |
118 | + if (pci_mmcfg_arch_map(cfg)) { | |
122 | 119 | pci_mmcfg_arch_free(); |
123 | 120 | return 0; |
124 | 121 | } |
125 | - } | |
122 | + | |
126 | 123 | raw_pci_ext_ops = &pci_mmcfg; |
124 | + | |
127 | 125 | return 1; |
128 | 126 | } |
129 | 127 | |
... | ... | @@ -131,11 +129,27 @@ |
131 | 129 | { |
132 | 130 | struct pci_mmcfg_region *cfg; |
133 | 131 | |
134 | - list_for_each_entry(cfg, &pci_mmcfg_list, list) { | |
135 | - if (cfg->virt) { | |
136 | - iounmap(cfg->virt + PCI_MMCFG_BUS_OFFSET(cfg->start_bus)); | |
137 | - cfg->virt = NULL; | |
138 | - } | |
132 | + list_for_each_entry(cfg, &pci_mmcfg_list, list) | |
133 | + pci_mmcfg_arch_unmap(cfg); | |
134 | +} | |
135 | + | |
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 | } |