diff options
Diffstat (limited to 'drivers/usb')
-rw-r--r-- | drivers/usb/class/cdc-acm.c | 14 | ||||
-rw-r--r-- | drivers/usb/common/ulpi.c | 4 | ||||
-rw-r--r-- | drivers/usb/dwc3/gadget.c | 23 | ||||
-rw-r--r-- | drivers/usb/gadget/function/u_audio.c | 23 | ||||
-rw-r--r-- | drivers/usb/gadget/function/u_serial.c | 36 | ||||
-rw-r--r-- | drivers/usb/host/xhci-dbgtty.c | 4 | ||||
-rw-r--r-- | drivers/usb/host/xhci-pci-renesas.c | 35 | ||||
-rw-r--r-- | drivers/usb/serial/bus.c | 4 | ||||
-rw-r--r-- | drivers/usb/serial/ch341.c | 1 | ||||
-rw-r--r-- | drivers/usb/serial/option.c | 2 | ||||
-rw-r--r-- | drivers/usb/serial/usb-serial.c | 13 | ||||
-rw-r--r-- | drivers/usb/typec/bus.c | 4 | ||||
-rw-r--r-- | drivers/usb/typec/tcpm/tcpm.c | 81 |
13 files changed, 126 insertions, 118 deletions
diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index 4895325b16a4..8bbd8e29e60d 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c @@ -2027,16 +2027,16 @@ static const struct tty_operations acm_ops = { static int __init acm_init(void) { int retval; - acm_tty_driver = alloc_tty_driver(ACM_TTY_MINORS); - if (!acm_tty_driver) - return -ENOMEM; + acm_tty_driver = tty_alloc_driver(ACM_TTY_MINORS, TTY_DRIVER_REAL_RAW | + TTY_DRIVER_DYNAMIC_DEV); + if (IS_ERR(acm_tty_driver)) + return PTR_ERR(acm_tty_driver); acm_tty_driver->driver_name = "acm", acm_tty_driver->name = "ttyACM", acm_tty_driver->major = ACM_TTY_MAJOR, acm_tty_driver->minor_start = 0, acm_tty_driver->type = TTY_DRIVER_TYPE_SERIAL, acm_tty_driver->subtype = SERIAL_TYPE_NORMAL, - acm_tty_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV; acm_tty_driver->init_termios = tty_std_termios; acm_tty_driver->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL; @@ -2044,14 +2044,14 @@ static int __init acm_init(void) retval = tty_register_driver(acm_tty_driver); if (retval) { - put_tty_driver(acm_tty_driver); + tty_driver_kref_put(acm_tty_driver); return retval; } retval = usb_register(&acm_driver); if (retval) { tty_unregister_driver(acm_tty_driver); - put_tty_driver(acm_tty_driver); + tty_driver_kref_put(acm_tty_driver); return retval; } @@ -2064,7 +2064,7 @@ static void __exit acm_exit(void) { usb_deregister(&acm_driver); tty_unregister_driver(acm_tty_driver); - put_tty_driver(acm_tty_driver); + tty_driver_kref_put(acm_tty_driver); idr_destroy(&acm_minors); } diff --git a/drivers/usb/common/ulpi.c b/drivers/usb/common/ulpi.c index 7e13b74e60e5..4169cf40a03b 100644 --- a/drivers/usb/common/ulpi.c +++ b/drivers/usb/common/ulpi.c @@ -78,14 +78,12 @@ static int ulpi_probe(struct device *dev) return drv->probe(to_ulpi_dev(dev)); } -static int ulpi_remove(struct device *dev) +static void ulpi_remove(struct device *dev) { struct ulpi_driver *drv = to_ulpi_driver(dev->driver); if (drv->remove) drv->remove(to_ulpi_dev(dev)); - - return 0; } static struct bus_type ulpi_bus = { diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 5d084542718d..804b50548163 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -1125,19 +1125,19 @@ static struct dwc3_trb *dwc3_ep_prev_trb(struct dwc3_ep *dep, u8 index) static u32 dwc3_calc_trbs_left(struct dwc3_ep *dep) { - struct dwc3_trb *tmp; u8 trbs_left; /* - * If enqueue & dequeue are equal than it is either full or empty. - * - * One way to know for sure is if the TRB right before us has HWO bit - * set or not. If it has, then we're definitely full and can't fit any - * more transfers in our ring. + * If the enqueue & dequeue are equal then the TRB ring is either full + * or empty. It's considered full when there are DWC3_TRB_NUM-1 of TRBs + * pending to be processed by the driver. */ if (dep->trb_enqueue == dep->trb_dequeue) { - tmp = dwc3_ep_prev_trb(dep, dep->trb_enqueue); - if (tmp->ctrl & DWC3_TRB_CTRL_HWO) + /* + * If there is any request remained in the started_list at + * this point, that means there is no TRB available. + */ + if (!list_empty(&dep->started_list)) return 0; return DWC3_TRB_NUM - 1; @@ -2428,10 +2428,8 @@ static int dwc3_gadget_pullup(struct usb_gadget *g, int is_on) ret = wait_for_completion_timeout(&dwc->ep0_in_setup, msecs_to_jiffies(DWC3_PULL_UP_TIMEOUT)); - if (ret == 0) { - dev_err(dwc->dev, "timed out waiting for SETUP phase\n"); - return -ETIMEDOUT; - } + if (ret == 0) + dev_warn(dwc->dev, "timed out waiting for SETUP phase\n"); } /* @@ -2643,6 +2641,7 @@ static int __dwc3_gadget_start(struct dwc3 *dwc) /* begin to receive SETUP packets */ dwc->ep0state = EP0_SETUP_PHASE; dwc->link_state = DWC3_LINK_STATE_SS_DIS; + dwc->delayed_status = false; dwc3_ep0_out_start(dwc); dwc3_gadget_enable_irq(dwc); diff --git a/drivers/usb/gadget/function/u_audio.c b/drivers/usb/gadget/function/u_audio.c index f6b5b9547236..32ef22857083 100644 --- a/drivers/usb/gadget/function/u_audio.c +++ b/drivers/usb/gadget/function/u_audio.c @@ -250,7 +250,13 @@ static void u_audio_iso_fback_complete(struct usb_ep *ep, int status = req->status; /* i/f shutting down */ - if (!prm->fb_ep_enabled || req->status == -ESHUTDOWN) + if (!prm->fb_ep_enabled) { + kfree(req->buf); + usb_ep_free_request(ep, req); + return; + } + + if (req->status == -ESHUTDOWN) return; /* @@ -408,8 +414,6 @@ static inline void free_ep(struct uac_rtd_params *prm, struct usb_ep *ep) if (!prm->ep_enabled) return; - prm->ep_enabled = false; - audio_dev = uac->audio_dev; params = &audio_dev->params; @@ -427,6 +431,8 @@ static inline void free_ep(struct uac_rtd_params *prm, struct usb_ep *ep) } } + prm->ep_enabled = false; + if (usb_ep_disable(ep)) dev_err(uac->card->dev, "%s:%d Error!\n", __func__, __LINE__); } @@ -438,15 +444,16 @@ static inline void free_ep_fback(struct uac_rtd_params *prm, struct usb_ep *ep) if (!prm->fb_ep_enabled) return; - prm->fb_ep_enabled = false; - if (prm->req_fback) { - usb_ep_dequeue(ep, prm->req_fback); - kfree(prm->req_fback->buf); - usb_ep_free_request(ep, prm->req_fback); + if (usb_ep_dequeue(ep, prm->req_fback)) { + kfree(prm->req_fback->buf); + usb_ep_free_request(ep, prm->req_fback); + } prm->req_fback = NULL; } + prm->fb_ep_enabled = false; + if (usb_ep_disable(ep)) dev_err(uac->card->dev, "%s:%d Error!\n", __func__, __LINE__); } diff --git a/drivers/usb/gadget/function/u_serial.c b/drivers/usb/gadget/function/u_serial.c index 281ca766698a..6f68cbeeee7c 100644 --- a/drivers/usb/gadget/function/u_serial.c +++ b/drivers/usb/gadget/function/u_serial.c @@ -1445,51 +1445,53 @@ EXPORT_SYMBOL_GPL(gserial_resume); static int userial_init(void) { + struct tty_driver *driver; unsigned i; int status; - gs_tty_driver = alloc_tty_driver(MAX_U_SERIAL_PORTS); - if (!gs_tty_driver) - return -ENOMEM; + driver = tty_alloc_driver(MAX_U_SERIAL_PORTS, TTY_DRIVER_REAL_RAW | + TTY_DRIVER_DYNAMIC_DEV); + if (IS_ERR(driver)) + return PTR_ERR(driver); - gs_tty_driver->driver_name = "g_serial"; - gs_tty_driver->name = "ttyGS"; + driver->driver_name = "g_serial"; + driver->name = "ttyGS"; /* uses dynamically assigned dev_t values */ - gs_tty_driver->type = TTY_DRIVER_TYPE_SERIAL; - gs_tty_driver->subtype = SERIAL_TYPE_NORMAL; - gs_tty_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV; - gs_tty_driver->init_termios = tty_std_termios; + driver->type = TTY_DRIVER_TYPE_SERIAL; + driver->subtype = SERIAL_TYPE_NORMAL; + driver->init_termios = tty_std_termios; /* 9600-8-N-1 ... matches defaults expected by "usbser.sys" on * MS-Windows. Otherwise, most of these flags shouldn't affect * anything unless we were to actually hook up to a serial line. */ - gs_tty_driver->init_termios.c_cflag = + driver->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL; - gs_tty_driver->init_termios.c_ispeed = 9600; - gs_tty_driver->init_termios.c_ospeed = 9600; + driver->init_termios.c_ispeed = 9600; + driver->init_termios.c_ospeed = 9600; - tty_set_operations(gs_tty_driver, &gs_tty_ops); + tty_set_operations(driver, &gs_tty_ops); for (i = 0; i < MAX_U_SERIAL_PORTS; i++) mutex_init(&ports[i].lock); /* export the driver ... */ - status = tty_register_driver(gs_tty_driver); + status = tty_register_driver(driver); if (status) { pr_err("%s: cannot register, err %d\n", __func__, status); goto fail; } + gs_tty_driver = driver; + pr_debug("%s: registered %d ttyGS* device%s\n", __func__, MAX_U_SERIAL_PORTS, (MAX_U_SERIAL_PORTS == 1) ? "" : "s"); return status; fail: - put_tty_driver(gs_tty_driver); - gs_tty_driver = NULL; + tty_driver_kref_put(driver); return status; } module_init(userial_init); @@ -1497,7 +1499,7 @@ module_init(userial_init); static void userial_cleanup(void) { tty_unregister_driver(gs_tty_driver); - put_tty_driver(gs_tty_driver); + tty_driver_kref_put(gs_tty_driver); gs_tty_driver = NULL; } module_exit(userial_cleanup); diff --git a/drivers/usb/host/xhci-dbgtty.c b/drivers/usb/host/xhci-dbgtty.c index bef104511352..6e784f2fc26d 100644 --- a/drivers/usb/host/xhci-dbgtty.c +++ b/drivers/usb/host/xhci-dbgtty.c @@ -541,7 +541,7 @@ static int dbc_tty_init(void) ret = tty_register_driver(dbc_tty_driver); if (ret) { pr_err("Can't register dbc tty driver\n"); - put_tty_driver(dbc_tty_driver); + tty_driver_kref_put(dbc_tty_driver); } return ret; } @@ -550,7 +550,7 @@ static void dbc_tty_exit(void) { if (dbc_tty_driver) { tty_unregister_driver(dbc_tty_driver); - put_tty_driver(dbc_tty_driver); + tty_driver_kref_put(dbc_tty_driver); dbc_tty_driver = NULL; } } diff --git a/drivers/usb/host/xhci-pci-renesas.c b/drivers/usb/host/xhci-pci-renesas.c index aa88e57649a9..52599d96634f 100644 --- a/drivers/usb/host/xhci-pci-renesas.c +++ b/drivers/usb/host/xhci-pci-renesas.c @@ -207,7 +207,8 @@ static int renesas_check_rom_state(struct pci_dev *pdev) return 0; case RENESAS_ROM_STATUS_NO_RESULT: /* No result yet */ - return 0; + dev_dbg(&pdev->dev, "Unknown ROM status ...\n"); + return -ENOENT; case RENESAS_ROM_STATUS_ERROR: /* Error State */ default: /* All other states are marked as "Reserved states" */ @@ -224,14 +225,6 @@ static int renesas_fw_check_running(struct pci_dev *pdev) u8 fw_state; int err; - /* Check if device has ROM and loaded, if so skip everything */ - err = renesas_check_rom(pdev); - if (err) { /* we have rom */ - err = renesas_check_rom_state(pdev); - if (!err) - return err; - } - /* * Test if the device is actually needing the firmware. As most * BIOSes will initialize the device for us. If the device is @@ -591,21 +584,39 @@ int renesas_xhci_check_request_fw(struct pci_dev *pdev, (struct xhci_driver_data *)id->driver_data; const char *fw_name = driver_data->firmware; const struct firmware *fw; + bool has_rom; int err; + /* Check if device has ROM and loaded, if so skip everything */ + has_rom = renesas_check_rom(pdev); + if (has_rom) { + err = renesas_check_rom_state(pdev); + if (!err) + return 0; + else if (err != -ENOENT) + has_rom = false; + } + err = renesas_fw_check_running(pdev); /* Continue ahead, if the firmware is already running. */ if (!err) return 0; + /* no firmware interface available */ if (err != 1) - return err; + return has_rom ? 0 : err; pci_dev_get(pdev); - err = request_firmware(&fw, fw_name, &pdev->dev); + err = firmware_request_nowarn(&fw, fw_name, &pdev->dev); pci_dev_put(pdev); if (err) { - dev_err(&pdev->dev, "request_firmware failed: %d\n", err); + if (has_rom) { + dev_info(&pdev->dev, "failed to load firmware %s, fallback to ROM\n", + fw_name); + return 0; + } + dev_err(&pdev->dev, "failed to load firmware %s: %d\n", + fw_name, err); return err; } diff --git a/drivers/usb/serial/bus.c b/drivers/usb/serial/bus.c index 7133818a58b9..9e38142acd38 100644 --- a/drivers/usb/serial/bus.c +++ b/drivers/usb/serial/bus.c @@ -74,7 +74,7 @@ err_autopm_put: return retval; } -static int usb_serial_device_remove(struct device *dev) +static void usb_serial_device_remove(struct device *dev) { struct usb_serial_port *port = to_usb_serial_port(dev); struct usb_serial_driver *driver; @@ -101,8 +101,6 @@ static int usb_serial_device_remove(struct device *dev) if (!autopm_err) usb_autopm_put_interface(port->serial->interface); - - return 0; } static ssize_t new_id_store(struct device_driver *driver, diff --git a/drivers/usb/serial/ch341.c b/drivers/usb/serial/ch341.c index 8a521b5ea769..2db917eab799 100644 --- a/drivers/usb/serial/ch341.c +++ b/drivers/usb/serial/ch341.c @@ -851,7 +851,6 @@ static struct usb_serial_driver ch341_device = { .owner = THIS_MODULE, .name = "ch341-uart", }, - .bulk_in_size = 512, .id_table = id_table, .num_ports = 1, .open = ch341_open, diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index 039450069ca4..29c765cc8495 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -2074,6 +2074,8 @@ static const struct usb_device_id option_ids[] = { .driver_info = RSVD(4) | RSVD(5) }, { USB_DEVICE_INTERFACE_CLASS(0x2cb7, 0x0105, 0xff), /* Fibocom NL678 series */ .driver_info = RSVD(6) }, + { 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(0x2df3, 0x9d03, 0xff) }, /* LongSung M5710 */ { USB_DEVICE_INTERFACE_CLASS(0x305a, 0x1404, 0xff) }, /* GosunCn GM500 RNDIS */ diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c index eeb441c77207..090a78c948f2 100644 --- a/drivers/usb/serial/usb-serial.c +++ b/drivers/usb/serial/usb-serial.c @@ -1319,9 +1319,10 @@ static int __init usb_serial_init(void) { int result; - usb_serial_tty_driver = alloc_tty_driver(USB_SERIAL_TTY_MINORS); - if (!usb_serial_tty_driver) - return -ENOMEM; + usb_serial_tty_driver = tty_alloc_driver(USB_SERIAL_TTY_MINORS, + TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV); + if (IS_ERR(usb_serial_tty_driver)) + return PTR_ERR(usb_serial_tty_driver); /* Initialize our global data */ result = bus_register(&usb_serial_bus_type); @@ -1336,8 +1337,6 @@ static int __init usb_serial_init(void) usb_serial_tty_driver->minor_start = 0; usb_serial_tty_driver->type = TTY_DRIVER_TYPE_SERIAL; usb_serial_tty_driver->subtype = SERIAL_TYPE_NORMAL; - usb_serial_tty_driver->flags = TTY_DRIVER_REAL_RAW | - TTY_DRIVER_DYNAMIC_DEV; usb_serial_tty_driver->init_termios = tty_std_termios; usb_serial_tty_driver->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL; @@ -1367,7 +1366,7 @@ exit_reg_driver: exit_bus: pr_err("%s - returning with error %d\n", __func__, result); - put_tty_driver(usb_serial_tty_driver); + tty_driver_kref_put(usb_serial_tty_driver); return result; } @@ -1379,7 +1378,7 @@ static void __exit usb_serial_exit(void) usb_serial_generic_deregister(); tty_unregister_driver(usb_serial_tty_driver); - put_tty_driver(usb_serial_tty_driver); + tty_driver_kref_put(usb_serial_tty_driver); bus_unregister(&usb_serial_bus_type); idr_destroy(&serial_minors); } diff --git a/drivers/usb/typec/bus.c b/drivers/usb/typec/bus.c index 7f3c9a8e2bf0..78e0e78954f2 100644 --- a/drivers/usb/typec/bus.c +++ b/drivers/usb/typec/bus.c @@ -382,7 +382,7 @@ static int typec_probe(struct device *dev) return ret; } -static int typec_remove(struct device *dev) +static void typec_remove(struct device *dev) { struct typec_altmode_driver *drv = to_altmode_driver(dev->driver); struct typec_altmode *adev = to_typec_altmode(dev); @@ -400,8 +400,6 @@ static int typec_remove(struct device *dev) adev->desc = NULL; adev->ops = NULL; - - return 0; } struct bus_type typec_bus = { diff --git a/drivers/usb/typec/tcpm/tcpm.c b/drivers/usb/typec/tcpm/tcpm.c index b981fc39fa3c..a4d37205df54 100644 --- a/drivers/usb/typec/tcpm/tcpm.c +++ b/drivers/usb/typec/tcpm/tcpm.c @@ -343,6 +343,7 @@ struct tcpm_port { bool vbus_source; bool vbus_charge; + /* Set to true when Discover_Identity Command is expected to be sent in Ready states. */ bool send_discover; bool op_vsafe5v; @@ -372,6 +373,7 @@ struct tcpm_port { struct hrtimer send_discover_timer; struct kthread_work send_discover_work; bool state_machine_running; + /* Set to true when VDM State Machine has following actions. */ bool vdm_sm_running; struct completion tx_complete; @@ -1436,6 +1438,7 @@ static void tcpm_queue_vdm(struct tcpm_port *port, const u32 header, /* Set ready, vdm state machine will actually send */ port->vdm_retries = 0; port->vdm_state = VDM_STATE_READY; + port->vdm_sm_running = true; mod_vdm_delayed_work(port, 0); } @@ -1678,7 +1681,6 @@ static int tcpm_pd_svdm(struct tcpm_port *port, struct typec_altmode *adev, rlen = 1; } else { tcpm_register_partner_altmodes(port); - port->vdm_sm_running = false; } break; case CMD_ENTER_MODE: @@ -1726,14 +1728,12 @@ static int tcpm_pd_svdm(struct tcpm_port *port, struct typec_altmode *adev, (VDO_SVDM_VERS(svdm_version)); break; } - port->vdm_sm_running = false; break; default: response[0] = p[0] | VDO_CMDT(CMDT_RSP_NAK); rlen = 1; response[0] = (response[0] & ~VDO_SVDM_VERS_MASK) | (VDO_SVDM_VERS(svdm_version)); - port->vdm_sm_running = false; break; } @@ -1774,6 +1774,20 @@ static void tcpm_handle_vdm_request(struct tcpm_port *port, } if (PD_VDO_SVDM(p[0]) && (adev || tcpm_vdm_ams(port) || port->nr_snk_vdo)) { + /* + * Here a SVDM is received (INIT or RSP or unknown). Set the vdm_sm_running in + * advance because we are dropping the lock but may send VDMs soon. + * For the cases of INIT received: + * - If no response to send, it will be cleared later in this function. + * - If there are responses to send, it will be cleared in the state machine. + * For the cases of RSP received: + * - If no further INIT to send, it will be cleared later in this function. + * - Otherwise, it will be cleared in the state machine if timeout or it will go + * back here until no further INIT to send. + * For the cases of unknown type received: + * - We will send NAK and the flag will be cleared in the state machine. + */ + port->vdm_sm_running = true; rlen = tcpm_pd_svdm(port, adev, p, cnt, response, &adev_action); } else { if (port->negotiated_rev >= PD_REV30) @@ -1842,6 +1856,8 @@ static void tcpm_handle_vdm_request(struct tcpm_port *port, if (rlen > 0) tcpm_queue_vdm(port, response[0], &response[1], rlen - 1); + else + port->vdm_sm_running = false; } static void tcpm_send_vdm(struct tcpm_port *port, u32 vid, int cmd, @@ -1907,8 +1923,10 @@ static void vdm_run_state_machine(struct tcpm_port *port) * if there's traffic or we're not in PDO ready state don't send * a VDM. */ - if (port->state != SRC_READY && port->state != SNK_READY) + if (port->state != SRC_READY && port->state != SNK_READY) { + port->vdm_sm_running = false; break; + } /* TODO: AMS operation for Unstructured VDM */ if (PD_VDO_SVDM(vdo_hdr) && PD_VDO_CMDT(vdo_hdr) == CMDT_INIT) { @@ -2561,10 +2579,6 @@ static void tcpm_pd_ctrl_request(struct tcpm_port *port, TYPEC_PWR_MODE_PD, port->pps_data.active, port->supply_voltage); - /* Set VDM running flag ASAP */ - if (port->data_role == TYPEC_HOST && - port->send_discover) - port->vdm_sm_running = true; tcpm_set_state(port, SNK_READY, 0); } else { /* @@ -2602,14 +2616,10 @@ static void tcpm_pd_ctrl_request(struct tcpm_port *port, switch (port->state) { case SNK_NEGOTIATE_CAPABILITIES: /* USB PD specification, Figure 8-43 */ - if (port->explicit_contract) { + if (port->explicit_contract) next_state = SNK_READY; - if (port->data_role == TYPEC_HOST && - port->send_discover) - port->vdm_sm_running = true; - } else { + else next_state = SNK_WAIT_CAPABILITIES; - } /* Threshold was relaxed before sending Request. Restore it back. */ tcpm_set_auto_vbus_discharge_threshold(port, TYPEC_PWR_MODE_PD, @@ -2624,10 +2634,6 @@ static void tcpm_pd_ctrl_request(struct tcpm_port *port, port->pps_status = (type == PD_CTRL_WAIT ? -EAGAIN : -EOPNOTSUPP); - if (port->data_role == TYPEC_HOST && - port->send_discover) - port->vdm_sm_running = true; - /* Threshold was relaxed before sending Request. Restore it back. */ tcpm_set_auto_vbus_discharge_threshold(port, TYPEC_PWR_MODE_PD, port->pps_data.active, @@ -2703,10 +2709,6 @@ static void tcpm_pd_ctrl_request(struct tcpm_port *port, } break; case DR_SWAP_SEND: - if (port->data_role == TYPEC_DEVICE && - port->send_discover) - port->vdm_sm_running = true; - tcpm_set_state(port, DR_SWAP_CHANGE_DR, 0); break; case PR_SWAP_SEND: @@ -2744,7 +2746,7 @@ static void tcpm_pd_ctrl_request(struct tcpm_port *port, PD_MSG_CTRL_NOT_SUPP, NONE_AMS); } else { - if (port->vdm_sm_running) { + if (port->send_discover) { tcpm_queue_message(port, PD_MSG_CTRL_WAIT); break; } @@ -2760,7 +2762,7 @@ static void tcpm_pd_ctrl_request(struct tcpm_port *port, PD_MSG_CTRL_NOT_SUPP, NONE_AMS); } else { - if (port->vdm_sm_running) { + if (port->send_discover) { tcpm_queue_message(port, PD_MSG_CTRL_WAIT); break; } @@ -2769,7 +2771,7 @@ static void tcpm_pd_ctrl_request(struct tcpm_port *port, } break; case PD_CTRL_VCONN_SWAP: - if (port->vdm_sm_running) { + if (port->send_discover) { tcpm_queue_message(port, PD_MSG_CTRL_WAIT); break; } @@ -4510,18 +4512,20 @@ static void run_state_machine(struct tcpm_port *port) /* DR_Swap states */ case DR_SWAP_SEND: tcpm_pd_send_control(port, PD_CTRL_DR_SWAP); + if (port->data_role == TYPEC_DEVICE || port->negotiated_rev > PD_REV20) + port->send_discover = true; tcpm_set_state_cond(port, DR_SWAP_SEND_TIMEOUT, PD_T_SENDER_RESPONSE); break; case DR_SWAP_ACCEPT: tcpm_pd_send_control(port, PD_CTRL_ACCEPT); - /* Set VDM state machine running flag ASAP */ - if (port->data_role == TYPEC_DEVICE && port->send_discover) - port->vdm_sm_running = true; + if (port->data_role == TYPEC_DEVICE || port->negotiated_rev > PD_REV20) + port->send_discover = true; tcpm_set_state_cond(port, DR_SWAP_CHANGE_DR, 0); break; case DR_SWAP_SEND_TIMEOUT: tcpm_swap_complete(port, -ETIMEDOUT); + port->send_discover = false; tcpm_ams_finish(port); tcpm_set_state(port, ready_state(port), 0); break; @@ -4533,7 +4537,6 @@ static void run_state_machine(struct tcpm_port *port) } else { tcpm_set_roles(port, true, port->pwr_role, TYPEC_HOST); - port->send_discover = true; } tcpm_ams_finish(port); tcpm_set_state(port, ready_state(port), 0); @@ -4676,8 +4679,6 @@ static void run_state_machine(struct tcpm_port *port) break; case VCONN_SWAP_SEND_TIMEOUT: tcpm_swap_complete(port, -ETIMEDOUT); - if (port->data_role == TYPEC_HOST && port->send_discover) - port->vdm_sm_running = true; tcpm_set_state(port, ready_state(port), 0); break; case VCONN_SWAP_START: @@ -4693,14 +4694,10 @@ static void run_state_machine(struct tcpm_port *port) case VCONN_SWAP_TURN_ON_VCONN: tcpm_set_vconn(port, true); tcpm_pd_send_control(port, PD_CTRL_PS_RDY); - if (port->data_role == TYPEC_HOST && port->send_discover) - port->vdm_sm_running = true; tcpm_set_state(port, ready_state(port), 0); break; case VCONN_SWAP_TURN_OFF_VCONN: tcpm_set_vconn(port, false); - if (port->data_role == TYPEC_HOST && port->send_discover) - port->vdm_sm_running = true; tcpm_set_state(port, ready_state(port), 0); break; @@ -4708,8 +4705,6 @@ static void run_state_machine(struct tcpm_port *port) case PR_SWAP_CANCEL: case VCONN_SWAP_CANCEL: tcpm_swap_complete(port, port->swap_status); - if (port->data_role == TYPEC_HOST && port->send_discover) - port->vdm_sm_running = true; if (port->pwr_role == TYPEC_SOURCE) tcpm_set_state(port, SRC_READY, 0); else @@ -5059,9 +5054,6 @@ static void _tcpm_pd_vbus_on(struct tcpm_port *port) switch (port->state) { case SNK_TRANSITION_SINK_VBUS: port->explicit_contract = true; - /* Set the VDM flag ASAP */ - if (port->data_role == TYPEC_HOST && port->send_discover) - port->vdm_sm_running = true; tcpm_set_state(port, SNK_READY, 0); break; case SNK_DISCOVERY: @@ -5456,15 +5448,18 @@ static void tcpm_send_discover_work(struct kthread_work *work) if (!port->send_discover) goto unlock; + if (port->data_role == TYPEC_DEVICE && port->negotiated_rev < PD_REV30) { + port->send_discover = false; + goto unlock; + } + /* Retry if the port is not idle */ if ((port->state != SRC_READY && port->state != SNK_READY) || port->vdm_sm_running) { mod_send_discover_delayed_work(port, SEND_DISCOVER_RETRY_MS); goto unlock; } - /* Only send the Message if the port is host for PD rev2.0 */ - if (port->data_role == TYPEC_HOST || port->negotiated_rev > PD_REV20) - tcpm_send_vdm(port, USB_SID_PD, CMD_DISCOVER_IDENT, NULL, 0); + tcpm_send_vdm(port, USB_SID_PD, CMD_DISCOVER_IDENT, NULL, 0); unlock: mutex_unlock(&port->lock); |