Merge tag 'devicetree-for-4.17' of git://git.kernel.org/pub/scm/linux/kernel/git/robh/linux

Pull DeviceTree updates from Rob Herring:

 - Sync dtc to upstream version v1.4.6-9-gaadd0b65c987. This adds a
   bunch more warnings (hidden behind W=1).

 - Build dtc lexer and parser files instead of using shipped versions.

 - Rework overlay apply API to take an FDT as input and apply overlays
   in a single step.

 - Add a phandle lookup cache. This improves boot time by hundreds of
   msec on systems with large DT.

 - Add trivial mcp4017/18/19 potentiometers bindings.

 - Remove VLA stack usage in DT code.

* tag 'devicetree-for-4.17' of git://git.kernel.org/pub/scm/linux/kernel/git/robh/linux: (26 commits)
  of: unittest: fix an error code in of_unittest_apply_overlay()
  of: unittest: move misplaced function declaration
  of: unittest: Remove VLA stack usage
  of: overlay: Fix forgotten reference to of_overlay_apply()
  of: Documentation: Fix forgotten reference to of_overlay_apply()
  of: unittest: local return value variable related cleanups
  of: unittest: remove unneeded local return value variables
  dt-bindings: trivial: add various mcp4017/18/19 potentiometers
  of: unittest: fix an error test in of_unittest_overlay_8()
  of: cache phandle nodes to reduce cost of of_find_node_by_phandle()
  dt-bindings: rockchip-dw-mshc: use consistent clock names
  MAINTAINERS: Add linux/of_*.h headers to appropriate subsystems
  scripts: turn off some new dtc warnings by default
  scripts/dtc: Update to upstream version v1.4.6-9-gaadd0b65c987
  scripts/dtc: generate lexer and parser during build instead of shipping
  powerpc: boot: add strrchr function
  of: overlay: do not include path in full_name of added nodes
  of: unittest: clean up changeset test
  arm64/efi: Make strrchr() available to the EFI namespace
  ARM: boot: add strrchr function
  ...
This commit is contained in:
Linus Torvalds
2018-04-05 21:03:42 -07:00
کامیت 9c2dd8405c
45فایلهای تغییر یافته به همراه1213 افزوده شده و 5169 حذف شده

مشاهده پرونده

