Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+4 −0
Original line number Original line Diff line number Diff line
@@ -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
+66 −0
Original line number Original line Diff line number Diff line
@@ -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)
			       &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);
+19 −0
Original line number Original line Diff line number Diff line
@@ -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