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

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

Merge tag 'gadget-for-v3.4' of...

Merge tag 'gadget-for-v3.4' of git://git.kernel.org/pub/scm/linux/kernel/git/balbi/usb into usb-next

USB: Gadget: changes for 3.4

This merge is rather big. Here's what it contains:

For am5536udc we have just simple coding style fixes. Nothing that has any
potential to cause any issues going forward.

With mv_udc, there's only one single change removing an unneeded NULL check.

at91_udc also only saw a single change this merge window, and that's only
removing a duplicated header.

The Renesas controller has a few more involved changes. Support for SUDMAC was
added, there's now a special handling of IRQ resources for when the IRQ line is
shared between Renesas controller and SUDMAC, we also had a bug fix where
Renesas controller would sleep in atomic context while doing DMA transfers from
a tasklet. There were also a set of minor cleanups.

The FSL UDC also had a scheduling in atomic context bug fix, but that's all.

Thanks to Sebastian, the dummy_hcd now works better than ever with support for
scatterlists and streams. Sebastian also added SuperSpeed descriptors to the
serial gadgets.

The highlight on this merge is the addition of a generic API for mapping and
unmapping usb_requests. This will avoid code duplication on all UDC controllers
and also kills all the defines for DMA_ADDR_INVALID which UDC controllers
sprinkled around. A few of the UDC controllers were already converted to use
this new API.

Conflicts:
	drivers/usb/dwc3/gadget.c
parents 8062d94a 6440093f
Loading
Loading
Loading
Loading
+0 −2
Original line number Diff line number Diff line
@@ -572,7 +572,6 @@ struct dwc3_request {
 * @ctrl_req_addr: dma address of ctrl_req
 * @ep0_trb: dma address of ep0_trb
 * @ep0_usb_req: dummy req used while handling STD USB requests
 * @setup_buf_addr: dma address of setup_buf
 * @ep0_bounce_addr: dma address of ep0_bounce
 * @lock: for synchronizing
 * @dev: pointer to our struct device
@@ -609,7 +608,6 @@ struct dwc3 {
	u8			*setup_buf;
	dma_addr_t		ctrl_req_addr;
	dma_addr_t		ep0_trb_addr;
	dma_addr_t		setup_buf_addr;
	dma_addr_t		ep0_bounce_addr;
	struct dwc3_request	ep0_usb_req;
	/* device lock */
+13 −3
Original line number Diff line number Diff line
@@ -302,7 +302,7 @@ static int dwc3_ep0_handle_status(struct dwc3 *dwc,
	dep = dwc->eps[0];
	dwc->ep0_usb_req.dep = dep;
	dwc->ep0_usb_req.request.length = sizeof(*response_pkt);
	dwc->ep0_usb_req.request.dma = dwc->setup_buf_addr;
	dwc->ep0_usb_req.request.buf = dwc->setup_buf;
	dwc->ep0_usb_req.request.complete = dwc3_ep0_status_cmpl;

	return __dwc3_gadget_ep0_queue(dep, &dwc->ep0_usb_req);
@@ -679,7 +679,12 @@ static void dwc3_ep0_do_control_data(struct dwc3 *dwc,
				DWC3_TRBCTL_CONTROL_DATA);
	} else if ((req->request.length % dep->endpoint.maxpacket)
			&& (event->endpoint_number == 0)) {
		dwc3_map_buffer_to_dma(req);
		ret = usb_gadget_map_request(&dwc->gadget, &req->request,
				event->endpoint_number);
		if (ret) {
			dev_dbg(dwc->dev, "failed to map request\n");
			return;
		}

		WARN_ON(req->request.length > dep->endpoint.maxpacket);

@@ -694,7 +699,12 @@ static void dwc3_ep0_do_control_data(struct dwc3 *dwc,
				dwc->ep0_bounce_addr, dep->endpoint.maxpacket,
				DWC3_TRBCTL_CONTROL_DATA);
	} else {
		dwc3_map_buffer_to_dma(req);
		ret = usb_gadget_map_request(&dwc->gadget, &req->request,
				event->endpoint_number);
		if (ret) {
			dev_dbg(dwc->dev, "failed to map request\n");
			return;
		}

		ret = dwc3_ep0_start_trans(dwc, event->endpoint_number,
				req->request.dma, req->request.length,
+18 −76
Original line number Diff line number Diff line
@@ -54,70 +54,6 @@
#include "gadget.h"
#include "io.h"

#define	DMA_ADDR_INVALID	(~(dma_addr_t)0)

void dwc3_map_buffer_to_dma(struct dwc3_request *req)
{
	struct dwc3			*dwc = req->dep->dwc;

	if (req->request.length == 0) {
		/* req->request.dma = dwc->setup_buf_addr; */
		return;
	}

	if (req->request.num_sgs) {
		int	mapped;

		mapped = dma_map_sg(dwc->dev, req->request.sg,
				req->request.num_sgs,
				req->direction ? DMA_TO_DEVICE
				: DMA_FROM_DEVICE);
		if (mapped < 0) {
			dev_err(dwc->dev, "failed to map SGs\n");
			return;
		}

		req->request.num_mapped_sgs = mapped;
		return;
	}

	if (req->request.dma == DMA_ADDR_INVALID) {
		req->request.dma = dma_map_single(dwc->dev, req->request.buf,
				req->request.length, req->direction
				? DMA_TO_DEVICE : DMA_FROM_DEVICE);
		req->mapped = true;
	}
}

void dwc3_unmap_buffer_from_dma(struct dwc3_request *req)
{
	struct dwc3			*dwc = req->dep->dwc;

	if (req->request.length == 0) {
		req->request.dma = DMA_ADDR_INVALID;
		return;
	}

	if (req->request.num_mapped_sgs) {
		req->request.dma = DMA_ADDR_INVALID;
		dma_unmap_sg(dwc->dev, req->request.sg,
				req->request.num_mapped_sgs,
				req->direction ? DMA_TO_DEVICE
				: DMA_FROM_DEVICE);

		req->request.num_mapped_sgs = 0;
		return;
	}

	if (req->mapped) {
		dma_unmap_single(dwc->dev, req->request.dma,
				req->request.length, req->direction
				? DMA_TO_DEVICE : DMA_FROM_DEVICE);
		req->mapped = 0;
		req->request.dma = DMA_ADDR_INVALID;
	}
}

void dwc3_gadget_giveback(struct dwc3_ep *dep, struct dwc3_request *req,
		int status)
{
@@ -144,14 +80,15 @@ void dwc3_gadget_giveback(struct dwc3_ep *dep, struct dwc3_request *req,
	if (req->request.status == -EINPROGRESS)
		req->request.status = status;

	dwc3_unmap_buffer_from_dma(req);
	usb_gadget_unmap_request(&dwc->gadget, &req->request,
			req->direction);

	dev_dbg(dwc->dev, "request %p from %s completed %d/%d ===> %d\n",
			req, dep->name, req->request.actual,
			req->request.length, status);

	spin_unlock(&dwc->lock);
	req->request.complete(&req->dep->endpoint, &req->request);
	req->request.complete(&dep->endpoint, &req->request);
	spin_lock(&dwc->lock);
}

@@ -440,6 +377,7 @@ static int __dwc3_gadget_ep_disable(struct dwc3_ep *dep)

	dep->stream_capable = false;
	dep->desc = NULL;
	dep->endpoint.desc = NULL;
	dep->comp_desc = NULL;
	dep->type = 0;
	dep->flags = 0;
@@ -562,7 +500,6 @@ static struct usb_request *dwc3_gadget_ep_alloc_request(struct usb_ep *ep,

	req->epnum	= dep->number;
	req->dep	= dep;
	req->request.dma = DMA_ADDR_INVALID;

	return &req->request;
}
@@ -821,7 +758,8 @@ static int __dwc3_gadget_kick_transfer(struct dwc3_ep *dep, u16 cmd_param,
		 * here and stop, unmap, free and del each of the linked
		 * requests instead of we do now.
		 */
		dwc3_unmap_buffer_from_dma(req);
		usb_gadget_unmap_request(&dwc->gadget, &req->request,
				req->direction);
		list_del(&req->list);
		return ret;
	}
@@ -837,6 +775,9 @@ static int __dwc3_gadget_kick_transfer(struct dwc3_ep *dep, u16 cmd_param,

static int __dwc3_gadget_ep_queue(struct dwc3_ep *dep, struct dwc3_request *req)
{
	struct dwc3		*dwc = dep->dwc;
	int			ret;

	req->request.actual	= 0;
	req->request.status	= -EINPROGRESS;
	req->direction		= dep->direction;
@@ -854,7 +795,11 @@ static int __dwc3_gadget_ep_queue(struct dwc3_ep *dep, struct dwc3_request *req)
	 * This will also avoid Host cancelling URBs due to too
	 * many NACKs.
	 */
	dwc3_map_buffer_to_dma(req);
	ret = usb_gadget_map_request(&dwc->gadget, &req->request,
			dep->direction);
	if (ret)
		return ret;

	list_add_tail(&req->list, &dep->request_list);

	/*
@@ -2149,9 +2094,8 @@ int __devinit dwc3_gadget_init(struct dwc3 *dwc)
		goto err1;
	}

	dwc->setup_buf = dma_alloc_coherent(dwc->dev,
			sizeof(*dwc->setup_buf) * 2,
			&dwc->setup_buf_addr, GFP_KERNEL);
	dwc->setup_buf = kzalloc(sizeof(*dwc->setup_buf) * 2,
			GFP_KERNEL);
	if (!dwc->setup_buf) {
		dev_err(dwc->dev, "failed to allocate setup buffer\n");
		ret = -ENOMEM;
@@ -2242,8 +2186,7 @@ int __devinit dwc3_gadget_init(struct dwc3 *dwc)
			dwc->ep0_bounce_addr);

err3:
	dma_free_coherent(dwc->dev, sizeof(*dwc->setup_buf) * 2,
			dwc->setup_buf, dwc->setup_buf_addr);
	kfree(dwc->setup_buf);

err2:
	dma_free_coherent(dwc->dev, sizeof(*dwc->ep0_trb),
@@ -2272,8 +2215,7 @@ void dwc3_gadget_exit(struct dwc3 *dwc)
	dma_free_coherent(dwc->dev, 512, dwc->ep0_bounce,
			dwc->ep0_bounce_addr);

	dma_free_coherent(dwc->dev, sizeof(*dwc->setup_buf) * 2,
			dwc->setup_buf, dwc->setup_buf_addr);
	kfree(dwc->setup_buf);

	dma_free_coherent(dwc->dev, sizeof(*dwc->ep0_trb),
			dwc->ep0_trb, dwc->ep0_trb_addr);
+0 −2
Original line number Diff line number Diff line
@@ -108,8 +108,6 @@ int dwc3_gadget_ep0_queue(struct usb_ep *ep, struct usb_request *request,
int __dwc3_gadget_ep_set_halt(struct dwc3_ep *dep, int value);
int dwc3_send_gadget_ep_cmd(struct dwc3 *dwc, unsigned ep,
		unsigned cmd, struct dwc3_gadget_ep_cmd_params *params);
void dwc3_map_buffer_to_dma(struct dwc3_request *req);
void dwc3_unmap_buffer_from_dma(struct dwc3_request *req);

/**
 * dwc3_gadget_ep_get_transfer_index - Gets transfer index from HW
+19 −6
Original line number Diff line number Diff line
@@ -599,16 +599,29 @@ config USB_AUDIO
	depends on SND
	select SND_PCM
	help
	  Gadget Audio is compatible with USB Audio Class specification 1.0.
	  It will include at least one AudioControl interface, zero or more
	  AudioStream interface and zero or more MIDIStream interface.

	  Gadget Audio will use on-board ALSA (CONFIG_SND) audio card to
	  playback or capture audio stream.
	  This Gadget Audio driver is compatible with USB Audio Class
	  specification 2.0. It implements 1 AudioControl interface,
	  1 AudioStreaming Interface each for USB-OUT and USB-IN.
	  Number of channels, sample rate and sample size can be
	  specified as module parameters.
	  This driver doesn't expect any real Audio codec to be present
	  on the device - the audio streams are simply sinked to and
	  sourced from a virtual ALSA sound card created. The user-space
	  application may choose to do whatever it wants with the data
	  received from the USB Host and choose to provide whatever it
	  wants as audio data to the USB Host.

	  Say "y" to link the driver statically, or "m" to build a
	  dynamically linked module called "g_audio".

config GADGET_UAC1
	bool "UAC 1.0 (Legacy)"
	depends on USB_AUDIO
	help
	  If you instead want older UAC Spec-1.0 driver that also has audio
	  paths hardwired to the Audio codec chip on-board and doesn't work
	  without one.

config USB_ETH
	tristate "Ethernet Gadget (with CDC Ethernet support)"
	depends on NET
Loading