diff options
Diffstat (limited to 'drivers/base/platform.c')
-rw-r--r-- | drivers/base/platform.c | 110 |
1 files changed, 29 insertions, 81 deletions
diff --git a/drivers/base/platform.c b/drivers/base/platform.c index f699fabf403b..c6c933f58102 100644 --- a/drivers/base/platform.c +++ b/drivers/base/platform.c | |||
@@ -192,13 +192,13 @@ int platform_device_add_resources(struct platform_device *pdev, | |||
192 | { | 192 | { |
193 | struct resource *r; | 193 | struct resource *r; |
194 | 194 | ||
195 | r = kmalloc(sizeof(struct resource) * num, GFP_KERNEL); | 195 | r = kmemdup(res, sizeof(struct resource) * num, GFP_KERNEL); |
196 | if (r) { | 196 | if (r) { |
197 | memcpy(r, res, sizeof(struct resource) * num); | ||
198 | pdev->resource = r; | 197 | pdev->resource = r; |
199 | pdev->num_resources = num; | 198 | pdev->num_resources = num; |
199 | return 0; | ||
200 | } | 200 | } |
201 | return r ? 0 : -ENOMEM; | 201 | return -ENOMEM; |
202 | } | 202 | } |
203 | EXPORT_SYMBOL_GPL(platform_device_add_resources); | 203 | EXPORT_SYMBOL_GPL(platform_device_add_resources); |
204 | 204 | ||
@@ -345,108 +345,56 @@ void platform_device_unregister(struct platform_device *pdev) | |||
345 | EXPORT_SYMBOL_GPL(platform_device_unregister); | 345 | EXPORT_SYMBOL_GPL(platform_device_unregister); |
346 | 346 | ||
347 | /** | 347 | /** |
348 | * platform_device_register_simple - add a platform-level device and its resources | 348 | * platform_device_register_resndata - add a platform-level device with |
349 | * @name: base name of the device we're adding | 349 | * resources and platform-specific data |
350 | * @id: instance id | ||
351 | * @res: set of resources that needs to be allocated for the device | ||
352 | * @num: number of resources | ||
353 | * | ||
354 | * This function creates a simple platform device that requires minimal | ||
355 | * resource and memory management. Canned release function freeing memory | ||
356 | * allocated for the device allows drivers using such devices to be | ||
357 | * unloaded without waiting for the last reference to the device to be | ||
358 | * dropped. | ||
359 | * | ||
360 | * This interface is primarily intended for use with legacy drivers which | ||
361 | * probe hardware directly. Because such drivers create sysfs device nodes | ||
362 | * themselves, rather than letting system infrastructure handle such device | ||
363 | * enumeration tasks, they don't fully conform to the Linux driver model. | ||
364 | * In particular, when such drivers are built as modules, they can't be | ||
365 | * "hotplugged". | ||
366 | * | 350 | * |
367 | * Returns &struct platform_device pointer on success, or ERR_PTR() on error. | ||
368 | */ | ||
369 | struct platform_device *platform_device_register_simple(const char *name, | ||
370 | int id, | ||
371 | const struct resource *res, | ||
372 | unsigned int num) | ||
373 | { | ||
374 | struct platform_device *pdev; | ||
375 | int retval; | ||
376 | |||
377 | pdev = platform_device_alloc(name, id); | ||
378 | if (!pdev) { | ||
379 | retval = -ENOMEM; | ||
380 | goto error; | ||
381 | } | ||
382 | |||
383 | if (num) { | ||
384 | retval = platform_device_add_resources(pdev, res, num); | ||
385 | if (retval) | ||
386 | goto error; | ||
387 | } | ||
388 | |||
389 | retval = platform_device_add(pdev); | ||
390 | if (retval) | ||
391 | goto error; | ||
392 | |||
393 | return pdev; | ||
394 | |||
395 | error: | ||
396 | platform_device_put(pdev); | ||
397 | return ERR_PTR(retval); | ||
398 | } | ||
399 | EXPORT_SYMBOL_GPL(platform_device_register_simple); | ||
400 | |||
401 | /** | ||
402 | * platform_device_register_data - add a platform-level device with platform-specific data | ||
403 | * @parent: parent device for the device we're adding | 351 | * @parent: parent device for the device we're adding |
404 | * @name: base name of the device we're adding | 352 | * @name: base name of the device we're adding |
405 | * @id: instance id | 353 | * @id: instance id |
354 | * @res: set of resources that needs to be allocated for the device | ||
355 | * @num: number of resources | ||
406 | * @data: platform specific data for this platform device | 356 | * @data: platform specific data for this platform device |
407 | * @size: size of platform specific data | 357 | * @size: size of platform specific data |
408 | * | 358 | * |
409 | * This function creates a simple platform device that requires minimal | ||
410 | * resource and memory management. Canned release function freeing memory | ||
411 | * allocated for the device allows drivers using such devices to be | ||
412 | * unloaded without waiting for the last reference to the device to be | ||
413 | * dropped. | ||
414 | * | ||
415 | * Returns &struct platform_device pointer on success, or ERR_PTR() on error. | 359 | * Returns &struct platform_device pointer on success, or ERR_PTR() on error. |
416 | */ | 360 | */ |
417 | struct platform_device *platform_device_register_data( | 361 | struct platform_device *__init_or_module platform_device_register_resndata( |
418 | struct device *parent, | 362 | struct device *parent, |
419 | const char *name, int id, | 363 | const char *name, int id, |
364 | const struct resource *res, unsigned int num, | ||
420 | const void *data, size_t size) | 365 | const void *data, size_t size) |
421 | { | 366 | { |
367 | int ret = -ENOMEM; | ||
422 | struct platform_device *pdev; | 368 | struct platform_device *pdev; |
423 | int retval; | ||
424 | 369 | ||
425 | pdev = platform_device_alloc(name, id); | 370 | pdev = platform_device_alloc(name, id); |
426 | if (!pdev) { | 371 | if (!pdev) |
427 | retval = -ENOMEM; | 372 | goto err; |
428 | goto error; | ||
429 | } | ||
430 | 373 | ||
431 | pdev->dev.parent = parent; | 374 | pdev->dev.parent = parent; |
432 | 375 | ||
433 | if (size) { | 376 | if (res) { |
434 | retval = platform_device_add_data(pdev, data, size); | 377 | ret = platform_device_add_resources(pdev, res, num); |
435 | if (retval) | 378 | if (ret) |
436 | goto error; | 379 | goto err; |
437 | } | 380 | } |
438 | 381 | ||
439 | retval = platform_device_add(pdev); | 382 | if (data) { |
440 | if (retval) | 383 | ret = platform_device_add_data(pdev, data, size); |
441 | goto error; | 384 | if (ret) |
385 | goto err; | ||
386 | } | ||
442 | 387 | ||
443 | return pdev; | 388 | ret = platform_device_add(pdev); |
389 | if (ret) { | ||
390 | err: | ||
391 | platform_device_put(pdev); | ||
392 | return ERR_PTR(ret); | ||
393 | } | ||
444 | 394 | ||
445 | error: | 395 | return pdev; |
446 | platform_device_put(pdev); | ||
447 | return ERR_PTR(retval); | ||
448 | } | 396 | } |
449 | EXPORT_SYMBOL_GPL(platform_device_register_data); | 397 | EXPORT_SYMBOL_GPL(platform_device_register_resndata); |
450 | 398 | ||
451 | static int platform_drv_probe(struct device *_dev) | 399 | static int platform_drv_probe(struct device *_dev) |
452 | { | 400 | { |