Commit 9cf0105d authored by Jiang Liu's avatar Jiang Liu Committed by Bjorn Helgaas

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: default avatarYinghai Lu <yinghai@kernel.org>
Signed-off-by: default avatarJiang Liu <liuj97@gmail.com>
Signed-off-by: default avatarBjorn Helgaas <bhelgaas@google.com>
parent 376f70ac
...@@ -135,6 +135,8 @@ struct pci_mmcfg_region { ...@@ -135,6 +135,8 @@ struct pci_mmcfg_region {
extern int __init pci_mmcfg_arch_init(void); extern int __init pci_mmcfg_arch_init(void);
extern void __init pci_mmcfg_arch_free(void); extern void __init pci_mmcfg_arch_free(void);
extern int __devinit pci_mmcfg_arch_map(struct pci_mmcfg_region *cfg);
extern void pci_mmcfg_arch_unmap(struct pci_mmcfg_region *cfg);
extern struct pci_mmcfg_region *pci_mmconfig_lookup(int segment, int bus); extern struct pci_mmcfg_region *pci_mmconfig_lookup(int segment, int bus);
extern struct list_head pci_mmcfg_list; extern struct list_head pci_mmcfg_list;
......
...@@ -141,3 +141,18 @@ int __init pci_mmcfg_arch_init(void) ...@@ -141,3 +141,18 @@ int __init pci_mmcfg_arch_init(void)
void __init pci_mmcfg_arch_free(void) void __init pci_mmcfg_arch_free(void)
{ {
} }
int __devinit pci_mmcfg_arch_map(struct pci_mmcfg_region *cfg)
{
return 0;
}
void pci_mmcfg_arch_unmap(struct pci_mmcfg_region *cfg)
{
unsigned long flags;
/* Invalidate the cached mmcfg map entry. */
raw_spin_lock_irqsave(&pci_config_lock, flags);
mmcfg_last_accessed_device = 0;
raw_spin_unlock_irqrestore(&pci_config_lock, flags);
}
...@@ -95,7 +95,7 @@ static const struct pci_raw_ops pci_mmcfg = { ...@@ -95,7 +95,7 @@ static const struct pci_raw_ops pci_mmcfg = {
.write = pci_mmcfg_write, .write = pci_mmcfg_write,
}; };
static void __iomem * __init mcfg_ioremap(struct pci_mmcfg_region *cfg) static void __iomem * __devinit mcfg_ioremap(struct pci_mmcfg_region *cfg)
{ {
void __iomem *addr; void __iomem *addr;
u64 start, size; u64 start, size;
...@@ -114,16 +114,14 @@ int __init pci_mmcfg_arch_init(void) ...@@ -114,16 +114,14 @@ int __init pci_mmcfg_arch_init(void)
{ {
struct pci_mmcfg_region *cfg; struct pci_mmcfg_region *cfg;
list_for_each_entry(cfg, &pci_mmcfg_list, list) { list_for_each_entry(cfg, &pci_mmcfg_list, list)
cfg->virt = mcfg_ioremap(cfg); if (pci_mmcfg_arch_map(cfg)) {
if (!cfg->virt) {
printk(KERN_ERR PREFIX "can't map MMCONFIG at %pR\n",
&cfg->res);
pci_mmcfg_arch_free(); pci_mmcfg_arch_free();
return 0; return 0;
} }
}
raw_pci_ext_ops = &pci_mmcfg; raw_pci_ext_ops = &pci_mmcfg;
return 1; return 1;
} }
...@@ -131,10 +129,26 @@ void __init pci_mmcfg_arch_free(void) ...@@ -131,10 +129,26 @@ void __init pci_mmcfg_arch_free(void)
{ {
struct pci_mmcfg_region *cfg; struct pci_mmcfg_region *cfg;
list_for_each_entry(cfg, &pci_mmcfg_list, list) { list_for_each_entry(cfg, &pci_mmcfg_list, list)
if (cfg->virt) { pci_mmcfg_arch_unmap(cfg);
}
int __devinit pci_mmcfg_arch_map(struct pci_mmcfg_region *cfg)
{
cfg->virt = mcfg_ioremap(cfg);
if (!cfg->virt) {
printk(KERN_ERR PREFIX "can't map MMCONFIG at %pR\n",
&cfg->res);
return -ENOMEM;
}
return 0;
}
void pci_mmcfg_arch_unmap(struct pci_mmcfg_region *cfg)
{
if (cfg && cfg->virt) {
iounmap(cfg->virt + PCI_MMCFG_BUS_OFFSET(cfg->start_bus)); iounmap(cfg->virt + PCI_MMCFG_BUS_OFFSET(cfg->start_bus));
cfg->virt = NULL; cfg->virt = NULL;
} }
}
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment