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

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
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -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;
+15 −0
Original line number Diff line number Diff line
@@ -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);
}
+26 −12
Original line number Diff line number Diff line
@@ -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) {
	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;
	}
}
}