aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/base/platform.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2008-01-25 11:34:42 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2008-01-25 11:35:13 -0500
commitdf8dc74e8a383eaf2d9b44b80a71ec6f0e52b42e (patch)
treebc3799a43e8b94fa84b32e37b1c124d5e4868f50 /drivers/base/platform.c
parent556a169dab38b5100df6f4a45b655dddd3db94c1 (diff)
parent4a3ad20ccd8f4d2a0535cf98fa83f7b561ba59a9 (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-2.6
This can be broken down into these major areas: - Documentation updates (language translations and fixes, as well as kobject and kset documenatation updates.) - major kset/kobject/ktype rework and fixes. This cleans up the kset and kobject and ktype relationship and architecture, making sense of things now, and good documenation and samples are provided for others to use. Also the attributes for kobjects are much easier to handle now. This cleaned up a LOT of code all through the kernel, making kobjects easier to use if you want to. - struct bus_type has been reworked to now handle the lifetime rules properly, as the kobject is properly dynamic. - struct driver has also been reworked, and now the lifetime issues are resolved. - the block subsystem has been converted to use struct device now, and not "raw" kobjects. This patch has been in the -mm tree for over a year now, and finally all the issues are worked out with it. Older distros now properly work with new kernels, and no userspace updates are needed at all. - nozomi driver is added. This has also been in -mm for a long time, and many people have asked for it to go in. It is now in good enough shape to do so. - lots of class_device conversions to use struct device instead. The tree is almost all cleaned up now, only SCSI and IB is the remaining code to fix up... * git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-2.6: (196 commits) Driver core: coding style fixes Kobject: fix coding style issues in kobject c files Kobject: fix coding style issues in kobject.h Driver core: fix coding style issues in device.h spi: use class iteration api scsi: use class iteration api rtc: use class iteration api power supply : use class iteration api ieee1394: use class iteration api Driver Core: add class iteration api Driver core: Cleanup get_device_parent() in device_add() and device_move() UIO: constify function pointer tables Driver Core: constify the name passed to platform_device_register_simple driver core: fix build with SYSFS=n sysfs: make SYSFS_DEPRECATED depend on SYSFS Driver core: use LIST_HEAD instead of call to INIT_LIST_HEAD in __init kobject: add sample code for how to use ksets/ktypes/kobjects kobject: add sample code for how to use kobjects in a simple manner. kobject: update the kobject/kset documentation kobject: remove old, outdated documentation. ...
Diffstat (limited to 'drivers/base/platform.c')
-rw-r--r--drivers/base/platform.c239
1 files changed, 120 insertions, 119 deletions
diff --git a/drivers/base/platform.c b/drivers/base/platform.c
index fb5609241482..efaf282c438c 100644
--- a/drivers/base/platform.c
+++ b/drivers/base/platform.c
@@ -20,7 +20,8 @@
20 20
21#include "base.h" 21#include "base.h"
22 22
23#define to_platform_driver(drv) (container_of((drv), struct platform_driver, driver)) 23#define to_platform_driver(drv) (container_of((drv), struct platform_driver, \
24 driver))
24 25
25struct device platform_bus = { 26struct device platform_bus = {
26 .bus_id = "platform", 27 .bus_id = "platform",
@@ -28,14 +29,13 @@ struct device platform_bus = {
28EXPORT_SYMBOL_GPL(platform_bus); 29EXPORT_SYMBOL_GPL(platform_bus);
29 30
30/** 31/**
31 * platform_get_resource - get a resource for a device 32 * platform_get_resource - get a resource for a device
32 * @dev: platform device 33 * @dev: platform device
33 * @type: resource type 34 * @type: resource type
34 * @num: resource index 35 * @num: resource index
35 */ 36 */
36struct resource * 37struct resource *platform_get_resource(struct platform_device *dev,
37platform_get_resource(struct platform_device *dev, unsigned int type, 38 unsigned int type, unsigned int num)
38 unsigned int num)
39{ 39{
40 int i; 40 int i;
41 41
@@ -43,8 +43,7 @@ platform_get_resource(struct platform_device *dev, unsigned int type,
43 struct resource *r = &dev->resource[i]; 43 struct resource *r = &dev->resource[i];
44 44
45 if ((r->flags & (IORESOURCE_IO|IORESOURCE_MEM| 45 if ((r->flags & (IORESOURCE_IO|IORESOURCE_MEM|
46 IORESOURCE_IRQ|IORESOURCE_DMA)) 46 IORESOURCE_IRQ|IORESOURCE_DMA)) == type)
47 == type)
48 if (num-- == 0) 47 if (num-- == 0)
49 return r; 48 return r;
50 } 49 }
@@ -53,9 +52,9 @@ platform_get_resource(struct platform_device *dev, unsigned int type,
53EXPORT_SYMBOL_GPL(platform_get_resource); 52EXPORT_SYMBOL_GPL(platform_get_resource);
54 53
55/** 54/**
56 * platform_get_irq - get an IRQ for a device 55 * platform_get_irq - get an IRQ for a device
57 * @dev: platform device 56 * @dev: platform device
58 * @num: IRQ number index 57 * @num: IRQ number index
59 */ 58 */
60int platform_get_irq(struct platform_device *dev, unsigned int num) 59int platform_get_irq(struct platform_device *dev, unsigned int num)
61{ 60{
@@ -66,14 +65,13 @@ int platform_get_irq(struct platform_device *dev, unsigned int num)
66EXPORT_SYMBOL_GPL(platform_get_irq); 65EXPORT_SYMBOL_GPL(platform_get_irq);
67 66
68/** 67/**
69 * platform_get_resource_byname - get a resource for a device by name 68 * platform_get_resource_byname - get a resource for a device by name
70 * @dev: platform device 69 * @dev: platform device
71 * @type: resource type 70 * @type: resource type
72 * @name: resource name 71 * @name: resource name
73 */ 72 */
74struct resource * 73struct resource *platform_get_resource_byname(struct platform_device *dev,
75platform_get_resource_byname(struct platform_device *dev, unsigned int type, 74 unsigned int type, char *name)
76 char *name)
77{ 75{
78 int i; 76 int i;
79 77
@@ -90,22 +88,23 @@ platform_get_resource_byname(struct platform_device *dev, unsigned int type,
90EXPORT_SYMBOL_GPL(platform_get_resource_byname); 88EXPORT_SYMBOL_GPL(platform_get_resource_byname);
91 89
92/** 90/**
93 * platform_get_irq - get an IRQ for a device 91 * platform_get_irq - get an IRQ for a device
94 * @dev: platform device 92 * @dev: platform device
95 * @name: IRQ name 93 * @name: IRQ name
96 */ 94 */
97int platform_get_irq_byname(struct platform_device *dev, char *name) 95int platform_get_irq_byname(struct platform_device *dev, char *name)
98{ 96{
99 struct resource *r = platform_get_resource_byname(dev, IORESOURCE_IRQ, name); 97 struct resource *r = platform_get_resource_byname(dev, IORESOURCE_IRQ,
98 name);
100 99
101 return r ? r->start : -ENXIO; 100 return r ? r->start : -ENXIO;
102} 101}
103EXPORT_SYMBOL_GPL(platform_get_irq_byname); 102EXPORT_SYMBOL_GPL(platform_get_irq_byname);
104 103
105/** 104/**
106 * platform_add_devices - add a numbers of platform devices 105 * platform_add_devices - add a numbers of platform devices
107 * @devs: array of platform devices to add 106 * @devs: array of platform devices to add
108 * @num: number of platform devices in array 107 * @num: number of platform devices in array
109 */ 108 */
110int platform_add_devices(struct platform_device **devs, int num) 109int platform_add_devices(struct platform_device **devs, int num)
111{ 110{
@@ -130,12 +129,11 @@ struct platform_object {
130}; 129};
131 130
132/** 131/**
133 * platform_device_put 132 * platform_device_put
134 * @pdev: platform device to free 133 * @pdev: platform device to free
135 * 134 *
136 * Free all memory associated with a platform device. This function 135 * Free all memory associated with a platform device. This function must
137 * must _only_ be externally called in error cases. All other usage 136 * _only_ be externally called in error cases. All other usage is a bug.
138 * is a bug.
139 */ 137 */
140void platform_device_put(struct platform_device *pdev) 138void platform_device_put(struct platform_device *pdev)
141{ 139{
@@ -146,7 +144,8 @@ EXPORT_SYMBOL_GPL(platform_device_put);
146 144
147static void platform_device_release(struct device *dev) 145static void platform_device_release(struct device *dev)
148{ 146{
149 struct platform_object *pa = container_of(dev, struct platform_object, pdev.dev); 147 struct platform_object *pa = container_of(dev, struct platform_object,
148 pdev.dev);
150 149
151 kfree(pa->pdev.dev.platform_data); 150 kfree(pa->pdev.dev.platform_data);
152 kfree(pa->pdev.resource); 151 kfree(pa->pdev.resource);
@@ -154,12 +153,12 @@ static void platform_device_release(struct device *dev)
154} 153}
155 154
156/** 155/**
157 * platform_device_alloc 156 * platform_device_alloc
158 * @name: base name of the device we're adding 157 * @name: base name of the device we're adding
159 * @id: instance id 158 * @id: instance id
160 * 159 *
161 * Create a platform device object which can have other objects attached 160 * Create a platform device object which can have other objects attached
162 * to it, and which will have attached objects freed when it is released. 161 * to it, and which will have attached objects freed when it is released.
163 */ 162 */
164struct platform_device *platform_device_alloc(const char *name, int id) 163struct platform_device *platform_device_alloc(const char *name, int id)
165{ 164{
@@ -179,16 +178,17 @@ struct platform_device *platform_device_alloc(const char *name, int id)
179EXPORT_SYMBOL_GPL(platform_device_alloc); 178EXPORT_SYMBOL_GPL(platform_device_alloc);
180 179
181/** 180/**
182 * platform_device_add_resources 181 * platform_device_add_resources
183 * @pdev: platform device allocated by platform_device_alloc to add resources to 182 * @pdev: platform device allocated by platform_device_alloc to add resources to
184 * @res: set of resources that needs to be allocated for the device 183 * @res: set of resources that needs to be allocated for the device
185 * @num: number of resources 184 * @num: number of resources
186 * 185 *
187 * Add a copy of the resources to the platform device. The memory 186 * Add a copy of the resources to the platform device. The memory
188 * associated with the resources will be freed when the platform 187 * associated with the resources will be freed when the platform device is
189 * device is released. 188 * released.
190 */ 189 */
191int platform_device_add_resources(struct platform_device *pdev, struct resource *res, unsigned int num) 190int platform_device_add_resources(struct platform_device *pdev,
191 struct resource *res, unsigned int num)
192{ 192{
193 struct resource *r; 193 struct resource *r;
194 194
@@ -203,16 +203,17 @@ int platform_device_add_resources(struct platform_device *pdev, struct resource
203EXPORT_SYMBOL_GPL(platform_device_add_resources); 203EXPORT_SYMBOL_GPL(platform_device_add_resources);
204 204
205/** 205/**
206 * platform_device_add_data 206 * platform_device_add_data
207 * @pdev: platform device allocated by platform_device_alloc to add resources to 207 * @pdev: platform device allocated by platform_device_alloc to add resources to
208 * @data: platform specific data for this platform device 208 * @data: platform specific data for this platform device
209 * @size: size of platform specific data 209 * @size: size of platform specific data
210 * 210 *
211 * Add a copy of platform specific data to the platform device's platform_data 211 * Add a copy of platform specific data to the platform device's
212 * pointer. The memory associated with the platform data will be freed 212 * platform_data pointer. The memory associated with the platform data
213 * when the platform device is released. 213 * will be freed when the platform device is released.
214 */ 214 */
215int platform_device_add_data(struct platform_device *pdev, const void *data, size_t size) 215int platform_device_add_data(struct platform_device *pdev, const void *data,
216 size_t size)
216{ 217{
217 void *d; 218 void *d;
218 219
@@ -226,11 +227,11 @@ int platform_device_add_data(struct platform_device *pdev, const void *data, siz
226EXPORT_SYMBOL_GPL(platform_device_add_data); 227EXPORT_SYMBOL_GPL(platform_device_add_data);
227 228
228/** 229/**
229 * platform_device_add - add a platform device to device hierarchy 230 * platform_device_add - add a platform device to device hierarchy
230 * @pdev: platform device we're adding 231 * @pdev: platform device we're adding
231 * 232 *
232 * This is part 2 of platform_device_register(), though may be called 233 * This is part 2 of platform_device_register(), though may be called
233 * separately _iff_ pdev was allocated by platform_device_alloc(). 234 * separately _iff_ pdev was allocated by platform_device_alloc().
234 */ 235 */
235int platform_device_add(struct platform_device *pdev) 236int platform_device_add(struct platform_device *pdev)
236{ 237{
@@ -289,13 +290,12 @@ int platform_device_add(struct platform_device *pdev)
289EXPORT_SYMBOL_GPL(platform_device_add); 290EXPORT_SYMBOL_GPL(platform_device_add);
290 291
291/** 292/**
292 * platform_device_del - remove a platform-level device 293 * platform_device_del - remove a platform-level device
293 * @pdev: platform device we're removing 294 * @pdev: platform device we're removing
294 * 295 *
295 * Note that this function will also release all memory- and port-based 296 * Note that this function will also release all memory- and port-based
296 * resources owned by the device (@dev->resource). This function 297 * resources owned by the device (@dev->resource). This function must
297 * must _only_ be externally called in error cases. All other usage 298 * _only_ be externally called in error cases. All other usage is a bug.
298 * is a bug.
299 */ 299 */
300void platform_device_del(struct platform_device *pdev) 300void platform_device_del(struct platform_device *pdev)
301{ 301{
@@ -314,11 +314,10 @@ void platform_device_del(struct platform_device *pdev)
314EXPORT_SYMBOL_GPL(platform_device_del); 314EXPORT_SYMBOL_GPL(platform_device_del);
315 315
316/** 316/**
317 * platform_device_register - add a platform-level device 317 * platform_device_register - add a platform-level device
318 * @pdev: platform device we're adding 318 * @pdev: platform device we're adding
319 *
320 */ 319 */
321int platform_device_register(struct platform_device * pdev) 320int platform_device_register(struct platform_device *pdev)
322{ 321{
323 device_initialize(&pdev->dev); 322 device_initialize(&pdev->dev);
324 return platform_device_add(pdev); 323 return platform_device_add(pdev);
@@ -326,14 +325,14 @@ int platform_device_register(struct platform_device * pdev)
326EXPORT_SYMBOL_GPL(platform_device_register); 325EXPORT_SYMBOL_GPL(platform_device_register);
327 326
328/** 327/**
329 * platform_device_unregister - unregister a platform-level device 328 * platform_device_unregister - unregister a platform-level device
330 * @pdev: platform device we're unregistering 329 * @pdev: platform device we're unregistering
331 * 330 *
332 * Unregistration is done in 2 steps. First we release all resources 331 * Unregistration is done in 2 steps. First we release all resources
333 * and remove it from the subsystem, then we drop reference count by 332 * and remove it from the subsystem, then we drop reference count by
334 * calling platform_device_put(). 333 * calling platform_device_put().
335 */ 334 */
336void platform_device_unregister(struct platform_device * pdev) 335void platform_device_unregister(struct platform_device *pdev)
337{ 336{
338 platform_device_del(pdev); 337 platform_device_del(pdev);
339 platform_device_put(pdev); 338 platform_device_put(pdev);
@@ -341,27 +340,29 @@ void platform_device_unregister(struct platform_device * pdev)
341EXPORT_SYMBOL_GPL(platform_device_unregister); 340EXPORT_SYMBOL_GPL(platform_device_unregister);
342 341
343/** 342/**
344 * platform_device_register_simple 343 * platform_device_register_simple
345 * @name: base name of the device we're adding 344 * @name: base name of the device we're adding
346 * @id: instance id 345 * @id: instance id
347 * @res: set of resources that needs to be allocated for the device 346 * @res: set of resources that needs to be allocated for the device
348 * @num: number of resources 347 * @num: number of resources
349 * 348 *
350 * This function creates a simple platform device that requires minimal 349 * This function creates a simple platform device that requires minimal
351 * resource and memory management. Canned release function freeing 350 * resource and memory management. Canned release function freeing memory
352 * memory allocated for the device allows drivers using such devices 351 * allocated for the device allows drivers using such devices to be
353 * to be unloaded without waiting for the last reference to the device 352 * unloaded without waiting for the last reference to the device to be
354 * to be dropped. 353 * dropped.
355 * 354 *
356 * This interface is primarily intended for use with legacy drivers 355 * This interface is primarily intended for use with legacy drivers which
357 * which probe hardware directly. Because such drivers create sysfs 356 * probe hardware directly. Because such drivers create sysfs device nodes
358 * device nodes themselves, rather than letting system infrastructure 357 * themselves, rather than letting system infrastructure handle such device
359 * handle such device enumeration tasks, they don't fully conform to 358 * enumeration tasks, they don't fully conform to the Linux driver model.
360 * the Linux driver model. In particular, when such drivers are built 359 * In particular, when such drivers are built as modules, they can't be
361 * as modules, they can't be "hotplugged". 360 * "hotplugged".
362 */ 361 */
363struct platform_device *platform_device_register_simple(char *name, int id, 362struct platform_device *platform_device_register_simple(const char *name,
364 struct resource *res, unsigned int num) 363 int id,
364 struct resource *res,
365 unsigned int num)
365{ 366{
366 struct platform_device *pdev; 367 struct platform_device *pdev;
367 int retval; 368 int retval;
@@ -436,8 +437,8 @@ static int platform_drv_resume(struct device *_dev)
436} 437}
437 438
438/** 439/**
439 * platform_driver_register 440 * platform_driver_register
440 * @drv: platform driver structure 441 * @drv: platform driver structure
441 */ 442 */
442int platform_driver_register(struct platform_driver *drv) 443int platform_driver_register(struct platform_driver *drv)
443{ 444{
@@ -457,8 +458,8 @@ int platform_driver_register(struct platform_driver *drv)
457EXPORT_SYMBOL_GPL(platform_driver_register); 458EXPORT_SYMBOL_GPL(platform_driver_register);
458 459
459/** 460/**
460 * platform_driver_unregister 461 * platform_driver_unregister
461 * @drv: platform driver structure 462 * @drv: platform driver structure
462 */ 463 */
463void platform_driver_unregister(struct platform_driver *drv) 464void platform_driver_unregister(struct platform_driver *drv)
464{ 465{
@@ -497,12 +498,12 @@ int __init_or_module platform_driver_probe(struct platform_driver *drv,
497 * if the probe was successful, and make sure any forced probes of 498 * if the probe was successful, and make sure any forced probes of
498 * new devices fail. 499 * new devices fail.
499 */ 500 */
500 spin_lock(&platform_bus_type.klist_drivers.k_lock); 501 spin_lock(&platform_bus_type.p->klist_drivers.k_lock);
501 drv->probe = NULL; 502 drv->probe = NULL;
502 if (code == 0 && list_empty(&drv->driver.klist_devices.k_list)) 503 if (code == 0 && list_empty(&drv->driver.p->klist_devices.k_list))
503 retval = -ENODEV; 504 retval = -ENODEV;
504 drv->driver.probe = platform_drv_probe_fail; 505 drv->driver.probe = platform_drv_probe_fail;
505 spin_unlock(&platform_bus_type.klist_drivers.k_lock); 506 spin_unlock(&platform_bus_type.p->klist_drivers.k_lock);
506 507
507 if (code != retval) 508 if (code != retval)
508 platform_driver_unregister(drv); 509 platform_driver_unregister(drv);
@@ -516,8 +517,8 @@ EXPORT_SYMBOL_GPL(platform_driver_probe);
516 * (b) sysfs attribute lets new-style coldplug recover from hotplug events 517 * (b) sysfs attribute lets new-style coldplug recover from hotplug events
517 * mishandled before system is fully running: "modprobe $(cat modalias)" 518 * mishandled before system is fully running: "modprobe $(cat modalias)"
518 */ 519 */
519static ssize_t 520static ssize_t modalias_show(struct device *dev, struct device_attribute *a,
520modalias_show(struct device *dev, struct device_attribute *a, char *buf) 521 char *buf)
521{ 522{
522 struct platform_device *pdev = to_platform_device(dev); 523 struct platform_device *pdev = to_platform_device(dev);
523 int len = snprintf(buf, PAGE_SIZE, "platform:%s\n", pdev->name); 524 int len = snprintf(buf, PAGE_SIZE, "platform:%s\n", pdev->name);
@@ -538,26 +539,24 @@ static int platform_uevent(struct device *dev, struct kobj_uevent_env *env)
538 return 0; 539 return 0;
539} 540}
540 541
541
542/** 542/**
543 * platform_match - bind platform device to platform driver. 543 * platform_match - bind platform device to platform driver.
544 * @dev: device. 544 * @dev: device.
545 * @drv: driver. 545 * @drv: driver.
546 * 546 *
547 * Platform device IDs are assumed to be encoded like this: 547 * Platform device IDs are assumed to be encoded like this:
548 * "<name><instance>", where <name> is a short description of the 548 * "<name><instance>", where <name> is a short description of the type of
549 * type of device, like "pci" or "floppy", and <instance> is the 549 * device, like "pci" or "floppy", and <instance> is the enumerated
550 * enumerated instance of the device, like '0' or '42'. 550 * instance of the device, like '0' or '42'. Driver IDs are simply
551 * Driver IDs are simply "<name>". 551 * "<name>". So, extract the <name> from the platform_device structure,
552 * So, extract the <name> from the platform_device structure, 552 * and compare it against the name of the driver. Return whether they match
553 * and compare it against the name of the driver. Return whether 553 * or not.
554 * they match or not.
555 */ 554 */
556 555static int platform_match(struct device *dev, struct device_driver *drv)
557static int platform_match(struct device * dev, struct device_driver * drv)
558{ 556{
559 struct platform_device *pdev = container_of(dev, struct platform_device, dev); 557 struct platform_device *pdev;
560 558
559 pdev = container_of(dev, struct platform_device, dev);
561 return (strncmp(pdev->name, drv->name, BUS_ID_SIZE) == 0); 560 return (strncmp(pdev->name, drv->name, BUS_ID_SIZE) == 0);
562} 561}
563 562
@@ -574,9 +573,10 @@ static int platform_suspend(struct device *dev, pm_message_t mesg)
574static int platform_suspend_late(struct device *dev, pm_message_t mesg) 573static int platform_suspend_late(struct device *dev, pm_message_t mesg)
575{ 574{
576 struct platform_driver *drv = to_platform_driver(dev->driver); 575 struct platform_driver *drv = to_platform_driver(dev->driver);
577 struct platform_device *pdev = container_of(dev, struct platform_device, dev); 576 struct platform_device *pdev;
578 int ret = 0; 577 int ret = 0;
579 578
579 pdev = container_of(dev, struct platform_device, dev);
580 if (dev->driver && drv->suspend_late) 580 if (dev->driver && drv->suspend_late)
581 ret = drv->suspend_late(pdev, mesg); 581 ret = drv->suspend_late(pdev, mesg);
582 582
@@ -586,16 +586,17 @@ static int platform_suspend_late(struct device *dev, pm_message_t mesg)
586static int platform_resume_early(struct device *dev) 586static int platform_resume_early(struct device *dev)
587{ 587{
588 struct platform_driver *drv = to_platform_driver(dev->driver); 588 struct platform_driver *drv = to_platform_driver(dev->driver);
589 struct platform_device *pdev = container_of(dev, struct platform_device, dev); 589 struct platform_device *pdev;
590 int ret = 0; 590 int ret = 0;
591 591
592 pdev = container_of(dev, struct platform_device, dev);
592 if (dev->driver && drv->resume_early) 593 if (dev->driver && drv->resume_early)
593 ret = drv->resume_early(pdev); 594 ret = drv->resume_early(pdev);
594 595
595 return ret; 596 return ret;
596} 597}
597 598
598static int platform_resume(struct device * dev) 599static int platform_resume(struct device *dev)
599{ 600{
600 int ret = 0; 601 int ret = 0;
601 602