aboutsummaryrefslogtreecommitdiffstats
path: root/lib/genalloc.c
diff options
context:
space:
mode:
authorPhilipp Zabel <p.zabel@pengutronix.de>2013-04-29 19:17:10 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2013-04-29 21:28:13 -0400
commit9375db07adeaeea5f5ea7ca0463a8b371d71ddbb (patch)
tree8825d1985a7bd6acd9e13de4594c574c81dd11fe /lib/genalloc.c
parent3119b487e03650b51589a86aac33098b7cc2a09e (diff)
genalloc: add devres support, allow to find a managed pool by device
This patch adds three exported functions to lib/genalloc.c: devm_gen_pool_create, dev_get_gen_pool, and of_get_named_gen_pool. devm_gen_pool_create is a managed version of gen_pool_create that keeps track of the pool via devres and allows the management code to automatically destroy it after device removal. dev_get_gen_pool retrieves the gen_pool for a given device, if it was created with devm_gen_pool_create, using devres_find. of_get_named_gen_pool retrieves the gen_pool for a given device node and property name, where the property must contain a phandle pointing to a platform device node. The corresponding platform device is then fed into dev_get_gen_pool and the resulting gen_pool is returned. [akpm@linux-foundation.org: make the of_get_named_gen_pool() stub static, fixing a zillion link errors] [akpm@linux-foundation.org: squish "struct device declared inside parameter list" warning] Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de> Acked-by: Grant Likely <grant.likely@secretlab.ca> Tested-by: Michal Simek <monstr@monstr.eu> Cc: Fabio Estevam <fabio.estevam@freescale.com> Cc: Matt Porter <mporter@ti.com> Cc: Dong Aisheng <dong.aisheng@linaro.org> Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Cc: Rob Herring <rob.herring@calxeda.com> Cc: Paul Gortmaker <paul.gortmaker@windriver.com> Cc: Javier Martin <javier.martin@vista-silicon.com> Cc: Huang Shijie <shijie8@gmail.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'lib/genalloc.c')
-rw-r--r--lib/genalloc.c81
1 files changed, 81 insertions, 0 deletions
diff --git a/lib/genalloc.c b/lib/genalloc.c
index 54920433705a..b35cfa9bc3d4 100644
--- a/lib/genalloc.c
+++ b/lib/genalloc.c
@@ -34,6 +34,8 @@
34#include <linux/rculist.h> 34#include <linux/rculist.h>
35#include <linux/interrupt.h> 35#include <linux/interrupt.h>
36#include <linux/genalloc.h> 36#include <linux/genalloc.h>
37#include <linux/of_address.h>
38#include <linux/of_device.h>
37 39
38static int set_bits_ll(unsigned long *addr, unsigned long mask_to_set) 40static int set_bits_ll(unsigned long *addr, unsigned long mask_to_set)
39{ 41{
@@ -480,3 +482,82 @@ unsigned long gen_pool_best_fit(unsigned long *map, unsigned long size,
480 return start_bit; 482 return start_bit;
481} 483}
482EXPORT_SYMBOL(gen_pool_best_fit); 484EXPORT_SYMBOL(gen_pool_best_fit);
485
486static void devm_gen_pool_release(struct device *dev, void *res)
487{
488 gen_pool_destroy(*(struct gen_pool **)res);
489}
490
491/**
492 * devm_gen_pool_create - managed gen_pool_create
493 * @dev: device that provides the gen_pool
494 * @min_alloc_order: log base 2 of number of bytes each bitmap bit represents
495 * @nid: node id of the node the pool structure should be allocated on, or -1
496 *
497 * Create a new special memory pool that can be used to manage special purpose
498 * memory not managed by the regular kmalloc/kfree interface. The pool will be
499 * automatically destroyed by the device management code.
500 */
501struct gen_pool *devm_gen_pool_create(struct device *dev, int min_alloc_order,
502 int nid)
503{
504 struct gen_pool **ptr, *pool;
505
506 ptr = devres_alloc(devm_gen_pool_release, sizeof(*ptr), GFP_KERNEL);
507
508 pool = gen_pool_create(min_alloc_order, nid);
509 if (pool) {
510 *ptr = pool;
511 devres_add(dev, ptr);
512 } else {
513 devres_free(ptr);
514 }
515
516 return pool;
517}
518
519/**
520 * dev_get_gen_pool - Obtain the gen_pool (if any) for a device
521 * @dev: device to retrieve the gen_pool from
522 * @name: Optional name for the gen_pool, usually NULL
523 *
524 * Returns the gen_pool for the device if one is present, or NULL.
525 */
526struct gen_pool *dev_get_gen_pool(struct device *dev)
527{
528 struct gen_pool **p = devres_find(dev, devm_gen_pool_release, NULL,
529 NULL);
530
531 if (!p)
532 return NULL;
533 return *p;
534}
535EXPORT_SYMBOL_GPL(dev_get_gen_pool);
536
537#ifdef CONFIG_OF
538/**
539 * of_get_named_gen_pool - find a pool by phandle property
540 * @np: device node
541 * @propname: property name containing phandle(s)
542 * @index: index into the phandle array
543 *
544 * Returns the pool that contains the chunk starting at the physical
545 * address of the device tree node pointed at by the phandle property,
546 * or NULL if not found.
547 */
548struct gen_pool *of_get_named_gen_pool(struct device_node *np,
549 const char *propname, int index)
550{
551 struct platform_device *pdev;
552 struct device_node *np_pool;
553
554 np_pool = of_parse_phandle(np, propname, index);
555 if (!np_pool)
556 return NULL;
557 pdev = of_find_device_by_node(np_pool);
558 if (!pdev)
559 return NULL;
560 return dev_get_gen_pool(&pdev->dev);
561}
562EXPORT_SYMBOL_GPL(of_get_named_gen_pool);
563#endif /* CONFIG_OF */