Commit aa05cfa9 authored by Greg Kroah-Hartman's avatar Greg Kroah-Hartman

Merge tag 'fixes-for-v4.4-rc2' of...

Merge tag 'fixes-for-v4.4-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/balbi/usb into usb-linus

Felipe writes:

usb: fixes for v4.4-rc2

First round of fixes for this -rc cycle. We have the
usual set of miscellaneous fixes. The important
thing here is support for Intel Broxton SoC on dwc3,
some fixes for Rockchip SoCs on dwc2 and a fix on
dwc3 to let it report lower speeds than
USB_SPEED_SUPER.
parents 8005c49d d134c48d
...@@ -324,12 +324,13 @@ void dwc2_hcd_disconnect(struct dwc2_hsotg *hsotg) ...@@ -324,12 +324,13 @@ void dwc2_hcd_disconnect(struct dwc2_hsotg *hsotg)
*/ */
static void dwc2_hcd_rem_wakeup(struct dwc2_hsotg *hsotg) static void dwc2_hcd_rem_wakeup(struct dwc2_hsotg *hsotg)
{ {
if (hsotg->lx_state == DWC2_L2) { if (hsotg->bus_suspended) {
hsotg->flags.b.port_suspend_change = 1; hsotg->flags.b.port_suspend_change = 1;
usb_hcd_resume_root_hub(hsotg->priv); usb_hcd_resume_root_hub(hsotg->priv);
} else {
hsotg->flags.b.port_l1_change = 1;
} }
if (hsotg->lx_state == DWC2_L1)
hsotg->flags.b.port_l1_change = 1;
} }
/** /**
...@@ -1428,8 +1429,8 @@ static void dwc2_wakeup_detected(unsigned long data) ...@@ -1428,8 +1429,8 @@ static void dwc2_wakeup_detected(unsigned long data)
dev_dbg(hsotg->dev, "Clear Resume: HPRT0=%0x\n", dev_dbg(hsotg->dev, "Clear Resume: HPRT0=%0x\n",
dwc2_readl(hsotg->regs + HPRT0)); dwc2_readl(hsotg->regs + HPRT0));
hsotg->bus_suspended = 0;
dwc2_hcd_rem_wakeup(hsotg); dwc2_hcd_rem_wakeup(hsotg);
hsotg->bus_suspended = 0;
/* Change to L0 state */ /* Change to L0 state */
hsotg->lx_state = DWC2_L0; hsotg->lx_state = DWC2_L0;
......
...@@ -108,7 +108,8 @@ static const struct dwc2_core_params params_rk3066 = { ...@@ -108,7 +108,8 @@ static const struct dwc2_core_params params_rk3066 = {
.host_ls_low_power_phy_clk = -1, .host_ls_low_power_phy_clk = -1,
.ts_dline = -1, .ts_dline = -1,
.reload_ctl = -1, .reload_ctl = -1,
.ahbcfg = 0x7, /* INCR16 */ .ahbcfg = GAHBCFG_HBSTLEN_INCR16 <<
GAHBCFG_HBSTLEN_SHIFT,
.uframe_sched = -1, .uframe_sched = -1,
.external_id_pin_ctl = -1, .external_id_pin_ctl = -1,
.hibernation = -1, .hibernation = -1,
......
...@@ -34,6 +34,8 @@ ...@@ -34,6 +34,8 @@
#define PCI_DEVICE_ID_INTEL_BSW 0x22b7 #define PCI_DEVICE_ID_INTEL_BSW 0x22b7
#define PCI_DEVICE_ID_INTEL_SPTLP 0x9d30 #define PCI_DEVICE_ID_INTEL_SPTLP 0x9d30
#define PCI_DEVICE_ID_INTEL_SPTH 0xa130 #define PCI_DEVICE_ID_INTEL_SPTH 0xa130
#define PCI_DEVICE_ID_INTEL_BXT 0x0aaa
#define PCI_DEVICE_ID_INTEL_APL 0x5aaa
static const struct acpi_gpio_params reset_gpios = { 0, 0, false }; static const struct acpi_gpio_params reset_gpios = { 0, 0, false };
static const struct acpi_gpio_params cs_gpios = { 1, 0, false }; static const struct acpi_gpio_params cs_gpios = { 1, 0, false };
...@@ -210,6 +212,8 @@ static const struct pci_device_id dwc3_pci_id_table[] = { ...@@ -210,6 +212,8 @@ static const struct pci_device_id dwc3_pci_id_table[] = {
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_MRFLD), }, { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_MRFLD), },
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_SPTLP), }, { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_SPTLP), },
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_SPTH), }, { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_SPTH), },
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_BXT), },
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_APL), },
{ 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 */
}; };
......
...@@ -2744,11 +2744,33 @@ int dwc3_gadget_init(struct dwc3 *dwc) ...@@ -2744,11 +2744,33 @@ int dwc3_gadget_init(struct dwc3 *dwc)
} }
dwc->gadget.ops = &dwc3_gadget_ops; dwc->gadget.ops = &dwc3_gadget_ops;
dwc->gadget.max_speed = USB_SPEED_SUPER;
dwc->gadget.speed = USB_SPEED_UNKNOWN; dwc->gadget.speed = USB_SPEED_UNKNOWN;
dwc->gadget.sg_supported = true; dwc->gadget.sg_supported = true;
dwc->gadget.name = "dwc3-gadget"; dwc->gadget.name = "dwc3-gadget";
/*
* FIXME We might be setting max_speed to <SUPER, however versions
* <2.20a of dwc3 have an issue with metastability (documented
* elsewhere in this driver) which tells us we can't set max speed to
* anything lower than SUPER.
*
* Because gadget.max_speed is only used by composite.c and function
* drivers (i.e. it won't go into dwc3's registers) we are allowing this
* to happen so we avoid sending SuperSpeed Capability descriptor
* together with our BOS descriptor as that could confuse host into
* thinking we can handle super speed.
*
* Note that, in fact, we won't even support GetBOS requests when speed
* is less than super speed because we don't have means, yet, to tell
* composite.c that we are USB 2.0 + LPM ECN.
*/
if (dwc->revision < DWC3_REVISION_220A)
dwc3_trace(trace_dwc3_gadget,
"Changing max_speed on rev %08x\n",
dwc->revision);
dwc->gadget.max_speed = dwc->maximum_speed;
/* /*
* Per databook, DWC3 needs buffer size to be aligned to MaxPacketSize * Per databook, DWC3 needs buffer size to be aligned to MaxPacketSize
* on ep out. * on ep out.
......
...@@ -329,7 +329,7 @@ static int alloc_requests(struct usb_composite_dev *cdev, ...@@ -329,7 +329,7 @@ static int alloc_requests(struct usb_composite_dev *cdev,
for (i = 0; i < loop->qlen && result == 0; i++) { for (i = 0; i < loop->qlen && result == 0; i++) {
result = -ENOMEM; result = -ENOMEM;
in_req = usb_ep_alloc_request(loop->in_ep, GFP_KERNEL); in_req = usb_ep_alloc_request(loop->in_ep, GFP_ATOMIC);
if (!in_req) if (!in_req)
goto fail; goto fail;
......
...@@ -1633,7 +1633,7 @@ static irqreturn_t usba_udc_irq(int irq, void *devid) ...@@ -1633,7 +1633,7 @@ static irqreturn_t usba_udc_irq(int irq, void *devid)
spin_lock(&udc->lock); spin_lock(&udc->lock);
int_enb = usba_int_enb_get(udc); int_enb = usba_int_enb_get(udc);
status = usba_readl(udc, INT_STA) & int_enb; status = usba_readl(udc, INT_STA) & (int_enb | USBA_HIGH_SPEED);
DBG(DBG_INT, "irq, status=%#08x\n", status); DBG(DBG_INT, "irq, status=%#08x\n", status);
if (status & USBA_DET_SUSPEND) { if (status & USBA_DET_SUSPEND) {
......
...@@ -132,7 +132,7 @@ static inline struct musb *dev_to_musb(struct device *dev) ...@@ -132,7 +132,7 @@ static inline struct musb *dev_to_musb(struct device *dev)
/*-------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------*/
#ifndef CONFIG_BLACKFIN #ifndef CONFIG_BLACKFIN
static int musb_ulpi_read(struct usb_phy *phy, u32 offset) static int musb_ulpi_read(struct usb_phy *phy, u32 reg)
{ {
void __iomem *addr = phy->io_priv; void __iomem *addr = phy->io_priv;
int i = 0; int i = 0;
...@@ -151,7 +151,7 @@ static int musb_ulpi_read(struct usb_phy *phy, u32 offset) ...@@ -151,7 +151,7 @@ static int musb_ulpi_read(struct usb_phy *phy, u32 offset)
* ULPICarKitControlDisableUTMI after clearing POWER_SUSPENDM. * ULPICarKitControlDisableUTMI after clearing POWER_SUSPENDM.
*/ */
musb_writeb(addr, MUSB_ULPI_REG_ADDR, (u8)offset); musb_writeb(addr, MUSB_ULPI_REG_ADDR, (u8)reg);
musb_writeb(addr, MUSB_ULPI_REG_CONTROL, musb_writeb(addr, MUSB_ULPI_REG_CONTROL,
MUSB_ULPI_REG_REQ | MUSB_ULPI_RDN_WR); MUSB_ULPI_REG_REQ | MUSB_ULPI_RDN_WR);
...@@ -176,7 +176,7 @@ static int musb_ulpi_read(struct usb_phy *phy, u32 offset) ...@@ -176,7 +176,7 @@ static int musb_ulpi_read(struct usb_phy *phy, u32 offset)
return ret; return ret;
} }
static int musb_ulpi_write(struct usb_phy *phy, u32 offset, u32 data) static int musb_ulpi_write(struct usb_phy *phy, u32 val, u32 reg)
{ {
void __iomem *addr = phy->io_priv; void __iomem *addr = phy->io_priv;
int i = 0; int i = 0;
...@@ -191,8 +191,8 @@ static int musb_ulpi_write(struct usb_phy *phy, u32 offset, u32 data) ...@@ -191,8 +191,8 @@ static int musb_ulpi_write(struct usb_phy *phy, u32 offset, u32 data)
power &= ~MUSB_POWER_SUSPENDM; power &= ~MUSB_POWER_SUSPENDM;
musb_writeb(addr, MUSB_POWER, power); musb_writeb(addr, MUSB_POWER, power);
musb_writeb(addr, MUSB_ULPI_REG_ADDR, (u8)offset); musb_writeb(addr, MUSB_ULPI_REG_ADDR, (u8)reg);
musb_writeb(addr, MUSB_ULPI_REG_DATA, (u8)data); musb_writeb(addr, MUSB_ULPI_REG_DATA, (u8)val);
musb_writeb(addr, MUSB_ULPI_REG_CONTROL, MUSB_ULPI_REG_REQ); musb_writeb(addr, MUSB_ULPI_REG_CONTROL, MUSB_ULPI_REG_REQ);
while (!(musb_readb(addr, MUSB_ULPI_REG_CONTROL) while (!(musb_readb(addr, MUSB_ULPI_REG_CONTROL)
...@@ -1668,7 +1668,7 @@ EXPORT_SYMBOL_GPL(musb_interrupt); ...@@ -1668,7 +1668,7 @@ EXPORT_SYMBOL_GPL(musb_interrupt);
static bool use_dma = 1; static bool use_dma = 1;
/* "modprobe ... use_dma=0" etc */ /* "modprobe ... use_dma=0" etc */
module_param(use_dma, bool, 0); module_param(use_dma, bool, 0644);
MODULE_PARM_DESC(use_dma, "enable/disable use of DMA"); MODULE_PARM_DESC(use_dma, "enable/disable use of DMA");
void musb_dma_completion(struct musb *musb, u8 epnum, u8 transmit) void musb_dma_completion(struct musb *musb, u8 epnum, u8 transmit)
......
...@@ -112,22 +112,32 @@ static void musb_h_tx_flush_fifo(struct musb_hw_ep *ep) ...@@ -112,22 +112,32 @@ static void musb_h_tx_flush_fifo(struct musb_hw_ep *ep)
struct musb *musb = ep->musb; struct musb *musb = ep->musb;
void __iomem *epio = ep->regs; void __iomem *epio = ep->regs;
u16 csr; u16 csr;
u16 lastcsr = 0;
int retries = 1000; int retries = 1000;
csr = musb_readw(epio, MUSB_TXCSR); csr = musb_readw(epio, MUSB_TXCSR);
while (csr & MUSB_TXCSR_FIFONOTEMPTY) { while (csr & MUSB_TXCSR_FIFONOTEMPTY) {
if (csr != lastcsr)
dev_dbg(musb->controller, "Host TX FIFONOTEMPTY csr: %02x\n", csr);
lastcsr = csr;
csr |= MUSB_TXCSR_FLUSHFIFO | MUSB_TXCSR_TXPKTRDY; csr |= MUSB_TXCSR_FLUSHFIFO | MUSB_TXCSR_TXPKTRDY;
musb_writew(epio, MUSB_TXCSR, csr); musb_writew(epio, MUSB_TXCSR, csr);
csr = musb_readw(epio, MUSB_TXCSR); csr = musb_readw(epio, MUSB_TXCSR);
if (WARN(retries-- < 1,
/*
* FIXME: sometimes the tx fifo flush failed, it has been
* observed during device disconnect on AM335x.
*
* To reproduce the issue, ensure tx urb(s) are queued when
* unplug the usb device which is connected to AM335x usb
* host port.
*
* I found using a usb-ethernet device and running iperf
* (client on AM335x) has very high chance to trigger it.
*
* Better to turn on dev_dbg() in musb_cleanup_urb() with
* CPPI enabled to see the issue when aborting the tx channel.
*/
if (dev_WARN_ONCE(musb->controller, retries-- < 1,
"Could not flush host TX%d fifo: csr: %04x\n", "Could not flush host TX%d fifo: csr: %04x\n",
ep->epnum, csr)) ep->epnum, csr))
return; return;
mdelay(1);
} }
} }
......
...@@ -452,10 +452,13 @@ static int mxs_phy_probe(struct platform_device *pdev) ...@@ -452,10 +452,13 @@ static int mxs_phy_probe(struct platform_device *pdev)
struct clk *clk; struct clk *clk;
struct mxs_phy *mxs_phy; struct mxs_phy *mxs_phy;
int ret; int ret;
const struct of_device_id *of_id = const struct of_device_id *of_id;
of_match_device(mxs_phy_dt_ids, &pdev->dev);
struct device_node *np = pdev->dev.of_node; struct device_node *np = pdev->dev.of_node;
of_id = of_match_device(mxs_phy_dt_ids, &pdev->dev);
if (!of_id)
return -ENODEV;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0); res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
base = devm_ioremap_resource(&pdev->dev, res); base = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(base)) if (IS_ERR(base))
......
...@@ -105,7 +105,6 @@ static int omap_otg_probe(struct platform_device *pdev) ...@@ -105,7 +105,6 @@ static int omap_otg_probe(struct platform_device *pdev)
extcon = extcon_get_extcon_dev(config->extcon); extcon = extcon_get_extcon_dev(config->extcon);
if (!extcon) if (!extcon)
return -EPROBE_DEFER; return -EPROBE_DEFER;
otg_dev->extcon = extcon;
otg_dev = devm_kzalloc(&pdev->dev, sizeof(*otg_dev), GFP_KERNEL); otg_dev = devm_kzalloc(&pdev->dev, sizeof(*otg_dev), GFP_KERNEL);
if (!otg_dev) if (!otg_dev)
...@@ -115,6 +114,7 @@ static int omap_otg_probe(struct platform_device *pdev) ...@@ -115,6 +114,7 @@ static int omap_otg_probe(struct platform_device *pdev)
if (IS_ERR(otg_dev->base)) if (IS_ERR(otg_dev->base))
return PTR_ERR(otg_dev->base); return PTR_ERR(otg_dev->base);
otg_dev->extcon = extcon;
otg_dev->id_nb.notifier_call = omap_otg_id_notifier; otg_dev->id_nb.notifier_call = omap_otg_id_notifier;
otg_dev->vbus_nb.notifier_call = omap_otg_vbus_notifier; otg_dev->vbus_nb.notifier_call = omap_otg_vbus_notifier;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment