Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v3 5/6] arch: simplify several early memory allocations
From: Mike Rapoport @ 2018-12-09 15:00 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Michal Hocko, linux-sh, Benjamin Herrenschmidt, linux-mm,
	Rich Felker, Paul Mackerras, sparclinux, Vincent Chen, Jonas Bonn,
	linux-c6x-dev, Yoshinori Sato, Michael Ellerman, Russell King,
	Mike Rapoport, Mark Salter, Arnd Bergmann, Stefan Kristiansson,
	openrisc, Greentime Hu, Stafford Horne, Guan Xuetao,
	linux-arm-kernel, Michal Simek, linux-kernel, linuxppc-dev,
	David S. Miller
In-Reply-To: <1544367624-15376-1-git-send-email-rppt@linux.ibm.com>

There are several early memory allocations in arch/ code that use
memblock_phys_alloc() to allocate memory, convert the returned physical
address to the virtual address and then set the allocated memory to zero.

Exactly the same behaviour can be achieved simply by calling
memblock_alloc(): it allocates the memory in the same way as
memblock_phys_alloc(), then it performs the phys_to_virt() conversion and
clears the allocated memory.

Replace the longer sequence with a simpler call to memblock_alloc().

Signed-off-by: Mike Rapoport <rppt@linux.ibm.com>
---
 arch/arm/mm/mmu.c                     |  4 +---
 arch/c6x/mm/dma-coherent.c            |  9 ++-------
 arch/nds32/mm/init.c                  | 12 ++++--------
 arch/powerpc/kernel/setup-common.c    |  4 ++--
 arch/powerpc/mm/pgtable_32.c          |  4 +---
 arch/powerpc/mm/ppc_mmu_32.c          |  3 +--
 arch/powerpc/platforms/powernv/opal.c |  3 +--
 arch/sparc/kernel/prom_64.c           |  7 ++-----
 arch/sparc/mm/init_64.c               |  9 +++------
 arch/unicore32/mm/mmu.c               |  4 +---
 10 files changed, 18 insertions(+), 41 deletions(-)

diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
index f5cc1cc..0a04c9a5 100644
--- a/arch/arm/mm/mmu.c
+++ b/arch/arm/mm/mmu.c
@@ -721,9 +721,7 @@ EXPORT_SYMBOL(phys_mem_access_prot);
 
 static void __init *early_alloc_aligned(unsigned long sz, unsigned long align)
 {
-	void *ptr = __va(memblock_phys_alloc(sz, align));
-	memset(ptr, 0, sz);
-	return ptr;
+	return memblock_alloc(sz, align);
 }
 
 static void __init *early_alloc(unsigned long sz)
diff --git a/arch/c6x/mm/dma-coherent.c b/arch/c6x/mm/dma-coherent.c
index 01305c7..ffc49e2 100644
--- a/arch/c6x/mm/dma-coherent.c
+++ b/arch/c6x/mm/dma-coherent.c
@@ -118,8 +118,6 @@ void arch_dma_free(struct device *dev, size_t size, void *vaddr,
  */
 void __init coherent_mem_init(phys_addr_t start, u32 size)
 {
-	phys_addr_t bitmap_phys;
-
 	if (!size)
 		return;
 
@@ -135,11 +133,8 @@ void __init coherent_mem_init(phys_addr_t start, u32 size)
 	if (dma_size & (PAGE_SIZE - 1))
 		++dma_pages;
 
-	bitmap_phys = memblock_phys_alloc(BITS_TO_LONGS(dma_pages) * sizeof(long),
-					  sizeof(long));
-
-	dma_bitmap = phys_to_virt(bitmap_phys);
-	memset(dma_bitmap, 0, dma_pages * PAGE_SIZE);
+	dma_bitmap = memblock_alloc(BITS_TO_LONGS(dma_pages) * sizeof(long),
+				    sizeof(long));
 }
 
 static void c6x_dma_sync(struct device *dev, phys_addr_t paddr, size_t size,
diff --git a/arch/nds32/mm/init.c b/arch/nds32/mm/init.c
index 131104b..9f19be8 100644
--- a/arch/nds32/mm/init.c
+++ b/arch/nds32/mm/init.c
@@ -80,8 +80,7 @@ static void __init map_ram(void)
 		}
 
 		/* Alloc one page for holding PTE's... */
-		pte = (pte_t *) __va(memblock_phys_alloc(PAGE_SIZE, PAGE_SIZE));
-		memset(pte, 0, PAGE_SIZE);
+		pte = memblock_alloc(PAGE_SIZE, PAGE_SIZE);
 		set_pmd(pme, __pmd(__pa(pte) + _PAGE_KERNEL_TABLE));
 
 		/* Fill the newly allocated page with PTE'S */
@@ -113,8 +112,7 @@ static void __init fixedrange_init(void)
 	pgd = swapper_pg_dir + pgd_index(vaddr);
 	pud = pud_offset(pgd, vaddr);
 	pmd = pmd_offset(pud, vaddr);
-	fixmap_pmd_p = (pmd_t *) __va(memblock_phys_alloc(PAGE_SIZE, PAGE_SIZE));
-	memset(fixmap_pmd_p, 0, PAGE_SIZE);
+	fixmap_pmd_p = memblock_alloc(PAGE_SIZE, PAGE_SIZE);
 	set_pmd(pmd, __pmd(__pa(fixmap_pmd_p) + _PAGE_KERNEL_TABLE));
 
 #ifdef CONFIG_HIGHMEM
@@ -126,8 +124,7 @@ static void __init fixedrange_init(void)
 	pgd = swapper_pg_dir + pgd_index(vaddr);
 	pud = pud_offset(pgd, vaddr);
 	pmd = pmd_offset(pud, vaddr);
-	pte = (pte_t *) __va(memblock_phys_alloc(PAGE_SIZE, PAGE_SIZE));
-	memset(pte, 0, PAGE_SIZE);
+	pte = memblock_alloc(PAGE_SIZE, PAGE_SIZE);
 	set_pmd(pmd, __pmd(__pa(pte) + _PAGE_KERNEL_TABLE));
 	pkmap_page_table = pte;
 #endif /* CONFIG_HIGHMEM */
@@ -152,8 +149,7 @@ void __init paging_init(void)
 	fixedrange_init();
 
 	/* allocate space for empty_zero_page */
-	zero_page = __va(memblock_phys_alloc(PAGE_SIZE, PAGE_SIZE));
-	memset(zero_page, 0, PAGE_SIZE);
+	zero_page = memblock_alloc(PAGE_SIZE, PAGE_SIZE);
 	zone_sizes_init();
 
 	empty_zero_page = virt_to_page(zero_page);
diff --git a/arch/powerpc/kernel/setup-common.c b/arch/powerpc/kernel/setup-common.c
index 93ee370..8f6c763 100644
--- a/arch/powerpc/kernel/setup-common.c
+++ b/arch/powerpc/kernel/setup-common.c
@@ -459,8 +459,8 @@ void __init smp_setup_cpu_maps(void)
 
 	DBG("smp_setup_cpu_maps()\n");
 
-	cpu_to_phys_id = __va(memblock_phys_alloc(nr_cpu_ids * sizeof(u32), __alignof__(u32)));
-	memset(cpu_to_phys_id, 0, nr_cpu_ids * sizeof(u32));
+	cpu_to_phys_id = memblock_alloc(nr_cpu_ids * sizeof(u32),
+					__alignof__(u32));
 
 	for_each_node_by_type(dn, "cpu") {
 		const __be32 *intserv;
diff --git a/arch/powerpc/mm/pgtable_32.c b/arch/powerpc/mm/pgtable_32.c
index bda3c6f..9931e68 100644
--- a/arch/powerpc/mm/pgtable_32.c
+++ b/arch/powerpc/mm/pgtable_32.c
@@ -50,9 +50,7 @@ __ref pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address)
 	if (slab_is_available()) {
 		pte = (pte_t *)__get_free_page(GFP_KERNEL|__GFP_ZERO);
 	} else {
-		pte = __va(memblock_phys_alloc(PAGE_SIZE, PAGE_SIZE));
-		if (pte)
-			clear_page(pte);
+		pte = memblock_alloc(PAGE_SIZE, PAGE_SIZE);
 	}
 	return pte;
 }
diff --git a/arch/powerpc/mm/ppc_mmu_32.c b/arch/powerpc/mm/ppc_mmu_32.c
index f6f575b..fddf823 100644
--- a/arch/powerpc/mm/ppc_mmu_32.c
+++ b/arch/powerpc/mm/ppc_mmu_32.c
@@ -224,8 +224,7 @@ void __init MMU_init_hw(void)
 	 * Find some memory for the hash table.
 	 */
 	if ( ppc_md.progress ) ppc_md.progress("hash:find piece", 0x322);
-	Hash = __va(memblock_phys_alloc(Hash_size, Hash_size));
-	memset(Hash, 0, Hash_size);
+	Hash = memblock_alloc(Hash_size, Hash_size);
 	_SDR1 = __pa(Hash) | SDR1_LOW_BITS;
 
 	Hash_end = (struct hash_pte *) ((unsigned long)Hash + Hash_size);
diff --git a/arch/powerpc/platforms/powernv/opal.c b/arch/powerpc/platforms/powernv/opal.c
index beed86f..29ee2ea 100644
--- a/arch/powerpc/platforms/powernv/opal.c
+++ b/arch/powerpc/platforms/powernv/opal.c
@@ -171,8 +171,7 @@ int __init early_init_dt_scan_recoverable_ranges(unsigned long node,
 	/*
 	 * Allocate a buffer to hold the MC recoverable ranges.
 	 */
-	mc_recoverable_range =__va(memblock_phys_alloc(size, __alignof__(u64)));
-	memset(mc_recoverable_range, 0, size);
+	mc_recoverable_range = memblock_alloc(size, __alignof__(u64));
 
 	for (i = 0; i < mc_recoverable_range_len; i++) {
 		mc_recoverable_range[i].start_addr =
diff --git a/arch/sparc/kernel/prom_64.c b/arch/sparc/kernel/prom_64.c
index c37955d..2a17665 100644
--- a/arch/sparc/kernel/prom_64.c
+++ b/arch/sparc/kernel/prom_64.c
@@ -34,16 +34,13 @@
 
 void * __init prom_early_alloc(unsigned long size)
 {
-	unsigned long paddr = memblock_phys_alloc(size, SMP_CACHE_BYTES);
-	void *ret;
+	void *ret = memblock_alloc(size, SMP_CACHE_BYTES);
 
-	if (!paddr) {
+	if (!ret) {
 		prom_printf("prom_early_alloc(%lu) failed\n", size);
 		prom_halt();
 	}
 
-	ret = __va(paddr);
-	memset(ret, 0, size);
 	prom_early_allocated += size;
 
 	return ret;
diff --git a/arch/sparc/mm/init_64.c b/arch/sparc/mm/init_64.c
index 3c8aac2..52884f4 100644
--- a/arch/sparc/mm/init_64.c
+++ b/arch/sparc/mm/init_64.c
@@ -1089,16 +1089,13 @@ static void __init allocate_node_data(int nid)
 	struct pglist_data *p;
 	unsigned long start_pfn, end_pfn;
 #ifdef CONFIG_NEED_MULTIPLE_NODES
-	unsigned long paddr;
 
-	paddr = memblock_phys_alloc_try_nid(sizeof(struct pglist_data),
-					    SMP_CACHE_BYTES, nid);
-	if (!paddr) {
+	NODE_DATA(nid) = memblock_alloc_node(sizeof(struct pglist_data),
+					     SMP_CACHE_BYTES, nid);
+	if (!NODE_DATA(nid)) {
 		prom_printf("Cannot allocate pglist_data for nid[%d]\n", nid);
 		prom_halt();
 	}
-	NODE_DATA(nid) = __va(paddr);
-	memset(NODE_DATA(nid), 0, sizeof(struct pglist_data));
 
 	NODE_DATA(nid)->node_id = nid;
 #endif
diff --git a/arch/unicore32/mm/mmu.c b/arch/unicore32/mm/mmu.c
index 040a8c2..50d8c1a 100644
--- a/arch/unicore32/mm/mmu.c
+++ b/arch/unicore32/mm/mmu.c
@@ -143,9 +143,7 @@ static void __init build_mem_type_table(void)
 
 static void __init *early_alloc(unsigned long sz)
 {
-	void *ptr = __va(memblock_phys_alloc(sz, sz));
-	memset(ptr, 0, sz);
-	return ptr;
+	return memblock_alloc(sz, sz);
 }
 
 static pte_t * __init early_pte_alloc(pmd_t *pmd, unsigned long addr,
-- 
2.7.4


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

^ permalink raw reply related

* [PATCH v3 4/6] openrisc: simplify pte_alloc_one_kernel()
From: Mike Rapoport @ 2018-12-09 15:00 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Michal Hocko, linux-sh, Benjamin Herrenschmidt, linux-mm,
	Rich Felker, Paul Mackerras, sparclinux, Vincent Chen, Jonas Bonn,
	linux-c6x-dev, Yoshinori Sato, Michael Ellerman, Russell King,
	Mike Rapoport, Mark Salter, Arnd Bergmann, Stefan Kristiansson,
	openrisc, Greentime Hu, Stafford Horne, Guan Xuetao,
	linux-arm-kernel, Michal Simek, linux-kernel, linuxppc-dev,
	David S. Miller
In-Reply-To: <1544367624-15376-1-git-send-email-rppt@linux.ibm.com>

The pte_alloc_one_kernel() function allocates a page using
__get_free_page(GFP_KERNEL) when mm initialization is complete and
memblock_phys_alloc() on the earlier stages. The physical address of the
page allocated with memblock_phys_alloc() is converted to the virtual
address and in the both cases the allocated page is cleared using
clear_page().

The code is simplified by replacing __get_free_page() with
get_zeroed_page() and by replacing memblock_phys_alloc() with
memblock_alloc().

Signed-off-by: Mike Rapoport <rppt@linux.ibm.com>
Acked-by: Stafford Horne <shorne@gmail.com>
---
 arch/openrisc/mm/ioremap.c | 11 ++++-------
 1 file changed, 4 insertions(+), 7 deletions(-)

diff --git a/arch/openrisc/mm/ioremap.c b/arch/openrisc/mm/ioremap.c
index c969752..cfef989 100644
--- a/arch/openrisc/mm/ioremap.c
+++ b/arch/openrisc/mm/ioremap.c
@@ -123,13 +123,10 @@ pte_t __ref *pte_alloc_one_kernel(struct mm_struct *mm,
 {
 	pte_t *pte;
 
-	if (likely(mem_init_done)) {
-		pte = (pte_t *) __get_free_page(GFP_KERNEL);
-	} else {
-		pte = (pte_t *) __va(memblock_phys_alloc(PAGE_SIZE, PAGE_SIZE));
-	}
+	if (likely(mem_init_done))
+		pte = (pte_t *)get_zeroed_page(GFP_KERNEL);
+	else
+		pte = memblock_alloc(PAGE_SIZE, PAGE_SIZE);
 
-	if (pte)
-		clear_page(pte);
 	return pte;
 }
-- 
2.7.4


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

^ permalink raw reply related

* [PATCH v3 0/6] memblock: simplify several early memory allocation
From: Mike Rapoport @ 2018-12-09 15:00 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Michal Hocko, linux-sh, Benjamin Herrenschmidt, linux-mm,
	Rich Felker, Paul Mackerras, sparclinux, Vincent Chen, Jonas Bonn,
	linux-c6x-dev, Yoshinori Sato, Michael Ellerman, Russell King,
	Mike Rapoport, Mark Salter, Arnd Bergmann, Stefan Kristiansson,
	openrisc, Greentime Hu, Stafford Horne, Guan Xuetao,
	linux-arm-kernel, Michal Simek, linux-kernel, linuxppc-dev,
	David S. Miller

Hi,

These patches simplify some of the early memory allocations by replacing
usage of older memblock APIs with newer and shinier ones.

Quite a few places in the arch/ code allocated memory using a memblock API
that returns a physical address of the allocated area, then converted this
physical address to a virtual one and then used memset(0) to clear the
allocated range.

More recent memblock APIs do all the three steps in one call and their
usage simplifies the code.

It's important to note that regardless of API used, the core allocation is
nearly identical for any set of memblock allocators: first it tries to find
a free memory with all the constraints specified by the caller and then
falls back to the allocation with some or all constraints disabled.

The first three patches perform the conversion of call sites that have
exact requirements for the node and the possible memory range.

The fourth patch is a bit one-off as it simplifies openrisc's
implementation of pte_alloc_one_kernel(), and not only the memblock usage.

The fifth patch takes care of simpler cases when the allocation can be
satisfied with a simple call to memblock_alloc().

The sixth patch removes one-liner wrappers for memblock_alloc on arm and
unicore32, as suggested by Christoph.

v3:
* added Tested-by from Michal Simek for microblaze changes
* updated powerpc changes as per Michael Ellerman comments:
  - use allocations that clear memory in alloc_paca_data() and alloc_stack()
  - ensure the replacement is equivalent to old API

v2:
* added Ack from Stafford Horne for openrisc changes
* entirely drop early_alloc wrappers on arm and unicore32, as per Christoph
Hellwig



Mike Rapoport (6):
  powerpc: prefer memblock APIs returning virtual address
  microblaze: prefer memblock API returning virtual address
  sh: prefer memblock APIs returning virtual address
  openrisc: simplify pte_alloc_one_kernel()
  arch: simplify several early memory allocations
  arm, unicore32: remove early_alloc*() wrappers

 arch/arm/mm/mmu.c                      | 13 +++----------
 arch/c6x/mm/dma-coherent.c             |  9 ++-------
 arch/microblaze/mm/init.c              |  5 +++--
 arch/nds32/mm/init.c                   | 12 ++++--------
 arch/openrisc/mm/ioremap.c             | 11 ++++-------
 arch/powerpc/kernel/paca.c             | 16 ++++++----------
 arch/powerpc/kernel/setup-common.c     |  4 ++--
 arch/powerpc/kernel/setup_64.c         | 24 ++++++++++--------------
 arch/powerpc/mm/hash_utils_64.c        |  6 +++---
 arch/powerpc/mm/pgtable-book3e.c       |  8 ++------
 arch/powerpc/mm/pgtable-book3s64.c     |  5 +----
 arch/powerpc/mm/pgtable-radix.c        | 25 +++++++------------------
 arch/powerpc/mm/pgtable_32.c           |  4 +---
 arch/powerpc/mm/ppc_mmu_32.c           |  3 +--
 arch/powerpc/platforms/pasemi/iommu.c  |  5 +++--
 arch/powerpc/platforms/powernv/opal.c  |  3 +--
 arch/powerpc/platforms/pseries/setup.c | 18 ++++++++++++++----
 arch/powerpc/sysdev/dart_iommu.c       |  7 +++++--
 arch/sh/mm/init.c                      | 18 +++++-------------
 arch/sh/mm/numa.c                      |  5 ++---
 arch/sparc/kernel/prom_64.c            |  7 ++-----
 arch/sparc/mm/init_64.c                |  9 +++------
 arch/unicore32/mm/mmu.c                | 14 ++++----------
 23 files changed, 88 insertions(+), 143 deletions(-)

-- 
2.7.4


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

^ permalink raw reply

* [PATCH v3 1/6] powerpc: prefer memblock APIs returning virtual address
From: Mike Rapoport @ 2018-12-09 15:00 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Michal Hocko, linux-sh, Benjamin Herrenschmidt, linux-mm,
	Rich Felker, Paul Mackerras, sparclinux, Vincent Chen, Jonas Bonn,
	linux-c6x-dev, Yoshinori Sato, Michael Ellerman, Russell King,
	Mike Rapoport, Mark Salter, Arnd Bergmann, Stefan Kristiansson,
	openrisc, Greentime Hu, Stafford Horne, Guan Xuetao,
	linux-arm-kernel, Michal Simek, linux-kernel, linuxppc-dev,
	David S. Miller
In-Reply-To: <1544367624-15376-1-git-send-email-rppt@linux.ibm.com>

There are a several places that allocate memory using memblock APIs that
return a physical address, convert the returned address to the virtual
address and frequently also memset(0) the allocated range.

Update these places to use memblock allocators already returning a virtual
address. Use memblock functions that clear the allocated memory instead of
calling memset(0) where appropriate.

The calls to memblock_alloc_base() that were not followed by memset(0) are
replaced with memblock_alloc_try_nid_raw(). Since the latter does not
panic() when the allocation fails, the appropriate panic() calls are added
to the call sites.

Signed-off-by: Mike Rapoport <rppt@linux.ibm.com>
---
 arch/powerpc/kernel/paca.c             | 16 ++++++----------
 arch/powerpc/kernel/setup_64.c         | 24 ++++++++++--------------
 arch/powerpc/mm/hash_utils_64.c        |  6 +++---
 arch/powerpc/mm/pgtable-book3e.c       |  8 ++------
 arch/powerpc/mm/pgtable-book3s64.c     |  5 +----
 arch/powerpc/mm/pgtable-radix.c        | 25 +++++++------------------
 arch/powerpc/platforms/pasemi/iommu.c  |  5 +++--
 arch/powerpc/platforms/pseries/setup.c | 18 ++++++++++++++----
 arch/powerpc/sysdev/dart_iommu.c       |  7 +++++--
 9 files changed, 51 insertions(+), 63 deletions(-)

diff --git a/arch/powerpc/kernel/paca.c b/arch/powerpc/kernel/paca.c
index 913bfca..276d36d4 100644
--- a/arch/powerpc/kernel/paca.c
+++ b/arch/powerpc/kernel/paca.c
@@ -27,7 +27,7 @@
 static void *__init alloc_paca_data(unsigned long size, unsigned long align,
 				unsigned long limit, int cpu)
 {
-	unsigned long pa;
+	void *ptr;
 	int nid;
 
 	/*
@@ -42,17 +42,15 @@ static void *__init alloc_paca_data(unsigned long size, unsigned long align,
 		nid = early_cpu_to_node(cpu);
 	}
 
-	pa = memblock_alloc_base_nid(size, align, limit, nid, MEMBLOCK_NONE);
-	if (!pa) {
-		pa = memblock_alloc_base(size, align, limit);
-		if (!pa)
-			panic("cannot allocate paca data");
-	}
+	ptr = memblock_alloc_try_nid(size, align, MEMBLOCK_LOW_LIMIT,
+				     limit, nid);
+	if (!ptr)
+		panic("cannot allocate paca data");
 
 	if (cpu == boot_cpuid)
 		memblock_set_bottom_up(false);
 
-	return __va(pa);
+	return ptr;
 }
 
 #ifdef CONFIG_PPC_PSERIES
@@ -118,7 +116,6 @@ static struct slb_shadow * __init new_slb_shadow(int cpu, unsigned long limit)
 	}
 
 	s = alloc_paca_data(sizeof(*s), L1_CACHE_BYTES, limit, cpu);
-	memset(s, 0, sizeof(*s));
 
 	s->persistent = cpu_to_be32(SLB_NUM_BOLTED);
 	s->buffer_length = cpu_to_be32(sizeof(*s));
@@ -222,7 +219,6 @@ void __init allocate_paca(int cpu)
 	paca = alloc_paca_data(sizeof(struct paca_struct), L1_CACHE_BYTES,
 				limit, cpu);
 	paca_ptrs[cpu] = paca;
-	memset(paca, 0, sizeof(struct paca_struct));
 
 	initialise_paca(paca, cpu);
 #ifdef CONFIG_PPC_PSERIES
diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c
index 236c115..3dcd779 100644
--- a/arch/powerpc/kernel/setup_64.c
+++ b/arch/powerpc/kernel/setup_64.c
@@ -634,19 +634,17 @@ __init u64 ppc64_bolted_size(void)
 
 static void *__init alloc_stack(unsigned long limit, int cpu)
 {
-	unsigned long pa;
+	void *ptr;
 
 	BUILD_BUG_ON(STACK_INT_FRAME_SIZE % 16);
 
-	pa = memblock_alloc_base_nid(THREAD_SIZE, THREAD_SIZE, limit,
-					early_cpu_to_node(cpu), MEMBLOCK_NONE);
-	if (!pa) {
-		pa = memblock_alloc_base(THREAD_SIZE, THREAD_SIZE, limit);
-		if (!pa)
-			panic("cannot allocate stacks");
-	}
+	ptr = memblock_alloc_try_nid(THREAD_SIZE, THREAD_SIZE,
+				     MEMBLOCK_LOW_LIMIT, limit,
+				     early_cpu_to_node(cpu));
+	if (!ptr)
+		panic("cannot allocate stacks");
 
-	return __va(pa);
+	return ptr;
 }
 
 void __init irqstack_early_init(void)
@@ -739,20 +737,17 @@ void __init emergency_stack_init(void)
 		struct thread_info *ti;
 
 		ti = alloc_stack(limit, i);
-		memset(ti, 0, THREAD_SIZE);
 		emerg_stack_init_thread_info(ti, i);
 		paca_ptrs[i]->emergency_sp = (void *)ti + THREAD_SIZE;
 
 #ifdef CONFIG_PPC_BOOK3S_64
 		/* emergency stack for NMI exception handling. */
 		ti = alloc_stack(limit, i);
-		memset(ti, 0, THREAD_SIZE);
 		emerg_stack_init_thread_info(ti, i);
 		paca_ptrs[i]->nmi_emergency_sp = (void *)ti + THREAD_SIZE;
 
 		/* emergency stack for machine check exception handling. */
 		ti = alloc_stack(limit, i);
-		memset(ti, 0, THREAD_SIZE);
 		emerg_stack_init_thread_info(ti, i);
 		paca_ptrs[i]->mc_emergency_sp = (void *)ti + THREAD_SIZE;
 #endif
@@ -933,8 +928,9 @@ static void __ref init_fallback_flush(void)
 	 * hardware prefetch runoff. We don't have a recipe for load patterns to
 	 * reliably avoid the prefetcher.
 	 */
-	l1d_flush_fallback_area = __va(memblock_alloc_base(l1d_size * 2, l1d_size, limit));
-	memset(l1d_flush_fallback_area, 0, l1d_size * 2);
+	l1d_flush_fallback_area = memblock_alloc_try_nid(l1d_size * 2,
+						l1d_size, MEMBLOCK_LOW_LIMIT,
+						limit, NUMA_NO_NODE);
 
 	for_each_possible_cpu(cpu) {
 		struct paca_struct *paca = paca_ptrs[cpu];
diff --git a/arch/powerpc/mm/hash_utils_64.c b/arch/powerpc/mm/hash_utils_64.c
index 0cc7fbc..bc6be44 100644
--- a/arch/powerpc/mm/hash_utils_64.c
+++ b/arch/powerpc/mm/hash_utils_64.c
@@ -908,9 +908,9 @@ static void __init htab_initialize(void)
 #ifdef CONFIG_DEBUG_PAGEALLOC
 	if (debug_pagealloc_enabled()) {
 		linear_map_hash_count = memblock_end_of_DRAM() >> PAGE_SHIFT;
-		linear_map_hash_slots = __va(memblock_alloc_base(
-				linear_map_hash_count, 1, ppc64_rma_size));
-		memset(linear_map_hash_slots, 0, linear_map_hash_count);
+		linear_map_hash_slots = memblock_alloc_try_nid(
+				linear_map_hash_count, 1, MEMBLOCK_LOW_LIMIT,
+				ppc64_rma_size,	NUMA_NO_NODE);
 	}
 #endif /* CONFIG_DEBUG_PAGEALLOC */
 
diff --git a/arch/powerpc/mm/pgtable-book3e.c b/arch/powerpc/mm/pgtable-book3e.c
index e0ccf36..53cbc7d 100644
--- a/arch/powerpc/mm/pgtable-book3e.c
+++ b/arch/powerpc/mm/pgtable-book3e.c
@@ -57,12 +57,8 @@ void vmemmap_remove_mapping(unsigned long start,
 
 static __ref void *early_alloc_pgtable(unsigned long size)
 {
-	void *pt;
-
-	pt = __va(memblock_alloc_base(size, size, __pa(MAX_DMA_ADDRESS)));
-	memset(pt, 0, size);
-
-	return pt;
+	return memblock_alloc_try_nid(size, size, MEMBLOCK_LOW_LIMIT,
+				      __pa(MAX_DMA_ADDRESS), NUMA_NO_NODE);
 }
 
 /*
diff --git a/arch/powerpc/mm/pgtable-book3s64.c b/arch/powerpc/mm/pgtable-book3s64.c
index 9f93c9f..70d5478 100644
--- a/arch/powerpc/mm/pgtable-book3s64.c
+++ b/arch/powerpc/mm/pgtable-book3s64.c
@@ -195,11 +195,8 @@ void __init mmu_partition_table_init(void)
 	unsigned long ptcr;
 
 	BUILD_BUG_ON_MSG((PATB_SIZE_SHIFT > 36), "Partition table size too large.");
-	partition_tb = __va(memblock_alloc_base(patb_size, patb_size,
-						MEMBLOCK_ALLOC_ANYWHERE));
-
 	/* Initialize the Partition Table with no entries */
-	memset((void *)partition_tb, 0, patb_size);
+	partition_tb = memblock_alloc(patb_size, patb_size);
 
 	/*
 	 * update partition table control register,
diff --git a/arch/powerpc/mm/pgtable-radix.c b/arch/powerpc/mm/pgtable-radix.c
index 9311560..29bcea5 100644
--- a/arch/powerpc/mm/pgtable-radix.c
+++ b/arch/powerpc/mm/pgtable-radix.c
@@ -51,26 +51,15 @@ static int native_register_process_table(unsigned long base, unsigned long pg_sz
 static __ref void *early_alloc_pgtable(unsigned long size, int nid,
 			unsigned long region_start, unsigned long region_end)
 {
-	unsigned long pa = 0;
-	void *pt;
+	phys_addr_t min_addr = MEMBLOCK_LOW_LIMIT;
+	phys_addr_t max_addr = MEMBLOCK_ALLOC_ANYWHERE;
 
-	if (region_start || region_end) /* has region hint */
-		pa = memblock_alloc_range(size, size, region_start, region_end,
-						MEMBLOCK_NONE);
-	else if (nid != -1) /* has node hint */
-		pa = memblock_alloc_base_nid(size, size,
-						MEMBLOCK_ALLOC_ANYWHERE,
-						nid, MEMBLOCK_NONE);
+	if (region_start)
+		min_addr = region_start;
+	if (region_end)
+		max_addr = region_end;
 
-	if (!pa)
-		pa = memblock_alloc_base(size, size, MEMBLOCK_ALLOC_ANYWHERE);
-
-	BUG_ON(!pa);
-
-	pt = __va(pa);
-	memset(pt, 0, size);
-
-	return pt;
+	return memblock_alloc_try_nid(size, size, min_addr, max_addr, nid);
 }
 
 static int early_map_kernel_page(unsigned long ea, unsigned long pa,
diff --git a/arch/powerpc/platforms/pasemi/iommu.c b/arch/powerpc/platforms/pasemi/iommu.c
index f297152..f62930f 100644
--- a/arch/powerpc/platforms/pasemi/iommu.c
+++ b/arch/powerpc/platforms/pasemi/iommu.c
@@ -208,7 +208,9 @@ static int __init iob_init(struct device_node *dn)
 	pr_debug(" -> %s\n", __func__);
 
 	/* For 2G space, 8x64 pages (2^21 bytes) is max total l2 size */
-	iob_l2_base = (u32 *)__va(memblock_alloc_base(1UL<<21, 1UL<<21, 0x80000000));
+	iob_l2_base = memblock_alloc_try_nid_raw(1UL << 21, 1UL << 21,
+					MEMBLOCK_LOW_LIMIT, 0x80000000,
+					NUMA_NO_NODE);
 
 	pr_info("IOBMAP L2 allocated at: %p\n", iob_l2_base);
 
@@ -269,4 +271,3 @@ void __init iommu_init_early_pasemi(void)
 	pasemi_pci_controller_ops.dma_bus_setup = pci_dma_bus_setup_pasemi;
 	set_pci_dma_ops(&dma_iommu_ops);
 }
-
diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c
index 0f553dc..1382360 100644
--- a/arch/powerpc/platforms/pseries/setup.c
+++ b/arch/powerpc/platforms/pseries/setup.c
@@ -130,8 +130,13 @@ static void __init fwnmi_init(void)
 	 * It will be used in real mode mce handler, hence it needs to be
 	 * below RMA.
 	 */
-	mce_data_buf = __va(memblock_alloc_base(RTAS_ERROR_LOG_MAX * nr_cpus,
-					RTAS_ERROR_LOG_MAX, ppc64_rma_size));
+	mce_data_buf = memblock_alloc_try_nid_raw(RTAS_ERROR_LOG_MAX * nr_cpus,
+					RTAS_ERROR_LOG_MAX, MEMBLOCK_LOW_LIMIT,
+					ppc64_rma_size, NUMA_NO_NODE);
+	if (!mce_data_buf)
+		panic("Failed to allocate %d bytes below %pa for MCE buffer\n",
+		      RTAS_ERROR_LOG_MAX * nr_cpus, &ppc64_rma_size);
+
 	for_each_possible_cpu(i) {
 		paca_ptrs[i]->mce_data_buf = mce_data_buf +
 						(RTAS_ERROR_LOG_MAX * i);
@@ -140,8 +145,13 @@ static void __init fwnmi_init(void)
 #ifdef CONFIG_PPC_BOOK3S_64
 	/* Allocate per cpu slb area to save old slb contents during MCE */
 	size = sizeof(struct slb_entry) * mmu_slb_size * nr_cpus;
-	slb_ptr = __va(memblock_alloc_base(size, sizeof(struct slb_entry),
-					   ppc64_rma_size));
+	slb_ptr = memblock_alloc_try_nid_raw(size, sizeof(struct slb_entry),
+					MEMBLOCK_LOW_LIMIT, ppc64_rma_size,
+					NUMA_NO_NODE);
+	if (!slb_ptr)
+		panic("Failed to allocate %zu bytes below %pa for slb area\n",
+		      size, &ppc64_rma_size);
+
 	for_each_possible_cpu(i)
 		paca_ptrs[i]->mce_faulty_slbs = slb_ptr + (mmu_slb_size * i);
 #endif
diff --git a/arch/powerpc/sysdev/dart_iommu.c b/arch/powerpc/sysdev/dart_iommu.c
index a5b40d1..25bc25f 100644
--- a/arch/powerpc/sysdev/dart_iommu.c
+++ b/arch/powerpc/sysdev/dart_iommu.c
@@ -251,8 +251,11 @@ static void allocate_dart(void)
 	 * 16MB (1 << 24) alignment. We allocate a full 16Mb chuck since we
 	 * will blow up an entire large page anyway in the kernel mapping.
 	 */
-	dart_tablebase = __va(memblock_alloc_base(1UL<<24,
-						  1UL<<24, 0x80000000L));
+	dart_tablebase = memblock_alloc_try_nid_raw(SZ_16M, SZ_16M,
+					MEMBLOCK_LOW_LIMIT, SZ_2G,
+					NUMA_NO_NODE);
+	if (!dart_tablebase)
+		panic("Failed to allocate 16MB below 2GB for DART table\n");
 
 	/* There is no point scanning the DART space for leaks*/
 	kmemleak_no_scan((void *)dart_tablebase);
-- 
2.7.4


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

^ permalink raw reply related

* [PATCH v3 2/6] microblaze: prefer memblock API returning virtual address
From: Mike Rapoport @ 2018-12-09 15:00 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Michal Hocko, linux-sh, Benjamin Herrenschmidt, linux-mm,
	Rich Felker, Paul Mackerras, sparclinux, Vincent Chen, Jonas Bonn,
	linux-c6x-dev, Yoshinori Sato, Michael Ellerman, Russell King,
	Mike Rapoport, Mark Salter, Arnd Bergmann, Stefan Kristiansson,
	openrisc, Greentime Hu, Stafford Horne, Guan Xuetao,
	linux-arm-kernel, Michal Simek, linux-kernel, linuxppc-dev,
	David S. Miller
In-Reply-To: <1544367624-15376-1-git-send-email-rppt@linux.ibm.com>

Rather than use the memblock_alloc_base that returns a physical address and
then convert this address to the virtual one, use appropriate memblock
function that returns a virtual address.

Signed-off-by: Mike Rapoport <rppt@linux.ibm.com>
Tested-by: Michal Simek <michal.simek@xilinx.com>
---
 arch/microblaze/mm/init.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/arch/microblaze/mm/init.c b/arch/microblaze/mm/init.c
index b17fd8a..44f4b89 100644
--- a/arch/microblaze/mm/init.c
+++ b/arch/microblaze/mm/init.c
@@ -363,8 +363,9 @@ void __init *early_get_page(void)
 	 * Mem start + kernel_tlb -> here is limit
 	 * because of mem mapping from head.S
 	 */
-	return __va(memblock_alloc_base(PAGE_SIZE, PAGE_SIZE,
-				memory_start + kernel_tlb));
+	return memblock_alloc_try_nid_raw(PAGE_SIZE, PAGE_SIZE,
+				MEMBLOCK_LOW_LIMIT, memory_start + kernel_tlb,
+				NUMA_NO_NODE);
 }
 
 #endif /* CONFIG_MMU */
-- 
2.7.4


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

^ permalink raw reply related

* Re: [PATCH v6 07/13] arm64: add basic pointer authentication support
From: Richard Henderson @ 2018-12-09 14:59 UTC (permalink / raw)
  To: Kristina Martsenko, linux-arm-kernel
  Cc: Mark Rutland, Andrew Jones, Jacob Bramley, Ard Biesheuvel,
	Marc Zyngier, Catalin Marinas, Adam Wallis, Suzuki K Poulose,
	Will Deacon, Christoffer Dall, kvmarm, Cyrill Gorcunov,
	Ramana Radhakrishnan, Amit Kachhap, Dave P Martin, linux-kernel,
	Kees Cook
In-Reply-To: <20181207183931.4285-8-kristina.martsenko@arm.com>

On 12/7/18 12:39 PM, Kristina Martsenko wrote:
> From: Mark Rutland <mark.rutland@arm.com>
> 
> This patch adds basic support for pointer authentication, allowing
> userspace to make use of APIAKey, APIBKey, APDAKey, APDBKey, and
> APGAKey. The kernel maintains key values for each process (shared by all
> threads within), which are initialised to random values at exec() time.
> 
> The ID_AA64ISAR1_EL1.{APA,API,GPA,GPI} fields are exposed to userspace,
> to describe that pointer authentication instructions are available and
> that the kernel is managing the keys. Two new hwcaps are added for the
> same reason: PACA (for address authentication) and PACG (for generic
> authentication).
> 
> Signed-off-by: Mark Rutland <mark.rutland@arm.com>
> Signed-off-by: Kristina Martsenko <kristina.martsenko@arm.com>
> Tested-by: Adam Wallis <awallis@codeaurora.org>
> Cc: Catalin Marinas <catalin.marinas@arm.com>
> Cc: Ramana Radhakrishnan <ramana.radhakrishnan@arm.com>
> Cc: Suzuki K Poulose <suzuki.poulose@arm.com>
> Cc: Will Deacon <will.deacon@arm.com>
> ---
>  arch/arm64/include/asm/pointer_auth.h | 75 +++++++++++++++++++++++++++++++++++
>  arch/arm64/include/asm/thread_info.h  |  4 ++
>  arch/arm64/include/uapi/asm/hwcap.h   |  2 +
>  arch/arm64/kernel/cpufeature.c        | 13 ++++++
>  arch/arm64/kernel/cpuinfo.c           |  2 +
>  arch/arm64/kernel/process.c           |  4 ++
>  6 files changed, 100 insertions(+)
>  create mode 100644 arch/arm64/include/asm/pointer_auth.h

Reviewed-by: Richard Henderson <richard.henderson@linaro.org>


r~


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

^ permalink raw reply

* Re: [PATCH v6 06/13] arm64/cpufeature: detect pointer authentication
From: Richard Henderson @ 2018-12-09 14:58 UTC (permalink / raw)
  To: Kristina Martsenko, linux-arm-kernel
  Cc: Mark Rutland, Andrew Jones, Jacob Bramley, Ard Biesheuvel,
	Marc Zyngier, Catalin Marinas, Adam Wallis, Suzuki K Poulose,
	Will Deacon, Christoffer Dall, kvmarm, Cyrill Gorcunov,
	Ramana Radhakrishnan, Amit Kachhap, Dave P Martin, linux-kernel,
	Kees Cook
In-Reply-To: <20181207183931.4285-7-kristina.martsenko@arm.com>

On 12/7/18 12:39 PM, Kristina Martsenko wrote:
> From: Mark Rutland <mark.rutland@arm.com>
> 
> So that we can dynamically handle the presence of pointer authentication
> functionality, wire up probing code in cpufeature.c.
> 
> From ARMv8.3 onwards, ID_AA64ISAR1 is no longer entirely RES0, and now
> has four fields describing the presence of pointer authentication
> functionality:
> 
> * APA - address authentication present, using an architected algorithm
> * API - address authentication present, using an IMP DEF algorithm
> * GPA - generic authentication present, using an architected algorithm
> * GPI - generic authentication present, using an IMP DEF algorithm
> 
> This patch checks for both address and generic authentication,
> separately. It is assumed that if all CPUs support an IMP DEF algorithm,
> the same algorithm is used across all CPUs.
> 
> Signed-off-by: Mark Rutland <mark.rutland@arm.com>
> Signed-off-by: Kristina Martsenko <kristina.martsenko@arm.com>
> Cc: Catalin Marinas <catalin.marinas@arm.com>
> Cc: Suzuki K Poulose <suzuki.poulose@arm.com>
> Cc: Will Deacon <will.deacon@arm.com>
> ---
>  arch/arm64/include/asm/cpucaps.h    |  8 +++-
>  arch/arm64/include/asm/cpufeature.h | 12 +++++
>  arch/arm64/kernel/cpufeature.c      | 90 +++++++++++++++++++++++++++++++++++++
>  3 files changed, 109 insertions(+), 1 deletion(-)

Reviewed-by: Richard Henderson <richard.henderson@linaro.org>


r~


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

^ permalink raw reply

* Re: [PATCH v6 05/13] arm64: Don't trap host pointer auth use to EL2
From: Richard Henderson @ 2018-12-09 14:54 UTC (permalink / raw)
  To: Kristina Martsenko, linux-arm-kernel
  Cc: Mark Rutland, Andrew Jones, Jacob Bramley, Ard Biesheuvel,
	Marc Zyngier, Catalin Marinas, Adam Wallis, Suzuki K Poulose,
	Will Deacon, Christoffer Dall, kvmarm, Cyrill Gorcunov,
	Ramana Radhakrishnan, Amit Kachhap, Dave P Martin, linux-kernel,
	Kees Cook
In-Reply-To: <20181207183931.4285-6-kristina.martsenko@arm.com>

On 12/7/18 12:39 PM, Kristina Martsenko wrote:
> From: Mark Rutland <mark.rutland@arm.com>
> 
> To allow EL0 (and/or EL1) to use pointer authentication functionality,
> we must ensure that pointer authentication instructions and accesses to
> pointer authentication keys are not trapped to EL2.
> 
> This patch ensures that HCR_EL2 is configured appropriately when the
> kernel is booted at EL2. For non-VHE kernels we set HCR_EL2.{API,APK},
> ensuring that EL1 can access keys and permit EL0 use of instructions.
> For VHE kernels host EL0 (TGE && E2H) is unaffected by these settings,
> and it doesn't matter how we configure HCR_EL2.{API,APK}, so we don't
> bother setting them.
> 
> This does not enable support for KVM guests, since KVM manages HCR_EL2
> itself when running VMs.
> 
> Signed-off-by: Mark Rutland <mark.rutland@arm.com>
> Signed-off-by: Kristina Martsenko <kristina.martsenko@arm.com>
> Acked-by: Christoffer Dall <christoffer.dall@arm.com>
> Cc: Catalin Marinas <catalin.marinas@arm.com>
> Cc: Marc Zyngier <marc.zyngier@arm.com>
> Cc: Will Deacon <will.deacon@arm.com>
> Cc: kvmarm@lists.cs.columbia.edu
> ---
>  arch/arm64/include/asm/kvm_arm.h | 4 +++-
>  1 file changed, 3 insertions(+), 1 deletion(-)

Reviewed-by: Richard Henderson <richard.henderson@linaro.org>


r~

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

^ permalink raw reply

* Re: [PATCH v6 04/13] arm64/kvm: hide ptrauth from guests
From: Richard Henderson @ 2018-12-09 14:53 UTC (permalink / raw)
  To: Kristina Martsenko, linux-arm-kernel
  Cc: Mark Rutland, Andrew Jones, Jacob Bramley, Ard Biesheuvel,
	Marc Zyngier, Catalin Marinas, Adam Wallis, Suzuki K Poulose,
	Will Deacon, Christoffer Dall, kvmarm, Cyrill Gorcunov,
	Ramana Radhakrishnan, Amit Kachhap, Dave P Martin, linux-kernel,
	Kees Cook
In-Reply-To: <20181207183931.4285-5-kristina.martsenko@arm.com>

On 12/7/18 12:39 PM, Kristina Martsenko wrote:
> From: Mark Rutland <mark.rutland@arm.com>
> 
> In subsequent patches we're going to expose ptrauth to the host kernel
> and userspace, but things are a bit trickier for guest kernels. For the
> time being, let's hide ptrauth from KVM guests.
> 
> Regardless of how well-behaved the guest kernel is, guest userspace
> could attempt to use ptrauth instructions, triggering a trap to EL2,
> resulting in noise from kvm_handle_unknown_ec(). So let's write up a
> handler for the PAC trap, which silently injects an UNDEF into the
> guest, as if the feature were really missing.

Reviewing the long thread that accompanied v5, I thought we were *not* going to
trap PAuth instructions from the guest.

In particular, the OS distribution may legitimately be built to include
hint-space nops.  This includes XPACLRI, which is used by the C++ exception
unwinder and not controlled by SCTLR_EL1.EnI{A,B}.

It seems like the header comment here, and

> +/*
> + * Guest usage of a ptrauth instruction (which the guest EL1 did not turn into
> + * a NOP).
> + */
> +static int kvm_handle_ptrauth(struct kvm_vcpu *vcpu, struct kvm_run *run)
> +

here, need updating.


r~

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

^ permalink raw reply

* Re: [PATCH v6 03/13] arm64/kvm: consistently handle host HCR_EL2 flags
From: Richard Henderson @ 2018-12-09 14:35 UTC (permalink / raw)
  To: Kristina Martsenko, linux-arm-kernel
  Cc: Mark Rutland, Andrew Jones, Jacob Bramley, Ard Biesheuvel,
	Marc Zyngier, Catalin Marinas, Adam Wallis, Suzuki K Poulose,
	Will Deacon, Christoffer Dall, kvmarm, Cyrill Gorcunov,
	Ramana Radhakrishnan, Amit Kachhap, Dave P Martin, linux-kernel,
	Kees Cook
In-Reply-To: <20181207183931.4285-4-kristina.martsenko@arm.com>

On 12/7/18 12:39 PM, Kristina Martsenko wrote:
> From: Mark Rutland <mark.rutland@arm.com>
> 
> In KVM we define the configuration of HCR_EL2 for a VHE HOST in
> HCR_HOST_VHE_FLAGS, but we don't have a similar definition for the
> non-VHE host flags, and open-code HCR_RW. Further, in head.S we
> open-code the flags for VHE and non-VHE configurations.
> 
> In future, we're going to want to configure more flags for the host, so
> lets add a HCR_HOST_NVHE_FLAGS defintion, and consistently use both
> HCR_HOST_VHE_FLAGS and HCR_HOST_NVHE_FLAGS in the kvm code and head.S.
> 
> We now use mov_q to generate the HCR_EL2 value, as we use when
> configuring other registers in head.S.
> 
> Signed-off-by: Mark Rutland <mark.rutland@arm.com>
> Signed-off-by: Kristina Martsenko <kristina.martsenko@arm.com>
> Reviewed-by: Christoffer Dall <christoffer.dall@arm.com>
> Cc: Catalin Marinas <catalin.marinas@arm.com>
> Cc: Marc Zyngier <marc.zyngier@arm.com>
> Cc: Will Deacon <will.deacon@arm.com>
> Cc: kvmarm@lists.cs.columbia.edu
> ---
>  arch/arm64/include/asm/kvm_arm.h | 1 +
>  arch/arm64/kernel/head.S         | 5 ++---
>  arch/arm64/kvm/hyp/switch.c      | 2 +-
>  3 files changed, 4 insertions(+), 4 deletions(-)

Reviewed-by: Richard Henderson <richard.henderson@linaro.org>


r~


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

^ permalink raw reply

* Re: [PATCH v6 01/13] arm64: add comments about EC exception levels
From: Richard Henderson @ 2018-12-09 14:34 UTC (permalink / raw)
  To: Kristina Martsenko, linux-arm-kernel
  Cc: Mark Rutland, Andrew Jones, Jacob Bramley, Ard Biesheuvel,
	Marc Zyngier, Catalin Marinas, Adam Wallis, Suzuki K Poulose,
	Will Deacon, Christoffer Dall, kvmarm, Cyrill Gorcunov,
	Ramana Radhakrishnan, Amit Kachhap, Dave P Martin, linux-kernel,
	Kees Cook
In-Reply-To: <20181207183931.4285-2-kristina.martsenko@arm.com>

On 12/7/18 12:39 PM, Kristina Martsenko wrote:
> To make it clear which exceptions can't be taken to EL1 or EL2, add
> comments next to the ESR_ELx_EC_* macro definitions.
> 
> Signed-off-by: Kristina Martsenko <kristina.martsenko@arm.com>
> ---
>  arch/arm64/include/asm/esr.h | 14 +++++++-------
>  1 file changed, 7 insertions(+), 7 deletions(-)

Reviewed-by: Richard Henderson <richard.henderson@linaro.org>


r~

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

^ permalink raw reply

* [PATCH v5 6/6] arm64: dts: imx8mq-evk: enable watchdog
From: Abel Vesa @ 2018-12-09 14:26 UTC (permalink / raw)
  To: Lucas Stach, linux-arm-kernel@lists.infradead.org, Shawn Guo,
	Rob Herring
  Cc: Aisheng Dong, devicetree@vger.kernel.org, Baruch Siach, Abel Vesa,
	Linux Kernel Mailing List, patchwork-lst@pengutronix.de,
	Abel Vesa, dl-linux-imx, Pengutronix Kernel Team, Fabio Estevam
In-Reply-To: <1544365552-30270-1-git-send-email-abel.vesa@nxp.com>

From: Baruch Siach <baruch@tkos.co.il>

The external nWDOG signal connects to the EVK board reset circuit.

Tested on the i.MX8MQ EVK rev B3.

Signed-off-by: Baruch Siach <baruch@tkos.co.il>
Signed-off-by: Lucas Stach <l.stach@pengutronix.de>
---
 arch/arm64/boot/dts/freescale/imx8mq-evk.dts | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/arch/arm64/boot/dts/freescale/imx8mq-evk.dts b/arch/arm64/boot/dts/freescale/imx8mq-evk.dts
index 04ce13f..64acccc 100644
--- a/arch/arm64/boot/dts/freescale/imx8mq-evk.dts
+++ b/arch/arm64/boot/dts/freescale/imx8mq-evk.dts
@@ -160,6 +160,13 @@
 	status = "okay";
 };
 
+&wdog1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_wdog>;
+	fsl,ext-reset-output;
+	status = "okay";
+};
+
 &iomuxc {
 	pinctrl_fec1: fec1grp {
 		fsl,pins = <
@@ -287,4 +294,10 @@
 			MX8MQ_IOMUXC_GPIO1_IO04_USDHC2_VSELECT		0xc1
 		>;
 	};
+
+	pinctrl_wdog: wdog1grp {
+		fsl,pins = <
+			MX8MQ_IOMUXC_GPIO1_IO02_WDOG1_WDOG_B		0xc6
+		>;
+	};
 };
-- 
2.7.4


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

^ permalink raw reply related

* [PATCH v5 5/6] arm64: dts: imx8mq: add watchdog devices
From: Abel Vesa @ 2018-12-09 14:26 UTC (permalink / raw)
  To: Lucas Stach, linux-arm-kernel@lists.infradead.org, Shawn Guo,
	Rob Herring
  Cc: Aisheng Dong, devicetree@vger.kernel.org, Baruch Siach, Abel Vesa,
	Linux Kernel Mailing List, patchwork-lst@pengutronix.de,
	Abel Vesa, dl-linux-imx, Pengutronix Kernel Team, Fabio Estevam
In-Reply-To: <1544365552-30270-1-git-send-email-abel.vesa@nxp.com>

From: Baruch Siach <baruch@tkos.co.il>

Signed-off-by: Baruch Siach <baruch@tkos.co.il>
Signed-off-by: Lucas Stach <l.stach@pengutronix.de>
---
 arch/arm64/boot/dts/freescale/imx8mq.dtsi | 24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)

diff --git a/arch/arm64/boot/dts/freescale/imx8mq.dtsi b/arch/arm64/boot/dts/freescale/imx8mq.dtsi
index 3703bca..8e9d6d5 100644
--- a/arch/arm64/boot/dts/freescale/imx8mq.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mq.dtsi
@@ -228,6 +228,30 @@
 				              "clk_ext1", "clk_ext2",
 				              "clk_ext3", "clk_ext4";
 			};
+
+			wdog1: watchdog@30280000 {
+				compatible = "fsl,imx8mq-wdt", "fsl,imx21-wdt";
+				reg = <0x30280000 0x10000>;
+				interrupts = <GIC_SPI 78 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&clk IMX8MQ_CLK_WDOG1_ROOT>;
+				status = "disabled";
+			};
+
+			wdog2: watchdog@30290000 {
+				compatible = "fsl,imx8mq-wdt", "fsl,imx21-wdt";
+				reg = <0x30290000 0x10000>;
+				interrupts = <GIC_SPI 79 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&clk IMX8MQ_CLK_WDOG2_ROOT>;
+				status = "disabled";
+			};
+
+			wdog3: watchdog@302a0000 {
+				compatible = "fsl,imx8mq-wdt", "fsl,imx21-wdt";
+				reg = <0x302a0000 0x10000>;
+				interrupts = <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&clk IMX8MQ_CLK_WDOG3_ROOT>;
+				status = "disabled";
+			};
 		};
 
 		bus@30400000 { /* AIPS2 */
-- 
2.7.4


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

^ permalink raw reply related

* [PATCH v5 2/6] arm64: add basic DTS for i.MX8MQ
From: Abel Vesa @ 2018-12-09 14:26 UTC (permalink / raw)
  To: Lucas Stach, linux-arm-kernel@lists.infradead.org, Shawn Guo,
	Rob Herring
  Cc: Aisheng Dong, devicetree@vger.kernel.org, Abel Vesa,
	Linux Kernel Mailing List, patchwork-lst@pengutronix.de,
	Abel Vesa, dl-linux-imx, Pengutronix Kernel Team, Fabio Estevam
In-Reply-To: <1544365552-30270-1-git-send-email-abel.vesa@nxp.com>

From: Lucas Stach <l.stach@pengutronix.de>

This adds the basic DTS for the i.MX8MQ.
For now only the following peripherals are supported:
- IOMUXC (pin controller)
- CCM (clock controller)
- GPIO
- UART
- uSDHC (SD/eMMC controller)
- FEC (ethernet controller)
- i2c

This is enough to get a very basic board support up and running.

One known limitation is that the driver for the GPC interrupt
controller is still missing, rendering the CPU sleep states unusable
as there is nothing waking them up anymore.

Signed-off-by: Lucas Stach <l.stach@pengutronix.de>
Reviewed-by: Dong Aisheng <Aisheng.dong@nxp.com>
---
 Documentation/devicetree/bindings/arm/fsl.txt  |   4 +
 arch/arm64/boot/dts/freescale/imx8mq-pinfunc.h | 623 +++++++++++++++++++++++++
 arch/arm64/boot/dts/freescale/imx8mq.dtsi      | 392 ++++++++++++++++
 3 files changed, 1019 insertions(+)
 create mode 100644 arch/arm64/boot/dts/freescale/imx8mq-pinfunc.h
 create mode 100644 arch/arm64/boot/dts/freescale/imx8mq.dtsi

diff --git a/Documentation/devicetree/bindings/arm/fsl.txt b/Documentation/devicetree/bindings/arm/fsl.txt
index 1ac461ae..9f4aba2 100644
--- a/Documentation/devicetree/bindings/arm/fsl.txt
+++ b/Documentation/devicetree/bindings/arm/fsl.txt
@@ -131,6 +131,10 @@ i.MX7ULP generic board
 Required root node properties:
     - compatible = "fsl,imx7ulp";
 
+i.MX8MQ generic board
+Required root node properties:
+    - compatible = "fsl,imx8mq";
+
 Freescale Vybrid Platform Device Tree Bindings
 ----------------------------------------------
 
diff --git a/arch/arm64/boot/dts/freescale/imx8mq-pinfunc.h b/arch/arm64/boot/dts/freescale/imx8mq-pinfunc.h
new file mode 100644
index 0000000..b94b020
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx8mq-pinfunc.h
@@ -0,0 +1,623 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ * Copyright 2017 NXP
+ */
+
+#ifndef __DTS_IMX8MQ_PINFUNC_H
+#define __DTS_IMX8MQ_PINFUNC_H
+
+/*
+ * The pin function ID is a tuple of
+ * <mux_reg conf_reg input_reg mux_mode input_val>
+ */
+
+#define MX8MQ_IOMUXC_PMIC_STBY_REQ_CCMSRCGPCMIX_PMIC_STBY_REQ               0x014 0x27C 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_PMIC_ON_REQ_SNVSMIX_PMIC_ON_REQ                        0x018 0x280 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_ONOFF_SNVSMIX_ONOFF                                    0x01C 0x284 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_POR_B_SNVSMIX_POR_B                                    0x020 0x288 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_RTC_RESET_B_SNVSMIX_RTC_RESET_B                        0x024 0x28C 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO00_GPIO1_IO0                                   0x028 0x290 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO00_CCMSRCGPCMIX_ENET_PHY_REF_CLK_ROOT          0x028 0x290 0x4C0 0x1 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO00_ANAMIX_REF_CLK_32K                          0x028 0x290 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO00_CCMSRCGPCMIX_EXT_CLK1                       0x028 0x290 0x000 0x6 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO00_SJC_FAIL                                    0x028 0x290 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO01_GPIO1_IO1                                   0x02C 0x294 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO01_PWM1_OUT                                    0x02C 0x294 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO01_ANAMIX_REF_CLK_24M                          0x02C 0x294 0x4BC 0x5 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO01_CCMSRCGPCMIX_EXT_CLK2                       0x02C 0x294 0x000 0x6 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO01_SJC_ACTIVE                                  0x02C 0x294 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO02_GPIO1_IO2                                   0x030 0x298 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO02_WDOG1_WDOG_B                                0x030 0x298 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO02_WDOG1_WDOG_ANY                              0x030 0x298 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO02_SJC_DE_B                                    0x030 0x298 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO03_GPIO1_IO3                                   0x034 0x29C 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO03_USDHC1_VSELECT                              0x034 0x29C 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO03_SDMA1_EXT_EVENT0                            0x034 0x29C 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO03_ANAMIX_XTAL_OK                              0x034 0x29C 0x000 0x6 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO03_SJC_DONE                                    0x034 0x29C 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO04_GPIO1_IO4                                   0x038 0x2A0 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO04_USDHC2_VSELECT                              0x038 0x2A0 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO04_SDMA1_EXT_EVENT1                            0x038 0x2A0 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO04_ANAMIX_XTAL_OK_LV                           0x038 0x2A0 0x000 0x6 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO04_USDHC1_TEST_TRIG                            0x038 0x2A0 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO05_GPIO1_IO5                                   0x03C 0x2A4 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO05_M4_NMI                                      0x03C 0x2A4 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO05_CCMSRCGPCMIX_PMIC_READY                     0x03C 0x2A4 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO05_CCMSRCGPCMIX_INT_BOOT                       0x03C 0x2A4 0x000 0x6 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO05_USDHC2_TEST_TRIG                            0x03C 0x2A4 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO06_GPIO1_IO6                                   0x040 0x2A8 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO06_ENET1_MDC                                   0x040 0x2A8 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO06_USDHC1_CD_B                                 0x040 0x2A8 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO06_CCMSRCGPCMIX_EXT_CLK3                       0x040 0x2A8 0x000 0x6 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO06_ECSPI1_TEST_TRIG                            0x040 0x2A8 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO07_GPIO1_IO7                                   0x044 0x2AC 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO07_ENET1_MDIO                                  0x044 0x2AC 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO07_USDHC1_WP                                   0x044 0x2AC 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO07_CCMSRCGPCMIX_EXT_CLK4                       0x044 0x2AC 0x000 0x6 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO07_ECSPI2_TEST_TRIG                            0x044 0x2AC 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO08_GPIO1_IO8                                   0x048 0x2B0 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO08_ENET1_1588_EVENT0_IN                        0x048 0x2B0 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO08_USDHC2_RESET_B                              0x048 0x2B0 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO08_CCMSRCGPCMIX_WAIT                           0x048 0x2B0 0x000 0x6 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO08_QSPI_TEST_TRIG                              0x048 0x2B0 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO09_GPIO1_IO9                                   0x04C 0x2B4 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO09_ENET1_1588_EVENT0_OUT                       0x04C 0x2B4 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO09_SDMA2_EXT_EVENT0                            0x04C 0x2B4 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO09_CCMSRCGPCMIX_STOP                           0x04C 0x2B4 0x000 0x6 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO09_RAWNAND_TEST_TRIG                           0x04C 0x2B4 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO10_GPIO1_IO10                                  0x050 0x2B8 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO10_USB1_OTG_ID                                 0x050 0x2B8 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO10_OCOTP_CTRL_WRAPPER_FUSE_LATCHED             0x050 0x2B8 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO11_GPIO1_IO11                                  0x054 0x2BC 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO11_USB2_OTG_ID                                 0x054 0x2BC 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO11_CCMSRCGPCMIX_PMIC_READY                     0x054 0x2BC 0x4BC 0x5 0x1
+#define MX8MQ_IOMUXC_GPIO1_IO11_CCMSRCGPCMIX_OUT0                           0x054 0x2BC 0x000 0x6 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO11_CAAM_WRAPPER_RNG_OSC_OBS                    0x054 0x2BC 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO12_GPIO1_IO12                                  0x058 0x2C0 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO12_USB1_OTG_PWR                                0x058 0x2C0 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO12_SDMA2_EXT_EVENT1                            0x058 0x2C0 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO12_CCMSRCGPCMIX_OUT1                           0x058 0x2C0 0x000 0x6 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO12_CSU_CSU_ALARM_AUT0                          0x058 0x2C0 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO13_GPIO1_IO13                                  0x05C 0x2C4 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO13_USB1_OTG_OC                                 0x05C 0x2C4 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO13_PWM2_OUT                                    0x05C 0x2C4 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO13_CCMSRCGPCMIX_OUT2                           0x05C 0x2C4 0x000 0x6 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO13_CSU_CSU_ALARM_AUT1                          0x05C 0x2C4 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO14_GPIO1_IO14                                  0x060 0x2C8 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO14_USB2_OTG_PWR                                0x060 0x2C8 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO14_PWM3_OUT                                    0x060 0x2C8 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO14_CCMSRCGPCMIX_CLKO1                          0x060 0x2C8 0x000 0x6 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO14_CSU_CSU_ALARM_AUT2                          0x060 0x2C8 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO15_GPIO1_IO15                                  0x064 0x2CC 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO15_USB2_OTG_OC                                 0x064 0x2CC 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO15_PWM4_OUT                                    0x064 0x2CC 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO15_CCMSRCGPCMIX_CLKO2                          0x064 0x2CC 0x000 0x6 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO15_CSU_CSU_INT_DEB                             0x064 0x2CC 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_ENET_MDC_ENET1_MDC                                     0x068 0x2D0 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_ENET_MDC_GPIO1_IO16                                    0x068 0x2D0 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_ENET_MDIO_ENET1_MDIO                                   0x06C 0x2D4 0x4C0 0x0 0x1
+#define MX8MQ_IOMUXC_ENET_MDIO_GPIO1_IO17                                   0x06C 0x2D4 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_ENET_TD3_ENET1_RGMII_TD3                               0x070 0x2D8 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_ENET_TD3_GPIO1_IO18                                    0x070 0x2D8 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_ENET_TD2_ENET1_RGMII_TD2                               0x074 0x2DC 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_ENET_TD2_ENET1_TX_CLK                                  0x074 0x2DC 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_ENET_TD2_GPIO1_IO19                                    0x074 0x2DC 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_ENET_TD1_ENET1_RGMII_TD1                               0x078 0x2E0 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_ENET_TD1_GPIO1_IO20                                    0x078 0x2E0 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_ENET_TD0_ENET1_RGMII_TD0                               0x07C 0x2E4 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_ENET_TD0_GPIO1_IO21                                    0x07C 0x2E4 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_ENET_TX_CTL_ENET1_RGMII_TX_CTL                         0x080 0x2E8 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_ENET_TX_CTL_GPIO1_IO22                                 0x080 0x2E8 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_ENET_TXC_ENET1_RGMII_TXC                               0x084 0x2EC 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_ENET_TXC_ENET1_TX_ER                                   0x084 0x2EC 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_ENET_TXC_GPIO1_IO23                                    0x084 0x2EC 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_ENET_RX_CTL_ENET1_RGMII_RX_CTL                         0x088 0x2F0 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_ENET_RX_CTL_GPIO1_IO24                                 0x088 0x2F0 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_ENET_RXC_ENET1_RGMII_RXC                               0x08C 0x2F4 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_ENET_RXC_ENET1_RX_ER                                   0x08C 0x2F4 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_ENET_RXC_GPIO1_IO25                                    0x08C 0x2F4 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_ENET_RD0_ENET1_RGMII_RD0                               0x090 0x2F8 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_ENET_RD0_GPIO1_IO26                                    0x090 0x2F8 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_ENET_RD1_ENET1_RGMII_RD1                               0x094 0x2FC 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_ENET_RD1_GPIO1_IO27                                    0x094 0x2FC 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_ENET_RD2_ENET1_RGMII_RD2                               0x098 0x300 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_ENET_RD2_GPIO1_IO28                                    0x098 0x300 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_ENET_RD3_ENET1_RGMII_RD3                               0x09C 0x304 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_ENET_RD3_GPIO1_IO29                                    0x09C 0x304 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SD1_CLK_USDHC1_CLK                                     0x0A0 0x308 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_SD1_CLK_GPIO2_IO0                                      0x0A0 0x308 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SD1_CMD_USDHC1_CMD                                     0x0A4 0x30C 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_SD1_CMD_GPIO2_IO1                                      0x0A4 0x30C 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SD1_DATA0_USDHC1_DATA0                                 0x0A8 0x310 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_SD1_DATA0_GPIO2_IO2                                    0x0A8 0x31  0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SD1_DATA1_USDHC1_DATA1                                 0x0AC 0x314 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_SD1_DATA1_GPIO2_IO3                                    0x0AC 0x314 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SD1_DATA2_USDHC1_DATA2                                 0x0B0 0x318 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_SD1_DATA2_GPIO2_IO4                                    0x0B0 0x318 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SD1_DATA3_USDHC1_DATA3                                 0x0B4 0x31C 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_SD1_DATA3_GPIO2_IO5                                    0x0B4 0x31C 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SD1_DATA4_USDHC1_DATA4                                 0x0B8 0x320 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_SD1_DATA4_GPIO2_IO6                                    0x0B8 0x320 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SD1_DATA5_USDHC1_DATA5                                 0x0BC 0x324 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_SD1_DATA5_GPIO2_IO7                                    0x0BC 0x324 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SD1_DATA6_USDHC1_DATA6                                 0x0C0 0x328 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_SD1_DATA6_GPIO2_IO8                                    0x0C0 0x328 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SD1_DATA7_USDHC1_DATA7                                 0x0C4 0x32C 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_SD1_DATA7_GPIO2_IO9                                    0x0C4 0x32C 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SD1_RESET_B_USDHC1_RESET_B                             0x0C8 0x330 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_SD1_RESET_B_GPIO2_IO10                                 0x0C8 0x330 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SD1_STROBE_USDHC1_STROBE                               0x0CC 0x334 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_SD1_STROBE_GPIO2_IO11                                  0x0CC 0x334 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SD2_CD_B_USDHC2_CD_B                                   0x0D0 0x338 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_SD2_CD_B_GPIO2_IO12                                    0x0D0 0x338 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SD2_CLK_USDHC2_CLK                                     0x0D4 0x33C 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_SD2_CLK_GPIO2_IO13                                     0x0D4 0x33C 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SD2_CLK_CCMSRCGPCMIX_OBSERVE0                          0x0D4 0x33C 0x000 0x6 0x0
+#define MX8MQ_IOMUXC_SD2_CLK_OBSERVE_MUX_OUT0                               0x0D4 0x33C 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_SD2_CMD_USDHC2_CMD                                     0x0D8 0x340 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_SD2_CMD_GPIO2_IO14                                     0x0D8 0x340 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SD2_CMD_CCMSRCGPCMIX_OBSERVE1                          0x0D8 0x340 0x000 0x6 0x0
+#define MX8MQ_IOMUXC_SD2_CMD_OBSERVE_MUX_OUT1                               0x0D8 0x340 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_SD2_DATA0_USDHC2_DATA0                                 0x0DC 0x344 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_SD2_DATA0_GPIO2_IO15                                   0x0DC 0x344 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SD2_DATA0_CCMSRCGPCMIX_OBSERVE2                        0x0DC 0x344 0x000 0x6 0x0
+#define MX8MQ_IOMUXC_SD2_DATA0_OBSERVE_MUX_OUT2                             0x0DC 0x344 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_SD2_DATA1_USDHC2_DATA1                                 0x0E0 0x348 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_SD2_DATA1_GPIO2_IO16                                   0x0E0 0x348 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SD2_DATA1_CCMSRCGPCMIX_WAIT                            0x0E0 0x348 0x000 0x6 0x0
+#define MX8MQ_IOMUXC_SD2_DATA1_OBSERVE_MUX_OUT3                             0x0E0 0x348 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_SD2_DATA2_USDHC2_DATA2                                 0x0E4 0x34C 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_SD2_DATA2_GPIO2_IO17                                   0x0E4 0x34C 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SD2_DATA2_CCMSRCGPCMIX_STOP                            0x0E4 0x34C 0x000 0x6 0x0
+#define MX8MQ_IOMUXC_SD2_DATA2_OBSERVE_MUX_OUT4                             0x0E4 0x34C 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_SD2_DATA3_USDHC2_DATA3                                 0x0E8 0x350 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_SD2_DATA3_GPIO2_IO18                                   0x0E8 0x350 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SD2_DATA3_CCMSRCGPCMIX_EARLY_RESET                     0x0E8 0x350 0x000 0x6 0x0
+#define MX8MQ_IOMUXC_SD2_RESET_B_USDHC2_RESET_B                             0x0EC 0x354 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_SD2_RESET_B_GPIO2_IO19                                 0x0EC 0x354 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SD2_RESET_B_CCMSRCGPCMIX_SYSTEM_RESET                  0x0EC 0x354 0x000 0x6 0x0
+#define MX8MQ_IOMUXC_SD2_WP_USDHC2_WP                                       0x0F0 0x358 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_SD2_WP_GPIO2_IO20                                      0x0F0 0x358 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SD2_WP_SIM_M_HMASTLOCK                                 0x0F0 0x358 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_NAND_ALE_RAWNAND_ALE                                   0x0F4 0x35C 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_NAND_ALE_QSPI_A_SCLK                                   0x0F4 0x35C 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_NAND_ALE_GPIO3_IO0                                     0x0F4 0x35C 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_NAND_ALE_SIM_M_HPROT0                                  0x0F4 0x35C 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_NAND_CE0_B_RAWNAND_CE0_B                               0x0F8 0x360 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_NAND_CE0_B_QSPI_A_SS0_B                                0x0F8 0x360 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_NAND_CE0_B_GPIO3_IO1                                   0x0F8 0x360 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_NAND_CE0_B_SIM_M_HPROT1                                0x0F8 0x360 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_NAND_CE1_B_RAWNAND_CE1_B                               0x0FC 0x364 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_NAND_CE1_B_QSPI_A_SS1_B                                0x0FC 0x364 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_NAND_CE1_B_GPIO3_IO2                                   0x0FC 0x364 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_NAND_CE1_B_SIM_M_HPROT2                                0x0FC 0x364 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_NAND_CE2_B_RAWNAND_CE2_B                               0x100 0x368 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_NAND_CE2_B_QSPI_B_SS0_B                                0x100 0x368 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_NAND_CE2_B_GPIO3_IO3                                   0x100 0x368 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_NAND_CE2_B_SIM_M_HPROT3                                0x100 0x368 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_NAND_CE3_B_RAWNAND_CE3_B                               0x104 0x36C 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_NAND_CE3_B_QSPI_B_SS1_B                                0x104 0x36C 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_NAND_CE3_B_GPIO3_IO4                                   0x104 0x36C 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_NAND_CE3_B_SIM_M_HADDR0                                0x104 0x36C 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_NAND_CLE_RAWNAND_CLE                                   0x108 0x370 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_NAND_CLE_QSPI_B_SCLK                                   0x108 0x370 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_NAND_CLE_GPIO3_IO5                                     0x108 0x370 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_NAND_CLE_SIM_M_HADDR1                                  0x108 0x370 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_NAND_DATA00_RAWNAND_DATA00                             0x10C 0x374 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_NAND_DATA00_QSPI_A_DATA0                               0x10C 0x374 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_NAND_DATA00_GPIO3_IO6                                  0x10C 0x374 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_NAND_DATA00_SIM_M_HADDR2                               0x10C 0x374 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_NAND_DATA01_RAWNAND_DATA01                             0x110 0x378 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_NAND_DATA01_QSPI_A_DATA1                               0x110 0x378 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_NAND_DATA01_GPIO3_IO7                                  0x110 0x378 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_NAND_DATA01_SIM_M_HADDR3                               0x110 0x378 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_NAND_DATA02_RAWNAND_DATA02                             0x114 0x37C 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_NAND_DATA02_QSPI_A_DATA2                               0x114 0x37C 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_NAND_DATA02_GPIO3_IO8                                  0x114 0x37C 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_NAND_DATA02_SIM_M_HADDR4                               0x114 0x37C 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_NAND_DATA03_RAWNAND_DATA03                             0x118 0x380 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_NAND_DATA03_QSPI_A_DATA3                               0x118 0x380 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_NAND_DATA03_GPIO3_IO9                                  0x118 0x380 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_NAND_DATA03_SIM_M_HADDR5                               0x118 0x380 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_NAND_DATA04_RAWNAND_DATA04                             0x11C 0x384 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_NAND_DATA04_QSPI_B_DATA0                               0x11C 0x384 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_NAND_DATA04_GPIO3_IO10                                 0x11C 0x384 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_NAND_DATA04_SIM_M_HADDR6                               0x11C 0x384 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_NAND_DATA05_RAWNAND_DATA05                             0x120 0x388 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_NAND_DATA05_QSPI_B_DATA1                               0x120 0x388 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_NAND_DATA05_GPIO3_IO11                                 0x120 0x388 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_NAND_DATA05_SIM_M_HADDR7                               0x120 0x388 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_NAND_DATA06_RAWNAND_DATA06                             0x124 0x38C 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_NAND_DATA06_QSPI_B_DATA2                               0x124 0x38C 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_NAND_DATA06_GPIO3_IO12                                 0x124 0x38C 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_NAND_DATA06_SIM_M_HADDR8                               0x124 0x38C 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_NAND_DATA07_RAWNAND_DATA07                             0x128 0x390 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_NAND_DATA07_QSPI_B_DATA3                               0x128 0x390 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_NAND_DATA07_GPIO3_IO13                                 0x128 0x390 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_NAND_DATA07_SIM_M_HADDR9                               0x128 0x390 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_NAND_DQS_RAWNAND_DQS                                   0x12C 0x394 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_NAND_DQS_QSPI_A_DQS                                    0x12C 0x394 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_NAND_DQS_GPIO3_IO14                                    0x12C 0x394 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_NAND_DQS_SIM_M_HADDR10                                 0x12C 0x394 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_NAND_RE_B_RAWNAND_RE_B                                 0x130 0x398 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_NAND_RE_B_QSPI_B_DQS                                   0x130 0x398 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_NAND_RE_B_GPIO3_IO15                                   0x130 0x398 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_NAND_RE_B_SIM_M_HADDR11                                0x130 0x398 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_NAND_READY_B_RAWNAND_READY_B                           0x134 0x39C 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_NAND_READY_B_GPIO3_IO16                                0x134 0x39C 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_NAND_READY_B_SIM_M_HADDR12                             0x134 0x39C 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_NAND_WE_B_RAWNAND_WE_B                                 0x138 0x3A0 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_NAND_WE_B_GPIO3_IO17                                   0x138 0x3A0 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_NAND_WE_B_SIM_M_HADDR13                                0x138 0x3A0 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_NAND_WP_B_RAWNAND_WP_B                                 0x13C 0x3A4 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_NAND_WP_B_GPIO3_IO18                                   0x13C 0x3A4 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_NAND_WP_B_SIM_M_HADDR14                                0x13C 0x3A4 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_SAI5_RXFS_SAI5_RX_SYNC                                 0x140 0x3A8 0x4E4 0x0 0x0
+#define MX8MQ_IOMUXC_SAI5_RXFS_SAI1_TX_DATA0                                0x140 0x3A8 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_SAI5_RXFS_GPIO3_IO19                                   0x140 0x3A8 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SAI5_RXC_SAI5_RX_BCLK                                  0x144 0x3AC 0x4D0 0x0 0x0
+#define MX8MQ_IOMUXC_SAI5_RXC_SAI1_TX_DATA1                                 0x144 0x3AC 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_SAI5_RXC_GPIO3_IO20                                    0x144 0x3AC 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SAI5_RXD0_SAI5_RX_DATA0                                0x148 0x3B0 0x4D4 0x0 0x0
+#define MX8MQ_IOMUXC_SAI5_RXD0_SAI1_TX_DATA2                                0x148 0x3B0 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_SAI5_RXD0_GPIO3_IO21                                   0x148 0x3B0 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SAI5_RXD1_SAI5_RX_DATA1                                0x14C 0x3B4 0x4D8 0x0 0x0
+#define MX8MQ_IOMUXC_SAI5_RXD1_SAI1_TX_DATA3                                0x14C 0x3B4 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_SAI5_RXD1_SAI1_TX_SYNC                                 0x14C 0x3B4 0x4CC 0x2 0x0
+#define MX8MQ_IOMUXC_SAI5_RXD1_SAI5_TX_SYNC                                 0x14C 0x3B4 0x4EC 0x3 0x0
+#define MX8MQ_IOMUXC_SAI5_RXD1_GPIO3_IO22                                   0x14C 0x3B4 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SAI5_RXD2_SAI5_RX_DATA2                                0x150 0x3B8 0x4DC 0x0 0x0
+#define MX8MQ_IOMUXC_SAI5_RXD2_SAI1_TX_DATA4                                0x150 0x3B8 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_SAI5_RXD2_SAI1_TX_SYNC                                 0x150 0x3B8 0x4CC 0x2 0x1
+#define MX8MQ_IOMUXC_SAI5_RXD2_SAI5_TX_BCLK                                 0x150 0x3B8 0x4E8 0x3 0x0
+#define MX8MQ_IOMUXC_SAI5_RXD2_GPIO3_IO23                                   0x150 0x3B8 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SAI5_RXD3_SAI5_RX_DATA3                                0x154 0x3BC 0x4E0 0x0 0x0
+#define MX8MQ_IOMUXC_SAI5_RXD3_SAI1_TX_DATA5                                0x154 0x3BC 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_SAI5_RXD3_SAI1_TX_SYNC                                 0x154 0x3BC 0x4CC 0x2 0x2
+#define MX8MQ_IOMUXC_SAI5_RXD3_SAI5_TX_DATA0                                0x154 0x3BC 0x000 0x3 0x0
+#define MX8MQ_IOMUXC_SAI5_RXD3_GPIO3_IO24                                   0x154 0x3BC 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SAI5_MCLK_SAI5_MCLK                                    0x158 0x3C0 0x52C 0x0 0x0
+#define MX8MQ_IOMUXC_SAI5_MCLK_SAI1_TX_BCLK                                 0x158 0x3C0 0x4C8 0x1 0x0
+#define MX8MQ_IOMUXC_SAI5_MCLK_SAI4_MCLK                                    0x158 0x3C0 0x000 0x2 0x0
+#define MX8MQ_IOMUXC_SAI5_MCLK_GPIO3_IO25                                   0x158 0x3C0 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SAI5_MCLK_CCMSRCGPCMIX_TESTER_ACK                      0x158 0x3C0 0x000 0x6 0x0
+#define MX8MQ_IOMUXC_SAI1_RXFS_SAI1_RX_SYNC                                 0x15C 0x3C4 0x4C4 0x0 0x0
+#define MX8MQ_IOMUXC_SAI1_RXFS_SAI5_RX_SYNC                                 0x15C 0x3C4 0x4E4 0x1 0x1
+#define MX8MQ_IOMUXC_SAI1_RXFS_CORESIGHT_TRACE_CLK                          0x15C 0x3C4 0x000 0x4 0x0
+#define MX8MQ_IOMUXC_SAI1_RXFS_GPIO4_IO0                                    0x15C 0x3C4 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SAI1_RXFS_SIM_M_HADDR15                                0x15C 0x3C4 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_SAI1_RXC_SAI1_RX_BCLK                                  0x160 0x3C8 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_SAI1_RXC_SAI5_RX_BCLK                                  0x160 0x3C8 0x4D0 0x1 0x1
+#define MX8MQ_IOMUXC_SAI1_RXC_CORESIGHT_TRACE_CTL                           0x160 0x3C8 0x000 0x4 0x0
+#define MX8MQ_IOMUXC_SAI1_RXC_GPIO4_IO1                                     0x160 0x3C8 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SAI1_RXC_SIM_M_HADDR16                                 0x160 0x3C8 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_SAI1_RXD0_SAI1_RX_DATA0                                0x164 0x3CC 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_SAI1_RXD0_SAI5_RX_DATA0                                0x164 0x3CC 0x4D4 0x1 0x1
+#define MX8MQ_IOMUXC_SAI1_RXD0_CORESIGHT_TRACE0                             0x164 0x3CC 0x000 0x4 0x0
+#define MX8MQ_IOMUXC_SAI1_RXD0_GPIO4_IO2                                    0x164 0x3CC 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SAI1_RXD0_CCMSRCGPCMIX_BOOT_CFG0                       0x164 0x3CC 0x000 0x6 0x0
+#define MX8MQ_IOMUXC_SAI1_RXD0_SIM_M_HADDR17                                0x164 0x3CC 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_SAI1_RXD1_SAI1_RX_DATA1                                0x168 0x3D0 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_SAI1_RXD1_SAI5_RX_DATA1                                0x168 0x3D0 0x4D8 0x1 0x1
+#define MX8MQ_IOMUXC_SAI1_RXD1_CORESIGHT_TRACE1                             0x168 0x3D0 0x000 0x4 0x0
+#define MX8MQ_IOMUXC_SAI1_RXD1_GPIO4_IO3                                    0x168 0x3D0 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SAI1_RXD1_CCMSRCGPCMIX_BOOT_CFG1                       0x168 0x3D0 0x000 0x6 0x0
+#define MX8MQ_IOMUXC_SAI1_RXD1_SIM_M_HADDR18                                0x168 0x3D0 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_SAI1_RXD2_SAI1_RX_DATA2                                0x16C 0x3D4 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_SAI1_RXD2_SAI5_RX_DATA2                                0x16C 0x3D4 0x4DC 0x1 0x1
+#define MX8MQ_IOMUXC_SAI1_RXD2_CORESIGHT_TRACE2                             0x16C 0x3D4 0x000 0x4 0x0
+#define MX8MQ_IOMUXC_SAI1_RXD2_GPIO4_IO4                                    0x16C 0x3D4 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SAI1_RXD2_CCMSRCGPCMIX_BOOT_CFG2                       0x16C 0x3D4 0x000 0x6 0x0
+#define MX8MQ_IOMUXC_SAI1_RXD2_SIM_M_HADDR19                                0x16C 0x3D4 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_SAI1_RXD3_SAI1_RX_DATA3                                0x170 0x3D8 0x4E0 0x0 0x1
+#define MX8MQ_IOMUXC_SAI1_RXD3_SAI5_RX_DATA3                                0x170 0x3D8 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_SAI1_RXD3_CORESIGHT_TRACE3                             0x170 0x3D8 0x000 0x4 0x0
+#define MX8MQ_IOMUXC_SAI1_RXD3_GPIO4_IO5                                    0x170 0x3D8 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SAI1_RXD3_CCMSRCGPCMIX_BOOT_CFG3                       0x170 0x3D8 0x000 0x6 0x0
+#define MX8MQ_IOMUXC_SAI1_RXD3_SIM_M_HADDR20                                0x170 0x3D8 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_SAI1_RXD4_SAI1_RX_DATA4                                0x174 0x3DC 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_SAI1_RXD4_SAI6_TX_BCLK                                 0x174 0x3DC 0x51C 0x1 0x0
+#define MX8MQ_IOMUXC_SAI1_RXD4_SAI6_RX_BCLK                                 0x174 0x3DC 0x510 0x2 0x0
+#define MX8MQ_IOMUXC_SAI1_RXD4_CORESIGHT_TRACE4                             0x174 0x3DC 0x000 0x4 0x0
+#define MX8MQ_IOMUXC_SAI1_RXD4_GPIO4_IO6                                    0x174 0x3DC 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SAI1_RXD4_CCMSRCGPCMIX_BOOT_CFG4                       0x174 0x3DC 0x000 0x6 0x0
+#define MX8MQ_IOMUXC_SAI1_RXD4_SIM_M_HADDR21                                0x174 0x3DC 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_SAI1_RXD5_SAI1_RX_DATA5                                0x178 0x3E0 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_SAI1_RXD5_SAI6_TX_DATA0                                0x178 0x3E0 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_SAI1_RXD5_SAI6_RX_DATA0                                0x178 0x3E0 0x514 0x2 0x0
+#define MX8MQ_IOMUXC_SAI1_RXD5_SAI1_RX_SYNC                                 0x178 0x3E0 0x4C4 0x3 0x1
+#define MX8MQ_IOMUXC_SAI1_RXD5_CORESIGHT_TRACE5                             0x178 0x3E0 0x000 0x4 0x0
+#define MX8MQ_IOMUXC_SAI1_RXD5_GPIO4_IO7                                    0x178 0x3E0 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SAI1_RXD5_CCMSRCGPCMIX_BOOT_CFG5                       0x178 0x3E0 0x000 0x6 0x0
+#define MX8MQ_IOMUXC_SAI1_RXD5_SIM_M_HADDR22                                0x178 0x3E0 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_SAI1_RXD6_SAI1_RX_DATA6                                0x17C 0x3E4 0x520 0x0 0x0
+#define MX8MQ_IOMUXC_SAI1_RXD6_SAI6_TX_SYNC                                 0x17C 0x3E4 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_SAI1_RXD6_SAI6_RX_SYNC                                 0x17C 0x3E4 0x518 0x2 0x0
+#define MX8MQ_IOMUXC_SAI1_RXD6_CORESIGHT_TRACE6                             0x17C 0x3E4 0x000 0x4 0x0
+#define MX8MQ_IOMUXC_SAI1_RXD6_GPIO4_IO8                                    0x17C 0x3E4 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SAI1_RXD6_CCMSRCGPCMIX_BOOT_CFG6                       0x17C 0x3E4 0x000 0x6 0x0
+#define MX8MQ_IOMUXC_SAI1_RXD6_SIM_M_HADDR23                                0x17C 0x3E4 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_SAI1_RXD7_SAI1_RX_DATA7                                0x180 0x3E8 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_SAI1_RXD7_SAI6_MCLK                                    0x180 0x3E8 0x530 0x1 0x0
+#define MX8MQ_IOMUXC_SAI1_RXD7_SAI1_TX_SYNC                                 0x180 0x3E8 0x4CC 0x2 0x4
+#define MX8MQ_IOMUXC_SAI1_RXD7_SAI1_TX_DATA4                                0x180 0x3E8 0x000 0x3 0x0
+#define MX8MQ_IOMUXC_SAI1_RXD7_CORESIGHT_TRACE7                             0x180 0x3E8 0x000 0x4 0x0
+#define MX8MQ_IOMUXC_SAI1_RXD7_GPIO4_IO9                                    0x180 0x3E8 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SAI1_RXD7_CCMSRCGPCMIX_BOOT_CFG7                       0x180 0x3E8 0x000 0x6 0x0
+#define MX8MQ_IOMUXC_SAI1_RXD7_SIM_M_HADDR24                                0x180 0x3E8 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_SAI1_TXFS_SAI1_TX_SYNC                                 0x184 0x3EC 0x4CC 0x0 0x3
+#define MX8MQ_IOMUXC_SAI1_TXFS_SAI5_TX_SYNC                                 0x184 0x3EC 0x4EC 0x1 0x1
+#define MX8MQ_IOMUXC_SAI1_TXFS_CORESIGHT_EVENTO                             0x184 0x3EC 0x000 0x4 0x0
+#define MX8MQ_IOMUXC_SAI1_TXFS_GPIO4_IO10                                   0x184 0x3EC 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SAI1_TXFS_SIM_M_HADDR25                                0x184 0x3EC 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_SAI1_TXC_SAI1_TX_BCLK                                  0x188 0x3F0 0x4C8 0x0 0x1
+#define MX8MQ_IOMUXC_SAI1_TXC_SAI5_TX_BCLK                                  0x188 0x3F0 0x4E8 0x1 0x1
+#define MX8MQ_IOMUXC_SAI1_TXC_CORESIGHT_EVENTI                              0x188 0x3F0 0x000 0x4 0x0
+#define MX8MQ_IOMUXC_SAI1_TXC_GPIO4_IO11                                    0x188 0x3F0 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SAI1_TXC_SIM_M_HADDR26                                 0x188 0x3F0 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_SAI1_TXD0_SAI1_TX_DATA0                                0x18C 0x3F4 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_SAI1_TXD0_SAI5_TX_DATA0                                0x18C 0x3F4 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_SAI1_TXD0_CORESIGHT_TRACE8                             0x18C 0x3F4 0x000 0x4 0x0
+#define MX8MQ_IOMUXC_SAI1_TXD0_GPIO4_IO12                                   0x18C 0x3F4 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SAI1_TXD0_CCMSRCGPCMIX_BOOT_CFG8                       0x18C 0x3F4 0x000 0x6 0x0
+#define MX8MQ_IOMUXC_SAI1_TXD0_SIM_M_HADDR27                                0x18C 0x3F4 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_SAI1_TXD1_SAI1_TX_DATA1                                0x190 0x3F8 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_SAI1_TXD1_SAI5_TX_DATA1                                0x190 0x3F8 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_SAI1_TXD1_CORESIGHT_TRACE9                             0x190 0x3F8 0x000 0x4 0x0
+#define MX8MQ_IOMUXC_SAI1_TXD1_GPIO4_IO13                                   0x190 0x3F8 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SAI1_TXD1_CCMSRCGPCMIX_BOOT_CFG9                       0x190 0x3F8 0x000 0x6 0x0
+#define MX8MQ_IOMUXC_SAI1_TXD1_SIM_M_HADDR28                                0x190 0x3F8 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_SAI1_TXD2_SAI1_TX_DATA2                                0x194 0x3FC 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_SAI1_TXD2_SAI5_TX_DATA2                                0x194 0x3FC 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_SAI1_TXD2_CORESIGHT_TRACE10                            0x194 0x3FC 0x000 0x4 0x0
+#define MX8MQ_IOMUXC_SAI1_TXD2_GPIO4_IO14                                   0x194 0x3FC 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SAI1_TXD2_CCMSRCGPCMIX_BOOT_CFG10                      0x194 0x3FC 0x000 0x6 0x0
+#define MX8MQ_IOMUXC_SAI1_TXD2_SIM_M_HADDR29                                0x194 0x3FC 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_SAI1_TXD3_SAI1_TX_DATA3                                0x198 0x400 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_SAI1_TXD3_SAI5_TX_DATA3                                0x198 0x400 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_SAI1_TXD3_CORESIGHT_TRACE11                            0x198 0x400 0x000 0x4 0x0
+#define MX8MQ_IOMUXC_SAI1_TXD3_GPIO4_IO15                                   0x198 0x400 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SAI1_TXD3_CCMSRCGPCMIX_BOOT_CFG11                      0x198 0x400 0x000 0x6 0x0
+#define MX8MQ_IOMUXC_SAI1_TXD3_SIM_M_HADDR30                                0x198 0x400 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_SAI1_TXD4_SAI1_TX_DATA4                                0x19C 0x404 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_SAI1_TXD4_SAI6_RX_BCLK                                 0x19C 0x404 0x510 0x1 0x1
+#define MX8MQ_IOMUXC_SAI1_TXD4_SAI6_TX_BCLK                                 0x19C 0x404 0x51C 0x2 0x1
+#define MX8MQ_IOMUXC_SAI1_TXD4_CORESIGHT_TRACE12                            0x19C 0x404 0x000 0x4 0x0
+#define MX8MQ_IOMUXC_SAI1_TXD4_GPIO4_IO16                                   0x19C 0x404 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SAI1_TXD4_CCMSRCGPCMIX_BOOT_CFG12                      0x19C 0x404 0x000 0x6 0x0
+#define MX8MQ_IOMUXC_SAI1_TXD4_SIM_M_HADDR31                                0x19C 0x404 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_SAI1_TXD5_SAI1_TX_DATA5                                0x1A0 0x408 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_SAI1_TXD5_SAI6_RX_DATA0                                0x1A0 0x408 0x514 0x1 0x1
+#define MX8MQ_IOMUXC_SAI1_TXD5_SAI6_TX_DATA0                                0x1A0 0x408 0x000 0x2 0x0
+#define MX8MQ_IOMUXC_SAI1_TXD5_CORESIGHT_TRACE13                            0x1A0 0x408 0x000 0x4 0x0
+#define MX8MQ_IOMUXC_SAI1_TXD5_GPIO4_IO17                                   0x1A0 0x408 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SAI1_TXD5_CCMSRCGPCMIX_BOOT_CFG13                      0x1A0 0x408 0x000 0x6 0x0
+#define MX8MQ_IOMUXC_SAI1_TXD5_SIM_M_HBURST0                                0x1A0 0x408 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_SAI1_TXD6_SAI1_TX_DATA6                                0x1A4 0x40C 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_SAI1_TXD6_SAI6_RX_SYNC                                 0x1A4 0x40C 0x518 0x1 0x1
+#define MX8MQ_IOMUXC_SAI1_TXD6_SAI6_TX_SYNC                                 0x1A4 0x40C 0x520 0x2 0x1
+#define MX8MQ_IOMUXC_SAI1_TXD6_CORESIGHT_TRACE14                            0x1A4 0x40C 0x000 0x4 0x0
+#define MX8MQ_IOMUXC_SAI1_TXD6_GPIO4_IO18                                   0x1A4 0x40C 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SAI1_TXD6_CCMSRCGPCMIX_BOOT_CFG14                      0x1A4 0x40C 0x000 0x6 0x0
+#define MX8MQ_IOMUXC_SAI1_TXD6_SIM_M_HBURST1                                0x1A4 0x40C 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_SAI1_TXD7_SAI1_TX_DATA7                                0x1A8 0x410 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_SAI1_TXD7_SAI6_MCLK                                    0x1A8 0x410 0x530 0x1 0x1
+#define MX8MQ_IOMUXC_SAI1_TXD7_CORESIGHT_TRACE15                            0x1A8 0x410 0x000 0x4 0x0
+#define MX8MQ_IOMUXC_SAI1_TXD7_GPIO4_IO19                                   0x1A8 0x410 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SAI1_TXD7_CCMSRCGPCMIX_BOOT_CFG15                      0x1A8 0x410 0x000 0x6 0x0
+#define MX8MQ_IOMUXC_SAI1_TXD7_SIM_M_HBURST2                                0x1A8 0x410 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_SAI1_MCLK_SAI1_MCLK                                    0x1AC 0x414 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_SAI1_MCLK_SAI5_MCLK                                    0x1AC 0x414 0x52C 0x1 0x1
+#define MX8MQ_IOMUXC_SAI1_MCLK_SAI1_TX_BCLK                                 0x1AC 0x414 0x4C8 0x2 0x2
+#define MX8MQ_IOMUXC_SAI1_MCLK_GPIO4_IO20                                   0x1AC 0x414 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SAI1_MCLK_SIM_M_HRESP                                  0x1AC 0x414 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_SAI2_RXFS_SAI2_RX_SYNC                                 0x1B0 0x418 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_SAI2_RXFS_SAI5_TX_SYNC                                 0x1B0 0x418 0x4EC 0x1 0x2
+#define MX8MQ_IOMUXC_SAI2_RXFS_GPIO4_IO21                                   0x1B0 0x418 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SAI2_RXFS_SIM_M_HSIZE0                                 0x1B0 0x418 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_SAI2_RXC_SAI2_RX_BCLK                                  0x1B4 0x41C 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_SAI2_RXC_SAI5_TX_BCLK                                  0x1B4 0x41C 0x4E8 0x1 0x2
+#define MX8MQ_IOMUXC_SAI2_RXC_GPIO4_IO22                                    0x1B4 0x41C 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SAI2_RXC_SIM_M_HSIZE1                                  0x1B4 0x41C 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_SAI2_RXD0_SAI2_RX_DATA0                                0x1B8 0x420 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_SAI2_RXD0_SAI5_TX_DATA0                                0x1B8 0x420 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_SAI2_RXD0_GPIO4_IO23                                   0x1B8 0x420 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SAI2_RXD0_SIM_M_HSIZE2                                 0x1B8 0x420 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_SAI2_TXFS_SAI2_TX_SYNC                                 0x1BC 0x424 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_SAI2_TXFS_SAI5_TX_DATA1                                0x1BC 0x424 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_SAI2_TXFS_GPIO4_IO24                                   0x1BC 0x424 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SAI2_TXFS_SIM_M_HWRITE                                 0x1BC 0x424 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_SAI2_TXC_SAI2_TX_BCLK                                  0x1C0 0x428 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_SAI2_TXC_SAI5_TX_DATA2                                 0x1C0 0x428 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_SAI2_TXC_GPIO4_IO25                                    0x1C0 0x428 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SAI2_TXC_SIM_M_HREADYOUT                               0x1C0 0x428 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_SAI2_TXD0_SAI2_TX_DATA0                                0x1C4 0x42C 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_SAI2_TXD0_SAI5_TX_DATA3                                0x1C4 0x42C 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_SAI2_TXD0_GPIO4_IO26                                   0x1C4 0x42C 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SAI2_TXD0_TPSMP_CLK                                    0x1C4 0x42C 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_SAI2_MCLK_SAI2_MCLK                                    0x1C8 0x430 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_SAI2_MCLK_SAI5_MCLK                                    0x1C8 0x430 0x52C 0x1 0x2
+#define MX8MQ_IOMUXC_SAI2_MCLK_GPIO4_IO27                                   0x1C8 0x430 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SAI2_MCLK_TPSMP_HDATA_DIR                              0x1C8 0x430 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_SAI3_RXFS_SAI3_RX_SYNC                                 0x1CC 0x434 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_SAI3_RXFS_GPT1_CAPTURE1                                0x1CC 0x434 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_SAI3_RXFS_SAI5_RX_SYNC                                 0x1CC 0x434 0x4E4 0x2 0x2
+#define MX8MQ_IOMUXC_SAI3_RXFS_GPIO4_IO28                                   0x1CC 0x434 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SAI3_RXFS_TPSMP_HTRANS0                                0x1CC 0x434 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_SAI3_RXC_SAI3_RX_BCLK                                  0x1D0 0x438 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_SAI3_RXC_GPT1_CAPTURE2                                 0x1D0 0x438 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_SAI3_RXC_SAI5_RX_BCLK                                  0x1D0 0x438 0x4D0 0x2 0x2
+#define MX8MQ_IOMUXC_SAI3_RXC_GPIO4_IO29                                    0x1D0 0x438 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SAI3_RXC_TPSMP_HTRANS1                                 0x1D0 0x438 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_SAI3_RXD_SAI3_RX_DATA0                                 0x1D4 0x43C 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_SAI3_RXD_GPT1_COMPARE1                                 0x1D4 0x43C 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_SAI3_RXD_SAI5_RX_DATA0                                 0x1D4 0x43C 0x4D4 0x2 0x2
+#define MX8MQ_IOMUXC_SAI3_RXD_GPIO4_IO30                                    0x1D4 0x43C 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SAI3_RXD_TPSMP_HDATA0                                  0x1D4 0x43C 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_SAI3_TXFS_SAI3_TX_SYNC                                 0x1D8 0x440 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_SAI3_TXFS_GPT1_CLK                                     0x1D8 0x440 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_SAI3_TXFS_SAI5_RX_DATA1                                0x1D8 0x440 0x4D8 0x2 0x2
+#define MX8MQ_IOMUXC_SAI3_TXFS_GPIO4_IO31                                   0x1D8 0x440 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SAI3_TXFS_TPSMP_HDATA1                                 0x1D8 0x440 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_SAI3_TXC_SAI3_TX_BCLK                                  0x1DC 0x444 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_SAI3_TXC_GPT1_COMPARE2                                 0x1DC 0x444 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_SAI3_TXC_SAI5_RX_DATA2                                 0x1DC 0x444 0x4DC 0x2 0x2
+#define MX8MQ_IOMUXC_SAI3_TXC_GPIO5_IO0                                     0x1DC 0x444 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SAI3_TXC_TPSMP_HDATA2                                  0x1DC 0x444 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_SAI3_TXD_SAI3_TX_DATA0                                 0x1E0 0x448 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_SAI3_TXD_GPT1_COMPARE3                                 0x1E0 0x448 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_SAI3_TXD_SAI5_RX_DATA3                                 0x1E0 0x448 0x4E0 0x2 0x2
+#define MX8MQ_IOMUXC_SAI3_TXD_GPIO5_IO1                                     0x1E0 0x448 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SAI3_TXD_TPSMP_HDATA3                                  0x1E0 0x448 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_SAI3_MCLK_SAI3_MCLK                                    0x1E4 0x44C 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_SAI3_MCLK_PWM4_OUT                                     0x1E4 0x44C 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_SAI3_MCLK_SAI5_MCLK                                    0x1E4 0x44C 0x52C 0x2 0x3
+#define MX8MQ_IOMUXC_SAI3_MCLK_GPIO5_IO2                                    0x1E4 0x44C 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SAI3_MCLK_TPSMP_HDATA4                                 0x1E4 0x44C 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_SPDIF_TX_SPDIF1_OUT                                    0x1E8 0x450 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_SPDIF_TX_PWM3_OUT                                      0x1E8 0x450 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_SPDIF_TX_GPIO5_IO3                                     0x1E8 0x450 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SPDIF_TX_TPSMP_HDATA5                                  0x1E8 0x450 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_SPDIF_RX_SPDIF1_IN                                     0x1EC 0x454 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_SPDIF_RX_PWM2_OUT                                      0x1EC 0x454 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_SPDIF_RX_GPIO5_IO4                                     0x1EC 0x454 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SPDIF_RX_TPSMP_HDATA6                                  0x1EC 0x454 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_SPDIF_EXT_CLK_SPDIF1_EXT_CLK                           0x1F0 0x458 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_SPDIF_EXT_CLK_PWM1_OUT                                 0x1F0 0x458 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_SPDIF_EXT_CLK_GPIO5_IO5                                0x1F0 0x458 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SPDIF_EXT_CLK_TPSMP_HDATA7                             0x1F0 0x458 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_ECSPI1_SCLK_ECSPI1_SCLK                                0x1F4 0x45C 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_ECSPI1_SCLK_UART3_DCE_RX                               0x1F4 0x45C 0x504 0x1 0x0
+#define MX8MQ_IOMUXC_ECSPI1_SCLK_UART3_DTE_TX                               0x1F4 0x45C 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_ECSPI1_SCLK_GPIO5_IO6                                  0x1F4 0x45C 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_ECSPI1_SCLK_TPSMP_HDATA8                               0x1F4 0x45C 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_ECSPI1_MOSI_ECSPI1_MOSI                                0x1F8 0x460 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_ECSPI1_MOSI_UART3_DCE_TX                               0x1F8 0x460 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_ECSPI1_MOSI_UART3_DTE_RX                               0x1F8 0x460 0x504 0x1 0x1
+#define MX8MQ_IOMUXC_ECSPI1_MOSI_GPIO5_IO7                                  0x1F8 0x460 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_ECSPI1_MOSI_TPSMP_HDATA9                               0x1F8 0x460 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_ECSPI1_MISO_ECSPI1_MISO                                0x1FC 0x464 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_ECSPI1_MISO_UART3_DCE_CTS_B                            0x1FC 0x464 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_ECSPI1_MISO_UART3_DTE_RTS_B                            0x1FC 0x464 0x500 0x1 0x0
+#define MX8MQ_IOMUXC_ECSPI1_MISO_GPIO5_IO8                                  0x1FC 0x464 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_ECSPI1_MISO_TPSMP_HDATA10                              0x1FC 0x464 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_ECSPI1_SS0_ECSPI1_SS0                                  0x200 0x468 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_ECSPI1_SS0_UART3_DCE_RTS_B                             0x200 0x468 0x500 0x1 0x1
+#define MX8MQ_IOMUXC_ECSPI1_SS0_UART3_DTE_CTS_B                             0x200 0x468 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_ECSPI1_SS0_GPIO5_IO9                                   0x200 0x468 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_ECSPI1_SS0_TPSMP_HDATA11                               0x200 0x468 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_ECSPI2_SCLK_ECSPI2_SCLK                                0x204 0x46C 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_ECSPI2_SCLK_UART4_DCE_RX                               0x204 0x46C 0x50C 0x1 0x0
+#define MX8MQ_IOMUXC_ECSPI2_SCLK_UART4_DTE_TX                               0x204 0x46C 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_ECSPI2_SCLK_GPIO5_IO10                                 0x204 0x46C 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_ECSPI2_SCLK_TPSMP_HDATA12                              0x204 0x46C 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_ECSPI2_MOSI_ECSPI2_MOSI                                0x208 0x470 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_ECSPI2_MOSI_UART4_DCE_TX                               0x208 0x470 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_ECSPI2_MOSI_UART4_DTE_RX                               0x208 0x470 0x50C 0x1 0x1
+#define MX8MQ_IOMUXC_ECSPI2_MOSI_GPIO5_IO11                                 0x208 0x470 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_ECSPI2_MOSI_TPSMP_HDATA13                              0x208 0x470 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_ECSPI2_MISO_ECSPI2_MISO                                0x20C 0x474 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_ECSPI2_MISO_UART4_DCE_CTS_B                            0x20C 0x474 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_ECSPI2_MISO_UART4_DTE_RTS_B                            0x20C 0x474 0x508 0x1 0x0
+#define MX8MQ_IOMUXC_ECSPI2_MISO_GPIO5_IO12                                 0x20C 0x474 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_ECSPI2_MISO_TPSMP_HDATA14                              0x20C 0x474 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_ECSPI2_SS0_ECSPI2_SS0                                  0x210 0x478 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_ECSPI2_SS0_UART4_DCE_RTS_B                             0x210 0x478 0x508 0x1 0x1
+#define MX8MQ_IOMUXC_ECSPI2_SS0_UART4_DTE_CTS_B                             0x210 0x478 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_ECSPI2_SS0_GPIO5_IO13                                  0x210 0x478 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_ECSPI2_SS0_TPSMP_HDATA15                               0x210 0x478 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_I2C1_SCL_I2C1_SCL                                      0x214 0x47C 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_I2C1_SCL_ENET1_MDC                                     0x214 0x47C 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_I2C1_SCL_GPIO5_IO14                                    0x214 0x47C 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_I2C1_SCL_TPSMP_HDATA16                                 0x214 0x47C 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_I2C1_SDA_I2C1_SDA                                      0x218 0x480 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_I2C1_SDA_ENET1_MDIO                                    0x218 0x480 0x4C0 0x1 0x2
+#define MX8MQ_IOMUXC_I2C1_SDA_GPIO5_IO15                                    0x218 0x480 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_I2C1_SDA_TPSMP_HDATA17                                 0x218 0x480 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_I2C2_SCL_I2C2_SCL                                      0x21C 0x484 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_I2C2_SCL_ENET1_1588_EVENT1_IN                          0x21C 0x484 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_I2C2_SCL_GPIO5_IO16                                    0x21C 0x484 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_I2C2_SCL_TPSMP_HDATA18                                 0x21C 0x484 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_I2C2_SDA_I2C2_SDA                                      0x220 0x488 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_I2C2_SDA_ENET1_1588_EVENT1_OUT                         0x220 0x488 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_I2C2_SDA_GPIO5_IO17                                    0x220 0x488 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_I2C2_SDA_TPSMP_HDATA19                                 0x220 0x488 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_I2C3_SCL_I2C3_SCL                                      0x224 0x48C 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_I2C3_SCL_PWM4_OUT                                      0x224 0x48C 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_I2C3_SCL_GPT2_CLK                                      0x224 0x48C 0x000 0x2 0x0
+#define MX8MQ_IOMUXC_I2C3_SCL_GPIO5_IO18                                    0x224 0x48C 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_I2C3_SCL_TPSMP_HDATA20                                 0x224 0x48C 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_I2C3_SDA_I2C3_SDA                                      0x228 0x490 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_I2C3_SDA_PWM3_OUT                                      0x228 0x490 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_I2C3_SDA_GPT3_CLK                                      0x228 0x490 0x000 0x2 0x0
+#define MX8MQ_IOMUXC_I2C3_SDA_GPIO5_IO19                                    0x228 0x490 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_I2C3_SDA_TPSMP_HDATA21                                 0x228 0x490 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_I2C4_SCL_I2C4_SCL                                      0x22C 0x494 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_I2C4_SCL_PWM2_OUT                                      0x22C 0x494 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_I2C4_SCL_PCIE1_CLKREQ_B                                0x22C 0x494 0x524 0x2 0x0
+#define MX8MQ_IOMUXC_I2C4_SCL_GPIO5_IO20                                    0x22C 0x494 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_I2C4_SCL_TPSMP_HDATA22                                 0x22C 0x494 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_I2C4_SDA_I2C4_SDA                                      0x230 0x498 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_I2C4_SDA_PWM1_OUT                                      0x230 0x498 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_I2C4_SDA_PCIE2_CLKREQ_B                                0x230 0x498 0x528 0x2 0x0
+#define MX8MQ_IOMUXC_I2C4_SDA_GPIO5_IO21                                    0x230 0x498 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_I2C4_SDA_TPSMP_HDATA23                                 0x230 0x498 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_UART1_RXD_UART1_DCE_RX                                 0x234 0x49C 0x4F4 0x0 0x0
+#define MX8MQ_IOMUXC_UART1_RXD_UART1_DTE_TX                                 0x234 0x49C 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_UART1_RXD_ECSPI3_SCLK                                  0x234 0x49C 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_UART1_RXD_GPIO5_IO22                                   0x234 0x49C 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_UART1_RXD_TPSMP_HDATA24                                0x234 0x49C 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_UART1_TXD_UART1_DCE_TX                                 0x238 0x4A0 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_UART1_TXD_UART1_DTE_RX                                 0x238 0x4A0 0x4F4 0x0 0x0
+#define MX8MQ_IOMUXC_UART1_TXD_ECSPI3_MOSI                                  0x238 0x4A0 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_UART1_TXD_GPIO5_IO23                                   0x238 0x4A0 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_UART1_TXD_TPSMP_HDATA25                                0x238 0x4A0 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_UART2_RXD_UART2_DCE_RX                                 0x23C 0x4A4 0x4FC 0x0 0x0
+#define MX8MQ_IOMUXC_UART2_RXD_UART2_DTE_TX                                 0x23C 0x4A4 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_UART2_RXD_ECSPI3_MISO                                  0x23C 0x4A4 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_UART2_RXD_GPIO5_IO24                                   0x23C 0x4A4 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_UART2_RXD_TPSMP_HDATA26                                0x23C 0x4A4 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_UART2_TXD_UART2_DCE_TX                                 0x240 0x4A8 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_UART2_TXD_UART2_DTE_RX                                 0x240 0x4A8 0x4FC 0x0 0x1
+#define MX8MQ_IOMUXC_UART2_TXD_ECSPI3_SS0                                   0x240 0x4A8 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_UART2_TXD_GPIO5_IO25                                   0x240 0x4A8 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_UART2_TXD_TPSMP_HDATA27                                0x240 0x4A8 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_UART3_RXD_UART3_DCE_RX                                 0x244 0x4AC 0x504 0x0 0x2
+#define MX8MQ_IOMUXC_UART3_RXD_UART3_DTE_TX                                 0x244 0x4AC 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_UART3_RXD_UART1_DCE_CTS_B                              0x244 0x4AC 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_UART3_RXD_UART1_DTE_RTS_B                              0x244 0x4AC 0x4F0 0x1 0x0
+#define MX8MQ_IOMUXC_UART3_RXD_GPIO5_IO26                                   0x244 0x4AC 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_UART3_RXD_TPSMP_HDATA28                                0x244 0x4AC 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_UART3_TXD_UART3_DCE_TX                                 0x248 0x4B0 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_UART3_TXD_UART3_DTE_RX                                 0x248 0x4B0 0x504 0x0 0x3
+#define MX8MQ_IOMUXC_UART3_TXD_UART1_DCE_RTS_B                              0x248 0x4B0 0x4F0 0x1 0x1
+#define MX8MQ_IOMUXC_UART3_TXD_UART1_DTE_CTS_B                              0x248 0x4B0 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_UART3_TXD_GPIO5_IO27                                   0x248 0x4B0 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_UART3_TXD_TPSMP_HDATA29                                0x248 0x4B0 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_UART4_RXD_UART4_DCE_RX                                 0x24C 0x4B4 0x50C 0x0 0x2
+#define MX8MQ_IOMUXC_UART4_RXD_UART4_DTE_TX                                 0x24C 0x4B4 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_UART4_RXD_UART2_DCE_CTS_B                              0x24C 0x4B4 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_UART4_RXD_UART2_DTE_RTS_B                              0x24C 0x4B4 0x4F8 0x1 0x0
+#define MX8MQ_IOMUXC_UART4_RXD_PCIE1_CLKREQ_B                               0x24C 0x4B4 0x524 0x2 0x1
+#define MX8MQ_IOMUXC_UART4_RXD_GPIO5_IO28                                   0x24C 0x4B4 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_UART4_RXD_TPSMP_HDATA30                                0x24C 0x4B4 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_UART4_TXD_UART4_DCE_TX                                 0x250 0x4B8 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_UART4_TXD_UART4_DTE_RX                                 0x250 0x4B8 0x50C 0x0 0x3
+#define MX8MQ_IOMUXC_UART4_TXD_UART2_DCE_RTS_B                              0x250 0x4B8 0x4F8 0x1 0x1
+#define MX8MQ_IOMUXC_UART4_TXD_UART2_DTE_CTS_B                              0x250 0x4B8 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_UART4_TXD_PCIE2_CLKREQ_B                               0x250 0x4B8 0x528 0x2 0x1
+#define MX8MQ_IOMUXC_UART4_TXD_GPIO5_IO29                                   0x250 0x4B8 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_UART4_TXD_TPSMP_HDATA31                                0x250 0x4B8 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_TEST_MODE                                              0x000 0x254 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_BOOT_MODE0                                             0x000 0x258 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_BOOT_MODE1                                             0x000 0x25C 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_JTAG_MOD                                               0x000 0x260 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_JTAG_TRST_B                                            0x000 0x264 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_JTAG_TDI                                               0x000 0x268 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_JTAG_TMS                                               0x000 0x26C 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_JTAG_TCK                                               0x000 0x270 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_JTAG_TDO                                               0x000 0x274 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_RTC                                                    0x000 0x278 0x000 0x0 0x0
+
+#endif /* __DTS_IMX8MQ_PINFUNC_H */
diff --git a/arch/arm64/boot/dts/freescale/imx8mq.dtsi b/arch/arm64/boot/dts/freescale/imx8mq.dtsi
new file mode 100644
index 0000000..3703bca
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx8mq.dtsi
@@ -0,0 +1,392 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright 2017 NXP
+ * Copyright (C) 2017-2018 Pengutronix, Lucas Stach <kernel@pengutronix.de>
+ */
+
+#include <dt-bindings/clock/imx8mq-clock.h>
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include "imx8mq-pinfunc.h"
+
+/ {
+	/* This should really be the GPC, but we need a driver for this first */
+	interrupt-parent = <&gic>;
+
+	#address-cells = <2>;
+	#size-cells = <2>;
+
+	aliases {
+		i2c0 = &i2c1;
+		i2c1 = &i2c2;
+		i2c2 = &i2c3;
+		i2c3 = &i2c4;
+		serial0 = &uart1;
+		serial1 = &uart2;
+		serial2 = &uart3;
+		serial3 = &uart4;
+	};
+
+	ckil: clock-ckil {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <32768>;
+		clock-output-names = "ckil";
+	};
+
+	osc_25m: clock-osc-25m {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <25000000>;
+		clock-output-names = "osc_25m";
+	};
+
+	osc_27m: clock-osc-27m {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <27000000>;
+		clock-output-names = "osc_27m";
+	};
+
+	clk_ext1: clock-ext1 {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <133000000>;
+		clock-output-names = "clk_ext1";
+	};
+
+	clk_ext2: clock-ext2 {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <133000000>;
+		clock-output-names = "clk_ext2";
+	};
+
+	clk_ext3: clock-ext3 {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <133000000>;
+		clock-output-names = "clk_ext3";
+	};
+
+	clk_ext4: clock-ext4 {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency= <133000000>;
+		clock-output-names = "clk_ext4";
+	};
+
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		A53_0: cpu@0 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a53";
+			reg = <0x0>;
+			enable-method = "psci";
+			next-level-cache = <&A53_L2>;
+		};
+
+		A53_1: cpu@1 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a53";
+			reg = <0x1>;
+			enable-method = "psci";
+			next-level-cache = <&A53_L2>;
+		};
+
+		A53_2: cpu@2 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a53";
+			reg = <0x2>;
+			enable-method = "psci";
+			next-level-cache = <&A53_L2>;
+		};
+
+		A53_3: cpu@3 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a53";
+			reg = <0x3>;
+			enable-method = "psci";
+			next-level-cache = <&A53_L2>;
+		};
+
+		A53_L2: l2-cache0 {
+			compatible = "cache";
+		};
+	};
+
+	psci {
+		compatible = "arm,psci-1.0";
+		method = "smc";
+	};
+
+	timer {
+		compatible = "arm,armv8-timer";
+		interrupts = <GIC_PPI 13 IRQ_TYPE_LEVEL_LOW>, /* Physical Secure */
+		             <GIC_PPI 14 IRQ_TYPE_LEVEL_LOW>, /* Physical Non-Secure */
+		             <GIC_PPI 11 IRQ_TYPE_LEVEL_LOW>, /* Virtual */
+		             <GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>; /* Hypervisor */
+		interrupt-parent = <&gic>;
+		arm,no-tick-in-suspend;
+	};
+
+	soc@0 {
+		compatible = "simple-bus";
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ranges = <0x0 0x0 0x0 0x3e000000>;
+
+		bus@30000000 { /* AIPS1 */
+			compatible = "fsl,imx8mq-aips-bus", "simple-bus";
+			#address-cells = <1>;
+			#size-cells = <1>;
+			ranges = <0x30000000 0x30000000 0x400000>;
+
+			gpio1: gpio@30200000 {
+				compatible = "fsl,imx8mq-gpio", "fsl,imx35-gpio";
+				reg = <0x30200000 0x10000>;
+				interrupts = <GIC_SPI 64 IRQ_TYPE_LEVEL_HIGH>,
+				             <GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>;
+				gpio-controller;
+				#gpio-cells = <2>;
+				interrupt-controller;
+				#interrupt-cells = <2>;
+			};
+
+			gpio2: gpio@30210000 {
+				compatible = "fsl,imx8mq-gpio", "fsl,imx35-gpio";
+				reg = <0x30210000 0x10000>;
+				interrupts = <GIC_SPI 66 IRQ_TYPE_LEVEL_HIGH>,
+				             <GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>;
+				gpio-controller;
+				#gpio-cells = <2>;
+				interrupt-controller;
+				#interrupt-cells = <2>;
+			};
+
+			gpio3: gpio@30220000 {
+				compatible = "fsl,imx8mq-gpio", "fsl,imx35-gpio";
+				reg = <0x30220000 0x10000>;
+				interrupts = <GIC_SPI 68 IRQ_TYPE_LEVEL_HIGH>,
+				             <GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH>;
+				gpio-controller;
+				#gpio-cells = <2>;
+				interrupt-controller;
+				#interrupt-cells = <2>;
+			};
+
+			gpio4: gpio@30230000 {
+				compatible = "fsl,imx8mq-gpio", "fsl,imx35-gpio";
+				reg = <0x30230000 0x10000>;
+				interrupts = <GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH>,
+				             <GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH>;
+				gpio-controller;
+				#gpio-cells = <2>;
+				interrupt-controller;
+				#interrupt-cells = <2>;
+			};
+
+			gpio5: gpio@30240000 {
+				compatible = "fsl,imx8mq-gpio", "fsl,imx35-gpio";
+				reg = <0x30240000 0x10000>;
+				interrupts = <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>,
+				             <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>;
+				gpio-controller;
+				#gpio-cells = <2>;
+				interrupt-controller;
+				#interrupt-cells = <2>;
+			};
+
+			iomuxc: iomuxc@30330000 {
+				compatible = "fsl,imx8mq-iomuxc";
+				reg = <0x30330000 0x10000>;
+			};
+
+			iomuxc_gpr: syscon@30340000 {
+				compatible = "fsl,imx8mq-iomuxc-gpr", "syscon";
+				reg = <0x30340000 0x10000>;
+			};
+
+			anatop: syscon@30360000 {
+				compatible = "fsl,imx8mq-anatop", "syscon";
+				reg = <0x30360000 0x10000>;
+				interrupts = <GIC_SPI 49 IRQ_TYPE_LEVEL_HIGH>;
+			};
+
+			clk: clock-controller@30380000 {
+				compatible = "fsl,imx8mq-ccm";
+				reg = <0x30380000 0x10000>;
+				interrupts = <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>,
+				             <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>;
+				#clock-cells = <1>;
+				clocks = <&ckil>, <&osc_25m>, <&osc_27m>,
+				         <&clk_ext1>, <&clk_ext2>,
+				         <&clk_ext3>, <&clk_ext4>;
+				clock-names = "ckil", "osc_25m", "osc_27m",
+				              "clk_ext1", "clk_ext2",
+				              "clk_ext3", "clk_ext4";
+			};
+		};
+
+		bus@30400000 { /* AIPS2 */
+			compatible = "fsl,imx8mq-aips-bus", "simple-bus";
+			#address-cells = <1>;
+			#size-cells = <1>;
+			ranges = <0x30400000 0x30400000 0x400000>;
+		};
+
+		bus@30800000 { /* AIPS3 */
+			compatible = "fsl,imx8mq-aips-bus", "simple-bus";
+			#address-cells = <1>;
+			#size-cells = <1>;
+			ranges = <0x30800000 0x30800000 0x400000>;
+
+			uart1: serial@30860000 {
+				compatible = "fsl,imx8mq-uart",
+				             "fsl,imx6q-uart";
+				reg = <0x30860000 0x10000>;
+				interrupts = <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&clk IMX8MQ_CLK_UART1_ROOT>,
+				         <&clk IMX8MQ_CLK_UART1_ROOT>;
+				clock-names = "ipg", "per";
+				status = "disabled";
+			};
+
+			uart3: serial@30880000 {
+				compatible = "fsl,imx8mq-uart",
+				             "fsl,imx6q-uart";
+				reg = <0x30880000 0x10000>;
+				interrupts = <GIC_SPI 28 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&clk IMX8MQ_CLK_UART3_ROOT>,
+				         <&clk IMX8MQ_CLK_UART3_ROOT>;
+				clock-names = "ipg", "per";
+				status = "disabled";
+			};
+
+			uart2: serial@30890000 {
+				compatible = "fsl,imx8mq-uart",
+				             "fsl,imx6q-uart";
+				reg = <0x30890000 0x10000>;
+				interrupts = <GIC_SPI 27 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&clk IMX8MQ_CLK_UART2_ROOT>,
+				         <&clk IMX8MQ_CLK_UART2_ROOT>;
+				clock-names = "ipg", "per";
+				status = "disabled";
+			};
+
+			i2c1: i2c@30a20000 {
+				compatible = "fsl,imx8mq-i2c", "fsl,imx21-i2c";
+				reg = <0x30a20000 0x10000>;
+				interrupts = <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&clk IMX8MQ_CLK_I2C1_ROOT>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+				status = "disabled";
+			};
+
+			i2c2: i2c@30a30000 {
+				compatible = "fsl,imx8mq-i2c", "fsl,imx21-i2c";
+				reg = <0x30a30000 0x10000>;
+				interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&clk IMX8MQ_CLK_I2C2_ROOT>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+				status = "disabled";
+			};
+
+			i2c3: i2c@30a40000 {
+				compatible = "fsl,imx8mq-i2c", "fsl,imx21-i2c";
+				reg = <0x30a40000 0x10000>;
+				interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&clk IMX8MQ_CLK_I2C3_ROOT>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+				status = "disabled";
+			};
+
+			i2c4: i2c@30a50000 {
+				compatible = "fsl,imx8mq-i2c", "fsl,imx21-i2c";
+				reg = <0x30a50000 0x10000>;
+				interrupts = <GIC_SPI 38 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&clk IMX8MQ_CLK_I2C4_ROOT>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+				status = "disabled";
+			};
+
+			uart4: serial@30a60000 {
+				compatible = "fsl,imx8mq-uart",
+				             "fsl,imx6q-uart";
+				reg = <0x30a60000 0x10000>;
+				interrupts = <GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&clk IMX8MQ_CLK_UART4_ROOT>,
+				         <&clk IMX8MQ_CLK_UART4_ROOT>;
+				clock-names = "ipg", "per";
+				status = "disabled";
+			};
+
+			usdhc1: mmc@30b40000 {
+				compatible = "fsl,imx8mq-usdhc",
+				             "fsl,imx7d-usdhc";
+				reg = <0x30b40000 0x10000>;
+				interrupts = <GIC_SPI 22 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&clk IMX8MQ_CLK_DUMMY>,
+				         <&clk IMX8MQ_CLK_NAND_USDHC_BUS>,
+				         <&clk IMX8MQ_CLK_USDHC1_ROOT>;
+				clock-names = "ipg", "ahb", "per";
+				fsl,tuning-start-tap = <20>;
+				fsl,tuning-step = <2>;
+				bus-width = <4>;
+				status = "disabled";
+			};
+
+			usdhc2: mmc@30b50000 {
+				compatible = "fsl,imx8mq-usdhc",
+				             "fsl,imx7d-usdhc";
+				reg = <0x30b50000 0x10000>;
+				interrupts = <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&clk IMX8MQ_CLK_DUMMY>,
+				         <&clk IMX8MQ_CLK_NAND_USDHC_BUS>,
+				         <&clk IMX8MQ_CLK_USDHC2_ROOT>;
+				clock-names = "ipg", "ahb", "per";
+				fsl,tuning-start-tap = <20>;
+				fsl,tuning-step = <2>;
+				bus-width = <4>;
+				status = "disabled";
+			};
+
+			fec1: ethernet@30be0000 {
+				compatible = "fsl,imx8mq-fec", "fsl,imx6sx-fec";
+				reg = <0x30be0000 0x10000>;
+				interrupts = <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>,
+				             <GIC_SPI 119 IRQ_TYPE_LEVEL_HIGH>,
+				             <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&clk IMX8MQ_CLK_ENET1_ROOT>,
+				         <&clk IMX8MQ_CLK_ENET1_ROOT>,
+				         <&clk IMX8MQ_CLK_ENET_TIMER>,
+				         <&clk IMX8MQ_CLK_ENET_REF>,
+				         <&clk IMX8MQ_CLK_ENET_PHY_REF>;
+				clock-names = "ipg", "ahb", "ptp",
+				              "enet_clk_ref", "enet_out";
+				fsl,num-tx-queues = <3>;
+				fsl,num-rx-queues = <3>;
+				status = "disabled";
+			};
+		};
+
+		gic: interrupt-controller@38800000 {
+			compatible = "arm,gic-v3";
+			reg = <0x38800000 0x10000>,	/* GIC Dist */
+			      <0x38880000 0xc0000>,	/* GICR */
+			      <0x31000000 0x2000>,	/* GICC */
+			      <0x31010000 0x2000>,	/* GICV */
+			      <0x31020000 0x2000>;	/* GICH */
+			#interrupt-cells = <3>;
+			interrupt-controller;
+			interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-parent = <&gic>;
+		};
+	};
+};
-- 
2.7.4


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

^ permalink raw reply related

* [PATCH v5 4/6] MAINTAINERS: add i.MX8 DT path to i.MX architecture
From: Abel Vesa @ 2018-12-09 14:26 UTC (permalink / raw)
  To: Lucas Stach, linux-arm-kernel@lists.infradead.org, Shawn Guo,
	Rob Herring
  Cc: Aisheng Dong, devicetree@vger.kernel.org, Abel Vesa,
	Linux Kernel Mailing List, patchwork-lst@pengutronix.de,
	Abel Vesa, dl-linux-imx, Pengutronix Kernel Team, Fabio Estevam
In-Reply-To: <1544365552-30270-1-git-send-email-abel.vesa@nxp.com>

From: Lucas Stach <l.stach@pengutronix.de>

Shawn agreed to take patches for the i.MX8 parts through his tree.

Signed-off-by: Lucas Stach <l.stach@pengutronix.de>
Reviewed-by: Dong Aisheng <aisheng.dong@nxp.com>
---
 MAINTAINERS | 1 +
 1 file changed, 1 insertion(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 3625a8d..b41ebff 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1530,6 +1530,7 @@ F:	arch/arm/mach-imx/
 F:	arch/arm/mach-mxs/
 F:	arch/arm/boot/dts/imx*
 F:	arch/arm/configs/imx*_defconfig
+F:	arch/arm64/boot/dts/freescale/imx*
 F:	drivers/clk/imx/
 F:	drivers/firmware/imx/
 F:	drivers/soc/imx/
-- 
2.7.4


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

^ permalink raw reply related

* [PATCH v5 3/6] arm64: add support for i.MX8M EVK board
From: Abel Vesa @ 2018-12-09 14:26 UTC (permalink / raw)
  To: Lucas Stach, linux-arm-kernel@lists.infradead.org, Shawn Guo,
	Rob Herring
  Cc: Aisheng Dong, devicetree@vger.kernel.org, Abel Vesa,
	Linux Kernel Mailing List, patchwork-lst@pengutronix.de,
	Abel Vesa, dl-linux-imx, Pengutronix Kernel Team, Fabio Estevam
In-Reply-To: <1544365552-30270-1-git-send-email-abel.vesa@nxp.com>

From: Lucas Stach <l.stach@pengutronix.de>

This is the evaluation kit board for the i.MX8M. The current level of
support yields a working console and is able to boot userspace from
SD card or Network.

Signed-off-by: Lucas Stach <l.stach@pengutronix.de>
Reviewed-by: Fabio Estevam <fabio.estevam@nxp.com> (v1)
Reviewed-by: Rob Herring <robh@kernel.org> (v3)
Tested-by: Tested-by: Baruch Siach <baruch@tkos.co.il> (v1)
Reviewed-by: Dong Aisheng <aisheng.dong@nxp.com>
---
 Documentation/devicetree/bindings/arm/fsl.txt |   4 +
 arch/arm64/boot/dts/freescale/Makefile        |   2 +
 arch/arm64/boot/dts/freescale/imx8mq-evk.dts  | 290 ++++++++++++++++++++++++++
 3 files changed, 296 insertions(+)
 create mode 100644 arch/arm64/boot/dts/freescale/imx8mq-evk.dts

diff --git a/Documentation/devicetree/bindings/arm/fsl.txt b/Documentation/devicetree/bindings/arm/fsl.txt
index 9f4aba2..71b78ff 100644
--- a/Documentation/devicetree/bindings/arm/fsl.txt
+++ b/Documentation/devicetree/bindings/arm/fsl.txt
@@ -105,6 +105,10 @@ i.MX7ULP Evaluation Kit
 Required root node properties:
     - compatible = "fsl,imx7ulp-evk", "fsl,imx7ulp";
 
+i.MX8MQ Evaluation Kit
+Required root node properties:
+    - compatible = "fsl,imx8mq-evk", "fsl,imx8mq";
+
 Generic i.MX boards
 -------------------
 
diff --git a/arch/arm64/boot/dts/freescale/Makefile b/arch/arm64/boot/dts/freescale/Makefile
index 7748e6d..0001361 100644
--- a/arch/arm64/boot/dts/freescale/Makefile
+++ b/arch/arm64/boot/dts/freescale/Makefile
@@ -18,3 +18,5 @@ dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls2088a-qds.dtb
 dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls2088a-rdb.dtb
 dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-lx2160a-qds.dtb
 dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-lx2160a-rdb.dtb
+
+dtb-$(CONFIG_SOC_IMX8MQ) += imx8mq-evk.dtb
diff --git a/arch/arm64/boot/dts/freescale/imx8mq-evk.dts b/arch/arm64/boot/dts/freescale/imx8mq-evk.dts
new file mode 100644
index 0000000..04ce13f
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx8mq-evk.dts
@@ -0,0 +1,290 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/*
+ * Copyright 2017 NXP
+ * Copyright (C) 2017-2018 Pengutronix, Lucas Stach <kernel@pengutronix.de>
+ */
+
+/dts-v1/;
+
+#include "imx8mq.dtsi"
+
+/ {
+	model = "NXP i.MX8MQ EVK";
+	compatible = "fsl,imx8mq-evk", "fsl,imx8mq";
+
+	chosen {
+		stdout-path = &uart1;
+	};
+
+	memory@40000000 {
+		device_type = "memory";
+		reg = <0x00000000 0x40000000 0 0xc0000000>;
+	};
+
+	reg_usdhc2_vmmc: regulator-vsd-3v3 {
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_reg_usdhc2>;
+		compatible = "regulator-fixed";
+		regulator-name = "VSD_3V3";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		gpio = <&gpio2 19 GPIO_ACTIVE_HIGH>;
+		enable-active-high;
+	};
+};
+
+&fec1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_fec1>;
+	phy-mode = "rgmii-id";
+	status = "okay";
+};
+
+&i2c1 {
+	clock-frequency = <100000>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_i2c1>;
+	status = "okay";
+
+	pmic@8 {
+		compatible = "fsl,pfuze100";
+		reg = <0x8>;
+
+		regulators {
+			sw1a_reg: sw1ab {
+				regulator-min-microvolt = <825000>;
+				regulator-max-microvolt = <1100000>;
+			};
+
+			sw1c_reg: sw1c {
+				regulator-min-microvolt = <825000>;
+				regulator-max-microvolt = <1100000>;
+			};
+
+			sw2_reg: sw2 {
+				regulator-min-microvolt = <1100000>;
+				regulator-max-microvolt = <1100000>;
+				regulator-always-on;
+			};
+
+			sw3a_reg: sw3ab {
+				regulator-min-microvolt = <825000>;
+				regulator-max-microvolt = <1100000>;
+				regulator-always-on;
+			};
+
+			sw4_reg: sw4 {
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+				regulator-always-on;
+			};
+
+			swbst_reg: swbst {
+				regulator-min-microvolt = <5000000>;
+				regulator-max-microvolt = <5150000>;
+			};
+
+			snvs_reg: vsnvs {
+				regulator-min-microvolt = <1000000>;
+				regulator-max-microvolt = <3000000>;
+				regulator-always-on;
+			};
+
+			vref_reg: vrefddr {
+				regulator-always-on;
+			};
+
+			vgen1_reg: vgen1 {
+				regulator-min-microvolt = <800000>;
+				regulator-max-microvolt = <1550000>;
+			};
+
+			vgen2_reg: vgen2 {
+				regulator-min-microvolt = <850000>;
+				regulator-max-microvolt = <975000>;
+				regulator-always-on;
+			};
+
+			vgen3_reg: vgen3 {
+				regulator-min-microvolt = <1675000>;
+				regulator-max-microvolt = <1975000>;
+				regulator-always-on;
+			};
+
+			vgen4_reg: vgen4 {
+				regulator-min-microvolt = <1625000>;
+				regulator-max-microvolt = <1875000>;
+				regulator-always-on;
+			};
+
+			vgen5_reg: vgen5 {
+				regulator-min-microvolt = <3075000>;
+				regulator-max-microvolt = <3625000>;
+				regulator-always-on;
+			};
+
+			vgen6_reg: vgen6 {
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <3300000>;
+			};
+		};
+	};
+};
+
+&uart1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_uart1>;
+	status = "okay";
+};
+
+&usdhc1 {
+	pinctrl-names = "default", "state_100mhz", "state_200mhz";
+	pinctrl-0 = <&pinctrl_usdhc1>;
+	pinctrl-1 = <&pinctrl_usdhc1_100mhz>;
+	pinctrl-2 = <&pinctrl_usdhc1_200mhz>;
+	vqmmc-supply = <&sw4_reg>;
+	bus-width = <8>;
+	non-removable;
+	no-sd;
+	no-sdio;
+	status = "okay";
+};
+
+&usdhc2 {
+	pinctrl-names = "default", "state_100mhz", "state_200mhz";
+	pinctrl-0 = <&pinctrl_usdhc2>;
+	pinctrl-1 = <&pinctrl_usdhc2_100mhz>;
+	pinctrl-2 = <&pinctrl_usdhc2_200mhz>;
+	cd-gpios = <&gpio2 12 GPIO_ACTIVE_LOW>;
+	vmmc-supply = <&reg_usdhc2_vmmc>;
+	status = "okay";
+};
+
+&iomuxc {
+	pinctrl_fec1: fec1grp {
+		fsl,pins = <
+			MX8MQ_IOMUXC_ENET_MDC_ENET1_MDC			0x3
+			MX8MQ_IOMUXC_ENET_MDIO_ENET1_MDIO		0x23
+			MX8MQ_IOMUXC_ENET_TD3_ENET1_RGMII_TD3		0x1f
+			MX8MQ_IOMUXC_ENET_TD2_ENET1_RGMII_TD2		0x1f
+			MX8MQ_IOMUXC_ENET_TD1_ENET1_RGMII_TD1		0x1f
+			MX8MQ_IOMUXC_ENET_TD0_ENET1_RGMII_TD0		0x1f
+			MX8MQ_IOMUXC_ENET_RD3_ENET1_RGMII_RD3		0x91
+			MX8MQ_IOMUXC_ENET_RD2_ENET1_RGMII_RD2		0x91
+			MX8MQ_IOMUXC_ENET_RD1_ENET1_RGMII_RD1		0x91
+			MX8MQ_IOMUXC_ENET_RD0_ENET1_RGMII_RD0		0x91
+			MX8MQ_IOMUXC_ENET_TXC_ENET1_RGMII_TXC		0x1f
+			MX8MQ_IOMUXC_ENET_RXC_ENET1_RGMII_RXC		0x91
+			MX8MQ_IOMUXC_ENET_RX_CTL_ENET1_RGMII_RX_CTL	0x91
+			MX8MQ_IOMUXC_ENET_TX_CTL_ENET1_RGMII_TX_CTL	0x1f
+			MX8MQ_IOMUXC_GPIO1_IO09_GPIO1_IO9		0x19
+		>;
+	};
+
+	pinctrl_i2c1: i2c1grp {
+		fsl,pins = <
+			MX8MQ_IOMUXC_I2C1_SCL_I2C1_SCL			0x4000007f
+			MX8MQ_IOMUXC_I2C1_SDA_I2C1_SDA			0x4000007f
+		>;
+	};
+
+	pinctrl_reg_usdhc2: regusdhc2grpgpio {
+		fsl,pins = <
+			MX8MQ_IOMUXC_SD2_RESET_B_GPIO2_IO19		0x41
+		>;
+	};
+
+	pinctrl_uart1: uart1grp {
+		fsl,pins = <
+			MX8MQ_IOMUXC_UART1_RXD_UART1_DCE_RX		0x49
+			MX8MQ_IOMUXC_UART1_TXD_UART1_DCE_TX		0x49
+		>;
+	};
+
+	pinctrl_usdhc1: usdhc1grp {
+		fsl,pins = <
+			MX8MQ_IOMUXC_SD1_CLK_USDHC1_CLK			0x83
+			MX8MQ_IOMUXC_SD1_CMD_USDHC1_CMD			0xc3
+			MX8MQ_IOMUXC_SD1_DATA0_USDHC1_DATA0		0xc3
+			MX8MQ_IOMUXC_SD1_DATA1_USDHC1_DATA1		0xc3
+			MX8MQ_IOMUXC_SD1_DATA2_USDHC1_DATA2		0xc3
+			MX8MQ_IOMUXC_SD1_DATA3_USDHC1_DATA3		0xc3
+			MX8MQ_IOMUXC_SD1_DATA4_USDHC1_DATA4		0xc3
+			MX8MQ_IOMUXC_SD1_DATA5_USDHC1_DATA5		0xc3
+			MX8MQ_IOMUXC_SD1_DATA6_USDHC1_DATA6		0xc3
+			MX8MQ_IOMUXC_SD1_DATA7_USDHC1_DATA7		0xc3
+			MX8MQ_IOMUXC_SD1_STROBE_USDHC1_STROBE		0x83
+			MX8MQ_IOMUXC_SD1_RESET_B_USDHC1_RESET_B		0xc1
+		>;
+	};
+
+	pinctrl_usdhc1_100mhz: usdhc1-100grp {
+		fsl,pins = <
+			MX8MQ_IOMUXC_SD1_CLK_USDHC1_CLK			0x85
+			MX8MQ_IOMUXC_SD1_CMD_USDHC1_CMD			0xc5
+			MX8MQ_IOMUXC_SD1_DATA0_USDHC1_DATA0		0xc5
+			MX8MQ_IOMUXC_SD1_DATA1_USDHC1_DATA1		0xc5
+			MX8MQ_IOMUXC_SD1_DATA2_USDHC1_DATA2		0xc5
+			MX8MQ_IOMUXC_SD1_DATA3_USDHC1_DATA3		0xc5
+			MX8MQ_IOMUXC_SD1_DATA4_USDHC1_DATA4		0xc5
+			MX8MQ_IOMUXC_SD1_DATA5_USDHC1_DATA5		0xc5
+			MX8MQ_IOMUXC_SD1_DATA6_USDHC1_DATA6		0xc5
+			MX8MQ_IOMUXC_SD1_DATA7_USDHC1_DATA7		0xc5
+			MX8MQ_IOMUXC_SD1_STROBE_USDHC1_STROBE		0x85
+			MX8MQ_IOMUXC_SD1_RESET_B_USDHC1_RESET_B		0xc1
+		>;
+	};
+
+	pinctrl_usdhc1_200mhz: usdhc1-200grp {
+		fsl,pins = <
+			MX8MQ_IOMUXC_SD1_CLK_USDHC1_CLK			0x87
+			MX8MQ_IOMUXC_SD1_CMD_USDHC1_CMD			0xc7
+			MX8MQ_IOMUXC_SD1_DATA0_USDHC1_DATA0		0xc7
+			MX8MQ_IOMUXC_SD1_DATA1_USDHC1_DATA1		0xc7
+			MX8MQ_IOMUXC_SD1_DATA2_USDHC1_DATA2		0xc7
+			MX8MQ_IOMUXC_SD1_DATA3_USDHC1_DATA3		0xc7
+			MX8MQ_IOMUXC_SD1_DATA4_USDHC1_DATA4		0xc7
+			MX8MQ_IOMUXC_SD1_DATA5_USDHC1_DATA5		0xc7
+			MX8MQ_IOMUXC_SD1_DATA6_USDHC1_DATA6		0xc7
+			MX8MQ_IOMUXC_SD1_DATA7_USDHC1_DATA7		0xc7
+			MX8MQ_IOMUXC_SD1_STROBE_USDHC1_STROBE		0x87
+			MX8MQ_IOMUXC_SD1_RESET_B_USDHC1_RESET_B		0xc1
+		>;
+	};
+
+	pinctrl_usdhc2: usdhc2grp {
+		fsl,pins = <
+			MX8MQ_IOMUXC_SD2_CLK_USDHC2_CLK			0x83
+			MX8MQ_IOMUXC_SD2_CMD_USDHC2_CMD			0xc3
+			MX8MQ_IOMUXC_SD2_DATA0_USDHC2_DATA0		0xc3
+			MX8MQ_IOMUXC_SD2_DATA1_USDHC2_DATA1		0xc3
+			MX8MQ_IOMUXC_SD2_DATA2_USDHC2_DATA2		0xc3
+			MX8MQ_IOMUXC_SD2_DATA3_USDHC2_DATA3		0xc3
+			MX8MQ_IOMUXC_GPIO1_IO04_USDHC2_VSELECT		0xc1
+		>;
+	};
+
+	pinctrl_usdhc2_100mhz: usdhc2-100grp {
+		fsl,pins = <
+			MX8MQ_IOMUXC_SD2_CLK_USDHC2_CLK			0x85
+			MX8MQ_IOMUXC_SD2_CMD_USDHC2_CMD			0xc5
+			MX8MQ_IOMUXC_SD2_DATA0_USDHC2_DATA0		0xc5
+			MX8MQ_IOMUXC_SD2_DATA1_USDHC2_DATA1		0xc5
+			MX8MQ_IOMUXC_SD2_DATA2_USDHC2_DATA2		0xc5
+			MX8MQ_IOMUXC_SD2_DATA3_USDHC2_DATA3		0xc5
+			MX8MQ_IOMUXC_GPIO1_IO04_USDHC2_VSELECT		0xc1
+		>;
+	};
+
+	pinctrl_usdhc2_200mhz: usdhc2-200grp {
+		fsl,pins = <
+			MX8MQ_IOMUXC_SD2_CLK_USDHC2_CLK			0x87
+			MX8MQ_IOMUXC_SD2_CMD_USDHC2_CMD			0xc7
+			MX8MQ_IOMUXC_SD2_DATA0_USDHC2_DATA0		0xc7
+			MX8MQ_IOMUXC_SD2_DATA1_USDHC2_DATA1		0xc7
+			MX8MQ_IOMUXC_SD2_DATA2_USDHC2_DATA2		0xc7
+			MX8MQ_IOMUXC_SD2_DATA3_USDHC2_DATA3		0xc7
+			MX8MQ_IOMUXC_GPIO1_IO04_USDHC2_VSELECT		0xc1
+		>;
+	};
+};
-- 
2.7.4


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

^ permalink raw reply related

* [PATCH v5 1/6] arm64: add basic Kconfig symbols for i.MX8
From: Abel Vesa @ 2018-12-09 14:26 UTC (permalink / raw)
  To: Lucas Stach, linux-arm-kernel@lists.infradead.org, Shawn Guo,
	Rob Herring
  Cc: Aisheng Dong, devicetree@vger.kernel.org, Abel Vesa,
	Linux Kernel Mailing List, patchwork-lst@pengutronix.de,
	Abel Vesa, dl-linux-imx, Pengutronix Kernel Team, Fabio Estevam
In-Reply-To: <1544365552-30270-1-git-send-email-abel.vesa@nxp.com>

From: Lucas Stach <l.stach@pengutronix.de>

Add basic Kconfig symbols to make the MXC architecture available
in the ARM64 world.

Signed-off-by: Lucas Stach <l.stach@pengutronix.de>
Reviewed-by: Fabio Estevam <fabio.estevam@nxp.com>
---
 arch/arm64/Kconfig.platforms | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/arch/arm64/Kconfig.platforms b/arch/arm64/Kconfig.platforms
index 28f0521..7e1545a 100644
--- a/arch/arm64/Kconfig.platforms
+++ b/arch/arm64/Kconfig.platforms
@@ -142,6 +142,20 @@ config ARCH_MVEBU
 	   - Armada 7K SoC Family
 	   - Armada 8K SoC Family
 
+config ARCH_MXC
+	bool "ARMv8 based NXP i.MX SoC family"
+	help
+	  This enables support for the ARMv8 based SoCs in the
+	  NXP i.MX family.
+
+config SOC_IMX8MQ
+	bool "i.MX8MQ support"
+	depends on ARCH_MXC
+	select ARM64_ERRATUM_843419
+	select ARM64_ERRATUM_845719
+	help
+	  This enables support for the i.MX8MQ SoC.
+
 config ARCH_QCOM
 	bool "Qualcomm Platforms"
 	select GPIOLIB
-- 
2.7.4


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

^ permalink raw reply related

* [PATCH v5 0/6] Add basic support for i.MX8MQ SoC and i.MX8MQ EVK board
From: Abel Vesa @ 2018-12-09 14:26 UTC (permalink / raw)
  To: Lucas Stach, linux-arm-kernel@lists.infradead.org, Shawn Guo,
	Rob Herring
  Cc: Aisheng Dong, devicetree@vger.kernel.org, Abel Vesa,
	Linux Kernel Mailing List, patchwork-lst@pengutronix.de,
	Abel Vesa, dl-linux-imx, Pengutronix Kernel Team, Fabio Estevam

Took this from Lucas since he's busy with some other work for the moment and
I thought we might be able to get this ready for the merge window.

Basically is just a respin with a minor fix for a comment from Rob.

Lucas, thanks for all the effort with this.

Changes since v5:
 * replaced the name of the node peripherals with soc in dts file

Baruch Siach (2):
  arm64: dts: imx8mq: add watchdog devices
  arm64: dts: imx8mq-evk: enable watchdog

Lucas Stach (4):
  arm64: add basic Kconfig symbols for i.MX8
  arm64: add basic DTS for i.MX8MQ
  arm64: add support for i.MX8M EVK board
  MAINTAINERS: add i.MX8 DT path to i.MX architecture

 Documentation/devicetree/bindings/arm/fsl.txt  |   8 +
 MAINTAINERS                                    |   1 +
 arch/arm64/Kconfig.platforms                   |  14 +
 arch/arm64/boot/dts/freescale/Makefile         |   2 +
 arch/arm64/boot/dts/freescale/imx8mq-evk.dts   | 303 ++++++++++++
 arch/arm64/boot/dts/freescale/imx8mq-pinfunc.h | 623 +++++++++++++++++++++++++
 arch/arm64/boot/dts/freescale/imx8mq.dtsi      | 416 +++++++++++++++++
 7 files changed, 1367 insertions(+)
 create mode 100644 arch/arm64/boot/dts/freescale/imx8mq-evk.dts
 create mode 100644 arch/arm64/boot/dts/freescale/imx8mq-pinfunc.h
 create mode 100644 arch/arm64/boot/dts/freescale/imx8mq.dtsi

-- 
2.7.4


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

^ permalink raw reply

* Re: [PATCH v6 02/13] arm64: add pointer authentication register bits
From: Richard Henderson @ 2018-12-09 14:24 UTC (permalink / raw)
  To: Kristina Martsenko, linux-arm-kernel
  Cc: Mark Rutland, Andrew Jones, Jacob Bramley, Ard Biesheuvel,
	Marc Zyngier, Catalin Marinas, Adam Wallis, Suzuki K Poulose,
	Will Deacon, Christoffer Dall, kvmarm, Cyrill Gorcunov,
	Ramana Radhakrishnan, Amit Kachhap, Dave P Martin, linux-kernel,
	Kees Cook
In-Reply-To: <20181207183931.4285-3-kristina.martsenko@arm.com>

On 12/7/18 12:39 PM, Kristina Martsenko wrote:
>  #define SCTLR_ELx_DSSBS	(1UL << 44)
> +#define SCTLR_ELx_ENIA	(1 << 31)

1U or 1UL lest you produce signed -0x80000000.

Otherwise,
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>


r~

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

^ permalink raw reply

* [PATCH 2/5] spi: stm32: rename spi-stm32 to spi-stm32h7
From: cezary.gapinski @ 2018-12-09 13:53 UTC (permalink / raw)
  To: Mark Brown, linux-spi, linux-stm32, linux-arm-kernel,
	linux-kernel, Rob Herring, devicetree
  Cc: Mark Rutland, Amelie Delaunay, Cezary Gapinski, Alexandre Torgue,
	Maxime Coquelin
In-Reply-To: <1544363636-12161-1-git-send-email-cezary.gapinski@gmail.com>

From: Cezary Gapinski <cezary.gapinski@gmail.com>

Rename spi-stm32 driver to be related to STM32H7 type.

Signed-off-by: Cezary Gapinski <cezary.gapinski@gmail.com>
---
 drivers/spi/Kconfig       |    8 +-
 drivers/spi/Makefile      |    2 +-
 drivers/spi/spi-stm32.c   | 1340 ---------------------------------------------
 drivers/spi/spi-stm32h7.c | 1340 +++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 1345 insertions(+), 1345 deletions(-)
 delete mode 100644 drivers/spi/spi-stm32.c
 create mode 100644 drivers/spi/spi-stm32h7.c

diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
index 7d3a5c9..0151334 100644
--- a/drivers/spi/Kconfig
+++ b/drivers/spi/Kconfig
@@ -645,13 +645,13 @@ config SPI_SPRD_ADI
 	help
 	  ADI driver based on SPI for Spreadtrum SoCs.
 
-config SPI_STM32
-	tristate "STMicroelectronics STM32 SPI controller"
+config SPI_STM32H7
+	tristate "STMicroelectronics STM32H7 SPI controller"
 	depends on ARCH_STM32 || COMPILE_TEST
 	help
-	  SPI driver for STMicroelectonics STM32 SoCs.
+	  SPI driver for STMicroelectronics STM32H7 SoCs.
 
-	  STM32 SPI controller supports DMA and PIO modes. When DMA
+	  STM32H7 SPI controller supports DMA and PIO modes. When DMA
 	  is not available, the driver automatically falls back to
 	  PIO mode.
 
diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile
index 3575205..6f24938 100644
--- a/drivers/spi/Makefile
+++ b/drivers/spi/Makefile
@@ -94,7 +94,7 @@ obj-$(CONFIG_SPI_SIRF)		+= spi-sirf.o
 obj-$(CONFIG_SPI_SLAVE_MT27XX)          += spi-slave-mt27xx.o
 obj-$(CONFIG_SPI_SPRD)			+= spi-sprd.o
 obj-$(CONFIG_SPI_SPRD_ADI)		+= spi-sprd-adi.o
-obj-$(CONFIG_SPI_STM32) 		+= spi-stm32.o
+obj-$(CONFIG_SPI_STM32H7) 		+= spi-stm32h7.o
 obj-$(CONFIG_SPI_STM32_QSPI) 		+= spi-stm32-qspi.o
 obj-$(CONFIG_SPI_ST_SSC4)		+= spi-st-ssc4.o
 obj-$(CONFIG_SPI_SUN4I)			+= spi-sun4i.o
diff --git a/drivers/spi/spi-stm32.c b/drivers/spi/spi-stm32.c
deleted file mode 100644
index eb4d93e..0000000
--- a/drivers/spi/spi-stm32.c
+++ /dev/null
@@ -1,1340 +0,0 @@
-/*
- * STMicroelectronics STM32 SPI Controller driver (master mode only)
- *
- * Copyright (C) 2017, STMicroelectronics - All Rights Reserved
- * Author(s): Amelie Delaunay <amelie.delaunay@st.com> for STMicroelectronics.
- *
- * License terms: GPL V2.0.
- *
- * spi_stm32 driver 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.
- *
- * spi_stm32 driver is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
- * details.
- *
- * You should have received a copy of the GNU General Public License along with
- * spi_stm32 driver. If not, see <http://www.gnu.org/licenses/>.
- */
-#include <linux/debugfs.h>
-#include <linux/clk.h>
-#include <linux/delay.h>
-#include <linux/dmaengine.h>
-#include <linux/gpio.h>
-#include <linux/interrupt.h>
-#include <linux/iopoll.h>
-#include <linux/module.h>
-#include <linux/of_platform.h>
-#include <linux/pm_runtime.h>
-#include <linux/reset.h>
-#include <linux/spi/spi.h>
-
-#define DRIVER_NAME "spi_stm32"
-
-/* STM32H7 SPI registers */
-#define STM32H7_SPI_CR1			0x00
-#define STM32H7_SPI_CR2			0x04
-#define STM32H7_SPI_CFG1		0x08
-#define STM32H7_SPI_CFG2		0x0C
-#define STM32H7_SPI_IER			0x10
-#define STM32H7_SPI_SR			0x14
-#define STM32H7_SPI_IFCR		0x18
-#define STM32H7_SPI_TXDR		0x20
-#define STM32H7_SPI_RXDR		0x30
-#define STM32H7_SPI_I2SCFGR		0x50
-
-/* STM32H7_SPI_CR1 bit fields */
-#define STM32H7_SPI_CR1_SPE		BIT(0)
-#define STM32H7_SPI_CR1_MASRX		BIT(8)
-#define STM32H7_SPI_CR1_CSTART		BIT(9)
-#define STM32H7_SPI_CR1_CSUSP		BIT(10)
-#define STM32H7_SPI_CR1_HDDIR		BIT(11)
-#define STM32H7_SPI_CR1_SSI		BIT(12)
-
-/* STM32H7_SPI_CR2 bit fields */
-#define STM32H7_SPI_CR2_TSIZE_SHIFT	0
-#define STM32H7_SPI_CR2_TSIZE		GENMASK(15, 0)
-
-/* STM32H7_SPI_CFG1 bit fields */
-#define STM32H7_SPI_CFG1_DSIZE_SHIFT	0
-#define STM32H7_SPI_CFG1_DSIZE		GENMASK(4, 0)
-#define STM32H7_SPI_CFG1_FTHLV_SHIFT	5
-#define STM32H7_SPI_CFG1_FTHLV		GENMASK(8, 5)
-#define STM32H7_SPI_CFG1_RXDMAEN	BIT(14)
-#define STM32H7_SPI_CFG1_TXDMAEN	BIT(15)
-#define STM32H7_SPI_CFG1_MBR_SHIFT	28
-#define STM32H7_SPI_CFG1_MBR		GENMASK(30, 28)
-#define STM32H7_SPI_CFG1_MBR_MIN	0
-#define STM32H7_SPI_CFG1_MBR_MAX	(GENMASK(30, 28) >> 28)
-
-/* STM32H7_SPI_CFG2 bit fields */
-#define STM32H7_SPI_CFG2_MIDI_SHIFT	4
-#define STM32H7_SPI_CFG2_MIDI		GENMASK(7, 4)
-#define STM32H7_SPI_CFG2_COMM_SHIFT	17
-#define STM32H7_SPI_CFG2_COMM		GENMASK(18, 17)
-#define STM32H7_SPI_CFG2_SP_SHIFT	19
-#define STM32H7_SPI_CFG2_SP		GENMASK(21, 19)
-#define STM32H7_SPI_CFG2_MASTER		BIT(22)
-#define STM32H7_SPI_CFG2_LSBFRST	BIT(23)
-#define STM32H7_SPI_CFG2_CPHA		BIT(24)
-#define STM32H7_SPI_CFG2_CPOL		BIT(25)
-#define STM32H7_SPI_CFG2_SSM		BIT(26)
-#define STM32H7_SPI_CFG2_AFCNTR		BIT(31)
-
-/* STM32H7_SPI_IER bit fields */
-#define STM32H7_SPI_IER_RXPIE		BIT(0)
-#define STM32H7_SPI_IER_TXPIE		BIT(1)
-#define STM32H7_SPI_IER_DXPIE		BIT(2)
-#define STM32H7_SPI_IER_EOTIE		BIT(3)
-#define STM32H7_SPI_IER_TXTFIE		BIT(4)
-#define STM32H7_SPI_IER_OVRIE		BIT(6)
-#define STM32H7_SPI_IER_MODFIE		BIT(9)
-#define STM32H7_SPI_IER_ALL		GENMASK(10, 0)
-
-/* STM32H7_SPI_SR bit fields */
-#define STM32H7_SPI_SR_RXP		BIT(0)
-#define STM32H7_SPI_SR_TXP		BIT(1)
-#define STM32H7_SPI_SR_EOT		BIT(3)
-#define STM32H7_SPI_SR_OVR		BIT(6)
-#define STM32H7_SPI_SR_MODF		BIT(9)
-#define STM32H7_SPI_SR_SUSP		BIT(11)
-#define STM32H7_SPI_SR_RXPLVL_SHIFT	13
-#define STM32H7_SPI_SR_RXPLVL		GENMASK(14, 13)
-#define STM32H7_SPI_SR_RXWNE		BIT(15)
-
-/* STM32H7_SPI_IFCR bit fields */
-#define STM32H7_SPI_IFCR_ALL		GENMASK(11, 3)
-
-/* STM32H7_SPI_I2SCFGR bit fields */
-#define STM32H7_SPI_I2SCFGR_I2SMOD	BIT(0)
-
-/* STM32H7 SPI Master Baud Rate min/max divisor */
-#define STM32H7_SPI_MBR_DIV_MIN		(2 << STM32H7_SPI_CFG1_MBR_MIN)
-#define STM32H7_SPI_MBR_DIV_MAX		(2 << STM32H7_SPI_CFG1_MBR_MAX)
-
-/* STM32H7 SPI Communication mode */
-#define STM32H7_SPI_FULL_DUPLEX		0
-#define STM32H7_SPI_SIMPLEX_TX		1
-#define STM32H7_SPI_SIMPLEX_RX		2
-#define STM32H7_SPI_HALF_DUPLEX		3
-
-#define STM32H7_SPI_1HZ_NS		1000000000
-
-/**
- * struct stm32h7_spi - private data of the SPI controller
- * @dev: driver model representation of the controller
- * @master: controller master interface
- * @base: virtual memory area
- * @clk: hw kernel clock feeding the SPI clock generator
- * @clk_rate: rate of the hw kernel clock feeding the SPI clock generator
- * @rst: SPI controller reset line
- * @lock: prevent I/O concurrent access
- * @irq: SPI controller interrupt line
- * @fifo_size: size of the embedded fifo in bytes
- * @cur_midi: master inter-data idleness in ns
- * @cur_speed: speed configured in Hz
- * @cur_bpw: number of bits in a single SPI data frame
- * @cur_fthlv: fifo threshold level (data frames in a single data packet)
- * @cur_comm: SPI communication mode
- * @cur_xferlen: current transfer length in bytes
- * @cur_usedma: boolean to know if dma is used in current transfer
- * @tx_buf: data to be written, or NULL
- * @rx_buf: data to be read, or NULL
- * @tx_len: number of data to be written in bytes
- * @rx_len: number of data to be read in bytes
- * @dma_tx: dma channel for TX transfer
- * @dma_rx: dma channel for RX transfer
- * @phys_addr: SPI registers physical base address
- */
-struct stm32h7_spi {
-	struct device *dev;
-	struct spi_master *master;
-	void __iomem *base;
-	struct clk *clk;
-	u32 clk_rate;
-	struct reset_control *rst;
-	spinlock_t lock; /* prevent I/O concurrent access */
-	int irq;
-	unsigned int fifo_size;
-
-	unsigned int cur_midi;
-	unsigned int cur_speed;
-	unsigned int cur_bpw;
-	unsigned int cur_fthlv;
-	unsigned int cur_comm;
-	unsigned int cur_xferlen;
-	bool cur_usedma;
-
-	const void *tx_buf;
-	void *rx_buf;
-	int tx_len;
-	int rx_len;
-	struct dma_chan *dma_tx;
-	struct dma_chan *dma_rx;
-	dma_addr_t phys_addr;
-};
-
-static inline void stm32h7_spi_set_bits(struct stm32h7_spi *spi,
-					u32 offset, u32 bits)
-{
-	writel_relaxed(readl_relaxed(spi->base + offset) | bits,
-		       spi->base + offset);
-}
-
-static inline void stm32h7_spi_clr_bits(struct stm32h7_spi *spi,
-					u32 offset, u32 bits)
-{
-	writel_relaxed(readl_relaxed(spi->base + offset) & ~bits,
-		       spi->base + offset);
-}
-
-/**
- * stm32h7_spi_get_fifo_size - Return fifo size
- * @spi: pointer to the spi controller data structure
- */
-static int stm32h7_spi_get_fifo_size(struct stm32h7_spi *spi)
-{
-	unsigned long flags;
-	u32 count = 0;
-
-	spin_lock_irqsave(&spi->lock, flags);
-
-	stm32h7_spi_set_bits(spi, STM32H7_SPI_CR1, STM32H7_SPI_CR1_SPE);
-
-	while (readl_relaxed(spi->base + STM32H7_SPI_SR) & STM32H7_SPI_SR_TXP)
-		writeb_relaxed(++count, spi->base + STM32H7_SPI_TXDR);
-
-	stm32h7_spi_clr_bits(spi, STM32H7_SPI_CR1, STM32H7_SPI_CR1_SPE);
-
-	spin_unlock_irqrestore(&spi->lock, flags);
-
-	dev_dbg(spi->dev, "%d x 8-bit fifo size\n", count);
-
-	return count;
-}
-
-/**
- * stm32h7_spi_get_bpw_mask - Return bits per word mask
- * @spi: pointer to the spi controller data structure
- */
-static int stm32h7_spi_get_bpw_mask(struct stm32h7_spi *spi)
-{
-	unsigned long flags;
-	u32 cfg1, max_bpw;
-
-	spin_lock_irqsave(&spi->lock, flags);
-
-	/*
-	 * The most significant bit at DSIZE bit field is reserved when the
-	 * maximum data size of periperal instances is limited to 16-bit
-	 */
-	stm32h7_spi_set_bits(spi, STM32H7_SPI_CFG1, STM32H7_SPI_CFG1_DSIZE);
-
-	cfg1 = readl_relaxed(spi->base + STM32H7_SPI_CFG1);
-	max_bpw = (cfg1 & STM32H7_SPI_CFG1_DSIZE) >>
-		  STM32H7_SPI_CFG1_DSIZE_SHIFT;
-	max_bpw += 1;
-
-	spin_unlock_irqrestore(&spi->lock, flags);
-
-	dev_dbg(spi->dev, "%d-bit maximum data frame\n", max_bpw);
-
-	return SPI_BPW_RANGE_MASK(4, max_bpw);
-}
-
-/**
- * stm32h7_spi_prepare_mbr - Determine STM32H7_SPI_CFG1.MBR value
- * @spi: pointer to the spi controller data structure
- * @speed_hz: requested speed
- *
- * Return STM32H7_SPI_CFG1.MBR value in case of success or -EINVAL
- */
-static int stm32h7_spi_prepare_mbr(struct stm32h7_spi *spi, u32 speed_hz)
-{
-	u32 div, mbrdiv;
-
-	div = DIV_ROUND_UP(spi->clk_rate, speed_hz);
-
-	/*
-	 * SPI framework set xfer->speed_hz to master->max_speed_hz if
-	 * xfer->speed_hz is greater than master->max_speed_hz, and it returns
-	 * an error when xfer->speed_hz is lower than master->min_speed_hz, so
-	 * no need to check it there.
-	 * However, we need to ensure the following calculations.
-	 */
-	if (div < STM32H7_SPI_MBR_DIV_MIN ||
-	    div > STM32H7_SPI_MBR_DIV_MAX)
-		return -EINVAL;
-
-	/* Determine the first power of 2 greater than or equal to div */
-	if (div & (div - 1))
-		mbrdiv = fls(div);
-	else
-		mbrdiv = fls(div) - 1;
-
-	spi->cur_speed = spi->clk_rate / (1 << mbrdiv);
-
-	return mbrdiv - 1;
-}
-
-/**
- * stm32h7_spi_prepare_fthlv - Determine FIFO threshold level
- * @spi: pointer to the spi controller data structure
- */
-static u32 stm32h7_spi_prepare_fthlv(struct stm32h7_spi *spi)
-{
-	u32 fthlv, half_fifo;
-
-	/* data packet should not exceed 1/2 of fifo space */
-	half_fifo = (spi->fifo_size / 2);
-
-	if (spi->cur_bpw <= 8)
-		fthlv = half_fifo;
-	else if (spi->cur_bpw <= 16)
-		fthlv = half_fifo / 2;
-	else
-		fthlv = half_fifo / 4;
-
-	/* align packet size with data registers access */
-	if (spi->cur_bpw > 8)
-		fthlv -= (fthlv % 2); /* multiple of 2 */
-	else
-		fthlv -= (fthlv % 4); /* multiple of 4 */
-
-	return fthlv;
-}
-
-/**
- * stm32h7_spi_write_txfifo - Write bytes in Transmit Data Register
- * @spi: pointer to the spi controller data structure
- *
- * Read from tx_buf depends on remaining bytes to avoid to read beyond
- * tx_buf end.
- */
-static void stm32h7_spi_write_txfifo(struct stm32h7_spi *spi)
-{
-	while ((spi->tx_len > 0) &&
-	       (readl_relaxed(spi->base + STM32H7_SPI_SR) &
-		STM32H7_SPI_SR_TXP)) {
-		u32 offs = spi->cur_xferlen - spi->tx_len;
-
-		if (spi->tx_len >= sizeof(u32)) {
-			const u32 *tx_buf32 = (const u32 *)(spi->tx_buf + offs);
-
-			writel_relaxed(*tx_buf32, spi->base + STM32H7_SPI_TXDR);
-			spi->tx_len -= sizeof(u32);
-		} else if (spi->tx_len >= sizeof(u16)) {
-			const u16 *tx_buf16 = (const u16 *)(spi->tx_buf + offs);
-
-			writew_relaxed(*tx_buf16, spi->base + STM32H7_SPI_TXDR);
-			spi->tx_len -= sizeof(u16);
-		} else {
-			const u8 *tx_buf8 = (const u8 *)(spi->tx_buf + offs);
-
-			writeb_relaxed(*tx_buf8, spi->base + STM32H7_SPI_TXDR);
-			spi->tx_len -= sizeof(u8);
-		}
-	}
-
-	dev_dbg(spi->dev, "%s: %d bytes left\n", __func__, spi->tx_len);
-}
-
-/**
- * stm32h7_spi_read_rxfifo - Read bytes in Receive Data Register
- * @spi: pointer to the spi controller data structure
- *
- * Write in rx_buf depends on remaining bytes to avoid to write beyond
- * rx_buf end.
- */
-static void stm32h7_spi_read_rxfifo(struct stm32h7_spi *spi, bool flush)
-{
-	u32 sr = readl_relaxed(spi->base + STM32H7_SPI_SR);
-	u32 rxplvl = (sr & STM32H7_SPI_SR_RXPLVL) >>
-		     STM32H7_SPI_SR_RXPLVL_SHIFT;
-
-	while ((spi->rx_len > 0) &&
-	       ((sr & STM32H7_SPI_SR_RXP) ||
-		(flush && ((sr & STM32H7_SPI_SR_RXWNE) || (rxplvl > 0))))) {
-		u32 offs = spi->cur_xferlen - spi->rx_len;
-
-		if ((spi->rx_len >= sizeof(u32)) ||
-		    (flush && (sr & STM32H7_SPI_SR_RXWNE))) {
-			u32 *rx_buf32 = (u32 *)(spi->rx_buf + offs);
-
-			*rx_buf32 = readl_relaxed(spi->base + STM32H7_SPI_RXDR);
-			spi->rx_len -= sizeof(u32);
-		} else if ((spi->rx_len >= sizeof(u16)) ||
-			   (flush && (rxplvl >= 2 || spi->cur_bpw > 8))) {
-			u16 *rx_buf16 = (u16 *)(spi->rx_buf + offs);
-
-			*rx_buf16 = readw_relaxed(spi->base + STM32H7_SPI_RXDR);
-			spi->rx_len -= sizeof(u16);
-		} else {
-			u8 *rx_buf8 = (u8 *)(spi->rx_buf + offs);
-
-			*rx_buf8 = readb_relaxed(spi->base + STM32H7_SPI_RXDR);
-			spi->rx_len -= sizeof(u8);
-		}
-
-		sr = readl_relaxed(spi->base + STM32H7_SPI_SR);
-		rxplvl = (sr & STM32H7_SPI_SR_RXPLVL) >>
-			 STM32H7_SPI_SR_RXPLVL_SHIFT;
-	}
-
-	dev_dbg(spi->dev, "%s%s: %d bytes left\n", __func__,
-		flush ? "(flush)" : "", spi->rx_len);
-}
-
-/**
- * stm32h7_spi_enable - Enable SPI controller
- * @spi: pointer to the spi controller data structure
- *
- * SPI data transfer is enabled but spi_ker_ck is idle.
- * STM32H7_SPI_CFG1 and STM32H7_SPI_CFG2 are now write protected.
- */
-static void stm32h7_spi_enable(struct stm32h7_spi *spi)
-{
-	dev_dbg(spi->dev, "enable controller\n");
-
-	stm32h7_spi_set_bits(spi, STM32H7_SPI_CR1, STM32H7_SPI_CR1_SPE);
-}
-
-/**
- * stm32h7_spi_disable - Disable SPI controller
- * @spi: pointer to the spi controller data structure
- *
- * RX-Fifo is flushed when SPI controller is disabled. To prevent any data
- * loss, use stm32h7_spi_read_rxfifo(flush) to read the remaining bytes in
- * RX-Fifo.
- */
-static void stm32h7_spi_disable(struct stm32h7_spi *spi)
-{
-	unsigned long flags;
-	u32 cr1, sr;
-
-	dev_dbg(spi->dev, "disable controller\n");
-
-	spin_lock_irqsave(&spi->lock, flags);
-
-	cr1 = readl_relaxed(spi->base + STM32H7_SPI_CR1);
-
-	if (!(cr1 & STM32H7_SPI_CR1_SPE)) {
-		spin_unlock_irqrestore(&spi->lock, flags);
-		return;
-	}
-
-	/* Wait on EOT or suspend the flow */
-	if (readl_relaxed_poll_timeout_atomic(spi->base + STM32H7_SPI_SR,
-					      sr, !(sr & STM32H7_SPI_SR_EOT),
-					      10, 100000) < 0) {
-		if (cr1 & STM32H7_SPI_CR1_CSTART) {
-			writel_relaxed(cr1 | STM32H7_SPI_CR1_CSUSP,
-				       spi->base + STM32H7_SPI_CR1);
-			if (readl_relaxed_poll_timeout_atomic(
-						spi->base + STM32H7_SPI_SR,
-						sr, !(sr & STM32H7_SPI_SR_SUSP),
-						10, 100000) < 0)
-				dev_warn(spi->dev,
-					 "Suspend request timeout\n");
-		}
-	}
-
-	if (!spi->cur_usedma && spi->rx_buf && (spi->rx_len > 0))
-		stm32h7_spi_read_rxfifo(spi, true);
-
-	if (spi->cur_usedma && spi->tx_buf)
-		dmaengine_terminate_all(spi->dma_tx);
-	if (spi->cur_usedma && spi->rx_buf)
-		dmaengine_terminate_all(spi->dma_rx);
-
-	stm32h7_spi_clr_bits(spi, STM32H7_SPI_CR1, STM32H7_SPI_CR1_SPE);
-
-	stm32h7_spi_clr_bits(spi, STM32H7_SPI_CFG1, STM32H7_SPI_CFG1_TXDMAEN |
-						    STM32H7_SPI_CFG1_RXDMAEN);
-
-	/* Disable interrupts and clear status flags */
-	writel_relaxed(0, spi->base + STM32H7_SPI_IER);
-	writel_relaxed(STM32H7_SPI_IFCR_ALL, spi->base + STM32H7_SPI_IFCR);
-
-	spin_unlock_irqrestore(&spi->lock, flags);
-}
-
-/**
- * stm32h7_spi_can_dma - Determine if the transfer is eligible for DMA use
- *
- * If the current transfer size is greater than fifo size, use DMA.
- */
-static bool stm32h7_spi_can_dma(struct spi_master *master,
-				struct spi_device *spi_dev,
-				struct spi_transfer *transfer)
-{
-	struct stm32h7_spi *spi = spi_master_get_devdata(master);
-
-	dev_dbg(spi->dev, "%s: %s\n", __func__,
-		(transfer->len > spi->fifo_size) ? "true" : "false");
-
-	return (transfer->len > spi->fifo_size);
-}
-
-/**
- * stm32h7_spi_irq - Interrupt handler for SPI controller events
- * @irq: interrupt line
- * @dev_id: SPI controller master interface
- */
-static irqreturn_t stm32h7_spi_irq(int irq, void *dev_id)
-{
-	struct spi_master *master = dev_id;
-	struct stm32h7_spi *spi = spi_master_get_devdata(master);
-	u32 sr, ier, mask;
-	unsigned long flags;
-	bool end = false;
-
-	spin_lock_irqsave(&spi->lock, flags);
-
-	sr = readl_relaxed(spi->base + STM32H7_SPI_SR);
-	ier = readl_relaxed(spi->base + STM32H7_SPI_IER);
-
-	mask = ier;
-	/* EOTIE is triggered on EOT, SUSP and TXC events. */
-	mask |= STM32H7_SPI_SR_SUSP;
-	/*
-	 * When TXTF is set, DXPIE and TXPIE are cleared. So in case of
-	 * Full-Duplex, need to poll RXP event to know if there are remaining
-	 * data, before disabling SPI.
-	 */
-	if (spi->rx_buf && !spi->cur_usedma)
-		mask |= STM32H7_SPI_SR_RXP;
-
-	if (!(sr & mask)) {
-		dev_dbg(spi->dev, "spurious IT (sr=0x%08x, ier=0x%08x)\n",
-			sr, ier);
-		spin_unlock_irqrestore(&spi->lock, flags);
-		return IRQ_NONE;
-	}
-
-	if (sr & STM32H7_SPI_SR_SUSP) {
-		dev_warn(spi->dev, "Communication suspended\n");
-		if (!spi->cur_usedma && (spi->rx_buf && (spi->rx_len > 0)))
-			stm32h7_spi_read_rxfifo(spi, false);
-		/*
-		 * If communication is suspended while using DMA, it means
-		 * that something went wrong, so stop the current transfer
-		 */
-		if (spi->cur_usedma)
-			end = true;
-	}
-
-	if (sr & STM32H7_SPI_SR_MODF) {
-		dev_warn(spi->dev, "Mode fault: transfer aborted\n");
-		end = true;
-	}
-
-	if (sr & STM32H7_SPI_SR_OVR) {
-		dev_warn(spi->dev, "Overrun: received value discarded\n");
-		if (!spi->cur_usedma && (spi->rx_buf && (spi->rx_len > 0)))
-			stm32h7_spi_read_rxfifo(spi, false);
-		/*
-		 * If overrun is detected while using DMA, it means that
-		 * something went wrong, so stop the current transfer
-		 */
-		if (spi->cur_usedma)
-			end = true;
-	}
-
-	if (sr & STM32H7_SPI_SR_EOT) {
-		if (!spi->cur_usedma && (spi->rx_buf && (spi->rx_len > 0)))
-			stm32h7_spi_read_rxfifo(spi, true);
-		end = true;
-	}
-
-	if (sr & STM32H7_SPI_SR_TXP)
-		if (!spi->cur_usedma && (spi->tx_buf && (spi->tx_len > 0)))
-			stm32h7_spi_write_txfifo(spi);
-
-	if (sr & STM32H7_SPI_SR_RXP)
-		if (!spi->cur_usedma && (spi->rx_buf && (spi->rx_len > 0)))
-			stm32h7_spi_read_rxfifo(spi, false);
-
-	writel_relaxed(mask, spi->base + STM32H7_SPI_IFCR);
-
-	spin_unlock_irqrestore(&spi->lock, flags);
-
-	if (end) {
-		spi_finalize_current_transfer(master);
-		stm32h7_spi_disable(spi);
-	}
-
-	return IRQ_HANDLED;
-}
-
-/**
- * stm32h7_spi_setup - setup device chip select
- */
-static int stm32h7_spi_setup(struct spi_device *spi_dev)
-{
-	int ret = 0;
-
-	if (!gpio_is_valid(spi_dev->cs_gpio)) {
-		dev_err(&spi_dev->dev, "%d is not a valid gpio\n",
-			spi_dev->cs_gpio);
-		return -EINVAL;
-	}
-
-	dev_dbg(&spi_dev->dev, "%s: set gpio%d output %s\n", __func__,
-		spi_dev->cs_gpio,
-		(spi_dev->mode & SPI_CS_HIGH) ? "low" : "high");
-
-	ret = gpio_direction_output(spi_dev->cs_gpio,
-				    !(spi_dev->mode & SPI_CS_HIGH));
-
-	return ret;
-}
-
-/**
- * stm32h7_spi_prepare_msg - set up the controller to transfer a single message
- */
-static int stm32h7_spi_prepare_msg(struct spi_master *master,
-				   struct spi_message *msg)
-{
-	struct stm32h7_spi *spi = spi_master_get_devdata(master);
-	struct spi_device *spi_dev = msg->spi;
-	struct device_node *np = spi_dev->dev.of_node;
-	unsigned long flags;
-	u32 cfg2_clrb = 0, cfg2_setb = 0;
-
-	/* SPI slave device may need time between data frames */
-	spi->cur_midi = 0;
-	if (np && !of_property_read_u32(np, "st,spi-midi-ns", &spi->cur_midi))
-		dev_dbg(spi->dev, "%dns inter-data idleness\n", spi->cur_midi);
-
-	if (spi_dev->mode & SPI_CPOL)
-		cfg2_setb |= STM32H7_SPI_CFG2_CPOL;
-	else
-		cfg2_clrb |= STM32H7_SPI_CFG2_CPOL;
-
-	if (spi_dev->mode & SPI_CPHA)
-		cfg2_setb |= STM32H7_SPI_CFG2_CPHA;
-	else
-		cfg2_clrb |= STM32H7_SPI_CFG2_CPHA;
-
-	if (spi_dev->mode & SPI_LSB_FIRST)
-		cfg2_setb |= STM32H7_SPI_CFG2_LSBFRST;
-	else
-		cfg2_clrb |= STM32H7_SPI_CFG2_LSBFRST;
-
-	dev_dbg(spi->dev, "cpol=%d cpha=%d lsb_first=%d cs_high=%d\n",
-		spi_dev->mode & SPI_CPOL,
-		spi_dev->mode & SPI_CPHA,
-		spi_dev->mode & SPI_LSB_FIRST,
-		spi_dev->mode & SPI_CS_HIGH);
-
-	spin_lock_irqsave(&spi->lock, flags);
-
-	if (cfg2_clrb || cfg2_setb)
-		writel_relaxed(
-			(readl_relaxed(spi->base + STM32H7_SPI_CFG2) &
-				~cfg2_clrb) | cfg2_setb,
-			       spi->base + STM32H7_SPI_CFG2);
-
-	spin_unlock_irqrestore(&spi->lock, flags);
-
-	return 0;
-}
-
-/**
- * stm32h7_spi_dma_cb - dma callback
- *
- * DMA callback is called when the transfer is complete or when an error
- * occurs. If the transfer is complete, EOT flag is raised.
- */
-static void stm32h7_spi_dma_cb(void *data)
-{
-	struct stm32h7_spi *spi = data;
-	unsigned long flags;
-	u32 sr;
-
-	spin_lock_irqsave(&spi->lock, flags);
-
-	sr = readl_relaxed(spi->base + STM32H7_SPI_SR);
-
-	spin_unlock_irqrestore(&spi->lock, flags);
-
-	if (!(sr & STM32H7_SPI_SR_EOT))
-		dev_warn(spi->dev, "DMA error (sr=0x%08x)\n", sr);
-
-	/* Now wait for EOT, or SUSP or OVR in case of error */
-}
-
-/**
- * stm32h7_spi_dma_config - configure dma slave channel depending on current
- *			    transfer bits_per_word.
- */
-static void stm32h7_spi_dma_config(struct stm32h7_spi *spi,
-				   struct dma_slave_config *dma_conf,
-				   enum dma_transfer_direction dir)
-{
-	enum dma_slave_buswidth buswidth;
-	u32 maxburst;
-
-	if (spi->cur_bpw <= 8)
-		buswidth = DMA_SLAVE_BUSWIDTH_1_BYTE;
-	else if (spi->cur_bpw <= 16)
-		buswidth = DMA_SLAVE_BUSWIDTH_2_BYTES;
-	else
-		buswidth = DMA_SLAVE_BUSWIDTH_4_BYTES;
-
-	/* Valid for DMA Half or Full Fifo threshold */
-	if (spi->cur_fthlv == 2)
-		maxburst = 1;
-	else
-		maxburst = spi->cur_fthlv;
-
-	memset(dma_conf, 0, sizeof(struct dma_slave_config));
-	dma_conf->direction = dir;
-	if (dma_conf->direction == DMA_DEV_TO_MEM) { /* RX */
-		dma_conf->src_addr = spi->phys_addr + STM32H7_SPI_RXDR;
-		dma_conf->src_addr_width = buswidth;
-		dma_conf->src_maxburst = maxburst;
-
-		dev_dbg(spi->dev, "Rx DMA config buswidth=%d, maxburst=%d\n",
-			buswidth, maxburst);
-	} else if (dma_conf->direction == DMA_MEM_TO_DEV) { /* TX */
-		dma_conf->dst_addr = spi->phys_addr + STM32H7_SPI_TXDR;
-		dma_conf->dst_addr_width = buswidth;
-		dma_conf->dst_maxburst = maxburst;
-
-		dev_dbg(spi->dev, "Tx DMA config buswidth=%d, maxburst=%d\n",
-			buswidth, maxburst);
-	}
-}
-
-/**
- * stm32h7_spi_transfer_one_irq - transfer a single spi_transfer using
- *				  interrupts
- *
- * It must returns 0 if the transfer is finished or 1 if the transfer is still
- * in progress.
- */
-static int stm32h7_spi_transfer_one_irq(struct stm32h7_spi *spi)
-{
-	unsigned long flags;
-	u32 ier = 0;
-
-	/* Enable the interrupts relative to the current communication mode */
-	if (spi->tx_buf && spi->rx_buf)	/* Full Duplex */
-		ier |= STM32H7_SPI_IER_DXPIE;
-	else if (spi->tx_buf)		/* Half-Duplex TX dir or Simplex TX */
-		ier |= STM32H7_SPI_IER_TXPIE;
-	else if (spi->rx_buf)		/* Half-Duplex RX dir or Simplex RX */
-		ier |= STM32H7_SPI_IER_RXPIE;
-
-	/* Enable the interrupts relative to the end of transfer */
-	ier |= STM32H7_SPI_IER_EOTIE | STM32H7_SPI_IER_TXTFIE |
-	       STM32H7_SPI_IER_OVRIE | STM32H7_SPI_IER_MODFIE;
-
-	spin_lock_irqsave(&spi->lock, flags);
-
-	stm32h7_spi_enable(spi);
-
-	/* Be sure to have data in fifo before starting data transfer */
-	if (spi->tx_buf)
-		stm32h7_spi_write_txfifo(spi);
-
-	stm32h7_spi_set_bits(spi, STM32H7_SPI_CR1, STM32H7_SPI_CR1_CSTART);
-
-	writel_relaxed(ier, spi->base + STM32H7_SPI_IER);
-
-	spin_unlock_irqrestore(&spi->lock, flags);
-
-	return 1;
-}
-
-/**
- * stm32h7_spi_transfer_one_dma - transfer a single spi_transfer using DMA
- *
- * It must returns 0 if the transfer is finished or 1 if the transfer is still
- * in progress.
- */
-static int stm32h7_spi_transfer_one_dma(struct stm32h7_spi *spi,
-					struct spi_transfer *xfer)
-{
-	struct dma_slave_config tx_dma_conf, rx_dma_conf;
-	struct dma_async_tx_descriptor *tx_dma_desc, *rx_dma_desc;
-	unsigned long flags;
-	u32 ier = 0;
-
-	spin_lock_irqsave(&spi->lock, flags);
-
-	rx_dma_desc = NULL;
-	if (spi->rx_buf) {
-		stm32h7_spi_dma_config(spi, &rx_dma_conf, DMA_DEV_TO_MEM);
-		dmaengine_slave_config(spi->dma_rx, &rx_dma_conf);
-
-		/* Enable Rx DMA request */
-		stm32h7_spi_set_bits(spi, STM32H7_SPI_CFG1,
-				   STM32H7_SPI_CFG1_RXDMAEN);
-
-		rx_dma_desc = dmaengine_prep_slave_sg(
-					spi->dma_rx, xfer->rx_sg.sgl,
-					xfer->rx_sg.nents,
-					rx_dma_conf.direction,
-					DMA_PREP_INTERRUPT);
-	}
-
-	tx_dma_desc = NULL;
-	if (spi->tx_buf) {
-		stm32h7_spi_dma_config(spi, &tx_dma_conf, DMA_MEM_TO_DEV);
-		dmaengine_slave_config(spi->dma_tx, &tx_dma_conf);
-
-		tx_dma_desc = dmaengine_prep_slave_sg(
-					spi->dma_tx, xfer->tx_sg.sgl,
-					xfer->tx_sg.nents,
-					tx_dma_conf.direction,
-					DMA_PREP_INTERRUPT);
-	}
-
-	if ((spi->tx_buf && !tx_dma_desc) ||
-	    (spi->rx_buf && !rx_dma_desc))
-		goto dma_desc_error;
-
-	if (rx_dma_desc) {
-		rx_dma_desc->callback = stm32h7_spi_dma_cb;
-		rx_dma_desc->callback_param = spi;
-
-		if (dma_submit_error(dmaengine_submit(rx_dma_desc))) {
-			dev_err(spi->dev, "Rx DMA submit failed\n");
-			goto dma_desc_error;
-		}
-		/* Enable Rx DMA channel */
-		dma_async_issue_pending(spi->dma_rx);
-	}
-
-	if (tx_dma_desc) {
-		if (spi->cur_comm == STM32H7_SPI_SIMPLEX_TX) {
-			tx_dma_desc->callback = stm32h7_spi_dma_cb;
-			tx_dma_desc->callback_param = spi;
-		}
-
-		if (dma_submit_error(dmaengine_submit(tx_dma_desc))) {
-			dev_err(spi->dev, "Tx DMA submit failed\n");
-			goto dma_submit_error;
-		}
-		/* Enable Tx DMA channel */
-		dma_async_issue_pending(spi->dma_tx);
-
-		/* Enable Tx DMA request */
-		stm32h7_spi_set_bits(spi, STM32H7_SPI_CFG1,
-				     STM32H7_SPI_CFG1_TXDMAEN);
-	}
-
-	/* Enable the interrupts relative to the end of transfer */
-	ier |= STM32H7_SPI_IER_EOTIE | STM32H7_SPI_IER_TXTFIE |
-	       STM32H7_SPI_IER_OVRIE | STM32H7_SPI_IER_MODFIE;
-	writel_relaxed(ier, spi->base + STM32H7_SPI_IER);
-
-	stm32h7_spi_enable(spi);
-
-	stm32h7_spi_set_bits(spi, STM32H7_SPI_CR1, STM32H7_SPI_CR1_CSTART);
-
-	spin_unlock_irqrestore(&spi->lock, flags);
-
-	return 1;
-
-dma_submit_error:
-	if (spi->rx_buf)
-		dmaengine_terminate_all(spi->dma_rx);
-
-dma_desc_error:
-	stm32h7_spi_clr_bits(spi, STM32H7_SPI_CFG1, STM32H7_SPI_CFG1_RXDMAEN);
-
-	spin_unlock_irqrestore(&spi->lock, flags);
-
-	dev_info(spi->dev, "DMA issue: fall back to irq transfer\n");
-
-	return stm32h7_spi_transfer_one_irq(spi);
-}
-
-/**
- * stm32h7_spi_transfer_one_setup - common setup to transfer a single
- *				    spi_transfer either using DMA or
- *				    interrupts.
- */
-static int stm32h7_spi_transfer_one_setup(struct stm32h7_spi *spi,
-					  struct spi_device *spi_dev,
-					  struct spi_transfer *transfer)
-{
-	unsigned long flags;
-	u32 cfg1_clrb = 0, cfg1_setb = 0, cfg2_clrb = 0, cfg2_setb = 0;
-	u32 mode, nb_words;
-	int ret = 0;
-
-	spin_lock_irqsave(&spi->lock, flags);
-
-	if (spi->cur_bpw != transfer->bits_per_word) {
-		u32 bpw, fthlv;
-
-		spi->cur_bpw = transfer->bits_per_word;
-		bpw = spi->cur_bpw - 1;
-
-		cfg1_clrb |= STM32H7_SPI_CFG1_DSIZE;
-		cfg1_setb |= (bpw << STM32H7_SPI_CFG1_DSIZE_SHIFT) &
-			     STM32H7_SPI_CFG1_DSIZE;
-
-		spi->cur_fthlv = stm32h7_spi_prepare_fthlv(spi);
-		fthlv = spi->cur_fthlv - 1;
-
-		cfg1_clrb |= STM32H7_SPI_CFG1_FTHLV;
-		cfg1_setb |= (fthlv << STM32H7_SPI_CFG1_FTHLV_SHIFT) &
-			     STM32H7_SPI_CFG1_FTHLV;
-	}
-
-	if (spi->cur_speed != transfer->speed_hz) {
-		int mbr;
-
-		/* Update spi->cur_speed with real clock speed */
-		mbr = stm32h7_spi_prepare_mbr(spi, transfer->speed_hz);
-		if (mbr < 0) {
-			ret = mbr;
-			goto out;
-		}
-
-		transfer->speed_hz = spi->cur_speed;
-
-		cfg1_clrb |= STM32H7_SPI_CFG1_MBR;
-		cfg1_setb |= ((u32)mbr << STM32H7_SPI_CFG1_MBR_SHIFT) &
-			     STM32H7_SPI_CFG1_MBR;
-	}
-
-	if (cfg1_clrb || cfg1_setb)
-		writel_relaxed((readl_relaxed(spi->base + STM32H7_SPI_CFG1) &
-				~cfg1_clrb) | cfg1_setb,
-			       spi->base + STM32H7_SPI_CFG1);
-
-	mode = STM32H7_SPI_FULL_DUPLEX;
-	if (spi_dev->mode & SPI_3WIRE) { /* MISO/MOSI signals shared */
-		/*
-		 * SPI_3WIRE and xfer->tx_buf != NULL and xfer->rx_buf != NULL
-		 * is forbidden und unvalidated by SPI subsystem so depending
-		 * on the valid buffer, we can determine the direction of the
-		 * transfer.
-		 */
-		mode = STM32H7_SPI_HALF_DUPLEX;
-		if (!transfer->tx_buf)
-			stm32h7_spi_clr_bits(spi, STM32H7_SPI_CR1,
-					     STM32H7_SPI_CR1_HDDIR);
-		else if (!transfer->rx_buf)
-			stm32h7_spi_set_bits(spi, STM32H7_SPI_CR1,
-					     STM32H7_SPI_CR1_HDDIR);
-	} else {
-		if (!transfer->tx_buf)
-			mode = STM32H7_SPI_SIMPLEX_RX;
-		else if (!transfer->rx_buf)
-			mode = STM32H7_SPI_SIMPLEX_TX;
-	}
-	if (spi->cur_comm != mode) {
-		spi->cur_comm = mode;
-
-		cfg2_clrb |= STM32H7_SPI_CFG2_COMM;
-		cfg2_setb |= (mode << STM32H7_SPI_CFG2_COMM_SHIFT) &
-			     STM32H7_SPI_CFG2_COMM;
-	}
-
-	cfg2_clrb |= STM32H7_SPI_CFG2_MIDI;
-	if ((transfer->len > 1) && (spi->cur_midi > 0)) {
-		u32 sck_period_ns = DIV_ROUND_UP(STM32H7_SPI_1HZ_NS,
-						 spi->cur_speed);
-		u32 midi = min((u32)DIV_ROUND_UP(spi->cur_midi, sck_period_ns),
-			       (u32)STM32H7_SPI_CFG2_MIDI >>
-			       STM32H7_SPI_CFG2_MIDI_SHIFT);
-
-		dev_dbg(spi->dev, "period=%dns, midi=%d(=%dns)\n",
-			sck_period_ns, midi, midi * sck_period_ns);
-
-		cfg2_setb |= (midi << STM32H7_SPI_CFG2_MIDI_SHIFT) &
-			     STM32H7_SPI_CFG2_MIDI;
-	}
-
-	if (cfg2_clrb || cfg2_setb)
-		writel_relaxed((readl_relaxed(spi->base + STM32H7_SPI_CFG2) &
-				~cfg2_clrb) | cfg2_setb,
-			       spi->base + STM32H7_SPI_CFG2);
-
-	if (spi->cur_bpw <= 8)
-		nb_words = transfer->len;
-	else if (spi->cur_bpw <= 16)
-		nb_words = DIV_ROUND_UP(transfer->len * 8, 16);
-	else
-		nb_words = DIV_ROUND_UP(transfer->len * 8, 32);
-	nb_words <<= STM32H7_SPI_CR2_TSIZE_SHIFT;
-
-	if (nb_words <= STM32H7_SPI_CR2_TSIZE) {
-		writel_relaxed(nb_words, spi->base + STM32H7_SPI_CR2);
-	} else {
-		ret = -EMSGSIZE;
-		goto out;
-	}
-
-	spi->cur_xferlen = transfer->len;
-
-	dev_dbg(spi->dev, "transfer communication mode set to %d\n",
-		spi->cur_comm);
-	dev_dbg(spi->dev,
-		"data frame of %d-bit, data packet of %d data frames\n",
-		spi->cur_bpw, spi->cur_fthlv);
-	dev_dbg(spi->dev, "speed set to %dHz\n", spi->cur_speed);
-	dev_dbg(spi->dev, "transfer of %d bytes (%d data frames)\n",
-		spi->cur_xferlen, nb_words);
-	dev_dbg(spi->dev, "dma %s\n",
-		(spi->cur_usedma) ? "enabled" : "disabled");
-
-out:
-	spin_unlock_irqrestore(&spi->lock, flags);
-
-	return ret;
-}
-
-/**
- * stm32h7_spi_transfer_one - transfer a single spi_transfer
- *
- * It must return 0 if the transfer is finished or 1 if the transfer is still
- * in progress.
- */
-static int stm32h7_spi_transfer_one(struct spi_master *master,
-				    struct spi_device *spi_dev,
-				    struct spi_transfer *transfer)
-{
-	struct stm32h7_spi *spi = spi_master_get_devdata(master);
-	int ret;
-
-	spi->tx_buf = transfer->tx_buf;
-	spi->rx_buf = transfer->rx_buf;
-	spi->tx_len = spi->tx_buf ? transfer->len : 0;
-	spi->rx_len = spi->rx_buf ? transfer->len : 0;
-
-	spi->cur_usedma = (master->can_dma &&
-			   stm32h7_spi_can_dma(master, spi_dev, transfer));
-
-	ret = stm32h7_spi_transfer_one_setup(spi, spi_dev, transfer);
-	if (ret) {
-		dev_err(spi->dev, "SPI transfer setup failed\n");
-		return ret;
-	}
-
-	if (spi->cur_usedma)
-		return stm32h7_spi_transfer_one_dma(spi, transfer);
-	else
-		return stm32h7_spi_transfer_one_irq(spi);
-}
-
-/**
- * stm32h7_spi_unprepare_msg - relax the hardware
- *
- * Normally, if TSIZE has been configured, we should relax the hardware at the
- * reception of the EOT interrupt. But in case of error, EOT will not be
- * raised. So the subsystem unprepare_message call allows us to properly
- * complete the transfer from an hardware point of view.
- */
-static int stm32h7_spi_unprepare_msg(struct spi_master *master,
-				     struct spi_message *msg)
-{
-	struct stm32h7_spi *spi = spi_master_get_devdata(master);
-
-	stm32h7_spi_disable(spi);
-
-	return 0;
-}
-
-/**
- * stm32h7_spi_config - Configure SPI controller as SPI master
- */
-static int stm32h7_spi_config(struct stm32h7_spi *spi)
-{
-	unsigned long flags;
-
-	spin_lock_irqsave(&spi->lock, flags);
-
-	/* Ensure I2SMOD bit is kept cleared */
-	stm32h7_spi_clr_bits(spi, STM32H7_SPI_I2SCFGR,
-			     STM32H7_SPI_I2SCFGR_I2SMOD);
-
-	/*
-	 * - SS input value high
-	 * - transmitter half duplex direction
-	 * - automatic communication suspend when RX-Fifo is full
-	 */
-	stm32h7_spi_set_bits(spi, STM32H7_SPI_CR1, STM32H7_SPI_CR1_SSI |
-						   STM32H7_SPI_CR1_HDDIR |
-						   STM32H7_SPI_CR1_MASRX);
-
-	/*
-	 * - Set the master mode (default Motorola mode)
-	 * - Consider 1 master/n slaves configuration and
-	 *   SS input value is determined by the SSI bit
-	 * - keep control of all associated GPIOs
-	 */
-	stm32h7_spi_set_bits(spi, STM32H7_SPI_CFG2, STM32H7_SPI_CFG2_MASTER |
-						    STM32H7_SPI_CFG2_SSM |
-						    STM32H7_SPI_CFG2_AFCNTR);
-
-	spin_unlock_irqrestore(&spi->lock, flags);
-
-	return 0;
-}
-
-static const struct of_device_id stm32h7_spi_of_match[] = {
-	{ .compatible = "st,stm32h7-spi", },
-	{},
-};
-MODULE_DEVICE_TABLE(of, stm32h7_spi_of_match);
-
-static int stm32h7_spi_probe(struct platform_device *pdev)
-{
-	struct spi_master *master;
-	struct stm32h7_spi *spi;
-	struct resource *res;
-	int i, ret;
-
-	master = spi_alloc_master(&pdev->dev, sizeof(struct stm32h7_spi));
-	if (!master) {
-		dev_err(&pdev->dev, "spi master allocation failed\n");
-		return -ENOMEM;
-	}
-	platform_set_drvdata(pdev, master);
-
-	spi = spi_master_get_devdata(master);
-	spi->dev = &pdev->dev;
-	spi->master = master;
-	spin_lock_init(&spi->lock);
-
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	spi->base = devm_ioremap_resource(&pdev->dev, res);
-	if (IS_ERR(spi->base)) {
-		ret = PTR_ERR(spi->base);
-		goto err_master_put;
-	}
-	spi->phys_addr = (dma_addr_t)res->start;
-
-	spi->irq = platform_get_irq(pdev, 0);
-	if (spi->irq <= 0) {
-		dev_err(&pdev->dev, "no irq: %d\n", spi->irq);
-		ret = -ENOENT;
-		goto err_master_put;
-	}
-	ret = devm_request_threaded_irq(&pdev->dev, spi->irq, NULL,
-					stm32h7_spi_irq, IRQF_ONESHOT,
-					pdev->name, master);
-	if (ret) {
-		dev_err(&pdev->dev, "irq%d request failed: %d\n", spi->irq,
-			ret);
-		goto err_master_put;
-	}
-
-	spi->clk = devm_clk_get(&pdev->dev, 0);
-	if (IS_ERR(spi->clk)) {
-		ret = PTR_ERR(spi->clk);
-		dev_err(&pdev->dev, "clk get failed: %d\n", ret);
-		goto err_master_put;
-	}
-
-	ret = clk_prepare_enable(spi->clk);
-	if (ret) {
-		dev_err(&pdev->dev, "clk enable failed: %d\n", ret);
-		goto err_master_put;
-	}
-	spi->clk_rate = clk_get_rate(spi->clk);
-	if (!spi->clk_rate) {
-		dev_err(&pdev->dev, "clk rate = 0\n");
-		ret = -EINVAL;
-		goto err_clk_disable;
-	}
-
-	spi->rst = devm_reset_control_get_exclusive(&pdev->dev, NULL);
-	if (!IS_ERR(spi->rst)) {
-		reset_control_assert(spi->rst);
-		udelay(2);
-		reset_control_deassert(spi->rst);
-	}
-
-	spi->fifo_size = stm32h7_spi_get_fifo_size(spi);
-
-	ret = stm32h7_spi_config(spi);
-	if (ret) {
-		dev_err(&pdev->dev, "controller configuration failed: %d\n",
-			ret);
-		goto err_clk_disable;
-	}
-
-	master->dev.of_node = pdev->dev.of_node;
-	master->auto_runtime_pm = true;
-	master->bus_num = pdev->id;
-	master->mode_bits = SPI_MODE_3 | SPI_CS_HIGH | SPI_LSB_FIRST |
-			    SPI_3WIRE | SPI_LOOP;
-	master->bits_per_word_mask = stm32h7_spi_get_bpw_mask(spi);
-	master->max_speed_hz = spi->clk_rate / STM32H7_SPI_MBR_DIV_MIN;
-	master->min_speed_hz = spi->clk_rate / STM32H7_SPI_MBR_DIV_MAX;
-	master->setup = stm32h7_spi_setup;
-	master->prepare_message = stm32h7_spi_prepare_msg;
-	master->transfer_one = stm32h7_spi_transfer_one;
-	master->unprepare_message = stm32h7_spi_unprepare_msg;
-
-	spi->dma_tx = dma_request_slave_channel(spi->dev, "tx");
-	if (!spi->dma_tx)
-		dev_warn(&pdev->dev, "failed to request tx dma channel\n");
-	else
-		master->dma_tx = spi->dma_tx;
-
-	spi->dma_rx = dma_request_slave_channel(spi->dev, "rx");
-	if (!spi->dma_rx)
-		dev_warn(&pdev->dev, "failed to request rx dma channel\n");
-	else
-		master->dma_rx = spi->dma_rx;
-
-	if (spi->dma_tx || spi->dma_rx)
-		master->can_dma = stm32h7_spi_can_dma;
-
-	pm_runtime_set_active(&pdev->dev);
-	pm_runtime_enable(&pdev->dev);
-
-	ret = devm_spi_register_master(&pdev->dev, master);
-	if (ret) {
-		dev_err(&pdev->dev, "spi master registration failed: %d\n",
-			ret);
-		goto err_dma_release;
-	}
-
-	if (!master->cs_gpios) {
-		dev_err(&pdev->dev, "no CS gpios available\n");
-		ret = -EINVAL;
-		goto err_dma_release;
-	}
-
-	for (i = 0; i < master->num_chipselect; i++) {
-		if (!gpio_is_valid(master->cs_gpios[i])) {
-			dev_err(&pdev->dev, "%i is not a valid gpio\n",
-				master->cs_gpios[i]);
-			ret = -EINVAL;
-			goto err_dma_release;
-		}
-
-		ret = devm_gpio_request(&pdev->dev, master->cs_gpios[i],
-					DRIVER_NAME);
-		if (ret) {
-			dev_err(&pdev->dev, "can't get CS gpio %i\n",
-				master->cs_gpios[i]);
-			goto err_dma_release;
-		}
-	}
-
-	dev_info(&pdev->dev, "driver initialized\n");
-
-	return 0;
-
-err_dma_release:
-	if (spi->dma_tx)
-		dma_release_channel(spi->dma_tx);
-	if (spi->dma_rx)
-		dma_release_channel(spi->dma_rx);
-
-	pm_runtime_disable(&pdev->dev);
-err_clk_disable:
-	clk_disable_unprepare(spi->clk);
-err_master_put:
-	spi_master_put(master);
-
-	return ret;
-}
-
-static int stm32h7_spi_remove(struct platform_device *pdev)
-{
-	struct spi_master *master = platform_get_drvdata(pdev);
-	struct stm32h7_spi *spi = spi_master_get_devdata(master);
-
-	stm32h7_spi_disable(spi);
-
-	if (master->dma_tx)
-		dma_release_channel(master->dma_tx);
-	if (master->dma_rx)
-		dma_release_channel(master->dma_rx);
-
-	clk_disable_unprepare(spi->clk);
-
-	pm_runtime_disable(&pdev->dev);
-
-	return 0;
-}
-
-#ifdef CONFIG_PM
-static int stm32h7_spi_runtime_suspend(struct device *dev)
-{
-	struct spi_master *master = dev_get_drvdata(dev);
-	struct stm32h7_spi *spi = spi_master_get_devdata(master);
-
-	clk_disable_unprepare(spi->clk);
-
-	return 0;
-}
-
-static int stm32h7_spi_runtime_resume(struct device *dev)
-{
-	struct spi_master *master = dev_get_drvdata(dev);
-	struct stm32h7_spi *spi = spi_master_get_devdata(master);
-
-	return clk_prepare_enable(spi->clk);
-}
-#endif
-
-#ifdef CONFIG_PM_SLEEP
-static int stm32h7_spi_suspend(struct device *dev)
-{
-	struct spi_master *master = dev_get_drvdata(dev);
-	int ret;
-
-	ret = spi_master_suspend(master);
-	if (ret)
-		return ret;
-
-	return pm_runtime_force_suspend(dev);
-}
-
-static int stm32h7_spi_resume(struct device *dev)
-{
-	struct spi_master *master = dev_get_drvdata(dev);
-	struct stm32h7_spi *spi = spi_master_get_devdata(master);
-	int ret;
-
-	ret = pm_runtime_force_resume(dev);
-	if (ret)
-		return ret;
-
-	ret = spi_master_resume(master);
-	if (ret)
-		clk_disable_unprepare(spi->clk);
-
-	return ret;
-}
-#endif
-
-static const struct dev_pm_ops stm32h7_spi_pm_ops = {
-	SET_SYSTEM_SLEEP_PM_OPS(stm32h7_spi_suspend, stm32h7_spi_resume)
-	SET_RUNTIME_PM_OPS(stm32h7_spi_runtime_suspend,
-			   stm32h7_spi_runtime_resume, NULL)
-};
-
-static struct platform_driver stm32h7_spi_driver = {
-	.probe = stm32h7_spi_probe,
-	.remove = stm32h7_spi_remove,
-	.driver = {
-		.name = DRIVER_NAME,
-		.pm = &stm32h7_spi_pm_ops,
-		.of_match_table = stm32h7_spi_of_match,
-	},
-};
-
-module_platform_driver(stm32h7_spi_driver);
-
-MODULE_ALIAS("platform:" DRIVER_NAME);
-MODULE_DESCRIPTION("STMicroelectronics STM32 SPI Controller driver");
-MODULE_AUTHOR("Amelie Delaunay <amelie.delaunay@st.com>");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/spi/spi-stm32h7.c b/drivers/spi/spi-stm32h7.c
new file mode 100644
index 0000000..4ae3e94
--- /dev/null
+++ b/drivers/spi/spi-stm32h7.c
@@ -0,0 +1,1340 @@
+/*
+ * STMicroelectronics STM32H7 SPI Controller driver (master mode only)
+ *
+ * Copyright (C) 2017, STMicroelectronics - All Rights Reserved
+ * Author(s): Amelie Delaunay <amelie.delaunay@st.com> for STMicroelectronics.
+ *
+ * License terms: GPL V2.0.
+ *
+ * spi_stm32h7 driver 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.
+ *
+ * spi_stm32h7 driver is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * spi_stm32h7 driver. If not, see <http://www.gnu.org/licenses/>.
+ */
+#include <linux/debugfs.h>
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/dmaengine.h>
+#include <linux/gpio.h>
+#include <linux/interrupt.h>
+#include <linux/iopoll.h>
+#include <linux/module.h>
+#include <linux/of_platform.h>
+#include <linux/pm_runtime.h>
+#include <linux/reset.h>
+#include <linux/spi/spi.h>
+
+#define DRIVER_NAME "spi_stm32h7"
+
+/* STM32H7 SPI registers */
+#define STM32H7_SPI_CR1			0x00
+#define STM32H7_SPI_CR2			0x04
+#define STM32H7_SPI_CFG1		0x08
+#define STM32H7_SPI_CFG2		0x0C
+#define STM32H7_SPI_IER			0x10
+#define STM32H7_SPI_SR			0x14
+#define STM32H7_SPI_IFCR		0x18
+#define STM32H7_SPI_TXDR		0x20
+#define STM32H7_SPI_RXDR		0x30
+#define STM32H7_SPI_I2SCFGR		0x50
+
+/* STM32H7_SPI_CR1 bit fields */
+#define STM32H7_SPI_CR1_SPE		BIT(0)
+#define STM32H7_SPI_CR1_MASRX		BIT(8)
+#define STM32H7_SPI_CR1_CSTART		BIT(9)
+#define STM32H7_SPI_CR1_CSUSP		BIT(10)
+#define STM32H7_SPI_CR1_HDDIR		BIT(11)
+#define STM32H7_SPI_CR1_SSI		BIT(12)
+
+/* STM32H7_SPI_CR2 bit fields */
+#define STM32H7_SPI_CR2_TSIZE_SHIFT	0
+#define STM32H7_SPI_CR2_TSIZE		GENMASK(15, 0)
+
+/* STM32H7_SPI_CFG1 bit fields */
+#define STM32H7_SPI_CFG1_DSIZE_SHIFT	0
+#define STM32H7_SPI_CFG1_DSIZE		GENMASK(4, 0)
+#define STM32H7_SPI_CFG1_FTHLV_SHIFT	5
+#define STM32H7_SPI_CFG1_FTHLV		GENMASK(8, 5)
+#define STM32H7_SPI_CFG1_RXDMAEN	BIT(14)
+#define STM32H7_SPI_CFG1_TXDMAEN	BIT(15)
+#define STM32H7_SPI_CFG1_MBR_SHIFT	28
+#define STM32H7_SPI_CFG1_MBR		GENMASK(30, 28)
+#define STM32H7_SPI_CFG1_MBR_MIN	0
+#define STM32H7_SPI_CFG1_MBR_MAX	(GENMASK(30, 28) >> 28)
+
+/* STM32H7_SPI_CFG2 bit fields */
+#define STM32H7_SPI_CFG2_MIDI_SHIFT	4
+#define STM32H7_SPI_CFG2_MIDI		GENMASK(7, 4)
+#define STM32H7_SPI_CFG2_COMM_SHIFT	17
+#define STM32H7_SPI_CFG2_COMM		GENMASK(18, 17)
+#define STM32H7_SPI_CFG2_SP_SHIFT	19
+#define STM32H7_SPI_CFG2_SP		GENMASK(21, 19)
+#define STM32H7_SPI_CFG2_MASTER		BIT(22)
+#define STM32H7_SPI_CFG2_LSBFRST	BIT(23)
+#define STM32H7_SPI_CFG2_CPHA		BIT(24)
+#define STM32H7_SPI_CFG2_CPOL		BIT(25)
+#define STM32H7_SPI_CFG2_SSM		BIT(26)
+#define STM32H7_SPI_CFG2_AFCNTR		BIT(31)
+
+/* STM32H7_SPI_IER bit fields */
+#define STM32H7_SPI_IER_RXPIE		BIT(0)
+#define STM32H7_SPI_IER_TXPIE		BIT(1)
+#define STM32H7_SPI_IER_DXPIE		BIT(2)
+#define STM32H7_SPI_IER_EOTIE		BIT(3)
+#define STM32H7_SPI_IER_TXTFIE		BIT(4)
+#define STM32H7_SPI_IER_OVRIE		BIT(6)
+#define STM32H7_SPI_IER_MODFIE		BIT(9)
+#define STM32H7_SPI_IER_ALL		GENMASK(10, 0)
+
+/* STM32H7_SPI_SR bit fields */
+#define STM32H7_SPI_SR_RXP		BIT(0)
+#define STM32H7_SPI_SR_TXP		BIT(1)
+#define STM32H7_SPI_SR_EOT		BIT(3)
+#define STM32H7_SPI_SR_OVR		BIT(6)
+#define STM32H7_SPI_SR_MODF		BIT(9)
+#define STM32H7_SPI_SR_SUSP		BIT(11)
+#define STM32H7_SPI_SR_RXPLVL_SHIFT	13
+#define STM32H7_SPI_SR_RXPLVL		GENMASK(14, 13)
+#define STM32H7_SPI_SR_RXWNE		BIT(15)
+
+/* STM32H7_SPI_IFCR bit fields */
+#define STM32H7_SPI_IFCR_ALL		GENMASK(11, 3)
+
+/* STM32H7_SPI_I2SCFGR bit fields */
+#define STM32H7_SPI_I2SCFGR_I2SMOD	BIT(0)
+
+/* STM32H7 SPI Master Baud Rate min/max divisor */
+#define STM32H7_SPI_MBR_DIV_MIN		(2 << STM32H7_SPI_CFG1_MBR_MIN)
+#define STM32H7_SPI_MBR_DIV_MAX		(2 << STM32H7_SPI_CFG1_MBR_MAX)
+
+/* STM32H7 SPI Communication mode */
+#define STM32H7_SPI_FULL_DUPLEX		0
+#define STM32H7_SPI_SIMPLEX_TX		1
+#define STM32H7_SPI_SIMPLEX_RX		2
+#define STM32H7_SPI_HALF_DUPLEX		3
+
+#define STM32H7_SPI_1HZ_NS		1000000000
+
+/**
+ * struct stm32h7_spi - private data of the SPI controller
+ * @dev: driver model representation of the controller
+ * @master: controller master interface
+ * @base: virtual memory area
+ * @clk: hw kernel clock feeding the SPI clock generator
+ * @clk_rate: rate of the hw kernel clock feeding the SPI clock generator
+ * @rst: SPI controller reset line
+ * @lock: prevent I/O concurrent access
+ * @irq: SPI controller interrupt line
+ * @fifo_size: size of the embedded fifo in bytes
+ * @cur_midi: master inter-data idleness in ns
+ * @cur_speed: speed configured in Hz
+ * @cur_bpw: number of bits in a single SPI data frame
+ * @cur_fthlv: fifo threshold level (data frames in a single data packet)
+ * @cur_comm: SPI communication mode
+ * @cur_xferlen: current transfer length in bytes
+ * @cur_usedma: boolean to know if dma is used in current transfer
+ * @tx_buf: data to be written, or NULL
+ * @rx_buf: data to be read, or NULL
+ * @tx_len: number of data to be written in bytes
+ * @rx_len: number of data to be read in bytes
+ * @dma_tx: dma channel for TX transfer
+ * @dma_rx: dma channel for RX transfer
+ * @phys_addr: SPI registers physical base address
+ */
+struct stm32h7_spi {
+	struct device *dev;
+	struct spi_master *master;
+	void __iomem *base;
+	struct clk *clk;
+	u32 clk_rate;
+	struct reset_control *rst;
+	spinlock_t lock; /* prevent I/O concurrent access */
+	int irq;
+	unsigned int fifo_size;
+
+	unsigned int cur_midi;
+	unsigned int cur_speed;
+	unsigned int cur_bpw;
+	unsigned int cur_fthlv;
+	unsigned int cur_comm;
+	unsigned int cur_xferlen;
+	bool cur_usedma;
+
+	const void *tx_buf;
+	void *rx_buf;
+	int tx_len;
+	int rx_len;
+	struct dma_chan *dma_tx;
+	struct dma_chan *dma_rx;
+	dma_addr_t phys_addr;
+};
+
+static inline void stm32h7_spi_set_bits(struct stm32h7_spi *spi,
+					u32 offset, u32 bits)
+{
+	writel_relaxed(readl_relaxed(spi->base + offset) | bits,
+		       spi->base + offset);
+}
+
+static inline void stm32h7_spi_clr_bits(struct stm32h7_spi *spi,
+					u32 offset, u32 bits)
+{
+	writel_relaxed(readl_relaxed(spi->base + offset) & ~bits,
+		       spi->base + offset);
+}
+
+/**
+ * stm32h7_spi_get_fifo_size - Return fifo size
+ * @spi: pointer to the spi controller data structure
+ */
+static int stm32h7_spi_get_fifo_size(struct stm32h7_spi *spi)
+{
+	unsigned long flags;
+	u32 count = 0;
+
+	spin_lock_irqsave(&spi->lock, flags);
+
+	stm32h7_spi_set_bits(spi, STM32H7_SPI_CR1, STM32H7_SPI_CR1_SPE);
+
+	while (readl_relaxed(spi->base + STM32H7_SPI_SR) & STM32H7_SPI_SR_TXP)
+		writeb_relaxed(++count, spi->base + STM32H7_SPI_TXDR);
+
+	stm32h7_spi_clr_bits(spi, STM32H7_SPI_CR1, STM32H7_SPI_CR1_SPE);
+
+	spin_unlock_irqrestore(&spi->lock, flags);
+
+	dev_dbg(spi->dev, "%d x 8-bit fifo size\n", count);
+
+	return count;
+}
+
+/**
+ * stm32h7_spi_get_bpw_mask - Return bits per word mask
+ * @spi: pointer to the spi controller data structure
+ */
+static int stm32h7_spi_get_bpw_mask(struct stm32h7_spi *spi)
+{
+	unsigned long flags;
+	u32 cfg1, max_bpw;
+
+	spin_lock_irqsave(&spi->lock, flags);
+
+	/*
+	 * The most significant bit at DSIZE bit field is reserved when the
+	 * maximum data size of periperal instances is limited to 16-bit
+	 */
+	stm32h7_spi_set_bits(spi, STM32H7_SPI_CFG1, STM32H7_SPI_CFG1_DSIZE);
+
+	cfg1 = readl_relaxed(spi->base + STM32H7_SPI_CFG1);
+	max_bpw = (cfg1 & STM32H7_SPI_CFG1_DSIZE) >>
+		  STM32H7_SPI_CFG1_DSIZE_SHIFT;
+	max_bpw += 1;
+
+	spin_unlock_irqrestore(&spi->lock, flags);
+
+	dev_dbg(spi->dev, "%d-bit maximum data frame\n", max_bpw);
+
+	return SPI_BPW_RANGE_MASK(4, max_bpw);
+}
+
+/**
+ * stm32h7_spi_prepare_mbr - Determine STM32H7_SPI_CFG1.MBR value
+ * @spi: pointer to the spi controller data structure
+ * @speed_hz: requested speed
+ *
+ * Return STM32H7_SPI_CFG1.MBR value in case of success or -EINVAL
+ */
+static int stm32h7_spi_prepare_mbr(struct stm32h7_spi *spi, u32 speed_hz)
+{
+	u32 div, mbrdiv;
+
+	div = DIV_ROUND_UP(spi->clk_rate, speed_hz);
+
+	/*
+	 * SPI framework set xfer->speed_hz to master->max_speed_hz if
+	 * xfer->speed_hz is greater than master->max_speed_hz, and it returns
+	 * an error when xfer->speed_hz is lower than master->min_speed_hz, so
+	 * no need to check it there.
+	 * However, we need to ensure the following calculations.
+	 */
+	if (div < STM32H7_SPI_MBR_DIV_MIN ||
+	    div > STM32H7_SPI_MBR_DIV_MAX)
+		return -EINVAL;
+
+	/* Determine the first power of 2 greater than or equal to div */
+	if (div & (div - 1))
+		mbrdiv = fls(div);
+	else
+		mbrdiv = fls(div) - 1;
+
+	spi->cur_speed = spi->clk_rate / (1 << mbrdiv);
+
+	return mbrdiv - 1;
+}
+
+/**
+ * stm32h7_spi_prepare_fthlv - Determine FIFO threshold level
+ * @spi: pointer to the spi controller data structure
+ */
+static u32 stm32h7_spi_prepare_fthlv(struct stm32h7_spi *spi)
+{
+	u32 fthlv, half_fifo;
+
+	/* data packet should not exceed 1/2 of fifo space */
+	half_fifo = (spi->fifo_size / 2);
+
+	if (spi->cur_bpw <= 8)
+		fthlv = half_fifo;
+	else if (spi->cur_bpw <= 16)
+		fthlv = half_fifo / 2;
+	else
+		fthlv = half_fifo / 4;
+
+	/* align packet size with data registers access */
+	if (spi->cur_bpw > 8)
+		fthlv -= (fthlv % 2); /* multiple of 2 */
+	else
+		fthlv -= (fthlv % 4); /* multiple of 4 */
+
+	return fthlv;
+}
+
+/**
+ * stm32h7_spi_write_txfifo - Write bytes in Transmit Data Register
+ * @spi: pointer to the spi controller data structure
+ *
+ * Read from tx_buf depends on remaining bytes to avoid to read beyond
+ * tx_buf end.
+ */
+static void stm32h7_spi_write_txfifo(struct stm32h7_spi *spi)
+{
+	while ((spi->tx_len > 0) &&
+	       (readl_relaxed(spi->base + STM32H7_SPI_SR) &
+		STM32H7_SPI_SR_TXP)) {
+		u32 offs = spi->cur_xferlen - spi->tx_len;
+
+		if (spi->tx_len >= sizeof(u32)) {
+			const u32 *tx_buf32 = (const u32 *)(spi->tx_buf + offs);
+
+			writel_relaxed(*tx_buf32, spi->base + STM32H7_SPI_TXDR);
+			spi->tx_len -= sizeof(u32);
+		} else if (spi->tx_len >= sizeof(u16)) {
+			const u16 *tx_buf16 = (const u16 *)(spi->tx_buf + offs);
+
+			writew_relaxed(*tx_buf16, spi->base + STM32H7_SPI_TXDR);
+			spi->tx_len -= sizeof(u16);
+		} else {
+			const u8 *tx_buf8 = (const u8 *)(spi->tx_buf + offs);
+
+			writeb_relaxed(*tx_buf8, spi->base + STM32H7_SPI_TXDR);
+			spi->tx_len -= sizeof(u8);
+		}
+	}
+
+	dev_dbg(spi->dev, "%s: %d bytes left\n", __func__, spi->tx_len);
+}
+
+/**
+ * stm32h7_spi_read_rxfifo - Read bytes in Receive Data Register
+ * @spi: pointer to the spi controller data structure
+ *
+ * Write in rx_buf depends on remaining bytes to avoid to write beyond
+ * rx_buf end.
+ */
+static void stm32h7_spi_read_rxfifo(struct stm32h7_spi *spi, bool flush)
+{
+	u32 sr = readl_relaxed(spi->base + STM32H7_SPI_SR);
+	u32 rxplvl = (sr & STM32H7_SPI_SR_RXPLVL) >>
+		     STM32H7_SPI_SR_RXPLVL_SHIFT;
+
+	while ((spi->rx_len > 0) &&
+	       ((sr & STM32H7_SPI_SR_RXP) ||
+		(flush && ((sr & STM32H7_SPI_SR_RXWNE) || (rxplvl > 0))))) {
+		u32 offs = spi->cur_xferlen - spi->rx_len;
+
+		if ((spi->rx_len >= sizeof(u32)) ||
+		    (flush && (sr & STM32H7_SPI_SR_RXWNE))) {
+			u32 *rx_buf32 = (u32 *)(spi->rx_buf + offs);
+
+			*rx_buf32 = readl_relaxed(spi->base + STM32H7_SPI_RXDR);
+			spi->rx_len -= sizeof(u32);
+		} else if ((spi->rx_len >= sizeof(u16)) ||
+			   (flush && (rxplvl >= 2 || spi->cur_bpw > 8))) {
+			u16 *rx_buf16 = (u16 *)(spi->rx_buf + offs);
+
+			*rx_buf16 = readw_relaxed(spi->base + STM32H7_SPI_RXDR);
+			spi->rx_len -= sizeof(u16);
+		} else {
+			u8 *rx_buf8 = (u8 *)(spi->rx_buf + offs);
+
+			*rx_buf8 = readb_relaxed(spi->base + STM32H7_SPI_RXDR);
+			spi->rx_len -= sizeof(u8);
+		}
+
+		sr = readl_relaxed(spi->base + STM32H7_SPI_SR);
+		rxplvl = (sr & STM32H7_SPI_SR_RXPLVL) >>
+			 STM32H7_SPI_SR_RXPLVL_SHIFT;
+	}
+
+	dev_dbg(spi->dev, "%s%s: %d bytes left\n", __func__,
+		flush ? "(flush)" : "", spi->rx_len);
+}
+
+/**
+ * stm32h7_spi_enable - Enable SPI controller
+ * @spi: pointer to the spi controller data structure
+ *
+ * SPI data transfer is enabled but spi_ker_ck is idle.
+ * STM32H7_SPI_CFG1 and STM32H7_SPI_CFG2 are now write protected.
+ */
+static void stm32h7_spi_enable(struct stm32h7_spi *spi)
+{
+	dev_dbg(spi->dev, "enable controller\n");
+
+	stm32h7_spi_set_bits(spi, STM32H7_SPI_CR1, STM32H7_SPI_CR1_SPE);
+}
+
+/**
+ * stm32h7_spi_disable - Disable SPI controller
+ * @spi: pointer to the spi controller data structure
+ *
+ * RX-Fifo is flushed when SPI controller is disabled. To prevent any data
+ * loss, use stm32h7_spi_read_rxfifo(flush) to read the remaining bytes in
+ * RX-Fifo.
+ */
+static void stm32h7_spi_disable(struct stm32h7_spi *spi)
+{
+	unsigned long flags;
+	u32 cr1, sr;
+
+	dev_dbg(spi->dev, "disable controller\n");
+
+	spin_lock_irqsave(&spi->lock, flags);
+
+	cr1 = readl_relaxed(spi->base + STM32H7_SPI_CR1);
+
+	if (!(cr1 & STM32H7_SPI_CR1_SPE)) {
+		spin_unlock_irqrestore(&spi->lock, flags);
+		return;
+	}
+
+	/* Wait on EOT or suspend the flow */
+	if (readl_relaxed_poll_timeout_atomic(spi->base + STM32H7_SPI_SR,
+					      sr, !(sr & STM32H7_SPI_SR_EOT),
+					      10, 100000) < 0) {
+		if (cr1 & STM32H7_SPI_CR1_CSTART) {
+			writel_relaxed(cr1 | STM32H7_SPI_CR1_CSUSP,
+				       spi->base + STM32H7_SPI_CR1);
+			if (readl_relaxed_poll_timeout_atomic(
+						spi->base + STM32H7_SPI_SR,
+						sr, !(sr & STM32H7_SPI_SR_SUSP),
+						10, 100000) < 0)
+				dev_warn(spi->dev,
+					 "Suspend request timeout\n");
+		}
+	}
+
+	if (!spi->cur_usedma && spi->rx_buf && (spi->rx_len > 0))
+		stm32h7_spi_read_rxfifo(spi, true);
+
+	if (spi->cur_usedma && spi->tx_buf)
+		dmaengine_terminate_all(spi->dma_tx);
+	if (spi->cur_usedma && spi->rx_buf)
+		dmaengine_terminate_all(spi->dma_rx);
+
+	stm32h7_spi_clr_bits(spi, STM32H7_SPI_CR1, STM32H7_SPI_CR1_SPE);
+
+	stm32h7_spi_clr_bits(spi, STM32H7_SPI_CFG1, STM32H7_SPI_CFG1_TXDMAEN |
+						    STM32H7_SPI_CFG1_RXDMAEN);
+
+	/* Disable interrupts and clear status flags */
+	writel_relaxed(0, spi->base + STM32H7_SPI_IER);
+	writel_relaxed(STM32H7_SPI_IFCR_ALL, spi->base + STM32H7_SPI_IFCR);
+
+	spin_unlock_irqrestore(&spi->lock, flags);
+}
+
+/**
+ * stm32h7_spi_can_dma - Determine if the transfer is eligible for DMA use
+ *
+ * If the current transfer size is greater than fifo size, use DMA.
+ */
+static bool stm32h7_spi_can_dma(struct spi_master *master,
+				struct spi_device *spi_dev,
+				struct spi_transfer *transfer)
+{
+	struct stm32h7_spi *spi = spi_master_get_devdata(master);
+
+	dev_dbg(spi->dev, "%s: %s\n", __func__,
+		(transfer->len > spi->fifo_size) ? "true" : "false");
+
+	return (transfer->len > spi->fifo_size);
+}
+
+/**
+ * stm32h7_spi_irq - Interrupt handler for SPI controller events
+ * @irq: interrupt line
+ * @dev_id: SPI controller master interface
+ */
+static irqreturn_t stm32h7_spi_irq(int irq, void *dev_id)
+{
+	struct spi_master *master = dev_id;
+	struct stm32h7_spi *spi = spi_master_get_devdata(master);
+	u32 sr, ier, mask;
+	unsigned long flags;
+	bool end = false;
+
+	spin_lock_irqsave(&spi->lock, flags);
+
+	sr = readl_relaxed(spi->base + STM32H7_SPI_SR);
+	ier = readl_relaxed(spi->base + STM32H7_SPI_IER);
+
+	mask = ier;
+	/* EOTIE is triggered on EOT, SUSP and TXC events. */
+	mask |= STM32H7_SPI_SR_SUSP;
+	/*
+	 * When TXTF is set, DXPIE and TXPIE are cleared. So in case of
+	 * Full-Duplex, need to poll RXP event to know if there are remaining
+	 * data, before disabling SPI.
+	 */
+	if (spi->rx_buf && !spi->cur_usedma)
+		mask |= STM32H7_SPI_SR_RXP;
+
+	if (!(sr & mask)) {
+		dev_dbg(spi->dev, "spurious IT (sr=0x%08x, ier=0x%08x)\n",
+			sr, ier);
+		spin_unlock_irqrestore(&spi->lock, flags);
+		return IRQ_NONE;
+	}
+
+	if (sr & STM32H7_SPI_SR_SUSP) {
+		dev_warn(spi->dev, "Communication suspended\n");
+		if (!spi->cur_usedma && (spi->rx_buf && (spi->rx_len > 0)))
+			stm32h7_spi_read_rxfifo(spi, false);
+		/*
+		 * If communication is suspended while using DMA, it means
+		 * that something went wrong, so stop the current transfer
+		 */
+		if (spi->cur_usedma)
+			end = true;
+	}
+
+	if (sr & STM32H7_SPI_SR_MODF) {
+		dev_warn(spi->dev, "Mode fault: transfer aborted\n");
+		end = true;
+	}
+
+	if (sr & STM32H7_SPI_SR_OVR) {
+		dev_warn(spi->dev, "Overrun: received value discarded\n");
+		if (!spi->cur_usedma && (spi->rx_buf && (spi->rx_len > 0)))
+			stm32h7_spi_read_rxfifo(spi, false);
+		/*
+		 * If overrun is detected while using DMA, it means that
+		 * something went wrong, so stop the current transfer
+		 */
+		if (spi->cur_usedma)
+			end = true;
+	}
+
+	if (sr & STM32H7_SPI_SR_EOT) {
+		if (!spi->cur_usedma && (spi->rx_buf && (spi->rx_len > 0)))
+			stm32h7_spi_read_rxfifo(spi, true);
+		end = true;
+	}
+
+	if (sr & STM32H7_SPI_SR_TXP)
+		if (!spi->cur_usedma && (spi->tx_buf && (spi->tx_len > 0)))
+			stm32h7_spi_write_txfifo(spi);
+
+	if (sr & STM32H7_SPI_SR_RXP)
+		if (!spi->cur_usedma && (spi->rx_buf && (spi->rx_len > 0)))
+			stm32h7_spi_read_rxfifo(spi, false);
+
+	writel_relaxed(mask, spi->base + STM32H7_SPI_IFCR);
+
+	spin_unlock_irqrestore(&spi->lock, flags);
+
+	if (end) {
+		spi_finalize_current_transfer(master);
+		stm32h7_spi_disable(spi);
+	}
+
+	return IRQ_HANDLED;
+}
+
+/**
+ * stm32h7_spi_setup - setup device chip select
+ */
+static int stm32h7_spi_setup(struct spi_device *spi_dev)
+{
+	int ret = 0;
+
+	if (!gpio_is_valid(spi_dev->cs_gpio)) {
+		dev_err(&spi_dev->dev, "%d is not a valid gpio\n",
+			spi_dev->cs_gpio);
+		return -EINVAL;
+	}
+
+	dev_dbg(&spi_dev->dev, "%s: set gpio%d output %s\n", __func__,
+		spi_dev->cs_gpio,
+		(spi_dev->mode & SPI_CS_HIGH) ? "low" : "high");
+
+	ret = gpio_direction_output(spi_dev->cs_gpio,
+				    !(spi_dev->mode & SPI_CS_HIGH));
+
+	return ret;
+}
+
+/**
+ * stm32h7_spi_prepare_msg - set up the controller to transfer a single message
+ */
+static int stm32h7_spi_prepare_msg(struct spi_master *master,
+				   struct spi_message *msg)
+{
+	struct stm32h7_spi *spi = spi_master_get_devdata(master);
+	struct spi_device *spi_dev = msg->spi;
+	struct device_node *np = spi_dev->dev.of_node;
+	unsigned long flags;
+	u32 cfg2_clrb = 0, cfg2_setb = 0;
+
+	/* SPI slave device may need time between data frames */
+	spi->cur_midi = 0;
+	if (np && !of_property_read_u32(np, "st,spi-midi-ns", &spi->cur_midi))
+		dev_dbg(spi->dev, "%dns inter-data idleness\n", spi->cur_midi);
+
+	if (spi_dev->mode & SPI_CPOL)
+		cfg2_setb |= STM32H7_SPI_CFG2_CPOL;
+	else
+		cfg2_clrb |= STM32H7_SPI_CFG2_CPOL;
+
+	if (spi_dev->mode & SPI_CPHA)
+		cfg2_setb |= STM32H7_SPI_CFG2_CPHA;
+	else
+		cfg2_clrb |= STM32H7_SPI_CFG2_CPHA;
+
+	if (spi_dev->mode & SPI_LSB_FIRST)
+		cfg2_setb |= STM32H7_SPI_CFG2_LSBFRST;
+	else
+		cfg2_clrb |= STM32H7_SPI_CFG2_LSBFRST;
+
+	dev_dbg(spi->dev, "cpol=%d cpha=%d lsb_first=%d cs_high=%d\n",
+		spi_dev->mode & SPI_CPOL,
+		spi_dev->mode & SPI_CPHA,
+		spi_dev->mode & SPI_LSB_FIRST,
+		spi_dev->mode & SPI_CS_HIGH);
+
+	spin_lock_irqsave(&spi->lock, flags);
+
+	if (cfg2_clrb || cfg2_setb)
+		writel_relaxed(
+			(readl_relaxed(spi->base + STM32H7_SPI_CFG2) &
+				~cfg2_clrb) | cfg2_setb,
+			       spi->base + STM32H7_SPI_CFG2);
+
+	spin_unlock_irqrestore(&spi->lock, flags);
+
+	return 0;
+}
+
+/**
+ * stm32h7_spi_dma_cb - dma callback
+ *
+ * DMA callback is called when the transfer is complete or when an error
+ * occurs. If the transfer is complete, EOT flag is raised.
+ */
+static void stm32h7_spi_dma_cb(void *data)
+{
+	struct stm32h7_spi *spi = data;
+	unsigned long flags;
+	u32 sr;
+
+	spin_lock_irqsave(&spi->lock, flags);
+
+	sr = readl_relaxed(spi->base + STM32H7_SPI_SR);
+
+	spin_unlock_irqrestore(&spi->lock, flags);
+
+	if (!(sr & STM32H7_SPI_SR_EOT))
+		dev_warn(spi->dev, "DMA error (sr=0x%08x)\n", sr);
+
+	/* Now wait for EOT, or SUSP or OVR in case of error */
+}
+
+/**
+ * stm32h7_spi_dma_config - configure dma slave channel depending on current
+ *			    transfer bits_per_word.
+ */
+static void stm32h7_spi_dma_config(struct stm32h7_spi *spi,
+				   struct dma_slave_config *dma_conf,
+				   enum dma_transfer_direction dir)
+{
+	enum dma_slave_buswidth buswidth;
+	u32 maxburst;
+
+	if (spi->cur_bpw <= 8)
+		buswidth = DMA_SLAVE_BUSWIDTH_1_BYTE;
+	else if (spi->cur_bpw <= 16)
+		buswidth = DMA_SLAVE_BUSWIDTH_2_BYTES;
+	else
+		buswidth = DMA_SLAVE_BUSWIDTH_4_BYTES;
+
+	/* Valid for DMA Half or Full Fifo threshold */
+	if (spi->cur_fthlv == 2)
+		maxburst = 1;
+	else
+		maxburst = spi->cur_fthlv;
+
+	memset(dma_conf, 0, sizeof(struct dma_slave_config));
+	dma_conf->direction = dir;
+	if (dma_conf->direction == DMA_DEV_TO_MEM) { /* RX */
+		dma_conf->src_addr = spi->phys_addr + STM32H7_SPI_RXDR;
+		dma_conf->src_addr_width = buswidth;
+		dma_conf->src_maxburst = maxburst;
+
+		dev_dbg(spi->dev, "Rx DMA config buswidth=%d, maxburst=%d\n",
+			buswidth, maxburst);
+	} else if (dma_conf->direction == DMA_MEM_TO_DEV) { /* TX */
+		dma_conf->dst_addr = spi->phys_addr + STM32H7_SPI_TXDR;
+		dma_conf->dst_addr_width = buswidth;
+		dma_conf->dst_maxburst = maxburst;
+
+		dev_dbg(spi->dev, "Tx DMA config buswidth=%d, maxburst=%d\n",
+			buswidth, maxburst);
+	}
+}
+
+/**
+ * stm32h7_spi_transfer_one_irq - transfer a single spi_transfer using
+ *				  interrupts
+ *
+ * It must returns 0 if the transfer is finished or 1 if the transfer is still
+ * in progress.
+ */
+static int stm32h7_spi_transfer_one_irq(struct stm32h7_spi *spi)
+{
+	unsigned long flags;
+	u32 ier = 0;
+
+	/* Enable the interrupts relative to the current communication mode */
+	if (spi->tx_buf && spi->rx_buf)	/* Full Duplex */
+		ier |= STM32H7_SPI_IER_DXPIE;
+	else if (spi->tx_buf)		/* Half-Duplex TX dir or Simplex TX */
+		ier |= STM32H7_SPI_IER_TXPIE;
+	else if (spi->rx_buf)		/* Half-Duplex RX dir or Simplex RX */
+		ier |= STM32H7_SPI_IER_RXPIE;
+
+	/* Enable the interrupts relative to the end of transfer */
+	ier |= STM32H7_SPI_IER_EOTIE | STM32H7_SPI_IER_TXTFIE |
+	       STM32H7_SPI_IER_OVRIE | STM32H7_SPI_IER_MODFIE;
+
+	spin_lock_irqsave(&spi->lock, flags);
+
+	stm32h7_spi_enable(spi);
+
+	/* Be sure to have data in fifo before starting data transfer */
+	if (spi->tx_buf)
+		stm32h7_spi_write_txfifo(spi);
+
+	stm32h7_spi_set_bits(spi, STM32H7_SPI_CR1, STM32H7_SPI_CR1_CSTART);
+
+	writel_relaxed(ier, spi->base + STM32H7_SPI_IER);
+
+	spin_unlock_irqrestore(&spi->lock, flags);
+
+	return 1;
+}
+
+/**
+ * stm32h7_spi_transfer_one_dma - transfer a single spi_transfer using DMA
+ *
+ * It must returns 0 if the transfer is finished or 1 if the transfer is still
+ * in progress.
+ */
+static int stm32h7_spi_transfer_one_dma(struct stm32h7_spi *spi,
+					struct spi_transfer *xfer)
+{
+	struct dma_slave_config tx_dma_conf, rx_dma_conf;
+	struct dma_async_tx_descriptor *tx_dma_desc, *rx_dma_desc;
+	unsigned long flags;
+	u32 ier = 0;
+
+	spin_lock_irqsave(&spi->lock, flags);
+
+	rx_dma_desc = NULL;
+	if (spi->rx_buf) {
+		stm32h7_spi_dma_config(spi, &rx_dma_conf, DMA_DEV_TO_MEM);
+		dmaengine_slave_config(spi->dma_rx, &rx_dma_conf);
+
+		/* Enable Rx DMA request */
+		stm32h7_spi_set_bits(spi, STM32H7_SPI_CFG1,
+				   STM32H7_SPI_CFG1_RXDMAEN);
+
+		rx_dma_desc = dmaengine_prep_slave_sg(
+					spi->dma_rx, xfer->rx_sg.sgl,
+					xfer->rx_sg.nents,
+					rx_dma_conf.direction,
+					DMA_PREP_INTERRUPT);
+	}
+
+	tx_dma_desc = NULL;
+	if (spi->tx_buf) {
+		stm32h7_spi_dma_config(spi, &tx_dma_conf, DMA_MEM_TO_DEV);
+		dmaengine_slave_config(spi->dma_tx, &tx_dma_conf);
+
+		tx_dma_desc = dmaengine_prep_slave_sg(
+					spi->dma_tx, xfer->tx_sg.sgl,
+					xfer->tx_sg.nents,
+					tx_dma_conf.direction,
+					DMA_PREP_INTERRUPT);
+	}
+
+	if ((spi->tx_buf && !tx_dma_desc) ||
+	    (spi->rx_buf && !rx_dma_desc))
+		goto dma_desc_error;
+
+	if (rx_dma_desc) {
+		rx_dma_desc->callback = stm32h7_spi_dma_cb;
+		rx_dma_desc->callback_param = spi;
+
+		if (dma_submit_error(dmaengine_submit(rx_dma_desc))) {
+			dev_err(spi->dev, "Rx DMA submit failed\n");
+			goto dma_desc_error;
+		}
+		/* Enable Rx DMA channel */
+		dma_async_issue_pending(spi->dma_rx);
+	}
+
+	if (tx_dma_desc) {
+		if (spi->cur_comm == STM32H7_SPI_SIMPLEX_TX) {
+			tx_dma_desc->callback = stm32h7_spi_dma_cb;
+			tx_dma_desc->callback_param = spi;
+		}
+
+		if (dma_submit_error(dmaengine_submit(tx_dma_desc))) {
+			dev_err(spi->dev, "Tx DMA submit failed\n");
+			goto dma_submit_error;
+		}
+		/* Enable Tx DMA channel */
+		dma_async_issue_pending(spi->dma_tx);
+
+		/* Enable Tx DMA request */
+		stm32h7_spi_set_bits(spi, STM32H7_SPI_CFG1,
+				     STM32H7_SPI_CFG1_TXDMAEN);
+	}
+
+	/* Enable the interrupts relative to the end of transfer */
+	ier |= STM32H7_SPI_IER_EOTIE | STM32H7_SPI_IER_TXTFIE |
+	       STM32H7_SPI_IER_OVRIE | STM32H7_SPI_IER_MODFIE;
+	writel_relaxed(ier, spi->base + STM32H7_SPI_IER);
+
+	stm32h7_spi_enable(spi);
+
+	stm32h7_spi_set_bits(spi, STM32H7_SPI_CR1, STM32H7_SPI_CR1_CSTART);
+
+	spin_unlock_irqrestore(&spi->lock, flags);
+
+	return 1;
+
+dma_submit_error:
+	if (spi->rx_buf)
+		dmaengine_terminate_all(spi->dma_rx);
+
+dma_desc_error:
+	stm32h7_spi_clr_bits(spi, STM32H7_SPI_CFG1, STM32H7_SPI_CFG1_RXDMAEN);
+
+	spin_unlock_irqrestore(&spi->lock, flags);
+
+	dev_info(spi->dev, "DMA issue: fall back to irq transfer\n");
+
+	return stm32h7_spi_transfer_one_irq(spi);
+}
+
+/**
+ * stm32h7_spi_transfer_one_setup - common setup to transfer a single
+ *				    spi_transfer either using DMA or
+ *				    interrupts.
+ */
+static int stm32h7_spi_transfer_one_setup(struct stm32h7_spi *spi,
+					  struct spi_device *spi_dev,
+					  struct spi_transfer *transfer)
+{
+	unsigned long flags;
+	u32 cfg1_clrb = 0, cfg1_setb = 0, cfg2_clrb = 0, cfg2_setb = 0;
+	u32 mode, nb_words;
+	int ret = 0;
+
+	spin_lock_irqsave(&spi->lock, flags);
+
+	if (spi->cur_bpw != transfer->bits_per_word) {
+		u32 bpw, fthlv;
+
+		spi->cur_bpw = transfer->bits_per_word;
+		bpw = spi->cur_bpw - 1;
+
+		cfg1_clrb |= STM32H7_SPI_CFG1_DSIZE;
+		cfg1_setb |= (bpw << STM32H7_SPI_CFG1_DSIZE_SHIFT) &
+			     STM32H7_SPI_CFG1_DSIZE;
+
+		spi->cur_fthlv = stm32h7_spi_prepare_fthlv(spi);
+		fthlv = spi->cur_fthlv - 1;
+
+		cfg1_clrb |= STM32H7_SPI_CFG1_FTHLV;
+		cfg1_setb |= (fthlv << STM32H7_SPI_CFG1_FTHLV_SHIFT) &
+			     STM32H7_SPI_CFG1_FTHLV;
+	}
+
+	if (spi->cur_speed != transfer->speed_hz) {
+		int mbr;
+
+		/* Update spi->cur_speed with real clock speed */
+		mbr = stm32h7_spi_prepare_mbr(spi, transfer->speed_hz);
+		if (mbr < 0) {
+			ret = mbr;
+			goto out;
+		}
+
+		transfer->speed_hz = spi->cur_speed;
+
+		cfg1_clrb |= STM32H7_SPI_CFG1_MBR;
+		cfg1_setb |= ((u32)mbr << STM32H7_SPI_CFG1_MBR_SHIFT) &
+			     STM32H7_SPI_CFG1_MBR;
+	}
+
+	if (cfg1_clrb || cfg1_setb)
+		writel_relaxed((readl_relaxed(spi->base + STM32H7_SPI_CFG1) &
+				~cfg1_clrb) | cfg1_setb,
+			       spi->base + STM32H7_SPI_CFG1);
+
+	mode = STM32H7_SPI_FULL_DUPLEX;
+	if (spi_dev->mode & SPI_3WIRE) { /* MISO/MOSI signals shared */
+		/*
+		 * SPI_3WIRE and xfer->tx_buf != NULL and xfer->rx_buf != NULL
+		 * is forbidden und unvalidated by SPI subsystem so depending
+		 * on the valid buffer, we can determine the direction of the
+		 * transfer.
+		 */
+		mode = STM32H7_SPI_HALF_DUPLEX;
+		if (!transfer->tx_buf)
+			stm32h7_spi_clr_bits(spi, STM32H7_SPI_CR1,
+					     STM32H7_SPI_CR1_HDDIR);
+		else if (!transfer->rx_buf)
+			stm32h7_spi_set_bits(spi, STM32H7_SPI_CR1,
+					     STM32H7_SPI_CR1_HDDIR);
+	} else {
+		if (!transfer->tx_buf)
+			mode = STM32H7_SPI_SIMPLEX_RX;
+		else if (!transfer->rx_buf)
+			mode = STM32H7_SPI_SIMPLEX_TX;
+	}
+	if (spi->cur_comm != mode) {
+		spi->cur_comm = mode;
+
+		cfg2_clrb |= STM32H7_SPI_CFG2_COMM;
+		cfg2_setb |= (mode << STM32H7_SPI_CFG2_COMM_SHIFT) &
+			     STM32H7_SPI_CFG2_COMM;
+	}
+
+	cfg2_clrb |= STM32H7_SPI_CFG2_MIDI;
+	if ((transfer->len > 1) && (spi->cur_midi > 0)) {
+		u32 sck_period_ns = DIV_ROUND_UP(STM32H7_SPI_1HZ_NS,
+						 spi->cur_speed);
+		u32 midi = min((u32)DIV_ROUND_UP(spi->cur_midi, sck_period_ns),
+			       (u32)STM32H7_SPI_CFG2_MIDI >>
+			       STM32H7_SPI_CFG2_MIDI_SHIFT);
+
+		dev_dbg(spi->dev, "period=%dns, midi=%d(=%dns)\n",
+			sck_period_ns, midi, midi * sck_period_ns);
+
+		cfg2_setb |= (midi << STM32H7_SPI_CFG2_MIDI_SHIFT) &
+			     STM32H7_SPI_CFG2_MIDI;
+	}
+
+	if (cfg2_clrb || cfg2_setb)
+		writel_relaxed((readl_relaxed(spi->base + STM32H7_SPI_CFG2) &
+				~cfg2_clrb) | cfg2_setb,
+			       spi->base + STM32H7_SPI_CFG2);
+
+	if (spi->cur_bpw <= 8)
+		nb_words = transfer->len;
+	else if (spi->cur_bpw <= 16)
+		nb_words = DIV_ROUND_UP(transfer->len * 8, 16);
+	else
+		nb_words = DIV_ROUND_UP(transfer->len * 8, 32);
+	nb_words <<= STM32H7_SPI_CR2_TSIZE_SHIFT;
+
+	if (nb_words <= STM32H7_SPI_CR2_TSIZE) {
+		writel_relaxed(nb_words, spi->base + STM32H7_SPI_CR2);
+	} else {
+		ret = -EMSGSIZE;
+		goto out;
+	}
+
+	spi->cur_xferlen = transfer->len;
+
+	dev_dbg(spi->dev, "transfer communication mode set to %d\n",
+		spi->cur_comm);
+	dev_dbg(spi->dev,
+		"data frame of %d-bit, data packet of %d data frames\n",
+		spi->cur_bpw, spi->cur_fthlv);
+	dev_dbg(spi->dev, "speed set to %dHz\n", spi->cur_speed);
+	dev_dbg(spi->dev, "transfer of %d bytes (%d data frames)\n",
+		spi->cur_xferlen, nb_words);
+	dev_dbg(spi->dev, "dma %s\n",
+		(spi->cur_usedma) ? "enabled" : "disabled");
+
+out:
+	spin_unlock_irqrestore(&spi->lock, flags);
+
+	return ret;
+}
+
+/**
+ * stm32h7_spi_transfer_one - transfer a single spi_transfer
+ *
+ * It must return 0 if the transfer is finished or 1 if the transfer is still
+ * in progress.
+ */
+static int stm32h7_spi_transfer_one(struct spi_master *master,
+				    struct spi_device *spi_dev,
+				    struct spi_transfer *transfer)
+{
+	struct stm32h7_spi *spi = spi_master_get_devdata(master);
+	int ret;
+
+	spi->tx_buf = transfer->tx_buf;
+	spi->rx_buf = transfer->rx_buf;
+	spi->tx_len = spi->tx_buf ? transfer->len : 0;
+	spi->rx_len = spi->rx_buf ? transfer->len : 0;
+
+	spi->cur_usedma = (master->can_dma &&
+			   stm32h7_spi_can_dma(master, spi_dev, transfer));
+
+	ret = stm32h7_spi_transfer_one_setup(spi, spi_dev, transfer);
+	if (ret) {
+		dev_err(spi->dev, "SPI transfer setup failed\n");
+		return ret;
+	}
+
+	if (spi->cur_usedma)
+		return stm32h7_spi_transfer_one_dma(spi, transfer);
+	else
+		return stm32h7_spi_transfer_one_irq(spi);
+}
+
+/**
+ * stm32h7_spi_unprepare_msg - relax the hardware
+ *
+ * Normally, if TSIZE has been configured, we should relax the hardware at the
+ * reception of the EOT interrupt. But in case of error, EOT will not be
+ * raised. So the subsystem unprepare_message call allows us to properly
+ * complete the transfer from an hardware point of view.
+ */
+static int stm32h7_spi_unprepare_msg(struct spi_master *master,
+				     struct spi_message *msg)
+{
+	struct stm32h7_spi *spi = spi_master_get_devdata(master);
+
+	stm32h7_spi_disable(spi);
+
+	return 0;
+}
+
+/**
+ * stm32h7_spi_config - Configure SPI controller as SPI master
+ */
+static int stm32h7_spi_config(struct stm32h7_spi *spi)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&spi->lock, flags);
+
+	/* Ensure I2SMOD bit is kept cleared */
+	stm32h7_spi_clr_bits(spi, STM32H7_SPI_I2SCFGR,
+			     STM32H7_SPI_I2SCFGR_I2SMOD);
+
+	/*
+	 * - SS input value high
+	 * - transmitter half duplex direction
+	 * - automatic communication suspend when RX-Fifo is full
+	 */
+	stm32h7_spi_set_bits(spi, STM32H7_SPI_CR1, STM32H7_SPI_CR1_SSI |
+						   STM32H7_SPI_CR1_HDDIR |
+						   STM32H7_SPI_CR1_MASRX);
+
+	/*
+	 * - Set the master mode (default Motorola mode)
+	 * - Consider 1 master/n slaves configuration and
+	 *   SS input value is determined by the SSI bit
+	 * - keep control of all associated GPIOs
+	 */
+	stm32h7_spi_set_bits(spi, STM32H7_SPI_CFG2, STM32H7_SPI_CFG2_MASTER |
+						    STM32H7_SPI_CFG2_SSM |
+						    STM32H7_SPI_CFG2_AFCNTR);
+
+	spin_unlock_irqrestore(&spi->lock, flags);
+
+	return 0;
+}
+
+static const struct of_device_id stm32h7_spi_of_match[] = {
+	{ .compatible = "st,stm32h7-spi", },
+	{},
+};
+MODULE_DEVICE_TABLE(of, stm32h7_spi_of_match);
+
+static int stm32h7_spi_probe(struct platform_device *pdev)
+{
+	struct spi_master *master;
+	struct stm32h7_spi *spi;
+	struct resource *res;
+	int i, ret;
+
+	master = spi_alloc_master(&pdev->dev, sizeof(struct stm32h7_spi));
+	if (!master) {
+		dev_err(&pdev->dev, "spi master allocation failed\n");
+		return -ENOMEM;
+	}
+	platform_set_drvdata(pdev, master);
+
+	spi = spi_master_get_devdata(master);
+	spi->dev = &pdev->dev;
+	spi->master = master;
+	spin_lock_init(&spi->lock);
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	spi->base = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(spi->base)) {
+		ret = PTR_ERR(spi->base);
+		goto err_master_put;
+	}
+	spi->phys_addr = (dma_addr_t)res->start;
+
+	spi->irq = platform_get_irq(pdev, 0);
+	if (spi->irq <= 0) {
+		dev_err(&pdev->dev, "no irq: %d\n", spi->irq);
+		ret = -ENOENT;
+		goto err_master_put;
+	}
+	ret = devm_request_threaded_irq(&pdev->dev, spi->irq, NULL,
+					stm32h7_spi_irq, IRQF_ONESHOT,
+					pdev->name, master);
+	if (ret) {
+		dev_err(&pdev->dev, "irq%d request failed: %d\n", spi->irq,
+			ret);
+		goto err_master_put;
+	}
+
+	spi->clk = devm_clk_get(&pdev->dev, 0);
+	if (IS_ERR(spi->clk)) {
+		ret = PTR_ERR(spi->clk);
+		dev_err(&pdev->dev, "clk get failed: %d\n", ret);
+		goto err_master_put;
+	}
+
+	ret = clk_prepare_enable(spi->clk);
+	if (ret) {
+		dev_err(&pdev->dev, "clk enable failed: %d\n", ret);
+		goto err_master_put;
+	}
+	spi->clk_rate = clk_get_rate(spi->clk);
+	if (!spi->clk_rate) {
+		dev_err(&pdev->dev, "clk rate = 0\n");
+		ret = -EINVAL;
+		goto err_clk_disable;
+	}
+
+	spi->rst = devm_reset_control_get_exclusive(&pdev->dev, NULL);
+	if (!IS_ERR(spi->rst)) {
+		reset_control_assert(spi->rst);
+		udelay(2);
+		reset_control_deassert(spi->rst);
+	}
+
+	spi->fifo_size = stm32h7_spi_get_fifo_size(spi);
+
+	ret = stm32h7_spi_config(spi);
+	if (ret) {
+		dev_err(&pdev->dev, "controller configuration failed: %d\n",
+			ret);
+		goto err_clk_disable;
+	}
+
+	master->dev.of_node = pdev->dev.of_node;
+	master->auto_runtime_pm = true;
+	master->bus_num = pdev->id;
+	master->mode_bits = SPI_MODE_3 | SPI_CS_HIGH | SPI_LSB_FIRST |
+			    SPI_3WIRE | SPI_LOOP;
+	master->bits_per_word_mask = stm32h7_spi_get_bpw_mask(spi);
+	master->max_speed_hz = spi->clk_rate / STM32H7_SPI_MBR_DIV_MIN;
+	master->min_speed_hz = spi->clk_rate / STM32H7_SPI_MBR_DIV_MAX;
+	master->setup = stm32h7_spi_setup;
+	master->prepare_message = stm32h7_spi_prepare_msg;
+	master->transfer_one = stm32h7_spi_transfer_one;
+	master->unprepare_message = stm32h7_spi_unprepare_msg;
+
+	spi->dma_tx = dma_request_slave_channel(spi->dev, "tx");
+	if (!spi->dma_tx)
+		dev_warn(&pdev->dev, "failed to request tx dma channel\n");
+	else
+		master->dma_tx = spi->dma_tx;
+
+	spi->dma_rx = dma_request_slave_channel(spi->dev, "rx");
+	if (!spi->dma_rx)
+		dev_warn(&pdev->dev, "failed to request rx dma channel\n");
+	else
+		master->dma_rx = spi->dma_rx;
+
+	if (spi->dma_tx || spi->dma_rx)
+		master->can_dma = stm32h7_spi_can_dma;
+
+	pm_runtime_set_active(&pdev->dev);
+	pm_runtime_enable(&pdev->dev);
+
+	ret = devm_spi_register_master(&pdev->dev, master);
+	if (ret) {
+		dev_err(&pdev->dev, "spi master registration failed: %d\n",
+			ret);
+		goto err_dma_release;
+	}
+
+	if (!master->cs_gpios) {
+		dev_err(&pdev->dev, "no CS gpios available\n");
+		ret = -EINVAL;
+		goto err_dma_release;
+	}
+
+	for (i = 0; i < master->num_chipselect; i++) {
+		if (!gpio_is_valid(master->cs_gpios[i])) {
+			dev_err(&pdev->dev, "%i is not a valid gpio\n",
+				master->cs_gpios[i]);
+			ret = -EINVAL;
+			goto err_dma_release;
+		}
+
+		ret = devm_gpio_request(&pdev->dev, master->cs_gpios[i],
+					DRIVER_NAME);
+		if (ret) {
+			dev_err(&pdev->dev, "can't get CS gpio %i\n",
+				master->cs_gpios[i]);
+			goto err_dma_release;
+		}
+	}
+
+	dev_info(&pdev->dev, "driver initialized\n");
+
+	return 0;
+
+err_dma_release:
+	if (spi->dma_tx)
+		dma_release_channel(spi->dma_tx);
+	if (spi->dma_rx)
+		dma_release_channel(spi->dma_rx);
+
+	pm_runtime_disable(&pdev->dev);
+err_clk_disable:
+	clk_disable_unprepare(spi->clk);
+err_master_put:
+	spi_master_put(master);
+
+	return ret;
+}
+
+static int stm32h7_spi_remove(struct platform_device *pdev)
+{
+	struct spi_master *master = platform_get_drvdata(pdev);
+	struct stm32h7_spi *spi = spi_master_get_devdata(master);
+
+	stm32h7_spi_disable(spi);
+
+	if (master->dma_tx)
+		dma_release_channel(master->dma_tx);
+	if (master->dma_rx)
+		dma_release_channel(master->dma_rx);
+
+	clk_disable_unprepare(spi->clk);
+
+	pm_runtime_disable(&pdev->dev);
+
+	return 0;
+}
+
+#ifdef CONFIG_PM
+static int stm32h7_spi_runtime_suspend(struct device *dev)
+{
+	struct spi_master *master = dev_get_drvdata(dev);
+	struct stm32h7_spi *spi = spi_master_get_devdata(master);
+
+	clk_disable_unprepare(spi->clk);
+
+	return 0;
+}
+
+static int stm32h7_spi_runtime_resume(struct device *dev)
+{
+	struct spi_master *master = dev_get_drvdata(dev);
+	struct stm32h7_spi *spi = spi_master_get_devdata(master);
+
+	return clk_prepare_enable(spi->clk);
+}
+#endif
+
+#ifdef CONFIG_PM_SLEEP
+static int stm32h7_spi_suspend(struct device *dev)
+{
+	struct spi_master *master = dev_get_drvdata(dev);
+	int ret;
+
+	ret = spi_master_suspend(master);
+	if (ret)
+		return ret;
+
+	return pm_runtime_force_suspend(dev);
+}
+
+static int stm32h7_spi_resume(struct device *dev)
+{
+	struct spi_master *master = dev_get_drvdata(dev);
+	struct stm32h7_spi *spi = spi_master_get_devdata(master);
+	int ret;
+
+	ret = pm_runtime_force_resume(dev);
+	if (ret)
+		return ret;
+
+	ret = spi_master_resume(master);
+	if (ret)
+		clk_disable_unprepare(spi->clk);
+
+	return ret;
+}
+#endif
+
+static const struct dev_pm_ops stm32h7_spi_pm_ops = {
+	SET_SYSTEM_SLEEP_PM_OPS(stm32h7_spi_suspend, stm32h7_spi_resume)
+	SET_RUNTIME_PM_OPS(stm32h7_spi_runtime_suspend,
+			   stm32h7_spi_runtime_resume, NULL)
+};
+
+static struct platform_driver stm32h7_spi_driver = {
+	.probe = stm32h7_spi_probe,
+	.remove = stm32h7_spi_remove,
+	.driver = {
+		.name = DRIVER_NAME,
+		.pm = &stm32h7_spi_pm_ops,
+		.of_match_table = stm32h7_spi_of_match,
+	},
+};
+
+module_platform_driver(stm32h7_spi_driver);
+
+MODULE_ALIAS("platform:" DRIVER_NAME);
+MODULE_DESCRIPTION("STMicroelectronics STM32H7 SPI Controller driver");
+MODULE_AUTHOR("Amelie Delaunay <amelie.delaunay@st.com>");
+MODULE_LICENSE("GPL v2");
-- 
2.7.4


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

^ permalink raw reply related

* [PATCH 3/5] spi: stm32: add driver for STM32F4 controller
From: cezary.gapinski @ 2018-12-09 13:53 UTC (permalink / raw)
  To: Mark Brown, linux-spi, linux-stm32, linux-arm-kernel,
	linux-kernel, Rob Herring, devicetree
  Cc: Mark Rutland, Amelie Delaunay, Cezary Gapinski, Alexandre Torgue,
	Maxime Coquelin
In-Reply-To: <1544363636-12161-1-git-send-email-cezary.gapinski@gmail.com>

From: Cezary Gapinski <cezary.gapinski@gmail.com>

The STM32F4 Serial Peripheral Interface (SPI) can be used to communicate
with external devices while using the specific synchronous protocol. This
version supports full-duplex communication  with 8 or 16-bit per word.
DMA capability is optionally supported when RX and TX DMA channels are
enabled at the same time for transfer longer than 16 bytes.
Now only master mode can be used.

Signed-off-by: Cezary Gapinski <cezary.gapinski@gmail.com>
---
 drivers/spi/Kconfig       |   10 +
 drivers/spi/Makefile      |    1 +
 drivers/spi/spi-stm32f4.c | 1002 +++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 1013 insertions(+)
 create mode 100644 drivers/spi/spi-stm32f4.c

diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
index 0151334..fc40616 100644
--- a/drivers/spi/Kconfig
+++ b/drivers/spi/Kconfig
@@ -655,6 +655,16 @@ config SPI_STM32H7
 	  is not available, the driver automatically falls back to
 	  PIO mode.
 
+config SPI_STM32F4
+	tristate "STMicroelectronics STM32F4 SPI controller"
+	depends on ARCH_STM32 || COMPILE_TEST
+	help
+	  SPI driver for STMicroelectronics STM32F4 SoCs.
+
+	  STM32F4 SPI controller supports DMA and PIO modes. When DMA
+	  is not available, the driver automatically falls back to
+	  PIO mode.
+
 config SPI_STM32_QSPI
 	tristate "STMicroelectronics STM32 QUAD SPI controller"
 	depends on ARCH_STM32 || COMPILE_TEST
diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile
index 6f24938..3fb0f98 100644
--- a/drivers/spi/Makefile
+++ b/drivers/spi/Makefile
@@ -94,6 +94,7 @@ obj-$(CONFIG_SPI_SIRF)		+= spi-sirf.o
 obj-$(CONFIG_SPI_SLAVE_MT27XX)          += spi-slave-mt27xx.o
 obj-$(CONFIG_SPI_SPRD)			+= spi-sprd.o
 obj-$(CONFIG_SPI_SPRD_ADI)		+= spi-sprd-adi.o
+obj-$(CONFIG_SPI_STM32F4) 		+= spi-stm32f4.o
 obj-$(CONFIG_SPI_STM32H7) 		+= spi-stm32h7.o
 obj-$(CONFIG_SPI_STM32_QSPI) 		+= spi-stm32-qspi.o
 obj-$(CONFIG_SPI_ST_SSC4)		+= spi-st-ssc4.o
diff --git a/drivers/spi/spi-stm32f4.c b/drivers/spi/spi-stm32f4.c
new file mode 100644
index 0000000..755222b
--- /dev/null
+++ b/drivers/spi/spi-stm32f4.c
@@ -0,0 +1,1002 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// STMicroelectronics STM32F4 SPI Controller driver (master mode only)
+//
+// Author(s): Cezary Gapinski <cezary.gapinski@gmail.com>
+//
+// This driver is based on spi-stm32h7.c
+
+#include <linux/debugfs.h>
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/dmaengine.h>
+#include <linux/gpio.h>
+#include <linux/interrupt.h>
+#include <linux/iopoll.h>
+#include <linux/module.h>
+#include <linux/of_platform.h>
+#include <linux/pm_runtime.h>
+#include <linux/reset.h>
+#include <linux/spi/spi.h>
+
+#define DRIVER_NAME "spi_stm32f4"
+
+/* STM32F4 SPI registers */
+#define STM32F4_SPI_CR1			0x00
+#define STM32F4_SPI_CR2			0x04
+#define STM32F4_SPI_SR			0x08
+#define STM32F4_SPI_DR			0x0C
+#define STM32F4_SPI_I2SCFGR		0x1C
+
+/* STM32F4_SPI_CR1 bit fields */
+#define STM32F4_SPI_CR1_CPHA		BIT(0)
+#define STM32F4_SPI_CR1_CPOL		BIT(1)
+#define STM32F4_SPI_CR1_MSTR		BIT(2)
+#define STM32F4_SPI_CR1_BR_SHIFT	3
+#define STM32F4_SPI_CR1_BR		GENMASK(5, 3)
+#define STM32F4_SPI_CR1_SPE		BIT(6)
+#define STM32F4_SPI_CR1_LSBFRST		BIT(7)
+#define STM32F4_SPI_CR1_SSI		BIT(8)
+#define STM32F4_SPI_CR1_SSM		BIT(9)
+#define STM32F4_SPI_CR1_RXONLY		BIT(10)
+#define STM32F4_SPI_CR1_DFF		BIT(11)
+#define STM32F4_SPI_CR1_CRCNEXT		BIT(12)
+#define STM32F4_SPI_CR1_CRCEN		BIT(13)
+#define STM32F4_SPI_CR1_BIDIOE		BIT(14)
+#define STM32F4_SPI_CR1_BIDIMODE	BIT(15)
+#define STM32F4_SPI_CR1_BR_MIN		0
+#define STM32F4_SPI_CR1_BR_MAX		(GENMASK(5, 3) >> 3)
+
+/* STM32F4_SPI_CR2 bit fields */
+#define STM32F4_SPI_CR2_RXDMAEN		BIT(0)
+#define STM32F4_SPI_CR2_TXDMAEN		BIT(1)
+#define STM32F4_SPI_CR2_SSOE		BIT(2)
+#define STM32F4_SPI_CR2_FRF		BIT(4)
+#define STM32F4_SPI_CR2_ERRIE		BIT(5)
+#define STM32F4_SPI_CR2_RXNEIE		BIT(6)
+#define STM32F4_SPI_CR2_TXEIE		BIT(7)
+
+/* STM32F4_SPI_SR bit fields */
+#define STM32F4_SPI_SR_RXNE		BIT(0)
+#define STM32F4_SPI_SR_TXE		BIT(1)
+#define STM32F4_SPI_SR_CHSIDE		BIT(2)
+#define STM32F4_SPI_SR_UDR		BIT(3)
+#define STM32F4_SPI_SR_CRCERR		BIT(4)
+#define STM32F4_SPI_SR_MODF		BIT(5)
+#define STM32F4_SPI_SR_OVR		BIT(6)
+#define STM32F4_SPI_SR_BSY		BIT(7)
+#define STM32F4_SPI_SR_FRE		BIT(8)
+
+/* STM32F4_SPI_I2SCFGR bit fields */
+#define STM32F4_SPI_I2SCFGR_I2SMOD	BIT(11)
+
+/* STM32F4 SPI Baud Rate min/max divisor */
+#define STM32F4_SPI_BR_DIV_MIN		(2 << STM32F4_SPI_CR1_BR_MIN)
+#define STM32F4_SPI_BR_DIV_MAX		(2 << STM32F4_SPI_CR1_BR_MAX)
+
+/* use PIO for small transfers, avoiding DMA setup/teardown overhead */
+#define STM32F4_DMA_MIN_BYTES		16
+
+/**
+ * struct stm32f4_spi - private data of the SPI controller
+ * @dev: driver model representation of the controller
+ * @master: controller master interface
+ * @base: virtual memory area
+ * @clk: hw kernel clock feeding the SPI clock generator
+ * @clk_rate: rate of the hw kernel clock feeding the SPI clock generator
+ * @rst: SPI controller reset line
+ * @lock: prevent I/O concurrent access
+ * @irq: SPI controller interrupt line
+ * @cur_speed: speed configured in Hz
+ * @cur_bpw: number of bits in a single SPI data frame
+ * @cur_xferlen: current transfer length in bytes
+ * @cur_usedma: boolean to know if dma is used in current transfer
+ * @tx_buf: data to be written, or NULL
+ * @rx_buf: data to be read, or NULL
+ * @tx_len: number of data to be written in bytes
+ * @rx_len: number of data to be read in bytes
+ * @phys_addr: SPI registers physical base address
+ */
+struct stm32f4_spi {
+	struct device *dev;
+	struct spi_master *master;
+	void __iomem *base;
+	struct clk *clk;
+	u32 clk_rate;
+	struct reset_control *rst;
+	spinlock_t lock;
+	int irq;
+
+	unsigned int cur_speed;
+	unsigned int cur_bpw;
+	unsigned int cur_xferlen;
+	bool cur_usedma;
+
+	const void *tx_buf;
+	void *rx_buf;
+	int tx_len;
+	int rx_len;
+	dma_addr_t phys_addr;
+};
+
+static inline void stm32f4_spi_set_bits(struct stm32f4_spi *spi,
+					u32 offset, u32 bits)
+{
+	writel_relaxed(readl_relaxed(spi->base + offset) | bits,
+		       spi->base + offset);
+}
+
+static inline void stm32f4_spi_clr_bits(struct stm32f4_spi *spi,
+					u32 offset, u32 bits)
+{
+	writel_relaxed(readl_relaxed(spi->base + offset) & ~bits,
+		       spi->base + offset);
+}
+
+/**
+ * stm32f4_spi_prepare_mbr - Determine STM32F4_SPI_CR1.BR value
+ * @spi: pointer to the spi controller data structure
+ * @speed_hz: requested speed
+ *
+ * Return STM32F4_SPI_CR1.BR value in case of success or -EINVAL
+ */
+static int stm32f4_spi_prepare_mbr(struct stm32f4_spi *spi, u32 speed_hz)
+{
+	u32 div, mbrdiv;
+
+	div = DIV_ROUND_UP(spi->clk_rate, speed_hz);
+
+	/*
+	 * SPI framework set xfer->speed_hz to master->max_speed_hz if
+	 * xfer->speed_hz is greater than master->max_speed_hz, and it returns
+	 * an error when xfer->speed_hz is lower than master->min_speed_hz, so
+	 * no need to check it there.
+	 * However, we need to ensure the following calculations.
+	 */
+	if (div < STM32F4_SPI_BR_DIV_MIN ||
+	    div > STM32F4_SPI_BR_DIV_MAX)
+		return -EINVAL;
+
+	/* Determine the first power of 2 greater than or equal to div */
+	if (div & (div - 1))
+		mbrdiv = fls(div);
+	else
+		mbrdiv = fls(div) - 1;
+
+	spi->cur_speed = spi->clk_rate / (1 << mbrdiv);
+
+	return mbrdiv - 1;
+}
+
+/**
+ * stm32f4_spi_write_tx - Write bytes to Data Register
+ * @spi: pointer to the spi controller data structure
+ *
+ * Read from tx_buf depends on remaining bytes to avoid to read beyond
+ * tx_buf end.
+ */
+static void stm32f4_spi_write_tx(struct stm32f4_spi *spi)
+{
+	if (spi->tx_len > 0) {
+		u32 offs = spi->cur_xferlen - spi->tx_len;
+
+		if (spi->cur_bpw == 16) {
+			const u16 *tx_buf16 = (const u16 *)(spi->tx_buf + offs);
+
+			writew_relaxed(*tx_buf16, spi->base + STM32F4_SPI_DR);
+			spi->tx_len -= sizeof(u16);
+		} else {
+			const u8 *tx_buf8 = (const u8 *)(spi->tx_buf + offs);
+
+			writeb_relaxed(*tx_buf8, spi->base + STM32F4_SPI_DR);
+			spi->tx_len -= sizeof(u8);
+		}
+	}
+
+	dev_dbg(spi->dev, "%s: %d bytes left\n", __func__, spi->tx_len);
+}
+
+/**
+ * stm32f4_spi_read_rx - Read bytes from Data Register
+ * @spi: pointer to the spi controller data structure
+ *
+ * Write in rx_buf depends on remaining bytes to avoid to write beyond
+ * rx_buf end.
+ */
+static void stm32f4_spi_read_rx(struct stm32f4_spi *spi)
+{
+	if (spi->rx_len > 0) {
+		u32 offs = spi->cur_xferlen - spi->rx_len;
+
+		if (spi->cur_bpw == 16) {
+			u16 *rx_buf16 = (u16 *)(spi->rx_buf + offs);
+
+			*rx_buf16 = readw_relaxed(spi->base + STM32F4_SPI_DR);
+			spi->rx_len -= sizeof(u16);
+		} else {
+			u8 *rx_buf8 = (u8 *)(spi->rx_buf + offs);
+
+			*rx_buf8 = readb_relaxed(spi->base + STM32F4_SPI_DR);
+			spi->rx_len -= sizeof(u8);
+		}
+	}
+
+	dev_dbg(spi->dev, "%s: %d bytes left\n", __func__, spi->rx_len);
+}
+
+/**
+ * stm32f4_spi_enable - Enable SPI controller
+ * @spi: pointer to the spi controller data structure
+ */
+static void stm32f4_spi_enable(struct stm32f4_spi *spi)
+{
+	dev_dbg(spi->dev, "enable controller\n");
+
+	stm32f4_spi_set_bits(spi, STM32F4_SPI_CR1, STM32F4_SPI_CR1_SPE);
+}
+
+/**
+ * stm32f4_spi_disable - Disable SPI controller
+ * @spi: pointer to the spi controller data structure
+ */
+static void stm32f4_spi_disable(struct stm32f4_spi *spi)
+{
+	unsigned long flags;
+	struct spi_master *master = spi->master;
+
+	dev_dbg(spi->dev, "disable controller\n");
+
+	spin_lock_irqsave(&spi->lock, flags);
+
+	stm32f4_spi_clr_bits(spi, STM32F4_SPI_CR1, STM32F4_SPI_CR1_SPE);
+
+	if (spi->cur_usedma) {
+		dmaengine_terminate_all(master->dma_tx);
+		dmaengine_terminate_all(master->dma_rx);
+	}
+
+	stm32f4_spi_clr_bits(spi, STM32F4_SPI_CR2, STM32F4_SPI_CR2_TXDMAEN |
+						   STM32F4_SPI_CR2_RXDMAEN);
+
+	/* Disable interrupts */
+	stm32f4_spi_clr_bits(spi, STM32F4_SPI_CR2, STM32F4_SPI_CR2_RXNEIE |
+						   STM32F4_SPI_CR2_ERRIE);
+	/* Sequence to clear OVR flag */
+	readl_relaxed(spi->base + STM32F4_SPI_DR);
+	readl_relaxed(spi->base + STM32F4_SPI_SR);
+
+	spin_unlock_irqrestore(&spi->lock, flags);
+}
+
+/**
+ * stm32f4_spi_can_dma - Determine if the transfer is eligible for DMA use
+ *
+ * If the current transfer size is greater than defined size, use DMA.
+ */
+static bool stm32f4_spi_can_dma(struct spi_master *master,
+				struct spi_device *spi_dev,
+				struct spi_transfer *transfer)
+{
+	struct stm32f4_spi *spi = spi_master_get_devdata(master);
+
+	dev_dbg(spi->dev, "%s: %s\n", __func__,
+		(transfer->len > STM32F4_DMA_MIN_BYTES) ? "true" : "false");
+
+	return (transfer->len > STM32F4_DMA_MIN_BYTES);
+}
+
+/**
+ * stm32f4_spi_irq_event - Interrupt handler for SPI controller events
+ * @irq: interrupt line
+ * @dev_id: SPI controller master interface
+ */
+static irqreturn_t stm32f4_spi_irq_event(int irq, void *dev_id)
+{
+	struct spi_master *master = dev_id;
+	struct stm32f4_spi *spi = spi_master_get_devdata(master);
+	u32 sr, mask;
+	unsigned long flags;
+	bool end = false;
+
+	spin_lock_irqsave(&spi->lock, flags);
+
+	sr = readl_relaxed(spi->base + STM32F4_SPI_SR);
+	/*
+	 * BSY flag is not handled in interrupt
+	 * TXE flag is set and is handled when RXNE flag occurs
+	 */
+	sr &= ~(STM32F4_SPI_SR_BSY | STM32F4_SPI_SR_TXE);
+
+	mask = STM32F4_SPI_SR_RXNE;
+	if (spi->cur_usedma)
+		mask |= STM32F4_SPI_SR_OVR;
+
+	if (!(sr & mask)) {
+		dev_dbg(spi->dev, "spurious IT (sr=0x%08x)\n", sr);
+		spin_unlock_irqrestore(&spi->lock, flags);
+		return IRQ_NONE;
+	}
+
+	if (sr & STM32F4_SPI_SR_OVR) {
+		dev_warn(spi->dev, "Overrun: received value discarded\n");
+
+		/* Sequence to clear OVR flag */
+		readl_relaxed(spi->base + STM32F4_SPI_DR);
+		readl_relaxed(spi->base + STM32F4_SPI_SR);
+
+		/*
+		 * If overrun is detected, it means that something went wrong,
+		 * so stop the current transfer. For interrupt transfer for
+		 * current configuration it should newer occurs. If it is
+		 * detected for DMA stop transfer.
+		 */
+		end = true;
+		goto end_irq;
+	}
+
+	stm32f4_spi_read_rx(spi);
+	if (spi->rx_len == 0)
+		end = true;
+	else
+		stm32f4_spi_write_tx(spi);
+
+end_irq:
+	spin_unlock_irqrestore(&spi->lock, flags);
+
+	if (end)
+		return IRQ_WAKE_THREAD;
+
+	return IRQ_HANDLED;
+}
+
+/**
+ * stm32f4_spi_irq_thread - Thread of interrupt handler for SPI controller
+ * @irq: interrupt line
+ * @dev_id: SPI controller master interface
+ */
+static irqreturn_t stm32f4_spi_irq_thread(int irq, void *dev_id)
+{
+	struct spi_master *master = dev_id;
+	struct stm32f4_spi *spi = spi_master_get_devdata(master);
+
+	spi_finalize_current_transfer(master);
+	stm32f4_spi_disable(spi);
+
+	return IRQ_HANDLED;
+}
+
+/**
+ * stm32f4_spi_setup - setup device chip select
+ */
+static int stm32f4_spi_setup(struct spi_device *spi_dev)
+{
+	int ret = 0;
+
+	if (!gpio_is_valid(spi_dev->cs_gpio)) {
+		dev_err(&spi_dev->dev, "%d is not a valid gpio\n",
+			spi_dev->cs_gpio);
+		return -EINVAL;
+	}
+
+	dev_dbg(&spi_dev->dev, "%s: set gpio%d output %s\n", __func__,
+		spi_dev->cs_gpio,
+		(spi_dev->mode & SPI_CS_HIGH) ? "low" : "high");
+
+	ret = gpio_direction_output(spi_dev->cs_gpio,
+				    !(spi_dev->mode & SPI_CS_HIGH));
+
+	return ret;
+}
+
+/**
+ * stm32f4_spi_prepare_msg - set up the controller to transfer a single message
+ */
+static int stm32f4_spi_prepare_msg(struct spi_master *master,
+				   struct spi_message *msg)
+{
+	struct stm32f4_spi *spi = spi_master_get_devdata(master);
+	struct spi_device *spi_dev = msg->spi;
+	unsigned long flags;
+	u32 cr1_clrb = 0, cr1_setb = 0;
+
+	if (spi_dev->mode & SPI_CPOL)
+		cr1_setb |= STM32F4_SPI_CR1_CPOL;
+	else
+		cr1_clrb |= STM32F4_SPI_CR1_CPOL;
+
+	if (spi_dev->mode & SPI_CPHA)
+		cr1_setb |= STM32F4_SPI_CR1_CPHA;
+	else
+		cr1_clrb |= STM32F4_SPI_CR1_CPHA;
+
+	if (spi_dev->mode & SPI_LSB_FIRST)
+		cr1_setb |= STM32F4_SPI_CR1_LSBFRST;
+	else
+		cr1_clrb |= STM32F4_SPI_CR1_LSBFRST;
+
+	dev_dbg(spi->dev, "cpol=%d cpha=%d lsb_first=%d cs_high=%d\n",
+		spi_dev->mode & SPI_CPOL,
+		spi_dev->mode & SPI_CPHA,
+		spi_dev->mode & SPI_LSB_FIRST,
+		spi_dev->mode & SPI_CS_HIGH);
+
+	spin_lock_irqsave(&spi->lock, flags);
+
+	if (cr1_clrb || cr1_setb)
+		writel_relaxed((readl_relaxed(spi->base + STM32F4_SPI_CR1) &
+				~cr1_clrb) | cr1_setb,
+			       spi->base + STM32F4_SPI_CR1);
+
+	spin_unlock_irqrestore(&spi->lock, flags);
+
+	return 0;
+}
+
+/**
+ * stm32f4_spi_dma_rx_cb - DMA callback
+ *
+ * DMA callback is called when the transfer is complete for receiving mode.
+ */
+static void stm32f4_spi_dma_rx_cb(void *data)
+{
+	struct spi_master *master = data;
+	struct stm32f4_spi *spi = spi_master_get_devdata(master);
+
+	spi_finalize_current_transfer(master);
+	stm32f4_spi_disable(spi);
+}
+
+/**
+ * stm32f4_spi_dma_config - configure DMA slave channel depending on current
+ *			    transfer bits_per_word.
+ */
+static void stm32f4_spi_dma_config(struct stm32f4_spi *spi,
+				   struct dma_slave_config *dma_conf,
+				   enum dma_transfer_direction dir)
+{
+	enum dma_slave_buswidth buswidth;
+
+	if (spi->cur_bpw == 16)
+		buswidth = DMA_SLAVE_BUSWIDTH_2_BYTES;
+	else
+		buswidth = DMA_SLAVE_BUSWIDTH_1_BYTE;
+
+	memset(dma_conf, 0, sizeof(struct dma_slave_config));
+	dma_conf->direction = dir;
+	if (dma_conf->direction == DMA_DEV_TO_MEM) { /* RX */
+		dma_conf->src_addr = spi->phys_addr + STM32F4_SPI_DR;
+		dma_conf->src_addr_width = buswidth;
+
+		dev_dbg(spi->dev, "Rx DMA config buswidth=%d\n", buswidth);
+	} else if (dma_conf->direction == DMA_MEM_TO_DEV) { /* TX */
+		dma_conf->dst_addr = spi->phys_addr + STM32F4_SPI_DR;
+		dma_conf->dst_addr_width = buswidth;
+
+		dev_dbg(spi->dev, "Tx DMA config buswidth=%d\n", buswidth);
+	}
+}
+
+/**
+ * stm32f4_spi_transfer_one_irq - transfer a single spi_transfer using
+ *				  interrupts
+ *
+ * It must returns 0 if the transfer is finished or 1 if the transfer is still
+ * in progress.
+ */
+static int stm32f4_spi_transfer_one_irq(struct stm32f4_spi *spi)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&spi->lock, flags);
+
+	stm32f4_spi_set_bits(spi, STM32F4_SPI_CR2, STM32F4_SPI_CR2_RXNEIE |
+						   STM32F4_SPI_CR2_ERRIE);
+	stm32f4_spi_enable(spi);
+	stm32f4_spi_write_tx(spi);
+
+	spin_unlock_irqrestore(&spi->lock, flags);
+
+	return 1;
+}
+
+/**
+ * stm32f4_spi_transfer_one_dma - transfer a single spi_transfer using DMA
+ *
+ * It must returns 0 if the transfer is finished or 1 if the transfer is still
+ * in progress.
+ */
+static int stm32f4_spi_transfer_one_dma(struct stm32f4_spi *spi,
+					struct spi_transfer *xfer)
+{
+	struct dma_slave_config tx_dma_conf, rx_dma_conf;
+	struct dma_async_tx_descriptor *tx_dma_desc, *rx_dma_desc;
+	unsigned long flags;
+	struct spi_master *master = spi->master;
+
+	spin_lock_irqsave(&spi->lock, flags);
+
+	rx_dma_desc = NULL;
+	stm32f4_spi_dma_config(spi, &rx_dma_conf, DMA_DEV_TO_MEM);
+	dmaengine_slave_config(master->dma_rx, &rx_dma_conf);
+
+	/* Enable Rx DMA request */
+	stm32f4_spi_set_bits(spi, STM32F4_SPI_CR2, STM32F4_SPI_CR2_RXDMAEN);
+
+	rx_dma_desc = dmaengine_prep_slave_sg(
+				master->dma_rx, xfer->rx_sg.sgl,
+				xfer->rx_sg.nents,
+				rx_dma_conf.direction,
+				DMA_PREP_INTERRUPT);
+
+	tx_dma_desc = NULL;
+	stm32f4_spi_dma_config(spi, &tx_dma_conf, DMA_MEM_TO_DEV);
+	dmaengine_slave_config(master->dma_tx, &tx_dma_conf);
+
+	tx_dma_desc = dmaengine_prep_slave_sg(
+				master->dma_tx, xfer->tx_sg.sgl,
+				xfer->tx_sg.nents,
+				tx_dma_conf.direction,
+				DMA_PREP_INTERRUPT);
+
+	if (!tx_dma_desc || !rx_dma_desc)
+		goto dma_desc_error;
+
+	rx_dma_desc->callback = stm32f4_spi_dma_rx_cb;
+	rx_dma_desc->callback_param = spi->master;
+
+	if (dma_submit_error(dmaengine_submit(rx_dma_desc))) {
+		dev_err(spi->dev, "Rx DMA submit failed\n");
+		goto dma_desc_error;
+	}
+	/* Enable Rx DMA channel */
+	dma_async_issue_pending(master->dma_rx);
+
+	if (dma_submit_error(dmaengine_submit(tx_dma_desc))) {
+		dev_err(spi->dev, "Tx DMA submit failed\n");
+		goto dma_submit_error;
+	}
+	/* Enable Tx DMA channel */
+	dma_async_issue_pending(master->dma_tx);
+
+	/* Enable Tx DMA request */
+	stm32f4_spi_set_bits(spi, STM32F4_SPI_CR2, STM32F4_SPI_CR2_TXDMAEN);
+
+	/*
+	 * End of transfer will be handled in DMA RX Callback.
+	 * Enable the interrupts to detect OVR flag
+	 */
+	stm32f4_spi_set_bits(spi, STM32F4_SPI_CR2, STM32F4_SPI_CR2_ERRIE);
+
+	stm32f4_spi_enable(spi);
+
+	spin_unlock_irqrestore(&spi->lock, flags);
+
+	return 1;
+
+dma_submit_error:
+	dmaengine_terminate_all(master->dma_rx);
+
+dma_desc_error:
+	stm32f4_spi_clr_bits(spi, STM32F4_SPI_CR2, STM32F4_SPI_CR2_RXDMAEN);
+
+	spin_unlock_irqrestore(&spi->lock, flags);
+
+	dev_info(spi->dev, "DMA issue: fall back to irq transfer\n");
+
+	return stm32f4_spi_transfer_one_irq(spi);
+}
+
+/**
+ * stm32f4_spi_transfer_one_setup - common setup to transfer a single
+ *				    spi_transfer either using DMA or
+ *				    interrupts.
+ */
+static int stm32f4_spi_transfer_one_setup(struct stm32f4_spi *spi,
+					  struct spi_device *spi_dev,
+					  struct spi_transfer *transfer)
+{
+	unsigned long flags;
+	u32 cr1_clrb = 0, cr1_setb = 0;
+	u32 nb_words;
+	int ret = 0;
+
+	spin_lock_irqsave(&spi->lock, flags);
+
+	if (spi->cur_bpw != transfer->bits_per_word) {
+		spi->cur_bpw = transfer->bits_per_word;
+		nb_words = spi->cur_bpw;
+		cr1_clrb |= STM32F4_SPI_CR1_DFF;
+
+		if (spi->cur_bpw == 16)
+			cr1_setb |= STM32F4_SPI_CR1_DFF;
+	}
+
+	if (spi->cur_speed != transfer->speed_hz) {
+		int mbr;
+
+		/* Update spi->cur_speed with real clock speed */
+		mbr = stm32f4_spi_prepare_mbr(spi, transfer->speed_hz);
+		if (mbr < 0) {
+			ret = mbr;
+			goto out;
+		}
+
+		transfer->speed_hz = spi->cur_speed;
+
+		cr1_clrb |= STM32F4_SPI_CR1_BR;
+		cr1_setb |= ((u32)mbr << STM32F4_SPI_CR1_BR_SHIFT) &
+			     STM32F4_SPI_CR1_BR;
+	}
+
+	if (cr1_clrb || cr1_setb)
+		writel_relaxed((readl_relaxed(spi->base + STM32F4_SPI_CR1) &
+				~cr1_clrb) | cr1_setb,
+			       spi->base + STM32F4_SPI_CR1);
+
+	spi->cur_xferlen = transfer->len;
+
+	dev_dbg(spi->dev, "full-duplex communication mode\n");
+	dev_dbg(spi->dev, "data frame of %d-bit\n", spi->cur_bpw);
+	dev_dbg(spi->dev, "speed set to %dHz\n", spi->cur_speed);
+	dev_dbg(spi->dev, "transfer of %d bytes (%d data frames)\n",
+		spi->cur_xferlen, nb_words);
+	dev_dbg(spi->dev, "dma %s\n",
+		(spi->cur_usedma) ? "enabled" : "disabled");
+
+out:
+	spin_unlock_irqrestore(&spi->lock, flags);
+
+	return ret;
+}
+
+/**
+ * stm32f4_spi_transfer_one - transfer a single spi_transfer
+ *
+ * It must return 0 if the transfer is finished or 1 if the transfer is still
+ * in progress.
+ */
+static int stm32f4_spi_transfer_one(struct spi_master *master,
+				    struct spi_device *spi_dev,
+				    struct spi_transfer *transfer)
+{
+	struct stm32f4_spi *spi = spi_master_get_devdata(master);
+	int ret;
+
+	spi->tx_buf = transfer->tx_buf;
+	spi->rx_buf = transfer->rx_buf;
+	spi->tx_len = spi->tx_buf ? transfer->len : 0;
+	spi->rx_len = spi->rx_buf ? transfer->len : 0;
+
+	spi->cur_usedma = (master->can_dma &&
+			   stm32f4_spi_can_dma(master, spi_dev, transfer));
+
+	ret = stm32f4_spi_transfer_one_setup(spi, spi_dev, transfer);
+	if (ret) {
+		dev_err(spi->dev, "SPI transfer setup failed\n");
+		return ret;
+	}
+
+	if (spi->cur_usedma)
+		return stm32f4_spi_transfer_one_dma(spi, transfer);
+	else
+		return stm32f4_spi_transfer_one_irq(spi);
+}
+
+/**
+ * stm32f4_spi_unprepare_msg - relax the hardware
+ */
+static int stm32f4_spi_unprepare_msg(struct spi_master *master,
+				     struct spi_message *msg)
+{
+	struct stm32f4_spi *spi = spi_master_get_devdata(master);
+
+	stm32f4_spi_disable(spi);
+
+	return 0;
+}
+
+/**
+ * stm32f4_spi_config - configure SPI controller as SPI master
+ */
+static int stm32f4_spi_config(struct stm32f4_spi *spi)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&spi->lock, flags);
+
+	/* Ensure I2SMOD bit is kept cleared */
+	stm32f4_spi_clr_bits(spi, STM32F4_SPI_I2SCFGR,
+			     STM32F4_SPI_I2SCFGR_I2SMOD);
+
+	/*
+	 * - SS input value high
+	 * - Set the master mode (default Motorola mode)
+	 * - Consider 1 master/n slaves configuration and
+	 *   SS input value is determined by the SSI bit
+	 */
+	stm32f4_spi_set_bits(spi, STM32F4_SPI_CR1, STM32F4_SPI_CR1_SSI |
+						   STM32F4_SPI_CR1_MSTR |
+						   STM32F4_SPI_CR1_SSM);
+
+	spin_unlock_irqrestore(&spi->lock, flags);
+
+	return 0;
+}
+
+/**
+ * stm32f4_release_dma - release DMA tx and rx channels
+ */
+static void stm32f4_release_dma(struct spi_master *master)
+{
+	if (master->dma_tx)
+		dma_release_channel(master->dma_tx);
+	if (master->dma_rx)
+		dma_release_channel(master->dma_rx);
+}
+
+/**
+ * stm32f4_spi_dma_prep - prepare controller to use DMA tx and rx channels
+ */
+static int stm32f4_spi_dma_prep(struct stm32f4_spi *spi,  struct device *dev)
+{
+	struct spi_master *master = spi->master;
+
+	master->dma_tx = dma_request_slave_channel(spi->dev, "tx");
+	if (!master->dma_tx) {
+		dev_warn(dev, "failed to request tx dma channel\n");
+		return -ENODEV;
+	}
+
+	master->dma_rx = dma_request_slave_channel(spi->dev, "rx");
+	if (!master->dma_rx) {
+		dev_warn(dev, "failed to request rx dma channel\n");
+		stm32f4_release_dma(master);
+		return -ENODEV;
+	}
+
+	master->can_dma = stm32f4_spi_can_dma;
+	dev_info(dev, "DMA available");
+	return 0;
+}
+
+static const struct of_device_id stm32f4_spi_of_match[] = {
+	{ .compatible = "st,stm32f4-spi", },
+	{},
+};
+MODULE_DEVICE_TABLE(of, stm32f4_spi_of_match);
+
+static int stm32f4_spi_probe(struct platform_device *pdev)
+{
+	struct spi_master *master;
+	struct stm32f4_spi *spi;
+	struct resource *res;
+	int i, ret;
+
+	master = spi_alloc_master(&pdev->dev, sizeof(struct stm32f4_spi));
+	if (!master) {
+		dev_err(&pdev->dev, "spi master allocation failed\n");
+		return -ENOMEM;
+	}
+	platform_set_drvdata(pdev, master);
+
+	spi = spi_master_get_devdata(master);
+	spi->dev = &pdev->dev;
+	spi->master = master;
+	spin_lock_init(&spi->lock);
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	spi->base = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(spi->base)) {
+		ret = PTR_ERR(spi->base);
+		goto err_master_put;
+	}
+	spi->phys_addr = (dma_addr_t)res->start;
+
+	spi->irq = platform_get_irq(pdev, 0);
+	if (spi->irq <= 0) {
+		dev_err(&pdev->dev, "no irq: %d\n", spi->irq);
+		ret = -ENOENT;
+		goto err_master_put;
+	}
+	ret = devm_request_threaded_irq(&pdev->dev, spi->irq,
+					stm32f4_spi_irq_event,
+					stm32f4_spi_irq_thread,
+					IRQF_ONESHOT, pdev->name, master);
+	if (ret) {
+		dev_err(&pdev->dev, "irq%d request failed: %d\n", spi->irq,
+			ret);
+		goto err_master_put;
+	}
+
+	spi->clk = devm_clk_get(&pdev->dev, NULL);
+	if (IS_ERR(spi->clk)) {
+		ret = PTR_ERR(spi->clk);
+		dev_err(&pdev->dev, "clk get failed: %d\n", ret);
+		goto err_master_put;
+	}
+
+	ret = clk_prepare_enable(spi->clk);
+	if (ret) {
+		dev_err(&pdev->dev, "clk enable failed: %d\n", ret);
+		goto err_master_put;
+	}
+	spi->clk_rate = clk_get_rate(spi->clk);
+	if (!spi->clk_rate) {
+		dev_err(&pdev->dev, "clk rate = 0\n");
+		ret = -EINVAL;
+		goto err_clk_disable;
+	}
+
+	spi->rst = devm_reset_control_get_exclusive(&pdev->dev, NULL);
+	if (!IS_ERR(spi->rst)) {
+		reset_control_assert(spi->rst);
+		udelay(2);
+		reset_control_deassert(spi->rst);
+	}
+
+	ret = stm32f4_spi_config(spi);
+	if (ret) {
+		dev_err(&pdev->dev, "controller configuration failed: %d\n",
+			ret);
+		goto err_clk_disable;
+	}
+
+	master->dev.of_node = pdev->dev.of_node;
+	master->auto_runtime_pm = true;
+	master->bus_num = pdev->id;
+	master->mode_bits = SPI_CPHA | SPI_CPOL | SPI_CS_HIGH | SPI_LSB_FIRST;
+	master->flags = SPI_MASTER_MUST_RX | SPI_MASTER_MUST_TX;
+	master->bits_per_word_mask = SPI_BPW_MASK(8) | SPI_BPW_MASK(16);
+	master->max_speed_hz = spi->clk_rate / STM32F4_SPI_BR_DIV_MIN;
+	master->min_speed_hz = spi->clk_rate / STM32F4_SPI_BR_DIV_MAX;
+	master->setup = stm32f4_spi_setup;
+	master->prepare_message = stm32f4_spi_prepare_msg;
+	master->transfer_one = stm32f4_spi_transfer_one;
+	master->unprepare_message = stm32f4_spi_unprepare_msg;
+
+	/* optional DMA support */
+	ret = stm32f4_spi_dma_prep(spi, &pdev->dev);
+	if (ret < 0)
+		dev_warn(&pdev->dev, "DMA not available, using PIO mode\n");
+
+	pm_runtime_set_active(&pdev->dev);
+	pm_runtime_enable(&pdev->dev);
+
+	ret = devm_spi_register_master(&pdev->dev, master);
+	if (ret) {
+		dev_err(&pdev->dev, "spi master registration failed: %d\n",
+			ret);
+		goto err_dma_release;
+	}
+
+	if (!master->cs_gpios) {
+		dev_err(&pdev->dev, "no CS gpios available\n");
+		ret = -EINVAL;
+		goto err_dma_release;
+	}
+
+	for (i = 0; i < master->num_chipselect; i++) {
+		if (!gpio_is_valid(master->cs_gpios[i])) {
+			dev_err(&pdev->dev, "%i is not a valid gpio\n",
+				master->cs_gpios[i]);
+			ret = -EINVAL;
+			goto err_dma_release;
+		}
+
+		ret = devm_gpio_request(&pdev->dev, master->cs_gpios[i],
+					DRIVER_NAME);
+		if (ret) {
+			dev_err(&pdev->dev, "can't get CS gpio %i\n",
+				master->cs_gpios[i]);
+			goto err_dma_release;
+		}
+	}
+
+	dev_info(&pdev->dev, "driver initialized\n");
+
+	return 0;
+
+err_dma_release:
+	stm32f4_release_dma(master);
+
+	pm_runtime_disable(&pdev->dev);
+err_clk_disable:
+	clk_disable_unprepare(spi->clk);
+err_master_put:
+	spi_master_put(master);
+
+	return ret;
+}
+
+static int stm32f4_spi_remove(struct platform_device *pdev)
+{
+	struct spi_master *master = platform_get_drvdata(pdev);
+	struct stm32f4_spi *spi = spi_master_get_devdata(master);
+
+	stm32f4_spi_disable(spi);
+
+	if (master->dma_tx)
+		dma_release_channel(master->dma_tx);
+	if (master->dma_rx)
+		dma_release_channel(master->dma_rx);
+
+	clk_disable_unprepare(spi->clk);
+
+	pm_runtime_disable(&pdev->dev);
+
+	return 0;
+}
+
+#ifdef CONFIG_PM
+static int stm32f4_spi_runtime_suspend(struct device *dev)
+{
+	struct spi_master *master = dev_get_drvdata(dev);
+	struct stm32f4_spi *spi = spi_master_get_devdata(master);
+
+	clk_disable_unprepare(spi->clk);
+
+	return 0;
+}
+
+static int stm32f4_spi_runtime_resume(struct device *dev)
+{
+	struct spi_master *master = dev_get_drvdata(dev);
+	struct stm32f4_spi *spi = spi_master_get_devdata(master);
+
+	return clk_prepare_enable(spi->clk);
+}
+#endif
+
+#ifdef CONFIG_PM_SLEEP
+static int stm32f4_spi_suspend(struct device *dev)
+{
+	struct spi_master *master = dev_get_drvdata(dev);
+	int ret;
+
+	ret = spi_master_suspend(master);
+	if (ret)
+		return ret;
+
+	return pm_runtime_force_suspend(dev);
+}
+
+static int stm32f4_spi_resume(struct device *dev)
+{
+	struct spi_master *master = dev_get_drvdata(dev);
+	struct stm32f4_spi *spi = spi_master_get_devdata(master);
+	int ret;
+
+	ret = pm_runtime_force_resume(dev);
+	if (ret)
+		return ret;
+
+	ret = spi_master_resume(master);
+	if (ret)
+		clk_disable_unprepare(spi->clk);
+
+	return ret;
+}
+#endif
+
+static const struct dev_pm_ops stm32f4_spi_pm_ops = {
+	SET_SYSTEM_SLEEP_PM_OPS(stm32f4_spi_suspend, stm32f4_spi_resume)
+	SET_RUNTIME_PM_OPS(stm32f4_spi_runtime_suspend,
+			   stm32f4_spi_runtime_resume, NULL)
+};
+
+static struct platform_driver stm32f4_spi_driver = {
+	.probe = stm32f4_spi_probe,
+	.remove = stm32f4_spi_remove,
+	.driver = {
+		.name = DRIVER_NAME,
+		.pm = &stm32f4_spi_pm_ops,
+		.of_match_table = stm32f4_spi_of_match,
+	},
+};
+
+module_platform_driver(stm32f4_spi_driver);
+
+MODULE_ALIAS("platform:" DRIVER_NAME);
+MODULE_DESCRIPTION("STMicroelectronics STM32F4 SPI Controller driver");
+MODULE_AUTHOR("Cezary Gapinski <cezary.gapinski@gmail.com>");
+MODULE_LICENSE("GPL v2");
-- 
2.7.4


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

^ permalink raw reply related

* [PATCH 4/5] ARM: dts: stm32: add SPI support on STM32F429 SoC
From: cezary.gapinski @ 2018-12-09 13:53 UTC (permalink / raw)
  To: Mark Brown, linux-spi, linux-stm32, linux-arm-kernel,
	linux-kernel, Rob Herring, devicetree
  Cc: Mark Rutland, Amelie Delaunay, Cezary Gapinski, Alexandre Torgue,
	Maxime Coquelin
In-Reply-To: <1544363636-12161-1-git-send-email-cezary.gapinski@gmail.com>

From: Cezary Gapinski <cezary.gapinski@gmail.com>

This patch adds all SPI instances of the STM32F429 SoC.

Signed-off-by: Cezary Gapinski <cezary.gapinski@gmail.com>
---
 arch/arm/boot/dts/stm32f429.dtsi | 60 ++++++++++++++++++++++++++++++++++++++++
 1 file changed, 60 insertions(+)

diff --git a/arch/arm/boot/dts/stm32f429.dtsi b/arch/arm/boot/dts/stm32f429.dtsi
index 8d6f028..8dbec00 100644
--- a/arch/arm/boot/dts/stm32f429.dtsi
+++ b/arch/arm/boot/dts/stm32f429.dtsi
@@ -314,6 +314,26 @@
 			status = "disabled";
 		};
 
+		spi2: spi@40003800 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "st,stm32f4-spi";
+			reg = <0x40003800 0x400>;
+			interrupts = <36>;
+			clocks = <&rcc 0 STM32F4_APB1_CLOCK(SPI2)>;
+			status = "disabled";
+		};
+
+		spi3: spi@40003C00 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "st,stm32f4-spi";
+			reg = <0x40003C00 0x400>;
+			interrupts = <51>;
+			clocks = <&rcc 0 STM32F4_APB1_CLOCK(SPI3)>;
+			status = "disabled";
+		};
+
 		usart2: serial@40004400 {
 			compatible = "st,stm32-uart";
 			reg = <0x40004400 0x400>;
@@ -523,6 +543,26 @@
 			status = "disabled";
 		};
 
+		spi1: spi@40013000 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "st,stm32f4-spi";
+			reg = <0x40013000 0x400>;
+			interrupts = <35>;
+			clocks = <&rcc 0 STM32F4_APB2_CLOCK(SPI1)>;
+			status = "disabled";
+		};
+
+		spi4: spi@40013400 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "st,stm32f4-spi";
+			reg = <0x40013400 0x400>;
+			interrupts = <84>;
+			clocks = <&rcc 0 STM32F4_APB2_CLOCK(SPI4)>;
+			status = "disabled";
+		};
+
 		syscfg: system-config@40013800 {
 			compatible = "syscon";
 			reg = <0x40013800 0x400>;
@@ -587,6 +627,26 @@
 			};
 		};
 
+		spi5: spi@40015000 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "st,stm32f4-spi";
+			reg = <0x40015000 0x400>;
+			interrupts = <85>;
+			clocks = <&rcc 0 STM32F4_APB2_CLOCK(SPI5)>;
+			status = "disabled";
+		};
+
+		spi6: spi@40015400 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "st,stm32f4-spi";
+			reg = <0x40015400 0x400>;
+			interrupts = <86>;
+			clocks = <&rcc 0 STM32F4_APB2_CLOCK(SPI6)>;
+			status = "disabled";
+		};
+
 		pwrcfg: power-config@40007000 {
 			compatible = "syscon";
 			reg = <0x40007000 0x400>;
-- 
2.7.4


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

^ permalink raw reply related

* [PATCH 1/5] spi: stm32: rename STM32 SPI registers and functions to STM32H7
From: cezary.gapinski @ 2018-12-09 13:53 UTC (permalink / raw)
  To: Mark Brown, linux-spi, linux-stm32, linux-arm-kernel,
	linux-kernel, Rob Herring, devicetree
  Cc: Mark Rutland, Amelie Delaunay, Cezary Gapinski, Alexandre Torgue,
	Maxime Coquelin
In-Reply-To: <1544363636-12161-1-git-send-email-cezary.gapinski@gmail.com>

From: Cezary Gapinski <cezary.gapinski@gmail.com>

Rename STM32 SPI registers and functions to be related to STM32H7 SPI
driver and not STM32 generally.

Signed-off-by: Cezary Gapinski <cezary.gapinski@gmail.com>
---
 drivers/spi/spi-stm32.c | 662 +++++++++++++++++++++++++-----------------------
 1 file changed, 340 insertions(+), 322 deletions(-)

diff --git a/drivers/spi/spi-stm32.c b/drivers/spi/spi-stm32.c
index ad1e55d..eb4d93e 100644
--- a/drivers/spi/spi-stm32.c
+++ b/drivers/spi/spi-stm32.c
@@ -33,97 +33,97 @@
 
 #define DRIVER_NAME "spi_stm32"
 
-/* STM32 SPI registers */
-#define STM32_SPI_CR1		0x00
-#define STM32_SPI_CR2		0x04
-#define STM32_SPI_CFG1		0x08
-#define STM32_SPI_CFG2		0x0C
-#define STM32_SPI_IER		0x10
-#define STM32_SPI_SR		0x14
-#define STM32_SPI_IFCR		0x18
-#define STM32_SPI_TXDR		0x20
-#define STM32_SPI_RXDR		0x30
-#define STM32_SPI_I2SCFGR	0x50
-
-/* STM32_SPI_CR1 bit fields */
-#define SPI_CR1_SPE		BIT(0)
-#define SPI_CR1_MASRX		BIT(8)
-#define SPI_CR1_CSTART		BIT(9)
-#define SPI_CR1_CSUSP		BIT(10)
-#define SPI_CR1_HDDIR		BIT(11)
-#define SPI_CR1_SSI		BIT(12)
-
-/* STM32_SPI_CR2 bit fields */
-#define SPI_CR2_TSIZE_SHIFT	0
-#define SPI_CR2_TSIZE		GENMASK(15, 0)
-
-/* STM32_SPI_CFG1 bit fields */
-#define SPI_CFG1_DSIZE_SHIFT	0
-#define SPI_CFG1_DSIZE		GENMASK(4, 0)
-#define SPI_CFG1_FTHLV_SHIFT	5
-#define SPI_CFG1_FTHLV		GENMASK(8, 5)
-#define SPI_CFG1_RXDMAEN	BIT(14)
-#define SPI_CFG1_TXDMAEN	BIT(15)
-#define SPI_CFG1_MBR_SHIFT	28
-#define SPI_CFG1_MBR		GENMASK(30, 28)
-#define SPI_CFG1_MBR_MIN	0
-#define SPI_CFG1_MBR_MAX	(GENMASK(30, 28) >> 28)
-
-/* STM32_SPI_CFG2 bit fields */
-#define SPI_CFG2_MIDI_SHIFT	4
-#define SPI_CFG2_MIDI		GENMASK(7, 4)
-#define SPI_CFG2_COMM_SHIFT	17
-#define SPI_CFG2_COMM		GENMASK(18, 17)
-#define SPI_CFG2_SP_SHIFT	19
-#define SPI_CFG2_SP		GENMASK(21, 19)
-#define SPI_CFG2_MASTER		BIT(22)
-#define SPI_CFG2_LSBFRST	BIT(23)
-#define SPI_CFG2_CPHA		BIT(24)
-#define SPI_CFG2_CPOL		BIT(25)
-#define SPI_CFG2_SSM		BIT(26)
-#define SPI_CFG2_AFCNTR		BIT(31)
-
-/* STM32_SPI_IER bit fields */
-#define SPI_IER_RXPIE		BIT(0)
-#define SPI_IER_TXPIE		BIT(1)
-#define SPI_IER_DXPIE		BIT(2)
-#define SPI_IER_EOTIE		BIT(3)
-#define SPI_IER_TXTFIE		BIT(4)
-#define SPI_IER_OVRIE		BIT(6)
-#define SPI_IER_MODFIE		BIT(9)
-#define SPI_IER_ALL		GENMASK(10, 0)
-
-/* STM32_SPI_SR bit fields */
-#define SPI_SR_RXP		BIT(0)
-#define SPI_SR_TXP		BIT(1)
-#define SPI_SR_EOT		BIT(3)
-#define SPI_SR_OVR		BIT(6)
-#define SPI_SR_MODF		BIT(9)
-#define SPI_SR_SUSP		BIT(11)
-#define SPI_SR_RXPLVL_SHIFT	13
-#define SPI_SR_RXPLVL		GENMASK(14, 13)
-#define SPI_SR_RXWNE		BIT(15)
-
-/* STM32_SPI_IFCR bit fields */
-#define SPI_IFCR_ALL		GENMASK(11, 3)
-
-/* STM32_SPI_I2SCFGR bit fields */
-#define SPI_I2SCFGR_I2SMOD	BIT(0)
-
-/* SPI Master Baud Rate min/max divisor */
-#define SPI_MBR_DIV_MIN		(2 << SPI_CFG1_MBR_MIN)
-#define SPI_MBR_DIV_MAX		(2 << SPI_CFG1_MBR_MAX)
-
-/* SPI Communication mode */
-#define SPI_FULL_DUPLEX		0
-#define SPI_SIMPLEX_TX		1
-#define SPI_SIMPLEX_RX		2
-#define SPI_HALF_DUPLEX		3
-
-#define SPI_1HZ_NS		1000000000
+/* STM32H7 SPI registers */
+#define STM32H7_SPI_CR1			0x00
+#define STM32H7_SPI_CR2			0x04
+#define STM32H7_SPI_CFG1		0x08
+#define STM32H7_SPI_CFG2		0x0C
+#define STM32H7_SPI_IER			0x10
+#define STM32H7_SPI_SR			0x14
+#define STM32H7_SPI_IFCR		0x18
+#define STM32H7_SPI_TXDR		0x20
+#define STM32H7_SPI_RXDR		0x30
+#define STM32H7_SPI_I2SCFGR		0x50
+
+/* STM32H7_SPI_CR1 bit fields */
+#define STM32H7_SPI_CR1_SPE		BIT(0)
+#define STM32H7_SPI_CR1_MASRX		BIT(8)
+#define STM32H7_SPI_CR1_CSTART		BIT(9)
+#define STM32H7_SPI_CR1_CSUSP		BIT(10)
+#define STM32H7_SPI_CR1_HDDIR		BIT(11)
+#define STM32H7_SPI_CR1_SSI		BIT(12)
+
+/* STM32H7_SPI_CR2 bit fields */
+#define STM32H7_SPI_CR2_TSIZE_SHIFT	0
+#define STM32H7_SPI_CR2_TSIZE		GENMASK(15, 0)
+
+/* STM32H7_SPI_CFG1 bit fields */
+#define STM32H7_SPI_CFG1_DSIZE_SHIFT	0
+#define STM32H7_SPI_CFG1_DSIZE		GENMASK(4, 0)
+#define STM32H7_SPI_CFG1_FTHLV_SHIFT	5
+#define STM32H7_SPI_CFG1_FTHLV		GENMASK(8, 5)
+#define STM32H7_SPI_CFG1_RXDMAEN	BIT(14)
+#define STM32H7_SPI_CFG1_TXDMAEN	BIT(15)
+#define STM32H7_SPI_CFG1_MBR_SHIFT	28
+#define STM32H7_SPI_CFG1_MBR		GENMASK(30, 28)
+#define STM32H7_SPI_CFG1_MBR_MIN	0
+#define STM32H7_SPI_CFG1_MBR_MAX	(GENMASK(30, 28) >> 28)
+
+/* STM32H7_SPI_CFG2 bit fields */
+#define STM32H7_SPI_CFG2_MIDI_SHIFT	4
+#define STM32H7_SPI_CFG2_MIDI		GENMASK(7, 4)
+#define STM32H7_SPI_CFG2_COMM_SHIFT	17
+#define STM32H7_SPI_CFG2_COMM		GENMASK(18, 17)
+#define STM32H7_SPI_CFG2_SP_SHIFT	19
+#define STM32H7_SPI_CFG2_SP		GENMASK(21, 19)
+#define STM32H7_SPI_CFG2_MASTER		BIT(22)
+#define STM32H7_SPI_CFG2_LSBFRST	BIT(23)
+#define STM32H7_SPI_CFG2_CPHA		BIT(24)
+#define STM32H7_SPI_CFG2_CPOL		BIT(25)
+#define STM32H7_SPI_CFG2_SSM		BIT(26)
+#define STM32H7_SPI_CFG2_AFCNTR		BIT(31)
+
+/* STM32H7_SPI_IER bit fields */
+#define STM32H7_SPI_IER_RXPIE		BIT(0)
+#define STM32H7_SPI_IER_TXPIE		BIT(1)
+#define STM32H7_SPI_IER_DXPIE		BIT(2)
+#define STM32H7_SPI_IER_EOTIE		BIT(3)
+#define STM32H7_SPI_IER_TXTFIE		BIT(4)
+#define STM32H7_SPI_IER_OVRIE		BIT(6)
+#define STM32H7_SPI_IER_MODFIE		BIT(9)
+#define STM32H7_SPI_IER_ALL		GENMASK(10, 0)
+
+/* STM32H7_SPI_SR bit fields */
+#define STM32H7_SPI_SR_RXP		BIT(0)
+#define STM32H7_SPI_SR_TXP		BIT(1)
+#define STM32H7_SPI_SR_EOT		BIT(3)
+#define STM32H7_SPI_SR_OVR		BIT(6)
+#define STM32H7_SPI_SR_MODF		BIT(9)
+#define STM32H7_SPI_SR_SUSP		BIT(11)
+#define STM32H7_SPI_SR_RXPLVL_SHIFT	13
+#define STM32H7_SPI_SR_RXPLVL		GENMASK(14, 13)
+#define STM32H7_SPI_SR_RXWNE		BIT(15)
+
+/* STM32H7_SPI_IFCR bit fields */
+#define STM32H7_SPI_IFCR_ALL		GENMASK(11, 3)
+
+/* STM32H7_SPI_I2SCFGR bit fields */
+#define STM32H7_SPI_I2SCFGR_I2SMOD	BIT(0)
+
+/* STM32H7 SPI Master Baud Rate min/max divisor */
+#define STM32H7_SPI_MBR_DIV_MIN		(2 << STM32H7_SPI_CFG1_MBR_MIN)
+#define STM32H7_SPI_MBR_DIV_MAX		(2 << STM32H7_SPI_CFG1_MBR_MAX)
+
+/* STM32H7 SPI Communication mode */
+#define STM32H7_SPI_FULL_DUPLEX		0
+#define STM32H7_SPI_SIMPLEX_TX		1
+#define STM32H7_SPI_SIMPLEX_RX		2
+#define STM32H7_SPI_HALF_DUPLEX		3
+
+#define STM32H7_SPI_1HZ_NS		1000000000
 
 /**
- * struct stm32_spi - private data of the SPI controller
+ * struct stm32h7_spi - private data of the SPI controller
  * @dev: driver model representation of the controller
  * @master: controller master interface
  * @base: virtual memory area
@@ -148,7 +148,7 @@
  * @dma_rx: dma channel for RX transfer
  * @phys_addr: SPI registers physical base address
  */
-struct stm32_spi {
+struct stm32h7_spi {
 	struct device *dev;
 	struct spi_master *master;
 	void __iomem *base;
@@ -176,37 +176,37 @@ struct stm32_spi {
 	dma_addr_t phys_addr;
 };
 
-static inline void stm32_spi_set_bits(struct stm32_spi *spi,
-				      u32 offset, u32 bits)
+static inline void stm32h7_spi_set_bits(struct stm32h7_spi *spi,
+					u32 offset, u32 bits)
 {
 	writel_relaxed(readl_relaxed(spi->base + offset) | bits,
 		       spi->base + offset);
 }
 
-static inline void stm32_spi_clr_bits(struct stm32_spi *spi,
-				      u32 offset, u32 bits)
+static inline void stm32h7_spi_clr_bits(struct stm32h7_spi *spi,
+					u32 offset, u32 bits)
 {
 	writel_relaxed(readl_relaxed(spi->base + offset) & ~bits,
 		       spi->base + offset);
 }
 
 /**
- * stm32_spi_get_fifo_size - Return fifo size
+ * stm32h7_spi_get_fifo_size - Return fifo size
  * @spi: pointer to the spi controller data structure
  */
-static int stm32_spi_get_fifo_size(struct stm32_spi *spi)
+static int stm32h7_spi_get_fifo_size(struct stm32h7_spi *spi)
 {
 	unsigned long flags;
 	u32 count = 0;
 
 	spin_lock_irqsave(&spi->lock, flags);
 
-	stm32_spi_set_bits(spi, STM32_SPI_CR1, SPI_CR1_SPE);
+	stm32h7_spi_set_bits(spi, STM32H7_SPI_CR1, STM32H7_SPI_CR1_SPE);
 
-	while (readl_relaxed(spi->base + STM32_SPI_SR) & SPI_SR_TXP)
-		writeb_relaxed(++count, spi->base + STM32_SPI_TXDR);
+	while (readl_relaxed(spi->base + STM32H7_SPI_SR) & STM32H7_SPI_SR_TXP)
+		writeb_relaxed(++count, spi->base + STM32H7_SPI_TXDR);
 
-	stm32_spi_clr_bits(spi, STM32_SPI_CR1, SPI_CR1_SPE);
+	stm32h7_spi_clr_bits(spi, STM32H7_SPI_CR1, STM32H7_SPI_CR1_SPE);
 
 	spin_unlock_irqrestore(&spi->lock, flags);
 
@@ -216,10 +216,10 @@ static int stm32_spi_get_fifo_size(struct stm32_spi *spi)
 }
 
 /**
- * stm32_spi_get_bpw_mask - Return bits per word mask
+ * stm32h7_spi_get_bpw_mask - Return bits per word mask
  * @spi: pointer to the spi controller data structure
  */
-static int stm32_spi_get_bpw_mask(struct stm32_spi *spi)
+static int stm32h7_spi_get_bpw_mask(struct stm32h7_spi *spi)
 {
 	unsigned long flags;
 	u32 cfg1, max_bpw;
@@ -230,10 +230,11 @@ static int stm32_spi_get_bpw_mask(struct stm32_spi *spi)
 	 * The most significant bit at DSIZE bit field is reserved when the
 	 * maximum data size of periperal instances is limited to 16-bit
 	 */
-	stm32_spi_set_bits(spi, STM32_SPI_CFG1, SPI_CFG1_DSIZE);
+	stm32h7_spi_set_bits(spi, STM32H7_SPI_CFG1, STM32H7_SPI_CFG1_DSIZE);
 
-	cfg1 = readl_relaxed(spi->base + STM32_SPI_CFG1);
-	max_bpw = (cfg1 & SPI_CFG1_DSIZE) >> SPI_CFG1_DSIZE_SHIFT;
+	cfg1 = readl_relaxed(spi->base + STM32H7_SPI_CFG1);
+	max_bpw = (cfg1 & STM32H7_SPI_CFG1_DSIZE) >>
+		  STM32H7_SPI_CFG1_DSIZE_SHIFT;
 	max_bpw += 1;
 
 	spin_unlock_irqrestore(&spi->lock, flags);
@@ -244,13 +245,13 @@ static int stm32_spi_get_bpw_mask(struct stm32_spi *spi)
 }
 
 /**
- * stm32_spi_prepare_mbr - Determine SPI_CFG1.MBR value
+ * stm32h7_spi_prepare_mbr - Determine STM32H7_SPI_CFG1.MBR value
  * @spi: pointer to the spi controller data structure
  * @speed_hz: requested speed
  *
- * Return SPI_CFG1.MBR value in case of success or -EINVAL
+ * Return STM32H7_SPI_CFG1.MBR value in case of success or -EINVAL
  */
-static int stm32_spi_prepare_mbr(struct stm32_spi *spi, u32 speed_hz)
+static int stm32h7_spi_prepare_mbr(struct stm32h7_spi *spi, u32 speed_hz)
 {
 	u32 div, mbrdiv;
 
@@ -263,8 +264,8 @@ static int stm32_spi_prepare_mbr(struct stm32_spi *spi, u32 speed_hz)
 	 * no need to check it there.
 	 * However, we need to ensure the following calculations.
 	 */
-	if (div < SPI_MBR_DIV_MIN ||
-	    div > SPI_MBR_DIV_MAX)
+	if (div < STM32H7_SPI_MBR_DIV_MIN ||
+	    div > STM32H7_SPI_MBR_DIV_MAX)
 		return -EINVAL;
 
 	/* Determine the first power of 2 greater than or equal to div */
@@ -279,10 +280,10 @@ static int stm32_spi_prepare_mbr(struct stm32_spi *spi, u32 speed_hz)
 }
 
 /**
- * stm32_spi_prepare_fthlv - Determine FIFO threshold level
+ * stm32h7_spi_prepare_fthlv - Determine FIFO threshold level
  * @spi: pointer to the spi controller data structure
  */
-static u32 stm32_spi_prepare_fthlv(struct stm32_spi *spi)
+static u32 stm32h7_spi_prepare_fthlv(struct stm32h7_spi *spi)
 {
 	u32 fthlv, half_fifo;
 
@@ -306,32 +307,33 @@ static u32 stm32_spi_prepare_fthlv(struct stm32_spi *spi)
 }
 
 /**
- * stm32_spi_write_txfifo - Write bytes in Transmit Data Register
+ * stm32h7_spi_write_txfifo - Write bytes in Transmit Data Register
  * @spi: pointer to the spi controller data structure
  *
  * Read from tx_buf depends on remaining bytes to avoid to read beyond
  * tx_buf end.
  */
-static void stm32_spi_write_txfifo(struct stm32_spi *spi)
+static void stm32h7_spi_write_txfifo(struct stm32h7_spi *spi)
 {
 	while ((spi->tx_len > 0) &&
-	       (readl_relaxed(spi->base + STM32_SPI_SR) & SPI_SR_TXP)) {
+	       (readl_relaxed(spi->base + STM32H7_SPI_SR) &
+		STM32H7_SPI_SR_TXP)) {
 		u32 offs = spi->cur_xferlen - spi->tx_len;
 
 		if (spi->tx_len >= sizeof(u32)) {
 			const u32 *tx_buf32 = (const u32 *)(spi->tx_buf + offs);
 
-			writel_relaxed(*tx_buf32, spi->base + STM32_SPI_TXDR);
+			writel_relaxed(*tx_buf32, spi->base + STM32H7_SPI_TXDR);
 			spi->tx_len -= sizeof(u32);
 		} else if (spi->tx_len >= sizeof(u16)) {
 			const u16 *tx_buf16 = (const u16 *)(spi->tx_buf + offs);
 
-			writew_relaxed(*tx_buf16, spi->base + STM32_SPI_TXDR);
+			writew_relaxed(*tx_buf16, spi->base + STM32H7_SPI_TXDR);
 			spi->tx_len -= sizeof(u16);
 		} else {
 			const u8 *tx_buf8 = (const u8 *)(spi->tx_buf + offs);
 
-			writeb_relaxed(*tx_buf8, spi->base + STM32_SPI_TXDR);
+			writeb_relaxed(*tx_buf8, spi->base + STM32H7_SPI_TXDR);
 			spi->tx_len -= sizeof(u8);
 		}
 	}
@@ -340,43 +342,45 @@ static void stm32_spi_write_txfifo(struct stm32_spi *spi)
 }
 
 /**
- * stm32_spi_read_rxfifo - Read bytes in Receive Data Register
+ * stm32h7_spi_read_rxfifo - Read bytes in Receive Data Register
  * @spi: pointer to the spi controller data structure
  *
  * Write in rx_buf depends on remaining bytes to avoid to write beyond
  * rx_buf end.
  */
-static void stm32_spi_read_rxfifo(struct stm32_spi *spi, bool flush)
+static void stm32h7_spi_read_rxfifo(struct stm32h7_spi *spi, bool flush)
 {
-	u32 sr = readl_relaxed(spi->base + STM32_SPI_SR);
-	u32 rxplvl = (sr & SPI_SR_RXPLVL) >> SPI_SR_RXPLVL_SHIFT;
+	u32 sr = readl_relaxed(spi->base + STM32H7_SPI_SR);
+	u32 rxplvl = (sr & STM32H7_SPI_SR_RXPLVL) >>
+		     STM32H7_SPI_SR_RXPLVL_SHIFT;
 
 	while ((spi->rx_len > 0) &&
-	       ((sr & SPI_SR_RXP) ||
-		(flush && ((sr & SPI_SR_RXWNE) || (rxplvl > 0))))) {
+	       ((sr & STM32H7_SPI_SR_RXP) ||
+		(flush && ((sr & STM32H7_SPI_SR_RXWNE) || (rxplvl > 0))))) {
 		u32 offs = spi->cur_xferlen - spi->rx_len;
 
 		if ((spi->rx_len >= sizeof(u32)) ||
-		    (flush && (sr & SPI_SR_RXWNE))) {
+		    (flush && (sr & STM32H7_SPI_SR_RXWNE))) {
 			u32 *rx_buf32 = (u32 *)(spi->rx_buf + offs);
 
-			*rx_buf32 = readl_relaxed(spi->base + STM32_SPI_RXDR);
+			*rx_buf32 = readl_relaxed(spi->base + STM32H7_SPI_RXDR);
 			spi->rx_len -= sizeof(u32);
 		} else if ((spi->rx_len >= sizeof(u16)) ||
 			   (flush && (rxplvl >= 2 || spi->cur_bpw > 8))) {
 			u16 *rx_buf16 = (u16 *)(spi->rx_buf + offs);
 
-			*rx_buf16 = readw_relaxed(spi->base + STM32_SPI_RXDR);
+			*rx_buf16 = readw_relaxed(spi->base + STM32H7_SPI_RXDR);
 			spi->rx_len -= sizeof(u16);
 		} else {
 			u8 *rx_buf8 = (u8 *)(spi->rx_buf + offs);
 
-			*rx_buf8 = readb_relaxed(spi->base + STM32_SPI_RXDR);
+			*rx_buf8 = readb_relaxed(spi->base + STM32H7_SPI_RXDR);
 			spi->rx_len -= sizeof(u8);
 		}
 
-		sr = readl_relaxed(spi->base + STM32_SPI_SR);
-		rxplvl = (sr & SPI_SR_RXPLVL) >> SPI_SR_RXPLVL_SHIFT;
+		sr = readl_relaxed(spi->base + STM32H7_SPI_SR);
+		rxplvl = (sr & STM32H7_SPI_SR_RXPLVL) >>
+			 STM32H7_SPI_SR_RXPLVL_SHIFT;
 	}
 
 	dev_dbg(spi->dev, "%s%s: %d bytes left\n", __func__,
@@ -384,28 +388,28 @@ static void stm32_spi_read_rxfifo(struct stm32_spi *spi, bool flush)
 }
 
 /**
- * stm32_spi_enable - Enable SPI controller
+ * stm32h7_spi_enable - Enable SPI controller
  * @spi: pointer to the spi controller data structure
  *
  * SPI data transfer is enabled but spi_ker_ck is idle.
- * SPI_CFG1 and SPI_CFG2 are now write protected.
+ * STM32H7_SPI_CFG1 and STM32H7_SPI_CFG2 are now write protected.
  */
-static void stm32_spi_enable(struct stm32_spi *spi)
+static void stm32h7_spi_enable(struct stm32h7_spi *spi)
 {
 	dev_dbg(spi->dev, "enable controller\n");
 
-	stm32_spi_set_bits(spi, STM32_SPI_CR1, SPI_CR1_SPE);
+	stm32h7_spi_set_bits(spi, STM32H7_SPI_CR1, STM32H7_SPI_CR1_SPE);
 }
 
 /**
- * stm32_spi_disable - Disable SPI controller
+ * stm32h7_spi_disable - Disable SPI controller
  * @spi: pointer to the spi controller data structure
  *
  * RX-Fifo is flushed when SPI controller is disabled. To prevent any data
- * loss, use stm32_spi_read_rxfifo(flush) to read the remaining bytes in
+ * loss, use stm32h7_spi_read_rxfifo(flush) to read the remaining bytes in
  * RX-Fifo.
  */
-static void stm32_spi_disable(struct stm32_spi *spi)
+static void stm32h7_spi_disable(struct stm32h7_spi *spi)
 {
 	unsigned long flags;
 	u32 cr1, sr;
@@ -414,23 +418,23 @@ static void stm32_spi_disable(struct stm32_spi *spi)
 
 	spin_lock_irqsave(&spi->lock, flags);
 
-	cr1 = readl_relaxed(spi->base + STM32_SPI_CR1);
+	cr1 = readl_relaxed(spi->base + STM32H7_SPI_CR1);
 
-	if (!(cr1 & SPI_CR1_SPE)) {
+	if (!(cr1 & STM32H7_SPI_CR1_SPE)) {
 		spin_unlock_irqrestore(&spi->lock, flags);
 		return;
 	}
 
 	/* Wait on EOT or suspend the flow */
-	if (readl_relaxed_poll_timeout_atomic(spi->base + STM32_SPI_SR,
-					      sr, !(sr & SPI_SR_EOT),
+	if (readl_relaxed_poll_timeout_atomic(spi->base + STM32H7_SPI_SR,
+					      sr, !(sr & STM32H7_SPI_SR_EOT),
 					      10, 100000) < 0) {
-		if (cr1 & SPI_CR1_CSTART) {
-			writel_relaxed(cr1 | SPI_CR1_CSUSP,
-				       spi->base + STM32_SPI_CR1);
+		if (cr1 & STM32H7_SPI_CR1_CSTART) {
+			writel_relaxed(cr1 | STM32H7_SPI_CR1_CSUSP,
+				       spi->base + STM32H7_SPI_CR1);
 			if (readl_relaxed_poll_timeout_atomic(
-						spi->base + STM32_SPI_SR,
-						sr, !(sr & SPI_SR_SUSP),
+						spi->base + STM32H7_SPI_SR,
+						sr, !(sr & STM32H7_SPI_SR_SUSP),
 						10, 100000) < 0)
 				dev_warn(spi->dev,
 					 "Suspend request timeout\n");
@@ -438,35 +442,35 @@ static void stm32_spi_disable(struct stm32_spi *spi)
 	}
 
 	if (!spi->cur_usedma && spi->rx_buf && (spi->rx_len > 0))
-		stm32_spi_read_rxfifo(spi, true);
+		stm32h7_spi_read_rxfifo(spi, true);
 
 	if (spi->cur_usedma && spi->tx_buf)
 		dmaengine_terminate_all(spi->dma_tx);
 	if (spi->cur_usedma && spi->rx_buf)
 		dmaengine_terminate_all(spi->dma_rx);
 
-	stm32_spi_clr_bits(spi, STM32_SPI_CR1, SPI_CR1_SPE);
+	stm32h7_spi_clr_bits(spi, STM32H7_SPI_CR1, STM32H7_SPI_CR1_SPE);
 
-	stm32_spi_clr_bits(spi, STM32_SPI_CFG1, SPI_CFG1_TXDMAEN |
-						SPI_CFG1_RXDMAEN);
+	stm32h7_spi_clr_bits(spi, STM32H7_SPI_CFG1, STM32H7_SPI_CFG1_TXDMAEN |
+						    STM32H7_SPI_CFG1_RXDMAEN);
 
 	/* Disable interrupts and clear status flags */
-	writel_relaxed(0, spi->base + STM32_SPI_IER);
-	writel_relaxed(SPI_IFCR_ALL, spi->base + STM32_SPI_IFCR);
+	writel_relaxed(0, spi->base + STM32H7_SPI_IER);
+	writel_relaxed(STM32H7_SPI_IFCR_ALL, spi->base + STM32H7_SPI_IFCR);
 
 	spin_unlock_irqrestore(&spi->lock, flags);
 }
 
 /**
- * stm32_spi_can_dma - Determine if the transfer is eligible for DMA use
+ * stm32h7_spi_can_dma - Determine if the transfer is eligible for DMA use
  *
  * If the current transfer size is greater than fifo size, use DMA.
  */
-static bool stm32_spi_can_dma(struct spi_master *master,
-			      struct spi_device *spi_dev,
-			      struct spi_transfer *transfer)
+static bool stm32h7_spi_can_dma(struct spi_master *master,
+				struct spi_device *spi_dev,
+				struct spi_transfer *transfer)
 {
-	struct stm32_spi *spi = spi_master_get_devdata(master);
+	struct stm32h7_spi *spi = spi_master_get_devdata(master);
 
 	dev_dbg(spi->dev, "%s: %s\n", __func__,
 		(transfer->len > spi->fifo_size) ? "true" : "false");
@@ -475,33 +479,33 @@ static bool stm32_spi_can_dma(struct spi_master *master,
 }
 
 /**
- * stm32_spi_irq - Interrupt handler for SPI controller events
+ * stm32h7_spi_irq - Interrupt handler for SPI controller events
  * @irq: interrupt line
  * @dev_id: SPI controller master interface
  */
-static irqreturn_t stm32_spi_irq(int irq, void *dev_id)
+static irqreturn_t stm32h7_spi_irq(int irq, void *dev_id)
 {
 	struct spi_master *master = dev_id;
-	struct stm32_spi *spi = spi_master_get_devdata(master);
+	struct stm32h7_spi *spi = spi_master_get_devdata(master);
 	u32 sr, ier, mask;
 	unsigned long flags;
 	bool end = false;
 
 	spin_lock_irqsave(&spi->lock, flags);
 
-	sr = readl_relaxed(spi->base + STM32_SPI_SR);
-	ier = readl_relaxed(spi->base + STM32_SPI_IER);
+	sr = readl_relaxed(spi->base + STM32H7_SPI_SR);
+	ier = readl_relaxed(spi->base + STM32H7_SPI_IER);
 
 	mask = ier;
 	/* EOTIE is triggered on EOT, SUSP and TXC events. */
-	mask |= SPI_SR_SUSP;
+	mask |= STM32H7_SPI_SR_SUSP;
 	/*
 	 * When TXTF is set, DXPIE and TXPIE are cleared. So in case of
 	 * Full-Duplex, need to poll RXP event to know if there are remaining
 	 * data, before disabling SPI.
 	 */
 	if (spi->rx_buf && !spi->cur_usedma)
-		mask |= SPI_SR_RXP;
+		mask |= STM32H7_SPI_SR_RXP;
 
 	if (!(sr & mask)) {
 		dev_dbg(spi->dev, "spurious IT (sr=0x%08x, ier=0x%08x)\n",
@@ -510,10 +514,10 @@ static irqreturn_t stm32_spi_irq(int irq, void *dev_id)
 		return IRQ_NONE;
 	}
 
-	if (sr & SPI_SR_SUSP) {
+	if (sr & STM32H7_SPI_SR_SUSP) {
 		dev_warn(spi->dev, "Communication suspended\n");
 		if (!spi->cur_usedma && (spi->rx_buf && (spi->rx_len > 0)))
-			stm32_spi_read_rxfifo(spi, false);
+			stm32h7_spi_read_rxfifo(spi, false);
 		/*
 		 * If communication is suspended while using DMA, it means
 		 * that something went wrong, so stop the current transfer
@@ -522,15 +526,15 @@ static irqreturn_t stm32_spi_irq(int irq, void *dev_id)
 			end = true;
 	}
 
-	if (sr & SPI_SR_MODF) {
+	if (sr & STM32H7_SPI_SR_MODF) {
 		dev_warn(spi->dev, "Mode fault: transfer aborted\n");
 		end = true;
 	}
 
-	if (sr & SPI_SR_OVR) {
+	if (sr & STM32H7_SPI_SR_OVR) {
 		dev_warn(spi->dev, "Overrun: received value discarded\n");
 		if (!spi->cur_usedma && (spi->rx_buf && (spi->rx_len > 0)))
-			stm32_spi_read_rxfifo(spi, false);
+			stm32h7_spi_read_rxfifo(spi, false);
 		/*
 		 * If overrun is detected while using DMA, it means that
 		 * something went wrong, so stop the current transfer
@@ -539,36 +543,36 @@ static irqreturn_t stm32_spi_irq(int irq, void *dev_id)
 			end = true;
 	}
 
-	if (sr & SPI_SR_EOT) {
+	if (sr & STM32H7_SPI_SR_EOT) {
 		if (!spi->cur_usedma && (spi->rx_buf && (spi->rx_len > 0)))
-			stm32_spi_read_rxfifo(spi, true);
+			stm32h7_spi_read_rxfifo(spi, true);
 		end = true;
 	}
 
-	if (sr & SPI_SR_TXP)
+	if (sr & STM32H7_SPI_SR_TXP)
 		if (!spi->cur_usedma && (spi->tx_buf && (spi->tx_len > 0)))
-			stm32_spi_write_txfifo(spi);
+			stm32h7_spi_write_txfifo(spi);
 
-	if (sr & SPI_SR_RXP)
+	if (sr & STM32H7_SPI_SR_RXP)
 		if (!spi->cur_usedma && (spi->rx_buf && (spi->rx_len > 0)))
-			stm32_spi_read_rxfifo(spi, false);
+			stm32h7_spi_read_rxfifo(spi, false);
 
-	writel_relaxed(mask, spi->base + STM32_SPI_IFCR);
+	writel_relaxed(mask, spi->base + STM32H7_SPI_IFCR);
 
 	spin_unlock_irqrestore(&spi->lock, flags);
 
 	if (end) {
 		spi_finalize_current_transfer(master);
-		stm32_spi_disable(spi);
+		stm32h7_spi_disable(spi);
 	}
 
 	return IRQ_HANDLED;
 }
 
 /**
- * stm32_spi_setup - setup device chip select
+ * stm32h7_spi_setup - setup device chip select
  */
-static int stm32_spi_setup(struct spi_device *spi_dev)
+static int stm32h7_spi_setup(struct spi_device *spi_dev)
 {
 	int ret = 0;
 
@@ -589,12 +593,12 @@ static int stm32_spi_setup(struct spi_device *spi_dev)
 }
 
 /**
- * stm32_spi_prepare_msg - set up the controller to transfer a single message
+ * stm32h7_spi_prepare_msg - set up the controller to transfer a single message
  */
-static int stm32_spi_prepare_msg(struct spi_master *master,
-				 struct spi_message *msg)
+static int stm32h7_spi_prepare_msg(struct spi_master *master,
+				   struct spi_message *msg)
 {
-	struct stm32_spi *spi = spi_master_get_devdata(master);
+	struct stm32h7_spi *spi = spi_master_get_devdata(master);
 	struct spi_device *spi_dev = msg->spi;
 	struct device_node *np = spi_dev->dev.of_node;
 	unsigned long flags;
@@ -606,19 +610,19 @@ static int stm32_spi_prepare_msg(struct spi_master *master,
 		dev_dbg(spi->dev, "%dns inter-data idleness\n", spi->cur_midi);
 
 	if (spi_dev->mode & SPI_CPOL)
-		cfg2_setb |= SPI_CFG2_CPOL;
+		cfg2_setb |= STM32H7_SPI_CFG2_CPOL;
 	else
-		cfg2_clrb |= SPI_CFG2_CPOL;
+		cfg2_clrb |= STM32H7_SPI_CFG2_CPOL;
 
 	if (spi_dev->mode & SPI_CPHA)
-		cfg2_setb |= SPI_CFG2_CPHA;
+		cfg2_setb |= STM32H7_SPI_CFG2_CPHA;
 	else
-		cfg2_clrb |= SPI_CFG2_CPHA;
+		cfg2_clrb |= STM32H7_SPI_CFG2_CPHA;
 
 	if (spi_dev->mode & SPI_LSB_FIRST)
-		cfg2_setb |= SPI_CFG2_LSBFRST;
+		cfg2_setb |= STM32H7_SPI_CFG2_LSBFRST;
 	else
-		cfg2_clrb |= SPI_CFG2_LSBFRST;
+		cfg2_clrb |= STM32H7_SPI_CFG2_LSBFRST;
 
 	dev_dbg(spi->dev, "cpol=%d cpha=%d lsb_first=%d cs_high=%d\n",
 		spi_dev->mode & SPI_CPOL,
@@ -630,9 +634,9 @@ static int stm32_spi_prepare_msg(struct spi_master *master,
 
 	if (cfg2_clrb || cfg2_setb)
 		writel_relaxed(
-			(readl_relaxed(spi->base + STM32_SPI_CFG2) &
+			(readl_relaxed(spi->base + STM32H7_SPI_CFG2) &
 				~cfg2_clrb) | cfg2_setb,
-			       spi->base + STM32_SPI_CFG2);
+			       spi->base + STM32H7_SPI_CFG2);
 
 	spin_unlock_irqrestore(&spi->lock, flags);
 
@@ -640,36 +644,36 @@ static int stm32_spi_prepare_msg(struct spi_master *master,
 }
 
 /**
- * stm32_spi_dma_cb - dma callback
+ * stm32h7_spi_dma_cb - dma callback
  *
  * DMA callback is called when the transfer is complete or when an error
  * occurs. If the transfer is complete, EOT flag is raised.
  */
-static void stm32_spi_dma_cb(void *data)
+static void stm32h7_spi_dma_cb(void *data)
 {
-	struct stm32_spi *spi = data;
+	struct stm32h7_spi *spi = data;
 	unsigned long flags;
 	u32 sr;
 
 	spin_lock_irqsave(&spi->lock, flags);
 
-	sr = readl_relaxed(spi->base + STM32_SPI_SR);
+	sr = readl_relaxed(spi->base + STM32H7_SPI_SR);
 
 	spin_unlock_irqrestore(&spi->lock, flags);
 
-	if (!(sr & SPI_SR_EOT))
+	if (!(sr & STM32H7_SPI_SR_EOT))
 		dev_warn(spi->dev, "DMA error (sr=0x%08x)\n", sr);
 
 	/* Now wait for EOT, or SUSP or OVR in case of error */
 }
 
 /**
- * stm32_spi_dma_config - configure dma slave channel depending on current
- *			  transfer bits_per_word.
+ * stm32h7_spi_dma_config - configure dma slave channel depending on current
+ *			    transfer bits_per_word.
  */
-static void stm32_spi_dma_config(struct stm32_spi *spi,
-				 struct dma_slave_config *dma_conf,
-				 enum dma_transfer_direction dir)
+static void stm32h7_spi_dma_config(struct stm32h7_spi *spi,
+				   struct dma_slave_config *dma_conf,
+				   enum dma_transfer_direction dir)
 {
 	enum dma_slave_buswidth buswidth;
 	u32 maxburst;
@@ -690,14 +694,14 @@ static void stm32_spi_dma_config(struct stm32_spi *spi,
 	memset(dma_conf, 0, sizeof(struct dma_slave_config));
 	dma_conf->direction = dir;
 	if (dma_conf->direction == DMA_DEV_TO_MEM) { /* RX */
-		dma_conf->src_addr = spi->phys_addr + STM32_SPI_RXDR;
+		dma_conf->src_addr = spi->phys_addr + STM32H7_SPI_RXDR;
 		dma_conf->src_addr_width = buswidth;
 		dma_conf->src_maxburst = maxburst;
 
 		dev_dbg(spi->dev, "Rx DMA config buswidth=%d, maxburst=%d\n",
 			buswidth, maxburst);
 	} else if (dma_conf->direction == DMA_MEM_TO_DEV) { /* TX */
-		dma_conf->dst_addr = spi->phys_addr + STM32_SPI_TXDR;
+		dma_conf->dst_addr = spi->phys_addr + STM32H7_SPI_TXDR;
 		dma_conf->dst_addr_width = buswidth;
 		dma_conf->dst_maxburst = maxburst;
 
@@ -707,39 +711,40 @@ static void stm32_spi_dma_config(struct stm32_spi *spi,
 }
 
 /**
- * stm32_spi_transfer_one_irq - transfer a single spi_transfer using
- *				interrupts
+ * stm32h7_spi_transfer_one_irq - transfer a single spi_transfer using
+ *				  interrupts
  *
  * It must returns 0 if the transfer is finished or 1 if the transfer is still
  * in progress.
  */
-static int stm32_spi_transfer_one_irq(struct stm32_spi *spi)
+static int stm32h7_spi_transfer_one_irq(struct stm32h7_spi *spi)
 {
 	unsigned long flags;
 	u32 ier = 0;
 
 	/* Enable the interrupts relative to the current communication mode */
 	if (spi->tx_buf && spi->rx_buf)	/* Full Duplex */
-		ier |= SPI_IER_DXPIE;
+		ier |= STM32H7_SPI_IER_DXPIE;
 	else if (spi->tx_buf)		/* Half-Duplex TX dir or Simplex TX */
-		ier |= SPI_IER_TXPIE;
+		ier |= STM32H7_SPI_IER_TXPIE;
 	else if (spi->rx_buf)		/* Half-Duplex RX dir or Simplex RX */
-		ier |= SPI_IER_RXPIE;
+		ier |= STM32H7_SPI_IER_RXPIE;
 
 	/* Enable the interrupts relative to the end of transfer */
-	ier |= SPI_IER_EOTIE | SPI_IER_TXTFIE |	SPI_IER_OVRIE |	SPI_IER_MODFIE;
+	ier |= STM32H7_SPI_IER_EOTIE | STM32H7_SPI_IER_TXTFIE |
+	       STM32H7_SPI_IER_OVRIE | STM32H7_SPI_IER_MODFIE;
 
 	spin_lock_irqsave(&spi->lock, flags);
 
-	stm32_spi_enable(spi);
+	stm32h7_spi_enable(spi);
 
 	/* Be sure to have data in fifo before starting data transfer */
 	if (spi->tx_buf)
-		stm32_spi_write_txfifo(spi);
+		stm32h7_spi_write_txfifo(spi);
 
-	stm32_spi_set_bits(spi, STM32_SPI_CR1, SPI_CR1_CSTART);
+	stm32h7_spi_set_bits(spi, STM32H7_SPI_CR1, STM32H7_SPI_CR1_CSTART);
 
-	writel_relaxed(ier, spi->base + STM32_SPI_IER);
+	writel_relaxed(ier, spi->base + STM32H7_SPI_IER);
 
 	spin_unlock_irqrestore(&spi->lock, flags);
 
@@ -747,13 +752,13 @@ static int stm32_spi_transfer_one_irq(struct stm32_spi *spi)
 }
 
 /**
- * stm32_spi_transfer_one_dma - transfer a single spi_transfer using DMA
+ * stm32h7_spi_transfer_one_dma - transfer a single spi_transfer using DMA
  *
  * It must returns 0 if the transfer is finished or 1 if the transfer is still
  * in progress.
  */
-static int stm32_spi_transfer_one_dma(struct stm32_spi *spi,
-				      struct spi_transfer *xfer)
+static int stm32h7_spi_transfer_one_dma(struct stm32h7_spi *spi,
+					struct spi_transfer *xfer)
 {
 	struct dma_slave_config tx_dma_conf, rx_dma_conf;
 	struct dma_async_tx_descriptor *tx_dma_desc, *rx_dma_desc;
@@ -764,11 +769,12 @@ static int stm32_spi_transfer_one_dma(struct stm32_spi *spi,
 
 	rx_dma_desc = NULL;
 	if (spi->rx_buf) {
-		stm32_spi_dma_config(spi, &rx_dma_conf, DMA_DEV_TO_MEM);
+		stm32h7_spi_dma_config(spi, &rx_dma_conf, DMA_DEV_TO_MEM);
 		dmaengine_slave_config(spi->dma_rx, &rx_dma_conf);
 
 		/* Enable Rx DMA request */
-		stm32_spi_set_bits(spi, STM32_SPI_CFG1, SPI_CFG1_RXDMAEN);
+		stm32h7_spi_set_bits(spi, STM32H7_SPI_CFG1,
+				   STM32H7_SPI_CFG1_RXDMAEN);
 
 		rx_dma_desc = dmaengine_prep_slave_sg(
 					spi->dma_rx, xfer->rx_sg.sgl,
@@ -779,7 +785,7 @@ static int stm32_spi_transfer_one_dma(struct stm32_spi *spi,
 
 	tx_dma_desc = NULL;
 	if (spi->tx_buf) {
-		stm32_spi_dma_config(spi, &tx_dma_conf, DMA_MEM_TO_DEV);
+		stm32h7_spi_dma_config(spi, &tx_dma_conf, DMA_MEM_TO_DEV);
 		dmaengine_slave_config(spi->dma_tx, &tx_dma_conf);
 
 		tx_dma_desc = dmaengine_prep_slave_sg(
@@ -794,7 +800,7 @@ static int stm32_spi_transfer_one_dma(struct stm32_spi *spi,
 		goto dma_desc_error;
 
 	if (rx_dma_desc) {
-		rx_dma_desc->callback = stm32_spi_dma_cb;
+		rx_dma_desc->callback = stm32h7_spi_dma_cb;
 		rx_dma_desc->callback_param = spi;
 
 		if (dma_submit_error(dmaengine_submit(rx_dma_desc))) {
@@ -806,8 +812,8 @@ static int stm32_spi_transfer_one_dma(struct stm32_spi *spi,
 	}
 
 	if (tx_dma_desc) {
-		if (spi->cur_comm == SPI_SIMPLEX_TX) {
-			tx_dma_desc->callback = stm32_spi_dma_cb;
+		if (spi->cur_comm == STM32H7_SPI_SIMPLEX_TX) {
+			tx_dma_desc->callback = stm32h7_spi_dma_cb;
 			tx_dma_desc->callback_param = spi;
 		}
 
@@ -819,16 +825,18 @@ static int stm32_spi_transfer_one_dma(struct stm32_spi *spi,
 		dma_async_issue_pending(spi->dma_tx);
 
 		/* Enable Tx DMA request */
-		stm32_spi_set_bits(spi, STM32_SPI_CFG1, SPI_CFG1_TXDMAEN);
+		stm32h7_spi_set_bits(spi, STM32H7_SPI_CFG1,
+				     STM32H7_SPI_CFG1_TXDMAEN);
 	}
 
 	/* Enable the interrupts relative to the end of transfer */
-	ier |= SPI_IER_EOTIE | SPI_IER_TXTFIE |	SPI_IER_OVRIE |	SPI_IER_MODFIE;
-	writel_relaxed(ier, spi->base + STM32_SPI_IER);
+	ier |= STM32H7_SPI_IER_EOTIE | STM32H7_SPI_IER_TXTFIE |
+	       STM32H7_SPI_IER_OVRIE | STM32H7_SPI_IER_MODFIE;
+	writel_relaxed(ier, spi->base + STM32H7_SPI_IER);
 
-	stm32_spi_enable(spi);
+	stm32h7_spi_enable(spi);
 
-	stm32_spi_set_bits(spi, STM32_SPI_CR1, SPI_CR1_CSTART);
+	stm32h7_spi_set_bits(spi, STM32H7_SPI_CR1, STM32H7_SPI_CR1_CSTART);
 
 	spin_unlock_irqrestore(&spi->lock, flags);
 
@@ -839,23 +847,23 @@ static int stm32_spi_transfer_one_dma(struct stm32_spi *spi,
 		dmaengine_terminate_all(spi->dma_rx);
 
 dma_desc_error:
-	stm32_spi_clr_bits(spi, STM32_SPI_CFG1, SPI_CFG1_RXDMAEN);
+	stm32h7_spi_clr_bits(spi, STM32H7_SPI_CFG1, STM32H7_SPI_CFG1_RXDMAEN);
 
 	spin_unlock_irqrestore(&spi->lock, flags);
 
 	dev_info(spi->dev, "DMA issue: fall back to irq transfer\n");
 
-	return stm32_spi_transfer_one_irq(spi);
+	return stm32h7_spi_transfer_one_irq(spi);
 }
 
 /**
- * stm32_spi_transfer_one_setup - common setup to transfer a single
- *				  spi_transfer either using DMA or
- *				  interrupts.
+ * stm32h7_spi_transfer_one_setup - common setup to transfer a single
+ *				    spi_transfer either using DMA or
+ *				    interrupts.
  */
-static int stm32_spi_transfer_one_setup(struct stm32_spi *spi,
-					struct spi_device *spi_dev,
-					struct spi_transfer *transfer)
+static int stm32h7_spi_transfer_one_setup(struct stm32h7_spi *spi,
+					  struct spi_device *spi_dev,
+					  struct spi_transfer *transfer)
 {
 	unsigned long flags;
 	u32 cfg1_clrb = 0, cfg1_setb = 0, cfg2_clrb = 0, cfg2_setb = 0;
@@ -870,21 +878,23 @@ static int stm32_spi_transfer_one_setup(struct stm32_spi *spi,
 		spi->cur_bpw = transfer->bits_per_word;
 		bpw = spi->cur_bpw - 1;
 
-		cfg1_clrb |= SPI_CFG1_DSIZE;
-		cfg1_setb |= (bpw << SPI_CFG1_DSIZE_SHIFT) & SPI_CFG1_DSIZE;
+		cfg1_clrb |= STM32H7_SPI_CFG1_DSIZE;
+		cfg1_setb |= (bpw << STM32H7_SPI_CFG1_DSIZE_SHIFT) &
+			     STM32H7_SPI_CFG1_DSIZE;
 
-		spi->cur_fthlv = stm32_spi_prepare_fthlv(spi);
+		spi->cur_fthlv = stm32h7_spi_prepare_fthlv(spi);
 		fthlv = spi->cur_fthlv - 1;
 
-		cfg1_clrb |= SPI_CFG1_FTHLV;
-		cfg1_setb |= (fthlv << SPI_CFG1_FTHLV_SHIFT) & SPI_CFG1_FTHLV;
+		cfg1_clrb |= STM32H7_SPI_CFG1_FTHLV;
+		cfg1_setb |= (fthlv << STM32H7_SPI_CFG1_FTHLV_SHIFT) &
+			     STM32H7_SPI_CFG1_FTHLV;
 	}
 
 	if (spi->cur_speed != transfer->speed_hz) {
 		int mbr;
 
 		/* Update spi->cur_speed with real clock speed */
-		mbr = stm32_spi_prepare_mbr(spi, transfer->speed_hz);
+		mbr = stm32h7_spi_prepare_mbr(spi, transfer->speed_hz);
 		if (mbr < 0) {
 			ret = mbr;
 			goto out;
@@ -892,16 +902,17 @@ static int stm32_spi_transfer_one_setup(struct stm32_spi *spi,
 
 		transfer->speed_hz = spi->cur_speed;
 
-		cfg1_clrb |= SPI_CFG1_MBR;
-		cfg1_setb |= ((u32)mbr << SPI_CFG1_MBR_SHIFT) & SPI_CFG1_MBR;
+		cfg1_clrb |= STM32H7_SPI_CFG1_MBR;
+		cfg1_setb |= ((u32)mbr << STM32H7_SPI_CFG1_MBR_SHIFT) &
+			     STM32H7_SPI_CFG1_MBR;
 	}
 
 	if (cfg1_clrb || cfg1_setb)
-		writel_relaxed((readl_relaxed(spi->base + STM32_SPI_CFG1) &
+		writel_relaxed((readl_relaxed(spi->base + STM32H7_SPI_CFG1) &
 				~cfg1_clrb) | cfg1_setb,
-			       spi->base + STM32_SPI_CFG1);
+			       spi->base + STM32H7_SPI_CFG1);
 
-	mode = SPI_FULL_DUPLEX;
+	mode = STM32H7_SPI_FULL_DUPLEX;
 	if (spi_dev->mode & SPI_3WIRE) { /* MISO/MOSI signals shared */
 		/*
 		 * SPI_3WIRE and xfer->tx_buf != NULL and xfer->rx_buf != NULL
@@ -909,40 +920,46 @@ static int stm32_spi_transfer_one_setup(struct stm32_spi *spi,
 		 * on the valid buffer, we can determine the direction of the
 		 * transfer.
 		 */
-		mode = SPI_HALF_DUPLEX;
+		mode = STM32H7_SPI_HALF_DUPLEX;
 		if (!transfer->tx_buf)
-			stm32_spi_clr_bits(spi, STM32_SPI_CR1, SPI_CR1_HDDIR);
+			stm32h7_spi_clr_bits(spi, STM32H7_SPI_CR1,
+					     STM32H7_SPI_CR1_HDDIR);
 		else if (!transfer->rx_buf)
-			stm32_spi_set_bits(spi, STM32_SPI_CR1, SPI_CR1_HDDIR);
+			stm32h7_spi_set_bits(spi, STM32H7_SPI_CR1,
+					     STM32H7_SPI_CR1_HDDIR);
 	} else {
 		if (!transfer->tx_buf)
-			mode = SPI_SIMPLEX_RX;
+			mode = STM32H7_SPI_SIMPLEX_RX;
 		else if (!transfer->rx_buf)
-			mode = SPI_SIMPLEX_TX;
+			mode = STM32H7_SPI_SIMPLEX_TX;
 	}
 	if (spi->cur_comm != mode) {
 		spi->cur_comm = mode;
 
-		cfg2_clrb |= SPI_CFG2_COMM;
-		cfg2_setb |= (mode << SPI_CFG2_COMM_SHIFT) & SPI_CFG2_COMM;
+		cfg2_clrb |= STM32H7_SPI_CFG2_COMM;
+		cfg2_setb |= (mode << STM32H7_SPI_CFG2_COMM_SHIFT) &
+			     STM32H7_SPI_CFG2_COMM;
 	}
 
-	cfg2_clrb |= SPI_CFG2_MIDI;
+	cfg2_clrb |= STM32H7_SPI_CFG2_MIDI;
 	if ((transfer->len > 1) && (spi->cur_midi > 0)) {
-		u32 sck_period_ns = DIV_ROUND_UP(SPI_1HZ_NS, spi->cur_speed);
+		u32 sck_period_ns = DIV_ROUND_UP(STM32H7_SPI_1HZ_NS,
+						 spi->cur_speed);
 		u32 midi = min((u32)DIV_ROUND_UP(spi->cur_midi, sck_period_ns),
-			       (u32)SPI_CFG2_MIDI >> SPI_CFG2_MIDI_SHIFT);
+			       (u32)STM32H7_SPI_CFG2_MIDI >>
+			       STM32H7_SPI_CFG2_MIDI_SHIFT);
 
 		dev_dbg(spi->dev, "period=%dns, midi=%d(=%dns)\n",
 			sck_period_ns, midi, midi * sck_period_ns);
 
-		cfg2_setb |= (midi << SPI_CFG2_MIDI_SHIFT) & SPI_CFG2_MIDI;
+		cfg2_setb |= (midi << STM32H7_SPI_CFG2_MIDI_SHIFT) &
+			     STM32H7_SPI_CFG2_MIDI;
 	}
 
 	if (cfg2_clrb || cfg2_setb)
-		writel_relaxed((readl_relaxed(spi->base + STM32_SPI_CFG2) &
+		writel_relaxed((readl_relaxed(spi->base + STM32H7_SPI_CFG2) &
 				~cfg2_clrb) | cfg2_setb,
-			       spi->base + STM32_SPI_CFG2);
+			       spi->base + STM32H7_SPI_CFG2);
 
 	if (spi->cur_bpw <= 8)
 		nb_words = transfer->len;
@@ -950,10 +967,10 @@ static int stm32_spi_transfer_one_setup(struct stm32_spi *spi,
 		nb_words = DIV_ROUND_UP(transfer->len * 8, 16);
 	else
 		nb_words = DIV_ROUND_UP(transfer->len * 8, 32);
-	nb_words <<= SPI_CR2_TSIZE_SHIFT;
+	nb_words <<= STM32H7_SPI_CR2_TSIZE_SHIFT;
 
-	if (nb_words <= SPI_CR2_TSIZE) {
-		writel_relaxed(nb_words, spi->base + STM32_SPI_CR2);
+	if (nb_words <= STM32H7_SPI_CR2_TSIZE) {
+		writel_relaxed(nb_words, spi->base + STM32H7_SPI_CR2);
 	} else {
 		ret = -EMSGSIZE;
 		goto out;
@@ -979,16 +996,16 @@ static int stm32_spi_transfer_one_setup(struct stm32_spi *spi,
 }
 
 /**
- * stm32_spi_transfer_one - transfer a single spi_transfer
+ * stm32h7_spi_transfer_one - transfer a single spi_transfer
  *
  * It must return 0 if the transfer is finished or 1 if the transfer is still
  * in progress.
  */
-static int stm32_spi_transfer_one(struct spi_master *master,
-				  struct spi_device *spi_dev,
-				  struct spi_transfer *transfer)
+static int stm32h7_spi_transfer_one(struct spi_master *master,
+				    struct spi_device *spi_dev,
+				    struct spi_transfer *transfer)
 {
-	struct stm32_spi *spi = spi_master_get_devdata(master);
+	struct stm32h7_spi *spi = spi_master_get_devdata(master);
 	int ret;
 
 	spi->tx_buf = transfer->tx_buf;
@@ -997,58 +1014,59 @@ static int stm32_spi_transfer_one(struct spi_master *master,
 	spi->rx_len = spi->rx_buf ? transfer->len : 0;
 
 	spi->cur_usedma = (master->can_dma &&
-			   stm32_spi_can_dma(master, spi_dev, transfer));
+			   stm32h7_spi_can_dma(master, spi_dev, transfer));
 
-	ret = stm32_spi_transfer_one_setup(spi, spi_dev, transfer);
+	ret = stm32h7_spi_transfer_one_setup(spi, spi_dev, transfer);
 	if (ret) {
 		dev_err(spi->dev, "SPI transfer setup failed\n");
 		return ret;
 	}
 
 	if (spi->cur_usedma)
-		return stm32_spi_transfer_one_dma(spi, transfer);
+		return stm32h7_spi_transfer_one_dma(spi, transfer);
 	else
-		return stm32_spi_transfer_one_irq(spi);
+		return stm32h7_spi_transfer_one_irq(spi);
 }
 
 /**
- * stm32_spi_unprepare_msg - relax the hardware
+ * stm32h7_spi_unprepare_msg - relax the hardware
  *
  * Normally, if TSIZE has been configured, we should relax the hardware at the
  * reception of the EOT interrupt. But in case of error, EOT will not be
  * raised. So the subsystem unprepare_message call allows us to properly
  * complete the transfer from an hardware point of view.
  */
-static int stm32_spi_unprepare_msg(struct spi_master *master,
-				   struct spi_message *msg)
+static int stm32h7_spi_unprepare_msg(struct spi_master *master,
+				     struct spi_message *msg)
 {
-	struct stm32_spi *spi = spi_master_get_devdata(master);
+	struct stm32h7_spi *spi = spi_master_get_devdata(master);
 
-	stm32_spi_disable(spi);
+	stm32h7_spi_disable(spi);
 
 	return 0;
 }
 
 /**
- * stm32_spi_config - Configure SPI controller as SPI master
+ * stm32h7_spi_config - Configure SPI controller as SPI master
  */
-static int stm32_spi_config(struct stm32_spi *spi)
+static int stm32h7_spi_config(struct stm32h7_spi *spi)
 {
 	unsigned long flags;
 
 	spin_lock_irqsave(&spi->lock, flags);
 
 	/* Ensure I2SMOD bit is kept cleared */
-	stm32_spi_clr_bits(spi, STM32_SPI_I2SCFGR, SPI_I2SCFGR_I2SMOD);
+	stm32h7_spi_clr_bits(spi, STM32H7_SPI_I2SCFGR,
+			     STM32H7_SPI_I2SCFGR_I2SMOD);
 
 	/*
 	 * - SS input value high
 	 * - transmitter half duplex direction
 	 * - automatic communication suspend when RX-Fifo is full
 	 */
-	stm32_spi_set_bits(spi, STM32_SPI_CR1, SPI_CR1_SSI |
-					       SPI_CR1_HDDIR |
-					       SPI_CR1_MASRX);
+	stm32h7_spi_set_bits(spi, STM32H7_SPI_CR1, STM32H7_SPI_CR1_SSI |
+						   STM32H7_SPI_CR1_HDDIR |
+						   STM32H7_SPI_CR1_MASRX);
 
 	/*
 	 * - Set the master mode (default Motorola mode)
@@ -1056,29 +1074,29 @@ static int stm32_spi_config(struct stm32_spi *spi)
 	 *   SS input value is determined by the SSI bit
 	 * - keep control of all associated GPIOs
 	 */
-	stm32_spi_set_bits(spi, STM32_SPI_CFG2, SPI_CFG2_MASTER |
-						SPI_CFG2_SSM |
-						SPI_CFG2_AFCNTR);
+	stm32h7_spi_set_bits(spi, STM32H7_SPI_CFG2, STM32H7_SPI_CFG2_MASTER |
+						    STM32H7_SPI_CFG2_SSM |
+						    STM32H7_SPI_CFG2_AFCNTR);
 
 	spin_unlock_irqrestore(&spi->lock, flags);
 
 	return 0;
 }
 
-static const struct of_device_id stm32_spi_of_match[] = {
+static const struct of_device_id stm32h7_spi_of_match[] = {
 	{ .compatible = "st,stm32h7-spi", },
 	{},
 };
-MODULE_DEVICE_TABLE(of, stm32_spi_of_match);
+MODULE_DEVICE_TABLE(of, stm32h7_spi_of_match);
 
-static int stm32_spi_probe(struct platform_device *pdev)
+static int stm32h7_spi_probe(struct platform_device *pdev)
 {
 	struct spi_master *master;
-	struct stm32_spi *spi;
+	struct stm32h7_spi *spi;
 	struct resource *res;
 	int i, ret;
 
-	master = spi_alloc_master(&pdev->dev, sizeof(struct stm32_spi));
+	master = spi_alloc_master(&pdev->dev, sizeof(struct stm32h7_spi));
 	if (!master) {
 		dev_err(&pdev->dev, "spi master allocation failed\n");
 		return -ENOMEM;
@@ -1105,7 +1123,7 @@ static int stm32_spi_probe(struct platform_device *pdev)
 		goto err_master_put;
 	}
 	ret = devm_request_threaded_irq(&pdev->dev, spi->irq, NULL,
-					stm32_spi_irq, IRQF_ONESHOT,
+					stm32h7_spi_irq, IRQF_ONESHOT,
 					pdev->name, master);
 	if (ret) {
 		dev_err(&pdev->dev, "irq%d request failed: %d\n", spi->irq,
@@ -1139,9 +1157,9 @@ static int stm32_spi_probe(struct platform_device *pdev)
 		reset_control_deassert(spi->rst);
 	}
 
-	spi->fifo_size = stm32_spi_get_fifo_size(spi);
+	spi->fifo_size = stm32h7_spi_get_fifo_size(spi);
 
-	ret = stm32_spi_config(spi);
+	ret = stm32h7_spi_config(spi);
 	if (ret) {
 		dev_err(&pdev->dev, "controller configuration failed: %d\n",
 			ret);
@@ -1153,13 +1171,13 @@ static int stm32_spi_probe(struct platform_device *pdev)
 	master->bus_num = pdev->id;
 	master->mode_bits = SPI_MODE_3 | SPI_CS_HIGH | SPI_LSB_FIRST |
 			    SPI_3WIRE | SPI_LOOP;
-	master->bits_per_word_mask = stm32_spi_get_bpw_mask(spi);
-	master->max_speed_hz = spi->clk_rate / SPI_MBR_DIV_MIN;
-	master->min_speed_hz = spi->clk_rate / SPI_MBR_DIV_MAX;
-	master->setup = stm32_spi_setup;
-	master->prepare_message = stm32_spi_prepare_msg;
-	master->transfer_one = stm32_spi_transfer_one;
-	master->unprepare_message = stm32_spi_unprepare_msg;
+	master->bits_per_word_mask = stm32h7_spi_get_bpw_mask(spi);
+	master->max_speed_hz = spi->clk_rate / STM32H7_SPI_MBR_DIV_MIN;
+	master->min_speed_hz = spi->clk_rate / STM32H7_SPI_MBR_DIV_MAX;
+	master->setup = stm32h7_spi_setup;
+	master->prepare_message = stm32h7_spi_prepare_msg;
+	master->transfer_one = stm32h7_spi_transfer_one;
+	master->unprepare_message = stm32h7_spi_unprepare_msg;
 
 	spi->dma_tx = dma_request_slave_channel(spi->dev, "tx");
 	if (!spi->dma_tx)
@@ -1174,7 +1192,7 @@ static int stm32_spi_probe(struct platform_device *pdev)
 		master->dma_rx = spi->dma_rx;
 
 	if (spi->dma_tx || spi->dma_rx)
-		master->can_dma = stm32_spi_can_dma;
+		master->can_dma = stm32h7_spi_can_dma;
 
 	pm_runtime_set_active(&pdev->dev);
 	pm_runtime_enable(&pdev->dev);
@@ -1228,12 +1246,12 @@ static int stm32_spi_probe(struct platform_device *pdev)
 	return ret;
 }
 
-static int stm32_spi_remove(struct platform_device *pdev)
+static int stm32h7_spi_remove(struct platform_device *pdev)
 {
 	struct spi_master *master = platform_get_drvdata(pdev);
-	struct stm32_spi *spi = spi_master_get_devdata(master);
+	struct stm32h7_spi *spi = spi_master_get_devdata(master);
 
-	stm32_spi_disable(spi);
+	stm32h7_spi_disable(spi);
 
 	if (master->dma_tx)
 		dma_release_channel(master->dma_tx);
@@ -1248,27 +1266,27 @@ static int stm32_spi_remove(struct platform_device *pdev)
 }
 
 #ifdef CONFIG_PM
-static int stm32_spi_runtime_suspend(struct device *dev)
+static int stm32h7_spi_runtime_suspend(struct device *dev)
 {
 	struct spi_master *master = dev_get_drvdata(dev);
-	struct stm32_spi *spi = spi_master_get_devdata(master);
+	struct stm32h7_spi *spi = spi_master_get_devdata(master);
 
 	clk_disable_unprepare(spi->clk);
 
 	return 0;
 }
 
-static int stm32_spi_runtime_resume(struct device *dev)
+static int stm32h7_spi_runtime_resume(struct device *dev)
 {
 	struct spi_master *master = dev_get_drvdata(dev);
-	struct stm32_spi *spi = spi_master_get_devdata(master);
+	struct stm32h7_spi *spi = spi_master_get_devdata(master);
 
 	return clk_prepare_enable(spi->clk);
 }
 #endif
 
 #ifdef CONFIG_PM_SLEEP
-static int stm32_spi_suspend(struct device *dev)
+static int stm32h7_spi_suspend(struct device *dev)
 {
 	struct spi_master *master = dev_get_drvdata(dev);
 	int ret;
@@ -1280,10 +1298,10 @@ static int stm32_spi_suspend(struct device *dev)
 	return pm_runtime_force_suspend(dev);
 }
 
-static int stm32_spi_resume(struct device *dev)
+static int stm32h7_spi_resume(struct device *dev)
 {
 	struct spi_master *master = dev_get_drvdata(dev);
-	struct stm32_spi *spi = spi_master_get_devdata(master);
+	struct stm32h7_spi *spi = spi_master_get_devdata(master);
 	int ret;
 
 	ret = pm_runtime_force_resume(dev);
@@ -1298,23 +1316,23 @@ static int stm32_spi_resume(struct device *dev)
 }
 #endif
 
-static const struct dev_pm_ops stm32_spi_pm_ops = {
-	SET_SYSTEM_SLEEP_PM_OPS(stm32_spi_suspend, stm32_spi_resume)
-	SET_RUNTIME_PM_OPS(stm32_spi_runtime_suspend,
-			   stm32_spi_runtime_resume, NULL)
+static const struct dev_pm_ops stm32h7_spi_pm_ops = {
+	SET_SYSTEM_SLEEP_PM_OPS(stm32h7_spi_suspend, stm32h7_spi_resume)
+	SET_RUNTIME_PM_OPS(stm32h7_spi_runtime_suspend,
+			   stm32h7_spi_runtime_resume, NULL)
 };
 
-static struct platform_driver stm32_spi_driver = {
-	.probe = stm32_spi_probe,
-	.remove = stm32_spi_remove,
+static struct platform_driver stm32h7_spi_driver = {
+	.probe = stm32h7_spi_probe,
+	.remove = stm32h7_spi_remove,
 	.driver = {
 		.name = DRIVER_NAME,
-		.pm = &stm32_spi_pm_ops,
-		.of_match_table = stm32_spi_of_match,
+		.pm = &stm32h7_spi_pm_ops,
+		.of_match_table = stm32h7_spi_of_match,
 	},
 };
 
-module_platform_driver(stm32_spi_driver);
+module_platform_driver(stm32h7_spi_driver);
 
 MODULE_ALIAS("platform:" DRIVER_NAME);
 MODULE_DESCRIPTION("STMicroelectronics STM32 SPI Controller driver");
-- 
2.7.4


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

^ permalink raw reply related

* [PATCH 5/5] spi: stm32: add description about STM32F4 bindings
From: cezary.gapinski @ 2018-12-09 13:53 UTC (permalink / raw)
  To: Mark Brown, linux-spi, linux-stm32, linux-arm-kernel,
	linux-kernel, Rob Herring, devicetree
  Cc: Mark Rutland, Amelie Delaunay, Cezary Gapinski, Alexandre Torgue,
	Maxime Coquelin
In-Reply-To: <1544363636-12161-1-git-send-email-cezary.gapinski@gmail.com>

From: Cezary Gapinski <cezary.gapinski@gmail.com>

Add description that STM32F4 can be used in compatible property.
Master Inter-Data Idleness optional property cannot be used in STM32F4.

Signed-off-by: Cezary Gapinski <cezary.gapinski@gmail.com>
---
 Documentation/devicetree/bindings/spi/spi-stm32.txt | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/Documentation/devicetree/bindings/spi/spi-stm32.txt b/Documentation/devicetree/bindings/spi/spi-stm32.txt
index 1b3fa2c1..d82755c 100644
--- a/Documentation/devicetree/bindings/spi/spi-stm32.txt
+++ b/Documentation/devicetree/bindings/spi/spi-stm32.txt
@@ -7,7 +7,9 @@ from 4 to 32-bit data size. Although it can be configured as master or slave,
 only master is supported by the driver.
 
 Required properties:
-- compatible: Must be "st,stm32h7-spi".
+- compatible: Should be one of:
+  "st,stm32h7-spi"
+  "st,stm32f4-spi"
 - reg: Offset and length of the device's register set.
 - interrupts: Must contain the interrupt id.
 - clocks: Must contain an entry for spiclk (which feeds the internal clock
@@ -30,8 +32,9 @@ Child nodes represent devices on the SPI bus
   See ../spi/spi-bus.txt
 
 Optional properties:
-- st,spi-midi-ns: (Master Inter-Data Idleness) minimum time delay in
-		  nanoseconds inserted between two consecutive data frames.
+- st,spi-midi-ns: Only for STM32H7, (Master Inter-Data Idleness) minimum time
+		  delay in nanoseconds inserted between two consecutive data
+		  frames.
 
 
 Example:
-- 
2.7.4


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

^ permalink raw reply related

* [PATCH 0/5] Add support for STM32F4 SPI
From: cezary.gapinski @ 2018-12-09 13:53 UTC (permalink / raw)
  To: Mark Brown, linux-spi, linux-stm32, linux-arm-kernel,
	linux-kernel, Rob Herring, devicetree
  Cc: Mark Rutland, Amelie Delaunay, Cezary Gapinski, Alexandre Torgue,
	Maxime Coquelin

From: Cezary Gapinski <cezary.gapinski@gmail.com>

This series of patches adds support for first generation of SPI interface
for STM32F4 family.

This version of driver is mostly different to STM32H7 one. Based on linux
kernel I2C drivers for STM32 where drivers were splited into STM32F4 and
STM32F7 family the same approach seems to be sufficient for SPI STM32
drivers. Therefore STM32H7 driver was moved to spi-stm32h7.c file and
register and functions were renamed to be more specific to STM32H7.

For current version master mode with full-duplex and 8/16 bit data frame
format are supported. There is no TX and RX FIFOs like in STM32H7.
DMA capabilility is supported for messages longer than arbitrary number
of bytes (that is set already to 16 bytes) when TX and RX channels are
set at the same time.

Cezary Gapinski (5):
  spi: stm32: rename STM32 SPI registers and functions to STM32H7
  spi: stm32: rename spi-stm32 to spi-stm32h7
  spi: stm32: add driver for STM32F4 controller
  ARM: dts: stm32: add SPI support on STM32F429 SoC
  spi: stm32: add description about STM32F4 bindings

 .../devicetree/bindings/spi/spi-stm32.txt          |    9 +-
 arch/arm/boot/dts/stm32f429.dtsi                   |   60 +
 drivers/spi/Kconfig                                |   18 +-
 drivers/spi/Makefile                               |    3 +-
 drivers/spi/spi-stm32.c                            | 1322 -------------------
 drivers/spi/spi-stm32f4.c                          | 1002 +++++++++++++++
 drivers/spi/spi-stm32h7.c                          | 1340 ++++++++++++++++++++
 7 files changed, 2424 insertions(+), 1330 deletions(-)
 delete mode 100644 drivers/spi/spi-stm32.c
 create mode 100644 drivers/spi/spi-stm32f4.c
 create mode 100644 drivers/spi/spi-stm32h7.c

-- 
2.7.4


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

^ 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