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

Commit bcba282a authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull USB fixes from Greg KH:
 "Here are some USB driver fixes for 4.3-rc3.

  There's the usual assortment of new device ids, combined with xhci and
  gadget driver fixes.  Full details in the shortlog.  All of these have
  been in linux-next with no reported problems"

* tag 'usb-4.3-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb: (34 commits)
  MAINTAINERS: remove amd5536udc USB gadget driver maintainer
  USB: whiteheat: fix potential null-deref at probe
  xhci: init command timeout timer earlier to avoid deleting it uninitialized
  xhci: change xhci 1.0 only restrictions to support xhci 1.1
  usb: xhci: exit early in xhci_setup_device() if we're halted or dying
  usb: xhci: stop everything on the first call to xhci_stop
  usb: xhci: Clear XHCI_STATE_DYING on start
  usb: xhci: lock mutex on xhci_stop
  xhci: Move xhci_pme_quirk() behind #ifdef CONFIG_PM
  xhci: give command abortion one more chance before killing xhci
  usb: Use the USB_SS_MULT() macro to get the burst multiplier.
  usb: dwc3: gadget: Fix BUG in RT config
  usb: musb: fix cppi channel teardown for isoch transfer
  usb: phy: isp1301: Export I2C module alias information
  usb: gadget: drop null test before destroy functions
  usb: gadget: dummy_hcd: in transfer(), return data sent, not limit
  usb: gadget: dummy_hcd: fix rescan logic for transfer
  usb: gadget: dummy_hcd: fix unneeded else-if condition
  usb: gadget: dummy_hcd: emulate sending zlp in packet logic
  usb: musb: dsps: fix polling in device-only mode
  ...
parents fb740f9b b4731977
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -6,6 +6,7 @@ Required properties:
	"lsi,zevio-usb"
	"qcom,ci-hdrc"
	"chipidea,usb2"
	"xlnx,zynq-usb-2.20a"
- reg: base address and length of the registers
- interrupts: interrupt for the USB controller

+1 −2
Original line number Diff line number Diff line
@@ -615,9 +615,8 @@ F: Documentation/hwmon/fam15h_power
F:	drivers/hwmon/fam15h_power.c

AMD GEODE CS5536 USB DEVICE CONTROLLER DRIVER
M:	Thomas Dahlmann <dahlmann.thomas@arcor.de>
L:	linux-geode@lists.infradead.org (moderated for non-subscribers)
S:	Supported
S:	Orphan
F:	drivers/usb/gadget/udc/amd5536udc.*

AMD GEODE PROCESSOR/CHIPSET SUPPORT
+1 −1
Original line number Diff line number Diff line
@@ -61,7 +61,7 @@ static const struct of_device_id ci_hdrc_imx_dt_ids[] = {
	{ .compatible = "fsl,imx27-usb", .data = &imx27_usb_data},
	{ .compatible = "fsl,imx6q-usb", .data = &imx6q_usb_data},
	{ .compatible = "fsl,imx6sl-usb", .data = &imx6sl_usb_data},
	{ .compatible = "fsl,imx6sx-usb", .data = &imx6sl_usb_data},
	{ .compatible = "fsl,imx6sx-usb", .data = &imx6sx_usb_data},
	{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, ci_hdrc_imx_dt_ids);
+19 −6
Original line number Diff line number Diff line
@@ -12,6 +12,7 @@
#include <linux/dma-mapping.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_platform.h>
#include <linux/phy/phy.h>
#include <linux/platform_device.h>
#include <linux/usb/chipidea.h>
@@ -30,18 +31,36 @@ static const struct ci_hdrc_platform_data ci_default_pdata = {
	.flags		= CI_HDRC_DISABLE_STREAMING,
};

static struct ci_hdrc_platform_data ci_zynq_pdata = {
	.capoffset	= DEF_CAPOFFSET,
};

static const struct of_device_id ci_hdrc_usb2_of_match[] = {
	{ .compatible = "chipidea,usb2"},
	{ .compatible = "xlnx,zynq-usb-2.20a", .data = &ci_zynq_pdata},
	{ }
};
MODULE_DEVICE_TABLE(of, ci_hdrc_usb2_of_match);

static int ci_hdrc_usb2_probe(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	struct ci_hdrc_usb2_priv *priv;
	struct ci_hdrc_platform_data *ci_pdata = dev_get_platdata(dev);
	int ret;
	const struct of_device_id *match;

	if (!ci_pdata) {
		ci_pdata = devm_kmalloc(dev, sizeof(*ci_pdata), GFP_KERNEL);
		*ci_pdata = ci_default_pdata;	/* struct copy */
	}

	match = of_match_device(ci_hdrc_usb2_of_match, &pdev->dev);
	if (match && match->data) {
		/* struct copy */
		*ci_pdata = *(struct ci_hdrc_platform_data *)match->data;
	}

	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
	if (!priv)
		return -ENOMEM;
@@ -96,12 +115,6 @@ static int ci_hdrc_usb2_remove(struct platform_device *pdev)
	return 0;
}

static const struct of_device_id ci_hdrc_usb2_of_match[] = {
	{ .compatible = "chipidea,usb2" },
	{ }
};
MODULE_DEVICE_TABLE(of, ci_hdrc_usb2_of_match);

static struct platform_driver ci_hdrc_usb2_driver = {
	.probe	= ci_hdrc_usb2_probe,
	.remove	= ci_hdrc_usb2_remove,
+44 −40
Original line number Diff line number Diff line
@@ -656,6 +656,44 @@ __acquires(hwep->lock)
	return 0;
}

static int _ep_set_halt(struct usb_ep *ep, int value, bool check_transfer)
{
	struct ci_hw_ep *hwep = container_of(ep, struct ci_hw_ep, ep);
	int direction, retval = 0;
	unsigned long flags;

	if (ep == NULL || hwep->ep.desc == NULL)
		return -EINVAL;

	if (usb_endpoint_xfer_isoc(hwep->ep.desc))
		return -EOPNOTSUPP;

	spin_lock_irqsave(hwep->lock, flags);

	if (value && hwep->dir == TX && check_transfer &&
		!list_empty(&hwep->qh.queue) &&
			!usb_endpoint_xfer_control(hwep->ep.desc)) {
		spin_unlock_irqrestore(hwep->lock, flags);
		return -EAGAIN;
	}

	direction = hwep->dir;
	do {
		retval |= hw_ep_set_halt(hwep->ci, hwep->num, hwep->dir, value);

		if (!value)
			hwep->wedge = 0;

		if (hwep->type == USB_ENDPOINT_XFER_CONTROL)
			hwep->dir = (hwep->dir == TX) ? RX : TX;

	} while (hwep->dir != direction);

	spin_unlock_irqrestore(hwep->lock, flags);
	return retval;
}


/**
 * _gadget_stop_activity: stops all USB activity, flushes & disables all endpts
 * @gadget: gadget
@@ -1051,7 +1089,7 @@ __acquires(ci->lock)
				num += ci->hw_ep_max / 2;

			spin_unlock(&ci->lock);
			err = usb_ep_set_halt(&ci->ci_hw_ep[num].ep);
			err = _ep_set_halt(&ci->ci_hw_ep[num].ep, 1, false);
			spin_lock(&ci->lock);
			if (!err)
				isr_setup_status_phase(ci);
@@ -1117,8 +1155,8 @@ __acquires(ci->lock)

	if (err < 0) {
		spin_unlock(&ci->lock);
		if (usb_ep_set_halt(&hwep->ep))
			dev_err(ci->dev, "error: ep_set_halt\n");
		if (_ep_set_halt(&hwep->ep, 1, false))
			dev_err(ci->dev, "error: _ep_set_halt\n");
		spin_lock(&ci->lock);
	}
}
@@ -1149,9 +1187,9 @@ __acquires(ci->lock)
					err = isr_setup_status_phase(ci);
				if (err < 0) {
					spin_unlock(&ci->lock);
					if (usb_ep_set_halt(&hwep->ep))
					if (_ep_set_halt(&hwep->ep, 1, false))
						dev_err(ci->dev,
							"error: ep_set_halt\n");
						"error: _ep_set_halt\n");
					spin_lock(&ci->lock);
				}
			}
@@ -1397,41 +1435,7 @@ static int ep_dequeue(struct usb_ep *ep, struct usb_request *req)
 */
static int ep_set_halt(struct usb_ep *ep, int value)
{
	struct ci_hw_ep *hwep = container_of(ep, struct ci_hw_ep, ep);
	int direction, retval = 0;
	unsigned long flags;

	if (ep == NULL || hwep->ep.desc == NULL)
		return -EINVAL;

	if (usb_endpoint_xfer_isoc(hwep->ep.desc))
		return -EOPNOTSUPP;

	spin_lock_irqsave(hwep->lock, flags);

#ifndef STALL_IN
	/* g_file_storage MS compliant but g_zero fails chapter 9 compliance */
	if (value && hwep->type == USB_ENDPOINT_XFER_BULK && hwep->dir == TX &&
	    !list_empty(&hwep->qh.queue)) {
		spin_unlock_irqrestore(hwep->lock, flags);
		return -EAGAIN;
	}
#endif

	direction = hwep->dir;
	do {
		retval |= hw_ep_set_halt(hwep->ci, hwep->num, hwep->dir, value);

		if (!value)
			hwep->wedge = 0;

		if (hwep->type == USB_ENDPOINT_XFER_CONTROL)
			hwep->dir = (hwep->dir == TX) ? RX : TX;

	} while (hwep->dir != direction);

	spin_unlock_irqrestore(hwep->lock, flags);
	return retval;
	return _ep_set_halt(ep, value, true);
}

/**
Loading