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); |
