summaryrefslogtreecommitdiff
path: root/drivers/usb/gadget/udc/tegra-xudc.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/gadget/udc/tegra-xudc.c')
-rw-r--r--drivers/usb/gadget/udc/tegra-xudc.c24
1 files changed, 13 insertions, 11 deletions
diff --git a/drivers/usb/gadget/udc/tegra-xudc.c b/drivers/usb/gadget/udc/tegra-xudc.c
index 7aa46d426f31..9d2007f448c0 100644
--- a/drivers/usb/gadget/udc/tegra-xudc.c
+++ b/drivers/usb/gadget/udc/tegra-xudc.c
@@ -502,6 +502,7 @@ struct tegra_xudc {
struct clk_bulk_data *clks;
bool device_mode;
+ bool current_device_mode;
struct work_struct usb_role_sw_work;
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,
USB_ROLE_DEVICE);
+
+ xudc->current_device_mode = true;
}
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");
+ xudc->current_device_mode = false;
+
connected = !!(xudc_readl(xudc, PORTSC) & PORTSC_CCS);
reinit_completion(&xudc->disconnect_complete);
@@ -807,8 +812,7 @@ static void tegra_xudc_update_data_role(struct tegra_xudc *xudc,
return;
}
- xudc->device_mode = (usbphy->last_event == USB_EVENT_VBUS) ? true :
- false;
+ xudc->device_mode = usbphy->last_event == USB_EVENT_VBUS;
phy_index = tegra_xudc_get_phy_index(xudc, usbphy);
dev_dbg(xudc->dev, "%s(): current phy index is %d\n", __func__,
@@ -1554,12 +1558,6 @@ static int __tegra_xudc_ep_set_halt(struct tegra_xudc_ep *ep, bool halt)
return -ENOTSUPP;
}
- if (!!(xudc_readl(xudc, EP_HALT) & BIT(ep->index)) == halt) {
- dev_dbg(xudc->dev, "EP %u already %s\n", ep->index,
- halt ? "halted" : "not halted");
- return 0;
- }
-
if (halt) {
ep_halt(xudc, ep->index);
} else {
@@ -1749,6 +1747,10 @@ static int __tegra_xudc_ep_disable(struct tegra_xudc_ep *ep)
val = xudc_readl(xudc, CTRL);
val &= ~CTRL_RUN;
xudc_writel(xudc, val, CTRL);
+
+ val = xudc_readl(xudc, ST);
+ if (val & ST_RC)
+ xudc_writel(xudc, ST_RC, ST);
}
dev_info(xudc->dev, "ep %u disabled\n", ep->index);
@@ -4040,10 +4042,10 @@ static int __maybe_unused tegra_xudc_resume(struct device *dev)
spin_lock_irqsave(&xudc->lock, flags);
xudc->suspended = false;
+ if (xudc->device_mode != xudc->current_device_mode)
+ schedule_work(&xudc->usb_role_sw_work);
spin_unlock_irqrestore(&xudc->lock, flags);
- schedule_work(&xudc->usb_role_sw_work);
-
pm_runtime_enable(dev);
return 0;
@@ -4071,7 +4073,7 @@ static const struct dev_pm_ops tegra_xudc_pm_ops = {
static struct platform_driver tegra_xudc_driver = {
.probe = tegra_xudc_probe,
- .remove_new = tegra_xudc_remove,
+ .remove = tegra_xudc_remove,
.driver = {
.name = "tegra-xudc",
.pm = &tegra_xudc_pm_ops,