Merge tag 'efi-2022-07-rc1' of https://source.denx.de/u-boot/custodians/u-boot-efi

Pull request for efi-2022-07-rc1

Documentation:

* Describe how enable DM_SERIAL for a board

UEFI

* Preparatory patches for better integration of DM and UEFI
* Use sysreset after capsule updates instead of do_reset
* Allow to disable persisting non-volatile variables
diff --git a/common/spl/spl.c b/common/spl/spl.c
index b452d4f..c9750ee 100644
--- a/common/spl/spl.c
+++ b/common/spl/spl.c
@@ -20,6 +20,7 @@
 #include <serial.h>
 #include <spl.h>
 #include <asm/global_data.h>
+#include <asm-generic/gpio.h>
 #include <asm/u-boot.h>
 #include <nand.h>
 #include <fat.h>
@@ -743,6 +744,9 @@
 		}
 	}
 
+	if (CONFIG_IS_ENABLED(GPIO_HOG))
+		gpio_hog_probe_all();
+
 #if CONFIG_IS_ENABLED(BOARD_INIT)
 	spl_board_init();
 #endif
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index a55e368..89068c7 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -57,6 +57,15 @@
 	  is a mechanism providing automatic GPIO request and config-
 	  uration as part of the gpio-controller's driver probe function.
 
+config SPL_GPIO_HOG
+	bool "Enable GPIO hog support in SPL"
+	depends on SPL_GPIO_SUPPORT
+	help
+	  Enable gpio hog support in SPL
+	  The GPIO chip may contain GPIO hog definitions. GPIO hogging
+	  is a mechanism providing automatic GPIO request and config-
+	  uration as part of the gpio-controller's driver probe function.
+
 config DM_GPIO_LOOKUP_LABEL
 	bool "Enable searching for gpio labelnames"
 	depends on DM_GPIO
diff --git a/drivers/gpio/gpio-uclass.c b/drivers/gpio/gpio-uclass.c
index 125ae53..0ed32b7 100644
--- a/drivers/gpio/gpio-uclass.c
+++ b/drivers/gpio/gpio-uclass.c
@@ -1187,6 +1187,32 @@
 				 index, desc, flags, index > 0, NULL);
 }
 
+int gpio_request_by_line_name(struct udevice *dev, const char *line_name,
+			      struct gpio_desc *desc, int flags)
+{
+	int ret;
+
+	ret = dev_read_stringlist_search(dev, "gpio-line-names", line_name);
+	if (ret < 0)
+		return ret;
+
+	desc->dev = dev;
+	desc->offset = ret;
+	desc->flags = 0;
+
+	ret = dm_gpio_request(desc, line_name);
+	if (ret) {
+		debug("%s: dm_gpio_requestf failed\n", __func__);
+		return ret;
+	}
+
+	ret = dm_gpio_set_dir_flags(desc, flags | desc->flags);
+	if (ret)
+		debug("%s: dm_gpio_set_dir failed\n", __func__);
+
+	return ret;
+}
+
 int gpio_request_list_by_name_nodev(ofnode node, const char *list_name,
 				    struct gpio_desc *desc, int max_count,
 				    int flags)
@@ -1432,9 +1458,6 @@
 
 static int gpio_post_bind(struct udevice *dev)
 {
-	struct udevice *child;
-	ofnode node;
-
 #if defined(CONFIG_NEEDS_MANUAL_RELOC)
 	struct dm_gpio_ops *ops = (struct dm_gpio_ops *)device_get_ops(dev);
 	static int reloc_done;
@@ -1465,7 +1488,10 @@
 	}
 #endif
 
