Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8071e6f8 authored by Greg Kroah-Hartman's avatar Greg Kroah-Hartman
Browse files

Merge tag 'fixes-for-v3.18-rc2' of...

Merge tag 'fixes-for-v3.18-rc2' of git://git.kernel.org/pub/scm/linux/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: default avatarFelipe Balbi <balbi@ti.com>
parents f114040e 9b176355
Loading
Loading
Loading
Loading
+1 −1
Original line number Original line Diff line number Diff line
@@ -619,7 +619,7 @@ struct dwc2_hsotg {
			unsigned port_suspend_change:1;
			unsigned port_suspend_change:1;
			unsigned port_over_current_change:1;
			unsigned port_over_current_change:1;
			unsigned port_l1_change:1;
			unsigned port_l1_change:1;
			unsigned reserved:26;
			unsigned reserved:25;
		} b;
		} b;
	} flags;
	} flags;


+7 −7
Original line number Original line Diff line number Diff line
@@ -2561,8 +2561,10 @@ static int s3c_hsotg_ep_enable(struct usb_ep *ep,
			hs_ep->fifo_size = val;
			hs_ep->fifo_size = val;
			break;
			break;
		}
		}
		if (i == 8)
		if (i == 8) {
			return -ENOMEM;
			ret = -ENOMEM;
			goto error;
		}
	}
	}


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


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


	spin_lock_irqsave(&hsotg->lock, flags);
	spin_lock_irqsave(&hsotg->lock, flags);


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

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


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


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


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


	s3c_hsotg_phy_disable(hsotg);

	ret = usb_add_gadget_udc(&pdev->dev, &hsotg->gadget);
	ret = usb_add_gadget_udc(&pdev->dev, &hsotg->gadget);
	if (ret)
	if (ret)
		goto err_ep_mem;
		goto err_ep_mem;
+2 −13
Original line number Original line Diff line number Diff line
@@ -597,7 +597,7 @@ static int dwc3_omap_prepare(struct device *dev)
{
{
	struct dwc3_omap	*omap = dev_get_drvdata(dev);
	struct dwc3_omap	*omap = dev_get_drvdata(dev);


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


	return 0;
	return 0;
}
}
@@ -605,19 +605,8 @@ static int dwc3_omap_prepare(struct device *dev)
static void dwc3_omap_complete(struct device *dev)
static void dwc3_omap_complete(struct device *dev)
{
{
	struct dwc3_omap	*omap = dev_get_drvdata(dev);
	struct dwc3_omap	*omap = dev_get_drvdata(dev);
	u32			reg;


	reg = (USBOTGSS_IRQMISC_OEVT |
	dwc3_omap_enable_irqs(omap);
			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);
}
}


static int dwc3_omap_suspend(struct device *dev)
static int dwc3_omap_suspend(struct device *dev)
+2 −0
Original line number Original line Diff line number Diff line
@@ -30,6 +30,7 @@
#define PCI_DEVICE_ID_SYNOPSYS_HAPSUSB3	0xabcd
#define PCI_DEVICE_ID_SYNOPSYS_HAPSUSB3	0xabcd
#define PCI_DEVICE_ID_INTEL_BYT		0x0f37
#define PCI_DEVICE_ID_INTEL_BYT		0x0f37
#define PCI_DEVICE_ID_INTEL_MRFLD	0x119e
#define PCI_DEVICE_ID_INTEL_MRFLD	0x119e
#define PCI_DEVICE_ID_INTEL_BSW		0x22B7


struct dwc3_pci {
struct dwc3_pci {
	struct device		*dev;
	struct device		*dev;
@@ -181,6 +182,7 @@ static const struct pci_device_id dwc3_pci_id_table[] = {
		PCI_DEVICE(PCI_VENDOR_ID_SYNOPSYS,
		PCI_DEVICE(PCI_VENDOR_ID_SYNOPSYS,
				PCI_DEVICE_ID_SYNOPSYS_HAPSUSB3),
				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_BYT), },
	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_MRFLD), },
	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_MRFLD), },
	{  }	/* Terminating Entry */
	{  }	/* Terminating Entry */
+36 −12
Original line number Original line Diff line number Diff line
@@ -256,7 +256,7 @@ static void dwc3_ep0_stall_and_restart(struct dwc3 *dwc)


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


@@ -271,7 +271,7 @@ static void dwc3_ep0_stall_and_restart(struct dwc3 *dwc)
	dwc3_ep0_out_start(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_ep			*dep = to_dwc3_ep(ep);
	struct dwc3			*dwc = dep->dwc;
	struct dwc3			*dwc = dep->dwc;
@@ -281,6 +281,20 @@ int dwc3_gadget_ep0_set_halt(struct usb_ep *ep, int value)
	return 0;
	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)
void dwc3_ep0_out_start(struct dwc3 *dwc)
{
{
	int				ret;
	int				ret;
@@ -466,7 +480,7 @@ static int dwc3_ep0_handle_feature(struct dwc3 *dwc,
				return -EINVAL;
				return -EINVAL;
			if (set == 0 && (dep->flags & DWC3_EP_WEDGE))
			if (set == 0 && (dep->flags & DWC3_EP_WEDGE))
				break;
				break;
			ret = __dwc3_gadget_ep_set_halt(dep, set);
			ret = __dwc3_gadget_ep_set_halt(dep, set, true);
			if (ret)
			if (ret)
				return -EINVAL;
				return -EINVAL;
			break;
			break;
@@ -775,9 +789,6 @@ static void dwc3_ep0_complete_data(struct dwc3 *dwc,


	dwc->ep0_next_event = DWC3_EP0_NRDY_STATUS;
	dwc->ep0_next_event = DWC3_EP0_NRDY_STATUS;


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

	trb = dwc->ep0_trb;
	trb = dwc->ep0_trb;


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


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

	ur = &r->request;

	length = trb->size & DWC3_TRB_SIZE_MASK;
	length = trb->size & DWC3_TRB_SIZE_MASK;


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


		dwc3_ep0_stall_and_restart(dwc);
		dwc3_ep0_stall_and_restart(dwc);
	} else {
	} 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);
		}
	}
	}
}
}


Loading