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 | { |
