All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/2] fdtget: Split out cell list display into a new function
@ 2017-08-20 12:28 Simon Glass
       [not found] ` <20170820122855.171271-1-sjg-F7+t8E8rja9g9hUCZPvPmw@public.gmane.org>
  0 siblings, 1 reply; 4+ messages in thread
From: Simon Glass @ 2017-08-20 12:28 UTC (permalink / raw)
  To: Devicetree Compiler; +Cc: Jason Clinton, David Gibson, Simon Glass

The show_data() function is quite long. Split out the part that loops
through the values. This makes it easier to add new features.

Signed-off-by: Simon Glass <sjg-F7+t8E8rja9g9hUCZPvPmw@public.gmane.org>
---

 fdtget.c | 49 ++++++++++++++++++++++++++++++++++---------------
 1 file changed, 34 insertions(+), 15 deletions(-)

diff --git a/fdtget.c b/fdtget.c
index 39f1742..6cc5242 100644
--- a/fdtget.c
+++ b/fdtget.c
@@ -53,6 +53,37 @@ static void report_error(const char *where, int err)
 	fprintf(stderr, "Error at '%s': %s\n", where, fdt_strerror(err));
 }
 
+/**
+ * Shows a list of cells in the requested format
+ *
+ * @param disp		Display information / options
+ * @param data		Data to display
+ * @param len		Maximum length of buffer
+ * @param size		Data size to use for display (e.g. 4 for 32-bit)
+ * @return 0 if ok, -1 on error
+ */
+static int show_cell_list(struct display_info *disp, const char *data, int len,
+			  int size)
+{
+	const uint8_t *p = (const uint8_t *)data;
+	char fmt[3];
+	int value;
+	int i;
+
+	fmt[0] = '%';
+	fmt[1] = disp->type ? disp->type : 'd';
+	fmt[2] = '\0';
+	for (i = 0; i < len; i += size, p += size) {
+		if (i)
+			printf(" ");
+		value = size == 4 ? fdt32_to_cpu(*(const fdt32_t *)p) :
+			size == 2 ? (*p << 8) | p[1] : *p;
+		printf(fmt, value);
+	}
+
+	return 0;
+}
+
 /**
  * Displays data of a given length according to selected options
  *
@@ -66,12 +97,9 @@ static void report_error(const char *where, int err)
  */
 static int show_data(struct display_info *disp, const char *data, int len)
 {
-	int i, size;
-	const uint8_t *p = (const uint8_t *)data;
+	int size;
 	const char *s;
-	int value;
 	int is_string;
-	char fmt[3];
 
 	/* no data, don't print */
 	if (len == 0)
@@ -99,17 +127,8 @@ static int show_data(struct display_info *disp, const char *data, int len)
 				"selected data size\n");
 		return -1;
 	}
-	fmt[0] = '%';
-	fmt[1] = disp->type ? disp->type : 'd';
-	fmt[2] = '\0';
-	for (i = 0; i < len; i += size, p += size) {
-		if (i)
-			printf(" ");
-		value = size == 4 ? fdt32_to_cpu(*(const fdt32_t *)p) :
-			size == 2 ? (*p << 8) | p[1] : *p;
-		printf(fmt, value);
-	}
-	return 0;
+
+	return show_cell_list(disp, data, len, size);
 }
 
 /**
-- 
2.14.1.480.gb18f417b89-goog

^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH 2/2] fdtget: Support following phandles
       [not found] ` <20170820122855.171271-1-sjg-F7+t8E8rja9g9hUCZPvPmw@public.gmane.org>
