All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v3 0/5] sysinfo: Add gpio sysinfo driver
@ 2021-03-31 17:50 Sean Anderson
  2021-03-31 17:50 ` [PATCH v3 1/5] dm: gpio: Fix gpio_get_list_count failing with livetree Sean Anderson
                   ` (4 more replies)
  0 siblings, 5 replies; 9+ messages in thread
From: Sean Anderson @ 2021-03-31 17:50 UTC (permalink / raw)
  To: u-boot

This series adds a GPIO sysinfo driver using the
dm_gpio_get_values_as_int_base3 function. The board revision is mapped
based in devicetree properties. This series is based on Simon's GPIO
series [1].

[1] https://patchwork.ozlabs.org/project/uboot/list/?series=228126

Changes in v3:
- Fix assuming any nonzero return of dev_count_phandle_with_args was an error.
- Fix assuming nonzero return from dm_gpio_get_values_as_int_base3 is an
  error.
- Move detected bool into sysinfo_priv struct
- Rebase onto u-boot/next
- Use SYSINFO_ID_BOARD_MODEL instead of SYSINFO_ID_REVISION

Changes in v2:
- Document sysinfo_gpio_priv
- Enforce sysinfo detect ordering in uclass. Users must still call
  sysinfo_detect beforehand.
- Fix unbalanced brace in sysinfo_gpio_get_int
- Modify sysinfo test to check for detect() ordering.
- Refactor driver to take advantage of the uclass detect ordering
  guarantee.
- Reorder includes
- Set BOARD_HWVERSION to SYSINFO_ID_REVISION, as they represent the same
  content.
- Use enums instead of defines for sysinfo ids

Sean Anderson (5):
  dm: gpio: Fix gpio_get_list_count failing with livetree
  sysinfo: Use global sysinfo IDs for existing sysinfo drivers
  sysinfo: Require that sysinfo_detect be called before other methods
  sysinfo: Add gpio-sysinfo driver
  test: Add gpio-sysinfo test

 arch/sandbox/dts/test.dts                     |   7 +
 common/spl/spl_fit.c                          |   4 +
 .../sysinfo/gpio-sysinfo.txt                  |  37 +++++
 drivers/gpio/gpio-uclass.c                    |   6 +-
 drivers/sysinfo/Kconfig                       |   8 +
 drivers/sysinfo/Makefile                      |   1 +
 drivers/sysinfo/gazerbeam.h                   |   8 +-
 drivers/sysinfo/gpio.c                        | 141 ++++++++++++++++++
 drivers/sysinfo/sandbox.h                     |   2 +-
 drivers/sysinfo/sysinfo-uclass.c              |  29 +++-
 include/sysinfo.h                             |  26 ++--
 test/dm/Makefile                              |   1 +
 test/dm/sysinfo-gpio.c                        |  69 +++++++++
 test/dm/sysinfo.c                             |  23 +--
 14 files changed, 336 insertions(+), 26 deletions(-)
 create mode 100644 doc/device-tree-bindings/sysinfo/gpio-sysinfo.txt
 create mode 100644 drivers/sysinfo/gpio.c
 create mode 100644 test/dm/sysinfo-gpio.c

-- 
2.25.1

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

* [PATCH v3 1/5] dm: gpio: Fix gpio_get_list_count failing with livetree
  2021-03-31 17:50 [PATCH v3 0/5] sysinfo: Add gpio sysinfo driver Sean Anderson
@ 2021-03-31 17:50 ` Sean Anderson
  2021-03-31 17:50 ` [PATCH v3 2/5] sysinfo: Use global sysinfo IDs for existing sysinfo drivers Sean Anderson
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 9+ messages in thread
From: Sean Anderson @ 2021-03-31 17:50 UTC (permalink / raw)
  To: u-boot

of_parse_phandle_with_args (called by dev_read_phandle_with_args) does not
support getting the length of a phandle list by using the index -1.
Instead, use dev_count_phandle_with_args which supports exactly this
use-case.

Fixes: 8558217153 ("gpio: Convert to use APIs which support live DT")

Signed-off-by: Sean Anderson <sean.anderson@seco.com>
Reviewed-by: Simon Glass <sjg@chromium.org>
---

Changes in v3:
- Fix assuming any nonzero return of dev_count_phandle_with_args was an error.

Changes in v2:
- Change Fixes tag to the most recent commit touching these lines

 drivers/gpio/gpio-uclass.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/gpio/gpio-uclass.c b/drivers/gpio/gpio-uclass.c
index f24db87ef0..ac362f007d 100644
--- a/drivers/gpio/gpio-uclass.c
+++ b/drivers/gpio/gpio-uclass.c
@@ -1226,9 +1226,9 @@ int gpio_get_list_count(struct udevice *dev, const char *list_name)
 {
 	int ret;
 
-	ret = dev_read_phandle_with_args(dev, list_name, "#gpio-cells", 0, -1,
-					 NULL);
-	if (ret) {
+	ret = dev_count_phandle_with_args(dev, list_name, "#gpio-cells",
+					  -ENOENT);
+	if (ret < 0) {
 		debug("%s: Node '%s', property '%s', GPIO count failed: %d\n",
 		      __func__, dev->name, list_name, ret);
 	}
-- 
2.25.1

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

* [PATCH v3 2/5] sysinfo: Use global sysinfo IDs for existing sysinfo drivers
  2021-03-31 17:50 [PATCH v3 0/5] sysinfo: Add gpio sysinfo driver Sean Anderson
  2021-03-31 17:50 ` [PATCH v3 1/5] dm: gpio: Fix gpio_get_list_count failing with livetree Sean Anderson
@ 2021-03-31 17:50 ` Sean Anderson
  2021-03-31 17:50 ` [PATCH v3 3/5] sysinfo: Require that sysinfo_detect be called before other methods Sean Anderson
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 9+ messages in thread
From: Sean Anderson @ 2021-03-31 17:50 UTC (permalink / raw)
  To: u-boot

Since 07c9e683a4 ("smbios: Allow a few values to come from sysinfo")
there are common global sysinfo IDs. This patch moved existing IDs above
SYSINFO_ID_USER.

Signed-off-by: Sean Anderson <sean.anderson@seco.com>
Reviewed-by: Simon Glass <sjg@chromium.org>
---

Changes in v3:
- Rework patch to use sjg's sysinfo IDs

Changes in v2:
- Set BOARD_HWVERSION to SYSINFO_ID_REVISION, as they represent the same
  content.
- Use enums instead of defines for sysinfo ids

 drivers/sysinfo/gazerbeam.h | 8 +++++---
 drivers/sysinfo/sandbox.h   | 2 +-
 2 files changed, 6 insertions(+), 4 deletions(-)

diff --git a/drivers/sysinfo/gazerbeam.h b/drivers/sysinfo/gazerbeam.h
index 171729d203..6bf3c0098d 100644
--- a/drivers/sysinfo/gazerbeam.h
+++ b/drivers/sysinfo/gazerbeam.h
@@ -5,10 +5,12 @@
  *
  */
 
+#include <sysinfo.h>
+
 enum {
-	BOARD_MULTICHANNEL,
-	BOARD_VARIANT,
-	BOARD_HWVERSION,
+	BOARD_HWVERSION = SYSINFO_ID_BOARD_MODEL,
+	BOARD_MULTICHANNEL = SYSINFO_ID_USER,
+	BOARD_VARIANT
 };
 
 enum {
diff --git a/drivers/sysinfo/sandbox.h b/drivers/sysinfo/sandbox.h
index 2cff494f56..d9c5804c26 100644
--- a/drivers/sysinfo/sandbox.h
+++ b/drivers/sysinfo/sandbox.h
@@ -5,7 +5,7 @@
  */
 
 enum {
-	BOOL_CALLED_DETECT,
+	BOOL_CALLED_DETECT = SYSINFO_ID_USER,
 	INT_TEST1,
 	INT_TEST2,
 	STR_VACATIONSPOT,
-- 
2.25.1

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

* [PATCH v3 3/5] sysinfo: Require that sysinfo_detect be called before other methods
  2021-03-31 17:50 [PATCH v3 0/5] sysinfo: Add gpio sysinfo driver Sean Anderson
  2021-03-31 17:50 ` [PATCH v3 1/5] dm: gpio: Fix gpio_get_list_count failing with livetree Sean Anderson
  2021-03-31 17:50 ` [PATCH v3 2/5] sysinfo: Use global sysinfo IDs for existing sysinfo drivers Sean Anderson
@ 2021-03-31 17:50 ` Sean Anderson
  2021-03-31 17:50 ` [PATCH v3 4/5] sysinfo: Add gpio-sysinfo driver Sean Anderson
  2021-03-31 17:50 ` [PATCH v3 5/5] test: Add gpio-sysinfo test Sean Anderson
  4 siblings, 0 replies; 9+ messages in thread
From: Sean Anderson @ 2021-03-31 17:50 UTC (permalink / raw)
  To: u-boot

This has the uclass enforce calling detect() before other methods.  This
allows drivers to cache information in detect() and perform (cheaper)
retrieval in the other accessors. This also modifies the only instance
where this sequencing was not followed.

Signed-off-by: Sean Anderson <sean.anderson@seco.com>
Reviewed-by: Simon Glass <sjg@chromium.org>
---

Changes in v3:
- Move detected bool into sysinfo_priv struct

Changes in v2:
- Enforce sysinfo detect ordering in uclass. Users must still call
  sysinfo_detect beforehand.
- Modify sysinfo test to check for detect() ordering.

 common/spl/spl_fit.c             |  4 ++++
 drivers/sysinfo/sysinfo-uclass.c | 29 ++++++++++++++++++++++++++++-
 include/sysinfo.h                | 26 +++++++++++++++++---------
 test/dm/sysinfo.c                | 23 ++++++++++++++---------
 4 files changed, 63 insertions(+), 19 deletions(-)

diff --git a/common/spl/spl_fit.c b/common/spl/spl_fit.c
index 49508fc518..f51321a74c 100644
--- a/common/spl/spl_fit.c
+++ b/common/spl/spl_fit.c
@@ -110,6 +110,10 @@ static int spl_fit_get_image_name(const struct spl_fit_info *ctx,
 		 * no string in the property for this index. Check if the
 		 * sysinfo-level code can supply one.
 		 */
+		rc = sysinfo_detect(sysinfo);
+		if (rc)
+			return rc;
+
 		rc = sysinfo_get_fit_loadable(sysinfo, index - i - 1, type,
 					      &str);
 		if (rc && rc != -ENOENT)
diff --git a/drivers/sysinfo/sysinfo-uclass.c b/drivers/sysinfo/sysinfo-uclass.c
index 6df58fe160..4a660dfd15 100644
--- a/drivers/sysinfo/sysinfo-uclass.c
+++ b/drivers/sysinfo/sysinfo-uclass.c
@@ -8,6 +8,10 @@
 #include <dm.h>
 #include <sysinfo.h>
 
+struct sysinfo_priv {
+	bool detected;
+};
+
 int sysinfo_get(struct udevice **devp)
 {
 	return uclass_first_device_err(UCLASS_SYSINFO, devp);
@@ -15,19 +19,29 @@ int sysinfo_get(struct udevice **devp)
 
 int sysinfo_detect(struct udevice *dev)
 {
+	int ret;
+	struct sysinfo_priv *priv = dev_get_uclass_priv(dev);
 	struct sysinfo_ops *ops = sysinfo_get_ops(dev);
 
 	if (!ops->detect)
 		return -ENOSYS;
 
-	return ops->detect(dev);
+	ret = ops->detect(dev);
+	if (!ret)
+		priv->detected = true;
+
+	return ret;
 }
 
 int sysinfo_get_fit_loadable(struct udevice *dev, int index, const char *type,
 			     const char **strp)
 {
+	struct sysinfo_priv *priv = dev_get_uclass_priv(dev);
 	struct sysinfo_ops *ops = sysinfo_get_ops(dev);
 
+	if (!priv->detected)
+		return -EPERM;
+
 	if (!ops->get_fit_loadable)
 		return -ENOSYS;
 
@@ -36,8 +50,12 @@ int sysinfo_get_fit_loadable(struct udevice *dev, int index, const char *type,
 
 int sysinfo_get_bool(struct udevice *dev, int id, bool *val)
 {
+	struct sysinfo_priv *priv = dev_get_uclass_priv(dev);
 	struct sysinfo_ops *ops = sysinfo_get_ops(dev);
 
+	if (!priv->detected)
+		return -EPERM;
+
 	if (!ops->get_bool)
 		return -ENOSYS;
 
@@ -46,8 +64,12 @@ int sysinfo_get_bool(struct udevice *dev, int id, bool *val)
 
 int sysinfo_get_int(struct udevice *dev, int id, int *val)
 {
+	struct sysinfo_priv *priv = dev_get_uclass_priv(dev);
 	struct sysinfo_ops *ops = sysinfo_get_ops(dev);
 
+	if (!priv->detected)
+		return -EPERM;
+
 	if (!ops->get_int)
 		return -ENOSYS;
 
@@ -56,8 +78,12 @@ int sysinfo_get_int(struct udevice *dev, int id, int *val)
 
 int sysinfo_get_str(struct udevice *dev, int id, size_t size, char *val)
 {
+	struct sysinfo_priv *priv = dev_get_uclass_priv(dev);
 	struct sysinfo_ops *ops = sysinfo_get_ops(dev);
 
+	if (!priv->detected)
+		return -EPERM;
+
 	if (!ops->get_str)
 		return -ENOSYS;
 
@@ -68,4 +94,5 @@ UCLASS_DRIVER(sysinfo) = {
 	.id		= UCLASS_SYSINFO,
 	.name		= "sysinfo",
 	.post_bind	= dm_scan_fdt_dev,
+	.per_device_auto	= sizeof(bool),
 };
diff --git a/include/sysinfo.h b/include/sysinfo.h
index 68fad25a06..7b21140880 100644
--- a/include/sysinfo.h
+++ b/include/sysinfo.h
@@ -57,7 +57,8 @@ struct sysinfo_ops {
 	 * This operation might take a long time (e.g. read from EEPROM,
 	 * check the presence of a device on a bus etc.), hence this is not
 	 * done in the probe() method, but later during operation in this
-	 * dedicated method.
+	 * dedicated method. This method will be called before any other
+	 * methods.
 	 *
 	 * Return: 0 if OK, -ve on error.
 	 */
@@ -101,7 +102,7 @@ struct sysinfo_ops {
 	 * get_fit_loadable - Get the name of an image to load from FIT
 	 * This function can be used to provide the image names based on runtime
 	 * detection. A classic use-case would when DTBOs are used to describe
-	 * additionnal daughter cards.
+	 * additional daughter cards.
 	 *
 	 * @dev:	The sysinfo instance to gather the data.
 	 * @index:	Index of the image. Starts at 0 and gets incremented
@@ -124,6 +125,9 @@ struct sysinfo_ops {
  *
  * @dev:	The device containing the information
  *
+ * This function must be called before any other accessor function for this
+ * device.
+ *
  * Return: 0 if OK, -ve on error.
  */
 int sysinfo_detect(struct udevice *dev);
@@ -135,7 +139,8 @@ int sysinfo_detect(struct udevice *dev);
  * @id:		A unique identifier for the bool value to be read.
  * @val:	Pointer to a buffer that receives the value read.
  *
- * Return: 0 if OK, -ve on error.
+ * Return: 0 if OK, -EPERM if called before sysinfo_detect(), else -ve on
+ * error.
  */
 int sysinfo_get_bool(struct udevice *dev, int id, bool *val);
 
@@ -146,7 +151,8 @@ int sysinfo_get_bool(struct udevice *dev, int id, bool *val);
  * @id:		A unique identifier for the int value to be read.
  * @val:	Pointer to a buffer that receives the value read.
  *
- * Return: 0 if OK, -ve on error.
+ * Return: 0 if OK, -EPERM if called before sysinfo_detect(), else -ve on
+ * error.
  */
 int sysinfo_get_int(struct udevice *dev, int id, int *val);
 
@@ -158,7 +164,8 @@ int sysinfo_get_int(struct udevice *dev, int id, int *val);
  * @size:	The size of the buffer to receive the string data.
  * @val:	Pointer to a buffer that receives the value read.
  *
- * Return: 0 if OK, -ve on error.
+ * Return: 0 if OK, -EPERM if called before sysinfo_detect(), else -ve on
+ * error.
  */
 int sysinfo_get_str(struct udevice *dev, int id, size_t size, char *val);
 
@@ -170,7 +177,8 @@ int sysinfo_get_str(struct udevice *dev, int id, size_t size, char *val);
  * function that returns the unique device. This is especially useful for use
  * in sysinfo files.
  *
- * Return: 0 if OK, -ve on error.
+ * Return: 0 if OK, -EPERM if called before sysinfo_detect(), else -ve on
+ * error.
  */
 int sysinfo_get(struct udevice **devp);
 
@@ -178,7 +186,7 @@ int sysinfo_get(struct udevice **devp);
  * sysinfo_get_fit_loadable - Get the name of an image to load from FIT
  * This function can be used to provide the image names based on runtime
  * detection. A classic use-case would when DTBOs are used to describe
- * additionnal daughter cards.
+ * additional daughter cards.
  *
  * @dev:	The sysinfo instance to gather the data.
  * @index:	Index of the image. Starts at 0 and gets incremented
@@ -187,8 +195,8 @@ int sysinfo_get(struct udevice **devp);
  * @strp:	A pointer to string. Untouched if the function fails
  *
  *
- * Return: 0 if OK, -ENOENT if no loadable is available else -ve on
- * error.
+ * Return: 0 if OK, -EPERM if called before sysinfo_detect(), -ENOENT if no
+ * loadable is available else -ve on error.
  */
 int sysinfo_get_fit_loadable(struct udevice *dev, int index, const char *type,
 			     const char **strp);
diff --git a/test/dm/sysinfo.c b/test/dm/sysinfo.c
index 4aaa9e85bc..fd13f6aac5 100644
--- a/test/dm/sysinfo.c
+++ b/test/dm/sysinfo.c
@@ -24,33 +24,38 @@ static int dm_test_sysinfo(struct unit_test_state *uts)
 	ut_assertok(sysinfo_get(&sysinfo));
 	ut_assert(sysinfo);
 
-	sysinfo_get_bool(sysinfo, BOOL_CALLED_DETECT, &called_detect);
+	ut_asserteq(-EPERM, sysinfo_get_bool(sysinfo, BOOL_CALLED_DETECT,
+					     &called_detect));
 	ut_assert(!called_detect);
 
 	sysinfo_detect(sysinfo);
 
-	sysinfo_get_bool(sysinfo, BOOL_CALLED_DETECT, &called_detect);
+	ut_assertok(sysinfo_get_bool(sysinfo, BOOL_CALLED_DETECT,
+				     &called_detect));
 	ut_assert(called_detect);
 
-	sysinfo_get_str(sysinfo, STR_VACATIONSPOT, sizeof(str), str);
+	ut_assertok(sysinfo_get_str(sysinfo, STR_VACATIONSPOT, sizeof(str),
+				    str));
 	ut_assertok(strcmp(str, "R'lyeh"));
 
-	sysinfo_get_int(sysinfo, INT_TEST1, &i);
+	ut_assertok(sysinfo_get_int(sysinfo, INT_TEST1, &i));
 	ut_asserteq(0, i);
 
-	sysinfo_get_int(sysinfo, INT_TEST2, &i);
+	ut_assertok(sysinfo_get_int(sysinfo, INT_TEST2, &i));
 	ut_asserteq(100, i);
 
-	sysinfo_get_str(sysinfo, STR_VACATIONSPOT, sizeof(str), str);
+	ut_assertok(sysinfo_get_str(sysinfo, STR_VACATIONSPOT, sizeof(str),
+				    str));
 	ut_assertok(strcmp(str, "Carcosa"));
 
-	sysinfo_get_int(sysinfo, INT_TEST1, &i);
+	ut_assertok(sysinfo_get_int(sysinfo, INT_TEST1, &i));
 	ut_asserteq(1, i);
 
-	sysinfo_get_int(sysinfo, INT_TEST2, &i);
+	ut_assertok(sysinfo_get_int(sysinfo, INT_TEST2, &i));
 	ut_asserteq(99, i);
 
-	sysinfo_get_str(sysinfo, STR_VACATIONSPOT, sizeof(str), str);
+	ut_assertok(sysinfo_get_str(sysinfo, STR_VACATIONSPOT, sizeof(str),
+				    str));
 	ut_assertok(strcmp(str, "Yuggoth"));
 
 	return 0;
-- 
2.25.1

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

* [PATCH v3 4/5] sysinfo: Add gpio-sysinfo driver
  2021-03-31 17:50 [PATCH v3 0/5] sysinfo: Add gpio sysinfo driver Sean Anderson
                   ` (2 preceding siblings ...)
  2021-03-31 17:50 ` [PATCH v3 3/5] sysinfo: Require that sysinfo_detect be called before other methods Sean Anderson
@ 2021-03-31 17:50 ` Sean Anderson
  2021-03-31 17:50 ` [PATCH v3 5/5] test: Add gpio-sysinfo test Sean Anderson
  4 siblings, 0 replies; 9+ messages in thread
From: Sean Anderson @ 2021-03-31 17:50 UTC (permalink / raw)
  To: u-boot

This uses the newly-added dm_gpio_get_values_as_int_base3 function to
implement a sysinfo device. The revision map is stored in the device tree.

Signed-off-by: Sean Anderson <sean.anderson@seco.com>
Reviewed-by: Simon Glass <sjg@chromium.org>
---

Changes in v3:
- Fix assuming nonzero return from dm_gpio_get_values_as_int_base3 is an
  error.
- Use SYSINFO_ID_BOARD_MODEL instead of SYSINFO_ID_REVISION

Changes in v2:
- Document sysinfo_gpio_priv
- Fix unbalanced brace in sysinfo_gpio_get_int
- Refactor driver to take advantage of the uclass detect ordering
  guarantee.
- Reorder includes

 .../sysinfo/gpio-sysinfo.txt                  |  37 +++++
 drivers/sysinfo/Kconfig                       |   8 +
 drivers/sysinfo/Makefile                      |   1 +
 drivers/sysinfo/gpio.c                        | 141 ++++++++++++++++++
 4 files changed, 187 insertions(+)
 create mode 100644 doc/device-tree-bindings/sysinfo/gpio-sysinfo.txt
 create mode 100644 drivers/sysinfo/gpio.c

diff --git a/doc/device-tree-bindings/sysinfo/gpio-sysinfo.txt b/doc/device-tree-bindings/sysinfo/gpio-sysinfo.txt
new file mode 100644
index 0000000000..b5739d94e9
--- /dev/null
+++ b/doc/device-tree-bindings/sysinfo/gpio-sysinfo.txt
@@ -0,0 +1,37 @@
+GPIO-based Sysinfo device
+
+This binding describes several GPIOs which specify a board revision. Each GPIO
+forms a digit in a ternary revision number. This revision is then mapped to a
+name using the revisions and names properties.
+
+Each GPIO may be floating, pulled-up, or pulled-down, mapping to digits 2, 1,
+and 0, respectively. The first GPIO forms the least-significant digit of the
+revision. For example, consider the property
+
+	gpios = <&gpio 0>, <&gpio 1>, <&gpio 2>;
+
+If GPIO 0 is pulled-up, GPIO 1 is pulled-down, and GPIO 2 is floating, then the
+revision would be
+
+	0t201 = 2*9 + 0*3 + 1*3 = 19
+
+If instead GPIO 0 is floating, GPIO 1 is pulled-up, and GPIO 2 is pulled-down,
+then the revision would be
+
+	0t012 = 0*9 + 1*3 + 2*1 = 5
+
+Required properties:
+- compatible: should be "gpio-sysinfo".
+- gpios: should be a list of gpios forming the revision number,
+  least-significant-digit first
+- revisions: a list of known revisions; any revisions not present will have the
+  name "unknown"
+- names: the name of each revision in revisions
+
+Example:
+sysinfo {
+	compatible = "gpio-sysinfo";
+	gpios = <&gpio_a 15>, <&gpio_a 16>, <&gpio_a 17>;
+	revisions = <19>, <5>;
+	names = "rev_a", "foo";
+};
diff --git a/drivers/sysinfo/Kconfig b/drivers/sysinfo/Kconfig
index 85c1e81e41..381dcd8844 100644
--- a/drivers/sysinfo/Kconfig
+++ b/drivers/sysinfo/Kconfig
@@ -30,4 +30,12 @@ config SYSINFO_SMBIOS
 	  one which provides a way to specify this SMBIOS information in the
 	  devicetree, without needing any board-specific functionality.
 
+config SYSINFO_GPIO
+	bool "Enable gpio sysinfo driver"
+	help
+	  Support querying gpios to determine board revision. This uses gpios to
+	  form a ternary number (when they are pulled-up, -down, or floating).
+	  This ternary number is then mapped to a board revision name using
+	  device tree properties.
+
 endif
diff --git a/drivers/sysinfo/Makefile b/drivers/sysinfo/Makefile
index 6d04fcba1d..d9f708b7ea 100644
--- a/drivers/sysinfo/Makefile
+++ b/drivers/sysinfo/Makefile
@@ -4,5 +4,6 @@
 # Mario Six,  Guntermann & Drunck GmbH, mario.six at gdsys.cc
 obj-y += sysinfo-uclass.o
 obj-$(CONFIG_SYSINFO_GAZERBEAM) += gazerbeam.o
+obj-$(CONFIG_SYSINFO_GPIO) += gpio.o
 obj-$(CONFIG_SYSINFO_SANDBOX) += sandbox.o
 obj-$(CONFIG_SYSINFO_SMBIOS) += smbios.o
diff --git a/drivers/sysinfo/gpio.c b/drivers/sysinfo/gpio.c
new file mode 100644
index 0000000000..1d7f050998
--- /dev/null
+++ b/drivers/sysinfo/gpio.c
@@ -0,0 +1,141 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2021 Sean Anderson <sean.anderson@seco.com>
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <log.h>
+#include <sysinfo.h>
+#include <asm/gpio.h>
+#include <dm/device_compat.h>
+
+/**
+ * struct sysinfo_gpio_priv - GPIO sysinfo private data
+ * @gpios: List of GPIOs used to detect the revision
+ * @gpio_num: The number of GPIOs in @gpios
+ * @revision: The revision as detected from the GPIOs.
+ */
+struct sysinfo_gpio_priv {
+	struct gpio_desc *gpios;
+	int gpio_num, revision;
+};
+
+static int sysinfo_gpio_detect(struct udevice *dev)
+{
+	int ret;
+	struct sysinfo_gpio_priv *priv = dev_get_priv(dev);
+
+	ret = dm_gpio_get_values_as_int_base3(priv->gpios, priv->gpio_num);
+	if (ret < 0)
+		return ret;
+
+	priv->revision = ret;
+	return 0;
+}
+
+static int sysinfo_gpio_get_int(struct udevice *dev, int id, int *val)
+{
+	struct sysinfo_gpio_priv *priv = dev_get_priv(dev);
+
+	switch (id) {
+	case SYSINFO_ID_BOARD_MODEL:
+		*val = priv->revision;
+		return 0;
+	default:
+		return -EINVAL;
+	};
+}
+
+static int sysinfo_gpio_get_str(struct udevice *dev, int id, size_t size, char *val)
+{
+	struct sysinfo_gpio_priv *priv = dev_get_priv(dev);
+
+	switch (id) {
+	case SYSINFO_ID_BOARD_MODEL: {
+		const char *name = NULL;
+		int i, ret;
+		u32 revision;
+
+		for (i = 0; i < priv->gpio_num; i++) {
+			ret = dev_read_u32_index(dev, "revisions", i,
+						 &revision);
+			if (ret) {
+				if (ret != -EOVERFLOW)
+					return ret;
+				break;
+			}
+
+			if (revision == priv->revision) {
+				ret = dev_read_string_index(dev, "names", i,
+							    &name);
+				if (ret < 0)
+					return ret;
+				break;
+			}
+		}
+		if (!name)
+			name = "unknown";
+
+		strncpy(val, name, size);
+		val[size - 1] = '\0';
+		return 0;
+	} default:
+		return -EINVAL;
+	};
+}
+
+static const struct sysinfo_ops sysinfo_gpio_ops = {
+	.detect = sysinfo_gpio_detect,
+	.get_int = sysinfo_gpio_get_int,
+	.get_str = sysinfo_gpio_get_str,
+};
+
+static int sysinfo_gpio_probe(struct udevice *dev)
+{
+	int ret;
+	struct sysinfo_gpio_priv *priv = dev_get_priv(dev);
+
+	priv->gpio_num = gpio_get_list_count(dev, "gpios");
+	if (priv->gpio_num < 0) {
+		dev_err(dev, "could not get gpios length (err = %d)\n",
+			priv->gpio_num);
+		return priv->gpio_num;
+	}
+
+	priv->gpios = calloc(priv->gpio_num, sizeof(*priv->gpios));
+	if (!priv->gpios) {
+		dev_err(dev, "could not allocate memory for %d gpios\n",
+			priv->gpio_num);
+		return -ENOMEM;
+	}
+
+	ret = gpio_request_list_by_name(dev, "gpios", priv->gpios,
+					priv->gpio_num, GPIOD_IS_IN);
+	if (ret != priv->gpio_num) {
+		dev_err(dev, "could not get gpios (err = %d)\n",
+			priv->gpio_num);
+		return ret;
+	}
+
+	if (!dev_read_bool(dev, "revisions") || !dev_read_bool(dev, "names")) {
+		dev_err(dev, "revisions or names properties missing\n");
+		return -ENOENT;
+	}
+
+	return 0;
+}
+
+static const struct udevice_id sysinfo_gpio_ids[] = {
+	{ .compatible = "gpio-sysinfo" },
+	{ /* sentinel */ }
+};
+
+U_BOOT_DRIVER(sysinfo_gpio) = {
+	.name           = "sysinfo_gpio",
+	.id             = UCLASS_SYSINFO,
+	.of_match       = sysinfo_gpio_ids,
+	.ops		= &sysinfo_gpio_ops,
+	.priv_auto	= sizeof(struct sysinfo_gpio_priv),
+	.probe          = sysinfo_gpio_probe,
+};
-- 
2.25.1

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

* [PATCH v3 5/5] test: Add gpio-sysinfo test
  2021-03-31 17:50 [PATCH v3 0/5] sysinfo: Add gpio sysinfo driver Sean Anderson
                   ` (3 preceding siblings ...)
  2021-03-31 17:50 ` [PATCH v3 4/5] sysinfo: Add gpio-sysinfo driver Sean Anderson
@ 2021-03-31 17:50 ` Sean Anderson
  2021-04-20 11:29   ` Tom Rini
  4 siblings, 1 reply; 9+ messages in thread
From: Sean Anderson @ 2021-03-31 17:50 UTC (permalink / raw)
  To: u-boot

This adds a test for the gpio-sysinfo driver.

Signed-off-by: Sean Anderson <sean.anderson@seco.com>
Reviewed-by: Simon Glass <sjg@chromium.org>
---

Changes in v3:
- Use SYSINFO_ID_BOARD_MODEL instead of SYSINFO_ID_REVISION

Changes in v2:
- Reorder includes

 arch/sandbox/dts/test.dts |  7 ++++
 test/dm/Makefile          |  1 +
 test/dm/sysinfo-gpio.c    | 69 +++++++++++++++++++++++++++++++++++++++
 3 files changed, 77 insertions(+)
 create mode 100644 test/dm/sysinfo-gpio.c

diff --git a/arch/sandbox/dts/test.dts b/arch/sandbox/dts/test.dts
index 899e75f260..3ba927607e 100644
--- a/arch/sandbox/dts/test.dts
+++ b/arch/sandbox/dts/test.dts
@@ -1387,6 +1387,13 @@
 		compatible = "sandbox,sysinfo-sandbox";
 	};
 
+	sysinfo-gpio {
+		compatible = "gpio-sysinfo";
+		gpios = <&gpio_a 15>, <&gpio_a 16>, <&gpio_a 17>;
+		revisions = <19>, <5>;
+		names = "rev_a", "foo";
+	};
+
 	some_regmapped-bus {
 		#address-cells = <0x1>;
 		#size-cells = <0x1>;
diff --git a/test/dm/Makefile b/test/dm/Makefile
index f5cc5540e8..219f8d8d7c 100644
--- a/test/dm/Makefile
+++ b/test/dm/Makefile
@@ -98,5 +98,6 @@ endif
 ifneq ($(CONFIG_EFI_PARTITION),)
 obj-$(CONFIG_FASTBOOT_FLASH_MMC) += fastboot.o
 endif
+obj-$(CONFIG_SYSINFO_GPIO) += sysinfo-gpio.o
 endif
 endif # !SPL
diff --git a/test/dm/sysinfo-gpio.c b/test/dm/sysinfo-gpio.c
new file mode 100644
index 0000000000..2e494b3f34
--- /dev/null
+++ b/test/dm/sysinfo-gpio.c
@@ -0,0 +1,69 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2021 Sean Anderson <sean.anderson@seco.com>
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <log.h>
+#include <sysinfo.h>
+#include <asm/gpio.h>
+#include <dm/test.h>
+#include <test/test.h>
+#include <test/ut.h>
+
+static int dm_test_sysinfo_gpio(struct unit_test_state *uts)
+{
+	char buf[64];
+	int val;
+	struct udevice *sysinfo, *gpio;
+
+	ut_assertok(uclass_get_device_by_name(UCLASS_SYSINFO, "sysinfo-gpio",
+					      &sysinfo));
+	ut_assertok(uclass_get_device_by_name(UCLASS_GPIO, "base-gpios", &gpio));
+
+	/*
+	 * Set up pins: pull-up (1), pull-down (0) and floating (2). This should
+	 * result in digits 2 0 1, i.e. 2 * 9 + 1 * 3 = 19
+	 */
+	sandbox_gpio_set_flags(gpio, 15, GPIOD_EXT_PULL_UP);
+	sandbox_gpio_set_flags(gpio, 16, GPIOD_EXT_PULL_DOWN);
+	sandbox_gpio_set_flags(gpio, 17, 0);
+	ut_assertok(sysinfo_detect(sysinfo));
+	ut_assertok(sysinfo_get_int(sysinfo, SYSINFO_ID_BOARD_MODEL, &val));
+	ut_asserteq(19, val);
+	ut_assertok(sysinfo_get_str(sysinfo, SYSINFO_ID_BOARD_MODEL, sizeof(buf),
+				    buf));
+	ut_asserteq_str("rev_a", buf);
+
+	/*
+	 * Set up pins: floating (2), pull-up (1) and pull-down (0). This should
+	 * result in digits 0 1 2, i.e. 1 * 3 + 2 = 5
+	 */
+	sandbox_gpio_set_flags(gpio, 15, 0);
+	sandbox_gpio_set_flags(gpio, 16, GPIOD_EXT_PULL_UP);
+	sandbox_gpio_set_flags(gpio, 17, GPIOD_EXT_PULL_DOWN);
+	ut_assertok(sysinfo_detect(sysinfo));
+	ut_assertok(sysinfo_get_int(sysinfo, SYSINFO_ID_BOARD_MODEL, &val));
+	ut_asserteq(5, val);
+	ut_assertok(sysinfo_get_str(sysinfo, SYSINFO_ID_BOARD_MODEL, sizeof(buf),
+				    buf));
+	ut_asserteq_str("foo", buf);
+
+	/*
+	 * Set up pins: floating (2), pull-up (1) and pull-down (0). This should
+	 * result in digits 1 2 0, i.e. 1 * 9 + 2 * 3 = 15
+	 */
+	sandbox_gpio_set_flags(gpio, 15, GPIOD_EXT_PULL_DOWN);
+	sandbox_gpio_set_flags(gpio, 16, 0);
+	sandbox_gpio_set_flags(gpio, 17, GPIOD_EXT_PULL_UP);
+	ut_assertok(sysinfo_detect(sysinfo));
+	ut_assertok(sysinfo_get_int(sysinfo, SYSINFO_ID_BOARD_MODEL, &val));
+	ut_asserteq(15, val);
+	ut_assertok(sysinfo_get_str(sysinfo, SYSINFO_ID_BOARD_MODEL, sizeof(buf),
+				    buf));
+	ut_asserteq_str("unknown", buf);
+
+	return 0;
+}
+DM_TEST(dm_test_sysinfo_gpio, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
-- 
2.25.1

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

* [PATCH v3 5/5] test: Add gpio-sysinfo test
  2021-03-31 17:50 ` [PATCH v3 5/5] test: Add gpio-sysinfo test Sean Anderson
@ 2021-04-20 11:29   ` Tom Rini
  2021-04-20 14:08     ` Sean Anderson
  0 siblings, 1 reply; 9+ messages in thread
From: Tom Rini @ 2021-04-20 11:29 UTC (permalink / raw)
  To: u-boot

On Wed, Mar 31, 2021 at 01:50:40PM -0400, Sean Anderson wrote:

> This adds a test for the gpio-sysinfo driver.
> 
> Signed-off-by: Sean Anderson <sean.anderson@seco.com>
> Reviewed-by: Simon Glass <sjg@chromium.org>

This test no longer passes.  Can you please rebase the series and
retest?  Thanks.

-- 
Tom
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 659 bytes
Desc: not available
URL: <https://lists.denx.de/pipermail/u-boot/attachments/20210420/c44f2411/attachment.sig>

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

* [PATCH v3 5/5] test: Add gpio-sysinfo test
  2021-04-20 11:29   ` Tom Rini
@ 2021-04-20 14:08     ` Sean Anderson
  2021-04-20 14:17       ` Tom Rini
  0 siblings, 1 reply; 9+ messages in thread
From: Sean Anderson @ 2021-04-20 14:08 UTC (permalink / raw)
  To: u-boot


On 4/20/21 7:29 AM, Tom Rini wrote:
 > On Wed, Mar 31, 2021 at 01:50:40PM -0400, Sean Anderson wrote:
 >
 >> This adds a test for the gpio-sysinfo driver.
 >>
 >> Signed-off-by: Sean Anderson <sean.anderson@seco.com>
 >> Reviewed-by: Simon Glass <sjg@chromium.org>
 >
 > This test no longer passes.  Can you please rebase the series and
 > retest?  Thanks.
 >

I rebased onto u-boot/master and the test passes on sandbox and
sandbox64. Do you have a specific configuration I can try out? Or a log
of the failing test?

--Sean

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

* [PATCH v3 5/5] test: Add gpio-sysinfo test
  2021-04-20 14:08     ` Sean Anderson
@ 2021-04-20 14:17       ` Tom Rini
  0 siblings, 0 replies; 9+ messages in thread
From: Tom Rini @ 2021-04-20 14:17 UTC (permalink / raw)
  To: u-boot

On Tue, Apr 20, 2021 at 10:08:07AM -0400, Sean Anderson wrote:
> 
> On 4/20/21 7:29 AM, Tom Rini wrote:
> > On Wed, Mar 31, 2021 at 01:50:40PM -0400, Sean Anderson wrote:
> >
> >> This adds a test for the gpio-sysinfo driver.
> >>
> >> Signed-off-by: Sean Anderson <sean.anderson@seco.com>
> >> Reviewed-by: Simon Glass <sjg@chromium.org>
> >
> > This test no longer passes.  Can you please rebase the series and
> > retest?  Thanks.
> >
> 
> I rebased onto u-boot/master and the test passes on sandbox and
> sandbox64. Do you have a specific configuration I can try out? Or a log
> of the failing test?

https://source.denx.de/u-boot/u-boot/-/jobs/257499

-- 
Tom
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 659 bytes
Desc: not available
URL: <https://lists.denx.de/pipermail/u-boot/attachments/20210420/2f252b66/attachment.sig>

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

end of thread, other threads:[~2021-04-20 14:17 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-03-31 17:50 [PATCH v3 0/5] sysinfo: Add gpio sysinfo driver Sean Anderson
2021-03-31 17:50 ` [PATCH v3 1/5] dm: gpio: Fix gpio_get_list_count failing with livetree Sean Anderson
2021-03-31 17:50 ` [PATCH v3 2/5] sysinfo: Use global sysinfo IDs for existing sysinfo drivers Sean Anderson
2021-03-31 17:50 ` [PATCH v3 3/5] sysinfo: Require that sysinfo_detect be called before other methods Sean Anderson
2021-03-31 17:50 ` [PATCH v3 4/5] sysinfo: Add gpio-sysinfo driver Sean Anderson
2021-03-31 17:50 ` [PATCH v3 5/5] test: Add gpio-sysinfo test Sean Anderson
2021-04-20 11:29   ` Tom Rini
2021-04-20 14:08     ` Sean Anderson
2021-04-20 14:17       ` Tom Rini

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.