Root/drivers/base/isa.c

1/*
2 * ISA bus.
3 */
4
5#include <linux/device.h>
6#include <linux/kernel.h>
7#include <linux/slab.h>
8#include <linux/module.h>
9#include <linux/init.h>
10#include <linux/dma-mapping.h>
11#include <linux/isa.h>
12
13static struct device isa_bus = {
14    .init_name = "isa"
15};
16
17struct isa_dev {
18    struct device dev;
19    struct device *next;
20    unsigned int id;
21};
22
23#define to_isa_dev(x) container_of((x), struct isa_dev, dev)
24
25static int isa_bus_match(struct device *dev, struct device_driver *driver)
26{
27    struct isa_driver *isa_driver = to_isa_driver(driver);
28
29    if (dev->platform_data == isa_driver) {
30        if (!isa_driver->match ||
31            isa_driver->match(dev, to_isa_dev(dev)->id))
32            return 1;
33        dev->platform_data = NULL;
34    }
35    return 0;
36}
37
38static int isa_bus_probe(struct device *dev)
39{
40    struct isa_driver *isa_driver = dev->platform_data;
41
42    if (isa_driver->probe)
43        return isa_driver->probe(dev, to_isa_dev(dev)->id);
44
45    return 0;
46}
47
48static int isa_bus_remove(struct device *dev)
49{
50    struct isa_driver *isa_driver = dev->platform_data;
51
52    if (isa_driver->remove)
53        return isa_driver->remove(dev, to_isa_dev(dev)->id);
54
55    return 0;
56}
57
58static void isa_bus_shutdown(struct device *dev)
59{
60    struct isa_driver *isa_driver = dev->platform_data;
61
62    if (isa_driver->shutdown)
63        isa_driver->shutdown(dev, to_isa_dev(dev)->id);
64}
65
66static int isa_bus_suspend(struct device *dev, pm_message_t state)
67{
68    struct isa_driver *isa_driver = dev->platform_data;
69
70    if (isa_driver->suspend)
71        return isa_driver->suspend(dev, to_isa_dev(dev)->id, state);
72
73    return 0;
74}
75
76static int isa_bus_resume(struct device *dev)
77{
78    struct isa_driver *isa_driver = dev->platform_data;
79
80    if (isa_driver->resume)
81        return isa_driver->resume(dev, to_isa_dev(dev)->id);
82
83    return 0;
84}
85
86static struct bus_type isa_bus_type = {
87    .name = "isa",
88    .match = isa_bus_match,
89    .probe = isa_bus_probe,
90    .remove = isa_bus_remove,
91    .shutdown = isa_bus_shutdown,
92    .suspend = isa_bus_suspend,
93    .resume = isa_bus_resume
94};
95
96static void isa_dev_release(struct device *dev)
97{
98    kfree(to_isa_dev(dev));
99}
100
101void isa_unregister_driver(struct isa_driver *isa_driver)
102{
103    struct device *dev = isa_driver->devices;
104
105    while (dev) {
106        struct device *tmp = to_isa_dev(dev)->next;
107        device_unregister(dev);
108        dev = tmp;
109    }
110    driver_unregister(&isa_driver->driver);
111}
112EXPORT_SYMBOL_GPL(isa_unregister_driver);
113
114int isa_register_driver(struct isa_driver *isa_driver, unsigned int ndev)
115{
116    int error;
117    unsigned int id;
118
119    isa_driver->driver.bus = &isa_bus_type;
120    isa_driver->devices = NULL;
121
122    error = driver_register(&isa_driver->driver);
123    if (error)
124        return error;
125
126    for (id = 0; id < ndev; id++) {
127        struct isa_dev *isa_dev;
128
129        isa_dev = kzalloc(sizeof *isa_dev, GFP_KERNEL);
130        if (!isa_dev) {
131            error = -ENOMEM;
132            break;
133        }
134
135        isa_dev->dev.parent = &isa_bus;
136        isa_dev->dev.bus = &isa_bus_type;
137
138        dev_set_name(&isa_dev->dev, "%s.%u",
139                 isa_driver->driver.name, id);
140        isa_dev->dev.platform_data = isa_driver;
141        isa_dev->dev.release = isa_dev_release;
142        isa_dev->id = id;
143
144        isa_dev->dev.coherent_dma_mask = DMA_BIT_MASK(24);
145        isa_dev->dev.dma_mask = &isa_dev->dev.coherent_dma_mask;
146
147        error = device_register(&isa_dev->dev);
148        if (error) {
149            put_device(&isa_dev->dev);
150            break;
151        }
152
153        if (isa_dev->dev.platform_data) {
154            isa_dev->next = isa_driver->devices;
155            isa_driver->devices = &isa_dev->dev;
156        } else
157            device_unregister(&isa_dev->dev);
158    }
159
160    if (!error && !isa_driver->devices)
161        error = -ENODEV;
162
163    if (error)
164        isa_unregister_driver(isa_driver);
165
166    return error;
167}
168EXPORT_SYMBOL_GPL(isa_register_driver);
169
170static int __init isa_bus_init(void)
171{
172    int error;
173
174    error = bus_register(&isa_bus_type);
175    if (!error) {
176        error = device_register(&isa_bus);
177        if (error)
178            bus_unregister(&isa_bus_type);
179    }
180    return error;
181}
182
183device_initcall(isa_bus_init);
184

Archive Download this file



interactive