@ 2017-08-20 12:28   ` Simon Glass
       [not found]     ` <20170820122855.171271-2-sjg-F7+t8E8rja9g9hUCZPvPmw@public.gmane.org>
  2017-08-21  0:29   ` [PATCH 1/2] fdtget: Split out cell list display into a new function David Gibson
  1 sibling, 1 reply; 4+ messages in thread
From: Simon Glass @ 2017-08-20 12:28 UTC (permalink / raw)
  To: Devicetree Compiler; +Cc: Jason Clinton, David Gibson, Simon Glass

Currently nodes with phandles just print out as plain integer values, e.g.

   $ fdtget firefly-rk3288/u-boot.dtb /gpio-keys/button@0 gpios
   112 5 1

It is useful to be able to follow these phandles and print them out in a
properly formatted way, e.g.

   $ fdtget firefly-rk3288/u-boot.dtb -f -c gpio /gpio-keys/button@0 gpios
   /pinctrl/gpio0@ff750000 5 1

Add a -f option to follow phandles. For those which require arguments, add
a -c option to specify the name of the '#xxx-cells' property in the target
node.

Signed-off-by: Simon Glass <sjg-F7+t8E8rja9g9hUCZPvPmw@public.gmane.org>
---

 fdtget.c           | 115 +++++++++++++++++++++++++++++++++++++++++++++++++----
 tests/label01.dts  |  30 ++++++++++++++
 tests/run_tests.sh |  18 +++++++++
 3 files changed, 156 insertions(+), 7 deletions(-)

diff --git a/fdtget.c b/fdtget.c
index 6cc5242..6d7c6af 100644
--- a/fdtget.c
+++ b/fdtget.c
@@ -46,6 +46,10 @@ struct display_info {
 	int size;		/* data size (1/2/4) */
 	enum display_mode mode;	/* display mode that we are using */
 	const char *default_val; /* default value if node/property not found */
+
+	int follow;		/* follow phandle links */
+	/* property which defines the number of parameter cells for a phandle */
+	char *phandle_cells;
 };
 
 static void report_error(const char *where, int err)
@@ -53,6 +57,59 @@ static void report_error(const char *where, int err)
 	fprintf(stderr, "Error at '%s': %s\n", where, fdt_strerror(err));
 }
 
+/**
+ * Shows the target node of a phandle
+ *
+ * @param disp		Display information / options
+ * @param value		Phandle value to look up
+ * @param blob		Device tree blob (for looking up phandles)
+ * @return number of arguments expected, or -1 on error
+ */
+static int show_phandle_target(struct display_info *disp, int value,
+			       const char *blob)
+{
+	const void *cells_prop;
+	int phandle_args = 0;
+	int cells_size;
+	char buf[256];
+	int target;
+	int ret;
+
+	target = fdt_node_offset_by_phandle(blob, value);
+	if (target < 0) {
+		printf("invalid_%d", value);
+		return -1;
+	}
+
+	if (disp->phandle_cells) {
+		cells_prop = fdt_getprop(blob, target, disp->phandle_cells,
+					 &cells_size);
+		if (!cells_prop) {
+			fprintf(stderr, "Expected node '%s' to have property "
+				"'%s' but it is missing\n",
+				fdt_get_name(blob, target, NULL),
+				disp->phandle_cells);
+			return -1;
+		}
+		if (cells_size != 4) {
+			fprintf(stderr, "Expected node '%s' property '%s' size "
+				"to be 4, but it is %d\n",
+				fdt_get_name(blob, target, NULL),
+				disp->phandle_cells, cells_size);
+			return -1;
+		}
+		phandle_args = fdt32_to_cpu(*(const fdt32_t *)cells_prop);
+	}
+	ret = fdt_get_path(blob, target, buf, sizeof(buf));
+	if (ret < 0) {
+		report_error("Could not get full path", ret);
+		return -1;
+	}
+	printf("%s", buf);
+
+	return phandle_args;
+}
+
 /**
  * Shows a list of cells in the requested format
  *
@@ -60,12 +117,15 @@ static void report_error(const char *where, int err)
  * @param data		Data to display
  * @param len		Maximum length of buffer
  * @param size		Data size to use for display (e.g. 4 for 32-bit)
+ * @param blob		Device tree blob (for looking up phandles)
  * @return 0 if ok, -1 on error
  */
 static int show_cell_list(struct display_info *disp, const char *data, int len,
-			  int size)
+			  int size, const void *blob)
 {
 	const uint8_t *p = (const uint8_t *)data;
+	int phandle_start = 0; /* expecting a phandle pointer next */
+	int phandle_args = 0; /* numnber of phandle args left to process */
 	char fmt[3];
 	int value;
 	int i;
@@ -73,12 +133,33 @@ static int show_cell_list(struct display_info *disp, const char *data, int len,
 	fmt[0] = '%';
 	fmt[1] = disp->type ? disp->type : 'd';
 	fmt[2] = '\0';
+	if (disp->follow) {
+		if (size != 4) {
+			fprintf(stderr, "Following phandles requires an output "
+				"size of 4 bytes\n");
+			return -1;
+		}
+		phandle_start = 1;
+	}
 	for (i = 0; i < len; i += size, p += size) {
 		if (i)
 			printf(" ");
 		value = size == 4 ? fdt32_to_cpu(*(const fdt32_t *)p) :
 			size == 2 ? (*p << 8) | p[1] : *p;
-		printf(fmt, value);
+		if (phandle_start && phandle_args <= 0) {
+			phandle_args = show_phandle_target(disp, value, blob);
+			if (phandle_args < 0)
+				return phandle_args;
+		} else {
+			printf(fmt, value);
+			if (phandle_args > 0)
+				phandle_args--;
+		}
+	}
+	if (phandle_args > 0) {
+		fprintf(stderr, "Not enough data: %d more arg(s) expected",
+			phandle_args);
+		return -1;
 	}
 
 	return 0;
@@ -93,9 +174,11 @@ static int show_cell_list(struct display_info *disp, const char *data, int len,
  * @param disp		Display information / options
  * @param data		Data to display
  * @param len		Maximum length of buffer
- * @return 0 if ok, -1 if data does not match format
+ * @param blob		Device tree blob (for looking up phandles)
+ * @return 0 if ok, -1 on error
  */
-static int show_data(struct display_info *disp, const char *data, int len)
+static int show_data(struct display_info *disp, const char *data, int len,
+		     const void *blob)
 {
 	int size;
 	const char *s;
@@ -128,7 +211,7 @@ static int show_data(struct display_info *disp, const char *data, int len)
 		return -1;
 	}
 
-	return show_cell_list(disp, data, len, size);
+	return show_cell_list(disp, data, len, size, blob);
 }
 
 /**
@@ -241,7 +324,7 @@ static int show_data_for_item(const void *blob, struct display_info *disp,
 		assert(property);
 		value = fdt_getprop(blob, node, property, &len);
 		if (value) {
-			if (show_data(disp, value, len))
+			if (show_data(disp, value, len, blob))
 				err = -1;
 			else
 				printf("\n");
@@ -310,12 +393,14 @@ static const char usage_synopsis[] =
 	"\n"
 	"Each value is printed on a new line.\n"
 	USAGE_TYPE_MSG;
-static const char usage_short_opts[] = "t:pld:" USAGE_COMMON_SHORT_OPTS;
+static const char usage_short_opts[] = "t:pld:fc:" USAGE_COMMON_SHORT_OPTS;
 static struct option const usage_long_opts[] = {
 	{"type",              a_argument, NULL, 't'},
 	{"properties",       no_argument, NULL, 'p'},
 	{"list",             no_argument, NULL, 'l'},
 	{"default",           a_argument, NULL, 'd'},
+	{"follow",           no_argument, NULL, 'f'},
+	{"cells",             a_argument, NULL, 'c'},
 	USAGE_COMMON_LONG_OPTS,
 };
 static const char * const usage_opts_help[] = {
@@ -323,6 +408,8 @@ static const char * const usage_opts_help[] = {
 	"List properties for each node",
 	"List subnodes for each node",
 	"Default value to display when the property is missing",
+	"Print phandle targets and (with -c) args",
+	"Cells property in phandle target (e.g. 'gpio' for '#gpio-cells') ",
 	USAGE_COMMON_OPTS_HELP
 };
 
@@ -360,6 +447,20 @@ int main(int argc, char *argv[])
 		case 'd':
 			disp.default_val = optarg;
 			break;
+
+		case 'f':
+			disp.follow = 1;
+			break;
+
+		case 'c':
+			disp.phandle_cells = malloc(strlen(optarg) +
+						    strlen("#-cells"));
+			if (!disp.phandle_cells) {
+				fprintf(stderr, "Out of memory\n");
+				return 1;
+			}
+			sprintf(disp.phandle_cells, "#%s-cells", optarg);
+			break;
 		}
 	}
 
diff --git a/tests/label01.dts b/tests/label01.dts
index a895803..020e27d 100644
--- a/tests/label01.dts
+++ b/tests/label01.dts
@@ -59,5 +59,35 @@ memrsv2: /memreserve/ 0x2000000000000000 0x0100000000000000;
 		linux,platform = <0x600>;
 	};
 
+	phandle-test {
+		first = <&target_a 10 20>;
+		both = <&target_a 30 40 &target_b 50 &target_a 60 70>;
+		third = <&target_c &target_c>;
+		all = <&target_a 30 40 &target_b 50 &target_c &target_a 60 70>;
+		too-few-args = <&target_a 80>;
+		invalid-size = [01];
+		invalid-target = <&target_d>;
+	};
+
+	target_a: target@0 {
+		reg = <0 0 0 0>;
+		#gpio-cells = <2>;
+	};
+
+	target_b: target@1 {
+		reg = <1 0 0 0>;
+		#gpio-cells = <1>;
+	};
+
+	target_c: target@2 {
+		reg = <2 0 0 0>;
+		#gpio-cells = <0>;
+	};
+
+	target_d: target@3 {
+		reg = <3 0 0 0>;
+		#gpio-cells = [01];	/* invalid cell value */
+	};
+
 };
 
diff --git a/tests/run_tests.sh b/tests/run_tests.sh
index 3bc5b41..6272675 100755
--- a/tests/run_tests.sh
+++ b/tests/run_tests.sh
@@ -692,6 +692,24 @@ fdtget_tests () {
     run_fdtget_test "<the dead silence>" -tx \
 	-d "<the dead silence>" $dtb /randomnode doctor-who
     run_fdtget_test "<blink>" -tx -d "<blink>" $dtb /memory doctor-who
+
+    # Test following of phandles
+    run_fdtget_test "/target@0 10 20" -f -c "gpio" $dtb /phandle-test first
+    run_fdtget_test "/target@0 30 40 /target@1 50 /target@0 60 70" \
+	-f -c "gpio" $dtb /phandle-test both
+    run_fdtget_test "/target@2 /target@2" -f -c "gpio" $dtb /phandle-test third
+    run_fdtget_test "/target@0 30 40 /target@1 50 /target@2 /target@0 60 70" \
+	-f -c "gpio" $dtb /phandle-test all
+
+    # Without the -c parameter we cannot decode some phandles.
+    run_wrap_error_test $DTGET -f $dtb /phandle-test first
+    run_wrap_error_test $DTGET -f $dtb /phandle-test both
+    run_wrap_error_test $DTGET -f $dtb /phandle-test all
+    run_wrap_error_test $DTGET -f -c wrong $dtb /phandle-test all
+
+    run_wrap_error_test $DTGET -f -c gpio $dtb /phandle-test too-few-args
+    run_wrap_error_test $DTGET -f -c gpio $dtb /phandle-test invalid-size
+    run_wrap_error_test $DTGET -f -c gpio $dtb /phandle-test invalid-target
 }
 
 fdtput_tests () {
-- 
2.14.1.480.gb18f417b89-goog

^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH 1/2] fdtget: Split out cell list display into a new function
       [not found] ` <20170820122855.171271-1-sjg-F7+t8E8rja9g9hUCZPvPmw@public.gmane.org>
  2017-08-20 12:28   ` [PATCH 2/2] fdtget: Support following phandles Simon Glass
@ 2017-08-21  0:29   ` David Gibson
  1 sibling, 0 replies; 4+ messages in thread
