Re: [Patch Part3 V5 5/8] iommu/vt-d: Enhance intel_irq_remapping driver to support DMAR unit hotplug

2014-09-16 Thread Jiang Liu
On 2014/9/15 10:20, Yijing Wang wrote:
 +static void ir_remove_ioapic_hpet_scope(struct intel_iommu *iommu)
 +{
 +int i;
  
 -ir_parse_one_hpet_scope(scope, iommu);
 -}
 -start += scope-length;
 -}
 +for (i = 0; i  MAX_HPET_TBS; i++)
 +if (ir_hpet[i].iommu == iommu)
 +ir_hpet[i].iommu = NULL;
 
 Hi Gerry, why not reset whole ir_hpe and ir_ioapic data struct?
Hi Yijing,
Thanks for review. Zero is legal for id, bus and devfn in
struct ioapic_scope and struct hpet_scope. So we use domain field
as a flag to mark entry valid or invalid and only reset iommu field.

Regards!
Gerry
 
 
 
  
 -return 0;
 +for (i = 0; i  MAX_IO_APICS; i++)
 +if (ir_ioapic[i].iommu == iommu)
 +ir_ioapic[i].iommu = NULL;
  }
  
 
 --
 To unsubscribe from this list: send the line unsubscribe linux-kernel in
 the body of a message to majord...@vger.kernel.org
 More majordomo info at  http://vger.kernel.org/majordomo-info.html
 Please read the FAQ at  http://www.tux.org/lkml/
 
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [Patch Part3 V5 1/8] iommu/vt-d: Introduce helper function dmar_walk_resources()

2014-09-16 Thread Jiang Liu
On 2014/9/12 17:16, Yijing Wang wrote:
 On 2014/9/12 10:10, Jiang Liu wrote:
 Introduce helper function dmar_walk_resources to walk resource entries
 in DMAR table and ACPI buffer object returned by ACPI _DSM method
 for IOMMU hot-plug.

 Signed-off-by: Jiang Liu jiang@linux.intel.com
 
 Hi Gerry. some comments below.
Hi Yijing,
Thanks for review. Please refer inline comments below.

 
 
 ---
  drivers/iommu/dmar.c|  209 
 +++
  drivers/iommu/intel-iommu.c |4 +-
  include/linux/dmar.h|   19 ++--
  3 files changed, 122 insertions(+), 110 deletions(-)

 diff --git a/drivers/iommu/dmar.c b/drivers/iommu/dmar.c
 index 60ab474bfff3..afd46eb9a5de 100644
 --- a/drivers/iommu/dmar.c
 +++ b/drivers/iommu/dmar.c
 @@ -44,6 +44,14 @@
  
  #include irq_remapping.h
  
 +typedef int (*dmar_res_handler_t)(struct acpi_dmar_header *, void *);
 +struct dmar_res_callback {
 +dmar_res_handler_t  cb[ACPI_DMAR_TYPE_RESERVED];
 +void*arg[ACPI_DMAR_TYPE_RESERVED];
 +boolignore_unhandled;
 +boolprint_entry;
 
 Why do we need a switch to control print ?
We will walk DMAR entries several times during hotplug and only
want to print once.

 
 +};
 +
  
 +static int dmar_walk_resources(struct acpi_dmar_header *start, size_t len,
 +   struct dmar_res_callback *cb)
 
 The name dmar_walk_resources easily make people think this is related with 
 I/O or memory resources.
 Do you have a better idea of this ?  What about dmar_walk_remapping_entry() 
 or dmar_walk_remapping_structure() ?
