diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2018-04-05 03:55:35 +0300 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2018-04-05 03:55:35 +0300 |
commit | ac9053d2dcb9e8c3fa35ce458dfca8fddc141680 (patch) | |
tree | 3ffa30d58dac22ee0a80e2dd32f41b71da91132b /drivers/usb/gadget | |
parent | f9ca6a561d40115696a54f16085c4edb17effc74 (diff) | |
parent | 5267c5e09c25e2ee6242b37833a9bdf9d97f54a2 (diff) | |
download | linux-ac9053d2dcb9e8c3fa35ce458dfca8fddc141680.tar.xz |
Merge tag 'usb-4.17-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb
Pull USB/PHY updates from Greg KH:
"Here is the big set of USB and PHY driver patches for 4.17-rc1.
Lots of USB typeC work happened this round, with code moving from the
staging directory into the "real" part of the kernel, as well as new
infrastructure being added to be able to handle the different types of
"roles" that typeC requires.
There is also the normal huge set of USB gadget controller and driver
updates, along with XHCI changes, and a raft of other tiny fixes all
over the USB tree. And the PHY driver updates are merged in here as
well as they interacted with the USB drivers in some places.
All of these have been in linux-next for a while with no reported
issues"
* tag 'usb-4.17-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb: (250 commits)
Revert "USB: serial: ftdi_sio: add Id for Physik Instrumente E-870"
usb: musb: gadget: misplaced out of bounds check
usb: chipidea: imx: Fix ULPI on imx53
usb: chipidea: imx: Cleanup ci_hdrc_imx_platform_flag
usb: chipidea: usbmisc: small clean up
usb: chipidea: usbmisc: evdo can be set e/o reset
usb: chipidea: usbmisc: evdo is only specific to OTG port
USB: serial: ftdi_sio: add Id for Physik Instrumente E-870
usb: dwc3: gadget: never call ->complete() from ->ep_queue()
usb: gadget: udc: core: update usb_ep_queue() documentation
usb: host: Remove the deprecated ATH79 USB host config options
usb: roles: Fix return value check in intel_xhci_usb_probe()
USB: gadget: f_midi: fixing a possible double-free in f_midi
usb: core: Add USB_QUIRK_DELAY_CTRL_MSG to usbcore quirks
usb: core: Copy parameter string correctly and remove superfluous null check
USB: announce bcdDevice as well as idVendor, idProduct.
USB:fix USB3 devices behind USB3 hubs not resuming at hibernate thaw
usb: hub: Reduce warning to notice on power loss
USB: serial: ftdi_sio: add support for Harman FirmwareHubEmulator
USB: serial: cp210x: add ELDAT Easywave RX09 id
...
Diffstat (limited to 'drivers/usb/gadget')
-rw-r--r-- | drivers/usb/gadget/composite.c | 126 | ||||
-rw-r--r-- | drivers/usb/gadget/function/f_fs.c | 6 | ||||
-rw-r--r-- | drivers/usb/gadget/function/f_midi.c | 3 | ||||
-rw-r--r-- | drivers/usb/gadget/function/f_tcm.c | 2 | ||||
-rw-r--r-- | drivers/usb/gadget/legacy/mass_storage.c | 2 | ||||
-rw-r--r-- | drivers/usb/gadget/u_f.h | 2 | ||||
-rw-r--r-- | drivers/usb/gadget/udc/atmel_usba_udc.c | 158 | ||||
-rw-r--r-- | drivers/usb/gadget/udc/atmel_usba_udc.h | 4 | ||||
-rw-r--r-- | drivers/usb/gadget/udc/bcm63xx_udc.c | 33 | ||||
-rw-r--r-- | drivers/usb/gadget/udc/bdc/bdc_ep.c | 3 | ||||
-rw-r--r-- | drivers/usb/gadget/udc/core.c | 7 | ||||
-rw-r--r-- | drivers/usb/gadget/udc/dummy_hcd.c | 2 | ||||
-rw-r--r-- | drivers/usb/gadget/udc/goku_udc.h | 2 | ||||
-rw-r--r-- | drivers/usb/gadget/udc/gr_udc.c | 17 | ||||
-rw-r--r-- | drivers/usb/gadget/udc/pxa25x_udc.c | 20 | ||||
-rw-r--r-- | drivers/usb/gadget/udc/pxa27x_udc.c | 42 |
16 files changed, 127 insertions, 302 deletions
diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c index 77c7ecca816a..63a7cb87514a 100644 --- a/drivers/usb/gadget/composite.c +++ b/drivers/usb/gadget/composite.c @@ -1422,11 +1422,12 @@ static int count_ext_compat(struct usb_configuration *c) return res; } -static void fill_ext_compat(struct usb_configuration *c, u8 *buf) +static int fill_ext_compat(struct usb_configuration *c, u8 *buf) { int i, count; count = 16; + buf += 16; for (i = 0; i < c->next_interface_id; ++i) { struct usb_function *f; int j; @@ -1449,10 +1450,12 @@ static void fill_ext_compat(struct usb_configuration *c, u8 *buf) buf += 23; } count += 24; - if (count >= 4096) - return; + if (count + 24 >= USB_COMP_EP0_OS_DESC_BUFSIZ) + return count; } } + + return count; } static int count_ext_prop(struct usb_configuration *c, int interface) @@ -1497,25 +1500,21 @@ static int fill_ext_prop(struct usb_configuration *c, int interface, u8 *buf) struct usb_os_desc *d; struct usb_os_desc_ext_prop *ext_prop; int j, count, n, ret; - u8 *start = buf; f = c->interface[interface]; + count = 10; /* header length */ + buf += 10; for (j = 0; j < f->os_desc_n; ++j) { if (interface != f->os_desc_table[j].if_id) continue; d = f->os_desc_table[j].os_desc; if (d) list_for_each_entry(ext_prop, &d->ext_prop, entry) { - /* 4kB minus header length */ - n = buf - start; - if (n >= 4086) - return 0; - - count = ext_prop->data_len + + n = ext_prop->data_len + ext_prop->name_len + 14; - if (count > 4086 - n) - return -EINVAL; - usb_ext_prop_put_size(buf, count); + if (count + n >= USB_COMP_EP0_OS_DESC_BUFSIZ) + return count; + usb_ext_prop_put_size(buf, n); usb_ext_prop_put_type(buf, ext_prop->type); ret = usb_ext_prop_put_name(buf, ext_prop->name, ext_prop->name_len); @@ -1541,11 +1540,12 @@ static int fill_ext_prop(struct usb_configuration *c, int interface, u8 *buf) default: return -EINVAL; } - buf += count; + buf += n; + count += n; } } - return 0; + return count; } /* @@ -1827,6 +1827,7 @@ unknown: req->complete = composite_setup_complete; buf = req->buf; os_desc_cfg = cdev->os_desc_config; + w_length = min_t(u16, w_length, USB_COMP_EP0_OS_DESC_BUFSIZ); memset(buf, 0, w_length); buf[5] = 0x01; switch (ctrl->bRequestType & USB_RECIP_MASK) { @@ -1834,24 +1835,16 @@ unknown: if (w_index != 0x4 || (w_value >> 8)) break; buf[6] = w_index; - if (w_length == 0x10) { - /* Number of ext compat interfaces */ - count = count_ext_compat(os_desc_cfg); - buf[8] = count; - count *= 24; /* 24 B/ext compat desc */ - count += 16; /* header */ - put_unaligned_le32(count, buf); - value = w_length; - } else { - /* "extended compatibility ID"s */ - count = count_ext_compat(os_desc_cfg); - buf[8] = count; - count *= 24; /* 24 B/ext compat desc */ - count += 16; /* header */ - put_unaligned_le32(count, buf); - buf += 16; - fill_ext_compat(os_desc_cfg, buf); - value = w_length; + /* Number of ext compat interfaces */ + count = count_ext_compat(os_desc_cfg); + buf[8] = count; + count *= 24; /* 24 B/ext compat desc */ + count += 16; /* header */ + put_unaligned_le32(count, buf); + value = w_length; + if (w_length > 0x10) { + value = fill_ext_compat(os_desc_cfg, buf); + value = min_t(u16, w_length, value); } break; case USB_RECIP_INTERFACE: @@ -1859,47 +1852,23 @@ unknown: break; interface = w_value & 0xFF; buf[6] = w_index; - if (w_length == 0x0A) { - count = count_ext_prop(os_desc_cfg, - interface); - put_unaligned_le16(count, buf + 8); - count = len_ext_prop(os_desc_cfg, - interface); - put_unaligned_le32(count, buf); - - value = w_length; - } else { - count = count_ext_prop(os_desc_cfg, - interface); - put_unaligned_le16(count, buf + 8); - count = len_ext_prop(os_desc_cfg, - interface); - put_unaligned_le32(count, buf); - buf += 10; + count = count_ext_prop(os_desc_cfg, + interface); + put_unaligned_le16(count, buf + 8); + count = len_ext_prop(os_desc_cfg, + interface); + put_unaligned_le32(count, buf); + value = w_length; + if (w_length > 0x0A) { value = fill_ext_prop(os_desc_cfg, interface, buf); - if (value < 0) - return value; - - value = w_length; + if (value >= 0) + value = min_t(u16, w_length, value); } break; } - if (value >= 0) { - req->length = value; - req->context = cdev; - req->zero = value < w_length; - value = composite_ep0_queue(cdev, req, - GFP_ATOMIC); - if (value < 0) { - DBG(cdev, "ep_queue --> %d\n", value); - req->status = 0; - composite_setup_complete(gadget->ep0, - req); - } - } - return value; + goto check_value; } VDBG(cdev, @@ -1973,6 +1942,7 @@ try_fun_setup: goto done; } +check_value: /* respond with data transfer before status phase? */ if (value >= 0 && value != USB_GADGET_DELAYED_STATUS) { req->length = value; @@ -2156,8 +2126,8 @@ int composite_os_desc_req_prepare(struct usb_composite_dev *cdev, goto end; } - /* OS feature descriptor length <= 4kB */ - cdev->os_desc_req->buf = kmalloc(4096, GFP_KERNEL); + cdev->os_desc_req->buf = kmalloc(USB_COMP_EP0_OS_DESC_BUFSIZ, + GFP_KERNEL); if (!cdev->os_desc_req->buf) { ret = -ENOMEM; usb_ep_free_request(ep0, cdev->os_desc_req); @@ -2172,6 +2142,7 @@ end: void composite_dev_cleanup(struct usb_composite_dev *cdev) { struct usb_gadget_string_container *uc, *tmp; + struct usb_ep *ep, *tmp_ep; list_for_each_entry_safe(uc, tmp, &cdev->gstrings, list) { list_del(&uc->list); @@ -2193,6 +2164,21 @@ void composite_dev_cleanup(struct usb_composite_dev *cdev) } cdev->next_string_id = 0; device_remove_file(&cdev->gadget->dev, &dev_attr_suspended); + + /* + * Some UDC backends have a dynamic EP allocation scheme. + * + * In that case, the dispose() callback is used to notify the + * backend that the EPs are no longer in use. + * + * Note: The UDC backend can remove the EP from the ep_list as + * a result, so we need to use the _safe list iterator. + */ + list_for_each_entry_safe(ep, tmp_ep, + &cdev->gadget->ep_list, ep_list) { + if (ep->ops->dispose) + ep->ops->dispose(ep); + } } static int composite_bind(struct usb_gadget *gadget, diff --git a/drivers/usb/gadget/function/f_fs.c b/drivers/usb/gadget/function/f_fs.c index d2428a9e8900..0294e4f18873 100644 --- a/drivers/usb/gadget/function/f_fs.c +++ b/drivers/usb/gadget/function/f_fs.c @@ -758,9 +758,13 @@ static void ffs_user_copy_worker(struct work_struct *work) bool kiocb_has_eventfd = io_data->kiocb->ki_flags & IOCB_EVENTFD; if (io_data->read && ret > 0) { + mm_segment_t oldfs = get_fs(); + + set_fs(USER_DS); use_mm(io_data->mm); ret = ffs_copy_to_iter(io_data->buf, ret, &io_data->data); unuse_mm(io_data->mm); + set_fs(oldfs); } io_data->kiocb->ki_complete(io_data->kiocb, ret, ret); @@ -3238,7 +3242,7 @@ static int ffs_func_setup(struct usb_function *f, __ffs_event_add(ffs, FUNCTIONFS_SETUP); spin_unlock_irqrestore(&ffs->ev.waitq.lock, flags); - return 0; + return USB_GADGET_DELAYED_STATUS; } static bool ffs_func_req_match(struct usb_function *f, diff --git a/drivers/usb/gadget/function/f_midi.c b/drivers/usb/gadget/function/f_midi.c index 4eb96b91cc40..e8f35db42394 100644 --- a/drivers/usb/gadget/function/f_midi.c +++ b/drivers/usb/gadget/function/f_midi.c @@ -404,7 +404,8 @@ static int f_midi_set_alt(struct usb_function *f, unsigned intf, unsigned alt) if (err) { ERROR(midi, "%s: couldn't enqueue request: %d\n", midi->out_ep->name, err); - free_ep_req(midi->out_ep, req); + if (req->buf != NULL) + free_ep_req(midi->out_ep, req); return err; } } diff --git a/drivers/usb/gadget/function/f_tcm.c b/drivers/usb/gadget/function/f_tcm.c index da81cf16b850..d78dbb73bde8 100644 --- a/drivers/usb/gadget/function/f_tcm.c +++ b/drivers/usb/gadget/function/f_tcm.c @@ -1094,7 +1094,7 @@ static int usbg_submit_command(struct f_uas *fu, struct command_iu *cmd_iu = cmdbuf; struct usbg_cmd *cmd; struct usbg_tpg *tpg = fu->tpg; - struct tcm_usbg_nexus *tv_nexus = tpg->tpg_nexus; + struct tcm_usbg_nexus *tv_nexus; u32 cmd_len; u16 scsi_tag; diff --git a/drivers/usb/gadget/legacy/mass_storage.c b/drivers/usb/gadget/legacy/mass_storage.c index ef3d25259b0e..fd5595ac5bf7 100644 --- a/drivers/usb/gadget/legacy/mass_storage.c +++ b/drivers/usb/gadget/legacy/mass_storage.c @@ -225,7 +225,7 @@ static int msg_unbind(struct usb_composite_dev *cdev) static struct usb_composite_driver msg_driver = { .name = "g_mass_storage", .dev = &msg_device_desc, - .max_speed = USB_SPEED_SUPER, + .max_speed = USB_SPEED_SUPER_PLUS, .needs_serial = 1, .strings = dev_strings, .bind = msg_bind, diff --git a/drivers/usb/gadget/u_f.h b/drivers/usb/gadget/u_f.h index c3fbef2bb5db..09f90447fed5 100644 --- a/drivers/usb/gadget/u_f.h +++ b/drivers/usb/gadget/u_f.h @@ -61,7 +61,9 @@ struct usb_request *alloc_ep_req(struct usb_ep *ep, size_t len); /* Frees a usb_request previously allocated by alloc_ep_req() */ static inline void free_ep_req(struct usb_ep *ep, struct usb_request *req) { + WARN_ON(req->buf == NULL); kfree(req->buf); + req->buf = NULL; usb_ep_free_request(ep, req); } diff --git a/drivers/usb/gadget/udc/atmel_usba_udc.c b/drivers/usb/gadget/udc/atmel_usba_udc.c index 075eaaa8a408..27c16399c7e8 100644 --- a/drivers/usb/gadget/udc/atmel_usba_udc.c +++ b/drivers/usb/gadget/udc/atmel_usba_udc.c @@ -23,7 +23,8 @@ #include <linux/usb/atmel_usba_udc.h> #include <linux/delay.h> #include <linux/of.h> -#include <linux/of_gpio.h> +#include <linux/irq.h> +#include <linux/gpio/consumer.h> #include "atmel_usba_udc.h" #define USBA_VBUS_IRQFLAGS (IRQF_ONESHOT \ @@ -415,8 +416,8 @@ static inline void usba_int_enb_set(struct usba_udc *udc, u32 val) static int vbus_is_present(struct usba_udc *udc) { - if (gpio_is_valid(udc->vbus_pin)) - return gpio_get_value(udc->vbus_pin) ^ udc->vbus_pin_inverted; + if (udc->vbus_pin) + return gpiod_get_value(udc->vbus_pin) ^ udc->vbus_pin_inverted; /* No Vbus detection: Assume always present */ return 1; @@ -1975,8 +1976,8 @@ static int atmel_usba_start(struct usb_gadget *gadget, mutex_lock(&udc->vbus_mutex); - if (gpio_is_valid(udc->vbus_pin)) - enable_irq(gpio_to_irq(udc->vbus_pin)); + if (udc->vbus_pin) + enable_irq(gpiod_to_irq(udc->vbus_pin)); /* If Vbus is present, enable the controller and wait for reset */ udc->vbus_prev = vbus_is_present(udc); @@ -1990,8 +1991,8 @@ static int atmel_usba_start(struct usb_gadget *gadget, return 0; err: - if (gpio_is_valid(udc->vbus_pin)) - disable_irq(gpio_to_irq(udc->vbus_pin)); + if (udc->vbus_pin) + disable_irq(gpiod_to_irq(udc->vbus_pin)); mutex_unlock(&udc->vbus_mutex); @@ -2006,8 +2007,8 @@ static int atmel_usba_stop(struct usb_gadget *gadget) { struct usba_udc *udc = container_of(gadget, struct usba_udc, gadget); - if (gpio_is_valid(udc->vbus_pin)) - disable_irq(gpio_to_irq(udc->vbus_pin)); + if (udc->vbus_pin) + disable_irq(gpiod_to_irq(udc->vbus_pin)); if (fifo_mode == 0) udc->configured_ep = 1; @@ -2019,7 +2020,6 @@ static int atmel_usba_stop(struct usb_gadget *gadget) return 0; } -#ifdef CONFIG_OF static void at91sam9rl_toggle_bias(struct usba_udc *udc, int is_on) { regmap_update_bits(udc->pmc, AT91_CKGR_UCKR, AT91_PMC_BIASEN, @@ -2055,7 +2055,6 @@ static struct usba_ep * atmel_udc_of_init(struct platform_device *pdev, { u32 val; const char *name; - enum of_gpio_flags flags; struct device_node *np = pdev->dev.of_node; const struct of_device_id *match; struct device_node *pp; @@ -2075,9 +2074,9 @@ static struct usba_ep * atmel_udc_of_init(struct platform_device *pdev, udc->num_ep = 0; - udc->vbus_pin = of_get_named_gpio_flags(np, "atmel,vbus-gpio", 0, - &flags); - udc->vbus_pin_inverted = (flags & OF_GPIO_ACTIVE_LOW) ? 1 : 0; + udc->vbus_pin = devm_gpiod_get_optional(&pdev->dev, "atmel,vbus", + GPIOD_IN); + udc->vbus_pin_inverted = gpiod_is_active_low(udc->vbus_pin); if (fifo_mode == 0) { pp = NULL; @@ -2204,75 +2203,10 @@ static struct usba_ep * atmel_udc_of_init(struct platform_device *pdev, err: return ERR_PTR(ret); } -#else -static struct usba_ep * atmel_udc_of_init(struct platform_device *pdev, - struct usba_udc *udc) -{ - return ERR_PTR(-ENOSYS); -} -#endif - -static struct usba_ep * usba_udc_pdata(struct platform_device *pdev, - struct usba_udc *udc) -{ - struct usba_platform_data *pdata = dev_get_platdata(&pdev->dev); - struct usba_ep *eps; - int i; - - if (!pdata) - return ERR_PTR(-ENXIO); - - eps = devm_kzalloc(&pdev->dev, sizeof(struct usba_ep) * pdata->num_ep, - GFP_KERNEL); - if (!eps) - return ERR_PTR(-ENOMEM); - - udc->gadget.ep0 = &eps[0].ep; - - udc->vbus_pin = pdata->vbus_pin; - udc->vbus_pin_inverted = pdata->vbus_pin_inverted; - udc->num_ep = pdata->num_ep; - - INIT_LIST_HEAD(&eps[0].ep.ep_list); - - for (i = 0; i < pdata->num_ep; i++) { - struct usba_ep *ep = &eps[i]; - - ep->ep_regs = udc->regs + USBA_EPT_BASE(i); - ep->dma_regs = udc->regs + USBA_DMA_BASE(i); - ep->fifo = udc->fifo + USBA_FIFO_BASE(i); - ep->ep.ops = &usba_ep_ops; - ep->ep.name = pdata->ep[i].name; - ep->fifo_size = pdata->ep[i].fifo_size; - usb_ep_set_maxpacket_limit(&ep->ep, ep->fifo_size); - ep->udc = udc; - INIT_LIST_HEAD(&ep->queue); - ep->nr_banks = pdata->ep[i].nr_banks; - ep->index = pdata->ep[i].index; - ep->can_dma = pdata->ep[i].can_dma; - ep->can_isoc = pdata->ep[i].can_isoc; - - if (i == 0) { - ep->ep.caps.type_control = true; - } else { - ep->ep.caps.type_iso = ep->can_isoc; - ep->ep.caps.type_bulk = true; - ep->ep.caps.type_int = true; - } - - ep->ep.caps.dir_in = true; - ep->ep.caps.dir_out = true; - - if (i) - list_add_tail(&ep->ep.ep_list, &udc->gadget.ep_list); - } - - return eps; -} static int usba_udc_probe(struct platform_device *pdev) { - struct resource *regs, *fifo; + struct resource *res; struct clk *pclk, *hclk; struct usba_udc *udc; int irq, ret, i; @@ -2284,10 +2218,18 @@ static int usba_udc_probe(struct platform_device *pdev) udc->gadget = usba_gadget_template; INIT_LIST_HEAD(&udc->gadget.ep_list); - regs = platform_get_resource(pdev, IORESOURCE_MEM, CTRL_IOMEM_ID); - fifo = platform_get_resource(pdev, IORESOURCE_MEM, FIFO_IOMEM_ID); - if (!regs || !fifo) - return -ENXIO; + res = platform_get_resource(pdev, IORESOURCE_MEM, CTRL_IOMEM_ID); + udc->regs = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(udc->regs)) + return PTR_ERR(udc->regs); + dev_info(&pdev->dev, "MMIO registers at %pR mapped at %p\n", + res, udc->regs); + + res = platform_get_resource(pdev, IORESOURCE_MEM, FIFO_IOMEM_ID); + udc->fifo = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(udc->fifo)) + return PTR_ERR(udc->fifo); + dev_info(&pdev->dev, "FIFO at %pR mapped at %p\n", res, udc->fifo); irq = platform_get_irq(pdev, 0); if (irq < 0) @@ -2305,23 +2247,6 @@ static int usba_udc_probe(struct platform_device *pdev) udc->pdev = pdev; udc->pclk = pclk; udc->hclk = hclk; - udc->vbus_pin = -ENODEV; - - ret = -ENOMEM; - udc->regs = devm_ioremap(&pdev->dev, regs->start, resource_size(regs)); - if (!udc->regs) { - dev_err(&pdev->dev, "Unable to map I/O memory, aborting.\n"); - return ret; - } - dev_info(&pdev->dev, "MMIO registers at 0x%08lx mapped at %p\n", - (unsigned long)regs->start, udc->regs); - udc->fifo = devm_ioremap(&pdev->dev, fifo->start, resource_size(fifo)); - if (!udc->fifo) { - dev_err(&pdev->dev, "Unable to map FIFO, aborting.\n"); - return ret; - } - dev_info(&pdev->dev, "FIFO at 0x%08lx mapped at %p\n", - (unsigned long)fifo->start, udc->fifo); platform_set_drvdata(pdev, udc); @@ -2335,10 +2260,7 @@ static int usba_udc_probe(struct platform_device *pdev) usba_writel(udc, CTRL, USBA_DISABLE_MASK); clk_disable_unprepare(pclk); - if (pdev->dev.of_node) - udc->usba_ep = atmel_udc_of_init(pdev, udc); - else - udc->usba_ep = usba_udc_pdata(pdev, udc); + udc->usba_ep = atmel_udc_of_init(pdev, udc); toggle_bias(udc, 0); @@ -2354,24 +2276,18 @@ static int usba_udc_probe(struct platform_device *pdev) } udc->irq = irq; - if (gpio_is_valid(udc->vbus_pin)) { - if (!devm_gpio_request(&pdev->dev, udc->vbus_pin, "atmel_usba_udc")) { - irq_set_status_flags(gpio_to_irq(udc->vbus_pin), - IRQ_NOAUTOEN); - ret = devm_request_threaded_irq(&pdev->dev, - gpio_to_irq(udc->vbus_pin), NULL, + if (udc->vbus_pin) { + irq_set_status_flags(gpiod_to_irq(udc->vbus_pin), IRQ_NOAUTOEN); + ret = devm_request_threaded_irq(&pdev->dev, + gpiod_to_irq(udc->vbus_pin), NULL, usba_vbus_irq_thread, USBA_VBUS_IRQFLAGS, "atmel_usba_udc", udc); if (ret) { - udc->vbus_pin = -ENODEV; + udc->vbus_pin = NULL; dev_warn(&udc->pdev->dev, "failed to request vbus irq; " "assuming always on\n"); } - } else { - /* gpio_request fail so use -EINVAL for gpio_is_valid */ - udc->vbus_pin = -EINVAL; - } } ret = usb_add_gadget_udc(&pdev->dev, &udc->gadget); @@ -2423,9 +2339,9 @@ static int usba_udc_suspend(struct device *dev) * Device may wake up. We stay clocked if we failed * to request vbus irq, assuming always on. */ - if (gpio_is_valid(udc->vbus_pin)) { + if (udc->vbus_pin) { usba_stop(udc); - enable_irq_wake(gpio_to_irq(udc->vbus_pin)); + enable_irq_wake(gpiod_to_irq(udc->vbus_pin)); } out: @@ -2441,8 +2357,8 @@ static int usba_udc_resume(struct device *dev) if (!udc->driver) return 0; - if (device_may_wakeup(dev) && gpio_is_valid(udc->vbus_pin)) - disable_irq_wake(gpio_to_irq(udc->vbus_pin)); + if (device_may_wakeup(dev) && udc->vbus_pin) + disable_irq_wake(gpiod_to_irq(udc->vbus_pin)); /* If Vbus is present, enable the controller and wait for reset */ mutex_lock(&udc->vbus_mutex); @@ -2462,7 +2378,7 @@ static struct platform_driver udc_driver = { .driver = { .name = "atmel_usba_udc", .pm = &usba_udc_pm_ops, - .of_match_table = of_match_ptr(atmel_udc_dt_ids), + .of_match_table = atmel_udc_dt_ids, }, }; diff --git a/drivers/usb/gadget/udc/atmel_usba_udc.h b/drivers/usb/gadget/udc/atmel_usba_udc.h index 860a00a6fdd0..969ce8f3c3e2 100644 --- a/drivers/usb/gadget/udc/atmel_usba_udc.h +++ b/drivers/usb/gadget/udc/atmel_usba_udc.h @@ -7,6 +7,8 @@ #ifndef __LINUX_USB_GADGET_USBA_UDC_H__ #define __LINUX_USB_GADGET_USBA_UDC_H__ +#include <linux/gpio/consumer.h> + /* USB register offsets */ #define USBA_CTRL 0x0000 #define USBA_FNUM 0x0004 @@ -323,7 +325,7 @@ struct usba_udc { struct platform_device *pdev; const struct usba_udc_errata *errata; int irq; - int vbus_pin; + struct gpio_desc *vbus_pin; int vbus_pin_inverted; int num_ep; int configured_ep; diff --git a/drivers/usb/gadget/udc/bcm63xx_udc.c b/drivers/usb/gadget/udc/bcm63xx_udc.c index 465ccd1104de..3a8df8601074 100644 --- a/drivers/usb/gadget/udc/bcm63xx_udc.c +++ b/drivers/usb/gadget/udc/bcm63xx_udc.c @@ -2158,6 +2158,7 @@ static int bcm63xx_usbd_dbg_show(struct seq_file *s, void *p) return 0; } +DEFINE_SHOW_ATTRIBUTE(bcm63xx_usbd_dbg); /* * bcm63xx_iudma_dbg_show - Show IUDMA status and descriptors. @@ -2238,33 +2239,7 @@ static int bcm63xx_iudma_dbg_show(struct seq_file *s, void *p) return 0; } - -static int bcm63xx_usbd_dbg_open(struct inode *inode, struct file *file) -{ - return single_open(file, bcm63xx_usbd_dbg_show, inode->i_private); -} - -static int bcm63xx_iudma_dbg_open(struct inode *inode, struct file *file) -{ - return single_open(file, bcm63xx_iudma_dbg_show, inode->i_private); -} - -static const struct file_operations usbd_dbg_fops = { - .owner = THIS_MODULE, - .open = bcm63xx_usbd_dbg_open, - .llseek = seq_lseek, - .read = seq_read, - .release = single_release, -}; - -static const struct file_operations iudma_dbg_fops = { - .owner = THIS_MODULE, - .open = bcm63xx_iudma_dbg_open, - .llseek = seq_lseek, - .read = seq_read, - .release = single_release, -}; - +DEFINE_SHOW_ATTRIBUTE(bcm63xx_iudma_dbg); /** * bcm63xx_udc_init_debugfs - Create debugfs entries. @@ -2282,11 +2257,11 @@ static void bcm63xx_udc_init_debugfs(struct bcm63xx_udc *udc) goto err_root; usbd = debugfs_create_file("usbd", 0400, root, udc, - &usbd_dbg_fops); + &bcm63xx_usbd_dbg_fops); if (!usbd) goto err_usbd; iudma = debugfs_create_file("iudma", 0400, root, udc, - &iudma_dbg_fops); + &bcm63xx_iudma_dbg_fops); if (!iudma) goto err_iudma; diff --git a/drivers/usb/gadget/udc/bdc/bdc_ep.c b/drivers/usb/gadget/udc/bdc/bdc_ep.c index f40d4c13cfa4..03149b9d7ea7 100644 --- a/drivers/usb/gadget/udc/bdc/bdc_ep.c +++ b/drivers/usb/gadget/udc/bdc/bdc_ep.c @@ -151,7 +151,7 @@ static int ep_bd_list_alloc(struct bdc_ep *ep) if (!bd_table) goto fail; - bd_table->start_bd = dma_pool_alloc(bdc->bd_table_pool, + bd_table->start_bd = dma_pool_zalloc(bdc->bd_table_pool, GFP_ATOMIC, &dma); if (!bd_table->start_bd) { @@ -167,7 +167,6 @@ static int ep_bd_list_alloc(struct bdc_ep *ep) (unsigned long long)bd_table->dma, prev_table); ep->bd_list.bd_table_array[index] = bd_table; - memset(bd_table->start_bd, 0, bd_p_tab * sizeof(struct bdc_bd)); if (prev_table) chain_table(prev_table, bd_table, bd_p_tab); diff --git a/drivers/usb/gadget/udc/core.c b/drivers/usb/gadget/udc/core.c index 1f8b19d9cf97..842814bc0e4f 100644 --- a/drivers/usb/gadget/udc/core.c +++ b/drivers/usb/gadget/udc/core.c @@ -238,6 +238,9 @@ EXPORT_SYMBOL_GPL(usb_ep_free_request); * arranges to poll once per interval, and the gadget driver usually will * have queued some data to transfer at that time. * + * Note that @req's ->complete() callback must never be called from + * within usb_ep_queue() as that can create deadlock situations. + * * Returns zero, or a negative error code. Endpoints that are not enabled * report errors; errors will also be * reported when the usb peripheral is disconnected. @@ -1482,7 +1485,7 @@ ssize_t name##_show(struct device *dev, \ struct device_attribute *attr, char *buf) \ { \ struct usb_udc *udc = container_of(dev, struct usb_udc, dev); \ - return snprintf(buf, PAGE_SIZE, "%s\n", \ + return scnprintf(buf, PAGE_SIZE, "%s\n", \ usb_speed_string(udc->gadget->param)); \ } \ static DEVICE_ATTR_RO(name) @@ -1497,7 +1500,7 @@ ssize_t name##_show(struct device *dev, \ struct usb_udc *udc = container_of(dev, struct usb_udc, dev); \ struct usb_gadget *gadget = udc->gadget; \ \ - return snprintf(buf, PAGE_SIZE, "%d\n", gadget->name); \ + return scnprintf(buf, PAGE_SIZE, "%d\n", gadget->name); \ } \ static DEVICE_ATTR_RO(name) diff --git a/drivers/usb/gadget/udc/dummy_hcd.c b/drivers/usb/gadget/udc/dummy_hcd.c index e744d4b7bfed..baf72f95f0f1 100644 --- a/drivers/usb/gadget/udc/dummy_hcd.c +++ b/drivers/usb/gadget/udc/dummy_hcd.c @@ -2366,7 +2366,7 @@ static inline ssize_t show_urb(char *buf, size_t size, struct urb *urb) { int ep = usb_pipeendpoint(urb->pipe); - return snprintf(buf, size, + return scnprintf(buf, size, "urb/%p %s ep%d%s%s len %d/%d\n", urb, ({ char *s; diff --git a/drivers/usb/gadget/udc/goku_udc.h b/drivers/usb/gadget/udc/goku_udc.h index 26601bf4e7a9..70023d401079 100644 --- a/drivers/usb/gadget/udc/goku_udc.h +++ b/drivers/usb/gadget/udc/goku_udc.h @@ -25,7 +25,7 @@ struct goku_udc_regs { # define INT_EP1DATASET 0x00040 # define INT_EP2DATASET 0x00080 # define INT_EP3DATASET 0x00100 -#define INT_EPnNAK(n) (0x00100 < (n)) /* 0 < n < 4 */ +#define INT_EPnNAK(n) (0x00100 << (n)) /* 0 < n < 4 */ # define INT_EP1NAK 0x00200 # define INT_EP2NAK 0x00400 # define INT_EP3NAK 0x00800 diff --git a/drivers/usb/gadget/udc/gr_udc.c b/drivers/usb/gadget/udc/gr_udc.c index b3fb1bbdb854..ca83c15d8ea4 100644 --- a/drivers/usb/gadget/udc/gr_udc.c +++ b/drivers/usb/gadget/udc/gr_udc.c @@ -179,8 +179,7 @@ static void gr_seq_ep_show(struct seq_file *seq, struct gr_ep *ep) seq_puts(seq, "\n"); } - -static int gr_seq_show(struct seq_file *seq, void *v) +static int gr_dfs_show(struct seq_file *seq, void *v) { struct gr_udc *dev = seq->private; u32 control = gr_read32(&dev->regs->control); @@ -203,19 +202,7 @@ static int gr_seq_show(struct seq_file *seq, void *v) return 0; } - -static int gr_dfs_open(struct inode *inode, struct file *file) -{ - return single_open(file, gr_seq_show, inode->i_private); -} - -static const struct file_operations gr_dfs_fops = { - .owner = THIS_MODULE, - .open = gr_dfs_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; +DEFINE_SHOW_ATTRIBUTE(gr_dfs); static void gr_dfs_create(struct gr_udc *dev) { diff --git a/drivers/usb/gadget/udc/pxa25x_udc.c b/drivers/usb/gadget/udc/pxa25x_udc.c index 0e3f5faa000e..d4be53559f2e 100644 --- a/drivers/usb/gadget/udc/pxa25x_udc.c +++ b/drivers/usb/gadget/udc/pxa25x_udc.c @@ -1233,8 +1233,7 @@ static const struct usb_gadget_ops pxa25x_udc_ops = { #ifdef CONFIG_USB_GADGET_DEBUG_FS -static int -udc_seq_show(struct seq_file *m, void *_d) +static int udc_debug_show(struct seq_file *m, void *_d) { struct pxa25x_udc *dev = m->private; unsigned long flags; @@ -1335,25 +1334,12 @@ done: local_irq_restore(flags); return 0; } - -static int -udc_debugfs_open(struct inode *inode, struct file *file) -{ - return single_open(file, udc_seq_show, inode->i_private); -} - -static const struct file_operations debug_fops = { - .open = udc_debugfs_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, - .owner = THIS_MODULE, -}; +DEFINE_SHOW_ATTRIBUTE(udc_debug); #define create_debug_files(dev) \ do { \ dev->debugfs_udc = debugfs_create_file(dev->gadget.name, \ - S_IRUGO, NULL, dev, &debug_fops); \ + S_IRUGO, NULL, dev, &udc_debug_fops); \ } while (0) #define remove_debug_files(dev) debugfs_remove(dev->debugfs_udc) diff --git a/drivers/usb/gadget/udc/pxa27x_udc.c b/drivers/usb/gadget/udc/pxa27x_udc.c index fadcf2653c3d..a58242e901df 100644 --- a/drivers/usb/gadget/udc/pxa27x_udc.c +++ b/drivers/usb/gadget/udc/pxa27x_udc.c @@ -131,6 +131,7 @@ static int state_dbg_show(struct seq_file *s, void *p) return 0; } +DEFINE_SHOW_ATTRIBUTE(state_dbg); static int queues_dbg_show(struct seq_file *s, void *p) { @@ -163,6 +164,7 @@ static int queues_dbg_show(struct seq_file *s, void *p) return 0; } +DEFINE_SHOW_ATTRIBUTE(queues_dbg); static int eps_dbg_show(struct seq_file *s, void *p) { @@ -199,45 +201,7 @@ static int eps_dbg_show(struct seq_file *s, void *p) return 0; } - -static int eps_dbg_open(struct inode *inode, struct file *file) -{ - return single_open(file, eps_dbg_show, inode->i_private); -} - -static int queues_dbg_open(struct inode *inode, struct file *file) -{ - return single_open(file, queues_dbg_show, inode->i_private); -} - -static int state_dbg_open(struct inode *inode, struct file *file) -{ - return single_open(file, state_dbg_show, inode->i_private); -} - -static const struct file_operations state_dbg_fops = { - .owner = THIS_MODULE, - .open = state_dbg_open, - .llseek = seq_lseek, - .read = seq_read, - .release = single_release, -}; - -static const struct file_operations queues_dbg_fops = { - .owner = THIS_MODULE, - .open = queues_dbg_open, - .llseek = seq_lseek, - .read = seq_read, - .release = single_release, -}; - -static const struct file_operations eps_dbg_fops = { - .owner = THIS_MODULE, - .open = eps_dbg_open, - .llseek = seq_lseek, - .read = seq_read, - .release = single_release, -}; +DEFINE_SHOW_ATTRIBUTE(eps_dbg); static void pxa_init_debugfs(struct pxa_udc *udc) { |