Commit 5fa0ab45 authored by Linus Torvalds's avatar Linus Torvalds

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

Pull USB / Thunderbolt driver fixes from Greg KH:
 "Here are some small USB and Thunderbolt driver fixes for 6.9-rc5.
  Included in here are:

   - MAINTAINER file update for invalid email address

   - usb-serial device id updates

   - typec driver fixes

   - thunderbolt / usb4 driver fixes

   - usb core shutdown fixes

   - cdc-wdm driver revert for reported problem in -rc1

   - usb gadget driver fixes

   - xhci driver fixes

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

* tag 'usb-6.9-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb: (25 commits)
  USB: serial: option: add Telit FN920C04 rmnet compositions
  usb: dwc3: ep0: Don't reset resource alloc flag
  Revert "usb: cdc-wdm: close race between read and workqueue"
  USB: serial: option: add Rolling RW101-GL and RW135-GL support
  USB: serial: option: add Lonsung U8300/U9300 product
  USB: serial: option: add support for Fibocom FM650/FG650
  USB: serial: option: support Quectel EM060K sub-models
  USB: serial: option: add Fibocom FM135-GL variants
  usb: misc: onboard_usb_hub: Disable the USB hub clock on failure
  thunderbolt: Avoid notify PM core about runtime PM resume
  thunderbolt: Fix wake configurations after device unplug
  usb: dwc2: host: Fix dereference issue in DDMA completion flow.
  usb: typec: mux: it5205: Fix ChipID value typo
  MAINTAINERS: Drop Li Yang as their email address stopped working
  usb: gadget: fsl: Initialize udc before using it
  usb: Disable USB3 LPM at shutdown
  usb: gadget: f_ncm: Fix UAF ncm object at re-bind after usb ep transport error
  usb: typec: tcpm: Correct the PDO counting in pd_set
  usb: gadget: functionfs: Wait for fences before enqueueing DMABUF
  usb: gadget: functionfs: Fix inverted DMA fence direction
  ...
