aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2011-07-22 17:53:38 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2011-07-22 17:53:38 -0400
commit8181780c163e7111f15619067cfa044172d532e1 (patch)
tree7eec99ddd1b20e9018edfba5c05a179b317c27fe /drivers
parent7235dd74a4733d4b3651349b5261d2e06996427d (diff)
parent99ce39e359fa29e4b609a6a13485e7573eda5dfb (diff)
Merge branch 'devicetree/next' of git://git.secretlab.ca/git/linux-2.6
* 'devicetree/next' of git://git.secretlab.ca/git/linux-2.6: dt: include linux/errno.h in linux/of_address.h of/address: Add of_find_matching_node_by_address helper dt: remove extra xsysace platform_driver registration tty/serial: Add devicetree support for nVidia Tegra serial ports dt: add empty of_property_read_u32[_array] for non-dt dt: bindings: move SEC node under new crypto/ dt: add helper function to read u32 arrays tty/serial: change of_serial to use new of_property_read_u32() api dt: add 'const' for of_property_read_string parameter **out_string dt: add helper functions to read u32 and string property values tty: of_serial: support for 32 bit accesses dt: document the of_serial bindings dt/platform: allow device name to be overridden drivers/amba: create devices from device tree dt: add of_platform_populate() for creating device from the device tree dt: Add default match table for bus ids
Diffstat (limited to 'drivers')
-rw-r--r--drivers/block/xsysace.c98
-rw-r--r--drivers/of/address.c18
-rw-r--r--drivers/of/base.c65
-rw-r--r--drivers/of/platform.c196
-rw-r--r--drivers/tty/serial/of_serial.c43
5 files changed, 313 insertions, 107 deletions
diff --git a/drivers/block/xsysace.c b/drivers/block/xsysace.c
index 6c7fd7db6df..fb1975d82a7 100644
--- a/drivers/block/xsysace.c
+++ b/drivers/block/xsysace.c
@@ -1155,12 +1155,19 @@ static int __devinit ace_probe(struct platform_device *dev)
1155{ 1155{
1156 resource_size_t physaddr = 0; 1156 resource_size_t physaddr = 0;
1157 int bus_width = ACE_BUS_WIDTH_16; /* FIXME: should not be hard coded */ 1157 int bus_width = ACE_BUS_WIDTH_16; /* FIXME: should not be hard coded */
1158 int id = dev->id; 1158 u32 id = dev->id;
1159 int irq = NO_IRQ; 1159 int irq = NO_IRQ;
1160 int i; 1160 int i;
1161 1161
1162 dev_dbg(&dev->dev, "ace_probe(%p)\n", dev); 1162 dev_dbg(&dev->dev, "ace_probe(%p)\n", dev);
1163 1163
1164 /* device id and bus width */
1165 of_property_read_u32(dev->dev.of_node, "port-number", &id);
1166 if (id < 0)
1167 id = 0;
1168 if (of_find_property(dev->dev.of_node, "8-bit", NULL))
1169 bus_width = ACE_BUS_WIDTH_8;
1170
1164 for (i = 0; i < dev->num_resources; i++) { 1171 for (i = 0; i < dev->num_resources; i++) {
1165 if (dev->resource[i].flags & IORESOURCE_MEM) 1172 if (dev->resource[i].flags & IORESOURCE_MEM)
1166 physaddr = dev->resource[i].start; 1173 physaddr = dev->resource[i].start;
@@ -1181,57 +1188,7 @@ static int __devexit ace_remove(struct platform_device *dev)
1181 return 0; 1188 return 0;
1182} 1189}
1183 1190
1184static struct platform_driver ace_platform_driver = {
1185 .probe = ace_probe,
1186 .remove = __devexit_p(ace_remove),
1187 .driver = {
1188 .owner = THIS_MODULE,
1189 .name = "xsysace",
1190 },
1191};
1192
1193/* ---------------------------------------------------------------------
1194 * OF_Platform Bus Support
1195 */
1196
1197#if defined(CONFIG_OF) 1191#if defined(CONFIG_OF)
1198static int __devinit ace_of_probe(struct platform_device *op)
1199{
1200 struct resource res;
1201 resource_size_t physaddr;
1202 const u32 *id;
1203 int irq, bus_width, rc;
1204
1205 /* device id */
1206 id = of_get_property(op->dev.of_node, "port-number", NULL);
1207
1208 /* physaddr */
1209 rc = of_address_to_resource(op->dev.of_node, 0, &res);
1210 if (rc) {
1211 dev_err(&op->dev, "invalid address\n");
1212 return rc;
1213 }
1214 physaddr = res.start;
1215
1216 /* irq */
1217 irq = irq_of_parse_and_map(op->dev.of_node, 0);
1218
1219 /* bus width */
1220 bus_width = ACE_BUS_WIDTH_16;
1221 if (of_find_property(op->dev.of_node, "8-bit", NULL))
1222 bus_width = ACE_BUS_WIDTH_8;
1223
1224 /* Call the bus-independent setup code */
1225 return ace_alloc(&op->dev, id ? be32_to_cpup(id) : 0,
1226 physaddr, irq, bus_width);
1227}
1228
1229static int __devexit ace_of_remove(struct platform_device *op)
1230{
1231 ace_free(&op->dev);
1232 return 0;
1233}
1234
1235/* Match table for of_platform binding */ 1192/* Match table for of_platform binding */
1236static const struct of_device_id ace_of_match[] __devinitconst = { 1193static const struct of_device_id ace_of_match[] __devinitconst = {
1237 { .compatible = "xlnx,opb-sysace-1.00.b", }, 1194 { .compatible = "xlnx,opb-sysace-1.00.b", },
@@ -1241,34 +1198,20 @@ static const struct of_device_id ace_of_match[] __devinitconst = {
1241 {}, 1198 {},
1242}; 1199};
1243MODULE_DEVICE_TABLE(of, ace_of_match); 1200MODULE_DEVICE_TABLE(of, ace_of_match);
1201#else /* CONFIG_OF */
1202#define ace_of_match NULL
1203#endif /* CONFIG_OF */
1244 1204
1245static struct platform_driver ace_of_driver = { 1205static struct platform_driver ace_platform_driver = {
1246 .probe = ace_of_probe, 1206 .probe = ace_probe,
1247 .remove = __devexit_p(ace_of_remove), 1207 .remove = __devexit_p(ace_remove),
1248 .driver = { 1208 .driver = {
1249 .name = "xsysace",
1250 .owner = THIS_MODULE, 1209 .owner = THIS_MODULE,
1210 .name = "xsysace",
1251 .of_match_table = ace_of_match, 1211 .of_match_table = ace_of_match,
1252 }, 1212 },
1253}; 1213};
1254 1214
1255/* Registration helpers to keep the number of #ifdefs to a minimum */
1256static inline int __init ace_of_register(void)
1257{
1258 pr_debug("xsysace: registering OF binding\n");
1259 return platform_driver_register(&ace_of_driver);
1260}
1261
1262static inline void __exit ace_of_unregister(void)
1263{
1264 platform_driver_unregister(&ace_of_driver);
1265}
1266#else /* CONFIG_OF */
1267/* CONFIG_OF not enabled; do nothing helpers */
1268static inline int __init ace_of_register(void) { return 0; }
1269static inline void __exit ace_of_unregister(void) { }
1270#endif /* CONFIG_OF */
1271
1272/* --------------------------------------------------------------------- 1215/* ---------------------------------------------------------------------
1273 * Module init/exit routines 1216 * Module init/exit routines
1274 */ 1217 */
@@ -1282,11 +1225,6 @@ static int __init ace_init(void)
1282 goto err_blk; 1225 goto err_blk;
1283 } 1226 }
1284 1227
1285 rc = ace_of_register();
1286 if (rc)
1287 goto err_of;
1288
1289 pr_debug("xsysace: registering platform binding\n");
1290 rc = platform_driver_register(&ace_platform_driver); 1228 rc = platform_driver_register(&ace_platform_driver);
1291 if (rc) 1229 if (rc)
1292 goto err_plat; 1230 goto err_plat;
@@ -1295,21 +1233,17 @@ static int __init ace_init(void)
1295 return 0; 1233 return 0;
1296 1234
1297err_plat: 1235err_plat:
1298 ace_of_unregister();
1299err_of:
1300 unregister_blkdev(ace_major, "xsysace"); 1236 unregister_blkdev(ace_major, "xsysace");
1301err_blk: 1237err_blk:
1302 printk(KERN_ERR "xsysace: registration failed; err=%i\n", rc); 1238 printk(KERN_ERR "xsysace: registration failed; err=%i\n", rc);
1303 return rc; 1239 return rc;
1304} 1240}
1241module_init(ace_init);
1305 1242
1306static void __exit ace_exit(void) 1243static void __exit ace_exit(void)
1307{ 1244{
1308 pr_debug("Unregistering Xilinx SystemACE driver\n"); 1245 pr_debug("Unregistering Xilinx SystemACE driver\n");
1309 platform_driver_unregister(&ace_platform_driver); 1246 platform_driver_unregister(&ace_platform_driver);
1310 ace_of_unregister();
1311 unregister_blkdev(ace_major, "xsysace"); 1247 unregister_blkdev(ace_major, "xsysace");
1312} 1248}
1313
1314module_init(ace_init);
1315module_exit(ace_exit); 1249module_exit(ace_exit);
diff --git a/drivers/of/address.c b/drivers/of/address.c
index b4559c58c09..da1f4b9605d 100644
--- a/drivers/of/address.c
+++ b/drivers/of/address.c
@@ -577,6 +577,24 @@ int of_address_to_resource(struct device_node *dev, int index,
577} 577}
578EXPORT_SYMBOL_GPL(of_address_to_resource); 578EXPORT_SYMBOL_GPL(of_address_to_resource);
579 579
580struct device_node *of_find_matching_node_by_address(struct device_node *from,
581 const struct of_device_id *matches,
582 u64 base_address)
583{
584 struct device_node *dn = of_find_matching_node(from, matches);
585 struct resource res;
586
587 while (dn) {
588 if (of_address_to_resource(dn, 0, &res))
589 continue;
590 if (res.start == base_address)
591 return dn;
592 dn = of_find_matching_node(dn, matches);
593 }
594
595 return NULL;
596}
597
580 598
581/** 599/**
582 * of_iomap - Maps the memory mapped IO for a given device_node 600 * of_iomap - Maps the memory mapped IO for a given device_node
diff --git a/drivers/of/base.c b/drivers/of/base.c
index 632ebae7f17..02ed36719de 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -596,6 +596,71 @@ struct device_node *of_find_node_by_phandle(phandle handle)
596EXPORT_SYMBOL(of_find_node_by_phandle); 596EXPORT_SYMBOL(of_find_node_by_phandle);
597 597
598/** 598/**
599 * of_property_read_u32_array - Find and read an array of 32 bit integers
600 * from a property.
601 *
602 * @np: device node from which the property value is to be read.
603 * @propname: name of the property to be searched.
604 * @out_value: pointer to return value, modified only if return value is 0.
605 *
606 * Search for a property in a device node and read 32-bit value(s) from
607 * it. Returns 0 on success, -EINVAL if the property does not exist,
608 * -ENODATA if property does not have a value, and -EOVERFLOW if the
609 * property data isn't large enough.
610 *
611 * The out_value is modified only if a valid u32 value can be decoded.
612 */
613int of_property_read_u32_array(const struct device_node *np, char *propname,
614 u32 *out_values, size_t sz)
615{
616 struct property *prop = of_find_property(np, propname, NULL);
617 const __be32 *val;
618
619 if (!prop)
620 return -EINVAL;
621 if (!prop->value)
622 return -ENODATA;
623 if ((sz * sizeof(*out_values)) > prop->length)
624 return -EOVERFLOW;
625
626 val = prop->value;
627 while (sz--)
628 *out_values++ = be32_to_cpup(val++);
629 return 0;
630}
631EXPORT_SYMBOL_GPL(of_property_read_u32_array);
632
633/**
634 * of_property_read_string - Find and read a string from a property
635 * @np: device node from which the property value is to be read.
636 * @propname: name of the property to be searched.
637 * @out_string: pointer to null terminated return string, modified only if
638 * return value is 0.
639 *
640 * Search for a property in a device tree node and retrieve a null
641 * terminated string value (pointer to data, not a copy). Returns 0 on
642 * success, -EINVAL if the property does not exist, -ENODATA if property
643 * does not have a value, and -EILSEQ if the string is not null-terminated
644 * within the length of the property data.
645 *
646 * The out_string pointer is modified only if a valid string can be decoded.
647 */
648int of_property_read_string(struct device_node *np, char *propname,
649 const char **out_string)
650{
651 struct property *prop = of_find_property(np, propname, NULL);
652 if (!prop)
653 return -EINVAL;
654 if (!prop->value)
655 return -ENODATA;
656 if (strnlen(prop->value, prop->length) >= prop->length)
657 return -EILSEQ;
658 *out_string = prop->value;
659 return 0;
660}
661EXPORT_SYMBOL_GPL(of_property_read_string);
662
663/**
599 * of_parse_phandle - Resolve a phandle property to a device_node pointer 664 * of_parse_phandle - Resolve a phandle property to a device_node pointer
600 * @np: Pointer to device node holding phandle property 665 * @np: Pointer to device node holding phandle property
601 * @phandle_name: Name of property holding a phandle value 666 * @phandle_name: Name of property holding a phandle value
diff --git a/drivers/of/platform.c b/drivers/of/platform.c
index 63d3cb73bdb..e75af391e28 100644
--- a/drivers/of/platform.c
+++ b/drivers/of/platform.c
@@ -13,6 +13,7 @@
13 */ 13 */
14#include <linux/errno.h> 14#include <linux/errno.h>
15#include <linux/module.h> 15#include <linux/module.h>
16#include <linux/amba/bus.h>
16#include <linux/device.h> 17#include <linux/device.h>
17#include <linux/dma-mapping.h> 18#include <linux/dma-mapping.h>
18#include <linux/slab.h> 19#include <linux/slab.h>
@@ -22,6 +23,14 @@
22#include <linux/of_platform.h> 23#include <linux/of_platform.h>
23#include <linux/platform_device.h> 24#include <linux/platform_device.h>
24 25
26const struct of_device_id of_default_bus_match_table[] = {
27 { .compatible = "simple-bus", },
28#ifdef CONFIG_ARM_AMBA
29 { .compatible = "arm,amba-bus", },
30#endif /* CONFIG_ARM_AMBA */
31 {} /* Empty terminated list */
32};
33
25static int of_dev_node_match(struct device *dev, void *data) 34static int of_dev_node_match(struct device *dev, void *data)
26{ 35{
27 return dev->of_node == data; 36 return dev->of_node == data;
@@ -168,17 +177,20 @@ struct platform_device *of_device_alloc(struct device_node *np,
168EXPORT_SYMBOL(of_device_alloc); 177EXPORT_SYMBOL(of_device_alloc);
169 178
170/** 179/**
171 * of_platform_device_create - Alloc, initialize and register an of_device 180 * of_platform_device_create_pdata - Alloc, initialize and register an of_device
172 * @np: pointer to node to create device for 181 * @np: pointer to node to create device for
173 * @bus_id: name to assign device 182 * @bus_id: name to assign device
183 * @platform_data: pointer to populate platform_data pointer with
174 * @parent: Linux device model parent device. 184 * @parent: Linux device model parent device.
175 * 185 *
176 * Returns pointer to created platform device, or NULL if a device was not 186 * Returns pointer to created platform device, or NULL if a device was not
177 * registered. Unavailable devices will not get registered. 187 * registered. Unavailable devices will not get registered.
178 */ 188 */
179struct platform_device *of_platform_device_create(struct device_node *np, 189struct platform_device *of_platform_device_create_pdata(
180 const char *bus_id, 190 struct device_node *np,
181 struct device *parent) 191 const char *bus_id,
192 void *platform_data,
193 struct device *parent)
182{ 194{
183 struct platform_device *dev; 195 struct platform_device *dev;
184 196
@@ -194,6 +206,7 @@ struct platform_device *of_platform_device_create(struct device_node *np,
194#endif 206#endif
195 dev->dev.coherent_dma_mask = DMA_BIT_MASK(32); 207 dev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
196 dev->dev.bus = &platform_bus_type; 208 dev->dev.bus = &platform_bus_type;
209 dev->dev.platform_data = platform_data;
197 210
198 /* We do not fill the DMA ops for platform devices by default. 211 /* We do not fill the DMA ops for platform devices by default.
199 * This is currently the responsibility of the platform code 212 * This is currently the responsibility of the platform code
@@ -207,8 +220,111 @@ struct platform_device *of_platform_device_create(struct device_node *np,
207 220
208 return dev; 221 return dev;
209} 222}
223
224/**
225 * of_platform_device_create - Alloc, initialize and register an of_device
226 * @np: pointer to node to create device for
227 * @bus_id: name to assign device
228 * @parent: Linux device model parent device.
229 *
230 * Returns pointer to created platform device, or NULL if a device was not
231 * registered. Unavailable devices will not get registered.
232 */
233struct platform_device *of_platform_device_create(struct device_node *np,
234 const char *bus_id,
235 struct device *parent)
236{
237 return of_platform_device_create_pdata(np, bus_id, NULL, parent);
238}
210EXPORT_SYMBOL(of_platform_device_create); 239EXPORT_SYMBOL(of_platform_device_create);
211 240
241#ifdef CONFIG_ARM_AMBA
242static struct amba_device *of_amba_device_create(struct device_node *node,
243 const char *bus_id,
244 void *platform_data,
245 struct device *parent)
246{
247 struct amba_device *dev;
248 const void *prop;
249 int i, ret;
250
251 pr_debug("Creating amba device %s\n", node->full_name);
252
253 if (!of_device_is_available(node))
254 return NULL;
255
256 dev = kzalloc(sizeof(*dev), GFP_KERNEL);
257 if (!dev)
258 return NULL;
259
260 /* setup generic device info */
261 dev->dev.coherent_dma_mask = ~0;
262 dev->dev.of_node = of_node_get(node);
263 dev->dev.parent = parent;
264 dev->dev.platform_data = platform_data;
265 if (bus_id)
266 dev_set_name(&dev->dev, "%s", bus_id);
267 else
268 of_device_make_bus_id(&dev->dev);
269
270 /* setup amba-specific device info */
271 dev->dma_mask = ~0;
272
273 /* Allow the HW Peripheral ID to be overridden */
274 prop = of_get_property(node, "arm,primecell-periphid", NULL);
275 if (prop)
276 dev->periphid = of_read_ulong(prop, 1);
277
278 /* Decode the IRQs and address ranges */
279 for (i = 0; i < AMBA_NR_IRQS; i++)
280 dev->irq[i] = irq_of_parse_and_map(node, i);
281
282 ret = of_address_to_resource(node, 0, &dev->res);
283 if (ret)
284 goto err_free;
285
286 ret = amba_device_register(dev, &iomem_resource);
287 if (ret)
288 goto err_free;
289
290 return dev;
291
292err_free:
293 kfree(dev);
294 return NULL;
295}
296#else /* CONFIG_ARM_AMBA */
297static struct amba_device *of_amba_device_create(struct device_node *node,
298 const char *bus_id,
299 void *platform_data,
300 struct device *parent)
301{
302 return NULL;
303}
304#endif /* CONFIG_ARM_AMBA */
305
306/**
307 * of_devname_lookup() - Given a device node, lookup the preferred Linux name
308 */
309static const struct of_dev_auxdata *of_dev_lookup(const struct of_dev_auxdata *lookup,
310 struct device_node *np)
311{
312 struct resource res;
313 if (lookup) {
314 for(; lookup->name != NULL; lookup++) {
315 if (!of_device_is_compatible(np, lookup->compatible))
316 continue;
317 if (of_address_to_resource(np, 0, &res))
318 continue;
319 if (res.start != lookup->phys_addr)
320 continue;
321 pr_debug("%s: devname=%s\n", np->full_name, lookup->name);
322 return lookup;
323 }
324 }
325 return NULL;
326}
327
212/** 328/**
213 * of_platform_bus_create() - Create a device for a node and its children. 329 * of_platform_bus_create() - Create a device for a node and its children.
214 * @bus: device node of the bus to instantiate 330 * @bus: device node of the bus to instantiate
@@ -221,19 +337,41 @@ EXPORT_SYMBOL(of_platform_device_create);
221 */ 337 */
222static int of_platform_bus_create(struct device_node *bus, 338static int of_platform_bus_create(struct device_node *bus,
223 const struct of_device_id *matches, 339 const struct of_device_id *matches,
224 struct device *parent) 340 const struct of_dev_auxdata *lookup,
341 struct device *parent, bool strict)
225{ 342{
343 const struct of_dev_auxdata *auxdata;
226 struct device_node *child; 344 struct device_node *child;
227 struct platform_device *dev; 345 struct platform_device *dev;
346 const char *bus_id = NULL;
347 void *platform_data = NULL;
228 int rc = 0; 348 int rc = 0;
229 349
230 dev = of_platform_device_create(bus, NULL, parent); 350 /* Make sure it has a compatible property */
351 if (strict && (!of_get_property(bus, "compatible", NULL))) {
352 pr_debug("%s() - skipping %s, no compatible prop\n",
353 __func__, bus->full_name);
354 return 0;
355 }
356
357 auxdata = of_dev_lookup(lookup, bus);
358 if (auxdata) {
359 bus_id = auxdata->name;
360 platform_data = auxdata->platform_data;
361 }
362
363 if (of_device_is_compatible(bus, "arm,primecell")) {
364 of_amba_device_create(bus, bus_id, platform_data, parent);
365 return 0;
366 }
367
368 dev = of_platform_device_create_pdata(bus, bus_id, platform_data, parent);
231 if (!dev || !of_match_node(matches, bus)) 369 if (!dev || !of_match_node(matches, bus))
232 return 0; 370 return 0;
233 371
234 for_each_child_of_node(bus, child) { 372 for_each_child_of_node(bus, child) {
235 pr_debug(" create child: %s\n", child->full_name); 373 pr_debug(" create child: %s\n", child->full_name);
236 rc = of_platform_bus_create(child, matches, &dev->dev); 374 rc = of_platform_bus_create(child, matches, lookup, &dev->dev, strict);
237 if (rc) { 375 if (rc) {
238 of_node_put(child); 376 of_node_put(child);
239 break; 377 break;
@@ -267,11 +405,11 @@ int of_platform_bus_probe(struct device_node *root,
267 405
268 /* Do a self check of bus type, if there's a match, create children */ 406 /* Do a self check of bus type, if there's a match, create children */
269 if (of_match_node(matches, root)) { 407 if (of_match_node(matches, root)) {
270 rc = of_platform_bus_create(root, matches, parent); 408 rc = of_platform_bus_create(root, matches, NULL, parent, false);
271 } else for_each_child_of_node(root, child) { 409 } else for_each_child_of_node(root, child) {
272 if (!of_match_node(matches, child)) 410 if (!of_match_node(matches, child))
273 continue; 411 continue;
274 rc = of_platform_bus_create(child, matches, parent); 412 rc = of_platform_bus_create(child, matches, NULL, parent, false);
275 if (rc) 413 if (rc)
276 break; 414 break;
277 } 415 }
@@ -280,4 +418,44 @@ int of_platform_bus_probe(struct device_node *root,
280 return rc; 418 return rc;
281} 419}
282EXPORT_SYMBOL(of_platform_bus_probe); 420EXPORT_SYMBOL(of_platform_bus_probe);
421
422/**
423 * of_platform_populate() - Populate platform_devices from device tree data
424 * @root: parent of the first level to probe or NULL for the root of the tree
425 * @matches: match table, NULL to use the default
426 * @parent: parent to hook devices from, NULL for toplevel
427 *
428 * Similar to of_platform_bus_probe(), this function walks the device tree
429 * and creates devices from nodes. It differs in that it follows the modern
430 * convention of requiring all device nodes to have a 'compatible' property,
431 * and it is suitable for creating devices which are children of the root
432 * node (of_platform_bus_probe will only create children of the root which
433 * are selected by the @matches argument).
434 *
435 * New board support should be using this function instead of
436 * of_platform_bus_probe().
437 *
438 * Returns 0 on success, < 0 on failure.
439 */
440int of_platform_populate(struct device_node *root,
441 const struct of_device_id *matches,
442 const struct of_dev_auxdata *lookup,
443 struct device *parent)
444{
445 struct device_node *child;
446 int rc = 0;
447
448 root = root ? of_node_get(root) : of_find_node_by_path("/");
449 if (!root)
450 return -EINVAL;
451
452 for_each_child_of_node(root, child) {
453 rc = of_platform_bus_create(child, matches, lookup, parent, true);
454 if (rc)
455 break;
456 }
457
458 of_node_put(root);
459 return rc;
460}
283#endif /* !CONFIG_SPARC */ 461#endif /* !CONFIG_SPARC */
diff --git a/drivers/tty/serial/of_serial.c b/drivers/tty/serial/of_serial.c
index c911b2419ab..e58cece6f44 100644
--- a/drivers/tty/serial/of_serial.c
+++ b/drivers/tty/serial/of_serial.c
@@ -32,17 +32,17 @@ static int __devinit of_platform_serial_setup(struct platform_device *ofdev,
32{ 32{
33 struct resource resource; 33 struct resource resource;
34 struct device_node *np = ofdev->dev.of_node; 34 struct device_node *np = ofdev->dev.of_node;
35 const __be32 *clk, *spd; 35 u32 clk, spd, prop;
36 const __be32 *prop; 36 int ret;
37 int ret, prop_size;
38 37
39 memset(port, 0, sizeof *port); 38 memset(port, 0, sizeof *port);
40 spd = of_get_property(np, "current-speed", NULL); 39 if (of_property_read_u32(np, "clock-frequency", &clk)) {
41 clk = of_get_property(np, "clock-frequency", NULL);
42 if (!clk) {
43 dev_warn(&ofdev->dev, "no clock-frequency property set\n"); 40 dev_warn(&ofdev->dev, "no clock-frequency property set\n");
44 return -ENODEV; 41 return -ENODEV;
45 } 42 }
43 /* If current-speed was set, then try not to change it. */
44 if (of_property_read_u32(np, "current-speed", &spd) == 0)
45 port->custom_divisor = clk / (16 * spd);
46 46
47 ret = of_address_to_resource(np, 0, &resource); 47 ret = of_address_to_resource(np, 0, &resource);
48 if (ret) { 48 if (ret) {
@@ -54,25 +54,35 @@ static int __devinit of_platform_serial_setup(struct platform_device *ofdev,
54 port->mapbase = resource.start; 54 port->mapbase = resource.start;
55 55
56 /* Check for shifted address mapping */ 56 /* Check for shifted address mapping */
57 prop = of_get_property(np, "reg-offset", &prop_size); 57 if (of_property_read_u32(np, "reg-offset", &prop) == 0)
58 if (prop && (prop_size == sizeof(u32))) 58 port->mapbase += prop;
59 port->mapbase += be32_to_cpup(prop);
60 59
61 /* Check for registers offset within the devices address range */ 60 /* Check for registers offset within the devices address range */
62 prop = of_get_property(np, "reg-shift", &prop_size); 61 if (of_property_read_u32(np, "reg-shift", &prop) == 0)
63 if (prop && (prop_size == sizeof(u32))) 62 port->regshift = prop;
64 port->regshift = be32_to_cpup(prop);
65 63
66 port->irq = irq_of_parse_and_map(np, 0); 64 port->irq = irq_of_parse_and_map(np, 0);
67 port->iotype = UPIO_MEM; 65 port->iotype = UPIO_MEM;
66 if (of_property_read_u32(np, "reg-io-width", &prop) == 0) {
67 switch (prop) {
68 case 1:
69 port->iotype = UPIO_MEM;
70 break;
71 case 4:
72 port->iotype = UPIO_MEM32;
73 break;
74 default:
75 dev_warn(&ofdev->dev, "unsupported reg-io-width (%d)\n",
76 prop);
77 return -EINVAL;
78 }
79 }
80
68 port->type = type; 81 port->type = type;
69 port->uartclk = be32_to_cpup(clk); 82 port->uartclk = clk;
70 port->flags = UPF_SHARE_IRQ | UPF_BOOT_AUTOCONF | UPF_IOREMAP 83 port->flags = UPF_SHARE_IRQ | UPF_BOOT_AUTOCONF | UPF_IOREMAP
71 | UPF_FIXED_PORT | UPF_FIXED_TYPE; 84 | UPF_FIXED_PORT | UPF_FIXED_TYPE;
72 port->dev = &ofdev->dev; 85 port->dev = &ofdev->dev;
73 /* If current-speed was set, then try not to change it. */
74 if (spd)
75 port->custom_divisor = be32_to_cpup(clk) / (16 * (be32_to_cpup(spd)));
76 86
77 return 0; 87 return 0;
78} 88}
@@ -171,6 +181,7 @@ static struct of_device_id __devinitdata of_platform_serial_table[] = {
171 { .compatible = "ns16550", .data = (void *)PORT_16550, }, 181 { .compatible = "ns16550", .data = (void *)PORT_16550, },
172 { .compatible = "ns16750", .data = (void *)PORT_16750, }, 182 { .compatible = "ns16750", .data = (void *)PORT_16750, },
173 { .compatible = "ns16850", .data = (void *)PORT_16850, }, 183 { .compatible = "ns16850", .data = (void *)PORT_16850, },
184 { .compatible = "nvidia,tegra20-uart", .data = (void *)PORT_TEGRA, },
174#ifdef CONFIG_SERIAL_OF_PLATFORM_NWPSERIAL 185#ifdef CONFIG_SERIAL_OF_PLATFORM_NWPSERIAL
175 { .compatible = "ibm,qpace-nwp-serial", 186 { .compatible = "ibm,qpace-nwp-serial",
176 .data = (void *)PORT_NWPSERIAL, }, 187 .data = (void *)PORT_NWPSERIAL, },