Root/
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 | |
13 | static struct device isa_bus = { |
14 | .init_name = "isa" |
15 | }; |
16 | |
17 | struct 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 | |
25 | static 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 | |
38 | static 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 | |
48 | static 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 | |
58 | static 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 | |
66 | static 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 | |
76 | static 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 | |
86 | static 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 | |
96 | static void isa_dev_release(struct device *dev) |
97 | { |
98 | kfree(to_isa_dev(dev)); |
99 | } |
100 | |
101 | void 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 | } |
112 | EXPORT_SYMBOL_GPL(isa_unregister_driver); |
113 | |
114 | int 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 | } |
168 | EXPORT_SYMBOL_GPL(isa_register_driver); |
169 | |
170 | static 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 | |
183 | device_initcall(isa_bus_init); |
184 |
Branches:
ben-wpan
ben-wpan-stefan
javiroman/ks7010
jz-2.6.34
jz-2.6.34-rc5
jz-2.6.34-rc6
jz-2.6.34-rc7
jz-2.6.35
jz-2.6.36
jz-2.6.37
jz-2.6.38
jz-2.6.39
jz-3.0
jz-3.1
jz-3.11
jz-3.12
jz-3.13
jz-3.15
jz-3.16
jz-3.18-dt
jz-3.2
jz-3.3
jz-3.4
jz-3.5
jz-3.6
jz-3.6-rc2-pwm
jz-3.9
jz-3.9-clk
jz-3.9-rc8
jz47xx
jz47xx-2.6.38
master
Tags:
od-2011-09-04
od-2011-09-18
v2.6.34-rc5
v2.6.34-rc6
v2.6.34-rc7
v3.9