Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [RFC PATCH v5 4/7] drivers: dma-coherent: Introduce default DMA pool
From: Vladimir Murzin @ 2017-01-18 11:13 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1484738003-29892-1-git-send-email-vladimir.murzin@arm.com>

This patch introduces default coherent DMA pool similar to default CMA
area concept. To keep other users safe code kept under CONFIG_ARM.

Cc: Michal Nazarewicz <mina86@mina86.com>
Cc: Marek Szyprowski <m.szyprowski@samsung.com>
Cc: Rob Herring <robh+dt@kernel.org>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Suggested-by: Robin Murphy <robin.murphy@arm.com>
Signed-off-by: Vladimir Murzin <vladimir.murzin@arm.com>
---
 .../bindings/reserved-memory/reserved-memory.txt   |  3 ++
 drivers/base/dma-coherent.c                        | 59 +++++++++++++++++++---
 2 files changed, 55 insertions(+), 7 deletions(-)

diff --git a/Documentation/devicetree/bindings/reserved-memory/reserved-memory.txt b/Documentation/devicetree/bindings/reserved-memory/reserved-memory.txt
index 3da0ebd..16291f2 100644
--- a/Documentation/devicetree/bindings/reserved-memory/reserved-memory.txt
+++ b/Documentation/devicetree/bindings/reserved-memory/reserved-memory.txt
@@ -68,6 +68,9 @@ Linux implementation note:
 - If a "linux,cma-default" property is present, then Linux will use the
   region for the default pool of the contiguous memory allocator.
 
+- If a "linux,dma-default" property is present, then Linux will use the
+  region for the default pool of the consistent DMA allocator.
+
 Device node references to reserved memory
 -----------------------------------------
 Regions in the /reserved-memory node may be referenced by other device
diff --git a/drivers/base/dma-coherent.c b/drivers/base/dma-coherent.c
index c59708c..0c577ea 100644
--- a/drivers/base/dma-coherent.c
+++ b/drivers/base/dma-coherent.c
@@ -18,6 +18,15 @@ struct dma_coherent_mem {
 	spinlock_t	spinlock;
 };
 
