forked from Minki/linux
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);
|
||||
if (IS_ERR(data->phy)) {
|
||||
ret = PTR_ERR(data->phy);
|
||||
if (ret == -ENODEV) {
|
||||
data->phy = devm_usb_get_phy_by_phandle(dev, "phys", 0);
|
||||
if (IS_ERR(data->phy)) {
|
||||
ret = PTR_ERR(data->phy);
|
||||
if (ret == -ENODEV)
|
||||
data->phy = NULL;
|
||||
else
|
||||
goto err_clk;
|
||||
}
|
||||
if (ret != -ENODEV)
|
||||
goto err_clk;
|
||||
data->phy = devm_usb_get_phy_by_phandle(dev, "phys", 0);
|
||||
if (IS_ERR(data->phy)) {
|
||||
ret = PTR_ERR(data->phy);
|
||||
if (ret == -ENODEV)
|
||||
data->phy = NULL;
|
||||
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)
|
||||
delay = HUB_LONG_RESET_TIME;
|
||||
|
||||
mutex_lock(hcd->address0_mutex);
|
||||
|
||||
/* Reset the device; full speed may morph to high speed */
|
||||
/* FIXME a USB 2.0 device may morph into SuperSpeed on reset. */
|
||||
retval = hub_port_reset(hub, port1, udev, delay, false);
|
||||
@ -5016,7 +5014,6 @@ fail:
|
||||
hub_port_disable(hub, port1, 0);
|
||||
update_devnum(udev, devnum); /* for disconnect processing */
|
||||
}
|
||||
mutex_unlock(hcd->address0_mutex);
|
||||
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_device *udev = port_dev->child;
|
||||
static int unreliable_port = -1;
|
||||
bool retry_locked;
|
||||
|
||||
/* Disconnect any existing devices under this port */
|
||||
if (udev) {
|
||||
@ -5246,8 +5244,11 @@ static void hub_port_connect(struct usb_hub *hub, int port1, u16 portstatus,
|
||||
unit_load = 100;
|
||||
|
||||
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
|
||||
* 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) {
|
||||
dev_err(&port_dev->dev,
|
||||
"couldn't allocate usb_device\n");
|
||||
mutex_unlock(hcd->address0_mutex);
|
||||
usb_unlock_port(port_dev);
|
||||
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 */
|
||||
usb_lock_port(port_dev);
|
||||
status = hub_port_init(hub, udev, port1, i);
|
||||
usb_unlock_port(port_dev);
|
||||
if (status < 0)
|
||||
goto loop;
|
||||
|
||||
mutex_unlock(hcd->address0_mutex);
|
||||
usb_unlock_port(port_dev);
|
||||
retry_locked = false;
|
||||
|
||||
if (udev->quirks & USB_QUIRK_DELAY_INIT)
|
||||
msleep(2000);
|
||||
|
||||
@ -5374,6 +5379,10 @@ loop:
|
||||
usb_ep0_reinit(udev);
|
||||
release_devnum(udev);
|
||||
hub_free_dev(udev);
|
||||
if (retry_locked) {
|
||||
mutex_unlock(hcd->address0_mutex);
|
||||
usb_unlock_port(port_dev);
|
||||
}
|
||||
usb_put_dev(udev);
|
||||
if ((status == -ENOTCONN) || (status == -ENOTSUPP))
|
||||
break;
|
||||
@ -5915,6 +5924,8 @@ static int usb_reset_and_verify_device(struct usb_device *udev)
|
||||
bos = udev->bos;
|
||||
udev->bos = NULL;
|
||||
|
||||
mutex_lock(hcd->address0_mutex);
|
||||
|
||||
for (i = 0; i < PORT_INIT_TRIES; ++i) {
|
||||
|
||||
/* 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)
|
||||
break;
|
||||
}
|
||||
mutex_unlock(hcd->address0_mutex);
|
||||
|
||||
if (ret < 0)
|
||||
goto re_enumerate;
|
||||
|
@ -1198,6 +1198,8 @@ static void dwc2_hsotg_start_req(struct dwc2_hsotg *hsotg,
|
||||
}
|
||||
ctrl |= DXEPCTL_CNAK;
|
||||
} 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);
|
||||
return;
|
||||
}
|
||||
@ -2857,9 +2859,12 @@ static void dwc2_gadget_handle_ep_disabled(struct dwc2_hsotg_ep *hs_ep)
|
||||
|
||||
do {
|
||||
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_gadget_incr_frame_num(hs_ep);
|
||||
/* Update current frame number value. */
|
||||
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)) {
|
||||
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_gadget_incr_frame_num(ep);
|
||||
/* 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)) {
|
||||
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_gadget_incr_frame_num(hs_ep);
|
||||
/* Update current frame number value. */
|
||||
|
@ -59,7 +59,7 @@
|
||||
#define DWC2_UNRESERVE_DELAY (msecs_to_jiffies(5))
|
||||
|
||||
/* 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
|
||||
|
@ -1594,9 +1594,11 @@ static int dwc3_probe(struct platform_device *pdev)
|
||||
|
||||
dwc3_get_properties(dwc);
|
||||
|
||||
ret = dma_set_mask_and_coherent(dwc->sysdev, DMA_BIT_MASK(64));
|
||||
if (ret)
|
||||
return ret;
|
||||
if (!dwc->sysdev_is_parent) {
|
||||
ret = dma_set_mask_and_coherent(dwc->sysdev, DMA_BIT_MASK(64));
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
dwc->reset = devm_reset_control_array_get_optional_shared(dev);
|
||||
if (IS_ERR(dwc->reset))
|
||||
|
@ -143,7 +143,7 @@
|
||||
#define DWC3_GHWPARAMS8 0xc600
|
||||
#define DWC3_GUCTL3 0xc60c
|
||||
#define DWC3_GFLADJ 0xc630
|
||||
#define DWC3_GHWPARAMS9 0xc680
|
||||
#define DWC3_GHWPARAMS9 0xc6e0
|
||||
|
||||
/* Device Registers */
|
||||
#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) {
|
||||
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);
|
||||
if (link_state == DWC3_LINK_STATE_U1 ||
|
||||
link_state == DWC3_LINK_STATE_U2 ||
|
||||
link_state == DWC3_LINK_STATE_U3) {
|
||||
switch (link_state) {
|
||||
case DWC3_LINK_STATE_U2:
|
||||
if (dwc->gadget->speed >= USB_SPEED_SUPER)
|
||||
break;
|
||||
|
||||
fallthrough;
|
||||
case DWC3_LINK_STATE_U3:
|
||||
ret = __dwc3_gadget_wakeup(dwc);
|
||||
dev_WARN_ONCE(dwc->dev, ret, "wakeup failed --> %d\n",
|
||||
ret);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -3252,6 +3263,9 @@ static bool dwc3_gadget_endpoint_trbs_complete(struct dwc3_ep *dep,
|
||||
struct dwc3 *dwc = dep->dwc;
|
||||
bool no_started_trb = true;
|
||||
|
||||
if (!dep->endpoint.desc)
|
||||
return no_started_trb;
|
||||
|
||||
dwc3_gadget_ep_cleanup_completed_requests(dep, event, status);
|
||||
|
||||
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;
|
||||
|
||||
if (!dep->endpoint.desc)
|
||||
return;
|
||||
|
||||
if (usb_endpoint_xfer_isoc(dep->endpoint.desc))
|
||||
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)
|
||||
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_TRANSFER_STARTED;
|
||||
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);
|
||||
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)
|
||||
dep->flags &= ~DWC3_EP_TRANSFER_STARTED;
|
||||
else
|
||||
|
@ -2136,7 +2136,7 @@ static int xudc_probe(struct platform_device *pdev)
|
||||
|
||||
ret = usb_add_gadget_udc(&pdev->dev, &udc->gadget);
|
||||
if (ret)
|
||||
goto fail;
|
||||
goto err_disable_unprepare_clk;
|
||||
|
||||
udc->dev = &udc->gadget.dev;
|
||||
|
||||
@ -2155,6 +2155,9 @@ static int xudc_probe(struct platform_device *pdev)
|
||||
udc->dma_enabled ? "with DMA" : "without DMA");
|
||||
|
||||
return 0;
|
||||
|
||||
err_disable_unprepare_clk:
|
||||
clk_disable_unprepare(udc->clk);
|
||||
fail:
|
||||
dev_err(&pdev->dev, "probe failed, %d\n", 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)
|
||||
{
|
||||
struct of_phandle_args args;
|
||||
struct tegra_xusb *tegra;
|
||||
struct device_node *np;
|
||||
struct resource *regs;
|
||||
@ -1454,10 +1455,17 @@ static int tegra_xusb_probe(struct platform_device *pdev)
|
||||
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;
|
||||
/* Older device-trees don't have padctrl interrupt */
|
||||
err = of_irq_parse_one(np, 0, &args);
|
||||
if (!err) {
|
||||
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");
|
||||
@ -1696,11 +1704,15 @@ static int tegra_xusb_probe(struct platform_device *pdev)
|
||||
goto remove_usb3;
|
||||
}
|
||||
|
||||
err = devm_request_threaded_irq(&pdev->dev, tegra->padctl_irq, NULL, tegra_xusb_padctl_irq,
|
||||
IRQF_ONESHOT, dev_name(&pdev->dev), tegra);
|
||||
if (err < 0) {
|
||||
dev_err(&pdev->dev, "failed to request padctl IRQ: %d\n", err);
|
||||
goto remove_usb3;
|
||||
if (tegra->padctl_irq) {
|
||||
err = devm_request_threaded_irq(&pdev->dev, tegra->padctl_irq,
|
||||
NULL, tegra_xusb_padctl_irq,
|
||||
IRQF_ONESHOT, dev_name(&pdev->dev),
|
||||
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);
|
||||
@ -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 */
|
||||
device_init_wakeup(&tegra->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_set_autosuspend_delay(tegra->dev, 2000);
|
||||
pm_runtime_mark_last_busy(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;
|
||||
|
||||
@ -1772,7 +1787,9 @@ static int tegra_xusb_remove(struct platform_device *pdev)
|
||||
dma_free_coherent(&pdev->dev, tegra->fw.size, tegra->fw.virt,
|
||||
tegra->fw.phys);
|
||||
|
||||
pm_runtime_disable(&pdev->dev);
|
||||
if (tegra->padctl_irq)
|
||||
pm_runtime_disable(&pdev->dev);
|
||||
|
||||
pm_runtime_put(&pdev->dev);
|
||||
|
||||
tegra_xusb_powergate_partitions(tegra);
|
||||
|
@ -1267,6 +1267,8 @@ static const struct usb_device_id option_ids[] = {
|
||||
.driver_info = NCTRL(2) },
|
||||
{ USB_DEVICE(TELIT_VENDOR_ID, 0x9010), /* Telit SBL FN980 flashing device */
|
||||
.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, 0x0002, 0xff, 0xff, 0xff),
|
||||
.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, 0, 0) }, /* Fibocom FG150 AT */
|
||||
{ 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(0x305a, 0x1404, 0xff) }, /* GosunCn GM500 RNDIS */
|
||||
{ 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:
|
||||
switch (bcdDevice) {
|
||||
case 0x100:
|
||||
case 0x105:
|
||||
case 0x305:
|
||||
case 0x405:
|
||||
/*
|
||||
|
@ -666,18 +666,6 @@ static int tcpm_set_cc(struct tcpc_dev *dev, enum typec_cc_status cc)
|
||||
ret);
|
||||
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,
|
||||
FUSB_REG_MASK_BC_LVL |
|
||||
FUSB_REG_MASK_COMP_CHNG,
|
||||
@ -687,7 +675,21 @@ static int tcpm_set_cc(struct tcpc_dev *dev, enum typec_cc_status cc)
|
||||
ret);
|
||||
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_comp_chng = false;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
@ -653,7 +653,7 @@ static int cd321x_switch_power_state(struct tps6598x *tps, u8 target_state)
|
||||
if (state == target_state)
|
||||
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)
|
||||
return ret;
|
||||
|
||||
@ -707,6 +707,7 @@ static int tps6598x_probe(struct i2c_client *client)
|
||||
u32 conf;
|
||||
u32 vid;
|
||||
int ret;
|
||||
u64 mask1;
|
||||
|
||||
tps = devm_kzalloc(&client->dev, sizeof(*tps), GFP_KERNEL);
|
||||
if (!tps)
|
||||
@ -730,11 +731,6 @@ static int tps6598x_probe(struct i2c_client *client)
|
||||
if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C))
|
||||
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")) {
|
||||
/* Switch CD321X chips to the correct system power state */
|
||||
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;
|
||||
|
||||
/* CD321X chips have all interrupts masked initially */
|
||||
ret = tps6598x_write64(tps, TPS_REG_INT_MASK1,
|
||||
APPLE_CD_REG_INT_POWER_STATUS_UPDATE |
|
||||
APPLE_CD_REG_INT_DATA_STATUS_UPDATE |
|
||||
APPLE_CD_REG_INT_PLUG_EVENT);
|
||||
if (ret)
|
||||
return ret;
|
||||
mask1 = APPLE_CD_REG_INT_POWER_STATUS_UPDATE |
|
||||
APPLE_CD_REG_INT_DATA_STATUS_UPDATE |
|
||||
APPLE_CD_REG_INT_PLUG_EVENT;
|
||||
|
||||
irq_handler = cd321x_interrupt;
|
||||
} else {
|
||||
/* Enable power status, data status and plug event interrupts */
|
||||
ret = tps6598x_write64(tps, TPS_REG_INT_MASK1,
|
||||
TPS_REG_INT_POWER_STATUS_UPDATE |
|
||||
TPS_REG_INT_DATA_STATUS_UPDATE |
|
||||
TPS_REG_INT_PLUG_EVENT);
|
||||
if (ret)
|
||||
return ret;
|
||||
mask1 = TPS_REG_INT_POWER_STATUS_UPDATE |
|
||||
TPS_REG_INT_DATA_STATUS_UPDATE |
|
||||
TPS_REG_INT_PLUG_EVENT;
|
||||
}
|
||||
|
||||
/* 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);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
Loading…
Reference in New Issue
Block a user