From: Tomasz Nowicki <tomasz.nowicki@linaro.org>
To: bhelgaas@google.com, wangyijing@huawei.com, arnd@arndb.de,
hanjun.guo@linaro.org, Liviu.Dudau@arm.com, tglx@linutronix.de,
mingo@redhat.com, hpa@zytor.com, rjw@rjwysocki.net,
al.stone@linaro.org
Cc: linux-arm-kernel@lists.infradead.org,
linux-kernel@vger.kernel.org, x86@kernel.org,
linux-pci@vger.kernel.org, linux-acpi@vger.kernel.org,
linaro-acpi@lists.linaro.org,
Tomasz Nowicki <tomasz.nowicki@linaro.org>
Subject: [PATCH v3 7/9] x86, pci, ecam: mmconfig_64.c becomes default implementation for ECAM driver.
Date: Tue, 10 Mar 2015 12:35:18 +0100 [thread overview]
Message-ID: <1425987320-15020-8-git-send-email-tomasz.nowicki@linaro.org> (raw)
In-Reply-To: <1425987320-15020-1-git-send-email-tomasz.nowicki@linaro.org>
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 dd926f4..9f30dab 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 PCI_ECAM_GENERIC 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 e2eb982..32e0a73 100644
--- a/drivers/pci/Kconfig
+++ b/drivers/pci/Kconfig
@@ -26,6 +26,9 @@ config PCI_ECAM
bool "Enhanced Configuration Access Mechanism (ECAM)"
depends on PCI
+config PCI_ECAM_GENERIC
+ 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 f540184..f886796 100644
--- a/drivers/pci/ecam.c
+++ b/drivers/pci/ecam.c
@@ -21,6 +21,119 @@ static DEFINE_MUTEX(pci_mmcfg_lock);
LIST_HEAD(pci_mmcfg_list);
+#ifdef CONFIG_PCI_ECAM_GENERIC
+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
next prev parent reply other threads:[~2015-03-10 11:34 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-03-10 11:35 [PATCH v3 0/9] PCI: MMCONFIG clean up Tomasz Nowicki
2015-03-10 11:35 ` [PATCH v3 1/9] x86, pci: Clean up comment about buggy MMIO config space access for AMD Fam10h CPUs Tomasz Nowicki
2015-03-10 11:35 ` [PATCH v3 2/9] x86, pci: Abstract PCI config accessors and use AMD Fam10h workaround exclusively Tomasz Nowicki
2015-03-10 11:35 ` [PATCH v3 3/9] x86, pci: Reorder logic of pci_mmconfig_insert() function Tomasz Nowicki
2015-03-10 11:35 ` [PATCH v3 4/9] x86, pci, acpi: Move arch-agnostic MMCONFIG (aka ECAM) and ACPI code out of arch/x86/ directory Tomasz Nowicki
2015-03-13 16:35 ` Mark Salter
2015-03-16 14:38 ` Tomasz Nowicki
2015-03-10 11:35 ` [PATCH v3 5/9] pci, acpi, mcfg: Provide generic implementation of MCFG code initialization Tomasz Nowicki
2015-03-10 11:35 ` [PATCH v3 6/9] x86, pci: mmconfig_{32,64}.c code refactoring - remove code duplication Tomasz Nowicki
2015-03-10 11:35 ` Tomasz Nowicki [this message]
2015-03-10 11:35 ` [PATCH v3 8/9] pci, acpi, mcfg: Share ACPI PCI config space accessors Tomasz Nowicki
2015-03-10 11:35 ` [PATCH v3 9/9] pci, ecam: Improve naming for ecam.c content and areas where it is used Tomasz Nowicki
2015-03-10 12:22 ` Tomasz Nowicki
2015-03-10 12:25 ` Tomasz Nowicki
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1425987320-15020-8-git-send-email-tomasz.nowicki@linaro.org \
--to=tomasz.nowicki@linaro.org \
--cc=Liviu.Dudau@arm.com \
--cc=al.stone@linaro.org \
--cc=arnd@arndb.de \
--cc=bhelgaas@google.com \
--cc=hanjun.guo@linaro.org \
--cc=hpa@zytor.com \
--cc=linaro-acpi@lists.linaro.org \
--cc=linux-acpi@vger.kernel.org \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-pci@vger.kernel.org \
--cc=mingo@redhat.com \
--cc=rjw@rjwysocki.net \
--cc=tglx@linutronix.de \
--cc=wangyijing@huawei.com \
--cc=x86@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).