diff options
author | Scott Wood <scottwood@freescale.com> | 2007-08-20 13:39:48 -0400 |
---|---|---|
committer | Paul Mackerras <paulus@samba.org> | 2007-08-22 01:21:48 -0400 |
commit | a73ac50c4787b1b28d5c94bb18c60352f5dd7d6f (patch) | |
tree | 8c78ad293d3ee4bb43543e25df348b729832a02c /arch/powerpc/boot | |
parent | 0602801c22ea1767cd0298b11da140bd5cb764d2 (diff) |
[POWERPC] bootwrapper: Add dt_is_compatible()
This can be used rather than doing a simple strcmp, which will fail to
handle multiple compatible entries.
Signed-off-by: Scott Wood <scottwood@freescale.com>
Acked-by: David Gibson <david@gibson.dropbear.id.au>
Signed-off-by: Paul Mackerras <paulus@samba.org>
Diffstat (limited to 'arch/powerpc/boot')
-rw-r--r-- | arch/powerpc/boot/devtree.c | 48 | ||||
-rw-r--r-- | arch/powerpc/boot/ops.h | 1 |
2 files changed, 34 insertions, 15 deletions
diff --git a/arch/powerpc/boot/devtree.c b/arch/powerpc/boot/devtree.c index 129e6d9b8d43..3a18bfe0fdf7 100644 --- a/arch/powerpc/boot/devtree.c +++ b/arch/powerpc/boot/devtree.c | |||
@@ -113,7 +113,6 @@ void __dt_fixup_mac_addresses(u32 startindex, ...) | |||
113 | } | 113 | } |
114 | 114 | ||
115 | #define MAX_ADDR_CELLS 4 | 115 | #define MAX_ADDR_CELLS 4 |
116 | #define MAX_RANGES 8 | ||
117 | 116 | ||
118 | static void get_reg_format(void *node, u32 *naddr, u32 *nsize) | 117 | static void get_reg_format(void *node, u32 *naddr, u32 *nsize) |
119 | { | 118 | { |
@@ -209,7 +208,7 @@ static int find_range(u32 *reg, u32 *ranges, int nregaddr, | |||
209 | * In particular, PCI is not supported. Also, only the beginning of the | 208 | * In particular, PCI is not supported. Also, only the beginning of the |
210 | * reg block is tracked; size is ignored except in ranges. | 209 | * reg block is tracked; size is ignored except in ranges. |
211 | */ | 210 | */ |
212 | static u32 dt_xlate_buf[MAX_ADDR_CELLS * MAX_RANGES * 3]; | 211 | static u32 prop_buf[MAX_PROP_LEN / 4]; |
213 | 212 | ||
214 | static int dt_xlate(void *node, int res, int reglen, unsigned long *addr, | 213 | static int dt_xlate(void *node, int res, int reglen, unsigned long *addr, |
215 | unsigned long *size) | 214 | unsigned long *size) |
@@ -233,15 +232,15 @@ static int dt_xlate(void *node, int res, int reglen, unsigned long *addr, | |||
233 | offset = (naddr + nsize) * res; | 232 | offset = (naddr + nsize) * res; |
234 | 233 | ||
235 | if (reglen < offset + naddr + nsize || | 234 | if (reglen < offset + naddr + nsize || |
236 | sizeof(dt_xlate_buf) < (offset + naddr + nsize) * 4) | 235 | MAX_PROP_LEN < (offset + naddr + nsize) * 4) |
237 | return 0; | 236 | return 0; |
238 | 237 | ||
239 | copy_val(last_addr, dt_xlate_buf + offset, naddr); | 238 | copy_val(last_addr, prop_buf + offset, naddr); |
240 | 239 | ||
241 | ret_size = dt_xlate_buf[offset + naddr]; | 240 | ret_size = prop_buf[offset + naddr]; |
242 | if (nsize == 2) { | 241 | if (nsize == 2) { |
243 | ret_size <<= 32; | 242 | ret_size <<= 32; |
244 | ret_size |= dt_xlate_buf[offset + naddr + 1]; | 243 | ret_size |= prop_buf[offset + naddr + 1]; |
245 | } | 244 | } |
246 | 245 | ||
247 | for (;;) { | 246 | for (;;) { |
@@ -255,25 +254,25 @@ static int dt_xlate(void *node, int res, int reglen, unsigned long *addr, | |||
255 | 254 | ||
256 | get_reg_format(parent, &naddr, &nsize); | 255 | get_reg_format(parent, &naddr, &nsize); |
257 | 256 | ||
258 | buflen = getprop(node, "ranges", dt_xlate_buf, | 257 | buflen = getprop(node, "ranges", prop_buf, |
259 | sizeof(dt_xlate_buf)); | 258 | sizeof(prop_buf)); |
260 | if (buflen == 0) | 259 | if (buflen == 0) |
261 | continue; | 260 | continue; |
262 | if (buflen < 0 || buflen > sizeof(dt_xlate_buf)) | 261 | if (buflen < 0 || buflen > sizeof(prop_buf)) |
263 | return 0; | 262 | return 0; |
264 | 263 | ||
265 | offset = find_range(last_addr, dt_xlate_buf, prev_naddr, | 264 | offset = find_range(last_addr, prop_buf, prev_naddr, |
266 | naddr, prev_nsize, buflen / 4); | 265 | naddr, prev_nsize, buflen / 4); |
267 | 266 | ||
268 | if (offset < 0) | 267 | if (offset < 0) |
269 | return 0; | 268 | return 0; |
270 | 269 | ||
271 | copy_val(this_addr, dt_xlate_buf + offset, prev_naddr); | 270 | copy_val(this_addr, prop_buf + offset, prev_naddr); |
272 | 271 | ||
273 | if (!sub_reg(last_addr, this_addr)) | 272 | if (!sub_reg(last_addr, this_addr)) |
274 | return 0; | 273 | return 0; |
275 | 274 | ||
276 | copy_val(this_addr, dt_xlate_buf + offset + prev_naddr, naddr); | 275 | copy_val(this_addr, prop_buf + offset + prev_naddr, naddr); |
277 | 276 | ||
278 | if (!add_reg(last_addr, this_addr, naddr)) | 277 | if (!add_reg(last_addr, this_addr, naddr)) |
279 | return 0; | 278 | return 0; |
@@ -300,16 +299,35 @@ int dt_xlate_reg(void *node, int res, unsigned long *addr, unsigned long *size) | |||
300 | { | 299 | { |
301 | int reglen; | 300 | int reglen; |
302 | 301 | ||
303 | reglen = getprop(node, "reg", dt_xlate_buf, sizeof(dt_xlate_buf)) / 4; | 302 | reglen = getprop(node, "reg", prop_buf, sizeof(prop_buf)) / 4; |
304 | return dt_xlate(node, res, reglen, addr, size); | 303 | return dt_xlate(node, res, reglen, addr, size); |
305 | } | 304 | } |
306 | 305 | ||
307 | int dt_xlate_addr(void *node, u32 *buf, int buflen, unsigned long *xlated_addr) | 306 | int dt_xlate_addr(void *node, u32 *buf, int buflen, unsigned long *xlated_addr) |
308 | { | 307 | { |
309 | 308 | ||
310 | if (buflen > sizeof(dt_xlate_buf)) | 309 | if (buflen > sizeof(prop_buf)) |
311 | return 0; | 310 | return 0; |
312 | 311 | ||
313 | memcpy(dt_xlate_buf, buf, buflen); | 312 | memcpy(prop_buf, buf, buflen); |
314 | return dt_xlate(node, 0, buflen / 4, xlated_addr, NULL); | 313 | return dt_xlate(node, 0, buflen / 4, xlated_addr, NULL); |
315 | } | 314 | } |
315 | |||
316 | int dt_is_compatible(void *node, const char *compat) | ||
317 | { | ||
318 | char *buf = (char *)prop_buf; | ||
319 | int len, pos; | ||
320 | |||
321 | len = getprop(node, "compatible", buf, MAX_PROP_LEN); | ||
322 | if (len < 0) | ||
323 | return 0; | ||
324 | |||
325 | for (pos = 0; pos < len; pos++) { | ||
326 | if (!strcmp(buf + pos, compat)) | ||
327 | return 1; | ||
328 | |||
329 | pos += strnlen(&buf[pos], len - pos); | ||
330 | } | ||
331 | |||
332 | return 0; | ||
333 | } | ||
diff --git a/arch/powerpc/boot/ops.h b/arch/powerpc/boot/ops.h index aebd6edc9a90..a10bf5a153d5 100644 --- a/arch/powerpc/boot/ops.h +++ b/arch/powerpc/boot/ops.h | |||
@@ -87,6 +87,7 @@ void *simple_alloc_init(char *base, unsigned long heap_size, | |||
87 | extern void flush_cache(void *, unsigned long); | 87 | extern void flush_cache(void *, unsigned long); |
88 | int dt_xlate_reg(void *node, int res, unsigned long *addr, unsigned long *size); | 88 | int dt_xlate_reg(void *node, int res, unsigned long *addr, unsigned long *size); |
89 | int dt_xlate_addr(void *node, u32 *buf, int buflen, unsigned long *xlated_addr); | 89 | int dt_xlate_addr(void *node, u32 *buf, int buflen, unsigned long *xlated_addr); |
90 | int dt_is_compatible(void *node, const char *compat); | ||
90 | 91 | ||
91 | static inline void *finddevice(const char *name) | 92 | static inline void *finddevice(const char *name) |
92 | { | 93 | { |