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)" <rmk+kernel@armlinux.org.uk> Link: https://lore.kernel.org/r/E1uhtkH-007KDZ-JT@rmk-PC.armlinux.org.uk Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>pull/1322/head
parent
e664036cf3
commit
202ad1aaca
|
|
@ -502,6 +502,7 @@ struct tegra_xudc {
|
||||||
struct clk_bulk_data *clks;
|
struct clk_bulk_data *clks;
|
||||||
|
|
||||||
bool device_mode;
|
bool device_mode;
|
||||||
|
bool current_device_mode;
|
||||||
struct work_struct usb_role_sw_work;
|
struct work_struct usb_role_sw_work;
|
||||||
|
|
||||||
struct phy **usb3_phy;
|
struct phy **usb3_phy;
|
||||||
|
|
@ -715,6 +716,8 @@ static void tegra_xudc_device_mode_on(struct tegra_xudc *xudc)
|
||||||
|
|
||||||
phy_set_mode_ext(xudc->curr_utmi_phy, PHY_MODE_USB_OTG,
|
phy_set_mode_ext(xudc->curr_utmi_phy, PHY_MODE_USB_OTG,
|
||||||
USB_ROLE_DEVICE);
|
USB_ROLE_DEVICE);
|
||||||
|
|
||||||
|
xudc->current_device_mode = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void tegra_xudc_device_mode_off(struct tegra_xudc *xudc)
|
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)
|
||||||
|
|
||||||
dev_dbg(xudc->dev, "device mode off\n");
|
dev_dbg(xudc->dev, "device mode off\n");
|
||||||
|
|
||||||
|
xudc->current_device_mode = false;
|
||||||
|
|
||||||
connected = !!(xudc_readl(xudc, PORTSC) & PORTSC_CCS);
|
connected = !!(xudc_readl(xudc, PORTSC) & PORTSC_CCS);
|
||||||
|
|
||||||
reinit_completion(&xudc->disconnect_complete);
|
reinit_completion(&xudc->disconnect_complete);
|
||||||
|
|
@ -4044,10 +4049,10 @@ static int __maybe_unused tegra_xudc_resume(struct device *dev)
|
||||||
|
|
||||||
spin_lock_irqsave(&xudc->lock, flags);
|
spin_lock_irqsave(&xudc->lock, flags);
|
||||||
xudc->suspended = false;
|
xudc->suspended = false;
|
||||||
|
if (xudc->device_mode != xudc->current_device_mode)
|
||||||
|
schedule_work(&xudc->usb_role_sw_work);
|
||||||
spin_unlock_irqrestore(&xudc->lock, flags);
|
spin_unlock_irqrestore(&xudc->lock, flags);
|
||||||
|
|
||||||
schedule_work(&xudc->usb_role_sw_work);
|
|
||||||
|
|
||||||
pm_runtime_enable(dev);
|
pm_runtime_enable(dev);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue