All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v4 0/9] PCI: MMCONFIG clean up
@ 2015-03-11 14:12 ` Tomasz Nowicki
  0 siblings, 0 replies; 38+ messages in thread
From: Tomasz Nowicki @ 2015-03-11 14:12 UTC (permalink / raw)
  To: bhelgaas, wangyijing, arnd, hanjun.guo, Liviu.Dudau, tglx, mingo,
	hpa, rjw, al.stone
  Cc: linux-arm-kernel, linux-kernel, x86, linux-pci, linux-acpi,
	linaro-acpi, Tomasz Nowicki

MCFG ACPI table and PCI ECAM standard have no arch dependencies so it can be
used across all architectures. Currently MMCONFIG related code resides in
arch/x86 directories. This patch set is going to isolate non-architecture
specific code and make it accessible for all architectures.

v3 -> v4 changes:
- bug fixes after kbuild test robot report
    - add asm/io.h header for ecam.c
    - rename mmcfg -> ecam for drivers/xen/pci.c and arch/x86/pci/numachip.c
- rework Kconfig logic

v2 -> v3 changes:
- rebase patch set v2 to v4.0-rc1

v1 -> v2 changes:
- use generic readb/readw etc. accessors instead of AMD Fam10h workaround
- separate ACPI and ECAM code
- improve ECAM code naming

Tomasz Nowicki (9):
  x86, pci: Clean up comment about buggy MMIO config space access for
    AMD Fam10h CPUs.
  x86, pci: Abstract PCI config accessors and use AMD Fam10h workaround
    exclusively.
  x86, pci: Reorder logic of pci_mmconfig_insert() function
  x86, pci, acpi: Move arch-agnostic MMCONFIG (aka ECAM) and ACPI code
    out of arch/x86/ directory
  pci, acpi, mcfg: Provide generic implementation of MCFG code
    initialization.
  x86, pci: mmconfig_{32,64}.c code refactoring - remove code
    duplication.
  x86, pci, ecam: mmconfig_64.c becomes default implementation for ECAM
    driver.
  pci, acpi, mcfg: Share ACPI PCI config space accessors.
  pci, ecam: Improve naming for ecam.c content and areas where it is
    used.

 arch/x86/Kconfig               |   4 +
 arch/x86/include/asm/pci_x86.h |  34 +---
 arch/x86/pci/Makefile          |   5 +-
 arch/x86/pci/acpi.c            |   3 +-
 arch/x86/pci/mmconfig-shared.c | 346 +++++++++++----------------------------
 arch/x86/pci/mmconfig_32.c     |  47 ++----
 arch/x86/pci/mmconfig_64.c     | 153 ------------------
 arch/x86/pci/numachip.c        |  29 +---
 drivers/acpi/Makefile          |   1 +
 drivers/acpi/mcfg.c            | 121 ++++++++++++++
 drivers/pci/Kconfig            |  10 ++
 drivers/pci/Makefile           |   5 +
 drivers/pci/ecam.c             | 358 +++++++++++++++++++++++++++++++++++++++++
 drivers/xen/pci.c              |   7 +-
 include/linux/ecam.h           |  56 +++++++
 15 files changed, 679 insertions(+), 500 deletions(-)
 delete mode 100644 arch/x86/pci/mmconfig_64.c
 create mode 100644 drivers/acpi/mcfg.c
 create mode 100644 drivers/pci/ecam.c
 create mode 100644 include/linux/ecam.h

-- 
1.9.1

^ permalink raw reply	[flat|nested] 38+ messages in thread

* [PATCH v4 0/9] PCI: MMCONFIG clean up
@ 2015-03-11 14:12 ` Tomasz Nowicki
  0 siblings, 0 replies; 38+ messages in thread
From: Tomasz Nowicki @ 2015-03-11 14:12 UTC (permalink / raw)
  To: linux-arm-kernel

MCFG ACPI table and PCI ECAM standard have no arch dependencies so it can be
used across all architectures. Currently MMCONFIG related code resides in
arch/x86 directories. This patch set is going to isolate non-architecture
specific code and make it accessible for all architectures.

v3 -> v4 changes:
- bug fixes after kbuild test robot report
    - add asm/io.h header for ecam.c
    - rename mmcfg -> ecam for drivers/xen/pci.c and arch/x86/pci/numachip.c
- rework Kconfig logic

v2 -> v3 changes:
- rebase patch set v2 to v4.0-rc1

v1 -> v2 changes:
- use generic readb/readw etc. accessors instead of AMD Fam10h workaround
- separate ACPI and ECAM code
- improve ECAM code naming

Tomasz Nowicki (9):
  x86, pci: Clean up comment about buggy MMIO config space access for
    AMD Fam10h CPUs.
  x86, pci: Abstract PCI config accessors and use AMD Fam10h workaround
    exclusively.
  x86, pci: Reorder logic of pci_mmconfig_insert() function
  x86, pci, acpi: Move arch-agnostic MMCONFIG (aka ECAM) and ACPI code
    out of arch/x86/ directory
  pci, acpi, mcfg: Provide generic implementation of MCFG code
    initialization.
  x86, pci: mmconfig_{32,64}.c code refactoring - remove code
    duplication.
  x86, pci, ecam: mmconfig_64.c becomes default implementation for ECAM
    driver.
  pci, acpi, mcfg: Share ACPI PCI config space accessors.
  pci, ecam: Improve naming for ecam.c content and areas where it is
    used.

 arch/x86/Kconfig               |   4 +
 arch/x86/include/asm/pci_x86.h |  34 +---
 arch/x86/pci/Makefile          |   5 +-
 arch/x86/pci/acpi.c            |   3 +-
 arch/x86/pci/mmconfig-shared.c | 346 +++++++++++----------------------------
 arch/x86/pci/mmconfig_32.c     |  47 ++----
 arch/x86/pci/mmconfig_64.c     | 153 ------------------
 arch/x86/pci/numachip.c        |  29 +---
 drivers/acpi/Makefile          |   1 +
 drivers/acpi/mcfg.c            | 121 ++++++++++++++
 drivers/pci/Kconfig            |  10 ++
 drivers/pci/Makefile           |   5 +
 drivers/pci/ecam.c             | 358 +++++++++++++++++++++++++++++++++++++++++
 drivers/xen/pci.c              |   7 +-
 include/linux/ecam.h           |  56 +++++++
 15 files changed, 679 insertions(+), 500 deletions(-)
 delete mode 100644 arch/x86/pci/mmconfig_64.c
 create mode 100644 drivers/acpi/mcfg.c
 create mode 100644 drivers/pci/ecam.c
 create mode 100644 include/linux/ecam.h

-- 
1.9.1

^ permalink raw reply	[flat|nested] 38+ messages in thread

* [PATCH v4 1/9] x86, pci: Clean up comment about buggy MMIO config space access for AMD Fam10h CPUs.
  2015-03-11 14:12 ` Tomasz Nowicki
@ 2015-03-11 14:12   ` Tomasz Nowicki
  -1 siblings, 0 replies; 38+ messages in thread
From: Tomasz Nowicki @ 2015-03-11 14:12 UTC (permalink / raw)
  To: bhelgaas, wangyijing, arnd, hanjun.guo, Liviu.Dudau, tglx, mingo,
	hpa, rjw, al.stone
  Cc: linux-arm-kernel, linux-kernel, x86, linux-pci, linux-acpi,
	linaro-acpi, Tomasz Nowicki

- fix typo
- improve explanation
- add reference to the related document

Signed-off-by: Tomasz Nowicki <tomasz.nowicki@linaro.org>
---
 arch/x86/include/asm/pci_x86.h | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/arch/x86/include/asm/pci_x86.h b/arch/x86/include/asm/pci_x86.h
index fa1195d..d024f4d 100644
--- a/arch/x86/include/asm/pci_x86.h
+++ b/arch/x86/include/asm/pci_x86.h
@@ -152,10 +152,13 @@ extern struct list_head pci_mmcfg_list;
 
 /*
  * AMD Fam10h CPUs are buggy, and cannot access MMIO config space
- * on their northbrige except through the * %eax register. As such, you MUST
- * NOT use normal IOMEM accesses, you need to only use the magic mmio-config
+ * on their northbridge except through the * %eax register. As such, you MUST
+ * NOT use normal IOMEM accesses, you need to only use the magic mmio_config_*
  * accessor functions.
- * In fact just use pci_config_*, nothing else please.
+ *
+ * Please refer to the following doc:
+ * "BIOS and Kernel Developer's Guide (BKDG) For AMD Family 10h Processors",
+ * rev. 3.48, sec 2.11.1, "MMIO Configuration Coding Requirements".
  */
 static inline unsigned char mmio_config_readb(void __iomem *pos)
 {
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [PATCH v4 1/9] x86, pci: Clean up comment about buggy MMIO config space access for AMD Fam10h CPUs.
@ 2015-03-11 14:12   ` Tomasz Nowicki
  0 siblings, 0 replies; 38+ messages in thread
From: Tomasz Nowicki @ 2015-03-11 14:12 UTC (permalink / raw)
  To: linux-arm-kernel

- fix typo
- improve explanation
- add reference to the related document

Signed-off-by: Tomasz Nowicki <tomasz.nowicki@linaro.org>
---
 arch/x86/include/asm/pci_x86.h | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/arch/x86/include/asm/pci_x86.h b/arch/x86/include/asm/pci_x86.h
index fa1195d..d024f4d 100644
--- a/arch/x86/include/asm/pci_x86.h
+++ b/arch/x86/include/asm/pci_x86.h
@@ -152,10 +152,13 @@ extern struct list_head pci_mmcfg_list;
 
 /*
  * AMD Fam10h CPUs are buggy, and cannot access MMIO config space
- * on their northbrige except through the * %eax register. As such, you MUST
- * NOT use normal IOMEM accesses, you need to only use the magic mmio-config
+ * on their northbridge except through the * %eax register. As such, you MUST
+ * NOT use normal IOMEM accesses, you need to only use the magic mmio_config_*
  * accessor functions.
- * In fact just use pci_config_*, nothing else please.
+ *
+ * Please refer to the following doc:
+ * "BIOS and Kernel Developer's Guide (BKDG) For AMD Family 10h Processors",
+ * rev. 3.48, sec 2.11.1, "MMIO Configuration Coding Requirements".
  */
 static inline unsigned char mmio_config_readb(void __iomem *pos)
 {
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [PATCH v4 2/9] x86, pci: Abstract PCI config accessors and use AMD Fam10h workaround exclusively.
  2015-03-11 14:12 ` Tomasz Nowicki
@ 2015-03-11 14:12   ` Tomasz Nowicki
  -1 siblings, 0 replies; 38+ messages in thread
From: Tomasz Nowicki @ 2015-03-11 14:12 UTC (permalink / raw)
  To: bhelgaas, wangyijing, arnd, hanjun.guo, Liviu.Dudau, tglx, mingo,
	hpa, rjw, al.stone
  Cc: linux-arm-kernel, linux-kernel, x86, linux-pci, linux-acpi,
	linaro-acpi, Tomasz Nowicki

>From now on, readb()/writeb()/etc. generic calls are used as default
approach. Special MMIO accessors are registered for AMD Fam10h CPUs only.

Signed-off-by: Tomasz Nowicki <tomasz.nowicki@linaro.org>
---
 arch/x86/include/asm/pci_x86.h |   8 +++
 arch/x86/pci/mmconfig-shared.c | 114 +++++++++++++++++++++++++++++++++++++++++
 arch/x86/pci/mmconfig_32.c     |  24 +--------
 arch/x86/pci/mmconfig_64.c     |  24 +--------
 arch/x86/pci/numachip.c        |  24 +--------
 5 files changed, 128 insertions(+), 66 deletions(-)

diff --git a/arch/x86/include/asm/pci_x86.h b/arch/x86/include/asm/pci_x86.h
index d024f4d..c57c225 100644
--- a/arch/x86/include/asm/pci_x86.h
+++ b/arch/x86/include/asm/pci_x86.h
@@ -137,6 +137,11 @@ struct pci_mmcfg_region {
 	char name[PCI_MMCFG_RESOURCE_NAME_LEN];
 };
 
+struct pci_mmcfg_mmio_ops {
+	u32 (*read)(int len, void __iomem *addr);
+	void (*write)(int len, void __iomem *addr, u32 value);
+};
+
 extern int __init pci_mmcfg_arch_init(void);
 extern void __init pci_mmcfg_arch_free(void);
 extern int pci_mmcfg_arch_map(struct pci_mmcfg_region *cfg);
@@ -145,6 +150,9 @@ extern int pci_mmconfig_insert(struct device *dev, u16 seg, u8 start, u8 end,
 			       phys_addr_t addr);
 extern int pci_mmconfig_delete(u16 seg, u8 start, u8 end);
 extern struct pci_mmcfg_region *pci_mmconfig_lookup(int segment, int bus);
+extern u32 pci_mmio_read(int len, void __iomem *addr);
+extern void pci_mmio_write(int len, void __iomem *addr, u32 value);
+extern void pci_mmconfig_register_mmio(struct pci_mmcfg_mmio_ops *ops);
 
 extern struct list_head pci_mmcfg_list;
 
diff --git a/arch/x86/pci/mmconfig-shared.c b/arch/x86/pci/mmconfig-shared.c
index dd30b7e..8b3bc4f 100644
--- a/arch/x86/pci/mmconfig-shared.c
+++ b/arch/x86/pci/mmconfig-shared.c
@@ -31,6 +31,118 @@ static DEFINE_MUTEX(pci_mmcfg_lock);
 
 LIST_HEAD(pci_mmcfg_list);
 
+static u32
+pci_mmconfig_generic_read(int len, void __iomem *addr)
+{
+	u32 data = 0;
+
+	switch (len) {
+	case 1:
+		data = readb(addr);
+		break;
+	case 2:
+		data = readw(addr);
+		break;
+	case 4:
+		data = readl(addr);
+		break;
+	}
+
+	return data;
+}
+
+static void
+pci_mmconfig_generic_write(int len, void __iomem *addr, u32 value)
+{
+	switch (len) {
+	case 1:
+		writeb(value, addr);
+		break;
+	case 2:
+		writew(value, addr);
+		break;
+	case 4:
+		writel(value, addr);
+		break;
+	}
+}
+
+static struct pci_mmcfg_mmio_ops pci_mmcfg_mmio_default = {
+	.read = pci_mmconfig_generic_read,
+	.write = pci_mmconfig_generic_write,
+};
+
+static struct pci_mmcfg_mmio_ops *pci_mmcfg_mmio = &pci_mmcfg_mmio_default;
+
+static u32
+pci_mmconfig_amd_read(int len, void __iomem *addr)
+{
+	u32 data = 0;
+
+	switch (len) {
+	case 1:
+		data = mmio_config_readb(addr);
+		break;
+	case 2:
+		data = mmio_config_readw(addr);
+		break;
+	case 4:
+		data = mmio_config_readl(addr);
+		break;
+	}
+
+	return data;
+}
+
+static void
+pci_mmconfig_amd_write(int len, void __iomem *addr, u32 value)
+{
+	switch (len) {
+	case 1:
+		mmio_config_writeb(addr, value);
+		break;
+	case 2:
+		mmio_config_writew(addr, value);
+		break;
+	case 4:
+		mmio_config_writel(addr, value);
+		break;
+	}
+}
+
+static struct pci_mmcfg_mmio_ops pci_mmcfg_mmio_amd_fam10h = {
+	.read = pci_mmconfig_amd_read,
+	.write = pci_mmconfig_amd_write,
+};
+
+void
+pci_mmconfig_register_mmio(struct pci_mmcfg_mmio_ops *ops)
+{
+	pci_mmcfg_mmio = ops;
+}
+
+u32
+pci_mmio_read(int len, void __iomem *addr)
+{
+	if (!pci_mmcfg_mmio) {
+		pr_err("PCI config space has no accessors !");
+		return 0;
+	}
+
+	return pci_mmcfg_mmio->read(len, addr);
+}
+
+void
+pci_mmio_write(int len, void __iomem *addr, u32 value)
+{
+	if (!pci_mmcfg_mmio) {
+		pr_err("PCI config space has no accessors !");
+		return;
+	}
+
+	pci_mmcfg_mmio->write(len, addr, value);
+}
+
 static void __init pci_mmconfig_remove(struct pci_mmcfg_region *cfg)
 {
 	if (cfg->res.parent)
@@ -231,6 +343,8 @@ static const char *__init pci_mmcfg_amd_fam10h(void)
 			return NULL;
 		}
 
+	pci_mmconfig_register_mmio(&pci_mmcfg_mmio_amd_fam10h);
+
 	return "AMD Family 10h NB";
 }
 
diff --git a/arch/x86/pci/mmconfig_32.c b/arch/x86/pci/mmconfig_32.c
index 43984bc..4b3d025 100644
--- a/arch/x86/pci/mmconfig_32.c
+++ b/arch/x86/pci/mmconfig_32.c
@@ -71,17 +71,7 @@ err:		*value = -1;
 
 	pci_exp_set_dev_base(base, bus, devfn);
 
-	switch (len) {
-	case 1:
-		*value = mmio_config_readb(mmcfg_virt_addr + reg);
-		break;
-	case 2:
-		*value = mmio_config_readw(mmcfg_virt_addr + reg);
-		break;
-	case 4:
-		*value = mmio_config_readl(mmcfg_virt_addr + reg);
-		break;
-	}
+	*value = pci_mmio_read(len, mmcfg_virt_addr + reg);
 	raw_spin_unlock_irqrestore(&pci_config_lock, flags);
 	rcu_read_unlock();
 
@@ -108,17 +98,7 @@ static int pci_mmcfg_write(unsigned int seg, unsigned int bus,
 
 	pci_exp_set_dev_base(base, bus, devfn);
 
-	switch (len) {
-	case 1:
-		mmio_config_writeb(mmcfg_virt_addr + reg, value);
-		break;
-	case 2:
-		mmio_config_writew(mmcfg_virt_addr + reg, value);
-		break;
-	case 4:
-		mmio_config_writel(mmcfg_virt_addr + reg, value);
-		break;
-	}
+	pci_mmio_write(len, mmcfg_virt_addr + reg, value);
 	raw_spin_unlock_irqrestore(&pci_config_lock, flags);
 	rcu_read_unlock();
 
diff --git a/arch/x86/pci/mmconfig_64.c b/arch/x86/pci/mmconfig_64.c
index bea5249..032593d 100644
--- a/arch/x86/pci/mmconfig_64.c
+++ b/arch/x86/pci/mmconfig_64.c
@@ -42,17 +42,7 @@ err:		*value = -1;
 		goto err;
 	}
 
-	switch (len) {
-	case 1:
-		*value = mmio_config_readb(addr + reg);
-		break;
-	case 2:
-		*value = mmio_config_readw(addr + reg);
-		break;
-	case 4:
-		*value = mmio_config_readl(addr + reg);
-		break;
-	}
+	*value = pci_mmio_read(len, addr + reg);
 	rcu_read_unlock();
 
 	return 0;
@@ -74,17 +64,7 @@ static int pci_mmcfg_write(unsigned int seg, unsigned int bus,
 		return -EINVAL;
 	}
 
-	switch (len) {
-	case 1:
-		mmio_config_writeb(addr + reg, value);
-		break;
-	case 2:
-		mmio_config_writew(addr + reg, value);
-		break;
-	case 4:
-		mmio_config_writel(addr + reg, value);
-		break;
-	}
+	pci_mmio_write(len, addr + reg, value);
 	rcu_read_unlock();
 
 	return 0;
diff --git a/arch/x86/pci/numachip.c b/arch/x86/pci/numachip.c
index 2e565e6..5047e9b 100644
--- a/arch/x86/pci/numachip.c
+++ b/arch/x86/pci/numachip.c
@@ -51,17 +51,7 @@ err:		*value = -1;
 		goto err;
 	}
 
-	switch (len) {
-	case 1:
-		*value = mmio_config_readb(addr + reg);
-		break;
-	case 2:
-		*value = mmio_config_readw(addr + reg);
-		break;
-	case 4:
-		*value = mmio_config_readl(addr + reg);
-		break;
-	}
+	*value = pci_mmio_read(len, addr + reg);
 	rcu_read_unlock();
 
 	return 0;
@@ -87,17 +77,7 @@ static int pci_mmcfg_write_numachip(unsigned int seg, unsigned int bus,
 		return -EINVAL;
 	}
 
-	switch (len) {
-	case 1:
-		mmio_config_writeb(addr + reg, value);
-		break;
-	case 2:
-		mmio_config_writew(addr + reg, value);
-		break;
-	case 4:
-		mmio_config_writel(addr + reg, value);
-		break;
-	}
+	pci_mmio_write(len, addr + reg, value);
 	rcu_read_unlock();
 
 	return 0;
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [PATCH v4 2/9] x86, pci: Abstract PCI config accessors and use AMD Fam10h workaround exclusively.
@ 2015-03-11 14:12   ` Tomasz Nowicki
  0 siblings, 0 replies; 38+ messages in thread
From: Tomasz Nowicki @ 2015-03-11 14:12 UTC (permalink / raw)
  To: linux-arm-kernel

>From now on, readb()/writeb()/etc. generic calls are used as default
approach. Special MMIO accessors are registered for AMD Fam10h CPUs only.

Signed-off-by: Tomasz Nowicki <tomasz.nowicki@linaro.org>
---
 arch/x86/include/asm/pci_x86.h |   8 +++
 arch/x86/pci/mmconfig-shared.c | 114 +++++++++++++++++++++++++++++++++++++++++
 arch/x86/pci/mmconfig_32.c     |  24 +--------
 arch/x86/pci/mmconfig_64.c     |  24 +--------
 arch/x86/pci/numachip.c        |  24 +--------
 5 files changed, 128 insertions(+), 66 deletions(-)

diff --git a/arch/x86/include/asm/pci_x86.h b/arch/x86/include/asm/pci_x86.h
index d024f4d..c57c225 100644
--- a/arch/x86/include/asm/pci_x86.h
+++ b/arch/x86/include/asm/pci_x86.h
@@ -137,6 +137,11 @@ struct pci_mmcfg_region {
 	char name[PCI_MMCFG_RESOURCE_NAME_LEN];
 };
 
+struct pci_mmcfg_mmio_ops {
+	u32 (*read)(int len, void __iomem *addr);
+	void (*write)(int len, void __iomem *addr, u32 value);
+};
+
 extern int __init pci_mmcfg_arch_init(void);
 extern void __init pci_mmcfg_arch_free(void);
 extern int pci_mmcfg_arch_map(struct pci_mmcfg_region *cfg);
@@ -145,6 +150,9 @@ extern int pci_mmconfig_insert(struct device *dev, u16 seg, u8 start, u8 end,
 			       phys_addr_t addr);
 extern int pci_mmconfig_delete(u16 seg, u8 start, u8 end);
 extern struct pci_mmcfg_region *pci_mmconfig_lookup(int segment, int bus);
+extern u32 pci_mmio_read(int len, void __iomem *addr);
+extern void pci_mmio_write(int len, void __iomem *addr, u32 value);
+extern void pci_mmconfig_register_mmio(struct pci_mmcfg_mmio_ops *ops);
 
 extern struct list_head pci_mmcfg_list;
 
diff --git a/arch/x86/pci/mmconfig-shared.c b/arch/x86/pci/mmconfig-shared.c
index dd30b7e..8b3bc4f 100644
--- a/arch/x86/pci/mmconfig-shared.c
+++ b/arch/x86/pci/mmconfig-shared.c
@@ -31,6 +31,118 @@ static DEFINE_MUTEX(pci_mmcfg_lock);
 
 LIST_HEAD(pci_mmcfg_list);
 
+static u32
+pci_mmconfig_generic_read(int len, void __iomem *addr)
+{
+	u32 data = 0;
+
+	switch (len) {
+	case 1:
+		data = readb(addr);
+		break;
+	case 2:
+		data = readw(addr);
+		break;
+	case 4:
+		data = readl(addr);
+		break;
+	}
+
+	return data;
+}
+
+static void
+pci_mmconfig_generic_write(int len, void __iomem *addr, u32 value)
+{
+	switch (len) {
+	case 1:
+		writeb(value, addr);
+		break;
+	case 2:
+		writew(value, addr);
+		break;
+	case 4:
+		writel(value, addr);
+		break;
+	}
+}
+
+static struct pci_mmcfg_mmio_ops pci_mmcfg_mmio_default = {
+	.read = pci_mmconfig_generic_read,
+	.write = pci_mmconfig_generic_write,
+};
+
+static struct pci_mmcfg_mmio_ops *pci_mmcfg_mmio = &pci_mmcfg_mmio_default;
+
+static u32
+pci_mmconfig_amd_read(int len, void __iomem *addr)
+{
+	u32 data = 0;
+
+	switch (len) {
+	case 1:
+		data = mmio_config_readb(addr);
+		break;
+	case 2:
+		data = mmio_config_readw(addr);
+		break;
+	case 4:
+		data = mmio_config_readl(addr);
+		break;
+	}
+
+	return data;
+}
+
+static void
+pci_mmconfig_amd_write(int len, void __iomem *addr, u32 value)
+{
+	switch (len) {
+	case 1:
+		mmio_config_writeb(addr, value);
+		break;
+	case 2:
+		mmio_config_writew(addr, value);
+		break;
+	case 4:
+		mmio_config_writel(addr, value);
+		break;
+	}
+}
+
+static struct pci_mmcfg_mmio_ops pci_mmcfg_mmio_amd_fam10h = {
+	.read = pci_mmconfig_amd_read,
+	.write = pci_mmconfig_amd_write,
+};
+
+void
+pci_mmconfig_register_mmio(struct pci_mmcfg_mmio_ops *ops)
+{
+	pci_mmcfg_mmio = ops;
+}
+
+u32
+pci_mmio_read(int len, void __iomem *addr)
+{
+	if (!pci_mmcfg_mmio) {
+		pr_err("PCI config space has no accessors !");
+		return 0;
+	}
+
+	return pci_mmcfg_mmio->read(len, addr);
+}
+
+void
+pci_mmio_write(int len, void __iomem *addr, u32 value)
+{
+	if (!pci_mmcfg_mmio) {
+		pr_err("PCI config space has no accessors !");
+		return;
+	}
+
+	pci_mmcfg_mmio->write(len, addr, value);
+}
+
 static void __init pci_mmconfig_remove(struct pci_mmcfg_region *cfg)
 {
 	if (cfg->res.parent)
@@ -231,6 +343,8 @@ static const char *__init pci_mmcfg_amd_fam10h(void)
 			return NULL;
 		}
 
+	pci_mmconfig_register_mmio(&pci_mmcfg_mmio_amd_fam10h);
+
 	return "AMD Family 10h NB";
 }
 
diff --git a/arch/x86/pci/mmconfig_32.c b/arch/x86/pci/mmconfig_32.c
index 43984bc..4b3d025 100644
--- a/arch/x86/pci/mmconfig_32.c
+++ b/arch/x86/pci/mmconfig_32.c
@@ -71,17 +71,7 @@ err:		*value = -1;
 
 	pci_exp_set_dev_base(base, bus, devfn);
 
-	switch (len) {
-	case 1:
-		*value = mmio_config_readb(mmcfg_virt_addr + reg);
-		break;
-	case 2:
-		*value = mmio_config_readw(mmcfg_virt_addr + reg);
-		break;
-	case 4:
-		*value = mmio_config_readl(mmcfg_virt_addr + reg);
-		break;
-	}
+	*value = pci_mmio_read(len, mmcfg_virt_addr + reg);
 	raw_spin_unlock_irqrestore(&pci_config_lock, flags);
 	rcu_read_unlock();
 
@@ -108,17 +98,7 @@ static int pci_mmcfg_write(unsigned int seg, unsigned int bus,
 
 	pci_exp_set_dev_base(base, bus, devfn);
 
-	switch (len) {
-	case 1:
-		mmio_config_writeb(mmcfg_virt_addr + reg, value);
-		break;
-	case 2:
-		mmio_config_writew(mmcfg_virt_addr + reg, value);
-		break;
-	case 4:
-		mmio_config_writel(mmcfg_virt_addr + reg, value);
-		break;
-	}
+	pci_mmio_write(len, mmcfg_virt_addr + reg, value);
 	raw_spin_unlock_irqrestore(&pci_config_lock, flags);
 	rcu_read_unlock();
 
diff --git a/arch/x86/pci/mmconfig_64.c b/arch/x86/pci/mmconfig_64.c
index bea5249..032593d 100644
--- a/arch/x86/pci/mmconfig_64.c
+++ b/arch/x86/pci/mmconfig_64.c
@@ -42,17 +42,7 @@ err:		*value = -1;
 		goto err;
 	}
 
-	switch (len) {
-	case 1:
-		*value = mmio_config_readb(addr + reg);
-		break;
-	case 2:
-		*value = mmio_config_readw(addr + reg);
-		break;
-	case 4:
-		*value = mmio_config_readl(addr + reg);
-		break;
-	}
+	*value = pci_mmio_read(len, addr + reg);
 	rcu_read_unlock();
 
 	return 0;
@@ -74,17 +64,7 @@ static int pci_mmcfg_write(unsigned int seg, unsigned int bus,
 		return -EINVAL;
 	}
 
-	switch (len) {
-	case 1:
-		mmio_config_writeb(addr + reg, value);
-		break;
-	case 2:
-		mmio_config_writew(addr + reg, value);
-		break;
-	case 4:
-		mmio_config_writel(addr + reg, value);
-		break;
-	}
+	pci_mmio_write(len, addr + reg, value);
 	rcu_read_unlock();
 
 	return 0;
diff --git a/arch/x86/pci/numachip.c b/arch/x86/pci/numachip.c
index 2e565e6..5047e9b 100644
--- a/arch/x86/pci/numachip.c
+++ b/arch/x86/pci/numachip.c
@@ -51,17 +51,7 @@ err:		*value = -1;
 		goto err;
 	}
 
-	switch (len) {
-	case 1:
-		*value = mmio_config_readb(addr + reg);
-		break;
-	case 2:
-		*value = mmio_config_readw(addr + reg);
-		break;
-	case 4:
-		*value = mmio_config_readl(addr + reg);
-		break;
-	}
+	*value = pci_mmio_read(len, addr + reg);
 	rcu_read_unlock();
 
 	return 0;
@@ -87,17 +77,7 @@ static int pci_mmcfg_write_numachip(unsigned int seg, unsigned int bus,
 		return -EINVAL;
 	}
 
-	switch (len) {
-	case 1:
-		mmio_config_writeb(addr + reg, value);
-		break;
-	case 2:
-		mmio_config_writew(addr + reg, value);
-		break;
-	case 4:
-		mmio_config_writel(addr + reg, value);
-		break;
-	}
+	pci_mmio_write(len, addr + reg, value);
 	rcu_read_unlock();
 
 	return 0;
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [PATCH v4 3/9] x86, pci: Reorder logic of pci_mmconfig_insert() function
  2015-03-11 14:12 ` Tomasz Nowicki
  (?)
@ 2015-03-11 14:12   ` Tomasz Nowicki
  -1 siblings, 0 replies; 38+ messages in thread
From: Tomasz Nowicki @ 2015-03-11 14:12 UTC (permalink / raw)
  To: bhelgaas, wangyijing, arnd, hanjun.guo, Liviu.Dudau, tglx, mingo,
	hpa, rjw, al.stone
  Cc: linaro-acpi, linux-pci, x86, linux-kernel, Tomasz Nowicki,
	linux-acpi, linux-arm-kernel

This patch is the first step for MMCONFIG refactoring process.

Code that uses pci_mmcfg_lock will be moved to common file and become
accessible for all architectures. pci_mmconfig_insert() cannot be moved
so easily since it is mixing generic mmconfig code with x86 specific logic
inside of mutual exclusive block guarded by pci_mmcfg_lock.

To get rid of that constraint, we reorder actions as follow:
1. mmconfig entry allocation can be done first, no need to lock
2. insertion to iomem_resource has its own lock, no need to wrap it into mutex
3. insertion to mmconfig list can be done as the final step in separate
function (candidate for further refactoring)

Signed-off-by: Tomasz Nowicki <tomasz.nowicki@linaro.org>
---
 arch/x86/pci/mmconfig-shared.c | 100 ++++++++++++++++++++++-------------------
 1 file changed, 54 insertions(+), 46 deletions(-)

diff --git a/arch/x86/pci/mmconfig-shared.c b/arch/x86/pci/mmconfig-shared.c
index 8b3bc4f..685cd4c 100644
--- a/arch/x86/pci/mmconfig-shared.c
+++ b/arch/x86/pci/mmconfig-shared.c
@@ -834,6 +834,39 @@ static int __init pci_mmcfg_late_insert_resources(void)
  */
 late_initcall(pci_mmcfg_late_insert_resources);
 
+static int pci_mmconfig_inject(struct pci_mmcfg_region *cfg)
+{
+	struct pci_mmcfg_region *cfg_conflict;
+	int err = 0;
+
+	mutex_lock(&pci_mmcfg_lock);
+	cfg_conflict = pci_mmconfig_lookup(cfg->segment, cfg->start_bus);
+	if (cfg_conflict) {
+		if (cfg_conflict->end_bus < cfg->end_bus)
+			pr_info(FW_INFO "MMCONFIG for "
+				"domain %04x [bus %02x-%02x] "
+				"only partially covers this bridge\n",
+				cfg_conflict->segment, cfg_conflict->start_bus,
+				cfg_conflict->end_bus);
+		err = -EEXIST;
+		goto out;
+	}
+
+	if (pci_mmcfg_arch_map(cfg)) {
+		pr_warn("fail to map MMCONFIG %pR.\n", &cfg->res);
+		err = -ENOMEM;
+		goto out;
+	} else {
+		list_add_sorted(cfg);
+		pr_info("MMCONFIG at %pR (base %#lx)\n",
+			&cfg->res, (unsigned long)cfg->address);
+
+	}
+out:
+	mutex_unlock(&pci_mmcfg_lock);
+	return err;
+}
+
 /* Add MMCFG information for host bridges */
 int pci_mmconfig_insert(struct device *dev, u16 seg, u8 start, u8 end,
 			phys_addr_t addr)
@@ -845,66 +878,41 @@ int pci_mmconfig_insert(struct device *dev, u16 seg, u8 start, u8 end,
 	if (!(pci_probe & PCI_PROBE_MMCONF) || pci_mmcfg_arch_init_failed)
 		return -ENODEV;
 
-	if (start > end)
+	if (start > end || !addr)
 		return -EINVAL;
 
-	mutex_lock(&pci_mmcfg_lock);
-	cfg = pci_mmconfig_lookup(seg, start);
-	if (cfg) {
-		if (cfg->end_bus < end)
-			dev_info(dev, FW_INFO
-				 "MMCONFIG for "
-				 "domain %04x [bus %02x-%02x] "
-				 "only partially covers this bridge\n",
-				  cfg->segment, cfg->start_bus, cfg->end_bus);
-		mutex_unlock(&pci_mmcfg_lock);
-		return -EEXIST;
-	}
-
-	if (!addr) {
-		mutex_unlock(&pci_mmcfg_lock);
-		return -EINVAL;
-	}
-
 	rc = -EBUSY;
 	cfg = pci_mmconfig_alloc(seg, start, end, addr);
 	if (cfg == NULL) {
 		dev_warn(dev, "fail to add MMCONFIG (out of memory)\n");
-		rc = -ENOMEM;
+		return -ENOMEM;
 	} else if (!pci_mmcfg_check_reserved(dev, cfg, 0)) {
 		dev_warn(dev, FW_BUG "MMCONFIG %pR isn't reserved\n",
 			 &cfg->res);
-	} else {
-		/* Insert resource if it's not in boot stage */
-		if (pci_mmcfg_running_state)
-			tmp = insert_resource_conflict(&iomem_resource,
-						       &cfg->res);
-
-		if (tmp) {
-			dev_warn(dev,
-				 "MMCONFIG %pR conflicts with "
-				 "%s %pR\n",
-				 &cfg->res, tmp->name, tmp);
-		} else if (pci_mmcfg_arch_map(cfg)) {
-			dev_warn(dev, "fail to map MMCONFIG %pR.\n",
-				 &cfg->res);
-		} else {
-			list_add_sorted(cfg);
-			dev_info(dev, "MMCONFIG at %pR (base %#lx)\n",
-				 &cfg->res, (unsigned long)addr);
-			cfg = NULL;
-			rc = 0;
-		}
+		goto error;
 	}
 
-	if (cfg) {
-		if (cfg->res.parent)
-			release_resource(&cfg->res);
-		kfree(cfg);
+	/* Insert resource if it's not in boot stage */
+	if (pci_mmcfg_running_state)
+		tmp = insert_resource_conflict(&iomem_resource, &cfg->res);
+
+	if (tmp) {
+		dev_warn(dev,
+			 "MMCONFIG %pR conflicts with %s %pR\n",
+			 &cfg->res, tmp->name, tmp);
+		goto error;
 	}
 
-	mutex_unlock(&pci_mmcfg_lock);
+	rc = pci_mmconfig_inject(cfg);
+	if (rc)
+		goto error;
+
+	return 0;
 
+error:
+	if (cfg->res.parent)
+		release_resource(&cfg->res);
+	kfree(cfg);
 	return rc;
 }
 
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [PATCH v4 3/9] x86, pci: Reorder logic of pci_mmconfig_insert() function
@ 2015-03-11 14:12   ` Tomasz Nowicki
  0 siblings, 0 replies; 38+ messages in thread
From: Tomasz Nowicki @ 2015-03-11 14:12 UTC (permalink / raw)
  To: bhelgaas, wangyijing, arnd, hanjun.guo, Liviu.Dudau, tglx, mingo,
	hpa, rjw, al.stone
  Cc: linux-arm-kernel, linux-kernel, x86, linux-pci, linux-acpi,
	linaro-acpi, Tomasz Nowicki

This patch is the first step for MMCONFIG refactoring process.

Code that uses pci_mmcfg_lock will be moved to common file and become
accessible for all architectures. pci_mmconfig_insert() cannot be moved
so easily since it is mixing generic mmconfig code with x86 specific logic
inside of mutual exclusive block guarded by pci_mmcfg_lock.

To get rid of that constraint, we reorder actions as follow:
1. mmconfig entry allocation can be done first, no need to lock
2. insertion to iomem_resource has its own lock, no need to wrap it into mutex
3. insertion to mmconfig list can be done as the final step in separate
function (candidate for further refactoring)

Signed-off-by: Tomasz Nowicki <tomasz.nowicki@linaro.org>
---
 arch/x86/pci/mmconfig-shared.c | 100 ++++++++++++++++++++++-------------------
 1 file changed, 54 insertions(+), 46 deletions(-)

diff --git a/arch/x86/pci/mmconfig-shared.c b/arch/x86/pci/mmconfig-shared.c
index 8b3bc4f..685cd4c 100644
--- a/arch/x86/pci/mmconfig-shared.c
+++ b/arch/x86/pci/mmconfig-shared.c
@@ -834,6 +834,39 @@ static int __init pci_mmcfg_late_insert_resources(void)
  */
 late_initcall(pci_mmcfg_late_insert_resources);
 
+static int pci_mmconfig_inject(struct pci_mmcfg_region *cfg)
+{
+	struct pci_mmcfg_region *cfg_conflict;
+	int err = 0;
+
+	mutex_lock(&pci_mmcfg_lock);
+	cfg_conflict = pci_mmconfig_lookup(cfg->segment, cfg->start_bus);
+	if (cfg_conflict) {
+		if (cfg_conflict->end_bus < cfg->end_bus)
+			pr_info(FW_INFO "MMCONFIG for "
+				"domain %04x [bus %02x-%02x] "
+				"only partially covers this bridge\n",
+				cfg_conflict->segment, cfg_conflict->start_bus,
+				cfg_conflict->end_bus);
+		err = -EEXIST;
+		goto out;
+	}
+
+	if (pci_mmcfg_arch_map(cfg)) {
+		pr_warn("fail to map MMCONFIG %pR.\n", &cfg->res);
+		err = -ENOMEM;
+		goto out;
+	} else {
+		list_add_sorted(cfg);
+		pr_info("MMCONFIG at %pR (base %#lx)\n",
+			&cfg->res, (unsigned long)cfg->address);
+
+	}
+out:
+	mutex_unlock(&pci_mmcfg_lock);
+	return err;
+}
+
 /* Add MMCFG information for host bridges */
 int pci_mmconfig_insert(struct device *dev, u16 seg, u8 start, u8 end,
 			phys_addr_t addr)
@@ -845,66 +878,41 @@ int pci_mmconfig_insert(struct device *dev, u16 seg, u8 start, u8 end,
 	if (!(pci_probe & PCI_PROBE_MMCONF) || pci_mmcfg_arch_init_failed)
 		return -ENODEV;
 
-	if (start > end)
+	if (start > end || !addr)
 		return -EINVAL;
 
-	mutex_lock(&pci_mmcfg_lock);
-	cfg = pci_mmconfig_lookup(seg, start);
-	if (cfg) {
-		if (cfg->end_bus < end)
-			dev_info(dev, FW_INFO
-				 "MMCONFIG for "
-				 "domain %04x [bus %02x-%02x] "
-				 "only partially covers this bridge\n",
-				  cfg->segment, cfg->start_bus, cfg->end_bus);
-		mutex_unlock(&pci_mmcfg_lock);
-		return -EEXIST;
-	}
-
-	if (!addr) {
-		mutex_unlock(&pci_mmcfg_lock);
-		return -EINVAL;
-	}
-
 	rc = -EBUSY;
 	cfg = pci_mmconfig_alloc(seg, start, end, addr);
 	if (cfg == NULL) {
 		dev_warn(dev, "fail to add MMCONFIG (out of memory)\n");
-		rc = -ENOMEM;
+		return -ENOMEM;
 	} else if (!pci_mmcfg_check_reserved(dev, cfg, 0)) {
 		dev_warn(dev, FW_BUG "MMCONFIG %pR isn't reserved\n",
 			 &cfg->res);
-	} else {
-		/* Insert resource if it's not in boot stage */
-		if (pci_mmcfg_running_state)
-			tmp = insert_resource_conflict(&iomem_resource,
-						       &cfg->res);
-
-		if (tmp) {
-			dev_warn(dev,
-				 "MMCONFIG %pR conflicts with "
-				 "%s %pR\n",
-				 &cfg->res, tmp->name, tmp);
-		} else if (pci_mmcfg_arch_map(cfg)) {
-			dev_warn(dev, "fail to map MMCONFIG %pR.\n",
-				 &cfg->res);
-		} else {
-			list_add_sorted(cfg);
-			dev_info(dev, "MMCONFIG at %pR (base %#lx)\n",
-				 &cfg->res, (unsigned long)addr);
-			cfg = NULL;
-			rc = 0;
-		}
+		goto error;
 	}
 
-	if (cfg) {
-		if (cfg->res.parent)
-			release_resource(&cfg->res);
-		kfree(cfg);
+	/* Insert resource if it's not in boot stage */
+	if (pci_mmcfg_running_state)
+		tmp = insert_resource_conflict(&iomem_resource, &cfg->res);
+
+	if (tmp) {
+		dev_warn(dev,
+			 "MMCONFIG %pR conflicts with %s %pR\n",
+			 &cfg->res, tmp->name, tmp);
+		goto error;
 	}
 
-	mutex_unlock(&pci_mmcfg_lock);
+	rc = pci_mmconfig_inject(cfg);
+	if (rc)
+		goto error;
+
+	return 0;
 
+error:
+	if (cfg->res.parent)
+		release_resource(&cfg->res);
+	kfree(cfg);
 	return rc;
 }
 
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [PATCH v4 3/9] x86, pci: Reorder logic of pci_mmconfig_insert() function
@ 2015-03-11 14:12   ` Tomasz Nowicki
  0 siblings, 0 replies; 38+ messages in thread
From: Tomasz Nowicki @ 2015-03-11 14:12 UTC (permalink / raw)
  To: linux-arm-kernel

This patch is the first step for MMCONFIG refactoring process.

Code that uses pci_mmcfg_lock will be moved to common file and become
accessible for all architectures. pci_mmconfig_insert() cannot be moved
so easily since it is mixing generic mmconfig code with x86 specific logic
inside of mutual exclusive block guarded by pci_mmcfg_lock.

To get rid of that constraint, we reorder actions as follow:
1. mmconfig entry allocation can be done first, no need to lock
2. insertion to iomem_resource has its own lock, no need to wrap it into mutex
3. insertion to mmconfig list can be done as the final step in separate
function (candidate for further refactoring)

Signed-off-by: Tomasz Nowicki <tomasz.nowicki@linaro.org>
---
 arch/x86/pci/mmconfig-shared.c | 100 ++++++++++++++++++++++-------------------
 1 file changed, 54 insertions(+), 46 deletions(-)

diff --git a/arch/x86/pci/mmconfig-shared.c b/arch/x86/pci/mmconfig-shared.c
index 8b3bc4f..685cd4c 100644
--- a/arch/x86/pci/mmconfig-shared.c
+++ b/arch/x86/pci/mmconfig-shared.c
@@ -834,6 +834,39 @@ static int __init pci_mmcfg_late_insert_resources(void)
  */
 late_initcall(pci_mmcfg_late_insert_resources);
 
+static int pci_mmconfig_inject(struct pci_mmcfg_region *cfg)
+{
+	struct pci_mmcfg_region *cfg_conflict;
+	int err = 0;
+
+	mutex_lock(&pci_mmcfg_lock);
+	cfg_conflict = pci_mmconfig_lookup(cfg->segment, cfg->start_bus);
+	if (cfg_conflict) {
+		if (cfg_conflict->end_bus < cfg->end_bus)
+			pr_info(FW_INFO "MMCONFIG for "
+				"domain %04x [bus %02x-%02x] "
+				"only partially covers this bridge\n",
+				cfg_conflict->segment, cfg_conflict->start_bus,
+				cfg_conflict->end_bus);
+		err = -EEXIST;
+		goto out;
+	}
+
+	if (pci_mmcfg_arch_map(cfg)) {
+		pr_warn("fail to map MMCONFIG %pR.\n", &cfg->res);
+		err = -ENOMEM;
+		goto out;
+	} else {
+		list_add_sorted(cfg);
+		pr_info("MMCONFIG at %pR (base %#lx)\n",
+			&cfg->res, (unsigned long)cfg->address);
+
+	}
+out:
+	mutex_unlock(&pci_mmcfg_lock);
+	return err;
+}
+
 /* Add MMCFG information for host bridges */
 int pci_mmconfig_insert(struct device *dev, u16 seg, u8 start, u8 end,
 			phys_addr_t addr)
@@ -845,66 +878,41 @@ int pci_mmconfig_insert(struct device *dev, u16 seg, u8 start, u8 end,
 	if (!(pci_probe & PCI_PROBE_MMCONF) || pci_mmcfg_arch_init_failed)
 		return -ENODEV;
 
-	if (start > end)
+	if (start > end || !addr)
 		return -EINVAL;
 
-	mutex_lock(&pci_mmcfg_lock);
-	cfg = pci_mmconfig_lookup(seg, start);
-	if (cfg) {
-		if (cfg->end_bus < end)
-			dev_info(dev, FW_INFO
-				 "MMCONFIG for "
-				 "domain %04x [bus %02x-%02x] "
-				 "only partially covers this bridge\n",
-				  cfg->segment, cfg->start_bus, cfg->end_bus);
-		mutex_unlock(&pci_mmcfg_lock);
-		return -EEXIST;
-	}
-
-	if (!addr) {
-		mutex_unlock(&pci_mmcfg_lock);
-		return -EINVAL;
-	}
-
 	rc = -EBUSY;
 	cfg = pci_mmconfig_alloc(seg, start, end, addr);
 	if (cfg == NULL) {
 		dev_warn(dev, "fail to add MMCONFIG (out of memory)\n");
-		rc = -ENOMEM;
+		return -ENOMEM;
 	} else if (!pci_mmcfg_check_reserved(dev, cfg, 0)) {
 		dev_warn(dev, FW_BUG "MMCONFIG %pR isn't reserved\n",
 			 &cfg->res);
-	} else {
-		/* Insert resource if it's not in boot stage */
-		if (pci_mmcfg_running_state)
-			tmp = insert_resource_conflict(&iomem_resource,
-						       &cfg->res);
-
-		if (tmp) {
-			dev_warn(dev,
-				 "MMCONFIG %pR conflicts with "
-				 "%s %pR\n",
-				 &cfg->res, tmp->name, tmp);
-		} else if (pci_mmcfg_arch_map(cfg)) {
-			dev_warn(dev, "fail to map MMCONFIG %pR.\n",
-				 &cfg->res);
-		} else {
-			list_add_sorted(cfg);
-			dev_info(dev, "MMCONFIG at %pR (base %#lx)\n",
-				 &cfg->res, (unsigned long)addr);
-			cfg = NULL;
-			rc = 0;
-		}
+		goto error;
 	}
 
-	if (cfg) {
-		if (cfg->res.parent)
-			release_resource(&cfg->res);
-		kfree(cfg);
+	/* Insert resource if it's not in boot stage */
+	if (pci_mmcfg_running_state)
+		tmp = insert_resource_conflict(&iomem_resource, &cfg->res);
+
+	if (tmp) {
+		dev_warn(dev,
+			 "MMCONFIG %pR conflicts with %s %pR\n",
+			 &cfg->res, tmp->name, tmp);
+		goto error;
 	}
 
-	mutex_unlock(&pci_mmcfg_lock);
+	rc = pci_mmconfig_inject(cfg);
+	if (rc)
+		goto error;
+
+	return 0;
 
+error:
+	if (cfg->res.parent)
+		release_resource(&cfg->res);
+	kfree(cfg);
 	return rc;
 }
 
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [PATCH v4 4/9] x86, pci, acpi: Move arch-agnostic MMCONFIG (aka ECAM) and ACPI code out of arch/x86/ directory
  2015-03-11 14:12 ` Tomasz Nowicki
@ 2015-03-11 14:12   ` Tomasz Nowicki
  -1 siblings, 0 replies; 38+ messages in thread
From: Tomasz Nowicki @ 2015-03-11 14:12 UTC (permalink / raw)
  To: bhelgaas, wangyijing, arnd, hanjun.guo, Liviu.Dudau, tglx, mingo,
	hpa, rjw, al.stone
  Cc: linux-arm-kernel, linux-kernel, x86, linux-pci, linux-acpi,
	linaro-acpi, Tomasz Nowicki

ECAM standard and MCFG table are architecture independent and it makes
sense to share common code across all architectures. Both are going to
corresponding files - ecam.c and mcfg.c

While we are here, rename pci_parse_mcfg to acpi_parse_mcfg.
We already have acpi_parse_mcfg prototype which is used nowhere.
At the same time, we need pci_parse_mcfg been global so acpi_parse_mcfg
can be used perfectly here.

Signed-off-by: Tomasz Nowicki <tomasz.nowicki@linaro.org>
---
 arch/x86/Kconfig               |   3 +
 arch/x86/include/asm/pci_x86.h |  33 -----
 arch/x86/pci/acpi.c            |   1 +
 arch/x86/pci/mmconfig-shared.c | 296 +----------------------------------------
 arch/x86/pci/mmconfig_32.c     |   1 +
 arch/x86/pci/mmconfig_64.c     |   1 +
 arch/x86/pci/numachip.c        |   1 +
 drivers/acpi/Makefile          |   1 +
 drivers/acpi/mcfg.c            |  81 +++++++++++
 drivers/pci/Kconfig            |   7 +
 drivers/pci/Makefile           |   5 +
 drivers/pci/ecam.c             | 245 ++++++++++++++++++++++++++++++++++
 drivers/xen/pci.c              |   1 +
 include/linux/ecam.h           |  51 +++++++
 14 files changed, 401 insertions(+), 326 deletions(-)
 create mode 100644 drivers/acpi/mcfg.c
 create mode 100644 drivers/pci/ecam.c
 create mode 100644 include/linux/ecam.h

diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index c2fb8a8..aa451bf 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -141,6 +141,7 @@ config X86
 	select ACPI_LEGACY_TABLES_LOOKUP if ACPI
 	select X86_FEATURE_NAMES if PROC_FS
 	select SRCU
+	select HAVE_PCI_ECAM
 
 config INSTRUCTION_DECODER
 	def_bool y
@@ -2276,6 +2277,7 @@ config PCI_DIRECT
 
 config PCI_MMCONFIG
 	def_bool y
+	select PCI_ECAM
 	depends on X86_32 && PCI && (ACPI || SFI) && (PCI_GOMMCONFIG || PCI_GOANY)
 
 config PCI_OLPC
@@ -2293,6 +2295,7 @@ config PCI_DOMAINS
 
 config PCI_MMCONFIG
 	bool "Support mmconfig PCI config space access"
+	select PCI_ECAM
 	depends on X86_64 && PCI && ACPI
 
 config PCI_CNB20LE_QUIRK
diff --git a/arch/x86/include/asm/pci_x86.h b/arch/x86/include/asm/pci_x86.h
index c57c225..e8a237f 100644
--- a/arch/x86/include/asm/pci_x86.h
+++ b/arch/x86/include/asm/pci_x86.h
@@ -122,41 +122,8 @@ extern int pci_legacy_init(void);
 extern void pcibios_fixup_irqs(void);
 
 /* pci-mmconfig.c */
-
-/* "PCI MMCONFIG %04x [bus %02x-%02x]" */
-#define PCI_MMCFG_RESOURCE_NAME_LEN (22 + 4 + 2 + 2)
-
-struct pci_mmcfg_region {
-	struct list_head list;
-	struct resource res;
-	u64 address;
-	char __iomem *virt;
-	u16 segment;
-	u8 start_bus;
-	u8 end_bus;
-	char name[PCI_MMCFG_RESOURCE_NAME_LEN];
-};
-
-struct pci_mmcfg_mmio_ops {
-	u32 (*read)(int len, void __iomem *addr);
-	void (*write)(int len, void __iomem *addr, u32 value);
-};
-
-extern int __init pci_mmcfg_arch_init(void);
-extern void __init pci_mmcfg_arch_free(void);
-extern int pci_mmcfg_arch_map(struct pci_mmcfg_region *cfg);
-extern void pci_mmcfg_arch_unmap(struct pci_mmcfg_region *cfg);
 extern int pci_mmconfig_insert(struct device *dev, u16 seg, u8 start, u8 end,
 			       phys_addr_t addr);
-extern int pci_mmconfig_delete(u16 seg, u8 start, u8 end);
-extern struct pci_mmcfg_region *pci_mmconfig_lookup(int segment, int bus);
-extern u32 pci_mmio_read(int len, void __iomem *addr);
-extern void pci_mmio_write(int len, void __iomem *addr, u32 value);
-extern void pci_mmconfig_register_mmio(struct pci_mmcfg_mmio_ops *ops);
-
-extern struct list_head pci_mmcfg_list;
-
-#define PCI_MMCFG_BUS_OFFSET(bus)      ((bus) << 20)
 
 /*
  * AMD Fam10h CPUs are buggy, and cannot access MMIO config space
diff --git a/arch/x86/pci/acpi.c b/arch/x86/pci/acpi.c
index 6ac2738..5dfccef 100644
--- a/arch/x86/pci/acpi.c
+++ b/arch/x86/pci/acpi.c
@@ -4,6 +4,7 @@
 #include <linux/irq.h>
 #include <linux/dmi.h>
 #include <linux/slab.h>
+#include <linux/ecam.h>
 #include <asm/numa.h>
 #include <asm/pci_x86.h>
 
diff --git a/arch/x86/pci/mmconfig-shared.c b/arch/x86/pci/mmconfig-shared.c
index 685cd4c..5064302 100644
--- a/arch/x86/pci/mmconfig-shared.c
+++ b/arch/x86/pci/mmconfig-shared.c
@@ -18,6 +18,7 @@
 #include <linux/slab.h>
 #include <linux/mutex.h>
 #include <linux/rculist.h>
+#include <linux/ecam.h>
 #include <asm/e820.h>
 #include <asm/pci_x86.h>
 #include <asm/acpi.h>
@@ -27,52 +28,6 @@
 /* Indicate if the mmcfg resources have been placed into the resource table. */
 static bool pci_mmcfg_running_state;
 static bool pci_mmcfg_arch_init_failed;
-static DEFINE_MUTEX(pci_mmcfg_lock);
-
-LIST_HEAD(pci_mmcfg_list);
-
-static u32
-pci_mmconfig_generic_read(int len, void __iomem *addr)
-{
-	u32 data = 0;
-
-	switch (len) {
-	case 1:
-		data = readb(addr);
-		break;
-	case 2:
-		data = readw(addr);
-		break;
-	case 4:
-		data = readl(addr);
-		break;
-	}
-
-	return data;
-}
-
-static void
-pci_mmconfig_generic_write(int len, void __iomem *addr, u32 value)
-{
-	switch (len) {
-	case 1:
-		writeb(value, addr);
-		break;
-	case 2:
-		writew(value, addr);
-		break;
-	case 4:
-		writel(value, addr);
-		break;
-	}
-}
-
-static struct pci_mmcfg_mmio_ops pci_mmcfg_mmio_default = {
-	.read = pci_mmconfig_generic_read,
-	.write = pci_mmconfig_generic_write,
-};
-
-static struct pci_mmcfg_mmio_ops *pci_mmcfg_mmio = &pci_mmcfg_mmio_default;
 
 static u32
 pci_mmconfig_amd_read(int len, void __iomem *addr)
@@ -115,128 +70,6 @@ static struct pci_mmcfg_mmio_ops pci_mmcfg_mmio_amd_fam10h = {
 	.write = pci_mmconfig_amd_write,
 };
 
-void
-pci_mmconfig_register_mmio(struct pci_mmcfg_mmio_ops *ops)
-{
-	pci_mmcfg_mmio = ops;
-}
-
-u32
-pci_mmio_read(int len, void __iomem *addr)
-{
-	if (!pci_mmcfg_mmio) {
-		pr_err("PCI config space has no accessors !");
-		return 0;
-	}
-
-	return pci_mmcfg_mmio->read(len, addr);
-}
-
-void
-pci_mmio_write(int len, void __iomem *addr, u32 value)
-{
-	if (!pci_mmcfg_mmio) {
-		pr_err("PCI config space has no accessors !");
-		return;
-	}
-
-	pci_mmcfg_mmio->write(len, addr, value);
-}
-
-static void __init pci_mmconfig_remove(struct pci_mmcfg_region *cfg)
-{
-	if (cfg->res.parent)
-		release_resource(&cfg->res);
-	list_del(&cfg->list);
-	kfree(cfg);
-}
-
-static void __init free_all_mmcfg(void)
-{
-	struct pci_mmcfg_region *cfg, *tmp;
-
-	pci_mmcfg_arch_free();
-	list_for_each_entry_safe(cfg, tmp, &pci_mmcfg_list, list)
-		pci_mmconfig_remove(cfg);
-}
-
-static void list_add_sorted(struct pci_mmcfg_region *new)
-{
-	struct pci_mmcfg_region *cfg;
-
-	/* keep list sorted by segment and starting bus number */
-	list_for_each_entry_rcu(cfg, &pci_mmcfg_list, list) {
-		if (cfg->segment > new->segment ||
-		    (cfg->segment == new->segment &&
-		     cfg->start_bus >= new->start_bus)) {
-			list_add_tail_rcu(&new->list, &cfg->list);
-			return;
-		}
-	}
-	list_add_tail_rcu(&new->list, &pci_mmcfg_list);
-}
-
-static struct pci_mmcfg_region *pci_mmconfig_alloc(int segment, int start,
-						   int end, u64 addr)
-{
-	struct pci_mmcfg_region *new;
-	struct resource *res;
-
-	if (addr == 0)
-		return NULL;
-
-	new = kzalloc(sizeof(*new), GFP_KERNEL);
-	if (!new)
-		return NULL;
-
-	new->address = addr;
-	new->segment = segment;
-	new->start_bus = start;
-	new->end_bus = end;
-
-	res = &new->res;
-	res->start = addr + PCI_MMCFG_BUS_OFFSET(start);
-	res->end = addr + PCI_MMCFG_BUS_OFFSET(end + 1) - 1;
-	res->flags = IORESOURCE_MEM | IORESOURCE_BUSY;
-	snprintf(new->name, PCI_MMCFG_RESOURCE_NAME_LEN,
-		 "PCI MMCONFIG %04x [bus %02x-%02x]", segment, start, end);
-	res->name = new->name;
-
-	return new;
-}
-
-static struct pci_mmcfg_region *__init pci_mmconfig_add(int segment, int start,
-							int end, u64 addr)
-{
-	struct pci_mmcfg_region *new;
-
-	new = pci_mmconfig_alloc(segment, start, end, addr);
-	if (new) {
-		mutex_lock(&pci_mmcfg_lock);
-		list_add_sorted(new);
-		mutex_unlock(&pci_mmcfg_lock);
-
-		pr_info(PREFIX
-		       "MMCONFIG for domain %04x [bus %02x-%02x] at %pR "
-		       "(base %#lx)\n",
-		       segment, start, end, &new->res, (unsigned long)addr);
-	}
-
-	return new;
-}
-
-struct pci_mmcfg_region *pci_mmconfig_lookup(int segment, int bus)
-{
-	struct pci_mmcfg_region *cfg;
-
-	list_for_each_entry_rcu(cfg, &pci_mmcfg_list, list)
-		if (cfg->segment == segment &&
-		    cfg->start_bus <= bus && bus <= cfg->end_bus)
-			return cfg;
-
-	return NULL;
-}
-
 static const char *__init pci_mmcfg_e7520(void)
 {
 	u32 win;
@@ -657,73 +490,6 @@ static void __init pci_mmcfg_reject_broken(int early)
 	}
 }
 
-static int __init acpi_mcfg_check_entry(struct acpi_table_mcfg *mcfg,
-					struct acpi_mcfg_allocation *cfg)
-{
-	int year;
-
-	if (cfg->address < 0xFFFFFFFF)
-		return 0;
-
-	if (!strncmp(mcfg->header.oem_id, "SGI", 3))
-		return 0;
-
-	if (mcfg->header.revision >= 1) {
-		if (dmi_get_date(DMI_BIOS_DATE, &year, NULL, NULL) &&
-		    year >= 2010)
-			return 0;
-	}
-
-	pr_err(PREFIX "MCFG region for %04x [bus %02x-%02x] at %#llx "
-	       "is above 4GB, ignored\n", cfg->pci_segment,
-	       cfg->start_bus_number, cfg->end_bus_number, cfg->address);
-	return -EINVAL;
-}
-
-static int __init pci_parse_mcfg(struct acpi_table_header *header)
-{
-	struct acpi_table_mcfg *mcfg;
-	struct acpi_mcfg_allocation *cfg_table, *cfg;
-	unsigned long i;
-	int entries;
-
-	if (!header)
-		return -EINVAL;
-
-	mcfg = (struct acpi_table_mcfg *)header;
-
-	/* how many config structures do we have */
-	free_all_mmcfg();
-	entries = 0;
-	i = header->length - sizeof(struct acpi_table_mcfg);
-	while (i >= sizeof(struct acpi_mcfg_allocation)) {
-		entries++;
-		i -= sizeof(struct acpi_mcfg_allocation);
-	}
-	if (entries == 0) {
-		pr_err(PREFIX "MMCONFIG has no entries\n");
-		return -ENODEV;
-	}
-
-	cfg_table = (struct acpi_mcfg_allocation *) &mcfg[1];
-	for (i = 0; i < entries; i++) {
-		cfg = &cfg_table[i];
-		if (acpi_mcfg_check_entry(mcfg, cfg)) {
-			free_all_mmcfg();
-			return -ENODEV;
-		}
-
-		if (pci_mmconfig_add(cfg->pci_segment, cfg->start_bus_number,
-				   cfg->end_bus_number, cfg->address) == NULL) {
-			pr_warn(PREFIX "no memory for MCFG entries\n");
-			free_all_mmcfg();
-			return -ENOMEM;
-		}
-	}
-
-	return 0;
-}
-
 #ifdef CONFIG_ACPI_APEI
 extern int (*arch_apei_filter_addr)(int (*func)(__u64 start, __u64 size,
 				     void *data), void *data);
@@ -782,7 +548,7 @@ void __init pci_mmcfg_early_init(void)
 		if (pci_mmcfg_check_hostbridge())
 			known_bridge = 1;
 		else
-			acpi_sfi_table_parse(ACPI_SIG_MCFG, pci_parse_mcfg);
+			acpi_sfi_table_parse(ACPI_SIG_MCFG, acpi_parse_mcfg);
 		__pci_mmcfg_init(1);
 
 		set_apei_filter();
@@ -800,7 +566,7 @@ void __init pci_mmcfg_late_init(void)
 
 	/* MMCONFIG hasn't been enabled yet, try again */
 	if (pci_probe & PCI_PROBE_MASK & ~PCI_PROBE_MMCONF) {
-		acpi_sfi_table_parse(ACPI_SIG_MCFG, pci_parse_mcfg);
+		acpi_sfi_table_parse(ACPI_SIG_MCFG, acpi_parse_mcfg);
 		__pci_mmcfg_init(0);
 	}
 }
@@ -834,39 +600,6 @@ static int __init pci_mmcfg_late_insert_resources(void)
  */
 late_initcall(pci_mmcfg_late_insert_resources);
 
-static int pci_mmconfig_inject(struct pci_mmcfg_region *cfg)
-{
-	struct pci_mmcfg_region *cfg_conflict;
-	int err = 0;
-
-	mutex_lock(&pci_mmcfg_lock);
-	cfg_conflict = pci_mmconfig_lookup(cfg->segment, cfg->start_bus);
-	if (cfg_conflict) {
-		if (cfg_conflict->end_bus < cfg->end_bus)
-			pr_info(FW_INFO "MMCONFIG for "
-				"domain %04x [bus %02x-%02x] "
-				"only partially covers this bridge\n",
-				cfg_conflict->segment, cfg_conflict->start_bus,
-				cfg_conflict->end_bus);
-		err = -EEXIST;
-		goto out;
-	}
-
-	if (pci_mmcfg_arch_map(cfg)) {
-		pr_warn("fail to map MMCONFIG %pR.\n", &cfg->res);
-		err = -ENOMEM;
-		goto out;
-	} else {
-		list_add_sorted(cfg);
-		pr_info("MMCONFIG at %pR (base %#lx)\n",
-			&cfg->res, (unsigned long)cfg->address);
-
-	}
-out:
-	mutex_unlock(&pci_mmcfg_lock);
-	return err;
-}
-
 /* Add MMCFG information for host bridges */
 int pci_mmconfig_insert(struct device *dev, u16 seg, u8 start, u8 end,
 			phys_addr_t addr)
@@ -915,26 +648,3 @@ error:
 	kfree(cfg);
 	return rc;
 }
-
-/* Delete MMCFG information for host bridges */
-int pci_mmconfig_delete(u16 seg, u8 start, u8 end)
-{
-	struct pci_mmcfg_region *cfg;
-
-	mutex_lock(&pci_mmcfg_lock);
-	list_for_each_entry_rcu(cfg, &pci_mmcfg_list, list)
-		if (cfg->segment == seg && cfg->start_bus == start &&
-		    cfg->end_bus == end) {
-			list_del_rcu(&cfg->list);
-			synchronize_rcu();
-			pci_mmcfg_arch_unmap(cfg);
-			if (cfg->res.parent)
-				release_resource(&cfg->res);
-			mutex_unlock(&pci_mmcfg_lock);
-			kfree(cfg);
-			return 0;
-		}
-	mutex_unlock(&pci_mmcfg_lock);
-
-	return -ENOENT;
-}
diff --git a/arch/x86/pci/mmconfig_32.c b/arch/x86/pci/mmconfig_32.c
index 4b3d025..5cf6291 100644
--- a/arch/x86/pci/mmconfig_32.c
+++ b/arch/x86/pci/mmconfig_32.c
@@ -12,6 +12,7 @@
 #include <linux/pci.h>
 #include <linux/init.h>
 #include <linux/rcupdate.h>
+#include <linux/ecam.h>
 #include <asm/e820.h>
 #include <asm/pci_x86.h>
 
diff --git a/arch/x86/pci/mmconfig_64.c b/arch/x86/pci/mmconfig_64.c
index 032593d..b62ff18 100644
--- a/arch/x86/pci/mmconfig_64.c
+++ b/arch/x86/pci/mmconfig_64.c
@@ -10,6 +10,7 @@
 #include <linux/acpi.h>
 #include <linux/bitmap.h>
 #include <linux/rcupdate.h>
+#include <linux/ecam.h>
 #include <asm/e820.h>
 #include <asm/pci_x86.h>
 
diff --git a/arch/x86/pci/numachip.c b/arch/x86/pci/numachip.c
index 5047e9b..01868b6 100644
--- a/arch/x86/pci/numachip.c
+++ b/arch/x86/pci/numachip.c
@@ -13,6 +13,7 @@
  *
  */
 
+#include <linux/ecam.h>
 #include <linux/pci.h>
 #include <asm/pci_x86.h>
 
diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile
index 623b117..39498a1 100644
--- a/drivers/acpi/Makefile
+++ b/drivers/acpi/Makefile
@@ -67,6 +67,7 @@ obj-$(CONFIG_ACPI_BUTTON)	+= button.o
 obj-$(CONFIG_ACPI_FAN)		+= fan.o
 obj-$(CONFIG_ACPI_VIDEO)	+= video.o
 obj-$(CONFIG_ACPI_PCI_SLOT)	+= pci_slot.o
+obj-$(CONFIG_PCI_MMCONFIG)	+= mcfg.o
 obj-$(CONFIG_ACPI_PROCESSOR)	+= processor.o
 obj-y				+= container.o
 obj-$(CONFIG_ACPI_THERMAL)	+= thermal.o
diff --git a/drivers/acpi/mcfg.c b/drivers/acpi/mcfg.c
new file mode 100644
index 0000000..a2e2326
--- /dev/null
+++ b/drivers/acpi/mcfg.c
@@ -0,0 +1,81 @@
+/*
+ * MCFG ACPI table parser.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/acpi.h>
+#include <linux/dmi.h>
+#include <linux/ecam.h>
+
+#define	PREFIX	"MCFG: "
+
+static int __init acpi_mcfg_check_entry(struct acpi_table_mcfg *mcfg,
+					struct acpi_mcfg_allocation *cfg)
+{
+	int year;
+
+	if (cfg->address < 0xFFFFFFFF)
+		return 0;
+
+	if (!strncmp(mcfg->header.oem_id, "SGI", 3))
+		return 0;
+
+	if (mcfg->header.revision >= 1) {
+		if (dmi_get_date(DMI_BIOS_DATE, &year, NULL, NULL) &&
+		    year >= 2010)
+			return 0;
+	}
+
+	pr_err(PREFIX "MCFG region for %04x [bus %02x-%02x] at %#llx "
+	       "is above 4GB, ignored\n", cfg->pci_segment,
+	       cfg->start_bus_number, cfg->end_bus_number, cfg->address);
+	return -EINVAL;
+}
+
+int __init acpi_parse_mcfg(struct acpi_table_header *header)
+{
+	struct acpi_table_mcfg *mcfg;
+	struct acpi_mcfg_allocation *cfg_table, *cfg;
+	unsigned long i;
+	int entries;
+
+	if (!header)
+		return -EINVAL;
+
+	mcfg = (struct acpi_table_mcfg *)header;
+
+	/* how many config structures do we have */
+	free_all_mmcfg();
+	entries = 0;
+	i = header->length - sizeof(struct acpi_table_mcfg);
+	while (i >= sizeof(struct acpi_mcfg_allocation)) {
+		entries++;
+		i -= sizeof(struct acpi_mcfg_allocation);
+	}
+	if (entries == 0) {
+		pr_err(PREFIX "MCFG table has no entries\n");
+		return -ENODEV;
+	}
+
+	cfg_table = (struct acpi_mcfg_allocation *) &mcfg[1];
+	for (i = 0; i < entries; i++) {
+		cfg = &cfg_table[i];
+		if (acpi_mcfg_check_entry(mcfg, cfg)) {
+			free_all_mmcfg();
+			return -ENODEV;
+		}
+
+		if (pci_mmconfig_add(cfg->pci_segment, cfg->start_bus_number,
+				   cfg->end_bus_number, cfg->address) == NULL) {
+			pr_warn(PREFIX "no memory for MCFG entries\n");
+			free_all_mmcfg();
+			return -ENOMEM;
+		}
+	}
+
+	return 0;
+}
diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig
index 7a8f1c5..90a5fb9 100644
--- a/drivers/pci/Kconfig
+++ b/drivers/pci/Kconfig
@@ -22,6 +22,13 @@ config PCI_MSI_IRQ_DOMAIN
 	depends on PCI_MSI
 	select GENERIC_MSI_IRQ_DOMAIN
 
+config PCI_ECAM
+	bool "Enhanced Configuration Access Mechanism (ECAM)"
+	depends on PCI && HAVE_PCI_ECAM
+
+config HAVE_PCI_ECAM
+	bool
+
 config PCI_DEBUG
 	bool "PCI Debugging"
 	depends on PCI && DEBUG_KERNEL
diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile
index 73e4af4..ce7b630 100644
--- a/drivers/pci/Makefile
+++ b/drivers/pci/Makefile
@@ -41,6 +41,11 @@ obj-$(CONFIG_SPARC_LEON) += setup-irq.o
 obj-$(CONFIG_M68K) += setup-irq.o
 
 #
+# Enhanced Configuration Access Mechanism (ECAM)
+#
+obj-$(CONFIG_PCI_ECAM)	+= ecam.o
+
+#
 # ACPI Related PCI FW Functions
 # ACPI _DSM provided firmware instance and string name
 #
diff --git a/drivers/pci/ecam.c b/drivers/pci/ecam.c
new file mode 100644
index 0000000..c588234
--- /dev/null
+++ b/drivers/pci/ecam.c
@@ -0,0 +1,245 @@
+/*
+ * Arch agnostic direct PCI config space access via
+ * ECAM (Enhanced Configuration Access Mechanism)
+ *
+ * Per-architecture code takes care of the mappings, region validation and
+ * accesses themselves.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/mutex.h>
+#include <linux/rculist.h>
+#include <linux/ecam.h>
+
+#include <asm/io.h>
+
+#define PREFIX "PCI: "
+
+static DEFINE_MUTEX(pci_mmcfg_lock);
+
+LIST_HEAD(pci_mmcfg_list);
+
+static u32
+pci_mmconfig_generic_read(int len, void __iomem *addr)
+{
+	u32 data = 0;
+
+	switch (len) {
+	case 1:
+		data = readb(addr);
+		break;
+	case 2:
+		data = readw(addr);
+		break;
+	case 4:
+		data = readl(addr);
+		break;
+	}
+
+	return data;
+}
+
+static void
+pci_mmconfig_generic_write(int len, void __iomem *addr, u32 value)
+{
+	switch (len) {
+	case 1:
+		writeb(value, addr);
+		break;
+	case 2:
+		writew(value, addr);
+		break;
+	case 4:
+		writel(value, addr);
+		break;
+	}
+}
+
+static struct pci_mmcfg_mmio_ops pci_mmcfg_mmio_default = {
+	.read = pci_mmconfig_generic_read,
+	.write = pci_mmconfig_generic_write,
+};
+
+static struct pci_mmcfg_mmio_ops *pci_mmcfg_mmio = &pci_mmcfg_mmio_default;
+
+void
+pci_mmconfig_register_mmio(struct pci_mmcfg_mmio_ops *ops)
+{
+	pci_mmcfg_mmio = ops;
+}
+
+u32
+pci_mmio_read(int len, void __iomem *addr)
+{
+	if (!pci_mmcfg_mmio) {
+		pr_err("PCI config space has no accessors !");
+		return 0;
+	}
+
+	return pci_mmcfg_mmio->read(len, addr);
+}
+
+void
+pci_mmio_write(int len, void __iomem *addr, u32 value)
+{
+	if (!pci_mmcfg_mmio) {
+		pr_err("PCI config space has no accessors !");
+		return;
+	}
+
+	pci_mmcfg_mmio->write(len, addr, value);
+}
+
+static void __init pci_mmconfig_remove(struct pci_mmcfg_region *cfg)
+{
+	if (cfg->res.parent)
+		release_resource(&cfg->res);
+	list_del(&cfg->list);
+	kfree(cfg);
+}
+
+void __init free_all_mmcfg(void)
+{
+	struct pci_mmcfg_region *cfg, *tmp;
+
+	pci_mmcfg_arch_free();
+	list_for_each_entry_safe(cfg, tmp, &pci_mmcfg_list, list)
+		pci_mmconfig_remove(cfg);
+}
+
+void list_add_sorted(struct pci_mmcfg_region *new)
+{
+	struct pci_mmcfg_region *cfg;
+
+	/* keep list sorted by segment and starting bus number */
+	list_for_each_entry_rcu(cfg, &pci_mmcfg_list, list) {
+		if (cfg->segment > new->segment ||
+		    (cfg->segment == new->segment &&
+		     cfg->start_bus >= new->start_bus)) {
+			list_add_tail_rcu(&new->list, &cfg->list);
+			return;
+		}
+	}
+	list_add_tail_rcu(&new->list, &pci_mmcfg_list);
+}
+
+struct pci_mmcfg_region *pci_mmconfig_alloc(int segment, int start,
+					    int end, u64 addr)
+{
+	struct pci_mmcfg_region *new;
+	struct resource *res;
+
+	if (addr == 0)
+		return NULL;
+
+	new = kzalloc(sizeof(*new), GFP_KERNEL);
+	if (!new)
+		return NULL;
+
+	new->address = addr;
+	new->segment = segment;
+	new->start_bus = start;
+	new->end_bus = end;
+
+	res = &new->res;
+	res->start = addr + PCI_MMCFG_BUS_OFFSET(start);
+	res->end = addr + PCI_MMCFG_BUS_OFFSET(end + 1) - 1;
+	res->flags = IORESOURCE_MEM | IORESOURCE_BUSY;
+	snprintf(new->name, PCI_MMCFG_RESOURCE_NAME_LEN,
+		 "PCI MMCONFIG %04x [bus %02x-%02x]", segment, start, end);
+	res->name = new->name;
+
+	return new;
+}
+
+struct pci_mmcfg_region *pci_mmconfig_add(int segment, int start,
+					  int end, u64 addr)
+{
+	struct pci_mmcfg_region *new;
+
+	new = pci_mmconfig_alloc(segment, start, end, addr);
+	if (new) {
+		mutex_lock(&pci_mmcfg_lock);
+		list_add_sorted(new);
+		mutex_unlock(&pci_mmcfg_lock);
+
+		pr_info(PREFIX
+		       "MMCONFIG for domain %04x [bus %02x-%02x] at %pR "
+		       "(base %#lx)\n",
+		       segment, start, end, &new->res, (unsigned long)addr);
+	}
+
+	return new;
+}
+
+struct pci_mmcfg_region *pci_mmconfig_lookup(int segment, int bus)
+{
+	struct pci_mmcfg_region *cfg;
+
+	list_for_each_entry_rcu(cfg, &pci_mmcfg_list, list)
+		if (cfg->segment == segment &&
+		    cfg->start_bus <= bus && bus <= cfg->end_bus)
+			return cfg;
+
+	return NULL;
+}
+
+/* Delete MMCFG information for host bridges */
+int pci_mmconfig_delete(u16 seg, u8 start, u8 end)
+{
+	struct pci_mmcfg_region *cfg;
+
+	mutex_lock(&pci_mmcfg_lock);
+	list_for_each_entry_rcu(cfg, &pci_mmcfg_list, list)
+		if (cfg->segment == seg && cfg->start_bus == start &&
+		    cfg->end_bus == end) {
+			list_del_rcu(&cfg->list);
+			synchronize_rcu();
+			pci_mmcfg_arch_unmap(cfg);
+			if (cfg->res.parent)
+				release_resource(&cfg->res);
+			mutex_unlock(&pci_mmcfg_lock);
+			kfree(cfg);
+			return 0;
+		}
+	mutex_unlock(&pci_mmcfg_lock);
+
+	return -ENOENT;
+}
+
+int pci_mmconfig_inject(struct pci_mmcfg_region *cfg)
+{
+	struct pci_mmcfg_region *cfg_conflict;
+	int err = 0;
+
+	mutex_lock(&pci_mmcfg_lock);
+	cfg_conflict = pci_mmconfig_lookup(cfg->segment, cfg->start_bus);
+	if (cfg_conflict) {
+		if (cfg_conflict->end_bus < cfg->end_bus)
+			pr_info(FW_INFO "MMCONFIG for "
+				"domain %04x [bus %02x-%02x] "
+				"only partially covers this bridge\n",
+				cfg_conflict->segment, cfg_conflict->start_bus,
+				cfg_conflict->end_bus);
+		err = -EEXIST;
+		goto out;
+	}
+
+	if (pci_mmcfg_arch_map(cfg)) {
+		pr_warn("fail to map MMCONFIG %pR.\n", &cfg->res);
+		err = -ENOMEM;
+		goto out;
+	} else {
+		list_add_sorted(cfg);
+		pr_info("MMCONFIG at %pR (base %#lx)\n",
+			&cfg->res, (unsigned long)cfg->address);
+
+	}
+out:
+	mutex_unlock(&pci_mmcfg_lock);
+	return err;
+}
diff --git a/drivers/xen/pci.c b/drivers/xen/pci.c
index 95ee430..7a34a72 100644
--- a/drivers/xen/pci.c
+++ b/drivers/xen/pci.c
@@ -19,6 +19,7 @@
 
 #include <linux/pci.h>
 #include <linux/acpi.h>
+#include <linux/ecam.h>
 #include <xen/xen.h>
 #include <xen/interface/physdev.h>
 #include <xen/interface/xen.h>
diff --git a/include/linux/ecam.h b/include/linux/ecam.h
new file mode 100644
index 0000000..2387df5
--- /dev/null
+++ b/include/linux/ecam.h
@@ -0,0 +1,51 @@
+#ifndef __ECAM_H
+#define __ECAM_H
+#ifdef __KERNEL__
+
+#include <linux/types.h>
+#include <linux/acpi.h>
+
+/* "PCI MMCONFIG %04x [bus %02x-%02x]" */
+#define PCI_MMCFG_RESOURCE_NAME_LEN (22 + 4 + 2 + 2)
+
+struct pci_mmcfg_region {
+	struct list_head list;
+	struct resource res;
+	u64 address;
+	char __iomem *virt;
+	u16 segment;
+	u8 start_bus;
+	u8 end_bus;
+	char name[PCI_MMCFG_RESOURCE_NAME_LEN];
+};
+
+struct pci_mmcfg_mmio_ops {
+	u32 (*read)(int len, void __iomem *addr);
+	void (*write)(int len, void __iomem *addr, u32 value);
+};
+
+struct pci_mmcfg_region *pci_mmconfig_lookup(int segment, int bus);
+struct pci_mmcfg_region *pci_mmconfig_alloc(int segment, int start,
+						   int end, u64 addr);
+int pci_mmconfig_inject(struct pci_mmcfg_region *cfg);
+struct pci_mmcfg_region *pci_mmconfig_add(int segment, int start,
+						 int end, u64 addr);
+void list_add_sorted(struct pci_mmcfg_region *new);
+void free_all_mmcfg(void);
+int pci_mmconfig_delete(u16 seg, u8 start, u8 end);
+
+/* Arch specific calls */
+int pci_mmcfg_arch_init(void);
+void pci_mmcfg_arch_free(void);
+int pci_mmcfg_arch_map(struct pci_mmcfg_region *cfg);
+void pci_mmcfg_arch_unmap(struct pci_mmcfg_region *cfg);
+extern u32 pci_mmio_read(int len, void __iomem *addr);
+extern void pci_mmio_write(int len, void __iomem *addr, u32 value);
+extern void pci_mmconfig_register_mmio(struct pci_mmcfg_mmio_ops *ops);
+
+extern struct list_head pci_mmcfg_list;
+
+#define PCI_MMCFG_BUS_OFFSET(bus)      ((bus) << 20)
+
+#endif  /* __KERNEL__ */
+#endif  /* __ECAM_H */
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [PATCH v4 4/9] x86, pci, acpi: Move arch-agnostic MMCONFIG (aka ECAM) and ACPI code out of arch/x86/ directory
@ 2015-03-11 14:12   ` Tomasz Nowicki
  0 siblings, 0 replies; 38+ messages in thread
From: Tomasz Nowicki @ 2015-03-11 14:12 UTC (permalink / raw)
  To: linux-arm-kernel

ECAM standard and MCFG table are architecture independent and it makes
sense to share common code across all architectures. Both are going to
corresponding files - ecam.c and mcfg.c

While we are here, rename pci_parse_mcfg to acpi_parse_mcfg.
We already have acpi_parse_mcfg prototype which is used nowhere.
At the same time, we need pci_parse_mcfg been global so acpi_parse_mcfg
can be used perfectly here.

Signed-off-by: Tomasz Nowicki <tomasz.nowicki@linaro.org>
---
 arch/x86/Kconfig               |   3 +
 arch/x86/include/asm/pci_x86.h |  33 -----
 arch/x86/pci/acpi.c            |   1 +
 arch/x86/pci/mmconfig-shared.c | 296 +----------------------------------------
 arch/x86/pci/mmconfig_32.c     |   1 +
 arch/x86/pci/mmconfig_64.c     |   1 +
 arch/x86/pci/numachip.c        |   1 +
 drivers/acpi/Makefile          |   1 +
 drivers/acpi/mcfg.c            |  81 +++++++++++
 drivers/pci/Kconfig            |   7 +
 drivers/pci/Makefile           |   5 +
 drivers/pci/ecam.c             | 245 ++++++++++++++++++++++++++++++++++
 drivers/xen/pci.c              |   1 +
 include/linux/ecam.h           |  51 +++++++
 14 files changed, 401 insertions(+), 326 deletions(-)
 create mode 100644 drivers/acpi/mcfg.c
 create mode 100644 drivers/pci/ecam.c
 create mode 100644 include/linux/ecam.h

diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index c2fb8a8..aa451bf 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -141,6 +141,7 @@ config X86
 	select ACPI_LEGACY_TABLES_LOOKUP if ACPI
 	select X86_FEATURE_NAMES if PROC_FS
 	select SRCU
+	select HAVE_PCI_ECAM
 
 config INSTRUCTION_DECODER
 	def_bool y
@@ -2276,6 +2277,7 @@ config PCI_DIRECT
 
 config PCI_MMCONFIG
 	def_bool y
+	select PCI_ECAM
 	depends on X86_32 && PCI && (ACPI || SFI) && (PCI_GOMMCONFIG || PCI_GOANY)
 
 config PCI_OLPC
@@ -2293,6 +2295,7 @@ config PCI_DOMAINS
 
 config PCI_MMCONFIG
 	bool "Support mmconfig PCI config space access"
+	select PCI_ECAM
 	depends on X86_64 && PCI && ACPI
 
 config PCI_CNB20LE_QUIRK
diff --git a/arch/x86/include/asm/pci_x86.h b/arch/x86/include/asm/pci_x86.h
index c57c225..e8a237f 100644
--- a/arch/x86/include/asm/pci_x86.h
+++ b/arch/x86/include/asm/pci_x86.h
@@ -122,41 +122,8 @@ extern int pci_legacy_init(void);
 extern void pcibios_fixup_irqs(void);
 
 /* pci-mmconfig.c */
-
-/* "PCI MMCONFIG %04x [bus %02x-%02x]" */
-#define PCI_MMCFG_RESOURCE_NAME_LEN (22 + 4 + 2 + 2)
-
-struct pci_mmcfg_region {
-	struct list_head list;
-	struct resource res;
-	u64 address;
-	char __iomem *virt;
-	u16 segment;
-	u8 start_bus;
-	u8 end_bus;
-	char name[PCI_MMCFG_RESOURCE_NAME_LEN];
-};
-
-struct pci_mmcfg_mmio_ops {
-	u32 (*read)(int len, void __iomem *addr);
-	void (*write)(int len, void __iomem *addr, u32 value);
-};
-
-extern int __init pci_mmcfg_arch_init(void);
-extern void __init pci_mmcfg_arch_free(void);
-extern int pci_mmcfg_arch_map(struct pci_mmcfg_region *cfg);
-extern void pci_mmcfg_arch_unmap(struct pci_mmcfg_region *cfg);
 extern int pci_mmconfig_insert(struct device *dev, u16 seg, u8 start, u8 end,
 			       phys_addr_t addr);
-extern int pci_mmconfig_delete(u16 seg, u8 start, u8 end);
-extern struct pci_mmcfg_region *pci_mmconfig_lookup(int segment, int bus);
-extern u32 pci_mmio_read(int len, void __iomem *addr);
-extern void pci_mmio_write(int len, void __iomem *addr, u32 value);
-extern void pci_mmconfig_register_mmio(struct pci_mmcfg_mmio_ops *ops);
-
-extern struct list_head pci_mmcfg_list;
-
-#define PCI_MMCFG_BUS_OFFSET(bus)      ((bus) << 20)
 
 /*
  * AMD Fam10h CPUs are buggy, and cannot access MMIO config space
diff --git a/arch/x86/pci/acpi.c b/arch/x86/pci/acpi.c
index 6ac2738..5dfccef 100644
--- a/arch/x86/pci/acpi.c
+++ b/arch/x86/pci/acpi.c
@@ -4,6 +4,7 @@
 #include <linux/irq.h>
 #include <linux/dmi.h>
 #include <linux/slab.h>
+#include <linux/ecam.h>
 #include <asm/numa.h>
 #include <asm/pci_x86.h>
 
diff --git a/arch/x86/pci/mmconfig-shared.c b/arch/x86/pci/mmconfig-shared.c
index 685cd4c..5064302 100644
--- a/arch/x86/pci/mmconfig-shared.c
+++ b/arch/x86/pci/mmconfig-shared.c
@@ -18,6 +18,7 @@
 #include <linux/slab.h>
 #include <linux/mutex.h>
 #include <linux/rculist.h>
+#include <linux/ecam.h>
 #include <asm/e820.h>
 #include <asm/pci_x86.h>
 #include <asm/acpi.h>
@@ -27,52 +28,6 @@
 /* Indicate if the mmcfg resources have been placed into the resource table. */
 static bool pci_mmcfg_running_state;
 static bool pci_mmcfg_arch_init_failed;
-static DEFINE_MUTEX(pci_mmcfg_lock);
-
-LIST_HEAD(pci_mmcfg_list);
-
-static u32
-pci_mmconfig_generic_read(int len, void __iomem *addr)
-{
-	u32 data = 0;
-
-	switch (len) {
-	case 1:
-		data = readb(addr);
-		break;
-	case 2:
-		data = readw(addr);
-		break;
-	case 4:
-		data = readl(addr);
-		break;
-	}
-
-	return data;
-}
-
-static void
-pci_mmconfig_generic_write(int len, void __iomem *addr, u32 value)
-{
-	switch (len) {
-	case 1:
-		writeb(value, addr);
-		break;
-	case 2:
-		writew(value, addr);
-		break;
-	case 4:
-		writel(value, addr);
-		break;
-	}
-}
-
-static struct pci_mmcfg_mmio_ops pci_mmcfg_mmio_default = {
-	.read = pci_mmconfig_generic_read,
-	.write = pci_mmconfig_generic_write,
-};
-
-static struct pci_mmcfg_mmio_ops *pci_mmcfg_mmio = &pci_mmcfg_mmio_default;
 
 static u32
 pci_mmconfig_amd_read(int len, void __iomem *addr)
@@ -115,128 +70,6 @@ static struct pci_mmcfg_mmio_ops pci_mmcfg_mmio_amd_fam10h = {
 	.write = pci_mmconfig_amd_write,
 };
 
-void
-pci_mmconfig_register_mmio(struct pci_mmcfg_mmio_ops *ops)
-{
-	pci_mmcfg_mmio = ops;
-}
-
-u32
-pci_mmio_read(int len, void __iomem *addr)
-{
-	if (!pci_mmcfg_mmio) {
-		pr_err("PCI config space has no accessors !");
-		return 0;
-	}
-
-	return pci_mmcfg_mmio->read(len, addr);
-}
-
-void
-pci_mmio_write(int len, void __iomem *addr, u32 value)
-{
-	if (!pci_mmcfg_mmio) {
-		pr_err("PCI config space has no accessors !");
-		return;
-	}
-
-	pci_mmcfg_mmio->write(len, addr, value);
-}
-
-static void __init pci_mmconfig_remove(struct pci_mmcfg_region *cfg)
-{
-	if (cfg->res.parent)
-		release_resource(&cfg->res);
-	list_del(&cfg->list);
-	kfree(cfg);
-}
-
-static void __init free_all_mmcfg(void)
-{
-	struct pci_mmcfg_region *cfg, *tmp;
-
-	pci_mmcfg_arch_free();
-	list_for_each_entry_safe(cfg, tmp, &pci_mmcfg_list, list)
-		pci_mmconfig_remove(cfg);
-}
-
-static void list_add_sorted(struct pci_mmcfg_region *new)
-{
-	struct pci_mmcfg_region *cfg;
-
-	/* keep list sorted by segment and starting bus number */
-	list_for_each_entry_rcu(cfg, &pci_mmcfg_list, list) {
-		if (cfg->segment > new->segment ||
-		    (cfg->segment == new->segment &&
-		     cfg->start_bus >= new->start_bus)) {
-			list_add_tail_rcu(&new->list, &cfg->list);
-			return;
-		}
-	}
-	list_add_tail_rcu(&new->list, &pci_mmcfg_list);
-}
-
-static struct pci_mmcfg_region *pci_mmconfig_alloc(int segment, int start,
-						   int end, u64 addr)
-{
-	struct pci_mmcfg_region *new;
-	struct resource *res;
-
-	if (addr == 0)
-		return NULL;
-
-	new = kzalloc(sizeof(*new), GFP_KERNEL);
-	if (!new)
-		return NULL;
-
-	new->address = addr;
-	new->segment = segment;
-	new->start_bus = start;
-	new->end_bus = end;
-
-	res = &new->res;
-	res->start = addr + PCI_MMCFG_BUS_OFFSET(start);
-	res->end = addr + PCI_MMCFG_BUS_OFFSET(end + 1) - 1;
-	res->flags = IORESOURCE_MEM | IORESOURCE_BUSY;
-	snprintf(new->name, PCI_MMCFG_RESOURCE_NAME_LEN,
-		 "PCI MMCONFIG %04x [bus %02x-%02x]", segment, start, end);
-	res->name = new->name;
-
-	return new;
-}
-
-static struct pci_mmcfg_region *__init pci_mmconfig_add(int segment, int start,
-							int end, u64 addr)
-{
-	struct pci_mmcfg_region *new;
-
-	new = pci_mmconfig_alloc(segment, start, end, addr);
-	if (new) {
-		mutex_lock(&pci_mmcfg_lock);
-		list_add_sorted(new);
-		mutex_unlock(&pci_mmcfg_lock);
-
-		pr_info(PREFIX
-		       "MMCONFIG for domain %04x [bus %02x-%02x] at %pR "
-		       "(base %#lx)\n",
-		       segment, start, end, &new->res, (unsigned long)addr);
-	}
-
-	return new;
-}
-
-struct pci_mmcfg_region *pci_mmconfig_lookup(int segment, int bus)
-{
-	struct pci_mmcfg_region *cfg;
-
-	list_for_each_entry_rcu(cfg, &pci_mmcfg_list, list)
-		if (cfg->segment == segment &&
-		    cfg->start_bus <= bus && bus <= cfg->end_bus)
-			return cfg;
-
-	return NULL;
-}
-
 static const char *__init pci_mmcfg_e7520(void)
 {
 	u32 win;
@@ -657,73 +490,6 @@ static void __init pci_mmcfg_reject_broken(int early)
 	}
 }
 
-static int __init acpi_mcfg_check_entry(struct acpi_table_mcfg *mcfg,
-					struct acpi_mcfg_allocation *cfg)
-{
-	int year;
-
-	if (cfg->address < 0xFFFFFFFF)
-		return 0;
-
-	if (!strncmp(mcfg->header.oem_id, "SGI", 3))
-		return 0;
-
-	if (mcfg->header.revision >= 1) {
-		if (dmi_get_date(DMI_BIOS_DATE, &year, NULL, NULL) &&
-		    year >= 2010)
-			return 0;
-	}
-
-	pr_err(PREFIX "MCFG region for %04x [bus %02x-%02x] at %#llx "
-	       "is above 4GB, ignored\n", cfg->pci_segment,
-	       cfg->start_bus_number, cfg->end_bus_number, cfg->address);
-	return -EINVAL;
-}
-
-static int __init pci_parse_mcfg(struct acpi_table_header *header)
-{
-	struct acpi_table_mcfg *mcfg;
-	struct acpi_mcfg_allocation *cfg_table, *cfg;
-	unsigned long i;
-	int entries;
-
-	if (!header)
-		return -EINVAL;
-
-	mcfg = (struct acpi_table_mcfg *)header;
-
-	/* how many config structures do we have */
-	free_all_mmcfg();
-	entries = 0;
-	i = header->length - sizeof(struct acpi_table_mcfg);
-	while (i >= sizeof(struct acpi_mcfg_allocation)) {
-		entries++;
-		i -= sizeof(struct acpi_mcfg_allocation);
-	}
-	if (entries == 0) {
-		pr_err(PREFIX "MMCONFIG has no entries\n");
-		return -ENODEV;
-	}
-
-	cfg_table = (struct acpi_mcfg_allocation *) &mcfg[1];
-	for (i = 0; i < entries; i++) {
-		cfg = &cfg_table[i];
-		if (acpi_mcfg_check_entry(mcfg, cfg)) {
-			free_all_mmcfg();
-			return -ENODEV;
-		}
-
-		if (pci_mmconfig_add(cfg->pci_segment, cfg->start_bus_number,
-				   cfg->end_bus_number, cfg->address) == NULL) {
-			pr_warn(PREFIX "no memory for MCFG entries\n");
-			free_all_mmcfg();
-			return -ENOMEM;
-		}
-	}
-
-	return 0;
-}
-
 #ifdef CONFIG_ACPI_APEI
 extern int (*arch_apei_filter_addr)(int (*func)(__u64 start, __u64 size,
 				     void *data), void *data);
@@ -782,7 +548,7 @@ void __init pci_mmcfg_early_init(void)
 		if (pci_mmcfg_check_hostbridge())
 			known_bridge = 1;
 		else
-			acpi_sfi_table_parse(ACPI_SIG_MCFG, pci_parse_mcfg);
+			acpi_sfi_table_parse(ACPI_SIG_MCFG, acpi_parse_mcfg);
 		__pci_mmcfg_init(1);
 
 		set_apei_filter();
@@ -800,7 +566,7 @@ void __init pci_mmcfg_late_init(void)
 
 	/* MMCONFIG hasn't been enabled yet, try again */
 	if (pci_probe & PCI_PROBE_MASK & ~PCI_PROBE_MMCONF) {
-		acpi_sfi_table_parse(ACPI_SIG_MCFG, pci_parse_mcfg);
+		acpi_sfi_table_parse(ACPI_SIG_MCFG, acpi_parse_mcfg);
 		__pci_mmcfg_init(0);
 	}
 }
@@ -834,39 +600,6 @@ static int __init pci_mmcfg_late_insert_resources(void)
  */
 late_initcall(pci_mmcfg_late_insert_resources);
 
-static int pci_mmconfig_inject(struct pci_mmcfg_region *cfg)
-{
-	struct pci_mmcfg_region *cfg_conflict;
-	int err = 0;
-
-	mutex_lock(&pci_mmcfg_lock);
-	cfg_conflict = pci_mmconfig_lookup(cfg->segment, cfg->start_bus);
-	if (cfg_conflict) {
-		if (cfg_conflict->end_bus < cfg->end_bus)
-			pr_info(FW_INFO "MMCONFIG for "
-				"domain %04x [bus %02x-%02x] "
-				"only partially covers this bridge\n",
-				cfg_conflict->segment, cfg_conflict->start_bus,
-				cfg_conflict->end_bus);
-		err = -EEXIST;
-		goto out;
-	}
-
-	if (pci_mmcfg_arch_map(cfg)) {
-		pr_warn("fail to map MMCONFIG %pR.\n", &cfg->res);
-		err = -ENOMEM;
-		goto out;
-	} else {
-		list_add_sorted(cfg);
-		pr_info("MMCONFIG at %pR (base %#lx)\n",
-			&cfg->res, (unsigned long)cfg->address);
-
-	}
-out:
-	mutex_unlock(&pci_mmcfg_lock);
-	return err;
-}
-
 /* Add MMCFG information for host bridges */
 int pci_mmconfig_insert(struct device *dev, u16 seg, u8 start, u8 end,
 			phys_addr_t addr)
@@ -915,26 +648,3 @@ error:
 	kfree(cfg);
 	return rc;
 }
-
-/* Delete MMCFG information for host bridges */
-int pci_mmconfig_delete(u16 seg, u8 start, u8 end)
-{
-	struct pci_mmcfg_region *cfg;
-
-	mutex_lock(&pci_mmcfg_lock);
-	list_for_each_entry_rcu(cfg, &pci_mmcfg_list, list)
-		if (cfg->segment == seg && cfg->start_bus == start &&
-		    cfg->end_bus == end) {
-			list_del_rcu(&cfg->list);
-			synchronize_rcu();
-			pci_mmcfg_arch_unmap(cfg);
-			if (cfg->res.parent)
-				release_resource(&cfg->res);
-			mutex_unlock(&pci_mmcfg_lock);
-			kfree(cfg);
-			return 0;
-		}
-	mutex_unlock(&pci_mmcfg_lock);
-
-	return -ENOENT;
-}
diff --git a/arch/x86/pci/mmconfig_32.c b/arch/x86/pci/mmconfig_32.c
index 4b3d025..5cf6291 100644
--- a/arch/x86/pci/mmconfig_32.c
+++ b/arch/x86/pci/mmconfig_32.c
@@ -12,6 +12,7 @@
 #include <linux/pci.h>
 #include <linux/init.h>
 #include <linux/rcupdate.h>
+#include <linux/ecam.h>
 #include <asm/e820.h>
 #include <asm/pci_x86.h>
 
diff --git a/arch/x86/pci/mmconfig_64.c b/arch/x86/pci/mmconfig_64.c
index 032593d..b62ff18 100644
--- a/arch/x86/pci/mmconfig_64.c
+++ b/arch/x86/pci/mmconfig_64.c
@@ -10,6 +10,7 @@
 #include <linux/acpi.h>
 #include <linux/bitmap.h>
 #include <linux/rcupdate.h>
+#include <linux/ecam.h>
 #include <asm/e820.h>
 #include <asm/pci_x86.h>
 
diff --git a/arch/x86/pci/numachip.c b/arch/x86/pci/numachip.c
index 5047e9b..01868b6 100644
--- a/arch/x86/pci/numachip.c
+++ b/arch/x86/pci/numachip.c
@@ -13,6 +13,7 @@
  *
  */
 
+#include <linux/ecam.h>
 #include <linux/pci.h>
 #include <asm/pci_x86.h>
 
diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile
index 623b117..39498a1 100644
--- a/drivers/acpi/Makefile
+++ b/drivers/acpi/Makefile
@@ -67,6 +67,7 @@ obj-$(CONFIG_ACPI_BUTTON)	+= button.o
 obj-$(CONFIG_ACPI_FAN)		+= fan.o
 obj-$(CONFIG_ACPI_VIDEO)	+= video.o
 obj-$(CONFIG_ACPI_PCI_SLOT)	+= pci_slot.o
+obj-$(CONFIG_PCI_MMCONFIG)	+= mcfg.o
 obj-$(CONFIG_ACPI_PROCESSOR)	+= processor.o
 obj-y				+= container.o
 obj-$(CONFIG_ACPI_THERMAL)	+= thermal.o
diff --git a/drivers/acpi/mcfg.c b/drivers/acpi/mcfg.c
new file mode 100644
index 0000000..a2e2326
--- /dev/null
+++ b/drivers/acpi/mcfg.c
@@ -0,0 +1,81 @@
+/*
+ * MCFG ACPI table parser.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/acpi.h>
+#include <linux/dmi.h>
+#include <linux/ecam.h>
+
+#define	PREFIX	"MCFG: "
+
+static int __init acpi_mcfg_check_entry(struct acpi_table_mcfg *mcfg,
+					struct acpi_mcfg_allocation *cfg)
+{
+	int year;
+
+	if (cfg->address < 0xFFFFFFFF)
+		return 0;
+
+	if (!strncmp(mcfg->header.oem_id, "SGI", 3))
+		return 0;
+
+	if (mcfg->header.revision >= 1) {
+		if (dmi_get_date(DMI_BIOS_DATE, &year, NULL, NULL) &&
+		    year >= 2010)
+			return 0;
+	}
+
+	pr_err(PREFIX "MCFG region for %04x [bus %02x-%02x] at %#llx "
+	       "is above 4GB, ignored\n", cfg->pci_segment,
+	       cfg->start_bus_number, cfg->end_bus_number, cfg->address);
+	return -EINVAL;
+}
+
+int __init acpi_parse_mcfg(struct acpi_table_header *header)
+{
+	struct acpi_table_mcfg *mcfg;
+	struct acpi_mcfg_allocation *cfg_table, *cfg;
+	unsigned long i;
+	int entries;
+
+	if (!header)
+		return -EINVAL;
+
+	mcfg = (struct acpi_table_mcfg *)header;
+
+	/* how many config structures do we have */
+	free_all_mmcfg();
+	entries = 0;
+	i = header->length - sizeof(struct acpi_table_mcfg);
+	while (i >= sizeof(struct acpi_mcfg_allocation)) {
+		entries++;
+		i -= sizeof(struct acpi_mcfg_allocation);
+	}
+	if (entries == 0) {
+		pr_err(PREFIX "MCFG table has no entries\n");
+		return -ENODEV;
+	}
+
+	cfg_table = (struct acpi_mcfg_allocation *) &mcfg[1];
+	for (i = 0; i < entries; i++) {
+		cfg = &cfg_table[i];
+		if (acpi_mcfg_check_entry(mcfg, cfg)) {
+			free_all_mmcfg();
+			return -ENODEV;
+		}
+
+		if (pci_mmconfig_add(cfg->pci_segment, cfg->start_bus_number,
+				   cfg->end_bus_number, cfg->address) == NULL) {
+			pr_warn(PREFIX "no memory for MCFG entries\n");
+			free_all_mmcfg();
+			return -ENOMEM;
+		}
+	}
+
+	return 0;
+}
diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig
index 7a8f1c5..90a5fb9 100644
--- a/drivers/pci/Kconfig
+++ b/drivers/pci/Kconfig
@@ -22,6 +22,13 @@ config PCI_MSI_IRQ_DOMAIN
 	depends on PCI_MSI
 	select GENERIC_MSI_IRQ_DOMAIN
 
+config PCI_ECAM
+	bool "Enhanced Configuration Access Mechanism (ECAM)"
+	depends on PCI && HAVE_PCI_ECAM
+
+config HAVE_PCI_ECAM
+	bool
+
 config PCI_DEBUG
 	bool "PCI Debugging"
 	depends on PCI && DEBUG_KERNEL
diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile
index 73e4af4..ce7b630 100644
--- a/drivers/pci/Makefile
+++ b/drivers/pci/Makefile
@@ -41,6 +41,11 @@ obj-$(CONFIG_SPARC_LEON) += setup-irq.o
 obj-$(CONFIG_M68K) += setup-irq.o
 
 #
+# Enhanced Configuration Access Mechanism (ECAM)
+#
+obj-$(CONFIG_PCI_ECAM)	+= ecam.o
+
+#
 # ACPI Related PCI FW Functions
 # ACPI _DSM provided firmware instance and string name
 #
diff --git a/drivers/pci/ecam.c b/drivers/pci/ecam.c
new file mode 100644
index 0000000..c588234
--- /dev/null
+++ b/drivers/pci/ecam.c
@@ -0,0 +1,245 @@
+/*
+ * Arch agnostic direct PCI config space access via
+ * ECAM (Enhanced Configuration Access Mechanism)
+ *
+ * Per-architecture code takes care of the mappings, region validation and
+ * accesses themselves.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/mutex.h>
+#include <linux/rculist.h>
+#include <linux/ecam.h>
+
+#include <asm/io.h>
+
+#define PREFIX "PCI: "
+
+static DEFINE_MUTEX(pci_mmcfg_lock);
+
+LIST_HEAD(pci_mmcfg_list);
+
+static u32
+pci_mmconfig_generic_read(int len, void __iomem *addr)
+{
+	u32 data = 0;
+
+	switch (len) {
+	case 1:
+		data = readb(addr);
+		break;
+	case 2:
+		data = readw(addr);
+		break;
+	case 4:
+		data = readl(addr);
+		break;
+	}
+
+	return data;
+}
+
+static void
+pci_mmconfig_generic_write(int len, void __iomem *addr, u32 value)
+{
+	switch (len) {
+	case 1:
+		writeb(value, addr);
+		break;
+	case 2:
+		writew(value, addr);
+		break;
+	case 4:
+		writel(value, addr);
+		break;
+	}
+}
+
+static struct pci_mmcfg_mmio_ops pci_mmcfg_mmio_default = {
+	.read = pci_mmconfig_generic_read,
+	.write = pci_mmconfig_generic_write,
+};
+
+static struct pci_mmcfg_mmio_ops *pci_mmcfg_mmio = &pci_mmcfg_mmio_default;
+
+void
+pci_mmconfig_register_mmio(struct pci_mmcfg_mmio_ops *ops)
+{
+	pci_mmcfg_mmio = ops;
+}
+
+u32
+pci_mmio_read(int len, void __iomem *addr)
+{
+	if (!pci_mmcfg_mmio) {
+		pr_err("PCI config space has no accessors !");
+		return 0;
+	}
+
+	return pci_mmcfg_mmio->read(len, addr);
+}
+
+void
+pci_mmio_write(int len, void __iomem *addr, u32 value)
+{
+	if (!pci_mmcfg_mmio) {
+		pr_err("PCI config space has no accessors !");
+		return;
+	}
+
+	pci_mmcfg_mmio->write(len, addr, value);
+}
+
+static void __init pci_mmconfig_remove(struct pci_mmcfg_region *cfg)
+{
+	if (cfg->res.parent)
+		release_resource(&cfg->res);
+	list_del(&cfg->list);
+	kfree(cfg);
+}
+
+void __init free_all_mmcfg(void)
+{
+	struct pci_mmcfg_region *cfg, *tmp;
+
+	pci_mmcfg_arch_free();
+	list_for_each_entry_safe(cfg, tmp, &pci_mmcfg_list, list)
+		pci_mmconfig_remove(cfg);
+}
+
+void list_add_sorted(struct pci_mmcfg_region *new)
+{
+	struct pci_mmcfg_region *cfg;
+
+	/* keep list sorted by segment and starting bus number */
+	list_for_each_entry_rcu(cfg, &pci_mmcfg_list, list) {
+		if (cfg->segment > new->segment ||
+		    (cfg->segment == new->segment &&
+		     cfg->start_bus >= new->start_bus)) {
+			list_add_tail_rcu(&new->list, &cfg->list);
+			return;
+		}
+	}
+	list_add_tail_rcu(&new->list, &pci_mmcfg_list);
+}
+
+struct pci_mmcfg_region *pci_mmconfig_alloc(int segment, int start,
+					    int end, u64 addr)
+{
+	struct pci_mmcfg_region *new;
+	struct resource *res;
+
+	if (addr == 0)
+		return NULL;
+
+	new = kzalloc(sizeof(*new), GFP_KERNEL);
+	if (!new)
+		return NULL;
+
+	new->address = addr;
+	new->segment = segment;
+	new->start_bus = start;
+	new->end_bus = end;
+
+	res = &new->res;
+	res->start = addr + PCI_MMCFG_BUS_OFFSET(start);
+	res->end = addr + PCI_MMCFG_BUS_OFFSET(end + 1) - 1;
+	res->flags = IORESOURCE_MEM | IORESOURCE_BUSY;
+	snprintf(new->name, PCI_MMCFG_RESOURCE_NAME_LEN,
+		 "PCI MMCONFIG %04x [bus %02x-%02x]", segment, start, end);
+	res->name = new->name;
+
+	return new;
+}
+
+struct pci_mmcfg_region *pci_mmconfig_add(int segment, int start,
+					  int end, u64 addr)
+{
+	struct pci_mmcfg_region *new;
+
+	new = pci_mmconfig_alloc(segment, start, end, addr);
+	if (new) {
+		mutex_lock(&pci_mmcfg_lock);
+		list_add_sorted(new);
+		mutex_unlock(&pci_mmcfg_lock);
+
+		pr_info(PREFIX
+		       "MMCONFIG for domain %04x [bus %02x-%02x] at %pR "
+		       "(base %#lx)\n",
+		       segment, start, end, &new->res, (unsigned long)addr);
+	}
+
+	return new;
+}
+
+struct pci_mmcfg_region *pci_mmconfig_lookup(int segment, int bus)
+{
+	struct pci_mmcfg_region *cfg;
+
+	list_for_each_entry_rcu(cfg, &pci_mmcfg_list, list)
+		if (cfg->segment == segment &&
+		    cfg->start_bus <= bus && bus <= cfg->end_bus)
+			return cfg;
+
+	return NULL;
+}
+
+/* Delete MMCFG information for host bridges */
+int pci_mmconfig_delete(u16 seg, u8 start, u8 end)
+{
+	struct pci_mmcfg_region *cfg;
+
+	mutex_lock(&pci_mmcfg_lock);
+	list_for_each_entry_rcu(cfg, &pci_mmcfg_list, list)
+		if (cfg->segment == seg && cfg->start_bus == start &&
+		    cfg->end_bus == end) {
+			list_del_rcu(&cfg->list);
+			synchronize_rcu();
+			pci_mmcfg_arch_unmap(cfg);
+			if (cfg->res.parent)
+				release_resource(&cfg->res);
+			mutex_unlock(&pci_mmcfg_lock);
+			kfree(cfg);
+			return 0;
+		}
+	mutex_unlock(&pci_mmcfg_lock);
+
+	return -ENOENT;
+}
+
+int pci_mmconfig_inject(struct pci_mmcfg_region *cfg)
+{
+	struct pci_mmcfg_region *cfg_conflict;
+	int err = 0;
+
+	mutex_lock(&pci_mmcfg_lock);
+	cfg_conflict = pci_mmconfig_lookup(cfg->segment, cfg->start_bus);
+	if (cfg_conflict) {
+		if (cfg_conflict->end_bus < cfg->end_bus)
+			pr_info(FW_INFO "MMCONFIG for "
+				"domain %04x [bus %02x-%02x] "
+				"only partially covers this bridge\n",
+				cfg_conflict->segment, cfg_conflict->start_bus,
+				cfg_conflict->end_bus);
+		err = -EEXIST;
+		goto out;
+	}
+
+	if (pci_mmcfg_arch_map(cfg)) {
+		pr_warn("fail to map MMCONFIG %pR.\n", &cfg->res);
+		err = -ENOMEM;
+		goto out;
+	} else {
+		list_add_sorted(cfg);
+		pr_info("MMCONFIG at %pR (base %#lx)\n",
+			&cfg->res, (unsigned long)cfg->address);
+
+	}
+out:
+	mutex_unlock(&pci_mmcfg_lock);
+	return err;
+}
diff --git a/drivers/xen/pci.c b/drivers/xen/pci.c
index 95ee430..7a34a72 100644
--- a/drivers/xen/pci.c
+++ b/drivers/xen/pci.c
@@ -19,6 +19,7 @@
 
 #include <linux/pci.h>
 #include <linux/acpi.h>
+#include <linux/ecam.h>
 #include <xen/xen.h>
 #include <xen/interface/physdev.h>
 #include <xen/interface/xen.h>
diff --git a/include/linux/ecam.h b/include/linux/ecam.h
new file mode 100644
index 0000000..2387df5
--- /dev/null
+++ b/include/linux/ecam.h
@@ -0,0 +1,51 @@
+#ifndef __ECAM_H
+#define __ECAM_H
+#ifdef __KERNEL__
+
+#include <linux/types.h>
+#include <linux/acpi.h>
+
+/* "PCI MMCONFIG %04x [bus %02x-%02x]" */
+#define PCI_MMCFG_RESOURCE_NAME_LEN (22 + 4 + 2 + 2)
+
+struct pci_mmcfg_region {
+	struct list_head list;
+	struct resource res;
+	u64 address;
+	char __iomem *virt;
+	u16 segment;
+	u8 start_bus;
+	u8 end_bus;
+	char name[PCI_MMCFG_RESOURCE_NAME_LEN];
+};
+
+struct pci_mmcfg_mmio_ops {
+	u32 (*read)(int len, void __iomem *addr);
+	void (*write)(int len, void __iomem *addr, u32 value);
+};
+
+struct pci_mmcfg_region *pci_mmconfig_lookup(int segment, int bus);
+struct pci_mmcfg_region *pci_mmconfig_alloc(int segment, int start,
+						   int end, u64 addr);
+int pci_mmconfig_inject(struct pci_mmcfg_region *cfg);
+struct pci_mmcfg_region *pci_mmconfig_add(int segment, int start,
+						 int end, u64 addr);
+void list_add_sorted(struct pci_mmcfg_region *new);
+void free_all_mmcfg(void);
+int pci_mmconfig_delete(u16 seg, u8 start, u8 end);
+
+/* Arch specific calls */
+int pci_mmcfg_arch_init(void);
+void pci_mmcfg_arch_free(void);
+int pci_mmcfg_arch_map(struct pci_mmcfg_region *cfg);
+void pci_mmcfg_arch_unmap(struct pci_mmcfg_region *cfg);
+extern u32 pci_mmio_read(int len, void __iomem *addr);
+extern void pci_mmio_write(int len, void __iomem *addr, u32 value);
+extern void pci_mmconfig_register_mmio(struct pci_mmcfg_mmio_ops *ops);
+
+extern struct list_head pci_mmcfg_list;
+
+#define PCI_MMCFG_BUS_OFFSET(bus)      ((bus) << 20)
+
+#endif  /* __KERNEL__ */
+#endif  /* __ECAM_H */
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [PATCH v4 5/9] pci, acpi, mcfg: Provide generic implementation of MCFG code initialization.
  2015-03-11 14:12 ` Tomasz Nowicki
@ 2015-03-11 14:12   ` Tomasz Nowicki
  -1 siblings, 0 replies; 38+ messages in thread
From: Tomasz Nowicki @ 2015-03-11 14:12 UTC (permalink / raw)
  To: bhelgaas, wangyijing, arnd, hanjun.guo, Liviu.Dudau, tglx, mingo,
	hpa, rjw, al.stone
  Cc: linux-arm-kernel, linux-kernel, x86, linux-pci, linux-acpi,
	linaro-acpi, Tomasz Nowicki

Those two functions are required by ACPI subsystem to make PCI config
space accessible. Generic code assume to do nothing for early init call but
late init call does as follow:
- parse MCFG table and add regions to ECAM resource list
- map regions
- add regions to iomem_resource

Signed-off-by: Tomasz Nowicki <tomasz.nowicki@linaro.org>
---
 drivers/acpi/mcfg.c | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

diff --git a/drivers/acpi/mcfg.c b/drivers/acpi/mcfg.c
index a2e2326..1e646fc 100644
--- a/drivers/acpi/mcfg.c
+++ b/drivers/acpi/mcfg.c
@@ -79,3 +79,23 @@ int __init acpi_parse_mcfg(struct acpi_table_header *header)
 
 	return 0;
 }
+
+void __init __weak pci_mmcfg_early_init(void)
+{
+
+}
+
+void __init __weak pci_mmcfg_late_init(void)
+{
+	struct pci_mmcfg_region *cfg;
+
+	acpi_table_parse(ACPI_SIG_MCFG, acpi_parse_mcfg);
+
+	if (list_empty(&pci_mmcfg_list))
+		return;
+	if (!pci_mmcfg_arch_init())
+		free_all_mmcfg();
+
+	list_for_each_entry(cfg, &pci_mmcfg_list, list)
+		insert_resource(&iomem_resource, &cfg->res);
+}
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [PATCH v4 5/9] pci, acpi, mcfg: Provide generic implementation of MCFG code initialization.
@ 2015-03-11 14:12   ` Tomasz Nowicki
  0 siblings, 0 replies; 38+ messages in thread
From: Tomasz Nowicki @ 2015-03-11 14:12 UTC (permalink / raw)
  To: linux-arm-kernel

Those two functions are required by ACPI subsystem to make PCI config
space accessible. Generic code assume to do nothing for early init call but
late init call does as follow:
- parse MCFG table and add regions to ECAM resource list
- map regions
- add regions to iomem_resource

Signed-off-by: Tomasz Nowicki <tomasz.nowicki@linaro.org>
---
 drivers/acpi/mcfg.c | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

diff --git a/drivers/acpi/mcfg.c b/drivers/acpi/mcfg.c
index a2e2326..1e646fc 100644
--- a/drivers/acpi/mcfg.c
+++ b/drivers/acpi/mcfg.c
@@ -79,3 +79,23 @@ int __init acpi_parse_mcfg(struct acpi_table_header *header)
 
 	return 0;
 }
+
+void __init __weak pci_mmcfg_early_init(void)
+{
+
+}
+
+void __init __weak pci_mmcfg_late_init(void)
+{
+	struct pci_mmcfg_region *cfg;
+
+	acpi_table_parse(ACPI_SIG_MCFG, acpi_parse_mcfg);
+
+	if (list_empty(&pci_mmcfg_list))
+		return;
+	if (!pci_mmcfg_arch_init())
+		free_all_mmcfg();
+
+	list_for_each_entry(cfg, &pci_mmcfg_list, list)
+		insert_resource(&iomem_resource, &cfg->res);
+}
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [PATCH v4 6/9] x86, pci: mmconfig_{32,64}.c code refactoring - remove code duplication.
  2015-03-11 14:12 ` Tomasz Nowicki
@ 2015-03-11 14:12   ` Tomasz Nowicki
  -1 siblings, 0 replies; 38+ messages in thread
From: Tomasz Nowicki @ 2015-03-11 14:12 UTC (permalink / raw)
  To: bhelgaas, wangyijing, arnd, hanjun.guo, Liviu.Dudau, tglx, mingo,
	hpa, rjw, al.stone
  Cc: linux-arm-kernel, linux-kernel, x86, linux-pci, linux-acpi,
	linaro-acpi, Tomasz Nowicki

mmconfig_64.c version is going to be default implementation for arch
agnostic low-level direct PCI config space accessors for ECAM dirver.
However, now it initialize raw_pci_ext_ops pointer which is x86 specific
code only. Moreover, mmconfig_32.c is doing the same thing at the same time.

Move it to mmconfig_shared.c so it becomes common for both and
mmconfig_64.c turns out to be purely arch agnostic.

Signed-off-by: Tomasz Nowicki <tomasz.nowicki@linaro.org>
---
 arch/x86/pci/mmconfig-shared.c | 10 ++++++++--
 arch/x86/pci/mmconfig_32.c     | 10 ++--------
 arch/x86/pci/mmconfig_64.c     | 11 ++---------
 include/linux/ecam.h           |  5 +++++
 4 files changed, 17 insertions(+), 19 deletions(-)

diff --git a/arch/x86/pci/mmconfig-shared.c b/arch/x86/pci/mmconfig-shared.c
index 5064302..6dfe614 100644
--- a/arch/x86/pci/mmconfig-shared.c
+++ b/arch/x86/pci/mmconfig-shared.c
@@ -29,6 +29,11 @@
 static bool pci_mmcfg_running_state;
 static bool pci_mmcfg_arch_init_failed;
 
+const struct pci_raw_ops pci_mmcfg = {
+	.read =		pci_mmcfg_read,
+	.write =	pci_mmcfg_write,
+};
+
 static u32
 pci_mmconfig_amd_read(int len, void __iomem *addr)
 {
@@ -532,9 +537,10 @@ static void __init __pci_mmcfg_init(int early)
 		}
 	}
 
-	if (pci_mmcfg_arch_init())
+	if (pci_mmcfg_arch_init()) {
+		raw_pci_ext_ops = &pci_mmcfg;
 		pci_probe = (pci_probe & ~PCI_PROBE_MASK) | PCI_PROBE_MMCONF;
-	else {
+	} else {
 		free_all_mmcfg();
 		pci_mmcfg_arch_init_failed = true;
 	}
diff --git a/arch/x86/pci/mmconfig_32.c b/arch/x86/pci/mmconfig_32.c
index 5cf6291..7a050cb 100644
--- a/arch/x86/pci/mmconfig_32.c
+++ b/arch/x86/pci/mmconfig_32.c
@@ -50,7 +50,7 @@ static void pci_exp_set_dev_base(unsigned int base, int bus, int devfn)
 	}
 }
 
