Commit ff86aae3 authored by Madalin Bucur's avatar Madalin Bucur Committed by David S. Miller

devres: add devm_alloc_percpu()

Introduce managed counterparts for alloc_percpu() and free_percpu().
Add devm_alloc_percpu() and devm_free_percpu() into the managed
interfaces list.
Signed-off-by: default avatarMadalin Bucur <madalin.bucur@nxp.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 319b0534
...@@ -332,6 +332,10 @@ MEM ...@@ -332,6 +332,10 @@ MEM
MFD MFD
devm_mfd_add_devices() devm_mfd_add_devices()
PER-CPU MEM
devm_alloc_percpu()
devm_free_percpu()
PCI PCI
pcim_enable_device() : after success, all PCI ops become managed pcim_enable_device() : after success, all PCI ops become managed
pcim_pin_device() : keep PCI device enabled after release pcim_pin_device() : keep PCI device enabled after release
......
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#include <linux/device.h> #include <linux/device.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/percpu.h>
#include "base.h" #include "base.h"
...@@ -985,3 +986,68 @@ void devm_free_pages(struct device *dev, unsigned long addr) ...@@ -985,3 +986,68 @@ void devm_free_pages(struct device *dev, unsigned long addr)
&devres)); &devres));
} }
EXPORT_SYMBOL_GPL(devm_free_pages); EXPORT_SYMBOL_GPL(devm_free_pages);
static void devm_percpu_release(struct device *dev, void *pdata)
{
void __percpu *p;
p = *(void __percpu **)pdata;
free_percpu(p);
}
static int devm_percpu_match(struct device *dev, void *data, void *p)
{
struct devres *devr = container_of(data, struct devres, data);
return *(void **)devr->data == p;
}
/**
* __devm_alloc_percpu - Resource-managed alloc_percpu
* @dev: Device to allocate per-cpu memory for
* @size: Size of per-cpu memory to allocate
* @align: Alignment of per-cpu memory to allocate
*
* Managed alloc_percpu. Per-cpu memory allocated with this function is
* automatically freed on driver detach.
*
* RETURNS:
* Pointer to allocated memory on success, NULL on failure.
*/
void __percpu *__devm_alloc_percpu(struct device *dev, size_t size,
size_t align)
{
void *p;
void __percpu *pcpu;
pcpu = __alloc_percpu(size, align);
if (!pcpu)
return NULL;
p = devres_alloc(devm_percpu_release, sizeof(void *), GFP_KERNEL);
if (!p) {
free_percpu(pcpu);
return NULL;
}
*(void __percpu **)p = pcpu;
devres_add(dev, p);
return pcpu;
}
EXPORT_SYMBOL_GPL(__devm_alloc_percpu);
/**
* devm_free_percpu - Resource-managed free_percpu
* @dev: Device this memory belongs to
* @pdata: Per-cpu memory to free
*
* Free memory allocated with devm_alloc_percpu().
*/
void devm_free_percpu(struct device *dev, void __percpu *pdata)
{
WARN_ON(devres_destroy(dev, devm_percpu_release, devm_percpu_match,
(void *)pdata));
}
EXPORT_SYMBOL_GPL(devm_free_percpu);
...@@ -698,6 +698,25 @@ static inline int devm_add_action_or_reset(struct device *dev, ...@@ -698,6 +698,25 @@ static inline int devm_add_action_or_reset(struct device *dev,
return ret; return ret;
} }
/**
* devm_alloc_percpu - Resource-managed alloc_percpu
* @dev: Device to allocate per-cpu memory for
* @type: Type to allocate per-cpu memory for
*
* Managed alloc_percpu. Per-cpu memory allocated with this function is
* automatically freed on driver detach.
*
* RETURNS:
* Pointer to allocated memory on success, NULL on failure.
*/
#define devm_alloc_percpu(dev, type) \
((typeof(type) __percpu *)__devm_alloc_percpu((dev), sizeof(type), \
__alignof__(type)))
void __percpu *__devm_alloc_percpu(struct device *dev, size_t size,
size_t align);
void devm_free_percpu(struct device *dev, void __percpu *pdata);
struct device_dma_parameters { struct device_dma_parameters {
/* /*
* a low level driver may set these to teach IOMMU code about * a low level driver may set these to teach IOMMU code about
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment