diff options
author | David S. Miller <davem@sunset.davemloft.net> | 2006-06-23 04:44:10 -0400 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2006-06-24 02:15:43 -0400 |
commit | a2bd4fd17926d715a470fbe0ebe05128ba410984 (patch) | |
tree | 3e39a2f6aaf3a628b955067ef3668cae3456de03 | |
parent | 8cd24ed4f8031636fb5dacb04adee9e02556ecd5 (diff) |
[SPARC64]: Add of_device layer and make ebus/isa use it.
Sparcspkr and power drivers are converted, to make sure it works.
Eventually the SBUS device layer will use this as a sub-class.
I really cannot cut loose on that bit until sparc32 is given the
same infrastructure.
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | arch/sparc64/kernel/Makefile | 2 | ||||
-rw-r--r-- | arch/sparc64/kernel/ebus.c | 21 | ||||
-rw-r--r-- | arch/sparc64/kernel/isa.c | 37 | ||||
-rw-r--r-- | arch/sparc64/kernel/of_device.c | 279 | ||||
-rw-r--r-- | arch/sparc64/kernel/power.c | 109 | ||||
-rw-r--r-- | drivers/input/misc/Kconfig | 2 | ||||
-rw-r--r-- | drivers/input/misc/sparcspkr.c | 218 | ||||
-rw-r--r-- | include/asm-sparc64/ebus.h | 5 | ||||
-rw-r--r-- | include/asm-sparc64/isa.h | 5 | ||||
-rw-r--r-- | include/asm-sparc64/of_device.h | 64 |
10 files changed, 585 insertions, 157 deletions
diff --git a/arch/sparc64/kernel/Makefile b/arch/sparc64/kernel/Makefile index 7f00189ed294..86c9fe3f3e4a 100644 --- a/arch/sparc64/kernel/Makefile +++ b/arch/sparc64/kernel/Makefile | |||
@@ -12,7 +12,7 @@ obj-y := process.o setup.o cpu.o idprom.o \ | |||
12 | irq.o ptrace.o time.o sys_sparc.o signal.o \ | 12 | irq.o ptrace.o time.o sys_sparc.o signal.o \ |
13 | unaligned.o central.o pci.o starfire.o semaphore.o \ | 13 | unaligned.o central.o pci.o starfire.o semaphore.o \ |
14 | power.o sbus.o iommu_common.o sparc64_ksyms.o chmc.o \ | 14 | power.o sbus.o iommu_common.o sparc64_ksyms.o chmc.o \ |
15 | visemul.o prom.o | 15 | visemul.o prom.o of_device.o |
16 | 16 | ||
17 | obj-$(CONFIG_PCI) += ebus.o isa.o pci_common.o pci_iommu.o \ | 17 | obj-$(CONFIG_PCI) += ebus.o isa.o pci_common.o pci_iommu.o \ |
18 | pci_psycho.o pci_sabre.o pci_schizo.o \ | 18 | pci_psycho.o pci_sabre.o pci_schizo.o \ |
diff --git a/arch/sparc64/kernel/ebus.c b/arch/sparc64/kernel/ebus.c index 33d79e10c653..b390a2f3a15e 100644 --- a/arch/sparc64/kernel/ebus.c +++ b/arch/sparc64/kernel/ebus.c | |||
@@ -475,6 +475,16 @@ probe_interrupts: | |||
475 | } | 475 | } |
476 | } | 476 | } |
477 | 477 | ||
478 | dev->ofdev.node = dp; | ||
479 | dev->ofdev.dev.parent = &dev->bus->ofdev.dev; | ||
480 | dev->ofdev.dev.bus = &ebus_bus_type; | ||
481 | strcpy(dev->ofdev.dev.bus_id, dp->path_component_name); | ||
482 | |||
483 | /* Register with core */ | ||
484 | if (of_device_register(&dev->ofdev) != 0) | ||
485 | printk(KERN_DEBUG "ebus: device registration error for %s!\n", | ||
486 | dev->ofdev.dev.bus_id); | ||
487 | |||
478 | dp = dp->child; | 488 | dp = dp->child; |
479 | if (dp) { | 489 | if (dp) { |
480 | printk(" ->"); | 490 | printk(" ->"); |
@@ -570,6 +580,17 @@ void __init ebus_init(void) | |||
570 | ebus->self = pdev; | 580 | ebus->self = pdev; |
571 | ebus->parent = pbm = cookie->pbm; | 581 | ebus->parent = pbm = cookie->pbm; |
572 | 582 | ||
583 | ebus->ofdev.node = dp; | ||
584 | ebus->ofdev.dev.parent = &pdev->dev; | ||
585 | ebus->ofdev.dev.bus = &ebus_bus_type; | ||
586 | strcpy(ebus->ofdev.dev.bus_id, dp->path_component_name); | ||
587 | |||
588 | /* Register with core */ | ||
589 | if (of_device_register(&ebus->ofdev) != 0) | ||
590 | printk(KERN_DEBUG "ebus: device registration error for %s!\n", | ||
591 | ebus->ofdev.dev.bus_id); | ||
592 | |||
593 | |||
573 | child = dp->child; | 594 | child = dp->child; |
574 | if (!child) | 595 | if (!child) |
575 | goto next_ebus; | 596 | goto next_ebus; |
diff --git a/arch/sparc64/kernel/isa.c b/arch/sparc64/kernel/isa.c index 2693f2de549c..6f16dee280a8 100644 --- a/arch/sparc64/kernel/isa.c +++ b/arch/sparc64/kernel/isa.c | |||
@@ -195,12 +195,25 @@ static void __init isa_fill_devices(struct sparc_isa_bridge *isa_br) | |||
195 | 195 | ||
196 | isa_dev = kmalloc(sizeof(*isa_dev), GFP_KERNEL); | 196 | isa_dev = kmalloc(sizeof(*isa_dev), GFP_KERNEL); |
197 | if (!isa_dev) { | 197 | if (!isa_dev) { |
198 | fatal_err("cannot allocate isa_dev"); | 198 | printk(KERN_DEBUG "ISA: cannot allocate isa_dev"); |
199 | prom_halt(); | 199 | return; |
200 | } | 200 | } |
201 | 201 | ||
202 | memset(isa_dev, 0, sizeof(*isa_dev)); | 202 | memset(isa_dev, 0, sizeof(*isa_dev)); |
203 | 203 | ||
204 | isa_dev->ofdev.node = dp; | ||
205 | isa_dev->ofdev.dev.parent = &isa_br->ofdev.dev; | ||
206 | isa_dev->ofdev.dev.bus = &isa_bus_type; | ||
207 | strcpy(isa_dev->ofdev.dev.bus_id, dp->path_component_name); | ||
208 | |||
209 | /* Register with core */ | ||
210 | if (of_device_register(&isa_dev->ofdev) != 0) { | ||
211 | printk(KERN_DEBUG "isa: device registration error for %s!\n", | ||
212 | isa_dev->ofdev.dev.bus_id); | ||
213 | kfree(isa_dev); | ||
214 | goto next_sibling; | ||
215 | } | ||
216 | |||
204 | /* Link it in. */ | 217 | /* Link it in. */ |
205 | isa_dev->next = NULL; | 218 | isa_dev->next = NULL; |
206 | if (isa_br->devices == NULL) { | 219 | if (isa_br->devices == NULL) { |
@@ -226,6 +239,7 @@ static void __init isa_fill_devices(struct sparc_isa_bridge *isa_br) | |||
226 | 239 | ||
227 | printk("]"); | 240 | printk("]"); |
228 | 241 | ||
242 | next_sibling: | ||
229 | dp = dp->sibling; | 243 | dp = dp->sibling; |
230 | } | 244 | } |
231 | } | 245 | } |
@@ -244,6 +258,7 @@ void __init isa_init(void) | |||
244 | struct pcidev_cookie *pdev_cookie; | 258 | struct pcidev_cookie *pdev_cookie; |
245 | struct pci_pbm_info *pbm; | 259 | struct pci_pbm_info *pbm; |
246 | struct sparc_isa_bridge *isa_br; | 260 | struct sparc_isa_bridge *isa_br; |
261 | struct device_node *dp; | ||
247 | 262 | ||
248 | pdev_cookie = pdev->sysdata; | 263 | pdev_cookie = pdev->sysdata; |
249 | if (!pdev_cookie) { | 264 | if (!pdev_cookie) { |
@@ -252,15 +267,29 @@ void __init isa_init(void) | |||
252 | continue; | 267 | continue; |
253 | } | 268 | } |
254 | pbm = pdev_cookie->pbm; | 269 | pbm = pdev_cookie->pbm; |
270 | dp = pdev_cookie->prom_node; | ||
255 | 271 | ||
256 | isa_br = kmalloc(sizeof(*isa_br), GFP_KERNEL); | 272 | isa_br = kmalloc(sizeof(*isa_br), GFP_KERNEL); |
257 | if (!isa_br) { | 273 | if (!isa_br) { |
258 | fatal_err("cannot allocate sparc_isa_bridge"); | 274 | printk(KERN_DEBUG "isa: cannot allocate sparc_isa_bridge"); |
259 | prom_halt(); | 275 | return; |
260 | } | 276 | } |
261 | 277 | ||
262 | memset(isa_br, 0, sizeof(*isa_br)); | 278 | memset(isa_br, 0, sizeof(*isa_br)); |
263 | 279 | ||
280 | isa_br->ofdev.node = dp; | ||
281 | isa_br->ofdev.dev.parent = &pdev->dev; | ||
282 | isa_br->ofdev.dev.bus = &isa_bus_type; | ||
283 | strcpy(isa_br->ofdev.dev.bus_id, dp->path_component_name); | ||
284 | |||
285 | /* Register with core */ | ||
286 | if (of_device_register(&isa_br->ofdev) != 0) { | ||
287 | printk(KERN_DEBUG "isa: device registration error for %s!\n", | ||
288 | isa_br->ofdev.dev.bus_id); | ||
289 | kfree(isa_br); | ||
290 | return; | ||
291 | } | ||
292 | |||
264 | /* Link it in. */ | 293 | /* Link it in. */ |
265 | isa_br->next = isa_chain; | 294 | isa_br->next = isa_chain; |
266 | isa_chain = isa_br; | 295 | isa_chain = isa_br; |
diff --git a/arch/sparc64/kernel/of_device.c b/arch/sparc64/kernel/of_device.c new file mode 100644 index 000000000000..566aa343aa62 --- /dev/null +++ b/arch/sparc64/kernel/of_device.c | |||
@@ -0,0 +1,279 @@ | |||
1 | #include <linux/config.h> | ||
2 | #include <linux/string.h> | ||
3 | #include <linux/kernel.h> | ||
4 | #include <linux/init.h> | ||
5 | #include <linux/module.h> | ||
6 | #include <linux/mod_devicetable.h> | ||
7 | #include <linux/slab.h> | ||
8 | |||
9 | #include <asm/errno.h> | ||
10 | #include <asm/of_device.h> | ||
11 | |||
12 | /** | ||
13 | * of_match_device - Tell if an of_device structure has a matching | ||
14 | * of_match structure | ||
15 | * @ids: array of of device match structures to search in | ||
16 | * @dev: the of device structure to match against | ||
17 | * | ||
18 | * Used by a driver to check whether an of_device present in the | ||
19 | * system is in its list of supported devices. | ||
20 | */ | ||
21 | const struct of_device_id *of_match_device(const struct of_device_id *matches, | ||
22 | const struct of_device *dev) | ||
23 | { | ||
24 | if (!dev->node) | ||
25 | return NULL; | ||
26 | while (matches->name[0] || matches->type[0] || matches->compatible[0]) { | ||
27 | int match = 1; | ||
28 | if (matches->name[0]) | ||
29 | match &= dev->node->name | ||
30 | && !strcmp(matches->name, dev->node->name); | ||
31 | if (matches->type[0]) | ||
32 | match &= dev->node->type | ||
33 | && !strcmp(matches->type, dev->node->type); | ||
34 | if (matches->compatible[0]) | ||
35 | match &= of_device_is_compatible(dev->node, | ||
36 | matches->compatible); | ||
37 | if (match) | ||
38 | return matches; | ||
39 | matches++; | ||
40 | } | ||
41 | return NULL; | ||
42 | } | ||
43 | |||
44 | static int of_platform_bus_match(struct device *dev, struct device_driver *drv) | ||
45 | { | ||
46 | struct of_device * of_dev = to_of_device(dev); | ||
47 | struct of_platform_driver * of_drv = to_of_platform_driver(drv); | ||
48 | const struct of_device_id * matches = of_drv->match_table; | ||
49 | |||
50 | if (!matches) | ||
51 | return 0; | ||
52 | |||
53 | return of_match_device(matches, of_dev) != NULL; | ||
54 | } | ||
55 | |||
56 | struct of_device *of_dev_get(struct of_device *dev) | ||
57 | { | ||
58 | struct device *tmp; | ||
59 | |||
60 | if (!dev) | ||
61 | return NULL; | ||
62 | tmp = get_device(&dev->dev); | ||
63 | if (tmp) | ||
64 | return to_of_device(tmp); | ||
65 | else | ||
66 | return NULL; | ||
67 | } | ||
68 | |||
69 | void of_dev_put(struct of_device *dev) | ||
70 | { | ||
71 | if (dev) | ||
72 | put_device(&dev->dev); | ||
73 | } | ||
74 | |||
75 | |||
76 | static int of_device_probe(struct device *dev) | ||
77 | { | ||
78 | int error = -ENODEV; | ||
79 | struct of_platform_driver *drv; | ||
80 | struct of_device *of_dev; | ||
81 | const struct of_device_id *match; | ||
82 | |||
83 | drv = to_of_platform_driver(dev->driver); | ||
84 | of_dev = to_of_device(dev); | ||
85 | |||
86 | if (!drv->probe) | ||
87 | return error; | ||
88 | |||
89 | of_dev_get(of_dev); | ||
90 | |||
91 | match = of_match_device(drv->match_table, of_dev); | ||
92 | if (match) | ||
93 | error = drv->probe(of_dev, match); | ||
94 | if (error) | ||
95 | of_dev_put(of_dev); | ||
96 | |||
97 | return error; | ||
98 | } | ||
99 | |||
100 | static int of_device_remove(struct device *dev) | ||
101 | { | ||
102 | struct of_device * of_dev = to_of_device(dev); | ||
103 | struct of_platform_driver * drv = to_of_platform_driver(dev->driver); | ||
104 | |||
105 | if (dev->driver && drv->remove) | ||
106 | drv->remove(of_dev); | ||
107 | return 0; | ||
108 | } | ||
109 | |||
110 | static int of_device_suspend(struct device *dev, pm_message_t state) | ||
111 | { | ||
112 | struct of_device * of_dev = to_of_device(dev); | ||
113 | struct of_platform_driver * drv = to_of_platform_driver(dev->driver); | ||
114 | int error = 0; | ||
115 | |||
116 | if (dev->driver && drv->suspend) | ||
117 | error = drv->suspend(of_dev, state); | ||
118 | return error; | ||
119 | } | ||
120 | |||
121 | static int of_device_resume(struct device * dev) | ||
122 | { | ||
123 | struct of_device * of_dev = to_of_device(dev); | ||
124 | struct of_platform_driver * drv = to_of_platform_driver(dev->driver); | ||
125 | int error = 0; | ||
126 | |||
127 | if (dev->driver && drv->resume) | ||
128 | error = drv->resume(of_dev); | ||
129 | return error; | ||
130 | } | ||
131 | |||
132 | #ifdef CONFIG_PCI | ||
133 | struct bus_type isa_bus_type = { | ||
134 | .name = "isa", | ||
135 | .match = of_platform_bus_match, | ||
136 | .probe = of_device_probe, | ||
137 | .remove = of_device_remove, | ||
138 | .suspend = of_device_suspend, | ||
139 | .resume = of_device_resume, | ||
140 | }; | ||
141 | |||
142 | struct bus_type ebus_bus_type = { | ||
143 | .name = "ebus", | ||
144 | .match = of_platform_bus_match, | ||
145 | .probe = of_device_probe, | ||
146 | .remove = of_device_remove, | ||
147 | .suspend = of_device_suspend, | ||
148 | .resume = of_device_resume, | ||
149 | }; | ||
150 | #endif | ||
151 | |||
152 | #ifdef CONFIG_SBUS | ||
153 | struct bus_type sbus_bus_type = { | ||
154 | .name = "sbus", | ||
155 | .match = of_platform_bus_match, | ||
156 | .probe = of_device_probe, | ||
157 | .remove = of_device_remove, | ||
158 | .suspend = of_device_suspend, | ||
159 | .resume = of_device_resume, | ||
160 | }; | ||
161 | #endif | ||
162 | |||
163 | static int __init of_bus_driver_init(void) | ||
164 | { | ||
165 | int err = 0; | ||
166 | |||
167 | #ifdef CONFIG_PCI | ||
168 | if (!err) | ||
169 | err = bus_register(&isa_bus_type); | ||
170 | if (!err) | ||
171 | err = bus_register(&ebus_bus_type); | ||
172 | #endif | ||
173 | #ifdef CONFIG_SBUS | ||
174 | if (!err) | ||
175 | err = bus_register(&sbus_bus_type); | ||
176 | #endif | ||
177 | return 0; | ||
178 | } | ||
179 | |||
180 | postcore_initcall(of_bus_driver_init); | ||
181 | |||
182 | int of_register_driver(struct of_platform_driver *drv, struct bus_type *bus) | ||
183 | { | ||
184 | /* initialize common driver fields */ | ||
185 | drv->driver.name = drv->name; | ||
186 | drv->driver.bus = bus; | ||
187 | |||
188 | /* register with core */ | ||
189 | return driver_register(&drv->driver); | ||
190 | } | ||
191 | |||
192 | void of_unregister_driver(struct of_platform_driver *drv) | ||
193 | { | ||
194 | driver_unregister(&drv->driver); | ||
195 | } | ||
196 | |||
197 | |||
198 | static ssize_t dev_show_devspec(struct device *dev, struct device_attribute *attr, char *buf) | ||
199 | { | ||
200 | struct of_device *ofdev; | ||
201 | |||
202 | ofdev = to_of_device(dev); | ||
203 | return sprintf(buf, "%s", ofdev->node->full_name); | ||
204 | } | ||
205 | |||
206 | static DEVICE_ATTR(devspec, S_IRUGO, dev_show_devspec, NULL); | ||
207 | |||
208 | /** | ||
209 | * of_release_dev - free an of device structure when all users of it are finished. | ||
210 | * @dev: device that's been disconnected | ||
211 | * | ||
212 | * Will be called only by the device core when all users of this of device are | ||
213 | * done. | ||
214 | */ | ||
215 | void of_release_dev(struct device *dev) | ||
216 | { | ||
217 | struct of_device *ofdev; | ||
218 | |||
219 | ofdev = to_of_device(dev); | ||
220 | |||
221 | kfree(ofdev); | ||
222 | } | ||
223 | |||
224 | int of_device_register(struct of_device *ofdev) | ||
225 | { | ||
226 | int rc; | ||
227 | |||
228 | BUG_ON(ofdev->node == NULL); | ||
229 | |||
230 | rc = device_register(&ofdev->dev); | ||
231 | if (rc) | ||
232 | return rc; | ||
233 | |||
234 | device_create_file(&ofdev->dev, &dev_attr_devspec); | ||
235 | |||
236 | return 0; | ||
237 | } | ||
238 | |||
239 | void of_device_unregister(struct of_device *ofdev) | ||
240 | { | ||
241 | device_remove_file(&ofdev->dev, &dev_attr_devspec); | ||
242 | device_unregister(&ofdev->dev); | ||
243 | } | ||
244 | |||
245 | struct of_device* of_platform_device_create(struct device_node *np, | ||
246 | const char *bus_id, | ||
247 | struct device *parent, | ||
248 | struct bus_type *bus) | ||
249 | { | ||
250 | struct of_device *dev; | ||
251 | |||
252 | dev = kmalloc(sizeof(*dev), GFP_KERNEL); | ||
253 | if (!dev) | ||
254 | return NULL; | ||
255 | memset(dev, 0, sizeof(*dev)); | ||
256 | |||
257 | dev->dev.parent = parent; | ||
258 | dev->dev.bus = bus; | ||
259 | dev->dev.release = of_release_dev; | ||
260 | |||
261 | strlcpy(dev->dev.bus_id, bus_id, BUS_ID_SIZE); | ||
262 | |||
263 | if (of_device_register(dev) != 0) { | ||
264 | kfree(dev); | ||
265 | return NULL; | ||
266 | } | ||
267 | |||
268 | return dev; | ||
269 | } | ||
270 | |||
271 | EXPORT_SYMBOL(of_match_device); | ||
272 | EXPORT_SYMBOL(of_register_driver); | ||
273 | EXPORT_SYMBOL(of_unregister_driver); | ||
274 | EXPORT_SYMBOL(of_device_register); | ||
275 | EXPORT_SYMBOL(of_device_unregister); | ||
276 | EXPORT_SYMBOL(of_dev_get); | ||
277 | EXPORT_SYMBOL(of_dev_put); | ||
278 | EXPORT_SYMBOL(of_platform_device_create); | ||
279 | EXPORT_SYMBOL(of_release_dev); | ||
diff --git a/arch/sparc64/kernel/power.c b/arch/sparc64/kernel/power.c index 75159a7843f1..9496c7734014 100644 --- a/arch/sparc64/kernel/power.c +++ b/arch/sparc64/kernel/power.c | |||
@@ -115,66 +115,15 @@ static int __init has_button_interrupt(unsigned int irq, struct device_node *dp) | |||
115 | return 1; | 115 | return 1; |
116 | } | 116 | } |
117 | 117 | ||
118 | static int __init power_probe_ebus(struct resource **resp, unsigned int *irq_p, struct device_node **prom_node_p) | 118 | static void __devinit power_probe_common(struct of_device *dev, struct resource *res, unsigned int irq) |
119 | { | 119 | { |
120 | struct linux_ebus *ebus; | ||
121 | struct linux_ebus_device *edev; | ||
122 | |||
123 | for_each_ebus(ebus) { | ||
124 | for_each_ebusdev(edev, ebus) { | ||
125 | if (!strcmp(edev->prom_node->name, "power")) { | ||
126 | *resp = &edev->resource[0]; | ||
127 | *irq_p = edev->irqs[0]; | ||
128 | *prom_node_p = edev->prom_node; | ||
129 | return 0; | ||
130 | } | ||
131 | } | ||
132 | } | ||
133 | return -ENODEV; | ||
134 | } | ||
135 | |||
136 | static int __init power_probe_isa(struct resource **resp, unsigned int *irq_p, struct device_node **prom_node_p) | ||
137 | { | ||
138 | struct sparc_isa_bridge *isa_bus; | ||
139 | struct sparc_isa_device *isa_dev; | ||
140 | |||
141 | for_each_isa(isa_bus) { | ||
142 | for_each_isadev(isa_dev, isa_bus) { | ||
143 | if (!strcmp(isa_dev->prom_node->name, "power")) { | ||
144 | *resp = &isa_dev->resource; | ||
145 | *irq_p = isa_dev->irq; | ||
146 | *prom_node_p = isa_dev->prom_node; | ||
147 | return 0; | ||
148 | } | ||
149 | } | ||
150 | } | ||
151 | return -ENODEV; | ||
152 | } | ||
153 | |||
154 | void __init power_init(void) | ||
155 | { | ||
156 | struct resource *res = NULL; | ||
157 | unsigned int irq; | ||
158 | struct device_node *dp; | ||
159 | static int invoked; | ||
160 | |||
161 | if (invoked) | ||
162 | return; | ||
163 | invoked = 1; | ||
164 | |||
165 | if (!power_probe_ebus(&res, &irq, &dp)) | ||
166 | goto found; | ||
167 | |||
168 | if (!power_probe_isa(&res, &irq, &dp)) | ||
169 | goto found; | ||
170 | |||
171 | return; | ||
172 | |||
173 | found: | ||
174 | power_reg = ioremap(res->start, 0x4); | 120 | power_reg = ioremap(res->start, 0x4); |
121 | |||
175 | printk("power: Control reg at %p ... ", power_reg); | 122 | printk("power: Control reg at %p ... ", power_reg); |
123 | |||
176 | poweroff_method = machine_halt; /* able to use the standard halt */ | 124 | poweroff_method = machine_halt; /* able to use the standard halt */ |
177 | if (has_button_interrupt(irq, dp)) { | 125 | |
126 | if (has_button_interrupt(irq, dev->node)) { | ||
178 | if (kernel_thread(powerd, NULL, CLONE_FS) < 0) { | 127 | if (kernel_thread(powerd, NULL, CLONE_FS) < 0) { |
179 | printk("Failed to start power daemon.\n"); | 128 | printk("Failed to start power daemon.\n"); |
180 | return; | 129 | return; |
@@ -188,4 +137,52 @@ found: | |||
188 | printk("not using powerd.\n"); | 137 | printk("not using powerd.\n"); |
189 | } | 138 | } |
190 | } | 139 | } |
140 | |||
141 | static struct of_device_id power_match[] = { | ||
142 | { | ||
143 | .name = "power", | ||
144 | }, | ||
145 | {}, | ||
146 | }; | ||
147 | |||
148 | static int __devinit ebus_power_probe(struct of_device *dev, const struct of_device_id *match) | ||
149 | { | ||
150 | struct linux_ebus_device *edev = to_ebus_device(&dev->dev); | ||
151 | struct resource *res = &edev->resource[0]; | ||
152 | unsigned int irq = edev->irqs[0]; | ||
153 | |||
154 | power_probe_common(dev, res,irq); | ||
155 | |||
156 | return 0; | ||
157 | } | ||
158 | |||
159 | static struct of_platform_driver ebus_power_driver = { | ||
160 | .name = "power", | ||
161 | .match_table = power_match, | ||
162 | .probe = ebus_power_probe, | ||
163 | }; | ||
164 | |||
165 | static int __devinit isa_power_probe(struct of_device *dev, const struct of_device_id *match) | ||
166 | { | ||
167 | struct sparc_isa_device *idev = to_isa_device(&dev->dev); | ||
168 | struct resource *res = &idev->resource; | ||
169 | unsigned int irq = idev->irq; | ||
170 | |||
171 | power_probe_common(dev, res,irq); | ||
172 | |||
173 | return 0; | ||
174 | } | ||
175 | |||
176 | static struct of_platform_driver isa_power_driver = { | ||
177 | .name = "power", | ||
178 | .match_table = power_match, | ||
179 | .probe = isa_power_probe, | ||
180 | }; | ||
181 | |||
182 | void __init power_init(void) | ||
183 | { | ||
184 | of_register_driver(&ebus_power_driver, &ebus_bus_type); | ||
185 | of_register_driver(&isa_power_driver, &isa_bus_type); | ||
186 | return; | ||
187 | } | ||
191 | #endif /* CONFIG_PCI */ | 188 | #endif /* CONFIG_PCI */ |
diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig index 4bad588d0e5d..a6dfc7455733 100644 --- a/drivers/input/misc/Kconfig +++ b/drivers/input/misc/Kconfig | |||
@@ -26,7 +26,7 @@ config INPUT_PCSPKR | |||
26 | 26 | ||
27 | config INPUT_SPARCSPKR | 27 | config INPUT_SPARCSPKR |
28 | tristate "SPARC Speaker support" | 28 | tristate "SPARC Speaker support" |
29 | depends on PCI && SPARC | 29 | depends on PCI && SPARC64 |
30 | help | 30 | help |
31 | Say Y here if you want the standard Speaker on Sparc PCI systems | 31 | Say Y here if you want the standard Speaker on Sparc PCI systems |
32 | to be used for bells and whistles. | 32 | to be used for bells and whistles. |
diff --git a/drivers/input/misc/sparcspkr.c b/drivers/input/misc/sparcspkr.c index ed95dc9420dd..42c11fbf3c79 100644 --- a/drivers/input/misc/sparcspkr.c +++ b/drivers/input/misc/sparcspkr.c | |||
@@ -2,7 +2,7 @@ | |||
2 | * Driver for PC-speaker like devices found on various Sparc systems. | 2 | * Driver for PC-speaker like devices found on various Sparc systems. |
3 | * | 3 | * |
4 | * Copyright (c) 2002 Vojtech Pavlik | 4 | * Copyright (c) 2002 Vojtech Pavlik |
5 | * Copyright (c) 2002 David S. Miller (davem@redhat.com) | 5 | * Copyright (c) 2002, 2006 David S. Miller (davem@davemloft.net) |
6 | */ | 6 | */ |
7 | #include <linux/config.h> | 7 | #include <linux/config.h> |
8 | #include <linux/kernel.h> | 8 | #include <linux/kernel.h> |
@@ -13,21 +13,23 @@ | |||
13 | 13 | ||
14 | #include <asm/io.h> | 14 | #include <asm/io.h> |
15 | #include <asm/ebus.h> | 15 | #include <asm/ebus.h> |
16 | #ifdef CONFIG_SPARC64 | ||
17 | #include <asm/isa.h> | 16 | #include <asm/isa.h> |
18 | #endif | ||
19 | 17 | ||
20 | MODULE_AUTHOR("David S. Miller <davem@redhat.com>"); | 18 | MODULE_AUTHOR("David S. Miller <davem@davemloft.net>"); |
21 | MODULE_DESCRIPTION("Sparc Speaker beeper driver"); | 19 | MODULE_DESCRIPTION("Sparc Speaker beeper driver"); |
22 | MODULE_LICENSE("GPL"); | 20 | MODULE_LICENSE("GPL"); |
23 | 21 | ||
24 | const char *beep_name; | 22 | struct sparcspkr_state { |
25 | static unsigned long beep_iobase; | 23 | const char *name; |
26 | static int (*beep_event)(struct input_dev *dev, unsigned int type, unsigned int code, int value); | 24 | unsigned long iobase; |
27 | static DEFINE_SPINLOCK(beep_lock); | 25 | int (*event)(struct input_dev *dev, unsigned int type, unsigned int code, int value); |
26 | spinlock_t lock; | ||
27 | struct input_dev *input_dev; | ||
28 | }; | ||
28 | 29 | ||
29 | static int ebus_spkr_event(struct input_dev *dev, unsigned int type, unsigned int code, int value) | 30 | static int ebus_spkr_event(struct input_dev *dev, unsigned int type, unsigned int code, int value) |
30 | { | 31 | { |
32 | struct sparcspkr_state *state = dev_get_drvdata(dev->cdev.dev); | ||
31 | unsigned int count = 0; | 33 | unsigned int count = 0; |
32 | unsigned long flags; | 34 | unsigned long flags; |
33 | 35 | ||
@@ -43,24 +45,24 @@ static int ebus_spkr_event(struct input_dev *dev, unsigned int type, unsigned in | |||
43 | if (value > 20 && value < 32767) | 45 | if (value > 20 && value < 32767) |
44 | count = 1193182 / value; | 46 | count = 1193182 / value; |
45 | 47 | ||
46 | spin_lock_irqsave(&beep_lock, flags); | 48 | spin_lock_irqsave(&state->lock, flags); |
47 | 49 | ||
48 | /* EBUS speaker only has on/off state, the frequency does not | 50 | /* EBUS speaker only has on/off state, the frequency does not |
49 | * appear to be programmable. | 51 | * appear to be programmable. |
50 | */ | 52 | */ |
51 | if (beep_iobase & 0x2UL) | 53 | if (state->iobase & 0x2UL) |
52 | outb(!!count, beep_iobase); | 54 | outb(!!count, state->iobase); |
53 | else | 55 | else |
54 | outl(!!count, beep_iobase); | 56 | outl(!!count, state->iobase); |
55 | 57 | ||
56 | spin_unlock_irqrestore(&beep_lock, flags); | 58 | spin_unlock_irqrestore(&state->lock, flags); |
57 | 59 | ||
58 | return 0; | 60 | return 0; |
59 | } | 61 | } |
60 | 62 | ||
61 | #ifdef CONFIG_SPARC64 | ||
62 | static int isa_spkr_event(struct input_dev *dev, unsigned int type, unsigned int code, int value) | 63 | static int isa_spkr_event(struct input_dev *dev, unsigned int type, unsigned int code, int value) |
63 | { | 64 | { |
65 | struct sparcspkr_state *state = dev_get_drvdata(dev->cdev.dev); | ||
64 | unsigned int count = 0; | 66 | unsigned int count = 0; |
65 | unsigned long flags; | 67 | unsigned long flags; |
66 | 68 | ||
@@ -76,29 +78,29 @@ static int isa_spkr_event(struct input_dev *dev, unsigned int type, unsigned int | |||
76 | if (value > 20 && value < 32767) | 78 | if (value > 20 && value < 32767) |
77 | count = 1193182 / value; | 79 | count = 1193182 / value; |
78 | 80 | ||
79 | spin_lock_irqsave(&beep_lock, flags); | 81 | spin_lock_irqsave(&state->lock, flags); |
80 | 82 | ||
81 | if (count) { | 83 | if (count) { |
82 | /* enable counter 2 */ | 84 | /* enable counter 2 */ |
83 | outb(inb(beep_iobase + 0x61) | 3, beep_iobase + 0x61); | 85 | outb(inb(state->iobase + 0x61) | 3, state->iobase + 0x61); |
84 | /* set command for counter 2, 2 byte write */ | 86 | /* set command for counter 2, 2 byte write */ |
85 | outb(0xB6, beep_iobase + 0x43); | 87 | outb(0xB6, state->iobase + 0x43); |
86 | /* select desired HZ */ | 88 | /* select desired HZ */ |
87 | outb(count & 0xff, beep_iobase + 0x42); | 89 | outb(count & 0xff, state->iobase + 0x42); |
88 | outb((count >> 8) & 0xff, beep_iobase + 0x42); | 90 | outb((count >> 8) & 0xff, state->iobase + 0x42); |
89 | } else { | 91 | } else { |
90 | /* disable counter 2 */ | 92 | /* disable counter 2 */ |
91 | outb(inb_p(beep_iobase + 0x61) & 0xFC, beep_iobase + 0x61); | 93 | outb(inb_p(state->iobase + 0x61) & 0xFC, state->iobase + 0x61); |
92 | } | 94 | } |
93 | 95 | ||
94 | spin_unlock_irqrestore(&beep_lock, flags); | 96 | spin_unlock_irqrestore(&state->lock, flags); |
95 | 97 | ||
96 | return 0; | 98 | return 0; |
97 | } | 99 | } |
98 | #endif | ||
99 | 100 | ||
100 | static int __devinit sparcspkr_probe(struct platform_device *dev) | 101 | static int __devinit sparcspkr_probe(struct device *dev) |
101 | { | 102 | { |
103 | struct sparcspkr_state *state = dev_get_drvdata(dev); | ||
102 | struct input_dev *input_dev; | 104 | struct input_dev *input_dev; |
103 | int error; | 105 | int error; |
104 | 106 | ||
@@ -106,18 +108,18 @@ static int __devinit sparcspkr_probe(struct platform_device *dev) | |||
106 | if (!input_dev) | 108 | if (!input_dev) |
107 | return -ENOMEM; | 109 | return -ENOMEM; |
108 | 110 | ||
109 | input_dev->name = beep_name; | 111 | input_dev->name = state->name; |
110 | input_dev->phys = "sparc/input0"; | 112 | input_dev->phys = "sparc/input0"; |
111 | input_dev->id.bustype = BUS_ISA; | 113 | input_dev->id.bustype = BUS_ISA; |
112 | input_dev->id.vendor = 0x001f; | 114 | input_dev->id.vendor = 0x001f; |
113 | input_dev->id.product = 0x0001; | 115 | input_dev->id.product = 0x0001; |
114 | input_dev->id.version = 0x0100; | 116 | input_dev->id.version = 0x0100; |
115 | input_dev->cdev.dev = &dev->dev; | 117 | input_dev->cdev.dev = dev; |
116 | 118 | ||
117 | input_dev->evbit[0] = BIT(EV_SND); | 119 | input_dev->evbit[0] = BIT(EV_SND); |
118 | input_dev->sndbit[0] = BIT(SND_BELL) | BIT(SND_TONE); | 120 | input_dev->sndbit[0] = BIT(SND_BELL) | BIT(SND_TONE); |
119 | 121 | ||
120 | input_dev->event = beep_event; | 122 | input_dev->event = state->event; |
121 | 123 | ||
122 | error = input_register_device(input_dev); | 124 | error = input_register_device(input_dev); |
123 | if (error) { | 125 | if (error) { |
@@ -125,111 +127,137 @@ static int __devinit sparcspkr_probe(struct platform_device *dev) | |||
125 | return error; | 127 | return error; |
126 | } | 128 | } |
127 | 129 | ||
128 | platform_set_drvdata(dev, input_dev); | 130 | state->input_dev = input_dev; |
129 | 131 | ||
130 | return 0; | 132 | return 0; |
131 | } | 133 | } |
132 | 134 | ||
133 | static int __devexit sparcspkr_remove(struct platform_device *dev) | 135 | static int __devexit sparcspkr_remove(struct of_device *dev) |
134 | { | 136 | { |
135 | struct input_dev *input_dev = platform_get_drvdata(dev); | 137 | struct sparcspkr_state *state = dev_get_drvdata(&dev->dev); |
138 | struct input_dev *input_dev = state->input_dev; | ||
136 | 139 | ||
137 | input_unregister_device(input_dev); | ||
138 | platform_set_drvdata(dev, NULL); | ||
139 | /* turn off the speaker */ | 140 | /* turn off the speaker */ |
140 | beep_event(NULL, EV_SND, SND_BELL, 0); | 141 | state->event(input_dev, EV_SND, SND_BELL, 0); |
142 | |||
143 | input_unregister_device(input_dev); | ||
144 | |||
145 | dev_set_drvdata(&dev->dev, NULL); | ||
146 | kfree(state); | ||
141 | 147 | ||
142 | return 0; | 148 | return 0; |
143 | } | 149 | } |
144 | 150 | ||
145 | static void sparcspkr_shutdown(struct platform_device *dev) | 151 | static int sparcspkr_shutdown(struct of_device *dev) |
146 | { | 152 | { |
153 | struct sparcspkr_state *state = dev_get_drvdata(&dev->dev); | ||
154 | struct input_dev *input_dev = state->input_dev; | ||
155 | |||
147 | /* turn off the speaker */ | 156 | /* turn off the speaker */ |
148 | beep_event(NULL, EV_SND, SND_BELL, 0); | 157 | state->event(input_dev, EV_SND, SND_BELL, 0); |
158 | |||
159 | return 0; | ||
160 | } | ||
161 | |||
162 | static int __devinit ebus_beep_probe(struct of_device *dev, const struct of_device_id *match) | ||
163 | { | ||
164 | struct linux_ebus_device *edev = to_ebus_device(&dev->dev); | ||
165 | struct sparcspkr_state *state; | ||
166 | int err; | ||
167 | |||
168 | state = kzalloc(sizeof(*state), GFP_KERNEL); | ||
169 | if (!state) | ||
170 | return -ENOMEM; | ||
171 | |||
172 | state->name = "Sparc EBUS Speaker"; | ||
173 | state->iobase = edev->resource[0].start; | ||
174 | state->event = ebus_spkr_event; | ||
175 | spin_lock_init(&state->lock); | ||
176 | |||
177 | dev_set_drvdata(&dev->dev, state); | ||
178 | |||
179 | err = sparcspkr_probe(&dev->dev); | ||
180 | if (err) { | ||
181 | dev_set_drvdata(&dev->dev, NULL); | ||
182 | kfree(state); | ||
183 | } | ||
184 | |||
185 | return 0; | ||
149 | } | 186 | } |
150 | 187 | ||
151 | static struct platform_driver sparcspkr_platform_driver = { | 188 | static struct of_device_id ebus_beep_match[] = { |
152 | .driver = { | 189 | { |
153 | .name = "sparcspkr", | 190 | .name = "beep", |
154 | .owner = THIS_MODULE, | ||
155 | }, | 191 | }, |
156 | .probe = sparcspkr_probe, | 192 | {}, |
157 | .remove = __devexit_p(sparcspkr_remove), | ||
158 | .shutdown = sparcspkr_shutdown, | ||
159 | }; | 193 | }; |
160 | 194 | ||
161 | static struct platform_device *sparcspkr_platform_device; | 195 | static struct of_platform_driver ebus_beep_driver = { |
196 | .name = "beep", | ||
197 | .match_table = ebus_beep_match, | ||
198 | .probe = ebus_beep_probe, | ||
199 | .remove = sparcspkr_remove, | ||
200 | .shutdown = sparcspkr_shutdown, | ||
201 | }; | ||
162 | 202 | ||
163 | static int __init sparcspkr_drv_init(void) | 203 | static int __devinit isa_beep_probe(struct of_device *dev, const struct of_device_id *match) |
164 | { | 204 | { |
165 | int error; | 205 | struct sparc_isa_device *idev = to_isa_device(&dev->dev); |
206 | struct sparcspkr_state *state; | ||
207 | int err; | ||
166 | 208 | ||
167 | error = platform_driver_register(&sparcspkr_platform_driver); | 209 | state = kzalloc(sizeof(*state), GFP_KERNEL); |
168 | if (error) | 210 | if (!state) |
169 | return error; | 211 | return -ENOMEM; |
170 | 212 | ||
171 | sparcspkr_platform_device = platform_device_alloc("sparcspkr", -1); | 213 | state->name = "Sparc ISA Speaker"; |
172 | if (!sparcspkr_platform_device) { | 214 | state->iobase = idev->resource.start; |
173 | error = -ENOMEM; | 215 | state->event = isa_spkr_event; |
174 | goto err_unregister_driver; | 216 | spin_lock_init(&state->lock); |
175 | } | 217 | |
218 | dev_set_drvdata(&dev->dev, state); | ||
176 | 219 | ||
177 | error = platform_device_add(sparcspkr_platform_device); | 220 | err = sparcspkr_probe(&dev->dev); |
178 | if (error) | 221 | if (err) { |
179 | goto err_free_device; | 222 | dev_set_drvdata(&dev->dev, NULL); |
223 | kfree(state); | ||
224 | } | ||
180 | 225 | ||
181 | return 0; | 226 | return 0; |
227 | } | ||
182 | 228 | ||
183 | err_free_device: | 229 | static struct of_device_id isa_beep_match[] = { |
184 | platform_device_put(sparcspkr_platform_device); | 230 | { |
185 | err_unregister_driver: | 231 | .name = "dma", |
186 | platform_driver_unregister(&sparcspkr_platform_driver); | 232 | }, |
233 | {}, | ||
234 | }; | ||
187 | 235 | ||
188 | return error; | 236 | static struct of_platform_driver isa_beep_driver = { |
189 | } | 237 | .name = "beep", |
238 | .match_table = isa_beep_match, | ||
239 | .probe = isa_beep_probe, | ||
240 | .remove = sparcspkr_remove, | ||
241 | .shutdown = sparcspkr_shutdown, | ||
242 | }; | ||
190 | 243 | ||
191 | static int __init sparcspkr_init(void) | 244 | static int __init sparcspkr_init(void) |
192 | { | 245 | { |
193 | struct linux_ebus *ebus; | 246 | int err = of_register_driver(&ebus_beep_driver, &ebus_bus_type); |
194 | struct linux_ebus_device *edev; | 247 | |
195 | #ifdef CONFIG_SPARC64 | 248 | if (!err) { |
196 | struct sparc_isa_bridge *isa_br; | 249 | err = of_register_driver(&isa_beep_driver, &isa_bus_type); |
197 | struct sparc_isa_device *isa_dev; | 250 | if (err) |
198 | #endif | 251 | of_unregister_driver(&ebus_beep_driver); |
199 | |||
200 | for_each_ebus(ebus) { | ||
201 | for_each_ebusdev(edev, ebus) { | ||
202 | if (!strcmp(edev->prom_node->name, "beep")) { | ||
203 | beep_name = "Sparc EBUS Speaker"; | ||
204 | beep_event = ebus_spkr_event; | ||
205 | beep_iobase = edev->resource[0].start; | ||
206 | return sparcspkr_drv_init(); | ||
207 | } | ||
208 | } | ||
209 | } | ||
210 | #ifdef CONFIG_SPARC64 | ||
211 | for_each_isa(isa_br) { | ||
212 | for_each_isadev(isa_dev, isa_br) { | ||
213 | /* A hack, the beep device's base lives in | ||
214 | * the DMA isa node. | ||
215 | */ | ||
216 | if (!strcmp(isa_dev->prom_node->name, "dma")) { | ||
217 | beep_name = "Sparc ISA Speaker"; | ||
218 | beep_event = isa_spkr_event, | ||
219 | beep_iobase = isa_dev->resource.start; | ||
220 | return sparcspkr_drv_init(); | ||
221 | } | ||
222 | } | ||
223 | } | 252 | } |
224 | #endif | ||
225 | 253 | ||
226 | return -ENODEV; | 254 | return err; |
227 | } | 255 | } |
228 | 256 | ||
229 | static void __exit sparcspkr_exit(void) | 257 | static void __exit sparcspkr_exit(void) |
230 | { | 258 | { |
231 | platform_device_unregister(sparcspkr_platform_device); | 259 | of_unregister_driver(&ebus_beep_driver); |
232 | platform_driver_unregister(&sparcspkr_platform_driver); | 260 | of_unregister_driver(&isa_beep_driver); |
233 | } | 261 | } |
234 | 262 | ||
235 | module_init(sparcspkr_init); | 263 | module_init(sparcspkr_init); |
diff --git a/include/asm-sparc64/ebus.h b/include/asm-sparc64/ebus.h index 545882bd3563..a4afe9d5703a 100644 --- a/include/asm-sparc64/ebus.h +++ b/include/asm-sparc64/ebus.h | |||
@@ -11,6 +11,7 @@ | |||
11 | #include <asm/pbm.h> | 11 | #include <asm/pbm.h> |
12 | #include <asm/oplib.h> | 12 | #include <asm/oplib.h> |
13 | #include <asm/prom.h> | 13 | #include <asm/prom.h> |
14 | #include <asm/of_device.h> | ||
14 | 15 | ||
15 | struct linux_ebus_child { | 16 | struct linux_ebus_child { |
16 | struct linux_ebus_child *next; | 17 | struct linux_ebus_child *next; |
@@ -24,6 +25,7 @@ struct linux_ebus_child { | |||
24 | }; | 25 | }; |
25 | 26 | ||
26 | struct linux_ebus_device { | 27 | struct linux_ebus_device { |
28 | struct of_device ofdev; | ||
27 | struct linux_ebus_device *next; | 29 | struct linux_ebus_device *next; |
28 | struct linux_ebus_child *children; | 30 | struct linux_ebus_child *children; |
29 | struct linux_ebus *bus; | 31 | struct linux_ebus *bus; |
@@ -33,8 +35,10 @@ struct linux_ebus_device { | |||
33 | unsigned int irqs[PROMINTR_MAX]; | 35 | unsigned int irqs[PROMINTR_MAX]; |
34 | int num_irqs; | 36 | int num_irqs; |
35 | }; | 37 | }; |
38 | #define to_ebus_device(d) container_of(d, struct linux_ebus_device, ofdev.dev) | ||
36 | 39 | ||
37 | struct linux_ebus { | 40 | struct linux_ebus { |
41 | struct of_device ofdev; | ||
38 | struct linux_ebus *next; | 42 | struct linux_ebus *next; |
39 | struct linux_ebus_device *devices; | 43 | struct linux_ebus_device *devices; |
40 | struct pci_pbm_info *parent; | 44 | struct pci_pbm_info *parent; |
@@ -43,6 +47,7 @@ struct linux_ebus { | |||
43 | int is_rio; | 47 | int is_rio; |
44 | struct device_node *prom_node; | 48 | struct device_node *prom_node; |
45 | }; | 49 | }; |
50 | #define to_ebus(d) container_of(d, struct linux_ebus, ofdev.dev) | ||
46 | 51 | ||
47 | struct ebus_dma_info { | 52 | struct ebus_dma_info { |
48 | spinlock_t lock; | 53 | spinlock_t lock; |
diff --git a/include/asm-sparc64/isa.h b/include/asm-sparc64/isa.h index 2e7fb18ec1be..d9728b9031fc 100644 --- a/include/asm-sparc64/isa.h +++ b/include/asm-sparc64/isa.h | |||
@@ -10,10 +10,12 @@ | |||
10 | #include <asm/pbm.h> | 10 | #include <asm/pbm.h> |
11 | #include <asm/oplib.h> | 11 | #include <asm/oplib.h> |
12 | #include <asm/prom.h> | 12 | #include <asm/prom.h> |
13 | #include <asm/of_device.h> | ||
13 | 14 | ||
14 | struct sparc_isa_bridge; | 15 | struct sparc_isa_bridge; |
15 | 16 | ||
16 | struct sparc_isa_device { | 17 | struct sparc_isa_device { |
18 | struct of_device ofdev; | ||
17 | struct sparc_isa_device *next; | 19 | struct sparc_isa_device *next; |
18 | struct sparc_isa_device *child; | 20 | struct sparc_isa_device *child; |
19 | struct sparc_isa_bridge *bus; | 21 | struct sparc_isa_bridge *bus; |
@@ -21,8 +23,10 @@ struct sparc_isa_device { | |||
21 | struct resource resource; | 23 | struct resource resource; |
22 | unsigned int irq; | 24 | unsigned int irq; |
23 | }; | 25 | }; |
26 | #define to_isa_device(d) container_of(d, struct sparc_isa_device, ofdev.dev) | ||
24 | 27 | ||
25 | struct sparc_isa_bridge { | 28 | struct sparc_isa_bridge { |
29 | struct of_device ofdev; | ||
26 | struct sparc_isa_bridge *next; | 30 | struct sparc_isa_bridge *next; |
27 | struct sparc_isa_device *devices; | 31 | struct sparc_isa_device *devices; |
28 | struct pci_pbm_info *parent; | 32 | struct pci_pbm_info *parent; |
@@ -30,6 +34,7 @@ struct sparc_isa_bridge { | |||
30 | int index; | 34 | int index; |
31 | struct device_node *prom_node; | 35 | struct device_node *prom_node; |
32 | }; | 36 | }; |
37 | #define to_isa_bridge(d) container_of(d, struct sparc_isa_bridge, ofdev.dev) | ||
33 | 38 | ||
34 | extern struct sparc_isa_bridge *isa_chain; | 39 | extern struct sparc_isa_bridge *isa_chain; |
35 | 40 | ||
diff --git a/include/asm-sparc64/of_device.h b/include/asm-sparc64/of_device.h new file mode 100644 index 000000000000..ceea825899ce --- /dev/null +++ b/include/asm-sparc64/of_device.h | |||
@@ -0,0 +1,64 @@ | |||
1 | #ifndef _ASM_SPARC64_OF_DEVICE_H | ||
2 | #define _ASM_SPARC64_OF_DEVICE_H | ||
3 | #ifdef __KERNEL__ | ||
4 | |||
5 | #include <linux/device.h> | ||
6 | #include <linux/mod_devicetable.h> | ||
7 | #include <asm/prom.h> | ||
8 | |||
9 | extern struct bus_type isa_bus_type; | ||
10 | extern struct bus_type ebus_bus_type; | ||
11 | extern struct bus_type sbus_bus_type; | ||
12 | |||
13 | /* | ||
14 | * The of_device is a kind of "base class" that is a superset of | ||
15 | * struct device for use by devices attached to an OF node and | ||
16 | * probed using OF properties. | ||
17 | */ | ||
18 | struct of_device | ||
19 | { | ||
20 | struct device_node *node; /* OF device node */ | ||
21 | struct device dev; /* Generic device interface */ | ||
22 | }; | ||
23 | #define to_of_device(d) container_of(d, struct of_device, dev) | ||
24 | |||
25 | extern const struct of_device_id *of_match_device( | ||
26 | const struct of_device_id *matches, const struct of_device *dev); | ||
27 | |||
28 | extern struct of_device *of_dev_get(struct of_device *dev); | ||
29 | extern void of_dev_put(struct of_device *dev); | ||
30 | |||
31 | /* | ||
32 | * An of_platform_driver driver is attached to a basic of_device on | ||
33 | * the ISA, EBUS, and SBUS busses on sparc64. | ||
34 | */ | ||
35 | struct of_platform_driver | ||
36 | { | ||
37 | char *name; | ||
38 | struct of_device_id *match_table; | ||
39 | struct module *owner; | ||
40 | |||
41 | int (*probe)(struct of_device* dev, const struct of_device_id *match); | ||
42 | int (*remove)(struct of_device* dev); | ||
43 | |||
44 | int (*suspend)(struct of_device* dev, pm_message_t state); | ||
45 | int (*resume)(struct of_device* dev); | ||
46 | int (*shutdown)(struct of_device* dev); | ||
47 | |||
48 | struct device_driver driver; | ||
49 | }; | ||
50 | #define to_of_platform_driver(drv) container_of(drv,struct of_platform_driver, driver) | ||
51 | |||
52 | extern int of_register_driver(struct of_platform_driver *drv, | ||
53 | struct bus_type *bus); | ||
54 | extern void of_unregister_driver(struct of_platform_driver *drv); | ||
55 | extern int of_device_register(struct of_device *ofdev); | ||
56 | extern void of_device_unregister(struct of_device *ofdev); | ||
57 | extern struct of_device *of_platform_device_create(struct device_node *np, | ||
58 | const char *bus_id, | ||
59 | struct device *parent, | ||
60 | struct bus_type *bus); | ||
61 | extern void of_release_dev(struct device *dev); | ||
62 | |||
63 | #endif /* __KERNEL__ */ | ||
64 | #endif /* _ASM_POWERPC_OF_DEVICE_H */ | ||