Good suggestion, I like dmar_walk_remapping_entries().
 
 +{
 +int ret = 0;
 +struct acpi_dmar_header *iter, *next;
 +struct acpi_dmar_header *end = ((void *)start) + len;
 +
 +for (iter = start; iter  end  ret == 0; iter = next) {
 +next = (void *)iter + iter-length;
 +if (iter-length == 0) {
 +/* Avoid looping forever on bad ACPI tables */
 +pr_debug(FW_BUG Invalid 0-length structure\n);
 
 What about use pr_warn() instead of pr_debug(), pr_debug() default is off.
It seems a common practice for BIOS engineer to mark the last entry with
zero length. So it will be annoying if we generate this debug message
on product kernel.

 
 +break;
 +} else if (next  end) {
 +/* Avoid passing table end */
 +pr_warn(FW_BUG record passes table end\n);
 +ret = -EINVAL;
 +break;
 +}
 +
 +if (cb-print_entry)
 +dmar_table_print_dmar_entry(iter);
 +
 +if (iter-type = ACPI_DMAR_TYPE_RESERVED) {
 +/* continue for forward compatibility */
 +pr_debug(Unknown DMAR structure type %d\n,
 + iter-type);
 
 Same as above.
This is typically caused by new DMAR specification. It will also be
annoying too if  we also generate this debug message on an newer
hardware platform with older linux kernel.

 
 +} else if (cb-cb[iter-type]) {
 +ret = cb-cb[iter-type](iter, cb-arg[iter-type]);
 +} else if (!cb-ignore_unhandled) {
 +pr_warn(No handler for DMAR structure type %d\n,
 +iter-type);
 +ret = -EINVAL;
 +}
 +}
 +
 +return ret;
 +}
 +
 +static inline int dmar_walk_dmar_table(struct acpi_table_dmar *dmar,
 +   struct dmar_res_callback *cb)
 +{
 +return dmar_walk_resources((struct acpi_dmar_header *)(dmar + 1),
 +   dmar-header.length - sizeof(*dmar), cb);
 +}
 +
  /**
   * parse_dmar_table - parses the DMA reporting table
   */
 @@ -493,9 +554,18 @@ static int __init
  parse_dmar_table(void)
  {
  struct acpi_table_dmar *dmar;
 -struct acpi_dmar_header *entry_header;
  int ret = 0;
  int drhd_count = 0;
 +struct dmar_res_callback cb = {
 +.print_entry = true,
 +.ignore_unhandled = true,
 +.arg[ACPI_DMAR_TYPE_HARDWARE_UNIT] = drhd_count,
 +.cb[ACPI_DMAR_TYPE_HARDWARE_UNIT] = dmar_parse_one_drhd,
 +.cb[ACPI_DMAR_TYPE_RESERVED_MEMORY] = dmar_parse_one_rmrr,
 +.cb[ACPI_DMAR_TYPE_ROOT_ATS] = dmar_parse_one_atsr,
 +.cb[ACPI_DMAR_TYPE_HARDWARE_AFFINITY] = dmar_parse_one_rhsa,
 +.cb[ACPI_DMAR_TYPE_NAMESPACE] = dmar_parse_one_andd,
 +};
  
  /*
   * Do it again, earlier dmar_tbl mapping could be mapped with
 @@ -519,51 +589,10 @@ parse_dmar_table(void)
  }
  
  pr_info(Host address width %d\n, dmar-width + 1);
 -
 -entry_header = (struct acpi_dmar_header *)(dmar + 1);
 -while (((unsigned long)entry_header) 
 -(((unsigned long)dmar) + dmar_tbl-length)) {
 -/* 

Re: [Patch Part3 V5 0/8] Enable support of Intel DMAR device hotplug

2014-09-16 Thread Jiang Liu


On 2014/9/15 15:54, Yijing Wang wrote:
 I built and boot this series in Huawei RH5885 (Intel(R) Xeon(R) CPU E7- 4807, 
 two IOHs and two IOMMUs),
 It works fine, IRQ remap and DMA remap are both look good.
 But because my platform BIOS has no _DSM, so I didn't test the hotplug case 
 yet.
 
 Thanks!
 Yijing.
Hi Yijing,
Thanks for your great effort to review and test this patch set!
Regards!
Gerry
 
 
 On 2014/9/12 10:10, Jiang Liu wrote:
 When hot plugging a descrete IOH or a physical processor with embedded
 IIO, we need to handle DMAR(or IOMMU) unit in the PCIe host bridge if
 DMAR is in use. This patch set tries to enhance current DMAR/IOMMU/IR
 drivers to support hotplug and is based on latest Linus master branch.

 All prerequisite patches to support DMAR device hotplug have been merged
 into the mainstream kernel, and this is the last patch set to enable
 DMAR device hotplug.

 You may access the patch set at:
 https://github.com/jiangliu/linux.git iommu/hotplug_v5

 This patch set has been tested on Intel development machine.
 Appreciate any comments and tests.

 Patch 1-4 enhances DMAR framework to support hotplug
 Patch 5 enhances Intel interrupt remapping driver to support hotplug
 Patch 6 enhances error handling in Intel IR driver
 Patch 7 enhance Intel IOMMU to support hotplug
 Patch 8 enhance ACPI pci_root driver to handle DMAR units

 Jiang Liu (8):
   iommu/vt-d: Introduce helper function dmar_walk_resources()
   iommu/vt-d: Dynamically allocate and free seq_id for DMAR units
   iommu/vt-d: Implement DMAR unit hotplug framework
   iommu/vt-d: Search for ACPI _DSM method for DMAR hotplug
   iommu/vt-d: Enhance intel_irq_remapping driver to support DMAR unit
 hotplug
   iommu/vt-d: Enhance error recovery in function
 intel_enable_irq_remapping()
   iommu/vt-d: Enhance intel-iommu driver to support DMAR unit hotplug
   pci, ACPI, iommu: Enhance pci_root to support DMAR device hotplug

  drivers/acpi/pci_root.c |   16 +-
  drivers/iommu/dmar.c|  532 
 ---
  drivers/iommu/intel-iommu.c |  297 ++-
  drivers/iommu/intel_irq_remapping.c |  233 +++
  include/linux/dmar.h|   50 +++-
  5 files changed, 888 insertions(+), 240 deletions(-)

 
 
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [Patch Part3 V5 5/8] iommu/vt-d: Enhance intel_irq_remapping driver to support DMAR unit hotplug

2014-09-16 Thread Yijing Wang
On 2014/9/16 15:00, Jiang Liu wrote:
 On 2014/9/15 10:20, Yijing Wang wrote:
 +static void ir_remove_ioapic_hpet_scope(struct intel_iommu *iommu)
 +{
 +   int i;
  
 -   ir_parse_one_hpet_scope(scope, iommu);
 -   }
 -   start += scope-length;
 -   }
 +   for (i = 0; i  MAX_HPET_TBS; i++)
 +   if (ir_hpet[i].iommu == iommu)
 +   ir_hpet[i].iommu = NULL;

 Hi Gerry, why not reset whole ir_hpe and ir_ioapic data struct?
 Hi Yijing,
   Thanks for review. Zero is legal for id, bus and devfn in
 struct ioapic_scope and struct hpet_scope. So we use domain field
 as a flag to mark entry valid or invalid and only reset iommu field.

Hi Gerry, use iommu field as a flag to mark entry valid may be not safe enough,
I found map_hpet_to_ir() and map_ioapic_to_ir() still only check the id field 
to return the valid iommu.

What about this case:
E.g. ir_hpet[2].id = N, ir_hpet[2].iommu = NULL, ir_hpet[4].id = N, 
ir_hpet[4].iommu = iommu;

ir_hpet[2] maybe released yet, and the hpet now has been saved in ir_hpet[4], 
but map_hpet_to_irq()
will return the wrong iommu(NULL).


static struct intel_iommu *map_hpet_to_ir(u8 hpet_id)
{
int i;

for (i = 0; i  MAX_HPET_TBS; i++)
if (ir_hpet[i].id == hpet_id)
return ir_hpet[i].iommu;
return NULL;
}

 
 Regards!
 Gerry



  
 -   return 0;
 +   for (i = 0; i  MAX_IO_APICS; i++)
 +   if (ir_ioapic[i].iommu == iommu)
 +   ir_ioapic[i].iommu = NULL;
  }
  

 --
 To unsubscribe from this list: send the line unsubscribe linux-kernel in
 the body of a message to majord...@vger.kernel.org
 More majordomo info at  http://vger.kernel.org/majordomo-info.html
 Please read the FAQ at  http://www.tux.org/lkml/

 
 .
 


-- 
Thanks!
Yijing

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [Patch Part3 V5 1/8] iommu/vt-d: Introduce helper function dmar_walk_resources()

2014-09-16 Thread Yijing Wang
  #include irq_remapping.h
  
 +typedef int (*dmar_res_handler_t)(struct acpi_dmar_header *, void *);
 +struct dmar_res_callback {
 +   dmar_res_handler_t  cb[ACPI_DMAR_TYPE_RESERVED];
 +   void*arg[ACPI_DMAR_TYPE_RESERVED];
 +   boolignore_unhandled;
 +   boolprint_entry;

 Why do we need a switch to control print ?
 We will walk DMAR entries several times during hotplug and only
 want to print once.

Fine, thanks for your explanation.

 

 +};
 +
  
 +static int dmar_walk_resources(struct acpi_dmar_header *start, size_t len,
 +  struct dmar_res_callback *cb)

 The name dmar_walk_resources easily make people think this is related with 
 I/O or memory resources.
 Do you have a better idea of this ?  What about dmar_walk_remapping_entry() 
 or dmar_walk_remapping_structure() ?
 Good suggestion, I like dmar_walk_remapping_entries().

 +{
 +   int ret = 0;
 +   struct acpi_dmar_header *iter, *next;
 +   struct acpi_dmar_header *end = ((void *)start) + len;
 +
 +   for (iter = start; iter  end  ret == 0; iter = next) {
 +   next = (void *)iter + iter-length;
 +   if (iter-length == 0) {
 +   /* Avoid looping forever on bad ACPI tables */
 +   pr_debug(FW_BUG Invalid 0-length structure\n);

 What about use pr_warn() instead of pr_debug(), pr_debug() default is off.
 It seems a common practice for BIOS engineer to mark the last entry with
 zero length. So it will be annoying if we generate this debug message
 on product kernel.

OK.

 

 +   break;
 +   } else if (next  end) {
 +   /* Avoid passing table end */
 +   pr_warn(FW_BUG record passes table end\n);
 +   ret = -EINVAL;
 +   break;
 +   }
 +
 +   if (cb-print_entry)
 +   dmar_table_print_dmar_entry(iter);
 +
 +   if (iter-type = ACPI_DMAR_TYPE_RESERVED) {
 +   /* continue for forward compatibility */
 +   pr_debug(Unknown DMAR structure type %d\n,
 +iter-type);

 Same as above.
 This is typically caused by new DMAR specification. It will also be
 annoying too if  we also generate this debug message on an newer
 hardware platform with older linux kernel.

OK.

 

 +   } else if (cb-cb[iter-type]) {
 +   ret = cb-cb[iter-type](iter, cb-arg[iter-type]);
 +   } else if (!cb-ignore_unhandled) {
 +   pr_warn(No handler for DMAR structure type %d\n,

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [Patch Part3 V5 5/8] iommu/vt-d: Enhance intel_irq_remapping driver to support DMAR unit hotplug

2014-09-16 Thread Jiang Liu


On 2014/9/16 15:53, Yijing Wang wrote:
 On 2014/9/16 15:00, Jiang Liu wrote:
 On 2014/9/15 10:20, Yijing Wang wrote:
 +static void ir_remove_ioapic_hpet_scope(struct intel_iommu *iommu)
 +{
 +  int i;
  
 -  ir_parse_one_hpet_scope(scope, iommu);
 -  }
 -  start += scope-length;
 -  }
 +  for (i = 0; i  MAX_HPET_TBS; i++)
 +  if (ir_hpet[i].iommu == iommu)
 +  ir_hpet[i].iommu = NULL;

 Hi Gerry, why not reset whole ir_hpe and ir_ioapic data struct?
 Hi Yijing,
  Thanks for review. Zero is legal for id, bus and devfn in
 struct ioapic_scope and struct hpet_scope. So we use domain field
 as a flag to mark entry valid or invalid and only reset iommu field.
 
 Hi Gerry, use iommu field as a flag to mark entry valid may be not safe 
 enough,
 I found map_hpet_to_ir() and map_ioapic_to_ir() still only check the id field 
 to return the valid iommu.
 
 What about this case:
 E.g. ir_hpet[2].id = N, ir_hpet[2].iommu = NULL, ir_hpet[4].id = N, 
 ir_hpet[4].iommu = iommu;
 
 ir_hpet[2] maybe released yet, and the hpet now has been saved in ir_hpet[4], 
 but map_hpet_to_irq()
 will return the wrong iommu(NULL).
Hi Yijing,
Good catch, I will enhance map_hpet_to_ir() and map_ioapic_to_ir().
Regards!
Gerry
 
 
 static struct intel_iommu *map_hpet_to_ir(u8 hpet_id)
 {
   int i;
 
   for (i = 0; i  MAX_HPET_TBS; i++)
   if (ir_hpet[i].id == hpet_id)
   return ir_hpet[i].iommu;
   return NULL;
 }
 

 Regards!
 Gerry



  
 -  return 0;
 +  for (i = 0; i  MAX_IO_APICS; i++)
 +  if (ir_ioapic[i].iommu == iommu)
 +  ir_ioapic[i].iommu = NULL;
  }
  

 --
 To unsubscribe from this list: send the line unsubscribe linux-kernel in
 the body of a message to majord...@vger.kernel.org
 More majordomo info at  http://vger.kernel.org/majordomo-info.html
 Please read the FAQ at  http://www.tux.org/lkml/


 .

 
 
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH v1 03/21] MSI: Remove the redundant irq_set_chip_data()

2014-09-16 Thread Yijing Wang
 arch_teardown_msi_irq() expects to find the msi_chip in the irq
 chip_data field. As this means drivers don't have any reasonable other
 possibility to stuff things into this field, I think it would make sense
 to do the cleanup the other way around: keep the irq_set_chip_data
 arch_setup_msi_irq() and rip it out of the individual drivers.

 Hi Lucas, thanks for your review and comments!
 irq_set_chip_data() should not be placed in MSI core functions, because 
 other arch like x86,
 use irq_data-chip_data to stores irq_cfg. So how to set the chip_data is 
 arch dependent.
 And this series is mainly to use MSI chip framework in all platforms.
 Currently, only ARM platform MSI drivers use the chip_data to store 
 msi_chip, and the drivers call
 irq_set_chip_data() in their driver already. So I thought we should clean up 
 it in MSI core code.

 Okay I see your point, so the cleanup done this way is okay.
 
 But then this still introduces a problem: arch_teardown_msi_irq()
 expects to find the msi_chip in the chip_data field, which is okay for
 all ARM PCI host drivers, but not for other arch MSI chips.
 
 You fix this by completely removing arch_teardown_msi_irq() at the end
 of the series, but this still has the potential to introduce issues for
 other arches than ARM within the series. So this patch should include a
 change to replace the line
 
 struct msi_chip *chip = irq_get_chip_data(irq);
 
 with something that doesn't rely on the msi_chip being in the irq
 chip_data field.

OK, I will update arch_teardown_msi_irq() in this patch, thanks!

Thanks!
Yijing.

 
 Regards,
 Lucas
 


-- 
Thanks!
Yijing

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH v2 06/18] iommu: exynos: don't read version register on every tlb operation

2014-09-16 Thread Marek Szyprowski
This patch removes reading of REG_MMU_VERSION register on every tlb
operation and caches SYSMMU version in driver's internal data.

Signed-off-by: Marek Szyprowski m.szyprow...@samsung.com
---
 drivers/iommu/exynos-iommu.c | 13 +
 1 file changed, 5 insertions(+), 8 deletions(-)

diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c
index d037e87a1fe5..73499b05e62e 100644
--- a/drivers/iommu/exynos-iommu.c
+++ b/drivers/iommu/exynos-iommu.c
@@ -212,6 +212,7 @@ struct sysmmu_drvdata {
spinlock_t lock;
struct iommu_domain *domain;
phys_addr_t pgtable;
+   int version;
 };
 
 static bool set_sysmmu_active(struct sysmmu_drvdata *data)
@@ -238,11 +239,6 @@ static void sysmmu_unblock(void __iomem *sfrbase)
__raw_writel(CTRL_ENABLE, sfrbase + REG_MMU_CTRL);
 }
 
