Commit 9cf0105da5a315677d8f91043fb87fdade0d8b39

Authored by Jiang Liu
Committed by Bjorn Helgaas
1 parent 376f70acfe

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 }