* [PATCH 14/25] openrisc: fix cache maintainance the the sync_single_for_device DMA operation
From: Christoph Hellwig @ 2018-05-22 12:04 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180522120430.28709-1-hch@lst.de>
The cache maintaince in the sync_single_for_device operation should be
equivalent to the map_page operation to facilitate reusing buffers. Fix the
openrisc implementation by moving the cache maintaince performed in map_page
into the sync_single method, and calling that from map_page.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
arch/openrisc/kernel/dma.c | 42 +++++++++++++++++---------------------
1 file changed, 19 insertions(+), 23 deletions(-)
diff --git a/arch/openrisc/kernel/dma.c b/arch/openrisc/kernel/dma.c
index 7cadff93d179..d6a0bf1fa713 100644
--- a/arch/openrisc/kernel/dma.c
+++ b/arch/openrisc/kernel/dma.c
@@ -133,19 +133,15 @@ or1k_dma_free(struct device *dev, size_t size, void *vaddr,
free_pages_exact(vaddr, size);
}
-static dma_addr_t
-or1k_map_page(struct device *dev, struct page *page,
- unsigned long offset, size_t size,
- enum dma_data_direction dir,
- unsigned long attrs)
+static void
+or1k_sync_single_for_device(struct device *dev,
+ dma_addr_t dma_handle, size_t size,
+ enum dma_data_direction dir)
{
unsigned long cl;
- dma_addr_t addr = page_to_phys(page) + offset;
+ dma_addr_t addr = dma_handle;
struct cpuinfo_or1k *cpuinfo = &cpuinfo_or1k[smp_processor_id()];
- if (attrs & DMA_ATTR_SKIP_CPU_SYNC)
- return addr;
-
switch (dir) {
case DMA_TO_DEVICE:
/* Flush the dcache for the requested range */
@@ -168,6 +164,20 @@ or1k_map_page(struct device *dev, struct page *page,
break;
}
+}
+
+static dma_addr_t
+or1k_map_page(struct device *dev, struct page *page,
+ unsigned long offset, size_t size,
+ enum dma_data_direction dir,
+ unsigned long attrs)
+{
+ unsigned long cl;
+ dma_addr_t addr = page_to_phys(page) + offset;
+ struct cpuinfo_or1k *cpuinfo = &cpuinfo_or1k[smp_processor_id()];
+
+ if (!(attrs & DMA_ATTR_SKIP_CPU_SYNC))
+ or1k_sync_single_for_device(dev, addr, size, dir);
return addr;
}
@@ -187,20 +197,6 @@ or1k_map_sg(struct device *dev, struct scatterlist *sg,
return nents;
}
-static void
-or1k_sync_single_for_device(struct device *dev,
- dma_addr_t dma_handle, size_t size,
- enum dma_data_direction dir)
-{
- unsigned long cl;
- dma_addr_t addr = dma_handle;
- struct cpuinfo_or1k *cpuinfo = &cpuinfo_or1k[smp_processor_id()];
-
- /* Flush the dcache for the requested range */
- for (cl = addr; cl < addr + size; cl += cpuinfo->dcache_block_size)
- mtspr(SPR_DCBFR, cl);
-}
-
const struct dma_map_ops or1k_dma_map_ops = {
.alloc = or1k_dma_alloc,
.free = or1k_dma_free,
--
2.17.0
^ permalink raw reply related
* [PATCH 13/25] openrisc: remove the no-op unmap_page and unmap_sg DMA operations
From: Christoph Hellwig @ 2018-05-22 12:04 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180522120430.28709-1-hch@lst.de>
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
arch/openrisc/kernel/dma.c | 23 -----------------------
1 file changed, 23 deletions(-)
diff --git a/arch/openrisc/kernel/dma.c b/arch/openrisc/kernel/dma.c
index 47601274abf7..7cadff93d179 100644
--- a/arch/openrisc/kernel/dma.c
+++ b/arch/openrisc/kernel/dma.c
@@ -171,14 +171,6 @@ or1k_map_page(struct device *dev, struct page *page,
return addr;
}
-static void
-or1k_unmap_page(struct device *dev, dma_addr_t dma_handle,
- size_t size, enum dma_data_direction dir,
- unsigned long attrs)
-{
- /* Nothing special to do here... */
-}
-
static int
or1k_map_sg(struct device *dev, struct scatterlist *sg,
int nents, enum dma_data_direction dir,
@@ -195,19 +187,6 @@ or1k_map_sg(struct device *dev, struct scatterlist *sg,
return nents;
}
-static void
-or1k_unmap_sg(struct device *dev, struct scatterlist *sg,
- int nents, enum dma_data_direction dir,
- unsigned long attrs)
-{
- struct scatterlist *s;
- int i;
-
- for_each_sg(sg, s, nents, i) {
- or1k_unmap_page(dev, sg_dma_address(s), sg_dma_len(s), dir, 0);
- }
-}
-
static void
or1k_sync_single_for_device(struct device *dev,
dma_addr_t dma_handle, size_t size,
@@ -226,9 +205,7 @@ const struct dma_map_ops or1k_dma_map_ops = {
.alloc = or1k_dma_alloc,
.free = or1k_dma_free,
.map_page = or1k_map_page,
- .unmap_page = or1k_unmap_page,
.map_sg = or1k_map_sg,
- .unmap_sg = or1k_unmap_sg,
.sync_single_for_device = or1k_sync_single_for_device,
};
EXPORT_SYMBOL(or1k_dma_map_ops);
--
2.17.0
^ permalink raw reply related
* [PATCH 12/25] openrisc: remove the sync_single_for_cpu DMA operation
From: Christoph Hellwig @ 2018-05-22 12:04 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180522120430.28709-1-hch@lst.de>
openrisc does all the required cache maintainance at dma map time, and none
at unmap time. It thus has to implement sync_single_for_device to match
the map cace for buffer reuse, but there is no point in doing another
invalidation in the sync_single_cpu_case, which in terms of cache
maintainance is equivalent to the unmap case.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
arch/openrisc/kernel/dma.c | 15 ---------------
1 file changed, 15 deletions(-)
diff --git a/arch/openrisc/kernel/dma.c b/arch/openrisc/kernel/dma.c
index ec7fd45704d2..47601274abf7 100644
--- a/arch/openrisc/kernel/dma.c
+++ b/arch/openrisc/kernel/dma.c
@@ -208,20 +208,6 @@ or1k_unmap_sg(struct device *dev, struct scatterlist *sg,
}
}
-static void
-or1k_sync_single_for_cpu(struct device *dev,
- dma_addr_t dma_handle, size_t size,
- enum dma_data_direction dir)
-{
- unsigned long cl;
- dma_addr_t addr = dma_handle;
- struct cpuinfo_or1k *cpuinfo = &cpuinfo_or1k[smp_processor_id()];
-
- /* Invalidate the dcache for the requested range */
- for (cl = addr; cl < addr + size; cl += cpuinfo->dcache_block_size)
- mtspr(SPR_DCBIR, cl);
-}
-
static void
or1k_sync_single_for_device(struct device *dev,
dma_addr_t dma_handle, size_t size,
@@ -243,7 +229,6 @@ const struct dma_map_ops or1k_dma_map_ops = {
.unmap_page = or1k_unmap_page,
.map_sg = or1k_map_sg,
.unmap_sg = or1k_unmap_sg,
- .sync_single_for_cpu = or1k_sync_single_for_cpu,
.sync_single_for_device = or1k_sync_single_for_device,
};
EXPORT_SYMBOL(or1k_dma_map_ops);
--
2.17.0
^ permalink raw reply related
* [PATCH 11/25] nios2: use generic dma_noncoherent_ops
From: Christoph Hellwig @ 2018-05-22 12:04 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180522120430.28709-1-hch@lst.de>
Switch to the generic noncoherent direct mapping implementation.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
arch/nios2/Kconfig | 3 +
arch/nios2/include/asm/Kbuild | 1 +
arch/nios2/include/asm/dma-mapping.h | 20 ----
arch/nios2/mm/dma-mapping.c | 139 +++------------------------
4 files changed, 17 insertions(+), 146 deletions(-)
delete mode 100644 arch/nios2/include/asm/dma-mapping.h
diff --git a/arch/nios2/Kconfig b/arch/nios2/Kconfig
index 3d4ec88f1db1..92035042cf62 100644
--- a/arch/nios2/Kconfig
+++ b/arch/nios2/Kconfig
@@ -1,6 +1,9 @@
# SPDX-License-Identifier: GPL-2.0
config NIOS2
def_bool y
+ select ARCH_HAS_SYNC_DMA_FOR_CPU
+ select ARCH_HAS_SYNC_DMA_FOR_DEVICE
+ select DMA_NONCOHERENT_OPS
select TIMER_OF
select GENERIC_ATOMIC64
select GENERIC_CLOCKEVENTS
diff --git a/arch/nios2/include/asm/Kbuild b/arch/nios2/include/asm/Kbuild
index d232da2cbb38..24f6ee1ee69b 100644
--- a/arch/nios2/include/asm/Kbuild
+++ b/arch/nios2/include/asm/Kbuild
@@ -8,6 +8,7 @@ generic-y += current.h
generic-y += device.h
generic-y += div64.h
generic-y += dma.h
+generic-y += dma-mapping.h
generic-y += emergency-restart.h
generic-y += exec.h
generic-y += extable.h
diff --git a/arch/nios2/include/asm/dma-mapping.h b/arch/nios2/include/asm/dma-mapping.h
deleted file mode 100644
index 6ceb92251da0..000000000000
--- a/arch/nios2/include/asm/dma-mapping.h
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * Copyright (C) 2011 Tobias Klauser <tklauser@distanz.ch>
- * Copyright (C) 2009 Wind River Systems Inc
- *
- * This file is subject to the terms and conditions of the GNU General
- * Public License. See the file COPYING in the main directory of this
- * archive for more details.
- */
-
-#ifndef _ASM_NIOS2_DMA_MAPPING_H
-#define _ASM_NIOS2_DMA_MAPPING_H
-
-extern const struct dma_map_ops nios2_dma_ops;
-
-static inline const struct dma_map_ops *get_arch_dma_ops(struct bus_type *bus)
-{
- return &nios2_dma_ops;
-}
-
-#endif /* _ASM_NIOS2_DMA_MAPPING_H */
diff --git a/arch/nios2/mm/dma-mapping.c b/arch/nios2/mm/dma-mapping.c
index 4be815519dd4..4af9e5b5ba1c 100644
--- a/arch/nios2/mm/dma-mapping.c
+++ b/arch/nios2/mm/dma-mapping.c
@@ -12,18 +12,18 @@
#include <linux/types.h>
#include <linux/mm.h>
-#include <linux/export.h>
#include <linux/string.h>
-#include <linux/scatterlist.h>
#include <linux/dma-mapping.h>
#include <linux/io.h>
#include <linux/cache.h>
#include <asm/cacheflush.h>
-static inline void __dma_sync_for_device(void *vaddr, size_t size,
- enum dma_data_direction direction)
+void arch_sync_dma_for_device(struct device *dev, phys_addr_t paddr,
+ size_t size, enum dma_data_direction dir)
{
- switch (direction) {
+ void *vaddr = phys_to_virt(paddr);
+
+ switch (dir) {
case DMA_FROM_DEVICE:
invalidate_dcache_range((unsigned long)vaddr,
(unsigned long)(vaddr + size));
@@ -42,10 +42,12 @@ static inline void __dma_sync_for_device(void *vaddr, size_t size,
}
}
-static inline void __dma_sync_for_cpu(void *vaddr, size_t size,
- enum dma_data_direction direction)
+void arch_sync_dma_for_cpu(struct device *dev, phys_addr_t paddr,
+ size_t size, enum dma_data_direction dir)
{
- switch (direction) {
+ void *vaddr = phys_to_virt(paddr);
+
+ switch (dir) {
case DMA_BIDIRECTIONAL:
case DMA_FROM_DEVICE:
invalidate_dcache_range((unsigned long)vaddr,
@@ -58,8 +60,8 @@ static inline void __dma_sync_for_cpu(void *vaddr, size_t size,
}
}
-static void *nios2_dma_alloc(struct device *dev, size_t size,
- dma_addr_t *dma_handle, gfp_t gfp, unsigned long attrs)
+void *arch_dma_alloc(struct device *dev, size_t size, dma_addr_t *dma_handle,
+ gfp_t gfp, unsigned long attrs)
{
void *ret;
@@ -80,125 +82,10 @@ static void *nios2_dma_alloc(struct device *dev, size_t size,
return ret;
}
-static void nios2_dma_free(struct device *dev, size_t size, void *vaddr,
+void arch_dma_free(struct device *dev, size_t size, void *vaddr,
dma_addr_t dma_handle, unsigned long attrs)
{
unsigned long addr = (unsigned long) CAC_ADDR((unsigned long) vaddr);
free_pages(addr, get_order(size));
}
-
-static int nios2_dma_map_sg(struct device *dev, struct scatterlist *sg,
- int nents, enum dma_data_direction direction,
- unsigned long attrs)
-{
- int i;
-
- for_each_sg(sg, sg, nents, i) {
- void *addr = sg_virt(sg);
-
- if (!addr)
- continue;
-
- sg->dma_address = sg_phys(sg);
-
- if (attrs & DMA_ATTR_SKIP_CPU_SYNC)
- continue;
-
- __dma_sync_for_device(addr, sg->length, direction);
- }
-
- return nents;
-}
-
-static dma_addr_t nios2_dma_map_page(struct device *dev, struct page *page,
- unsigned long offset, size_t size,
- enum dma_data_direction direction,
- unsigned long attrs)
-{
- void *addr = page_address(page) + offset;
-
- if (!(attrs & DMA_ATTR_SKIP_CPU_SYNC))
- __dma_sync_for_device(addr, size, direction);
-
- return page_to_phys(page) + offset;
-}
-
-static void nios2_dma_unmap_page(struct device *dev, dma_addr_t dma_address,
- size_t size, enum dma_data_direction direction,
- unsigned long attrs)
-{
- if (!(attrs & DMA_ATTR_SKIP_CPU_SYNC))
- __dma_sync_for_cpu(phys_to_virt(dma_address), size, direction);
-}
-
-static void nios2_dma_unmap_sg(struct device *dev, struct scatterlist *sg,
- int nhwentries, enum dma_data_direction direction,
- unsigned long attrs)
-{
- void *addr;
- int i;
-
- if (direction == DMA_TO_DEVICE)
- return;
-
- if (attrs & DMA_ATTR_SKIP_CPU_SYNC)
- return;
-
- for_each_sg(sg, sg, nhwentries, i) {
- addr = sg_virt(sg);
- if (addr)
- __dma_sync_for_cpu(addr, sg->length, direction);
- }
-}
-
-static void nios2_dma_sync_single_for_cpu(struct device *dev,
- dma_addr_t dma_handle, size_t size,
- enum dma_data_direction direction)
-{
- __dma_sync_for_cpu(phys_to_virt(dma_handle), size, direction);
-}
-
-static void nios2_dma_sync_single_for_device(struct device *dev,
- dma_addr_t dma_handle, size_t size,
- enum dma_data_direction direction)
-{
- __dma_sync_for_device(phys_to_virt(dma_handle), size, direction);
-}
-
-static void nios2_dma_sync_sg_for_cpu(struct device *dev,
- struct scatterlist *sg, int nelems,
- enum dma_data_direction direction)
-{
- int i;
-
- /* Make sure that gcc doesn't leave the empty loop body. */
- for_each_sg(sg, sg, nelems, i)
- __dma_sync_for_cpu(sg_virt(sg), sg->length, direction);
-}
-
-static void nios2_dma_sync_sg_for_device(struct device *dev,
- struct scatterlist *sg, int nelems,
- enum dma_data_direction direction)
-{
- int i;
-
- /* Make sure that gcc doesn't leave the empty loop body. */
- for_each_sg(sg, sg, nelems, i)
- __dma_sync_for_device(sg_virt(sg), sg->length, direction);
-
-}
-
-const struct dma_map_ops nios2_dma_ops = {
- .alloc = nios2_dma_alloc,
- .free = nios2_dma_free,
- .map_page = nios2_dma_map_page,
- .unmap_page = nios2_dma_unmap_page,
- .map_sg = nios2_dma_map_sg,
- .unmap_sg = nios2_dma_unmap_sg,
- .sync_single_for_device = nios2_dma_sync_single_for_device,
- .sync_single_for_cpu = nios2_dma_sync_single_for_cpu,
- .sync_sg_for_cpu = nios2_dma_sync_sg_for_cpu,
- .sync_sg_for_device = nios2_dma_sync_sg_for_device,
-};
-EXPORT_SYMBOL(nios2_dma_ops);
--
2.17.0
^ permalink raw reply related
* [PATCH 10/25] nds32: use generic dma_noncoherent_ops
From: Christoph Hellwig @ 2018-05-22 12:04 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180522120430.28709-1-hch@lst.de>
Switch to the generic noncoherent direct mapping implementation.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
arch/nds32/Kconfig | 3 +
arch/nds32/include/asm/Kbuild | 1 +
arch/nds32/include/asm/dma-mapping.h | 14 ----
arch/nds32/kernel/dma.c | 113 +++------------------------
4 files changed, 15 insertions(+), 116 deletions(-)
delete mode 100644 arch/nds32/include/asm/dma-mapping.h
diff --git a/arch/nds32/Kconfig b/arch/nds32/Kconfig
index 249f38d3388f..67d0ac0a989c 100644
--- a/arch/nds32/Kconfig
+++ b/arch/nds32/Kconfig
@@ -5,10 +5,13 @@
config NDS32
def_bool y
+ select ARCH_HAS_SYNC_DMA_FOR_CPU
+ select ARCH_HAS_SYNC_DMA_FOR_DEVICE
select ARCH_WANT_FRAME_POINTERS if FTRACE
select CLKSRC_MMIO
select CLONE_BACKWARDS
select COMMON_CLK
+ select DMA_NONCOHERENT_OPS
select GENERIC_ATOMIC64
select GENERIC_CPU_DEVICES
select GENERIC_CLOCKEVENTS
diff --git a/arch/nds32/include/asm/Kbuild b/arch/nds32/include/asm/Kbuild
index 06bdf8167f5a..b3e951f805f8 100644
--- a/arch/nds32/include/asm/Kbuild
+++ b/arch/nds32/include/asm/Kbuild
@@ -13,6 +13,7 @@ generic-y += cputime.h
generic-y += device.h
generic-y += div64.h
generic-y += dma.h
+generic-y += dma-mapping.h
generic-y += emergency-restart.h
generic-y += errno.h
generic-y += exec.h
diff --git a/arch/nds32/include/asm/dma-mapping.h b/arch/nds32/include/asm/dma-mapping.h
deleted file mode 100644
index 2dd47d245c25..000000000000
--- a/arch/nds32/include/asm/dma-mapping.h
+++ /dev/null
@@ -1,14 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-// Copyright (C) 2005-2017 Andes Technology Corporation
-
-#ifndef ASMNDS32_DMA_MAPPING_H
-#define ASMNDS32_DMA_MAPPING_H
-
-extern struct dma_map_ops nds32_dma_ops;
-
-static inline struct dma_map_ops *get_arch_dma_ops(struct bus_type *bus)
-{
- return &nds32_dma_ops;
-}
-
-#endif
diff --git a/arch/nds32/kernel/dma.c b/arch/nds32/kernel/dma.c
index 43d7fd432bb6..2b3167a1f259 100644
--- a/arch/nds32/kernel/dma.c
+++ b/arch/nds32/kernel/dma.c
@@ -3,17 +3,14 @@
#include <linux/types.h>
#include <linux/mm.h>
-#include <linux/export.h>
#include <linux/string.h>
-#include <linux/scatterlist.h>
-#include <linux/dma-mapping.h>
+#include <linux/dma-noncoherent.h>
#include <linux/io.h>
#include <linux/cache.h>
#include <linux/highmem.h>
#include <linux/slab.h>
#include <asm/cacheflush.h>
#include <asm/tlbflush.h>
-#include <asm/dma-mapping.h>
#include <asm/proc-fns.h>
/*
@@ -119,10 +116,8 @@ static struct arch_vm_region *vm_region_find(struct arch_vm_region *head,
return c;
}
-/* FIXME: attrs is not used. */
-static void *nds32_dma_alloc_coherent(struct device *dev, size_t size,
- dma_addr_t * handle, gfp_t gfp,
- unsigned long attrs)
+void *arch_dma_alloc(struct device *dev, size_t size, dma_addr_t *handle,
+ gfp_t gfp, unsigned long attrs)
{
struct page *page;
struct arch_vm_region *c;
@@ -227,8 +222,8 @@ static void *nds32_dma_alloc_coherent(struct device *dev, size_t size,
return NULL;
}
-static void nds32_dma_free(struct device *dev, size_t size, void *cpu_addr,
- dma_addr_t handle, unsigned long attrs)
+void arch_dma_free(struct device *dev, size_t size, void *cpu_addr,
+ dma_addr_t handle, unsigned long attrs)
{
struct arch_vm_region *c;
unsigned long flags, addr;
@@ -329,11 +324,10 @@ static int __init consistent_init(void)
core_initcall(consistent_init);
-static void
-nds32_dma_sync_single_for_device(struct device *dev, dma_addr_t handle,
- size_t size, enum dma_data_direction dir)
+void arch_sync_dma_for_device(struct device *dev, phys_addr_t paddr,
+ size_t size, enum dma_data_direction dir)
{
- unsigned long start = (unsigned long)phys_to_virt(handle);
+ unsigned long start = (unsigned long)phys_to_virt(paddr);
switch (dir) {
case DMA_FROM_DEVICE:
@@ -347,11 +341,10 @@ nds32_dma_sync_single_for_device(struct device *dev, dma_addr_t handle,
}
}
-static void
-nds32_dma_sync_single_for_cpu(struct device *dev, dma_addr_t handle,
- size_t size, enum dma_data_direction dir)
+void arch_sync_dma_for_cpu(struct device *dev, phys_addr_t paddr,
+ size_t size, enum dma_data_direction dir)
{
- unsigned long start = (unsigned long)phys_to_virt(handle);
+ unsigned long start = (unsigned long)phys_to_virt(paddr);
switch (dir) {
case DMA_TO_DEVICE:
@@ -364,87 +357,3 @@ nds32_dma_sync_single_for_cpu(struct device *dev, dma_addr_t handle,
BUG();
}
}
-
-static dma_addr_t nds32_dma_map_page(struct device *dev, struct page *page,
- unsigned long offset, size_t size,
- enum dma_data_direction dir,
- unsigned long attrs)
-{
- dma_addr_t dma_addr = page_to_phys(page) + offset;
-
- if (!(attrs & DMA_ATTR_SKIP_CPU_SYNC))
- nds32_dma_sync_single_for_device(dev, handle, size, dir);
- return dma_addr;
-}
-
-static void nds32_dma_unmap_page(struct device *dev, dma_addr_t handle,
- size_t size, enum dma_data_direction dir,
- unsigned long attrs)
-{
- if (!(attrs & DMA_ATTR_SKIP_CPU_SYNC))
- nds32_dma_sync_single_for_cpu(dev, handle, size, dir);
-}
-
-static void
-nds32_dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg,
- int nents, enum dma_data_direction dir)
-{
- int i;
-
- for (i = 0; i < nents; i++, sg++) {
- nds32_dma_sync_single_for_device(dev, sg_dma_address(sg),
- sg->length, dir);
- }
-}
-
-static void
-nds32_dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg, int nents,
- enum dma_data_direction dir)
-{
- int i;
-
- for (i = 0; i < nents; i++, sg++) {
- nds32_dma_sync_single_for_cpu(dev, sg_dma_address(sg),
- sg->length, dir);
- }
-}
-
-static int nds32_dma_map_sg(struct device *dev, struct scatterlist *sg,
- int nents, enum dma_data_direction dir,
- unsigned long attrs)
-{
- int i;
-
- for (i = 0; i < nents; i++, sg++) {
- nds32_dma_sync_single_for_device(dev, sg_dma_address(sg),
- sg->length, dir);
- }
- return nents;
-}
-
-static void nds32_dma_unmap_sg(struct device *dev, struct scatterlist *sg,
- int nhwentries, enum dma_data_direction dir,
- unsigned long attrs)
-{
- int i;
-
- for (i = 0; i < nhwentries; i++, sg++) {
- nds32_dma_sync_single_for_cpu(dev, sg_dma_address(sg),
- sg->length, dir);
- }
-}
-
-struct dma_map_ops nds32_dma_ops = {
- .alloc = nds32_dma_alloc_coherent,
- .free = nds32_dma_free,
- .map_page = nds32_dma_map_page,
- .unmap_page = nds32_dma_unmap_page,
- .map_sg = nds32_dma_map_sg,
- .unmap_sg = nds32_dma_unmap_sg,
- .sync_single_for_device = nds32_dma_sync_single_for_device,
- .sync_single_for_cpu = nds32_dma_sync_single_for_cpu,
- .sync_sg_for_cpu = nds32_dma_sync_sg_for_cpu,
- .sync_sg_for_device = nds32_dma_sync_sg_for_device,
-};
-
-EXPORT_SYMBOL(nds32_dma_ops);
--
2.17.0
^ permalink raw reply related
* [PATCH 09/25] nds32: implement the unmap_sg DMA operation
From: Christoph Hellwig @ 2018-05-22 12:04 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180522120430.28709-1-hch@lst.de>
This matches the implementation of the more commonly used unmap_single
routines and the sync_sg_for_cpu method which should provide equivalent
cache maintainance.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
arch/nds32/kernel/dma.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/arch/nds32/kernel/dma.c b/arch/nds32/kernel/dma.c
index 4e6fb4ffd3f7..43d7fd432bb6 100644
--- a/arch/nds32/kernel/dma.c
+++ b/arch/nds32/kernel/dma.c
@@ -426,6 +426,12 @@ static void nds32_dma_unmap_sg(struct device *dev, struct scatterlist *sg,
int nhwentries, enum dma_data_direction dir,
unsigned long attrs)
{
+ int i;
+
+ for (i = 0; i < nhwentries; i++, sg++) {
+ nds32_dma_sync_single_for_cpu(dev, sg_dma_address(sg),
+ sg->length, dir);
+ }
}
struct dma_map_ops nds32_dma_ops = {
--
2.17.0
^ permalink raw reply related
* [PATCH 08/25] nds32: consolidate DMA cache maintainance routines
From: Christoph Hellwig @ 2018-05-22 12:04 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180522120430.28709-1-hch@lst.de>
Make sure all other DMA methods call nds32_dma_sync_single_for_{device,cpu}
to perform cache maintaince, and remove the consisteny_sync helper that
implemented both with entirely separate code based off an argument.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
arch/nds32/kernel/dma.c | 140 +++++++++++++++++-----------------------
1 file changed, 61 insertions(+), 79 deletions(-)
diff --git a/arch/nds32/kernel/dma.c b/arch/nds32/kernel/dma.c
index e1bf7206e015..4e6fb4ffd3f7 100644
--- a/arch/nds32/kernel/dma.c
+++ b/arch/nds32/kernel/dma.c
@@ -22,11 +22,6 @@
static pte_t *consistent_pte;
static DEFINE_RAW_SPINLOCK(consistent_lock);
-enum master_type {
- FOR_CPU = 0,
- FOR_DEVICE = 1,
-};
-
/*
* VM region handling support.
*
@@ -333,15 +328,53 @@ static int __init consistent_init(void)
}
core_initcall(consistent_init);
-static void consistent_sync(void *vaddr, size_t size, int direction, int master_type);
+
+static void
+nds32_dma_sync_single_for_device(struct device *dev, dma_addr_t handle,
+ size_t size, enum dma_data_direction dir)
+{
+ unsigned long start = (unsigned long)phys_to_virt(handle);
+
+ switch (dir) {
+ case DMA_FROM_DEVICE:
+ break;
+ case DMA_TO_DEVICE:
+ case DMA_BIDIRECTIONAL:
+ cpu_dma_wb_range(start, start + size);
+ break;
+ default:
+ BUG();
+ }
+}
+
+static void
+nds32_dma_sync_single_for_cpu(struct device *dev, dma_addr_t handle,
+ size_t size, enum dma_data_direction dir)
+{
+ unsigned long start = (unsigned long)phys_to_virt(handle);
+
+ switch (dir) {
+ case DMA_TO_DEVICE:
+ break;
+ case DMA_FROM_DEVICE:
+ case DMA_BIDIRECTIONAL:
+ cpu_dma_inval_range(start, start + size);
+ break;
+ default:
+ BUG();
+ }
+}
+
static dma_addr_t nds32_dma_map_page(struct device *dev, struct page *page,
unsigned long offset, size_t size,
enum dma_data_direction dir,
unsigned long attrs)
{
+ dma_addr_t dma_addr = page_to_phys(page) + offset;
+
if (!(attrs & DMA_ATTR_SKIP_CPU_SYNC))
- consistent_sync((void *)(page_address(page) + offset), size, dir, FOR_DEVICE);
- return page_to_phys(page) + offset;
+ nds32_dma_sync_single_for_device(dev, handle, size, dir);
+ return dma_addr;
}
static void nds32_dma_unmap_page(struct device *dev, dma_addr_t handle,
@@ -349,75 +382,19 @@ static void nds32_dma_unmap_page(struct device *dev, dma_addr_t handle,
unsigned long attrs)
{
if (!(attrs & DMA_ATTR_SKIP_CPU_SYNC))
- consistent_sync(phys_to_virt(handle), size, dir, FOR_CPU);
+ nds32_dma_sync_single_for_cpu(dev, handle, size, dir);
}
-/*
- * Make an area consistent for devices.
- */
-static void consistent_sync(void *vaddr, size_t size, int direction, int master_type)
-{
- unsigned long start = (unsigned long)vaddr;
- unsigned long end = start + size;
-
- if (master_type == FOR_CPU) {
- switch (direction) {
- case DMA_TO_DEVICE:
- break;
- case DMA_FROM_DEVICE:
- case DMA_BIDIRECTIONAL:
- cpu_dma_inval_range(start, end);
- break;
- default:
- BUG();
- }
- } else {
- /* FOR_DEVICE */
- switch (direction) {
- case DMA_FROM_DEVICE:
- break;
- case DMA_TO_DEVICE:
- case DMA_BIDIRECTIONAL:
- cpu_dma_wb_range(start, end);
- break;
- default:
- BUG();
- }
- }
-}
-
-static int nds32_dma_map_sg(struct device *dev, struct scatterlist *sg,
- int nents, enum dma_data_direction dir,
- unsigned long attrs)
+static void
+nds32_dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg,
+ int nents, enum dma_data_direction dir)
{
int i;
for (i = 0; i < nents; i++, sg++) {
- char *virt =
- page_address((struct page *)sg->page_link) + sg->offset;
- consistent_sync(virt, sg->length, dir, FOR_CPU);
+ nds32_dma_sync_single_for_device(dev, sg_dma_address(sg),
+ sg->length, dir);
}
- return nents;
-}
-
-static void nds32_dma_unmap_sg(struct device *dev, struct scatterlist *sg,
- int nhwentries, enum dma_data_direction dir,
- unsigned long attrs)
-{
-}
-
-static void
-nds32_dma_sync_single_for_cpu(struct device *dev, dma_addr_t handle,
- size_t size, enum dma_data_direction dir)
-{
- consistent_sync((void *)phys_to_virt(handle), size, dir, FOR_CPU);
-}
-
-static void
-nds32_dma_sync_single_for_device(struct device *dev, dma_addr_t handle,
- size_t size, enum dma_data_direction dir)
-{
- consistent_sync((void *)phys_to_virt(handle), size, dir, FOR_DEVICE);
}
static void
@@ -427,23 +404,28 @@ nds32_dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg, int nents,
int i;
for (i = 0; i < nents; i++, sg++) {
- char *virt =
- page_address((struct page *)sg->page_link) + sg->offset;
- consistent_sync(virt, sg->length, dir, FOR_CPU);
+ nds32_dma_sync_single_for_cpu(dev, sg_dma_address(sg),
+ sg->length, dir);
}
}
-static void
-nds32_dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg,
- int nents, enum dma_data_direction dir)
+static int nds32_dma_map_sg(struct device *dev, struct scatterlist *sg,
+ int nents, enum dma_data_direction dir,
+ unsigned long attrs)
{
int i;
for (i = 0; i < nents; i++, sg++) {
- char *virt =
- page_address((struct page *)sg->page_link) + sg->offset;
- consistent_sync(virt, sg->length, dir, FOR_DEVICE);
+ nds32_dma_sync_single_for_device(dev, sg_dma_address(sg),
+ sg->length, dir);
}
+ return nents;
+}
+
+static void nds32_dma_unmap_sg(struct device *dev, struct scatterlist *sg,
+ int nhwentries, enum dma_data_direction dir,
+ unsigned long attrs)
+{
}
struct dma_map_ops nds32_dma_ops = {
--
2.17.0
^ permalink raw reply related
* [PATCH 07/25] nds32: remove the broken kmap code in nds32_dma_map_sg
From: Christoph Hellwig @ 2018-05-22 12:04 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180522120430.28709-1-hch@lst.de>
nds32_dma_map_sg is the only of the various DMA operations that tries
to deal with highmem (the single page variants and SG sync routines are
missing, SG unmap is entirely unimplemented), and it does so without
taking into account S/G list items that are bigger than a page, which
are legal and can happen frequently.
Remove this code for now - if highmem support on nds32 becomes a real
thing it needs to be added back as a loop over pages in the newly
consolidated code that deals with all operations.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
arch/nds32/kernel/dma.c | 21 +++------------------
1 file changed, 3 insertions(+), 18 deletions(-)
diff --git a/arch/nds32/kernel/dma.c b/arch/nds32/kernel/dma.c
index d291800fc621..e1bf7206e015 100644
--- a/arch/nds32/kernel/dma.c
+++ b/arch/nds32/kernel/dma.c
@@ -393,24 +393,9 @@ static int nds32_dma_map_sg(struct device *dev, struct scatterlist *sg,
int i;
for (i = 0; i < nents; i++, sg++) {
- void *virt;
- unsigned long pfn;
- struct page *page = sg_page(sg);
-
- sg->dma_address = sg_phys(sg);
- pfn = page_to_pfn(page) + sg->offset / PAGE_SIZE;
- page = pfn_to_page(pfn);
- if (PageHighMem(page)) {
- virt = kmap_atomic(page);
- consistent_sync(virt, sg->length, dir, FOR_CPU);
- kunmap_atomic(virt);
- } else {
- if (sg->offset > PAGE_SIZE)
- panic("sg->offset:%08x > PAGE_SIZE\n",
- sg->offset);
- virt = page_address(page) + sg->offset;
- consistent_sync(virt, sg->length, dir, FOR_CPU);
- }
+ char *virt =
+ page_address((struct page *)sg->page_link) + sg->offset;
+ consistent_sync(virt, sg->length, dir, FOR_CPU);
}
return nents;
}
--
2.17.0
^ permalink raw reply related
* [PATCH 06/25] microblaze: remove the consistent_sync and consistent_sync_page
From: Christoph Hellwig @ 2018-05-22 12:04 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180522120430.28709-1-hch@lst.de>
Both unused.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
arch/microblaze/include/asm/pgtable.h | 3 --
arch/microblaze/mm/consistent.c | 45 ---------------------------
2 files changed, 48 deletions(-)
diff --git a/arch/microblaze/include/asm/pgtable.h b/arch/microblaze/include/asm/pgtable.h
index 8a2e654b709f..7b650ab14fa0 100644
--- a/arch/microblaze/include/asm/pgtable.h
+++ b/arch/microblaze/include/asm/pgtable.h
@@ -553,9 +553,6 @@ void __init *early_get_page(void);
extern unsigned long ioremap_bot, ioremap_base;
-void consistent_sync(void *vaddr, size_t size, int direction);
-void consistent_sync_page(struct page *page, unsigned long offset,
- size_t size, int direction);
unsigned long consistent_virt_to_pfn(void *vaddr);
void setup_memory(void);
diff --git a/arch/microblaze/mm/consistent.c b/arch/microblaze/mm/consistent.c
index b9a9c8c3397b..c9a278ac795a 100644
--- a/arch/microblaze/mm/consistent.c
+++ b/arch/microblaze/mm/consistent.c
@@ -220,48 +220,3 @@ void arch_dma_free(struct device *dev, size_t size, void *vaddr,
flush_tlb_all();
#endif
}
-
-/*
- * make an area consistent.
- */
-void consistent_sync(void *vaddr, size_t size, int direction)
-{
- unsigned long start;
- unsigned long end;
-
- start = (unsigned long)vaddr;
-
- /* Convert start address back down to unshadowed memory region */
-#ifdef CONFIG_XILINX_UNCACHED_SHADOW
- start &= ~UNCACHED_SHADOW_MASK;
-#endif
- end = start + size;
-
- switch (direction) {
- case PCI_DMA_NONE:
- BUG();
- case PCI_DMA_FROMDEVICE: /* invalidate only */
- invalidate_dcache_range(start, end);
- break;
- case PCI_DMA_TODEVICE: /* writeback only */
- flush_dcache_range(start, end);
- break;
- case PCI_DMA_BIDIRECTIONAL: /* writeback and invalidate */
- flush_dcache_range(start, end);
- break;
- }
-}
-EXPORT_SYMBOL(consistent_sync);
-
-/*
- * consistent_sync_page makes memory consistent. identical
- * to consistent_sync, but takes a struct page instead of a
- * virtual address
- */
-void consistent_sync_page(struct page *page, unsigned long offset,
- size_t size, int direction)
-{
- unsigned long start = (unsigned long)page_address(page) + offset;
- consistent_sync((void *)start, size, direction);
-}
-EXPORT_SYMBOL(consistent_sync_page);
--
2.17.0
^ permalink raw reply related
* [PATCH 05/25] microblaze: use generic dma_noncoherent_ops
From: Christoph Hellwig @ 2018-05-22 12:04 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180522120430.28709-1-hch@lst.de>
Switch to the generic noncoherent direct mapping implementation.
This removes the direction-based optimizations in
sync_{single,sg}_for_{cpu,device} which were marked untestested and
do not match the usually very well tested {un,}map_{single,sg}
implementations.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
arch/microblaze/Kconfig | 4 +
arch/microblaze/include/asm/Kbuild | 1 +
arch/microblaze/include/asm/dma-mapping.h | 28 -----
arch/microblaze/include/asm/pgtable.h | 2 -
arch/microblaze/kernel/dma.c | 144 ++--------------------
arch/microblaze/mm/consistent.c | 9 +-
6 files changed, 22 insertions(+), 166 deletions(-)
delete mode 100644 arch/microblaze/include/asm/dma-mapping.h
diff --git a/arch/microblaze/Kconfig b/arch/microblaze/Kconfig
index d14782100088..848e31a86ba5 100644
--- a/arch/microblaze/Kconfig
+++ b/arch/microblaze/Kconfig
@@ -1,6 +1,8 @@
config MICROBLAZE
def_bool y
select ARCH_HAS_GCOV_PROFILE_ALL
+ select ARCH_HAS_SYNC_DMA_FOR_CPU
+ select ARCH_HAS_SYNC_DMA_FOR_DEVICE
select ARCH_MIGHT_HAVE_PC_PARPORT
select ARCH_NO_COHERENT_DMA_MMAP if !MMU
select ARCH_WANT_IPC_PARSE_VERSION
@@ -8,6 +10,8 @@ config MICROBLAZE
select TIMER_OF
select CLONE_BACKWARDS3
select COMMON_CLK
+ select DMA_NONCOHERENT_OPS
+ select DMA_NONCOHERENT_MMAP
select GENERIC_ATOMIC64
select GENERIC_CLOCKEVENTS
select GENERIC_CPU_DEVICES
diff --git a/arch/microblaze/include/asm/Kbuild b/arch/microblaze/include/asm/Kbuild
index 3c80a5a308ed..8d3e71f43a3e 100644
--- a/arch/microblaze/include/asm/Kbuild
+++ b/arch/microblaze/include/asm/Kbuild
@@ -4,6 +4,7 @@ generic-y += bug.h
generic-y += bugs.h
generic-y += device.h
generic-y += div64.h
+generic-y += dma-mapping.h
generic-y += emergency-restart.h
generic-y += exec.h
generic-y += extable.h
diff --git a/arch/microblaze/include/asm/dma-mapping.h b/arch/microblaze/include/asm/dma-mapping.h
deleted file mode 100644
index add50c1373bf..000000000000
--- a/arch/microblaze/include/asm/dma-mapping.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Implements the generic device dma API for microblaze and the pci
- *
- * Copyright (C) 2009-2010 Michal Simek <monstr@monstr.eu>
- * Copyright (C) 2009-2010 PetaLogix
- *
- * This file is subject to the terms and conditions of the GNU General
- * Public License. See the file COPYING in the main directory of this
- * archive for more details.
- *
- * This file is base on powerpc and x86 dma-mapping.h versions
- * Copyright (C) 2004 IBM
- */
-
-#ifndef _ASM_MICROBLAZE_DMA_MAPPING_H
-#define _ASM_MICROBLAZE_DMA_MAPPING_H
-
-/*
- * Available generic sets of operations
- */
-extern const struct dma_map_ops dma_nommu_ops;
-
-static inline const struct dma_map_ops *get_arch_dma_ops(struct bus_type *bus)
-{
- return &dma_nommu_ops;
-}
-
-#endif /* _ASM_MICROBLAZE_DMA_MAPPING_H */
diff --git a/arch/microblaze/include/asm/pgtable.h b/arch/microblaze/include/asm/pgtable.h
index db8b1fa83452..8a2e654b709f 100644
--- a/arch/microblaze/include/asm/pgtable.h
+++ b/arch/microblaze/include/asm/pgtable.h
@@ -553,8 +553,6 @@ void __init *early_get_page(void);
extern unsigned long ioremap_bot, ioremap_base;
-void *consistent_alloc(gfp_t gfp, size_t size, dma_addr_t *dma_handle);
-void consistent_free(size_t size, void *vaddr);
void consistent_sync(void *vaddr, size_t size, int direction);
void consistent_sync_page(struct page *page, unsigned long offset,
size_t size, int direction);
diff --git a/arch/microblaze/kernel/dma.c b/arch/microblaze/kernel/dma.c
index 3145e7dc8ab1..71032cf64669 100644
--- a/arch/microblaze/kernel/dma.c
+++ b/arch/microblaze/kernel/dma.c
@@ -8,29 +8,15 @@
*/
#include <linux/device.h>
-#include <linux/dma-mapping.h>
+#include <linux/dma-noncoherent.h>
#include <linux/gfp.h>
#include <linux/dma-debug.h>
#include <linux/export.h>
#include <linux/bug.h>
#include <asm/cacheflush.h>
-static void *dma_nommu_alloc_coherent(struct device *dev, size_t size,
- dma_addr_t *dma_handle, gfp_t flag,
- unsigned long attrs)
-{
- return consistent_alloc(flag, size, dma_handle);
-}
-
-static void dma_nommu_free_coherent(struct device *dev, size_t size,
- void *vaddr, dma_addr_t dma_handle,
- unsigned long attrs)
-{
- consistent_free(size, vaddr);
-}
-
-static inline void __dma_sync(unsigned long paddr,
- size_t size, enum dma_data_direction direction)
+static void __dma_sync(struct device *dev, phys_addr_t paddr, size_t size,
+ enum dma_data_direction direction)
{
switch (direction) {
case DMA_TO_DEVICE:
@@ -45,113 +31,21 @@ static inline void __dma_sync(unsigned long paddr,
}
}
-static int dma_nommu_map_sg(struct device *dev, struct scatterlist *sgl,
- int nents, enum dma_data_direction direction,
- unsigned long attrs)
+void arch_sync_dma_for_device(struct device *dev, phys_addr_t paddr,
+ size_t size, enum dma_data_direction dir)
{
- struct scatterlist *sg;
- int i;
-
- /* FIXME this part of code is untested */
- for_each_sg(sgl, sg, nents, i) {
- sg->dma_address = sg_phys(sg);
-
- if (attrs & DMA_ATTR_SKIP_CPU_SYNC)
- continue;
-
- __dma_sync(sg_phys(sg), sg->length, direction);
- }
-
- return nents;
-}
-
-static inline dma_addr_t dma_nommu_map_page(struct device *dev,
- struct page *page,
- unsigned long offset,
- size_t size,
- enum dma_data_direction direction,
- unsigned long attrs)
-{
- if (!(attrs & DMA_ATTR_SKIP_CPU_SYNC))
- __dma_sync(page_to_phys(page) + offset, size, direction);
- return page_to_phys(page) + offset;
+ __dma_sync(dev, paddr, size, dir);
}
-static inline void dma_nommu_unmap_page(struct device *dev,
- dma_addr_t dma_address,
- size_t size,
- enum dma_data_direction direction,
- unsigned long attrs)
+void arch_sync_dma_for_cpu(struct device *dev, phys_addr_t paddr,
+ size_t size, enum dma_data_direction dir)
{
-/* There is not necessary to do cache cleanup
- *
- * phys_to_virt is here because in __dma_sync_page is __virt_to_phys and
- * dma_address is physical address
- */
- if (!(attrs & DMA_ATTR_SKIP_CPU_SYNC))
- __dma_sync(dma_address, size, direction);
+ __dma_sync(dev, paddr, size, dir);
}
-static inline void
-dma_nommu_sync_single_for_cpu(struct device *dev,
- dma_addr_t dma_handle, size_t size,
- enum dma_data_direction direction)
-{
- /*
- * It's pointless to flush the cache as the memory segment
- * is given to the CPU
- */
-
- if (direction == DMA_FROM_DEVICE)
- __dma_sync(dma_handle, size, direction);
-}
-
-static inline void
-dma_nommu_sync_single_for_device(struct device *dev,
- dma_addr_t dma_handle, size_t size,
- enum dma_data_direction direction)
-{
- /*
- * It's pointless to invalidate the cache if the device isn't
- * supposed to write to the relevant region
- */
-
- if (direction == DMA_TO_DEVICE)
- __dma_sync(dma_handle, size, direction);
-}
-
-static inline void
-dma_nommu_sync_sg_for_cpu(struct device *dev,
- struct scatterlist *sgl, int nents,
- enum dma_data_direction direction)
-{
- struct scatterlist *sg;
- int i;
-
- /* FIXME this part of code is untested */
- if (direction == DMA_FROM_DEVICE)
- for_each_sg(sgl, sg, nents, i)
- __dma_sync(sg->dma_address, sg->length, direction);
-}
-
-static inline void
-dma_nommu_sync_sg_for_device(struct device *dev,
- struct scatterlist *sgl, int nents,
- enum dma_data_direction direction)
-{
- struct scatterlist *sg;
- int i;
-
- /* FIXME this part of code is untested */
- if (direction == DMA_TO_DEVICE)
- for_each_sg(sgl, sg, nents, i)
- __dma_sync(sg->dma_address, sg->length, direction);
-}
-
-static
-int dma_nommu_mmap_coherent(struct device *dev, struct vm_area_struct *vma,
- void *cpu_addr, dma_addr_t handle, size_t size,
- unsigned long attrs)
+int arch_dma_mmap(struct device *dev, struct vm_area_struct *vma,
+ void *cpu_addr, dma_addr_t handle, size_t size,
+ unsigned long attrs)
{
#ifdef CONFIG_MMU
unsigned long user_count = vma_pages(vma);
@@ -170,17 +64,3 @@ int dma_nommu_mmap_coherent(struct device *dev, struct vm_area_struct *vma,
return -ENXIO;
#endif
}
-
-const struct dma_map_ops dma_nommu_ops = {
- .alloc = dma_nommu_alloc_coherent,
- .free = dma_nommu_free_coherent,
- .mmap = dma_nommu_mmap_coherent,
- .map_sg = dma_nommu_map_sg,
- .map_page = dma_nommu_map_page,
- .unmap_page = dma_nommu_unmap_page,
- .sync_single_for_cpu = dma_nommu_sync_single_for_cpu,
- .sync_single_for_device = dma_nommu_sync_single_for_device,
- .sync_sg_for_cpu = dma_nommu_sync_sg_for_cpu,
- .sync_sg_for_device = dma_nommu_sync_sg_for_device,
-};
-EXPORT_SYMBOL(dma_nommu_ops);
diff --git a/arch/microblaze/mm/consistent.c b/arch/microblaze/mm/consistent.c
index b06c3a7faf20..b9a9c8c3397b 100644
--- a/arch/microblaze/mm/consistent.c
+++ b/arch/microblaze/mm/consistent.c
@@ -33,6 +33,7 @@
#include <linux/pci.h>
#include <linux/interrupt.h>
#include <linux/gfp.h>
+#include <linux/dma-noncoherent.h>
#include <asm/pgalloc.h>
#include <linux/io.h>
@@ -59,7 +60,8 @@
* uncached region. This will no doubt cause big problems if memory allocated
* here is not also freed properly. -- JW
*/
-void *consistent_alloc(gfp_t gfp, size_t size, dma_addr_t *dma_handle)
+void *arch_dma_alloc(struct device *dev, size_t size, dma_addr_t *dma_handle,
+ gfp_t gfp, unsigned long attrs)
{
unsigned long order, vaddr;
void *ret;
@@ -154,7 +156,6 @@ void *consistent_alloc(gfp_t gfp, size_t size, dma_addr_t *dma_handle)
return ret;
}
-EXPORT_SYMBOL(consistent_alloc);
#ifdef CONFIG_MMU
static pte_t *consistent_virt_to_pte(void *vaddr)
@@ -178,7 +179,8 @@ unsigned long consistent_virt_to_pfn(void *vaddr)
/*
* free page(s) as defined by the above mapping.
*/
-void consistent_free(size_t size, void *vaddr)
+void arch_dma_free(struct device *dev, size_t size, void *vaddr,
+ dma_addr_t dma_addr, unsigned long attrs)
{
struct page *page;
@@ -218,7 +220,6 @@ void consistent_free(size_t size, void *vaddr)
flush_tlb_all();
#endif
}
-EXPORT_SYMBOL(consistent_free);
/*
* make an area consistent.
--
2.17.0
^ permalink raw reply related
* [PULL v8] KVM: arm64: Optimise FPSIMD context switching
From: Dave Martin @ 2018-05-22 12:04 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180520141441.3d999f16@why.wild-wind.fr.eu.org>
On Sun, May 20, 2018 at 02:14:41PM +0100, Marc Zyngier wrote:
> On Wed, 16 May 2018 11:49:42 +0100
> Dave Martin <Dave.Martin@arm.com> wrote:
>
> Hi Dave,
>
> > Hi Marc,
> >
> > This is a trivial update to the previously posted v7 [1]. The only
> > changes are a couple of minor cosmetic changes requested by reviewers,
> > on-list and the addition of Acked-by/Reviewed-by tags received since the
> > series was posted.
> >
> > Let me know if you need anything else on this.
>
> So I've taken this, merged in Linus' top of tree, started a guest on a
> dual A53 board, and immediately hit the following:
>
> root at sy-borg:~# [ 287.226184] Unable to handle kernel NULL pointer dereference at virtual address 00000000
> [ 287.231672] Mem abort info:
> [ 287.234537] ESR = 0x96000044
> [ 287.237674] Exception class = DABT (current EL), IL = 32 bits
> [ 287.243765] SET = 0, FnV = 0
> [ 287.246900] EA = 0, S1PTW = 0
> [ 287.250126] Data abort info:
> [ 287.253083] ISV = 0, ISS = 0x00000044
> [ 287.257025] CM = 0, WnR = 1
> [ 287.260076] user pgtable: 4k pages, 48-bit VAs, pgdp = 00000000b8483f75
> [ 287.266882] [0000000000000000] pgd=0000000000000000
> [ 287.271903] Internal error: Oops: 96000044 [#1] PREEMPT SMP
> [ 287.277636] Modules linked in:
> [ 287.280776] CPU: 1 PID: 3098 Comm: kworker/u4:3 Not tainted 4.17.0-rc5-00166-gd84e81cca249 #136
> [ 287.289730] Hardware name: Globalscale Marvell ESPRESSOBin Board (DT)
> [ 287.296364] pstate: 40000085 (nZcv daIf -PAN -UAO)
> [ 287.301301] pc : fpsimd_save_state+0x0/0x54
> [ 287.305595] lr : fpsimd_save+0x50/0x100
> [ 287.309531] sp : ffff00000dde3af0
> [ 287.312936] x29: ffff00000dde3af0 x28: ffff000008cd565c
> [ 287.318401] x27: ffff800078ee9c80 x26: ffff80007b207628
> [ 287.323867] x25: ffff0000093f9000 x24: 0000000000000001
> [ 287.329333] x23: ffff0000093d4000 x22: ffff80007b207000
> [ 287.334798] x21: ffff80007efd7d80 x20: ffff80007b207000
> [ 287.340264] x19: 0000000000000000 x18: 0000000000040f0b
> [ 287.345729] x17: 0000ffffb70752b8 x16: 0000ffffb708e008
> [ 287.351195] x15: 0000000000000000 x14: 0000000000000400
> [ 287.356661] x13: 0000000000000001 x12: 0000000000000001
> [ 287.362127] x11: 0000000000000001 x10: 0000000000000000
> [ 287.367592] x9 : 0000000000000253 x8 : ffff80007b207200
> [ 287.373057] x7 : ffff80007b207100 x6 : ffff80007c378f18
> [ 287.378523] x5 : 00000042c2094c00 x4 : 0000000000000000
> [ 287.383990] x3 : 00000042e0033450 x2 : 0000000000000000
> [ 287.389454] x1 : 0000800075bf6000 x0 : 0000000000000000
> [ 287.394922] Process kworker/u4:3 (pid: 3098, stack limit = 0x00000000ca0dd8c6)
> [ 287.402358] Call trace:
> [ 287.404873] fpsimd_save_state+0x0/0x54
> [ 287.408813] fpsimd_thread_switch+0x28/0xa0
> [ 287.413114] __switch_to+0x1c/0xd0
> [ 287.416609] __schedule+0x1b8/0x730
> [ 287.420191] preempt_schedule_common+0x24/0x48
> [ 287.424760] preempt_schedule.part.23+0x1c/0x28
> [ 287.429419] preempt_schedule+0x1c/0x28
> [ 287.433363] _raw_spin_unlock+0x34/0x48
> [ 287.437308] flush_old_exec+0x45c/0x6a0
> [ 287.441250] load_elf_binary+0x324/0x1198
> [ 287.445372] search_binary_handler+0xac/0x230
> [ 287.449851] do_execveat_common.isra.14+0x508/0x6e0
> [ 287.454867] do_execve+0x28/0x30
> [ 287.458185] call_usermodehelper_exec_async+0xdc/0x140
> [ 287.463468] ret_from_fork+0x10/0x18
> [ 287.467143] Code: a9425bf5 a8c37bfd d65f03c0 d65f03c0 (ad000400)
> [ 287.473414] ---[ end trace c4346b99cc877f8e ]---
>
> It happened just after having loaded the guest kernel, so I presume
> we're missing some kind of initialization. I couldn't subsequently
> reproduce it on the same machine, and the same kernel is doing
> absolutely fine on a Seattle box.
>
> I can't immediately see how st would be NULL, unless we somehow are
> missing some state tracking somewhere...
>
> Any idea?
I have a reproducer now for something that resembles the above bug.
(Build test.c separately and run it from the target.)
In order for this particular bug to happen we need some kernel thread
or softirq in a kernel thread to use kernel-mode NEON (thus setting
fpsimd_last_state.st to NULL but leaving TIF_FOREIGN_FPSTATE clear),
then a kernel thread with no mm is scheduled in on the same cpu, then
that thread gans an mm and get scheduled out.
I don't force-affine anything in this test, but on an idle system it
seems to fire reliably.
There may be more plausible failure scenarios, but this is the
definite one that I've found.
There are two overlapping problems here: firstly the conditional
failure to set TIF_FOREIGN_FPSTATE in kernel_neon_begin() (which
was a latent bug prior to the VHE FPSIMD series), and secondly
the assumption that !TIF_FOREIGN_FPSTATE implies that current's
FPSIMD state is loaded (so fpsimd_last_state.st != NULL):
the latter is not true for kernel threads.
I will post patches shortly. My current approach is to pull the
set_thread_flag(TIF_FOREIGN_FPSTATE) into fpsimd_flush_cpu_state()
(so that it can't be forgotten in this scenario), and to remove
the special-case handling of kernel threads in fpsimd.c: the only
requirement is to ensure TIF_FOREIGN_FPSTATE is set for the init task,
and remove the ->mm based "optimisation" that allows a wrong
TIF_FOREIGN_FPSTATE to be left behind on sched-in.
kernel threads never get any FPSIMD state loaded, but virtue of
never entering userspace. They will now never save state either,
by virtue of TIF_FOREIGN_FPSTATE always being true for these
threads.
Cheers
---Dave
diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c
index b0d29b7..c85f4eb 100644
--- a/arch/arm64/kernel/fpsimd.c
+++ b/arch/arm64/kernel/fpsimd.c
@@ -1314,3 +1314,10 @@ static int __init fpsimd_init(void)
return sve_sysctl_init();
}
core_initcall(fpsimd_init);
+
+void __fpsimd_print_state(char const *file, int line)
+{
+ pr_info("%s[%d]: %s:%d: current->mm = %p, fpsimd_last_state.st = %p, TIF_FOREIGN_FPSTATE = %d\n",
+ current->comm, task_pid_nr(current), file, line,
+ current->mm, this_cpu_read(fpsimd_last_state.st), test_thread_flag(TIF_FOREIGN_FPSTATE) ? 1 : 0);
+}
diff --git a/arch/arm64/kernel/sys.c b/arch/arm64/kernel/sys.c
index 72981ba..745f5f0 100644
--- a/arch/arm64/kernel/sys.c
+++ b/arch/arm64/kernel/sys.c
@@ -59,7 +59,9 @@ asmlinkage long sys_rt_sigreturn_wrapper(void);
* The sys_call_table array must be 4K aligned to be accessible from
* kernel/entry.S.
*/
+extern long arm64_ni_syscall(long nr);
+
void * const sys_call_table[__NR_syscalls] __aligned(4096) = {
- [0 ... __NR_syscalls - 1] = sys_ni_syscall,
+ [0 ... __NR_syscalls - 1] = arm64_ni_syscall,
#include <asm/unistd.h>
};
diff --git a/arch/arm64/kernel/traps.c b/arch/arm64/kernel/traps.c
index 8bbdc17..a9a8589 100644
--- a/arch/arm64/kernel/traps.c
+++ b/arch/arm64/kernel/traps.c
@@ -18,6 +18,7 @@
*/
#include <linux/bug.h>
+#include <linux/completion.h>
#include <linux/signal.h>
#include <linux/personality.h>
#include <linux/kallsyms.h>
@@ -27,10 +28,13 @@
#include <linux/kdebug.h>
#include <linux/module.h>
#include <linux/kexec.h>
+#include <linux/kthread.h>
#include <linux/delay.h>
#include <linux/init.h>
+#include <linux/mmu_context.h>
#include <linux/sched/signal.h>
#include <linux/sched/debug.h>
+#include <linux/sched/mm.h>
#include <linux/sched/task_stack.h>
#include <linux/sizes.h>
#include <linux/syscalls.h>
@@ -43,6 +47,7 @@
#include <asm/debug-monitors.h>
#include <asm/esr.h>
#include <asm/insn.h>
+#include <asm/neon.h>
#include <asm/traps.h>
#include <asm/smp.h>
#include <asm/stack_pointer.h>
@@ -549,10 +554,92 @@ asmlinkage void __exception do_sysinstr(unsigned int esr, struct pt_regs *regs)
long compat_arm_syscall(struct pt_regs *regs);
+struct grabber_data {
+ int err;
+ struct completion c, c2;
+ struct mm_struct *mm;
+};
+
+extern void __fpsimd_print_state(char const *, int);
+#define fpsimd_print_state() __fpsimd_print_state(__FILE__, __LINE__)
+
+static int grabber(void *data)
+{
+ struct grabber_data *g = data;
+
+ if (!mmget_not_zero(g->mm)) {
+ g->err = -ESRCH;
+ goto out;
+ }
+
+ fpsimd_print_state();
+
+ g->err = 0;
+
+ kernel_neon_begin();
+ kernel_neon_end();
+
+ fpsimd_print_state();
+
+ use_mm(g->mm);
+
+ fpsimd_print_state();
+
+ complete(&g->c);
+ wait_for_completion(&g->c2);
+
+ g->err = 0;
+out:
+ complete(&g->c);
+ return g->err;
+}
+
+static int do_trigger_bug(void)
+{
+ struct task_struct *kth;
+ struct grabber_data g;
+
+ pr_info("%s[%d]: do_trigger_bug() called\n",
+ current->comm, task_pid_nr(current));
+
+ init_completion(&g.c);
+ init_completion(&g.c2);
+ mmgrab(current->mm);
+ g.mm = current->mm;
+
+ kth = kthread_create(grabber, &g, "grabber[%d]", task_pid_nr(current));
+ if (IS_ERR(kth)) {
+ mmdrop(current->mm);
+ return PTR_ERR(kth);
+ }
+
+ wake_up_process(kth);
+ wait_for_completion(&g.c);
+ mmdrop(current->mm);
+ if (g.err) {
+ pr_info("%s: mm disappeared\n", __func__);
+ return g.err;
+ }
+
+ init_completion(&g.c);
+ complete(&g.c2);
+ wait_for_completion(&g.c);
+ return g.err;
+}
+
+long arm64_ni_syscall(long nr)
+{
+ if ((int)nr == 8888)
+ return do_trigger_bug();
+
+ return -ENOSYS;
+}
+
asmlinkage long do_ni_syscall(struct pt_regs *regs)
{
-#ifdef CONFIG_COMPAT
long ret;
+
+#ifdef CONFIG_COMPAT
if (is_compat_task()) {
ret = compat_arm_syscall(regs);
if (ret != -ENOSYS)
@@ -560,7 +647,7 @@ asmlinkage long do_ni_syscall(struct pt_regs *regs)
}
#endif
- return sys_ni_syscall();
+ return arm64_ni_syscall(regs->regs[8]);
}
static const char *esr_class_str[] = {
--- /dev/null 2017-09-27 16:25:00.179999999 +0100
+++ test.c 2018-05-22 11:59:58.671159660 +0100
@@ -0,0 +1,12 @@
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <unistd.h>
+#include <sys/syscall.h>
+
+int main(void)
+{
+ if (syscall(8888) == -1)
+ perror("8888");
+
+ return 0;
+}
yielding
[ 229.246349] Unable to handle kernel NULL pointer dereference at virtual address 00000000
[ 229.246423] Mem abort info:
[ 229.246474] ESR = 0x96000046
[ 229.246529] Exception class = DABT (current EL), IL = 32 bits
[ 229.246598] SET = 0, FnV = 0
[ 229.246652] EA = 0, S1PTW = 0
[ 229.246700] Data abort info:
[ 229.246751] ISV = 0, ISS = 0x00000046
[ 229.246809] CM = 0, WnR = 1
[ 229.246871] user pgtable: 4k pages, 48-bit VAs, pgdp = (ptrval)
[ 229.246944] [0000000000000000] pgd=00000008fa6be003, pud=00000008fa6b5003, pmd=0000000000000000
[ 229.247070] Internal error: Oops: 96000046 [#1] PREEMPT SMP
[ 229.247130] Modules linked in:
[ 229.247214] CPU: 0 PID: 1348 Comm: grabber[1347] Not tainted 4.17.0-rc3-00016-g885df5d-dirty #25
[ 229.247296] Hardware name: FVP Base (DT)
[ 229.247368] pstate: 40000085 (nZcv daIf -PAN -UAO)
[ 229.247452] pc : fpsimd_save_state+0x0/0x54
[ 229.247530] lr : fpsimd_save+0x54/0xe8
[ 229.247586] sp : ffff00000ad13c10
[ 229.247643] x29: ffff00000ad13c10 x28: 0000000000000000
[ 229.247734] x27: 0000000000000000 x26: ffff80087ac7cc20
[ 229.247830] x25: ffff000008a554f0 x24: ffff000009269b88
[ 229.247926] x23: ffff00000924f010 x22: ffff80087ac7c600
[ 229.248022] x21: ffff000009272a80 x20: ffff80087ac7c600
[ 229.248115] x19: 0000000000000000 x18: 0000000000000010
[ 229.248209] x17: 00000000d12b3c86 x16: 000000000be55560
[ 229.248302] x15: 0000000000000400 x14: 0000000000000400
[ 229.248395] x13: 0000000000000400 x12: 0000000000000001
[ 229.248488] x11: 00000000000001bd x10: 0000000000000000
[ 229.248580] x9 : 0000000002e79c03 x8 : 0000000000000000
[ 229.248671] x7 : 0000000000000000 x6 : ffff80087ac7c730
[ 229.248767] x5 : ffff80087ac7c600 x4 : 0000000000000000
[ 229.248858] x3 : 0000000000000002 x2 : 0000000000000000
[ 229.248951] x1 : 0000800876d64000 x0 : 0000000000000000
[ 229.249050] Process grabber[1347] (pid: 1348, stack limit = 0x (ptrval))
[ 229.249119] Call trace:
[ 229.249193] fpsimd_save_state+0x0/0x54
[ 229.249272] fpsimd_thread_switch+0x28/0xc0
[ 229.249353] __switch_to+0x1c/0xd0
[ 229.249426] __schedule+0x1c0/0x5d0
[ 229.249502] schedule+0x38/0xa0
[ 229.249580] schedule_timeout+0x23c/0x338
[ 229.249661] wait_for_common+0x140/0x168
[ 229.249741] wait_for_completion+0x14/0x20
[ 229.249824] grabber+0x108/0x128
[ 229.249897] kthread+0x124/0x128
[ 229.249970] ret_from_fork+0x10/0x18
[ 229.250058] Code: 94273d7b b9403fe1 f9401be0 17ffffe8 (ad000400)
[ 229.250133] ---[ end trace b5b40d96060ea368 ]---
^ permalink raw reply related
* [PATCH 04/25] m68k: use generic dma_noncoherent_ops
From: Christoph Hellwig @ 2018-05-22 12:04 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180522120430.28709-1-hch@lst.de>
Switch to the generic noncoherent direct mapping implementation.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
arch/m68k/Kconfig | 2 +
arch/m68k/include/asm/Kbuild | 1 +
arch/m68k/include/asm/dma-mapping.h | 12 -----
arch/m68k/kernel/dma.c | 68 ++++-------------------------
4 files changed, 11 insertions(+), 72 deletions(-)
delete mode 100644 arch/m68k/include/asm/dma-mapping.h
diff --git a/arch/m68k/Kconfig b/arch/m68k/Kconfig
index 785612b576f7..3f61327da2d5 100644
--- a/arch/m68k/Kconfig
+++ b/arch/m68k/Kconfig
@@ -2,6 +2,7 @@
config M68K
bool
default y
+ select ARCH_HAS_SYNC_DMA_FOR_DEVICE if HAS_DMA
select ARCH_MIGHT_HAVE_PC_PARPORT if ISA
select ARCH_NO_COHERENT_DMA_MMAP if !MMU
select HAVE_IDE
@@ -24,6 +25,7 @@ config M68K
select MODULES_USE_ELF_RELA
select OLD_SIGSUSPEND3
select OLD_SIGACTION
+ select DMA_NONCOHERENT_OPS if HAS_DMA
config CPU_BIG_ENDIAN
def_bool y
diff --git a/arch/m68k/include/asm/Kbuild b/arch/m68k/include/asm/Kbuild
index 88a9d27df1ac..a853c00f1374 100644
--- a/arch/m68k/include/asm/Kbuild
+++ b/arch/m68k/include/asm/Kbuild
@@ -1,5 +1,6 @@
generic-y += barrier.h
generic-y += device.h
+generic-y += dma-mapping.h
generic-y += emergency-restart.h
generic-y += exec.h
generic-y += extable.h
diff --git a/arch/m68k/include/asm/dma-mapping.h b/arch/m68k/include/asm/dma-mapping.h
deleted file mode 100644
index e3722ed04fbb..000000000000
--- a/arch/m68k/include/asm/dma-mapping.h
+++ /dev/null
@@ -1,12 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef _M68K_DMA_MAPPING_H
-#define _M68K_DMA_MAPPING_H
-
-extern const struct dma_map_ops m68k_dma_ops;
-
-static inline const struct dma_map_ops *get_arch_dma_ops(struct bus_type *bus)
-{
- return &m68k_dma_ops;
-}
-
-#endif /* _M68K_DMA_MAPPING_H */
diff --git a/arch/m68k/kernel/dma.c b/arch/m68k/kernel/dma.c
index c01b9b8f97bf..3d561c577d35 100644
--- a/arch/m68k/kernel/dma.c
+++ b/arch/m68k/kernel/dma.c
@@ -6,7 +6,7 @@
#undef DEBUG
-#include <linux/dma-mapping.h>
+#include <linux/dma-noncoherent.h>
#include <linux/device.h>
#include <linux/kernel.h>
#include <linux/scatterlist.h>
@@ -18,7 +18,7 @@
#if defined(CONFIG_MMU) && !defined(CONFIG_COLDFIRE)
-static void *m68k_dma_alloc(struct device *dev, size_t size, dma_addr_t *handle,
+void *arch_dma_alloc(struct device *dev, size_t size, dma_addr_t *handle,
gfp_t flag, unsigned long attrs)
{
struct page *page, **map;
@@ -61,7 +61,7 @@ static void *m68k_dma_alloc(struct device *dev, size_t size, dma_addr_t *handle,
return addr;
}
-static void m68k_dma_free(struct device *dev, size_t size, void *addr,
+void arch_dma_free(struct device *dev, size_t size, void *addr,
dma_addr_t handle, unsigned long attrs)
{
pr_debug("dma_free_coherent: %p, %x\n", addr, handle);
@@ -72,8 +72,8 @@ static void m68k_dma_free(struct device *dev, size_t size, void *addr,
#include <asm/cacheflush.h>
-static void *m68k_dma_alloc(struct device *dev, size_t size,
- dma_addr_t *dma_handle, gfp_t gfp, unsigned long attrs)
+void *arch_dma_alloc(struct device *dev, size_t size, dma_addr_t *dma_handle,
+ gfp_t gfp, unsigned long attrs)
{
void *ret;
@@ -88,7 +88,7 @@ static void *m68k_dma_alloc(struct device *dev, size_t size,
return ret;
}
-static void m68k_dma_free(struct device *dev, size_t size, void *vaddr,
+void arch_dma_free(struct device *dev, size_t size, void *vaddr,
dma_addr_t dma_handle, unsigned long attrs)
{
free_pages((unsigned long)vaddr, get_order(size));
@@ -96,8 +96,8 @@ static void m68k_dma_free(struct device *dev, size_t size, void *vaddr,
#endif /* CONFIG_MMU && !CONFIG_COLDFIRE */
-static void m68k_dma_sync_single_for_device(struct device *dev,
- dma_addr_t handle, size_t size, enum dma_data_direction dir)
+void arch_sync_dma_for_device(struct device *dev, phys_addr_t handle,
+ size_t size, enum dma_data_direction dir)
{
switch (dir) {
case DMA_BIDIRECTIONAL:
@@ -113,55 +113,3 @@ static void m68k_dma_sync_single_for_device(struct device *dev,
break;
}
}
-
-static void m68k_dma_sync_sg_for_device(struct device *dev,
- struct scatterlist *sglist, int nents, enum dma_data_direction dir)
-{
- int i;
- struct scatterlist *sg;
-
- for_each_sg(sglist, sg, nents, i) {
- dma_sync_single_for_device(dev, sg->dma_address, sg->length,
- dir);
- }
-}
-
-static dma_addr_t m68k_dma_map_page(struct device *dev, struct page *page,
- unsigned long offset, size_t size, enum dma_data_direction dir,
- unsigned long attrs)
-{
- dma_addr_t handle = page_to_phys(page) + offset;
-
- if (!(attrs & DMA_ATTR_SKIP_CPU_SYNC))
- dma_sync_single_for_device(dev, handle, size, dir);
-
- return handle;
-}
-
-static int m68k_dma_map_sg(struct device *dev, struct scatterlist *sglist,
- int nents, enum dma_data_direction dir, unsigned long attrs)
-{
- int i;
- struct scatterlist *sg;
-
- for_each_sg(sglist, sg, nents, i) {
- sg->dma_address = sg_phys(sg);
-
- if (attrs & DMA_ATTR_SKIP_CPU_SYNC)
- continue;
-
- dma_sync_single_for_device(dev, sg->dma_address, sg->length,
- dir);
- }
- return nents;
-}
-
-const struct dma_map_ops m68k_dma_ops = {
- .alloc = m68k_dma_alloc,
- .free = m68k_dma_free,
- .map_page = m68k_dma_map_page,
- .map_sg = m68k_dma_map_sg,
- .sync_single_for_device = m68k_dma_sync_single_for_device,
- .sync_sg_for_device = m68k_dma_sync_sg_for_device,
-};
-EXPORT_SYMBOL(m68k_dma_ops);
--
2.17.0
^ permalink raw reply related
* [PATCH 03/25] hexagon: use generic dma_noncoherent_ops
From: Christoph Hellwig @ 2018-05-22 12:04 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180522120430.28709-1-hch@lst.de>
Switch to the generic noncoherent direct mapping implementation.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
arch/hexagon/Kconfig | 2 +
arch/hexagon/include/asm/Kbuild | 1 +
arch/hexagon/include/asm/dma-mapping.h | 40 -------
arch/hexagon/kernel/dma.c | 148 ++-----------------------
4 files changed, 11 insertions(+), 180 deletions(-)
delete mode 100644 arch/hexagon/include/asm/dma-mapping.h
diff --git a/arch/hexagon/Kconfig b/arch/hexagon/Kconfig
index 37adb2003033..bcbdcb32935c 100644
--- a/arch/hexagon/Kconfig
+++ b/arch/hexagon/Kconfig
@@ -4,6 +4,7 @@ comment "Linux Kernel Configuration for Hexagon"
config HEXAGON
def_bool y
+ select ARCH_HAS_SYNC_DMA_FOR_DEVICE
select HAVE_OPROFILE
# Other pending projects/to-do items.
# select HAVE_REGS_AND_STACK_ACCESS_API
@@ -28,6 +29,7 @@ config HEXAGON
select GENERIC_CLOCKEVENTS_BROADCAST
select MODULES_USE_ELF_RELA
select GENERIC_CPU_DEVICES
+ select DMA_NONCOHERENT_OPS
---help---
Qualcomm Hexagon is a processor architecture designed for high
performance and low power across a wide variety of applications.
diff --git a/arch/hexagon/include/asm/Kbuild b/arch/hexagon/include/asm/Kbuild
index e9743f689fb8..843a8086e980 100644
--- a/arch/hexagon/include/asm/Kbuild
+++ b/arch/hexagon/include/asm/Kbuild
@@ -5,6 +5,7 @@ generic-y += bugs.h
generic-y += current.h
generic-y += device.h
generic-y += div64.h
+generic-y += dma-mapping.h
generic-y += emergency-restart.h
generic-y += extable.h
generic-y += fb.h
diff --git a/arch/hexagon/include/asm/dma-mapping.h b/arch/hexagon/include/asm/dma-mapping.h
deleted file mode 100644
index 263f6acbfb0f..000000000000
--- a/arch/hexagon/include/asm/dma-mapping.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * DMA operations for the Hexagon architecture
- *
- * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 and
- * only version 2 as published by the Free Software Foundation.
- *
- * This program 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 this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- */
-
-#ifndef _ASM_DMA_MAPPING_H
-#define _ASM_DMA_MAPPING_H
-
-#include <linux/types.h>
-#include <linux/cache.h>
-#include <linux/mm.h>
-#include <linux/scatterlist.h>
-#include <linux/dma-debug.h>
-#include <asm/io.h>
-
-struct device;
-
-extern const struct dma_map_ops *dma_ops;
-
-static inline const struct dma_map_ops *get_arch_dma_ops(struct bus_type *bus)
-{
- return dma_ops;
-}
-
-#endif
diff --git a/arch/hexagon/kernel/dma.c b/arch/hexagon/kernel/dma.c
index 9e46556a227d..ffc4ae8e126f 100644
--- a/arch/hexagon/kernel/dma.c
+++ b/arch/hexagon/kernel/dma.c
@@ -18,32 +18,19 @@
* 02110-1301, USA.
*/
-#include <linux/dma-mapping.h>
-#include <linux/dma-direct.h>
+#include <linux/dma-noncoherent.h>
#include <linux/bootmem.h>
#include <linux/genalloc.h>
-#include <asm/dma-mapping.h>
#include <linux/module.h>
#include <asm/page.h>
-#define HEXAGON_MAPPING_ERROR 0
-
-const struct dma_map_ops *dma_ops;
-EXPORT_SYMBOL(dma_ops);
-
-static inline void *dma_addr_to_virt(dma_addr_t dma_addr)
-{
- return phys_to_virt((unsigned long) dma_addr);
-}
-
static struct gen_pool *coherent_pool;
/* Allocates from a pool of uncached memory that was reserved at boot time */
-static void *hexagon_dma_alloc_coherent(struct device *dev, size_t size,
- dma_addr_t *dma_addr, gfp_t flag,
- unsigned long attrs)
+void *arch_dma_alloc(struct device *dev, size_t size, dma_addr_t *dma_addr,
+ gfp_t flag, unsigned long attrs)
{
void *ret;
@@ -75,58 +62,17 @@ static void *hexagon_dma_alloc_coherent(struct device *dev, size_t size,
return ret;
}
-static void hexagon_free_coherent(struct device *dev, size_t size, void *vaddr,
- dma_addr_t dma_addr, unsigned long attrs)
+void arch_dma_free(struct device *dev, size_t size, void *vaddr,
+ dma_addr_t dma_addr, unsigned long attrs)
{
gen_pool_free(coherent_pool, (unsigned long) vaddr, size);
}
-static int check_addr(const char *name, struct device *hwdev,
- dma_addr_t bus, size_t size)
-{
- if (hwdev && hwdev->dma_mask && !dma_capable(hwdev, bus, size)) {
- if (*hwdev->dma_mask >= DMA_BIT_MASK(32))
- printk(KERN_ERR
- "%s: overflow %Lx+%zu of device mask %Lx\n",
- name, (long long)bus, size,
- (long long)*hwdev->dma_mask);
- return 0;
- }
- return 1;
-}
-
-static int hexagon_map_sg(struct device *hwdev, struct scatterlist *sg,
- int nents, enum dma_data_direction dir,
- unsigned long attrs)
+void arch_sync_dma_for_device(struct device *dev, phys_addr_t paddr,
+ size_t size, enum dma_data_direction dir)
{
- struct scatterlist *s;
- int i;
-
- WARN_ON(nents == 0 || sg[0].length == 0);
-
- for_each_sg(sg, s, nents, i) {
- s->dma_address = sg_phys(s);
- if (!check_addr("map_sg", hwdev, s->dma_address, s->length))
- return 0;
-
- s->dma_length = s->length;
+ void *addr = phys_to_virt(paddr);
- if (attrs & DMA_ATTR_SKIP_CPU_SYNC)
- continue;
-
- flush_dcache_range(dma_addr_to_virt(s->dma_address),
- dma_addr_to_virt(s->dma_address + s->length));
- }
-
- return nents;
-}
-
-/*
- * address is virtual
- */
-static inline void dma_sync(void *addr, size_t size,
- enum dma_data_direction dir)
-{
switch (dir) {
case DMA_TO_DEVICE:
hexagon_clean_dcache_range((unsigned long) addr,
@@ -144,81 +90,3 @@ static inline void dma_sync(void *addr, size_t size,
BUG();
}
}
-
-/**
- * hexagon_map_page() - maps an address for device DMA
- * @dev: pointer to DMA device
- * @page: pointer to page struct of DMA memory
- * @offset: offset within page
- * @size: size of memory to map
- * @dir: transfer direction
- * @attrs: pointer to DMA attrs (not used)
- *
- * Called to map a memory address to a DMA address prior
- * to accesses to/from device.
- *
- * We don't particularly have many hoops to jump through
- * so far. Straight translation between phys and virtual.
- *
- * DMA is not cache coherent so sync is necessary; this
- * seems to be a convenient place to do it.
- *
- */
-static dma_addr_t hexagon_map_page(struct device *dev, struct page *page,
- unsigned long offset, size_t size,
- enum dma_data_direction dir,
- unsigned long attrs)
-{
- dma_addr_t bus = page_to_phys(page) + offset;
- WARN_ON(size == 0);
-
- if (!check_addr("map_single", dev, bus, size))
- return HEXAGON_MAPPING_ERROR;
-
- if (!(attrs & DMA_ATTR_SKIP_CPU_SYNC))
- dma_sync(dma_addr_to_virt(bus), size, dir);
-
- return bus;
-}
-
-static void hexagon_sync_single_for_device(struct device *dev,
- dma_addr_t dma_handle, size_t size,
- enum dma_data_direction dir)
-{
- dma_sync(dma_addr_to_virt(dma_handle), size, dir);
-}
-
-static void hexagon_sync_sg_for_device(struct device *dev,
- struct scatterlist *sgl, int nents, enum dma_data_direction dir)
-{
- struct scatterlist *sg;
- int i;
-
- for_each_sg(sgl, sg, nents, i)
- hexagon_sync_single_for_device(dev, sg_dma_address(sg),
- sg->length, dir);
-}
-
-
-static int hexagon_mapping_error(struct device *dev, dma_addr_t dma_addr)
-{
- return dma_addr == HEXAGON_MAPPING_ERROR;
-}
-
-const struct dma_map_ops hexagon_dma_ops = {
- .alloc = hexagon_dma_alloc_coherent,
- .free = hexagon_free_coherent,
- .map_sg = hexagon_map_sg,
- .map_page = hexagon_map_page,
- .sync_single_for_device = hexagon_sync_single_for_device,
- .sync_sg_for_device = hexagon_sync_sg_for_device,
- .mapping_error = hexagon_mapping_error,
-};
-
-void __init hexagon_dma_init(void)
-{
- if (dma_ops)
- return;
-
- dma_ops = &hexagon_dma_ops;
-}
--
2.17.0
^ permalink raw reply related
* [PATCH 02/25] hexagon: implement the sync_sg_for_device DMA operation
From: Christoph Hellwig @ 2018-05-22 12:04 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180522120430.28709-1-hch@lst.de>
This methods needs to provide the equivalent of sync_single_for_device
for each S/G list element, but was missing.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
arch/hexagon/kernel/dma.c | 13 +++++++++++++
1 file changed, 13 insertions(+)
diff --git a/arch/hexagon/kernel/dma.c b/arch/hexagon/kernel/dma.c
index d2b717f352f4..9e46556a227d 100644
--- a/arch/hexagon/kernel/dma.c
+++ b/arch/hexagon/kernel/dma.c
@@ -188,6 +188,18 @@ static void hexagon_sync_single_for_device(struct device *dev,
dma_sync(dma_addr_to_virt(dma_handle), size, dir);
}
+static void hexagon_sync_sg_for_device(struct device *dev,
+ struct scatterlist *sgl, int nents, enum dma_data_direction dir)
+{
+ struct scatterlist *sg;
+ int i;
+
+ for_each_sg(sgl, sg, nents, i)
+ hexagon_sync_single_for_device(dev, sg_dma_address(sg),
+ sg->length, dir);
+}
+
+
static int hexagon_mapping_error(struct device *dev, dma_addr_t dma_addr)
{
return dma_addr == HEXAGON_MAPPING_ERROR;
@@ -199,6 +211,7 @@ const struct dma_map_ops hexagon_dma_ops = {
.map_sg = hexagon_map_sg,
.map_page = hexagon_map_page,
.sync_single_for_device = hexagon_sync_single_for_device,
+ .sync_sg_for_device = hexagon_sync_sg_for_device,
.mapping_error = hexagon_mapping_error,
};
--
2.17.0
^ permalink raw reply related
* [PATCH 01/25] hexagon: remove the sync_single_for_cpu DMA operation
From: Christoph Hellwig @ 2018-05-22 12:04 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180522120430.28709-1-hch@lst.de>
hexagon does all the required cache maintainance at dma map time, and none
at unmap time. It thus has to implement sync_single_for_device to match
the map cace for buffer reuse, but there is no point in doing another
invalidation in the sync_single_cpu_case, which in terms of cache
maintainance is equivalent to the unmap case.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
arch/hexagon/kernel/dma.c | 8 --------
1 file changed, 8 deletions(-)
diff --git a/arch/hexagon/kernel/dma.c b/arch/hexagon/kernel/dma.c
index 77459df34e2e..d2b717f352f4 100644
--- a/arch/hexagon/kernel/dma.c
+++ b/arch/hexagon/kernel/dma.c
@@ -181,13 +181,6 @@ static dma_addr_t hexagon_map_page(struct device *dev, struct page *page,
return bus;
}
-static void hexagon_sync_single_for_cpu(struct device *dev,
- dma_addr_t dma_handle, size_t size,
- enum dma_data_direction dir)
-{
- dma_sync(dma_addr_to_virt(dma_handle), size, dir);
-}
-
static void hexagon_sync_single_for_device(struct device *dev,
dma_addr_t dma_handle, size_t size,
enum dma_data_direction dir)
@@ -205,7 +198,6 @@ const struct dma_map_ops hexagon_dma_ops = {
.free = hexagon_free_coherent,
.map_sg = hexagon_map_sg,
.map_page = hexagon_map_page,
- .sync_single_for_cpu = hexagon_sync_single_for_cpu,
.sync_single_for_device = hexagon_sync_single_for_device,
.mapping_error = hexagon_mapping_error,
};
--
2.17.0
^ permalink raw reply related
* common non-cache coherent direct dma mapping ops v2
From: Christoph Hellwig @ 2018-05-22 12:04 UTC (permalink / raw)
To: linux-arm-kernel
Hi all,
this series continues consolidating the dma-mapping code, with a focus
on architectures that do not (always) provide cache coherence for DMA.
Three architectures (arm, mips and powerpc) are still left to be
converted later due to complexity of their dma ops selection.
The dma-noncoherent ops calls the dma-direct ops for the actual
translation of streaming mappins and allow the architecture to provide
any cache flushing required for cpu to device and/or device to cpu
ownership transfers. The dma coherent allocator is for now still left
entirely to architecture supplied implementations due the amount of
variations. Hopefully we can do some consolidation for them later on
as well.
A lot of architectures are currently doing very questionable things
in their dma mapping routines, which are documented in the changelogs
for each patch. Please review them very careful and correct me on
incorrect assumptions.
Because this series sits on top of three previously submitted series
a git tree might be useful to actually test it. It is provided here:
git://git.infradead.org/users/hch/misc.git generic-dma-noncoherent.2
Gitweb:
http://git.infradead.org/users/hch/misc.git/shortlog/refs/heads/generic-dma-noncoherent.2
Changes since v1:
- dropped the already merged generic, arc and c6x patches
(with the map_single offset fix from Alexey Brodkin)
- split various changes into smaller patches
- dropped the arm-nommu changes for now
- fixed a typo
Changes since RFC:
- fix a typo accidentally disabling the device to cpu transfer sync
- fixed a few compile failures
^ permalink raw reply
* [PATCH 9/9] ARM: dts: silk: Drop MTD partitioning from DT
From: Marek Vasut @ 2018-05-22 12:02 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180522120257.13232-1-marek.vasut+renesas@gmail.com>
Drop the MTD partitioning from DT, since it does not describe HW
and to give way to a more flexible kernel command line partition
passing.
To retain the original partitioning, assure you have enabled
CONFIG_MTD_CMDLINE_PARTS in your kernel config and add the
following to your kernel command line:
mtdparts=spi0.0:256k at 0(loader),4096k(user),-(flash)
Signed-off-by: Marek Vasut <marek.vasut+renesas@gmail.com>
Cc: Geert Uytterhoeven <geert+renesas@glider.be>
Cc: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Cc: Simon Horman <horms+renesas@verge.net.au>
Cc: Wolfram Sang <wsa@the-dreams.de>
Cc: linux-renesas-soc at vger.kernel.org
---
arch/arm/boot/dts/r8a7794-silk.dts | 21 ---------------------
1 file changed, 21 deletions(-)
diff --git a/arch/arm/boot/dts/r8a7794-silk.dts b/arch/arm/boot/dts/r8a7794-silk.dts
index 7808aaee6644..b8163a0e2190 100644
--- a/arch/arm/boot/dts/r8a7794-silk.dts
+++ b/arch/arm/boot/dts/r8a7794-silk.dts
@@ -444,27 +444,6 @@
spi-cpol;
spi-cpha;
m25p,fast-read;
-
- partitions {
- compatible = "fixed-partitions";
- #address-cells = <1>;
- #size-cells = <1>;
-
- partition at 0 {
- label = "loader";
- reg = <0x00000000 0x00040000>;
- read-only;
- };
- partition at 40000 {
- label = "user";
- reg = <0x00040000 0x00400000>;
- read-only;
- };
- partition at 440000 {
- label = "flash";
- reg = <0x00440000 0x03bc0000>;
- };
- };
};
};
--
2.16.2
^ permalink raw reply related
* [PATCH 8/9] ARM: dts: alt: Drop MTD partitioning from DT
From: Marek Vasut @ 2018-05-22 12:02 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180522120257.13232-1-marek.vasut+renesas@gmail.com>
Drop the MTD partitioning from DT, since it does not describe HW
and to give way to a more flexible kernel command line partition
passing.
To retain the original partitioning, assure you have enabled
CONFIG_MTD_CMDLINE_PARTS in your kernel config and add the
following to your kernel command line:
mtdparts=spi0.0:256k at 0(loader),256k(system),-(user)
Signed-off-by: Marek Vasut <marek.vasut+renesas@gmail.com>
Cc: Geert Uytterhoeven <geert+renesas@glider.be>
Cc: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Cc: Simon Horman <horms+renesas@verge.net.au>
Cc: Wolfram Sang <wsa@the-dreams.de>
Cc: linux-renesas-soc at vger.kernel.org
---
arch/arm/boot/dts/r8a7794-alt.dts | 21 ---------------------
1 file changed, 21 deletions(-)
diff --git a/arch/arm/boot/dts/r8a7794-alt.dts b/arch/arm/boot/dts/r8a7794-alt.dts
index e17027532941..1d044ed598f3 100644
--- a/arch/arm/boot/dts/r8a7794-alt.dts
+++ b/arch/arm/boot/dts/r8a7794-alt.dts
@@ -419,26 +419,5 @@
spi-cpol;
spi-cpha;
m25p,fast-read;
-
- partitions {
- compatible = "fixed-partitions";
- #address-cells = <1>;
- #size-cells = <1>;
-
- partition at 0 {
- label = "loader";
- reg = <0x00000000 0x00040000>;
- read-only;
- };
- partition at 40000 {
- label = "system";
- reg = <0x00040000 0x00040000>;
- read-only;
- };
- partition at 80000 {
- label = "user";
- reg = <0x00080000 0x03f80000>;
- };
- };
};
};
--
2.16.2
^ permalink raw reply related
* [PATCH 7/9] ARM: dts: gose: Drop MTD partitioning from DT
From: Marek Vasut @ 2018-05-22 12:02 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180522120257.13232-1-marek.vasut+renesas@gmail.com>
Drop the MTD partitioning from DT, since it does not describe HW
and to give way to a more flexible kernel command line partition
passing.
To retain the original partitioning, assure you have enabled
CONFIG_MTD_CMDLINE_PARTS in your kernel config and add the
following to your kernel command line:
mtdparts=spi0.0:256k at 0(loader),4096k(user),-(flash)
Signed-off-by: Marek Vasut <marek.vasut+renesas@gmail.com>
Cc: Geert Uytterhoeven <geert+renesas@glider.be>
Cc: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Cc: Simon Horman <horms+renesas@verge.net.au>
Cc: Wolfram Sang <wsa@the-dreams.de>
Cc: linux-renesas-soc at vger.kernel.org
---
arch/arm/boot/dts/r8a7793-gose.dts | 21 ---------------------
1 file changed, 21 deletions(-)
diff --git a/arch/arm/boot/dts/r8a7793-gose.dts b/arch/arm/boot/dts/r8a7793-gose.dts
index aa209f6e5d71..b2dd54fbe40c 100644
--- a/arch/arm/boot/dts/r8a7793-gose.dts
+++ b/arch/arm/boot/dts/r8a7793-gose.dts
@@ -676,27 +676,6 @@
spi-cpol;
spi-cpha;
m25p,fast-read;
-
- partitions {
- compatible = "fixed-partitions";
- #address-cells = <1>;
- #size-cells = <1>;
-
- partition at 0 {
- label = "loader";
- reg = <0x00000000 0x00040000>;
- read-only;
- };
- partition at 40000 {
- label = "user";
- reg = <0x00040000 0x00400000>;
- read-only;
- };
- partition at 440000 {
- label = "flash";
- reg = <0x00440000 0x03bc0000>;
- };
- };
};
};
--
2.16.2
^ permalink raw reply related
* [PATCH 6/9] ARM: dts: wheat: Drop MTD partitioning from DT
From: Marek Vasut @ 2018-05-22 12:02 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180522120257.13232-1-marek.vasut+renesas@gmail.com>
Drop the MTD partitioning from DT, since it does not describe HW
and to give way to a more flexible kernel command line partition
passing.
To retain the original partitioning, assure you have enabled
CONFIG_MTD_CMDLINE_PARTS in your kernel config and add the
following to your kernel command line:
mtdparts=spi0.0:256k at 0(loader),4096k(user),-(flash)
Signed-off-by: Marek Vasut <marek.vasut+renesas@gmail.com>
Cc: Geert Uytterhoeven <geert+renesas@glider.be>
Cc: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Cc: Simon Horman <horms+renesas@verge.net.au>
Cc: Wolfram Sang <wsa@the-dreams.de>
Cc: linux-renesas-soc at vger.kernel.org
---
arch/arm/boot/dts/r8a7792-wheat.dts | 21 ---------------------
1 file changed, 21 deletions(-)
diff --git a/arch/arm/boot/dts/r8a7792-wheat.dts b/arch/arm/boot/dts/r8a7792-wheat.dts
index db01de7a3811..93f78716225a 100644
--- a/arch/arm/boot/dts/r8a7792-wheat.dts
+++ b/arch/arm/boot/dts/r8a7792-wheat.dts
@@ -217,27 +217,6 @@
spi-cpol;
spi-cpha;
m25p,fast-read;
-
- partitions {
- compatible = "fixed-partitions";
- #address-cells = <1>;
- #size-cells = <1>;
-
- partition at 0 {
- label = "loader";
- reg = <0x00000000 0x00040000>;
- read-only;
- };
- partition at 40000 {
- label = "user";
- reg = <0x00040000 0x00400000>;
- read-only;
- };
- partition at 440000 {
- label = "flash";
- reg = <0x00440000 0x03bc0000>;
- };
- };
};
};
--
2.16.2
^ permalink raw reply related
* [PATCH 5/9] ARM: dts: porter: Drop MTD partitioning from DT
From: Marek Vasut @ 2018-05-22 12:02 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180522120257.13232-1-marek.vasut+renesas@gmail.com>
Drop the MTD partitioning from DT, since it does not describe HW
and to give way to a more flexible kernel command line partition
passing.
To retain the original partitioning, assure you have enabled
CONFIG_MTD_CMDLINE_PARTS in your kernel config and add the
following to your kernel command line:
mtdparts=spi0.0:256k at 0(loader_prg),4096k(user_prg),-(flash_fs)
Signed-off-by: Marek Vasut <marek.vasut+renesas@gmail.com>
Cc: Geert Uytterhoeven <geert+renesas@glider.be>
Cc: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Cc: Simon Horman <horms+renesas@verge.net.au>
Cc: Wolfram Sang <wsa@the-dreams.de>
Cc: linux-renesas-soc at vger.kernel.org
---
arch/arm/boot/dts/r8a7791-porter.dts | 21 ---------------------
1 file changed, 21 deletions(-)
diff --git a/arch/arm/boot/dts/r8a7791-porter.dts b/arch/arm/boot/dts/r8a7791-porter.dts
index a01101b49d99..45d89e064407 100644
--- a/arch/arm/boot/dts/r8a7791-porter.dts
+++ b/arch/arm/boot/dts/r8a7791-porter.dts
@@ -344,27 +344,6 @@
spi-tx-bus-width = <4>;
spi-rx-bus-width = <4>;
m25p,fast-read;
-
- partitions {
- compatible = "fixed-partitions";
- #address-cells = <1>;
- #size-cells = <1>;
-
- partition at 0 {
- label = "loader_prg";
- reg = <0x00000000 0x00040000>;
- read-only;
- };
- partition at 40000 {
- label = "user_prg";
- reg = <0x00040000 0x00400000>;
- read-only;
- };
- partition at 440000 {
- label = "flash_fs";
- reg = <0x00440000 0x03bc0000>;
- };
- };
};
};
--
2.16.2
^ permalink raw reply related
* [PATCH 4/9] ARM: dts: koelsch: Drop MTD partitioning from DT
From: Marek Vasut @ 2018-05-22 12:02 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180522120257.13232-1-marek.vasut+renesas@gmail.com>
Drop the MTD partitioning from DT, since it does not describe HW
and to give way to a more flexible kernel command line partition
passing.
To retain the original partitioning, assure you have enabled
CONFIG_MTD_CMDLINE_PARTS in your kernel config and add the
following to your kernel command line:
mtdparts=spi0.0:512k at 0(loader),5632k(user),-(flash)
Signed-off-by: Marek Vasut <marek.vasut+renesas@gmail.com>
Cc: Geert Uytterhoeven <geert+renesas@glider.be>
Cc: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Cc: Simon Horman <horms+renesas@verge.net.au>
Cc: Wolfram Sang <wsa@the-dreams.de>
Cc: linux-renesas-soc at vger.kernel.org
---
arch/arm/boot/dts/r8a7791-koelsch.dts | 21 ---------------------
1 file changed, 21 deletions(-)
diff --git a/arch/arm/boot/dts/r8a7791-koelsch.dts b/arch/arm/boot/dts/r8a7791-koelsch.dts
index 8ab793d8b2fd..406d5d29e29c 100644
--- a/arch/arm/boot/dts/r8a7791-koelsch.dts
+++ b/arch/arm/boot/dts/r8a7791-koelsch.dts
@@ -724,27 +724,6 @@
spi-cpha;
spi-cpol;
m25p,fast-read;
-
- partitions {
- compatible = "fixed-partitions";
- #address-cells = <1>;
- #size-cells = <1>;
-
- partition at 0 {
- label = "loader";
- reg = <0x00000000 0x00080000>;
- read-only;
- };
- partition at 80000 {
- label = "user";
- reg = <0x00080000 0x00580000>;
- read-only;
- };
- partition at 600000 {
- label = "flash";
- reg = <0x00600000 0x03a00000>;
- };
- };
};
};
--
2.16.2
^ permalink raw reply related
* [PATCH 3/9] ARM: dts: stout: Drop MTD partitioning from DT
From: Marek Vasut @ 2018-05-22 12:02 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180522120257.13232-1-marek.vasut+renesas@gmail.com>
Drop the MTD partitioning from DT, since it does not describe HW
and to give way to a more flexible kernel command line partition
passing.
To retain the original partitioning, assure you have enabled
CONFIG_MTD_CMDLINE_PARTS in your kernel config and add the
following to your kernel command line:
mtdparts=spi0.0:512k at 0(loader),256k(uboot),256k(uboot-env),-(flash)
Signed-off-by: Marek Vasut <marek.vasut+renesas@gmail.com>
Cc: Geert Uytterhoeven <geert+renesas@glider.be>
Cc: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Cc: Simon Horman <horms+renesas@verge.net.au>
Cc: Wolfram Sang <wsa@the-dreams.de>
Cc: linux-renesas-soc at vger.kernel.org
---
arch/arm/boot/dts/r8a7790-stout.dts | 26 --------------------------
1 file changed, 26 deletions(-)
diff --git a/arch/arm/boot/dts/r8a7790-stout.dts b/arch/arm/boot/dts/r8a7790-stout.dts
index a13a92c26645..dc65519d53ab 100644
--- a/arch/arm/boot/dts/r8a7790-stout.dts
+++ b/arch/arm/boot/dts/r8a7790-stout.dts
@@ -211,32 +211,6 @@
spi-cpha;
spi-cpol;
m25p,fast-read;
-
- partitions {
- compatible = "fixed-partitions";
- #address-cells = <1>;
- #size-cells = <1>;
-
- partition at 0 {
- label = "loader";
- reg = <0x00000000 0x00080000>;
- read-only;
- };
- partition at 80000 {
- label = "uboot";
- reg = <0x00080000 0x00040000>;
- read-only;
- };
- partition at c0000 {
- label = "uboot-env";
- reg = <0x000c0000 0x00040000>;
- read-only;
- };
- partition at 100000 {
- label = "flash";
- reg = <0x00100000 0x03f00000>;
- };
- };
};
};
--
2.16.2
^ permalink raw reply related
* [PATCH 2/9] ARM: dts: lager: Drop MTD partitioning from DT
From: Marek Vasut @ 2018-05-22 12:02 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180522120257.13232-1-marek.vasut+renesas@gmail.com>
Drop the MTD partitioning from DT, since it does not describe HW
and to give way to a more flexible kernel command line partition
passing.
To retain the original partitioning, assure you have enabled
CONFIG_MTD_CMDLINE_PARTS in your kernel config and add the
following to your kernel command line:
mtdparts=spi0.0:256k at 0(loader),4096k(user),-(flash)
Signed-off-by: Marek Vasut <marek.vasut+renesas@gmail.com>
Cc: Geert Uytterhoeven <geert+renesas@glider.be>
Cc: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Cc: Simon Horman <horms+renesas@verge.net.au>
Cc: Wolfram Sang <wsa@the-dreams.de>
Cc: linux-renesas-soc at vger.kernel.org
---
arch/arm/boot/dts/r8a7790-lager.dts | 21 ---------------------
1 file changed, 21 deletions(-)
diff --git a/arch/arm/boot/dts/r8a7790-lager.dts b/arch/arm/boot/dts/r8a7790-lager.dts
index 092610e3f953..7c95e62efd46 100644
--- a/arch/arm/boot/dts/r8a7790-lager.dts
+++ b/arch/arm/boot/dts/r8a7790-lager.dts
@@ -710,27 +710,6 @@
spi-cpha;
spi-cpol;
m25p,fast-read;
-
- partitions {
- compatible = "fixed-partitions";
- #address-cells = <1>;
- #size-cells = <1>;
-
- partition at 0 {
- label = "loader";
- reg = <0x00000000 0x00040000>;
- read-only;
- };
- partition at 40000 {
- label = "user";
- reg = <0x00040000 0x00400000>;
- read-only;
- };
- partition at 440000 {
- label = "flash";
- reg = <0x00440000 0x03bc0000>;
- };
- };
};
};
--
2.16.2
^ permalink raw reply related
* [PATCH 1/9] ARM: shmobile: defconfig: Enable MTD command line partition parsing
From: Marek Vasut @ 2018-05-22 12:02 UTC (permalink / raw)
To: linux-arm-kernel
In preparation for removing MTD partitioning from the DTs and moving
it over to kernel command line partition parsing, enable the support
for kernel command line MTD partition parsing.
The argument for not having MTD partitions in the DT is the same as
for not having hard drive partitions in DT, neither describes the
hardware itself, so it shouldn't be in the DT. Furthermore, kernel
command line MTD partition passing allows greater flexibility in
case someone decided to repartition the flash, which is well in the
realm of possibility with these systems.
Signed-off-by: Marek Vasut <marek.vasut+renesas@gmail.com>
Cc: Geert Uytterhoeven <geert+renesas@glider.be>
Cc: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Cc: Simon Horman <horms+renesas@verge.net.au>
Cc: Wolfram Sang <wsa@the-dreams.de>
Cc: linux-renesas-soc at vger.kernel.org
---
arch/arm/configs/shmobile_defconfig | 1 +
1 file changed, 1 insertion(+)
diff --git a/arch/arm/configs/shmobile_defconfig b/arch/arm/configs/shmobile_defconfig
index b49887e86a3d..4d0d5a00a188 100644
--- a/arch/arm/configs/shmobile_defconfig
+++ b/arch/arm/configs/shmobile_defconfig
@@ -64,6 +64,7 @@ CONFIG_DMA_CMA=y
CONFIG_CMA_SIZE_MBYTES=64
CONFIG_SIMPLE_PM_BUS=y
CONFIG_MTD=y
+CONFIG_MTD_CMDLINE_PARTS=y
CONFIG_MTD_BLOCK=y
CONFIG_MTD_M25P80=y
CONFIG_MTD_SPI_NOR=y
--
2.16.2
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox