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

Merge tag 'usb-for-v5.9' of git://git.kernel.org/pub/scm/linux/kernel/git/balbi/usb into usb-next

Felipe writes:

USB: changes for v5.9 merge window

CDNS3 got several improvements, most of which are non-critical fixes.
DWC3 has a reset fix for the meson platform, while dwc2 has
improvements for role switch on STM32MP15 SoCs.

Apart from these, we have the usual set of non-critical fixes all over
the place and support for new Ingenic SoC to their PHY driver.

* tag 'usb-for-v5.9' of git://git.kernel.org/pub/scm/linux/kernel/git/balbi/usb: (38 commits)
  usb: dwc3: gadget: when the started list is empty stop the active xfer
  usb: dwc3: gadget: make starting isoc transfers more robust
  usb: dwc3: gadget: add frame number mask
  usb: gadget: function: printer: Interface is disabled and returns error
  usb: gadget: f_uac2: fix AC Interface Header Descriptor wTotalLength
  dt-bindings: usb: ti,keystone-dwc3.yaml: Improve schema
  usb: bdc: Use devm_clk_get_optional()
  usb: bdc: Halt controller on suspend
  usb: bdc: driver runs out of buffer descriptors on large ADB transfers
  usb: bdc: Adb shows offline after resuming from S2
  bdc: Fix bug causing crash after multiple disconnects
  usb: bdc: Add compatible string for new style USB DT nodes
  dt-bindings: usb: bdc: Update compatible strings
  USB: PHY: JZ4770: Reformat the code to align it.
  USB: PHY: JZ4770: Add support for new Ingenic SoCs.
  USB: PHY: JZ4770: Unify code style and simplify code.
  dt-bindings: USB: Add bindings for new Ingenic SoCs.
  usb: gadget: net2280: fix memory leak on probe error handling paths
  usb: cdns3: drd: simplify *switch_gadet and *switch_host
  usb: cdns3: core: removed overwriting some error code
  ...
parents c9779308 f5e46aa4
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -4,7 +4,7 @@ Broadcom USB Device Controller (BDC)
Required properties:

- compatible: must be one of:
                "brcm,bdc-v0.16"
                "brcm,bdc-udc-v2"
                "brcm,bdc"
