mirror of
https://github.com/suyu-emu/horinux.git
synced 2026-09-21 14:15:21 -07:00
Merge tag 'usb-4.0-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb
Pull USB fixes from Greg KH: "Here's a round of USB fixes for 4.0-rc3. Nothing major, the usual gadget, xhci and usb-serial fixes and a few new device ids as well. All have been in linux-next successfully" * tag 'usb-4.0-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb: (36 commits) xhci: Workaround for PME stuck issues in Intel xhci xhci: fix reporting of 0-sized URBs in control endpoint usb: ftdi_sio: Add jtag quirk support for Cyber Cortex AV boards USB: ch341: set tty baud speed according to tty struct USB: serial: cp210x: Adding Seletek device id's USB: pl2303: disable break on shutdown USB: mxuport: fix null deref when used as a console USB: serial: clean up bus probe error handling USB: serial: fix port attribute-creation race USB: serial: fix tty-device error handling at probe USB: serial: fix potential use-after-free after failed probe USB: console: add dummy __module_get USB: ftdi_sio: add PIDs for Actisense USB devices Revert "USB: serial: make bulk_out_size a lower limit" cdc-acm: Add support for Denso cradle CU-321 usb-storage: support for more than 8 LUNs uas: Add US_FL_NO_REPORT_OPCODES for JMicron JMS539 USB: usbfs: don't leak kernel data in siginfo xhci: Clear the host side toggle manually when endpoint is 'soft reset' xhci: Allocate correct amount of scratchpad buffers ...
This commit is contained in:
@@ -1650,6 +1650,8 @@ static int acm_reset_resume(struct usb_interface *intf)
|
||||
|
||||
static const struct usb_device_id acm_ids[] = {
|
||||
/* quirky and broken devices */
|
||||
{ USB_DEVICE(0x076d, 0x0006), /* Denso Cradle CU-321 */
|
||||
.driver_info = NO_UNION_NORMAL, },/* has no union descriptor */
|
||||
{ USB_DEVICE(0x17ef, 0x7000), /* Lenovo USB modem */
|
||||
.driver_info = NO_UNION_NORMAL, },/* has no union descriptor */
|
||||
{ USB_DEVICE(0x0870, 0x0001), /* Metricom GS Modem */
|
||||
|
||||
@@ -501,6 +501,7 @@ static void async_completed(struct urb *urb)
|
||||
as->status = urb->status;
|
||||
signr = as->signr;
|
||||
if (signr) {
|
||||
memset(&sinfo, 0, sizeof(sinfo));
|
||||
sinfo.si_signo = as->signr;
|
||||
sinfo.si_errno = as->status;
|
||||
sinfo.si_code = SI_ASYNCIO;
|
||||
@@ -2382,6 +2383,7 @@ static void usbdev_remove(struct usb_device *udev)
|
||||
wake_up_all(&ps->wait);
|
||||
list_del_init(&ps->list);
|
||||
if (ps->discsignr) {
|
||||
memset(&sinfo, 0, sizeof(sinfo));
|
||||
sinfo.si_signo = ps->discsignr;
|
||||
sinfo.si_errno = EPIPE;
|
||||
sinfo.si_code = SI_ASYNCIO;
|
||||
|
||||
@@ -205,6 +205,18 @@ static void dwc3_omap_write_irq0_set(struct dwc3_omap *omap, u32 value)
|
||||
omap->irq0_offset, value);
|
||||
}
|
||||
|
||||
static void dwc3_omap_write_irqmisc_clr(struct dwc3_omap *omap, u32 value)
|
||||
{
|
||||
dwc3_omap_writel(omap->base, USBOTGSS_IRQENABLE_CLR_MISC +
|
||||
omap->irqmisc_offset, value);
|
||||
}
|
||||
|
||||
static void dwc3_omap_write_irq0_clr(struct dwc3_omap *omap, u32 value)
|
||||
{
|
||||
dwc3_omap_writel(omap->base, USBOTGSS_IRQENABLE_CLR_0 -
|
||||
omap->irq0_offset, value);
|
||||
}
|
||||
|
||||
static void dwc3_omap_set_mailbox(struct dwc3_omap *omap,
|
||||
enum omap_dwc3_vbus_id_status status)
|
||||
{
|
||||
@@ -345,9 +357,23 @@ static void dwc3_omap_enable_irqs(struct dwc3_omap *omap)
|
||||
|
||||
static void dwc3_omap_disable_irqs(struct dwc3_omap *omap)
|
||||
{
|
||||
u32 reg;
|
||||
|
||||
/* disable all IRQs */
|
||||
dwc3_omap_write_irqmisc_set(omap, 0x00);
|
||||
dwc3_omap_write_irq0_set(omap, 0x00);
|
||||
reg = USBOTGSS_IRQO_COREIRQ_ST;
|
||||
dwc3_omap_write_irq0_clr(omap, reg);
|
||||
|
||||
reg = (USBOTGSS_IRQMISC_OEVT |
|
||||
USBOTGSS_IRQMISC_DRVVBUS_RISE |
|
||||
USBOTGSS_IRQMISC_CHRGVBUS_RISE |
|
||||
USBOTGSS_IRQMISC_DISCHRGVBUS_RISE |
|
||||
USBOTGSS_IRQMISC_IDPULLUP_RISE |
|
||||
USBOTGSS_IRQMISC_DRVVBUS_FALL |
|
||||
USBOTGSS_IRQMISC_CHRGVBUS_FALL |
|
||||
USBOTGSS_IRQMISC_DISCHRGVBUS_FALL |
|
||||
USBOTGSS_IRQMISC_IDPULLUP_FALL);
|
||||
|
||||
dwc3_omap_write_irqmisc_clr(omap, reg);
|
||||
}
|
||||
|
||||
static u64 dwc3_omap_dma_mask = DMA_BIT_MASK(32);
|
||||
|
||||
@@ -1161,7 +1161,6 @@ static ssize_t interf_grp_compatible_id_store(struct usb_os_desc *desc,
|
||||
if (desc->opts_mutex)
|
||||
mutex_lock(desc->opts_mutex);
|
||||
memcpy(desc->ext_compat_id, page, l);
|
||||
desc->ext_compat_id[l] = '\0';
|
||||
|
||||
if (desc->opts_mutex)
|
||||
mutex_unlock(desc->opts_mutex);
|
||||
@@ -1192,7 +1191,6 @@ static ssize_t interf_grp_sub_compatible_id_store(struct usb_os_desc *desc,
|
||||
if (desc->opts_mutex)
|
||||
mutex_lock(desc->opts_mutex);
|
||||
memcpy(desc->ext_compat_id + 8, page, l);
|
||||
desc->ext_compat_id[l + 8] = '\0';
|
||||
|
||||
if (desc->opts_mutex)
|
||||
mutex_unlock(desc->opts_mutex);
|
||||
|
||||
@@ -569,7 +569,7 @@ fail:
|
||||
return status;
|
||||
}
|
||||
|
||||
const struct file_operations f_hidg_fops = {
|
||||
static const struct file_operations f_hidg_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = f_hidg_open,
|
||||
.release = f_hidg_release,
|
||||
|
||||
@@ -417,7 +417,10 @@ static int pn_set_alt(struct usb_function *f, unsigned intf, unsigned alt)
|
||||
return -EINVAL;
|
||||
|
||||
spin_lock(&port->lock);
|
||||
__pn_reset(f);
|
||||
|
||||
if (fp->in_ep->driver_data)
|
||||
__pn_reset(f);
|
||||
|
||||
if (alt == 1) {
|
||||
int i;
|
||||
|
||||
|
||||
@@ -344,7 +344,7 @@ static struct usb_endpoint_descriptor ss_int_source_desc = {
|
||||
.bInterval = USB_MS_TO_SS_INTERVAL(GZERO_INT_INTERVAL),
|
||||
};
|
||||
|
||||
struct usb_ss_ep_comp_descriptor ss_int_source_comp_desc = {
|
||||
static struct usb_ss_ep_comp_descriptor ss_int_source_comp_desc = {
|
||||
.bLength = USB_DT_SS_EP_COMP_SIZE,
|
||||
.bDescriptorType = USB_DT_SS_ENDPOINT_COMP,
|
||||
|
||||
@@ -362,7 +362,7 @@ static struct usb_endpoint_descriptor ss_int_sink_desc = {
|
||||
.bInterval = USB_MS_TO_SS_INTERVAL(GZERO_INT_INTERVAL),
|
||||
};
|
||||
|
||||
struct usb_ss_ep_comp_descriptor ss_int_sink_comp_desc = {
|
||||
static struct usb_ss_ep_comp_descriptor ss_int_sink_comp_desc = {
|
||||
.bLength = USB_DT_SS_EP_COMP_SIZE,
|
||||
.bDescriptorType = USB_DT_SS_ENDPOINT_COMP,
|
||||
|
||||
|
||||
@@ -54,7 +54,7 @@
|
||||
#define UNFLW_CTRL 8
|
||||
#define OVFLW_CTRL 10
|
||||
|
||||
const char *uac2_name = "snd_uac2";
|
||||
static const char *uac2_name = "snd_uac2";
|
||||
|
||||
struct uac2_req {
|
||||
struct uac2_rtd_params *pp; /* parent param */
|
||||
@@ -634,7 +634,7 @@ static struct usb_interface_descriptor std_ac_if_desc = {
|
||||
};
|
||||
|
||||
/* Clock source for IN traffic */
|
||||
struct uac_clock_source_descriptor in_clk_src_desc = {
|
||||
static struct uac_clock_source_descriptor in_clk_src_desc = {
|
||||
.bLength = sizeof in_clk_src_desc,
|
||||
.bDescriptorType = USB_DT_CS_INTERFACE,
|
||||
|
||||
@@ -646,7 +646,7 @@ struct uac_clock_source_descriptor in_clk_src_desc = {
|
||||
};
|
||||
|
||||
/* Clock source for OUT traffic */
|
||||
struct uac_clock_source_descriptor out_clk_src_desc = {
|
||||
static struct uac_clock_source_descriptor out_clk_src_desc = {
|
||||
.bLength = sizeof out_clk_src_desc,
|
||||
.bDescriptorType = USB_DT_CS_INTERFACE,
|
||||
|
||||
@@ -658,7 +658,7 @@ struct uac_clock_source_descriptor out_clk_src_desc = {
|
||||
};
|
||||
|
||||
/* Input Terminal for USB_OUT */
|
||||
struct uac2_input_terminal_descriptor usb_out_it_desc = {
|
||||
static struct uac2_input_terminal_descriptor usb_out_it_desc = {
|
||||
.bLength = sizeof usb_out_it_desc,
|
||||
.bDescriptorType = USB_DT_CS_INTERFACE,
|
||||
|
||||
@@ -672,7 +672,7 @@ struct uac2_input_terminal_descriptor usb_out_it_desc = {
|
||||
};
|
||||
|
||||
/* Input Terminal for I/O-In */
|
||||
struct uac2_input_terminal_descriptor io_in_it_desc = {
|
||||
static struct uac2_input_terminal_descriptor io_in_it_desc = {
|
||||
.bLength = sizeof io_in_it_desc,
|
||||
.bDescriptorType = USB_DT_CS_INTERFACE,
|
||||
|
||||
@@ -686,7 +686,7 @@ struct uac2_input_terminal_descriptor io_in_it_desc = {
|
||||
};
|
||||
|
||||
/* Ouput Terminal for USB_IN */
|
||||
struct uac2_output_terminal_descriptor usb_in_ot_desc = {
|
||||
static struct uac2_output_terminal_descriptor usb_in_ot_desc = {
|
||||
.bLength = sizeof usb_in_ot_desc,
|
||||
.bDescriptorType = USB_DT_CS_INTERFACE,
|
||||
|
||||
@@ -700,7 +700,7 @@ struct uac2_output_terminal_descriptor usb_in_ot_desc = {
|
||||
};
|
||||
|
||||
/* Ouput Terminal for I/O-Out */
|
||||
struct uac2_output_terminal_descriptor io_out_ot_desc = {
|
||||
static struct uac2_output_terminal_descriptor io_out_ot_desc = {
|
||||
.bLength = sizeof io_out_ot_desc,
|
||||
.bDescriptorType = USB_DT_CS_INTERFACE,
|
||||
|
||||
@@ -713,7 +713,7 @@ struct uac2_output_terminal_descriptor io_out_ot_desc = {
|
||||
.bmControls = (CONTROL_RDWR << COPY_CTRL),
|
||||
};
|
||||
|
||||
struct uac2_ac_header_descriptor ac_hdr_desc = {
|
||||
static struct uac2_ac_header_descriptor ac_hdr_desc = {
|
||||
.bLength = sizeof ac_hdr_desc,
|
||||
.bDescriptorType = USB_DT_CS_INTERFACE,
|
||||
|
||||
@@ -751,7 +751,7 @@ static struct usb_interface_descriptor std_as_out_if1_desc = {
|
||||
};
|
||||
|
||||
/* Audio Stream OUT Intface Desc */
|
||||
struct uac2_as_header_descriptor as_out_hdr_desc = {
|
||||
static struct uac2_as_header_descriptor as_out_hdr_desc = {
|
||||
.bLength = sizeof as_out_hdr_desc,
|
||||
.bDescriptorType = USB_DT_CS_INTERFACE,
|
||||
|
||||
@@ -764,7 +764,7 @@ struct uac2_as_header_descriptor as_out_hdr_desc = {
|
||||
};
|
||||
|
||||
/* Audio USB_OUT Format */
|
||||
struct uac2_format_type_i_descriptor as_out_fmt1_desc = {
|
||||
static struct uac2_format_type_i_descriptor as_out_fmt1_desc = {
|
||||
.bLength = sizeof as_out_fmt1_desc,
|
||||
.bDescriptorType = USB_DT_CS_INTERFACE,
|
||||
.bDescriptorSubtype = UAC_FORMAT_TYPE,
|
||||
@@ -772,7 +772,7 @@ struct uac2_format_type_i_descriptor as_out_fmt1_desc = {
|
||||
};
|
||||
|
||||
/* STD AS ISO OUT Endpoint */
|
||||
struct usb_endpoint_descriptor fs_epout_desc = {
|
||||
static struct usb_endpoint_descriptor fs_epout_desc = {
|
||||
.bLength = USB_DT_ENDPOINT_SIZE,
|
||||
.bDescriptorType = USB_DT_ENDPOINT,
|
||||
|
||||
@@ -782,7 +782,7 @@ struct usb_endpoint_descriptor fs_epout_desc = {
|
||||
.bInterval = 1,
|
||||
};
|
||||
|
||||
struct usb_endpoint_descriptor hs_epout_desc = {
|
||||
static struct usb_endpoint_descriptor hs_epout_desc = {
|
||||
.bLength = USB_DT_ENDPOINT_SIZE,
|
||||
.bDescriptorType = USB_DT_ENDPOINT,
|
||||
|
||||
@@ -828,7 +828,7 @@ static struct usb_interface_descriptor std_as_in_if1_desc = {
|
||||
};
|
||||
|
||||
/* Audio Stream IN Intface Desc */
|
||||
struct uac2_as_header_descriptor as_in_hdr_desc = {
|
||||
static struct uac2_as_header_descriptor as_in_hdr_desc = {
|
||||
.bLength = sizeof as_in_hdr_desc,
|
||||
.bDescriptorType = USB_DT_CS_INTERFACE,
|
||||
|
||||
@@ -841,7 +841,7 @@ struct uac2_as_header_descriptor as_in_hdr_desc = {
|
||||
};
|
||||
|
||||
/* Audio USB_IN Format */
|
||||
struct uac2_format_type_i_descriptor as_in_fmt1_desc = {
|
||||
static struct uac2_format_type_i_descriptor as_in_fmt1_desc = {
|
||||
.bLength = sizeof as_in_fmt1_desc,
|
||||
.bDescriptorType = USB_DT_CS_INTERFACE,
|
||||
.bDescriptorSubtype = UAC_FORMAT_TYPE,
|
||||
@@ -849,7 +849,7 @@ struct uac2_format_type_i_descriptor as_in_fmt1_desc = {
|
||||
};
|
||||
|
||||
/* STD AS ISO IN Endpoint */
|
||||
struct usb_endpoint_descriptor fs_epin_desc = {
|
||||
static struct usb_endpoint_descriptor fs_epin_desc = {
|
||||
.bLength = USB_DT_ENDPOINT_SIZE,
|
||||
.bDescriptorType = USB_DT_ENDPOINT,
|
||||
|
||||
@@ -859,7 +859,7 @@ struct usb_endpoint_descriptor fs_epin_desc = {
|
||||
.bInterval = 1,
|
||||
};
|
||||
|
||||
struct usb_endpoint_descriptor hs_epin_desc = {
|
||||
static struct usb_endpoint_descriptor hs_epin_desc = {
|
||||
.bLength = USB_DT_ENDPOINT_SIZE,
|
||||
.bDescriptorType = USB_DT_ENDPOINT,
|
||||
|
||||
@@ -1563,7 +1563,7 @@ static void afunc_unbind(struct usb_configuration *c, struct usb_function *f)
|
||||
agdev->out_ep->driver_data = NULL;
|
||||
}
|
||||
|
||||
struct usb_function *afunc_alloc(struct usb_function_instance *fi)
|
||||
static struct usb_function *afunc_alloc(struct usb_function_instance *fi)
|
||||
{
|
||||
struct audio_dev *agdev;
|
||||
struct f_uac2_opts *opts;
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
#include "uvc.h"
|
||||
#include "uvc_queue.h"
|
||||
#include "uvc_video.h"
|
||||
#include "uvc_v4l2.h"
|
||||
|
||||
/* --------------------------------------------------------------------------
|
||||
* Requests handling
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
|
||||
#include "uvc.h"
|
||||
#include "uvc_queue.h"
|
||||
#include "uvc_video.h"
|
||||
|
||||
/* --------------------------------------------------------------------------
|
||||
* Video codecs
|
||||
|
||||
@@ -133,7 +133,9 @@ struct gfs_configuration {
|
||||
struct usb_configuration c;
|
||||
int (*eth)(struct usb_configuration *c);
|
||||
int num;
|
||||
} gfs_configurations[] = {
|
||||
};
|
||||
|
||||
static struct gfs_configuration gfs_configurations[] = {
|
||||
#ifdef CONFIG_USB_FUNCTIONFS_RNDIS
|
||||
{
|
||||
.eth = bind_rndis_config,
|
||||
@@ -278,7 +280,7 @@ static void *functionfs_acquire_dev(struct ffs_dev *dev)
|
||||
if (!try_module_get(THIS_MODULE))
|
||||
return ERR_PTR(-ENOENT);
|
||||
|
||||
return 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void functionfs_release_dev(struct ffs_dev *dev)
|
||||
|
||||
@@ -37,6 +37,9 @@
|
||||
|
||||
#define PCI_DEVICE_ID_INTEL_LYNXPOINT_XHCI 0x8c31
|
||||
#define PCI_DEVICE_ID_INTEL_LYNXPOINT_LP_XHCI 0x9c31
|
||||
#define PCI_DEVICE_ID_INTEL_CHERRYVIEW_XHCI 0x22b5
|
||||
#define PCI_DEVICE_ID_INTEL_SUNRISEPOINT_H_XHCI 0xa12f
|
||||
#define PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_XHCI 0x9d2f
|
||||
|
||||
static const char hcd_name[] = "xhci_hcd";
|
||||
|
||||
@@ -133,6 +136,12 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci)
|
||||
pdev->device == PCI_DEVICE_ID_INTEL_LYNXPOINT_LP_XHCI) {
|
||||
xhci->quirks |= XHCI_SPURIOUS_REBOOT;
|
||||
}
|
||||
if (pdev->vendor == PCI_VENDOR_ID_INTEL &&
|
||||
(pdev->device == PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_XHCI ||
|
||||
pdev->device == PCI_DEVICE_ID_INTEL_SUNRISEPOINT_H_XHCI ||
|
||||
pdev->device == PCI_DEVICE_ID_INTEL_CHERRYVIEW_XHCI)) {
|
||||
xhci->quirks |= XHCI_PME_STUCK_QUIRK;
|
||||
}
|
||||
if (pdev->vendor == PCI_VENDOR_ID_ETRON &&
|
||||
pdev->device == PCI_DEVICE_ID_EJ168) {
|
||||
xhci->quirks |= XHCI_RESET_ON_RESUME;
|
||||
@@ -159,6 +168,21 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci)
|
||||
"QUIRK: Resetting on resume");
|
||||
}
|
||||
|
||||
/*
|
||||
* Make sure PME works on some Intel xHCI controllers by writing 1 to clear
|
||||
* the Internal PME flag bit in vendor specific PMCTRL register at offset 0x80a4
|
||||
*/
|
||||
static void xhci_pme_quirk(struct xhci_hcd *xhci)
|
||||
{
|
||||
u32 val;
|
||||
void __iomem *reg;
|
||||
|
||||
reg = (void __iomem *) xhci->cap_regs + 0x80a4;
|
||||
val = readl(reg);
|
||||
writel(val | BIT(28), reg);
|
||||
readl(reg);
|
||||
}
|
||||
|
||||
/* called during probe() after chip reset completes */
|
||||
static int xhci_pci_setup(struct usb_hcd *hcd)
|
||||
{
|
||||
@@ -283,6 +307,9 @@ static int xhci_pci_suspend(struct usb_hcd *hcd, bool do_wakeup)
|
||||
if (xhci->quirks & XHCI_COMP_MODE_QUIRK)
|
||||
pdev->no_d3cold = true;
|
||||
|
||||
if (xhci->quirks & XHCI_PME_STUCK_QUIRK)
|
||||
xhci_pme_quirk(xhci);
|
||||
|
||||
return xhci_suspend(xhci, do_wakeup);
|
||||
}
|
||||
|
||||
@@ -313,6 +340,9 @@ static int xhci_pci_resume(struct usb_hcd *hcd, bool hibernated)
|
||||
if (pdev->vendor == PCI_VENDOR_ID_INTEL)
|
||||
usb_enable_intel_xhci_ports(pdev);
|
||||
|
||||
if (xhci->quirks & XHCI_PME_STUCK_QUIRK)
|
||||
xhci_pme_quirk(xhci);
|
||||
|
||||
retval = xhci_resume(xhci, hibernated);
|
||||
return retval;
|
||||
}
|
||||
|
||||
@@ -83,16 +83,6 @@ static int xhci_plat_probe(struct platform_device *pdev)
|
||||
if (irq < 0)
|
||||
return -ENODEV;
|
||||
|
||||
|
||||
if (of_device_is_compatible(pdev->dev.of_node,
|
||||
"marvell,armada-375-xhci") ||
|
||||
of_device_is_compatible(pdev->dev.of_node,
|
||||
"marvell,armada-380-xhci")) {
|
||||
ret = xhci_mvebu_mbus_init_quirk(pdev);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Initialize dma_mask and coherent_dma_mask to 32-bits */
|
||||
ret = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32));
|
||||
if (ret)
|
||||
@@ -127,6 +117,15 @@ static int xhci_plat_probe(struct platform_device *pdev)
|
||||
goto put_hcd;
|
||||
}
|
||||
|
||||
if (of_device_is_compatible(pdev->dev.of_node,
|
||||
"marvell,armada-375-xhci") ||
|
||||
of_device_is_compatible(pdev->dev.of_node,
|
||||
"marvell,armada-380-xhci")) {
|
||||
ret = xhci_mvebu_mbus_init_quirk(pdev);
|
||||
if (ret)
|
||||
goto disable_clk;
|
||||
}
|
||||
|
||||
ret = usb_add_hcd(hcd, irq, IRQF_SHARED);
|
||||
if (ret)
|
||||
goto disable_clk;
|
||||
|
||||
@@ -1729,7 +1729,7 @@ static void xhci_cleanup_halted_endpoint(struct xhci_hcd *xhci,
|
||||
if (!command)
|
||||
return;
|
||||
|
||||
ep->ep_state |= EP_HALTED;
|
||||
ep->ep_state |= EP_HALTED | EP_RECENTLY_HALTED;
|
||||
ep->stopped_stream = stream_id;
|
||||
|
||||
xhci_queue_reset_ep(xhci, command, slot_id, ep_index);
|
||||
@@ -1946,7 +1946,7 @@ static int process_ctrl_td(struct xhci_hcd *xhci, struct xhci_td *td,
|
||||
if (event_trb != ep_ring->dequeue) {
|
||||
/* The event was for the status stage */
|
||||
if (event_trb == td->last_trb) {
|
||||
if (td->urb->actual_length != 0) {
|
||||
if (td->urb_length_set) {
|
||||
/* Don't overwrite a previously set error code
|
||||
*/
|
||||
if ((*status == -EINPROGRESS || *status == 0) &&
|
||||
@@ -1960,7 +1960,13 @@ static int process_ctrl_td(struct xhci_hcd *xhci, struct xhci_td *td,
|
||||
td->urb->transfer_buffer_length;
|
||||
}
|
||||
} else {
|
||||
/* Maybe the event was for the data stage? */
|
||||
/*
|
||||
* Maybe the event was for the data stage? If so, update
|
||||
* already the actual_length of the URB and flag it as
|
||||
* set, so that it is not overwritten in the event for
|
||||
* the last TRB.
|
||||
*/
|
||||
td->urb_length_set = true;
|
||||
td->urb->actual_length =
|
||||
td->urb->transfer_buffer_length -
|
||||
EVENT_TRB_LEN(le32_to_cpu(event->transfer_len));
|
||||
|
||||
+91
-9
@@ -1338,6 +1338,12 @@ int xhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flags)
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/* Reject urb if endpoint is in soft reset, queue must stay empty */
|
||||
if (xhci->devs[slot_id]->eps[ep_index].ep_state & EP_CONFIG_PENDING) {
|
||||
xhci_warn(xhci, "Can't enqueue URB while ep is in soft reset\n");
|
||||
ret = -EINVAL;
|
||||
}
|
||||
|
||||
if (usb_endpoint_xfer_isoc(&urb->ep->desc))
|
||||
size = urb->number_of_packets;
|
||||
else
|
||||
@@ -2948,23 +2954,36 @@ void xhci_cleanup_stalled_ring(struct xhci_hcd *xhci,
|
||||
}
|
||||
}
|
||||
|
||||
/* Called when clearing halted device. The core should have sent the control
|
||||
/* Called after clearing a halted device. USB core should have sent the control
|
||||
* message to clear the device halt condition. The host side of the halt should
|
||||
* already be cleared with a reset endpoint command issued when the STALL tx
|
||||
* event was received.
|
||||
*
|
||||
* Context: in_interrupt
|
||||
* already be cleared with a reset endpoint command issued immediately when the
|
||||
* STALL tx event was received.
|
||||
*/
|
||||
|
||||
void xhci_endpoint_reset(struct usb_hcd *hcd,
|
||||
struct usb_host_endpoint *ep)
|
||||
{
|
||||
struct xhci_hcd *xhci;
|
||||
struct usb_device *udev;
|
||||
struct xhci_virt_device *virt_dev;
|
||||
struct xhci_virt_ep *virt_ep;
|
||||
struct xhci_input_control_ctx *ctrl_ctx;
|
||||
struct xhci_command *command;
|
||||
unsigned int ep_index, ep_state;
|
||||
unsigned long flags;
|
||||
u32 ep_flag;
|
||||
|
||||
xhci = hcd_to_xhci(hcd);
|
||||
udev = (struct usb_device *) ep->hcpriv;
|
||||
if (!ep->hcpriv)
|
||||
return;
|
||||
virt_dev = xhci->devs[udev->slot_id];
|
||||
ep_index = xhci_get_endpoint_index(&ep->desc);
|
||||
virt_ep = &virt_dev->eps[ep_index];
|
||||
ep_state = virt_ep->ep_state;
|
||||
|
||||
/*
|
||||
* We might need to implement the config ep cmd in xhci 4.8.1 note:
|
||||
* Implement the config ep command in xhci 4.6.8 additional note:
|
||||
* The Reset Endpoint Command may only be issued to endpoints in the
|
||||
* Halted state. If software wishes reset the Data Toggle or Sequence
|
||||
* Number of an endpoint that isn't in the Halted state, then software
|
||||
@@ -2972,9 +2991,72 @@ void xhci_endpoint_reset(struct usb_hcd *hcd,
|
||||
* for the target endpoint. that is in the Stopped state.
|
||||
*/
|
||||
|
||||
/* For now just print debug to follow the situation */
|
||||
xhci_dbg(xhci, "Endpoint 0x%x ep reset callback called\n",
|
||||
ep->desc.bEndpointAddress);
|
||||
if (ep_state & SET_DEQ_PENDING || ep_state & EP_RECENTLY_HALTED) {
|
||||
virt_ep->ep_state &= ~EP_RECENTLY_HALTED;
|
||||
xhci_dbg(xhci, "ep recently halted, no toggle reset needed\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Only interrupt and bulk ep's use Data toggle, USB2 spec 5.5.4-> */
|
||||
if (usb_endpoint_xfer_control(&ep->desc) ||
|
||||
usb_endpoint_xfer_isoc(&ep->desc))
|
||||
return;
|
||||
|
||||
ep_flag = xhci_get_endpoint_flag(&ep->desc);
|
||||
|
||||
if (ep_flag == SLOT_FLAG || ep_flag == EP0_FLAG)
|
||||
return;
|
||||
|
||||
command = xhci_alloc_command(xhci, true, true, GFP_NOWAIT);
|
||||
if (!command) {
|
||||
xhci_err(xhci, "Could not allocate xHCI command structure.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
spin_lock_irqsave(&xhci->lock, flags);
|
||||
|
||||
/* block ringing ep doorbell */
|
||||
virt_ep->ep_state |= EP_CONFIG_PENDING;
|
||||
|
||||
/*
|
||||
* Make sure endpoint ring is empty before resetting the toggle/seq.
|
||||
* Driver is required to synchronously cancel all transfer request.
|
||||
*
|
||||
* xhci 4.6.6 says we can issue a configure endpoint command on a
|
||||
* running endpoint ring as long as it's idle (queue empty)
|
||||
*/
|
||||
|
||||
if (!list_empty(&virt_ep->ring->td_list)) {
|
||||
dev_err(&udev->dev, "EP not empty, refuse reset\n");
|
||||
spin_unlock_irqrestore(&xhci->lock, flags);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
xhci_dbg(xhci, "Reset toggle/seq for slot %d, ep_index: %d\n",
|
||||
udev->slot_id, ep_index);
|
||||
|
||||
ctrl_ctx = xhci_get_input_control_ctx(command->in_ctx);
|
||||
if (!ctrl_ctx) {
|
||||
xhci_err(xhci, "Could not get input context, bad type. virt_dev: %p, in_ctx %p\n",
|
||||
virt_dev, virt_dev->in_ctx);
|
||||
spin_unlock_irqrestore(&xhci->lock, flags);
|
||||
goto cleanup;
|
||||
}
|
||||
xhci_setup_input_ctx_for_config_ep(xhci, command->in_ctx,
|
||||
virt_dev->out_ctx, ctrl_ctx,
|
||||
ep_flag, ep_flag);
|
||||
xhci_endpoint_copy(xhci, command->in_ctx, virt_dev->out_ctx, ep_index);
|
||||
|
||||
xhci_queue_configure_endpoint(xhci, command, command->in_ctx->dma,
|
||||
udev->slot_id, false);
|
||||
xhci_ring_cmd_db(xhci);
|
||||
spin_unlock_irqrestore(&xhci->lock, flags);
|
||||
|
||||
wait_for_completion(command->completion);
|
||||
|
||||
cleanup:
|
||||
virt_ep->ep_state &= ~EP_CONFIG_PENDING;
|
||||
xhci_free_command(xhci, command);
|
||||
}
|
||||
|
||||
static int xhci_check_streams_endpoint(struct xhci_hcd *xhci,
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
|
||||
/*
|
||||
* xHCI host controller driver
|
||||
*
|
||||
@@ -88,9 +89,10 @@ struct xhci_cap_regs {
|
||||
#define HCS_IST(p) (((p) >> 0) & 0xf)
|
||||
/* bits 4:7, max number of Event Ring segments */
|
||||
#define HCS_ERST_MAX(p) (((p) >> 4) & 0xf)
|
||||
/* bits 21:25 Hi 5 bits of Scratchpad buffers SW must allocate for the HW */
|
||||
/* bit 26 Scratchpad restore - for save/restore HW state - not used yet */
|
||||
/* bits 27:31 number of Scratchpad buffers SW must allocate for the HW */
|
||||
#define HCS_MAX_SCRATCHPAD(p) (((p) >> 27) & 0x1f)
|
||||
/* bits 27:31 Lo 5 bits of Scratchpad buffers SW must allocate for the HW */
|
||||
#define HCS_MAX_SCRATCHPAD(p) ((((p) >> 16) & 0x3e0) | (((p) >> 27) & 0x1f))
|
||||
|
||||
/* HCSPARAMS3 - hcs_params3 - bitmasks */
|
||||
/* bits 0:7, Max U1 to U0 latency for the roothub ports */
|
||||
@@ -863,6 +865,8 @@ struct xhci_virt_ep {
|
||||
#define EP_HAS_STREAMS (1 << 4)
|
||||
/* Transitioning the endpoint to not using streams, don't enqueue URBs */
|
||||
#define EP_GETTING_NO_STREAMS (1 << 5)
|
||||
#define EP_RECENTLY_HALTED (1 << 6)
|
||||
#define EP_CONFIG_PENDING (1 << 7)
|
||||
/* ---- Related to URB cancellation ---- */
|
||||
struct list_head cancelled_td_list;
|
||||
struct xhci_td *stopped_td;
|
||||
@@ -1288,6 +1292,8 @@ struct xhci_td {
|
||||
struct xhci_segment *start_seg;
|
||||
union xhci_trb *first_trb;
|
||||
union xhci_trb *last_trb;
|
||||
/* actual_length of the URB has already been set */
|
||||
bool urb_length_set;
|
||||
};
|
||||
|
||||
/* xHCI command default timeout value */
|
||||
@@ -1560,6 +1566,7 @@ struct xhci_hcd {
|
||||
#define XHCI_SPURIOUS_WAKEUP (1 << 18)
|
||||
/* For controllers with a broken beyond repair streams implementation */
|
||||
#define XHCI_BROKEN_STREAMS (1 << 19)
|
||||
#define XHCI_PME_STUCK_QUIRK (1 << 20)
|
||||
unsigned int num_active_eps;
|
||||
unsigned int limit_active_eps;
|
||||
/* There are two roothubs to keep track of bus suspend info for */
|
||||
|
||||
@@ -1274,7 +1274,7 @@ static void errata2_function(unsigned long data)
|
||||
for (slot = 0; slot < 32; slot++)
|
||||
if (priv->atl_slots[slot].qh && time_after(jiffies,
|
||||
priv->atl_slots[slot].timestamp +
|
||||
SLOT_TIMEOUT * HZ / 1000)) {
|
||||
msecs_to_jiffies(SLOT_TIMEOUT))) {
|
||||
ptd_read(hcd->regs, ATL_PTD_OFFSET, slot, &ptd);
|
||||
if (!FROM_DW0_VALID(ptd.dw0) &&
|
||||
!FROM_DW3_ACTIVE(ptd.dw3))
|
||||
@@ -1286,7 +1286,7 @@ static void errata2_function(unsigned long data)
|
||||
|
||||
spin_unlock_irqrestore(&priv->lock, spinflags);
|
||||
|
||||
errata2_timer.expires = jiffies + SLOT_CHECK_PERIOD * HZ / 1000;
|
||||
errata2_timer.expires = jiffies + msecs_to_jiffies(SLOT_CHECK_PERIOD);
|
||||
add_timer(&errata2_timer);
|
||||
}
|
||||
|
||||
@@ -1336,7 +1336,7 @@ static int isp1760_run(struct usb_hcd *hcd)
|
||||
return retval;
|
||||
|
||||
setup_timer(&errata2_timer, errata2_function, (unsigned long)hcd);
|
||||
errata2_timer.expires = jiffies + SLOT_CHECK_PERIOD * HZ / 1000;
|
||||
errata2_timer.expires = jiffies + msecs_to_jiffies(SLOT_CHECK_PERIOD);
|
||||
add_timer(&errata2_timer);
|
||||
|
||||
chipid = reg_read32(hcd->regs, HC_CHIP_ID_REG);
|
||||
|
||||
@@ -1969,10 +1969,6 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl)
|
||||
goto fail0;
|
||||
}
|
||||
|
||||
pm_runtime_use_autosuspend(musb->controller);
|
||||
pm_runtime_set_autosuspend_delay(musb->controller, 200);
|
||||
pm_runtime_enable(musb->controller);
|
||||
|
||||
spin_lock_init(&musb->lock);
|
||||
musb->board_set_power = plat->set_power;
|
||||
musb->min_power = plat->min_power;
|
||||
@@ -1991,6 +1987,12 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl)
|
||||
musb_readl = musb_default_readl;
|
||||
musb_writel = musb_default_writel;
|
||||
|
||||
/* We need musb_read/write functions initialized for PM */
|
||||
pm_runtime_use_autosuspend(musb->controller);
|
||||
pm_runtime_set_autosuspend_delay(musb->controller, 200);
|
||||
pm_runtime_irq_safe(musb->controller);
|
||||
pm_runtime_enable(musb->controller);
|
||||
|
||||
/* The musb_platform_init() call:
|
||||
* - adjusts musb->mregs
|
||||
* - sets the musb->isr
|
||||
|
||||
@@ -457,12 +457,27 @@ static int dsps_musb_init(struct musb *musb)
|
||||
if (IS_ERR(musb->xceiv))
|
||||
return PTR_ERR(musb->xceiv);
|
||||
|
||||
musb->phy = devm_phy_get(dev->parent, "usb2-phy");
|
||||
|
||||
/* Returns zero if e.g. not clocked */
|
||||
rev = dsps_readl(reg_base, wrp->revision);
|
||||
if (!rev)
|
||||
return -ENODEV;
|
||||
|
||||
usb_phy_init(musb->xceiv);
|
||||
if (IS_ERR(musb->phy)) {
|
||||
musb->phy = NULL;
|
||||
} else {
|
||||
ret = phy_init(musb->phy);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
ret = phy_power_on(musb->phy);
|
||||
if (ret) {
|
||||
phy_exit(musb->phy);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
setup_timer(&glue->timer, otg_timer, (unsigned long) musb);
|
||||
|
||||
/* Reset the musb */
|
||||
@@ -502,6 +517,8 @@ static int dsps_musb_exit(struct musb *musb)
|
||||
|
||||
del_timer_sync(&glue->timer);
|
||||
usb_phy_shutdown(musb->xceiv);
|
||||
phy_power_off(musb->phy);
|
||||
phy_exit(musb->phy);
|
||||
debugfs_remove_recursive(glue->dbgfs_root);
|
||||
|
||||
return 0;
|
||||
@@ -610,7 +627,7 @@ static int dsps_musb_reset(struct musb *musb)
|
||||
struct device *dev = musb->controller;
|
||||
struct dsps_glue *glue = dev_get_drvdata(dev->parent);
|
||||
const struct dsps_musb_wrapper *wrp = glue->wrp;
|
||||
int session_restart = 0;
|
||||
int session_restart = 0, error;
|
||||
|
||||
if (glue->sw_babble_enabled)
|
||||
session_restart = sw_babble_control(musb);
|
||||
@@ -624,8 +641,14 @@ static int dsps_musb_reset(struct musb *musb)
|
||||
dsps_writel(musb->ctrl_base, wrp->control, (1 << wrp->reset));
|
||||
usleep_range(100, 200);
|
||||
usb_phy_shutdown(musb->xceiv);
|
||||
error = phy_power_off(musb->phy);
|
||||
if (error)
|
||||
dev_err(dev, "phy shutdown failed: %i\n", error);
|
||||
usleep_range(100, 200);
|
||||
usb_phy_init(musb->xceiv);
|
||||
error = phy_power_on(musb->phy);
|
||||
if (error)
|
||||
dev_err(dev, "phy powerup failed: %i\n", error);
|
||||
session_restart = 1;
|
||||
}
|
||||
|
||||
@@ -687,7 +710,7 @@ static int dsps_create_musb_pdev(struct dsps_glue *glue,
|
||||
struct musb_hdrc_config *config;
|
||||
struct platform_device *musb;
|
||||
struct device_node *dn = parent->dev.of_node;
|
||||
int ret;
|
||||
int ret, val;
|
||||
|
||||
memset(resources, 0, sizeof(resources));
|
||||
res = platform_get_resource_byname(parent, IORESOURCE_MEM, "mc");
|
||||
@@ -739,7 +762,10 @@ static int dsps_create_musb_pdev(struct dsps_glue *glue,
|
||||
pdata.mode = get_musb_port_mode(dev);
|
||||
/* DT keeps this entry in mA, musb expects it as per USB spec */
|
||||
pdata.power = get_int_prop(dn, "mentor,power") / 2;
|
||||
config->multipoint = of_property_read_bool(dn, "mentor,multipoint");
|
||||
|
||||
ret = of_property_read_u32(dn, "mentor,multipoint", &val);
|
||||
if (!ret && val)
|
||||
config->multipoint = true;
|
||||
|
||||
ret = platform_device_add_data(musb, &pdata, sizeof(pdata));
|
||||
if (ret) {
|
||||
|
||||
@@ -2613,7 +2613,7 @@ static const struct hc_driver musb_hc_driver = {
|
||||
.description = "musb-hcd",
|
||||
.product_desc = "MUSB HDRC host driver",
|
||||
.hcd_priv_size = sizeof(struct musb *),
|
||||
.flags = HCD_USB2 | HCD_MEMORY,
|
||||
.flags = HCD_USB2 | HCD_MEMORY | HCD_BH,
|
||||
|
||||
/* not using irq handler or reset hooks from usbcore, since
|
||||
* those must be shared with peripheral code for OTG configs
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user