Merge https://source.denx.de/u-boot/custodians/u-boot-usb
diff --git a/cmd/Kconfig b/cmd/Kconfig
index bfa12ce..6f00bd9 100644
--- a/cmd/Kconfig
+++ b/cmd/Kconfig
@@ -1914,7 +1914,6 @@
 
 config CMD_CLS
 	bool "Enable clear screen command 'cls'"
-	depends on DM_VIDEO || LCD || VIDEO
 	default y if LCD
 	help
 	  Enable the 'cls' command which clears the screen contents
diff --git a/doc/build/gcc.rst b/doc/build/gcc.rst
index a71f860..a0650a5 100644
--- a/doc/build/gcc.rst
+++ b/doc/build/gcc.rst
@@ -27,10 +27,11 @@
       device-tree-compiler dfu-util efitools flex gdisk graphviz imagemagick \
       liblz4-tool libgnutls28-dev libguestfs-tools libncurses-dev \
       libpython3-dev libsdl2-dev libssl-dev lz4 lzma lzma-alone openssl \
-      pkg-config python3 python3-asteval python3-coverage \
+      pkg-config python3 python3-asteval python3-coverage python3-filelock \
       python3-pkg-resources python3-pycryptodome python3-pyelftools \
-      python3-pytest python3-sphinxcontrib.apidoc python3-sphinx-rtd-theme \
-      python3-subunit python3-testtools python3-virtualenv swig uuid-dev
+      python3-pytest python3-pytest-xdist python3-sphinxcontrib.apidoc \
+      python3-sphinx-rtd-theme python3-subunit python3-testtools \
+      python3-virtualenv swig uuid-dev
 
 SUSE based
 ~~~~~~~~~~
diff --git a/doc/develop/py_testing.rst b/doc/develop/py_testing.rst
index 92fbd22..6ff7810 100644
--- a/doc/develop/py_testing.rst
+++ b/doc/develop/py_testing.rst
@@ -47,6 +47,7 @@
 * coreutils
 * dosfstools
 * efitools
+* guestfs-tools
 * mount
 * mtools
 * sbsigntool
@@ -63,6 +64,24 @@
   physical board, attach to the board's console stream, and reset the board.
   Further details are described later.
 
+The usage of command 'sudo' should be avoided in tests. To create disk images
+use command virt-make-fs which is provided by package guestfs-tools. This
+command creates a virtual machine with QEMU in which the disk image is
+generated.
+
+Command virt-make-fs needs read access to the current kernel. On Ubuntu only
+root has this privilege. You can add a script /etc/initramfs-tools/hooks/vmlinuz
+with the following content to overcome the problem:
+
+.. code-block:: bash
+
+    #!/bin/sh
+    echo "chmod a+r vmlinuz-*"
+    chmod a+r /boot/vmlinuz-*
+
+The script should be chmod 755. It will be invoked whenever the initial RAM file
+system is updated.
+
 Using `virtualenv` to provide requirements
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
diff --git a/doc/usage/cmd/cls.rst b/doc/usage/cmd/cls.rst
new file mode 100644
index 0000000..b5c43e0
--- /dev/null
+++ b/doc/usage/cmd/cls.rst
@@ -0,0 +1,26 @@
+.. SPDX-License-Identifier: GPL-2.0+
+
+cls command
+===========
+
+Synopsis
+--------
+
+::
+
+    cls
+
+Description
+-----------
+
+The cls command clears the screen.
+
+Configuration
+-------------
+
+The cls command is only available if CONFIG_CMD_CLS=y.
+
+Return value
+------------
+
+The return value $? is 0 (true) on success and 1 (false) on failure.
diff --git a/doc/usage/index.rst b/doc/usage/index.rst
index 0fda121..d064110 100644
--- a/doc/usage/index.rst
+++ b/doc/usage/index.rst
@@ -32,6 +32,7 @@
    cmd/button
    cmd/bootz
    cmd/cbsysinfo
+   cmd/cls
    cmd/conitrace
    cmd/cyclic
    cmd/dm