@@ -91,10 +91,72 @@ int __weak of_node_to_nid(struct device_node *np)
}
#endif
static struct device_node **phandle_cache;
static u32 phandle_cache_mask;
/*
* Assumptions behind phandle_cache implementation:
* - phandle property values are in a contiguous range of 1..n
*
* If the assumptions do not hold, then
* - the phandle lookup overhead reduction provided by the cache
* will likely be less
*/
static void of_populate_phandle_cache(void)
{
unsigned long flags;
u32 cache_entries;
struct device_node *np;
u32 phandles = 0;
raw_spin_lock_irqsave(&devtree_lock, flags);
kfree(phandle_cache);
phandle_cache = NULL;
for_each_of_allnodes(np)
if (np->phandle && np->phandle != OF_PHANDLE_ILLEGAL)
phandles++;
cache_entries = roundup_pow_of_two(phandles);
phandle_cache_mask = cache_entries - 1;
phandle_cache = kcalloc(cache_entries, sizeof(*phandle_cache),
GFP_ATOMIC);
if (!phandle_cache)
goto out;
for_each_of_allnodes(np)
if (np->phandle && np->phandle != OF_PHANDLE_ILLEGAL)
phandle_cache[np->phandle & phandle_cache_mask] = np;
out:
raw_spin_unlock_irqrestore(&devtree_lock, flags);
}
#ifndef CONFIG_MODULES
static int __init of_free_phandle_cache(void)
{
unsigned long flags;
raw_spin_lock_irqsave(&devtree_lock, flags);
kfree(phandle_cache);
phandle_cache = NULL;
raw_spin_unlock_irqrestore(&devtree_lock, flags);
return 0;
}
late_initcall_sync(of_free_phandle_cache);
#endif
void __init of_core_init(void)
{
struct device_node *np;
of_populate_phandle_cache();
/* Create the kset, and register existing nodes */
mutex_lock(&of_mutex);
of_kset = kset_create_and_add("devicetree", NULL, firmware_kobj);
@@ -1021,16 +1083,32 @@ EXPORT_SYMBOL_GPL(of_modalias_node);
*/
struct device_node *of_find_node_by_phandle(phandle handle)
{
struct device_node *np;
struct device_node *np = NULL;
unsigned long flags;
phandle masked_handle;
if (!handle)
return NULL;
raw_spin_lock_irqsave(&devtree_lock, flags);
for_each_of_allnodes(np)
if (np->phandle == handle)
break;
masked_handle = handle & phandle_cache_mask;
if (phandle_cache) {
if (phandle_cache[masked_handle] &&
handle == phandle_cache[masked_handle]->phandle)
np = phandle_cache[masked_handle];
}
if (!np) {
for_each_of_allnodes(np)
if (np->phandle == handle) {
if (phandle_cache)
phandle_cache[masked_handle] = np;
break;
}
}
of_node_get(np);
raw_spin_unlock_irqrestore(&devtree_lock, flags);
return np;
@@ -1283,6 +1361,190 @@ int of_parse_phandle_with_args(const struct device_node *np, const char *list_na
}
EXPORT_SYMBOL(of_parse_phandle_with_args);
/**
* of_parse_phandle_with_args_map() - Find a node pointed by phandle in a list and remap it
* @np: pointer to a device tree node containing a list
* @list_name: property name that contains a list
* @stem_name: stem of property names that specify phandles' arguments count
* @index: index of a phandle to parse out
* @out_args: optional pointer to output arguments structure (will be filled)
*
* This function is useful to parse lists of phandles and their arguments.
* Returns 0 on success and fills out_args, on error returns appropriate errno
* value. The difference between this function and of_parse_phandle_with_args()
* is that this API remaps a phandle if the node the phandle points to has
* a <@stem_name>-map property.
*
* Caller is responsible to call of_node_put() on the returned out_args->np
* pointer.
*
* Example:
*
* phandle1: node1 {
* #list-cells = <2>;
* }
*
* phandle2: node2 {
* #list-cells = <1>;
* }
*
* phandle3: node3 {
* #list-cells = <1>;
* list-map = <0 &phandle2 3>,
* <1 &phandle2 2>,
* <2 &phandle1 5 1>;
* list-map-mask = <0x3>;
* };
*
* node4 {
* list = <&phandle1 1 2 &phandle3 0>;
* }
*
* To get a device_node of the `node2' node you may call this:
* of_parse_phandle_with_args(node4, "list", "list", 1, &args);
*/
int of_parse_phandle_with_args_map(const struct device_node *np,
const char *list_name,
const char *stem_name,
int index, struct of_phandle_args *out_args)
{
char *cells_name, *map_name = NULL, *mask_name = NULL;
char *pass_name = NULL;
struct device_node *cur, *new = NULL;
const __be32 *map, *mask, *pass;
static const __be32 dummy_mask[] = { [0 ... MAX_PHANDLE_ARGS] = ~0 };
static const __be32 dummy_pass[] = { [0 ... MAX_PHANDLE_ARGS] = 0 };
__be32 initial_match_array[MAX_PHANDLE_ARGS];
const __be32 *match_array = initial_match_array;
int i, ret, map_len, match;
u32 list_size, new_size;
if (index < 0)
return -EINVAL;
cells_name = kasprintf(GFP_KERNEL, "#%s-cells", stem_name);
if (!cells_name)
return -ENOMEM;
ret = -ENOMEM;
map_name = kasprintf(GFP_KERNEL, "%s-map", stem_name);
if (!map_name)
goto free;
mask_name = kasprintf(GFP_KERNEL, "%s-map-mask", stem_name);
if (!mask_name)
goto free;
pass_name = kasprintf(GFP_KERNEL, "%s-map-pass-thru", stem_name);
if (!pass_name)
goto free;
ret = __of_parse_phandle_with_args(np, list_name, cells_name, 0, index,
out_args);
if (ret)
goto free;
/* Get the #<list>-cells property */
cur = out_args->np;
ret = of_property_read_u32(cur, cells_name, &list_size);
if (ret < 0)
goto put;
/* Precalculate the match array - this simplifies match loop */
for (i = 0; i < list_size; i++)
initial_match_array[i] = cpu_to_be32(out_args->args[i]);
ret = -EINVAL;
while (cur) {
/* Get the <list>-map property */
map = of_get_property(cur, map_name, &map_len);
if (!map) {
ret = 0;
goto free;
}
map_len /= sizeof(u32);
/* Get the <list>-map-mask property (optional) */
mask = of_get_property(cur, mask_name, NULL);
if (!mask)
mask = dummy_mask;
/* Iterate through <list>-map property */
match = 0;
while (map_len > (list_size + 1) && !match) {
/* Compare specifiers */
match = 1;
for (i = 0; i < list_size; i++, map_len--)
match &= !((match_array[i] ^ *map++) & mask[i]);
of_node_put(new);
new = of_find_node_by_phandle(be32_to_cpup(map));
map++;
map_len--;
/* Check if not found */
if (!new)
goto put;
if (!of_device_is_available(new))
match = 0;
ret = of_property_read_u32(new, cells_name, &new_size);
if (ret)
goto put;
/* Check for malformed properties */
if (WARN_ON(new_size > MAX_PHANDLE_ARGS))
goto put;
if (map_len < new_size)
goto put;
/* Move forward by new node's #<list>-cells amount */
map += new_size;
map_len -= new_size;
}
if (!match)
goto put;
/* Get the <list>-map-pass-thru property (optional) */
pass = of_get_property(cur, pass_name, NULL);
if (!pass)
pass = dummy_pass;
/*
* Successfully parsed a <list>-map translation; copy new
* specifier into the out_args structure, keeping the
* bits specified in <list>-map-pass-thru.
*/
match_array = map - new_size;
for (i = 0; i < new_size; i++) {
__be32 val = *(map - new_size + i);
if (i < list_size) {
val &= ~pass[i];
val |= cpu_to_be32(out_args->args[i]) & pass[i];
}
out_args->args[i] = be32_to_cpu(val);
}
out_args->args_count = list_size = new_size;
/* Iterate again with new provider */
out_args->np = new;
of_node_put(cur);
cur = new;
}
put:
of_node_put(cur);
of_node_put(new);
free:
kfree(mask_name);
kfree(map_name);
kfree(cells_name);
kfree(pass_name);
return ret;
}
EXPORT_SYMBOL(of_parse_phandle_with_args_map);
/**
* of_parse_phandle_with_fixed_args() - Find a node pointed by phandle in a list
* @np: pointer to a device tree node containing a list

مشاهده پرونده

@@ -383,25 +383,24 @@ struct property *__of_prop_dup(const struct property *prop, gfp_t allocflags)
/**
* __of_node_dup() - Duplicate or create an empty device node dynamically.
* @fmt: Format string (plus vargs) for new full name of the device node
* @np: if not NULL, contains properties to be duplicated in new node
* @full_name: string value to be duplicated into new node's full_name field
*
* Create an device tree node, either by duplicating an empty node or by allocating
* an empty one suitable for further modification. The node data are
* dynamically allocated and all the node flags have the OF_DYNAMIC &
* OF_DETACHED bits set. Returns the newly allocated node or NULL on out of
* memory error.
* Create a device tree node, optionally duplicating the properties of
* another node. The node data are dynamically allocated and all the node
* flags have the OF_DYNAMIC & OF_DETACHED bits set.
*
* Returns the newly allocated node or NULL on out of memory error.
*/
struct device_node *__of_node_dup(const struct device_node *np, const char *fmt, ...)
struct device_node *__of_node_dup(const struct device_node *np,
const char *full_name)
{
va_list vargs;
struct device_node *node;
node = kzalloc(sizeof(*node), GFP_KERNEL);
if (!node)
return NULL;
va_start(vargs, fmt);
node->full_name = kvasprintf(GFP_KERNEL, fmt, vargs);
va_end(vargs);
node->full_name = kstrdup(full_name, GFP_KERNEL);
if (!node->full_name) {
kfree(node);
return NULL;

مشاهده پرونده

@@ -104,7 +104,8 @@ extern void *__unflatten_device_tree(const void *blob,
* own the devtree lock or work on detached trees only.
*/
struct property *__of_prop_dup(const struct property *prop, gfp_t allocflags);
__printf(2, 3) struct device_node *__of_node_dup(const struct device_node *np, const char *fmt, ...);
struct device_node *__of_node_dup(const struct device_node *np,
const char *full_name);
struct device_node *__of_find_node_by_path(struct device_node *parent,
const char *path);
@@ -131,6 +132,9 @@ extern void __of_detach_node_sysfs(struct device_node *np);
extern void __of_sysfs_remove_bin_file(struct device_node *np,
struct property *prop);
/* illegal phandle value (set when unresolved) */
#define OF_PHANDLE_ILLEGAL 0xdeadbeef
/* iterators for transactions, used for overlays */
/* forward iterator */
#define for_each_transaction_entry(_oft, _te) \

مشاهده پرونده

@@ -312,7 +312,20 @@ static int add_changeset_property(struct overlay_changeset *ovcs,
* If @node has child nodes, add the children recursively via
* build_changeset_next_level().
*
* NOTE: Multiple mods of created nodes not supported.
* NOTE_1: A live devicetree created from a flattened device tree (FDT) will
* not contain the full path in node->full_name. Thus an overlay
* created from an FDT also will not contain the full path in
* node->full_name. However, a live devicetree created from Open
* Firmware may have the full path in node->full_name.
*
* add_changeset_node() follows the FDT convention and does not include
* the full path in node->full_name. Even though it expects the overlay
* to not contain the full path, it uses kbasename() to remove the
* full path should it exist. It also uses kbasename() in comparisons
* to nodes in the live devicetree so that it can apply an overlay to
* a live devicetree created from Open Firmware.
*
* NOTE_2: Multiple mods of created nodes not supported.
* If more than one fragment contains a node that does not already exist
* in the live tree, then for each fragment of_changeset_attach_node()
* will add a changeset entry to add the node. When the changeset is
@@ -339,8 +352,7 @@ static int add_changeset_node(struct overlay_changeset *ovcs,
break;
if (!tchild) {
tchild = __of_node_dup(node, "%pOF/%s",
target_node, node_kbasename);
tchild = __of_node_dup(node, node_kbasename);
if (!tchild)
return -ENOMEM;
@@ -958,7 +970,7 @@ static int overlay_removal_is_ok(struct overlay_changeset *remove_ovcs)
* @ovcs_id: Pointer to overlay changeset id
*
* Removes an overlay if it is permissible. @ovcs_id was previously returned
* by of_overlay_apply().
* by of_overlay_fdt_apply().
*
* If an error occurred while attempting to revert the overlay changeset,
* then an attempt is made to re-apply any changeset entry that was

مشاهده پرونده

@@ -19,9 +19,6 @@
#include "of_private.h"
/* illegal phandle value (set when unresolved) */
#define OF_PHANDLE_ILLEGAL 0xdeadbeef
static phandle live_tree_max_phandle(void)
{
struct device_node *node;

مشاهده پرونده

@@ -26,6 +26,18 @@
#phandle-cells = <3>;
};
provider4: provider4 {
#phandle-cells = <2>;
phandle-map = <0 1 &provider1 3>,
<4 0 &provider0>,
<16 5 &provider3 3 5 0>,
<200 8 &provider2 23 6>,
<19 0 &provider2 15 0>,
<2 3 &provider3 2 5 3>;
phandle-map-mask = <0xff 0xf>;
phandle-map-pass-thru = <0x0 0xf0>;
};
consumer-a {
phandle-list = <&provider1 1>,
<&provider2 2 0>,
@@ -44,6 +56,19 @@
unterminated-string = [40 41 42 43];
unterminated-string-list = "first", "second", [40 41 42 43];
};
consumer-b {
phandle-list = <&provider1 1>,
<&provider4 2 3>,
<0>,
<&provider4 4 0x100>,
<&provider4 0 0x61>,
<&provider0>,
<&provider4 19 0x20>;
phandle-list-bad-phandle = <12345678 0 0>;
phandle-list-bad-args = <&provider2 1 0>,
<&provider4 0>;
};
};
};
};

مشاهده پرونده

@@ -45,8 +45,6 @@ static struct unittest_results {
failed; \
})
static int __init overlay_data_apply(const char *overlay_name, int *overlay_id);
static void __init of_unittest_find_node_by_name(void)
{
struct device_node *np;
@@ -254,12 +252,18 @@ static void __init of_unittest_check_tree_linkage(void)
static void __init of_unittest_printf_one(struct device_node *np, const char *fmt,
const char *expected)
{
unsigned char buf[strlen(expected)+10];
unsigned char *buf;
int buf_size;
int size, i;
buf_size = strlen(expected) + 10;
buf = kmalloc(buf_size, GFP_KERNEL);
if (!buf)
return;
/* Baseline; check conversion with a large size limit */
memset(buf, 0xff, sizeof(buf));
size = snprintf(buf, sizeof(buf) - 2, fmt, np);
memset(buf, 0xff, buf_size);
size = snprintf(buf, buf_size - 2, fmt, np);
/* use strcmp() instead of strncmp() here to be absolutely sure strings match */
unittest((strcmp(buf, expected) == 0) && (buf[size+1] == 0xff),
@@ -270,12 +274,13 @@ static void __init of_unittest_printf_one(struct device_node *np, const char *fm
size++;
for (i = 0; i < 2; i++, size--) {
/* Clear the buffer, and make sure it works correctly still */
memset(buf, 0xff, sizeof(buf));
memset(buf, 0xff, buf_size);
snprintf(buf, size+1, fmt, np);
unittest(strncmp(buf, expected, size) == 0 && (buf[size+1] == 0xff),
"snprintf failed; size=%i fmt='%s' expected='%s' rslt='%s'\n",
size, fmt, expected, buf);
}
kfree(buf);
}
static void __init of_unittest_printf(void)
@@ -455,6 +460,125 @@ static void __init of_unittest_parse_phandle_with_args(void)
unittest(rc == -EINVAL, "expected:%i got:%i\n", -EINVAL, rc);
}
static void __init of_unittest_parse_phandle_with_args_map(void)
{
struct device_node *np, *p0, *p1, *p2, *p3;
struct of_phandle_args args;
int i, rc;
np = of_find_node_by_path("/testcase-data/phandle-tests/consumer-b");
if (!np) {
pr_err("missing testcase data\n");
return;
}
p0 = of_find_node_by_path("/testcase-data/phandle-tests/provider0");
if (!p0) {
pr_err("missing testcase data\n");
return;
}
p1 = of_find_node_by_path("/testcase-data/phandle-tests/provider1");
if (!p1) {
pr_err("missing testcase data\n");
return;
}
p2 = of_find_node_by_path("/testcase-data/phandle-tests/provider2");
if (!p2) {
pr_err("missing testcase data\n");
return;
}
p3 = of_find_node_by_path("/testcase-data/phandle-tests/provider3");
if (!p3) {
pr_err("missing testcase data\n");
return;
}
rc = of_count_phandle_with_args(np, "phandle-list", "#phandle-cells");
unittest(rc == 7, "of_count_phandle_with_args() returned %i, expected 7\n", rc);
for (i = 0; i < 8; i++) {
bool passed = true;
rc = of_parse_phandle_with_args_map(np, "phandle-list",
"phandle", i, &args);
/* Test the values from tests-phandle.dtsi */
switch (i) {
case 0:
passed &= !rc;
passed &= (args.np == p1);
passed &= (args.args_count == 1);
passed &= (args.args[0] == 1);
break;
case 1:
passed &= !rc;
passed &= (args.np == p3);
passed &= (args.args_count == 3);
passed &= (args.args[0] == 2);
passed &= (args.args[1] == 5);
passed &= (args.args[2] == 3);
break;
case 2:
passed &= (rc == -ENOENT);
break;
case 3:
passed &= !rc;
passed &= (args.np == p0);
passed &= (args.args_count == 0);
break;
case 4:
passed &= !rc;
passed &= (args.np == p1);
passed &= (args.args_count == 1);
passed &= (args.args[0] == 3);
break;
case 5:
passed &= !rc;
passed &= (args.np == p0);
passed &= (args.args_count == 0);
break;
case 6:
passed &= !rc;
passed &= (args.np == p2);
passed &= (args.args_count == 2);
passed &= (args.args[0] == 15);
passed &= (args.args[1] == 0x20);
break;
case 7:
passed &= (rc == -ENOENT);
break;
default:
passed = false;
}
unittest(passed, "index %i - data error on node %s rc=%i\n",
i, args.np->full_name, rc);
}
/* Check for missing list property */
rc = of_parse_phandle_with_args_map(np, "phandle-list-missing",
"phandle", 0, &args);
unittest(rc == -ENOENT, "expected:%i got:%i\n", -ENOENT, rc);
/* Check for missing cells,map,mask property */
rc = of_parse_phandle_with_args_map(np, "phandle-list",
"phandle-missing", 0, &args);
unittest(rc == -EINVAL, "expected:%i got:%i\n", -EINVAL, rc);
/* Check for bad phandle in list */
rc = of_parse_phandle_with_args_map(np, "phandle-list-bad-phandle",
"phandle", 0, &args);
unittest(rc == -EINVAL, "expected:%i got:%i\n", -EINVAL, rc);
/* Check for incorrectly formed argument list */
rc = of_parse_phandle_with_args_map(np, "phandle-list-bad-args",
"phandle", 1, &args);
unittest(rc == -EINVAL, "expected:%i got:%i\n", -EINVAL, rc);
}
static void __init of_unittest_property_string(void)
{
const char *strings[4];
@@ -564,42 +688,72 @@ static void __init of_unittest_property_copy(void)
static void __init of_unittest_changeset(void)
{
#ifdef CONFIG_OF_DYNAMIC
struct property *ppadd, padd = { .name = "prop-add", .length = 0, .value = "" };
struct property *ppadd, padd = { .name = "prop-add", .length = 1, .value = "" };
struct property *ppname_n1, pname_n1 = { .name = "name", .length = 3, .value = "n1" };
struct property *ppname_n2, pname_n2 = { .name = "name", .length = 3, .value = "n2" };
struct property *ppname_n21, pname_n21 = { .name = "name", .length = 3, .value = "n21" };
struct property *ppupdate, pupdate = { .name = "prop-update", .length = 5, .value = "abcd" };
struct property *ppremove;
struct device_node *n1, *n2, *n21, *nremove, *parent, *np;
struct device_node *n1, *n2, *n21, *nchangeset, *nremove, *parent, *np;
struct of_changeset chgset;
n1 = __of_node_dup(NULL, "/testcase-data/changeset/n1");
n1 = __of_node_dup(NULL, "n1");
unittest(n1, "testcase setup failure\n");
n2 = __of_node_dup(NULL, "/testcase-data/changeset/n2");
n2 = __of_node_dup(NULL, "n2");
unittest(n2, "testcase setup failure\n");
n21 = __of_node_dup(NULL, "%s/%s", "/testcase-data/changeset/n2", "n21");
n21 = __of_node_dup(NULL, "n21");
unittest(n21, "testcase setup failure %p\n", n21);
nremove = of_find_node_by_path("/testcase-data/changeset/node-remove");
nchangeset = of_find_node_by_path("/testcase-data/changeset");
nremove = of_get_child_by_name(nchangeset, "node-remove");
unittest(nremove, "testcase setup failure\n");
ppadd = __of_prop_dup(&padd, GFP_KERNEL);
unittest(ppadd, "testcase setup failure\n");
ppname_n1 = __of_prop_dup(&pname_n1, GFP_KERNEL);
unittest(ppname_n1, "testcase setup failure\n");
ppname_n2 = __of_prop_dup(&pname_n2, GFP_KERNEL);
unittest(ppname_n2, "testcase setup failure\n");
ppname_n21 = __of_prop_dup(&pname_n21, GFP_KERNEL);
unittest(ppname_n21, "testcase setup failure\n");
ppupdate = __of_prop_dup(&pupdate, GFP_KERNEL);
unittest(ppupdate, "testcase setup failure\n");
parent = nremove->parent;
parent = nchangeset;
n1->parent = parent;
n2->parent = parent;
n21->parent = n2;
n2->child = n21;
ppremove = of_find_property(parent, "prop-remove", NULL);
unittest(ppremove, "failed to find removal prop");
of_changeset_init(&chgset);
unittest(!of_changeset_attach_node(&chgset, n1), "fail attach n1\n");
unittest(!of_changeset_add_property(&chgset, n1, ppname_n1), "fail add prop name\n");
unittest(!of_changeset_attach_node(&chgset, n2), "fail attach n2\n");
unittest(!of_changeset_add_property(&chgset, n2, ppname_n2), "fail add prop name\n");
unittest(!of_changeset_detach_node(&chgset, nremove), "fail remove node\n");
unittest(!of_changeset_add_property(&chgset, n21, ppname_n21), "fail add prop name\n");
unittest(!of_changeset_attach_node(&chgset, n21), "fail attach n21\n");
unittest(!of_changeset_add_property(&chgset, parent, ppadd), "fail add prop\n");
unittest(!of_changeset_add_property(&chgset, parent, ppadd), "fail add prop prop-add\n");
unittest(!of_changeset_update_property(&chgset, parent, ppupdate), "fail update prop\n");
unittest(!of_changeset_remove_property(&chgset, parent, ppremove), "fail remove prop\n");
unittest(!of_changeset_apply(&chgset), "apply failed\n");
of_node_put(nchangeset);
/* Make sure node names are constructed correctly */
unittest((np = of_find_node_by_path("/testcase-data/changeset/n2/n21")),
"'%pOF' not added\n", n21);
@@ -1036,6 +1190,7 @@ static int __init unittest_data_add(void)
}
#ifdef CONFIG_OF_OVERLAY
static int __init overlay_data_apply(const char *overlay_name, int *overlay_id);
static int unittest_probe(struct platform_device *pdev)
{
@@ -1267,26 +1422,18 @@ static void of_unittest_destroy_tracked_overlays(void)
static int __init of_unittest_apply_overlay(int overlay_nr, int unittest_nr,
int *overlay_id)
{
struct device_node *np = NULL;
const char *overlay_name;
int ret;
overlay_name = overlay_name_from_nr(overlay_nr);
ret = overlay_data_apply(overlay_name, overlay_id);
if (!ret) {
if (!overlay_data_apply(overlay_name, overlay_id)) {
unittest(0, "could not apply overlay \"%s\"\n",
overlay_name);
goto out;
return -EFAULT;
}
of_unittest_track_overlay(*overlay_id);
ret = 0;
out:
of_node_put(np);
return ret;
return 0;
}
/* apply an overlay while checking before and after states */
@@ -1380,11 +1527,8 @@ static int __init of_unittest_apply_revert_overlay_check(int overlay_nr,
/* test activation of device */
static void __init of_unittest_overlay_0(void)
{
int ret;
/* device should enable */
ret = of_unittest_apply_overlay_check(0, 0, 0, 1, PDEV_OVERLAY);
if (ret != 0)
if (of_unittest_apply_overlay_check(0, 0, 0, 1, PDEV_OVERLAY))
return;
unittest(1, "overlay test %d passed\n", 0);
@@ -1393,11 +1537,8 @@ static void __init of_unittest_overlay_0(void)
/* test deactivation of device */
static void __init of_unittest_overlay_1(void)
{
int ret;
/* device should disable */
ret = of_unittest_apply_overlay_check(1, 1, 1, 0, PDEV_OVERLAY);
if (ret != 0)
if (of_unittest_apply_overlay_check(1, 1, 1, 0, PDEV_OVERLAY))
return;
unittest(1, "overlay test %d passed\n", 1);
@@ -1406,11 +1547,8 @@ static void __init of_unittest_overlay_1(void)
/* test activation of device */
static void __init of_unittest_overlay_2(void)
{
int ret;
/* device should enable */
ret = of_unittest_apply_overlay_check(2, 2, 0, 1, PDEV_OVERLAY);
if (ret != 0)
if (of_unittest_apply_overlay_check(2, 2, 0, 1, PDEV_OVERLAY))
return;
unittest(1, "overlay test %d passed\n", 2);
@@ -1419,11 +1557,8 @@ static void __init of_unittest_overlay_2(void)
/* test deactivation of device */
static void __init of_unittest_overlay_3(void)
{
int ret;
/* device should disable */
ret = of_unittest_apply_overlay_check(3, 3, 1, 0, PDEV_OVERLAY);
if (ret != 0)
if (of_unittest_apply_overlay_check(3, 3, 1, 0, PDEV_OVERLAY))
return;
unittest(1, "overlay test %d passed\n", 3);
@@ -1432,11 +1567,8 @@ static void __init of_unittest_overlay_3(void)
/* test activation of a full device node */
static void __init of_unittest_overlay_4(void)
{
int ret;
/* device should disable */
ret = of_unittest_apply_overlay_check(4, 4, 0, 1, PDEV_OVERLAY);
if (ret != 0)
if (of_unittest_apply_overlay_check(4, 4, 0, 1, PDEV_OVERLAY))
return;
unittest(1, "overlay test %d passed\n", 4);
@@ -1445,11 +1577,8 @@ static void __init of_unittest_overlay_4(void)
/* test overlay apply/revert sequence */
static void __init of_unittest_overlay_5(void)
{
int ret;
/* device should disable */
ret = of_unittest_apply_revert_overlay_check(5, 5, 0, 1, PDEV_OVERLAY);
if (ret != 0)
if (of_unittest_apply_revert_overlay_check(5, 5, 0, 1, PDEV_OVERLAY))
return;
unittest(1, "overlay test %d passed\n", 5);
@@ -1458,7 +1587,7 @@ static void __init of_unittest_overlay_5(void)
/* test overlay application in sequence */
static void __init of_unittest_overlay_6(void)
{
int ret, i, ov_id[2], ovcs_id;
int i, ov_id[2], ovcs_id;
int overlay_nr = 6, unittest_nr = 6;
int before = 0, after = 1;
const char *overlay_name;
@@ -1481,8 +1610,7 @@ static void __init of_unittest_overlay_6(void)
overlay_name = overlay_name_from_nr(overlay_nr + i);
ret = overlay_data_apply(overlay_name, &ovcs_id);
if (!ret) {
if (!overlay_data_apply(overlay_name, &ovcs_id)) {
unittest(0, "could not apply overlay \"%s\"\n",
overlay_name);
return;
@@ -1506,8 +1634,7 @@ static void __init of_unittest_overlay_6(void)
for (i = 1; i >= 0; i--) {
ovcs_id = ov_id[i];
ret = of_overlay_remove(&ovcs_id);
if (ret != 0) {
if (of_overlay_remove(&ovcs_id)) {
unittest(0, "%s failed destroy @\"%s\"\n",
overlay_name_from_nr(overlay_nr + i),
unittest_path(unittest_nr + i,
@@ -1536,7 +1663,7 @@ static void __init of_unittest_overlay_6(void)
/* test overlay application in sequence */
static void __init of_unittest_overlay_8(void)
{
int ret, i, ov_id[2], ovcs_id;
int i, ov_id[2], ovcs_id;
int overlay_nr = 8, unittest_nr = 8;
const char *overlay_name;
@@ -1547,8 +1674,7 @@ static void __init of_unittest_overlay_8(void)
overlay_name = overlay_name_from_nr(overlay_nr + i);
ret = overlay_data_apply(overlay_name, &ovcs_id);
if (ret < 0) {
if (!overlay_data_apply(overlay_name, &ovcs_id)) {
unittest(0, "could not apply overlay \"%s\"\n",
overlay_name);
return;
@@ -1559,8 +1685,7 @@ static void __init of_unittest_overlay_8(void)
/* now try to remove first overlay (it should fail) */
ovcs_id = ov_id[0];
ret = of_overlay_remove(&ovcs_id);
if (ret == 0) {
if (!of_overlay_remove(&ovcs_id)) {
unittest(0, "%s was destroyed @\"%s\"\n",
overlay_name_from_nr(overlay_nr + 0),
unittest_path(unittest_nr,
@@ -1571,8 +1696,7 @@ static void __init of_unittest_overlay_8(void)
/* removing them in order should work */
for (i = 1; i >= 0; i--) {
ovcs_id = ov_id[i];
ret = of_overlay_remove(&ovcs_id);
if (ret != 0) {
if (of_overlay_remove(&ovcs_id)) {
unittest(0, "%s not destroyed @\"%s\"\n",
overlay_name_from_nr(overlay_nr + i),
unittest_path(unittest_nr,
@@ -1604,8 +1728,8 @@ static void __init of_unittest_overlay_10(void)
ret = of_path_device_type_exists(child_path, PDEV_OVERLAY);
kfree(child_path);
if (unittest(ret, "overlay test %d failed; no child device\n", 10))
return;
unittest(ret, "overlay test %d failed; no child device\n", 10);
}
/* test insertion of a bus with parent devices (and revert) */
@@ -1616,9 +1740,7 @@ static void __init of_unittest_overlay_11(void)
/* device should disable */
ret = of_unittest_apply_revert_overlay_check(11, 11, 0, 1,
PDEV_OVERLAY);
if (unittest(ret == 0,
"overlay test %d failed; overlay application\n", 11))
return;
unittest(ret == 0, "overlay test %d failed; overlay apply\n", 11);
}
#if IS_BUILTIN(CONFIG_I2C) && IS_ENABLED(CONFIG_OF_OVERLAY)
@@ -1769,7 +1891,7 @@ static int unittest_i2c_mux_select_chan(struct i2c_mux_core *muxc, u32 chan)
static int unittest_i2c_mux_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
int ret, i, nchans;
int i, nchans;
struct device *dev = &client->dev;
struct i2c_adapter *adap = to_i2c_adapter(dev->parent);
struct device_node *np = client->dev.of_node, *child;
@@ -1785,8 +1907,7 @@ static int unittest_i2c_mux_probe(struct i2c_client *client,
max_reg = (u32)-1;
for_each_child_of_node(np, child) {
ret = of_property_read_u32(child, "reg", &reg);
if (ret)
if (of_property_read_u32(child, "reg", &reg))
continue;
if (max_reg == (u32)-1 || reg > max_reg)
max_reg = reg;
@@ -1802,8 +1923,7 @@ static int unittest_i2c_mux_probe(struct i2c_client *client,
if (!muxc)
return -ENOMEM;
for (i = 0; i < nchans; i++) {
ret = i2c_mux_add_adapter(muxc, 0, i, 0);
if (ret) {
if (i2c_mux_add_adapter(muxc, 0, i, 0)) {
dev_err(dev, "Failed to register mux #%d\n", i);
i2c_mux_del_adapters(muxc);
return -ENODEV;
@@ -1877,11 +1997,8 @@ static void of_unittest_overlay_i2c_cleanup(void)
static void __init of_unittest_overlay_i2c_12(void)
{
int ret;
/* device should enable */
ret = of_unittest_apply_overlay_check(12, 12, 0, 1, I2C_OVERLAY);
if (ret != 0)
if (of_unittest_apply_overlay_check(12, 12, 0, 1, I2C_OVERLAY))
return;
unittest(1, "overlay test %d passed\n", 12);
@@ -1890,11 +2007,8 @@ static void __init of_unittest_overlay_i2c_12(void)
/* test deactivation of device */
static void __init of_unittest_overlay_i2c_13(void)
{
int ret;
/* device should disable */
ret = of_unittest_apply_overlay_check(13, 13, 1, 0, I2C_OVERLAY);
if (ret != 0)
if (of_unittest_apply_overlay_check(13, 13, 1, 0, I2C_OVERLAY))
return;
unittest(1, "overlay test %d passed\n", 13);
@@ -1907,11 +2021,8 @@ static void of_unittest_overlay_i2c_14(void)
static void __init of_unittest_overlay_i2c_15(void)
{
int ret;
/* device should enable */
ret = of_unittest_apply_overlay_check(15, 15, 0, 1, I2C_OVERLAY);
if (ret != 0)
if (of_unittest_apply_overlay_check(15, 15, 0, 1, I2C_OVERLAY))
return;
unittest(1, "overlay test %d passed\n", 15);
@@ -1927,10 +2038,8 @@ static inline void of_unittest_overlay_i2c_15(void) { }
static void __init of_unittest_overlay(void)
{
struct device_node *bus_np = NULL;
int ret;
ret = platform_driver_register(&unittest_driver);
if (ret != 0) {
if (platform_driver_register(&unittest_driver)) {
unittest(0, "could not register unittest driver\n");
goto out;
}
@@ -1941,8 +2050,7 @@ static void __init of_unittest_overlay(void)
goto out;
}
ret = of_platform_default_populate(bus_np, NULL, NULL);
if (ret != 0) {
if (of_platform_default_populate(bus_np, NULL, NULL)) {
unittest(0, "could not populate bus @ \"%s\"\n", bus_path);
goto out;
}
@@ -2156,10 +2264,8 @@ static int __init overlay_data_apply(const char *overlay_name, int *overlay_id)
}
size = info->dtb_end - info->dtb_begin;
if (!size) {
if (!size)
pr_err("no overlay data for %s\n", overlay_name);
ret = 0;
}
ret = of_overlay_fdt_apply(info->dtb_begin, size, &info->overlay_id);
if (overlay_id)
@@ -2193,7 +2299,6 @@ static __init void of_unittest_overlay_high_level(void)
struct device_node *overlay_base_symbols;
struct device_node **pprev;
struct property *prop;
int ret;
if (!overlay_base_root) {
unittest(0, "overlay_base_root not initialized\n");
@@ -2284,19 +2389,15 @@ static __init void of_unittest_overlay_high_level(void)
prop->name);
goto err_unlock;
}
ret = __of_add_property(of_symbols, new_prop);
if (ret) {
if (!strcmp(new_prop->name, "name")) {
/* auto-generated by unflatten */
ret = 0;
if (__of_add_property(of_symbols, new_prop)) {
/* "name" auto-generated by unflatten */
if (!strcmp(new_prop->name, "name"))
continue;
}
unittest(0, "duplicate property '%s' in overlay_base node __symbols__",
prop->name);
goto err_unlock;
}
ret = __of_add_property_sysfs(of_symbols, new_prop);
if (ret) {
if (__of_add_property_sysfs(of_symbols, new_prop)) {
unittest(0, "unable to add property '%s' in overlay_base node __symbols__ to sysfs",
prop->name);
goto err_unlock;
@@ -2355,6 +2456,7 @@ static int __init of_unittest(void)
of_unittest_find_node_by_name();
of_unittest_dynamic();
of_unittest_parse_phandle_with_args();
of_unittest_parse_phandle_with_args_map();
of_unittest_printf();
of_unittest_property_string();
of_unittest_property_copy();