+static struct dma_coherent_mem *dma_coherent_default_memory __ro_after_init;
+
+static inline struct dma_coherent_mem *dev_get_coherent_memory(struct device *dev)
+{
+	if (dev && dev->dma_mem)
+		return dev->dma_mem;
+	return dma_coherent_default_memory;
+}
+
 static inline dma_addr_t dma_get_device_base(struct device *dev,
 					     struct dma_coherent_mem * mem)
 {
@@ -91,6 +100,9 @@ static int dma_assign_coherent_memory(struct device *dev,
 {
 	unsigned long dma_pfn_offset = mem->pfn_base - PFN_DOWN(mem->device_base);
 
+	if (!dev)
+		return -ENODEV;
+
 	if (dev->dma_mem)
 		return -EBUSY;
 
@@ -174,15 +186,12 @@ EXPORT_SYMBOL(dma_mark_declared_memory_occupied);
 int dma_alloc_from_coherent(struct device *dev, ssize_t size,
 				       dma_addr_t *dma_handle, void **ret)
 {
-	struct dma_coherent_mem *mem;
+	struct dma_coherent_mem *mem = dev_get_coherent_memory(dev);
 	int order = get_order(size);
 	unsigned long flags;
 	int pageno;
 	int dma_memory_map;
 
-	if (!dev)
-		return 0;
-	mem = dev->dma_mem;
 	if (!mem)
 		return 0;
 
@@ -236,7 +245,7 @@ EXPORT_SYMBOL(dma_alloc_from_coherent);
  */
 int dma_release_from_coherent(struct device *dev, int order, void *vaddr)
 {
-	struct dma_coherent_mem *mem = dev ? dev->dma_mem : NULL;
+	struct dma_coherent_mem *mem = dev_get_coherent_memory(dev);
 
 	if (mem && vaddr >= mem->virt_base && vaddr <
 		   (mem->virt_base + (mem->size << PAGE_SHIFT))) {
@@ -270,7 +279,7 @@ EXPORT_SYMBOL(dma_release_from_coherent);
 int dma_mmap_from_coherent(struct device *dev, struct vm_area_struct *vma,
 			   void *vaddr, size_t size, int *ret)
 {
-	struct dma_coherent_mem *mem = dev ? dev->dma_mem : NULL;
+	struct dma_coherent_mem *mem = dev_get_coherent_memory(dev);
 
 	if (mem && vaddr >= mem->virt_base && vaddr + size <=
 		   (mem->virt_base + (mem->size << PAGE_SHIFT))) {
@@ -300,6 +309,8 @@ EXPORT_SYMBOL(dma_mmap_from_coherent);
 #include <linux/of_fdt.h>
 #include <linux/of_reserved_mem.h>
 
+static struct reserved_mem *dma_reserved_default_memory __initdata;
+
 static int rmem_dma_device_init(struct reserved_mem *rmem, struct device *dev)
 {
 	struct dma_coherent_mem *mem = rmem->priv;
@@ -320,7 +331,8 @@ static int rmem_dma_device_init(struct reserved_mem *rmem, struct device *dev)
 static void rmem_dma_device_release(struct reserved_mem *rmem,
 				    struct device *dev)
 {
-	dev->dma_mem = NULL;
+	if (dev)
+		dev->dma_mem = NULL;
 }
 
 static const struct reserved_mem_ops rmem_dma_ops = {
@@ -340,6 +352,12 @@ static int __init rmem_dma_setup(struct reserved_mem *rmem)
 		pr_err("Reserved memory: regions without no-map are not yet supported\n");
 		return -EINVAL;
 	}
+
+	if (of_get_flat_dt_prop(node, "linux,dma-default", NULL)) {
+		WARN(dma_reserved_default_memory,
+		     "Reserved memory: region for default DMA coherent area is redefined\n");
+		dma_reserved_default_memory = rmem;
+	}
 #endif
 
 	rmem->ops = &rmem_dma_ops;
@@ -347,5 +365,32 @@ static int __init rmem_dma_setup(struct reserved_mem *rmem)
 		&rmem->base, (unsigned long)rmem->size / SZ_1M);
 	return 0;
 }
+
+static int __init dma_init_reserved_memory(void)
+{
+	const struct reserved_mem_ops *ops;
+	int ret;
+
+	if (!dma_reserved_default_memory)
+		return -ENOMEM;
+
+	ops = dma_reserved_default_memory->ops;
+
+	/*
+	 * We rely on rmem_dma_device_init() does not propagate error of
+	 * dma_assign_coherent_memory() for "NULL" device.
+	 */
+	ret = ops->device_init(dma_reserved_default_memory, NULL);
+
+	if (!ret) {
+		dma_coherent_default_memory = dma_reserved_default_memory->priv;
+		pr_info("DMA: default coherent area is set\n");
+	}
+
+	return ret;
+}
+
+core_initcall(dma_init_reserved_memory);
+
 RESERVEDMEM_OF_DECLARE(dma, "shared-dma-pool", rmem_dma_setup);
 #endif
-- 
2.0.0

^ permalink raw reply related

* [RFC PATCH v5 5/7] ARM: NOMMU: Introduce dma operations for noMMU
From: Vladimir Murzin @ 2017-01-18 11:13 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1484738003-29892-1-git-send-email-vladimir.murzin@arm.com>

R/M classes of cpus can have memory covered by MPU which in turn might
configure RAM as Normal i.e. bufferable and cacheable. It breaks
dma_alloc_coherent() and friends, since data can stuck in caches now
or be buffered.

This patch factors out DMA support for NOMMU configuration into
separate entity which provides dedicated dma_ops. We have to handle
there several cases:
- configurations with MMU/MPU setup
- configurations without MMU/MPU setup
- special case for M-class, since caches and MPU there are optional

In general we rely on default DMA area for coherent allocations or/and
per-device memory reserves suitable for coherent DMA, so if such
regions are set coherent allocations go from there.

In case MPU/MPU was not setup we fallback to normal page allocator for
DMA memory allocation.

In case we run M-class cpus, for configuration without cache support
(like Cortex-M3/M4) dma operations are forced to be coherent and wired
with dma-noop (such decision is made based on cacheid global
variable); however, if caches are detected there and no DMA coherent
region is given (either default or per-device), dma is disallowed even
MPU is not set - it is because M-class implement system memory map
which defines part of address space as Normal memory.

Reported-by: Alexandre Torgue <alexandre.torgue@st.com>
Reported-by: Andras Szemzo <sza@esh.hu>
Signed-off-by: Vladimir Murzin <vladimir.murzin@arm.com>
---
 arch/arm/include/asm/dma-mapping.h |   3 +-
 arch/arm/mm/Makefile               |   5 +-
 arch/arm/mm/dma-mapping-nommu.c    | 252 +++++++++++++++++++++++++++++++++++++
 3 files changed, 256 insertions(+), 4 deletions(-)
 create mode 100644 arch/arm/mm/dma-mapping-nommu.c

diff --git a/arch/arm/include/asm/dma-mapping.h b/arch/arm/include/asm/dma-mapping.h
index bf02dbd..559faad 100644
--- a/arch/arm/include/asm/dma-mapping.h
+++ b/arch/arm/include/asm/dma-mapping.h
@@ -20,7 +20,8 @@ static inline struct dma_map_ops *__generic_dma_ops(struct device *dev)
 {
 	if (dev && dev->archdata.dma_ops)
 		return dev->archdata.dma_ops;
-	return &arm_dma_ops;
+
+	return IS_ENABLED(CONFIG_MMU) ? &arm_dma_ops : &dma_noop_ops;
 }
 
 static inline struct dma_map_ops *get_dma_ops(struct device *dev)
diff --git a/arch/arm/mm/Makefile b/arch/arm/mm/Makefile
index 2ac7988..5796357 100644
--- a/arch/arm/mm/Makefile
+++ b/arch/arm/mm/Makefile
@@ -2,9 +2,8 @@
 # Makefile for the linux arm-specific parts of the memory manager.
 #
 
-obj-y				:= dma-mapping.o extable.o fault.o init.o \
-				   iomap.o
-
+obj-y				:= extable.o fault.o init.o iomap.o
+obj-y				+= dma-mapping$(MMUEXT).o
 obj-$(CONFIG_MMU)		+= fault-armv.o flush.o idmap.o ioremap.o \
 				   mmap.o pgd.o mmu.o pageattr.o
 
diff --git a/arch/arm/mm/dma-mapping-nommu.c b/arch/arm/mm/dma-mapping-nommu.c
new file mode 100644
index 0000000..76f00c9
--- /dev/null
+++ b/arch/arm/mm/dma-mapping-nommu.c
@@ -0,0 +1,252 @@
+/*
+ *  Based on linux/arch/arm/mm/dma-mapping.c
+ *
+ *  Copyright (C) 2000-2004 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/export.h>
+#include <linux/mm.h>
+#include <linux/dma-mapping.h>
+#include <linux/scatterlist.h>
+
+#include <asm/cachetype.h>
+#include <asm/cacheflush.h>
+#include <asm/outercache.h>
+#include <asm/cp15.h>
+
+#include "dma.h"
+
+/*
+ *  dma_noop_ops is used if
+ *   - MMU/MPU is off
+ *   - cpu is v7m w/o cache support
+ *   - device is coherent
+ *  otherwise arm_nommu_dma_ops is used.
+ *
+ *  arm_nommu_dma_ops rely on consistent DMA memory (please, refer to
+ *  [1] on how to declare such memory).
+ *
+ *  [1] Documentation/devicetree/bindings/reserved-memory/reserved-memory.txt
+ */
+
+static void *arm_nommu_dma_alloc(struct device *dev, size_t size,
+				 dma_addr_t *dma_handle, gfp_t gfp,
+				 unsigned long attrs)
+
+{
+	struct dma_map_ops *ops = &dma_noop_ops;
+
+	/*
+	 * We are here because:
+	 * - no consistent DMA region has been defined, so we can't
+	 *   continue.
+	 * - there is no space left in consistent DMA region, so we
+	 *   only can fallback to generic allocator if we are
+	 *   advertised that consistency is not required.
+	 */
+
+	if (attrs & DMA_ATTR_NON_CONSISTENT)
+		return ops->alloc(dev, size, dma_handle, gfp, attrs);
+
+	WARN_ON_ONCE(1);
+	return NULL;
+}
+
+static void arm_nommu_dma_free(struct device *dev, size_t size,
+			       void *cpu_addr, dma_addr_t dma_addr,
+			       unsigned long attrs)
+{
+	struct dma_map_ops *ops = &dma_noop_ops;
+
+	if (attrs & DMA_ATTR_NON_CONSISTENT)
+		ops->free(dev, size, cpu_addr, dma_addr, attrs);
+
+	WARN_ON_ONCE(1);
+	return;
+}
+
+static int arm_nommu_dma_mmap(struct device *dev, struct vm_area_struct *vma,
+			      void *cpu_addr, dma_addr_t dma_addr, size_t size,
+			      unsigned long attrs)
+{
+	struct dma_map_ops *ops = &dma_noop_ops;
+	int ret;
+
+	if (dma_mmap_from_coherent(dev, vma, cpu_addr, size, &ret))
+		return ret;
+
+	if (attrs & DMA_ATTR_NON_CONSISTENT)
+		return ops->mmap(dev, vma, cpu_addr, dma_addr, size, attrs);
+
+	WARN_ON_ONCE(1);
+	return -ENXIO;
+}
+
+static void __dma_page_cpu_to_dev(phys_addr_t paddr, size_t size,
+				  enum dma_data_direction dir)
+{
+	dmac_map_area(__va(paddr), size, dir);
+
+	if (dir == DMA_FROM_DEVICE)
+		outer_inv_range(paddr, paddr + size);
+	else
+		outer_clean_range(paddr, paddr + size);
+}
+
+static void __dma_page_dev_to_cpu(phys_addr_t paddr, size_t size,
+				  enum dma_data_direction dir)
+{
+	if (dir != DMA_TO_DEVICE) {
+		outer_inv_range(paddr, paddr + size);
+		dmac_unmap_area(__va(paddr), size, dir);
+	}
+}
+
+static dma_addr_t arm_nommu_dma_map_page(struct device *dev, struct page *page,
+					 unsigned long offset, size_t size,
+					 enum dma_data_direction dir,
+					 unsigned long attrs)
+{
+	dma_addr_t handle = page_to_phys(page) + offset;
+
+	__dma_page_cpu_to_dev(handle, size, dir);
+
+	return handle;
+}
+
+static void arm_nommu_dma_unmap_page(struct device *dev, dma_addr_t handle,
+				     size_t size, enum dma_data_direction dir,
+				     unsigned long attrs)
+{
+	__dma_page_dev_to_cpu(handle, size, dir);
+}
+
+
+static int arm_nommu_dma_map_sg(struct device *dev, struct scatterlist *sgl,
+				int nents, enum dma_data_direction dir,
+				unsigned long attrs)
+{
+	int i;
+	struct scatterlist *sg;
+
+	for_each_sg(sgl, sg, nents, i) {
+		sg_dma_address(sg) = sg_phys(sg);
+		sg_dma_len(sg) = sg->length;
+		__dma_page_cpu_to_dev(sg_dma_address(sg), sg_dma_len(sg), dir);
+	}
+
+	return nents;
+}
+
+static void arm_nommu_dma_unmap_sg(struct device *dev, struct scatterlist *sgl,
+				   int nents, enum dma_data_direction dir,
+				   unsigned long attrs)
+{
+	struct scatterlist *sg;
+	int i;
+
+	for_each_sg(sgl, sg, nents, i)
+		__dma_page_dev_to_cpu(sg_dma_address(sg), sg_dma_len(sg), dir);
+}
+
+static void arm_nommu_dma_sync_single_for_device(struct device *dev,
+		dma_addr_t handle, size_t size, enum dma_data_direction dir)
+{
+	__dma_page_cpu_to_dev(handle, size, dir);
+}
+
+static void arm_nommu_dma_sync_single_for_cpu(struct device *dev,
+		dma_addr_t handle, size_t size, enum dma_data_direction dir)
+{
+	__dma_page_cpu_to_dev(handle, size, dir);
+}
+
+static void arm_nommu_dma_sync_sg_for_device(struct device *dev, struct scatterlist *sgl,
+					     int nents, enum dma_data_direction dir)
+{
+	struct scatterlist *sg;
+	int i;
+
+	for_each_sg(sgl, sg, nents, i)
+		__dma_page_cpu_to_dev(sg_dma_address(sg), sg_dma_len(sg), dir);
+}
+
+static void arm_nommu_dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sgl,
+					  int nents, enum dma_data_direction dir)
+{
+	struct scatterlist *sg;
+	int i;
+
+	for_each_sg(sgl, sg, nents, i)
+		__dma_page_dev_to_cpu(sg_dma_address(sg), sg_dma_len(sg), dir);
+}
+
+struct dma_map_ops arm_nommu_dma_ops = {
+	.alloc			= arm_nommu_dma_alloc,
+	.free			= arm_nommu_dma_free,
+	.mmap			= arm_nommu_dma_mmap,
+	.map_page		= arm_nommu_dma_map_page,
+	.unmap_page		= arm_nommu_dma_unmap_page,
+	.map_sg			= arm_nommu_dma_map_sg,
+	.unmap_sg		= arm_nommu_dma_unmap_sg,
+	.sync_single_for_device	= arm_nommu_dma_sync_single_for_device,
+	.sync_single_for_cpu	= arm_nommu_dma_sync_single_for_cpu,
+	.sync_sg_for_device	= arm_nommu_dma_sync_sg_for_device,
+	.sync_sg_for_cpu	= arm_nommu_dma_sync_sg_for_cpu,
+};
+EXPORT_SYMBOL(arm_nommu_dma_ops);
+
+static struct dma_map_ops *arm_nommu_get_dma_map_ops(bool coherent)
+{
+	return coherent ? &dma_noop_ops : &arm_nommu_dma_ops;
+}
+
+void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
+			const struct iommu_ops *iommu, bool coherent)
+{
+	struct dma_map_ops *dma_ops;
+
+	if (IS_ENABLED(CONFIG_CPU_V7M)) {
+		/*
+		 * Cache support for v7m is optional, so can be treated as
+		 * coherent if no cache has been detected. Note that it is not
+		 * enough to check if MPU is in use or not since in absense of
+		 * MPU system memory map is used.
+		 */
+		dev->archdata.dma_coherent = (cacheid) ? coherent : true;
+	} else {
+		/*
+		 * Assume coherent DMA in case MMU/MPU has not been set up.
+		 */
+		dev->archdata.dma_coherent = (get_cr() & CR_M) ? coherent : true;
+	}
+
+	dma_ops = arm_nommu_get_dma_map_ops(dev->archdata.dma_coherent);
+
+	set_dma_ops(dev, dma_ops);
+}
+
+void arch_teardown_dma_ops(struct device *dev)
+{
+}
+
+int dma_supported(struct device *dev, u64 mask)
+{
+	return 1;
+}
+
+EXPORT_SYMBOL(dma_supported);
+
+#define PREALLOC_DMA_DEBUG_ENTRIES	4096
+
+static int __init dma_debug_do_init(void)
+{
+	dma_debug_init(PREALLOC_DMA_DEBUG_ENTRIES);
+	return 0;
+}
+core_initcall(dma_debug_do_init);
-- 
2.0.0

^ permalink raw reply related

* [RFC PATCH v5 6/7] ARM: NOMMU: Set ARM_DMA_MEM_BUFFERABLE for M-class cpus
From: Vladimir Murzin @ 2017-01-18 11:13 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1484738003-29892-1-git-send-email-vladimir.murzin@arm.com>

Now, we have dedicated non-cacheable region for consistent DMA
operations. However, that region can still be marked as bufferable by
MPU, so it'd be safer to have barriers by default.

Signed-off-by: Vladimir Murzin <vladimir.murzin@arm.com>
---
 arch/arm/mm/Kconfig | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig
index 0b79f12..64a1465c 100644
--- a/arch/arm/mm/Kconfig
+++ b/arch/arm/mm/Kconfig
@@ -1029,7 +1029,7 @@ config ARM_L1_CACHE_SHIFT
 
 config ARM_DMA_MEM_BUFFERABLE
 	bool "Use non-cacheable memory for DMA" if (CPU_V6 || CPU_V6K) && !CPU_V7
-	default y if CPU_V6 || CPU_V6K || CPU_V7
+	default y if CPU_V6 || CPU_V6K || CPU_V7 || CPU_V7M
 	help
 	  Historically, the kernel has used strongly ordered mappings to
 	  provide DMA coherent memory.  With the advent of ARMv7, mapping
-- 
2.0.0

^ permalink raw reply related

* [RFC PATCH v5 7/7] ARM: dma-mapping: Remove traces of NOMMU code
From: Vladimir Murzin @ 2017-01-18 11:13 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1484738003-29892-1-git-send-email-vladimir.murzin@arm.com>

DMA operations for NOMMU case have been just factored out into
separate compilation unit, so don't keep dead code.

Signed-off-by: Vladimir Murzin <vladimir.murzin@arm.com>
---
 arch/arm/mm/dma-mapping.c | 26 ++------------------------
 1 file changed, 2 insertions(+), 24 deletions(-)

diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
index ab77100..d8a755b 100644
--- a/arch/arm/mm/dma-mapping.c
+++ b/arch/arm/mm/dma-mapping.c
@@ -344,8 +344,6 @@ static void __dma_free_buffer(struct page *page, size_t size)
 	}
 }
 
-#ifdef CONFIG_MMU
-
 static void *__alloc_from_contiguous(struct device *dev, size_t size,
 				     pgprot_t prot, struct page **ret_page,
 				     const void *caller, bool want_vaddr,
@@ -646,22 +644,6 @@ static inline pgprot_t __get_dma_pgprot(unsigned long attrs, pgprot_t prot)
 	return prot;
 }
 
-#define nommu() 0
-
-#else	/* !CONFIG_MMU */
-
-#define nommu() 1
-
-#define __get_dma_pgprot(attrs, prot)				__pgprot(0)
-#define __alloc_remap_buffer(dev, size, gfp, prot, ret, c, wv)	NULL
-#define __alloc_from_pool(size, ret_page)			NULL
-#define __alloc_from_contiguous(dev, size, prot, ret, c, wv, coherent_flag)	NULL
-#define __free_from_pool(cpu_addr, size)			do { } while (0)
-#define __free_from_contiguous(dev, page, cpu_addr, size, wv)	do { } while (0)
-#define __dma_free_remap(cpu_addr, size)			do { } while (0)
-
-#endif	/* CONFIG_MMU */
-
 static void *__alloc_simple_buffer(struct device *dev, size_t size, gfp_t gfp,
 				   struct page **ret_page)
 {
@@ -803,7 +785,7 @@ static void *__dma_alloc(struct device *dev, size_t size, dma_addr_t *handle,
 
 	if (cma)
 		buf->allocator = &cma_allocator;
-	else if (nommu() || is_coherent)
+	else if (is_coherent)
 		buf->allocator = &simple_allocator;
 	else if (allowblock)
 		buf->allocator = &remap_allocator;
@@ -852,8 +834,7 @@ static int __arm_dma_mmap(struct device *dev, struct vm_area_struct *vma,
 		 void *cpu_addr, dma_addr_t dma_addr, size_t size,
 		 unsigned long attrs)
 {
-	int ret = -ENXIO;
-#ifdef CONFIG_MMU
+	int ret;
 	unsigned long nr_vma_pages = (vma->vm_end - vma->vm_start) >> PAGE_SHIFT;
 	unsigned long nr_pages = PAGE_ALIGN(size) >> PAGE_SHIFT;
 	unsigned long pfn = dma_to_pfn(dev, dma_addr);
@@ -868,7 +849,6 @@ static int __arm_dma_mmap(struct device *dev, struct vm_area_struct *vma,
 				      vma->vm_end - vma->vm_start,
 				      vma->vm_page_prot);
 	}
-#endif	/* CONFIG_MMU */
 
 	return ret;
 }
@@ -887,9 +867,7 @@ int arm_dma_mmap(struct device *dev, struct vm_area_struct *vma,
 		 void *cpu_addr, dma_addr_t dma_addr, size_t size,
 		 unsigned long attrs)
 {
-#ifdef CONFIG_MMU
 	vma->vm_page_prot = __get_dma_pgprot(attrs, vma->vm_page_prot);
-#endif	/* CONFIG_MMU */
 	return __arm_dma_mmap(dev, vma, cpu_addr, dma_addr, size, attrs);
 }
 
-- 
2.0.0

^ permalink raw reply related

* [PATCH v7 4/8] PWM: add PWM driver for STM32 plaftorm
From: Benjamin Gaignard @ 2017-01-18 11:15 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20170118100817.GF18989@ulmo.ba.sec>

2017-01-18 11:08 GMT+01:00 Thierry Reding <thierry.reding@gmail.com>:
> On Thu, Jan 05, 2017 at 10:25:40AM +0100, Benjamin Gaignard wrote:
>> This driver adds support for PWM driver on STM32 platform.
>> The SoC have multiple instances of the hardware IP and each
>> of them could have small differences: number of channels,
>> complementary output, auto reload register size...
>>
>> version 6:
>> - change st,breakinput parameter to make it usuable for stm32f7 too.
>>
>> version 4:
>> - detect at probe time hardware capabilities
>> - fix comments done on v2 and v3
>> - use PWM atomic ops
>>
>> version 2:
>> - only keep one comptatible
>> - use DT parameters to discover hardware block configuration
>>
>> Signed-off-by: Benjamin Gaignard <benjamin.gaignard@st.com>
>> ---
>>  drivers/pwm/Kconfig     |   9 +
>>  drivers/pwm/Makefile    |   1 +
>>  drivers/pwm/pwm-stm32.c | 434 ++++++++++++++++++++++++++++++++++++++++++++++++
>>  3 files changed, 444 insertions(+)
>>  create mode 100644 drivers/pwm/pwm-stm32.c
>>
>> diff --git a/drivers/pwm/Kconfig b/drivers/pwm/Kconfig
>> index f92dd41..88035c0 100644
>> --- a/drivers/pwm/Kconfig
>> +++ b/drivers/pwm/Kconfig
>> @@ -397,6 +397,15 @@ config PWM_STI
>>         To compile this driver as a module, choose M here: the module
>>         will be called pwm-sti.
>>
>> +config PWM_STM32
>> +     tristate "STMicroelectronics STM32 PWM"
>> +     depends on (ARCH_STM32 && OF && MFD_STM32_TIMERS) || COMPILE_TEST
>> +     help
>> +       Generic PWM framework driver for STM32 SoCs.
>> +
>> +       To compile this driver as a module, choose M here: the module
>> +       will be called pwm-stm32.
>> +
>>  config PWM_STMPE
>>       bool "STMPE expander PWM export"
>>       depends on MFD_STMPE
>> diff --git a/drivers/pwm/Makefile b/drivers/pwm/Makefile
>> index a48bdb5..346a83b 100644
>> --- a/drivers/pwm/Makefile
>> +++ b/drivers/pwm/Makefile
>> @@ -38,6 +38,7 @@ obj-$(CONFIG_PWM_ROCKCHIP)  += pwm-rockchip.o
>>  obj-$(CONFIG_PWM_SAMSUNG)    += pwm-samsung.o
>>  obj-$(CONFIG_PWM_SPEAR)              += pwm-spear.o
>>  obj-$(CONFIG_PWM_STI)                += pwm-sti.o
>> +obj-$(CONFIG_PWM_STM32)              += pwm-stm32.o
>>  obj-$(CONFIG_PWM_STMPE)              += pwm-stmpe.o
>>  obj-$(CONFIG_PWM_SUN4I)              += pwm-sun4i.o
>>  obj-$(CONFIG_PWM_TEGRA)              += pwm-tegra.o
>> diff --git a/drivers/pwm/pwm-stm32.c b/drivers/pwm/pwm-stm32.c
>> new file mode 100644
>> index 0000000..fcf0a78
>> --- /dev/null
>> +++ b/drivers/pwm/pwm-stm32.c
>> @@ -0,0 +1,434 @@
>> +/*
>> + * Copyright (C) STMicroelectronics 2016
>> + *
>> + * Author: Gerald Baeza <gerald.baeza@st.com>
>> + *
>> + * License terms: GNU General Public License (GPL), version 2
>> + *
>> + * Inspired by timer-stm32.c from Maxime Coquelin
>> + *             pwm-atmel.c from Bo Shen
>> + */
>> +
>> +#include <linux/mfd/stm32-timers.h>
>> +#include <linux/module.h>
>> +#include <linux/platform_device.h>
>> +#include <linux/pwm.h>
>> +#include <linux/of.h>
>
> Can you please sort these alphabetically?

sure

>
>> +
>> +#define CCMR_CHANNEL_SHIFT 8
>> +#define CCMR_CHANNEL_MASK  0xFF
>> +#define MAX_BREAKINPUT 2
>
> Okay, this answers my question regarding the st,breakinput property. I
> still think it'd be good to have this in the binding documentation just
> to avoid having to look at implementation to find out.
>
>> +
>> +struct stm32_pwm {
>> +     struct pwm_chip chip;
>> +     struct device *dev;
>> +     struct clk *clk;
>> +     struct regmap *regmap;
>> +     unsigned int caps;
>
> This seems completely unused?

Yes I will remove it

>
>> +     unsigned int npwm;
>
> It's somewhat redundant to have this here, since the same information is
> already contained in struct pwm_chip.npwm.
>
> Since you use this primarily for detection, how about you make the
> stm32_pwm_detect_channels() function return the value and store it in a
> local variable in ->probe()? That might be useful also because you
> need to check the return value of regmap_update_bits() which technically
> could fail.
>

I will remove npwm field and put the result of stm32_pwm_detect_channels()
directly on chip.npwm.

regmap functions could failed (even if I haven't experiment that case)
but testing all
return make the code unreadable so I have decide to not test it....

>> +     u32 max_arr;
>> +     bool have_complementary_output;
>> +};
>> +
>> +struct stm32_breakinput {
>> +     u32 index;
>> +     u32 level;
>> +     u32 filter;
>> +};
>> +
>> +static inline struct stm32_pwm *to_stm32_pwm_dev(struct pwm_chip *chip)
>> +{
>> +     return container_of(chip, struct stm32_pwm, chip);
>> +}
>> +
>> +static u32 active_channels(struct stm32_pwm *dev)
>> +{
>> +     u32 ccer;
>> +
>> +     regmap_read(dev->regmap, TIM_CCER, &ccer);
>> +
>> +     return ccer & TIM_CCER_CCXE;
>> +}
>
> This looks like something that you could track in software, but this is
> probably fine, too. Again, technically regmap_read() could fail, so you
> might want to consider adding some code to handle it. In practice it
> probably won't, so maybe you don't.

TIM_CCER_CCXE is a value that IIO timer can also read (not write) so
I have keep the same logic for pwm driver.

>
>> +
>> +static int write_ccrx(struct stm32_pwm *dev, struct pwm_device *pwm,
>> +                   u32 value)
>> +{
>> +     switch (pwm->hwpwm) {
>> +     case 0:
>> +             return regmap_write(dev->regmap, TIM_CCR1, value);
>> +     case 1:
>> +             return regmap_write(dev->regmap, TIM_CCR2, value);
>> +     case 2:
>> +             return regmap_write(dev->regmap, TIM_CCR3, value);
>> +     case 3:
>> +             return regmap_write(dev->regmap, TIM_CCR4, value);
>> +     }
>> +     return -EINVAL;
>> +}
>> +
>> +static int stm32_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
>> +                         int duty_ns, int period_ns)
>> +{
>> +     struct stm32_pwm *priv = to_stm32_pwm_dev(chip);
>> +     unsigned long long prd, div, dty;
>> +     unsigned int prescaler = 0;
>> +     u32 ccmr, mask, shift;
>> +
>> +     /* Period and prescaler values depends on clock rate */
>> +     div = (unsigned long long)clk_get_rate(priv->clk) * period_ns;
>> +
>> +     do_div(div, NSEC_PER_SEC);
>> +     prd = div;
>> +
>> +     while (div > priv->max_arr) {
>> +             prescaler++;
>> +             div = prd;
>> +             do_div(div, (prescaler + 1));
>
> Nit: there's no need for the parentheses here.

okay

>> +     }
>> +
>> +     prd = div;
>> +
>> +     if (prescaler > MAX_TIM_PSC) {
>> +             dev_err(chip->dev, "prescaler exceeds the maximum value\n");
>> +             return -EINVAL;
>> +     }
>> +
>> +     /*
>> +      * All channels share the same prescaler and counter so when two
>> +      * channels are active at the same we can't change them
>
> Nit: "at the same time"?

okay

>
>> +      */
>> +     if (active_channels(priv) & ~(1 << pwm->hwpwm * 4)) {
>> +             u32 psc, arr;
>> +
>> +             regmap_read(priv->regmap, TIM_PSC, &psc);
>> +             regmap_read(priv->regmap, TIM_ARR, &arr);
>> +
>> +             if ((psc != prescaler) || (arr != prd - 1))
>> +                     return -EBUSY;
>> +     }
>> +
>> +     regmap_write(priv->regmap, TIM_PSC, prescaler);
>> +     regmap_write(priv->regmap, TIM_ARR, prd - 1);
>> +     regmap_update_bits(priv->regmap, TIM_CR1, TIM_CR1_ARPE, TIM_CR1_ARPE);
>> +
>> +     /* Calculate the duty cycles */
>> +     dty = prd * duty_ns;
>> +     do_div(dty, period_ns);
>> +
>> +     write_ccrx(priv, pwm, dty);
>> +
>> +     /* Configure output mode */
>> +     shift = (pwm->hwpwm & 0x1) * CCMR_CHANNEL_SHIFT;
>> +     ccmr = (TIM_CCMR_PE | TIM_CCMR_M1) << shift;
>> +     mask = CCMR_CHANNEL_MASK << shift;
>> +
>> +     if (pwm->hwpwm < 2)
>> +             regmap_update_bits(priv->regmap, TIM_CCMR1, mask, ccmr);
>> +     else
>> +             regmap_update_bits(priv->regmap, TIM_CCMR2, mask, ccmr);
>> +
>> +     regmap_update_bits(priv->regmap, TIM_BDTR,
>> +                        TIM_BDTR_MOE | TIM_BDTR_AOE,
>> +                        TIM_BDTR_MOE | TIM_BDTR_AOE);
>> +
>> +     return 0;
>> +}
>> +
>> +static int stm32_pwm_set_polarity(struct pwm_chip *chip, struct pwm_device *pwm,
>> +                               enum pwm_polarity polarity)
>> +{
>> +     u32 mask;
>> +     struct stm32_pwm *priv = to_stm32_pwm_dev(chip);
>> +
>> +     mask = TIM_CCER_CC1P << (pwm->hwpwm * 4);
>> +     if (priv->have_complementary_output)
>> +             mask |= TIM_CCER_CC1NP << (pwm->hwpwm * 4);
>> +
>> +     regmap_update_bits(priv->regmap, TIM_CCER, mask,
>> +                        polarity == PWM_POLARITY_NORMAL ? 0 : mask);
>> +
>> +     return 0;
>> +}
>> +
>> +static int stm32_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
>> +{
>> +     u32 mask;
>> +     struct stm32_pwm *priv = to_stm32_pwm_dev(chip);
>> +
>> +     clk_enable(priv->clk);
>
> This can fail, so its return value should be checked. Also, I don't see
> a clk_prepare() anywhere. Is that something that maybe the MFD driver
> should be doing? It currently isn't.

I will check the return value.
You are right clk_prepare() is done in mfd driver when calling
devm_regmap_init_mmio_clk()

>
>> +
>> +     /* Enable channel */
>> +     mask = TIM_CCER_CC1E << (pwm->hwpwm * 4);
>> +     if (priv->have_complementary_output)
>> +             mask |= TIM_CCER_CC1NE << (pwm->hwpwm * 4);
>> +
>> +     regmap_update_bits(priv->regmap, TIM_CCER, mask, mask);
>> +
>> +     /* Make sure that registers are updated */
>> +     regmap_update_bits(priv->regmap, TIM_EGR, TIM_EGR_UG, TIM_EGR_UG);
>> +
>> +     /* Enable controller */
>> +     regmap_update_bits(priv->regmap, TIM_CR1, TIM_CR1_CEN, TIM_CR1_CEN);
>> +
>> +     return 0;
>> +}
>> +
>> +static void stm32_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
>> +{
>> +     u32 mask;
>> +     struct stm32_pwm *priv = to_stm32_pwm_dev(chip);
>> +
>> +     /* Disable channel */
>> +     mask = TIM_CCER_CC1E << (pwm->hwpwm * 4);
>> +     if (priv->have_complementary_output)
>> +             mask |= TIM_CCER_CC1NE << (pwm->hwpwm * 4);
>> +
>> +     regmap_update_bits(priv->regmap, TIM_CCER, mask, 0);
>> +
>> +     /* When all channels are disabled, we can disable the controller */
>> +     if (!active_channels(priv))
>> +             regmap_update_bits(priv->regmap, TIM_CR1, TIM_CR1_CEN, 0);
>> +
>> +     clk_disable(priv->clk);
>> +}
>> +
>> +static int stm32_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
>> +                        struct pwm_state *state)
>> +{
>> +     struct pwm_state curstate;
>> +     bool enabled;
>> +     int ret;
>> +
>> +     pwm_get_state(pwm, &curstate);
>> +     enabled = curstate.enabled;
>
> There should be no need to do this in drivers. pwm_get_state() is for
> PWM API users. Drivers can directly dereference pwm->state.

ok

>
>> +
>> +     if (enabled && !state->enabled) {
>> +             stm32_pwm_disable(chip, pwm);
>> +             return 0;
>> +     }
>> +
>> +     if (state->polarity != curstate.polarity && enabled)
>> +             stm32_pwm_set_polarity(chip, pwm, state->polarity);
>
> So that's kind of a violation of atomic API semantics. The above means
> that if you have a PWM in the following state:
>
>         enabled: no
>         polarity: normal
>
> and want to set this:
>
>         enabled: yes
>         polarity: inversed
>
> then you will ignore the new polarity setting. What's the reason for
> "&& enabled) in the conditional above?

There is no reason, I will remove it.

>> +
>> +     ret = stm32_pwm_config(chip, pwm, state->duty_cycle, state->period);
>> +     if (ret)
>> +             return ret;
>> +
>> +     if (!enabled && state->enabled)
>> +             ret = stm32_pwm_enable(chip, pwm);
>> +
>> +     return ret;
>> +}
>
> Would it be possible to merge stm32_pwm_disable(), stm32_pwm_enable(),
> stm32_pwm_set_polarity() and stm32_pwm_config() into stm32_pwm_apply()?
> Part of the reason for the atomic API was to make it easier to write
> these drivers, but your implementation effectively copies what the
> transitional helpers do.
>
> It might not make a difference technically in your case, but I think
> it'd make the implementation more compact and set a better example for
> future reference.

hmm... it will create a fat function with lot of where
enabling/disabling/configuration
will be mixed I'm really not convince that will more compact and readable.

>
>> +
>> +static const struct pwm_ops stm32pwm_ops = {
>> +     .owner = THIS_MODULE,
>> +     .apply = stm32_pwm_apply,
>> +};
>> +
>> +static int stm32_pwm_set_breakinput(struct stm32_pwm *priv,
>> +                                 int level, int filter)
>> +{
>> +     u32 bdtr = TIM_BDTR_BKE;
>> +
>> +     if (level)
>> +             bdtr |= TIM_BDTR_BKP;
>> +
>> +     bdtr |= (filter & TIM_BDTR_BKF_MASK) << TIM_BDTR_BKF_SHIFT;
>> +
>> +     regmap_update_bits(priv->regmap,
>> +                        TIM_BDTR, TIM_BDTR_BKE | TIM_BDTR_BKP | TIM_BDTR_BKF,
>> +                        bdtr);
>> +
>> +     regmap_read(priv->regmap, TIM_BDTR, &bdtr);
>> +
>> +     return (bdtr & TIM_BDTR_BKE) ? 0 : -EINVAL;
>> +}
>> +
>> +static int stm32_pwm_set_breakinput2(struct stm32_pwm *priv,
>> +                                  int level, int filter)
>> +{
>> +     u32 bdtr = TIM_BDTR_BK2E;
>> +
>> +     if (level)
>> +             bdtr |= TIM_BDTR_BK2P;
>> +
>> +     bdtr |= (filter & TIM_BDTR_BKF_MASK) << TIM_BDTR_BK2F_SHIFT;
>> +
>> +     regmap_update_bits(priv->regmap,
>> +                        TIM_BDTR, TIM_BDTR_BK2E |
>> +                        TIM_BDTR_BK2P |
>> +                        TIM_BDTR_BK2F,
>> +                        bdtr);
>> +
>> +     regmap_read(priv->regmap, TIM_BDTR, &bdtr);
>> +
>> +     return (bdtr & TIM_BDTR_BK2E) ? 0 : -EINVAL;
>> +}
>
> As far as I can tell the only difference here is the various bit
> positions. Can you collapse the above two functions and add a new
> parameter to unify some code?

Yes it is all about bit shifting, I had try unify those two functions
with index has additional parameter
but it just add if() before each lines so no real benefit for code size.

>
>> +
>> +static int stm32_pwm_apply_breakinputs(struct stm32_pwm *priv,
>> +                                    struct device_node *np)
>> +{
>> +     struct stm32_breakinput breakinput[MAX_BREAKINPUT];
>> +     int nb, ret, i, array_size;
>> +
>> +     nb = of_property_count_elems_of_size(np, "st,breakinput",
>> +                                          sizeof(struct stm32_breakinput));
>> +
>> +     /*
>> +      * Because "st,breakinput" parameter is optional do not make probe
>> +      * failed if it doesn't exist.
>> +      */
>> +     if (nb <= 0)
>> +             return 0;
>> +
>> +     if (nb > MAX_BREAKINPUT)
>> +             return -EINVAL;
>> +
>> +     array_size = nb * sizeof(struct stm32_breakinput) / sizeof(u32);
>> +     ret = of_property_read_u32_array(np, "st,breakinput",
>> +                                      &breakinput[0].index, array_size);
>
> Maybe (u32 *)breakinput? That would make it more resilient against
> changes in ordering of fields in the struct. Granted, that's not likely
> to change, but I think it's a good idea in general to write code in a
> way that's safe in a more general case. That way if somebody ever were
> to copy from your code and then decide to reorder fields in their code
> things wouldn't fall apart.

Yes it is not suppose to change but I will use (u32 *)breakinput.

>> +     if (ret)
>> +             return ret;
>> +
>> +     for (i = 0; i < nb && !ret; i++) {
>> +             switch (breakinput[i].index) {
>> +             case 0:
>> +             {
>> +                     ret = stm32_pwm_set_breakinput(priv,
>> +                                                    breakinput[i].level,
>> +                                                    breakinput[i].filter);
>> +                     break;
>> +             }
>
> Curly braces are unnecessary here.

removed

>
>> +             case 1:
>> +             {
>> +                     ret = stm32_pwm_set_breakinput2(priv,
>> +                                                     breakinput[i].level,
>> +                                                     breakinput[i].filter);
>> +
>> +                     break;
>> +             }
>> +             default:
>> +             {
>> +                     ret = -EINVAL;
>> +                     break;
>> +             }
>> +             }
>> +     }
>> +
>> +     return ret;
>> +}
>> +
>> +static void stm32_pwm_detect_complementary(struct stm32_pwm *priv)
>> +{
>> +     u32 ccer;
>> +
>> +     /*
>> +      * If complementary bit doesn't exist writing 1 will have no
>> +      * effect so we can detect it.
>> +      */
>> +     regmap_update_bits(priv->regmap,
>> +                        TIM_CCER, TIM_CCER_CC1NE, TIM_CCER_CC1NE);
>> +     regmap_read(priv->regmap, TIM_CCER, &ccer);
>> +     regmap_update_bits(priv->regmap, TIM_CCER, TIM_CCER_CCXE, 0);
>
> This is strange: why are we disabling outputs here? Shouldn't the last
> line here undo the first instead?

Yes it should TIM_CCER_CC1NE not TIM_CCER_CCXE, I will fix it, thanks

>
>> +
>> +     priv->have_complementary_output = (ccer != 0);
>> +}
>> +
>> +static void stm32_pwm_detect_channels(struct stm32_pwm *priv)
>> +{
>> +     u32 ccer;
>> +
>> +     /*
>> +      * If channels enable bits don't exist writing 1 will have no
>> +      * effect so we can detect and count them.
>> +      */
>> +     regmap_update_bits(priv->regmap,
>> +                        TIM_CCER, TIM_CCER_CCXE, TIM_CCER_CCXE);
>> +     regmap_read(priv->regmap, TIM_CCER, &ccer);
>> +     regmap_update_bits(priv->regmap, TIM_CCER, TIM_CCER_CCXE, 0);
>
> Does this have the potential to glitch? I suspect that the clock may not
> be on at this point and therefore no PWM outputs will be generated, but
> is that guaranteed to always be the case?

Set TIM_CCER_CCXE isn't enough to enable PWM generation, TIM_CR1_CEN
in TIM_CR1 register must also to set so no risk of glitch here

>
> Thierry



-- 
Benjamin Gaignard

Graphic Study Group

Linaro.org ? Open source software for ARM SoCs

Follow Linaro: Facebook | Twitter | Blog

^ permalink raw reply

* [PATCH v7 4/8] PWM: add PWM driver for STM32 plaftorm
From: Benjamin Gaignard @ 2017-01-18 11:16 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20170118101628.GG18989@ulmo.ba.sec>

2017-01-18 11:16 GMT+01:00 Thierry Reding <thierry.reding@gmail.com>:
> On Thu, Jan 05, 2017 at 10:25:40AM +0100, Benjamin Gaignard wrote:
> [...]
>> diff --git a/drivers/pwm/Kconfig b/drivers/pwm/Kconfig
>> index f92dd41..88035c0 100644
>> --- a/drivers/pwm/Kconfig
>> +++ b/drivers/pwm/Kconfig
>> @@ -397,6 +397,15 @@ config PWM_STI
>>         To compile this driver as a module, choose M here: the module
>>         will be called pwm-sti.
>>
>> +config PWM_STM32
>> +     tristate "STMicroelectronics STM32 PWM"
>> +     depends on (ARCH_STM32 && OF && MFD_STM32_TIMERS) || COMPILE_TEST
>
> One other thing: is the dependency on ARCH_STM32 and OF necessary here?
> ARCH_STM32 and OF are both pulled in by MFD_STM32_TIMERS. The dependency
> is probably fine for MFD_STM32_TIMERS, though even there && OF seems too
> much, since it's already pulled in via ARCH_STM32 -> ARM_SINGLE_ARMV7M
> -> USE_OF.

Said like that MFD_STM32_TIMERS is enough so I will keep this one

Thanks

>
> Thierry



-- 
Benjamin Gaignard

Graphic Study Group

Linaro.org ? Open source software for ARM SoCs

Follow Linaro: Facebook | Twitter | Blog

^ permalink raw reply

* [PATCH v3 6/9] kvm: arm/arm64: Add host pmu to support VM introspection
From: Marc Zyngier @ 2017-01-18 11:21 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20170110113856.7183-7-punit.agrawal@arm.com>

+Mark

On 10/01/17 11:38, Punit Agrawal wrote:
> Both AArch32 and AArch64 mode of the ARMv8 architecture support trapping
> certain VM operations, e.g, TLB and cache maintenance
> operations. Selective trapping of these operations for specific VMs can
> be used to track the frequency with which these occur during execution.
> 
> Add a software PMU on the host that can support tracking VM
> operations (in the form of PMU events). Supporting new events requires
> providing callbacks to configure the VM to enable/disable the trapping
> and read a count of the frequency.
> 
> The host PMU events can be controlled by tools like perf that use
> standard kernel perf interfaces.
> 
> Signed-off-by: Punit Agrawal <punit.agrawal@arm.com>
> Cc: Christoffer Dall <christoffer.dall@linaro.org>
> Cc: Marc Zyngier <marc.zyngier@arm.com>
> Cc: Will Deacon <will.deacon@arm.com>
> ---
>  arch/arm/include/asm/kvm_host.h   |   8 ++
>  arch/arm/kvm/arm.c                |   2 +
>  arch/arm64/include/asm/kvm_host.h |   8 ++
>  virt/kvm/arm/host_pmu.c           | 272 ++++++++++++++++++++++++++++++++++++++
>  4 files changed, 290 insertions(+)
>  create mode 100644 virt/kvm/arm/host_pmu.c
> 
> diff --git a/arch/arm/include/asm/kvm_host.h b/arch/arm/include/asm/kvm_host.h
> index 26f0c8a0b790..b988f8801b86 100644
> --- a/arch/arm/include/asm/kvm_host.h
> +++ b/arch/arm/include/asm/kvm_host.h
> @@ -289,6 +289,14 @@ static inline int kvm_arch_dev_ioctl_check_extension(struct kvm *kvm, long ext)
>  int kvm_perf_init(void);
>  int kvm_perf_teardown(void);
>  
> +#if !defined(CONFIG_KVM_HOST_PMU)
> +static inline int kvm_host_pmu_init(void) { return 0; }
> +static inline void kvm_host_pmu_teardown(void) { }
> +#else
> +int kvm_host_pmu_init(void);
> +void kvm_host_pmu_teardown(void);
> +#endif
> +
>  void kvm_mmu_wp_memory_region(struct kvm *kvm, int slot);
>  
>  struct kvm_vcpu *kvm_mpidr_to_vcpu(struct kvm *kvm, unsigned long mpidr);
> diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c
> index 11676787ad49..058626b65b8d 100644
> --- a/arch/arm/kvm/arm.c
> +++ b/arch/arm/kvm/arm.c
> @@ -1263,6 +1263,7 @@ static int init_subsystems(void)
>  		goto out;
>  
>  	kvm_perf_init();
> +	kvm_host_pmu_init();
>  	kvm_coproc_table_init();
>  
>  out:
> @@ -1453,6 +1454,7 @@ int kvm_arch_init(void *opaque)
>  void kvm_arch_exit(void)
>  {
>  	kvm_perf_teardown();
> +	kvm_host_pmu_teardown();
>  }
>  
>  static int arm_init(void)
> diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
> index 1e83b707f14c..018f887e8964 100644
> --- a/arch/arm64/include/asm/kvm_host.h
> +++ b/arch/arm64/include/asm/kvm_host.h
> @@ -349,6 +349,14 @@ int handle_exit(struct kvm_vcpu *vcpu, struct kvm_run *run,
>  int kvm_perf_init(void);
>  int kvm_perf_teardown(void);
>  
> +#if !defined(CONFIG_KVM_HOST_PMU)
> +static inline int kvm_host_pmu_init(void) { return 0; }
> +static inline void kvm_host_pmu_teardown(void) { }
> +#else
> +int kvm_host_pmu_init(void);
> +void kvm_host_pmu_teardown(void);
> +#endif
> +
>  struct kvm_vcpu *kvm_mpidr_to_vcpu(struct kvm *kvm, unsigned long mpidr);
>  
>  static inline void __cpu_init_hyp_mode(phys_addr_t pgd_ptr,
> diff --git a/virt/kvm/arm/host_pmu.c b/virt/kvm/arm/host_pmu.c
> new file mode 100644
> index 000000000000..fc610ccc169a
> --- /dev/null
> +++ b/virt/kvm/arm/host_pmu.c
> @@ -0,0 +1,272 @@
> +#include <linux/cpumask.h>
> +#include <linux/device.h>
> +#include <linux/kernel.h>
> +#include <linux/kvm_host.h>
> +#include <linux/list.h>
> +#include <linux/perf_event.h>
> +#include <linux/pid.h>
> +#include <linux/sched.h>
> +#include <linux/slab.h>
> +#include <linux/spinlock_types.h>
> +#include <linux/sysfs.h>
> +
> +#include <asm/kvm_emulate.h>
> +
> +enum host_pmu_events {
> +	KVM_HOST_MAX_EVENTS,
> +};
> +
> +struct host_pmu {
> +	struct pmu pmu;
> +	spinlock_t event_list_lock;
> +	struct list_head event_list_head;
> +} host_pmu;
> +#define to_host_pmu(p) (container_of(p, struct host_pmu, pmu))
> +
> +typedef void (*configure_event_fn)(struct kvm *kvm, bool enable);
> +typedef u64 (*get_event_count_fn)(struct kvm *kvm);
> +
> +struct kvm_event_cb {
> +	enum host_pmu_events event;
> +	get_event_count_fn get_event_count;
> +	configure_event_fn configure_event;
> +};
> +
> +struct event_data {
> +	bool enable;
> +	struct kvm *kvm;
> +	struct kvm_event_cb *cb;
> +	struct work_struct work;
> +	struct list_head event_list;
> +};
> +
> +static struct kvm_event_cb event_callbacks[] = {
> +};
> +
> +static struct attribute *event_attrs[] = {
> +	NULL,
> +};
> +
> +static struct attribute_group events_attr_group = {
> +	.name	= "events",
> +	.attrs	= event_attrs,
> +};
> +
> +
> +#define VM_MASK	GENMASK_ULL(31, 0)
> +#define EVENT_MASK	GENMASK_ULL(32, 39)
> +#define EVENT_SHIFT	(32)
> +
> +#define to_pid(cfg)	((cfg) & VM_MASK)
> +#define to_event(cfg)	(((cfg) & EVENT_MASK) >> EVENT_SHIFT)
> +
> +PMU_FORMAT_ATTR(vm, "config:0-31");
> +PMU_FORMAT_ATTR(event, "config:32-39");

I'm a bit confused by these. Can't you get the PID of the VM you're
tracing directly from perf, without having to encode things? And if you
can't, surely this should be a function of the size of pid_t?

Mark, can you shine some light here?

> +
> +static struct attribute *format_attrs[] = {
> +	&format_attr_vm.attr,
> +	&format_attr_event.attr,
> +	NULL,
> +};
> +
> +static struct attribute_group format_attr_group = {
> +	.name	= "format",
> +	.attrs	= format_attrs,
> +};
> +
> +static const struct attribute_group *attr_groups[] = {
> +	&events_attr_group,
> +	&format_attr_group,
> +	NULL,
> +};
> +
> +static void host_event_destroy(struct perf_event *event)
> +{
> +	struct host_pmu *host_pmu = to_host_pmu(event->pmu);
> +	struct event_data *e_data = event->pmu_private;
> +
> +	/*
> +	 * Ensure outstanding work items related to this event are
> +	 * completed before freeing resources.
> +	 */
> +	flush_work(&e_data->work);
> +
> +	kvm_put_kvm(e_data->kvm);
> +
> +	spin_lock(&host_pmu->event_list_lock);
> +	list_del(&e_data->event_list);
> +	spin_unlock(&host_pmu->event_list_lock);
> +	kfree(e_data);
> +}
> +
> +void host_event_work(struct work_struct *work)
> +{
> +	struct event_data *e_data = container_of(work, struct event_data, work);
> +	struct kvm *kvm = e_data->kvm;
> +
> +	e_data->cb->configure_event(kvm, e_data->enable);
> +}
> +
> +static int host_event_init(struct perf_event *event)
> +{
> +	struct host_pmu *host_pmu = to_host_pmu(event->pmu);
> +	int event_id = to_event(event->attr.config);
> +	pid_t task_pid = to_pid(event->attr.config);
> +	struct event_data *e_data, *pos;
> +	bool found = false;
> +	struct pid *pid;
> +	struct kvm *kvm;
> +	int ret = 0;
> +
> +	if (event->attr.type != event->pmu->type)
> +		return -ENOENT;
> +
> +	if (has_branch_stack(event)	||
> +	    is_sampling_event(event)	||
> +	    event->attr.exclude_user	||
> +	    event->attr.exclude_kernel	||
> +	    event->attr.exclude_hv	||
> +	    event->attr.exclude_idle	||
> +	    event->attr.exclude_guest) {
> +		return -EINVAL;
> +	}
> +
> +	if (event->attach_state == PERF_ATTACH_TASK)
> +		return -EOPNOTSUPP;
> +
> +	if (event->cpu < 0)
> +		return -EINVAL;
> +
> +	if (event_id >= KVM_HOST_MAX_EVENTS)
> +		return -EINVAL;
> +
> +	pid = find_get_pid(task_pid);
> +	spin_lock(&kvm_lock);
> +	list_for_each_entry(kvm, &vm_list, vm_list) {
> +		if (kvm->pid == pid) {
> +			kvm_get_kvm(kvm);
> +			found = true;
> +			break;
> +		}
> +	}
> +	spin_unlock(&kvm_lock);
> +	put_pid(pid);
> +
> +	if (!found)
> +		return -EINVAL;
> +
> +	spin_lock(&host_pmu->event_list_lock);
> +	/* Make sure we don't already have the (event_id, kvm) pair */
> +	list_for_each_entry(pos, &host_pmu->event_list_head, event_list) {
> +		if (pos->cb->event == event_id &&
> +		    pos->kvm->pid == pid) {
> +			kvm_put_kvm(kvm);
> +			ret = -EOPNOTSUPP;
> +			goto unlock;
> +		}
> +	}
> +
> +	e_data = kzalloc(sizeof(*e_data), GFP_KERNEL);
> +	e_data->kvm = kvm;
> +	e_data->cb = &event_callbacks[event_id];
> +	INIT_WORK(&e_data->work, host_event_work);
> +	event->pmu_private = e_data;
> +	event->cpu = cpumask_first(cpu_online_mask);
> +	event->destroy = host_event_destroy;
> +
> +	list_add_tail(&e_data->event_list, &host_pmu->event_list_head);
> +
> +unlock:
> +	spin_unlock(&host_pmu->event_list_lock);
> +
> +	return ret;
> +}
> +
> +static void host_event_update(struct perf_event *event)
> +{
> +	struct event_data *e_data = event->pmu_private;
> +	struct kvm_event_cb *cb = e_data->cb;
> +	struct kvm *kvm = e_data->kvm;
> +	struct hw_perf_event *hw = &event->hw;
> +	u64 prev_count, new_count;
> +
> +	do {
> +		prev_count = local64_read(&hw->prev_count);
> +		new_count = cb->get_event_count(kvm);
> +	} while (local64_xchg(&hw->prev_count, new_count) != prev_count);
> +
> +	local64_add(new_count - prev_count, &event->count);
> +}
> +
> +static void host_event_start(struct perf_event *event, int flags)
> +{
> +	struct event_data *e_data = event->pmu_private;
> +	struct kvm_event_cb *cb = e_data->cb;
> +	struct kvm *kvm = e_data->kvm;
> +	u64 val;
> +
> +	val = cb->get_event_count(kvm);
> +	local64_set(&event->hw.prev_count, val);
> +
> +	e_data->enable = true;
> +	schedule_work(&e_data->work);
> +}
> +
> +static void host_event_stop(struct perf_event *event, int flags)
> +{
> +	struct event_data *e_data = event->pmu_private;
> +
> +	e_data->enable = false;
> +	schedule_work(&e_data->work);
> +
> +	if (flags & PERF_EF_UPDATE)
> +		host_event_update(event);
> +}
> +
> +static int host_event_add(struct perf_event *event, int flags)
> +{
> +	if (flags & PERF_EF_START)
> +		host_event_start(event, flags);
> +
> +	return 0;
> +}
> +
> +static void host_event_del(struct perf_event *event, int flags)
> +{
> +	host_event_stop(event, PERF_EF_UPDATE);
> +}
> +
> +static void host_event_read(struct perf_event *event)
> +{
> +	host_event_update(event);
> +}
> +
> +static void init_host_pmu(struct host_pmu *host_pmu)
> +{
> +	host_pmu->pmu = (struct pmu) {
> +		.task_ctx_nr	= perf_sw_context,
> +		.attr_groups	= attr_groups,
> +		.event_init	= host_event_init,
> +		.add		= host_event_add,
> +		.del		= host_event_del,
> +		.start		= host_event_start,
> +		.stop		= host_event_stop,
> +		.read		= host_event_read,
> +		.capabilities	= PERF_PMU_CAP_NO_INTERRUPT,
> +	};
> +
> +	INIT_LIST_HEAD(&host_pmu->event_list_head);
> +	spin_lock_init(&host_pmu->event_list_lock);
> +}
> +
> +int kvm_host_pmu_init(void)
> +{
> +	init_host_pmu(&host_pmu);
> +
> +	return perf_pmu_register(&host_pmu.pmu, "kvm", -1);
> +}
> +
> +void kvm_host_pmu_teardown(void)
> +{
> +	perf_pmu_unregister(&host_pmu.pmu);
> +}
> 

This patch really makes me think that there is nothing arm-specific in
here at all. Why can't it be a generic feature through which
architectures can expose events in a generic way (or as close as
possible to being generic)?

Thanks,

	M.
-- 
Jazz is not dead. It just smells funny...

^ permalink raw reply

* [PATCH v1] arm64: mm: avoid name clash in __page_to_voff()
From: Catalin Marinas @ 2017-01-18 11:24 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1484723365-24147-1-git-send-email-andr2000@gmail.com>

On Wed, Jan 18, 2017 at 09:09:25AM +0200, Oleksandr Andrushchenko wrote:
> From: Oleksandr Andrushchenko <Oleksandr_Andrushchenko@epam.com>
> 
> The arm64 __page_to_voff() macro takes a parameter called 'page', and
> also refers to 'struct page'. Thus, if the value passed in is not
> called 'page', we'll refer to the wrong struct name (which might not
> exist).
> 
> Fixes: 3fa72fe9c614 ("arm64: mm: fix __page_to_voff definition")
> Acked-by: Mark Rutland <mark.rutland@arm.com>
> Suggested-by: Volodymyr Babchuk <Volodymyr_Babchuk@epam.com>
> Signed-off-by: Oleksandr Andrushchenko <Oleksandr_Andrushchenko@epam.com>

Queued for 4.10. Thanks.

-- 
Catalin

^ permalink raw reply

* [PATCH 2/2] ARM: DTS: Fix register map for virt-capable GIC
From: Heiko Stübner @ 2017-01-18 11:25 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1484736811-24002-3-git-send-email-marc.zyngier@arm.com>

Am Mittwoch, 18. Januar 2017, 10:53:31 CET schrieb Marc Zyngier:
> Since everybody copied my own mistake from the DT binding example,
> let's address all the offenders in one swift go.
> 
> Most of them got the CPU interface size wrong (4kB, while it should
> be 8kB), except for both keystone platforms which got the control
> interface wrong (4kB instead of 8kB).
> 
> In the couple of cases were I knew for sure what implementation
> was used, I've added the "arm,gic-400" compatible string. I'm 99%
> sure that this is what everyong is using, but short of having the
> TRM for all the other SoCs, I've let them alone.
> 
> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>

for the Rockchip parts
Acked-by: Heiko Stuebner <heiko@sntech.de>

> diff --git a/arch/arm/boot/dts/rk1108.dtsi b/arch/arm/boot/dts/rk1108.dtsi
> index d770023..d6194bf 100644
> --- a/arch/arm/boot/dts/rk1108.dtsi
> +++ b/arch/arm/boot/dts/rk1108.dtsi
> @@ -215,7 +215,7 @@
>  		#address-cells = <0>;
> 
>  		reg = <0x32011000 0x1000>,
> -		      <0x32012000 0x1000>,
> +		      <0x32012000 0x2000>,
>  		      <0x32014000 0x2000>,
>  		      <0x32016000 0x2000>;
>  		interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(1) | 
IRQ_TYPE_LEVEL_HIGH)>;
> diff --git a/arch/arm/boot/dts/rk3036.dtsi b/arch/arm/boot/dts/rk3036.dtsi
> index 4ed49a2..ff9b90b 100644
> --- a/arch/arm/boot/dts/rk3036.dtsi
> +++ b/arch/arm/boot/dts/rk3036.dtsi
> @@ -189,7 +189,7 @@
>  		#address-cells = <0>;
> 
>  		reg = <0x10139000 0x1000>,
> -		      <0x1013a000 0x1000>,
> +		      <0x1013a000 0x2000>,
>  		      <0x1013c000 0x2000>,
>  		      <0x1013e000 0x2000>;
>  		interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(2) | 
IRQ_TYPE_LEVEL_HIGH)>;
> diff --git a/arch/arm/boot/dts/rk322x.dtsi b/arch/arm/boot/dts/rk322x.dtsi
> index 9d3aee5..9dff822 100644
> --- a/arch/arm/boot/dts/rk322x.dtsi
> +++ b/arch/arm/boot/dts/rk322x.dtsi
> @@ -443,7 +443,7 @@
>  		#address-cells = <0>;
> 
>  		reg = <0x32011000 0x1000>,
> -		      <0x32012000 0x1000>,
> +		      <0x32012000 0x2000>,
>  		      <0x32014000 0x2000>,
>  		      <0x32016000 0x2000>;
>  		interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(4) | 
IRQ_TYPE_LEVEL_HIGH)>;
> diff --git a/arch/arm/boot/dts/rk3288.dtsi b/arch/arm/boot/dts/rk3288.dtsi
> index 4fad133..af46cba 100644
> --- a/arch/arm/boot/dts/rk3288.dtsi
> +++ b/arch/arm/boot/dts/rk3288.dtsi
> @@ -1110,7 +1110,7 @@
>  		#address-cells = <0>;
> 
>  		reg = <0xffc01000 0x1000>,
> -		      <0xffc02000 0x1000>,
> +		      <0xffc02000 0x2000>,
>  		      <0xffc04000 0x2000>,
>  		      <0xffc06000 0x2000>;
>  		interrupts = <GIC_PPI 9 0xf04>;

^ permalink raw reply

* [PATCH] arm64: Fix swiotlb fallback allocation
From: Catalin Marinas @ 2017-01-18 11:25 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1484567193-71258-1-git-send-email-agraf@suse.de>

On Mon, Jan 16, 2017 at 12:46:33PM +0100, Alexander Graf wrote:
> Commit b67a8b29df introduced logic to skip swiotlb allocation when all memory
> is DMA accessible anyway.
> 
> While this is a great idea, __dma_alloc still calls swiotlb code unconditionally
> to allocate memory when there is no CMA memory available. The swiotlb code is
> called to ensure that we at least try get_free_pages().
> 
> Without initialization, swiotlb allocation code tries to access io_tlb_list
> which is NULL. That results in a stack trace like this:
> 
>   Unable to handle kernel NULL pointer dereference at virtual address 00000000
>   [...]
>   [<ffff00000845b908>] swiotlb_tbl_map_single+0xd0/0x2b0
>   [<ffff00000845be94>] swiotlb_alloc_coherent+0x10c/0x198
>   [<ffff000008099dc0>] __dma_alloc+0x68/0x1a8
>   [<ffff000000a1b410>] drm_gem_cma_create+0x98/0x108 [drm]
>   [<ffff000000abcaac>] drm_fbdev_cma_create_with_funcs+0xbc/0x368 [drm_kms_helper]
>   [<ffff000000abcd84>] drm_fbdev_cma_create+0x2c/0x40 [drm_kms_helper]
>   [<ffff000000abc040>] drm_fb_helper_initial_config+0x238/0x410 [drm_kms_helper]
>   [<ffff000000abce88>] drm_fbdev_cma_init_with_funcs+0x98/0x160 [drm_kms_helper]
>   [<ffff000000abcf90>] drm_fbdev_cma_init+0x40/0x58 [drm_kms_helper]
>   [<ffff000000b47980>] vc4_kms_load+0x90/0xf0 [vc4]
>   [<ffff000000b46a94>] vc4_drm_bind+0xec/0x168 [vc4]
>   [...]
> 
> Thankfully swiotlb code just learned how to not do allocations with the FORCE_NO
> option. This patch configures the swiotlb code to use that if we decide not to
> initialize the swiotlb framework.
> 
> Fixes: b67a8b29df ("arm64: mm: only initialize swiotlb when necessary")
> Signed-off-by: Alexander Graf <agraf@suse.de>
> CC: Catalin Marinas <catalin.marinas@arm.com>
> CC: Jisheng Zhang <jszhang@marvell.com>
> CC: Geert Uytterhoeven <geert+renesas@glider.be>
> CC: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>

Queued for 4.10. Thanks.

-- 
Catalin

^ permalink raw reply

* [PATCH 0/4] Bluetooth support for GXBB/GXL/GXM based devices
From: Martin Blumenstingl @ 2017-01-18 11:25 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20170115223255.10350-1-martin.blumenstingl@googlemail.com>

Kevin,

On Sun, Jan 15, 2017 at 11:32 PM, Martin Blumenstingl
<martin.blumenstingl@googlemail.com> wrote:
> This adds the missing kernel bits for Bluetooth support on the
> Tronsmart Vega S95 (GXBB based) boards as well as for the GXL
> P230/P231 and GXM Q200/Q201 reference boards.
>
> The Bluetooth functionality on these boards is provided by the
> SDIO wifi/Bluetooth combo-chip (Broadcom bcm43xx based). The
> Bluetooth module on that combo-chip has to be taken out of reset,
> which is taken care of the GPIO in the sdio_pwrseq.
>
> Once the module is taken out of reset it can be set up from userspace
> using the "hciattach" tool from bluez, which talks to the Bluetooth
> module which is connected to one of the serial ports (in our case
> uart_A). To get the Bluetooth module initialized within the timeout
> defined by "hciattach" (and to achieve usable speeds for Bluetooth
> transfers) the communication uses a speed of 2000000 baud, which was
> not supported by meson_uart before.
>
> NOTE: The .dts-changes from this series depends on my previous series
> "add support for uart_AO_B" - see [0]
>
>
> [0] http://lists.infradead.org/pipermail/linux-amlogic/2017-January/001982.html
>
>
> Martin Blumenstingl (4):
>   tty: serial: meson: allow baud-rates higher than 115200
>   ARM64: dts: meson-gx: add the serial CTS and RTS pin groups

Neil just informed me that Rob Herring is working on defining the UART
Bluetooth device properly using devicetree (preparation for this is
named "[PATCH v2 0/9] Serial slave device bus", see [0] for the
mailing-list conversation and [1] for a WiP git repo).
This means that there will be a better solution than the one proposed
in the meson-gx-p23x-q20x and meson-gxbb-vega-s95 patches (patches #1
and #2 are not affected by this), namely:
- I'm currently (ab)using sdio-pwrseq node to power on the UART
Bluetooth module, this can solved by specifying a bluetooth {  } node
inside the &uart_A node in the future and providing the corresponding
GPIOs there
- all the userspace commands will not be necessary once
drivers/bluetooth/hci_bcm.c is changed to the serio framework and gets
devicetree support
>   ARM64: dts: meson-gx-p23x-q20x: enable the Bluetooth module
>   ARM64: dts: meson-gxbb-vega-s95: enable the Bluetooth module
>
>  .../arm64/boot/dts/amlogic/meson-gx-p23x-q20x.dtsi | 12 ++++++-
>  .../boot/dts/amlogic/meson-gxbb-vega-s95.dtsi      |  9 +++++
>  arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi        | 40 ++++++++++++++++++++++
>  arch/arm64/boot/dts/amlogic/meson-gxl.dtsi         | 40 ++++++++++++++++++++++
>  drivers/tty/serial/meson_uart.c                    |  2 +-
>  5 files changed, 101 insertions(+), 2 deletions(-)
>
> --
> 2.11.0
>


[0] http://marc.info/?l=linux-serial&m=148460728417109&w=2
[1] https://git.kernel.org/cgit/linux/kernel/git/robh/linux.git/log/?h=serial-bus-v3

^ permalink raw reply

* [PATCH 2/2] ARM: DTS: Fix register map for virt-capable GIC
From: Matthias Brugger @ 2017-01-18 11:29 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1484736811-24002-3-git-send-email-marc.zyngier@arm.com>



On 18/01/17 11:53, Marc Zyngier wrote:
> Since everybody copied my own mistake from the DT binding example,
> let's address all the offenders in one swift go.
>
> Most of them got the CPU interface size wrong (4kB, while it should
> be 8kB), except for both keystone platforms which got the control
> interface wrong (4kB instead of 8kB).
>
> In the couple of cases were I knew for sure what implementation
> was used, I've added the "arm,gic-400" compatible string. I'm 99%
> sure that this is what everyong is using, but short of having the
> TRM for all the other SoCs, I've let them alone.
>
> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
> ---
>  arch/arm/boot/dts/alpine.dtsi        | 2 +-
>  arch/arm/boot/dts/axm55xx.dtsi       | 2 +-
>  arch/arm/boot/dts/dra7.dtsi          | 2 +-
>  arch/arm/boot/dts/ecx-2000.dts       | 2 +-
>  arch/arm/boot/dts/exynos3250.dtsi    | 2 +-
>  arch/arm/boot/dts/exynos5.dtsi       | 2 +-
>  arch/arm/boot/dts/exynos5260.dtsi    | 2 +-
>  arch/arm/boot/dts/exynos5440.dtsi    | 2 +-
>  arch/arm/boot/dts/imx6ul.dtsi        | 4 ++--
>  arch/arm/boot/dts/keystone-k2g.dtsi  | 2 +-
>  arch/arm/boot/dts/keystone.dtsi      | 2 +-
>  arch/arm/boot/dts/ls1021a.dtsi       | 4 ++--
>  arch/arm/boot/dts/mt2701.dtsi        | 2 +-
>  arch/arm/boot/dts/mt6580.dtsi        | 2 +-
>  arch/arm/boot/dts/mt6589.dtsi        | 2 +-
>  arch/arm/boot/dts/mt7623.dtsi        | 2 +-
>  arch/arm/boot/dts/mt8127.dtsi        | 2 +-
>  arch/arm/boot/dts/mt8135.dtsi        | 2 +-

for the Mediatek SoCs:

Acked-by: Matthias Brugger <matthias.bgg@gmail.com>

>  arch/arm/boot/dts/omap5.dtsi         | 2 +-
>  arch/arm/boot/dts/r8a73a4.dtsi       | 2 +-
>  arch/arm/boot/dts/r8a7743.dtsi       | 2 +-
>  arch/arm/boot/dts/r8a7745.dtsi       | 2 +-
>  arch/arm/boot/dts/r8a7790.dtsi       | 2 +-
>  arch/arm/boot/dts/r8a7791.dtsi       | 2 +-
>  arch/arm/boot/dts/r8a7792.dtsi       | 2 +-
>  arch/arm/boot/dts/r8a7793.dtsi       | 2 +-
>  arch/arm/boot/dts/r8a7794.dtsi       | 2 +-
>  arch/arm/boot/dts/rk1108.dtsi        | 2 +-
>  arch/arm/boot/dts/rk3036.dtsi        | 2 +-
>  arch/arm/boot/dts/rk322x.dtsi        | 2 +-
>  arch/arm/boot/dts/rk3288.dtsi        | 2 +-
>  arch/arm/boot/dts/sun6i-a31.dtsi     | 2 +-
>  arch/arm/boot/dts/sun7i-a20.dtsi     | 4 ++--
>  arch/arm/boot/dts/sun8i-a23-a33.dtsi | 2 +-
>  arch/arm/boot/dts/sun8i-a83t.dtsi    | 2 +-
>  arch/arm/boot/dts/sun8i-h3.dtsi      | 2 +-
>  arch/arm/boot/dts/sun9i-a80.dtsi     | 2 +-
>  37 files changed, 40 insertions(+), 40 deletions(-)
>
> diff --git a/arch/arm/boot/dts/alpine.dtsi b/arch/arm/boot/dts/alpine.dtsi
> index db8752f..d0eefc3 100644
> --- a/arch/arm/boot/dts/alpine.dtsi
> +++ b/arch/arm/boot/dts/alpine.dtsi
> @@ -93,7 +93,7 @@
>  			interrupt-controller;
>  			reg = <0x0 0xfb001000 0x0 0x1000>,
>  			      <0x0 0xfb002000 0x0 0x2000>,
> -			      <0x0 0xfb004000 0x0 0x1000>,
> +			      <0x0 0xfb004000 0x0 0x2000>,
>  			      <0x0 0xfb006000 0x0 0x2000>;
>  			interrupts =
>  				<GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
> diff --git a/arch/arm/boot/dts/axm55xx.dtsi b/arch/arm/boot/dts/axm55xx.dtsi
> index a9d6d59..47799f5 100644
> --- a/arch/arm/boot/dts/axm55xx.dtsi
> +++ b/arch/arm/boot/dts/axm55xx.dtsi
> @@ -62,7 +62,7 @@
>  		#address-cells = <0>;
>  		interrupt-controller;
>  		reg = <0x20 0x01001000 0 0x1000>,
> -		      <0x20 0x01002000 0 0x1000>,
> +		      <0x20 0x01002000 0 0x2000>,
>  		      <0x20 0x01004000 0 0x2000>,
>  		      <0x20 0x01006000 0 0x2000>;
>  		interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(4) |
> diff --git a/arch/arm/boot/dts/dra7.dtsi b/arch/arm/boot/dts/dra7.dtsi
> index 1faf24a..a9ffa49 100644
> --- a/arch/arm/boot/dts/dra7.dtsi
> +++ b/arch/arm/boot/dts/dra7.dtsi
> @@ -57,7 +57,7 @@
>  		interrupt-controller;
>  		#interrupt-cells = <3>;
>  		reg = <0x0 0x48211000 0x0 0x1000>,
> -		      <0x0 0x48212000 0x0 0x1000>,
> +		      <0x0 0x48212000 0x0 0x2000>,
>  		      <0x0 0x48214000 0x0 0x2000>,
>  		      <0x0 0x48216000 0x0 0x2000>;
>  		interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_HIGH)>;
> diff --git a/arch/arm/boot/dts/ecx-2000.dts b/arch/arm/boot/dts/ecx-2000.dts
> index 2ccbb57f..c15e7e0 100644
> --- a/arch/arm/boot/dts/ecx-2000.dts
> +++ b/arch/arm/boot/dts/ecx-2000.dts
> @@ -99,7 +99,7 @@
>  			interrupt-controller;
>  			interrupts = <1 9 0xf04>;
>  			reg = <0xfff11000 0x1000>,
> -			      <0xfff12000 0x1000>,
> +			      <0xfff12000 0x2000>,
>  			      <0xfff14000 0x2000>,
>  			      <0xfff16000 0x2000>;
>  		};
> diff --git a/arch/arm/boot/dts/exynos3250.dtsi b/arch/arm/boot/dts/exynos3250.dtsi
> index ba17ee1..9c28ef4 100644
> --- a/arch/arm/boot/dts/exynos3250.dtsi
> +++ b/arch/arm/boot/dts/exynos3250.dtsi
> @@ -234,7 +234,7 @@
>  			#interrupt-cells = <3>;
>  			interrupt-controller;
>  			reg = <0x10481000 0x1000>,
> -			      <0x10482000 0x1000>,
> +			      <0x10482000 0x2000>,
>  			      <0x10484000 0x2000>,
>  			      <0x10486000 0x2000>;
>  			interrupts = <GIC_PPI 9
> diff --git a/arch/arm/boot/dts/exynos5.dtsi b/arch/arm/boot/dts/exynos5.dtsi
> index 7fd870e..678c08e 100644
> --- a/arch/arm/boot/dts/exynos5.dtsi
> +++ b/arch/arm/boot/dts/exynos5.dtsi
> @@ -94,7 +94,7 @@
>  			#interrupt-cells = <3>;
>  			interrupt-controller;
>  			reg =	<0x10481000 0x1000>,
> -				<0x10482000 0x1000>,
> +				<0x10482000 0x2000>,
>  				<0x10484000 0x2000>,
>  				<0x10486000 0x2000>;
>  			interrupts = <GIC_PPI 9
> diff --git a/arch/arm/boot/dts/exynos5260.dtsi b/arch/arm/boot/dts/exynos5260.dtsi
> index 5818718..5e88c96 100644
> --- a/arch/arm/boot/dts/exynos5260.dtsi
> +++ b/arch/arm/boot/dts/exynos5260.dtsi
> @@ -167,7 +167,7 @@
>  			#size-cells = <0>;
>  			interrupt-controller;
>  			reg = <0x10481000 0x1000>,
> -				<0x10482000 0x1000>,
> +				<0x10482000 0x2000>,
>  				<0x10484000 0x2000>,
>  				<0x10486000 0x2000>;
>  			interrupts = <GIC_PPI 9
> diff --git a/arch/arm/boot/dts/exynos5440.dtsi b/arch/arm/boot/dts/exynos5440.dtsi
> index 2a2e570..77d35bb 100644
> --- a/arch/arm/boot/dts/exynos5440.dtsi
> +++ b/arch/arm/boot/dts/exynos5440.dtsi
> @@ -40,7 +40,7 @@
>  		#interrupt-cells = <3>;
>  		interrupt-controller;
>  		reg =	<0x2E1000 0x1000>,
> -			<0x2E2000 0x1000>,
> +			<0x2E2000 0x2000>,
>  			<0x2E4000 0x2000>,
>  			<0x2E6000 0x2000>;
>  		interrupts = <GIC_PPI 9
> diff --git a/arch/arm/boot/dts/imx6ul.dtsi b/arch/arm/boot/dts/imx6ul.dtsi
> index 39845a7..ac5371a 100644
> --- a/arch/arm/boot/dts/imx6ul.dtsi
> +++ b/arch/arm/boot/dts/imx6ul.dtsi
> @@ -91,11 +91,11 @@
>  	};
>
>  	intc: interrupt-controller at 00a01000 {
> -		compatible = "arm,cortex-a7-gic";
> +		compatible = "arm,gic-400", "arm,cortex-a7-gic";
>  		#interrupt-cells = <3>;
>  		interrupt-controller;
>  		reg = <0x00a01000 0x1000>,
> -		      <0x00a02000 0x1000>,
> +		      <0x00a02000 0x2000>,
>  		      <0x00a04000 0x2000>,
>  		      <0x00a06000 0x2000>;
>  	};
> diff --git a/arch/arm/boot/dts/keystone-k2g.dtsi b/arch/arm/boot/dts/keystone-k2g.dtsi
> index 63c7cf0..07bf300 100644
> --- a/arch/arm/boot/dts/keystone-k2g.dtsi
> +++ b/arch/arm/boot/dts/keystone-k2g.dtsi
> @@ -45,7 +45,7 @@
>  		interrupt-controller;
>  		reg = <0x0 0x02561000 0x0 0x1000>,
>  		      <0x0 0x02562000 0x0 0x2000>,
> -		      <0x0 0x02564000 0x0 0x1000>,
> +		      <0x0 0x02564000 0x0 0x2000>,
>  		      <0x0 0x02566000 0x0 0x2000>;
>  		interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(4) |
>  				IRQ_TYPE_LEVEL_HIGH)>;
> diff --git a/arch/arm/boot/dts/keystone.dtsi b/arch/arm/boot/dts/keystone.dtsi
> index 02708ba..aaff6816 100644
> --- a/arch/arm/boot/dts/keystone.dtsi
> +++ b/arch/arm/boot/dts/keystone.dtsi
> @@ -35,7 +35,7 @@
>  		interrupt-controller;
>  		reg = <0x0 0x02561000 0x0 0x1000>,
>  		      <0x0 0x02562000 0x0 0x2000>,
> -		      <0x0 0x02564000 0x0 0x1000>,
> +		      <0x0 0x02564000 0x0 0x2000>,
>  		      <0x0 0x02566000 0x0 0x2000>;
>  		interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(4) |
>  				IRQ_TYPE_LEVEL_HIGH)>;
> diff --git a/arch/arm/boot/dts/ls1021a.dtsi b/arch/arm/boot/dts/ls1021a.dtsi
> index 282d854..45ea57f 100644
> --- a/arch/arm/boot/dts/ls1021a.dtsi
> +++ b/arch/arm/boot/dts/ls1021a.dtsi
> @@ -110,11 +110,11 @@
>  		ranges;
>
>  		gic: interrupt-controller at 1400000 {
> -			compatible = "arm,cortex-a7-gic";
> +			compatible = "arm,gic-400", "arm,cortex-a7-gic";
>  			#interrupt-cells = <3>;
>  			interrupt-controller;
>  			reg = <0x0 0x1401000 0x0 0x1000>,
> -			      <0x0 0x1402000 0x0 0x1000>,
> +			      <0x0 0x1402000 0x0 0x2000>,
>  			      <0x0 0x1404000 0x0 0x2000>,
>  			      <0x0 0x1406000 0x0 0x2000>;
>  			interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_HIGH)>;
> diff --git a/arch/arm/boot/dts/mt2701.dtsi b/arch/arm/boot/dts/mt2701.dtsi
> index 7eab6f4..454d099 100644
> --- a/arch/arm/boot/dts/mt2701.dtsi
> +++ b/arch/arm/boot/dts/mt2701.dtsi
> @@ -170,7 +170,7 @@
>  		#interrupt-cells = <3>;
>  		interrupt-parent = <&gic>;
>  		reg = <0 0x10211000 0 0x1000>,
> -		      <0 0x10212000 0 0x1000>,
> +		      <0 0x10212000 0 0x2000>,
>  		      <0 0x10214000 0 0x2000>,
>  		      <0 0x10216000 0 0x2000>;
>  	};
> diff --git a/arch/arm/boot/dts/mt6580.dtsi b/arch/arm/boot/dts/mt6580.dtsi
> index 06fdf6c..a349dba 100644
> --- a/arch/arm/boot/dts/mt6580.dtsi
> +++ b/arch/arm/boot/dts/mt6580.dtsi
> @@ -91,7 +91,7 @@
>  		#interrupt-cells = <3>;
>  		interrupt-parent = <&gic>;
>  		reg = <0x10211000 0x1000>,
> -		      <0x10212000 0x1000>,
> +		      <0x10212000 0x2000>,
>  		      <0x10214000 0x2000>,
>  		      <0x10216000 0x2000>;
>  	};
> diff --git a/arch/arm/boot/dts/mt6589.dtsi b/arch/arm/boot/dts/mt6589.dtsi
> index 88b3cb1..0d6f60a 100644
> --- a/arch/arm/boot/dts/mt6589.dtsi
> +++ b/arch/arm/boot/dts/mt6589.dtsi
> @@ -102,7 +102,7 @@
>  			#interrupt-cells = <3>;
>  			interrupt-parent = <&gic>;
>  			reg = <0x10211000 0x1000>,
> -			      <0x10212000 0x1000>,
> +			      <0x10212000 0x2000>,
>  			      <0x10214000 0x2000>,
>  			      <0x10216000 0x2000>;
>  		};
> diff --git a/arch/arm/boot/dts/mt7623.dtsi b/arch/arm/boot/dts/mt7623.dtsi
> index fd2b614..19a54a3 100644
> --- a/arch/arm/boot/dts/mt7623.dtsi
> +++ b/arch/arm/boot/dts/mt7623.dtsi
> @@ -104,7 +104,7 @@
>  		#interrupt-cells = <3>;
>  		interrupt-parent = <&gic>;
>  		reg = <0 0x10211000 0 0x1000>,
> -		      <0 0x10212000 0 0x1000>,
> +		      <0 0x10212000 0 0x2000>,
>  		      <0 0x10214000 0 0x2000>,
>  		      <0 0x10216000 0 0x2000>;
>  	};
> diff --git a/arch/arm/boot/dts/mt8127.dtsi b/arch/arm/boot/dts/mt8127.dtsi
> index 52086c8..916c095 100644
> --- a/arch/arm/boot/dts/mt8127.dtsi
> +++ b/arch/arm/boot/dts/mt8127.dtsi
> @@ -129,7 +129,7 @@
>  			#interrupt-cells = <3>;
>  			interrupt-parent = <&gic>;
>  			reg = <0 0x10211000 0 0x1000>,
> -			      <0 0x10212000 0 0x1000>,
> +			      <0 0x10212000 0 0x2000>,
>  			      <0 0x10214000 0 0x2000>,
>  			      <0 0x10216000 0 0x2000>;
>  		};
> diff --git a/arch/arm/boot/dts/mt8135.dtsi b/arch/arm/boot/dts/mt8135.dtsi
> index 1d7f92b..a97b4ee 100644
> --- a/arch/arm/boot/dts/mt8135.dtsi
> +++ b/arch/arm/boot/dts/mt8135.dtsi
> @@ -221,7 +221,7 @@
>  			#interrupt-cells = <3>;
>  			interrupt-parent = <&gic>;
>  			reg = <0 0x10211000 0 0x1000>,
> -			      <0 0x10212000 0 0x1000>,
> +			      <0 0x10212000 0 0x2000>,
>  			      <0 0x10214000 0 0x2000>,
>  			      <0 0x10216000 0 0x2000>;
>  		};
> diff --git a/arch/arm/boot/dts/omap5.dtsi b/arch/arm/boot/dts/omap5.dtsi
> index 7cd92ba..71b4809 100644
> --- a/arch/arm/boot/dts/omap5.dtsi
> +++ b/arch/arm/boot/dts/omap5.dtsi
> @@ -92,7 +92,7 @@
>  		interrupt-controller;
>  		#interrupt-cells = <3>;
>  		reg = <0 0x48211000 0 0x1000>,
> -		      <0 0x48212000 0 0x1000>,
> +		      <0 0x48212000 0 0x2000>,
>  		      <0 0x48214000 0 0x2000>,
>  		      <0 0x48216000 0 0x2000>;
>  		interrupt-parent = <&gic>;
> diff --git a/arch/arm/boot/dts/r8a73a4.dtsi b/arch/arm/boot/dts/r8a73a4.dtsi
> index 53183ff..14a66ca 100644
> --- a/arch/arm/boot/dts/r8a73a4.dtsi
> +++ b/arch/arm/boot/dts/r8a73a4.dtsi
> @@ -465,7 +465,7 @@
>  		#address-cells = <0>;
>  		interrupt-controller;
>  		reg = <0 0xf1001000 0 0x1000>,
> -			<0 0xf1002000 0 0x1000>,
> +			<0 0xf1002000 0 0x2000>,
>  			<0 0xf1004000 0 0x2000>,
>  			<0 0xf1006000 0 0x2000>;
>  		interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
> diff --git a/arch/arm/boot/dts/r8a7743.dtsi b/arch/arm/boot/dts/r8a7743.dtsi
> index 216cb1f..172a944 100644
> --- a/arch/arm/boot/dts/r8a7743.dtsi
> +++ b/arch/arm/boot/dts/r8a7743.dtsi
> @@ -55,7 +55,7 @@
>  			#address-cells = <0>;
>  			interrupt-controller;
>  			reg = <0 0xf1001000 0 0x1000>,
> -			      <0 0xf1002000 0 0x1000>,
> +			      <0 0xf1002000 0 0x2000>,
>  			      <0 0xf1004000 0 0x2000>,
>  			      <0 0xf1006000 0 0x2000>;
>  			interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(2) |
> diff --git a/arch/arm/boot/dts/r8a7745.dtsi b/arch/arm/boot/dts/r8a7745.dtsi
> index 0b2e2f3..7390ec0 100644
> --- a/arch/arm/boot/dts/r8a7745.dtsi
> +++ b/arch/arm/boot/dts/r8a7745.dtsi
> @@ -55,7 +55,7 @@
>  			#address-cells = <0>;
>  			interrupt-controller;
>  			reg = <0 0xf1001000 0 0x1000>,
> -			      <0 0xf1002000 0 0x1000>,
> +			      <0 0xf1002000 0 0x2000>,
>  			      <0 0xf1004000 0 0x2000>,
>  			      <0 0xf1006000 0 0x2000>;
>  			interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(2) |
> diff --git a/arch/arm/boot/dts/r8a7790.dtsi b/arch/arm/boot/dts/r8a7790.dtsi
> index 0c8900d..ac38764 100644
> --- a/arch/arm/boot/dts/r8a7790.dtsi
> +++ b/arch/arm/boot/dts/r8a7790.dtsi
> @@ -183,7 +183,7 @@
>  		#address-cells = <0>;
>  		interrupt-controller;
>  		reg = <0 0xf1001000 0 0x1000>,
> -			<0 0xf1002000 0 0x1000>,
> +			<0 0xf1002000 0 0x2000>,
>  			<0 0xf1004000 0 0x2000>,
>  			<0 0xf1006000 0 0x2000>;
>  		interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
> diff --git a/arch/arm/boot/dts/r8a7791.dtsi b/arch/arm/boot/dts/r8a7791.dtsi
> index 8721466..28039db 100644
> --- a/arch/arm/boot/dts/r8a7791.dtsi
> +++ b/arch/arm/boot/dts/r8a7791.dtsi
> @@ -114,7 +114,7 @@
>  		#address-cells = <0>;
>  		interrupt-controller;
>  		reg = <0 0xf1001000 0 0x1000>,
> -			<0 0xf1002000 0 0x1000>,
> +			<0 0xf1002000 0 0x2000>,
>  			<0 0xf1004000 0 0x2000>,
>  			<0 0xf1006000 0 0x2000>;
>  		interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_HIGH)>;
> diff --git a/arch/arm/boot/dts/r8a7792.dtsi b/arch/arm/boot/dts/r8a7792.dtsi
> index 6ced3c1..1ed5c88 100644
> --- a/arch/arm/boot/dts/r8a7792.dtsi
> +++ b/arch/arm/boot/dts/r8a7792.dtsi
> @@ -88,7 +88,7 @@
>  			#interrupt-cells = <3>;
>  			interrupt-controller;
>  			reg = <0 0xf1001000 0 0x1000>,
> -			      <0 0xf1002000 0 0x1000>,
> +			      <0 0xf1002000 0 0x2000>,
>  			      <0 0xf1004000 0 0x2000>,
>  			      <0 0xf1006000 0 0x2000>;
>  			interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(2) |
> diff --git a/arch/arm/boot/dts/r8a7793.dtsi b/arch/arm/boot/dts/r8a7793.dtsi
> index 2fb527c..934c097 100644
> --- a/arch/arm/boot/dts/r8a7793.dtsi
> +++ b/arch/arm/boot/dts/r8a7793.dtsi
> @@ -105,7 +105,7 @@
>  		#address-cells = <0>;
>  		interrupt-controller;
>  		reg = <0 0xf1001000 0 0x1000>,
> -			<0 0xf1002000 0 0x1000>,
> +			<0 0xf1002000 0 0x2000>,
>  			<0 0xf1004000 0 0x2000>,
>  			<0 0xf1006000 0 0x2000>;
>  		interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_HIGH)>;
> diff --git a/arch/arm/boot/dts/r8a7794.dtsi b/arch/arm/boot/dts/r8a7794.dtsi
> index fb576db..09f7823 100644
> --- a/arch/arm/boot/dts/r8a7794.dtsi
> +++ b/arch/arm/boot/dts/r8a7794.dtsi
> @@ -71,7 +71,7 @@
>  		#address-cells = <0>;
>  		interrupt-controller;
>  		reg = <0 0xf1001000 0 0x1000>,
> -			<0 0xf1002000 0 0x1000>,
> +			<0 0xf1002000 0 0x2000>,
>  			<0 0xf1004000 0 0x2000>,
>  			<0 0xf1006000 0 0x2000>;
>  		interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_HIGH)>;
> diff --git a/arch/arm/boot/dts/rk1108.dtsi b/arch/arm/boot/dts/rk1108.dtsi
> index d770023..d6194bf 100644
> --- a/arch/arm/boot/dts/rk1108.dtsi
> +++ b/arch/arm/boot/dts/rk1108.dtsi
> @@ -215,7 +215,7 @@
>  		#address-cells = <0>;
>
>  		reg = <0x32011000 0x1000>,
> -		      <0x32012000 0x1000>,
> +		      <0x32012000 0x2000>,
>  		      <0x32014000 0x2000>,
>  		      <0x32016000 0x2000>;
>  		interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(1) | IRQ_TYPE_LEVEL_HIGH)>;
> diff --git a/arch/arm/boot/dts/rk3036.dtsi b/arch/arm/boot/dts/rk3036.dtsi
> index 4ed49a2..ff9b90b 100644
> --- a/arch/arm/boot/dts/rk3036.dtsi
> +++ b/arch/arm/boot/dts/rk3036.dtsi
> @@ -189,7 +189,7 @@
>  		#address-cells = <0>;
>
>  		reg = <0x10139000 0x1000>,
> -		      <0x1013a000 0x1000>,
> +		      <0x1013a000 0x2000>,
>  		      <0x1013c000 0x2000>,
>  		      <0x1013e000 0x2000>;
>  		interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_HIGH)>;
> diff --git a/arch/arm/boot/dts/rk322x.dtsi b/arch/arm/boot/dts/rk322x.dtsi
> index 9d3aee5..9dff822 100644
> --- a/arch/arm/boot/dts/rk322x.dtsi
> +++ b/arch/arm/boot/dts/rk322x.dtsi
> @@ -443,7 +443,7 @@
>  		#address-cells = <0>;
>
>  		reg = <0x32011000 0x1000>,
> -		      <0x32012000 0x1000>,
> +		      <0x32012000 0x2000>,
>  		      <0x32014000 0x2000>,
>  		      <0x32016000 0x2000>;
>  		interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
> diff --git a/arch/arm/boot/dts/rk3288.dtsi b/arch/arm/boot/dts/rk3288.dtsi
> index 4fad133..af46cba 100644
> --- a/arch/arm/boot/dts/rk3288.dtsi
> +++ b/arch/arm/boot/dts/rk3288.dtsi
> @@ -1110,7 +1110,7 @@
>  		#address-cells = <0>;
>
>  		reg = <0xffc01000 0x1000>,
> -		      <0xffc02000 0x1000>,
> +		      <0xffc02000 0x2000>,
>  		      <0xffc04000 0x2000>,
>  		      <0xffc06000 0x2000>;
>  		interrupts = <GIC_PPI 9 0xf04>;
> diff --git a/arch/arm/boot/dts/sun6i-a31.dtsi b/arch/arm/boot/dts/sun6i-a31.dtsi
> index 2b26175..6ed505a 100644
> --- a/arch/arm/boot/dts/sun6i-a31.dtsi
> +++ b/arch/arm/boot/dts/sun6i-a31.dtsi
> @@ -861,7 +861,7 @@
>  		gic: interrupt-controller at 01c81000 {
>  			compatible = "arm,cortex-a7-gic", "arm,cortex-a15-gic";
>  			reg = <0x01c81000 0x1000>,
> -			      <0x01c82000 0x1000>,
> +			      <0x01c82000 0x2000>,
>  			      <0x01c84000 0x2000>,
>  			      <0x01c86000 0x2000>;
>  			interrupt-controller;
> diff --git a/arch/arm/boot/dts/sun7i-a20.dtsi b/arch/arm/boot/dts/sun7i-a20.dtsi
> index f7db067..3c24832 100644
> --- a/arch/arm/boot/dts/sun7i-a20.dtsi
> +++ b/arch/arm/boot/dts/sun7i-a20.dtsi
> @@ -1686,9 +1686,9 @@
>  		};
>
>  		gic: interrupt-controller at 01c81000 {
> -			compatible = "arm,cortex-a7-gic", "arm,cortex-a15-gic";
> +			compatible = "arm,gic-400", "arm,cortex-a7-gic", "arm,cortex-a15-gic";
>  			reg = <0x01c81000 0x1000>,
> -			      <0x01c82000 0x1000>,
> +			      <0x01c82000 0x2000>,
>  			      <0x01c84000 0x2000>,
>  			      <0x01c86000 0x2000>;
>  			interrupt-controller;
> diff --git a/arch/arm/boot/dts/sun8i-a23-a33.dtsi b/arch/arm/boot/dts/sun8i-a23-a33.dtsi
> index e4991a7..49dfe86 100644
> --- a/arch/arm/boot/dts/sun8i-a23-a33.dtsi
> +++ b/arch/arm/boot/dts/sun8i-a23-a33.dtsi
> @@ -489,7 +489,7 @@
>  		gic: interrupt-controller at 01c81000 {
>  			compatible = "arm,cortex-a7-gic", "arm,cortex-a15-gic";
>  			reg = <0x01c81000 0x1000>,
> -			      <0x01c82000 0x1000>,
> +			      <0x01c82000 0x2000>,
>  			      <0x01c84000 0x2000>,
>  			      <0x01c86000 0x2000>;
>  			interrupt-controller;
> diff --git a/arch/arm/boot/dts/sun8i-a83t.dtsi b/arch/arm/boot/dts/sun8i-a83t.dtsi
> index d3473f8..04c3fdd 100644
> --- a/arch/arm/boot/dts/sun8i-a83t.dtsi
> +++ b/arch/arm/boot/dts/sun8i-a83t.dtsi
> @@ -217,7 +217,7 @@
>  		gic: interrupt-controller at 01c81000 {
>  			compatible = "arm,cortex-a7-gic", "arm,cortex-a15-gic";
>  			reg = <0x01c81000 0x1000>,
> -			      <0x01c82000 0x1000>,
> +			      <0x01c82000 0x2000>,
>  			      <0x01c84000 0x2000>,
>  			      <0x01c86000 0x2000>;
>  			interrupt-controller;
> diff --git a/arch/arm/boot/dts/sun8i-h3.dtsi b/arch/arm/boot/dts/sun8i-h3.dtsi
> index 6c14a6f..292abd0 100644
> --- a/arch/arm/boot/dts/sun8i-h3.dtsi
> +++ b/arch/arm/boot/dts/sun8i-h3.dtsi
> @@ -580,7 +580,7 @@
>  		gic: interrupt-controller at 01c81000 {
>  			compatible = "arm,cortex-a7-gic", "arm,cortex-a15-gic";
>  			reg = <0x01c81000 0x1000>,
> -			      <0x01c82000 0x1000>,
> +			      <0x01c82000 0x2000>,
>  			      <0x01c84000 0x2000>,
>  			      <0x01c86000 0x2000>;
>  			interrupt-controller;
> diff --git a/arch/arm/boot/dts/sun9i-a80.dtsi b/arch/arm/boot/dts/sun9i-a80.dtsi
> index 979ad1a..b7b5831 100644
> --- a/arch/arm/boot/dts/sun9i-a80.dtsi
> +++ b/arch/arm/boot/dts/sun9i-a80.dtsi
> @@ -613,7 +613,7 @@
>  		gic: interrupt-controller at 01c41000 {
>  			compatible = "arm,cortex-a7-gic", "arm,cortex-a15-gic";
>  			reg = <0x01c41000 0x1000>,
> -			      <0x01c42000 0x1000>,
> +			      <0x01c42000 0x2000>,
>  			      <0x01c44000 0x2000>,
>  			      <0x01c46000 0x2000>;
>  			interrupt-controller;
>

^ permalink raw reply

* [PATCH v3 6/9] kvm: arm/arm64: Add host pmu to support VM introspection
From: Mark Rutland @ 2017-01-18 11:35 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1a6b8d71-58a5-b29b-3f01-e945deb2baf6@arm.com>

On Wed, Jan 18, 2017 at 11:21:21AM +0000, Marc Zyngier wrote:
> On 10/01/17 11:38, Punit Agrawal wrote:
> > +#define VM_MASK	GENMASK_ULL(31, 0)
> > +#define EVENT_MASK	GENMASK_ULL(32, 39)
> > +#define EVENT_SHIFT	(32)
> > +
> > +#define to_pid(cfg)	((cfg) & VM_MASK)
> > +#define to_event(cfg)	(((cfg) & EVENT_MASK) >> EVENT_SHIFT)
> > +
> > +PMU_FORMAT_ATTR(vm, "config:0-31");
> > +PMU_FORMAT_ATTR(event, "config:32-39");
> 
> I'm a bit confused by these. Can't you get the PID of the VM you're
> tracing directly from perf, without having to encode things? And if you
> can't, surely this should be a function of the size of pid_t?
>
> Mark, can you shine some light here?

AFAICT, this is not necessary.

The perf_event_open() syscall takes a PID separately from the
perf_event_attr. i.e. we should be able to do:

// monitor a particular vCPU
perf_event_open(attr, vcpupid, -1, -1, 0)

... or .. 

// monitor a particular vCPU on a pCPU
perf_event_open(attr, vcpupid, cpu, -1, 0)

... or ...

// monitor all vCPUs on a pCPU
perf_event_open(attr, -1, cpu, -1, 0)

... so this shouldn't be necessary. AFAICT, this is a SW PMU, so there
should be no issue with using the perf_sw_context.

If this is a bodge to avoid opening a perf_event per vCPU thread, then I
completely disagree with the approach. This would be better handled in
userspace by discovering the set of threads and opening events for each.

Thanks,
Mark.

^ permalink raw reply

* [PATCH v7 4/8] PWM: add PWM driver for STM32 plaftorm
From: Thierry Reding @ 2017-01-18 11:37 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CA+M3ks64VEE8a0oeiA8J-T5FDzwWTo=pdaMACy+pz7EyOQY-Jg@mail.gmail.com>

On Wed, Jan 18, 2017 at 12:15:58PM +0100, Benjamin Gaignard wrote:
> 2017-01-18 11:08 GMT+01:00 Thierry Reding <thierry.reding@gmail.com>:
> > On Thu, Jan 05, 2017 at 10:25:40AM +0100, Benjamin Gaignard wrote:
[...]
> >> +static u32 active_channels(struct stm32_pwm *dev)
> >> +{
> >> +     u32 ccer;
> >> +
> >> +     regmap_read(dev->regmap, TIM_CCER, &ccer);
> >> +
> >> +     return ccer & TIM_CCER_CCXE;
> >> +}
> >
> > This looks like something that you could track in software, but this is
> > probably fine, too. Again, technically regmap_read() could fail, so you
> > might want to consider adding some code to handle it. In practice it
> > probably won't, so maybe you don't.
> 
> TIM_CCER_CCXE is a value that IIO timer can also read (not write) so
> I have keep the same logic for pwm driver.

Would that not be racy? What happens if after active_channels() here,
the IIO timer modifies the TIM_CCER register?

> >> +     ret = stm32_pwm_config(chip, pwm, state->duty_cycle, state->period);
> >> +     if (ret)
> >> +             return ret;
> >> +
> >> +     if (!enabled && state->enabled)
> >> +             ret = stm32_pwm_enable(chip, pwm);
> >> +
> >> +     return ret;
> >> +}
> >
> > Would it be possible to merge stm32_pwm_disable(), stm32_pwm_enable(),
> > stm32_pwm_set_polarity() and stm32_pwm_config() into stm32_pwm_apply()?
> > Part of the reason for the atomic API was to make it easier to write
> > these drivers, but your implementation effectively copies what the
> > transitional helpers do.
> >
> > It might not make a difference technically in your case, but I think
> > it'd make the implementation more compact and set a better example for
> > future reference.
> 
> hmm... it will create a fat function with lot of where
> enabling/disabling/configuration
> will be mixed I'm really not convince that will more compact and readable.

I don't object to splitting this up into separate functions, I just
don't think the functions should correspond to the legacy ones. One
variant that I think could work out nicely would be to have one
function that precomputes the various values, call in from ->apply()
and then do only the register writes along with a couple of
conditionals depending on enable state, for example.

> >> +static const struct pwm_ops stm32pwm_ops = {
> >> +     .owner = THIS_MODULE,
> >> +     .apply = stm32_pwm_apply,
> >> +};
> >> +
> >> +static int stm32_pwm_set_breakinput(struct stm32_pwm *priv,
> >> +                                 int level, int filter)
> >> +{
> >> +     u32 bdtr = TIM_BDTR_BKE;
> >> +
> >> +     if (level)
> >> +             bdtr |= TIM_BDTR_BKP;
> >> +
> >> +     bdtr |= (filter & TIM_BDTR_BKF_MASK) << TIM_BDTR_BKF_SHIFT;
> >> +
> >> +     regmap_update_bits(priv->regmap,
> >> +                        TIM_BDTR, TIM_BDTR_BKE | TIM_BDTR_BKP | TIM_BDTR_BKF,
> >> +                        bdtr);
> >> +
> >> +     regmap_read(priv->regmap, TIM_BDTR, &bdtr);
> >> +
> >> +     return (bdtr & TIM_BDTR_BKE) ? 0 : -EINVAL;
> >> +}
> >> +
> >> +static int stm32_pwm_set_breakinput2(struct stm32_pwm *priv,
> >> +                                  int level, int filter)
> >> +{
> >> +     u32 bdtr = TIM_BDTR_BK2E;
> >> +
> >> +     if (level)
> >> +             bdtr |= TIM_BDTR_BK2P;
> >> +
> >> +     bdtr |= (filter & TIM_BDTR_BKF_MASK) << TIM_BDTR_BK2F_SHIFT;
> >> +
> >> +     regmap_update_bits(priv->regmap,
> >> +                        TIM_BDTR, TIM_BDTR_BK2E |
> >> +                        TIM_BDTR_BK2P |
> >> +                        TIM_BDTR_BK2F,
> >> +                        bdtr);
> >> +
> >> +     regmap_read(priv->regmap, TIM_BDTR, &bdtr);
> >> +
> >> +     return (bdtr & TIM_BDTR_BK2E) ? 0 : -EINVAL;
> >> +}
> >
> > As far as I can tell the only difference here is the various bit
> > positions. Can you collapse the above two functions and add a new
> > parameter to unify some code?
> 
> Yes it is all about bit shifting, I had try unify those two functions
> with index has additional parameter
> but it just add if() before each lines so no real benefit for code size.

How about if you precompute the values and masks? Something like:

	u32 bke = (index == 0) ? ... : ...;
	u32 bkp = (index == 0) ? ... : ...;
	u32 bkf = (index == 0) ? ... : ...;
	u32 mask = (index == 0) ? ... : ...;

	bdtr = bke | bkf;

	if (level)
		bdtr |= bkp;

	regmap_update_bits(priv->regmap, TIM_BDTR, mask, bdtr);

	regmap_read(priv->regmap, TIM_BDTR, &bdtr);

	return (bdtr & bke) ? 0 : -EINVAL;

?
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20170118/7b32fa5f/attachment.sig>

^ permalink raw reply

* [PATCH v8 18/18] iommu/arm-smmu: Do not advertise IOMMU_CAP_INTR_REMAP anymore
From: Tomasz Nowicki @ 2017-01-18 11:46 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1484127714-3263-19-git-send-email-eric.auger@redhat.com>

On 11.01.2017 10:41, Eric Auger wrote:
> IOMMU_CAP_INTR_REMAP has been advertised in arm-smmu(-v3) although
> on ARM this property is not attached to the IOMMU but rather is
> implemented in the MSI controller (GICv3 ITS).
>
> Now vfio_iommu_type1 checks MSI remapping capability at MSI controller
> level, let's correct this.
>
> Signed-off-by: Eric Auger <eric.auger@redhat.com>
> Acked-by: Will Deacon <will.deacon@arm.com>

For patches [15-18]:
Reviewed-by: Tomasz Nowicki <tomasz.nowicki@caviumnetworks.com>

Thanks,
Tomasz

>
> ---
>
> v7 -> v8:
> - added Will's A-b
> ---
>  drivers/iommu/arm-smmu-v3.c | 2 --
>  drivers/iommu/arm-smmu.c    | 2 --
>  2 files changed, 4 deletions(-)
>
> diff --git a/drivers/iommu/arm-smmu-v3.c b/drivers/iommu/arm-smmu-v3.c
> index 6c4111c..d9cf6cb 100644
> --- a/drivers/iommu/arm-smmu-v3.c
> +++ b/drivers/iommu/arm-smmu-v3.c
> @@ -1375,8 +1375,6 @@ static bool arm_smmu_capable(enum iommu_cap cap)
>  	switch (cap) {
>  	case IOMMU_CAP_CACHE_COHERENCY:
>  		return true;
> -	case IOMMU_CAP_INTR_REMAP:
> -		return true; /* MSIs are just memory writes */
>  	case IOMMU_CAP_NOEXEC:
>  		return true;
>  	default:
> diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
> index a354572..13d2600 100644
> --- a/drivers/iommu/arm-smmu.c
> +++ b/drivers/iommu/arm-smmu.c
> @@ -1374,8 +1374,6 @@ static bool arm_smmu_capable(enum iommu_cap cap)
>  		 * requests.
>  		 */
>  		return true;
> -	case IOMMU_CAP_INTR_REMAP:
> -		return true; /* MSIs are just memory writes */
>  	case IOMMU_CAP_NOEXEC:
>  		return true;
>  	default:
>

^ permalink raw reply

* [PATCH] ARM: OMAP5: Add HWMOD_SWSUP_SIDLE_ACT flag for UART
From: Vignesh R @ 2017-01-18 11:48 UTC (permalink / raw)
  To: linux-arm-kernel

According to the commit ca43ea345de9 ("ARM: OMAP2+: hwmod: Add a new
flag to handle SIDLE in SWSUP only in active"), UART IP needs the sidle
mode to be controlled in SW only while they are active. Once inactive,
the IP needs to be put back in HW control so they are also wakeup
capable. The flag HWMOD_SWSUP_SIDLE takes care of this. So add this flag
to all instances of UART.

With this change, 8250 UART now gives out proper RX Timeout interrupts
and is usable as console.

Signed-off-by: Vignesh R <vigneshr@ti.com>
---

Tested on OMAP5 uEVM.

 arch/arm/mach-omap2/omap_hwmod_54xx_data.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/arch/arm/mach-omap2/omap_hwmod_54xx_data.c b/arch/arm/mach-omap2/omap_hwmod_54xx_data.c
index 8cdfd9b7ab4f..a2d763a4cc57 100644
--- a/arch/arm/mach-omap2/omap_hwmod_54xx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_54xx_data.c
@@ -1748,6 +1748,7 @@ static struct omap_hwmod omap54xx_uart1_hwmod = {
 	.name		= "uart1",
 	.class		= &omap54xx_uart_hwmod_class,
 	.clkdm_name	= "l4per_clkdm",
+	.flags		= HWMOD_SWSUP_SIDLE_ACT,
 	.main_clk	= "func_48m_fclk",
 	.prcm = {
 		.omap4 = {
@@ -1763,6 +1764,7 @@ static struct omap_hwmod omap54xx_uart2_hwmod = {
 	.name		= "uart2",
 	.class		= &omap54xx_uart_hwmod_class,
 	.clkdm_name	= "l4per_clkdm",
+	.flags		= HWMOD_SWSUP_SIDLE_ACT,
 	.main_clk	= "func_48m_fclk",
 	.prcm = {
 		.omap4 = {
@@ -1778,7 +1780,7 @@ static struct omap_hwmod omap54xx_uart3_hwmod = {
 	.name		= "uart3",
 	.class		= &omap54xx_uart_hwmod_class,
 	.clkdm_name	= "l4per_clkdm",
-	.flags		= DEBUG_OMAP4UART3_FLAGS,
+	.flags		= DEBUG_OMAP4UART3_FLAGS | HWMOD_SWSUP_SIDLE_ACT,
 	.main_clk	= "func_48m_fclk",
 	.prcm = {
 		.omap4 = {
@@ -1794,7 +1796,7 @@ static struct omap_hwmod omap54xx_uart4_hwmod = {
 	.name		= "uart4",
 	.class		= &omap54xx_uart_hwmod_class,
 	.clkdm_name	= "l4per_clkdm",
-	.flags		= DEBUG_OMAP4UART4_FLAGS,
+	.flags		= DEBUG_OMAP4UART4_FLAGS | HWMOD_SWSUP_SIDLE_ACT,
 	.main_clk	= "func_48m_fclk",
 	.prcm = {
 		.omap4 = {
@@ -1810,6 +1812,7 @@ static struct omap_hwmod omap54xx_uart5_hwmod = {
 	.name		= "uart5",
 	.class		= &omap54xx_uart_hwmod_class,
 	.clkdm_name	= "l4per_clkdm",
+	.flags		= HWMOD_SWSUP_SIDLE_ACT,
 	.main_clk	= "func_48m_fclk",
 	.prcm = {
 		.omap4 = {
@@ -1825,6 +1828,7 @@ static struct omap_hwmod omap54xx_uart6_hwmod = {
 	.name		= "uart6",
 	.class		= &omap54xx_uart_hwmod_class,
 	.clkdm_name	= "l4per_clkdm",
+	.flags		= HWMOD_SWSUP_SIDLE_ACT,
 	.main_clk	= "func_48m_fclk",
 	.prcm = {
 		.omap4 = {
-- 
2.11.0

^ permalink raw reply related

* [PATCH 2/2] ARM: DTS: Fix register map for virt-capable GIC
From: Robin Murphy @ 2017-01-18 11:57 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1484736811-24002-3-git-send-email-marc.zyngier@arm.com>

On 18/01/17 10:53, Marc Zyngier wrote:
> Since everybody copied my own mistake from the DT binding example,
> let's address all the offenders in one swift go.
> 
> Most of them got the CPU interface size wrong (4kB, while it should
> be 8kB), except for both keystone platforms which got the control
> interface wrong (4kB instead of 8kB).
> 
> In the couple of cases were I knew for sure what implementation

                         where

> was used, I've added the "arm,gic-400" compatible string. I'm 99%
> sure that this is what everyong is using, but short of having the

                         everyone

> TRM for all the other SoCs, I've let them alone.
> 
> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
> ---
[...]
> diff --git a/arch/arm/boot/dts/keystone-k2g.dtsi b/arch/arm/boot/dts/keystone-k2g.dtsi
> index 63c7cf0..07bf300 100644
> --- a/arch/arm/boot/dts/keystone-k2g.dtsi
> +++ b/arch/arm/boot/dts/keystone-k2g.dtsi
> @@ -45,7 +45,7 @@
>  		interrupt-controller;
>  		reg = <0x0 0x02561000 0x0 0x1000>,
>  		      <0x0 0x02562000 0x0 0x2000>,
> -		      <0x0 0x02564000 0x0 0x1000>,
> +		      <0x0 0x02564000 0x0 0x2000>,
>  		      <0x0 0x02566000 0x0 0x2000>;
>  		interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(4) |
>  				IRQ_TYPE_LEVEL_HIGH)>;
> diff --git a/arch/arm/boot/dts/keystone.dtsi b/arch/arm/boot/dts/keystone.dtsi
> index 02708ba..aaff6816 100644
> --- a/arch/arm/boot/dts/keystone.dtsi
> +++ b/arch/arm/boot/dts/keystone.dtsi
> @@ -35,7 +35,7 @@
>  		interrupt-controller;
>  		reg = <0x0 0x02561000 0x0 0x1000>,
>  		      <0x0 0x02562000 0x0 0x2000>,
> -		      <0x0 0x02564000 0x0 0x1000>,
> +		      <0x0 0x02564000 0x0 0x2000>,
>  		      <0x0 0x02566000 0x0 0x2000>;
>  		interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(4) |
>  				IRQ_TYPE_LEVEL_HIGH)>;

FWIW I happen to have some public Keystone TRMs handy from my DMA offset
investigations, and both K2G and K2H explicitly say it's a GIC-400 too.

Robin.

^ permalink raw reply

* [PATCH 1/2] ARM: dts: dra7-evm: increase QSPI SPL partition size
From: Sekhar Nori @ 2017-01-18 11:58 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20170117232743.GA7403@atomide.com>

Hi Tony,

On Wednesday 18 January 2017 04:57 AM, Tony Lindgren wrote:
> * B, Ravi <ravibabu@ti.com> [170117 00:15]:
>> Hi Tony
>>
>>> * Ravi Babu <ravibabu@ti.com> [170113 04:41]:
>>>> The SPL size for DRA74x platform has increased and is now more than 
>>>> 64KB. Increase QSPI SPL partition size to 256KB for DRA74x EVM.
>>>>
>>>> QSPI partition numbering changes because of this.
>>
>>> And this will break the existing partitions potentially..
>>> See what was discussed on the list few days ago in thread "[PATCH 1/6] ARM: dts: am335x-phycore-som: Update NAND partition table".
>>
>>> It's best to have these left empty or as they originally were and let u-boot configure the partitions.
>>
>> Agree with you. For dra7xx platform the SPL size has been increased to 256KB and hence the existing QSPI SPL partition in kernel (64K size) will break when latest mainline u-boot is used. 
>> Here only SPL partition has been changed and other partition & size is NOT changed and kept intact. I feel it will not break the existing partitions for dra7xx platform.
> 
> What about the renumbering of partitions in your patch?

Thats true, partitions will get renumbered. But mtd numbering can change
depending on probe order of devices anyway. So usespace which uses
hardcoded mtd partition numbers is pretty fragile already, I guess.

> 
> Probably just best to make the partition information empty in the
> kernel as discussed.

Given that existing dtbs already have the partition information, wont
this be treated as a regression for someone upgrading to new kernel?

Going forward, is the preference that new boards shall not have
partition information in DT?

Thanks,
Sekhar

^ permalink raw reply

* [PATCH] arm64/cpufeatures: Enforce inline/const properties of cpus_have_const_cap
From: Marc Zyngier @ 2017-01-18 11:58 UTC (permalink / raw)
  To: linux-arm-kernel

Despite being flagged "inline", cpus_have_const_cap may end-up being
placed out of line if the compiler decides so. This would be unfortunate,
as we want to be able to use this function in HYP, where we need to
be 100% sure of what is mapped there. __always_inline seems to be a
better choice given the constraint.

Also, be a lot tougher on non-const or out-of-range capability values
(a non-const cap value shouldn't be used here, and the semantic of an
OOR value is at best ill defined). In those two case, BUILD_BUG_ON is
what you get.

Reviewed-by: Suzuki K Poulose <suzuki.poulose@arm.com>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 arch/arm64/include/asm/cpufeature.h | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/arch/arm64/include/asm/cpufeature.h b/arch/arm64/include/asm/cpufeature.h
index b4989df..4710469 100644
--- a/arch/arm64/include/asm/cpufeature.h
+++ b/arch/arm64/include/asm/cpufeature.h
@@ -105,10 +105,11 @@ static inline bool cpu_have_feature(unsigned int num)
 }
 
 /* System capability check for constant caps */
-static inline bool cpus_have_const_cap(int num)
+static __always_inline bool cpus_have_const_cap(int num)
 {
-	if (num >= ARM64_NCAPS)
-		return false;
+	BUILD_BUG_ON(!__builtin_constant_p(num));
+	BUILD_BUG_ON(num >= ARM64_NCAPS);
+
 	return static_branch_unlikely(&cpu_hwcap_keys[num]);
 }
 
-- 
2.1.4

^ permalink raw reply related

* [PATCH v2 00/13] Move pad retention control to Exynos pin controller driver
From: Krzysztof Kozlowski @ 2017-01-18 12:06 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CACRpkdbXcY5PtLUfJ5idq0XnHUZOdUk2GT5PVG9pkNYvQJ4vbQ@mail.gmail.com>

On Wed, Jan 18, 2017 at 12:39 PM, Linus Walleij
<linus.walleij@linaro.org> wrote:
> On Tue, Jan 17, 2017 at 1:44 PM, Marek Szyprowski
> <m.szyprowski@samsung.com> wrote:
>
>> This patchset is a follow-up of my work on adding runtime PM support
>> to Exynos pin controller driver:
>> http://www.spinics.net/lists/arm-kernel/msg550161.html
>
> Nice, once you are done fixing the remaining nits, add Tomasz ACKs
> and resend as v3 and I will apply it.

Wait, for the pinctrl patches (and also the commits moving the bits
arch/arm -> pintrl) you need the soc changes (mostly: the header).
I'll prepare a tag with them but I am still giving some time for
review.

Best regards,
Krzysztof

^ permalink raw reply

* [PATCH v4 1/2] power: reset: add linkstation-reset driver
From: Roger Shimizu @ 2017-01-18 12:08 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20170107150451.17912-2-rogershimizu@gmail.com>

Dear Sebastian,

On Sun, Jan 8, 2017 at 12:04 AM, Roger Shimizu <rogershimizu@gmail.com> wrote:
> Buffalo Linkstation / KuroBox and their variants need magic command
> sending to UART1 to power-off.
>
> Power driver linkstation-reset implements the magic command and I/O
> routine, which come from files listed below:
>   - arch/arm/mach-orion5x/kurobox_pro-setup.c
>   - arch/arm/mach-orion5x/terastation_pro2-setup.c

I think there's not much concern regarding to this series.
Could you kindly help to apply this patch?
Thank you!

Cheers,
-- 
Roger Shimizu, GMT +9 Tokyo
PGP/GPG: 4096R/6C6ACD6417B3ACB1

^ permalink raw reply

* [PATCH 1/3] arm64: dts: juno: Add dma-ranges property
From: Robin Murphy @ 2017-01-18 12:12 UTC (permalink / raw)
  To: linux-arm-kernel

The interconnects around Juno have a 40-bit address width, and DMA
masters have no restrictions beyond their own individual limitations.
Describe this to ensure that DT-based DMA masks get set up correctly
for all devices capable of 40-bit addressing.

Signed-off-by: Robin Murphy <robin.murphy@arm.com>
---

These apply on top of Sudeep's for-next/updates/juno branch, which
supercedes the .dtsi cleanup I had locally to make this one work.

Robin.

 arch/arm64/boot/dts/arm/juno-base.dtsi | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/boot/dts/arm/juno-base.dtsi b/arch/arm64/boot/dts/arm/juno-base.dtsi
index 44db27776b9d..5e7640d6ec69 100644
--- a/arch/arm64/boot/dts/arm/juno-base.dtsi
+++ b/arch/arm64/boot/dts/arm/juno-base.dtsi
@@ -4,6 +4,7 @@
 	/*
 	 *  Devices shared by all Juno boards
 	 */
+	dma-ranges = <0 0 0 0 0x100 0>;
 
 	memtimer: timer at 2a810000 {
 		compatible = "arm,armv7-timer-mem";
-- 
2.11.0.dirty

^ permalink raw reply related

* [PATCH 2/3] arm64: dts: juno: Add ETR SMMU power domain
From: Robin Murphy @ 2017-01-18 12:12 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <74595d6d866518db7cfabc39b4cf9b54d3be9bde.1484741104.git.robin.murphy@arm.com>

It is not at all clear from the documentation, but straightforward to
determine in practice, that the ETR SMMU is actually in the DEBUGSYS
power domain. Add that to the DT so that anyone brave enough to enable
said SMMU doesn't experience a system lockup on boot, especially a
sneaky one which goes away as soon as you connect an external debugger
to have a look at where it's stuck (thus powering up DEBUGSYS by other
means and allowing it to make progress again before actually halting...)

Signed-off-by: Robin Murphy <robin.murphy@arm.com>
---
 arch/arm64/boot/dts/arm/juno-base.dtsi | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/boot/dts/arm/juno-base.dtsi b/arch/arm64/boot/dts/arm/juno-base.dtsi
index 5e7640d6ec69..37225dfdc995 100644
--- a/arch/arm64/boot/dts/arm/juno-base.dtsi
+++ b/arch/arm64/boot/dts/arm/juno-base.dtsi
@@ -52,6 +52,7 @@
 		#iommu-cells = <1>;
 		#global-interrupts = <1>;
 		dma-coherent;
+		power-domains = <&scpi_devpd 0>;
 		status = "disabled";
 	};
 
-- 
2.11.0.dirty

^ permalink raw reply related

* [PATCH 3/3] arm64: dts: juno: Remove Motherboard USB node
From: Robin Murphy @ 2017-01-18 12:12 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <74595d6d866518db7cfabc39b4cf9b54d3be9bde.1484741104.git.robin.murphy@arm.com>

The first batch of Juno boards included a discrete USB controller chip
as a contingency in case of issues with the USB 2.0 IP integrated into
the SoC. As it turned out, the latter was fine, and to the best of my
knowledge the motherboard USB was never even brought up and validated.

Since this also isn't present on later boards, and uses a compatible
string undocumented and unmatched by any driver in the kernel, let's
just tidy it away for ever to avoid any confusion.

Signed-off-by: Robin Murphy <robin.murphy@arm.com>
---
 arch/arm64/boot/dts/arm/juno-motherboard.dtsi | 7 -------
 1 file changed, 7 deletions(-)

diff --git a/arch/arm64/boot/dts/arm/juno-motherboard.dtsi b/arch/arm64/boot/dts/arm/juno-motherboard.dtsi
index 3ad4c3000611..098601657f82 100644
--- a/arch/arm64/boot/dts/arm/juno-motherboard.dtsi
+++ b/arch/arm64/boot/dts/arm/juno-motherboard.dtsi
@@ -131,13 +131,6 @@
 				vddvario-supply = <&mb_fixed_3v3>;
 			};
 
-			usb at 5,00000000 {
-				compatible = "nxp,usb-isp1763";
-				reg = <5 0x00000000 0x20000>;
-				bus-width = <16>;
-				interrupts = <4>;
-			};
-
 			iofpga at 3,00000000 {
 				compatible = "simple-bus";
 				#address-cells = <1>;
-- 
2.11.0.dirty

^ permalink raw reply related

* [PATCH v2 0/3] Support for USB DRD Phy driver for NS2
From: Raviteja Garimella @ 2017-01-18 12:20 UTC (permalink / raw)
  To: linux-arm-kernel

Changes from v1:
===============
1. Initialize file operatiosn .owner field with THIS_MODULE
2. Remove unnecessary gpio example in DT bindings documentation.
   This is previously acked by Rob Herring <robh@kernel.org>.

Introduction:

This patch adds support for USB Dual Role Device Phy for Broadcom
Northstar2 SoC. Apart from the new phy driver, this patchset contains
changes to Kconfig, Makefile, and Device tree files.

This patchset is tested on Broadcom NS2 BCM958712K reference board.

Repo: https://github.com/Broadcom/arm64-linux.git
Branch: ns2_drdphy_v2

Raviteja Garimella (3):
  Add DT bindings documentation for NS2 USB DRD phy
  Broadcom USB DRD Phy driver for Northstar2
  DT nodes for Broadcom Northstar2 USB DRD Phy

 .../devicetree/bindings/phy/brcm,ns2-drd-phy.txt   |  30 ++
 arch/arm64/boot/dts/broadcom/ns2.dtsi              |  14 +
 drivers/phy/Kconfig                                |  13 +
 drivers/phy/Makefile                               |   1 +
 drivers/phy/phy-bcm-ns2-usbdrd.c                   | 588 +++++++++++++++++++++
 5 files changed, 646 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/phy/brcm,ns2-drd-phy.txt
 create mode 100644 drivers/phy/phy-bcm-ns2-usbdrd.c

-- 
2.1.0

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox