~sircmpwn/linux

4ae8beac0abb9c3bbbb8340bab46eb287aea3001 — Greg Kroah-Hartman 1 year, 2 days ago d6d5df1 + f3fb802
Merge tag 'fixes-for-v5.4-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/balbi/usb into usb-linus

Felipe writes:

USB: fixes for v5.4-rc5

Not much here, only 14 commits in different drivers.

As for the specifics, Roger Quadros fixed an important bug in cdns3
where the driver was making decisions about data pull-up management
behind the UDC framework's back.

The Atmel UDC got a fix for interrupt storm in FIFO mode, this was done
by Cristian Brisan.

Apart from these, we have the usual set of non-critical fixes.

Signed-off-by: Felipe Balbi <balbi@kernel.org>

* tag 'fixes-for-v5.4-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/balbi/usb:
  usb: cdns3: gadget: Don't manage pullups
  usb: dwc3: remove the call trace of USBx_GFLADJ
  usb: gadget: configfs: fix concurrent issue between composite APIs
  usb: dwc3: pci: prevent memory leak in dwc3_pci_probe
  usb: gadget: composite: Fix possible double free memory bug
  usb: gadget: udc: atmel: Fix interrupt storm in FIFO mode.
  usb: renesas_usbhs: fix type of buf
  usb: renesas_usbhs: Fix warnings in usbhsg_recip_handler_std_set_device()
  usb: gadget: udc: renesas_usb3: Fix __le16 warnings
  usb: renesas_usbhs: fix __le16 warnings
  usb: cdns3: include host-export,h for cdns3_host_init
  usb: mtu3: fix missing include of mtu3_dr.h
  usb: fsl: Check memory resource before releasing it
  usb: dwc3: select CONFIG_REGMAP_MMIO
M drivers/usb/cdns3/gadget.c => drivers/usb/cdns3/gadget.c +0 -4
@@ 2329,8 2329,6 @@ static void cdns3_gadget_config(struct cdns3_device *priv_dev)
	writel(USB_CONF_CLK2OFFDS | USB_CONF_L1DS, &regs->usb_conf);

	cdns3_configure_dmult(priv_dev, NULL);

	cdns3_gadget_pullup(&priv_dev->gadget, 1);
}

/**


@@ 2713,8 2711,6 @@ static int cdns3_gadget_suspend(struct cdns3 *cdns, bool do_wakeup)
	/* disable interrupt for device */
	writel(0, &priv_dev->regs->usb_ien);

	cdns3_gadget_pullup(&priv_dev->gadget, 0);

	return 0;
}


M drivers/usb/cdns3/host-export.h => drivers/usb/cdns3/host-export.h +0 -1
@@ 12,7 12,6 @@
#ifdef CONFIG_USB_CDNS3_HOST

int cdns3_host_init(struct cdns3 *cdns);
void cdns3_host_exit(struct cdns3 *cdns);

#else


M drivers/usb/cdns3/host.c => drivers/usb/cdns3/host.c +1 -0
@@ 12,6 12,7 @@
#include <linux/platform_device.h>
#include "core.h"
#include "drd.h"
#include "host-export.h"

static int __cdns3_host_init(struct cdns3 *cdns)
{

M drivers/usb/dwc3/Kconfig => drivers/usb/dwc3/Kconfig +1 -0
@@ 102,6 102,7 @@ config USB_DWC3_MESON_G12A
       depends on ARCH_MESON || COMPILE_TEST
       default USB_DWC3
       select USB_ROLE_SWITCH
	select REGMAP_MMIO
       help
         Support USB2/3 functionality in Amlogic G12A platforms.
	 Say 'Y' or 'M' if you have one such device.

M drivers/usb/dwc3/core.c => drivers/usb/dwc3/core.c +1 -2
@@ 312,8 312,7 @@ static void dwc3_frame_length_adjustment(struct dwc3 *dwc)

	reg = dwc3_readl(dwc->regs, DWC3_GFLADJ);
	dft = reg & DWC3_GFLADJ_30MHZ_MASK;
	if (!dev_WARN_ONCE(dwc->dev, dft == dwc->fladj,
	    "request value same as default, ignoring\n")) {
	if (dft != dwc->fladj) {
		reg &= ~DWC3_GFLADJ_30MHZ_MASK;
		reg |= DWC3_GFLADJ_30MHZ_SDBND_SEL | dwc->fladj;
		dwc3_writel(dwc->regs, DWC3_GFLADJ, reg);

M drivers/usb/dwc3/dwc3-pci.c => drivers/usb/dwc3/dwc3-pci.c +1 -1
@@ 258,7 258,7 @@ static int dwc3_pci_probe(struct pci_dev *pci, const struct pci_device_id *id)

	ret = platform_device_add_properties(dwc->dwc3, p);
	if (ret < 0)
		return ret;
		goto err;

	ret = dwc3_pci_quirks(dwc);
	if (ret)

M drivers/usb/gadget/composite.c => drivers/usb/gadget/composite.c +4 -0
@@ 2170,14 2170,18 @@ void composite_dev_cleanup(struct usb_composite_dev *cdev)
			usb_ep_dequeue(cdev->gadget->ep0, cdev->os_desc_req);

		kfree(cdev->os_desc_req->buf);
		cdev->os_desc_req->buf = NULL;
		usb_ep_free_request(cdev->gadget->ep0, cdev->os_desc_req);
		cdev->os_desc_req = NULL;
	}
	if (cdev->req) {
		if (cdev->setup_pending)
			usb_ep_dequeue(cdev->gadget->ep0, cdev->req);

		kfree(cdev->req->buf);
		cdev->req->buf = NULL;
		usb_ep_free_request(cdev->gadget->ep0, cdev->req);
		cdev->req = NULL;
	}
	cdev->next_string_id = 0;
	device_remove_file(&cdev->gadget->dev, &dev_attr_suspended);

M drivers/usb/gadget/configfs.c => drivers/usb/gadget/configfs.c +105 -5
@@ 61,6 61,8 @@ struct gadget_info {
	bool use_os_desc;
	char b_vendor_code;
	char qw_sign[OS_STRING_QW_SIGN_LEN];
	spinlock_t spinlock;
	bool unbind;
};

static inline struct gadget_info *to_gadget_info(struct config_item *item)


@@ 1244,6 1246,7 @@ static int configfs_composite_bind(struct usb_gadget *gadget,
	int				ret;

	/* the gi->lock is hold by the caller */
	gi->unbind = 0;
	cdev->gadget = gadget;
	set_gadget_data(gadget, cdev);
	ret = composite_dev_prepare(composite, cdev);


@@ 1376,31 1379,128 @@ static void configfs_composite_unbind(struct usb_gadget *gadget)
{
	struct usb_composite_dev	*cdev;
	struct gadget_info		*gi;
	unsigned long flags;

	/* the gi->lock is hold by the caller */

	cdev = get_gadget_data(gadget);
	gi = container_of(cdev, struct gadget_info, cdev);
	spin_lock_irqsave(&gi->spinlock, flags);
	gi->unbind = 1;
	spin_unlock_irqrestore(&gi->spinlock, flags);

	kfree(otg_desc[0]);
	otg_desc[0] = NULL;
	purge_configs_funcs(gi);
	composite_dev_cleanup(cdev);
	usb_ep_autoconfig_reset(cdev->gadget);
	spin_lock_irqsave(&gi->spinlock, flags);
	cdev->gadget = NULL;
	set_gadget_data(gadget, NULL);
	spin_unlock_irqrestore(&gi->spinlock, flags);
}

static int configfs_composite_setup(struct usb_gadget *gadget,
		const struct usb_ctrlrequest *ctrl)
{
	struct usb_composite_dev *cdev;
	struct gadget_info *gi;
	unsigned long flags;
	int ret;

	cdev = get_gadget_data(gadget);
	if (!cdev)
		return 0;

	gi = container_of(cdev, struct gadget_info, cdev);
	spin_lock_irqsave(&gi->spinlock, flags);
	cdev = get_gadget_data(gadget);
	if (!cdev || gi->unbind) {
		spin_unlock_irqrestore(&gi->spinlock, flags);
		return 0;
	}

	ret = composite_setup(gadget, ctrl);
	spin_unlock_irqrestore(&gi->spinlock, flags);
	return ret;
}

static void configfs_composite_disconnect(struct usb_gadget *gadget)
{
	struct usb_composite_dev *cdev;
	struct gadget_info *gi;
	unsigned long flags;

	cdev = get_gadget_data(gadget);
	if (!cdev)
		return;

	gi = container_of(cdev, struct gadget_info, cdev);
	spin_lock_irqsave(&gi->spinlock, flags);
	cdev = get_gadget_data(gadget);
	if (!cdev || gi->unbind) {
		spin_unlock_irqrestore(&gi->spinlock, flags);
		return;
	}

	composite_disconnect(gadget);
	spin_unlock_irqrestore(&gi->spinlock, flags);
}

static void configfs_composite_suspend(struct usb_gadget *gadget)
{
	struct usb_composite_dev *cdev;
	struct gadget_info *gi;
	unsigned long flags;

	cdev = get_gadget_data(gadget);
	if (!cdev)
		return;

	gi = container_of(cdev, struct gadget_info, cdev);
	spin_lock_irqsave(&gi->spinlock, flags);
	cdev = get_gadget_data(gadget);
	if (!cdev || gi->unbind) {
		spin_unlock_irqrestore(&gi->spinlock, flags);
		return;
	}

	composite_suspend(gadget);
	spin_unlock_irqrestore(&gi->spinlock, flags);
}

static void configfs_composite_resume(struct usb_gadget *gadget)
{
	struct usb_composite_dev *cdev;
	struct gadget_info *gi;
	unsigned long flags;

	cdev = get_gadget_data(gadget);
	if (!cdev)
		return;

	gi = container_of(cdev, struct gadget_info, cdev);
	spin_lock_irqsave(&gi->spinlock, flags);
	cdev = get_gadget_data(gadget);
	if (!cdev || gi->unbind) {
		spin_unlock_irqrestore(&gi->spinlock, flags);
		return;
	}

	composite_resume(gadget);
	spin_unlock_irqrestore(&gi->spinlock, flags);
}

static const struct usb_gadget_driver configfs_driver_template = {
	.bind           = configfs_composite_bind,
	.unbind         = configfs_composite_unbind,

	.setup          = composite_setup,
	.reset          = composite_disconnect,
	.disconnect     = composite_disconnect,
	.setup          = configfs_composite_setup,
	.reset          = configfs_composite_disconnect,
	.disconnect     = configfs_composite_disconnect,

	.suspend	= composite_suspend,
	.resume		= composite_resume,
	.suspend	= configfs_composite_suspend,
	.resume		= configfs_composite_resume,

	.max_speed	= USB_SPEED_SUPER,
	.driver = {

M drivers/usb/gadget/udc/atmel_usba_udc.c => drivers/usb/gadget/udc/atmel_usba_udc.c +4 -2
@@ 449,9 449,11 @@ static void submit_request(struct usba_ep *ep, struct usba_request *req)
		next_fifo_transaction(ep, req);
		if (req->last_transaction) {
			usba_ep_writel(ep, CTL_DIS, USBA_TX_PK_RDY);
			usba_ep_writel(ep, CTL_ENB, USBA_TX_COMPLETE);
			if (ep_is_control(ep))
				usba_ep_writel(ep, CTL_ENB, USBA_TX_COMPLETE);
		} else {
			usba_ep_writel(ep, CTL_DIS, USBA_TX_COMPLETE);
			if (ep_is_control(ep))
				usba_ep_writel(ep, CTL_DIS, USBA_TX_COMPLETE);
			usba_ep_writel(ep, CTL_ENB, USBA_TX_PK_RDY);
		}
	}

M drivers/usb/gadget/udc/fsl_udc_core.c => drivers/usb/gadget/udc/fsl_udc_core.c +1 -1
@@ 2576,7 2576,7 @@ static int fsl_udc_remove(struct platform_device *pdev)
	dma_pool_destroy(udc_controller->td_pool);
	free_irq(udc_controller->irq, udc_controller);
	iounmap(dr_regs);
	if (pdata->operating_mode == FSL_USB2_DR_DEVICE)
	if (res && (pdata->operating_mode == FSL_USB2_DR_DEVICE))
		release_mem_region(res->start, resource_size(res));

	/* free udc --wait for the release() finished */

M drivers/usb/gadget/udc/renesas_usb3.c => drivers/usb/gadget/udc/renesas_usb3.c +6 -5
@@ 1544,10 1544,10 @@ static void usb3_set_device_address(struct renesas_usb3 *usb3, u16 addr)
static bool usb3_std_req_set_address(struct renesas_usb3 *usb3,
				     struct usb_ctrlrequest *ctrl)
{
	if (ctrl->wValue >= 128)
	if (le16_to_cpu(ctrl->wValue) >= 128)
		return true;	/* stall */

	usb3_set_device_address(usb3, ctrl->wValue);
	usb3_set_device_address(usb3, le16_to_cpu(ctrl->wValue));
	usb3_set_p0_con_for_no_data(usb3);

	return false;


@@ 1582,6 1582,7 @@ static bool usb3_std_req_get_status(struct renesas_usb3 *usb3,
	struct renesas_usb3_ep *usb3_ep;
	int num;
	u16 status = 0;
	__le16 tx_data;

	switch (ctrl->bRequestType & USB_RECIP_MASK) {
	case USB_RECIP_DEVICE:


@@ 1604,10 1605,10 @@ static bool usb3_std_req_get_status(struct renesas_usb3 *usb3,
	}

	if (!stall) {
		status = cpu_to_le16(status);
		tx_data = cpu_to_le16(status);
		dev_dbg(usb3_to_dev(usb3), "get_status: req = %p\n",
			usb_req_to_usb3_req(usb3->ep0_req));
		usb3_pipe0_internal_xfer(usb3, &status, sizeof(status),
		usb3_pipe0_internal_xfer(usb3, &tx_data, sizeof(tx_data),
					 usb3_pipe0_get_status_completion);
	}



@@ 1772,7 1773,7 @@ static bool usb3_std_req_set_sel(struct renesas_usb3 *usb3,
static bool usb3_std_req_set_configuration(struct renesas_usb3 *usb3,
					   struct usb_ctrlrequest *ctrl)
{
	if (ctrl->wValue > 0)
	if (le16_to_cpu(ctrl->wValue) > 0)
		usb3_set_bit(usb3, USB_COM_CON_CONF, USB3_USB_COM_CON);
	else
		usb3_clear_bit(usb3, USB_COM_CON_CONF, USB3_USB_COM_CON);

M drivers/usb/mtu3/mtu3_core.c => drivers/usb/mtu3/mtu3_core.c +1 -0
@@ 16,6 16,7 @@
#include <linux/platform_device.h>

#include "mtu3.h"
#include "mtu3_dr.h"
#include "mtu3_debug.h"
#include "mtu3_trace.h"


M drivers/usb/renesas_usbhs/common.c => drivers/usb/renesas_usbhs/common.c +6 -6
@@ 162,17 162,17 @@ void usbhs_usbreq_get_val(struct usbhs_priv *priv, struct usb_ctrlrequest *req)
	req->bRequest		= (val >> 8) & 0xFF;
	req->bRequestType	= (val >> 0) & 0xFF;

	req->wValue	= usbhs_read(priv, USBVAL);
	req->wIndex	= usbhs_read(priv, USBINDX);
	req->wLength	= usbhs_read(priv, USBLENG);
	req->wValue	= cpu_to_le16(usbhs_read(priv, USBVAL));
	req->wIndex	= cpu_to_le16(usbhs_read(priv, USBINDX));
	req->wLength	= cpu_to_le16(usbhs_read(priv, USBLENG));
}

void usbhs_usbreq_set_val(struct usbhs_priv *priv, struct usb_ctrlrequest *req)
{
	usbhs_write(priv, USBREQ,  (req->bRequest << 8) | req->bRequestType);
	usbhs_write(priv, USBVAL,  req->wValue);
	usbhs_write(priv, USBINDX, req->wIndex);
	usbhs_write(priv, USBLENG, req->wLength);
	usbhs_write(priv, USBVAL,  le16_to_cpu(req->wValue));
	usbhs_write(priv, USBINDX, le16_to_cpu(req->wIndex));
	usbhs_write(priv, USBLENG, le16_to_cpu(req->wLength));

	usbhs_bset(priv, DCPCTR, SUREQ, SUREQ);
}

M drivers/usb/renesas_usbhs/mod_gadget.c => drivers/usb/renesas_usbhs/mod_gadget.c +2 -2
@@ 265,7 265,7 @@ static int usbhsg_recip_handler_std_set_device(struct usbhs_priv *priv,
	case USB_DEVICE_TEST_MODE:
		usbhsg_recip_handler_std_control_done(priv, uep, ctrl);
		udelay(100);
		usbhs_sys_set_test_mode(priv, le16_to_cpu(ctrl->wIndex >> 8));
		usbhs_sys_set_test_mode(priv, le16_to_cpu(ctrl->wIndex) >> 8);
		break;
	default:
		usbhsg_recip_handler_std_control_done(priv, uep, ctrl);


@@ 315,7 315,7 @@ static void __usbhsg_recip_send_status(struct usbhsg_gpriv *gpriv,
	struct usbhs_pipe *pipe = usbhsg_uep_to_pipe(dcp);
	struct device *dev = usbhsg_gpriv_to_dev(gpriv);
	struct usb_request *req;
	unsigned short *buf;
	__le16 *buf;

	/* alloc new usb_request for recip */
	req = usb_ep_alloc_request(&dcp->ep, GFP_ATOMIC);