From: David Gibson @ 2017-08-21  0:29 UTC (permalink / raw)
  To: Simon Glass; +Cc: Devicetree Compiler, Jason Clinton

[-- Attachment #1: Type: text/plain, Size: 496 bytes --]

On Sun, Aug 20, 2017 at 06:28:54AM -0600, Simon Glass wrote:
> The show_data() function is quite long. Split out the part that loops
> through the values. This makes it easier to add new features.
> 
> Signed-off-by: Simon Glass <sjg-F7+t8E8rja9g9hUCZPvPmw@public.gmane.org>

Applied, thanks.

-- 
David Gibson			| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
				| _way_ _around_!
http://www.ozlabs.org/~dgibson

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH 2/2] fdtget: Support following phandles
       [not found]     ` <20170820122855.171271-2-sjg-F7+t8E8rja9g9hUCZPvPmw@public.gmane.org>
@ 2017-08-23  5:47       ` David Gibson
  0 siblings, 0 replies; 4+ messages in thread
From: David Gibson @ 2017-08-23  5:47 UTC (permalink / raw)
  To: Simon Glass; +Cc: Devicetree Compiler, Jason Clinton

[-- Attachment #1: Type: text/plain, Size: 11514 bytes --]

On Sun, Aug 20, 2017 at 06:28:55AM -0600, Simon Glass wrote:
> Currently nodes with phandles just print out as plain integer values, e.g.
> 
>    $ fdtget firefly-rk3288/u-boot.dtb /gpio-keys/button@0 gpios
>    112 5 1
> 
> It is useful to be able to follow these phandles and print them out in a
> properly formatted way, e.g.

So, I don't think "follow" is the right word here (and throughout).
To me "follow" implies displaying information from the target of the
phandle, rather than the phandle itself.  This is about decoding the
phandle to display in a more readable fashion, but we are still
basically displaying the phandle.

>    $ fdtget firefly-rk3288/u-boot.dtb -f -c gpio /gpio-keys/button@0 gpios
>    /pinctrl/gpio0@ff750000 5 1
> 
> Add a -f option to follow phandles. For those which require arguments, add
> a -c option to specify the name of the '#xxx-cells' property in the target
> node.

AFAICT this is substantially less general than the commit message and
help text suggest.  It specifically decodes properties of the form
	<phandle> <n cells of stuff> <phandle> <m cells of stuff>

Where the n & m are determined by a single #*-cells property in the
phandle target.  That's a fairly common property format, but it's
certainly not the only place phandles can appear.  It will also handle
the case of a simple array of phandles, though that requires a bit of
thinking to work through.

It won't work with something like interrupt-map for example, and
obviously in general there's no way to automatically detect phandles.

Having an option to interpret a particular property format is fine of
course, but it shouldn't advertise as doing more than it can.

> Signed-off-by: Simon Glass <sjg-F7+t8E8rja9g9hUCZPvPmw@public.gmane.org>
> ---
> 
>  fdtget.c           | 115 +++++++++++++++++++++++++++++++++++++++++++++++++----
>  tests/label01.dts  |  30 ++++++++++++++
>  tests/run_tests.sh |  18 +++++++++
>  3 files changed, 156 insertions(+), 7 deletions(-)
> 
> diff --git a/fdtget.c b/fdtget.c
> index 6cc5242..6d7c6af 100644
> --- a/fdtget.c
> +++ b/fdtget.c
> @@ -46,6 +46,10 @@ struct display_info {
>  	int size;		/* data size (1/2/4) */
>  	enum display_mode mode;	/* display mode that we are using */
>  	const char *default_val; /* default value if node/property not found */
> +
> +	int follow;		/* follow phandle links */
> +	/* property which defines the number of parameter cells for a phandle */
> +	char *phandle_cells;
>  };
>  
>  static void report_error(const char *where, int err)
> @@ -53,6 +57,59 @@ static void report_error(const char *where, int err)
>  	fprintf(stderr, "Error at '%s': %s\n", where, fdt_strerror(err));
>  }
>  
> +/**
> + * Shows the target node of a phandle
> + *
> + * @param disp		Display information / options
> + * @param value		Phandle value to look up
> + * @param blob		Device tree blob (for looking up phandles)
> + * @return number of arguments expected, or -1 on error
> + */
> +static int show_phandle_target(struct display_info *disp, int value,
> +			       const char *blob)
> +{
> +	const void *cells_prop;
> +	int phandle_args = 0;
> +	int cells_size;
> +	char buf[256];
> +	int target;
> +	int ret;
> +
> +	target = fdt_node_offset_by_phandle(blob, value);
> +	if (target < 0) {
> +		printf("invalid_%d", value);
> +		return -1;
> +	}
> +
> +	if (disp->phandle_cells) {
> +		cells_prop = fdt_getprop(blob, target, disp->phandle_cells,
> +					 &cells_size);
> +		if (!cells_prop) {
> +			fprintf(stderr, "Expected node '%s' to have property "
> +				"'%s' but it is missing\n",
> +				fdt_get_name(blob, target, NULL),
> +				disp->phandle_cells);
> +			return -1;
> +		}
> +		if (cells_size != 4) {
> +			fprintf(stderr, "Expected node '%s' property '%s' size "
> +				"to be 4, but it is %d\n",
> +				fdt_get_name(blob, target, NULL),
> +				disp->phandle_cells, cells_size);
> +			return -1;
> +		}
> +		phandle_args = fdt32_to_cpu(*(const fdt32_t *)cells_prop);
> +	}
> +	ret = fdt_get_path(blob, target, buf, sizeof(buf));
> +	if (ret < 0) {
> +		report_error("Could not get full path", ret);
> +		return -1;
> +	}
> +	printf("%s", buf);
> +
> +	return phandle_args;
> +}
> +
>  /**
>   * Shows a list of cells in the requested format
>   *
> @@ -60,12 +117,15 @@ static void report_error(const char *where, int err)
>   * @param data		Data to display
>   * @param len		Maximum length of buffer
>   * @param size		Data size to use for display (e.g. 4 for 32-bit)
> + * @param blob		Device tree blob (for looking up phandles)
>   * @return 0 if ok, -1 on error
>   */
>  static int show_cell_list(struct display_info *disp, const char *data, int len,
> -			  int size)
> +			  int size, const void *blob)
>  {
>  	const uint8_t *p = (const uint8_t *)data;
> +	int phandle_start = 0; /* expecting a phandle pointer next */
> +	int phandle_args = 0; /* numnber of phandle args left to process */
>  	char fmt[3];
>  	int value;
>  	int i;
> @@ -73,12 +133,33 @@ static int show_cell_list(struct display_info *disp, const char *data, int len,
>  	fmt[0] = '%';
>  	fmt[1] = disp->type ? disp->type : 'd';
>  	fmt[2] = '\0';
> +	if (disp->follow) {
> +		if (size != 4) {
> +			fprintf(stderr, "Following phandles requires an output "
> +				"size of 4 bytes\n");
> +			return -1;
> +		}
> +		phandle_start = 1;
> +	}
>  	for (i = 0; i < len; i += size, p += size) {
>  		if (i)
>  			printf(" ");
>  		value = size == 4 ? fdt32_to_cpu(*(const fdt32_t *)p) :
>  			size == 2 ? (*p << 8) | p[1] : *p;
> -		printf(fmt, value);
> +		if (phandle_start && phandle_args <= 0) {
> +			phandle_args = show_phandle_target(disp, value, blob);
> +			if (phandle_args < 0)
> +				return phandle_args;
> +		} else {
> +			printf(fmt, value);
> +			if (phandle_args > 0)
> +				phandle_args--;
> +		}
> +	}
> +	if (phandle_args > 0) {
> +		fprintf(stderr, "Not enough data: %d more arg(s) expected",
> +			phandle_args);
> +		return -1;
>  	}
>  
>  	return 0;
> @@ -93,9 +174,11 @@ static int show_cell_list(struct display_info *disp, const char *data, int len,
>   * @param disp		Display information / options
>   * @param data		Data to display
>   * @param len		Maximum length of buffer
> - * @return 0 if ok, -1 if data does not match format
> + * @param blob		Device tree blob (for looking up phandles)
> + * @return 0 if ok, -1 on error
>   */
> -static int show_data(struct display_info *disp, const char *data, int len)
> +static int show_data(struct display_info *disp, const char *data, int len,
> +		     const void *blob)
>  {
>  	int size;
>  	const char *s;
> @@ -128,7 +211,7 @@ static int show_data(struct display_info *disp, const char *data, int len)
>  		return -1;
>  	}
>  
> -	return show_cell_list(disp, data, len, size);
> +	return show_cell_list(disp, data, len, size, blob);
>  }
>  
>  /**
> @@ -241,7 +324,7 @@ static int show_data_for_item(const void *blob, struct display_info *disp,
>  		assert(property);
>  		value = fdt_getprop(blob, node, property, &len);
>  		if (value) {
> -			if (show_data(disp, value, len))
> +			if (show_data(disp, value, len, blob))
>  				err = -1;
>  			else
>  				printf("\n");
> @@ -310,12 +393,14 @@ static const char usage_synopsis[] =
>  	"\n"
>  	"Each value is printed on a new line.\n"
>  	USAGE_TYPE_MSG;
> -static const char usage_short_opts[] = "t:pld:" USAGE_COMMON_SHORT_OPTS;
> +static const char usage_short_opts[] = "t:pld:fc:" USAGE_COMMON_SHORT_OPTS;
>  static struct option const usage_long_opts[] = {
>  	{"type",              a_argument, NULL, 't'},
>  	{"properties",       no_argument, NULL, 'p'},
>  	{"list",             no_argument, NULL, 'l'},
>  	{"default",           a_argument, NULL, 'd'},
> +	{"follow",           no_argument, NULL, 'f'},
> +	{"cells",             a_argument, NULL, 'c'},
>  	USAGE_COMMON_LONG_OPTS,
>  };
>  static const char * const usage_opts_help[] = {
> @@ -323,6 +408,8 @@ static const char * const usage_opts_help[] = {
>  	"List properties for each node",
>  	"List subnodes for each node",
>  	"Default value to display when the property is missing",
> +	"Print phandle targets and (with -c) args",
> +	"Cells property in phandle target (e.g. 'gpio' for '#gpio-cells') ",
>  	USAGE_COMMON_OPTS_HELP
>  };
>  
> @@ -360,6 +447,20 @@ int main(int argc, char *argv[])
>  		case 'd':
>  			disp.default_val = optarg;
>  			break;
> +
> +		case 'f':
> +			disp.follow = 1;
> +			break;
> +
> +		case 'c':
> +			disp.phandle_cells = malloc(strlen(optarg) +
> +						    strlen("#-cells"));
> +			if (!disp.phandle_cells) {
> +				fprintf(stderr, "Out of memory\n");
> +				return 1;
> +			}
> +			sprintf(disp.phandle_cells, "#%s-cells", optarg);
> +			break;
>  		}
>  	}
>  
> diff --git a/tests/label01.dts b/tests/label01.dts
> index a895803..020e27d 100644
> --- a/tests/label01.dts
> +++ b/tests/label01.dts
> @@ -59,5 +59,35 @@ memrsv2: /memreserve/ 0x2000000000000000 0x0100000000000000;
>  		linux,platform = <0x600>;
>  	};
>  
> +	phandle-test {
> +		first = <&target_a 10 20>;
> +		both = <&target_a 30 40 &target_b 50 &target_a 60 70>;
> +		third = <&target_c &target_c>;
> +		all = <&target_a 30 40 &target_b 50 &target_c &target_a 60 70>;
> +		too-few-args = <&target_a 80>;
> +		invalid-size = [01];
> +		invalid-target = <&target_d>;
> +	};
> +
> +	target_a: target@0 {
> +		reg = <0 0 0 0>;
> +		#gpio-cells = <2>;
> +	};
> +
> +	target_b: target@1 {
> +		reg = <1 0 0 0>;
> +		#gpio-cells = <1>;
> +	};
> +
> +	target_c: target@2 {
> +		reg = <2 0 0 0>;
> +		#gpio-cells = <0>;
> +	};
> +
> +	target_d: target@3 {
> +		reg = <3 0 0 0>;
> +		#gpio-cells = [01];	/* invalid cell value */
> +	};
> +
>  };
>  
> diff --git a/tests/run_tests.sh b/tests/run_tests.sh
> index 3bc5b41..6272675 100755
> --- a/tests/run_tests.sh
> +++ b/tests/run_tests.sh
> @@ -692,6 +692,24 @@ fdtget_tests () {
>      run_fdtget_test "<the dead silence>" -tx \
>  	-d "<the dead silence>" $dtb /randomnode doctor-who
>      run_fdtget_test "<blink>" -tx -d "<blink>" $dtb /memory doctor-who
> +
> +    # Test following of phandles
> +    run_fdtget_test "/target@0 10 20" -f -c "gpio" $dtb /phandle-test first
> +    run_fdtget_test "/target@0 30 40 /target@1 50 /target@0 60 70" \
> +	-f -c "gpio" $dtb /phandle-test both
> +    run_fdtget_test "/target@2 /target@2" -f -c "gpio" $dtb /phandle-test third
> +    run_fdtget_test "/target@0 30 40 /target@1 50 /target@2 /target@0 60 70" \
> +	-f -c "gpio" $dtb /phandle-test all
> +
> +    # Without the -c parameter we cannot decode some phandles.
> +    run_wrap_error_test $DTGET -f $dtb /phandle-test first
> +    run_wrap_error_test $DTGET -f $dtb /phandle-test both
> +    run_wrap_error_test $DTGET -f $dtb /phandle-test all
> +    run_wrap_error_test $DTGET -f -c wrong $dtb /phandle-test all
> +
> +    run_wrap_error_test $DTGET -f -c gpio $dtb /phandle-test too-few-args
> +    run_wrap_error_test $DTGET -f -c gpio $dtb /phandle-test invalid-size
> +    run_wrap_error_test $DTGET -f -c gpio $dtb /phandle-test invalid-target
>  }
>  
>  fdtput_tests () {

-- 
David Gibson			| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
				| _way_ _around_!
http://www.ozlabs.org/~dgibson

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2017-08-23  5:47 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-08-20 12:28 [PATCH 1/2] fdtget: Split out cell list display into a new function Simon Glass
     [not found] ` <20170820122855.171271-1-sjg-F7+t8E8rja9g9hUCZPvPmw@public.gmane.org>
2017-08-20 12:28   ` [PATCH 2/2] fdtget: Support following phandles Simon Glass
     [not found]     ` <20170820122855.171271-2-sjg-F7+t8E8rja9g9hUCZPvPmw@public.gmane.org>
2017-08-23  5:47       ` David Gibson
2017-08-21  0:29   ` [PATCH 1/2] fdtget: Split out cell list display into a new function David Gibson

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.