diff options
Diffstat (limited to 'drivers/usb')
| -rw-r--r-- | drivers/usb/dwc2/gadget.c | 11 | ||||
| -rw-r--r-- | drivers/usb/dwc3/gadget.c | 1 | ||||
| -rw-r--r-- | drivers/usb/gadget/function/f_fs.c | 14 | ||||
| -rw-r--r-- | drivers/usb/gadget/function/f_midi2.c | 2 | ||||
| -rw-r--r-- | drivers/usb/gadget/function/f_tcm.c | 23 | ||||
| -rw-r--r-- | drivers/usb/gadget/function/f_uvc.c | 7 | ||||
| -rw-r--r-- | drivers/usb/gadget/function/u_audio.c | 24 | ||||
| -rw-r--r-- | drivers/usb/gadget/function/uvc_video.c | 2 | ||||
| -rw-r--r-- | drivers/usb/gadget/udc/at91_udc.c | 20 | ||||
| -rw-r--r-- | drivers/usb/gadget/udc/snps_udc_plat.c | 5 | ||||
| -rw-r--r-- | drivers/usb/phy/phy-fsl-usb.c | 52 | ||||
| -rw-r--r-- | drivers/usb/phy/phy-fsl-usb.h | 6 | ||||
| -rw-r--r-- | drivers/usb/typec/altmodes/thunderbolt.c | 2 | ||||
| -rw-r--r-- | drivers/usb/typec/tcpm/tcpci.c | 12 | ||||
| -rw-r--r-- | drivers/usb/typec/ucsi/ucsi.c | 3 |
15 files changed, 125 insertions, 59 deletions
diff --git a/drivers/usb/dwc2/gadget.c b/drivers/usb/dwc2/gadget.c index a6c2b8de3908..8282de6df011 100644 --- a/drivers/usb/dwc2/gadget.c +++ b/drivers/usb/dwc2/gadget.c @@ -4680,6 +4680,7 @@ static int dwc2_hsotg_pullup(struct usb_gadget *gadget, int is_on) { struct dwc2_hsotg *hsotg = to_hsotg(gadget); unsigned long flags; + int ret = 0; dev_dbg(hsotg->dev, "%s: is_on: %d op_state: %d\n", __func__, is_on, hsotg->op_state); @@ -4691,6 +4692,13 @@ static int dwc2_hsotg_pullup(struct usb_gadget *gadget, int is_on) } spin_lock_irqsave(&hsotg->lock, flags); + if (hsotg->in_ppd) { + ret = dwc2_exit_partial_power_down(hsotg, 0, true); + if (ret) { + dev_err(hsotg->dev, "exit partial_power_down failed\n"); + goto exit; + } + } if (is_on) { hsotg->enabled = 1; dwc2_hsotg_core_init_disconnected(hsotg, false); @@ -4704,9 +4712,10 @@ static int dwc2_hsotg_pullup(struct usb_gadget *gadget, int is_on) } hsotg->gadget.speed = USB_SPEED_UNKNOWN; +exit: spin_unlock_irqrestore(&hsotg->lock, flags); - return 0; + return ret; } static int dwc2_hsotg_vbus_session(struct usb_gadget *gadget, int is_active) diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index ea8487d4bbb3..a2c735276909 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -3497,6 +3497,7 @@ static void dwc3_gadget_free_endpoints(struct dwc3 *dwc) } dwc3_debugfs_remove_endpoint_dir(dep); + cancel_delayed_work_sync(&dep->nostream_work); kfree(dep); } } diff --git a/drivers/usb/gadget/function/f_fs.c b/drivers/usb/gadget/function/f_fs.c index 311606097718..15e8ca3a616b 100644 --- a/drivers/usb/gadget/function/f_fs.c +++ b/drivers/usb/gadget/function/f_fs.c @@ -549,6 +549,7 @@ static ssize_t ffs_ep0_read(struct file *file, char __user *buf, if (ffs_setup_state_clear_cancelled(ffs) == FFS_SETUP_CANCELLED) return -EIDRM; +retry: /* Acquire mutex */ ret = ffs_mutex_lock(&ffs->mutex, file->f_flags & O_NONBLOCK); if (ret < 0) @@ -583,10 +584,15 @@ static ssize_t ffs_ep0_read(struct file *file, char __user *buf, break; } - if (wait_event_interruptible_exclusive_locked_irq(ffs->ev.waitq, - ffs->ev.count)) { - ret = -EINTR; - break; + if (!ffs->ev.count) { + spin_unlock_irq(&ffs->ev.waitq.lock); + mutex_unlock(&ffs->mutex); + + if (wait_event_interruptible_exclusive(ffs->ev.waitq, + ffs->ev.count)) + return -EINTR; + + goto retry; } /* unlocks spinlock */ diff --git a/drivers/usb/gadget/function/f_midi2.c b/drivers/usb/gadget/function/f_midi2.c index de16b02d857e..0199d95ff803 100644 --- a/drivers/usb/gadget/function/f_midi2.c +++ b/drivers/usb/gadget/function/f_midi2.c @@ -2474,6 +2474,7 @@ static void f_midi2_ep_opts_release(struct config_item *item) { struct f_midi2_ep_opts *opts = to_f_midi2_ep_opts(item); + configfs_remove_default_groups(&opts->group); kfree(opts->info.ep_name); kfree(opts->info.product_id); kfree(opts); @@ -2640,6 +2641,7 @@ static void f_midi2_free_inst(struct usb_function_instance *f) opts = container_of(f, struct f_midi2_opts, func_inst); + configfs_remove_default_groups(&opts->func_inst.group); kfree(opts->info.iface_name); kfree(opts); } diff --git a/drivers/usb/gadget/function/f_tcm.c b/drivers/usb/gadget/function/f_tcm.c index 09d72bb4f855..02c5d9cfda45 100644 --- a/drivers/usb/gadget/function/f_tcm.c +++ b/drivers/usb/gadget/function/f_tcm.c @@ -1674,19 +1674,25 @@ static struct se_portal_group *usbg_make_tpg(struct se_wwn *wwn, opts = container_of(tpg_instances[i].func_inst, struct f_tcm_opts, func_inst); - mutex_lock(&opts->dep_lock); - if (!opts->ready) - goto unlock_dep; + if (!READ_ONCE(opts->ready)) + goto unlock_inst; if (opts->has_dep) { if (!try_module_get(opts->dependent)) - goto unlock_dep; + goto unlock_inst; } else { + /* + * configfs_depend_item_unlocked() may acquire the configfs + * root inode lock when the target belongs to a different + * subsystem. Calling it under dep_lock would create a + * circular dependency: + * dep_lock -> configfs inode lock -> su_mutex -> dep_lock + */ ret = configfs_depend_item_unlocked( wwn->wwn_group.cg_subsys, &opts->func_inst.group.cg_item); if (ret) - goto unlock_dep; + goto unlock_inst; } tpg = kzalloc(sizeof(struct usbg_tpg), GFP_KERNEL); @@ -1713,7 +1719,6 @@ static struct se_portal_group *usbg_make_tpg(struct se_wwn *wwn, tpg_instances[i].tpg = tpg; tpg->fi = tpg_instances[i].func_inst; - mutex_unlock(&opts->dep_lock); mutex_unlock(&tpg_instances_lock); return &tpg->se_tpg; @@ -1726,8 +1731,6 @@ unref_dep: module_put(opts->dependent); else configfs_undepend_item_unlocked(&opts->func_inst.group.cg_item); -unlock_dep: - mutex_unlock(&opts->dep_lock); unlock_inst: mutex_unlock(&tpg_instances_lock); @@ -2664,9 +2667,7 @@ static int tcm_set_name(struct usb_function_instance *f, const char *name) pr_debug("tcm: Activating %s\n", name); - mutex_lock(&opts->dep_lock); - opts->ready = true; - mutex_unlock(&opts->dep_lock); + WRITE_ONCE(opts->ready, true); return 0; } diff --git a/drivers/usb/gadget/function/f_uvc.c b/drivers/usb/gadget/function/f_uvc.c index 72601e15563c..ab77e6bf001a 100644 --- a/drivers/usb/gadget/function/f_uvc.c +++ b/drivers/usb/gadget/function/f_uvc.c @@ -889,9 +889,12 @@ error_unlock: v4l2_error: v4l2_device_unregister(&uvc->v4l2_dev); error: - if (uvc->control_req) + if (uvc->control_req) { usb_ep_free_request(cdev->gadget->ep0, uvc->control_req); + uvc->control_req = NULL; + } kfree(uvc->control_buf); + uvc->control_buf = NULL; usb_free_all_descriptors(f); return ret; @@ -1075,7 +1078,9 @@ static void uvc_function_unbind(struct usb_configuration *c, uvc->vdev_release_done = NULL; usb_ep_free_request(cdev->gadget->ep0, uvc->control_req); + uvc->control_req = NULL; kfree(uvc->control_buf); + uvc->control_buf = NULL; usb_free_all_descriptors(f); } diff --git a/drivers/usb/gadget/function/u_audio.c b/drivers/usb/gadget/function/u_audio.c index ca8dbec65f73..24c673dcbbd7 100644 --- a/drivers/usb/gadget/function/u_audio.c +++ b/drivers/usb/gadget/function/u_audio.c @@ -1177,6 +1177,20 @@ static struct snd_kcontrol_new u_audio_controls[] = { }, }; +static void u_audio_card_free(struct snd_card *card) +{ + struct snd_uac_chip *uac = card->private_data; + + if (!uac) + return; + + kfree(uac->p_prm.reqs); + kfree(uac->c_prm.reqs); + kfree(uac->p_prm.rbuf); + kfree(uac->c_prm.rbuf); + kfree(uac); +} + int g_audio_setup(struct g_audio *g_audio, const char *pcm_name, const char *card_name) { @@ -1258,6 +1272,8 @@ int g_audio_setup(struct g_audio *g_audio, const char *pcm_name, goto fail; uac->card = card; + card->private_data = uac; + card->private_free = u_audio_card_free; /* * Create first PCM device @@ -1426,6 +1442,8 @@ int g_audio_setup(struct g_audio *g_audio, const char *pcm_name, snd_fail: snd_card_free(card); + return err; + fail: kfree(uac->p_prm.reqs); kfree(uac->c_prm.reqs); @@ -1451,12 +1469,6 @@ void g_audio_cleanup(struct g_audio *g_audio) card = uac->card; if (card) snd_card_free_when_closed(card); - - kfree(uac->p_prm.reqs); - kfree(uac->c_prm.reqs); - kfree(uac->p_prm.rbuf); - kfree(uac->c_prm.rbuf); - kfree(uac); } EXPORT_SYMBOL_GPL(g_audio_cleanup); diff --git a/drivers/usb/gadget/function/uvc_video.c b/drivers/usb/gadget/function/uvc_video.c index f24746e72877..dd9105a8ef78 100644 --- a/drivers/usb/gadget/function/uvc_video.c +++ b/drivers/usb/gadget/function/uvc_video.c @@ -821,7 +821,7 @@ int uvcg_video_init(struct uvc_video *video, struct uvc_device *uvc) /* Allocate a kthread for asynchronous hw submit handler. */ video->kworker = kthread_run_worker(0, "UVCG"); if (IS_ERR(video->kworker)) { - uvcg_err(&video->uvc->func, "failed to create UVCG kworker\n"); + uvcg_err(&uvc->func, "failed to create UVCG kworker\n"); return PTR_ERR(video->kworker); } diff --git a/drivers/usb/gadget/udc/at91_udc.c b/drivers/usb/gadget/udc/at91_udc.c index 42b94d858e37..005152798000 100644 --- a/drivers/usb/gadget/udc/at91_udc.c +++ b/drivers/usb/gadget/udc/at91_udc.c @@ -1794,6 +1794,19 @@ static void at91udc_of_init(struct at91_udc *udc, struct device_node *np) udc->caps = match->data; } +/* + * The work handler re-arms this timer, so shut the timer down before + * draining the work; otherwise it restarts the polling cycle. + */ +static void at91_udc_shutdown_vbus_timer(struct at91_udc *udc) +{ + if (!(udc->board.vbus_pin && udc->board.vbus_polled)) + return; + + timer_shutdown_sync(&udc->vbus_timer); + cancel_work_sync(&udc->vbus_timer_work); +} + static int at91udc_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; @@ -1907,7 +1920,7 @@ static int at91udc_probe(struct platform_device *pdev) } retval = usb_add_gadget_udc(dev, &udc->gadget); if (retval) - goto err_unprepare_iclk; + goto err_shutdown_vbus; dev_set_drvdata(dev, udc); device_init_wakeup(dev, 1); create_debug_file(udc); @@ -1915,6 +1928,8 @@ static int at91udc_probe(struct platform_device *pdev) INFO("%s version %s\n", driver_name, DRIVER_VERSION); return 0; +err_shutdown_vbus: + at91_udc_shutdown_vbus_timer(udc); err_unprepare_iclk: clk_unprepare(udc->iclk); err_unprepare_fclk: @@ -1933,6 +1948,9 @@ static void at91udc_remove(struct platform_device *pdev) DBG("remove\n"); usb_del_gadget_udc(&udc->gadget); + + at91_udc_shutdown_vbus_timer(udc); + if (udc->driver) { dev_err(&pdev->dev, "Driver still in use but removing anyhow\n"); diff --git a/drivers/usb/gadget/udc/snps_udc_plat.c b/drivers/usb/gadget/udc/snps_udc_plat.c index db842a6de643..0ee3ed185d9c 100644 --- a/drivers/usb/gadget/udc/snps_udc_plat.c +++ b/drivers/usb/gadget/udc/snps_udc_plat.c @@ -159,10 +159,9 @@ static int udc_plat_probe(struct platform_device *pdev) if (of_property_present(dev->of_node, "extcon")) { udc->edev = extcon_get_edev_by_phandle(dev, 0); if (IS_ERR(udc->edev)) { - if (PTR_ERR(udc->edev) == -EPROBE_DEFER) - return -EPROBE_DEFER; - dev_err(dev, "Invalid or missing extcon\n"); ret = PTR_ERR(udc->edev); + if (ret != -EPROBE_DEFER) + dev_err(dev, "Invalid or missing extcon\n"); goto exit_phy; } diff --git a/drivers/usb/phy/phy-fsl-usb.c b/drivers/usb/phy/phy-fsl-usb.c index e266a47c4d48..1c405e5dc32c 100644 --- a/drivers/usb/phy/phy-fsl-usb.c +++ b/drivers/usb/phy/phy-fsl-usb.c @@ -46,7 +46,7 @@ static const char driver_name[] = "fsl-usb2-otg"; -const pm_message_t otg_suspend_state = { +static const pm_message_t otg_suspend_state = { .event = 1, }; @@ -57,11 +57,11 @@ static struct fsl_otg *fsl_otg_dev; static int srp_wait_done; /* FSM timers */ -struct fsl_otg_timer *a_wait_vrise_tmr, *a_wait_bcon_tmr, *a_aidl_bdis_tmr, +static struct fsl_otg_timer *a_wait_vrise_tmr, *a_wait_bcon_tmr, *a_aidl_bdis_tmr, *b_ase0_brst_tmr, *b_se0_srp_tmr; /* Driver specific timers */ -struct fsl_otg_timer *b_data_pulse_tmr, *b_vbus_pulse_tmr, *b_srp_fail_tmr, +static struct fsl_otg_timer *b_data_pulse_tmr, *b_vbus_pulse_tmr, *b_srp_fail_tmr, *b_srp_wait_tmr, *a_wait_enum_tmr; static struct list_head active_timers; @@ -102,7 +102,7 @@ static void (*_fsl_writel)(u32 v, unsigned __iomem *p); #define fsl_writel(val, addr) writel(val, addr) #endif /* CONFIG_PPC32 */ -int write_ulpi(u8 addr, u8 data) +static int write_ulpi(u8 addr, u8 data) { u32 temp; @@ -115,7 +115,7 @@ int write_ulpi(u8 addr, u8 data) /* Operations that will be called from OTG Finite State Machine */ /* Charge vbus for vbus pulsing in SRP */ -void fsl_otg_chrg_vbus(struct otg_fsm *fsm, int on) +static void fsl_otg_chrg_vbus(struct otg_fsm *fsm, int on) { u32 tmp; @@ -133,7 +133,7 @@ void fsl_otg_chrg_vbus(struct otg_fsm *fsm, int on) } /* Discharge vbus through a resistor to ground */ -void fsl_otg_dischrg_vbus(int on) +static void fsl_otg_dischrg_vbus(int on) { u32 tmp; @@ -151,7 +151,7 @@ void fsl_otg_dischrg_vbus(int on) } /* A-device driver vbus, controlled through PP bit in PORTSC */ -void fsl_otg_drv_vbus(struct otg_fsm *fsm, int on) +static void fsl_otg_drv_vbus(struct otg_fsm *fsm, int on) { u32 tmp; @@ -169,7 +169,7 @@ void fsl_otg_drv_vbus(struct otg_fsm *fsm, int on) * Pull-up D+, signalling connect by periperal. Also used in * data-line pulsing in SRP */ -void fsl_otg_loc_conn(struct otg_fsm *fsm, int on) +static void fsl_otg_loc_conn(struct otg_fsm *fsm, int on) { u32 tmp; @@ -188,7 +188,7 @@ void fsl_otg_loc_conn(struct otg_fsm *fsm, int on) * port. In host mode, controller will automatically send SOF. * Suspend will block the data on the port. */ -void fsl_otg_loc_sof(struct otg_fsm *fsm, int on) +static void fsl_otg_loc_sof(struct otg_fsm *fsm, int on) { u32 tmp; @@ -203,7 +203,7 @@ void fsl_otg_loc_sof(struct otg_fsm *fsm, int on) } /* Start SRP pulsing by data-line pulsing, followed with v-bus pulsing. */ -void fsl_otg_start_pulse(struct otg_fsm *fsm) +static void fsl_otg_start_pulse(struct otg_fsm *fsm) { u32 tmp; @@ -219,7 +219,7 @@ void fsl_otg_start_pulse(struct otg_fsm *fsm) fsl_otg_add_timer(fsm, b_data_pulse_tmr); } -void b_data_pulse_end(unsigned long foo) +static void b_data_pulse_end(unsigned long foo) { #ifdef HA_DATA_PULSE #else @@ -230,7 +230,7 @@ void b_data_pulse_end(unsigned long foo) fsl_otg_pulse_vbus(); } -void fsl_otg_pulse_vbus(void) +static void fsl_otg_pulse_vbus(void) { srp_wait_done = 0; fsl_otg_chrg_vbus(&fsl_otg_dev->fsm, 1); @@ -238,7 +238,7 @@ void fsl_otg_pulse_vbus(void) fsl_otg_add_timer(&fsl_otg_dev->fsm, b_vbus_pulse_tmr); } -void b_vbus_pulse_end(unsigned long foo) +static void b_vbus_pulse_end(unsigned long foo) { fsl_otg_chrg_vbus(&fsl_otg_dev->fsm, 0); @@ -251,7 +251,7 @@ void b_vbus_pulse_end(unsigned long foo) fsl_otg_add_timer(&fsl_otg_dev->fsm, b_srp_wait_tmr); } -void b_srp_end(unsigned long foo) +static void b_srp_end(unsigned long foo) { fsl_otg_dischrg_vbus(0); srp_wait_done = 1; @@ -266,7 +266,7 @@ void b_srp_end(unsigned long foo) * a_host will start by SRP. It needs to set b_hnp_enable before * actually suspending to start HNP */ -void a_wait_enum(unsigned long foo) +static void a_wait_enum(unsigned long foo) { VDBG("a_wait_enum timeout\n"); if (!fsl_otg_dev->phy.otg->host->b_hnp_enable) @@ -276,13 +276,13 @@ void a_wait_enum(unsigned long foo) } /* The timeout callback function to set time out bit */ -void set_tmout(unsigned long indicator) +static void set_tmout(unsigned long indicator) { *(int *)indicator = 1; } /* Initialize timers */ -int fsl_otg_init_timers(struct otg_fsm *fsm) +static int fsl_otg_init_timers(struct otg_fsm *fsm) { /* FSM used timers */ a_wait_vrise_tmr = otg_timer_initializer(&set_tmout, TA_WAIT_VRISE, @@ -339,7 +339,7 @@ int fsl_otg_init_timers(struct otg_fsm *fsm) } /* Uninitialize timers */ -void fsl_otg_uninit_timers(void) +static void fsl_otg_uninit_timers(void) { /* FSM used timers */ kfree(a_wait_vrise_tmr); @@ -391,7 +391,7 @@ static struct fsl_otg_timer *fsl_otg_get_timer(enum otg_fsm_timer t) } /* Add timer to timer list */ -void fsl_otg_add_timer(struct otg_fsm *fsm, void *gtimer) +static void fsl_otg_add_timer(struct otg_fsm *fsm, void *gtimer) { struct fsl_otg_timer *timer = gtimer; struct fsl_otg_timer *tmp_timer; @@ -421,7 +421,7 @@ static void fsl_otg_fsm_add_timer(struct otg_fsm *fsm, enum otg_fsm_timer t) } /* Remove timer from the timer list; clear timeout status */ -void fsl_otg_del_timer(struct otg_fsm *fsm, void *gtimer) +static void fsl_otg_del_timer(struct otg_fsm *fsm, void *gtimer) { struct fsl_otg_timer *timer = gtimer; struct fsl_otg_timer *tmp_timer, *del_tmp; @@ -443,7 +443,7 @@ static void fsl_otg_fsm_del_timer(struct otg_fsm *fsm, enum otg_fsm_timer t) } /* Reset controller, not reset the bus */ -void otg_reset_controller(void) +static void otg_reset_controller(void) { u32 command; @@ -455,7 +455,7 @@ void otg_reset_controller(void) } /* Call suspend/resume routines in host driver */ -int fsl_otg_start_host(struct otg_fsm *fsm, int on) +static int fsl_otg_start_host(struct otg_fsm *fsm, int on) { struct usb_otg *otg = fsm->otg; struct device *dev; @@ -522,7 +522,7 @@ end: * Call suspend and resume function in udc driver * to stop and start udc driver. */ -int fsl_otg_start_gadget(struct otg_fsm *fsm, int on) +static int fsl_otg_start_gadget(struct otg_fsm *fsm, int on) { struct usb_otg *otg = fsm->otg; struct device *dev; @@ -704,7 +704,7 @@ static int fsl_otg_start_hnp(struct usb_otg *otg) * intact. It needs to have knowledge of some USB interrupts * such as port change. */ -irqreturn_t fsl_otg_isr(int irq, void *dev_id) +static irqreturn_t fsl_otg_isr(int irq, void *dev_id) { struct otg_fsm *fsm = &((struct fsl_otg *)dev_id)->fsm; struct usb_otg *otg = ((struct fsl_otg *)dev_id)->phy.otg; @@ -830,7 +830,7 @@ err: } /* OTG Initialization */ -int usb_otg_start(struct platform_device *pdev) +static int usb_otg_start(struct platform_device *pdev) { struct fsl_otg *p_otg; struct usb_phy *otg_trans = usb_get_phy(USB_PHY_TYPE_USB2); @@ -1002,7 +1002,7 @@ static void fsl_otg_remove(struct platform_device *pdev) pdata->exit(pdev); } -struct platform_driver fsl_otg_driver = { +static struct platform_driver fsl_otg_driver = { .probe = fsl_otg_probe, .remove = fsl_otg_remove, .driver = { diff --git a/drivers/usb/phy/phy-fsl-usb.h b/drivers/usb/phy/phy-fsl-usb.h index d70341ae5a92..cc841c4e4762 100644 --- a/drivers/usb/phy/phy-fsl-usb.h +++ b/drivers/usb/phy/phy-fsl-usb.h @@ -373,6 +373,6 @@ struct fsl_otg_config { #define FSL_OTG_NAME "fsl-usb2-otg" -void fsl_otg_add_timer(struct otg_fsm *fsm, void *timer); -void fsl_otg_del_timer(struct otg_fsm *fsm, void *timer); -void fsl_otg_pulse_vbus(void); +static void fsl_otg_add_timer(struct otg_fsm *fsm, void *timer); +static void fsl_otg_del_timer(struct otg_fsm *fsm, void *timer); +static void fsl_otg_pulse_vbus(void); diff --git a/drivers/usb/typec/altmodes/thunderbolt.c b/drivers/usb/typec/altmodes/thunderbolt.c index d09dd09cf1c3..1f4dab8d6264 100644 --- a/drivers/usb/typec/altmodes/thunderbolt.c +++ b/drivers/usb/typec/altmodes/thunderbolt.c @@ -303,6 +303,8 @@ static void tbt_altmode_remove(struct typec_altmode *alt) { struct tbt_altmode *tbt = typec_altmode_get_drvdata(alt); + disable_work_sync(&tbt->work); + for (int i = TYPEC_PLUG_SOP_PP; i >= 0; --i) { if (tbt->plug[i]) typec_altmode_put_plug(tbt->plug[i]); diff --git a/drivers/usb/typec/tcpm/tcpci.c b/drivers/usb/typec/tcpm/tcpci.c index 2a951c585e92..3be5d3f58c50 100644 --- a/drivers/usb/typec/tcpm/tcpci.c +++ b/drivers/usb/typec/tcpm/tcpci.c @@ -37,6 +37,7 @@ struct tcpci { struct regmap *regmap; unsigned int alert_mask; + unsigned int rx_type_mask; bool controls_vbus; @@ -485,6 +486,8 @@ static int tcpci_set_pd_rx(struct tcpc_dev *tcpc, bool enable) if (tcpci->data->cable_comm_capable) reg |= TCPC_RX_DETECT_SOP1; } + + tcpci->rx_type_mask = reg; ret = regmap_write(tcpci->regmap, TCPC_RX_DETECT, reg); if (ret < 0) return ret; @@ -746,6 +749,7 @@ process_status: if (status & TCPC_ALERT_RX_STATUS) { struct pd_message msg; unsigned int cnt, payload_cnt; + enum tcpm_transmit_type rx_type; u16 header; regmap_read(tcpci->regmap, TCPC_RX_BYTE_CNT, &cnt); @@ -770,10 +774,16 @@ process_status: regmap_raw_read(tcpci->regmap, TCPC_RX_DATA, &msg.payload, payload_cnt); + ret = regmap_read(tcpci->regmap, TCPC_RX_BUF_FRAME_TYPE, &rx_type); + if (ret) + return ret; + /* Read complete, clear RX status alert bit */ tcpci_write16(tcpci, TCPC_ALERT, TCPC_ALERT_RX_STATUS); - tcpm_pd_receive(tcpci->port, &msg, TCPC_TX_SOP); + rx_type &= TCPC_RX_BUF_FRAME_TYPE_MASK; + if (tcpci->rx_type_mask & BIT(rx_type)) + tcpm_pd_receive(tcpci->port, &msg, rx_type); } if (tcpci->data->vbus_vsafe0v && (status & TCPC_ALERT_EXTENDED_STATUS)) { diff --git a/drivers/usb/typec/ucsi/ucsi.c b/drivers/usb/typec/ucsi/ucsi.c index 0d1062191951..85e2e7fcd02c 100644 --- a/drivers/usb/typec/ucsi/ucsi.c +++ b/drivers/usb/typec/ucsi/ucsi.c @@ -78,7 +78,8 @@ int ucsi_sync_control_common(struct ucsi *ucsi, u64 command, u32 *cci, if (ret) goto out_clear_bit; - if (!wait_for_completion_timeout(&ucsi->complete, 5 * HZ)) + if (!wait_for_completion_timeout(&ucsi->complete, + msecs_to_jiffies(UCSI_TIMEOUT_MS))) ret = -ETIMEDOUT; out_clear_bit: |
