All of lore.kernel.org
 help / color / mirror / Atom feed
* [RFC PATCH v2 00/15] ACPI IORT ARM SMMU v3 support
@ 2016-06-07 13:30 ` Lorenzo Pieralisi
  0 siblings, 0 replies; 88+ messages in thread
From: Lorenzo Pieralisi @ 2016-06-07 13:30 UTC (permalink / raw)
  To: iommu
  Cc: Lorenzo Pieralisi, Will Deacon, Marc Zyngier, Robin Murphy,
	Joerg Roedel, Rafael J. Wysocki, Tomasz Nowicki, Hanjun Guo,
	Jon Masters, Sinan Kaya, linux-acpi, linux-pci, linux-kernel,
	linux-arm-kernel

This RFC patch series is v2 of a previous posting:

https://lkml.org/lkml/2016/4/14/702

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-2) fix compile warning/errors in [2]

PATCH (3) rework ARM64 IOMMU bus notifier to attach dma_ops.

PATCH (4) provides IORT support for registering IOMMU components.

PATCH (5) adds IORT based look-up for named components.

PATCH (6) improve IORT identifiers mapping API to make it work across
          all possible IORT components.

PATCH (7) provides an IORT function to detect existence of specific type
          of IORT components.

PATCH (8) 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 (9) rework ARM SMMU v3 platform driver registration to make it work on
          ACPI systems.

PATCH (10) creates the kernel infrastructure required to create ARM SMMU
           platform devices for IORT nodes.

PATCH (11) Building on patch (10), it adds ARM SMMU v3 IORT IOMMU operations
           to create and probe ARM SMMU v3 components.

PATCH (12) 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 (13) provides IORT infrastructure to carry out IOMMU configuration
           for devices and hook it up to the previously introduced ACPI
           DMA configure API.

PATCH (14) define a function to look-up platform devices through their
           respective IORT nodes stored in platform_data. This patch is
           somewhat controversial and is provided as an initial solution
           to the problem pending further discussions.

PATCH (15) provides code to carry out ACPI IORT based device identifiers
           translation for ARM SMMU v3 components.

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"
    http://marc.info/?l=linux-arm-kernel&m=146497432413816&w=2

[2] T.Nowicki "Introduce ACPI world to ITS irqchip" v5
    http://marc.info/?l=linux-acpi&m=146469369703684&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-v2

Tested on FVP models for ARM SMMU v3 probing path.

Lorenzo Pieralisi (15):
  drivers: acpi: iort: fix struct pci_dev compiler warnings
  drivers: irqchip: its: fix its_acpi_probe() prototype
  arm64: mm: change IOMMU notifier action to attach DMA ops
  drivers: acpi: iort: add support for IOMMU registration
  drivers: acpi: iort: add support for named component look-up
  drivers: acpi: iort: enhance device identifiers mappings
  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 iommu configuration
  drivers: acpi: implement acpi_dma_configure
  drivers: acpi: iort: introduce iort_iommu_configure
  drivers: acpi: iort: add function to retrieve IOMMU platform devices
  drivers: iommu: arm-smmu-v3: allow ACPI based streamid translation

 arch/arm64/mm/dma-mapping.c      |   2 +-
 drivers/acpi/glue.c              |   4 +-
 drivers/acpi/iort.c              | 361 ++++++++++++++++++++++++++++++++++++++-
 drivers/acpi/scan.c              |  29 ++++
 drivers/iommu/arm-smmu-v3.c      | 235 ++++++++++++++++++++++---
 drivers/irqchip/irq-gic-v3-its.c |   2 +-
 drivers/pci/probe.c              |   3 +-
 include/acpi/acpi_bus.h          |   2 +
 include/linux/acpi.h             |   5 +
 include/linux/iort.h             |  43 +++++
 10 files changed, 652 insertions(+), 34 deletions(-)

-- 
2.6.4


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

* [RFC PATCH v2 00/15] ACPI IORT ARM SMMU v3 support
@ 2016-06-07 13:30 ` Lorenzo Pieralisi
  0 siblings, 0 replies; 88+ messages in thread
From: Lorenzo Pieralisi @ 2016-06-07 13:30 UTC (permalink / raw)
  To: linux-arm-kernel

This RFC patch series is v2 of a previous posting:

https://lkml.org/lkml/2016/4/14/702

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-2) fix compile warning/errors in [2]

PATCH (3) rework ARM64 IOMMU bus notifier to attach dma_ops.

PATCH (4) provides IORT support for registering IOMMU components.

PATCH (5) adds IORT based look-up for named components.

PATCH (6) improve IORT identifiers mapping API to make it work across
          all possible IORT components.

PATCH (7) provides an IORT function to detect existence of specific type
          of IORT components.

PATCH (8) 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 (9) rework ARM SMMU v3 platform driver registration to make it work on
          ACPI systems.

PATCH (10) creates the kernel infrastructure required to create ARM SMMU
           platform devices for IORT nodes.

PATCH (11) Building on patch (10), it adds ARM SMMU v3 IORT IOMMU operations
           to create and probe ARM SMMU v3 components.

PATCH (12) 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 (13) provides IORT infrastructure to carry out IOMMU configuration
           for devices and hook it up to the previously introduced ACPI
           DMA configure API.

PATCH (14) define a function to look-up platform devices through their
           respective IORT nodes stored in platform_data. This patch is
           somewhat controversial and is provided as an initial solution
           to the problem pending further discussions.

PATCH (15) provides code to carry out ACPI IORT based device identifiers
           translation for ARM SMMU v3 components.

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"
    http://marc.info/?l=linux-arm-kernel&m=146497432413816&w=2

[2] T.Nowicki "Introduce ACPI world to ITS irqchip" v5
    http://marc.info/?l=linux-acpi&m=146469369703684&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-v2

Tested on FVP models for ARM SMMU v3 probing path.

Lorenzo Pieralisi (15):
  drivers: acpi: iort: fix struct pci_dev compiler warnings
  drivers: irqchip: its: fix its_acpi_probe() prototype
  arm64: mm: change IOMMU notifier action to attach DMA ops
  drivers: acpi: iort: add support for IOMMU registration
  drivers: acpi: iort: add support for named component look-up
  drivers: acpi: iort: enhance device identifiers mappings
  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 iommu configuration
  drivers: acpi: implement acpi_dma_configure
  drivers: acpi: iort: introduce iort_iommu_configure
  drivers: acpi: iort: add function to retrieve IOMMU platform devices
  drivers: iommu: arm-smmu-v3: allow ACPI based streamid translation

 arch/arm64/mm/dma-mapping.c      |   2 +-
 drivers/acpi/glue.c              |   4 +-
 drivers/acpi/iort.c              | 361 ++++++++++++++++++++++++++++++++++++++-
 drivers/acpi/scan.c              |  29 ++++
 drivers/iommu/arm-smmu-v3.c      | 235 ++++++++++++++++++++++---
 drivers/irqchip/irq-gic-v3-its.c |   2 +-
 drivers/pci/probe.c              |   3 +-
 include/acpi/acpi_bus.h          |   2 +
 include/linux/acpi.h             |   5 +
 include/linux/iort.h             |  43 +++++
 10 files changed, 652 insertions(+), 34 deletions(-)

-- 
2.6.4

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

* [RFC PATCH v2 01/15] drivers: acpi: iort: fix struct pci_dev compiler warnings
  2016-06-07 13:30 ` Lorenzo Pieralisi
  (?)
  (?)
@ 2016-06-07 13:30     ` Lorenzo Pieralisi
  -1 siblings, 0 replies; 88+ messages in thread
From: Lorenzo Pieralisi @ 2016-06-07 13:30 UTC (permalink / raw)
  To: iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA
  Cc: Rafael J. Wysocki, Marc Zyngier, Tomasz Nowicki, Will Deacon,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-pci-u79uwXL29TY76Z2rM5mHXA, Sinan Kaya,
	linux-acpi-u79uwXL29TY76Z2rM5mHXA, Hanjun Guo, Jon Masters,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r

When the kernel is configured with no IORT support the compilation
issues the following warnings:

In file included from drivers/irqchip/irq-gic-v3-its-pci-msi.c:19:0:
include/linux/iort.h:28:33: warning: 'struct pci_dev' declared inside
parameter list
 u32 iort_pci_get_msi_rid(struct pci_dev *pdev, u32 req_id);
                                 ^
include/linux/iort.h:28:33: warning: its scope is only this definition
or declaration, which is probably not what you want
include/linux/iort.h:29:50: warning: 'struct pci_dev' declared inside
parameter list
 struct fwnode_handle *iort_pci_get_domain(struct pci_dev *pdev, u32
req_id);

This patch fixes the warnings with a struct pci_dev forward declaration
in the IORT header file.

Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi-5wv7dgnIgG8@public.gmane.org>
Cc: Tomasz Nowicki <tn-nYOzD4b6Jr9Wk0Htik3J/w@public.gmane.org>
---
 include/linux/iort.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/include/linux/iort.h b/include/linux/iort.h
index 490ff4d..6f2fec3 100644
--- a/include/linux/iort.h
+++ b/include/linux/iort.h
@@ -21,6 +21,7 @@
 
 #include <linux/acpi.h>
 
+struct pci_dev;
 struct fwnode_handle;
 int iort_register_domain_token(int trans_id, struct fwnode_handle *fw_node);
 void iort_deregister_domain_token(int trans_id);
-- 
2.6.4

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

* [RFC PATCH v2 01/15] drivers: acpi: iort: fix struct pci_dev compiler warnings
@ 2016-06-07 13:30     ` Lorenzo Pieralisi
  0 siblings, 0 replies; 88+ messages in thread
From: Lorenzo Pieralisi @ 2016-06-07 13:30 UTC (permalink / raw)
  To: iommu
  Cc: Lorenzo Pieralisi, Tomasz Nowicki, Will Deacon, Marc Zyngier,
	Robin Murphy, Joerg Roedel, Rafael J. Wysocki, Hanjun Guo,
	Jon Masters, Sinan Kaya, linux-acpi, linux-pci, linux-kernel,
	linux-arm-kernel

When the kernel is configured with no IORT support the compilation
issues the following warnings:

In file included from drivers/irqchip/irq-gic-v3-its-pci-msi.c:19:0:
include/linux/iort.h:28:33: warning: 'struct pci_dev' declared inside
parameter list
 u32 iort_pci_get_msi_rid(struct pci_dev *pdev, u32 req_id);
                                 ^
include/linux/iort.h:28:33: warning: its scope is only this definition
or declaration, which is probably not what you want
include/linux/iort.h:29:50: warning: 'struct pci_dev' declared inside
parameter list
 struct fwnode_handle *iort_pci_get_domain(struct pci_dev *pdev, u32
req_id);

This patch fixes the warnings with a struct pci_dev forward declaration
in the IORT header file.

Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Cc: Tomasz Nowicki <tn@semihalf.com>
---
 include/linux/iort.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/include/linux/iort.h b/include/linux/iort.h
index 490ff4d..6f2fec3 100644
--- a/include/linux/iort.h
+++ b/include/linux/iort.h
@@ -21,6 +21,7 @@
 
 #include <linux/acpi.h>
 
+struct pci_dev;
 struct fwnode_handle;
 int iort_register_domain_token(int trans_id, struct fwnode_handle *fw_node);
 void iort_deregister_domain_token(int trans_id);
-- 
2.6.4

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

* [RFC PATCH v2 01/15] drivers: acpi: iort: fix struct pci_dev compiler warnings
@ 2016-06-07 13:30     ` Lorenzo Pieralisi
  0 siblings, 0 replies; 88+ messages in thread
From: Lorenzo Pieralisi @ 2016-06-07 13:30 UTC (permalink / raw)
  To: iommu
  Cc: Rafael J. Wysocki, Lorenzo Pieralisi, Marc Zyngier,
	Tomasz Nowicki, Joerg Roedel, Will Deacon, linux-kernel,
	linux-pci, Sinan Kaya, linux-acpi, Hanjun Guo, Jon Masters,
	Robin Murphy, linux-arm-kernel

When the kernel is configured with no IORT support the compilation
issues the following warnings:

In file included from drivers/irqchip/irq-gic-v3-its-pci-msi.c:19:0:
include/linux/iort.h:28:33: warning: 'struct pci_dev' declared inside
parameter list
 u32 iort_pci_get_msi_rid(struct pci_dev *pdev, u32 req_id);
                                 ^
include/linux/iort.h:28:33: warning: its scope is only this definition
or declaration, which is probably not what you want
include/linux/iort.h:29:50: warning: 'struct pci_dev' declared inside
parameter list
 struct fwnode_handle *iort_pci_get_domain(struct pci_dev *pdev, u32
req_id);

This patch fixes the warnings with a struct pci_dev forward declaration
in the IORT header file.

Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Cc: Tomasz Nowicki <tn@semihalf.com>
---
 include/linux/iort.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/include/linux/iort.h b/include/linux/iort.h
index 490ff4d..6f2fec3 100644
--- a/include/linux/iort.h
+++ b/include/linux/iort.h
@@ -21,6 +21,7 @@
 
 #include <linux/acpi.h>
 
+struct pci_dev;
 struct fwnode_handle;
 int iort_register_domain_token(int trans_id, struct fwnode_handle *fw_node);
 void iort_deregister_domain_token(int trans_id);
-- 
2.6.4


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [RFC PATCH v2 01/15] drivers: acpi: iort: fix struct pci_dev compiler warnings
@ 2016-06-07 13:30     ` Lorenzo Pieralisi
  0 siblings, 0 replies; 88+ messages in thread
From: Lorenzo Pieralisi @ 2016-06-07 13:30 UTC (permalink / raw)
  To: linux-arm-kernel

When the kernel is configured with no IORT support the compilation
issues the following warnings:

In file included from drivers/irqchip/irq-gic-v3-its-pci-msi.c:19:0:
include/linux/iort.h:28:33: warning: 'struct pci_dev' declared inside
parameter list
 u32 iort_pci_get_msi_rid(struct pci_dev *pdev, u32 req_id);
                                 ^
include/linux/iort.h:28:33: warning: its scope is only this definition
or declaration, which is probably not what you want
include/linux/iort.h:29:50: warning: 'struct pci_dev' declared inside
parameter list
 struct fwnode_handle *iort_pci_get_domain(struct pci_dev *pdev, u32
req_id);

This patch fixes the warnings with a struct pci_dev forward declaration
in the IORT header file.

Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Cc: Tomasz Nowicki <tn@semihalf.com>
---
 include/linux/iort.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/include/linux/iort.h b/include/linux/iort.h
index 490ff4d..6f2fec3 100644
--- a/include/linux/iort.h
+++ b/include/linux/iort.h
@@ -21,6 +21,7 @@
 
 #include <linux/acpi.h>
 
+struct pci_dev;
 struct fwnode_handle;
 int iort_register_domain_token(int trans_id, struct fwnode_handle *fw_node);
 void iort_deregister_domain_token(int trans_id);
-- 
2.6.4

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

* [RFC PATCH v2 02/15] drivers: irqchip: its: fix its_acpi_probe() prototype
  2016-06-07 13:30 ` Lorenzo Pieralisi
  (?)
  (?)
@ 2016-06-07 13:30     ` Lorenzo Pieralisi
  -1 siblings, 0 replies; 88+ messages in thread
From: Lorenzo Pieralisi @ 2016-06-07 13:30 UTC (permalink / raw)
  To: iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA
  Cc: Rafael J. Wysocki, Marc Zyngier, Tomasz Nowicki, Will Deacon,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-pci-u79uwXL29TY76Z2rM5mHXA, Sinan Kaya,
	linux-acpi-u79uwXL29TY76Z2rM5mHXA, Hanjun Guo, Jon Masters,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r

The empty stub for its_acpi_probe() on !CONFIG_ACPI systems has
a wrong prototype, which causes compilation errors:

drivers/irqchip/irq-gic-v3-its.c: In function 'its_init':
drivers/irqchip/irq-gic-v3-its.c:1762:3: error: too few arguments to
function 'its_acpi_probe'
   its_acpi_probe();
   ^
drivers/irqchip/irq-gic-v3-its.c:1749:27: note: declared here
 static inline void __init its_acpi_probe(struct irq_domain
*parent_domain) { }

This patch fixes the prototype and the corresponding compilation
errors.

Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi-5wv7dgnIgG8@public.gmane.org>
Cc: Tomasz Nowicki <tn-nYOzD4b6Jr9Wk0Htik3J/w@public.gmane.org>
---
 drivers/irqchip/irq-gic-v3-its.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
index c8f36a5..1846800 100644
--- a/drivers/irqchip/irq-gic-v3-its.c
+++ b/drivers/irqchip/irq-gic-v3-its.c
@@ -1700,7 +1700,7 @@ void __init its_acpi_probe(void)
 		pr_info("No valid GIC ITS entries exist\n");
 }
 #else
-static inline void __init its_acpi_probe(struct irq_domain *parent_domain) { }
+static inline void __init its_acpi_probe(void) { }
 #endif
 
 int __init its_init(struct fwnode_handle *handle, struct rdists *rdists,
-- 
2.6.4

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

* [RFC PATCH v2 02/15] drivers: irqchip: its: fix its_acpi_probe() prototype
@ 2016-06-07 13:30     ` Lorenzo Pieralisi
  0 siblings, 0 replies; 88+ messages in thread
From: Lorenzo Pieralisi @ 2016-06-07 13:30 UTC (permalink / raw)
  To: iommu
  Cc: Lorenzo Pieralisi, Tomasz Nowicki, Will Deacon, Marc Zyngier,
	Robin Murphy, Joerg Roedel, Rafael J. Wysocki, Hanjun Guo,
	Jon Masters, Sinan Kaya, linux-acpi, linux-pci, linux-kernel,
	linux-arm-kernel

The empty stub for its_acpi_probe() on !CONFIG_ACPI systems has
a wrong prototype, which causes compilation errors:

drivers/irqchip/irq-gic-v3-its.c: In function 'its_init':
drivers/irqchip/irq-gic-v3-its.c:1762:3: error: too few arguments to
function 'its_acpi_probe'
   its_acpi_probe();
   ^
drivers/irqchip/irq-gic-v3-its.c:1749:27: note: declared here
 static inline void __init its_acpi_probe(struct irq_domain
*parent_domain) { }

This patch fixes the prototype and the corresponding compilation
errors.

Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Cc: Tomasz Nowicki <tn@semihalf.com>
---
 drivers/irqchip/irq-gic-v3-its.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
index c8f36a5..1846800 100644
--- a/drivers/irqchip/irq-gic-v3-its.c
+++ b/drivers/irqchip/irq-gic-v3-its.c
@@ -1700,7 +1700,7 @@ void __init its_acpi_probe(void)
 		pr_info("No valid GIC ITS entries exist\n");
 }
 #else
-static inline void __init its_acpi_probe(struct irq_domain *parent_domain) { }
+static inline void __init its_acpi_probe(void) { }
 #endif
 
 int __init its_init(struct fwnode_handle *handle, struct rdists *rdists,
-- 
2.6.4

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

* [RFC PATCH v2 02/15] drivers: irqchip: its: fix its_acpi_probe() prototype
@ 2016-06-07 13:30     ` Lorenzo Pieralisi
  0 siblings, 0 replies; 88+ messages in thread
From: Lorenzo Pieralisi @ 2016-06-07 13:30 UTC (permalink / raw)
  To: iommu
  Cc: Rafael J. Wysocki, Lorenzo Pieralisi, Marc Zyngier,
	Tomasz Nowicki, Joerg Roedel, Will Deacon, linux-kernel,
	linux-pci, Sinan Kaya, linux-acpi, Hanjun Guo, Jon Masters,
	Robin Murphy, linux-arm-kernel

The empty stub for its_acpi_probe() on !CONFIG_ACPI systems has
a wrong prototype, which causes compilation errors:

drivers/irqchip/irq-gic-v3-its.c: In function 'its_init':
drivers/irqchip/irq-gic-v3-its.c:1762:3: error: too few arguments to
function 'its_acpi_probe'
   its_acpi_probe();
   ^
drivers/irqchip/irq-gic-v3-its.c:1749:27: note: declared here
 static inline void __init its_acpi_probe(struct irq_domain
*parent_domain) { }

This patch fixes the prototype and the corresponding compilation
errors.

Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Cc: Tomasz Nowicki <tn@semihalf.com>
---
 drivers/irqchip/irq-gic-v3-its.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
index c8f36a5..1846800 100644
--- a/drivers/irqchip/irq-gic-v3-its.c
+++ b/drivers/irqchip/irq-gic-v3-its.c
@@ -1700,7 +1700,7 @@ void __init its_acpi_probe(void)
 		pr_info("No valid GIC ITS entries exist\n");
 }
 #else
-static inline void __init its_acpi_probe(struct irq_domain *parent_domain) { }
+static inline void __init its_acpi_probe(void) { }
 #endif
 
 int __init its_init(struct fwnode_handle *handle, struct rdists *rdists,
-- 
2.6.4


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [RFC PATCH v2 02/15] drivers: irqchip: its: fix its_acpi_probe() prototype
@ 2016-06-07 13:30     ` Lorenzo Pieralisi
  0 siblings, 0 replies; 88+ messages in thread
From: Lorenzo Pieralisi @ 2016-06-07 13:30 UTC (permalink / raw)
  To: linux-arm-kernel

The empty stub for its_acpi_probe() on !CONFIG_ACPI systems has
a wrong prototype, which causes compilation errors:

drivers/irqchip/irq-gic-v3-its.c: In function 'its_init':
drivers/irqchip/irq-gic-v3-its.c:1762:3: error: too few arguments to
function 'its_acpi_probe'
   its_acpi_probe();
   ^
drivers/irqchip/irq-gic-v3-its.c:1749:27: note: declared here
 static inline void __init its_acpi_probe(struct irq_domain
*parent_domain) { }

This patch fixes the prototype and the corresponding compilation
errors.

Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Cc: Tomasz Nowicki <tn@semihalf.com>
---
 drivers/irqchip/irq-gic-v3-its.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
index c8f36a5..1846800 100644
--- a/drivers/irqchip/irq-gic-v3-its.c
+++ b/drivers/irqchip/irq-gic-v3-its.c
@@ -1700,7 +1700,7 @@ void __init its_acpi_probe(void)
 		pr_info("No valid GIC ITS entries exist\n");
 }
 #else
-static inline void __init its_acpi_probe(struct irq_domain *parent_domain) { }
+static inline void __init its_acpi_probe(void) { }
 #endif
 
 int __init its_init(struct fwnode_handle *handle, struct rdists *rdists,
-- 
2.6.4

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

* [RFC PATCH v2 03/15] arm64: mm: change IOMMU notifier action to attach DMA ops
  2016-06-07 13:30 ` Lorenzo Pieralisi
  (?)
@ 2016-06-07 13:30     ` Lorenzo Pieralisi
  -1 siblings, 0 replies; 88+ messages in thread
From: Lorenzo Pieralisi @ 2016-06-07 13:30 UTC (permalink / raw)
  To: iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA
  Cc: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	Rafael J. Wysocki, Marc Zyngier, Catalin Marinas, Will Deacon,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-pci-u79uwXL29TY76Z2rM5mHXA, Sinan Kaya,
	linux-acpi-u79uwXL29TY76Z2rM5mHXA, Hanjun Guo, Tomasz Nowicki,
	Jon Masters

Current bus notifier in ARM64 (__iommu_attach_notifier)
attempts to attach dma_ops to a device on BUS_NOTIFY_ADD_DEVICE
action notification.

This causes issues on ACPI based systems, where PCI devices
can be added before the IOMMUs the devices are attached to
had a chance to be probed, causing failures on attempts to
attach dma_ops in that the domain for the respective IOMMU
may not be set-up yet by the time the bus notifier is run.

Devices dma_ops do not require to be set-up till the matching
device drivers are probed. This means that instead of running
the notifier attaching dma_ops to devices (__iommu_attach_notifier)
on BUS_NOTIFY_ADD_DEVICE action, it can be run just before the
device driver is bound to the device in question (on action
BUS_NOTIFY_BIND_DRIVER) so that it is certain that its IOMMU
group and domain are set-up accordingly at the time the
notifier is triggered.

This patch changes the notifier action upon which dma_ops
are attached to devices and defer it to driver binding time,
so that IOMMU devices have a chance to be probed and to register
their bus notifiers before the dma_ops attach sequence for a
device is actually carried out.

Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi-5wv7dgnIgG8@public.gmane.org>
Cc: Will Deacon <will.deacon-5wv7dgnIgG8@public.gmane.org>
Cc: Catalin Marinas <catalin.marinas-5wv7dgnIgG8@public.gmane.org>
Cc: Robin Murphy <robin.murphy-5wv7dgnIgG8@public.gmane.org>
---
 arch/arm64/mm/dma-mapping.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm64/mm/dma-mapping.c b/arch/arm64/mm/dma-mapping.c
index c566ec8..79b0882 100644
--- a/arch/arm64/mm/dma-mapping.c
+++ b/arch/arm64/mm/dma-mapping.c
@@ -848,7 +848,7 @@ static int __iommu_attach_notifier(struct notifier_block *nb,
 {
 	struct iommu_dma_notifier_data *master, *tmp;
 
-	if (action != BUS_NOTIFY_ADD_DEVICE)
+	if (action != BUS_NOTIFY_BIND_DRIVER)
 		return 0;
 
 	mutex_lock(&iommu_dma_notifier_lock);
-- 
2.6.4

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

* [RFC PATCH v2 03/15] arm64: mm: change IOMMU notifier action to attach DMA ops
@ 2016-06-07 13:30     ` Lorenzo Pieralisi
  0 siblings, 0 replies; 88+ messages in thread
From: Lorenzo Pieralisi @ 2016-06-07 13:30 UTC (permalink / raw)
  To: iommu
  Cc: Lorenzo Pieralisi, Will Deacon, Catalin Marinas, Robin Murphy,
	Marc Zyngier, Joerg Roedel, Rafael J. Wysocki, Tomasz Nowicki,
	Hanjun Guo, Jon Masters, Sinan Kaya, linux-acpi, linux-pci,
	linux-kernel, linux-arm-kernel

Current bus notifier in ARM64 (__iommu_attach_notifier)
attempts to attach dma_ops to a device on BUS_NOTIFY_ADD_DEVICE
action notification.

This causes issues on ACPI based systems, where PCI devices
can be added before the IOMMUs the devices are attached to
had a chance to be probed, causing failures on attempts to
attach dma_ops in that the domain for the respective IOMMU
may not be set-up yet by the time the bus notifier is run.

Devices dma_ops do not require to be set-up till the matching
device drivers are probed. This means that instead of running
the notifier attaching dma_ops to devices (__iommu_attach_notifier)
on BUS_NOTIFY_ADD_DEVICE action, it can be run just before the
device driver is bound to the device in question (on action
BUS_NOTIFY_BIND_DRIVER) so that it is certain that its IOMMU
group and domain are set-up accordingly at the time the
notifier is triggered.

This patch changes the notifier action upon which dma_ops
are attached to devices and defer it to driver binding time,
so that IOMMU devices have a chance to be probed and to register
their bus notifiers before the dma_ops attach sequence for a
device is actually carried out.

Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Cc: Will Deacon <will.deacon@arm.com>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Robin Murphy <robin.murphy@arm.com>
---
 arch/arm64/mm/dma-mapping.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm64/mm/dma-mapping.c b/arch/arm64/mm/dma-mapping.c
index c566ec8..79b0882 100644
--- a/arch/arm64/mm/dma-mapping.c
+++ b/arch/arm64/mm/dma-mapping.c
@@ -848,7 +848,7 @@ static int __iommu_attach_notifier(struct notifier_block *nb,
 {
 	struct iommu_dma_notifier_data *master, *tmp;
 
-	if (action != BUS_NOTIFY_ADD_DEVICE)
+	if (action != BUS_NOTIFY_BIND_DRIVER)
 		return 0;
 
 	mutex_lock(&iommu_dma_notifier_lock);
-- 
2.6.4

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

* [RFC PATCH v2 03/15] arm64: mm: change IOMMU notifier action to attach DMA ops
@ 2016-06-07 13:30     ` Lorenzo Pieralisi
  0 siblings, 0 replies; 88+ messages in thread
From: Lorenzo Pieralisi @ 2016-06-07 13:30 UTC (permalink / raw)
  To: linux-arm-kernel

Current bus notifier in ARM64 (__iommu_attach_notifier)
attempts to attach dma_ops to a device on BUS_NOTIFY_ADD_DEVICE
action notification.

This causes issues on ACPI based systems, where PCI devices
can be added before the IOMMUs the devices are attached to
had a chance to be probed, causing failures on attempts to
attach dma_ops in that the domain for the respective IOMMU
may not be set-up yet by the time the bus notifier is run.

Devices dma_ops do not require to be set-up till the matching
device drivers are probed. This means that instead of running
the notifier attaching dma_ops to devices (__iommu_attach_notifier)
on BUS_NOTIFY_ADD_DEVICE action, it can be run just before the
device driver is bound to the device in question (on action
BUS_NOTIFY_BIND_DRIVER) so that it is certain that its IOMMU
group and domain are set-up accordingly at the time the
notifier is triggered.

This patch changes the notifier action upon which dma_ops
are attached to devices and defer it to driver binding time,
so that IOMMU devices have a chance to be probed and to register
their bus notifiers before the dma_ops attach sequence for a
device is actually carried out.

Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Cc: Will Deacon <will.deacon@arm.com>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Robin Murphy <robin.murphy@arm.com>
---
 arch/arm64/mm/dma-mapping.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm64/mm/dma-mapping.c b/arch/arm64/mm/dma-mapping.c
index c566ec8..79b0882 100644
--- a/arch/arm64/mm/dma-mapping.c
+++ b/arch/arm64/mm/dma-mapping.c
@@ -848,7 +848,7 @@ static int __iommu_attach_notifier(struct notifier_block *nb,
 {
 	struct iommu_dma_notifier_data *master, *tmp;
 
-	if (action != BUS_NOTIFY_ADD_DEVICE)
+	if (action != BUS_NOTIFY_BIND_DRIVER)
 		return 0;
 
 	mutex_lock(&iommu_dma_notifier_lock);
-- 
2.6.4

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

* [RFC PATCH v2 04/15] drivers: acpi: iort: add support for IOMMU registration
  2016-06-07 13:30 ` Lorenzo Pieralisi
  (?)
  (?)
@ 2016-06-07 13:30     ` Lorenzo Pieralisi
  -1 siblings, 0 replies; 88+ messages in thread
From: Lorenzo Pieralisi @ 2016-06-07 13:30 UTC (permalink / raw)
  To: iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA
  Cc: Marc Zyngier, Tomasz Nowicki, Rafael J. Wysocki,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, Will Deacon, Sinan Kaya,
	linux-acpi-u79uwXL29TY76Z2rM5mHXA,
	linux-pci-u79uwXL29TY76Z2rM5mHXA, Hanjun Guo, Jon Masters,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r

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 IOMMU operations, along with a hook
(ie iommu_xlate()) that is used to translate devices ids to ids usable
by the SMMU driver to set-up IOMMU group/domain configuration.

Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi-5wv7dgnIgG8@public.gmane.org>
Cc: Hanjun Guo <hanjun.guo-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
Cc: Tomasz Nowicki <tn-nYOzD4b6Jr9Wk0Htik3J/w@public.gmane.org>
Cc: "Rafael J. Wysocki" <rjw-LthD3rsA81gm4RdzfppkhA@public.gmane.org>
---
 drivers/acpi/iort.c  | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 include/linux/iort.h |  5 ++++
 2 files changed, 77 insertions(+)

diff --git a/drivers/acpi/iort.c b/drivers/acpi/iort.c
index 226eb6d..7cc9880 100644
--- a/drivers/acpi/iort.c
+++ b/drivers/acpi/iort.c
@@ -19,10 +19,13 @@
 #define pr_fmt(fmt)	"ACPI: IORT: " fmt
 
 #include <linux/export.h>
+#include <linux/iommu.h>
 #include <linux/iort.h>
 #include <linux/irqdomain.h>
 #include <linux/kernel.h>
+#include <linux/list.h>
 #include <linux/pci.h>
+#include <linux/slab.h>
 
 struct iort_its_msi_chip {
 	struct list_head	list;
@@ -30,6 +33,75 @@ struct iort_its_msi_chip {
 	u32			translation_id;
 };
 
+struct iort_ops_node {
+	struct list_head list;
+	struct acpi_iort_node *node;
+	const struct iommu_ops *ops;
+	int (*iommu_xlate)(struct device *dev, u32 streamid,
+			   struct acpi_iort_node *node);
+};
+static LIST_HEAD(iort_iommu_ops);
+static DEFINE_SPINLOCK(iort_ops_lock);
+
+/**
+ * iort_smmu_set_ops - Create iort_ops_node and use it to register
+ *		       iommu data in the iort_iommu_ops list.
+ *
+ * @node: IORT table node associated with the IOMMU
+ * @ops: IOMMU operations associated with the IORT node
+ * @iommu_xlate: iommu translate function to be used to carry out stream id
+ *		 translation
+ *
+ * Returns: 0 on success
+ *          -ENOMEM on failure
+ */
+int iort_smmu_set_ops(struct acpi_iort_node *node,
+		       const struct iommu_ops *ops,
+		       int (*iommu_xlate)(struct device *dev, u32 streamid,
+					  struct acpi_iort_node *node))
+{
+	struct iort_ops_node *iommu = kzalloc(sizeof(*iommu), GFP_KERNEL);
+
+	if (WARN_ON(!iommu))
+		return -ENOMEM;
+
+	INIT_LIST_HEAD(&iommu->list);
+	iommu->node = node;
+	iommu->ops = ops;
+	iommu->iommu_xlate = iommu_xlate;
+
+	spin_lock(&iort_ops_lock);
+	list_add_tail(&iommu->list, &iort_iommu_ops);
+	spin_unlock(&iort_ops_lock);
+
+	return 0;
+}
+
+/**
+ * iort_smmu_get_ops_node - Retrieve iort_ops_node associated with an
+ *			    IORT node.
+ *
+ * @node: IORT table node to be looked-up
+ *
+ * Returns: iort_ops_node pointer on success
+ *          NULL on failure
+*/
+const struct iort_ops_node *iort_smmu_get_ops_node(struct acpi_iort_node *node)
+{
+	struct iort_ops_node *curr, *iommu_node = NULL;
+
+	spin_lock(&iort_ops_lock);
+	list_for_each_entry(curr, &iort_iommu_ops, list) {
+		if (curr->node == node) {
+			iommu_node = curr;
+			break;
+		}
+	}
+	spin_unlock(&iort_ops_lock);
+
+	return iommu_node;
+}
+
 typedef acpi_status (*iort_find_node_callback)
 	(struct acpi_iort_node *node, void *context);
 
diff --git a/include/linux/iort.h b/include/linux/iort.h
index 6f2fec3..5053cc3 100644
--- a/include/linux/iort.h
+++ b/include/linux/iort.h
@@ -35,5 +35,10 @@ static inline u32 iort_pci_get_msi_rid(struct pci_dev *pdev, u32 req_id)
 static inline struct irq_domain *
 iort_pci_get_domain(struct pci_dev *pdev, u32 req_id) { return NULL; }
 #endif
+int iort_smmu_set_ops(struct acpi_iort_node *node,
+		      const struct iommu_ops *ops,
+		      int (*iommu_xlate)(struct device *dev,
+					 u32 streamid,
+					 struct acpi_iort_node *node));
 
 #endif /* __IORT_H__ */
-- 
2.6.4

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

* [RFC PATCH v2 04/15] drivers: acpi: iort: add support for IOMMU registration
@ 2016-06-07 13:30     ` Lorenzo Pieralisi
  0 siblings, 0 replies; 88+ messages in thread
From: Lorenzo Pieralisi @ 2016-06-07 13:30 UTC (permalink / raw)
  To: iommu
  Cc: Lorenzo Pieralisi, Hanjun Guo, Tomasz Nowicki, Rafael J. Wysocki,
	Will Deacon, Marc Zyngier, Robin Murphy, Joerg Roedel,
	Jon Masters, Sinan Kaya, linux-acpi, linux-pci, linux-kernel,
	linux-arm-kernel

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 IOMMU operations, along with a hook
(ie iommu_xlate()) that is used to translate devices ids to ids usable
by the SMMU driver to set-up IOMMU group/domain configuration.

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  | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 include/linux/iort.h |  5 ++++
 2 files changed, 77 insertions(+)

diff --git a/drivers/acpi/iort.c b/drivers/acpi/iort.c
index 226eb6d..7cc9880 100644
--- a/drivers/acpi/iort.c
+++ b/drivers/acpi/iort.c
@@ -19,10 +19,13 @@
 #define pr_fmt(fmt)	"ACPI: IORT: " fmt
 
 #include <linux/export.h>
+#include <linux/iommu.h>
 #include <linux/iort.h>
 #include <linux/irqdomain.h>
 #include <linux/kernel.h>
+#include <linux/list.h>
 #include <linux/pci.h>
+#include <linux/slab.h>
 
 struct iort_its_msi_chip {
 	struct list_head	list;
@@ -30,6 +33,75 @@ struct iort_its_msi_chip {
 	u32			translation_id;
 };
 
+struct iort_ops_node {
+	struct list_head list;
+	struct acpi_iort_node *node;
+	const struct iommu_ops *ops;
+	int (*iommu_xlate)(struct device *dev, u32 streamid,
+			   struct acpi_iort_node *node);
+};
+static LIST_HEAD(iort_iommu_ops);
+static DEFINE_SPINLOCK(iort_ops_lock);
+
+/**
+ * iort_smmu_set_ops - Create iort_ops_node and use it to register
+ *		       iommu data in the iort_iommu_ops list.
+ *
+ * @node: IORT table node associated with the IOMMU
+ * @ops: IOMMU operations associated with the IORT node
+ * @iommu_xlate: iommu translate function to be used to carry out stream id
+ *		 translation
+ *
+ * Returns: 0 on success
+ *          -ENOMEM on failure
+ */
+int iort_smmu_set_ops(struct acpi_iort_node *node,
+		       const struct iommu_ops *ops,
+		       int (*iommu_xlate)(struct device *dev, u32 streamid,
+					  struct acpi_iort_node *node))
+{
+	struct iort_ops_node *iommu = kzalloc(sizeof(*iommu), GFP_KERNEL);
+
+	if (WARN_ON(!iommu))
+		return -ENOMEM;
+
+	INIT_LIST_HEAD(&iommu->list);
+	iommu->node = node;
+	iommu->ops = ops;
+	iommu->iommu_xlate = iommu_xlate;
+
+	spin_lock(&iort_ops_lock);
+	list_add_tail(&iommu->list, &iort_iommu_ops);
+	spin_unlock(&iort_ops_lock);
+
+	return 0;
+}
+
+/**
+ * iort_smmu_get_ops_node - Retrieve iort_ops_node associated with an
+ *			    IORT node.
+ *
+ * @node: IORT table node to be looked-up
+ *
+ * Returns: iort_ops_node pointer on success
+ *          NULL on failure
+*/
+const struct iort_ops_node *iort_smmu_get_ops_node(struct acpi_iort_node *node)
+{
+	struct iort_ops_node *curr, *iommu_node = NULL;
+
+	spin_lock(&iort_ops_lock);
+	list_for_each_entry(curr, &iort_iommu_ops, list) {
+		if (curr->node == node) {
+			iommu_node = curr;
+			break;
+		}
+	}
+	spin_unlock(&iort_ops_lock);
+
+	return iommu_node;
+}
+
 typedef acpi_status (*iort_find_node_callback)
 	(struct acpi_iort_node *node, void *context);
 
diff --git a/include/linux/iort.h b/include/linux/iort.h
index 6f2fec3..5053cc3 100644
--- a/include/linux/iort.h
+++ b/include/linux/iort.h
@@ -35,5 +35,10 @@ static inline u32 iort_pci_get_msi_rid(struct pci_dev *pdev, u32 req_id)
 static inline struct irq_domain *
 iort_pci_get_domain(struct pci_dev *pdev, u32 req_id) { return NULL; }
 #endif
+int iort_smmu_set_ops(struct acpi_iort_node *node,
+		      const struct iommu_ops *ops,
+		      int (*iommu_xlate)(struct device *dev,
+					 u32 streamid,
+					 struct acpi_iort_node *node));
 
 #endif /* __IORT_H__ */
-- 
2.6.4

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

* [RFC PATCH v2 04/15] drivers: acpi: iort: add support for IOMMU registration
@ 2016-06-07 13:30     ` Lorenzo Pieralisi
  0 siblings, 0 replies; 88+ messages in thread
From: Lorenzo Pieralisi @ 2016-06-07 13:30 UTC (permalink / raw)
  To: iommu
  Cc: Lorenzo Pieralisi, Marc Zyngier, Tomasz Nowicki, Joerg Roedel,
	Rafael J. Wysocki, linux-kernel, Will Deacon, Sinan Kaya,
	linux-acpi, linux-pci, Hanjun Guo, Jon Masters, Robin Murphy,
	linux-arm-kernel

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 IOMMU operations, along with a hook
(ie iommu_xlate()) that is used to translate devices ids to ids usable
by the SMMU driver to set-up IOMMU group/domain configuration.

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  | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 include/linux/iort.h |  5 ++++
 2 files changed, 77 insertions(+)

diff --git a/drivers/acpi/iort.c b/drivers/acpi/iort.c
index 226eb6d..7cc9880 100644
--- a/drivers/acpi/iort.c
+++ b/drivers/acpi/iort.c
@@ -19,10 +19,13 @@
 #define pr_fmt(fmt)	"ACPI: IORT: " fmt
 
 #include <linux/export.h>
+#include <linux/iommu.h>
 #include <linux/iort.h>
 #include <linux/irqdomain.h>
 #include <linux/kernel.h>
+#include <linux/list.h>
 #include <linux/pci.h>
+#include <linux/slab.h>
 
 struct iort_its_msi_chip {
 	struct list_head	list;
@@ -30,6 +33,75 @@ struct iort_its_msi_chip {
 	u32			translation_id;
 };
 
+struct iort_ops_node {
+	struct list_head list;
+	struct acpi_iort_node *node;
+	const struct iommu_ops *ops;
+	int (*iommu_xlate)(struct device *dev, u32 streamid,
+			   struct acpi_iort_node *node);
+};
+static LIST_HEAD(iort_iommu_ops);
+static DEFINE_SPINLOCK(iort_ops_lock);
+
+/**
+ * iort_smmu_set_ops - Create iort_ops_node and use it to register
+ *		       iommu data in the iort_iommu_ops list.
+ *
+ * @node: IORT table node associated with the IOMMU
+ * @ops: IOMMU operations associated with the IORT node
+ * @iommu_xlate: iommu translate function to be used to carry out stream id
+ *		 translation
+ *
+ * Returns: 0 on success
+ *          -ENOMEM on failure
+ */
+int iort_smmu_set_ops(struct acpi_iort_node *node,
+		       const struct iommu_ops *ops,
+		       int (*iommu_xlate)(struct device *dev, u32 streamid,
+					  struct acpi_iort_node *node))
+{
+	struct iort_ops_node *iommu = kzalloc(sizeof(*iommu), GFP_KERNEL);
+
+	if (WARN_ON(!iommu))
+		return -ENOMEM;
+
+	INIT_LIST_HEAD(&iommu->list);
+	iommu->node = node;
+	iommu->ops = ops;
+	iommu->iommu_xlate = iommu_xlate;
+
+	spin_lock(&iort_ops_lock);
+	list_add_tail(&iommu->list, &iort_iommu_ops);
+	spin_unlock(&iort_ops_lock);
+
+	return 0;
+}
+
+/**
+ * iort_smmu_get_ops_node - Retrieve iort_ops_node associated with an
+ *			    IORT node.
+ *
+ * @node: IORT table node to be looked-up
+ *
+ * Returns: iort_ops_node pointer on success
+ *          NULL on failure
+*/
+const struct iort_ops_node *iort_smmu_get_ops_node(struct acpi_iort_node *node)
+{
+	struct iort_ops_node *curr, *iommu_node = NULL;
+
+	spin_lock(&iort_ops_lock);
+	list_for_each_entry(curr, &iort_iommu_ops, list) {
+		if (curr->node == node) {
+			iommu_node = curr;
+			break;
+		}
+	}
+	spin_unlock(&iort_ops_lock);
+
+	return iommu_node;
+}
+
 typedef acpi_status (*iort_find_node_callback)
 	(struct acpi_iort_node *node, void *context);
 
diff --git a/include/linux/iort.h b/include/linux/iort.h
index 6f2fec3..5053cc3 100644
--- a/include/linux/iort.h
+++ b/include/linux/iort.h
@@ -35,5 +35,10 @@ static inline u32 iort_pci_get_msi_rid(struct pci_dev *pdev, u32 req_id)
 static inline struct irq_domain *
 iort_pci_get_domain(struct pci_dev *pdev, u32 req_id) { return NULL; }
 #endif
+int iort_smmu_set_ops(struct acpi_iort_node *node,
+		      const struct iommu_ops *ops,
+		      int (*iommu_xlate)(struct device *dev,
+					 u32 streamid,
+					 struct acpi_iort_node *node));
 
 #endif /* __IORT_H__ */
-- 
2.6.4


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [RFC PATCH v2 04/15] drivers: acpi: iort: add support for IOMMU registration
@ 2016-06-07 13:30     ` Lorenzo Pieralisi
  0 siblings, 0 replies; 88+ messages in thread
From: Lorenzo Pieralisi @ 2016-06-07 13:30 UTC (permalink / raw)
  To: linux-arm-kernel

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 IOMMU operations, along with a hook
(ie iommu_xlate()) that is used to translate devices ids to ids usable
by the SMMU driver to set-up IOMMU group/domain configuration.

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  | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 include/linux/iort.h |  5 ++++
 2 files changed, 77 insertions(+)

diff --git a/drivers/acpi/iort.c b/drivers/acpi/iort.c
index 226eb6d..7cc9880 100644
--- a/drivers/acpi/iort.c
+++ b/drivers/acpi/iort.c
@@ -19,10 +19,13 @@
 #define pr_fmt(fmt)	"ACPI: IORT: " fmt
 
 #include <linux/export.h>
+#include <linux/iommu.h>
 #include <linux/iort.h>
 #include <linux/irqdomain.h>
 #include <linux/kernel.h>
+#include <linux/list.h>
 #include <linux/pci.h>
+#include <linux/slab.h>
 
 struct iort_its_msi_chip {
 	struct list_head	list;
@@ -30,6 +33,75 @@ struct iort_its_msi_chip {
 	u32			translation_id;
 };
 
+struct iort_ops_node {
+	struct list_head list;
+	struct acpi_iort_node *node;
+	const struct iommu_ops *ops;
+	int (*iommu_xlate)(struct device *dev, u32 streamid,
+			   struct acpi_iort_node *node);
+};
+static LIST_HEAD(iort_iommu_ops);
+static DEFINE_SPINLOCK(iort_ops_lock);
+
+/**
+ * iort_smmu_set_ops - Create iort_ops_node and use it to register
+ *		       iommu data in the iort_iommu_ops list.
+ *
+ * @node: IORT table node associated with the IOMMU
+ * @ops: IOMMU operations associated with the IORT node
+ * @iommu_xlate: iommu translate function to be used to carry out stream id
+ *		 translation
+ *
+ * Returns: 0 on success
+ *          -ENOMEM on failure
+ */
+int iort_smmu_set_ops(struct acpi_iort_node *node,
+		       const struct iommu_ops *ops,
+		       int (*iommu_xlate)(struct device *dev, u32 streamid,
+					  struct acpi_iort_node *node))
+{
+	struct iort_ops_node *iommu = kzalloc(sizeof(*iommu), GFP_KERNEL);
+
+	if (WARN_ON(!iommu))
+		return -ENOMEM;
+
+	INIT_LIST_HEAD(&iommu->list);
+	iommu->node = node;
+	iommu->ops = ops;
+	iommu->iommu_xlate = iommu_xlate;
+
+	spin_lock(&iort_ops_lock);
+	list_add_tail(&iommu->list, &iort_iommu_ops);
+	spin_unlock(&iort_ops_lock);
+
+	return 0;
+}
+
+/**
+ * iort_smmu_get_ops_node - Retrieve iort_ops_node associated with an
+ *			    IORT node.
+ *
+ * @node: IORT table node to be looked-up
+ *
+ * Returns: iort_ops_node pointer on success
+ *          NULL on failure
+*/
+const struct iort_ops_node *iort_smmu_get_ops_node(struct acpi_iort_node *node)
+{
+	struct iort_ops_node *curr, *iommu_node = NULL;
+
+	spin_lock(&iort_ops_lock);
+	list_for_each_entry(curr, &iort_iommu_ops, list) {
+		if (curr->node == node) {
+			iommu_node = curr;
+			break;
+		}
+	}
+	spin_unlock(&iort_ops_lock);
+
+	return iommu_node;
+}
+
 typedef acpi_status (*iort_find_node_callback)
 	(struct acpi_iort_node *node, void *context);
 
diff --git a/include/linux/iort.h b/include/linux/iort.h
index 6f2fec3..5053cc3 100644
--- a/include/linux/iort.h
+++ b/include/linux/iort.h
@@ -35,5 +35,10 @@ static inline u32 iort_pci_get_msi_rid(struct pci_dev *pdev, u32 req_id)
 static inline struct irq_domain *
 iort_pci_get_domain(struct pci_dev *pdev, u32 req_id) { return NULL; }
 #endif
+int iort_smmu_set_ops(struct acpi_iort_node *node,
+		      const struct iommu_ops *ops,
+		      int (*iommu_xlate)(struct device *dev,
+					 u32 streamid,
+					 struct acpi_iort_node *node));
 
 #endif /* __IORT_H__ */
-- 
2.6.4

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

* [RFC PATCH v2 05/15] drivers: acpi: iort: add support for named component look-up
  2016-06-07 13:30 ` Lorenzo Pieralisi
  (?)
@ 2016-06-07 13:31     ` Lorenzo Pieralisi
  -1 siblings, 0 replies; 88+ messages in thread
From: Lorenzo Pieralisi @ 2016-06-07 13:31 UTC (permalink / raw)
  To: iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA
  Cc: Marc Zyngier, Tomasz Nowicki, Rafael J. Wysocki,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, Will Deacon, Sinan Kaya,
	linux-acpi-u79uwXL29TY76Z2rM5mHXA,
	linux-pci-u79uwXL29TY76Z2rM5mHXA, Hanjun Guo, Jon Masters,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r

ACPI IORT table allows ids translations for PCI devices (through
their respective root complex) and name components (ie components
identified through their ACPI namespace path).

Current IORT code only allows look-up and retrieval of IORT nodes
corresponding to PCI root complexes components; this patch fills
the gap by adding support for named components IORT node look-ups.

Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi-5wv7dgnIgG8@public.gmane.org>
Cc: Hanjun Guo <hanjun.guo-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
Cc: Tomasz Nowicki <tn-nYOzD4b6Jr9Wk0Htik3J/w@public.gmane.org>
Cc: "Rafael J. Wysocki" <rjw-LthD3rsA81gm4RdzfppkhA@public.gmane.org>
---
 drivers/acpi/iort.c | 30 +++++++++++++++++++++++++++---
 1 file changed, 27 insertions(+), 3 deletions(-)

diff --git a/drivers/acpi/iort.c b/drivers/acpi/iort.c
index 7cc9880..cfdde71 100644
--- a/drivers/acpi/iort.c
+++ b/drivers/acpi/iort.c
@@ -215,12 +215,35 @@ iort_scan_node(enum acpi_iort_node_type type,
 static acpi_status
 iort_find_dev_callback(struct acpi_iort_node *node, void *context)
 {
-	struct acpi_iort_root_complex *pci_rc;
 	struct device *dev = context;
-	struct pci_bus *bus;
 
 	switch (node->type) {
-	case ACPI_IORT_NODE_PCI_ROOT_COMPLEX:
+	case ACPI_IORT_NODE_NAMED_COMPONENT: {
+		struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
+		struct acpi_iort_named_component *ncomp;
+		struct acpi_device *adev = to_acpi_device_node(dev->fwnode);
+
+		if (!adev)
+			break;
+
+		ncomp = (struct acpi_iort_named_component *)node->node_data;
+
+		if (ACPI_FAILURE(acpi_get_name(adev->handle,
+					       ACPI_FULL_PATHNAME, &buffer))) {
+			pr_warn("Can't get device full path name\n");
+			break;
+		}
+
+		if (!strcmp(ncomp->device_name, (char *)buffer.pointer))
+			return AE_OK;
+
+		break;
+	}
+
+	case ACPI_IORT_NODE_PCI_ROOT_COMPLEX: {
+		struct acpi_iort_root_complex *pci_rc;
+		struct pci_bus *bus;
+
 		bus = to_pci_bus(dev);
 		pci_rc = (struct acpi_iort_root_complex *)node->node_data;
 
@@ -234,6 +257,7 @@ iort_find_dev_callback(struct acpi_iort_node *node, void *context)
 
 		break;
 	}
+	}
 
 	return AE_NOT_FOUND;
 }
-- 
2.6.4

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

* [RFC PATCH v2 05/15] drivers: acpi: iort: add support for named component look-up
@ 2016-06-07 13:31     ` Lorenzo Pieralisi
  0 siblings, 0 replies; 88+ messages in thread
From: Lorenzo Pieralisi @ 2016-06-07 13:31 UTC (permalink / raw)
  To: iommu
  Cc: Lorenzo Pieralisi, Hanjun Guo, Tomasz Nowicki, Rafael J. Wysocki,
	Will Deacon, Marc Zyngier, Robin Murphy, Joerg Roedel,
	Jon Masters, Sinan Kaya, linux-acpi, linux-pci, linux-kernel,
	linux-arm-kernel

ACPI IORT table allows ids translations for PCI devices (through
their respective root complex) and name components (ie components
identified through their ACPI namespace path).

Current IORT code only allows look-up and retrieval of IORT nodes
corresponding to PCI root complexes components; this patch fills
the gap by adding support for named components IORT node look-ups.

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 | 30 +++++++++++++++++++++++++++---
 1 file changed, 27 insertions(+), 3 deletions(-)

diff --git a/drivers/acpi/iort.c b/drivers/acpi/iort.c
index 7cc9880..cfdde71 100644
--- a/drivers/acpi/iort.c
+++ b/drivers/acpi/iort.c
@@ -215,12 +215,35 @@ iort_scan_node(enum acpi_iort_node_type type,
 static acpi_status
 iort_find_dev_callback(struct acpi_iort_node *node, void *context)
 {
-	struct acpi_iort_root_complex *pci_rc;
 	struct device *dev = context;
-	struct pci_bus *bus;
 
 	switch (node->type) {
-	case ACPI_IORT_NODE_PCI_ROOT_COMPLEX:
+	case ACPI_IORT_NODE_NAMED_COMPONENT: {
+		struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
+		struct acpi_iort_named_component *ncomp;
+		struct acpi_device *adev = to_acpi_device_node(dev->fwnode);
+
+		if (!adev)
+			break;
+
+		ncomp = (struct acpi_iort_named_component *)node->node_data;
+
+		if (ACPI_FAILURE(acpi_get_name(adev->handle,
+					       ACPI_FULL_PATHNAME, &buffer))) {
+			pr_warn("Can't get device full path name\n");
+			break;
+		}
+
+		if (!strcmp(ncomp->device_name, (char *)buffer.pointer))
+			return AE_OK;
+
+		break;
+	}
+
+	case ACPI_IORT_NODE_PCI_ROOT_COMPLEX: {
+		struct acpi_iort_root_complex *pci_rc;
+		struct pci_bus *bus;
+
 		bus = to_pci_bus(dev);
 		pci_rc = (struct acpi_iort_root_complex *)node->node_data;
 
@@ -234,6 +257,7 @@ iort_find_dev_callback(struct acpi_iort_node *node, void *context)
 
 		break;
 	}
+	}
 
 	return AE_NOT_FOUND;
 }
-- 
2.6.4

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

* [RFC PATCH v2 05/15] drivers: acpi: iort: add support for named component look-up
@ 2016-06-07 13:31     ` Lorenzo Pieralisi
  0 siblings, 0 replies; 88+ messages in thread
From: Lorenzo Pieralisi @ 2016-06-07 13:31 UTC (permalink / raw)
  To: linux-arm-kernel

ACPI IORT table allows ids translations for PCI devices (through
their respective root complex) and name components (ie components
identified through their ACPI namespace path).

Current IORT code only allows look-up and retrieval of IORT nodes
corresponding to PCI root complexes components; this patch fills
the gap by adding support for named components IORT node look-ups.

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 | 30 +++++++++++++++++++++++++++---
 1 file changed, 27 insertions(+), 3 deletions(-)

diff --git a/drivers/acpi/iort.c b/drivers/acpi/iort.c
index 7cc9880..cfdde71 100644
--- a/drivers/acpi/iort.c
+++ b/drivers/acpi/iort.c
@@ -215,12 +215,35 @@ iort_scan_node(enum acpi_iort_node_type type,
 static acpi_status
 iort_find_dev_callback(struct acpi_iort_node *node, void *context)
 {
-	struct acpi_iort_root_complex *pci_rc;
 	struct device *dev = context;
-	struct pci_bus *bus;
 
 	switch (node->type) {
-	case ACPI_IORT_NODE_PCI_ROOT_COMPLEX:
+	case ACPI_IORT_NODE_NAMED_COMPONENT: {
+		struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
+		struct acpi_iort_named_component *ncomp;
+		struct acpi_device *adev = to_acpi_device_node(dev->fwnode);
+
+		if (!adev)
+			break;
+
+		ncomp = (struct acpi_iort_named_component *)node->node_data;
+
+		if (ACPI_FAILURE(acpi_get_name(adev->handle,
+					       ACPI_FULL_PATHNAME, &buffer))) {
+			pr_warn("Can't get device full path name\n");
+			break;
+		}
+
+		if (!strcmp(ncomp->device_name, (char *)buffer.pointer))
+			return AE_OK;
+
+		break;
+	}
+
+	case ACPI_IORT_NODE_PCI_ROOT_COMPLEX: {
+		struct acpi_iort_root_complex *pci_rc;
+		struct pci_bus *bus;
+
 		bus = to_pci_bus(dev);
 		pci_rc = (struct acpi_iort_root_complex *)node->node_data;
 
@@ -234,6 +257,7 @@ iort_find_dev_callback(struct acpi_iort_node *node, void *context)
 
 		break;
 	}
+	}
 
 	return AE_NOT_FOUND;
 }
-- 
2.6.4

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

* [RFC PATCH v2 06/15] drivers: acpi: iort: enhance device identifiers mappings
  2016-06-07 13:30 ` Lorenzo Pieralisi
  (?)
  (?)
@ 2016-06-07 13:31     ` Lorenzo Pieralisi
  -1 siblings, 0 replies; 88+ messages in thread
From: Lorenzo Pieralisi @ 2016-06-07 13:31 UTC (permalink / raw)
  To: iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA
  Cc: Marc Zyngier, Tomasz Nowicki, Rafael J. Wysocki,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, Will Deacon, Sinan Kaya,
	linux-acpi-u79uwXL29TY76Z2rM5mHXA,
	linux-pci-u79uwXL29TY76Z2rM5mHXA, Hanjun Guo, Jon Masters,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r

Current IORT code only allow to map device identifiers to the
corresponding ITS group device id. This is not sufficient, in that
current code does not allow device id mappings to components
that sit between devices and ITS interrupt controllers (eg IOMMUs).

This patch enhances the current IORT ids mapping API to cater for
all mappings allowed by the IORT specification.

Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi-5wv7dgnIgG8@public.gmane.org>
Cc: Hanjun Guo <hanjun.guo-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
Cc: Tomasz Nowicki <tn-nYOzD4b6Jr9Wk0Htik3J/w@public.gmane.org>
Cc: "Rafael J. Wysocki" <rjw-LthD3rsA81gm4RdzfppkhA@public.gmane.org>
---
 drivers/acpi/iort.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/acpi/iort.c b/drivers/acpi/iort.c
index cfdde71..0ba6c8a 100644
--- a/drivers/acpi/iort.c
+++ b/drivers/acpi/iort.c
@@ -264,14 +264,14 @@ iort_find_dev_callback(struct acpi_iort_node *node, void *context)
 
 static struct acpi_iort_node *
 iort_dev_map_rid(struct acpi_iort_node *node, u32 rid_in,
-			    u32 *rid_out)
+			    u32 *rid_out, u8 type)
 {
 
 	if (!node)
 		goto out;
 
 	/* Go upstream */
-	while (node->type != ACPI_IORT_NODE_ITS_GROUP) {
+	while (node->type != type) {
 		struct acpi_iort_id_mapping *id;
 		int i, found = 0;
 
@@ -346,7 +346,7 @@ iort_its_find_node_and_map_rid(struct pci_dev *pdev, u32 req_id, u32 *dev_id)
 		return NULL;
 	}
 
-	return iort_dev_map_rid(node, req_id, dev_id);
+	return iort_dev_map_rid(node, req_id, dev_id, ACPI_IORT_NODE_ITS_GROUP);
 }
 
 /**
-- 
2.6.4

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

* [RFC PATCH v2 06/15] drivers: acpi: iort: enhance device identifiers mappings
@ 2016-06-07 13:31     ` Lorenzo Pieralisi
  0 siblings, 0 replies; 88+ messages in thread
From: Lorenzo Pieralisi @ 2016-06-07 13:31 UTC (permalink / raw)
  To: iommu
  Cc: Lorenzo Pieralisi, Hanjun Guo, Tomasz Nowicki, Rafael J. Wysocki,
	Will Deacon, Marc Zyngier, Robin Murphy, Joerg Roedel,
	Jon Masters, Sinan Kaya, linux-acpi, linux-pci, linux-kernel,
	linux-arm-kernel

Current IORT code only allow to map device identifiers to the
corresponding ITS group device id. This is not sufficient, in that
current code does not allow device id mappings to components
that sit between devices and ITS interrupt controllers (eg IOMMUs).

This patch enhances the current IORT ids mapping API to cater for
all mappings allowed by the IORT specification.

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 | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/acpi/iort.c b/drivers/acpi/iort.c
index cfdde71..0ba6c8a 100644
--- a/drivers/acpi/iort.c
+++ b/drivers/acpi/iort.c
@@ -264,14 +264,14 @@ iort_find_dev_callback(struct acpi_iort_node *node, void *context)
 
 static struct acpi_iort_node *
 iort_dev_map_rid(struct acpi_iort_node *node, u32 rid_in,
-			    u32 *rid_out)
+			    u32 *rid_out, u8 type)
 {
 
 	if (!node)
 		goto out;
 
 	/* Go upstream */
-	while (node->type != ACPI_IORT_NODE_ITS_GROUP) {
+	while (node->type != type) {
 		struct acpi_iort_id_mapping *id;
 		int i, found = 0;
 
@@ -346,7 +346,7 @@ iort_its_find_node_and_map_rid(struct pci_dev *pdev, u32 req_id, u32 *dev_id)
 		return NULL;
 	}
 
-	return iort_dev_map_rid(node, req_id, dev_id);
+	return iort_dev_map_rid(node, req_id, dev_id, ACPI_IORT_NODE_ITS_GROUP);
 }
 
 /**
-- 
2.6.4

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

* [RFC PATCH v2 06/15] drivers: acpi: iort: enhance device identifiers mappings
@ 2016-06-07 13:31     ` Lorenzo Pieralisi
  0 siblings, 0 replies; 88+ messages in thread
From: Lorenzo Pieralisi @ 2016-06-07 13:31 UTC (permalink / raw)
  To: iommu
  Cc: Lorenzo Pieralisi, Marc Zyngier, Tomasz Nowicki, Joerg Roedel,
	Rafael J. Wysocki, linux-kernel, Will Deacon, Sinan Kaya,
	linux-acpi, linux-pci, Hanjun Guo, Jon Masters, Robin Murphy,
	linux-arm-kernel

Current IORT code only allow to map device identifiers to the
corresponding ITS group device id. This is not sufficient, in that
current code does not allow device id mappings to components
that sit between devices and ITS interrupt controllers (eg IOMMUs).

This patch enhances the current IORT ids mapping API to cater for
all mappings allowed by the IORT specification.

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 | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/acpi/iort.c b/drivers/acpi/iort.c
index cfdde71..0ba6c8a 100644
--- a/drivers/acpi/iort.c
+++ b/drivers/acpi/iort.c
@@ -264,14 +264,14 @@ iort_find_dev_callback(struct acpi_iort_node *node, void *context)
 
 static struct acpi_iort_node *
 iort_dev_map_rid(struct acpi_iort_node *node, u32 rid_in,
-			    u32 *rid_out)
+			    u32 *rid_out, u8 type)
 {
 
 	if (!node)
 		goto out;
 
 	/* Go upstream */
-	while (node->type != ACPI_IORT_NODE_ITS_GROUP) {
+	while (node->type != type) {
 		struct acpi_iort_id_mapping *id;
 		int i, found = 0;
 
@@ -346,7 +346,7 @@ iort_its_find_node_and_map_rid(struct pci_dev *pdev, u32 req_id, u32 *dev_id)
 		return NULL;
 	}
 
-	return iort_dev_map_rid(node, req_id, dev_id);
+	return iort_dev_map_rid(node, req_id, dev_id, ACPI_IORT_NODE_ITS_GROUP);
 }
 
 /**
-- 
2.6.4


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [RFC PATCH v2 06/15] drivers: acpi: iort: enhance device identifiers mappings
@ 2016-06-07 13:31     ` Lorenzo Pieralisi
  0 siblings, 0 replies; 88+ messages in thread
From: Lorenzo Pieralisi @ 2016-06-07 13:31 UTC (permalink / raw)
  To: linux-arm-kernel

Current IORT code only allow to map device identifiers to the
corresponding ITS group device id. This is not sufficient, in that
current code does not allow device id mappings to components
that sit between devices and ITS interrupt controllers (eg IOMMUs).

This patch enhances the current IORT ids mapping API to cater for
all mappings allowed by the IORT specification.

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 | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/acpi/iort.c b/drivers/acpi/iort.c
index cfdde71..0ba6c8a 100644
--- a/drivers/acpi/iort.c
+++ b/drivers/acpi/iort.c
@@ -264,14 +264,14 @@ iort_find_dev_callback(struct acpi_iort_node *node, void *context)
 
 static struct acpi_iort_node *
 iort_dev_map_rid(struct acpi_iort_node *node, u32 rid_in,
-			    u32 *rid_out)
+			    u32 *rid_out, u8 type)
 {
 
 	if (!node)
 		goto out;
 
 	/* Go upstream */
-	while (node->type != ACPI_IORT_NODE_ITS_GROUP) {
+	while (node->type != type) {
 		struct acpi_iort_id_mapping *id;
 		int i, found = 0;
 
@@ -346,7 +346,7 @@ iort_its_find_node_and_map_rid(struct pci_dev *pdev, u32 req_id, u32 *dev_id)
 		return NULL;
 	}
 
-	return iort_dev_map_rid(node, req_id, dev_id);
+	return iort_dev_map_rid(node, req_id, dev_id, ACPI_IORT_NODE_ITS_GROUP);
 }
 
 /**
-- 
2.6.4

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

* [RFC PATCH v2 07/15] drivers: acpi: iort: add node match function
  2016-06-07 13:30 ` Lorenzo Pieralisi
@ 2016-06-07 13:31   ` Lorenzo Pieralisi
  -1 siblings, 0 replies; 88+ messages in thread
From: Lorenzo Pieralisi @ 2016-06-07 13:31 UTC (permalink / raw)
  To: iommu
  Cc: Lorenzo Pieralisi, Hanjun Guo, Tomasz Nowicki, Rafael J. Wysocki,
	Will Deacon, Marc Zyngier, Robin Murphy, Joerg Roedel,
	Jon Masters, Sinan Kaya, linux-acpi, linux-pci, linux-kernel,
	linux-arm-kernel

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 0ba6c8a..875edde 100644
--- a/drivers/acpi/iort.c
+++ b/drivers/acpi/iort.c
@@ -213,6 +213,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_find_dev_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 5053cc3..5ebe7e5 100644
--- a/include/linux/iort.h
+++ b/include/linux/iort.h
@@ -27,9 +27,11 @@ 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_its_find_domain_token(int trans_id);
 #ifdef CONFIG_IORT_TABLE
+bool iort_node_match(u8 type);
 u32 iort_pci_get_msi_rid(struct pci_dev *pdev, u32 req_id);
 struct irq_domain *iort_pci_get_domain(struct pci_dev *pdev, u32 req_id);
 #else
+static inline bool iort_node_match(u8 type) { return false; }
 static inline u32 iort_pci_get_msi_rid(struct pci_dev *pdev, u32 req_id)
 { return req_id; }
 static inline struct irq_domain *
-- 
2.6.4

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

* [RFC PATCH v2 07/15] drivers: acpi: iort: add node match function
@ 2016-06-07 13:31   ` Lorenzo Pieralisi
  0 siblings, 0 replies; 88+ messages in thread
From: Lorenzo Pieralisi @ 2016-06-07 13:31 UTC (permalink / raw)
  To: linux-arm-kernel

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 0ba6c8a..875edde 100644
--- a/drivers/acpi/iort.c
+++ b/drivers/acpi/iort.c
@@ -213,6 +213,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_find_dev_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 5053cc3..5ebe7e5 100644
--- a/include/linux/iort.h
+++ b/include/linux/iort.h
@@ -27,9 +27,11 @@ 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_its_find_domain_token(int trans_id);
 #ifdef CONFIG_IORT_TABLE
+bool iort_node_match(u8 type);
 u32 iort_pci_get_msi_rid(struct pci_dev *pdev, u32 req_id);
 struct irq_domain *iort_pci_get_domain(struct pci_dev *pdev, u32 req_id);
 #else
+static inline bool iort_node_match(u8 type) { return false; }
 static inline u32 iort_pci_get_msi_rid(struct pci_dev *pdev, u32 req_id)
 { return req_id; }
 static inline struct irq_domain *
-- 
2.6.4

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

* [RFC PATCH v2 08/15] drivers: acpi: iort: add support for ARM SMMU platform devices creation
  2016-06-07 13:30 ` Lorenzo Pieralisi
  (?)
@ 2016-06-07 13:31     ` Lorenzo Pieralisi
  -1 siblings, 0 replies; 88+ messages in thread
From: Lorenzo Pieralisi @ 2016-06-07 13:31 UTC (permalink / raw)
  To: iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA
  Cc: Marc Zyngier, Tomasz Nowicki, Rafael J. Wysocki,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, Will Deacon, Sinan Kaya,
	linux-acpi-u79uwXL29TY76Z2rM5mHXA,
	linux-pci-u79uwXL29TY76Z2rM5mHXA, Hanjun Guo, Jon Masters,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r

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 by specific ARM SMMU drivers) to be
used to define the platform devices names, init the IOMMUs, count their
resources and finally initialize them.

Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi-5wv7dgnIgG8@public.gmane.org>
Cc: Hanjun Guo <hanjun.guo-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
Cc: Tomasz Nowicki <tn-nYOzD4b6Jr9Wk0Htik3J/w@public.gmane.org>
Cc: "Rafael J. Wysocki" <rjw-LthD3rsA81gm4RdzfppkhA@public.gmane.org>
---
 drivers/acpi/iort.c  | 125 +++++++++++++++++++++++++++++++++++++++++++++++++++
 include/linux/iort.h |  15 +++++++
 2 files changed, 140 insertions(+)

diff --git a/drivers/acpi/iort.c b/drivers/acpi/iort.c
index 875edde..2ef08d9 100644
--- a/drivers/acpi/iort.c
+++ b/drivers/acpi/iort.c
@@ -25,6 +25,7 @@
 #include <linux/kernel.h>
 #include <linux/list.h>
 #include <linux/pci.h>
+#include <linux/platform_device.h>
 #include <linux/slab.h>
 
 struct iort_its_msi_chip {
@@ -436,6 +437,128 @@ iort_pci_get_domain(struct pci_dev *pdev, u32 req_id)
 	return irq_find_matching_fwnode(handle, DOMAIN_BUS_PCI_MSI);
 }
 
+static int __init
+add_smmu_platform_device(const struct iort_iommu_config *iort_cfg,
+			 struct acpi_iort_node *node)
+{
+	struct platform_device *pdev;
+	struct resource *r;
+	enum dev_dma_attr attr;
+	int ret, count;
+
+	pdev = platform_device_alloc(iort_cfg->name, PLATFORM_DEVID_AUTO);
+	if (!pdev)
+		return PTR_ERR(pdev);
+
+	count = iort_cfg->iommu_count_resources(node);
+
+	r = kcalloc(count, sizeof(*r), GFP_KERNEL);
+	if (!r) {
+		ret = -ENOMEM;
+		goto dev_put;
+	}
+
+	iort_cfg->iommu_init_resources(r, node);
+
+	ret = platform_device_add_resources(pdev, r, count);
+	/*
+	 * Resources are duplicated in platform_device_add_resources,
+	 * free their allocated memory
+	 */
+	kfree(r);
+
+	if (ret)
+		goto dev_put;
+
+	/*
+	 * Add a copy of IORT node pointer to platform_data to
+	 * be used to retrieve IORT data information.
+	 */
+	ret = platform_device_add_data(pdev, &node, sizeof(node));
+	if (ret)
+		goto dev_put;
+
+	pdev->dev.dma_mask = kmalloc(sizeof(*pdev->dev.dma_mask), GFP_KERNEL);
+	if (!pdev->dev.dma_mask) {
+		ret = -ENOMEM;
+		goto dev_put;
+	}
+
+	/*
+	 * Set default dma mask value for the table walker,
+	 * to be overridden on probing with correct value.
+	 */
+	*pdev->dev.dma_mask = DMA_BIT_MASK(32);
+	pdev->dev.coherent_dma_mask = *pdev->dev.dma_mask;
+
+	attr = iort_cfg->iommu_is_coherent(node) ?
+			     DEV_DMA_COHERENT : DEV_DMA_NON_COHERENT;
+
+	/* Configure DMA for the page table walker */
+	arch_setup_dma_ops(&pdev->dev, 0, 0, NULL,
+					 attr == DEV_DMA_COHERENT);
+
+	ret = platform_device_add(pdev);
+	if (ret)
+		goto dma_deconfigure;
+
+	ret = iort_cfg->iommu_init(node);
+	if (ret)
+		goto dma_deconfigure;
+
+	return 0;
+
+dma_deconfigure:
+	arch_teardown_dma_ops(&pdev->dev);
+	kfree(pdev->dev.dma_mask);
+
+dev_put:
+	platform_device_put(pdev);
+
+	return ret;
+}
+
+static int __init iort_smmu_init(void)
+{
+	struct acpi_iort_node *iort_node, *iort_end;
+	struct acpi_table_iort *iort;
+	int i, ret;
+
+	/*
+	 * iort_table and iort both point to the start of IORT table, but
+	 * have different struct types
+	 */
+	iort = (struct acpi_table_iort *)iort_table;
+
+	/* Get the first IORT node */
+	iort_node = ACPI_ADD_PTR(struct acpi_iort_node, iort,
+				 iort->node_offset);
+	iort_end = ACPI_ADD_PTR(struct acpi_iort_node, iort_table,
+				iort_table->length);
+
+	for (i = 0; i < iort->node_count; i++) {
+		const struct iort_iommu_config *ops;
+
+		if (iort_node >= iort_end) {
+			pr_err("iort node pointer overflows, bad table\n");
+			return -EINVAL;
+		}
+
+		ops = iort_get_iommu_config(iort_node);
+		if (!ops)
+			goto next;
+
+		ret = add_smmu_platform_device(ops, iort_node);
+		if (ret)
+			return ret;
+next:
+		iort_node = ACPI_ADD_PTR(struct acpi_iort_node, iort_node,
+					 iort_node->length);
+	}
+
+	return 0;
+}
+
 static int __init iort_table_detect(void)
 {
 	acpi_status status;
@@ -450,6 +573,8 @@ static int __init iort_table_detect(void)
 		return -EINVAL;
 	}
 
+	iort_smmu_init();
+
 	return 0;
 }
 arch_initcall(iort_table_detect);
diff --git a/include/linux/iort.h b/include/linux/iort.h
index 5ebe7e5..ced3054 100644
--- a/include/linux/iort.h
+++ b/include/linux/iort.h
@@ -43,4 +43,19 @@ int iort_smmu_set_ops(struct acpi_iort_node *node,
 					 u32 streamid,
 					 struct acpi_iort_node *node));
 
+struct iort_iommu_config {
+	const char *name;
+	int (*iommu_init)(struct acpi_iort_node *node);
+	bool (*iommu_is_coherent)(struct acpi_iort_node *node);
+	int (*iommu_count_resources)(struct acpi_iort_node *node);
+	void (*iommu_init_resources)(struct resource *res,
+				     struct acpi_iort_node *node);
+};
+
+static inline const struct iort_iommu_config *
+iort_get_iommu_config(struct acpi_iort_node *node)
+{
+	return NULL;
+}
+
 #endif /* __IORT_H__ */
-- 
2.6.4

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

* [RFC PATCH v2 08/15] drivers: acpi: iort: add support for ARM SMMU platform devices creation
@ 2016-06-07 13:31     ` Lorenzo Pieralisi
  0 siblings, 0 replies; 88+ messages in thread
From: Lorenzo Pieralisi @ 2016-06-07 13:31 UTC (permalink / raw)
  To: iommu
  Cc: Lorenzo Pieralisi, Hanjun Guo, Tomasz Nowicki, Rafael J. Wysocki,
	Will Deacon, Marc Zyngier, Robin Murphy, Joerg Roedel,
	Jon Masters, Sinan Kaya, linux-acpi, linux-pci, linux-kernel,
	linux-arm-kernel

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 by specific ARM SMMU drivers) to be
used to define the platform devices names, init the IOMMUs, count their
resources and finally initialize them.

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  | 125 +++++++++++++++++++++++++++++++++++++++++++++++++++
 include/linux/iort.h |  15 +++++++
 2 files changed, 140 insertions(+)

diff --git a/drivers/acpi/iort.c b/drivers/acpi/iort.c
index 875edde..2ef08d9 100644
--- a/drivers/acpi/iort.c
+++ b/drivers/acpi/iort.c
@@ -25,6 +25,7 @@
 #include <linux/kernel.h>
 #include <linux/list.h>
 #include <linux/pci.h>
+#include <linux/platform_device.h>
 #include <linux/slab.h>
 
 struct iort_its_msi_chip {
@@ -436,6 +437,128 @@ iort_pci_get_domain(struct pci_dev *pdev, u32 req_id)
 	return irq_find_matching_fwnode(handle, DOMAIN_BUS_PCI_MSI);
 }
 
+static int __init
+add_smmu_platform_device(const struct iort_iommu_config *iort_cfg,
+			 struct acpi_iort_node *node)
+{
+	struct platform_device *pdev;
+	struct resource *r;
+	enum dev_dma_attr attr;
+	int ret, count;
+
+	pdev = platform_device_alloc(iort_cfg->name, PLATFORM_DEVID_AUTO);
+	if (!pdev)
+		return PTR_ERR(pdev);
+
+	count = iort_cfg->iommu_count_resources(node);
+
+	r = kcalloc(count, sizeof(*r), GFP_KERNEL);
+	if (!r) {
+		ret = -ENOMEM;
+		goto dev_put;
+	}
+
+	iort_cfg->iommu_init_resources(r, node);
+
+	ret = platform_device_add_resources(pdev, r, count);
+	/*
+	 * Resources are duplicated in platform_device_add_resources,
+	 * free their allocated memory
+	 */
+	kfree(r);
+
+	if (ret)
+		goto dev_put;
+
+	/*
+	 * Add a copy of IORT node pointer to platform_data to
+	 * be used to retrieve IORT data information.
+	 */
+	ret = platform_device_add_data(pdev, &node, sizeof(node));
+	if (ret)
+		goto dev_put;
+
+	pdev->dev.dma_mask = kmalloc(sizeof(*pdev->dev.dma_mask), GFP_KERNEL);
+	if (!pdev->dev.dma_mask) {
+		ret = -ENOMEM;
+		goto dev_put;
+	}
+
+	/*
+	 * Set default dma mask value for the table walker,
+	 * to be overridden on probing with correct value.
+	 */
+	*pdev->dev.dma_mask = DMA_BIT_MASK(32);
+	pdev->dev.coherent_dma_mask = *pdev->dev.dma_mask;
+
+	attr = iort_cfg->iommu_is_coherent(node) ?
+			     DEV_DMA_COHERENT : DEV_DMA_NON_COHERENT;
+
+	/* Configure DMA for the page table walker */
+	arch_setup_dma_ops(&pdev->dev, 0, 0, NULL,
+					 attr == DEV_DMA_COHERENT);
+
+	ret = platform_device_add(pdev);
+	if (ret)
+		goto dma_deconfigure;
+
+	ret = iort_cfg->iommu_init(node);
+	if (ret)
+		goto dma_deconfigure;
+
+	return 0;
+
+dma_deconfigure:
+	arch_teardown_dma_ops(&pdev->dev);
+	kfree(pdev->dev.dma_mask);
+
+dev_put:
+	platform_device_put(pdev);
+
+	return ret;
+}
+
+static int __init iort_smmu_init(void)
+{
+	struct acpi_iort_node *iort_node, *iort_end;
+	struct acpi_table_iort *iort;
+	int i, ret;
+
+	/*
+	 * iort_table and iort both point to the start of IORT table, but
+	 * have different struct types
+	 */
+	iort = (struct acpi_table_iort *)iort_table;
+
+	/* Get the first IORT node */
+	iort_node = ACPI_ADD_PTR(struct acpi_iort_node, iort,
+				 iort->node_offset);
+	iort_end = ACPI_ADD_PTR(struct acpi_iort_node, iort_table,
+				iort_table->length);
+
+	for (i = 0; i < iort->node_count; i++) {
+		const struct iort_iommu_config *ops;
+
+		if (iort_node >= iort_end) {
+			pr_err("iort node pointer overflows, bad table\n");
+			return -EINVAL;
+		}
+
+		ops = iort_get_iommu_config(iort_node);
+		if (!ops)
+			goto next;
+
+		ret = add_smmu_platform_device(ops, iort_node);
+		if (ret)
+			return ret;
+next:
+		iort_node = ACPI_ADD_PTR(struct acpi_iort_node, iort_node,
+					 iort_node->length);
+	}
+
+	return 0;
+}
+
 static int __init iort_table_detect(void)
 {
 	acpi_status status;
@@ -450,6 +573,8 @@ static int __init iort_table_detect(void)
 		return -EINVAL;
 	}
 
+	iort_smmu_init();
+
 	return 0;
 }
 arch_initcall(iort_table_detect);
diff --git a/include/linux/iort.h b/include/linux/iort.h
index 5ebe7e5..ced3054 100644
--- a/include/linux/iort.h
+++ b/include/linux/iort.h
@@ -43,4 +43,19 @@ int iort_smmu_set_ops(struct acpi_iort_node *node,
 					 u32 streamid,
 					 struct acpi_iort_node *node));
 
+struct iort_iommu_config {
+	const char *name;
+	int (*iommu_init)(struct acpi_iort_node *node);
+	bool (*iommu_is_coherent)(struct acpi_iort_node *node);
+	int (*iommu_count_resources)(struct acpi_iort_node *node);
+	void (*iommu_init_resources)(struct resource *res,
+				     struct acpi_iort_node *node);
+};
+
+static inline const struct iort_iommu_config *
+iort_get_iommu_config(struct acpi_iort_node *node)
+{
+	return NULL;
+}
+
 #endif /* __IORT_H__ */
-- 
2.6.4

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

* [RFC PATCH v2 08/15] drivers: acpi: iort: add support for ARM SMMU platform devices creation
@ 2016-06-07 13:31     ` Lorenzo Pieralisi
  0 siblings, 0 replies; 88+ messages in thread
From: Lorenzo Pieralisi @ 2016-06-07 13:31 UTC (permalink / raw)
  To: linux-arm-kernel

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 by specific ARM SMMU drivers) to be
used to define the platform devices names, init the IOMMUs, count their
resources and finally initialize them.

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  | 125 +++++++++++++++++++++++++++++++++++++++++++++++++++
 include/linux/iort.h |  15 +++++++
 2 files changed, 140 insertions(+)

diff --git a/drivers/acpi/iort.c b/drivers/acpi/iort.c
index 875edde..2ef08d9 100644
--- a/drivers/acpi/iort.c
+++ b/drivers/acpi/iort.c
@@ -25,6 +25,7 @@
 #include <linux/kernel.h>
 #include <linux/list.h>
 #include <linux/pci.h>
+#include <linux/platform_device.h>
 #include <linux/slab.h>
 
 struct iort_its_msi_chip {
@@ -436,6 +437,128 @@ iort_pci_get_domain(struct pci_dev *pdev, u32 req_id)
 	return irq_find_matching_fwnode(handle, DOMAIN_BUS_PCI_MSI);
 }
 
+static int __init
+add_smmu_platform_device(const struct iort_iommu_config *iort_cfg,
+			 struct acpi_iort_node *node)
+{
+	struct platform_device *pdev;
+	struct resource *r;
+	enum dev_dma_attr attr;
+	int ret, count;
+
+	pdev = platform_device_alloc(iort_cfg->name, PLATFORM_DEVID_AUTO);
+	if (!pdev)
+		return PTR_ERR(pdev);
+
+	count = iort_cfg->iommu_count_resources(node);
+
+	r = kcalloc(count, sizeof(*r), GFP_KERNEL);
+	if (!r) {
+		ret = -ENOMEM;
+		goto dev_put;
+	}
+
+	iort_cfg->iommu_init_resources(r, node);
+
+	ret = platform_device_add_resources(pdev, r, count);
+	/*
+	 * Resources are duplicated in platform_device_add_resources,
+	 * free their allocated memory
+	 */
+	kfree(r);
+
+	if (ret)
+		goto dev_put;
+
+	/*
+	 * Add a copy of IORT node pointer to platform_data to
+	 * be used to retrieve IORT data information.
+	 */
+	ret = platform_device_add_data(pdev, &node, sizeof(node));
+	if (ret)
+		goto dev_put;
+
+	pdev->dev.dma_mask = kmalloc(sizeof(*pdev->dev.dma_mask), GFP_KERNEL);
+	if (!pdev->dev.dma_mask) {
+		ret = -ENOMEM;
+		goto dev_put;
+	}
+
+	/*
+	 * Set default dma mask value for the table walker,
+	 * to be overridden on probing with correct value.
+	 */
+	*pdev->dev.dma_mask = DMA_BIT_MASK(32);
+	pdev->dev.coherent_dma_mask = *pdev->dev.dma_mask;
+
+	attr = iort_cfg->iommu_is_coherent(node) ?
+			     DEV_DMA_COHERENT : DEV_DMA_NON_COHERENT;
+
+	/* Configure DMA for the page table walker */
+	arch_setup_dma_ops(&pdev->dev, 0, 0, NULL,
+					 attr == DEV_DMA_COHERENT);
+
+	ret = platform_device_add(pdev);
+	if (ret)
+		goto dma_deconfigure;
+
+	ret = iort_cfg->iommu_init(node);
+	if (ret)
+		goto dma_deconfigure;
+
+	return 0;
+
+dma_deconfigure:
+	arch_teardown_dma_ops(&pdev->dev);
+	kfree(pdev->dev.dma_mask);
+
+dev_put:
+	platform_device_put(pdev);
+
+	return ret;
+}
+
+static int __init iort_smmu_init(void)
+{
+	struct acpi_iort_node *iort_node, *iort_end;
+	struct acpi_table_iort *iort;
+	int i, ret;
+
+	/*
+	 * iort_table and iort both point to the start of IORT table, but
+	 * have different struct types
+	 */
+	iort = (struct acpi_table_iort *)iort_table;
+
+	/* Get the first IORT node */
+	iort_node = ACPI_ADD_PTR(struct acpi_iort_node, iort,
+				 iort->node_offset);
+	iort_end = ACPI_ADD_PTR(struct acpi_iort_node, iort_table,
+				iort_table->length);
+
+	for (i = 0; i < iort->node_count; i++) {
+		const struct iort_iommu_config *ops;
+
+		if (iort_node >= iort_end) {
+			pr_err("iort node pointer overflows, bad table\n");
+			return -EINVAL;
+		}
+
+		ops = iort_get_iommu_config(iort_node);
+		if (!ops)
+			goto next;
+
+		ret = add_smmu_platform_device(ops, iort_node);
+		if (ret)
+			return ret;
+next:
+		iort_node = ACPI_ADD_PTR(struct acpi_iort_node, iort_node,
+					 iort_node->length);
+	}
+
+	return 0;
+}
+
 static int __init iort_table_detect(void)
 {
 	acpi_status status;
@@ -450,6 +573,8 @@ static int __init iort_table_detect(void)
 		return -EINVAL;
 	}
 
+	iort_smmu_init();
+
 	return 0;
 }
 arch_initcall(iort_table_detect);
diff --git a/include/linux/iort.h b/include/linux/iort.h
index 5ebe7e5..ced3054 100644
--- a/include/linux/iort.h
+++ b/include/linux/iort.h
@@ -43,4 +43,19 @@ int iort_smmu_set_ops(struct acpi_iort_node *node,
 					 u32 streamid,
 					 struct acpi_iort_node *node));
 
+struct iort_iommu_config {
+	const char *name;
+	int (*iommu_init)(struct acpi_iort_node *node);
+	bool (*iommu_is_coherent)(struct acpi_iort_node *node);
+	int (*iommu_count_resources)(struct acpi_iort_node *node);
+	void (*iommu_init_resources)(struct resource *res,
+				     struct acpi_iort_node *node);
+};
+
+static inline const struct iort_iommu_config *
+iort_get_iommu_config(struct acpi_iort_node *node)
+{
+	return NULL;
+}
+
 #endif /* __IORT_H__ */
-- 
2.6.4

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

* [RFC PATCH v2 09/15] drivers: iommu: arm-smmu-v3: split probe functions into DT/generic portions
  2016-06-07 13:30 ` Lorenzo Pieralisi
  (?)
@ 2016-06-07 13:31     ` Lorenzo Pieralisi
  -1 siblings, 0 replies; 88+ messages in thread
From: Lorenzo Pieralisi @ 2016-06-07 13:31 UTC (permalink / raw)
  To: iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA
  Cc: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, Marc Zyngier,
	Rafael J. Wysocki, Will Deacon,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-pci-u79uwXL29TY76Z2rM5mHXA, Sinan Kaya,
	linux-acpi-u79uwXL29TY76Z2rM5mHXA, Hanjun Guo, Tomasz Nowicki,
	Jon Masters

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-5wv7dgnIgG8@public.gmane.org>
Cc: Will Deacon <will.deacon-5wv7dgnIgG8@public.gmane.org>
Cc: Hanjun Guo <hanjun.guo-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
Cc: Robin Murphy <robin.murphy-5wv7dgnIgG8@public.gmane.org>
Cc: Joerg Roedel <joro-zLv9SwRftAIdnm+yROfE0A@public.gmane.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 6379f0a..75f93aa 100644
--- a/drivers/iommu/arm-smmu-v3.c
+++ b/drivers/iommu/arm-smmu-v3.c
@@ -20,12 +20,14 @@
  * 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>
 #include <linux/interrupt.h>
 #include <linux/iommu.h>
 #include <linux/iopoll.h>
+#include <linux/iort.h>
 #include <linux/module.h>
 #include <linux/msi.h>
 #include <linux/of.h>
@@ -2331,10 +2333,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);
@@ -2386,13 +2388,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");
@@ -2513,7 +2511,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;
@@ -2555,10 +2590,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;
 
@@ -2593,7 +2634,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

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

* [RFC PATCH v2 09/15] drivers: iommu: arm-smmu-v3: split probe functions into DT/generic portions
@ 2016-06-07 13:31     ` Lorenzo Pieralisi
  0 siblings, 0 replies; 88+ messages in thread
From: Lorenzo Pieralisi @ 2016-06-07 13:31 UTC (permalink / raw)
  To: iommu
  Cc: Lorenzo Pieralisi, Will Deacon, Hanjun Guo, Robin Murphy,
	Joerg Roedel, Marc Zyngier, Rafael J. Wysocki, Tomasz Nowicki,
	Jon Masters, Sinan Kaya, linux-acpi, linux-pci, linux-kernel,
	linux-arm-kernel

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>
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 6379f0a..75f93aa 100644
--- a/drivers/iommu/arm-smmu-v3.c
+++ b/drivers/iommu/arm-smmu-v3.c
@@ -20,12 +20,14 @@
  * 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>
 #include <linux/interrupt.h>
 #include <linux/iommu.h>
 #include <linux/iopoll.h>
+#include <linux/iort.h>
 #include <linux/module.h>
 #include <linux/msi.h>
 #include <linux/of.h>
@@ -2331,10 +2333,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);
@@ -2386,13 +2388,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");
@@ -2513,7 +2511,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;
@@ -2555,10 +2590,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;
 
@@ -2593,7 +2634,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

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

* [RFC PATCH v2 09/15] drivers: iommu: arm-smmu-v3: split probe functions into DT/generic portions
@ 2016-06-07 13:31     ` Lorenzo Pieralisi
  0 siblings, 0 replies; 88+ messages in thread
From: Lorenzo Pieralisi @ 2016-06-07 13:31 UTC (permalink / raw)
  To: linux-arm-kernel

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>
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 6379f0a..75f93aa 100644
--- a/drivers/iommu/arm-smmu-v3.c
+++ b/drivers/iommu/arm-smmu-v3.c
@@ -20,12 +20,14 @@
  * 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>
 #include <linux/interrupt.h>
 #include <linux/iommu.h>
 #include <linux/iopoll.h>
+#include <linux/iort.h>
 #include <linux/module.h>
 #include <linux/msi.h>
 #include <linux/of.h>
@@ -2331,10 +2333,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);
@@ -2386,13 +2388,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");
@@ -2513,7 +2511,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;
@@ -2555,10 +2590,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;
 
@@ -2593,7 +2634,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

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

* [RFC PATCH v2 10/15] drivers: iommu: arm-smmu-v3: enable ACPI driver initialization
  2016-06-07 13:30 ` Lorenzo Pieralisi
  (?)
@ 2016-06-07 13:31     ` Lorenzo Pieralisi
  -1 siblings, 0 replies; 88+ messages in thread
From: Lorenzo Pieralisi @ 2016-06-07 13:31 UTC (permalink / raw)
  To: iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA
  Cc: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, Marc Zyngier,
	Rafael J. Wysocki, Will Deacon,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-pci-u79uwXL29TY76Z2rM5mHXA, Sinan Kaya,
	linux-acpi-u79uwXL29TY76Z2rM5mHXA, Hanjun Guo, Tomasz Nowicki,
	Jon Masters

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-5wv7dgnIgG8@public.gmane.org>
Cc: Will Deacon <will.deacon-5wv7dgnIgG8@public.gmane.org>
Cc: Robin Murphy <robin.murphy-5wv7dgnIgG8@public.gmane.org>
Cc: Joerg Roedel <joro-zLv9SwRftAIdnm+yROfE0A@public.gmane.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 75f93aa..90745a8 100644
--- a/drivers/iommu/arm-smmu-v3.c
+++ b/drivers/iommu/arm-smmu-v3.c
@@ -2643,11 +2643,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

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

* [RFC PATCH v2 10/15] drivers: iommu: arm-smmu-v3: enable ACPI driver initialization
@ 2016-06-07 13:31     ` Lorenzo Pieralisi
  0 siblings, 0 replies; 88+ messages in thread
From: Lorenzo Pieralisi @ 2016-06-07 13:31 UTC (permalink / raw)
  To: iommu
  Cc: Lorenzo Pieralisi, Will Deacon, Robin Murphy, Joerg Roedel,
	Marc Zyngier, Rafael J. Wysocki, Tomasz Nowicki, Hanjun Guo,
	Jon Masters, Sinan Kaya, linux-acpi, linux-pci, linux-kernel,
	linux-arm-kernel

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>
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 75f93aa..90745a8 100644
--- a/drivers/iommu/arm-smmu-v3.c
+++ b/drivers/iommu/arm-smmu-v3.c
@@ -2643,11 +2643,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

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

* [RFC PATCH v2 10/15] drivers: iommu: arm-smmu-v3: enable ACPI driver initialization
@ 2016-06-07 13:31     ` Lorenzo Pieralisi
  0 siblings, 0 replies; 88+ messages in thread
From: Lorenzo Pieralisi @ 2016-06-07 13:31 UTC (permalink / raw)
  To: linux-arm-kernel

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>
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 75f93aa..90745a8 100644
--- a/drivers/iommu/arm-smmu-v3.c
+++ b/drivers/iommu/arm-smmu-v3.c
@@ -2643,11 +2643,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

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

* [RFC PATCH v2 11/15] drivers: iommu: arm-smmu-v3: add IORT iommu configuration
  2016-06-07 13:30 ` Lorenzo Pieralisi
@ 2016-06-07 13:31   ` Lorenzo Pieralisi
  -1 siblings, 0 replies; 88+ messages in thread
From: Lorenzo Pieralisi @ 2016-06-07 13:31 UTC (permalink / raw)
  To: iommu
  Cc: Lorenzo Pieralisi, Will Deacon, Robin Murphy, Joerg Roedel,
	Marc Zyngier, Rafael J. Wysocki, Tomasz Nowicki, Hanjun Guo,
	Jon Masters, Sinan Kaya, linux-acpi, linux-pci, linux-kernel,
	linux-arm-kernel

In ACPI bases systems, in order to be able to create platform
devices and initialize them for arm-smmu-v3 components, the IORT
infrastructure requires ARM SMMU drivers to initialize a set of
operations that are used by the IORT kernel layer to configure platform
devices for ARM SMMU components in turn.

This patch adds the IORT IOMMU configuration for the ARM SMMU v3 kernel
driver.

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/iommu/arm-smmu-v3.c | 101 ++++++++++++++++++++++++++++++++++++++++++++
 include/linux/iort.h        |  12 +++++-
 2 files changed, 112 insertions(+), 1 deletion(-)

diff --git a/drivers/iommu/arm-smmu-v3.c b/drivers/iommu/arm-smmu-v3.c
index 90745a8..7acb6b5 100644
--- a/drivers/iommu/arm-smmu-v3.c
+++ b/drivers/iommu/arm-smmu-v3.c
@@ -2687,6 +2687,107 @@ 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_init(struct acpi_iort_node *node)
+{
+	iort_smmu_set_ops(node, &arm_smmu_ops, NULL);
+
+	return 0;
+}
+
+static void acpi_smmu_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_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_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_register_irq(smmu->event_gsiv, "eventq",
+				       &res[num_res++]);
+
+	if (smmu->pri_gsiv)
+		acpi_smmu_register_irq(smmu->pri_gsiv, "priq",
+				       &res[num_res++]);
+
+	if (smmu->gerr_gsiv)
+		acpi_smmu_register_irq(smmu->gerr_gsiv, "gerror",
+				       &res[num_res++]);
+
+	if (smmu->sync_gsiv)
+		acpi_smmu_register_irq(smmu->sync_gsiv, "cmdq-sync",
+				       &res[num_res++]);
+}
+
+static bool arm_smmu_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;
+}
+
+const struct iort_iommu_config iort_arm_smmu_v3_cfg = {
+	.name = "arm-smmu-v3",
+	.iommu_init = acpi_smmu_init,
+	.iommu_is_coherent = arm_smmu_is_coherent,
+	.iommu_count_resources = arm_smmu_count_resources,
+	.iommu_init_resources = arm_smmu_init_resources
+};
+#endif
+
 MODULE_DESCRIPTION("IOMMU API for ARM architected SMMUv3 implementations");
 MODULE_AUTHOR("Will Deacon <will.deacon@arm.com>");
 MODULE_LICENSE("GPL v2");