diff --git a/include/efi_loader.h b/include/efi_loader.h
index 69d6d00..1bac3f4 100644
--- a/include/efi_loader.h
+++ b/include/efi_loader.h
@@ -651,8 +651,6 @@
 efi_status_t efi_remove_protocol(const efi_handle_t handle,
 				 const efi_guid_t *protocol,
 				 void *protocol_interface);
-/* Delete all protocols from a handle */
-efi_status_t efi_remove_all_protocols(const efi_handle_t handle);
 /* Install multiple protocol interfaces */
 efi_status_t EFIAPI
 efi_install_multiple_protocol_interfaces(efi_handle_t *handle, ...);
@@ -663,11 +661,10 @@
 			enum efi_locate_search_type search_type,
 			const efi_guid_t *protocol, void *search_key,
 			efi_uintn_t *no_handles, efi_handle_t **buffer);
-/* Close an previously opened protocol interface */
-efi_status_t EFIAPI efi_close_protocol(efi_handle_t handle,
-				       const efi_guid_t *protocol,
-				       efi_handle_t agent_handle,
-				       efi_handle_t controller_handle);
+/* Close a previously opened protocol interface */
+efi_status_t efi_close_protocol(efi_handle_t handle, const efi_guid_t *protocol,
+				efi_handle_t agent_handle,
+				efi_handle_t controller_handle);
 /* Open a protocol interface */
 efi_status_t EFIAPI efi_handle_protocol(efi_handle_t handle,
 					const efi_guid_t *protocol,
diff --git a/lib/efi_driver/efi_uclass.c b/lib/efi_driver/efi_uclass.c
index 2193f84..45f9351 100644
--- a/lib/efi_driver/efi_uclass.c
+++ b/lib/efi_driver/efi_uclass.c
@@ -97,10 +97,9 @@
 
 	ret = check_node_type(controller_handle);
 
-	r = EFI_CALL(systab.boottime->close_protocol(
-				controller_handle, bp->ops->protocol,
-				this->driver_binding_handle,
-				controller_handle));
+	r = efi_close_protocol(controller_handle, bp->ops->protocol,
+			       this->driver_binding_handle,
+			       controller_handle);
 	if (r != EFI_SUCCESS)
 		ret = EFI_UNSUPPORTED;
 out:
@@ -151,10 +150,9 @@
 		goto out;
 
 err:
-	r = EFI_CALL(systab.boottime->close_protocol(
-			controller_handle, bp->ops->protocol,
-			this->driver_binding_handle,
-			controller_handle));
+	r = efi_close_protocol(controller_handle, bp->ops->protocol,
+			       this->driver_binding_handle,
+			       controller_handle);
 	if (r != EFI_SUCCESS)
 		EFI_PRINT("Failure to close handle\n");
 
@@ -177,9 +175,8 @@
 	efi_guid_t *guid_controller = NULL;
 	efi_guid_t *guid_child_controller = NULL;
 
-	ret = EFI_CALL(systab.boottime->close_protocol(
-				controller_handle, guid_controller,
-				child_handle, child_handle));
+	ret = efi_close_protocol(controller_handle, guid_controller,
+				 child_handle, child_handle);
 	if (ret != EFI_SUCCESS) {
 		EFI_PRINT("Cannot close protocol\n");
 		return ret;
@@ -225,9 +222,10 @@
 			ret = disconnect_child(controller_handle,
 					       child_handle_buffer[i]);
 			if (ret != EFI_SUCCESS)
-				return ret;
+				goto out;
 		}
-		return EFI_SUCCESS;
+		ret = EFI_SUCCESS;
+			goto out;
 	}
 
 	/* Destroy all children */
@@ -251,9 +249,9 @@
 		log_err("Cannot free EFI memory pool\n");
 
 	/* Detach driver from controller */
-	ret = EFI_CALL(systab.boottime->close_protocol(
-			controller_handle, bp->ops->protocol,
-			this->driver_binding_handle, controller_handle));
+	ret = efi_close_protocol(controller_handle, bp->ops->protocol,
+				 this->driver_binding_handle,
+				 controller_handle);
 out:
 	return EFI_EXIT(ret);
 }
