diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-10-27 02:35:41 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-10-27 02:35:41 -0400 |
commit | 5fffb9513cb7fdd39e03c4cab1cda9c2f2694576 (patch) | |
tree | f28f1c232dd5774c9157ba257df37e66d4097870 /drivers | |
parent | b96d71571f7745216ef63f13770b5a10b94ddd34 (diff) | |
parent | ae97159aed6eff68f4ac86472b018985f071fed5 (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:
of_mdio: Don't phy_scan_fixups() twice
Devicetree: Expand on ARM Primecell binding documentation
dt: Add empty of_match_node() macro
dt: add empty dt helpers for non-dt build
devicetree: fix build error on drivers/tty/serial/altera_jtaguart.c
devicetree: Add ARM pl022 spi controller binding doc
devicetree: Add ARM pl061 gpio controller binding doc
of/irq: of_irq_find_parent: check for parent equal to child
MAINTAINERS: update devicetree maintainers
dt: add helper to read 64-bit integers
tty: use of_match_ptr() for of_match_table entry
OF: Add of_match_ptr() macro
dt: add empty for_each_child_of_node, of_find_property
devicetree: Document Qualcomm and Atmel prefixes
serial/imx: add of_alias_get_id() reference back
dt: add of_alias_scan and of_alias_get_id
devicetree: Add a registry of vendor prefixes
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/of/base.c | 150 | ||||
-rw-r--r-- | drivers/of/fdt.c | 6 | ||||
-rw-r--r-- | drivers/of/irq.c | 14 | ||||
-rw-r--r-- | drivers/of/of_mdio.c | 1 | ||||
-rw-r--r-- | drivers/of/pdt.c | 8 | ||||
-rw-r--r-- | drivers/tty/serial/altera_jtaguart.c | 5 | ||||
-rw-r--r-- | drivers/tty/serial/altera_uart.c | 4 | ||||
-rw-r--r-- | drivers/tty/serial/imx.c | 11 | ||||
-rw-r--r-- | drivers/tty/serial/uartlite.c | 4 |
9 files changed, 178 insertions, 25 deletions
diff --git a/drivers/of/base.c b/drivers/of/base.c index 3ff22e32b602..b970562e0111 100644 --- a/drivers/of/base.c +++ b/drivers/of/base.c | |||
@@ -17,14 +17,39 @@ | |||
17 | * as published by the Free Software Foundation; either version | 17 | * as published by the Free Software Foundation; either version |
18 | * 2 of the License, or (at your option) any later version. | 18 | * 2 of the License, or (at your option) any later version. |
19 | */ | 19 | */ |
20 | #include <linux/ctype.h> | ||
20 | #include <linux/module.h> | 21 | #include <linux/module.h> |
21 | #include <linux/of.h> | 22 | #include <linux/of.h> |
22 | #include <linux/spinlock.h> | 23 | #include <linux/spinlock.h> |
23 | #include <linux/slab.h> | 24 | #include <linux/slab.h> |
24 | #include <linux/proc_fs.h> | 25 | #include <linux/proc_fs.h> |
25 | 26 | ||
27 | /** | ||
28 | * struct alias_prop - Alias property in 'aliases' node | ||
29 | * @link: List node to link the structure in aliases_lookup list | ||
30 | * @alias: Alias property name | ||
31 | * @np: Pointer to device_node that the alias stands for | ||
32 | * @id: Index value from end of alias name | ||
33 | * @stem: Alias string without the index | ||
34 | * | ||
35 | * The structure represents one alias property of 'aliases' node as | ||
36 | * an entry in aliases_lookup list. | ||
37 | */ | ||
38 | struct alias_prop { | ||
39 | struct list_head link; | ||
40 | const char *alias; | ||
41 | struct device_node *np; | ||
42 | int id; | ||
43 | char stem[0]; | ||
44 | }; | ||
45 | |||
46 | static LIST_HEAD(aliases_lookup); | ||
47 | |||
26 | struct device_node *allnodes; | 48 | struct device_node *allnodes; |
27 | struct device_node *of_chosen; | 49 | struct device_node *of_chosen; |
50 | struct device_node *of_aliases; | ||
51 | |||
52 | static DEFINE_MUTEX(of_aliases_mutex); | ||
28 | 53 | ||
29 | /* use when traversing tree through the allnext, child, sibling, | 54 | /* use when traversing tree through the allnext, child, sibling, |
30 | * or parent members of struct device_node. | 55 | * or parent members of struct device_node. |
@@ -632,6 +657,35 @@ int of_property_read_u32_array(const struct device_node *np, | |||
632 | EXPORT_SYMBOL_GPL(of_property_read_u32_array); | 657 | EXPORT_SYMBOL_GPL(of_property_read_u32_array); |
633 | 658 | ||
634 | /** | 659 | /** |
660 | * of_property_read_u64 - Find and read a 64 bit integer from a property | ||
661 | * @np: device node from which the property value is to be read. | ||
662 | * @propname: name of the property to be searched. | ||
663 | * @out_value: pointer to return value, modified only if return value is 0. | ||
664 | * | ||
665 | * Search for a property in a device node and read a 64-bit value from | ||
666 | * it. Returns 0 on success, -EINVAL if the property does not exist, | ||
667 | * -ENODATA if property does not have a value, and -EOVERFLOW if the | ||
668 | * property data isn't large enough. | ||
669 | * | ||
670 | * The out_value is modified only if a valid u64 value can be decoded. | ||
671 | */ | ||
672 | int of_property_read_u64(const struct device_node *np, const char *propname, | ||
673 | u64 *out_value) | ||
674 | { | ||
675 | struct property *prop = of_find_property(np, propname, NULL); | ||
676 | |||
677 | if (!prop) | ||
678 | return -EINVAL; | ||
679 | if (!prop->value) | ||
680 | return -ENODATA; | ||
681 | if (sizeof(*out_value) > prop->length) | ||
682 | return -EOVERFLOW; | ||
683 | *out_value = of_read_number(prop->value, 2); | ||
684 | return 0; | ||
685 | } | ||
686 | EXPORT_SYMBOL_GPL(of_property_read_u64); | ||
687 | |||
688 | /** | ||
635 | * of_property_read_string - Find and read a string from a property | 689 | * of_property_read_string - Find and read a string from a property |
636 | * @np: device node from which the property value is to be read. | 690 | * @np: device node from which the property value is to be read. |
637 | * @propname: name of the property to be searched. | 691 | * @propname: name of the property to be searched. |
@@ -988,3 +1042,99 @@ out_unlock: | |||
988 | } | 1042 | } |
989 | #endif /* defined(CONFIG_OF_DYNAMIC) */ | 1043 | #endif /* defined(CONFIG_OF_DYNAMIC) */ |
990 | 1044 | ||
1045 | static void of_alias_add(struct alias_prop *ap, struct device_node *np, | ||
1046 | int id, const char *stem, int stem_len) | ||
1047 | { | ||
1048 | ap->np = np; | ||
1049 | ap->id = id; | ||
1050 | strncpy(ap->stem, stem, stem_len); | ||
1051 | ap->stem[stem_len] = 0; | ||
1052 | list_add_tail(&ap->link, &aliases_lookup); | ||
1053 | pr_debug("adding DT alias:%s: stem=%s id=%i node=%s\n", | ||
1054 | ap->alias, ap->stem, ap->id, np ? np->full_name : NULL); | ||
1055 | } | ||
1056 | |||
1057 | /** | ||
1058 | * of_alias_scan - Scan all properties of 'aliases' node | ||
1059 | * | ||
1060 | * The function scans all the properties of 'aliases' node and populate | ||
1061 | * the the global lookup table with the properties. It returns the | ||
1062 | * number of alias_prop found, or error code in error case. | ||
1063 | * | ||
1064 | * @dt_alloc: An allocator that provides a virtual address to memory | ||
1065 | * for the resulting tree | ||
1066 | */ | ||
1067 | void of_alias_scan(void * (*dt_alloc)(u64 size, u64 align)) | ||
1068 | { | ||
1069 | struct property *pp; | ||
1070 | |||
1071 | of_chosen = of_find_node_by_path("/chosen"); | ||
1072 | if (of_chosen == NULL) | ||
1073 | of_chosen = of_find_node_by_path("/chosen@0"); | ||
1074 | of_aliases = of_find_node_by_path("/aliases"); | ||
1075 | if (!of_aliases) | ||
1076 | return; | ||
1077 | |||
1078 | for_each_property(pp, of_aliases->properties) { | ||
1079 | const char *start = pp->name; | ||
1080 | const char *end = start + strlen(start); | ||
1081 | struct device_node *np; | ||
1082 | struct alias_prop *ap; | ||
1083 | int id, len; | ||
1084 | |||
1085 | /* Skip those we do not want to proceed */ | ||
1086 | if (!strcmp(pp->name, "name") || | ||
1087 | !strcmp(pp->name, "phandle") || | ||
1088 | !strcmp(pp->name, "linux,phandle")) | ||
1089 | continue; | ||
1090 | |||
1091 | np = of_find_node_by_path(pp->value); | ||
1092 | if (!np) | ||
1093 | continue; | ||
1094 | |||
1095 | /* walk the alias backwards to extract the id and work out | ||
1096 | * the 'stem' string */ | ||
1097 | while (isdigit(*(end-1)) && end > start) | ||
1098 | end--; | ||
1099 | len = end - start; | ||
1100 | |||
1101 | if (kstrtoint(end, 10, &id) < 0) | ||
1102 | continue; | ||
1103 | |||
1104 | /* Allocate an alias_prop with enough space for the stem */ | ||
1105 | ap = dt_alloc(sizeof(*ap) + len + 1, 4); | ||
1106 | if (!ap) | ||
1107 | continue; | ||
1108 | ap->alias = start; | ||
1109 | of_alias_add(ap, np, id, start, len); | ||
1110 | } | ||
1111 | } | ||
1112 | |||
1113 | /** | ||
1114 | * of_alias_get_id - Get alias id for the given device_node | ||
1115 | * @np: Pointer to the given device_node | ||
1116 | * @stem: Alias stem of the given device_node | ||
1117 | * | ||
1118 | * The function travels the lookup table to get alias id for the given | ||
1119 | * device_node and alias stem. It returns the alias id if find it. | ||
1120 | */ | ||
1121 | int of_alias_get_id(struct device_node *np, const char *stem) | ||
1122 | { | ||
1123 | struct alias_prop *app; | ||
1124 | int id = -ENODEV; | ||
1125 | |||
1126 | mutex_lock(&of_aliases_mutex); | ||
1127 | list_for_each_entry(app, &aliases_lookup, link) { | ||
1128 | if (strcmp(app->stem, stem) != 0) | ||
1129 | continue; | ||
1130 | |||
1131 | if (np == app->np) { | ||
1132 | id = app->id; | ||
1133 | break; | ||
1134 | } | ||
1135 | } | ||
1136 | mutex_unlock(&of_aliases_mutex); | ||
1137 | |||
1138 | return id; | ||
1139 | } | ||
1140 | EXPORT_SYMBOL_GPL(of_alias_get_id); | ||
diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c index 65200af29c52..aeec35bc3789 100644 --- a/drivers/of/fdt.c +++ b/drivers/of/fdt.c | |||
@@ -707,10 +707,8 @@ void __init unflatten_device_tree(void) | |||
707 | __unflatten_device_tree(initial_boot_params, &allnodes, | 707 | __unflatten_device_tree(initial_boot_params, &allnodes, |
708 | early_init_dt_alloc_memory_arch); | 708 | early_init_dt_alloc_memory_arch); |
709 | 709 | ||
710 | /* Get pointer to OF "/chosen" node for use everywhere */ | 710 | /* Get pointer to "/chosen" and "/aliasas" nodes for use everywhere */ |
711 | of_chosen = of_find_node_by_path("/chosen"); | 711 | of_alias_scan(early_init_dt_alloc_memory_arch); |
712 | if (of_chosen == NULL) | ||
713 | of_chosen = of_find_node_by_path("/chosen@0"); | ||
714 | } | 712 | } |
715 | 713 | ||
716 | #endif /* CONFIG_OF_EARLY_FLATTREE */ | 714 | #endif /* CONFIG_OF_EARLY_FLATTREE */ |
diff --git a/drivers/of/irq.c b/drivers/of/irq.c index 9f689f1da0fc..6a5b5e777dd2 100644 --- a/drivers/of/irq.c +++ b/drivers/of/irq.c | |||
@@ -58,27 +58,27 @@ EXPORT_SYMBOL_GPL(irq_of_parse_and_map); | |||
58 | */ | 58 | */ |
59 | struct device_node *of_irq_find_parent(struct device_node *child) | 59 | struct device_node *of_irq_find_parent(struct device_node *child) |
60 | { | 60 | { |
61 | struct device_node *p; | 61 | struct device_node *p, *c = child; |
62 | const __be32 *parp; | 62 | const __be32 *parp; |
63 | 63 | ||
64 | if (!of_node_get(child)) | 64 | if (!of_node_get(c)) |
65 | return NULL; | 65 | return NULL; |
66 | 66 | ||
67 | do { | 67 | do { |
68 | parp = of_get_property(child, "interrupt-parent", NULL); | 68 | parp = of_get_property(c, "interrupt-parent", NULL); |
69 | if (parp == NULL) | 69 | if (parp == NULL) |
70 | p = of_get_parent(child); | 70 | p = of_get_parent(c); |
71 | else { | 71 | else { |
72 | if (of_irq_workarounds & OF_IMAP_NO_PHANDLE) | 72 | if (of_irq_workarounds & OF_IMAP_NO_PHANDLE) |
73 | p = of_node_get(of_irq_dflt_pic); | 73 | p = of_node_get(of_irq_dflt_pic); |
74 | else | 74 | else |
75 | p = of_find_node_by_phandle(be32_to_cpup(parp)); | 75 | p = of_find_node_by_phandle(be32_to_cpup(parp)); |
76 | } | 76 | } |
77 | of_node_put(child); | 77 | of_node_put(c); |
78 | child = p; | 78 | c = p; |
79 | } while (p && of_get_property(p, "#interrupt-cells", NULL) == NULL); | 79 | } while (p && of_get_property(p, "#interrupt-cells", NULL) == NULL); |
80 | 80 | ||
81 | return p; | 81 | return (p == child) ? NULL : p; |
82 | } | 82 | } |
83 | 83 | ||
84 | /** | 84 | /** |
diff --git a/drivers/of/of_mdio.c b/drivers/of/of_mdio.c index d35e300b0ad1..980c079e4443 100644 --- a/drivers/of/of_mdio.c +++ b/drivers/of/of_mdio.c | |||
@@ -83,7 +83,6 @@ int of_mdiobus_register(struct mii_bus *mdio, struct device_node *np) | |||
83 | addr); | 83 | addr); |
84 | continue; | 84 | continue; |
85 | } | 85 | } |
86 | phy_scan_fixups(phy); | ||
87 | 86 | ||
88 | /* Associate the OF node with the device structure so it | 87 | /* Associate the OF node with the device structure so it |
89 | * can be looked up later */ | 88 | * can be looked up later */ |
diff --git a/drivers/of/pdt.c b/drivers/of/pdt.c index 4d87b5dc9284..bc5b3990f6ed 100644 --- a/drivers/of/pdt.c +++ b/drivers/of/pdt.c | |||
@@ -229,6 +229,11 @@ static struct device_node * __init of_pdt_build_tree(struct device_node *parent, | |||
229 | return ret; | 229 | return ret; |
230 | } | 230 | } |
231 | 231 | ||
232 | static void *kernel_tree_alloc(u64 size, u64 align) | ||
233 | { | ||
234 | return prom_early_alloc(size); | ||
235 | } | ||
236 | |||
232 | void __init of_pdt_build_devicetree(phandle root_node, struct of_pdt_ops *ops) | 237 | void __init of_pdt_build_devicetree(phandle root_node, struct of_pdt_ops *ops) |
233 | { | 238 | { |
234 | struct device_node **nextp; | 239 | struct device_node **nextp; |
@@ -245,4 +250,7 @@ void __init of_pdt_build_devicetree(phandle root_node, struct of_pdt_ops *ops) | |||
245 | nextp = &allnodes->allnext; | 250 | nextp = &allnodes->allnext; |
246 | allnodes->child = of_pdt_build_tree(allnodes, | 251 | allnodes->child = of_pdt_build_tree(allnodes, |
247 | of_pdt_prom_ops->getchild(allnodes->phandle), &nextp); | 252 | of_pdt_prom_ops->getchild(allnodes->phandle), &nextp); |
253 | |||
254 | /* Get pointer to "/chosen" and "/aliasas" nodes for use everywhere */ | ||
255 | of_alias_scan(kernel_tree_alloc); | ||
248 | } | 256 | } |
diff --git a/drivers/tty/serial/altera_jtaguart.c b/drivers/tty/serial/altera_jtaguart.c index 00a73ecb2dfb..530181e49f6b 100644 --- a/drivers/tty/serial/altera_jtaguart.c +++ b/drivers/tty/serial/altera_jtaguart.c | |||
@@ -18,6 +18,7 @@ | |||
18 | #include <linux/interrupt.h> | 18 | #include <linux/interrupt.h> |
19 | #include <linux/module.h> | 19 | #include <linux/module.h> |
20 | #include <linux/console.h> | 20 | #include <linux/console.h> |
21 | #include <linux/of.h> | ||
21 | #include <linux/tty.h> | 22 | #include <linux/tty.h> |
22 | #include <linux/tty_flip.h> | 23 | #include <linux/tty_flip.h> |
23 | #include <linux/serial.h> | 24 | #include <linux/serial.h> |
@@ -472,8 +473,6 @@ static struct of_device_id altera_jtaguart_match[] = { | |||
472 | {}, | 473 | {}, |
473 | }; | 474 | }; |
474 | MODULE_DEVICE_TABLE(of, altera_jtaguart_match); | 475 | MODULE_DEVICE_TABLE(of, altera_jtaguart_match); |
475 | #else | ||
476 | #define altera_jtaguart_match NULL | ||
477 | #endif /* CONFIG_OF */ | 476 | #endif /* CONFIG_OF */ |
478 | 477 | ||
479 | static struct platform_driver altera_jtaguart_platform_driver = { | 478 | static struct platform_driver altera_jtaguart_platform_driver = { |
@@ -482,7 +481,7 @@ static struct platform_driver altera_jtaguart_platform_driver = { | |||
482 | .driver = { | 481 | .driver = { |
483 | .name = DRV_NAME, | 482 | .name = DRV_NAME, |
484 | .owner = THIS_MODULE, | 483 | .owner = THIS_MODULE, |
485 | .of_match_table = altera_jtaguart_match, | 484 | .of_match_table = of_match_ptr(altera_jtaguart_match), |
486 | }, | 485 | }, |
487 | }; | 486 | }; |
488 | 487 | ||
diff --git a/drivers/tty/serial/altera_uart.c b/drivers/tty/serial/altera_uart.c index d902558ccfd2..1d04c5037f25 100644 --- a/drivers/tty/serial/altera_uart.c +++ b/drivers/tty/serial/altera_uart.c | |||
@@ -616,8 +616,6 @@ static struct of_device_id altera_uart_match[] = { | |||
616 | {}, | 616 | {}, |
617 | }; | 617 | }; |
618 | MODULE_DEVICE_TABLE(of, altera_uart_match); | 618 | MODULE_DEVICE_TABLE(of, altera_uart_match); |
619 | #else | ||
620 | #define altera_uart_match NULL | ||
621 | #endif /* CONFIG_OF */ | 619 | #endif /* CONFIG_OF */ |
622 | 620 | ||
623 | static struct platform_driver altera_uart_platform_driver = { | 621 | static struct platform_driver altera_uart_platform_driver = { |
@@ -626,7 +624,7 @@ static struct platform_driver altera_uart_platform_driver = { | |||
626 | .driver = { | 624 | .driver = { |
627 | .name = DRV_NAME, | 625 | .name = DRV_NAME, |
628 | .owner = THIS_MODULE, | 626 | .owner = THIS_MODULE, |
629 | .of_match_table = altera_uart_match, | 627 | .of_match_table = of_match_ptr(altera_uart_match), |
630 | }, | 628 | }, |
631 | }; | 629 | }; |
632 | 630 | ||
diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c index 54ffdc6243f9..163fc9021f5a 100644 --- a/drivers/tty/serial/imx.c +++ b/drivers/tty/serial/imx.c | |||
@@ -1290,17 +1290,20 @@ static int serial_imx_resume(struct platform_device *dev) | |||
1290 | static int serial_imx_probe_dt(struct imx_port *sport, | 1290 | static int serial_imx_probe_dt(struct imx_port *sport, |
1291 | struct platform_device *pdev) | 1291 | struct platform_device *pdev) |
1292 | { | 1292 | { |
1293 | static int portnum = 0; | ||
1294 | struct device_node *np = pdev->dev.of_node; | 1293 | struct device_node *np = pdev->dev.of_node; |
1295 | const struct of_device_id *of_id = | 1294 | const struct of_device_id *of_id = |
1296 | of_match_device(imx_uart_dt_ids, &pdev->dev); | 1295 | of_match_device(imx_uart_dt_ids, &pdev->dev); |
1296 | int ret; | ||
1297 | 1297 | ||
1298 | if (!np) | 1298 | if (!np) |
1299 | return -ENODEV; | 1299 | return -ENODEV; |
1300 | 1300 | ||
1301 | sport->port.line = portnum++; | 1301 | ret = of_alias_get_id(np, "serial"); |
1302 | if (sport->port.line >= UART_NR) | 1302 | if (ret < 0) { |
1303 | return -EINVAL; | 1303 | dev_err(&pdev->dev, "failed to get alias id, errno %d\n", ret); |
1304 | return -ENODEV; | ||
1305 | } | ||
1306 | sport->port.line = ret; | ||
1304 | 1307 | ||
1305 | if (of_get_property(np, "fsl,uart-has-rtscts", NULL)) | 1308 | if (of_get_property(np, "fsl,uart-has-rtscts", NULL)) |
1306 | sport->have_rtscts = 1; | 1309 | sport->have_rtscts = 1; |
diff --git a/drivers/tty/serial/uartlite.c b/drivers/tty/serial/uartlite.c index b908615ccaaf..6cd414341d5e 100644 --- a/drivers/tty/serial/uartlite.c +++ b/drivers/tty/serial/uartlite.c | |||
@@ -569,8 +569,6 @@ static struct of_device_id ulite_of_match[] __devinitdata = { | |||
569 | {} | 569 | {} |
570 | }; | 570 | }; |
571 | MODULE_DEVICE_TABLE(of, ulite_of_match); | 571 | MODULE_DEVICE_TABLE(of, ulite_of_match); |
572 | #else /* CONFIG_OF */ | ||
573 | #define ulite_of_match NULL | ||
574 | #endif /* CONFIG_OF */ | 572 | #endif /* CONFIG_OF */ |
575 | 573 | ||
576 | static int __devinit ulite_probe(struct platform_device *pdev) | 574 | static int __devinit ulite_probe(struct platform_device *pdev) |
@@ -610,7 +608,7 @@ static struct platform_driver ulite_platform_driver = { | |||
610 | .driver = { | 608 | .driver = { |
611 | .owner = THIS_MODULE, | 609 | .owner = THIS_MODULE, |
612 | .name = "uartlite", | 610 | .name = "uartlite", |
613 | .of_match_table = ulite_of_match, | 611 | .of_match_table = of_match_ptr(ulite_of_match), |
614 | }, | 612 | }, |
615 | }; | 613 | }; |
616 | 614 | ||