diff --git a/include/linux/iort.h b/include/linux/iort.h
index ced3054..5dcfa09 100644
--- a/include/linux/iort.h
+++ b/include/linux/iort.h
@@ -55,7 +55,17 @@ struct iort_iommu_config {
 static inline const struct iort_iommu_config *
 iort_get_iommu_config(struct acpi_iort_node *node)
 {
-	return NULL;
+	switch (node->type) {
+#if IS_ENABLED(CONFIG_ARM_SMMU_V3)
+	case ACPI_IORT_NODE_SMMU_V3: {
+		extern const struct iort_iommu_config iort_arm_smmu_v3_cfg;
+
+		return &iort_arm_smmu_v3_cfg;
+	}
+#endif
+	default:
+		return NULL;
+	}
 }
 
 #endif /* __IORT_H__ */
-- 
2.6.4

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

* [RFC PATCH v2 11/15] drivers: iommu: arm-smmu-v3: add IORT iommu configuration
@ 2016-06-07 13:31   ` Lorenzo Pieralisi
  0 siblings, 0 replies; 88+ messages in thread
From: Lorenzo Pieralisi @ 2016-06-07 13:31 UTC (permalink / raw)
  To: linux-arm-kernel

In ACPI bases systems, in order to be able to create platform
devices and initialize them for arm-smmu-v3 components, the IORT
infrastructure requires ARM SMMU drivers to initialize a set of
operations that are used by the IORT kernel layer to configure platform
devices for ARM SMMU components in turn.

This patch adds the IORT IOMMU configuration for the ARM SMMU v3 kernel
driver.

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/iommu/arm-smmu-v3.c | 101 ++++++++++++++++++++++++++++++++++++++++++++
 include/linux/iort.h        |  12 +++++-
 2 files changed, 112 insertions(+), 1 deletion(-)

diff --git a/drivers/iommu/arm-smmu-v3.c b/drivers/iommu/arm-smmu-v3.c
index 90745a8..7acb6b5 100644
--- a/drivers/iommu/arm-smmu-v3.c
+++ b/drivers/iommu/arm-smmu-v3.c
@@ -2687,6 +2687,107 @@ 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_init(struct acpi_iort_node *node)
+{
+	iort_smmu_set_ops(node, &arm_smmu_ops, NULL);
+
+	return 0;
+}
+
+static void acpi_smmu_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_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_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_register_irq(smmu->event_gsiv, "eventq",
+				       &res[num_res++]);
+
+	if (smmu->pri_gsiv)
+		acpi_smmu_register_irq(smmu->pri_gsiv, "priq",
+				       &res[num_res++]);
+
+	if (smmu->gerr_gsiv)
+		acpi_smmu_register_irq(smmu->gerr_gsiv, "gerror",
+				       &res[num_res++]);
+
+	if (smmu->sync_gsiv)
+		acpi_smmu_register_irq(smmu->sync_gsiv, "cmdq-sync",
+				       &res[num_res++]);
+}
+
+static bool arm_smmu_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;
+}
+
+const struct iort_iommu_config iort_arm_smmu_v3_cfg = {
+	.name = "arm-smmu-v3",
+	.iommu_init = acpi_smmu_init,
+	.iommu_is_coherent = arm_smmu_is_coherent,
+	.iommu_count_resources = arm_smmu_count_resources,
+	.iommu_init_resources = arm_smmu_init_resources
+};
+#endif
+
 MODULE_DESCRIPTION("IOMMU API for ARM architected SMMUv3 implementations");
 MODULE_AUTHOR("Will Deacon <will.deacon@arm.com>");
 MODULE_LICENSE("GPL v2");
diff --git a/include/linux/iort.h b/include/linux/iort.h
index ced3054..5dcfa09 100644
--- a/include/linux/iort.h
+++ b/include/linux/iort.h
@@ -55,7 +55,17 @@ struct iort_iommu_config {
 static inline const struct iort_iommu_config *
 iort_get_iommu_config(struct acpi_iort_node *node)
 {
-	return NULL;
+	switch (node->type) {
+#if IS_ENABLED(CONFIG_ARM_SMMU_V3)
+	case ACPI_IORT_NODE_SMMU_V3: {
+		extern const struct iort_iommu_config iort_arm_smmu_v3_cfg;
+
+		return &iort_arm_smmu_v3_cfg;
+	}
+#endif
+	default:
+		return NULL;
+	}
 }
 
 #endif /* __IORT_H__ */
-- 
2.6.4

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

* [RFC PATCH v2 12/15] drivers: acpi: implement acpi_dma_configure
  2016-06-07 13:30 ` Lorenzo Pieralisi
@ 2016-06-07 13:31   ` Lorenzo Pieralisi
  -1 siblings, 0 replies; 88+ messages in thread
From: Lorenzo Pieralisi @ 2016-06-07 13:31 UTC (permalink / raw)
  To: iommu
  Cc: Lorenzo Pieralisi, Bjorn Helgaas, Robin Murphy, Tomasz Nowicki,
	Joerg Roedel, Rafael J. Wysocki, Will Deacon, Marc Zyngier,
	Hanjun Guo, Jon Masters, Sinan Kaya, linux-acpi, linux-pci,
	linux-kernel, linux-arm-kernel

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>
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 8e3ef72..01dd369 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

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

* [RFC PATCH v2 12/15] drivers: acpi: implement acpi_dma_configure
@ 2016-06-07 13:31   ` Lorenzo Pieralisi
  0 siblings, 0 replies; 88+ messages in thread
From: Lorenzo Pieralisi @ 2016-06-07 13:31 UTC (permalink / raw)
  To: linux-arm-kernel

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>
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 8e3ef72..01dd369 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

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

* [RFC PATCH v2 13/15] drivers: acpi: iort: introduce iort_iommu_configure
  2016-06-07 13:30 ` Lorenzo Pieralisi
  (?)
@ 2016-06-07 13:31     ` Lorenzo Pieralisi
  -1 siblings, 0 replies; 88+ messages in thread
From: Lorenzo Pieralisi @ 2016-06-07 13:31 UTC (permalink / raw)
  To: iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA
  Cc: Marc Zyngier, Tomasz Nowicki, Rafael J. Wysocki,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, Will Deacon, Sinan Kaya,
	linux-acpi-u79uwXL29TY76Z2rM5mHXA,
	linux-pci-u79uwXL29TY76Z2rM5mHXA, Hanjun Guo, Jon Masters,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r

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.

The iort_iommu_configure() implementation requires an IORT API
to retrieve the parent node for any given IORT node, so this
patch adds a function to the IORT kernel layer that serves that
specific purpose.

This patch implements 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-5wv7dgnIgG8@public.gmane.org>
Cc: Hanjun Guo <hanjun.guo-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
Cc: Tomasz Nowicki <tn-nYOzD4b6Jr9Wk0Htik3J/w@public.gmane.org>
Cc: "Rafael J. Wysocki" <rjw-LthD3rsA81gm4RdzfppkhA@public.gmane.org>
---
 drivers/acpi/iort.c  | 77 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 drivers/acpi/scan.c  |  7 ++++-
 include/linux/iort.h |  7 +++++
 3 files changed, 90 insertions(+), 1 deletion(-)

diff --git a/drivers/acpi/iort.c b/drivers/acpi/iort.c
index 2ef08d9..56258ac 100644
--- a/drivers/acpi/iort.c
+++ b/drivers/acpi/iort.c
@@ -213,6 +213,29 @@ iort_scan_node(enum acpi_iort_node_type type,
 	return NULL;
 }
 
+static struct acpi_iort_node *
+iort_find_parent_node(struct acpi_iort_node *node)
+{
+	struct acpi_iort_id_mapping *id;
+
+	if (!node || !node->mapping_offset || !node->mapping_count)
+		return NULL;
+
+	id = ACPI_ADD_PTR(struct acpi_iort_id_mapping, node,
+			  node->mapping_offset);
+
+	if (!id->output_reference) {
+		pr_err(FW_BUG "[node %p type %d] ID map has NULL parent reference\n",
+		       node, node->type);
+		return NULL;
+	}
+
+	node = ACPI_ADD_PTR(struct acpi_iort_node, iort_table,
+			    id->output_reference);
+
+	return node;
+}
+
 static acpi_status
 iort_match_callback(struct acpi_iort_node *node, void *context)
 {
@@ -437,6 +460,60 @@ iort_pci_get_domain(struct pci_dev *pdev, 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;
+}
+
+/**
+ * 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;
+	const struct iort_ops_node *iort_ops;
+	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_find_dev_callback, &bus->dev);
+	} else {
+		node = iort_scan_node(ACPI_IORT_NODE_NAMED_COMPONENT,
+				      iort_find_dev_callback, dev);
+	}
+
+	if (!node)
+		return NULL;
+
+	parent = iort_find_parent_node(node);
+
+	if (!parent)
+		return NULL;
+
+	iort_ops = iort_smmu_get_ops_node(parent);
+
+	if (iort_ops && iort_ops->iommu_xlate) {
+		iort_dev_map_rid(node, rid, &devid, parent->type);
+		iort_ops->iommu_xlate(dev, devid, parent);
+		return iort_ops->ops;
+	}
+
+	return NULL;
+}
+
 static int __init
 add_smmu_platform_device(const struct iort_iommu_config *iort_cfg,
 			 struct acpi_iort_node *node)
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 5dcfa09..bb29647 100644
--- a/include/linux/iort.h
+++ b/include/linux/iort.h
@@ -30,12 +30,19 @@ struct fwnode_handle *iort_its_find_domain_token(int trans_id);
 bool iort_node_match(u8 type);
 u32 iort_pci_get_msi_rid(struct pci_dev *pdev, u32 req_id);
 struct irq_domain *iort_pci_get_domain(struct pci_dev *pdev, u32 req_id);
+
+/* IOMMU interface */
+const struct iommu_ops *iort_iommu_configure(struct device *dev);
 #else
 static inline bool iort_node_match(u8 type) { return false; }
 static inline u32 iort_pci_get_msi_rid(struct pci_dev *pdev, u32 req_id)
 { return req_id; }
 static inline struct irq_domain *
 iort_pci_get_domain(struct pci_dev *pdev, u32 req_id) { return NULL; }
+
+/* IOMMU interface */
+static inline const struct iommu_ops *
+iort_iommu_configure(struct device *dev) { return NULL; }
 #endif
 int iort_smmu_set_ops(struct acpi_iort_node *node,
 		      const struct iommu_ops *ops,
-- 
2.6.4

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

* [RFC PATCH v2 13/15] drivers: acpi: iort: introduce iort_iommu_configure
@ 2016-06-07 13:31     ` Lorenzo Pieralisi
  0 siblings, 0 replies; 88+ messages in thread
From: Lorenzo Pieralisi @ 2016-06-07 13:31 UTC (permalink / raw)
  To: iommu
  Cc: Lorenzo Pieralisi, Hanjun Guo, Tomasz Nowicki, Rafael J. Wysocki,
	Will Deacon, Marc Zyngier, Robin Murphy, Joerg Roedel,
	Jon Masters, Sinan Kaya, linux-acpi, linux-pci, linux-kernel,
	linux-arm-kernel

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.

The iort_iommu_configure() implementation requires an IORT API
to retrieve the parent node for any given IORT node, so this
patch adds a function to the IORT kernel layer that serves that
specific purpose.

This patch implements 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  | 77 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 drivers/acpi/scan.c  |  7 ++++-
 include/linux/iort.h |  7 +++++
 3 files changed, 90 insertions(+), 1 deletion(-)

diff --git a/drivers/acpi/iort.c b/drivers/acpi/iort.c
index 2ef08d9..56258ac 100644
--- a/drivers/acpi/iort.c
+++ b/drivers/acpi/iort.c
@@ -213,6 +213,29 @@ iort_scan_node(enum acpi_iort_node_type type,
 	return NULL;
 }
 
+static struct acpi_iort_node *
+iort_find_parent_node(struct acpi_iort_node *node)
+{
+	struct acpi_iort_id_mapping *id;
+
+	if (!node || !node->mapping_offset || !node->mapping_count)
+		return NULL;
+
+	id = ACPI_ADD_PTR(struct acpi_iort_id_mapping, node,
+			  node->mapping_offset);
+
+	if (!id->output_reference) {
+		pr_err(FW_BUG "[node %p type %d] ID map has NULL parent reference\n",
+		       node, node->type);
+		return NULL;
+	}
+
+	node = ACPI_ADD_PTR(struct acpi_iort_node, iort_table,
+			    id->output_reference);
+
+	return node;
+}
+
 static acpi_status
 iort_match_callback(struct acpi_iort_node *node, void *context)
 {
@@ -437,6 +460,60 @@ iort_pci_get_domain(struct pci_dev *pdev, 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;
+}
+
+/**
+ * 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;
+	const struct iort_ops_node *iort_ops;
+	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_find_dev_callback, &bus->dev);
+	} else {
+		node = iort_scan_node(ACPI_IORT_NODE_NAMED_COMPONENT,
+				      iort_find_dev_callback, dev);
+	}
+
+	if (!node)
+		return NULL;
+
+	parent = iort_find_parent_node(node);
+
+	if (!parent)
+		return NULL;
+
+	iort_ops = iort_smmu_get_ops_node(parent);
+
+	if (iort_ops && iort_ops->iommu_xlate) {
+		iort_dev_map_rid(node, rid, &devid, parent->type);
+		iort_ops->iommu_xlate(dev, devid, parent);
+		return iort_ops->ops;
+	}
+
+	return NULL;
+}
+
 static int __init
 add_smmu_platform_device(const struct iort_iommu_config *iort_cfg,
 			 struct acpi_iort_node *node)
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 5dcfa09..bb29647 100644
--- a/include/linux/iort.h
+++ b/include/linux/iort.h
@@ -30,12 +30,19 @@ struct fwnode_handle *iort_its_find_domain_token(int trans_id);
 bool iort_node_match(u8 type);
 u32 iort_pci_get_msi_rid(struct pci_dev *pdev, u32 req_id);
 struct irq_domain *iort_pci_get_domain(struct pci_dev *pdev, u32 req_id);
+
+/* IOMMU interface */
+const struct iommu_ops *iort_iommu_configure(struct device *dev);
 #else
 static inline bool iort_node_match(u8 type) { return false; }
 static inline u32 iort_pci_get_msi_rid(struct pci_dev *pdev, u32 req_id)
 { return req_id; }
 static inline struct irq_domain *
 iort_pci_get_domain(struct pci_dev *pdev, u32 req_id) { return NULL; }
+
+/* IOMMU interface */
+static inline const struct iommu_ops *
+iort_iommu_configure(struct device *dev) { return NULL; }
 #endif
 int iort_smmu_set_ops(struct acpi_iort_node *node,
 		      const struct iommu_ops *ops,
-- 
2.6.4

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

* [RFC PATCH v2 13/15] drivers: acpi: iort: introduce iort_iommu_configure
@ 2016-06-07 13:31     ` Lorenzo Pieralisi
  0 siblings, 0 replies; 88+ messages in thread
From: Lorenzo Pieralisi @ 2016-06-07 13:31 UTC (permalink / raw)
  To: linux-arm-kernel

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.

The iort_iommu_configure() implementation requires an IORT API
to retrieve the parent node for any given IORT node, so this
patch adds a function to the IORT kernel layer that serves that
specific purpose.

This patch implements 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  | 77 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 drivers/acpi/scan.c  |  7 ++++-
 include/linux/iort.h |  7 +++++
 3 files changed, 90 insertions(+), 1 deletion(-)

diff --git a/drivers/acpi/iort.c b/drivers/acpi/iort.c
index 2ef08d9..56258ac 100644
--- a/drivers/acpi/iort.c
+++ b/drivers/acpi/iort.c
@@ -213,6 +213,29 @@ iort_scan_node(enum acpi_iort_node_type type,
 	return NULL;
 }
 
+static struct acpi_iort_node *
+iort_find_parent_node(struct acpi_iort_node *node)
+{
+	struct acpi_iort_id_mapping *id;
+
+	if (!node || !node->mapping_offset || !node->mapping_count)
+		return NULL;
+
+	id = ACPI_ADD_PTR(struct acpi_iort_id_mapping, node,
+			  node->mapping_offset);
+
+	if (!id->output_reference) {
+		pr_err(FW_BUG "[node %p type %d] ID map has NULL parent reference\n",
+		       node, node->type);
+		return NULL;
+	}
+
+	node = ACPI_ADD_PTR(struct acpi_iort_node, iort_table,
+			    id->output_reference);
+
+	return node;
+}
+
 static acpi_status
 iort_match_callback(struct acpi_iort_node *node, void *context)
 {
@@ -437,6 +460,60 @@ iort_pci_get_domain(struct pci_dev *pdev, 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;
+}
+
+/**
+ * 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;
+	const struct iort_ops_node *iort_ops;
+	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_find_dev_callback, &bus->dev);
+	} else {
+		node = iort_scan_node(ACPI_IORT_NODE_NAMED_COMPONENT,
+				      iort_find_dev_callback, dev);
+	}
+
+	if (!node)
+		return NULL;
+
+	parent = iort_find_parent_node(node);
+
+	if (!parent)
+		return NULL;
+
+	iort_ops = iort_smmu_get_ops_node(parent);
+
+	if (iort_ops && iort_ops->iommu_xlate) {
+		iort_dev_map_rid(node, rid, &devid, parent->type);
+		iort_ops->iommu_xlate(dev, devid, parent);
+		return iort_ops->ops;
+	}
+
+	return NULL;
+}
+
 static int __init
 add_smmu_platform_device(const struct iort_iommu_config *iort_cfg,
 			 struct acpi_iort_node *node)
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 5dcfa09..bb29647 100644
--- a/include/linux/iort.h
+++ b/include/linux/iort.h
@@ -30,12 +30,19 @@ struct fwnode_handle *iort_its_find_domain_token(int trans_id);
 bool iort_node_match(u8 type);
 u32 iort_pci_get_msi_rid(struct pci_dev *pdev, u32 req_id);
 struct irq_domain *iort_pci_get_domain(struct pci_dev *pdev, u32 req_id);
+
+/* IOMMU interface */
+const struct iommu_ops *iort_iommu_configure(struct device *dev);
 #else
 static inline bool iort_node_match(u8 type) { return false; }
 static inline u32 iort_pci_get_msi_rid(struct pci_dev *pdev, u32 req_id)
 { return req_id; }
 static inline struct irq_domain *
 iort_pci_get_domain(struct pci_dev *pdev, u32 req_id) { return NULL; }
+
+/* IOMMU interface */
+static inline const struct iommu_ops *
+iort_iommu_configure(struct device *dev) { return NULL; }
 #endif
 int iort_smmu_set_ops(struct acpi_iort_node *node,
 		      const struct iommu_ops *ops,
-- 
2.6.4

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

* [RFC PATCH v2 14/15] drivers: acpi: iort: add function to retrieve IOMMU platform devices
  2016-06-07 13:30 ` Lorenzo Pieralisi
@ 2016-06-07 13:31   ` Lorenzo Pieralisi
  -1 siblings, 0 replies; 88+ messages in thread
From: Lorenzo Pieralisi @ 2016-06-07 13:31 UTC (permalink / raw)
  To: iommu
  Cc: Lorenzo Pieralisi, Hanjun Guo, Tomasz Nowicki, Rafael J. Wysocki,
	Will Deacon, Marc Zyngier, Robin Murphy, Joerg Roedel,
	Jon Masters, Sinan Kaya, linux-acpi, linux-pci, linux-kernel,
	linux-arm-kernel

Some kernel components (ie ARM SMMU drivers) require to look-up
the platform device corresponding to a specific IORT node to
carry out streamid translation.

Platform devices created for ARM SMMU components out of IORT tables
have no fwnode token initialized, in that they do not have any device
tree node or ACPI device backing them.

Therefore, to implement the IORT node<->platform device look-up, this
patch adds a function to the IORT kernel layer that allows to
retrieve the platform device corresponding to an IORT node through
platform device name and its platform_data (that for platform devices
created out of IORT nodes for SMMUs contains a pointer to the respective
IORT 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  | 36 ++++++++++++++++++++++++++++++++++++
 include/linux/iort.h |  3 +++
 2 files changed, 39 insertions(+)

diff --git a/drivers/acpi/iort.c b/drivers/acpi/iort.c
index 56258ac..8e76acc 100644
--- a/drivers/acpi/iort.c
+++ b/drivers/acpi/iort.c
@@ -34,6 +34,42 @@ struct iort_its_msi_chip {
 	u32			translation_id;
 };
 
+static int iort_dev_match(struct device *dev, void *data)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	const char *name = data;
+
+	return !strcmp(pdev->name, name);
+}
+
+/**
+ * iort_find_iommu_device- Retrieve IOMMU platform_device associated with
+ *			   IORT node
+ *
+ * @node: IORT table node associated with the device
+ *
+ * Returns: device on success
+ *          NULL on failure
+ */
+struct platform_device *iort_find_iommu_device(struct acpi_iort_node *node)
+{
+	struct acpi_iort_node *curr;
+	struct device *dev = NULL;
+	const struct iort_iommu_config *cfg = iort_get_iommu_config(node);
+
+	if (!cfg)
+		return NULL;
+
+	while ((dev = bus_find_device(&platform_bus_type, dev,
+				      (void *)cfg->name, iort_dev_match))) {
+		curr = *(struct acpi_iort_node **) dev_get_platdata(dev);
+		if (curr == node)
+			return to_platform_device(dev);
+	}
+
+	return NULL;
+}
+
 struct iort_ops_node {
 	struct list_head list;
 	struct acpi_iort_node *node;
diff --git a/include/linux/iort.h b/include/linux/iort.h
index bb29647..4c8dcf8 100644
--- a/include/linux/iort.h
+++ b/include/linux/iort.h
@@ -32,6 +32,7 @@ u32 iort_pci_get_msi_rid(struct pci_dev *pdev, u32 req_id);
 struct irq_domain *iort_pci_get_domain(struct pci_dev *pdev, u32 req_id);
 
 /* IOMMU interface */
+struct platform_device *iort_find_iommu_device(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; }
@@ -41,6 +42,8 @@ static inline struct irq_domain *
 iort_pci_get_domain(struct pci_dev *pdev, u32 req_id) { return NULL; }
 
 /* IOMMU interface */
+static inline struct platform_device *
+iort_find_iommu_device(struct acpi_iort_node *node) { return NULL; }
 static inline const struct iommu_ops *
 iort_iommu_configure(struct device *dev) { return NULL; }
 #endif
-- 
2.6.4


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

* [RFC PATCH v2 14/15] drivers: acpi: iort: add function to retrieve IOMMU platform devices
@ 2016-06-07 13:31   ` Lorenzo Pieralisi
  0 siblings, 0 replies; 88+ messages in thread
From: Lorenzo Pieralisi @ 2016-06-07 13:31 UTC (permalink / raw)
  To: linux-arm-kernel

Some kernel components (ie ARM SMMU drivers) require to look-up
the platform device corresponding to a specific IORT node to
carry out streamid translation.

Platform devices created for ARM SMMU components out of IORT tables
have no fwnode token initialized, in that they do not have any device
tree node or ACPI device backing them.

Therefore, to implement the IORT node<->platform device look-up, this
patch adds a function to the IORT kernel layer that allows to
retrieve the platform device corresponding to an IORT node through
platform device name and its platform_data (that for platform devices
created out of IORT nodes for SMMUs contains a pointer to the respective
IORT 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  | 36 ++++++++++++++++++++++++++++++++++++
 include/linux/iort.h |  3 +++
 2 files changed, 39 insertions(+)

diff --git a/drivers/acpi/iort.c b/drivers/acpi/iort.c
index 56258ac..8e76acc 100644
--- a/drivers/acpi/iort.c
+++ b/drivers/acpi/iort.c
@@ -34,6 +34,42 @@ struct iort_its_msi_chip {
 	u32			translation_id;
 };
 
+static int iort_dev_match(struct device *dev, void *data)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	const char *name = data;
+
+	return !strcmp(pdev->name, name);
+}
+
+/**
+ * iort_find_iommu_device- Retrieve IOMMU platform_device associated with
+ *			   IORT node
+ *
+ * @node: IORT table node associated with the device
+ *
+ * Returns: device on success
+ *          NULL on failure
+ */
+struct platform_device *iort_find_iommu_device(struct acpi_iort_node *node)
+{
+	struct acpi_iort_node *curr;
+	struct device *dev = NULL;
+	const struct iort_iommu_config *cfg = iort_get_iommu_config(node);
+
+	if (!cfg)
+		return NULL;
+
+	while ((dev = bus_find_device(&platform_bus_type, dev,
+				      (void *)cfg->name, iort_dev_match))) {
+		curr = *(struct acpi_iort_node **) dev_get_platdata(dev);
+		if (curr == node)
+			return to_platform_device(dev);
+	}
+
+	return NULL;
+}
+
 struct iort_ops_node {
 	struct list_head list;
 	struct acpi_iort_node *node;
diff --git a/include/linux/iort.h b/include/linux/iort.h
index bb29647..4c8dcf8 100644
--- a/include/linux/iort.h
+++ b/include/linux/iort.h
@@ -32,6 +32,7 @@ u32 iort_pci_get_msi_rid(struct pci_dev *pdev, u32 req_id);
 struct irq_domain *iort_pci_get_domain(struct pci_dev *pdev, u32 req_id);
 
 /* IOMMU interface */
+struct platform_device *iort_find_iommu_device(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; }
@@ -41,6 +42,8 @@ static inline struct irq_domain *
 iort_pci_get_domain(struct pci_dev *pdev, u32 req_id) { return NULL; }
 
 /* IOMMU interface */
+static inline struct platform_device *
+iort_find_iommu_device(struct acpi_iort_node *node) { return NULL; }
 static inline const struct iommu_ops *
 iort_iommu_configure(struct device *dev) { return NULL; }
 #endif
-- 
2.6.4

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

* [RFC PATCH v2 15/15] drivers: iommu: arm-smmu-v3: allow ACPI based streamid translation
  2016-06-07 13:30 ` Lorenzo Pieralisi
@ 2016-06-07 13:31   ` Lorenzo Pieralisi
  -1 siblings, 0 replies; 88+ messages in thread
From: Lorenzo Pieralisi @ 2016-06-07 13:31 UTC (permalink / raw)
  To: iommu
  Cc: Lorenzo Pieralisi, Will Deacon, Robin Murphy, Joerg Roedel,
	Marc Zyngier, Rafael J. Wysocki, Tomasz Nowicki, Hanjun Guo,
	Jon Masters, Sinan Kaya, linux-acpi, linux-pci, linux-kernel,
	linux-arm-kernel

The ACPI IORT table provides data to ARM SMMU drivers to carry out
streamid mappings and the kernel has the infrastructure to implement
it through the iommu_xlate() IORT SMMU operation hook.

By reusing the infrastructure implemented for of_xlate(), this patch
adds the ARM SMMU v3 iommu_xlate() hook to carry out streamid
translation for ARM SMMU v3 on ACPI based systems.

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/iommu/arm-smmu-v3.c | 60 +++++++++++++++++++++++++++++++++++++++------
 1 file changed, 52 insertions(+), 8 deletions(-)

diff --git a/drivers/iommu/arm-smmu-v3.c b/drivers/iommu/arm-smmu-v3.c
index 7acb6b5..96d0504 100644
--- a/drivers/iommu/arm-smmu-v3.c
+++ b/drivers/iommu/arm-smmu-v3.c
@@ -634,8 +634,23 @@ struct arm_smmu_domain {
 	struct iommu_domain		domain;
 };
 
+enum arm_smmu_fw_type {
+	ARM_SMMU_FW_INVALID = 0,
+	ARM_SMMU_FW_OF,
+	ARM_SMMU_FW_IORT,
+};
+
+struct arm_smmu_fw_handle {
+	enum arm_smmu_fw_type type;
+	union {
+		struct device_node *np;
+		struct acpi_iort_node *iort_node;
+	};
+};
+
 /* SMMU private data for each master */
 struct arm_smmu_master_data {
+	struct arm_smmu_fw_handle	handle;
 	struct arm_smmu_device		*smmu;
 
 	struct arm_smmu_strtab_ent	ste;
@@ -1721,9 +1736,17 @@ 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_dev(struct arm_smmu_fw_handle *handle)
 {
-	struct platform_device *smmu_pdev = of_find_device_by_node(np);
+	struct platform_device *smmu_pdev = NULL;
+
+	if (handle->type == ARM_SMMU_FW_OF) {
+		smmu_pdev = of_find_device_by_node(handle->np);
+		of_node_put(handle->np);
+	} else if (handle->type == ARM_SMMU_FW_IORT) {
+		smmu_pdev = iort_find_iommu_device(handle->iort_node);
+	}
 
 	if (!smmu_pdev)
 		return NULL;
@@ -1743,16 +1766,14 @@ static bool arm_smmu_sid_in_range(struct arm_smmu_device *smmu, u32 sid)
 
 static int arm_smmu_add_device(struct device *dev)
 {
-	struct device_node *np;
 	struct arm_smmu_device *smmu;
 	struct arm_smmu_master_data *data = dev->archdata.iommu;
 
 	if (!data)
 		return -ENODEV;
 
-	np = (struct device_node *)data->smmu;
-	smmu = data->smmu = arm_smmu_get_by_node(np);
-	of_node_put(np);
+	smmu = data->smmu = arm_smmu_get_dev(&data->handle);
+
 	if (!smmu)
 		return -ENODEV;
 
@@ -1854,7 +1875,8 @@ static int arm_smmu_of_xlate(struct device *dev, struct of_phandle_args *args)
 	 * By the time we see this again in an add_device callback, we'll
 	 * be in a position to fix it up with the real thing.
 	 */
-	data->smmu = (struct arm_smmu_device *)args->np;
+	data->handle.type = ARM_SMMU_FW_OF;
+	data->handle.np = args->np;
 	data->sid = args->args[0];
 	dev->archdata.iommu = data;
 
@@ -2688,9 +2710,31 @@ 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 arm_smmu_iort_xlate(struct device *dev, u32 streamid,
+			       struct acpi_iort_node *node)
+{
+	struct arm_smmu_master_data *data;
+
+	if (!node || (node->type != ACPI_IORT_NODE_SMMU_V3))
+		return -ENODEV;
+
+	if (dev->archdata.iommu)
+		return -EEXIST;
+
+	data = kzalloc(sizeof(*data), GFP_KERNEL);
+	if (!data)
+		return -ENOMEM;
+
+	data->handle.type = ARM_SMMU_FW_IORT;
+	data->handle.iort_node = node;
+	data->sid = streamid;
+	dev->archdata.iommu = data;
+	return 0;
+}
+
 static int acpi_smmu_init(struct acpi_iort_node *node)
 {
-	iort_smmu_set_ops(node, &arm_smmu_ops, NULL);
+	iort_smmu_set_ops(node, &arm_smmu_ops, arm_smmu_iort_xlate);
 
 	return 0;
 }
-- 
2.6.4

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

* [RFC PATCH v2 15/15] drivers: iommu: arm-smmu-v3: allow ACPI based streamid translation
@ 2016-06-07 13:31   ` Lorenzo Pieralisi
  0 siblings, 0 replies; 88+ messages in thread
From: Lorenzo Pieralisi @ 2016-06-07 13:31 UTC (permalink / raw)
  To: linux-arm-kernel

The ACPI IORT table provides data to ARM SMMU drivers to carry out
streamid mappings and the kernel has the infrastructure to implement
it through the iommu_xlate() IORT SMMU operation hook.

By reusing the infrastructure implemented for of_xlate(), this patch
adds the ARM SMMU v3 iommu_xlate() hook to carry out streamid
translation for ARM SMMU v3 on ACPI based systems.

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/iommu/arm-smmu-v3.c | 60 +++++++++++++++++++++++++++++++++++++++------
 1 file changed, 52 insertions(+), 8 deletions(-)

diff --git a/drivers/iommu/arm-smmu-v3.c b/drivers/iommu/arm-smmu-v3.c
index 7acb6b5..96d0504 100644
--- a/drivers/iommu/arm-smmu-v3.c
+++ b/drivers/iommu/arm-smmu-v3.c
@@ -634,8 +634,23 @@ struct arm_smmu_domain {
 	struct iommu_domain		domain;
 };
 
+enum arm_smmu_fw_type {
+	ARM_SMMU_FW_INVALID = 0,
+	ARM_SMMU_FW_OF,
+	ARM_SMMU_FW_IORT,
+};
+
+struct arm_smmu_fw_handle {
+	enum arm_smmu_fw_type type;
+	union {
+		struct device_node *np;
+		struct acpi_iort_node *iort_node;
+	};
+};
+
 /* SMMU private data for each master */
 struct arm_smmu_master_data {
+	struct arm_smmu_fw_handle	handle;
 	struct arm_smmu_device		*smmu;
 
 	struct arm_smmu_strtab_ent	ste;
@@ -1721,9 +1736,17 @@ 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_dev(struct arm_smmu_fw_handle *handle)
 {
-	struct platform_device *smmu_pdev = of_find_device_by_node(np);
+	struct platform_device *smmu_pdev = NULL;
+
+	if (handle->type == ARM_SMMU_FW_OF) {
+		smmu_pdev = of_find_device_by_node(handle->np);
+		of_node_put(handle->np);
+	} else if (handle->type == ARM_SMMU_FW_IORT) {
+		smmu_pdev = iort_find_iommu_device(handle->iort_node);
+	}
 
 	if (!smmu_pdev)
 		return NULL;
@@ -1743,16 +1766,14 @@ static bool arm_smmu_sid_in_range(struct arm_smmu_device *smmu, u32 sid)
 
 static int arm_smmu_add_device(struct device *dev)
 {
-	struct device_node *np;
 	struct arm_smmu_device *smmu;
 	struct arm_smmu_master_data *data = dev->archdata.iommu;
 
 	if (!data)
 		return -ENODEV;
 
-	np = (struct device_node *)data->smmu;
-	smmu = data->smmu = arm_smmu_get_by_node(np);
-	of_node_put(np);
+	smmu = data->smmu = arm_smmu_get_dev(&data->handle);
+
 	if (!smmu)
 		return -ENODEV;
 
@@ -1854,7 +1875,8 @@ static int arm_smmu_of_xlate(struct device *dev, struct of_phandle_args *args)
 	 * By the time we see this again in an add_device callback, we'll
 	 * be in a position to fix it up with the real thing.
 	 */
-	data->smmu = (struct arm_smmu_device *)args->np;
+	data->handle.type = ARM_SMMU_FW_OF;
+	data->handle.np = args->np;
 	data->sid = args->args[0];
 	dev->archdata.iommu = data;
 
@@ -2688,9 +2710,31 @@ 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 arm_smmu_iort_xlate(struct device *dev, u32 streamid,
+			       struct acpi_iort_node *node)
+{
+	struct arm_smmu_master_data *data;
+
+	if (!node || (node->type != ACPI_IORT_NODE_SMMU_V3))
+		return -ENODEV;
+
+	if (dev->archdata.iommu)
+		return -EEXIST;
+
+	data = kzalloc(sizeof(*data), GFP_KERNEL);
+	if (!data)
+		return -ENOMEM;
+
+	data->handle.type = ARM_SMMU_FW_IORT;
+	data->handle.iort_node = node;
+	data->sid = streamid;
+	dev->archdata.iommu = data;
+	return 0;
+}
+
 static int acpi_smmu_init(struct acpi_iort_node *node)
 {
-	iort_smmu_set_ops(node, &arm_smmu_ops, NULL);
+	iort_smmu_set_ops(node, &arm_smmu_ops, arm_smmu_iort_xlate);
 
 	return 0;
 }
-- 
2.6.4

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

* Re: [RFC PATCH v2 13/15] drivers: acpi: iort: introduce iort_iommu_configure
  2016-06-07 13:31     ` Lorenzo Pieralisi
  (?)
@ 2016-06-10 12:46       ` Tomasz Nowicki
  -1 siblings, 0 replies; 88+ messages in thread
From: Tomasz Nowicki @ 2016-06-10 12:46 UTC (permalink / raw)
  To: Lorenzo Pieralisi, iommu
  Cc: Hanjun Guo, Rafael J. Wysocki, Will Deacon, Marc Zyngier,
	Robin Murphy, Joerg Roedel, Jon Masters, Sinan Kaya, linux-acpi,
	linux-pci, linux-kernel, linux-arm-kernel

On 07.06.2016 15:31, Lorenzo Pieralisi wrote:
> +static int __get_pci_rid(struct pci_dev *pdev, u16 alias, void *data)
> +{
> +	u32 *rid = data;
> +
> +	*rid = alias;
> +	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;
> +	const struct iort_ops_node *iort_ops;
> +	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);

I think we should find here the root bus which is connected to RC IORT node.

> +
> +		node = iort_scan_node(ACPI_IORT_NODE_PCI_ROOT_COMPLEX,
> +				      iort_find_dev_callback, &bus->dev);
> +	} else {
> +		node = iort_scan_node(ACPI_IORT_NODE_NAMED_COMPONENT,
> +				      iort_find_dev_callback, dev);
> +	}
> +
> +	if (!node)
> +		return NULL;
> +
> +	parent = iort_find_parent_node(node);
> +
> +	if (!parent)
> +		return NULL;
> +
> +	iort_ops = iort_smmu_get_ops_node(parent);
> +
> +	if (iort_ops && iort_ops->iommu_xlate) {
> +		iort_dev_map_rid(node, rid, &devid, parent->type);
> +		iort_ops->iommu_xlate(dev, devid, parent);
> +		return iort_ops->ops;
> +	}
> +
> +	return NULL;
> +}
> +

Thanks,
Tomasz

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

* Re: [RFC PATCH v2 13/15] drivers: acpi: iort: introduce iort_iommu_configure
@ 2016-06-10 12:46       ` Tomasz Nowicki
  0 siblings, 0 replies; 88+ messages in thread
From: Tomasz Nowicki @ 2016-06-10 12:46 UTC (permalink / raw)
  To: Lorenzo Pieralisi, iommu
  Cc: Marc Zyngier, Rafael J. Wysocki, Joerg Roedel, Will Deacon,
	linux-kernel, linux-pci, Sinan Kaya, linux-acpi, Hanjun Guo,
	Jon Masters, Robin Murphy, linux-arm-kernel

On 07.06.2016 15:31, Lorenzo Pieralisi wrote:
> +static int __get_pci_rid(struct pci_dev *pdev, u16 alias, void *data)
> +{
> +	u32 *rid = data;
> +
> +	*rid = alias;
> +	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;
> +	const struct iort_ops_node *iort_ops;
> +	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);

I think we should find here the root bus which is connected to RC IORT node.

> +
> +		node = iort_scan_node(ACPI_IORT_NODE_PCI_ROOT_COMPLEX,
> +				      iort_find_dev_callback, &bus->dev);
> +	} else {
> +		node = iort_scan_node(ACPI_IORT_NODE_NAMED_COMPONENT,
> +				      iort_find_dev_callback, dev);
> +	}
> +
> +	if (!node)
> +		return NULL;
> +
> +	parent = iort_find_parent_node(node);
> +
> +	if (!parent)
> +		return NULL;
> +
> +	iort_ops = iort_smmu_get_ops_node(parent);
> +
> +	if (iort_ops && iort_ops->iommu_xlate) {
> +		iort_dev_map_rid(node, rid, &devid, parent->type);
> +		iort_ops->iommu_xlate(dev, devid, parent);
> +		return iort_ops->ops;
> +	}
> +
> +	return NULL;
> +}
> +

Thanks,
Tomasz

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [RFC PATCH v2 13/15] drivers: acpi: iort: introduce iort_iommu_configure
@ 2016-06-10 12:46       ` Tomasz Nowicki
  0 siblings, 0 replies; 88+ messages in thread
From: Tomasz Nowicki @ 2016-06-10 12:46 UTC (permalink / raw)
  To: linux-arm-kernel

On 07.06.2016 15:31, Lorenzo Pieralisi wrote:
> +static int __get_pci_rid(struct pci_dev *pdev, u16 alias, void *data)
> +{
> +	u32 *rid = data;
> +
> +	*rid = alias;
> +	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;
> +	const struct iort_ops_node *iort_ops;
> +	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);

I think we should find here the root bus which is connected to RC IORT node.

> +
> +		node = iort_scan_node(ACPI_IORT_NODE_PCI_ROOT_COMPLEX,
> +				      iort_find_dev_callback, &bus->dev);
> +	} else {
> +		node = iort_scan_node(ACPI_IORT_NODE_NAMED_COMPONENT,
> +				      iort_find_dev_callback, dev);
> +	}
> +
> +	if (!node)
> +		return NULL;
> +
> +	parent = iort_find_parent_node(node);
> +
> +	if (!parent)
> +		return NULL;
> +
> +	iort_ops = iort_smmu_get_ops_node(parent);
> +
> +	if (iort_ops && iort_ops->iommu_xlate) {
> +		iort_dev_map_rid(node, rid, &devid, parent->type);
> +		iort_ops->iommu_xlate(dev, devid, parent);
> +		return iort_ops->ops;
> +	}
> +
> +	return NULL;
> +}
> +

Thanks,
Tomasz

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

* Re: [RFC PATCH v2 12/15] drivers: acpi: implement acpi_dma_configure
  2016-06-07 13:31   ` Lorenzo Pieralisi
  (?)
@ 2016-06-10 16:25       ` Bjorn Helgaas
  -1 siblings, 0 replies; 88+ messages in thread
From: Bjorn Helgaas @ 2016-06-10 16:25 UTC (permalink / raw)
  To: Lorenzo Pieralisi
  Cc: Marc Zyngier, Tomasz Nowicki, Rafael J. Wysocki,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, Will Deacon,
	linux-pci-u79uwXL29TY76Z2rM5mHXA, Sinan Kaya,
	linux-acpi-u79uwXL29TY76Z2rM5mHXA,
	iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA, Hanjun Guo,
	Jon Masters, Bjorn Helgaas,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r

On Tue, Jun 07, 2016 at 02:31:07PM +0100, Lorenzo Pieralisi wrote:
> 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-5wv7dgnIgG8@public.gmane.org>
> Cc: Bjorn Helgaas <bhelgaas-hpIqsD4AKlfQT0dZR+AlfA@public.gmane.org>
> Cc: Robin Murphy <robin.murphy-5wv7dgnIgG8@public.gmane.org>
> Cc: Tomasz Nowicki <tn-nYOzD4b6Jr9Wk0Htik3J/w@public.gmane.org>
> Cc: Joerg Roedel <joro-zLv9SwRftAIdnm+yROfE0A@public.gmane.org>
> Cc: "Rafael J. Wysocki" <rjw-LthD3rsA81gm4RdzfppkhA@public.gmane.org>

Acked-by: Bjorn Helgaas <bhelgaas-hpIqsD4AKlfQT0dZR+AlfA@public.gmane.org>

I assume this will be merged by somebody else along with the rest
of the series.

> ---
>  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 8e3ef72..01dd369 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
> 

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

* Re: [RFC PATCH v2 12/15] drivers: acpi: implement acpi_dma_configure
@ 2016-06-10 16:25       ` Bjorn Helgaas
  0 siblings, 0 replies; 88+ messages in thread
From: Bjorn Helgaas @ 2016-06-10 16:25 UTC (permalink / raw)
  To: Lorenzo Pieralisi
  Cc: iommu, Bjorn Helgaas, Robin Murphy, Tomasz Nowicki, Joerg Roedel,
	Rafael J. Wysocki, Will Deacon, Marc Zyngier, Hanjun Guo,
	Jon Masters, Sinan Kaya, linux-acpi, linux-pci, linux-kernel,
	linux-arm-kernel

On Tue, Jun 07, 2016 at 02:31:07PM +0100, Lorenzo Pieralisi wrote:
> 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>
> 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>

Acked-by: Bjorn Helgaas <bhelgaas@google.com>

I assume this will be merged by somebody else along with the rest
of the series.

> ---
>  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 8e3ef72..01dd369 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
> 

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

* [RFC PATCH v2 12/15] drivers: acpi: implement acpi_dma_configure
@ 2016-06-10 16:25       ` Bjorn Helgaas
  0 siblings, 0 replies; 88+ messages in thread
From: Bjorn Helgaas @ 2016-06-10 16:25 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Jun 07, 2016 at 02:31:07PM +0100, Lorenzo Pieralisi wrote:
> 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>
> 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>

Acked-by: Bjorn Helgaas <bhelgaas@google.com>

I assume this will be merged by somebody else along with the rest
of the series.

> ---
>  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 8e3ef72..01dd369 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
> 

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

* Re: [RFC PATCH v2 09/15] drivers: iommu: arm-smmu-v3: split probe functions into DT/generic portions
  2016-06-07 13:31     ` Lorenzo Pieralisi
@ 2016-06-14 18:09       ` Will Deacon
  -1 siblings, 0 replies; 88+ messages in thread
From: Will Deacon @ 2016-06-14 18:09 UTC (permalink / raw)
  To: Lorenzo Pieralisi
  Cc: iommu, Hanjun Guo, Robin Murphy, Joerg Roedel, Marc Zyngier,
	Rafael J. Wysocki, Tomasz Nowicki, Jon Masters, Sinan Kaya,
	linux-acpi, linux-pci, linux-kernel, linux-arm-kernel

On Tue, Jun 07, 2016 at 02:31:04PM +0100, Lorenzo Pieralisi wrote:
> 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>
> 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(-)

This looks sensible to me.

Acked-by: Will Deacon <will.deacon@arm.com>

Will

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

* [RFC PATCH v2 09/15] drivers: iommu: arm-smmu-v3: split probe functions into DT/generic portions
@ 2016-06-14 18:09       ` Will Deacon
  0 siblings, 0 replies; 88+ messages in thread
From: Will Deacon @ 2016-06-14 18:09 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Jun 07, 2016 at 02:31:04PM +0100, Lorenzo Pieralisi wrote:
> 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>
> 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(-)

This looks sensible to me.

Acked-by: Will Deacon <will.deacon@arm.com>

Will

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

* Re: [RFC PATCH v2 10/15] drivers: iommu: arm-smmu-v3: enable ACPI driver initialization
  2016-06-07 13:31     ` Lorenzo Pieralisi
@ 2016-06-14 18:12       ` Will Deacon
  -1 siblings, 0 replies; 88+ messages in thread
From: Will Deacon @ 2016-06-14 18:12 UTC (permalink / raw)
  To: Lorenzo Pieralisi
  Cc: iommu, Robin Murphy, Joerg Roedel, Marc Zyngier,
	Rafael J. Wysocki, Tomasz Nowicki, Hanjun Guo, Jon Masters,
	Sinan Kaya, linux-acpi, linux-pci, linux-kernel,
	linux-arm-kernel

On Tue, Jun 07, 2016 at 02:31:05PM +0100, Lorenzo Pieralisi wrote:
> 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>
> 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(-)

Acked-by: Will Deacon <will.deacon@arm.com>

Will

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

* [RFC PATCH v2 10/15] drivers: iommu: arm-smmu-v3: enable ACPI driver initialization
@ 2016-06-14 18:12       ` Will Deacon
  0 siblings, 0 replies; 88+ messages in thread
From: Will Deacon @ 2016-06-14 18:12 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Jun 07, 2016 at 02:31:05PM +0100, Lorenzo Pieralisi wrote:
> 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>
> 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(-)

Acked-by: Will Deacon <will.deacon@arm.com>

Will

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

* Re: [RFC PATCH v2 11/15] drivers: iommu: arm-smmu-v3: add IORT iommu configuration
  2016-06-07 13:31   ` Lorenzo Pieralisi
@ 2016-06-14 18:39     ` Will Deacon
  -1 siblings, 0 replies; 88+ messages in thread
From: Will Deacon @ 2016-06-14 18:39 UTC (permalink / raw)
  To: Lorenzo Pieralisi
  Cc: iommu, Robin Murphy, Joerg Roedel, Marc Zyngier,
	Rafael J. Wysocki, Tomasz Nowicki, Hanjun Guo, Jon Masters,
	Sinan Kaya, linux-acpi, linux-pci, linux-kernel,
	linux-arm-kernel

On Tue, Jun 07, 2016 at 02:31:06PM +0100, 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
> infrastructure requires ARM SMMU drivers to initialize a set of
> operations that are used by the IORT kernel layer to configure platform
> devices for ARM SMMU components in turn.
> 
> This patch adds the IORT IOMMU configuration for the ARM SMMU v3 kernel
> driver.
> 
> 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/iommu/arm-smmu-v3.c | 101 ++++++++++++++++++++++++++++++++++++++++++++
>  include/linux/iort.h        |  12 +++++-
>  2 files changed, 112 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/iommu/arm-smmu-v3.c b/drivers/iommu/arm-smmu-v3.c
> index 90745a8..7acb6b5 100644
> --- a/drivers/iommu/arm-smmu-v3.c
> +++ b/drivers/iommu/arm-smmu-v3.c
> @@ -2687,6 +2687,107 @@ 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_init(struct acpi_iort_node *node)
> +{
> +	iort_smmu_set_ops(node, &arm_smmu_ops, NULL);
> +
> +	return 0;
> +}
> +
> +static void acpi_smmu_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_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_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_register_irq(smmu->event_gsiv, "eventq",
> +				       &res[num_res++]);
> +
> +	if (smmu->pri_gsiv)
> +		acpi_smmu_register_irq(smmu->pri_gsiv, "priq",
> +				       &res[num_res++]);
> +
> +	if (smmu->gerr_gsiv)
> +		acpi_smmu_register_irq(smmu->gerr_gsiv, "gerror",
> +				       &res[num_res++]);
> +
> +	if (smmu->sync_gsiv)
> +		acpi_smmu_register_irq(smmu->sync_gsiv, "cmdq-sync",
> +				       &res[num_res++]);
> +}
> +
> +static bool arm_smmu_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;
> +}
> +
> +const struct iort_iommu_config iort_arm_smmu_v3_cfg = {
> +	.name = "arm-smmu-v3",
> +	.iommu_init = acpi_smmu_init,
> +	.iommu_is_coherent = arm_smmu_is_coherent,
> +	.iommu_count_resources = arm_smmu_count_resources,
> +	.iommu_init_resources = arm_smmu_init_resources
> +};
> +#endif
> +
>  MODULE_DESCRIPTION("IOMMU API for ARM architected SMMUv3 implementations");
>  MODULE_AUTHOR("Will Deacon <will.deacon@arm.com>");
>  MODULE_LICENSE("GPL v2");
> diff --git a/include/linux/iort.h b/include/linux/iort.h
> index ced3054..5dcfa09 100644
> --- a/include/linux/iort.h
> +++ b/include/linux/iort.h
> @@ -55,7 +55,17 @@ struct iort_iommu_config {
>  static inline const struct iort_iommu_config *
>  iort_get_iommu_config(struct acpi_iort_node *node)
>  {
> -	return NULL;
> +	switch (node->type) {
> +#if IS_ENABLED(CONFIG_ARM_SMMU_V3)
> +	case ACPI_IORT_NODE_SMMU_V3: {
> +		extern const struct iort_iommu_config iort_arm_smmu_v3_cfg;
> +
> +		return &iort_arm_smmu_v3_cfg;
> +	}
> +#endif

Oh, yuck! I really don't like this mixture of SMMU driver code and IORT
code over two files using a global structure of largely stateless function
pointers.

I think you have two options:

  (1) Move this all into iort.c (my preference)
  (2) Introduce something like SMMU_ACPI_DECLARE which allows drivers to
      register a callback if they're matched in the IORT.

that at least keeps internal data in one place, rather than spreading it
around.

Cheers,

Will

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

* [RFC PATCH v2 11/15] drivers: iommu: arm-smmu-v3: add IORT iommu configuration
@ 2016-06-14 18:39     ` Will Deacon
  0 siblings, 0 replies; 88+ messages in thread
From: Will Deacon @ 2016-06-14 18:39 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Jun 07, 2016 at 02:31:06PM +0100, 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
> infrastructure requires ARM SMMU drivers to initialize a set of
> operations that are used by the IORT kernel layer to configure platform
> devices for ARM SMMU components in turn.
> 
> This patch adds the IORT IOMMU configuration for the ARM SMMU v3 kernel
> driver.
> 
> 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/iommu/arm-smmu-v3.c | 101 ++++++++++++++++++++++++++++++++++++++++++++
>  include/linux/iort.h        |  12 +++++-
>  2 files changed, 112 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/iommu/arm-smmu-v3.c b/drivers/iommu/arm-smmu-v3.c
> index 90745a8..7acb6b5 100644
> --- a/drivers/iommu/arm-smmu-v3.c
> +++ b/drivers/iommu/arm-smmu-v3.c
> @@ -2687,6 +2687,107 @@ 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_init(struct acpi_iort_node *node)
> +{
> +	iort_smmu_set_ops(node, &arm_smmu_ops, NULL);
> +
> +	return 0;
> +}
> +
> +static void acpi_smmu_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_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_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_register_irq(smmu->event_gsiv, "eventq",
> +				       &res[num_res++]);
> +
> +	if (smmu->pri_gsiv)
> +		acpi_smmu_register_irq(smmu->pri_gsiv, "priq",
> +				       &res[num_res++]);
> +
> +	if (smmu->gerr_gsiv)
> +		acpi_smmu_register_irq(smmu->gerr_gsiv, "gerror",
> +				       &res[num_res++]);
> +
> +	if (smmu->sync_gsiv)
> +		acpi_smmu_register_irq(smmu->sync_gsiv, "cmdq-sync",
> +				       &res[num_res++]);
> +}
> +
> +static bool arm_smmu_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;
> +}
> +
> +const struct iort_iommu_config iort_arm_smmu_v3_cfg = {
> +	.name = "arm-smmu-v3",
> +	.iommu_init = acpi_smmu_init,
> +	.iommu_is_coherent = arm_smmu_is_coherent,
> +	.iommu_count_resources = arm_smmu_count_resources,
> +	.iommu_init_resources = arm_smmu_init_resources
> +};
> +#endif
> +
>  MODULE_DESCRIPTION("IOMMU API for ARM architected SMMUv3 implementations");
>  MODULE_AUTHOR("Will Deacon <will.deacon@arm.com>");
>  MODULE_LICENSE("GPL v2");
> diff --git a/include/linux/iort.h b/include/linux/iort.h
> index ced3054..5dcfa09 100644
> --- a/include/linux/iort.h
> +++ b/include/linux/iort.h
> @@ -55,7 +55,17 @@ struct iort_iommu_config {
>  static inline const struct iort_iommu_config *
>  iort_get_iommu_config(struct acpi_iort_node *node)
>  {
> -	return NULL;
> +	switch (node->type) {
> +#if IS_ENABLED(CONFIG_ARM_SMMU_V3)
> +	case ACPI_IORT_NODE_SMMU_V3: {
> +		extern const struct iort_iommu_config iort_arm_smmu_v3_cfg;
> +
> +		return &iort_arm_smmu_v3_cfg;
> +	}
> +#endif

Oh, yuck! I really don't like this mixture of SMMU driver code and IORT
code over two files using a global structure of largely stateless function
pointers.

I think you have two options:

  (1) Move this all into iort.c (my preference)
  (2) Introduce something like SMMU_ACPI_DECLARE which allows drivers to
      register a callback if they're matched in the IORT.

that at least keeps internal data in one place, rather than spreading it
around.

Cheers,

Will

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

* Re: [RFC PATCH v2 11/15] drivers: iommu: arm-smmu-v3: add IORT iommu configuration
  2016-06-14 18:39     ` Will Deacon
  (?)
@ 2016-06-15  8:52         ` Lorenzo Pieralisi
  -1 siblings, 0 replies; 88+ messages in thread
From: Lorenzo Pieralisi @ 2016-06-15  8:52 UTC (permalink / raw)
  To: Will Deacon
  Cc: Marc Zyngier, Tomasz Nowicki, Rafael J. Wysocki,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-pci-u79uwXL29TY76Z2rM5mHXA, Sinan Kaya,
	linux-acpi-u79uwXL29TY76Z2rM5mHXA,
	iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA, Hanjun Guo,
	Jon Masters, linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r

On Tue, Jun 14, 2016 at 07:39:39PM +0100, Will Deacon wrote:
> On Tue, Jun 07, 2016 at 02:31:06PM +0100, 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
> > infrastructure requires ARM SMMU drivers to initialize a set of
> > operations that are used by the IORT kernel layer to configure platform
> > devices for ARM SMMU components in turn.
> > 
> > This patch adds the IORT IOMMU configuration for the ARM SMMU v3 kernel
> > driver.
> > 
> > Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi-5wv7dgnIgG8@public.gmane.org>
> > Cc: Will Deacon <will.deacon-5wv7dgnIgG8@public.gmane.org>
> > Cc: Robin Murphy <robin.murphy-5wv7dgnIgG8@public.gmane.org>
> > Cc: Joerg Roedel <joro-zLv9SwRftAIdnm+yROfE0A@public.gmane.org>
> > ---
> >  drivers/iommu/arm-smmu-v3.c | 101 ++++++++++++++++++++++++++++++++++++++++++++
> >  include/linux/iort.h        |  12 +++++-
> >  2 files changed, 112 insertions(+), 1 deletion(-)
> > 
> > diff --git a/drivers/iommu/arm-smmu-v3.c b/drivers/iommu/arm-smmu-v3.c
> > index 90745a8..7acb6b5 100644
> > --- a/drivers/iommu/arm-smmu-v3.c
> > +++ b/drivers/iommu/arm-smmu-v3.c
> > @@ -2687,6 +2687,107 @@ 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_init(struct acpi_iort_node *node)
> > +{
> > +	iort_smmu_set_ops(node, &arm_smmu_ops, NULL);
> > +
> > +	return 0;
> > +}
> > +
> > +static void acpi_smmu_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_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_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_register_irq(smmu->event_gsiv, "eventq",
> > +				       &res[num_res++]);
> > +
> > +	if (smmu->pri_gsiv)
> > +		acpi_smmu_register_irq(smmu->pri_gsiv, "priq",
> > +				       &res[num_res++]);
> > +
> > +	if (smmu->gerr_gsiv)
> > +		acpi_smmu_register_irq(smmu->gerr_gsiv, "gerror",
> > +				       &res[num_res++]);
> > +
> > +	if (smmu->sync_gsiv)
> > +		acpi_smmu_register_irq(smmu->sync_gsiv, "cmdq-sync",
> > +				       &res[num_res++]);
> > +}
> > +
> > +static bool arm_smmu_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;
> > +}
> > +
> > +const struct iort_iommu_config iort_arm_smmu_v3_cfg = {
> > +	.name = "arm-smmu-v3",
> > +	.iommu_init = acpi_smmu_init,
> > +	.iommu_is_coherent = arm_smmu_is_coherent,
> > +	.iommu_count_resources = arm_smmu_count_resources,
> > +	.iommu_init_resources = arm_smmu_init_resources
> > +};
> > +#endif
> > +
> >  MODULE_DESCRIPTION("IOMMU API for ARM architected SMMUv3 implementations");
> >  MODULE_AUTHOR("Will Deacon <will.deacon-5wv7dgnIgG8@public.gmane.org>");
> >  MODULE_LICENSE("GPL v2");
> > diff --git a/include/linux/iort.h b/include/linux/iort.h
> > index ced3054..5dcfa09 100644
> > --- a/include/linux/iort.h
> > +++ b/include/linux/iort.h
> > @@ -55,7 +55,17 @@ struct iort_iommu_config {
> >  static inline const struct iort_iommu_config *
> >  iort_get_iommu_config(struct acpi_iort_node *node)
> >  {
> > -	return NULL;
> > +	switch (node->type) {
> > +#if IS_ENABLED(CONFIG_ARM_SMMU_V3)
> > +	case ACPI_IORT_NODE_SMMU_V3: {
> > +		extern const struct iort_iommu_config iort_arm_smmu_v3_cfg;
> > +
> > +		return &iort_arm_smmu_v3_cfg;
> > +	}
> > +#endif
> 
> Oh, yuck! I really don't like this mixture of SMMU driver code and IORT
> code over two files using a global structure of largely stateless function
> pointers.
> 
> I think you have two options:
> 
>   (1) Move this all into iort.c (my preference)
>   (2) Introduce something like SMMU_ACPI_DECLARE which allows drivers to
>       register a callback if they're matched in the IORT.
> 
> that at least keeps internal data in one place, rather than spreading it
> around.

(1) is possible for most of the function pointers. Problem is that iort.c
has to know ARM SMMU v3 driver internals (driver name for platform
device matching and IRQ resources names - I wanted to keep the ARM SMMU
v3 probing routine as FW agnostic as possible), it is obviously doable
but I have to make sure I keep them in sync.

We still need (2) to have an IOMMU_OF_DECLARE() equivalent (ie to
make sure that we can carry out the of_xlate() equivalent when
devices are probed), I did not want to add a linker script section
for two components (ARM SMMUv1/v2 and v3) but that's doable too,
I will make changes for v3.

Thanks for having a look !

Lorenzo

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

* Re: [RFC PATCH v2 11/15] drivers: iommu: arm-smmu-v3: add IORT iommu configuration
@ 2016-06-15  8:52         ` Lorenzo Pieralisi
  0 siblings, 0 replies; 88+ messages in thread
From: Lorenzo Pieralisi @ 2016-06-15  8:52 UTC (permalink / raw)
  To: Will Deacon
  Cc: iommu, Robin Murphy, Joerg Roedel, Marc Zyngier,
	Rafael J. Wysocki, Tomasz Nowicki, Hanjun Guo, Jon Masters,
	Sinan Kaya, linux-acpi, linux-pci, linux-kernel,
	linux-arm-kernel

On Tue, Jun 14, 2016 at 07:39:39PM +0100, Will Deacon wrote:
> On Tue, Jun 07, 2016 at 02:31:06PM +0100, 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
> > infrastructure requires ARM SMMU drivers to initialize a set of
> > operations that are used by the IORT kernel layer to configure platform
> > devices for ARM SMMU components in turn.
> > 
> > This patch adds the IORT IOMMU configuration for the ARM SMMU v3 kernel
> > driver.
> > 
> > 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/iommu/arm-smmu-v3.c | 101 ++++++++++++++++++++++++++++++++++++++++++++
> >  include/linux/iort.h        |  12 +++++-
> >  2 files changed, 112 insertions(+), 1 deletion(-)
> > 
> > diff --git a/drivers/iommu/arm-smmu-v3.c b/drivers/iommu/arm-smmu-v3.c
> > index 90745a8..7acb6b5 100644
> > --- a/drivers/iommu/arm-smmu-v3.c
> > +++ b/drivers/iommu/arm-smmu-v3.c
> > @@ -2687,6 +2687,107 @@ 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_init(struct acpi_iort_node *node)
> > +{
> > +	iort_smmu_set_ops(node, &arm_smmu_ops, NULL);
> > +
> > +	return 0;
> > +}
> > +
> > +static void acpi_smmu_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_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_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_register_irq(smmu->event_gsiv, "eventq",
> > +				       &res[num_res++]);
> > +
> > +	if (smmu->pri_gsiv)
> > +		acpi_smmu_register_irq(smmu->pri_gsiv, "priq",
> > +				       &res[num_res++]);
> > +
> > +	if (smmu->gerr_gsiv)
> > +		acpi_smmu_register_irq(smmu->gerr_gsiv, "gerror",
> > +				       &res[num_res++]);
> > +
> > +	if (smmu->sync_gsiv)
> > +		acpi_smmu_register_irq(smmu->sync_gsiv, "cmdq-sync",
> > +				       &res[num_res++]);
> > +}
> > +
> > +static bool arm_smmu_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;
> > +}
> > +
> > +const struct iort_iommu_config iort_arm_smmu_v3_cfg = {
> > +	.name = "arm-smmu-v3",
> > +	.iommu_init = acpi_smmu_init,
> > +	.iommu_is_coherent = arm_smmu_is_coherent,
> > +	.iommu_count_resources = arm_smmu_count_resources,
> > +	.iommu_init_resources = arm_smmu_init_resources
> > +};
> > +#endif
> > +
> >  MODULE_DESCRIPTION("IOMMU API for ARM architected SMMUv3 implementations");
> >  MODULE_AUTHOR("Will Deacon <will.deacon@arm.com>");
> >  MODULE_LICENSE("GPL v2");
> > diff --git a/include/linux/iort.h b/include/linux/iort.h
> > index ced3054..5dcfa09 100644
> > --- a/include/linux/iort.h
> > +++ b/include/linux/iort.h
> > @@ -55,7 +55,17 @@ struct iort_iommu_config {
> >  static inline const struct iort_iommu_config *
> >  iort_get_iommu_config(struct acpi_iort_node *node)
> >  {
> > -	return NULL;
> > +	switch (node->type) {
> > +#if IS_ENABLED(CONFIG_ARM_SMMU_V3)
> > +	case ACPI_IORT_NODE_SMMU_V3: {
> > +		extern const struct iort_iommu_config iort_arm_smmu_v3_cfg;
> > +
> > +		return &iort_arm_smmu_v3_cfg;
> > +	}
> > +#endif
> 
> Oh, yuck! I really don't like this mixture of SMMU driver code and IORT
> code over two files using a global structure of largely stateless function
> pointers.
> 
> I think you have two options:
> 
>   (1) Move this all into iort.c (my preference)
>   (2) Introduce something like SMMU_ACPI_DECLARE which allows drivers to
>       register a callback if they're matched in the IORT.
> 
> that at least keeps internal data in one place, rather than spreading it
> around.

(1) is possible for most of the function pointers. Problem is that iort.c
has to know ARM SMMU v3 driver internals (driver name for platform
device matching and IRQ resources names - I wanted to keep the ARM SMMU
v3 probing routine as FW agnostic as possible), it is obviously doable
but I have to make sure I keep them in sync.

We still need (2) to have an IOMMU_OF_DECLARE() equivalent (ie to
make sure that we can carry out the of_xlate() equivalent when
devices are probed), I did not want to add a linker script section
for two components (ARM SMMUv1/v2 and v3) but that's doable too,
I will make changes for v3.

Thanks for having a look !

Lorenzo

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

* [RFC PATCH v2 11/15] drivers: iommu: arm-smmu-v3: add IORT iommu configuration
@ 2016-06-15  8:52         ` Lorenzo Pieralisi
  0 siblings, 0 replies; 88+ messages in thread
From: Lorenzo Pieralisi @ 2016-06-15  8:52 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Jun 14, 2016 at 07:39:39PM +0100, Will Deacon wrote:
> On Tue, Jun 07, 2016 at 02:31:06PM +0100, 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
> > infrastructure requires ARM SMMU drivers to initialize a set of
> > operations that are used by the IORT kernel layer to configure platform
> > devices for ARM SMMU components in turn.
> > 
> > This patch adds the IORT IOMMU configuration for the ARM SMMU v3 kernel
> > driver.
> > 
> > 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/iommu/arm-smmu-v3.c | 101 ++++++++++++++++++++++++++++++++++++++++++++
> >  include/linux/iort.h        |  12 +++++-
> >  2 files changed, 112 insertions(+), 1 deletion(-)
> > 
> > diff --git a/drivers/iommu/arm-smmu-v3.c b/drivers/iommu/arm-smmu-v3.c
> > index 90745a8..7acb6b5 100644
> > --- a/drivers/iommu/arm-smmu-v3.c
> > +++ b/drivers/iommu/arm-smmu-v3.c
> > @@ -2687,6 +2687,107 @@ 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_init(struct acpi_iort_node *node)
> > +{
> > +	iort_smmu_set_ops(node, &arm_smmu_ops, NULL);
> > +
> > +	return 0;
> > +}
> > +
> > +static void acpi_smmu_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_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_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_register_irq(smmu->event_gsiv, "eventq",
> > +				       &res[num_res++]);
> > +
> > +	if (smmu->pri_gsiv)
> > +		acpi_smmu_register_irq(smmu->pri_gsiv, "priq",
> > +				       &res[num_res++]);
> > +
> > +	if (smmu->gerr_gsiv)
> > +		acpi_smmu_register_irq(smmu->gerr_gsiv, "gerror",
> > +				       &res[num_res++]);
> > +
> > +	if (smmu->sync_gsiv)
> > +		acpi_smmu_register_irq(smmu->sync_gsiv, "cmdq-sync",
> > +				       &res[num_res++]);
> > +}
> > +
> > +static bool arm_smmu_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;
> > +}
> > +
> > +const struct iort_iommu_config iort_arm_smmu_v3_cfg = {
> > +	.name = "arm-smmu-v3",
> > +	.iommu_init = acpi_smmu_init,
> > +	.iommu_is_coherent = arm_smmu_is_coherent,
> > +	.iommu_count_resources = arm_smmu_count_resources,
> > +	.iommu_init_resources = arm_smmu_init_resources
> > +};
> > +#endif
> > +
> >  MODULE_DESCRIPTION("IOMMU API for ARM architected SMMUv3 implementations");
> >  MODULE_AUTHOR("Will Deacon <will.deacon@arm.com>");
> >  MODULE_LICENSE("GPL v2");
> > diff --git a/include/linux/iort.h b/include/linux/iort.h
> > index ced3054..5dcfa09 100644
> > --- a/include/linux/iort.h
> > +++ b/include/linux/iort.h
> > @@ -55,7 +55,17 @@ struct iort_iommu_config {
> >  static inline const struct iort_iommu_config *
> >  iort_get_iommu_config(struct acpi_iort_node *node)
> >  {
> > -	return NULL;
> > +	switch (node->type) {
> > +#if IS_ENABLED(CONFIG_ARM_SMMU_V3)
> > +	case ACPI_IORT_NODE_SMMU_V3: {
> > +		extern const struct iort_iommu_config iort_arm_smmu_v3_cfg;
> > +
> > +		return &iort_arm_smmu_v3_cfg;
> > +	}
> > +#endif
> 
> Oh, yuck! I really don't like this mixture of SMMU driver code and IORT
> code over two files using a global structure of largely stateless function
> pointers.
> 
> I think you have two options:
> 
>   (1) Move this all into iort.c (my preference)
>   (2) Introduce something like SMMU_ACPI_DECLARE which allows drivers to
>       register a callback if they're matched in the IORT.
> 
> that at least keeps internal data in one place, rather than spreading it
> around.

(1) is possible for most of the function pointers. Problem is that iort.c
has to know ARM SMMU v3 driver internals (driver name for platform
device matching and IRQ resources names - I wanted to keep the ARM SMMU
v3 probing routine as FW agnostic as possible), it is obviously doable
but I have to make sure I keep them in sync.

We still need (2) to have an IOMMU_OF_DECLARE() equivalent (ie to
make sure that we can carry out the of_xlate() equivalent when
devices are probed), I did not want to add a linker script section
for two components (ARM SMMUv1/v2 and v3) but that's doable too,
I will make changes for v3.

Thanks for having a look !

Lorenzo

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

* Re: [RFC PATCH v2 03/15] arm64: mm: change IOMMU notifier action to attach DMA ops
  2016-06-07 13:30     ` Lorenzo Pieralisi
@ 2016-06-17  9:27       ` Robin Murphy
  -1 siblings, 0 replies; 88+ messages in thread
From: Robin Murphy @ 2016-06-17  9:27 UTC (permalink / raw)
  To: Lorenzo Pieralisi, iommu, Marek Szyprowski
  Cc: linux-arm-kernel, Rafael J. Wysocki, Marc Zyngier,
	Catalin Marinas, Joerg Roedel, Will Deacon, linux-kernel,
	linux-pci, Sinan Kaya, linux-acpi, Hanjun Guo, Tomasz Nowicki,
	Jon Masters

Hi Lorenzo,

I think this patch makes sense even independent of the rest of the 
series, one nit inline notwithstanding.

Marek; I'm curious as to whether this could make the workaround in 
722ec35f7 obsolete as well, or are all the drivers also bound 
super-early in the setup you had there?

On 07/06/16 14:30, Lorenzo Pieralisi wrote:
> Current bus notifier in ARM64 (__iommu_attach_notifier)
> attempts to attach dma_ops to a device on BUS_NOTIFY_ADD_DEVICE
> action notification.
>
> This causes issues on ACPI based systems, where PCI devices
> can be added before the IOMMUs the devices are attached to
> had a chance to be probed, causing failures on attempts to
> attach dma_ops in that the domain for the respective IOMMU
> may not be set-up yet by the time the bus notifier is run.
>
> Devices dma_ops do not require to be set-up till the matching
> device drivers are probed. This means that instead of running
> the notifier attaching dma_ops to devices (__iommu_attach_notifier)
> on BUS_NOTIFY_ADD_DEVICE action, it can be run just before the
> device driver is bound to the device in question (on action
> BUS_NOTIFY_BIND_DRIVER) so that it is certain that its IOMMU
> group and domain are set-up accordingly at the time the
> notifier is triggered.
>
> This patch changes the notifier action upon which dma_ops
> are attached to devices and defer it to driver binding time,
> so that IOMMU devices have a chance to be probed and to register
> their bus notifiers before the dma_ops attach sequence for a
> device is actually carried out.
>
> Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
> Cc: Will Deacon <will.deacon@arm.com>
> Cc: Catalin Marinas <catalin.marinas@arm.com>
> Cc: Robin Murphy <robin.murphy@arm.com>
> ---
>   arch/arm64/mm/dma-mapping.c | 2 +-
>   1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/arch/arm64/mm/dma-mapping.c b/arch/arm64/mm/dma-mapping.c
> index c566ec8..79b0882 100644
> --- a/arch/arm64/mm/dma-mapping.c
> +++ b/arch/arm64/mm/dma-mapping.c
> @@ -848,7 +848,7 @@ static int __iommu_attach_notifier(struct notifier_block *nb,
>   {
>   	struct iommu_dma_notifier_data *master, *tmp;
>
> -	if (action != BUS_NOTIFY_ADD_DEVICE)
> +	if (action != BUS_NOTIFY_BIND_DRIVER)

With this, you can also get rid of the priority setting and big fat 
explanatory comment in register_iommu_dma_ops_notifier().

Robin.

>   		return 0;
>
>   	mutex_lock(&iommu_dma_notifier_lock);
>


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

* [RFC PATCH v2 03/15] arm64: mm: change IOMMU notifier action to attach DMA ops
@ 2016-06-17  9:27       ` Robin Murphy
  0 siblings, 0 replies; 88+ messages in thread
From: Robin Murphy @ 2016-06-17  9:27 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Lorenzo,

I think this patch makes sense even independent of the rest of the 
series, one nit inline notwithstanding.

Marek; I'm curious as to whether this could make the workaround in 
722ec35f7 obsolete as well, or are all the drivers also bound 
super-early in the setup you had there?

On 07/06/16 14:30, Lorenzo Pieralisi wrote:
> Current bus notifier in ARM64 (__iommu_attach_notifier)
> attempts to attach dma_ops to a device on BUS_NOTIFY_ADD_DEVICE
> action notification.
>
> This causes issues on ACPI based systems, where PCI devices
> can be added before the IOMMUs the devices are attached to
> had a chance to be probed, causing failures on attempts to
> attach dma_ops in that the domain for the respective IOMMU
> may not be set-up yet by the time the bus notifier is run.
>
> Devices dma_ops do not require to be set-up till the matching
> device drivers are probed. This means that instead of running
> the notifier attaching dma_ops to devices (__iommu_attach_notifier)
> on BUS_NOTIFY_ADD_DEVICE action, it can be run just before the
> device driver is bound to the device in question (on action
> BUS_NOTIFY_BIND_DRIVER) so that it is certain that its IOMMU
> group and domain are set-up accordingly at the time the
> notifier is triggered.
>
> This patch changes the notifier action upon which dma_ops
> are attached to devices and defer it to driver binding time,
> so that IOMMU devices have a chance to be probed and to register
> their bus notifiers before the dma_ops attach sequence for a
> device is actually carried out.
>
> Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
> Cc: Will Deacon <will.deacon@arm.com>
> Cc: Catalin Marinas <catalin.marinas@arm.com>
> Cc: Robin Murphy <robin.murphy@arm.com>
> ---
>   arch/arm64/mm/dma-mapping.c | 2 +-
>   1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/arch/arm64/mm/dma-mapping.c b/arch/arm64/mm/dma-mapping.c
> index c566ec8..79b0882 100644
> --- a/arch/arm64/mm/dma-mapping.c
> +++ b/arch/arm64/mm/dma-mapping.c
> @@ -848,7 +848,7 @@ static int __iommu_attach_notifier(struct notifier_block *nb,
>   {
>   	struct iommu_dma_notifier_data *master, *tmp;
>
> -	if (action != BUS_NOTIFY_ADD_DEVICE)
> +	if (action != BUS_NOTIFY_BIND_DRIVER)

With this, you can also get rid of the priority setting and big fat 
explanatory comment in register_iommu_dma_ops_notifier().

Robin.

>   		return 0;
>
>   	mutex_lock(&iommu_dma_notifier_lock);
>

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

* Re: [RFC PATCH v2 03/15] arm64: mm: change IOMMU notifier action to attach DMA ops
  2016-06-17  9:27       ` Robin Murphy
  (?)
@ 2016-06-17 14:15           ` Lorenzo Pieralisi
  -1 siblings, 0 replies; 88+ messages in thread
From: Lorenzo Pieralisi @ 2016-06-17 14:15 UTC (permalink / raw)
  To: Robin Murphy
  Cc: Jon Masters, Marc Zyngier, Catalin Marinas, Rafael J. Wysocki,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, Will Deacon, Sinan Kaya,
	linux-acpi-u79uwXL29TY76Z2rM5mHXA,
	iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA, Hanjun Guo,
	linux-pci-u79uwXL29TY76Z2rM5mHXA, Tomasz Nowicki,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r

Hi Robin,

On Fri, Jun 17, 2016 at 10:27:22AM +0100, Robin Murphy wrote:
> Hi Lorenzo,
> 
> I think this patch makes sense even independent of the rest of the
> series, one nit inline notwithstanding.

Thanks. Yes I added it to this series since it is not strictly
necessary (ie it does not fix anything) in the mainline, but
it *is* necessary for this whole series to function when we
boot through ACPI.

I will send it out in a separate patch and fold changes you
request below, it would be good to have some coverage for
it before merging it.

Thank you !
Lorenzo

> Marek; I'm curious as to whether this could make the workaround in
> 722ec35f7 obsolete as well, or are all the drivers also bound
> super-early in the setup you had there?
> 
> On 07/06/16 14:30, Lorenzo Pieralisi wrote:
> >Current bus notifier in ARM64 (__iommu_attach_notifier)
> >attempts to attach dma_ops to a device on BUS_NOTIFY_ADD_DEVICE
> >action notification.
> >
> >This causes issues on ACPI based systems, where PCI devices
> >can be added before the IOMMUs the devices are attached to
> >had a chance to be probed, causing failures on attempts to
> >attach dma_ops in that the domain for the respective IOMMU
> >may not be set-up yet by the time the bus notifier is run.
> >
> >Devices dma_ops do not require to be set-up till the matching
> >device drivers are probed. This means that instead of running
> >the notifier attaching dma_ops to devices (__iommu_attach_notifier)
> >on BUS_NOTIFY_ADD_DEVICE action, it can be run just before the
> >device driver is bound to the device in question (on action
> >BUS_NOTIFY_BIND_DRIVER) so that it is certain that its IOMMU
> >group and domain are set-up accordingly at the time the
> >notifier is triggered.
> >
> >This patch changes the notifier action upon which dma_ops
> >are attached to devices and defer it to driver binding time,
> >so that IOMMU devices have a chance to be probed and to register
> >their bus notifiers before the dma_ops attach sequence for a
> >device is actually carried out.
> >
> >Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi-5wv7dgnIgG8@public.gmane.org>
> >Cc: Will Deacon <will.deacon-5wv7dgnIgG8@public.gmane.org>
> >Cc: Catalin Marinas <catalin.marinas-5wv7dgnIgG8@public.gmane.org>
> >Cc: Robin Murphy <robin.murphy-5wv7dgnIgG8@public.gmane.org>
> >---
> >  arch/arm64/mm/dma-mapping.c | 2 +-
> >  1 file changed, 1 insertion(+), 1 deletion(-)
> >
> >diff --git a/arch/arm64/mm/dma-mapping.c b/arch/arm64/mm/dma-mapping.c
> >index c566ec8..79b0882 100644
> >--- a/arch/arm64/mm/dma-mapping.c
> >+++ b/arch/arm64/mm/dma-mapping.c
> >@@ -848,7 +848,7 @@ static int __iommu_attach_notifier(struct notifier_block *nb,
> >  {
> >  	struct iommu_dma_notifier_data *master, *tmp;
> >
> >-	if (action != BUS_NOTIFY_ADD_DEVICE)
> >+	if (action != BUS_NOTIFY_BIND_DRIVER)
> 
> With this, you can also get rid of the priority setting and big fat
> explanatory comment in register_iommu_dma_ops_notifier().
> 
> Robin.
> 
> >  		return 0;
> >
> >  	mutex_lock(&iommu_dma_notifier_lock);
> >
> 

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

* Re: [RFC PATCH v2 03/15] arm64: mm: change IOMMU notifier action to attach DMA ops
@ 2016-06-17 14:15           ` Lorenzo Pieralisi
  0 siblings, 0 replies; 88+ messages in thread
From: Lorenzo Pieralisi @ 2016-06-17 14:15 UTC (permalink / raw)
  To: Robin Murphy
  Cc: iommu, Marek Szyprowski, linux-arm-kernel, Rafael J. Wysocki,
	Marc Zyngier, Catalin Marinas, Joerg Roedel, Will Deacon,
	linux-kernel, linux-pci, Sinan Kaya, linux-acpi, Hanjun Guo,
	Tomasz Nowicki, Jon Masters

Hi Robin,

On Fri, Jun 17, 2016 at 10:27:22AM +0100, Robin Murphy wrote:
> Hi Lorenzo,
> 
> I think this patch makes sense even independent of the rest of the
> series, one nit inline notwithstanding.

Thanks. Yes I added it to this series since it is not strictly
necessary (ie it does not fix anything) in the mainline, but
it *is* necessary for this whole series to function when we
boot through ACPI.

I will send it out in a separate patch and fold changes you
request below, it would be good to have some coverage for
it before merging it.

Thank you !
Lorenzo

> Marek; I'm curious as to whether this could make the workaround in
> 722ec35f7 obsolete as well, or are all the drivers also bound
> super-early in the setup you had there?
> 
> On 07/06/16 14:30, Lorenzo Pieralisi wrote:
> >Current bus notifier in ARM64 (__iommu_attach_notifier)
> >attempts to attach dma_ops to a device on BUS_NOTIFY_ADD_DEVICE
> >action notification.
> >
> >This causes issues on ACPI based systems, where PCI devices
> >can be added before the IOMMUs the devices are attached to
> >had a chance to be probed, causing failures on attempts to
> >attach dma_ops in that the domain for the respective IOMMU
> >may not be set-up yet by the time the bus notifier is run.
> >
> >Devices dma_ops do not require to be set-up till the matching
> >device drivers are probed. This means that instead of running
> >the notifier attaching dma_ops to devices (__iommu_attach_notifier)
> >on BUS_NOTIFY_ADD_DEVICE action, it can be run just before the
> >device driver is bound to the device in question (on action
> >BUS_NOTIFY_BIND_DRIVER) so that it is certain that its IOMMU
> >group and domain are set-up accordingly at the time the
> >notifier is triggered.
> >
> >This patch changes the notifier action upon which dma_ops
> >are attached to devices and defer it to driver binding time,
> >so that IOMMU devices have a chance to be probed and to register
> >their bus notifiers before the dma_ops attach sequence for a
> >device is actually carried out.
> >
> >Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
> >Cc: Will Deacon <will.deacon@arm.com>
> >Cc: Catalin Marinas <catalin.marinas@arm.com>
> >Cc: Robin Murphy <robin.murphy@arm.com>
> >---
> >  arch/arm64/mm/dma-mapping.c | 2 +-
> >  1 file changed, 1 insertion(+), 1 deletion(-)
> >
> >diff --git a/arch/arm64/mm/dma-mapping.c b/arch/arm64/mm/dma-mapping.c
> >index c566ec8..79b0882 100644
> >--- a/arch/arm64/mm/dma-mapping.c
> >+++ b/arch/arm64/mm/dma-mapping.c
> >@@ -848,7 +848,7 @@ static int __iommu_attach_notifier(struct notifier_block *nb,
> >  {
> >  	struct iommu_dma_notifier_data *master, *tmp;
> >
> >-	if (action != BUS_NOTIFY_ADD_DEVICE)
> >+	if (action != BUS_NOTIFY_BIND_DRIVER)
> 
> With this, you can also get rid of the priority setting and big fat
> explanatory comment in register_iommu_dma_ops_notifier().
> 
> Robin.
> 
> >  		return 0;
> >
> >  	mutex_lock(&iommu_dma_notifier_lock);
> >
> 

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

* [RFC PATCH v2 03/15] arm64: mm: change IOMMU notifier action to attach DMA ops
@ 2016-06-17 14:15           ` Lorenzo Pieralisi
  0 siblings, 0 replies; 88+ messages in thread
From: Lorenzo Pieralisi @ 2016-06-17 14:15 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Robin,

On Fri, Jun 17, 2016 at 10:27:22AM +0100, Robin Murphy wrote:
> Hi Lorenzo,
> 
> I think this patch makes sense even independent of the rest of the
> series, one nit inline notwithstanding.

Thanks. Yes I added it to this series since it is not strictly
necessary (ie it does not fix anything) in the mainline, but
it *is* necessary for this whole series to function when we
boot through ACPI.

I will send it out in a separate patch and fold changes you
request below, it would be good to have some coverage for
it before merging it.

Thank you !
Lorenzo

> Marek; I'm curious as to whether this could make the workaround in
> 722ec35f7 obsolete as well, or are all the drivers also bound
> super-early in the setup you had there?
> 
> On 07/06/16 14:30, Lorenzo Pieralisi wrote:
> >Current bus notifier in ARM64 (__iommu_attach_notifier)
> >attempts to attach dma_ops to a device on BUS_NOTIFY_ADD_DEVICE
> >action notification.
> >
> >This causes issues on ACPI based systems, where PCI devices
> >can be added before the IOMMUs the devices are attached to
> >had a chance to be probed, causing failures on attempts to
> >attach dma_ops in that the domain for the respective IOMMU
> >may not be set-up yet by the time the bus notifier is run.
> >
> >Devices dma_ops do not require to be set-up till the matching
> >device drivers are probed. This means that instead of running
> >the notifier attaching dma_ops to devices (__iommu_attach_notifier)
> >on BUS_NOTIFY_ADD_DEVICE action, it can be run just before the
> >device driver is bound to the device in question (on action
> >BUS_NOTIFY_BIND_DRIVER) so that it is certain that its IOMMU
> >group and domain are set-up accordingly at the time the
> >notifier is triggered.
> >
> >This patch changes the notifier action upon which dma_ops
> >are attached to devices and defer it to driver binding time,
> >so that IOMMU devices have a chance to be probed and to register
> >their bus notifiers before the dma_ops attach sequence for a
> >device is actually carried out.
> >
> >Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
> >Cc: Will Deacon <will.deacon@arm.com>
> >Cc: Catalin Marinas <catalin.marinas@arm.com>
> >Cc: Robin Murphy <robin.murphy@arm.com>
> >---
> >  arch/arm64/mm/dma-mapping.c | 2 +-
> >  1 file changed, 1 insertion(+), 1 deletion(-)
> >
> >diff --git a/arch/arm64/mm/dma-mapping.c b/arch/arm64/mm/dma-mapping.c
> >index c566ec8..79b0882 100644
> >--- a/arch/arm64/mm/dma-mapping.c
> >+++ b/arch/arm64/mm/dma-mapping.c
> >@@ -848,7 +848,7 @@ static int __iommu_attach_notifier(struct notifier_block *nb,
> >  {
> >  	struct iommu_dma_notifier_data *master, *tmp;
> >
> >-	if (action != BUS_NOTIFY_ADD_DEVICE)
> >+	if (action != BUS_NOTIFY_BIND_DRIVER)
> 
> With this, you can also get rid of the priority setting and big fat
> explanatory comment in register_iommu_dma_ops_notifier().
> 
> Robin.
> 
> >  		return 0;
> >
> >  	mutex_lock(&iommu_dma_notifier_lock);
> >
> 

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

* Re: [RFC PATCH v2 03/15] arm64: mm: change IOMMU notifier action to attach DMA ops
  2016-06-17  9:27       ` Robin Murphy
  (?)
  (?)
@ 2016-06-21  7:53           ` Marek Szyprowski
  -1 siblings, 0 replies; 88+ messages in thread
From: Marek Szyprowski @ 2016-06-21  7:53 UTC (permalink / raw)
  To: Robin Murphy, Lorenzo Pieralisi,
	iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA
  Cc: Jon Masters, Marc Zyngier, Catalin Marinas, Rafael J. Wysocki,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, Will Deacon, Sinan Kaya,
	linux-acpi-u79uwXL29TY76Z2rM5mHXA, Hanjun Guo,
	linux-pci-u79uwXL29TY76Z2rM5mHXA, Tomasz Nowicki,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r

Hi Robin,


On 2016-06-17 11:27, Robin Murphy wrote:
> Hi Lorenzo,
>
> I think this patch makes sense even independent of the rest of the 
> series, one nit inline notwithstanding.
>
> Marek; I'm curious as to whether this could make the workaround in 
> 722ec35f7 obsolete as well, or are all the drivers also bound 
> super-early in the setup you had there?

Yes, this will solve that problem too. I will also hide some possible
deferred probe issues, because the moment at which IOMMU is activated
will be postponed. The only drawback with this approach is the fact
that is drivers won't be allowed to do any dma-mapping operations on
devices, which they don't own. This should not be a big issue, but
this was the reason to setup IOMMU on device add instead of driver
bind.

While at it, please make sure that the case of failed client driver
probe will be handled properly. IOMMU might do some operations while
setting up and if the client driver fails to probe (for whatever
reason, might be a deferred probe too), those operation has to be
undone. However the current code of the driver core won't call any
notifier (like BUS_NOTIFY_UNBOUND_DRIVER or whatever else) in such
case.

Long time ago I used BUS_NOTIFY_BIND_DRIVER based approach for my
Exynos IOMMU patches and had to extend bus core with such patch:
https://patchwork.kernel.org/patch/4678181/ to properly cleanup
after failed client driver probe and avoid leaking resources. Please
read the discussion, because some changes were requested to it.


Best regards
Marek Szyprowski, PhD
Samsung R&D Institute Poland

>
> On 07/06/16 14:30, Lorenzo Pieralisi wrote:
>> Current bus notifier in ARM64 (__iommu_attach_notifier)
>> attempts to attach dma_ops to a device on BUS_NOTIFY_ADD_DEVICE
>> action notification.
>>
>> This causes issues on ACPI based systems, where PCI devices
>> can be added before the IOMMUs the devices are attached to
>> had a chance to be probed, causing failures on attempts to
>> attach dma_ops in that the domain for the respective IOMMU
>> may not be set-up yet by the time the bus notifier is run.
>>
>> Devices dma_ops do not require to be set-up till the matching
>> device drivers are probed. This means that instead of running
>> the notifier attaching dma_ops to devices (__iommu_attach_notifier)
>> on BUS_NOTIFY_ADD_DEVICE action, it can be run just before the
>> device driver is bound to the device in question (on action
>> BUS_NOTIFY_BIND_DRIVER) so that it is certain that its IOMMU
>> group and domain are set-up accordingly at the time the
>> notifier is triggered.
>>
>> This patch changes the notifier action upon which dma_ops
>> are attached to devices and defer it to driver binding time,
>> so that IOMMU devices have a chance to be probed and to register
>> their bus notifiers before the dma_ops attach sequence for a
>> device is actually carried out.
>>
>> Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi-5wv7dgnIgG8@public.gmane.org>
>> Cc: Will Deacon <will.deacon-5wv7dgnIgG8@public.gmane.org>
>> Cc: Catalin Marinas <catalin.marinas-5wv7dgnIgG8@public.gmane.org>
>> Cc: Robin Murphy <robin.murphy-5wv7dgnIgG8@public.gmane.org>
>> ---
>>   arch/arm64/mm/dma-mapping.c | 2 +-
>>   1 file changed, 1 insertion(+), 1 deletion(-)
>>
>> diff --git a/arch/arm64/mm/dma-mapping.c b/arch/arm64/mm/dma-mapping.c
>> index c566ec8..79b0882 100644
>> --- a/arch/arm64/mm/dma-mapping.c
>> +++ b/arch/arm64/mm/dma-mapping.c
>> @@ -848,7 +848,7 @@ static int __iommu_attach_notifier(struct 
>> notifier_block *nb,
>>   {
>>       struct iommu_dma_notifier_data *master, *tmp;
>>
>> -    if (action != BUS_NOTIFY_ADD_DEVICE)
>> +    if (action != BUS_NOTIFY_BIND_DRIVER)
>
> With this, you can also get rid of the priority setting and big fat 
> explanatory comment in register_iommu_dma_ops_notifier().
>
> Robin.
>
>>           return 0;
>>
>>       mutex_lock(&iommu_dma_notifier_lock);
>>
>
>
>

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

* Re: [RFC PATCH v2 03/15] arm64: mm: change IOMMU notifier action to attach DMA ops
@ 2016-06-21  7:53           ` Marek Szyprowski
  0 siblings, 0 replies; 88+ messages in thread
From: Marek Szyprowski @ 2016-06-21  7:53 UTC (permalink / raw)
  To: Robin Murphy, Lorenzo Pieralisi, iommu
  Cc: linux-arm-kernel, Rafael J. Wysocki, Marc Zyngier,
	Catalin Marinas, Joerg Roedel, Will Deacon, linux-kernel,
	linux-pci, Sinan Kaya, linux-acpi, Hanjun Guo, Tomasz Nowicki,
	Jon Masters

Hi Robin,


On 2016-06-17 11:27, Robin Murphy wrote:
> Hi Lorenzo,
>
> I think this patch makes sense even independent of the rest of the 
> series, one nit inline notwithstanding.
>
> Marek; I'm curious as to whether this could make the workaround in 
> 722ec35f7 obsolete as well, or are all the drivers also bound 
> super-early in the setup you had there?

Yes, this will solve that problem too. I will also hide some possible
deferred probe issues, because the moment at which IOMMU is activated
will be postponed. The only drawback with this approach is the fact
that is drivers won't be allowed to do any dma-mapping operations on
devices, which they don't own. This should not be a big issue, but
this was the reason to setup IOMMU on device add instead of driver
bind.

While at it, please make sure that the case of failed client driver
probe will be handled properly. IOMMU might do some operations while
setting up and if the client driver fails to probe (for whatever
reason, might be a deferred probe too), those operation has to be
undone. However the current code of the driver core won't call any
notifier (like BUS_NOTIFY_UNBOUND_DRIVER or whatever else) in such
case.

Long time ago I used BUS_NOTIFY_BIND_DRIVER based approach for my
Exynos IOMMU patches and had to extend bus core with such patch:
https://patchwork.kernel.org/patch/4678181/ to properly cleanup
after failed client driver probe and avoid leaking resources. Please
read the discussion, because some changes were requested to it.


Best regards
Marek Szyprowski, PhD
Samsung R&D Institute Poland

>
> On 07/06/16 14:30, Lorenzo Pieralisi wrote:
>> Current bus notifier in ARM64 (__iommu_attach_notifier)
>> attempts to attach dma_ops to a device on BUS_NOTIFY_ADD_DEVICE
>> action notification.
>>
>> This causes issues on ACPI based systems, where PCI devices
>> can be added before the IOMMUs the devices are attached to
>> had a chance to be probed, causing failures on attempts to
>> attach dma_ops in that the domain for the respective IOMMU
>> may not be set-up yet by the time the bus notifier is run.
>>
>> Devices dma_ops do not require to be set-up till the matching
>> device drivers are probed. This means that instead of running
>> the notifier attaching dma_ops to devices (__iommu_attach_notifier)
>> on BUS_NOTIFY_ADD_DEVICE action, it can be run just before the
>> device driver is bound to the device in question (on action
>> BUS_NOTIFY_BIND_DRIVER) so that it is certain that its IOMMU
>> group and domain are set-up accordingly at the time the
>> notifier is triggered.
>>
>> This patch changes the notifier action upon which dma_ops
>> are attached to devices and defer it to driver binding time,
>> so that IOMMU devices have a chance to be probed and to register
>> their bus notifiers before the dma_ops attach sequence for a
>> device is actually carried out.
>>
>> Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
>> Cc: Will Deacon <will.deacon@arm.com>
>> Cc: Catalin Marinas <catalin.marinas@arm.com>
>> Cc: Robin Murphy <robin.murphy@arm.com>
>> ---
>>   arch/arm64/mm/dma-mapping.c | 2 +-
>>   1 file changed, 1 insertion(+), 1 deletion(-)
>>
>> diff --git a/arch/arm64/mm/dma-mapping.c b/arch/arm64/mm/dma-mapping.c
>> index c566ec8..79b0882 100644
>> --- a/arch/arm64/mm/dma-mapping.c
>> +++ b/arch/arm64/mm/dma-mapping.c
>> @@ -848,7 +848,7 @@ static int __iommu_attach_notifier(struct 
>> notifier_block *nb,
>>   {
>>       struct iommu_dma_notifier_data *master, *tmp;
>>
>> -    if (action != BUS_NOTIFY_ADD_DEVICE)
>> +    if (action != BUS_NOTIFY_BIND_DRIVER)
>
> With this, you can also get rid of the priority setting and big fat 
> explanatory comment in register_iommu_dma_ops_notifier().
>
> Robin.
>
>>           return 0;
>>
>>       mutex_lock(&iommu_dma_notifier_lock);
>>
>
>
>

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

* Re: [RFC PATCH v2 03/15] arm64: mm: change IOMMU notifier action to attach DMA ops
@ 2016-06-21  7:53           ` Marek Szyprowski
  0 siblings, 0 replies; 88+ messages in thread
From: Marek Szyprowski @ 2016-06-21  7:53 UTC (permalink / raw)
  To: Robin Murphy, Lorenzo Pieralisi, iommu
  Cc: Jon Masters, Marc Zyngier, Catalin Marinas, Joerg Roedel,
	Rafael J. Wysocki, linux-kernel, Will Deacon, Sinan Kaya,
	linux-acpi, Hanjun Guo, linux-pci, Tomasz Nowicki,
	linux-arm-kernel

Hi Robin,


On 2016-06-17 11:27, Robin Murphy wrote:
> Hi Lorenzo,
>
> I think this patch makes sense even independent of the rest of the 
> series, one nit inline notwithstanding.
>
> Marek; I'm curious as to whether this could make the workaround in 
> 722ec35f7 obsolete as well, or are all the drivers also bound 
> super-early in the setup you had there?

Yes, this will solve that problem too. I will also hide some possible
deferred probe issues, because the moment at which IOMMU is activated
will be postponed. The only drawback with this approach is the fact
that is drivers won't be allowed to do any dma-mapping operations on
devices, which they don't own. This should not be a big issue, but
this was the reason to setup IOMMU on device add instead of driver
bind.

While at it, please make sure that the case of failed client driver
probe will be handled properly. IOMMU might do some operations while
setting up and if the client driver fails to probe (for whatever
reason, might be a deferred probe too), those operation has to be
undone. However the current code of the driver core won't call any
notifier (like BUS_NOTIFY_UNBOUND_DRIVER or whatever else) in such
case.

Long time ago I used BUS_NOTIFY_BIND_DRIVER based approach for my
Exynos IOMMU patches and had to extend bus core with such patch:
https://patchwork.kernel.org/patch/4678181/ to properly cleanup
after failed client driver probe and avoid leaking resources. Please
read the discussion, because some changes were requested to it.


Best regards
Marek Szyprowski, PhD
Samsung R&D Institute Poland

>
> On 07/06/16 14:30, Lorenzo Pieralisi wrote:
>> Current bus notifier in ARM64 (__iommu_attach_notifier)
>> attempts to attach dma_ops to a device on BUS_NOTIFY_ADD_DEVICE
>> action notification.
>>
>> This causes issues on ACPI based systems, where PCI devices
>> can be added before the IOMMUs the devices are attached to
>> had a chance to be probed, causing failures on attempts to
>> attach dma_ops in that the domain for the respective IOMMU
>> may not be set-up yet by the time the bus notifier is run.
>>
>> Devices dma_ops do not require to be set-up till the matching
>> device drivers are probed. This means that instead of running
>> the notifier attaching dma_ops to devices (__iommu_attach_notifier)
>> on BUS_NOTIFY_ADD_DEVICE action, it can be run just before the
>> device driver is bound to the device in question (on action
>> BUS_NOTIFY_BIND_DRIVER) so that it is certain that its IOMMU
>> group and domain are set-up accordingly at the time the
>> notifier is triggered.
>>
>> This patch changes the notifier action upon which dma_ops
>> are attached to devices and defer it to driver binding time,
>> so that IOMMU devices have a chance to be probed and to register
>> their bus notifiers before the dma_ops attach sequence for a
>> device is actually carried out.
>>
>> Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
>> Cc: Will Deacon <will.deacon@arm.com>
>> Cc: Catalin Marinas <catalin.marinas@arm.com>
>> Cc: Robin Murphy <robin.murphy@arm.com>
>> ---
>>   arch/arm64/mm/dma-mapping.c | 2 +-
>>   1 file changed, 1 insertion(+), 1 deletion(-)
>>
>> diff --git a/arch/arm64/mm/dma-mapping.c b/arch/arm64/mm/dma-mapping.c
>> index c566ec8..79b0882 100644
>> --- a/arch/arm64/mm/dma-mapping.c
>> +++ b/arch/arm64/mm/dma-mapping.c
>> @@ -848,7 +848,7 @@ static int __iommu_attach_notifier(struct 
>> notifier_block *nb,
>>   {
>>       struct iommu_dma_notifier_data *master, *tmp;
>>
>> -    if (action != BUS_NOTIFY_ADD_DEVICE)
>> +    if (action != BUS_NOTIFY_BIND_DRIVER)
>
> With this, you can also get rid of the priority setting and big fat 
> explanatory comment in register_iommu_dma_ops_notifier().
>
> Robin.
>
>>           return 0;
>>
>>       mutex_lock(&iommu_dma_notifier_lock);
>>
>
>
>


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [RFC PATCH v2 03/15] arm64: mm: change IOMMU notifier action to attach DMA ops
@ 2016-06-21  7:53           ` Marek Szyprowski
  0 siblings, 0 replies; 88+ messages in thread
From: Marek Szyprowski @ 2016-06-21  7:53 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Robin,


On 2016-06-17 11:27, Robin Murphy wrote:
> Hi Lorenzo,
>
> I think this patch makes sense even independent of the rest of the 
> series, one nit inline notwithstanding.
>
> Marek; I'm curious as to whether this could make the workaround in 
> 722ec35f7 obsolete as well, or are all the drivers also bound 
> super-early in the setup you had there?

Yes, this will solve that problem too. I will also hide some possible
deferred probe issues, because the moment at which IOMMU is activated
will be postponed. The only drawback with this approach is the fact
that is drivers won't be allowed to do any dma-mapping operations on
devices, which they don't own. This should not be a big issue, but
this was the reason to setup IOMMU on device add instead of driver
bind.

While at it, please make sure that the case of failed client driver
probe will be handled properly. IOMMU might do some operations while
setting up and if the client driver fails to probe (for whatever
reason, might be a deferred probe too), those operation has to be
undone. However the current code of the driver core won't call any
notifier (like BUS_NOTIFY_UNBOUND_DRIVER or whatever else) in such
case.

Long time ago I used BUS_NOTIFY_BIND_DRIVER based approach for my
Exynos IOMMU patches and had to extend bus core with such patch:
https://patchwork.kernel.org/patch/4678181/ to properly cleanup
after failed client driver probe and avoid leaking resources. Please
read the discussion, because some changes were requested to it.


Best regards
Marek Szyprowski, PhD
Samsung R&D Institute Poland

>
> On 07/06/16 14:30, Lorenzo Pieralisi wrote:
>> Current bus notifier in ARM64 (__iommu_attach_notifier)
>> attempts to attach dma_ops to a device on BUS_NOTIFY_ADD_DEVICE
>> action notification.
>>
>> This causes issues on ACPI based systems, where PCI devices
>> can be added before the IOMMUs the devices are attached to
>> had a chance to be probed, causing failures on attempts to
>> attach dma_ops in that the domain for the respective IOMMU
>> may not be set-up yet by the time the bus notifier is run.
>>
>> Devices dma_ops do not require to be set-up till the matching
>> device drivers are probed. This means that instead of running
>> the notifier attaching dma_ops to devices (__iommu_attach_notifier)
>> on BUS_NOTIFY_ADD_DEVICE action, it can be run just before the
>> device driver is bound to the device in question (on action
>> BUS_NOTIFY_BIND_DRIVER) so that it is certain that its IOMMU
>> group and domain are set-up accordingly at the time the
>> notifier is triggered.
>>
>> This patch changes the notifier action upon which dma_ops
>> are attached to devices and defer it to driver binding time,
>> so that IOMMU devices have a chance to be probed and to register
>> their bus notifiers before the dma_ops attach sequence for a
>> device is actually carried out.
>>
>> Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
>> Cc: Will Deacon <will.deacon@arm.com>
>> Cc: Catalin Marinas <catalin.marinas@arm.com>
>> Cc: Robin Murphy <robin.murphy@arm.com>
>> ---
>>   arch/arm64/mm/dma-mapping.c | 2 +-
>>   1 file changed, 1 insertion(+), 1 deletion(-)
>>
>> diff --git a/arch/arm64/mm/dma-mapping.c b/arch/arm64/mm/dma-mapping.c
>> index c566ec8..79b0882 100644
>> --- a/arch/arm64/mm/dma-mapping.c
>> +++ b/arch/arm64/mm/dma-mapping.c
>> @@ -848,7 +848,7 @@ static int __iommu_attach_notifier(struct 
>> notifier_block *nb,
>>   {
>>       struct iommu_dma_notifier_data *master, *tmp;
>>
>> -    if (action != BUS_NOTIFY_ADD_DEVICE)
>> +    if (action != BUS_NOTIFY_BIND_DRIVER)
>
> With this, you can also get rid of the priority setting and big fat 
> explanatory comment in register_iommu_dma_ops_notifier().
>
> Robin.
>
>>           return 0;
>>
>>       mutex_lock(&iommu_dma_notifier_lock);
>>
>
>
>

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

* Re: [RFC PATCH v2 00/15] ACPI IORT ARM SMMU v3 support
  2016-06-07 13:30 ` Lorenzo Pieralisi
  (?)
@ 2016-06-21 10:37   ` Hanjun Guo
  -1 siblings, 0 replies; 88+ messages in thread
From: Hanjun Guo @ 2016-06-21 10:37 UTC (permalink / raw)
  To: Lorenzo Pieralisi, iommu
  Cc: Rafael J. Wysocki, Marc Zyngier, Tomasz Nowicki, Joerg Roedel,
	Will Deacon, linux-kernel, linux-pci, linuxarm, Sinan Kaya,
	linux-acpi, Jon Masters, Robin Murphy, linux-arm-kernel

Hi Lorenzo,

On 2016/6/7 21:30, Lorenzo Pieralisi wrote:
> This RFC patch series is v2 of a previous posting:
>
> https://lkml.org/lkml/2016/4/14/702
>
> 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.

I'm trying to test your patches on D03 (SMMUv3 based) but ...

[...]
> [1] R.Murphy "Generic DT bindings for PCI and ARM SMMU v3"
>     http://marc.info/?l=linux-arm-kernel&m=146497432413816&w=2

...This patch set is still in discussion and seems not work
for non-PCI devices.

>
> [2] T.Nowicki "Introduce ACPI world to ITS irqchip" v5
>     http://marc.info/?l=linux-acpi&m=146469369703684&w=2

Tomasz sent out the v7 and included patches in your series.

I think a updated version before the test makes sense, what
do you think? Let me know your thoughts.

Thanks
Hanjun

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

* Re: [RFC PATCH v2 00/15] ACPI IORT ARM SMMU v3 support
@ 2016-06-21 10:37   ` Hanjun Guo
  0 siblings, 0 replies; 88+ messages in thread
From: Hanjun Guo @ 2016-06-21 10:37 UTC (permalink / raw)
  To: Lorenzo Pieralisi, iommu
  Cc: Will Deacon, Marc Zyngier, Robin Murphy, Joerg Roedel,
	Rafael J. Wysocki, Tomasz Nowicki, Jon Masters, Sinan Kaya,
	linux-acpi, linux-pci, linux-kernel, linux-arm-kernel, linuxarm

Hi Lorenzo,

On 2016/6/7 21:30, Lorenzo Pieralisi wrote:
> This RFC patch series is v2 of a previous posting:
>
> https://lkml.org/lkml/2016/4/14/702
>
> 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.

I'm trying to test your patches on D03 (SMMUv3 based) but ...

[...]
> [1] R.Murphy "Generic DT bindings for PCI and ARM SMMU v3"
>     http://marc.info/?l=linux-arm-kernel&m=146497432413816&w=2

...This patch set is still in discussion and seems not work
for non-PCI devices.

>
> [2] T.Nowicki "Introduce ACPI world to ITS irqchip" v5
>     http://marc.info/?l=linux-acpi&m=146469369703684&w=2

Tomasz sent out the v7 and included patches in your series.

I think a updated version before the test makes sense, what
do you think? Let me know your thoughts.

Thanks
Hanjun

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

* [RFC PATCH v2 00/15] ACPI IORT ARM SMMU v3 support
@ 2016-06-21 10:37   ` Hanjun Guo
  0 siblings, 0 replies; 88+ messages in thread
From: Hanjun Guo @ 2016-06-21 10:37 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Lorenzo,

On 2016/6/7 21:30, Lorenzo Pieralisi wrote:
> This RFC patch series is v2 of a previous posting:
>
> https://lkml.org/lkml/2016/4/14/702
>
> 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.

I'm trying to test your patches on D03 (SMMUv3 based) but ...

[...]
> [1] R.Murphy "Generic DT bindings for PCI and ARM SMMU v3"
>     http://marc.info/?l=linux-arm-kernel&m=146497432413816&w=2

...This patch set is still in discussion and seems not work
for non-PCI devices.

>
> [2] T.Nowicki "Introduce ACPI world to ITS irqchip" v5
>     http://marc.info/?l=linux-acpi&m=146469369703684&w=2

Tomasz sent out the v7 and included patches in your series.

I think a updated version before the test makes sense, what
do you think? Let me know your thoughts.

Thanks
Hanjun

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

* Re: [RFC PATCH v2 00/15] ACPI IORT ARM SMMU v3 support
  2016-06-21 10:37   ` Hanjun Guo
  (?)
  (?)
@ 2016-06-21 14:27       ` Lorenzo Pieralisi
  -1 siblings, 0 replies; 88+ messages in thread
From: Lorenzo Pieralisi @ 2016-06-21 14:27 UTC (permalink / raw)
  To: Hanjun Guo
  Cc: Marc Zyngier, Rafael J. Wysocki, Will Deacon,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-pci-u79uwXL29TY76Z2rM5mHXA,
	linuxarm-hv44wF8Li93QT0dZR+AlfA, Sinan Kaya,
	linux-acpi-u79uwXL29TY76Z2rM5mHXA,
	iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	Tomasz Nowicki, Jon Masters

Hi Hanjun,

On Tue, Jun 21, 2016 at 06:37:17PM +0800, Hanjun Guo wrote:
> Hi Lorenzo,
> 
> On 2016/6/7 21:30, Lorenzo Pieralisi wrote:
> >This RFC patch series is v2 of a previous posting:
> >
> >https://lkml.org/lkml/2016/4/14/702
> >
> >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.
> 
> I'm trying to test your patches on D03 (SMMUv3 based) but ...

What do you mean by "I am trying.." :), have you actually tested
this series ?

> [...]
> >[1] R.Murphy "Generic DT bindings for PCI and ARM SMMU v3"
> >    http://marc.info/?l=linux-arm-kernel&m=146497432413816&w=2
> 
> ...This patch set is still in discussion and seems not work
> for non-PCI devices.

Can you be more specific please ? Yes, both series are work
in progress.

> >[2] T.Nowicki "Introduce ACPI world to ITS irqchip" v5
> >    http://marc.info/?l=linux-acpi&m=146469369703684&w=2
> 
> Tomasz sent out the v7 and included patches in your series.
> 
> I think a updated version before the test makes sense, what
> do you think? Let me know your thoughts.

I am working with Robin so that the xlate() mechanism works
properly and seamlessly for both DT and ACPI, given the
dependencies I think it makes more sense to wait for Tomasz
and Robin patches to get merged or at least stabilize before
doing anything else, I am curently working on a v3.

Thanks,
Lorenzo

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

* Re: [RFC PATCH v2 00/15] ACPI IORT ARM SMMU v3 support
@ 2016-06-21 14:27       ` Lorenzo Pieralisi
  0 siblings, 0 replies; 88+ messages in thread
From: Lorenzo Pieralisi @ 2016-06-21 14:27 UTC (permalink / raw)
  To: Hanjun Guo
  Cc: iommu, Will Deacon, Marc Zyngier, Robin Murphy, Joerg Roedel,
	Rafael J. Wysocki, Tomasz Nowicki, Jon Masters, Sinan Kaya,
	linux-acpi, linux-pci, linux-kernel, linux-arm-kernel, linuxarm

Hi Hanjun,

On Tue, Jun 21, 2016 at 06:37:17PM +0800, Hanjun Guo wrote:
> Hi Lorenzo,
> 
> On 2016/6/7 21:30, Lorenzo Pieralisi wrote:
> >This RFC patch series is v2 of a previous posting:
> >
> >https://lkml.org/lkml/2016/4/14/702
> >
> >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.
> 
> I'm trying to test your patches on D03 (SMMUv3 based) but ...

What do you mean by "I am trying.." :), have you actually tested
this series ?

> [...]
> >[1] R.Murphy "Generic DT bindings for PCI and ARM SMMU v3"
> >    http://marc.info/?l=linux-arm-kernel&m=146497432413816&w=2
> 
> ...This patch set is still in discussion and seems not work
> for non-PCI devices.

Can you be more specific please ? Yes, both series are work
in progress.

> >[2] T.Nowicki "Introduce ACPI world to ITS irqchip" v5
> >    http://marc.info/?l=linux-acpi&m=146469369703684&w=2
> 
> Tomasz sent out the v7 and included patches in your series.
> 
> I think a updated version before the test makes sense, what
> do you think? Let me know your thoughts.

I am working with Robin so that the xlate() mechanism works
properly and seamlessly for both DT and ACPI, given the
dependencies I think it makes more sense to wait for Tomasz
and Robin patches to get merged or at least stabilize before
doing anything else, I am curently working on a v3.

Thanks,
Lorenzo

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

* Re: [RFC PATCH v2 00/15] ACPI IORT ARM SMMU v3 support
@ 2016-06-21 14:27       ` Lorenzo Pieralisi
  0 siblings, 0 replies; 88+ messages in thread
From: Lorenzo Pieralisi @ 2016-06-21 14:27 UTC (permalink / raw)
  To: Hanjun Guo
  Cc: Marc Zyngier, Rafael J. Wysocki, Joerg Roedel, Will Deacon,
	linux-kernel, linux-pci, linuxarm, Sinan Kaya, linux-acpi, iommu,
	linux-arm-kernel, Tomasz Nowicki, Robin Murphy, Jon Masters

Hi Hanjun,

On Tue, Jun 21, 2016 at 06:37:17PM +0800, Hanjun Guo wrote:
> Hi Lorenzo,
> 
> On 2016/6/7 21:30, Lorenzo Pieralisi wrote:
> >This RFC patch series is v2 of a previous posting:
> >
> >https://lkml.org/lkml/2016/4/14/702
> >
> >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.
> 
> I'm trying to test your patches on D03 (SMMUv3 based) but ...

What do you mean by "I am trying.." :), have you actually tested
this series ?

> [...]
> >[1] R.Murphy "Generic DT bindings for PCI and ARM SMMU v3"
> >    http://marc.info/?l=linux-arm-kernel&m=146497432413816&w=2
> 
> ...This patch set is still in discussion and seems not work
> for non-PCI devices.

Can you be more specific please ? Yes, both series are work
in progress.

> >[2] T.Nowicki "Introduce ACPI world to ITS irqchip" v5
> >    http://marc.info/?l=linux-acpi&m=146469369703684&w=2
> 
> Tomasz sent out the v7 and included patches in your series.
> 
> I think a updated version before the test makes sense, what
> do you think? Let me know your thoughts.

I am working with Robin so that the xlate() mechanism works
properly and seamlessly for both DT and ACPI, given the
dependencies I think it makes more sense to wait for Tomasz
and Robin patches to get merged or at least stabilize before
doing anything else, I am curently working on a v3.

Thanks,
Lorenzo

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [RFC PATCH v2 00/15] ACPI IORT ARM SMMU v3 support
@ 2016-06-21 14:27       ` Lorenzo Pieralisi
  0 siblings, 0 replies; 88+ messages in thread
From: Lorenzo Pieralisi @ 2016-06-21 14:27 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Hanjun,

On Tue, Jun 21, 2016 at 06:37:17PM +0800, Hanjun Guo wrote:
> Hi Lorenzo,
> 
> On 2016/6/7 21:30, Lorenzo Pieralisi wrote:
> >This RFC patch series is v2 of a previous posting:
> >
> >https://lkml.org/lkml/2016/4/14/702
> >
> >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.
> 
> I'm trying to test your patches on D03 (SMMUv3 based) but ...

What do you mean by "I am trying.." :), have you actually tested
this series ?

> [...]
> >[1] R.Murphy "Generic DT bindings for PCI and ARM SMMU v3"
> >    http://marc.info/?l=linux-arm-kernel&m=146497432413816&w=2
> 
> ...This patch set is still in discussion and seems not work
> for non-PCI devices.

Can you be more specific please ? Yes, both series are work
in progress.

> >[2] T.Nowicki "Introduce ACPI world to ITS irqchip" v5
> >    http://marc.info/?l=linux-acpi&m=146469369703684&w=2
> 
> Tomasz sent out the v7 and included patches in your series.
> 
> I think a updated version before the test makes sense, what
> do you think? Let me know your thoughts.

I am working with Robin so that the xlate() mechanism works
properly and seamlessly for both DT and ACPI, given the
dependencies I think it makes more sense to wait for Tomasz
and Robin patches to get merged or at least stabilize before
doing anything else, I am curently working on a v3.

Thanks,
Lorenzo

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

* Re: [RFC PATCH v2 03/15] arm64: mm: change IOMMU notifier action to attach DMA ops
  2016-06-21  7:53           ` Marek Szyprowski
  (?)
  (?)
@ 2016-06-21 16:06               ` Lorenzo Pieralisi
  -1 siblings, 0 replies; 88+ messages in thread
From: Lorenzo Pieralisi @ 2016-06-21 16:06 UTC (permalink / raw)
  To: Marek Szyprowski
  Cc: Jon Masters, Marc Zyngier, Catalin Marinas, Rafael J. Wysocki,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, Will Deacon, Sinan Kaya,
	linux-acpi-u79uwXL29TY76Z2rM5mHXA,
	iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA, Hanjun Guo,
	linux-pci-u79uwXL29TY76Z2rM5mHXA, Tomasz Nowicki,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r

Hi Marek,

On Tue, Jun 21, 2016 at 09:53:20AM +0200, Marek Szyprowski wrote:
> Hi Robin,
> 
> 
> On 2016-06-17 11:27, Robin Murphy wrote:
> >Hi Lorenzo,
> >
> >I think this patch makes sense even independent of the rest of the
> >series, one nit inline notwithstanding.
> >
> >Marek; I'm curious as to whether this could make the workaround in
> >722ec35f7 obsolete as well, or are all the drivers also bound
> >super-early in the setup you had there?
> 
> Yes, this will solve that problem too. I will also hide some possible
> deferred probe issues, because the moment at which IOMMU is activated
> will be postponed. The only drawback with this approach is the fact
> that is drivers won't be allowed to do any dma-mapping operations on
> devices, which they don't own. This should not be a big issue, but
> this was the reason to setup IOMMU on device add instead of driver
> bind.
> 
> While at it, please make sure that the case of failed client driver
> probe will be handled properly. IOMMU might do some operations while
> setting up and if the client driver fails to probe (for whatever
> reason, might be a deferred probe too), those operation has to be
> undone. However the current code of the driver core won't call any
> notifier (like BUS_NOTIFY_UNBOUND_DRIVER or whatever else) in such
> case.

Isn't Andy's commit 14b6257a5f3d enough ? Is that what you had in
mind ?

> Long time ago I used BUS_NOTIFY_BIND_DRIVER based approach for my
> Exynos IOMMU patches and had to extend bus core with such patch:
> https://patchwork.kernel.org/patch/4678181/ to properly cleanup
> after failed client driver probe and avoid leaking resources. Please
> read the discussion, because some changes were requested to it.

It looks like commit 14b6257a5f3d ("device core: add
BUS_NOTIFY_DRIVER_NOT_BOUND notification") does what you
are requesting, please let me know if that's enough.

I will revert the changes in 722ec35f7 and fold them in the
new version along with Robin's suggestions.

Thanks,
Lorenzo

> 
> 
> Best regards
> Marek Szyprowski, PhD
> Samsung R&D Institute Poland
> 
> >
> >On 07/06/16 14:30, Lorenzo Pieralisi wrote:
> >>Current bus notifier in ARM64 (__iommu_attach_notifier)
> >>attempts to attach dma_ops to a device on BUS_NOTIFY_ADD_DEVICE
> >>action notification.
> >>
> >>This causes issues on ACPI based systems, where PCI devices
> >>can be added before the IOMMUs the devices are attached to
> >>had a chance to be probed, causing failures on attempts to
> >>attach dma_ops in that the domain for the respective IOMMU
> >>may not be set-up yet by the time the bus notifier is run.
> >>
> >>Devices dma_ops do not require to be set-up till the matching
> >>device drivers are probed. This means that instead of running
> >>the notifier attaching dma_ops to devices (__iommu_attach_notifier)
> >>on BUS_NOTIFY_ADD_DEVICE action, it can be run just before the
> >>device driver is bound to the device in question (on action
> >>BUS_NOTIFY_BIND_DRIVER) so that it is certain that its IOMMU
> >>group and domain are set-up accordingly at the time the
> >>notifier is triggered.
> >>
> >>This patch changes the notifier action upon which dma_ops
> >>are attached to devices and defer it to driver binding time,
> >>so that IOMMU devices have a chance to be probed and to register
> >>their bus notifiers before the dma_ops attach sequence for a
> >>device is actually carried out.
> >>
> >>Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi-5wv7dgnIgG8@public.gmane.org>
> >>Cc: Will Deacon <will.deacon-5wv7dgnIgG8@public.gmane.org>
> >>Cc: Catalin Marinas <catalin.marinas-5wv7dgnIgG8@public.gmane.org>
> >>Cc: Robin Murphy <robin.murphy-5wv7dgnIgG8@public.gmane.org>
> >>---
> >>  arch/arm64/mm/dma-mapping.c | 2 +-
> >>  1 file changed, 1 insertion(+), 1 deletion(-)
> >>
> >>diff --git a/arch/arm64/mm/dma-mapping.c b/arch/arm64/mm/dma-mapping.c
> >>index c566ec8..79b0882 100644
> >>--- a/arch/arm64/mm/dma-mapping.c
> >>+++ b/arch/arm64/mm/dma-mapping.c
> >>@@ -848,7 +848,7 @@ static int __iommu_attach_notifier(struct
> >>notifier_block *nb,
> >>  {
> >>      struct iommu_dma_notifier_data *master, *tmp;
> >>
> >>-    if (action != BUS_NOTIFY_ADD_DEVICE)
> >>+    if (action != BUS_NOTIFY_BIND_DRIVER)
> >
> >With this, you can also get rid of the priority setting and big
> >fat explanatory comment in register_iommu_dma_ops_notifier().
> >
> >Robin.
> >
> >>          return 0;
> >>
> >>      mutex_lock(&iommu_dma_notifier_lock);
> >>
> >
> >
> >
> 

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

* Re: [RFC PATCH v2 03/15] arm64: mm: change IOMMU notifier action to attach DMA ops
@ 2016-06-21 16:06               ` Lorenzo Pieralisi
  0 siblings, 0 replies; 88+ messages in thread
From: Lorenzo Pieralisi @ 2016-06-21 16:06 UTC (permalink / raw)
  To: Marek Szyprowski
  Cc: Robin Murphy, iommu, linux-arm-kernel, Rafael J. Wysocki,
	Marc Zyngier, Catalin Marinas, Joerg Roedel, Will Deacon,
	linux-kernel, linux-pci, Sinan Kaya, linux-acpi, Hanjun Guo,
	Tomasz Nowicki, Jon Masters

Hi Marek,

On Tue, Jun 21, 2016 at 09:53:20AM +0200, Marek Szyprowski wrote:
> Hi Robin,
> 
> 
> On 2016-06-17 11:27, Robin Murphy wrote:
> >Hi Lorenzo,
> >
> >I think this patch makes sense even independent of the rest of the
> >series, one nit inline notwithstanding.
> >
> >Marek; I'm curious as to whether this could make the workaround in
> >722ec35f7 obsolete as well, or are all the drivers also bound
> >super-early in the setup you had there?
> 
> Yes, this will solve that problem too. I will also hide some possible
> deferred probe issues, because the moment at which IOMMU is activated
> will be postponed. The only drawback with this approach is the fact
> that is drivers won't be allowed to do any dma-mapping operations on
> devices, which they don't own. This should not be a big issue, but
> this was the reason to setup IOMMU on device add instead of driver
> bind.
> 
> While at it, please make sure that the case of failed client driver
> probe will be handled properly. IOMMU might do some operations while
> setting up and if the client driver fails to probe (for whatever
> reason, might be a deferred probe too), those operation has to be
> undone. However the current code of the driver core won't call any
> notifier (like BUS_NOTIFY_UNBOUND_DRIVER or whatever else) in such
> case.

Isn't Andy's commit 14b6257a5f3d enough ? Is that what you had in
mind ?

> Long time ago I used BUS_NOTIFY_BIND_DRIVER based approach for my
> Exynos IOMMU patches and had to extend bus core with such patch:
> https://patchwork.kernel.org/patch/4678181/ to properly cleanup
> after failed client driver probe and avoid leaking resources. Please
> read the discussion, because some changes were requested to it.

It looks like commit 14b6257a5f3d ("device core: add
BUS_NOTIFY_DRIVER_NOT_BOUND notification") does what you
are requesting, please let me know if that's enough.

I will revert the changes in 722ec35f7 and fold them in the
new version along with Robin's suggestions.

Thanks,
Lorenzo

> 
> 
> Best regards
> Marek Szyprowski, PhD
> Samsung R&D Institute Poland
> 
> >
> >On 07/06/16 14:30, Lorenzo Pieralisi wrote:
> >>Current bus notifier in ARM64 (__iommu_attach_notifier)
> >>attempts to attach dma_ops to a device on BUS_NOTIFY_ADD_DEVICE
> >>action notification.
> >>
> >>This causes issues on ACPI based systems, where PCI devices
> >>can be added before the IOMMUs the devices are attached to
> >>had a chance to be probed, causing failures on attempts to
> >>attach dma_ops in that the domain for the respective IOMMU
> >>may not be set-up yet by the time the bus notifier is run.
> >>
> >>Devices dma_ops do not require to be set-up till the matching
> >>device drivers are probed. This means that instead of running
> >>the notifier attaching dma_ops to devices (__iommu_attach_notifier)
> >>on BUS_NOTIFY_ADD_DEVICE action, it can be run just before the
> >>device driver is bound to the device in question (on action
> >>BUS_NOTIFY_BIND_DRIVER) so that it is certain that its IOMMU
> >>group and domain are set-up accordingly at the time the
> >>notifier is triggered.
> >>
> >>This patch changes the notifier action upon which dma_ops
> >>are attached to devices and defer it to driver binding time,
> >>so that IOMMU devices have a chance to be probed and to register
> >>their bus notifiers before the dma_ops attach sequence for a
> >>device is actually carried out.
> >>
> >>Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
> >>Cc: Will Deacon <will.deacon@arm.com>
> >>Cc: Catalin Marinas <catalin.marinas@arm.com>
> >>Cc: Robin Murphy <robin.murphy@arm.com>
> >>---
> >>  arch/arm64/mm/dma-mapping.c | 2 +-
> >>  1 file changed, 1 insertion(+), 1 deletion(-)
> >>
> >>diff --git a/arch/arm64/mm/dma-mapping.c b/arch/arm64/mm/dma-mapping.c
> >>index c566ec8..79b0882 100644
> >>--- a/arch/arm64/mm/dma-mapping.c
> >>+++ b/arch/arm64/mm/dma-mapping.c
> >>@@ -848,7 +848,7 @@ static int __iommu_attach_notifier(struct
> >>notifier_block *nb,
> >>  {
> >>      struct iommu_dma_notifier_data *master, *tmp;
> >>
> >>-    if (action != BUS_NOTIFY_ADD_DEVICE)
> >>+    if (action != BUS_NOTIFY_BIND_DRIVER)
> >
> >With this, you can also get rid of the priority setting and big
> >fat explanatory comment in register_iommu_dma_ops_notifier().
> >
> >Robin.
> >
> >>          return 0;
> >>
> >>      mutex_lock(&iommu_dma_notifier_lock);
> >>
> >
> >
> >
> 

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

* Re: [RFC PATCH v2 03/15] arm64: mm: change IOMMU notifier action to attach DMA ops
@ 2016-06-21 16:06               ` Lorenzo Pieralisi
  0 siblings, 0 replies; 88+ messages in thread
From: Lorenzo Pieralisi @ 2016-06-21 16:06 UTC (permalink / raw)
  To: Marek Szyprowski
  Cc: Jon Masters, Marc Zyngier, Catalin Marinas, Joerg Roedel,
	Rafael J. Wysocki, linux-kernel, Will Deacon, Sinan Kaya,
	linux-acpi, iommu, Hanjun Guo, linux-pci, Tomasz Nowicki,
	Robin Murphy, linux-arm-kernel

Hi Marek,

On Tue, Jun 21, 2016 at 09:53:20AM +0200, Marek Szyprowski wrote:
> Hi Robin,
> 
> 
> On 2016-06-17 11:27, Robin Murphy wrote:
> >Hi Lorenzo,
> >
> >I think this patch makes sense even independent of the rest of the
> >series, one nit inline notwithstanding.
> >
> >Marek; I'm curious as to whether this could make the workaround in
> >722ec35f7 obsolete as well, or are all the drivers also bound
> >super-early in the setup you had there?
> 
> Yes, this will solve that problem too. I will also hide some possible
> deferred probe issues, because the moment at which IOMMU is activated
> will be postponed. The only drawback with this approach is the fact
> that is drivers won't be allowed to do any dma-mapping operations on
> devices, which they don't own. This should not be a big issue, but
> this was the reason to setup IOMMU on device add instead of driver
> bind.
> 
> While at it, please make sure that the case of failed client driver
> probe will be handled properly. IOMMU might do some operations while
> setting up and if the client driver fails to probe (for whatever
> reason, might be a deferred probe too), those operation has to be
> undone. However the current code of the driver core won't call any
> notifier (like BUS_NOTIFY_UNBOUND_DRIVER or whatever else) in such
> case.

Isn't Andy's commit 14b6257a5f3d enough ? Is that what you had in
mind ?

> Long time ago I used BUS_NOTIFY_BIND_DRIVER based approach for my
> Exynos IOMMU patches and had to extend bus core with such patch:
> https://patchwork.kernel.org/patch/4678181/ to properly cleanup
> after failed client driver probe and avoid leaking resources. Please
> read the discussion, because some changes were requested to it.

It looks like commit 14b6257a5f3d ("device core: add
BUS_NOTIFY_DRIVER_NOT_BOUND notification") does what you
are requesting, please let me know if that's enough.

I will revert the changes in 722ec35f7 and fold them in the
new version along with Robin's suggestions.

Thanks,
Lorenzo

> 
> 
> Best regards
> Marek Szyprowski, PhD
> Samsung R&D Institute Poland
> 
> >
> >On 07/06/16 14:30, Lorenzo Pieralisi wrote:
> >>Current bus notifier in ARM64 (__iommu_attach_notifier)
> >>attempts to attach dma_ops to a device on BUS_NOTIFY_ADD_DEVICE
> >>action notification.
> >>
> >>This causes issues on ACPI based systems, where PCI devices
> >>can be added before the IOMMUs the devices are attached to
> >>had a chance to be probed, causing failures on attempts to
> >>attach dma_ops in that the domain for the respective IOMMU
> >>may not be set-up yet by the time the bus notifier is run.
> >>
> >>Devices dma_ops do not require to be set-up till the matching
> >>device drivers are probed. This means that instead of running
> >>the notifier attaching dma_ops to devices (__iommu_attach_notifier)
> >>on BUS_NOTIFY_ADD_DEVICE action, it can be run just before the
> >>device driver is bound to the device in question (on action
> >>BUS_NOTIFY_BIND_DRIVER) so that it is certain that its IOMMU
> >>group and domain are set-up accordingly at the time the
> >>notifier is triggered.
> >>
> >>This patch changes the notifier action upon which dma_ops
> >>are attached to devices and defer it to driver binding time,
> >>so that IOMMU devices have a chance to be probed and to register
> >>their bus notifiers before the dma_ops attach sequence for a
> >>device is actually carried out.
> >>
> >>Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
> >>Cc: Will Deacon <will.deacon@arm.com>
> >>Cc: Catalin Marinas <catalin.marinas@arm.com>
> >>Cc: Robin Murphy <robin.murphy@arm.com>
> >>---
> >>  arch/arm64/mm/dma-mapping.c | 2 +-
> >>  1 file changed, 1 insertion(+), 1 deletion(-)
> >>
> >>diff --git a/arch/arm64/mm/dma-mapping.c b/arch/arm64/mm/dma-mapping.c
> >>index c566ec8..79b0882 100644
> >>--- a/arch/arm64/mm/dma-mapping.c
> >>+++ b/arch/arm64/mm/dma-mapping.c
> >>@@ -848,7 +848,7 @@ static int __iommu_attach_notifier(struct
> >>notifier_block *nb,
> >>  {
> >>      struct iommu_dma_notifier_data *master, *tmp;
> >>
> >>-    if (action != BUS_NOTIFY_ADD_DEVICE)
> >>+    if (action != BUS_NOTIFY_BIND_DRIVER)
> >
> >With this, you can also get rid of the priority setting and big
> >fat explanatory comment in register_iommu_dma_ops_notifier().
> >
> >Robin.
> >
> >>          return 0;
> >>
> >>      mutex_lock(&iommu_dma_notifier_lock);
> >>
> >
> >
> >
> 

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [RFC PATCH v2 03/15] arm64: mm: change IOMMU notifier action to attach DMA ops
@ 2016-06-21 16:06               ` Lorenzo Pieralisi
  0 siblings, 0 replies; 88+ messages in thread
From: Lorenzo Pieralisi @ 2016-06-21 16:06 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Marek,

On Tue, Jun 21, 2016 at 09:53:20AM +0200, Marek Szyprowski wrote:
> Hi Robin,
> 
> 
> On 2016-06-17 11:27, Robin Murphy wrote:
> >Hi Lorenzo,
> >
> >I think this patch makes sense even independent of the rest of the
> >series, one nit inline notwithstanding.
> >
> >Marek; I'm curious as to whether this could make the workaround in
> >722ec35f7 obsolete as well, or are all the drivers also bound
> >super-early in the setup you had there?
> 
> Yes, this will solve that problem too. I will also hide some possible
> deferred probe issues, because the moment at which IOMMU is activated
> will be postponed. The only drawback with this approach is the fact
> that is drivers won't be allowed to do any dma-mapping operations on
> devices, which they don't own. This should not be a big issue, but
> this was the reason to setup IOMMU on device add instead of driver
> bind.
> 
> While at it, please make sure that the case of failed client driver
> probe will be handled properly. IOMMU might do some operations while
> setting up and if the client driver fails to probe (for whatever
> reason, might be a deferred probe too), those operation has to be
> undone. However the current code of the driver core won't call any
> notifier (like BUS_NOTIFY_UNBOUND_DRIVER or whatever else) in such
> case.

Isn't Andy's commit 14b6257a5f3d enough ? Is that what you had in
mind ?

> Long time ago I used BUS_NOTIFY_BIND_DRIVER based approach for my
> Exynos IOMMU patches and had to extend bus core with such patch:
> https://patchwork.kernel.org/patch/4678181/ to properly cleanup
> after failed client driver probe and avoid leaking resources. Please
> read the discussion, because some changes were requested to it.

It looks like commit 14b6257a5f3d ("device core: add
BUS_NOTIFY_DRIVER_NOT_BOUND notification") does what you
are requesting, please let me know if that's enough.

I will revert the changes in 722ec35f7 and fold them in the
new version along with Robin's suggestions.

Thanks,
Lorenzo

> 
> 
> Best regards
> Marek Szyprowski, PhD
> Samsung R&D Institute Poland
> 
> >
> >On 07/06/16 14:30, Lorenzo Pieralisi wrote:
> >>Current bus notifier in ARM64 (__iommu_attach_notifier)
> >>attempts to attach dma_ops to a device on BUS_NOTIFY_ADD_DEVICE
> >>action notification.
> >>
> >>This causes issues on ACPI based systems, where PCI devices
> >>can be added before the IOMMUs the devices are attached to
> >>had a chance to be probed, causing failures on attempts to
> >>attach dma_ops in that the domain for the respective IOMMU
> >>may not be set-up yet by the time the bus notifier is run.
> >>
> >>Devices dma_ops do not require to be set-up till the matching
> >>device drivers are probed. This means that instead of running
> >>the notifier attaching dma_ops to devices (__iommu_attach_notifier)
> >>on BUS_NOTIFY_ADD_DEVICE action, it can be run just before the
> >>device driver is bound to the device in question (on action
> >>BUS_NOTIFY_BIND_DRIVER) so that it is certain that its IOMMU
> >>group and domain are set-up accordingly at the time the
> >>notifier is triggered.
> >>
> >>This patch changes the notifier action upon which dma_ops
> >>are attached to devices and defer it to driver binding time,
> >>so that IOMMU devices have a chance to be probed and to register
> >>their bus notifiers before the dma_ops attach sequence for a
> >>device is actually carried out.
> >>
> >>Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
> >>Cc: Will Deacon <will.deacon@arm.com>
> >>Cc: Catalin Marinas <catalin.marinas@arm.com>
> >>Cc: Robin Murphy <robin.murphy@arm.com>
> >>---
> >>  arch/arm64/mm/dma-mapping.c | 2 +-
> >>  1 file changed, 1 insertion(+), 1 deletion(-)
> >>
> >>diff --git a/arch/arm64/mm/dma-mapping.c b/arch/arm64/mm/dma-mapping.c
> >>index c566ec8..79b0882 100644
> >>--- a/arch/arm64/mm/dma-mapping.c
> >>+++ b/arch/arm64/mm/dma-mapping.c
> >>@@ -848,7 +848,7 @@ static int __iommu_attach_notifier(struct
> >>notifier_block *nb,
> >>  {
> >>      struct iommu_dma_notifier_data *master, *tmp;
> >>
> >>-    if (action != BUS_NOTIFY_ADD_DEVICE)
> >>+    if (action != BUS_NOTIFY_BIND_DRIVER)
> >
> >With this, you can also get rid of the priority setting and big
> >fat explanatory comment in register_iommu_dma_ops_notifier().
> >
> >Robin.
> >
> >>          return 0;
> >>
> >>      mutex_lock(&iommu_dma_notifier_lock);
> >>
> >
> >
> >
> 

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

* Re: [RFC PATCH v2 00/15] ACPI IORT ARM SMMU v3 support
  2016-06-21 14:27       ` Lorenzo Pieralisi
  (?)
@ 2016-06-22  2:45         ` Hanjun Guo
  -1 siblings, 0 replies; 88+ messages in thread
From: Hanjun Guo @ 2016-06-22  2:45 UTC (permalink / raw)
  To: Lorenzo Pieralisi
  Cc: Marc Zyngier, Rafael J. Wysocki, Will Deacon,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-pci-u79uwXL29TY76Z2rM5mHXA,
	linuxarm-hv44wF8Li93QT0dZR+AlfA, Sinan Kaya,
	linux-acpi-u79uwXL29TY76Z2rM5mHXA,
	iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	Tomasz Nowicki, Jon Masters

On 2016/6/21 22:27, Lorenzo Pieralisi wrote:
> Hi Hanjun,
>
> On Tue, Jun 21, 2016 at 06:37:17PM +0800, Hanjun Guo wrote:
>> Hi Lorenzo,
>>
>> On 2016/6/7 21:30, Lorenzo Pieralisi wrote:
>>> This RFC patch series is v2 of a previous posting:
>>>
>>> https://lkml.org/lkml/2016/4/14/702
>>>
>>> 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.
>>
>> I'm trying to test your patches on D03 (SMMUv3 based) but ...
>
> What do you mean by "I am trying.." :), have you actually tested
> this series ?

I was rebasing this series on top of Tomasz's latest ITS patchset,
and found that patch 1~2,5 are not needed, and also have conflicts
(expected), so I think it's better to wait for the updated version
from you :)

>
>> [...]
>>> [1] R.Murphy "Generic DT bindings for PCI and ARM SMMU v3"
>>>    http://marc.info/?l=linux-arm-kernel&m=146497432413816&w=2
>>
>> ...This patch set is still in discussion and seems not work
>> for non-PCI devices.
>
> Can you be more specific please ? Yes, both series are work
> in progress.
>
>>> [2] T.Nowicki "Introduce ACPI world to ITS irqchip" v5
>>>    http://marc.info/?l=linux-acpi&m=146469369703684&w=2
>>
>> Tomasz sent out the v7 and included patches in your series.
>>
>> I think a updated version before the test makes sense, what
>> do you think? Let me know your thoughts.
>
> I am working with Robin so that the xlate() mechanism works
> properly and seamlessly for both DT and ACPI, given the
> dependencies I think it makes more sense to wait for Tomasz
> and Robin patches to get merged or at least stabilize before
> doing anything else, I am curently working on a v3.

OK.

Thanks
Hanjun

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

* Re: [RFC PATCH v2 00/15] ACPI IORT ARM SMMU v3 support
@ 2016-06-22  2:45         ` Hanjun Guo
  0 siblings, 0 replies; 88+ messages in thread
From: Hanjun Guo @ 2016-06-22  2:45 UTC (permalink / raw)
  To: Lorenzo Pieralisi
  Cc: iommu, Will Deacon, Marc Zyngier, Robin Murphy, Joerg Roedel,
	Rafael J. Wysocki, Tomasz Nowicki, Jon Masters, Sinan Kaya,
	linux-acpi, linux-pci, linux-kernel, linux-arm-kernel, linuxarm

On 2016/6/21 22:27, Lorenzo Pieralisi wrote:
> Hi Hanjun,
>
> On Tue, Jun 21, 2016 at 06:37:17PM +0800, Hanjun Guo wrote:
>> Hi Lorenzo,
>>
>> On 2016/6/7 21:30, Lorenzo Pieralisi wrote:
>>> This RFC patch series is v2 of a previous posting:
>>>
>>> https://lkml.org/lkml/2016/4/14/702
>>>
>>> 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.
>>
>> I'm trying to test your patches on D03 (SMMUv3 based) but ...
>
> What do you mean by "I am trying.." :), have you actually tested
> this series ?

I was rebasing this series on top of Tomasz's latest ITS patchset,
and found that patch 1~2,5 are not needed, and also have conflicts
(expected), so I think it's better to wait for the updated version
from you :)

>
>> [...]
>>> [1] R.Murphy "Generic DT bindings for PCI and ARM SMMU v3"
>>>    http://marc.info/?l=linux-arm-kernel&m=146497432413816&w=2
>>
>> ...This patch set is still in discussion and seems not work
>> for non-PCI devices.
>
> Can you be more specific please ? Yes, both series are work
> in progress.
>
>>> [2] T.Nowicki "Introduce ACPI world to ITS irqchip" v5
>>>    http://marc.info/?l=linux-acpi&m=146469369703684&w=2
>>
>> Tomasz sent out the v7 and included patches in your series.
>>
>> I think a updated version before the test makes sense, what
>> do you think? Let me know your thoughts.
>
> I am working with Robin so that the xlate() mechanism works
> properly and seamlessly for both DT and ACPI, given the
> dependencies I think it makes more sense to wait for Tomasz
> and Robin patches to get merged or at least stabilize before
> doing anything else, I am curently working on a v3.

OK.

Thanks
Hanjun

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

* [RFC PATCH v2 00/15] ACPI IORT ARM SMMU v3 support
@ 2016-06-22  2:45         ` Hanjun Guo
  0 siblings, 0 replies; 88+ messages in thread
From: Hanjun Guo @ 2016-06-22  2:45 UTC (permalink / raw)
  To: linux-arm-kernel

On 2016/6/21 22:27, Lorenzo Pieralisi wrote:
> Hi Hanjun,
>
> On Tue, Jun 21, 2016 at 06:37:17PM +0800, Hanjun Guo wrote:
>> Hi Lorenzo,
>>
>> On 2016/6/7 21:30, Lorenzo Pieralisi wrote:
>>> This RFC patch series is v2 of a previous posting:
>>>
>>> https://lkml.org/lkml/2016/4/14/702
>>>
>>> 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.
>>
>> I'm trying to test your patches on D03 (SMMUv3 based) but ...
>
> What do you mean by "I am trying.." :), have you actually tested
> this series ?

I was rebasing this series on top of Tomasz's latest ITS patchset,
and found that patch 1~2,5 are not needed, and also have conflicts
(expected), so I think it's better to wait for the updated version
from you :)

>
>> [...]
>>> [1] R.Murphy "Generic DT bindings for PCI and ARM SMMU v3"
>>>    http://marc.info/?l=linux-arm-kernel&m=146497432413816&w=2
>>
>> ...This patch set is still in discussion and seems not work
>> for non-PCI devices.
>
> Can you be more specific please ? Yes, both series are work
> in progress.
>
>>> [2] T.Nowicki "Introduce ACPI world to ITS irqchip" v5
>>>    http://marc.info/?l=linux-acpi&m=146469369703684&w=2
>>
>> Tomasz sent out the v7 and included patches in your series.
>>
>> I think a updated version before the test makes sense, what
>> do you think? Let me know your thoughts.
>
> I am working with Robin so that the xlate() mechanism works
> properly and seamlessly for both DT and ACPI, given the
> dependencies I think it makes more sense to wait for Tomasz
> and Robin patches to get merged or at least stabilize before
> doing anything else, I am curently working on a v3.

OK.

Thanks
Hanjun

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

* Re: [RFC PATCH v2 03/15] arm64: mm: change IOMMU notifier action to attach DMA ops
  2016-06-21 16:06               ` Lorenzo Pieralisi
@ 2016-06-23  6:13                 ` Marek Szyprowski
  -1 siblings, 0 replies; 88+ messages in thread
From: Marek Szyprowski @ 2016-06-23  6:13 UTC (permalink / raw)
  To: Lorenzo Pieralisi
  Cc: Robin Murphy, iommu, linux-arm-kernel, Rafael J. Wysocki,
	Marc Zyngier, Catalin Marinas, Joerg Roedel, Will Deacon,
	linux-kernel, linux-pci, Sinan Kaya, linux-acpi, Hanjun Guo,
	Tomasz Nowicki, Jon Masters

Hi Lorenzo,


On 2016-06-21 18:06, Lorenzo Pieralisi wrote:
> Hi Marek,
>
> On Tue, Jun 21, 2016 at 09:53:20AM +0200, Marek Szyprowski wrote:
>> Hi Robin,
>>
>>
>> On 2016-06-17 11:27, Robin Murphy wrote:
>>> Hi Lorenzo,
>>>
>>> I think this patch makes sense even independent of the rest of the
>>> series, one nit inline notwithstanding.
>>>
>>> Marek; I'm curious as to whether this could make the workaround in
>>> 722ec35f7 obsolete as well, or are all the drivers also bound
>>> super-early in the setup you had there?
>> Yes, this will solve that problem too. I will also hide some possible
>> deferred probe issues, because the moment at which IOMMU is activated
>> will be postponed. The only drawback with this approach is the fact
>> that is drivers won't be allowed to do any dma-mapping operations on
>> devices, which they don't own. This should not be a big issue, but
>> this was the reason to setup IOMMU on device add instead of driver
>> bind.
>>
>> While at it, please make sure that the case of failed client driver
>> probe will be handled properly. IOMMU might do some operations while
>> setting up and if the client driver fails to probe (for whatever
>> reason, might be a deferred probe too), those operation has to be
>> undone. However the current code of the driver core won't call any
>> notifier (like BUS_NOTIFY_UNBOUND_DRIVER or whatever else) in such
>> case.
> Isn't Andy's commit 14b6257a5f3d enough ? Is that what you had in
> mind ?
>
>> Long time ago I used BUS_NOTIFY_BIND_DRIVER based approach for my
>> Exynos IOMMU patches and had to extend bus core with such patch:
>> https://patchwork.kernel.org/patch/4678181/ to properly cleanup
>> after failed client driver probe and avoid leaking resources. Please
>> read the discussion, because some changes were requested to it.
> It looks like commit 14b6257a5f3d ("device core: add
> BUS_NOTIFY_DRIVER_NOT_BOUND notification") does what you
> are requesting, please let me know if that's enough.

Yes, that's exactly the change I needed that time. Nice to see that it
finally landed in mainline.

> I will revert the changes in 722ec35f7 and fold them in the
> new version along with Robin's suggestions.

Okay.

Best regards
-- 
Marek Szyprowski, PhD
Samsung R&D Institute Poland

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

* [RFC PATCH v2 03/15] arm64: mm: change IOMMU notifier action to attach DMA ops
@ 2016-06-23  6:13                 ` Marek Szyprowski
  0 siblings, 0 replies; 88+ messages in thread
From: Marek Szyprowski @ 2016-06-23  6:13 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Lorenzo,


On 2016-06-21 18:06, Lorenzo Pieralisi wrote:
> Hi Marek,
>
> On Tue, Jun 21, 2016 at 09:53:20AM +0200, Marek Szyprowski wrote:
>> Hi Robin,
>>
>>
>> On 2016-06-17 11:27, Robin Murphy wrote:
>>> Hi Lorenzo,
>>>
>>> I think this patch makes sense even independent of the rest of the
>>> series, one nit inline notwithstanding.
>>>
>>> Marek; I'm curious as to whether this could make the workaround in
>>> 722ec35f7 obsolete as well, or are all the drivers also bound
>>> super-early in the setup you had there?
>> Yes, this will solve that problem too. I will also hide some possible
>> deferred probe issues, because the moment at which IOMMU is activated
>> will be postponed. The only drawback with this approach is the fact
>> that is drivers won't be allowed to do any dma-mapping operations on
>> devices, which they don't own. This should not be a big issue, but
>> this was the reason to setup IOMMU on device add instead of driver
>> bind.
>>
>> While at it, please make sure that the case of failed client driver
>> probe will be handled properly. IOMMU might do some operations while
>> setting up and if the client driver fails to probe (for whatever
>> reason, might be a deferred probe too), those operation has to be
>> undone. However the current code of the driver core won't call any
>> notifier (like BUS_NOTIFY_UNBOUND_DRIVER or whatever else) in such
>> case.
> Isn't Andy's commit 14b6257a5f3d enough ? Is that what you had in
> mind ?
>
>> Long time ago I used BUS_NOTIFY_BIND_DRIVER based approach for my
>> Exynos IOMMU patches and had to extend bus core with such patch:
>> https://patchwork.kernel.org/patch/4678181/ to properly cleanup
>> after failed client driver probe and avoid leaking resources. Please
>> read the discussion, because some changes were requested to it.
> It looks like commit 14b6257a5f3d ("device core: add
> BUS_NOTIFY_DRIVER_NOT_BOUND notification") does what you
> are requesting, please let me know if that's enough.

Yes, that's exactly the change I needed that time. Nice to see that it
finally landed in mainline.

> I will revert the changes in 722ec35f7 and fold them in the
> new version along with Robin's suggestions.

Okay.

Best regards
-- 
Marek Szyprowski, PhD
Samsung R&D Institute Poland

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

* Re: [RFC PATCH v2 03/15] arm64: mm: change IOMMU notifier action to attach DMA ops
  2016-06-17 14:15           ` Lorenzo Pieralisi
@ 2016-06-23 11:32             ` Robin Murphy
  -1 siblings, 0 replies; 88+ messages in thread
From: Robin Murphy @ 2016-06-23 11:32 UTC (permalink / raw)
  To: Lorenzo Pieralisi
  Cc: Jon Masters, Marc Zyngier, Catalin Marinas, Rafael J. Wysocki,
	linux-kernel, Will Deacon, Sinan Kaya, linux-acpi, iommu,
	Hanjun Guo, linux-pci, Tomasz Nowicki, linux-arm-kernel

Hi Lorenzo,

On 17/06/16 15:15, Lorenzo Pieralisi wrote:
>> I think this patch makes sense even independent of the rest of the
>> series, one nit inline notwithstanding.
>
> Thanks. Yes I added it to this series since it is not strictly
> necessary (ie it does not fix anything) in the mainline, but
> it *is* necessary for this whole series to function when we
> boot through ACPI.
>
> I will send it out in a separate patch and fold changes you
> request below, it would be good to have some coverage for
> it before merging it.

Having considered it a bit more, triggering on BIND_DRIVER also means 
the silly "process the whole list every time" behaviour should go away. 
There's little point in trying to configure a device's ops before we 
know they're actually needed, and once a driver has bound it's too late 
to change anything anyway. What do you think of squashing in something 
like the below?

Robin.

----->8-----
diff --git a/arch/arm64/mm/dma-mapping.c b/arch/arm64/mm/dma-mapping.c
index 7d3fa9ae8a11..02484dc3f369 100644
--- a/arch/arm64/mm/dma-mapping.c
+++ b/arch/arm64/mm/dma-mapping.c
@@ -854,10 +854,11 @@ static int __iommu_attach_notifier(struct 
notifier_block *nb,

  	mutex_lock(&iommu_dma_notifier_lock);
  	list_for_each_entry_safe(master, tmp, &iommu_dma_masters, list) {
-		if (do_iommu_attach(master->dev, master->ops,
-				master->dma_base, master->size)) {
+		if (data == master->dev && do_iommu_attach(master->dev,
+				master->ops, master->dma_base, master->size)) {
  			list_del(&master->list);
  			kfree(master);
+			break;
  		}
  	}
  	mutex_unlock(&iommu_dma_notifier_lock);


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

* [RFC PATCH v2 03/15] arm64: mm: change IOMMU notifier action to attach DMA ops
@ 2016-06-23 11:32             ` Robin Murphy
  0 siblings, 0 replies; 88+ messages in thread
From: Robin Murphy @ 2016-06-23 11:32 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Lorenzo,

On 17/06/16 15:15, Lorenzo Pieralisi wrote:
>> I think this patch makes sense even independent of the rest of the
>> series, one nit inline notwithstanding.
>
> Thanks. Yes I added it to this series since it is not strictly
> necessary (ie it does not fix anything) in the mainline, but
> it *is* necessary for this whole series to function when we
> boot through ACPI.
>
> I will send it out in a separate patch and fold changes you
> request below, it would be good to have some coverage for
> it before merging it.

Having considered it a bit more, triggering on BIND_DRIVER also means 
the silly "process the whole list every time" behaviour should go away. 
There's little point in trying to configure a device's ops before we 
know they're actually needed, and once a driver has bound it's too late 
to change anything anyway. What do you think of squashing in something 
like the below?

Robin.

----->8-----
diff --git a/arch/arm64/mm/dma-mapping.c b/arch/arm64/mm/dma-mapping.c
index 7d3fa9ae8a11..02484dc3f369 100644
--- a/arch/arm64/mm/dma-mapping.c
+++ b/arch/arm64/mm/dma-mapping.c
@@ -854,10 +854,11 @@ static int __iommu_attach_notifier(struct 
notifier_block *nb,

  	mutex_lock(&iommu_dma_notifier_lock);
  	list_for_each_entry_safe(master, tmp, &iommu_dma_masters, list) {
-		if (do_iommu_attach(master->dev, master->ops,
-				master->dma_base, master->size)) {
+		if (data == master->dev && do_iommu_attach(master->dev,
+				master->ops, master->dma_base, master->size)) {
  			list_del(&master->list);
  			kfree(master);
+			break;
  		}
  	}
  	mutex_unlock(&iommu_dma_notifier_lock);

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

end of thread, other threads:[~2016-06-23 11:32 UTC | newest]

Thread overview: 88+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-06-07 13:30 [RFC PATCH v2 00/15] ACPI IORT ARM SMMU v3 support Lorenzo Pieralisi
2016-06-07 13:30 ` Lorenzo Pieralisi
     [not found] ` <1465306270-27076-1-git-send-email-lorenzo.pieralisi-5wv7dgnIgG8@public.gmane.org>
2016-06-07 13:30   ` [RFC PATCH v2 01/15] drivers: acpi: iort: fix struct pci_dev compiler warnings Lorenzo Pieralisi
2016-06-07 13:30     ` Lorenzo Pieralisi
2016-06-07 13:30     ` Lorenzo Pieralisi
2016-06-07 13:30     ` Lorenzo Pieralisi
2016-06-07 13:30   ` [RFC PATCH v2 02/15] drivers: irqchip: its: fix its_acpi_probe() prototype Lorenzo Pieralisi
2016-06-07 13:30     ` Lorenzo Pieralisi
2016-06-07 13:30     ` Lorenzo Pieralisi
2016-06-07 13:30     ` Lorenzo Pieralisi
2016-06-07 13:30   ` [RFC PATCH v2 03/15] arm64: mm: change IOMMU notifier action to attach DMA ops Lorenzo Pieralisi
2016-06-07 13:30     ` Lorenzo Pieralisi
2016-06-07 13:30     ` Lorenzo Pieralisi
2016-06-17  9:27     ` Robin Murphy
2016-06-17  9:27       ` Robin Murphy
     [not found]       ` <5763C27A.9030306-5wv7dgnIgG8@public.gmane.org>
2016-06-17 14:15         ` Lorenzo Pieralisi
2016-06-17 14:15           ` Lorenzo Pieralisi
2016-06-17 14:15           ` Lorenzo Pieralisi
2016-06-23 11:32           ` Robin Murphy
2016-06-23 11:32             ` Robin Murphy
2016-06-21  7:53         ` Marek Szyprowski
2016-06-21  7:53           ` Marek Szyprowski
2016-06-21  7:53           ` Marek Szyprowski
2016-06-21  7:53           ` Marek Szyprowski
     [not found]           ` <03c537e7-0acf-edca-d0e0-369490c828df-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
2016-06-21 16:06             ` Lorenzo Pieralisi
2016-06-21 16:06               ` Lorenzo Pieralisi
2016-06-21 16:06               ` Lorenzo Pieralisi
2016-06-21 16:06               ` Lorenzo Pieralisi
2016-06-23  6:13               ` Marek Szyprowski
2016-06-23  6:13                 ` Marek Szyprowski
2016-06-07 13:30   ` [RFC PATCH v2 04/15] drivers: acpi: iort: add support for IOMMU registration Lorenzo Pieralisi
2016-06-07 13:30     ` Lorenzo Pieralisi
2016-06-07 13:30     ` Lorenzo Pieralisi
2016-06-07 13:30     ` Lorenzo Pieralisi
2016-06-07 13:31   ` [RFC PATCH v2 05/15] drivers: acpi: iort: add support for named component look-up Lorenzo Pieralisi
2016-06-07 13:31     ` Lorenzo Pieralisi
2016-06-07 13:31     ` Lorenzo Pieralisi
2016-06-07 13:31   ` [RFC PATCH v2 06/15] drivers: acpi: iort: enhance device identifiers mappings Lorenzo Pieralisi
2016-06-07 13:31     ` Lorenzo Pieralisi
2016-06-07 13:31     ` Lorenzo Pieralisi
2016-06-07 13:31     ` Lorenzo Pieralisi
2016-06-07 13:31   ` [RFC PATCH v2 08/15] drivers: acpi: iort: add support for ARM SMMU platform devices creation Lorenzo Pieralisi
2016-06-07 13:31     ` Lorenzo Pieralisi
2016-06-07 13:31     ` Lorenzo Pieralisi
2016-06-07 13:31   ` [RFC PATCH v2 09/15] drivers: iommu: arm-smmu-v3: split probe functions into DT/generic portions Lorenzo Pieralisi
2016-06-07 13:31     ` Lorenzo Pieralisi
2016-06-07 13:31     ` Lorenzo Pieralisi
2016-06-14 18:09     ` Will Deacon
2016-06-14 18:09       ` Will Deacon
2016-06-07 13:31   ` [RFC PATCH v2 10/15] drivers: iommu: arm-smmu-v3: enable ACPI driver initialization Lorenzo Pieralisi
2016-06-07 13:31     ` Lorenzo Pieralisi
2016-06-07 13:31     ` Lorenzo Pieralisi
2016-06-14 18:12     ` Will Deacon
2016-06-14 18:12       ` Will Deacon
2016-06-07 13:31   ` [RFC PATCH v2 13/15] drivers: acpi: iort: introduce iort_iommu_configure Lorenzo Pieralisi
2016-06-07 13:31     ` Lorenzo Pieralisi
2016-06-07 13:31     ` Lorenzo Pieralisi
2016-06-10 12:46     ` Tomasz Nowicki
2016-06-10 12:46       ` Tomasz Nowicki
2016-06-10 12:46       ` Tomasz Nowicki
2016-06-07 13:31 ` [RFC PATCH v2 07/15] drivers: acpi: iort: add node match function Lorenzo Pieralisi
2016-06-07 13:31   ` Lorenzo Pieralisi
2016-06-07 13:31 ` [RFC PATCH v2 11/15] drivers: iommu: arm-smmu-v3: add IORT iommu configuration Lorenzo Pieralisi
2016-06-07 13:31   ` Lorenzo Pieralisi
2016-06-14 18:39   ` Will Deacon
2016-06-14 18:39     ` Will Deacon
     [not found]     ` <20160614183939.GL16531-5wv7dgnIgG8@public.gmane.org>
2016-06-15  8:52       ` Lorenzo Pieralisi
2016-06-15  8:52         ` Lorenzo Pieralisi
2016-06-15  8:52         ` Lorenzo Pieralisi
2016-06-07 13:31 ` [RFC PATCH v2 12/15] drivers: acpi: implement acpi_dma_configure Lorenzo Pieralisi
2016-06-07 13:31   ` Lorenzo Pieralisi
     [not found]   ` <1465306270-27076-13-git-send-email-lorenzo.pieralisi-5wv7dgnIgG8@public.gmane.org>
2016-06-10 16:25     ` Bjorn Helgaas
2016-06-10 16:25       ` Bjorn Helgaas
2016-06-10 16:25       ` Bjorn Helgaas
2016-06-07 13:31 ` [RFC PATCH v2 14/15] drivers: acpi: iort: add function to retrieve IOMMU platform devices Lorenzo Pieralisi
2016-06-07 13:31   ` Lorenzo Pieralisi
2016-06-07 13:31 ` [RFC PATCH v2 15/15] drivers: iommu: arm-smmu-v3: allow ACPI based streamid translation Lorenzo Pieralisi
2016-06-07 13:31   ` Lorenzo Pieralisi
2016-06-21 10:37 ` [RFC PATCH v2 00/15] ACPI IORT ARM SMMU v3 support Hanjun Guo
2016-06-21 10:37   ` Hanjun Guo
2016-06-21 10:37   ` Hanjun Guo
     [not found]   ` <b00f33ad-be24-21a9-b03b-611756bbc8e9-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
2016-06-21 14:27     ` Lorenzo Pieralisi
2016-06-21 14:27       ` Lorenzo Pieralisi
2016-06-21 14:27       ` Lorenzo Pieralisi
2016-06-21 14:27       ` Lorenzo Pieralisi
2016-06-22  2:45       ` Hanjun Guo
2016-06-22  2:45         ` Hanjun Guo
2016-06-22  2:45         ` Hanjun Guo

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