diff options
author | Uwe Kleine-König <u.kleine-koenig@pengutronix.de> | 2011-08-25 05:16:00 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2011-08-26 14:31:09 -0400 |
commit | 01dcc60a7cb8cd5193676554b94a90d349bdfd15 (patch) | |
tree | b2081df8c0f1b47fa43076522a1fb42de67f1178 | |
parent | b7565fa3a4b84460ce1765cc468700a6bfd82746 (diff) |
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: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r-- | drivers/base/platform.c | 52 | ||||
-rw-r--r-- | include/linux/platform_device.h | 48 |
2 files changed, 78 insertions, 22 deletions
diff --git a/drivers/base/platform.c b/drivers/base/platform.c index cd7157575e58..4573f5ec9367 100644 --- a/drivers/base/platform.c +++ b/drivers/base/platform.c | |||
@@ -375,52 +375,64 @@ void platform_device_unregister(struct platform_device *pdev) | |||
375 | EXPORT_SYMBOL_GPL(platform_device_unregister); | 375 | EXPORT_SYMBOL_GPL(platform_device_unregister); |
376 | 376 | ||
377 | /** | 377 | /** |
378 | * platform_device_register_resndata - add a platform-level device with | 378 | * platform_device_register_full - add a platform-level device with |
379 | * resources and platform-specific data | 379 | * resources and platform-specific data |
380 | * | 380 | * |
381 | * @parent: parent device for the device we're adding | 381 | * @pdevinfo: data used to create device |
382 | * @name: base name of the device we're adding | ||
383 | * @id: instance id | ||
384 | * @res: set of resources that needs to be allocated for the device | ||
385 | * @num: number of resources | ||
386 | * @data: platform specific data for this platform device | ||
387 | * @size: size of platform specific data | ||
388 | * | 382 | * |
389 | * Returns &struct platform_device pointer on success, or ERR_PTR() on error. | 383 | * Returns &struct platform_device pointer on success, or ERR_PTR() on error. |
390 | */ | 384 | */ |
391 | struct platform_device *platform_device_register_resndata( | 385 | struct platform_device *platform_device_register_full( |
392 | struct device *parent, | 386 | struct platform_device_info *pdevinfo) |
393 | const char *name, int id, | ||
394 | const struct resource *res, unsigned int num, | ||
395 | const void *data, size_t size) | ||
396 | { | 387 | { |
397 | int ret = -ENOMEM; | 388 | int ret = -ENOMEM; |
398 | struct platform_device *pdev; | 389 | struct platform_device *pdev; |
399 | 390 | ||
400 | pdev = platform_device_alloc(name, id); | 391 | pdev = platform_device_alloc(pdevinfo->name, pdevinfo->id); |
401 | if (!pdev) | 392 | if (!pdev) |
402 | goto err; | 393 | goto err_alloc; |
403 | 394 | ||
404 | pdev->dev.parent = parent; | 395 | pdev->dev.parent = pdevinfo->parent; |
396 | |||
397 | if (pdevinfo->dma_mask) { | ||
398 | /* | ||
399 | * This memory isn't freed when the device is put, | ||
400 | * I don't have a nice idea for that though. Conceptually | ||
401 | * dma_mask in struct device should not be a pointer. | ||
402 | * See http://thread.gmane.org/gmane.linux.kernel.pci/9081 | ||
403 | */ | ||
404 | pdev->dev.dma_mask = | ||
405 | kmalloc(sizeof(*pdev->dev.dma_mask), GFP_KERNEL); | ||
406 | if (!pdev->dev.dma_mask) | ||
407 | goto err; | ||
408 | |||
409 | *pdev->dev.dma_mask = pdevinfo->dma_mask; | ||
410 | pdev->dev.coherent_dma_mask = pdevinfo->dma_mask; | ||
411 | } | ||
405 | 412 | ||
406 | ret = platform_device_add_resources(pdev, res, num); | 413 | ret = platform_device_add_resources(pdev, |
414 | pdevinfo->res, pdevinfo->num_res); | ||
407 | if (ret) | 415 | if (ret) |
408 | goto err; | 416 | goto err; |
409 | 417 | ||
410 | ret = platform_device_add_data(pdev, data, size); | 418 | ret = platform_device_add_data(pdev, |
419 | pdevinfo->data, pdevinfo->size_data); | ||
411 | if (ret) | 420 | if (ret) |
412 | goto err; | 421 | goto err; |
413 | 422 | ||
414 | ret = platform_device_add(pdev); | 423 | ret = platform_device_add(pdev); |
415 | if (ret) { | 424 | if (ret) { |
416 | err: | 425 | err: |
426 | kfree(pdev->dev.dma_mask); | ||
427 | |||
428 | err_alloc: | ||
417 | platform_device_put(pdev); | 429 | platform_device_put(pdev); |
418 | return ERR_PTR(ret); | 430 | return ERR_PTR(ret); |
419 | } | 431 | } |
420 | 432 | ||
421 | return pdev; | 433 | return pdev; |
422 | } | 434 | } |
423 | EXPORT_SYMBOL_GPL(platform_device_register_resndata); | 435 | EXPORT_SYMBOL_GPL(platform_device_register_full); |
424 | 436 | ||
425 | static int platform_drv_probe(struct device *_dev) | 437 | static int platform_drv_probe(struct device *_dev) |
426 | { | 438 | { |
diff --git a/include/linux/platform_device.h b/include/linux/platform_device.h index 27bb05aae70d..651a066686ac 100644 --- a/include/linux/platform_device.h +++ b/include/linux/platform_device.h | |||
@@ -49,10 +49,54 @@ extern struct resource *platform_get_resource_byname(struct platform_device *, u | |||
49 | extern int platform_get_irq_byname(struct platform_device *, const char *); | 49 | extern int platform_get_irq_byname(struct platform_device *, const char *); |
50 | extern int platform_add_devices(struct platform_device **, int); | 50 | extern int platform_add_devices(struct platform_device **, int); |
51 | 51 | ||
52 | extern struct platform_device *platform_device_register_resndata( | 52 | struct platform_device_info { |
53 | struct device *parent; | ||
54 | |||
55 | const char *name; | ||
56 | int id; | ||
57 | |||
58 | const struct resource *res; | ||
59 | unsigned int num_res; | ||
60 | |||
61 | const void *data; | ||
62 | size_t size_data; | ||
63 | u64 dma_mask; | ||
64 | }; | ||
65 | extern struct platform_device *platform_device_register_full( | ||
66 | struct platform_device_info *pdevinfo); | ||
67 | |||
68 | /** | ||
69 | * platform_device_register_resndata - add a platform-level device with | ||
70 | * resources and platform-specific data | ||
71 | * | ||
72 | * @parent: parent device for the device we're adding | ||
73 | * @name: base name of the device we're adding | ||
74 | * @id: instance id | ||
75 | * @res: set of resources that needs to be allocated for the device | ||
76 | * @num: number of resources | ||
77 | * @data: platform specific data for this platform device | ||
78 | * @size: size of platform specific data | ||
79 | * | ||
80 | * Returns &struct platform_device pointer on success, or ERR_PTR() on error. | ||
81 | */ | ||
82 | static inline struct platform_device *platform_device_register_resndata( | ||
53 | struct device *parent, const char *name, int id, | 83 | struct device *parent, const char *name, int id, |
54 | const struct resource *res, unsigned int num, | 84 | const struct resource *res, unsigned int num, |
55 | const void *data, size_t size); | 85 | const void *data, size_t size) { |
86 | |||
87 | struct platform_device_info pdevinfo = { | ||
88 | .parent = parent, | ||
89 | .name = name, | ||
90 | .id = id, | ||
91 | .res = res, | ||
92 | .num_res = num, | ||
93 | .data = data, | ||
94 | .size_data = size, | ||
95 | .dma_mask = 0, | ||
96 | }; | ||
97 | |||
98 | return platform_device_register_full(&pdevinfo); | ||
99 | } | ||
56 | 100 | ||
57 | /** | 101 | /** |
58 | * platform_device_register_simple - add a platform-level device and its resources | 102 | * platform_device_register_simple - add a platform-level device and its resources |