提交 7ac0bbf9 编写于 作者: L Linus Torvalds

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
...@@ -4,11 +4,13 @@ Specifying interrupt information for devices ...@@ -4,11 +4,13 @@ Specifying interrupt information for devices
1) Interrupt client nodes 1) Interrupt client nodes
------------------------- -------------------------
Nodes that describe devices which generate interrupts must contain an either an Nodes that describe devices which generate interrupts must contain an
"interrupts" property or an "interrupts-extended" property. These properties "interrupts" property, an "interrupts-extended" property, or both. If both are
contain a list of interrupt specifiers, one per output interrupt. The format of present, the latter should take precedence; the former may be provided simply
the interrupt specifier is determined by the interrupt controller to which the for compatibility with software that does not recognize the latter. These
interrupts are routed; see section 2 below for details. 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: Example:
interrupt-parent = <&intc1>; interrupt-parent = <&intc1>;
......
...@@ -453,7 +453,7 @@ static int __init __reserved_mem_reserve_reg(unsigned long node, ...@@ -453,7 +453,7 @@ static int __init __reserved_mem_reserve_reg(unsigned long node,
base = dt_mem_next_cell(dt_root_addr_cells, &prop); base = dt_mem_next_cell(dt_root_addr_cells, &prop);
size = dt_mem_next_cell(dt_root_size_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) 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", pr_debug("Reserved memory: reserved region for node '%s': base %pa, size %ld MiB\n",
uname, &base, (unsigned long)size / SZ_1M); 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 ...@@ -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) */ /* Get the reg property (if any) */
addr = of_get_property(device, "reg", NULL); 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 */ /* Get the interrupts property */
intspec = of_get_property(device, "interrupts", &intlen); intspec = of_get_property(device, "interrupts", &intlen);
if (intspec == NULL) { if (intspec == NULL)
/* Try the new-style interrupts-extended */ return -EINVAL;
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);
}
intlen /= sizeof(*intspec); intlen /= sizeof(*intspec);
pr_debug(" intspec=%d intlen=%d\n", be32_to_cpup(intspec), intlen); pr_debug(" intspec=%d intlen=%d\n", be32_to_cpup(intspec), intlen);
......
...@@ -27,6 +27,7 @@ static struct selftest_results { ...@@ -27,6 +27,7 @@ static struct selftest_results {
#define NO_OF_NODES 2 #define NO_OF_NODES 2
static struct device_node *nodes[NO_OF_NODES]; static struct device_node *nodes[NO_OF_NODES];
static int last_node_index; static int last_node_index;
static bool selftest_live_tree;
#define selftest(result, fmt, ...) { \ #define selftest(result, fmt, ...) { \
if (!(result)) { \ if (!(result)) { \
...@@ -630,13 +631,6 @@ static int attach_node_and_children(struct device_node *np) ...@@ -630,13 +631,6 @@ static int attach_node_and_children(struct device_node *np)
{ {
struct device_node *next, *root = np, *dup; 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 */ /* skip root node */
np = np->child; np = np->child;
/* storing a copy in temporary node */ /* storing a copy in temporary node */
...@@ -672,12 +666,12 @@ static int attach_node_and_children(struct device_node *np) ...@@ -672,12 +666,12 @@ static int attach_node_and_children(struct device_node *np)
static int __init selftest_data_add(void) static int __init selftest_data_add(void)
{ {
void *selftest_data; 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_begin[];
extern uint8_t __dtb_testcases_end[]; extern uint8_t __dtb_testcases_end[];
const int size = __dtb_testcases_end - __dtb_testcases_begin; 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", pr_warn("%s: No testcase data to attach; not running tests\n",
__func__); __func__);
return -ENODATA; return -ENODATA;
...@@ -692,6 +686,22 @@ static int __init selftest_data_add(void) ...@@ -692,6 +686,22 @@ static int __init selftest_data_add(void)
return -ENOMEM; return -ENOMEM;
} }
of_fdt_unflatten_tree(selftest_data, &selftest_data_node); 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 */ /* attach the sub-tree to live tree */
return attach_node_and_children(selftest_data_node); return attach_node_and_children(selftest_data_node);
...@@ -723,6 +733,18 @@ static void selftest_data_remove(void) ...@@ -723,6 +733,18 @@ static void selftest_data_remove(void)
struct device_node *np; struct device_node *np;
struct property *prop; 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) { while (last_node_index >= 0) {
if (nodes[last_node_index]) { if (nodes[last_node_index]) {
np = of_find_node_by_path(nodes[last_node_index]->full_name); np = of_find_node_by_path(nodes[last_node_index]->full_name);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册