提交 01dcc60a 编写于 作者: U Uwe Kleine-König 提交者: Greg Kroah-Hartman

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: NUwe Kleine-König <u.kleine-koenig@pengutronix.de>
Signed-off-by: NGreg Kroah-Hartman <gregkh@suse.de>
上级 b7565fa3
...@@ -375,52 +375,64 @@ void platform_device_unregister(struct platform_device *pdev) ...@@ -375,52 +375,64 @@ void platform_device_unregister(struct platform_device *pdev)
EXPORT_SYMBOL_GPL(platform_device_unregister); 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 * resources and platform-specific data
* *
* @parent: parent device for the device we're adding * @pdevinfo: data used to create device
* @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. * Returns &struct platform_device pointer on success, or ERR_PTR() on error.
*/ */
struct platform_device *platform_device_register_resndata( struct platform_device *platform_device_register_full(
struct device *parent, struct platform_device_info *pdevinfo)
const char *name, int id,
const struct resource *res, unsigned int num,
const void *data, size_t size)
{ {
int ret = -ENOMEM; int ret = -ENOMEM;
struct platform_device *pdev; struct platform_device *pdev;
pdev = platform_device_alloc(name, id); pdev = platform_device_alloc(pdevinfo->name, pdevinfo->id);
if (!pdev) if (!pdev)
goto err; goto err_alloc;
pdev->dev.parent = parent; 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.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) if (ret)
goto err; goto err;
ret = platform_device_add_data(pdev, data, size); ret = platform_device_add_data(pdev,
pdevinfo->data, pdevinfo->size_data);
if (ret) if (ret)
goto err; goto err;
ret = platform_device_add(pdev); ret = platform_device_add(pdev);
if (ret) { if (ret) {
err: err:
kfree(pdev->dev.dma_mask);
err_alloc:
platform_device_put(pdev); platform_device_put(pdev);
return ERR_PTR(ret); return ERR_PTR(ret);
} }
return pdev; return pdev;
} }
EXPORT_SYMBOL_GPL(platform_device_register_resndata); EXPORT_SYMBOL_GPL(platform_device_register_full);
static int platform_drv_probe(struct device *_dev) static int platform_drv_probe(struct device *_dev)
{ {
......
...@@ -49,10 +49,54 @@ extern struct resource *platform_get_resource_byname(struct platform_device *, u ...@@ -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_get_irq_byname(struct platform_device *, const char *);
extern int platform_add_devices(struct platform_device **, int); 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, struct device *parent, const char *name, int id,
const struct resource *res, unsigned int num, 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 * platform_device_register_simple - add a platform-level device and its resources
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册