USB fixes for 4.18-rc3
Here is a number of USB gadget and other driver fixes for 4.18-rc3. There's a bunch of them here, most of them being gadget driver and xhci host controller fixes for reported issues (as normal), but there are also some new device ids, and some fixes for the typec code. There is an acpi core patch in here that was acked by the acpi maintainer as it is needed for the typec fixes in order to properly solve a problem in that driver. All of these have been in linux-next this week with no reported issues. Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> -----BEGIN PGP SIGNATURE----- iG0EABECAC0WIQT0tgzFv3jCIUoxPcsxR9QN2y37KQUCWziS+Q8cZ3JlZ0Brcm9h aC5jb20ACgkQMUfUDdst+yn8QQCfU8PnLo+uPoV+DU7Nm1486mHTP4YAoLU3Q0nE oRmnzA3TnxytluWgbC7M =H8MG -----END PGP SIGNATURE----- Merge tag 'usb-4.18-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb Pull USB fixes from Greg KH: "Here is a number of USB gadget and other driver fixes for 4.18-rc3. There's a bunch of them here, most of them being gadget driver and xhci host controller fixes for reported issues (as normal), but there are also some new device ids, and some fixes for the typec code. There is an acpi core patch in here that was acked by the acpi maintainer as it is needed for the typec fixes in order to properly solve a problem in that driver. All of these have been in linux-next this week with no reported issues" * tag 'usb-4.18-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb: (33 commits) usb: chipidea: host: fix disconnection detect issue usb: typec: tcpm: fix logbuffer index is wrong if _tcpm_log is re-entered typec: tcpm: Fix a msecs vs jiffies bug NFC: pn533: Fix wrong GFP flag usage usb: cdc_acm: Add quirk for Uniden UBC125 scanner staging/typec: fix tcpci_rt1711h build errors usb: typec: ucsi: Fix for incorrect status data issue usb: typec: ucsi: acpi: Workaround for cache mode issue acpi: Add helper for deactivating memory region usb: xhci: increase CRS timeout value usb: xhci: tegra: fix runtime PM error handling usb: xhci: remove the code build warning xhci: Fix kernel oops in trace_xhci_free_virt_device xhci: Fix perceived dead host due to runtime suspend race with event handler dwc2: gadget: Fix ISOC IN DDMA PID bitfield value calculation usb: gadget: dwc2: fix memory leak in gadget_init() usb: gadget: composite: fix delayed_status race condition when set_interface usb: dwc2: fix isoc split in transfer with no data usb: dwc2: alloc dma aligned buffer for isoc split in usb: dwc2: fix the incorrect bitmaps for the ports of multi_tt hub ...
This commit is contained in:
commit
c2aee376cf
|
@ -226,7 +226,7 @@ $ rm configs/<config name>.<number>/<function>
|
||||||
where <config name>.<number> specify the configuration and <function> is
|
where <config name>.<number> specify the configuration and <function> is
|
||||||
a symlink to a function being removed from the configuration, e.g.:
|
a symlink to a function being removed from the configuration, e.g.:
|
||||||
|
|
||||||
$ rm configfs/c.1/ncm.usb0
|
$ rm configs/c.1/ncm.usb0
|
||||||
|
|
||||||
...
|
...
|
||||||
...
|
...
|
||||||
|
|
|
@ -45,6 +45,8 @@
|
||||||
#include <linux/uaccess.h>
|
#include <linux/uaccess.h>
|
||||||
#include <linux/io-64-nonatomic-lo-hi.h>
|
#include <linux/io-64-nonatomic-lo-hi.h>
|
||||||
|
|
||||||
|
#include "acpica/accommon.h"
|
||||||
|
#include "acpica/acnamesp.h"
|
||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
|
|
||||||
#define _COMPONENT ACPI_OS_SERVICES
|
#define _COMPONENT ACPI_OS_SERVICES
|
||||||
|
@ -1490,6 +1492,76 @@ int acpi_check_region(resource_size_t start, resource_size_t n,
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(acpi_check_region);
|
EXPORT_SYMBOL(acpi_check_region);
|
||||||
|
|
||||||
|
static acpi_status acpi_deactivate_mem_region(acpi_handle handle, u32 level,
|
||||||
|
void *_res, void **return_value)
|
||||||
|
{
|
||||||
|
struct acpi_mem_space_context **mem_ctx;
|
||||||
|
union acpi_operand_object *handler_obj;
|
||||||
|
union acpi_operand_object *region_obj2;
|
||||||
|
union acpi_operand_object *region_obj;
|
||||||
|
struct resource *res = _res;
|
||||||
|
acpi_status status;
|
||||||
|
|
||||||
|
region_obj = acpi_ns_get_attached_object(handle);
|
||||||
|
if (!region_obj)
|
||||||
|
return AE_OK;
|
||||||
|
|
||||||
|
handler_obj = region_obj->region.handler;
|
||||||
|
if (!handler_obj)
|
||||||
|
return AE_OK;
|
||||||
|
|
||||||
|
if (region_obj->region.space_id != ACPI_ADR_SPACE_SYSTEM_MEMORY)
|
||||||
|
return AE_OK;
|
||||||
|
|
||||||
|
if (!(region_obj->region.flags & AOPOBJ_SETUP_COMPLETE))
|
||||||
|
return AE_OK;
|
||||||
|
|
||||||
|
region_obj2 = acpi_ns_get_secondary_object(region_obj);
|
||||||
|
if (!region_obj2)
|
||||||
|
return AE_OK;
|
||||||
|
|
||||||
|
mem_ctx = (void *)®ion_obj2->extra.region_context;
|
||||||
|
|
||||||
|
if (!(mem_ctx[0]->address >= res->start &&
|
||||||
|
mem_ctx[0]->address < res->end))
|
||||||
|
return AE_OK;
|
||||||
|
|
||||||
|
status = handler_obj->address_space.setup(region_obj,
|
||||||
|
ACPI_REGION_DEACTIVATE,
|
||||||
|
NULL, (void **)mem_ctx);
|
||||||
|
if (ACPI_SUCCESS(status))
|
||||||
|
region_obj->region.flags &= ~(AOPOBJ_SETUP_COMPLETE);
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* acpi_release_memory - Release any mappings done to a memory region
|
||||||
|
* @handle: Handle to namespace node
|
||||||
|
* @res: Memory resource
|
||||||
|
* @level: A level that terminates the search
|
||||||
|
*
|
||||||
|
* Walks through @handle and unmaps all SystemMemory Operation Regions that
|
||||||
|
* overlap with @res and that have already been activated (mapped).
|
||||||
|
*
|
||||||
|
* This is a helper that allows drivers to place special requirements on memory
|
||||||
|
* region that may overlap with operation regions, primarily allowing them to
|
||||||
|
* safely map the region as non-cached memory.
|
||||||
|
*
|
||||||
|
* The unmapped Operation Regions will be automatically remapped next time they
|
||||||
|
* are called, so the drivers do not need to do anything else.
|
||||||
|
*/
|
||||||
|
acpi_status acpi_release_memory(acpi_handle handle, struct resource *res,
|
||||||
|
u32 level)
|
||||||
|
{
|
||||||
|
if (!(res->flags & IORESOURCE_MEM))
|
||||||
|
return AE_TYPE;
|
||||||
|
|
||||||
|
return acpi_walk_namespace(ACPI_TYPE_REGION, handle, level,
|
||||||
|
acpi_deactivate_mem_region, NULL, res, NULL);
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(acpi_release_memory);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Let drivers know whether the resource checks are effective
|
* Let drivers know whether the resource checks are effective
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -74,7 +74,7 @@ static void pn533_recv_response(struct urb *urb)
|
||||||
struct sk_buff *skb = NULL;
|
struct sk_buff *skb = NULL;
|
||||||
|
|
||||||
if (!urb->status) {
|
if (!urb->status) {
|
||||||
skb = alloc_skb(urb->actual_length, GFP_KERNEL);
|
skb = alloc_skb(urb->actual_length, GFP_ATOMIC);
|
||||||
if (!skb) {
|
if (!skb) {
|
||||||
nfc_err(&phy->udev->dev, "failed to alloc memory\n");
|
nfc_err(&phy->udev->dev, "failed to alloc memory\n");
|
||||||
} else {
|
} else {
|
||||||
|
@ -186,7 +186,7 @@ static int pn533_usb_send_frame(struct pn533 *dev,
|
||||||
|
|
||||||
if (dev->protocol_type == PN533_PROTO_REQ_RESP) {
|
if (dev->protocol_type == PN533_PROTO_REQ_RESP) {
|
||||||
/* request for response for sent packet directly */
|
/* request for response for sent packet directly */
|
||||||
rc = pn533_submit_urb_for_response(phy, GFP_ATOMIC);
|
rc = pn533_submit_urb_for_response(phy, GFP_KERNEL);
|
||||||
if (rc)
|
if (rc)
|
||||||
goto error;
|
goto error;
|
||||||
} else if (dev->protocol_type == PN533_PROTO_REQ_ACK_RESP) {
|
} else if (dev->protocol_type == PN533_PROTO_REQ_ACK_RESP) {
|
||||||
|
|
|
@ -11,6 +11,7 @@ config TYPEC_TCPCI
|
||||||
|
|
||||||
config TYPEC_RT1711H
|
config TYPEC_RT1711H
|
||||||
tristate "Richtek RT1711H Type-C chip driver"
|
tristate "Richtek RT1711H Type-C chip driver"
|
||||||
|
depends on I2C
|
||||||
select TYPEC_TCPCI
|
select TYPEC_TCPCI
|
||||||
help
|
help
|
||||||
Richtek RT1711H Type-C chip driver that works with
|
Richtek RT1711H Type-C chip driver that works with
|
||||||
|
|
|
@ -124,8 +124,11 @@ static int host_start(struct ci_hdrc *ci)
|
||||||
|
|
||||||
hcd->power_budget = ci->platdata->power_budget;
|
hcd->power_budget = ci->platdata->power_budget;
|
||||||
hcd->tpl_support = ci->platdata->tpl_support;
|
hcd->tpl_support = ci->platdata->tpl_support;
|
||||||
if (ci->phy || ci->usb_phy)
|
if (ci->phy || ci->usb_phy) {
|
||||||
hcd->skip_phy_initialization = 1;
|
hcd->skip_phy_initialization = 1;
|
||||||
|
if (ci->usb_phy)
|
||||||
|
hcd->usb_phy = ci->usb_phy;
|
||||||
|
}
|
||||||
|
|
||||||
ehci = hcd_to_ehci(hcd);
|
ehci = hcd_to_ehci(hcd);
|
||||||
ehci->caps = ci->hw_bank.cap;
|
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 */
|
{ USB_DEVICE(0x11ca, 0x0201), /* VeriFone Mx870 Gadget Serial */
|
||||||
.driver_info = SINGLE_RX_URB,
|
.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 */
|
{ USB_DEVICE(0x22b8, 0x7000), /* Motorola Q Phone */
|
||||||
.driver_info = NO_UNION_NORMAL, /* has no union descriptor */
|
.driver_info = NO_UNION_NORMAL, /* has no union descriptor */
|
||||||
},
|
},
|
||||||
|
|
|
@ -1004,6 +1004,7 @@ struct dwc2_hregs_backup {
|
||||||
* @frame_list_sz: Frame list size
|
* @frame_list_sz: Frame list size
|
||||||
* @desc_gen_cache: Kmem cache for generic descriptors
|
* @desc_gen_cache: Kmem cache for generic descriptors
|
||||||
* @desc_hsisoc_cache: Kmem cache for hs isochronous 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:
|
* These are for peripheral mode:
|
||||||
*
|
*
|
||||||
|
@ -1177,6 +1178,8 @@ struct dwc2_hsotg {
|
||||||
u32 frame_list_sz;
|
u32 frame_list_sz;
|
||||||
struct kmem_cache *desc_gen_cache;
|
struct kmem_cache *desc_gen_cache;
|
||||||
struct kmem_cache *desc_hsisoc_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 */
|
#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 index;
|
||||||
u32 maxsize = 0;
|
u32 maxsize = 0;
|
||||||
u32 mask = 0;
|
u32 mask = 0;
|
||||||
|
u8 pid = 0;
|
||||||
|
|
||||||
maxsize = dwc2_gadget_get_desc_params(hs_ep, &mask);
|
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));
|
((len << DEV_DMA_NBYTES_SHIFT) & mask));
|
||||||
|
|
||||||
if (hs_ep->dir_in) {
|
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) |
|
DEV_DMA_ISOC_PID_MASK) |
|
||||||
((len % hs_ep->ep.maxpacket) ?
|
((len % hs_ep->ep.maxpacket) ?
|
||||||
DEV_DMA_SHORT : 0) |
|
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;
|
struct dwc2_dma_desc *desc;
|
||||||
|
|
||||||
if (list_empty(&hs_ep->queue)) {
|
if (list_empty(&hs_ep->queue)) {
|
||||||
|
hs_ep->target_frame = TARGET_FRAME_INITIAL;
|
||||||
dev_dbg(hsotg->dev, "%s: No requests in queue\n", __func__);
|
dev_dbg(hsotg->dev, "%s: No requests in queue\n", __func__);
|
||||||
return;
|
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);
|
tmp = dwc2_hsotg_read_frameno(hsotg);
|
||||||
|
|
||||||
dwc2_hsotg_complete_request(hsotg, ep, get_ep_head(ep), 0);
|
|
||||||
|
|
||||||
if (using_desc_dma(hsotg)) {
|
if (using_desc_dma(hsotg)) {
|
||||||
if (ep->target_frame == TARGET_FRAME_INITIAL) {
|
if (ep->target_frame == TARGET_FRAME_INITIAL) {
|
||||||
/* Start first ISO Out */
|
/* 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);
|
tmp = dwc2_hsotg_read_frameno(hsotg);
|
||||||
if (using_desc_dma(hsotg)) {
|
if (using_desc_dma(hsotg)) {
|
||||||
dwc2_hsotg_complete_request(hsotg, hs_ep,
|
|
||||||
get_ep_head(hs_ep), 0);
|
|
||||||
|
|
||||||
hs_ep->target_frame = tmp;
|
hs_ep->target_frame = tmp;
|
||||||
dwc2_gadget_incr_frame_num(hs_ep);
|
dwc2_gadget_incr_frame_num(hs_ep);
|
||||||
dwc2_gadget_start_isoc_ddma(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);
|
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;
|
return ret;
|
||||||
|
}
|
||||||
dwc2_hsotg_dump(hsotg);
|
dwc2_hsotg_dump(hsotg);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -4755,6 +4758,7 @@ int dwc2_gadget_init(struct dwc2_hsotg *hsotg)
|
||||||
int dwc2_hsotg_remove(struct dwc2_hsotg *hsotg)
|
int dwc2_hsotg_remove(struct dwc2_hsotg *hsotg)
|
||||||
{
|
{
|
||||||
usb_del_gadget_udc(&hsotg->gadget);
|
usb_del_gadget_udc(&hsotg->gadget);
|
||||||
|
dwc2_hsotg_ep_free_request(&hsotg->eps_out[0]->ep, hsotg->ctrl_req);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1567,11 +1567,20 @@ static void dwc2_hc_start_transfer(struct dwc2_hsotg *hsotg,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hsotg->params.host_dma) {
|
if (hsotg->params.host_dma) {
|
||||||
dwc2_writel((u32)chan->xfer_dma,
|
dma_addr_t dma_addr;
|
||||||
hsotg->regs + HCDMA(chan->hc_num));
|
|
||||||
|
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))
|
if (dbg_hc(chan))
|
||||||
dev_vdbg(hsotg->dev, "Wrote %08lx to HCDMA(%d)\n",
|
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 */
|
/* 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
|
#define DWC2_USB_DMA_ALIGN 4
|
||||||
|
|
||||||
struct dma_aligned_buffer {
|
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 */
|
/* Set the transfer attributes */
|
||||||
dwc2_hc_init_xfer(hsotg, chan, qtd);
|
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 ||
|
if (chan->ep_type == USB_ENDPOINT_XFER_INT ||
|
||||||
chan->ep_type == USB_ENDPOINT_XFER_ISOC)
|
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->otg_port = 1;
|
||||||
hsotg->frame_list = NULL;
|
hsotg->frame_list = NULL;
|
||||||
hsotg->frame_list_dma = 0;
|
hsotg->frame_list_dma = 0;
|
||||||
|
@ -5280,8 +5357,9 @@ int dwc2_hcd_init(struct dwc2_hsotg *hsotg)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
error4:
|
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_hsisoc_cache);
|
||||||
|
kmem_cache_destroy(hsotg->desc_gen_cache);
|
||||||
error3:
|
error3:
|
||||||
dwc2_hcd_release(hsotg);
|
dwc2_hcd_release(hsotg);
|
||||||
error2:
|
error2:
|
||||||
|
@ -5322,8 +5400,9 @@ void dwc2_hcd_remove(struct dwc2_hsotg *hsotg)
|
||||||
usb_remove_hcd(hcd);
|
usb_remove_hcd(hcd);
|
||||||
hsotg->priv = NULL;
|
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_hsisoc_cache);
|
||||||
|
kmem_cache_destroy(hsotg->desc_gen_cache);
|
||||||
|
|
||||||
dwc2_hcd_release(hsotg);
|
dwc2_hcd_release(hsotg);
|
||||||
usb_put_hcd(hcd);
|
usb_put_hcd(hcd);
|
||||||
|
@ -5435,7 +5514,7 @@ int dwc2_host_enter_hibernation(struct dwc2_hsotg *hsotg)
|
||||||
dwc2_writel(hprt0, hsotg->regs + HPRT0);
|
dwc2_writel(hprt0, hsotg->regs + HPRT0);
|
||||||
|
|
||||||
/* Wait for the HPRT0.PrtSusp register field to be set */
|
/* 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");
|
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;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dwc2_hcd_rem_wakeup(hsotg);
|
||||||
|
|
||||||
hsotg->hibernated = 0;
|
hsotg->hibernated = 0;
|
||||||
hsotg->bus_suspended = 0;
|
hsotg->bus_suspended = 0;
|
||||||
hsotg->lx_state = DWC2_L0;
|
hsotg->lx_state = DWC2_L0;
|
||||||
|
|
|
@ -76,6 +76,8 @@ struct dwc2_qh;
|
||||||
* (micro)frame
|
* (micro)frame
|
||||||
* @xfer_buf: Pointer to current transfer buffer position
|
* @xfer_buf: Pointer to current transfer buffer position
|
||||||
* @xfer_dma: DMA address of xfer_buf
|
* @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_len: Total number of bytes to transfer
|
||||||
* @xfer_count: Number of bytes transferred so far
|
* @xfer_count: Number of bytes transferred so far
|
||||||
* @start_pkt_count: Packet count at start of transfer
|
* @start_pkt_count: Packet count at start of transfer
|
||||||
|
@ -133,6 +135,7 @@ struct dwc2_host_chan {
|
||||||
|
|
||||||
u8 *xfer_buf;
|
u8 *xfer_buf;
|
||||||
dma_addr_t xfer_dma;
|
dma_addr_t xfer_dma;
|
||||||
|
dma_addr_t align_buf;
|
||||||
u32 xfer_len;
|
u32 xfer_len;
|
||||||
u32 xfer_count;
|
u32 xfer_count;
|
||||||
u16 start_pkt_count;
|
u16 start_pkt_count;
|
||||||
|
@ -302,6 +305,9 @@ struct dwc2_hs_transfer_time {
|
||||||
* speed. Note that this is in "schedule slice" which
|
* speed. Note that this is in "schedule slice" which
|
||||||
* is tightly packed.
|
* is tightly packed.
|
||||||
* @ntd: Actual number of transfer descriptors in a list
|
* @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
|
* @qtd_list: List of QTDs for this QH
|
||||||
* @channel: Host channel currently processing transfers 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
|
* @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];
|
struct dwc2_hs_transfer_time hs_transfers[DWC2_HS_SCHEDULE_UFRAMES];
|
||||||
u32 ls_start_schedule_slice;
|
u32 ls_start_schedule_slice;
|
||||||
u16 ntd;
|
u16 ntd;
|
||||||
|
u8 *dw_align_buf;
|
||||||
|
dma_addr_t dw_align_buf_dma;
|
||||||
struct list_head qtd_list;
|
struct list_head qtd_list;
|
||||||
struct dwc2_host_chan *channel;
|
struct dwc2_host_chan *channel;
|
||||||
struct list_head qh_list_entry;
|
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];
|
frame_desc = &qtd->urb->iso_descs[qtd->isoc_frame_index];
|
||||||
len = dwc2_get_actual_xfer_length(hsotg, chan, chnum, qtd,
|
len = dwc2_get_actual_xfer_length(hsotg, chan, chnum, qtd,
|
||||||
DWC2_HC_XFER_COMPLETE, NULL);
|
DWC2_HC_XFER_COMPLETE, NULL);
|
||||||
if (!len) {
|
if (!len && !qtd->isoc_split_offset) {
|
||||||
qtd->complete_split = 0;
|
qtd->complete_split = 0;
|
||||||
qtd->isoc_split_offset = 0;
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
frame_desc->actual_length += len;
|
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;
|
qtd->isoc_split_offset += len;
|
||||||
|
|
||||||
hctsiz = dwc2_readl(hsotg->regs + HCTSIZ(chnum));
|
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 */
|
/* Get the map and adjust if this is a multi_tt hub */
|
||||||
map = qh->dwc_tt->periodic_bitmaps;
|
map = qh->dwc_tt->periodic_bitmaps;
|
||||||
if (qh->dwc_tt->usb_tt->multi)
|
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;
|
return map;
|
||||||
}
|
}
|
||||||
|
@ -1696,6 +1696,9 @@ void dwc2_hcd_qh_free(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh)
|
||||||
|
|
||||||
if (qh->desc_list)
|
if (qh->desc_list)
|
||||||
dwc2_hcd_qh_free_ddma(hsotg, qh);
|
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);
|
kfree(qh);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1272,7 +1272,6 @@ static int dwc3_probe(struct platform_device *pdev)
|
||||||
if (!dwc->clks)
|
if (!dwc->clks)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
dwc->num_clks = ARRAY_SIZE(dwc3_core_clks);
|
|
||||||
dwc->dev = dev;
|
dwc->dev = dev;
|
||||||
|
|
||||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
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))
|
if (IS_ERR(dwc->reset))
|
||||||
return PTR_ERR(dwc->reset);
|
return PTR_ERR(dwc->reset);
|
||||||
|
|
||||||
ret = clk_bulk_get(dev, dwc->num_clks, dwc->clks);
|
if (dev->of_node) {
|
||||||
if (ret == -EPROBE_DEFER)
|
dwc->num_clks = ARRAY_SIZE(dwc3_core_clks);
|
||||||
return ret;
|
|
||||||
/*
|
ret = clk_bulk_get(dev, dwc->num_clks, dwc->clks);
|
||||||
* Clocks are optional, but new DT platforms should support all clocks
|
if (ret == -EPROBE_DEFER)
|
||||||
* as required by the DT-binding.
|
return ret;
|
||||||
*/
|
/*
|
||||||
if (ret)
|
* Clocks are optional, but new DT platforms should support all
|
||||||
dwc->num_clks = 0;
|
* clocks as required by the DT-binding.
|
||||||
|
*/
|
||||||
|
if (ret)
|
||||||
|
dwc->num_clks = 0;
|
||||||
|
}
|
||||||
|
|
||||||
ret = reset_control_deassert(dwc->reset);
|
ret = reset_control_deassert(dwc->reset);
|
||||||
if (ret)
|
if (ret)
|
||||||
|
|
|
@ -165,8 +165,9 @@ static int dwc3_of_simple_remove(struct platform_device *pdev)
|
||||||
|
|
||||||
reset_control_put(simple->resets);
|
reset_control_put(simple->resets);
|
||||||
|
|
||||||
pm_runtime_put_sync(dev);
|
|
||||||
pm_runtime_disable(dev);
|
pm_runtime_disable(dev);
|
||||||
|
pm_runtime_put_noidle(dev);
|
||||||
|
pm_runtime_set_suspended(dev);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,6 +34,7 @@
|
||||||
#define PCI_DEVICE_ID_INTEL_GLK 0x31aa
|
#define PCI_DEVICE_ID_INTEL_GLK 0x31aa
|
||||||
#define PCI_DEVICE_ID_INTEL_CNPLP 0x9dee
|
#define PCI_DEVICE_ID_INTEL_CNPLP 0x9dee
|
||||||
#define PCI_DEVICE_ID_INTEL_CNPH 0xa36e
|
#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_DSM_GUID "732b85d5-b7a7-4a1b-9ba0-4bbd00ffd511"
|
||||||
#define PCI_INTEL_BXT_FUNC_PMU_PWR 4
|
#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_GLK), },
|
||||||
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_CNPLP), },
|
{ 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_CNPH), },
|
||||||
|
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICLLP), },
|
||||||
{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_NL_USB), },
|
{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_NL_USB), },
|
||||||
{ } /* Terminating Entry */
|
{ } /* Terminating Entry */
|
||||||
};
|
};
|
||||||
|
|
|
@ -490,6 +490,7 @@ static int dwc3_qcom_probe(struct platform_device *pdev)
|
||||||
qcom->dwc3 = of_find_device_by_node(dwc3_np);
|
qcom->dwc3 = of_find_device_by_node(dwc3_np);
|
||||||
if (!qcom->dwc3) {
|
if (!qcom->dwc3) {
|
||||||
dev_err(&pdev->dev, "failed to get dwc3 platform device\n");
|
dev_err(&pdev->dev, "failed to get dwc3 platform device\n");
|
||||||
|
ret = -ENODEV;
|
||||||
goto depopulate;
|
goto depopulate;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -547,8 +548,7 @@ static int dwc3_qcom_remove(struct platform_device *pdev)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_PM_SLEEP
|
static int __maybe_unused dwc3_qcom_pm_suspend(struct device *dev)
|
||||||
static int dwc3_qcom_pm_suspend(struct device *dev)
|
|
||||||
{
|
{
|
||||||
struct dwc3_qcom *qcom = dev_get_drvdata(dev);
|
struct dwc3_qcom *qcom = dev_get_drvdata(dev);
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
@ -560,7 +560,7 @@ static int dwc3_qcom_pm_suspend(struct device *dev)
|
||||||
return ret;
|
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);
|
struct dwc3_qcom *qcom = dev_get_drvdata(dev);
|
||||||
int ret;
|
int ret;
|
||||||
|
@ -571,23 +571,20 @@ static int dwc3_qcom_pm_resume(struct device *dev)
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef CONFIG_PM
|
static int __maybe_unused dwc3_qcom_runtime_suspend(struct device *dev)
|
||||||
static int dwc3_qcom_runtime_suspend(struct device *dev)
|
|
||||||
{
|
{
|
||||||
struct dwc3_qcom *qcom = dev_get_drvdata(dev);
|
struct dwc3_qcom *qcom = dev_get_drvdata(dev);
|
||||||
|
|
||||||
return dwc3_qcom_suspend(qcom);
|
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);
|
struct dwc3_qcom *qcom = dev_get_drvdata(dev);
|
||||||
|
|
||||||
return dwc3_qcom_resume(qcom);
|
return dwc3_qcom_resume(qcom);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
static const struct dev_pm_ops dwc3_qcom_dev_pm_ops = {
|
static const struct dev_pm_ops dwc3_qcom_dev_pm_ops = {
|
||||||
SET_SYSTEM_SLEEP_PM_OPS(dwc3_qcom_pm_suspend, dwc3_qcom_pm_resume)
|
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)
|
if (w_value && !f->get_alt)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
spin_lock(&cdev->lock);
|
||||||
value = f->set_alt(f, w_index, w_value);
|
value = f->set_alt(f, w_index, w_value);
|
||||||
if (value == USB_GADGET_DELAYED_STATUS) {
|
if (value == USB_GADGET_DELAYED_STATUS) {
|
||||||
DBG(cdev,
|
DBG(cdev,
|
||||||
|
@ -1728,6 +1730,7 @@ composite_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl)
|
||||||
DBG(cdev, "delayed_status count %d\n",
|
DBG(cdev, "delayed_status count %d\n",
|
||||||
cdev->delayed_status);
|
cdev->delayed_status);
|
||||||
}
|
}
|
||||||
|
spin_unlock(&cdev->lock);
|
||||||
break;
|
break;
|
||||||
case USB_REQ_GET_INTERFACE:
|
case USB_REQ_GET_INTERFACE:
|
||||||
if (ctrl->bRequestType != (USB_DIR_IN|USB_RECIP_INTERFACE))
|
if (ctrl->bRequestType != (USB_DIR_IN|USB_RECIP_INTERFACE))
|
||||||
|
|
|
@ -215,6 +215,7 @@ struct ffs_io_data {
|
||||||
|
|
||||||
struct mm_struct *mm;
|
struct mm_struct *mm;
|
||||||
struct work_struct work;
|
struct work_struct work;
|
||||||
|
struct work_struct cancellation_work;
|
||||||
|
|
||||||
struct usb_ep *ep;
|
struct usb_ep *ep;
|
||||||
struct usb_request *req;
|
struct usb_request *req;
|
||||||
|
@ -1072,22 +1073,31 @@ ffs_epfile_open(struct inode *inode, struct file *file)
|
||||||
return 0;
|
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)
|
static int ffs_aio_cancel(struct kiocb *kiocb)
|
||||||
{
|
{
|
||||||
struct ffs_io_data *io_data = kiocb->private;
|
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;
|
int value;
|
||||||
|
|
||||||
ENTER();
|
ENTER();
|
||||||
|
|
||||||
spin_lock_irq(&epfile->ffs->eps_lock);
|
if (likely(io_data && io_data->ep && io_data->req)) {
|
||||||
|
INIT_WORK(&io_data->cancellation_work, ffs_aio_cancel_worker);
|
||||||
if (likely(io_data && io_data->ep && io_data->req))
|
queue_work(ffs->io_completion_wq, &io_data->cancellation_work);
|
||||||
value = usb_ep_dequeue(io_data->ep, io_data->req);
|
value = -EINPROGRESS;
|
||||||
else
|
} else {
|
||||||
value = -EINVAL;
|
value = -EINVAL;
|
||||||
|
}
|
||||||
spin_unlock_irq(&epfile->ffs->eps_lock);
|
|
||||||
|
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
|
@ -886,12 +886,12 @@ void xhci_free_virt_device(struct xhci_hcd *xhci, int slot_id)
|
||||||
|
|
||||||
dev = xhci->devs[slot_id];
|
dev = xhci->devs[slot_id];
|
||||||
|
|
||||||
trace_xhci_free_virt_device(dev);
|
|
||||||
|
|
||||||
xhci->dcbaa->dev_context_ptrs[slot_id] = 0;
|
xhci->dcbaa->dev_context_ptrs[slot_id] = 0;
|
||||||
if (!dev)
|
if (!dev)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
trace_xhci_free_virt_device(dev);
|
||||||
|
|
||||||
if (dev->tt_info)
|
if (dev->tt_info)
|
||||||
old_active_eps = dev->tt_info->active_eps;
|
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 long mask;
|
||||||
unsigned int port;
|
unsigned int port;
|
||||||
bool idle, enable;
|
bool idle, enable;
|
||||||
int err;
|
int err = 0;
|
||||||
|
|
||||||
memset(&rsp, 0, sizeof(rsp));
|
memset(&rsp, 0, sizeof(rsp));
|
||||||
|
|
||||||
|
@ -1223,10 +1223,10 @@ disable_rpm:
|
||||||
pm_runtime_disable(&pdev->dev);
|
pm_runtime_disable(&pdev->dev);
|
||||||
usb_put_hcd(tegra->hcd);
|
usb_put_hcd(tegra->hcd);
|
||||||
disable_xusbc:
|
disable_xusbc:
|
||||||
if (!&pdev->dev.pm_domain)
|
if (!pdev->dev.pm_domain)
|
||||||
tegra_powergate_power_off(TEGRA_POWERGATE_XUSBC);
|
tegra_powergate_power_off(TEGRA_POWERGATE_XUSBC);
|
||||||
disable_xusba:
|
disable_xusba:
|
||||||
if (!&pdev->dev.pm_domain)
|
if (!pdev->dev.pm_domain)
|
||||||
tegra_powergate_power_off(TEGRA_POWERGATE_XUSBA);
|
tegra_powergate_power_off(TEGRA_POWERGATE_XUSBA);
|
||||||
put_padctl:
|
put_padctl:
|
||||||
tegra_xusb_padctl_put(tegra->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)
|
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,
|
DECLARE_EVENT_CLASS(xhci_log_virt_dev,
|
||||||
TP_PROTO(struct xhci_virt_device *vdev),
|
TP_PROTO(struct xhci_virt_device *vdev),
|
||||||
TP_ARGS(vdev),
|
TP_ARGS(vdev),
|
||||||
|
@ -208,11 +239,6 @@ DEFINE_EVENT(xhci_log_virt_dev, xhci_alloc_virt_device,
|
||||||
TP_ARGS(vdev)
|
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,
|
DEFINE_EVENT(xhci_log_virt_dev, xhci_setup_device,
|
||||||
TP_PROTO(struct xhci_virt_device *vdev),
|
TP_PROTO(struct xhci_virt_device *vdev),
|
||||||
TP_ARGS(vdev)
|
TP_ARGS(vdev)
|
||||||
|
|
|
@ -908,6 +908,41 @@ static void xhci_disable_port_wake_on_bits(struct xhci_hcd *xhci)
|
||||||
spin_unlock_irqrestore(&xhci->lock, flags);
|
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)
|
* Stop HC (not bus-specific)
|
||||||
*
|
*
|
||||||
|
@ -1009,7 +1044,7 @@ EXPORT_SYMBOL_GPL(xhci_suspend);
|
||||||
*/
|
*/
|
||||||
int xhci_resume(struct xhci_hcd *xhci, bool hibernated)
|
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 *hcd = xhci_to_hcd(xhci);
|
||||||
struct usb_hcd *secondary_hcd;
|
struct usb_hcd *secondary_hcd;
|
||||||
int retval = 0;
|
int retval = 0;
|
||||||
|
@ -1043,8 +1078,13 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated)
|
||||||
command = readl(&xhci->op_regs->command);
|
command = readl(&xhci->op_regs->command);
|
||||||
command |= CMD_CRS;
|
command |= CMD_CRS;
|
||||||
writel(command, &xhci->op_regs->command);
|
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,
|
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");
|
xhci_warn(xhci, "WARN: xHC restore state timeout\n");
|
||||||
spin_unlock_irq(&xhci->lock);
|
spin_unlock_irq(&xhci->lock);
|
||||||
return -ETIMEDOUT;
|
return -ETIMEDOUT;
|
||||||
|
@ -1134,8 +1174,7 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated)
|
||||||
done:
|
done:
|
||||||
if (retval == 0) {
|
if (retval == 0) {
|
||||||
/* Resume root hubs only when have pending events. */
|
/* Resume root hubs only when have pending events. */
|
||||||
status = readl(&xhci->op_regs->status);
|
if (xhci_pending_portevent(xhci)) {
|
||||||
if (status & STS_EINT) {
|
|
||||||
usb_hcd_resume_root_hub(xhci->shared_hcd);
|
usb_hcd_resume_root_hub(xhci->shared_hcd);
|
||||||
usb_hcd_resume_root_hub(hcd);
|
usb_hcd_resume_root_hub(hcd);
|
||||||
}
|
}
|
||||||
|
|
|
@ -382,6 +382,10 @@ struct xhci_op_regs {
|
||||||
#define PORT_PLC (1 << 22)
|
#define PORT_PLC (1 << 22)
|
||||||
/* port configure error change - port failed to configure its link partner */
|
/* port configure error change - port failed to configure its link partner */
|
||||||
#define PORT_CEC (1 << 23)
|
#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
|
/* 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
|
* Sx state. Warm port reset should be perfomed to clear this bit and move port
|
||||||
* to connected state.
|
* 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, 0x8156) }, /* B&G H3000 link cable */
|
||||||
{ USB_DEVICE(0x10C4, 0x815E) }, /* Helicomm IP-Link 1220-DVM */
|
{ USB_DEVICE(0x10C4, 0x815E) }, /* Helicomm IP-Link 1220-DVM */
|
||||||
{ USB_DEVICE(0x10C4, 0x815F) }, /* Timewave HamLinkUSB */
|
{ 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, 0x818B) }, /* AVIT Research USB to TTL */
|
||||||
{ USB_DEVICE(0x10C4, 0x819F) }, /* MJS USB Toslink Switcher */
|
{ USB_DEVICE(0x10C4, 0x819F) }, /* MJS USB Toslink Switcher */
|
||||||
{ USB_DEVICE(0x10C4, 0x81A6) }, /* ThinkOptics WavIt */
|
{ 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, 0x826B) }, /* Cygnal Integrated Products, Inc., Fasttrax GPS demonstration module */
|
||||||
{ USB_DEVICE(0x10C4, 0x8281) }, /* Nanotec Plug & Drive */
|
{ USB_DEVICE(0x10C4, 0x8281) }, /* Nanotec Plug & Drive */
|
||||||
{ USB_DEVICE(0x10C4, 0x8293) }, /* Telegesis ETRX2USB */
|
{ 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, 0x82F4) }, /* Starizona MicroTouch */
|
||||||
{ USB_DEVICE(0x10C4, 0x82F9) }, /* Procyon AVS */
|
{ USB_DEVICE(0x10C4, 0x82F9) }, /* Procyon AVS */
|
||||||
{ USB_DEVICE(0x10C4, 0x8341) }, /* Siemens MC35PU GPRS Modem */
|
{ 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, 0x8470) }, /* Juniper Networks BX Series System Console */
|
||||||
{ USB_DEVICE(0x10C4, 0x8477) }, /* Balluff RFID */
|
{ USB_DEVICE(0x10C4, 0x8477) }, /* Balluff RFID */
|
||||||
{ USB_DEVICE(0x10C4, 0x84B6) }, /* Starizona Hyperion */
|
{ 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, 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, 0x85EA) }, /* AC-Services IBUS-IF */
|
||||||
{ USB_DEVICE(0x10C4, 0x85EB) }, /* AC-Services CIS-IBUS */
|
{ USB_DEVICE(0x10C4, 0x85EB) }, /* AC-Services CIS-IBUS */
|
||||||
{ USB_DEVICE(0x10C4, 0x85F8) }, /* Virtenio Preon32 */
|
{ 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, 0x8857) }, /* CEL EM357 ZigBee USB Stick */
|
||||||
{ USB_DEVICE(0x10C4, 0x88A4) }, /* MMB Networks ZigBee USB Device */
|
{ USB_DEVICE(0x10C4, 0x88A4) }, /* MMB Networks ZigBee USB Device */
|
||||||
{ USB_DEVICE(0x10C4, 0x88A5) }, /* Planet Innovation Ingeni 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, 0x8946) }, /* Ketra N1 Wireless Interface */
|
||||||
{ USB_DEVICE(0x10C4, 0x8962) }, /* Brim Brothers charging dock */
|
{ USB_DEVICE(0x10C4, 0x8962) }, /* Brim Brothers charging dock */
|
||||||
{ USB_DEVICE(0x10C4, 0x8977) }, /* CEL MeshWorks DevKit Device */
|
{ USB_DEVICE(0x10C4, 0x8977) }, /* CEL MeshWorks DevKit Device */
|
||||||
{ USB_DEVICE(0x10C4, 0x8998) }, /* KCF Technologies PRN */
|
{ 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, 0x8A2A) }, /* HubZ dual ZigBee and Z-Wave dongle */
|
||||||
{ USB_DEVICE(0x10C4, 0x8A5E) }, /* CEL EM3588 ZigBee USB Stick Long Range */
|
{ USB_DEVICE(0x10C4, 0x8A5E) }, /* CEL EM3588 ZigBee USB Stick Long Range */
|
||||||
{ USB_DEVICE(0x10C4, 0x8B34) }, /* Qivicon ZigBee USB Radio Stick */
|
{ USB_DEVICE(0x10C4, 0x8B34) }, /* Qivicon ZigBee USB Radio Stick */
|
||||||
{ USB_DEVICE(0x10C4, 0xEA60) }, /* Silicon Labs factory default */
|
{ USB_DEVICE(0x10C4, 0xEA60) }, /* Silicon Labs factory default */
|
||||||
{ USB_DEVICE(0x10C4, 0xEA61) }, /* 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, 0xEA70) }, /* Silicon Labs factory default */
|
||||||
{ USB_DEVICE(0x10C4, 0xEA71) }, /* Infinity GPS-MIC-1 Radio Monophone */
|
{ 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, 0xF001) }, /* Elan Digital Systems USBscope50 */
|
||||||
{ USB_DEVICE(0x10C4, 0xF002) }, /* Elan Digital Systems USBwave12 */
|
{ USB_DEVICE(0x10C4, 0xF002) }, /* Elan Digital Systems USBwave12 */
|
||||||
{ USB_DEVICE(0x10C4, 0xF003) }, /* Elan Digital Systems USBpulse100 */
|
{ 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();
|
u64 ts_nsec = local_clock();
|
||||||
unsigned long rem_nsec;
|
unsigned long rem_nsec;
|
||||||
|
|
||||||
|
mutex_lock(&port->logbuffer_lock);
|
||||||
if (!port->logbuffer[port->logbuffer_head]) {
|
if (!port->logbuffer[port->logbuffer_head]) {
|
||||||
port->logbuffer[port->logbuffer_head] =
|
port->logbuffer[port->logbuffer_head] =
|
||||||
kzalloc(LOG_BUFFER_ENTRY_SIZE, GFP_KERNEL);
|
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;
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
vsnprintf(tmpbuffer, sizeof(tmpbuffer), fmt, args);
|
vsnprintf(tmpbuffer, sizeof(tmpbuffer), fmt, args);
|
||||||
|
|
||||||
mutex_lock(&port->logbuffer_lock);
|
|
||||||
|
|
||||||
if (tcpm_log_full(port)) {
|
if (tcpm_log_full(port)) {
|
||||||
port->logbuffer_head = max(port->logbuffer_head - 1, 0);
|
port->logbuffer_head = max(port->logbuffer_head - 1, 0);
|
||||||
strcpy(tmpbuffer, "overflow");
|
strcpy(tmpbuffer, "overflow");
|
||||||
|
@ -3043,7 +3044,8 @@ static void run_state_machine(struct tcpm_port *port)
|
||||||
tcpm_port_is_sink(port) &&
|
tcpm_port_is_sink(port) &&
|
||||||
time_is_after_jiffies(port->delayed_runtime)) {
|
time_is_after_jiffies(port->delayed_runtime)) {
|
||||||
tcpm_set_state(port, SNK_DISCOVERY,
|
tcpm_set_state(port, SNK_DISCOVERY,
|
||||||
port->delayed_runtime - jiffies);
|
jiffies_to_msecs(port->delayed_runtime -
|
||||||
|
jiffies));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
tcpm_set_state(port, unattached_state(port), 0);
|
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) {
|
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)
|
if (con->status.connected)
|
||||||
ucsi_register_partner(con);
|
ucsi_register_partner(con);
|
||||||
else
|
else
|
||||||
|
|
|
@ -79,6 +79,11 @@ static int ucsi_acpi_probe(struct platform_device *pdev)
|
||||||
return -ENODEV;
|
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
|
* NOTE: The memory region for the data structures is used also in an
|
||||||
* operation region, which means ACPI has already reserved it. Therefore
|
* operation region, which means ACPI has already reserved it. Therefore
|
||||||
|
|
|
@ -443,6 +443,9 @@ int acpi_check_resource_conflict(const struct resource *res);
|
||||||
int acpi_check_region(resource_size_t start, resource_size_t n,
|
int acpi_check_region(resource_size_t start, resource_size_t n,
|
||||||
const char *name);
|
const char *name);
|
||||||
|
|
||||||
|
acpi_status acpi_release_memory(acpi_handle handle, struct resource *res,
|
||||||
|
u32 level);
|
||||||
|
|
||||||
int acpi_resources_are_enforced(void);
|
int acpi_resources_are_enforced(void);
|
||||||
|
|
||||||
#ifdef CONFIG_HIBERNATION
|
#ifdef CONFIG_HIBERNATION
|
||||||
|
|
Loading…
Reference in a new issue