Skip to content

Commit

Permalink
Merge tag 'fixes-for-v3.18-rc2' of git://git.kernel.org/pub/scm/linux…
Browse files Browse the repository at this point in the history
…/kernel/git/balbi/usb into usb-linus

Felipe writes:

usb: fixes for v3.18-rc2

Here's the first set of fixes for v3.18-rc cycle. It includes
a whole bunch of bug fixes related to USB20CV and USB30CV when
running on DWC3 and MUSB. After this series, we have clean chapter 9
and MSC tests for all gadget drivers.

We also have a new PCI ID for Intel Braswell platform so they can use
DWC3 out-of-the-box.

A regression on functionfs wrt quirk_ep_out_aligned_size flag has also
been fixed.

DWC2 got a couple of fixes for the gadget role. The first of which fixes
rmmod followed by modprobe while the second makes sure to disable PHYs
before killing the regulators powering them.

These are the most important fixes worth mentioning, there are a few
other minor fixes as well.

Signed-off-by: Felipe Balbi <balbi@ti.com>
  • Loading branch information
Greg Kroah-Hartman committed Oct 25, 2014
2 parents f114040 + 9b17635 commit 8071e6f
Show file tree
Hide file tree
Showing 26 changed files with 294 additions and 156 deletions.
2 changes: 1 addition & 1 deletion drivers/usb/dwc2/core.h
Original file line number Diff line number Diff line change
Expand Up @@ -619,7 +619,7 @@ struct dwc2_hsotg {
unsigned port_suspend_change:1;
unsigned port_over_current_change:1;
unsigned port_l1_change:1;
unsigned reserved:26;
unsigned reserved:25;
} b;
} flags;

Expand Down
14 changes: 7 additions & 7 deletions drivers/usb/dwc2/gadget.c
Original file line number Diff line number Diff line change
Expand Up @@ -2561,8 +2561,10 @@ static int s3c_hsotg_ep_enable(struct usb_ep *ep,
hs_ep->fifo_size = val;
break;
}
if (i == 8)
return -ENOMEM;
if (i == 8) {
ret = -ENOMEM;
goto error;
}
}

/* for non control endpoints, set PID to D0 */
Expand All @@ -2579,6 +2581,7 @@ static int s3c_hsotg_ep_enable(struct usb_ep *ep,
/* enable the endpoint interrupt */
s3c_hsotg_ctrl_epint(hsotg, index, dir_in, 1);

error:
spin_unlock_irqrestore(&hsotg->lock, flags);
return ret;
}
Expand Down Expand Up @@ -2934,9 +2937,7 @@ static int s3c_hsotg_udc_stop(struct usb_gadget *gadget,

spin_lock_irqsave(&hsotg->lock, flags);

if (!driver)
hsotg->driver = NULL;

hsotg->driver = NULL;
hsotg->gadget.speed = USB_SPEED_UNKNOWN;

spin_unlock_irqrestore(&hsotg->lock, flags);
Expand Down Expand Up @@ -3567,6 +3568,7 @@ static int s3c_hsotg_probe(struct platform_device *pdev)
s3c_hsotg_initep(hsotg, &hsotg->eps[epnum], epnum);

/* disable power and clock */
s3c_hsotg_phy_disable(hsotg);

ret = regulator_bulk_disable(ARRAY_SIZE(hsotg->supplies),
hsotg->supplies);
Expand All @@ -3575,8 +3577,6 @@ static int s3c_hsotg_probe(struct platform_device *pdev)
goto err_ep_mem;
}

s3c_hsotg_phy_disable(hsotg);

ret = usb_add_gadget_udc(&pdev->dev, &hsotg->gadget);
if (ret)
goto err_ep_mem;
Expand Down
15 changes: 2 additions & 13 deletions drivers/usb/dwc3/dwc3-omap.c
Original file line number Diff line number Diff line change
Expand Up @@ -597,27 +597,16 @@ static int dwc3_omap_prepare(struct device *dev)
{
struct dwc3_omap *omap = dev_get_drvdata(dev);

dwc3_omap_write_irqmisc_set(omap, 0x00);
dwc3_omap_disable_irqs(omap);

return 0;
}

static void dwc3_omap_complete(struct device *dev)
{
struct dwc3_omap *omap = dev_get_drvdata(dev);
u32 reg;

reg = (USBOTGSS_IRQMISC_OEVT |
USBOTGSS_IRQMISC_DRVVBUS_RISE |
USBOTGSS_IRQMISC_CHRGVBUS_RISE |
USBOTGSS_IRQMISC_DISCHRGVBUS_RISE |
USBOTGSS_IRQMISC_IDPULLUP_RISE |
USBOTGSS_IRQMISC_DRVVBUS_FALL |
USBOTGSS_IRQMISC_CHRGVBUS_FALL |
USBOTGSS_IRQMISC_DISCHRGVBUS_FALL |
USBOTGSS_IRQMISC_IDPULLUP_FALL);

dwc3_omap_write_irqmisc_set(omap, reg);
dwc3_omap_enable_irqs(omap);
}

