|
|
@ -438,3 +438,122 @@ const char * of_fdt_get_machine_name(void *mempos) |
|
|
|
return name; |
|
|
|
} |
|
|
|
|
|
|
|
/**
|
|
|
|
* of_fdt_is_big_endian - Return true if given node needs BE MMIO accesses |
|
|
|
* @blob: A device tree blob |
|
|
|
* @node: node to test |
|
|
|
* |
|
|
|
* Returns true if the node has a "big-endian" property, or if the kernel |
|
|
|
* was compiled for BE *and* the node has a "native-endian" property. |
|
|
|
* Returns false otherwise. |
|
|
|
*/ |
|
|
|
int of_fdt_is_big_endian(const void *blob, unsigned long node) |
|
|
|
{ |
|
|
|
if (fdt_getprop(blob, node, "big-endian", NULL)) |
|
|
|
return 1; |
|
|
|
#ifdef _LITTLE_ENDIAN |
|
|
|
#else |
|
|
|
if (fdt_getprop(blob, node, "native-endian", NULL)) |
|
|
|
return 1; |
|
|
|
#endif |
|
|
|
return 0; |
|
|
|
} |
|
|
|
|
|
|
|
/**
|
|
|
|
* of_fdt_is_compatible - Return true if given node from the given blob has |
|
|
|
* compat in its compatible list |
|
|
|
* @blob: A device tree blob |
|
|
|
* @node: node to test |
|
|
|
* @compat: compatible string to compare with compatible list. |
|
|
|
* |
|
|
|
* On match, returns a non-zero value with smaller values returned for more |
|
|
|
* specific compatible values. |
|
|
|
*/ |
|
|
|
int of_fdt_is_compatible(const void *blob, unsigned long node, const char *compat) |
|
|
|
{ |
|
|
|
const char *cp; |
|
|
|
int cplen; |
|
|
|
unsigned long l, score = 0; |
|
|
|
|
|
|
|
cp = fdt_getprop(blob, node, "compatible", &cplen); |
|
|
|
if (cp == NULL) |
|
|
|
return 0; |
|
|
|
while (cplen > 0) { |
|
|
|
score++; |
|
|
|
if (strcasecmp(cp, compat) == 0) |
|
|
|
return score; |
|
|
|
l = strlen(cp) + 1; |
|
|
|
cp += l; |
|
|
|
cplen -= l; |
|
|
|
} |
|
|
|
|
|
|
|
return 0; |
|
|
|
} |
|
|
|
|
|
|
|
/**
|
|
|
|
* of_fdt_match - Return true if node matches a list of compatible values |
|
|
|
*/ |
|
|
|
int of_fdt_match(const void *blob, unsigned long node, const char *const *compat) |
|
|
|
{ |
|
|
|
unsigned int tmp, score = 0; |
|
|
|
|
|
|
|
if (!compat) |
|
|
|
return 0; |
|
|
|
|
|
|
|
while (*compat) { |
|
|
|
tmp = of_fdt_is_compatible(blob, node, *compat); |
|
|
|
if (tmp && (score == 0 || (tmp < score))) |
|
|
|
score = tmp; |
|
|
|
compat++; |
|
|
|
} |
|
|
|
|
|
|
|
return score; |
|
|
|
} |
|
|
|
|
|
|
|
/**
|
|
|
|
* of_flat_dt_match_machine - Iterate match tables to find matching machine. |
|
|
|
* |
|
|
|
* @default_match: A machine specific ptr to return in case of no match. |
|
|
|
* @get_next_compat: callback function to return next compatible match table. |
|
|
|
* |
|
|
|
* Iterate through machine match tables to find the best match for the machine |
|
|
|
* compatible string in the FDT. |
|
|
|
*/ |
|
|
|
const void * of_flat_dt_match_machine(void *mempos, const void *default_match, const void * (*get_next_compat)(const char * const**)) |
|
|
|
{ |
|
|
|
const void *data = NULL; |
|
|
|
const void *best_data = default_match; |
|
|
|
unsigned long dt_root; |
|
|
|
const char *const *compat; |
|
|
|
unsigned int best_score = ~1, score = 0; |
|
|
|
|
|
|
|
while ((data = get_next_compat(&compat))) { |
|
|
|
score = of_fdt_match(mempos, dt_root, compat); |
|
|
|
if (score > 0 && score < best_score) { |
|
|
|
best_data = data; |
|
|
|
best_score = score; |
|
|
|
} |
|
|
|
} |
|
|
|
if (!best_data) { |
|
|
|
const char *prop; |
|
|
|
int size; |
|
|
|
|
|
|
|
printf("\n unrecognized device tree list:\n[ "); |
|
|
|
|
|
|
|
prop = fdt_getprop(mempos, dt_root, "compatible", &size); |
|
|
|
if (prop) { |
|
|
|
while (size > 0) { |
|
|
|
printf("'%s' ", prop); |
|
|
|
size -= strlen(prop) + 1; |
|
|
|
prop += strlen(prop) + 1; |
|
|
|
} |
|
|
|
} |
|
|
|
printf("]\n\n"); |
|
|
|
return NULL; |
|
|
|
} |
|
|
|
|
|
|
|
printf("Machine model: %s\n", of_fdt_get_machine_name(mempos)); |
|
|
|
|
|
|
|
return best_data; |
|
|
|
} |
|
|
|
|
|
|
|