Skip to content

Commit 23a3b8d

Browse files
matnymangregkh
authored andcommitted
xhci: Add update_hub_device override for PCI xHCI hosts
Allow PCI hosts to check and tune roothub and port settings before the hub is up and running. This override is needed to turn off U1 and U2 LPM for some ports based on per port ACPI _DSM, _UPC, or possibly vendor specific mmio values for Intel xHC hosts. Usb core calls the host update_hub_device once it creates a hub. Entering U1 or U2 link power save state on ports with this limitation will cause link to fail, turning the usb device unusable in that setup. Cc: [email protected] Signed-off-by: Mathias Nyman <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent a2bc47c commit 23a3b8d

File tree

3 files changed

+17
-1
lines changed

3 files changed

+17
-1
lines changed

drivers/usb/host/xhci-pci.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,9 +78,12 @@ static const char hcd_name[] = "xhci_hcd";
7878
static struct hc_driver __read_mostly xhci_pci_hc_driver;
7979

8080
static int xhci_pci_setup(struct usb_hcd *hcd);
81+
static int xhci_pci_update_hub_device(struct usb_hcd *hcd, struct usb_device *hdev,
82+
struct usb_tt *tt, gfp_t mem_flags);
8183

8284
static const struct xhci_driver_overrides xhci_pci_overrides __initconst = {
8385
.reset = xhci_pci_setup,
86+
.update_hub_device = xhci_pci_update_hub_device,
8487
};
8588

8689
/* called after powerup, by probe or system-pm "wakeup" */
@@ -386,6 +389,12 @@ static int xhci_pci_setup(struct usb_hcd *hcd)
386389
return xhci_pci_reinit(xhci, pdev);
387390
}
388391

392+
static int xhci_pci_update_hub_device(struct usb_hcd *hcd, struct usb_device *hdev,
393+
struct usb_tt *tt, gfp_t mem_flags)
394+
{
395+
return xhci_update_hub_device(hcd, hdev, tt, mem_flags);
396+
}
397+
389398
/*
390399
* We need to register our own PCI probe function (instead of the USB core's
391400
* function) in order to create a second roothub under xHCI.

drivers/usb/host/xhci.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5124,7 +5124,7 @@ static int xhci_disable_usb3_lpm_timeout(struct usb_hcd *hcd,
51245124
/* Once a hub descriptor is fetched for a device, we need to update the xHC's
51255125
* internal data structures for the device.
51265126
*/
5127-
static int xhci_update_hub_device(struct usb_hcd *hcd, struct usb_device *hdev,
5127+
int xhci_update_hub_device(struct usb_hcd *hcd, struct usb_device *hdev,
51285128
struct usb_tt *tt, gfp_t mem_flags)
51295129
{
51305130
struct xhci_hcd *xhci = hcd_to_xhci(hcd);
@@ -5224,6 +5224,7 @@ static int xhci_update_hub_device(struct usb_hcd *hcd, struct usb_device *hdev,
52245224
xhci_free_command(xhci, config_cmd);
52255225
return ret;
52265226
}
5227+
EXPORT_SYMBOL_GPL(xhci_update_hub_device);
52275228

52285229
static int xhci_get_frame(struct usb_hcd *hcd)
52295230
{
@@ -5507,6 +5508,8 @@ void xhci_init_driver(struct hc_driver *drv,
55075508
drv->check_bandwidth = over->check_bandwidth;
55085509
if (over->reset_bandwidth)
55095510
drv->reset_bandwidth = over->reset_bandwidth;
5511+
if (over->update_hub_device)
5512+
drv->update_hub_device = over->update_hub_device;
55105513
}
55115514
}
55125515
EXPORT_SYMBOL_GPL(xhci_init_driver);

drivers/usb/host/xhci.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1943,6 +1943,8 @@ struct xhci_driver_overrides {
19431943
struct usb_host_endpoint *ep);
19441944
int (*check_bandwidth)(struct usb_hcd *, struct usb_device *);
19451945
void (*reset_bandwidth)(struct usb_hcd *, struct usb_device *);
1946+
int (*update_hub_device)(struct usb_hcd *hcd, struct usb_device *hdev,
1947+
struct usb_tt *tt, gfp_t mem_flags);
19461948
};
19471949

19481950
#define XHCI_CFC_DELAY 10
@@ -2122,6 +2124,8 @@ int xhci_drop_endpoint(struct usb_hcd *hcd, struct usb_device *udev,
21222124
struct usb_host_endpoint *ep);
21232125
int xhci_check_bandwidth(struct usb_hcd *hcd, struct usb_device *udev);
21242126
void xhci_reset_bandwidth(struct usb_hcd *hcd, struct usb_device *udev);
2127+
int xhci_update_hub_device(struct usb_hcd *hcd, struct usb_device *hdev,
2128+
struct usb_tt *tt, gfp_t mem_flags);
21252129
int xhci_disable_slot(struct xhci_hcd *xhci, u32 slot_id);
21262130
int xhci_ext_cap_init(struct xhci_hcd *xhci);
21272131

0 commit comments

Comments
 (0)