From 901b46bf605a553a6edea4722028eed9cf07b23a Mon Sep 17 00:00:00 2001 From: Martin Kepplinger Date: Fri, 8 Apr 2022 10:45:56 +0200 Subject: [PATCH] hack: usb: add quirk to skip reset_resume in hub_activate() For devices with AVOID_RESET_RESUME set, dont set reset_resume in hub_activate() but (from hub_resume()) but let it be set later via port_resume() only. This is a hacky workaround to improve stability when a permanently connected device acts like it's disconnected from the hubs' port. Since we see this for the BM818 modem, enable the quirk there. --- drivers/usb/core/hub.c | 5 ++++- drivers/usb/core/quirks.c | 4 ++++ include/linux/usb/quirks.h | 6 ++++++ 3 files changed, 14 insertions(+), 1 deletion(-) diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index ac6c5ccfe1cb..ee25ad4a91e9 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -1232,7 +1232,10 @@ static void hub_activate(struct usb_hub *hub, enum hub_activation_type type) } else if (udev->persist_enabled) { #ifdef CONFIG_PM - udev->reset_resume = 1; + if (udev->quirks & USB_QUIRK_AVOID_RESET_RESUME) + dev_warn(&port_dev->dev, "QUIRK: skip setting reset_resume.\n"); + else + udev->reset_resume = 1; #endif /* Don't set the change_bits when the device * was powered off. diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c index f77a6399e1c8..8eed0615949f 100644 --- a/drivers/usb/core/quirks.c +++ b/drivers/usb/core/quirks.c @@ -487,6 +487,10 @@ static const struct usb_device_id usb_quirk_list[] = { { USB_DEVICE(0x1c75, 0x0204), .driver_info = USB_QUIRK_CONFIG_INTF_STRINGS }, + /* Broadmobi 818 4G modem */ + { USB_DEVICE(0x2020, 0x2060), .driver_info = + USB_QUIRK_AVOID_RESET_RESUME }, + /* Acer C120 LED Projector */ { USB_DEVICE(0x1de1, 0xc102), .driver_info = USB_QUIRK_NO_LPM }, diff --git a/include/linux/usb/quirks.h b/include/linux/usb/quirks.h index eeb7c2157c72..c2f358c5394a 100644 --- a/include/linux/usb/quirks.h +++ b/include/linux/usb/quirks.h @@ -72,4 +72,10 @@ /* device has endpoints that should be ignored */ #define USB_QUIRK_ENDPOINT_IGNORE BIT(15) +/* + * Avoid resetting a port/device when it reports to be disconnected. Use + * this for permanently (on-board) connected devices only. + */ +#define USB_QUIRK_AVOID_RESET_RESUME BIT(16) + #endif /* __LINUX_USB_QUIRKS_H */ -- 2.35.1