Skip to content

Commit 9375db0

Browse files
pH5torvalds
authored andcommitted
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>
1 parent 3119b48 commit 9375db0

File tree

2 files changed

+99
-0
lines changed

2 files changed

+99
-0
lines changed

include/linux/genalloc.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,10 @@
2929

3030
#ifndef __GENALLOC_H__
3131
#define __GENALLOC_H__
32+
33+
struct device;
34+
struct device_node;
35+
3236
/**
3337
* Allocation callback function type definition
3438
* @map: Pointer to bitmap
@@ -105,4 +109,18 @@ extern unsigned long gen_pool_first_fit(unsigned long *map, unsigned long size,
105109
extern unsigned long gen_pool_best_fit(unsigned long *map, unsigned long size,
106110
unsigned long start, unsigned int nr, void *data);
107111

112+
extern struct gen_pool *devm_gen_pool_create(struct device *dev,
113+
int min_alloc_order, int nid);
114+
extern struct gen_pool *dev_get_gen_pool(struct device *dev);
115+
116+
#ifdef CONFIG_OF
117+
extern struct gen_pool *of_get_named_gen_pool(struct device_node *np,
118+
const char *propname, int index);
119+
#else
120+
static inline struct gen_pool *of_get_named_gen_pool(struct device_node *np,
121+
const char *propname, int index)
122+
{
123+
return NULL;
124+
}
125+
#endif
108126
#endif /* __GENALLOC_H__ */

lib/genalloc.c

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@
3434
#include <linux/rculist.h>
3535
#include <linux/interrupt.h>
3636
#include <linux/genalloc.h>
37+
#include <linux/of_address.h>
38+
#include <linux/of_device.h>
3739

3840
static int set_bits_ll(unsigned long *addr, unsigned long mask_to_set)
3941
{
@@ -480,3 +482,82 @@ unsigned long gen_pool_best_fit(unsigned long *map, unsigned long size,
480482
return start_bit;
481483
}
482484
EXPORT_SYMBOL(gen_pool_best_fit);
485+
486+
static 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+
*/
501+
struct 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+
*/
526+
struct 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+
}
535+
EXPORT_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+
*/
548+
struct 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+
}
562+
EXPORT_SYMBOL_GPL(of_get_named_gen_pool);
563+
#endif /* CONFIG_OF */

0 commit comments

Comments
 (0)