aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/base/platform.c
diff options
context:
space:
mode:
authorLen Brown <len.brown@intel.com>2010-08-15 01:06:31 -0400
committerLen Brown <len.brown@intel.com>2010-08-15 01:06:31 -0400
commit95ee46aa8698f2000647dfb362400fadbb5807cf (patch)
treee5a05c7297f997e191c73091934e42e3195c0e40 /drivers/base/platform.c
parentcfa806f059801dbe7e435745eb2e187c8bfe1e7f (diff)
parent92fa5bd9a946b6e7aab6764e7312e4e3d9bed295 (diff)
Merge branch 'linus' into release
Conflicts: drivers/acpi/debug.c Signed-off-by: Len Brown <len.brown@intel.com>
Diffstat (limited to 'drivers/base/platform.c')
-rw-r--r--drivers/base/platform.c123
1 files changed, 41 insertions, 82 deletions
diff --git a/drivers/base/platform.c b/drivers/base/platform.c
index 4d99c8bdfedc..c6c933f58102 100644
--- a/drivers/base/platform.c
+++ b/drivers/base/platform.c
@@ -12,6 +12,7 @@
12 12
13#include <linux/string.h> 13#include <linux/string.h>
14#include <linux/platform_device.h> 14#include <linux/platform_device.h>
15#include <linux/of_device.h>
15#include <linux/module.h> 16#include <linux/module.h>
16#include <linux/init.h> 17#include <linux/init.h>
17#include <linux/dma-mapping.h> 18#include <linux/dma-mapping.h>
@@ -191,13 +192,13 @@ int platform_device_add_resources(struct platform_device *pdev,
191{ 192{
192 struct resource *r; 193 struct resource *r;
193 194
194 r = kmalloc(sizeof(struct resource) * num, GFP_KERNEL); 195 r = kmemdup(res, sizeof(struct resource) * num, GFP_KERNEL);
195 if (r) { 196 if (r) {
196 memcpy(r, res, sizeof(struct resource) * num);
197 pdev->resource = r; 197 pdev->resource = r;
198 pdev->num_resources = num; 198 pdev->num_resources = num;
199 return 0;
199 } 200 }
200 return r ? 0 : -ENOMEM; 201 return -ENOMEM;
201} 202}
202EXPORT_SYMBOL_GPL(platform_device_add_resources); 203EXPORT_SYMBOL_GPL(platform_device_add_resources);
203 204
@@ -344,108 +345,56 @@ void platform_device_unregister(struct platform_device *pdev)
344EXPORT_SYMBOL_GPL(platform_device_unregister); 345EXPORT_SYMBOL_GPL(platform_device_unregister);
345 346
346/** 347/**
347 * platform_device_register_simple - add a platform-level device and its resources 348 * platform_device_register_resndata - add a platform-level device with
348 * @name: base name of the device we're adding 349 * resources and platform-specific data
349 * @id: instance id
350 * @res: set of resources that needs to be allocated for the device
351 * @num: number of resources
352 * 350 *
353 * This function creates a simple platform device that requires minimal
354 * resource and memory management. Canned release function freeing memory
355 * allocated for the device allows drivers using such devices to be
356 * unloaded without waiting for the last reference to the device to be
357 * dropped.
358 *
359 * This interface is primarily intended for use with legacy drivers which
360 * probe hardware directly. Because such drivers create sysfs device nodes
361 * themselves, rather than letting system infrastructure handle such device
362 * enumeration tasks, they don't fully conform to the Linux driver model.
363 * In particular, when such drivers are built as modules, they can't be
364 * "hotplugged".
365 *
366 * Returns &struct platform_device pointer on success, or ERR_PTR() on error.
367 */
368struct platform_device *platform_device_register_simple(const char *name,
369 int id,
370 const struct resource *res,
371 unsigned int num)
372{
373 struct platform_device *pdev;
374 int retval;
375
376 pdev = platform_device_alloc(name, id);
377 if (!pdev) {
378 retval = -ENOMEM;
379 goto error;
380 }
381
382 if (num) {
383 retval = platform_device_add_resources(pdev, res, num);
384 if (retval)
385 goto error;
386 }
387
388 retval = platform_device_add(pdev);
389 if (retval)
390 goto error;
391
392 return pdev;
393
394error:
395 platform_device_put(pdev);
396 return ERR_PTR(retval);
397}
398EXPORT_SYMBOL_GPL(platform_device_register_simple);
399
400/**
401 * platform_device_register_data - add a platform-level device with platform-specific data
402 * @parent: parent device for the device we're adding 351 * @parent: parent device for the device we're adding
403 * @name: base name of the device we're adding 352 * @name: base name of the device we're adding
404 * @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
405 * @data: platform specific data for this platform device 356 * @data: platform specific data for this platform device
406 * @size: size of platform specific data 357 * @size: size of platform specific data
407 * 358 *
408 * This function creates a simple platform device that requires minimal
409 * resource and memory management. Canned release function freeing memory
410 * allocated for the device allows drivers using such devices to be
411 * unloaded without waiting for the last reference to the device to be
412 * dropped.
413 *
414 * 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.
415 */ 360 */
416struct platform_device *platform_device_register_data( 361struct platform_device *__init_or_module platform_device_register_resndata(
417 struct device *parent, 362 struct device *parent,
418 const char *name, int id, 363 const char *name, int id,
364 const struct resource *res, unsigned int num,
419 const void *data, size_t size) 365 const void *data, size_t size)
420{ 366{
367 int ret = -ENOMEM;
421 struct platform_device *pdev; 368 struct platform_device *pdev;
422 int retval;
423 369
424 pdev = platform_device_alloc(name, id); 370 pdev = platform_device_alloc(name, id);
425 if (!pdev) { 371 if (!pdev)
426 retval = -ENOMEM; 372 goto err;
427 goto error;
428 }
429 373
430 pdev->dev.parent = parent; 374 pdev->dev.parent = parent;
431 375
432 if (size) { 376 if (res) {
433 retval = platform_device_add_data(pdev, data, size); 377 ret = platform_device_add_resources(pdev, res, num);
434 if (retval) 378 if (ret)
435 goto error; 379 goto err;
436 } 380 }
437 381
438 retval = platform_device_add(pdev); 382 if (data) {
439 if (retval) 383 ret = platform_device_add_data(pdev, data, size);
440 goto error; 384 if (ret)
385 goto err;
386 }
441 387
442 return pdev; 388 ret = platform_device_add(pdev);
389 if (ret) {
390err:
391 platform_device_put(pdev);
392 return ERR_PTR(ret);
393 }
443 394
444error: 395 return pdev;
445 platform_device_put(pdev);
446 return ERR_PTR(retval);
447} 396}
448EXPORT_SYMBOL_GPL(platform_device_register_data); 397EXPORT_SYMBOL_GPL(platform_device_register_resndata);
449 398
450static int platform_drv_probe(struct device *_dev) 399static int platform_drv_probe(struct device *_dev)
451{ 400{
@@ -635,6 +584,12 @@ static struct device_attribute platform_dev_attrs[] = {
635static int platform_uevent(struct device *dev, struct kobj_uevent_env *env) 584static int platform_uevent(struct device *dev, struct kobj_uevent_env *env)
636{ 585{
637 struct platform_device *pdev = to_platform_device(dev); 586 struct platform_device *pdev = to_platform_device(dev);
587 int rc;
588
589 /* Some devices have extra OF data and an OF-style MODALIAS */
590 rc = of_device_uevent(dev,env);
591 if (rc != -ENODEV)
592 return rc;
638 593
639 add_uevent_var(env, "MODALIAS=%s%s", PLATFORM_MODULE_PREFIX, 594 add_uevent_var(env, "MODALIAS=%s%s", PLATFORM_MODULE_PREFIX,
640 (pdev->id_entry) ? pdev->id_entry->name : pdev->name); 595 (pdev->id_entry) ? pdev->id_entry->name : pdev->name);
@@ -673,7 +628,11 @@ static int platform_match(struct device *dev, struct device_driver *drv)
673 struct platform_device *pdev = to_platform_device(dev); 628 struct platform_device *pdev = to_platform_device(dev);
674 struct platform_driver *pdrv = to_platform_driver(drv); 629 struct platform_driver *pdrv = to_platform_driver(drv);
675 630
676 /* match against the id table first */ 631 /* Attempt an OF style match first */
632 if (of_driver_match_device(dev, drv))
633 return 1;
634
635 /* Then try to match against the id table */
677 if (pdrv->id_table) 636 if (pdrv->id_table)
678 return platform_match_id(pdrv->id_table, pdev) != NULL; 637 return platform_match_id(pdrv->id_table, pdev) != NULL;
679 638