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>
This commit is contained in:
parent
376f70acfe
commit
9cf0105da5
@ -135,6 +135,8 @@ struct pci_mmcfg_region {
|
||||
|
||||
extern int __init pci_mmcfg_arch_init(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 list_head pci_mmcfg_list;
|
||||
|
@ -141,3 +141,18 @@ int __init pci_mmcfg_arch_init(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 = {
|
||||
.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;
|
||||
u64 start, size;
|
||||
@ -114,16 +114,14 @@ int __init pci_mmcfg_arch_init(void)
|
||||
{
|
||||
struct pci_mmcfg_region *cfg;
|
||||
|
||||
list_for_each_entry(cfg, &pci_mmcfg_list, list) {
|
||||
cfg->virt = mcfg_ioremap(cfg);
|
||||
if (!cfg->virt) {
|
||||
printk(KERN_ERR PREFIX "can't map MMCONFIG at %pR\n",
|
||||
&cfg->res);
|
||||
list_for_each_entry(cfg, &pci_mmcfg_list, list)
|
||||
if (pci_mmcfg_arch_map(cfg)) {
|
||||
pci_mmcfg_arch_free();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
raw_pci_ext_ops = &pci_mmcfg;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -131,10 +129,26 @@ void __init pci_mmcfg_arch_free(void)
|
||||
{
|
||||
struct pci_mmcfg_region *cfg;
|
||||
|
||||
list_for_each_entry(cfg, &pci_mmcfg_list, list) {
|
||||
if (cfg->virt) {
|
||||
iounmap(cfg->virt + PCI_MMCFG_BUS_OFFSET(cfg->start_bus));
|
||||
cfg->virt = NULL;
|
||||
}
|
||||
list_for_each_entry(cfg, &pci_mmcfg_list, list)
|
||||
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));
|
||||
cfg->virt = NULL;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user