USB fixes for 5.16-rc3
Here are a number of small USB fixes for reported problems for 5.16-rc3 Then 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. Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> -----BEGIN PGP SIGNATURE----- iG0EABECAC0WIQT0tgzFv3jCIUoxPcsxR9QN2y37KQUCYaD5qA8cZ3JlZ0Brcm9h aC5jb20ACgkQMUfUDdst+ykERACgkxi+H6dGSS7jVcoN+094/EnvZ7EAoInuQRY6 8iyGS1rDI9yKKNipPmI4 =oy2C -----END PGP SIGNATURE----- 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
This commit is contained in:
commit
ba2cacc18c
@ -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,
|
|||||||
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 @@ fail:
|
|||||||
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,
|
|||||||
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,
|
|||||||
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,
|
|||||||
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,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* 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 @@ loop:
|
|||||||
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)
|
|||||||
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)
|
|||||||
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,
|
|||||||
}
|
}
|
||||||
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)
|
|||||||
|
|
||||||
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)
|
|||||||
|
|
||||||
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)
|
|||||||
|
|
||||||
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 @@
|
|||||||
#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)
|
|||||||
|
|
||||||
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 @@
|
|||||||
#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,
|
|||||||
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,
|
|||||||
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,
|
|||||||
{
|
{
|
||||||
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,
|
|||||||
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,
|
|||||||
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)
|
|||||||
|
|
||||||
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)
|
|||||||
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)
|
|||||||
|
|
||||||
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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
/* 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)
|
|||||||
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[] = {
|
|||||||
.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[] = {
|
|||||||
{ 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)
|
|||||||
case 0x200:
|
case 0x200:
|
||||||
switch (bcdDevice) {
|
switch (bcdDevice) {
|
||||||
case 0x100:
|
case 0x100:
|
||||||
|
case 0x105:
|
||||||
case 0x305:
|
case 0x305:
|
||||||
case 0x405:
|
case 0x405:
|
||||||
/*
|
/*
|
||||||
|
@ -666,18 +666,6 @@ static int tcpm_set_cc(struct tcpc_dev *dev, enum typec_cc_status cc)
|
|||||||
ret);
|
ret);
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
ret = fusb302_i2c_mask_write(chip, FUSB_REG_MASK,
|
|
||||||
FUSB_REG_MASK_BC_LVL |
|
|
||||||
FUSB_REG_MASK_COMP_CHNG,
|
|
||||||
FUSB_REG_MASK_COMP_CHNG);
|
|
||||||
if (ret < 0) {
|
|
||||||
fusb302_log(chip, "cannot set SRC interrupt, ret=%d",
|
|
||||||
ret);
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
chip->intr_comp_chng = true;
|
|
||||||
break;
|
|
||||||
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,
|
||||||
@ -687,7 +675,21 @@ static int tcpm_set_cc(struct tcpc_dev *dev, enum typec_cc_status cc)
|
|||||||
ret);
|
ret);
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
chip->intr_comp_chng = true;
|
||||||
|
chip->intr_bc_lvl = false;
|
||||||
|
break;
|
||||||
|
case TYPEC_CC_RD:
|
||||||
|
ret = fusb302_i2c_mask_write(chip, FUSB_REG_MASK,
|
||||||
|
FUSB_REG_MASK_BC_LVL |
|
||||||
|
FUSB_REG_MASK_COMP_CHNG,
|
||||||
|
FUSB_REG_MASK_COMP_CHNG);
|
||||||
|
if (ret < 0) {
|
||||||
|
fusb302_log(chip, "cannot set SRC interrupt, ret=%d",
|
||||||
|
ret);
|
||||||
|
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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
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;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user