v4.19.13 snapshot.
diff --git a/Documentation/usb/usbdevfs-drop-permissions.c b/Documentation/usb/usbdevfs-drop-permissions.c
new file mode 100644
index 0000000..6b8da6e
--- /dev/null
+++ b/Documentation/usb/usbdevfs-drop-permissions.c
@@ -0,0 +1,120 @@
+#include <sys/ioctl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <errno.h>
+#include <string.h>
+#include <inttypes.h>
+#include <unistd.h>
+
+#include <linux/usbdevice_fs.h>
+
+/* For building without an updated set of headers */
+#ifndef USBDEVFS_DROP_PRIVILEGES
+#define USBDEVFS_DROP_PRIVILEGES		_IOW('U', 30, __u32)
+#define USBDEVFS_CAP_DROP_PRIVILEGES		0x40
+#endif
+
+void drop_privileges(int fd, uint32_t mask)
+{
+	int res;
+
+	res = ioctl(fd, USBDEVFS_DROP_PRIVILEGES, &mask);
+	if (res)
+		printf("ERROR: USBDEVFS_DROP_PRIVILEGES returned %d\n", res);
+	else
+		printf("OK: privileges dropped!\n");
+}
+
+void reset_device(int fd)
+{
+	int res;
+
+	res = ioctl(fd, USBDEVFS_RESET);
+	if (!res)
+		printf("OK: USBDEVFS_RESET succeeded\n");
+	else
+		printf("ERROR: reset failed! (%d - %s)\n",
+		       -res, strerror(-res));
+}
+
+void claim_some_intf(int fd)
+{
+	int i, res;
+
+	for (i = 0; i < 4; i++) {
+		res = ioctl(fd, USBDEVFS_CLAIMINTERFACE, &i);
+		if (!res)
+			printf("OK: claimed if %d\n", i);
+		else
+			printf("ERROR claiming if %d (%d - %s)\n",
+			       i, -res, strerror(-res));
+	}
+}
+
+int main(int argc, char *argv[])
+{
+	uint32_t mask, caps;
+	int c, fd;
+
+	fd = open(argv[1], O_RDWR);
+	if (fd < 0) {
+		printf("Failed to open file\n");
+		goto err_fd;
+	}
+
+	/*
+	 * check if dropping privileges is supported,
+	 * bail on systems where the capability is not present
+	 */
+	ioctl(fd, USBDEVFS_GET_CAPABILITIES, &caps);
+	if (!(caps & USBDEVFS_CAP_DROP_PRIVILEGES)) {
+		printf("DROP_PRIVILEGES not supported\n");
+		goto err;
+	}
+
+	/*
+	 * Drop privileges but keep the ability to claim all
+	 * free interfaces (i.e., those not used by kernel drivers)
+	 */
+	drop_privileges(fd, -1U);
+
+	printf("Available options:\n"
+		"[0] Exit now\n"
+		"[1] Reset device. Should fail if device is in use\n"
+		"[2] Claim 4 interfaces. Should succeed where not in use\n"
+		"[3] Narrow interface permission mask\n"
+		"Which option shall I run?: ");
+
+	while (scanf("%d", &c) == 1) {
+		switch (c) {
+		case 0:
+			goto exit;
+		case 1:
+			reset_device(fd);
+			break;
+		case 2:
+			claim_some_intf(fd);
+			break;
+		case 3:
+			printf("Insert new mask: ");
+			scanf("%x", &mask);
+			drop_privileges(fd, mask);
+			break;
+		default:
+			printf("I don't recognize that\n");
+		}
+
+		printf("Which test shall I run next?: ");
+	}
+
+exit:
+	close(fd);
+	return 0;
+
+err:
+	close(fd);
+err_fd:
+	return 1;
+}