xhci: Bug fixes and quirks for 3.12
Hi Greg, Here's four patches for 3.12. The first patch is a bug fix for the USB 2.0 Link PM registers that I sent out to the list a long time ago (August), but forgot to queue up. The second and fourth patches are quirks for xHCI hosts. These patches are marked for stable. The third patch fixes a bug uncovered with sparse. Sarah Sharp -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.11 (GNU/Linux) iQIcBAABAgAGBQJSVedBAAoJEBMGWMLi1Gc56NwP/RHNqTr08qcYdGFANtXXzJz7 ztZaHePXgd/G1Xx0NihjEsqakbY30RmXBqvqdaEYI2nl6B0LnbKe8n3ihBqnwyHp N3v9d9zA3uUZwN9vep3/wL7aulwhE2kldyfaofo4cVCbICtP88YLdjdpWtRl/Jxs bqu9tO3QCwokZfOQgZTnWUMUVtz1bt2EV3eXJNh+2SZVqLwr4FxUfqkW6OZ+6Dmr 6Lu7crD8AAygKEqOeGJHZTkfZ3vX8P0Ne9p+YQqrdSRV+D9As7kppcRwr5Ehh3hI pkSiu1rx7FBBp94pLy/573R9KOdzBcUB/B0mP5nbBGytCNRtP7dOS+dMN1kZr/7+ BbXY5p9BEdTNJJKy72P+4MngdLj6EtLewBXyYIIzdD6Yem/OZrrp6h7huakdsCrT fbYscLy2fP1HVjfJ9adnV77DAWOUsOFNId68YbQoAGjSRRulKMPP7piMDBKqfCPW HyOgjeTk+E2M38xhJm2fTYXc0uhC/dH/xMObHWxC0OGZ3g8miQm6uoeSAsWTQpfS UOPJFcd7pkYOIs9KWtmOwKVIeozkicScrl58JoLzsUVenDrXhfmQN1rbh2wSAl/0 JDT8qIlMwG9BTDyQJBXQCbK/3Z4JLv5IcmZiGzI1b3UI7pP8J7R7mmtqHzduDVFS WqJOSyZM9xEk2WYFFtzx =4Y1d -----END PGP SIGNATURE----- Merge tag 'for-usb-linus-2013-10-09' of git://git.kernel.org/pub/scm/linux/kernel/git/sarah/xhci into usb-linus Pull xhci USB fixes from Sarah: xhci: Bug fixes and quirks for 3.12 Hi Greg, Here's four patches for 3.12. The first patch is a bug fix for the USB 2.0 Link PM registers that I sent out to the list a long time ago (August), but forgot to queue up. The second and fourth patches are quirks for xHCI hosts. These patches are marked for stable. The third patch fixes a bug uncovered with sparse. Sarah Sharp
This commit is contained in:
Коммит
625816a430
|
@ -799,7 +799,7 @@ void usb_enable_intel_xhci_ports(struct pci_dev *xhci_pdev)
|
|||
* switchable ports.
|
||||
*/
|
||||
pci_write_config_dword(xhci_pdev, USB_INTEL_USB3_PSSEN,
|
||||
cpu_to_le32(ports_available));
|
||||
ports_available);
|
||||
|
||||
pci_read_config_dword(xhci_pdev, USB_INTEL_USB3_PSSEN,
|
||||
&ports_available);
|
||||
|
@ -821,7 +821,7 @@ void usb_enable_intel_xhci_ports(struct pci_dev *xhci_pdev)
|
|||
* host.
|
||||
*/
|
||||
pci_write_config_dword(xhci_pdev, USB_INTEL_XUSB2PR,
|
||||
cpu_to_le32(ports_available));
|
||||
ports_available);
|
||||
|
||||
pci_read_config_dword(xhci_pdev, USB_INTEL_XUSB2PR,
|
||||
&ports_available);
|
||||
|
|
|
@ -1157,18 +1157,6 @@ int xhci_bus_suspend(struct usb_hcd *hcd)
|
|||
t1 = xhci_port_state_to_neutral(t1);
|
||||
if (t1 != t2)
|
||||
xhci_writel(xhci, t2, port_array[port_index]);
|
||||
|
||||
if (hcd->speed != HCD_USB3) {
|
||||
/* enable remote wake up for USB 2.0 */
|
||||
__le32 __iomem *addr;
|
||||
u32 tmp;
|
||||
|
||||
/* Get the port power control register address. */
|
||||
addr = port_array[port_index] + PORTPMSC;
|
||||
tmp = xhci_readl(xhci, addr);
|
||||
tmp |= PORT_RWE;
|
||||
xhci_writel(xhci, tmp, addr);
|
||||
}
|
||||
}
|
||||
hcd->state = HC_STATE_SUSPENDED;
|
||||
bus_state->next_statechange = jiffies + msecs_to_jiffies(10);
|
||||
|
@ -1247,20 +1235,6 @@ int xhci_bus_resume(struct usb_hcd *hcd)
|
|||
xhci_ring_device(xhci, slot_id);
|
||||
} else
|
||||
xhci_writel(xhci, temp, port_array[port_index]);
|
||||
|
||||
if (hcd->speed != HCD_USB3) {
|
||||
/* disable remote wake up for USB 2.0 */
|
||||
__le32 __iomem *addr;
|
||||
u32 tmp;
|
||||
|
||||
/* Add one to the port status register address to get
|
||||
* the port power control register address.
|
||||
*/
|
||||
addr = port_array[port_index] + PORTPMSC;
|
||||
tmp = xhci_readl(xhci, addr);
|
||||
tmp &= ~PORT_RWE;
|
||||
xhci_writel(xhci, tmp, addr);
|
||||
}
|
||||
}
|
||||
|
||||
(void) xhci_readl(xhci, &xhci->op_regs->command);
|
||||
|
|
|
@ -35,6 +35,9 @@
|
|||
#define PCI_VENDOR_ID_ETRON 0x1b6f
|
||||
#define PCI_DEVICE_ID_ASROCK_P67 0x7023
|
||||
|
||||
#define PCI_DEVICE_ID_INTEL_LYNXPOINT_XHCI 0x8c31
|
||||
#define PCI_DEVICE_ID_INTEL_LYNXPOINT_LP_XHCI 0x9c31
|
||||
|
||||
static const char hcd_name[] = "xhci_hcd";
|
||||
|
||||
/* called after powerup, by probe or system-pm "wakeup" */
|
||||
|
@ -69,6 +72,14 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci)
|
|||
"QUIRK: Fresco Logic xHC needs configure"
|
||||
" endpoint cmd after reset endpoint");
|
||||
}
|
||||
if (pdev->device == PCI_DEVICE_ID_FRESCO_LOGIC_PDK &&
|
||||
pdev->revision == 0x4) {
|
||||
xhci->quirks |= XHCI_SLOW_SUSPEND;
|
||||
xhci_dbg_trace(xhci, trace_xhci_dbg_quirks,
|
||||
"QUIRK: Fresco Logic xHC revision %u"
|
||||
"must be suspended extra slowly",
|
||||
pdev->revision);
|
||||
}
|
||||
/* Fresco Logic confirms: all revisions of this chip do not
|
||||
* support MSI, even though some of them claim to in their PCI
|
||||
* capabilities.
|
||||
|
@ -110,6 +121,15 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci)
|
|||
xhci->quirks |= XHCI_SPURIOUS_REBOOT;
|
||||
xhci->quirks |= XHCI_AVOID_BEI;
|
||||
}
|
||||
if (pdev->vendor == PCI_VENDOR_ID_INTEL &&
|
||||
(pdev->device == PCI_DEVICE_ID_INTEL_LYNXPOINT_XHCI ||
|
||||
pdev->device == PCI_DEVICE_ID_INTEL_LYNXPOINT_LP_XHCI)) {
|
||||
/* Workaround for occasional spurious wakeups from S5 (or
|
||||
* any other sleep) on Haswell machines with LPT and LPT-LP
|
||||
* with the new Intel BIOS
|
||||
*/
|
||||
xhci->quirks |= XHCI_SPURIOUS_WAKEUP;
|
||||
}
|
||||
if (pdev->vendor == PCI_VENDOR_ID_ETRON &&
|
||||
pdev->device == PCI_DEVICE_ID_ASROCK_P67) {
|
||||
xhci->quirks |= XHCI_RESET_ON_RESUME;
|
||||
|
@ -217,6 +237,11 @@ static void xhci_pci_remove(struct pci_dev *dev)
|
|||
usb_put_hcd(xhci->shared_hcd);
|
||||
}
|
||||
usb_hcd_pci_remove(dev);
|
||||
|
||||
/* Workaround for spurious wakeups at shutdown with HSW */
|
||||
if (xhci->quirks & XHCI_SPURIOUS_WAKEUP)
|
||||
pci_set_power_state(dev, PCI_D3hot);
|
||||
|
||||
kfree(xhci);
|
||||
}
|
||||
|
||||
|
|
|
@ -730,6 +730,9 @@ void xhci_shutdown(struct usb_hcd *hcd)
|
|||
|
||||
spin_lock_irq(&xhci->lock);
|
||||
xhci_halt(xhci);
|
||||
/* Workaround for spurious wakeups at shutdown with HSW */
|
||||
if (xhci->quirks & XHCI_SPURIOUS_WAKEUP)
|
||||
xhci_reset(xhci);
|
||||
spin_unlock_irq(&xhci->lock);
|
||||
|
||||
xhci_cleanup_msix(xhci);
|
||||
|
@ -737,6 +740,10 @@ void xhci_shutdown(struct usb_hcd *hcd)
|
|||
xhci_dbg_trace(xhci, trace_xhci_dbg_init,
|
||||
"xhci_shutdown completed - status = %x",
|
||||
xhci_readl(xhci, &xhci->op_regs->status));
|
||||
|
||||
/* Yet another workaround for spurious wakeups at shutdown with HSW */
|
||||
if (xhci->quirks & XHCI_SPURIOUS_WAKEUP)
|
||||
pci_set_power_state(to_pci_dev(hcd->self.controller), PCI_D3hot);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
|
@ -839,6 +846,7 @@ static void xhci_clear_command_ring(struct xhci_hcd *xhci)
|
|||
int xhci_suspend(struct xhci_hcd *xhci)
|
||||
{
|
||||
int rc = 0;
|
||||
unsigned int delay = XHCI_MAX_HALT_USEC;
|
||||
struct usb_hcd *hcd = xhci_to_hcd(xhci);
|
||||
u32 command;
|
||||
|
||||
|
@ -861,8 +869,12 @@ int xhci_suspend(struct xhci_hcd *xhci)
|
|||
command = xhci_readl(xhci, &xhci->op_regs->command);
|
||||
command &= ~CMD_RUN;
|
||||
xhci_writel(xhci, command, &xhci->op_regs->command);
|
||||
|
||||
/* Some chips from Fresco Logic need an extraordinary delay */
|
||||
delay *= (xhci->quirks & XHCI_SLOW_SUSPEND) ? 10 : 1;
|
||||
|
||||
if (xhci_handshake(xhci, &xhci->op_regs->status,
|
||||
STS_HALT, STS_HALT, XHCI_MAX_HALT_USEC)) {
|
||||
STS_HALT, STS_HALT, delay)) {
|
||||
xhci_warn(xhci, "WARN: xHC CMD_RUN timeout\n");
|
||||
spin_unlock_irq(&xhci->lock);
|
||||
return -ETIMEDOUT;
|
||||
|
|
|
@ -1548,6 +1548,8 @@ struct xhci_hcd {
|
|||
#define XHCI_COMP_MODE_QUIRK (1 << 14)
|
||||
#define XHCI_AVOID_BEI (1 << 15)
|
||||
#define XHCI_PLAT (1 << 16)
|
||||
#define XHCI_SLOW_SUSPEND (1 << 17)
|
||||
#define XHCI_SPURIOUS_WAKEUP (1 << 18)
|
||||
unsigned int num_active_eps;
|
||||
unsigned int limit_active_eps;
|
||||
/* There are two roothubs to keep track of bus suspend info for */
|
||||
|
|
Загрузка…
Ссылка в новой задаче