Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1380019 > unrolled thread
| Started by | Tomasz Nowicki <tn@semihalf.com> |
|---|---|
| First post | 2016-04-15 19:10 +0200 |
| Last post | 2016-04-25 19:30 +0200 |
| Articles | 20 on this page of 69 — 15 participants |
Back to article view | Back to linux.kernel
[PATCH V6 00/13] Support for generic ACPI based PCI host controller Tomasz Nowicki <tn@semihalf.com> - 2016-04-15 19:10 +0200
[PATCH V6 11/13] pci, acpi: Match PCI config space accessors against platfrom specific quirks. Tomasz Nowicki <tn@semihalf.com> - 2016-04-15 19:10 +0200
Re: [PATCH V6 11/13] pci, acpi: Match PCI config space accessors against platfrom specific quirks. "liudongdong (C)" <liudongdong3@huawei.com> - 2016-04-18 14:00 +0200
Re: [PATCH V6 11/13] pci, acpi: Match PCI config space accessors against platfrom specific quirks. Tomasz Nowicki <tn@semihalf.com> - 2016-04-18 14:30 +0200
[PATCH V6 13/13] pci, pci-thunder-pem: Add ACPI support for ThunderX PEM. Tomasz Nowicki <tn@semihalf.com> - 2016-04-15 19:10 +0200
[PATCH V6 02/13] pci, acpi: Provide generic way to assign bus domain number. Tomasz Nowicki <tn@semihalf.com> - 2016-04-15 19:10 +0200
Re: [PATCH V6 02/13] pci, acpi: Provide generic way to assign bus domain number. Bjorn Helgaas <helgaas@kernel.org> - 2016-04-27 04:30 +0200
Re: [PATCH V6 02/13] pci, acpi: Provide generic way to assign bus domain number. Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> - 2016-04-27 13:20 +0200
Re: [PATCH V6 02/13] pci, acpi: Provide generic way to assign bus domain number. Bjorn Helgaas <helgaas@kernel.org> - 2016-04-27 18:50 +0200
Re: [PATCH V6 02/13] pci, acpi: Provide generic way to assign bus domain number. Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> - 2016-04-27 19:40 +0200
Re: [PATCH V6 02/13] pci, acpi: Provide generic way to assign bus domain number. Liviu.Dudau@arm.com - 2016-04-28 10:20 +0200
Re: [PATCH V6 02/13] pci, acpi: Provide generic way to assign bus domain number. Tomasz Nowicki <tn@semihalf.com> - 2016-04-27 14:10 +0200
[PATCH V6 12/13] pci, pci-thunder-ecam: Add ACPI support for ThunderX ECAM. Tomasz Nowicki <tn@semihalf.com> - 2016-04-15 19:10 +0200
Re: [PATCH V6 12/13] pci, pci-thunder-ecam: Add ACPI support for ThunderX ECAM. Tomasz Nowicki <tn@semihalf.com> - 2016-04-19 12:30 +0200
Re: [Linaro-acpi] [PATCH V6 12/13] pci, pci-thunder-ecam: Add ACPI support for ThunderX ECAM. G Gregory <graeme.gregory@linaro.org> - 2016-04-19 12:50 +0200
Re: [Linaro-acpi] [PATCH V6 12/13] pci, pci-thunder-ecam: Add ACPI support for ThunderX ECAM. Graeme Gregory <gg@slimlogic.co.uk> - 2016-04-19 13:20 +0200
Re: [Linaro-acpi] [PATCH V6 12/13] pci, pci-thunder-ecam: Add ACPI support for ThunderX ECAM. Tomasz Nowicki <tn@semihalf.com> - 2016-04-19 13:30 +0200
Re: [Linaro-acpi] [PATCH V6 12/13] pci, pci-thunder-ecam: Add ACPI support for ThunderX ECAM. G Gregory <graeme.gregory@linaro.org> - 2016-04-19 14:30 +0200
[PATCH V6 08/13] PCI: generic, thunder: update to use generic ECAM API Tomasz Nowicki <tn@semihalf.com> - 2016-04-15 19:10 +0200
Re: [PATCH V6 08/13] PCI: generic, thunder: update to use generic ECAM API Arnd Bergmann <arnd@arndb.de> - 2016-04-15 20:50 +0200
Re: [PATCH V6 08/13] PCI: generic, thunder: update to use generic ECAM API Jayachandran C <jchandra@broadcom.com> - 2016-04-16 09:30 +0200
Re: [PATCH V6 08/13] PCI: generic, thunder: update to use generic ECAM API Arnd Bergmann <arnd@arndb.de> - 2016-04-16 09:40 +0200
Re: [PATCH V6 08/13] PCI: generic, thunder: update to use generic ECAM API Jayachandran C <jchandra@broadcom.com> - 2016-04-16 16:40 +0200
Re: [PATCH V6 08/13] PCI: generic, thunder: update to use generic ECAM API Tomasz Nowicki <tn@semihalf.com> - 2016-04-18 15:10 +0200
Re: [PATCH V6 08/13] PCI: generic, thunder: update to use generic ECAM API Arnd Bergmann <arnd@arndb.de> - 2016-04-18 16:50 +0200
Re: [PATCH V6 08/13] PCI: generic, thunder: update to use generic ECAM API Tomasz Nowicki <tn@semihalf.com> - 2016-04-18 21:40 +0200
Re: [PATCH V6 08/13] PCI: generic, thunder: update to use generic ECAM API Arnd Bergmann <arnd@arndb.de> - 2016-04-19 15:10 +0200
Re: [PATCH V6 08/13] PCI: generic, thunder: update to use generic ECAM API Tomasz Nowicki <tn@semihalf.com> - 2016-04-21 11:30 +0200
Re: [PATCH V6 08/13] PCI: generic, thunder: update to use generic ECAM API Arnd Bergmann <arnd@arndb.de> - 2016-04-21 11:40 +0200
Re: [PATCH V6 08/13] PCI: generic, thunder: update to use generic ECAM API Tomasz Nowicki <tn@semihalf.com> - 2016-04-21 12:10 +0200
Re: [PATCH V6 08/13] PCI: generic, thunder: update to use generic ECAM API Jon Masters <jcm@redhat.com> - 2016-04-22 16:40 +0200
Re: [PATCH V6 08/13] PCI: generic, thunder: update to use generic ECAM API David Daney <ddaney.cavm@gmail.com> - 2016-04-22 18:10 +0200
Re: [PATCH V6 08/13] PCI: generic, thunder: update to use generic ECAM API Arnd Bergmann <arnd@arndb.de> - 2016-04-19 23:50 +0200
Re: [PATCH V6 08/13] PCI: generic, thunder: update to use generic ECAM API Jayachandran C <jchandra@broadcom.com> - 2016-04-20 02:30 +0200
[PATCH V6 04/13] pci, of: Move the PCI I/O space management to PCI core code. Tomasz Nowicki <tn@semihalf.com> - 2016-04-15 19:10 +0200
[PATCH V6 09/13] pci, acpi: Support for ACPI based generic PCI host controller Tomasz Nowicki <tn@semihalf.com> - 2016-04-15 19:10 +0200
Re: [PATCH V6 09/13] pci, acpi: Support for ACPI based generic PCI host controller Jayachandran C <jchandra@broadcom.com> - 2016-04-20 21:20 +0200
Re: [PATCH V6 09/13] pci, acpi: Support for ACPI based generic PCI host controller Tomasz Nowicki <tn@semihalf.com> - 2016-04-21 11:10 +0200
Re: [PATCH V6 09/13] pci, acpi: Support for ACPI based generic PCI host controller Jayachandran C <jchandra@broadcom.com> - 2016-04-22 15:00 +0200
Re: [PATCH V6 09/13] pci, acpi: Support for ACPI based generic PCI host controller Jon Masters <jcm@redhat.com> - 2016-04-22 16:50 +0200
Re: [PATCH V6 09/13] pci, acpi: Support for ACPI based generic PCI host controller Jon Masters <jcm@redhat.com> - 2016-04-23 17:30 +0200
[PATCH V6 10/13] arm64, pci, acpi: Start using ACPI based PCI host controller driver for ARM64. Tomasz Nowicki <tn@semihalf.com> - 2016-04-15 19:10 +0200
[PATCH V6 06/13] arm64, pci, acpi: ACPI support for legacy IRQs parsing and consolidation with DT code. Tomasz Nowicki <tn@semihalf.com> - 2016-04-15 19:20 +0200
Re: [PATCH V6 06/13] arm64, pci, acpi: ACPI support for legacy IRQs parsing and consolidation with DT code. Bjorn Helgaas <helgaas@kernel.org> - 2016-04-27 04:50 +0200
Re: [PATCH V6 06/13] arm64, pci, acpi: ACPI support for legacy IRQs parsing and consolidation with DT code. Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> - 2016-04-27 13:50 +0200
[PATCH V6 07/13] PCI: Provide common functions for ECAM mapping Tomasz Nowicki <tn@semihalf.com> - 2016-04-15 19:20 +0200
Re: [PATCH V6 07/13] PCI: Provide common functions for ECAM mapping Arnd Bergmann <arnd@arndb.de> - 2016-04-15 20:50 +0200
[PATCH V6 01/13] pci, acpi, x86, ia64: Move ACPI host bridge device companion assignment to core code. Tomasz Nowicki <tn@semihalf.com> - 2016-04-15 19:20 +0200
Re: [PATCH V6 01/13] pci, acpi, x86, ia64: Move ACPI host bridge device companion assignment to core code. Bjorn Helgaas <helgaas@kernel.org> - 2016-04-27 00:40 +0200
Re: [PATCH V6 01/13] pci, acpi, x86, ia64: Move ACPI host bridge device companion assignment to core code. Tomasz Nowicki <tn@semihalf.com> - 2016-04-27 12:20 +0200
Re: [PATCH V6 01/13] pci, acpi, x86, ia64: Move ACPI host bridge device companion assignment to core code. Bjorn Helgaas <helgaas@kernel.org> - 2016-04-27 04:50 +0200
[PATCH V6 03/13] x86, ia64: Include acpi_pci_{add|remove}_bus to the default pcibios_{add|remove}_bus implementation. Tomasz Nowicki <tn@semihalf.com> - 2016-04-15 19:20 +0200
Re: [PATCH V6 03/13] x86, ia64: Include acpi_pci_{add|remove}_bus to the default pcibios_{add|remove}_bus implementation. Bjorn Helgaas <helgaas@kernel.org> - 2016-04-27 04:40 +0200
Re: [PATCH V6 03/13] x86, ia64: Include acpi_pci_{add|remove}_bus to the default pcibios_{add|remove}_bus implementation. Tomasz Nowicki <tn@semihalf.com> - 2016-04-27 15:30 +0200
[PATCH V6 05/13] acpi, pci: Support IO resources when parsing PCI host bridge resources. Tomasz Nowicki <tn@semihalf.com> - 2016-04-15 19:20 +0200
Re: [PATCH V6 05/13] acpi, pci: Support IO resources when parsing PCI host bridge resources. Bjorn Helgaas <helgaas@kernel.org> - 2016-04-27 04:40 +0200
Re: [PATCH V6 05/13] acpi, pci: Support IO resources when parsing PCI host bridge resources. Jon Masters <jcm@redhat.com> - 2016-04-27 07:40 +0200
Re: [PATCH V6 05/13] acpi, pci: Support IO resources when parsing PCI host bridge resources. Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> - 2016-04-27 16:30 +0200
Re: [PATCH V6 05/13] acpi, pci: Support IO resources when parsing PCI host bridge resources. Liviu.Dudau@arm.com - 2016-04-27 17:20 +0200
Re: [PATCH V6 05/13] acpi, pci: Support IO resources when parsing PCI host bridge resources. Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> - 2016-04-27 18:10 +0200
Re: [PATCH V6 00/13] Support for generic ACPI based PCI host controller Jon Masters <jcm@redhat.com> - 2016-04-15 20:20 +0200
Re: [PATCH V6 00/13] Support for generic ACPI based PCI host controller Jayachandran C <jchandra@broadcom.com> - 2016-04-16 17:40 +0200
Re: [PATCH V6 00/13] Support for generic ACPI based PCI host controller Tomasz Nowicki <tn@semihalf.com> - 2016-04-18 15:40 +0200
Re: [PATCH V6 00/13] Support for generic ACPI based PCI host controller Arnd Bergmann <arnd@arndb.de> - 2016-04-18 16:40 +0200
Re: [PATCH V6 00/13] Support for generic ACPI based PCI host controller Tomasz Nowicki <tn@semihalf.com> - 2016-04-18 17:30 +0200
Re: [PATCH V6 00/13] Support for generic ACPI based PCI host controller Martinez Kristofer <kristofer.s.martinez@gmail.com> - 2016-04-17 11:30 +0200
Re: [PATCH V6 00/13] Support for generic ACPI based PCI host controller Duc Dang <dhdang@apm.com> - 2016-04-16 20:40 +0200
Re: [PATCH V6 00/13] Support for generic ACPI based PCI host controller Sinan Kaya <okaya@codeaurora.org> - 2016-04-17 06:20 +0200
Re: [PATCH V6 00/13] Support for generic ACPI based PCI host controller Jeremy Linton <jeremy.linton@arm.com> - 2016-04-25 19:30 +0200
Page 1 of 4 [1] 2 3 4 Next page →
| From | Tomasz Nowicki <tn@semihalf.com> |
|---|---|
| Date | 2016-04-15 19:10 +0200 |
| Subject | [PATCH V6 00/13] Support for generic ACPI based PCI host controller |
| Message-ID | <rofpL-6tr-1@gated-at.bofh.it> |
From the functionality point of view this series might be split into the
following logic parts:
1. Necessary fixes as the preparation for using driver on ARM64.
2. New ECAM API and update for users of the pci-host-common API
3. Use new MCFG interface and implement generic ACPI based PCI host controller driver.
4. Enable above driver on ARM64
Patches has been built on top of 4.6-rc2 and can be found here:
git@github.com:semihalf-nowicki-tomasz/linux.git (pci-acpi-v6)
This has been tested on Cavium ThunderX server. Any help in reviewing and
testing is very appreciated.
v5 -> v6
- dropped idea of x86 MMCONFIG code refactoring
- integrated JC's patches which introduce new ECAM API:
https://lkml.org/lkml/2016/4/11/907
git: https://github.com/jchandra-brcm/linux/ (arm64-acpi-pci-v3)
- integrated Sinan's fix for releasing IO resources, see patch [06/13]
- added ACPI support for ThunderX ECAM and PEM drivers
- rebased to 4.6-rc2
v4 -> v5
- dropped MCFG refactoring group patches 1-6 from series v4 and integrated Jayachandran's patch
https://patchwork.ozlabs.org/patch/575525/
- rewrite PCI legacy IRQs allocation
- squashed two patches 11 and 12 from series v4, fixed bisection issue
- changelog improvements
- rebased to 4.5-rc3
v3 -> v4
- dropped Jiang's fix http://lkml.iu.edu/hypermail/linux/kernel/1601.1/04318.html
- added Lorenzo's fix patch 19/24
- ACPI PCI bus domain number assigning cleanup
- changed resource management, we now claim and reassign resources
- improvements for applying quirks
- dropped Matthew's http://www.spinics.net/lists/linux-pci/msg45950.html dependency
- rebased to 4.5-rc1
v2 -> v3
- fix legacy IRQ assigning and IO ports registration
- remove reference to arch specific companion device for ia64
- move ACPI PCI host controller driver to pci_root.c
- drop generic domain assignment for x86 and ia64 as I am not
able to run all necessary test variants
- drop patch which cleaned legacy IRQ assignment since it belongs to
Mathew's series:
https://patchwork.ozlabs.org/patch/557504/
- extend MCFG quirk code
- rebased to 4.4
v1 -> v2
- moved non-arch specific piece of code to dirver/acpi/ directory
- fixed IO resource handling
- introduced PCI config accessors quirks matching
- moved ACPI_COMPANION_SET to generic code
v1 - https://lkml.org/lkml/2015/10/27/504
v2 - https://lkml.org/lkml/2015/12/16/246
v3 - http://lkml.iu.edu/hypermail/linux/kernel/1601.1/04308.html
v4 - https://lkml.org/lkml/2016/2/4/646
v5 - https://lkml.org/lkml/2016/2/16/426
Jayachandran C (2):
PCI: Provide common functions for ECAM mapping
PCI: generic, thunder: update to use generic ECAM API
Tomasz Nowicki (11):
pci, acpi, x86, ia64: Move ACPI host bridge device companion
assignment to core code.
pci, acpi: Provide generic way to assign bus domain number.
x86, ia64: Include acpi_pci_{add|remove}_bus to the default
pcibios_{add|remove}_bus implementation.
pci, of: Move the PCI I/O space management to PCI core code.
acpi, pci: Support IO resources when parsing PCI host bridge
resources.
arm64, pci, acpi: ACPI support for legacy IRQs parsing and
consolidation with DT code.
pci, acpi: Support for ACPI based generic PCI host controller
arm64, pci, acpi: Start using ACPI based PCI host controller driver
for ARM64.
pci, acpi: Match PCI config space accessors against platfrom specific
quirks.
pci, pci-thunder-ecam: Add ACPI support for ThunderX ECAM.
pci, pci-thunder-pem: Add ACPI support for ThunderX PEM.
arch/arm64/Kconfig | 15 +++
arch/arm64/include/asm/cpufeature.h | 3 +-
arch/arm64/kernel/cpu_errata.c | 8 ++
arch/arm64/kernel/pci.c | 35 ++---
arch/ia64/hp/common/sba_iommu.c | 2 +-
arch/ia64/include/asm/pci.h | 1 -
arch/ia64/pci/pci.c | 26 ----
arch/ia64/sn/kernel/io_acpi_init.c | 4 +-
arch/x86/include/asm/pci.h | 3 -
arch/x86/pci/acpi.c | 17 ---
arch/x86/pci/common.c | 10 --
drivers/acpi/Kconfig | 8 ++
drivers/acpi/Makefile | 1 +
drivers/acpi/bus.c | 1 +
drivers/acpi/pci_gen_host.c | 259 ++++++++++++++++++++++++++++++++++++
drivers/acpi/pci_root.c | 58 +++++++-
drivers/of/address.c | 116 +---------------
drivers/pci/Kconfig | 3 +
drivers/pci/Makefile | 2 +
drivers/pci/ecam.c | 137 +++++++++++++++++++
drivers/pci/ecam.h | 66 +++++++++
drivers/pci/host/Kconfig | 1 +
drivers/pci/host/pci-host-common.c | 119 ++++++++---------
drivers/pci/host/pci-host-common.h | 47 -------
drivers/pci/host/pci-host-generic.c | 52 ++------
drivers/pci/host/pci-thunder-ecam.c | 70 ++++++----
drivers/pci/host/pci-thunder-pem.c | 215 ++++++++++++++++++++++--------
drivers/pci/pci.c | 150 ++++++++++++++++++++-
drivers/pci/probe.c | 5 +
include/asm-generic/vmlinux.lds.h | 7 +
include/linux/of_address.h | 9 --
include/linux/pci-acpi.h | 20 +++
include/linux/pci.h | 12 ++
33 files changed, 1029 insertions(+), 453 deletions(-)
create mode 100644 drivers/acpi/pci_gen_host.c
create mode 100644 drivers/pci/ecam.c
create mode 100644 drivers/pci/ecam.h
delete mode 100644 drivers/pci/host/pci-host-common.h
--
1.9.1
[toc] | [next] | [standalone]
| From | Tomasz Nowicki <tn@semihalf.com> |
|---|---|
| Date | 2016-04-15 19:10 +0200 |
| Subject | [PATCH V6 11/13] pci, acpi: Match PCI config space accessors against platfrom specific quirks. |
| Message-ID | <rofpL-6tr-3@gated-at.bofh.it> |
| In reply to | #1380019 |
Some platforms may not be fully compliant with generic set of PCI config
accessors. For these cases we implement the way to overwrite accessors
set prior to PCI buses enumeration. Algorithm traverses available quirk
list, matches against <DMI ID (optional), domain, bus number> tuple and
an extra match call and returns corresponding PCI config ops.
All quirks can be defined using:
DECLARE_ACPI_MCFG_FIXUP() macro and kept self contained. Example:
/* Additional DMI platform identification (optional) */
static const struct dmi_system_id foo_dmi[] = {
{
.ident = "<Platform ident string>",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "<system vendor>"),
DMI_MATCH(DMI_PRODUCT_NAME, "<product name>"),
DMI_MATCH(DMI_PRODUCT_VERSION, "product version"),
},
},
{ }
};
/* Custom PCI config ops */
static struct pci_generic_ecam_ops foo_pci_ops = {
.bus_shift = 24,
.pci_ops = {
.map_bus = pci_mcfg_dev_base,
.read = foo_ecam_config_read,
.write = foo_ecam_config_write,
}
};
static int foo_match(struct pci_mcfg_fixup *fixup, struct acpi_pci_root *root)
{
if (additional platform identification)
return true;
return false;
}
DECLARE_ACPI_MCFG_FIXUP(foo_dmi, foo_init, &foo_root_ops, <domain_nr>, <bus_nr>);
Signed-off-by: Tomasz Nowicki <tn@semihalf.com>
---
drivers/acpi/pci_gen_host.c | 30 +++++++++++++++++++++++++++++-
include/asm-generic/vmlinux.lds.h | 7 +++++++
include/linux/pci-acpi.h | 18 ++++++++++++++++++
3 files changed, 54 insertions(+), 1 deletion(-)
diff --git a/drivers/acpi/pci_gen_host.c b/drivers/acpi/pci_gen_host.c
index fd360b5..e55dfca 100644
--- a/drivers/acpi/pci_gen_host.c
+++ b/drivers/acpi/pci_gen_host.c
@@ -11,6 +11,8 @@
* You should have received a copy of the GNU General Public License
* version 2 (GPLv2) along with this source code.
*/
+
+#include <linux/dmi.h>
#include <linux/kernel.h>
#include <linux/pci.h>
#include <linux/pci-acpi.h>
@@ -54,6 +56,32 @@ static struct mcfg_entry *pci_mcfg_lookup(u16 seg, u8 bus_start)
return NULL;
}
+extern struct pci_cfg_fixup __start_acpi_mcfg_fixups[];
+extern struct pci_cfg_fixup __end_acpi_mcfg_fixups[];
+
+static struct pci_generic_ecam_ops *pci_acpi_get_ops(struct acpi_pci_root *root)
+{
+ int bus_num = root->secondary.start;
+ int domain = root->segment;
+ struct pci_cfg_fixup *f;
+
+ /*
+ * Match against platform specific quirks and return corresponding
+ * CAM ops.
+ *
+ * First match against PCI topology <domain:bus> then use DMI or
+ * custom match handler.
+ */
+ for (f = __start_acpi_mcfg_fixups; f < __end_acpi_mcfg_fixups; f++) {
+ if ((f->domain == domain || f->domain == PCI_MCFG_DOMAIN_ANY) &&
+ (f->bus_num == bus_num || f->bus_num == PCI_MCFG_BUS_ANY) &&
+ (f->system ? dmi_check_system(f->system) : 1) &&
+ (f->match ? f->match(f, root) : 1))
+ return f->ops;
+ }
+ /* No quirks, use ECAM */
+ return &pci_generic_ecam_default_ops;
+}
/*
* Lookup the bus range for the domain in MCFG, and set up config space
@@ -95,7 +123,7 @@ static int pci_acpi_setup_ecam_mapping(struct acpi_pci_root *root,
}
cfg = pci_generic_ecam_create(&root->device->dev, addr, bus_start,
- bus_end, &pci_generic_ecam_default_ops);
+ bus_end, pci_acpi_get_ops(root));
if (IS_ERR(cfg)) {
err = PTR_ERR(cfg);
pr_err("%04x:%02x-%02x error %d mapping CAM\n", seg,
diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h
index 339125b..c53b6b7 100644
--- a/include/asm-generic/vmlinux.lds.h
+++ b/include/asm-generic/vmlinux.lds.h
@@ -298,6 +298,13 @@
VMLINUX_SYMBOL(__end_pci_fixups_suspend_late) = .; \
} \
\
+ /* ACPI MCFG quirks */ \
+ .acpi_fixup : AT(ADDR(.acpi_fixup) - LOAD_OFFSET) { \
+ VMLINUX_SYMBOL(__start_acpi_mcfg_fixups) = .; \
+ *(.acpi_fixup_mcfg) \
+ VMLINUX_SYMBOL(__end_acpi_mcfg_fixups) = .; \
+ } \
+ \
/* Built-in firmware blobs */ \
.builtin_fw : AT(ADDR(.builtin_fw) - LOAD_OFFSET) { \
VMLINUX_SYMBOL(__start_builtin_fw) = .; \
diff --git a/include/linux/pci-acpi.h b/include/linux/pci-acpi.h
index a72e22d..9545988 100644
--- a/include/linux/pci-acpi.h
+++ b/include/linux/pci-acpi.h
@@ -71,6 +71,24 @@ struct acpi_pci_root_ops {
int (*prepare_resources)(struct acpi_pci_root_info *info);
};
+struct pci_cfg_fixup {
+ const struct dmi_system_id *system;
+ bool (*match)(struct pci_cfg_fixup *, struct acpi_pci_root *);
+ struct pci_generic_ecam_ops *ops;
+ int domain;
+ int bus_num;
+};
+
+#define PCI_MCFG_DOMAIN_ANY -1
+#define PCI_MCFG_BUS_ANY -1
+
+/* Designate a routine to fix up buggy MCFG */
+#define DECLARE_ACPI_MCFG_FIXUP(system, match, ops, dom, bus) \
+ static const struct pci_cfg_fixup __mcfg_fixup_##system##dom##bus\
+ __used __attribute__((__section__(".acpi_fixup_mcfg"), \
+ aligned((sizeof(void *))))) = \
+ { system, match, ops, dom, bus };
+
extern int acpi_pci_probe_root_resources(struct acpi_pci_root_info *info);
extern struct pci_bus *acpi_pci_root_create(struct acpi_pci_root *root,
struct acpi_pci_root_ops *ops,
--
1.9.1
[toc] | [prev] | [next] | [standalone]
| From | "liudongdong (C)" <liudongdong3@huawei.com> |
|---|---|
| Date | 2016-04-18 14:00 +0200 |
| Subject | Re: [PATCH V6 11/13] pci, acpi: Match PCI config space accessors against platfrom specific quirks. |
| Message-ID | <rpg0r-502-19@gated-at.bofh.it> |
| In reply to | #1380020 |
Hi Tomasz
I merged my patchset to branch topci-acpi-v6.
The patchset is used for Hisilicon DO2 PCIe ACPI support.
I found some compile errors. The log as below.
drivers/pci/host/pcie-hisi-acpi.c: In function 'hisi_pcie_init':
drivers/pci/host/pcie-hisi-acpi.c:130:6: error: 'struct acpi_pci_root' has no member named 'sysdata'
root->sysdata = reg_base;
In your PATCH V5, add "sysdata" for strcut acpi_pci_root, but PATCH V6 has not add it.
In my patch, I used root->sysdata which will be available along read/write accessor.
I want to know the reason this v6 patchset does not add "sysdata". I need this.
diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h
index 14362a8..0fc6f13 100644
--- a/include/acpi/acpi_bus.h
+++ b/include/acpi/acpi_bus.h
@@ -556,6 +556,7 @@ struct acpi_pci_root {
struct pci_bus *bus;
u16 segment;
struct resource secondary; /* downstream bus range */
+ void *sysdata;
u32 osc_support_set; /* _OSC state of support bits */
u32 osc_control_set; /* _OSC state of control bits */
Thanks
Dongdong
在 2016/4/16 1:06, Tomasz Nowicki 写道:
> Some platforms may not be fully compliant with generic set of PCI config
> accessors. For these cases we implement the way to overwrite accessors
> set prior to PCI buses enumeration. Algorithm traverses available quirk
> list, matches against <DMI ID (optional), domain, bus number> tuple and
> an extra match call and returns corresponding PCI config ops.
> All quirks can be defined using:
> DECLARE_ACPI_MCFG_FIXUP() macro and kept self contained. Example:
>
> /* Additional DMI platform identification (optional) */
> static const struct dmi_system_id foo_dmi[] = {
> {
> .ident = "<Platform ident string>",
> .matches = {
> DMI_MATCH(DMI_SYS_VENDOR, "<system vendor>"),
> DMI_MATCH(DMI_PRODUCT_NAME, "<product name>"),
> DMI_MATCH(DMI_PRODUCT_VERSION, "product version"),
> },
> },
> { }
> };
>
> /* Custom PCI config ops */
> static struct pci_generic_ecam_ops foo_pci_ops = {
> .bus_shift = 24,
> .pci_ops = {
> .map_bus = pci_mcfg_dev_base,
> .read = foo_ecam_config_read,
> .write = foo_ecam_config_write,
> }
> };
>
> static int foo_match(struct pci_mcfg_fixup *fixup, struct acpi_pci_root *root)
> {
> if (additional platform identification)
> return true;
> return false;
> }
>
> DECLARE_ACPI_MCFG_FIXUP(foo_dmi, foo_init, &foo_root_ops, <domain_nr>, <bus_nr>);
>
> Signed-off-by: Tomasz Nowicki <tn@semihalf.com>
> ---
> drivers/acpi/pci_gen_host.c | 30 +++++++++++++++++++++++++++++-
> include/asm-generic/vmlinux.lds.h | 7 +++++++
> include/linux/pci-acpi.h | 18 ++++++++++++++++++
> 3 files changed, 54 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/acpi/pci_gen_host.c b/drivers/acpi/pci_gen_host.c
> index fd360b5..e55dfca 100644
> --- a/drivers/acpi/pci_gen_host.c
> +++ b/drivers/acpi/pci_gen_host.c
> @@ -11,6 +11,8 @@
> * You should have received a copy of the GNU General Public License
> * version 2 (GPLv2) along with this source code.
> */
> +
> +#include <linux/dmi.h>
> #include <linux/kernel.h>
> #include <linux/pci.h>
> #include <linux/pci-acpi.h>
> @@ -54,6 +56,32 @@ static struct mcfg_entry *pci_mcfg_lookup(u16 seg, u8 bus_start)
> return NULL;
> }
>
> +extern struct pci_cfg_fixup __start_acpi_mcfg_fixups[];
> +extern struct pci_cfg_fixup __end_acpi_mcfg_fixups[];
> +
> +static struct pci_generic_ecam_ops *pci_acpi_get_ops(struct acpi_pci_root *root)
> +{
> + int bus_num = root->secondary.start;
> + int domain = root->segment;
> + struct pci_cfg_fixup *f;
> +
> + /*
> + * Match against platform specific quirks and return corresponding
> + * CAM ops.
> + *
> + * First match against PCI topology <domain:bus> then use DMI or
> + * custom match handler.
> + */
> + for (f = __start_acpi_mcfg_fixups; f < __end_acpi_mcfg_fixups; f++) {
> + if ((f->domain == domain || f->domain == PCI_MCFG_DOMAIN_ANY) &&
> + (f->bus_num == bus_num || f->bus_num == PCI_MCFG_BUS_ANY) &&
> + (f->system ? dmi_check_system(f->system) : 1) &&
> + (f->match ? f->match(f, root) : 1))
> + return f->ops;
> + }
> + /* No quirks, use ECAM */
> + return &pci_generic_ecam_default_ops;
> +}
>
> /*
> * Lookup the bus range for the domain in MCFG, and set up config space
> @@ -95,7 +123,7 @@ static int pci_acpi_setup_ecam_mapping(struct acpi_pci_root *root,
> }
>
> cfg = pci_generic_ecam_create(&root->device->dev, addr, bus_start,
> - bus_end, &pci_generic_ecam_default_ops);
> + bus_end, pci_acpi_get_ops(root));
> if (IS_ERR(cfg)) {
> err = PTR_ERR(cfg);
> pr_err("%04x:%02x-%02x error %d mapping CAM\n", seg,
> diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h
> index 339125b..c53b6b7 100644
> --- a/include/asm-generic/vmlinux.lds.h
> +++ b/include/asm-generic/vmlinux.lds.h
> @@ -298,6 +298,13 @@
> VMLINUX_SYMBOL(__end_pci_fixups_suspend_late) = .; \
> } \
> \
> + /* ACPI MCFG quirks */ \
> + .acpi_fixup : AT(ADDR(.acpi_fixup) - LOAD_OFFSET) { \
> + VMLINUX_SYMBOL(__start_acpi_mcfg_fixups) = .; \
> + *(.acpi_fixup_mcfg) \
> + VMLINUX_SYMBOL(__end_acpi_mcfg_fixups) = .; \
> + } \
> + \
> /* Built-in firmware blobs */ \
> .builtin_fw : AT(ADDR(.builtin_fw) - LOAD_OFFSET) { \
> VMLINUX_SYMBOL(__start_builtin_fw) = .; \
> diff --git a/include/linux/pci-acpi.h b/include/linux/pci-acpi.h
> index a72e22d..9545988 100644
> --- a/include/linux/pci-acpi.h
> +++ b/include/linux/pci-acpi.h
> @@ -71,6 +71,24 @@ struct acpi_pci_root_ops {
> int (*prepare_resources)(struct acpi_pci_root_info *info);
> };
>
> +struct pci_cfg_fixup {
> + const struct dmi_system_id *system;
> + bool (*match)(struct pci_cfg_fixup *, struct acpi_pci_root *);
> + struct pci_generic_ecam_ops *ops;
> + int domain;
> + int bus_num;
> +};
> +
> +#define PCI_MCFG_DOMAIN_ANY -1
> +#define PCI_MCFG_BUS_ANY -1
> +
> +/* Designate a routine to fix up buggy MCFG */
> +#define DECLARE_ACPI_MCFG_FIXUP(system, match, ops, dom, bus) \
> + static const struct pci_cfg_fixup __mcfg_fixup_##system##dom##bus\
> + __used __attribute__((__section__(".acpi_fixup_mcfg"), \
> + aligned((sizeof(void *))))) = \
> + { system, match, ops, dom, bus };
> +
> extern int acpi_pci_probe_root_resources(struct acpi_pci_root_info *info);
> extern struct pci_bus *acpi_pci_root_create(struct acpi_pci_root *root,
> struct acpi_pci_root_ops *ops,
>
[toc] | [prev] | [next] | [standalone]
| From | Tomasz Nowicki <tn@semihalf.com> |
|---|---|
| Date | 2016-04-18 14:30 +0200 |
| Subject | Re: [PATCH V6 11/13] pci, acpi: Match PCI config space accessors against platfrom specific quirks. |
| Message-ID | <rpgts-5Be-7@gated-at.bofh.it> |
| In reply to | #1381638 |
On 18.04.2016 13:37, liudongdong (C) wrote: > Hi Tomasz > > I merged my patchset to branch topci-acpi-v6. > The patchset is used for Hisilicon DO2 PCIe ACPI support. > I found some compile errors. The log as below. > drivers/pci/host/pcie-hisi-acpi.c: In function 'hisi_pcie_init': > drivers/pci/host/pcie-hisi-acpi.c:130:6: error: 'struct acpi_pci_root' > has no member named 'sysdata' > root->sysdata = reg_base; > > In your PATCH V5, add "sysdata" for strcut acpi_pci_root, but PATCH V6 > has not add it. > In my patch, I used root->sysdata which will be available along > read/write accessor. > I want to know the reason this v6 patchset does not add "sysdata". I > need this. We are handling this different way. You can now use "struct pci_config_window" -> priv, see pci-thunder-pem.c driver. Tomasz
[toc] | [prev] | [next] | [standalone]
| From | Tomasz Nowicki <tn@semihalf.com> |
|---|---|
| Date | 2016-04-15 19:10 +0200 |
| Subject | [PATCH V6 13/13] pci, pci-thunder-pem: Add ACPI support for ThunderX PEM. |
| Message-ID | <rofpM-6tr-13@gated-at.bofh.it> |
| In reply to | #1380019 |
This patch uses DECLARE_ACPI_MCFG_FIXUP to overwrite PCI config accessors.
Also, it provides alternative way to find additional configuration region:
thunder_pem_get_acpi_res is looking for host bridge's child (_HID "THRX0001")
which contains mentioned configuration region description.
See example below:
Device (PEM0) {
Name (_HID, EISAID ("PNP0A08"))
Name (_CID, EISAID ("PNP0A03"))
[...]
Device (CFG0)
{
Name (_HID, "THRX0001") // PEM configuration space resources
Name (_CRS, ResourceTemplate () {
QWordMemory(ResourceConsumer, PosDecode, MinFixed, MaxFixed,
NonCacheable, ReadWrite, 0, 0x87e0c5000000, 0x87E0C5FFFFFF,
0, 0x01000000)
})
}
}
Signed-off-by: Tomasz Nowicki <tn@semihalf.com>
---
drivers/pci/host/pci-thunder-pem.c | 137 ++++++++++++++++++++++++++++++++++---
1 file changed, 128 insertions(+), 9 deletions(-)
diff --git a/drivers/pci/host/pci-thunder-pem.c b/drivers/pci/host/pci-thunder-pem.c
index 91cfeb9..685cd79 100644
--- a/drivers/pci/host/pci-thunder-pem.c
+++ b/drivers/pci/host/pci-thunder-pem.c
@@ -18,6 +18,7 @@
#include <linux/module.h>
#include <linux/of_address.h>
#include <linux/of_pci.h>
+#include <linux/pci-acpi.h>
#include <linux/platform_device.h>
#include "../ecam.h"
@@ -259,6 +260,83 @@ static int thunder_pem_config_write(struct pci_bus *bus, unsigned int devfn,
return pci_generic_config_write(bus, devfn, where, size, val);
}
+#ifdef CONFIG_ACPI
+
+struct pem_acpi_res {
+ struct resource resource;
+ int found;
+};
+
+static acpi_status
+thunder_pem_cfg(struct acpi_resource *resource, void *ctx)
+{
+ struct pem_acpi_res *pem_ctx = ctx;
+ struct resource *res = &pem_ctx->resource;
+
+ if ((resource->type != ACPI_RESOURCE_TYPE_ADDRESS64) ||
+ (resource->data.address32.resource_type != ACPI_MEMORY_RANGE))
+ return AE_OK;
+
+ res->start = resource->data.address64.address.minimum;
+ res->end = resource->data.address64.address.maximum;
+ res->flags = IORESOURCE_MEM;
+
+ pem_ctx->found++;
+ return AE_OK;
+}
+
+static acpi_status
+thunder_pem_find_dev(acpi_handle handle, u32 level, void *ctx, void **ret)
+{
+ struct pem_acpi_res *pem_ctx = ctx;
+ struct acpi_device_info *info;
+ acpi_status status = AE_OK;
+
+ status = acpi_get_object_info(handle, &info);
+ if (ACPI_FAILURE(status))
+ return AE_OK;
+
+ if (strncmp(info->hardware_id.string, "THRX0001", 8) != 0)
+ goto out;
+
+ pem_ctx->found = 0;
+ status = acpi_walk_resources(handle, METHOD_NAME__CRS, thunder_pem_cfg,
+ pem_ctx);
+ if (ACPI_FAILURE(status))
+ goto out;
+
+ if (pem_ctx->found)
+ status = AE_CTRL_TERMINATE;
+out:
+ kfree(info);
+ return status;
+}
+
+static struct resource *thunder_pem_get_acpi_res(struct device *dev)
+{
+ struct acpi_device *adev = ACPI_COMPANION(dev);
+ acpi_handle handle = acpi_device_handle(adev);
+ struct pem_acpi_res *pem_ctx;
+ acpi_status status;
+
+ pem_ctx = devm_kzalloc(dev, sizeof(*pem_ctx), GFP_KERNEL);
+ if (!pem_ctx)
+ return NULL;
+
+ status = acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, 1,
+ thunder_pem_find_dev, NULL, pem_ctx, NULL);
+ if (ACPI_FAILURE(status) || !pem_ctx->found)
+ return NULL;
+
+ return &pem_ctx->resource;
+}
+#else
+static struct resource *thunder_pem_get_acpi_res(struct device *dev)
+{
+ return NULL;
+}
+#endif
+
static int thunder_pem_init(struct device *dev, struct pci_config_window *cfg)
{
resource_size_t bar4_start;
@@ -270,16 +348,20 @@ static int thunder_pem_init(struct device *dev, struct pci_config_window *cfg)
if (!pem_pci)
return -ENOMEM;
- pdev = to_platform_device(dev);
-
- /*
- * The second register range is the PEM bridge to the PCIe
- * bus. It has a different config access method than those
- * devices behind the bridge.
- */
- res_pem = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+ if (acpi_disabled) {
+ pdev = to_platform_device(dev);
+
+ /*
+ * The second register range is the PEM bridge to the PCIe
+ * bus. It has a different config access method than those
+ * devices behind the bridge.
+ */
+ res_pem = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+ } else {
+ res_pem = thunder_pem_get_acpi_res(dev);
+ }
if (!res_pem) {
- dev_err(dev, "missing \"reg[1]\"property\n");
+ dev_err(dev, "missing configuration region\n");
return -EINVAL;
}
@@ -332,5 +414,42 @@ static struct platform_driver thunder_pem_driver = {
};
module_platform_driver(thunder_pem_driver);
+#ifdef CONFIG_ACPI
+
+static bool thunder_pem_acpi_init(struct pci_cfg_fixup *fixup,
+ struct acpi_pci_root *root)
+{
+ u32 midr = read_cpuid_id();
+
+ return (MIDR_IMPLEMENTOR(midr) == ARM_CPU_IMP_CAVIUM) &&
+ (MIDR_PARTNUM(midr) == CAVIUM_CPU_PART_THUNDERX);
+}
+
+DECLARE_ACPI_MCFG_FIXUP(NULL, thunder_pem_acpi_init, &pci_thunder_pem_ops,
+ 4, PCI_MCFG_BUS_ANY);
+DECLARE_ACPI_MCFG_FIXUP(NULL, thunder_pem_acpi_init, &pci_thunder_pem_ops,
+ 5, PCI_MCFG_BUS_ANY);
+DECLARE_ACPI_MCFG_FIXUP(NULL, thunder_pem_acpi_init, &pci_thunder_pem_ops,
+ 6, PCI_MCFG_BUS_ANY);
+DECLARE_ACPI_MCFG_FIXUP(NULL, thunder_pem_acpi_init, &pci_thunder_pem_ops,
+ 7, PCI_MCFG_BUS_ANY);
+DECLARE_ACPI_MCFG_FIXUP(NULL, thunder_pem_acpi_init, &pci_thunder_pem_ops,
+ 8, PCI_MCFG_BUS_ANY);
+DECLARE_ACPI_MCFG_FIXUP(NULL, thunder_pem_acpi_init, &pci_thunder_pem_ops,
+ 9, PCI_MCFG_BUS_ANY);
+DECLARE_ACPI_MCFG_FIXUP(NULL, thunder_pem_acpi_init, &pci_thunder_pem_ops,
+ 14, PCI_MCFG_BUS_ANY);
+DECLARE_ACPI_MCFG_FIXUP(NULL, thunder_pem_acpi_init, &pci_thunder_pem_ops,
+ 15, PCI_MCFG_BUS_ANY);
+DECLARE_ACPI_MCFG_FIXUP(NULL, thunder_pem_acpi_init, &pci_thunder_pem_ops,
+ 16, PCI_MCFG_BUS_ANY);
+DECLARE_ACPI_MCFG_FIXUP(NULL, thunder_pem_acpi_init, &pci_thunder_pem_ops,
+ 17, PCI_MCFG_BUS_ANY);
+DECLARE_ACPI_MCFG_FIXUP(NULL, thunder_pem_acpi_init, &pci_thunder_pem_ops,
+ 18, PCI_MCFG_BUS_ANY);
+DECLARE_ACPI_MCFG_FIXUP(NULL, thunder_pem_acpi_init, &pci_thunder_pem_ops,
+ 19, PCI_MCFG_BUS_ANY);
+#endif
+
MODULE_DESCRIPTION("Thunder PEM PCIe host driver");
MODULE_LICENSE("GPL v2");
--
1.9.1
[toc] | [prev] | [next] | [standalone]
| From | Tomasz Nowicki <tn@semihalf.com> |
|---|---|
| Date | 2016-04-15 19:10 +0200 |
| Subject | [PATCH V6 02/13] pci, acpi: Provide generic way to assign bus domain number. |
| Message-ID | <rofpM-6tr-29@gated-at.bofh.it> |
| In reply to | #1380019 |
As we now have valid PCI host bridge device reference we can
introduce code that is going to find its bus domain number using
ACPI _SEG method.
Note that _SEG method is optional, therefore _SEG absence means
that all PCI buses belong to domain 0.
While at it, for the sake of code clarity we put ACPI and DT domain
assign methods into the corresponding helpers.
Signed-off-by: Tomasz Nowicki <tn@semihalf.com>
Reviewed-by: Liviu Dudau <Liviu.Dudau@arm.com>
Tested-by: Suravee Suthikulpanit <Suravee.Suthikulpanit@amd.com>
Tested-by: Jeremy Linton <jeremy.linton@arm.com>
Tested-by: Duc Dang <dhdang@apm.com>
Tested-by: Dongdong Liu <liudongdong3@huawei.com>
Tested-by: Hanjun Guo <hanjun.guo@linaro.org>
Tested-by: Graeme Gregory <graeme.gregory@linaro.org>
Tested-by: Sinan Kaya <okaya@codeaurora.org>
---
drivers/acpi/pci_root.c | 18 ++++++++++++++++++
drivers/pci/pci.c | 11 +++++++++--
include/linux/pci-acpi.h | 2 ++
3 files changed, 29 insertions(+), 2 deletions(-)
diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
index 4581e0e..d9a70c4 100644
--- a/drivers/acpi/pci_root.c
+++ b/drivers/acpi/pci_root.c
@@ -419,6 +419,24 @@ out:
}
EXPORT_SYMBOL(acpi_pci_osc_control_set);
+int acpi_pci_bus_domain_nr(struct device *parent)
+{
+ struct acpi_device *acpi_dev = to_acpi_device(parent);
+ unsigned long long segment = 0;
+ acpi_status status;
+
+ /*
+ * If _SEG method does not exist, following ACPI spec (6.5.6)
+ * all PCI buses belong to domain 0.
+ */
+ status = acpi_evaluate_integer(acpi_dev->handle, METHOD_NAME__SEG, NULL,
+ &segment);
+ if (ACPI_FAILURE(status) && status != AE_NOT_FOUND)
+ dev_err(&acpi_dev->dev, "can't evaluate _SEG\n");
+
+ return segment;
+}
+
static void negotiate_os_control(struct acpi_pci_root *root, int *no_aspm)
{
u32 support, control, requested;
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index 25e0327..1a74e87 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -19,6 +19,7 @@
#include <linux/spinlock.h>
#include <linux/string.h>
#include <linux/log2.h>
+#include <linux/pci-acpi.h>
#include <linux/pci-aspm.h>
#include <linux/pm_wakeup.h>
#include <linux/interrupt.h>
@@ -4779,7 +4780,7 @@ int pci_get_new_domain_nr(void)
}
#ifdef CONFIG_PCI_DOMAINS_GENERIC
-void pci_bus_assign_domain_nr(struct pci_bus *bus, struct device *parent)
+static int of_pci_bus_domain_nr(struct device *parent)
{
static int use_dt_domains = -1;
int domain = -1;
@@ -4823,7 +4824,13 @@ void pci_bus_assign_domain_nr(struct pci_bus *bus, struct device *parent)
domain = -1;
}
- bus->domain_nr = domain;
+ return domain;
+}
+
+void pci_bus_assign_domain_nr(struct pci_bus *bus, struct device *parent)
+{
+ bus->domain_nr = acpi_disabled ? of_pci_bus_domain_nr(parent) :
+ acpi_pci_bus_domain_nr(parent);
}
#endif
#endif
diff --git a/include/linux/pci-acpi.h b/include/linux/pci-acpi.h
index 89ab057..a72e22d 100644
--- a/include/linux/pci-acpi.h
+++ b/include/linux/pci-acpi.h
@@ -22,6 +22,7 @@ static inline acpi_status pci_acpi_remove_pm_notifier(struct acpi_device *dev)
{
return acpi_remove_pm_notifier(dev);
}
+extern int acpi_pci_bus_domain_nr(struct device *parent);
extern phys_addr_t acpi_pci_root_get_mcfg_addr(acpi_handle handle);
static inline acpi_handle acpi_find_root_bridge_handle(struct pci_dev *pdev)
@@ -109,6 +110,7 @@ extern const u8 pci_acpi_dsm_uuid[];
#else /* CONFIG_ACPI */
static inline void acpi_pci_add_bus(struct pci_bus *bus) { }
static inline void acpi_pci_remove_bus(struct pci_bus *bus) { }
+static inline int acpi_pci_bus_domain_nr(struct device *parent) { return -1; }
#endif /* CONFIG_ACPI */
#ifdef CONFIG_ACPI_APEI
--
1.9.1
[toc] | [prev] | [next] | [standalone]
| From | Bjorn Helgaas <helgaas@kernel.org> |
|---|---|
| Date | 2016-04-27 04:30 +0200 |
| Subject | Re: [PATCH V6 02/13] pci, acpi: Provide generic way to assign bus domain number. |
| Message-ID | <rsnoK-1L5-11@gated-at.bofh.it> |
| In reply to | #1380027 |
On Fri, Apr 15, 2016 at 07:06:37PM +0200, Tomasz Nowicki wrote:
> As we now have valid PCI host bridge device reference we can
> introduce code that is going to find its bus domain number using
> ACPI _SEG method.
>
> Note that _SEG method is optional, therefore _SEG absence means
> that all PCI buses belong to domain 0.
>
> While at it, for the sake of code clarity we put ACPI and DT domain
> assign methods into the corresponding helpers.
>
> Signed-off-by: Tomasz Nowicki <tn@semihalf.com>
> Reviewed-by: Liviu Dudau <Liviu.Dudau@arm.com>
> Tested-by: Suravee Suthikulpanit <Suravee.Suthikulpanit@amd.com>
> Tested-by: Jeremy Linton <jeremy.linton@arm.com>
> Tested-by: Duc Dang <dhdang@apm.com>
> Tested-by: Dongdong Liu <liudongdong3@huawei.com>
> Tested-by: Hanjun Guo <hanjun.guo@linaro.org>
> Tested-by: Graeme Gregory <graeme.gregory@linaro.org>
> Tested-by: Sinan Kaya <okaya@codeaurora.org>
> ---
> drivers/acpi/pci_root.c | 18 ++++++++++++++++++
> drivers/pci/pci.c | 11 +++++++++--
> include/linux/pci-acpi.h | 2 ++
> 3 files changed, 29 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
> index 4581e0e..d9a70c4 100644
> --- a/drivers/acpi/pci_root.c
> +++ b/drivers/acpi/pci_root.c
> @@ -419,6 +419,24 @@ out:
> }
> EXPORT_SYMBOL(acpi_pci_osc_control_set);
>
> +int acpi_pci_bus_domain_nr(struct device *parent)
> +{
> + struct acpi_device *acpi_dev = to_acpi_device(parent);
> + unsigned long long segment = 0;
> + acpi_status status;
> +
> + /*
> + * If _SEG method does not exist, following ACPI spec (6.5.6)
> + * all PCI buses belong to domain 0.
> + */
> + status = acpi_evaluate_integer(acpi_dev->handle, METHOD_NAME__SEG, NULL,
> + &segment);
We already have code in acpi_pci_root_add() to evaluate _SEG. We
don't want to evaluate it *twice*, do we?
I was sort of expecting that if you added it here, we'd remove the
existing call, but it looks like you're keeping both?
> + if (ACPI_FAILURE(status) && status != AE_NOT_FOUND)
> + dev_err(&acpi_dev->dev, "can't evaluate _SEG\n");
> +
> + return segment;
> +}
> +
> static void negotiate_os_control(struct acpi_pci_root *root, int *no_aspm)
> {
> u32 support, control, requested;
> diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
> index 25e0327..1a74e87 100644
> --- a/drivers/pci/pci.c
> +++ b/drivers/pci/pci.c
> @@ -19,6 +19,7 @@
> #include <linux/spinlock.h>
> #include <linux/string.h>
> #include <linux/log2.h>
> +#include <linux/pci-acpi.h>
> #include <linux/pci-aspm.h>
> #include <linux/pm_wakeup.h>
> #include <linux/interrupt.h>
> @@ -4779,7 +4780,7 @@ int pci_get_new_domain_nr(void)
> }
>
> #ifdef CONFIG_PCI_DOMAINS_GENERIC
> -void pci_bus_assign_domain_nr(struct pci_bus *bus, struct device *parent)
> +static int of_pci_bus_domain_nr(struct device *parent)
> {
> static int use_dt_domains = -1;
> int domain = -1;
> @@ -4823,7 +4824,13 @@ void pci_bus_assign_domain_nr(struct pci_bus *bus, struct device *parent)
> domain = -1;
> }
>
> - bus->domain_nr = domain;
> + return domain;
> +}
> +
> +void pci_bus_assign_domain_nr(struct pci_bus *bus, struct device *parent)
> +{
> + bus->domain_nr = acpi_disabled ? of_pci_bus_domain_nr(parent) :
> + acpi_pci_bus_domain_nr(parent);
> }
> #endif
> #endif
> diff --git a/include/linux/pci-acpi.h b/include/linux/pci-acpi.h
> index 89ab057..a72e22d 100644
> --- a/include/linux/pci-acpi.h
> +++ b/include/linux/pci-acpi.h
> @@ -22,6 +22,7 @@ static inline acpi_status pci_acpi_remove_pm_notifier(struct acpi_device *dev)
> {
> return acpi_remove_pm_notifier(dev);
> }
> +extern int acpi_pci_bus_domain_nr(struct device *parent);
> extern phys_addr_t acpi_pci_root_get_mcfg_addr(acpi_handle handle);
>
> static inline acpi_handle acpi_find_root_bridge_handle(struct pci_dev *pdev)
> @@ -109,6 +110,7 @@ extern const u8 pci_acpi_dsm_uuid[];
> #else /* CONFIG_ACPI */
> static inline void acpi_pci_add_bus(struct pci_bus *bus) { }
> static inline void acpi_pci_remove_bus(struct pci_bus *bus) { }
> +static inline int acpi_pci_bus_domain_nr(struct device *parent) { return -1; }
> #endif /* CONFIG_ACPI */
>
> #ifdef CONFIG_ACPI_APEI
> --
> 1.9.1
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
[toc] | [prev] | [next] | [standalone]
| From | Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> |
|---|---|
| Date | 2016-04-27 13:20 +0200 |
| Subject | Re: [PATCH V6 02/13] pci, acpi: Provide generic way to assign bus domain number. |
| Message-ID | <rsvFF-dE-35@gated-at.bofh.it> |
| In reply to | #1388598 |
On Tue, Apr 26, 2016 at 09:26:49PM -0500, Bjorn Helgaas wrote:
> On Fri, Apr 15, 2016 at 07:06:37PM +0200, Tomasz Nowicki wrote:
> > As we now have valid PCI host bridge device reference we can
> > introduce code that is going to find its bus domain number using
> > ACPI _SEG method.
> >
> > Note that _SEG method is optional, therefore _SEG absence means
> > that all PCI buses belong to domain 0.
> >
> > While at it, for the sake of code clarity we put ACPI and DT domain
> > assign methods into the corresponding helpers.
> >
> > Signed-off-by: Tomasz Nowicki <tn@semihalf.com>
> > Reviewed-by: Liviu Dudau <Liviu.Dudau@arm.com>
> > Tested-by: Suravee Suthikulpanit <Suravee.Suthikulpanit@amd.com>
> > Tested-by: Jeremy Linton <jeremy.linton@arm.com>
> > Tested-by: Duc Dang <dhdang@apm.com>
> > Tested-by: Dongdong Liu <liudongdong3@huawei.com>
> > Tested-by: Hanjun Guo <hanjun.guo@linaro.org>
> > Tested-by: Graeme Gregory <graeme.gregory@linaro.org>
> > Tested-by: Sinan Kaya <okaya@codeaurora.org>
> > ---
> > drivers/acpi/pci_root.c | 18 ++++++++++++++++++
> > drivers/pci/pci.c | 11 +++++++++--
> > include/linux/pci-acpi.h | 2 ++
> > 3 files changed, 29 insertions(+), 2 deletions(-)
> >
> > diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
> > index 4581e0e..d9a70c4 100644
> > --- a/drivers/acpi/pci_root.c
> > +++ b/drivers/acpi/pci_root.c
> > @@ -419,6 +419,24 @@ out:
> > }
> > EXPORT_SYMBOL(acpi_pci_osc_control_set);
> >
> > +int acpi_pci_bus_domain_nr(struct device *parent)
> > +{
> > + struct acpi_device *acpi_dev = to_acpi_device(parent);
> > + unsigned long long segment = 0;
> > + acpi_status status;
> > +
> > + /*
> > + * If _SEG method does not exist, following ACPI spec (6.5.6)
> > + * all PCI buses belong to domain 0.
> > + */
> > + status = acpi_evaluate_integer(acpi_dev->handle, METHOD_NAME__SEG, NULL,
> > + &segment);
>
> We already have code in acpi_pci_root_add() to evaluate _SEG. We
> don't want to evaluate it *twice*, do we?
>
> I was sort of expecting that if you added it here, we'd remove the
> existing call, but it looks like you're keeping both?
We can't remove the existing call, since it is used on X86 and IA64
to store the segment number that, in the process, is used in their
pci_domain_nr() arch specific callback to retrieve the domain nr.
On ARM64, that selects PCI_DOMAINS_GENERIC, we have to find a way
to retrieve the domain number that is not arch dependent, since
this is generic code, we can't rely on any bus->sysdata format (unless
we do something like JC did below), therefore the only way is to call
the _SEG method *again* here, which also forced Tomasz to go through
the ACPI_COMPANION setting song and dance and pass the parent pointer
to pci_create_root_bus() (see patch 1), which BTW is a source of
trouble on its own as you noticed.
JC solved it differently, via sysdata and pseudo-generic code:
http://www.spinics.net/lists/arm-kernel/msg478167.html
http://www.spinics.net/lists/arm-kernel/msg478169.html
I like neither, we need the lesser of two evils though.
Lorenzo
> > + if (ACPI_FAILURE(status) && status != AE_NOT_FOUND)
> > + dev_err(&acpi_dev->dev, "can't evaluate _SEG\n");
> > +
> > + return segment;
> > +}
> > +
> > static void negotiate_os_control(struct acpi_pci_root *root, int *no_aspm)
> > {
> > u32 support, control, requested;
> > diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
> > index 25e0327..1a74e87 100644
> > --- a/drivers/pci/pci.c
> > +++ b/drivers/pci/pci.c
> > @@ -19,6 +19,7 @@
> > #include <linux/spinlock.h>
> > #include <linux/string.h>
> > #include <linux/log2.h>
> > +#include <linux/pci-acpi.h>
> > #include <linux/pci-aspm.h>
> > #include <linux/pm_wakeup.h>
> > #include <linux/interrupt.h>
> > @@ -4779,7 +4780,7 @@ int pci_get_new_domain_nr(void)
> > }
> >
> > #ifdef CONFIG_PCI_DOMAINS_GENERIC
> > -void pci_bus_assign_domain_nr(struct pci_bus *bus, struct device *parent)
> > +static int of_pci_bus_domain_nr(struct device *parent)
> > {
> > static int use_dt_domains = -1;
> > int domain = -1;
> > @@ -4823,7 +4824,13 @@ void pci_bus_assign_domain_nr(struct pci_bus *bus, struct device *parent)
> > domain = -1;
> > }
> >
> > - bus->domain_nr = domain;
> > + return domain;
> > +}
> > +
> > +void pci_bus_assign_domain_nr(struct pci_bus *bus, struct device *parent)
> > +{
> > + bus->domain_nr = acpi_disabled ? of_pci_bus_domain_nr(parent) :
> > + acpi_pci_bus_domain_nr(parent);
> > }
> > #endif
> > #endif
> > diff --git a/include/linux/pci-acpi.h b/include/linux/pci-acpi.h
> > index 89ab057..a72e22d 100644
> > --- a/include/linux/pci-acpi.h
> > +++ b/include/linux/pci-acpi.h
> > @@ -22,6 +22,7 @@ static inline acpi_status pci_acpi_remove_pm_notifier(struct acpi_device *dev)
> > {
> > return acpi_remove_pm_notifier(dev);
> > }
> > +extern int acpi_pci_bus_domain_nr(struct device *parent);
> > extern phys_addr_t acpi_pci_root_get_mcfg_addr(acpi_handle handle);
> >
> > static inline acpi_handle acpi_find_root_bridge_handle(struct pci_dev *pdev)
> > @@ -109,6 +110,7 @@ extern const u8 pci_acpi_dsm_uuid[];
> > #else /* CONFIG_ACPI */
> > static inline void acpi_pci_add_bus(struct pci_bus *bus) { }
> > static inline void acpi_pci_remove_bus(struct pci_bus *bus) { }
> > +static inline int acpi_pci_bus_domain_nr(struct device *parent) { return -1; }
> > #endif /* CONFIG_ACPI */
> >
> > #ifdef CONFIG_ACPI_APEI
> > --
> > 1.9.1
> >
> > --
> > To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
> > the body of a message to majordomo@vger.kernel.org
> > More majordomo info at http://vger.kernel.org/majordomo-info.html
>
[toc] | [prev] | [next] | [standalone]
| From | Bjorn Helgaas <helgaas@kernel.org> |
|---|---|
| Date | 2016-04-27 18:50 +0200 |
| Subject | Re: [PATCH V6 02/13] pci, acpi: Provide generic way to assign bus domain number. |
| Message-ID | <rsAP0-4gK-13@gated-at.bofh.it> |
| In reply to | #1388912 |
On Wed, Apr 27, 2016 at 12:17:58PM +0100, Lorenzo Pieralisi wrote:
> On Tue, Apr 26, 2016 at 09:26:49PM -0500, Bjorn Helgaas wrote:
> > On Fri, Apr 15, 2016 at 07:06:37PM +0200, Tomasz Nowicki wrote:
> > > As we now have valid PCI host bridge device reference we can
> > > introduce code that is going to find its bus domain number using
> > > ACPI _SEG method.
> > >
> > > Note that _SEG method is optional, therefore _SEG absence means
> > > that all PCI buses belong to domain 0.
> > >
> > > While at it, for the sake of code clarity we put ACPI and DT domain
> > > assign methods into the corresponding helpers.
> > >
> > > Signed-off-by: Tomasz Nowicki <tn@semihalf.com>
> > > Reviewed-by: Liviu Dudau <Liviu.Dudau@arm.com>
> > > Tested-by: Suravee Suthikulpanit <Suravee.Suthikulpanit@amd.com>
> > > Tested-by: Jeremy Linton <jeremy.linton@arm.com>
> > > Tested-by: Duc Dang <dhdang@apm.com>
> > > Tested-by: Dongdong Liu <liudongdong3@huawei.com>
> > > Tested-by: Hanjun Guo <hanjun.guo@linaro.org>
> > > Tested-by: Graeme Gregory <graeme.gregory@linaro.org>
> > > Tested-by: Sinan Kaya <okaya@codeaurora.org>
> > > ---
> > > drivers/acpi/pci_root.c | 18 ++++++++++++++++++
> > > drivers/pci/pci.c | 11 +++++++++--
> > > include/linux/pci-acpi.h | 2 ++
> > > 3 files changed, 29 insertions(+), 2 deletions(-)
> > >
> > > diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
> > > index 4581e0e..d9a70c4 100644
> > > --- a/drivers/acpi/pci_root.c
> > > +++ b/drivers/acpi/pci_root.c
> > > @@ -419,6 +419,24 @@ out:
> > > }
> > > EXPORT_SYMBOL(acpi_pci_osc_control_set);
> > >
> > > +int acpi_pci_bus_domain_nr(struct device *parent)
It looks like acpi_pci_bus_domain_nr() could be under #ifdef
CONFIG_PCI_DOMAINS_GENERIC, right?
> > > +{
> > > + struct acpi_device *acpi_dev = to_acpi_device(parent);
> > > + unsigned long long segment = 0;
> > > + acpi_status status;
> > > +
> > > + /*
> > > + * If _SEG method does not exist, following ACPI spec (6.5.6)
> > > + * all PCI buses belong to domain 0.
> > > + */
> > > + status = acpi_evaluate_integer(acpi_dev->handle, METHOD_NAME__SEG, NULL,
> > > + &segment);
> >
> > We already have code in acpi_pci_root_add() to evaluate _SEG. We
> > don't want to evaluate it *twice*, do we?
> >
> > I was sort of expecting that if you added it here, we'd remove the
> > existing call, but it looks like you're keeping both?
>
> We can't remove the existing call, since it is used on X86 and IA64
> to store the segment number that, in the process, is used in their
> pci_domain_nr() arch specific callback to retrieve the domain nr.
>
> On ARM64, that selects PCI_DOMAINS_GENERIC, we have to find a way
> to retrieve the domain number that is not arch dependent, since
> this is generic code, we can't rely on any bus->sysdata format (unless
> we do something like JC did below), therefore the only way is to call
> the _SEG method *again* here, which also forced Tomasz to go through
> the ACPI_COMPANION setting song and dance and pass the parent pointer
> to pci_create_root_bus() (see patch 1), which BTW is a source of
> trouble on its own as you noticed.
>
> JC solved it differently, via sysdata and pseudo-generic code:
>
> http://www.spinics.net/lists/arm-kernel/msg478167.html
The thing I don't like about this is the special case of checking
parent and parent->of_node to figure out whether we should use the
segment from ACPI and the fragility of depending on the fact that the
companion hasn't been set yet.
> http://www.spinics.net/lists/arm-kernel/msg478169.html
>
> I like neither, we need the lesser of two evils though.
Today we call pci_bus_assign_domain_nr() from the PCI core (from
pci_create_root_bus()). This is only implemented for
PCI_DOMAINS_GENERIC, but even so, it fiddles around to figure out
whether to get the domain from DT or to assign a new one.
That seems backwards to me. The host bridge drivers already know
where the domain should come from (ACPI _SEG, DT, etc.) and in the
long term, I think they should be responsible for looking up or
assigning a domain number *before* they call pci_create_root_bus().
> > > + if (ACPI_FAILURE(status) && status != AE_NOT_FOUND)
> > > + dev_err(&acpi_dev->dev, "can't evaluate _SEG\n");
> > > +
> > > + return segment;
> > > +}
> > > +
> > > static void negotiate_os_control(struct acpi_pci_root *root, int *no_aspm)
> > > {
> > > u32 support, control, requested;
> > > diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
> > > index 25e0327..1a74e87 100644
> > > --- a/drivers/pci/pci.c
> > > +++ b/drivers/pci/pci.c
> > > @@ -19,6 +19,7 @@
> > > #include <linux/spinlock.h>
> > > #include <linux/string.h>
> > > #include <linux/log2.h>
> > > +#include <linux/pci-acpi.h>
> > > #include <linux/pci-aspm.h>
> > > #include <linux/pm_wakeup.h>
> > > #include <linux/interrupt.h>
> > > @@ -4779,7 +4780,7 @@ int pci_get_new_domain_nr(void)
> > > }
> > >
> > > #ifdef CONFIG_PCI_DOMAINS_GENERIC
> > > -void pci_bus_assign_domain_nr(struct pci_bus *bus, struct device *parent)
> > > +static int of_pci_bus_domain_nr(struct device *parent)
> > > {
> > > static int use_dt_domains = -1;
> > > int domain = -1;
> > > @@ -4823,7 +4824,13 @@ void pci_bus_assign_domain_nr(struct pci_bus *bus, struct device *parent)
> > > domain = -1;
> > > }
> > >
> > > - bus->domain_nr = domain;
> > > + return domain;
> > > +}
> > > +
> > > +void pci_bus_assign_domain_nr(struct pci_bus *bus, struct device *parent)
> > > +{
> > > + bus->domain_nr = acpi_disabled ? of_pci_bus_domain_nr(parent) :
> > > + acpi_pci_bus_domain_nr(parent);
We have the pci_bus * here, so to_pci_host_bridge(bus->bridge) gives
us the struct pci_host_bridge. I can't remember why we put domain_nr
in the struct pci_bus instead of in the struct pci_host_bridge. It
seems like pci_host_bridge is the more logical place for it, because
every bus below the host bridge must have the same domain by
definition.
Would it be feasible to either (a) move domain_nr to the
pci_host_bridge, or (b) change acpi_pci_bus_domain_nr() so it uses the
struct pci_bus * or the struct device * to find the struct
acpi_pci_root where segment has already been stored by
acpi_pci_root_add()?
Another wrinkle is the quirk added by 1f09b09b4de0 ("x86/PCI: Ignore
_SEG on HP xw9300"). x86 doesn't use PCI_DOMAINS_GENERIC yet, so this
patch wouldn't break it, but I hope x86 can use PCI_DOMAINS_GENERIC in
the future, and then it will be a problem if we evaluate _SEG again.
> > > }
> > > #endif
> > > #endif
> > > diff --git a/include/linux/pci-acpi.h b/include/linux/pci-acpi.h
> > > index 89ab057..a72e22d 100644
> > > --- a/include/linux/pci-acpi.h
> > > +++ b/include/linux/pci-acpi.h
> > > @@ -22,6 +22,7 @@ static inline acpi_status pci_acpi_remove_pm_notifier(struct acpi_device *dev)
> > > {
> > > return acpi_remove_pm_notifier(dev);
> > > }
> > > +extern int acpi_pci_bus_domain_nr(struct device *parent);
> > > extern phys_addr_t acpi_pci_root_get_mcfg_addr(acpi_handle handle);
> > >
> > > static inline acpi_handle acpi_find_root_bridge_handle(struct pci_dev *pdev)
> > > @@ -109,6 +110,7 @@ extern const u8 pci_acpi_dsm_uuid[];
> > > #else /* CONFIG_ACPI */
> > > static inline void acpi_pci_add_bus(struct pci_bus *bus) { }
> > > static inline void acpi_pci_remove_bus(struct pci_bus *bus) { }
> > > +static inline int acpi_pci_bus_domain_nr(struct device *parent) { return -1; }
> > > #endif /* CONFIG_ACPI */
> > >
> > > #ifdef CONFIG_ACPI_APEI
> > > --
> > > 1.9.1
> > >
> > > --
> > > To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
> > > the body of a message to majordomo@vger.kernel.org
> > > More majordomo info at http://vger.kernel.org/majordomo-info.html
> >
[toc] | [prev] | [next] | [standalone]
| From | Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> |
|---|---|
| Date | 2016-04-27 19:40 +0200 |
| Subject | Re: [PATCH V6 02/13] pci, acpi: Provide generic way to assign bus domain number. |
| Message-ID | <rsBBo-53U-9@gated-at.bofh.it> |
| In reply to | #1389363 |
On Wed, Apr 27, 2016 at 11:44:53AM -0500, Bjorn Helgaas wrote:
> On Wed, Apr 27, 2016 at 12:17:58PM +0100, Lorenzo Pieralisi wrote:
> > On Tue, Apr 26, 2016 at 09:26:49PM -0500, Bjorn Helgaas wrote:
> > > On Fri, Apr 15, 2016 at 07:06:37PM +0200, Tomasz Nowicki wrote:
> > > > As we now have valid PCI host bridge device reference we can
> > > > introduce code that is going to find its bus domain number using
> > > > ACPI _SEG method.
> > > >
> > > > Note that _SEG method is optional, therefore _SEG absence means
> > > > that all PCI buses belong to domain 0.
> > > >
> > > > While at it, for the sake of code clarity we put ACPI and DT domain
> > > > assign methods into the corresponding helpers.
> > > >
> > > > Signed-off-by: Tomasz Nowicki <tn@semihalf.com>
> > > > Reviewed-by: Liviu Dudau <Liviu.Dudau@arm.com>
> > > > Tested-by: Suravee Suthikulpanit <Suravee.Suthikulpanit@amd.com>
> > > > Tested-by: Jeremy Linton <jeremy.linton@arm.com>
> > > > Tested-by: Duc Dang <dhdang@apm.com>
> > > > Tested-by: Dongdong Liu <liudongdong3@huawei.com>
> > > > Tested-by: Hanjun Guo <hanjun.guo@linaro.org>
> > > > Tested-by: Graeme Gregory <graeme.gregory@linaro.org>
> > > > Tested-by: Sinan Kaya <okaya@codeaurora.org>
> > > > ---
> > > > drivers/acpi/pci_root.c | 18 ++++++++++++++++++
> > > > drivers/pci/pci.c | 11 +++++++++--
> > > > include/linux/pci-acpi.h | 2 ++
> > > > 3 files changed, 29 insertions(+), 2 deletions(-)
> > > >
> > > > diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
> > > > index 4581e0e..d9a70c4 100644
> > > > --- a/drivers/acpi/pci_root.c
> > > > +++ b/drivers/acpi/pci_root.c
> > > > @@ -419,6 +419,24 @@ out:
> > > > }
> > > > EXPORT_SYMBOL(acpi_pci_osc_control_set);
> > > >
> > > > +int acpi_pci_bus_domain_nr(struct device *parent)
>
> It looks like acpi_pci_bus_domain_nr() could be under #ifdef
> CONFIG_PCI_DOMAINS_GENERIC, right?
Yes it should.
> > > > +{
> > > > + struct acpi_device *acpi_dev = to_acpi_device(parent);
> > > > + unsigned long long segment = 0;
> > > > + acpi_status status;
> > > > +
> > > > + /*
> > > > + * If _SEG method does not exist, following ACPI spec (6.5.6)
> > > > + * all PCI buses belong to domain 0.
> > > > + */
> > > > + status = acpi_evaluate_integer(acpi_dev->handle, METHOD_NAME__SEG, NULL,
> > > > + &segment);
> > >
> > > We already have code in acpi_pci_root_add() to evaluate _SEG. We
> > > don't want to evaluate it *twice*, do we?
> > >
> > > I was sort of expecting that if you added it here, we'd remove the
> > > existing call, but it looks like you're keeping both?
> >
> > We can't remove the existing call, since it is used on X86 and IA64
> > to store the segment number that, in the process, is used in their
> > pci_domain_nr() arch specific callback to retrieve the domain nr.
> >
> > On ARM64, that selects PCI_DOMAINS_GENERIC, we have to find a way
> > to retrieve the domain number that is not arch dependent, since
> > this is generic code, we can't rely on any bus->sysdata format (unless
> > we do something like JC did below), therefore the only way is to call
> > the _SEG method *again* here, which also forced Tomasz to go through
> > the ACPI_COMPANION setting song and dance and pass the parent pointer
> > to pci_create_root_bus() (see patch 1), which BTW is a source of
> > trouble on its own as you noticed.
> >
> > JC solved it differently, via sysdata and pseudo-generic code:
> >
> > http://www.spinics.net/lists/arm-kernel/msg478167.html
>
> The thing I don't like about this is the special case of checking
> parent and parent->of_node to figure out whether we should use the
> segment from ACPI and the fragility of depending on the fact that the
> companion hasn't been set yet.
>
> > http://www.spinics.net/lists/arm-kernel/msg478169.html
> >
> > I like neither, we need the lesser of two evils though.
>
> Today we call pci_bus_assign_domain_nr() from the PCI core (from
> pci_create_root_bus()). This is only implemented for
> PCI_DOMAINS_GENERIC, but even so, it fiddles around to figure out
> whether to get the domain from DT or to assign a new one.
>
> That seems backwards to me. The host bridge drivers already know
> where the domain should come from (ACPI _SEG, DT, etc.) and in the
> long term, I think they should be responsible for looking up or
> assigning a domain number *before* they call pci_create_root_bus().
Yes, the question still is how pci_create_root_bus() can get that
value (I am pretty certain this was heavily debated in the past, which
does not mean we can't give it another try).
> > > > + if (ACPI_FAILURE(status) && status != AE_NOT_FOUND)
> > > > + dev_err(&acpi_dev->dev, "can't evaluate _SEG\n");
> > > > +
> > > > + return segment;
> > > > +}
> > > > +
> > > > static void negotiate_os_control(struct acpi_pci_root *root, int *no_aspm)
> > > > {
> > > > u32 support, control, requested;
> > > > diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
> > > > index 25e0327..1a74e87 100644
> > > > --- a/drivers/pci/pci.c
> > > > +++ b/drivers/pci/pci.c
> > > > @@ -19,6 +19,7 @@
> > > > #include <linux/spinlock.h>
> > > > #include <linux/string.h>
> > > > #include <linux/log2.h>
> > > > +#include <linux/pci-acpi.h>
> > > > #include <linux/pci-aspm.h>
> > > > #include <linux/pm_wakeup.h>
> > > > #include <linux/interrupt.h>
> > > > @@ -4779,7 +4780,7 @@ int pci_get_new_domain_nr(void)
> > > > }
> > > >
> > > > #ifdef CONFIG_PCI_DOMAINS_GENERIC
> > > > -void pci_bus_assign_domain_nr(struct pci_bus *bus, struct device *parent)
> > > > +static int of_pci_bus_domain_nr(struct device *parent)
> > > > {
> > > > static int use_dt_domains = -1;
> > > > int domain = -1;
> > > > @@ -4823,7 +4824,13 @@ void pci_bus_assign_domain_nr(struct pci_bus *bus, struct device *parent)
> > > > domain = -1;
> > > > }
> > > >
> > > > - bus->domain_nr = domain;
> > > > + return domain;
> > > > +}
> > > > +
> > > > +void pci_bus_assign_domain_nr(struct pci_bus *bus, struct device *parent)
> > > > +{
> > > > + bus->domain_nr = acpi_disabled ? of_pci_bus_domain_nr(parent) :
> > > > + acpi_pci_bus_domain_nr(parent);
>
> We have the pci_bus * here, so to_pci_host_bridge(bus->bridge) gives
> us the struct pci_host_bridge. I can't remember why we put domain_nr
> in the struct pci_bus instead of in the struct pci_host_bridge. It
> seems like pci_host_bridge is the more logical place for it, because
> every bus below the host bridge must have the same domain by
> definition.
>
> Would it be feasible to either (a) move domain_nr to the
> pci_host_bridge, or (b) change acpi_pci_bus_domain_nr() so it uses the
> struct pci_bus * or the struct device * to find the struct
> acpi_pci_root where segment has already been stored by
> acpi_pci_root_add()?
(b) is what JC implemented even though it works differently for
different hosts since it all depends on what's in bus->sysdata.
It can certainly be done in a generic way (that works on X86 and IA64
too), let's give it more thought.
> Another wrinkle is the quirk added by 1f09b09b4de0 ("x86/PCI: Ignore
> _SEG on HP xw9300"). x86 doesn't use PCI_DOMAINS_GENERIC yet, so this
> patch wouldn't break it, but I hope x86 can use PCI_DOMAINS_GENERIC in
> the future, and then it will be a problem if we evaluate _SEG again.
Yes, I share your concern here and I thought about that, if that's the
end goal let's find a solution that works across arches (or we temporarily
use JC's code and we then generalize it).
Thanks,
Lorenzo
>
> > > > }
> > > > #endif
> > > > #endif
> > > > diff --git a/include/linux/pci-acpi.h b/include/linux/pci-acpi.h
> > > > index 89ab057..a72e22d 100644
> > > > --- a/include/linux/pci-acpi.h
> > > > +++ b/include/linux/pci-acpi.h
> > > > @@ -22,6 +22,7 @@ static inline acpi_status pci_acpi_remove_pm_notifier(struct acpi_device *dev)
> > > > {
> > > > return acpi_remove_pm_notifier(dev);
> > > > }
> > > > +extern int acpi_pci_bus_domain_nr(struct device *parent);
> > > > extern phys_addr_t acpi_pci_root_get_mcfg_addr(acpi_handle handle);
> > > >
> > > > static inline acpi_handle acpi_find_root_bridge_handle(struct pci_dev *pdev)
> > > > @@ -109,6 +110,7 @@ extern const u8 pci_acpi_dsm_uuid[];
> > > > #else /* CONFIG_ACPI */
> > > > static inline void acpi_pci_add_bus(struct pci_bus *bus) { }
> > > > static inline void acpi_pci_remove_bus(struct pci_bus *bus) { }
> > > > +static inline int acpi_pci_bus_domain_nr(struct device *parent) { return -1; }
> > > > #endif /* CONFIG_ACPI */
> > > >
> > > > #ifdef CONFIG_ACPI_APEI
> > > > --
> > > > 1.9.1
> > > >
> > > > --
> > > > To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
> > > > the body of a message to majordomo@vger.kernel.org
> > > > More majordomo info at http://vger.kernel.org/majordomo-info.html
> > >
>
[toc] | [prev] | [next] | [standalone]
| From | Liviu.Dudau@arm.com |
|---|---|
| Date | 2016-04-28 10:20 +0200 |
| Subject | Re: [PATCH V6 02/13] pci, acpi: Provide generic way to assign bus domain number. |
| Message-ID | <rsPkZ-8pu-1@gated-at.bofh.it> |
| In reply to | #1389405 |
On Wed, Apr 27, 2016 at 06:31:29PM +0100, Lorenzo Pieralisi wrote:
> On Wed, Apr 27, 2016 at 11:44:53AM -0500, Bjorn Helgaas wrote:
> > On Wed, Apr 27, 2016 at 12:17:58PM +0100, Lorenzo Pieralisi wrote:
> > > On Tue, Apr 26, 2016 at 09:26:49PM -0500, Bjorn Helgaas wrote:
> > > > On Fri, Apr 15, 2016 at 07:06:37PM +0200, Tomasz Nowicki wrote:
> > > > > As we now have valid PCI host bridge device reference we can
> > > > > introduce code that is going to find its bus domain number using
> > > > > ACPI _SEG method.
> > > > >
> > > > > Note that _SEG method is optional, therefore _SEG absence means
> > > > > that all PCI buses belong to domain 0.
> > > > >
> > > > > While at it, for the sake of code clarity we put ACPI and DT domain
> > > > > assign methods into the corresponding helpers.
> > > > >
> > > > > Signed-off-by: Tomasz Nowicki <tn@semihalf.com>
> > > > > Reviewed-by: Liviu Dudau <Liviu.Dudau@arm.com>
> > > > > Tested-by: Suravee Suthikulpanit <Suravee.Suthikulpanit@amd.com>
> > > > > Tested-by: Jeremy Linton <jeremy.linton@arm.com>
> > > > > Tested-by: Duc Dang <dhdang@apm.com>
> > > > > Tested-by: Dongdong Liu <liudongdong3@huawei.com>
> > > > > Tested-by: Hanjun Guo <hanjun.guo@linaro.org>
> > > > > Tested-by: Graeme Gregory <graeme.gregory@linaro.org>
> > > > > Tested-by: Sinan Kaya <okaya@codeaurora.org>
> > > > > ---
> > > > > drivers/acpi/pci_root.c | 18 ++++++++++++++++++
> > > > > drivers/pci/pci.c | 11 +++++++++--
> > > > > include/linux/pci-acpi.h | 2 ++
> > > > > 3 files changed, 29 insertions(+), 2 deletions(-)
> > > > >
> > > > > diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
> > > > > index 4581e0e..d9a70c4 100644
> > > > > --- a/drivers/acpi/pci_root.c
> > > > > +++ b/drivers/acpi/pci_root.c
> > > > > @@ -419,6 +419,24 @@ out:
> > > > > }
> > > > > EXPORT_SYMBOL(acpi_pci_osc_control_set);
> > > > >
> > > > > +int acpi_pci_bus_domain_nr(struct device *parent)
> >
> > It looks like acpi_pci_bus_domain_nr() could be under #ifdef
> > CONFIG_PCI_DOMAINS_GENERIC, right?
>
> Yes it should.
>
> > > > > +{
> > > > > + struct acpi_device *acpi_dev = to_acpi_device(parent);
> > > > > + unsigned long long segment = 0;
> > > > > + acpi_status status;
> > > > > +
> > > > > + /*
> > > > > + * If _SEG method does not exist, following ACPI spec (6.5.6)
> > > > > + * all PCI buses belong to domain 0.
> > > > > + */
> > > > > + status = acpi_evaluate_integer(acpi_dev->handle, METHOD_NAME__SEG, NULL,
> > > > > + &segment);
> > > >
> > > > We already have code in acpi_pci_root_add() to evaluate _SEG. We
> > > > don't want to evaluate it *twice*, do we?
> > > >
> > > > I was sort of expecting that if you added it here, we'd remove the
> > > > existing call, but it looks like you're keeping both?
> > >
> > > We can't remove the existing call, since it is used on X86 and IA64
> > > to store the segment number that, in the process, is used in their
> > > pci_domain_nr() arch specific callback to retrieve the domain nr.
> > >
> > > On ARM64, that selects PCI_DOMAINS_GENERIC, we have to find a way
> > > to retrieve the domain number that is not arch dependent, since
> > > this is generic code, we can't rely on any bus->sysdata format (unless
> > > we do something like JC did below), therefore the only way is to call
> > > the _SEG method *again* here, which also forced Tomasz to go through
> > > the ACPI_COMPANION setting song and dance and pass the parent pointer
> > > to pci_create_root_bus() (see patch 1), which BTW is a source of
> > > trouble on its own as you noticed.
> > >
> > > JC solved it differently, via sysdata and pseudo-generic code:
> > >
> > > http://www.spinics.net/lists/arm-kernel/msg478167.html
> >
> > The thing I don't like about this is the special case of checking
> > parent and parent->of_node to figure out whether we should use the
> > segment from ACPI and the fragility of depending on the fact that the
> > companion hasn't been set yet.
> >
> > > http://www.spinics.net/lists/arm-kernel/msg478169.html
> > >
> > > I like neither, we need the lesser of two evils though.
> >
> > Today we call pci_bus_assign_domain_nr() from the PCI core (from
> > pci_create_root_bus()). This is only implemented for
> > PCI_DOMAINS_GENERIC, but even so, it fiddles around to figure out
> > whether to get the domain from DT or to assign a new one.
> >
> > That seems backwards to me. The host bridge drivers already know
> > where the domain should come from (ACPI _SEG, DT, etc.) and in the
> > long term, I think they should be responsible for looking up or
> > assigning a domain number *before* they call pci_create_root_bus().
>
> Yes, the question still is how pci_create_root_bus() can get that
> value (I am pretty certain this was heavily debated in the past, which
> does not mean we can't give it another try).
The main issue is that pci_create_root_bus() does a weird dance trying to
figure out if the root bus hasn't been already allocated. It allocates a
new bus, assigns a domain number and then it tries to find it in the list
of already allocated busses. Because pci_alloc_bus() does not pass any
additional information, pci_bus_assign_domain_nr() needs to try to guess
where the barely initialised bus should live and give you back a number.
Simplifying the creation of root busses to be the job of the host bridges
would greatly simplify the code as well.
Best regards,
Liviu
>
> > > > > + if (ACPI_FAILURE(status) && status != AE_NOT_FOUND)
> > > > > + dev_err(&acpi_dev->dev, "can't evaluate _SEG\n");
> > > > > +
> > > > > + return segment;
> > > > > +}
> > > > > +
> > > > > static void negotiate_os_control(struct acpi_pci_root *root, int *no_aspm)
> > > > > {
> > > > > u32 support, control, requested;
> > > > > diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
> > > > > index 25e0327..1a74e87 100644
> > > > > --- a/drivers/pci/pci.c
> > > > > +++ b/drivers/pci/pci.c
> > > > > @@ -19,6 +19,7 @@
> > > > > #include <linux/spinlock.h>
> > > > > #include <linux/string.h>
> > > > > #include <linux/log2.h>
> > > > > +#include <linux/pci-acpi.h>
> > > > > #include <linux/pci-aspm.h>
> > > > > #include <linux/pm_wakeup.h>
> > > > > #include <linux/interrupt.h>
> > > > > @@ -4779,7 +4780,7 @@ int pci_get_new_domain_nr(void)
> > > > > }
> > > > >
> > > > > #ifdef CONFIG_PCI_DOMAINS_GENERIC
> > > > > -void pci_bus_assign_domain_nr(struct pci_bus *bus, struct device *parent)
> > > > > +static int of_pci_bus_domain_nr(struct device *parent)
> > > > > {
> > > > > static int use_dt_domains = -1;
> > > > > int domain = -1;
> > > > > @@ -4823,7 +4824,13 @@ void pci_bus_assign_domain_nr(struct pci_bus *bus, struct device *parent)
> > > > > domain = -1;
> > > > > }
> > > > >
> > > > > - bus->domain_nr = domain;
> > > > > + return domain;
> > > > > +}
> > > > > +
> > > > > +void pci_bus_assign_domain_nr(struct pci_bus *bus, struct device *parent)
> > > > > +{
> > > > > + bus->domain_nr = acpi_disabled ? of_pci_bus_domain_nr(parent) :
> > > > > + acpi_pci_bus_domain_nr(parent);
> >
> > We have the pci_bus * here, so to_pci_host_bridge(bus->bridge) gives
> > us the struct pci_host_bridge. I can't remember why we put domain_nr
> > in the struct pci_bus instead of in the struct pci_host_bridge. It
> > seems like pci_host_bridge is the more logical place for it, because
> > every bus below the host bridge must have the same domain by
> > definition.
> >
> > Would it be feasible to either (a) move domain_nr to the
> > pci_host_bridge, or (b) change acpi_pci_bus_domain_nr() so it uses the
> > struct pci_bus * or the struct device * to find the struct
> > acpi_pci_root where segment has already been stored by
> > acpi_pci_root_add()?
>
> (b) is what JC implemented even though it works differently for
> different hosts since it all depends on what's in bus->sysdata.
>
> It can certainly be done in a generic way (that works on X86 and IA64
> too), let's give it more thought.
>
> > Another wrinkle is the quirk added by 1f09b09b4de0 ("x86/PCI: Ignore
> > _SEG on HP xw9300"). x86 doesn't use PCI_DOMAINS_GENERIC yet, so this
> > patch wouldn't break it, but I hope x86 can use PCI_DOMAINS_GENERIC in
> > the future, and then it will be a problem if we evaluate _SEG again.
>
> Yes, I share your concern here and I thought about that, if that's the
> end goal let's find a solution that works across arches (or we temporarily
> use JC's code and we then generalize it).
>
> Thanks,
> Lorenzo
>
> >
> > > > > }
> > > > > #endif
> > > > > #endif
> > > > > diff --git a/include/linux/pci-acpi.h b/include/linux/pci-acpi.h
> > > > > index 89ab057..a72e22d 100644
> > > > > --- a/include/linux/pci-acpi.h
> > > > > +++ b/include/linux/pci-acpi.h
> > > > > @@ -22,6 +22,7 @@ static inline acpi_status pci_acpi_remove_pm_notifier(struct acpi_device *dev)
> > > > > {
> > > > > return acpi_remove_pm_notifier(dev);
> > > > > }
> > > > > +extern int acpi_pci_bus_domain_nr(struct device *parent);
> > > > > extern phys_addr_t acpi_pci_root_get_mcfg_addr(acpi_handle handle);
> > > > >
> > > > > static inline acpi_handle acpi_find_root_bridge_handle(struct pci_dev *pdev)
> > > > > @@ -109,6 +110,7 @@ extern const u8 pci_acpi_dsm_uuid[];
> > > > > #else /* CONFIG_ACPI */
> > > > > static inline void acpi_pci_add_bus(struct pci_bus *bus) { }
> > > > > static inline void acpi_pci_remove_bus(struct pci_bus *bus) { }
> > > > > +static inline int acpi_pci_bus_domain_nr(struct device *parent) { return -1; }
> > > > > #endif /* CONFIG_ACPI */
> > > > >
> > > > > #ifdef CONFIG_ACPI_APEI
> > > > > --
> > > > > 1.9.1
> > > > >
> > > > > --
> > > > > To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
> > > > > the body of a message to majordomo@vger.kernel.org
> > > > > More majordomo info at http://vger.kernel.org/majordomo-info.html
> > > >
> >
>
--
====================
| I would like to |
| fix the world, |
| but they're not |
| giving me the |
\ source code! /
---------------
¯\_(ツ)_/¯
[toc] | [prev] | [next] | [standalone]
| From | Tomasz Nowicki <tn@semihalf.com> |
|---|---|
| Date | 2016-04-27 14:10 +0200 |
| Subject | Re: [PATCH V6 02/13] pci, acpi: Provide generic way to assign bus domain number. |
| Message-ID | <rsws2-11E-11@gated-at.bofh.it> |
| In reply to | #1388598 |
On 27.04.2016 04:26, Bjorn Helgaas wrote:
> On Fri, Apr 15, 2016 at 07:06:37PM +0200, Tomasz Nowicki wrote:
>> As we now have valid PCI host bridge device reference we can
>> introduce code that is going to find its bus domain number using
>> ACPI _SEG method.
>>
>> Note that _SEG method is optional, therefore _SEG absence means
>> that all PCI buses belong to domain 0.
>>
>> While at it, for the sake of code clarity we put ACPI and DT domain
>> assign methods into the corresponding helpers.
>>
>> Signed-off-by: Tomasz Nowicki <tn@semihalf.com>
>> Reviewed-by: Liviu Dudau <Liviu.Dudau@arm.com>
>> Tested-by: Suravee Suthikulpanit <Suravee.Suthikulpanit@amd.com>
>> Tested-by: Jeremy Linton <jeremy.linton@arm.com>
>> Tested-by: Duc Dang <dhdang@apm.com>
>> Tested-by: Dongdong Liu <liudongdong3@huawei.com>
>> Tested-by: Hanjun Guo <hanjun.guo@linaro.org>
>> Tested-by: Graeme Gregory <graeme.gregory@linaro.org>
>> Tested-by: Sinan Kaya <okaya@codeaurora.org>
>> ---
>> drivers/acpi/pci_root.c | 18 ++++++++++++++++++
>> drivers/pci/pci.c | 11 +++++++++--
>> include/linux/pci-acpi.h | 2 ++
>> 3 files changed, 29 insertions(+), 2 deletions(-)
>>
>> diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
>> index 4581e0e..d9a70c4 100644
>> --- a/drivers/acpi/pci_root.c
>> +++ b/drivers/acpi/pci_root.c
>> @@ -419,6 +419,24 @@ out:
>> }
>> EXPORT_SYMBOL(acpi_pci_osc_control_set);
>>
>> +int acpi_pci_bus_domain_nr(struct device *parent)
>> +{
>> + struct acpi_device *acpi_dev = to_acpi_device(parent);
>> + unsigned long long segment = 0;
>> + acpi_status status;
>> +
>> + /*
>> + * If _SEG method does not exist, following ACPI spec (6.5.6)
>> + * all PCI buses belong to domain 0.
>> + */
>> + status = acpi_evaluate_integer(acpi_dev->handle, METHOD_NAME__SEG, NULL,
>> + &segment);
>
> We already have code in acpi_pci_root_add() to evaluate _SEG. We
> don't want to evaluate it *twice*, do we?
Ideally we do not want.
The main intention here was to avoid using "void *sysdata" to retrieve
domain number. sysdata means something different for each architectures.
This would be common way for all arch using PCI_DOMAINS_GENERIC option
such as ARM64.
>
> I was sort of expecting that if you added it here, we'd remove the
> existing call, but it looks like you're keeping both?
I leave _SEG evaluation in acpi_pci_root_add to keep support for IA64
and x86 which are still using arch-specific sysdata (struct
pci_sysdata->domain for x86 and struct pci_controller->segment for IA64)
to retrieve domain number.
ARM64 uses PCI_DOMAINS_GENERIC for DT boot method, it would be
consistent to keep it for ACPI too.
I am open to suggestions, do you think we should use sysdata for ARM64?
Thanks,
Tomasz
[toc] | [prev] | [next] | [standalone]
| From | Tomasz Nowicki <tn@semihalf.com> |
|---|---|
| Date | 2016-04-15 19:10 +0200 |
| Subject | [PATCH V6 12/13] pci, pci-thunder-ecam: Add ACPI support for ThunderX ECAM. |
| Message-ID | <rofpM-6tr-25@gated-at.bofh.it> |
| In reply to | #1380019 |
Passes 1.x miss PCI enhanced allocation (EA) header for fixed-BARs,
thus these passes should use Cavium-specific config access functions
that synthesize the missing EA capabilities.
We already have DT driver which addresses errata requirements and
allows to use special PCI config accessors. Currently this driver uses
compatible = "cavium,pci-host-thunder-ecam" to mach against the errata.
For ACPI case we need explicit errata number and corresponding
DECLARE_ACPI_MCFG_FIXUP fixup code.
Signed-off-by: Tomasz Nowicki <tn@semihalf.com>
---
arch/arm64/Kconfig | 14 ++++++++++++++
arch/arm64/include/asm/cpufeature.h | 3 ++-
arch/arm64/kernel/cpu_errata.c | 8 ++++++++
drivers/pci/host/pci-thunder-ecam.c | 35 +++++++++++++++++++++++++++++++++++
4 files changed, 59 insertions(+), 1 deletion(-)
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 1bded87..b7614b8 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -445,6 +445,20 @@ config CAVIUM_ERRATUM_27456
If unsure, say Y.
+config CAVIUM_ERRATUM_24575
+ bool "Cavium erratum 24575: Enhanced Allocation (EA) emualaion"
+ default y
+ help
+ Enable workaround for erratum 24575.
+
+ Early versions of the Cavium Thunder CN88XX processor are missing
+ Enhanced Allocation (EA) capabilities for the fixed BAR addresses used
+ by the on-SoC hardware blocks. The erratum adds config access
+ functions that synthesize the missing EA capabilities for versions
+ that are missing that information.
+
+ If unsure, say Y.
+
endmenu
diff --git a/arch/arm64/include/asm/cpufeature.h b/arch/arm64/include/asm/cpufeature.h
index b9b6494..a78364e 100644
--- a/arch/arm64/include/asm/cpufeature.h
+++ b/arch/arm64/include/asm/cpufeature.h
@@ -35,8 +35,9 @@
#define ARM64_ALT_PAN_NOT_UAO 10
#define ARM64_HAS_VIRT_HOST_EXTN 11
#define ARM64_WORKAROUND_CAVIUM_27456 12
+#define ARM64_WORKAROUND_CAVIUM_24575 13
-#define ARM64_NCAPS 13
+#define ARM64_NCAPS 14
#ifndef __ASSEMBLY__
diff --git a/arch/arm64/kernel/cpu_errata.c b/arch/arm64/kernel/cpu_errata.c
index 06afd04..89c13d7 100644
--- a/arch/arm64/kernel/cpu_errata.c
+++ b/arch/arm64/kernel/cpu_errata.c
@@ -97,6 +97,14 @@ const struct arm64_cpu_capabilities arm64_errata[] = {
(1 << MIDR_VARIANT_SHIFT) | 1),
},
#endif
+#ifdef CONFIG_CAVIUM_ERRATUM_24575
+ {
+ /* Cavium ThunderX, pass 1.x */
+ .desc = "Cavium erratum 24575",
+ .capability = ARM64_WORKAROUND_CAVIUM_24575,
+ MIDR_RANGE(MIDR_THUNDERX, 0x00, 0x01),
+ },
+#endif
{
}
};
diff --git a/drivers/pci/host/pci-thunder-ecam.c b/drivers/pci/host/pci-thunder-ecam.c
index f67c6d7..01de697 100644
--- a/drivers/pci/host/pci-thunder-ecam.c
+++ b/drivers/pci/host/pci-thunder-ecam.c
@@ -11,10 +11,14 @@
#include <linux/ioport.h>
#include <linux/of_pci.h>
#include <linux/of.h>
+#include <linux/pci-acpi.h>
#include <linux/platform_device.h>
+#include <asm/virt.h>
+
#include "../ecam.h"
+
static void set_val(u32 v, int where, int size, u32 *val)
{
int shift = (where & 3) * 8;
@@ -376,5 +380,36 @@ static struct platform_driver thunder_ecam_driver = {
};
module_platform_driver(thunder_ecam_driver);
+#ifdef CONFIG_ACPI
+
+static bool needs_cavium_erratum_24575(struct pci_cfg_fixup *fixup,
+ struct acpi_pci_root *root)
+{
+ /*
+ * We must match errata code and be hypervisor, quirk does not apply
+ * for virtual machines.
+ */
+ return cpus_have_cap(ARM64_WORKAROUND_CAVIUM_24575) &&
+ is_hyp_mode_available();
+}
+
+DECLARE_ACPI_MCFG_FIXUP(NULL, needs_cavium_erratum_24575, &pci_thunder_ecam_ops,
+ 0, PCI_MCFG_BUS_ANY);
+DECLARE_ACPI_MCFG_FIXUP(NULL, needs_cavium_erratum_24575, &pci_thunder_ecam_ops,
+ 1, PCI_MCFG_BUS_ANY);
+DECLARE_ACPI_MCFG_FIXUP(NULL, needs_cavium_erratum_24575, &pci_thunder_ecam_ops,
+ 2, PCI_MCFG_BUS_ANY);
+DECLARE_ACPI_MCFG_FIXUP(NULL, needs_cavium_erratum_24575, &pci_thunder_ecam_ops,
+ 3, PCI_MCFG_BUS_ANY);
+DECLARE_ACPI_MCFG_FIXUP(NULL, needs_cavium_erratum_24575, &pci_thunder_ecam_ops,
+ 10, PCI_MCFG_BUS_ANY);
+DECLARE_ACPI_MCFG_FIXUP(NULL, needs_cavium_erratum_24575, &pci_thunder_ecam_ops,
+ 11, PCI_MCFG_BUS_ANY);
+DECLARE_ACPI_MCFG_FIXUP(NULL, needs_cavium_erratum_24575, &pci_thunder_ecam_ops,
+ 12, PCI_MCFG_BUS_ANY);
+DECLARE_ACPI_MCFG_FIXUP(NULL, needs_cavium_erratum_24575, &pci_thunder_ecam_ops,
+ 13, PCI_MCFG_BUS_ANY);
+#endif
+
MODULE_DESCRIPTION("Thunder ECAM PCI host driver");
MODULE_LICENSE("GPL v2");
--
1.9.1
[toc] | [prev] | [next] | [standalone]
| From | Tomasz Nowicki <tn@semihalf.com> |
|---|---|
| Date | 2016-04-19 12:30 +0200 |
| Subject | Re: [PATCH V6 12/13] pci, pci-thunder-ecam: Add ACPI support for ThunderX ECAM. |
| Message-ID | <rpB4S-5lW-7@gated-at.bofh.it> |
| In reply to | #1380028 |
On 15.04.2016 19:06, Tomasz Nowicki wrote:
> Passes 1.x miss PCI enhanced allocation (EA) header for fixed-BARs,
> thus these passes should use Cavium-specific config access functions
> that synthesize the missing EA capabilities.
>
> We already have DT driver which addresses errata requirements and
> allows to use special PCI config accessors. Currently this driver uses
> compatible = "cavium,pci-host-thunder-ecam" to mach against the errata.
> For ACPI case we need explicit errata number and corresponding
> DECLARE_ACPI_MCFG_FIXUP fixup code.
>
> Signed-off-by: Tomasz Nowicki <tn@semihalf.com>
> ---
> arch/arm64/Kconfig | 14 ++++++++++++++
> arch/arm64/include/asm/cpufeature.h | 3 ++-
> arch/arm64/kernel/cpu_errata.c | 8 ++++++++
> drivers/pci/host/pci-thunder-ecam.c | 35 +++++++++++++++++++++++++++++++++++
> 4 files changed, 59 insertions(+), 1 deletion(-)
>
> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
> index 1bded87..b7614b8 100644
> --- a/arch/arm64/Kconfig
> +++ b/arch/arm64/Kconfig
> @@ -445,6 +445,20 @@ config CAVIUM_ERRATUM_27456
>
> If unsure, say Y.
>
> +config CAVIUM_ERRATUM_24575
> + bool "Cavium erratum 24575: Enhanced Allocation (EA) emualaion"
> + default y
> + help
> + Enable workaround for erratum 24575.
> +
> + Early versions of the Cavium Thunder CN88XX processor are missing
> + Enhanced Allocation (EA) capabilities for the fixed BAR addresses used
> + by the on-SoC hardware blocks. The erratum adds config access
> + functions that synthesize the missing EA capabilities for versions
> + that are missing that information.
> +
> + If unsure, say Y.
> +
> endmenu
>
>
> diff --git a/arch/arm64/include/asm/cpufeature.h b/arch/arm64/include/asm/cpufeature.h
> index b9b6494..a78364e 100644
> --- a/arch/arm64/include/asm/cpufeature.h
> +++ b/arch/arm64/include/asm/cpufeature.h
> @@ -35,8 +35,9 @@
> #define ARM64_ALT_PAN_NOT_UAO 10
> #define ARM64_HAS_VIRT_HOST_EXTN 11
> #define ARM64_WORKAROUND_CAVIUM_27456 12
> +#define ARM64_WORKAROUND_CAVIUM_24575 13
>
> -#define ARM64_NCAPS 13
> +#define ARM64_NCAPS 14
>
> #ifndef __ASSEMBLY__
>
> diff --git a/arch/arm64/kernel/cpu_errata.c b/arch/arm64/kernel/cpu_errata.c
> index 06afd04..89c13d7 100644
> --- a/arch/arm64/kernel/cpu_errata.c
> +++ b/arch/arm64/kernel/cpu_errata.c
> @@ -97,6 +97,14 @@ const struct arm64_cpu_capabilities arm64_errata[] = {
> (1 << MIDR_VARIANT_SHIFT) | 1),
> },
> #endif
> +#ifdef CONFIG_CAVIUM_ERRATUM_24575
> + {
> + /* Cavium ThunderX, pass 1.x */
> + .desc = "Cavium erratum 24575",
> + .capability = ARM64_WORKAROUND_CAVIUM_24575,
> + MIDR_RANGE(MIDR_THUNDERX, 0x00, 0x01),
> + },
> +#endif
> {
> }
> };
> diff --git a/drivers/pci/host/pci-thunder-ecam.c b/drivers/pci/host/pci-thunder-ecam.c
> index f67c6d7..01de697 100644
> --- a/drivers/pci/host/pci-thunder-ecam.c
> +++ b/drivers/pci/host/pci-thunder-ecam.c
> @@ -11,10 +11,14 @@
> #include <linux/ioport.h>
> #include <linux/of_pci.h>
> #include <linux/of.h>
> +#include <linux/pci-acpi.h>
> #include <linux/platform_device.h>
>
> +#include <asm/virt.h>
> +
> #include "../ecam.h"
>
> +
> static void set_val(u32 v, int where, int size, u32 *val)
> {
> int shift = (where & 3) * 8;
> @@ -376,5 +380,36 @@ static struct platform_driver thunder_ecam_driver = {
> };
> module_platform_driver(thunder_ecam_driver);
>
> +#ifdef CONFIG_ACPI
> +
> +static bool needs_cavium_erratum_24575(struct pci_cfg_fixup *fixup,
> + struct acpi_pci_root *root)
> +{
> + /*
> + * We must match errata code and be hypervisor, quirk does not apply
> + * for virtual machines.
> + */
> + return cpus_have_cap(ARM64_WORKAROUND_CAVIUM_24575) &&
> + is_hyp_mode_available();
> +}
> +
> +DECLARE_ACPI_MCFG_FIXUP(NULL, needs_cavium_erratum_24575, &pci_thunder_ecam_ops,
> + 0, PCI_MCFG_BUS_ANY);
> +DECLARE_ACPI_MCFG_FIXUP(NULL, needs_cavium_erratum_24575, &pci_thunder_ecam_ops,
> + 1, PCI_MCFG_BUS_ANY);
> +DECLARE_ACPI_MCFG_FIXUP(NULL, needs_cavium_erratum_24575, &pci_thunder_ecam_ops,
> + 2, PCI_MCFG_BUS_ANY);
> +DECLARE_ACPI_MCFG_FIXUP(NULL, needs_cavium_erratum_24575, &pci_thunder_ecam_ops,
> + 3, PCI_MCFG_BUS_ANY);
> +DECLARE_ACPI_MCFG_FIXUP(NULL, needs_cavium_erratum_24575, &pci_thunder_ecam_ops,
> + 10, PCI_MCFG_BUS_ANY);
> +DECLARE_ACPI_MCFG_FIXUP(NULL, needs_cavium_erratum_24575, &pci_thunder_ecam_ops,
> + 11, PCI_MCFG_BUS_ANY);
> +DECLARE_ACPI_MCFG_FIXUP(NULL, needs_cavium_erratum_24575, &pci_thunder_ecam_ops,
> + 12, PCI_MCFG_BUS_ANY);
> +DECLARE_ACPI_MCFG_FIXUP(NULL, needs_cavium_erratum_24575, &pci_thunder_ecam_ops,
> + 13, PCI_MCFG_BUS_ANY);
> +#endif
> +
I wonder if we can identify quirk based on _DSD properties, like that:
Name (_DSD, Package () {
ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
Package () {
Package (2) {"cavium,pci-host-thunder-ecam", 1},
}
})
similar for PEM driver:
Name (_DSD, Package () {
ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
Package () {
Package (2) {"cavium,pci-host-thunder-pem", 1},
}
})
Do you think it is right thing to do?
Tomasz
[toc] | [prev] | [next] | [standalone]
| From | G Gregory <graeme.gregory@linaro.org> |
|---|---|
| Date | 2016-04-19 12:50 +0200 |
| Subject | Re: [Linaro-acpi] [PATCH V6 12/13] pci, pci-thunder-ecam: Add ACPI support for ThunderX ECAM. |
| Message-ID | <rpBod-5vc-11@gated-at.bofh.it> |
| In reply to | #1382374 |
On 19 April 2016 at 11:26, Tomasz Nowicki <tn@semihalf.com> wrote:
> On 15.04.2016 19:06, Tomasz Nowicki wrote:
>>
>> Passes 1.x miss PCI enhanced allocation (EA) header for fixed-BARs,
>> thus these passes should use Cavium-specific config access functions
>> that synthesize the missing EA capabilities.
>>
>> We already have DT driver which addresses errata requirements and
>> allows to use special PCI config accessors. Currently this driver uses
>> compatible = "cavium,pci-host-thunder-ecam" to mach against the errata.
>> For ACPI case we need explicit errata number and corresponding
>> DECLARE_ACPI_MCFG_FIXUP fixup code.
>>
>> Signed-off-by: Tomasz Nowicki <tn@semihalf.com>
>> ---
>> arch/arm64/Kconfig | 14 ++++++++++++++
>> arch/arm64/include/asm/cpufeature.h | 3 ++-
>> arch/arm64/kernel/cpu_errata.c | 8 ++++++++
>> drivers/pci/host/pci-thunder-ecam.c | 35
>> +++++++++++++++++++++++++++++++++++
>> 4 files changed, 59 insertions(+), 1 deletion(-)
>>
>> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
>> index 1bded87..b7614b8 100644
>> --- a/arch/arm64/Kconfig
>> +++ b/arch/arm64/Kconfig
>> @@ -445,6 +445,20 @@ config CAVIUM_ERRATUM_27456
>>
>> If unsure, say Y.
>>
>> +config CAVIUM_ERRATUM_24575
>> + bool "Cavium erratum 24575: Enhanced Allocation (EA) emualaion"
>> + default y
>> + help
>> + Enable workaround for erratum 24575.
>> +
>> + Early versions of the Cavium Thunder CN88XX processor are
>> missing
>> + Enhanced Allocation (EA) capabilities for the fixed BAR
>> addresses used
>> + by the on-SoC hardware blocks. The erratum adds config access
>> + functions that synthesize the missing EA capabilities for
>> versions
>> + that are missing that information.
>> +
>> + If unsure, say Y.
>> +
>> endmenu
>>
>>
>> diff --git a/arch/arm64/include/asm/cpufeature.h
>> b/arch/arm64/include/asm/cpufeature.h
>> index b9b6494..a78364e 100644
>> --- a/arch/arm64/include/asm/cpufeature.h
>> +++ b/arch/arm64/include/asm/cpufeature.h
>> @@ -35,8 +35,9 @@
>> #define ARM64_ALT_PAN_NOT_UAO 10
>> #define ARM64_HAS_VIRT_HOST_EXTN 11
>> #define ARM64_WORKAROUND_CAVIUM_27456 12
>> +#define ARM64_WORKAROUND_CAVIUM_24575 13
>>
>> -#define ARM64_NCAPS 13
>> +#define ARM64_NCAPS 14
>>
>> #ifndef __ASSEMBLY__
>>
>> diff --git a/arch/arm64/kernel/cpu_errata.c
>> b/arch/arm64/kernel/cpu_errata.c
>> index 06afd04..89c13d7 100644
>> --- a/arch/arm64/kernel/cpu_errata.c
>> +++ b/arch/arm64/kernel/cpu_errata.c
>> @@ -97,6 +97,14 @@ const struct arm64_cpu_capabilities arm64_errata[] = {
>> (1 << MIDR_VARIANT_SHIFT) | 1),
>> },
>> #endif
>> +#ifdef CONFIG_CAVIUM_ERRATUM_24575
>> + {
>> + /* Cavium ThunderX, pass 1.x */
>> + .desc = "Cavium erratum 24575",
>> + .capability = ARM64_WORKAROUND_CAVIUM_24575,
>> + MIDR_RANGE(MIDR_THUNDERX, 0x00, 0x01),
>> + },
>> +#endif
>> {
>> }
>> };
>> diff --git a/drivers/pci/host/pci-thunder-ecam.c
>> b/drivers/pci/host/pci-thunder-ecam.c
>> index f67c6d7..01de697 100644
>> --- a/drivers/pci/host/pci-thunder-ecam.c
>> +++ b/drivers/pci/host/pci-thunder-ecam.c
>> @@ -11,10 +11,14 @@
>> #include <linux/ioport.h>
>> #include <linux/of_pci.h>
>> #include <linux/of.h>
>> +#include <linux/pci-acpi.h>
>> #include <linux/platform_device.h>
>>
>> +#include <asm/virt.h>
>> +
>> #include "../ecam.h"
>>
>> +
>> static void set_val(u32 v, int where, int size, u32 *val)
>> {
>> int shift = (where & 3) * 8;
>> @@ -376,5 +380,36 @@ static struct platform_driver thunder_ecam_driver = {
>> };
>> module_platform_driver(thunder_ecam_driver);
>>
>> +#ifdef CONFIG_ACPI
>> +
>> +static bool needs_cavium_erratum_24575(struct pci_cfg_fixup *fixup,
>> + struct acpi_pci_root *root)
>> +{
>> + /*
>> + * We must match errata code and be hypervisor, quirk does not
>> apply
>> + * for virtual machines.
>> + */
>> + return cpus_have_cap(ARM64_WORKAROUND_CAVIUM_24575) &&
>> + is_hyp_mode_available();
>> +}
>> +
>> +DECLARE_ACPI_MCFG_FIXUP(NULL, needs_cavium_erratum_24575,
>> &pci_thunder_ecam_ops,
>> + 0, PCI_MCFG_BUS_ANY);
>> +DECLARE_ACPI_MCFG_FIXUP(NULL, needs_cavium_erratum_24575,
>> &pci_thunder_ecam_ops,
>> + 1, PCI_MCFG_BUS_ANY);
>> +DECLARE_ACPI_MCFG_FIXUP(NULL, needs_cavium_erratum_24575,
>> &pci_thunder_ecam_ops,
>> + 2, PCI_MCFG_BUS_ANY);
>> +DECLARE_ACPI_MCFG_FIXUP(NULL, needs_cavium_erratum_24575,
>> &pci_thunder_ecam_ops,
>> + 3, PCI_MCFG_BUS_ANY);
>> +DECLARE_ACPI_MCFG_FIXUP(NULL, needs_cavium_erratum_24575,
>> &pci_thunder_ecam_ops,
>> + 10, PCI_MCFG_BUS_ANY);
>> +DECLARE_ACPI_MCFG_FIXUP(NULL, needs_cavium_erratum_24575,
>> &pci_thunder_ecam_ops,
>> + 11, PCI_MCFG_BUS_ANY);
>> +DECLARE_ACPI_MCFG_FIXUP(NULL, needs_cavium_erratum_24575,
>> &pci_thunder_ecam_ops,
>> + 12, PCI_MCFG_BUS_ANY);
>> +DECLARE_ACPI_MCFG_FIXUP(NULL, needs_cavium_erratum_24575,
>> &pci_thunder_ecam_ops,
>> + 13, PCI_MCFG_BUS_ANY);
>> +#endif
>> +
>
>
> I wonder if we can identify quirk based on _DSD properties, like that:
>
> Name (_DSD, Package () {
> ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
> Package () {
> Package (2) {"cavium,pci-host-thunder-ecam", 1},
> }
> })
>
> similar for PEM driver:
>
> Name (_DSD, Package () {
> ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
> Package () {
> Package (2) {"cavium,pci-host-thunder-pem", 1},
> }
> })
>
> Do you think it is right thing to do?
>
Well if your adding new properties why not add a Cavium specific _CID?
Graeme
[toc] | [prev] | [next] | [standalone]
| From | Graeme Gregory <gg@slimlogic.co.uk> |
|---|---|
| Date | 2016-04-19 13:20 +0200 |
| Subject | Re: [Linaro-acpi] [PATCH V6 12/13] pci, pci-thunder-ecam: Add ACPI support for ThunderX ECAM. |
| Message-ID | <rpBRg-615-19@gated-at.bofh.it> |
| In reply to | #1382386 |
On Tue, Apr 19, 2016 at 11:41:29AM +0100, G Gregory wrote:
> On 19 April 2016 at 11:26, Tomasz Nowicki <tn@semihalf.com> wrote:
> > On 15.04.2016 19:06, Tomasz Nowicki wrote:
> >>
> >> Passes 1.x miss PCI enhanced allocation (EA) header for fixed-BARs,
> >> thus these passes should use Cavium-specific config access functions
> >> that synthesize the missing EA capabilities.
> >>
> >> We already have DT driver which addresses errata requirements and
> >> allows to use special PCI config accessors. Currently this driver uses
> >> compatible = "cavium,pci-host-thunder-ecam" to mach against the errata.
> >> For ACPI case we need explicit errata number and corresponding
> >> DECLARE_ACPI_MCFG_FIXUP fixup code.
> >>
> >> Signed-off-by: Tomasz Nowicki <tn@semihalf.com>
> >> ---
> >> arch/arm64/Kconfig | 14 ++++++++++++++
> >> arch/arm64/include/asm/cpufeature.h | 3 ++-
> >> arch/arm64/kernel/cpu_errata.c | 8 ++++++++
> >> drivers/pci/host/pci-thunder-ecam.c | 35
> >> +++++++++++++++++++++++++++++++++++
> >> 4 files changed, 59 insertions(+), 1 deletion(-)
> >>
> >> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
> >> index 1bded87..b7614b8 100644
> >> --- a/arch/arm64/Kconfig
> >> +++ b/arch/arm64/Kconfig
> >> @@ -445,6 +445,20 @@ config CAVIUM_ERRATUM_27456
> >>
> >> If unsure, say Y.
> >>
> >> +config CAVIUM_ERRATUM_24575
> >> + bool "Cavium erratum 24575: Enhanced Allocation (EA) emualaion"
> >> + default y
> >> + help
> >> + Enable workaround for erratum 24575.
> >> +
> >> + Early versions of the Cavium Thunder CN88XX processor are
> >> missing
> >> + Enhanced Allocation (EA) capabilities for the fixed BAR
> >> addresses used
> >> + by the on-SoC hardware blocks. The erratum adds config access
> >> + functions that synthesize the missing EA capabilities for
> >> versions
> >> + that are missing that information.
> >> +
> >> + If unsure, say Y.
> >> +
> >> endmenu
> >>
> >>
> >> diff --git a/arch/arm64/include/asm/cpufeature.h
> >> b/arch/arm64/include/asm/cpufeature.h
> >> index b9b6494..a78364e 100644
> >> --- a/arch/arm64/include/asm/cpufeature.h
> >> +++ b/arch/arm64/include/asm/cpufeature.h
> >> @@ -35,8 +35,9 @@
> >> #define ARM64_ALT_PAN_NOT_UAO 10
> >> #define ARM64_HAS_VIRT_HOST_EXTN 11
> >> #define ARM64_WORKAROUND_CAVIUM_27456 12
> >> +#define ARM64_WORKAROUND_CAVIUM_24575 13
> >>
> >> -#define ARM64_NCAPS 13
> >> +#define ARM64_NCAPS 14
> >>
> >> #ifndef __ASSEMBLY__
> >>
> >> diff --git a/arch/arm64/kernel/cpu_errata.c
> >> b/arch/arm64/kernel/cpu_errata.c
> >> index 06afd04..89c13d7 100644
> >> --- a/arch/arm64/kernel/cpu_errata.c
> >> +++ b/arch/arm64/kernel/cpu_errata.c
> >> @@ -97,6 +97,14 @@ const struct arm64_cpu_capabilities arm64_errata[] = {
> >> (1 << MIDR_VARIANT_SHIFT) | 1),
> >> },
> >> #endif
> >> +#ifdef CONFIG_CAVIUM_ERRATUM_24575
> >> + {
> >> + /* Cavium ThunderX, pass 1.x */
> >> + .desc = "Cavium erratum 24575",
> >> + .capability = ARM64_WORKAROUND_CAVIUM_24575,
> >> + MIDR_RANGE(MIDR_THUNDERX, 0x00, 0x01),
> >> + },
> >> +#endif
> >> {
> >> }
> >> };
> >> diff --git a/drivers/pci/host/pci-thunder-ecam.c
> >> b/drivers/pci/host/pci-thunder-ecam.c
> >> index f67c6d7..01de697 100644
> >> --- a/drivers/pci/host/pci-thunder-ecam.c
> >> +++ b/drivers/pci/host/pci-thunder-ecam.c
> >> @@ -11,10 +11,14 @@
> >> #include <linux/ioport.h>
> >> #include <linux/of_pci.h>
> >> #include <linux/of.h>
> >> +#include <linux/pci-acpi.h>
> >> #include <linux/platform_device.h>
> >>
> >> +#include <asm/virt.h>
> >> +
> >> #include "../ecam.h"
> >>
> >> +
> >> static void set_val(u32 v, int where, int size, u32 *val)
> >> {
> >> int shift = (where & 3) * 8;
> >> @@ -376,5 +380,36 @@ static struct platform_driver thunder_ecam_driver = {
> >> };
> >> module_platform_driver(thunder_ecam_driver);
> >>
> >> +#ifdef CONFIG_ACPI
> >> +
> >> +static bool needs_cavium_erratum_24575(struct pci_cfg_fixup *fixup,
> >> + struct acpi_pci_root *root)
> >> +{
> >> + /*
> >> + * We must match errata code and be hypervisor, quirk does not
> >> apply
> >> + * for virtual machines.
> >> + */
> >> + return cpus_have_cap(ARM64_WORKAROUND_CAVIUM_24575) &&
> >> + is_hyp_mode_available();
> >> +}
> >> +
> >> +DECLARE_ACPI_MCFG_FIXUP(NULL, needs_cavium_erratum_24575,
> >> &pci_thunder_ecam_ops,
> >> + 0, PCI_MCFG_BUS_ANY);
> >> +DECLARE_ACPI_MCFG_FIXUP(NULL, needs_cavium_erratum_24575,
> >> &pci_thunder_ecam_ops,
> >> + 1, PCI_MCFG_BUS_ANY);
> >> +DECLARE_ACPI_MCFG_FIXUP(NULL, needs_cavium_erratum_24575,
> >> &pci_thunder_ecam_ops,
> >> + 2, PCI_MCFG_BUS_ANY);
> >> +DECLARE_ACPI_MCFG_FIXUP(NULL, needs_cavium_erratum_24575,
> >> &pci_thunder_ecam_ops,
> >> + 3, PCI_MCFG_BUS_ANY);
> >> +DECLARE_ACPI_MCFG_FIXUP(NULL, needs_cavium_erratum_24575,
> >> &pci_thunder_ecam_ops,
> >> + 10, PCI_MCFG_BUS_ANY);
> >> +DECLARE_ACPI_MCFG_FIXUP(NULL, needs_cavium_erratum_24575,
> >> &pci_thunder_ecam_ops,
> >> + 11, PCI_MCFG_BUS_ANY);
> >> +DECLARE_ACPI_MCFG_FIXUP(NULL, needs_cavium_erratum_24575,
> >> &pci_thunder_ecam_ops,
> >> + 12, PCI_MCFG_BUS_ANY);
> >> +DECLARE_ACPI_MCFG_FIXUP(NULL, needs_cavium_erratum_24575,
> >> &pci_thunder_ecam_ops,
> >> + 13, PCI_MCFG_BUS_ANY);
> >> +#endif
> >> +
> >
> >
> > I wonder if we can identify quirk based on _DSD properties, like that:
> >
> > Name (_DSD, Package () {
> > ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
> > Package () {
> > Package (2) {"cavium,pci-host-thunder-ecam", 1},
> > }
> > })
> >
> > similar for PEM driver:
> >
> > Name (_DSD, Package () {
> > ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
> > Package () {
> > Package (2) {"cavium,pci-host-thunder-pem", 1},
> > }
> > })
> >
> > Do you think it is right thing to do?
> >
>
> Well if your adding new properties why not add a Cavium specific _CID?
>
For clarity what I mean is something like this allowed.
Device (PCI0)
{
Name (_HID, EisaId ("PNP0A08"))
Name (_CID, EisaId ("PNP0A03"))
Name (_HID, "CAV0666")) // Cavium Quirky Hardware
....
}
Graeme
[toc] | [prev] | [next] | [standalone]
| From | Tomasz Nowicki <tn@semihalf.com> |
|---|---|
| Date | 2016-04-19 13:30 +0200 |
| Subject | Re: [Linaro-acpi] [PATCH V6 12/13] pci, pci-thunder-ecam: Add ACPI support for ThunderX ECAM. |
| Message-ID | <rpC0W-64Y-3@gated-at.bofh.it> |
| In reply to | #1382402 |
On 19.04.2016 13:12, Graeme Gregory wrote:
> On Tue, Apr 19, 2016 at 11:41:29AM +0100, G Gregory wrote:
>> On 19 April 2016 at 11:26, Tomasz Nowicki <tn@semihalf.com> wrote:
>>> On 15.04.2016 19:06, Tomasz Nowicki wrote:
>>>>
>>>> Passes 1.x miss PCI enhanced allocation (EA) header for fixed-BARs,
>>>> thus these passes should use Cavium-specific config access functions
>>>> that synthesize the missing EA capabilities.
>>>>
>>>> We already have DT driver which addresses errata requirements and
>>>> allows to use special PCI config accessors. Currently this driver uses
>>>> compatible = "cavium,pci-host-thunder-ecam" to mach against the errata.
>>>> For ACPI case we need explicit errata number and corresponding
>>>> DECLARE_ACPI_MCFG_FIXUP fixup code.
>>>>
>>>> Signed-off-by: Tomasz Nowicki <tn@semihalf.com>
>>>> ---
>>>> arch/arm64/Kconfig | 14 ++++++++++++++
>>>> arch/arm64/include/asm/cpufeature.h | 3 ++-
>>>> arch/arm64/kernel/cpu_errata.c | 8 ++++++++
>>>> drivers/pci/host/pci-thunder-ecam.c | 35
>>>> +++++++++++++++++++++++++++++++++++
>>>> 4 files changed, 59 insertions(+), 1 deletion(-)
>>>>
>>>> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
>>>> index 1bded87..b7614b8 100644
>>>> --- a/arch/arm64/Kconfig
>>>> +++ b/arch/arm64/Kconfig
>>>> @@ -445,6 +445,20 @@ config CAVIUM_ERRATUM_27456
>>>>
>>>> If unsure, say Y.
>>>>
>>>> +config CAVIUM_ERRATUM_24575
>>>> + bool "Cavium erratum 24575: Enhanced Allocation (EA) emualaion"
>>>> + default y
>>>> + help
>>>> + Enable workaround for erratum 24575.
>>>> +
>>>> + Early versions of the Cavium Thunder CN88XX processor are
>>>> missing
>>>> + Enhanced Allocation (EA) capabilities for the fixed BAR
>>>> addresses used
>>>> + by the on-SoC hardware blocks. The erratum adds config access
>>>> + functions that synthesize the missing EA capabilities for
>>>> versions
>>>> + that are missing that information.
>>>> +
>>>> + If unsure, say Y.
>>>> +
>>>> endmenu
>>>>
>>>>
>>>> diff --git a/arch/arm64/include/asm/cpufeature.h
>>>> b/arch/arm64/include/asm/cpufeature.h
>>>> index b9b6494..a78364e 100644
>>>> --- a/arch/arm64/include/asm/cpufeature.h
>>>> +++ b/arch/arm64/include/asm/cpufeature.h
>>>> @@ -35,8 +35,9 @@
>>>> #define ARM64_ALT_PAN_NOT_UAO 10
>>>> #define ARM64_HAS_VIRT_HOST_EXTN 11
>>>> #define ARM64_WORKAROUND_CAVIUM_27456 12
>>>> +#define ARM64_WORKAROUND_CAVIUM_24575 13
>>>>
>>>> -#define ARM64_NCAPS 13
>>>> +#define ARM64_NCAPS 14
>>>>
>>>> #ifndef __ASSEMBLY__
>>>>
>>>> diff --git a/arch/arm64/kernel/cpu_errata.c
>>>> b/arch/arm64/kernel/cpu_errata.c
>>>> index 06afd04..89c13d7 100644
>>>> --- a/arch/arm64/kernel/cpu_errata.c
>>>> +++ b/arch/arm64/kernel/cpu_errata.c
>>>> @@ -97,6 +97,14 @@ const struct arm64_cpu_capabilities arm64_errata[] = {
>>>> (1 << MIDR_VARIANT_SHIFT) | 1),
>>>> },
>>>> #endif
>>>> +#ifdef CONFIG_CAVIUM_ERRATUM_24575
>>>> + {
>>>> + /* Cavium ThunderX, pass 1.x */
>>>> + .desc = "Cavium erratum 24575",
>>>> + .capability = ARM64_WORKAROUND_CAVIUM_24575,
>>>> + MIDR_RANGE(MIDR_THUNDERX, 0x00, 0x01),
>>>> + },
>>>> +#endif
>>>> {
>>>> }
>>>> };
>>>> diff --git a/drivers/pci/host/pci-thunder-ecam.c
>>>> b/drivers/pci/host/pci-thunder-ecam.c
>>>> index f67c6d7..01de697 100644
>>>> --- a/drivers/pci/host/pci-thunder-ecam.c
>>>> +++ b/drivers/pci/host/pci-thunder-ecam.c
>>>> @@ -11,10 +11,14 @@
>>>> #include <linux/ioport.h>
>>>> #include <linux/of_pci.h>
>>>> #include <linux/of.h>
>>>> +#include <linux/pci-acpi.h>
>>>> #include <linux/platform_device.h>
>>>>
>>>> +#include <asm/virt.h>
>>>> +
>>>> #include "../ecam.h"
>>>>
>>>> +
>>>> static void set_val(u32 v, int where, int size, u32 *val)
>>>> {
>>>> int shift = (where & 3) * 8;
>>>> @@ -376,5 +380,36 @@ static struct platform_driver thunder_ecam_driver = {
>>>> };
>>>> module_platform_driver(thunder_ecam_driver);
>>>>
>>>> +#ifdef CONFIG_ACPI
>>>> +
>>>> +static bool needs_cavium_erratum_24575(struct pci_cfg_fixup *fixup,
>>>> + struct acpi_pci_root *root)
>>>> +{
>>>> + /*
>>>> + * We must match errata code and be hypervisor, quirk does not
>>>> apply
>>>> + * for virtual machines.
>>>> + */
>>>> + return cpus_have_cap(ARM64_WORKAROUND_CAVIUM_24575) &&
>>>> + is_hyp_mode_available();
>>>> +}
>>>> +
>>>> +DECLARE_ACPI_MCFG_FIXUP(NULL, needs_cavium_erratum_24575,
>>>> &pci_thunder_ecam_ops,
>>>> + 0, PCI_MCFG_BUS_ANY);
>>>> +DECLARE_ACPI_MCFG_FIXUP(NULL, needs_cavium_erratum_24575,
>>>> &pci_thunder_ecam_ops,
>>>> + 1, PCI_MCFG_BUS_ANY);
>>>> +DECLARE_ACPI_MCFG_FIXUP(NULL, needs_cavium_erratum_24575,
>>>> &pci_thunder_ecam_ops,
>>>> + 2, PCI_MCFG_BUS_ANY);
>>>> +DECLARE_ACPI_MCFG_FIXUP(NULL, needs_cavium_erratum_24575,
>>>> &pci_thunder_ecam_ops,
>>>> + 3, PCI_MCFG_BUS_ANY);
>>>> +DECLARE_ACPI_MCFG_FIXUP(NULL, needs_cavium_erratum_24575,
>>>> &pci_thunder_ecam_ops,
>>>> + 10, PCI_MCFG_BUS_ANY);
>>>> +DECLARE_ACPI_MCFG_FIXUP(NULL, needs_cavium_erratum_24575,
>>>> &pci_thunder_ecam_ops,
>>>> + 11, PCI_MCFG_BUS_ANY);
>>>> +DECLARE_ACPI_MCFG_FIXUP(NULL, needs_cavium_erratum_24575,
>>>> &pci_thunder_ecam_ops,
>>>> + 12, PCI_MCFG_BUS_ANY);
>>>> +DECLARE_ACPI_MCFG_FIXUP(NULL, needs_cavium_erratum_24575,
>>>> &pci_thunder_ecam_ops,
>>>> + 13, PCI_MCFG_BUS_ANY);
>>>> +#endif
>>>> +
>>>
>>>
>>> I wonder if we can identify quirk based on _DSD properties, like that:
>>>
>>> Name (_DSD, Package () {
>>> ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
>>> Package () {
>>> Package (2) {"cavium,pci-host-thunder-ecam", 1},
>>> }
>>> })
>>>
>>> similar for PEM driver:
>>>
>>> Name (_DSD, Package () {
>>> ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
>>> Package () {
>>> Package (2) {"cavium,pci-host-thunder-pem", 1},
>>> }
>>> })
>>>
>>> Do you think it is right thing to do?
>>>
>>
>> Well if your adding new properties why not add a Cavium specific _CID?
>>
>
> For clarity what I mean is something like this allowed.
>
> Device (PCI0)
> {
> Name (_HID, EisaId ("PNP0A08"))
> Name (_CID, EisaId ("PNP0A03"))
> Name (_HID, "CAV0666")) // Cavium Quirky Hardware
>
> ....
>
> }
>
Rafael, Bjorn, what do you think?
Tomasz
[toc] | [prev] | [next] | [standalone]
| From | G Gregory <graeme.gregory@linaro.org> |
|---|---|
| Date | 2016-04-19 14:30 +0200 |
| Subject | Re: [Linaro-acpi] [PATCH V6 12/13] pci, pci-thunder-ecam: Add ACPI support for ThunderX ECAM. |
| Message-ID | <rpCX1-6Oi-43@gated-at.bofh.it> |
| In reply to | #1382406 |
On Tue, Apr 19, 2016 at 01:22:29PM +0200, Tomasz Nowicki wrote:
>
>
> On 19.04.2016 13:12, Graeme Gregory wrote:
> >On Tue, Apr 19, 2016 at 11:41:29AM +0100, G Gregory wrote:
> >>On 19 April 2016 at 11:26, Tomasz Nowicki <tn@semihalf.com> wrote:
> >>>On 15.04.2016 19:06, Tomasz Nowicki wrote:
> >>>>
> >>>>Passes 1.x miss PCI enhanced allocation (EA) header for fixed-BARs,
> >>>>thus these passes should use Cavium-specific config access functions
> >>>>that synthesize the missing EA capabilities.
> >>>>
> >>>>We already have DT driver which addresses errata requirements and
> >>>>allows to use special PCI config accessors. Currently this driver uses
> >>>>compatible = "cavium,pci-host-thunder-ecam" to mach against the errata.
> >>>>For ACPI case we need explicit errata number and corresponding
> >>>>DECLARE_ACPI_MCFG_FIXUP fixup code.
> >>>>
> >>>>Signed-off-by: Tomasz Nowicki <tn@semihalf.com>
> >>>>---
> >>>> arch/arm64/Kconfig | 14 ++++++++++++++
> >>>> arch/arm64/include/asm/cpufeature.h | 3 ++-
> >>>> arch/arm64/kernel/cpu_errata.c | 8 ++++++++
> >>>> drivers/pci/host/pci-thunder-ecam.c | 35
> >>>>+++++++++++++++++++++++++++++++++++
> >>>> 4 files changed, 59 insertions(+), 1 deletion(-)
> >>>>
> >>>>diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
> >>>>index 1bded87..b7614b8 100644
> >>>>--- a/arch/arm64/Kconfig
> >>>>+++ b/arch/arm64/Kconfig
> >>>>@@ -445,6 +445,20 @@ config CAVIUM_ERRATUM_27456
> >>>>
> >>>> If unsure, say Y.
> >>>>
> >>>>+config CAVIUM_ERRATUM_24575
> >>>>+ bool "Cavium erratum 24575: Enhanced Allocation (EA) emualaion"
> >>>>+ default y
> >>>>+ help
> >>>>+ Enable workaround for erratum 24575.
> >>>>+
> >>>>+ Early versions of the Cavium Thunder CN88XX processor are
> >>>>missing
> >>>>+ Enhanced Allocation (EA) capabilities for the fixed BAR
> >>>>addresses used
> >>>>+ by the on-SoC hardware blocks. The erratum adds config access
> >>>>+ functions that synthesize the missing EA capabilities for
> >>>>versions
> >>>>+ that are missing that information.
> >>>>+
> >>>>+ If unsure, say Y.
> >>>>+
> >>>> endmenu
> >>>>
> >>>>
> >>>>diff --git a/arch/arm64/include/asm/cpufeature.h
> >>>>b/arch/arm64/include/asm/cpufeature.h
> >>>>index b9b6494..a78364e 100644
> >>>>--- a/arch/arm64/include/asm/cpufeature.h
> >>>>+++ b/arch/arm64/include/asm/cpufeature.h
> >>>>@@ -35,8 +35,9 @@
> >>>> #define ARM64_ALT_PAN_NOT_UAO 10
> >>>> #define ARM64_HAS_VIRT_HOST_EXTN 11
> >>>> #define ARM64_WORKAROUND_CAVIUM_27456 12
> >>>>+#define ARM64_WORKAROUND_CAVIUM_24575 13
> >>>>
> >>>>-#define ARM64_NCAPS 13
> >>>>+#define ARM64_NCAPS 14
> >>>>
> >>>> #ifndef __ASSEMBLY__
> >>>>
> >>>>diff --git a/arch/arm64/kernel/cpu_errata.c
> >>>>b/arch/arm64/kernel/cpu_errata.c
> >>>>index 06afd04..89c13d7 100644
> >>>>--- a/arch/arm64/kernel/cpu_errata.c
> >>>>+++ b/arch/arm64/kernel/cpu_errata.c
> >>>>@@ -97,6 +97,14 @@ const struct arm64_cpu_capabilities arm64_errata[] = {
> >>>> (1 << MIDR_VARIANT_SHIFT) | 1),
> >>>> },
> >>>> #endif
> >>>>+#ifdef CONFIG_CAVIUM_ERRATUM_24575
> >>>>+ {
> >>>>+ /* Cavium ThunderX, pass 1.x */
> >>>>+ .desc = "Cavium erratum 24575",
> >>>>+ .capability = ARM64_WORKAROUND_CAVIUM_24575,
> >>>>+ MIDR_RANGE(MIDR_THUNDERX, 0x00, 0x01),
> >>>>+ },
> >>>>+#endif
> >>>> {
> >>>> }
> >>>> };
> >>>>diff --git a/drivers/pci/host/pci-thunder-ecam.c
> >>>>b/drivers/pci/host/pci-thunder-ecam.c
> >>>>index f67c6d7..01de697 100644
> >>>>--- a/drivers/pci/host/pci-thunder-ecam.c
> >>>>+++ b/drivers/pci/host/pci-thunder-ecam.c
> >>>>@@ -11,10 +11,14 @@
> >>>> #include <linux/ioport.h>
> >>>> #include <linux/of_pci.h>
> >>>> #include <linux/of.h>
> >>>>+#include <linux/pci-acpi.h>
> >>>> #include <linux/platform_device.h>
> >>>>
> >>>>+#include <asm/virt.h>
> >>>>+
> >>>> #include "../ecam.h"
> >>>>
> >>>>+
> >>>> static void set_val(u32 v, int where, int size, u32 *val)
> >>>> {
> >>>> int shift = (where & 3) * 8;
> >>>>@@ -376,5 +380,36 @@ static struct platform_driver thunder_ecam_driver = {
> >>>> };
> >>>> module_platform_driver(thunder_ecam_driver);
> >>>>
> >>>>+#ifdef CONFIG_ACPI
> >>>>+
> >>>>+static bool needs_cavium_erratum_24575(struct pci_cfg_fixup *fixup,
> >>>>+ struct acpi_pci_root *root)
> >>>>+{
> >>>>+ /*
> >>>>+ * We must match errata code and be hypervisor, quirk does not
> >>>>apply
> >>>>+ * for virtual machines.
> >>>>+ */
> >>>>+ return cpus_have_cap(ARM64_WORKAROUND_CAVIUM_24575) &&
> >>>>+ is_hyp_mode_available();
> >>>>+}
> >>>>+
> >>>>+DECLARE_ACPI_MCFG_FIXUP(NULL, needs_cavium_erratum_24575,
> >>>>&pci_thunder_ecam_ops,
> >>>>+ 0, PCI_MCFG_BUS_ANY);
> >>>>+DECLARE_ACPI_MCFG_FIXUP(NULL, needs_cavium_erratum_24575,
> >>>>&pci_thunder_ecam_ops,
> >>>>+ 1, PCI_MCFG_BUS_ANY);
> >>>>+DECLARE_ACPI_MCFG_FIXUP(NULL, needs_cavium_erratum_24575,
> >>>>&pci_thunder_ecam_ops,
> >>>>+ 2, PCI_MCFG_BUS_ANY);
> >>>>+DECLARE_ACPI_MCFG_FIXUP(NULL, needs_cavium_erratum_24575,
> >>>>&pci_thunder_ecam_ops,
> >>>>+ 3, PCI_MCFG_BUS_ANY);
> >>>>+DECLARE_ACPI_MCFG_FIXUP(NULL, needs_cavium_erratum_24575,
> >>>>&pci_thunder_ecam_ops,
> >>>>+ 10, PCI_MCFG_BUS_ANY);
> >>>>+DECLARE_ACPI_MCFG_FIXUP(NULL, needs_cavium_erratum_24575,
> >>>>&pci_thunder_ecam_ops,
> >>>>+ 11, PCI_MCFG_BUS_ANY);
> >>>>+DECLARE_ACPI_MCFG_FIXUP(NULL, needs_cavium_erratum_24575,
> >>>>&pci_thunder_ecam_ops,
> >>>>+ 12, PCI_MCFG_BUS_ANY);
> >>>>+DECLARE_ACPI_MCFG_FIXUP(NULL, needs_cavium_erratum_24575,
> >>>>&pci_thunder_ecam_ops,
> >>>>+ 13, PCI_MCFG_BUS_ANY);
> >>>>+#endif
> >>>>+
> >>>
> >>>
> >>>I wonder if we can identify quirk based on _DSD properties, like that:
> >>>
> >>>Name (_DSD, Package () {
> >>> ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
> >>> Package () {
> >>> Package (2) {"cavium,pci-host-thunder-ecam", 1},
> >>> }
> >>>})
> >>>
> >>>similar for PEM driver:
> >>>
> >>>Name (_DSD, Package () {
> >>> ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
> >>> Package () {
> >>> Package (2) {"cavium,pci-host-thunder-pem", 1},
> >>> }
> >>>})
> >>>
> >>>Do you think it is right thing to do?
> >>>
> >>
> >>Well if your adding new properties why not add a Cavium specific _CID?
> >>
> >
> >For clarity what I mean is something like this allowed.
> >
> >Device (PCI0)
> >{
> > Name (_HID, EisaId ("PNP0A08"))
> > Name (_CID, EisaId ("PNP0A03"))
> > Name (_HID, "CAV0666")) // Cavium Quirky Hardware
> >
> > ....
> >
> >}
> >
>
> Rafael, Bjorn, what do you think?
>
Another option as has been pointed out to me is that devices that are
not compliant don't advertise the IDs PNP0A03/8 and should use hardware
specific IDs.
Obviously in linux the drivers for them would re-use 90% of the generic
code with just their added accessors.
I do not know though what knock-on effects that would have and if there
is stuff that relies on the host bridge being IDed as the standard one.
Graeme
[toc] | [prev] | [next] | [standalone]
| From | Tomasz Nowicki <tn@semihalf.com> |
|---|---|
| Date | 2016-04-15 19:10 +0200 |
| Subject | [PATCH V6 08/13] PCI: generic, thunder: update to use generic ECAM API |
| Message-ID | <rofpM-6tr-27@gated-at.bofh.it> |
| In reply to | #1380019 |
From: Jayachandran C <jchandra@broadcom.com>
Use functions provided by drivers/pci/ecam.h for mapping the config
space in drivers/pci/host/pci-host-common.c, and update its users to
use 'struct pci_config_window' and 'struct pci_generic_ecam_ops'
The changes are mostly to use 'struct pci_config_window' in place of
'struct gen_pci'. Some of the fields of gen_pci were only used
temporarily and can be eliminated by using local variables or function
arguments, these are not carried over to struct pci_config_window.
pci-thunder-ecam.c and pci-thunder-pem.c are the only users of the
pci_host_common_probe function and the gen_pci structure, these have
been updated to use the new API as well.
The patch does not introduce any functional changes other than a very
minor one: with the new code, on 64-bit platforms, we do just a single
ioremap for the whole config space.
Signed-off-by: Jayachandran C <jchandra@broadcom.com>
---
drivers/pci/ecam.h | 5 ++
drivers/pci/host/Kconfig | 1 +
drivers/pci/host/pci-host-common.c | 119 ++++++++++++++++--------------------
drivers/pci/host/pci-host-common.h | 47 --------------
drivers/pci/host/pci-host-generic.c | 52 +++-------------
drivers/pci/host/pci-thunder-ecam.c | 39 +++---------
drivers/pci/host/pci-thunder-pem.c | 88 ++++++++++++--------------
7 files changed, 115 insertions(+), 236 deletions(-)
delete mode 100644 drivers/pci/host/pci-host-common.h
diff --git a/drivers/pci/ecam.h b/drivers/pci/ecam.h
index 34c0aba..706621a 100644
--- a/drivers/pci/ecam.h
+++ b/drivers/pci/ecam.h
@@ -58,4 +58,9 @@ void __iomem *pci_generic_ecam_map_bus(struct pci_bus *bus, unsigned int devfn,
/* default ECAM ops, bus shift 20, generic read and write */
extern struct pci_generic_ecam_ops pci_generic_ecam_default_ops;
+#ifdef CONFIG_PCI_HOST_GENERIC
+/* for DT based pci controllers that support ECAM */
+int pci_host_common_probe(struct platform_device *pdev,
+ struct pci_generic_ecam_ops *ops);
+#endif
#endif
diff --git a/drivers/pci/host/Kconfig b/drivers/pci/host/Kconfig
index 7a0780d..31d6eb5 100644
--- a/drivers/pci/host/Kconfig
+++ b/drivers/pci/host/Kconfig
@@ -82,6 +82,7 @@ config PCI_HOST_GENERIC
bool "Generic PCI host controller"
depends on (ARM || ARM64) && OF
select PCI_HOST_COMMON
+ select PCI_GENERIC_ECAM
help
Say Y here if you want to support a simple generic PCI host
controller, such as the one emulated by kvmtool.
diff --git a/drivers/pci/host/pci-host-common.c b/drivers/pci/host/pci-host-common.c
index e9f850f..99d99b3 100644
--- a/drivers/pci/host/pci-host-common.c
+++ b/drivers/pci/host/pci-host-common.c
@@ -22,27 +22,21 @@
#include <linux/of_pci.h>
#include <linux/platform_device.h>
-#include "pci-host-common.h"
+#include "../ecam.h"
-static void gen_pci_release_of_pci_ranges(struct gen_pci *pci)
-{
- pci_free_resource_list(&pci->resources);
-}
-
-static int gen_pci_parse_request_of_pci_ranges(struct gen_pci *pci)
+static int gen_pci_parse_request_of_pci_ranges(struct device *dev,
+ struct list_head *resources, struct resource **bus_range)
{
int err, res_valid = 0;
- struct device *dev = pci->host.dev.parent;
struct device_node *np = dev->of_node;
resource_size_t iobase;
struct resource_entry *win;
- err = of_pci_get_host_bridge_resources(np, 0, 0xff, &pci->resources,
- &iobase);
+ err = of_pci_get_host_bridge_resources(np, 0, 0xff, resources, &iobase);
if (err)
return err;
- resource_list_for_each_entry(win, &pci->resources) {
+ resource_list_for_each_entry(win, resources) {
struct resource *parent, *res = win->res;
switch (resource_type(res)) {
@@ -60,7 +54,7 @@ static int gen_pci_parse_request_of_pci_ranges(struct gen_pci *pci)
res_valid |= !(res->flags & IORESOURCE_PREFETCH);
break;
case IORESOURCE_BUS:
- pci->cfg.bus_range = res;
+ *bus_range = res;
default:
continue;
}
@@ -79,65 +73,67 @@ static int gen_pci_parse_request_of_pci_ranges(struct gen_pci *pci)
return 0;
out_release_res:
- gen_pci_release_of_pci_ranges(pci);
return err;
}
-static int gen_pci_parse_map_cfg_windows(struct gen_pci *pci)
+static void gen_pci_generic_unmap_cfg(void *ptr)
+{
+ pci_generic_ecam_free((struct pci_config_window *)ptr);
+}
+
+static struct pci_config_window *gen_pci_init(struct device *dev,
+ struct list_head *resources, struct pci_generic_ecam_ops *ops)
{
int err;
- u8 bus_max;
- resource_size_t busn;
- struct resource *bus_range;
- struct device *dev = pci->host.dev.parent;
- struct device_node *np = dev->of_node;
- u32 sz = 1 << pci->cfg.ops->bus_shift;
+ struct resource cfgres;
+ struct resource *bus_range = NULL;
+ struct pci_config_window *cfg;
+ unsigned int bus_shift = ops->bus_shift;
- err = of_address_to_resource(np, 0, &pci->cfg.res);
+ /* Parse our PCI ranges and request their resources */
+ err = gen_pci_parse_request_of_pci_ranges(dev, resources, &bus_range);
+ if (err)
+ goto err_out;
+
+ err = of_address_to_resource(dev->of_node, 0, &cfgres);
if (err) {
dev_err(dev, "missing \"reg\" property\n");
- return err;
+ goto err_out;
}
/* Limit the bus-range to fit within reg */
- bus_max = pci->cfg.bus_range->start +
- (resource_size(&pci->cfg.res) >> pci->cfg.ops->bus_shift) - 1;
- pci->cfg.bus_range->end = min_t(resource_size_t,
- pci->cfg.bus_range->end, bus_max);
-
- pci->cfg.win = devm_kcalloc(dev, resource_size(pci->cfg.bus_range),
- sizeof(*pci->cfg.win), GFP_KERNEL);
- if (!pci->cfg.win)
- return -ENOMEM;
-
- /* Map our Configuration Space windows */
- if (!devm_request_mem_region(dev, pci->cfg.res.start,
- resource_size(&pci->cfg.res),
- "Configuration Space"))
- return -ENOMEM;
-
- bus_range = pci->cfg.bus_range;
- for (busn = bus_range->start; busn <= bus_range->end; ++busn) {
- u32 idx = busn - bus_range->start;
-
- pci->cfg.win[idx] = devm_ioremap(dev,
- pci->cfg.res.start + idx * sz,
- sz);
- if (!pci->cfg.win[idx])
- return -ENOMEM;
+ bus_range->end = min(bus_range->end,
+ bus_range->start + (resource_size(&cfgres) >> bus_shift) - 1);
+
+ cfg = pci_generic_ecam_create(dev, cfgres.start, bus_range->start,
+ bus_range->end, ops);
+ if (IS_ERR(cfg)) {
+ err = PTR_ERR(cfg);
+ goto err_out;
}
- return 0;
+ err = devm_add_action(dev, gen_pci_generic_unmap_cfg, cfg);
+ if (err) {
+ gen_pci_generic_unmap_cfg(cfg);
+ goto err_out;
+ }
+ return cfg;
+
+err_out:
+ pci_free_resource_list(resources);
+ return ERR_PTR(err);
}
int pci_host_common_probe(struct platform_device *pdev,
- struct gen_pci *pci)
+ struct pci_generic_ecam_ops *ops)
+
{
- int err;
const char *type;
struct device *dev = &pdev->dev;
struct device_node *np = dev->of_node;
struct pci_bus *bus, *child;
+ struct pci_config_window *cfg;
+ struct list_head resources;
type = of_get_property(np, "device_type", NULL);
if (!type || strcmp(type, "pci")) {
@@ -147,29 +143,18 @@ int pci_host_common_probe(struct platform_device *pdev,
of_pci_check_probe_only();
- pci->host.dev.parent = dev;
- INIT_LIST_HEAD(&pci->host.windows);
- INIT_LIST_HEAD(&pci->resources);
-
- /* Parse our PCI ranges and request their resources */
- err = gen_pci_parse_request_of_pci_ranges(pci);
- if (err)
- return err;
-
/* Parse and map our Configuration Space windows */
- err = gen_pci_parse_map_cfg_windows(pci);
- if (err) {
- gen_pci_release_of_pci_ranges(pci);
- return err;
- }
+ INIT_LIST_HEAD(&resources);
+ cfg = gen_pci_init(dev, &resources, ops);
+ if (IS_ERR(cfg))
+ return PTR_ERR(cfg);
/* Do not reassign resources if probe only */
if (!pci_has_flag(PCI_PROBE_ONLY))
pci_add_flags(PCI_REASSIGN_ALL_RSRC | PCI_REASSIGN_ALL_BUS);
-
- bus = pci_scan_root_bus(dev, pci->cfg.bus_range->start,
- &pci->cfg.ops->ops, pci, &pci->resources);
+ bus = pci_scan_root_bus(dev, cfg->bus_start, &ops->pci_ops, cfg,
+ &resources);
if (!bus) {
dev_err(dev, "Scanning rootbus failed");
return -ENODEV;
diff --git a/drivers/pci/host/pci-host-common.h b/drivers/pci/host/pci-host-common.h
deleted file mode 100644
index 09f3fa0..0000000
--- a/drivers/pci/host/pci-host-common.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * 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.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
- * Copyright (C) 2014 ARM Limited
- *
- * Author: Will Deacon <will.deacon@arm.com>
- */
-
-#ifndef _PCI_HOST_COMMON_H
-#define _PCI_HOST_COMMON_H
-
-#include <linux/kernel.h>
-#include <linux/platform_device.h>
-
-struct gen_pci_cfg_bus_ops {
- u32 bus_shift;
- struct pci_ops ops;
-};
-
-struct gen_pci_cfg_windows {
- struct resource res;
- struct resource *bus_range;
- void __iomem **win;
-
- struct gen_pci_cfg_bus_ops *ops;
-};
-
-struct gen_pci {
- struct pci_host_bridge host;
- struct gen_pci_cfg_windows cfg;
- struct list_head resources;
-};
-
-int pci_host_common_probe(struct platform_device *pdev,
- struct gen_pci *pci);
-
-#endif /* _PCI_HOST_COMMON_H */
diff --git a/drivers/pci/host/pci-host-generic.c b/drivers/pci/host/pci-host-generic.c
index e8aa78f..0150a62 100644
--- a/drivers/pci/host/pci-host-generic.c
+++ b/drivers/pci/host/pci-host-generic.c
@@ -25,41 +25,12 @@
#include <linux/of_pci.h>
#include <linux/platform_device.h>
-#include "pci-host-common.h"
+#include "../ecam.h"
-static void __iomem *gen_pci_map_cfg_bus_cam(struct pci_bus *bus,
- unsigned int devfn,
- int where)
-{
- struct gen_pci *pci = bus->sysdata;
- resource_size_t idx = bus->number - pci->cfg.bus_range->start;
-
- return pci->cfg.win[idx] + ((devfn << 8) | where);
-}
-
-static struct gen_pci_cfg_bus_ops gen_pci_cfg_cam_bus_ops = {
+static struct pci_generic_ecam_ops gen_pci_cfg_cam_bus_ops = {
.bus_shift = 16,
- .ops = {
- .map_bus = gen_pci_map_cfg_bus_cam,
- .read = pci_generic_config_read,
- .write = pci_generic_config_write,
- }
-};
-
-static void __iomem *gen_pci_map_cfg_bus_ecam(struct pci_bus *bus,
- unsigned int devfn,
- int where)
-{
- struct gen_pci *pci = bus->sysdata;
- resource_size_t idx = bus->number - pci->cfg.bus_range->start;
-
- return pci->cfg.win[idx] + ((devfn << 12) | where);
-}
-
-static struct gen_pci_cfg_bus_ops gen_pci_cfg_ecam_bus_ops = {
- .bus_shift = 20,
- .ops = {
- .map_bus = gen_pci_map_cfg_bus_ecam,
+ .pci_ops = {
+ .map_bus = pci_generic_ecam_map_bus,
.read = pci_generic_config_read,
.write = pci_generic_config_write,
}
@@ -70,25 +41,22 @@ static const struct of_device_id gen_pci_of_match[] = {
.data = &gen_pci_cfg_cam_bus_ops },
{ .compatible = "pci-host-ecam-generic",
- .data = &gen_pci_cfg_ecam_bus_ops },
+ .data = &pci_generic_ecam_default_ops },
{ },
};
+
MODULE_DEVICE_TABLE(of, gen_pci_of_match);
static int gen_pci_probe(struct platform_device *pdev)
{
- struct device *dev = &pdev->dev;
const struct of_device_id *of_id;
- struct gen_pci *pci = devm_kzalloc(dev, sizeof(*pci), GFP_KERNEL);
-
- if (!pci)
- return -ENOMEM;
+ struct pci_generic_ecam_ops *ops;
- of_id = of_match_node(gen_pci_of_match, dev->of_node);
- pci->cfg.ops = (struct gen_pci_cfg_bus_ops *)of_id->data;
+ of_id = of_match_node(gen_pci_of_match, pdev->dev.of_node);
+ ops = (struct pci_generic_ecam_ops *)of_id->data;
- return pci_host_common_probe(pdev, pci);
+ return pci_host_common_probe(pdev, ops);
}
static struct platform_driver gen_pci_driver = {
diff --git a/drivers/pci/host/pci-thunder-ecam.c b/drivers/pci/host/pci-thunder-ecam.c
index d71935cb..f67c6d7 100644
--- a/drivers/pci/host/pci-thunder-ecam.c
+++ b/drivers/pci/host/pci-thunder-ecam.c
@@ -13,18 +13,7 @@
#include <linux/of.h>
#include <linux/platform_device.h>
-#include "pci-host-common.h"
-
-/* Mapping is standard ECAM */
-static void __iomem *thunder_ecam_map_bus(struct pci_bus *bus,
- unsigned int devfn,
- int where)
-{
- struct gen_pci *pci = bus->sysdata;
- resource_size_t idx = bus->number - pci->cfg.bus_range->start;
-
- return pci->cfg.win[idx] + ((devfn << 12) | where);
-}
+#include "../ecam.h"
static void set_val(u32 v, int where, int size, u32 *val)
{
@@ -99,7 +88,7 @@ static int handle_ea_bar(u32 e0, int bar, struct pci_bus *bus,
static int thunder_ecam_p2_config_read(struct pci_bus *bus, unsigned int devfn,
int where, int size, u32 *val)
{
- struct gen_pci *pci = bus->sysdata;
+ struct pci_config_window *cfg = bus->sysdata;
int where_a = where & ~3;
void __iomem *addr;
u32 node_bits;
@@ -129,7 +118,7 @@ static int thunder_ecam_p2_config_read(struct pci_bus *bus, unsigned int devfn,
* the config space access window. Since we are working with
* the high-order 32 bits, shift everything down by 32 bits.
*/
- node_bits = (pci->cfg.res.start >> 32) & (1 << 12);
+ node_bits = (cfg->cfgaddr >> 32) & (1 << 12);
v |= node_bits;
set_val(v, where, size, val);
@@ -358,36 +347,24 @@ static int thunder_ecam_config_write(struct pci_bus *bus, unsigned int devfn,
return pci_generic_config_write(bus, devfn, where, size, val);
}
-static struct gen_pci_cfg_bus_ops thunder_ecam_bus_ops = {
+static struct pci_generic_ecam_ops pci_thunder_ecam_ops = {
.bus_shift = 20,
- .ops = {
- .map_bus = thunder_ecam_map_bus,
+ .pci_ops = {
+ .map_bus = pci_generic_ecam_map_bus,
.read = thunder_ecam_config_read,
.write = thunder_ecam_config_write,
}
};
static const struct of_device_id thunder_ecam_of_match[] = {
- { .compatible = "cavium,pci-host-thunder-ecam",
- .data = &thunder_ecam_bus_ops },
-
+ { .compatible = "cavium,pci-host-thunder-ecam" },
{ },
};
MODULE_DEVICE_TABLE(of, thunder_ecam_of_match);
static int thunder_ecam_probe(struct platform_device *pdev)
{
- struct device *dev = &pdev->dev;
- const struct of_device_id *of_id;
- struct gen_pci *pci = devm_kzalloc(dev, sizeof(*pci), GFP_KERNEL);
-
- if (!pci)
- return -ENOMEM;
-
- of_id = of_match_node(thunder_ecam_of_match, dev->of_node);
- pci->cfg.ops = (struct gen_pci_cfg_bus_ops *)of_id->data;
-
- return pci_host_common_probe(pdev, pci);
+ return pci_host_common_probe(pdev, &pci_thunder_ecam_ops);
}
static struct platform_driver thunder_ecam_driver = {
diff --git a/drivers/pci/host/pci-thunder-pem.c b/drivers/pci/host/pci-thunder-pem.c
index cabb92a..91cfeb9 100644
--- a/drivers/pci/host/pci-thunder-pem.c
+++ b/drivers/pci/host/pci-thunder-pem.c
@@ -20,34 +20,22 @@
#include <linux/of_pci.h>
#include <linux/platform_device.h>
-#include "pci-host-common.h"
+#include "../ecam.h"
#define PEM_CFG_WR 0x28
#define PEM_CFG_RD 0x30
struct thunder_pem_pci {
- struct gen_pci gen_pci;
u32 ea_entry[3];
void __iomem *pem_reg_base;
};
-static void __iomem *thunder_pem_map_bus(struct pci_bus *bus,
- unsigned int devfn, int where)
-{
- struct gen_pci *pci = bus->sysdata;
- resource_size_t idx = bus->number - pci->cfg.bus_range->start;
-
- return pci->cfg.win[idx] + ((devfn << 16) | where);
-}
-
static int thunder_pem_bridge_read(struct pci_bus *bus, unsigned int devfn,
int where, int size, u32 *val)
{
u64 read_val;
- struct thunder_pem_pci *pem_pci;
- struct gen_pci *pci = bus->sysdata;
-
- pem_pci = container_of(pci, struct thunder_pem_pci, gen_pci);
+ struct pci_config_window *cfg = bus->sysdata;
+ struct thunder_pem_pci *pem_pci = (struct thunder_pem_pci *)cfg->priv;
if (devfn != 0 || where >= 2048) {
*val = ~0;
@@ -132,17 +120,17 @@ static int thunder_pem_bridge_read(struct pci_bus *bus, unsigned int devfn,
static int thunder_pem_config_read(struct pci_bus *bus, unsigned int devfn,
int where, int size, u32 *val)
{
- struct gen_pci *pci = bus->sysdata;
+ struct pci_config_window *cfg = bus->sysdata;
- if (bus->number < pci->cfg.bus_range->start ||
- bus->number > pci->cfg.bus_range->end)
+ if (bus->number < cfg->bus_start ||
+ bus->number > cfg->bus_end)
return PCIBIOS_DEVICE_NOT_FOUND;
/*
* The first device on the bus is the PEM PCIe bridge.
* Special case its config access.
*/
- if (bus->number == pci->cfg.bus_range->start)
+ if (bus->number == cfg->bus_start)
return thunder_pem_bridge_read(bus, devfn, where, size, val);
return pci_generic_config_read(bus, devfn, where, size, val);
@@ -187,12 +175,11 @@ static u32 thunder_pem_bridge_w1c_bits(int where)
static int thunder_pem_bridge_write(struct pci_bus *bus, unsigned int devfn,
int where, int size, u32 val)
{
- struct gen_pci *pci = bus->sysdata;
- struct thunder_pem_pci *pem_pci;
+ struct pci_config_window *cfg = bus->sysdata;
+ struct thunder_pem_pci *pem_pci = (struct thunder_pem_pci *)cfg->priv;
u64 write_val, read_val;
u32 mask = 0;
- pem_pci = container_of(pci, struct thunder_pem_pci, gen_pci);
if (devfn != 0 || where >= 2048)
return PCIBIOS_DEVICE_NOT_FOUND;
@@ -256,53 +243,34 @@ static int thunder_pem_bridge_write(struct pci_bus *bus, unsigned int devfn,
static int thunder_pem_config_write(struct pci_bus *bus, unsigned int devfn,
int where, int size, u32 val)
{
- struct gen_pci *pci = bus->sysdata;
+ struct pci_config_window *cfg = bus->sysdata;
- if (bus->number < pci->cfg.bus_range->start ||
- bus->number > pci->cfg.bus_range->end)
+ if (bus->number < cfg->bus_start ||
+ bus->number > cfg->bus_end)
return PCIBIOS_DEVICE_NOT_FOUND;
/*
* The first device on the bus is the PEM PCIe bridge.
* Special case its config access.
*/
- if (bus->number == pci->cfg.bus_range->start)
+ if (bus->number == cfg->bus_start)
return thunder_pem_bridge_write(bus, devfn, where, size, val);
return pci_generic_config_write(bus, devfn, where, size, val);
}
-static struct gen_pci_cfg_bus_ops thunder_pem_bus_ops = {
- .bus_shift = 24,
- .ops = {
- .map_bus = thunder_pem_map_bus,
- .read = thunder_pem_config_read,
- .write = thunder_pem_config_write,
- }
-};
-
-static const struct of_device_id thunder_pem_of_match[] = {
- { .compatible = "cavium,pci-host-thunder-pem",
- .data = &thunder_pem_bus_ops },
-
- { },
-};
-MODULE_DEVICE_TABLE(of, thunder_pem_of_match);
-
-static int thunder_pem_probe(struct platform_device *pdev)
+static int thunder_pem_init(struct device *dev, struct pci_config_window *cfg)
{
- struct device *dev = &pdev->dev;
- const struct of_device_id *of_id;
resource_size_t bar4_start;
struct resource *res_pem;
struct thunder_pem_pci *pem_pci;
+ struct platform_device *pdev;
pem_pci = devm_kzalloc(dev, sizeof(*pem_pci), GFP_KERNEL);
if (!pem_pci)
return -ENOMEM;
- of_id = of_match_node(thunder_pem_of_match, dev->of_node);
- pem_pci->gen_pci.cfg.ops = (struct gen_pci_cfg_bus_ops *)of_id->data;
+ pdev = to_platform_device(dev);
/*
* The second register range is the PEM bridge to the PCIe
@@ -330,7 +298,29 @@ static int thunder_pem_probe(struct platform_device *pdev)
pem_pci->ea_entry[1] = (u32)(res_pem->end - bar4_start) & ~3u;
pem_pci->ea_entry[2] = (u32)(bar4_start >> 32);
- return pci_host_common_probe(pdev, &pem_pci->gen_pci);
+ cfg->priv = pem_pci;
+ return 0;
+}
+
+static struct pci_generic_ecam_ops pci_thunder_pem_ops = {
+ .bus_shift = 24,
+ .init = thunder_pem_init,
+ .pci_ops = {
+ .map_bus = pci_generic_ecam_map_bus,
+ .read = thunder_pem_config_read,
+ .write = thunder_pem_config_write,
+ }
+};
+
+static const struct of_device_id thunder_pem_of_match[] = {
+ { .compatible = "cavium,pci-host-thunder-pem" },
+ { },
+};
+MODULE_DEVICE_TABLE(of, thunder_pem_of_match);
+
+static int thunder_pem_probe(struct platform_device *pdev)
+{
+ return pci_host_common_probe(pdev, &pci_thunder_pem_ops);
}
static struct platform_driver thunder_pem_driver = {
--
1.9.1
[toc] | [prev] | [next] | [standalone]
| From | Arnd Bergmann <arnd@arndb.de> |
|---|---|
| Date | 2016-04-15 20:50 +0200 |
| Subject | Re: [PATCH V6 08/13] PCI: generic, thunder: update to use generic ECAM API |
| Message-ID | <rogYy-7wu-17@gated-at.bofh.it> |
| In reply to | #1380029 |
On Friday 15 April 2016 19:06:43 Tomasz Nowicki wrote:
> -MODULE_DEVICE_TABLE(of, thunder_pem_of_match);
> -
> -static int thunder_pem_probe(struct platform_device *pdev)
> +static int thunder_pem_init(struct device *dev, struct pci_config_window *cfg)
> {
> - struct device *dev = &pdev->dev;
> - const struct of_device_id *of_id;
> resource_size_t bar4_start;
> struct resource *res_pem;
> struct thunder_pem_pci *pem_pci;
> + struct platform_device *pdev;
>
> pem_pci = devm_kzalloc(dev, sizeof(*pem_pci), GFP_KERNEL);
> if (!pem_pci)
> return -ENOMEM;
>
> - of_id = of_match_node(thunder_pem_of_match, dev->of_node);
> - pem_pci->gen_pci.cfg.ops = (struct gen_pci_cfg_bus_ops *)of_id->data;
> + pdev = to_platform_device(dev);
>
> /*
> * The second register range is the PEM bridge to the PCIe
> @@ -330,7 +298,29 @@ static int thunder_pem_probe(struct platform_device *pdev)
> pem_pci->ea_entry[1] = (u32)(res_pem->end - bar4_start) & ~3u;
> pem_pci->ea_entry[2] = (u32)(bar4_start >> 32);
>
> - return pci_host_common_probe(pdev, &pem_pci->gen_pci);
> + cfg->priv = pem_pci;
> + return 0;
> +}
> +
>
I still think it would be better to keep the loadable PCI host drivers
separate from the ACPI PCI infrastructure. There are a number of
simplifications that we want to do to the DT based drivers in the long
run, so it's better if that code is not shared at this level. Abstracting
out the ECAM code is fine, but at that point you should be able to just
call it from the ACPI layer.
Arnd
[toc] | [prev] | [next] | [standalone]
Page 1 of 4 [1] 2 3 4 Next page →
Back to top | Article view | linux.kernel
csiph-web