diff --git a/lib/efi_loader/efi_boottime.c b/lib/efi_loader/efi_boottime.c
index e776d25..a560215 100644
--- a/lib/efi_loader/efi_boottime.c
+++ b/lib/efi_loader/efi_boottime.c
@@ -1993,7 +1993,7 @@
 	if (ret != EFI_SUCCESS)
 		efi_free_pages(addr, pages);
 out:
-	EFI_CALL(efi_close_protocol(device, guid, efi_root, NULL));
+	efi_close_protocol(device, guid, efi_root, NULL);
 	if (ret == EFI_SUCCESS) {
 		*buffer = (void *)(uintptr_t)addr;
 		*size = buffer_size;
@@ -2290,45 +2290,70 @@
  * @agent_handle:      handle of the driver
  * @controller_handle: handle of the controller
  *
- * This function implements the CloseProtocol service.
+ * This is the function implementing the CloseProtocol service is for internal
+ * usage in U-Boot. For API usage wrapper efi_close_protocol_ext() is provided.
  *
  * See the Unified Extensible Firmware Interface (UEFI) specification for
  * details.
  *
  * Return: status code
  */
-efi_status_t EFIAPI efi_close_protocol(efi_handle_t handle,
-				       const efi_guid_t *protocol,
-				       efi_handle_t agent_handle,
-				       efi_handle_t controller_handle)
+efi_status_t efi_close_protocol(efi_handle_t handle, const efi_guid_t *protocol,
+				efi_handle_t agent_handle,
+				efi_handle_t controller_handle)
 {
 	struct efi_handler *handler;
 	struct efi_open_protocol_info_item *item;
 	struct efi_open_protocol_info_item *pos;
-	efi_status_t r;
-
-	EFI_ENTRY("%p, %pUs, %p, %p", handle, protocol, agent_handle,
-		  controller_handle);
+	efi_status_t ret;
 
 	if (!efi_search_obj(agent_handle) ||
-	    (controller_handle && !efi_search_obj(controller_handle))) {
-		r = EFI_INVALID_PARAMETER;
-		goto out;
-	}
-	r = efi_search_protocol(handle, protocol, &handler);
-	if (r != EFI_SUCCESS)
-		goto out;
+	    (controller_handle && !efi_search_obj(controller_handle)))
+		return EFI_INVALID_PARAMETER;
+	ret = efi_search_protocol(handle, protocol, &handler);
+	if (ret != EFI_SUCCESS)
+		return ret;
 
-	r = EFI_NOT_FOUND;
+	ret = EFI_NOT_FOUND;
 	list_for_each_entry_safe(item, pos, &handler->open_infos, link) {
 		if (item->info.agent_handle == agent_handle &&
 		    item->info.controller_handle == controller_handle) {
 			efi_delete_open_info(item);
-			r = EFI_SUCCESS;
+			ret = EFI_SUCCESS;
 		}
 	}
-out:
-	return EFI_EXIT(r);
+
+	return ret;
+}
+
+/**
+ * efi_close_protocol_ext() - close a protocol
+ * @handle:            handle on which the protocol shall be closed
+ * @protocol:          GUID of the protocol to close
+ * @agent_handle:      handle of the driver
+ * @controller_handle: handle of the controller
+ *
+ * This function implements the CloseProtocol service.
+ *
+ * See the Unified Extensible Firmware Interface (UEFI) specification for
+ * details.
+ *
+ * Return: status code
+ */
+static efi_status_t EFIAPI
+efi_close_protocol_ext(efi_handle_t handle, const efi_guid_t *protocol,
+		       efi_handle_t agent_handle,
+		       efi_handle_t controller_handle)
+{
+	efi_status_t ret;
+
+	EFI_ENTRY("%p, %pUs, %p, %p", handle, protocol, agent_handle,
+		  controller_handle);
+
+	ret = efi_close_protocol(handle, protocol,
+				 agent_handle, controller_handle);
+
+	return EFI_EXIT(ret);
 }
 
 /**
@@ -3213,11 +3238,10 @@
 				if (info->info.agent_handle !=
 				    (efi_handle_t)image_obj)
 					continue;
-				r = EFI_CALL(efi_close_protocol
-						(efiobj, &protocol->guid,
-						 info->info.agent_handle,
-						 info->info.controller_handle
-						));
+				r = efi_close_protocol(
+						efiobj, &protocol->guid,
+						info->info.agent_handle,
+						info->info.controller_handle);
 				if (r !=  EFI_SUCCESS)
 					ret = r;
 				/*
@@ -3481,9 +3505,9 @@
 		r = EFI_CALL(binding_protocol->start(binding_protocol,
 						     controller_handle,
 						     remain_device_path));
-	EFI_CALL(efi_close_protocol(driver_image_handle,
-				    &efi_guid_driver_binding_protocol,
-				    driver_image_handle, NULL));
+	efi_close_protocol(driver_image_handle,
+			   &efi_guid_driver_binding_protocol,
+			   driver_image_handle, NULL);
 	return r;
 }
 
@@ -3834,9 +3858,9 @@
 			goto out;
 		}
 	}
-	EFI_CALL(efi_close_protocol(driver_image_handle,
-				    &efi_guid_driver_binding_protocol,
-				    driver_image_handle, NULL));
+	efi_close_protocol(driver_image_handle,
+			   &efi_guid_driver_binding_protocol,
+			   driver_image_handle, NULL);
 	r = EFI_SUCCESS;
 out:
 	if (!child_handle)
@@ -3883,7 +3907,7 @@
 	.connect_controller = efi_connect_controller,
 	.disconnect_controller = efi_disconnect_controller,
 	.open_protocol = efi_open_protocol,
-	.close_protocol = efi_close_protocol,
+	.close_protocol = efi_close_protocol_ext,
 	.open_protocol_information = efi_open_protocol_information,
 	.protocols_per_handle = efi_protocols_per_handle,
 	.locate_handle_buffer = efi_locate_handle_buffer,
diff --git a/lib/efi_loader/efi_capsule.c b/lib/efi_loader/efi_capsule.c
index b6bd2d6..397e393 100644
--- a/lib/efi_loader/efi_capsule.c
+++ b/lib/efi_loader/efi_capsule.c
@@ -159,12 +159,14 @@
 	efi_status_t ret;
 
 	for (i = 0, handle = handles; i < no_handles; i++, handle++) {
-		ret = EFI_CALL(efi_handle_protocol(
-				*handle,
-				&efi_guid_firmware_management_protocol,
-				(void **)&fmp));
+		struct efi_handler *fmp_handler;
+
+		ret = efi_search_protocol(
+				*handle, &efi_guid_firmware_management_protocol,
+				&fmp_handler);
 		if (ret != EFI_SUCCESS)
 			continue;
+		fmp = fmp_handler->protocol_interface;
 
 		/* get device's image info */
 		info_size = 0;
