aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/davicom
diff options
context:
space:
mode:
authorAndrew Ruder <andrew.ruder@elecsyscorp.com>2014-06-04 18:28:46 -0400
committerDavid S. Miller <davem@davemloft.net>2014-06-05 18:12:10 -0400
commit17ad78de7f60bfc9711acb57c3c9561def6ee402 (patch)
tree2677355c2646a5b32facf7e6a5836a7e8aa53acc /drivers/net/ethernet/davicom
parent751bb6fd80b728d4820e0176837bc2c5e339e358 (diff)
dm9000: clean up edge-triggered irq compatibility
DM9000 uses level-triggered interrupts. Some systems (PXA270) only support edge-triggered interrupts on GPIOs. Some changes are necessary to ensure that interrupts are not triggered while the GPIO interrupt is masked or we will miss the interrupt forever. * Make some helper functions called dm9000_mask_interrupts() and dm9000_unmask_interrupts() for readability. * dm9000_init_dm9000(): ensure that this function always leaves interrupts masked regardless of the state when it entered the function. This is primarily to support the situation in dm9000_open where the logic used to go: dm9000_open() dm9000_init_dm9000() unmask interrupts request_irq() If an interrupt occurred between unmasking the interrupt and requesting the irq, it would be missed forever as the edge event would never be seen by the GPIO hardware in the PXA270. This allows us to change the logic to: dm9000_open() dm9000_init_dm9000() dm9000_mask_interrupts() request_irq() dm9000_unmask_interrupts() * dm9000_timeout(), dm9000_drv_resume(): Add the missing dm9000_unmask_interrupts() now required by the change above. * dm9000_shutdown(): Use mask helper function * dm9000_interrupt(): Use mask/unmask helper functions Signed-off-by: Andrew Ruder <andrew.ruder@elecsyscorp.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/davicom')
-rw-r--r--drivers/net/ethernet/davicom/dm9000.c32
1 files changed, 22 insertions, 10 deletions
diff --git a/drivers/net/ethernet/davicom/dm9000.c b/drivers/net/ethernet/davicom/dm9000.c
index a10671ecbf81..a34f9fcc3992 100644
--- a/drivers/net/ethernet/davicom/dm9000.c
+++ b/drivers/net/ethernet/davicom/dm9000.c
@@ -882,6 +882,18 @@ dm9000_hash_table(struct net_device *dev)
882 spin_unlock_irqrestore(&db->lock, flags); 882 spin_unlock_irqrestore(&db->lock, flags);
883} 883}
884 884
885static void
886dm9000_mask_interrupts(board_info_t *db)
887{
888 iow(db, DM9000_IMR, IMR_PAR);
889}
890
891static void
892dm9000_unmask_interrupts(board_info_t *db)
893{
894 iow(db, DM9000_IMR, db->imr_all);
895}
896
885/* 897/*
886 * Initialize dm9000 board 898 * Initialize dm9000 board
887 */ 899 */
@@ -895,6 +907,7 @@ dm9000_init_dm9000(struct net_device *dev)
895 dm9000_dbg(db, 1, "entering %s\n", __func__); 907 dm9000_dbg(db, 1, "entering %s\n", __func__);
896 908
897 dm9000_reset(db); 909 dm9000_reset(db);
910 dm9000_mask_interrupts(db);
898 911
899 /* I/O mode */ 912 /* I/O mode */
900 db->io_mode = ior(db, DM9000_ISR) >> 6; /* ISR bit7:6 keeps I/O mode */ 913 db->io_mode = ior(db, DM9000_ISR) >> 6; /* ISR bit7:6 keeps I/O mode */
@@ -943,9 +956,6 @@ dm9000_init_dm9000(struct net_device *dev)
943 956
944 db->imr_all = imr; 957 db->imr_all = imr;
945 958
946 /* Enable TX/RX interrupt mask */
947 iow(db, DM9000_IMR, imr);
948
949 /* Init Driver variable */ 959 /* Init Driver variable */
950 db->tx_pkt_cnt = 0; 960 db->tx_pkt_cnt = 0;
951 db->queue_pkt_len = 0; 961 db->queue_pkt_len = 0;
@@ -965,6 +975,7 @@ static void dm9000_timeout(struct net_device *dev)
965 975
966 netif_stop_queue(dev); 976 netif_stop_queue(dev);
967 dm9000_init_dm9000(dev); 977 dm9000_init_dm9000(dev);
978 dm9000_unmask_interrupts(db);
968 /* We can accept TX packets again */ 979 /* We can accept TX packets again */
969 dev->trans_start = jiffies; /* prevent tx timeout */ 980 dev->trans_start = jiffies; /* prevent tx timeout */
970 netif_wake_queue(dev); 981 netif_wake_queue(dev);
@@ -1194,9 +1205,7 @@ static irqreturn_t dm9000_interrupt(int irq, void *dev_id)
1194 /* Save previous register address */ 1205 /* Save previous register address */
1195 reg_save = readb(db->io_addr); 1206 reg_save = readb(db->io_addr);
1196 1207
1197 /* Disable all interrupts */ 1208 dm9000_mask_interrupts(db);
1198 iow(db, DM9000_IMR, IMR_PAR);
1199
1200 /* Got DM9000 interrupt status */ 1209 /* Got DM9000 interrupt status */
1201 int_status = ior(db, DM9000_ISR); /* Got ISR */ 1210 int_status = ior(db, DM9000_ISR); /* Got ISR */
1202 iow(db, DM9000_ISR, int_status); /* Clear ISR status */ 1211 iow(db, DM9000_ISR, int_status); /* Clear ISR status */
@@ -1219,9 +1228,7 @@ static irqreturn_t dm9000_interrupt(int irq, void *dev_id)
1219 } 1228 }
1220 } 1229 }
1221 1230
1222 /* Re-enable interrupt mask */ 1231 dm9000_unmask_interrupts(db);
1223 iow(db, DM9000_IMR, db->imr_all);
1224
1225 /* Restore previous register address */ 1232 /* Restore previous register address */
1226 writeb(reg_save, db->io_addr); 1233 writeb(reg_save, db->io_addr);
1227 1234
@@ -1309,6 +1316,10 @@ dm9000_open(struct net_device *dev)
1309 1316
1310 if (request_irq(dev->irq, dm9000_interrupt, irqflags, dev->name, dev)) 1317 if (request_irq(dev->irq, dm9000_interrupt, irqflags, dev->name, dev))
1311 return -EAGAIN; 1318 return -EAGAIN;
1319 /* Now that we have an interrupt handler hooked up we can unmask
1320 * our interrupts
1321 */
1322 dm9000_unmask_interrupts(db);
1312 1323
1313 /* Init driver variable */ 1324 /* Init driver variable */
1314 db->dbug_cnt = 0; 1325 db->dbug_cnt = 0;
@@ -1329,7 +1340,7 @@ dm9000_shutdown(struct net_device *dev)
1329 /* RESET device */ 1340 /* RESET device */
1330 dm9000_phy_write(dev, 0, MII_BMCR, BMCR_RESET); /* PHY RESET */ 1341 dm9000_phy_write(dev, 0, MII_BMCR, BMCR_RESET); /* PHY RESET */
1331 iow(db, DM9000_GPR, 0x01); /* Power-Down PHY */ 1342 iow(db, DM9000_GPR, 0x01); /* Power-Down PHY */
1332 iow(db, DM9000_IMR, IMR_PAR); /* Disable all interrupt */ 1343 dm9000_mask_interrupts(db);
1333 iow(db, DM9000_RCR, 0x00); /* Disable RX */ 1344 iow(db, DM9000_RCR, 0x00); /* Disable RX */
1334} 1345}
1335 1346
@@ -1694,6 +1705,7 @@ dm9000_drv_resume(struct device *dev)
1694 * the device was powered off it is in a known state */ 1705 * the device was powered off it is in a known state */
1695 if (!db->wake_state) { 1706 if (!db->wake_state) {
1696 dm9000_init_dm9000(ndev); 1707 dm9000_init_dm9000(ndev);
1708 dm9000_unmask_interrupts(db);
1697 } 1709 }
1698 1710
1699 netif_device_attach(ndev); 1711 netif_device_attach(ndev);