lkml.org 
[lkml]   [2016]   [Mar]   [7]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 4.2.y-ckt 083/273] usb: xhci: add a quirk bit for ssic port unused
    Date
    4.2.8-ckt5 -stable review patch.  If anyone has any objections, please let me know.

    ---8<------------------------------------------------------------

    From: Lu Baolu <baolu.lu@linux.intel.com>

    commit 7e70cbffe236721051bbaff965e477df06dcb190 upstream.

    Two workarounds introduced by commit b8cb91e058cd ("xhci: Workaround
    for PME stuck issues in Intel xhci") and commit abce329c27b3 ("xhci:
    Workaround to get D3 working in Intel xHCI") share a single quirk bit
    XHCI_PME_STUCK_QUIRK. These two workarounds actually are different and
    might happen on different hardwares. Need to separate them by adding a
    quirk bit for the later.

    Signed-off-by: Lu Baolu <baolu.lu@linux.intel.com>
    Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
    Signed-off-by: Kamal Mostafa <kamal@canonical.com>
    ---
    drivers/usb/host/xhci-pci.c | 79 ++++++++++++++++++++++++++-------------------
    drivers/usb/host/xhci.h | 1 +
    2 files changed, 46 insertions(+), 34 deletions(-)

    diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c
    index fda3c5c..87f33a5 100644
    --- a/drivers/usb/host/xhci-pci.c
    +++ b/drivers/usb/host/xhci-pci.c
    @@ -157,6 +157,10 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci)
    pdev->device == PCI_DEVICE_ID_INTEL_CHERRYVIEW_XHCI)) {
    xhci->quirks |= XHCI_PME_STUCK_QUIRK;
    }
    + if (pdev->vendor == PCI_VENDOR_ID_INTEL &&
    + pdev->device == PCI_DEVICE_ID_INTEL_CHERRYVIEW_XHCI) {
    + xhci->quirks |= XHCI_SSIC_PORT_UNUSED;
    + }
    if (pdev->vendor == PCI_VENDOR_ID_ETRON &&
    pdev->device == PCI_DEVICE_ID_EJ168) {
    xhci->quirks |= XHCI_RESET_ON_RESUME;
    @@ -313,46 +317,47 @@ static void xhci_pci_remove(struct pci_dev *dev)
    * SSIC PORT need to be marked as "unused" before putting xHCI
    * into D3. After D3 exit, the SSIC port need to be marked as "used".
    * Without this change, xHCI might not enter D3 state.
    - * 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 usb_hcd *hcd, bool suspend)
    +static void xhci_ssic_port_unused_quirk(struct usb_hcd *hcd, bool suspend)
    {
    struct xhci_hcd *xhci = hcd_to_xhci(hcd);
    - struct pci_dev *pdev = to_pci_dev(hcd->self.controller);
    u32 val;
    void __iomem *reg;
    int i;

    - if (pdev->vendor == PCI_VENDOR_ID_INTEL &&
    - pdev->device == PCI_DEVICE_ID_INTEL_CHERRYVIEW_XHCI) {
    -
    - for (i = 0; i < SSIC_PORT_NUM; i++) {
    - reg = (void __iomem *) xhci->cap_regs +
    - SSIC_PORT_CFG2 +
    - i * SSIC_PORT_CFG2_OFFSET;
    -
    - /*
    - * Notify SSIC that SSIC profile programming
    - * is not done.
    - */
    - val = readl(reg) & ~PROG_DONE;
    - writel(val, reg);
    -
    - /* Mark SSIC port as unused(suspend) or used(resume) */
    - val = readl(reg);
    - if (suspend)
    - val |= SSIC_PORT_UNUSED;
    - else
    - val &= ~SSIC_PORT_UNUSED;
    - writel(val, reg);
    -
    - /* Notify SSIC that SSIC profile programming is done */
    - val = readl(reg) | PROG_DONE;
    - writel(val, reg);
    - readl(reg);
    - }
    + for (i = 0; i < SSIC_PORT_NUM; i++) {
    + reg = (void __iomem *) xhci->cap_regs +
    + SSIC_PORT_CFG2 +
    + i * SSIC_PORT_CFG2_OFFSET;
    +
    + /* Notify SSIC that SSIC profile programming is not done. */
    + val = readl(reg) & ~PROG_DONE;
    + writel(val, reg);
    +
    + /* Mark SSIC port as unused(suspend) or used(resume) */
    + val = readl(reg);
    + if (suspend)
    + val |= SSIC_PORT_UNUSED;
    + else
    + val &= ~SSIC_PORT_UNUSED;
    + writel(val, reg);
    +
    + /* Notify SSIC that SSIC profile programming is done */
    + val = readl(reg) | PROG_DONE;
    + writel(val, reg);
    + readl(reg);
    }
    +}
    +
    +/*
    + * 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 usb_hcd *hcd)
    +{
    + struct xhci_hcd *xhci = hcd_to_xhci(hcd);
    + void __iomem *reg;
    + u32 val;

    reg = (void __iomem *) xhci->cap_regs + 0x80a4;
    val = readl(reg);
    @@ -373,7 +378,10 @@ static int xhci_pci_suspend(struct usb_hcd *hcd, bool do_wakeup)
    pdev->no_d3cold = true;

    if (xhci->quirks & XHCI_PME_STUCK_QUIRK)
    - xhci_pme_quirk(hcd, true);
    + xhci_pme_quirk(hcd);
    +
    + if (xhci->quirks & XHCI_SSIC_PORT_UNUSED)
    + xhci_ssic_port_unused_quirk(hcd, true);

    return xhci_suspend(xhci, do_wakeup);
    }
    @@ -405,8 +413,11 @@ 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_SSIC_PORT_UNUSED)
    + xhci_ssic_port_unused_quirk(hcd, false);
    +
    if (xhci->quirks & XHCI_PME_STUCK_QUIRK)
    - xhci_pme_quirk(hcd, false);
    + xhci_pme_quirk(hcd);

    retval = xhci_resume(xhci, hibernated);
    return retval;
    diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
    index ed2ebf6..d77ce5f 100644
    --- a/drivers/usb/host/xhci.h
    +++ b/drivers/usb/host/xhci.h
    @@ -1568,6 +1568,7 @@ struct xhci_hcd {
    /* For controllers with a broken beyond repair streams implementation */
    #define XHCI_BROKEN_STREAMS (1 << 19)
    #define XHCI_PME_STUCK_QUIRK (1 << 20)
    +#define XHCI_SSIC_PORT_UNUSED (1 << 22)
    unsigned int num_active_eps;
    unsigned int limit_active_eps;
    /* There are two roothubs to keep track of bus suspend info for */
    --
    2.7.0
    \
     
     \ /
      Last update: 2016-03-08 02:21    [W:6.154 / U:1.908 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site