Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1447169 > unrolled thread
| Started by | Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> |
|---|---|
| First post | 2016-07-20 13:30 +0200 |
| Last post | 2016-07-25 10:40 +0200 |
| Articles | 18 — 3 participants |
Back to article view | Back to linux.kernel
[RFC PATCH v3 00/13] ACPI IORT ARM SMMU v3 support Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> - 2016-07-20 13:30 +0200
[RFC PATCH v3 06/13] drivers: acpi: implement acpi_dma_configure Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> - 2016-07-20 13:30 +0200
[RFC PATCH v3 04/13] drivers: platform: add fwnode base platform devices retrieval Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> - 2016-07-20 13:30 +0200
[RFC PATCH v3 07/13] drivers: acpi: iort: add node match function Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> - 2016-07-20 13:30 +0200
[RFC PATCH v3 10/13] drivers: iommu: arm-smmu-v3: enable ACPI driver initialization Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> - 2016-07-20 13:30 +0200
[RFC PATCH v3 02/13] drivers: acpi: iort: introduce linker section for IORT entries probing Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> - 2016-07-20 13:30 +0200
[RFC PATCH v3 01/13] drivers: iommu: add FWNODE_IOMMU fwnode type Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> - 2016-07-20 13:30 +0200
[RFC PATCH v3 13/13] drivers: acpi: iort: introduce iort_iommu_configure Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> - 2016-07-20 13:30 +0200
[RFC PATCH v3 09/13] drivers: iommu: arm-smmu-v3: split probe functions into DT/generic portions Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> - 2016-07-20 13:30 +0200
[RFC PATCH v3 11/13] drivers: iommu: arm-smmu-v3: add IORT platform device creation Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> - 2016-07-20 13:30 +0200
[RFC PATCH v3 05/13] drivers: iommu: make iommu_fwspec OF agnostic Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> - 2016-07-20 13:30 +0200
Re: [RFC PATCH v3 05/13] drivers: iommu: make iommu_fwspec OF agnostic Robin Murphy <robin.murphy@arm.com> - 2016-07-25 17:20 +0200
Re: [RFC PATCH v3 05/13] drivers: iommu: make iommu_fwspec OF agnostic Rob Herring <robh@kernel.org> - 2016-07-25 17:30 +0200
Re: [RFC PATCH v3 05/13] drivers: iommu: make iommu_fwspec OF agnostic Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> - 2016-07-25 18:00 +0200
Re: [RFC PATCH v3 05/13] drivers: iommu: make iommu_fwspec OF agnostic Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> - 2016-07-25 17:50 +0200
Re: [RFC PATCH v3 05/13] drivers: iommu: make iommu_fwspec OF agnostic Robin Murphy <robin.murphy@arm.com> - 2016-07-25 18:00 +0200
Re: [RFC PATCH v3 05/13] drivers: iommu: make iommu_fwspec OF agnostic Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> - 2016-07-25 18:20 +0200
Re: [RFC PATCH v3 00/13] ACPI IORT ARM SMMU v3 support Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> - 2016-07-25 10:40 +0200
| From | Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> |
|---|---|
| Date | 2016-07-20 13:30 +0200 |
| Subject | [RFC PATCH v3 00/13] ACPI IORT ARM SMMU v3 support |
| Message-ID | <rWXRn-M3-5@gated-at.bofh.it> |
This RFC patch series is v3 of a previous posting:
https://lkml.org/lkml/2016/6/7/523
v2 -> v3
- Rebased on top of dependencies series [1][2][3](v4.7-rc3)
- Added back reliance on ACPI early probing infrastructure
- Patch[1-3] merged through other dependent series
- Added back IOMMU fwnode generalization
- Move SMMU v3 static functions configuration to IORT code
- Implemented generic IOMMU fwspec API
- Added code to implement fwnode platform device look-up
v1 -> v2:
- Rebased on top of dependencies series [1][2][3](v4.7-rc1)
- Removed IOMMU fwnode generalization
- Implemented ARM SMMU v3 ACPI probing instead of ARM SMMU v2
owing to patch series dependencies [1]
- Moved platform device creation logic to IORT code to
generalize its usage for ARM SMMU v1-v2-v3 components
- Removed reliance on ACPI early device probing
- Created IORT specific iommu_xlate() translation hook leaving
OF code unchanged according to v1 reviews
The ACPI IORT table provides information that allows instantiating
ARM SMMU devices and carrying out id mappings between components on
ARM based systems (devices, IOMMUs, interrupt controllers).
http://infocenter.arm.com/help/topic/com.arm.doc.den0049b/DEN0049B_IO_Remapping_Table.pdf
Building on basic IORT support, available through [2]:
this patchset enables ARM SMMU v3 support on ACPI systems.
Most of the code is aimed at building the required generic ACPI
infrastructure to create and enable IOMMU components and to bring
the IOMMU infrastructure for ACPI on par with DT, which is going to
make future ARM SMMU components easier to integrate.
PATCH (1) adds a FWNODE_IOMMU type to the struct fwnode_handle type.
It is required to attach a fwnode identifier to platform
devices allocated/detected through IORT tables entries;
IOMMU devices have to have an identifier to look them up
eg IOMMU core layer carrying out id translation. This can be
done through a fwnode_handle (ie IOMMU platform devices created
out of IORT tables are not ACPI devices hence they can't be
allocated as such, otherwise they would have a fwnode_handle of
type FWNODE_ACPI). This patch requires discussion and it is key
to the RFC.
PATCH (2) makes use of the ACPI early probing API to add a linker script
section for probing devices via IORT ACPI kernel code.
PATCH (3) provides IORT support for registering IOMMU IORT node through
their fwnode handle.
PATCH (4) implements core code fwnode based platform devices look-up.
PATCH (5) extends iommu_fwspec so that it can be used on ACPI based
system by creating a generic IOMMU fwspec kernel layer.
PATCH (6) implements the of_dma_configure() API in ACPI world -
acpi_dma_configure() - and patches PCI and ACPI core code to
start making use of it.
PATCH (7) provides an IORT function to detect existence of specific type
of IORT components.
PATCH (8) creates the kernel infrastructure required to create ARM SMMU
platform devices for IORT nodes.
PATCH (9) refactors the ARM SMMU v3 driver so that the init functions are
split in a way that groups together code that probes through DT
and code that carries out HW registers FW agnostic probing, in
preparation for adding the ACPI probing path.
PATCH (10) rework ARM SMMU v3 platform driver registration to make it work
on ACPI systems.
PATCH (11) Building on patch (8), it adds ARM SMMU v3 IORT IOMMU
operations to create and probe ARM SMMU v3 components.
PATCH (12) Extend the IORT iort_node_map_rid() to work on a type mask
instead of a single type so that the translation API can
be used on a range of components.
PATCH (13) provides IORT infrastructure to carry out IOMMU configuration
for devices and hook it up to the previously introduced ACPI
DMA configure API.
This patchset is built on top and depends on these three patch series:
[1] R.Murphy "Generic DT bindings for PCI and ARM SMMU v3" v4
https://marc.info/?l=devicetree&m=146739193215518&w=2
[2] T.Nowicki "Introduce ACPI world to ITS irqchip" v7
https://marc.info/?l=linux-arm-kernel&m=146642080022289&w=2
[3] T.Nowicki "Support for ARM64 ACPI based PCI host controller" v8
http://marc.info/?l=linux-acpi&m=146462129816292&w=2
and is provided for early review/testing purposes here:
git://git.kernel.org/pub/scm/linux/kernel/git/lpieralisi/linux.git acpi/iort-smmu-v3
Tested on FVP models for ARM SMMU v3 probing path.
Lorenzo Pieralisi (13):
drivers: iommu: add FWNODE_IOMMU fwnode type
drivers: acpi: iort: introduce linker section for IORT entries probing
drivers: acpi: iort: add support for IOMMU fwnode registration
drivers: platform: add fwnode base platform devices retrieval
drivers: iommu: make iommu_fwspec OF agnostic
drivers: acpi: implement acpi_dma_configure
drivers: acpi: iort: add node match function
drivers: acpi: iort: add support for ARM SMMU platform devices
creation
drivers: iommu: arm-smmu-v3: split probe functions into DT/generic
portions
drivers: iommu: arm-smmu-v3: enable ACPI driver initialization
drivers: iommu: arm-smmu-v3: add IORT platform device creation
drivers: acpi: iort: replace rid map type with type mask
drivers: acpi: iort: introduce iort_iommu_configure
drivers/acpi/glue.c | 4 +-
drivers/acpi/iort.c | 360 +++++++++++++++++++++++++++++++++++++-
drivers/acpi/scan.c | 29 +++
drivers/base/platform.c | 23 +++
drivers/iommu/Kconfig | 4 +
drivers/iommu/Makefile | 1 +
drivers/iommu/arm-smmu-v3.c | 147 ++++++++++++++--
drivers/iommu/iommu-fwspec.c | 114 ++++++++++++
drivers/iommu/of_iommu.c | 52 ------
drivers/pci/probe.c | 3 +-
include/acpi/acpi_bus.h | 2 +
include/asm-generic/vmlinux.lds.h | 1 +
include/linux/acpi.h | 5 +
include/linux/fwnode.h | 1 +
include/linux/iommu-fwspec.h | 60 +++++++
include/linux/iommu.h | 25 +++
include/linux/iort.h | 19 ++
include/linux/of_iommu.h | 24 +--
include/linux/platform_device.h | 3 +
19 files changed, 782 insertions(+), 95 deletions(-)
create mode 100644 drivers/iommu/iommu-fwspec.c
create mode 100644 include/linux/iommu-fwspec.h
--
2.6.4
[toc] | [next] | [standalone]
| From | Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> |
|---|---|
| Date | 2016-07-20 13:30 +0200 |
| Subject | [RFC PATCH v3 06/13] drivers: acpi: implement acpi_dma_configure |
| Message-ID | <rWXRn-M3-7@gated-at.bofh.it> |
| In reply to | #1447169 |
On DT based systems, the of_dma_configure() API implements DMA
configuration for a given device. On ACPI systems an API equivalent to
of_dma_configure() is missing which implies that it is currently not
possible to set-up DMA operations for devices through the ACPI generic
kernel layer.
This patch fills the gap by introducing acpi_dma_configure/deconfigure()
calls that for now are just wrappers around arch_setup_dma_ops() and
arch_teardown_dma_ops() and also updates ACPI and PCI core code to use
the newly introduced acpi_dma_configure/acpi_dma_deconfigure functions.
The DMA range size passed to arch_setup_dma_ops() is sized according
to the device coherent_dma_mask (starting at address 0x0), mirroring the
DT probing path behaviour when a dma-ranges property is not provided
for the device being probed; this changes the current arch_setup_dma_ops()
call parameters in the ACPI probing case, but since arch_setup_dma_ops()
is a NOP on all architectures but ARM/ARM64 this patch does not change
the current kernel behaviour on them.
Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Acked-by: Bjorn Helgaas <bhelgaas@google.com> [pci]
Cc: Bjorn Helgaas <bhelgaas@google.com>
Cc: Robin Murphy <robin.murphy@arm.com>
Cc: Tomasz Nowicki <tn@semihalf.com>
Cc: Joerg Roedel <joro@8bytes.org>
Cc: "Rafael J. Wysocki" <rjw@rjwysocki.net>
---
drivers/acpi/glue.c | 4 ++--
drivers/acpi/scan.c | 24 ++++++++++++++++++++++++
drivers/pci/probe.c | 3 +--
include/acpi/acpi_bus.h | 2 ++
include/linux/acpi.h | 5 +++++
5 files changed, 34 insertions(+), 4 deletions(-)
diff --git a/drivers/acpi/glue.c b/drivers/acpi/glue.c
index 5ea5dc2..f8d6564 100644
--- a/drivers/acpi/glue.c
+++ b/drivers/acpi/glue.c
@@ -227,8 +227,7 @@ int acpi_bind_one(struct device *dev, struct acpi_device *acpi_dev)
attr = acpi_get_dma_attr(acpi_dev);
if (attr != DEV_DMA_NOT_SUPPORTED)
- arch_setup_dma_ops(dev, 0, 0, NULL,
- attr == DEV_DMA_COHERENT);
+ acpi_dma_configure(dev, attr);
acpi_physnode_link_name(physical_node_name, node_id);
retval = sysfs_create_link(&acpi_dev->dev.kobj, &dev->kobj,
@@ -251,6 +250,7 @@ int acpi_bind_one(struct device *dev, struct acpi_device *acpi_dev)
return 0;
err:
+ acpi_dma_deconfigure(dev);
ACPI_COMPANION_SET(dev, NULL);
put_device(dev);
put_device(&acpi_dev->dev);
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index 5f28cf7..b4b9064 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -1358,6 +1358,30 @@ enum dev_dma_attr acpi_get_dma_attr(struct acpi_device *adev)
return DEV_DMA_NON_COHERENT;
}
+/**
+ * acpi_dma_configure - Set-up DMA configuration for the device.
+ * @dev: The pointer to the device
+ * @attr: device dma attributes
+ */
+void acpi_dma_configure(struct device *dev, enum dev_dma_attr attr)
+{
+ /*
+ * Assume dma valid range starts at 0 and covers the whole
+ * coherent_dma_mask.
+ */
+ arch_setup_dma_ops(dev, 0, dev->coherent_dma_mask + 1, NULL,
+ attr == DEV_DMA_COHERENT);
+}
+
+/**
+ * acpi_dma_deconfigure - Tear-down DMA configuration for the device.
+ * @dev: The pointer to the device
+ */
+void acpi_dma_deconfigure(struct device *dev)
+{
+ arch_teardown_dma_ops(dev);
+}
+
static void acpi_init_coherency(struct acpi_device *adev)
{
unsigned long long cca = 0;
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index 380d46d..7ef3933 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -1725,8 +1725,7 @@ static void pci_dma_configure(struct pci_dev *dev)
if (attr == DEV_DMA_NOT_SUPPORTED)
dev_warn(&dev->dev, "DMA not supported.\n");
else
- arch_setup_dma_ops(&dev->dev, 0, 0, NULL,
- attr == DEV_DMA_COHERENT);
+ acpi_dma_configure(&dev->dev, attr);
}
pci_put_host_bridge_device(bridge);
diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h
index 788c6c35..8b5039a 100644
--- a/include/acpi/acpi_bus.h
+++ b/include/acpi/acpi_bus.h
@@ -566,6 +566,8 @@ struct acpi_pci_root {
bool acpi_dma_supported(struct acpi_device *adev);
enum dev_dma_attr acpi_get_dma_attr(struct acpi_device *adev);
+void acpi_dma_configure(struct device *dev, enum dev_dma_attr attr);
+void acpi_dma_deconfigure(struct device *dev);
struct acpi_device *acpi_find_child_device(struct acpi_device *parent,
u64 address, bool check_children);
diff --git a/include/linux/acpi.h b/include/linux/acpi.h
index 288fac5..135a452 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -676,6 +676,11 @@ static inline enum dev_dma_attr acpi_get_dma_attr(struct acpi_device *adev)
return DEV_DMA_NOT_SUPPORTED;
}
+static inline void acpi_dma_configure(struct device *dev,
+ enum dev_dma_attr attr) { }
+
+static inline void acpi_dma_deconfigure(struct device *dev) { }
+
#define ACPI_PTR(_ptr) (NULL)
#endif /* !CONFIG_ACPI */
--
2.6.4
[toc] | [prev] | [next] | [standalone]
| From | Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> |
|---|---|
| Date | 2016-07-20 13:30 +0200 |
| Subject | [RFC PATCH v3 04/13] drivers: platform: add fwnode base platform devices retrieval |
| Message-ID | <rWXRn-M3-19@gated-at.bofh.it> |
| In reply to | #1447169 |
The platform device kernel API does not provide functions to
retrieve a platform device through the corresponding struct
device fwnode pointer.
Implement the fwnode platform_device look-up in drivers core
code by using the bus_find_device() API and a corresponding
matching function. The OF equivalent (eg of_find_device_by_node())
will reuse the newly introduced function when OF code will
take care of setting up the device->fwnode value that is
currently left dangling for platform devices instantiated out
of device tree nodes.
Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: "Rafael J. Wysocki" <rjw@rjwysocki.net>
---
drivers/base/platform.c | 23 +++++++++++++++++++++++
include/linux/platform_device.h | 3 +++
2 files changed, 26 insertions(+)
diff --git a/drivers/base/platform.c b/drivers/base/platform.c
index 6482d47..3ef150d 100644
--- a/drivers/base/platform.c
+++ b/drivers/base/platform.c
@@ -760,6 +760,29 @@ err_out:
}
EXPORT_SYMBOL_GPL(__platform_create_bundle);
+static int fwnode_dev_match(struct device *dev, void *data)
+{
+ return dev->fwnode == data;
+}
+
+/**
+ * platform_find_device_by_fwnode() - Find the platform_device associated
+ * with a fwnode
+ * @fwnode: Pointer to firmware node
+ *
+ * Returns platform_device pointer, or NULL if not found
+ */
+struct platform_device *
+platform_find_device_by_fwnode(struct fwnode_handle *fwnode)
+{
+ struct device *dev;
+
+ dev = bus_find_device(&platform_bus_type, NULL, fwnode,
+ fwnode_dev_match);
+ return dev ? to_platform_device(dev) : NULL;
+}
+EXPORT_SYMBOL(platform_find_device_by_fwnode);
+
/**
* __platform_register_drivers - register an array of platform drivers
* @drivers: an array of drivers to register
diff --git a/include/linux/platform_device.h b/include/linux/platform_device.h
index 98c2a7c..01a3eb2 100644
--- a/include/linux/platform_device.h
+++ b/include/linux/platform_device.h
@@ -276,6 +276,9 @@ extern struct platform_device *__platform_create_bundle(
struct resource *res, unsigned int n_res,
const void *data, size_t size, struct module *module);
+extern struct platform_device *
+platform_find_device_by_fwnode(struct fwnode_handle *fwnode);
+
int __platform_register_drivers(struct platform_driver * const *drivers,
unsigned int count, struct module *owner);
void platform_unregister_drivers(struct platform_driver * const *drivers,
--
2.6.4
[toc] | [prev] | [next] | [standalone]
| From | Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> |
|---|---|
| Date | 2016-07-20 13:30 +0200 |
| Subject | [RFC PATCH v3 07/13] drivers: acpi: iort: add node match function |
| Message-ID | <rWXRo-M3-21@gated-at.bofh.it> |
| In reply to | #1447169 |
Device drivers (eg ARM SMMU) need to know if a specific component
is part of the IORT table, so that kernel data structures are not
initialized at initcalls time if the respective component is not
part of the IORT table.
To this end, this patch adds a trivial function that allows detecting
if a given IORT node type is present or not in the ACPI table, providing
an ACPI IORT equivalent for of_find_matching_node().
Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Cc: Hanjun Guo <hanjun.guo@linaro.org>
Cc: Tomasz Nowicki <tn@semihalf.com>
Cc: "Rafael J. Wysocki" <rjw@rjwysocki.net>
---
drivers/acpi/iort.c | 15 +++++++++++++++
include/linux/iort.h | 2 ++
2 files changed, 17 insertions(+)
diff --git a/drivers/acpi/iort.c b/drivers/acpi/iort.c
index 86f6985..71516e8 100644
--- a/drivers/acpi/iort.c
+++ b/drivers/acpi/iort.c
@@ -205,6 +205,21 @@ iort_scan_node(enum acpi_iort_node_type type,
}
static acpi_status
+iort_match_callback(struct acpi_iort_node *node, void *context)
+{
+ return AE_OK;
+}
+
+bool iort_node_match(u8 type)
+{
+ struct acpi_iort_node *node;
+
+ node = iort_scan_node(type, iort_match_callback, NULL);
+
+ return node != NULL;
+}
+
+static acpi_status
iort_match_node_callback(struct acpi_iort_node *node, void *context)
{
struct device *dev = context;
diff --git a/include/linux/iort.h b/include/linux/iort.h
index 9bb30c5..ac2706a 100644
--- a/include/linux/iort.h
+++ b/include/linux/iort.h
@@ -27,10 +27,12 @@ int iort_register_domain_token(int trans_id, struct fwnode_handle *fw_node);
void iort_deregister_domain_token(int trans_id);
struct fwnode_handle *iort_find_domain_token(int trans_id);
#ifdef CONFIG_IORT_TABLE
+bool iort_node_match(u8 type);
void iort_table_detect(void);
u32 iort_msi_map_rid(struct device *dev, u32 req_id);
struct irq_domain *iort_get_device_domain(struct device *dev, u32 req_id);
#else
+static inline bool iort_node_match(u8 type) { return false; }
static inline void iort_table_detect(void) { }
static inline u32 iort_msi_map_rid(struct device *dev, u32 req_id)
{ return req_id; }
--
2.6.4
[toc] | [prev] | [next] | [standalone]
| From | Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> |
|---|---|
| Date | 2016-07-20 13:30 +0200 |
| Subject | [RFC PATCH v3 10/13] drivers: iommu: arm-smmu-v3: enable ACPI driver initialization |
| Message-ID | <rWXRo-M3-25@gated-at.bofh.it> |
| In reply to | #1447169 |
On systems booting with ACPI that enable the ARM SMMU components
in the kernel config options, the ARM SMMU v3 init function
(ie arm_smmu_init(), that registers the driver and sets-up bus
iommu operations) does not run only because the device tree interface
(of_find_matching_node()) fails to find the respective device tree
nodes for ARM SMMU devices.
This works as long as there are no ARM SMMU devices to be probed
with ACPI. If ARM SMMU v3 components are part of the IORT tables,
for them to be instantiated and probed the function registering
the ARM SMMU v3 driver must be able to register the driver and
initialize the bus IOMMU operations accordingly.
This patch changes the logic in arm-smmu-v3 init call to allow
for it to be probed in ACPI systems.
Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Acked-by: Will Deacon <will.deacon@arm.com>
Cc: Will Deacon <will.deacon@arm.com>
Cc: Robin Murphy <robin.murphy@arm.com>
Cc: Joerg Roedel <joro@8bytes.org>
---
drivers/iommu/arm-smmu-v3.c | 13 +++++++++----
1 file changed, 9 insertions(+), 4 deletions(-)
diff --git a/drivers/iommu/arm-smmu-v3.c b/drivers/iommu/arm-smmu-v3.c
index 15e74da..1a4e9ce 100644
--- a/drivers/iommu/arm-smmu-v3.c
+++ b/drivers/iommu/arm-smmu-v3.c
@@ -2689,11 +2689,16 @@ static int __init arm_smmu_init(void)
struct device_node *np;
int ret;
- np = of_find_matching_node(NULL, arm_smmu_of_match);
- if (!np)
- return 0;
+ if (acpi_disabled) {
+ np = of_find_matching_node(NULL, arm_smmu_of_match);
+ if (!np)
+ return 0;
- of_node_put(np);
+ of_node_put(np);
+ } else {
+ if (!iort_node_match(ACPI_IORT_NODE_SMMU_V3))
+ return 0;
+ }
ret = platform_driver_register(&arm_smmu_driver);
if (ret)
--
2.6.4
[toc] | [prev] | [next] | [standalone]
| From | Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> |
|---|---|
| Date | 2016-07-20 13:30 +0200 |
| Subject | [RFC PATCH v3 02/13] drivers: acpi: iort: introduce linker section for IORT entries probing |
| Message-ID | <rWXRo-M3-29@gated-at.bofh.it> |
| In reply to | #1447169 |
Since commit e647b532275b ("ACPI: Add early device probing
infrastructure") the kernel has gained the infrastructure that allows
adding linker script section entries to execute ACPI driver callbacks
(ie probe routines) for all subsystems that register a table entry
in the respective kernel section (eg clocksource, irqchip).
Since ARM IOMMU devices data is described through IORT tables when
booting with ACPI, the ARM IOMMU drivers must be made able to hook ACPI
callback routines that are called to probe IORT entries and initialize
the respective IOMMU devices.
To avoid adding driver specific hooks into IORT table initialization
code (breaking therefore code modularity - ie ACPI IORT code must be made
aware of ARM SMMU drivers ACPI init callbacks), this patch adds code
that allows ARM SMMU drivers to take advantage of the ACPI early probing
infrastructure, so that they can add linker script section entries
containing drivers callback to be executed on IORT tables detection.
Since IORT nodes are differentiated by a type, the callback routines
can easily parse the IORT table entries, check the IORT nodes and
carry out some actions whenever the IORT node type associated with
the driver specific callback is matched.
Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Cc: Tomasz Nowicki <tn@semihalf.com>
Cc: "Rafael J. Wysocki" <rjw@rjwysocki.net>
Cc: Marc Zyngier <marc.zyngier@arm.com>
---
drivers/acpi/iort.c | 2 ++
include/asm-generic/vmlinux.lds.h | 1 +
include/linux/iort.h | 3 +++
3 files changed, 6 insertions(+)
diff --git a/drivers/acpi/iort.c b/drivers/acpi/iort.c
index 6611607..1f440d2 100644
--- a/drivers/acpi/iort.c
+++ b/drivers/acpi/iort.c
@@ -383,4 +383,6 @@ void __init iort_table_detect(void)
const char *msg = acpi_format_exception(status);
pr_err("Failed to get table, %s\n", msg);
}
+
+ acpi_probe_device_table(iort);
}
diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h
index 6a67ab9..b896ab2 100644
--- a/include/asm-generic/vmlinux.lds.h
+++ b/include/asm-generic/vmlinux.lds.h
@@ -538,6 +538,7 @@
IRQCHIP_OF_MATCH_TABLE() \
ACPI_PROBE_TABLE(irqchip) \
ACPI_PROBE_TABLE(clksrc) \
+ ACPI_PROBE_TABLE(iort) \
EARLYCON_TABLE()
#define INIT_TEXT \
diff --git a/include/linux/iort.h b/include/linux/iort.h
index d7daba1..9bb30c5 100644
--- a/include/linux/iort.h
+++ b/include/linux/iort.h
@@ -38,4 +38,7 @@ static inline struct irq_domain *
iort_get_device_domain(struct device *dev, u32 req_id) { return NULL; }
#endif
+#define IORT_ACPI_DECLARE(name, table_id, fn) \
+ ACPI_DECLARE_PROBE_ENTRY(iort, name, table_id, 0, NULL, 0, fn)
+
#endif /* __IORT_H__ */
--
2.6.4
[toc] | [prev] | [next] | [standalone]
| From | Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> |
|---|---|
| Date | 2016-07-20 13:30 +0200 |
| Subject | [RFC PATCH v3 01/13] drivers: iommu: add FWNODE_IOMMU fwnode type |
| Message-ID | <rWXRo-M3-41@gated-at.bofh.it> |
| In reply to | #1447169 |
On systems booting with a device tree, every struct device is
associated with a struct device_node, that represents its DT
representation. The device node can be used in generic kernel
contexts (eg IRQ translation, IOMMU streamid mapping), to
retrieve the properties associated with the device and carry
out kernel operation accordingly. Owing to the 1:1 relationship
between the device and its device_node, the device_node can also
be used as a look-up token for the device (eg looking up a device
through its device_node), to retrieve the device in kernel paths
where the device_node is available.
On systems booting with ACPI, the same abstraction provided by
the device_node is required to provide look-up functionality.
Therefore, mirroring the approach implemented in the IRQ domain
kernel layer, this patch adds an additional fwnode type FWNODE_IOMMU.
This patch also implements a glue kernel layer that allows to
allocate/free FWNODE_IOMMU fwnode_handle structures and associate
them with IOMMU devices.
Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Cc: Joerg Roedel <joro@8bytes.org>
Cc: "Rafael J. Wysocki" <rjw@rjwysocki.net>
---
include/linux/fwnode.h | 1 +
include/linux/iommu.h | 25 +++++++++++++++++++++++++
2 files changed, 26 insertions(+)
diff --git a/include/linux/fwnode.h b/include/linux/fwnode.h
index 8516717..6e10050 100644
--- a/include/linux/fwnode.h
+++ b/include/linux/fwnode.h
@@ -19,6 +19,7 @@ enum fwnode_type {
FWNODE_ACPI_DATA,
FWNODE_PDATA,
FWNODE_IRQCHIP,
+ FWNODE_IOMMU,
};
struct fwnode_handle {
diff --git a/include/linux/iommu.h b/include/linux/iommu.h
index 664683a..298328a 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -38,6 +38,7 @@ struct bus_type;
struct device;
struct iommu_domain;
struct notifier_block;
+struct fwnode_handle;
/* iommu fault flags */
#define IOMMU_FAULT_READ 0x0
@@ -540,4 +541,28 @@ static inline void iommu_device_unlink(struct device *dev, struct device *link)
#endif /* CONFIG_IOMMU_API */
+/* IOMMU fwnode handling */
+static inline bool is_fwnode_iommu(struct fwnode_handle *fwnode)
+{
+ return fwnode && fwnode->type == FWNODE_IOMMU;
+}
+
+static inline struct fwnode_handle *iommu_alloc_fwnode(void)
+{
+ struct fwnode_handle *fwnode;
+
+ fwnode = kzalloc(sizeof(struct fwnode_handle), GFP_KERNEL);
+ fwnode->type = FWNODE_IOMMU;
+
+ return fwnode;
+}
+
+static inline void iommu_free_fwnode(struct fwnode_handle *fwnode)
+{
+ if (WARN_ON(!is_fwnode_iommu(fwnode)))
+ return;
+
+ kfree(fwnode);
+}
+
#endif /* __LINUX_IOMMU_H */
--
2.6.4
[toc] | [prev] | [next] | [standalone]
| From | Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> |
|---|---|
| Date | 2016-07-20 13:30 +0200 |
| Subject | [RFC PATCH v3 13/13] drivers: acpi: iort: introduce iort_iommu_configure |
| Message-ID | <rWXRo-M3-39@gated-at.bofh.it> |
| In reply to | #1447169 |
DT based systems have a generic kernel API to configure IOMMUs
for devices (ie of_iommu_configure()).
On ARM based ACPI systems, the of_iommu_configure() equivalent can
be implemented atop ACPI IORT kernel API, with the corresponding
functions to map device identifiers to IOMMUs and retrieve the
corresponding IOMMU operations necessary for DMA operations set-up.
By relying on the iommu_fwspec generic kernel infrastructure,
implement the IORT based IOMMU configuration for ARM ACPI systems
and hook it up in the ACPI kernel layer that implements DMA
configuration for a device.
Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Cc: Hanjun Guo <hanjun.guo@linaro.org>
Cc: Tomasz Nowicki <tn@semihalf.com>
Cc: "Rafael J. Wysocki" <rjw@rjwysocki.net>
---
drivers/acpi/iort.c | 64 ++++++++++++++++++++++++++++++++++++++++++++++++++++
drivers/acpi/scan.c | 7 +++++-
include/linux/iort.h | 4 ++++
3 files changed, 74 insertions(+), 1 deletion(-)
diff --git a/drivers/acpi/iort.c b/drivers/acpi/iort.c
index c116b68..a12a4ff 100644
--- a/drivers/acpi/iort.c
+++ b/drivers/acpi/iort.c
@@ -18,6 +18,7 @@
#define pr_fmt(fmt) "ACPI: IORT: " fmt
+#include <linux/iommu-fwspec.h>
#include <linux/iort.h>
#include <linux/kernel.h>
#include <linux/list.h>
@@ -27,6 +28,8 @@
#define IORT_TYPE_MASK(type) (1 << (type))
#define IORT_MSI_TYPE (1 << ACPI_IORT_NODE_ITS_GROUP)
+#define IORT_IOMMU_TYPE ((1 << ACPI_IORT_NODE_SMMU) | \
+ (1 << ACPI_IORT_NODE_SMMU_V3))
struct iort_its_msi_chip {
struct list_head list;
@@ -458,6 +461,67 @@ iort_get_device_domain(struct device *dev, u32 req_id)
return irq_find_matching_fwnode(handle, DOMAIN_BUS_PCI_MSI);
}
+static int __get_pci_rid(struct pci_dev *pdev, u16 alias, void *data)
+{
+ u32 *rid = data;
+
+ *rid = alias;
+ return 0;
+}
+
+static int arm_smmu_iort_xlate(struct device *dev, u32 streamid,
+ struct fwnode_handle *fwnode)
+{
+ int ret = iommu_fwspec_init(dev, fwnode);
+
+ if (!ret)
+ ret = iommu_fwspec_add_ids(dev, &streamid, 1);
+
+ return 0;
+}
+
+/**
+ * iort_iommu_configure - Set-up IOMMU configuration for a device.
+ *
+ * @dev: device to configure
+ *
+ * Returns: iommu_ops pointer on configuration success
+ * NULL on configuration failure
+ */
+const struct iommu_ops *iort_iommu_configure(struct device *dev)
+{
+ struct acpi_iort_node *node, *parent;
+ struct fwnode_handle *iort_fwnode;
+ u32 rid = 0, devid = 0;
+
+ if (dev_is_pci(dev)) {
+ struct pci_bus *bus = to_pci_dev(dev)->bus;
+
+ pci_for_each_dma_alias(to_pci_dev(dev), __get_pci_rid,
+ &rid);
+
+ node = iort_scan_node(ACPI_IORT_NODE_PCI_ROOT_COMPLEX,
+ iort_match_node_callback, &bus->dev);
+ } else {
+ node = iort_scan_node(ACPI_IORT_NODE_NAMED_COMPONENT,
+ iort_match_node_callback, dev);
+ }
+
+ if (!node)
+ return NULL;
+
+ parent = iort_node_map_rid(node, rid, &devid, IORT_IOMMU_TYPE);
+ if (parent) {
+ iort_fwnode = iort_get_fwnode(parent);
+ if (iort_fwnode) {
+ arm_smmu_iort_xlate(dev, devid, iort_fwnode);
+ return fwspec_iommu_get_ops(iort_fwnode);
+ }
+ }
+
+ return NULL;
+}
+
static void acpi_smmu_v3_register_irq(int hwirq, const char *name,
struct resource *res)
{
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index b4b9064..de28825 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -7,6 +7,7 @@
#include <linux/slab.h>
#include <linux/kernel.h>
#include <linux/acpi.h>
+#include <linux/iort.h>
#include <linux/signal.h>
#include <linux/kthread.h>
#include <linux/dmi.h>
@@ -1365,11 +1366,15 @@ enum dev_dma_attr acpi_get_dma_attr(struct acpi_device *adev)
*/
void acpi_dma_configure(struct device *dev, enum dev_dma_attr attr)
{
+ const struct iommu_ops *iommu;
+
+ iommu = iort_iommu_configure(dev);
+
/*
* Assume dma valid range starts at 0 and covers the whole
* coherent_dma_mask.
*/
- arch_setup_dma_ops(dev, 0, dev->coherent_dma_mask + 1, NULL,
+ arch_setup_dma_ops(dev, 0, dev->coherent_dma_mask + 1, iommu,
attr == DEV_DMA_COHERENT);
}
diff --git a/include/linux/iort.h b/include/linux/iort.h
index 18e6836..bbe08ef 100644
--- a/include/linux/iort.h
+++ b/include/linux/iort.h
@@ -34,6 +34,8 @@ struct irq_domain *iort_get_device_domain(struct device *dev, u32 req_id);
/* IOMMU interface */
int iort_add_smmu_platform_device(struct fwnode_handle *fwnode,
struct acpi_iort_node *node);
+
+const struct iommu_ops *iort_iommu_configure(struct device *dev);
#else
static inline bool iort_node_match(u8 type) { return false; }
static inline void iort_table_detect(void) { }
@@ -48,6 +50,8 @@ iort_add_smmu_platform_device(struct fwnode_handle *fwnode,
{
return -ENODEV;
}
+static inline const struct iommu_ops *
+iort_iommu_configure(struct device *dev) { return NULL; }
#endif
#define IORT_ACPI_DECLARE(name, table_id, fn) \
--
2.6.4
[toc] | [prev] | [next] | [standalone]
| From | Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> |
|---|---|
| Date | 2016-07-20 13:30 +0200 |
| Subject | [RFC PATCH v3 09/13] drivers: iommu: arm-smmu-v3: split probe functions into DT/generic portions |
| Message-ID | <rWXRo-M3-43@gated-at.bofh.it> |
| In reply to | #1447169 |
Current ARM SMMUv3 probe functions intermingle HW and DT probing in the
initialization functions to detect and programme the ARM SMMU v3 driver
features. In order to allow probing the ARM SMMUv3 with other firmwares
than DT, this patch splits the ARM SMMUv3 init functions into DT and HW
specific portions so that other FW interfaces (ie ACPI) can reuse the HW
probing functions and skip the DT portion accordingly.
This patch implements no functional change, only code reshuffling.
Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Acked-by: Will Deacon <will.deacon@arm.com>
Cc: Will Deacon <will.deacon@arm.com>
Cc: Hanjun Guo <hanjun.guo@linaro.org>
Cc: Robin Murphy <robin.murphy@arm.com>
Cc: Joerg Roedel <joro@8bytes.org>
---
drivers/iommu/arm-smmu-v3.c | 63 +++++++++++++++++++++++++++++++++++++--------
1 file changed, 52 insertions(+), 11 deletions(-)
diff --git a/drivers/iommu/arm-smmu-v3.c b/drivers/iommu/arm-smmu-v3.c
index 052a26c..15e74da 100644
--- a/drivers/iommu/arm-smmu-v3.c
+++ b/drivers/iommu/arm-smmu-v3.c
@@ -20,6 +20,7 @@
* This driver is powered by bad coffee and bombay mix.
*/
+#include <linux/acpi.h>
#include <linux/delay.h>
#include <linux/dma-iommu.h>
#include <linux/err.h>
@@ -27,6 +28,7 @@
#include <linux/iommu.h>
#include <linux/iommu-fwspec.h>
#include <linux/iopoll.h>
+#include <linux/iort.h>
#include <linux/module.h>
#include <linux/msi.h>
#include <linux/of.h>
@@ -2377,10 +2379,10 @@ static int arm_smmu_device_reset(struct arm_smmu_device *smmu)
return 0;
}
-static int arm_smmu_device_probe(struct arm_smmu_device *smmu)
+static int arm_smmu_device_hw_probe(struct arm_smmu_device *smmu)
{
u32 reg;
- bool coherent;
+ bool coherent = smmu->features & ARM_SMMU_FEAT_COHERENCY;
/* IDR0 */
reg = readl_relaxed(smmu->base + ARM_SMMU_IDR0);
@@ -2432,13 +2434,9 @@ static int arm_smmu_device_probe(struct arm_smmu_device *smmu)
smmu->features |= ARM_SMMU_FEAT_HYP;
/*
- * The dma-coherent property is used in preference to the ID
+ * The coherency feature as set by FW is used in preference to the ID
* register, but warn on mismatch.
*/
- coherent = of_dma_is_coherent(smmu->dev->of_node);
- if (coherent)
- smmu->features |= ARM_SMMU_FEAT_COHERENCY;
-
if (!!(reg & IDR0_COHACC) != coherent)
dev_warn(smmu->dev, "IDR0.COHACC overridden by dma-coherent property (%s)\n",
coherent ? "true" : "false");
@@ -2559,7 +2557,44 @@ static int arm_smmu_device_probe(struct arm_smmu_device *smmu)
return 0;
}
-static int arm_smmu_device_dt_probe(struct platform_device *pdev)
+#ifdef CONFIG_ACPI
+static int arm_smmu_device_acpi_probe(struct platform_device *pdev,
+ struct arm_smmu_device *smmu)
+{
+ struct acpi_iort_smmu_v3 *iort_smmu;
+ struct device *dev = smmu->dev;
+ struct acpi_iort_node *node;
+
+ node = *(struct acpi_iort_node **)dev_get_platdata(dev);
+
+ /* Retrieve SMMUv3 specific data */
+ iort_smmu = (struct acpi_iort_smmu_v3 *)node->node_data;
+
+ if (iort_smmu->flags & ACPI_IORT_SMMU_V3_COHACC_OVERRIDE)
+ smmu->features |= ARM_SMMU_FEAT_COHERENCY;
+
+ return 0;
+}
+#else
+static int arm_smmu_device_acpi_probe(struct platform_device *pdev,
+ struct arm_smmu_device *smmu)
+{
+ return -ENODEV;
+}
+#endif
+
+static int arm_smmu_device_dt_probe(struct platform_device *pdev,
+ struct arm_smmu_device *smmu)
+{
+ parse_driver_options(smmu);
+
+ if (of_dma_is_coherent(smmu->dev->of_node))
+ smmu->features |= ARM_SMMU_FEAT_COHERENCY;
+
+ return 0;
+}
+
+static int arm_smmu_device_probe(struct platform_device *pdev)
{
int irq, ret;
struct resource *res;
@@ -2601,10 +2636,16 @@ static int arm_smmu_device_dt_probe(struct platform_device *pdev)
if (irq > 0)
smmu->gerr_irq = irq;
- parse_driver_options(smmu);
+ if (acpi_disabled)
+ ret = arm_smmu_device_dt_probe(pdev, smmu);
+ else
+ ret = arm_smmu_device_acpi_probe(pdev, smmu);
+
+ if (ret)
+ return ret;
/* Probe the h/w */
- ret = arm_smmu_device_probe(smmu);
+ ret = arm_smmu_device_hw_probe(smmu);
if (ret)
return ret;
@@ -2639,7 +2680,7 @@ static struct platform_driver arm_smmu_driver = {
.name = "arm-smmu-v3",
.of_match_table = of_match_ptr(arm_smmu_of_match),
},
- .probe = arm_smmu_device_dt_probe,
+ .probe = arm_smmu_device_probe,
.remove = arm_smmu_device_remove,
};
--
2.6.4
[toc] | [prev] | [next] | [standalone]
| From | Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> |
|---|---|
| Date | 2016-07-20 13:30 +0200 |
| Subject | [RFC PATCH v3 11/13] drivers: iommu: arm-smmu-v3: add IORT platform device creation |
| Message-ID | <rWXRo-M3-45@gated-at.bofh.it> |
| In reply to | #1447169 |
In ACPI bases systems, in order to be able to create platform
devices and initialize them for ARM SMMU v3 components, the IORT
kernel implementation requires a set of static functions to be
used by the IORT kernel layer to configure platform devices for
ARM SMMU v3 components.
Add static configuration functions to the IORT kernel layer for
the ARM SMMU v3 components, so that the ARM SMMU v3 driver can
initialize its respective platform device by relying on the IORT
kernel infrastructure and by adding a corresponding ACPI device
early probe section entry.
Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Cc: Will Deacon <will.deacon@arm.com>
Cc: Robin Murphy <robin.murphy@arm.com>
Cc: Joerg Roedel <joro@8bytes.org>
---
drivers/acpi/iort.c | 98 ++++++++++++++++++++++++++++++++++++++++++++-
drivers/iommu/arm-smmu-v3.c | 58 +++++++++++++++++++++++++++
2 files changed, 155 insertions(+), 1 deletion(-)
diff --git a/drivers/acpi/iort.c b/drivers/acpi/iort.c
index 23c80c7..c91e45d 100644
--- a/drivers/acpi/iort.c
+++ b/drivers/acpi/iort.c
@@ -455,6 +455,90 @@ iort_get_device_domain(struct device *dev, u32 req_id)
return irq_find_matching_fwnode(handle, DOMAIN_BUS_PCI_MSI);
}
+static void acpi_smmu_v3_register_irq(int hwirq, const char *name,
+ struct resource *res)
+{
+ int irq = acpi_register_gsi(NULL, hwirq, ACPI_EDGE_SENSITIVE,
+ ACPI_ACTIVE_HIGH);
+
+ if (irq < 0) {
+ pr_err("could not register gsi hwirq %d name [%s]\n", hwirq,
+ name);
+ return;
+ }
+
+ res->start = irq;
+ res->end = irq;
+ res->flags = IORESOURCE_IRQ;
+ res->name = name;
+}
+
+static int arm_smmu_v3_count_resources(struct acpi_iort_node *node)
+{
+ struct acpi_iort_smmu_v3 *smmu;
+ /* Always present mem resource */
+ int num_res = 1;
+
+ /* Retrieve SMMUv3 specific data */
+ smmu = (struct acpi_iort_smmu_v3 *)node->node_data;
+
+ if (smmu->event_gsiv)
+ num_res++;
+
+ if (smmu->pri_gsiv)
+ num_res++;
+
+ if (smmu->gerr_gsiv)
+ num_res++;
+
+ if (smmu->sync_gsiv)
+ num_res++;
+
+ return num_res;
+}
+
+static void arm_smmu_v3_init_resources(struct resource *res,
+ struct acpi_iort_node *node)
+{
+ struct acpi_iort_smmu_v3 *smmu;
+ int num_res = 0;
+
+ /* Retrieve SMMUv3 specific data */
+ smmu = (struct acpi_iort_smmu_v3 *)node->node_data;
+
+ res[num_res].start = smmu->base_address;
+ res[num_res].end = smmu->base_address + SZ_128K - 1;
+ res[num_res].flags = IORESOURCE_MEM;
+
+ num_res++;
+
+ if (smmu->event_gsiv)
+ acpi_smmu_v3_register_irq(smmu->event_gsiv, "eventq",
+ &res[num_res++]);
+
+ if (smmu->pri_gsiv)
+ acpi_smmu_v3_register_irq(smmu->pri_gsiv, "priq",
+ &res[num_res++]);
+
+ if (smmu->gerr_gsiv)
+ acpi_smmu_v3_register_irq(smmu->gerr_gsiv, "gerror",
+ &res[num_res++]);
+
+ if (smmu->sync_gsiv)
+ acpi_smmu_v3_register_irq(smmu->sync_gsiv, "cmdq-sync",
+ &res[num_res++]);
+}
+
+static bool arm_smmu_v3_is_coherent(struct acpi_iort_node *node)
+{
+ struct acpi_iort_smmu_v3 *smmu;
+
+ /* Retrieve SMMUv3 specific data */
+ smmu = (struct acpi_iort_smmu_v3 *)node->node_data;
+
+ return smmu->flags & ACPI_IORT_SMMU_V3_COHACC_OVERRIDE;
+}
+
struct iort_iommu_config {
const char *name;
int (*iommu_init)(struct acpi_iort_node *node);
@@ -464,10 +548,22 @@ struct iort_iommu_config {
struct acpi_iort_node *node);
};
+const struct iort_iommu_config iort_arm_smmu_v3_cfg = {
+ .name = "arm-smmu-v3",
+ .iommu_is_coherent = arm_smmu_v3_is_coherent,
+ .iommu_count_resources = arm_smmu_v3_count_resources,
+ .iommu_init_resources = arm_smmu_v3_init_resources
+};
+
static inline const struct iort_iommu_config *
iort_get_iommu_config(struct acpi_iort_node *node)
{
- return NULL;
+ switch (node->type) {
+ case ACPI_IORT_NODE_SMMU_V3:
+ return &iort_arm_smmu_v3_cfg;
+ default:
+ return NULL;
+ }
}
/**
diff --git a/drivers/iommu/arm-smmu-v3.c b/drivers/iommu/arm-smmu-v3.c
index 1a4e9ce..294ed5e 100644
--- a/drivers/iommu/arm-smmu-v3.c
+++ b/drivers/iommu/arm-smmu-v3.c
@@ -1749,6 +1749,8 @@ arm_smmu_get_by_fwnode(struct fwnode_handle *handle)
if (is_of_node(handle))
smmu_pdev = of_find_device_by_node(to_of_node(handle));
+ else if (is_fwnode_iommu(handle))
+ smmu_pdev = platform_find_device_by_fwnode(handle);
if (!smmu_pdev)
return NULL;
@@ -1771,6 +1773,7 @@ static struct iommu_ops arm_smmu_ops;
static int arm_smmu_add_device(struct device *dev)
{
int i, ret;
+
struct arm_smmu_device *smmu;
struct arm_smmu_master_data *master;
struct iommu_fwspec *fwspec = dev_iommu_fwspec(dev);
@@ -2741,6 +2744,61 @@ static int __init arm_smmu_of_init(struct device_node *np)
}
IOMMU_OF_DECLARE(arm_smmuv3, "arm,smmu-v3", arm_smmu_of_init);
+#ifdef CONFIG_ACPI
+static int acpi_smmu_v3_init(struct acpi_table_header *table)
+{
+ struct acpi_iort_node *iort_node, *iort_end;
+ struct acpi_table_iort *iort;
+ struct fwnode_handle *fwnode;
+ int i, ret;
+
+ /*
+ * table and iort will both point to the start of IORT table, but
+ * have different struct types
+ */
+ iort = (struct acpi_table_iort *)table;
+
+ /* Get the first IORT node */
+ iort_node = ACPI_ADD_PTR(struct acpi_iort_node, table,
+ iort->node_offset);
+ iort_end = ACPI_ADD_PTR(struct acpi_iort_node, table,
+ table->length);
+
+ for (i = 0; i < iort->node_count; i++) {
+
+ if (iort_node >= iort_end) {
+ pr_err("iort node pointer overflows, bad table\n");
+ return -EINVAL;
+ }
+
+ if (iort_node->type == ACPI_IORT_NODE_SMMU_V3) {
+ fwnode = iommu_alloc_fwnode();
+
+ if (!fwnode)
+ return -ENOMEM;
+
+ ret = iort_add_smmu_platform_device(fwnode,
+ iort_node);
+ if (ret)
+ goto free;
+
+ fwspec_iommu_set_ops(fwnode, &arm_smmu_ops);
+ }
+
+ iort_node = ACPI_ADD_PTR(struct acpi_iort_node, iort_node,
+ iort_node->length);
+ }
+
+ return 0;
+free:
+ iommu_free_fwnode(fwnode);
+ return ret;
+
+}
+IORT_ACPI_DECLARE(arm_smmu_v3, ACPI_SIG_IORT, acpi_smmu_v3_init);
+
+#endif
+
MODULE_DESCRIPTION("IOMMU API for ARM architected SMMUv3 implementations");
MODULE_AUTHOR("Will Deacon <will.deacon@arm.com>");
MODULE_LICENSE("GPL v2");
--
2.6.4
[toc] | [prev] | [next] | [standalone]
| From | Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> |
|---|---|
| Date | 2016-07-20 13:30 +0200 |
| Subject | [RFC PATCH v3 05/13] drivers: iommu: make iommu_fwspec OF agnostic |
| Message-ID | <rWXRo-M3-49@gated-at.bofh.it> |
| In reply to | #1447169 |
The iommu_fwspec structure, used to hold per device iommu configuration
data is not OF specific and therefore can be moved to a generic
and OF independent compilation unit.
In particular, the iommu_fwspec handling hinges on the device_node
pointer to identify the IOMMU device associated with the iommu_fwspec
structure, that is easily converted to a more generic fwnode_handle
pointer that can cater for OF and non-OF (ie ACPI) systems.
Create the files and related Kconfig entry to decouple iommu_fwspec
structure from the OF iommu kernel layer.
Given that the current iommu_fwspec implementation relies on
the arch specific struct device.archdata.iommu field in its
implementation, by making the code standalone and independent
of the OF layer this patch makes sure that the iommu_fwspec
kernel code can be selected only on arches implementing the
struct device.archdata.iommu field by adding an explicit
arch dependency in its config entry.
Current drivers using the iommu_fwspec for streamid translation
are converted to the new iommu_fwspec API by simply converting
the device_node to its fwnode_handle pointer.
Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Cc: Will Deacon <will.deacon@arm.com>
Cc: Hanjun Guo <hanjun.guo@linaro.org>
Cc: Robin Murphy <robin.murphy@arm.com>
Cc: Joerg Roedel <joro@8bytes.org>
---
drivers/iommu/Kconfig | 4 ++
drivers/iommu/Makefile | 1 +
drivers/iommu/arm-smmu-v3.c | 13 +++--
drivers/iommu/iommu-fwspec.c | 114 +++++++++++++++++++++++++++++++++++++++++++
drivers/iommu/of_iommu.c | 52 --------------------
include/linux/iommu-fwspec.h | 60 +++++++++++++++++++++++
include/linux/of_iommu.h | 24 +++------
7 files changed, 196 insertions(+), 72 deletions(-)
create mode 100644 drivers/iommu/iommu-fwspec.c
create mode 100644 include/linux/iommu-fwspec.h
diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig
index d1c66af..2b26bfb 100644
--- a/drivers/iommu/Kconfig
+++ b/drivers/iommu/Kconfig
@@ -67,6 +67,10 @@ config OF_IOMMU
def_bool y
depends on OF && IOMMU_API
+config IOMMU_FWSPEC
+ def_bool y
+ depends on ARM64 && IOMMU_API
+
# IOMMU-agnostic DMA-mapping layer
config IOMMU_DMA
bool
diff --git a/drivers/iommu/Makefile b/drivers/iommu/Makefile
index c6edb31..dd85337 100644
--- a/drivers/iommu/Makefile
+++ b/drivers/iommu/Makefile
@@ -7,6 +7,7 @@ obj-$(CONFIG_IOMMU_IO_PGTABLE_ARMV7S) += io-pgtable-arm-v7s.o
obj-$(CONFIG_IOMMU_IO_PGTABLE_LPAE) += io-pgtable-arm.o
obj-$(CONFIG_IOMMU_IOVA) += iova.o
obj-$(CONFIG_OF_IOMMU) += of_iommu.o
+obj-$(CONFIG_IOMMU_FWSPEC) += iommu-fwspec.o
obj-$(CONFIG_MSM_IOMMU) += msm_iommu.o msm_iommu_dev.o
obj-$(CONFIG_AMD_IOMMU) += amd_iommu.o amd_iommu_init.o
obj-$(CONFIG_AMD_IOMMU_V2) += amd_iommu_v2.o
diff --git a/drivers/iommu/arm-smmu-v3.c b/drivers/iommu/arm-smmu-v3.c
index 98e6441..052a26c 100644
--- a/drivers/iommu/arm-smmu-v3.c
+++ b/drivers/iommu/arm-smmu-v3.c
@@ -25,6 +25,7 @@
#include <linux/err.h>
#include <linux/interrupt.h>
#include <linux/iommu.h>
+#include <linux/iommu-fwspec.h>
#include <linux/iopoll.h>
#include <linux/module.h>
#include <linux/msi.h>
@@ -1739,9 +1740,13 @@ arm_smmu_iova_to_phys(struct iommu_domain *domain, dma_addr_t iova)
return ret;
}
-static struct arm_smmu_device *arm_smmu_get_by_node(struct device_node *np)
+static struct arm_smmu_device *
+arm_smmu_get_by_fwnode(struct fwnode_handle *handle)
{
- struct platform_device *smmu_pdev = of_find_device_by_node(np);
+ struct platform_device *smmu_pdev = NULL;
+
+ if (is_of_node(handle))
+ smmu_pdev = of_find_device_by_node(to_of_node(handle));
if (!smmu_pdev)
return NULL;
@@ -1780,7 +1785,7 @@ static int arm_smmu_add_device(struct device *dev)
master = fwspec->iommu_priv;
smmu = master->smmu;
} else {
- smmu = arm_smmu_get_by_node(fwspec->iommu_np);
+ smmu = arm_smmu_get_by_fwnode(fwspec->iommu_fwnode);
if (!smmu)
return -ENODEV;
master = kzalloc(sizeof(*master), GFP_KERNEL);
@@ -1892,7 +1897,7 @@ out_unlock:
static int arm_smmu_of_xlate(struct device *dev, struct of_phandle_args *args)
{
- int ret = iommu_fwspec_init(dev, args->np);
+ int ret = iommu_fwspec_init(dev, &args->np->fwnode);
if (!ret)
ret = iommu_fwspec_add_ids(dev, &args->args[0], 1);
diff --git a/drivers/iommu/iommu-fwspec.c b/drivers/iommu/iommu-fwspec.c
new file mode 100644
index 0000000..0600c17
--- /dev/null
+++ b/drivers/iommu/iommu-fwspec.c
@@ -0,0 +1,114 @@
+/*
+ * Firmware handling helpers for IOMMU
+ *
+ * Copyright (c) 2016 ARM Ltd. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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.
+ */
+
+#include <linux/iommu.h>
+#include <linux/iommu-fwspec.h>
+#include <linux/of_iommu.h>
+#include <linux/slab.h>
+
+struct fwspec_iommu_node {
+ struct list_head list;
+ struct fwnode_handle *fwnode;
+ const struct iommu_ops *ops;
+};
+static LIST_HEAD(fwnode_iommu_list);
+static DEFINE_SPINLOCK(fwspec_iommu_lock);
+
+void fwspec_iommu_set_ops(struct fwnode_handle *fwnode,
+ const struct iommu_ops *ops)
+{
+ struct fwspec_iommu_node *iommu =
+ kzalloc(sizeof(*iommu), GFP_KERNEL);
+
+ if (WARN_ON(!iommu))
+ return;
+
+ INIT_LIST_HEAD(&iommu->list);
+ iommu->fwnode = fwnode;
+ iommu->ops = ops;
+ spin_lock(&fwspec_iommu_lock);
+ list_add_tail(&iommu->list, &fwnode_iommu_list);
+ spin_unlock(&fwspec_iommu_lock);
+}
+
+const struct iommu_ops *fwspec_iommu_get_ops(struct fwnode_handle *fwnode)
+{
+ struct fwspec_iommu_node *node;
+ const struct iommu_ops *ops = NULL;
+
+ spin_lock(&fwspec_iommu_lock);
+ list_for_each_entry(node, &fwnode_iommu_list, list)
+ if (node->fwnode == fwnode) {
+ ops = node->ops;
+ break;
+ }
+ spin_unlock(&fwspec_iommu_lock);
+ return ops;
+}
+
+int iommu_fwspec_init(struct device *dev,
+ struct fwnode_handle *iommu_fwnode)
+{
+ struct iommu_fwspec *fwspec = dev->archdata.iommu;
+ const struct iommu_ops *ops;
+
+ if (fwspec)
+ return 0;
+
+ fwspec = kzalloc(sizeof(*fwspec), GFP_KERNEL);
+ if (!fwspec)
+ return -ENOMEM;
+
+ if (is_of_node(iommu_fwnode))
+ ops = of_iommu_get_ops(to_of_node(iommu_fwnode));
+ else
+ ops = fwspec_iommu_get_ops(iommu_fwnode);
+
+ fwspec->iommu_fwnode = iommu_fwnode;
+ fwspec->iommu_ops = ops;
+
+ dev->archdata.iommu = fwspec;
+ return 0;
+}
+
+void iommu_fwspec_free(struct device *dev)
+{
+ kfree(dev->archdata.iommu);
+}
+
+int iommu_fwspec_add_ids(struct device *dev, u32 *ids, int num_ids)
+{
+ struct iommu_fwspec *fwspec = dev->archdata.iommu;
+ size_t size;
+
+ if (!fwspec)
+ return -EINVAL;
+
+ size = offsetof(struct iommu_fwspec, ids[fwspec->num_ids + 1]);
+ fwspec = krealloc(dev->archdata.iommu, size, GFP_KERNEL);
+ if (!fwspec)
+ return -ENOMEM;
+
+ while (num_ids--)
+ fwspec->ids[fwspec->num_ids++] = *ids++;
+
+ dev->archdata.iommu = fwspec;
+ return 0;
+}
+
+inline struct iommu_fwspec *dev_iommu_fwspec(struct device *dev)
+{
+ return dev->archdata.iommu;
+}
diff --git a/drivers/iommu/of_iommu.c b/drivers/iommu/of_iommu.c
index 4618e89..1fe1f62 100644
--- a/drivers/iommu/of_iommu.c
+++ b/drivers/iommu/of_iommu.c
@@ -216,55 +216,3 @@ void __init of_iommu_init(void)
of_node_full_name(np));
}
}
-
-int iommu_fwspec_init(struct device *dev, struct device_node *iommu_np)
-{
- struct iommu_fwspec *fwspec = dev->archdata.iommu;
-
- if (fwspec)
- return 0;
-
- fwspec = kzalloc(sizeof(*fwspec), GFP_KERNEL);
- if (!fwspec)
- return -ENOMEM;
-
- fwspec->iommu_np = of_node_get(iommu_np);
- fwspec->iommu_ops = of_iommu_get_ops(iommu_np);
- dev->archdata.iommu = fwspec;
- return 0;
-}
-
-void iommu_fwspec_free(struct device *dev)
-{
- struct iommu_fwspec *fwspec = dev->archdata.iommu;
-
- if (fwspec) {
- of_node_put(fwspec->iommu_np);
- kfree(fwspec);
- }
-}
-
-int iommu_fwspec_add_ids(struct device *dev, u32 *ids, int num_ids)
-{
- struct iommu_fwspec *fwspec = dev->archdata.iommu;
- size_t size;
-
- if (!fwspec)
- return -EINVAL;
-
- size = offsetof(struct iommu_fwspec, ids[fwspec->num_ids + 1]);
- fwspec = krealloc(dev->archdata.iommu, size, GFP_KERNEL);
- if (!fwspec)
- return -ENOMEM;
-
- while (num_ids--)
- fwspec->ids[fwspec->num_ids++] = *ids++;
-
- dev->archdata.iommu = fwspec;
- return 0;
-}
-
-inline struct iommu_fwspec *dev_iommu_fwspec(struct device *dev)
-{
- return dev->archdata.iommu;
-}
diff --git a/include/linux/iommu-fwspec.h b/include/linux/iommu-fwspec.h
new file mode 100644
index 0000000..3a572c6
--- /dev/null
+++ b/include/linux/iommu-fwspec.h
@@ -0,0 +1,60 @@
+#ifndef __IOMMU_FWSPEC_H
+#define __IOMMU_FWSPEC_H
+
+#include <linux/device.h>
+#include <linux/iommu.h>
+
+struct iommu_fwspec {
+ const struct iommu_ops *iommu_ops;
+ struct fwnode_handle *iommu_fwnode;
+ void *iommu_priv;
+ unsigned int num_ids;
+ u32 ids[];
+};
+
+#ifdef CONFIG_IOMMU_FWSPEC
+int iommu_fwspec_init(struct device *dev,
+ struct fwnode_handle *iommu_fwnode);
+void iommu_fwspec_free(struct device *dev);
+int iommu_fwspec_add_ids(struct device *dev, u32 *ids, int num_ids);
+struct iommu_fwspec *dev_iommu_fwspec(struct device *dev);
+
+void fwspec_iommu_set_ops(struct fwnode_handle *fwnode,
+ const struct iommu_ops *ops);
+const struct iommu_ops *fwspec_iommu_get_ops(struct fwnode_handle *fwnode);
+#else /* CONFIG_IOMMU_FWSPEC */
+static inline int iommu_fwspec_init(struct device *dev,
+ struct fwnode_handle *iommu_fwnode)
+{
+ return -ENODEV;
+}
+
+static inline void iommu_fwspec_free(struct device *dev)
+{
+}
+
+static inline int iommu_fwspec_add_ids(struct device *dev, u32 *ids,
+ int num_ids)
+{
+ return -ENODEV;
+}
+
+static inline struct iommu_fwspec *dev_iommu_fwspec(struct device *dev)
+{
+ return NULL;
+}
+
+static inline void fwspec_iommu_set_ops(struct fwnode_handle *fwnode,
+ const struct iommu_ops *ops)
+{
+}
+
+static inline const struct iommu_ops *
+fwspec_iommu_get_ops(struct fwnode_handle *fwnode)
+{
+ return NULL;
+}
+
+#endif /* CONFIG_IOMMU_FWSPEC */
+
+#endif /* __IOMMU_FWSPEC_H */
diff --git a/include/linux/of_iommu.h b/include/linux/of_iommu.h
index 308791f..2362232 100644
--- a/include/linux/of_iommu.h
+++ b/include/linux/of_iommu.h
@@ -15,13 +15,8 @@ extern void of_iommu_init(void);
extern const struct iommu_ops *of_iommu_configure(struct device *dev,
struct device_node *master_np);
-struct iommu_fwspec {
- const struct iommu_ops *iommu_ops;
- struct device_node *iommu_np;
- void *iommu_priv;
- unsigned int num_ids;
- u32 ids[];
-};
+void of_iommu_set_ops(struct device_node *np, const struct iommu_ops *ops);
+const struct iommu_ops *of_iommu_get_ops(struct device_node *np);
#else
@@ -39,17 +34,14 @@ static inline const struct iommu_ops *of_iommu_configure(struct device *dev,
return NULL;
}
-struct iommu_fwspec;
-
-#endif /* CONFIG_OF_IOMMU */
+static inline void of_iommu_set_ops(struct device_node *np,
+ const struct iommu_ops *ops)
+{ }
-int iommu_fwspec_init(struct device *dev, struct device_node *iommu_np);
-void iommu_fwspec_free(struct device *dev);
-int iommu_fwspec_add_ids(struct device *dev, u32 *ids, int num_ids);
-struct iommu_fwspec *dev_iommu_fwspec(struct device *dev);
+static inline const struct iommu_ops *
+of_iommu_get_ops(struct device_node *np) { return NULL; }
-void of_iommu_set_ops(struct device_node *np, const struct iommu_ops *ops);
-const struct iommu_ops *of_iommu_get_ops(struct device_node *np);
+#endif /* CONFIG_OF_IOMMU */
extern struct of_device_id __iommu_of_table;
--
2.6.4
[toc] | [prev] | [next] | [standalone]
| From | Robin Murphy <robin.murphy@arm.com> |
|---|---|
| Date | 2016-07-25 17:20 +0200 |
| Subject | Re: [RFC PATCH v3 05/13] drivers: iommu: make iommu_fwspec OF agnostic |
| Message-ID | <rYPPH-6aR-9@gated-at.bofh.it> |
| In reply to | #1447183 |
Hi Lorenzo,
On 20/07/16 12:23, Lorenzo Pieralisi wrote:
> The iommu_fwspec structure, used to hold per device iommu configuration
> data is not OF specific and therefore can be moved to a generic
> and OF independent compilation unit.
>
> In particular, the iommu_fwspec handling hinges on the device_node
> pointer to identify the IOMMU device associated with the iommu_fwspec
> structure, that is easily converted to a more generic fwnode_handle
> pointer that can cater for OF and non-OF (ie ACPI) systems.
>
> Create the files and related Kconfig entry to decouple iommu_fwspec
> structure from the OF iommu kernel layer.
>
> Given that the current iommu_fwspec implementation relies on
> the arch specific struct device.archdata.iommu field in its
> implementation, by making the code standalone and independent
> of the OF layer this patch makes sure that the iommu_fwspec
> kernel code can be selected only on arches implementing the
> struct device.archdata.iommu field by adding an explicit
> arch dependency in its config entry.
>
> Current drivers using the iommu_fwspec for streamid translation
> are converted to the new iommu_fwspec API by simply converting
> the device_node to its fwnode_handle pointer.
>
> Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
> Cc: Will Deacon <will.deacon@arm.com>
> Cc: Hanjun Guo <hanjun.guo@linaro.org>
> Cc: Robin Murphy <robin.murphy@arm.com>
> Cc: Joerg Roedel <joro@8bytes.org>
> ---
> drivers/iommu/Kconfig | 4 ++
> drivers/iommu/Makefile | 1 +
> drivers/iommu/arm-smmu-v3.c | 13 +++--
> drivers/iommu/iommu-fwspec.c | 114 +++++++++++++++++++++++++++++++++++++++++++
> drivers/iommu/of_iommu.c | 52 --------------------
> include/linux/iommu-fwspec.h | 60 +++++++++++++++++++++++
> include/linux/of_iommu.h | 24 +++------
> 7 files changed, 196 insertions(+), 72 deletions(-)
> create mode 100644 drivers/iommu/iommu-fwspec.c
> create mode 100644 include/linux/iommu-fwspec.h
>
> diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig
> index d1c66af..2b26bfb 100644
> --- a/drivers/iommu/Kconfig
> +++ b/drivers/iommu/Kconfig
> @@ -67,6 +67,10 @@ config OF_IOMMU
> def_bool y
> depends on OF && IOMMU_API
>
> +config IOMMU_FWSPEC
> + def_bool y
> + depends on ARM64 && IOMMU_API
I think that could be at least (ARM || ARM64).
> +
> # IOMMU-agnostic DMA-mapping layer
> config IOMMU_DMA
> bool
[...]
> diff --git a/include/linux/of_iommu.h b/include/linux/of_iommu.h
> index 308791f..2362232 100644
> --- a/include/linux/of_iommu.h
> +++ b/include/linux/of_iommu.h
> @@ -15,13 +15,8 @@ extern void of_iommu_init(void);
> extern const struct iommu_ops *of_iommu_configure(struct device *dev,
> struct device_node *master_np);
>
> -struct iommu_fwspec {
> - const struct iommu_ops *iommu_ops;
> - struct device_node *iommu_np;
> - void *iommu_priv;
> - unsigned int num_ids;
> - u32 ids[];
> -};
> +void of_iommu_set_ops(struct device_node *np, const struct iommu_ops *ops);
> +const struct iommu_ops *of_iommu_get_ops(struct device_node *np);
Is there some reason we need to retain the existing definitions of
these? I was assuming we'd be able to move the entire implementation
over to the fwspec code and leave behind nothing more than trivial
wrappers, e.g.:
#define of_iommu_get_ops(np) iommu_fwspec_get_ops(&(np)->fwnode_handle)
Robin.
> #else
>
> @@ -39,17 +34,14 @@ static inline const struct iommu_ops *of_iommu_configure(struct device *dev,
> return NULL;
> }
>
> -struct iommu_fwspec;
> -
> -#endif /* CONFIG_OF_IOMMU */
> +static inline void of_iommu_set_ops(struct device_node *np,
> + const struct iommu_ops *ops)
> +{ }
>
> -int iommu_fwspec_init(struct device *dev, struct device_node *iommu_np);
> -void iommu_fwspec_free(struct device *dev);
> -int iommu_fwspec_add_ids(struct device *dev, u32 *ids, int num_ids);
> -struct iommu_fwspec *dev_iommu_fwspec(struct device *dev);
> +static inline const struct iommu_ops *
> +of_iommu_get_ops(struct device_node *np) { return NULL; }
>
> -void of_iommu_set_ops(struct device_node *np, const struct iommu_ops *ops);
> -const struct iommu_ops *of_iommu_get_ops(struct device_node *np);
> +#endif /* CONFIG_OF_IOMMU */
>
> extern struct of_device_id __iommu_of_table;
>
>
[toc] | [prev] | [next] | [standalone]
| From | Rob Herring <robh@kernel.org> |
|---|---|
| Date | 2016-07-25 17:30 +0200 |
| Subject | Re: [RFC PATCH v3 05/13] drivers: iommu: make iommu_fwspec OF agnostic |
| Message-ID | <rYPZn-6e9-3@gated-at.bofh.it> |
| In reply to | #1449564 |
On Mon, Jul 25, 2016 at 10:09 AM, Robin Murphy <robin.murphy@arm.com> wrote: > Hi Lorenzo, > > On 20/07/16 12:23, Lorenzo Pieralisi wrote: >> The iommu_fwspec structure, used to hold per device iommu configuration >> data is not OF specific and therefore can be moved to a generic >> and OF independent compilation unit. >> >> In particular, the iommu_fwspec handling hinges on the device_node >> pointer to identify the IOMMU device associated with the iommu_fwspec >> structure, that is easily converted to a more generic fwnode_handle >> pointer that can cater for OF and non-OF (ie ACPI) systems. >> >> Create the files and related Kconfig entry to decouple iommu_fwspec >> structure from the OF iommu kernel layer. >> >> Given that the current iommu_fwspec implementation relies on >> the arch specific struct device.archdata.iommu field in its >> implementation, by making the code standalone and independent >> of the OF layer this patch makes sure that the iommu_fwspec >> kernel code can be selected only on arches implementing the >> struct device.archdata.iommu field by adding an explicit >> arch dependency in its config entry. >> >> Current drivers using the iommu_fwspec for streamid translation >> are converted to the new iommu_fwspec API by simply converting >> the device_node to its fwnode_handle pointer. >> >> Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> >> Cc: Will Deacon <will.deacon@arm.com> >> Cc: Hanjun Guo <hanjun.guo@linaro.org> >> Cc: Robin Murphy <robin.murphy@arm.com> >> Cc: Joerg Roedel <joro@8bytes.org> >> --- >> drivers/iommu/Kconfig | 4 ++ >> drivers/iommu/Makefile | 1 + >> drivers/iommu/arm-smmu-v3.c | 13 +++-- >> drivers/iommu/iommu-fwspec.c | 114 +++++++++++++++++++++++++++++++++++++++++++ >> drivers/iommu/of_iommu.c | 52 -------------------- >> include/linux/iommu-fwspec.h | 60 +++++++++++++++++++++++ >> include/linux/of_iommu.h | 24 +++------ >> 7 files changed, 196 insertions(+), 72 deletions(-) >> create mode 100644 drivers/iommu/iommu-fwspec.c >> create mode 100644 include/linux/iommu-fwspec.h >> >> diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig >> index d1c66af..2b26bfb 100644 >> --- a/drivers/iommu/Kconfig >> +++ b/drivers/iommu/Kconfig >> @@ -67,6 +67,10 @@ config OF_IOMMU >> def_bool y >> depends on OF && IOMMU_API >> >> +config IOMMU_FWSPEC >> + def_bool y >> + depends on ARM64 && IOMMU_API > > I think that could be at least (ARM || ARM64). Why any arch dependency? Seems like OF_IOMMU (and ACPI?) should select this. Rob
[toc] | [prev] | [next] | [standalone]
| From | Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> |
|---|---|
| Date | 2016-07-25 18:00 +0200 |
| Subject | Re: [RFC PATCH v3 05/13] drivers: iommu: make iommu_fwspec OF agnostic |
| Message-ID | <rYQsr-6og-43@gated-at.bofh.it> |
| In reply to | #1449571 |
On Mon, Jul 25, 2016 at 10:21:10AM -0500, Rob Herring wrote: > On Mon, Jul 25, 2016 at 10:09 AM, Robin Murphy <robin.murphy@arm.com> wrote: > > Hi Lorenzo, > > > > On 20/07/16 12:23, Lorenzo Pieralisi wrote: > >> The iommu_fwspec structure, used to hold per device iommu configuration > >> data is not OF specific and therefore can be moved to a generic > >> and OF independent compilation unit. > >> > >> In particular, the iommu_fwspec handling hinges on the device_node > >> pointer to identify the IOMMU device associated with the iommu_fwspec > >> structure, that is easily converted to a more generic fwnode_handle > >> pointer that can cater for OF and non-OF (ie ACPI) systems. > >> > >> Create the files and related Kconfig entry to decouple iommu_fwspec > >> structure from the OF iommu kernel layer. > >> > >> Given that the current iommu_fwspec implementation relies on > >> the arch specific struct device.archdata.iommu field in its > >> implementation, by making the code standalone and independent > >> of the OF layer this patch makes sure that the iommu_fwspec > >> kernel code can be selected only on arches implementing the > >> struct device.archdata.iommu field by adding an explicit > >> arch dependency in its config entry. > >> > >> Current drivers using the iommu_fwspec for streamid translation > >> are converted to the new iommu_fwspec API by simply converting > >> the device_node to its fwnode_handle pointer. > >> > >> Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> > >> Cc: Will Deacon <will.deacon@arm.com> > >> Cc: Hanjun Guo <hanjun.guo@linaro.org> > >> Cc: Robin Murphy <robin.murphy@arm.com> > >> Cc: Joerg Roedel <joro@8bytes.org> > >> --- > >> drivers/iommu/Kconfig | 4 ++ > >> drivers/iommu/Makefile | 1 + > >> drivers/iommu/arm-smmu-v3.c | 13 +++-- > >> drivers/iommu/iommu-fwspec.c | 114 +++++++++++++++++++++++++++++++++++++++++++ > >> drivers/iommu/of_iommu.c | 52 -------------------- > >> include/linux/iommu-fwspec.h | 60 +++++++++++++++++++++++ > >> include/linux/of_iommu.h | 24 +++------ > >> 7 files changed, 196 insertions(+), 72 deletions(-) > >> create mode 100644 drivers/iommu/iommu-fwspec.c > >> create mode 100644 include/linux/iommu-fwspec.h > >> > >> diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig > >> index d1c66af..2b26bfb 100644 > >> --- a/drivers/iommu/Kconfig > >> +++ b/drivers/iommu/Kconfig > >> @@ -67,6 +67,10 @@ config OF_IOMMU > >> def_bool y > >> depends on OF && IOMMU_API > >> > >> +config IOMMU_FWSPEC > >> + def_bool y > >> + depends on ARM64 && IOMMU_API > > > > I think that could be at least (ARM || ARM64). > > Why any arch dependency? > > Seems like OF_IOMMU (and ACPI?) should select this. Absolutely, that's the end goal. Current issue is that the iommu_fwspec mechanism relies on dev_archdata.iommu pointer internally to work and since that's arch specific I can't select it on arches that do not have that field, it would break the compilation. I will follow up with Robin to make sure we will be able to implement what you request above. Thanks ! Lorenzo
[toc] | [prev] | [next] | [standalone]
| From | Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> |
|---|---|
| Date | 2016-07-25 17:50 +0200 |
| Subject | Re: [RFC PATCH v3 05/13] drivers: iommu: make iommu_fwspec OF agnostic |
| Message-ID | <rYQiJ-6kP-19@gated-at.bofh.it> |
| In reply to | #1449564 |
On Mon, Jul 25, 2016 at 04:09:55PM +0100, Robin Murphy wrote:
> Hi Lorenzo,
>
> On 20/07/16 12:23, Lorenzo Pieralisi wrote:
> > The iommu_fwspec structure, used to hold per device iommu configuration
> > data is not OF specific and therefore can be moved to a generic
> > and OF independent compilation unit.
> >
> > In particular, the iommu_fwspec handling hinges on the device_node
> > pointer to identify the IOMMU device associated with the iommu_fwspec
> > structure, that is easily converted to a more generic fwnode_handle
> > pointer that can cater for OF and non-OF (ie ACPI) systems.
> >
> > Create the files and related Kconfig entry to decouple iommu_fwspec
> > structure from the OF iommu kernel layer.
> >
> > Given that the current iommu_fwspec implementation relies on
> > the arch specific struct device.archdata.iommu field in its
> > implementation, by making the code standalone and independent
> > of the OF layer this patch makes sure that the iommu_fwspec
> > kernel code can be selected only on arches implementing the
> > struct device.archdata.iommu field by adding an explicit
> > arch dependency in its config entry.
> >
> > Current drivers using the iommu_fwspec for streamid translation
> > are converted to the new iommu_fwspec API by simply converting
> > the device_node to its fwnode_handle pointer.
> >
> > Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
> > Cc: Will Deacon <will.deacon@arm.com>
> > Cc: Hanjun Guo <hanjun.guo@linaro.org>
> > Cc: Robin Murphy <robin.murphy@arm.com>
> > Cc: Joerg Roedel <joro@8bytes.org>
> > ---
> > drivers/iommu/Kconfig | 4 ++
> > drivers/iommu/Makefile | 1 +
> > drivers/iommu/arm-smmu-v3.c | 13 +++--
> > drivers/iommu/iommu-fwspec.c | 114 +++++++++++++++++++++++++++++++++++++++++++
> > drivers/iommu/of_iommu.c | 52 --------------------
> > include/linux/iommu-fwspec.h | 60 +++++++++++++++++++++++
> > include/linux/of_iommu.h | 24 +++------
> > 7 files changed, 196 insertions(+), 72 deletions(-)
> > create mode 100644 drivers/iommu/iommu-fwspec.c
> > create mode 100644 include/linux/iommu-fwspec.h
> >
> > diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig
> > index d1c66af..2b26bfb 100644
> > --- a/drivers/iommu/Kconfig
> > +++ b/drivers/iommu/Kconfig
> > @@ -67,6 +67,10 @@ config OF_IOMMU
> > def_bool y
> > depends on OF && IOMMU_API
> >
> > +config IOMMU_FWSPEC
> > + def_bool y
> > + depends on ARM64 && IOMMU_API
>
> I think that could be at least (ARM || ARM64).
Yes agreed.
> > # IOMMU-agnostic DMA-mapping layer
> > config IOMMU_DMA
> > bool
>
> [...]
>
> > diff --git a/include/linux/of_iommu.h b/include/linux/of_iommu.h
> > index 308791f..2362232 100644
> > --- a/include/linux/of_iommu.h
> > +++ b/include/linux/of_iommu.h
> > @@ -15,13 +15,8 @@ extern void of_iommu_init(void);
> > extern const struct iommu_ops *of_iommu_configure(struct device *dev,
> > struct device_node *master_np);
> >
> > -struct iommu_fwspec {
> > - const struct iommu_ops *iommu_ops;
> > - struct device_node *iommu_np;
> > - void *iommu_priv;
> > - unsigned int num_ids;
> > - u32 ids[];
> > -};
> > +void of_iommu_set_ops(struct device_node *np, const struct iommu_ops *ops);
> > +const struct iommu_ops *of_iommu_get_ops(struct device_node *np);
>
> Is there some reason we need to retain the existing definitions of
> these? I was assuming we'd be able to move the entire implementation
> over to the fwspec code and leave behind nothing more than trivial
> wrappers, e.g.:
>
> #define of_iommu_get_ops(np) iommu_fwspec_get_ops(&(np)->fwnode_handle)
Yep, that's exactly what I did but then I was bitten by config
dependencies. If we implement of_iommu_get/set_ops() as wrappers,
we have to compile iommu_fwspec_get/set_ops() on arches that may
not have struct dev_archdata.iommu, unless we introduce yet another
config symbol to avoid compiling that code (see eg iommu_fwspec_init(),
we can't compile it on eg x86 even though we do need of_iommu_get_ops()
on it - so iommu_fwspec_get_ops(), that lives in the same compilation
unit as eg iommu_fwspec_init()).
So short answer is: there is no reason apart from dev_archdata.iommu
being arch specific, if we were able to move iommu_fwspec to generic
code (ie struct device, somehow) I would certainly get rid of this
stupid code duplication (or as I said I can add a config entry for
that, more ideas are welcome).
Thanks,
Lorenzo
>
> Robin.
>
> > #else
> >
> > @@ -39,17 +34,14 @@ static inline const struct iommu_ops *of_iommu_configure(struct device *dev,
> > return NULL;
> > }
> >
> > -struct iommu_fwspec;
> > -
> > -#endif /* CONFIG_OF_IOMMU */
> > +static inline void of_iommu_set_ops(struct device_node *np,
> > + const struct iommu_ops *ops)
> > +{ }
> >
> > -int iommu_fwspec_init(struct device *dev, struct device_node *iommu_np);
> > -void iommu_fwspec_free(struct device *dev);
> > -int iommu_fwspec_add_ids(struct device *dev, u32 *ids, int num_ids);
> > -struct iommu_fwspec *dev_iommu_fwspec(struct device *dev);
> > +static inline const struct iommu_ops *
> > +of_iommu_get_ops(struct device_node *np) { return NULL; }
> >
> > -void of_iommu_set_ops(struct device_node *np, const struct iommu_ops *ops);
> > -const struct iommu_ops *of_iommu_get_ops(struct device_node *np);
> > +#endif /* CONFIG_OF_IOMMU */
> >
> > extern struct of_device_id __iommu_of_table;
> >
> >
>
[toc] | [prev] | [next] | [standalone]
| From | Robin Murphy <robin.murphy@arm.com> |
|---|---|
| Date | 2016-07-25 18:00 +0200 |
| Subject | Re: [RFC PATCH v3 05/13] drivers: iommu: make iommu_fwspec OF agnostic |
| Message-ID | <rYQsq-6og-27@gated-at.bofh.it> |
| In reply to | #1449599 |
On 25/07/16 16:41, Lorenzo Pieralisi wrote:
[...]
>>> diff --git a/include/linux/of_iommu.h b/include/linux/of_iommu.h
>>> index 308791f..2362232 100644
>>> --- a/include/linux/of_iommu.h
>>> +++ b/include/linux/of_iommu.h
>>> @@ -15,13 +15,8 @@ extern void of_iommu_init(void);
>>> extern const struct iommu_ops *of_iommu_configure(struct device *dev,
>>> struct device_node *master_np);
>>>
>>> -struct iommu_fwspec {
>>> - const struct iommu_ops *iommu_ops;
>>> - struct device_node *iommu_np;
>>> - void *iommu_priv;
>>> - unsigned int num_ids;
>>> - u32 ids[];
>>> -};
>>> +void of_iommu_set_ops(struct device_node *np, const struct iommu_ops *ops);
>>> +const struct iommu_ops *of_iommu_get_ops(struct device_node *np);
>>
>> Is there some reason we need to retain the existing definitions of
>> these? I was assuming we'd be able to move the entire implementation
>> over to the fwspec code and leave behind nothing more than trivial
>> wrappers, e.g.:
>>
>> #define of_iommu_get_ops(np) iommu_fwspec_get_ops(&(np)->fwnode_handle)
>
> Yep, that's exactly what I did but then I was bitten by config
> dependencies. If we implement of_iommu_get/set_ops() as wrappers,
> we have to compile iommu_fwspec_get/set_ops() on arches that may
> not have struct dev_archdata.iommu, unless we introduce yet another
> config symbol to avoid compiling that code (see eg iommu_fwspec_init(),
> we can't compile it on eg x86 even though we do need of_iommu_get_ops()
> on it - so iommu_fwspec_get_ops(), that lives in the same compilation
> unit as eg iommu_fwspec_init()).
>
> So short answer is: there is no reason apart from dev_archdata.iommu
> being arch specific, if we were able to move iommu_fwspec to generic
> code (ie struct device, somehow) I would certainly get rid of this
> stupid code duplication (or as I said I can add a config entry for
> that, more ideas are welcome).
OK, given Rob's comment as well, I guess breaking that dependency is to
everyone's benefit. Since it's quite closely related, how about if we
follow the arch_setup_dma_ops() pattern with an
arch_{get,set}_iommu_fwspec(dev) type thing?
Robin.
>
> Thanks,
> Lorenzo
>
>>
>> Robin.
>>
>>> #else
>>>
>>> @@ -39,17 +34,14 @@ static inline const struct iommu_ops *of_iommu_configure(struct device *dev,
>>> return NULL;
>>> }
>>>
>>> -struct iommu_fwspec;
>>> -
>>> -#endif /* CONFIG_OF_IOMMU */
>>> +static inline void of_iommu_set_ops(struct device_node *np,
>>> + const struct iommu_ops *ops)
>>> +{ }
>>>
>>> -int iommu_fwspec_init(struct device *dev, struct device_node *iommu_np);
>>> -void iommu_fwspec_free(struct device *dev);
>>> -int iommu_fwspec_add_ids(struct device *dev, u32 *ids, int num_ids);
>>> -struct iommu_fwspec *dev_iommu_fwspec(struct device *dev);
>>> +static inline const struct iommu_ops *
>>> +of_iommu_get_ops(struct device_node *np) { return NULL; }
>>>
>>> -void of_iommu_set_ops(struct device_node *np, const struct iommu_ops *ops);
>>> -const struct iommu_ops *of_iommu_get_ops(struct device_node *np);
>>> +#endif /* CONFIG_OF_IOMMU */
>>>
>>> extern struct of_device_id __iommu_of_table;
>>>
>>>
>>
>
[toc] | [prev] | [next] | [standalone]
| From | Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> |
|---|---|
| Date | 2016-07-25 18:20 +0200 |
| Subject | Re: [RFC PATCH v3 05/13] drivers: iommu: make iommu_fwspec OF agnostic |
| Message-ID | <rYQLM-6JY-23@gated-at.bofh.it> |
| In reply to | #1449603 |
On Mon, Jul 25, 2016 at 04:51:00PM +0100, Robin Murphy wrote:
> On 25/07/16 16:41, Lorenzo Pieralisi wrote:
> [...]
> >>> diff --git a/include/linux/of_iommu.h b/include/linux/of_iommu.h
> >>> index 308791f..2362232 100644
> >>> --- a/include/linux/of_iommu.h
> >>> +++ b/include/linux/of_iommu.h
> >>> @@ -15,13 +15,8 @@ extern void of_iommu_init(void);
> >>> extern const struct iommu_ops *of_iommu_configure(struct device *dev,
> >>> struct device_node *master_np);
> >>>
> >>> -struct iommu_fwspec {
> >>> - const struct iommu_ops *iommu_ops;
> >>> - struct device_node *iommu_np;
> >>> - void *iommu_priv;
> >>> - unsigned int num_ids;
> >>> - u32 ids[];
> >>> -};
> >>> +void of_iommu_set_ops(struct device_node *np, const struct iommu_ops *ops);
> >>> +const struct iommu_ops *of_iommu_get_ops(struct device_node *np);
> >>
> >> Is there some reason we need to retain the existing definitions of
> >> these? I was assuming we'd be able to move the entire implementation
> >> over to the fwspec code and leave behind nothing more than trivial
> >> wrappers, e.g.:
> >>
> >> #define of_iommu_get_ops(np) iommu_fwspec_get_ops(&(np)->fwnode_handle)
> >
> > Yep, that's exactly what I did but then I was bitten by config
> > dependencies. If we implement of_iommu_get/set_ops() as wrappers,
> > we have to compile iommu_fwspec_get/set_ops() on arches that may
> > not have struct dev_archdata.iommu, unless we introduce yet another
> > config symbol to avoid compiling that code (see eg iommu_fwspec_init(),
> > we can't compile it on eg x86 even though we do need of_iommu_get_ops()
> > on it - so iommu_fwspec_get_ops(), that lives in the same compilation
> > unit as eg iommu_fwspec_init()).
> >
> > So short answer is: there is no reason apart from dev_archdata.iommu
> > being arch specific, if we were able to move iommu_fwspec to generic
> > code (ie struct device, somehow) I would certainly get rid of this
> > stupid code duplication (or as I said I can add a config entry for
> > that, more ideas are welcome).
>
> OK, given Rob's comment as well, I guess breaking that dependency is to
> everyone's benefit. Since it's quite closely related, how about if we
> follow the arch_setup_dma_ops() pattern with an
> arch_{get,set}_iommu_fwspec(dev) type thing?
Yes we can do that too as an intermediate step, that solves the
problem (and it makes this patch much simpler), it is cleaner
than doing it with a(nother) Kconfig entry.
Thanks,
Lorenzo
> Robin.
>
> >
> > Thanks,
> > Lorenzo
> >
> >>
> >> Robin.
> >>
> >>> #else
> >>>
> >>> @@ -39,17 +34,14 @@ static inline const struct iommu_ops *of_iommu_configure(struct device *dev,
> >>> return NULL;
> >>> }
> >>>
> >>> -struct iommu_fwspec;
> >>> -
> >>> -#endif /* CONFIG_OF_IOMMU */
> >>> +static inline void of_iommu_set_ops(struct device_node *np,
> >>> + const struct iommu_ops *ops)
> >>> +{ }
> >>>
> >>> -int iommu_fwspec_init(struct device *dev, struct device_node *iommu_np);
> >>> -void iommu_fwspec_free(struct device *dev);
> >>> -int iommu_fwspec_add_ids(struct device *dev, u32 *ids, int num_ids);
> >>> -struct iommu_fwspec *dev_iommu_fwspec(struct device *dev);
> >>> +static inline const struct iommu_ops *
> >>> +of_iommu_get_ops(struct device_node *np) { return NULL; }
> >>>
> >>> -void of_iommu_set_ops(struct device_node *np, const struct iommu_ops *ops);
> >>> -const struct iommu_ops *of_iommu_get_ops(struct device_node *np);
> >>> +#endif /* CONFIG_OF_IOMMU */
> >>>
> >>> extern struct of_device_id __iommu_of_table;
> >>>
> >>>
> >>
> >
>
[toc] | [prev] | [next] | [standalone]
| From | Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> |
|---|---|
| Date | 2016-07-25 10:40 +0200 |
| Message-ID | <rYJAC-2kh-37@gated-at.bofh.it> |
| In reply to | #1447169 |
On Mon, Jul 25, 2016 at 01:53:32PM +0800, Dennis Chen wrote: > Hi > On Wed, Jul 20, 2016 at 12:23:22PM +0100, Lorenzo Pieralisi wrote: > > This RFC patch series is v3 of a previous posting: > > > > https://lkml.org/lkml/2016/6/7/523 > > > > v2 -> v3 > > - Rebased on top of dependencies series [1][2][3](v4.7-rc3) > > - Added back reliance on ACPI early probing infrastructure > > - Patch[1-3] merged through other dependent series > > - Added back IOMMU fwnode generalization > > - Move SMMU v3 static functions configuration to IORT code > > - Implemented generic IOMMU fwspec API > > - Added code to implement fwnode platform device look-up > > > > v1 -> v2: > > - Rebased on top of dependencies series [1][2][3](v4.7-rc1) > > - Removed IOMMU fwnode generalization > > - Implemented ARM SMMU v3 ACPI probing instead of ARM SMMU v2 > > owing to patch series dependencies [1] > > - Moved platform device creation logic to IORT code to > > generalize its usage for ARM SMMU v1-v2-v3 components > > - Removed reliance on ACPI early device probing > > - Created IORT specific iommu_xlate() translation hook leaving > > OF code unchanged according to v1 reviews > > > > The ACPI IORT table provides information that allows instantiating > > ARM SMMU devices and carrying out id mappings between components on > > ARM based systems (devices, IOMMUs, interrupt controllers). > > > > http://infocenter.arm.com/help/topic/com.arm.doc.den0049b/DEN0049B_IO_Remapping_Table.pdf > > > > Building on basic IORT support, available through [2]: > > > > this patchset enables ARM SMMU v3 support on ACPI systems. > > > > Most of the code is aimed at building the required generic ACPI > > infrastructure to create and enable IOMMU components and to bring > > the IOMMU infrastructure for ACPI on par with DT, which is going to > > make future ARM SMMU components easier to integrate. > > > > PATCH (1) adds a FWNODE_IOMMU type to the struct fwnode_handle type. > > It is required to attach a fwnode identifier to platform > > devices allocated/detected through IORT tables entries; > > IOMMU devices have to have an identifier to look them up > > eg IOMMU core layer carrying out id translation. This can be > > done through a fwnode_handle (ie IOMMU platform devices created > > out of IORT tables are not ACPI devices hence they can't be > > allocated as such, otherwise they would have a fwnode_handle of > > type FWNODE_ACPI). This patch requires discussion and it is key > > to the RFC. > > > > PATCH (2) makes use of the ACPI early probing API to add a linker script > > section for probing devices via IORT ACPI kernel code. > > > > PATCH (3) provides IORT support for registering IOMMU IORT node through > > their fwnode handle. > > > > PATCH (4) implements core code fwnode based platform devices look-up. > > > > PATCH (5) extends iommu_fwspec so that it can be used on ACPI based > > system by creating a generic IOMMU fwspec kernel layer. > > > > PATCH (6) implements the of_dma_configure() API in ACPI world - > > acpi_dma_configure() - and patches PCI and ACPI core code to > > start making use of it. > > > > PATCH (7) provides an IORT function to detect existence of specific type > > of IORT components. > > > > PATCH (8) creates the kernel infrastructure required to create ARM SMMU > > platform devices for IORT nodes. > > > > PATCH (9) refactors the ARM SMMU v3 driver so that the init functions are > > split in a way that groups together code that probes through DT > > and code that carries out HW registers FW agnostic probing, in > > preparation for adding the ACPI probing path. > > > > PATCH (10) rework ARM SMMU v3 platform driver registration to make it work > > on ACPI systems. > > > > PATCH (11) Building on patch (8), it adds ARM SMMU v3 IORT IOMMU > > operations to create and probe ARM SMMU v3 components. > > > > PATCH (12) Extend the IORT iort_node_map_rid() to work on a type mask > > instead of a single type so that the translation API can > > be used on a range of components. > > > > PATCH (13) provides IORT infrastructure to carry out IOMMU configuration > > for devices and hook it up to the previously introduced ACPI > > DMA configure API. > > > > This patchset is built on top and depends on these three patch series: > > > > [1] R.Murphy "Generic DT bindings for PCI and ARM SMMU v3" v4 > > https://marc.info/?l=devicetree&m=146739193215518&w=2 > > > > [2] T.Nowicki "Introduce ACPI world to ITS irqchip" v7 > > https://marc.info/?l=linux-arm-kernel&m=146642080022289&w=2 > > > > [3] T.Nowicki "Support for ARM64 ACPI based PCI host controller" v8 > > http://marc.info/?l=linux-acpi&m=146462129816292&w=2 > > > > and is provided for early review/testing purposes here: > > > > git://git.kernel.org/pub/scm/linux/kernel/git/lpieralisi/linux.git acpi/iort-smmu-v3i > > > I thought I can got all the 13 patches applied with the above git > tree, but I can't find any ACPI related stuff after I cloned the git > repos to my local machine, am I missing something here? Have you pulled the acpi/iort-smmu-v3 branch ? Thanks, Lorenzo
[toc] | [prev] | [standalone]
Back to top | Article view | linux.kernel
csiph-web