Commit 49b97d9c8ea7b11c4fc9e457cc2cd9fd6ebf0c21

Authored by Kumar Gala
1 parent 69bcf5bc80
Exists in master and in 56 other branches 8qm-imx_v2020.04_5.4.70_2.3.0, emb_lf_v2022.04, emb_lf_v2023.04, emb_lf_v2024.04, imx_v2015.04_4.1.15_1.0.0_ga, pitx_8mp_lf_v2020.04, smarc-8m-android-10.0.0_2.6.0, smarc-8m-android-11.0.0_2.0.0, smarc-8mp-android-11.0.0_2.0.0, smarc-emmc-imx_v2014.04_3.10.53_1.1.0_ga, smarc-emmc-imx_v2014.04_3.14.28_1.0.0_ga, smarc-imx-l5.0.0_1.0.0-ga, smarc-imx6_v2018.03_4.14.98_2.0.0_ga, smarc-imx7_v2017.03_4.9.11_1.0.0_ga, smarc-imx7_v2018.03_4.14.98_2.0.0_ga, smarc-imx_v2014.04_3.14.28_1.0.0_ga, smarc-imx_v2015.04_4.1.15_1.0.0_ga, smarc-imx_v2017.03_4.9.11_1.0.0_ga, smarc-imx_v2017.03_4.9.88_2.0.0_ga, smarc-imx_v2017.03_o8.1.0_1.3.0_8m, smarc-imx_v2018.03_4.14.78_1.0.0_ga, smarc-m6.0.1_2.1.0-ga, smarc-n7.1.2_2.0.0-ga, smarc-rel_imx_4.1.15_2.0.0_ga, smarc_8m-imx_v2018.03_4.14.98_2.0.0_ga, smarc_8m-imx_v2019.04_4.19.35_1.1.0, smarc_8m_00d0-imx_v2018.03_4.14.98_2.0.0_ga, smarc_8mm-imx_v2018.03_4.14.98_2.0.0_ga, smarc_8mm-imx_v2019.04_4.19.35_1.1.0, smarc_8mm-imx_v2020.04_5.4.24_2.1.0, smarc_8mp_lf_v2020.04, smarc_8mq-imx_v2020.04_5.4.24_2.1.0, smarc_8mq_lf_v2020.04, ti-u-boot-2015.07, u-boot-2013.01.y, v2013.10, v2013.10-smarct33, v2013.10-smartmen, v2014.01, v2014.04, v2014.04-smarct33, v2014.04-smarct33-emmc, v2014.04-smartmen, v2014.07, v2014.07-smarct33, v2014.07-smartmen, v2015.07-smarct33, v2015.07-smarct33-emmc, v2015.07-smarct4x, v2016.05-dlt, v2016.05-smarct3x, v2016.05-smarct3x-emmc, v2016.05-smarct4x, v2017.01-smarct3x, v2017.01-smarct3x-emmc, v2017.01-smarct4x

fdt: Add fdt_del_node_and_alias helper

Add a helper function that given an alias will delete both the node
the alias points to and the alias itself

Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
Acked-by: Gerald Van Baren <vanbaren@cideas.com>

Showing 2 changed files with 14 additions and 0 deletions Inline Diff

common/fdt_support.c
1 /* 1 /*
2 * (C) Copyright 2007 2 * (C) Copyright 2007
3 * Gerald Van Baren, Custom IDEAS, vanbaren@cideas.com 3 * Gerald Van Baren, Custom IDEAS, vanbaren@cideas.com
4 * 4 *
5 * See file CREDITS for list of people who contributed to this 5 * See file CREDITS for list of people who contributed to this
6 * project. 6 * project.
7 * 7 *
8 * This program is free software; you can redistribute it and/or 8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License as 9 * modify it under the terms of the GNU General Public License as
10 * published by the Free Software Foundation; either version 2 of 10 * published by the Free Software Foundation; either version 2 of
11 * the License, or (at your option) any later version. 11 * the License, or (at your option) any later version.
12 * 12 *
13 * This program is distributed in the hope that it will be useful, 13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details. 16 * GNU General Public License for more details.
17 * 17 *
18 * You should have received a copy of the GNU General Public License 18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software 19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, 20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
21 * MA 02111-1307 USA 21 * MA 02111-1307 USA
22 */ 22 */
23 23
24 #include <common.h> 24 #include <common.h>
25 #include <stdio_dev.h> 25 #include <stdio_dev.h>
26 #include <linux/ctype.h> 26 #include <linux/ctype.h>
27 #include <linux/types.h> 27 #include <linux/types.h>
28 #include <asm/global_data.h> 28 #include <asm/global_data.h>
29 #include <fdt.h> 29 #include <fdt.h>
30 #include <libfdt.h> 30 #include <libfdt.h>
31 #include <fdt_support.h> 31 #include <fdt_support.h>
32 #include <exports.h> 32 #include <exports.h>
33 33
34 /* 34 /*
35 * Global data (for the gd->bd) 35 * Global data (for the gd->bd)
36 */ 36 */
37 DECLARE_GLOBAL_DATA_PTR; 37 DECLARE_GLOBAL_DATA_PTR;
38 38
39 /** 39 /**
40 * fdt_getprop_u32_default - Find a node and return it's property or a default 40 * fdt_getprop_u32_default - Find a node and return it's property or a default
41 * 41 *
42 * @fdt: ptr to device tree 42 * @fdt: ptr to device tree
43 * @path: path of node 43 * @path: path of node
44 * @prop: property name 44 * @prop: property name
45 * @dflt: default value if the property isn't found 45 * @dflt: default value if the property isn't found
46 * 46 *
47 * Convenience function to find a node and return it's property or a 47 * Convenience function to find a node and return it's property or a
48 * default value if it doesn't exist. 48 * default value if it doesn't exist.
49 */ 49 */
50 u32 fdt_getprop_u32_default(void *fdt, const char *path, const char *prop, 50 u32 fdt_getprop_u32_default(void *fdt, const char *path, const char *prop,
51 const u32 dflt) 51 const u32 dflt)
52 { 52 {
53 const u32 *val; 53 const u32 *val;
54 int off; 54 int off;
55 55
56 off = fdt_path_offset(fdt, path); 56 off = fdt_path_offset(fdt, path);
57 if (off < 0) 57 if (off < 0)
58 return dflt; 58 return dflt;
59 59
60 val = fdt_getprop(fdt, off, prop, NULL); 60 val = fdt_getprop(fdt, off, prop, NULL);
61 if (val) 61 if (val)
62 return *val; 62 return *val;
63 else 63 else
64 return dflt; 64 return dflt;
65 } 65 }
66 66
67 /** 67 /**
68 * fdt_find_and_setprop: Find a node and set it's property 68 * fdt_find_and_setprop: Find a node and set it's property
69 * 69 *
70 * @fdt: ptr to device tree 70 * @fdt: ptr to device tree
71 * @node: path of node 71 * @node: path of node
72 * @prop: property name 72 * @prop: property name
73 * @val: ptr to new value 73 * @val: ptr to new value
74 * @len: length of new property value 74 * @len: length of new property value
75 * @create: flag to create the property if it doesn't exist 75 * @create: flag to create the property if it doesn't exist
76 * 76 *
77 * Convenience function to directly set a property given the path to the node. 77 * Convenience function to directly set a property given the path to the node.
78 */ 78 */
79 int fdt_find_and_setprop(void *fdt, const char *node, const char *prop, 79 int fdt_find_and_setprop(void *fdt, const char *node, const char *prop,
80 const void *val, int len, int create) 80 const void *val, int len, int create)
81 { 81 {
82 int nodeoff = fdt_path_offset(fdt, node); 82 int nodeoff = fdt_path_offset(fdt, node);
83 83
84 if (nodeoff < 0) 84 if (nodeoff < 0)
85 return nodeoff; 85 return nodeoff;
86 86
87 if ((!create) && (fdt_get_property(fdt, nodeoff, prop, 0) == NULL)) 87 if ((!create) && (fdt_get_property(fdt, nodeoff, prop, 0) == NULL))
88 return 0; /* create flag not set; so exit quietly */ 88 return 0; /* create flag not set; so exit quietly */
89 89
90 return fdt_setprop(fdt, nodeoff, prop, val, len); 90 return fdt_setprop(fdt, nodeoff, prop, val, len);
91 } 91 }
92 92
93 #ifdef CONFIG_OF_STDOUT_VIA_ALIAS 93 #ifdef CONFIG_OF_STDOUT_VIA_ALIAS
94 94
95 #ifdef CONFIG_SERIAL_MULTI 95 #ifdef CONFIG_SERIAL_MULTI
96 static void fdt_fill_multisername(char *sername, size_t maxlen) 96 static void fdt_fill_multisername(char *sername, size_t maxlen)
97 { 97 {
98 const char *outname = stdio_devices[stdout]->name; 98 const char *outname = stdio_devices[stdout]->name;
99 99
100 if (strcmp(outname, "serial") > 0) 100 if (strcmp(outname, "serial") > 0)
101 strncpy(sername, outname, maxlen); 101 strncpy(sername, outname, maxlen);
102 102
103 /* eserial? */ 103 /* eserial? */
104 if (strcmp(outname + 1, "serial") > 0) 104 if (strcmp(outname + 1, "serial") > 0)
105 strncpy(sername, outname + 1, maxlen); 105 strncpy(sername, outname + 1, maxlen);
106 } 106 }
107 #else 107 #else
108 static inline void fdt_fill_multisername(char *sername, size_t maxlen) {} 108 static inline void fdt_fill_multisername(char *sername, size_t maxlen) {}
109 #endif /* CONFIG_SERIAL_MULTI */ 109 #endif /* CONFIG_SERIAL_MULTI */
110 110
111 static int fdt_fixup_stdout(void *fdt, int chosenoff) 111 static int fdt_fixup_stdout(void *fdt, int chosenoff)
112 { 112 {
113 int err = 0; 113 int err = 0;
114 #ifdef CONFIG_CONS_INDEX 114 #ifdef CONFIG_CONS_INDEX
115 int node; 115 int node;
116 char sername[9] = { 0 }; 116 char sername[9] = { 0 };
117 const char *path; 117 const char *path;
118 118
119 fdt_fill_multisername(sername, sizeof(sername) - 1); 119 fdt_fill_multisername(sername, sizeof(sername) - 1);
120 if (!sername[0]) 120 if (!sername[0])
121 sprintf(sername, "serial%d", CONFIG_CONS_INDEX - 1); 121 sprintf(sername, "serial%d", CONFIG_CONS_INDEX - 1);
122 122
123 err = node = fdt_path_offset(fdt, "/aliases"); 123 err = node = fdt_path_offset(fdt, "/aliases");
124 if (node >= 0) { 124 if (node >= 0) {
125 int len; 125 int len;
126 path = fdt_getprop(fdt, node, sername, &len); 126 path = fdt_getprop(fdt, node, sername, &len);
127 if (path) { 127 if (path) {
128 char *p = malloc(len); 128 char *p = malloc(len);
129 err = -FDT_ERR_NOSPACE; 129 err = -FDT_ERR_NOSPACE;
130 if (p) { 130 if (p) {
131 memcpy(p, path, len); 131 memcpy(p, path, len);
132 err = fdt_setprop(fdt, chosenoff, 132 err = fdt_setprop(fdt, chosenoff,
133 "linux,stdout-path", p, len); 133 "linux,stdout-path", p, len);
134 free(p); 134 free(p);
135 } 135 }
136 } else { 136 } else {
137 err = len; 137 err = len;
138 } 138 }
139 } 139 }
140 #endif 140 #endif
141 if (err < 0) 141 if (err < 0)
142 printf("WARNING: could not set linux,stdout-path %s.\n", 142 printf("WARNING: could not set linux,stdout-path %s.\n",
143 fdt_strerror(err)); 143 fdt_strerror(err));
144 144
145 return err; 145 return err;
146 } 146 }
147 #endif 147 #endif
148 148
149 int fdt_initrd(void *fdt, ulong initrd_start, ulong initrd_end, int force) 149 int fdt_initrd(void *fdt, ulong initrd_start, ulong initrd_end, int force)
150 { 150 {
151 int nodeoffset; 151 int nodeoffset;
152 int err, j, total; 152 int err, j, total;
153 u32 tmp; 153 u32 tmp;
154 const char *path; 154 const char *path;
155 uint64_t addr, size; 155 uint64_t addr, size;
156 156
157 /* Find the "chosen" node. */ 157 /* Find the "chosen" node. */
158 nodeoffset = fdt_path_offset (fdt, "/chosen"); 158 nodeoffset = fdt_path_offset (fdt, "/chosen");
159 159
160 /* If there is no "chosen" node in the blob return */ 160 /* If there is no "chosen" node in the blob return */
161 if (nodeoffset < 0) { 161 if (nodeoffset < 0) {
162 printf("fdt_initrd: %s\n", fdt_strerror(nodeoffset)); 162 printf("fdt_initrd: %s\n", fdt_strerror(nodeoffset));
163 return nodeoffset; 163 return nodeoffset;
164 } 164 }
165 165
166 /* just return if initrd_start/end aren't valid */ 166 /* just return if initrd_start/end aren't valid */
167 if ((initrd_start == 0) || (initrd_end == 0)) 167 if ((initrd_start == 0) || (initrd_end == 0))
168 return 0; 168 return 0;
169 169
170 total = fdt_num_mem_rsv(fdt); 170 total = fdt_num_mem_rsv(fdt);
171 171
172 /* 172 /*
173 * Look for an existing entry and update it. If we don't find 173 * Look for an existing entry and update it. If we don't find
174 * the entry, we will j be the next available slot. 174 * the entry, we will j be the next available slot.
175 */ 175 */
176 for (j = 0; j < total; j++) { 176 for (j = 0; j < total; j++) {
177 err = fdt_get_mem_rsv(fdt, j, &addr, &size); 177 err = fdt_get_mem_rsv(fdt, j, &addr, &size);
178 if (addr == initrd_start) { 178 if (addr == initrd_start) {
179 fdt_del_mem_rsv(fdt, j); 179 fdt_del_mem_rsv(fdt, j);
180 break; 180 break;
181 } 181 }
182 } 182 }
183 183
184 err = fdt_add_mem_rsv(fdt, initrd_start, initrd_end - initrd_start + 1); 184 err = fdt_add_mem_rsv(fdt, initrd_start, initrd_end - initrd_start + 1);
185 if (err < 0) { 185 if (err < 0) {
186 printf("fdt_initrd: %s\n", fdt_strerror(err)); 186 printf("fdt_initrd: %s\n", fdt_strerror(err));
187 return err; 187 return err;
188 } 188 }
189 189
190 path = fdt_getprop(fdt, nodeoffset, "linux,initrd-start", NULL); 190 path = fdt_getprop(fdt, nodeoffset, "linux,initrd-start", NULL);
191 if ((path == NULL) || force) { 191 if ((path == NULL) || force) {
192 tmp = __cpu_to_be32(initrd_start); 192 tmp = __cpu_to_be32(initrd_start);
193 err = fdt_setprop(fdt, nodeoffset, 193 err = fdt_setprop(fdt, nodeoffset,
194 "linux,initrd-start", &tmp, sizeof(tmp)); 194 "linux,initrd-start", &tmp, sizeof(tmp));
195 if (err < 0) { 195 if (err < 0) {
196 printf("WARNING: " 196 printf("WARNING: "
197 "could not set linux,initrd-start %s.\n", 197 "could not set linux,initrd-start %s.\n",
198 fdt_strerror(err)); 198 fdt_strerror(err));
199 return err; 199 return err;
200 } 200 }
201 tmp = __cpu_to_be32(initrd_end); 201 tmp = __cpu_to_be32(initrd_end);
202 err = fdt_setprop(fdt, nodeoffset, 202 err = fdt_setprop(fdt, nodeoffset,
203 "linux,initrd-end", &tmp, sizeof(tmp)); 203 "linux,initrd-end", &tmp, sizeof(tmp));
204 if (err < 0) { 204 if (err < 0) {
205 printf("WARNING: could not set linux,initrd-end %s.\n", 205 printf("WARNING: could not set linux,initrd-end %s.\n",
206 fdt_strerror(err)); 206 fdt_strerror(err));
207 207
208 return err; 208 return err;
209 } 209 }
210 } 210 }
211 211
212 return 0; 212 return 0;
213 } 213 }
214 214
215 int fdt_chosen(void *fdt, int force) 215 int fdt_chosen(void *fdt, int force)
216 { 216 {
217 int nodeoffset; 217 int nodeoffset;
218 int err; 218 int err;
219 char *str; /* used to set string properties */ 219 char *str; /* used to set string properties */
220 const char *path; 220 const char *path;
221 221
222 err = fdt_check_header(fdt); 222 err = fdt_check_header(fdt);
223 if (err < 0) { 223 if (err < 0) {
224 printf("fdt_chosen: %s\n", fdt_strerror(err)); 224 printf("fdt_chosen: %s\n", fdt_strerror(err));
225 return err; 225 return err;
226 } 226 }
227 227
228 /* 228 /*
229 * Find the "chosen" node. 229 * Find the "chosen" node.
230 */ 230 */
231 nodeoffset = fdt_path_offset (fdt, "/chosen"); 231 nodeoffset = fdt_path_offset (fdt, "/chosen");
232 232
233 /* 233 /*
234 * If there is no "chosen" node in the blob, create it. 234 * If there is no "chosen" node in the blob, create it.
235 */ 235 */
236 if (nodeoffset < 0) { 236 if (nodeoffset < 0) {
237 /* 237 /*
238 * Create a new node "/chosen" (offset 0 is root level) 238 * Create a new node "/chosen" (offset 0 is root level)
239 */ 239 */
240 nodeoffset = fdt_add_subnode(fdt, 0, "chosen"); 240 nodeoffset = fdt_add_subnode(fdt, 0, "chosen");
241 if (nodeoffset < 0) { 241 if (nodeoffset < 0) {
242 printf("WARNING: could not create /chosen %s.\n", 242 printf("WARNING: could not create /chosen %s.\n",
243 fdt_strerror(nodeoffset)); 243 fdt_strerror(nodeoffset));
244 return nodeoffset; 244 return nodeoffset;
245 } 245 }
246 } 246 }
247 247
248 /* 248 /*
249 * Create /chosen properites that don't exist in the fdt. 249 * Create /chosen properites that don't exist in the fdt.
250 * If the property exists, update it only if the "force" parameter 250 * If the property exists, update it only if the "force" parameter
251 * is true. 251 * is true.
252 */ 252 */
253 str = getenv("bootargs"); 253 str = getenv("bootargs");
254 if (str != NULL) { 254 if (str != NULL) {
255 path = fdt_getprop(fdt, nodeoffset, "bootargs", NULL); 255 path = fdt_getprop(fdt, nodeoffset, "bootargs", NULL);
256 if ((path == NULL) || force) { 256 if ((path == NULL) || force) {
257 err = fdt_setprop(fdt, nodeoffset, 257 err = fdt_setprop(fdt, nodeoffset,
258 "bootargs", str, strlen(str)+1); 258 "bootargs", str, strlen(str)+1);
259 if (err < 0) 259 if (err < 0)
260 printf("WARNING: could not set bootargs %s.\n", 260 printf("WARNING: could not set bootargs %s.\n",
261 fdt_strerror(err)); 261 fdt_strerror(err));
262 } 262 }
263 } 263 }
264 264
265 #ifdef CONFIG_OF_STDOUT_VIA_ALIAS 265 #ifdef CONFIG_OF_STDOUT_VIA_ALIAS
266 path = fdt_getprop(fdt, nodeoffset, "linux,stdout-path", NULL); 266 path = fdt_getprop(fdt, nodeoffset, "linux,stdout-path", NULL);
267 if ((path == NULL) || force) 267 if ((path == NULL) || force)
268 err = fdt_fixup_stdout(fdt, nodeoffset); 268 err = fdt_fixup_stdout(fdt, nodeoffset);
269 #endif 269 #endif
270 270
271 #ifdef OF_STDOUT_PATH 271 #ifdef OF_STDOUT_PATH
272 path = fdt_getprop(fdt, nodeoffset, "linux,stdout-path", NULL); 272 path = fdt_getprop(fdt, nodeoffset, "linux,stdout-path", NULL);
273 if ((path == NULL) || force) { 273 if ((path == NULL) || force) {
274 err = fdt_setprop(fdt, nodeoffset, 274 err = fdt_setprop(fdt, nodeoffset,
275 "linux,stdout-path", OF_STDOUT_PATH, strlen(OF_STDOUT_PATH)+1); 275 "linux,stdout-path", OF_STDOUT_PATH, strlen(OF_STDOUT_PATH)+1);
276 if (err < 0) 276 if (err < 0)
277 printf("WARNING: could not set linux,stdout-path %s.\n", 277 printf("WARNING: could not set linux,stdout-path %s.\n",
278 fdt_strerror(err)); 278 fdt_strerror(err));
279 } 279 }
280 #endif 280 #endif
281 281
282 return err; 282 return err;
283 } 283 }
284 284
285 void do_fixup_by_path(void *fdt, const char *path, const char *prop, 285 void do_fixup_by_path(void *fdt, const char *path, const char *prop,
286 const void *val, int len, int create) 286 const void *val, int len, int create)
287 { 287 {
288 #if defined(DEBUG) 288 #if defined(DEBUG)
289 int i; 289 int i;
290 debug("Updating property '%s/%s' = ", path, prop); 290 debug("Updating property '%s/%s' = ", path, prop);
291 for (i = 0; i < len; i++) 291 for (i = 0; i < len; i++)
292 debug(" %.2x", *(u8*)(val+i)); 292 debug(" %.2x", *(u8*)(val+i));
293 debug("\n"); 293 debug("\n");
294 #endif 294 #endif
295 int rc = fdt_find_and_setprop(fdt, path, prop, val, len, create); 295 int rc = fdt_find_and_setprop(fdt, path, prop, val, len, create);
296 if (rc) 296 if (rc)
297 printf("Unable to update property %s:%s, err=%s\n", 297 printf("Unable to update property %s:%s, err=%s\n",
298 path, prop, fdt_strerror(rc)); 298 path, prop, fdt_strerror(rc));
299 } 299 }
300 300
301 void do_fixup_by_path_u32(void *fdt, const char *path, const char *prop, 301 void do_fixup_by_path_u32(void *fdt, const char *path, const char *prop,
302 u32 val, int create) 302 u32 val, int create)
303 { 303 {
304 val = cpu_to_fdt32(val); 304 val = cpu_to_fdt32(val);
305 do_fixup_by_path(fdt, path, prop, &val, sizeof(val), create); 305 do_fixup_by_path(fdt, path, prop, &val, sizeof(val), create);
306 } 306 }
307 307
308 void do_fixup_by_prop(void *fdt, 308 void do_fixup_by_prop(void *fdt,
309 const char *pname, const void *pval, int plen, 309 const char *pname, const void *pval, int plen,
310 const char *prop, const void *val, int len, 310 const char *prop, const void *val, int len,
311 int create) 311 int create)
312 { 312 {
313 int off; 313 int off;
314 #if defined(DEBUG) 314 #if defined(DEBUG)
315 int i; 315 int i;
316 debug("Updating property '%s' = ", prop); 316 debug("Updating property '%s' = ", prop);
317 for (i = 0; i < len; i++) 317 for (i = 0; i < len; i++)
318 debug(" %.2x", *(u8*)(val+i)); 318 debug(" %.2x", *(u8*)(val+i));
319 debug("\n"); 319 debug("\n");
320 #endif 320 #endif
321 off = fdt_node_offset_by_prop_value(fdt, -1, pname, pval, plen); 321 off = fdt_node_offset_by_prop_value(fdt, -1, pname, pval, plen);
322 while (off != -FDT_ERR_NOTFOUND) { 322 while (off != -FDT_ERR_NOTFOUND) {
323 if (create || (fdt_get_property(fdt, off, prop, 0) != NULL)) 323 if (create || (fdt_get_property(fdt, off, prop, 0) != NULL))
324 fdt_setprop(fdt, off, prop, val, len); 324 fdt_setprop(fdt, off, prop, val, len);
325 off = fdt_node_offset_by_prop_value(fdt, off, pname, pval, plen); 325 off = fdt_node_offset_by_prop_value(fdt, off, pname, pval, plen);
326 } 326 }
327 } 327 }
328 328
329 void do_fixup_by_prop_u32(void *fdt, 329 void do_fixup_by_prop_u32(void *fdt,
330 const char *pname, const void *pval, int plen, 330 const char *pname, const void *pval, int plen,
331 const char *prop, u32 val, int create) 331 const char *prop, u32 val, int create)
332 { 332 {
333 val = cpu_to_fdt32(val); 333 val = cpu_to_fdt32(val);
334 do_fixup_by_prop(fdt, pname, pval, plen, prop, &val, 4, create); 334 do_fixup_by_prop(fdt, pname, pval, plen, prop, &val, 4, create);
335 } 335 }
336 336
337 void do_fixup_by_compat(void *fdt, const char *compat, 337 void do_fixup_by_compat(void *fdt, const char *compat,
338 const char *prop, const void *val, int len, int create) 338 const char *prop, const void *val, int len, int create)
339 { 339 {
340 int off = -1; 340 int off = -1;
341 #if defined(DEBUG) 341 #if defined(DEBUG)
342 int i; 342 int i;
343 debug("Updating property '%s' = ", prop); 343 debug("Updating property '%s' = ", prop);
344 for (i = 0; i < len; i++) 344 for (i = 0; i < len; i++)
345 debug(" %.2x", *(u8*)(val+i)); 345 debug(" %.2x", *(u8*)(val+i));
346 debug("\n"); 346 debug("\n");
347 #endif 347 #endif
348 off = fdt_node_offset_by_compatible(fdt, -1, compat); 348 off = fdt_node_offset_by_compatible(fdt, -1, compat);
349 while (off != -FDT_ERR_NOTFOUND) { 349 while (off != -FDT_ERR_NOTFOUND) {
350 if (create || (fdt_get_property(fdt, off, prop, 0) != NULL)) 350 if (create || (fdt_get_property(fdt, off, prop, 0) != NULL))
351 fdt_setprop(fdt, off, prop, val, len); 351 fdt_setprop(fdt, off, prop, val, len);
352 off = fdt_node_offset_by_compatible(fdt, off, compat); 352 off = fdt_node_offset_by_compatible(fdt, off, compat);
353 } 353 }
354 } 354 }
355 355
356 void do_fixup_by_compat_u32(void *fdt, const char *compat, 356 void do_fixup_by_compat_u32(void *fdt, const char *compat,
357 const char *prop, u32 val, int create) 357 const char *prop, u32 val, int create)
358 { 358 {
359 val = cpu_to_fdt32(val); 359 val = cpu_to_fdt32(val);
360 do_fixup_by_compat(fdt, compat, prop, &val, 4, create); 360 do_fixup_by_compat(fdt, compat, prop, &val, 4, create);
361 } 361 }
362 362
363 int fdt_fixup_memory(void *blob, u64 start, u64 size) 363 int fdt_fixup_memory(void *blob, u64 start, u64 size)
364 { 364 {
365 int err, nodeoffset, len = 0; 365 int err, nodeoffset, len = 0;
366 u8 tmp[16]; 366 u8 tmp[16];
367 const u32 *addrcell, *sizecell; 367 const u32 *addrcell, *sizecell;
368 368
369 err = fdt_check_header(blob); 369 err = fdt_check_header(blob);
370 if (err < 0) { 370 if (err < 0) {
371 printf("%s: %s\n", __FUNCTION__, fdt_strerror(err)); 371 printf("%s: %s\n", __FUNCTION__, fdt_strerror(err));
372 return err; 372 return err;
373 } 373 }
374 374
375 /* update, or add and update /memory node */ 375 /* update, or add and update /memory node */
376 nodeoffset = fdt_path_offset(blob, "/memory"); 376 nodeoffset = fdt_path_offset(blob, "/memory");
377 if (nodeoffset < 0) { 377 if (nodeoffset < 0) {
378 nodeoffset = fdt_add_subnode(blob, 0, "memory"); 378 nodeoffset = fdt_add_subnode(blob, 0, "memory");
379 if (nodeoffset < 0) 379 if (nodeoffset < 0)
380 printf("WARNING: could not create /memory: %s.\n", 380 printf("WARNING: could not create /memory: %s.\n",
381 fdt_strerror(nodeoffset)); 381 fdt_strerror(nodeoffset));
382 return nodeoffset; 382 return nodeoffset;
383 } 383 }
384 err = fdt_setprop(blob, nodeoffset, "device_type", "memory", 384 err = fdt_setprop(blob, nodeoffset, "device_type", "memory",
385 sizeof("memory")); 385 sizeof("memory"));
386 if (err < 0) { 386 if (err < 0) {
387 printf("WARNING: could not set %s %s.\n", "device_type", 387 printf("WARNING: could not set %s %s.\n", "device_type",
388 fdt_strerror(err)); 388 fdt_strerror(err));
389 return err; 389 return err;
390 } 390 }
391 391
392 addrcell = fdt_getprop(blob, 0, "#address-cells", NULL); 392 addrcell = fdt_getprop(blob, 0, "#address-cells", NULL);
393 /* use shifts and mask to ensure endianness */ 393 /* use shifts and mask to ensure endianness */
394 if ((addrcell) && (*addrcell == 2)) { 394 if ((addrcell) && (*addrcell == 2)) {
395 tmp[0] = (start >> 56) & 0xff; 395 tmp[0] = (start >> 56) & 0xff;
396 tmp[1] = (start >> 48) & 0xff; 396 tmp[1] = (start >> 48) & 0xff;
397 tmp[2] = (start >> 40) & 0xff; 397 tmp[2] = (start >> 40) & 0xff;
398 tmp[3] = (start >> 32) & 0xff; 398 tmp[3] = (start >> 32) & 0xff;
399 tmp[4] = (start >> 24) & 0xff; 399 tmp[4] = (start >> 24) & 0xff;
400 tmp[5] = (start >> 16) & 0xff; 400 tmp[5] = (start >> 16) & 0xff;
401 tmp[6] = (start >> 8) & 0xff; 401 tmp[6] = (start >> 8) & 0xff;
402 tmp[7] = (start ) & 0xff; 402 tmp[7] = (start ) & 0xff;
403 len = 8; 403 len = 8;
404 } else { 404 } else {
405 tmp[0] = (start >> 24) & 0xff; 405 tmp[0] = (start >> 24) & 0xff;
406 tmp[1] = (start >> 16) & 0xff; 406 tmp[1] = (start >> 16) & 0xff;
407 tmp[2] = (start >> 8) & 0xff; 407 tmp[2] = (start >> 8) & 0xff;
408 tmp[3] = (start ) & 0xff; 408 tmp[3] = (start ) & 0xff;
409 len = 4; 409 len = 4;
410 } 410 }
411 411
412 sizecell = fdt_getprop(blob, 0, "#size-cells", NULL); 412 sizecell = fdt_getprop(blob, 0, "#size-cells", NULL);
413 /* use shifts and mask to ensure endianness */ 413 /* use shifts and mask to ensure endianness */
414 if ((sizecell) && (*sizecell == 2)) { 414 if ((sizecell) && (*sizecell == 2)) {
415 tmp[0+len] = (size >> 56) & 0xff; 415 tmp[0+len] = (size >> 56) & 0xff;
416 tmp[1+len] = (size >> 48) & 0xff; 416 tmp[1+len] = (size >> 48) & 0xff;
417 tmp[2+len] = (size >> 40) & 0xff; 417 tmp[2+len] = (size >> 40) & 0xff;
418 tmp[3+len] = (size >> 32) & 0xff; 418 tmp[3+len] = (size >> 32) & 0xff;
419 tmp[4+len] = (size >> 24) & 0xff; 419 tmp[4+len] = (size >> 24) & 0xff;
420 tmp[5+len] = (size >> 16) & 0xff; 420 tmp[5+len] = (size >> 16) & 0xff;
421 tmp[6+len] = (size >> 8) & 0xff; 421 tmp[6+len] = (size >> 8) & 0xff;
422 tmp[7+len] = (size ) & 0xff; 422 tmp[7+len] = (size ) & 0xff;
423 len += 8; 423 len += 8;
424 } else { 424 } else {
425 tmp[0+len] = (size >> 24) & 0xff; 425 tmp[0+len] = (size >> 24) & 0xff;
426 tmp[1+len] = (size >> 16) & 0xff; 426 tmp[1+len] = (size >> 16) & 0xff;
427 tmp[2+len] = (size >> 8) & 0xff; 427 tmp[2+len] = (size >> 8) & 0xff;
428 tmp[3+len] = (size ) & 0xff; 428 tmp[3+len] = (size ) & 0xff;
429 len += 4; 429 len += 4;
430 } 430 }
431 431
432 err = fdt_setprop(blob, nodeoffset, "reg", tmp, len); 432 err = fdt_setprop(blob, nodeoffset, "reg", tmp, len);
433 if (err < 0) { 433 if (err < 0) {
434 printf("WARNING: could not set %s %s.\n", 434 printf("WARNING: could not set %s %s.\n",
435 "reg", fdt_strerror(err)); 435 "reg", fdt_strerror(err));
436 return err; 436 return err;
437 } 437 }
438 return 0; 438 return 0;
439 } 439 }
440 440
441 void fdt_fixup_ethernet(void *fdt) 441 void fdt_fixup_ethernet(void *fdt)
442 { 442 {
443 int node, i, j; 443 int node, i, j;
444 char enet[16], *tmp, *end; 444 char enet[16], *tmp, *end;
445 char mac[16] = "ethaddr"; 445 char mac[16] = "ethaddr";
446 const char *path; 446 const char *path;
447 unsigned char mac_addr[6]; 447 unsigned char mac_addr[6];
448 448
449 node = fdt_path_offset(fdt, "/aliases"); 449 node = fdt_path_offset(fdt, "/aliases");
450 if (node < 0) 450 if (node < 0)
451 return; 451 return;
452 452
453 i = 0; 453 i = 0;
454 while ((tmp = getenv(mac)) != NULL) { 454 while ((tmp = getenv(mac)) != NULL) {
455 sprintf(enet, "ethernet%d", i); 455 sprintf(enet, "ethernet%d", i);
456 path = fdt_getprop(fdt, node, enet, NULL); 456 path = fdt_getprop(fdt, node, enet, NULL);
457 if (!path) { 457 if (!path) {
458 debug("No alias for %s\n", enet); 458 debug("No alias for %s\n", enet);
459 sprintf(mac, "eth%daddr", ++i); 459 sprintf(mac, "eth%daddr", ++i);
460 continue; 460 continue;
461 } 461 }
462 462
463 for (j = 0; j < 6; j++) { 463 for (j = 0; j < 6; j++) {
464 mac_addr[j] = tmp ? simple_strtoul(tmp, &end, 16) : 0; 464 mac_addr[j] = tmp ? simple_strtoul(tmp, &end, 16) : 0;
465 if (tmp) 465 if (tmp)
466 tmp = (*end) ? end+1 : end; 466 tmp = (*end) ? end+1 : end;
467 } 467 }
468 468
469 do_fixup_by_path(fdt, path, "mac-address", &mac_addr, 6, 0); 469 do_fixup_by_path(fdt, path, "mac-address", &mac_addr, 6, 0);
470 do_fixup_by_path(fdt, path, "local-mac-address", 470 do_fixup_by_path(fdt, path, "local-mac-address",
471 &mac_addr, 6, 1); 471 &mac_addr, 6, 1);
472 472
473 sprintf(mac, "eth%daddr", ++i); 473 sprintf(mac, "eth%daddr", ++i);
474 } 474 }
475 } 475 }
476 476
477 #ifdef CONFIG_HAS_FSL_DR_USB 477 #ifdef CONFIG_HAS_FSL_DR_USB
478 void fdt_fixup_dr_usb(void *blob, bd_t *bd) 478 void fdt_fixup_dr_usb(void *blob, bd_t *bd)
479 { 479 {
480 char *mode; 480 char *mode;
481 char *type; 481 char *type;
482 const char *compat = "fsl-usb2-dr"; 482 const char *compat = "fsl-usb2-dr";
483 const char *prop_mode = "dr_mode"; 483 const char *prop_mode = "dr_mode";
484 const char *prop_type = "phy_type"; 484 const char *prop_type = "phy_type";
485 int node_offset; 485 int node_offset;
486 int err; 486 int err;
487 487
488 mode = getenv("usb_dr_mode"); 488 mode = getenv("usb_dr_mode");
489 type = getenv("usb_phy_type"); 489 type = getenv("usb_phy_type");
490 if (!mode && !type) 490 if (!mode && !type)
491 return; 491 return;
492 492
493 node_offset = fdt_node_offset_by_compatible(blob, 0, compat); 493 node_offset = fdt_node_offset_by_compatible(blob, 0, compat);
494 if (node_offset < 0) { 494 if (node_offset < 0) {
495 printf("WARNING: could not find compatible node %s: %s.\n", 495 printf("WARNING: could not find compatible node %s: %s.\n",
496 compat, fdt_strerror(node_offset)); 496 compat, fdt_strerror(node_offset));
497 return; 497 return;
498 } 498 }
499 499
500 if (mode) { 500 if (mode) {
501 err = fdt_setprop(blob, node_offset, prop_mode, mode, 501 err = fdt_setprop(blob, node_offset, prop_mode, mode,
502 strlen(mode) + 1); 502 strlen(mode) + 1);
503 if (err < 0) 503 if (err < 0)
504 printf("WARNING: could not set %s for %s: %s.\n", 504 printf("WARNING: could not set %s for %s: %s.\n",
505 prop_mode, compat, fdt_strerror(err)); 505 prop_mode, compat, fdt_strerror(err));
506 } 506 }
507 507
508 if (type) { 508 if (type) {
509 err = fdt_setprop(blob, node_offset, prop_type, type, 509 err = fdt_setprop(blob, node_offset, prop_type, type,
510 strlen(type) + 1); 510 strlen(type) + 1);
511 if (err < 0) 511 if (err < 0)
512 printf("WARNING: could not set %s for %s: %s.\n", 512 printf("WARNING: could not set %s for %s: %s.\n",
513 prop_type, compat, fdt_strerror(err)); 513 prop_type, compat, fdt_strerror(err));
514 } 514 }
515 } 515 }
516 #endif /* CONFIG_HAS_FSL_DR_USB */ 516 #endif /* CONFIG_HAS_FSL_DR_USB */
517 517
518 #if defined(CONFIG_MPC83xx) || defined(CONFIG_MPC85xx) 518 #if defined(CONFIG_MPC83xx) || defined(CONFIG_MPC85xx)
519 /* 519 /*
520 * update crypto node properties to a specified revision of the SEC 520 * update crypto node properties to a specified revision of the SEC
521 * called with sec_rev == 0 if not on an mpc8xxxE processor 521 * called with sec_rev == 0 if not on an mpc8xxxE processor
522 */ 522 */
523 void fdt_fixup_crypto_node(void *blob, int sec_rev) 523 void fdt_fixup_crypto_node(void *blob, int sec_rev)
524 { 524 {
525 const struct sec_rev_prop { 525 const struct sec_rev_prop {
526 u32 sec_rev; 526 u32 sec_rev;
527 u32 num_channels; 527 u32 num_channels;
528 u32 channel_fifo_len; 528 u32 channel_fifo_len;
529 u32 exec_units_mask; 529 u32 exec_units_mask;
530 u32 descriptor_types_mask; 530 u32 descriptor_types_mask;
531 } sec_rev_prop_list [] = { 531 } sec_rev_prop_list [] = {
532 { 0x0200, 4, 24, 0x07e, 0x01010ebf }, /* SEC 2.0 */ 532 { 0x0200, 4, 24, 0x07e, 0x01010ebf }, /* SEC 2.0 */
533 { 0x0201, 4, 24, 0x0fe, 0x012b0ebf }, /* SEC 2.1 */ 533 { 0x0201, 4, 24, 0x0fe, 0x012b0ebf }, /* SEC 2.1 */
534 { 0x0202, 1, 24, 0x04c, 0x0122003f }, /* SEC 2.2 */ 534 { 0x0202, 1, 24, 0x04c, 0x0122003f }, /* SEC 2.2 */
535 { 0x0204, 4, 24, 0x07e, 0x012b0ebf }, /* SEC 2.4 */ 535 { 0x0204, 4, 24, 0x07e, 0x012b0ebf }, /* SEC 2.4 */
536 { 0x0300, 4, 24, 0x9fe, 0x03ab0ebf }, /* SEC 3.0 */ 536 { 0x0300, 4, 24, 0x9fe, 0x03ab0ebf }, /* SEC 3.0 */
537 { 0x0303, 4, 24, 0x97c, 0x03ab0abf }, /* SEC 3.3 */ 537 { 0x0303, 4, 24, 0x97c, 0x03ab0abf }, /* SEC 3.3 */
538 }; 538 };
539 char compat_strlist[ARRAY_SIZE(sec_rev_prop_list) * 539 char compat_strlist[ARRAY_SIZE(sec_rev_prop_list) *
540 sizeof("fsl,secX.Y")]; 540 sizeof("fsl,secX.Y")];
541 int crypto_node, sec_idx, err; 541 int crypto_node, sec_idx, err;
542 char *p; 542 char *p;
543 u32 val; 543 u32 val;
544 544
545 /* locate crypto node based on lowest common compatible */ 545 /* locate crypto node based on lowest common compatible */
546 crypto_node = fdt_node_offset_by_compatible(blob, -1, "fsl,sec2.0"); 546 crypto_node = fdt_node_offset_by_compatible(blob, -1, "fsl,sec2.0");
547 if (crypto_node == -FDT_ERR_NOTFOUND) 547 if (crypto_node == -FDT_ERR_NOTFOUND)
548 return; 548 return;
549 549
550 /* delete it if not on an E-processor */ 550 /* delete it if not on an E-processor */
551 if (crypto_node > 0 && !sec_rev) { 551 if (crypto_node > 0 && !sec_rev) {
552 fdt_del_node(blob, crypto_node); 552 fdt_del_node(blob, crypto_node);
553 return; 553 return;
554 } 554 }
555 555
556 /* else we got called for possible uprev */ 556 /* else we got called for possible uprev */
557 for (sec_idx = 0; sec_idx < ARRAY_SIZE(sec_rev_prop_list); sec_idx++) 557 for (sec_idx = 0; sec_idx < ARRAY_SIZE(sec_rev_prop_list); sec_idx++)
558 if (sec_rev_prop_list[sec_idx].sec_rev == sec_rev) 558 if (sec_rev_prop_list[sec_idx].sec_rev == sec_rev)
559 break; 559 break;
560 560
561 if (sec_idx == ARRAY_SIZE(sec_rev_prop_list)) { 561 if (sec_idx == ARRAY_SIZE(sec_rev_prop_list)) {
562 puts("warning: unknown SEC revision number\n"); 562 puts("warning: unknown SEC revision number\n");
563 return; 563 return;
564 } 564 }
565 565
566 val = cpu_to_fdt32(sec_rev_prop_list[sec_idx].num_channels); 566 val = cpu_to_fdt32(sec_rev_prop_list[sec_idx].num_channels);
567 err = fdt_setprop(blob, crypto_node, "fsl,num-channels", &val, 4); 567 err = fdt_setprop(blob, crypto_node, "fsl,num-channels", &val, 4);
568 if (err < 0) 568 if (err < 0)
569 printf("WARNING: could not set crypto property: %s\n", 569 printf("WARNING: could not set crypto property: %s\n",
570 fdt_strerror(err)); 570 fdt_strerror(err));
571 571
572 val = cpu_to_fdt32(sec_rev_prop_list[sec_idx].descriptor_types_mask); 572 val = cpu_to_fdt32(sec_rev_prop_list[sec_idx].descriptor_types_mask);
573 err = fdt_setprop(blob, crypto_node, "fsl,descriptor-types-mask", &val, 4); 573 err = fdt_setprop(blob, crypto_node, "fsl,descriptor-types-mask", &val, 4);
574 if (err < 0) 574 if (err < 0)
575 printf("WARNING: could not set crypto property: %s\n", 575 printf("WARNING: could not set crypto property: %s\n",
576 fdt_strerror(err)); 576 fdt_strerror(err));
577 577
578 val = cpu_to_fdt32(sec_rev_prop_list[sec_idx].exec_units_mask); 578 val = cpu_to_fdt32(sec_rev_prop_list[sec_idx].exec_units_mask);
579 err = fdt_setprop(blob, crypto_node, "fsl,exec-units-mask", &val, 4); 579 err = fdt_setprop(blob, crypto_node, "fsl,exec-units-mask", &val, 4);
580 if (err < 0) 580 if (err < 0)
581 printf("WARNING: could not set crypto property: %s\n", 581 printf("WARNING: could not set crypto property: %s\n",
582 fdt_strerror(err)); 582 fdt_strerror(err));
583 583
584 val = cpu_to_fdt32(sec_rev_prop_list[sec_idx].channel_fifo_len); 584 val = cpu_to_fdt32(sec_rev_prop_list[sec_idx].channel_fifo_len);
585 err = fdt_setprop(blob, crypto_node, "fsl,channel-fifo-len", &val, 4); 585 err = fdt_setprop(blob, crypto_node, "fsl,channel-fifo-len", &val, 4);
586 if (err < 0) 586 if (err < 0)
587 printf("WARNING: could not set crypto property: %s\n", 587 printf("WARNING: could not set crypto property: %s\n",
588 fdt_strerror(err)); 588 fdt_strerror(err));
589 589
590 val = 0; 590 val = 0;
591 while (sec_idx >= 0) { 591 while (sec_idx >= 0) {
592 p = compat_strlist + val; 592 p = compat_strlist + val;
593 val += sprintf(p, "fsl,sec%d.%d", 593 val += sprintf(p, "fsl,sec%d.%d",
594 (sec_rev_prop_list[sec_idx].sec_rev & 0xff00) >> 8, 594 (sec_rev_prop_list[sec_idx].sec_rev & 0xff00) >> 8,
595 sec_rev_prop_list[sec_idx].sec_rev & 0x00ff) + 1; 595 sec_rev_prop_list[sec_idx].sec_rev & 0x00ff) + 1;
596 sec_idx--; 596 sec_idx--;
597 } 597 }
598 err = fdt_setprop(blob, crypto_node, "compatible", &compat_strlist, val); 598 err = fdt_setprop(blob, crypto_node, "compatible", &compat_strlist, val);
599 if (err < 0) 599 if (err < 0)
600 printf("WARNING: could not set crypto property: %s\n", 600 printf("WARNING: could not set crypto property: %s\n",
601 fdt_strerror(err)); 601 fdt_strerror(err));
602 } 602 }
603 #endif /* defined(CONFIG_MPC83xx) || defined(CONFIG_MPC85xx) */ 603 #endif /* defined(CONFIG_MPC83xx) || defined(CONFIG_MPC85xx) */
604 604
605 /* Resize the fdt to its actual size + a bit of padding */ 605 /* Resize the fdt to its actual size + a bit of padding */
606 int fdt_resize(void *blob) 606 int fdt_resize(void *blob)
607 { 607 {
608 int i; 608 int i;
609 uint64_t addr, size; 609 uint64_t addr, size;
610 int total, ret; 610 int total, ret;
611 uint actualsize; 611 uint actualsize;
612 612
613 if (!blob) 613 if (!blob)
614 return 0; 614 return 0;
615 615
616 total = fdt_num_mem_rsv(blob); 616 total = fdt_num_mem_rsv(blob);
617 for (i = 0; i < total; i++) { 617 for (i = 0; i < total; i++) {
618 fdt_get_mem_rsv(blob, i, &addr, &size); 618 fdt_get_mem_rsv(blob, i, &addr, &size);
619 if (addr == (uint64_t)(u32)blob) { 619 if (addr == (uint64_t)(u32)blob) {
620 fdt_del_mem_rsv(blob, i); 620 fdt_del_mem_rsv(blob, i);
621 break; 621 break;
622 } 622 }
623 } 623 }
624 624
625 /* 625 /*
626 * Calculate the actual size of the fdt 626 * Calculate the actual size of the fdt
627 * plus the size needed for two fdt_add_mem_rsv, one 627 * plus the size needed for two fdt_add_mem_rsv, one
628 * for the fdt itself and one for a possible initrd 628 * for the fdt itself and one for a possible initrd
629 */ 629 */
630 actualsize = fdt_off_dt_strings(blob) + 630 actualsize = fdt_off_dt_strings(blob) +
631 fdt_size_dt_strings(blob) + 2*sizeof(struct fdt_reserve_entry); 631 fdt_size_dt_strings(blob) + 2*sizeof(struct fdt_reserve_entry);
632 632
633 /* Make it so the fdt ends on a page boundary */ 633 /* Make it so the fdt ends on a page boundary */
634 actualsize = ALIGN(actualsize + ((uint)blob & 0xfff), 0x1000); 634 actualsize = ALIGN(actualsize + ((uint)blob & 0xfff), 0x1000);
635 actualsize = actualsize - ((uint)blob & 0xfff); 635 actualsize = actualsize - ((uint)blob & 0xfff);
636 636
637 /* Change the fdt header to reflect the correct size */ 637 /* Change the fdt header to reflect the correct size */
638 fdt_set_totalsize(blob, actualsize); 638 fdt_set_totalsize(blob, actualsize);
639 639
640 /* Add the new reservation */ 640 /* Add the new reservation */
641 ret = fdt_add_mem_rsv(blob, (uint)blob, actualsize); 641 ret = fdt_add_mem_rsv(blob, (uint)blob, actualsize);
642 if (ret < 0) 642 if (ret < 0)
643 return ret; 643 return ret;
644 644
645 return actualsize; 645 return actualsize;
646 } 646 }
647 647
648 #ifdef CONFIG_PCI 648 #ifdef CONFIG_PCI
649 #define CONFIG_SYS_PCI_NR_INBOUND_WIN 4 649 #define CONFIG_SYS_PCI_NR_INBOUND_WIN 4
650 650
651 #define FDT_PCI_PREFETCH (0x40000000) 651 #define FDT_PCI_PREFETCH (0x40000000)
652 #define FDT_PCI_MEM32 (0x02000000) 652 #define FDT_PCI_MEM32 (0x02000000)
653 #define FDT_PCI_IO (0x01000000) 653 #define FDT_PCI_IO (0x01000000)
654 #define FDT_PCI_MEM64 (0x03000000) 654 #define FDT_PCI_MEM64 (0x03000000)
655 655
656 int fdt_pci_dma_ranges(void *blob, int phb_off, struct pci_controller *hose) { 656 int fdt_pci_dma_ranges(void *blob, int phb_off, struct pci_controller *hose) {
657 657
658 int addrcell, sizecell, len, r; 658 int addrcell, sizecell, len, r;
659 u32 *dma_range; 659 u32 *dma_range;
660 /* sized based on pci addr cells, size-cells, & address-cells */ 660 /* sized based on pci addr cells, size-cells, & address-cells */
661 u32 dma_ranges[(3 + 2 + 2) * CONFIG_SYS_PCI_NR_INBOUND_WIN]; 661 u32 dma_ranges[(3 + 2 + 2) * CONFIG_SYS_PCI_NR_INBOUND_WIN];
662 662
663 addrcell = fdt_getprop_u32_default(blob, "/", "#address-cells", 1); 663 addrcell = fdt_getprop_u32_default(blob, "/", "#address-cells", 1);
664 sizecell = fdt_getprop_u32_default(blob, "/", "#size-cells", 1); 664 sizecell = fdt_getprop_u32_default(blob, "/", "#size-cells", 1);
665 665
666 dma_range = &dma_ranges[0]; 666 dma_range = &dma_ranges[0];
667 for (r = 0; r < hose->region_count; r++) { 667 for (r = 0; r < hose->region_count; r++) {
668 u64 bus_start, phys_start, size; 668 u64 bus_start, phys_start, size;
669 669
670 /* skip if !PCI_REGION_SYS_MEMORY */ 670 /* skip if !PCI_REGION_SYS_MEMORY */
671 if (!(hose->regions[r].flags & PCI_REGION_SYS_MEMORY)) 671 if (!(hose->regions[r].flags & PCI_REGION_SYS_MEMORY))
672 continue; 672 continue;
673 673
674 bus_start = (u64)hose->regions[r].bus_start; 674 bus_start = (u64)hose->regions[r].bus_start;
675 phys_start = (u64)hose->regions[r].phys_start; 675 phys_start = (u64)hose->regions[r].phys_start;
676 size = (u64)hose->regions[r].size; 676 size = (u64)hose->regions[r].size;
677 677
678 dma_range[0] = 0; 678 dma_range[0] = 0;
679 if (size >= 0x100000000ull) 679 if (size >= 0x100000000ull)
680 dma_range[0] |= FDT_PCI_MEM64; 680 dma_range[0] |= FDT_PCI_MEM64;
681 else 681 else
682 dma_range[0] |= FDT_PCI_MEM32; 682 dma_range[0] |= FDT_PCI_MEM32;
683 if (hose->regions[r].flags & PCI_REGION_PREFETCH) 683 if (hose->regions[r].flags & PCI_REGION_PREFETCH)
684 dma_range[0] |= FDT_PCI_PREFETCH; 684 dma_range[0] |= FDT_PCI_PREFETCH;
685 #ifdef CONFIG_SYS_PCI_64BIT 685 #ifdef CONFIG_SYS_PCI_64BIT
686 dma_range[1] = bus_start >> 32; 686 dma_range[1] = bus_start >> 32;
687 #else 687 #else
688 dma_range[1] = 0; 688 dma_range[1] = 0;
689 #endif 689 #endif
690 dma_range[2] = bus_start & 0xffffffff; 690 dma_range[2] = bus_start & 0xffffffff;
691 691
692 if (addrcell == 2) { 692 if (addrcell == 2) {
693 dma_range[3] = phys_start >> 32; 693 dma_range[3] = phys_start >> 32;
694 dma_range[4] = phys_start & 0xffffffff; 694 dma_range[4] = phys_start & 0xffffffff;
695 } else { 695 } else {
696 dma_range[3] = phys_start & 0xffffffff; 696 dma_range[3] = phys_start & 0xffffffff;
697 } 697 }
698 698
699 if (sizecell == 2) { 699 if (sizecell == 2) {
700 dma_range[3 + addrcell + 0] = size >> 32; 700 dma_range[3 + addrcell + 0] = size >> 32;
701 dma_range[3 + addrcell + 1] = size & 0xffffffff; 701 dma_range[3 + addrcell + 1] = size & 0xffffffff;
702 } else { 702 } else {
703 dma_range[3 + addrcell + 0] = size & 0xffffffff; 703 dma_range[3 + addrcell + 0] = size & 0xffffffff;
704 } 704 }
705 705
706 dma_range += (3 + addrcell + sizecell); 706 dma_range += (3 + addrcell + sizecell);
707 } 707 }
708 708
709 len = dma_range - &dma_ranges[0]; 709 len = dma_range - &dma_ranges[0];
710 if (len) 710 if (len)
711 fdt_setprop(blob, phb_off, "dma-ranges", &dma_ranges[0], len*4); 711 fdt_setprop(blob, phb_off, "dma-ranges", &dma_ranges[0], len*4);
712 712
713 return 0; 713 return 0;
714 } 714 }
715 #endif 715 #endif
716 716
717 #ifdef CONFIG_FDT_FIXUP_NOR_FLASH_SIZE 717 #ifdef CONFIG_FDT_FIXUP_NOR_FLASH_SIZE
718 /* 718 /*
719 * This function can be used to update the size in the "reg" property 719 * This function can be used to update the size in the "reg" property
720 * of the NOR FLASH device nodes. This is necessary for boards with 720 * of the NOR FLASH device nodes. This is necessary for boards with
721 * non-fixed NOR FLASH sizes. 721 * non-fixed NOR FLASH sizes.
722 */ 722 */
723 int fdt_fixup_nor_flash_size(void *blob, int cs, u32 size) 723 int fdt_fixup_nor_flash_size(void *blob, int cs, u32 size)
724 { 724 {
725 char compat[][16] = { "cfi-flash", "jedec-flash" }; 725 char compat[][16] = { "cfi-flash", "jedec-flash" };
726 int off; 726 int off;
727 int len; 727 int len;
728 struct fdt_property *prop; 728 struct fdt_property *prop;
729 u32 *reg; 729 u32 *reg;
730 int i; 730 int i;
731 731
732 for (i = 0; i < 2; i++) { 732 for (i = 0; i < 2; i++) {
733 off = fdt_node_offset_by_compatible(blob, -1, compat[i]); 733 off = fdt_node_offset_by_compatible(blob, -1, compat[i]);
734 while (off != -FDT_ERR_NOTFOUND) { 734 while (off != -FDT_ERR_NOTFOUND) {
735 /* 735 /*
736 * Found one compatible node, now check if this one 736 * Found one compatible node, now check if this one
737 * has the correct CS 737 * has the correct CS
738 */ 738 */
739 prop = fdt_get_property_w(blob, off, "reg", &len); 739 prop = fdt_get_property_w(blob, off, "reg", &len);
740 if (prop) { 740 if (prop) {
741 reg = (u32 *)&prop->data[0]; 741 reg = (u32 *)&prop->data[0];
742 if (reg[0] == cs) { 742 if (reg[0] == cs) {
743 reg[2] = size; 743 reg[2] = size;
744 fdt_setprop(blob, off, "reg", reg, 744 fdt_setprop(blob, off, "reg", reg,
745 3 * sizeof(u32)); 745 3 * sizeof(u32));
746 746
747 return 0; 747 return 0;
748 } 748 }
749 } 749 }
750 750
751 /* Move to next compatible node */ 751 /* Move to next compatible node */
752 off = fdt_node_offset_by_compatible(blob, off, 752 off = fdt_node_offset_by_compatible(blob, off,
753 compat[i]); 753 compat[i]);
754 } 754 }
755 } 755 }
756 756
757 return -1; 757 return -1;
758 } 758 }
759 #endif 759 #endif
760 760
761 #ifdef CONFIG_FDT_FIXUP_PARTITIONS 761 #ifdef CONFIG_FDT_FIXUP_PARTITIONS
762 #include <jffs2/load_kernel.h> 762 #include <jffs2/load_kernel.h>
763 #include <mtd_node.h> 763 #include <mtd_node.h>
764 764
765 struct reg_cell { 765 struct reg_cell {
766 unsigned int r0; 766 unsigned int r0;
767 unsigned int r1; 767 unsigned int r1;
768 }; 768 };
769 769
770 int fdt_del_subnodes(const void *blob, int parent_offset) 770 int fdt_del_subnodes(const void *blob, int parent_offset)
771 { 771 {
772 int off, ndepth; 772 int off, ndepth;
773 int ret; 773 int ret;
774 774
775 for (ndepth = 0, off = fdt_next_node(blob, parent_offset, &ndepth); 775 for (ndepth = 0, off = fdt_next_node(blob, parent_offset, &ndepth);
776 (off >= 0) && (ndepth > 0); 776 (off >= 0) && (ndepth > 0);
777 off = fdt_next_node(blob, off, &ndepth)) { 777 off = fdt_next_node(blob, off, &ndepth)) {
778 if (ndepth == 1) { 778 if (ndepth == 1) {
779 debug("delete %s: offset: %x\n", 779 debug("delete %s: offset: %x\n",
780 fdt_get_name(blob, off, 0), off); 780 fdt_get_name(blob, off, 0), off);
781 ret = fdt_del_node((void *)blob, off); 781 ret = fdt_del_node((void *)blob, off);
782 if (ret < 0) { 782 if (ret < 0) {
783 printf("Can't delete node: %s\n", 783 printf("Can't delete node: %s\n",
784 fdt_strerror(ret)); 784 fdt_strerror(ret));
785 return ret; 785 return ret;
786 } else { 786 } else {
787 ndepth = 0; 787 ndepth = 0;
788 off = parent_offset; 788 off = parent_offset;
789 } 789 }
790 } 790 }
791 } 791 }
792 return 0; 792 return 0;
793 } 793 }
794 794
795 int fdt_increase_size(void *fdt, int add_len) 795 int fdt_increase_size(void *fdt, int add_len)
796 { 796 {
797 int newlen; 797 int newlen;
798 798
799 newlen = fdt_totalsize(fdt) + add_len; 799 newlen = fdt_totalsize(fdt) + add_len;
800 800
801 /* Open in place with a new len */ 801 /* Open in place with a new len */
802 return fdt_open_into(fdt, fdt, newlen); 802 return fdt_open_into(fdt, fdt, newlen);
803 } 803 }
804 804
805 int fdt_del_partitions(void *blob, int parent_offset) 805 int fdt_del_partitions(void *blob, int parent_offset)
806 { 806 {
807 const void *prop; 807 const void *prop;
808 int ndepth = 0; 808 int ndepth = 0;
809 int off; 809 int off;
810 int ret; 810 int ret;
811 811
812 off = fdt_next_node(blob, parent_offset, &ndepth); 812 off = fdt_next_node(blob, parent_offset, &ndepth);
813 if (off > 0 && ndepth == 1) { 813 if (off > 0 && ndepth == 1) {
814 prop = fdt_getprop(blob, off, "label", NULL); 814 prop = fdt_getprop(blob, off, "label", NULL);
815 if (prop == NULL) { 815 if (prop == NULL) {
816 /* 816 /*
817 * Could not find label property, nand {}; node? 817 * Could not find label property, nand {}; node?
818 * Check subnode, delete partitions there if any. 818 * Check subnode, delete partitions there if any.
819 */ 819 */
820 return fdt_del_partitions(blob, off); 820 return fdt_del_partitions(blob, off);
821 } else { 821 } else {
822 ret = fdt_del_subnodes(blob, parent_offset); 822 ret = fdt_del_subnodes(blob, parent_offset);
823 if (ret < 0) { 823 if (ret < 0) {
824 printf("Can't remove subnodes: %s\n", 824 printf("Can't remove subnodes: %s\n",
825 fdt_strerror(ret)); 825 fdt_strerror(ret));
826 return ret; 826 return ret;
827 } 827 }
828 } 828 }
829 } 829 }
830 return 0; 830 return 0;
831 } 831 }
832 832
833 int fdt_node_set_part_info(void *blob, int parent_offset, 833 int fdt_node_set_part_info(void *blob, int parent_offset,
834 struct mtd_device *dev) 834 struct mtd_device *dev)
835 { 835 {
836 struct list_head *pentry; 836 struct list_head *pentry;
837 struct part_info *part; 837 struct part_info *part;
838 struct reg_cell cell; 838 struct reg_cell cell;
839 int off, ndepth = 0; 839 int off, ndepth = 0;
840 int part_num, ret; 840 int part_num, ret;
841 char buf[64]; 841 char buf[64];
842 842
843 ret = fdt_del_partitions(blob, parent_offset); 843 ret = fdt_del_partitions(blob, parent_offset);
844 if (ret < 0) 844 if (ret < 0)
845 return ret; 845 return ret;
846 846
847 /* 847 /*
848 * Check if it is nand {}; subnode, adjust 848 * Check if it is nand {}; subnode, adjust
849 * the offset in this case 849 * the offset in this case
850 */ 850 */
851 off = fdt_next_node(blob, parent_offset, &ndepth); 851 off = fdt_next_node(blob, parent_offset, &ndepth);
852 if (off > 0 && ndepth == 1) 852 if (off > 0 && ndepth == 1)
853 parent_offset = off; 853 parent_offset = off;
854 854
855 part_num = 0; 855 part_num = 0;
856 list_for_each_prev(pentry, &dev->parts) { 856 list_for_each_prev(pentry, &dev->parts) {
857 int newoff; 857 int newoff;
858 858
859 part = list_entry(pentry, struct part_info, link); 859 part = list_entry(pentry, struct part_info, link);
860 860
861 debug("%2d: %-20s0x%08x\t0x%08x\t%d\n", 861 debug("%2d: %-20s0x%08x\t0x%08x\t%d\n",
862 part_num, part->name, part->size, 862 part_num, part->name, part->size,
863 part->offset, part->mask_flags); 863 part->offset, part->mask_flags);
864 864
865 sprintf(buf, "partition@%x", part->offset); 865 sprintf(buf, "partition@%x", part->offset);
866 add_sub: 866 add_sub:
867 ret = fdt_add_subnode(blob, parent_offset, buf); 867 ret = fdt_add_subnode(blob, parent_offset, buf);
868 if (ret == -FDT_ERR_NOSPACE) { 868 if (ret == -FDT_ERR_NOSPACE) {
869 ret = fdt_increase_size(blob, 512); 869 ret = fdt_increase_size(blob, 512);
870 if (!ret) 870 if (!ret)
871 goto add_sub; 871 goto add_sub;
872 else 872 else
873 goto err_size; 873 goto err_size;
874 } else if (ret < 0) { 874 } else if (ret < 0) {
875 printf("Can't add partition node: %s\n", 875 printf("Can't add partition node: %s\n",
876 fdt_strerror(ret)); 876 fdt_strerror(ret));
877 return ret; 877 return ret;
878 } 878 }
879 newoff = ret; 879 newoff = ret;
880 880
881 /* Check MTD_WRITEABLE_CMD flag */ 881 /* Check MTD_WRITEABLE_CMD flag */
882 if (part->mask_flags & 1) { 882 if (part->mask_flags & 1) {
883 add_ro: 883 add_ro:
884 ret = fdt_setprop(blob, newoff, "read_only", NULL, 0); 884 ret = fdt_setprop(blob, newoff, "read_only", NULL, 0);
885 if (ret == -FDT_ERR_NOSPACE) { 885 if (ret == -FDT_ERR_NOSPACE) {
886 ret = fdt_increase_size(blob, 512); 886 ret = fdt_increase_size(blob, 512);
887 if (!ret) 887 if (!ret)
888 goto add_ro; 888 goto add_ro;
889 else 889 else
890 goto err_size; 890 goto err_size;
891 } else if (ret < 0) 891 } else if (ret < 0)
892 goto err_prop; 892 goto err_prop;
893 } 893 }
894 894
895 cell.r0 = cpu_to_fdt32(part->offset); 895 cell.r0 = cpu_to_fdt32(part->offset);
896 cell.r1 = cpu_to_fdt32(part->size); 896 cell.r1 = cpu_to_fdt32(part->size);
897 add_reg: 897 add_reg:
898 ret = fdt_setprop(blob, newoff, "reg", &cell, sizeof(cell)); 898 ret = fdt_setprop(blob, newoff, "reg", &cell, sizeof(cell));
899 if (ret == -FDT_ERR_NOSPACE) { 899 if (ret == -FDT_ERR_NOSPACE) {
900 ret = fdt_increase_size(blob, 512); 900 ret = fdt_increase_size(blob, 512);
901 if (!ret) 901 if (!ret)
902 goto add_reg; 902 goto add_reg;
903 else 903 else
904 goto err_size; 904 goto err_size;
905 } else if (ret < 0) 905 } else if (ret < 0)
906 goto err_prop; 906 goto err_prop;
907 907
908 add_label: 908 add_label:
909 ret = fdt_setprop_string(blob, newoff, "label", part->name); 909 ret = fdt_setprop_string(blob, newoff, "label", part->name);
910 if (ret == -FDT_ERR_NOSPACE) { 910 if (ret == -FDT_ERR_NOSPACE) {
911 ret = fdt_increase_size(blob, 512); 911 ret = fdt_increase_size(blob, 512);
912 if (!ret) 912 if (!ret)
913 goto add_label; 913 goto add_label;
914 else 914 else
915 goto err_size; 915 goto err_size;
916 } else if (ret < 0) 916 } else if (ret < 0)
917 goto err_prop; 917 goto err_prop;
918 918
919 part_num++; 919 part_num++;
920 } 920 }
921 return 0; 921 return 0;
922 err_size: 922 err_size:
923 printf("Can't increase blob size: %s\n", fdt_strerror(ret)); 923 printf("Can't increase blob size: %s\n", fdt_strerror(ret));
924 return ret; 924 return ret;
925 err_prop: 925 err_prop:
926 printf("Can't add property: %s\n", fdt_strerror(ret)); 926 printf("Can't add property: %s\n", fdt_strerror(ret));
927 return ret; 927 return ret;
928 } 928 }
929 929
930 /* 930 /*
931 * Update partitions in nor/nand nodes using info from 931 * Update partitions in nor/nand nodes using info from
932 * mtdparts environment variable. The nodes to update are 932 * mtdparts environment variable. The nodes to update are
933 * specified by node_info structure which contains mtd device 933 * specified by node_info structure which contains mtd device
934 * type and compatible string: E. g. the board code in 934 * type and compatible string: E. g. the board code in
935 * ft_board_setup() could use: 935 * ft_board_setup() could use:
936 * 936 *
937 * struct node_info nodes[] = { 937 * struct node_info nodes[] = {
938 * { "fsl,mpc5121-nfc", MTD_DEV_TYPE_NAND, }, 938 * { "fsl,mpc5121-nfc", MTD_DEV_TYPE_NAND, },
939 * { "cfi-flash", MTD_DEV_TYPE_NOR, }, 939 * { "cfi-flash", MTD_DEV_TYPE_NOR, },
940 * }; 940 * };
941 * 941 *
942 * fdt_fixup_mtdparts(blob, nodes, ARRAY_SIZE(nodes)); 942 * fdt_fixup_mtdparts(blob, nodes, ARRAY_SIZE(nodes));
943 */ 943 */
944 void fdt_fixup_mtdparts(void *blob, void *node_info, int node_info_size) 944 void fdt_fixup_mtdparts(void *blob, void *node_info, int node_info_size)
945 { 945 {
946 struct node_info *ni = node_info; 946 struct node_info *ni = node_info;
947 struct mtd_device *dev; 947 struct mtd_device *dev;
948 char *parts; 948 char *parts;
949 int i, idx; 949 int i, idx;
950 int noff; 950 int noff;
951 951
952 parts = getenv("mtdparts"); 952 parts = getenv("mtdparts");
953 if (!parts) 953 if (!parts)
954 return; 954 return;
955 955
956 if (mtdparts_init() != 0) 956 if (mtdparts_init() != 0)
957 return; 957 return;
958 958
959 for (i = 0; i < node_info_size; i++) { 959 for (i = 0; i < node_info_size; i++) {
960 idx = 0; 960 idx = 0;
961 noff = fdt_node_offset_by_compatible(blob, -1, ni[i].compat); 961 noff = fdt_node_offset_by_compatible(blob, -1, ni[i].compat);
962 while (noff != -FDT_ERR_NOTFOUND) { 962 while (noff != -FDT_ERR_NOTFOUND) {
963 debug("%s: %s, mtd dev type %d\n", 963 debug("%s: %s, mtd dev type %d\n",
964 fdt_get_name(blob, noff, 0), 964 fdt_get_name(blob, noff, 0),
965 ni[i].compat, ni[i].type); 965 ni[i].compat, ni[i].type);
966 dev = device_find(ni[i].type, idx++); 966 dev = device_find(ni[i].type, idx++);
967 if (dev) { 967 if (dev) {
968 if (fdt_node_set_part_info(blob, noff, dev)) 968 if (fdt_node_set_part_info(blob, noff, dev))
969 return; /* return on error */ 969 return; /* return on error */
970 } 970 }
971 971
972 /* Jump to next flash node */ 972 /* Jump to next flash node */
973 noff = fdt_node_offset_by_compatible(blob, noff, 973 noff = fdt_node_offset_by_compatible(blob, noff,
974 ni[i].compat); 974 ni[i].compat);
975 } 975 }
976 } 976 }
977 } 977 }
978 #endif 978 #endif
979
980 void fdt_del_node_and_alias(void *blob, const char *alias)
981 {
982 int off = fdt_path_offset(blob, alias);
983
984 if (off < 0)
985 return;
986
987 fdt_del_node(blob, off);
988
989 off = fdt_path_offset(blob, "/aliases");
990 fdt_delprop(blob, off, alias);
991 }
979 992
include/fdt_support.h
1 /* 1 /*
2 * (C) Copyright 2007 2 * (C) Copyright 2007
3 * Gerald Van Baren, Custom IDEAS, vanbaren@cideas.com 3 * Gerald Van Baren, Custom IDEAS, vanbaren@cideas.com
4 * 4 *
5 * See file CREDITS for list of people who contributed to this 5 * See file CREDITS for list of people who contributed to this
6 * project. 6 * project.
7 * 7 *
8 * This program is free software; you can redistribute it and/or 8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License as 9 * modify it under the terms of the GNU General Public License as
10 * published by the Free Software Foundation; either version 2 of 10 * published by the Free Software Foundation; either version 2 of
11 * the License, or (at your option) any later version. 11 * the License, or (at your option) any later version.
12 * 12 *
13 * This program is distributed in the hope that it will be useful, 13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details. 16 * GNU General Public License for more details.
17 * 17 *
18 * You should have received a copy of the GNU General Public License 18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software 19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, 20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
21 * MA 02111-1307 USA 21 * MA 02111-1307 USA
22 */ 22 */
23 23
24 #ifndef __FDT_SUPPORT_H 24 #ifndef __FDT_SUPPORT_H
25 #define __FDT_SUPPORT_H 25 #define __FDT_SUPPORT_H
26 26
27 #ifdef CONFIG_OF_LIBFDT 27 #ifdef CONFIG_OF_LIBFDT
28 28
29 #include <fdt.h> 29 #include <fdt.h>
30 30
31 u32 fdt_getprop_u32_default(void *fdt, const char *path, const char *prop, 31 u32 fdt_getprop_u32_default(void *fdt, const char *path, const char *prop,
32 const u32 dflt); 32 const u32 dflt);
33 int fdt_chosen(void *fdt, int force); 33 int fdt_chosen(void *fdt, int force);
34 int fdt_initrd(void *fdt, ulong initrd_start, ulong initrd_end, int force); 34 int fdt_initrd(void *fdt, ulong initrd_start, ulong initrd_end, int force);
35 void do_fixup_by_path(void *fdt, const char *path, const char *prop, 35 void do_fixup_by_path(void *fdt, const char *path, const char *prop,
36 const void *val, int len, int create); 36 const void *val, int len, int create);
37 void do_fixup_by_path_u32(void *fdt, const char *path, const char *prop, 37 void do_fixup_by_path_u32(void *fdt, const char *path, const char *prop,
38 u32 val, int create); 38 u32 val, int create);
39 void do_fixup_by_prop(void *fdt, 39 void do_fixup_by_prop(void *fdt,
40 const char *pname, const void *pval, int plen, 40 const char *pname, const void *pval, int plen,
41 const char *prop, const void *val, int len, 41 const char *prop, const void *val, int len,
42 int create); 42 int create);
43 void do_fixup_by_prop_u32(void *fdt, 43 void do_fixup_by_prop_u32(void *fdt,
44 const char *pname, const void *pval, int plen, 44 const char *pname, const void *pval, int plen,
45 const char *prop, u32 val, int create); 45 const char *prop, u32 val, int create);
46 void do_fixup_by_compat(void *fdt, const char *compat, 46 void do_fixup_by_compat(void *fdt, const char *compat,
47 const char *prop, const void *val, int len, int create); 47 const char *prop, const void *val, int len, int create);
48 void do_fixup_by_compat_u32(void *fdt, const char *compat, 48 void do_fixup_by_compat_u32(void *fdt, const char *compat,
49 const char *prop, u32 val, int create); 49 const char *prop, u32 val, int create);
50 int fdt_fixup_memory(void *blob, u64 start, u64 size); 50 int fdt_fixup_memory(void *blob, u64 start, u64 size);
51 void fdt_fixup_ethernet(void *fdt); 51 void fdt_fixup_ethernet(void *fdt);
52 int fdt_find_and_setprop(void *fdt, const char *node, const char *prop, 52 int fdt_find_and_setprop(void *fdt, const char *node, const char *prop,
53 const void *val, int len, int create); 53 const void *val, int len, int create);
54 void fdt_fixup_qe_firmware(void *fdt); 54 void fdt_fixup_qe_firmware(void *fdt);
55 55
56 #ifdef CONFIG_HAS_FSL_DR_USB 56 #ifdef CONFIG_HAS_FSL_DR_USB
57 void fdt_fixup_dr_usb(void *blob, bd_t *bd); 57 void fdt_fixup_dr_usb(void *blob, bd_t *bd);
58 #else 58 #else
59 static inline void fdt_fixup_dr_usb(void *blob, bd_t *bd) {} 59 static inline void fdt_fixup_dr_usb(void *blob, bd_t *bd) {}
60 #endif /* CONFIG_HAS_FSL_DR_USB */ 60 #endif /* CONFIG_HAS_FSL_DR_USB */
61 61
62 #if defined(CONFIG_MPC85xx) || defined(CONFIG_MPC83xx) 62 #if defined(CONFIG_MPC85xx) || defined(CONFIG_MPC83xx)
63 void fdt_fixup_crypto_node(void *blob, int sec_rev); 63 void fdt_fixup_crypto_node(void *blob, int sec_rev);
64 #else 64 #else
65 static inline void fdt_fixup_crypto_node(void *blob, int sec_rev) {} 65 static inline void fdt_fixup_crypto_node(void *blob, int sec_rev) {}
66 #endif 66 #endif
67 67
68 #ifdef CONFIG_PCI 68 #ifdef CONFIG_PCI
69 #include <pci.h> 69 #include <pci.h>
70 int fdt_pci_dma_ranges(void *blob, int phb_off, struct pci_controller *hose); 70 int fdt_pci_dma_ranges(void *blob, int phb_off, struct pci_controller *hose);
71 #endif 71 #endif
72 72
73 #ifdef CONFIG_OF_BOARD_SETUP 73 #ifdef CONFIG_OF_BOARD_SETUP
74 void ft_board_setup(void *blob, bd_t *bd); 74 void ft_board_setup(void *blob, bd_t *bd);
75 void ft_cpu_setup(void *blob, bd_t *bd); 75 void ft_cpu_setup(void *blob, bd_t *bd);
76 void ft_pci_setup(void *blob, bd_t *bd); 76 void ft_pci_setup(void *blob, bd_t *bd);
77 #endif 77 #endif
78 78
79 void set_working_fdt_addr(void *addr); 79 void set_working_fdt_addr(void *addr);
80 int fdt_resize(void *blob); 80 int fdt_resize(void *blob);
81 81
82 int fdt_fixup_nor_flash_size(void *blob, int cs, u32 size); 82 int fdt_fixup_nor_flash_size(void *blob, int cs, u32 size);
83 83
84 void fdt_fixup_mtdparts(void *fdt, void *node_info, int node_info_size); 84 void fdt_fixup_mtdparts(void *fdt, void *node_info, int node_info_size);
85 void fdt_del_node_and_alias(void *blob, const char *alias);
85 86
86 #endif /* ifdef CONFIG_OF_LIBFDT */ 87 #endif /* ifdef CONFIG_OF_LIBFDT */
87 #endif /* ifndef __FDT_SUPPORT_H */ 88 #endif /* ifndef __FDT_SUPPORT_H */
88 89