-static int pci_mmcfg_read(unsigned int seg, unsigned int bus,
+int pci_mmcfg_read(unsigned int seg, unsigned int bus,
 			  unsigned int devfn, int reg, int len, u32 *value)
 {
 	unsigned long flags;
@@ -79,7 +79,7 @@ err:		*value = -1;
 	return 0;
 }
 
-static int pci_mmcfg_write(unsigned int seg, unsigned int bus,
+int pci_mmcfg_write(unsigned int seg, unsigned int bus,
 			   unsigned int devfn, int reg, int len, u32 value)
 {
 	unsigned long flags;
@@ -106,15 +106,9 @@ static int pci_mmcfg_write(unsigned int seg, unsigned int bus,
 	return 0;
 }
 
-const struct pci_raw_ops pci_mmcfg = {
-	.read =		pci_mmcfg_read,
-	.write =	pci_mmcfg_write,
-};
-
 int __init pci_mmcfg_arch_init(void)
 {
 	printk(KERN_INFO "PCI: Using MMCONFIG for extended config space\n");
-	raw_pci_ext_ops = &pci_mmcfg;
 	return 1;
 }
 
diff --git a/arch/x86/pci/mmconfig_64.c b/arch/x86/pci/mmconfig_64.c
index b62ff18..fd857ea 100644
--- a/arch/x86/pci/mmconfig_64.c
+++ b/arch/x86/pci/mmconfig_64.c
@@ -25,7 +25,7 @@ static char __iomem *pci_dev_base(unsigned int seg, unsigned int bus, unsigned i
 	return NULL;
 }
 
-static int pci_mmcfg_read(unsigned int seg, unsigned int bus,
+int pci_mmcfg_read(unsigned int seg, unsigned int bus,
 			  unsigned int devfn, int reg, int len, u32 *value)
 {
 	char __iomem *addr;
@@ -49,7 +49,7 @@ err:		*value = -1;
 	return 0;
 }
 
-static int pci_mmcfg_write(unsigned int seg, unsigned int bus,
+int pci_mmcfg_write(unsigned int seg, unsigned int bus,
 			   unsigned int devfn, int reg, int len, u32 value)
 {
 	char __iomem *addr;
@@ -71,11 +71,6 @@ static int pci_mmcfg_write(unsigned int seg, unsigned int bus,
 	return 0;
 }
 
-const struct pci_raw_ops pci_mmcfg = {
-	.read =		pci_mmcfg_read,
-	.write =	pci_mmcfg_write,
-};
-
 static void __iomem *mcfg_ioremap(struct pci_mmcfg_region *cfg)
 {
 	void __iomem *addr;
@@ -101,8 +96,6 @@ int __init pci_mmcfg_arch_init(void)
 			return 0;
 		}
 
-	raw_pci_ext_ops = &pci_mmcfg;
-
 	return 1;
 }
 
diff --git a/include/linux/ecam.h b/include/linux/ecam.h
index 2387df5..fba5d6b 100644
--- a/include/linux/ecam.h
+++ b/include/linux/ecam.h
@@ -47,5 +47,10 @@ extern struct list_head pci_mmcfg_list;
 
 #define PCI_MMCFG_BUS_OFFSET(bus)      ((bus) << 20)
 
+int pci_mmcfg_read(unsigned int seg, unsigned int bus,
+		   unsigned int devfn, int reg, int len, u32 *value);
+int pci_mmcfg_write(unsigned int seg, unsigned int bus,
+		    unsigned int devfn, int reg, int len, u32 value);
+
 #endif  /* __KERNEL__ */
 #endif  /* __ECAM_H */
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [PATCH v4 6/9] x86, pci: mmconfig_{32, 64}.c code refactoring - remove code duplication.
@ 2015-03-11 14:12   ` Tomasz Nowicki
  0 siblings, 0 replies; 38+ messages in thread
From: Tomasz Nowicki @ 2015-03-11 14:12 UTC (permalink / raw)
  To: linux-arm-kernel

mmconfig_64.c version is going to be default implementation for arch
agnostic low-level direct PCI config space accessors for ECAM dirver.
However, now it initialize raw_pci_ext_ops pointer which is x86 specific
code only. Moreover, mmconfig_32.c is doing the same thing at the same time.

Move it to mmconfig_shared.c so it becomes common for both and
mmconfig_64.c turns out to be purely arch agnostic.

Signed-off-by: Tomasz Nowicki <tomasz.nowicki@linaro.org>
---
 arch/x86/pci/mmconfig-shared.c | 10 ++++++++--
 arch/x86/pci/mmconfig_32.c     | 10 ++--------
 arch/x86/pci/mmconfig_64.c     | 11 ++---------
 include/linux/ecam.h           |  5 +++++
 4 files changed, 17 insertions(+), 19 deletions(-)

diff --git a/arch/x86/pci/mmconfig-shared.c b/arch/x86/pci/mmconfig-shared.c
index 5064302..6dfe614 100644
--- a/arch/x86/pci/mmconfig-shared.c
+++ b/arch/x86/pci/mmconfig-shared.c
@@ -29,6 +29,11 @@
 static bool pci_mmcfg_running_state;
 static bool pci_mmcfg_arch_init_failed;
 
+const struct pci_raw_ops pci_mmcfg = {
+	.read =		pci_mmcfg_read,
+	.write =	pci_mmcfg_write,
+};
+
 static u32
 pci_mmconfig_amd_read(int len, void __iomem *addr)
 {
@@ -532,9 +537,10 @@ static void __init __pci_mmcfg_init(int early)
 		}
 	}
 
-	if (pci_mmcfg_arch_init())
+	if (pci_mmcfg_arch_init()) {
+		raw_pci_ext_ops = &pci_mmcfg;
 		pci_probe = (pci_probe & ~PCI_PROBE_MASK) | PCI_PROBE_MMCONF;
-	else {
+	} else {
 		free_all_mmcfg();
 		pci_mmcfg_arch_init_failed = true;
 	}
diff --git a/arch/x86/pci/mmconfig_32.c b/arch/x86/pci/mmconfig_32.c
index 5cf6291..7a050cb 100644
--- a/arch/x86/pci/mmconfig_32.c
+++ b/arch/x86/pci/mmconfig_32.c
@@ -50,7 +50,7 @@ static void pci_exp_set_dev_base(unsigned int base, int bus, int devfn)
 	}
 }
 
-static int pci_mmcfg_read(unsigned int seg, unsigned int bus,
+int pci_mmcfg_read(unsigned int seg, unsigned int bus,
 			  unsigned int devfn, int reg, int len, u32 *value)
 {
 	unsigned long flags;
@@ -79,7 +79,7 @@ err:		*value = -1;
 	return 0;
 }
 
-static int pci_mmcfg_write(unsigned int seg, unsigned int bus,
+int pci_mmcfg_write(unsigned int seg, unsigned int bus,
 			   unsigned int devfn, int reg, int len, u32 value)
 {
 	unsigned long flags;
@@ -106,15 +106,9 @@ static int pci_mmcfg_write(unsigned int seg, unsigned int bus,
 	return 0;
 }
 
-const struct pci_raw_ops pci_mmcfg = {
-	.read =		pci_mmcfg_read,
-	.write =	pci_mmcfg_write,
-};
-
 int __init pci_mmcfg_arch_init(void)
 {
 	printk(KERN_INFO "PCI: Using MMCONFIG for extended config space\n");
-	raw_pci_ext_ops = &pci_mmcfg;
 	return 1;
 }
 
diff --git a/arch/x86/pci/mmconfig_64.c b/arch/x86/pci/mmconfig_64.c
index b62ff18..fd857ea 100644
--- a/arch/x86/pci/mmconfig_64.c
+++ b/arch/x86/pci/mmconfig_64.c
@@ -25,7 +25,7 @@ static char __iomem *pci_dev_base(unsigned int seg, unsigned int bus, unsigned i
 	return NULL;
 }
 
-static int pci_mmcfg_read(unsigned int seg, unsigned int bus,
+int pci_mmcfg_read(unsigned int seg, unsigned int bus,
 			  unsigned int devfn, int reg, int len, u32 *value)
 {
 	char __iomem *addr;
@@ -49,7 +49,7 @@ err:		*value = -1;
 	return 0;
 }
 
-static int pci_mmcfg_write(unsigned int seg, unsigned int bus,
+int pci_mmcfg_write(unsigned int seg, unsigned int bus,
 			   unsigned int devfn, int reg, int len, u32 value)
 {
 	char __iomem *addr;
@@ -71,11 +71,6 @@ static int pci_mmcfg_write(unsigned int seg, unsigned int bus,
 	return 0;
 }
 
-const struct pci_raw_ops pci_mmcfg = {
-	.read =		pci_mmcfg_read,
-	.write =	pci_mmcfg_write,
-};
-
 static void __iomem *mcfg_ioremap(struct pci_mmcfg_region *cfg)
 {
 	void __iomem *addr;
@@ -101,8 +96,6 @@ int __init pci_mmcfg_arch_init(void)
 			return 0;
 		}
 
-	raw_pci_ext_ops = &pci_mmcfg;
-
 	return 1;
 }
 
diff --git a/include/linux/ecam.h b/include/linux/ecam.h
index 2387df5..fba5d6b 100644
--- a/include/linux/ecam.h
+++ b/include/linux/ecam.h
@@ -47,5 +47,10 @@ extern struct list_head pci_mmcfg_list;
 
 #define PCI_MMCFG_BUS_OFFSET(bus)      ((bus) << 20)
 
+int pci_mmcfg_read(unsigned int seg, unsigned int bus,
+		   unsigned int devfn, int reg, int len, u32 *value);
+int pci_mmcfg_write(unsigned int seg, unsigned int bus,
+		    unsigned int devfn, int reg, int len, u32 value);
+
 #endif  /* __KERNEL__ */
 #endif  /* __ECAM_H */
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [PATCH v4 7/9] x86, pci, ecam: mmconfig_64.c becomes default implementation for ECAM driver.
  2015-03-11 14:12 ` Tomasz Nowicki
@ 2015-03-11 14:12   ` Tomasz Nowicki
  -1 siblings, 0 replies; 38+ messages in thread
From: Tomasz Nowicki @ 2015-03-11 14:12 UTC (permalink / raw)
  To: bhelgaas, wangyijing, arnd, hanjun.guo, Liviu.Dudau, tglx, mingo,
	hpa, rjw, al.stone
  Cc: linux-arm-kernel, linux-kernel, x86, linux-pci, linux-acpi,
	linaro-acpi, Tomasz Nowicki

Architectures which want to take advantage of ECAM generic goodness
should select CONFIG_PCI_ECAM_GENERIC. Otherwise, like x86 32bits machines,
are obligated to provide own low-level ECAM calls.

Signed-off-by: Tomasz Nowicki <tomasz.nowicki@linaro.org>
---
 arch/x86/Kconfig           |   1 +
 arch/x86/pci/Makefile      |   5 +-
 arch/x86/pci/mmconfig_64.c | 127 ---------------------------------------------
 drivers/pci/Kconfig        |   3 ++
 drivers/pci/ecam.c         | 113 ++++++++++++++++++++++++++++++++++++++++
 5 files changed, 121 insertions(+), 128 deletions(-)
 delete mode 100644 arch/x86/pci/mmconfig_64.c

diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index aa451bf..3bf1aa5 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -142,6 +142,7 @@ config X86
 	select X86_FEATURE_NAMES if PROC_FS
 	select SRCU
 	select HAVE_PCI_ECAM
+	select GENERIC_PCI_ECAM if X86_64
 
 config INSTRUCTION_DECODER
 	def_bool y
diff --git a/arch/x86/pci/Makefile b/arch/x86/pci/Makefile
index 5c6fc35..35c765b 100644
--- a/arch/x86/pci/Makefile
+++ b/arch/x86/pci/Makefile
@@ -1,7 +1,10 @@
 obj-y				:= i386.o init.o
 
 obj-$(CONFIG_PCI_BIOS)		+= pcbios.o
-obj-$(CONFIG_PCI_MMCONFIG)	+= mmconfig_$(BITS).o direct.o mmconfig-shared.o
+obj-$(CONFIG_PCI_MMCONFIG)	+= direct.o mmconfig-shared.o
+ifeq ($(BITS),32)
+obj-$(CONFIG_PCI_MMCONFIG)	+= mmconfig_32.o
+endif
 obj-$(CONFIG_PCI_DIRECT)	+= direct.o
 obj-$(CONFIG_PCI_OLPC)		+= olpc.o
 obj-$(CONFIG_PCI_XEN)		+= xen.o
diff --git a/arch/x86/pci/mmconfig_64.c b/arch/x86/pci/mmconfig_64.c
deleted file mode 100644
index fd857ea..0000000
--- a/arch/x86/pci/mmconfig_64.c
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
- * mmconfig.c - Low-level direct PCI config space access via MMCONFIG
- *
- * This is an 64bit optimized version that always keeps the full mmconfig
- * space mapped. This allows lockless config space operation.
- */
-
-#include <linux/pci.h>
-#include <linux/init.h>
-#include <linux/acpi.h>
-#include <linux/bitmap.h>
-#include <linux/rcupdate.h>
-#include <linux/ecam.h>
-#include <asm/e820.h>
-#include <asm/pci_x86.h>
-
-#define PREFIX "PCI: "
-
-static char __iomem *pci_dev_base(unsigned int seg, unsigned int bus, unsigned int devfn)
-{
-	struct pci_mmcfg_region *cfg = pci_mmconfig_lookup(seg, bus);
-
-	if (cfg && cfg->virt)
-		return cfg->virt + (PCI_MMCFG_BUS_OFFSET(bus) | (devfn << 12));
-	return NULL;
-}
-
-int pci_mmcfg_read(unsigned int seg, unsigned int bus,
-			  unsigned int devfn, int reg, int len, u32 *value)
-{
-	char __iomem *addr;
-
-	/* Why do we have this when nobody checks it. How about a BUG()!? -AK */
-	if (unlikely((bus > 255) || (devfn > 255) || (reg > 4095))) {
-err:		*value = -1;
-		return -EINVAL;
-	}
-
-	rcu_read_lock();
-	addr = pci_dev_base(seg, bus, devfn);
-	if (!addr) {
-		rcu_read_unlock();
-		goto err;
-	}
-
-	*value = pci_mmio_read(len, addr + reg);
-	rcu_read_unlock();
-
-	return 0;
-}
-
-int pci_mmcfg_write(unsigned int seg, unsigned int bus,
-			   unsigned int devfn, int reg, int len, u32 value)
-{
-	char __iomem *addr;
-
-	/* Why do we have this when nobody checks it. How about a BUG()!? -AK */
-	if (unlikely((bus > 255) || (devfn > 255) || (reg > 4095)))
-		return -EINVAL;
-
-	rcu_read_lock();
-	addr = pci_dev_base(seg, bus, devfn);
-	if (!addr) {
-		rcu_read_unlock();
-		return -EINVAL;
-	}
-
-	pci_mmio_write(len, addr + reg, value);
-	rcu_read_unlock();
-
-	return 0;
-}
-
-static void __iomem *mcfg_ioremap(struct pci_mmcfg_region *cfg)
-{
-	void __iomem *addr;
-	u64 start, size;
-	int num_buses;
-
-	start = cfg->address + PCI_MMCFG_BUS_OFFSET(cfg->start_bus);
-	num_buses = cfg->end_bus - cfg->start_bus + 1;
-	size = PCI_MMCFG_BUS_OFFSET(num_buses);
-	addr = ioremap_nocache(start, size);
-	if (addr)
-		addr -= PCI_MMCFG_BUS_OFFSET(cfg->start_bus);
-	return addr;
-}
-
-int __init pci_mmcfg_arch_init(void)
-{
-	struct pci_mmcfg_region *cfg;
-
-	list_for_each_entry(cfg, &pci_mmcfg_list, list)
-		if (pci_mmcfg_arch_map(cfg)) {
-			pci_mmcfg_arch_free();
-			return 0;
-		}
-
-	return 1;
-}
-
-void __init pci_mmcfg_arch_free(void)
-{
-	struct pci_mmcfg_region *cfg;
-
-	list_for_each_entry(cfg, &pci_mmcfg_list, list)
-		pci_mmcfg_arch_unmap(cfg);
-}
-
-int pci_mmcfg_arch_map(struct pci_mmcfg_region *cfg)
-{
-	cfg->virt = mcfg_ioremap(cfg);
-	if (!cfg->virt) {
-		pr_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;
-	}
-}
diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig
index 90a5fb9..fae4aa7 100644
--- a/drivers/pci/Kconfig
+++ b/drivers/pci/Kconfig
@@ -29,6 +29,9 @@ config PCI_ECAM
 config HAVE_PCI_ECAM
 	bool
 
+config GENERIC_PCI_ECAM
+	bool
+
 config PCI_DEBUG
 	bool "PCI Debugging"
 	depends on PCI && DEBUG_KERNEL
diff --git a/drivers/pci/ecam.c b/drivers/pci/ecam.c
index c588234..796b6e7 100644
--- a/drivers/pci/ecam.c
+++ b/drivers/pci/ecam.c
@@ -23,6 +23,119 @@ static DEFINE_MUTEX(pci_mmcfg_lock);
 
 LIST_HEAD(pci_mmcfg_list);
 
+#ifdef CONFIG_GENERIC_PCI_ECAM
+static char __iomem *pci_dev_base(unsigned int seg, unsigned int bus,
+				  unsigned int devfn)
+{
+	struct pci_mmcfg_region *cfg = pci_mmconfig_lookup(seg, bus);
+
+	if (cfg && cfg->virt)
+		return cfg->virt + (PCI_MMCFG_BUS_OFFSET(bus) | (devfn << 12));
+	return NULL;
+}
+
+int pci_mmcfg_read(unsigned int seg, unsigned int bus,
+			  unsigned int devfn, int reg, int len, u32 *value)
+{
+	char __iomem *addr;
+
+	/* Why do we have this when nobody checks it. How about a BUG()!? -AK */
+	if (unlikely((bus > 255) || (devfn > 255) || (reg > 4095))) {
+err:		*value = -1;
+		return -EINVAL;
+	}
+
+	rcu_read_lock();
+	addr = pci_dev_base(seg, bus, devfn);
+	if (!addr) {
+		rcu_read_unlock();
+		goto err;
+	}
+
+	*value = pci_mmio_read(len, addr + reg);
+	rcu_read_unlock();
+
+	return 0;
+}
+
+int pci_mmcfg_write(unsigned int seg, unsigned int bus,
+			   unsigned int devfn, int reg, int len, u32 value)
+{
+	char __iomem *addr;
+
+	/* Why do we have this when nobody checks it. How about a BUG()!? -AK */
+	if (unlikely((bus > 255) || (devfn > 255) || (reg > 4095)))
+		return -EINVAL;
+
+	rcu_read_lock();
+	addr = pci_dev_base(seg, bus, devfn);
+	if (!addr) {
+		rcu_read_unlock();
+		return -EINVAL;
+	}
+
+	pci_mmio_write(len, addr + reg, value);
+	rcu_read_unlock();
+
+	return 0;
+}
+
+static void __iomem *mcfg_ioremap(struct pci_mmcfg_region *cfg)
+{
+	void __iomem *addr;
+	u64 start, size;
+	int num_buses;
+
+	start = cfg->address + PCI_MMCFG_BUS_OFFSET(cfg->start_bus);
+	num_buses = cfg->end_bus - cfg->start_bus + 1;
+	size = PCI_MMCFG_BUS_OFFSET(num_buses);
+	addr = ioremap_nocache(start, size);
+	if (addr)
+		addr -= PCI_MMCFG_BUS_OFFSET(cfg->start_bus);
+	return addr;
+}
+
+int __init pci_mmcfg_arch_init(void)
+{
+	struct pci_mmcfg_region *cfg;
+
+	list_for_each_entry(cfg, &pci_mmcfg_list, list)
+		if (pci_mmcfg_arch_map(cfg)) {
+			pci_mmcfg_arch_free();
+			return 0;
+		}
+
+	return 1;
+}
+
+void __init pci_mmcfg_arch_free(void)
+{
+	struct pci_mmcfg_region *cfg;
+
+	list_for_each_entry(cfg, &pci_mmcfg_list, list)
+		pci_mmcfg_arch_unmap(cfg);
+}
+
+int pci_mmcfg_arch_map(struct pci_mmcfg_region *cfg)
+{
+	cfg->virt = mcfg_ioremap(cfg);
+	if (!cfg->virt) {
+		pr_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;
+	}
+}
+#endif
+
 static u32
 pci_mmconfig_generic_read(int len, void __iomem *addr)
 {
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [PATCH v4 7/9] x86, pci, ecam: mmconfig_64.c becomes default implementation for ECAM driver.
@ 2015-03-11 14:12   ` Tomasz Nowicki
  0 siblings, 0 replies; 38+ messages in thread
From: Tomasz Nowicki @ 2015-03-11 14:12 UTC (permalink / raw)
  To: linux-arm-kernel

Architectures which want to take advantage of ECAM generic goodness
should select CONFIG_PCI_ECAM_GENERIC. Otherwise, like x86 32bits machines,
are obligated to provide own low-level ECAM calls.

Signed-off-by: Tomasz Nowicki <tomasz.nowicki@linaro.org>
---
 arch/x86/Kconfig           |   1 +
 arch/x86/pci/Makefile      |   5 +-
 arch/x86/pci/mmconfig_64.c | 127 ---------------------------------------------
 drivers/pci/Kconfig        |   3 ++
 drivers/pci/ecam.c         | 113 ++++++++++++++++++++++++++++++++++++++++
 5 files changed, 121 insertions(+), 128 deletions(-)
 delete mode 100644 arch/x86/pci/mmconfig_64.c

diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index aa451bf..3bf1aa5 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -142,6 +142,7 @@ config X86
 	select X86_FEATURE_NAMES if PROC_FS
 	select SRCU
 	select HAVE_PCI_ECAM
+	select GENERIC_PCI_ECAM if X86_64
 
 config INSTRUCTION_DECODER
 	def_bool y
diff --git a/arch/x86/pci/Makefile b/arch/x86/pci/Makefile
index 5c6fc35..35c765b 100644
--- a/arch/x86/pci/Makefile
+++ b/arch/x86/pci/Makefile
@@ -1,7 +1,10 @@
 obj-y				:= i386.o init.o
 
 obj-$(CONFIG_PCI_BIOS)		+= pcbios.o
-obj-$(CONFIG_PCI_MMCONFIG)	+= mmconfig_$(BITS).o direct.o mmconfig-shared.o
+obj-$(CONFIG_PCI_MMCONFIG)	+= direct.o mmconfig-shared.o
+ifeq ($(BITS),32)
+obj-$(CONFIG_PCI_MMCONFIG)	+= mmconfig_32.o
+endif
 obj-$(CONFIG_PCI_DIRECT)	+= direct.o
 obj-$(CONFIG_PCI_OLPC)		+= olpc.o
 obj-$(CONFIG_PCI_XEN)		+= xen.o
diff --git a/arch/x86/pci/mmconfig_64.c b/arch/x86/pci/mmconfig_64.c
deleted file mode 100644
index fd857ea..0000000
--- a/arch/x86/pci/mmconfig_64.c
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
- * mmconfig.c - Low-level direct PCI config space access via MMCONFIG
- *
- * This is an 64bit optimized version that always keeps the full mmconfig
- * space mapped. This allows lockless config space operation.
- */
-
-#include <linux/pci.h>
-#include <linux/init.h>
-#include <linux/acpi.h>
-#include <linux/bitmap.h>
-#include <linux/rcupdate.h>
-#include <linux/ecam.h>
-#include <asm/e820.h>
-#include <asm/pci_x86.h>
-
-#define PREFIX "PCI: "
-
-static char __iomem *pci_dev_base(unsigned int seg, unsigned int bus, unsigned int devfn)
-{
-	struct pci_mmcfg_region *cfg = pci_mmconfig_lookup(seg, bus);
-
-	if (cfg && cfg->virt)
-		return cfg->virt + (PCI_MMCFG_BUS_OFFSET(bus) | (devfn << 12));
-	return NULL;
-}
-
-int pci_mmcfg_read(unsigned int seg, unsigned int bus,
-			  unsigned int devfn, int reg, int len, u32 *value)
-{
-	char __iomem *addr;
-
-	/* Why do we have this when nobody checks it. How about a BUG()!? -AK */
-	if (unlikely((bus > 255) || (devfn > 255) || (reg > 4095))) {
-err:		*value = -1;
-		return -EINVAL;
-	}
-
-	rcu_read_lock();
-	addr = pci_dev_base(seg, bus, devfn);
-	if (!addr) {
-		rcu_read_unlock();
-		goto err;
-	}
-
-	*value = pci_mmio_read(len, addr + reg);
-	rcu_read_unlock();
-
-	return 0;
-}
-
-int pci_mmcfg_write(unsigned int seg, unsigned int bus,
-			   unsigned int devfn, int reg, int len, u32 value)
-{
-	char __iomem *addr;
-
-	/* Why do we have this when nobody checks it. How about a BUG()!? -AK */
-	if (unlikely((bus > 255) || (devfn > 255) || (reg > 4095)))
-		return -EINVAL;
-
-	rcu_read_lock();
-	addr = pci_dev_base(seg, bus, devfn);
-	if (!addr) {
-		rcu_read_unlock();
-		return -EINVAL;
-	}
-
-	pci_mmio_write(len, addr + reg, value);
-	rcu_read_unlock();
-
-	return 0;
-}
-
-static void __iomem *mcfg_ioremap(struct pci_mmcfg_region *cfg)
-{
-	void __iomem *addr;
-	u64 start, size;
-	int num_buses;
-
-	start = cfg->address + PCI_MMCFG_BUS_OFFSET(cfg->start_bus);
-	num_buses = cfg->end_bus - cfg->start_bus + 1;
-	size = PCI_MMCFG_BUS_OFFSET(num_buses);
-	addr = ioremap_nocache(start, size);
-	if (addr)
-		addr -= PCI_MMCFG_BUS_OFFSET(cfg->start_bus);
-	return addr;
-}
-
-int __init pci_mmcfg_arch_init(void)
-{
-	struct pci_mmcfg_region *cfg;
-
-	list_for_each_entry(cfg, &pci_mmcfg_list, list)
-		if (pci_mmcfg_arch_map(cfg)) {
-			pci_mmcfg_arch_free();
-			return 0;
-		}
-
-	return 1;
-}
-
-void __init pci_mmcfg_arch_free(void)
-{
-	struct pci_mmcfg_region *cfg;
-
-	list_for_each_entry(cfg, &pci_mmcfg_list, list)
-		pci_mmcfg_arch_unmap(cfg);
-}
-
-int pci_mmcfg_arch_map(struct pci_mmcfg_region *cfg)
-{
-	cfg->virt = mcfg_ioremap(cfg);
-	if (!cfg->virt) {
-		pr_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;
-	}
-}
diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig
index 90a5fb9..fae4aa7 100644
--- a/drivers/pci/Kconfig
+++ b/drivers/pci/Kconfig
@@ -29,6 +29,9 @@ config PCI_ECAM
 config HAVE_PCI_ECAM
 	bool
 
+config GENERIC_PCI_ECAM
+	bool
+
 config PCI_DEBUG
 	bool "PCI Debugging"
 	depends on PCI && DEBUG_KERNEL
diff --git a/drivers/pci/ecam.c b/drivers/pci/ecam.c
index c588234..796b6e7 100644
--- a/drivers/pci/ecam.c
+++ b/drivers/pci/ecam.c
@@ -23,6 +23,119 @@ static DEFINE_MUTEX(pci_mmcfg_lock);
 
 LIST_HEAD(pci_mmcfg_list);
 
+#ifdef CONFIG_GENERIC_PCI_ECAM
+static char __iomem *pci_dev_base(unsigned int seg, unsigned int bus,
+				  unsigned int devfn)
+{
+	struct pci_mmcfg_region *cfg = pci_mmconfig_lookup(seg, bus);
+
+	if (cfg && cfg->virt)
+		return cfg->virt + (PCI_MMCFG_BUS_OFFSET(bus) | (devfn << 12));
+	return NULL;
+}
+
+int pci_mmcfg_read(unsigned int seg, unsigned int bus,
+			  unsigned int devfn, int reg, int len, u32 *value)
+{
+	char __iomem *addr;
+
+	/* Why do we have this when nobody checks it. How about a BUG()!? -AK */
+	if (unlikely((bus > 255) || (devfn > 255) || (reg > 4095))) {
+err:		*value = -1;
+		return -EINVAL;
+	}
+
+	rcu_read_lock();
+	addr = pci_dev_base(seg, bus, devfn);
+	if (!addr) {
+		rcu_read_unlock();
+		goto err;
+	}
+
+	*value = pci_mmio_read(len, addr + reg);
+	rcu_read_unlock();
+
+	return 0;
+}
+
+int pci_mmcfg_write(unsigned int seg, unsigned int bus,
+			   unsigned int devfn, int reg, int len, u32 value)
+{
+	char __iomem *addr;
+
+	/* Why do we have this when nobody checks it. How about a BUG()!? -AK */
+	if (unlikely((bus > 255) || (devfn > 255) || (reg > 4095)))
+		return -EINVAL;
+
+	rcu_read_lock();
+	addr = pci_dev_base(seg, bus, devfn);
+	if (!addr) {
+		rcu_read_unlock();
+		return -EINVAL;
+	}
+
+	pci_mmio_write(len, addr + reg, value);
+	rcu_read_unlock();
+
+	return 0;
+}
+
+static void __iomem *mcfg_ioremap(struct pci_mmcfg_region *cfg)
+{
+	void __iomem *addr;
+	u64 start, size;
+	int num_buses;
+
+	start = cfg->address + PCI_MMCFG_BUS_OFFSET(cfg->start_bus);
+	num_buses = cfg->end_bus - cfg->start_bus + 1;
+	size = PCI_MMCFG_BUS_OFFSET(num_buses);
+	addr = ioremap_nocache(start, size);
+	if (addr)
+		addr -= PCI_MMCFG_BUS_OFFSET(cfg->start_bus);
+	return addr;
+}
+
+int __init pci_mmcfg_arch_init(void)
+{
+	struct pci_mmcfg_region *cfg;
+
+	list_for_each_entry(cfg, &pci_mmcfg_list, list)
+		if (pci_mmcfg_arch_map(cfg)) {
+			pci_mmcfg_arch_free();
+			return 0;
+		}
+
+	return 1;
+}
+
+void __init pci_mmcfg_arch_free(void)
+{
+	struct pci_mmcfg_region *cfg;
+
+	list_for_each_entry(cfg, &pci_mmcfg_list, list)
+		pci_mmcfg_arch_unmap(cfg);
+}
+
+int pci_mmcfg_arch_map(struct pci_mmcfg_region *cfg)
+{
+	cfg->virt = mcfg_ioremap(cfg);
+	if (!cfg->virt) {
+		pr_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;
+	}
+}
+#endif
+
 static u32
 pci_mmconfig_generic_read(int len, void __iomem *addr)
 {
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [PATCH v4 8/9] pci, acpi, mcfg: Share ACPI PCI config space accessors.
  2015-03-11 14:12 ` Tomasz Nowicki
@ 2015-03-11 14:12   ` Tomasz Nowicki
  -1 siblings, 0 replies; 38+ messages in thread
From: Tomasz Nowicki @ 2015-03-11 14:12 UTC (permalink / raw)
  To: bhelgaas, wangyijing, arnd, hanjun.guo, Liviu.Dudau, tglx, mingo,
	hpa, rjw, al.stone
  Cc: linux-arm-kernel, linux-kernel, x86, linux-pci, linux-acpi,
	linaro-acpi, Tomasz Nowicki

MCFG can be used perfectly for all architectures which support ACPI.
ACPI mandates MCFG to describe PCI config space ranges which means
we should use MMCONFIG accessors by default.

Signed-off-by: Tomasz Nowicki <tomasz.nowicki@linaro.org>
---
 drivers/acpi/mcfg.c | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

diff --git a/drivers/acpi/mcfg.c b/drivers/acpi/mcfg.c
index 1e646fc..e285f62 100644
--- a/drivers/acpi/mcfg.c
+++ b/drivers/acpi/mcfg.c
@@ -13,6 +13,26 @@
 
 #define	PREFIX	"MCFG: "
 
+/*
+ * raw_pci_read/write - ACPI PCI config space accessors.
+ *
+ * ACPI spec defines MCFG table as the way we can describe access to PCI config
+ * space, so let MCFG be default (__weak).
+ *
+ * If platform needs more fancy stuff, should provides its own implementation.
+ */
+int __weak raw_pci_read(unsigned int domain, unsigned int bus,
+			unsigned int devfn, int reg, int len, u32 *val)
+{
+	return pci_mmcfg_read(domain, bus, devfn, reg, len, val);
+}
+
+int __weak raw_pci_write(unsigned int domain, unsigned int bus,
+			 unsigned int devfn, int reg, int len, u32 val)
+{
+	return pci_mmcfg_write(domain, bus, devfn, reg, len, val);
+}
+
 static int __init acpi_mcfg_check_entry(struct acpi_table_mcfg *mcfg,
 					struct acpi_mcfg_allocation *cfg)
 {
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [PATCH v4 8/9] pci, acpi, mcfg: Share ACPI PCI config space accessors.
@ 2015-03-11 14:12   ` Tomasz Nowicki
  0 siblings, 0 replies; 38+ messages in thread
From: Tomasz Nowicki @ 2015-03-11 14:12 UTC (permalink / raw)
  To: linux-arm-kernel

MCFG can be used perfectly for all architectures which support ACPI.
ACPI mandates MCFG to describe PCI config space ranges which means
we should use MMCONFIG accessors by default.

Signed-off-by: Tomasz Nowicki <tomasz.nowicki@linaro.org>
---
 drivers/acpi/mcfg.c | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

diff --git a/drivers/acpi/mcfg.c b/drivers/acpi/mcfg.c
index 1e646fc..e285f62 100644
--- a/drivers/acpi/mcfg.c
+++ b/drivers/acpi/mcfg.c
@@ -13,6 +13,26 @@
 
 #define	PREFIX	"MCFG: "
 
+/*
+ * raw_pci_read/write - ACPI PCI config space accessors.
+ *
+ * ACPI spec defines MCFG table as the way we can describe access to PCI config
+ * space, so let MCFG be default (__weak).
+ *
+ * If platform needs more fancy stuff, should provides its own implementation.
+ */
+int __weak raw_pci_read(unsigned int domain, unsigned int bus,
+			unsigned int devfn, int reg, int len, u32 *val)
+{
+	return pci_mmcfg_read(domain, bus, devfn, reg, len, val);
+}
+
+int __weak raw_pci_write(unsigned int domain, unsigned int bus,
+			 unsigned int devfn, int reg, int len, u32 val)
+{
+	return pci_mmcfg_write(domain, bus, devfn, reg, len, val);
+}
+
 static int __init acpi_mcfg_check_entry(struct acpi_table_mcfg *mcfg,
 					struct acpi_mcfg_allocation *cfg)
 {
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [PATCH v4 9/9] pci, ecam: Improve naming for ecam.c content and areas where it is used.
  2015-03-11 14:12 ` Tomasz Nowicki
@ 2015-03-11 14:12   ` Tomasz Nowicki
  -1 siblings, 0 replies; 38+ messages in thread
From: Tomasz Nowicki @ 2015-03-11 14:12 UTC (permalink / raw)
  To: bhelgaas, wangyijing, arnd, hanjun.guo, Liviu.Dudau, tglx, mingo,
	hpa, rjw, al.stone
  Cc: linux-arm-kernel, linux-kernel, x86, linux-pci, linux-acpi,
	linaro-acpi, Tomasz Nowicki

This commit is consequence of making x86 MMCONFIG code available for all
architectures. Current code has old name fashion so for the sake of
making it more understandable and express where it comes from,
we are changing functions/variables/macros etc. name *mmconfig* -> *ecam*

Signed-off-by: Tomasz Nowicki <tomasz.nowicki@linaro.org>
---
 arch/x86/pci/acpi.c            |   2 +-
 arch/x86/pci/mmconfig-shared.c |  70 +++++++++---------
 arch/x86/pci/mmconfig_32.c     |  16 ++--
 arch/x86/pci/numachip.c        |   4 +-
 drivers/acpi/mcfg.c            |  22 +++---
 drivers/pci/ecam.c             | 162 ++++++++++++++++++++---------------------
 drivers/xen/pci.c              |   6 +-
 include/linux/ecam.h           |  42 +++++------
 8 files changed, 162 insertions(+), 162 deletions(-)

diff --git a/arch/x86/pci/acpi.c b/arch/x86/pci/acpi.c
index 5dfccef..fa3ef35 100644
--- a/arch/x86/pci/acpi.c
+++ b/arch/x86/pci/acpi.c
@@ -199,7 +199,7 @@ static int setup_mcfg_map(struct pci_root_info *info, u16 seg, u8 start,
 static void teardown_mcfg_map(struct pci_root_info *info)
 {
 	if (info->mcfg_added) {
-		pci_mmconfig_delete(info->segment, info->start_bus,
+		pci_ecam_delete(info->segment, info->start_bus,
 				    info->end_bus);
 		info->mcfg_added = false;
 	}
diff --git a/arch/x86/pci/mmconfig-shared.c b/arch/x86/pci/mmconfig-shared.c
index 6dfe614..8f78671 100644
--- a/arch/x86/pci/mmconfig-shared.c
+++ b/arch/x86/pci/mmconfig-shared.c
@@ -30,8 +30,8 @@ static bool pci_mmcfg_running_state;
 static bool pci_mmcfg_arch_init_failed;
 
 const struct pci_raw_ops pci_mmcfg = {
-	.read =		pci_mmcfg_read,
-	.write =	pci_mmcfg_write,
+	.read =		pci_ecam_read,
+	.write =	pci_ecam_write,
 };
 
 static u32
@@ -70,7 +70,7 @@ pci_mmconfig_amd_write(int len, void __iomem *addr, u32 value)
 	}
 }
 
-static struct pci_mmcfg_mmio_ops pci_mmcfg_mmio_amd_fam10h = {
+static struct pci_ecam_mmio_ops pci_mmcfg_mmio_amd_fam10h = {
 	.read = pci_mmconfig_amd_read,
 	.write = pci_mmconfig_amd_write,
 };
@@ -84,7 +84,7 @@ static const char *__init pci_mmcfg_e7520(void)
 	if (win == 0x0000 || win == 0xf000)
 		return NULL;
 
-	if (pci_mmconfig_add(0, 0, 255, win << 16) == NULL)
+	if (pci_ecam_add(0, 0, 255, win << 16) == NULL)
 		return NULL;
 
 	return "Intel Corporation E7520 Memory Controller Hub";
@@ -128,7 +128,7 @@ static const char *__init pci_mmcfg_intel_945(void)
 	if ((pciexbar & mask) >= 0xf0000000U)
 		return NULL;
 
-	if (pci_mmconfig_add(0, 0, (len >> 20) - 1, pciexbar & mask) == NULL)
+	if (pci_ecam_add(0, 0, (len >> 20) - 1, pciexbar & mask) == NULL)
 		return NULL;
 
 	return "Intel Corporation 945G/GZ/P/PL Express Memory Controller Hub";
@@ -175,13 +175,13 @@ static const char *__init pci_mmcfg_amd_fam10h(void)
 
 	end_bus = (1 << busnbits) - 1;
 	for (i = 0; i < (1 << segnbits); i++)
-		if (pci_mmconfig_add(i, 0, end_bus,
+		if (pci_ecam_add(i, 0, end_bus,
 				     base + (1<<28) * i) == NULL) {
-			free_all_mmcfg();
+			pci_ecam_free_all();
 			return NULL;
 		}
 
-	pci_mmconfig_register_mmio(&pci_mmcfg_mmio_amd_fam10h);
+	pci_ecam_register_mmio(&pci_mmcfg_mmio_amd_fam10h);
 
 	return "AMD Family 10h NB";
 }
@@ -210,7 +210,7 @@ static const char *__init pci_mmcfg_nvidia_mcp55(void)
 	/*
 	 * do check if amd fam10h already took over
 	 */
-	if (!acpi_disabled || !list_empty(&pci_mmcfg_list) || mcp55_checked)
+	if (!acpi_disabled || !list_empty(&pci_ecam_list) || mcp55_checked)
 		return NULL;
 
 	mcp55_checked = true;
@@ -239,7 +239,7 @@ static const char *__init pci_mmcfg_nvidia_mcp55(void)
 		base <<= extcfg_base_lshift;
 		start = (extcfg & extcfg_start_mask) >> extcfg_start_shift;
 		end = start + extcfg_sizebus[size_index] - 1;
-		if (pci_mmconfig_add(0, start, end, base) == NULL)
+		if (pci_ecam_add(0, start, end, base) == NULL)
 			continue;
 		mcp55_mmconf_found++;
 	}
@@ -273,15 +273,15 @@ static const struct pci_mmcfg_hostbridge_probe pci_mmcfg_probes[] __initconst =
 
 static void __init pci_mmcfg_check_end_bus_number(void)
 {
-	struct pci_mmcfg_region *cfg, *cfgx;
+	struct pci_ecam_region *cfg, *cfgx;
 
 	/* Fixup overlaps */
-	list_for_each_entry(cfg, &pci_mmcfg_list, list) {
+	list_for_each_entry(cfg, &pci_ecam_list, list) {
 		if (cfg->end_bus < cfg->start_bus)
 			cfg->end_bus = 255;
 
 		/* Don't access the list head ! */
-		if (cfg->list.next == &pci_mmcfg_list)
+		if (cfg->list.next == &pci_ecam_list)
 			break;
 
 		cfgx = list_entry(cfg->list.next, typeof(*cfg), list);
@@ -301,7 +301,7 @@ static int __init pci_mmcfg_check_hostbridge(void)
 	if (!raw_pci_ops)
 		return 0;
 
-	free_all_mmcfg();
+	pci_ecam_free_all();
 
 	for (i = 0; i < ARRAY_SIZE(pci_mmcfg_probes); i++) {
 		bus =  pci_mmcfg_probes[i].bus;
@@ -322,7 +322,7 @@ static int __init pci_mmcfg_check_hostbridge(void)
 	/* some end_bus_number is crazy, fix it */
 	pci_mmcfg_check_end_bus_number();
 
-	return !list_empty(&pci_mmcfg_list);
+	return !list_empty(&pci_ecam_list);
 }
 
 static acpi_status check_mcfg_resource(struct acpi_resource *res, void *data)
@@ -395,7 +395,7 @@ static int is_acpi_reserved(u64 start, u64 end, unsigned not_used)
 typedef int (*check_reserved_t)(u64 start, u64 end, unsigned type);
 
 static int __ref is_mmconf_reserved(check_reserved_t is_reserved,
-				    struct pci_mmcfg_region *cfg,
+				    struct pci_ecam_region *cfg,
 				    struct device *dev, int with_e820)
 {
 	u64 addr = cfg->res.start;
@@ -425,8 +425,8 @@ static int __ref is_mmconf_reserved(check_reserved_t is_reserved,
 		cfg->end_bus = cfg->start_bus + ((size>>20) - 1);
 		num_buses = cfg->end_bus - cfg->start_bus + 1;
 		cfg->res.end = cfg->res.start +
-		    PCI_MMCFG_BUS_OFFSET(num_buses) - 1;
-		snprintf(cfg->name, PCI_MMCFG_RESOURCE_NAME_LEN,
+		    PCI_ECAM_BUS_OFFSET(num_buses) - 1;
+		snprintf(cfg->name, PCI_ECAM_RESOURCE_NAME_LEN,
 			 "PCI MMCONFIG %04x [bus %02x-%02x]",
 			 cfg->segment, cfg->start_bus, cfg->end_bus);
 
@@ -447,7 +447,7 @@ static int __ref is_mmconf_reserved(check_reserved_t is_reserved,
 }
 
 static int __ref pci_mmcfg_check_reserved(struct device *dev,
-		  struct pci_mmcfg_region *cfg, int early)
+		  struct pci_ecam_region *cfg, int early)
 {
 	if (!early && !acpi_disabled) {
 		if (is_mmconf_reserved(is_acpi_reserved, cfg, dev, 0))
@@ -484,12 +484,12 @@ static int __ref pci_mmcfg_check_reserved(struct device *dev,
 
 static void __init pci_mmcfg_reject_broken(int early)
 {
-	struct pci_mmcfg_region *cfg;
+	struct pci_ecam_region *cfg;
 
-	list_for_each_entry(cfg, &pci_mmcfg_list, list) {
+	list_for_each_entry(cfg, &pci_ecam_list, list) {
 		if (pci_mmcfg_check_reserved(NULL, cfg, early) == 0) {
 			pr_info(PREFIX "not using MMCONFIG\n");
-			free_all_mmcfg();
+			pci_ecam_free_all();
 			return;
 		}
 	}
@@ -502,13 +502,13 @@ extern int (*arch_apei_filter_addr)(int (*func)(__u64 start, __u64 size,
 static int pci_mmcfg_for_each_region(int (*func)(__u64 start, __u64 size,
 				     void *data), void *data)
 {
-	struct pci_mmcfg_region *cfg;
+	struct pci_ecam_region *cfg;
 	int rc;
 
-	if (list_empty(&pci_mmcfg_list))
+	if (list_empty(&pci_ecam_list))
 		return 0;
 
-	list_for_each_entry(cfg, &pci_mmcfg_list, list) {
+	list_for_each_entry(cfg, &pci_ecam_list, list) {
 		rc = func(cfg->res.start, resource_size(&cfg->res), data);
 		if (rc)
 			return rc;
@@ -524,24 +524,24 @@ static int pci_mmcfg_for_each_region(int (*func)(__u64 start, __u64 size,
 static void __init __pci_mmcfg_init(int early)
 {
 	pci_mmcfg_reject_broken(early);
-	if (list_empty(&pci_mmcfg_list))
+	if (list_empty(&pci_ecam_list))
 		return;
 
 	if (pcibios_last_bus < 0) {
-		const struct pci_mmcfg_region *cfg;
+		const struct pci_ecam_region *cfg;
 
-		list_for_each_entry(cfg, &pci_mmcfg_list, list) {
+		list_for_each_entry(cfg, &pci_ecam_list, list) {
 			if (cfg->segment)
 				break;
 			pcibios_last_bus = cfg->end_bus;
 		}
 	}
 
-	if (pci_mmcfg_arch_init()) {
+	if (pci_ecam_arch_init()) {
 		raw_pci_ext_ops = &pci_mmcfg;
 		pci_probe = (pci_probe & ~PCI_PROBE_MASK) | PCI_PROBE_MMCONF;
 	} else {
-		free_all_mmcfg();
+		pci_ecam_free_all();
 		pci_mmcfg_arch_init_failed = true;
 	}
 }
@@ -579,7 +579,7 @@ void __init pci_mmcfg_late_init(void)
 
 static int __init pci_mmcfg_late_insert_resources(void)
 {
-	struct pci_mmcfg_region *cfg;
+	struct pci_ecam_region *cfg;
 
 	pci_mmcfg_running_state = true;
 
@@ -592,7 +592,7 @@ static int __init pci_mmcfg_late_insert_resources(void)
 	 * marked so it won't cause request errors when __request_region is
 	 * called.
 	 */
-	list_for_each_entry(cfg, &pci_mmcfg_list, list)
+	list_for_each_entry(cfg, &pci_ecam_list, list)
 		if (!cfg->res.parent)
 			insert_resource(&iomem_resource, &cfg->res);
 
@@ -612,7 +612,7 @@ int pci_mmconfig_insert(struct device *dev, u16 seg, u8 start, u8 end,
 {
 	int rc;
 	struct resource *tmp = NULL;
-	struct pci_mmcfg_region *cfg;
+	struct pci_ecam_region *cfg;
 
 	if (!(pci_probe & PCI_PROBE_MMCONF) || pci_mmcfg_arch_init_failed)
 		return -ENODEV;
@@ -621,7 +621,7 @@ int pci_mmconfig_insert(struct device *dev, u16 seg, u8 start, u8 end,
 		return -EINVAL;
 
 	rc = -EBUSY;
-	cfg = pci_mmconfig_alloc(seg, start, end, addr);
+	cfg = pci_ecam_alloc(seg, start, end, addr);
 	if (cfg == NULL) {
 		dev_warn(dev, "fail to add MMCONFIG (out of memory)\n");
 		return -ENOMEM;
@@ -642,7 +642,7 @@ int pci_mmconfig_insert(struct device *dev, u16 seg, u8 start, u8 end,
 		goto error;
 	}
 
-	rc = pci_mmconfig_inject(cfg);
+	rc = pci_ecam_inject(cfg);
 	if (rc)
 		goto error;
 
diff --git a/arch/x86/pci/mmconfig_32.c b/arch/x86/pci/mmconfig_32.c
index 7a050cb..27e707d 100644
--- a/arch/x86/pci/mmconfig_32.c
+++ b/arch/x86/pci/mmconfig_32.c
@@ -28,7 +28,7 @@ static int mmcfg_last_accessed_cpu;
  */
 static u32 get_base_addr(unsigned int seg, int bus, unsigned devfn)
 {
-	struct pci_mmcfg_region *cfg = pci_mmconfig_lookup(seg, bus);
+	struct pci_ecam_region *cfg = pci_ecam_lookup(seg, bus);
 
 	if (cfg)
 		return cfg->address;
@@ -40,7 +40,7 @@ static u32 get_base_addr(unsigned int seg, int bus, unsigned devfn)
  */
 static void pci_exp_set_dev_base(unsigned int base, int bus, int devfn)
 {
-	u32 dev_base = base | PCI_MMCFG_BUS_OFFSET(bus) | (devfn << 12);
+	u32 dev_base = base | PCI_ECAM_BUS_OFFSET(bus) | (devfn << 12);
 	int cpu = smp_processor_id();
 	if (dev_base != mmcfg_last_accessed_device ||
 	    cpu != mmcfg_last_accessed_cpu) {
@@ -50,7 +50,7 @@ static void pci_exp_set_dev_base(unsigned int base, int bus, int devfn)
 	}
 }
 
-int pci_mmcfg_read(unsigned int seg, unsigned int bus,
+int pci_ecam_read(unsigned int seg, unsigned int bus,
 			  unsigned int devfn, int reg, int len, u32 *value)
 {
 	unsigned long flags;
@@ -79,7 +79,7 @@ err:		*value = -1;
 	return 0;
 }
 
-int pci_mmcfg_write(unsigned int seg, unsigned int bus,
+int pci_ecam_write(unsigned int seg, unsigned int bus,
 			   unsigned int devfn, int reg, int len, u32 value)
 {
 	unsigned long flags;
@@ -106,22 +106,22 @@ int pci_mmcfg_write(unsigned int seg, unsigned int bus,
 	return 0;
 }
 
-int __init pci_mmcfg_arch_init(void)
+int __init pci_ecam_arch_init(void)
 {
 	printk(KERN_INFO "PCI: Using MMCONFIG for extended config space\n");
 	return 1;
 }
 
-void __init pci_mmcfg_arch_free(void)
+void __init pci_ecam_arch_free(void)
 {
 }
 
-int pci_mmcfg_arch_map(struct pci_mmcfg_region *cfg)
+int pci_ecam_arch_map(struct pci_ecam_region *cfg)
 {
 	return 0;
 }
 
-void pci_mmcfg_arch_unmap(struct pci_mmcfg_region *cfg)
+void pci_ecam_arch_unmap(struct pci_ecam_region *cfg)
 {
 	unsigned long flags;
 
diff --git a/arch/x86/pci/numachip.c b/arch/x86/pci/numachip.c
index 01868b6..af41247 100644
--- a/arch/x86/pci/numachip.c
+++ b/arch/x86/pci/numachip.c
@@ -21,10 +21,10 @@ static u8 limit __read_mostly;
 
 static inline char __iomem *pci_dev_base(unsigned int seg, unsigned int bus, unsigned int devfn)
 {
-	struct pci_mmcfg_region *cfg = pci_mmconfig_lookup(seg, bus);
+	struct pci_ecam_region *cfg = pci_ecam_lookup(seg, bus);
 
 	if (cfg && cfg->virt)
-		return cfg->virt + (PCI_MMCFG_BUS_OFFSET(bus) | (devfn << 12));
+		return cfg->virt + (PCI_ECAM_BUS_OFFSET(bus) | (devfn << 12));
 	return NULL;
 }
 
diff --git a/drivers/acpi/mcfg.c b/drivers/acpi/mcfg.c
index e285f62..40926a3 100644
--- a/drivers/acpi/mcfg.c
+++ b/drivers/acpi/mcfg.c
@@ -24,13 +24,13 @@
 int __weak raw_pci_read(unsigned int domain, unsigned int bus,
 			unsigned int devfn, int reg, int len, u32 *val)
 {
-	return pci_mmcfg_read(domain, bus, devfn, reg, len, val);
+	return pci_ecam_read(domain, bus, devfn, reg, len, val);
 }
 
 int __weak raw_pci_write(unsigned int domain, unsigned int bus,
 			 unsigned int devfn, int reg, int len, u32 val)
 {
-	return pci_mmcfg_write(domain, bus, devfn, reg, len, val);
+	return pci_ecam_write(domain, bus, devfn, reg, len, val);
 }
 
 static int __init acpi_mcfg_check_entry(struct acpi_table_mcfg *mcfg,
@@ -69,7 +69,7 @@ int __init acpi_parse_mcfg(struct acpi_table_header *header)
 	mcfg = (struct acpi_table_mcfg *)header;
 
 	/* how many config structures do we have */
-	free_all_mmcfg();
+	pci_ecam_free_all();
 	entries = 0;
 	i = header->length - sizeof(struct acpi_table_mcfg);
 	while (i >= sizeof(struct acpi_mcfg_allocation)) {
@@ -85,14 +85,14 @@ int __init acpi_parse_mcfg(struct acpi_table_header *header)
 	for (i = 0; i < entries; i++) {
 		cfg = &cfg_table[i];
 		if (acpi_mcfg_check_entry(mcfg, cfg)) {
-			free_all_mmcfg();
+			pci_ecam_free_all();
 			return -ENODEV;
 		}
 
-		if (pci_mmconfig_add(cfg->pci_segment, cfg->start_bus_number,
+		if (pci_ecam_add(cfg->pci_segment, cfg->start_bus_number,
 				   cfg->end_bus_number, cfg->address) == NULL) {
 			pr_warn(PREFIX "no memory for MCFG entries\n");
-			free_all_mmcfg();
+			pci_ecam_free_all();
 			return -ENOMEM;
 		}
 	}
@@ -107,15 +107,15 @@ void __init __weak pci_mmcfg_early_init(void)
 
 void __init __weak pci_mmcfg_late_init(void)
 {
-	struct pci_mmcfg_region *cfg;
+	struct pci_ecam_region *cfg;
 
 	acpi_table_parse(ACPI_SIG_MCFG, acpi_parse_mcfg);
 
-	if (list_empty(&pci_mmcfg_list))
+	if (list_empty(&pci_ecam_list))
 		return;
-	if (!pci_mmcfg_arch_init())
-		free_all_mmcfg();
+	if (!pci_ecam_arch_init())
+		pci_ecam_free_all();
 
-	list_for_each_entry(cfg, &pci_mmcfg_list, list)
+	list_for_each_entry(cfg, &pci_ecam_list, list)
 		insert_resource(&iomem_resource, &cfg->res);
 }
diff --git a/drivers/pci/ecam.c b/drivers/pci/ecam.c
index 796b6e7..d6281a2 100644
--- a/drivers/pci/ecam.c
+++ b/drivers/pci/ecam.c
@@ -17,24 +17,24 @@
 
 #include <asm/io.h>
 
-#define PREFIX "PCI: "
+#define PREFIX "PCI ECAM: "
 
-static DEFINE_MUTEX(pci_mmcfg_lock);
+static DEFINE_MUTEX(pci_ecam_lock);
 
-LIST_HEAD(pci_mmcfg_list);
+LIST_HEAD(pci_ecam_list);
 
 #ifdef CONFIG_GENERIC_PCI_ECAM
 static char __iomem *pci_dev_base(unsigned int seg, unsigned int bus,
 				  unsigned int devfn)
 {
-	struct pci_mmcfg_region *cfg = pci_mmconfig_lookup(seg, bus);
+	struct pci_ecam_region *cfg = pci_ecam_lookup(seg, bus);
 
 	if (cfg && cfg->virt)
-		return cfg->virt + (PCI_MMCFG_BUS_OFFSET(bus) | (devfn << 12));
+		return cfg->virt + (PCI_ECAM_BUS_OFFSET(bus) | (devfn << 12));
 	return NULL;
 }
 
-int pci_mmcfg_read(unsigned int seg, unsigned int bus,
+int pci_ecam_read(unsigned int seg, unsigned int bus,
 			  unsigned int devfn, int reg, int len, u32 *value)
 {
 	char __iomem *addr;
@@ -58,7 +58,7 @@ err:		*value = -1;
 	return 0;
 }
 
-int pci_mmcfg_write(unsigned int seg, unsigned int bus,
+int pci_ecam_write(unsigned int seg, unsigned int bus,
 			   unsigned int devfn, int reg, int len, u32 value)
 {
 	char __iomem *addr;
@@ -80,64 +80,64 @@ int pci_mmcfg_write(unsigned int seg, unsigned int bus,
 	return 0;
 }
 
-static void __iomem *mcfg_ioremap(struct pci_mmcfg_region *cfg)
+static void __iomem *pci_ecam_ioremap(struct pci_ecam_region *cfg)
 {
 	void __iomem *addr;
 	u64 start, size;
 	int num_buses;
 
-	start = cfg->address + PCI_MMCFG_BUS_OFFSET(cfg->start_bus);
+	start = cfg->address + PCI_ECAM_BUS_OFFSET(cfg->start_bus);
 	num_buses = cfg->end_bus - cfg->start_bus + 1;
-	size = PCI_MMCFG_BUS_OFFSET(num_buses);
+	size = PCI_ECAM_BUS_OFFSET(num_buses);
 	addr = ioremap_nocache(start, size);
 	if (addr)
-		addr -= PCI_MMCFG_BUS_OFFSET(cfg->start_bus);
+		addr -= PCI_ECAM_BUS_OFFSET(cfg->start_bus);
 	return addr;
 }
 
-int __init pci_mmcfg_arch_init(void)
+int __init pci_ecam_arch_init(void)
 {
-	struct pci_mmcfg_region *cfg;
+	struct pci_ecam_region *cfg;
 
-	list_for_each_entry(cfg, &pci_mmcfg_list, list)
-		if (pci_mmcfg_arch_map(cfg)) {
-			pci_mmcfg_arch_free();
+	list_for_each_entry(cfg, &pci_ecam_list, list)
+		if (pci_ecam_arch_map(cfg)) {
+			pci_ecam_arch_free();
 			return 0;
 		}
 
 	return 1;
 }
 
-void __init pci_mmcfg_arch_free(void)
+void __init pci_ecam_arch_free(void)
 {
-	struct pci_mmcfg_region *cfg;
+	struct pci_ecam_region *cfg;
 
-	list_for_each_entry(cfg, &pci_mmcfg_list, list)
-		pci_mmcfg_arch_unmap(cfg);
+	list_for_each_entry(cfg, &pci_ecam_list, list)
+		pci_ecam_arch_unmap(cfg);
 }
 
-int pci_mmcfg_arch_map(struct pci_mmcfg_region *cfg)
+int pci_ecam_arch_map(struct pci_ecam_region *cfg)
 {
-	cfg->virt = mcfg_ioremap(cfg);
+	cfg->virt = pci_ecam_ioremap(cfg);
 	if (!cfg->virt) {
-		pr_err(PREFIX "can't map MMCONFIG at %pR\n", &cfg->res);
+		pr_err(PREFIX "can't map ECAM at %pR\n", &cfg->res);
 		return -ENOMEM;
 	}
 
 	return 0;
 }
 
-void pci_mmcfg_arch_unmap(struct pci_mmcfg_region *cfg)
+void pci_ecam_arch_unmap(struct pci_ecam_region *cfg)
 {
 	if (cfg && cfg->virt) {
-		iounmap(cfg->virt + PCI_MMCFG_BUS_OFFSET(cfg->start_bus));
+		iounmap(cfg->virt + PCI_ECAM_BUS_OFFSET(cfg->start_bus));
 		cfg->virt = NULL;
 	}
 }
 #endif
 
 static u32
-pci_mmconfig_generic_read(int len, void __iomem *addr)
+pci_ecam_generic_read(int len, void __iomem *addr)
 {
 	u32 data = 0;
 
@@ -157,7 +157,7 @@ pci_mmconfig_generic_read(int len, void __iomem *addr)
 }
 
 static void
-pci_mmconfig_generic_write(int len, void __iomem *addr, u32 value)
+pci_ecam_generic_write(int len, void __iomem *addr, u32 value)
 {
 	switch (len) {
 	case 1:
@@ -172,42 +172,42 @@ pci_mmconfig_generic_write(int len, void __iomem *addr, u32 value)
 	}
 }
 
-static struct pci_mmcfg_mmio_ops pci_mmcfg_mmio_default = {
-	.read = pci_mmconfig_generic_read,
-	.write = pci_mmconfig_generic_write,
+static struct pci_ecam_mmio_ops pci_ecam_mmio_default = {
+	.read = pci_ecam_generic_read,
+	.write = pci_ecam_generic_write,
 };
 
-static struct pci_mmcfg_mmio_ops *pci_mmcfg_mmio = &pci_mmcfg_mmio_default;
+static struct pci_ecam_mmio_ops *pci_ecam_mmio = &pci_ecam_mmio_default;
 
 void
-pci_mmconfig_register_mmio(struct pci_mmcfg_mmio_ops *ops)
+pci_ecam_register_mmio(struct pci_ecam_mmio_ops *ops)
 {
-	pci_mmcfg_mmio = ops;
+	pci_ecam_mmio = ops;
 }
 
 u32
 pci_mmio_read(int len, void __iomem *addr)
 {
-	if (!pci_mmcfg_mmio) {
+	if (!pci_ecam_mmio) {
 		pr_err("PCI config space has no accessors !");
 		return 0;
 	}
 
-	return pci_mmcfg_mmio->read(len, addr);
+	return pci_ecam_mmio->read(len, addr);
 }
 
 void
 pci_mmio_write(int len, void __iomem *addr, u32 value)
 {
-	if (!pci_mmcfg_mmio) {
+	if (!pci_ecam_mmio) {
 		pr_err("PCI config space has no accessors !");
 		return;
 	}
 
-	pci_mmcfg_mmio->write(len, addr, value);
+	pci_ecam_mmio->write(len, addr, value);
 }
 
-static void __init pci_mmconfig_remove(struct pci_mmcfg_region *cfg)
+static void __init pci_ecam_remove(struct pci_ecam_region *cfg)
 {
 	if (cfg->res.parent)
 		release_resource(&cfg->res);
@@ -215,21 +215,21 @@ static void __init pci_mmconfig_remove(struct pci_mmcfg_region *cfg)
 	kfree(cfg);
 }
 
-void __init free_all_mmcfg(void)
+void __init pci_ecam_free_all(void)
 {
-	struct pci_mmcfg_region *cfg, *tmp;
+	struct pci_ecam_region *cfg, *tmp;
 
-	pci_mmcfg_arch_free();
-	list_for_each_entry_safe(cfg, tmp, &pci_mmcfg_list, list)
-		pci_mmconfig_remove(cfg);
+	pci_ecam_arch_free();
+	list_for_each_entry_safe(cfg, tmp, &pci_ecam_list, list)
+		pci_ecam_remove(cfg);
 }
 
-void list_add_sorted(struct pci_mmcfg_region *new)
+void pci_ecam_list_add_sorted(struct pci_ecam_region *new)
 {
-	struct pci_mmcfg_region *cfg;
+	struct pci_ecam_region *cfg;
 
 	/* keep list sorted by segment and starting bus number */
-	list_for_each_entry_rcu(cfg, &pci_mmcfg_list, list) {
+	list_for_each_entry_rcu(cfg, &pci_ecam_list, list) {
 		if (cfg->segment > new->segment ||
 		    (cfg->segment == new->segment &&
 		     cfg->start_bus >= new->start_bus)) {
@@ -237,13 +237,13 @@ void list_add_sorted(struct pci_mmcfg_region *new)
 			return;
 		}
 	}
-	list_add_tail_rcu(&new->list, &pci_mmcfg_list);
+	list_add_tail_rcu(&new->list, &pci_ecam_list);
 }
 
-struct pci_mmcfg_region *pci_mmconfig_alloc(int segment, int start,
+struct pci_ecam_region *pci_ecam_alloc(int segment, int start,
 					    int end, u64 addr)
 {
-	struct pci_mmcfg_region *new;
+	struct pci_ecam_region *new;
 	struct resource *res;
 
 	if (addr == 0)
@@ -259,29 +259,29 @@ struct pci_mmcfg_region *pci_mmconfig_alloc(int segment, int start,
 	new->end_bus = end;
 
 	res = &new->res;
-	res->start = addr + PCI_MMCFG_BUS_OFFSET(start);
-	res->end = addr + PCI_MMCFG_BUS_OFFSET(end + 1) - 1;
+	res->start = addr + PCI_ECAM_BUS_OFFSET(start);
+	res->end = addr + PCI_ECAM_BUS_OFFSET(end + 1) - 1;
 	res->flags = IORESOURCE_MEM | IORESOURCE_BUSY;
-	snprintf(new->name, PCI_MMCFG_RESOURCE_NAME_LEN,
-		 "PCI MMCONFIG %04x [bus %02x-%02x]", segment, start, end);
+	snprintf(new->name, PCI_ECAM_RESOURCE_NAME_LEN,
+		 "PCI ECAM %04x [bus %02x-%02x]", segment, start, end);
 	res->name = new->name;
 
 	return new;
 }
 
-struct pci_mmcfg_region *pci_mmconfig_add(int segment, int start,
+struct pci_ecam_region *pci_ecam_add(int segment, int start,
 					  int end, u64 addr)
 {
-	struct pci_mmcfg_region *new;
+	struct pci_ecam_region *new;
 
-	new = pci_mmconfig_alloc(segment, start, end, addr);
+	new = pci_ecam_alloc(segment, start, end, addr);
 	if (new) {
-		mutex_lock(&pci_mmcfg_lock);
-		list_add_sorted(new);
-		mutex_unlock(&pci_mmcfg_lock);
+		mutex_lock(&pci_ecam_lock);
+		pci_ecam_list_add_sorted(new);
+		mutex_unlock(&pci_ecam_lock);
 
 		pr_info(PREFIX
-		       "MMCONFIG for domain %04x [bus %02x-%02x] at %pR "
+		       "ECAM for domain %04x [bus %02x-%02x] at %pR "
 		       "(base %#lx)\n",
 		       segment, start, end, &new->res, (unsigned long)addr);
 	}
@@ -289,11 +289,11 @@ struct pci_mmcfg_region *pci_mmconfig_add(int segment, int start,
 	return new;
 }
 
-struct pci_mmcfg_region *pci_mmconfig_lookup(int segment, int bus)
+struct pci_ecam_region *pci_ecam_lookup(int segment, int bus)
 {
-	struct pci_mmcfg_region *cfg;
+	struct pci_ecam_region *cfg;
 
-	list_for_each_entry_rcu(cfg, &pci_mmcfg_list, list)
+	list_for_each_entry_rcu(cfg, &pci_ecam_list, list)
 		if (cfg->segment == segment &&
 		    cfg->start_bus <= bus && bus <= cfg->end_bus)
 			return cfg;
@@ -301,39 +301,39 @@ struct pci_mmcfg_region *pci_mmconfig_lookup(int segment, int bus)
 	return NULL;
 }
 
-/* Delete MMCFG information for host bridges */
-int pci_mmconfig_delete(u16 seg, u8 start, u8 end)
+/* Delete ECAM information for host bridges */
+int pci_ecam_delete(u16 seg, u8 start, u8 end)
 {
-	struct pci_mmcfg_region *cfg;
+	struct pci_ecam_region *cfg;
 
-	mutex_lock(&pci_mmcfg_lock);
-	list_for_each_entry_rcu(cfg, &pci_mmcfg_list, list)
+	mutex_lock(&pci_ecam_lock);
+	list_for_each_entry_rcu(cfg, &pci_ecam_list, list)
 		if (cfg->segment == seg && cfg->start_bus == start &&
 		    cfg->end_bus == end) {
 			list_del_rcu(&cfg->list);
 			synchronize_rcu();
-			pci_mmcfg_arch_unmap(cfg);
+			pci_ecam_arch_unmap(cfg);
 			if (cfg->res.parent)
 				release_resource(&cfg->res);
-			mutex_unlock(&pci_mmcfg_lock);
+			mutex_unlock(&pci_ecam_lock);
 			kfree(cfg);
 			return 0;
 		}
-	mutex_unlock(&pci_mmcfg_lock);
+	mutex_unlock(&pci_ecam_lock);
 
 	return -ENOENT;
 }
 
-int pci_mmconfig_inject(struct pci_mmcfg_region *cfg)
+int pci_ecam_inject(struct pci_ecam_region *cfg)
 {
-	struct pci_mmcfg_region *cfg_conflict;
+	struct pci_ecam_region *cfg_conflict;
 	int err = 0;
 
-	mutex_lock(&pci_mmcfg_lock);
-	cfg_conflict = pci_mmconfig_lookup(cfg->segment, cfg->start_bus);
+	mutex_lock(&pci_ecam_lock);
+	cfg_conflict = pci_ecam_lookup(cfg->segment, cfg->start_bus);
 	if (cfg_conflict) {
 		if (cfg_conflict->end_bus < cfg->end_bus)
-			pr_info(FW_INFO "MMCONFIG for "
+			pr_info(FW_INFO "ECAM for "
 				"domain %04x [bus %02x-%02x] "
 				"only partially covers this bridge\n",
 				cfg_conflict->segment, cfg_conflict->start_bus,
@@ -342,17 +342,17 @@ int pci_mmconfig_inject(struct pci_mmcfg_region *cfg)
 		goto out;
 	}
 
-	if (pci_mmcfg_arch_map(cfg)) {
-		pr_warn("fail to map MMCONFIG %pR.\n", &cfg->res);
+	if (pci_ecam_arch_map(cfg)) {
+		pr_warn("fail to map ECAM %pR.\n", &cfg->res);
 		err = -ENOMEM;
 		goto out;
 	} else {
-		list_add_sorted(cfg);
-		pr_info("MMCONFIG at %pR (base %#lx)\n",
+		pci_ecam_list_add_sorted(cfg);
+		pr_info("ECAM at %pR (base %#lx)\n",
 			&cfg->res, (unsigned long)cfg->address);
 
 	}
 out:
-	mutex_unlock(&pci_mmcfg_lock);
+	mutex_unlock(&pci_ecam_lock);
 	return err;
 }
diff --git a/drivers/xen/pci.c b/drivers/xen/pci.c
index 7a34a72..76b3ca2 100644
--- a/drivers/xen/pci.c
+++ b/drivers/xen/pci.c
@@ -205,7 +205,7 @@ arch_initcall(register_xen_pci_notifier);
 #ifdef CONFIG_PCI_MMCONFIG
 static int __init xen_mcfg_late(void)
 {
-	struct pci_mmcfg_region *cfg;
+	struct pci_ecam_region *cfg;
 	int rc;
 
 	if (!xen_initial_domain())
@@ -214,11 +214,11 @@ static int __init xen_mcfg_late(void)
 	if ((pci_probe & PCI_PROBE_MMCONF) == 0)
 		return 0;
 
-	if (list_empty(&pci_mmcfg_list))
+	if (list_empty(&pci_ecam_list))
 		return 0;
 
 	/* Check whether they are in the right area. */
-	list_for_each_entry(cfg, &pci_mmcfg_list, list) {
+	list_for_each_entry(cfg, &pci_ecam_list, list) {
 		struct physdev_pci_mmcfg_reserved r;
 
 		r.address = cfg->address;
diff --git a/include/linux/ecam.h b/include/linux/ecam.h
index fba5d6b..363691b 100644
--- a/include/linux/ecam.h
+++ b/include/linux/ecam.h
@@ -5,10 +5,10 @@
 #include <linux/types.h>
 #include <linux/acpi.h>
 
-/* "PCI MMCONFIG %04x [bus %02x-%02x]" */
-#define PCI_MMCFG_RESOURCE_NAME_LEN (22 + 4 + 2 + 2)
+/* "PCI ECAM %04x [bus %02x-%02x]" */
+#define PCI_ECAM_RESOURCE_NAME_LEN (22 + 4 + 2 + 2)
 
-struct pci_mmcfg_region {
+struct pci_ecam_region {
 	struct list_head list;
 	struct resource res;
 	u64 address;
@@ -16,40 +16,40 @@ struct pci_mmcfg_region {
 	u16 segment;
 	u8 start_bus;
 	u8 end_bus;
-	char name[PCI_MMCFG_RESOURCE_NAME_LEN];
+	char name[PCI_ECAM_RESOURCE_NAME_LEN];
 };
 
-struct pci_mmcfg_mmio_ops {
+struct pci_ecam_mmio_ops {
 	u32 (*read)(int len, void __iomem *addr);
 	void (*write)(int len, void __iomem *addr, u32 value);
 };
 
-struct pci_mmcfg_region *pci_mmconfig_lookup(int segment, int bus);
-struct pci_mmcfg_region *pci_mmconfig_alloc(int segment, int start,
+struct pci_ecam_region *pci_ecam_lookup(int segment, int bus);
+struct pci_ecam_region *pci_ecam_alloc(int segment, int start,
 						   int end, u64 addr);
-int pci_mmconfig_inject(struct pci_mmcfg_region *cfg);
-struct pci_mmcfg_region *pci_mmconfig_add(int segment, int start,
+int pci_ecam_inject(struct pci_ecam_region *cfg);
+struct pci_ecam_region *pci_ecam_add(int segment, int start,
 						 int end, u64 addr);
-void list_add_sorted(struct pci_mmcfg_region *new);
-void free_all_mmcfg(void);
-int pci_mmconfig_delete(u16 seg, u8 start, u8 end);
+void pci_ecam_list_add_sorted(struct pci_ecam_region *new);
+void pci_ecam_free_all(void);
+int pci_ecam_delete(u16 seg, u8 start, u8 end);
 
 /* Arch specific calls */
-int pci_mmcfg_arch_init(void);
-void pci_mmcfg_arch_free(void);
-int pci_mmcfg_arch_map(struct pci_mmcfg_region *cfg);
-void pci_mmcfg_arch_unmap(struct pci_mmcfg_region *cfg);
+int pci_ecam_arch_init(void);
+void pci_ecam_arch_free(void);
+int pci_ecam_arch_map(struct pci_ecam_region *cfg);
+void pci_ecam_arch_unmap(struct pci_ecam_region *cfg);
 extern u32 pci_mmio_read(int len, void __iomem *addr);
 extern void pci_mmio_write(int len, void __iomem *addr, u32 value);
-extern void pci_mmconfig_register_mmio(struct pci_mmcfg_mmio_ops *ops);
+extern void pci_ecam_register_mmio(struct pci_ecam_mmio_ops *ops);
 
-extern struct list_head pci_mmcfg_list;
+extern struct list_head pci_ecam_list;
 
-#define PCI_MMCFG_BUS_OFFSET(bus)      ((bus) << 20)
+#define PCI_ECAM_BUS_OFFSET(bus)      ((bus) << 20)
 
-int pci_mmcfg_read(unsigned int seg, unsigned int bus,
+int pci_ecam_read(unsigned int seg, unsigned int bus,
 		   unsigned int devfn, int reg, int len, u32 *value);
-int pci_mmcfg_write(unsigned int seg, unsigned int bus,
+int pci_ecam_write(unsigned int seg, unsigned int bus,
 		    unsigned int devfn, int reg, int len, u32 value);
 
 #endif  /* __KERNEL__ */
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [PATCH v4 9/9] pci, ecam: Improve naming for ecam.c content and areas where it is used.
@ 2015-03-11 14:12   ` Tomasz Nowicki
  0 siblings, 0 replies; 38+ messages in thread
From: Tomasz Nowicki @ 2015-03-11 14:12 UTC (permalink / raw)
  To: linux-arm-kernel

This commit is consequence of making x86 MMCONFIG code available for all
architectures. Current code has old name fashion so for the sake of
making it more understandable and express where it comes from,
we are changing functions/variables/macros etc. name *mmconfig* -> *ecam*

Signed-off-by: Tomasz Nowicki <tomasz.nowicki@linaro.org>
---
 arch/x86/pci/acpi.c            |   2 +-
 arch/x86/pci/mmconfig-shared.c |  70 +++++++++---------
 arch/x86/pci/mmconfig_32.c     |  16 ++--
 arch/x86/pci/numachip.c        |   4 +-
 drivers/acpi/mcfg.c            |  22 +++---
 drivers/pci/ecam.c             | 162 ++++++++++++++++++++---------------------
 drivers/xen/pci.c              |   6 +-
 include/linux/ecam.h           |  42 +++++------
 8 files changed, 162 insertions(+), 162 deletions(-)

diff --git a/arch/x86/pci/acpi.c b/arch/x86/pci/acpi.c
index 5dfccef..fa3ef35 100644
--- a/arch/x86/pci/acpi.c
+++ b/arch/x86/pci/acpi.c
@@ -199,7 +199,7 @@ static int setup_mcfg_map(struct pci_root_info *info, u16 seg, u8 start,
 static void teardown_mcfg_map(struct pci_root_info *info)
 {
 	if (info->mcfg_added) {
-		pci_mmconfig_delete(info->segment, info->start_bus,
+		pci_ecam_delete(info->segment, info->start_bus,
 				    info->end_bus);
 		info->mcfg_added = false;
 	}
diff --git a/arch/x86/pci/mmconfig-shared.c b/arch/x86/pci/mmconfig-shared.c
index 6dfe614..8f78671 100644
--- a/arch/x86/pci/mmconfig-shared.c
+++ b/arch/x86/pci/mmconfig-shared.c
@@ -30,8 +30,8 @@ static bool pci_mmcfg_running_state;
 static bool pci_mmcfg_arch_init_failed;
 
 const struct pci_raw_ops pci_mmcfg = {
-	.read =		pci_mmcfg_read,
-	.write =	pci_mmcfg_write,
+	.read =		pci_ecam_read,
+	.write =	pci_ecam_write,
 };
 
 static u32
@@ -70,7 +70,7 @@ pci_mmconfig_amd_write(int len, void __iomem *addr, u32 value)
 	}
 }
 
-static struct pci_mmcfg_mmio_ops pci_mmcfg_mmio_amd_fam10h = {
+static struct pci_ecam_mmio_ops pci_mmcfg_mmio_amd_fam10h = {
 	.read = pci_mmconfig_amd_read,
 	.write = pci_mmconfig_amd_write,
 };
@@ -84,7 +84,7 @@ static const char *__init pci_mmcfg_e7520(void)
 	if (win == 0x0000 || win == 0xf000)
 		return NULL;
 
-	if (pci_mmconfig_add(0, 0, 255, win << 16) == NULL)
+	if (pci_ecam_add(0, 0, 255, win << 16) == NULL)
 		return NULL;
 
 	return "Intel Corporation E7520 Memory Controller Hub";
@@ -128,7 +128,7 @@ static const char *__init pci_mmcfg_intel_945(void)
 	if ((pciexbar & mask) >= 0xf0000000U)
 		return NULL;
 
-	if (pci_mmconfig_add(0, 0, (len >> 20) - 1, pciexbar & mask) == NULL)
+	if (pci_ecam_add(0, 0, (len >> 20) - 1, pciexbar & mask) == NULL)
 		return NULL;
 
 	return "Intel Corporation 945G/GZ/P/PL Express Memory Controller Hub";
@@ -175,13 +175,13 @@ static const char *__init pci_mmcfg_amd_fam10h(void)
 
 	end_bus = (1 << busnbits) - 1;
 	for (i = 0; i < (1 << segnbits); i++)
-		if (pci_mmconfig_add(i, 0, end_bus,
+		if (pci_ecam_add(i, 0, end_bus,
 				     base + (1<<28) * i) == NULL) {
-			free_all_mmcfg();
+			pci_ecam_free_all();
 			return NULL;
 		}
 
-	pci_mmconfig_register_mmio(&pci_mmcfg_mmio_amd_fam10h);
+	pci_ecam_register_mmio(&pci_mmcfg_mmio_amd_fam10h);
 
 	return "AMD Family 10h NB";
 }
@@ -210,7 +210,7 @@ static const char *__init pci_mmcfg_nvidia_mcp55(void)
 	/*
 	 * do check if amd fam10h already took over
 	 */
-	if (!acpi_disabled || !list_empty(&pci_mmcfg_list) || mcp55_checked)
+	if (!acpi_disabled || !list_empty(&pci_ecam_list) || mcp55_checked)
 		return NULL;
 
 	mcp55_checked = true;
@@ -239,7 +239,7 @@ static const char *__init pci_mmcfg_nvidia_mcp55(void)
 		base <<= extcfg_base_lshift;
 		start = (extcfg & extcfg_start_mask) >> extcfg_start_shift;
 		end = start + extcfg_sizebus[size_index] - 1;
-		if (pci_mmconfig_add(0, start, end, base) == NULL)
+		if (pci_ecam_add(0, start, end, base) == NULL)
 			continue;
 		mcp55_mmconf_found++;
 	}
@@ -273,15 +273,15 @@ static const struct pci_mmcfg_hostbridge_probe pci_mmcfg_probes[] __initconst =
 
 static void __init pci_mmcfg_check_end_bus_number(void)
 {
-	struct pci_mmcfg_region *cfg, *cfgx;
+	struct pci_ecam_region *cfg, *cfgx;
 
 	/* Fixup overlaps */
-	list_for_each_entry(cfg, &pci_mmcfg_list, list) {
+	list_for_each_entry(cfg, &pci_ecam_list, list) {
 		if (cfg->end_bus < cfg->start_bus)
 			cfg->end_bus = 255;
 
 		/* Don't access the list head ! */
-		if (cfg->list.next == &pci_mmcfg_list)
+		if (cfg->list.next == &pci_ecam_list)
 			break;
 
 		cfgx = list_entry(cfg->list.next, typeof(*cfg), list);
@@ -301,7 +301,7 @@ static int __init pci_mmcfg_check_hostbridge(void)
 	if (!raw_pci_ops)
 		return 0;
 
-	free_all_mmcfg();
+	pci_ecam_free_all();
 
 	for (i = 0; i < ARRAY_SIZE(pci_mmcfg_probes); i++) {
 		bus =  pci_mmcfg_probes[i].bus;
@@ -322,7 +322,7 @@ static int __init pci_mmcfg_check_hostbridge(void)
 	/* some end_bus_number is crazy, fix it */
 	pci_mmcfg_check_end_bus_number();
 
-	return !list_empty(&pci_mmcfg_list);
+	return !list_empty(&pci_ecam_list);
 }
 
 static acpi_status check_mcfg_resource(struct acpi_resource *res, void *data)
@@ -395,7 +395,7 @@ static int is_acpi_reserved(u64 start, u64 end, unsigned not_used)
 typedef int (*check_reserved_t)(u64 start, u64 end, unsigned type);
 
 static int __ref is_mmconf_reserved(check_reserved_t is_reserved,
-				    struct pci_mmcfg_region *cfg,
+				    struct pci_ecam_region *cfg,
 				    struct device *dev, int with_e820)
 {
 	u64 addr = cfg->res.start;
@@ -425,8 +425,8 @@ static int __ref is_mmconf_reserved(check_reserved_t is_reserved,
 		cfg->end_bus = cfg->start_bus + ((size>>20) - 1);
 		num_buses = cfg->end_bus - cfg->start_bus + 1;
 		cfg->res.end = cfg->res.start +
-		    PCI_MMCFG_BUS_OFFSET(num_buses) - 1;
-		snprintf(cfg->name, PCI_MMCFG_RESOURCE_NAME_LEN,
+		    PCI_ECAM_BUS_OFFSET(num_buses) - 1;
+		snprintf(cfg->name, PCI_ECAM_RESOURCE_NAME_LEN,
 			 "PCI MMCONFIG %04x [bus %02x-%02x]",
 			 cfg->segment, cfg->start_bus, cfg->end_bus);
 
@@ -447,7 +447,7 @@ static int __ref is_mmconf_reserved(check_reserved_t is_reserved,
 }
 
 static int __ref pci_mmcfg_check_reserved(struct device *dev,
-		  struct pci_mmcfg_region *cfg, int early)
+		  struct pci_ecam_region *cfg, int early)
 {
 	if (!early && !acpi_disabled) {
 		if (is_mmconf_reserved(is_acpi_reserved, cfg, dev, 0))
@@ -484,12 +484,12 @@ static int __ref pci_mmcfg_check_reserved(struct device *dev,
 
 static void __init pci_mmcfg_reject_broken(int early)
 {
-	struct pci_mmcfg_region *cfg;
+	struct pci_ecam_region *cfg;
 
-	list_for_each_entry(cfg, &pci_mmcfg_list, list) {
+	list_for_each_entry(cfg, &pci_ecam_list, list) {
 		if (pci_mmcfg_check_reserved(NULL, cfg, early) == 0) {
 			pr_info(PREFIX "not using MMCONFIG\n");
-			free_all_mmcfg();
+			pci_ecam_free_all();
 			return;
 		}
 	}
@@ -502,13 +502,13 @@ extern int (*arch_apei_filter_addr)(int (*func)(__u64 start, __u64 size,
 static int pci_mmcfg_for_each_region(int (*func)(__u64 start, __u64 size,
 				     void *data), void *data)
 {
-	struct pci_mmcfg_region *cfg;
+	struct pci_ecam_region *cfg;
 	int rc;
 
-	if (list_empty(&pci_mmcfg_list))
+	if (list_empty(&pci_ecam_list))
 		return 0;
 
-	list_for_each_entry(cfg, &pci_mmcfg_list, list) {
+	list_for_each_entry(cfg, &pci_ecam_list, list) {
 		rc = func(cfg->res.start, resource_size(&cfg->res), data);
 		if (rc)
 			return rc;
@@ -524,24 +524,24 @@ static int pci_mmcfg_for_each_region(int (*func)(__u64 start, __u64 size,
 static void __init __pci_mmcfg_init(int early)
 {
 	pci_mmcfg_reject_broken(early);
-	if (list_empty(&pci_mmcfg_list))
+	if (list_empty(&pci_ecam_list))
 		return;
 
 	if (pcibios_last_bus < 0) {
-		const struct pci_mmcfg_region *cfg;
+		const struct pci_ecam_region *cfg;
 
-		list_for_each_entry(cfg, &pci_mmcfg_list, list) {
+		list_for_each_entry(cfg, &pci_ecam_list, list) {
 			if (cfg->segment)
 				break;
 			pcibios_last_bus = cfg->end_bus;
 		}
 	}
 
-	if (pci_mmcfg_arch_init()) {
+	if (pci_ecam_arch_init()) {
 		raw_pci_ext_ops = &pci_mmcfg;
 		pci_probe = (pci_probe & ~PCI_PROBE_MASK) | PCI_PROBE_MMCONF;
 	} else {
-		free_all_mmcfg();
+		pci_ecam_free_all();
 		pci_mmcfg_arch_init_failed = true;
 	}
 }
@@ -579,7 +579,7 @@ void __init pci_mmcfg_late_init(void)
 
 static int __init pci_mmcfg_late_insert_resources(void)
 {
-	struct pci_mmcfg_region *cfg;
+	struct pci_ecam_region *cfg;
 
 	pci_mmcfg_running_state = true;
 
@@ -592,7 +592,7 @@ static int __init pci_mmcfg_late_insert_resources(void)
 	 * marked so it won't cause request errors when __request_region is
 	 * called.
 	 */
-	list_for_each_entry(cfg, &pci_mmcfg_list, list)
+	list_for_each_entry(cfg, &pci_ecam_list, list)
 		if (!cfg->res.parent)
 			insert_resource(&iomem_resource, &cfg->res);
 
@@ -612,7 +612,7 @@ int pci_mmconfig_insert(struct device *dev, u16 seg, u8 start, u8 end,
 {
 	int rc;
 	struct resource *tmp = NULL;
-	struct pci_mmcfg_region *cfg;
+	struct pci_ecam_region *cfg;
 
 	if (!(pci_probe & PCI_PROBE_MMCONF) || pci_mmcfg_arch_init_failed)
 		return -ENODEV;
@@ -621,7 +621,7 @@ int pci_mmconfig_insert(struct device *dev, u16 seg, u8 start, u8 end,
 		return -EINVAL;
 
 	rc = -EBUSY;
-	cfg = pci_mmconfig_alloc(seg, start, end, addr);
+	cfg = pci_ecam_alloc(seg, start, end, addr);
 	if (cfg == NULL) {
 		dev_warn(dev, "fail to add MMCONFIG (out of memory)\n");
 		return -ENOMEM;
@@ -642,7 +642,7 @@ int pci_mmconfig_insert(struct device *dev, u16 seg, u8 start, u8 end,
 		goto error;
 	}
 
-	rc = pci_mmconfig_inject(cfg);
+	rc = pci_ecam_inject(cfg);
 	if (rc)
 		goto error;
 
diff --git a/arch/x86/pci/mmconfig_32.c b/arch/x86/pci/mmconfig_32.c
index 7a050cb..27e707d 100644
--- a/arch/x86/pci/mmconfig_32.c
+++ b/arch/x86/pci/mmconfig_32.c
@@ -28,7 +28,7 @@ static int mmcfg_last_accessed_cpu;
  */
 static u32 get_base_addr(unsigned int seg, int bus, unsigned devfn)
 {
-	struct pci_mmcfg_region *cfg = pci_mmconfig_lookup(seg, bus);
+	struct pci_ecam_region *cfg = pci_ecam_lookup(seg, bus);
 
 	if (cfg)
 		return cfg->address;
@@ -40,7 +40,7 @@ static u32 get_base_addr(unsigned int seg, int bus, unsigned devfn)
  */
 static void pci_exp_set_dev_base(unsigned int base, int bus, int devfn)
 {
-	u32 dev_base = base | PCI_MMCFG_BUS_OFFSET(bus) | (devfn << 12);
+	u32 dev_base = base | PCI_ECAM_BUS_OFFSET(bus) | (devfn << 12);
 	int cpu = smp_processor_id();
 	if (dev_base != mmcfg_last_accessed_device ||
 	    cpu != mmcfg_last_accessed_cpu) {
@@ -50,7 +50,7 @@ static void pci_exp_set_dev_base(unsigned int base, int bus, int devfn)
 	}
 }
 
-int pci_mmcfg_read(unsigned int seg, unsigned int bus,
+int pci_ecam_read(unsigned int seg, unsigned int bus,
 			  unsigned int devfn, int reg, int len, u32 *value)
 {
 	unsigned long flags;
@@ -79,7 +79,7 @@ err:		*value = -1;
 	return 0;
 }
 
-int pci_mmcfg_write(unsigned int seg, unsigned int bus,
+int pci_ecam_write(unsigned int seg, unsigned int bus,
 			   unsigned int devfn, int reg, int len, u32 value)
 {
 	unsigned long flags;
@@ -106,22 +106,22 @@ int pci_mmcfg_write(unsigned int seg, unsigned int bus,
 	return 0;
 }
 
-int __init pci_mmcfg_arch_init(void)
+int __init pci_ecam_arch_init(void)
 {
 	printk(KERN_INFO "PCI: Using MMCONFIG for extended config space\n");
 	return 1;
 }
 
-void __init pci_mmcfg_arch_free(void)
+void __init pci_ecam_arch_free(void)
 {
 }
 
-int pci_mmcfg_arch_map(struct pci_mmcfg_region *cfg)
+int pci_ecam_arch_map(struct pci_ecam_region *cfg)
 {
 	return 0;
 }
 
-void pci_mmcfg_arch_unmap(struct pci_mmcfg_region *cfg)
+void pci_ecam_arch_unmap(struct pci_ecam_region *cfg)
 {
 	unsigned long flags;
 
diff --git a/arch/x86/pci/numachip.c b/arch/x86/pci/numachip.c
index 01868b6..af41247 100644
--- a/arch/x86/pci/numachip.c
+++ b/arch/x86/pci/numachip.c
@@ -21,10 +21,10 @@ static u8 limit __read_mostly;
 
 static inline char __iomem *pci_dev_base(unsigned int seg, unsigned int bus, unsigned int devfn)
 {
-	struct pci_mmcfg_region *cfg = pci_mmconfig_lookup(seg, bus);
+	struct pci_ecam_region *cfg = pci_ecam_lookup(seg, bus);
 
 	if (cfg && cfg->virt)
-		return cfg->virt + (PCI_MMCFG_BUS_OFFSET(bus) | (devfn << 12));
+		return cfg->virt + (PCI_ECAM_BUS_OFFSET(bus) | (devfn << 12));
 	return NULL;
 }
 
diff --git a/drivers/acpi/mcfg.c b/drivers/acpi/mcfg.c
index e285f62..40926a3 100644
--- a/drivers/acpi/mcfg.c
+++ b/drivers/acpi/mcfg.c
@@ -24,13 +24,13 @@
 int __weak raw_pci_read(unsigned int domain, unsigned int bus,
 			unsigned int devfn, int reg, int len, u32 *val)
 {
-	return pci_mmcfg_read(domain, bus, devfn, reg, len, val);
+	return pci_ecam_read(domain, bus, devfn, reg, len, val);
 }
 
 int __weak raw_pci_write(unsigned int domain, unsigned int bus,
 			 unsigned int devfn, int reg, int len, u32 val)
 {
-	return pci_mmcfg_write(domain, bus, devfn, reg, len, val);
+	return pci_ecam_write(domain, bus, devfn, reg, len, val);
 }
 
 static int __init acpi_mcfg_check_entry(struct acpi_table_mcfg *mcfg,
@@ -69,7 +69,7 @@ int __init acpi_parse_mcfg(struct acpi_table_header *header)
 	mcfg = (struct acpi_table_mcfg *)header;
 
 	/* how many config structures do we have */
-	free_all_mmcfg();
+	pci_ecam_free_all();
 	entries = 0;
 	i = header->length - sizeof(struct acpi_table_mcfg);
 	while (i >= sizeof(struct acpi_mcfg_allocation)) {
@@ -85,14 +85,14 @@ int __init acpi_parse_mcfg(struct acpi_table_header *header)
 	for (i = 0; i < entries; i++) {
 		cfg = &cfg_table[i];
 		if (acpi_mcfg_check_entry(mcfg, cfg)) {
-			free_all_mmcfg();
+			pci_ecam_free_all();
 			return -ENODEV;
 		}
 
-		if (pci_mmconfig_add(cfg->pci_segment, cfg->start_bus_number,
+		if (pci_ecam_add(cfg->pci_segment, cfg->start_bus_number,
 				   cfg->end_bus_number, cfg->address) == NULL) {
 			pr_warn(PREFIX "no memory for MCFG entries\n");
-			free_all_mmcfg();
+			pci_ecam_free_all();
 			return -ENOMEM;
 		}
 	}
@@ -107,15 +107,15 @@ void __init __weak pci_mmcfg_early_init(void)
 
 void __init __weak pci_mmcfg_late_init(void)
 {
-	struct pci_mmcfg_region *cfg;
+	struct pci_ecam_region *cfg;
 
 	acpi_table_parse(ACPI_SIG_MCFG, acpi_parse_mcfg);
 
-	if (list_empty(&pci_mmcfg_list))
+	if (list_empty(&pci_ecam_list))
 		return;
-	if (!pci_mmcfg_arch_init())
-		free_all_mmcfg();
+	if (!pci_ecam_arch_init())
+		pci_ecam_free_all();
 
-	list_for_each_entry(cfg, &pci_mmcfg_list, list)
+	list_for_each_entry(cfg, &pci_ecam_list, list)
 		insert_resource(&iomem_resource, &cfg->res);
 }
diff --git a/drivers/pci/ecam.c b/drivers/pci/ecam.c
index 796b6e7..d6281a2 100644
--- a/drivers/pci/ecam.c
+++ b/drivers/pci/ecam.c
@@ -17,24 +17,24 @@
 
 #include <asm/io.h>
 
-#define PREFIX "PCI: "
+#define PREFIX "PCI ECAM: "
 
-static DEFINE_MUTEX(pci_mmcfg_lock);
+static DEFINE_MUTEX(pci_ecam_lock);
 
-LIST_HEAD(pci_mmcfg_list);
+LIST_HEAD(pci_ecam_list);
 
 #ifdef CONFIG_GENERIC_PCI_ECAM
 static char __iomem *pci_dev_base(unsigned int seg, unsigned int bus,
 				  unsigned int devfn)
 {
-	struct pci_mmcfg_region *cfg = pci_mmconfig_lookup(seg, bus);
+	struct pci_ecam_region *cfg = pci_ecam_lookup(seg, bus);
 
 	if (cfg && cfg->virt)
-		return cfg->virt + (PCI_MMCFG_BUS_OFFSET(bus) | (devfn << 12));
+		return cfg->virt + (PCI_ECAM_BUS_OFFSET(bus) | (devfn << 12));
 	return NULL;
 }
 
-int pci_mmcfg_read(unsigned int seg, unsigned int bus,
+int pci_ecam_read(unsigned int seg, unsigned int bus,
 			  unsigned int devfn, int reg, int len, u32 *value)
 {
 	char __iomem *addr;
@@ -58,7 +58,7 @@ err:		*value = -1;
 	return 0;
 }
 
-int pci_mmcfg_write(unsigned int seg, unsigned int bus,
+int pci_ecam_write(unsigned int seg, unsigned int bus,
 			   unsigned int devfn, int reg, int len, u32 value)
 {
 	char __iomem *addr;
@@ -80,64 +80,64 @@ int pci_mmcfg_write(unsigned int seg, unsigned int bus,
 	return 0;
 }
 
-static void __iomem *mcfg_ioremap(struct pci_mmcfg_region *cfg)
+static void __iomem *pci_ecam_ioremap(struct pci_ecam_region *cfg)
 {
 	void __iomem *addr;
 	u64 start, size;
 	int num_buses;
 
-	start = cfg->address + PCI_MMCFG_BUS_OFFSET(cfg->start_bus);
+	start = cfg->address + PCI_ECAM_BUS_OFFSET(cfg->start_bus);
 	num_buses = cfg->end_bus - cfg->start_bus + 1;
-	size = PCI_MMCFG_BUS_OFFSET(num_buses);
+	size = PCI_ECAM_BUS_OFFSET(num_buses);
 	addr = ioremap_nocache(start, size);
 	if (addr)
-		addr -= PCI_MMCFG_BUS_OFFSET(cfg->start_bus);
+		addr -= PCI_ECAM_BUS_OFFSET(cfg->start_bus);
 	return addr;
 }
 
-int __init pci_mmcfg_arch_init(void)
+int __init pci_ecam_arch_init(void)
 {
-	struct pci_mmcfg_region *cfg;
+	struct pci_ecam_region *cfg;
 
-	list_for_each_entry(cfg, &pci_mmcfg_list, list)
-		if (pci_mmcfg_arch_map(cfg)) {
-			pci_mmcfg_arch_free();
+	list_for_each_entry(cfg, &pci_ecam_list, list)
+		if (pci_ecam_arch_map(cfg)) {
+			pci_ecam_arch_free();
 			return 0;
 		}
 
 	return 1;
 }
 
-void __init pci_mmcfg_arch_free(void)
+void __init pci_ecam_arch_free(void)
 {
-	struct pci_mmcfg_region *cfg;
+	struct pci_ecam_region *cfg;
 
-	list_for_each_entry(cfg, &pci_mmcfg_list, list)
-		pci_mmcfg_arch_unmap(cfg);
+	list_for_each_entry(cfg, &pci_ecam_list, list)
+		pci_ecam_arch_unmap(cfg);
 }
 
-int pci_mmcfg_arch_map(struct pci_mmcfg_region *cfg)
+int pci_ecam_arch_map(struct pci_ecam_region *cfg)
 {
-	cfg->virt = mcfg_ioremap(cfg);
+	cfg->virt = pci_ecam_ioremap(cfg);
 	if (!cfg->virt) {
-		pr_err(PREFIX "can't map MMCONFIG at %pR\n", &cfg->res);
+		pr_err(PREFIX "can't map ECAM at %pR\n", &cfg->res);
 		return -ENOMEM;
 	}
 
 	return 0;
 }
 
-void pci_mmcfg_arch_unmap(struct pci_mmcfg_region *cfg)
+void pci_ecam_arch_unmap(struct pci_ecam_region *cfg)
 {
 	if (cfg && cfg->virt) {
-		iounmap(cfg->virt + PCI_MMCFG_BUS_OFFSET(cfg->start_bus));
+		iounmap(cfg->virt + PCI_ECAM_BUS_OFFSET(cfg->start_bus));
 		cfg->virt = NULL;
 	}
 }
 #endif
 
 static u32
-pci_mmconfig_generic_read(int len, void __iomem *addr)
+pci_ecam_generic_read(int len, void __iomem *addr)
 {
 	u32 data = 0;
 
@@ -157,7 +157,7 @@ pci_mmconfig_generic_read(int len, void __iomem *addr)
 }
 
 static void
-pci_mmconfig_generic_write(int len, void __iomem *addr, u32 value)
+pci_ecam_generic_write(int len, void __iomem *addr, u32 value)
 {
 	switch (len) {
 	case 1:
@@ -172,42 +172,42 @@ pci_mmconfig_generic_write(int len, void __iomem *addr, u32 value)
 	}
 }
 
-static struct pci_mmcfg_mmio_ops pci_mmcfg_mmio_default = {
-	.read = pci_mmconfig_generic_read,
-	.write = pci_mmconfig_generic_write,
+static struct pci_ecam_mmio_ops pci_ecam_mmio_default = {
+	.read = pci_ecam_generic_read,
+	.write = pci_ecam_generic_write,
 };
 
-static struct pci_mmcfg_mmio_ops *pci_mmcfg_mmio = &pci_mmcfg_mmio_default;
+static struct pci_ecam_mmio_ops *pci_ecam_mmio = &pci_ecam_mmio_default;
 
 void
-pci_mmconfig_register_mmio(struct pci_mmcfg_mmio_ops *ops)
+pci_ecam_register_mmio(struct pci_ecam_mmio_ops *ops)
 {
-	pci_mmcfg_mmio = ops;
+	pci_ecam_mmio = ops;
 }
 
 u32
 pci_mmio_read(int len, void __iomem *addr)
 {
-	if (!pci_mmcfg_mmio) {
+	if (!pci_ecam_mmio) {
 		pr_err("PCI config space has no accessors !");
 		return 0;
 	}
 
-	return pci_mmcfg_mmio->read(len, addr);
+	return pci_ecam_mmio->read(len, addr);
 }
 
 void
 pci_mmio_write(int len, void __iomem *addr, u32 value)
 {
-	if (!pci_mmcfg_mmio) {
+	if (!pci_ecam_mmio) {
 		pr_err("PCI config space has no accessors !");
 		return;
 	}
 
-	pci_mmcfg_mmio->write(len, addr, value);
+	pci_ecam_mmio->write(len, addr, value);
 }
 
-static void __init pci_mmconfig_remove(struct pci_mmcfg_region *cfg)
+static void __init pci_ecam_remove(struct pci_ecam_region *cfg)
 {
 	if (cfg->res.parent)
 		release_resource(&cfg->res);
@@ -215,21 +215,21 @@ static void __init pci_mmconfig_remove(struct pci_mmcfg_region *cfg)
 	kfree(cfg);
 }
 
-void __init free_all_mmcfg(void)
+void __init pci_ecam_free_all(void)
 {
-	struct pci_mmcfg_region *cfg, *tmp;
+	struct pci_ecam_region *cfg, *tmp;
 
-	pci_mmcfg_arch_free();
-	list_for_each_entry_safe(cfg, tmp, &pci_mmcfg_list, list)
-		pci_mmconfig_remove(cfg);
+	pci_ecam_arch_free();
+	list_for_each_entry_safe(cfg, tmp, &pci_ecam_list, list)
+		pci_ecam_remove(cfg);
 }
 
-void list_add_sorted(struct pci_mmcfg_region *new)
+void pci_ecam_list_add_sorted(struct pci_ecam_region *new)
 {
-	struct pci_mmcfg_region *cfg;
+	struct pci_ecam_region *cfg;
 
 	/* keep list sorted by segment and starting bus number */
-	list_for_each_entry_rcu(cfg, &pci_mmcfg_list, list) {
+	list_for_each_entry_rcu(cfg, &pci_ecam_list, list) {
 		if (cfg->segment > new->segment ||
 		    (cfg->segment == new->segment &&
 		     cfg->start_bus >= new->start_bus)) {
@@ -237,13 +237,13 @@ void list_add_sorted(struct pci_mmcfg_region *new)
 			return;
 		}
 	}
-	list_add_tail_rcu(&new->list, &pci_mmcfg_list);
+	list_add_tail_rcu(&new->list, &pci_ecam_list);
 }
 
-struct pci_mmcfg_region *pci_mmconfig_alloc(int segment, int start,
+struct pci_ecam_region *pci_ecam_alloc(int segment, int start,
 					    int end, u64 addr)
 {
-	struct pci_mmcfg_region *new;
+	struct pci_ecam_region *new;
 	struct resource *res;
 
 	if (addr == 0)
@@ -259,29 +259,29 @@ struct pci_mmcfg_region *pci_mmconfig_alloc(int segment, int start,
 	new->end_bus = end;
 
 	res = &new->res;
-	res->start = addr + PCI_MMCFG_BUS_OFFSET(start);
-	res->end = addr + PCI_MMCFG_BUS_OFFSET(end + 1) - 1;
+	res->start = addr + PCI_ECAM_BUS_OFFSET(start);
+	res->end = addr + PCI_ECAM_BUS_OFFSET(end + 1) - 1;
 	res->flags = IORESOURCE_MEM | IORESOURCE_BUSY;
-	snprintf(new->name, PCI_MMCFG_RESOURCE_NAME_LEN,
-		 "PCI MMCONFIG %04x [bus %02x-%02x]", segment, start, end);
+	snprintf(new->name, PCI_ECAM_RESOURCE_NAME_LEN,
+		 "PCI ECAM %04x [bus %02x-%02x]", segment, start, end);
 	res->name = new->name;
 
 	return new;
 }
 
-struct pci_mmcfg_region *pci_mmconfig_add(int segment, int start,
+struct pci_ecam_region *pci_ecam_add(int segment, int start,
 					  int end, u64 addr)
 {
-	struct pci_mmcfg_region *new;
+	struct pci_ecam_region *new;
 
-	new = pci_mmconfig_alloc(segment, start, end, addr);
+	new = pci_ecam_alloc(segment, start, end, addr);
 	if (new) {
-		mutex_lock(&pci_mmcfg_lock);
-		list_add_sorted(new);
-		mutex_unlock(&pci_mmcfg_lock);
+		mutex_lock(&pci_ecam_lock);
+		pci_ecam_list_add_sorted(new);
+		mutex_unlock(&pci_ecam_lock);
 
 		pr_info(PREFIX
-		       "MMCONFIG for domain %04x [bus %02x-%02x] at %pR "
+		       "ECAM for domain %04x [bus %02x-%02x] at %pR "
 		       "(base %#lx)\n",
 		       segment, start, end, &new->res, (unsigned long)addr);
 	}
@@ -289,11 +289,11 @@ struct pci_mmcfg_region *pci_mmconfig_add(int segment, int start,
 	return new;
 }
 
-struct pci_mmcfg_region *pci_mmconfig_lookup(int segment, int bus)
+struct pci_ecam_region *pci_ecam_lookup(int segment, int bus)
 {
-	struct pci_mmcfg_region *cfg;
+	struct pci_ecam_region *cfg;
 
-	list_for_each_entry_rcu(cfg, &pci_mmcfg_list, list)
+	list_for_each_entry_rcu(cfg, &pci_ecam_list, list)
 		if (cfg->segment == segment &&
 		    cfg->start_bus <= bus && bus <= cfg->end_bus)
 			return cfg;
@@ -301,39 +301,39 @@ struct pci_mmcfg_region *pci_mmconfig_lookup(int segment, int bus)
 	return NULL;
 }
 
-/* Delete MMCFG information for host bridges */
-int pci_mmconfig_delete(u16 seg, u8 start, u8 end)
+/* Delete ECAM information for host bridges */
+int pci_ecam_delete(u16 seg, u8 start, u8 end)
 {
-	struct pci_mmcfg_region *cfg;
+	struct pci_ecam_region *cfg;
 
-	mutex_lock(&pci_mmcfg_lock);
-	list_for_each_entry_rcu(cfg, &pci_mmcfg_list, list)
+	mutex_lock(&pci_ecam_lock);
+	list_for_each_entry_rcu(cfg, &pci_ecam_list, list)
 		if (cfg->segment == seg && cfg->start_bus == start &&
 		    cfg->end_bus == end) {
 			list_del_rcu(&cfg->list);
 			synchronize_rcu();
-			pci_mmcfg_arch_unmap(cfg);
+			pci_ecam_arch_unmap(cfg);
 			if (cfg->res.parent)
 				release_resource(&cfg->res);
-			mutex_unlock(&pci_mmcfg_lock);
+			mutex_unlock(&pci_ecam_lock);
 			kfree(cfg);
 			return 0;
 		}
-	mutex_unlock(&pci_mmcfg_lock);
+	mutex_unlock(&pci_ecam_lock);
 
 	return -ENOENT;
 }
 
-int pci_mmconfig_inject(struct pci_mmcfg_region *cfg)
+int pci_ecam_inject(struct pci_ecam_region *cfg)
 {
-	struct pci_mmcfg_region *cfg_conflict;
+	struct pci_ecam_region *cfg_conflict;
 	int err = 0;
 
-	mutex_lock(&pci_mmcfg_lock);
-	cfg_conflict = pci_mmconfig_lookup(cfg->segment, cfg->start_bus);
+	mutex_lock(&pci_ecam_lock);
+	cfg_conflict = pci_ecam_lookup(cfg->segment, cfg->start_bus);
 	if (cfg_conflict) {
 		if (cfg_conflict->end_bus < cfg->end_bus)
-			pr_info(FW_INFO "MMCONFIG for "
+			pr_info(FW_INFO "ECAM for "
 				"domain %04x [bus %02x-%02x] "
 				"only partially covers this bridge\n",
 				cfg_conflict->segment, cfg_conflict->start_bus,
@@ -342,17 +342,17 @@ int pci_mmconfig_inject(struct pci_mmcfg_region *cfg)
 		goto out;
 	}
 
-	if (pci_mmcfg_arch_map(cfg)) {
-		pr_warn("fail to map MMCONFIG %pR.\n", &cfg->res);
+	if (pci_ecam_arch_map(cfg)) {
+		pr_warn("fail to map ECAM %pR.\n", &cfg->res);
 		err = -ENOMEM;
 		goto out;
 	} else {
-		list_add_sorted(cfg);
-		pr_info("MMCONFIG at %pR (base %#lx)\n",
+		pci_ecam_list_add_sorted(cfg);
+		pr_info("ECAM at %pR (base %#lx)\n",
 			&cfg->res, (unsigned long)cfg->address);
 
 	}
 out:
-	mutex_unlock(&pci_mmcfg_lock);
+	mutex_unlock(&pci_ecam_lock);
 	return err;
 }
diff --git a/drivers/xen/pci.c b/drivers/xen/pci.c
index 7a34a72..76b3ca2 100644
--- a/drivers/xen/pci.c
+++ b/drivers/xen/pci.c
@@ -205,7 +205,7 @@ arch_initcall(register_xen_pci_notifier);
 #ifdef CONFIG_PCI_MMCONFIG
 static int __init xen_mcfg_late(void)
 {
-	struct pci_mmcfg_region *cfg;
+	struct pci_ecam_region *cfg;
 	int rc;
 
 	if (!xen_initial_domain())
@@ -214,11 +214,11 @@ static int __init xen_mcfg_late(void)
 	if ((pci_probe & PCI_PROBE_MMCONF) == 0)
 		return 0;
 
-	if (list_empty(&pci_mmcfg_list))
+	if (list_empty(&pci_ecam_list))
 		return 0;
 
 	/* Check whether they are in the right area. */
-	list_for_each_entry(cfg, &pci_mmcfg_list, list) {
+	list_for_each_entry(cfg, &pci_ecam_list, list) {
 		struct physdev_pci_mmcfg_reserved r;
 
 		r.address = cfg->address;
diff --git a/include/linux/ecam.h b/include/linux/ecam.h
index fba5d6b..363691b 100644
--- a/include/linux/ecam.h
+++ b/include/linux/ecam.h
@@ -5,10 +5,10 @@
 #include <linux/types.h>
 #include <linux/acpi.h>
 
-/* "PCI MMCONFIG %04x [bus %02x-%02x]" */
-#define PCI_MMCFG_RESOURCE_NAME_LEN (22 + 4 + 2 + 2)
+/* "PCI ECAM %04x [bus %02x-%02x]" */
+#define PCI_ECAM_RESOURCE_NAME_LEN (22 + 4 + 2 + 2)
 
-struct pci_mmcfg_region {
+struct pci_ecam_region {
 	struct list_head list;
 	struct resource res;
 	u64 address;
@@ -16,40 +16,40 @@ struct pci_mmcfg_region {
 	u16 segment;
 	u8 start_bus;
 	u8 end_bus;
-	char name[PCI_MMCFG_RESOURCE_NAME_LEN];
+	char name[PCI_ECAM_RESOURCE_NAME_LEN];
 };
 
-struct pci_mmcfg_mmio_ops {
+struct pci_ecam_mmio_ops {
 	u32 (*read)(int len, void __iomem *addr);
 	void (*write)(int len, void __iomem *addr, u32 value);
 };
 
-struct pci_mmcfg_region *pci_mmconfig_lookup(int segment, int bus);
-struct pci_mmcfg_region *pci_mmconfig_alloc(int segment, int start,
+struct pci_ecam_region *pci_ecam_lookup(int segment, int bus);
+struct pci_ecam_region *pci_ecam_alloc(int segment, int start,
 						   int end, u64 addr);
-int pci_mmconfig_inject(struct pci_mmcfg_region *cfg);
-struct pci_mmcfg_region *pci_mmconfig_add(int segment, int start,
+int pci_ecam_inject(struct pci_ecam_region *cfg);
+struct pci_ecam_region *pci_ecam_add(int segment, int start,
 						 int end, u64 addr);
-void list_add_sorted(struct pci_mmcfg_region *new);
-void free_all_mmcfg(void);
-int pci_mmconfig_delete(u16 seg, u8 start, u8 end);
+void pci_ecam_list_add_sorted(struct pci_ecam_region *new);
+void pci_ecam_free_all(void);
+int pci_ecam_delete(u16 seg, u8 start, u8 end);
 
 /* Arch specific calls */
-int pci_mmcfg_arch_init(void);
-void pci_mmcfg_arch_free(void);
-int pci_mmcfg_arch_map(struct pci_mmcfg_region *cfg);
-void pci_mmcfg_arch_unmap(struct pci_mmcfg_region *cfg);
+int pci_ecam_arch_init(void);
+void pci_ecam_arch_free(void);
+int pci_ecam_arch_map(struct pci_ecam_region *cfg);
+void pci_ecam_arch_unmap(struct pci_ecam_region *cfg);
 extern u32 pci_mmio_read(int len, void __iomem *addr);
 extern void pci_mmio_write(int len, void __iomem *addr, u32 value);
-extern void pci_mmconfig_register_mmio(struct pci_mmcfg_mmio_ops *ops);
+extern void pci_ecam_register_mmio(struct pci_ecam_mmio_ops *ops);
 
-extern struct list_head pci_mmcfg_list;
+extern struct list_head pci_ecam_list;
 
-#define PCI_MMCFG_BUS_OFFSET(bus)      ((bus) << 20)
+#define PCI_ECAM_BUS_OFFSET(bus)      ((bus) << 20)
 
-int pci_mmcfg_read(unsigned int seg, unsigned int bus,
+int pci_ecam_read(unsigned int seg, unsigned int bus,
 		   unsigned int devfn, int reg, int len, u32 *value);
-int pci_mmcfg_write(unsigned int seg, unsigned int bus,
+int pci_ecam_write(unsigned int seg, unsigned int bus,
 		    unsigned int devfn, int reg, int len, u32 value);
 
 #endif  /* __KERNEL__ */
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 38+ messages in thread

* Re: [PATCH v4 2/9] x86, pci: Abstract PCI config accessors and use AMD Fam10h workaround exclusively.
  2015-03-11 14:12   ` Tomasz Nowicki
  (?)
@ 2015-03-11 15:19     ` Rob Herring
  -1 siblings, 0 replies; 38+ messages in thread
From: Rob Herring @ 2015-03-11 15:19 UTC (permalink / raw)
  To: Tomasz Nowicki
  Cc: Bjorn Helgaas, Yijing Wang, Arnd Bergmann, Hanjun Guo,
	Liviu Dudau, Thomas Gleixner, Ingo Molnar, H. Peter Anvin,
	Rafael J. Wysocki, Al Stone, linaro-acpi, linux-pci, x86,
	linux-kernel, linux-acpi, linux-arm-kernel

On Wed, Mar 11, 2015 at 9:12 AM, Tomasz Nowicki
<tomasz.nowicki@linaro.org> wrote:
> From now on, readb()/writeb()/etc. generic calls are used as default
> approach. Special MMIO accessors are registered for AMD Fam10h CPUs only.
>
> Signed-off-by: Tomasz Nowicki <tomasz.nowicki@linaro.org>
> ---
>  arch/x86/include/asm/pci_x86.h |   8 +++
>  arch/x86/pci/mmconfig-shared.c | 114 +++++++++++++++++++++++++++++++++++++++++
>  arch/x86/pci/mmconfig_32.c     |  24 +--------
>  arch/x86/pci/mmconfig_64.c     |  24 +--------
>  arch/x86/pci/numachip.c        |  24 +--------
>  5 files changed, 128 insertions(+), 66 deletions(-)
>
> diff --git a/arch/x86/include/asm/pci_x86.h b/arch/x86/include/asm/pci_x86.h
> index d024f4d..c57c225 100644
> --- a/arch/x86/include/asm/pci_x86.h
> +++ b/arch/x86/include/asm/pci_x86.h
> @@ -137,6 +137,11 @@ struct pci_mmcfg_region {
>         char name[PCI_MMCFG_RESOURCE_NAME_LEN];
>  };
>
> +struct pci_mmcfg_mmio_ops {
> +       u32 (*read)(int len, void __iomem *addr);
> +       void (*write)(int len, void __iomem *addr, u32 value);

We already have nearly the same struct with pci_ops...

> +};
> +
>  extern int __init pci_mmcfg_arch_init(void);
>  extern void __init pci_mmcfg_arch_free(void);
>  extern int pci_mmcfg_arch_map(struct pci_mmcfg_region *cfg);
> @@ -145,6 +150,9 @@ extern int pci_mmconfig_insert(struct device *dev, u16 seg, u8 start, u8 end,
>                                phys_addr_t addr);
>  extern int pci_mmconfig_delete(u16 seg, u8 start, u8 end);
>  extern struct pci_mmcfg_region *pci_mmconfig_lookup(int segment, int bus);
> +extern u32 pci_mmio_read(int len, void __iomem *addr);
> +extern void pci_mmio_write(int len, void __iomem *addr, u32 value);
> +extern void pci_mmconfig_register_mmio(struct pci_mmcfg_mmio_ops *ops);
>
>  extern struct list_head pci_mmcfg_list;
>
> diff --git a/arch/x86/pci/mmconfig-shared.c b/arch/x86/pci/mmconfig-shared.c
> index dd30b7e..8b3bc4f 100644
> --- a/arch/x86/pci/mmconfig-shared.c
> +++ b/arch/x86/pci/mmconfig-shared.c
> @@ -31,6 +31,118 @@ static DEFINE_MUTEX(pci_mmcfg_lock);
>
>  LIST_HEAD(pci_mmcfg_list);
>
> +static u32
> +pci_mmconfig_generic_read(int len, void __iomem *addr)
> +{
> +       u32 data = 0;
> +
> +       switch (len) {
> +       case 1:
> +               data = readb(addr);
> +               break;
> +       case 2:
> +               data = readw(addr);
> +               break;
> +       case 4:
> +               data = readl(addr);
> +               break;
> +       }

This same function logic already exists with pci_generic_config_read.
I think you need to move the differentiation between AMD and generic
ECAM to pci_ops.

Rob

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH v4 2/9] x86, pci: Abstract PCI config accessors and use AMD Fam10h workaround exclusively.
@ 2015-03-11 15:19     ` Rob Herring
  0 siblings, 0 replies; 38+ messages in thread
From: Rob Herring @ 2015-03-11 15:19 UTC (permalink / raw)
  To: Tomasz Nowicki
  Cc: Bjorn Helgaas, Yijing Wang, Arnd Bergmann, Hanjun Guo,
	Liviu Dudau, Thomas Gleixner, Ingo Molnar, H. Peter Anvin,
	Rafael J. Wysocki, Al Stone, linaro-acpi, linux-pci, x86,
	linux-kernel, linux-acpi, linux-arm-kernel

On Wed, Mar 11, 2015 at 9:12 AM, Tomasz Nowicki
<tomasz.nowicki@linaro.org> wrote:
> From now on, readb()/writeb()/etc. generic calls are used as default
> approach. Special MMIO accessors are registered for AMD Fam10h CPUs only.
>
> Signed-off-by: Tomasz Nowicki <tomasz.nowicki@linaro.org>
> ---
>  arch/x86/include/asm/pci_x86.h |   8 +++
>  arch/x86/pci/mmconfig-shared.c | 114 +++++++++++++++++++++++++++++++++++++++++
>  arch/x86/pci/mmconfig_32.c     |  24 +--------
>  arch/x86/pci/mmconfig_64.c     |  24 +--------
>  arch/x86/pci/numachip.c        |  24 +--------
>  5 files changed, 128 insertions(+), 66 deletions(-)
>
> diff --git a/arch/x86/include/asm/pci_x86.h b/arch/x86/include/asm/pci_x86.h
> index d024f4d..c57c225 100644
> --- a/arch/x86/include/asm/pci_x86.h
> +++ b/arch/x86/include/asm/pci_x86.h
> @@ -137,6 +137,11 @@ struct pci_mmcfg_region {
>         char name[PCI_MMCFG_RESOURCE_NAME_LEN];
>  };
>
> +struct pci_mmcfg_mmio_ops {
> +       u32 (*read)(int len, void __iomem *addr);
> +       void (*write)(int len, void __iomem *addr, u32 value);

We already have nearly the same struct with pci_ops...

> +};
> +
>  extern int __init pci_mmcfg_arch_init(void);
>  extern void __init pci_mmcfg_arch_free(void);
>  extern int pci_mmcfg_arch_map(struct pci_mmcfg_region *cfg);
> @@ -145,6 +150,9 @@ extern int pci_mmconfig_insert(struct device *dev, u16 seg, u8 start, u8 end,
>                                phys_addr_t addr);
>  extern int pci_mmconfig_delete(u16 seg, u8 start, u8 end);
>  extern struct pci_mmcfg_region *pci_mmconfig_lookup(int segment, int bus);
> +extern u32 pci_mmio_read(int len, void __iomem *addr);
> +extern void pci_mmio_write(int len, void __iomem *addr, u32 value);
> +extern void pci_mmconfig_register_mmio(struct pci_mmcfg_mmio_ops *ops);
>
>  extern struct list_head pci_mmcfg_list;
>
> diff --git a/arch/x86/pci/mmconfig-shared.c b/arch/x86/pci/mmconfig-shared.c
> index dd30b7e..8b3bc4f 100644
> --- a/arch/x86/pci/mmconfig-shared.c
> +++ b/arch/x86/pci/mmconfig-shared.c
> @@ -31,6 +31,118 @@ static DEFINE_MUTEX(pci_mmcfg_lock);
>
>  LIST_HEAD(pci_mmcfg_list);
>
> +static u32
> +pci_mmconfig_generic_read(int len, void __iomem *addr)
> +{
> +       u32 data = 0;
> +
> +       switch (len) {
> +       case 1:
> +               data = readb(addr);
> +               break;
> +       case 2:
> +               data = readw(addr);
> +               break;
> +       case 4:
> +               data = readl(addr);
> +               break;
> +       }

This same function logic already exists with pci_generic_config_read.
I think you need to move the differentiation between AMD and generic
ECAM to pci_ops.

Rob

^ permalink raw reply	[flat|nested] 38+ messages in thread

* [PATCH v4 2/9] x86, pci: Abstract PCI config accessors and use AMD Fam10h workaround exclusively.
@ 2015-03-11 15:19     ` Rob Herring
  0 siblings, 0 replies; 38+ messages in thread
From: Rob Herring @ 2015-03-11 15:19 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Mar 11, 2015 at 9:12 AM, Tomasz Nowicki
<tomasz.nowicki@linaro.org> wrote:
> From now on, readb()/writeb()/etc. generic calls are used as default
> approach. Special MMIO accessors are registered for AMD Fam10h CPUs only.
>
> Signed-off-by: Tomasz Nowicki <tomasz.nowicki@linaro.org>
> ---
>  arch/x86/include/asm/pci_x86.h |   8 +++
>  arch/x86/pci/mmconfig-shared.c | 114 +++++++++++++++++++++++++++++++++++++++++
>  arch/x86/pci/mmconfig_32.c     |  24 +--------
>  arch/x86/pci/mmconfig_64.c     |  24 +--------
>  arch/x86/pci/numachip.c        |  24 +--------
>  5 files changed, 128 insertions(+), 66 deletions(-)
>
> diff --git a/arch/x86/include/asm/pci_x86.h b/arch/x86/include/asm/pci_x86.h
> index d024f4d..c57c225 100644
> --- a/arch/x86/include/asm/pci_x86.h
> +++ b/arch/x86/include/asm/pci_x86.h
> @@ -137,6 +137,11 @@ struct pci_mmcfg_region {
>         char name[PCI_MMCFG_RESOURCE_NAME_LEN];
>  };
>
> +struct pci_mmcfg_mmio_ops {
> +       u32 (*read)(int len, void __iomem *addr);
> +       void (*write)(int len, void __iomem *addr, u32 value);

We already have nearly the same struct with pci_ops...

> +};
> +
>  extern int __init pci_mmcfg_arch_init(void);
>  extern void __init pci_mmcfg_arch_free(void);
>  extern int pci_mmcfg_arch_map(struct pci_mmcfg_region *cfg);
> @@ -145,6 +150,9 @@ extern int pci_mmconfig_insert(struct device *dev, u16 seg, u8 start, u8 end,
>                                phys_addr_t addr);
>  extern int pci_mmconfig_delete(u16 seg, u8 start, u8 end);
>  extern struct pci_mmcfg_region *pci_mmconfig_lookup(int segment, int bus);
> +extern u32 pci_mmio_read(int len, void __iomem *addr);
> +extern void pci_mmio_write(int len, void __iomem *addr, u32 value);
> +extern void pci_mmconfig_register_mmio(struct pci_mmcfg_mmio_ops *ops);
>
>  extern struct list_head pci_mmcfg_list;
>
> diff --git a/arch/x86/pci/mmconfig-shared.c b/arch/x86/pci/mmconfig-shared.c
> index dd30b7e..8b3bc4f 100644
> --- a/arch/x86/pci/mmconfig-shared.c
> +++ b/arch/x86/pci/mmconfig-shared.c
> @@ -31,6 +31,118 @@ static DEFINE_MUTEX(pci_mmcfg_lock);
>
>  LIST_HEAD(pci_mmcfg_list);
>
> +static u32
> +pci_mmconfig_generic_read(int len, void __iomem *addr)
> +{
> +       u32 data = 0;
> +
> +       switch (len) {
> +       case 1:
> +               data = readb(addr);
> +               break;
> +       case 2:
> +               data = readw(addr);
> +               break;
> +       case 4:
> +               data = readl(addr);
> +               break;
> +       }

This same function logic already exists with pci_generic_config_read.
I think you need to move the differentiation between AMD and generic
ECAM to pci_ops.

Rob

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH v4 7/9] x86, pci, ecam: mmconfig_64.c becomes default implementation for ECAM driver.
  2015-03-11 14:12   ` Tomasz Nowicki
  (?)
@ 2015-03-11 15:37     ` Rob Herring
  -1 siblings, 0 replies; 38+ messages in thread
From: Rob Herring @ 2015-03-11 15:37 UTC (permalink / raw)
  To: Tomasz Nowicki
  Cc: Bjorn Helgaas, Yijing Wang, Arnd Bergmann, Hanjun Guo,
	Liviu Dudau, Thomas Gleixner, Ingo Molnar, H. Peter Anvin,
	Rafael J. Wysocki, Al Stone, linaro-acpi, linux-pci, x86,
	linux-kernel, linux-acpi, linux-arm-kernel

On Wed, Mar 11, 2015 at 9:12 AM, Tomasz Nowicki
<tomasz.nowicki@linaro.org> wrote:
> Architectures which want to take advantage of ECAM generic goodness

This is not necessarily an architecture decision. It is likely per host.

> should select CONFIG_PCI_ECAM_GENERIC. Otherwise, like x86 32bits machines,
> are obligated to provide own low-level ECAM calls.
>
> Signed-off-by: Tomasz Nowicki <tomasz.nowicki@linaro.org>
> ---

[...]

> diff --git a/drivers/pci/ecam.c b/drivers/pci/ecam.c
> index c588234..796b6e7 100644
> --- a/drivers/pci/ecam.c
> +++ b/drivers/pci/ecam.c
> @@ -23,6 +23,119 @@ static DEFINE_MUTEX(pci_mmcfg_lock);
>
>  LIST_HEAD(pci_mmcfg_list);
>
> +#ifdef CONFIG_GENERIC_PCI_ECAM
> +static char __iomem *pci_dev_base(unsigned int seg, unsigned int bus,
> +                                 unsigned int devfn)
> +{
> +       struct pci_mmcfg_region *cfg = pci_mmconfig_lookup(seg, bus);
> +
> +       if (cfg && cfg->virt)
> +               return cfg->virt + (PCI_MMCFG_BUS_OFFSET(bus) | (devfn << 12));
> +       return NULL;
> +}
> +
> +int pci_mmcfg_read(unsigned int seg, unsigned int bus,
> +                         unsigned int devfn, int reg, int len, u32 *value)
> +{
> +       char __iomem *addr;
> +
> +       /* Why do we have this when nobody checks it. How about a BUG()!? -AK */
> +       if (unlikely((bus > 255) || (devfn > 255) || (reg > 4095))) {
> +err:           *value = -1;
> +               return -EINVAL;
> +       }
> +
> +       rcu_read_lock();

What is the purpose of the rcu lock other than the old implementation had it?

> +       addr = pci_dev_base(seg, bus, devfn);

The .map_bus op provides the same function if you restructure to use
the generic accessors.

> +       if (!addr) {
> +               rcu_read_unlock();
> +               goto err;
> +       }
> +
> +       *value = pci_mmio_read(len, addr + reg);
> +       rcu_read_unlock();
> +
> +       return 0;
> +}
> +
> +int pci_mmcfg_write(unsigned int seg, unsigned int bus,
> +                          unsigned int devfn, int reg, int len, u32 value)
> +{
> +       char __iomem *addr;
> +
> +       /* Why do we have this when nobody checks it. How about a BUG()!? -AK */
> +       if (unlikely((bus > 255) || (devfn > 255) || (reg > 4095)))
> +               return -EINVAL;
> +
> +       rcu_read_lock();
> +       addr = pci_dev_base(seg, bus, devfn);
> +       if (!addr) {
> +               rcu_read_unlock();
> +               return -EINVAL;
> +       }
> +
> +       pci_mmio_write(len, addr + reg, value);
> +       rcu_read_unlock();
> +
> +       return 0;
> +}
> +
> +static void __iomem *mcfg_ioremap(struct pci_mmcfg_region *cfg)
> +{
> +       void __iomem *addr;
> +       u64 start, size;
> +       int num_buses;
> +
> +       start = cfg->address + PCI_MMCFG_BUS_OFFSET(cfg->start_bus);
> +       num_buses = cfg->end_bus - cfg->start_bus + 1;
> +       size = PCI_MMCFG_BUS_OFFSET(num_buses);
> +       addr = ioremap_nocache(start, size);
> +       if (addr)
> +               addr -= PCI_MMCFG_BUS_OFFSET(cfg->start_bus);
> +       return addr;
> +}
> +
> +int __init pci_mmcfg_arch_init(void)

Where would this be called for the case of the generic host and using DT?

Rob

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH v4 7/9] x86, pci, ecam: mmconfig_64.c becomes default implementation for ECAM driver.
@ 2015-03-11 15:37     ` Rob Herring
  0 siblings, 0 replies; 38+ messages in thread
From: Rob Herring @ 2015-03-11 15:37 UTC (permalink / raw)
  To: Tomasz Nowicki
  Cc: Bjorn Helgaas, Yijing Wang, Arnd Bergmann, Hanjun Guo,
	Liviu Dudau, Thomas Gleixner, Ingo Molnar, H. Peter Anvin,
	Rafael J. Wysocki, Al Stone, linaro-acpi, linux-pci, x86,
	linux-kernel, linux-acpi, linux-arm-kernel

On Wed, Mar 11, 2015 at 9:12 AM, Tomasz Nowicki
<tomasz.nowicki@linaro.org> wrote:
> Architectures which want to take advantage of ECAM generic goodness

This is not necessarily an architecture decision. It is likely per host.

> should select CONFIG_PCI_ECAM_GENERIC. Otherwise, like x86 32bits machines,
> are obligated to provide own low-level ECAM calls.
>
> Signed-off-by: Tomasz Nowicki <tomasz.nowicki@linaro.org>
> ---

[...]

> diff --git a/drivers/pci/ecam.c b/drivers/pci/ecam.c
> index c588234..796b6e7 100644
> --- a/drivers/pci/ecam.c
> +++ b/drivers/pci/ecam.c
> @@ -23,6 +23,119 @@ static DEFINE_MUTEX(pci_mmcfg_lock);
>
>  LIST_HEAD(pci_mmcfg_list);
>
> +#ifdef CONFIG_GENERIC_PCI_ECAM
> +static char __iomem *pci_dev_base(unsigned int seg, unsigned int bus,
> +                                 unsigned int devfn)
> +{
> +       struct pci_mmcfg_region *cfg = pci_mmconfig_lookup(seg, bus);
> +
> +       if (cfg && cfg->virt)
> +               return cfg->virt + (PCI_MMCFG_BUS_OFFSET(bus) | (devfn << 12));
> +       return NULL;
> +}
> +
> +int pci_mmcfg_read(unsigned int seg, unsigned int bus,
> +                         unsigned int devfn, int reg, int len, u32 *value)
> +{
> +       char __iomem *addr;
> +
> +       /* Why do we have this when nobody checks it. How about a BUG()!? -AK */
> +       if (unlikely((bus > 255) || (devfn > 255) || (reg > 4095))) {
> +err:           *value = -1;
> +               return -EINVAL;
> +       }
> +
> +       rcu_read_lock();

What is the purpose of the rcu lock other than the old implementation had it?

> +       addr = pci_dev_base(seg, bus, devfn);

The .map_bus op provides the same function if you restructure to use
the generic accessors.

> +       if (!addr) {
> +               rcu_read_unlock();
> +               goto err;
> +       }
> +
> +       *value = pci_mmio_read(len, addr + reg);
> +       rcu_read_unlock();
> +
> +       return 0;
> +}
> +
> +int pci_mmcfg_write(unsigned int seg, unsigned int bus,
> +                          unsigned int devfn, int reg, int len, u32 value)
> +{
> +       char __iomem *addr;
> +
> +       /* Why do we have this when nobody checks it. How about a BUG()!? -AK */
> +       if (unlikely((bus > 255) || (devfn > 255) || (reg > 4095)))
> +               return -EINVAL;
> +
> +       rcu_read_lock();
> +       addr = pci_dev_base(seg, bus, devfn);
> +       if (!addr) {
> +               rcu_read_unlock();
> +               return -EINVAL;
> +       }
> +
> +       pci_mmio_write(len, addr + reg, value);
> +       rcu_read_unlock();
> +
> +       return 0;
> +}
> +
> +static void __iomem *mcfg_ioremap(struct pci_mmcfg_region *cfg)
> +{
> +       void __iomem *addr;
> +       u64 start, size;
> +       int num_buses;
> +
> +       start = cfg->address + PCI_MMCFG_BUS_OFFSET(cfg->start_bus);
> +       num_buses = cfg->end_bus - cfg->start_bus + 1;
> +       size = PCI_MMCFG_BUS_OFFSET(num_buses);
> +       addr = ioremap_nocache(start, size);
> +       if (addr)
> +               addr -= PCI_MMCFG_BUS_OFFSET(cfg->start_bus);
> +       return addr;
> +}
> +
> +int __init pci_mmcfg_arch_init(void)

Where would this be called for the case of the generic host and using DT?

Rob

^ permalink raw reply	[flat|nested] 38+ messages in thread

* [PATCH v4 7/9] x86, pci, ecam: mmconfig_64.c becomes default implementation for ECAM driver.
@ 2015-03-11 15:37     ` Rob Herring
  0 siblings, 0 replies; 38+ messages in thread
From: Rob Herring @ 2015-03-11 15:37 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Mar 11, 2015 at 9:12 AM, Tomasz Nowicki
<tomasz.nowicki@linaro.org> wrote:
> Architectures which want to take advantage of ECAM generic goodness

This is not necessarily an architecture decision. It is likely per host.

> should select CONFIG_PCI_ECAM_GENERIC. Otherwise, like x86 32bits machines,
> are obligated to provide own low-level ECAM calls.
>
> Signed-off-by: Tomasz Nowicki <tomasz.nowicki@linaro.org>
> ---

[...]

> diff --git a/drivers/pci/ecam.c b/drivers/pci/ecam.c
> index c588234..796b6e7 100644
> --- a/drivers/pci/ecam.c
> +++ b/drivers/pci/ecam.c
> @@ -23,6 +23,119 @@ static DEFINE_MUTEX(pci_mmcfg_lock);
>
>  LIST_HEAD(pci_mmcfg_list);
>
> +#ifdef CONFIG_GENERIC_PCI_ECAM
> +static char __iomem *pci_dev_base(unsigned int seg, unsigned int bus,
> +                                 unsigned int devfn)
> +{
> +       struct pci_mmcfg_region *cfg = pci_mmconfig_lookup(seg, bus);
> +
> +       if (cfg && cfg->virt)
> +               return cfg->virt + (PCI_MMCFG_BUS_OFFSET(bus) | (devfn << 12));
> +       return NULL;
> +}
> +
> +int pci_mmcfg_read(unsigned int seg, unsigned int bus,
> +                         unsigned int devfn, int reg, int len, u32 *value)
> +{
> +       char __iomem *addr;
> +
> +       /* Why do we have this when nobody checks it. How about a BUG()!? -AK */
> +       if (unlikely((bus > 255) || (devfn > 255) || (reg > 4095))) {
> +err:           *value = -1;
> +               return -EINVAL;
> +       }
> +
> +       rcu_read_lock();

What is the purpose of the rcu lock other than the old implementation had it?

> +       addr = pci_dev_base(seg, bus, devfn);

The .map_bus op provides the same function if you restructure to use
the generic accessors.

> +       if (!addr) {
> +               rcu_read_unlock();
> +               goto err;
> +       }
> +
> +       *value = pci_mmio_read(len, addr + reg);
> +       rcu_read_unlock();
> +
> +       return 0;
> +}
> +
> +int pci_mmcfg_write(unsigned int seg, unsigned int bus,
> +                          unsigned int devfn, int reg, int len, u32 value)
> +{
> +       char __iomem *addr;
> +
> +       /* Why do we have this when nobody checks it. How about a BUG()!? -AK */
> +       if (unlikely((bus > 255) || (devfn > 255) || (reg > 4095)))
> +               return -EINVAL;
> +
> +       rcu_read_lock();
> +       addr = pci_dev_base(seg, bus, devfn);
> +       if (!addr) {
> +               rcu_read_unlock();
> +               return -EINVAL;
> +       }
> +
> +       pci_mmio_write(len, addr + reg, value);
> +       rcu_read_unlock();
> +
> +       return 0;
> +}
> +
> +static void __iomem *mcfg_ioremap(struct pci_mmcfg_region *cfg)
> +{
> +       void __iomem *addr;
> +       u64 start, size;
> +       int num_buses;
> +
> +       start = cfg->address + PCI_MMCFG_BUS_OFFSET(cfg->start_bus);
> +       num_buses = cfg->end_bus - cfg->start_bus + 1;
> +       size = PCI_MMCFG_BUS_OFFSET(num_buses);
> +       addr = ioremap_nocache(start, size);
> +       if (addr)
> +               addr -= PCI_MMCFG_BUS_OFFSET(cfg->start_bus);
> +       return addr;
> +}
> +
> +int __init pci_mmcfg_arch_init(void)

Where would this be called for the case of the generic host and using DT?

Rob

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH v4 7/9] x86, pci, ecam: mmconfig_64.c becomes default implementation for ECAM driver.
  2015-03-11 14:12   ` Tomasz Nowicki
@ 2015-03-11 16:30     ` Brian Gerst
  -1 siblings, 0 replies; 38+ messages in thread
From: Brian Gerst @ 2015-03-11 16:30 UTC (permalink / raw)
  To: Tomasz Nowicki
  Cc: bhelgaas, wangyijing, arnd, hanjun.guo, Liviu.Dudau,
	Thomas Gleixner, Ingo Molnar, H. Peter Anvin, rjw, al.stone,
	linux-arm-kernel, Linux Kernel Mailing List,
	the arch/x86 maintainers, linux-pci, linux-acpi, linaro-acpi

On Wed, Mar 11, 2015 at 10:12 AM, Tomasz Nowicki
<tomasz.nowicki@linaro.org> wrote:

> diff --git a/arch/x86/pci/Makefile b/arch/x86/pci/Makefile
> index 5c6fc35..35c765b 100644
> --- a/arch/x86/pci/Makefile
> +++ b/arch/x86/pci/Makefile
> @@ -1,7 +1,10 @@
>  obj-y                          := i386.o init.o
>
>  obj-$(CONFIG_PCI_BIOS)         += pcbios.o
> -obj-$(CONFIG_PCI_MMCONFIG)     += mmconfig_$(BITS).o direct.o mmconfig-shared.o
> +obj-$(CONFIG_PCI_MMCONFIG)     += direct.o mmconfig-shared.o
> +ifeq ($(BITS),32)
> +obj-$(CONFIG_PCI_MMCONFIG)     += mmconfig_32.o
> +endif
>  obj-$(CONFIG_PCI_DIRECT)       += direct.o
>  obj-$(CONFIG_PCI_OLPC)         += olpc.o
>  obj-$(CONFIG_PCI_XEN)          += xen.o

This would be better written as:

mmconfig-y := direct.o mmconfig-shared.o
mmconfig-$(CONFIG_X86_32) += mmconfig_32.o
obj-$(CONFIG_PCI_MMCONFIG) += $(mmconfig-y)

--
Brian Gerst

^ permalink raw reply	[flat|nested] 38+ messages in thread

* [PATCH v4 7/9] x86, pci, ecam: mmconfig_64.c becomes default implementation for ECAM driver.
@ 2015-03-11 16:30     ` Brian Gerst
  0 siblings, 0 replies; 38+ messages in thread
From: Brian Gerst @ 2015-03-11 16:30 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Mar 11, 2015 at 10:12 AM, Tomasz Nowicki
<tomasz.nowicki@linaro.org> wrote:

> diff --git a/arch/x86/pci/Makefile b/arch/x86/pci/Makefile
> index 5c6fc35..35c765b 100644
> --- a/arch/x86/pci/Makefile
> +++ b/arch/x86/pci/Makefile
> @@ -1,7 +1,10 @@
>  obj-y                          := i386.o init.o
>
>  obj-$(CONFIG_PCI_BIOS)         += pcbios.o
> -obj-$(CONFIG_PCI_MMCONFIG)     += mmconfig_$(BITS).o direct.o mmconfig-shared.o
> +obj-$(CONFIG_PCI_MMCONFIG)     += direct.o mmconfig-shared.o
> +ifeq ($(BITS),32)
> +obj-$(CONFIG_PCI_MMCONFIG)     += mmconfig_32.o
> +endif
>  obj-$(CONFIG_PCI_DIRECT)       += direct.o
>  obj-$(CONFIG_PCI_OLPC)         += olpc.o
>  obj-$(CONFIG_PCI_XEN)          += xen.o

This would be better written as:

mmconfig-y := direct.o mmconfig-shared.o
mmconfig-$(CONFIG_X86_32) += mmconfig_32.o
obj-$(CONFIG_PCI_MMCONFIG) += $(mmconfig-y)

--
Brian Gerst

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH v4 7/9] x86, pci, ecam: mmconfig_64.c becomes default implementation for ECAM driver.
  2015-03-11 15:37     ` Rob Herring
  (?)
@ 2015-03-12 13:42       ` Tomasz Nowicki
  -1 siblings, 0 replies; 38+ messages in thread
From: Tomasz Nowicki @ 2015-03-12 13:42 UTC (permalink / raw)
  To: Rob Herring
  Cc: Bjorn Helgaas, Yijing Wang, Arnd Bergmann, Hanjun Guo,
	Liviu Dudau, Thomas Gleixner, Ingo Molnar, H. Peter Anvin,
	Rafael J. Wysocki, Al Stone, linaro-acpi, linux-pci, x86,
	linux-kernel, linux-acpi, linux-arm-kernel

On 11.03.2015 16:37, Rob Herring wrote:
> On Wed, Mar 11, 2015 at 9:12 AM, Tomasz Nowicki
> <tomasz.nowicki@linaro.org> wrote:
>> Architectures which want to take advantage of ECAM generic goodness
>
> This is not necessarily an architecture decision. It is likely per host.
Right, good point.

>
>> should select CONFIG_PCI_ECAM_GENERIC. Otherwise, like x86 32bits machines,
>> are obligated to provide own low-level ECAM calls.
>>
>> Signed-off-by: Tomasz Nowicki <tomasz.nowicki@linaro.org>
>> ---
>
> [...]
>
>> diff --git a/drivers/pci/ecam.c b/drivers/pci/ecam.c
>> index c588234..796b6e7 100644
>> --- a/drivers/pci/ecam.c
>> +++ b/drivers/pci/ecam.c
>> @@ -23,6 +23,119 @@ static DEFINE_MUTEX(pci_mmcfg_lock);
>>
>>   LIST_HEAD(pci_mmcfg_list);
>>
>> +#ifdef CONFIG_GENERIC_PCI_ECAM
>> +static char __iomem *pci_dev_base(unsigned int seg, unsigned int bus,
>> +                                 unsigned int devfn)
>> +{
>> +       struct pci_mmcfg_region *cfg = pci_mmconfig_lookup(seg, bus);
>> +
>> +       if (cfg && cfg->virt)
>> +               return cfg->virt + (PCI_MMCFG_BUS_OFFSET(bus) | (devfn << 12));
>> +       return NULL;
>> +}
>> +
>> +int pci_mmcfg_read(unsigned int seg, unsigned int bus,
>> +                         unsigned int devfn, int reg, int len, u32 *value)
>> +{
>> +       char __iomem *addr;
>> +
>> +       /* Why do we have this when nobody checks it. How about a BUG()!? -AK */
>> +       if (unlikely((bus > 255) || (devfn > 255) || (reg > 4095))) {
>> +err:           *value = -1;
>> +               return -EINVAL;
>> +       }
>> +
>> +       rcu_read_lock();
>
> What is the purpose of the rcu lock other than the old implementation had it?

Read/write calls consist on lookup RCU list (with MMCONFIG regions) and 
then corresponding operation. It is possible to hotplug another pci root 
bridge which leads to RCU list modification.

>
>> +       addr = pci_dev_base(seg, bus, devfn);
>
> The .map_bus op provides the same function if you restructure to use
> the generic accessors.

As you noticed, pci_mmcfg_{read,write} and 
pci_generic_config_{read,write} prototypes are different.

int pci_mmcfg_read(unsigned int seg, unsigned int bus,
                    unsigned int devfn, int reg, int len, u32 *value);
vs
int pci_generic_config_read(struct pci_bus *bus, unsigned int devfn,
                             int where, int size, u32 *val);

This is because pci_mmcfg_{read,write} can be used before pci root 
bridge initialization (while we have no struct pci_bus *bus) inside of 
ACPICA code (osl.c --> acpi_os_read_pci_configuration())

For that reason, I decide to create ECAM related new accessors which do 
not depend on host bridge presence. In other words, 
pci_generic_config_{read,write} can be built on pci_mmcfg_{read,write} 
but not the other way around.

In the light of above, I could not used .map_bus. I might not see a 
nicer way to solve that so any opinion/suggestion very appreciated :)

>
>> +       if (!addr) {
>> +               rcu_read_unlock();
>> +               goto err;
>> +       }
>> +
>> +       *value = pci_mmio_read(len, addr + reg);
>> +       rcu_read_unlock();
>> +
>> +       return 0;
>> +}
>> +
>> +int pci_mmcfg_write(unsigned int seg, unsigned int bus,
>> +                          unsigned int devfn, int reg, int len, u32 value)
>> +{
>> +       char __iomem *addr;
>> +
>> +       /* Why do we have this when nobody checks it. How about a BUG()!? -AK */
>> +       if (unlikely((bus > 255) || (devfn > 255) || (reg > 4095)))
>> +               return -EINVAL;
>> +
>> +       rcu_read_lock();
>> +       addr = pci_dev_base(seg, bus, devfn);
>> +       if (!addr) {
>> +               rcu_read_unlock();
>> +               return -EINVAL;
>> +       }
>> +
>> +       pci_mmio_write(len, addr + reg, value);
>> +       rcu_read_unlock();
>> +
>> +       return 0;
>> +}
>> +
>> +static void __iomem *mcfg_ioremap(struct pci_mmcfg_region *cfg)
>> +{
>> +       void __iomem *addr;
>> +       u64 start, size;
>> +       int num_buses;
>> +
>> +       start = cfg->address + PCI_MMCFG_BUS_OFFSET(cfg->start_bus);
>> +       num_buses = cfg->end_bus - cfg->start_bus + 1;
>> +       size = PCI_MMCFG_BUS_OFFSET(num_buses);
>> +       addr = ioremap_nocache(start, size);
>> +       if (addr)
>> +               addr -= PCI_MMCFG_BUS_OFFSET(cfg->start_bus);
>> +       return addr;
>> +}
>> +
>> +int __init pci_mmcfg_arch_init(void)
>
> Where would this be called for the case of the generic host and using DT?
>
I focused on sharing the code in ACPI context and did not consider DT. I 
think we can improve that code as next steps.

Tomasz

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH v4 7/9] x86, pci, ecam: mmconfig_64.c becomes default implementation for ECAM driver.
@ 2015-03-12 13:42       ` Tomasz Nowicki
  0 siblings, 0 replies; 38+ messages in thread
From: Tomasz Nowicki @ 2015-03-12 13:42 UTC (permalink / raw)
  To: Rob Herring
  Cc: Bjorn Helgaas, Yijing Wang, Arnd Bergmann, Hanjun Guo,
	Liviu Dudau, Thomas Gleixner, Ingo Molnar, H. Peter Anvin,
	Rafael J. Wysocki, Al Stone, linaro-acpi, linux-pci, x86,
	linux-kernel, linux-acpi, linux-arm-kernel

On 11.03.2015 16:37, Rob Herring wrote:
> On Wed, Mar 11, 2015 at 9:12 AM, Tomasz Nowicki
> <tomasz.nowicki@linaro.org> wrote:
>> Architectures which want to take advantage of ECAM generic goodness
>
> This is not necessarily an architecture decision. It is likely per host.
Right, good point.

>
>> should select CONFIG_PCI_ECAM_GENERIC. Otherwise, like x86 32bits machines,
>> are obligated to provide own low-level ECAM calls.
>>
>> Signed-off-by: Tomasz Nowicki <tomasz.nowicki@linaro.org>
>> ---
>
> [...]
>
>> diff --git a/drivers/pci/ecam.c b/drivers/pci/ecam.c
>> index c588234..796b6e7 100644
>> --- a/drivers/pci/ecam.c
>> +++ b/drivers/pci/ecam.c
>> @@ -23,6 +23,119 @@ static DEFINE_MUTEX(pci_mmcfg_lock);
>>
>>   LIST_HEAD(pci_mmcfg_list);
>>
>> +#ifdef CONFIG_GENERIC_PCI_ECAM
>> +static char __iomem *pci_dev_base(unsigned int seg, unsigned int bus,
>> +                                 unsigned int devfn)
>> +{
>> +       struct pci_mmcfg_region *cfg = pci_mmconfig_lookup(seg, bus);
>> +
>> +       if (cfg && cfg->virt)
>> +               return cfg->virt + (PCI_MMCFG_BUS_OFFSET(bus) | (devfn << 12));
>> +       return NULL;
>> +}
>> +
>> +int pci_mmcfg_read(unsigned int seg, unsigned int bus,
>> +                         unsigned int devfn, int reg, int len, u32 *value)
>> +{
>> +       char __iomem *addr;
>> +
>> +       /* Why do we have this when nobody checks it. How about a BUG()!? -AK */
>> +       if (unlikely((bus > 255) || (devfn > 255) || (reg > 4095))) {
>> +err:           *value = -1;
>> +               return -EINVAL;
>> +       }
>> +
>> +       rcu_read_lock();
>
> What is the purpose of the rcu lock other than the old implementation had it?

Read/write calls consist on lookup RCU list (with MMCONFIG regions) and 
then corresponding operation. It is possible to hotplug another pci root 
bridge which leads to RCU list modification.

>
>> +       addr = pci_dev_base(seg, bus, devfn);
>
> The .map_bus op provides the same function if you restructure to use
> the generic accessors.

As you noticed, pci_mmcfg_{read,write} and 
pci_generic_config_{read,write} prototypes are different.

int pci_mmcfg_read(unsigned int seg, unsigned int bus,
                    unsigned int devfn, int reg, int len, u32 *value);
vs
int pci_generic_config_read(struct pci_bus *bus, unsigned int devfn,
                             int where, int size, u32 *val);

This is because pci_mmcfg_{read,write} can be used before pci root 
bridge initialization (while we have no struct pci_bus *bus) inside of 
ACPICA code (osl.c --> acpi_os_read_pci_configuration())

For that reason, I decide to create ECAM related new accessors which do 
not depend on host bridge presence. In other words, 
pci_generic_config_{read,write} can be built on pci_mmcfg_{read,write} 
but not the other way around.

In the light of above, I could not used .map_bus. I might not see a 
nicer way to solve that so any opinion/suggestion very appreciated :)

>
>> +       if (!addr) {
>> +               rcu_read_unlock();
>> +               goto err;
>> +       }
>> +
>> +       *value = pci_mmio_read(len, addr + reg);
>> +       rcu_read_unlock();
>> +
>> +       return 0;
>> +}
>> +
>> +int pci_mmcfg_write(unsigned int seg, unsigned int bus,
>> +                          unsigned int devfn, int reg, int len, u32 value)
>> +{
>> +       char __iomem *addr;
>> +
>> +       /* Why do we have this when nobody checks it. How about a BUG()!? -AK */
>> +       if (unlikely((bus > 255) || (devfn > 255) || (reg > 4095)))
>> +               return -EINVAL;
>> +
>> +       rcu_read_lock();
>> +       addr = pci_dev_base(seg, bus, devfn);
>> +       if (!addr) {
>> +               rcu_read_unlock();
>> +               return -EINVAL;
>> +       }
>> +
>> +       pci_mmio_write(len, addr + reg, value);
>> +       rcu_read_unlock();
>> +
>> +       return 0;
>> +}
>> +
>> +static void __iomem *mcfg_ioremap(struct pci_mmcfg_region *cfg)
>> +{
>> +       void __iomem *addr;
>> +       u64 start, size;
>> +       int num_buses;
>> +
>> +       start = cfg->address + PCI_MMCFG_BUS_OFFSET(cfg->start_bus);
>> +       num_buses = cfg->end_bus - cfg->start_bus + 1;
>> +       size = PCI_MMCFG_BUS_OFFSET(num_buses);
>> +       addr = ioremap_nocache(start, size);
>> +       if (addr)
>> +               addr -= PCI_MMCFG_BUS_OFFSET(cfg->start_bus);
>> +       return addr;
>> +}
>> +
>> +int __init pci_mmcfg_arch_init(void)
>
> Where would this be called for the case of the generic host and using DT?
>
I focused on sharing the code in ACPI context and did not consider DT. I 
think we can improve that code as next steps.

Tomasz

^ permalink raw reply	[flat|nested] 38+ messages in thread

* [PATCH v4 7/9] x86, pci, ecam: mmconfig_64.c becomes default implementation for ECAM driver.
@ 2015-03-12 13:42       ` Tomasz Nowicki
  0 siblings, 0 replies; 38+ messages in thread
From: Tomasz Nowicki @ 2015-03-12 13:42 UTC (permalink / raw)
  To: linux-arm-kernel

On 11.03.2015 16:37, Rob Herring wrote:
> On Wed, Mar 11, 2015 at 9:12 AM, Tomasz Nowicki
> <tomasz.nowicki@linaro.org> wrote:
>> Architectures which want to take advantage of ECAM generic goodness
>
> This is not necessarily an architecture decision. It is likely per host.
Right, good point.

>
>> should select CONFIG_PCI_ECAM_GENERIC. Otherwise, like x86 32bits machines,
>> are obligated to provide own low-level ECAM calls.
>>
>> Signed-off-by: Tomasz Nowicki <tomasz.nowicki@linaro.org>
>> ---
>
> [...]
>
>> diff --git a/drivers/pci/ecam.c b/drivers/pci/ecam.c
>> index c588234..796b6e7 100644
>> --- a/drivers/pci/ecam.c
>> +++ b/drivers/pci/ecam.c
>> @@ -23,6 +23,119 @@ static DEFINE_MUTEX(pci_mmcfg_lock);
>>
>>   LIST_HEAD(pci_mmcfg_list);
>>
>> +#ifdef CONFIG_GENERIC_PCI_ECAM
>> +static char __iomem *pci_dev_base(unsigned int seg, unsigned int bus,
>> +                                 unsigned int devfn)
>> +{
>> +       struct pci_mmcfg_region *cfg = pci_mmconfig_lookup(seg, bus);
>> +
>> +       if (cfg && cfg->virt)
>> +               return cfg->virt + (PCI_MMCFG_BUS_OFFSET(bus) | (devfn << 12));
>> +       return NULL;
>> +}
>> +
>> +int pci_mmcfg_read(unsigned int seg, unsigned int bus,
>> +                         unsigned int devfn, int reg, int len, u32 *value)
>> +{
>> +       char __iomem *addr;
>> +
>> +       /* Why do we have this when nobody checks it. How about a BUG()!? -AK */
>> +       if (unlikely((bus > 255) || (devfn > 255) || (reg > 4095))) {
>> +err:           *value = -1;
>> +               return -EINVAL;
>> +       }
>> +
>> +       rcu_read_lock();
>
> What is the purpose of the rcu lock other than the old implementation had it?

Read/write calls consist on lookup RCU list (with MMCONFIG regions) and 
then corresponding operation. It is possible to hotplug another pci root 
bridge which leads to RCU list modification.

>
>> +       addr = pci_dev_base(seg, bus, devfn);
>
> The .map_bus op provides the same function if you restructure to use
> the generic accessors.

As you noticed, pci_mmcfg_{read,write} and 
pci_generic_config_{read,write} prototypes are different.

int pci_mmcfg_read(unsigned int seg, unsigned int bus,
                    unsigned int devfn, int reg, int len, u32 *value);
vs
int pci_generic_config_read(struct pci_bus *bus, unsigned int devfn,
                             int where, int size, u32 *val);

This is because pci_mmcfg_{read,write} can be used before pci root 
bridge initialization (while we have no struct pci_bus *bus) inside of 
ACPICA code (osl.c --> acpi_os_read_pci_configuration())

For that reason, I decide to create ECAM related new accessors which do 
not depend on host bridge presence. In other words, 
pci_generic_config_{read,write} can be built on pci_mmcfg_{read,write} 
but not the other way around.

In the light of above, I could not used .map_bus. I might not see a 
nicer way to solve that so any opinion/suggestion very appreciated :)

>
>> +       if (!addr) {
>> +               rcu_read_unlock();
>> +               goto err;
>> +       }
>> +
>> +       *value = pci_mmio_read(len, addr + reg);
>> +       rcu_read_unlock();
>> +
>> +       return 0;
>> +}
>> +
>> +int pci_mmcfg_write(unsigned int seg, unsigned int bus,
>> +                          unsigned int devfn, int reg, int len, u32 value)
>> +{
>> +       char __iomem *addr;
>> +
>> +       /* Why do we have this when nobody checks it. How about a BUG()!? -AK */
>> +       if (unlikely((bus > 255) || (devfn > 255) || (reg > 4095)))
>> +               return -EINVAL;
>> +
>> +       rcu_read_lock();
>> +       addr = pci_dev_base(seg, bus, devfn);
>> +       if (!addr) {
>> +               rcu_read_unlock();
>> +               return -EINVAL;
>> +       }
>> +
>> +       pci_mmio_write(len, addr + reg, value);
>> +       rcu_read_unlock();
>> +
>> +       return 0;
>> +}
>> +
>> +static void __iomem *mcfg_ioremap(struct pci_mmcfg_region *cfg)
>> +{
>> +       void __iomem *addr;
>> +       u64 start, size;
>> +       int num_buses;
>> +
>> +       start = cfg->address + PCI_MMCFG_BUS_OFFSET(cfg->start_bus);
>> +       num_buses = cfg->end_bus - cfg->start_bus + 1;
>> +       size = PCI_MMCFG_BUS_OFFSET(num_buses);
>> +       addr = ioremap_nocache(start, size);
>> +       if (addr)
>> +               addr -= PCI_MMCFG_BUS_OFFSET(cfg->start_bus);
>> +       return addr;
>> +}
>> +
>> +int __init pci_mmcfg_arch_init(void)
>
> Where would this be called for the case of the generic host and using DT?
>
I focused on sharing the code in ACPI context and did not consider DT. I 
think we can improve that code as next steps.

Tomasz

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH v4 7/9] x86, pci, ecam: mmconfig_64.c becomes default implementation for ECAM driver.
  2015-03-11 16:30     ` Brian Gerst
@ 2015-03-12 13:42       ` Tomasz Nowicki
  -1 siblings, 0 replies; 38+ messages in thread
From: Tomasz Nowicki @ 2015-03-12 13:42 UTC (permalink / raw)
  To: Brian Gerst
  Cc: bhelgaas, wangyijing, arnd, hanjun.guo, Liviu.Dudau,
	Thomas Gleixner, Ingo Molnar, H. Peter Anvin, rjw, al.stone,
	linux-arm-kernel, Linux Kernel Mailing List,
	the arch/x86 maintainers, linux-pci, linux-acpi, linaro-acpi

On 11.03.2015 17:30, Brian Gerst wrote:
> On Wed, Mar 11, 2015 at 10:12 AM, Tomasz Nowicki
> <tomasz.nowicki@linaro.org> wrote:
>
>> diff --git a/arch/x86/pci/Makefile b/arch/x86/pci/Makefile
>> index 5c6fc35..35c765b 100644
>> --- a/arch/x86/pci/Makefile
>> +++ b/arch/x86/pci/Makefile
>> @@ -1,7 +1,10 @@
>>   obj-y                          := i386.o init.o
>>
>>   obj-$(CONFIG_PCI_BIOS)         += pcbios.o
>> -obj-$(CONFIG_PCI_MMCONFIG)     += mmconfig_$(BITS).o direct.o mmconfig-shared.o
>> +obj-$(CONFIG_PCI_MMCONFIG)     += direct.o mmconfig-shared.o
>> +ifeq ($(BITS),32)
>> +obj-$(CONFIG_PCI_MMCONFIG)     += mmconfig_32.o
>> +endif
>>   obj-$(CONFIG_PCI_DIRECT)       += direct.o
>>   obj-$(CONFIG_PCI_OLPC)         += olpc.o
>>   obj-$(CONFIG_PCI_XEN)          += xen.o
>
> This would be better written as:
>
> mmconfig-y := direct.o mmconfig-shared.o
> mmconfig-$(CONFIG_X86_32) += mmconfig_32.o
> obj-$(CONFIG_PCI_MMCONFIG) += $(mmconfig-y)

Nice! Will update my patch.

Tomasz

^ permalink raw reply	[flat|nested] 38+ messages in thread

* [PATCH v4 7/9] x86, pci, ecam: mmconfig_64.c becomes default implementation for ECAM driver.
@ 2015-03-12 13:42       ` Tomasz Nowicki
  0 siblings, 0 replies; 38+ messages in thread
From: Tomasz Nowicki @ 2015-03-12 13:42 UTC (permalink / raw)
  To: linux-arm-kernel

On 11.03.2015 17:30, Brian Gerst wrote:
> On Wed, Mar 11, 2015 at 10:12 AM, Tomasz Nowicki
> <tomasz.nowicki@linaro.org> wrote:
>
>> diff --git a/arch/x86/pci/Makefile b/arch/x86/pci/Makefile
>> index 5c6fc35..35c765b 100644
>> --- a/arch/x86/pci/Makefile
>> +++ b/arch/x86/pci/Makefile
>> @@ -1,7 +1,10 @@
>>   obj-y                          := i386.o init.o
>>
>>   obj-$(CONFIG_PCI_BIOS)         += pcbios.o
>> -obj-$(CONFIG_PCI_MMCONFIG)     += mmconfig_$(BITS).o direct.o mmconfig-shared.o
>> +obj-$(CONFIG_PCI_MMCONFIG)     += direct.o mmconfig-shared.o
>> +ifeq ($(BITS),32)
>> +obj-$(CONFIG_PCI_MMCONFIG)     += mmconfig_32.o
>> +endif
>>   obj-$(CONFIG_PCI_DIRECT)       += direct.o
>>   obj-$(CONFIG_PCI_OLPC)         += olpc.o
>>   obj-$(CONFIG_PCI_XEN)          += xen.o
>
> This would be better written as:
>
> mmconfig-y := direct.o mmconfig-shared.o
> mmconfig-$(CONFIG_X86_32) += mmconfig_32.o
> obj-$(CONFIG_PCI_MMCONFIG) += $(mmconfig-y)

Nice! Will update my patch.

Tomasz

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH v4 0/9] PCI: MMCONFIG clean up
  2015-03-11 14:12 ` Tomasz Nowicki
@ 2015-04-03 12:06   ` Tomasz Nowicki
  -1 siblings, 0 replies; 38+ messages in thread
From: Tomasz Nowicki @ 2015-04-03 12:06 UTC (permalink / raw)
  To: bhelgaas
  Cc: wangyijing, arnd, hanjun.guo, Liviu.Dudau, tglx, mingo, hpa, rjw,
	al.stone, linux-arm-kernel, linux-kernel, x86, linux-pci,
	linux-acpi, linaro-acpi

Hi Bjorn,

Any comments before I post next version ?

Regards,
Tomasz

On 11.03.2015 15:12, Tomasz Nowicki wrote:
> MCFG ACPI table and PCI ECAM standard have no arch dependencies so it can be
> used across all architectures. Currently MMCONFIG related code resides in
> arch/x86 directories. This patch set is going to isolate non-architecture
> specific code and make it accessible for all architectures.
>
> v3 -> v4 changes:
> - bug fixes after kbuild test robot report
>      - add asm/io.h header for ecam.c
>      - rename mmcfg -> ecam for drivers/xen/pci.c and arch/x86/pci/numachip.c
> - rework Kconfig logic
>
> v2 -> v3 changes:
> - rebase patch set v2 to v4.0-rc1
>
> v1 -> v2 changes:
> - use generic readb/readw etc. accessors instead of AMD Fam10h workaround
> - separate ACPI and ECAM code
> - improve ECAM code naming
>
> Tomasz Nowicki (9):
>    x86, pci: Clean up comment about buggy MMIO config space access for
>      AMD Fam10h CPUs.
>    x86, pci: Abstract PCI config accessors and use AMD Fam10h workaround
>      exclusively.
>    x86, pci: Reorder logic of pci_mmconfig_insert() function
>    x86, pci, acpi: Move arch-agnostic MMCONFIG (aka ECAM) and ACPI code
>      out of arch/x86/ directory
>    pci, acpi, mcfg: Provide generic implementation of MCFG code
>      initialization.
>    x86, pci: mmconfig_{32,64}.c code refactoring - remove code
>      duplication.
>    x86, pci, ecam: mmconfig_64.c becomes default implementation for ECAM
>      driver.
>    pci, acpi, mcfg: Share ACPI PCI config space accessors.
>    pci, ecam: Improve naming for ecam.c content and areas where it is
>      used.
>
>   arch/x86/Kconfig               |   4 +
>   arch/x86/include/asm/pci_x86.h |  34 +---
>   arch/x86/pci/Makefile          |   5 +-
>   arch/x86/pci/acpi.c            |   3 +-
>   arch/x86/pci/mmconfig-shared.c | 346 +++++++++++----------------------------
>   arch/x86/pci/mmconfig_32.c     |  47 ++----
>   arch/x86/pci/mmconfig_64.c     | 153 ------------------
>   arch/x86/pci/numachip.c        |  29 +---
>   drivers/acpi/Makefile          |   1 +
>   drivers/acpi/mcfg.c            | 121 ++++++++++++++
>   drivers/pci/Kconfig            |  10 ++
>   drivers/pci/Makefile           |   5 +
>   drivers/pci/ecam.c             | 358 +++++++++++++++++++++++++++++++++++++++++
>   drivers/xen/pci.c              |   7 +-
>   include/linux/ecam.h           |  56 +++++++
>   15 files changed, 679 insertions(+), 500 deletions(-)
>   delete mode 100644 arch/x86/pci/mmconfig_64.c
>   create mode 100644 drivers/acpi/mcfg.c
>   create mode 100644 drivers/pci/ecam.c
>   create mode 100644 include/linux/ecam.h
>

^ permalink raw reply	[flat|nested] 38+ messages in thread

* [PATCH v4 0/9] PCI: MMCONFIG clean up
@ 2015-04-03 12:06   ` Tomasz Nowicki
  0 siblings, 0 replies; 38+ messages in thread
From: Tomasz Nowicki @ 2015-04-03 12:06 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Bjorn,

Any comments before I post next version ?

Regards,
Tomasz

On 11.03.2015 15:12, Tomasz Nowicki wrote:
> MCFG ACPI table and PCI ECAM standard have no arch dependencies so it can be
> used across all architectures. Currently MMCONFIG related code resides in
> arch/x86 directories. This patch set is going to isolate non-architecture
> specific code and make it accessible for all architectures.
>
> v3 -> v4 changes:
> - bug fixes after kbuild test robot report
>      - add asm/io.h header for ecam.c
>      - rename mmcfg -> ecam for drivers/xen/pci.c and arch/x86/pci/numachip.c
> - rework Kconfig logic
>
> v2 -> v3 changes:
> - rebase patch set v2 to v4.0-rc1
>
> v1 -> v2 changes:
> - use generic readb/readw etc. accessors instead of AMD Fam10h workaround
> - separate ACPI and ECAM code
> - improve ECAM code naming
>
> Tomasz Nowicki (9):
>    x86, pci: Clean up comment about buggy MMIO config space access for
>      AMD Fam10h CPUs.
>    x86, pci: Abstract PCI config accessors and use AMD Fam10h workaround
>      exclusively.
>    x86, pci: Reorder logic of pci_mmconfig_insert() function
>    x86, pci, acpi: Move arch-agnostic MMCONFIG (aka ECAM) and ACPI code
>      out of arch/x86/ directory
>    pci, acpi, mcfg: Provide generic implementation of MCFG code
>      initialization.
>    x86, pci: mmconfig_{32,64}.c code refactoring - remove code
>      duplication.
>    x86, pci, ecam: mmconfig_64.c becomes default implementation for ECAM
>      driver.
>    pci, acpi, mcfg: Share ACPI PCI config space accessors.
>    pci, ecam: Improve naming for ecam.c content and areas where it is
>      used.
>
>   arch/x86/Kconfig               |   4 +
>   arch/x86/include/asm/pci_x86.h |  34 +---
>   arch/x86/pci/Makefile          |   5 +-
>   arch/x86/pci/acpi.c            |   3 +-
>   arch/x86/pci/mmconfig-shared.c | 346 +++++++++++----------------------------
>   arch/x86/pci/mmconfig_32.c     |  47 ++----
>   arch/x86/pci/mmconfig_64.c     | 153 ------------------
>   arch/x86/pci/numachip.c        |  29 +---
>   drivers/acpi/Makefile          |   1 +
>   drivers/acpi/mcfg.c            | 121 ++++++++++++++
>   drivers/pci/Kconfig            |  10 ++
>   drivers/pci/Makefile           |   5 +
>   drivers/pci/ecam.c             | 358 +++++++++++++++++++++++++++++++++++++++++
>   drivers/xen/pci.c              |   7 +-
>   include/linux/ecam.h           |  56 +++++++
>   15 files changed, 679 insertions(+), 500 deletions(-)
>   delete mode 100644 arch/x86/pci/mmconfig_64.c
>   create mode 100644 drivers/acpi/mcfg.c
>   create mode 100644 drivers/pci/ecam.c
>   create mode 100644 include/linux/ecam.h
>

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH v4 0/9] PCI: MMCONFIG clean up
  2015-04-03 12:06   ` Tomasz Nowicki
@ 2015-04-03 15:20     ` Bjorn Helgaas
  -1 siblings, 0 replies; 38+ messages in thread
From: Bjorn Helgaas @ 2015-04-03 15:20 UTC (permalink / raw)
  To: Tomasz Nowicki
  Cc: Yijing Wang, Arnd Bergmann, Hanjun Guo, Liviu Dudau,
	Thomas Gleixner, Ingo Molnar, H. Peter Anvin, Rafael Wysocki,
	Al Stone, linux-arm, linux-kernel, x86, linux-pci, linux-acpi,
	linaro-acpi

On Fri, Apr 3, 2015 at 7:06 AM, Tomasz Nowicki
<tomasz.nowicki@linaro.org> wrote:
> Hi Bjorn,
>
> Any comments before I post next version ?

Nope.  I've been on vacation for a week and am just trying to catch
up.  Haven't had time to do any more than build-test your v4 series.

Bjorn

> On 11.03.2015 15:12, Tomasz Nowicki wrote:
>>
>> MCFG ACPI table and PCI ECAM standard have no arch dependencies so it can
>> be
>> used across all architectures. Currently MMCONFIG related code resides in
>> arch/x86 directories. This patch set is going to isolate non-architecture
>> specific code and make it accessible for all architectures.
>>
>> v3 -> v4 changes:
>> - bug fixes after kbuild test robot report
>>      - add asm/io.h header for ecam.c
>>      - rename mmcfg -> ecam for drivers/xen/pci.c and
>> arch/x86/pci/numachip.c
>> - rework Kconfig logic
>>
>> v2 -> v3 changes:
>> - rebase patch set v2 to v4.0-rc1
>>
>> v1 -> v2 changes:
>> - use generic readb/readw etc. accessors instead of AMD Fam10h workaround
>> - separate ACPI and ECAM code
>> - improve ECAM code naming
>>
>> Tomasz Nowicki (9):
>>    x86, pci: Clean up comment about buggy MMIO config space access for
>>      AMD Fam10h CPUs.
>>    x86, pci: Abstract PCI config accessors and use AMD Fam10h workaround
>>      exclusively.
>>    x86, pci: Reorder logic of pci_mmconfig_insert() function
>>    x86, pci, acpi: Move arch-agnostic MMCONFIG (aka ECAM) and ACPI code
>>      out of arch/x86/ directory
>>    pci, acpi, mcfg: Provide generic implementation of MCFG code
>>      initialization.
>>    x86, pci: mmconfig_{32,64}.c code refactoring - remove code
>>      duplication.
>>    x86, pci, ecam: mmconfig_64.c becomes default implementation for ECAM
>>      driver.
>>    pci, acpi, mcfg: Share ACPI PCI config space accessors.
>>    pci, ecam: Improve naming for ecam.c content and areas where it is
>>      used.
>>
>>   arch/x86/Kconfig               |   4 +
>>   arch/x86/include/asm/pci_x86.h |  34 +---
>>   arch/x86/pci/Makefile          |   5 +-
>>   arch/x86/pci/acpi.c            |   3 +-
>>   arch/x86/pci/mmconfig-shared.c | 346
>> +++++++++++----------------------------
>>   arch/x86/pci/mmconfig_32.c     |  47 ++----
>>   arch/x86/pci/mmconfig_64.c     | 153 ------------------
>>   arch/x86/pci/numachip.c        |  29 +---
>>   drivers/acpi/Makefile          |   1 +
>>   drivers/acpi/mcfg.c            | 121 ++++++++++++++
>>   drivers/pci/Kconfig            |  10 ++
>>   drivers/pci/Makefile           |   5 +
>>   drivers/pci/ecam.c             | 358
>> +++++++++++++++++++++++++++++++++++++++++
>>   drivers/xen/pci.c              |   7 +-
>>   include/linux/ecam.h           |  56 +++++++
>>   15 files changed, 679 insertions(+), 500 deletions(-)
>>   delete mode 100644 arch/x86/pci/mmconfig_64.c
>>   create mode 100644 drivers/acpi/mcfg.c
>>   create mode 100644 drivers/pci/ecam.c
>>   create mode 100644 include/linux/ecam.h
>>
>

^ permalink raw reply	[flat|nested] 38+ messages in thread

* [PATCH v4 0/9] PCI: MMCONFIG clean up
@ 2015-04-03 15:20     ` Bjorn Helgaas
  0 siblings, 0 replies; 38+ messages in thread
From: Bjorn Helgaas @ 2015-04-03 15:20 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Apr 3, 2015 at 7:06 AM, Tomasz Nowicki
<tomasz.nowicki@linaro.org> wrote:
> Hi Bjorn,
>
> Any comments before I post next version ?

Nope.  I've been on vacation for a week and am just trying to catch
up.  Haven't had time to do any more than build-test your v4 series.

Bjorn

> On 11.03.2015 15:12, Tomasz Nowicki wrote:
>>
>> MCFG ACPI table and PCI ECAM standard have no arch dependencies so it can
>> be
>> used across all architectures. Currently MMCONFIG related code resides in
>> arch/x86 directories. This patch set is going to isolate non-architecture
>> specific code and make it accessible for all architectures.
>>
>> v3 -> v4 changes:
>> - bug fixes after kbuild test robot report
>>      - add asm/io.h header for ecam.c
>>      - rename mmcfg -> ecam for drivers/xen/pci.c and
>> arch/x86/pci/numachip.c
>> - rework Kconfig logic
>>
>> v2 -> v3 changes:
>> - rebase patch set v2 to v4.0-rc1
>>
>> v1 -> v2 changes:
>> - use generic readb/readw etc. accessors instead of AMD Fam10h workaround
>> - separate ACPI and ECAM code
>> - improve ECAM code naming
>>
>> Tomasz Nowicki (9):
>>    x86, pci: Clean up comment about buggy MMIO config space access for
>>      AMD Fam10h CPUs.
>>    x86, pci: Abstract PCI config accessors and use AMD Fam10h workaround
>>      exclusively.
>>    x86, pci: Reorder logic of pci_mmconfig_insert() function
>>    x86, pci, acpi: Move arch-agnostic MMCONFIG (aka ECAM) and ACPI code
>>      out of arch/x86/ directory
>>    pci, acpi, mcfg: Provide generic implementation of MCFG code
>>      initialization.
>>    x86, pci: mmconfig_{32,64}.c code refactoring - remove code
>>      duplication.
>>    x86, pci, ecam: mmconfig_64.c becomes default implementation for ECAM
>>      driver.
>>    pci, acpi, mcfg: Share ACPI PCI config space accessors.
>>    pci, ecam: Improve naming for ecam.c content and areas where it is
>>      used.
>>
>>   arch/x86/Kconfig               |   4 +
>>   arch/x86/include/asm/pci_x86.h |  34 +---
>>   arch/x86/pci/Makefile          |   5 +-
>>   arch/x86/pci/acpi.c            |   3 +-
>>   arch/x86/pci/mmconfig-shared.c | 346
>> +++++++++++----------------------------
>>   arch/x86/pci/mmconfig_32.c     |  47 ++----
>>   arch/x86/pci/mmconfig_64.c     | 153 ------------------
>>   arch/x86/pci/numachip.c        |  29 +---
>>   drivers/acpi/Makefile          |   1 +
>>   drivers/acpi/mcfg.c            | 121 ++++++++++++++
>>   drivers/pci/Kconfig            |  10 ++
>>   drivers/pci/Makefile           |   5 +
>>   drivers/pci/ecam.c             | 358
>> +++++++++++++++++++++++++++++++++++++++++
>>   drivers/xen/pci.c              |   7 +-
>>   include/linux/ecam.h           |  56 +++++++
>>   15 files changed, 679 insertions(+), 500 deletions(-)
>>   delete mode 100644 arch/x86/pci/mmconfig_64.c
>>   create mode 100644 drivers/acpi/mcfg.c
>>   create mode 100644 drivers/pci/ecam.c
>>   create mode 100644 include/linux/ecam.h
>>
>

^ permalink raw reply	[flat|nested] 38+ messages in thread

end of thread, other threads:[~2015-04-03 15:21 UTC | newest]

Thread overview: 38+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-03-11 14:12 [PATCH v4 0/9] PCI: MMCONFIG clean up Tomasz Nowicki
2015-03-11 14:12 ` Tomasz Nowicki
2015-03-11 14:12 ` [PATCH v4 1/9] x86, pci: Clean up comment about buggy MMIO config space access for AMD Fam10h CPUs Tomasz Nowicki
2015-03-11 14:12   ` Tomasz Nowicki
2015-03-11 14:12 ` [PATCH v4 2/9] x86, pci: Abstract PCI config accessors and use AMD Fam10h workaround exclusively Tomasz Nowicki
2015-03-11 14:12   ` Tomasz Nowicki
2015-03-11 15:19   ` Rob Herring
2015-03-11 15:19     ` Rob Herring
2015-03-11 15:19     ` Rob Herring
2015-03-11 14:12 ` [PATCH v4 3/9] x86, pci: Reorder logic of pci_mmconfig_insert() function Tomasz Nowicki
2015-03-11 14:12   ` Tomasz Nowicki
2015-03-11 14:12   ` Tomasz Nowicki
2015-03-11 14:12 ` [PATCH v4 4/9] x86, pci, acpi: Move arch-agnostic MMCONFIG (aka ECAM) and ACPI code out of arch/x86/ directory Tomasz Nowicki
2015-03-11 14:12   ` Tomasz Nowicki
2015-03-11 14:12 ` [PATCH v4 5/9] pci, acpi, mcfg: Provide generic implementation of MCFG code initialization Tomasz Nowicki
2015-03-11 14:12   ` Tomasz Nowicki
2015-03-11 14:12 ` [PATCH v4 6/9] x86, pci: mmconfig_{32,64}.c code refactoring - remove code duplication Tomasz Nowicki
2015-03-11 14:12   ` [PATCH v4 6/9] x86, pci: mmconfig_{32, 64}.c " Tomasz Nowicki
2015-03-11 14:12 ` [PATCH v4 7/9] x86, pci, ecam: mmconfig_64.c becomes default implementation for ECAM driver Tomasz Nowicki
2015-03-11 14:12   ` Tomasz Nowicki
2015-03-11 15:37   ` Rob Herring
2015-03-11 15:37     ` Rob Herring
2015-03-11 15:37     ` Rob Herring
2015-03-12 13:42     ` Tomasz Nowicki
2015-03-12 13:42       ` Tomasz Nowicki
2015-03-12 13:42       ` Tomasz Nowicki
2015-03-11 16:30   ` Brian Gerst
2015-03-11 16:30     ` Brian Gerst
2015-03-12 13:42     ` Tomasz Nowicki
2015-03-12 13:42       ` Tomasz Nowicki
2015-03-11 14:12 ` [PATCH v4 8/9] pci, acpi, mcfg: Share ACPI PCI config space accessors Tomasz Nowicki
2015-03-11 14:12   ` Tomasz Nowicki
2015-03-11 14:12 ` [PATCH v4 9/9] pci, ecam: Improve naming for ecam.c content and areas where it is used Tomasz Nowicki
2015-03-11 14:12   ` Tomasz Nowicki
2015-04-03 12:06 ` [PATCH v4 0/9] PCI: MMCONFIG clean up Tomasz Nowicki
2015-04-03 12:06   ` Tomasz Nowicki
2015-04-03 15:20   ` Bjorn Helgaas
2015-04-03 15:20     ` Bjorn Helgaas

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.