From patchwork Mon Aug 26 14:39:16 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marek Szyprowski X-Patchwork-Id: 19534 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-gh0-f197.google.com (mail-gh0-f197.google.com [209.85.160.197]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id 3E7F32469A for ; Mon, 26 Aug 2013 14:40:00 +0000 (UTC) Received: by mail-gh0-f197.google.com with SMTP id r20sf3531773ghr.0 for ; Mon, 26 Aug 2013 07:40:00 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=x-gm-message-state:delivered-to:from:to:date:message-id:in-reply-to :references:cc:subject:precedence:list-id:list-unsubscribe :list-archive:list-post:list-help:list-subscribe:mime-version :errors-to:sender:x-original-sender :x-original-authentication-results:mailing-list:content-type :content-transfer-encoding; bh=Mc1fNokL0KSPstiWvARQaDVHxOAF48LZC3XukE1RtGc=; b=gmmBCf/l/mHWAk5SlGTlzbuwGya2Owi0YfnAuk5U6RnY/lNfwJgt2LtBVFvMERngNM 3hmStNQQBIOTGQL5irmikS9dAHxcVu3rfM1Cx2in+/umbE4ieW2dlwOD3PyTng8L9ncf YVIjp9mJikUfg9Plu/CaSxa53qmxIbJ3s7+mrDv5cwXV28AyCTAA5Cjjuo6ad3OtKCHq yOfBMcY/sFZPTaIN6COSNlg3VK1Q+iDxAzNw/LMQ8MgBgeqb1C+c0cviqLr1fOU1GBvf j71d/3yFt1OiPDh6HAQRIUmFGZMhR5bLGxZNPW9hu/TU0chfrOLkYVfcuqdf0D4WtdTo RcAg== X-Received: by 10.236.111.73 with SMTP id v49mr5205245yhg.46.1377527999971; Mon, 26 Aug 2013 07:39:59 -0700 (PDT) X-BeenThere: patchwork-forward@linaro.org Received: by 10.49.71.148 with SMTP id v20ls2358490qeu.5.gmail; Mon, 26 Aug 2013 07:39:59 -0700 (PDT) X-Received: by 10.58.198.13 with SMTP id iy13mr15397866vec.11.1377527999869; Mon, 26 Aug 2013 07:39:59 -0700 (PDT) Received: from mail-vb0-f48.google.com (mail-vb0-f48.google.com [209.85.212.48]) by mx.google.com with ESMTPS id sk7si3640288vdc.129.1969.12.31.16.00.00 (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Mon, 26 Aug 2013 07:39:59 -0700 (PDT) Received-SPF: neutral (google.com: 209.85.212.48 is neither permitted nor denied by best guess record for domain of patch+caf_=patchwork-forward=linaro.org@linaro.org) client-ip=209.85.212.48; Received: by mail-vb0-f48.google.com with SMTP id w16so2112263vbf.35 for ; Mon, 26 Aug 2013 07:39:59 -0700 (PDT) X-Gm-Message-State: ALoCoQlmDr1103BZEVuGivnesvNWPVgyF7CX3Nc0CJY6FzuSeYnAV+Qimnn04ZnCzM5nuSVvhbXR X-Received: by 10.52.92.73 with SMTP id ck9mr12840418vdb.2.1377527999741; Mon, 26 Aug 2013 07:39:59 -0700 (PDT) X-Forwarded-To: patchwork-forward@linaro.org X-Forwarded-For: patch@linaro.org patchwork-forward@linaro.org Delivered-To: patches@linaro.org Received: by 10.220.174.196 with SMTP id u4csp238955vcz; Mon, 26 Aug 2013 07:39:58 -0700 (PDT) X-Received: by 10.180.73.103 with SMTP id k7mr7872260wiv.24.1377527998312; Mon, 26 Aug 2013 07:39:58 -0700 (PDT) Received: from ip-10-141-164-156.ec2.internal (lists.linaro.org. [54.225.227.206]) by mx.google.com with ESMTPS id op4si3306684wic.80.1969.12.31.16.00.00 (version=TLSv1 cipher=RC4-SHA bits=128/128); Mon, 26 Aug 2013 07:39:58 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linaro-mm-sig-bounces@lists.linaro.org designates 54.225.227.206 as permitted sender) client-ip=54.225.227.206; Received: from localhost ([127.0.0.1] helo=ip-10-141-164-156.ec2.internal) by ip-10-141-164-156.ec2.internal with esmtp (Exim 4.76) (envelope-from ) id 1VDxwm-0003OW-Cy; Mon, 26 Aug 2013 14:39:12 +0000 Received: from mailout1.samsung.com ([203.254.224.24]) by ip-10-141-164-156.ec2.internal with esmtp (Exim 4.76) (envelope-from ) id 1VDxwj-0003OF-UF for linaro-mm-sig@lists.linaro.org; Mon, 26 Aug 2013 14:39:10 +0000 Received: from epcpsbgm1.samsung.com (epcpsbgm1 [203.254.230.26]) by mailout1.samsung.com (Oracle Communications Messaging Server 7u4-24.01(7.0.4.24.0) 64bit (built Nov 17 2011)) with ESMTP id <0MS5009N07EABQ10@mailout1.samsung.com> for linaro-mm-sig@lists.linaro.org; Mon, 26 Aug 2013 23:39:47 +0900 (KST) X-AuditID: cbfee61a-b7f7a6d00000235f-f6-521b68b2391e Received: from epmmp2 ( [203.254.227.17]) by epcpsbgm1.samsung.com (EPCPMTA) with SMTP id D4.C4.09055.2B86B125; Mon, 26 Aug 2013 23:39:46 +0900 (KST) Received: from localhost.localdomain ([106.116.147.30]) by mmp2.samsung.com (Oracle Communications Messaging Server 7u4-24.01 (7.0.4.24.0) 64bit (built Nov 17 2011)) with ESMTPA id <0MS50074S7DMCL50@mmp2.samsung.com>; Mon, 26 Aug 2013 23:39:46 +0900 (KST) From: Marek Szyprowski To: linux-arm-kernel@lists.infradead.org, linaro-mm-sig@lists.linaro.org, devicetree@vger.kernel.org Date: Mon, 26 Aug 2013 16:39:16 +0200 Message-id: <1377527959-5080-2-git-send-email-m.szyprowski@samsung.com> X-Mailer: git-send-email 1.7.9.5 In-reply-to: <1377527959-5080-1-git-send-email-m.szyprowski@samsung.com> References: <1377527959-5080-1-git-send-email-m.szyprowski@samsung.com> X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFmpjkeLIzCtJLcpLzFFi42I5/e+xoO6mDOkgg1mvjCz+TjrGbjH/yDlW i/43C1ktXp3ZyGbxpreDxeJs0xt2i+2dM9gtvlx5yGSx6fE1Vou1R+6yW2x4eZDJYun1i0wW C463sFr8mS5ncer6ZzaLCdPXslh8//aNzeLv9k0sFofftAONO9jGYrF+xmsWi1W7/jA6iHms mbeG0eP3r0mMHq8nT2D0uNzXy+Sxc9Zddo/NS+o9bv97zOxx5UQTq8e6P6+YPPr/Gnj0bVnF 6PHzpY7H501yHhvnhgbwRXHZpKTmZJalFunbJXBlnJhwkb3gf1JF67avzA2M1wK6GDk5JARM JH5O+s4GYYtJXLi3Hsjm4hASmM4o8Xj3H1YIp51JomXuP1aQKjYBQ4mut11gHSICaRIzVm1g ASliFnjDKrHiUg87SEJYIEHi772TjCA2i4CqxOa3C8FsXgF3idl75wEN4gBapyAxZ5INSJhT wEPizrEZjCBhIaCS1lbNCYy8CxgZVjGKphYkFxQnpeca6hUn5haX5qXrJefnbmIEx84zqR2M KxssDjEKcDAq8fAGFkgFCbEmlhVX5h5ilOBgVhLh5UiVDhLiTUmsrEotyo8vKs1JLT7EKM3B oiTOe6DVOlBIID2xJDU7NbUgtQgmy8TBKdXAaHk15NC71xO3RcSkTtXRNPm6om/xVtttTjIn ZHjiIuZeXxWXGPB/Ue8k/vxDwudqHjH8keW5avlKMmpnpK6djhCPntkp4ctadpMdTi0/eSLs wcKpCZ/DF504sYYnNLU07MTR8w/43TK+XV+1pN5s7uWr2eqXVxU7mOyTmCn5QvqS66XdlwPO LlRiKc5INNRiLipOBABE292FmQIAAA== Cc: Mark Rutland , Pawel Moll , Arnd Bergmann , Stephen Warren , Tomasz Figa , Tomasz Figa , Michal Nazarewicz , Grant Likely , Kyungmin Park , Rob Herring , Sylwester Nawrocki , Kumar Gala , Olof Johansson , Ian Campbell , Sascha Hauer Subject: [Linaro-mm-sig] [PATCH v7 1/4] drivers: dma-contiguous: clean source code and prepare for device tree X-BeenThere: linaro-mm-sig@lists.linaro.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: , List-Help: , List-Subscribe: , MIME-Version: 1.0 Errors-To: linaro-mm-sig-bounces@lists.linaro.org Sender: linaro-mm-sig-bounces@lists.linaro.org X-Removed-Original-Auth: Dkim didn't pass. X-Original-Sender: m.szyprowski@samsung.com X-Original-Authentication-Results: mx.google.com; spf=neutral (google.com: 209.85.212.48 is neither permitted nor denied by best guess record for domain of patch+caf_=patchwork-forward=linaro.org@linaro.org) smtp.mail=patch+caf_=patchwork-forward=linaro.org@linaro.org Mailing-list: list patchwork-forward@linaro.org; contact patchwork-forward+owners@linaro.org X-Google-Group-Id: 836684582541 This patch cleans the initialization of dma contiguous framework. The all-in-one dma_declare_contiguous() function is now separated into dma_contiguous_reserve_area() which only steals the the memory from memblock allocator and dma_contiguous_add_device() function, which assigns given device to the specified reserved memory area. This improves the flexibility in defining contiguous memory areas and assigning device to them, because now it is possible to assign more than one device to the given contiguous memory area. Such split in initialization procedure is also required for upcoming device tree support. Signed-off-by: Marek Szyprowski Acked-by: Kyungmin Park Acked-by: Michal Nazarewicz Acked-by: Tomasz Figa --- arch/arm/include/asm/dma-contiguous.h | 1 - arch/x86/include/asm/dma-contiguous.h | 1 - drivers/base/dma-contiguous.c | 119 ++++++++++++--------------------- include/asm-generic/dma-contiguous.h | 28 -------- include/linux/device.h | 2 +- include/linux/dma-contiguous.h | 62 ++++++++++++++++- 6 files changed, 105 insertions(+), 108 deletions(-) delete mode 100644 include/asm-generic/dma-contiguous.h diff --git a/arch/arm/include/asm/dma-contiguous.h b/arch/arm/include/asm/dma-contiguous.h index e072bb2..4f8e9e5 100644 --- a/arch/arm/include/asm/dma-contiguous.h +++ b/arch/arm/include/asm/dma-contiguous.h @@ -5,7 +5,6 @@ #ifdef CONFIG_DMA_CMA #include -#include void dma_contiguous_early_fixup(phys_addr_t base, unsigned long size); diff --git a/arch/x86/include/asm/dma-contiguous.h b/arch/x86/include/asm/dma-contiguous.h index c092416..b4b38ba 100644 --- a/arch/x86/include/asm/dma-contiguous.h +++ b/arch/x86/include/asm/dma-contiguous.h @@ -4,7 +4,6 @@ #ifdef __KERNEL__ #include -#include static inline void dma_contiguous_early_fixup(phys_addr_t base, unsigned long size) { } diff --git a/drivers/base/dma-contiguous.c b/drivers/base/dma-contiguous.c index 0ca5442..4b94c91 100644 --- a/drivers/base/dma-contiguous.c +++ b/drivers/base/dma-contiguous.c @@ -96,7 +96,7 @@ static inline __maybe_unused phys_addr_t cma_early_percent_memory(void) #endif /** - * dma_contiguous_reserve() - reserve area for contiguous memory handling + * dma_contiguous_reserve() - reserve area(s) for contiguous memory handling * @limit: End address of the reserved memory (optional, 0 for any). * * This function reserves memory from early allocator. It should be @@ -124,22 +124,29 @@ void __init dma_contiguous_reserve(phys_addr_t limit) #endif } - if (selected_size) { + if (selected_size && !dma_contiguous_default_area) { pr_debug("%s: reserving %ld MiB for global area\n", __func__, (unsigned long)selected_size / SZ_1M); - dma_declare_contiguous(NULL, selected_size, 0, limit); + dma_contiguous_reserve_area(selected_size, 0, limit, + &dma_contiguous_default_area); } }; static DEFINE_MUTEX(cma_mutex); -static __init int cma_activate_area(unsigned long base_pfn, unsigned long count) +static __init int cma_activate_area(struct cma *cma) { - unsigned long pfn = base_pfn; - unsigned i = count >> pageblock_order; + int bitmap_size = BITS_TO_LONGS(cma->count) * sizeof(long); + unsigned long base_pfn = cma->base_pfn, pfn = base_pfn; + unsigned i = cma->count >> pageblock_order; struct zone *zone; + cma->bitmap = kzalloc(bitmap_size, GFP_KERNEL); + + if (!cma->bitmap) + return -ENOMEM; + WARN_ON_ONCE(!pfn_valid(pfn)); zone = page_zone(pfn_to_page(pfn)); @@ -153,92 +160,53 @@ static __init int cma_activate_area(unsigned long base_pfn, unsigned long count) } init_cma_reserved_pageblock(pfn_to_page(base_pfn)); } while (--i); - return 0; -} - -static __init struct cma *cma_create_area(unsigned long base_pfn, - unsigned long count) -{ - int bitmap_size = BITS_TO_LONGS(count) * sizeof(long); - struct cma *cma; - int ret = -ENOMEM; - - pr_debug("%s(base %08lx, count %lx)\n", __func__, base_pfn, count); - - cma = kmalloc(sizeof *cma, GFP_KERNEL); - if (!cma) - return ERR_PTR(-ENOMEM); - - cma->base_pfn = base_pfn; - cma->count = count; - cma->bitmap = kzalloc(bitmap_size, GFP_KERNEL); - if (!cma->bitmap) - goto no_mem; - - ret = cma_activate_area(base_pfn, count); - if (ret) - goto error; - - pr_debug("%s: returned %p\n", __func__, (void *)cma); - return cma; - -error: - kfree(cma->bitmap); -no_mem: - kfree(cma); - return ERR_PTR(ret); + return 0; } -static struct cma_reserved { - phys_addr_t start; - unsigned long size; - struct device *dev; -} cma_reserved[MAX_CMA_AREAS] __initdata; -static unsigned cma_reserved_count __initdata; +static struct cma cma_areas[MAX_CMA_AREAS]; +static unsigned cma_area_count; static int __init cma_init_reserved_areas(void) { - struct cma_reserved *r = cma_reserved; - unsigned i = cma_reserved_count; - - pr_debug("%s()\n", __func__); + int i; - for (; i; --i, ++r) { - struct cma *cma; - cma = cma_create_area(PFN_DOWN(r->start), - r->size >> PAGE_SHIFT); - if (!IS_ERR(cma)) - dev_set_cma_area(r->dev, cma); + for (i = 0; i < cma_area_count; i++) { + int ret = cma_activate_area(&cma_areas[i]); + if (ret) + return ret; } + return 0; } core_initcall(cma_init_reserved_areas); /** - * dma_declare_contiguous() - reserve area for contiguous memory handling - * for particular device - * @dev: Pointer to device structure. - * @size: Size of the reserved memory. - * @base: Start address of the reserved memory (optional, 0 for any). + * dma_contiguous_reserve_area() - reserve custom contiguous area + * @size: Size of the reserved area (in bytes), + * @base: Base address of the reserved area optional, use 0 for any * @limit: End address of the reserved memory (optional, 0 for any). + * @res_cma: Pointer to store the created cma region. * - * This function reserves memory for specified device. It should be - * called by board specific code when early allocator (memblock or bootmem) - * is still activate. + * This function reserves memory from early allocator. It should be + * called by arch specific code once the early allocator (memblock or bootmem) + * has been activated and all other subsystems have already allocated/reserved + * memory. This function allows to create custom reserved areas for specific + * devices. */ -int __init dma_declare_contiguous(struct device *dev, phys_addr_t size, - phys_addr_t base, phys_addr_t limit) +int __init dma_contiguous_reserve_area(phys_addr_t size, phys_addr_t base, + phys_addr_t limit, struct cma **res_cma) { - struct cma_reserved *r = &cma_reserved[cma_reserved_count]; + struct cma *cma = &cma_areas[cma_area_count]; phys_addr_t alignment; + int ret = 0; pr_debug("%s(size %lx, base %08lx, limit %08lx)\n", __func__, (unsigned long)size, (unsigned long)base, (unsigned long)limit); /* Sanity checks */ - if (cma_reserved_count == ARRAY_SIZE(cma_reserved)) { + if (cma_area_count == ARRAY_SIZE(cma_areas)) { pr_err("Not enough slots for CMA reserved regions!\n"); return -ENOSPC; } @@ -256,7 +224,7 @@ int __init dma_declare_contiguous(struct device *dev, phys_addr_t size, if (base) { if (memblock_is_region_reserved(base, size) || memblock_reserve(base, size) < 0) { - base = -EBUSY; + ret = -EBUSY; goto err; } } else { @@ -266,7 +234,7 @@ int __init dma_declare_contiguous(struct device *dev, phys_addr_t size, */ phys_addr_t addr = __memblock_alloc_base(size, alignment, limit); if (!addr) { - base = -ENOMEM; + ret = -ENOMEM; goto err; } else { base = addr; @@ -277,10 +245,11 @@ int __init dma_declare_contiguous(struct device *dev, phys_addr_t size, * Each reserved area must be initialised later, when more kernel * subsystems (like slab allocator) are available. */ - r->start = base; - r->size = size; - r->dev = dev; - cma_reserved_count++; + cma->base_pfn = PFN_DOWN(base); + cma->count = size >> PAGE_SHIFT; + *res_cma = cma; + cma_area_count++; + pr_info("CMA: reserved %ld MiB at %08lx\n", (unsigned long)size / SZ_1M, (unsigned long)base); @@ -289,7 +258,7 @@ int __init dma_declare_contiguous(struct device *dev, phys_addr_t size, return 0; err: pr_err("CMA: failed to reserve %ld MiB\n", (unsigned long)size / SZ_1M); - return base; + return ret; } /** diff --git a/include/asm-generic/dma-contiguous.h b/include/asm-generic/dma-contiguous.h deleted file mode 100644 index 294b1e7..0000000 --- a/include/asm-generic/dma-contiguous.h +++ /dev/null @@ -1,28 +0,0 @@ -#ifndef ASM_DMA_CONTIGUOUS_H -#define ASM_DMA_CONTIGUOUS_H - -#ifdef __KERNEL__ -#ifdef CONFIG_CMA - -#include -#include - -static inline struct cma *dev_get_cma_area(struct device *dev) -{ - if (dev && dev->cma_area) - return dev->cma_area; - return dma_contiguous_default_area; -} - -static inline void dev_set_cma_area(struct device *dev, struct cma *cma) -{ - if (dev) - dev->cma_area = cma; - if (!dev && !dma_contiguous_default_area) - dma_contiguous_default_area = cma; -} - -#endif -#endif - -#endif diff --git a/include/linux/device.h b/include/linux/device.h index 22b546a..8b2e2c0 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -727,7 +727,7 @@ struct device { struct dma_coherent_mem *dma_mem; /* internal for coherent mem override */ -#ifdef CONFIG_CMA +#ifdef CONFIG_DMA_CMA struct cma *cma_area; /* contiguous memory area for dma allocations */ #endif diff --git a/include/linux/dma-contiguous.h b/include/linux/dma-contiguous.h index 00141d3..3b28f93 100644 --- a/include/linux/dma-contiguous.h +++ b/include/linux/dma-contiguous.h @@ -67,9 +67,53 @@ struct device; extern struct cma *dma_contiguous_default_area; +static inline struct cma *dev_get_cma_area(struct device *dev) +{ + if (dev && dev->cma_area) + return dev->cma_area; + return dma_contiguous_default_area; +} + +static inline void dev_set_cma_area(struct device *dev, struct cma *cma) +{ + if (dev) + dev->cma_area = cma; +} + +static inline void dma_contiguous_set_default(struct cma *cma) +{ + dma_contiguous_default_area = cma; +} + void dma_contiguous_reserve(phys_addr_t addr_limit); -int dma_declare_contiguous(struct device *dev, phys_addr_t size, - phys_addr_t base, phys_addr_t limit); + +int __init dma_contiguous_reserve_area(phys_addr_t size, phys_addr_t base, + phys_addr_t limit, struct cma **res_cma); + +/** + * dma_declare_contiguous() - reserve area for contiguous memory handling + * for particular device + * @dev: Pointer to device structure. + * @size: Size of the reserved memory. + * @base: Start address of the reserved memory (optional, 0 for any). + * @limit: End address of the reserved memory (optional, 0 for any). + * + * This function reserves memory for specified device. It should be + * called by board specific code when early allocator (memblock or bootmem) + * is still activate. + */ + +static inline int dma_declare_contiguous(struct device *dev, phys_addr_t size, + phys_addr_t base, phys_addr_t limit) +{ + struct cma *cma; + int ret; + ret = dma_contiguous_reserve_area(size, base, limit, &cma); + if (ret == 0) + dev_set_cma_area(dev, cma); + + return ret; +} struct page *dma_alloc_from_contiguous(struct device *dev, int count, unsigned int order); @@ -80,8 +124,22 @@ bool dma_release_from_contiguous(struct device *dev, struct page *pages, #define MAX_CMA_AREAS (0) +static inline struct cma *dev_get_cma_area(struct device *dev) +{ + return NULL; +} + +static inline void dev_set_cma_area(struct device *dev, struct cma *cma) { } + +static inline void dma_contiguous_set_default(struct cma *cma) { } + static inline void dma_contiguous_reserve(phys_addr_t limit) { } +static inline int dma_contiguous_reserve_area(phys_addr_t size, phys_addr_t base, + phys_addr_t limit, struct cma **res_cma) { + return -ENOSYS; +} + static inline int dma_declare_contiguous(struct device *dev, phys_addr_t size, phys_addr_t base, phys_addr_t limit)