static int dwc3_omap_suspend(struct device *dev)
Expand Down
2 changes: 2 additions & 0 deletions drivers/usb/dwc3/dwc3-pci.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
#define PCI_DEVICE_ID_SYNOPSYS_HAPSUSB3 0xabcd
#define PCI_DEVICE_ID_INTEL_BYT 0x0f37
#define PCI_DEVICE_ID_INTEL_MRFLD 0x119e
#define PCI_DEVICE_ID_INTEL_BSW 0x22B7

struct dwc3_pci {
struct device *dev;
Expand Down Expand Up @@ -181,6 +182,7 @@ static const struct pci_device_id dwc3_pci_id_table[] = {
PCI_DEVICE(PCI_VENDOR_ID_SYNOPSYS,
PCI_DEVICE_ID_SYNOPSYS_HAPSUSB3),
},
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_BSW), },
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_BYT), },
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_MRFLD), },
{ } /* Terminating Entry */
Expand Down
48 changes: 36 additions & 12 deletions drivers/usb/dwc3/ep0.c
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,7 @@ static void dwc3_ep0_stall_and_restart(struct dwc3 *dwc)

/* stall is always issued on EP0 */
dep = dwc->eps[0];
__dwc3_gadget_ep_set_halt(dep, 1);
__dwc3_gadget_ep_set_halt(dep, 1, false);
dep->flags = DWC3_EP_ENABLED;
dwc->delayed_status = false;

Expand All @@ -271,7 +271,7 @@ static void dwc3_ep0_stall_and_restart(struct dwc3 *dwc)
dwc3_ep0_out_start(dwc);
}

int dwc3_gadget_ep0_set_halt(struct usb_ep *ep, int value)
int __dwc3_gadget_ep0_set_halt(struct usb_ep *ep, int value)
{
struct dwc3_ep *dep = to_dwc3_ep(ep);
struct dwc3 *dwc = dep->dwc;
Expand All @@ -281,6 +281,20 @@ int dwc3_gadget_ep0_set_halt(struct usb_ep *ep, int value)
return 0;
}

int dwc3_gadget_ep0_set_halt(struct usb_ep *ep, int value)
{
struct dwc3_ep *dep = to_dwc3_ep(ep);
struct dwc3 *dwc = dep->dwc;
unsigned long flags;
int ret;

spin_lock_irqsave(&dwc->lock, flags);
ret = __dwc3_gadget_ep0_set_halt(ep, value);
spin_unlock_irqrestore(&dwc->lock, flags);

return ret;
}

void dwc3_ep0_out_start(struct dwc3 *dwc)
{
int ret;
Expand Down Expand Up @@ -466,7 +480,7 @@ static int dwc3_ep0_handle_feature(struct dwc3 *dwc,
return -EINVAL;
if (set == 0 && (dep->flags & DWC3_EP_WEDGE))
break;
ret = __dwc3_gadget_ep_set_halt(dep, set);
ret = __dwc3_gadget_ep_set_halt(dep, set, true);
if (ret)
return -EINVAL;
break;
Expand Down Expand Up @@ -775,9 +789,6 @@ static void dwc3_ep0_complete_data(struct dwc3 *dwc,

dwc->ep0_next_event = DWC3_EP0_NRDY_STATUS;

r = next_request(&ep0->request_list);
ur = &r->request;

trb = dwc->ep0_trb;

status = DWC3_TRB_SIZE_TRBSTS(trb->size);
Expand All @@ -790,6 +801,12 @@ static void dwc3_ep0_complete_data(struct dwc3 *dwc,
return;
}

r = next_request(&ep0->request_list);
if (!r)
return;

ur = &r->request;

length = trb->size & DWC3_TRB_SIZE_MASK;

if (dwc->ep0_bounced) {
Expand All @@ -811,12 +828,19 @@ static void dwc3_ep0_complete_data(struct dwc3 *dwc,

dwc3_ep0_stall_and_restart(dwc);
} else {
/*
* handle the case where we have to send a zero packet. This
* seems to be case when req.length > maxpacket. Could it be?
*/
if (r)
dwc3_gadget_giveback(ep0, r, 0);
dwc3_gadget_giveback(ep0, r, 0);

if (IS_ALIGNED(ur->length, ep0->endpoint.maxpacket) &&
ur->length && ur->zero) {
int ret;

dwc->ep0_next_event = DWC3_EP0_COMPLETE;

ret = dwc3_ep0_start_trans(dwc, epnum,
dwc->ctrl_req_addr, 0,
DWC3_TRBCTL_CONTROL_DATA);
WARN_ON(ret < 0);
}
}
}

Expand Down
39 changes: 23 additions & 16 deletions drivers/usb/dwc3/gadget.c
Original file line number Diff line number Diff line change
Expand Up @@ -525,12 +525,11 @@ static int __dwc3_gadget_ep_enable(struct dwc3_ep *dep,
if (!usb_endpoint_xfer_isoc(desc))
return 0;

memset(&trb_link, 0, sizeof(trb_link));

/* Link TRB for ISOC. The HWO bit is never reset */
trb_st_hw = &dep->trb_pool[0];

trb_link = &dep->trb_pool[DWC3_TRB_NUM - 1];
memset(trb_link, 0, sizeof(*trb_link));

trb_link->bpl = lower_32_bits(dwc3_trb_dma_offset(dep, trb_st_hw));
trb_link->bph = upper_32_bits(dwc3_trb_dma_offset(dep, trb_st_hw));
Expand Down Expand Up @@ -581,7 +580,7 @@ static int __dwc3_gadget_ep_disable(struct dwc3_ep *dep)

/* make sure HW endpoint isn't stalled */
if (dep->flags & DWC3_EP_STALL)
__dwc3_gadget_ep_set_halt(dep, 0);
__dwc3_gadget_ep_set_halt(dep, 0, false);

reg = dwc3_readl(dwc->regs, DWC3_DALEPENA);
reg &= ~DWC3_DALEPENA_EP(dep->number);
Expand Down Expand Up @@ -1202,15 +1201,28 @@ static int dwc3_gadget_ep_dequeue(struct usb_ep *ep,
return ret;
}

int __dwc3_gadget_ep_set_halt(struct dwc3_ep *dep, int value)
int __dwc3_gadget_ep_set_halt(struct dwc3_ep *dep, int value, int protocol)
{
struct dwc3_gadget_ep_cmd_params params;
struct dwc3 *dwc = dep->dwc;
int ret;

if (usb_endpoint_xfer_isoc(dep->endpoint.desc)) {
dev_err(dwc->dev, "%s is of Isochronous type\n", dep->name);
return -EINVAL;
}

memset(&params, 0x00, sizeof(params));

if (value) {
if (!protocol && ((dep->direction && dep->flags & DWC3_EP_BUSY) ||
(!list_empty(&dep->req_queued) ||
!list_empty(&dep->request_list)))) {
dev_dbg(dwc->dev, "%s: pending request, cannot halt\n",
dep->name);
return -EAGAIN;
}

ret = dwc3_send_gadget_ep_cmd(dwc, dep->number,
DWC3_DEPCMD_SETSTALL, &params);
if (ret)
Expand Down Expand Up @@ -1241,15 +1253,7 @@ static int dwc3_gadget_ep_set_halt(struct usb_ep *ep, int value)
int ret;

spin_lock_irqsave(&dwc->lock, flags);

if (usb_endpoint_xfer_isoc(dep->endpoint.desc)) {
dev_err(dwc->dev, "%s is of Isochronous type\n", dep->name);
ret = -EINVAL;
goto out;
}

ret = __dwc3_gadget_ep_set_halt(dep, value);
out:
ret = __dwc3_gadget_ep_set_halt(dep, value, false);
spin_unlock_irqrestore(&dwc->lock, flags);

return ret;
Expand All @@ -1260,15 +1264,18 @@ static int dwc3_gadget_ep_set_wedge(struct usb_ep *ep)
struct dwc3_ep *dep = to_dwc3_ep(ep);
struct dwc3 *dwc = dep->dwc;
unsigned long flags;
int ret;

spin_lock_irqsave(&dwc->lock, flags);
dep->flags |= DWC3_EP_WEDGE;
spin_unlock_irqrestore(&dwc->lock, flags);

if (dep->number == 0 || dep->number == 1)
return dwc3_gadget_ep0_set_halt(ep, 1);
ret = __dwc3_gadget_ep0_set_halt(ep, 1);
else
return dwc3_gadget_ep_set_halt(ep, 1);
ret = __dwc3_gadget_ep_set_halt(dep, 1, false);
spin_unlock_irqrestore(&dwc->lock, flags);

return ret;
}

/* -------------------------------------------------------------------------- */
Expand Down
3 changes: 2 additions & 1 deletion drivers/usb/dwc3/gadget.h
Original file line number Diff line number Diff line change
Expand Up @@ -82,10 +82,11 @@ void dwc3_gadget_giveback(struct dwc3_ep *dep, struct dwc3_request *req,
void dwc3_ep0_interrupt(struct dwc3 *dwc,
const struct dwc3_event_depevt *event);
void dwc3_ep0_out_start(struct dwc3 *dwc);
int __dwc3_gadget_ep0_set_halt(struct usb_ep *ep, int value);
int dwc3_gadget_ep0_set_halt(struct usb_ep *ep, int value);
int dwc3_gadget_ep0_queue(struct usb_ep *ep, struct usb_request *request,
gfp_t gfp_flags);
int __dwc3_gadget_ep_set_halt(struct dwc3_ep *dep, int value);
int __dwc3_gadget_ep_set_halt(struct dwc3_ep *dep, int value, int protocol);

/**
* dwc3_gadget_ep_get_transfer_index - Gets transfer index from HW
Expand Down
Loading

0 comments on commit 8071e6f

Please sign in to comment.