-	if (CONFIG_IS_ENABLED(OF_REAL) && IS_ENABLED(CONFIG_GPIO_HOG)) {
+	if (CONFIG_IS_ENABLED(GPIO_HOG)) {
+		struct udevice *child;
+		ofnode node;
+
 		dev_for_each_subnode(node, dev) {
 			if (ofnode_read_bool(node, "gpio-hog")) {
 				const char *name = ofnode_get_name(node);
diff --git a/drivers/gpio/pca953x_gpio.c b/drivers/gpio/pca953x_gpio.c
index dc8911a..e98e1e5 100644
--- a/drivers/gpio/pca953x_gpio.c
+++ b/drivers/gpio/pca953x_gpio.c
@@ -35,6 +35,12 @@
 #define PCA953X_INVERT          2
 #define PCA953X_DIRECTION       3
 
+#define PCA957X_INPUT           0
+#define PCA957X_OUTPUT          5
+#define PCA957X_INVERT          1
+#define PCA957X_DIRECTION       4
+
+
 #define PCA_GPIO_MASK           0x00FF
 #define PCA_INT                 0x0100
 #define PCA953X_TYPE            0x1000
@@ -50,8 +56,29 @@
 #define MAX_BANK 5
 #define BANK_SZ 8
 
+struct pca95xx_reg {
+	int input;
+	int output;
+	int invert;
+	int direction;
+};
+
+static const struct pca95xx_reg pca953x_regs = {
+	.direction = PCA953X_DIRECTION,
+	.output = PCA953X_OUTPUT,
+	.input = PCA953X_INPUT,
+	.invert = PCA953X_INVERT,
+};
+
+static const struct pca95xx_reg pca957x_regs = {
+	.direction = PCA957X_DIRECTION,
+	.output = PCA957X_OUTPUT,
+	.input = PCA957X_INPUT,
+	.invert = PCA957X_INVERT,
+};
+
 /*
- * struct pca953x_info - Data for pca953x
+ * struct pca953x_info - Data for pca953x/pca957x
  *
  * @dev: udevice structure for the device
  * @addr: i2c slave address
@@ -61,6 +88,7 @@
  * @bank_count: the number of banks that the device supports
  * @reg_output: array to hold the value of output registers
  * @reg_direction: array to hold the value of direction registers
+ * @regs: struct to hold the registers addresses
  */
 struct pca953x_info {
 	struct udevice *dev;
@@ -71,6 +99,7 @@
 	int bank_count;
 	u8 reg_output[MAX_BANK];
 	u8 reg_direction[MAX_BANK];
+	const struct pca95xx_reg *regs;
 };
 
 static int pca953x_write_single(struct udevice *dev, int reg, u8 val,
@@ -171,12 +200,13 @@
 
 static int pca953x_get_value(struct udevice *dev, uint offset)
 {
+	struct pca953x_info *info = dev_get_plat(dev);
 	int ret;
 	u8 val = 0;
 
 	int off = offset % BANK_SZ;
 
-	ret = pca953x_read_single(dev, PCA953X_INPUT, &val, offset);
+	ret = pca953x_read_single(dev, info->regs->input, &val, offset);
 	if (ret)
 		return ret;
 
@@ -196,7 +226,7 @@
 	else
 		val = info->reg_output[bank] & ~(1 << off);
 
-	ret = pca953x_write_single(dev, PCA953X_OUTPUT, val, offset);
+	ret = pca953x_write_single(dev, info->regs->output, val, offset);
 	if (ret)
 		return ret;
 
@@ -218,7 +248,7 @@
 	else
 		val = info->reg_direction[bank] & ~(1 << off);
 
-	ret = pca953x_write_single(dev, PCA953X_DIRECTION, val, offset);
+	ret = pca953x_write_single(dev, info->regs->direction, val, offset);
 	if (ret)
 		return ret;
 
@@ -296,14 +326,14 @@
 	}
 
 	info->chip_type = PCA_CHIP_TYPE(driver_data);
-	if (info->chip_type != PCA953X_TYPE) {
-		dev_err(dev, "Only support PCA953X chip type now.\n");
-		return -EINVAL;
-	}
+	if (info->chip_type == PCA953X_TYPE)
+		info->regs = &pca953x_regs;
+	else
+		info->regs = &pca957x_regs;
 
 	info->bank_count = DIV_ROUND_UP(info->gpio_count, BANK_SZ);
 
-	ret = pca953x_read_regs(dev, PCA953X_OUTPUT, info->reg_output);
+	ret = pca953x_read_regs(dev, info->regs->output, info->reg_output);
 	if (ret) {
 		dev_err(dev, "Error reading output register\n");
 		return ret;
@@ -327,7 +357,7 @@
 
 	/* Clear the polarity registers to no invert */
 	memset(val, 0, MAX_BANK);
-	ret = pca953x_write_regs(dev, PCA953X_INVERT, val);
+	ret = pca953x_write_regs(dev, info->regs->invert, val);
 	if (ret < 0) {
 		dev_err(dev, "Error writing invert register\n");
 		return ret;
diff --git a/env/env.c b/env/env.c
index 7168cb9..e4dfb92 100644
--- a/env/env.c
+++ b/env/env.c
@@ -322,18 +322,17 @@
 
 		debug("%s: Environment %s init done (ret=%d)\n", __func__,
 		      drv->name, ret);
-	}
-
-	if (!prio) {
-		gd->env_addr = (ulong)&default_environment[0];
-		gd->env_valid = ENV_INVALID;
 
-		return 0;
+		if (gd->env_valid == ENV_INVALID)
+			ret = -ENOENT;
 	}
 
+	if (!prio)
+		return -ENODEV;
+
 	if (ret == -ENOENT) {
 		gd->env_addr = (ulong)&default_environment[0];
-		gd->env_valid = ENV_INVALID;
+		gd->env_valid = ENV_VALID;
 
 		return 0;
 	}
diff --git a/include/asm-generic/gpio.h b/include/asm-generic/gpio.h
index adc19e9..81f63f0 100644
--- a/include/asm-generic/gpio.h
+++ b/include/asm-generic/gpio.h
@@ -579,6 +579,25 @@
 int gpio_request_by_name(struct udevice *dev, const char *list_name,
 			 int index, struct gpio_desc *desc, int flags);
 
+/* gpio_request_by_line_name - Locate and request a GPIO by line name
+ *
+ * Request a GPIO using the offset of the provided line name in the
+ * gpio-line-names property found in the OF node of the GPIO udevice.
+ *
+ * This allows boards to implement common behaviours using GPIOs while not
+ * requiring specific GPIO offsets be used.
+ *
+ * @dev:	An instance of a GPIO controller udevice
+ * @line_name:	The name of the GPIO (e.g. "bmc-secure-boot")
+ * @desc:	A GPIO descriptor that is populated with the requested GPIO
+ *              upon return
+ * @flags:	The GPIO settings apply to the request
+ * @return 0 if the named line was found and requested successfully, or a
+ * negative error code if the GPIO cannot be found or the request failed.
+ */
+int gpio_request_by_line_name(struct udevice *dev, const char *line_name,
+			      struct gpio_desc *desc, int flags);
+
 /**
  * gpio_request_list_by_name() - Request a list of GPIOs
  *
diff --git a/test/py/tests/test_gpio.py b/test/py/tests/test_gpio.py
index 8c64f68..109649e 100644
--- a/test/py/tests/test_gpio.py
+++ b/test/py/tests/test_gpio.py
@@ -1,6 +1,16 @@
-# SPDX-License-Identifier: GPL-2.0+
+# SPDX-License-Identifier:  GPL-2.0+
+#
+# Copyright (c) 2021 Adarsh Babu Kalepalli <opensource.kab@gmail.com>
+# Copyright (c) 2020 Alex Kiernan <alex.kiernan@gmail.com>
 
 import pytest
+import time
+import u_boot_utils
+
+"""
+	test_gpio_input is intended to test the fix 4dbc107f4683.
+	4dbc107f4683:"cmd: gpio: Correct do_gpio() return value"
+"""
 
 @pytest.mark.boardspec('sandbox')
 @pytest.mark.buildconfigspec('cmd_gpio')
@@ -35,3 +45,166 @@
     assert(expected_response in response)
     response = u_boot_console.run_command('gpio input 200; echo rc:$?')
     assert(expected_response in response)
+
+
+"""
+Generic Tests for 'gpio' command on sandbox and real hardware.
+The below sequence of tests rely on env__gpio_dev_config for configuration values of gpio pins.
+
+ Configuration data for gpio command.
+ The  set,clear,toggle ,input and status options of 'gpio' command are verified.
+ For sake of verification,A  LED/buzzer could be connected to GPIO pins configured as O/P.
+ Logic level '1'/'0' can be applied onto GPIO pins configured as I/P
+
+
+env__gpio_dev_config = {
+        #the number of 'gpio_str_x' strings should equal to
+        #'gpio_str_count' value
+        'gpio_str_count':4 ,
+        'gpio_str_1': '0',
+        'gpio_str_2': '31',
+        'gpio_str_3': '63',
+        'gpio_str_4': '127',
+        'gpio_op_pin': '64',
+        'gpio_ip_pin_set':'65',
+        'gpio_ip_pin_clear':'66',
+        'gpio_clear_value': 'value is 0',
+        'gpio_set_value': 'value is 1',
+}
+"""
+
+
+@pytest.mark.buildconfigspec('cmd_gpio')
+def test_gpio_status_all_generic(u_boot_console):
+    """Test the 'gpio status' command.
+
+	Displays all gpio pins available on the Board.
+	To verify if the status of pins is displayed or not,
+        the user can configure (gpio_str_count) and verify existence of certain
+	pins.The details of these can be configured in 'gpio_str_n'.
+        of boardenv_* (example above).User can configure any
+        number of such pins and mention that count in 'gpio_str_count'.
+    """
+
+    f = u_boot_console.config.env.get('env__gpio_dev_config',False)
+    if not f:
+        pytest.skip("gpio not configured")
+
+    gpio_str_count = f['gpio_str_count']
+
+    #Display all the GPIO ports
+    cmd = 'gpio status -a'
+    response = u_boot_console.run_command(cmd)
+
+    for str_value in range(1,gpio_str_count + 1):
+        assert f["gpio_str_%d" %(str_value)] in response
+
+
+@pytest.mark.buildconfigspec('cmd_gpio')
+def test_gpio_set_generic(u_boot_console):
+    """Test the 'gpio set' command.
+
+	A specific gpio pin configured by user as output
+        (mentioned in gpio_op_pin) is verified for
+	'set' option
+
+    """
+
+    f = u_boot_console.config.env.get('env__gpio_dev_config',False)
+    if not f:
+        pytest.skip("gpio not configured")
+
+    gpio_pin_adr = f['gpio_op_pin'];
+    gpio_set_value = f['gpio_set_value'];
+
+
+    cmd = 'gpio set ' + gpio_pin_adr
+    response = u_boot_console.run_command(cmd)
+    good_response = gpio_set_value
+    assert good_response in response
+
+
+
+@pytest.mark.buildconfigspec('cmd_gpio')
+def test_gpio_clear_generic(u_boot_console):
+    """Test the 'gpio clear' command.
+
+	A specific gpio pin configured by user as output
+        (mentioned in gpio_op_pin) is verified for
+	'clear' option
+    """
+
+    f = u_boot_console.config.env.get('env__gpio_dev_config',False)
+    if not f:
+        pytest.skip("gpio not configured")
+
+    gpio_pin_adr = f['gpio_op_pin'];
+    gpio_clear_value = f['gpio_clear_value'];
+
+
+    cmd = 'gpio clear ' + gpio_pin_adr
+    response = u_boot_console.run_command(cmd)
+    good_response = gpio_clear_value
+    assert good_response in response
+
+
+@pytest.mark.buildconfigspec('cmd_gpio')
+def test_gpio_toggle_generic(u_boot_console):
+    """Test the 'gpio toggle' command.
+
+	A specific gpio pin configured by user as output
+        (mentioned in gpio_op_pin) is verified for
+	'toggle' option
+    """
+
+
+    f = u_boot_console.config.env.get('env__gpio_dev_config',False)
+    if not f:
+        pytest.skip("gpio not configured")
+
+    gpio_pin_adr = f['gpio_op_pin'];
+    gpio_set_value = f['gpio_set_value'];
+    gpio_clear_value = f['gpio_clear_value'];
+
+    cmd = 'gpio set ' + gpio_pin_adr
+    response = u_boot_console.run_command(cmd)
+    good_response = gpio_set_value
+    assert good_response in response
+
+    cmd = 'gpio toggle ' + gpio_pin_adr
+    response = u_boot_console.run_command(cmd)
+    good_response = gpio_clear_value
+    assert good_response in response
+
+
+@pytest.mark.buildconfigspec('cmd_gpio')
+def test_gpio_input_generic(u_boot_console):
+    """Test the 'gpio input' command.
+
+	Specific gpio pins configured by user as input
+        (mentioned in gpio_ip_pin_set and gpio_ip_pin_clear)
+	is verified for logic '1' and logic '0' states
+    """
+
+    f = u_boot_console.config.env.get('env__gpio_dev_config',False)
+    if not f:
+        pytest.skip("gpio not configured")
+
+    gpio_pin_adr = f['gpio_ip_pin_clear'];
+    gpio_clear_value = f['gpio_clear_value'];
+
+
+    cmd = 'gpio input ' + gpio_pin_adr
+    response = u_boot_console.run_command(cmd)
+    good_response = gpio_clear_value
+    assert good_response in response
+
+
+    gpio_pin_adr = f['gpio_ip_pin_set'];
+    gpio_set_value = f['gpio_set_value'];
+
+
+    cmd = 'gpio input ' + gpio_pin_adr
+    response = u_boot_console.run_command(cmd)
+    good_response = gpio_set_value
+    assert good_response in response