RG280M
解決"Kernel panic jz_musb_interrupt"問題
問題如下:
CPU 0 Unable to handle kernel paging request at virtual address 0000002c, epc == 80299dc8, ra == 80299dc0 Oops[#1]: CPU: 0 PID: 0 Comm: swapper Not tainted 3.12.1-lrgo #40 task: 8051dd50 ti: 80514000 task.ti: 80514000 $ 0 : 00000000 10000c00 00000000 00000087 $ 4 : 8c7b2010 00000001 8c08cf10 00200000 $ 8 : b0001008 2326dfcb 000000ad 00000000 $12 : 00000000 00000000 00000007 8046c468 $16 : 00000009 00000091 8c7b2010 00000000 $20 : 00000091 8c08ce90 00000001 8c7ca300 $24 : 00000067 80018054 $28 : 80514000 80515ce8 80540000 80299dc0 Hi : 00000000 Lo : 3b9aca00 epc : 80299dc8 musb_interrupt+0x648/0x974 Not tainted ra : 80299dc0 musb_interrupt+0x640/0x974 Status: 10000c02 KERNEL EXL Cause : 00800008 BadVA : 0000002c PrId : 2ed1024f (Ingenic JZRISC) Modules linked in: Process swapper (pid: 0, threadinfo=80514000, task=8051dd50, tls=00000000) Stack : 00000054 80528360 80520000 00000001 00000000 00000000 80540000 8006fba4 00000000 00000000 00000000 00000015 805265d8 80520000 80514000 00000000 8c7ca300 8029fe84 80515d90 8007718c 80515d98 8007718c 00000000 8006fab0 00000001 00000000 00000001 00000000 80540000 805316b0 805265d8 80540000 804c7370 80540000 00000001 80514000 00000000 00000041 b3410000 8006fcf8 ... Call Trace: [<80299dc8>] musb_interrupt+0x648/0x974 [<8029fe84>] jz_musb_interrupt+0x54/0xa4 [<8006fab0>] handle_irq_event_percpu+0x58/0x268 [<8006fcf8>] handle_irq_event+0x38/0x60 [<80072bd8>] handle_level_irq+0x90/0x110 [<8006f2dc>] generic_handle_irq+0x3c/0x54 [<8001831c>] do_IRQ+0x18/0x2c [<800164d0>] ret_from_irq+0x0/0x4 [<8006f268>] cpu_startup_entry+0xfc/0x134 [<805448f8>] start_kernel+0x360/0x380 Code: 02402021 8ea2000c 96430f84 <8c42002c> 7c4200c0 7c430004 a6430f84 8e420f84 30420001 ---[ end trace d1a9c488d7e5e4bf ]--- Kernel panic - not syncing: Fatal exception in interrupt
解法(drivers/usb/musb/jz4770.c)
static irqreturn_t jz_musb_interrupt(int irq, void *__hci) { unsigned long flags; struct musb *musb = __hci; irqreturn_t rv, rv_dma, rv_usb; rv = rv_dma = rv_usb = IRQ_NONE; spin_lock_irqsave(&musb->lock, flags); #if defined(CONFIG_USB_INVENTRA_DMA) if(musb->b_dma_share_usb_irq){ rv_dma = musb_call_dma_controller_irq(irq, musb); } #endif musb->int_usb = musb_readb(musb->mregs, MUSB_INTRUSB); musb->int_tx = musb_readw(musb->mregs, MUSB_INTRTX); musb->int_rx = musb_readw(musb->mregs, MUSB_INTRRX); if((musb->int_usb & MUSB_INTR_BABBLE) == 0){ if(musb->int_usb || musb->int_tx || musb->int_rx){ rv_usb = musb_interrupt(musb); } } spin_unlock_irqrestore(&musb->lock, flags); rv = (rv_dma == IRQ_HANDLED || rv_usb == IRQ_HANDLED) ? IRQ_HANDLED : IRQ_NONE; return rv; }