parents 3b680865 7a9a3040
...@@ -8746,10 +8746,9 @@ S: Orphan ...@@ -8746,10 +8746,9 @@ S: Orphan
F: drivers/usb/gadget/udc/fsl* F: drivers/usb/gadget/udc/fsl*
FREESCALE USB PHY DRIVER FREESCALE USB PHY DRIVER
M: Ran Wang <ran.wang_1@nxp.com>
L: linux-usb@vger.kernel.org L: linux-usb@vger.kernel.org
L: linuxppc-dev@lists.ozlabs.org L: linuxppc-dev@lists.ozlabs.org
S: Maintained S: Orphan
F: drivers/usb/phy/phy-fsl-usb* F: drivers/usb/phy/phy-fsl-usb*
FREEVXFS FILESYSTEM FREEVXFS FILESYSTEM
......
...@@ -3180,22 +3180,29 @@ void tb_switch_unconfigure_link(struct tb_switch *sw) ...@@ -3180,22 +3180,29 @@ void tb_switch_unconfigure_link(struct tb_switch *sw)
{ {
struct tb_port *up, *down; struct tb_port *up, *down;
if (sw->is_unplugged)
return;
if (!tb_route(sw) || tb_switch_is_icm(sw)) if (!tb_route(sw) || tb_switch_is_icm(sw))
return; return;
/*
* Unconfigure downstream port so that wake-on-connect can be
* configured after router unplug. No need to unconfigure upstream port
* since its router is unplugged.
*/
up = tb_upstream_port(sw); up = tb_upstream_port(sw);
if (tb_switch_is_usb4(up->sw))
usb4_port_unconfigure(up);
else
tb_lc_unconfigure_port(up);
down = up->remote; down = up->remote;
if (tb_switch_is_usb4(down->sw)) if (tb_switch_is_usb4(down->sw))
usb4_port_unconfigure(down); usb4_port_unconfigure(down);
else else
tb_lc_unconfigure_port(down); tb_lc_unconfigure_port(down);
if (sw->is_unplugged)
return;
up = tb_upstream_port(sw);
if (tb_switch_is_usb4(up->sw))
usb4_port_unconfigure(up);
else
tb_lc_unconfigure_port(up);
} }
static void tb_switch_credits_init(struct tb_switch *sw) static void tb_switch_credits_init(struct tb_switch *sw)
...@@ -3441,7 +3448,26 @@ static int tb_switch_set_wake(struct tb_switch *sw, unsigned int flags) ...@@ -3441,7 +3448,26 @@ static int tb_switch_set_wake(struct tb_switch *sw, unsigned int flags)
return tb_lc_set_wake(sw, flags); return tb_lc_set_wake(sw, flags);
} }
int tb_switch_resume(struct tb_switch *sw) static void tb_switch_check_wakes(struct tb_switch *sw)
{
if (device_may_wakeup(&sw->dev)) {
if (tb_switch_is_usb4(sw))
usb4_switch_check_wakes(sw);
}
}
/**
* tb_switch_resume() - Resume a switch after sleep
* @sw: Switch to resume
* @runtime: Is this resume from runtime suspend or system sleep
*
* Resumes and re-enumerates router (and all its children), if still plugged
* after suspend. Don't enumerate device router whose UID was changed during
* suspend. If this is resume from system sleep, notifies PM core about the
* wakes occurred during suspend. Disables all wakes, except USB4 wake of
* upstream port for USB4 routers that shall be always enabled.
*/
int tb_switch_resume(struct tb_switch *sw, bool runtime)
{ {
struct tb_port *port; struct tb_port *port;
int err; int err;
...@@ -3490,6 +3516,9 @@ int tb_switch_resume(struct tb_switch *sw) ...@@ -3490,6 +3516,9 @@ int tb_switch_resume(struct tb_switch *sw)
if (err) if (err)
return err; return err;
if (!runtime)
tb_switch_check_wakes(sw);
/* Disable wakes */ /* Disable wakes */
tb_switch_set_wake(sw, 0); tb_switch_set_wake(sw, 0);
...@@ -3519,7 +3548,8 @@ int tb_switch_resume(struct tb_switch *sw) ...@@ -3519,7 +3548,8 @@ int tb_switch_resume(struct tb_switch *sw)
*/ */
if (tb_port_unlock(port)) if (tb_port_unlock(port))
tb_port_warn(port, "failed to unlock port\n"); tb_port_warn(port, "failed to unlock port\n");
if (port->remote && tb_switch_resume(port->remote->sw)) { if (port->remote &&
tb_switch_resume(port->remote->sw, runtime)) {
tb_port_warn(port, tb_port_warn(port,
"lost during suspend, disconnecting\n"); "lost during suspend, disconnecting\n");
tb_sw_set_unplugged(port->remote->sw); tb_sw_set_unplugged(port->remote->sw);
......
...@@ -1801,6 +1801,12 @@ static struct tb_port *tb_find_dp_out(struct tb *tb, struct tb_port *in) ...@@ -1801,6 +1801,12 @@ static struct tb_port *tb_find_dp_out(struct tb *tb, struct tb_port *in)
continue; continue;
} }
/* Needs to be on different routers */
if (in->sw == port->sw) {
tb_port_dbg(port, "skipping DP OUT on same router\n");
continue;
}
tb_port_dbg(port, "DP OUT available\n"); tb_port_dbg(port, "DP OUT available\n");
/* /*
...@@ -2936,7 +2942,7 @@ static int tb_resume_noirq(struct tb *tb) ...@@ -2936,7 +2942,7 @@ static int tb_resume_noirq(struct tb *tb)
if (!tb_switch_is_usb4(tb->root_switch)) if (!tb_switch_is_usb4(tb->root_switch))
tb_switch_reset(tb->root_switch); tb_switch_reset(tb->root_switch);
tb_switch_resume(tb->root_switch); tb_switch_resume(tb->root_switch, false);
tb_free_invalid_tunnels(tb); tb_free_invalid_tunnels(tb);
tb_free_unplugged_children(tb->root_switch); tb_free_unplugged_children(tb->root_switch);
tb_restore_children(tb->root_switch); tb_restore_children(tb->root_switch);
...@@ -3062,7 +3068,7 @@ static int tb_runtime_resume(struct tb *tb) ...@@ -3062,7 +3068,7 @@ static int tb_runtime_resume(struct tb *tb)
struct tb_tunnel *tunnel, *n; struct tb_tunnel *tunnel, *n;
mutex_lock(&tb->lock); mutex_lock(&tb->lock);
tb_switch_resume(tb->root_switch); tb_switch_resume(tb->root_switch, true);
tb_free_invalid_tunnels(tb); tb_free_invalid_tunnels(tb);
tb_restore_children(tb->root_switch); tb_restore_children(tb->root_switch);
list_for_each_entry_safe(tunnel, n, &tcm->tunnel_list, list) list_for_each_entry_safe(tunnel, n, &tcm->tunnel_list, list)
......
...@@ -827,7 +827,7 @@ int tb_switch_configuration_valid(struct tb_switch *sw); ...@@ -827,7 +827,7 @@ int tb_switch_configuration_valid(struct tb_switch *sw);
int tb_switch_add(struct tb_switch *sw); int tb_switch_add(struct tb_switch *sw);
void tb_switch_remove(struct tb_switch *sw); void tb_switch_remove(struct tb_switch *sw);
void tb_switch_suspend(struct tb_switch *sw, bool runtime); void tb_switch_suspend(struct tb_switch *sw, bool runtime);
int tb_switch_resume(struct tb_switch *sw); int tb_switch_resume(struct tb_switch *sw, bool runtime);
int tb_switch_reset(struct tb_switch *sw); int tb_switch_reset(struct tb_switch *sw);
int tb_switch_wait_for_bit(struct tb_switch *sw, u32 offset, u32 bit, int tb_switch_wait_for_bit(struct tb_switch *sw, u32 offset, u32 bit,
u32 value, int timeout_msec); u32 value, int timeout_msec);
...@@ -1288,6 +1288,7 @@ static inline bool tb_switch_is_usb4(const struct tb_switch *sw) ...@@ -1288,6 +1288,7 @@ static inline bool tb_switch_is_usb4(const struct tb_switch *sw)
return usb4_switch_version(sw) > 0; return usb4_switch_version(sw) > 0;
} }
void usb4_switch_check_wakes(struct tb_switch *sw);
int usb4_switch_setup(struct tb_switch *sw); int usb4_switch_setup(struct tb_switch *sw);
int usb4_switch_configuration_valid(struct tb_switch *sw); int usb4_switch_configuration_valid(struct tb_switch *sw);
int usb4_switch_read_uid(struct tb_switch *sw, u64 *uid); int usb4_switch_read_uid(struct tb_switch *sw, u64 *uid);
......
...@@ -155,7 +155,13 @@ static inline int usb4_switch_op_data(struct tb_switch *sw, u16 opcode, ...@@ -155,7 +155,13 @@ static inline int usb4_switch_op_data(struct tb_switch *sw, u16 opcode,
tx_dwords, rx_data, rx_dwords); tx_dwords, rx_data, rx_dwords);
} }
static void usb4_switch_check_wakes(struct tb_switch *sw) /**
* usb4_switch_check_wakes() - Check for wakes and notify PM core about them
* @sw: Router whose wakes to check
*
* Checks wakes occurred during suspend and notify the PM core about them.
*/
void usb4_switch_check_wakes(struct tb_switch *sw)
{ {
bool wakeup_usb4 = false; bool wakeup_usb4 = false;
struct usb4_port *usb4; struct usb4_port *usb4;
...@@ -163,9 +169,6 @@ static void usb4_switch_check_wakes(struct tb_switch *sw) ...@@ -163,9 +169,6 @@ static void usb4_switch_check_wakes(struct tb_switch *sw)
bool wakeup = false; bool wakeup = false;
u32 val; u32 val;
if (!device_may_wakeup(&sw->dev))
return;
if (tb_route(sw)) { if (tb_route(sw)) {
if (tb_sw_read(sw, &val, TB_CFG_SWITCH, ROUTER_CS_6, 1)) if (tb_sw_read(sw, &val, TB_CFG_SWITCH, ROUTER_CS_6, 1))
return; return;
...@@ -244,8 +247,6 @@ int usb4_switch_setup(struct tb_switch *sw) ...@@ -244,8 +247,6 @@ int usb4_switch_setup(struct tb_switch *sw)
u32 val = 0; u32 val = 0;
int ret; int ret;
usb4_switch_check_wakes(sw);
if (!tb_route(sw)) if (!tb_route(sw))
return 0; return 0;
......
...@@ -485,7 +485,6 @@ static ssize_t wdm_write ...@@ -485,7 +485,6 @@ static ssize_t wdm_write
static int service_outstanding_interrupt(struct wdm_device *desc) static int service_outstanding_interrupt(struct wdm_device *desc)
{ {
int rv = 0; int rv = 0;
int used;
/* submit read urb only if the device is waiting for it */ /* submit read urb only if the device is waiting for it */
if (!desc->resp_count || !--desc->resp_count) if (!desc->resp_count || !--desc->resp_count)
...@@ -500,10 +499,7 @@ static int service_outstanding_interrupt(struct wdm_device *desc) ...@@ -500,10 +499,7 @@ static int service_outstanding_interrupt(struct wdm_device *desc)
goto out; goto out;
} }
used = test_and_set_bit(WDM_RESPONDING, &desc->flags); set_bit(WDM_RESPONDING, &desc->flags);
if (used)
goto out;
spin_unlock_irq(&desc->iuspin); spin_unlock_irq(&desc->iuspin);
rv = usb_submit_urb(desc->response, GFP_KERNEL); rv = usb_submit_urb(desc->response, GFP_KERNEL);
spin_lock_irq(&desc->iuspin); spin_lock_irq(&desc->iuspin);
......
...@@ -449,8 +449,10 @@ static void usb_port_shutdown(struct device *dev) ...@@ -449,8 +449,10 @@ static void usb_port_shutdown(struct device *dev)
{ {
struct usb_port *port_dev = to_usb_port(dev); struct usb_port *port_dev = to_usb_port(dev);
if (port_dev->child) if (port_dev->child) {
usb_disable_usb2_hardware_lpm(port_dev->child); usb_disable_usb2_hardware_lpm(port_dev->child);
usb_unlocked_disable_lpm(port_dev->child);
}
} }
static const struct dev_pm_ops usb_port_pm_ops = { static const struct dev_pm_ops usb_port_pm_ops = {
......
...@@ -867,13 +867,15 @@ static int dwc2_cmpl_host_isoc_dma_desc(struct dwc2_hsotg *hsotg, ...@@ -867,13 +867,15 @@ static int dwc2_cmpl_host_isoc_dma_desc(struct dwc2_hsotg *hsotg,
struct dwc2_dma_desc *dma_desc; struct dwc2_dma_desc *dma_desc;
struct dwc2_hcd_iso_packet_desc *frame_desc; struct dwc2_hcd_iso_packet_desc *frame_desc;
u16 frame_desc_idx; u16 frame_desc_idx;
struct urb *usb_urb = qtd->urb->priv; struct urb *usb_urb;
u16 remain = 0; u16 remain = 0;
int rc = 0; int rc = 0;
if (!qtd->urb) if (!qtd->urb)
return -EINVAL; return -EINVAL;
usb_urb = qtd->urb->priv;
dma_sync_single_for_cpu(hsotg->dev, qh->desc_list_dma + (idx * dma_sync_single_for_cpu(hsotg->dev, qh->desc_list_dma + (idx *
sizeof(struct dwc2_dma_desc)), sizeof(struct dwc2_dma_desc)),
sizeof(struct dwc2_dma_desc), sizeof(struct dwc2_dma_desc),
......
...@@ -226,7 +226,8 @@ void dwc3_ep0_stall_and_restart(struct dwc3 *dwc) ...@@ -226,7 +226,8 @@ void dwc3_ep0_stall_and_restart(struct dwc3 *dwc)
/* reinitialize physical ep1 */ /* reinitialize physical ep1 */
dep = dwc->eps[1]; dep = dwc->eps[1];
dep->flags = DWC3_EP_ENABLED; dep->flags &= DWC3_EP_RESOURCE_ALLOCATED;
dep->flags |= DWC3_EP_ENABLED;
/* stall is always issued on EP0 */ /* stall is always issued on EP0 */
dep = dwc->eps[0]; dep = dwc->eps[0];
......
...@@ -46,6 +46,8 @@ ...@@ -46,6 +46,8 @@
#define FUNCTIONFS_MAGIC 0xa647361 /* Chosen by a honest dice roll ;) */ #define FUNCTIONFS_MAGIC 0xa647361 /* Chosen by a honest dice roll ;) */
#define DMABUF_ENQUEUE_TIMEOUT_MS 5000
MODULE_IMPORT_NS(DMA_BUF); MODULE_IMPORT_NS(DMA_BUF);
/* Reference counter handling */ /* Reference counter handling */
...@@ -1578,10 +1580,13 @@ static int ffs_dmabuf_transfer(struct file *file, ...@@ -1578,10 +1580,13 @@ static int ffs_dmabuf_transfer(struct file *file,
struct ffs_dmabuf_priv *priv; struct ffs_dmabuf_priv *priv;
struct ffs_dma_fence *fence; struct ffs_dma_fence *fence;
struct usb_request *usb_req; struct usb_request *usb_req;
enum dma_resv_usage resv_dir;
struct dma_buf *dmabuf; struct dma_buf *dmabuf;
unsigned long timeout;
struct ffs_ep *ep; struct ffs_ep *ep;
bool cookie; bool cookie;
u32 seqno; u32 seqno;
long retl;
int ret; int ret;
if (req->flags & ~USB_FFS_DMABUF_TRANSFER_MASK) if (req->flags & ~USB_FFS_DMABUF_TRANSFER_MASK)
...@@ -1615,17 +1620,14 @@ static int ffs_dmabuf_transfer(struct file *file, ...@@ -1615,17 +1620,14 @@ static int ffs_dmabuf_transfer(struct file *file,
goto err_attachment_put; goto err_attachment_put;
/* Make sure we don't have writers */ /* Make sure we don't have writers */
if (!dma_resv_test_signaled(dmabuf->resv, DMA_RESV_USAGE_WRITE)) { timeout = nonblock ? 0 : msecs_to_jiffies(DMABUF_ENQUEUE_TIMEOUT_MS);
pr_vdebug("FFS WRITE fence is not signaled\n"); retl = dma_resv_wait_timeout(dmabuf->resv,
ret = -EBUSY; dma_resv_usage_rw(epfile->in),
goto err_resv_unlock; true, timeout);
} if (retl == 0)
retl = -EBUSY;
/* If we're writing to the DMABUF, make sure we don't have readers */ if (retl < 0) {
if (epfile->in && ret = (int)retl;
!dma_resv_test_signaled(dmabuf->resv, DMA_RESV_USAGE_READ)) {
pr_vdebug("FFS READ fence is not signaled\n");
ret = -EBUSY;
goto err_resv_unlock; goto err_resv_unlock;
} }
...@@ -1665,8 +1667,9 @@ static int ffs_dmabuf_transfer(struct file *file, ...@@ -1665,8 +1667,9 @@ static int ffs_dmabuf_transfer(struct file *file,
dma_fence_init(&fence->base, &ffs_dmabuf_fence_ops, dma_fence_init(&fence->base, &ffs_dmabuf_fence_ops,
&priv->lock, priv->context, seqno); &priv->lock, priv->context, seqno);
dma_resv_add_fence(dmabuf->resv, &fence->base, resv_dir = epfile->in ? DMA_RESV_USAGE_WRITE : DMA_RESV_USAGE_READ;
dma_resv_usage_rw(epfile->in));
dma_resv_add_fence(dmabuf->resv, &fence->base, resv_dir);
dma_resv_unlock(dmabuf->resv); dma_resv_unlock(dmabuf->resv);
/* Now that the dma_fence is in place, queue the transfer. */ /* Now that the dma_fence is in place, queue the transfer. */
......
...@@ -878,7 +878,7 @@ static int ncm_set_alt(struct usb_function *f, unsigned intf, unsigned alt) ...@@ -878,7 +878,7 @@ static int ncm_set_alt(struct usb_function *f, unsigned intf, unsigned alt)
if (alt > 1) if (alt > 1)
goto fail; goto fail;
if (ncm->port.in_ep->enabled) { if (ncm->netdev) {
DBG(cdev, "reset ncm\n"); DBG(cdev, "reset ncm\n");
ncm->netdev = NULL; ncm->netdev = NULL;
gether_disconnect(&ncm->port); gether_disconnect(&ncm->port);
...@@ -1367,7 +1367,7 @@ static void ncm_disable(struct usb_function *f) ...@@ -1367,7 +1367,7 @@ static void ncm_disable(struct usb_function *f)
DBG(cdev, "ncm deactivated\n"); DBG(cdev, "ncm deactivated\n");
if (ncm->port.in_ep->enabled) { if (ncm->netdev) {
ncm->netdev = NULL; ncm->netdev = NULL;
gether_disconnect(&ncm->port); gether_disconnect(&ncm->port);
} }
......
...@@ -868,7 +868,7 @@ fsl_ep_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags) ...@@ -868,7 +868,7 @@ fsl_ep_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags)
{ {
struct fsl_ep *ep = container_of(_ep, struct fsl_ep, ep); struct fsl_ep *ep = container_of(_ep, struct fsl_ep, ep);
struct fsl_req *req = container_of(_req, struct fsl_req, req); struct fsl_req *req = container_of(_req, struct fsl_req, req);
struct fsl_udc *udc; struct fsl_udc *udc = ep->udc;
unsigned long flags; unsigned long flags;
int ret; int ret;
...@@ -878,7 +878,7 @@ fsl_ep_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags) ...@@ -878,7 +878,7 @@ fsl_ep_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags)
dev_vdbg(&udc->gadget.dev, "%s, bad params\n", __func__); dev_vdbg(&udc->gadget.dev, "%s, bad params\n", __func__);
return -EINVAL; return -EINVAL;
} }
if (unlikely(!_ep || !ep->ep.desc)) { if (unlikely(!ep->ep.desc)) {
dev_vdbg(&udc->gadget.dev, "%s, bad ep\n", __func__); dev_vdbg(&udc->gadget.dev, "%s, bad ep\n", __func__);
return -EINVAL; return -EINVAL;
} }
...@@ -887,7 +887,6 @@ fsl_ep_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags) ...@@ -887,7 +887,6 @@ fsl_ep_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags)
return -EMSGSIZE; return -EMSGSIZE;
} }
udc = ep->udc;
if (!udc->driver || udc->gadget.speed == USB_SPEED_UNKNOWN) if (!udc->driver || udc->gadget.speed == USB_SPEED_UNKNOWN)
return -ESHUTDOWN; return -ESHUTDOWN;
......
...@@ -3133,7 +3133,7 @@ static int xhci_handle_events(struct xhci_hcd *xhci, struct xhci_interrupter *ir ...@@ -3133,7 +3133,7 @@ static int xhci_handle_events(struct xhci_hcd *xhci, struct xhci_interrupter *ir
irqreturn_t xhci_irq(struct usb_hcd *hcd) irqreturn_t xhci_irq(struct usb_hcd *hcd)
{ {
struct xhci_hcd *xhci = hcd_to_xhci(hcd); struct xhci_hcd *xhci = hcd_to_xhci(hcd);
irqreturn_t ret = IRQ_NONE; irqreturn_t ret = IRQ_HANDLED;
u32 status; u32 status;
spin_lock(&xhci->lock); spin_lock(&xhci->lock);
...@@ -3141,12 +3141,13 @@ irqreturn_t xhci_irq(struct usb_hcd *hcd) ...@@ -3141,12 +3141,13 @@ irqreturn_t xhci_irq(struct usb_hcd *hcd)
status = readl(&xhci->op_regs->status); status = readl(&xhci->op_regs->status);
if (status == ~(u32)0) { if (status == ~(u32)0) {
xhci_hc_died(xhci); xhci_hc_died(xhci);
ret = IRQ_HANDLED;
goto out; goto out;
} }
if (!(status & STS_EINT)) if (!(status & STS_EINT)) {
ret = IRQ_NONE;
goto out; goto out;
}
if (status & STS_HCE) { if (status & STS_HCE) {
xhci_warn(xhci, "WARNING: Host Controller Error\n"); xhci_warn(xhci, "WARNING: Host Controller Error\n");
...@@ -3156,7 +3157,6 @@ irqreturn_t xhci_irq(struct usb_hcd *hcd) ...@@ -3156,7 +3157,6 @@ irqreturn_t xhci_irq(struct usb_hcd *hcd)
if (status & STS_FATAL) { if (status & STS_FATAL) {
xhci_warn(xhci, "WARNING: Host System Error\n"); xhci_warn(xhci, "WARNING: Host System Error\n");
xhci_halt(xhci); xhci_halt(xhci);
ret = IRQ_HANDLED;
goto out; goto out;
} }
...@@ -3167,7 +3167,6 @@ irqreturn_t xhci_irq(struct usb_hcd *hcd) ...@@ -3167,7 +3167,6 @@ irqreturn_t xhci_irq(struct usb_hcd *hcd)
*/ */
status |= STS_EINT; status |= STS_EINT;
writel(status, &xhci->op_regs->status); writel(status, &xhci->op_regs->status);
ret = IRQ_HANDLED;
/* This is the handler of the primary interrupter */ /* This is the handler of the primary interrupter */
xhci_handle_events(xhci, xhci->interrupters[0]); xhci_handle_events(xhci, xhci->interrupters[0]);
......
...@@ -172,8 +172,7 @@ DECLARE_EVENT_CLASS(xhci_log_free_virt_dev, ...@@ -172,8 +172,7 @@ DECLARE_EVENT_CLASS(xhci_log_free_virt_dev,
__field(void *, vdev) __field(void *, vdev)
__field(unsigned long long, out_ctx) __field(unsigned long long, out_ctx)
__field(unsigned long long, in_ctx) __field(unsigned long long, in_ctx)
__field(int, hcd_portnum) __field(int, slot_id)
__field(int, hw_portnum)
__field(u16, current_mel) __field(u16, current_mel)
), ),
...@@ -181,13 +180,12 @@ DECLARE_EVENT_CLASS(xhci_log_free_virt_dev, ...@@ -181,13 +180,12 @@ DECLARE_EVENT_CLASS(xhci_log_free_virt_dev,
__entry->vdev = vdev; __entry->vdev = vdev;
__entry->in_ctx = (unsigned long long) vdev->in_ctx->dma; __entry->in_ctx = (unsigned long long) vdev->in_ctx->dma;
__entry->out_ctx = (unsigned long long) vdev->out_ctx->dma; __entry->out_ctx = (unsigned long long) vdev->out_ctx->dma;
__entry->hcd_portnum = (int) vdev->rhub_port->hcd_portnum; __entry->slot_id = (int) vdev->slot_id;
__entry->hw_portnum = (int) vdev->rhub_port->hw_portnum;
__entry->current_mel = (u16) vdev->current_mel; __entry->current_mel = (u16) vdev->current_mel;
), ),
TP_printk("vdev %p ctx %llx | %llx hcd_portnum %d hw_portnum %d current_mel %d", TP_printk("vdev %p slot %d ctx %llx | %llx current_mel %d",
__entry->vdev, __entry->in_ctx, __entry->out_ctx, __entry->vdev, __entry->slot_id, __entry->in_ctx,
__entry->hcd_portnum, __entry->hw_portnum, __entry->current_mel __entry->out_ctx, __entry->current_mel
) )
); );
......
...@@ -78,7 +78,7 @@ static int onboard_hub_power_on(struct onboard_hub *hub) ...@@ -78,7 +78,7 @@ static int onboard_hub_power_on(struct onboard_hub *hub)
err = regulator_bulk_enable(hub->pdata->num_supplies, hub->supplies); err = regulator_bulk_enable(hub->pdata->num_supplies, hub->supplies);
if (err) { if (err) {
dev_err(hub->dev, "failed to enable supplies: %pe\n", ERR_PTR(err)); dev_err(hub->dev, "failed to enable supplies: %pe\n", ERR_PTR(err));
return err; goto disable_clk;
} }
fsleep(hub->pdata->reset_us); fsleep(hub->pdata->reset_us);
...@@ -87,6 +87,10 @@ static int onboard_hub_power_on(struct onboard_hub *hub) ...@@ -87,6 +87,10 @@ static int onboard_hub_power_on(struct onboard_hub *hub)
hub->is_powered_on = true; hub->is_powered_on = true;
return 0; return 0;
disable_clk:
clk_disable_unprepare(hub->clk);
return err;
} }
static int onboard_hub_power_off(struct onboard_hub *hub) static int onboard_hub_power_off(struct onboard_hub *hub)
......
...@@ -255,6 +255,10 @@ static void option_instat_callback(struct urb *urb); ...@@ -255,6 +255,10 @@ static void option_instat_callback(struct urb *urb);
#define QUECTEL_PRODUCT_EM061K_LMS 0x0124 #define QUECTEL_PRODUCT_EM061K_LMS 0x0124
#define QUECTEL_PRODUCT_EC25 0x0125 #define QUECTEL_PRODUCT_EC25 0x0125
#define QUECTEL_PRODUCT_EM060K_128 0x0128 #define QUECTEL_PRODUCT_EM060K_128 0x0128
#define QUECTEL_PRODUCT_EM060K_129 0x0129
#define QUECTEL_PRODUCT_EM060K_12a 0x012a
#define QUECTEL_PRODUCT_EM060K_12b 0x012b
#define QUECTEL_PRODUCT_EM060K_12c 0x012c
#define QUECTEL_PRODUCT_EG91 0x0191 #define QUECTEL_PRODUCT_EG91 0x0191
#define QUECTEL_PRODUCT_EG95 0x0195 #define QUECTEL_PRODUCT_EG95 0x0195
#define QUECTEL_PRODUCT_BG96 0x0296 #define QUECTEL_PRODUCT_BG96 0x0296
...@@ -1218,6 +1222,18 @@ static const struct usb_device_id option_ids[] = { ...@@ -1218,6 +1222,18 @@ static const struct usb_device_id option_ids[] = {
{ USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM060K_128, 0xff, 0xff, 0x30) }, { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM060K_128, 0xff, 0xff, 0x30) },
{ USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM060K_128, 0xff, 0x00, 0x40) }, { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM060K_128, 0xff, 0x00, 0x40) },
{ USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM060K_128, 0xff, 0xff, 0x40) }, { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM060K_128, 0xff, 0xff, 0x40) },
{ USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM060K_129, 0xff, 0xff, 0x30) },
{ USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM060K_129, 0xff, 0x00, 0x40) },
{ USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM060K_129, 0xff, 0xff, 0x40) },
{ USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM060K_12a, 0xff, 0xff, 0x30) },
{ USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM060K_12a, 0xff, 0x00, 0x40) },
{ USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM060K_12a, 0xff, 0xff, 0x40) },
{ USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM060K_12b, 0xff, 0xff, 0x30) },
{ USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM060K_12b, 0xff, 0x00, 0x40) },
{ USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM060K_12b, 0xff, 0xff, 0x40) },
{ USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM060K_12c, 0xff, 0xff, 0x30) },
{ USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM060K_12c, 0xff, 0x00, 0x40) },
{ USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM060K_12c, 0xff, 0xff, 0x40) },
{ USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM061K_LCN, 0xff, 0xff, 0x30) }, { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM061K_LCN, 0xff, 0xff, 0x30) },
{ USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM061K_LCN, 0xff, 0x00, 0x40) }, { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM061K_LCN, 0xff, 0x00, 0x40) },
{ USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM061K_LCN, 0xff, 0xff, 0x40) }, { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM061K_LCN, 0xff, 0xff, 0x40) },
...@@ -1360,6 +1376,12 @@ static const struct usb_device_id option_ids[] = { ...@@ -1360,6 +1376,12 @@ static const struct usb_device_id option_ids[] = {
.driver_info = NCTRL(2) | RSVD(3) }, .driver_info = NCTRL(2) | RSVD(3) },
{ USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1083, 0xff), /* Telit FE990 (ECM) */ { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1083, 0xff), /* Telit FE990 (ECM) */
.driver_info = NCTRL(0) | RSVD(1) }, .driver_info = NCTRL(0) | RSVD(1) },
{ USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x10a0, 0xff), /* Telit FN20C04 (rmnet) */
.driver_info = RSVD(0) | NCTRL(3) },
{ USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x10a4, 0xff), /* Telit FN20C04 (rmnet) */
.driver_info = RSVD(0) | NCTRL(3) },
{ USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x10a9, 0xff), /* Telit FN20C04 (rmnet) */
.driver_info = RSVD(0) | NCTRL(2) | RSVD(3) | RSVD(4) },
{ USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_ME910), { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_ME910),
.driver_info = NCTRL(0) | RSVD(1) | RSVD(3) }, .driver_info = NCTRL(0) | RSVD(1) | RSVD(3) },
{ USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_ME910_DUAL_MODEM), { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_ME910_DUAL_MODEM),
...@@ -2052,6 +2074,10 @@ static const struct usb_device_id option_ids[] = { ...@@ -2052,6 +2074,10 @@ static const struct usb_device_id option_ids[] = {
.driver_info = RSVD(3) }, .driver_info = RSVD(3) },
{ USB_DEVICE_INTERFACE_CLASS(LONGCHEER_VENDOR_ID, 0x9803, 0xff), { USB_DEVICE_INTERFACE_CLASS(LONGCHEER_VENDOR_ID, 0x9803, 0xff),
.driver_info = RSVD(4) }, .driver_info = RSVD(4) },
{ USB_DEVICE(LONGCHEER_VENDOR_ID, 0x9b05), /* Longsung U8300 */
.driver_info = RSVD(4) | RSVD(5) },
{ USB_DEVICE(LONGCHEER_VENDOR_ID, 0x9b3c), /* Longsung U9300 */
.driver_info = RSVD(0) | RSVD(4) },
{ USB_DEVICE(LONGCHEER_VENDOR_ID, ZOOM_PRODUCT_4597) }, { USB_DEVICE(LONGCHEER_VENDOR_ID, ZOOM_PRODUCT_4597) },
{ USB_DEVICE(LONGCHEER_VENDOR_ID, IBALL_3_5G_CONNECT) }, { USB_DEVICE(LONGCHEER_VENDOR_ID, IBALL_3_5G_CONNECT) },
{ USB_DEVICE(HAIER_VENDOR_ID, HAIER_PRODUCT_CE100) }, { USB_DEVICE(HAIER_VENDOR_ID, HAIER_PRODUCT_CE100) },
...@@ -2272,15 +2298,29 @@ static const struct usb_device_id option_ids[] = { ...@@ -2272,15 +2298,29 @@ 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, 0x0111, 0xff) }, /* Fibocom FM160 (MBIM mode) */ { USB_DEVICE_INTERFACE_CLASS(0x2cb7, 0x0111, 0xff) }, /* Fibocom FM160 (MBIM mode) */
{ USB_DEVICE_INTERFACE_CLASS(0x2cb7, 0x0115, 0xff), /* Fibocom FM135 (laptop MBIM) */
.driver_info = RSVD(5) },
{ 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, 0x01a2, 0xff) }, /* Fibocom FM101-GL (laptop MBIM) */
{ USB_DEVICE_INTERFACE_CLASS(0x2cb7, 0x01a3, 0xff) }, /* Fibocom FM101-GL (laptop MBIM) */ { USB_DEVICE_INTERFACE_CLASS(0x2cb7, 0x01a3, 0xff) }, /* Fibocom FM101-GL (laptop MBIM) */
{ USB_DEVICE_INTERFACE_CLASS(0x2cb7, 0x01a4, 0xff), /* Fibocom FM101-GL (laptop MBIM) */ { USB_DEVICE_INTERFACE_CLASS(0x2cb7, 0x01a4, 0xff), /* Fibocom FM101-GL (laptop MBIM) */
.driver_info = RSVD(4) }, .driver_info = RSVD(4) },
{ USB_DEVICE_INTERFACE_CLASS(0x2cb7, 0x0a04, 0xff) }, /* Fibocom FM650-CN (ECM mode) */
{ USB_DEVICE_INTERFACE_CLASS(0x2cb7, 0x0a05, 0xff) }, /* Fibocom FM650-CN (NCM mode) */
{ USB_DEVICE_INTERFACE_CLASS(0x2cb7, 0x0a06, 0xff) }, /* Fibocom FM650-CN (RNDIS mode) */
{ USB_DEVICE_INTERFACE_CLASS(0x2cb7, 0x0a07, 0xff) }, /* Fibocom FM650-CN (MBIM mode) */
{ 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 */
{ USB_DEVICE_INTERFACE_CLASS(0x305a, 0x1406, 0xff) }, /* GosunCn GM500 ECM/NCM */ { USB_DEVICE_INTERFACE_CLASS(0x305a, 0x1406, 0xff) }, /* GosunCn GM500 ECM/NCM */
{ USB_DEVICE(0x33f8, 0x0104), /* Rolling RW101-GL (laptop RMNET) */
.driver_info = RSVD(4) | RSVD(5) },
{ USB_DEVICE_INTERFACE_CLASS(0x33f8, 0x01a2, 0xff) }, /* Rolling RW101-GL (laptop MBIM) */
{ USB_DEVICE_INTERFACE_CLASS(0x33f8, 0x01a3, 0xff) }, /* Rolling RW101-GL (laptop MBIM) */
{ USB_DEVICE_INTERFACE_CLASS(0x33f8, 0x01a4, 0xff), /* Rolling RW101-GL (laptop MBIM) */
.driver_info = RSVD(4) },
{ USB_DEVICE_INTERFACE_CLASS(0x33f8, 0x0115, 0xff), /* Rolling RW135-GL (laptop MBIM) */
.driver_info = RSVD(5) },
{ USB_DEVICE_AND_INTERFACE_INFO(OPPO_VENDOR_ID, OPPO_PRODUCT_R11, 0xff, 0xff, 0x30) }, { USB_DEVICE_AND_INTERFACE_INFO(OPPO_VENDOR_ID, OPPO_PRODUCT_R11, 0xff, 0xff, 0x30) },
{ USB_DEVICE_AND_INTERFACE_INFO(SIERRA_VENDOR_ID, SIERRA_PRODUCT_EM9191, 0xff, 0xff, 0x30) }, { USB_DEVICE_AND_INTERFACE_INFO(SIERRA_VENDOR_ID, SIERRA_PRODUCT_EM9191, 0xff, 0xff, 0x30) },
{ USB_DEVICE_AND_INTERFACE_INFO(SIERRA_VENDOR_ID, SIERRA_PRODUCT_EM9191, 0xff, 0xff, 0x40) }, { USB_DEVICE_AND_INTERFACE_INFO(SIERRA_VENDOR_ID, SIERRA_PRODUCT_EM9191, 0xff, 0xff, 0x40) },
......
...@@ -22,7 +22,7 @@ ...@@ -22,7 +22,7 @@
#include <linux/usb/typec_mux.h> #include <linux/usb/typec_mux.h>
#define IT5205_REG_CHIP_ID(x) (0x4 + (x)) #define IT5205_REG_CHIP_ID(x) (0x4 + (x))
#define IT5205FN_CHIP_ID 0x35323035 /* "5205" */ #define IT5205FN_CHIP_ID 0x35303235 /* "5025" -> "5205" */
/* MUX power down register */ /* MUX power down register */
#define IT5205_REG_MUXPDR 0x10 #define IT5205_REG_MUXPDR 0x10
......
...@@ -6855,14 +6855,14 @@ static int tcpm_pd_set(struct typec_port *p, struct usb_power_delivery *pd) ...@@ -6855,14 +6855,14 @@ static int tcpm_pd_set(struct typec_port *p, struct usb_power_delivery *pd)
if (data->sink_desc.pdo[0]) { if (data->sink_desc.pdo[0]) {
for (i = 0; i < PDO_MAX_OBJECTS && data->sink_desc.pdo[i]; i++) for (i = 0; i < PDO_MAX_OBJECTS && data->sink_desc.pdo[i]; i++)
port->snk_pdo[i] = data->sink_desc.pdo[i]; port->snk_pdo[i] = data->sink_desc.pdo[i];
port->nr_snk_pdo = i + 1; port->nr_snk_pdo = i;
port->operating_snk_mw = data->operating_snk_mw; port->operating_snk_mw = data->operating_snk_mw;
} }
if (data->source_desc.pdo[0]) { if (data->source_desc.pdo[0]) {
for (i = 0; i < PDO_MAX_OBJECTS && data->source_desc.pdo[i]; i++) for (i = 0; i < PDO_MAX_OBJECTS && data->source_desc.pdo[i]; i++)
port->src_pdo[i] = data->source_desc.pdo[i]; port->src_pdo[i] = data->source_desc.pdo[i];
port->nr_src_pdo = i + 1; port->nr_src_pdo = i;
} }
switch (port->state) { switch (port->state) {
......
...@@ -1736,11 +1736,13 @@ static int ucsi_init(struct ucsi *ucsi) ...@@ -1736,11 +1736,13 @@ static int ucsi_init(struct ucsi *ucsi)
ucsi->connector = connector; ucsi->connector = connector;
ucsi->ntfy = ntfy; ucsi->ntfy = ntfy;
mutex_lock(&ucsi->ppm_lock);
ret = ucsi->ops->read(ucsi, UCSI_CCI, &cci, sizeof(cci)); ret = ucsi->ops->read(ucsi, UCSI_CCI, &cci, sizeof(cci));
mutex_unlock(&ucsi->ppm_lock);
if (ret) if (ret)
return ret; return ret;
if (UCSI_CCI_CONNECTOR(READ_ONCE(cci))) if (UCSI_CCI_CONNECTOR(cci))
ucsi_connector_change(ucsi, cci); ucsi_connector_change(ucsi, UCSI_CCI_CONNECTOR(cci));
return 0; return 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment