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; 
}



返回上一頁