-static unsigned int __raw_sysmmu_version(struct sysmmu_drvdata *data)
-{
-   return MMU_RAW_VER(__raw_readl(data-sfrbase + REG_MMU_VERSION));
-}
-
 static bool sysmmu_block(void __iomem *sfrbase)
 {
int i = 120;
@@ -402,7 +398,7 @@ static void __sysmmu_init_config(struct sysmmu_drvdata 
*data)
unsigned int cfg = CFG_LRU | CFG_QOS(15);
unsigned int ver;
 
-   ver = __raw_sysmmu_version(data);
+   ver = MMU_RAW_VER(__raw_readl(data-sfrbase + REG_MMU_VERSION));
if (MMU_MAJ_VER(ver) == 3) {
if (MMU_MIN_VER(ver) = 2) {
cfg |= CFG_FLPDCACHE;
@@ -416,6 +412,7 @@ static void __sysmmu_init_config(struct sysmmu_drvdata 
*data)
}
 
__raw_writel(cfg, data-sfrbase + REG_MMU_CFG);
+   data-version = ver;
 }
 
 static void __sysmmu_enable_nocount(struct sysmmu_drvdata *data)
@@ -525,7 +522,7 @@ static bool exynos_sysmmu_disable(struct device *dev)
 static void __sysmmu_tlb_invalidate_flpdcache(struct sysmmu_drvdata *data,
  sysmmu_iova_t iova)
 {
-   if (__raw_sysmmu_version(data) == MAKE_MMU_VER(3, 3))
+   if (data-version == MAKE_MMU_VER(3, 3))
__raw_writel(iova | 0x1, data-sfrbase + REG_MMU_FLUSH_ENTRY);
 }
 
@@ -574,7 +571,7 @@ static void sysmmu_tlb_invalidate_entry(struct device *dev, 
sysmmu_iova_t iova,
 * 1MB page can be cached in one of all sets.
 * 64KB page can be one of 16 consecutive sets.
 */
-   if (MMU_MAJ_VER(__raw_sysmmu_version(data)) == 2)
+   if (MMU_MAJ_VER(data-version) == 2)
num_inv = min_t(unsigned int, size / PAGE_SIZE, 64);
 
if (sysmmu_block(data-sfrbase)) {
-- 
1.9.2

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH v2 04/18] clk: exynos: add missing smmu_g2d clock and update comments

2014-09-16 Thread Marek Szyprowski
This patch adds missing smmu_g2d clock implementation and updates
comment about Exynos4 clocks from 278-282 range. Those clocks are
available on all Exynos4 SoC series, so the misleading comment has been
removed.

Signed-off-by: Marek Szyprowski m.szyprow...@samsung.com
Acked-by: Tomasz Figa t.f...@samsung.com
---
 drivers/clk/samsung/clk-exynos4.c   |  1 +
 include/dt-bindings/clock/exynos4.h | 10 +-
 2 files changed, 6 insertions(+), 5 deletions(-)

diff --git a/drivers/clk/samsung/clk-exynos4.c 
b/drivers/clk/samsung/clk-exynos4.c
index ac163d7f5bc3..12a7cc3b5953 100644
--- a/drivers/clk/samsung/clk-exynos4.c
+++ b/drivers/clk/samsung/clk-exynos4.c
@@ -1183,6 +1183,7 @@ static struct samsung_gate_clock exynos4x12_gate_clks[] 
__initdata = {
GATE(CLK_SPI1_ISP, spi1_isp, aclk200, E4X12_GATE_ISP1, 13,
CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
GATE(CLK_G2D, g2d, aclk200, GATE_IP_DMC, 23, 0, 0),
+   GATE(CLK_SMMU_G2D, smmu_g2d, aclk200, GATE_IP_DMC, 24, 0, 0),
GATE(CLK_TMU_APBIF, tmu_apbif, aclk100, E4X12_GATE_IP_PERIR, 17, 0,
0),
 };
diff --git a/include/dt-bindings/clock/exynos4.h 
b/include/dt-bindings/clock/exynos4.h
index 459bd2bd411f..fb9816354079 100644
--- a/include/dt-bindings/clock/exynos4.h
+++ b/include/dt-bindings/clock/exynos4.h
@@ -115,11 +115,11 @@
 #define CLK_SMMU_MFCR  275
 #define CLK_G3D276
 #define CLK_G2D277
-#define CLK_ROTATOR278 /* Exynos4210 only */
-#define CLK_MDMA   279 /* Exynos4210 only */
-#define CLK_SMMU_G2D   280 /* Exynos4210 only */
-#define CLK_SMMU_ROTATOR   281 /* Exynos4210 only */
-#define CLK_SMMU_MDMA  282 /* Exynos4210 only */
+#define CLK_ROTATOR278
+#define CLK_MDMA   279
+#define CLK_SMMU_G2D   280
+#define CLK_SMMU_ROTATOR   281
+#define CLK_SMMU_MDMA  282
 #define CLK_FIMD0  283
 #define CLK_MIE0   284
 #define CLK_MDNIE0 285 /* Exynos4412 only */
-- 
1.9.2

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH v2 00/18] Exynos SYSMMU (IOMMU) integration with DT and DMA-mapping subsystem

2014-09-16 Thread Marek Szyprowski
Hello Everyone,

This is yet another attempt to finally make Exynos SYSMMU driver fully
integrated with DMA-mapping subsystem.

Previous approach is available here: https://lkml.org/lkml/2014/8/5/183

I meantime, there have been a discussion about the way the iommu driver
should be integrated with dma-mapping subsystem, which resulted in [RFC
PATCH v3 0/7] Introduce automatic DMA configuration for IOMMU masters
patches prepared by Will Deacon:
http://www.spinics.net/lists/arm-kernel/msg362076.html 
Those patches removed the need to use bus-specific notifiers for
initialization.

Main changes since previous version of my patches:

1. rebased onto [RFC PATCH v3 0/7] Introduce automatic DMA
configuration for IOMMU masters patches, changed initialization from
bus notifiers to DT related callbacks

2. removed support for separate IO address spaces - this will be
discussed separately after the basic support gets merged

3. removed support for power domain notifier-based runtime power
management - this also will be discussed separately later

I hope that the driver with above changes will be easier to be merged to
v3.18.

Best regards
Marek Szyprowski
Samsung RD Institute Poland



Patch summary:

Marek Szyprowski (18):
  arm: dma-mapping: arm_iommu_attach_device: automatically set
max_seg_size
  arm: exynos: bind power domains earlier, on device creation
  drm: exynos: detach from default dma-mapping domain on init
  clk: exynos: add missing smmu_g2d clock and update comments
  ARM: DTS: Exynos4: add System MMU nodes
  iommu: exynos: don't read version register on every tlb operation
  iommu: exynos: remove unused functions
  iommu: exynos: remove useless spinlock
  iommu: exynos: refactor function parameters to simplify code
  iommu: exynos: remove unused functions, part 2
  iommu: exynos: remove useless device_add/remove callbacks
  iommu: exynos: add support for binding more than one sysmmu to master
device
  iommu: exynos: add support for runtime_pm
  iommu: exynos: rename variables to reflect their purpose
  iommu: exynos: document internal structures
  iommu: exynos: remove excessive includes and sort others
alphabetically
  iommu: exynos: init from dt-specific callback instead of initcall
  iommu: exynos: add callback for initializing devices from device tree

 arch/arm/boot/dts/exynos4.dtsi| 117 +++
 arch/arm/boot/dts/exynos4210.dtsi |  23 ++
 arch/arm/boot/dts/exynos4x12.dtsi |  82 +
 arch/arm/mach-exynos/pm_domains.c |  12 +-
 arch/arm/mm/dma-mapping.c |  16 +
 drivers/clk/samsung/clk-exynos4.c |   1 +
 drivers/gpu/drm/exynos/exynos_drm_iommu.c |   3 +
 drivers/iommu/exynos-iommu.c  | 494 ++
 include/dt-bindings/clock/exynos4.h   |  10 +-
 9 files changed, 483 insertions(+), 275 deletions(-)

-- 
1.9.2

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH v2 01/18] arm: dma-mapping: arm_iommu_attach_device: automatically set max_seg_size

2014-09-16 Thread Marek Szyprowski
If device has no max_seg_size set, we assume that there is no limit and
force it to DMA_BIT_MASK(32) to always use contiguous mappings in DMA
address space.

Signed-off-by: Marek Szyprowski m.szyprow...@samsung.com
---
 arch/arm/mm/dma-mapping.c | 16 
 1 file changed, 16 insertions(+)

diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
index bcd5f836f27e..84705e24571b 100644
--- a/arch/arm/mm/dma-mapping.c
+++ b/arch/arm/mm/dma-mapping.c
@@ -2050,6 +2050,22 @@ int arm_iommu_attach_device(struct device *dev,
 {
int err;
 
+   /*
+* if device has no max_seg_size set, we assume that there is no limit
+* and force it to DMA_BIT_MASK(32) to always use contiguous mappings
+* in DMA address space
+*/
+   if (!dev-dma_parms) {
+   dev-dma_parms = kzalloc(sizeof(*dev-dma_parms), GFP_KERNEL);
+   if (!dev-dma_parms)
+   return -ENOMEM;
+   }
+   if (!dev-dma_parms-max_segment_size) {
+   err = dma_set_max_seg_size(dev, DMA_BIT_MASK(32));
+   if (err)
+   return err;
+   }
+
err = iommu_attach_device(mapping-domain, dev);
if (err)
return err;
-- 
1.9.2

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH v2 02/18] arm: exynos: bind power domains earlier, on device creation

2014-09-16 Thread Marek Szyprowski
This patches change initialization time of power domain driver from client
device driver bind to device creation. This lets other core drivers to
register power domain notifiers before client driver is bound.

Signed-off-by: Marek Szyprowski m.szyprow...@samsung.com
---
 arch/arm/mach-exynos/pm_domains.c | 12 ++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/arch/arm/mach-exynos/pm_domains.c 
b/arch/arm/mach-exynos/pm_domains.c
index fd76e1b5a471..1d368a26528c 100644
--- a/arch/arm/mach-exynos/pm_domains.c
+++ b/arch/arm/mach-exynos/pm_domains.c
@@ -159,13 +159,13 @@ static int exynos_pm_notifier_call(struct notifier_block 
*nb,
struct device *dev = data;
 
switch (event) {
-   case BUS_NOTIFY_BIND_DRIVER:
+   case BUS_NOTIFY_ADD_DEVICE:
if (dev-of_node)
exynos_read_domain_from_dt(dev);
 
break;
 
-   case BUS_NOTIFY_UNBOUND_DRIVER:
+   case BUS_NOTIFY_DEL_DEVICE:
exynos_remove_device_from_domain(dev);
 
break;
@@ -177,6 +177,13 @@ static struct notifier_block platform_nb = {
.notifier_call = exynos_pm_notifier_call,
 };
 
+static int exynos_pm_domain_add(struct device *dev, void *priv)
+{
+   if (dev-of_node)
+   exynos_read_domain_from_dt(dev);
+   return 0;
+}
+
 static __init int exynos4_pm_init_power_domain(void)
 {
struct platform_device *pdev;
@@ -236,6 +243,7 @@ no_clk:
}
 
bus_register_notifier(platform_bus_type, platform_nb);
+   bus_for_each_dev(platform_bus_type, NULL, NULL, exynos_pm_domain_add);
 
return 0;
 }
-- 
1.9.2

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH v2 05/18] ARM: DTS: Exynos4: add System MMU nodes

2014-09-16 Thread Marek Szyprowski
This patch adds System MMU nodes that are specific to Exynos4210/4x12 series.

Signed-off-by: Marek Szyprowski m.szyprow...@samsung.com
---
 arch/arm/boot/dts/exynos4.dtsi| 117 ++
 arch/arm/boot/dts/exynos4210.dtsi |  23 
 arch/arm/boot/dts/exynos4x12.dtsi |  82 ++
 3 files changed, 222 insertions(+)

diff --git a/arch/arm/boot/dts/exynos4.dtsi b/arch/arm/boot/dts/exynos4.dtsi
index e0278ecbc816..bfc19ec5 100644
--- a/arch/arm/boot/dts/exynos4.dtsi
+++ b/arch/arm/boot/dts/exynos4.dtsi
@@ -174,6 +174,7 @@
clock-names = fimc, sclk_fimc;
samsung,power-domain = pd_cam;
samsung,sysreg = sys_reg;
+   iommus = sysmmu_fimc0;
status = disabled;
};
 
@@ -185,6 +186,7 @@
clock-names = fimc, sclk_fimc;
samsung,power-domain = pd_cam;
samsung,sysreg = sys_reg;
+   iommus = sysmmu_fimc1;
status = disabled;
};
 
@@ -196,6 +198,7 @@
clock-names = fimc, sclk_fimc;
samsung,power-domain = pd_cam;
samsung,sysreg = sys_reg;
+   iommus = sysmmu_fimc2;
status = disabled;
};
 
@@ -207,6 +210,7 @@
clock-names = fimc, sclk_fimc;
samsung,power-domain = pd_cam;
samsung,sysreg = sys_reg;
+   iommus = sysmmu_fimc3;
status = disabled;
};
 
@@ -395,6 +399,8 @@
clocks = clock CLK_MFC;
clock-names = mfc;
status = disabled;
+   iommus = sysmmu_mfc_l, sysmmu_mfc_r;
+   iommu-names = left, right;
};
 
serial_0: serial@1380 {
@@ -643,6 +649,117 @@
clock-names = sclk_fimd, fimd;
samsung,power-domain = pd_lcd0;
samsung,sysreg = sys_reg;
+   iommus = sysmmu_fimd0;
status = disabled;
};
+
+   sysmmu_mfc_l: sysmmu@1362 {
+   compatible = samsung,exynos-sysmmu;
+   reg = 0x1362 0x1000;
+   interrupt-parent = combiner;
+   interrupts = 5 5;
+   clock-names = sysmmu, master;
+   clocks = clock CLK_SMMU_MFCL, clock CLK_MFC;
+   samsung,power-domain = pd_mfc;
+   #iommu-cells = 0;
+   };
+
+   sysmmu_mfc_r: sysmmu@1363 {
+   compatible = samsung,exynos-sysmmu;
+   reg = 0x1363 0x1000;
+   interrupt-parent = combiner;
+   interrupts = 5 6;
+   clock-names = sysmmu, master;
+   clocks = clock CLK_SMMU_MFCR, clock CLK_MFC;
+   samsung,power-domain = pd_mfc;
+   #iommu-cells = 0;
+   };
+
+   sysmmu_tv: sysmmu@12E2 {
+   compatible = samsung,exynos-sysmmu;
+   reg = 0x12E2 0x1000;
+   interrupt-parent = combiner;
+   interrupts = 5 4;
+   clock-names = sysmmu, master;
+   clocks = clock CLK_SMMU_TV, clock CLK_MIXER;
+   samsung,power-domain = pd_tv;
+   #iommu-cells = 0;
+   };
+
+   sysmmu_fimc0: sysmmu@11A2 {
+   compatible = samsung,exynos-sysmmu;
+   reg = 0x11A2 0x1000;
+   interrupt-parent = combiner;
+   interrupts = 4 2;
+   clock-names = sysmmu, master;
+   clocks = clock CLK_SMMU_FIMC0, clock CLK_FIMC0;
+   samsung,power-domain = pd_cam;
+   #iommu-cells = 0;
+   };
+
+   sysmmu_fimc1: sysmmu@11A3 {
+   compatible = samsung,exynos-sysmmu;
+   reg = 0x11A3 0x1000;
+   interrupt-parent = combiner;
+   interrupts = 4 3;
+   clock-names = sysmmu, master;
+   clocks = clock CLK_SMMU_FIMC1, clock CLK_FIMC1;
+   samsung,power-domain = pd_cam;
+   #iommu-cells = 0;
+   };
+
+   sysmmu_fimc2: sysmmu@11A4 {
+   compatible = samsung,exynos-sysmmu;
+   reg = 0x11A4 0x1000;
+   interrupt-parent = combiner;
+   interrupts = 4 4;
+   clock-names = sysmmu, master;
+   clocks = clock CLK_SMMU_FIMC2, clock CLK_FIMC2;
+   samsung,power-domain = pd_cam;
+   #iommu-cells = 0;
+   };
+
+   sysmmu_fimc3: sysmmu@11A5 {
+   compatible = samsung,exynos-sysmmu;
+   reg = 0x11A5 0x1000;
+   interrupt-parent = combiner;
+   interrupts = 4 5;
+   clock-names = sysmmu, master;
+  

[PATCH v2 07/18] iommu: exynos: remove unused functions

2014-09-16 Thread Marek Szyprowski
This patch removes two unneeded functions, which are not a part of
generic IOMMU API and were never used by any other driver.

Signed-off-by: Marek Szyprowski m.szyprow...@samsung.com
---
 drivers/iommu/exynos-iommu.c | 31 ---
 1 file changed, 31 deletions(-)

diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c
index 73499b05e62e..91feeca56abc 100644
--- a/drivers/iommu/exynos-iommu.c
+++ b/drivers/iommu/exynos-iommu.c
@@ -490,13 +490,6 @@ static int __exynos_sysmmu_enable(struct device *dev, 
phys_addr_t pgtable,
return ret;
 }
 
-int exynos_sysmmu_enable(struct device *dev, phys_addr_t pgtable)
-{
-   BUG_ON(!memblock_is_memory(pgtable));
-
-   return __exynos_sysmmu_enable(dev, pgtable, NULL);
-}
-
 static bool exynos_sysmmu_disable(struct device *dev)
 {
unsigned long flags;
@@ -588,30 +581,6 @@ static void sysmmu_tlb_invalidate_entry(struct device 
*dev, sysmmu_iova_t iova,
spin_unlock_irqrestore(data-lock, flags);
 }
 
-void exynos_sysmmu_tlb_invalidate(struct device *dev)
-{
-   struct exynos_iommu_owner *owner = dev-archdata.iommu;
-   unsigned long flags;
-   struct sysmmu_drvdata *data;
-
-   data = dev_get_drvdata(owner-sysmmu);
-
-   spin_lock_irqsave(data-lock, flags);
-   if (is_sysmmu_active(data)) {
-   if (!IS_ERR(data-clk_master))
-   clk_enable(data-clk_master);
-   if (sysmmu_block(data-sfrbase)) {
-   __sysmmu_tlb_invalidate(data-sfrbase);
-   sysmmu_unblock(data-sfrbase);
-   }
-   if (!IS_ERR(data-clk_master))
-   clk_disable(data-clk_master);
-   } else {
-   dev_dbg(dev, disabled. Skipping TLB invalidation\n);
-   }
-   spin_unlock_irqrestore(data-lock, flags);
-}
-
 static int __init exynos_sysmmu_probe(struct platform_device *pdev)
 {
int irq, ret;
-- 
1.9.2

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH v2 10/18] iommu: exynos: remove unused functions, part 2

2014-09-16 Thread Marek Szyprowski
After refactoring functions to use pointer to struct sysmmu_drvdata
directly, some functions became useless and thus never used, so remove
them completely.

Signed-off-by: Marek Szyprowski m.szyprow...@samsung.com
---
 drivers/iommu/exynos-iommu.c | 43 ---
 1 file changed, 43 deletions(-)

diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c
index ef30890f4069..b271348a4ec1 100644
--- a/drivers/iommu/exynos-iommu.c
+++ b/drivers/iommu/exynos-iommu.c
@@ -457,49 +457,6 @@ static int __sysmmu_enable(struct sysmmu_drvdata *data,
return ret;
 }
 
-/* __exynos_sysmmu_enable: Enables System MMU
- *
- * returns -error if an error occurred and System MMU is not enabled,
- * 0 if the System MMU has been just enabled and 1 if System MMU was already
- * enabled before.
- */
-static int __exynos_sysmmu_enable(struct device *dev, phys_addr_t pgtable,
- struct iommu_domain *domain)
-{
-   int ret = 0;
-   unsigned long flags;
-   struct exynos_iommu_owner *owner = dev-archdata.iommu;
-   struct sysmmu_drvdata *data;
-
-   BUG_ON(!has_sysmmu(dev));
-
-   data = dev_get_drvdata(owner-sysmmu);
-
-   ret = __sysmmu_enable(data, pgtable, domain);
-   if (ret = 0)
-   data-master = dev;
-
-   return ret;
-}
-
-static bool exynos_sysmmu_disable(struct device *dev)
-{
-   unsigned long flags;
-   bool disabled = true;
-   struct exynos_iommu_owner *owner = dev-archdata.iommu;
-   struct sysmmu_drvdata *data;
-
-   BUG_ON(!has_sysmmu(dev));
-
-   data = dev_get_drvdata(owner-sysmmu);
-
-   disabled = __sysmmu_disable(data);
-   if (disabled)
-   data-master = NULL;
-
-   return disabled;
-}
-
 static void __sysmmu_tlb_invalidate_flpdcache(struct sysmmu_drvdata *data,
  sysmmu_iova_t iova)
 {
-- 
1.9.2

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH v2 08/18] iommu: exynos: remove useless spinlock

2014-09-16 Thread Marek Szyprowski
This patch removes useless spinlocks and other unused members from
struct exynos_iommu_owner. There is no point is protecting this
structure by spinlock because content of this structure doesn't change
and other structures have their own spinlocks.

Signed-off-by: Marek Szyprowski m.szyprow...@samsung.com
---
 drivers/iommu/exynos-iommu.c | 11 ---
 1 file changed, 11 deletions(-)

diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c
index 91feeca56abc..ae2703ed91d8 100644
--- a/drivers/iommu/exynos-iommu.c
+++ b/drivers/iommu/exynos-iommu.c
@@ -189,9 +189,6 @@ struct exynos_iommu_owner {
struct list_head client; /* entry of exynos_iommu_domain.clients */
struct device *dev;
struct device *sysmmu;
-   struct iommu_domain *domain;
-   void *vmm_data; /* IO virtual memory manager's data */
-   spinlock_t lock;/* Lock to preserve consistency of System MMU */
 };
 
 struct exynos_iommu_domain {
@@ -477,16 +474,12 @@ static int __exynos_sysmmu_enable(struct device *dev, 
phys_addr_t pgtable,
 
BUG_ON(!has_sysmmu(dev));
 
-   spin_lock_irqsave(owner-lock, flags);
-
data = dev_get_drvdata(owner-sysmmu);
 
ret = __sysmmu_enable(data, pgtable, domain);
if (ret = 0)
data-master = dev;
 
-   spin_unlock_irqrestore(owner-lock, flags);
-
return ret;
 }
 
@@ -499,16 +492,12 @@ static bool exynos_sysmmu_disable(struct device *dev)
 
BUG_ON(!has_sysmmu(dev));
 
-   spin_lock_irqsave(owner-lock, flags);
-
data = dev_get_drvdata(owner-sysmmu);
 
disabled = __sysmmu_disable(data);
if (disabled)
data-master = NULL;
 
-   spin_unlock_irqrestore(owner-lock, flags);
-
return disabled;
 }
 
-- 
1.9.2

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH v2 12/18] iommu: exynos: add support for binding more than one sysmmu to master device

2014-09-16 Thread Marek Szyprowski
This patch adds support for assigning more than one SYSMMU controller to
the master device. This has been achieved simply by chaning the struct
device pointer in struct exynos_iommu_owner into the list of struct
sysmmu_drvdata of all controllers assigned to the given master device.

Signed-off-by: Marek Szyprowski m.szyprow...@samsung.com
---
 drivers/iommu/exynos-iommu.c | 11 +--
 1 file changed, 5 insertions(+), 6 deletions(-)

diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c
index 1b3f00726cd4..cf36cdecf335 100644
--- a/drivers/iommu/exynos-iommu.c
+++ b/drivers/iommu/exynos-iommu.c
@@ -186,7 +186,7 @@ static char *sysmmu_fault_name[SYSMMU_FAULTS_NUM] = {
 
 /* attached to dev.archdata.iommu of the master device */
 struct exynos_iommu_owner {
-   struct device *sysmmu;
+   struct list_head clients;
 };
 
 struct exynos_iommu_domain {
@@ -207,6 +207,7 @@ struct sysmmu_drvdata {
spinlock_t lock;
struct iommu_domain *domain;
struct list_head domain_node;
+   struct list_head owner_node;
phys_addr_t pgtable;
int version;
 };
@@ -694,8 +695,7 @@ static int exynos_iommu_attach_device(struct iommu_domain 
*domain,
if (!has_sysmmu(dev))
return -ENODEV;
 
-   data = dev_get_drvdata(owner-sysmmu);
-   if (data) {
+   list_for_each_entry(data, owner-clients, owner_node) {
ret = __sysmmu_enable(data, pagetable, domain);
if (ret = 0) {
data-master = dev;
@@ -723,7 +723,7 @@ static void exynos_iommu_detach_device(struct iommu_domain 
*domain,
 {
struct exynos_iommu_domain *priv = domain-priv;
phys_addr_t pagetable = virt_to_phys(priv-pgtable);
-   struct sysmmu_drvdata *data;
+   struct sysmmu_drvdata *data, *next;
unsigned long flags;
int found = 0;
 
@@ -731,14 +731,13 @@ static void exynos_iommu_detach_device(struct 
iommu_domain *domain,
return;
 
spin_lock_irqsave(priv-lock, flags);
-   list_for_each_entry(data, priv-clients, domain_node) {
+   list_for_each_entry_safe(data, next, priv-clients, domain_node) {
if (data-master == dev) {
if (__sysmmu_disable(data)) {
data-master = NULL;
list_del_init(data-domain_node);
}
found = true;
-   break;
}
}
spin_unlock_irqrestore(priv-lock, flags);
-- 
1.9.2

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH v2 11/18] iommu: exynos: remove useless device_add/remove callbacks

2014-09-16 Thread Marek Szyprowski
The driver doesn't need to do anything important in device add/remove
callbacks, because initialization will be done from device-tree specific
callbacks added later. IOMMU groups created by current code were never
used.

Signed-off-by: Marek Szyprowski m.szyprow...@samsung.com
---
 drivers/iommu/exynos-iommu.c | 28 
 1 file changed, 28 deletions(-)

diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c
index b271348a4ec1..1b3f00726cd4 100644
--- a/drivers/iommu/exynos-iommu.c
+++ b/drivers/iommu/exynos-iommu.c
@@ -1055,32 +1055,6 @@ static phys_addr_t exynos_iommu_iova_to_phys(struct 
iommu_domain *domain,
return phys;
 }
 
-static int exynos_iommu_add_device(struct device *dev)
-{
-   struct iommu_group *group;
-   int ret;
-
-   group = iommu_group_get(dev);
-
-   if (!group) {
-   group = iommu_group_alloc();
-   if (IS_ERR(group)) {
-   dev_err(dev, Failed to allocate IOMMU group\n);
-   return PTR_ERR(group);
-   }
-   }
-
-   ret = iommu_group_add_device(group, dev);
-   iommu_group_put(group);
-
-   return ret;
-}
-
-static void exynos_iommu_remove_device(struct device *dev)
-{
-   iommu_group_remove_device(dev);
-}
-
 static const struct iommu_ops exynos_iommu_ops = {
.domain_init = exynos_iommu_domain_init,
.domain_destroy = exynos_iommu_domain_destroy,
@@ -1089,8 +1063,6 @@ static const struct iommu_ops exynos_iommu_ops = {
.map = exynos_iommu_map,
.unmap = exynos_iommu_unmap,
.iova_to_phys = exynos_iommu_iova_to_phys,
-   .add_device = exynos_iommu_add_device,
-   .remove_device = exynos_iommu_remove_device,
.pgsize_bitmap = SECT_SIZE | LPAGE_SIZE | SPAGE_SIZE,
 };
 
-- 
1.9.2

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH v2 17/18] iommu: exynos: init from dt-specific callback instead of initcall

2014-09-16 Thread Marek Szyprowski
This patch introduces IOMMU_OF_DECLARE-based initialization to the
driver, which replaces subsys_initcall-based procedure.
exynos_iommu_of_setup ensures that each sysmmu controller is probed
before its master device. 

Signed-off-by: Marek Szyprowski m.szyprow...@samsung.com
---
 drivers/iommu/exynos-iommu.c | 32 +++-
 1 file changed, 31 insertions(+), 1 deletion(-)

diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c
index 5eb999d7653a..0d304c62956e 100644
--- a/drivers/iommu/exynos-iommu.c
+++ b/drivers/iommu/exynos-iommu.c
@@ -13,16 +13,21 @@
 #endif
 
 #include linux/clk.h
+#include linux/dma-mapping.h
 #include linux/err.h
 #include linux/io.h
 #include linux/iommu.h
 #include linux/interrupt.h
 #include linux/list.h
+#include linux/of.h
+#include linux/of_iommu.h
+#include linux/of_platform.h
 #include linux/platform_device.h
 #include linux/pm_runtime.h
 #include linux/slab.h
 
 #include asm/cacheflush.h
+#include asm/dma-iommu.h
 #include asm/pgtable.h
 
 typedef u32 sysmmu_iova_t;
@@ -1083,6 +1088,8 @@ static const struct iommu_ops exynos_iommu_ops = {
.pgsize_bitmap = SECT_SIZE | LPAGE_SIZE | SPAGE_SIZE,
 };
 
+static int init_done;
+
 static int __init exynos_iommu_init(void)
 {
int ret;
@@ -1115,6 +1122,8 @@ static int __init exynos_iommu_init(void)
goto err_set_iommu;
}
 
+   init_done = true;
+
return 0;
 err_set_iommu:
kmem_cache_free(lv2table_kmem_cache, zero_lv2_table);
@@ -1124,4 +1133,25 @@ err_reg_driver:
kmem_cache_destroy(lv2table_kmem_cache);
return ret;
 }
-subsys_initcall(exynos_iommu_init);
+
+static struct iommu_data exynos_of_data = {
+   .ops = exynos_iommu_ops,
+};
+
+static int __init exynos_iommu_of_setup(struct device_node *np)
+{
+   struct platform_device *pdev;
+
+   if (!init_done)
+   exynos_iommu_init();
+
+   pdev = of_platform_device_create(np, NULL, platform_bus_type.dev_root);
+   if (IS_ERR(pdev))
+   return PTR_ERR(pdev);
+
+   of_iommu_set_data(np, exynos_of_data);
+   return 0;
+}
+
+IOMMU_OF_DECLARE(exynos_iommu_of, samsung,exynos-sysmmu,
+exynos_iommu_of_setup);
-- 
1.9.2

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH v2 16/18] iommu: exynos: remove excessive includes and sort others alphabetically

2014-09-16 Thread Marek Szyprowski
Removed following unused includes: linux/mm.h, linux/errno.h,
linux/memblock.h and linux/export.h.

Signed-off-by: Marek Szyprowski m.szyprow...@samsung.com
---
 drivers/iommu/exynos-iommu.c | 14 +-
 1 file changed, 5 insertions(+), 9 deletions(-)

diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c
index a75b06365f97..5eb999d7653a 100644
--- a/drivers/iommu/exynos-iommu.c
+++ b/drivers/iommu/exynos-iommu.c
@@ -12,19 +12,15 @@
 #define DEBUG
 #endif
 
-#include linux/io.h
-#include linux/interrupt.h
-#include linux/platform_device.h
-#include linux/slab.h
-#include linux/pm_runtime.h
 #include linux/clk.h
 #include linux/err.h
-#include linux/mm.h
+#include linux/io.h
 #include linux/iommu.h
-#include linux/errno.h
+#include linux/interrupt.h
 #include linux/list.h
-#include linux/memblock.h
-#include linux/export.h
+#include linux/platform_device.h
+#include linux/pm_runtime.h
+#include linux/slab.h
 
 #include asm/cacheflush.h
 #include asm/pgtable.h
-- 
1.9.2

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH v2 18/18] iommu: exynos: add callback for initializing devices from device tree

2014-09-16 Thread Marek Szyprowski
This patch adds implementation of of_xlate callback, which prepares
masters device for attaching to IOMMU. This callback is called during
creating devices from device tree.

Signed-off-by: Marek Szyprowski m.szyprow...@samsung.com
---
 drivers/iommu/exynos-iommu.c | 28 
 1 file changed, 28 insertions(+)

diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c
index 0d304c62956e..6b8fe57d17f2 100644
--- a/drivers/iommu/exynos-iommu.c
+++ b/drivers/iommu/exynos-iommu.c
@@ -1077,6 +1077,33 @@ static phys_addr_t exynos_iommu_iova_to_phys(struct 
iommu_domain *iommu_domain,
return phys;
 }
 
+static int exynos_iommu_of_xlate(struct device *dev,
+struct of_phandle_args *spec)
+{
+   struct exynos_iommu_owner *owner = dev-archdata.iommu;
+   struct platform_device *sysmmu = of_find_device_by_node(spec-np);
+   struct sysmmu_drvdata *data;
+
+   if (!sysmmu)
+   return 0;
+
+   data = platform_get_drvdata(sysmmu);
+   if (!data)
+   return 0;
+
+   if (!owner) {
+   owner = kzalloc(sizeof(*owner), GFP_KERNEL);
+   if (!owner)
+   return 0;
+
+   INIT_LIST_HEAD(owner-clients);
+   dev-archdata.iommu = owner;
+   }
+
+   list_add_tail(data-owner_node, owner-clients);
+   return 1;
+}
+
 static const struct iommu_ops exynos_iommu_ops = {
.domain_init = exynos_iommu_domain_init,
.domain_destroy = exynos_iommu_domain_destroy,
@@ -1086,6 +1113,7 @@ static const struct iommu_ops exynos_iommu_ops = {
.unmap = exynos_iommu_unmap,
.iova_to_phys = exynos_iommu_iova_to_phys,
.pgsize_bitmap = SECT_SIZE | LPAGE_SIZE | SPAGE_SIZE,
+   .of_xlate = exynos_iommu_of_xlate,
 };
 
 static int init_done;
-- 
1.9.2

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH v2 15/18] iommu: exynos: document internal structures

2014-09-16 Thread Marek Szyprowski
Add a few words of comment to all internal structures used by the driver.

Signed-off-by: Marek Szyprowski m.szyprow...@samsung.com
---
 drivers/iommu/exynos-iommu.c | 49 +---
 1 file changed, 33 insertions(+), 16 deletions(-)

diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c
index ae61d0680b9a..a75b06365f97 100644
--- a/drivers/iommu/exynos-iommu.c
+++ b/drivers/iommu/exynos-iommu.c
@@ -184,32 +184,49 @@ static char *sysmmu_fault_name[SYSMMU_FAULTS_NUM] = {
UNKNOWN FAULT
 };
 
-/* attached to dev.archdata.iommu of the master device */
+/*
+ * This structure is attached to dev.archdata.iommu of the master device
+ * on device add, contains a list of SYSMMU controllers defined by device tree,
+ * which are bound to given master device. It is usually referenced by 'owner'
+ * pointer.
+ */
 struct exynos_iommu_owner {
-   struct list_head clients;
+   struct list_head clients; /* list of sysmmu_drvdata.owner_node */
 };
 
+/*
+ * This structure is stored in -priv field of generic struct iommu_domain,
+ * contains list of SYSMMU controllers from all master devices, which has been
+ * attached to this domain and page tables of IO address space defined by this
+ * domain. It is usually referenced by 'domain' pointer.
+ */
 struct exynos_iommu_domain {
-   struct list_head clients; /* list of sysmmu_drvdata.node */
+   struct list_head clients; /* list of sysmmu_drvdata.domain_node */
sysmmu_pte_t *pgtable; /* lv1 page table, 16KB */
short *lv2entcnt; /* free lv2 entry counter for each section */
-   spinlock_t lock; /* lock for this structure */
+   spinlock_t lock; /* lock for modyfying list of clients */
spinlock_t pgtablelock; /* lock for modifying page table @ pgtable */
 };
 
+/*
+ * This structure hold all data of a single SYSMMU controller, this includes
+ * hw resources like registers and clocks, pointers and list nodes to connect
+ * it to all other structures, internal state and parameters read from device
+ * tree. It is usually referenced by 'data' pointer.
+ */
 struct sysmmu_drvdata {
-   struct device *sysmmu;  /* System MMU's device descriptor */
-   struct device *master;  /* Owner of system MMU */
-   void __iomem *sfrbase;
-   struct clk *clk;
-   struct clk *clk_master;
-   int activations;
-   spinlock_t lock;
-   struct iommu_domain *domain;
-   struct list_head domain_node;
-   struct list_head owner_node;
-   phys_addr_t pgtable;
-   int version;
+   struct device *sysmmu; /* SYSMMU controller device */
+   struct device *master; /* master device (owner of given SYSMMU) */
+   void __iomem *sfrbase; /* our registers */
+   struct clk *clk; /* SYSMMU's clock */
+   struct clk *clk_master; /* master's device clock */
+   int activations; /* number of calls to sysmmu_enable */
+   spinlock_t lock; /* lock for modyfying enable/disable state */
+   struct iommu_domain *domain; /* domain we belong to */
+   struct list_head domain_node; /* node for domain clients list */
+   struct list_head owner_node; /* node for owner clients list */
+   phys_addr_t pgtable; /* assigned page table structure */
+   int version; /* our version */
 };
 
 static bool set_sysmmu_active(struct sysmmu_drvdata *data)
-- 
1.9.2

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


RE: [RFC][PATCH] devicetree: Add master-id-bits property to the iommu device

2014-09-16 Thread Varun Sethi
Hi Arnd,

 -Original Message-
 From: iommu-boun...@lists.linux-foundation.org [mailto:iommu-
 boun...@lists.linux-foundation.org] On Behalf Of Arnd Bergmann
 Sent: Monday, September 15, 2014 10:27 PM
 To: Sethi Varun-B16395
 Cc: mark.rutl...@arm.com; devicet...@vger.kernel.org;
 swar...@nvidia.com; will.dea...@arm.com; Yoder Stuart-B08248;
 robh...@kernel.org; iommu@lists.linux-foundation.org;
 thierry.red...@gmail.com; linux-arm-ker...@lists.infradead.org
 Subject: Re: [RFC][PATCH] devicetree: Add master-id-bits property to the
 iommu device
 
 On Monday 15 September 2014, Varun Sethi wrote:
  
   This seems rather specific to MMU-500. I don't think that most
   IOMMUs would use the term 'master ID', 'stream ID' or even the
   general concept, and you don't expand the acronym 'TBU'. I've seen
   many IOMMUs and I don't even know what that means.
 
  TBU refers to the translation buffer unit, which is responsible for caching
 page translations. In case of translation miss in the cache, translation 
 request is
 forwarded to the TCU (Translation control unit). The master id forwarded to
 TCU would also contain the TBU ID.  Using the master-id-bits property we can
 mask out the additional TBU bits at the TCU. This is a cause of concern when 
 we
 want to share master id for devices which are connected to different TBUs. We
 have a hot pluggable bus architecture, where a device group can have multiple
 devices connected to different TBUs. So, we need a mechanism to mask out
 additional TBIU bits.
 
 Ok, I think I understand now
 
   Why do you think this is something that is needed to be known at the
   global level, rather than a property for some individual drivers?
  
  In case of Freescale Layerscape SOCs, number of bits used for defining a
 stream id are specific to a given platform.
 
  Are you suggesting that this property should be added to the master device
 node, rather than the iommu node?
 
 Most importantly, I think this needs to be part of the (iommu) device specific
 binding, not the generic binding that is used for all iommus that may or may 
 not
 have this concept.
 
 I believe in case of the ARM SMMU, it should actually go into the master node
 as part of the 'iommus' property, because the mask can be different for each
 master. If your IOMMU has a fixed mask that is used for all devices, that's 
 fine
 and you can put it into the iommu node itself but document it in the binding 
 for
 your IOMMU.
 
 For hot-pluggable buses, you probably need to have the 'iommus' property in
 the node that corresponds to the bus controller, and that will have a mask 
 that
 is used for all devices plugged into it.
Can I add a note to the generic binding about representing the mask as a part 
of the iommus property. This would similar to the note about the dma-ranges

-Varun
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [RFC PATCH v3 0/7] Introduce automatic DMA configuration for IOMMU masters

2014-09-16 Thread Will Deacon
On Tue, Sep 16, 2014 at 12:40:27PM +0100, Robin Murphy wrote:
 On 12/09/14 17:34, Will Deacon wrote:
  Here is version three of the RFC I've previously posted here:
 
 RFCv1: 
  http://lists.infradead.org/pipermail/linux-arm-kernel/2014-August/283023.html
 RFCv2: 
  http://lists.infradead.org/pipermail/linux-arm-kernel/2014-September/283752.html
 
  Changes since RFCv2 include:
 
 - Put the iommu_ops in iommu_data so of_iommu_configure can avoid using
   the bus_type
 - Initialise the offset and DMA masks on the dev in of_dma_configure
   instead of in the arch callback (as this would cause a regression on
   some architectures)
 - Added deconfigure/teardown code based on ref counting the 
  iommu_dma_mapping
 - A bunch of small fixes (_OF_DECLARE,  some code shuffling, fix multiple
   IOMMU parsing)
 
  All feedback welcome. Hopefully this is now at a point where people can
  start looking to port dma-mapping and/or IOMMU drivers to it.
 
 
 What about AMBA devices? Playing with this on Juno and wondering why my 
 PL330 doesn't get any of_xlate callbacks, I see that 
 of_amba_device_create doesn't call of_dma_configure or anything from 
 that path. It's easy to work around by removing the arm,primecell 
 compatible, but that feels pretty dirty.

Yeah, that's just a bug in mainline. I'll look at fixing it if you don't
beat me to it.

Will
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [RFC PATCH v3 3/7] iommu: add new iommu_ops callback for adding an OF device

2014-09-16 Thread Will Deacon
On Mon, Sep 15, 2014 at 12:57:38PM +0100, Marek Szyprowski wrote:
 Hello,

Hi Marek,

Thanks for looking again at this -- I'll take at look at your exynos series
when I'm back in the UK next week.

 On 2014-09-12 18:34, Will Deacon wrote:
  This patch adds a new function to the iommu_ops structure to allow an
  OF device to be added to a specific IOMMU instance using the recently
  merged generic devicetree binding for IOMMUs. The callback (of_xlate)
  takes a struct device representing the master and an of_phandle_args
  representing the IOMMU and the correspondong IDs for the new master.
 
  Signed-off-by: Will Deacon will.dea...@arm.com
  ---
include/linux/iommu.h | 5 +
1 file changed, 5 insertions(+)
 
  diff --git a/include/linux/iommu.h b/include/linux/iommu.h
  index 4256f3ce1673..821eb0bd9f6c 100644
  --- a/include/linux/iommu.h
  +++ b/include/linux/iommu.h
  @@ -21,6 +21,7 @@

#include linux/errno.h
#include linux/err.h
  +#include linux/of.h
#include linux/types.h
#include trace/events/iommu.h

  @@ -140,6 +141,10 @@ struct iommu_ops {
  /* Get the numer of window per domain */
  u32 (*domain_get_windows)(struct iommu_domain *domain);

  +#ifdef CONFIG_OF_IOMMU
  +   int (*of_xlate)(struct device *dev, struct of_phandle_args *args);
  +#endif
 
 
 If I understand correctly, this callback is intended to do per-master 
 initialization
 of the iommu structures required by the given iommu driver (I stored them in
 dev-archdata.iommu). However I really don't get what is the meaning of 
 the return
 value. Is it a boolean value? It is used only by of_iommu_configure to 
 check if
 the parse loop should be terminated...

It should probably return 0 on success,  0 otherwise. I'll fix
of_iommu_configure to check for  0 and only exit the loop then. The idea is
that we don't swizzle the DMA ops for a device to IOMMU ops if of_xlate
failed for any of its IDs.

Will
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu