前文详情见
【Linux】在Xilinx平台上实现UVC Gadget(1)
在usb插入电脑时,开发板会瞬间报错,报错信息如下。
经过仔细研究,dwc3驱动drivers/usb/dwc3/gadget.c存在一个bug
在usb gadget 枚举过程中,会触发不需要的假中断,为了避免这个问题,
需要清除DWC3_DCTL_KEEP_CONNECT位,禁用DWC3_GCTL_GBLHIBERNATIONEN休眠中断
[ 111.954284] ------------[ cut here ]------------
[ 111.958916] WARNING: CPU: 0 PID: 1095 at drivers/usb/dwc3/gadget.c:3305 dwc3_stop_active_transfer.part.0+0xc4/0xd0
[ 111.969247] Modules linked in: vivid v4l2_tpg cec g_webcam g_ffs zocl(O) dmaproxy(O) al5e(O) al5d(O) allegro(O) mali(O) xlnx_vcu regmap_mmio uio_pdrv_genirq [last unloaded: zocl]
[ 111.985179] CPU: 0 PID: 1095 Comm: irq/92-dwc3 Tainted: G O 5.10.0-xilinx-v2021.1 #1
[ 111.994210] Hardware name: ZynqMP ZCU104 RevC (DT)
[ 111.998987] pstate: 60000085 (nZCv daIf -PAN -UAO -TCO BTYPE=--)
[ 112.004985] pc : dwc3_stop_active_transfer.part.0+0xc4/0xd0
[ 112.010549] lr : dwc3_stop_active_transfer.part.0+0x60/0xd0
[ 112.016110] sp : ffff80001239bc10
[ 112.019409] x29: ffff80001239bc10 x28: 0000000000000000
[ 112.024712] x27: ffff000002249380 x26: ffff00000224e880
[ 112.030015] x25: ffff800011140568 x24: ffff000004934300
[ 112.035319] x23: ffffffffffff3f00 x22: 0000000000000001
[ 112.040622] x21: 0000000000000000 x20: ffff000004934300
[ 112.045926] x19: ffff000002249000 x18: fffffdfffff27a08
[ 112.051229] x17: 0000000000000000 x16: 000000000000000e
[ 112.056532] x15: 0000000000000000 x14: 000006160d349044
[ 112.061836] x13: 00000000bd08a39e x12: 00000000000002d2
[ 112.067139] x11: 0000000000000000 x10: 00000000000008e0
[ 112.072443] x9 : ffff80001239bd10 x8 : ffff000004934c40
[ 112.077747] x7 : 000000000000b68d x6 : 0000000000000000
[ 112.083050] x5 : 0000000000000508 x4 : 0000000000000000
[ 112.088353] x3 : ffffffffffff3f08 x2 : 0000000000000000
[ 112.093657] x1 : ffff800012f00200 x0 : 00000000ffffff92
[ 112.098961] Call trace:
[ 112.101395] dwc3_stop_active_transfer.part.0+0xc4/0xd0
[ 112.106611] dwc3_stop_active_transfer+0x2c/0x40
[ 112.111219] dwc3_gadget_enter_hibernation.part.0+0xc0/0x2e0
[ 112.116860] dwc3_gadget_enter_hibernation+0x2c/0x40
[ 112.121809] dwc3_thread_interrupt+0x2f0/0xe5c
[ 112.126246] irq_thread_fn+0x2c/0x90
[ 112.129811] irq_thread+0x248/0x370
[ 112.133285] kthread+0x124/0x130
[ 112.136505] ret_from_fork+0x10/0x3c
[ 112.140069] ---[ end trace 5d566d21e39ee647 ]---
[ 112.253848] dwc3-xilinx ff9d0000.usb0: Failed to set power state to D3
[ 112.260367] dwc3-pmu-regulator: failed to disable: -EIO
[ 112.265585] dwc3 fe200000.dwc3: dwc3_gadget_enter_hibernation: 373 Failed to enable dwc3_pmu supply
[ 112.274619] dwc3 fe200000.dwc3: Fail in handling Hibernation Interrupt
find . -name "gadget.c"
可以看到第1行是我们要的源代码,但是不能直接修改这个文件,因为Petalinux会自动恢复
LeoWang@u16:/opt/work/uvc-demo/xilinx-zcu104-2021.1$ find . -name "gadget.c"
./build/tmp/work-shared/zynqmp-generic/kernel-source/drivers/usb/dwc3/gadget.c
./build/tmp/work-shared/zynqmp-generic/kernel-source/drivers/usb/cdns3/gadget.c
./build/tmp/work-shared/zynqmp-generic/kernel-source/drivers/usb/dwc2/gadget.c
./build/tmp/work/zynqmp_generic-xilinx-linux/u-boot-xlnx/v2021.01-xilinx-v2021.1+gitAUTOINC+41fc08b3fe-r0/git/board/samsung/common/gadget.c
./build/tmp/work/zynqmp_generic-xilinx-linux/u-boot-xlnx/v2021.01-xilinx-v2021.1+gitAUTOINC+41fc08b3fe-r0/git/drivers/usb/dwc3/gadget.c
./build/tmp/work/zynqmp_generic-xilinx-linux/u-boot-xlnx/v2021.01-xilinx-v2021.1+gitAUTOINC+41fc08b3fe-r0/git/drivers/usb/cdns3/gadget.c
把./build/tmp/work-shared/zynqmp-generic/kernel-source复制到其他文件夹
比如我的工程目录是
/opt/work/uvc-demo/xilinx-zcu104-2021.1
内核源码目录是
/opt/work/uvc-demo/xilinx-zcu104-2021.1/build/tmp/work-shared/zynqmp-generic/kernel-source
最后把内核复制并改名到这个目录
/opt/work/uvc-demo/kernel-source_leo_wang5.10
petalinux-config
回车输入自己内核源码的目录
打开文件drivers/usb/dwc3/gadget.c,找到函数
static void dwc3_gadget_reset_interrupt(struct dwc3 *dwc)
在if (DWC3_VER_IS_PRIOR(DWC3, 188A)) 和dwc3_reset_gadget(dwc)之间加上下面这一段
//add by LeoWang 2022.11.20
if (dwc->has_hibernation) {
reg = dwc3_readl(dwc->regs, DWC3_DCTL);
reg &= ~DWC3_DCTL_KEEP_CONNECT;
dwc3_writel(dwc->regs, DWC3_DCTL, reg);
reg = dwc3_readl(dwc->regs, DWC3_GCTL);
reg &= ~DWC3_GCTL_GBLHIBERNATIONEN;
dwc3_writel(dwc->regs, DWC3_GCTL, reg);
}
修改后的效果如下图
Ps:
确认在v2021.2还存在这个bug,在2022.1已经增加了这个修复
也就是版本<=2021.2的,必须手动修改