Skip to content

Commit

Permalink
Merge tag 'usb-3.12-rc6' of git://git.kernel.org/pub/scm/linux/kernel…
Browse files Browse the repository at this point in the history
…/git/gregkh/usb

Pull USB fixes from Greg KH:
 "Here are some USB fixes and new device ids for 3.12-rc6

  The largest change here is a bunch of new device ids for the option
  USB serial driver for new Huawei devices.  Other than that, just some
  small bug fixes for issues that people have reported (run-time and
  build-time), nothing major"

* tag 'usb-3.12-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb:
  usb: usb_phy_gen: refine conditional declaration of usb_nop_xceiv_register
  usb: misc: usb3503: Fix compile error due to incorrect regmap depedency
  usb/chipidea: fix oops on memory allocation failure
  usb-storage: add quirk for mandatory READ_CAPACITY_16
  usb: serial: option: blacklist Olivetti Olicard200
  USB: quirks: add touchscreen that is dazzeled by remote wakeup
  Revert "usb: musb: gadget: fix otg active status flag"
  USB: quirks.c: add one device that cannot deal with suspension
  USB: serial: option: add support for Inovia SEW858 device
  USB: serial: ti_usb_3410_5052: add Abbott strip port ID to combined table as well.
  USB: support new huawei devices in option.c
  usb: musb: start musb on the udc side, too
  xhci: Fix spurious wakeups after S5 on Haswell
  xhci: fix write to USB3_PSSEN and XUSB2PRM pci config registers
  xhci: quirk for extra long delay for S4
  xhci: Don't enable/disable RWE on bus suspend/resume.
  • Loading branch information
Linus Torvalds committed Oct 17, 2013
2 parents 7b4a515 + 9446878 commit 02a3250
Show file tree
Hide file tree
Showing 18 changed files with 343 additions and 82 deletions.
6 changes: 4 additions & 2 deletions drivers/usb/chipidea/host.c
Original file line number Diff line number Diff line change
Expand Up @@ -100,8 +100,10 @@ static void host_stop(struct ci_hdrc *ci)
{
struct usb_hcd *hcd = ci->hcd;

usb_remove_hcd(hcd);
usb_put_hcd(hcd);
if (hcd) {
usb_remove_hcd(hcd);
usb_put_hcd(hcd);
}
if (ci->platdata->reg_vbus)
regulator_disable(ci->platdata->reg_vbus);
}
Expand Down
6 changes: 6 additions & 0 deletions drivers/usb/core/quirks.c
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,9 @@ static const struct usb_device_id usb_quirk_list[] = {
/* Alcor Micro Corp. Hub */
{ USB_DEVICE(0x058f, 0x9254), .driver_info = USB_QUIRK_RESET_RESUME },

/* MicroTouch Systems touchscreen */
{ USB_DEVICE(0x0596, 0x051e), .driver_info = USB_QUIRK_RESET_RESUME },

/* appletouch */
{ USB_DEVICE(0x05ac, 0x021a), .driver_info = USB_QUIRK_RESET_RESUME },

Expand Down Expand Up @@ -130,6 +133,9 @@ static const struct usb_device_id usb_quirk_list[] = {
/* Broadcom BCM92035DGROM BT dongle */
{ USB_DEVICE(0x0a5c, 0x2021), .driver_info = USB_QUIRK_RESET_RESUME },

/* MAYA44USB sound device */
{ USB_DEVICE(0x0a92, 0x0091), .driver_info = USB_QUIRK_RESET_RESUME },

/* Action Semiconductor flash disk */
{ USB_DEVICE(0x10d6, 0x2200), .driver_info =
USB_QUIRK_STRING_FETCH_255 },
Expand Down
4 changes: 2 additions & 2 deletions drivers/usb/host/pci-quirks.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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);
Expand Down
26 changes: 0 additions & 26 deletions drivers/usb/host/xhci-hub.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down
25 changes: 25 additions & 0 deletions drivers/usb/host/xhci-pci.c
Original file line number Diff line number Diff line change
Expand Up @@ -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" */
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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);
}

Expand Down
14 changes: 13 additions & 1 deletion drivers/usb/host/xhci.c
Original file line number Diff line number Diff line change
Expand Up @@ -730,13 +730,20 @@ 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);

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
Expand Down Expand Up @@ -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;

Expand All @@ -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;
Expand Down
2 changes: 2 additions & 0 deletions drivers/usb/host/xhci.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down
2 changes: 1 addition & 1 deletion drivers/usb/misc/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,6 @@ config USB_EZUSB_FX2
config USB_HSIC_USB3503
tristate "USB3503 HSIC to USB20 Driver"
depends on I2C
select REGMAP
select REGMAP_I2C
help
This option enables support for SMSC USB3503 HSIC to USB 2.0 Driver.
46 changes: 46 additions & 0 deletions drivers/usb/musb/musb_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -921,6 +921,52 @@ static void musb_generic_disable(struct musb *musb)

}

/*
* Program the HDRC to start (enable interrupts, dma, etc.).
*/
void musb_start(struct musb *musb)
{
void __iomem *regs = musb->mregs;
u8 devctl = musb_readb(regs, MUSB_DEVCTL);

dev_dbg(musb->controller, "<== devctl %02x\n", devctl);

/* Set INT enable registers, enable interrupts */
musb->intrtxe = musb->epmask;
musb_writew(regs, MUSB_INTRTXE, musb->intrtxe);
musb->intrrxe = musb->epmask & 0xfffe;
musb_writew(regs, MUSB_INTRRXE, musb->intrrxe);
musb_writeb(regs, MUSB_INTRUSBE, 0xf7);

musb_writeb(regs, MUSB_TESTMODE, 0);

/* put into basic highspeed mode and start session */
musb_writeb(regs, MUSB_POWER, MUSB_POWER_ISOUPDATE
| MUSB_POWER_HSENAB
/* ENSUSPEND wedges tusb */
/* | MUSB_POWER_ENSUSPEND */
);

musb->is_active = 0;
devctl = musb_readb(regs, MUSB_DEVCTL);
devctl &= ~MUSB_DEVCTL_SESSION;

/* session started after:
* (a) ID-grounded irq, host mode;
* (b) vbus present/connect IRQ, peripheral mode;
* (c) peripheral initiates, using SRP
*/
if (musb->port_mode != MUSB_PORT_MODE_HOST &&
(devctl & MUSB_DEVCTL_VBUS) == MUSB_DEVCTL_VBUS) {
musb->is_active = 1;
} else {
devctl |= MUSB_DEVCTL_SESSION;
}

musb_platform_enable(musb);
musb_writeb(regs, MUSB_DEVCTL, devctl);
}

/*
* Make the HDRC stop (disable interrupts, etc.);
* reversible by musb_start
Expand Down
1 change: 1 addition & 0 deletions drivers/usb/musb/musb_core.h
Original file line number Diff line number Diff line change
Expand Up @@ -503,6 +503,7 @@ static inline void musb_configure_ep0(struct musb *musb)
extern const char musb_driver_name[];

extern void musb_stop(struct musb *musb);
extern void musb_start(struct musb *musb);

extern void musb_write_fifo(struct musb_hw_ep *ep, u16 len, const u8 *src);
extern void musb_read_fifo(struct musb_hw_ep *ep, u16 len, u8 *dst);
Expand Down
3 changes: 3 additions & 0 deletions drivers/usb/musb/musb_gadget.c
Original file line number Diff line number Diff line change
Expand Up @@ -1853,11 +1853,14 @@ static int musb_gadget_start(struct usb_gadget *g,
musb->gadget_driver = driver;

spin_lock_irqsave(&musb->lock, flags);
musb->is_active = 1;

otg_set_peripheral(otg, &musb->g);
musb->xceiv->state = OTG_STATE_B_IDLE;
spin_unlock_irqrestore(&musb->lock, flags);

musb_start(musb);

/* REVISIT: funcall to other code, which also
* handles power budgeting ... this way also
* ensures HdrcStart is indirectly called.
Expand Down
46 changes: 0 additions & 46 deletions drivers/usb/musb/musb_virthub.c
Original file line number Diff line number Diff line change
Expand Up @@ -44,52 +44,6 @@

#include "musb_core.h"

/*
* Program the HDRC to start (enable interrupts, dma, etc.).
*/
static void musb_start(struct musb *musb)
{
void __iomem *regs = musb->mregs;
u8 devctl = musb_readb(regs, MUSB_DEVCTL);

dev_dbg(musb->controller, "<== devctl %02x\n", devctl);

/* Set INT enable registers, enable interrupts */
musb->intrtxe = musb->epmask;
musb_writew(regs, MUSB_INTRTXE, musb->intrtxe);
musb->intrrxe = musb->epmask & 0xfffe;
musb_writew(regs, MUSB_INTRRXE, musb->intrrxe);
musb_writeb(regs, MUSB_INTRUSBE, 0xf7);

musb_writeb(regs, MUSB_TESTMODE, 0);

/* put into basic highspeed mode and start session */
musb_writeb(regs, MUSB_POWER, MUSB_POWER_ISOUPDATE
| MUSB_POWER_HSENAB
/* ENSUSPEND wedges tusb */
/* | MUSB_POWER_ENSUSPEND */
);

musb->is_active = 0;
devctl = musb_readb(regs, MUSB_DEVCTL);
devctl &= ~MUSB_DEVCTL_SESSION;

/* session started after:
* (a) ID-grounded irq, host mode;
* (b) vbus present/connect IRQ, peripheral mode;
* (c) peripheral initiates, using SRP
*/
if (musb->port_mode != MUSB_PORT_MODE_HOST &&
(devctl & MUSB_DEVCTL_VBUS) == MUSB_DEVCTL_VBUS) {
musb->is_active = 1;
} else {
devctl |= MUSB_DEVCTL_SESSION;
}

musb_platform_enable(musb);
musb_writeb(regs, MUSB_DEVCTL, devctl);
}

static void musb_port_suspend(struct musb *musb, bool do_suspend)
{
struct usb_otg *otg = musb->xceiv->otg;
Expand Down
Loading

0 comments on commit 02a3250

Please sign in to comment.