diff options
Diffstat (limited to 'drivers/of')
-rw-r--r-- | drivers/of/Kconfig | 5 | ||||
-rw-r--r-- | drivers/of/Makefile | 1 | ||||
-rw-r--r-- | drivers/of/address.c | 2 | ||||
-rw-r--r-- | drivers/of/base.c | 4 | ||||
-rw-r--r-- | drivers/of/device.c | 27 | ||||
-rw-r--r-- | drivers/of/fdt.c | 2 | ||||
-rw-r--r-- | drivers/of/irq.c | 39 | ||||
-rw-r--r-- | drivers/of/of_i2c.c | 1 | ||||
-rw-r--r-- | drivers/of/pdt.c | 276 | ||||
-rw-r--r-- | drivers/of/platform.c | 34 |
10 files changed, 347 insertions, 44 deletions
diff --git a/drivers/of/Kconfig b/drivers/of/Kconfig index 6acbff389ab6..aa675ebd8eb3 100644 --- a/drivers/of/Kconfig +++ b/drivers/of/Kconfig | |||
@@ -4,7 +4,7 @@ config DTC | |||
4 | config OF | 4 | config OF |
5 | bool | 5 | bool |
6 | 6 | ||
7 | menu "Flattened Device Tree and Open Firmware support" | 7 | menu "Device Tree and Open Firmware support" |
8 | depends on OF | 8 | depends on OF |
9 | 9 | ||
10 | config PROC_DEVICETREE | 10 | config PROC_DEVICETREE |
@@ -19,6 +19,9 @@ config OF_FLATTREE | |||
19 | bool | 19 | bool |
20 | select DTC | 20 | select DTC |
21 | 21 | ||
22 | config OF_PROMTREE | ||
23 | bool | ||
24 | |||
22 | config OF_DYNAMIC | 25 | config OF_DYNAMIC |
23 | def_bool y | 26 | def_bool y |
24 | depends on PPC_OF | 27 | depends on PPC_OF |
diff --git a/drivers/of/Makefile b/drivers/of/Makefile index 0052c405463a..7888155bea08 100644 --- a/drivers/of/Makefile +++ b/drivers/of/Makefile | |||
@@ -1,5 +1,6 @@ | |||
1 | obj-y = base.o | 1 | obj-y = base.o |
2 | obj-$(CONFIG_OF_FLATTREE) += fdt.o | 2 | obj-$(CONFIG_OF_FLATTREE) += fdt.o |
3 | obj-$(CONFIG_OF_PROMTREE) += pdt.o | ||
3 | obj-$(CONFIG_OF_ADDRESS) += address.o | 4 | obj-$(CONFIG_OF_ADDRESS) += address.o |
4 | obj-$(CONFIG_OF_IRQ) += irq.o | 5 | obj-$(CONFIG_OF_IRQ) += irq.o |
5 | obj-$(CONFIG_OF_DEVICE) += device.o platform.o | 6 | obj-$(CONFIG_OF_DEVICE) += device.o platform.o |
diff --git a/drivers/of/address.c b/drivers/of/address.c index fcadb726d4f9..3a1c7e70b192 100644 --- a/drivers/of/address.c +++ b/drivers/of/address.c | |||
@@ -163,7 +163,7 @@ static int of_bus_pci_translate(u32 *addr, u64 offset, int na) | |||
163 | const u32 *of_get_pci_address(struct device_node *dev, int bar_no, u64 *size, | 163 | const u32 *of_get_pci_address(struct device_node *dev, int bar_no, u64 *size, |
164 | unsigned int *flags) | 164 | unsigned int *flags) |
165 | { | 165 | { |
166 | const u32 *prop; | 166 | const __be32 *prop; |
167 | unsigned int psize; | 167 | unsigned int psize; |
168 | struct device_node *parent; | 168 | struct device_node *parent; |
169 | struct of_bus *bus; | 169 | struct of_bus *bus; |
diff --git a/drivers/of/base.c b/drivers/of/base.c index aa805250de76..710b53bfac6d 100644 --- a/drivers/of/base.c +++ b/drivers/of/base.c | |||
@@ -33,7 +33,7 @@ DEFINE_RWLOCK(devtree_lock); | |||
33 | 33 | ||
34 | int of_n_addr_cells(struct device_node *np) | 34 | int of_n_addr_cells(struct device_node *np) |
35 | { | 35 | { |
36 | const int *ip; | 36 | const __be32 *ip; |
37 | 37 | ||
38 | do { | 38 | do { |
39 | if (np->parent) | 39 | if (np->parent) |
@@ -49,7 +49,7 @@ EXPORT_SYMBOL(of_n_addr_cells); | |||
49 | 49 | ||
50 | int of_n_size_cells(struct device_node *np) | 50 | int of_n_size_cells(struct device_node *np) |
51 | { | 51 | { |
52 | const int *ip; | 52 | const __be32 *ip; |
53 | 53 | ||
54 | do { | 54 | do { |
55 | if (np->parent) | 55 | if (np->parent) |
diff --git a/drivers/of/device.c b/drivers/of/device.c index 92de0eb74aea..45d86530799f 100644 --- a/drivers/of/device.c +++ b/drivers/of/device.c | |||
@@ -81,29 +81,10 @@ struct device_attribute of_platform_device_attrs[] = { | |||
81 | __ATTR_NULL | 81 | __ATTR_NULL |
82 | }; | 82 | }; |
83 | 83 | ||
84 | /** | 84 | int of_device_add(struct platform_device *ofdev) |
85 | * of_release_dev - free an of device structure when all users of it are finished. | ||
86 | * @dev: device that's been disconnected | ||
87 | * | ||
88 | * Will be called only by the device core when all users of this of device are | ||
89 | * done. | ||
90 | */ | ||
91 | void of_release_dev(struct device *dev) | ||
92 | { | ||
93 | struct platform_device *ofdev; | ||
94 | |||
95 | ofdev = to_platform_device(dev); | ||
96 | of_node_put(ofdev->dev.of_node); | ||
97 | kfree(ofdev); | ||
98 | } | ||
99 | EXPORT_SYMBOL(of_release_dev); | ||
100 | |||
101 | int of_device_register(struct platform_device *ofdev) | ||
102 | { | 85 | { |
103 | BUG_ON(ofdev->dev.of_node == NULL); | 86 | BUG_ON(ofdev->dev.of_node == NULL); |
104 | 87 | ||
105 | device_initialize(&ofdev->dev); | ||
106 | |||
107 | /* name and id have to be set so that the platform bus doesn't get | 88 | /* name and id have to be set so that the platform bus doesn't get |
108 | * confused on matching */ | 89 | * confused on matching */ |
109 | ofdev->name = dev_name(&ofdev->dev); | 90 | ofdev->name = dev_name(&ofdev->dev); |
@@ -117,6 +98,12 @@ int of_device_register(struct platform_device *ofdev) | |||
117 | 98 | ||
118 | return device_add(&ofdev->dev); | 99 | return device_add(&ofdev->dev); |
119 | } | 100 | } |
101 | |||
102 | int of_device_register(struct platform_device *pdev) | ||
103 | { | ||
104 | device_initialize(&pdev->dev); | ||
105 | return of_device_add(pdev); | ||
106 | } | ||
120 | EXPORT_SYMBOL(of_device_register); | 107 | EXPORT_SYMBOL(of_device_register); |
121 | 108 | ||
122 | void of_device_unregister(struct platform_device *ofdev) | 109 | void of_device_unregister(struct platform_device *ofdev) |
diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c index 65da5aec7552..c1360e02f921 100644 --- a/drivers/of/fdt.c +++ b/drivers/of/fdt.c | |||
@@ -533,8 +533,6 @@ int __init early_init_dt_scan_chosen(unsigned long node, const char *uname, | |||
533 | strlcpy(cmd_line, CONFIG_CMDLINE, COMMAND_LINE_SIZE); | 533 | strlcpy(cmd_line, CONFIG_CMDLINE, COMMAND_LINE_SIZE); |
534 | #endif /* CONFIG_CMDLINE */ | 534 | #endif /* CONFIG_CMDLINE */ |
535 | 535 | ||
536 | early_init_dt_scan_chosen_arch(node); | ||
537 | |||
538 | pr_debug("Command line is: %s\n", cmd_line); | 536 | pr_debug("Command line is: %s\n", cmd_line); |
539 | 537 | ||
540 | /* break now */ | 538 | /* break now */ |
diff --git a/drivers/of/irq.c b/drivers/of/irq.c index 6e595e5a3977..75b0d3cb7676 100644 --- a/drivers/of/irq.c +++ b/drivers/of/irq.c | |||
@@ -24,6 +24,11 @@ | |||
24 | #include <linux/of_irq.h> | 24 | #include <linux/of_irq.h> |
25 | #include <linux/string.h> | 25 | #include <linux/string.h> |
26 | 26 | ||
27 | /* For archs that don't support NO_IRQ (such as x86), provide a dummy value */ | ||
28 | #ifndef NO_IRQ | ||
29 | #define NO_IRQ 0 | ||
30 | #endif | ||
31 | |||
27 | /** | 32 | /** |
28 | * irq_of_parse_and_map - Parse and map an interrupt into linux virq space | 33 | * irq_of_parse_and_map - Parse and map an interrupt into linux virq space |
29 | * @device: Device node of the device whose interrupt is to be mapped | 34 | * @device: Device node of the device whose interrupt is to be mapped |
@@ -347,3 +352,37 @@ int of_irq_to_resource(struct device_node *dev, int index, struct resource *r) | |||
347 | return irq; | 352 | return irq; |
348 | } | 353 | } |
349 | EXPORT_SYMBOL_GPL(of_irq_to_resource); | 354 | EXPORT_SYMBOL_GPL(of_irq_to_resource); |
355 | |||
356 | /** | ||
357 | * of_irq_count - Count the number of IRQs a node uses | ||
358 | * @dev: pointer to device tree node | ||
359 | */ | ||
360 | int of_irq_count(struct device_node *dev) | ||
361 | { | ||
362 | int nr = 0; | ||
363 | |||
364 | while (of_irq_to_resource(dev, nr, NULL) != NO_IRQ) | ||
365 | nr++; | ||
366 | |||
367 | return nr; | ||
368 | } | ||
369 | |||
370 | /** | ||
371 | * of_irq_to_resource_table - Fill in resource table with node's IRQ info | ||
372 | * @dev: pointer to device tree node | ||
373 | * @res: array of resources to fill in | ||
374 | * @nr_irqs: the number of IRQs (and upper bound for num of @res elements) | ||
375 | * | ||
376 | * Returns the size of the filled in table (up to @nr_irqs). | ||
377 | */ | ||
378 | int of_irq_to_resource_table(struct device_node *dev, struct resource *res, | ||
379 | int nr_irqs) | ||
380 | { | ||
381 | int i; | ||
382 | |||
383 | for (i = 0; i < nr_irqs; i++, res++) | ||
384 | if (of_irq_to_resource(dev, i, res) == NO_IRQ) | ||
385 | break; | ||
386 | |||
387 | return i; | ||
388 | } | ||
diff --git a/drivers/of/of_i2c.c b/drivers/of/of_i2c.c index 0a694debd226..c85d3c7421fc 100644 --- a/drivers/of/of_i2c.c +++ b/drivers/of/of_i2c.c | |||
@@ -12,6 +12,7 @@ | |||
12 | */ | 12 | */ |
13 | 13 | ||
14 | #include <linux/i2c.h> | 14 | #include <linux/i2c.h> |
15 | #include <linux/irq.h> | ||
15 | #include <linux/of.h> | 16 | #include <linux/of.h> |
16 | #include <linux/of_i2c.h> | 17 | #include <linux/of_i2c.h> |
17 | #include <linux/of_irq.h> | 18 | #include <linux/of_irq.h> |
diff --git a/drivers/of/pdt.c b/drivers/of/pdt.c new file mode 100644 index 000000000000..28295d0a50f6 --- /dev/null +++ b/drivers/of/pdt.c | |||
@@ -0,0 +1,276 @@ | |||
1 | /* pdt.c: OF PROM device tree support code. | ||
2 | * | ||
3 | * Paul Mackerras August 1996. | ||
4 | * Copyright (C) 1996-2005 Paul Mackerras. | ||
5 | * | ||
6 | * Adapted for 64bit PowerPC by Dave Engebretsen and Peter Bergner. | ||
7 | * {engebret|bergner}@us.ibm.com | ||
8 | * | ||
9 | * Adapted for sparc by David S. Miller davem@davemloft.net | ||
10 | * Adapted for multiple architectures by Andres Salomon <dilinger@queued.net> | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or | ||
13 | * modify it under the terms of the GNU General Public License | ||
14 | * as published by the Free Software Foundation; either version | ||
15 | * 2 of the License, or (at your option) any later version. | ||
16 | */ | ||
17 | |||
18 | #include <linux/kernel.h> | ||
19 | #include <linux/module.h> | ||
20 | #include <linux/errno.h> | ||
21 | #include <linux/mutex.h> | ||
22 | #include <linux/slab.h> | ||
23 | #include <linux/of.h> | ||
24 | #include <linux/of_pdt.h> | ||
25 | #include <asm/prom.h> | ||
26 | |||
27 | static struct of_pdt_ops *of_pdt_prom_ops __initdata; | ||
28 | |||
29 | void __initdata (*of_pdt_build_more)(struct device_node *dp, | ||
30 | struct device_node ***nextp); | ||
31 | |||
32 | #if defined(CONFIG_SPARC) | ||
33 | unsigned int of_pdt_unique_id __initdata; | ||
34 | |||
35 | #define of_pdt_incr_unique_id(p) do { \ | ||
36 | (p)->unique_id = of_pdt_unique_id++; \ | ||
37 | } while (0) | ||
38 | |||
39 | static inline const char *of_pdt_node_name(struct device_node *dp) | ||
40 | { | ||
41 | return dp->path_component_name; | ||
42 | } | ||
43 | |||
44 | #else | ||
45 | |||
46 | static inline void of_pdt_incr_unique_id(void *p) { } | ||
47 | static inline void irq_trans_init(struct device_node *dp) { } | ||
48 | |||
49 | static inline const char *of_pdt_node_name(struct device_node *dp) | ||
50 | { | ||
51 | return dp->name; | ||
52 | } | ||
53 | |||
54 | #endif /* !CONFIG_SPARC */ | ||
55 | |||
56 | static struct property * __init of_pdt_build_one_prop(phandle node, char *prev, | ||
57 | char *special_name, | ||
58 | void *special_val, | ||
59 | int special_len) | ||
60 | { | ||
61 | static struct property *tmp = NULL; | ||
62 | struct property *p; | ||
63 | int err; | ||
64 | |||
65 | if (tmp) { | ||
66 | p = tmp; | ||
67 | memset(p, 0, sizeof(*p) + 32); | ||
68 | tmp = NULL; | ||
69 | } else { | ||
70 | p = prom_early_alloc(sizeof(struct property) + 32); | ||
71 | of_pdt_incr_unique_id(p); | ||
72 | } | ||
73 | |||
74 | p->name = (char *) (p + 1); | ||
75 | if (special_name) { | ||
76 | strcpy(p->name, special_name); | ||
77 | p->length = special_len; | ||
78 | p->value = prom_early_alloc(special_len); | ||
79 | memcpy(p->value, special_val, special_len); | ||
80 | } else { | ||
81 | err = of_pdt_prom_ops->nextprop(node, prev, p->name); | ||
82 | if (err) { | ||
83 | tmp = p; | ||
84 | return NULL; | ||
85 | } | ||
86 | p->length = of_pdt_prom_ops->getproplen(node, p->name); | ||
87 | if (p->length <= 0) { | ||
88 | p->length = 0; | ||
89 | } else { | ||
90 | int len; | ||
91 | |||
92 | p->value = prom_early_alloc(p->length + 1); | ||
93 | len = of_pdt_prom_ops->getproperty(node, p->name, | ||
94 | p->value, p->length); | ||
95 | if (len <= 0) | ||
96 | p->length = 0; | ||
97 | ((unsigned char *)p->value)[p->length] = '\0'; | ||
98 | } | ||
99 | } | ||
100 | return p; | ||
101 | } | ||
102 | |||
103 | static struct property * __init of_pdt_build_prop_list(phandle node) | ||
104 | { | ||
105 | struct property *head, *tail; | ||
106 | |||
107 | head = tail = of_pdt_build_one_prop(node, NULL, | ||
108 | ".node", &node, sizeof(node)); | ||
109 | |||
110 | tail->next = of_pdt_build_one_prop(node, NULL, NULL, NULL, 0); | ||
111 | tail = tail->next; | ||
112 | while(tail) { | ||
113 | tail->next = of_pdt_build_one_prop(node, tail->name, | ||
114 | NULL, NULL, 0); | ||
115 | tail = tail->next; | ||
116 | } | ||
117 | |||
118 | return head; | ||
119 | } | ||
120 | |||
121 | static char * __init of_pdt_get_one_property(phandle node, const char *name) | ||
122 | { | ||
123 | char *buf = "<NULL>"; | ||
124 | int len; | ||
125 | |||
126 | len = of_pdt_prom_ops->getproplen(node, name); | ||
127 | if (len > 0) { | ||
128 | buf = prom_early_alloc(len); | ||
129 | len = of_pdt_prom_ops->getproperty(node, name, buf, len); | ||
130 | } | ||
131 | |||
132 | return buf; | ||
133 | } | ||
134 | |||
135 | static char * __init of_pdt_try_pkg2path(phandle node) | ||
136 | { | ||
137 | char *res, *buf = NULL; | ||
138 | int len; | ||
139 | |||
140 | if (!of_pdt_prom_ops->pkg2path) | ||
141 | return NULL; | ||
142 | |||
143 | if (of_pdt_prom_ops->pkg2path(node, buf, 0, &len)) | ||
144 | return NULL; | ||
145 | buf = prom_early_alloc(len + 1); | ||
146 | if (of_pdt_prom_ops->pkg2path(node, buf, len, &len)) { | ||
147 | pr_err("%s: package-to-path failed\n", __func__); | ||
148 | return NULL; | ||
149 | } | ||
150 | |||
151 | res = strrchr(buf, '/'); | ||
152 | if (!res) { | ||
153 | pr_err("%s: couldn't find / in %s\n", __func__, buf); | ||
154 | return NULL; | ||
155 | } | ||
156 | return res+1; | ||
157 | } | ||
158 | |||
159 | /* | ||
160 | * When fetching the node's name, first try using package-to-path; if | ||
161 | * that fails (either because the arch hasn't supplied a PROM callback, | ||
162 | * or some other random failure), fall back to just looking at the node's | ||
163 | * 'name' property. | ||
164 | */ | ||
165 | static char * __init of_pdt_build_name(phandle node) | ||
166 | { | ||
167 | char *buf; | ||
168 | |||
169 | buf = of_pdt_try_pkg2path(node); | ||
170 | if (!buf) | ||
171 | buf = of_pdt_get_one_property(node, "name"); | ||
172 | |||
173 | return buf; | ||
174 | } | ||
175 | |||
176 | static struct device_node * __init of_pdt_create_node(phandle node, | ||
177 | struct device_node *parent) | ||
178 | { | ||
179 | struct device_node *dp; | ||
180 | |||
181 | if (!node) | ||
182 | return NULL; | ||
183 | |||
184 | dp = prom_early_alloc(sizeof(*dp)); | ||
185 | of_pdt_incr_unique_id(dp); | ||
186 | dp->parent = parent; | ||
187 | |||
188 | kref_init(&dp->kref); | ||
189 | |||
190 | dp->name = of_pdt_build_name(node); | ||
191 | dp->type = of_pdt_get_one_property(node, "device_type"); | ||
192 | dp->phandle = node; | ||
193 | |||
194 | dp->properties = of_pdt_build_prop_list(node); | ||
195 | |||
196 | irq_trans_init(dp); | ||
197 | |||
198 | return dp; | ||
199 | } | ||
200 | |||
201 | static char * __init of_pdt_build_full_name(struct device_node *dp) | ||
202 | { | ||
203 | int len, ourlen, plen; | ||
204 | char *n; | ||
205 | |||
206 | plen = strlen(dp->parent->full_name); | ||
207 | ourlen = strlen(of_pdt_node_name(dp)); | ||
208 | len = ourlen + plen + 2; | ||
209 | |||
210 | n = prom_early_alloc(len); | ||
211 | strcpy(n, dp->parent->full_name); | ||
212 | if (!of_node_is_root(dp->parent)) { | ||
213 | strcpy(n + plen, "/"); | ||
214 | plen++; | ||
215 | } | ||
216 | strcpy(n + plen, of_pdt_node_name(dp)); | ||
217 | |||
218 | return n; | ||
219 | } | ||
220 | |||
221 | static struct device_node * __init of_pdt_build_tree(struct device_node *parent, | ||
222 | phandle node, | ||
223 | struct device_node ***nextp) | ||
224 | { | ||
225 | struct device_node *ret = NULL, *prev_sibling = NULL; | ||
226 | struct device_node *dp; | ||
227 | |||
228 | while (1) { | ||
229 | dp = of_pdt_create_node(node, parent); | ||
230 | if (!dp) | ||
231 | break; | ||
232 | |||
233 | if (prev_sibling) | ||
234 | prev_sibling->sibling = dp; | ||
235 | |||
236 | if (!ret) | ||
237 | ret = dp; | ||
238 | prev_sibling = dp; | ||
239 | |||
240 | *(*nextp) = dp; | ||
241 | *nextp = &dp->allnext; | ||
242 | |||
243 | #if defined(CONFIG_SPARC) | ||
244 | dp->path_component_name = build_path_component(dp); | ||
245 | #endif | ||
246 | dp->full_name = of_pdt_build_full_name(dp); | ||
247 | |||
248 | dp->child = of_pdt_build_tree(dp, | ||
249 | of_pdt_prom_ops->getchild(node), nextp); | ||
250 | |||
251 | if (of_pdt_build_more) | ||
252 | of_pdt_build_more(dp, nextp); | ||
253 | |||
254 | node = of_pdt_prom_ops->getsibling(node); | ||
255 | } | ||
256 | |||
257 | return ret; | ||
258 | } | ||
259 | |||
260 | void __init of_pdt_build_devicetree(phandle root_node, struct of_pdt_ops *ops) | ||
261 | { | ||
262 | struct device_node **nextp; | ||
263 | |||
264 | BUG_ON(!ops); | ||
265 | of_pdt_prom_ops = ops; | ||
266 | |||
267 | allnodes = of_pdt_create_node(root_node, NULL); | ||
268 | #if defined(CONFIG_SPARC) | ||
269 | allnodes->path_component_name = ""; | ||
270 | #endif | ||
271 | allnodes->full_name = "/"; | ||
272 | |||
273 | nextp = &allnodes->allnext; | ||
274 | allnodes->child = of_pdt_build_tree(allnodes, | ||
275 | of_pdt_prom_ops->getchild(allnodes->phandle), &nextp); | ||
276 | } | ||
diff --git a/drivers/of/platform.c b/drivers/of/platform.c index bb72223c22ae..5b4a07f1220e 100644 --- a/drivers/of/platform.c +++ b/drivers/of/platform.c | |||
@@ -584,34 +584,33 @@ struct platform_device *of_device_alloc(struct device_node *np, | |||
584 | struct device *parent) | 584 | struct device *parent) |
585 | { | 585 | { |
586 | struct platform_device *dev; | 586 | struct platform_device *dev; |
587 | int rc, i, num_reg = 0, num_irq = 0; | 587 | int rc, i, num_reg = 0, num_irq; |
588 | struct resource *res, temp_res; | 588 | struct resource *res, temp_res; |
589 | 589 | ||
590 | /* First count how many resources are needed */ | 590 | dev = platform_device_alloc("", -1); |
591 | while (of_address_to_resource(np, num_reg, &temp_res) == 0) | ||
592 | num_reg++; | ||
593 | while (of_irq_to_resource(np, num_irq, &temp_res) != NO_IRQ) | ||
594 | num_irq++; | ||
595 | |||
596 | /* Allocate memory for both the struct device and the resource table */ | ||
597 | dev = kzalloc(sizeof(*dev) + (sizeof(*res) * (num_reg + num_irq)), | ||
598 | GFP_KERNEL); | ||
599 | if (!dev) | 591 | if (!dev) |
600 | return NULL; | 592 | return NULL; |
601 | res = (struct resource *) &dev[1]; | 593 | |
594 | /* count the io and irq resources */ | ||
595 | while (of_address_to_resource(np, num_reg, &temp_res) == 0) | ||
596 | num_reg++; | ||
597 | num_irq = of_irq_count(np); | ||
602 | 598 | ||
603 | /* Populate the resource table */ | 599 | /* Populate the resource table */ |
604 | if (num_irq || num_reg) { | 600 | if (num_irq || num_reg) { |
601 | res = kzalloc(sizeof(*res) * (num_irq + num_reg), GFP_KERNEL); | ||
602 | if (!res) { | ||
603 | platform_device_put(dev); | ||
604 | return NULL; | ||
605 | } | ||
606 | |||
605 | dev->num_resources = num_reg + num_irq; | 607 | dev->num_resources = num_reg + num_irq; |
606 | dev->resource = res; | 608 | dev->resource = res; |
607 | for (i = 0; i < num_reg; i++, res++) { | 609 | for (i = 0; i < num_reg; i++, res++) { |
608 | rc = of_address_to_resource(np, i, res); | 610 | rc = of_address_to_resource(np, i, res); |
609 | WARN_ON(rc); | 611 | WARN_ON(rc); |
610 | } | 612 | } |
611 | for (i = 0; i < num_irq; i++, res++) { | 613 | WARN_ON(of_irq_to_resource_table(np, res, num_irq) != num_irq); |
612 | rc = of_irq_to_resource(np, i, res); | ||
613 | WARN_ON(rc == NO_IRQ); | ||
614 | } | ||
615 | } | 614 | } |
616 | 615 | ||
617 | dev->dev.of_node = of_node_get(np); | 616 | dev->dev.of_node = of_node_get(np); |
@@ -619,7 +618,6 @@ struct platform_device *of_device_alloc(struct device_node *np, | |||
619 | dev->dev.dma_mask = &dev->archdata.dma_mask; | 618 | dev->dev.dma_mask = &dev->archdata.dma_mask; |
620 | #endif | 619 | #endif |
621 | dev->dev.parent = parent; | 620 | dev->dev.parent = parent; |
622 | dev->dev.release = of_release_dev; | ||
623 | 621 | ||
624 | if (bus_id) | 622 | if (bus_id) |
625 | dev_set_name(&dev->dev, "%s", bus_id); | 623 | dev_set_name(&dev->dev, "%s", bus_id); |
@@ -657,8 +655,8 @@ struct platform_device *of_platform_device_create(struct device_node *np, | |||
657 | * to do such, possibly using a device notifier | 655 | * to do such, possibly using a device notifier |
658 | */ | 656 | */ |
659 | 657 | ||
660 | if (of_device_register(dev) != 0) { | 658 | if (of_device_add(dev) != 0) { |
661 | of_device_free(dev); | 659 | platform_device_put(dev); |
662 | return NULL; | 660 | return NULL; |
663 | } | 661 | } |
664 | 662 | ||