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

Commit 01dcc60a authored by Uwe Kleine-König's avatar Uwe Kleine-König Committed by Greg Kroah-Hartman
Browse files

new helper to create platform devices with dma mask



compared to the most powerful and already existing helper (namely
platform_device_register_resndata) this allows to specify a dma_mask.
To make eventual extensions later more easy, a struct holding the used
information is created instead of passing the information by function
parameters.

Signed-off-by: default avatarUwe Kleine-König <u.kleine-koenig@pengutronix.de>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent b7565fa3
Loading
Loading
Loading
Loading
+32 −20
Original line number Diff line number Diff line
@@ -375,52 +375,64 @@ void platform_device_unregister(struct platform_device *pdev)
EXPORT_SYMBOL_GPL(platform_device_unregister);

/**
 * platform_device_register_resndata - add a platform-level device with
 * platform_device_register_full - add a platform-level device with
 * resources and platform-specific data
 *
 * @parent: parent device for the device we're adding
 * @name: base name of the device we're adding
 * @id: instance id
 * @res: set of resources that needs to be allocated for the device
 * @num: number of resources
 * @data: platform specific data for this platform device
 * @size: size of platform specific data
 * @pdevinfo: data used to create device
 *
 * Returns &struct platform_device pointer on success, or ERR_PTR() on error.
 */
struct platform_device *platform_device_register_resndata(
		struct device *parent,
		const char *name, int id,
		const struct resource *res, unsigned int num,
		const void *data, size_t size)
struct platform_device *platform_device_register_full(
		struct platform_device_info *pdevinfo)
{
	int ret = -ENOMEM;
	struct platform_device *pdev;

	pdev = platform_device_alloc(name, id);
	pdev = platform_device_alloc(pdevinfo->name, pdevinfo->id);
	if (!pdev)
		goto err_alloc;

	pdev->dev.parent = pdevinfo->parent;

	if (pdevinfo->dma_mask) {
		/*
		 * This memory isn't freed when the device is put,
		 * I don't have a nice idea for that though.  Conceptually
		 * dma_mask in struct device should not be a pointer.
		 * See http://thread.gmane.org/gmane.linux.kernel.pci/9081
		 */
		pdev->dev.dma_mask =
			kmalloc(sizeof(*pdev->dev.dma_mask), GFP_KERNEL);
		if (!pdev->dev.dma_mask)
			goto err;

	pdev->dev.parent = parent;
		*pdev->dev.dma_mask = pdevinfo->dma_mask;
		pdev->dev.coherent_dma_mask = pdevinfo->dma_mask;
	}

	ret = platform_device_add_resources(pdev, res, num);
	ret = platform_device_add_resources(pdev,
			pdevinfo->res, pdevinfo->num_res);
	if (ret)
		goto err;

	ret = platform_device_add_data(pdev, data, size);
	ret = platform_device_add_data(pdev,
			pdevinfo->data, pdevinfo->size_data);
	if (ret)
		goto err;

	ret = platform_device_add(pdev);
	if (ret) {
err:
		kfree(pdev->dev.dma_mask);

err_alloc:
		platform_device_put(pdev);
		return ERR_PTR(ret);
	}

	return pdev;
}
EXPORT_SYMBOL_GPL(platform_device_register_resndata);
EXPORT_SYMBOL_GPL(platform_device_register_full);

static int platform_drv_probe(struct device *_dev)
{
+46 −2
Original line number Diff line number Diff line
@@ -49,10 +49,54 @@ extern struct resource *platform_get_resource_byname(struct platform_device *, u
extern int platform_get_irq_byname(struct platform_device *, const char *);
extern int platform_add_devices(struct platform_device **, int);

extern struct platform_device *platform_device_register_resndata(
struct platform_device_info {
		struct device *parent;

		const char *name;
		int id;

		const struct resource *res;
		unsigned int num_res;

		const void *data;
		size_t size_data;
		u64 dma_mask;
};
extern struct platform_device *platform_device_register_full(
		struct platform_device_info *pdevinfo);

/**
 * platform_device_register_resndata - add a platform-level device with
 * resources and platform-specific data
 *
 * @parent: parent device for the device we're adding
 * @name: base name of the device we're adding
 * @id: instance id
 * @res: set of resources that needs to be allocated for the device
 * @num: number of resources
 * @data: platform specific data for this platform device
 * @size: size of platform specific data
 *
 * Returns &struct platform_device pointer on success, or ERR_PTR() on error.
 */
static inline struct platform_device *platform_device_register_resndata(
		struct device *parent, const char *name, int id,
		const struct resource *res, unsigned int num,
		const void *data, size_t size);
		const void *data, size_t size) {

	struct platform_device_info pdevinfo = {
		.parent = parent,
		.name = name,
		.id = id,
		.res = res,
		.num_res = num,
		.data = data,
		.size_data = size,
		.dma_mask = 0,
	};

	return platform_device_register_full(&pdevinfo);
}

/**
 * platform_device_register_simple - add a platform-level device and its resources