diff mbox

[v9,04/11] x86/PCI: introduce pci_mmcfg_arch_map()/pci_mmcfg_arch_unmap()

Message ID 1340271423-4352-5-git-send-email-jiang.liu@huawei.com
State Superseded
Headers show

Commit Message

Jiang Liu June 21, 2012, 9:36 a.m. UTC
Introduce pci_mmcfg_arch_map()/pci_mmcfg_arch_unmap(), which will be used
when supporting PCI root bridge hotplug.

Signed-off-by: Jiang Liu <liuj97@gmail.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
---
 arch/x86/include/asm/pci_x86.h |    2 ++
 arch/x86/pci/mmconfig_32.c     |   15 +++++++++++++++
 arch/x86/pci/mmconfig_64.c     |   22 +++++++++++++++++++++-
 3 files changed, 38 insertions(+), 1 deletions(-)

Comments

Yinghai Lu June 21, 2012, 9:25 p.m. UTC | #1
On Thu, Jun 21, 2012 at 2:36 AM, Jiang Liu <jiang.liu@huawei.com> wrote:
> Introduce pci_mmcfg_arch_map()/pci_mmcfg_arch_unmap(), which will be used
> when supporting PCI root bridge hotplug.
>
> Signed-off-by: Jiang Liu <liuj97@gmail.com>
> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
> ---
>  arch/x86/include/asm/pci_x86.h |    2 ++
>  arch/x86/pci/mmconfig_32.c     |   15 +++++++++++++++
>  arch/x86/pci/mmconfig_64.c     |   22 +++++++++++++++++++++-
>  3 files changed, 38 insertions(+), 1 deletions(-)
>
> diff --git a/arch/x86/include/asm/pci_x86.h b/arch/x86/include/asm/pci_x86.h
> index b3a5317..df898ce 100644
> --- a/arch/x86/include/asm/pci_x86.h
> +++ b/arch/x86/include/asm/pci_x86.h
> @@ -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;
> diff --git a/arch/x86/pci/mmconfig_32.c b/arch/x86/pci/mmconfig_32.c
> index 5dad04a..a22785d 100644
> --- a/arch/x86/pci/mmconfig_32.c
> +++ b/arch/x86/pci/mmconfig_32.c
> @@ -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);
> +}
> diff --git a/arch/x86/pci/mmconfig_64.c b/arch/x86/pci/mmconfig_64.c
> index acc48c5..4e05779 100644
> --- a/arch/x86/pci/mmconfig_64.c
> +++ b/arch/x86/pci/mmconfig_64.c
> @@ -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;
> @@ -138,3 +138,23 @@ void __init pci_mmcfg_arch_free(void)
>                }
>        }
>  }
> +
> +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;
> +       }
> +}

Can you merge pci_mmcfg_arch_map/unmap with pci_mmcfg_arch_init/free?

at least init/free could call map/unmap.

Thanks

Yinghai
--
To unsubscribe from this list: send the line "unsubscribe linux-pci" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/arch/x86/include/asm/pci_x86.h b/arch/x86/include/asm/pci_x86.h
index b3a5317..df898ce 100644
--- a/arch/x86/include/asm/pci_x86.h
+++ b/arch/x86/include/asm/pci_x86.h
@@ -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;
diff --git a/arch/x86/pci/mmconfig_32.c b/arch/x86/pci/mmconfig_32.c
index 5dad04a..a22785d 100644
--- a/arch/x86/pci/mmconfig_32.c
+++ b/arch/x86/pci/mmconfig_32.c
@@ -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);
+}
diff --git a/arch/x86/pci/mmconfig_64.c b/arch/x86/pci/mmconfig_64.c
index acc48c5..4e05779 100644
--- a/arch/x86/pci/mmconfig_64.c
+++ b/arch/x86/pci/mmconfig_64.c
@@ -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;
@@ -138,3 +138,23 @@  void __init pci_mmcfg_arch_free(void)
 		}
 	}
 }
+
+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;
+	}
+}