From patchwork Wed Jul 16 15:51:32 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Zubair Lutfullah Kakakhel X-Patchwork-Id: 4568231 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 83FE5C0514 for ; Wed, 16 Jul 2014 15:54:23 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 9BA11201C7 for ; Wed, 16 Jul 2014 15:54:22 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.9]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id B5F38200E8 for ; Wed, 16 Jul 2014 15:54:21 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1X7RVY-0002j7-QV; Wed, 16 Jul 2014 15:52:40 +0000 Received: from mailapp01.imgtec.com ([195.59.15.196]) by bombadil.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1X7RV6-0002F5-6R for linux-arm-kernel@lists.infradead.org; Wed, 16 Jul 2014 15:52:13 +0000 Received: from KLMAIL01.kl.imgtec.org (unknown [192.168.5.35]) by Websense Email Security Gateway with ESMTPS id 84937600C0EC9; Wed, 16 Jul 2014 16:51:47 +0100 (IST) Received: from KLMAIL02.kl.imgtec.org (10.40.60.222) by KLMAIL01.kl.imgtec.org (192.168.5.35) with Microsoft SMTP Server (TLS) id 14.3.195.1; Wed, 16 Jul 2014 16:51:49 +0100 Received: from LEMAIL01.le.imgtec.org (192.168.152.62) by klmail02.kl.imgtec.org (10.40.60.222) with Microsoft SMTP Server (TLS) id 14.3.195.1; Wed, 16 Jul 2014 16:51:49 +0100 Received: from zkakakhel-linux.le.imgtec.org (192.168.154.89) by LEMAIL01.le.imgtec.org (192.168.152.62) with Microsoft SMTP Server (TLS) id 14.3.195.1; Wed, 16 Jul 2014 16:51:49 +0100 From: Zubair Lutfullah Kakakhel To: , , , , , , , , , Subject: [PATCH 4/4] mips: dma: Add cma support Date: Wed, 16 Jul 2014 16:51:32 +0100 Message-ID: <1405525892-60383-5-git-send-email-Zubair.Kakakhel@imgtec.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1405525892-60383-1-git-send-email-Zubair.Kakakhel@imgtec.com> References: <1405525892-60383-1-git-send-email-Zubair.Kakakhel@imgtec.com> MIME-Version: 1.0 X-Originating-IP: [192.168.154.89] X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20140716_085212_532882_F5AB6728 X-CRM114-Status: GOOD ( 15.14 ) X-Spam-Score: -0.0 (/) Cc: linux-arch@vger.kernel.org, linux-mips@linux-mips.org, x86@kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.18-1 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Adds cma support to the mips architecture. cma uses memblock. However, mips uses bootmem. bootmem is informed about any regions reserved by memblock dma api is modified to use cma reserved memory regions when available Tested using cma_test. cma_test is a simple driver that assigns blocks of memory from cma reserved sections. Signed-off-by: Zubair Lutfullah Kakakhel Acked-by: Michal Nazarewicz --- arch/mips/Kconfig | 1 + arch/mips/include/asm/Kbuild | 1 + arch/mips/kernel/setup.c | 9 +++++++++ arch/mips/mm/dma-default.c | 37 +++++++++++++++++++++++++------------ 4 files changed, 36 insertions(+), 12 deletions(-) diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 1f7bd32..7ebe54f 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -30,6 +30,7 @@ config MIPS select GENERIC_ATOMIC64 if !64BIT select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE select HAVE_DMA_ATTRS + select HAVE_DMA_CONTIGUOUS select HAVE_DMA_API_DEBUG select GENERIC_IRQ_PROBE select GENERIC_IRQ_SHOW diff --git a/arch/mips/include/asm/Kbuild b/arch/mips/include/asm/Kbuild index 0543918..552ed28 100644 --- a/arch/mips/include/asm/Kbuild +++ b/arch/mips/include/asm/Kbuild @@ -1,6 +1,7 @@ # MIPS headers generic-y += cputime.h generic-y += current.h +generic-y += dma-contiguous.h generic-y += emergency-restart.h generic-y += hash.h generic-y += local64.h diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c index a842154..217928f 100644 --- a/arch/mips/kernel/setup.c +++ b/arch/mips/kernel/setup.c @@ -24,6 +24,8 @@ #include #include #include +#include +#include #include #include @@ -476,6 +478,7 @@ static void __init bootmem_init(void) * o bootmem_init() * o sparse_init() * o paging_init() + * o dma_continguous_reserve() * * At this stage the bootmem allocator is ready to use. * @@ -609,6 +612,7 @@ static void __init request_crashkernel(struct resource *res) static void __init arch_mem_init(char **cmdline_p) { + struct memblock_region *reg; extern void plat_mem_setup(void); /* call board setup routine */ @@ -675,6 +679,11 @@ static void __init arch_mem_init(char **cmdline_p) sparse_init(); plat_swiotlb_setup(); paging_init(); + + dma_contiguous_reserve(PFN_PHYS(max_low_pfn)); + /* Tell bootmem about cma reserved memblock section */ + for_each_memblock(reserved, reg) + reserve_bootmem(reg->base, reg->size, BOOTMEM_DEFAULT); } static void __init resource_init(void) diff --git a/arch/mips/mm/dma-default.c b/arch/mips/mm/dma-default.c index 44b6dff..33ba3c5 100644 --- a/arch/mips/mm/dma-default.c +++ b/arch/mips/mm/dma-default.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include @@ -128,23 +129,30 @@ static void *mips_dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t * dma_handle, gfp_t gfp, struct dma_attrs *attrs) { void *ret; + struct page *page = NULL; + unsigned int count = PAGE_ALIGN(size) >> PAGE_SHIFT; if (dma_alloc_from_coherent(dev, size, dma_handle, &ret)) return ret; gfp = massage_gfp_flags(dev, gfp); - ret = (void *) __get_free_pages(gfp, get_order(size)); - - if (ret) { - memset(ret, 0, size); - *dma_handle = plat_map_dma_mem(dev, ret, size); - - if (!plat_device_is_coherent(dev)) { - dma_cache_wback_inv((unsigned long) ret, size); - if (!hw_coherentio) - ret = UNCAC_ADDR(ret); - } + if (IS_ENABLED(CONFIG_DMA_CMA) && !(gfp & GFP_ATOMIC)) + page = dma_alloc_from_contiguous(dev, + count, get_order(size)); + if (!page) + page = alloc_pages(gfp, get_order(size)); + + if (!page) + return NULL; + + ret = page_address(page); + memset(ret, 0, size); + *dma_handle = plat_map_dma_mem(dev, ret, size); + if (!plat_device_is_coherent(dev)) { + dma_cache_wback_inv((unsigned long) ret, size); + if (!hw_coherentio) + ret = UNCAC_ADDR(ret); } return ret; @@ -164,6 +172,8 @@ static void mips_dma_free_coherent(struct device *dev, size_t size, void *vaddr, { unsigned long addr = (unsigned long) vaddr; int order = get_order(size); + unsigned int count = PAGE_ALIGN(size) >> PAGE_SHIFT; + struct page *page = NULL; if (dma_release_from_coherent(dev, order, vaddr)) return; @@ -173,7 +183,10 @@ static void mips_dma_free_coherent(struct device *dev, size_t size, void *vaddr, if (!plat_device_is_coherent(dev) && !hw_coherentio) addr = CAC_ADDR(addr); - free_pages(addr, get_order(size)); + page = virt_to_page((void *) addr); + + if (!dma_release_from_contiguous(dev, page, count)) + __free_pages(page, get_order(size)); } static inline void __dma_sync_virtual(void *addr, size_t size,