aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/base/platform.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/base/platform.c')
-rw-r--r--drivers/base/platform.c54
1 files changed, 33 insertions, 21 deletions
diff --git a/drivers/base/platform.c b/drivers/base/platform.c
index 99a5272d7c2f..7a24895543e7 100644
--- a/drivers/base/platform.c
+++ b/drivers/base/platform.c
@@ -375,52 +375,64 @@ void platform_device_unregister(struct platform_device *pdev)
375EXPORT_SYMBOL_GPL(platform_device_unregister); 375EXPORT_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 */
391struct platform_device *platform_device_register_resndata( 385struct 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) {
416err: 425err:
426 kfree(pdev->dev.dma_mask);
427
428err_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}
423EXPORT_SYMBOL_GPL(platform_device_register_resndata); 435EXPORT_SYMBOL_GPL(platform_device_register_full);
424 436
425static int platform_drv_probe(struct device *_dev) 437static int platform_drv_probe(struct device *_dev)
426{ 438{
@@ -614,7 +626,7 @@ static int platform_uevent(struct device *dev, struct kobj_uevent_env *env)
614 return rc; 626 return rc;
615 627
616 add_uevent_var(env, "MODALIAS=%s%s", PLATFORM_MODULE_PREFIX, 628 add_uevent_var(env, "MODALIAS=%s%s", PLATFORM_MODULE_PREFIX,
617 (pdev->id_entry) ? pdev->id_entry->name : pdev->name); 629 pdev->name);
618 return 0; 630 return 0;
619} 631}
620 632