Commit ba2cacc1 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'usb-5.16-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb

Pull USB fixes from Greg KH:
 "Here are a number of small USB fixes for reported problems for
  5.16-rc3

  They include:

   - typec driver fixes

   - new usb-serial driver ids

   - usb hub enumeration issues that were much reported

   - gadget driver fixes

   - dwc3 driver fix

   - chipidea driver fixe

  All of these have been in linux-next with no reported problems"

* tag 'usb-5.16-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb:
  USB: serial: option: add Fibocom FM101-GL variants
  usb: typec: tipd: Fix initialization sequence for cd321x
  usb: typec: tipd: Fix typo in cd321x_switch_power_state
  usb: hub: Fix locking issues with address0_mutex
  USB: serial: pl2303: fix GC type detection
  USB: serial: option: add Telit LE910S1 0x9200 composition
  usb: chipidea: ci_hdrc_imx: fix potential error pointer dereference in probe
  usb: hub: Fix usb enumeration issue due to address0 race
  usb: typec: fusb302: Fix masking of comparator and bc_lvl interrupts
  usb: dwc3: leave default DMA for PCI devices
  usb: dwc2: hcd_queue: Fix use of floating point literal
  usb: dwc3: gadget: Fix null pointer exception
  usb: gadget: udc-xilinx: Fix an error handling path in 'xudc_probe()'
  usb: xhci: tegra: Check padctrl interrupt presence in device tree
  usb: dwc2: gadget: Fix ISOC flow for elapsed frames
  usb: dwc3: gadget: Check for L1/L2/U3 for Start Transfer
  usb: dwc3: gadget: Ignore NoStream after End Transfer
  usb: dwc3: core: Revise GHWPARAMS9 offset
