Re: [PATCH 2/4] usb: introduce usb force power off mechanism
On 2013/3/29 6:43, Sarah Sharp wrote: On Thu, Mar 28, 2013 at 05:00:23PM -0400, Alan Stern wrote: On Thu, 28 Mar 2013, Sarah Sharp wrote: On Thu, Mar 28, 2013 at 01:11:02AM +0800, Lan Tianyu wrote: Some devices' firmware will be broken at some points. Power down and power on device can help device to rework in this case. This patch is to add ioctl cmd USBDEVFS_POWER_RESET for usbfs node to repower usb device. First, call hub_port_logical_disconnect() to disconnect device. Second, Power down and up usb port. I don't think this is the right approach. We want to be able to power off a port, even if no devices are attached. One of the use case scenarios we discussed was allowing distros to turn off empty USB ports according to some policy (e.g. screen blank, lost bluetooth connection to their phone that indicates the user walked away from the computer, server admin wants to save power, etc). With the current patches in 3.9, I don't see a way we can do that. The ports have power/control, which can only be set to 'on' or 'auto'. You should add an 'off' option to that file. Won't empty ports naturally be powered off by runtime PM, so long as there isn't a PM_QOS constraint to prevent it? The user (or system software) may need to write auto to the port's power/control file, which may require us to put the ports on the usb_bus_type or to make them class devices. But however we do it, this should work automatically. Now I'm a bit confused and I'll have to look at the code again. I can't remember if Tianyu made the kernel add a PM_QOS constraint to set the no power off flag for hot pluggable ports, or if we expect userspace to use the connect type sysfs file to figure out it shouldn't write auto to the file. Actually, I exposed pm qos flags for usb port via dev_pm_qos_expose_flags(). It creates power/pm_qos_no_power_off under usb port sysfs directory. User can echo 0 pm_qos_no_power_off to power off the empty port. If the kernel isn't adding that constraint, then Tianyu *really* needs to document that. power/pm_qos_no_power_off is device's power attribute and it has been described in the sysfs-devices-power. I think I should mention in the usb/power-management.text. Sarah Sharp -- Best Regards Tianyu Lan linux kernel enabling team -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: usb video capture issue due to uvc_complete callback spends more time
On Friday 29 March 2013 05:24:27 B, Ravi wrote: On Thu, Mar 28, 2013 at 9:27 PM, Felipe Balbi wrote: On Thu, Mar 28, 2013 at 03:23:46PM +0200, Felipe Balbi wrote: On Thu, Mar 28, 2013 at 08:53:03PM +0800, Ming Lei wrote: On Thu, Mar 28, 2013 at 8:30 PM, B, Ravi ravib...@ti.com wrote: For example, in one iteration I have observed, the time taken by uvc_video_decode_isoc() was 2175 usec. In this maximum amount of time was consumed by uvc_video_decode_data() around 1792 usec. uvc_video_decode_data() is basically a memcpy() from coherent buffer to normal buffer. if that's the case, this should show, right ? Maybe not, it might be worse(per my previous test on Pandaboard A1) to change to DMA streaming buffer, since DMA unmapping has become expensive too for reading from device after invalidating buffer is added to handle speculative prefetching, and before that, DMA unmapping was basically a nop on ARM. But you guys can do the test again, or do some analysis about such slow memcpy() on coherent buffer. Since the uvc_video_complete() callback handler called from interrupt context, video post processing or memcpy can be deferred to tasklet or bottom half, rather than doing it in interrupt context. If that's the only way to fix the issue, yes. However, given your really poor memcpy() performances, I don't think you will be able to sustain the incoming video bandwidth. The driver would soon run out of URBs. It is not odd to see I/O performance isn't very good on ARM... -- Regards, Laurent Pinchart -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
RE: usb video capture issue due to uvc_complete callback spends more time
Laurent On Thu, Mar 28, 2013 at 08:53:03PM +0800, Ming Lei wrote: On Thu, Mar 28, 2013 at 8:30 PM, B, Ravi ravib...@ti.com wrote: For example, in one iteration I have observed, the time taken by uvc_video_decode_isoc() was 2175 usec. In this maximum amount of time was consumed by uvc_video_decode_data() around 1792 usec. uvc_video_decode_data() is basically a memcpy() from coherent buffer to normal buffer. if that's the case, this should show, right ? Maybe not, it might be worse(per my previous test on Pandaboard A1) to change to DMA streaming buffer, since DMA unmapping has become expensive too for reading from device after invalidating buffer is added to handle speculative prefetching, and before that, DMA unmapping was basically a nop on ARM. But you guys can do the test again, or do some analysis about such slow memcpy() on coherent buffer. Since the uvc_video_complete() callback handler called from interrupt context, video post processing or memcpy can be deferred to tasklet or bottom half, rather than doing it in interrupt context. If that's the only way to fix the issue, yes. However, given your really poor memcpy() performances, I don't think you will be able to sustain the incoming video bandwidth. The driver would soon run out of URBs. I agree with you, let me check whether memcpy is the bottle here, I will try to get profile info on this. But in general it would be good to move post processing to bottom half which helps to reduce interrupt latency. Thanks -- Ravi B -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
RE: usb video capture issue due to uvc_complete callback spends more time
Laurent On Thu, Mar 28, 2013 at 08:53:03PM +0800, Ming Lei wrote: On Thu, Mar 28, 2013 at 8:30 PM, B, Ravi ravib...@ti.com wrote: For example, in one iteration I have observed, the time taken by uvc_video_decode_isoc() was 2175 usec. In this maximum amount of time was consumed by uvc_video_decode_data() around 1792 usec. uvc_video_decode_data() is basically a memcpy() from coherent buffer to normal buffer. if that's the case, this should show, right ? Maybe not, it might be worse(per my previous test on Pandaboard A1) to change to DMA streaming buffer, since DMA unmapping has become expensive too for reading from device after invalidating buffer is added to handle speculative prefetching, and before that, DMA unmapping was basically a nop on ARM. But you guys can do the test again, or do some analysis about such slow memcpy() on coherent buffer. Since the uvc_video_complete() callback handler called from interrupt context, video post processing or memcpy can be deferred to tasklet or bottom half, rather than doing it in interrupt context. If that's the only way to fix the issue, yes. However, given your really poor memcpy() performances, I don't think you will be able to sustain the incoming video bandwidth. The driver would soon run out of URBs. I agree with you, let me check whether memcpy is the bottle here, typo mistake, read as bottle-neck I will try to get profile info on this. But in general it would be good to move post processing to bottom half which helps to reduce interrupt latency. Thanks -- Ravi B -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
RE: usb video capture issue due to uvc_complete callback spends more time
Laurent Since the uvc_video_complete() callback handler called from interrupt context, video post processing or memcpy can be deferred to tasklet or bottom half, rather than doing it in interrupt context. If that's the only way to fix the issue, yes. However, given your really poor memcpy() performances, I don't think you will be able to sustain the incoming video bandwidth. The driver would soon run out of URBs. I agree with you, let me check whether memcpy is the bottle here, typo mistake, read as bottle-neck I will try to get profile info on this. But in general it would be good to move post processing to bottom half which helps to reduce interrupt latency. You are correct, I have profiled, the timing I have posted in previous mail are due to the memcpy() in uvc_video_decode_data(). Which is the bottle-neck and consumes most of the time. Regards Ravi B -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] usb: ehci: mark unlink_empty_async_suspended() as __maybe_unused
On Thu, 28 Mar 2013, Arnd Bergmann wrote: Patch 4d053fdac3 usb: ehci: unlink_empty_async_suspended() only used with CONFIG_PM tried to hide the unlink_empty_async_suspended function inside of an #ifdef to work around an unused function warning. Unfortunately that had the effect of introducing a new warning: drivers/usb/host/ehci-q.c:1297:13: warning: 'unlink_empty_async_suspended' declared 'static' but never defined [-Wunused-function] While we could add another #ifdef around the function declaration to avoid this, a nicer solution is to mark it as __maybe_unused, which will let gcc silently drop the function definition when it is not needed. IMO the compiler is being stupid. -Wunused-function should warn about functions that are defined but not called, not about functions that are declared but not defined. Grumble... Anyway yes, this is a good fix. Acked-by: Alan Stern st...@rowland.harvard.edu -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] usb: ehci: mark unlink_empty_async_suspended() as __maybe_unused
On Fri, 29 Mar 2013, Tony Prisk wrote: On 29/03/13 10:16, Arnd Bergmann wrote: On Thursday 28 March 2013, Arnd Bergmann wrote: Patch 4d053fdac3 usb: ehci: unlink_empty_async_suspended() only used with CONFIG_PM tried to hide the unlink_empty_async_suspended function inside of an #ifdef to work around an unused function warning. Hi Greg, Apparently the warning is now also in 3.8.5, so you might want to backport this fix as well after you send it upstream. Arnd Grr, my bad - I originally wrote the patch with the forward decl #ifdef'd as well, but Alan pointed out that it didn't need to be. I thought I recompiled it after the change, but obviously not. It's my fault too. I didn't realize the compiler would issue a warning about a static declaration with no definition. Alan Stern -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 2/4] usb: introduce usb force power off mechanism
On Fri, 29 Mar 2013, Lan Tianyu wrote: Actually, I exposed pm qos flags for usb port via dev_pm_qos_expose_flags(). It creates power/pm_qos_no_power_off under usb port sysfs directory. User can echo 0 pm_qos_no_power_off to power off the empty port. Before it's too late, we should consider changing the flag's name. Writing 0 to a file named pm_qos_no_power_off is a double negative, which is always awkward to think about. Instead, how about calling the file pm_qos_allow_power_off? Will the PM-QOS system allow something like that, i.e., something that is the opposite of a constraint? If not, how about naming it pm_qos_keep_power_on? Alan Stern -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
RE: usb video capture issue due to uvc_complete callback spends more time
Laurent/Ming Lei Since the uvc_video_complete() callback handler called from interrupt context, video post processing or memcpy can be deferred to tasklet or bottom half, rather than doing it in interrupt context. If that's the only way to fix the issue, yes. However, given your really poor memcpy() performances, I don't think you will be able to sustain the incoming video bandwidth. The driver would soon run out of URBs. I agree with you, let me check whether memcpy is the bottle here, typo mistake, read as bottle-neck I will try to get profile info on this. But in general it would be good to move post processing to bottom half which helps to reduce interrupt latency. You are correct, I have profiled, the timing I have posted in previous mail are due to the memcpy() in uvc_video_decode_data(). Which is the bottle-neck and consumes most of the time. There is an improvement in timing after defining CONFIG_DMA_NONCOHERENT, the coherent memory access is very slow leads to this issue. #ifndef CONFIG_DMA_NONCOHERENT stream-urb_buffer[i] = usb_alloc_coherent( stream-dev-udev, stream-urb_size, gfp_flags | __GFP_NOWARN, stream-urb_dma[i]); #else stream-urb_buffer[i] = kmalloc(stream-urb_size, gfp_flags | __GFP_NOWARN); #endif The mentor host controller (driver/usb/musb) puts all overhead on SW to schedule the next urb, unlike like ehci/xhci where the multiple urbs (TDs) can be queued and HW executes the transfers on the bus without SW intervention. In case of musb host controller, the SW has to program the urb one by one, hence it is critical that urb completion callback called in interrupt context must be very thin. -- Ravi B -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: Linux USB file storage gadget with new UDC
On Fri, 29 Mar 2013, victor yeo wrote: Thanks. Working on this problem now. Another problem observed for SCSI_READ_10 command, when reading from the SD card, the gadget driver never sends the MBR address, the FAT boot record address, the start of FAT address, and the start of FAT cluster address to the SD card driver. The gadget doesn't make up addresses by itself. It always sends the address the host tells it to send. The address sent by gadget driver is wrong. Then the address sent by the host is wrong. However, I suspect you are mistaken. In your usbmon trace earlier, the very first READ(10) command had a logical block address of 0. That is the address of the MBR. If the driver hadn't failed at that point, the host would have gone on to ask for the address of the boot sector and other things. So is the gadget driver designed to work with SCSI/SATA/ATA drive only? The gadget driver is designed to work with any backing file capable of random access. It doesn't even have to be a device file; a regular file will work too. Alan Stern -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
RE: [PATCH v2 1/2] usb: chipidea: big-endian support
Svetoslav Neykov svetos...@neykov.name writes: Hi Michael, On Thu, March 28, 2013 4:13 PM Michael Grzeschik wrote: On Thu, Mar 28, 2013 at 11:28:32AM +0200, Alexander Shishkin wrote: Svetoslav Neykov svetos...@neykov.name writes: Convert between big-endian and little-endian format when accessing the usb controller structures which are little-endian by specification. Fix cases where the little-endian memory layout is taken for granted. The patch doesn't have any effect on the already supported little-endian architectures. Applied to my branch of things that are aiming at v3.10. Next time please make sure that it applies cleanly. I am currently rebasing my fix/cleanup/feature patches against your ci-for-greg and realised that this patch missed to fix debug.c with cpu_le_32 action. Is someone volunteering to cook a patch? I will gladly make the changes, but after having a look at it I didn't spot any candidates. The DMA buffers are printed either as addresses in memory or as raw data which doesn't make sense to be cpu_le_32'ed. If Alexander hasn't already made the changes could you point me to the lines in question. You're right, it's either physical addresses or raw data, no need for conversions there. Regards, -- Alex -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
RE: [PATCH v2 1/2] usb: chipidea: big-endian support
Svetoslav Neykov svetos...@neykov.name writes: Alexander Shishkin wrote: Svetoslav Neykov svetos...@neykov.name writes: Convert between big-endian and little-endian format when accessing the usb controller structures which are little-endian by specification. Fix cases where the little-endian memory layout is taken for granted. The patch doesn't have any effect on the already supported little-endian architectures. Applied to my branch of things that are aiming at v3.10. Next time please make sure that it applies cleanly. I am a bit confused about the workflow and which repository to base my work on. Should I use github/virtuoso/linux-ci for my future patches? Or linux-next? It really depends on what your patches change. For chipidea driver changes, yes it's that branch. For mips-related bits, it's most probably something else. For gadget, otg or phy patches, it's Felipe's tree. If you get it wrong, normally it shouldn't be too much work to rebase your patches onto a different tree, especially for the author of the patches. In some cases I might do it for you, but you should be aware of possible penalties [1]. :) For the coming merge window I'm fixing and rebasing everything for everybody anyway, so this time it's no big deal. [1] http://lwn.net/Articles/536546/ Regards, -- Alex -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v9 3/8] usb: chipidea: udc: read status of td only once in hardware_dequeue
Michael Grzeschik m.grzesc...@pengutronix.de writes: This patch changes the read of the td status to one atomic operation to analyse coherent bits. Signed-off-by: Michael Grzeschik m.grzesc...@pengutronix.de --- drivers/usb/chipidea/udc.c | 8 +--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c index 21e1dd6..19fc185 100644 --- a/drivers/usb/chipidea/udc.c +++ b/drivers/usb/chipidea/udc.c @@ -495,10 +495,12 @@ done: */ static int _hardware_dequeue(struct ci13xxx_ep *mEp, struct ci13xxx_req *mReq) { + u32 tmptoken = cpu_to_le32(mReq-ptr-token); This should really be le32_to_cpu(), since you're reading. [..] @@ -512,7 +514,7 @@ static int _hardware_dequeue(struct ci13xxx_ep *mEp, struct ci13xxx_req *mReq) usb_gadget_unmap_request(mEp-ci-gadget, mReq-req, mEp-dir); - mReq-req.status = le32_to_cpu(mReq-ptr-token) TD_STATUS; Like it was here, for example. + mReq-req.status = tmptoken TD_STATUS; if ((TD_STATUS_HALTED mReq-req.status) != 0) mReq-req.status = -1; else if ((TD_STATUS_DT_ERR mReq-req.status) != 0) @@ -520,7 +522,7 @@ static int _hardware_dequeue(struct ci13xxx_ep *mEp, struct ci13xxx_req *mReq) else if ((TD_STATUS_TR_ERR mReq-req.status) != 0) mReq-req.status = -1; - mReq-req.actual = le32_to_cpu(mReq-ptr-token) TD_TOTAL_BYTES; + mReq-req.actual = tmptoken TD_TOTAL_BYTES; mReq-req.actual = __ffs(TD_TOTAL_BYTES); mReq-req.actual = mReq-req.length - mReq-req.actual; mReq-req.actual = mReq-req.status ? 0 : mReq-req.actual; -- 1.8.2.rc2 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v9 4/8] usb: chipidea: udc: rework ep_enable cap setting
Michael Grzeschik m.grzesc...@pengutronix.de writes: This patch reworks the cap value from several read and write operations to one single operation. Signed-off-by: Michael Grzeschik m.grzesc...@pengutronix.de Reviewed-by: Felipe Balbi ba...@ti.com --- drivers/usb/chipidea/udc.c | 17 - 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c index 19fc185..b2c227f 100644 --- a/drivers/usb/chipidea/udc.c +++ b/drivers/usb/chipidea/udc.c @@ -1018,6 +1018,7 @@ static int ep_enable(struct usb_ep *ep, struct ci13xxx_ep *mEp = container_of(ep, struct ci13xxx_ep, ep); int retval = 0; unsigned long flags; + u32 val = 0; This guy could use a bit more descriptive name. if (ep == NULL || desc == NULL) return -EINVAL; @@ -1039,19 +1040,17 @@ static int ep_enable(struct usb_ep *ep, trace_ci_ep_enable(mEp, 0); - mEp-qh.ptr-cap = 0; - if (mEp-type == USB_ENDPOINT_XFER_CONTROL) - mEp-qh.ptr-cap |= cpu_to_le32(QH_IOS); + val |= QH_IOS; else if (mEp-type == USB_ENDPOINT_XFER_ISOC) - mEp-qh.ptr-cap = cpu_to_le32(~QH_MULT); - else - mEp-qh.ptr-cap = cpu_to_le32(~QH_ZLT); + val = ~QH_MULT; This does nothing, since val wasn't set to anything other than 0 at this point. + if (mEp-num) - mEp-qh.ptr-cap |= cpu_to_le32(QH_ZLT); + val |= QH_ZLT; + + val |= (mEp-ep.maxpacket __ffs(QH_MAX_PKT)) QH_MAX_PKT; + mEp-qh.ptr-cap = cpu_to_le32(val); - mEp-qh.ptr-cap |= cpu_to_le32((mEp-ep.maxpacket __ffs(QH_MAX_PKT)) - QH_MAX_PKT); mEp-qh.ptr-td.next |= cpu_to_le32(TD_TERMINATE); /* needed? */ /* -- 1.8.2.rc2 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v9 7/8] usb: chipidea: udc: prepare qhead with dma_alloc_coherent
Michael Grzeschik m.grzesc...@pengutronix.de writes: The prepared memory for the qhead needs to be contiguos and 2K aligned. We change the code from allocating extra buffer for every ep qhead to one big area. This patch lowers the amount of code to prepare the memory. Signed-off-by: Michael Grzeschik m.grzesc...@pengutronix.de --- drivers/usb/chipidea/ci.h | 9 +++-- drivers/usb/chipidea/udc.c | 32 +++- drivers/usb/chipidea/udc.h | 2 +- 3 files changed, 23 insertions(+), 20 deletions(-) diff --git a/drivers/usb/chipidea/ci.h b/drivers/usb/chipidea/ci.h index 7dcd390..7319bf6 100644 --- a/drivers/usb/chipidea/ci.h +++ b/drivers/usb/chipidea/ci.h @@ -121,7 +121,7 @@ struct hw_bank { * @is_otg: if the device is otg-capable * @work: work for role changing * @wq: workqueue thread - * @qh_pool: allocation pool for queue heads + * @qh: allocation struct for queue heads * @td_pool: allocation pool for transfer descriptors * @gadget: device side representation for peripheral controller * @driver: gadget driver @@ -154,7 +154,12 @@ struct ci13xxx { struct work_struct vbus_work; struct workqueue_struct *wq; - struct dma_pool *qh_pool; + struct { + struct ci13xxx_qh *ptr; + dma_addr_t dma; + size_t size; + } qh; + struct dma_pool *td_pool; struct usb_gadget gadget; diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c index dd4fe75..21f6558 100644 --- a/drivers/usb/chipidea/udc.c +++ b/drivers/usb/chipidea/udc.c @@ -13,9 +13,11 @@ #include linux/delay.h #include linux/device.h #include linux/dmapool.h +#include linux/dma-mapping.h #include linux/err.h #include linux/irqreturn.h #include linux/kernel.h +#include linux/sizes.h #include linux/slab.h #include linux/pm_runtime.h #include linux/usb/ch9.h @@ -1401,7 +1403,7 @@ static int ci13xxx_vbus_session(struct usb_gadget *_gadget, int is_active) pm_runtime_get_sync(_gadget-dev); hw_device_reset(ci, USBMODE_CM_DC); hw_enable_vbus_intr(ci); - hw_device_state(ci, ci-ep0out-qh.dma); + hw_device_state(ci, ci-qh.dma); } else { hw_device_state(ci, 0); if (ci-platdata-notify_event) @@ -1504,8 +1506,8 @@ static int init_eps(struct ci13xxx *ci) mEp-ep.maxpacket = (unsigned short)~0; INIT_LIST_HEAD(mEp-qh.queue); - mEp-qh.ptr = dma_pool_alloc(ci-qh_pool, GFP_KERNEL, - mEp-qh.dma); + mEp-qh.ptr = ci-qh.ptr[i * 2 + j]; + if (mEp-qh.ptr == NULL) retval = -ENOMEM; else @@ -1533,13 +1535,8 @@ static int init_eps(struct ci13xxx *ci) static void destroy_eps(struct ci13xxx *ci) { - int i; - - for (i = 0; i ci-hw_ep_max; i++) { - struct ci13xxx_ep *mEp = ci-ci13xxx_ep[i]; - - dma_pool_free(ci-qh_pool, mEp-qh.ptr, mEp-qh.dma); - } + dma_free_coherent(ci-dev, ci-qh.size, + ci-qh.ptr, ci-qh.dma); } /** @@ -1585,7 +1582,7 @@ static int ci13xxx_start(struct usb_gadget *gadget, } } - retval = hw_device_state(ci, ci-ep0out-qh.dma); + retval = hw_device_state(ci, ci-qh.dma); if (retval) pm_runtime_put_sync(ci-gadget.dev); @@ -1736,11 +1733,14 @@ static int udc_start(struct ci13xxx *ci) ci-gadget.dev.parent = dev; ci-gadget.dev.release = udc_release; + ci-qh.size = ci-hw_ep_max * sizeof(struct ci13xxx_qh); + ci-qh.size = ALIGN(ci-qh.size, SZ_2K); + /* alloc resources */ - ci-qh_pool = dma_pool_create(ci13xxx_qh, dev, -sizeof(struct ci13xxx_qh), -64, CI13XXX_PAGE_SIZE); - if (ci-qh_pool == NULL) + ci-qh.ptr = dma_alloc_coherent(dev, ci-qh.size, + ci-qh.dma, GFP_ATOMIC); + + if (ci-qh.ptr == NULL) return -ENOMEM; ci-td_pool = dma_pool_create(ci13xxx_td, dev, @@ -1814,7 +1814,6 @@ destroy_eps: free_pools: dma_pool_destroy(ci-td_pool); free_qh_pool: - dma_pool_destroy(ci-qh_pool); return retval; } @@ -1836,7 +1835,6 @@ static void udc_stop(struct ci13xxx *ci) destroy_eps(ci); dma_pool_destroy(ci-td_pool); - dma_pool_destroy(ci-qh_pool); if (!IS_ERR_OR_NULL(ci-transceiver)) { otg_set_peripheral(ci-transceiver-otg, NULL); diff --git a/drivers/usb/chipidea/udc.h
[RFC v2] ehci-hub.c - conflicting quirks handlings for MPC8349 / MAX4967
Hi, I am currently looking into a seeming regression in ehci-hub.c where a change triggered by the behaviour of the MAX4967 USB power supply chip has broken the handling of the MPC8349 USB controller at that point. I'd like to come up with a patch solving the issue for both chips and would appreciate any hints towards an acceptable solution. We had experienced problems with the EHCI on an MPC8343E, which after some over-current situations no longer asserts the Connect Change Status Bit in the Port Status and Control Register, leading to the result that USB would be fully functional, but is no longer effectively serviced - see http://www.mail-archive.com/linux-usb-devel@lists.sourceforge.net/msg54310.html The behaviour was verified by Freescale and following information provided: After the power fault condition is removed it is required to perform following steps: 1) Clear OCC bit by writing 1 to it. 2) Disable port power by clearing PORTSC[PP] bit - this effectively moves the host state machine to disabled state. 3) Reapply port power by setting PORTSC[PP] back to 1. At this stage CSC bit correctly reflects connect status change. and implemented in commit 756aa6b3d536afe85e151138cb03a293998887b3 My understanding is that the MAX4967 USB power supply chip used on some boards signals over-current when power is not enabled; once it's enabled, over-current signal returns to normal. That caused an endless stream of over-current change on port messages due to the behaviour as described above - see https://lkml.org/lkml/2011/8/5/478 and fixed for the MAX4967 in commit 81463c1d707186adbbe534016cd1249edeab0dac by only disabling port-power in case a currently active over-current situation is detected when handling the over-current change indication. Unfortunately this change removed power-cycling of the affected port after the fault condition is resolved, as required by the MPC8349. Regards, Christian -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v9 0/8] usb: chipidea: udc: cleanups and fixes for v3.10
Michael Grzeschik m.grzesc...@pengutronix.de writes: Hi, Hi, this series contains simples fixes and cleanup patches for the chipidea udc. It is based on Alexander Shishkins ci-for-greg. This is not really true, since your 7/8 relied on the alignment fix, which didn't make it anywhere yet. Some other problems I found: Michael Grzeschik (8): usb: chipidea: udc: only clear active and halted bits in qhead usb: chipidea: udc: move ZLT flag change to ep_enable usb: chipidea: udc: read status of td only once in hardware_dequeue This one tried to convert endianness the wrong way. usb: chipidea: udc: rework ep_enable cap setting This one is much better in front of the ZLT flag patch, makes it easier to read both. Especially after I dropped the extra isoc bit. usb: chipidea: udc: don't truncate requests to single tds usb: chipidea: udc: move _ep_queue into an unlocked function usb: chipidea: udc: prepare qhead with dma_alloc_coherent Didn't apply (see above), so I left it out for now. usb: chipidea: udc: add the define TD_PAGE_COUNT and fix all users I was tempted to move this one in front of don't truncate requests, but left it like this in the end. So after fixing these I applied it and pushed to ci-for-greg. Thanks, -- Alex -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: Linux USB file storage gadget with new UDC
Hi, Thanks. Working on this problem now. Another problem observed for SCSI_READ_10 command, when reading from the SD card, the gadget driver never sends the MBR address, the FAT boot record address, the start of FAT address, and the start of FAT cluster address to the SD card driver. The gadget doesn't make up addresses by itself. It always sends the address the host tells it to send. The address sent by gadget driver is wrong. Then the address sent by the host is wrong. However, I suspect you are mistaken. In your usbmon trace earlier, the very first READ(10) command had a logical block address of 0. That is the address of the MBR. If the driver hadn't failed at that point, the host would have gone on to ask for the address of the boot sector and other things. Yes, the very first READ(10) command has a logical block address of 0 (as shown below). I will generate the fresh usbmon trace the next day, i do not have access to the platform now. f59e13c0 3246885432 S Bo:2:046:1 -115 31 = 55534243 0c00 0010 8a28 0008 00 Thanks, victor -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[ANNOUNCE] chipidea: tree for Mar 29
Hi, I have massaged some more patches into the chipidea tree and rebased it on top of updated usb-next. Currently we have 26 patches: * reworked debugging, * a ton of fixes from Michael and some from others, * usbmisc updates, added quirks for imx25 and imx53, * support for big-endian cpus from Svetoslav. Alexander Shishkin (9): usb: chipidea: drop redundant includes usb: chipidea: trim include list in udc code usb: chipidea: trim include list in the core usb: chipidea: convert events to tracepoints usb: chipidea: replace interrupt accounting with tracepoints usb: chipidea: convert debug entries in sysfs to debugfs usb: chipidea: move role to debugfs usb: chipidea: move debug files creation/removal to the core usb: chipidea: make pci platform datas static Dan Carpenter (1): usb: chipidea: fix precedence bug in ci_requests_show() Felipe Balbi (2): usb: chipidea: don't redefine __ffs() usb: chipidea: core: switch over to devm_ioremap_resource Marc Kleine-Budde (3): usb: chipidea: usbmisc: unset global varibale usbmisc on driver remove usb: chipidea: usbmisc: fix a potential race condition usb: chipidea: usbmisc: prepare driver to handle more than one soc Michael Grzeschik (10): usb: chipidea: usbmisc: rename file, struct and functions to usbmisc_imx usb: chipidea: usbmisc: add mx53 support usb: chipidea: usbmisc: add post handling and errata fix for mx25 usb: chipidea: udc: only clear active and halted bits in qhead usb: chipidea: udc: rework ep_enable cap setting usb: chipidea: udc: move ZLT flag change to ep_enable usb: chipidea: udc: read status of td only once in hardware_dequeue usb: chipidea: udc: don't truncate requests to single tds usb: chipidea: udc: move _ep_queue into an unlocked function usb: chipidea: udc: add the define TD_PAGE_COUNT and fix all users Svetoslav Neykov (1): usb: chipidea: big-endian support .../devicetree/bindings/usb/ci13xxx-imx.txt|2 + drivers/usb/chipidea/Makefile |2 +- drivers/usb/chipidea/ci.h | 31 +- drivers/usb/chipidea/ci13xxx_imx.c | 12 + drivers/usb/chipidea/ci13xxx_imx.h |3 + drivers/usb/chipidea/ci13xxx_pci.c |6 +- drivers/usb/chipidea/core.c| 68 +- drivers/usb/chipidea/debug.c | 888 +--- drivers/usb/chipidea/debug.h | 34 +- drivers/usb/chipidea/udc.c | 254 +++--- drivers/usb/chipidea/udc.h |2 - drivers/usb/chipidea/usbmisc_imx.c | 261 ++ drivers/usb/chipidea/usbmisc_imx6q.c | 162 include/trace/events/chipidea.h| 151 14 files changed, 788 insertions(+), 1088 deletions(-) create mode 100644 drivers/usb/chipidea/usbmisc_imx.c delete mode 100644 drivers/usb/chipidea/usbmisc_imx6q.c create mode 100644 include/trace/events/chipidea.h -- 1.7.10.4 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v4 0/6] support other fsl SoCs with usbmisc + small fixes
Greg KH gre...@linuxfoundation.org writes: If I don't hear back from you by Wednesday this week, with a specific plan for how to get all of these fixes to me by the end of this week, I'm going to assume that you are missing, and will just start taking chipidea patches directly myself, sorry. Actually it looks like there might be more patches coming for this round, so I'd like to send chipidea stuff to you after rc5 if that's ok with you. Regards, -- Alex -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v4 0/6] support other fsl SoCs with usbmisc + small fixes
On Fri, Mar 29, 2013 at 06:00:36PM +0200, Alexander Shishkin wrote: Greg KH gre...@linuxfoundation.org writes: If I don't hear back from you by Wednesday this week, with a specific plan for how to get all of these fixes to me by the end of this week, I'm going to assume that you are missing, and will just start taking chipidea patches directly myself, sorry. Actually it looks like there might be more patches coming for this round, so I'd like to send chipidea stuff to you after rc5 if that's ok with you. That's cutting it _really_ close. How about sending me what you have now, and if you have more later, send them then. No need to postpone some of these patches any longer than you already have :) thanks, greg k-h -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [RFC v2] ehci-hub.c - conflicting quirks handlings for MPC8349 / MAX4967
On Fri, 29 Mar 2013, Christian Engelmayer wrote: Hi, I am currently looking into a seeming regression in ehci-hub.c where a change triggered by the behaviour of the MAX4967 USB power supply chip has broken the handling of the MPC8349 USB controller at that point. I'd like to come up with a patch solving the issue for both chips and would appreciate any hints towards an acceptable solution. We had experienced problems with the EHCI on an MPC8343E, which after some over-current situations no longer asserts the Connect Change Status Bit in the Port Status and Control Register, leading to the result that USB would be fully functional, but is no longer effectively serviced - see http://www.mail-archive.com/linux-usb-devel@lists.sourceforge.net/msg54310.html The behaviour was verified by Freescale and following information provided: After the power fault condition is removed it is required to perform following steps: 1) Clear OCC bit by writing 1 to it. 2) Disable port power by clearing PORTSC[PP] bit - this effectively moves the host state machine to disabled state. 3) Reapply port power by setting PORTSC[PP] back to 1. At this stage CSC bit correctly reflects connect status change. and implemented in commit 756aa6b3d536afe85e151138cb03a293998887b3 My understanding is that the MAX4967 USB power supply chip used on some boards signals over-current when power is not enabled; once it's enabled, over-current signal returns to normal. That caused an endless stream of over-current change on port messages due to the behaviour as described above - see https://lkml.org/lkml/2011/8/5/478 and fixed for the MAX4967 in commit 81463c1d707186adbbe534016cd1249edeab0dac by only disabling port-power in case a currently active over-current situation is detected when handling the over-current change indication. Unfortunately this change removed power-cycling of the affected port after the fault condition is resolved, as required by the MPC8349. To sum up, on some systems (the MPC8343E) it is necessary to cycle the port power whenever an over-current change occurs, whereas on other systems (those with the MAX4967) it is necessary _not_ to cycle the port power when an over-current change occurs. The right way to deal with this is to add a quirk flag. If this flag gets set on the MPC systems then it could essentially revert the behavior added by the 81463c1d7071 commit. Can you write a patch adding such a flag? Alan Stern -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v9 0/8] usb: chipidea: udc: cleanups and fixes for v3.10
Hi Alexander, On Fri, Mar 29, 2013 at 05:32:59PM +0200, Alexander Shishkin wrote: Michael Grzeschik m.grzesc...@pengutronix.de writes: usb: chipidea: udc: don't truncate requests to single tds usb: chipidea: udc: move _ep_queue into an unlocked function usb: chipidea: udc: prepare qhead with dma_alloc_coherent Didn't apply (see above), so I left it out for now. usb: chipidea: udc: add the define TD_PAGE_COUNT and fix all users I was tempted to move this one in front of don't truncate requests, but left it like this in the end. I was also thinking about moving the order of that patch. I also left it this way, cause i was not sure if the don't truncate requests patch is actually an candidate for stable. Especially, as it will run useless in the same kernel, when the multi-td patches will come above. So after fixing these I applied it and pushed to ci-for-greg. Thanks for the great work, Michael -- Pengutronix e.K. | | Industrial Linux Solutions | http://www.pengutronix.de/ | Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0| Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917- | -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 2/4] usb: introduce usb force power off mechanism
On Fri, Mar 29, 2013 at 02:37:24PM +0800, Lan Tianyu wrote: On 2013/3/29 6:43, Sarah Sharp wrote: On Thu, Mar 28, 2013 at 05:00:23PM -0400, Alan Stern wrote: On Thu, 28 Mar 2013, Sarah Sharp wrote: On Thu, Mar 28, 2013 at 01:11:02AM +0800, Lan Tianyu wrote: Now I'm a bit confused and I'll have to look at the code again. I can't remember if Tianyu made the kernel add a PM_QOS constraint to set the no power off flag for hot pluggable ports, or if we expect userspace to use the connect type sysfs file to figure out it shouldn't write auto to the file. Actually, I exposed pm qos flags for usb port via dev_pm_qos_expose_flags(). It creates power/pm_qos_no_power_off under usb port sysfs directory. User can echo 0 pm_qos_no_power_off to power off the empty port. Ugh. I agree with Alan that the name should be pm_qos_keep_power_on. However, what happens if you echo 0 to pm_qos_no_power_off, the power/control is set to auto, and there's a suspended USB device attached to the port with remote wakeup enabled? Will the port be powered off? I don't think it will with the current patchset, but I will have to double check. Maybe you have an Android smartphone or tablet, the user pushes the button to turn off the screen. In that case, you want to physically power off any USB devices, including ones that may be in USB device suspend with remote wakeup on, like a USB touchscreen. With the proposed patchset, you can do that through usbfs, but it feels awkward to have the PM QOS constraints and the manual power off in two separate places. I think if we're adding the usbfs interface, we should also add a manual 'off' to the port power/control file. Sarah Sharp -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 0/1] usb: musb: improve throughput in HOST mode
Hi guys, This is a resend (and v3) of my patch: http://permalink.gmane.org/gmane.linux.usb.general/67238 At this moment it has been successfully tested and used on top of 3.0 and 3.4 kernels on omap4 devices so it would be great to have it in upstream too. Regards, Ruslan v3: Implementation has been little bit changed to keep MUSB struct hc_driver as 'const' (as per Felipe's comments). Verified on top of 3.9-rc4. Ruslan Bilovol (1): usb: musb: implement (un)map_urb_for_dma hooks drivers/usb/musb/musb_host.c | 117 ++ 1 file changed, 117 insertions(+) -- 1.7.9.5 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 1/1] usb: musb: implement (un)map_urb_for_dma hooks
MUSB controller cannot work in DMA mode with misaligned buffers, switching in PIO mode. HCD core has hooks that allow to override the default DMA mapping and unmapping routines for host controllers that have special DMA requirements, such as alignment constraints. It is observed that work in PIO mode is slow and it's better to align buffers properly before passing them to MUSB This increased throughput 80-120 MBits/s over musb@omap4 with USB Gigabit Ethernet adapter attached. Some ideas are taken from ehci-tegra.c Signed-off-by: Ruslan Bilovol ruslan.bilo...@ti.com --- drivers/usb/musb/musb_host.c | 117 ++ 1 file changed, 117 insertions(+) diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c index 1ce1fcf..33277c9 100644 --- a/drivers/usb/musb/musb_host.c +++ b/drivers/usb/musb/musb_host.c @@ -2465,6 +2465,118 @@ static int musb_bus_resume(struct usb_hcd *hcd) return 0; } + +#ifndef CONFIG_MUSB_PIO_ONLY + +#define MUSB_USB_DMA_ALIGN 4 + +struct musb_temp_buffer { + void *kmalloc_ptr; + void *old_xfer_buffer; + u8 data[0]; +}; + +static void musb_free_temp_buffer(struct urb *urb) +{ + enum dma_data_direction dir; + struct musb_temp_buffer *temp; + + if (!(urb-transfer_flags URB_ALIGNED_TEMP_BUFFER)) + return; + + dir = usb_urb_dir_in(urb) ? DMA_FROM_DEVICE : DMA_TO_DEVICE; + + temp = container_of(urb-transfer_buffer, struct musb_temp_buffer, + data); + + if (dir == DMA_FROM_DEVICE) { + memcpy(temp-old_xfer_buffer, temp-data, + urb-transfer_buffer_length); + } + urb-transfer_buffer = temp-old_xfer_buffer; + kfree(temp-kmalloc_ptr); + + urb-transfer_flags = ~URB_ALIGNED_TEMP_BUFFER; +} + +static int musb_alloc_temp_buffer(struct urb *urb, gfp_t mem_flags) +{ + enum dma_data_direction dir; + struct musb_temp_buffer *temp; + void *kmalloc_ptr; + size_t kmalloc_size; + + if (urb-num_sgs || urb-sg || + urb-transfer_buffer_length == 0 || + !((uintptr_t)urb-transfer_buffer (MUSB_USB_DMA_ALIGN - 1))) + return 0; + + dir = usb_urb_dir_in(urb) ? DMA_FROM_DEVICE : DMA_TO_DEVICE; + + /* Allocate a buffer with enough padding for alignment */ + kmalloc_size = urb-transfer_buffer_length + + sizeof(struct musb_temp_buffer) + MUSB_USB_DMA_ALIGN - 1; + + kmalloc_ptr = kmalloc(kmalloc_size, mem_flags); + if (!kmalloc_ptr) + return -ENOMEM; + + /* Position our struct temp_buffer such that data is aligned */ + temp = PTR_ALIGN(kmalloc_ptr, MUSB_USB_DMA_ALIGN); + + + temp-kmalloc_ptr = kmalloc_ptr; + temp-old_xfer_buffer = urb-transfer_buffer; + if (dir == DMA_TO_DEVICE) + memcpy(temp-data, urb-transfer_buffer, + urb-transfer_buffer_length); + urb-transfer_buffer = temp-data; + + urb-transfer_flags |= URB_ALIGNED_TEMP_BUFFER; + + return 0; +} + +static int musb_map_urb_for_dma(struct usb_hcd *hcd, struct urb *urb, + gfp_t mem_flags) +{ + struct musb *musb = hcd_to_musb(hcd); + int ret; + + /* +* The DMA engine in RTL1.8 and above cannot handle +* DMA addresses that are not aligned to a 4 byte boundary. +* For such engine implemented (un)map_urb_for_dma hooks. +* Do not use these hooks for RTL1.8 +*/ + if (musb-hwvers MUSB_HWVERS_1800) + return usb_hcd_map_urb_for_dma(hcd, urb, mem_flags); + + ret = musb_alloc_temp_buffer(urb, mem_flags); + if (ret) + return ret; + + ret = usb_hcd_map_urb_for_dma(hcd, urb, mem_flags); + if (ret) + musb_free_temp_buffer(urb); + + return ret; +} + +static void musb_unmap_urb_for_dma(struct usb_hcd *hcd, struct urb *urb) +{ + struct musb *musb = hcd_to_musb(hcd); + + usb_hcd_unmap_urb_for_dma(hcd, urb); + + /* Do not use this hook for RTL1.8 (see description above) */ + if (musb-hwvers MUSB_HWVERS_1800) + return; + + musb_free_temp_buffer(urb); +} +#endif /* !CONFIG_MUSB_PIO_ONLY */ + const struct hc_driver musb_hc_driver = { .description= musb-hcd, .product_desc = MUSB HDRC host driver, @@ -2484,6 +2596,11 @@ const struct hc_driver musb_hc_driver = { .urb_dequeue= musb_urb_dequeue, .endpoint_disable = musb_h_disable, +#ifndef CONFIG_MUSB_PIO_ONLY + .map_urb_for_dma= musb_map_urb_for_dma, + .unmap_urb_for_dma = musb_unmap_urb_for_dma, +#endif + .hub_status_data= musb_hub_status_data, .hub_control= musb_hub_control, .bus_suspend= musb_bus_suspend, -- 1.7.9.5 -- To unsubscribe from this list:
Re: [PATCH 2/4] usb: introduce usb force power off mechanism
On Fri, 29 Mar 2013, Sarah Sharp wrote: However, what happens if you echo 0 to pm_qos_no_power_off, the power/control is set to auto, and there's a suspended USB device attached to the port with remote wakeup enabled? Will the port be powered off? I don't think it will with the current patchset, but I will have to double check. It shouldn't be, because remote wakeup is enabled. But what about the case where remote wakeup is disabled? Will writing a 0 to pm_qos_no_power_off cause the power to be turned off? Or what about the case where there's no device attached to the port? I guess both questions amount to the same thing: When the user writes to a pm_qos_* file, does the code call pm_runtime_idle? Maybe you have an Android smartphone or tablet, the user pushes the button to turn off the screen. In that case, you want to physically power off any USB devices, including ones that may be in USB device suspend with remote wakeup on, like a USB touchscreen. With the proposed patchset, you can do that through usbfs, but it feels awkward to have the PM QOS constraints and the manual power off in two separate places. I think if we're adding the usbfs interface, we should also add a manual 'off' to the port power/control file. That's not so easy to do. power/control is owned by the PM core, not by USB. From the PM core's perspective, power off is merely a variant of suspend. The USB subsystem gets to choose which variant to use, based on various constraints that userspace has imposed. In fact, if the user wants to, it is possible to set the port's pm_qos file to allow power off and then manage the port's actual behavior entirely by means of its power/control file. I sort of think that would be a cleaner approach ... but there may have been some reason for using the separate pm_qos attribute; I can't remember. Also, bear in mind that the proposed patch does not give userspace a way to power off ports via usbfs. What the new code does is a power-off reset -- it turns off power to the port, waits a short time, and then turns power back on. Alan Stern -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v3 1/7] USB: EHCI: make ehci-orion a separate driver
On Thu, 28 Mar 2013, Arnd Bergmann wrote: From: Manjunath Goudar manjunath.gou...@linaro.org Separate the Orion host controller driver from ehci-hcd host code into its own driver module because of following reason. ... On the whole this patch is good. --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig @@ -163,6 +163,16 @@ config USB_EHCI_HCD_OMAP Enables support for the on-chip EHCI controller on OMAP3 and later chips. +config USB_EHCI_HCD_ORION + tristate Support for Marvell EBU on-chip EHCI USB controller + depends on USB_EHCI_HCD PLAT_ORION + default y + ---help--- + Enables support for the on-chip EHCI controller on Marvell's + embedded ARM SoCs, including Orion, Kirkwood, Dove, Armada XP, + Armada 370. This is different from the EHCI implementation + on Marvell's mobile PXA and MMP SoC, see USB_EHCI_MV for those. I don't know about this last phrase. When someone is running make menuconfig, for example, what shows up is the symbol's description, not the symbol's name. That person would see EHCI support for Marvell on-chip controller, not USB_EHCI_MV. In fact, shouldn't the description for USB_EHCI_MV be changed too, to make it more distinct from this one? All the code changes are fine. Alan Stern -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v3 2/7] USB: EHCI: make ehci-spear a separate driver
On Thu, 28 Mar 2013, Arnd Bergmann wrote: From: Manjunath Goudar manjunath.gou...@linaro.org Separate the SPEAr host controller driver from ehci-hcd host code so that it can be built as a separate driver module. This work is part of enabling multi-platform kernels on ARM; however, note that other changes are still needed before SPEAr can be booted with a multi-platform kernel, but they are queued in the arm-soc tree for 3.10. With the infrastructure added by Alan Stern in patch 3e0232039 USB: EHCI: prepare to make ehci-hcd a library module, we can avoid this problem by turning a bus glue into a separate module, as we do here for the SPEAr bus glue. In V3: -Detailed commit message added here about why this patch is required. -Eliminated ehci_spear_setup routine beacuse hcd registers directly setting in spear_ehci_hcd_drv_probe function. Fix the grammar, please. -spear_overrides struct initialized. -Eliminate struct ehci_hcd ehci from struct spear_ehci,to enable SPEAr clock uses directly usb_hcd *hcd in spear_start_ehci function. -to_spear_ehci() macro modified for spear_ehci. In V2: Replaced spear as SPEAr everywhere, leaving functions/variables/config options. ... @@ -34,49 +45,7 @@ static void spear_stop_ehci(struct spear_ehci *ehci) clk_disable_unprepare(ehci-clk); } -static int ehci_spear_setup(struct usb_hcd *hcd) -{ - struct ehci_hcd *ehci = hcd_to_ehci(hcd); - - /* registers start at offset 0x0 */ - ehci-caps = hcd-regs; This line never got moved into spear_ehci_hcd_drv_probe(). @@ -161,7 +130,7 @@ static int spear_ehci_hcd_drv_probe(struct platform_device *pdev) goto err_put_hcd; } - ehci = (struct spear_ehci *)hcd_to_ehci(hcd); + ehci = to_spear_ehci(hcd); ehci-clk = usbh_clk; I strongly believe that the name ehci should be reserved for variables of type struct ehci_hcd. Here and in the start, stop, and remove routines, please use spear_ehci as the name for a variable of type struct spear_ehci. Or whatever else you want -- just don't call it ehci or ehci_p. Alan Stern -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 2/4] usb: introduce usb force power off mechanism
On Fri, Mar 29, 2013 at 01:23:14PM -0400, Alan Stern wrote: On Fri, 29 Mar 2013, Sarah Sharp wrote: However, what happens if you echo 0 to pm_qos_no_power_off, the power/control is set to auto, and there's a suspended USB device attached to the port with remote wakeup enabled? Will the port be powered off? I don't think it will with the current patchset, but I will have to double check. It shouldn't be, because remote wakeup is enabled. But what about the case where remote wakeup is disabled? Will writing a 0 to pm_qos_no_power_off cause the power to be turned off? Or what about the case where there's no device attached to the port? I guess both questions amount to the same thing: When the user writes to a pm_qos_* file, does the code call pm_runtime_idle? Tianyu? Maybe you have an Android smartphone or tablet, the user pushes the button to turn off the screen. In that case, you want to physically power off any USB devices, including ones that may be in USB device suspend with remote wakeup on, like a USB touchscreen. With the proposed patchset, you can do that through usbfs, but it feels awkward to have the PM QOS constraints and the manual power off in two separate places. I think if we're adding the usbfs interface, we should also add a manual 'off' to the port power/control file. That's not so easy to do. power/control is owned by the PM core, not by USB. From the PM core's perspective, power off is merely a variant of suspend. The USB subsystem gets to choose which variant to use, based on various constraints that userspace has imposed. Hmm, that's unfortunate. In fact, if the user wants to, it is possible to set the port's pm_qos file to allow power off and then manage the port's actual behavior entirely by means of its power/control file. I sort of think that would be a cleaner approach ... but there may have been some reason for using the separate pm_qos attribute; I can't remember. I think the implementation would be cleaner as well. I can't remember why we don't have power/control set to 'auto' and power/pm_qos_no_power_off set to '1' by default. I think the argument was about how to deal with multiple userspace programs that wanted to prevent port power off? It seems like you would want the opposite default (power/control set to 'on' and power/pm_qos_no_power_off set to '0'). That way, something like a firmware loader can express they don't want to power off a device by writing 1 to power/pm_qos_no_power_off, and programs like powertop can respect those decisions by just setting power/control to 'auto'. Right now, if powertop wanted to attempt to enable automatic port power off, it would have to overwrite any preferences the previous userspace programs expressed. Also, bear in mind that the proposed patch does not give userspace a way to power off ports via usbfs. What the new code does is a power-off reset -- it turns off power to the port, waits a short time, and then turns power back on. I think we need two separate IOCTLs: turn off the port power and turn it on. Then we get the manual port power off for our QA testing, distros can make interesting policies about manually powering off ports, and userspace can choose how long they want the port to be off. After all, different devices may need a longer powered-off period than others. Sarah Sharp -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 1/2 v3] usbnet: allow status interrupt URB to always be active
From: Dan Williams d...@redhat.com Date: Thu, 28 Mar 2013 11:30:07 -0500 + if (test_bit (EVENT_DEV_ASLEEP, dev-flags)) + return -EINVAL; + + mutex_lock (dev-interrupt_mutex); Please do not put a space between a function name and the openning parenthesis in the call. These are not C language primitives (where the space would be appropriate, f.e. if () they are C functions. -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 2/2 v3] sierra_net: keep status interrupt URB active
Please respin this along with patch #1 when you fix the coding style issues I mentioned, thanks. -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v3 3/7] USB: EHCI: make ehci-s5p a separate driver
On Thu, 28 Mar 2013, Arnd Bergmann wrote: From: Manjunath Goudar manjunath.gou...@linaro.org Separate the Samsung S5P/EXYNOS host controller driver from ehci-hcd host code so that it can be built as a separate driver module. This work is part of enabling multi-platform kernels on ARM; however, note that other changes are still needed before S5P/EXYNOS can be booted with a multi-platform kernel. We currently expect those to get merged for 3.10. With the infrastructure added by Alan Stern in patch 3e0232039 USB: EHCI: prepare to make ehci-hcd a library module, we can avoid this problem by turning a bus glue into a separate module, as we do here for the s5p bus glue. In V3: -Detail commit message added here,why this patch is required. -MODULE_LICENSE is GPL v2. -Added .extra_priv_size to eliminate the separate allocation of the s5p_ehci_hcd structure and removed .reset function pointer initialization. -Arranged #include's in alphabetical order. -After using extra_priv_size initialization,struct usb_hcd *hcd is redundant that's why removed from the prob function. -Eliminated s5p_ehci_phy_enable,contents of statements moved into the s5p_ehci_probe -Eliminated s5p_ehci_phy_disable, contents of statements moved into the s5p_ehci_remove. And several other places as well. Personally, I would have left these two functions the way they were and relied on the compiler to inline them when appropriate. Eliminating them just makes the code more complicated. ... @@ -113,9 +76,10 @@ static u64 ehci_s5p_dma_mask = DMA_BIT_MASK(32); static int s5p_ehci_probe(struct platform_device *pdev) { + struct usb_hcd *hcd ; struct s5p_ehci_platdata *pdata = pdev-dev.platform_data; + const struct hc_driver *driver = s5p_ehci_hc_driver; struct s5p_ehci_hcd *s5p_ehci; - struct usb_hcd *hcd; What's the reason for these changes? There's no need for the driver variable, and improper whitespace was added to the declaration of hcd. @@ -153,16 +117,12 @@ static int s5p_ehci_probe(struct platform_device *pdev) s5p_ehci-otg = phy-otg; } - s5p_ehci-dev = pdev-dev; - - hcd = usb_create_hcd(s5p_ehci_hc_driver, pdev-dev, - dev_name(pdev-dev)); + hcd = usb_create_hcd(driver, pdev-dev, dev_name(pdev-dev)); s5p_ehci is not initialized correctly. The devm_kzalloc() call was left in and to_s5p_ehci() was not called. Was anybody able to test this patch? Alan Stern -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v3 4/7] USB: EHCI: export ehci_shutdown
On Thu, 28 Mar 2013, Arnd Bergmann wrote: The ehci_shutdown function is used by the platform specific ehci backends for at91, tegra and ps3. In order to turn any of these into separate modules, we need to make this function globally visible and export it. Actually, I think this is not necessary. Instead those three glue files ought to be changed. They should not need to call ehci_shutdown() directly. The references to ehci_shutdown() in ehci-atmel.c and ehci-ps3.c seem totally unnecesary. That routine does a hard shutdown -- but the calls are immediately followed by usb_remove_hcd(), which calls ehci_stop(), which does an orderly shutdown followed by a reset. While it certainly would be good to check with the authors of these drivers, it would be surprising if removing those calls led to any trouble. The reference in ehci-tegra.c is there only so that tegra_ehci_shutdown() can call tegra_ehci_power_up() before doing its real work. Instead, tegra_ehci_power_up() should be called by tegra_ehci_hcd_shutdown(). Then there would be no need to have the tegra_ehci_shutdown() routine at all. Alan Stern -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v3 5/7] USB: EHCI: make ehci-atmel a separate driver
On Thu, 28 Mar 2013, Arnd Bergmann wrote: From: Manjunath Goudar manjunath.gou...@linaro.org Separate the Atmel host controller driver from ehci-hcd host code so that it can be built as a separate driver module. This work is part of enabling multi-platform kernels on ARM; however, note that other changes are still needed before Atmel can be booted with a multi-platform kernel. This is currently planned for Linux-3.11. With the infrastructure added by Alan Stern in patch 3e0232039 USB: EHCI: prepare to make ehci-hcd a library module, we can avoid this problem by turning a bus glue into a separate module, as we do here for the Atmel bus glue. Generally okay. diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig index 01c1acb..8c564aa 100644 --- a/drivers/usb/host/ehci-atmel.c +++ b/drivers/usb/host/ehci-atmel.c @@ -15,6 +15,19 @@ #include linux/platform_device.h #include linux/of.h #include linux/of_platform.h +#include linux/kernel.h +#include linux/module.h +#include linux/usb.h +#include linux/usb/hcd.h +#include linux/io.h +#include linux/dma-mapping.h While not absolutely necessary, it would be nice to have the #include files in alphabetical order. + +#include ehci.h + +#define DRIVER_DESC EHCI atmel driver atmel should have a capital 'A'. Alan Stern -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v3 6/7] USB: EHCI: make ehci-msm a separate driver
On Thu, 28 Mar 2013, Arnd Bergmann wrote: From: Manjunath Goudar manjunath.gou...@linaro.org Separate the Qualcomm QSD/MSM on-chip host controller driver from ehci-hcd host code so that it can be built as a separate driver module. This work is part of enabling multi-platform kernels on ARM; however, note that other changes are still needed before Qualcomm QSD/MSM can be booted with a multi-platform kernel, which is not expected before 3.11. With the infrastructure added by Alan Stern in patch 3e0232039 USB: EHCI: prepare to make ehci-hcd a library module, we can avoid this problem by turning a bus glue into a separate module, as we do here for the msm bus glue. This patch is good. However the ehci-msm driver itself is not. While checking through the code, I was struck by the fact that it never calls usb_add_hcd() or usb_remove_hcd(). Obviously the driver cannot work properly. In addition, it stores the PHY pointer in a global variable. (ehci-atmel does much the same thing for its clocks.) This means the driver cannot be used on a system having more than one EHCI controller. Maybe this doesn't matter, though. Maybe somebody would like to fix and test it... Alan Stern -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 2/4] usb: introduce usb force power off mechanism
On Fri, 29 Mar 2013, Sarah Sharp wrote: Also, bear in mind that the proposed patch does not give userspace a way to power off ports via usbfs. What the new code does is a power-off reset -- it turns off power to the port, waits a short time, and then turns power back on. I think we need two separate IOCTLs: turn off the port power and turn it on. Then we get the manual port power off for our QA testing, distros can make interesting policies about manually powering off ports, and userspace can choose how long they want the port to be off. After all, different devices may need a longer powered-off period than others. Or one port-power IOCTL that takes the setting as an argument. Yes, this would be more flexible than a power-off reset. Alan Stern -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [RFC PATCH 2/5] USB: remove USB_EHCI_BIG_ENDIAN_{DESC,MMIO} depends on architecture symbol
Hello Florian, On Tue, 26 Mar 2013 19:06:14 +0100 Florian Fainelli flor...@openwrt.org wrote: ... diff --git a/arch/powerpc/platforms/52xx/Kconfig b/arch/powerpc/platforms/52xx/Kconfig index 90f4496..65232cb 100644 --- a/arch/powerpc/platforms/52xx/Kconfig +++ b/arch/powerpc/platforms/52xx/Kconfig @@ -3,6 +3,8 @@ config PPC_MPC52xx depends on 6xx select PPC_CLOCK select PPC_PCI_CHOICE + select USB_EHCI_BIG_ENDIAN_MMIO + select USB_EHCI_BIG_ENDIAN_DESC Note that mpc52xx only has an OHCI controller, so this change here is wrong. It belongs into arch/powerpc/platforms/512x/Kconfig. mpc512x has an EHCI controller. Thanks, Anatolij -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] usb: PS3 EHCI remove unneeded ehci_shutdown
Remove an unneeded call to ehci_shutdown() in ps3_ehci_remove(). This removal will allow for a loadable ehci driver. Cc: Arnd Bergmann a...@arndb.de Signed-off-by: Geoff Levand ge...@infradead.org --- drivers/usb/host/ehci-ps3.c |1 - 1 file changed, 1 deletion(-) diff --git a/drivers/usb/host/ehci-ps3.c b/drivers/usb/host/ehci-ps3.c index df5925a..fd98377 100644 --- a/drivers/usb/host/ehci-ps3.c +++ b/drivers/usb/host/ehci-ps3.c @@ -221,7 +221,6 @@ static int ps3_ehci_remove(struct ps3_system_bus_device *dev) tmp = hcd-irq; - ehci_shutdown(hcd); usb_remove_hcd(hcd); ps3_system_bus_set_drvdata(dev, NULL); -- 1.7.9.5 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v3 4/7] USB: EHCI: export ehci_shutdown
Hi Alan, Actually, I think this is not necessary. Instead those three glue files ought to be changed. They should not need to call ehci_shutdown() directly. I sent out a separate patch that removes the ehci_shutdown() call in ps3_ehci_remove(). I tested it by removing and installing the ehci_hcd module and it seems to work OK. -Geoff -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 00/27] usb: chipidea: updates for v3.10
Hi Greg, This is an update for chipidea usb controller driver for usb-next. Some of these patches, though mostly mine, date as far back as november 2012. So here we have 27 patches, which * are coccinelle, smatch and sparse clean, save for the devm_ioremap_resource, * improve the core driver as well as some of the platforms, * include reworked debugging, * include a ton of fixes from Michael and some from others, * include usbmisc updates, add quirks for imx25 and imx53, * add support for big-endian cpus from Svetoslav, * revert something that has never worked, * all that at a negative diffstat. Alexander Shishkin (9): usb: chipidea: drop redundant includes usb: chipidea: trim include list in udc code usb: chipidea: trim include list in the core usb: chipidea: convert events to tracepoints usb: chipidea: replace interrupt accounting with tracepoints usb: chipidea: convert debug entries in sysfs to debugfs usb: chipidea: move role to debugfs usb: chipidea: move debug files creation/removal to the core usb: chipidea: make pci platform datas static Dan Carpenter (1): usb: chipidea: fix precedence bug in ci_requests_show() Felipe Balbi (2): usb: chipidea: don't redefine __ffs() usb: chipidea: core: switch over to devm_ioremap_resource Marc Kleine-Budde (3): usb: chipidea: usbmisc: unset global varibale usbmisc on driver remove usb: chipidea: usbmisc: fix a potential race condition usb: chipidea: usbmisc: prepare driver to handle more than one soc Michael Grzeschik (10): usb: chipidea: usbmisc: rename file, struct and functions to usbmisc_imx usb: chipidea: usbmisc: add mx53 support usb: chipidea: usbmisc: add post handling and errata fix for mx25 usb: chipidea: udc: only clear active and halted bits in qhead usb: chipidea: udc: rework ep_enable cap setting usb: chipidea: udc: move ZLT flag change to ep_enable usb: chipidea: udc: read status of td only once in hardware_dequeue usb: chipidea: udc: don't truncate requests to single tds usb: chipidea: udc: move _ep_queue into an unlocked function usb: chipidea: udc: add the define TD_PAGE_COUNT and fix all users Peter Chen (1): Revert USB: chipidea: add vbus detect for udc Svetoslav Neykov (1): usb: chipidea: big-endian support .../devicetree/bindings/usb/ci13xxx-imx.txt|2 + drivers/usb/chipidea/Makefile |2 +- drivers/usb/chipidea/ci.h | 32 +- drivers/usb/chipidea/ci13xxx_imx.c | 12 + drivers/usb/chipidea/ci13xxx_imx.h |3 + drivers/usb/chipidea/ci13xxx_pci.c |6 +- drivers/usb/chipidea/core.c| 68 +- drivers/usb/chipidea/debug.c | 888 +--- drivers/usb/chipidea/debug.h | 34 +- drivers/usb/chipidea/udc.c | 293 +++ drivers/usb/chipidea/udc.h |2 - drivers/usb/chipidea/usbmisc_imx.c | 261 ++ drivers/usb/chipidea/usbmisc_imx6q.c | 162 include/trace/events/chipidea.h| 151 14 files changed, 789 insertions(+), 1127 deletions(-) create mode 100644 drivers/usb/chipidea/usbmisc_imx.c delete mode 100644 drivers/usb/chipidea/usbmisc_imx6q.c create mode 100644 include/trace/events/chipidea.h -- 1.7.10.4 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 03/27] usb: chipidea: trim include list in the core
Some headers included in the chipidea controller core are not needed, remove them. Signed-off-by: Alexander Shishkin alexander.shish...@linux.intel.com --- drivers/usb/chipidea/core.c |3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c index 57cae1f..77963b6 100644 --- a/drivers/usb/chipidea/core.c +++ b/drivers/usb/chipidea/core.c @@ -51,15 +51,12 @@ */ #include linux/delay.h #include linux/device.h -#include linux/dmapool.h #include linux/dma-mapping.h -#include linux/init.h #include linux/platform_device.h #include linux/module.h #include linux/idr.h #include linux/interrupt.h #include linux/io.h -#include linux/irq.h #include linux/kernel.h #include linux/slab.h #include linux/pm_runtime.h -- 1.7.10.4 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 06/27] usb: chipidea: convert debug entries in sysfs to debugfs
Currently, we have a bunch of files in sysfs that display all sorts of debugging information for the device controller, so they have to move to debugfs where they belong. The registers interface have been removed, since it doesn't fit into the current driver design as is and it's hardly a good idea to touch the registers from userspace anyway. Signed-off-by: Alexander Shishkin alexander.shish...@linux.intel.com --- drivers/usb/chipidea/ci.h|2 + drivers/usb/chipidea/debug.c | 469 +- drivers/usb/chipidea/debug.h |9 +- drivers/usb/chipidea/udc.c |6 +- 4 files changed, 151 insertions(+), 335 deletions(-) diff --git a/drivers/usb/chipidea/ci.h b/drivers/usb/chipidea/ci.h index f67d101..fc8fc06 100644 --- a/drivers/usb/chipidea/ci.h +++ b/drivers/usb/chipidea/ci.h @@ -140,6 +140,7 @@ struct hw_bank { * @vbus_active: is VBUS active * @transceiver: pointer to USB PHY, if any * @hcd: pointer to usb_hcd for ehci host driver + * @debugfs: root dentry for this controller in debugfs */ struct ci13xxx { struct device *dev; @@ -176,6 +177,7 @@ struct ci13xxx { boolglobal_phy; struct usb_phy *transceiver; struct usb_hcd *hcd; + struct dentry *debugfs; }; static inline struct ci_role_driver *ci_role(struct ci13xxx *ci) diff --git a/drivers/usb/chipidea/debug.c b/drivers/usb/chipidea/debug.c index 898aca5..057ae09 100644 --- a/drivers/usb/chipidea/debug.c +++ b/drivers/usb/chipidea/debug.c @@ -2,6 +2,9 @@ #include linux/device.h #include linux/types.h #include linux/spinlock.h +#include linux/debugfs.h +#include linux/seq_file.h +#include linux/uaccess.h #include linux/usb/ch9.h #include linux/usb/gadget.h @@ -11,223 +14,113 @@ #include debug.h /** - * hw_register_read: reads all device registers (execute without interruption) - * @buf: destination buffer - * @size: buffer size - * - * This function returns number of registers read + * ci_device_show: prints information about device capabilities and status */ -static size_t hw_register_read(struct ci13xxx *ci, u32 *buf, size_t size) +static int ci_device_show(struct seq_file *s, void *data) { - unsigned i; - - if (size ci-hw_bank.size) - size = ci-hw_bank.size; - - for (i = 0; i size; i++) - buf[i] = hw_read(ci, i * sizeof(u32), ~0); - - return size; -} - -/** - * hw_register_write: writes to register - * @addr: register address - * @data: register value - * - * This function returns an error code - */ -static int hw_register_write(struct ci13xxx *ci, u16 addr, u32 data) -{ - /* align */ - addr /= sizeof(u32); + struct ci13xxx *ci = s-private; + struct usb_gadget *gadget = ci-gadget; - if (addr = ci-hw_bank.size) - return -EINVAL; + seq_printf(s, speed = %d\n, gadget-speed); + seq_printf(s, max_speed = %d\n, gadget-max_speed); + seq_printf(s, is_otg= %d\n, gadget-is_otg); + seq_printf(s, is_a_peripheral = %d\n, gadget-is_a_peripheral); + seq_printf(s, b_hnp_enable = %d\n, gadget-b_hnp_enable); + seq_printf(s, a_hnp_support = %d\n, gadget-a_hnp_support); + seq_printf(s, a_alt_hnp_support = %d\n, gadget-a_alt_hnp_support); + seq_printf(s, name = %s\n, + (gadget-name ? gadget-name : )); + + if (!ci-driver) + return 0; - /* align */ - addr *= sizeof(u32); + seq_printf(s, gadget function = %s\n, + (ci-driver-function ? ci-driver-function : )); + seq_printf(s, gadget max speed = %d\n, ci-driver-max_speed); - hw_write(ci, addr, ~0, data); return 0; } -/** - * hw_intr_clear: disables interrupt clears interrupt status (execute without - *interruption) - * @n: interrupt bit - * - * This function returns an error code - */ -static int hw_intr_clear(struct ci13xxx *ci, int n) +static int ci_device_open(struct inode *inode, struct file *file) { - if (n = REG_BITS) - return -EINVAL; - - hw_write(ci, OP_USBINTR, BIT(n), 0); - hw_write(ci, OP_USBSTS, BIT(n), BIT(n)); - return 0; + return single_open(file, ci_device_show, inode-i_private); } -/** - * hw_intr_force: enables interrupt forces interrupt status (execute without - *interruption) - * @n: interrupt bit - * - * This function returns an error code - */ -static int hw_intr_force(struct ci13xxx *ci, int n) -{ - if (n = REG_BITS) - return -EINVAL; - - hw_write(ci, CAP_TESTMODE, TESTMODE_FORCE, TESTMODE_FORCE); - hw_write(ci, OP_USBINTR, BIT(n), BIT(n)); - hw_write(ci, OP_USBSTS, BIT(n), BIT(n)); - hw_write(ci, CAP_TESTMODE, TESTMODE_FORCE, 0); - return 0; -} - -/** - *
[PATCH 07/27] usb: chipidea: move role to debugfs
Manual role switching function is there for debugging purposes, so has to move to debugfs. Signed-off-by: Alexander Shishkin alexander.shish...@linux.intel.com --- drivers/usb/chipidea/core.c | 39 -- drivers/usb/chipidea/debug.c | 54 ++ 2 files changed, 54 insertions(+), 39 deletions(-) diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c index d0aa172..ab7861d 100644 --- a/drivers/usb/chipidea/core.c +++ b/drivers/usb/chipidea/core.c @@ -282,38 +282,6 @@ static void ci_role_work(struct work_struct *work) } } -static ssize_t show_role(struct device *dev, struct device_attribute *attr, -char *buf) -{ - struct ci13xxx *ci = dev_get_drvdata(dev); - - return sprintf(buf, %s\n, ci_role(ci)-name); -} - -static ssize_t store_role(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) -{ - struct ci13xxx *ci = dev_get_drvdata(dev); - enum ci_role role; - int ret; - - for (role = CI_ROLE_HOST; role CI_ROLE_END; role++) - if (ci-roles[role] !strcmp(buf, ci-roles[role]-name)) - break; - - if (role == CI_ROLE_END || role == ci-role) - return -EINVAL; - - ci_role_stop(ci); - ret = ci_role_start(ci, role); - if (ret) - return ret; - - return count; -} - -static DEVICE_ATTR(role, S_IRUSR | S_IWUSR, show_role, store_role); - static irqreturn_t ci_irq(int irq, void *data) { struct ci13xxx *ci = data; @@ -488,17 +456,11 @@ static int ci_hdrc_probe(struct platform_device *pdev) if (ret) goto stop; - ret = device_create_file(dev, dev_attr_role); - if (ret) - goto rm_attr; - if (ci-is_otg) hw_write(ci, OP_OTGSC, OTGSC_IDIE, OTGSC_IDIE); return ret; -rm_attr: - device_remove_file(dev, dev_attr_role); stop: ci_role_stop(ci); rm_wq: @@ -514,7 +476,6 @@ static int ci_hdrc_remove(struct platform_device *pdev) flush_workqueue(ci-wq); destroy_workqueue(ci-wq); - device_remove_file(ci-dev, dev_attr_role); free_irq(ci-irq, ci); ci_role_stop(ci); diff --git a/drivers/usb/chipidea/debug.c b/drivers/usb/chipidea/debug.c index 057ae09..5738079 100644 --- a/drivers/usb/chipidea/debug.c +++ b/drivers/usb/chipidea/debug.c @@ -199,6 +199,55 @@ static const struct file_operations ci_requests_fops = { .release= single_release, }; +static int ci_role_show(struct seq_file *s, void *data) +{ + struct ci13xxx *ci = s-private; + + seq_printf(s, %s\n, ci_role(ci)-name); + + return 0; +} + +static ssize_t ci_role_write(struct file *file, const char __user *ubuf, +size_t count, loff_t *ppos) +{ + struct seq_file *s = file-private_data; + struct ci13xxx *ci = s-private; + enum ci_role role; + char buf[8]; + int ret; + + if (copy_from_user(buf, ubuf, min_t(size_t, sizeof(buf) - 1, count))) + return -EFAULT; + + for (role = CI_ROLE_HOST; role CI_ROLE_END; role++) + if (ci-roles[role] + !strncmp(buf, ci-roles[role]-name, +strlen(ci-roles[role]-name))) + break; + + if (role == CI_ROLE_END || role == ci-role) + return -EINVAL; + + ci_role_stop(ci); + ret = ci_role_start(ci, role); + + return ret ? ret : count; +} + +static int ci_role_open(struct inode *inode, struct file *file) +{ + return single_open(file, ci_role_show, inode-i_private); +} + +static const struct file_operations ci_role_fops = { + .open = ci_role_open, + .write = ci_role_write, + .read = seq_read, + .llseek = seq_lseek, + .release= single_release, +}; + /** * dbg_create_files: initializes the attribute interface * @ci: device @@ -230,6 +279,11 @@ int dbg_create_files(struct ci13xxx *ci) dent = debugfs_create_file(requests, S_IRUGO, ci-debugfs, ci, ci_requests_fops); + if (!dent) + goto err; + + dent = debugfs_create_file(role, S_IRUGO | S_IWUSR, ci-debugfs, ci, + ci_role_fops); if (dent) return 0; err: -- 1.7.10.4 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 02/27] usb: chipidea: trim include list in udc code
Some headers included in udc core code are not actually needed, remove them and add irqreturn.h, which was implicitly included via irq.h. Signed-off-by: Alexander Shishkin alexander.shish...@linux.intel.com --- drivers/usb/chipidea/udc.c |8 +--- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c index f64fbea..3dc5093 100644 --- a/drivers/usb/chipidea/udc.c +++ b/drivers/usb/chipidea/udc.c @@ -13,14 +13,8 @@ #include linux/delay.h #include linux/device.h #include linux/dmapool.h -#include linux/dma-mapping.h #include linux/err.h -#include linux/init.h -#include linux/platform_device.h -#include linux/module.h -#include linux/interrupt.h -#include linux/io.h -#include linux/irq.h +#include linux/irqreturn.h #include linux/kernel.h #include linux/slab.h #include linux/pm_runtime.h -- 1.7.10.4 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 08/27] usb: chipidea: move debug files creation/removal to the core
Create and remove debugfs entries in hdrc probe/remove instead of start/stop of the device controller. Gadget specific will not export anything while the controller is in host mode. Signed-off-by: Alexander Shishkin alexander.shish...@linux.intel.com --- drivers/usb/chipidea/core.c |6 +- drivers/usb/chipidea/udc.c |9 + 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c index ab7861d..8f1b083 100644 --- a/drivers/usb/chipidea/core.c +++ b/drivers/usb/chipidea/core.c @@ -459,8 +459,11 @@ static int ci_hdrc_probe(struct platform_device *pdev) if (ci-is_otg) hw_write(ci, OP_OTGSC, OTGSC_IDIE, OTGSC_IDIE); - return ret; + ret = dbg_create_files(ci); + if (!ret) + return 0; + free_irq(ci-irq, ci); stop: ci_role_stop(ci); rm_wq: @@ -474,6 +477,7 @@ static int ci_hdrc_remove(struct platform_device *pdev) { struct ci13xxx *ci = platform_get_drvdata(pdev); + dbg_remove_files(ci); flush_workqueue(ci-wq); destroy_workqueue(ci-wq); free_irq(ci-irq, ci); diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c index 6527f5c..58c8164 100644 --- a/drivers/usb/chipidea/udc.c +++ b/drivers/usb/chipidea/udc.c @@ -1756,15 +1756,11 @@ static int udc_start(struct ci13xxx *ci) goto put_transceiver; } - retval = dbg_create_files(ci); - if (retval) - goto unreg_device; - if (!IS_ERR_OR_NULL(ci-transceiver)) { retval = otg_set_peripheral(ci-transceiver-otg, ci-gadget); if (retval) - goto remove_dbg; + goto unreg_device; } retval = usb_add_gadget_udc(dev, ci-gadget); @@ -1784,8 +1780,6 @@ remove_trans: } dev_err(dev, error = %i\n, retval); -remove_dbg: - dbg_remove_files(ci); unreg_device: device_unregister(ci-gadget.dev); put_transceiver: @@ -1825,7 +1819,6 @@ static void udc_stop(struct ci13xxx *ci) if (ci-global_phy) usb_put_phy(ci-transceiver); } - dbg_remove_files(ci); device_unregister(ci-gadget.dev); /* my kobject is dynamic, I swear! */ memset(ci-gadget, 0, sizeof(ci-gadget)); -- 1.7.10.4 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 05/27] usb: chipidea: replace interrupt accounting with tracepoints
The driver also has interrupt counters and another ring buffer for keeping track of the order in which they arrive. This patch converts these counters to trace points. Userspace tools such as perf can provide information on both order and stats of the interrupts. Signed-off-by: Alexander Shishkin alexander.shish...@linux.intel.com --- drivers/usb/chipidea/debug.c| 160 +-- drivers/usb/chipidea/debug.h|5 -- drivers/usb/chipidea/udc.c | 11 ++- include/trace/events/chipidea.h | 18 - 4 files changed, 26 insertions(+), 168 deletions(-) diff --git a/drivers/usb/chipidea/debug.c b/drivers/usb/chipidea/debug.c index 9e9caa8..898aca5 100644 --- a/drivers/usb/chipidea/debug.c +++ b/drivers/usb/chipidea/debug.c @@ -10,46 +10,6 @@ #include bits.h #include debug.h -/* Interrupt statistics */ -#define ISR_MASK 0x1F -static struct isr_statistics { - u32 test; - u32 ui; - u32 uei; - u32 pci; - u32 uri; - u32 sli; - u32 none; - struct { - u32 cnt; - u32 buf[ISR_MASK+1]; - u32 idx; - } hndl; -} isr_statistics; - -void dbg_interrupt(u32 intmask) -{ - if (!intmask) { - isr_statistics.none++; - return; - } - - isr_statistics.hndl.buf[isr_statistics.hndl.idx++] = intmask; - isr_statistics.hndl.idx = ISR_MASK; - isr_statistics.hndl.cnt++; - - if (USBi_URI intmask) - isr_statistics.uri++; - if (USBi_PCI intmask) - isr_statistics.pci++; - if (USBi_UEI intmask) - isr_statistics.uei++; - if (USBi_UI intmask) - isr_statistics.ui++; - if (USBi_SLI intmask) - isr_statistics.sli++; -} - /** * hw_register_read: reads all device registers (execute without interruption) * @buf: destination buffer @@ -197,118 +157,6 @@ static ssize_t show_driver(struct device *dev, struct device_attribute *attr, static DEVICE_ATTR(driver, S_IRUSR, show_driver, NULL); /** - * show_inters: interrupt status, enable status and historic - * - * Check device.h for details - */ -static ssize_t show_inters(struct device *dev, struct device_attribute *attr, - char *buf) -{ - struct ci13xxx *ci = container_of(dev, struct ci13xxx, gadget.dev); - unsigned long flags; - u32 intr; - unsigned i, j, n = 0; - - if (attr == NULL || buf == NULL) { - dev_err(ci-dev, [%s] EINVAL\n, __func__); - return 0; - } - - spin_lock_irqsave(ci-lock, flags); - - /*n += scnprintf(buf + n, PAGE_SIZE - n, - status = %08x\n, hw_read_intr_status(ci)); - n += scnprintf(buf + n, PAGE_SIZE - n, - enable = %08x\n, hw_read_intr_enable(ci));*/ - - n += scnprintf(buf + n, PAGE_SIZE - n, *test = %d\n, - isr_statistics.test); - n += scnprintf(buf + n, PAGE_SIZE - n, ? ui = %d\n, - isr_statistics.ui); - n += scnprintf(buf + n, PAGE_SIZE - n, ? uei = %d\n, - isr_statistics.uei); - n += scnprintf(buf + n, PAGE_SIZE - n, ? pci = %d\n, - isr_statistics.pci); - n += scnprintf(buf + n, PAGE_SIZE - n, ? uri = %d\n, - isr_statistics.uri); - n += scnprintf(buf + n, PAGE_SIZE - n, ? sli = %d\n, - isr_statistics.sli); - n += scnprintf(buf + n, PAGE_SIZE - n, *none = %d\n, - isr_statistics.none); - n += scnprintf(buf + n, PAGE_SIZE - n, *hndl = %d\n, - isr_statistics.hndl.cnt); - - for (i = isr_statistics.hndl.idx, j = 0; j = ISR_MASK; j++, i++) { - i = ISR_MASK; - intr = isr_statistics.hndl.buf[i]; - - if (USBi_UI intr) - n += scnprintf(buf + n, PAGE_SIZE - n, ui ); - intr = ~USBi_UI; - if (USBi_UEI intr) - n += scnprintf(buf + n, PAGE_SIZE - n, uei ); - intr = ~USBi_UEI; - if (USBi_PCI intr) - n += scnprintf(buf + n, PAGE_SIZE - n, pci ); - intr = ~USBi_PCI; - if (USBi_URI intr) - n += scnprintf(buf + n, PAGE_SIZE - n, uri ); - intr = ~USBi_URI; - if (USBi_SLI intr) - n += scnprintf(buf + n, PAGE_SIZE - n, sli ); - intr = ~USBi_SLI; - if (intr) - n += scnprintf(buf + n, PAGE_SIZE - n, ??? ); - if (isr_statistics.hndl.buf[i]) - n += scnprintf(buf + n, PAGE_SIZE - n, \n); - } - - spin_unlock_irqrestore(ci-lock, flags); - - return n; -} - -/** - * store_inters: enable force or disable an individual interrutps - * (to be used for test
[PATCH 09/27] usb: chipidea: fix precedence bug in ci_requests_show()
From: Dan Carpenter dan.carpen...@oracle.com The intent here was to have parenthesis around the (ci-hw_ep_max / 2) so that it counts like 0 1 2 0 1 2. In the current code, the mod operation happens first so it counts like 0 0 1 1 2 2. Signed-off-by: Dan Carpenter dan.carpen...@oracle.com [rebased on top of debug.c changes] Signed-off-by: Alexander Shishkin alexander.shish...@linux.intel.com --- drivers/usb/chipidea/debug.c |2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/chipidea/debug.c b/drivers/usb/chipidea/debug.c index 5738079..36a7063 100644 --- a/drivers/usb/chipidea/debug.c +++ b/drivers/usb/chipidea/debug.c @@ -175,7 +175,7 @@ static int ci_requests_show(struct seq_file *s, void *data) req = list_entry(ptr, struct ci13xxx_req, queue); seq_printf(s, EP=%02i: TD=%08X %s\n, - i % ci-hw_ep_max/2, (u32)req-dma, + i % (ci-hw_ep_max / 2), (u32)req-dma, ((i ci-hw_ep_max/2) ? RX : TX)); for (j = 0; j qsize; j++) -- 1.7.10.4 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 04/27] usb: chipidea: convert events to tracepoints
As part of the legacy from the original driver design, we retain home-grown tracing infrastructure, complete with own ring buffer and timestamps. While it is useful for debugging certain cases, it's a lot of extra code, which these days is rather redundant. This patch replaces local tracing functionality with kernel tracepoints, thus getting rid of the ring buffer and all the maintenance code, while making use of standard kernel infrastructure. Signed-off-by: Alexander Shishkin alexander.shish...@linux.intel.com --- drivers/usb/chipidea/ci.h | 13 +++ drivers/usb/chipidea/core.c |2 + drivers/usb/chipidea/debug.c| 202 +-- drivers/usb/chipidea/debug.h| 20 drivers/usb/chipidea/udc.c | 46 - drivers/usb/chipidea/udc.h |2 - include/trace/events/chipidea.h | 135 ++ 7 files changed, 169 insertions(+), 251 deletions(-) create mode 100644 include/trace/events/chipidea.h diff --git a/drivers/usb/chipidea/ci.h b/drivers/usb/chipidea/ci.h index e25d126..f67d101 100644 --- a/drivers/usb/chipidea/ci.h +++ b/drivers/usb/chipidea/ci.h @@ -23,6 +23,8 @@ */ #define CI13XXX_PAGE_SIZE 4096ul /* page size for TD's */ #define ENDPT_MAX 32 +#define RX0 /* similar to USB_DIR_OUT but can be used as an index */ +#define TX1 /* similar to USB_DIR_IN but can be used as an index */ /** * STRUCTURES @@ -59,6 +61,15 @@ struct ci13xxx_ep { struct dma_pool *td_pool; }; +/** + * ci_ep_addr: calculates endpoint address from direction number + * @ep: endpoint + */ +static inline u8 ci_ep_addr(struct ci13xxx_ep *ep) +{ + return ((ep-dir == TX) ? USB_ENDPOINT_DIR_MASK : 0) | ep-num; +} + enum ci_role { CI_ROLE_HOST = 0, CI_ROLE_GADGET, @@ -313,4 +324,6 @@ int hw_port_test_set(struct ci13xxx *ci, u8 mode); u8 hw_port_test_get(struct ci13xxx *ci); +#include trace/events/chipidea.h + #endif /* __DRIVERS_USB_CHIPIDEA_CI_H */ diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c index 77963b6..d0aa172 100644 --- a/drivers/usb/chipidea/core.c +++ b/drivers/usb/chipidea/core.c @@ -65,6 +65,8 @@ #include linux/usb/otg.h #include linux/usb/chipidea.h +#define CREATE_TRACE_POINTS + #include ci.h #include udc.h #include bits.h diff --git a/drivers/usb/chipidea/debug.c b/drivers/usb/chipidea/debug.c index e6cc45e..9e9caa8 100644 --- a/drivers/usb/chipidea/debug.c +++ b/drivers/usb/chipidea/debug.c @@ -196,200 +196,6 @@ static ssize_t show_driver(struct device *dev, struct device_attribute *attr, } static DEVICE_ATTR(driver, S_IRUSR, show_driver, NULL); -/* Maximum event message length */ -#define DBG_DATA_MSG 64UL - -/* Maximum event messages */ -#define DBG_DATA_MAX 128UL - -/* Event buffer descriptor */ -static struct { - char (buf[DBG_DATA_MAX])[DBG_DATA_MSG]; /* buffer */ - unsigned idx; /* index */ - unsigned tty; /* print to console? */ - rwlock_t lck; /* lock */ -} dbg_data = { - .idx = 0, - .tty = 0, - .lck = __RW_LOCK_UNLOCKED(dbg_data.lck) -}; - -/** - * dbg_dec: decrements debug event index - * @idx: buffer index - */ -static void dbg_dec(unsigned *idx) -{ - *idx = (*idx - 1) (DBG_DATA_MAX-1); -} - -/** - * dbg_inc: increments debug event index - * @idx: buffer index - */ -static void dbg_inc(unsigned *idx) -{ - *idx = (*idx + 1) (DBG_DATA_MAX-1); -} - -/** - * dbg_print: prints the common part of the event - * @addr: endpoint address - * @name: event name - * @status: status - * @extra: extra information - */ -static void dbg_print(u8 addr, const char *name, int status, const char *extra) -{ - struct timeval tval; - unsigned int stamp; - unsigned long flags; - - write_lock_irqsave(dbg_data.lck, flags); - - do_gettimeofday(tval); - stamp = tval.tv_sec 0x; /* 2^32 = 4294967296. Limit to 4096s */ - stamp = stamp * 100 + tval.tv_usec; - - scnprintf(dbg_data.buf[dbg_data.idx], DBG_DATA_MSG, - %04X\t? %02X %-7.7s %4i ?\t%s\n, - stamp, addr, name, status, extra); - - dbg_inc(dbg_data.idx); - - write_unlock_irqrestore(dbg_data.lck, flags); - - if (dbg_data.tty != 0) - pr_notice(%04X\t? %02X %-7.7s %4i ?\t%s\n, - stamp, addr, name, status, extra); -} - -/** - * dbg_done: prints a DONE event - * @addr: endpoint address - * @td: transfer descriptor - * @status: status - */ -void dbg_done(u8 addr, const u32 token, int status) -{ - char msg[DBG_DATA_MSG]; - - scnprintf(msg, sizeof(msg), %d %02X, - (int)(token TD_TOTAL_BYTES) ffs_nr(TD_TOTAL_BYTES), - (int)(token TD_STATUS)
[PATCH 10/27] usb: chipidea: don't redefine __ffs()
From: Felipe Balbi ba...@ti.com chipidea's ffs_nr() is pretty much what __ffs() does. Use that one instead. Signed-off-by: Felipe Balbi ba...@ti.com [rebased on top of debug infrastructure rework] Signed-off-by: Alexander Shishkin alexander.shish...@linux.intel.com --- drivers/usb/chipidea/ci.h | 15 +-- drivers/usb/chipidea/core.c |8 drivers/usb/chipidea/udc.c | 12 ++-- 3 files changed, 11 insertions(+), 24 deletions(-) diff --git a/drivers/usb/chipidea/ci.h b/drivers/usb/chipidea/ci.h index fc8fc06..7dcd390 100644 --- a/drivers/usb/chipidea/ci.h +++ b/drivers/usb/chipidea/ci.h @@ -247,19 +247,6 @@ enum ci13xxx_regs { }; /** - * ffs_nr: find first (least significant) bit set - * @x: the word to search - * - * This function returns bit number (instead of position) - */ -static inline int ffs_nr(u32 x) -{ - int n = ffs(x); - - return n ? n-1 : 32; -} - -/** * hw_read: reads from a hw register * @reg: register index * @mask: bitfield mask @@ -317,7 +304,7 @@ static inline u32 hw_test_and_write(struct ci13xxx *ci, enum ci13xxx_regs reg, u32 val = hw_read(ci, reg, ~0); hw_write(ci, reg, mask, data); - return (val mask) ffs_nr(mask); + return (val mask) __ffs(mask); } int hw_device_reset(struct ci13xxx *ci, u32 mode); diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c index 8f1b083..47b8da2 100644 --- a/drivers/usb/chipidea/core.c +++ b/drivers/usb/chipidea/core.c @@ -157,7 +157,7 @@ int hw_port_test_set(struct ci13xxx *ci, u8 mode) if (mode TEST_MODE_MAX) return -EINVAL; - hw_write(ci, OP_PORTSC, PORTSC_PTC, mode ffs_nr(PORTSC_PTC)); + hw_write(ci, OP_PORTSC, PORTSC_PTC, mode __ffs(PORTSC_PTC)); return 0; } @@ -168,7 +168,7 @@ int hw_port_test_set(struct ci13xxx *ci, u8 mode) */ u8 hw_port_test_get(struct ci13xxx *ci) { - return hw_read(ci, OP_PORTSC, PORTSC_PTC) ffs_nr(PORTSC_PTC); + return hw_read(ci, OP_PORTSC, PORTSC_PTC) __ffs(PORTSC_PTC); } static int hw_device_init(struct ci13xxx *ci, void __iomem *base) @@ -184,7 +184,7 @@ static int hw_device_init(struct ci13xxx *ci, void __iomem *base) hw_alloc_regmap(ci, false); reg = hw_read(ci, CAP_HCCPARAMS, HCCPARAMS_LEN) - ffs_nr(HCCPARAMS_LEN); + __ffs(HCCPARAMS_LEN); ci-hw_bank.lpm = reg; hw_alloc_regmap(ci, !!reg); ci-hw_bank.size = ci-hw_bank.op - ci-hw_bank.abs; @@ -192,7 +192,7 @@ static int hw_device_init(struct ci13xxx *ci, void __iomem *base) ci-hw_bank.size /= sizeof(u32); reg = hw_read(ci, CAP_DCCPARAMS, DCCPARAMS_DEN) - ffs_nr(DCCPARAMS_DEN); + __ffs(DCCPARAMS_DEN); ci-hw_ep_max = reg * 2; /* cache hw ENDPT_MAX */ if (ci-hw_ep_max ENDPT_MAX) diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c index 58c8164..4a7b356 100644 --- a/drivers/usb/chipidea/udc.c +++ b/drivers/usb/chipidea/udc.c @@ -140,7 +140,7 @@ static int hw_ep_enable(struct ci13xxx *ci, int num, int dir, int type) if (dir) { mask = ENDPTCTRL_TXT; /* type*/ - data = type ffs_nr(mask); + data = type __ffs(mask); mask |= ENDPTCTRL_TXS; /* unstall */ mask |= ENDPTCTRL_TXR; /* reset data toggle */ @@ -149,7 +149,7 @@ static int hw_ep_enable(struct ci13xxx *ci, int num, int dir, int type) data |= ENDPTCTRL_TXE; } else { mask = ENDPTCTRL_RXT; /* type*/ - data = type ffs_nr(mask); + data = type __ffs(mask); mask |= ENDPTCTRL_RXS; /* unstall */ mask |= ENDPTCTRL_RXR; /* reset data toggle */ @@ -343,7 +343,7 @@ static int hw_test_and_set_setup_guard(struct ci13xxx *ci) static void hw_usb_set_address(struct ci13xxx *ci, u8 value) { hw_write(ci, OP_DEVICEADDR, DEVICEADDR_USBADR, -value ffs_nr(DEVICEADDR_USBADR)); +value __ffs(DEVICEADDR_USBADR)); } /** @@ -431,7 +431,7 @@ static int _hardware_enqueue(struct ci13xxx_ep *mEp, struct ci13xxx_req *mReq) * TODO - handle requests which spawns into several TDs */ memset(mReq-ptr, 0, sizeof(*mReq-ptr)); - mReq-ptr-token= length ffs_nr(TD_TOTAL_BYTES); + mReq-ptr-token= length __ffs(TD_TOTAL_BYTES); mReq-ptr-token = TD_TOTAL_BYTES; mReq-ptr-token |= TD_STATUS_ACTIVE; if (mReq-zptr) { @@ -517,7 +517,7 @@ static int _hardware_dequeue(struct ci13xxx_ep *mEp, struct ci13xxx_req *mReq) mReq-req.status = -1; mReq-req.actual = mReq-ptr-token TD_TOTAL_BYTES; - mReq-req.actual = ffs_nr(TD_TOTAL_BYTES); + mReq-req.actual = __ffs(TD_TOTAL_BYTES); mReq-req.actual = mReq-req.length - mReq-req.actual; mReq-req.actual =
[PATCH 11/27] usb: chipidea: core: switch over to devm_ioremap_resource
From: Felipe Balbi ba...@ti.com switch over to the newly added devm_ioremap_resource which provides more consistent error messages. Signed-off-by: Felipe Balbi ba...@ti.com Signed-off-by: Alexander Shishkin alexander.shish...@linux.intel.com --- drivers/usb/chipidea/core.c |8 +++- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c index 47b8da2..2824215 100644 --- a/drivers/usb/chipidea/core.c +++ b/drivers/usb/chipidea/core.c @@ -377,11 +377,9 @@ static int ci_hdrc_probe(struct platform_device *pdev) return -ENODEV; } - base = devm_request_and_ioremap(dev, res); - if (!base) { - dev_err(dev, can't request and ioremap resource\n); - return -ENOMEM; - } + base = devm_ioremap_resource(dev, res); + if (IS_ERR(base)) + return PTR_ERR(base); ci = devm_kzalloc(dev, sizeof(*ci), GFP_KERNEL); if (!ci) { -- 1.7.10.4 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 12/27] usb: chipidea: usbmisc: rename file, struct and functions to usbmisc_imx
From: Michael Grzeschik m.grzesc...@pengutronix.de This driver will be used for every Freescale SoC which has this misc memory layout to control the basic usb handling. So better name this driver, function and struct names in a more generic way. Reported-by: Fabio Estevam feste...@gmail.com Signed-off-by: Michael Grzeschik m.grzesc...@pengutronix.de Signed-off-by: Marc Kleine-Budde m...@pengutronix.de Signed-off-by: Alexander Shishkin alexander.shish...@linux.intel.com Conflicts: drivers/usb/chipidea/usbmisc_imx.c --- drivers/usb/chipidea/Makefile|2 +- drivers/usb/chipidea/usbmisc_imx.c | 162 ++ drivers/usb/chipidea/usbmisc_imx6q.c | 162 -- 3 files changed, 163 insertions(+), 163 deletions(-) create mode 100644 drivers/usb/chipidea/usbmisc_imx.c delete mode 100644 drivers/usb/chipidea/usbmisc_imx6q.c diff --git a/drivers/usb/chipidea/Makefile b/drivers/usb/chipidea/Makefile index d92ca32..4ab83e9 100644 --- a/drivers/usb/chipidea/Makefile +++ b/drivers/usb/chipidea/Makefile @@ -17,5 +17,5 @@ ifneq ($(CONFIG_PCI),) endif ifneq ($(CONFIG_OF_DEVICE),) - obj-$(CONFIG_USB_CHIPIDEA) += ci13xxx_imx.o usbmisc_imx6q.o + obj-$(CONFIG_USB_CHIPIDEA) += ci13xxx_imx.o usbmisc_imx.o endif diff --git a/drivers/usb/chipidea/usbmisc_imx.c b/drivers/usb/chipidea/usbmisc_imx.c new file mode 100644 index 000..3c42446 --- /dev/null +++ b/drivers/usb/chipidea/usbmisc_imx.c @@ -0,0 +1,162 @@ +/* + * Copyright 2012 Freescale Semiconductor, Inc. + * + * The code contained herein is licensed under the GNU General Public + * License. You may obtain a copy of the GNU General Public License + * Version 2 or later at the following locations: + * + * http://www.opensource.org/licenses/gpl-license.html + * http://www.gnu.org/copyleft/gpl.html + */ + +#include linux/module.h +#include linux/of_platform.h +#include linux/clk.h +#include linux/err.h +#include linux/io.h + +#include ci13xxx_imx.h + +#define USB_DEV_MAX 4 + +#define BM_OVER_CUR_DISBIT(7) + +struct imx_usbmisc { + void __iomem *base; + spinlock_t lock; + struct clk *clk; + struct usbmisc_usb_device usbdev[USB_DEV_MAX]; +}; + +static struct imx_usbmisc *usbmisc; + +static struct usbmisc_usb_device *get_usbdev(struct device *dev) +{ + int i, ret; + + for (i = 0; i USB_DEV_MAX; i++) { + if (usbmisc-usbdev[i].dev == dev) + return usbmisc-usbdev[i]; + else if (!usbmisc-usbdev[i].dev) + break; + } + + if (i = USB_DEV_MAX) + return ERR_PTR(-EBUSY); + + ret = usbmisc_get_init_data(dev, usbmisc-usbdev[i]); + if (ret) + return ERR_PTR(ret); + + return usbmisc-usbdev[i]; +} + +static int usbmisc_imx6q_init(struct device *dev) +{ + + struct usbmisc_usb_device *usbdev; + unsigned long flags; + u32 reg; + + usbdev = get_usbdev(dev); + if (IS_ERR(usbdev)) + return PTR_ERR(usbdev); + + if (usbdev-disable_oc) { + spin_lock_irqsave(usbmisc-lock, flags); + reg = readl(usbmisc-base + usbdev-index * 4); + writel(reg | BM_OVER_CUR_DIS, + usbmisc-base + usbdev-index * 4); + spin_unlock_irqrestore(usbmisc-lock, flags); + } + + return 0; +} + +static const struct usbmisc_ops imx6q_usbmisc_ops = { + .init = usbmisc_imx6q_init, +}; + +static const struct of_device_id usbmisc_imx_dt_ids[] = { + { .compatible = fsl,imx6q-usbmisc}, + { /* sentinel */ } +}; + +static int usbmisc_imx_probe(struct platform_device *pdev) +{ + struct resource *res; + struct imx_usbmisc *data; + int ret; + + if (usbmisc) + return -EBUSY; + + data = devm_kzalloc(pdev-dev, sizeof(*data), GFP_KERNEL); + if (!data) + return -ENOMEM; + + spin_lock_init(data-lock); + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + data-base = devm_ioremap_resource(pdev-dev, res); + if (IS_ERR(data-base)) + return PTR_ERR(data-base); + + data-clk = devm_clk_get(pdev-dev, NULL); + if (IS_ERR(data-clk)) { + dev_err(pdev-dev, + failed to get clock, err=%ld\n, PTR_ERR(data-clk)); + return PTR_ERR(data-clk); + } + + ret = clk_prepare_enable(data-clk); + if (ret) { + dev_err(pdev-dev, + clk_prepare_enable failed, err=%d\n, ret); + return ret; + } + + ret = usbmisc_set_ops(imx6q_usbmisc_ops); + if (ret) { + clk_disable_unprepare(data-clk); + return ret; + } + + usbmisc = data; + + return 0; +} + +static int usbmisc_imx_remove(struct platform_device *pdev) +{ +
[PATCH 13/27] usb: chipidea: usbmisc: unset global varibale usbmisc on driver remove
From: Marc Kleine-Budde m...@pengutronix.de The probe function checks usbmisc to be NULL in the beginning. Without this patch the can only be loaded once. Signed-off-by: Marc Kleine-Budde m...@pengutronix.de Signed-off-by: Michael Grzeschik m.grzesc...@pengutronix.de Signed-off-by: Alexander Shishkin alexander.shish...@linux.intel.com --- drivers/usb/chipidea/usbmisc_imx.c |1 + 1 file changed, 1 insertion(+) diff --git a/drivers/usb/chipidea/usbmisc_imx.c b/drivers/usb/chipidea/usbmisc_imx.c index 3c42446..fd4d339 100644 --- a/drivers/usb/chipidea/usbmisc_imx.c +++ b/drivers/usb/chipidea/usbmisc_imx.c @@ -131,6 +131,7 @@ static int usbmisc_imx_remove(struct platform_device *pdev) { usbmisc_unset_ops(imx6q_usbmisc_ops); clk_disable_unprepare(usbmisc-clk); + usbmisc = NULL; return 0; } -- 1.7.10.4 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 14/27] usb: chipidea: usbmisc: fix a potential race condition
From: Marc Kleine-Budde m...@pengutronix.de This fixes a potential race condition where the ci13xxx_imx glue code could be fast enough to call one of the usbmisc_ops before he got a valid value on the static usbmisc pointer. To fix that we first set usbmisc, then call usbmisc_set_ops(). Signed-off-by: Marc Kleine-Budde m...@pengutronix.de Signed-off-by: Michael Grzeschik m.grzesc...@pengutronix.de Signed-off-by: Alexander Shishkin alexander.shish...@linux.intel.com --- drivers/usb/chipidea/usbmisc_imx.c |4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/usb/chipidea/usbmisc_imx.c b/drivers/usb/chipidea/usbmisc_imx.c index fd4d339..d77e712 100644 --- a/drivers/usb/chipidea/usbmisc_imx.c +++ b/drivers/usb/chipidea/usbmisc_imx.c @@ -116,14 +116,14 @@ static int usbmisc_imx_probe(struct platform_device *pdev) return ret; } + usbmisc = data; ret = usbmisc_set_ops(imx6q_usbmisc_ops); if (ret) { + usbmisc = NULL; clk_disable_unprepare(data-clk); return ret; } - usbmisc = data; - return 0; } -- 1.7.10.4 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 17/27] usb: chipidea: usbmisc: add post handling and errata fix for mx25
From: Michael Grzeschik m.grzesc...@pengutronix.de This adds a post handling routine which is called after ci13xxx_add_device was called. The first user is the mx25, which has to disable the external-vbus-divider after the udc has started. Signed-off-by: Michael Grzeschik m.grzesc...@pengutronix.de Signed-off-by: Marc Kleine-Budde m...@pengutronix.de [Alex: also fixed a signed one-bit bitfield a whitespace error and yet another set of line-too-long and void pointer casting errors] Signed-off-by: Alexander Shishkin alexander.shish...@linux.intel.com Conflicts: drivers/usb/chipidea/ci13xxx_imx.h --- .../devicetree/bindings/usb/ci13xxx-imx.txt|2 ++ drivers/usb/chipidea/ci13xxx_imx.c | 12 +++ drivers/usb/chipidea/ci13xxx_imx.h |3 ++ drivers/usb/chipidea/usbmisc_imx.c | 36 4 files changed, 53 insertions(+) diff --git a/Documentation/devicetree/bindings/usb/ci13xxx-imx.txt b/Documentation/devicetree/bindings/usb/ci13xxx-imx.txt index 5778b9c..1c04a4c 100644 --- a/Documentation/devicetree/bindings/usb/ci13xxx-imx.txt +++ b/Documentation/devicetree/bindings/usb/ci13xxx-imx.txt @@ -11,6 +11,7 @@ Optional properties: that indicate usb controller index - vbus-supply: regulator for vbus - disable-over-current: disable over current detect +- external-vbus-divider: enables off-chip resistor divider for Vbus Examples: usb@02184000 { /* USB OTG */ @@ -20,4 +21,5 @@ usb@02184000 { /* USB OTG */ fsl,usbphy = usbphy1; fsl,usbmisc = usbmisc 0; disable-over-current; + external-vbus-divider; }; diff --git a/drivers/usb/chipidea/ci13xxx_imx.c b/drivers/usb/chipidea/ci13xxx_imx.c index 8c29122..8faec9d 100644 --- a/drivers/usb/chipidea/ci13xxx_imx.c +++ b/drivers/usb/chipidea/ci13xxx_imx.c @@ -79,6 +79,9 @@ int usbmisc_get_init_data(struct device *dev, struct usbmisc_usb_device *usbdev) if (of_find_property(np, disable-over-current, NULL)) usbdev-disable_oc = 1; + if (of_find_property(np, external-vbus-divider, NULL)) + usbdev-evdo = 1; + return 0; } EXPORT_SYMBOL_GPL(usbmisc_get_init_data); @@ -202,6 +205,15 @@ static int ci13xxx_imx_probe(struct platform_device *pdev) goto err; } + if (usbmisc_ops usbmisc_ops-post) { + ret = usbmisc_ops-post(pdev-dev); + if (ret) { + dev_err(pdev-dev, + usbmisc post failed, ret=%d\n, ret); + goto put_np; + } + } + data-ci_pdev = plat_ci; platform_set_drvdata(pdev, data); diff --git a/drivers/usb/chipidea/ci13xxx_imx.h b/drivers/usb/chipidea/ci13xxx_imx.h index 9cd2e91..550bfa4 100644 --- a/drivers/usb/chipidea/ci13xxx_imx.h +++ b/drivers/usb/chipidea/ci13xxx_imx.h @@ -13,6 +13,8 @@ struct usbmisc_ops { /* It's called once when probe a usb device */ int (*init)(struct device *dev); + /* It's called once after adding a usb device */ + int (*post)(struct device *dev); }; struct usbmisc_usb_device { @@ -20,6 +22,7 @@ struct usbmisc_usb_device { int index; unsigned int disable_oc:1; /* over current detect disabled */ + unsigned int evdo:1; /* set external vbus divider option */ }; int usbmisc_set_ops(const struct usbmisc_ops *ops); diff --git a/drivers/usb/chipidea/usbmisc_imx.c b/drivers/usb/chipidea/usbmisc_imx.c index 746013d..714a6bd 100644 --- a/drivers/usb/chipidea/usbmisc_imx.c +++ b/drivers/usb/chipidea/usbmisc_imx.c @@ -14,11 +14,15 @@ #include linux/clk.h #include linux/err.h #include linux/io.h +#include linux/delay.h #include ci13xxx_imx.h #define USB_DEV_MAX 4 +#define MX25_USB_PHY_CTRL_OFFSET 0x08 +#define MX25_BM_EXTERNAL_VBUS_DIVIDER BIT(23) + #define MX53_USB_OTG_PHY_CTRL_0_OFFSET 0x08 #define MX53_USB_UH2_CTRL_OFFSET 0x14 #define MX53_USB_UH3_CTRL_OFFSET 0x18 @@ -59,6 +63,30 @@ static struct usbmisc_usb_device *get_usbdev(struct device *dev) return usbmisc-usbdev[i]; } +static int usbmisc_imx25_post(struct device *dev) +{ + struct usbmisc_usb_device *usbdev; + void __iomem *reg; + unsigned long flags; + u32 val; + + usbdev = get_usbdev(dev); + if (IS_ERR(usbdev)) + return PTR_ERR(usbdev); + + reg = usbmisc-base + MX25_USB_PHY_CTRL_OFFSET; + + if (usbdev-evdo) { + spin_lock_irqsave(usbmisc-lock, flags); + val = readl(reg); + writel(val | MX25_BM_EXTERNAL_VBUS_DIVIDER, reg); + spin_unlock_irqrestore(usbmisc-lock, flags); + usleep_range(5000, 1); /* needed to stabilize voltage */ + } + + return 0; +} + static int usbmisc_imx53_init(struct device *dev) { struct usbmisc_usb_device *usbdev; @@ -120,6 +148,10 @@ static int usbmisc_imx6q_init(struct
[PATCH 16/27] usb: chipidea: usbmisc: add mx53 support
From: Michael Grzeschik m.grzesc...@pengutronix.de This adds mx53 as the next user of the usbmisc driver and makes it possible to disable the overcurrent-detection of the internal phy. Signed-off-by: Michael Grzeschik m.grzesc...@pengutronix.de Signed-off-by: Marc Kleine-Budde m...@pengutronix.de [Alex: fixed another set of line-too-long and void pointer cast] Signed-off-by: Alexander Shishkin alexander.shish...@linux.intel.com --- drivers/usb/chipidea/usbmisc_imx.c | 54 1 file changed, 54 insertions(+) diff --git a/drivers/usb/chipidea/usbmisc_imx.c b/drivers/usb/chipidea/usbmisc_imx.c index 08b046f..746013d 100644 --- a/drivers/usb/chipidea/usbmisc_imx.c +++ b/drivers/usb/chipidea/usbmisc_imx.c @@ -19,6 +19,13 @@ #define USB_DEV_MAX 4 +#define MX53_USB_OTG_PHY_CTRL_0_OFFSET 0x08 +#define MX53_USB_UH2_CTRL_OFFSET 0x14 +#define MX53_USB_UH3_CTRL_OFFSET 0x18 +#define MX53_BM_OVER_CUR_DIS_H1BIT(5) +#define MX53_BM_OVER_CUR_DIS_OTG BIT(8) +#define MX53_BM_OVER_CUR_DIS_UHx BIT(30) + #define MX6_BM_OVER_CUR_DISBIT(7) struct imx_usbmisc { @@ -52,6 +59,45 @@ static struct usbmisc_usb_device *get_usbdev(struct device *dev) return usbmisc-usbdev[i]; } +static int usbmisc_imx53_init(struct device *dev) +{ + struct usbmisc_usb_device *usbdev; + void __iomem *reg = NULL; + unsigned long flags; + u32 val = 0; + + usbdev = get_usbdev(dev); + if (IS_ERR(usbdev)) + return PTR_ERR(usbdev); + + if (usbdev-disable_oc) { + spin_lock_irqsave(usbmisc-lock, flags); + switch (usbdev-index) { + case 0: + reg = usbmisc-base + MX53_USB_OTG_PHY_CTRL_0_OFFSET; + val = readl(reg) | MX53_BM_OVER_CUR_DIS_OTG; + break; + case 1: + reg = usbmisc-base + MX53_USB_OTG_PHY_CTRL_0_OFFSET; + val = readl(reg) | MX53_BM_OVER_CUR_DIS_H1; + break; + case 2: + reg = usbmisc-base + MX53_USB_UH2_CTRL_OFFSET; + val = readl(reg) | MX53_BM_OVER_CUR_DIS_UHx; + break; + case 3: + reg = usbmisc-base + MX53_USB_UH3_CTRL_OFFSET; + val = readl(reg) | MX53_BM_OVER_CUR_DIS_UHx; + break; + } + if (reg val) + writel(val, reg); + spin_unlock_irqrestore(usbmisc-lock, flags); + } + + return 0; +} + static int usbmisc_imx6q_init(struct device *dev) { @@ -74,12 +120,20 @@ static int usbmisc_imx6q_init(struct device *dev) return 0; } +static const struct usbmisc_ops imx53_usbmisc_ops = { + .init = usbmisc_imx53_init, +}; + static const struct usbmisc_ops imx6q_usbmisc_ops = { .init = usbmisc_imx6q_init, }; static const struct of_device_id usbmisc_imx_dt_ids[] = { { + .compatible = fsl,imx53-usbmisc, + .data = imx53_usbmisc_ops, + }, + { .compatible = fsl,imx6q-usbmisc, .data = imx6q_usbmisc_ops, }, -- 1.7.10.4 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 15/27] usb: chipidea: usbmisc: prepare driver to handle more than one soc
From: Marc Kleine-Budde m...@pengutronix.de This attaches the usbmisc_ops to the of_device_id data and makes it possible to define special functions per soc. Signed-off-by: Marc Kleine-Budde m...@pengutronix.de Signed-off-by: Michael Grzeschik m.grzesc...@pengutronix.de [Alex: fixed one case of line-too-long and one bogus cast to void ptr] Signed-off-by: Alexander Shishkin alexander.shish...@linux.intel.com --- drivers/usb/chipidea/usbmisc_imx.c | 18 +- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/drivers/usb/chipidea/usbmisc_imx.c b/drivers/usb/chipidea/usbmisc_imx.c index d77e712..08b046f 100644 --- a/drivers/usb/chipidea/usbmisc_imx.c +++ b/drivers/usb/chipidea/usbmisc_imx.c @@ -19,13 +19,14 @@ #define USB_DEV_MAX 4 -#define BM_OVER_CUR_DISBIT(7) +#define MX6_BM_OVER_CUR_DISBIT(7) struct imx_usbmisc { void __iomem *base; spinlock_t lock; struct clk *clk; struct usbmisc_usb_device usbdev[USB_DEV_MAX]; + const struct usbmisc_ops *ops; }; static struct imx_usbmisc *usbmisc; @@ -65,7 +66,7 @@ static int usbmisc_imx6q_init(struct device *dev) if (usbdev-disable_oc) { spin_lock_irqsave(usbmisc-lock, flags); reg = readl(usbmisc-base + usbdev-index * 4); - writel(reg | BM_OVER_CUR_DIS, + writel(reg | MX6_BM_OVER_CUR_DIS, usbmisc-base + usbdev-index * 4); spin_unlock_irqrestore(usbmisc-lock, flags); } @@ -78,7 +79,10 @@ static const struct usbmisc_ops imx6q_usbmisc_ops = { }; static const struct of_device_id usbmisc_imx_dt_ids[] = { - { .compatible = fsl,imx6q-usbmisc}, + { + .compatible = fsl,imx6q-usbmisc, + .data = imx6q_usbmisc_ops, + }, { /* sentinel */ } }; @@ -87,6 +91,7 @@ static int usbmisc_imx_probe(struct platform_device *pdev) struct resource *res; struct imx_usbmisc *data; int ret; + struct of_device_id *tmp_dev; if (usbmisc) return -EBUSY; @@ -116,8 +121,11 @@ static int usbmisc_imx_probe(struct platform_device *pdev) return ret; } + tmp_dev = (struct of_device_id *) + of_match_device(usbmisc_imx_dt_ids, pdev-dev); + data-ops = (const struct usbmisc_ops *)tmp_dev-data; usbmisc = data; - ret = usbmisc_set_ops(imx6q_usbmisc_ops); + ret = usbmisc_set_ops(data-ops); if (ret) { usbmisc = NULL; clk_disable_unprepare(data-clk); @@ -129,7 +137,7 @@ static int usbmisc_imx_probe(struct platform_device *pdev) static int usbmisc_imx_remove(struct platform_device *pdev) { - usbmisc_unset_ops(imx6q_usbmisc_ops); + usbmisc_unset_ops(usbmisc-ops); clk_disable_unprepare(usbmisc-clk); usbmisc = NULL; return 0; -- 1.7.10.4 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 18/27] usb: chipidea: make pci platform datas static
PCI chipideas' platform datas are not static as all such things should be. Fix it. Reported-by: Marc Kleine-Budde m...@pengutronix.de Signed-off-by: Alexander Shishkin alexander.shish...@linux.intel.com --- drivers/usb/chipidea/ci13xxx_pci.c |6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/usb/chipidea/ci13xxx_pci.c b/drivers/usb/chipidea/ci13xxx_pci.c index 9b227e3..4e1fc61 100644 --- a/drivers/usb/chipidea/ci13xxx_pci.c +++ b/drivers/usb/chipidea/ci13xxx_pci.c @@ -23,17 +23,17 @@ /** * PCI block */ -struct ci13xxx_platform_data pci_platdata = { +static struct ci13xxx_platform_data pci_platdata = { .name = UDC_DRIVER_NAME, .capoffset = DEF_CAPOFFSET, }; -struct ci13xxx_platform_data langwell_pci_platdata = { +static struct ci13xxx_platform_data langwell_pci_platdata = { .name = UDC_DRIVER_NAME, .capoffset = 0, }; -struct ci13xxx_platform_data penwell_pci_platdata = { +static struct ci13xxx_platform_data penwell_pci_platdata = { .name = UDC_DRIVER_NAME, .capoffset = 0, .power_budget = 200, -- 1.7.10.4 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 19/27] usb: chipidea: big-endian support
From: Svetoslav Neykov svetos...@neykov.name Convert between big-endian and little-endian format when accessing the usb controller structures which are little-endian by specification. Fix cases where the little-endian memory layout is taken for granted. The patch doesn't have any effect on the already supported little-endian architectures. Signed-off-by: Svetoslav Neykov svetos...@neykov.name [Alex: minor cosmetic fixes] Signed-off-by: Alexander Shishkin alexander.shish...@linux.intel.com --- drivers/usb/chipidea/core.c |2 +- drivers/usb/chipidea/udc.c | 62 +++ 2 files changed, 34 insertions(+), 30 deletions(-) diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c index 2824215..7418eae 100644 --- a/drivers/usb/chipidea/core.c +++ b/drivers/usb/chipidea/core.c @@ -180,7 +180,7 @@ static int hw_device_init(struct ci13xxx *ci, void __iomem *base) ci-hw_bank.cap = ci-hw_bank.abs; ci-hw_bank.cap += ci-platdata-capoffset; - ci-hw_bank.op = ci-hw_bank.cap + ioread8(ci-hw_bank.cap); + ci-hw_bank.op = ci-hw_bank.cap + (ioread32(ci-hw_bank.cap) 0xff); hw_alloc_regmap(ci, false); reg = hw_read(ci, CAP_HCCPARAMS, HCCPARAMS_LEN) diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c index 4a7b356..e25c3a2 100644 --- a/drivers/usb/chipidea/udc.c +++ b/drivers/usb/chipidea/udc.c @@ -417,10 +417,10 @@ static int _hardware_enqueue(struct ci13xxx_ep *mEp, struct ci13xxx_req *mReq) return -ENOMEM; memset(mReq-zptr, 0, sizeof(*mReq-zptr)); - mReq-zptr-next= TD_TERMINATE; - mReq-zptr-token = TD_STATUS_ACTIVE; + mReq-zptr-next= cpu_to_le32(TD_TERMINATE); + mReq-zptr-token = cpu_to_le32(TD_STATUS_ACTIVE); if (!mReq-req.no_interrupt) - mReq-zptr-token |= TD_IOC; + mReq-zptr-token |= cpu_to_le32(TD_IOC); } ret = usb_gadget_map_request(ci-gadget, mReq-req, mEp-dir); if (ret) @@ -431,32 +431,35 @@ static int _hardware_enqueue(struct ci13xxx_ep *mEp, struct ci13xxx_req *mReq) * TODO - handle requests which spawns into several TDs */ memset(mReq-ptr, 0, sizeof(*mReq-ptr)); - mReq-ptr-token= length __ffs(TD_TOTAL_BYTES); - mReq-ptr-token = TD_TOTAL_BYTES; - mReq-ptr-token |= TD_STATUS_ACTIVE; + mReq-ptr-token= cpu_to_le32(length __ffs(TD_TOTAL_BYTES)); + mReq-ptr-token = cpu_to_le32(TD_TOTAL_BYTES); + mReq-ptr-token |= cpu_to_le32(TD_STATUS_ACTIVE); if (mReq-zptr) { - mReq-ptr-next= mReq-zdma; + mReq-ptr-next= cpu_to_le32(mReq-zdma); } else { - mReq-ptr-next= TD_TERMINATE; + mReq-ptr-next= cpu_to_le32(TD_TERMINATE); if (!mReq-req.no_interrupt) - mReq-ptr-token |= TD_IOC; + mReq-ptr-token |= cpu_to_le32(TD_IOC); + } + mReq-ptr-page[0] = cpu_to_le32(mReq-req.dma); + for (i = 1; i 5; i++) { + u32 page = mReq-req.dma + i * CI13XXX_PAGE_SIZE; + page = ~TD_RESERVED_MASK; + mReq-ptr-page[i] = cpu_to_le32(page); } - mReq-ptr-page[0] = mReq-req.dma; - for (i = 1; i 5; i++) - mReq-ptr-page[i] = - (mReq-req.dma + i * CI13XXX_PAGE_SIZE) ~TD_RESERVED_MASK; if (!list_empty(mEp-qh.queue)) { struct ci13xxx_req *mReqPrev; int n = hw_ep_bit(mEp-num, mEp-dir); int tmp_stat; + u32 next = mReq-dma TD_ADDR_MASK; mReqPrev = list_entry(mEp-qh.queue.prev, struct ci13xxx_req, queue); if (mReqPrev-zptr) - mReqPrev-zptr-next = mReq-dma TD_ADDR_MASK; + mReqPrev-zptr-next = cpu_to_le32(next); else - mReqPrev-ptr-next = mReq-dma TD_ADDR_MASK; + mReqPrev-ptr-next = cpu_to_le32(next); wmb(); if (hw_read(ci, OP_ENDPTPRIME, BIT(n))) goto done; @@ -470,9 +473,9 @@ static int _hardware_enqueue(struct ci13xxx_ep *mEp, struct ci13xxx_req *mReq) } /* QH configuration */ - mEp-qh.ptr-td.next = mReq-dma;/* TERMINATE = 0 */ - mEp-qh.ptr-td.token = ~TD_STATUS; /* clear status */ - mEp-qh.ptr-cap |= QH_ZLT; + mEp-qh.ptr-td.next = cpu_to_le32(mReq-dma);/* TERMINATE = 0 */ + mEp-qh.ptr-td.token = cpu_to_le32(~TD_STATUS); /* clear status */ + mEp-qh.ptr-cap |= cpu_to_le32(QH_ZLT); wmb(); /* synchronize before ep prime */ @@ -494,11 +497,11 @@ static int _hardware_dequeue(struct ci13xxx_ep *mEp, struct ci13xxx_req *mReq)
[PATCH 20/27] usb: chipidea: udc: only clear active and halted bits in qhead
From: Michael Grzeschik m.grzesc...@pengutronix.de The datasheet of the synopsys core describes only to overwrite the active and halted bits in the qhead before priming any endpoint. Signed-off-by: Michael Grzeschik m.grzesc...@pengutronix.de Reviewed-by: Felipe Balbi ba...@ti.com [Alex: fixed a case of line-too-long] Signed-off-by: Alexander Shishkin alexander.shish...@linux.intel.com --- drivers/usb/chipidea/udc.c |3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c index e25c3a2..d734936 100644 --- a/drivers/usb/chipidea/udc.c +++ b/drivers/usb/chipidea/udc.c @@ -474,7 +474,8 @@ static int _hardware_enqueue(struct ci13xxx_ep *mEp, struct ci13xxx_req *mReq) /* QH configuration */ mEp-qh.ptr-td.next = cpu_to_le32(mReq-dma);/* TERMINATE = 0 */ - mEp-qh.ptr-td.token = cpu_to_le32(~TD_STATUS); /* clear status */ + mEp-qh.ptr-td.token = + cpu_to_le32(~(TD_STATUS_HALTED|TD_STATUS_ACTIVE)); mEp-qh.ptr-cap |= cpu_to_le32(QH_ZLT); wmb(); /* synchronize before ep prime */ -- 1.7.10.4 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 21/27] usb: chipidea: udc: rework ep_enable cap setting
From: Michael Grzeschik m.grzesc...@pengutronix.de This patch reworks the cap value from several read and write operations to one single operation. Signed-off-by: Michael Grzeschik m.grzesc...@pengutronix.de Reviewed-by: Felipe Balbi ba...@ti.com [Alex: removed useless isoc-related bit of code] Signed-off-by: Alexander Shishkin alexander.shish...@linux.intel.com --- drivers/usb/chipidea/udc.c | 14 +- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c index d734936..20ae435 100644 --- a/drivers/usb/chipidea/udc.c +++ b/drivers/usb/chipidea/udc.c @@ -1010,6 +1010,7 @@ static int ep_enable(struct usb_ep *ep, struct ci13xxx_ep *mEp = container_of(ep, struct ci13xxx_ep, ep); int retval = 0; unsigned long flags; + u32 cap = 0; if (ep == NULL || desc == NULL) return -EINVAL; @@ -1031,17 +1032,12 @@ static int ep_enable(struct usb_ep *ep, trace_ci_ep_enable(mEp, 0); - mEp-qh.ptr-cap = 0; - if (mEp-type == USB_ENDPOINT_XFER_CONTROL) - mEp-qh.ptr-cap |= cpu_to_le32(QH_IOS); - else if (mEp-type == USB_ENDPOINT_XFER_ISOC) - mEp-qh.ptr-cap = cpu_to_le32(~QH_MULT); - else - mEp-qh.ptr-cap = cpu_to_le32(~QH_ZLT); + cap |= QH_IOS; + cap |= (mEp-ep.maxpacket __ffs(QH_MAX_PKT)) QH_MAX_PKT; + + mEp-qh.ptr-cap = cpu_to_le32(cap); - mEp-qh.ptr-cap |= cpu_to_le32((mEp-ep.maxpacket __ffs(QH_MAX_PKT)) -QH_MAX_PKT); mEp-qh.ptr-td.next |= cpu_to_le32(TD_TERMINATE); /* needed? */ /* -- 1.7.10.4 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 22/27] usb: chipidea: udc: move ZLT flag change to ep_enable
From: Michael Grzeschik m.grzesc...@pengutronix.de Its not necessary and also not specified in the datasheet to change the ZLT flag before every ep_prime. This patch moves this to the ep_enable and applies it only for non configuration endpoints. Signed-off-by: Michael Grzeschik m.grzesc...@pengutronix.de Reviewed-by: Felipe Balbi ba...@ti.com Signed-off-by: Alexander Shishkin alexander.shish...@linux.intel.com --- drivers/usb/chipidea/udc.c |3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c index 20ae435..d5f0322 100644 --- a/drivers/usb/chipidea/udc.c +++ b/drivers/usb/chipidea/udc.c @@ -476,7 +476,6 @@ static int _hardware_enqueue(struct ci13xxx_ep *mEp, struct ci13xxx_req *mReq) mEp-qh.ptr-td.next = cpu_to_le32(mReq-dma);/* TERMINATE = 0 */ mEp-qh.ptr-td.token = cpu_to_le32(~(TD_STATUS_HALTED|TD_STATUS_ACTIVE)); - mEp-qh.ptr-cap |= cpu_to_le32(QH_ZLT); wmb(); /* synchronize before ep prime */ @@ -1034,6 +1033,8 @@ static int ep_enable(struct usb_ep *ep, if (mEp-type == USB_ENDPOINT_XFER_CONTROL) cap |= QH_IOS; + if (mEp-num) + cap |= QH_ZLT; cap |= (mEp-ep.maxpacket __ffs(QH_MAX_PKT)) QH_MAX_PKT; mEp-qh.ptr-cap = cpu_to_le32(cap); -- 1.7.10.4 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 24/27] usb: chipidea: udc: don't truncate requests to single tds
From: Michael Grzeschik m.grzesc...@pengutronix.de It is not safe to truncate requests to the maximum possible size the controller can handle with one td and to keep working. That patch fixes that with proper error handling instead. Reported-by: Felipe Balbi ba...@ti.com Signed-off-by: Michael Grzeschik m.grzesc...@pengutronix.de Signed-off-by: Alexander Shishkin alexander.shish...@linux.intel.com --- drivers/usb/chipidea/udc.c |4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c index a918edc..bb82fbc 100644 --- a/drivers/usb/chipidea/udc.c +++ b/drivers/usb/chipidea/udc.c @@ -1190,9 +1190,9 @@ static int ep_queue(struct usb_ep *ep, struct usb_request *req, } if (req-length 4 * CI13XXX_PAGE_SIZE) { - req-length = 4 * CI13XXX_PAGE_SIZE; retval = -EMSGSIZE; - dev_warn(mEp-ci-dev, request length truncated\n); + dev_err(mEp-ci-dev, request bigger than one td\n); + goto done; } trace_ci_ep_queue_req(mEp, retval); -- 1.7.10.4 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 23/27] usb: chipidea: udc: read status of td only once in hardware_dequeue
From: Michael Grzeschik m.grzesc...@pengutronix.de This patch changes the read of the td status to one atomic operation to analyse coherent bits. Signed-off-by: Michael Grzeschik m.grzesc...@pengutronix.de [Alex: fixed backwards endianness conversion] Signed-off-by: Alexander Shishkin alexander.shish...@linux.intel.com --- drivers/usb/chipidea/udc.c |8 +--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c index d5f0322..a918edc 100644 --- a/drivers/usb/chipidea/udc.c +++ b/drivers/usb/chipidea/udc.c @@ -494,10 +494,12 @@ done: */ static int _hardware_dequeue(struct ci13xxx_ep *mEp, struct ci13xxx_req *mReq) { + u32 tmptoken = le32_to_cpu(mReq-ptr-token); + if (mReq-req.status != -EALREADY) return -EINVAL; - if ((cpu_to_le32(TD_STATUS_ACTIVE) mReq-ptr-token) != 0) + if ((TD_STATUS_ACTIVE tmptoken) != 0) return -EBUSY; if (mReq-zptr) { @@ -511,7 +513,7 @@ static int _hardware_dequeue(struct ci13xxx_ep *mEp, struct ci13xxx_req *mReq) usb_gadget_unmap_request(mEp-ci-gadget, mReq-req, mEp-dir); - mReq-req.status = le32_to_cpu(mReq-ptr-token) TD_STATUS; + mReq-req.status = tmptoken TD_STATUS; if ((TD_STATUS_HALTED mReq-req.status) != 0) mReq-req.status = -1; else if ((TD_STATUS_DT_ERR mReq-req.status) != 0) @@ -519,7 +521,7 @@ static int _hardware_dequeue(struct ci13xxx_ep *mEp, struct ci13xxx_req *mReq) else if ((TD_STATUS_TR_ERR mReq-req.status) != 0) mReq-req.status = -1; - mReq-req.actual = le32_to_cpu(mReq-ptr-token) TD_TOTAL_BYTES; + mReq-req.actual = tmptoken TD_TOTAL_BYTES; mReq-req.actual = __ffs(TD_TOTAL_BYTES); mReq-req.actual = mReq-req.length - mReq-req.actual; mReq-req.actual = mReq-req.status ? 0 : mReq-req.actual; -- 1.7.10.4 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 25/27] usb: chipidea: udc: move _ep_queue into an unlocked function
From: Michael Grzeschik m.grzesc...@pengutronix.de There is no need to call ep_queue unlocked inside the own driver. We move its functionionality into an unlocked version. This patch removes potential unlocked timeslots inside isr_setup_status_phase and isr_get_status_response, in which the lock got released just before acquired again inside usb_ep_queue. Signed-off-by: Michael Grzeschik m.grzesc...@pengutronix.de Signed-off-by: Marc Kleine-Budde m...@pengutronix.de Reviewed-by: Peter Chen peter.c...@freescale.com Signed-off-by: Alexander Shishkin alexander.shish...@linux.intel.com --- drivers/usb/chipidea/udc.c | 110 1 file changed, 60 insertions(+), 50 deletions(-) diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c index bb82fbc..0795bca 100644 --- a/drivers/usb/chipidea/udc.c +++ b/drivers/usb/chipidea/udc.c @@ -658,6 +658,63 @@ static void isr_get_status_complete(struct usb_ep *ep, struct usb_request *req) } /** + * _ep_queue: queues (submits) an I/O request to an endpoint + * + * Caller must hold lock + */ +static int _ep_queue(struct usb_ep *ep, struct usb_request *req, + gfp_t __maybe_unused gfp_flags) +{ + struct ci13xxx_ep *mEp = container_of(ep, struct ci13xxx_ep, ep); + struct ci13xxx_req *mReq = container_of(req, struct ci13xxx_req, req); + struct ci13xxx *ci = mEp-ci; + int retval = 0; + + if (ep == NULL || req == NULL || mEp-ep.desc == NULL) + return -EINVAL; + + if (mEp-type == USB_ENDPOINT_XFER_CONTROL) { + if (req-length) + mEp = (ci-ep0_dir == RX) ? + ci-ep0out : ci-ep0in; + if (!list_empty(mEp-qh.queue)) { + _ep_nuke(mEp); + retval = -EOVERFLOW; + dev_warn(mEp-ci-dev, endpoint ctrl %X nuked\n, +ci_ep_addr(mEp)); + } + } + + /* first nuke then test link, e.g. previous status has not sent */ + if (!list_empty(mReq-queue)) { + dev_err(mEp-ci-dev, request already in queue\n); + return -EBUSY; + } + + if (req-length 4 * CI13XXX_PAGE_SIZE) { + dev_err(mEp-ci-dev, request bigger than one td\n); + return -EMSGSIZE; + } + + trace_ci_ep_queue_req(mEp, retval); + + /* push request */ + mReq-req.status = -EINPROGRESS; + mReq-req.actual = 0; + + retval = _hardware_enqueue(mEp, mReq); + + if (retval == -EALREADY) { + trace_ci_ep_queue_req(mEp, retval); + retval = 0; + } + if (!retval) + list_add_tail(mReq-queue, mEp-qh.queue); + + return retval; +} + +/** * isr_get_status_response: get_status request response * @ci: ci struct * @setup: setup request packet @@ -704,9 +761,7 @@ __acquires(mEp-lock) } /* else do nothing; reserved for future use */ - spin_unlock(mEp-lock); - retval = usb_ep_queue(mEp-ep, req, gfp_flags); - spin_lock(mEp-lock); + retval = _ep_queue(mEp-ep, req, gfp_flags); if (retval) goto err_free_buf; @@ -753,8 +808,6 @@ isr_setup_status_complete(struct usb_ep *ep, struct usb_request *req) * This function returns an error code */ static int isr_setup_status_phase(struct ci13xxx *ci) -__releases(mEp-lock) -__acquires(mEp-lock) { int retval; struct ci13xxx_ep *mEp; @@ -763,9 +816,7 @@ __acquires(mEp-lock) ci-status-context = ci; ci-status-complete = isr_setup_status_complete; - spin_unlock(mEp-lock); - retval = usb_ep_queue(mEp-ep, ci-status, GFP_ATOMIC); - spin_lock(mEp-lock); + retval = _ep_queue(mEp-ep, ci-status, GFP_ATOMIC); return retval; } @@ -1160,8 +1211,6 @@ static int ep_queue(struct usb_ep *ep, struct usb_request *req, gfp_t __maybe_unused gfp_flags) { struct ci13xxx_ep *mEp = container_of(ep, struct ci13xxx_ep, ep); - struct ci13xxx_req *mReq = container_of(req, struct ci13xxx_req, req); - struct ci13xxx *ci = mEp-ci; int retval = 0; unsigned long flags; @@ -1170,47 +1219,8 @@ static int ep_queue(struct usb_ep *ep, struct usb_request *req, spin_lock_irqsave(mEp-lock, flags); - if (mEp-type == USB_ENDPOINT_XFER_CONTROL) { - if (req-length) - mEp = (ci-ep0_dir == RX) ? - ci-ep0out : ci-ep0in; - if (!list_empty(mEp-qh.queue)) { - _ep_nuke(mEp); - retval = -EOVERFLOW; - dev_warn(mEp-ci-dev, endpoint ctrl %X nuked\n, -ci_ep_addr(mEp)); - } - } - - /* first nuke then test link, e.g. previous status has not sent */ - if
[PATCH 26/27] usb: chipidea: udc: add the define TD_PAGE_COUNT and fix all users
From: Michael Grzeschik m.grzesc...@pengutronix.de A static count of transfer descriptors was used everywhere in the driver with the fixed number 5. This patch adds a define, named TD_PAGE_COUNT, and replaces all users of this value. This way its possible to have only one parameter to change and limit the amount of buffer pointers per TD. Signed-off-by: Michael Grzeschik m.grzesc...@pengutronix.de Reviewed-by: Peter Chen peter.c...@freescale.com Signed-off-by: Alexander Shishkin alexander.shish...@linux.intel.com --- drivers/usb/chipidea/ci.h |1 + drivers/usb/chipidea/udc.c |4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/usb/chipidea/ci.h b/drivers/usb/chipidea/ci.h index 7dcd390..4ca3373 100644 --- a/drivers/usb/chipidea/ci.h +++ b/drivers/usb/chipidea/ci.h @@ -21,6 +21,7 @@ /** * DEFINE */ +#define TD_PAGE_COUNT 5 #define CI13XXX_PAGE_SIZE 4096ul /* page size for TD's */ #define ENDPT_MAX 32 #define RX0 /* similar to USB_DIR_OUT but can be used as an index */ diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c index 0795bca..f203ecb 100644 --- a/drivers/usb/chipidea/udc.c +++ b/drivers/usb/chipidea/udc.c @@ -442,7 +442,7 @@ static int _hardware_enqueue(struct ci13xxx_ep *mEp, struct ci13xxx_req *mReq) mReq-ptr-token |= cpu_to_le32(TD_IOC); } mReq-ptr-page[0] = cpu_to_le32(mReq-req.dma); - for (i = 1; i 5; i++) { + for (i = 1; i TD_PAGE_COUNT; i++) { u32 page = mReq-req.dma + i * CI13XXX_PAGE_SIZE; page = ~TD_RESERVED_MASK; mReq-ptr-page[i] = cpu_to_le32(page); @@ -691,7 +691,7 @@ static int _ep_queue(struct usb_ep *ep, struct usb_request *req, return -EBUSY; } - if (req-length 4 * CI13XXX_PAGE_SIZE) { + if (req-length (TD_PAGE_COUNT - 1) * CI13XXX_PAGE_SIZE) { dev_err(mEp-ci-dev, request bigger than one td\n); return -EMSGSIZE; } -- 1.7.10.4 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 27/27] Revert USB: chipidea: add vbus detect for udc
From: Peter Chen peter.c...@freescale.com There are several problems with this patch: + in introduces a sparse warning for a condition that's always negative, + and because of that, it actually doesn't do anything useful, + and vbus detection belongs to otg, not device function anyway. This reverts commit 8c4fc031954b4eb72daf13d3c907a985a3eee208. Signed-off-by: Peter Chen peter.c...@freescale.com [Alex: amended the above text] Signed-off-by: Alexander Shishkin alexander.shish...@linux.intel.com --- drivers/usb/chipidea/ci.h |1 - drivers/usb/chipidea/udc.c | 39 +-- 2 files changed, 1 insertion(+), 39 deletions(-) diff --git a/drivers/usb/chipidea/ci.h b/drivers/usb/chipidea/ci.h index 4ca3373..f8ed2e2 100644 --- a/drivers/usb/chipidea/ci.h +++ b/drivers/usb/chipidea/ci.h @@ -152,7 +152,6 @@ struct ci13xxx { enum ci_rolerole; boolis_otg; struct work_struct work; - struct work_struct vbus_work; struct workqueue_struct *wq; struct dma_pool *qh_pool; diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c index f203ecb..36dd16e 100644 --- a/drivers/usb/chipidea/udc.c +++ b/drivers/usb/chipidea/udc.c @@ -299,18 +299,6 @@ static u32 hw_test_and_clear_intr_active(struct ci13xxx *ci) return reg; } -static void hw_enable_vbus_intr(struct ci13xxx *ci) -{ - hw_write(ci, OP_OTGSC, OTGSC_AVVIS, OTGSC_AVVIS); - hw_write(ci, OP_OTGSC, OTGSC_AVVIE, OTGSC_AVVIE); - queue_work(ci-wq, ci-vbus_work); -} - -static void hw_disable_vbus_intr(struct ci13xxx *ci) -{ - hw_write(ci, OP_OTGSC, OTGSC_AVVIE, 0); -} - /** * hw_test_and_clear_setup_guard: test clear setup guard (execute without *interruption) @@ -377,16 +365,6 @@ static int hw_usb_reset(struct ci13xxx *ci) return 0; } -static void vbus_work(struct work_struct *work) -{ - struct ci13xxx *ci = container_of(work, struct ci13xxx, vbus_work); - - if (hw_read(ci, OP_OTGSC, OTGSC_AVV)) - usb_gadget_vbus_connect(ci-gadget); - else - usb_gadget_vbus_disconnect(ci-gadget); -} - /** * UTIL block */ @@ -1390,7 +1368,6 @@ static int ci13xxx_vbus_session(struct usb_gadget *_gadget, int is_active) if (is_active) { pm_runtime_get_sync(_gadget-dev); hw_device_reset(ci, USBMODE_CM_DC); - hw_enable_vbus_intr(ci); hw_device_state(ci, ci-ep0out-qh.dma); } else { hw_device_state(ci, 0); @@ -1565,10 +1542,8 @@ static int ci13xxx_start(struct usb_gadget *gadget, pm_runtime_get_sync(ci-gadget.dev); if (ci-platdata-flags CI13XXX_PULLUP_ON_VBUS) { if (ci-vbus_active) { - if (ci-platdata-flags CI13XXX_REGS_SHARED) { + if (ci-platdata-flags CI13XXX_REGS_SHARED) hw_device_reset(ci, USBMODE_CM_DC); - hw_enable_vbus_intr(ci); - } } else { pm_runtime_put_sync(ci-gadget.dev); goto done; @@ -1679,13 +1654,6 @@ static irqreturn_t udc_irq(struct ci13xxx *ci) } else { retval = IRQ_NONE; } - - intr = hw_read(ci, OP_OTGSC, ~0); - hw_write(ci, OP_OTGSC, ~0, intr); - - if (intr (OTGSC_AVVIE OTGSC_AVVIS)) - queue_work(ci-wq, ci-vbus_work); - spin_unlock(ci-lock); return retval; @@ -1761,7 +1729,6 @@ static int udc_start(struct ci13xxx *ci) retval = hw_device_reset(ci, USBMODE_CM_DC); if (retval) goto put_transceiver; - hw_enable_vbus_intr(ci); } retval = device_register(ci-gadget.dev); @@ -1818,9 +1785,6 @@ static void udc_stop(struct ci13xxx *ci) if (ci == NULL) return; - hw_disable_vbus_intr(ci); - cancel_work_sync(ci-vbus_work); - usb_del_gadget_udc(ci-gadget); destroy_eps(ci); @@ -1860,7 +1824,6 @@ int ci_hdrc_gadget_init(struct ci13xxx *ci) rdrv-irq = udc_irq; rdrv-name = gadget; ci-roles[CI_ROLE_GADGET] = rdrv; - INIT_WORK(ci-vbus_work, vbus_work); return 0; } -- 1.7.10.4 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] staging: dwc2: fix potential null pointer access
We were testing hsotg pointer for null after we had already dereferenced it Reported-by: Fengguang Wu fengguang...@intel.com Signed-off-by: Paul Zimmerman pa...@synopsys.com --- drivers/staging/dwc2/hcd_ddma.c | 10 +- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/staging/dwc2/hcd_ddma.c b/drivers/staging/dwc2/hcd_ddma.c index ab88f50..d2180b2 100644 --- a/drivers/staging/dwc2/hcd_ddma.c +++ b/drivers/staging/dwc2/hcd_ddma.c @@ -217,18 +217,18 @@ static void dwc2_update_frame_list(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh, struct dwc2_host_chan *chan; u16 i, j, inc; - if (!qh-channel) { - dev_err(hsotg-dev, qh-channel = %p, qh-channel); + if (!hsotg) { + pr_err(hsotg = %p, hsotg); return; } - if (!hsotg) { - dev_err(hsotg-dev, --hsotg = %p, hsotg); + if (!qh-channel) { + dev_err(hsotg-dev, qh-channel = %p, qh-channel); return; } if (!hsotg-frame_list) { - dev_err(hsotg-dev, ---hsotg-frame_list = %p, + dev_err(hsotg-dev, hsotg-frame_list = %p, hsotg-frame_list); return; } -- 1.8.2.rc0.16.g20a599e -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v3 4/7] USB: EHCI: export ehci_shutdown
On Fri, 29 Mar 2013, Geoff Levand wrote: Hi Alan, Actually, I think this is not necessary. Instead those three glue files ought to be changed. They should not need to call ehci_shutdown() directly. I sent out a separate patch that removes the ehci_shutdown() call in ps3_ehci_remove(). I tested it by removing and installing the ehci_hcd module and it seems to work OK. Thanks! I'll send it on up. Alan Stern -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
cdc_acm device - unexpected characters sent to USB device
I'm having trouble with unexpected characters being sent on a USB port with the cdc_acm driver. What makes this all the more perplexing is that the code runs fine on Ubuntu 12.04 (3.2 kernel) but fails (the subject of this question) on Centos 6 (3.6 kernel) The USB device is a Bluegiga BLED112 Bluetooth Smart dongle. Its embedded microcontroller has the (unfortunate) behavior that it will reset any time there in unexpected input on it's USB interface. The test code opens the port, writes 4 bytes (a hello message) and expects to read a response. The read never completes because the unexpected characters cause the device to reset which causes the hub to drop the device and re-enumerate. To troubleshoot, here's what I've done: - Downloaded the source code for the cdc_acm driver. - Added a bunch of printk debug messages and stack_dumps to follow what's going on. - I rmmod'd the stock cdc_acm and insmod'd my instrumented module. - All the device enumeration works, right driver attached, etc. - Since the code works on Ubuntu 12.04/Linux 3.2, I grabbed the 3.2 cdc_acm code and compiled that module on the Centos 6 / Linux 3.6 platform. Using that 3.2 module instead of the 3.6 module did not make a difference. I reverted to the 3.6 module. - Turned on the debug file system with usbmon and watched the USB traffic. I can see that there are extra characters being sent on the USB interface. - To watch what's going on, on top of the printk's in the cdc_acm module, I've merged the output of usb mon (cat /sys/kernel/debug/usb/usbmon/3u | logger) and the output of the test application (scan_example /dev/ttyACM0 | logger -s) so I have a single stream of time correlated debug trail. - The spurious characters sent on the USB endpoint are x5E x40 x5E x40 x5E x40 x5E x40 x41 (in ASCII its ^@^@^@^@A ) which looks like some sort of probing or trying to get the attention of a modem These characters are sent immediately after the application's write() causes the 4 hello bytes to be sent to the end point. Since the cdc_acm device is supposed to be a modem, I tried to turn off the modem control by adding this to usb_device_id acm_ids[] in cdc_acm.c /* bluegiga BLED112*/ { USB_DEVICE(0x2458, 0x0001), .driver_info = NOT_A_MODEM, }, Recompiled and insmod'd and the syslog show that this was recognized (quirks is 8), but no change in function. Neither NetowrkManager nor modem-manager are running, but I still suspect that there is some sort of modem control function going on somewhere, I just don't know where. Here's a annotated debug log (MDV prefixes those printk's that I added to cdc_acm) Feb 13 18:14:32 localhost kernel: MDV:cdc-acm acm_write_bulk Feb 13 18:14:32 localhost kernel: MDV:cdc-acm acm_write_done Here are the 4 bytes sent by the application 00 00 00 01 Feb 13 18:14:32 localhost cpcenter: df046a80 3672670191 C Bi:3:006:4 0 4 = 0001 Feb 13 18:14:32 localhost cpcenter: 1360797272.669690 write: data2: len=0 contains: ... and these additonal characters show up unexpectedly 5e 40 5e 40 5e 40 Feb 13 18:14:32 localhost cpcenter: df046a80 3672670232 S Bi:3:006:4 -115 128 Feb 13 18:14:32 localhost cpcenter: f3cc5740 3672670297 S Bo:3:006:4 -115 1 = 5e Feb 13 18:14:32 localhost cpcenter: df2e1300 3672670332 S Bo:3:006:4 -115 1 = 40 Feb 13 18:14:32 localhost cpcenter: f3cc5740 3672670347 C Bo:3:006:4 0 1 Feb 13 18:14:32 localhost cpcenter: f3cc5740 3672670392 S Bo:3:006:4 -115 1 = 5e Feb 13 18:14:32 localhost cpcenter: df2e1180 3672670426 S Bo:3:006:4 -115 1 = 40 Feb 13 18:14:32 localhost cpcenter: df2e1c00 3672670461 S Bo:3:006:4 -115 1 = 5e Feb 13 18:14:32 localhost cpcenter: df2e1840 3672670496 S Bo:3:006:4 -115 1 = 40 Feb 13 18:14:32 localhost cpcenter: df2e1300 3672670591 C Bo:3:006:4 0 1 At this point we get a spontaneous disconnect. Feb 13 18:14:32 localhost kernel: usb 3-1: USB disconnect, device number 6 Feb 13 18:14:32 localhost kernel: MDV:cdc-acm acm_write_bulk Feb 13 18:14:32 localhost kernel: MDV:cdc-acm acm_write_done Feb 13 18:14:32 localhost kernel: MDV:cdc-acm read_bulk_callback Feb 13 18:14:32 localhost kernel: MDV 1 acm_read_bulk_callback - urb 1, len 0 Feb 13 18:14:32 localhost kernel: MDV 3 acm_read_bulk_callback - non-zero urb status: -71 Feb 13 18:14:32 localhost kernel: MDV:cdc-acm acm_write_bulk Feb 13 18:14:32 localhost kernel: MDV:cdc-acm acm_write_done Feb 13 18:14:32 localhost kernel: MDV:cdc-acm read_bulk_callback Feb 13 18:14:32 localhost kernel: MDV 1 acm_read_bulk_callback - urb 1, len 0 Feb 13 18:14:32 localhost kernel: MDV 3 acm_read_bulk_callback - non-zero urb status: -71 Feb 13 18:14:32 localhost kernel: MDV:cdc-acm acm_write_bulk Feb 13 18:14:32 localhost kernel: MDV:cdc-acm acm_write_done Feb 13 18:14:32 localhost kernel: MDV:cdc-acm read_bulk_callback Feb 13 18:14:32 localhost kernel: MDV 1 acm_read_bulk_callback - urb 2, len 0 Feb 13 18:14:32 localhost cpcenter: df2e1d80 3672670629 S Bo:3:006:4 -115
Re: [PATCH 04/27] usb: chipidea: convert events to tracepoints
On Sat, Mar 30, 2013 at 02:46:20AM +0200, Alexander Shishkin wrote: As part of the legacy from the original driver design, we retain home-grown tracing infrastructure, complete with own ring buffer and timestamps. While it is useful for debugging certain cases, it's a lot of extra code, which these days is rather redundant. This patch replaces local tracing functionality with kernel tracepoints, thus getting rid of the ring buffer and all the maintenance code, while making use of standard kernel infrastructure. What do these tracepoints do? Why do you still need them at all? Once you make a tracepoint, you are saying you are going to keep that api for forever, are you really willing to do that? I'm not, which is why you don't see any USB tracepoints yet, and I really don't think that a single driver needs them either. So I need a whole lot of convincing before I can take a patch like this, sorry. I took the first 3 patches here, but odds are, if I can't take this one, the rest will not apply, right? thanks, greg k-h -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 05/27] usb: chipidea: replace interrupt accounting with tracepoints
On Sat, Mar 30, 2013 at 02:46:21AM +0200, Alexander Shishkin wrote: The driver also has interrupt counters and another ring buffer for keeping track of the order in which they arrive. This patch converts these counters to trace points. Userspace tools such as perf can provide information on both order and stats of the interrupts. Why would perf care about a single driver? Why would a user? Why are these needed at all for anyone except the driver developer? greg k-h -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: Help with xHCI, uvcvideo driver, and Unknown event condition, HC probably busted
Hi Ezequiel, Thanks so much for replying, I worried my call for help would just become more buried. On Fri, Mar 29, 2013 at 3:34 PM, Ezequiel Garcia ezequiel.gar...@free-electrons.com wrote: Hi Ryan, Small world, uh? On Tue, Mar 26, 2013 at 02:55:48PM -0700, Ryan Press wrote: I'm working to get the 3.9-rc1 kernel working on the Globalscale Mirabox http://www.globalscaletechnologies.com/p-58-mirabox-development-kit.aspx. The PCIe driver by Thomas Petazzoni is not in mainline yet but I have his latest patch; this is required for the FL1009 host controller. I have everything mostly working. A USB 3.0 SSD works great, I tested un-buffered speed at 120 MB/s. I am trying to get a USB 2.0 video capture device working and I'm running into problems. So far I have tested using the uvcvideo and stk1160. They both fail with xhci_hcd :02:00.0: ERROR Unknown event condition, HC probably busted, although the uvcvideo device does work for perhaps a minute with smooth video. Sometimes it resets the host controller and the attached SSD goes offline. On a different ARM box running 3.8-rc1 kernel the stk1160 is known working, albeit it has only a USB 2.0 host controller. So I don't suspect this driver necessarily. Below is my dmesg log. I would think the PCIe driver could be the problem but because the USB 3.0 SSD works perfectly I'm not sure this is the case. Does anyone have insight into what's going on? As the stk1160 author, I'm glad to see someone is using it ;-) Wow, I didn't realize you wrote that as well. Thanks! This is really the driver I want to use. FWIW, stk1160 (as any other video device) uses isochronous URBs while your SSD (any other storage) *probably* uses bulk URBs. I'm not sure if this has anything to do with your problem, but at least it means you shouldn't compare those devices as similar. Yeah, I know; many years ago I wrote a WDM USB video driver, but now I'm more a hardware guy. I was just thinking that if it was some underlying problem with the PCIe, I would also see it with the SSD. But I'm sure there's more than meets my eye. I'll see what I can do about it and let you know. Great! This is really the last big problem I'm having and it would be fantastic to resolve it. Thanks, Ryan -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 09/27] usb: chipidea: fix precedence bug in ci_requests_show()
On Sat, Mar 30, 2013 at 02:46:25AM +0200, Alexander Shishkin wrote: From: Dan Carpenter dan.carpen...@oracle.com The intent here was to have parenthesis around the (ci-hw_ep_max / 2) so that it counts like 0 1 2 0 1 2. In the current code, the mod operation happens first so it counts like 0 0 1 1 2 2. Signed-off-by: Dan Carpenter dan.carpen...@oracle.com [rebased on top of debug.c changes] Can you rebase this not on top of those changes, so I can take this now? thanks, greg k-h -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 10/27] usb: chipidea: don't redefine __ffs()
On Sat, Mar 30, 2013 at 02:46:26AM +0200, Alexander Shishkin wrote: From: Felipe Balbi ba...@ti.com chipidea's ffs_nr() is pretty much what __ffs() does. Use that one instead. Signed-off-by: Felipe Balbi ba...@ti.com [rebased on top of debug infrastructure rework] Again, can you rebase this so I can take this now? thanks, greg k-h -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 12/27] usb: chipidea: usbmisc: rename file, struct and functions to usbmisc_imx
On Sat, Mar 30, 2013 at 02:46:28AM +0200, Alexander Shishkin wrote: From: Michael Grzeschik m.grzesc...@pengutronix.de This driver will be used for every Freescale SoC which has this misc memory layout to control the basic usb handling. So better name this driver, function and struct names in a more generic way. Reported-by: Fabio Estevam feste...@gmail.com Signed-off-by: Michael Grzeschik m.grzesc...@pengutronix.de Signed-off-by: Marc Kleine-Budde m...@pengutronix.de Signed-off-by: Alexander Shishkin alexander.shish...@linux.intel.com Conflicts: drivers/usb/chipidea/usbmisc_imx.c What does this mean? Why are these two lines in the changelog area? Hint, be more careful when using git rebase, and double check what you send me, before you send it. I'm stopping here, please redo this series as mentioned. greg k-h -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 00/27] usb: chipidea: updates for v3.10
On Sat, Mar 30, 2013 at 02:46:16AM +0200, Alexander Shishkin wrote: Hi Greg, This is an update for chipidea usb controller driver for usb-next. Some of these patches, though mostly mine, date as far back as november 2012. Why would you hold onto patches for that long? That's not ok for a maintainer to do, please be more responsive. greg k-h -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html