Skip to content

Commit 202ad1a

Browse files
Russell King (Oracle)gregkh
authored andcommitted
usb: gadget: tegra-xudc: fix PM use count underflow
Upon resume from system suspend, the PM runtime core issues the following warning: tegra-xudc 3550000.usb: Runtime PM usage count underflow! This is because tegra_xudc_resume() unconditionally calls schedule_work(&xudc->usb_role_sw_work) whether or not anything has changed, which causes tegra_xudc_device_mode_off() to be called even when we're already in that mode. Keep track of the current state of "device_mode", and only schedule this work if it has changed from the hardware state on resume. Signed-off-by: "Russell King (Oracle)" <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent e664036 commit 202ad1a

File tree

1 file changed

+7
-2
lines changed

1 file changed

+7
-2
lines changed

drivers/usb/gadget/udc/tegra-xudc.c

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -502,6 +502,7 @@ struct tegra_xudc {
502502
struct clk_bulk_data *clks;
503503

504504
bool device_mode;
505+
bool current_device_mode;
505506
struct work_struct usb_role_sw_work;
506507

507508
struct phy **usb3_phy;
@@ -715,6 +716,8 @@ static void tegra_xudc_device_mode_on(struct tegra_xudc *xudc)
715716

716717
phy_set_mode_ext(xudc->curr_utmi_phy, PHY_MODE_USB_OTG,
717718
USB_ROLE_DEVICE);
719+
720+
xudc->current_device_mode = true;
718721
}
719722

720723
static void tegra_xudc_device_mode_off(struct tegra_xudc *xudc)
@@ -725,6 +728,8 @@ static void tegra_xudc_device_mode_off(struct tegra_xudc *xudc)
725728

726729
dev_dbg(xudc->dev, "device mode off\n");
727730

731+
xudc->current_device_mode = false;
732+
728733
connected = !!(xudc_readl(xudc, PORTSC) & PORTSC_CCS);
729734

730735
reinit_completion(&xudc->disconnect_complete);
@@ -4044,10 +4049,10 @@ static int __maybe_unused tegra_xudc_resume(struct device *dev)
40444049

40454050
spin_lock_irqsave(&xudc->lock, flags);
40464051
xudc->suspended = false;
4052+
if (xudc->device_mode != xudc->current_device_mode)
4053+
schedule_work(&xudc->usb_role_sw_work);
40474054
spin_unlock_irqrestore(&xudc->lock, flags);
40484055

4049-
schedule_work(&xudc->usb_role_sw_work);
4050-
40514056
pm_runtime_enable(dev);
40524057

40534058
return 0;

0 commit comments

Comments
 (0)