The patches were generated from the RPi repo with the following command: git format-patch v6.6.34..rpi-6.1.y Some patches needed rebasing and, as usual, the applied and reverted, wireless drivers, Github workflows, READMEs and defconfigs patches were removed. Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
		
			
				
	
	
		
			105 lines
		
	
	
		
			3.9 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
			
		
		
	
	
			105 lines
		
	
	
		
			3.9 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
From 7c517e79b6ef29b331221829a125d816b87e8d02 Mon Sep 17 00:00:00 2001
 | 
						|
From: Jonathan Bell <jonathan@raspberrypi.org>
 | 
						|
Date: Tue, 11 Jun 2019 10:55:00 +0100
 | 
						|
Subject: [PATCH 1059/1085] usb: add plumbing for updating interrupt endpoint
 | 
						|
 interval state
 | 
						|
 | 
						|
xHCI caches device and endpoint data after the interface is configured,
 | 
						|
so an explicit command needs to be issued for any device driver wanting
 | 
						|
to alter the polling interval of an endpoint.
 | 
						|
 | 
						|
Add usb_fixup_endpoint() to allow drivers to do this. The fixup must be
 | 
						|
called after calculating endpoint bandwidth requirements but before any
 | 
						|
URBs are submitted.
 | 
						|
 | 
						|
If polling intervals are shortened, any bandwidth reservations are no
 | 
						|
longer valid but in practice polling intervals are only ever relaxed.
 | 
						|
 | 
						|
Limit the scope to interrupt transfers for now.
 | 
						|
 | 
						|
Signed-off-by: Jonathan Bell <jonathan@raspberrypi.org>
 | 
						|
---
 | 
						|
 drivers/usb/core/hcd.c     | 10 ++++++++++
 | 
						|
 drivers/usb/core/message.c | 15 +++++++++++++++
 | 
						|
 include/linux/usb.h        |  2 ++
 | 
						|
 include/linux/usb/hcd.h    |  7 +++++++
 | 
						|
 4 files changed, 34 insertions(+)
 | 
						|
 | 
						|
--- a/drivers/usb/core/hcd.c
 | 
						|
+++ b/drivers/usb/core/hcd.c
 | 
						|
@@ -1952,6 +1952,16 @@ reset:
 | 
						|
 	return ret;
 | 
						|
 }
 | 
						|
 
 | 
						|
+void usb_hcd_fixup_endpoint(struct usb_device *udev,
 | 
						|
+			    struct usb_host_endpoint *ep, int interval)
 | 
						|
+{
 | 
						|
+	struct usb_hcd *hcd;
 | 
						|
+
 | 
						|
+	hcd = bus_to_hcd(udev->bus);
 | 
						|
+	if (hcd->driver->fixup_endpoint)
 | 
						|
+		hcd->driver->fixup_endpoint(hcd, udev, ep, interval);
 | 
						|
+}
 | 
						|
+
 | 
						|
 /* Disables the endpoint: synchronizes with the hcd to make sure all
 | 
						|
  * endpoint state is gone from hardware.  usb_hcd_flush_endpoint() must
 | 
						|
  * have been called previously.  Use for set_configuration, set_interface,
 | 
						|
--- a/drivers/usb/core/message.c
 | 
						|
+++ b/drivers/usb/core/message.c
 | 
						|
@@ -1265,6 +1265,21 @@ static void remove_intf_ep_devs(struct u
 | 
						|
 	intf->ep_devs_created = 0;
 | 
						|
 }
 | 
						|
 
 | 
						|
+void usb_fixup_endpoint(struct usb_device *dev, int epaddr, int interval)
 | 
						|
+{
 | 
						|
+	unsigned int epnum = epaddr & USB_ENDPOINT_NUMBER_MASK;
 | 
						|
+	struct usb_host_endpoint *ep;
 | 
						|
+
 | 
						|
+	if (usb_endpoint_out(epaddr))
 | 
						|
+		ep = dev->ep_out[epnum];
 | 
						|
+	else
 | 
						|
+		ep = dev->ep_in[epnum];
 | 
						|
+
 | 
						|
+	if (ep && usb_endpoint_xfer_int(&ep->desc))
 | 
						|
+		usb_hcd_fixup_endpoint(dev, ep, interval);
 | 
						|
+}
 | 
						|
+EXPORT_SYMBOL_GPL(usb_fixup_endpoint);
 | 
						|
+
 | 
						|
 /**
 | 
						|
  * usb_disable_endpoint -- Disable an endpoint by address
 | 
						|
  * @dev: the device whose endpoint is being disabled
 | 
						|
--- a/include/linux/usb.h
 | 
						|
+++ b/include/linux/usb.h
 | 
						|
@@ -1888,6 +1888,8 @@ extern int usb_clear_halt(struct usb_dev
 | 
						|
 extern int usb_reset_configuration(struct usb_device *dev);
 | 
						|
 extern int usb_set_interface(struct usb_device *dev, int ifnum, int alternate);
 | 
						|
 extern void usb_reset_endpoint(struct usb_device *dev, unsigned int epaddr);
 | 
						|
+extern void usb_fixup_endpoint(struct usb_device *dev, int epaddr,
 | 
						|
+			       int interval);
 | 
						|
 
 | 
						|
 /* this request isn't really synchronous, but it belongs with the others */
 | 
						|
 extern int usb_driver_set_configuration(struct usb_device *udev, int config);
 | 
						|
--- a/include/linux/usb/hcd.h
 | 
						|
+++ b/include/linux/usb/hcd.h
 | 
						|
@@ -372,6 +372,11 @@ struct hc_driver {
 | 
						|
 		 * or bandwidth constraints.
 | 
						|
 		 */
 | 
						|
 	void	(*reset_bandwidth)(struct usb_hcd *, struct usb_device *);
 | 
						|
+		/* Override the endpoint-derived interval
 | 
						|
+		 * (if there is any cached hardware state).
 | 
						|
+		 */
 | 
						|
+	void	(*fixup_endpoint)(struct usb_hcd *hcd, struct usb_device *udev,
 | 
						|
+				  struct usb_host_endpoint *ep, int interval);
 | 
						|
 		/* Set the hardware-chosen device address */
 | 
						|
 	int	(*address_device)(struct usb_hcd *, struct usb_device *udev,
 | 
						|
 				  unsigned int timeout_ms);
 | 
						|
@@ -437,6 +442,8 @@ extern void usb_hcd_unmap_urb_setup_for_
 | 
						|
 extern void usb_hcd_unmap_urb_for_dma(struct usb_hcd *, struct urb *);
 | 
						|
 extern void usb_hcd_flush_endpoint(struct usb_device *udev,
 | 
						|
 		struct usb_host_endpoint *ep);
 | 
						|
+extern void usb_hcd_fixup_endpoint(struct usb_device *udev,
 | 
						|
+		struct usb_host_endpoint *ep, int interval);
 | 
						|
 extern void usb_hcd_disable_endpoint(struct usb_device *udev,
 | 
						|
 		struct usb_host_endpoint *ep);
 | 
						|
 extern void usb_hcd_reset_endpoint(struct usb_device *udev,
 |