summaryrefslogtreecommitdiffstats
path: root/drivers/usb/dwc2/hcd.c
Commit message (Collapse)AuthorAgeFilesLines
* usb: dwc2: use well defined macros for power_downJisheng Zhang2020-06-181-2/+2
| | | | | | | | | | | Use the well defined macros such as DWC2_POWER_DOWN_PARAM_NONE, DWC2_POWER_DOWN_PARAM_PARTIAL and DWC2_POWER_DOWN_PARAM_HIBERNATION to make code more readable. Signed-off-by: Jisheng Zhang <Jisheng.Zhang@synaptics.com> Acked-by: Minas Harutyunyan <hminas@synopsys.com> Link: https://lore.kernel.org/r/20200616162617.38365cc8@xhacker.debian Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
* usb: dwc2: Fix NULL qh in dwc2_queue_transactionAlexandru M Stan2020-01-151-1/+1
| | | | | | | | | | | | | | | | When a usb device disconnects in a certain way, dwc2_queue_transaction still gets called after dwc2_hcd_cleanup_channels. dwc2_hcd_cleanup_channels does "channel->qh = NULL;" but dwc2_queue_transaction still wants to dereference qh. This adds a check for a null qh. Acked-by: Minas Harutyunyan <hminas@synopsys.com> Signed-off-by: Alexandru M Stan <amstan@chromium.org> [dianders: rebased to mainline] Signed-off-by: Douglas Anderson <dianders@chromium.org> Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
* usb: add a HCD_DMA flag instead of guestimating DMA capabilitiesChristoph Hellwig2019-08-211-3/+3
| | | | | | | | | | | | | | | | | | The usb core is the only major place in the kernel that checks for a non-NULL device dma_mask to see if a device is DMA capable. This is generally a bad idea, as all major busses always set up a DMA mask, even if the device is not DMA capable - in fact bus layers like PCI can't even know if a device is DMA capable at enumeration time. This leads to lots of workaround in HCD drivers, and also prevented us from setting up a DMA mask for platform devices by default last time we tried. Replace this guess with an explicit HCD_DMA that is set by drivers that appear to have DMA support. Signed-off-by: Christoph Hellwig <hch@lst.de> Link: https://lore.kernel.org/r/20190816062435.881-4-hch@lst.de Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
* usb: add a hcd_uses_dma helperChristoph Hellwig2019-08-151-1/+1
| | | | | | | | | | | | | The USB buffer allocation code is the only place in the usb core (and in fact the whole kernel) that uses is_device_dma_capable, while the URB mapping code uses the uses_dma flag in struct usb_bus. Switch the buffer allocation to use the uses_dma flag used by the rest of the USB code, and create a helper in hcd.h that checks this flag as well as the CONFIG_HAS_DMA to simplify the caller a bit. Signed-off-by: Christoph Hellwig <hch@lst.de> Link: https://lore.kernel.org/r/20190811080520.21712-3-hch@lst.de Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
* Revert "usb: dwc2: host: Setting qtd to NULL after freeing it"Guenter Roeck2019-06-181-1/+0
| | | | | | | | | | | | | | | | | | This reverts commit b0d659022e5c96ee5c4bd62d22d3da2d66de306b. The reverted commit does nothing but adding two unnecessary lines of code. It sets a local variable to NULL in two functions, but that variable is not used anywhere in the rest of those functions. This is just confusing, so let's remove it. Cc: Vardan Mikayelyan <mvardan@synopsys.com> Cc: John Youn <johnyoun@synopsys.com> Cc: Douglas Anderson <dianders@chromiun.org> Cc: Felipe Balbi <felipe.balbi@linux.intel.com> Acked-by: Minas Harutyunyan <hminas@synopsys.com> Reviewed-by: Douglas Anderson <dianders@chromium.org> Signed-off-by: Guenter Roeck <linux@roeck-us.net> Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
* USB: dwc2: Don't turn off the usbphy in suspend if wakeup is enabledDouglas Anderson2019-06-181-0/+19
| | | | | | | | | | | | | | | | | | | | | If the 'snps,need-phy-for-wake' is set in the device tree then: - We know that we can wakeup, so call device_set_wakeup_capable(). The USB core will use this knowledge to enable wakeup by default. - We know that we should keep the PHY on during suspend if something on our root hub needs remote wakeup. This requires the patch (USB: Export usb_wakeup_enabled_descendants()). Note that we don't keep the PHY on at suspend time if it's not needed because it would be a power draw. If we later find some users of dwc2 that can support wakeup without keeping the PHY on we may want to add a way to call device_set_wakeup_capable() without keeping the PHY on at suspend time. Signed-off-by: Douglas Anderson <dianders@chromium.org> Signed-off-by: Chris Zhong <zyw@rock-chips.com> Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
* usb: dwc2: Fix DMA cache alignment issuesMartin Schiller2019-06-061-3/+7
| | | | | | | | | | | | | | | | | Insert a padding between data and the stored_xfer_buffer pointer to ensure they are not on the same cache line. Otherwise, the stored_xfer_buffer gets corrupted for IN URBs on non-cache-coherent systems. (In my case: Lantiq xRX200 MIPS) Fixes: 3bc04e28a030 ("usb: dwc2: host: Get aligned DMA in a more supported way") Fixes: 56406e017a88 ("usb: dwc2: Fix DMA alignment to start at allocated boundary") Cc: <stable@vger.kernel.org> Tested-by: Douglas Anderson <dianders@chromium.org> Reviewed-by: Douglas Anderson <dianders@chromium.org> Acked-by: Minas Harutyunyan <hminas@synopsys.com> Signed-off-by: Martin Schiller <ms@dev.tdt.de> Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
* usb: dwc2: host: Fix wMaxPacketSize handling (fix webcam regression)Douglas Anderson2019-06-061-12/+17
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | In commit abb621844f6a ("usb: ch9: make usb_endpoint_maxp() return only packet size") the API to usb_endpoint_maxp() changed. It used to just return wMaxPacketSize but after that commit it returned wMaxPacketSize with the high bits (the multiplier) masked off. If you wanted to get the multiplier it was now up to your code to call the new usb_endpoint_maxp_mult() which was introduced in commit 541b6fe63023 ("usb: add helper to extract bits 12:11 of wMaxPacketSize"). Prior to the API change most host drivers were updated, but no update was made to dwc2. Presumably it was assumed that dwc2 was too simplistic to use the multiplier and thus just didn't support a certain class of USB devices. However, it turns out that dwc2 did use the multiplier and many devices using it were working quite nicely. That means that many USB devices have been broken since the API change. One such device is a Logitech HD Pro Webcam C920. Specifically, though dwc2 didn't directly call usb_endpoint_maxp(), it did call usb_maxpacket() which in turn called usb_endpoint_maxp(). Let's update dwc2 to work properly with the new API. Fixes: abb621844f6a ("usb: ch9: make usb_endpoint_maxp() return only packet size") Cc: stable@vger.kernel.org Acked-by: Minas Harutyunyan <hminas@synopsys.com> Reviewed-by: Matthias Kaehlcke <mka@chromium.org> Signed-off-by: Douglas Anderson <dianders@chromium.org> Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
* usb: dwc2: Fix channel disable flowMinas Harutyunyan2019-05-031-14/+20
| | | | | | | | | Channel disabling/halting should performed for enabled only channels to avoid warnings "Unable to clear enable on channel N" which seen if host works in Slave mode. Signed-off-by: Minas Harutyunyan <hminas@synopsys.com> Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
* usb: dwc2: Move phy init into coreJules Maselbas2019-05-031-190/+0
| | | | | | | | | | As the phy initialization is almost the same in host and gadget mode. This only move the phy initialization functions into core.c for now, the goal is to share theses functions between the two modes. Acked-by: Minas Harutyunyan <hminas@synopsys.com> Signed-off-by: Jules Maselbas <jmaselbas@kalray.eu> Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
* usb: dwc2: optionally assert phy reset when waking upDouglas Anderson2019-05-031-3/+15
| | | | | | | | | | | | | | | | | | | | | | | | | | On the rk3288 USB host-only port (the one that's not the OTG-enabled port) the PHY can get into a bad state when a wakeup is asserted (not just a wakeup from full system suspend but also a wakeup from autosuspend). We can get the PHY out of its bad state by asserting its "port reset", but unfortunately that seems to assert a reset onto the USB bus so it could confuse things if we don't actually deenumerate / reenumerate the device. We can also get the PHY out of its bad state by fully resetting it using the reset from the CRU (clock reset unit), which does a more full reset. The CRU-based reset appears to actually cause devices on the bus to be removed and reinserted, which fixes the problem (albeit in a hacky way). It's unfortunate that we need to do a full re-enumeration of devices at wakeup time, but this is better than alternative of letting the bus get wedged. Signed-off-by: Douglas Anderson <dianders@chromium.org> Signed-off-by: Yunzhi Li <lyz@rock-chips.com> Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
* usb: dwc2: bus suspend/resume for hosts with DWC2_POWER_DOWN_PARAM_NONEDouglas Anderson2019-05-031-31/+53
| | | | | | | | | | | | | | | | | | This is an attempt to rehash commit 0cf884e819e0 ("usb: dwc2: add bus suspend/resume for dwc2") on ToT. That commit was reverted in commit b0bb9bb6ce01 ("Revert "usb: dwc2: add bus suspend/resume for dwc2"") because apparently it broke the Altera SOCFPGA. With all the changes that have happened to dwc2 in the meantime, it's possible that the Altera SOCFPGA will just magically work with this change now. ...and it would be good to get bus suspend/resume implemented. This change is a forward port of one that's been living in the Chrome OS 3.14 kernel tree. Signed-off-by: Douglas Anderson <dianders@chromium.org> Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
* usb: dwc2: use struct_size() in kzalloc()Gustavo A. R. Silva2019-02-191-3/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | One of the more common cases of allocation size calculations is finding the size of a structure that has a zero-sized array at the end, along with memory for some number of elements for that array. For example: struct foo { int stuff; struct boo entry[]; }; size = sizeof(struct foo) + count * sizeof(struct boo); instance = kzalloc(size, GFP_KERNEL); Instead of leaving these open-coded and prone to type mistakes, we can now use the new struct_size() helper: instance = kzalloc(struct_size(instance, entry, count), GFP_KERNEL); Notice that, in this case, variable size is not necessary, hence it is removed. This code was detected with the help of Coccinelle. Signed-off-by: Gustavo A. R. Silva <gustavo@embeddedor.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
* usb: dwc2: fix unbalanced use of external vbus-supplyFabrice Gasnier2018-10-021-7/+26
| | | | | | | | | | | | | | | | When using external vbus supply regulator, it should be enabled synchronously with PWR bit in HPRT register. This also fixes unbalanced use of this optional regulator (This can be reproduced easily when unbinding the driver). Fixes: 531ef5ebea96 ("usb: dwc2: add support for host mode external vbus supply") Tested-by: Artur Petrosyan <arturp@synopsys.com> Acked-by: Minas Harutyunyan <hminas@synopsys.com> Signed-off-by: Fabrice Gasnier <fabrice.gasnier@st.com> Signed-off-by: Amelie Delaunay <amelie.delaunay@st.com> Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
* usb: dwc2: fix call to vbus supply exit routine, call it unlockedFabrice Gasnier2018-10-021-0/+2
| | | | | | | | | | | | | | | dwc2_vbus_supply_exit() may call regulator_disable(). It shouldn't be called with interrupts disabled as it might sleep. This is seen with DEBUG_ATOMIC_SLEEP=y. Fixes: 531ef5ebea96 ("usb: dwc2: add support for host mode external vbus supply") Tested-by: Artur Petrosyan <arturp@synopsys.com> Acked-by: Minas Harutyunyan <hminas@synopsys.com> Signed-off-by: Fabrice Gasnier <fabrice.gasnier@st.com> Signed-off-by: Amelie Delaunay <amelie.delaunay@st.com> Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
* usb: dwc2: fix a race with external vbus supplyFabrice Gasnier2018-10-021-1/+9
| | | | | | | | | | | | | | | | There's a race with root hub resume, when using external vbus supply. Root hub gets resumed, but runtime pm autosuspend runs as external vbus supply isn't enabled. So, host never exit from power down properly. Initialize vbus external supply before, rater that after hub resume. Fixes: 531ef5ebea96 ("usb: dwc2: add support for host mode external vbus supply") Tested-by: Artur Petrosyan <arturp@synopsys.com> Acked-by: Minas Harutyunyan <hminas@synopsys.com> Signed-off-by: Fabrice Gasnier <fabrice.gasnier@st.com> Signed-off-by: Amelie Delaunay <amelie.delaunay@st.com> Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
* usb: dwc2: get optional vbus-supply regulator onceFabrice Gasnier2018-10-021-9/+3
| | | | | | | | | | | | | | | Move devm_regulator_get_optional() call to probe routine. This avoids 'vbus-supply' regulator to be requested lots of times, upon each call to dwc2_vbus_supply_init(), e.g. like with runtime pm. Fixes: 531ef5ebea96 ("usb: dwc2: add support for host mode external vbus supply") Tested-by: Artur Petrosyan <arturp@synopsys.com> Acked-by: Minas Harutyunyan <hminas@synopsys.com> Signed-off-by: Fabrice Gasnier <fabrice.gasnier@st.com> Signed-off-by: Amelie Delaunay <amelie.delaunay@st.com> Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
* usb: dwc2: remove set but unused variableJosh Abraham2018-10-021-3/+0
| | | | | | | | | | | This patch removes a set but unused variable in hcd.c. Fixes gcc warning: variable ‘data_fifo’ set but not used [-Wunused-but-set-variable] Acked-by: Minas Harutyunyan <hminas@synopsys.com> Signed-off-by: Joshua Abraham <j.abraham1776@gmail.com> Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
* Merge tag 'usb-for-v4.19' of ↵Greg Kroah-Hartman2018-07-301-230/+229
|\ | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | git://git.kernel.org/pub/scm/linux/kernel/git/balbi/usb into usb-next Felipe writes: usb: changes for v4.19 Not a big pull request with only 37 non-merge commits, most of which are touching dwc2 (74% of the changes). The most important changes are dwc2's support for uframe scheduling and its endian-agnostic readl/writel wrappers. From dwc3 side we have a special new glue layer for Synopsys HAPS which will help Synopsys running FPGA validation using our upstream driver. We also have the beginnings of dual-role support for Intel Merrifield platform. Apart from these, just a series of non-critical changes.
| * usb: dwc2: Modify dwc2_readl/writel functions prototypeGevorg Sahakyan2018-07-301-230/+229
| | | | | | | | | | | | | | | | | | | | | | | | Added hsotg argument to dwc2_readl/writel function prototype, and also instead of address pass offset of register. hsotg will contain flag field for endianness. Also customized dwc2_set_bit and dwc2_clear_bit function for dwc2_readl/writel functions. Signed-off-by: Gevorg Sahakyan <sahakyan@synopsys.com> Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
* | usb: dwc2: Fix inefficient copy of unaligned buffersAntti Seppälä2018-07-171-3/+9
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Make sure only to copy any actual data rather than the whole buffer, when releasing the temporary buffer used for unaligned non-isochronous transfers. Taken directly from commit 0efd937e27d5e ("USB: ehci-tegra: fix inefficient copy of unaligned buffers") Tested with Lantiq xRX200 (MIPS) and RPi Model B Rev 2 (ARM) Reviewed-by: Douglas Anderson <dianders@chromium.org> Signed-off-by: Antti Seppälä <a.seppala@gmail.com> Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
* | usb: dwc2: Fix DMA alignment to start at allocated boundaryAntti Seppälä2018-07-171-21/+23
|/ | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The commit 3bc04e28a030 ("usb: dwc2: host: Get aligned DMA in a more supported way") introduced a common way to align DMA allocations. The code in the commit aligns the struct dma_aligned_buffer but the actual DMA address pointed by data[0] gets aligned to an offset from the allocated boundary by the kmalloc_ptr and the old_xfer_buffer pointers. This is against the recommendation in Documentation/DMA-API.txt which states: Therefore, it is recommended that driver writers who don't take special care to determine the cache line size at run time only map virtual regions that begin and end on page boundaries (which are guaranteed also to be cache line boundaries). The effect of this is that architectures with non-coherent DMA caches may run into memory corruption or kernel crashes with Unhandled kernel unaligned accesses exceptions. Fix the alignment by positioning the DMA area in front of the allocation and use memory at the end of the area for storing the orginal transfer_buffer pointer. This may have the added benefit of increased performance as the DMA area is now fully aligned on all architectures. Tested with Lantiq xRX200 (MIPS) and RPi Model B Rev 2 (ARM). Fixes: 3bc04e28a030 ("usb: dwc2: host: Get aligned DMA in a more supported way") Cc: <stable@vger.kernel.org> Reviewed-by: Douglas Anderson <dianders@chromium.org> Signed-off-by: Antti Seppälä <a.seppala@gmail.com> Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
* usb: dwc2: alloc dma aligned buffer for isoc split inWilliam Wu2018-06-191-5/+84
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The commit 3bc04e28a030 ("usb: dwc2: host: Get aligned DMA in a more supported way") rips out a lot of code to simply the allocation of aligned DMA. However, it also introduces a new issue when use isoc split in transfer. In my test case, I connect the dwc2 controller with an usb hs Hub (GL852G-12), and plug an usb fs audio device (Plantronics headset) into the downstream port of Hub. Then use the usb mic to record, we can find noise when playback. It's because that the usb Hub uses an MDATA for the first transaction and a DATA0 for the second transaction for the isoc split in transaction. An typical isoc split in transaction sequence like this: - SSPLIT IN transaction - CSPLIT IN transaction - MDATA packet - CSPLIT IN transaction - DATA0 packet The DMA address of MDATA (urb->dma) is always DWORD-aligned, but the DMA address of DATA0 (urb->dma + qtd->isoc_split_offset) may not be DWORD-aligned, it depends on the qtd->isoc_split_offset (the length of MDATA). In my test case, the length of MDATA is usually unaligned, this cause DATA0 packet transmission error. This patch use kmem_cache to allocate aligned DMA buf for isoc split in transaction. Note that according to usb 2.0 spec, the maximum data payload size is 1023 bytes for each fs isoc ep, and the maximum allowable interrupt data payload size is 64 bytes or less for fs interrupt ep. So we set the size of object to be 1024 bytes in the kmem cache. Tested-by: Gevorg Sahakyan <sahakyan@synopsys.com> Tested-by: Heiko Stuebner <heiko@sntech.de> Acked-by: Minas Harutyunyan hminas@synopsys.com> Signed-off-by: William Wu <william.wu@rock-chips.com> Reviewed-by: Douglas Anderson <dianders@chromium.org> Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
* usb: dwc2: Fix host exit from hibernation flow.Artur Petrosyan2018-06-191-1/+3
| | | | | | | | | | | | | | | | In case when a hub is connected to DWC2 host auto suspend occurs and host goes to hibernation. When any device connected to hub host hibernation exiting incorrectly. - Added dwc2_hcd_rem_wakeup() function call to exit from suspend state by remote wakeup. - Increase timeout value for port suspend bit to be set. Acked-by: Minas Harutyunyan <hminas@synopsys.com> Signed-off-by: Artur Petrosyan <arturp@synopsys.com> Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
* treewide: kzalloc() -> kcalloc()Kees Cook2018-06-121-5/+6
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The kzalloc() function has a 2-factor argument form, kcalloc(). This patch replaces cases of: kzalloc(a * b, gfp) with: kcalloc(a * b, gfp) as well as handling cases of: kzalloc(a * b * c, gfp) with: kzalloc(array3_size(a, b, c), gfp) as it's slightly less ugly than: kzalloc_array(array_size(a, b), c, gfp) This does, however, attempt to ignore constant size factors like: kzalloc(4 * 1024, gfp) though any constants defined via macros get caught up in the conversion. Any factors with a sizeof() of "unsigned char", "char", and "u8" were dropped, since they're redundant. The Coccinelle script used for this was: // Fix redundant parens around sizeof(). @@ type TYPE; expression THING, E; @@ ( kzalloc( - (sizeof(TYPE)) * E + sizeof(TYPE) * E , ...) | kzalloc( - (sizeof(THING)) * E + sizeof(THING) * E , ...) ) // Drop single-byte sizes and redundant parens. @@ expression COUNT; typedef u8; typedef __u8; @@ ( kzalloc( - sizeof(u8) * (COUNT) + COUNT , ...) | kzalloc( - sizeof(__u8) * (COUNT) + COUNT , ...) | kzalloc( - sizeof(char) * (COUNT) + COUNT , ...) | kzalloc( - sizeof(unsigned char) * (COUNT) + COUNT , ...) | kzalloc( - sizeof(u8) * COUNT + COUNT , ...) | kzalloc( - sizeof(__u8) * COUNT + COUNT , ...) | kzalloc( - sizeof(char) * COUNT + COUNT , ...) | kzalloc( - sizeof(unsigned char) * COUNT + COUNT , ...) ) // 2-factor product with sizeof(type/expression) and identifier or constant. @@ type TYPE; expression THING; identifier COUNT_ID; constant COUNT_CONST; @@ ( - kzalloc + kcalloc ( - sizeof(TYPE) * (COUNT_ID) + COUNT_ID, sizeof(TYPE) , ...) | - kzalloc + kcalloc ( - sizeof(TYPE) * COUNT_ID + COUNT_ID, sizeof(TYPE) , ...) | - kzalloc + kcalloc ( - sizeof(TYPE) * (COUNT_CONST) + COUNT_CONST, sizeof(TYPE) , ...) | - kzalloc + kcalloc ( - sizeof(TYPE) * COUNT_CONST + COUNT_CONST, sizeof(TYPE) , ...) | - kzalloc + kcalloc ( - sizeof(THING) * (COUNT_ID) + COUNT_ID, sizeof(THING) , ...) | - kzalloc + kcalloc ( - sizeof(THING) * COUNT_ID + COUNT_ID, sizeof(THING) , ...) | - kzalloc + kcalloc ( - sizeof(THING) * (COUNT_CONST) + COUNT_CONST, sizeof(THING) , ...) | - kzalloc + kcalloc ( - sizeof(THING) * COUNT_CONST + COUNT_CONST, sizeof(THING) , ...) ) // 2-factor product, only identifiers. @@ identifier SIZE, COUNT; @@ - kzalloc + kcalloc ( - SIZE * COUNT + COUNT, SIZE , ...) // 3-factor product with 1 sizeof(type) or sizeof(expression), with // redundant parens removed. @@ expression THING; identifier STRIDE, COUNT; type TYPE; @@ ( kzalloc( - sizeof(TYPE) * (COUNT) * (STRIDE) + array3_size(COUNT, STRIDE, sizeof(TYPE)) , ...) | kzalloc( - sizeof(TYPE) * (COUNT) * STRIDE + array3_size(COUNT, STRIDE, sizeof(TYPE)) , ...) | kzalloc( - sizeof(TYPE) * COUNT * (STRIDE) + array3_size(COUNT, STRIDE, sizeof(TYPE)) , ...) | kzalloc( - sizeof(TYPE) * COUNT * STRIDE + array3_size(COUNT, STRIDE, sizeof(TYPE)) , ...) | kzalloc( - sizeof(THING) * (COUNT) * (STRIDE) + array3_size(COUNT, STRIDE, sizeof(THING)) , ...) | kzalloc( - sizeof(THING) * (COUNT) * STRIDE + array3_size(COUNT, STRIDE, sizeof(THING)) , ...) | kzalloc( - sizeof(THING) * COUNT * (STRIDE) + array3_size(COUNT, STRIDE, sizeof(THING)) , ...) | kzalloc( - sizeof(THING) * COUNT * STRIDE + array3_size(COUNT, STRIDE, sizeof(THING)) , ...) ) // 3-factor product with 2 sizeof(variable), with redundant parens removed. @@ expression THING1, THING2; identifier COUNT; type TYPE1, TYPE2; @@ ( kzalloc( - sizeof(TYPE1) * sizeof(TYPE2) * COUNT + array3_size(COUNT, sizeof(TYPE1), sizeof(TYPE2)) , ...) | kzalloc( - sizeof(TYPE1) * sizeof(THING2) * (COUNT) + array3_size(COUNT, sizeof(TYPE1), sizeof(TYPE2)) , ...) | kzalloc( - sizeof(THING1) * sizeof(THING2) * COUNT + array3_size(COUNT, sizeof(THING1), sizeof(THING2)) , ...) | kzalloc( - sizeof(THING1) * sizeof(THING2) * (COUNT) + array3_size(COUNT, sizeof(THING1), sizeof(THING2)) , ...) | kzalloc( - sizeof(TYPE1) * sizeof(THING2) * COUNT + array3_size(COUNT, sizeof(TYPE1), sizeof(THING2)) , ...) | kzalloc( - sizeof(TYPE1) * sizeof(THING2) * (COUNT) + array3_size(COUNT, sizeof(TYPE1), sizeof(THING2)) , ...) ) // 3-factor product, only identifiers, with redundant parens removed. @@ identifier STRIDE, SIZE, COUNT; @@ ( kzalloc( - (COUNT) * STRIDE * SIZE + array3_size(COUNT, STRIDE, SIZE) , ...) | kzalloc( - COUNT * (STRIDE) * SIZE + array3_size(COUNT, STRIDE, SIZE) , ...) | kzalloc( - COUNT * STRIDE * (SIZE) + array3_size(COUNT, STRIDE, SIZE) , ...) | kzalloc( - (COUNT) * (STRIDE) * SIZE + array3_size(COUNT, STRIDE, SIZE) , ...) | kzalloc( - COUNT * (STRIDE) * (SIZE) + array3_size(COUNT, STRIDE, SIZE) , ...) | kzalloc( - (COUNT) * STRIDE * (SIZE) + array3_size(COUNT, STRIDE, SIZE) , ...) | kzalloc( - (COUNT) * (STRIDE) * (SIZE) + array3_size(COUNT, STRIDE, SIZE) , ...) | kzalloc( - COUNT * STRIDE * SIZE + array3_size(COUNT, STRIDE, SIZE) , ...) ) // Any remaining multi-factor products, first at least 3-factor products, // when they're not all constants... @@ expression E1, E2, E3; constant C1, C2, C3; @@ ( kzalloc(C1 * C2 * C3, ...) | kzalloc( - (E1) * E2 * E3 + array3_size(E1, E2, E3) , ...) | kzalloc( - (E1) * (E2) * E3 + array3_size(E1, E2, E3) , ...) | kzalloc( - (E1) * (E2) * (E3) + array3_size(E1, E2, E3) , ...) | kzalloc( - E1 * E2 * E3 + array3_size(E1, E2, E3) , ...) ) // And then all remaining 2 factors products when they're not all constants, // keeping sizeof() as the second factor argument. @@ expression THING, E1, E2; type TYPE; constant C1, C2, C3; @@ ( kzalloc(sizeof(THING) * C2, ...) | kzalloc(sizeof(TYPE) * C2, ...) | kzalloc(C1 * C2 * C3, ...) | kzalloc(C1 * C2, ...) | - kzalloc + kcalloc ( - sizeof(TYPE) * (E2) + E2, sizeof(TYPE) , ...) | - kzalloc + kcalloc ( - sizeof(TYPE) * E2 + E2, sizeof(TYPE) , ...) | - kzalloc + kcalloc ( - sizeof(THING) * (E2) + E2, sizeof(THING) , ...) | - kzalloc + kcalloc ( - sizeof(THING) * E2 + E2, sizeof(THING) , ...) | - kzalloc + kcalloc ( - (E1) * E2 + E1, E2 , ...) | - kzalloc + kcalloc ( - (E1) * (E2) + E1, E2 , ...) | - kzalloc + kcalloc ( - E1 * E2 + E1, E2 , ...) ) Signed-off-by: Kees Cook <keescook@chromium.org>
* usb: dwc2: dwc2_vbus_supply_init: fix error checkTomeu Vizoso2018-05-211-5/+8
| | | | | | | | | | | | | | | | | | | devm_regulator_get_optional returns -ENODEV if the regulator isn't there, so if that's the case we have to make sure not to leave -ENODEV in the regulator pointer. Also, make sure we return 0 in that case, but correctly propagate any other errors. Also propagate the error from _dwc2_hcd_start. Fixes: 531ef5ebea96 ("usb: dwc2: add support for host mode external vbus supply") Cc: Amelie Delaunay <amelie.delaunay@st.com> Reviewed-by: Amelie Delaunay <amelie.delaunay@st.com> Reviewed-by: Heiko Stuebner <heiko@sntech.de> Reviewed-by: Grigor Tovmasyan <tovmasya@synopsys.com> Tested-by: Heiko Stuebner <heiko@sntech.de> Acked-by: Minas Harutyunyan <hminas@synopsys.com> Signed-off-by: Tomeu Vizoso <tomeu.vizoso@collabora.com> Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
* usb: dwc2: Fix kernel doc's warnings.Grigor Tovmasyan2018-05-211-2/+1
| | | | | | | | | Added descriptions for all not described parameters. Fix all kernel doc's warnings. Acked-by: Minas Harutyunyan <hminas@synopsys.com> Signed-off-by: Grigor Tovmasyan <tovmasya@synopsys.com> Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
* usb: dwc2: fix spelling mistake: "genereted" -> "generated"Colin Ian King2018-03-141-1/+1
| | | | | | | Trivial fix to spelling mistake in dev_warn warning message text. Signed-off-by: Colin Ian King <colin.king@canonical.com> Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
* usb: dwc2: add support for host mode external vbus supplyAmelie Delaunay2018-03-131-0/+26
| | | | | | | | | | | | | | This patch adds a way to enable an external vbus supply in host mode, when dwc2 drvvbus signal is not used. This patch is very similar to the one done in U-Boot dwc2 driver [1]. It also adds dynamic vbus supply management depending on the role and state of the core. [1] https://lists.denx.de/pipermail/u-boot/2017-March/283434.html Signed-off-by: Amelie Delaunay <amelie.delaunay@st.com> Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
* usb: dwc2: Force mode optimizationsVardan Mikayelyan2018-03-131-3/+3
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | If the dr_mode is USB_DR_MODE_OTG, forcing the mode is needed during driver probe to get the host and device specific HW parameters. Then we clear the force mode bits so that the core operates in OTG mode. The force mode bits should not be touched at any other time during the driver lifetime and they should be preserved whenever the GUSBCFG register is written to. The force mode bit values will persist across soft resets of the core. If the dr_mode is either USB_DR_MODE_HOST or USB_DR_MODE_PERIPHERAL, the force mode is set just once at probe to configure the core as either a host or peripheral. Given the above, we no longer need any other reset delays, force delays, or any forced modes anywhere else in the driver. So replace all calls to dwc2_core_reset_and_force_dr_mode() with dwc2_core_reset() and remove all other unnecessary delays. Also remove the dwc2_force_mode_if_needed() function since the "if needed" part is already taken care of by the polling in dwc2_force_mode(). Finally, remove all other calls to dwc2_clear_force_mode(). Tested-by: Stefan Wahren <stefan.wahren@i2se.com> Signed-off-by: John Youn <johnyoun@synopsys.com> Signed-off-by: Vardan Mikayelyan <mvardan@synopsys.com> Signed-off-by: Grigor Tovmasyan <tovmasya@synopsys.com> Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
* usb: dwc2: Change hub-control to allow hibernationVardan Mikayelyan2018-03-131-3/+13
| | | | | | | | | | | | | | | Affected cases: ClearPortFeature's USB_PORT_FEAT_SUSPEND SetPortFeature's USB_PORT_FEAT_SUSPEND USB_PORT_FEAT_RESET Signed-off-by: Vardan Mikayelyan <mvardan@synopsys.com> Signed-off-by: John Youn <johnyoun@synopsys.com> Signed-off-by: Grigor Tovmasyan <tovmasya@synopsys.com> Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
* usb: dwc2: Add dwc2_handle_gpwrdn_intr() handlerVardan Mikayelyan2018-03-131-1/+1
| | | | | | | | | | | | | | | | | | | | The GPWRDN interrupts are those that occur in both Host and Device mode while core is in hibernated state. Export dwc2_core_init to be able to use it in GPWRDN_IDSTS interrupt handler. Here we have duplicated init functions in host and gadget sides so I have left things as it was(used corresponing functions for host and gadget), maybe in the future we'll resolve this problem and will use dwc2_core_init for both sides. Signed-off-by: Vardan Mikayelyan <mvardan@synopsys.com> Signed-off-by: John Youn <johnyoun@synopsys.com> Signed-off-by: Artur Petrosyan <arturp@synopsys.com> Signed-off-by: Minas Harutyunyan <hminas@synopsys.com> Signed-off-by: Grigor Tovmasyan <tovmasya@synopsys.com> Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
* usb: dwc2: Add host/device hibernation functionsVardan Mikayelyan2018-03-131-0/+223
| | | | | | | | | | | | | | | | | | | | | | Add host/device hibernation functions which must be wrapped by core's dwc2_enter_hibernation()/dwc2_exit_hibernation() functions. Make dwc2_backup_global_registers dwc2_restore_global_register non-static to use them in both host/gadget sides. Added function names: dwc2_gadget_enter_hibernation() dwc2_gadget_exit_hibernation() dwc2_host_enter_hibernation() dwc2_host_exit_hibernation() Signed-off-by: Vardan Mikayelyan <mvardan@synopsys.com> Signed-off-by: John Youn <johnyoun@synopsys.com> Signed-off-by: Artur Petrosyan <arturp@synopsys.com> Signed-off-by: Minas Harutyunyan <hminas@synopsys.com> Signed-off-by: Grigor Tovmasyan <tovmasya@synopsys.com> Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
* usb: dwc2: Changes in registers backup/restore functionsVardan Mikayelyan2018-03-131-0/+2
| | | | | | | | | | | | | | | | | | | Move hptxfsiz to host register's backup/restore functions, not needed to have it in global register's backup/restore functions. Add backup for glpmcfg, and read/write for gi2cctl and pcgcctl. As requires programming guide. Affected functions: dwc2_backup_host_registers() dwc2_restore_host_registers() dwc2_backup_global_registers() dwc2_restore_global_registers() Signed-off-by: Vardan Mikayelyan <mvardan@synopsys.com> Signed-off-by: John Youn <johnyoun@synopsys.com> Signed-off-by: Grigor Tovmasyan <tovmasya@synopsys.com> Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
* usb: dwc2: Add hibernation field into dwc2_hw_paramsVardan Mikayelyan2018-03-131-2/+2
| | | | | | | | | | | | | | | Add parameter and it's initialization, needed for hibernation. Reimplement dwc2_set_param_power_down() to support hibernation too. Now 'power_down' parameter can be initialized with 0, 1 or 2. 0 - No 1 - Partial power down 2 - Hibernation Signed-off-by: Vardan Mikayelyan <mvardan@synopsys.com> Signed-off-by: John Youn <johnyoun@synopsys.com> Signed-off-by: Grigor Tovmasyan <tovmasya@synopsys.com> Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
* usb: dwc2: Rename hibernation to partial_power_downVardan Mikayelyan2018-03-131-13/+13
| | | | | | | | | | | | | | | No-op change, only rename. This code was misnamed originally. It was only responsible for partial power down and not for hibernation. Rename core_params->hibernation to core_params->power_down, dwc2_set_param_hibernation() to dwc2_set_param_power_down(). Signed-off-by: Vardan Mikayelyan <mvardan@synopsys.com> Signed-off-by: John Youn <johnyoun@synopsys.com> Signed-off-by: Grigor Tovmasyan <tovmasya@synopsys.com> Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
* usb: dwc2: Enable LPM Transaction Received interruptSevak Arakelyan2018-03-131-0/+3
| | | | | | | | | Enable "LPM Transaction Received" interrupt for receive an interrupt when host will send LPM token. Signed-off-by: Sevak Arakelyan <sevaka@synopsys.com> Signed-off-by: Grigor Tovmasyan <tovmasya@synopsys.com> Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
* usb: dwc2: Add ACG support to the driverRazmik Karapetyan2018-03-131-0/+5
| | | | | | | | | | | | | | | | | | | | | | | | | | | | Added function for supporting Active Clock Gating functionality in the driver. PCGCCTL1 (Power and Clock Control) register will be used for controlling the core`s active clock gating feature, and the previously reserved 12th bit in GHWCFG4 now indicates that the controller supports the Dynamic Power Reduction (Active Clock Gating) during no traffic scenarios such as L0, idle, resume and suspend states. dwc2_enable_acg() function sets GATEEN bit in PCGCCTL1 register and enables ACG, if it supported. According to ACG functional specification, enabling of ACG feature in host mode done in host initialization, before turning Vbus on, specifically in dwc2_core_host_init function. Enabling of ACG feature in device mode done in device initialization, before clearing the SftDiscon bit in DCTL. This bit was cleared in dwc2_hsotg_core_connect() function.So dwc2_enable_acg() called before dwc2_core_connect() calls. Signed-off-by: Razmik Karapetyan <razmik@synopsys.com> Signed-off-by: Grigor Tovmasyan <tovmasya@synopsys.com> Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
* usb: dwc2: host: Fix transaction errors in host modeMinas Harutyunyan2018-03-131-1/+13
| | | | | | | | | | | | | | | | Added missing GUSBCFG programming in host mode, which fixes transaction errors issue on HiKey and Altera Cyclone V boards. These field even if was programmed in device mode (in function dwc2_hsotg_core_init_disconnected()) will be resetting to POR values after core soft reset applied. So, each time when switching to host mode required to set this field to correct value. Acked-by: John Youn <johnyoun@synopsys.com> Signed-off-by: Minas Harutyunyan <hminas@synopsys.com> Signed-off-by: Grigor Tovmasyan <tovmasya@synopsys.com> Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
* usb: dwc2: hcd: Fix host channel halt flowMinas Harutyunyan2018-03-131-0/+18
| | | | | | | | | | According databook in Buffer and External DMA mode non-split periodic channels can't be halted. Acked-by: John Youn <johnyoun@synopsys.com> Signed-off-by: Minas Harutyunyan <hminas@synopsys.com> Signed-off-by: Grigor Tovmasyan <tovmasya@synopsys.com> Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
* usb: dwc2: Remove unnecessary debug printsRazmik Karapetyan2018-03-131-14/+2
| | | | | | | | | | Removed unnecessary debug prints about DMA mode for host side from dwc2_gahbcfg_init() function. Acked-by: John Youn <johnyoun@synopsys.com> Signed-off-by: Razmik Karapetyan <razmik@synopsys.com> Signed-off-by: Grigor Tovmasyan <tovmasya@synopsys.com> Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
* usb: dwc2: Delete unused functionalityGrigor Tovmasyan2018-03-131-70/+0
| | | | | | | | | | | | | | | | Deleted dwc2_hcd_dump_frrem() function, because it used undefined parameters from dwc2_hsotg structure. The function body was in #ifdef statement and was never compiled. Also removed that parameters from dwc2_hsotg structure, which were used only in dwc2_hcd_dump_frrem() function. And also delete dwc2_sample_frrem macro, because without dwc2_hcd_dump_frrem() function it's lose its purpose. Acked-by: John Youn <johnyoun@synopsys.com> Signed-off-by: Grigor Tovmasyan <tovmasya@synopsys.com> Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
* usb: dwc2: Update bit polling functionalitySevak Arakelyan2018-03-131-12/+6
| | | | | | | | | | | | | | | | Move dwc2_hsotg_wait_bit_set function to core.c so it can be used anywhere in the code. Added dwc2_hsotg_wait_bit_clear function in core.c. Replace all the parts of register bit polling code with dwc2_hsotg_wait_bit_set or dwc2_hsotg_wait_bit_clear functions calls depends on code logic. Acked-by: John Youn <johnyoun@synopsys.com> Signed-off-by: Sevak Arakelyan <sevaka@synopsys.com> Signed-off-by: Grigor Tovmasyan <tovmasya@synopsys.com> Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
* usb: dwc2: host: Don't retry NAKed transactions right awayDouglas Anderson2017-12-131-0/+7
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | On rk3288-veyron devices on Chrome OS it was found that plugging in an Arduino-based USB device could cause the system to lockup, especially if the CPU Frequency was at one of the slower operating points (like 100 MHz / 200 MHz). Upon tracing, I found that the following was happening: * The USB device (full speed) was connected to a high speed hub and then to the rk3288. Thus, we were dealing with split transactions, which is all handled in software on dwc2. * Userspace was initiating a BULK IN transfer * When we sent the SSPLIT (to start the split transaction), we got an ACK. Good. Then we issued the CSPLIT. * When we sent the CSPLIT, we got back a NAK. We immediately (from the interrupt handler) started to retry and sent another SSPLIT. * The device kept NAKing our CSPLIT, so we kept ping-ponging between sending a SSPLIT and a CSPLIT, each time sending from the interrupt handler. * The handling of the interrupts was (because of the low CPU speed and the inefficiency of the dwc2 interrupt handler) was actually taking _longer_ than it took the other side to send the ACK/NAK. Thus we were _always_ in the USB interrupt routine. * The fact that USB interrupts were always going off was preventing other things from happening in the system. This included preventing the system from being able to transition to a higher CPU frequency. As I understand it, there is no requirement to retry super quickly after a NAK, we just have to retry sometime in the future. Thus one solution to the above is to just add a delay between getting a NAK and retrying the transmission. If this delay is sufficiently long to get out of the interrupt routine then the rest of the system will be able to make forward progress. Even a 25 us delay would probably be enough, but we'll be extra conservative and try to delay 1 ms (the exact amount depends on HZ and the accuracy of the jiffy and how close the current jiffy is to ticking, but could be as much as 20 ms or as little as 1 ms). Presumably adding a delay like this could impact the USB throughput, so we only add the delay with repeated NAKs. NOTE: Upon further testing of a pl2303 serial adapter, I found that this fix may help with problems there. Specifically I found that the pl2303 serial adapters tend to respond with a NAK when they have nothing to say and thus we end with this same sequence. Signed-off-by: Douglas Anderson <dianders@chromium.org> Reviewed-by: Julius Werner <jwerner@chromium.org> Tested-by: Stefan Wahren <stefan.wahren@i2se.com> Acked-by: John Youn <johnyoun@synopsys.com> Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
* treewide: setup_timer() -> timer_setup()Kees Cook2017-11-211-4/+3
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This converts all remaining cases of the old setup_timer() API into using timer_setup(), where the callback argument is the structure already holding the struct timer_list. These should have no behavioral changes, since they just change which pointer is passed into the callback with the same available pointers after conversion. It handles the following examples, in addition to some other variations. Casting from unsigned long: void my_callback(unsigned long data) { struct something *ptr = (struct something *)data; ... } ... setup_timer(&ptr->my_timer, my_callback, ptr); and forced object casts: void my_callback(struct something *ptr) { ... } ... setup_timer(&ptr->my_timer, my_callback, (unsigned long)ptr); become: void my_callback(struct timer_list *t) { struct something *ptr = from_timer(ptr, t, my_timer); ... } ... timer_setup(&ptr->my_timer, my_callback, 0); Direct function assignments: void my_callback(unsigned long data) { struct something *ptr = (struct something *)data; ... } ... ptr->my_timer.function = my_callback; have a temporary cast added, along with converting the args: void my_callback(struct timer_list *t) { struct something *ptr = from_timer(ptr, t, my_timer); ... } ... ptr->my_timer.function = (TIMER_FUNC_TYPE)my_callback; And finally, callbacks without a data assignment: void my_callback(unsigned long data) { ... } ... setup_timer(&ptr->my_timer, my_callback, 0); have their argument renamed to verify they're unused during conversion: void my_callback(struct timer_list *unused) { ... } ... timer_setup(&ptr->my_timer, my_callback, 0); The conversion is done with the following Coccinelle script: spatch --very-quiet --all-includes --include-headers \ -I ./arch/x86/include -I ./arch/x86/include/generated \ -I ./include -I ./arch/x86/include/uapi \ -I ./arch/x86/include/generated/uapi -I ./include/uapi \ -I ./include/generated/uapi --include ./include/linux/kconfig.h \ --dir . \ --cocci-file ~/src/data/timer_setup.cocci @fix_address_of@ expression e; @@ setup_timer( -&(e) +&e , ...) // Update any raw setup_timer() usages that have a NULL callback, but // would otherwise match change_timer_function_usage, since the latter // will update all function assignments done in the face of a NULL // function initialization in setup_timer(). @change_timer_function_usage_NULL@ expression _E; identifier _timer; type _cast_data; @@ ( -setup_timer(&_E->_timer, NULL, _E); +timer_setup(&_E->_timer, NULL, 0); | -setup_timer(&_E->_timer, NULL, (_cast_data)_E); +timer_setup(&_E->_timer, NULL, 0); | -setup_timer(&_E._timer, NULL, &_E); +timer_setup(&_E._timer, NULL, 0); | -setup_timer(&_E._timer, NULL, (_cast_data)&_E); +timer_setup(&_E._timer, NULL, 0); ) @change_timer_function_usage@ expression _E; identifier _timer; struct timer_list _stl; identifier _callback; type _cast_func, _cast_data; @@ ( -setup_timer(&_E->_timer, _callback, _E); +timer_setup(&_E->_timer, _callback, 0); | -setup_timer(&_E->_timer, &_callback, _E); +timer_setup(&_E->_timer, _callback, 0); | -setup_timer(&_E->_timer, _callback, (_cast_data)_E); +timer_setup(&_E->_timer, _callback, 0); | -setup_timer(&_E->_timer, &_callback, (_cast_data)_E); +timer_setup(&_E->_timer, _callback, 0); | -setup_timer(&_E->_timer, (_cast_func)_callback, _E); +timer_setup(&_E->_timer, _callback, 0); | -setup_timer(&_E->_timer, (_cast_func)&_callback, _E); +timer_setup(&_E->_timer, _callback, 0); | -setup_timer(&_E->_timer, (_cast_func)_callback, (_cast_data)_E); +timer_setup(&_E->_timer, _callback, 0); | -setup_timer(&_E->_timer, (_cast_func)&_callback, (_cast_data)_E); +timer_setup(&_E->_timer, _callback, 0); | -setup_timer(&_E._timer, _callback, (_cast_data)_E); +timer_setup(&_E._timer, _callback, 0); | -setup_timer(&_E._timer, _callback, (_cast_data)&_E); +timer_setup(&_E._timer, _callback, 0); | -setup_timer(&_E._timer, &_callback, (_cast_data)_E); +timer_setup(&_E._timer, _callback, 0); | -setup_timer(&_E._timer, &_callback, (_cast_data)&_E); +timer_setup(&_E._timer, _callback, 0); | -setup_timer(&_E._timer, (_cast_func)_callback, (_cast_data)_E); +timer_setup(&_E._timer, _callback, 0); | -setup_timer(&_E._timer, (_cast_func)_callback, (_cast_data)&_E); +timer_setup(&_E._timer, _callback, 0); | -setup_timer(&_E._timer, (_cast_func)&_callback, (_cast_data)_E); +timer_setup(&_E._timer, _callback, 0); | -setup_timer(&_E._timer, (_cast_func)&_callback, (_cast_data)&_E); +timer_setup(&_E._timer, _callback, 0); | _E->_timer@_stl.function = _callback; | _E->_timer@_stl.function = &_callback; | _E->_timer@_stl.function = (_cast_func)_callback; | _E->_timer@_stl.function = (_cast_func)&_callback; | _E._timer@_stl.function = _callback; | _E._timer@_stl.function = &_callback; | _E._timer@_stl.function = (_cast_func)_callback; | _E._timer@_stl.function = (_cast_func)&_callback; ) // callback(unsigned long arg) @change_callback_handle_cast depends on change_timer_function_usage@ identifier change_timer_function_usage._callback; identifier change_timer_function_usage._timer; type _origtype; identifier _origarg; type _handletype; identifier _handle; @@ void _callback( -_origtype _origarg +struct timer_list *t ) { ( ... when != _origarg _handletype *_handle = -(_handletype *)_origarg; +from_timer(_handle, t, _timer); ... when != _origarg | ... when != _origarg _handletype *_handle = -(void *)_origarg; +from_timer(_handle, t, _timer); ... when != _origarg | ... when != _origarg _handletype *_handle; ... when != _handle _handle = -(_handletype *)_origarg; +from_timer(_handle, t, _timer); ... when != _origarg | ... when != _origarg _handletype *_handle; ... when != _handle _handle = -(void *)_origarg; +from_timer(_handle, t, _timer); ... when != _origarg ) } // callback(unsigned long arg) without existing variable @change_callback_handle_cast_no_arg depends on change_timer_function_usage && !change_callback_handle_cast@ identifier change_timer_function_usage._callback; identifier change_timer_function_usage._timer; type _origtype; identifier _origarg; type _handletype; @@ void _callback( -_origtype _origarg +struct timer_list *t ) { + _handletype *_origarg = from_timer(_origarg, t, _timer); + ... when != _origarg - (_handletype *)_origarg + _origarg ... when != _origarg } // Avoid already converted callbacks. @match_callback_converted depends on change_timer_function_usage && !change_callback_handle_cast && !change_callback_handle_cast_no_arg@ identifier change_timer_function_usage._callback; identifier t; @@ void _callback(struct timer_list *t) { ... } // callback(struct something *handle) @change_callback_handle_arg depends on change_timer_function_usage && !match_callback_converted && !change_callback_handle_cast && !change_callback_handle_cast_no_arg@ identifier change_timer_function_usage._callback; identifier change_timer_function_usage._timer; type _handletype; identifier _handle; @@ void _callback( -_handletype *_handle +struct timer_list *t ) { + _handletype *_handle = from_timer(_handle, t, _timer); ... } // If change_callback_handle_arg ran on an empty function, remove // the added handler. @unchange_callback_handle_arg depends on change_timer_function_usage && change_callback_handle_arg@ identifier change_timer_function_usage._callback; identifier change_timer_function_usage._timer; type _handletype; identifier _handle; identifier t; @@ void _callback(struct timer_list *t) { - _handletype *_handle = from_timer(_handle, t, _timer); } // We only want to refactor the setup_timer() data argument if we've found // the matching callback. This undoes changes in change_timer_function_usage. @unchange_timer_function_usage depends on change_timer_function_usage && !change_callback_handle_cast && !change_callback_handle_cast_no_arg && !change_callback_handle_arg@ expression change_timer_function_usage._E; identifier change_timer_function_usage._timer; identifier change_timer_function_usage._callback; type change_timer_function_usage._cast_data; @@ ( -timer_setup(&_E->_timer, _callback, 0); +setup_timer(&_E->_timer, _callback, (_cast_data)_E); | -timer_setup(&_E._timer, _callback, 0); +setup_timer(&_E._timer, _callback, (_cast_data)&_E); ) // If we fixed a callback from a .function assignment, fix the // assignment cast now. @change_timer_function_assignment depends on change_timer_function_usage && (change_callback_handle_cast || change_callback_handle_cast_no_arg || change_callback_handle_arg)@ expression change_timer_function_usage._E; identifier change_timer_function_usage._timer; identifier change_timer_function_usage._callback; type _cast_func; typedef TIMER_FUNC_TYPE; @@ ( _E->_timer.function = -_callback +(TIMER_FUNC_TYPE)_callback ; | _E->_timer.function = -&_callback +(TIMER_FUNC_TYPE)_callback ; | _E->_timer.function = -(_cast_func)_callback; +(TIMER_FUNC_TYPE)_callback ; | _E->_timer.function = -(_cast_func)&_callback +(TIMER_FUNC_TYPE)_callback ; | _E._timer.function = -_callback +(TIMER_FUNC_TYPE)_callback ; | _E._timer.function = -&_callback; +(TIMER_FUNC_TYPE)_callback ; | _E._timer.function = -(_cast_func)_callback +(TIMER_FUNC_TYPE)_callback ; | _E._timer.function = -(_cast_func)&_callback +(TIMER_FUNC_TYPE)_callback ; ) // Sometimes timer functions are called directly. Replace matched args. @change_timer_function_calls depends on change_timer_function_usage && (change_callback_handle_cast || change_callback_handle_cast_no_arg || change_callback_handle_arg)@ expression _E; identifier change_timer_function_usage._timer; identifier change_timer_function_usage._callback; type _cast_data; @@ _callback( ( -(_cast_data)_E +&_E->_timer | -(_cast_data)&_E +&_E._timer | -_E +&_E->_timer ) ) // If a timer has been configured without a data argument, it can be // converted without regard to the callback argument, since it is unused. @match_timer_function_unused_data@ expression _E; identifier _timer; identifier _callback; @@ ( -setup_timer(&_E->_timer, _callback, 0); +timer_setup(&_E->_timer, _callback, 0); | -setup_timer(&_E->_timer, _callback, 0L); +timer_setup(&_E->_timer, _callback, 0); | -setup_timer(&_E->_timer, _callback, 0UL); +timer_setup(&_E->_timer, _callback, 0); | -setup_timer(&_E._timer, _callback, 0); +timer_setup(&_E._timer, _callback, 0); | -setup_timer(&_E._timer, _callback, 0L); +timer_setup(&_E._timer, _callback, 0); | -setup_timer(&_E._timer, _callback, 0UL); +timer_setup(&_E._timer, _callback, 0); | -setup_timer(&_timer, _callback, 0); +timer_setup(&_timer, _callback, 0); | -setup_timer(&_timer, _callback, 0L); +timer_setup(&_timer, _callback, 0); | -setup_timer(&_timer, _callback, 0UL); +timer_setup(&_timer, _callback, 0); | -setup_timer(_timer, _callback, 0); +timer_setup(_timer, _callback, 0); | -setup_timer(_timer, _callback, 0L); +timer_setup(_timer, _callback, 0); | -setup_timer(_timer, _callback, 0UL); +timer_setup(_timer, _callback, 0); ) @change_callback_unused_data depends on match_timer_function_unused_data@ identifier match_timer_function_unused_data._callback; type _origtype; identifier _origarg; @@ void _callback( -_origtype _origarg +struct timer_list *unused ) { ... when != _origarg } Signed-off-by: Kees Cook <keescook@chromium.org>
* USB: add SPDX identifiers to all remaining files in drivers/usb/Greg Kroah-Hartman2017-11-041-0/+1
| | | | | | | | | | | | | | | | | | | | | It's good to have SPDX identifiers in all files to make it easier to audit the kernel tree for correct licenses. Update the drivers/usb/ and include/linux/usb* files with the correct SPDX license identifier based on the license text in the file itself. The SPDX identifier is a legally binding shorthand, which can be used instead of the full boiler plate text. This work is based on a script and data from Thomas Gleixner, Philippe Ombredanne, and Kate Stewart. Cc: Thomas Gleixner <tglx@linutronix.de> Cc: Kate Stewart <kstewart@linuxfoundation.org> Cc: Philippe Ombredanne <pombredanne@nexb.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Acked-by: Felipe Balbi <felipe.balbi@linux.intel.com> Acked-by: Johan Hovold <johan@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
* usb: dwc2: Improve gadget state disconnection handlingJohn Stultz2017-10-241-2/+5
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | In the earlier commit dad3f793f20f ("usb: dwc2: Make sure we disconnect the gadget state"), I was trying to fix up the fact that we somehow weren't disconnecting the gadget state, so that when the OTG port was plugged in the second time we would get warnings about the state tracking being wrong. (This seems to be due to a quirk of the HiKey board where we do not ever get any otg interrupts, particularly the session end detected signal. Instead we only see status change interrupt.) The fix there was somewhat simple, as it just made sure to call dwc2_hsotg_disconnect() before we connected things up in OTG mode, ensuring the state handling didn't throw errors. But in looking at a different issue I was seeing with UDC state handling, I realized that it would be much better to call dwc2_hsotg_disconnect when we get the state change signal moving to host mode. Thus, this patch removes the earlier disconnect call I added and moves it (and the needed locking) to the host mode transition. Cc: Wei Xu <xuwei5@hisilicon.com> Cc: Guodong Xu <guodong.xu@linaro.org> Cc: Amit Pundir <amit.pundir@linaro.org> Cc: YongQin Liu <yongqin.liu@linaro.org> Cc: John Youn <johnyoun@synopsys.com> Cc: Minas Harutyunyan <Minas.Harutyunyan@synopsys.com> Cc: Douglas Anderson <dianders@chromium.org> Cc: Chen Yu <chenyu56@huawei.com> Cc: Felipe Balbi <felipe.balbi@linux.intel.com> Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Cc: linux-usb@vger.kernel.org Acked-by: Minas Harutyunyan <hminas@synopsys.com> Tested-by: Minas Harutyunyan <hminas@synopsys.com> Signed-off-by: John Stultz <john.stultz@linaro.org> Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
* usb: dwc2: disable erroneous overcurrent conditionDinh Nguyen2017-10-191-0/+5
| | | | | | | | | | | | | For the case where an external VBUS is used, we should enable the external VBUS comparator in the driver. This would prevent an unnecessary overcurrent error which would then disable the host port. This patch uses the standard 'disable-over-current' binding to allow of the option of disabling the over-current condition. Reviewed-by: Marek Vasut <marex@denx.de> Signed-off-by: Dinh Nguyen <dinguyen@kernel.org> Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
* usb: dwc2: skip L2 state of hcd if controller work in device modeMeng Dongyang2017-08-151-0/+6
| | | | | | | | | | | | In the case hcd autosuspend is enabled, the hcd will enter L2 state if no device connected. But if the controller works in otg mode, the gadget driver still works in L0 state if connected with host. This may result in transfer fail when gadget enqueue new request but the hcd driver has set the global state into L2. This patch prevent the hcd enter L2 state if the controller work in device mode. Signed-off-by: Meng Dongyang <daniel.meng@rock-chips.com> Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
* usb: dwc2: Add support for STM32F429/439/469 USB OTG HS/FS in FS mode ↵Bruno Herrera2017-04-111-1/+14
| | | | | | | | | | | | | (internal PHY) This patch introduces a new parameter to activate USB OTG HS/FS core embedded phy transceiver. The STM32F4x9 SoC uses the GGPIO register to enable the transceiver. Also add the dwc2_set_params function for stm32f4 otg fs. Acked-by: John Youn <johnyoun@synopsys.com> Signed-off-by: Bruno Herrera <bruherrera@gmail.com> Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>