aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorIshizaki Kou <kou.ishizaki@toshiba.co.jp>2007-08-20 09:13:27 -0400
committerJeff Garzik <jeff@garzik.org>2007-09-13 00:16:31 -0400
commita041fe2e8d0bd749b2416ef79adc416e24af7c63 (patch)
treeda75b65fd154d284fae277d855bbeb9e225e24ba /drivers
parent64251621796d5d4c0c4b6a6b6d845e4a43c63aee (diff)
spidernet: fix interrupt reason recognition
This patch solves a problem that the spidernet driver sometimes fails to handle IRQ. The problem happens because, - In Cell architecture, interrupts may arrive at an interrupt controller, even if they are masked by the setting on registers of devices. It happens when interrupt packets are sent just before the interrupts are masked. - spidernet interrupt handler compares interrupt reasons with interrupt masks, so when such interrupts occurs, spidernet interrupt handler returns IRQ_NONE. - When all of interrupt handler return IRQ_NONE, linux kernel disables the IRQ and it no longer delivers interrupts to the interrupt handlers. spidernet doesn't work after above sequence, because it can't receive interrupts. This patch changes spidernet interrupt handler that it compares interrupt reason with SPIDER_NET_INTX_MASK_VALUE. Signed-off-by: Kou Ishizaki <kou.ishizaki@toshiba.co.jp> Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/spider_net.c12
1 files changed, 4 insertions, 8 deletions
diff --git a/drivers/net/spider_net.c b/drivers/net/spider_net.c
index 590b12c7246c..82d837ab4db9 100644
--- a/drivers/net/spider_net.c
+++ b/drivers/net/spider_net.c
@@ -1441,17 +1441,14 @@ static void
1441spider_net_handle_error_irq(struct spider_net_card *card, u32 status_reg) 1441spider_net_handle_error_irq(struct spider_net_card *card, u32 status_reg)
1442{ 1442{
1443 u32 error_reg1, error_reg2; 1443 u32 error_reg1, error_reg2;
1444 u32 mask_reg1, mask_reg2;
1445 u32 i; 1444 u32 i;
1446 int show_error = 1; 1445 int show_error = 1;
1447 1446
1448 error_reg1 = spider_net_read_reg(card, SPIDER_NET_GHIINT1STS); 1447 error_reg1 = spider_net_read_reg(card, SPIDER_NET_GHIINT1STS);
1449 error_reg2 = spider_net_read_reg(card, SPIDER_NET_GHIINT2STS); 1448 error_reg2 = spider_net_read_reg(card, SPIDER_NET_GHIINT2STS);
1450 mask_reg1 = spider_net_read_reg(card, SPIDER_NET_GHIINT1MSK);
1451 mask_reg2 = spider_net_read_reg(card,SPIDER_NET_GHIINT2MSK);
1452 1449
1453 error_reg1 &= mask_reg1; 1450 error_reg1 &= SPIDER_NET_INT1_MASK_VALUE;
1454 error_reg2 &= mask_reg2; 1451 error_reg2 &= SPIDER_NET_INT2_MASK_VALUE;
1455 1452
1456 /* check GHIINT0STS ************************************/ 1453 /* check GHIINT0STS ************************************/
1457 if (status_reg) 1454 if (status_reg)
@@ -1679,11 +1676,10 @@ spider_net_interrupt(int irq, void *ptr)
1679{ 1676{
1680 struct net_device *netdev = ptr; 1677 struct net_device *netdev = ptr;
1681 struct spider_net_card *card = netdev_priv(netdev); 1678 struct spider_net_card *card = netdev_priv(netdev);
1682 u32 status_reg, mask_reg; 1679 u32 status_reg;
1683 1680
1684 status_reg = spider_net_read_reg(card, SPIDER_NET_GHIINT0STS); 1681 status_reg = spider_net_read_reg(card, SPIDER_NET_GHIINT0STS);
1685 mask_reg = spider_net_read_reg(card, SPIDER_NET_GHIINT0MSK); 1682 status_reg &= SPIDER_NET_INT0_MASK_VALUE;
1686 status_reg &= mask_reg;
1687 1683
1688 if (!status_reg) 1684 if (!status_reg)
1689 return IRQ_NONE; 1685 return IRQ_NONE;