diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2021-07-06 00:16:22 +0300 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2021-07-06 00:16:22 +0300 |
commit | 79160a603bdb51916226caf4a6616cc4e1c58a58 (patch) | |
tree | 6aa2dd8ce76799921ba56eace1c0262ab947f115 /drivers/usb/gadget | |
parent | c932ed0adb09a7fa6d6649ee04dd78c83ab07ada (diff) | |
parent | 7756f1d6369e61d1cc47d6e51619d1e1d1681a2e (diff) | |
download | linux-79160a603bdb51916226caf4a6616cc4e1c58a58.tar.xz |
Merge tag 'usb-5.14-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb
Pull USB / Thunderbolt updates from Greg KH:
"Here is the big set of USB and Thunderbolt patches for 5.14-rc1.
Nothing major here just lots of little changes for new hardware and
features. Highlights are:
- more USB 4 support added to the thunderbolt core
- build warning fixes all over the place
- usb-serial driver updates and new device support
- mtu3 driver updates
- gadget driver updates
- dwc3 driver updates
- dwc2 driver updates
- isp1760 host driver updates
- musb driver updates
- lots of other tiny things.
Full details are in the shortlog.
All of these have been in linux-next for a while now with no reported
issues"
* tag 'usb-5.14-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb: (223 commits)
phy: qcom-qusb2: Add configuration for SM4250 and SM6115
dt-bindings: phy: qcom,qusb2: document sm4250/6115 compatible
dt-bindings: usb: qcom,dwc3: Add bindings for sm6115/4250
USB: cdc-acm: blacklist Heimann USB Appset device
usb: xhci-mtk: allow multiple Start-Split in a microframe
usb: ftdi-elan: remove redundant continue statement in a while-loop
usb: class: cdc-wdm: return the correct errno code
xhci: remove redundant continue statement
usb: dwc3: Fix debugfs creation flow
usb: gadget: hid: fix error return code in hid_bind()
usb: gadget: eem: fix echo command packet response issue
usb: gadget: f_hid: fix endianness issue with descriptors
Revert "USB: misc: Add onboard_usb_hub driver"
Revert "of/platform: Add stubs for of_platform_device_create/destroy()"
Revert "usb: host: xhci-plat: Create platform device for onboard hubs in probe()"
Revert "arm64: dts: qcom: sc7180-trogdor: Add nodes for onboard USB hub"
xhci: solve a double free problem while doing s4
xhci: handle failed buffer copy to URB sg list and fix a W=1 copiler warning
xhci: Add adaptive interrupt rate for isoch TRBs with XHCI_AVOID_BEI quirk
xhci: Remove unused defines for ERST_SIZE and ERST_ENTRIES
...
Diffstat (limited to 'drivers/usb/gadget')
38 files changed, 629 insertions, 206 deletions
diff --git a/drivers/usb/gadget/function/f_eem.c b/drivers/usb/gadget/function/f_eem.c index 2cd9942707b4..5d38f29bda72 100644 --- a/drivers/usb/gadget/function/f_eem.c +++ b/drivers/usb/gadget/function/f_eem.c @@ -30,6 +30,11 @@ struct f_eem { u8 ctrl_id; }; +struct in_context { + struct sk_buff *skb; + struct usb_ep *ep; +}; + static inline struct f_eem *func_to_eem(struct usb_function *f) { return container_of(f, struct f_eem, port.func); @@ -320,9 +325,12 @@ fail: static void eem_cmd_complete(struct usb_ep *ep, struct usb_request *req) { - struct sk_buff *skb = (struct sk_buff *)req->context; + struct in_context *ctx = req->context; - dev_kfree_skb_any(skb); + dev_kfree_skb_any(ctx->skb); + kfree(req->buf); + usb_ep_free_request(ctx->ep, req); + kfree(ctx); } /* @@ -410,7 +418,9 @@ static int eem_unwrap(struct gether *port, * b15: bmType (0 == data, 1 == command) */ if (header & BIT(15)) { - struct usb_request *req = cdev->req; + struct usb_request *req; + struct in_context *ctx; + struct usb_ep *ep; u16 bmEEMCmd; /* EEM command packet format: @@ -439,11 +449,36 @@ static int eem_unwrap(struct gether *port, skb_trim(skb2, len); put_unaligned_le16(BIT(15) | BIT(11) | len, skb_push(skb2, 2)); + + ep = port->in_ep; + req = usb_ep_alloc_request(ep, GFP_ATOMIC); + if (!req) { + dev_kfree_skb_any(skb2); + goto next; + } + + req->buf = kmalloc(skb2->len, GFP_KERNEL); + if (!req->buf) { + usb_ep_free_request(ep, req); + dev_kfree_skb_any(skb2); + goto next; + } + + ctx = kmalloc(sizeof(*ctx), GFP_KERNEL); + if (!ctx) { + kfree(req->buf); + usb_ep_free_request(ep, req); + dev_kfree_skb_any(skb2); + goto next; + } + ctx->skb = skb2; + ctx->ep = ep; + skb_copy_bits(skb2, 0, req->buf, skb2->len); req->length = skb2->len; req->complete = eem_cmd_complete; req->zero = 1; - req->context = skb2; + req->context = ctx; if (usb_ep_queue(port->in_ep, req, GFP_ATOMIC)) DBG(cdev, "echo response queue fail\n"); break; diff --git a/drivers/usb/gadget/function/f_fs.c b/drivers/usb/gadget/function/f_fs.c index d4844afeaffc..9c0c393abb39 100644 --- a/drivers/usb/gadget/function/f_fs.c +++ b/drivers/usb/gadget/function/f_fs.c @@ -250,8 +250,8 @@ EXPORT_SYMBOL_GPL(ffs_lock); static struct ffs_dev *_ffs_find_dev(const char *name); static struct ffs_dev *_ffs_alloc_dev(void); static void _ffs_free_dev(struct ffs_dev *dev); -static void *ffs_acquire_dev(const char *dev_name); -static void ffs_release_dev(struct ffs_data *ffs_data); +static int ffs_acquire_dev(const char *dev_name, struct ffs_data *ffs_data); +static void ffs_release_dev(struct ffs_dev *ffs_dev); static int ffs_ready(struct ffs_data *ffs); static void ffs_closed(struct ffs_data *ffs); @@ -1554,8 +1554,8 @@ unmapped_value: static int ffs_fs_get_tree(struct fs_context *fc) { struct ffs_sb_fill_data *ctx = fc->fs_private; - void *ffs_dev; struct ffs_data *ffs; + int ret; ENTER(); @@ -1574,13 +1574,12 @@ static int ffs_fs_get_tree(struct fs_context *fc) return -ENOMEM; } - ffs_dev = ffs_acquire_dev(ffs->dev_name); - if (IS_ERR(ffs_dev)) { + ret = ffs_acquire_dev(ffs->dev_name, ffs); + if (ret) { ffs_data_put(ffs); - return PTR_ERR(ffs_dev); + return ret; } - ffs->private_data = ffs_dev; ctx->ffs_data = ffs; return get_tree_nodev(fc, ffs_sb_fill); } @@ -1591,7 +1590,6 @@ static void ffs_fs_free_fc(struct fs_context *fc) if (ctx) { if (ctx->ffs_data) { - ffs_release_dev(ctx->ffs_data); ffs_data_put(ctx->ffs_data); } @@ -1630,10 +1628,8 @@ ffs_fs_kill_sb(struct super_block *sb) ENTER(); kill_litter_super(sb); - if (sb->s_fs_info) { - ffs_release_dev(sb->s_fs_info); + if (sb->s_fs_info) ffs_data_closed(sb->s_fs_info); - } } static struct file_system_type ffs_fs_type = { @@ -1703,6 +1699,7 @@ static void ffs_data_put(struct ffs_data *ffs) if (refcount_dec_and_test(&ffs->ref)) { pr_info("%s(): freeing\n", __func__); ffs_data_clear(ffs); + ffs_release_dev(ffs->private_data); BUG_ON(waitqueue_active(&ffs->ev.waitq) || swait_active(&ffs->ep0req_completion.wait) || waitqueue_active(&ffs->wait)); @@ -3032,6 +3029,7 @@ static inline struct f_fs_opts *ffs_do_functionfs_bind(struct usb_function *f, struct ffs_function *func = ffs_func_from_usb(f); struct f_fs_opts *ffs_opts = container_of(f->fi, struct f_fs_opts, func_inst); + struct ffs_data *ffs_data; int ret; ENTER(); @@ -3046,12 +3044,13 @@ static inline struct f_fs_opts *ffs_do_functionfs_bind(struct usb_function *f, if (!ffs_opts->no_configfs) ffs_dev_lock(); ret = ffs_opts->dev->desc_ready ? 0 : -ENODEV; - func->ffs = ffs_opts->dev->ffs_data; + ffs_data = ffs_opts->dev->ffs_data; if (!ffs_opts->no_configfs) ffs_dev_unlock(); if (ret) return ERR_PTR(ret); + func->ffs = ffs_data; func->conf = c; func->gadget = c->cdev->gadget; @@ -3506,6 +3505,7 @@ static void ffs_free_inst(struct usb_function_instance *f) struct f_fs_opts *opts; opts = to_f_fs_opts(f); + ffs_release_dev(opts->dev); ffs_dev_lock(); _ffs_free_dev(opts->dev); ffs_dev_unlock(); @@ -3693,47 +3693,48 @@ static void _ffs_free_dev(struct ffs_dev *dev) { list_del(&dev->entry); - /* Clear the private_data pointer to stop incorrect dev access */ - if (dev->ffs_data) - dev->ffs_data->private_data = NULL; - kfree(dev); if (list_empty(&ffs_devices)) functionfs_cleanup(); } -static void *ffs_acquire_dev(const char *dev_name) +static int ffs_acquire_dev(const char *dev_name, struct ffs_data *ffs_data) { + int ret = 0; struct ffs_dev *ffs_dev; ENTER(); ffs_dev_lock(); ffs_dev = _ffs_find_dev(dev_name); - if (!ffs_dev) - ffs_dev = ERR_PTR(-ENOENT); - else if (ffs_dev->mounted) - ffs_dev = ERR_PTR(-EBUSY); - else if (ffs_dev->ffs_acquire_dev_callback && - ffs_dev->ffs_acquire_dev_callback(ffs_dev)) - ffs_dev = ERR_PTR(-ENOENT); - else + if (!ffs_dev) { + ret = -ENOENT; + } else if (ffs_dev->mounted) { + ret = -EBUSY; + } else if (ffs_dev->ffs_acquire_dev_callback && + ffs_dev->ffs_acquire_dev_callback(ffs_dev)) { + ret = -ENOENT; + } else { ffs_dev->mounted = true; + ffs_dev->ffs_data = ffs_data; + ffs_data->private_data = ffs_dev; + } ffs_dev_unlock(); - return ffs_dev; + return ret; } -static void ffs_release_dev(struct ffs_data *ffs_data) +static void ffs_release_dev(struct ffs_dev *ffs_dev) { - struct ffs_dev *ffs_dev; - ENTER(); ffs_dev_lock(); - ffs_dev = ffs_data->private_data; - if (ffs_dev) { + if (ffs_dev && ffs_dev->mounted) { ffs_dev->mounted = false; + if (ffs_dev->ffs_data) { + ffs_dev->ffs_data->private_data = NULL; + ffs_dev->ffs_data = NULL; + } if (ffs_dev->ffs_release_dev_callback) ffs_dev->ffs_release_dev_callback(ffs_dev); @@ -3761,7 +3762,6 @@ static int ffs_ready(struct ffs_data *ffs) } ffs_obj->desc_ready = true; - ffs_obj->ffs_data = ffs; if (ffs_obj->ffs_ready_callback) { ret = ffs_obj->ffs_ready_callback(ffs); @@ -3789,7 +3789,6 @@ static void ffs_closed(struct ffs_data *ffs) goto done; ffs_obj->desc_ready = false; - ffs_obj->ffs_data = NULL; if (test_and_clear_bit(FFS_FL_CALL_CLOSED_CALLBACK, &ffs->flags) && ffs_obj->ffs_closed_callback) diff --git a/drivers/usb/gadget/function/f_hid.c b/drivers/usb/gadget/function/f_hid.c index e55699308117..02683ac0719d 100644 --- a/drivers/usb/gadget/function/f_hid.c +++ b/drivers/usb/gadget/function/f_hid.c @@ -88,7 +88,7 @@ static struct usb_interface_descriptor hidg_interface_desc = { static struct hid_descriptor hidg_desc = { .bLength = sizeof hidg_desc, .bDescriptorType = HID_DT_HID, - .bcdHID = 0x0101, + .bcdHID = cpu_to_le16(0x0101), .bCountryCode = 0x00, .bNumDescriptors = 0x1, /*.desc[0].bDescriptorType = DYNAMIC */ @@ -1118,7 +1118,7 @@ static struct usb_function *hidg_alloc(struct usb_function_instance *fi) hidg->func.setup = hidg_setup; hidg->func.free_func = hidg_free; - /* this could me made configurable at some point */ + /* this could be made configurable at some point */ hidg->qlen = 4; return &hidg->func; diff --git a/drivers/usb/gadget/function/f_printer.c b/drivers/usb/gadget/function/f_printer.c index 59d382fe1bbf..abec5c58f525 100644 --- a/drivers/usb/gadget/function/f_printer.c +++ b/drivers/usb/gadget/function/f_printer.c @@ -667,8 +667,7 @@ printer_write(struct file *fd, const char __user *buf, size_t len, loff_t *ptr) value = usb_ep_queue(dev->in_ep, req, GFP_ATOMIC); spin_lock(&dev->lock); if (value) { - list_del(&req->list); - list_add(&req->list, &dev->tx_reqs); + list_move(&req->list, &dev->tx_reqs); spin_unlock_irqrestore(&dev->lock, flags); mutex_unlock(&dev->lock_printer_io); return -EAGAIN; diff --git a/drivers/usb/gadget/function/f_uac2.c b/drivers/usb/gadget/function/f_uac2.c index 7aa4c8bc5a1a..ae29ff2b2b68 100644 --- a/drivers/usb/gadget/function/f_uac2.c +++ b/drivers/usb/gadget/function/f_uac2.c @@ -44,6 +44,7 @@ #define EPIN_EN(_opts) ((_opts)->p_chmask != 0) #define EPOUT_EN(_opts) ((_opts)->c_chmask != 0) +#define EPOUT_FBACK_IN_EN(_opts) ((_opts)->c_sync == USB_ENDPOINT_SYNC_ASYNC) struct f_uac2 { struct g_audio g_audio; @@ -273,7 +274,7 @@ static struct usb_endpoint_descriptor fs_epout_desc = { .bDescriptorType = USB_DT_ENDPOINT, .bEndpointAddress = USB_DIR_OUT, - .bmAttributes = USB_ENDPOINT_XFER_ISOC | USB_ENDPOINT_SYNC_ASYNC, + /* .bmAttributes = DYNAMIC */ /* .wMaxPacketSize = DYNAMIC */ .bInterval = 1, }; @@ -282,7 +283,7 @@ static struct usb_endpoint_descriptor hs_epout_desc = { .bLength = USB_DT_ENDPOINT_SIZE, .bDescriptorType = USB_DT_ENDPOINT, - .bmAttributes = USB_ENDPOINT_XFER_ISOC | USB_ENDPOINT_SYNC_ASYNC, + /* .bmAttributes = DYNAMIC */ /* .wMaxPacketSize = DYNAMIC */ .bInterval = 4, }; @@ -292,7 +293,7 @@ static struct usb_endpoint_descriptor ss_epout_desc = { .bDescriptorType = USB_DT_ENDPOINT, .bEndpointAddress = USB_DIR_OUT, - .bmAttributes = USB_ENDPOINT_XFER_ISOC | USB_ENDPOINT_SYNC_ASYNC, + /* .bmAttributes = DYNAMIC */ /* .wMaxPacketSize = DYNAMIC */ .bInterval = 4, }; @@ -317,6 +318,37 @@ static struct uac2_iso_endpoint_descriptor as_iso_out_desc = { .wLockDelay = 0, }; +/* STD AS ISO IN Feedback Endpoint */ +static struct usb_endpoint_descriptor fs_epin_fback_desc = { + .bLength = USB_DT_ENDPOINT_SIZE, + .bDescriptorType = USB_DT_ENDPOINT, + + .bEndpointAddress = USB_DIR_IN, + .bmAttributes = USB_ENDPOINT_XFER_ISOC | USB_ENDPOINT_USAGE_FEEDBACK, + .wMaxPacketSize = cpu_to_le16(3), + .bInterval = 1, +}; + +static struct usb_endpoint_descriptor hs_epin_fback_desc = { + .bLength = USB_DT_ENDPOINT_SIZE, + .bDescriptorType = USB_DT_ENDPOINT, + + .bmAttributes = USB_ENDPOINT_XFER_ISOC | USB_ENDPOINT_USAGE_FEEDBACK, + .wMaxPacketSize = cpu_to_le16(4), + .bInterval = 4, +}; + +static struct usb_endpoint_descriptor ss_epin_fback_desc = { + .bLength = USB_DT_ENDPOINT_SIZE, + .bDescriptorType = USB_DT_ENDPOINT, + + .bEndpointAddress = USB_DIR_IN, + .bmAttributes = USB_ENDPOINT_XFER_ISOC | USB_ENDPOINT_USAGE_FEEDBACK, + .wMaxPacketSize = cpu_to_le16(4), + .bInterval = 4, +}; + + /* Audio Streaming IN Interface - Alt0 */ static struct usb_interface_descriptor std_as_in_if0_desc = { .bLength = sizeof std_as_in_if0_desc, @@ -431,6 +463,7 @@ static struct usb_descriptor_header *fs_audio_desc[] = { (struct usb_descriptor_header *)&as_out_fmt1_desc, (struct usb_descriptor_header *)&fs_epout_desc, (struct usb_descriptor_header *)&as_iso_out_desc, + (struct usb_descriptor_header *)&fs_epin_fback_desc, (struct usb_descriptor_header *)&std_as_in_if0_desc, (struct usb_descriptor_header *)&std_as_in_if1_desc, @@ -461,6 +494,7 @@ static struct usb_descriptor_header *hs_audio_desc[] = { (struct usb_descriptor_header *)&as_out_fmt1_desc, (struct usb_descriptor_header *)&hs_epout_desc, (struct usb_descriptor_header *)&as_iso_out_desc, + (struct usb_descriptor_header *)&hs_epin_fback_desc, (struct usb_descriptor_header *)&std_as_in_if0_desc, (struct usb_descriptor_header *)&std_as_in_if1_desc, @@ -492,6 +526,7 @@ static struct usb_descriptor_header *ss_audio_desc[] = { (struct usb_descriptor_header *)&ss_epout_desc, (struct usb_descriptor_header *)&ss_epout_desc_comp, (struct usb_descriptor_header *)&as_iso_out_desc, + (struct usb_descriptor_header *)&ss_epin_fback_desc, (struct usb_descriptor_header *)&std_as_in_if0_desc, (struct usb_descriptor_header *)&std_as_in_if1_desc, @@ -549,8 +584,11 @@ static int set_ep_max_packet_size(const struct f_uac2_opts *uac2_opts, ssize = uac2_opts->c_ssize; } + if (!is_playback && (uac2_opts->c_sync == USB_ENDPOINT_SYNC_ASYNC)) + srate = srate * (1000 + uac2_opts->fb_max) / 1000; + max_size_bw = num_channels(chmask) * ssize * - ((srate / (factor / (1 << (ep_desc->bInterval - 1)))) + 1); + DIV_ROUND_UP(srate, factor / (1 << (ep_desc->bInterval - 1))); ep_desc->wMaxPacketSize = cpu_to_le16(min_t(u16, max_size_bw, max_size_ep)); @@ -568,22 +606,26 @@ static void setup_headers(struct f_uac2_opts *opts, struct usb_ss_ep_comp_descriptor *epin_desc_comp = NULL; struct usb_endpoint_descriptor *epout_desc; struct usb_endpoint_descriptor *epin_desc; + struct usb_endpoint_descriptor *epin_fback_desc; int i; switch (speed) { case USB_SPEED_FULL: epout_desc = &fs_epout_desc; epin_desc = &fs_epin_desc; + epin_fback_desc = &fs_epin_fback_desc; break; case USB_SPEED_HIGH: epout_desc = &hs_epout_desc; epin_desc = &hs_epin_desc; + epin_fback_desc = &hs_epin_fback_desc; break; default: epout_desc = &ss_epout_desc; epin_desc = &ss_epin_desc; epout_desc_comp = &ss_epout_desc_comp; epin_desc_comp = &ss_epin_desc_comp; + epin_fback_desc = &ss_epin_fback_desc; } i = 0; @@ -611,6 +653,9 @@ static void setup_headers(struct f_uac2_opts *opts, headers[i++] = USBDHDR(epout_desc_comp); headers[i++] = USBDHDR(&as_iso_out_desc); + + if (EPOUT_FBACK_IN_EN(opts)) + headers[i++] = USBDHDR(epin_fback_desc); } if (EPIN_EN(opts)) { headers[i++] = USBDHDR(&std_as_in_if0_desc); @@ -781,6 +826,23 @@ afunc_bind(struct usb_configuration *cfg, struct usb_function *fn) std_as_out_if1_desc.bInterfaceNumber = ret; uac2->as_out_intf = ret; uac2->as_out_alt = 0; + + if (EPOUT_FBACK_IN_EN(uac2_opts)) { + fs_epout_desc.bmAttributes = + USB_ENDPOINT_XFER_ISOC | USB_ENDPOINT_SYNC_ASYNC; + hs_epout_desc.bmAttributes = + USB_ENDPOINT_XFER_ISOC | USB_ENDPOINT_SYNC_ASYNC; + ss_epout_desc.bmAttributes = + USB_ENDPOINT_XFER_ISOC | USB_ENDPOINT_SYNC_ASYNC; + std_as_out_if1_desc.bNumEndpoints++; + } else { + fs_epout_desc.bmAttributes = + USB_ENDPOINT_XFER_ISOC | USB_ENDPOINT_SYNC_ADAPTIVE; + hs_epout_desc.bmAttributes = + USB_ENDPOINT_XFER_ISOC | USB_ENDPOINT_SYNC_ADAPTIVE; + ss_epout_desc.bmAttributes = + USB_ENDPOINT_XFER_ISOC | USB_ENDPOINT_SYNC_ADAPTIVE; + } } if (EPIN_EN(uac2_opts)) { @@ -844,6 +906,15 @@ afunc_bind(struct usb_configuration *cfg, struct usb_function *fn) dev_err(dev, "%s:%d Error!\n", __func__, __LINE__); return -ENODEV; } + if (EPOUT_FBACK_IN_EN(uac2_opts)) { + agdev->in_ep_fback = usb_ep_autoconfig(gadget, + &fs_epin_fback_desc); + if (!agdev->in_ep_fback) { + dev_err(dev, "%s:%d Error!\n", + __func__, __LINE__); + return -ENODEV; + } + } } if (EPIN_EN(uac2_opts)) { @@ -867,8 +938,10 @@ afunc_bind(struct usb_configuration *cfg, struct usb_function *fn) le16_to_cpu(ss_epout_desc.wMaxPacketSize)); hs_epout_desc.bEndpointAddress = fs_epout_desc.bEndpointAddress; + hs_epin_fback_desc.bEndpointAddress = fs_epin_fback_desc.bEndpointAddress; hs_epin_desc.bEndpointAddress = fs_epin_desc.bEndpointAddress; ss_epout_desc.bEndpointAddress = fs_epout_desc.bEndpointAddress; + ss_epin_fback_desc.bEndpointAddress = fs_epin_fback_desc.bEndpointAddress; ss_epin_desc.bEndpointAddress = fs_epin_desc.bEndpointAddress; setup_descriptor(uac2_opts); @@ -887,6 +960,7 @@ afunc_bind(struct usb_configuration *cfg, struct usb_function *fn) agdev->params.c_srate = uac2_opts->c_srate; agdev->params.c_ssize = uac2_opts->c_ssize; agdev->params.req_number = uac2_opts->req_number; + agdev->params.fb_max = uac2_opts->fb_max; ret = g_audio_setup(agdev, "UAC2 PCM", "UAC2_Gadget"); if (ret) goto err_free_descs; @@ -1195,13 +1269,71 @@ end: \ \ CONFIGFS_ATTR(f_uac2_opts_, name) +#define UAC2_ATTRIBUTE_SYNC(name) \ +static ssize_t f_uac2_opts_##name##_show(struct config_item *item, \ + char *page) \ +{ \ + struct f_uac2_opts *opts = to_f_uac2_opts(item); \ + int result; \ + char *str; \ + \ + mutex_lock(&opts->lock); \ + switch (opts->name) { \ + case USB_ENDPOINT_SYNC_ASYNC: \ + str = "async"; \ + break; \ + case USB_ENDPOINT_SYNC_ADAPTIVE: \ + str = "adaptive"; \ + break; \ + default: \ + str = "unknown"; \ + break; \ + } \ + result = sprintf(page, "%s\n", str); \ + mutex_unlock(&opts->lock); \ + \ + return result; \ +} \ + \ +static ssize_t f_uac2_opts_##name##_store(struct config_item *item, \ + const char *page, size_t len) \ +{ \ + struct f_uac2_opts *opts = to_f_uac2_opts(item); \ + int ret = 0; \ + \ + mutex_lock(&opts->lock); \ + if (opts->refcnt) { \ + ret = -EBUSY; \ + goto end; \ + } \ + \ + if (!strncmp(page, "async", 5)) \ + opts->name = USB_ENDPOINT_SYNC_ASYNC; \ + else if (!strncmp(page, "adaptive", 8)) \ + opts->name = USB_ENDPOINT_SYNC_ADAPTIVE; \ + else { \ + ret = -EINVAL; \ + goto end; \ + } \ + \ + ret = len; \ + \ +end: \ + mutex_unlock(&opts->lock); \ + return ret; \ +} \ + \ +CONFIGFS_ATTR(f_uac2_opts_, name) + UAC2_ATTRIBUTE(p_chmask); UAC2_ATTRIBUTE(p_srate); UAC2_ATTRIBUTE(p_ssize); UAC2_ATTRIBUTE(c_chmask); UAC2_ATTRIBUTE(c_srate); +UAC2_ATTRIBUTE_SYNC(c_sync); UAC2_ATTRIBUTE(c_ssize); UAC2_ATTRIBUTE(req_number); +UAC2_ATTRIBUTE(fb_max); static struct configfs_attribute *f_uac2_attrs[] = { &f_uac2_opts_attr_p_chmask, @@ -1210,7 +1342,9 @@ static struct configfs_attribute *f_uac2_attrs[] = { &f_uac2_opts_attr_c_chmask, &f_uac2_opts_attr_c_srate, &f_uac2_opts_attr_c_ssize, + &f_uac2_opts_attr_c_sync, &f_uac2_opts_attr_req_number, + &f_uac2_opts_attr_fb_max, NULL, }; @@ -1248,7 +1382,9 @@ static struct usb_function_instance *afunc_alloc_inst(void) opts->c_chmask = UAC2_DEF_CCHMASK; opts->c_srate = UAC2_DEF_CSRATE; opts->c_ssize = UAC2_DEF_CSSIZE; + opts->c_sync = UAC2_DEF_CSYNC; opts->req_number = UAC2_DEF_REQ_NUM; + opts->fb_max = UAC2_DEF_FB_MAX; return &opts->func_inst; } diff --git a/drivers/usb/gadget/function/u_audio.c b/drivers/usb/gadget/function/u_audio.c index 5fbceee897a3..018dd0978995 100644 --- a/drivers/usb/gadget/function/u_audio.c +++ b/drivers/usb/gadget/function/u_audio.c @@ -16,6 +16,7 @@ #include <sound/core.h> #include <sound/pcm.h> #include <sound/pcm_params.h> +#include <sound/control.h> #include "u_audio.h" @@ -35,9 +36,13 @@ struct uac_rtd_params { void *rbuf; + unsigned int pitch; /* Stream pitch ratio to 1000000 */ unsigned int max_psize; /* MaxPacketSize of endpoint */ struct usb_request **reqs; + + struct usb_request *req_fback; /* Feedback endpoint request */ + bool fb_ep_enabled; /* if the ep is enabled */ }; struct snd_uac_chip { @@ -70,6 +75,48 @@ static const struct snd_pcm_hardware uac_pcm_hardware = { .periods_min = MIN_PERIODS, }; +static void u_audio_set_fback_frequency(enum usb_device_speed speed, + unsigned long long freq, + unsigned int pitch, + void *buf) +{ + u32 ff = 0; + + /* + * Because the pitch base is 1000000, the final divider here + * will be 1000 * 1000000 = 1953125 << 9 + * + * Instead of dealing with big numbers lets fold this 9 left shift + */ + + if (speed == USB_SPEED_FULL) { + /* + * Full-speed feedback endpoints report frequency + * in samples/frame + * Format is encoded in Q10.10 left-justified in the 24 bits, + * so that it has a Q10.14 format. + * + * ff = (freq << 14) / 1000 + */ + freq <<= 5; + } else { + /* + * High-speed feedback endpoints report frequency + * in samples/microframe. + * Format is encoded in Q12.13 fitted into four bytes so that + * the binary point is located between the second and the third + * byte fromat (that is Q16.16) + * + * ff = (freq << 16) / 8000 + */ + freq <<= 4; + } + + ff = DIV_ROUND_CLOSEST_ULL((freq * pitch), 1953125); + + *(__le32 *)buf = cpu_to_le32(ff); +} + static void u_audio_iso_complete(struct usb_ep *ep, struct usb_request *req) { unsigned int pending; @@ -173,6 +220,35 @@ exit: dev_err(uac->card->dev, "%d Error!\n", __LINE__); } +static void u_audio_iso_fback_complete(struct usb_ep *ep, + struct usb_request *req) +{ + struct uac_rtd_params *prm = req->context; + struct snd_uac_chip *uac = prm->uac; + struct g_audio *audio_dev = uac->audio_dev; + struct uac_params *params = &audio_dev->params; + int status = req->status; + + /* i/f shutting down */ + if (!prm->fb_ep_enabled || req->status == -ESHUTDOWN) + return; + + /* + * We can't really do much about bad xfers. + * Afterall, the ISOCH xfers could fail legitimately. + */ + if (status) + pr_debug("%s: iso_complete status(%d) %d/%d\n", + __func__, status, req->actual, req->length); + + u_audio_set_fback_frequency(audio_dev->gadget->speed, + params->c_srate, prm->pitch, + req->buf); + + if (usb_ep_queue(ep, req, GFP_ATOMIC)) + dev_err(uac->card->dev, "%d Error!\n", __LINE__); +} + static int uac_pcm_trigger(struct snd_pcm_substream *substream, int cmd) { struct snd_uac_chip *uac = snd_pcm_substream_chip(substream); @@ -335,14 +411,33 @@ static inline void free_ep(struct uac_rtd_params *prm, struct usb_ep *ep) dev_err(uac->card->dev, "%s:%d Error!\n", __func__, __LINE__); } +static inline void free_ep_fback(struct uac_rtd_params *prm, struct usb_ep *ep) +{ + struct snd_uac_chip *uac = prm->uac; + + if (!prm->fb_ep_enabled) + return; + + prm->fb_ep_enabled = false; + + if (prm->req_fback) { + usb_ep_dequeue(ep, prm->req_fback); + kfree(prm->req_fback->buf); + usb_ep_free_request(ep, prm->req_fback); + prm->req_fback = NULL; + } + + if (usb_ep_disable(ep)) + dev_err(uac->card->dev, "%s:%d Error!\n", __func__, __LINE__); +} int u_audio_start_capture(struct g_audio *audio_dev) { struct snd_uac_chip *uac = audio_dev->uac; struct usb_gadget *gadget = audio_dev->gadget; struct device *dev = &gadget->dev; - struct usb_request *req; - struct usb_ep *ep; + struct usb_request *req, *req_fback; + struct usb_ep *ep, *ep_fback; struct uac_rtd_params *prm; struct uac_params *params = &audio_dev->params; int req_len, i; @@ -374,6 +469,43 @@ int u_audio_start_capture(struct g_audio *audio_dev) dev_err(dev, "%s:%d Error!\n", __func__, __LINE__); } + ep_fback = audio_dev->in_ep_fback; + if (!ep_fback) + return 0; + + /* Setup feedback endpoint */ + config_ep_by_speed(gadget, &audio_dev->func, ep_fback); + prm->fb_ep_enabled = true; + usb_ep_enable(ep_fback); + req_len = ep_fback->maxpacket; + + req_fback = usb_ep_alloc_request(ep_fback, GFP_ATOMIC); + if (req_fback == NULL) + return -ENOMEM; + + prm->req_fback = req_fback; + req_fback->zero = 0; + req_fback->context = prm; + req_fback->length = req_len; + req_fback->complete = u_audio_iso_fback_complete; + + req_fback->buf = kzalloc(req_len, GFP_ATOMIC); + if (!req_fback->buf) + return -ENOMEM; + + /* + * Configure the feedback endpoint's reported frequency. + * Always start with original frequency since its deviation can't + * be meauserd at start of playback + */ + prm->pitch = 1000000; + u_audio_set_fback_frequency(audio_dev->gadget->speed, + params->c_srate, prm->pitch, + req_fback->buf); + + if (usb_ep_queue(ep_fback, req_fback, GFP_ATOMIC)) + dev_err(dev, "%s:%d Error!\n", __func__, __LINE__); + return 0; } EXPORT_SYMBOL_GPL(u_audio_start_capture); @@ -382,6 +514,8 @@ void u_audio_stop_capture(struct g_audio *audio_dev) { struct snd_uac_chip *uac = audio_dev->uac; + if (audio_dev->in_ep_fback) + free_ep_fback(&uac->c_prm, audio_dev->in_ep_fback); free_ep(&uac->c_prm, audio_dev->out_ep); } EXPORT_SYMBOL_GPL(u_audio_stop_capture); @@ -463,12 +597,82 @@ void u_audio_stop_playback(struct g_audio *audio_dev) } EXPORT_SYMBOL_GPL(u_audio_stop_playback); +static int u_audio_pitch_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + struct uac_rtd_params *prm = snd_kcontrol_chip(kcontrol); + struct snd_uac_chip *uac = prm->uac; + struct g_audio *audio_dev = uac->audio_dev; + struct uac_params *params = &audio_dev->params; + unsigned int pitch_min, pitch_max; + + pitch_min = (1000 - FBACK_SLOW_MAX) * 1000; + pitch_max = (1000 + params->fb_max) * 1000; + + uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; + uinfo->count = 1; + uinfo->value.integer.min = pitch_min; + uinfo->value.integer.max = pitch_max; + uinfo->value.integer.step = 1; + return 0; +} + +static int u_audio_pitch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct uac_rtd_params *prm = snd_kcontrol_chip(kcontrol); + + ucontrol->value.integer.value[0] = prm->pitch; + + return 0; +} + +static int u_audio_pitch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct uac_rtd_params *prm = snd_kcontrol_chip(kcontrol); + struct snd_uac_chip *uac = prm->uac; + struct g_audio *audio_dev = uac->audio_dev; + struct uac_params *params = &audio_dev->params; + unsigned int val; + unsigned int pitch_min, pitch_max; + int change = 0; + + pitch_min = (1000 - FBACK_SLOW_MAX) * 1000; + pitch_max = (1000 + params->fb_max) * 1000; + + val = ucontrol->value.integer.value[0]; + + if (val < pitch_min) + val = pitch_min; + if (val > pitch_max) + val = pitch_max; + + if (prm->pitch != val) { + prm->pitch = val; + change = 1; + } + + return change; +} + +static const struct snd_kcontrol_new u_audio_controls[] = { +{ + .iface = SNDRV_CTL_ELEM_IFACE_PCM, + .name = "Capture Pitch 1000000", + .info = u_audio_pitch_info, + .get = u_audio_pitch_get, + .put = u_audio_pitch_put, +}, +}; + int g_audio_setup(struct g_audio *g_audio, const char *pcm_name, const char *card_name) { struct snd_uac_chip *uac; struct snd_card *card; struct snd_pcm *pcm; + struct snd_kcontrol *kctl; struct uac_params *params; int p_chmask, c_chmask; int err; @@ -556,6 +760,23 @@ int g_audio_setup(struct g_audio *g_audio, const char *pcm_name, snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &uac_pcm_ops); snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &uac_pcm_ops); + if (c_chmask && g_audio->in_ep_fback) { + strscpy(card->mixername, card_name, sizeof(card->driver)); + + kctl = snd_ctl_new1(&u_audio_controls[0], &uac->c_prm); + if (!kctl) { + err = -ENOMEM; + goto snd_fail; + } + + kctl->id.device = pcm->device; + kctl->id.subdevice = 0; + + err = snd_ctl_add(card, kctl); + if (err < 0) + goto snd_fail; + } + strscpy(card->driver, card_name, sizeof(card->driver)); strscpy(card->shortname, card_name, sizeof(card->shortname)); sprintf(card->longname, "%s %i", card_name, card->dev->id); diff --git a/drivers/usb/gadget/function/u_audio.h b/drivers/usb/gadget/function/u_audio.h index 5ea6b86f1fda..a218cdf771fe 100644 --- a/drivers/usb/gadget/function/u_audio.h +++ b/drivers/usb/gadget/function/u_audio.h @@ -11,6 +11,14 @@ #include <linux/usb/composite.h> +/* + * Same maximum frequency deviation on the slower side as in + * sound/usb/endpoint.c. Value is expressed in per-mil deviation. + * The maximum deviation on the faster side will be provided as + * parameter, as it impacts the endpoint required bandwidth. + */ +#define FBACK_SLOW_MAX 250 + struct uac_params { /* playback */ int p_chmask; /* channel mask */ @@ -23,6 +31,7 @@ struct uac_params { int c_ssize; /* sample size */ int req_number; /* number of preallocated requests */ + int fb_max; /* upper frequency drift feedback limit per-mil */ }; struct g_audio { @@ -30,7 +39,10 @@ struct g_audio { struct usb_gadget *gadget; struct usb_ep *in_ep; + struct usb_ep *out_ep; + /* feedback IN endpoint corresponding to out_ep */ + struct usb_ep *in_ep_fback; /* Max packet size for all in_ep possible speeds */ unsigned int in_ep_maxpsize; diff --git a/drivers/usb/gadget/function/u_hid.h b/drivers/usb/gadget/function/u_hid.h index 84e6da302499..98d6af558c03 100644 --- a/drivers/usb/gadget/function/u_hid.h +++ b/drivers/usb/gadget/function/u_hid.h @@ -29,8 +29,8 @@ struct f_hid_opts { * Protect the data form concurrent access by read/write * and create symlink/remove symlink. */ - struct mutex lock; - int refcnt; + struct mutex lock; + int refcnt; }; int ghid_setup(struct usb_gadget *g, int count); diff --git a/drivers/usb/gadget/function/u_midi.h b/drivers/usb/gadget/function/u_midi.h index f6e14af7f566..2e400b495cb8 100644 --- a/drivers/usb/gadget/function/u_midi.h +++ b/drivers/usb/gadget/function/u_midi.h @@ -29,8 +29,8 @@ struct f_midi_opts { * Protect the data form concurrent access by read/write * and create symlink/remove symlink. */ - struct mutex lock; - int refcnt; + struct mutex lock; + int refcnt; }; #endif /* U_MIDI_H */ diff --git a/drivers/usb/gadget/function/u_uac2.h b/drivers/usb/gadget/function/u_uac2.h index b5035711172d..179d3ef6a195 100644 --- a/drivers/usb/gadget/function/u_uac2.h +++ b/drivers/usb/gadget/function/u_uac2.h @@ -21,7 +21,9 @@ #define UAC2_DEF_CCHMASK 0x3 #define UAC2_DEF_CSRATE 64000 #define UAC2_DEF_CSSIZE 2 +#define UAC2_DEF_CSYNC USB_ENDPOINT_SYNC_ASYNC #define UAC2_DEF_REQ_NUM 2 +#define UAC2_DEF_FB_MAX 5 struct f_uac2_opts { struct usb_function_instance func_inst; @@ -31,7 +33,9 @@ struct f_uac2_opts { int c_chmask; int c_srate; int c_ssize; + int c_sync; int req_number; + int fb_max; bool bound; struct mutex lock; diff --git a/drivers/usb/gadget/function/uvc_configfs.c b/drivers/usb/gadget/function/uvc_configfs.c index cd28dec837dd..77d64031aa9c 100644 --- a/drivers/usb/gadget/function/uvc_configfs.c +++ b/drivers/usb/gadget/function/uvc_configfs.c @@ -914,8 +914,6 @@ static int uvcg_streaming_header_allow_link(struct config_item *src, target_fmt = container_of(to_config_group(target), struct uvcg_format, group); - if (!target_fmt) - goto out; uvcg_format_set_indices(to_config_group(target)); @@ -955,8 +953,6 @@ static void uvcg_streaming_header_drop_link(struct config_item *src, mutex_lock(&opts->lock); target_fmt = container_of(to_config_group(target), struct uvcg_format, group); - if (!target_fmt) - goto out; list_for_each_entry_safe(format_ptr, tmp, &src_hdr->formats, entry) if (format_ptr->fmt == target_fmt) { @@ -968,7 +964,6 @@ static void uvcg_streaming_header_drop_link(struct config_item *src, --target_fmt->linked; -out: mutex_unlock(&opts->lock); mutex_unlock(su_mutex); } diff --git a/drivers/usb/gadget/legacy/hid.c b/drivers/usb/gadget/legacy/hid.c index c4eda7fe7ab4..5b27d289443f 100644 --- a/drivers/usb/gadget/legacy/hid.c +++ b/drivers/usb/gadget/legacy/hid.c @@ -171,8 +171,10 @@ static int hid_bind(struct usb_composite_dev *cdev) struct usb_descriptor_header *usb_desc; usb_desc = usb_otg_descriptor_alloc(gadget); - if (!usb_desc) + if (!usb_desc) { + status = -ENOMEM; goto put; + } usb_otg_descriptor_init(gadget, usb_desc); otg_desc[0] = usb_desc; otg_desc[1] = NULL; diff --git a/drivers/usb/gadget/udc/bcm63xx_udc.c b/drivers/usb/gadget/udc/bcm63xx_udc.c index 9cd4a70ccdd6..a9f07c59fc37 100644 --- a/drivers/usb/gadget/udc/bcm63xx_udc.c +++ b/drivers/usb/gadget/udc/bcm63xx_udc.c @@ -288,7 +288,6 @@ struct bcm63xx_req { * @ep0_req_completed: ep0 request has completed; worker has not seen it yet. * @ep0_reply: Pending reply from gadget driver. * @ep0_request: Outstanding ep0 request. - * @debugfs_root: debugfs directory: /sys/kernel/debug/<DRV_MODULE_NAME>. */ struct bcm63xx_udc { spinlock_t lock; @@ -327,8 +326,6 @@ struct bcm63xx_udc { unsigned ep0_req_completed:1; struct usb_request *ep0_reply; struct usb_request *ep0_request; - - struct dentry *debugfs_root; }; static const struct usb_ep_ops bcm63xx_udc_ep_ops; @@ -2250,8 +2247,6 @@ static void bcm63xx_udc_init_debugfs(struct bcm63xx_udc *udc) return; root = debugfs_create_dir(udc->gadget.name, usb_debug_root); - udc->debugfs_root = root; - debugfs_create_file("usbd", 0400, root, udc, &bcm63xx_usbd_dbg_fops); debugfs_create_file("iudma", 0400, root, udc, &bcm63xx_iudma_dbg_fops); } @@ -2264,7 +2259,7 @@ static void bcm63xx_udc_init_debugfs(struct bcm63xx_udc *udc) */ static void bcm63xx_udc_cleanup_debugfs(struct bcm63xx_udc *udc) { - debugfs_remove_recursive(udc->debugfs_root); + debugfs_remove(debugfs_lookup(udc->gadget.name, usb_debug_root)); } /*********************************************************************** diff --git a/drivers/usb/gadget/udc/core.c b/drivers/usb/gadget/udc/core.c index 493ff93f7dda..b7f0b1ebaaa8 100644 --- a/drivers/usb/gadget/udc/core.c +++ b/drivers/usb/gadget/udc/core.c @@ -1148,6 +1148,53 @@ static inline void usb_gadget_udc_set_speed(struct usb_udc *udc, } /** + * usb_gadget_enable_async_callbacks - tell usb device controller to enable asynchronous callbacks + * @udc: The UDC which should enable async callbacks + * + * This routine is used when binding gadget drivers. It undoes the effect + * of usb_gadget_disable_async_callbacks(); the UDC driver should enable IRQs + * (if necessary) and resume issuing callbacks. + * + * This routine will always be called in process context. + */ +static inline void usb_gadget_enable_async_callbacks(struct usb_udc *udc) +{ + struct usb_gadget *gadget = udc->gadget; + + if (gadget->ops->udc_async_callbacks) + gadget->ops->udc_async_callbacks(gadget, true); +} + +/** + * usb_gadget_disable_async_callbacks - tell usb device controller to disable asynchronous callbacks + * @udc: The UDC which should disable async callbacks + * + * This routine is used when unbinding gadget drivers. It prevents a race: + * The UDC driver doesn't know when the gadget driver's ->unbind callback + * runs, so unless it is told to disable asynchronous callbacks, it might + * issue a callback (such as ->disconnect) after the unbind has completed. + * + * After this function runs, the UDC driver must suppress all ->suspend, + * ->resume, ->disconnect, ->reset, and ->setup callbacks to the gadget driver + * until async callbacks are again enabled. A simple-minded but effective + * way to accomplish this is to tell the UDC hardware not to generate any + * more IRQs. + * + * Request completion callbacks must still be issued. However, it's okay + * to defer them until the request is cancelled, since the pull-up will be + * turned off during the time period when async callbacks are disabled. + * + * This routine will always be called in process context. + */ +static inline void usb_gadget_disable_async_callbacks(struct usb_udc *udc) +{ + struct usb_gadget *gadget = udc->gadget; + + if (gadget->ops->udc_async_callbacks) + gadget->ops->udc_async_callbacks(gadget, false); +} + +/** * usb_udc_release - release the usb_udc struct * @dev: the dev member within usb_udc * @@ -1361,6 +1408,7 @@ static void usb_gadget_remove_driver(struct usb_udc *udc) kobject_uevent(&udc->dev.kobj, KOBJ_CHANGE); usb_gadget_disconnect(udc->gadget); + usb_gadget_disable_async_callbacks(udc); if (udc->gadget->irq) synchronize_irq(udc->gadget->irq); udc->driver->unbind(udc->gadget); @@ -1442,6 +1490,7 @@ static int udc_bind_to_driver(struct usb_udc *udc, struct usb_gadget_driver *dri driver->unbind(udc->gadget); goto err1; } + usb_gadget_enable_async_callbacks(udc); usb_udc_connect_control(udc); kobject_uevent(&udc->dev.kobj, KOBJ_CHANGE); diff --git a/drivers/usb/gadget/udc/dummy_hcd.c b/drivers/usb/gadget/udc/dummy_hcd.c index 7db773c87379..a2d956af42a2 100644 --- a/drivers/usb/gadget/udc/dummy_hcd.c +++ b/drivers/usb/gadget/udc/dummy_hcd.c @@ -934,6 +934,15 @@ static void dummy_udc_set_speed(struct usb_gadget *_gadget, dummy_udc_update_ep0(dum); } +static void dummy_udc_async_callbacks(struct usb_gadget *_gadget, bool enable) +{ + struct dummy *dum = gadget_dev_to_dummy(&_gadget->dev); + + spin_lock_irq(&dum->lock); + dum->ints_enabled = enable; + spin_unlock_irq(&dum->lock); +} + static int dummy_udc_start(struct usb_gadget *g, struct usb_gadget_driver *driver); static int dummy_udc_stop(struct usb_gadget *g); @@ -946,6 +955,7 @@ static const struct usb_gadget_ops dummy_ops = { .udc_start = dummy_udc_start, .udc_stop = dummy_udc_stop, .udc_set_speed = dummy_udc_set_speed, + .udc_async_callbacks = dummy_udc_async_callbacks, }; /*-------------------------------------------------------------------------*/ @@ -1005,7 +1015,6 @@ static int dummy_udc_start(struct usb_gadget *g, spin_lock_irq(&dum->lock); dum->devstatus = 0; dum->driver = driver; - dum->ints_enabled = 1; spin_unlock_irq(&dum->lock); return 0; diff --git a/drivers/usb/gadget/udc/fsl_qe_udc.c b/drivers/usb/gadget/udc/fsl_qe_udc.c index fa66449b3907..8e8588933628 100644 --- a/drivers/usb/gadget/udc/fsl_qe_udc.c +++ b/drivers/usb/gadget/udc/fsl_qe_udc.c @@ -541,6 +541,7 @@ static int qe_ep_init(struct qe_udc *udc, case USB_SPEED_HIGH: if ((max == 128) || (max == 256) || (max == 512)) break; + fallthrough; default: switch (max) { case 4: @@ -562,9 +563,11 @@ static int qe_ep_init(struct qe_udc *udc, case USB_SPEED_HIGH: if (max <= 1024) break; + fallthrough; case USB_SPEED_FULL: if (max <= 64) break; + fallthrough; default: if (max <= 8) break; @@ -579,6 +582,7 @@ static int qe_ep_init(struct qe_udc *udc, case USB_SPEED_HIGH: if (max <= 1024) break; + fallthrough; case USB_SPEED_FULL: if (max <= 1023) break; @@ -605,6 +609,7 @@ static int qe_ep_init(struct qe_udc *udc, default: goto en_done; } + fallthrough; case USB_SPEED_LOW: switch (max) { case 1: diff --git a/drivers/usb/gadget/udc/fsl_udc_core.c b/drivers/usb/gadget/udc/fsl_udc_core.c index ad6ff9c4188e..29fcb9b461d7 100644 --- a/drivers/usb/gadget/udc/fsl_udc_core.c +++ b/drivers/usb/gadget/udc/fsl_udc_core.c @@ -36,7 +36,6 @@ #include <linux/platform_device.h> #include <linux/fsl_devices.h> #include <linux/dmapool.h> -#include <linux/delay.h> #include <linux/of_device.h> #include <asm/byteorder.h> @@ -323,13 +322,11 @@ static int dr_controller_setup(struct fsl_udc *udc) fsl_writel(tmp, &dr_regs->endptctrl[ep_num]); } /* Config control enable i/o output, cpu endian register */ -#ifndef CONFIG_ARCH_MXC if (udc->pdata->have_sysif_regs) { ctrl = __raw_readl(&usb_sys_regs->control); ctrl |= USB_CTRL_IOENB; __raw_writel(ctrl, &usb_sys_regs->control); } -#endif #if defined(CONFIG_PPC32) && !defined(CONFIG_NOT_COHERENT_CACHE) /* Turn on cache snooping hardware, since some PowerPC platforms @@ -547,7 +544,7 @@ static int fsl_ep_enable(struct usb_ep *_ep, unsigned short max = 0; unsigned char mult = 0, zlt; int retval = -EINVAL; - unsigned long flags = 0; + unsigned long flags; ep = container_of(_ep, struct fsl_ep, ep); @@ -631,7 +628,7 @@ static int fsl_ep_disable(struct usb_ep *_ep) { struct fsl_udc *udc = NULL; struct fsl_ep *ep = NULL; - unsigned long flags = 0; + unsigned long flags; u32 epctrl; int ep_num; @@ -1001,7 +998,7 @@ out: epctrl = fsl_readl(&dr_regs->endptctrl[ep_num]); static int fsl_ep_set_halt(struct usb_ep *_ep, int value) { struct fsl_ep *ep = NULL; - unsigned long flags = 0; + unsigned long flags; int status = -EOPNOTSUPP; /* operation not supported */ unsigned char ep_dir = 0, ep_num = 0; struct fsl_udc *udc = NULL; @@ -1938,7 +1935,7 @@ static int fsl_udc_start(struct usb_gadget *g, struct usb_gadget_driver *driver) { int retval = 0; - unsigned long flags = 0; + unsigned long flags; /* lock is needed but whether should use this lock or another */ spin_lock_irqsave(&udc_controller->lock, flags); @@ -2153,7 +2150,6 @@ static int fsl_proc_read(struct seq_file *m, void *v) tmp_reg = fsl_readl(&dr_regs->endpointprime); seq_printf(m, "EP Prime Reg = [0x%x]\n\n", tmp_reg); -#ifndef CONFIG_ARCH_MXC if (udc->pdata->have_sysif_regs) { tmp_reg = usb_sys_regs->snoop1; seq_printf(m, "Snoop1 Reg : = [0x%x]\n\n", tmp_reg); @@ -2161,7 +2157,6 @@ static int fsl_proc_read(struct seq_file *m, void *v) tmp_reg = usb_sys_regs->control; seq_printf(m, "General Control Reg : = [0x%x]\n\n", tmp_reg); } -#endif /* ------fsl_udc, fsl_ep, fsl_request structure information ----- */ ep = &udc->eps[0]; @@ -2412,28 +2407,21 @@ static int fsl_udc_probe(struct platform_device *pdev) */ if (pdata->init && pdata->init(pdev)) { ret = -ENODEV; - goto err_iounmap_noclk; + goto err_iounmap; } /* Set accessors only after pdata->init() ! */ fsl_set_accessors(pdata); -#ifndef CONFIG_ARCH_MXC if (pdata->have_sysif_regs) usb_sys_regs = (void *)dr_regs + USB_DR_SYS_OFFSET; -#endif - - /* Initialize USB clocks */ - ret = fsl_udc_clk_init(pdev); - if (ret < 0) - goto err_iounmap_noclk; /* Read Device Controller Capability Parameters register */ dccparams = fsl_readl(&dr_regs->dccparams); if (!(dccparams & DCCPARAMS_DC)) { ERR("This SOC doesn't support device role\n"); ret = -ENODEV; - goto err_iounmap; + goto err_exit; } /* Get max device endpoints */ /* DEN is bidirectional ep number, max_ep doubles the number */ @@ -2442,7 +2430,7 @@ static int fsl_udc_probe(struct platform_device *pdev) ret = platform_get_irq(pdev, 0); if (ret <= 0) { ret = ret ? : -ENODEV; - goto err_iounmap; + goto err_exit; } udc_controller->irq = ret; @@ -2451,7 +2439,7 @@ static int fsl_udc_probe(struct platform_device *pdev) if (ret != 0) { ERR("cannot request irq %d err %d\n", udc_controller->irq, ret); - goto err_iounmap; + goto err_exit; } /* Initialize the udc structure including QH member and other member */ @@ -2467,10 +2455,6 @@ static int fsl_udc_probe(struct platform_device *pdev) dr_controller_setup(udc_controller); } - ret = fsl_udc_clk_finalize(pdev); - if (ret) - goto err_free_irq; - /* Setup gadget structure */ udc_controller->gadget.ops = &fsl_gadget_ops; udc_controller->gadget.max_speed = USB_SPEED_HIGH; @@ -2530,11 +2514,10 @@ err_del_udc: dma_pool_destroy(udc_controller->td_pool); err_free_irq: free_irq(udc_controller->irq, udc_controller); -err_iounmap: +err_exit: if (pdata->exit) pdata->exit(pdev); - fsl_udc_clk_release(); -err_iounmap_noclk: +err_iounmap: iounmap(dr_regs); err_release_mem_region: if (pdata->operating_mode == FSL_USB2_DR_DEVICE) @@ -2561,8 +2544,6 @@ static int fsl_udc_remove(struct platform_device *pdev) udc_controller->done = &done; usb_del_gadget_udc(&udc_controller->gadget); - fsl_udc_clk_release(); - /* DR has been stopped in usb_gadget_unregister_driver() */ remove_proc_file(); @@ -2677,10 +2658,6 @@ static int fsl_udc_otg_resume(struct device *dev) --------------------------------------------------------------------------*/ static const struct platform_device_id fsl_udc_devtype[] = { { - .name = "imx-udc-mx27", - }, { - .name = "imx-udc-mx51", - }, { .name = "fsl-usb2-udc", }, { /* sentinel */ @@ -2689,7 +2666,6 @@ static const struct platform_device_id fsl_udc_devtype[] = { MODULE_DEVICE_TABLE(platform, fsl_udc_devtype); static struct platform_driver udc_driver = { .remove = fsl_udc_remove, - /* Just for FSL i.mx SoC currently */ .id_table = fsl_udc_devtype, /* these suspend and resume are not usb suspend and resume */ .suspend = fsl_udc_suspend, diff --git a/drivers/usb/gadget/udc/fsl_usb2_udc.h b/drivers/usb/gadget/udc/fsl_usb2_udc.h index 4ba651ae9048..2efc5a930b48 100644 --- a/drivers/usb/gadget/udc/fsl_usb2_udc.h +++ b/drivers/usb/gadget/udc/fsl_usb2_udc.h @@ -588,23 +588,4 @@ static inline struct ep_queue_head *get_qh_by_ep(struct fsl_ep *ep) USB_DIR_IN) ? 1 : 0]; } -struct platform_device; -#ifdef CONFIG_ARCH_MXC -int fsl_udc_clk_init(struct platform_device *pdev); -int fsl_udc_clk_finalize(struct platform_device *pdev); -void fsl_udc_clk_release(void); -#else -static inline int fsl_udc_clk_init(struct platform_device *pdev) -{ - return 0; -} -static inline int fsl_udc_clk_finalize(struct platform_device *pdev) -{ - return 0; -} -static inline void fsl_udc_clk_release(void) -{ -} -#endif - #endif diff --git a/drivers/usb/gadget/udc/gr_udc.c b/drivers/usb/gadget/udc/gr_udc.c index f8f3aa52383b..4b35739d3695 100644 --- a/drivers/usb/gadget/udc/gr_udc.c +++ b/drivers/usb/gadget/udc/gr_udc.c @@ -207,14 +207,15 @@ DEFINE_SHOW_ATTRIBUTE(gr_dfs); static void gr_dfs_create(struct gr_udc *dev) { const char *name = "gr_udc_state"; + struct dentry *root; - dev->dfs_root = debugfs_create_dir(dev_name(dev->dev), usb_debug_root); - debugfs_create_file(name, 0444, dev->dfs_root, dev, &gr_dfs_fops); + root = debugfs_create_dir(dev_name(dev->dev), usb_debug_root); + debugfs_create_file(name, 0444, root, dev, &gr_dfs_fops); } static void gr_dfs_delete(struct gr_udc *dev) { - debugfs_remove_recursive(dev->dfs_root); + debugfs_remove(debugfs_lookup(dev_name(dev->dev), usb_debug_root)); } #else /* !CONFIG_USB_GADGET_DEBUG_FS */ diff --git a/drivers/usb/gadget/udc/gr_udc.h b/drivers/usb/gadget/udc/gr_udc.h index ac5b3f65adb5..70134239179e 100644 --- a/drivers/usb/gadget/udc/gr_udc.h +++ b/drivers/usb/gadget/udc/gr_udc.h @@ -215,8 +215,6 @@ struct gr_udc { struct list_head ep_list; spinlock_t lock; /* General lock, a.k.a. "dev->lock" in comments */ - - struct dentry *dfs_root; }; #define to_gr_udc(gadget) (container_of((gadget), struct gr_udc, gadget)) diff --git a/drivers/usb/gadget/udc/lpc32xx_udc.c b/drivers/usb/gadget/udc/lpc32xx_udc.c index 3f1c62adce4b..a25d01c89564 100644 --- a/drivers/usb/gadget/udc/lpc32xx_udc.c +++ b/drivers/usb/gadget/udc/lpc32xx_udc.c @@ -127,7 +127,6 @@ struct lpc32xx_udc { struct usb_gadget_driver *driver; struct platform_device *pdev; struct device *dev; - struct dentry *pde; spinlock_t lock; struct i2c_client *isp1301_i2c_client; @@ -528,12 +527,12 @@ DEFINE_SHOW_ATTRIBUTE(udc); static void create_debug_file(struct lpc32xx_udc *udc) { - udc->pde = debugfs_create_file(debug_filename, 0, NULL, udc, &udc_fops); + debugfs_create_file(debug_filename, 0, NULL, udc, &udc_fops); } static void remove_debug_file(struct lpc32xx_udc *udc) { - debugfs_remove(udc->pde); + debugfs_remove(debugfs_lookup(debug_filename, NULL)); } #else diff --git a/drivers/usb/gadget/udc/mv_u3d_core.c b/drivers/usb/gadget/udc/mv_u3d_core.c index 5486f5a70868..ce3d7a3eb7e3 100644 --- a/drivers/usb/gadget/udc/mv_u3d_core.c +++ b/drivers/usb/gadget/udc/mv_u3d_core.c @@ -941,7 +941,7 @@ mv_u3d_ep_set_stall(struct mv_u3d *u3d, u8 ep_num, u8 direction, int stall) static int mv_u3d_ep_set_halt_wedge(struct usb_ep *_ep, int halt, int wedge) { struct mv_u3d_ep *ep; - unsigned long flags = 0; + unsigned long flags; int status = 0; struct mv_u3d *u3d; diff --git a/drivers/usb/gadget/udc/mv_udc_core.c b/drivers/usb/gadget/udc/mv_udc_core.c index 0fb4ef464321..7f24ce400b59 100644 --- a/drivers/usb/gadget/udc/mv_udc_core.c +++ b/drivers/usb/gadget/udc/mv_udc_core.c @@ -888,7 +888,7 @@ static int ep_is_stall(struct mv_udc *udc, u8 ep_num, u8 direction) static int mv_ep_set_halt_wedge(struct usb_ep *_ep, int halt, int wedge) { struct mv_ep *ep; - unsigned long flags = 0; + unsigned long flags; int status = 0; struct mv_udc *udc; diff --git a/drivers/usb/gadget/udc/net2272.c b/drivers/usb/gadget/udc/net2272.c index 89f479b78d80..7c38057dcb4a 100644 --- a/drivers/usb/gadget/udc/net2272.c +++ b/drivers/usb/gadget/udc/net2272.c @@ -1150,6 +1150,7 @@ net2272_pullup(struct usb_gadget *_gadget, int is_on) static int net2272_start(struct usb_gadget *_gadget, struct usb_gadget_driver *driver); static int net2272_stop(struct usb_gadget *_gadget); +static void net2272_async_callbacks(struct usb_gadget *_gadget, bool enable); static const struct usb_gadget_ops net2272_ops = { .get_frame = net2272_get_frame, @@ -1158,6 +1159,7 @@ static const struct usb_gadget_ops net2272_ops = { .pullup = net2272_pullup, .udc_start = net2272_start, .udc_stop = net2272_stop, + .udc_async_callbacks = net2272_async_callbacks, }; /*---------------------------------------------------------------------------*/ @@ -1476,7 +1478,7 @@ stop_activity(struct net2272 *dev, struct usb_gadget_driver *driver) net2272_dequeue_all(&dev->ep[i]); /* report disconnect; the driver is already quiesced */ - if (driver) { + if (dev->async_callbacks && driver) { spin_unlock(&dev->lock); driver->disconnect(&dev->gadget); spin_lock(&dev->lock); @@ -1501,6 +1503,15 @@ static int net2272_stop(struct usb_gadget *_gadget) return 0; } +static void net2272_async_callbacks(struct usb_gadget *_gadget, bool enable) +{ + struct net2272 *dev = container_of(_gadget, struct net2272, gadget); + + spin_lock_irq(&dev->lock); + dev->async_callbacks = enable; + spin_unlock_irq(&dev->lock); +} + /*---------------------------------------------------------------------------*/ /* handle ep-a/ep-b dma completions */ static void @@ -1910,9 +1921,11 @@ net2272_handle_stat0_irqs(struct net2272 *dev, u8 stat) u.r.bRequestType, u.r.bRequest, u.r.wValue, u.r.wIndex, net2272_ep_read(ep, EP_CFG)); - spin_unlock(&dev->lock); - tmp = dev->driver->setup(&dev->gadget, &u.r); - spin_lock(&dev->lock); + if (dev->async_callbacks) { + spin_unlock(&dev->lock); + tmp = dev->driver->setup(&dev->gadget, &u.r); + spin_lock(&dev->lock); + } } /* stall ep0 on error */ @@ -1994,14 +2007,14 @@ net2272_handle_stat1_irqs(struct net2272 *dev, u8 stat) if (disconnect || reset) { stop_activity(dev, dev->driver); net2272_ep0_start(dev); - spin_unlock(&dev->lock); - if (reset) - usb_gadget_udc_reset - (&dev->gadget, dev->driver); - else - (dev->driver->disconnect) - (&dev->gadget); - spin_lock(&dev->lock); + if (dev->async_callbacks) { + spin_unlock(&dev->lock); + if (reset) + usb_gadget_udc_reset(&dev->gadget, dev->driver); + else + (dev->driver->disconnect)(&dev->gadget); + spin_lock(&dev->lock); + } return; } } @@ -2015,14 +2028,14 @@ net2272_handle_stat1_irqs(struct net2272 *dev, u8 stat) if (stat & tmp) { net2272_write(dev, IRQSTAT1, tmp); if (stat & (1 << SUSPEND_REQUEST_INTERRUPT)) { - if (dev->driver->suspend) + if (dev->async_callbacks && dev->driver->suspend) dev->driver->suspend(&dev->gadget); if (!enable_suspend) { stat &= ~(1 << SUSPEND_REQUEST_INTERRUPT); dev_dbg(dev->dev, "Suspend disabled, ignoring\n"); } } else { - if (dev->driver->resume) + if (dev->async_callbacks && dev->driver->resume) dev->driver->resume(&dev->gadget); } stat &= ~tmp; diff --git a/drivers/usb/gadget/udc/net2272.h b/drivers/usb/gadget/udc/net2272.h index c669308111c2..a9994f737588 100644 --- a/drivers/usb/gadget/udc/net2272.h +++ b/drivers/usb/gadget/udc/net2272.h @@ -442,6 +442,7 @@ struct net2272 { softconnect:1, wakeup:1, added:1, + async_callbacks:1, dma_eot_polarity:1, dma_dack_polarity:1, dma_dreq_polarity:1, diff --git a/drivers/usb/gadget/udc/net2280.c b/drivers/usb/gadget/udc/net2280.c index fc9f99fe7f37..16e7d2db6411 100644 --- a/drivers/usb/gadget/udc/net2280.c +++ b/drivers/usb/gadget/udc/net2280.c @@ -1617,6 +1617,7 @@ static struct usb_ep *net2280_match_ep(struct usb_gadget *_gadget, static int net2280_start(struct usb_gadget *_gadget, struct usb_gadget_driver *driver); static int net2280_stop(struct usb_gadget *_gadget); +static void net2280_async_callbacks(struct usb_gadget *_gadget, bool enable); static const struct usb_gadget_ops net2280_ops = { .get_frame = net2280_get_frame, @@ -1625,6 +1626,7 @@ static const struct usb_gadget_ops net2280_ops = { .pullup = net2280_pullup, .udc_start = net2280_start, .udc_stop = net2280_stop, + .udc_async_callbacks = net2280_async_callbacks, .match_ep = net2280_match_ep, }; @@ -2472,7 +2474,7 @@ static void stop_activity(struct net2280 *dev, struct usb_gadget_driver *driver) nuke(&dev->ep[i]); /* report disconnect; the driver is already quiesced */ - if (driver) { + if (dev->async_callbacks && driver) { spin_unlock(&dev->lock); driver->disconnect(&dev->gadget); spin_lock(&dev->lock); @@ -2502,6 +2504,15 @@ static int net2280_stop(struct usb_gadget *_gadget) return 0; } +static void net2280_async_callbacks(struct usb_gadget *_gadget, bool enable) +{ + struct net2280 *dev = container_of(_gadget, struct net2280, gadget); + + spin_lock_irq(&dev->lock); + dev->async_callbacks = enable; + spin_unlock_irq(&dev->lock); +} + /*-------------------------------------------------------------------------*/ /* handle ep0, ep-e, ep-f with 64 byte packets: packet per irq. @@ -2814,8 +2825,6 @@ static void defect7374_workaround(struct net2280 *dev, struct usb_ctrlrequest r) * - Wait and try again. */ udelay(DEFECT_7374_PROCESSOR_WAIT_TIME); - - continue; } @@ -3042,9 +3051,11 @@ usb3_delegate: readl(&ep->cfg->ep_cfg)); ep->responded = 0; - spin_unlock(&dev->lock); - tmp = dev->driver->setup(&dev->gadget, &r); - spin_lock(&dev->lock); + if (dev->async_callbacks) { + spin_unlock(&dev->lock); + tmp = dev->driver->setup(&dev->gadget, &r); + spin_lock(&dev->lock); + } } do_stall3: if (tmp < 0) { @@ -3284,9 +3295,11 @@ delegate: w_value, w_index, w_length, readl(&ep->cfg->ep_cfg)); ep->responded = 0; - spin_unlock(&dev->lock); - tmp = dev->driver->setup(&dev->gadget, &u.r); - spin_lock(&dev->lock); + if (dev->async_callbacks) { + spin_unlock(&dev->lock); + tmp = dev->driver->setup(&dev->gadget, &u.r); + spin_lock(&dev->lock); + } } /* stall ep0 on error */ @@ -3391,14 +3404,14 @@ __acquires(dev->lock) if (disconnect || reset) { stop_activity(dev, dev->driver); ep0_start(dev); - spin_unlock(&dev->lock); - if (reset) - usb_gadget_udc_reset - (&dev->gadget, dev->driver); - else - (dev->driver->disconnect) - (&dev->gadget); - spin_lock(&dev->lock); + if (dev->async_callbacks) { + spin_unlock(&dev->lock); + if (reset) + usb_gadget_udc_reset(&dev->gadget, dev->driver); + else + (dev->driver->disconnect)(&dev->gadget); + spin_lock(&dev->lock); + } return; } } @@ -3419,12 +3432,12 @@ __acquires(dev->lock) writel(tmp, &dev->regs->irqstat1); spin_unlock(&dev->lock); if (stat & BIT(SUSPEND_REQUEST_INTERRUPT)) { - if (dev->driver->suspend) + if (dev->async_callbacks && dev->driver->suspend) dev->driver->suspend(&dev->gadget); if (!enable_suspend) stat &= ~BIT(SUSPEND_REQUEST_INTERRUPT); } else { - if (dev->driver->resume) + if (dev->async_callbacks && dev->driver->resume) dev->driver->resume(&dev->gadget); /* at high speed, note erratum 0133 */ } diff --git a/drivers/usb/gadget/udc/net2280.h b/drivers/usb/gadget/udc/net2280.h index 7da3dc1e9729..34716a9f4926 100644 --- a/drivers/usb/gadget/udc/net2280.h +++ b/drivers/usb/gadget/udc/net2280.h @@ -162,6 +162,7 @@ struct net2280 { ltm_enable:1, wakeup_enable:1, addressed_state:1, + async_callbacks:1, bug7734_patched:1; u16 chiprev; int enhanced_mode; diff --git a/drivers/usb/gadget/udc/pxa25x_udc.c b/drivers/usb/gadget/udc/pxa25x_udc.c index 10324a7334fe..69ef1e669d0c 100644 --- a/drivers/usb/gadget/udc/pxa25x_udc.c +++ b/drivers/usb/gadget/udc/pxa25x_udc.c @@ -1338,10 +1338,10 @@ DEFINE_SHOW_ATTRIBUTE(udc_debug); #define create_debug_files(dev) \ do { \ - dev->debugfs_udc = debugfs_create_file(dev->gadget.name, \ + debugfs_create_file(dev->gadget.name, \ S_IRUGO, NULL, dev, &udc_debug_fops); \ } while (0) -#define remove_debug_files(dev) debugfs_remove(dev->debugfs_udc) +#define remove_debug_files(dev) debugfs_remove(debugfs_lookup(dev->gadget.name, NULL)) #else /* !CONFIG_USB_GADGET_DEBUG_FILES */ diff --git a/drivers/usb/gadget/udc/pxa25x_udc.h b/drivers/usb/gadget/udc/pxa25x_udc.h index ccc6b921f067..aa4b68fd9fc0 100644 --- a/drivers/usb/gadget/udc/pxa25x_udc.h +++ b/drivers/usb/gadget/udc/pxa25x_udc.h @@ -116,10 +116,6 @@ struct pxa25x_udc { struct usb_phy *transceiver; u64 dma_mask; struct pxa25x_ep ep [PXA_UDC_NUM_ENDPOINTS]; - -#ifdef CONFIG_USB_GADGET_DEBUG_FS - struct dentry *debugfs_udc; -#endif void __iomem *regs; }; #define to_pxa25x(g) (container_of((g), struct pxa25x_udc, gadget)) diff --git a/drivers/usb/gadget/udc/pxa27x_udc.c b/drivers/usb/gadget/udc/pxa27x_udc.c index ce57961dfd2d..f4b7a2a3e711 100644 --- a/drivers/usb/gadget/udc/pxa27x_udc.c +++ b/drivers/usb/gadget/udc/pxa27x_udc.c @@ -208,8 +208,6 @@ static void pxa_init_debugfs(struct pxa_udc *udc) struct dentry *root; root = debugfs_create_dir(udc->gadget.name, usb_debug_root); - udc->debugfs_root = root; - debugfs_create_file("udcstate", 0400, root, udc, &state_dbg_fops); debugfs_create_file("queues", 0400, root, udc, &queues_dbg_fops); debugfs_create_file("epstate", 0400, root, udc, &eps_dbg_fops); @@ -217,7 +215,7 @@ static void pxa_init_debugfs(struct pxa_udc *udc) static void pxa_cleanup_debugfs(struct pxa_udc *udc) { - debugfs_remove_recursive(udc->debugfs_root); + debugfs_remove(debugfs_lookup(udc->gadget.name, usb_debug_root)); } #else @@ -1730,7 +1728,7 @@ static void udc_enable(struct pxa_udc *udc) } /** - * pxa27x_start - Register gadget driver + * pxa27x_udc_start - Register gadget driver * @g: gadget * @driver: gadget driver * diff --git a/drivers/usb/gadget/udc/pxa27x_udc.h b/drivers/usb/gadget/udc/pxa27x_udc.h index 13b2977399ab..0a6bc18a1264 100644 --- a/drivers/usb/gadget/udc/pxa27x_udc.h +++ b/drivers/usb/gadget/udc/pxa27x_udc.h @@ -440,7 +440,6 @@ struct udc_stats { * @last_interface: UDC interface of the last SET_INTERFACE host request * @last_alternate: UDC altsetting of the last SET_INTERFACE host request * @udccsr0: save of udccsr0 in case of suspend - * @debugfs_root: root entry of debug filesystem * @debugfs_state: debugfs entry for "udcstate" * @debugfs_queues: debugfs entry for "queues" * @debugfs_eps: debugfs entry for "epstate" @@ -474,9 +473,6 @@ struct pxa_udc { #ifdef CONFIG_PM unsigned udccsr0; #endif -#ifdef CONFIG_USB_GADGET_DEBUG_FS - struct dentry *debugfs_root; -#endif }; #define to_pxa(g) (container_of((g), struct pxa_udc, gadget)) diff --git a/drivers/usb/gadget/udc/s3c-hsudc.c b/drivers/usb/gadget/udc/s3c-hsudc.c index 7bd5182ce3ef..89f1f8c9f02e 100644 --- a/drivers/usb/gadget/udc/s3c-hsudc.c +++ b/drivers/usb/gadget/udc/s3c-hsudc.c @@ -1220,9 +1220,8 @@ static int s3c_hsudc_probe(struct platform_device *pdev) struct s3c24xx_hsudc_platdata *pd = dev_get_platdata(&pdev->dev); int ret, i; - hsudc = devm_kzalloc(&pdev->dev, sizeof(struct s3c_hsudc) + - sizeof(struct s3c_hsudc_ep) * pd->epnum, - GFP_KERNEL); + hsudc = devm_kzalloc(&pdev->dev, struct_size(hsudc, ep, pd->epnum), + GFP_KERNEL); if (!hsudc) return -ENOMEM; diff --git a/drivers/usb/gadget/udc/s3c2410_udc.c b/drivers/usb/gadget/udc/s3c2410_udc.c index b154b62abefa..179777cb699f 100644 --- a/drivers/usb/gadget/udc/s3c2410_udc.c +++ b/drivers/usb/gadget/udc/s3c2410_udc.c @@ -198,7 +198,7 @@ static inline void s3c2410_udc_set_ep0_de(void __iomem *base) udc_writeb(base, S3C2410_UDC_EP0_CSR_DE, S3C2410_UDC_EP0_CSR_REG); } -inline void s3c2410_udc_set_ep0_ss(void __iomem *b) +static inline void s3c2410_udc_set_ep0_ss(void __iomem *b) { udc_writeb(b, S3C2410_UDC_INDEX_EP0, S3C2410_UDC_INDEX_REG); udc_writeb(b, S3C2410_UDC_EP0_CSR_SENDSTL, S3C2410_UDC_EP0_CSR_REG); @@ -1843,9 +1843,8 @@ static int s3c2410_udc_probe(struct platform_device *pdev) if (retval) goto err_add_udc; - udc->regs_info = debugfs_create_file("registers", S_IRUGO, - s3c2410_udc_debugfs_root, udc, - &s3c2410_udc_debugfs_fops); + debugfs_create_file("registers", S_IRUGO, s3c2410_udc_debugfs_root, udc, + &s3c2410_udc_debugfs_fops); dev_dbg(dev, "probe ok\n"); @@ -1889,7 +1888,7 @@ static int s3c2410_udc_remove(struct platform_device *pdev) return -EBUSY; usb_del_gadget_udc(&udc->gadget); - debugfs_remove(udc->regs_info); + debugfs_remove(debugfs_lookup("registers", s3c2410_udc_debugfs_root)); if (udc_info && !udc_info->udc_command && gpio_is_valid(udc_info->pullup_pin)) diff --git a/drivers/usb/gadget/udc/s3c2410_udc.h b/drivers/usb/gadget/udc/s3c2410_udc.h index 68bdf3e5aac2..135a5bff3c74 100644 --- a/drivers/usb/gadget/udc/s3c2410_udc.h +++ b/drivers/usb/gadget/udc/s3c2410_udc.h @@ -89,7 +89,6 @@ struct s3c2410_udc { unsigned req_config : 1; unsigned req_pending : 1; u8 vbus; - struct dentry *regs_info; int irq; }; #define to_s3c2410(g) (container_of((g), struct s3c2410_udc, gadget)) diff --git a/drivers/usb/gadget/udc/tegra-xudc.c b/drivers/usb/gadget/udc/tegra-xudc.c index 2319c9737c2b..a54d1cef17db 100644 --- a/drivers/usb/gadget/udc/tegra-xudc.c +++ b/drivers/usb/gadget/udc/tegra-xudc.c @@ -1907,7 +1907,7 @@ static void tegra_xudc_ep_free_request(struct usb_ep *usb_ep, kfree(req); } -static struct usb_ep_ops tegra_xudc_ep_ops = { +static const struct usb_ep_ops tegra_xudc_ep_ops = { .enable = tegra_xudc_ep_enable, .disable = tegra_xudc_ep_disable, .alloc_request = tegra_xudc_ep_alloc_request, @@ -1928,7 +1928,7 @@ static int tegra_xudc_ep0_disable(struct usb_ep *usb_ep) return -EBUSY; } -static struct usb_ep_ops tegra_xudc_ep0_ops = { +static const struct usb_ep_ops tegra_xudc_ep0_ops = { .enable = tegra_xudc_ep0_enable, .disable = tegra_xudc_ep0_disable, .alloc_request = tegra_xudc_ep_alloc_request, @@ -2168,7 +2168,7 @@ static int tegra_xudc_set_selfpowered(struct usb_gadget *gadget, int is_on) return 0; } -static struct usb_gadget_ops tegra_xudc_gadget_ops = { +static const struct usb_gadget_ops tegra_xudc_gadget_ops = { .get_frame = tegra_xudc_gadget_get_frame, .wakeup = tegra_xudc_gadget_wakeup, .pullup = tegra_xudc_gadget_pullup, @@ -3508,10 +3508,8 @@ static int tegra_xudc_phy_get(struct tegra_xudc *xudc) xudc->utmi_phy[i] = devm_phy_optional_get(xudc->dev, phy_name); if (IS_ERR(xudc->utmi_phy[i])) { err = PTR_ERR(xudc->utmi_phy[i]); - if (err != -EPROBE_DEFER) - dev_err(xudc->dev, "failed to get usb2-%d PHY: %d\n", - i, err); - + dev_err_probe(xudc->dev, err, + "failed to get usb2-%d PHY\n", i); goto clean_up; } else if (xudc->utmi_phy[i]) { /* Get usb-phy, if utmi phy is available */ @@ -3520,8 +3518,8 @@ static int tegra_xudc_phy_get(struct tegra_xudc *xudc) &xudc->vbus_nb); if (IS_ERR(xudc->usbphy[i])) { err = PTR_ERR(xudc->usbphy[i]); - dev_err(xudc->dev, "failed to get usbphy-%d: %d\n", - i, err); + dev_err_probe(xudc->dev, err, + "failed to get usbphy-%d\n", i); goto clean_up; } } else if (!xudc->utmi_phy[i]) { @@ -3538,10 +3536,8 @@ static int tegra_xudc_phy_get(struct tegra_xudc *xudc) xudc->usb3_phy[i] = devm_phy_optional_get(xudc->dev, phy_name); if (IS_ERR(xudc->usb3_phy[i])) { err = PTR_ERR(xudc->usb3_phy[i]); - if (err != -EPROBE_DEFER) - dev_err(xudc->dev, "failed to get usb3-%d PHY: %d\n", - usb3, err); - + dev_err_probe(xudc->dev, err, + "failed to get usb3-%d PHY\n", usb3); goto clean_up; } else if (xudc->usb3_phy[i]) dev_dbg(xudc->dev, "usb3-%d PHY registered", usb3); @@ -3781,9 +3777,7 @@ static int tegra_xudc_probe(struct platform_device *pdev) err = devm_clk_bulk_get(&pdev->dev, xudc->soc->num_clks, xudc->clks); if (err) { - if (err != -EPROBE_DEFER) - dev_err(xudc->dev, "failed to request clocks: %d\n", err); - + dev_err_probe(xudc->dev, err, "failed to request clocks\n"); return err; } @@ -3798,9 +3792,7 @@ static int tegra_xudc_probe(struct platform_device *pdev) err = devm_regulator_bulk_get(&pdev->dev, xudc->soc->num_supplies, xudc->supplies); if (err) { - if (err != -EPROBE_DEFER) - dev_err(xudc->dev, "failed to request regulators: %d\n", err); - + dev_err_probe(xudc->dev, err, "failed to request regulators\n"); return err; } diff --git a/drivers/usb/gadget/udc/trace.c b/drivers/usb/gadget/udc/trace.c index 7430624c0bd7..19e837de2a20 100644 --- a/drivers/usb/gadget/udc/trace.c +++ b/drivers/usb/gadget/udc/trace.c @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-2.0 -/** +/* * trace.c - USB Gadget Framework Trace Support * * Copyright (C) 2016 Intel Corporation diff --git a/drivers/usb/gadget/udc/trace.h b/drivers/usb/gadget/udc/trace.h index 2d1f68b5ea76..98584f6b6c66 100644 --- a/drivers/usb/gadget/udc/trace.h +++ b/drivers/usb/gadget/udc/trace.h @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-2.0 -/** +/* * udc.c - Core UDC Framework * * Copyright (C) 2016 Intel Corporation diff --git a/drivers/usb/gadget/udc/udc-xilinx.c b/drivers/usb/gadget/udc/udc-xilinx.c index 72f2ea062d55..fb4ffedd6f0d 100644 --- a/drivers/usb/gadget/udc/udc-xilinx.c +++ b/drivers/usb/gadget/udc/udc-xilinx.c @@ -791,7 +791,7 @@ static int xudc_ep_set_halt(struct usb_ep *_ep, int value) } /** - * xudc_ep_enable - Enables the given endpoint. + * __xudc_ep_enable - Enables the given endpoint. * @ep: pointer to the xusb endpoint structure. * @desc: pointer to usb endpoint descriptor. * @@ -987,7 +987,7 @@ static void xudc_free_request(struct usb_ep *_ep, struct usb_request *_req) } /** - * xudc_ep0_queue - Adds the request to endpoint 0 queue. + * __xudc_ep0_queue - Adds the request to endpoint 0 queue. * @ep0: pointer to the xusb endpoint 0 structure. * @req: pointer to the xusb request structure. * |