Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753140AbbFDL4F (ORCPT ); Thu, 4 Jun 2015 07:56:05 -0400 Received: from relay1.mentorg.com ([192.94.38.131]:49699 "EHLO relay1.mentorg.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752081AbbFDL4B (ORCPT ); Thu, 4 Jun 2015 07:56:01 -0400 From: Vladimir Zapolskiy To: Andrew Morton , Philipp Zabel CC: Olof Johansson , Catalin Marinas , Will Deacon , Subject: [PATCH] genalloc: add support of multiple gen_pools per device Date: Thu, 4 Jun 2015 14:55:52 +0300 Message-ID: <1433418952-31749-1-git-send-email-vladimir_zapolskiy@mentor.com> X-Mailer: git-send-email 2.1.4 MIME-Version: 1.0 Content-Type: text/plain X-Originating-IP: [137.202.0.76] Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 5468 Lines: 165 This change adds two more exported interfaces to genalloc: * devm_gen_pool_create_named() -- same as devm_gen_pool_create(), but the created gen_pool object can be referenced by a given name, * dev_get_gen_pool_named() -- same as dev_get_gen_pool(), but allows to get a previously registered particular gen_pool instance by name Also the change extends the logic of of_get_named_gen_pool(), if there is no associated platform device with a given device node, it attempts to get a label property or device node name (= repeats MTD OF partition standard) and seeks for a named gen_pool registered by parent device node device. The main idea of the change is to allow registration of independent gen_pools under the same umbrella device, say "partitions" on "storage device", the original functionality of one "partition" per "storage device" is untouched. Signed-off-by: Vladimir Zapolskiy --- include/linux/genalloc.h | 6 ++++ lib/genalloc.c | 74 ++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 78 insertions(+), 2 deletions(-) diff --git a/include/linux/genalloc.h b/include/linux/genalloc.h index 1ccaab4..213645f 100644 --- a/include/linux/genalloc.h +++ b/include/linux/genalloc.h @@ -59,6 +59,8 @@ struct gen_pool { genpool_algo_t algo; /* allocation function */ void *data; + + const char *name; }; /* @@ -117,8 +119,12 @@ extern unsigned long gen_pool_first_fit_order_align(unsigned long *map, extern unsigned long gen_pool_best_fit(unsigned long *map, unsigned long size, unsigned long start, unsigned int nr, void *data); +extern struct gen_pool *devm_gen_pool_create_named(struct device *dev, + int min_alloc_order, int nid, const char *name); extern struct gen_pool *devm_gen_pool_create(struct device *dev, int min_alloc_order, int nid); +extern struct gen_pool *dev_get_gen_pool_named(struct device *dev, + const char *name); extern struct gen_pool *dev_get_gen_pool(struct device *dev); bool addr_in_gen_pool(struct gen_pool *pool, unsigned long start, diff --git a/lib/genalloc.c b/lib/genalloc.c index d214866..3300071 100644 --- a/lib/genalloc.c +++ b/lib/genalloc.c @@ -602,6 +602,30 @@ struct gen_pool *devm_gen_pool_create(struct device *dev, int min_alloc_order, EXPORT_SYMBOL(devm_gen_pool_create); /** + * devm_gen_pool_create_named - managed gen_pool_create + * @dev: device that provides the gen_pool + * @min_alloc_order: log base 2 of number of bytes each bitmap bit represents + * @nid: node id of the node the pool structure should be allocated on, or -1 + * @name: name of a gen_pool within all gen_pool associated with the device + * + * Create a new special memory pool that can be used to manage special purpose + * memory not managed by the regular kmalloc/kfree interface. The pool will be + * automatically destroyed by the device management code. + */ +struct gen_pool *devm_gen_pool_create_named(struct device *dev, + int min_alloc_order, int nid, const char *name) +{ + struct gen_pool *pool; + + pool = devm_gen_pool_create(dev, min_alloc_order, nid); + if (pool) + pool->name = name; + + return pool; +} +EXPORT_SYMBOL(devm_gen_pool_create_named); + +/** * dev_get_gen_pool - Obtain the gen_pool (if any) for a device * @dev: device to retrieve the gen_pool from * @@ -618,6 +642,38 @@ struct gen_pool *dev_get_gen_pool(struct device *dev) } EXPORT_SYMBOL_GPL(dev_get_gen_pool); +static int dev_gen_pool_match(struct device *dev, void *res, void *data) +{ + struct gen_pool **p = res; + + /* Always get a match, if no data supplied */ + if (!data) + return 1; + + if (!(*p)->name) + return 0; + + return !strcmp((*p)->name, data); +} + +/** + * dev_get_gen_pool_named - Obtain the gen_pool (if any) for a device + * @dev: device to retrieve the gen_pool from + * @name: name of a gen_pool, addresses a particular gen_pool from device + * + * Returns the gen_pool for the device if one is present, or NULL. + */ +struct gen_pool *dev_get_gen_pool_named(struct device *dev, const char *name) +{ + struct gen_pool **p = devres_find(dev, devm_gen_pool_release, + dev_gen_pool_match, (void *)name); + + if (!p) + return NULL; + return *p; +} +EXPORT_SYMBOL_GPL(dev_get_gen_pool_named); + #ifdef CONFIG_OF /** * of_get_named_gen_pool - find a pool by phandle property @@ -633,16 +689,30 @@ struct gen_pool *of_get_named_gen_pool(struct device_node *np, const char *propname, int index) { struct platform_device *pdev; - struct device_node *np_pool; + struct device_node *np_pool, *parent; + const char *name = NULL; np_pool = of_parse_phandle(np, propname, index); if (!np_pool) return NULL; + pdev = of_find_device_by_node(np_pool); + if (!pdev) { + /* Check if named gen_pool is created by parent node device */ + parent = of_get_parent(np_pool); + pdev = of_find_device_by_node(parent); + of_node_put(parent); + + of_property_read_string(np_pool, "label", &name); + if (!name) + name = np_pool->name; + } of_node_put(np_pool); + if (!pdev) return NULL; - return dev_get_gen_pool(&pdev->dev); + + return dev_get_gen_pool_named(&pdev->dev, name); } EXPORT_SYMBOL_GPL(of_get_named_gen_pool); #endif /* CONFIG_OF */ -- 2.1.4 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/