parents d3e64792 a88db2ec
...@@ -420,15 +420,15 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev) ...@@ -420,15 +420,15 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev)
data->phy = devm_usb_get_phy_by_phandle(dev, "fsl,usbphy", 0); data->phy = devm_usb_get_phy_by_phandle(dev, "fsl,usbphy", 0);
if (IS_ERR(data->phy)) { if (IS_ERR(data->phy)) {
ret = PTR_ERR(data->phy); ret = PTR_ERR(data->phy);
if (ret == -ENODEV) { if (ret != -ENODEV)
data->phy = devm_usb_get_phy_by_phandle(dev, "phys", 0); goto err_clk;
if (IS_ERR(data->phy)) { data->phy = devm_usb_get_phy_by_phandle(dev, "phys", 0);
ret = PTR_ERR(data->phy); if (IS_ERR(data->phy)) {
if (ret == -ENODEV) ret = PTR_ERR(data->phy);
data->phy = NULL; if (ret == -ENODEV)
else data->phy = NULL;
goto err_clk; else
} goto err_clk;
} }
} }
......
...@@ -4700,8 +4700,6 @@ hub_port_init(struct usb_hub *hub, struct usb_device *udev, int port1, ...@@ -4700,8 +4700,6 @@ hub_port_init(struct usb_hub *hub, struct usb_device *udev, int port1,
if (oldspeed == USB_SPEED_LOW) if (oldspeed == USB_SPEED_LOW)
delay = HUB_LONG_RESET_TIME; delay = HUB_LONG_RESET_TIME;
mutex_lock(hcd->address0_mutex);
/* Reset the device; full speed may morph to high speed */ /* Reset the device; full speed may morph to high speed */
/* FIXME a USB 2.0 device may morph into SuperSpeed on reset. */ /* FIXME a USB 2.0 device may morph into SuperSpeed on reset. */
retval = hub_port_reset(hub, port1, udev, delay, false); retval = hub_port_reset(hub, port1, udev, delay, false);
...@@ -5016,7 +5014,6 @@ hub_port_init(struct usb_hub *hub, struct usb_device *udev, int port1, ...@@ -5016,7 +5014,6 @@ hub_port_init(struct usb_hub *hub, struct usb_device *udev, int port1,
hub_port_disable(hub, port1, 0); hub_port_disable(hub, port1, 0);
update_devnum(udev, devnum); /* for disconnect processing */ update_devnum(udev, devnum); /* for disconnect processing */
} }
mutex_unlock(hcd->address0_mutex);
return retval; return retval;
} }
...@@ -5191,6 +5188,7 @@ static void hub_port_connect(struct usb_hub *hub, int port1, u16 portstatus, ...@@ -5191,6 +5188,7 @@ static void hub_port_connect(struct usb_hub *hub, int port1, u16 portstatus,
struct usb_port *port_dev = hub->ports[port1 - 1]; struct usb_port *port_dev = hub->ports[port1 - 1];
struct usb_device *udev = port_dev->child; struct usb_device *udev = port_dev->child;
static int unreliable_port = -1; static int unreliable_port = -1;
bool retry_locked;
/* Disconnect any existing devices under this port */ /* Disconnect any existing devices under this port */
if (udev) { if (udev) {
...@@ -5246,8 +5244,11 @@ static void hub_port_connect(struct usb_hub *hub, int port1, u16 portstatus, ...@@ -5246,8 +5244,11 @@ static void hub_port_connect(struct usb_hub *hub, int port1, u16 portstatus,
unit_load = 100; unit_load = 100;
status = 0; status = 0;
for (i = 0; i < PORT_INIT_TRIES; i++) {
for (i = 0; i < PORT_INIT_TRIES; i++) {
usb_lock_port(port_dev);
mutex_lock(hcd->address0_mutex);
retry_locked = true;
/* reallocate for each attempt, since references /* reallocate for each attempt, since references
* to the previous one can escape in various ways * to the previous one can escape in various ways
*/ */
...@@ -5255,6 +5256,8 @@ static void hub_port_connect(struct usb_hub *hub, int port1, u16 portstatus, ...@@ -5255,6 +5256,8 @@ static void hub_port_connect(struct usb_hub *hub, int port1, u16 portstatus,
if (!udev) { if (!udev) {
dev_err(&port_dev->dev, dev_err(&port_dev->dev,
"couldn't allocate usb_device\n"); "couldn't allocate usb_device\n");
mutex_unlock(hcd->address0_mutex);
usb_unlock_port(port_dev);
goto done; goto done;
} }
...@@ -5276,12 +5279,14 @@ static void hub_port_connect(struct usb_hub *hub, int port1, u16 portstatus, ...@@ -5276,12 +5279,14 @@ static void hub_port_connect(struct usb_hub *hub, int port1, u16 portstatus,
} }
/* reset (non-USB 3.0 devices) and get descriptor */ /* reset (non-USB 3.0 devices) and get descriptor */
usb_lock_port(port_dev);
status = hub_port_init(hub, udev, port1, i); status = hub_port_init(hub, udev, port1, i);
usb_unlock_port(port_dev);
if (status < 0) if (status < 0)
goto loop; goto loop;
mutex_unlock(hcd->address0_mutex);
usb_unlock_port(port_dev);
retry_locked = false;
if (udev->quirks & USB_QUIRK_DELAY_INIT) if (udev->quirks & USB_QUIRK_DELAY_INIT)
msleep(2000); msleep(2000);
...@@ -5374,6 +5379,10 @@ static void hub_port_connect(struct usb_hub *hub, int port1, u16 portstatus, ...@@ -5374,6 +5379,10 @@ static void hub_port_connect(struct usb_hub *hub, int port1, u16 portstatus,
usb_ep0_reinit(udev); usb_ep0_reinit(udev);
release_devnum(udev); release_devnum(udev);
hub_free_dev(udev); hub_free_dev(udev);
if (retry_locked) {
mutex_unlock(hcd->address0_mutex);
usb_unlock_port(port_dev);
}
usb_put_dev(udev); usb_put_dev(udev);
if ((status == -ENOTCONN) || (status == -ENOTSUPP)) if ((status == -ENOTCONN) || (status == -ENOTSUPP))
break; break;
...@@ -5915,6 +5924,8 @@ static int usb_reset_and_verify_device(struct usb_device *udev) ...@@ -5915,6 +5924,8 @@ static int usb_reset_and_verify_device(struct usb_device *udev)
bos = udev->bos; bos = udev->bos;
udev->bos = NULL; udev->bos = NULL;
mutex_lock(hcd->address0_mutex);
for (i = 0; i < PORT_INIT_TRIES; ++i) { for (i = 0; i < PORT_INIT_TRIES; ++i) {
/* ep0 maxpacket size may change; let the HCD know about it. /* ep0 maxpacket size may change; let the HCD know about it.
...@@ -5924,6 +5935,7 @@ static int usb_reset_and_verify_device(struct usb_device *udev) ...@@ -5924,6 +5935,7 @@ static int usb_reset_and_verify_device(struct usb_device *udev)
if (ret >= 0 || ret == -ENOTCONN || ret == -ENODEV) if (ret >= 0 || ret == -ENOTCONN || ret == -ENODEV)
break; break;
} }
mutex_unlock(hcd->address0_mutex);
if (ret < 0) if (ret < 0)
goto re_enumerate; goto re_enumerate;
......
...@@ -1198,6 +1198,8 @@ static void dwc2_hsotg_start_req(struct dwc2_hsotg *hsotg, ...@@ -1198,6 +1198,8 @@ static void dwc2_hsotg_start_req(struct dwc2_hsotg *hsotg,
} }
ctrl |= DXEPCTL_CNAK; ctrl |= DXEPCTL_CNAK;
} else { } else {
hs_req->req.frame_number = hs_ep->target_frame;
hs_req->req.actual = 0;
dwc2_hsotg_complete_request(hsotg, hs_ep, hs_req, -ENODATA); dwc2_hsotg_complete_request(hsotg, hs_ep, hs_req, -ENODATA);
return; return;
} }
...@@ -2857,9 +2859,12 @@ static void dwc2_gadget_handle_ep_disabled(struct dwc2_hsotg_ep *hs_ep) ...@@ -2857,9 +2859,12 @@ static void dwc2_gadget_handle_ep_disabled(struct dwc2_hsotg_ep *hs_ep)
do { do {
hs_req = get_ep_head(hs_ep); hs_req = get_ep_head(hs_ep);
if (hs_req) if (hs_req) {
hs_req->req.frame_number = hs_ep->target_frame;
hs_req->req.actual = 0;
dwc2_hsotg_complete_request(hsotg, hs_ep, hs_req, dwc2_hsotg_complete_request(hsotg, hs_ep, hs_req,
-ENODATA); -ENODATA);
}
dwc2_gadget_incr_frame_num(hs_ep); dwc2_gadget_incr_frame_num(hs_ep);
/* Update current frame number value. */ /* Update current frame number value. */
hsotg->frame_number = dwc2_hsotg_read_frameno(hsotg); hsotg->frame_number = dwc2_hsotg_read_frameno(hsotg);
...@@ -2912,8 +2917,11 @@ static void dwc2_gadget_handle_out_token_ep_disabled(struct dwc2_hsotg_ep *ep) ...@@ -2912,8 +2917,11 @@ static void dwc2_gadget_handle_out_token_ep_disabled(struct dwc2_hsotg_ep *ep)
while (dwc2_gadget_target_frame_elapsed(ep)) { while (dwc2_gadget_target_frame_elapsed(ep)) {
hs_req = get_ep_head(ep); hs_req = get_ep_head(ep);
if (hs_req) if (hs_req) {
hs_req->req.frame_number = ep->target_frame;
hs_req->req.actual = 0;
dwc2_hsotg_complete_request(hsotg, ep, hs_req, -ENODATA); dwc2_hsotg_complete_request(hsotg, ep, hs_req, -ENODATA);
}
dwc2_gadget_incr_frame_num(ep); dwc2_gadget_incr_frame_num(ep);
/* Update current frame number value. */ /* Update current frame number value. */
...@@ -3002,8 +3010,11 @@ static void dwc2_gadget_handle_nak(struct dwc2_hsotg_ep *hs_ep) ...@@ -3002,8 +3010,11 @@ static void dwc2_gadget_handle_nak(struct dwc2_hsotg_ep *hs_ep)
while (dwc2_gadget_target_frame_elapsed(hs_ep)) { while (dwc2_gadget_target_frame_elapsed(hs_ep)) {
hs_req = get_ep_head(hs_ep); hs_req = get_ep_head(hs_ep);
if (hs_req) if (hs_req) {
hs_req->req.frame_number = hs_ep->target_frame;
hs_req->req.actual = 0;
dwc2_hsotg_complete_request(hsotg, hs_ep, hs_req, -ENODATA); dwc2_hsotg_complete_request(hsotg, hs_ep, hs_req, -ENODATA);
}
dwc2_gadget_incr_frame_num(hs_ep); dwc2_gadget_incr_frame_num(hs_ep);
/* Update current frame number value. */ /* Update current frame number value. */
......
...@@ -59,7 +59,7 @@ ...@@ -59,7 +59,7 @@
#define DWC2_UNRESERVE_DELAY (msecs_to_jiffies(5)) #define DWC2_UNRESERVE_DELAY (msecs_to_jiffies(5))
/* If we get a NAK, wait this long before retrying */ /* If we get a NAK, wait this long before retrying */
#define DWC2_RETRY_WAIT_DELAY (1 * 1E6L) #define DWC2_RETRY_WAIT_DELAY (1 * NSEC_PER_MSEC)
/** /**
* dwc2_periodic_channel_available() - Checks that a channel is available for a * dwc2_periodic_channel_available() - Checks that a channel is available for a
......
...@@ -1594,9 +1594,11 @@ static int dwc3_probe(struct platform_device *pdev) ...@@ -1594,9 +1594,11 @@ static int dwc3_probe(struct platform_device *pdev)
dwc3_get_properties(dwc); dwc3_get_properties(dwc);
ret = dma_set_mask_and_coherent(dwc->sysdev, DMA_BIT_MASK(64)); if (!dwc->sysdev_is_parent) {
if (ret) ret = dma_set_mask_and_coherent(dwc->sysdev, DMA_BIT_MASK(64));
return ret; if (ret)
return ret;
}
dwc->reset = devm_reset_control_array_get_optional_shared(dev); dwc->reset = devm_reset_control_array_get_optional_shared(dev);
if (IS_ERR(dwc->reset)) if (IS_ERR(dwc->reset))
......
...@@ -143,7 +143,7 @@ ...@@ -143,7 +143,7 @@
#define DWC3_GHWPARAMS8 0xc600 #define DWC3_GHWPARAMS8 0xc600
#define DWC3_GUCTL3 0xc60c #define DWC3_GUCTL3 0xc60c
#define DWC3_GFLADJ 0xc630 #define DWC3_GFLADJ 0xc630
#define DWC3_GHWPARAMS9 0xc680 #define DWC3_GHWPARAMS9 0xc6e0
/* Device Registers */ /* Device Registers */
#define DWC3_DCFG 0xc700 #define DWC3_DCFG 0xc700
......
...@@ -310,13 +310,24 @@ int dwc3_send_gadget_ep_cmd(struct dwc3_ep *dep, unsigned int cmd, ...@@ -310,13 +310,24 @@ int dwc3_send_gadget_ep_cmd(struct dwc3_ep *dep, unsigned int cmd,
if (DWC3_DEPCMD_CMD(cmd) == DWC3_DEPCMD_STARTTRANSFER) { if (DWC3_DEPCMD_CMD(cmd) == DWC3_DEPCMD_STARTTRANSFER) {
int link_state; int link_state;
/*
* Initiate remote wakeup if the link state is in U3 when
* operating in SS/SSP or L1/L2 when operating in HS/FS. If the
* link state is in U1/U2, no remote wakeup is needed. The Start
* Transfer command will initiate the link recovery.
*/
link_state = dwc3_gadget_get_link_state(dwc); link_state = dwc3_gadget_get_link_state(dwc);
if (link_state == DWC3_LINK_STATE_U1 || switch (link_state) {
link_state == DWC3_LINK_STATE_U2 || case DWC3_LINK_STATE_U2:
link_state == DWC3_LINK_STATE_U3) { if (dwc->gadget->speed >= USB_SPEED_SUPER)
break;
fallthrough;
case DWC3_LINK_STATE_U3:
ret = __dwc3_gadget_wakeup(dwc); ret = __dwc3_gadget_wakeup(dwc);
dev_WARN_ONCE(dwc->dev, ret, "wakeup failed --> %d\n", dev_WARN_ONCE(dwc->dev, ret, "wakeup failed --> %d\n",
ret); ret);
break;
} }
} }
...@@ -3252,6 +3263,9 @@ static bool dwc3_gadget_endpoint_trbs_complete(struct dwc3_ep *dep, ...@@ -3252,6 +3263,9 @@ static bool dwc3_gadget_endpoint_trbs_complete(struct dwc3_ep *dep,
struct dwc3 *dwc = dep->dwc; struct dwc3 *dwc = dep->dwc;
bool no_started_trb = true; bool no_started_trb = true;
if (!dep->endpoint.desc)
return no_started_trb;
dwc3_gadget_ep_cleanup_completed_requests(dep, event, status); dwc3_gadget_ep_cleanup_completed_requests(dep, event, status);
if (dep->flags & DWC3_EP_END_TRANSFER_PENDING) if (dep->flags & DWC3_EP_END_TRANSFER_PENDING)
...@@ -3299,6 +3313,9 @@ static void dwc3_gadget_endpoint_transfer_in_progress(struct dwc3_ep *dep, ...@@ -3299,6 +3313,9 @@ static void dwc3_gadget_endpoint_transfer_in_progress(struct dwc3_ep *dep,
{ {
int status = 0; int status = 0;
if (!dep->endpoint.desc)
return;
if (usb_endpoint_xfer_isoc(dep->endpoint.desc)) if (usb_endpoint_xfer_isoc(dep->endpoint.desc))
dwc3_gadget_endpoint_frame_from_event(dep, event); dwc3_gadget_endpoint_frame_from_event(dep, event);
...@@ -3352,6 +3369,14 @@ static void dwc3_gadget_endpoint_command_complete(struct dwc3_ep *dep, ...@@ -3352,6 +3369,14 @@ static void dwc3_gadget_endpoint_command_complete(struct dwc3_ep *dep,
if (cmd != DWC3_DEPCMD_ENDTRANSFER) if (cmd != DWC3_DEPCMD_ENDTRANSFER)
return; return;
/*
* The END_TRANSFER command will cause the controller to generate a
* NoStream Event, and it's not due to the host DP NoStream rejection.
* Ignore the next NoStream event.
*/
if (dep->stream_capable)
dep->flags |= DWC3_EP_IGNORE_NEXT_NOSTREAM;
dep->flags &= ~DWC3_EP_END_TRANSFER_PENDING; dep->flags &= ~DWC3_EP_END_TRANSFER_PENDING;
dep->flags &= ~DWC3_EP_TRANSFER_STARTED; dep->flags &= ~DWC3_EP_TRANSFER_STARTED;
dwc3_gadget_ep_cleanup_cancelled_requests(dep); dwc3_gadget_ep_cleanup_cancelled_requests(dep);
...@@ -3574,14 +3599,6 @@ static void dwc3_stop_active_transfer(struct dwc3_ep *dep, bool force, ...@@ -3574,14 +3599,6 @@ static void dwc3_stop_active_transfer(struct dwc3_ep *dep, bool force,
WARN_ON_ONCE(ret); WARN_ON_ONCE(ret);
dep->resource_index = 0; dep->resource_index = 0;
/*
* The END_TRANSFER command will cause the controller to generate a
* NoStream Event, and it's not due to the host DP NoStream rejection.
* Ignore the next NoStream event.
*/
if (dep->stream_capable)
dep->flags |= DWC3_EP_IGNORE_NEXT_NOSTREAM;
if (!interrupt) if (!interrupt)
dep->flags &= ~DWC3_EP_TRANSFER_STARTED; dep->flags &= ~DWC3_EP_TRANSFER_STARTED;
else else
......
...@@ -2136,7 +2136,7 @@ static int xudc_probe(struct platform_device *pdev) ...@@ -2136,7 +2136,7 @@ static int xudc_probe(struct platform_device *pdev)
ret = usb_add_gadget_udc(&pdev->dev, &udc->gadget); ret = usb_add_gadget_udc(&pdev->dev, &udc->gadget);
if (ret) if (ret)
goto fail; goto err_disable_unprepare_clk;
udc->dev = &udc->gadget.dev; udc->dev = &udc->gadget.dev;
...@@ -2155,6 +2155,9 @@ static int xudc_probe(struct platform_device *pdev) ...@@ -2155,6 +2155,9 @@ static int xudc_probe(struct platform_device *pdev)
udc->dma_enabled ? "with DMA" : "without DMA"); udc->dma_enabled ? "with DMA" : "without DMA");
return 0; return 0;
err_disable_unprepare_clk:
clk_disable_unprepare(udc->clk);
fail: fail:
dev_err(&pdev->dev, "probe failed, %d\n", ret); dev_err(&pdev->dev, "probe failed, %d\n", ret);
return ret; return ret;
......
...@@ -1400,6 +1400,7 @@ static void tegra_xusb_deinit_usb_phy(struct tegra_xusb *tegra) ...@@ -1400,6 +1400,7 @@ static void tegra_xusb_deinit_usb_phy(struct tegra_xusb *tegra)
static int tegra_xusb_probe(struct platform_device *pdev) static int tegra_xusb_probe(struct platform_device *pdev)
{ {
struct of_phandle_args args;
struct tegra_xusb *tegra; struct tegra_xusb *tegra;
struct device_node *np; struct device_node *np;
struct resource *regs; struct resource *regs;
...@@ -1454,10 +1455,17 @@ static int tegra_xusb_probe(struct platform_device *pdev) ...@@ -1454,10 +1455,17 @@ static int tegra_xusb_probe(struct platform_device *pdev)
goto put_padctl; goto put_padctl;
} }
tegra->padctl_irq = of_irq_get(np, 0); /* Older device-trees don't have padctrl interrupt */
if (tegra->padctl_irq <= 0) { err = of_irq_parse_one(np, 0, &args);
err = (tegra->padctl_irq == 0) ? -ENODEV : tegra->padctl_irq; if (!err) {
goto put_padctl; tegra->padctl_irq = of_irq_get(np, 0);
if (tegra->padctl_irq <= 0) {
err = (tegra->padctl_irq == 0) ? -ENODEV : tegra->padctl_irq;
goto put_padctl;
}
} else {
dev_dbg(&pdev->dev,
"%pOF is missing an interrupt, disabling PM support\n", np);
} }
tegra->host_clk = devm_clk_get(&pdev->dev, "xusb_host"); tegra->host_clk = devm_clk_get(&pdev->dev, "xusb_host");
...@@ -1696,11 +1704,15 @@ static int tegra_xusb_probe(struct platform_device *pdev) ...@@ -1696,11 +1704,15 @@ static int tegra_xusb_probe(struct platform_device *pdev)
goto remove_usb3; goto remove_usb3;
} }
err = devm_request_threaded_irq(&pdev->dev, tegra->padctl_irq, NULL, tegra_xusb_padctl_irq, if (tegra->padctl_irq) {
IRQF_ONESHOT, dev_name(&pdev->dev), tegra); err = devm_request_threaded_irq(&pdev->dev, tegra->padctl_irq,
if (err < 0) { NULL, tegra_xusb_padctl_irq,
dev_err(&pdev->dev, "failed to request padctl IRQ: %d\n", err); IRQF_ONESHOT, dev_name(&pdev->dev),
goto remove_usb3; tegra);
if (err < 0) {
dev_err(&pdev->dev, "failed to request padctl IRQ: %d\n", err);
goto remove_usb3;
}
} }
err = tegra_xusb_enable_firmware_messages(tegra); err = tegra_xusb_enable_firmware_messages(tegra);
...@@ -1718,13 +1730,16 @@ static int tegra_xusb_probe(struct platform_device *pdev) ...@@ -1718,13 +1730,16 @@ static int tegra_xusb_probe(struct platform_device *pdev)
/* Enable wake for both USB 2.0 and USB 3.0 roothubs */ /* Enable wake for both USB 2.0 and USB 3.0 roothubs */
device_init_wakeup(&tegra->hcd->self.root_hub->dev, true); device_init_wakeup(&tegra->hcd->self.root_hub->dev, true);
device_init_wakeup(&xhci->shared_hcd->self.root_hub->dev, true); device_init_wakeup(&xhci->shared_hcd->self.root_hub->dev, true);
device_init_wakeup(tegra->dev, true);
pm_runtime_use_autosuspend(tegra->dev); pm_runtime_use_autosuspend(tegra->dev);
pm_runtime_set_autosuspend_delay(tegra->dev, 2000); pm_runtime_set_autosuspend_delay(tegra->dev, 2000);
pm_runtime_mark_last_busy(tegra->dev); pm_runtime_mark_last_busy(tegra->dev);
pm_runtime_set_active(tegra->dev); pm_runtime_set_active(tegra->dev);
pm_runtime_enable(tegra->dev);
if (tegra->padctl_irq) {
device_init_wakeup(tegra->dev, true);
pm_runtime_enable(tegra->dev);
}
return 0; return 0;
...@@ -1772,7 +1787,9 @@ static int tegra_xusb_remove(struct platform_device *pdev) ...@@ -1772,7 +1787,9 @@ static int tegra_xusb_remove(struct platform_device *pdev)
dma_free_coherent(&pdev->dev, tegra->fw.size, tegra->fw.virt, dma_free_coherent(&pdev->dev, tegra->fw.size, tegra->fw.virt,
tegra->fw.phys); tegra->fw.phys);
pm_runtime_disable(&pdev->dev); if (tegra->padctl_irq)
pm_runtime_disable(&pdev->dev);
pm_runtime_put(&pdev->dev); pm_runtime_put(&pdev->dev);
tegra_xusb_powergate_partitions(tegra); tegra_xusb_powergate_partitions(tegra);
......
...@@ -1267,6 +1267,8 @@ static const struct usb_device_id option_ids[] = { ...@@ -1267,6 +1267,8 @@ static const struct usb_device_id option_ids[] = {
.driver_info = NCTRL(2) }, .driver_info = NCTRL(2) },
{ USB_DEVICE(TELIT_VENDOR_ID, 0x9010), /* Telit SBL FN980 flashing device */ { USB_DEVICE(TELIT_VENDOR_ID, 0x9010), /* Telit SBL FN980 flashing device */
.driver_info = NCTRL(0) | ZLP }, .driver_info = NCTRL(0) | ZLP },
{ USB_DEVICE(TELIT_VENDOR_ID, 0x9200), /* Telit LE910S1 flashing device */
.driver_info = NCTRL(0) | ZLP },
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_MF622, 0xff, 0xff, 0xff) }, /* ZTE WCDMA products */ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_MF622, 0xff, 0xff, 0xff) }, /* ZTE WCDMA products */
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0002, 0xff, 0xff, 0xff), { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0002, 0xff, 0xff, 0xff),
.driver_info = RSVD(1) }, .driver_info = RSVD(1) },
...@@ -2094,6 +2096,9 @@ static const struct usb_device_id option_ids[] = { ...@@ -2094,6 +2096,9 @@ static const struct usb_device_id option_ids[] = {
{ USB_DEVICE_AND_INTERFACE_INFO(0x2cb7, 0x010b, 0xff, 0xff, 0x30) }, /* Fibocom FG150 Diag */ { USB_DEVICE_AND_INTERFACE_INFO(0x2cb7, 0x010b, 0xff, 0xff, 0x30) }, /* Fibocom FG150 Diag */
{ USB_DEVICE_AND_INTERFACE_INFO(0x2cb7, 0x010b, 0xff, 0, 0) }, /* Fibocom FG150 AT */ { USB_DEVICE_AND_INTERFACE_INFO(0x2cb7, 0x010b, 0xff, 0, 0) }, /* Fibocom FG150 AT */
{ USB_DEVICE_INTERFACE_CLASS(0x2cb7, 0x01a0, 0xff) }, /* Fibocom NL668-AM/NL652-EU (laptop MBIM) */ { USB_DEVICE_INTERFACE_CLASS(0x2cb7, 0x01a0, 0xff) }, /* Fibocom NL668-AM/NL652-EU (laptop MBIM) */
{ USB_DEVICE_INTERFACE_CLASS(0x2cb7, 0x01a2, 0xff) }, /* Fibocom FM101-GL (laptop MBIM) */
{ USB_DEVICE_INTERFACE_CLASS(0x2cb7, 0x01a4, 0xff), /* Fibocom FM101-GL (laptop MBIM) */
.driver_info = RSVD(4) },
{ USB_DEVICE_INTERFACE_CLASS(0x2df3, 0x9d03, 0xff) }, /* LongSung M5710 */ { USB_DEVICE_INTERFACE_CLASS(0x2df3, 0x9d03, 0xff) }, /* LongSung M5710 */
{ USB_DEVICE_INTERFACE_CLASS(0x305a, 0x1404, 0xff) }, /* GosunCn GM500 RNDIS */ { USB_DEVICE_INTERFACE_CLASS(0x305a, 0x1404, 0xff) }, /* GosunCn GM500 RNDIS */
{ USB_DEVICE_INTERFACE_CLASS(0x305a, 0x1405, 0xff) }, /* GosunCn GM500 MBIM */ { USB_DEVICE_INTERFACE_CLASS(0x305a, 0x1405, 0xff) }, /* GosunCn GM500 MBIM */
......
...@@ -432,6 +432,7 @@ static int pl2303_detect_type(struct usb_serial *serial) ...@@ -432,6 +432,7 @@ static int pl2303_detect_type(struct usb_serial *serial)
case 0x200: case 0x200:
switch (bcdDevice) { switch (bcdDevice) {
case 0x100: case 0x100:
case 0x105:
case 0x305: case 0x305:
case 0x405: case 0x405:
/* /*
......
...@@ -669,25 +669,27 @@ static int tcpm_set_cc(struct tcpc_dev *dev, enum typec_cc_status cc) ...@@ -669,25 +669,27 @@ static int tcpm_set_cc(struct tcpc_dev *dev, enum typec_cc_status cc)
ret = fusb302_i2c_mask_write(chip, FUSB_REG_MASK, ret = fusb302_i2c_mask_write(chip, FUSB_REG_MASK,
FUSB_REG_MASK_BC_LVL | FUSB_REG_MASK_BC_LVL |
FUSB_REG_MASK_COMP_CHNG, FUSB_REG_MASK_COMP_CHNG,
FUSB_REG_MASK_COMP_CHNG); FUSB_REG_MASK_BC_LVL);
if (ret < 0) { if (ret < 0) {
fusb302_log(chip, "cannot set SRC interrupt, ret=%d", fusb302_log(chip, "cannot set SRC interrupt, ret=%d",
ret); ret);
goto done; goto done;
} }
chip->intr_comp_chng = true; chip->intr_comp_chng = true;
chip->intr_bc_lvl = false;
break; break;
case TYPEC_CC_RD: case TYPEC_CC_RD:
ret = fusb302_i2c_mask_write(chip, FUSB_REG_MASK, ret = fusb302_i2c_mask_write(chip, FUSB_REG_MASK,
FUSB_REG_MASK_BC_LVL | FUSB_REG_MASK_BC_LVL |
FUSB_REG_MASK_COMP_CHNG, FUSB_REG_MASK_COMP_CHNG,
FUSB_REG_MASK_BC_LVL); FUSB_REG_MASK_COMP_CHNG);
if (ret < 0) { if (ret < 0) {
fusb302_log(chip, "cannot set SRC interrupt, ret=%d", fusb302_log(chip, "cannot set SRC interrupt, ret=%d",
ret); ret);
goto done; goto done;
} }
chip->intr_bc_lvl = true; chip->intr_bc_lvl = true;
chip->intr_comp_chng = false;
break; break;
default: default:
break; break;
......
...@@ -653,7 +653,7 @@ static int cd321x_switch_power_state(struct tps6598x *tps, u8 target_state) ...@@ -653,7 +653,7 @@ static int cd321x_switch_power_state(struct tps6598x *tps, u8 target_state)
if (state == target_state) if (state == target_state)
return 0; return 0;
ret = tps6598x_exec_cmd(tps, "SPSS", sizeof(u8), &target_state, 0, NULL); ret = tps6598x_exec_cmd(tps, "SSPS", sizeof(u8), &target_state, 0, NULL);
if (ret) if (ret)
return ret; return ret;
...@@ -707,6 +707,7 @@ static int tps6598x_probe(struct i2c_client *client) ...@@ -707,6 +707,7 @@ static int tps6598x_probe(struct i2c_client *client)
u32 conf; u32 conf;
u32 vid; u32 vid;
int ret; int ret;
u64 mask1;
tps = devm_kzalloc(&client->dev, sizeof(*tps), GFP_KERNEL); tps = devm_kzalloc(&client->dev, sizeof(*tps), GFP_KERNEL);
if (!tps) if (!tps)
...@@ -730,11 +731,6 @@ static int tps6598x_probe(struct i2c_client *client) ...@@ -730,11 +731,6 @@ static int tps6598x_probe(struct i2c_client *client)
if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C))
tps->i2c_protocol = true; tps->i2c_protocol = true;
/* Make sure the controller has application firmware running */
ret = tps6598x_check_mode(tps);
if (ret)
return ret;
if (np && of_device_is_compatible(np, "apple,cd321x")) { if (np && of_device_is_compatible(np, "apple,cd321x")) {
/* Switch CD321X chips to the correct system power state */ /* Switch CD321X chips to the correct system power state */
ret = cd321x_switch_power_state(tps, TPS_SYSTEM_POWER_STATE_S0); ret = cd321x_switch_power_state(tps, TPS_SYSTEM_POWER_STATE_S0);
...@@ -742,24 +738,27 @@ static int tps6598x_probe(struct i2c_client *client) ...@@ -742,24 +738,27 @@ static int tps6598x_probe(struct i2c_client *client)
return ret; return ret;
/* CD321X chips have all interrupts masked initially */ /* CD321X chips have all interrupts masked initially */
ret = tps6598x_write64(tps, TPS_REG_INT_MASK1, mask1 = APPLE_CD_REG_INT_POWER_STATUS_UPDATE |
APPLE_CD_REG_INT_POWER_STATUS_UPDATE | APPLE_CD_REG_INT_DATA_STATUS_UPDATE |
APPLE_CD_REG_INT_DATA_STATUS_UPDATE | APPLE_CD_REG_INT_PLUG_EVENT;
APPLE_CD_REG_INT_PLUG_EVENT);
if (ret)
return ret;
irq_handler = cd321x_interrupt; irq_handler = cd321x_interrupt;
} else { } else {
/* Enable power status, data status and plug event interrupts */ /* Enable power status, data status and plug event interrupts */
ret = tps6598x_write64(tps, TPS_REG_INT_MASK1, mask1 = TPS_REG_INT_POWER_STATUS_UPDATE |
TPS_REG_INT_POWER_STATUS_UPDATE | TPS_REG_INT_DATA_STATUS_UPDATE |
TPS_REG_INT_DATA_STATUS_UPDATE | TPS_REG_INT_PLUG_EVENT;
TPS_REG_INT_PLUG_EVENT);
if (ret)
return ret;
} }
/* Make sure the controller has application firmware running */
ret = tps6598x_check_mode(tps);
if (ret)
return ret;
ret = tps6598x_write64(tps, TPS_REG_INT_MASK1, mask1);
if (ret)
return ret;
ret = tps6598x_read32(tps, TPS_REG_STATUS, &status); ret = tps6598x_read32(tps, TPS_REG_STATUS, &status);
if (ret < 0) if (ret < 0)
return ret; return ret;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment