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. -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQIcBAABAgAGBQJWS2YtAAoJEIaOsuA1yqREMgcP/2gd000XVC6KpxncXlB4LYUU 4sZ/mp1HQx10Stl4MzGn4rD5MK1yfffuDnyEMtA8grlPx62+RZiNxpePrggmiUVu Dtv9zag8OjuE9hgdCF8Qldi3QoeixpYSNhIdXJSRdxXviEehfY28VTeh1jXkXbQ1 r5xetQ+eONgx1xMVdbDBhn85w8RbrgOmtBAFebn5WukDd4eWzo5kj+EUs+uFrlf+ KX/tKXz/srsb+FTumUkxlXmfESgeUSoXQtsOJNjph+mpkEGQpnmxzfHQmYmSKXmo gSxUkVPylmbyqXJxsX8zRNMjriOIqKp84701Evyt0Je3w6cw1eQP89q8Dz9bWN8v FMQc/LWc1fwbxXUstgZqQigRFa0TdtBnLRueAWkeP7HjbeT9ZoVNKWnSTFj0H+zD Ci9dZ8iRdTPTTCDMDXbTw1zPvgoEb2BI21hYG8CkQc00xMIz2bKwDb2FyenApFKx qEXdyITsXiDKrw9Y7HZhf82KKWyw3JAfFzolmPFgF5lSJoUJGOBv1dgVjiRGpiBD IdFp2AIwHnhMX68+OW72Nh3SucUvxlgjjzgGekHo6QG+NQA8a6qgvoMiYHD9nMVj smS9Bc5+XvZUEI6falcJIcR2D/4ylYMNbq6c0oBOxkcdcktys/YPA/nj02S5F64Q 84k2UswwCbpRWpUoo471 =LniW -----END PGP SIGNATURE----- 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.
This commit is contained in:
Коммит
aa05cfa95f
|
@ -324,12 +324,13 @@ void dwc2_hcd_disconnect(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;
|
||||
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)
|
|||
dev_dbg(hsotg->dev, "Clear Resume: HPRT0=%0x\n",
|
||||
dwc2_readl(hsotg->regs + HPRT0));
|
||||
|
||||
hsotg->bus_suspended = 0;
|
||||
dwc2_hcd_rem_wakeup(hsotg);
|
||||
hsotg->bus_suspended = 0;
|
||||
|
||||
/* Change to L0 state */
|
||||
hsotg->lx_state = DWC2_L0;
|
||||
|
|
|
@ -108,7 +108,8 @@ static const struct dwc2_core_params params_rk3066 = {
|
|||
.host_ls_low_power_phy_clk = -1,
|
||||
.ts_dline = -1,
|
||||
.reload_ctl = -1,
|
||||
.ahbcfg = 0x7, /* INCR16 */
|
||||
.ahbcfg = GAHBCFG_HBSTLEN_INCR16 <<
|
||||
GAHBCFG_HBSTLEN_SHIFT,
|
||||
.uframe_sched = -1,
|
||||
.external_id_pin_ctl = -1,
|
||||
.hibernation = -1,
|
||||
|
|
|
@ -34,6 +34,8 @@
|
|||
#define PCI_DEVICE_ID_INTEL_BSW 0x22b7
|
||||
#define PCI_DEVICE_ID_INTEL_SPTLP 0x9d30
|
||||
#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 cs_gpios = { 1, 0, false };
|
||||
|
@ -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_SPTLP), },
|
||||
{ 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), },
|
||||
{ } /* Terminating Entry */
|
||||
};
|
||||
|
|
|
@ -2744,11 +2744,33 @@ int dwc3_gadget_init(struct dwc3 *dwc)
|
|||
}
|
||||
|
||||
dwc->gadget.ops = &dwc3_gadget_ops;
|
||||
dwc->gadget.max_speed = USB_SPEED_SUPER;
|
||||
dwc->gadget.speed = USB_SPEED_UNKNOWN;
|
||||
dwc->gadget.sg_supported = true;
|
||||
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
|
||||
* on ep out.
|
||||
|
|
|
@ -329,7 +329,7 @@ static int alloc_requests(struct usb_composite_dev *cdev,
|
|||
for (i = 0; i < loop->qlen && result == 0; i++) {
|
||||
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)
|
||||
goto fail;
|
||||
|
||||
|
|
|
@ -1633,7 +1633,7 @@ static irqreturn_t usba_udc_irq(int irq, void *devid)
|
|||
spin_lock(&udc->lock);
|
||||
|
||||
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);
|
||||
|
||||
if (status & USBA_DET_SUSPEND) {
|
||||
|
|
|
@ -132,7 +132,7 @@ static inline struct musb *dev_to_musb(struct device *dev)
|
|||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
#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;
|
||||
int i = 0;
|
||||
|
@ -151,7 +151,7 @@ static int musb_ulpi_read(struct usb_phy *phy, u32 offset)
|
|||
* 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_ULPI_REG_REQ | MUSB_ULPI_RDN_WR);
|
||||
|
||||
|
@ -176,7 +176,7 @@ out:
|
|||
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;
|
||||
int i = 0;
|
||||
|
@ -191,8 +191,8 @@ static int musb_ulpi_write(struct usb_phy *phy, u32 offset, u32 data)
|
|||
power &= ~MUSB_POWER_SUSPENDM;
|
||||
musb_writeb(addr, MUSB_POWER, power);
|
||||
|
||||
musb_writeb(addr, MUSB_ULPI_REG_ADDR, (u8)offset);
|
||||
musb_writeb(addr, MUSB_ULPI_REG_DATA, (u8)data);
|
||||
musb_writeb(addr, MUSB_ULPI_REG_ADDR, (u8)reg);
|
||||
musb_writeb(addr, MUSB_ULPI_REG_DATA, (u8)val);
|
||||
musb_writeb(addr, MUSB_ULPI_REG_CONTROL, MUSB_ULPI_REG_REQ);
|
||||
|
||||
while (!(musb_readb(addr, MUSB_ULPI_REG_CONTROL)
|
||||
|
@ -1668,7 +1668,7 @@ EXPORT_SYMBOL_GPL(musb_interrupt);
|
|||
static bool use_dma = 1;
|
||||
|
||||
/* "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");
|
||||
|
||||
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)
|
|||
struct musb *musb = ep->musb;
|
||||
void __iomem *epio = ep->regs;
|
||||
u16 csr;
|
||||
u16 lastcsr = 0;
|
||||
int retries = 1000;
|
||||
|
||||
csr = musb_readw(epio, MUSB_TXCSR);
|
||||
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;
|
||||
musb_writew(epio, MUSB_TXCSR, csr);
|
||||
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",
|
||||
ep->epnum, csr))
|
||||
return;
|
||||
mdelay(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -452,10 +452,13 @@ static int mxs_phy_probe(struct platform_device *pdev)
|
|||
struct clk *clk;
|
||||
struct mxs_phy *mxs_phy;
|
||||
int ret;
|
||||
const struct of_device_id *of_id =
|
||||
of_match_device(mxs_phy_dt_ids, &pdev->dev);
|
||||
const struct of_device_id *of_id;
|
||||
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);
|
||||
base = devm_ioremap_resource(&pdev->dev, res);
|
||||
if (IS_ERR(base))
|
||||
|
|
|
@ -105,7 +105,6 @@ static int omap_otg_probe(struct platform_device *pdev)
|
|||
extcon = extcon_get_extcon_dev(config->extcon);
|
||||
if (!extcon)
|
||||
return -EPROBE_DEFER;
|
||||
otg_dev->extcon = extcon;
|
||||
|
||||
otg_dev = devm_kzalloc(&pdev->dev, sizeof(*otg_dev), GFP_KERNEL);
|
||||
if (!otg_dev)
|
||||
|
@ -115,6 +114,7 @@ static int omap_otg_probe(struct platform_device *pdev)
|
|||
if (IS_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->vbus_nb.notifier_call = omap_otg_vbus_notifier;
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче