ftp://ftp.kernel.org/pub/linux/kernel/v2.6/linux-2.6.6.tar.bz2
[linux-2.6.git] / drivers / base / platform.c
1 /*
2  * platform.c - platform 'pseudo' bus for legacy devices
3  *
4  * Copyright (c) 2002-3 Patrick Mochel
5  * Copyright (c) 2002-3 Open Source Development Labs
6  * 
7  * This file is released under the GPLv2
8  *
9  * Please see Documentation/driver-model/platform.txt for more
10  * information.
11  */
12
13 #include <linux/device.h>
14 #include <linux/module.h>
15 #include <linux/init.h>
16
17 struct device platform_bus = {
18         .bus_id         = "platform",
19 };
20
21 /**
22  *      platform_device_register - add a platform-level device
23  *      @dev:   platform device we're adding
24  *
25  */
26 int platform_device_register(struct platform_device * pdev)
27 {
28         if (!pdev)
29                 return -EINVAL;
30
31         if (!pdev->dev.parent)
32                 pdev->dev.parent = &platform_bus;
33
34         pdev->dev.bus = &platform_bus_type;
35         
36         snprintf(pdev->dev.bus_id,BUS_ID_SIZE,"%s%u",pdev->name,pdev->id);
37
38         pr_debug("Registering platform device '%s'. Parent at %s\n",
39                  pdev->dev.bus_id,pdev->dev.parent->bus_id);
40         return device_register(&pdev->dev);
41 }
42
43 void platform_device_unregister(struct platform_device * pdev)
44 {
45         if (pdev)
46                 device_unregister(&pdev->dev);
47 }
48
49
50 /**
51  *      platform_match - bind platform device to platform driver.
52  *      @dev:   device.
53  *      @drv:   driver.
54  *
55  *      Platform device IDs are assumed to be encoded like this: 
56  *      "<name><instance>", where <name> is a short description of the 
57  *      type of device, like "pci" or "floppy", and <instance> is the 
58  *      enumerated instance of the device, like '0' or '42'.
59  *      Driver IDs are simply "<name>". 
60  *      So, extract the <name> from the device, and compare it against 
61  *      the name of the driver. Return whether they match or not.
62  */
63
64 static int platform_match(struct device * dev, struct device_driver * drv)
65 {
66         struct platform_device *pdev = container_of(dev, struct platform_device, dev);
67
68         return (strncmp(pdev->name, drv->name, BUS_ID_SIZE) == 0);
69 }
70
71 static int platform_suspend(struct device * dev, u32 state)
72 {
73         int ret = 0;
74
75         if (dev->driver && dev->driver->suspend) {
76                 ret = dev->driver->suspend(dev, state, SUSPEND_DISABLE);
77                 if (ret == 0)
78                         ret = dev->driver->suspend(dev, state, SUSPEND_SAVE_STATE);
79                 if (ret == 0)
80                         ret = dev->driver->suspend(dev, state, SUSPEND_POWER_DOWN);
81         }
82         return ret;
83 }
84
85 static int platform_resume(struct device * dev)
86 {
87         int ret = 0;
88
89         if (dev->driver && dev->driver->resume) {
90                 ret = dev->driver->resume(dev, RESUME_POWER_ON);
91                 if (ret == 0)
92                         ret = dev->driver->resume(dev, RESUME_RESTORE_STATE);
93                 if (ret == 0)
94                         ret = dev->driver->resume(dev, RESUME_ENABLE);
95         }
96         return ret;
97 }
98
99 struct bus_type platform_bus_type = {
100         .name           = "platform",
101         .match          = platform_match,
102         .suspend        = platform_suspend,
103         .resume         = platform_resume,
104 };
105
106 int __init platform_bus_init(void)
107 {
108         device_register(&platform_bus);
109         return bus_register(&platform_bus_type);
110 }
111
112 EXPORT_SYMBOL(platform_bus);
113 EXPORT_SYMBOL(platform_bus_type);
114 EXPORT_SYMBOL(platform_device_register);
115 EXPORT_SYMBOL(platform_device_unregister);