diff options
author | Jiri Kosina <jkosina@suse.cz> | 2013-01-29 04:48:30 -0500 |
---|---|---|
committer | Jiri Kosina <jkosina@suse.cz> | 2013-01-29 04:48:30 -0500 |
commit | 617677295b53a40d0e54aac4cbbc216ffbc755dd (patch) | |
tree | 51b9e87213243ed5efff252c8e8d8fec4eebc588 /drivers/of | |
parent | 5c8d1b68e01a144813e38795fe6dbe7ebb506131 (diff) | |
parent | 6abb7c25775b7fb2225ad0508236d63ca710e65f (diff) |
Merge branch 'master' into for-next
Conflicts:
drivers/devfreq/exynos4_bus.c
Sync with Linus' tree to be able to apply patches that are
against newer code (mvneta).
Diffstat (limited to 'drivers/of')
-rw-r--r-- | drivers/of/Kconfig | 2 | ||||
-rw-r--r-- | drivers/of/base.c | 274 | ||||
-rw-r--r-- | drivers/of/fdt.c | 26 | ||||
-rw-r--r-- | drivers/of/of_i2c.c | 2 | ||||
-rw-r--r-- | drivers/of/of_mdio.c | 2 | ||||
-rw-r--r-- | drivers/of/pdt.c | 12 |
6 files changed, 256 insertions, 62 deletions
diff --git a/drivers/of/Kconfig b/drivers/of/Kconfig index dfba3e64d595..d37bfcf5a3a2 100644 --- a/drivers/of/Kconfig +++ b/drivers/of/Kconfig | |||
@@ -53,7 +53,7 @@ config OF_DEVICE | |||
53 | 53 | ||
54 | config OF_I2C | 54 | config OF_I2C |
55 | def_tristate I2C | 55 | def_tristate I2C |
56 | depends on I2C && !SPARC | 56 | depends on I2C |
57 | help | 57 | help |
58 | OpenFirmware I2C accessors | 58 | OpenFirmware I2C accessors |
59 | 59 | ||
diff --git a/drivers/of/base.c b/drivers/of/base.c index af3b22ac7627..2390ddb22d60 100644 --- a/drivers/of/base.c +++ b/drivers/of/base.c | |||
@@ -45,7 +45,8 @@ struct alias_prop { | |||
45 | 45 | ||
46 | static LIST_HEAD(aliases_lookup); | 46 | static LIST_HEAD(aliases_lookup); |
47 | 47 | ||
48 | struct device_node *allnodes; | 48 | struct device_node *of_allnodes; |
49 | EXPORT_SYMBOL(of_allnodes); | ||
49 | struct device_node *of_chosen; | 50 | struct device_node *of_chosen; |
50 | struct device_node *of_aliases; | 51 | struct device_node *of_aliases; |
51 | 52 | ||
@@ -199,7 +200,7 @@ struct device_node *of_find_all_nodes(struct device_node *prev) | |||
199 | struct device_node *np; | 200 | struct device_node *np; |
200 | 201 | ||
201 | read_lock(&devtree_lock); | 202 | read_lock(&devtree_lock); |
202 | np = prev ? prev->allnext : allnodes; | 203 | np = prev ? prev->allnext : of_allnodes; |
203 | for (; np != NULL; np = np->allnext) | 204 | for (; np != NULL; np = np->allnext) |
204 | if (of_node_get(np)) | 205 | if (of_node_get(np)) |
205 | break; | 206 | break; |
@@ -422,7 +423,7 @@ EXPORT_SYMBOL(of_get_child_by_name); | |||
422 | */ | 423 | */ |
423 | struct device_node *of_find_node_by_path(const char *path) | 424 | struct device_node *of_find_node_by_path(const char *path) |
424 | { | 425 | { |
425 | struct device_node *np = allnodes; | 426 | struct device_node *np = of_allnodes; |
426 | 427 | ||
427 | read_lock(&devtree_lock); | 428 | read_lock(&devtree_lock); |
428 | for (; np; np = np->allnext) { | 429 | for (; np; np = np->allnext) { |
@@ -452,7 +453,7 @@ struct device_node *of_find_node_by_name(struct device_node *from, | |||
452 | struct device_node *np; | 453 | struct device_node *np; |
453 | 454 | ||
454 | read_lock(&devtree_lock); | 455 | read_lock(&devtree_lock); |
455 | np = from ? from->allnext : allnodes; | 456 | np = from ? from->allnext : of_allnodes; |
456 | for (; np; np = np->allnext) | 457 | for (; np; np = np->allnext) |
457 | if (np->name && (of_node_cmp(np->name, name) == 0) | 458 | if (np->name && (of_node_cmp(np->name, name) == 0) |
458 | && of_node_get(np)) | 459 | && of_node_get(np)) |
@@ -481,7 +482,7 @@ struct device_node *of_find_node_by_type(struct device_node *from, | |||
481 | struct device_node *np; | 482 | struct device_node *np; |
482 | 483 | ||
483 | read_lock(&devtree_lock); | 484 | read_lock(&devtree_lock); |
484 | np = from ? from->allnext : allnodes; | 485 | np = from ? from->allnext : of_allnodes; |
485 | for (; np; np = np->allnext) | 486 | for (; np; np = np->allnext) |
486 | if (np->type && (of_node_cmp(np->type, type) == 0) | 487 | if (np->type && (of_node_cmp(np->type, type) == 0) |
487 | && of_node_get(np)) | 488 | && of_node_get(np)) |
@@ -512,7 +513,7 @@ struct device_node *of_find_compatible_node(struct device_node *from, | |||
512 | struct device_node *np; | 513 | struct device_node *np; |
513 | 514 | ||
514 | read_lock(&devtree_lock); | 515 | read_lock(&devtree_lock); |
515 | np = from ? from->allnext : allnodes; | 516 | np = from ? from->allnext : of_allnodes; |
516 | for (; np; np = np->allnext) { | 517 | for (; np; np = np->allnext) { |
517 | if (type | 518 | if (type |
518 | && !(np->type && (of_node_cmp(np->type, type) == 0))) | 519 | && !(np->type && (of_node_cmp(np->type, type) == 0))) |
@@ -545,7 +546,7 @@ struct device_node *of_find_node_with_property(struct device_node *from, | |||
545 | struct property *pp; | 546 | struct property *pp; |
546 | 547 | ||
547 | read_lock(&devtree_lock); | 548 | read_lock(&devtree_lock); |
548 | np = from ? from->allnext : allnodes; | 549 | np = from ? from->allnext : of_allnodes; |
549 | for (; np; np = np->allnext) { | 550 | for (; np; np = np->allnext) { |
550 | for (pp = np->properties; pp; pp = pp->next) { | 551 | for (pp = np->properties; pp; pp = pp->next) { |
551 | if (of_prop_cmp(pp->name, prop_name) == 0) { | 552 | if (of_prop_cmp(pp->name, prop_name) == 0) { |
@@ -594,33 +595,41 @@ const struct of_device_id *of_match_node(const struct of_device_id *matches, | |||
594 | EXPORT_SYMBOL(of_match_node); | 595 | EXPORT_SYMBOL(of_match_node); |
595 | 596 | ||
596 | /** | 597 | /** |
597 | * of_find_matching_node - Find a node based on an of_device_id match | 598 | * of_find_matching_node_and_match - Find a node based on an of_device_id |
598 | * table. | 599 | * match table. |
599 | * @from: The node to start searching from or NULL, the node | 600 | * @from: The node to start searching from or NULL, the node |
600 | * you pass will not be searched, only the next one | 601 | * you pass will not be searched, only the next one |
601 | * will; typically, you pass what the previous call | 602 | * will; typically, you pass what the previous call |
602 | * returned. of_node_put() will be called on it | 603 | * returned. of_node_put() will be called on it |
603 | * @matches: array of of device match structures to search in | 604 | * @matches: array of of device match structures to search in |
605 | * @match Updated to point at the matches entry which matched | ||
604 | * | 606 | * |
605 | * Returns a node pointer with refcount incremented, use | 607 | * Returns a node pointer with refcount incremented, use |
606 | * of_node_put() on it when done. | 608 | * of_node_put() on it when done. |
607 | */ | 609 | */ |
608 | struct device_node *of_find_matching_node(struct device_node *from, | 610 | struct device_node *of_find_matching_node_and_match(struct device_node *from, |
609 | const struct of_device_id *matches) | 611 | const struct of_device_id *matches, |
612 | const struct of_device_id **match) | ||
610 | { | 613 | { |
611 | struct device_node *np; | 614 | struct device_node *np; |
612 | 615 | ||
616 | if (match) | ||
617 | *match = NULL; | ||
618 | |||
613 | read_lock(&devtree_lock); | 619 | read_lock(&devtree_lock); |
614 | np = from ? from->allnext : allnodes; | 620 | np = from ? from->allnext : of_allnodes; |
615 | for (; np; np = np->allnext) { | 621 | for (; np; np = np->allnext) { |
616 | if (of_match_node(matches, np) && of_node_get(np)) | 622 | if (of_match_node(matches, np) && of_node_get(np)) { |
623 | if (match) | ||
624 | *match = matches; | ||
617 | break; | 625 | break; |
626 | } | ||
618 | } | 627 | } |
619 | of_node_put(from); | 628 | of_node_put(from); |
620 | read_unlock(&devtree_lock); | 629 | read_unlock(&devtree_lock); |
621 | return np; | 630 | return np; |
622 | } | 631 | } |
623 | EXPORT_SYMBOL(of_find_matching_node); | 632 | EXPORT_SYMBOL(of_find_matching_node_and_match); |
624 | 633 | ||
625 | /** | 634 | /** |
626 | * of_modalias_node - Lookup appropriate modalias for a device node | 635 | * of_modalias_node - Lookup appropriate modalias for a device node |
@@ -661,7 +670,7 @@ struct device_node *of_find_node_by_phandle(phandle handle) | |||
661 | struct device_node *np; | 670 | struct device_node *np; |
662 | 671 | ||
663 | read_lock(&devtree_lock); | 672 | read_lock(&devtree_lock); |
664 | for (np = allnodes; np; np = np->allnext) | 673 | for (np = of_allnodes; np; np = np->allnext) |
665 | if (np->phandle == handle) | 674 | if (np->phandle == handle) |
666 | break; | 675 | break; |
667 | of_node_get(np); | 676 | of_node_get(np); |
@@ -671,12 +680,89 @@ struct device_node *of_find_node_by_phandle(phandle handle) | |||
671 | EXPORT_SYMBOL(of_find_node_by_phandle); | 680 | EXPORT_SYMBOL(of_find_node_by_phandle); |
672 | 681 | ||
673 | /** | 682 | /** |
683 | * of_property_read_u8_array - Find and read an array of u8 from a property. | ||
684 | * | ||
685 | * @np: device node from which the property value is to be read. | ||
686 | * @propname: name of the property to be searched. | ||
687 | * @out_value: pointer to return value, modified only if return value is 0. | ||
688 | * @sz: number of array elements to read | ||
689 | * | ||
690 | * Search for a property in a device node and read 8-bit value(s) from | ||
691 | * it. Returns 0 on success, -EINVAL if the property does not exist, | ||
692 | * -ENODATA if property does not have a value, and -EOVERFLOW if the | ||
693 | * property data isn't large enough. | ||
694 | * | ||
695 | * dts entry of array should be like: | ||
696 | * property = /bits/ 8 <0x50 0x60 0x70>; | ||
697 | * | ||
698 | * The out_value is modified only if a valid u8 value can be decoded. | ||
699 | */ | ||
700 | int of_property_read_u8_array(const struct device_node *np, | ||
701 | const char *propname, u8 *out_values, size_t sz) | ||
702 | { | ||
703 | struct property *prop = of_find_property(np, propname, NULL); | ||
704 | const u8 *val; | ||
705 | |||
706 | if (!prop) | ||
707 | return -EINVAL; | ||
708 | if (!prop->value) | ||
709 | return -ENODATA; | ||
710 | if ((sz * sizeof(*out_values)) > prop->length) | ||
711 | return -EOVERFLOW; | ||
712 | |||
713 | val = prop->value; | ||
714 | while (sz--) | ||
715 | *out_values++ = *val++; | ||
716 | return 0; | ||
717 | } | ||
718 | EXPORT_SYMBOL_GPL(of_property_read_u8_array); | ||
719 | |||
720 | /** | ||
721 | * of_property_read_u16_array - Find and read an array of u16 from a property. | ||
722 | * | ||
723 | * @np: device node from which the property value is to be read. | ||
724 | * @propname: name of the property to be searched. | ||
725 | * @out_value: pointer to return value, modified only if return value is 0. | ||
726 | * @sz: number of array elements to read | ||
727 | * | ||
728 | * Search for a property in a device node and read 16-bit value(s) from | ||
729 | * it. Returns 0 on success, -EINVAL if the property does not exist, | ||
730 | * -ENODATA if property does not have a value, and -EOVERFLOW if the | ||
731 | * property data isn't large enough. | ||
732 | * | ||
733 | * dts entry of array should be like: | ||
734 | * property = /bits/ 16 <0x5000 0x6000 0x7000>; | ||
735 | * | ||
736 | * The out_value is modified only if a valid u16 value can be decoded. | ||
737 | */ | ||
738 | int of_property_read_u16_array(const struct device_node *np, | ||
739 | const char *propname, u16 *out_values, size_t sz) | ||
740 | { | ||
741 | struct property *prop = of_find_property(np, propname, NULL); | ||
742 | const __be16 *val; | ||
743 | |||
744 | if (!prop) | ||
745 | return -EINVAL; | ||
746 | if (!prop->value) | ||
747 | return -ENODATA; | ||
748 | if ((sz * sizeof(*out_values)) > prop->length) | ||
749 | return -EOVERFLOW; | ||
750 | |||
751 | val = prop->value; | ||
752 | while (sz--) | ||
753 | *out_values++ = be16_to_cpup(val++); | ||
754 | return 0; | ||
755 | } | ||
756 | EXPORT_SYMBOL_GPL(of_property_read_u16_array); | ||
757 | |||
758 | /** | ||
674 | * of_property_read_u32_array - Find and read an array of 32 bit integers | 759 | * of_property_read_u32_array - Find and read an array of 32 bit integers |
675 | * from a property. | 760 | * from a property. |
676 | * | 761 | * |
677 | * @np: device node from which the property value is to be read. | 762 | * @np: device node from which the property value is to be read. |
678 | * @propname: name of the property to be searched. | 763 | * @propname: name of the property to be searched. |
679 | * @out_value: pointer to return value, modified only if return value is 0. | 764 | * @out_value: pointer to return value, modified only if return value is 0. |
765 | * @sz: number of array elements to read | ||
680 | * | 766 | * |
681 | * Search for a property in a device node and read 32-bit value(s) from | 767 | * Search for a property in a device node and read 32-bit value(s) from |
682 | * it. Returns 0 on success, -EINVAL if the property does not exist, | 768 | * it. Returns 0 on success, -EINVAL if the property does not exist, |
@@ -893,8 +979,8 @@ EXPORT_SYMBOL_GPL(of_property_count_strings); | |||
893 | * Returns the device_node pointer with refcount incremented. Use | 979 | * Returns the device_node pointer with refcount incremented. Use |
894 | * of_node_put() on it when done. | 980 | * of_node_put() on it when done. |
895 | */ | 981 | */ |
896 | struct device_node * | 982 | struct device_node *of_parse_phandle(const struct device_node *np, |
897 | of_parse_phandle(struct device_node *np, const char *phandle_name, int index) | 983 | const char *phandle_name, int index) |
898 | { | 984 | { |
899 | const __be32 *phandle; | 985 | const __be32 *phandle; |
900 | int size; | 986 | int size; |
@@ -939,7 +1025,7 @@ EXPORT_SYMBOL(of_parse_phandle); | |||
939 | * To get a device_node of the `node2' node you may call this: | 1025 | * To get a device_node of the `node2' node you may call this: |
940 | * of_parse_phandle_with_args(node3, "list", "#list-cells", 1, &args); | 1026 | * of_parse_phandle_with_args(node3, "list", "#list-cells", 1, &args); |
941 | */ | 1027 | */ |
942 | int of_parse_phandle_with_args(struct device_node *np, const char *list_name, | 1028 | int of_parse_phandle_with_args(const struct device_node *np, const char *list_name, |
943 | const char *cells_name, int index, | 1029 | const char *cells_name, int index, |
944 | struct of_phandle_args *out_args) | 1030 | struct of_phandle_args *out_args) |
945 | { | 1031 | { |
@@ -1028,13 +1114,36 @@ int of_parse_phandle_with_args(struct device_node *np, const char *list_name, | |||
1028 | } | 1114 | } |
1029 | EXPORT_SYMBOL(of_parse_phandle_with_args); | 1115 | EXPORT_SYMBOL(of_parse_phandle_with_args); |
1030 | 1116 | ||
1117 | #if defined(CONFIG_OF_DYNAMIC) | ||
1118 | static int of_property_notify(int action, struct device_node *np, | ||
1119 | struct property *prop) | ||
1120 | { | ||
1121 | struct of_prop_reconfig pr; | ||
1122 | |||
1123 | pr.dn = np; | ||
1124 | pr.prop = prop; | ||
1125 | return of_reconfig_notify(action, &pr); | ||
1126 | } | ||
1127 | #else | ||
1128 | static int of_property_notify(int action, struct device_node *np, | ||
1129 | struct property *prop) | ||
1130 | { | ||
1131 | return 0; | ||
1132 | } | ||
1133 | #endif | ||
1134 | |||
1031 | /** | 1135 | /** |
1032 | * prom_add_property - Add a property to a node | 1136 | * of_add_property - Add a property to a node |
1033 | */ | 1137 | */ |
1034 | int prom_add_property(struct device_node *np, struct property *prop) | 1138 | int of_add_property(struct device_node *np, struct property *prop) |
1035 | { | 1139 | { |
1036 | struct property **next; | 1140 | struct property **next; |
1037 | unsigned long flags; | 1141 | unsigned long flags; |
1142 | int rc; | ||
1143 | |||
1144 | rc = of_property_notify(OF_RECONFIG_ADD_PROPERTY, np, prop); | ||
1145 | if (rc) | ||
1146 | return rc; | ||
1038 | 1147 | ||
1039 | prop->next = NULL; | 1148 | prop->next = NULL; |
1040 | write_lock_irqsave(&devtree_lock, flags); | 1149 | write_lock_irqsave(&devtree_lock, flags); |
@@ -1060,18 +1169,23 @@ int prom_add_property(struct device_node *np, struct property *prop) | |||
1060 | } | 1169 | } |
1061 | 1170 | ||
1062 | /** | 1171 | /** |
1063 | * prom_remove_property - Remove a property from a node. | 1172 | * of_remove_property - Remove a property from a node. |
1064 | * | 1173 | * |
1065 | * Note that we don't actually remove it, since we have given out | 1174 | * Note that we don't actually remove it, since we have given out |
1066 | * who-knows-how-many pointers to the data using get-property. | 1175 | * who-knows-how-many pointers to the data using get-property. |
1067 | * Instead we just move the property to the "dead properties" | 1176 | * Instead we just move the property to the "dead properties" |
1068 | * list, so it won't be found any more. | 1177 | * list, so it won't be found any more. |
1069 | */ | 1178 | */ |
1070 | int prom_remove_property(struct device_node *np, struct property *prop) | 1179 | int of_remove_property(struct device_node *np, struct property *prop) |
1071 | { | 1180 | { |
1072 | struct property **next; | 1181 | struct property **next; |
1073 | unsigned long flags; | 1182 | unsigned long flags; |
1074 | int found = 0; | 1183 | int found = 0; |
1184 | int rc; | ||
1185 | |||
1186 | rc = of_property_notify(OF_RECONFIG_REMOVE_PROPERTY, np, prop); | ||
1187 | if (rc) | ||
1188 | return rc; | ||
1075 | 1189 | ||
1076 | write_lock_irqsave(&devtree_lock, flags); | 1190 | write_lock_irqsave(&devtree_lock, flags); |
1077 | next = &np->properties; | 1191 | next = &np->properties; |
@@ -1101,7 +1215,7 @@ int prom_remove_property(struct device_node *np, struct property *prop) | |||
1101 | } | 1215 | } |
1102 | 1216 | ||
1103 | /* | 1217 | /* |
1104 | * prom_update_property - Update a property in a node, if the property does | 1218 | * of_update_property - Update a property in a node, if the property does |
1105 | * not exist, add it. | 1219 | * not exist, add it. |
1106 | * | 1220 | * |
1107 | * Note that we don't actually remove it, since we have given out | 1221 | * Note that we don't actually remove it, since we have given out |
@@ -1109,19 +1223,22 @@ int prom_remove_property(struct device_node *np, struct property *prop) | |||
1109 | * Instead we just move the property to the "dead properties" list, | 1223 | * Instead we just move the property to the "dead properties" list, |
1110 | * and add the new property to the property list | 1224 | * and add the new property to the property list |
1111 | */ | 1225 | */ |
1112 | int prom_update_property(struct device_node *np, | 1226 | int of_update_property(struct device_node *np, struct property *newprop) |
1113 | struct property *newprop) | ||
1114 | { | 1227 | { |
1115 | struct property **next, *oldprop; | 1228 | struct property **next, *oldprop; |
1116 | unsigned long flags; | 1229 | unsigned long flags; |
1117 | int found = 0; | 1230 | int rc, found = 0; |
1231 | |||
1232 | rc = of_property_notify(OF_RECONFIG_UPDATE_PROPERTY, np, newprop); | ||
1233 | if (rc) | ||
1234 | return rc; | ||
1118 | 1235 | ||
1119 | if (!newprop->name) | 1236 | if (!newprop->name) |
1120 | return -EINVAL; | 1237 | return -EINVAL; |
1121 | 1238 | ||
1122 | oldprop = of_find_property(np, newprop->name, NULL); | 1239 | oldprop = of_find_property(np, newprop->name, NULL); |
1123 | if (!oldprop) | 1240 | if (!oldprop) |
1124 | return prom_add_property(np, newprop); | 1241 | return of_add_property(np, newprop); |
1125 | 1242 | ||
1126 | write_lock_irqsave(&devtree_lock, flags); | 1243 | write_lock_irqsave(&devtree_lock, flags); |
1127 | next = &np->properties; | 1244 | next = &np->properties; |
@@ -1160,20 +1277,87 @@ int prom_update_property(struct device_node *np, | |||
1160 | * device tree nodes. | 1277 | * device tree nodes. |
1161 | */ | 1278 | */ |
1162 | 1279 | ||
1280 | static BLOCKING_NOTIFIER_HEAD(of_reconfig_chain); | ||
1281 | |||
1282 | int of_reconfig_notifier_register(struct notifier_block *nb) | ||
1283 | { | ||
1284 | return blocking_notifier_chain_register(&of_reconfig_chain, nb); | ||
1285 | } | ||
1286 | EXPORT_SYMBOL_GPL(of_reconfig_notifier_register); | ||
1287 | |||
1288 | int of_reconfig_notifier_unregister(struct notifier_block *nb) | ||
1289 | { | ||
1290 | return blocking_notifier_chain_unregister(&of_reconfig_chain, nb); | ||
1291 | } | ||
1292 | EXPORT_SYMBOL_GPL(of_reconfig_notifier_unregister); | ||
1293 | |||
1294 | int of_reconfig_notify(unsigned long action, void *p) | ||
1295 | { | ||
1296 | int rc; | ||
1297 | |||
1298 | rc = blocking_notifier_call_chain(&of_reconfig_chain, action, p); | ||
1299 | return notifier_to_errno(rc); | ||
1300 | } | ||
1301 | |||
1302 | #ifdef CONFIG_PROC_DEVICETREE | ||
1303 | static void of_add_proc_dt_entry(struct device_node *dn) | ||
1304 | { | ||
1305 | struct proc_dir_entry *ent; | ||
1306 | |||
1307 | ent = proc_mkdir(strrchr(dn->full_name, '/') + 1, dn->parent->pde); | ||
1308 | if (ent) | ||
1309 | proc_device_tree_add_node(dn, ent); | ||
1310 | } | ||
1311 | #else | ||
1312 | static void of_add_proc_dt_entry(struct device_node *dn) | ||
1313 | { | ||
1314 | return; | ||
1315 | } | ||
1316 | #endif | ||
1317 | |||
1163 | /** | 1318 | /** |
1164 | * of_attach_node - Plug a device node into the tree and global list. | 1319 | * of_attach_node - Plug a device node into the tree and global list. |
1165 | */ | 1320 | */ |
1166 | void of_attach_node(struct device_node *np) | 1321 | int of_attach_node(struct device_node *np) |
1167 | { | 1322 | { |
1168 | unsigned long flags; | 1323 | unsigned long flags; |
1324 | int rc; | ||
1325 | |||
1326 | rc = of_reconfig_notify(OF_RECONFIG_ATTACH_NODE, np); | ||
1327 | if (rc) | ||
1328 | return rc; | ||
1169 | 1329 | ||
1170 | write_lock_irqsave(&devtree_lock, flags); | 1330 | write_lock_irqsave(&devtree_lock, flags); |
1171 | np->sibling = np->parent->child; | 1331 | np->sibling = np->parent->child; |
1172 | np->allnext = allnodes; | 1332 | np->allnext = of_allnodes; |
1173 | np->parent->child = np; | 1333 | np->parent->child = np; |
1174 | allnodes = np; | 1334 | of_allnodes = np; |
1175 | write_unlock_irqrestore(&devtree_lock, flags); | 1335 | write_unlock_irqrestore(&devtree_lock, flags); |
1336 | |||
1337 | of_add_proc_dt_entry(np); | ||
1338 | return 0; | ||
1339 | } | ||
1340 | |||
1341 | #ifdef CONFIG_PROC_DEVICETREE | ||
1342 | static void of_remove_proc_dt_entry(struct device_node *dn) | ||
1343 | { | ||
1344 | struct device_node *parent = dn->parent; | ||
1345 | struct property *prop = dn->properties; | ||
1346 | |||
1347 | while (prop) { | ||
1348 | remove_proc_entry(prop->name, dn->pde); | ||
1349 | prop = prop->next; | ||
1350 | } | ||
1351 | |||
1352 | if (dn->pde) | ||
1353 | remove_proc_entry(dn->pde->name, parent->pde); | ||
1176 | } | 1354 | } |
1355 | #else | ||
1356 | static void of_remove_proc_dt_entry(struct device_node *dn) | ||
1357 | { | ||
1358 | return; | ||
1359 | } | ||
1360 | #endif | ||
1177 | 1361 | ||
1178 | /** | 1362 | /** |
1179 | * of_detach_node - "Unplug" a node from the device tree. | 1363 | * of_detach_node - "Unplug" a node from the device tree. |
@@ -1181,22 +1365,35 @@ void of_attach_node(struct device_node *np) | |||
1181 | * The caller must hold a reference to the node. The memory associated with | 1365 | * The caller must hold a reference to the node. The memory associated with |
1182 | * the node is not freed until its refcount goes to zero. | 1366 | * the node is not freed until its refcount goes to zero. |
1183 | */ | 1367 | */ |
1184 | void of_detach_node(struct device_node *np) | 1368 | int of_detach_node(struct device_node *np) |
1185 | { | 1369 | { |
1186 | struct device_node *parent; | 1370 | struct device_node *parent; |
1187 | unsigned long flags; | 1371 | unsigned long flags; |
1372 | int rc = 0; | ||
1373 | |||
1374 | rc = of_reconfig_notify(OF_RECONFIG_DETACH_NODE, np); | ||
1375 | if (rc) | ||
1376 | return rc; | ||
1188 | 1377 | ||
1189 | write_lock_irqsave(&devtree_lock, flags); | 1378 | write_lock_irqsave(&devtree_lock, flags); |
1190 | 1379 | ||
1380 | if (of_node_check_flag(np, OF_DETACHED)) { | ||
1381 | /* someone already detached it */ | ||
1382 | write_unlock_irqrestore(&devtree_lock, flags); | ||
1383 | return rc; | ||
1384 | } | ||
1385 | |||
1191 | parent = np->parent; | 1386 | parent = np->parent; |
1192 | if (!parent) | 1387 | if (!parent) { |
1193 | goto out_unlock; | 1388 | write_unlock_irqrestore(&devtree_lock, flags); |
1389 | return rc; | ||
1390 | } | ||
1194 | 1391 | ||
1195 | if (allnodes == np) | 1392 | if (of_allnodes == np) |
1196 | allnodes = np->allnext; | 1393 | of_allnodes = np->allnext; |
1197 | else { | 1394 | else { |
1198 | struct device_node *prev; | 1395 | struct device_node *prev; |
1199 | for (prev = allnodes; | 1396 | for (prev = of_allnodes; |
1200 | prev->allnext != np; | 1397 | prev->allnext != np; |
1201 | prev = prev->allnext) | 1398 | prev = prev->allnext) |
1202 | ; | 1399 | ; |
@@ -1215,9 +1412,10 @@ void of_detach_node(struct device_node *np) | |||
1215 | } | 1412 | } |
1216 | 1413 | ||
1217 | of_node_set_flag(np, OF_DETACHED); | 1414 | of_node_set_flag(np, OF_DETACHED); |
1218 | |||
1219 | out_unlock: | ||
1220 | write_unlock_irqrestore(&devtree_lock, flags); | 1415 | write_unlock_irqrestore(&devtree_lock, flags); |
1416 | |||
1417 | of_remove_proc_dt_entry(np); | ||
1418 | return rc; | ||
1221 | } | 1419 | } |
1222 | #endif /* defined(CONFIG_OF_DYNAMIC) */ | 1420 | #endif /* defined(CONFIG_OF_DYNAMIC) */ |
1223 | 1421 | ||
diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c index 91a375fb6ae6..808be06bb67e 100644 --- a/drivers/of/fdt.c +++ b/drivers/of/fdt.c | |||
@@ -186,6 +186,8 @@ static unsigned long unflatten_dt_node(struct boot_param_header *blob, | |||
186 | */ | 186 | */ |
187 | fpsize = 1; | 187 | fpsize = 1; |
188 | allocl = 2; | 188 | allocl = 2; |
189 | l = 1; | ||
190 | *pathp = '\0'; | ||
189 | } else { | 191 | } else { |
190 | /* account for '/' and path size minus terminal 0 | 192 | /* account for '/' and path size minus terminal 0 |
191 | * already in 'l' | 193 | * already in 'l' |
@@ -198,10 +200,10 @@ static unsigned long unflatten_dt_node(struct boot_param_header *blob, | |||
198 | np = unflatten_dt_alloc(&mem, sizeof(struct device_node) + allocl, | 200 | np = unflatten_dt_alloc(&mem, sizeof(struct device_node) + allocl, |
199 | __alignof__(struct device_node)); | 201 | __alignof__(struct device_node)); |
200 | if (allnextpp) { | 202 | if (allnextpp) { |
203 | char *fn; | ||
201 | memset(np, 0, sizeof(*np)); | 204 | memset(np, 0, sizeof(*np)); |
202 | np->full_name = ((char *)np) + sizeof(struct device_node); | 205 | np->full_name = fn = ((char *)np) + sizeof(*np); |
203 | if (new_format) { | 206 | if (new_format) { |
204 | char *fn = np->full_name; | ||
205 | /* rebuild full path for new format */ | 207 | /* rebuild full path for new format */ |
206 | if (dad && dad->parent) { | 208 | if (dad && dad->parent) { |
207 | strcpy(fn, dad->full_name); | 209 | strcpy(fn, dad->full_name); |
@@ -215,9 +217,9 @@ static unsigned long unflatten_dt_node(struct boot_param_header *blob, | |||
215 | fn += strlen(fn); | 217 | fn += strlen(fn); |
216 | } | 218 | } |
217 | *(fn++) = '/'; | 219 | *(fn++) = '/'; |
218 | memcpy(fn, pathp, l); | 220 | } |
219 | } else | 221 | memcpy(fn, pathp, l); |
220 | memcpy(np->full_name, pathp, l); | 222 | |
221 | prev_pp = &np->properties; | 223 | prev_pp = &np->properties; |
222 | **allnextpp = np; | 224 | **allnextpp = np; |
223 | *allnextpp = &np->allnext; | 225 | *allnextpp = &np->allnext; |
@@ -459,7 +461,7 @@ int __init of_scan_flat_dt(int (*it)(unsigned long node, | |||
459 | 461 | ||
460 | do { | 462 | do { |
461 | u32 tag = be32_to_cpup((__be32 *)p); | 463 | u32 tag = be32_to_cpup((__be32 *)p); |
462 | char *pathp; | 464 | const char *pathp; |
463 | 465 | ||
464 | p += 4; | 466 | p += 4; |
465 | if (tag == OF_DT_END_NODE) { | 467 | if (tag == OF_DT_END_NODE) { |
@@ -486,14 +488,8 @@ int __init of_scan_flat_dt(int (*it)(unsigned long node, | |||
486 | depth++; | 488 | depth++; |
487 | pathp = (char *)p; | 489 | pathp = (char *)p; |
488 | p = ALIGN(p + strlen(pathp) + 1, 4); | 490 | p = ALIGN(p + strlen(pathp) + 1, 4); |
489 | if ((*pathp) == '/') { | 491 | if (*pathp == '/') |
490 | char *lp, *np; | 492 | pathp = kbasename(pathp); |
491 | for (lp = NULL, np = pathp; *np; np++) | ||
492 | if ((*np) == '/') | ||
493 | lp = np+1; | ||
494 | if (lp != NULL) | ||
495 | pathp = lp; | ||
496 | } | ||
497 | rc = it(p, pathp, depth, data); | 493 | rc = it(p, pathp, depth, data); |
498 | if (rc != 0) | 494 | if (rc != 0) |
499 | break; | 495 | break; |
@@ -710,7 +706,7 @@ int __init early_init_dt_scan_chosen(unsigned long node, const char *uname, | |||
710 | */ | 706 | */ |
711 | void __init unflatten_device_tree(void) | 707 | void __init unflatten_device_tree(void) |
712 | { | 708 | { |
713 | __unflatten_device_tree(initial_boot_params, &allnodes, | 709 | __unflatten_device_tree(initial_boot_params, &of_allnodes, |
714 | early_init_dt_alloc_memory_arch); | 710 | early_init_dt_alloc_memory_arch); |
715 | 711 | ||
716 | /* Get pointer to "/chosen" and "/aliasas" nodes for use everywhere */ | 712 | /* Get pointer to "/chosen" and "/aliasas" nodes for use everywhere */ |
diff --git a/drivers/of/of_i2c.c b/drivers/of/of_i2c.c index 3550f3bf4f92..b667264222cc 100644 --- a/drivers/of/of_i2c.c +++ b/drivers/of/of_i2c.c | |||
@@ -29,7 +29,7 @@ void of_i2c_register_devices(struct i2c_adapter *adap) | |||
29 | 29 | ||
30 | dev_dbg(&adap->dev, "of_i2c: walking child nodes\n"); | 30 | dev_dbg(&adap->dev, "of_i2c: walking child nodes\n"); |
31 | 31 | ||
32 | for_each_child_of_node(adap->dev.of_node, node) { | 32 | for_each_available_child_of_node(adap->dev.of_node, node) { |
33 | struct i2c_board_info info = {}; | 33 | struct i2c_board_info info = {}; |
34 | struct dev_archdata dev_ad = {}; | 34 | struct dev_archdata dev_ad = {}; |
35 | const __be32 *addr; | 35 | const __be32 *addr; |
diff --git a/drivers/of/of_mdio.c b/drivers/of/of_mdio.c index 8e6c25f35040..83ca06f4312b 100644 --- a/drivers/of/of_mdio.c +++ b/drivers/of/of_mdio.c | |||
@@ -53,7 +53,7 @@ int of_mdiobus_register(struct mii_bus *mdio, struct device_node *np) | |||
53 | return rc; | 53 | return rc; |
54 | 54 | ||
55 | /* Loop over the child nodes and register a phy_device for each one */ | 55 | /* Loop over the child nodes and register a phy_device for each one */ |
56 | for_each_child_of_node(np, child) { | 56 | for_each_available_child_of_node(np, child) { |
57 | const __be32 *paddr; | 57 | const __be32 *paddr; |
58 | u32 addr; | 58 | u32 addr; |
59 | int len; | 59 | int len; |
diff --git a/drivers/of/pdt.c b/drivers/of/pdt.c index 07cc1d678e4d..37b56fd716e6 100644 --- a/drivers/of/pdt.c +++ b/drivers/of/pdt.c | |||
@@ -241,15 +241,15 @@ void __init of_pdt_build_devicetree(phandle root_node, struct of_pdt_ops *ops) | |||
241 | BUG_ON(!ops); | 241 | BUG_ON(!ops); |
242 | of_pdt_prom_ops = ops; | 242 | of_pdt_prom_ops = ops; |
243 | 243 | ||
244 | allnodes = of_pdt_create_node(root_node, NULL); | 244 | of_allnodes = of_pdt_create_node(root_node, NULL); |
245 | #if defined(CONFIG_SPARC) | 245 | #if defined(CONFIG_SPARC) |
246 | allnodes->path_component_name = ""; | 246 | of_allnodes->path_component_name = ""; |
247 | #endif | 247 | #endif |
248 | allnodes->full_name = "/"; | 248 | of_allnodes->full_name = "/"; |
249 | 249 | ||
250 | nextp = &allnodes->allnext; | 250 | nextp = &of_allnodes->allnext; |
251 | allnodes->child = of_pdt_build_tree(allnodes, | 251 | of_allnodes->child = of_pdt_build_tree(of_allnodes, |
252 | of_pdt_prom_ops->getchild(allnodes->phandle), &nextp); | 252 | of_pdt_prom_ops->getchild(of_allnodes->phandle), &nextp); |
253 | 253 | ||
254 | /* Get pointer to "/chosen" and "/aliasas" nodes for use everywhere */ | 254 | /* Get pointer to "/chosen" and "/aliasas" nodes for use everywhere */ |
255 | of_alias_scan(kernel_tree_alloc); | 255 | of_alias_scan(kernel_tree_alloc); |