@@ -215,10 +217,6 @@
 skip:
 		efi_free_pool(package_version_name);
 		free(image_info);
-		EFI_CALL(efi_close_protocol(
-				(efi_handle_t)fmp,
-				&efi_guid_firmware_management_protocol,
-				NULL, NULL));
 		if (found)
 			return fmp;
 	}
diff --git a/lib/efi_loader/efi_disk.c b/lib/efi_loader/efi_disk.c
index e6a356b..cef4e45 100644
--- a/lib/efi_loader/efi_disk.c
+++ b/lib/efi_loader/efi_disk.c
@@ -395,7 +395,7 @@
 {
 	struct efi_disk_obj *diskobj;
 	struct efi_object *handle;
-	const efi_guid_t *guid = NULL;
+	const efi_guid_t *esp_guid = NULL;
 	efi_status_t ret;
 
 	/* Don't add empty devices */
@@ -439,7 +439,7 @@
 		efi_free_pool(node);
 		diskobj->media.last_block = part_info->size - 1;
 		if (part_info->bootable & PART_EFI_SYSTEM_PARTITION)
-			guid = &efi_system_partition_guid;
+			esp_guid = &efi_system_partition_guid;
 	} else {
 		diskobj->dp = efi_dp_from_part(desc, part);
 		diskobj->media.last_block = desc->lba - 1;
@@ -454,12 +454,16 @@
 	 * in this case.
 	 */
 	handle = &diskobj->header;
-	ret = efi_install_multiple_protocol_interfaces(&handle,
-						       &efi_guid_device_path,
-						       diskobj->dp,
-						       &efi_block_io_guid,
-						       &diskobj->ops, guid,
-						       NULL, NULL);
+	ret = efi_install_multiple_protocol_interfaces(
+					&handle,
+					&efi_guid_device_path, diskobj->dp,
+					&efi_block_io_guid, &diskobj->ops,
+					/*
+					 * esp_guid must be last entry as it
+					 * can be NULL. Its interface is NULL.
+					 */
+					esp_guid, NULL,
+					NULL);
 	if (ret != EFI_SUCCESS)
 		goto error;
 
@@ -786,7 +790,8 @@
 	if (is_partition) {
 		part_data = dev_get_uclass_plat(dev);
 		part = part_data->partnum;
-		count = snprintf(buf, size, "%s %d:%d", if_typename, diskid, part);
+		count = snprintf(buf, size, "%s %d:%u", if_typename, diskid,
+				 part);
 	} else {
 		count = snprintf(buf, size, "%s %d", if_typename, diskid);
 	}
diff --git a/lib/efi_loader/efi_load_options.c b/lib/efi_loader/efi_load_options.c
index 71454f0..3cfddee 100644
--- a/lib/efi_loader/efi_load_options.c
+++ b/lib/efi_loader/efi_load_options.c
@@ -27,23 +27,18 @@
 				  void *load_options)
 {
 	struct efi_loaded_image *loaded_image_info;
+	struct efi_handler *handler;
 	efi_status_t ret;
 
-	ret = EFI_CALL(systab.boottime->open_protocol(
-					handle,
-					&efi_guid_loaded_image,
-					(void **)&loaded_image_info,
-					efi_root, NULL,
-					EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL));
+	ret = efi_search_protocol(handle, &efi_guid_loaded_image, &handler);
+	loaded_image_info = handler->protocol_interface;
 	if (ret != EFI_SUCCESS)
 		return EFI_INVALID_PARAMETER;
 
 	loaded_image_info->load_options = load_options;
 	loaded_image_info->load_options_size = load_options_size;
 
-	return EFI_CALL(systab.boottime->close_protocol(handle,
-							&efi_guid_loaded_image,
-							efi_root, NULL));
+	return EFI_SUCCESS;
 }
 
 /**
diff --git a/lib/efi_loader/efi_tcg2.c b/lib/efi_loader/efi_tcg2.c
index 99ec3a5..a525ebf 100644
--- a/lib/efi_loader/efi_tcg2.c
+++ b/lib/efi_loader/efi_tcg2.c
@@ -2053,7 +2053,7 @@
 {
 	efi_status_t ret;
 	efi_handle_t handle;
-	struct efi_handler *dp_handler;
+	struct efi_handler *dp_handler, *io_handler;
 	struct efi_device_path *orig_device_path;
 	struct efi_device_path *device_path;
 	struct efi_device_path *dp;
@@ -2098,10 +2098,10 @@
 	if (ret != EFI_SUCCESS)
 		goto out1;
 
-	ret = EFI_CALL(efi_handle_protocol(handle,
-					   &efi_block_io_guid, (void **)&block_io));
+	ret = efi_search_protocol(handle, &efi_block_io_guid, &io_handler);
 	if (ret != EFI_SUCCESS)
 		goto out1;
+	block_io = io_handler->protocol_interface;
 
 	gpt_h = memalign(block_io->media->io_align, block_io->media->block_size);
 	if (!gpt_h) {
@@ -2164,12 +2164,8 @@
 	}
 
 	ret = tcg2_measure_event(dev, 5, EV_EFI_GPT_EVENT, event_size, (u8 *)event);
-	if (ret != EFI_SUCCESS)
-		goto out2;
 
 out2:
-	EFI_CALL(efi_close_protocol((efi_handle_t)block_io, &efi_block_io_guid,
-				    NULL, NULL));
 	free(gpt_h);
 	free(entry);
 	free(event);