From: Lorenzo Pieralisi <hidden> Date: 2016-11-16 15:28:42
This patch series is v8 of a previous posting:
https://lkml.org/lkml/2016/11/9/422
v7 -> v8
- Renamed fwnode iommu_ops registration API according to review
- Minor change in ARM SMMU driver DT/ACPI split
- Added review tags
v6 -> v7
- Rebased against v4.9-rc4
- Fixed IORT probing on ACPI systems with missing IORT table
- Fixed SMMUv1/v2 global interrupt detection
- Updated iommu_ops firmware look-up
v5 -> v6
- Rebased against v4.9-rc1
- Changed FWNODE_IOMMU to FWNODE_ACPI_STATIC
- Moved platform devices creation into IORT code
- Updated fwnode handling
- Added default dma masks initialization
v4 -> v5
- Added SMMUv1/v2 support
- Rebased against v4.8-rc5 and dependencies series
- Consolidated IORT platform devices creation
v3 -> v4
- Added single mapping API (for IORT named components)
- Fixed arm_smmu_iort_xlate() return value
- Reworked fwnode registration and platform device creation
ordering to fix probe ordering dependencies
- Added code to keep device_node ref count with new iommu
fwspec API
- Added patch to make iommu_fwspec arch agnostic
- Dropped RFC status
- Rebased against v4.8-rc2
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, this patchset enables ARM SMMUs 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_ACPI_STATIC type to the struct fwnode_handle type.
It is required to attach a fwnode identifier to platform
devices allocated/detected through static ACPI table entries
(ie 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).
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) make of_iommu_{set/get}_ops() functions DT agnostic and
rename the registration API.
PATCH (5) convert ARM SMMU driver to use fwnode instead of of_node as
look-up and iommu_ops retrieval token.
PATCH (6) convert ARM SMMU v3 driver to use fwnode instead of of_node as
look-up and iommu_ops retrieval token.
PATCH (7) 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 (8) provides an IORT function to detect existence of specific type
of IORT components.
PATCH (9) creates the kernel infrastructure required to create ARM SMMU
platform devices for IORT nodes.
PATCH (10) 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 (11) adds ARM SMMU v3 IORT IOMMU operations to create and probe
ARM SMMU v3 components.
PATCH (12) refactors the ARM SMMU v1/v2 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 (13) adds ARM SMMU v1/v2 IORT IOMMU operations to create and
probe ARM SMMU v1/v2 components.
PATCH (14) 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 (15) Add IORT API to carry out id mappings for components that do
do not have an input identifier/RIDs (ie named components).
PATCH (16) 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 provided for review/testing purposes here:
git://git.kernel.org/pub/scm/linux/kernel/git/lpieralisi/linux.git acpi/iort-smmu-v8
Tested on Juno and FVP models for ARM SMMU v1 and v3 probing path.
Lorenzo Pieralisi (16):
drivers: acpi: add FWNODE_ACPI_STATIC fwnode type
drivers: acpi: iort: introduce linker section for IORT entries probing
drivers: acpi: iort: add support for IOMMU fwnode registration
drivers: iommu: make of_iommu_set/get_ops() DT agnostic
drivers: iommu: arm-smmu: convert struct device of_node to fwnode
usage
drivers: iommu: arm-smmu-v3: convert struct device of_node to fwnode
usage
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: add IORT configuration
drivers: iommu: arm-smmu: split probe functions into DT/generic
portions
drivers: iommu: arm-smmu: add IORT configuration
drivers: acpi: iort: replace rid map type with type mask
drivers: acpi: iort: add single mapping function
drivers: acpi: iort: introduce iort_iommu_configure
drivers/acpi/arm64/iort.c | 595 +++++++++++++++++++++++++++++++++++++-
drivers/acpi/glue.c | 4 +-
drivers/acpi/scan.c | 45 +++
drivers/iommu/arm-smmu-v3.c | 105 +++++--
drivers/iommu/arm-smmu.c | 154 ++++++++--
drivers/iommu/iommu.c | 40 +++
drivers/iommu/of_iommu.c | 39 ---
drivers/pci/probe.c | 3 +-
include/acpi/acpi_bus.h | 2 +
include/asm-generic/vmlinux.lds.h | 1 +
include/linux/acpi.h | 26 ++
include/linux/acpi_iort.h | 14 +
include/linux/fwnode.h | 3 +-
include/linux/iommu.h | 14 +
include/linux/of_iommu.h | 12 +-
15 files changed, 953 insertions(+), 104 deletions(-)
--
2.10.0
From: Lorenzo Pieralisi <hidden> Date: 2016-11-16 15:28:47
On systems booting with a device tree, every struct device is associated
with a struct device_node, that provides its DT firmware 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 operations 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.
The struct acpi_device, that represents firmware objects in the
ACPI namespace already includes a struct fwnode_handle of
type FWNODE_ACPI as their member; the same abstraction is missing
though for devices that are instantiated out of static ACPI tables
entries (eg ARM SMMU devices).
Add a new fwnode_handle type to associate devices created out
of static ACPI table entries to the respective firmware components
and create a simple ACPI core layer interface to dynamically allocate
and free the corresponding firmware nodes so that kernel subsystems
can use it to instantiate the nodes and associate them with the
respective devices.
Signed-off-by: Lorenzo Pieralisi <redacted>
Acked-by: Rafael J. Wysocki <redacted>
Reviewed-by: Hanjun Guo <redacted>
Reviewed-by: Tomasz Nowicki <redacted>
Tested-by: Hanjun Guo <redacted>
Tested-by: Tomasz Nowicki <redacted>
Cc: "Rafael J. Wysocki" <redacted>
---
include/linux/acpi.h | 21 +++++++++++++++++++++
include/linux/fwnode.h | 3 ++-
2 files changed, 23 insertions(+), 1 deletion(-)
From: Lorenzo Pieralisi <hidden> Date: 2016-11-16 15:28:53
The ACPI IORT table provide entries for IOMMU (aka SMMU in ARM world)
components that allow creating the kernel data structures required to
probe and initialize the IOMMU devices.
This patch provides support in the IORT kernel code to register IOMMU
components and their respective fwnode.
Signed-off-by: Lorenzo Pieralisi <redacted>
Reviewed-by: Hanjun Guo <redacted>
Reviewed-by: Tomasz Nowicki <redacted>
Tested-by: Hanjun Guo <redacted>
Tested-by: Tomasz Nowicki <redacted>
Cc: Hanjun Guo <redacted>
Cc: Tomasz Nowicki <redacted>
Cc: "Rafael J. Wysocki" <redacted>
---
drivers/acpi/arm64/iort.c | 86 +++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 86 insertions(+)
From: Lorenzo Pieralisi <hidden> Date: 2016-11-16 15:28:55
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 <redacted>
Reviewed-by: Hanjun Guo <redacted>
Reviewed-by: Tomasz Nowicki <redacted>
Tested-by: Hanjun Guo <redacted>
Tested-by: Tomasz Nowicki <redacted>
Cc: Tomasz Nowicki <redacted>
Cc: "Rafael J. Wysocki" <redacted>
Cc: Marc Zyngier <redacted>
---
drivers/acpi/arm64/iort.c | 13 ++++++++++---
include/asm-generic/vmlinux.lds.h | 1 +
include/linux/acpi_iort.h | 3 +++
3 files changed, 14 insertions(+), 3 deletions(-)
@@ -361,8 +361,15 @@ void __init acpi_iort_init(void)acpi_statusstatus;status=acpi_get_table(ACPI_SIG_IORT,0,&iort_table);-if(ACPI_FAILURE(status)&&status!=AE_NOT_FOUND){-constchar*msg=acpi_format_exception(status);-pr_err("Failed to get table, %s\n",msg);+if(ACPI_FAILURE(status)){+if(status!=AE_NOT_FOUND){+constchar*msg=acpi_format_exception(status);++pr_err("Failed to get table, %s\n",msg);+}++return;}++acpi_probe_device_table(iort);}
From: Lorenzo Pieralisi <hidden> Date: 2016-11-16 15:29:01
Current ARM SMMU v3 driver rely on the struct device.of_node pointer for
device look-up and iommu_ops retrieval.
In preparation for ACPI probing enablement, convert the driver to use
the struct device.fwnode member for device and iommu_ops look-up so that
the driver infrastructure can be used also on systems that do not
associate an of_node pointer to a struct device (eg ACPI), making the
device look-up and iommu_ops retrieval firmware agnostic.
Signed-off-by: Lorenzo Pieralisi <redacted>
Reviewed-by: Robin Murphy <robin.murphy@arm.com>
Reviewed-by: Tomasz Nowicki <redacted>
Tested-by: Hanjun Guo <redacted>
Tested-by: Tomasz Nowicki <redacted>
Cc: Will Deacon <redacted>
Cc: Hanjun Guo <redacted>
Cc: Robin Murphy <robin.murphy@arm.com>
---
drivers/iommu/arm-smmu-v3.c | 12 +++++++-----
1 file changed, 7 insertions(+), 5 deletions(-)
@@ -1765,7 +1766,7 @@ static int arm_smmu_add_device(struct device *dev)master=fwspec->iommu_priv;smmu=master->smmu;}else{-smmu=arm_smmu_get_by_node(to_of_node(fwspec->iommu_fwnode));+smmu=arm_smmu_get_by_fwnode(fwspec->iommu_fwnode);if(!smmu)return-ENODEV;master=kzalloc(sizeof(*master),GFP_KERNEL);
@@ -2634,7 +2635,8 @@ static int arm_smmu_device_dt_probe(struct platform_device *pdev)returnret;/* And we're up. Go go go! */-of_iommu_set_ops(dev->of_node,&arm_smmu_ops);+iommu_register_instance(dev->fwnode,&arm_smmu_ops);+#ifdef CONFIG_PCIif(pci_bus_type.iommu_ops!=&arm_smmu_ops){pci_request_acs();
From: Will Deacon <hidden> Date: 2016-11-18 14:51:50
On Wed, Nov 16, 2016 at 03:29:26PM +0000, Lorenzo Pieralisi wrote:
Current ARM SMMU v3 driver rely on the struct device.of_node pointer for
device look-up and iommu_ops retrieval.
In preparation for ACPI probing enablement, convert the driver to use
the struct device.fwnode member for device and iommu_ops look-up so that
the driver infrastructure can be used also on systems that do not
associate an of_node pointer to a struct device (eg ACPI), making the
device look-up and iommu_ops retrieval firmware agnostic.
Signed-off-by: Lorenzo Pieralisi <redacted>
Reviewed-by: Robin Murphy <robin.murphy@arm.com>
Reviewed-by: Tomasz Nowicki <redacted>
Tested-by: Hanjun Guo <redacted>
Tested-by: Tomasz Nowicki <redacted>
Cc: Will Deacon <redacted>
Cc: Hanjun Guo <redacted>
Cc: Robin Murphy <robin.murphy@arm.com>
---
drivers/iommu/arm-smmu-v3.c | 12 +++++++-----
1 file changed, 7 insertions(+), 5 deletions(-)
From: Lorenzo Pieralisi <hidden> Date: 2016-11-16 15:29:04
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.
Since acpi_dma_configure() is used to configure DMA operations, the
function initializes the dma/coherent_dma masks to sane default values
if the current masks are uninitialized (also to keep the default values
consistent with DT systems) to make sure the device has a complete
default DMA set-up.
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 <redacted>
Acked-by: Bjorn Helgaas <bhelgaas@google.com> [pci]
Acked-by: Rafael J. Wysocki <redacted>
Reviewed-by: Tomasz Nowicki <redacted>
Tested-by: Hanjun Guo <redacted>
Tested-by: Tomasz Nowicki <redacted>
Cc: Bjorn Helgaas <bhelgaas@google.com>
Cc: Robin Murphy <robin.murphy@arm.com>
Cc: Tomasz Nowicki <redacted>
Cc: Joerg Roedel <joro@8bytes.org>
Cc: "Rafael J. Wysocki" <redacted>
---
drivers/acpi/glue.c | 4 ++--
drivers/acpi/scan.c | 40 ++++++++++++++++++++++++++++++++++++++++
drivers/pci/probe.c | 3 +--
include/acpi/acpi_bus.h | 2 ++
include/linux/acpi.h | 5 +++++
5 files changed, 50 insertions(+), 4 deletions(-)
From: Lorenzo Pieralisi <hidden> Date: 2016-11-16 15:29:10
Current ARM SMMU driver rely on the struct device.of_node pointer for
device look-up and iommu_ops retrieval.
In preparation for ACPI probing enablement, convert the driver to use
the struct device.fwnode member for device and iommu_ops look-up so that
the driver infrastructure can be used also on systems that do not
associate an of_node pointer to a struct device (eg ACPI), making the
device look-up and iommu_ops retrieval firmware agnostic.
Signed-off-by: Lorenzo Pieralisi <redacted>
Reviewed-by: Robin Murphy <robin.murphy@arm.com>
Reviewed-by: Tomasz Nowicki <redacted>
Tested-by: Hanjun Guo <redacted>
Tested-by: Tomasz Nowicki <redacted>
Cc: Will Deacon <redacted>
Cc: Hanjun Guo <redacted>
Cc: Robin Murphy <robin.murphy@arm.com>
---
drivers/iommu/arm-smmu.c | 11 ++++++-----
1 file changed, 6 insertions(+), 5 deletions(-)
From: Will Deacon <hidden> Date: 2016-11-18 14:49:58
On Wed, Nov 16, 2016 at 03:29:25PM +0000, Lorenzo Pieralisi wrote:
Current ARM SMMU driver rely on the struct device.of_node pointer for
device look-up and iommu_ops retrieval.
In preparation for ACPI probing enablement, convert the driver to use
the struct device.fwnode member for device and iommu_ops look-up so that
the driver infrastructure can be used also on systems that do not
associate an of_node pointer to a struct device (eg ACPI), making the
device look-up and iommu_ops retrieval firmware agnostic.
Signed-off-by: Lorenzo Pieralisi <redacted>
Reviewed-by: Robin Murphy <robin.murphy@arm.com>
Reviewed-by: Tomasz Nowicki <redacted>
Tested-by: Hanjun Guo <redacted>
Tested-by: Tomasz Nowicki <redacted>
Cc: Will Deacon <redacted>
Cc: Hanjun Guo <redacted>
Cc: Robin Murphy <robin.murphy@arm.com>
---
drivers/iommu/arm-smmu.c | 11 ++++++-----
1 file changed, 6 insertions(+), 5 deletions(-)
From: Lorenzo Pieralisi <hidden> Date: 2016-11-16 15:29:13
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 <redacted>
Reviewed-by: Tomasz Nowicki <redacted>
Tested-by: Hanjun Guo <redacted>
Tested-by: Tomasz Nowicki <redacted>
Cc: Hanjun Guo <redacted>
Cc: Tomasz Nowicki <redacted>
Cc: "Rafael J. Wysocki" <redacted>
---
drivers/acpi/arm64/iort.c | 15 +++++++++++++++
include/linux/acpi_iort.h | 2 ++
2 files changed, 17 insertions(+)
From: Lorenzo Pieralisi <hidden> Date: 2016-11-16 15:29:17
In ARM ACPI systems, IOMMU components are specified through static
IORT table entries. In order to create platform devices for the
corresponding ARM SMMU components, IORT kernel code should be made
able to parse IORT table entries and create platform devices
dynamically.
This patch adds the generic IORT infrastructure required to create
platform devices for ARM SMMUs.
ARM SMMU versions have different resources requirement therefore this
patch also introduces an IORT specific structure (ie iort_iommu_config)
that contains hooks (to be defined when the corresponding ARM SMMU
driver support is added to the kernel) to be used to define the
platform devices names, init the IOMMUs, count their resources and
finally initialize them.
Signed-off-by: Lorenzo Pieralisi <redacted>
Reviewed-by: Tomasz Nowicki <redacted>
Tested-by: Hanjun Guo <redacted>
Tested-by: Tomasz Nowicki <redacted>
Cc: Hanjun Guo <redacted>
Cc: Tomasz Nowicki <redacted>
Cc: "Rafael J. Wysocki" <redacted>
---
drivers/acpi/arm64/iort.c | 151 ++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 151 insertions(+)
@@ -457,6 +459,153 @@ struct irq_domain *iort_get_device_domain(struct device *dev, u32 req_id)returnirq_find_matching_fwnode(handle,DOMAIN_BUS_PCI_MSI);}+structiort_iommu_config{+constchar*name;+int(*iommu_init)(structacpi_iort_node*node);+bool(*iommu_is_coherent)(structacpi_iort_node*node);+int(*iommu_count_resources)(structacpi_iort_node*node);+void(*iommu_init_resources)(structresource*res,+structacpi_iort_node*node);+};++static__init+conststructiort_iommu_config*iort_get_iommu_cfg(structacpi_iort_node*node)+{+returnNULL;+}++/**+*iort_add_smmu_platform_device()-AllocateaplatformdeviceforSMMU+*@node:PointertoSMMUACPIIORTnode+*+*Returns:0onsuccess,<0failure+*/+staticint__initiort_add_smmu_platform_device(structacpi_iort_node*node)+{+structfwnode_handle*fwnode;+structplatform_device*pdev;+structresource*r;+enumdev_dma_attrattr;+intret,count;+conststructiort_iommu_config*ops=iort_get_iommu_cfg(node);++if(!ops)+return-ENODEV;++pdev=platform_device_alloc(ops->name,PLATFORM_DEVID_AUTO);+if(!pdev)+returnPTR_ERR(pdev);++count=ops->iommu_count_resources(node);++r=kcalloc(count,sizeof(*r),GFP_KERNEL);+if(!r){+ret=-ENOMEM;+gotodev_put;+}++ops->iommu_init_resources(r,node);++ret=platform_device_add_resources(pdev,r,count);+/*+*Resourcesareduplicatedinplatform_device_add_resources,+*freetheirallocatedmemory+*/+kfree(r);++if(ret)+gotodev_put;++/*+*AddacopyofIORTnodepointertoplatform_datato+*beusedtoretrieveIORTdatainformation.+*/+ret=platform_device_add_data(pdev,&node,sizeof(node));+if(ret)+gotodev_put;++/*+*Weexpectthedmamaskstobeequivalentfor+*allSMMUsset-ups+*/+pdev->dev.dma_mask=&pdev->dev.coherent_dma_mask;++fwnode=iort_get_fwnode(node);++if(!fwnode){+ret=-ENODEV;+gotodev_put;+}++pdev->dev.fwnode=fwnode;++attr=ops->iommu_is_coherent(node)?+DEV_DMA_COHERENT:DEV_DMA_NON_COHERENT;++/* Configure DMA for the page table walker */+acpi_dma_configure(&pdev->dev,attr);++ret=platform_device_add(pdev);+if(ret)+gotodma_deconfigure;++return0;++dma_deconfigure:+acpi_dma_deconfigure(&pdev->dev);+dev_put:+platform_device_put(pdev);++returnret;+}++staticvoid__initiort_init_platform_devices(void)+{+structacpi_iort_node*iort_node,*iort_end;+structacpi_table_iort*iort;+structfwnode_handle*fwnode;+inti,ret;++/*+*iort_tableandiortbothpointtothestartofIORTtable,but+*havedifferentstructtypes+*/+iort=(structacpi_table_iort*)iort_table;++/* Get the first IORT node */+iort_node=ACPI_ADD_PTR(structacpi_iort_node,iort,+iort->node_offset);+iort_end=ACPI_ADD_PTR(structacpi_iort_node,iort,+iort_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;+}++if((iort_node->type==ACPI_IORT_NODE_SMMU)||+(iort_node->type==ACPI_IORT_NODE_SMMU_V3)){++fwnode=acpi_alloc_fwnode_static();+if(!fwnode)+return;++iort_set_fwnode(iort_node,fwnode);++ret=iort_add_smmu_platform_device(iort_node);+if(ret){+iort_delete_fwnode(iort_node);+acpi_free_fwnode_static(fwnode);+return;+}+}++iort_node=ACPI_ADD_PTR(structacpi_iort_node,iort_node,+iort_node->length);+}+}+void__initacpi_iort_init(void){acpi_statusstatus;
From: Lorenzo Pieralisi <hidden> Date: 2016-11-16 15:29:20
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 <redacted>
Acked-by: Will Deacon <redacted>
Reviewed-by: Tomasz Nowicki <redacted>
Tested-by: Hanjun Guo <redacted>
Tested-by: Tomasz Nowicki <redacted>
Cc: Will Deacon <redacted>
Cc: Hanjun Guo <redacted>
Cc: Robin Murphy <robin.murphy@arm.com>
Cc: Joerg Roedel <joro@8bytes.org>
---
drivers/iommu/arm-smmu-v3.c | 46 +++++++++++++++++++++++++++++----------------
1 file changed, 30 insertions(+), 16 deletions(-)
From: Will Deacon <hidden> Date: 2016-11-18 15:44:16
On Wed, Nov 16, 2016 at 03:29:30PM +0000, Lorenzo Pieralisi wrote:
quoted hunk
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 <redacted>
Acked-by: Will Deacon <redacted>
Reviewed-by: Tomasz Nowicki <redacted>
Tested-by: Hanjun Guo <redacted>
Tested-by: Tomasz Nowicki <redacted>
Cc: Will Deacon <redacted>
Cc: Hanjun Guo <redacted>
Cc: Robin Murphy <robin.murphy@arm.com>
Cc: Joerg Roedel <joro@8bytes.org>
---
drivers/iommu/arm-smmu-v3.c | 46 +++++++++++++++++++++++++++++----------------
1 file changed, 30 insertions(+), 16 deletions(-)
@@ -2436,13 +2436,9 @@ static int arm_smmu_device_probe(struct arm_smmu_device *smmu)smmu->features|=ARM_SMMU_FEAT_HYP;/*-*Thedma-coherentpropertyisusedinpreferencetotheID+*ThecoherencyfeatureassetbyFWisusedinpreferencetotheID*register,butwarnonmismatch.*/-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");
@@ -2563,21 +2559,37 @@ static int arm_smmu_device_probe(struct arm_smmu_device *smmu)return0;}-staticintarm_smmu_device_dt_probe(structplatform_device*pdev)+staticintarm_smmu_device_dt_probe(structplatform_device*pdev,+structarm_smmu_device*smmu,+bool*bypass){-intirq,ret;-structresource*res;-structarm_smmu_device*smmu;structdevice*dev=&pdev->dev;-boolbypass=true;u32cells;+*bypass=true;+if(of_property_read_u32(dev->of_node,"#iommu-cells",&cells))dev_err(dev,"missing #iommu-cells property\n");elseif(cells!=1)dev_err(dev,"invalid #iommu-cells value (%d)\n",cells);else-bypass=false;+*bypass=false;++parse_driver_options(smmu);++if(of_dma_is_coherent(dev->of_node))+smmu->features|=ARM_SMMU_FEAT_COHERENCY;++return0;
I know you're only moving code here, but the *bypass output parameter
now seems to be redundant with the unconditional return 0. Given that
we only set bypass to true if something went wrong, why don't we return
-ENODEV in those cases, kill the bypass parameter and rework the return
value check in the caller so that, rather than fail the probe, we pass
bypass=true to the reset function?
Will
From: Lorenzo Pieralisi <hidden> Date: 2016-11-16 15:29:27
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 <redacted>
Reviewed-by: Tomasz Nowicki <redacted>
Tested-by: Hanjun Guo <redacted>
Tested-by: Tomasz Nowicki <redacted>
Cc: Will Deacon <redacted>
Cc: Robin Murphy <robin.murphy@arm.com>
Cc: Joerg Roedel <joro@8bytes.org>
---
drivers/acpi/arm64/iort.c | 103 +++++++++++++++++++++++++++++++++++++++++++-
drivers/iommu/arm-smmu-v3.c | 49 ++++++++++++++++++++-
2 files changed, 150 insertions(+), 2 deletions(-)
@@ -459,6 +459,95 @@ struct irq_domain *iort_get_device_domain(struct device *dev, u32 req_id)returnirq_find_matching_fwnode(handle,DOMAIN_BUS_PCI_MSI);}+staticvoid__initacpi_iort_register_irq(inthwirq,constchar*name,+inttrigger,+structresource*res)+{+intirq=acpi_register_gsi(NULL,hwirq,trigger,+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;+}++staticint__initarm_smmu_v3_count_resources(structacpi_iort_node*node)+{+structacpi_iort_smmu_v3*smmu;+/* Always present mem resource */+intnum_res=1;++/* Retrieve SMMUv3 specific data */+smmu=(structacpi_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++;++returnnum_res;+}++staticvoid__initarm_smmu_v3_init_resources(structresource*res,+structacpi_iort_node*node)+{+structacpi_iort_smmu_v3*smmu;+intnum_res=0;++/* Retrieve SMMUv3 specific data */+smmu=(structacpi_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_iort_register_irq(smmu->event_gsiv,"eventq",+ACPI_EDGE_SENSITIVE,+&res[num_res++]);++if(smmu->pri_gsiv)+acpi_iort_register_irq(smmu->pri_gsiv,"priq",+ACPI_EDGE_SENSITIVE,+&res[num_res++]);++if(smmu->gerr_gsiv)+acpi_iort_register_irq(smmu->gerr_gsiv,"gerror",+ACPI_EDGE_SENSITIVE,+&res[num_res++]);++if(smmu->sync_gsiv)+acpi_iort_register_irq(smmu->sync_gsiv,"cmdq-sync",+ACPI_EDGE_SENSITIVE,+&res[num_res++]);+}++staticbool__initarm_smmu_v3_is_coherent(structacpi_iort_node*node)+{+structacpi_iort_smmu_v3*smmu;++/* Retrieve SMMUv3 specific data */+smmu=(structacpi_iort_smmu_v3*)node->node_data;++returnsmmu->flags&ACPI_IORT_SMMU_V3_COHACC_OVERRIDE;+}+structiort_iommu_config{constchar*name;int(*iommu_init)(structacpi_iort_node*node);
@@ -2559,6 +2561,36 @@ static int arm_smmu_device_hw_probe(struct arm_smmu_device *smmu)return0;}+#ifdef CONFIG_ACPI+staticintarm_smmu_device_acpi_probe(structplatform_device*pdev,+structarm_smmu_device*smmu,+bool*bypass)+{+structacpi_iort_smmu_v3*iort_smmu;+structdevice*dev=smmu->dev;+structacpi_iort_node*node;++node=*(structacpi_iort_node**)dev_get_platdata(dev);++/* Retrieve SMMUv3 specific data */+iort_smmu=(structacpi_iort_smmu_v3*)node->node_data;++if(iort_smmu->flags&ACPI_IORT_SMMU_V3_COHACC_OVERRIDE)+smmu->features|=ARM_SMMU_FEAT_COHERENCY;++*bypass=false;++return0;+}+#else+staticinlineintarm_smmu_device_acpi_probe(structplatform_device*pdev,+structarm_smmu_device*smmu,+bool*bypass)+{+return-ENODEV;+}+#endif+staticintarm_smmu_device_dt_probe(structplatform_device*pdev,structarm_smmu_device*smmu,bool*bypass)
@@ -2626,7 +2658,11 @@ static int arm_smmu_device_probe(struct platform_device *pdev)if(irq>0)smmu->gerr_irq=irq;-ret=arm_smmu_device_dt_probe(pdev,smmu,&bypass);+if(dev->of_node)+ret=arm_smmu_device_dt_probe(pdev,smmu,&bypass);+else+ret=arm_smmu_device_acpi_probe(pdev,smmu,&bypass);+if(ret)returnret;
@@ -2731,6 +2767,17 @@ 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+staticint__initacpi_smmu_v3_init(structacpi_table_header*table)+{+if(iort_node_match(ACPI_IORT_NODE_SMMU_V3))+returnarm_smmu_init();++return0;+}+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");
From: Will Deacon <hidden> Date: 2016-11-18 15:55:49
On Wed, Nov 16, 2016 at 03:29:31PM +0000, Lorenzo Pieralisi wrote:
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 <redacted>
Reviewed-by: Tomasz Nowicki <redacted>
Tested-by: Hanjun Guo <redacted>
Tested-by: Tomasz Nowicki <redacted>
Cc: Will Deacon <redacted>
Cc: Robin Murphy <robin.murphy@arm.com>
Cc: Joerg Roedel <joro@8bytes.org>
---
drivers/acpi/arm64/iort.c | 103 +++++++++++++++++++++++++++++++++++++++++++-
drivers/iommu/arm-smmu-v3.c | 49 ++++++++++++++++++++-
2 files changed, 150 insertions(+), 2 deletions(-)
@@ -2559,6 +2561,36 @@ static int arm_smmu_device_hw_probe(struct arm_smmu_device *smmu)return0;}+#ifdef CONFIG_ACPI+staticintarm_smmu_device_acpi_probe(structplatform_device*pdev,+structarm_smmu_device*smmu,+bool*bypass)+{+structacpi_iort_smmu_v3*iort_smmu;+structdevice*dev=smmu->dev;+structacpi_iort_node*node;++node=*(structacpi_iort_node**)dev_get_platdata(dev);++/* Retrieve SMMUv3 specific data */+iort_smmu=(structacpi_iort_smmu_v3*)node->node_data;++if(iort_smmu->flags&ACPI_IORT_SMMU_V3_COHACC_OVERRIDE)+smmu->features|=ARM_SMMU_FEAT_COHERENCY;++*bypass=false;++return0;+}+#else+staticinlineintarm_smmu_device_acpi_probe(structplatform_device*pdev,+structarm_smmu_device*smmu,+bool*bypass)+{+return-ENODEV;+}+#endif
Same bypass comments as before, but you'll probably need to do something
so that you *can* abort the probe if !ACPI, perhaps by allocating two
error codes to distinguish the "I no nothing about this SMMU" from "I know
enough to put it into bypass, but nothing more".
Will
From: Lorenzo Pieralisi <hidden> Date: 2016-11-16 15:29:31
Current ARM SMMU probe functions intermingle HW and DT probing
in the initialization functions to detect and programme the ARM SMMU
driver features. In order to allow probing the ARM SMMU with other
firmwares than DT, this patch splits the ARM SMMU 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 <redacted>
Reviewed-by: Tomasz Nowicki <redacted>
Tested-by: Hanjun Guo <redacted>
Tested-by: Tomasz Nowicki <redacted>
Cc: Will Deacon <redacted>
Cc: Hanjun Guo <redacted>
Cc: Robin Murphy <robin.murphy@arm.com>
---
drivers/iommu/arm-smmu.c | 62 +++++++++++++++++++++++++++++-------------------
1 file changed, 37 insertions(+), 25 deletions(-)
@@ -1713,20 +1713,17 @@ static int arm_smmu_device_cfg_probe(struct arm_smmu_device *smmu)/**InorderforDMAAPIcallstoworkproperly,wemustdefertowhat-*theDTsaysaboutcoherency,regardlessofwhatthehardwareclaims.+*theFWsaysaboutcoherency,regardlessofwhatthehardwareclaims.*Fortunately,thisalsoopensupaworkaroundforsystemswherethe*IDregistervaluehasendedupconfiguredincorrectly.*/-cttw_dt=of_dma_is_coherent(smmu->dev->of_node);cttw_reg=!!(id&ID0_CTTW);-if(cttw_dt)-smmu->features|=ARM_SMMU_FEAT_COHERENT_WALK;-if(cttw_dt||cttw_reg)+if(cttw_fw||cttw_reg)dev_notice(smmu->dev,"\t%scoherent table walk\n",-cttw_dt?"":"non-");-if(cttw_dt!=cttw_reg)+cttw_fw?"":"non-");+if(cttw_fw!=cttw_reg)dev_notice(smmu->dev,-"\t(IDR0.CTTW overridden by dma-coherent property)\n");+"\t(IDR0.CTTW overridden by FW configuration)\n");/* Max. number of entries we have for stream matching/indexing */size=1<<((id>>ID0_NUMSIDB_SHIFT)&ID0_NUMSIDB_MASK);
From: Will Deacon <hidden> Date: 2016-11-18 16:00:09
On Wed, Nov 16, 2016 at 03:29:32PM +0000, Lorenzo Pieralisi wrote:
Current ARM SMMU probe functions intermingle HW and DT probing
in the initialization functions to detect and programme the ARM SMMU
driver features. In order to allow probing the ARM SMMU with other
firmwares than DT, this patch splits the ARM SMMU 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 <redacted>
Reviewed-by: Tomasz Nowicki <redacted>
Tested-by: Hanjun Guo <redacted>
Tested-by: Tomasz Nowicki <redacted>
Cc: Will Deacon <redacted>
Cc: Hanjun Guo <redacted>
Cc: Robin Murphy <robin.murphy@arm.com>
---
drivers/iommu/arm-smmu.c | 62 +++++++++++++++++++++++++++++-------------------
1 file changed, 37 insertions(+), 25 deletions(-)
Reviewed-by: Will Deacon <redacted>
Although I'd also like Robin to have a look at this.
Will
From: Robin Murphy <robin.murphy@arm.com> Date: 2016-11-18 16:43:38
On 18/11/16 16:00, Will Deacon wrote:
On Wed, Nov 16, 2016 at 03:29:32PM +0000, Lorenzo Pieralisi wrote:
quoted
Current ARM SMMU probe functions intermingle HW and DT probing
in the initialization functions to detect and programme the ARM SMMU
driver features. In order to allow probing the ARM SMMU with other
firmwares than DT, this patch splits the ARM SMMU 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 <redacted>
Reviewed-by: Tomasz Nowicki <redacted>
Tested-by: Hanjun Guo <redacted>
Tested-by: Tomasz Nowicki <redacted>
Cc: Will Deacon <redacted>
Cc: Hanjun Guo <redacted>
Cc: Robin Murphy <robin.murphy@arm.com>
---
drivers/iommu/arm-smmu.c | 62 +++++++++++++++++++++++++++++-------------------
1 file changed, 37 insertions(+), 25 deletions(-)
Reviewed-by: Will Deacon <redacted>
Although I'd also like Robin to have a look at this.
Sorry, I've been slow this week. Having finally got round to taking a
proper look, I swear this seems even tidier than the last version I
looked at closely. It doesn't break DT boot on my Juno, either.
Reviewed-by: Robin Murphy <robin.murphy@arm.com>
From: Lorenzo Pieralisi <hidden> Date: 2016-11-16 15:29:35
In ACPI bases systems, in order to be able to create platform
devices and initialize them for ARM SMMU 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 components.
Add static configuration functions to the IORT kernel layer for
the ARM SMMU components, so that the ARM SMMU 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 <redacted>
Reviewed-by: Tomasz Nowicki <redacted>
Tested-by: Hanjun Guo <redacted>
Tested-by: Tomasz Nowicki <redacted>
Cc: Will Deacon <redacted>
Cc: Robin Murphy <robin.murphy@arm.com>
Cc: Joerg Roedel <joro@8bytes.org>
---
drivers/acpi/arm64/iort.c | 81 +++++++++++++++++++++++++++++++++++++++++++++
drivers/iommu/arm-smmu.c | 83 ++++++++++++++++++++++++++++++++++++++++++++++-
include/linux/acpi_iort.h | 3 ++
3 files changed, 166 insertions(+), 1 deletion(-)
@@ -548,6 +548,78 @@ static bool __init arm_smmu_v3_is_coherent(struct acpi_iort_node *node)returnsmmu->flags&ACPI_IORT_SMMU_V3_COHACC_OVERRIDE;}+staticint__initarm_smmu_count_resources(structacpi_iort_node*node)+{+structacpi_iort_smmu*smmu;+intnum_irqs;+u64*glb_irq;++/* Retrieve SMMU specific data */+smmu=(structacpi_iort_smmu*)node->node_data;++glb_irq=ACPI_ADD_PTR(u64,node,smmu->global_interrupt_offset);+if(!IORT_IRQ_MASK(glb_irq[1]))/* 0 means not implemented */+num_irqs=1;+else+num_irqs=2;++num_irqs+=smmu->context_interrupt_count;++returnnum_irqs+1;+}++staticvoid__initarm_smmu_init_resources(structresource*res,+structacpi_iort_node*node)+{+structacpi_iort_smmu*smmu;+inti,hw_irq,trigger,num_res=0;+u64*ctx_irq,*glb_irq;++/* Retrieve SMMU specific data */+smmu=(structacpi_iort_smmu*)node->node_data;++res[num_res].start=smmu->base_address;+res[num_res].end=smmu->base_address+smmu->span-1;+res[num_res].flags=IORESOURCE_MEM;+num_res++;++glb_irq=ACPI_ADD_PTR(u64,node,smmu->global_interrupt_offset);+/* Global IRQs */+hw_irq=IORT_IRQ_MASK(glb_irq[0]);+trigger=IORT_IRQ_TRIGGER_MASK(glb_irq[0]);++acpi_iort_register_irq(hw_irq,"arm-smmu-global",trigger,+&res[num_res++]);++/* Global IRQs */+hw_irq=IORT_IRQ_MASK(glb_irq[1]);+if(hw_irq){+trigger=IORT_IRQ_TRIGGER_MASK(glb_irq[1]);+acpi_iort_register_irq(hw_irq,"arm-smmu-global",trigger,+&res[num_res++]);+}++/* Context IRQs */+ctx_irq=ACPI_ADD_PTR(u64,node,smmu->context_interrupt_offset);+for(i=0;i<smmu->context_interrupt_count;i++){+hw_irq=IORT_IRQ_MASK(ctx_irq[i]);+trigger=IORT_IRQ_TRIGGER_MASK(ctx_irq[i]);++acpi_iort_register_irq(hw_irq,"arm-smmu-context",trigger,+&res[num_res++]);+}+}++staticbool__initarm_smmu_is_coherent(structacpi_iort_node*node)+{+structacpi_iort_smmu*smmu;++/* Retrieve SMMU specific data */+smmu=(structacpi_iort_smmu*)node->node_data;++returnsmmu->flags&ACPI_IORT_SMMU_COHERENT_WALK;+}+structiort_iommu_config{constchar*name;int(*iommu_init)(structacpi_iort_node*node);
From: Will Deacon <hidden> Date: 2016-11-18 16:08:12
On Wed, Nov 16, 2016 at 03:29:33PM +0000, Lorenzo Pieralisi wrote:
In ACPI bases systems, in order to be able to create platform
devices and initialize them for ARM SMMU 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 components.
Add static configuration functions to the IORT kernel layer for
the ARM SMMU components, so that the ARM SMMU 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 <redacted>
Reviewed-by: Tomasz Nowicki <redacted>
Tested-by: Hanjun Guo <redacted>
Tested-by: Tomasz Nowicki <redacted>
Cc: Will Deacon <redacted>
Cc: Robin Murphy <robin.murphy@arm.com>
Cc: Joerg Roedel <joro@8bytes.org>
---
drivers/acpi/arm64/iort.c | 81 +++++++++++++++++++++++++++++++++++++++++++++
drivers/iommu/arm-smmu.c | 83 ++++++++++++++++++++++++++++++++++++++++++++++-
include/linux/acpi_iort.h | 3 ++
3 files changed, 166 insertions(+), 1 deletion(-)
From: Robin Murphy <robin.murphy@arm.com> Date: 2016-11-18 17:36:53
On 16/11/16 15:29, Lorenzo Pieralisi wrote:
In ACPI bases systems, in order to be able to create platform
based?
quoted hunk
devices and initialize them for ARM SMMU 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 components.
Add static configuration functions to the IORT kernel layer for
the ARM SMMU components, so that the ARM SMMU 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 <redacted>
Reviewed-by: Tomasz Nowicki <redacted>
Tested-by: Hanjun Guo <redacted>
Tested-by: Tomasz Nowicki <redacted>
Cc: Will Deacon <redacted>
Cc: Robin Murphy <robin.murphy@arm.com>
Cc: Joerg Roedel <joro@8bytes.org>
---
drivers/acpi/arm64/iort.c | 81 +++++++++++++++++++++++++++++++++++++++++++++
drivers/iommu/arm-smmu.c | 83 ++++++++++++++++++++++++++++++++++++++++++++++-
include/linux/acpi_iort.h | 3 ++
3 files changed, 166 insertions(+), 1 deletion(-)
@@ -548,6 +548,78 @@ static bool __init arm_smmu_v3_is_coherent(struct acpi_iort_node *node)returnsmmu->flags&ACPI_IORT_SMMU_V3_COHACC_OVERRIDE;}+staticint__initarm_smmu_count_resources(structacpi_iort_node*node)+{+structacpi_iort_smmu*smmu;+intnum_irqs;+u64*glb_irq;++/* Retrieve SMMU specific data */+smmu=(structacpi_iort_smmu*)node->node_data;++glb_irq=ACPI_ADD_PTR(u64,node,smmu->global_interrupt_offset);+if(!IORT_IRQ_MASK(glb_irq[1]))/* 0 means not implemented */+num_irqs=1;+else+num_irqs=2;
Do we actually need this - I mean, the configuration access interrupt is
of somewhat limited utility, implementation-defined, and we don't have
any handling for it. Nor should it, if present, ever happen anyway,
since it's not like anyone else should be randomly poking our SMMU in
invalid ways. Can we simply ignore it?
Related to the above, I think the driver generally assumes these to be
the global fault interrupt. If we *are* going to claim the config
interrupt as well, we should probably disambiguate them, although
admittedly we can't really do that retrospectively on the DT side.
From: Lorenzo Pieralisi <hidden> Date: 2016-11-18 18:03:01
On Fri, Nov 18, 2016 at 05:36:46PM +0000, Robin Murphy wrote:
On 16/11/16 15:29, Lorenzo Pieralisi wrote:
quoted
In ACPI bases systems, in order to be able to create platform
based?
Ok.
quoted
devices and initialize them for ARM SMMU 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 components.
Add static configuration functions to the IORT kernel layer for
the ARM SMMU components, so that the ARM SMMU 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 <redacted>
Reviewed-by: Tomasz Nowicki <redacted>
Tested-by: Hanjun Guo <redacted>
Tested-by: Tomasz Nowicki <redacted>
Cc: Will Deacon <redacted>
Cc: Robin Murphy <robin.murphy@arm.com>
Cc: Joerg Roedel <joro@8bytes.org>
---
drivers/acpi/arm64/iort.c | 81 +++++++++++++++++++++++++++++++++++++++++++++
drivers/iommu/arm-smmu.c | 83 ++++++++++++++++++++++++++++++++++++++++++++++-
include/linux/acpi_iort.h | 3 ++
3 files changed, 166 insertions(+), 1 deletion(-)
@@ -548,6 +548,78 @@ static bool __init arm_smmu_v3_is_coherent(struct acpi_iort_node *node)returnsmmu->flags&ACPI_IORT_SMMU_V3_COHACC_OVERRIDE;}+staticint__initarm_smmu_count_resources(structacpi_iort_node*node)+{+structacpi_iort_smmu*smmu;+intnum_irqs;+u64*glb_irq;++/* Retrieve SMMU specific data */+smmu=(structacpi_iort_smmu*)node->node_data;++glb_irq=ACPI_ADD_PTR(u64,node,smmu->global_interrupt_offset);+if(!IORT_IRQ_MASK(glb_irq[1]))/* 0 means not implemented */+num_irqs=1;+else+num_irqs=2;
Do we actually need this - I mean, the configuration access interrupt is
of somewhat limited utility, implementation-defined, and we don't have
any handling for it. Nor should it, if present, ever happen anyway,
since it's not like anyone else should be randomly poking our SMMU in
invalid ways. Can we simply ignore it?
I added its parsing to bring the same capabilities present in DT to
ACPI, from what you are saying I think that we'd better ignore it
and add its parsing later if we _ever_ need to handle it.
Related to the above, I think the driver generally assumes these to be
the global fault interrupt. If we *are* going to claim the config
interrupt as well, we should probably disambiguate them, although
admittedly we can't really do that retrospectively on the DT side.
I do not think we are missing functionality if for the time being
we just ignore the configuration access interrupt so that's what
I will do for this first version.
Thanks !
Lorenzo
From: Lorenzo Pieralisi <hidden> Date: 2016-11-16 15:29:38
IORT tables provide data that allow the kernel to carry out
device ID mappings between endpoints and system components
(eg interrupt controllers, IOMMUs). When the mapping for a
given device ID is carried out, the translation mechanism
is done on a per-subsystem basis rather than a component
subtype (ie the IOMMU kernel layer will look for mappings
from a device to all IORT node types corresponding to IOMMU
components), therefore the corresponding mapping API should
work on a range (ie mask) of IORT node types corresponding
to a common set of components (eg IOMMUs) rather than a
specific node type.
Upgrade the IORT iort_node_map_rid() API to work with a
type mask instead of a single node type so that it can
be used for mappings that span multiple components types
(ie IOMMUs).
Signed-off-by: Lorenzo Pieralisi <redacted>
Reviewed-by: Tomasz Nowicki <redacted>
Tested-by: Hanjun Guo <redacted>
Tested-by: Tomasz Nowicki <redacted>
Cc: Hanjun Guo <redacted>
Cc: Tomasz Nowicki <redacted>
Cc: "Rafael J. Wysocki" <redacted>
---
drivers/acpi/arm64/iort.c | 11 +++++++----
1 file changed, 7 insertions(+), 4 deletions(-)
From: Lorenzo Pieralisi <hidden> Date: 2016-11-16 15:30:05
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 <redacted>
Acked-by: Rafael J. Wysocki <redacted> [ACPI core]
Reviewed-by: Tomasz Nowicki <redacted>
Tested-by: Hanjun Guo <redacted>
Tested-by: Tomasz Nowicki <redacted>
Cc: Hanjun Guo <redacted>
Cc: Tomasz Nowicki <redacted>
Cc: "Rafael J. Wysocki" <redacted>
---
drivers/acpi/arm64/iort.c | 98 +++++++++++++++++++++++++++++++++++++++++++++++
drivers/acpi/scan.c | 7 +++-
include/linux/acpi_iort.h | 6 +++
3 files changed, 110 insertions(+), 1 deletion(-)
From: Lorenzo Pieralisi <hidden> Date: 2016-11-16 15:30:56
The current IORT id mapping API requires components to provide
an input requester ID (a Bus-Device-Function (BDF) identifier for
PCI devices) to translate an input identifier to an output
identifier through an IORT range mapping.
Named components do not have an identifiable source ID therefore
their respective input/output mapping can only be defined in
IORT tables through single mappings, that provide a translation
that does not require any input identifier.
Current IORT interface for requester id mappings (iort_node_map_rid())
is not suitable for components that do not provide a requester id,
so it cannot be used for IORT named components.
Add an interface to the IORT API to enable retrieval of id
by allowing an indexed walk of the single mappings array for
a given component, therefore completing the IORT mapping API.
Signed-off-by: Lorenzo Pieralisi <redacted>
Reviewed-by: Tomasz Nowicki <redacted>
Tested-by: Hanjun Guo <redacted>
Tested-by: Tomasz Nowicki <redacted>
Cc: Hanjun Guo <redacted>
Cc: Tomasz Nowicki <redacted>
Cc: "Rafael J. Wysocki" <redacted>
---
drivers/acpi/arm64/iort.c | 39 +++++++++++++++++++++++++++++++++++++++
1 file changed, 39 insertions(+)
From: Lorenzo Pieralisi <hidden> Date: 2016-11-16 15:33:34
The of_iommu_{set/get}_ops() API is used to associate a device
tree node with a specific set of IOMMU operations. The same
kernel interface is required on systems booting with ACPI, where
devices are not associated with a device tree node, therefore
the interface requires generalization.
The struct device fwnode member represents the fwnode token associated
with the device and the struct it points at is firmware specific;
regardless, it is initialized on both ACPI and DT systems and makes an
ideal candidate to use it to associate a set of IOMMU operations to a
given device, through its struct device.fwnode member pointer, paving
the way for representing per-device iommu_ops (ie an iommu instance
associated with a device).
Convert the DT specific of_iommu_{set/get}_ops() interface to
use struct device.fwnode as a look-up token, making the interface
usable on ACPI systems and rename the data structures and the
registration API so that they are made to represent their usage
more clearly.
Signed-off-by: Lorenzo Pieralisi <redacted>
Reviewed-by: Robin Murphy <robin.murphy@arm.com>
Reviewed-by: Tomasz Nowicki <redacted>
Tested-by: Hanjun Guo <redacted>
Tested-by: Tomasz Nowicki <redacted>
Cc: Will Deacon <redacted>
Cc: Hanjun Guo <redacted>
Cc: Robin Murphy <robin.murphy@arm.com>
Cc: Joerg Roedel <joro@8bytes.org>
---
drivers/iommu/iommu.c | 40 ++++++++++++++++++++++++++++++++++++++++
drivers/iommu/of_iommu.c | 39 ---------------------------------------
include/linux/iommu.h | 14 ++++++++++++++
include/linux/of_iommu.h | 12 ++++++++++--
4 files changed, 64 insertions(+), 41 deletions(-)
From: Will Deacon <hidden> Date: 2016-11-18 14:49:21
On Wed, Nov 16, 2016 at 03:29:24PM +0000, Lorenzo Pieralisi wrote:
The of_iommu_{set/get}_ops() API is used to associate a device
tree node with a specific set of IOMMU operations. The same
kernel interface is required on systems booting with ACPI, where
devices are not associated with a device tree node, therefore
the interface requires generalization.
The struct device fwnode member represents the fwnode token associated
with the device and the struct it points at is firmware specific;
regardless, it is initialized on both ACPI and DT systems and makes an
ideal candidate to use it to associate a set of IOMMU operations to a
given device, through its struct device.fwnode member pointer, paving
the way for representing per-device iommu_ops (ie an iommu instance
associated with a device).
Convert the DT specific of_iommu_{set/get}_ops() interface to
use struct device.fwnode as a look-up token, making the interface
usable on ACPI systems and rename the data structures and the
registration API so that they are made to represent their usage
more clearly.
Signed-off-by: Lorenzo Pieralisi <redacted>
Reviewed-by: Robin Murphy <robin.murphy@arm.com>
Reviewed-by: Tomasz Nowicki <redacted>
Tested-by: Hanjun Guo <redacted>
Tested-by: Tomasz Nowicki <redacted>
Cc: Will Deacon <redacted>
Cc: Hanjun Guo <redacted>
Cc: Robin Murphy <robin.murphy@arm.com>
Cc: Joerg Roedel <joro@8bytes.org>
---
drivers/iommu/iommu.c | 40 ++++++++++++++++++++++++++++++++++++++++
drivers/iommu/of_iommu.c | 39 ---------------------------------------
include/linux/iommu.h | 14 ++++++++++++++
include/linux/of_iommu.h | 12 ++++++++++--
4 files changed, 64 insertions(+), 41 deletions(-)