aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/base/platform.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2010-08-06 14:36:30 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2010-08-06 14:36:30 -0400
commitab69bcd66fb4be64edfc767365cb9eb084961246 (patch)
treef7623585aee58978fc7814460fff517ec39138f2 /drivers/base/platform.c
parentc513b67e68787eceafeede32bcd0edbee45c0006 (diff)
parent6937e8f8c0135f2325194c372ada6dc655499992 (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core-2.6: (28 commits) driver core: device_rename's new_name can be const sysfs: Remove owner field from sysfs struct attribute powerpc/pci: Remove owner field from attribute initialization in PCI bridge init regulator: Remove owner field from attribute initialization in regulator core driver leds: Remove owner field from attribute initialization in bd2802 driver scsi: Remove owner field from attribute initialization in ARCMSR driver scsi: Remove owner field from attribute initialization in LPFC driver cgroupfs: create /sys/fs/cgroup to mount cgroupfs on Driver core: Add BUS_NOTIFY_BIND_DRIVER driver core: fix memory leak on one error path in bus_register() debugfs: no longer needs to depend on SYSFS sysfs: Fix one more signature discrepancy between sysfs implementation and docs. sysfs: fix discrepancies between implementation and documentation dcdbas: remove a redundant smi_data_buf_free in dcdbas_exit dmi-id: fix a memory leak in dmi_id_init error path sysfs: sysfs_chmod_file's attr can be const firmware: Update hotplug script Driver core: move platform device creation helpers to .init.text (if MODULE=n) Driver core: reduce duplicated code for platform_device creation Driver core: use kmemdup in platform_device_add_resources ...
Diffstat (limited to 'drivers/base/platform.c')
-rw-r--r--drivers/base/platform.c110
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}
203EXPORT_SYMBOL_GPL(platform_device_add_resources); 203EXPORT_SYMBOL_GPL(platform_device_add_resources);
204 204
@@ -345,108 +345,56 @@ void platform_device_unregister(struct platform_device *pdev)
345EXPORT_SYMBOL_GPL(platform_device_unregister); 345EXPORT_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 */
369struct 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
395error:
396 platform_device_put(pdev);
397 return ERR_PTR(retval);
398}
399EXPORT_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 */
417struct platform_device *platform_device_register_data( 361struct 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) {
390err:
391 platform_device_put(pdev);
392 return ERR_PTR(ret);
393 }
444 394
445error: 395 return pdev;
446 platform_device_put(pdev);
447 return ERR_PTR(retval);
448} 396}
449EXPORT_SYMBOL_GPL(platform_device_register_data); 397EXPORT_SYMBOL_GPL(platform_device_register_resndata);
450 398
451static int platform_drv_probe(struct device *_dev) 399static int platform_drv_probe(struct device *_dev)
452{ 400{