- reg: the base register address and length
- interrupts: the interrupt line for this controller
@@ -21,7 +21,7 @@ On Broadcom STB platforms, these properties are required:
Example:

        bdc@f0b02000 {
                compatible = "brcm,bdc-v0.16";
                compatible = "brcm,bdc-udc-v2";
                reg = <0xf0b02000 0xfc4>;
                interrupts = <0x0 0x60 0x0>;
                phys = <&usbphy_0 0x0>;
+5 −1
Original line number Diff line number Diff line
@@ -4,10 +4,11 @@
$id: http://devicetree.org/schemas/usb/ingenic,jz4770-phy.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#

title: Ingenic JZ4770 USB PHY devicetree bindings
title: Ingenic SoCs USB PHY devicetree bindings

maintainers:
  - Paul Cercueil <paul@crapouillou.net>
  - 周琰杰 (Zhou Yanjie) <zhouyanjie@wanyeetech.com>

properties:
  $nodename:
@@ -16,6 +17,9 @@ properties:
  compatible:
    enum:
      - ingenic,jz4770-phy
      - ingenic,jz4780-phy
      - ingenic,x1000-phy
      - ingenic,x1830-phy

  reg:
    maxItems: 1
+37 −14
Original line number Diff line number Diff line
@@ -11,22 +11,36 @@ maintainers:

properties:
  compatible:
    oneOf:
      - const: "ti,keystone-dwc3"
      - const: "ti,am654-dwc3"
    items:
      - enum:
        - ti,keystone-dwc3
        - ti,am654-dwc3

  reg:
    maxItems: 1
    description: Address and length of the register set for the USB subsystem on
      the SOC.

  '#address-cells':
    const: 1

  '#size-cells':
    const: 1

  ranges: true

  interrupts:
    maxItems: 1
    description: The irq number of this device that is used to interrupt the MPU.


  clocks:
    description: Clock ID for USB functional clock.
    minItems: 1
    maxItems: 2

  assigned-clocks:
    minItems: 1
    maxItems: 2

  assigned-clock-parents:
    minItems: 1
    maxItems: 2

  power-domains:
    description: Should contain a phandle to a PM domain provider node
@@ -42,33 +56,42 @@ properties:

  phy-names:
    items:
      - const: "usb3-phy"
      - const: usb3-phy

  dma-coherent: true

  dwc3:
  dma-ranges: true

patternProperties:
  "usb@[a-f0-9]+$":
    type: object
    description: This is the node representing the DWC3 controller instance
      Documentation/devicetree/bindings/usb/dwc3.txt

required:
  - compatible
  - reg
  - "#address-cells"
  - "#size-cells"
  - ranges
  - interrupts
  - clocks

additionalProperties: false

examples:
  - |
    #include <dt-bindings/interrupt-controller/arm-gic.h>

    usb: usb@2680000 {
    dwc3@2680000 {
      compatible = "ti,keystone-dwc3";
      #address-cells = <1>;
      #size-cells = <1>;
      reg = <0x2680000 0x10000>;
      clocks = <&clkusb>;
      clock-names = "usb";
      interrupts = <GIC_SPI 393 IRQ_TYPE_EDGE_RISING>;
      ranges;

      dwc3@2690000 {
      usb@2690000 {
        compatible = "synopsys,dwc3";
        reg = <0x2690000 0x70000>;
        interrupts = <GIC_SPI 393 IRQ_TYPE_EDGE_RISING>;
+13 −26
Original line number Diff line number Diff line
@@ -27,13 +27,6 @@

static int cdns3_idle_init(struct cdns3 *cdns);

static inline
struct cdns3_role_driver *cdns3_get_current_role_driver(struct cdns3 *cdns)
{
	WARN_ON(!cdns->roles[cdns->role]);
	return cdns->roles[cdns->role];
}

static int cdns3_role_start(struct cdns3 *cdns, enum usb_role role)
{
	int ret;
@@ -93,7 +86,7 @@ static int cdns3_core_init_role(struct cdns3 *cdns)
	struct device *dev = cdns->dev;
	enum usb_dr_mode best_dr_mode;
	enum usb_dr_mode dr_mode;
	int ret = 0;
	int ret;

	dr_mode = usb_get_dr_mode(dev);
	cdns->role = USB_ROLE_NONE;
@@ -184,7 +177,7 @@ static int cdns3_core_init_role(struct cdns3 *cdns)
		goto err;
	}

	return ret;
	return 0;
err:
	cdns3_exit_roles(cdns);
	return ret;
@@ -198,11 +191,17 @@ err:
 */
static enum usb_role cdns3_hw_role_state_machine(struct cdns3 *cdns)
{
	enum usb_role role;
	enum usb_role role = USB_ROLE_NONE;
	int id, vbus;

	if (cdns->dr_mode != USB_DR_MODE_OTG)
		goto not_otg;
	if (cdns->dr_mode != USB_DR_MODE_OTG) {
		if (cdns3_is_host(cdns))
			role = USB_ROLE_HOST;
		if (cdns3_is_device(cdns))
			role = USB_ROLE_DEVICE;

		return role;
	}

	id = cdns3_get_id(cdns);
	vbus = cdns3_get_vbus(cdns);
@@ -239,14 +238,6 @@ static enum usb_role cdns3_hw_role_state_machine(struct cdns3 *cdns)
	dev_dbg(cdns->dev, "role %d -> %d\n", cdns->role, role);

	return role;

not_otg:
	if (cdns3_is_host(cdns))
		role = USB_ROLE_HOST;
	if (cdns3_is_device(cdns))
		role = USB_ROLE_DEVICE;

	return role;
}

static int cdns3_idle_role_start(struct cdns3 *cdns)
@@ -356,7 +347,6 @@ static int cdns3_role_set(struct usb_role_switch *sw, enum usb_role role)
		case USB_ROLE_HOST:
			break;
		default:
			ret = -EPERM;
			goto pm_put;
		}
	}
@@ -367,17 +357,14 @@ static int cdns3_role_set(struct usb_role_switch *sw, enum usb_role role)
		case USB_ROLE_DEVICE:
			break;
		default:
			ret = -EPERM;
			goto pm_put;
		}
	}

	cdns3_role_stop(cdns);
	ret = cdns3_role_start(cdns, role);
	if (ret) {
	if (ret)
		dev_err(cdns->dev, "set role %d has failed\n", role);
		ret = -EPERM;
	}

pm_put:
	pm_runtime_put_sync(cdns->dev);
@@ -402,7 +389,7 @@ static int cdns3_probe(struct platform_device *pdev)
	ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32));
	if (ret) {
		dev_err(dev, "error setting dma mask: %d\n", ret);
		return -ENODEV;
		return ret;
	}

	cdns = devm_kzalloc(dev, sizeof(*cdns), GFP_KERNEL);
+88 −77
Original line number Diff line number Diff line
@@ -29,7 +29,6 @@
 */
int cdns3_set_mode(struct cdns3 *cdns, enum usb_dr_mode mode)
{
	int ret = 0;
	u32 reg;

	switch (mode) {
@@ -61,7 +60,7 @@ int cdns3_set_mode(struct cdns3 *cdns, enum usb_dr_mode mode)
		return -EINVAL;
	}

	return ret;
	return 0;
}

int cdns3_get_id(struct cdns3 *cdns)
@@ -84,25 +83,25 @@ int cdns3_get_vbus(struct cdns3 *cdns)
	return vbus;
}

int cdns3_is_host(struct cdns3 *cdns)
bool cdns3_is_host(struct cdns3 *cdns)
{
	if (cdns->dr_mode == USB_DR_MODE_HOST)
		return 1;
	else if (!cdns3_get_id(cdns))
		return 1;
		return true;
	else if (cdns3_get_id(cdns) == CDNS3_ID_HOST)
		return true;

	return 0;
	return false;
}

int cdns3_is_device(struct cdns3 *cdns)
bool cdns3_is_device(struct cdns3 *cdns)
{
	if (cdns->dr_mode == USB_DR_MODE_PERIPHERAL)
		return 1;
		return true;
	else if (cdns->dr_mode == USB_DR_MODE_OTG)
		if (cdns3_get_id(cdns))
			return 1;
		if (cdns3_get_id(cdns) == CDNS3_ID_PERIPHERAL)
			return true;

	return 0;
	return false;
}

/**
@@ -125,56 +124,60 @@ static void cdns3_otg_enable_irq(struct cdns3 *cdns)
}

/**
 * cdns3_drd_switch_host - start/stop host
 * @cdns: Pointer to controller context structure
 * @on: 1 for start, 0 for stop
 * cdns3_drd_host_on - start host.
 * @cdns: Pointer to controller context structure.
 *
 * Returns 0 on success otherwise negative errno
 * Returns 0 on success otherwise negative errno.
 */
int cdns3_drd_switch_host(struct cdns3 *cdns, int on)
int cdns3_drd_host_on(struct cdns3 *cdns)
{
	int ret, val;
	u32 reg = OTGCMD_OTG_DIS;
	u32 val;
	int ret;

	/* switch OTG core */
	if (on) {
		writel(OTGCMD_HOST_BUS_REQ | reg, &cdns->otg_regs->cmd);
	/* Enable host mode. */
	writel(OTGCMD_HOST_BUS_REQ | OTGCMD_OTG_DIS,
	       &cdns->otg_regs->cmd);

	dev_dbg(cdns->dev, "Waiting till Host mode is turned on\n");
	ret = readl_poll_timeout_atomic(&cdns->otg_regs->sts, val,
						val & OTGSTS_XHCI_READY,
						1, 100000);
		if (ret) {
					val & OTGSTS_XHCI_READY, 1, 100000);

	if (ret)
		dev_err(cdns->dev, "timeout waiting for xhci_ready\n");

	return ret;
}
	} else {

/**
 * cdns3_drd_host_off - stop host.
 * @cdns: Pointer to controller context structure.
 */
void cdns3_drd_host_off(struct cdns3 *cdns)
{
	u32 val;

	writel(OTGCMD_HOST_BUS_DROP | OTGCMD_DEV_BUS_DROP |
	       OTGCMD_DEV_POWER_OFF | OTGCMD_HOST_POWER_OFF,
	       &cdns->otg_regs->cmd);

	/* Waiting till H_IDLE state.*/
	readl_poll_timeout_atomic(&cdns->otg_regs->state, val,
				  !(val & OTGSTATE_HOST_STATE_MASK),
				  1, 2000000);
}

	return 0;
}

/**
 * cdns3_drd_switch_gadget - start/stop gadget
 * @cdns: Pointer to controller context structure
 * @on: 1 for start, 0 for stop
 * cdns3_drd_gadget_on - start gadget.
 * @cdns: Pointer to controller context structure.
 *
 * Returns 0 on success otherwise negative errno
 */
int cdns3_drd_switch_gadget(struct cdns3 *cdns, int on)
int cdns3_drd_gadget_on(struct cdns3 *cdns)
{
	int ret, val;
	u32 reg = OTGCMD_OTG_DIS;

	/* switch OTG core */
	if (on) {
	writel(OTGCMD_DEV_BUS_REQ | reg, &cdns->otg_regs->cmd);

	dev_dbg(cdns->dev, "Waiting till Device mode is turned on\n");
@@ -186,10 +189,21 @@ int cdns3_drd_switch_gadget(struct cdns3 *cdns, int on)
		dev_err(cdns->dev, "timeout waiting for dev_ready\n");
		return ret;
	}
	} else {

	return 0;
}

/**
 * cdns3_drd_gadget_off - stop gadget.
 * @cdns: Pointer to controller context structure.
 */
void cdns3_drd_gadget_off(struct cdns3 *cdns)
{
	u32 val;

	/*
		 * driver should wait at least 10us after disabling Device
		 * before turning-off Device (DEV_BUS_DROP)
	 * Driver should wait at least 10us after disabling Device
	 * before turning-off Device (DEV_BUS_DROP).
	 */
	usleep_range(20, 30);
	writel(OTGCMD_HOST_BUS_DROP | OTGCMD_DEV_BUS_DROP |
@@ -201,9 +215,6 @@ int cdns3_drd_switch_gadget(struct cdns3 *cdns, int on)
				  1, 2000000);
}

	return 0;
}

/**
 * cdns3_init_otg_mode - initialize drd controller
 * @cdns: Pointer to controller context structure
@@ -212,7 +223,7 @@ int cdns3_drd_switch_gadget(struct cdns3 *cdns, int on)
 */
static int cdns3_init_otg_mode(struct cdns3 *cdns)
{
	int ret = 0;
	int ret;

	cdns3_otg_disable_irq(cdns);
	/* clear all interrupts */
@@ -223,7 +234,8 @@ static int cdns3_init_otg_mode(struct cdns3 *cdns)
		return ret;

	cdns3_otg_enable_irq(cdns);
	return ret;

	return 0;
}

/**
@@ -234,7 +246,7 @@ static int cdns3_init_otg_mode(struct cdns3 *cdns)
 */
int cdns3_drd_update_mode(struct cdns3 *cdns)
{
	int ret = 0;
	int ret;

	switch (cdns->dr_mode) {
	case USB_DR_MODE_PERIPHERAL:
@@ -279,12 +291,12 @@ static irqreturn_t cdns3_drd_irq(int irq, void *data)
	u32 reg;

	if (cdns->dr_mode != USB_DR_MODE_OTG)
		return ret;
		return IRQ_NONE;

	reg = readl(&cdns->otg_regs->ivect);

	if (!reg)
		return ret;
		return IRQ_NONE;

	if (reg & OTGIEN_ID_CHANGE_INT) {
		dev_dbg(cdns->dev, "OTG IRQ: new ID: %d\n",
@@ -307,8 +319,8 @@ static irqreturn_t cdns3_drd_irq(int irq, void *data)
int cdns3_drd_init(struct cdns3 *cdns)
{
	void __iomem *regs;
	int ret = 0;
	u32 state;
	int ret;

	regs = devm_ioremap_resource(cdns->dev, &cdns->otg_res);
	if (IS_ERR(regs))
@@ -359,19 +371,18 @@ int cdns3_drd_init(struct cdns3 *cdns)
					cdns3_drd_thread_irq,
					IRQF_SHARED,
					dev_name(cdns->dev), cdns);

	if (ret) {
		dev_err(cdns->dev, "couldn't get otg_irq\n");
		return ret;
	}

	state = readl(&cdns->otg_regs->sts);
	if (OTGSTS_OTG_NRDY(state) != 0) {
	if (OTGSTS_OTG_NRDY(state)) {
		dev_err(cdns->dev, "Cadence USB3 OTG device not ready\n");
		return -ENODEV;
	}

	return ret;
	return 0;
}

int cdns3_drd_exit(struct cdns3 *cdns)
Loading