Additional devicetree changes for v3.17
Three more commits needed for v3.17: A bug fix for reserved regions based at address zero, a clarification on how to interpret existence of both interrupts and interrupts-extended properties, and a fix to allow device tree testcases to run on any platform. -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQIbBAABAgAGBQJT77FEAAoJEMWQL496c2LNxPAP+OOyx76nq0yk5ee6pfWmL397 bqRfEtWX5Lp72Bq1jiyPQy5W525UClbfADCaal6Fy+xO0dz9DKZKoXdT5nX3NKx4 KAvsrJIvJN72HLIqbhqV45pUZMa3RTMx8+iC0LfNIKPB60GLuHZ/0SjFPN0btxDF 6nJAoAW/82kFdg+Kuq72oP955ejmYxXbbVwwDe6M4sGchArCAYxJcdGsEuokwhMm Cy0campj9eXbSGNceM6Kz6busO8ZliwzXEfe2+nvRPXwnETlqJZT8GmV3o5CZ+U9 aOSpZfYG8wb95o4tqaUnR9liPRutfF4HrRldD8sdfQheu4ylCLHUW6fcrgnvLUil a7djk5bSKdmvMWZUJ6v3VJRC3iiRJ2PHmF5Tk2PbFCPC8m/s+4QG2oh/3G8oI5Rf 7i3027xEtNtCmTBcuikPrPlJyiMIjFFibTjtB2i/jNSNv0XQdjKv/W+sE2VI3062 iHORCu7VGLXAK32gSAqtzBrcsXxq14rPdtkJ9DR8Cz3+gUvra17t8JcUk///a7r5 DRW6g93fyXqmqx4d63tp3pb44XbEiYkihyOz7R/dcrBFspZDvkMf5kF2rpQpHTmI n9pWsOoawZikHMFVSehcPzVJeQeFXtlJWSzPJkXwFEveUVsyhhCoSFXwuaI30BBr LELrzQ30VFcxtr4QRmY= =ZaXA -----END PGP SIGNATURE----- Merge tag 'devicetree-for-linus' of git://git.secretlab.ca/git/linux Pull devicetree fixes from Grant Likely: "Three more commits needed for v3.17: A bug fix for reserved regions based at address zero, a clarification on how to interpret existence of both interrupts and interrupts-extended properties, and a fix to allow device tree testcases to run on any platform" * tag 'devicetree-for-linus' of git://git.secretlab.ca/git/linux: of/irq: Fix lookup to use 'interrupts-extended' property first Enabling OF selftest to run without machine's devicetree of: Allow mem_reserve of memory with a base address of zero
This commit is contained in:
Коммит
7ac0bbf99d
|
@ -4,11 +4,13 @@ Specifying interrupt information for devices
|
|||
1) Interrupt client nodes
|
||||
-------------------------
|
||||
|
||||
Nodes that describe devices which generate interrupts must contain an either an
|
||||
"interrupts" property or an "interrupts-extended" property. These properties
|
||||
contain a list of interrupt specifiers, one per output interrupt. The format of
|
||||
the interrupt specifier is determined by the interrupt controller to which the
|
||||
interrupts are routed; see section 2 below for details.
|
||||
Nodes that describe devices which generate interrupts must contain an
|
||||
"interrupts" property, an "interrupts-extended" property, or both. If both are
|
||||
present, the latter should take precedence; the former may be provided simply
|
||||
for compatibility with software that does not recognize the latter. These
|
||||
properties contain a list of interrupt specifiers, one per output interrupt. The
|
||||
format of the interrupt specifier is determined by the interrupt controller to
|
||||
which the interrupts are routed; see section 2 below for details.
|
||||
|
||||
Example:
|
||||
interrupt-parent = <&intc1>;
|
||||
|
|
|
@ -453,7 +453,7 @@ static int __init __reserved_mem_reserve_reg(unsigned long node,
|
|||
base = dt_mem_next_cell(dt_root_addr_cells, &prop);
|
||||
size = dt_mem_next_cell(dt_root_size_cells, &prop);
|
||||
|
||||
if (base && size &&
|
||||
if (size &&
|
||||
early_init_dt_reserve_memory_arch(base, size, nomap) == 0)
|
||||
pr_debug("Reserved memory: reserved region for node '%s': base %pa, size %ld MiB\n",
|
||||
uname, &base, (unsigned long)size / SZ_1M);
|
||||
|
|
|
@ -301,16 +301,17 @@ int of_irq_parse_one(struct device_node *device, int index, struct of_phandle_ar
|
|||
/* Get the reg property (if any) */
|
||||
addr = of_get_property(device, "reg", NULL);
|
||||
|
||||
/* Try the new-style interrupts-extended first */
|
||||
res = of_parse_phandle_with_args(device, "interrupts-extended",
|
||||
"#interrupt-cells", index, out_irq);
|
||||
if (!res)
|
||||
return of_irq_parse_raw(addr, out_irq);
|
||||
|
||||
/* Get the interrupts property */
|
||||
intspec = of_get_property(device, "interrupts", &intlen);
|
||||
if (intspec == NULL) {
|
||||
/* Try the new-style interrupts-extended */
|
||||
res = of_parse_phandle_with_args(device, "interrupts-extended",
|
||||
"#interrupt-cells", index, out_irq);
|
||||
if (res)
|
||||
return -EINVAL;
|
||||
return of_irq_parse_raw(addr, out_irq);
|
||||
}
|
||||
if (intspec == NULL)
|
||||
return -EINVAL;
|
||||
|
||||
intlen /= sizeof(*intspec);
|
||||
|
||||
pr_debug(" intspec=%d intlen=%d\n", be32_to_cpup(intspec), intlen);
|
||||
|
|
|
@ -27,6 +27,7 @@ static struct selftest_results {
|
|||
#define NO_OF_NODES 2
|
||||
static struct device_node *nodes[NO_OF_NODES];
|
||||
static int last_node_index;
|
||||
static bool selftest_live_tree;
|
||||
|
||||
#define selftest(result, fmt, ...) { \
|
||||
if (!(result)) { \
|
||||
|
@ -630,13 +631,6 @@ static int attach_node_and_children(struct device_node *np)
|
|||
{
|
||||
struct device_node *next, *root = np, *dup;
|
||||
|
||||
if (!np) {
|
||||
pr_warn("%s: No tree to attach; not running tests\n",
|
||||
__func__);
|
||||
return -ENODATA;
|
||||
}
|
||||
|
||||
|
||||
/* skip root node */
|
||||
np = np->child;
|
||||
/* storing a copy in temporary node */
|
||||
|
@ -672,12 +666,12 @@ static int attach_node_and_children(struct device_node *np)
|
|||
static int __init selftest_data_add(void)
|
||||
{
|
||||
void *selftest_data;
|
||||
struct device_node *selftest_data_node;
|
||||
struct device_node *selftest_data_node, *np;
|
||||
extern uint8_t __dtb_testcases_begin[];
|
||||
extern uint8_t __dtb_testcases_end[];
|
||||
const int size = __dtb_testcases_end - __dtb_testcases_begin;
|
||||
|
||||
if (!size || !of_allnodes) {
|
||||
if (!size) {
|
||||
pr_warn("%s: No testcase data to attach; not running tests\n",
|
||||
__func__);
|
||||
return -ENODATA;
|
||||
|
@ -692,6 +686,22 @@ static int __init selftest_data_add(void)
|
|||
return -ENOMEM;
|
||||
}
|
||||
of_fdt_unflatten_tree(selftest_data, &selftest_data_node);
|
||||
if (!selftest_data_node) {
|
||||
pr_warn("%s: No tree to attach; not running tests\n", __func__);
|
||||
return -ENODATA;
|
||||
}
|
||||
|
||||
if (!of_allnodes) {
|
||||
/* enabling flag for removing nodes */
|
||||
selftest_live_tree = true;
|
||||
of_allnodes = selftest_data_node;
|
||||
|
||||
for_each_of_allnodes(np)
|
||||
__of_attach_node_sysfs(np);
|
||||
of_aliases = of_find_node_by_path("/aliases");
|
||||
of_chosen = of_find_node_by_path("/chosen");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* attach the sub-tree to live tree */
|
||||
return attach_node_and_children(selftest_data_node);
|
||||
|
@ -723,6 +733,18 @@ static void selftest_data_remove(void)
|
|||
struct device_node *np;
|
||||
struct property *prop;
|
||||
|
||||
if (selftest_live_tree) {
|
||||
of_node_put(of_aliases);
|
||||
of_node_put(of_chosen);
|
||||
of_aliases = NULL;
|
||||
of_chosen = NULL;
|
||||
for_each_child_of_node(of_allnodes, np)
|
||||
detach_node_and_children(np);
|
||||
__of_detach_node_sysfs(of_allnodes);
|
||||
of_allnodes = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
while (last_node_index >= 0) {
|
||||
if (nodes[last_node_index]) {
|
||||
np = of_find_node_by_path(nodes[last_node_index]->full_name);
|
||||
|
|
Загрузка…
Ссылка в новой задаче