Unbalanced enable for IRQ => phy_change

From: Jean-Michel Hautbois
Date: Thu Dec 16 2010 - 04:05:58 EST


Hi !

I am currently using a MPC8548 PowerPC board, and I have encountered
the following problem :
[ Â 19.867849] Unbalanced enable for IRQ 48
[ Â 19.867855] ------------[ cut here ]------------
[ Â 19.873819] Badness at /.../kernel/irq/manage.c:174
[ Â 19.873823] NIP: c0044acc LR: c0044acc CTR: c0018480
[ Â 19.873828] REGS: dfc2be60 TRAP: 0700 Â Tainted: P
(2.6.24.7_www.men.de_1.1)
[ Â 19.873831] MSR: 00021000 <ME> ÂCR: 24000022 ÂXER: 00000000
[ Â 19.873839] TASK = dfc204e0[5] 'events/0' THREAD: dfc2a000
[ Â 19.873842] GPR00: c0044acc dfc2bf10 dfc204e0 0000002f 00021000
00000000 00000000 00000000
[ Â 19.873854] GPR08: 00000034 ffffffff 0000574e de821b20 24000024
100607bc 00008000 00001020
[ Â 19.873865] GPR16: c0447b44 c0447b2c 00fff018 033327d2 00000008
c044b2c8 c048d1a8 c044b300
[ Â 19.873877] GPR24: dfc206a0 dfc204e0 dfc01f30 dfc2a000 00029000
c04cb714 00000030 c04cb6e4
[ Â 19.873890] NIP [c0044acc] enable_irq+0x6c/0xdc
[ Â 19.873903] LR [c0044acc] enable_irq+0x6c/0xdc
[ Â 19.873908] Call Trace:
[ Â 19.873911] [dfc2bf10] [c0044acc] enable_irq+0x6c/0xdc (unreliable)
[ Â 19.873919] [dfc2bf30] [c0217868] phy_change+0x74/0xe4
[ Â 19.873926] [dfc2bf50] [c002fb2c] run_workqueue+0xc4/0x15c
[ Â 19.873933] [dfc2bf90] [c002ffb0] worker_thread+0x74/0xd4
[ Â 19.873940] [dfc2bfd0] [c0034360] kthread+0x48/0x84
[ Â 19.873946] [dfc2bff0] [c00047bc] kernel_thread+0x44/0x60
[ Â 19.873953] Instruction dump:
[ Â 19.873957] 7fe04a14 3bbf0030 7fa3eb78 483a9461 813f001c 7c7c1b78
2f890000 409e0038
[ Â 19.873968] 3c60c045 7fc4f378 3863f1d4 4bfd9129 <0fe00000> 7fa3eb78
7f84e378 483a91a5


When looking at the phy_change function in drivers/net/phy/phy.c I
have noticed something quite strange :
We are calling phy_disable_interrupts() and after some operations, enable_irq().
The first thing I thought about is why aren't we calling
disable_irq/enable_irq or phy_disable_interrupts/phy_enable_interrupts
but a mix ?

Next, I took a more deep look at phy_disable_interrupts() and
sepcifically at the phy_config_interrupt() function :

   Âint err = 0;

   Âphydev->interrupts = interrupts;
   Âif (phydev->drv->config_intr)
       Âerr = phydev->drv->config_intr(phydev);

   Âreturn err;

If phydev->drv->config_intr is not implemented (this is my use case :
I am using the drivers/net/gianfar.c driver), then, nothing will be
done, and there is no disable_irq() call.

I don't know what is better : using disable_irq/enable_irq or the phy
specific functions, but I think that we should avoid using a mix...
Am I wrong ?

Thanks in advance,
Regards,
JM
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/