aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kernel/prom.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/kernel/prom.c')
-rw-r--r--arch/powerpc/kernel/prom.c167
1 files changed, 47 insertions, 120 deletions
diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c
index 8d52b23348bd..caef555f2dc0 100644
--- a/arch/powerpc/kernel/prom.c
+++ b/arch/powerpc/kernel/prom.c
@@ -390,18 +390,19 @@ static unsigned long __init unflatten_dt_node(unsigned long mem,
390 if (allnextpp) { 390 if (allnextpp) {
391 pp->name = "name"; 391 pp->name = "name";
392 pp->length = sz; 392 pp->length = sz;
393 pp->value = (unsigned char *)(pp + 1); 393 pp->value = pp + 1;
394 *prev_pp = pp; 394 *prev_pp = pp;
395 prev_pp = &pp->next; 395 prev_pp = &pp->next;
396 memcpy(pp->value, ps, sz - 1); 396 memcpy(pp->value, ps, sz - 1);
397 ((char *)pp->value)[sz - 1] = 0; 397 ((char *)pp->value)[sz - 1] = 0;
398 DBG("fixed up name for %s -> %s\n", pathp, pp->value); 398 DBG("fixed up name for %s -> %s\n", pathp,
399 (char *)pp->value);
399 } 400 }
400 } 401 }
401 if (allnextpp) { 402 if (allnextpp) {
402 *prev_pp = NULL; 403 *prev_pp = NULL;
403 np->name = get_property(np, "name", NULL); 404 np->name = of_get_property(np, "name", NULL);
404 np->type = get_property(np, "device_type", NULL); 405 np->type = of_get_property(np, "device_type", NULL);
405 406
406 if (!np->name) 407 if (!np->name)
407 np->name = "<NULL>"; 408 np->name = "<NULL>";
@@ -719,6 +720,7 @@ static int __init early_init_dt_scan_chosen(unsigned long node,
719 const char *uname, int depth, void *data) 720 const char *uname, int depth, void *data)
720{ 721{
721 unsigned long *lprop; 722 unsigned long *lprop;
723 u32 *prop;
722 unsigned long l; 724 unsigned long l;
723 char *p; 725 char *p;
724 726
@@ -760,6 +762,22 @@ static int __init early_init_dt_scan_chosen(unsigned long node,
760 crashk_res.end = crashk_res.start + *lprop - 1; 762 crashk_res.end = crashk_res.start + *lprop - 1;
761#endif 763#endif
762 764
765#ifdef CONFIG_BLK_DEV_INITRD
766 DBG("Looking for initrd properties... ");
767 prop = of_get_flat_dt_prop(node, "linux,initrd-start", &l);
768 if (prop) {
769 initrd_start = (unsigned long)__va(of_read_ulong(prop, l/4));
770 prop = of_get_flat_dt_prop(node, "linux,initrd-end", &l);
771 if (prop) {
772 initrd_end = (unsigned long)__va(of_read_ulong(prop, l/4));
773 initrd_below_start_ok = 1;
774 } else {
775 initrd_start = 0;
776 }
777 }
778 DBG("initrd_start=0x%lx initrd_end=0x%lx\n", initrd_start, initrd_end);
779#endif /* CONFIG_BLK_DEV_INITRD */
780
763 /* Retreive command line */ 781 /* Retreive command line */
764 p = of_get_flat_dt_prop(node, "bootargs", &l); 782 p = of_get_flat_dt_prop(node, "bootargs", &l);
765 if (p != NULL && l > 0) 783 if (p != NULL && l > 0)
@@ -926,6 +944,12 @@ static void __init early_reserve_mem(void)
926 self_size = initial_boot_params->totalsize; 944 self_size = initial_boot_params->totalsize;
927 lmb_reserve(self_base, self_size); 945 lmb_reserve(self_base, self_size);
928 946
947#ifdef CONFIG_BLK_DEV_INITRD
948 /* then reserve the initrd, if any */
949 if (initrd_start && (initrd_end > initrd_start))
950 lmb_reserve(__pa(initrd_start), initrd_end - initrd_start);
951#endif /* CONFIG_BLK_DEV_INITRD */
952
929#ifdef CONFIG_PPC32 953#ifdef CONFIG_PPC32
930 /* 954 /*
931 * Handle the case where we might be booting from an old kexec 955 * Handle the case where we might be booting from an old kexec
@@ -954,9 +978,6 @@ static void __init early_reserve_mem(void)
954 size = *(reserve_map++); 978 size = *(reserve_map++);
955 if (size == 0) 979 if (size == 0)
956 break; 980 break;
957 /* skip if the reservation is for the blob */
958 if (base == self_base && size == self_size)
959 continue;
960 DBG("reserving: %llx -> %llx\n", base, size); 981 DBG("reserving: %llx -> %llx\n", base, size);
961 lmb_reserve(base, size); 982 lmb_reserve(base, size);
962 } 983 }
@@ -1021,102 +1042,46 @@ void __init early_init_devtree(void *params)
1021 1042
1022#undef printk 1043#undef printk
1023 1044
1024int 1045int of_n_addr_cells(struct device_node* np)
1025prom_n_addr_cells(struct device_node* np)
1026{ 1046{
1027 const int *ip; 1047 const int *ip;
1028 do { 1048 do {
1029 if (np->parent) 1049 if (np->parent)
1030 np = np->parent; 1050 np = np->parent;
1031 ip = get_property(np, "#address-cells", NULL); 1051 ip = of_get_property(np, "#address-cells", NULL);
1032 if (ip != NULL) 1052 if (ip != NULL)
1033 return *ip; 1053 return *ip;
1034 } while (np->parent); 1054 } while (np->parent);
1035 /* No #address-cells property for the root node, default to 1 */ 1055 /* No #address-cells property for the root node, default to 1 */
1036 return 1; 1056 return 1;
1037} 1057}
1038EXPORT_SYMBOL(prom_n_addr_cells); 1058EXPORT_SYMBOL(of_n_addr_cells);
1039 1059
1040int 1060int of_n_size_cells(struct device_node* np)
1041prom_n_size_cells(struct device_node* np)
1042{ 1061{
1043 const int* ip; 1062 const int* ip;
1044 do { 1063 do {
1045 if (np->parent) 1064 if (np->parent)
1046 np = np->parent; 1065 np = np->parent;
1047 ip = get_property(np, "#size-cells", NULL); 1066 ip = of_get_property(np, "#size-cells", NULL);
1048 if (ip != NULL) 1067 if (ip != NULL)
1049 return *ip; 1068 return *ip;
1050 } while (np->parent); 1069 } while (np->parent);
1051 /* No #size-cells property for the root node, default to 1 */ 1070 /* No #size-cells property for the root node, default to 1 */
1052 return 1; 1071 return 1;
1053} 1072}
1054EXPORT_SYMBOL(prom_n_size_cells); 1073EXPORT_SYMBOL(of_n_size_cells);
1055
1056/**
1057 * Construct and return a list of the device_nodes with a given name.
1058 */
1059struct device_node *find_devices(const char *name)
1060{
1061 struct device_node *head, **prevp, *np;
1062
1063 prevp = &head;
1064 for (np = allnodes; np != 0; np = np->allnext) {
1065 if (np->name != 0 && strcasecmp(np->name, name) == 0) {
1066 *prevp = np;
1067 prevp = &np->next;
1068 }
1069 }
1070 *prevp = NULL;
1071 return head;
1072}
1073EXPORT_SYMBOL(find_devices);
1074
1075/**
1076 * Construct and return a list of the device_nodes with a given type.
1077 */
1078struct device_node *find_type_devices(const char *type)
1079{
1080 struct device_node *head, **prevp, *np;
1081
1082 prevp = &head;
1083 for (np = allnodes; np != 0; np = np->allnext) {
1084 if (np->type != 0 && strcasecmp(np->type, type) == 0) {
1085 *prevp = np;
1086 prevp = &np->next;
1087 }
1088 }
1089 *prevp = NULL;
1090 return head;
1091}
1092EXPORT_SYMBOL(find_type_devices);
1093
1094/**
1095 * Returns all nodes linked together
1096 */
1097struct device_node *find_all_nodes(void)
1098{
1099 struct device_node *head, **prevp, *np;
1100
1101 prevp = &head;
1102 for (np = allnodes; np != 0; np = np->allnext) {
1103 *prevp = np;
1104 prevp = &np->next;
1105 }
1106 *prevp = NULL;
1107 return head;
1108}
1109EXPORT_SYMBOL(find_all_nodes);
1110 1074
1111/** Checks if the given "compat" string matches one of the strings in 1075/** Checks if the given "compat" string matches one of the strings in
1112 * the device's "compatible" property 1076 * the device's "compatible" property
1113 */ 1077 */
1114int device_is_compatible(const struct device_node *device, const char *compat) 1078int of_device_is_compatible(const struct device_node *device,
1079 const char *compat)
1115{ 1080{
1116 const char* cp; 1081 const char* cp;
1117 int cplen, l; 1082 int cplen, l;
1118 1083
1119 cp = get_property(device, "compatible", &cplen); 1084 cp = of_get_property(device, "compatible", &cplen);
1120 if (cp == NULL) 1085 if (cp == NULL)
1121 return 0; 1086 return 0;
1122 while (cplen > 0) { 1087 while (cplen > 0) {
@@ -1129,7 +1094,7 @@ int device_is_compatible(const struct device_node *device, const char *compat)
1129 1094
1130 return 0; 1095 return 0;
1131} 1096}
1132EXPORT_SYMBOL(device_is_compatible); 1097EXPORT_SYMBOL(of_device_is_compatible);
1133 1098
1134 1099
1135/** 1100/**
@@ -1143,51 +1108,13 @@ int machine_is_compatible(const char *compat)
1143 1108
1144 root = of_find_node_by_path("/"); 1109 root = of_find_node_by_path("/");
1145 if (root) { 1110 if (root) {
1146 rc = device_is_compatible(root, compat); 1111 rc = of_device_is_compatible(root, compat);
1147 of_node_put(root); 1112 of_node_put(root);
1148 } 1113 }
1149 return rc; 1114 return rc;
1150} 1115}
1151EXPORT_SYMBOL(machine_is_compatible); 1116EXPORT_SYMBOL(machine_is_compatible);
1152 1117
1153/**
1154 * Construct and return a list of the device_nodes with a given type
1155 * and compatible property.
1156 */
1157struct device_node *find_compatible_devices(const char *type,
1158 const char *compat)
1159{
1160 struct device_node *head, **prevp, *np;
1161
1162 prevp = &head;
1163 for (np = allnodes; np != 0; np = np->allnext) {
1164 if (type != NULL
1165 && !(np->type != 0 && strcasecmp(np->type, type) == 0))
1166 continue;
1167 if (device_is_compatible(np, compat)) {
1168 *prevp = np;
1169 prevp = &np->next;
1170 }
1171 }
1172 *prevp = NULL;
1173 return head;
1174}
1175EXPORT_SYMBOL(find_compatible_devices);
1176
1177/**
1178 * Find the device_node with a given full_name.
1179 */
1180struct device_node *find_path_device(const char *path)
1181{
1182 struct device_node *np;
1183
1184 for (np = allnodes; np != 0; np = np->allnext)
1185 if (np->full_name != 0 && strcasecmp(np->full_name, path) == 0)
1186 return np;
1187 return NULL;
1188}
1189EXPORT_SYMBOL(find_path_device);
1190
1191/******* 1118/*******
1192 * 1119 *
1193 * New implementation of the OF "find" APIs, return a refcounted 1120 * New implementation of the OF "find" APIs, return a refcounted
@@ -1280,7 +1207,7 @@ struct device_node *of_find_compatible_node(struct device_node *from,
1280 if (type != NULL 1207 if (type != NULL
1281 && !(np->type != 0 && strcasecmp(np->type, type) == 0)) 1208 && !(np->type != 0 && strcasecmp(np->type, type) == 0))
1282 continue; 1209 continue;
1283 if (device_is_compatible(np, compatible) && of_node_get(np)) 1210 if (of_device_is_compatible(np, compatible) && of_node_get(np))
1284 break; 1211 break;
1285 } 1212 }
1286 of_node_put(from); 1213 of_node_put(from);
@@ -1527,8 +1454,8 @@ static int of_finish_dynamic_node(struct device_node *node)
1527 int err = 0; 1454 int err = 0;
1528 const phandle *ibm_phandle; 1455 const phandle *ibm_phandle;
1529 1456
1530 node->name = get_property(node, "name", NULL); 1457 node->name = of_get_property(node, "name", NULL);
1531 node->type = get_property(node, "device_type", NULL); 1458 node->type = of_get_property(node, "device_type", NULL);
1532 1459
1533 if (!parent) { 1460 if (!parent) {
1534 err = -ENODEV; 1461 err = -ENODEV;
@@ -1542,7 +1469,7 @@ static int of_finish_dynamic_node(struct device_node *node)
1542 return -ENODEV; 1469 return -ENODEV;
1543 1470
1544 /* fix up new node's linux_phandle field */ 1471 /* fix up new node's linux_phandle field */
1545 if ((ibm_phandle = get_property(node, "ibm,phandle", NULL))) 1472 if ((ibm_phandle = of_get_property(node, "ibm,phandle", NULL)))
1546 node->linux_phandle = *ibm_phandle; 1473 node->linux_phandle = *ibm_phandle;
1547 1474
1548out: 1475out:
@@ -1605,13 +1532,13 @@ EXPORT_SYMBOL(of_find_property);
1605 * Find a property with a given name for a given node 1532 * Find a property with a given name for a given node
1606 * and return the value. 1533 * and return the value.
1607 */ 1534 */
1608const void *get_property(const struct device_node *np, const char *name, 1535const void *of_get_property(const struct device_node *np, const char *name,
1609 int *lenp) 1536 int *lenp)
1610{ 1537{
1611 struct property *pp = of_find_property(np,name,lenp); 1538 struct property *pp = of_find_property(np,name,lenp);
1612 return pp ? pp->value : NULL; 1539 return pp ? pp->value : NULL;
1613} 1540}
1614EXPORT_SYMBOL(get_property); 1541EXPORT_SYMBOL(of_get_property);
1615 1542
1616/* 1543/*
1617 * Add a property to a node 1544 * Add a property to a node
@@ -1742,10 +1669,10 @@ struct device_node *of_get_cpu_node(int cpu, unsigned int *thread)
1742 /* Check for ibm,ppc-interrupt-server#s. If it doesn't exist 1669 /* Check for ibm,ppc-interrupt-server#s. If it doesn't exist
1743 * fallback to "reg" property and assume no threads 1670 * fallback to "reg" property and assume no threads
1744 */ 1671 */
1745 intserv = get_property(np, "ibm,ppc-interrupt-server#s", 1672 intserv = of_get_property(np, "ibm,ppc-interrupt-server#s",
1746 &plen); 1673 &plen);
1747 if (intserv == NULL) { 1674 if (intserv == NULL) {
1748 const u32 *reg = get_property(np, "reg", NULL); 1675 const u32 *reg = of_get_property(np, "reg", NULL);
1749 if (reg == NULL) 1676 if (reg == NULL)
1750 continue; 1677 continue;
1751 if (*reg == hardid) { 1678 if (*reg == hardid) {