diff options
Diffstat (limited to 'drivers/of/selftest.c')
| -rw-r--r-- | drivers/of/selftest.c | 139 | 
1 files changed, 139 insertions, 0 deletions
diff --git a/drivers/of/selftest.c b/drivers/of/selftest.c new file mode 100644 index 00000000000..9d2b4803a9d --- /dev/null +++ b/drivers/of/selftest.c @@ -0,0 +1,139 @@ +/* + * Self tests for device tree subsystem + */ + +#define pr_fmt(fmt) "### %s(): " fmt, __func__ + +#include <linux/clk.h> +#include <linux/err.h> +#include <linux/errno.h> +#include <linux/module.h> +#include <linux/of.h> +#include <linux/list.h> +#include <linux/mutex.h> +#include <linux/slab.h> +#include <linux/device.h> + +static bool selftest_passed = true; +#define selftest(result, fmt, ...) { \ +	selftest_passed &= (result); \ +	if (!(result)) \ +		pr_err("FAIL %s:%i " fmt, __FILE__, __LINE__, ##__VA_ARGS__); \ +} + +static void __init of_selftest_parse_phandle_with_args(void) +{ +	struct device_node *np; +	struct of_phandle_args args; +	int rc, i; +	bool passed_all = true; + +	pr_info("start\n"); +	np = of_find_node_by_path("/testcase-data/phandle-tests/consumer-a"); +	if (!np) { +		pr_err("missing testcase data\n"); +		return; +	} + +	for (i = 0; i < 7; i++) { +		bool passed = true; +		rc = of_parse_phandle_with_args(np, "phandle-list", +						"#phandle-cells", i, &args); + +		/* Test the values from tests-phandle.dtsi */ +		switch (i) { +		case 0: +			passed &= !rc; +			passed &= (args.args_count == 1); +			passed &= (args.args[0] == (i + 1)); +			break; +		case 1: +			passed &= !rc; +			passed &= (args.args_count == 2); +			passed &= (args.args[0] == (i + 1)); +			passed &= (args.args[1] == 0); +			break; +		case 2: +			passed &= (rc == -ENOENT); +			break; +		case 3: +			passed &= !rc; +			passed &= (args.args_count == 3); +			passed &= (args.args[0] == (i + 1)); +			passed &= (args.args[1] == 4); +			passed &= (args.args[2] == 3); +			break; +		case 4: +			passed &= !rc; +			passed &= (args.args_count == 2); +			passed &= (args.args[0] == (i + 1)); +			passed &= (args.args[1] == 100); +			break; +		case 5: +			passed &= !rc; +			passed &= (args.args_count == 0); +			break; +		case 6: +			passed &= !rc; +			passed &= (args.args_count == 1); +			passed &= (args.args[0] == (i + 1)); +			break; +		case 7: +			passed &= (rc == -EINVAL); +			break; +		default: +			passed = false; +		} + +		if (!passed) { +			int j; +			pr_err("index %i - data error on node %s rc=%i regs=[", +				i, args.np->full_name, rc); +			for (j = 0; j < args.args_count; j++) +				printk(" %i", args.args[j]); +			printk(" ]\n"); + +			passed_all = false; +		} +	} + +	/* Check for missing list property */ +	rc = of_parse_phandle_with_args(np, "phandle-list-missing", +					"#phandle-cells", 0, &args); +	passed_all &= (rc == -EINVAL); + +	/* Check for missing cells property */ +	rc = of_parse_phandle_with_args(np, "phandle-list", +					"#phandle-cells-missing", 0, &args); +	passed_all &= (rc == -EINVAL); + +	/* Check for bad phandle in list */ +	rc = of_parse_phandle_with_args(np, "phandle-list-bad-phandle", +					"#phandle-cells", 0, &args); +	passed_all &= (rc == -EINVAL); + +	/* Check for incorrectly formed argument list */ +	rc = of_parse_phandle_with_args(np, "phandle-list-bad-args", +					"#phandle-cells", 1, &args); +	passed_all &= (rc == -EINVAL); + +	pr_info("end - %s\n", passed_all ? "PASS" : "FAIL"); +} + +static int __init of_selftest(void) +{ +	struct device_node *np; + +	np = of_find_node_by_path("/testcase-data/phandle-tests/consumer-a"); +	if (!np) { +		pr_info("No testcase data in device tree; not running tests\n"); +		return 0; +	} +	of_node_put(np); + +	pr_info("start of selftest - you will see error messages\n"); +	of_selftest_parse_phandle_with_args(); +	pr_info("end of selftest - %s\n", selftest_passed ? "PASS" : "FAIL"); +	return 0; +} +late_initcall(of_selftest);  |