aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/base/platform.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/base/platform.c')
-rw-r--r--drivers/base/platform.c233
1 files changed, 117 insertions, 116 deletions
diff --git a/drivers/base/platform.c b/drivers/base/platform.c
index 48d5db4f92ee..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(const 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{
@@ -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