Merge 4.18-rc3 into usb-next
We want the USB and other fixes in here as well to make merges and testing easier. Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
@@ -124,8 +124,11 @@ static int host_start(struct ci_hdrc *ci)
|
||||
|
||||
hcd->power_budget = ci->platdata->power_budget;
|
||||
hcd->tpl_support = ci->platdata->tpl_support;
|
||||
if (ci->phy || ci->usb_phy)
|
||||
if (ci->phy || ci->usb_phy) {
|
||||
hcd->skip_phy_initialization = 1;
|
||||
if (ci->usb_phy)
|
||||
hcd->usb_phy = ci->usb_phy;
|
||||
}
|
||||
|
||||
ehci = hcd_to_ehci(hcd);
|
||||
ehci->caps = ci->hw_bank.cap;
|
||||
|
||||
@@ -1758,6 +1758,9 @@ static const struct usb_device_id acm_ids[] = {
|
||||
{ USB_DEVICE(0x11ca, 0x0201), /* VeriFone Mx870 Gadget Serial */
|
||||
.driver_info = SINGLE_RX_URB,
|
||||
},
|
||||
{ USB_DEVICE(0x1965, 0x0018), /* Uniden UBC125XLT */
|
||||
.driver_info = NO_UNION_NORMAL, /* has no union descriptor */
|
||||
},
|
||||
{ USB_DEVICE(0x22b8, 0x7000), /* Motorola Q Phone */
|
||||
.driver_info = NO_UNION_NORMAL, /* has no union descriptor */
|
||||
},
|
||||
|
||||
@@ -1004,6 +1004,7 @@ struct dwc2_hregs_backup {
|
||||
* @frame_list_sz: Frame list size
|
||||
* @desc_gen_cache: Kmem cache for generic descriptors
|
||||
* @desc_hsisoc_cache: Kmem cache for hs isochronous descriptors
|
||||
* @unaligned_cache: Kmem cache for DMA mode to handle non-aligned buf
|
||||
*
|
||||
* These are for peripheral mode:
|
||||
*
|
||||
@@ -1177,6 +1178,8 @@ struct dwc2_hsotg {
|
||||
u32 frame_list_sz;
|
||||
struct kmem_cache *desc_gen_cache;
|
||||
struct kmem_cache *desc_hsisoc_cache;
|
||||
struct kmem_cache *unaligned_cache;
|
||||
#define DWC2_KMEM_UNALIGNED_BUF_SIZE 1024
|
||||
|
||||
#endif /* CONFIG_USB_DWC2_HOST || CONFIG_USB_DWC2_DUAL_ROLE */
|
||||
|
||||
|
||||
@@ -812,6 +812,7 @@ static int dwc2_gadget_fill_isoc_desc(struct dwc2_hsotg_ep *hs_ep,
|
||||
u32 index;
|
||||
u32 maxsize = 0;
|
||||
u32 mask = 0;
|
||||
u8 pid = 0;
|
||||
|
||||
maxsize = dwc2_gadget_get_desc_params(hs_ep, &mask);
|
||||
|
||||
@@ -840,7 +841,11 @@ static int dwc2_gadget_fill_isoc_desc(struct dwc2_hsotg_ep *hs_ep,
|
||||
((len << DEV_DMA_NBYTES_SHIFT) & mask));
|
||||
|
||||
if (hs_ep->dir_in) {
|
||||
desc->status |= ((hs_ep->mc << DEV_DMA_ISOC_PID_SHIFT) &
|
||||
if (len)
|
||||
pid = DIV_ROUND_UP(len, hs_ep->ep.maxpacket);
|
||||
else
|
||||
pid = 1;
|
||||
desc->status |= ((pid << DEV_DMA_ISOC_PID_SHIFT) &
|
||||
DEV_DMA_ISOC_PID_MASK) |
|
||||
((len % hs_ep->ep.maxpacket) ?
|
||||
DEV_DMA_SHORT : 0) |
|
||||
@@ -884,6 +889,7 @@ static void dwc2_gadget_start_isoc_ddma(struct dwc2_hsotg_ep *hs_ep)
|
||||
struct dwc2_dma_desc *desc;
|
||||
|
||||
if (list_empty(&hs_ep->queue)) {
|
||||
hs_ep->target_frame = TARGET_FRAME_INITIAL;
|
||||
dev_dbg(hsotg->dev, "%s: No requests in queue\n", __func__);
|
||||
return;
|
||||
}
|
||||
@@ -2755,8 +2761,6 @@ static void dwc2_gadget_handle_out_token_ep_disabled(struct dwc2_hsotg_ep *ep)
|
||||
*/
|
||||
tmp = dwc2_hsotg_read_frameno(hsotg);
|
||||
|
||||
dwc2_hsotg_complete_request(hsotg, ep, get_ep_head(ep), 0);
|
||||
|
||||
if (using_desc_dma(hsotg)) {
|
||||
if (ep->target_frame == TARGET_FRAME_INITIAL) {
|
||||
/* Start first ISO Out */
|
||||
@@ -2817,9 +2821,6 @@ static void dwc2_gadget_handle_nak(struct dwc2_hsotg_ep *hs_ep)
|
||||
|
||||
tmp = dwc2_hsotg_read_frameno(hsotg);
|
||||
if (using_desc_dma(hsotg)) {
|
||||
dwc2_hsotg_complete_request(hsotg, hs_ep,
|
||||
get_ep_head(hs_ep), 0);
|
||||
|
||||
hs_ep->target_frame = tmp;
|
||||
dwc2_gadget_incr_frame_num(hs_ep);
|
||||
dwc2_gadget_start_isoc_ddma(hs_ep);
|
||||
@@ -4739,9 +4740,11 @@ int dwc2_gadget_init(struct dwc2_hsotg *hsotg)
|
||||
}
|
||||
|
||||
ret = usb_add_gadget_udc(dev, &hsotg->gadget);
|
||||
if (ret)
|
||||
if (ret) {
|
||||
dwc2_hsotg_ep_free_request(&hsotg->eps_out[0]->ep,
|
||||
hsotg->ctrl_req);
|
||||
return ret;
|
||||
|
||||
}
|
||||
dwc2_hsotg_dump(hsotg);
|
||||
|
||||
return 0;
|
||||
@@ -4755,6 +4758,7 @@ int dwc2_gadget_init(struct dwc2_hsotg *hsotg)
|
||||
int dwc2_hsotg_remove(struct dwc2_hsotg *hsotg)
|
||||
{
|
||||
usb_del_gadget_udc(&hsotg->gadget);
|
||||
dwc2_hsotg_ep_free_request(&hsotg->eps_out[0]->ep, hsotg->ctrl_req);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
+87
-6
@@ -1567,11 +1567,20 @@ static void dwc2_hc_start_transfer(struct dwc2_hsotg *hsotg,
|
||||
}
|
||||
|
||||
if (hsotg->params.host_dma) {
|
||||
dwc2_writel((u32)chan->xfer_dma,
|
||||
hsotg->regs + HCDMA(chan->hc_num));
|
||||
dma_addr_t dma_addr;
|
||||
|
||||
if (chan->align_buf) {
|
||||
if (dbg_hc(chan))
|
||||
dev_vdbg(hsotg->dev, "align_buf\n");
|
||||
dma_addr = chan->align_buf;
|
||||
} else {
|
||||
dma_addr = chan->xfer_dma;
|
||||
}
|
||||
dwc2_writel((u32)dma_addr, hsotg->regs + HCDMA(chan->hc_num));
|
||||
|
||||
if (dbg_hc(chan))
|
||||
dev_vdbg(hsotg->dev, "Wrote %08lx to HCDMA(%d)\n",
|
||||
(unsigned long)chan->xfer_dma, chan->hc_num);
|
||||
(unsigned long)dma_addr, chan->hc_num);
|
||||
}
|
||||
|
||||
/* Start the split */
|
||||
@@ -2625,6 +2634,35 @@ static void dwc2_hc_init_xfer(struct dwc2_hsotg *hsotg,
|
||||
}
|
||||
}
|
||||
|
||||
static int dwc2_alloc_split_dma_aligned_buf(struct dwc2_hsotg *hsotg,
|
||||
struct dwc2_qh *qh,
|
||||
struct dwc2_host_chan *chan)
|
||||
{
|
||||
if (!hsotg->unaligned_cache ||
|
||||
chan->max_packet > DWC2_KMEM_UNALIGNED_BUF_SIZE)
|
||||
return -ENOMEM;
|
||||
|
||||
if (!qh->dw_align_buf) {
|
||||
qh->dw_align_buf = kmem_cache_alloc(hsotg->unaligned_cache,
|
||||
GFP_ATOMIC | GFP_DMA);
|
||||
if (!qh->dw_align_buf)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
qh->dw_align_buf_dma = dma_map_single(hsotg->dev, qh->dw_align_buf,
|
||||
DWC2_KMEM_UNALIGNED_BUF_SIZE,
|
||||
DMA_FROM_DEVICE);
|
||||
|
||||
if (dma_mapping_error(hsotg->dev, qh->dw_align_buf_dma)) {
|
||||
dev_err(hsotg->dev, "can't map align_buf\n");
|
||||
chan->align_buf = 0;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
chan->align_buf = qh->dw_align_buf_dma;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define DWC2_USB_DMA_ALIGN 4
|
||||
|
||||
struct dma_aligned_buffer {
|
||||
@@ -2802,6 +2840,32 @@ static int dwc2_assign_and_init_hc(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh)
|
||||
/* Set the transfer attributes */
|
||||
dwc2_hc_init_xfer(hsotg, chan, qtd);
|
||||
|
||||
/* For non-dword aligned buffers */
|
||||
if (hsotg->params.host_dma && qh->do_split &&
|
||||
chan->ep_is_in && (chan->xfer_dma & 0x3)) {
|
||||
dev_vdbg(hsotg->dev, "Non-aligned buffer\n");
|
||||
if (dwc2_alloc_split_dma_aligned_buf(hsotg, qh, chan)) {
|
||||
dev_err(hsotg->dev,
|
||||
"Failed to allocate memory to handle non-aligned buffer\n");
|
||||
/* Add channel back to free list */
|
||||
chan->align_buf = 0;
|
||||
chan->multi_count = 0;
|
||||
list_add_tail(&chan->hc_list_entry,
|
||||
&hsotg->free_hc_list);
|
||||
qtd->in_process = 0;
|
||||
qh->channel = NULL;
|
||||
return -ENOMEM;
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* We assume that DMA is always aligned in non-split
|
||||
* case or split out case. Warn if not.
|
||||
*/
|
||||
WARN_ON_ONCE(hsotg->params.host_dma &&
|
||||
(chan->xfer_dma & 0x3));
|
||||
chan->align_buf = 0;
|
||||
}
|
||||
|
||||
if (chan->ep_type == USB_ENDPOINT_XFER_INT ||
|
||||
chan->ep_type == USB_ENDPOINT_XFER_ISOC)
|
||||
/*
|
||||
@@ -5246,6 +5310,19 @@ int dwc2_hcd_init(struct dwc2_hsotg *hsotg)
|
||||
}
|
||||
}
|
||||
|
||||
if (hsotg->params.host_dma) {
|
||||
/*
|
||||
* Create kmem caches to handle non-aligned buffer
|
||||
* in Buffer DMA mode.
|
||||
*/
|
||||
hsotg->unaligned_cache = kmem_cache_create("dwc2-unaligned-dma",
|
||||
DWC2_KMEM_UNALIGNED_BUF_SIZE, 4,
|
||||
SLAB_CACHE_DMA, NULL);
|
||||
if (!hsotg->unaligned_cache)
|
||||
dev_err(hsotg->dev,
|
||||
"unable to create dwc2 unaligned cache\n");
|
||||
}
|
||||
|
||||
hsotg->otg_port = 1;
|
||||
hsotg->frame_list = NULL;
|
||||
hsotg->frame_list_dma = 0;
|
||||
@@ -5280,8 +5357,9 @@ int dwc2_hcd_init(struct dwc2_hsotg *hsotg)
|
||||
return 0;
|
||||
|
||||
error4:
|
||||
kmem_cache_destroy(hsotg->desc_gen_cache);
|
||||
kmem_cache_destroy(hsotg->unaligned_cache);
|
||||
kmem_cache_destroy(hsotg->desc_hsisoc_cache);
|
||||
kmem_cache_destroy(hsotg->desc_gen_cache);
|
||||
error3:
|
||||
dwc2_hcd_release(hsotg);
|
||||
error2:
|
||||
@@ -5322,8 +5400,9 @@ void dwc2_hcd_remove(struct dwc2_hsotg *hsotg)
|
||||
usb_remove_hcd(hcd);
|
||||
hsotg->priv = NULL;
|
||||
|
||||
kmem_cache_destroy(hsotg->desc_gen_cache);
|
||||
kmem_cache_destroy(hsotg->unaligned_cache);
|
||||
kmem_cache_destroy(hsotg->desc_hsisoc_cache);
|
||||
kmem_cache_destroy(hsotg->desc_gen_cache);
|
||||
|
||||
dwc2_hcd_release(hsotg);
|
||||
usb_put_hcd(hcd);
|
||||
@@ -5435,7 +5514,7 @@ int dwc2_host_enter_hibernation(struct dwc2_hsotg *hsotg)
|
||||
dwc2_writel(hprt0, hsotg->regs + HPRT0);
|
||||
|
||||
/* Wait for the HPRT0.PrtSusp register field to be set */
|
||||
if (dwc2_hsotg_wait_bit_set(hsotg, HPRT0, HPRT0_SUSP, 300))
|
||||
if (dwc2_hsotg_wait_bit_set(hsotg, HPRT0, HPRT0_SUSP, 3000))
|
||||
dev_warn(hsotg->dev, "Suspend wasn't generated\n");
|
||||
|
||||
/*
|
||||
@@ -5616,6 +5695,8 @@ int dwc2_host_exit_hibernation(struct dwc2_hsotg *hsotg, int rem_wakeup,
|
||||
return ret;
|
||||
}
|
||||
|
||||
dwc2_hcd_rem_wakeup(hsotg);
|
||||
|
||||
hsotg->hibernated = 0;
|
||||
hsotg->bus_suspended = 0;
|
||||
hsotg->lx_state = DWC2_L0;
|
||||
|
||||
@@ -76,6 +76,8 @@ struct dwc2_qh;
|
||||
* (micro)frame
|
||||
* @xfer_buf: Pointer to current transfer buffer position
|
||||
* @xfer_dma: DMA address of xfer_buf
|
||||
* @align_buf: In Buffer DMA mode this will be used if xfer_buf is not
|
||||
* DWORD aligned
|
||||
* @xfer_len: Total number of bytes to transfer
|
||||
* @xfer_count: Number of bytes transferred so far
|
||||
* @start_pkt_count: Packet count at start of transfer
|
||||
@@ -133,6 +135,7 @@ struct dwc2_host_chan {
|
||||
|
||||
u8 *xfer_buf;
|
||||
dma_addr_t xfer_dma;
|
||||
dma_addr_t align_buf;
|
||||
u32 xfer_len;
|
||||
u32 xfer_count;
|
||||
u16 start_pkt_count;
|
||||
@@ -302,6 +305,9 @@ struct dwc2_hs_transfer_time {
|
||||
* speed. Note that this is in "schedule slice" which
|
||||
* is tightly packed.
|
||||
* @ntd: Actual number of transfer descriptors in a list
|
||||
* @dw_align_buf: Used instead of original buffer if its physical address
|
||||
* is not dword-aligned
|
||||
* @dw_align_buf_dma: DMA address for dw_align_buf
|
||||
* @qtd_list: List of QTDs for this QH
|
||||
* @channel: Host channel currently processing transfers for this QH
|
||||
* @qh_list_entry: Entry for QH in either the periodic or non-periodic
|
||||
@@ -350,6 +356,8 @@ struct dwc2_qh {
|
||||
struct dwc2_hs_transfer_time hs_transfers[DWC2_HS_SCHEDULE_UFRAMES];
|
||||
u32 ls_start_schedule_slice;
|
||||
u16 ntd;
|
||||
u8 *dw_align_buf;
|
||||
dma_addr_t dw_align_buf_dma;
|
||||
struct list_head qtd_list;
|
||||
struct dwc2_host_chan *channel;
|
||||
struct list_head qh_list_entry;
|
||||
|
||||
@@ -942,14 +942,21 @@ static int dwc2_xfercomp_isoc_split_in(struct dwc2_hsotg *hsotg,
|
||||
frame_desc = &qtd->urb->iso_descs[qtd->isoc_frame_index];
|
||||
len = dwc2_get_actual_xfer_length(hsotg, chan, chnum, qtd,
|
||||
DWC2_HC_XFER_COMPLETE, NULL);
|
||||
if (!len) {
|
||||
if (!len && !qtd->isoc_split_offset) {
|
||||
qtd->complete_split = 0;
|
||||
qtd->isoc_split_offset = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
frame_desc->actual_length += len;
|
||||
|
||||
if (chan->align_buf) {
|
||||
dev_vdbg(hsotg->dev, "non-aligned buffer\n");
|
||||
dma_unmap_single(hsotg->dev, chan->qh->dw_align_buf_dma,
|
||||
DWC2_KMEM_UNALIGNED_BUF_SIZE, DMA_FROM_DEVICE);
|
||||
memcpy(qtd->urb->buf + (chan->xfer_dma - qtd->urb->dma),
|
||||
chan->qh->dw_align_buf, len);
|
||||
}
|
||||
|
||||
qtd->isoc_split_offset += len;
|
||||
|
||||
hctsiz = dwc2_readl(hsotg->regs + HCTSIZ(chnum));
|
||||
|
||||
@@ -383,7 +383,7 @@ static unsigned long *dwc2_get_ls_map(struct dwc2_hsotg *hsotg,
|
||||
/* Get the map and adjust if this is a multi_tt hub */
|
||||
map = qh->dwc_tt->periodic_bitmaps;
|
||||
if (qh->dwc_tt->usb_tt->multi)
|
||||
map += DWC2_ELEMENTS_PER_LS_BITMAP * qh->ttport;
|
||||
map += DWC2_ELEMENTS_PER_LS_BITMAP * (qh->ttport - 1);
|
||||
|
||||
return map;
|
||||
}
|
||||
@@ -1696,6 +1696,9 @@ void dwc2_hcd_qh_free(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh)
|
||||
|
||||
if (qh->desc_list)
|
||||
dwc2_hcd_qh_free_ddma(hsotg, qh);
|
||||
else if (hsotg->unaligned_cache && qh->dw_align_buf)
|
||||
kmem_cache_free(hsotg->unaligned_cache, qh->dw_align_buf);
|
||||
|
||||
kfree(qh);
|
||||
}
|
||||
|
||||
|
||||
+13
-10
@@ -1272,7 +1272,6 @@ static int dwc3_probe(struct platform_device *pdev)
|
||||
if (!dwc->clks)
|
||||
return -ENOMEM;
|
||||
|
||||
dwc->num_clks = ARRAY_SIZE(dwc3_core_clks);
|
||||
dwc->dev = dev;
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
@@ -1307,15 +1306,19 @@ static int dwc3_probe(struct platform_device *pdev)
|
||||
if (IS_ERR(dwc->reset))
|
||||
return PTR_ERR(dwc->reset);
|
||||
|
||||
ret = clk_bulk_get(dev, dwc->num_clks, dwc->clks);
|
||||
if (ret == -EPROBE_DEFER)
|
||||
return ret;
|
||||
/*
|
||||
* Clocks are optional, but new DT platforms should support all clocks
|
||||
* as required by the DT-binding.
|
||||
*/
|
||||
if (ret)
|
||||
dwc->num_clks = 0;
|
||||
if (dev->of_node) {
|
||||
dwc->num_clks = ARRAY_SIZE(dwc3_core_clks);
|
||||
|
||||
ret = clk_bulk_get(dev, dwc->num_clks, dwc->clks);
|
||||
if (ret == -EPROBE_DEFER)
|
||||
return ret;
|
||||
/*
|
||||
* Clocks are optional, but new DT platforms should support all
|
||||
* clocks as required by the DT-binding.
|
||||
*/
|
||||
if (ret)
|
||||
dwc->num_clks = 0;
|
||||
}
|
||||
|
||||
ret = reset_control_deassert(dwc->reset);
|
||||
if (ret)
|
||||
|
||||
@@ -165,8 +165,9 @@ static int dwc3_of_simple_remove(struct platform_device *pdev)
|
||||
|
||||
reset_control_put(simple->resets);
|
||||
|
||||
pm_runtime_put_sync(dev);
|
||||
pm_runtime_disable(dev);
|
||||
pm_runtime_put_noidle(dev);
|
||||
pm_runtime_set_suspended(dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
#define PCI_DEVICE_ID_INTEL_GLK 0x31aa
|
||||
#define PCI_DEVICE_ID_INTEL_CNPLP 0x9dee
|
||||
#define PCI_DEVICE_ID_INTEL_CNPH 0xa36e
|
||||
#define PCI_DEVICE_ID_INTEL_ICLLP 0x34ee
|
||||
|
||||
#define PCI_INTEL_BXT_DSM_GUID "732b85d5-b7a7-4a1b-9ba0-4bbd00ffd511"
|
||||
#define PCI_INTEL_BXT_FUNC_PMU_PWR 4
|
||||
@@ -289,6 +290,7 @@ static const struct pci_device_id dwc3_pci_id_table[] = {
|
||||
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_GLK), },
|
||||
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_CNPLP), },
|
||||
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_CNPH), },
|
||||
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICLLP), },
|
||||
{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_NL_USB), },
|
||||
{ } /* Terminating Entry */
|
||||
};
|
||||
|
||||
@@ -490,6 +490,7 @@ static int dwc3_qcom_probe(struct platform_device *pdev)
|
||||
qcom->dwc3 = of_find_device_by_node(dwc3_np);
|
||||
if (!qcom->dwc3) {
|
||||
dev_err(&pdev->dev, "failed to get dwc3 platform device\n");
|
||||
ret = -ENODEV;
|
||||
goto depopulate;
|
||||
}
|
||||
|
||||
@@ -547,8 +548,7 @@ static int dwc3_qcom_remove(struct platform_device *pdev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
static int dwc3_qcom_pm_suspend(struct device *dev)
|
||||
static int __maybe_unused dwc3_qcom_pm_suspend(struct device *dev)
|
||||
{
|
||||
struct dwc3_qcom *qcom = dev_get_drvdata(dev);
|
||||
int ret = 0;
|
||||
@@ -560,7 +560,7 @@ static int dwc3_qcom_pm_suspend(struct device *dev)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int dwc3_qcom_pm_resume(struct device *dev)
|
||||
static int __maybe_unused dwc3_qcom_pm_resume(struct device *dev)
|
||||
{
|
||||
struct dwc3_qcom *qcom = dev_get_drvdata(dev);
|
||||
int ret;
|
||||
@@ -571,23 +571,20 @@ static int dwc3_qcom_pm_resume(struct device *dev)
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
static int dwc3_qcom_runtime_suspend(struct device *dev)
|
||||
static int __maybe_unused dwc3_qcom_runtime_suspend(struct device *dev)
|
||||
{
|
||||
struct dwc3_qcom *qcom = dev_get_drvdata(dev);
|
||||
|
||||
return dwc3_qcom_suspend(qcom);
|
||||
}
|
||||
|
||||
static int dwc3_qcom_runtime_resume(struct device *dev)
|
||||
static int __maybe_unused dwc3_qcom_runtime_resume(struct device *dev)
|
||||
{
|
||||
struct dwc3_qcom *qcom = dev_get_drvdata(dev);
|
||||
|
||||
return dwc3_qcom_resume(qcom);
|
||||
}
|
||||
#endif
|
||||
|
||||
static const struct dev_pm_ops dwc3_qcom_dev_pm_ops = {
|
||||
SET_SYSTEM_SLEEP_PM_OPS(dwc3_qcom_pm_suspend, dwc3_qcom_pm_resume)
|
||||
|
||||
@@ -1719,6 +1719,8 @@ composite_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl)
|
||||
*/
|
||||
if (w_value && !f->get_alt)
|
||||
break;
|
||||
|
||||
spin_lock(&cdev->lock);
|
||||
value = f->set_alt(f, w_index, w_value);
|
||||
if (value == USB_GADGET_DELAYED_STATUS) {
|
||||
DBG(cdev,
|
||||
@@ -1728,6 +1730,7 @@ composite_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl)
|
||||
DBG(cdev, "delayed_status count %d\n",
|
||||
cdev->delayed_status);
|
||||
}
|
||||
spin_unlock(&cdev->lock);
|
||||
break;
|
||||
case USB_REQ_GET_INTERFACE:
|
||||
if (ctrl->bRequestType != (USB_DIR_IN|USB_RECIP_INTERFACE))
|
||||
|
||||
@@ -215,6 +215,7 @@ struct ffs_io_data {
|
||||
|
||||
struct mm_struct *mm;
|
||||
struct work_struct work;
|
||||
struct work_struct cancellation_work;
|
||||
|
||||
struct usb_ep *ep;
|
||||
struct usb_request *req;
|
||||
@@ -1072,22 +1073,31 @@ ffs_epfile_open(struct inode *inode, struct file *file)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void ffs_aio_cancel_worker(struct work_struct *work)
|
||||
{
|
||||
struct ffs_io_data *io_data = container_of(work, struct ffs_io_data,
|
||||
cancellation_work);
|
||||
|
||||
ENTER();
|
||||
|
||||
usb_ep_dequeue(io_data->ep, io_data->req);
|
||||
}
|
||||
|
||||
static int ffs_aio_cancel(struct kiocb *kiocb)
|
||||
{
|
||||
struct ffs_io_data *io_data = kiocb->private;
|
||||
struct ffs_epfile *epfile = kiocb->ki_filp->private_data;
|
||||
struct ffs_data *ffs = io_data->ffs;
|
||||
int value;
|
||||
|
||||
ENTER();
|
||||
|
||||
spin_lock_irq(&epfile->ffs->eps_lock);
|
||||
|
||||
if (likely(io_data && io_data->ep && io_data->req))
|
||||
value = usb_ep_dequeue(io_data->ep, io_data->req);
|
||||
else
|
||||
if (likely(io_data && io_data->ep && io_data->req)) {
|
||||
INIT_WORK(&io_data->cancellation_work, ffs_aio_cancel_worker);
|
||||
queue_work(ffs->io_completion_wq, &io_data->cancellation_work);
|
||||
value = -EINPROGRESS;
|
||||
} else {
|
||||
value = -EINVAL;
|
||||
|
||||
spin_unlock_irq(&epfile->ffs->eps_lock);
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
@@ -886,12 +886,12 @@ void xhci_free_virt_device(struct xhci_hcd *xhci, int slot_id)
|
||||
|
||||
dev = xhci->devs[slot_id];
|
||||
|
||||
trace_xhci_free_virt_device(dev);
|
||||
|
||||
xhci->dcbaa->dev_context_ptrs[slot_id] = 0;
|
||||
if (!dev)
|
||||
return;
|
||||
|
||||
trace_xhci_free_virt_device(dev);
|
||||
|
||||
if (dev->tt_info)
|
||||
old_active_eps = dev->tt_info->active_eps;
|
||||
|
||||
|
||||
@@ -481,7 +481,7 @@ static void tegra_xusb_mbox_handle(struct tegra_xusb *tegra,
|
||||
unsigned long mask;
|
||||
unsigned int port;
|
||||
bool idle, enable;
|
||||
int err;
|
||||
int err = 0;
|
||||
|
||||
memset(&rsp, 0, sizeof(rsp));
|
||||
|
||||
@@ -1223,10 +1223,10 @@ disable_rpm:
|
||||
pm_runtime_disable(&pdev->dev);
|
||||
usb_put_hcd(tegra->hcd);
|
||||
disable_xusbc:
|
||||
if (!&pdev->dev.pm_domain)
|
||||
if (!pdev->dev.pm_domain)
|
||||
tegra_powergate_power_off(TEGRA_POWERGATE_XUSBC);
|
||||
disable_xusba:
|
||||
if (!&pdev->dev.pm_domain)
|
||||
if (!pdev->dev.pm_domain)
|
||||
tegra_powergate_power_off(TEGRA_POWERGATE_XUSBA);
|
||||
put_padctl:
|
||||
tegra_xusb_padctl_put(tegra->padctl);
|
||||
|
||||
@@ -171,6 +171,37 @@ DEFINE_EVENT(xhci_log_trb, xhci_dbc_gadget_ep_queue,
|
||||
TP_ARGS(ring, trb)
|
||||
);
|
||||
|
||||
DECLARE_EVENT_CLASS(xhci_log_free_virt_dev,
|
||||
TP_PROTO(struct xhci_virt_device *vdev),
|
||||
TP_ARGS(vdev),
|
||||
TP_STRUCT__entry(
|
||||
__field(void *, vdev)
|
||||
__field(unsigned long long, out_ctx)
|
||||
__field(unsigned long long, in_ctx)
|
||||
__field(u8, fake_port)
|
||||
__field(u8, real_port)
|
||||
__field(u16, current_mel)
|
||||
|
||||
),
|
||||
TP_fast_assign(
|
||||
__entry->vdev = vdev;
|
||||
__entry->in_ctx = (unsigned long long) vdev->in_ctx->dma;
|
||||
__entry->out_ctx = (unsigned long long) vdev->out_ctx->dma;
|
||||
__entry->fake_port = (u8) vdev->fake_port;
|
||||
__entry->real_port = (u8) vdev->real_port;
|
||||
__entry->current_mel = (u16) vdev->current_mel;
|
||||
),
|
||||
TP_printk("vdev %p ctx %llx | %llx fake_port %d real_port %d current_mel %d",
|
||||
__entry->vdev, __entry->in_ctx, __entry->out_ctx,
|
||||
__entry->fake_port, __entry->real_port, __entry->current_mel
|
||||
)
|
||||
);
|
||||
|
||||
DEFINE_EVENT(xhci_log_free_virt_dev, xhci_free_virt_device,
|
||||
TP_PROTO(struct xhci_virt_device *vdev),
|
||||
TP_ARGS(vdev)
|
||||
);
|
||||
|
||||
DECLARE_EVENT_CLASS(xhci_log_virt_dev,
|
||||
TP_PROTO(struct xhci_virt_device *vdev),
|
||||
TP_ARGS(vdev),
|
||||
@@ -208,11 +239,6 @@ DEFINE_EVENT(xhci_log_virt_dev, xhci_alloc_virt_device,
|
||||
TP_ARGS(vdev)
|
||||
);
|
||||
|
||||
DEFINE_EVENT(xhci_log_virt_dev, xhci_free_virt_device,
|
||||
TP_PROTO(struct xhci_virt_device *vdev),
|
||||
TP_ARGS(vdev)
|
||||
);
|
||||
|
||||
DEFINE_EVENT(xhci_log_virt_dev, xhci_setup_device,
|
||||
TP_PROTO(struct xhci_virt_device *vdev),
|
||||
TP_ARGS(vdev)
|
||||
|
||||
+43
-4
@@ -908,6 +908,41 @@ static void xhci_disable_port_wake_on_bits(struct xhci_hcd *xhci)
|
||||
spin_unlock_irqrestore(&xhci->lock, flags);
|
||||
}
|
||||
|
||||
static bool xhci_pending_portevent(struct xhci_hcd *xhci)
|
||||
{
|
||||
struct xhci_port **ports;
|
||||
int port_index;
|
||||
u32 status;
|
||||
u32 portsc;
|
||||
|
||||
status = readl(&xhci->op_regs->status);
|
||||
if (status & STS_EINT)
|
||||
return true;
|
||||
/*
|
||||
* Checking STS_EINT is not enough as there is a lag between a change
|
||||
* bit being set and the Port Status Change Event that it generated
|
||||
* being written to the Event Ring. See note in xhci 1.1 section 4.19.2.
|
||||
*/
|
||||
|
||||
port_index = xhci->usb2_rhub.num_ports;
|
||||
ports = xhci->usb2_rhub.ports;
|
||||
while (port_index--) {
|
||||
portsc = readl(ports[port_index]->addr);
|
||||
if (portsc & PORT_CHANGE_MASK ||
|
||||
(portsc & PORT_PLS_MASK) == XDEV_RESUME)
|
||||
return true;
|
||||
}
|
||||
port_index = xhci->usb3_rhub.num_ports;
|
||||
ports = xhci->usb3_rhub.ports;
|
||||
while (port_index--) {
|
||||
portsc = readl(ports[port_index]->addr);
|
||||
if (portsc & PORT_CHANGE_MASK ||
|
||||
(portsc & PORT_PLS_MASK) == XDEV_RESUME)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* Stop HC (not bus-specific)
|
||||
*
|
||||
@@ -1009,7 +1044,7 @@ EXPORT_SYMBOL_GPL(xhci_suspend);
|
||||
*/
|
||||
int xhci_resume(struct xhci_hcd *xhci, bool hibernated)
|
||||
{
|
||||
u32 command, temp = 0, status;
|
||||
u32 command, temp = 0;
|
||||
struct usb_hcd *hcd = xhci_to_hcd(xhci);
|
||||
struct usb_hcd *secondary_hcd;
|
||||
int retval = 0;
|
||||
@@ -1043,8 +1078,13 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated)
|
||||
command = readl(&xhci->op_regs->command);
|
||||
command |= CMD_CRS;
|
||||
writel(command, &xhci->op_regs->command);
|
||||
/*
|
||||
* Some controllers take up to 55+ ms to complete the controller
|
||||
* restore so setting the timeout to 100ms. Xhci specification
|
||||
* doesn't mention any timeout value.
|
||||
*/
|
||||
if (xhci_handshake(&xhci->op_regs->status,
|
||||
STS_RESTORE, 0, 10 * 1000)) {
|
||||
STS_RESTORE, 0, 100 * 1000)) {
|
||||
xhci_warn(xhci, "WARN: xHC restore state timeout\n");
|
||||
spin_unlock_irq(&xhci->lock);
|
||||
return -ETIMEDOUT;
|
||||
@@ -1134,8 +1174,7 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated)
|
||||
done:
|
||||
if (retval == 0) {
|
||||
/* Resume root hubs only when have pending events. */
|
||||
status = readl(&xhci->op_regs->status);
|
||||
if (status & STS_EINT) {
|
||||
if (xhci_pending_portevent(xhci)) {
|
||||
usb_hcd_resume_root_hub(xhci->shared_hcd);
|
||||
usb_hcd_resume_root_hub(hcd);
|
||||
}
|
||||
|
||||
@@ -382,6 +382,10 @@ struct xhci_op_regs {
|
||||
#define PORT_PLC (1 << 22)
|
||||
/* port configure error change - port failed to configure its link partner */
|
||||
#define PORT_CEC (1 << 23)
|
||||
#define PORT_CHANGE_MASK (PORT_CSC | PORT_PEC | PORT_WRC | PORT_OCC | \
|
||||
PORT_RC | PORT_PLC | PORT_CEC)
|
||||
|
||||
|
||||
/* Cold Attach Status - xHC can set this bit to report device attached during
|
||||
* Sx state. Warm port reset should be perfomed to clear this bit and move port
|
||||
* to connected state.
|
||||
|
||||
@@ -95,6 +95,9 @@ static const struct usb_device_id id_table[] = {
|
||||
{ USB_DEVICE(0x10C4, 0x8156) }, /* B&G H3000 link cable */
|
||||
{ USB_DEVICE(0x10C4, 0x815E) }, /* Helicomm IP-Link 1220-DVM */
|
||||
{ USB_DEVICE(0x10C4, 0x815F) }, /* Timewave HamLinkUSB */
|
||||
{ USB_DEVICE(0x10C4, 0x817C) }, /* CESINEL MEDCAL N Power Quality Monitor */
|
||||
{ USB_DEVICE(0x10C4, 0x817D) }, /* CESINEL MEDCAL NT Power Quality Monitor */
|
||||
{ USB_DEVICE(0x10C4, 0x817E) }, /* CESINEL MEDCAL S Power Quality Monitor */
|
||||
{ USB_DEVICE(0x10C4, 0x818B) }, /* AVIT Research USB to TTL */
|
||||
{ USB_DEVICE(0x10C4, 0x819F) }, /* MJS USB Toslink Switcher */
|
||||
{ USB_DEVICE(0x10C4, 0x81A6) }, /* ThinkOptics WavIt */
|
||||
@@ -112,6 +115,9 @@ static const struct usb_device_id id_table[] = {
|
||||
{ USB_DEVICE(0x10C4, 0x826B) }, /* Cygnal Integrated Products, Inc., Fasttrax GPS demonstration module */
|
||||
{ USB_DEVICE(0x10C4, 0x8281) }, /* Nanotec Plug & Drive */
|
||||
{ USB_DEVICE(0x10C4, 0x8293) }, /* Telegesis ETRX2USB */
|
||||
{ USB_DEVICE(0x10C4, 0x82EF) }, /* CESINEL FALCO 6105 AC Power Supply */
|
||||
{ USB_DEVICE(0x10C4, 0x82F1) }, /* CESINEL MEDCAL EFD Earth Fault Detector */
|
||||
{ USB_DEVICE(0x10C4, 0x82F2) }, /* CESINEL MEDCAL ST Network Analyzer */
|
||||
{ USB_DEVICE(0x10C4, 0x82F4) }, /* Starizona MicroTouch */
|
||||
{ USB_DEVICE(0x10C4, 0x82F9) }, /* Procyon AVS */
|
||||
{ USB_DEVICE(0x10C4, 0x8341) }, /* Siemens MC35PU GPRS Modem */
|
||||
@@ -124,7 +130,9 @@ static const struct usb_device_id id_table[] = {
|
||||
{ USB_DEVICE(0x10C4, 0x8470) }, /* Juniper Networks BX Series System Console */
|
||||
{ USB_DEVICE(0x10C4, 0x8477) }, /* Balluff RFID */
|
||||
{ USB_DEVICE(0x10C4, 0x84B6) }, /* Starizona Hyperion */
|
||||
{ USB_DEVICE(0x10C4, 0x851E) }, /* CESINEL MEDCAL PT Network Analyzer */
|
||||
{ USB_DEVICE(0x10C4, 0x85A7) }, /* LifeScan OneTouch Verio IQ */
|
||||
{ USB_DEVICE(0x10C4, 0x85B8) }, /* CESINEL ReCon T Energy Logger */
|
||||
{ USB_DEVICE(0x10C4, 0x85EA) }, /* AC-Services IBUS-IF */
|
||||
{ USB_DEVICE(0x10C4, 0x85EB) }, /* AC-Services CIS-IBUS */
|
||||
{ USB_DEVICE(0x10C4, 0x85F8) }, /* Virtenio Preon32 */
|
||||
@@ -134,17 +142,23 @@ static const struct usb_device_id id_table[] = {
|
||||
{ USB_DEVICE(0x10C4, 0x8857) }, /* CEL EM357 ZigBee USB Stick */
|
||||
{ USB_DEVICE(0x10C4, 0x88A4) }, /* MMB Networks ZigBee USB Device */
|
||||
{ USB_DEVICE(0x10C4, 0x88A5) }, /* Planet Innovation Ingeni ZigBee USB Device */
|
||||
{ USB_DEVICE(0x10C4, 0x88FB) }, /* CESINEL MEDCAL STII Network Analyzer */
|
||||
{ USB_DEVICE(0x10C4, 0x8938) }, /* CESINEL MEDCAL S II Network Analyzer */
|
||||
{ USB_DEVICE(0x10C4, 0x8946) }, /* Ketra N1 Wireless Interface */
|
||||
{ USB_DEVICE(0x10C4, 0x8962) }, /* Brim Brothers charging dock */
|
||||
{ USB_DEVICE(0x10C4, 0x8977) }, /* CEL MeshWorks DevKit Device */
|
||||
{ USB_DEVICE(0x10C4, 0x8998) }, /* KCF Technologies PRN */
|
||||
{ USB_DEVICE(0x10C4, 0x89A4) }, /* CESINEL FTBC Flexible Thyristor Bridge Controller */
|
||||
{ USB_DEVICE(0x10C4, 0x8A2A) }, /* HubZ dual ZigBee and Z-Wave dongle */
|
||||
{ USB_DEVICE(0x10C4, 0x8A5E) }, /* CEL EM3588 ZigBee USB Stick Long Range */
|
||||
{ USB_DEVICE(0x10C4, 0x8B34) }, /* Qivicon ZigBee USB Radio Stick */
|
||||
{ USB_DEVICE(0x10C4, 0xEA60) }, /* Silicon Labs factory default */
|
||||
{ USB_DEVICE(0x10C4, 0xEA61) }, /* Silicon Labs factory default */
|
||||
{ USB_DEVICE(0x10C4, 0xEA63) }, /* Silicon Labs Windows Update (CP2101-4/CP2102N) */
|
||||
{ USB_DEVICE(0x10C4, 0xEA70) }, /* Silicon Labs factory default */
|
||||
{ USB_DEVICE(0x10C4, 0xEA71) }, /* Infinity GPS-MIC-1 Radio Monophone */
|
||||
{ USB_DEVICE(0x10C4, 0xEA7A) }, /* Silicon Labs Windows Update (CP2105) */
|
||||
{ USB_DEVICE(0x10C4, 0xEA7B) }, /* Silicon Labs Windows Update (CP2108) */
|
||||
{ USB_DEVICE(0x10C4, 0xF001) }, /* Elan Digital Systems USBscope50 */
|
||||
{ USB_DEVICE(0x10C4, 0xF002) }, /* Elan Digital Systems USBwave12 */
|
||||
{ USB_DEVICE(0x10C4, 0xF003) }, /* Elan Digital Systems USBpulse100 */
|
||||
|
||||
@@ -418,17 +418,18 @@ static void _tcpm_log(struct tcpm_port *port, const char *fmt, va_list args)
|
||||
u64 ts_nsec = local_clock();
|
||||
unsigned long rem_nsec;
|
||||
|
||||
mutex_lock(&port->logbuffer_lock);
|
||||
if (!port->logbuffer[port->logbuffer_head]) {
|
||||
port->logbuffer[port->logbuffer_head] =
|
||||
kzalloc(LOG_BUFFER_ENTRY_SIZE, GFP_KERNEL);
|
||||
if (!port->logbuffer[port->logbuffer_head])
|
||||
if (!port->logbuffer[port->logbuffer_head]) {
|
||||
mutex_unlock(&port->logbuffer_lock);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
vsnprintf(tmpbuffer, sizeof(tmpbuffer), fmt, args);
|
||||
|
||||
mutex_lock(&port->logbuffer_lock);
|
||||
|
||||
if (tcpm_log_full(port)) {
|
||||
port->logbuffer_head = max(port->logbuffer_head - 1, 0);
|
||||
strcpy(tmpbuffer, "overflow");
|
||||
@@ -3043,7 +3044,8 @@ static void run_state_machine(struct tcpm_port *port)
|
||||
tcpm_port_is_sink(port) &&
|
||||
time_is_after_jiffies(port->delayed_runtime)) {
|
||||
tcpm_set_state(port, SNK_DISCOVERY,
|
||||
port->delayed_runtime - jiffies);
|
||||
jiffies_to_msecs(port->delayed_runtime -
|
||||
jiffies));
|
||||
break;
|
||||
}
|
||||
tcpm_set_state(port, unattached_state(port), 0);
|
||||
|
||||
@@ -350,6 +350,19 @@ static void ucsi_connector_change(struct work_struct *work)
|
||||
}
|
||||
|
||||
if (con->status.change & UCSI_CONSTAT_CONNECT_CHANGE) {
|
||||
typec_set_pwr_role(con->port, con->status.pwr_dir);
|
||||
|
||||
switch (con->status.partner_type) {
|
||||
case UCSI_CONSTAT_PARTNER_TYPE_UFP:
|
||||
typec_set_data_role(con->port, TYPEC_HOST);
|
||||
break;
|
||||
case UCSI_CONSTAT_PARTNER_TYPE_DFP:
|
||||
typec_set_data_role(con->port, TYPEC_DEVICE);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (con->status.connected)
|
||||
ucsi_register_partner(con);
|
||||
else
|
||||
|
||||
@@ -79,6 +79,11 @@ static int ucsi_acpi_probe(struct platform_device *pdev)
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
/* This will make sure we can use ioremap_nocache() */
|
||||
status = acpi_release_memory(ACPI_HANDLE(&pdev->dev), res, 1);
|
||||
if (ACPI_FAILURE(status))
|
||||
return -ENOMEM;
|
||||
|
||||
/*
|
||||
* NOTE: The memory region for the data structures is used also in an
|
||||
* operation region, which means ACPI has already reserved it. Therefore
|
||||
|
||||
Reference in New Issue
Block a user