diff options
author | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2017-10-24 14:03:12 +0200 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2017-10-24 14:03:12 +0200 |
commit | 2d5afd51fe6b469e09d8d63fff041cbf4a987278 (patch) | |
tree | 01ab99155c167c6203793e5c604e895d9af10588 /drivers/usb/gadget | |
parent | 0520d37bb3d49f8e62e30c80b001e0003b3f3ca9 (diff) | |
parent | ce2b21a4e5ce042c0a42c9db8fa9e0f849427d5e (diff) | |
download | blackbird-op-linux-2d5afd51fe6b469e09d8d63fff041cbf4a987278.tar.gz blackbird-op-linux-2d5afd51fe6b469e09d8d63fff041cbf4a987278.zip |
Merge tag 'usb-for-v4.15' of git://git.kernel.org/pub/scm/linux/kernel/git/balbi/usb into usb-next
Felipe writes:
usb: changes for v4.15 merge window
Not much going on this time around. With only 51 non-merge commits,
this was one of the smallest pull requests from the Gadget tree.
Most of the changes are in the mtu3 driver which added support for
36-bit DMA, support for USB 3.1 and support for dual-role (along with
some non-critical fixes).
The dwc2 driver got a few improvements to how we handle gadget state
tracking and also added support for STM32F7xx devices.
Other than that, we just some minor non-critical fixes and
improvements all over the place.
Diffstat (limited to 'drivers/usb/gadget')
-rw-r--r-- | drivers/usb/gadget/function/f_tcm.c | 1 | ||||
-rw-r--r-- | drivers/usb/gadget/function/u_serial.c | 1 | ||||
-rw-r--r-- | drivers/usb/gadget/function/uvc_v4l2.c | 2 | ||||
-rw-r--r-- | drivers/usb/gadget/function/uvc_v4l2.h | 2 | ||||
-rw-r--r-- | drivers/usb/gadget/udc/core.c | 2 | ||||
-rw-r--r-- | drivers/usb/gadget/udc/dummy_hcd.c | 65 | ||||
-rw-r--r-- | drivers/usb/gadget/udc/goku_udc.c | 14 | ||||
-rw-r--r-- | drivers/usb/gadget/udc/gr_udc.c | 2 | ||||
-rw-r--r-- | drivers/usb/gadget/udc/renesas_usb3.c | 71 |
9 files changed, 115 insertions, 45 deletions
diff --git a/drivers/usb/gadget/function/f_tcm.c b/drivers/usb/gadget/function/f_tcm.c index a82e2bd5ea34..c9d741dfeff4 100644 --- a/drivers/usb/gadget/function/f_tcm.c +++ b/drivers/usb/gadget/function/f_tcm.c @@ -1145,6 +1145,7 @@ static int usbg_submit_command(struct f_uas *fu, default: pr_debug_once("Unsupported prio_attr: %02x.\n", cmd_iu->prio_attr); + /* fall through */ case UAS_SIMPLE_TAG: cmd->prio_attr = TCM_SIMPLE_TAG; break; diff --git a/drivers/usb/gadget/function/u_serial.c b/drivers/usb/gadget/function/u_serial.c index 4176216d54be..961457ef5a1c 100644 --- a/drivers/usb/gadget/function/u_serial.c +++ b/drivers/usb/gadget/function/u_serial.c @@ -1078,6 +1078,7 @@ static void gs_complete_out(struct usb_ep *ep, struct usb_request *req) default: pr_warn("%s: unexpected %s status %d\n", __func__, ep->name, req->status); + /* fall through */ case 0: /* normal completion */ spin_lock(&info->con_lock); diff --git a/drivers/usb/gadget/function/uvc_v4l2.c b/drivers/usb/gadget/function/uvc_v4l2.c index 3e22b45687d3..66124024278b 100644 --- a/drivers/usb/gadget/function/uvc_v4l2.c +++ b/drivers/usb/gadget/function/uvc_v4l2.c @@ -354,7 +354,7 @@ static unsigned long uvcg_v4l2_get_unmapped_area(struct file *file, } #endif -struct v4l2_file_operations uvc_v4l2_fops = { +const struct v4l2_file_operations uvc_v4l2_fops = { .owner = THIS_MODULE, .open = uvc_v4l2_open, .release = uvc_v4l2_release, diff --git a/drivers/usb/gadget/function/uvc_v4l2.h b/drivers/usb/gadget/function/uvc_v4l2.h index 2683b92fda65..ad6ca0671740 100644 --- a/drivers/usb/gadget/function/uvc_v4l2.h +++ b/drivers/usb/gadget/function/uvc_v4l2.h @@ -17,6 +17,6 @@ #define __UVC_V4L2_H__ extern const struct v4l2_ioctl_ops uvc_v4l2_ioctl_ops; -extern struct v4l2_file_operations uvc_v4l2_fops; +extern const struct v4l2_file_operations uvc_v4l2_fops; #endif /* __UVC_V4L2_H__ */ diff --git a/drivers/usb/gadget/udc/core.c b/drivers/usb/gadget/udc/core.c index d41d07aae0ce..54b02eca0456 100644 --- a/drivers/usb/gadget/udc/core.c +++ b/drivers/usb/gadget/udc/core.c @@ -912,7 +912,7 @@ int usb_gadget_ep_match_desc(struct usb_gadget *gadget, return 0; type = usb_endpoint_type(desc); - max = 0x7ff & usb_endpoint_maxp(desc); + max = usb_endpoint_maxp(desc); if (usb_endpoint_dir_in(desc) && !ep->caps.dir_in) return 0; diff --git a/drivers/usb/gadget/udc/dummy_hcd.c b/drivers/usb/gadget/udc/dummy_hcd.c index 8f0f69783c8b..664b64eae834 100644 --- a/drivers/usb/gadget/udc/dummy_hcd.c +++ b/drivers/usb/gadget/udc/dummy_hcd.c @@ -23,6 +23,8 @@ * * Having this all in one kernel can help some stages of development, * bypassing some hardware (and driver) issues. UML could help too. + * + * Note: The emulation does not include isochronous transfers! */ #include <linux/module.h> @@ -137,6 +139,9 @@ static const struct { .caps = _caps, \ } +/* we don't provide isochronous endpoints since we don't support them */ +#define TYPE_BULK_OR_INT (USB_EP_CAPS_TYPE_BULK | USB_EP_CAPS_TYPE_INT) + /* everyone has ep0 */ EP_INFO(ep0name, USB_EP_CAPS(USB_EP_CAPS_TYPE_CONTROL, USB_EP_CAPS_DIR_ALL)), @@ -145,64 +150,72 @@ static const struct { USB_EP_CAPS(USB_EP_CAPS_TYPE_BULK, USB_EP_CAPS_DIR_IN)), EP_INFO("ep2out-bulk", USB_EP_CAPS(USB_EP_CAPS_TYPE_BULK, USB_EP_CAPS_DIR_OUT)), +/* EP_INFO("ep3in-iso", USB_EP_CAPS(USB_EP_CAPS_TYPE_ISO, USB_EP_CAPS_DIR_IN)), EP_INFO("ep4out-iso", USB_EP_CAPS(USB_EP_CAPS_TYPE_ISO, USB_EP_CAPS_DIR_OUT)), +*/ EP_INFO("ep5in-int", USB_EP_CAPS(USB_EP_CAPS_TYPE_INT, USB_EP_CAPS_DIR_IN)), EP_INFO("ep6in-bulk", USB_EP_CAPS(USB_EP_CAPS_TYPE_BULK, USB_EP_CAPS_DIR_IN)), EP_INFO("ep7out-bulk", USB_EP_CAPS(USB_EP_CAPS_TYPE_BULK, USB_EP_CAPS_DIR_OUT)), +/* EP_INFO("ep8in-iso", USB_EP_CAPS(USB_EP_CAPS_TYPE_ISO, USB_EP_CAPS_DIR_IN)), EP_INFO("ep9out-iso", USB_EP_CAPS(USB_EP_CAPS_TYPE_ISO, USB_EP_CAPS_DIR_OUT)), +*/ EP_INFO("ep10in-int", USB_EP_CAPS(USB_EP_CAPS_TYPE_INT, USB_EP_CAPS_DIR_IN)), EP_INFO("ep11in-bulk", USB_EP_CAPS(USB_EP_CAPS_TYPE_BULK, USB_EP_CAPS_DIR_IN)), EP_INFO("ep12out-bulk", USB_EP_CAPS(USB_EP_CAPS_TYPE_BULK, USB_EP_CAPS_DIR_OUT)), +/* EP_INFO("ep13in-iso", USB_EP_CAPS(USB_EP_CAPS_TYPE_ISO, USB_EP_CAPS_DIR_IN)), EP_INFO("ep14out-iso", USB_EP_CAPS(USB_EP_CAPS_TYPE_ISO, USB_EP_CAPS_DIR_OUT)), +*/ EP_INFO("ep15in-int", USB_EP_CAPS(USB_EP_CAPS_TYPE_INT, USB_EP_CAPS_DIR_IN)), + /* or like sa1100: two fixed function endpoints */ EP_INFO("ep1out-bulk", USB_EP_CAPS(USB_EP_CAPS_TYPE_BULK, USB_EP_CAPS_DIR_OUT)), EP_INFO("ep2in-bulk", USB_EP_CAPS(USB_EP_CAPS_TYPE_BULK, USB_EP_CAPS_DIR_IN)), + /* and now some generic EPs so we have enough in multi config */ EP_INFO("ep3out", - USB_EP_CAPS(USB_EP_CAPS_TYPE_ALL, USB_EP_CAPS_DIR_OUT)), + USB_EP_CAPS(TYPE_BULK_OR_INT, USB_EP_CAPS_DIR_OUT)), EP_INFO("ep4in", - USB_EP_CAPS(USB_EP_CAPS_TYPE_ALL, USB_EP_CAPS_DIR_IN)), + USB_EP_CAPS(TYPE_BULK_OR_INT, USB_EP_CAPS_DIR_IN)), EP_INFO("ep5out", - USB_EP_CAPS(USB_EP_CAPS_TYPE_ALL, USB_EP_CAPS_DIR_OUT)), + USB_EP_CAPS(TYPE_BULK_OR_INT, USB_EP_CAPS_DIR_OUT)), EP_INFO("ep6out", - USB_EP_CAPS(USB_EP_CAPS_TYPE_ALL, USB_EP_CAPS_DIR_OUT)), + USB_EP_CAPS(TYPE_BULK_OR_INT, USB_EP_CAPS_DIR_OUT)), EP_INFO("ep7in", - USB_EP_CAPS(USB_EP_CAPS_TYPE_ALL, USB_EP_CAPS_DIR_IN)), + USB_EP_CAPS(TYPE_BULK_OR_INT, USB_EP_CAPS_DIR_IN)), EP_INFO("ep8out", - USB_EP_CAPS(USB_EP_CAPS_TYPE_ALL, USB_EP_CAPS_DIR_OUT)), + USB_EP_CAPS(TYPE_BULK_OR_INT, USB_EP_CAPS_DIR_OUT)), EP_INFO("ep9in", - USB_EP_CAPS(USB_EP_CAPS_TYPE_ALL, USB_EP_CAPS_DIR_IN)), + USB_EP_CAPS(TYPE_BULK_OR_INT, USB_EP_CAPS_DIR_IN)), EP_INFO("ep10out", - USB_EP_CAPS(USB_EP_CAPS_TYPE_ALL, USB_EP_CAPS_DIR_OUT)), + USB_EP_CAPS(TYPE_BULK_OR_INT, USB_EP_CAPS_DIR_OUT)), EP_INFO("ep11out", - USB_EP_CAPS(USB_EP_CAPS_TYPE_ALL, USB_EP_CAPS_DIR_OUT)), + USB_EP_CAPS(TYPE_BULK_OR_INT, USB_EP_CAPS_DIR_OUT)), EP_INFO("ep12in", - USB_EP_CAPS(USB_EP_CAPS_TYPE_ALL, USB_EP_CAPS_DIR_IN)), + USB_EP_CAPS(TYPE_BULK_OR_INT, USB_EP_CAPS_DIR_IN)), EP_INFO("ep13out", - USB_EP_CAPS(USB_EP_CAPS_TYPE_ALL, USB_EP_CAPS_DIR_OUT)), + USB_EP_CAPS(TYPE_BULK_OR_INT, USB_EP_CAPS_DIR_OUT)), EP_INFO("ep14in", - USB_EP_CAPS(USB_EP_CAPS_TYPE_ALL, USB_EP_CAPS_DIR_IN)), + USB_EP_CAPS(TYPE_BULK_OR_INT, USB_EP_CAPS_DIR_IN)), EP_INFO("ep15out", - USB_EP_CAPS(USB_EP_CAPS_TYPE_ALL, USB_EP_CAPS_DIR_OUT)), + USB_EP_CAPS(TYPE_BULK_OR_INT, USB_EP_CAPS_DIR_OUT)), #undef EP_INFO }; @@ -1769,6 +1782,7 @@ static void dummy_timer(unsigned long _dum_hcd) int i; /* simplistic model for one frame's bandwidth */ + /* FIXME: account for transaction and packet overhead */ switch (dum->gadget.speed) { case USB_SPEED_LOW: total = 8/*bytes*/ * 12/*packets*/; @@ -1813,7 +1827,6 @@ restart: struct dummy_request *req; u8 address; struct dummy_ep *ep = NULL; - int type; int status = -EINPROGRESS; /* stop when we reach URBs queued after the timer interrupt */ @@ -1825,14 +1838,10 @@ restart: goto return_urb; else if (dum_hcd->rh_state != DUMMY_RH_RUNNING) continue; - type = usb_pipetype(urb->pipe); - /* used up this frame's non-periodic bandwidth? - * FIXME there's infinite bandwidth for control and - * periodic transfers ... unrealistic. - */ - if (total <= 0 && type == PIPE_BULK) - continue; + /* Used up this frame's bandwidth? */ + if (total <= 0) + break; /* find the gadget's ep for this request (if configured) */ address = usb_pipeendpoint (urb->pipe); @@ -1930,13 +1939,17 @@ restart: limit = total; switch (usb_pipetype(urb->pipe)) { case PIPE_ISOCHRONOUS: - /* FIXME is it urb->interval since the last xfer? - * use urb->iso_frame_desc[i]. - * complete whether or not ep has requests queued. - * report random errors, to debug drivers. + /* + * We don't support isochronous. But if we did, + * here are some of the issues we'd have to face: + * + * Is it urb->interval since the last xfer? + * Use urb->iso_frame_desc[i]. + * Complete whether or not ep has requests queued. + * Report random errors, to debug drivers. */ limit = max(limit, periodic_bytes(dum, ep)); - status = -ENOSYS; + status = -EINVAL; /* fail all xfers */ break; case PIPE_INTERRUPT: diff --git a/drivers/usb/gadget/udc/goku_udc.c b/drivers/usb/gadget/udc/goku_udc.c index 8433c22900dc..cccad51eb999 100644 --- a/drivers/usb/gadget/udc/goku_udc.c +++ b/drivers/usb/gadget/udc/goku_udc.c @@ -127,11 +127,15 @@ goku_ep_enable(struct usb_ep *_ep, const struct usb_endpoint_descriptor *desc) mode = 0; max = get_unaligned_le16(&desc->wMaxPacketSize); switch (max) { - case 64: mode++; - case 32: mode++; - case 16: mode++; - case 8: mode <<= 3; - break; + case 64: + mode++; /* fall through */ + case 32: + mode++; /* fall through */ + case 16: + mode++; /* fall through */ + case 8: + mode <<= 3; + break; default: return -EINVAL; } diff --git a/drivers/usb/gadget/udc/gr_udc.c b/drivers/usb/gadget/udc/gr_udc.c index 1f9941145746..48117a539146 100644 --- a/drivers/usb/gadget/udc/gr_udc.c +++ b/drivers/usb/gadget/udc/gr_udc.c @@ -1538,7 +1538,7 @@ static int gr_ep_enable(struct usb_ep *_ep, * Bits 10-0 set the max payload. 12-11 set the number of * additional transactions. */ - max = 0x7ff & usb_endpoint_maxp(desc); + max = usb_endpoint_maxp(desc); nt = usb_endpoint_maxp_mult(desc) - 1; buffer_size = GR_BUFFER_SIZE(epctrl); if (nt && (mode == 0 || mode == 2)) { diff --git a/drivers/usb/gadget/udc/renesas_usb3.c b/drivers/usb/gadget/udc/renesas_usb3.c index 63a206122058..4d9a40f452e1 100644 --- a/drivers/usb/gadget/udc/renesas_usb3.c +++ b/drivers/usb/gadget/udc/renesas_usb3.c @@ -1,7 +1,7 @@ /* * Renesas USB3.0 Peripheral driver (USB gadget) * - * Copyright (C) 2015 Renesas Electronics Corporation + * Copyright (C) 2015-2017 Renesas Electronics Corporation * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -17,6 +17,7 @@ #include <linux/io.h> #include <linux/module.h> #include <linux/of_device.h> +#include <linux/phy/phy.h> #include <linux/platform_device.h> #include <linux/pm_runtime.h> #include <linux/sizes.h> @@ -334,6 +335,7 @@ struct renesas_usb3 { struct usb_gadget_driver *driver; struct extcon_dev *extcon; struct work_struct extcon_work; + struct phy *phy; struct renesas_usb3_ep *usb3_ep; int num_usb3_eps; @@ -2239,7 +2241,9 @@ static int renesas_usb3_start(struct usb_gadget *gadget, /* hook up the driver */ usb3->driver = driver; - pm_runtime_enable(usb3_to_dev(usb3)); + if (usb3->phy) + phy_init(usb3->phy); + pm_runtime_get_sync(usb3_to_dev(usb3)); renesas_usb3_init_controller(usb3); @@ -2256,8 +2260,10 @@ static int renesas_usb3_stop(struct usb_gadget *gadget) usb3->driver = NULL; renesas_usb3_stop_controller(usb3); + if (usb3->phy) + phy_exit(usb3->phy); + pm_runtime_put(usb3_to_dev(usb3)); - pm_runtime_disable(usb3_to_dev(usb3)); return 0; } @@ -2405,6 +2411,9 @@ static int renesas_usb3_remove(struct platform_device *pdev) renesas_usb3_dma_free_prd(usb3, &pdev->dev); __renesas_usb3_ep_free_request(usb3->ep0_req); + if (usb3->phy) + phy_put(usb3->phy); + pm_runtime_disable(usb3_to_dev(usb3)); return 0; } @@ -2560,20 +2569,15 @@ static int renesas_usb3_probe(struct platform_device *pdev) { struct renesas_usb3 *usb3; struct resource *res; - const struct of_device_id *match; int irq, ret; const struct renesas_usb3_priv *priv; const struct soc_device_attribute *attr; - match = of_match_node(usb3_of_match, pdev->dev.of_node); - if (!match) - return -ENODEV; - attr = soc_device_match(renesas_usb3_quirks_match); if (attr) priv = attr->data; else - priv = match->data; + priv = of_device_get_match_data(&pdev->dev); irq = platform_get_irq(pdev, 0); if (irq < 0) { @@ -2635,11 +2639,20 @@ static int renesas_usb3_probe(struct platform_device *pdev) if (ret < 0) goto err_dev_create; + /* + * This is an optional. So, if this driver cannot get a phy, + * this driver will not handle a phy anymore. + */ + usb3->phy = devm_phy_get(&pdev->dev, "usb"); + if (IS_ERR(usb3->phy)) + usb3->phy = NULL; + usb3->workaround_for_vbus = priv->workaround_for_vbus; renesas_usb3_debugfs_init(usb3, &pdev->dev); - dev_info(&pdev->dev, "probed\n"); + dev_info(&pdev->dev, "probed%s\n", usb3->phy ? " with phy" : ""); + pm_runtime_enable(usb3_to_dev(usb3)); return 0; @@ -2655,11 +2668,49 @@ err_alloc_prd: return ret; } +#ifdef CONFIG_PM_SLEEP +static int renesas_usb3_suspend(struct device *dev) +{ + struct renesas_usb3 *usb3 = dev_get_drvdata(dev); + + /* Not started */ + if (!usb3->driver) + return 0; + + renesas_usb3_stop_controller(usb3); + if (usb3->phy) + phy_exit(usb3->phy); + pm_runtime_put(dev); + + return 0; +} + +static int renesas_usb3_resume(struct device *dev) +{ + struct renesas_usb3 *usb3 = dev_get_drvdata(dev); + + /* Not started */ + if (!usb3->driver) + return 0; + + if (usb3->phy) + phy_init(usb3->phy); + pm_runtime_get_sync(dev); + renesas_usb3_init_controller(usb3); + + return 0; +} +#endif + +static SIMPLE_DEV_PM_OPS(renesas_usb3_pm_ops, renesas_usb3_suspend, + renesas_usb3_resume); + static struct platform_driver renesas_usb3_driver = { .probe = renesas_usb3_probe, .remove = renesas_usb3_remove, .driver = { .name = (char *)udc_name, + .pm = &renesas_usb3_pm_ops, .of_match_table = of_match_ptr(usb3_of_match), }, }; |