Received: by 10.192.165.148 with SMTP id m20csp333957imm; Tue, 24 Apr 2018 23:40:51 -0700 (PDT) X-Google-Smtp-Source: AB8JxZprx0c8g8jRTcxbQsr9l3GF6/B5pWGLUmv/LH9MZaTOtWX9ZmjAUV2T7wgG6tzeFAMB7Kgc X-Received: by 2002:a17:902:74c6:: with SMTP id f6-v6mr4804115plt.7.1524638451013; Tue, 24 Apr 2018 23:40:51 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1524638450; cv=none; d=google.com; s=arc-20160816; b=vxAJ86nJYK7+6l0wBgmIJh4nic50IIXfS9Jozim72NIGpMJyrw0pGgM9+wK4+fEdeH IfustSQ27mXL3YeO++Un1koOssrqW7jfefk7+tA2P+aSKJrWQWuKcCw5BFyqFOb7Km9m IjqOhTMX1qIjUZOjsgQruW4Q4VStLz58mrOQYzsMM7VuU5AL7ORRJpM9OOKirEjRHutf sYAffLgMAwE+fT5LFNZ6M3yfB1kKRRQeBAnKruXrD/E5mAn3meIMKaL/U1NyAT/FTFxI lvRjLEF7UbigES2mmHm3DjUgjYWXu0kUgt+BkbmZMVjWB3GE5FztQjwwhDueEynIyiQg jYfw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:user-agent:in-reply-to :content-disposition:mime-version:references:message-id:subject:cc :to:from:date:arc-authentication-results; bh=/kB4gT/WJrnUqbRyEkYyzq6v5WufyQOUmaMRwsrqUhU=; b=q5UruVDrLQo6e/YOhnvpE0XULUIc22upYsoSVdx1eZz4W3NfzsBuKtte25J0shSSbY iry+YcFEL1GFpz3t+e91lhFd0u1AKD5z64yGG9C0zUGT4JeKDsvERaWYFFhDNuRaX7oQ KiENtfTX9h1RvFrk2itWsS20YLZRSvJDqp3xKx9F4TxLAnBQ5EaB+f+g16Rwm0ON/FpB IaPHP97LI80C+T8mzag0S8lQdR+3MvVE8dglS5ElZtZOumRrScOcPlQH4rZYUco5TTBO SzsoEJdDeZb+v1N4MYe4XifaPcpv+vIRNaJrDrRi7Wz/usB2ZZHGjoXBpRwUsgwheK5a 6Sew== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id s6-v6si17401453plp.18.2018.04.24.23.40.36; Tue, 24 Apr 2018 23:40:50 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751356AbeDYGj2 (ORCPT + 99 others); Wed, 25 Apr 2018 02:39:28 -0400 Received: from verein.lst.de ([213.95.11.211]:35008 "EHLO newverein.lst.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750841AbeDYGjW (ORCPT ); Wed, 25 Apr 2018 02:39:22 -0400 Received: by newverein.lst.de (Postfix, from userid 2407) id 009CC68DB3; Wed, 25 Apr 2018 08:40:55 +0200 (CEST) Date: Wed, 25 Apr 2018 08:40:55 +0200 From: Christoph Hellwig To: Greentime Hu Cc: Christoph Hellwig , linux-arch , Michal Simek , Vincent Chen , linux-alpha@vger.kernel.org, linux-snps-arc@lists.infradead.org, linux-arm-kernel@lists.infradead.org, linux-c6x-dev@linux-c6x.org, linux-hexagon@vger.kernel.org, linux-m68k@lists.linux-m68k.org, nios2-dev@lists.rocketboards.org, openrisc@lists.librecores.org, linux-parisc@vger.kernel.org, linux-sh@vger.kernel.org, sparclinux , linux-xtensa@linux-xtensa.org, Linux Kernel Mailing List Subject: Re: [PATCH 13/22] nds32: use generic dma_noncoherent_ops Message-ID: <20180425064055.GA11460@lst.de> References: <20180420080313.18796-1-hch@lst.de> <20180420080313.18796-14-hch@lst.de> <20180424191640.GA32495@lst.de> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.5.17 (2007-11-01) Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Wed, Apr 25, 2018 at 09:43:43AM +0800, Greentime Hu wrote: > Hi Crhistoph, > > The ftmac100 works if I revert this commit. Thanks. ftmac100 only use dma_map_page, which in the old nds32 code is just doing a plain page_address and never kmaps. Can you apply the patch below on the tree with the origin "nds32: use generic dma_noncoherent_ops" reverted? This always just uses page_address, although that, just like the original code is broken if you actually have highmem that needs to be mapped: --- From 1dc5d1cae4cd7b9ce03d0e2943364ed4cca938d7 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Mon, 16 Apr 2018 19:20:30 +0200 Subject: nds32: use generic dma_noncoherent_ops Switch to the generic noncoherent direct mapping implementation. This makes sure the cache_sync routines is called in the unmap_sg case, to match the unmap_single and sync_{single,sg}_to_cpu cases. Signed-off-by: Christoph Hellwig --- arch/nds32/Kconfig | 3 + arch/nds32/include/asm/Kbuild | 1 + arch/nds32/include/asm/dma-mapping.h | 14 --- arch/nds32/kernel/dma.c | 182 +++++---------------------- 4 files changed, 37 insertions(+), 163 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 d291800fc621..78311a1e6fd1 100644 --- a/arch/nds32/kernel/dma.c +++ b/arch/nds32/kernel/dma.c @@ -3,17 +3,14 @@ #include #include -#include #include -#include -#include +#include #include #include #include #include #include #include -#include #include /* @@ -22,11 +19,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. * @@ -124,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; @@ -232,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; @@ -333,145 +323,39 @@ 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 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) -{ - if (!(attrs & DMA_ATTR_SKIP_CPU_SYNC)) - consistent_sync((void *)(page_address(page) + offset), size, dir, FOR_DEVICE); - return page_to_phys(page) + offset; -} -static void nds32_dma_unmap_page(struct device *dev, dma_addr_t handle, - size_t size, 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) { - if (!(attrs & DMA_ATTR_SKIP_CPU_SYNC)) - consistent_sync(phys_to_virt(handle), size, dir, FOR_CPU); -} - -/* - * 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(); - } + void *addr = phys_to_virt(paddr); + unsigned long start = (unsigned long)addr; + + 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 int nds32_dma_map_sg(struct device *dev, struct scatterlist *sg, - int nents, enum dma_data_direction dir, - unsigned long attrs) +void arch_sync_dma_for_cpu(struct device *dev, phys_addr_t paddr, + size_t size, enum dma_data_direction dir) { - 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); - } + void *addr = phys_to_virt(paddr); + unsigned long start = (unsigned long)addr; + + switch (dir) { + case DMA_TO_DEVICE: + break; + case DMA_FROM_DEVICE: + case DMA_BIDIRECTIONAL: + cpu_dma_inval_range(start, start + size); + break; + default: + BUG(); } - 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 -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++) { - char *virt = - page_address((struct page *)sg->page_link) + sg->offset; - consistent_sync(virt, sg->length, dir, FOR_CPU); - } -} - -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_DEVICE); - } -} - -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