aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/korina.c27
1 files changed, 13 insertions, 14 deletions
diff --git a/drivers/net/korina.c b/drivers/net/korina.c
index 26bf1b76b997..13533f937e05 100644
--- a/drivers/net/korina.c
+++ b/drivers/net/korina.c
@@ -135,6 +135,7 @@ struct korina_private {
135 struct napi_struct napi; 135 struct napi_struct napi;
136 struct timer_list media_check_timer; 136 struct timer_list media_check_timer;
137 struct mii_if_info mii_if; 137 struct mii_if_info mii_if;
138 struct work_struct restart_task;
138 struct net_device *dev; 139 struct net_device *dev;
139 int phy_addr; 140 int phy_addr;
140}; 141};
@@ -890,12 +891,12 @@ static int korina_init(struct net_device *dev)
890 891
891/* 892/*
892 * Restart the RC32434 ethernet controller. 893 * Restart the RC32434 ethernet controller.
893 * FIXME: check the return status where we call it
894 */ 894 */
895static int korina_restart(struct net_device *dev) 895static void korina_restart_task(struct work_struct *work)
896{ 896{
897 struct korina_private *lp = netdev_priv(dev); 897 struct korina_private *lp = container_of(work,
898 int ret; 898 struct korina_private, restart_task);
899 struct net_device *dev = lp->dev;
899 900
900 /* 901 /*
901 * Disable interrupts 902 * Disable interrupts
@@ -916,10 +917,9 @@ static int korina_restart(struct net_device *dev)
916 917
917 napi_disable(&lp->napi); 918 napi_disable(&lp->napi);
918 919
919 ret = korina_init(dev); 920 if (korina_init(dev) < 0) {
920 if (ret < 0) {
921 printk(KERN_ERR "%s: cannot restart device\n", dev->name); 921 printk(KERN_ERR "%s: cannot restart device\n", dev->name);
922 return ret; 922 return;
923 } 923 }
924 korina_multicast_list(dev); 924 korina_multicast_list(dev);
925 925
@@ -927,8 +927,6 @@ static int korina_restart(struct net_device *dev)
927 enable_irq(lp->ovr_irq); 927 enable_irq(lp->ovr_irq);
928 enable_irq(lp->tx_irq); 928 enable_irq(lp->tx_irq);
929 enable_irq(lp->rx_irq); 929 enable_irq(lp->rx_irq);
930
931 return ret;
932} 930}
933 931
934static void korina_clear_and_restart(struct net_device *dev, u32 value) 932static void korina_clear_and_restart(struct net_device *dev, u32 value)
@@ -937,7 +935,7 @@ static void korina_clear_and_restart(struct net_device *dev, u32 value)
937 935
938 netif_stop_queue(dev); 936 netif_stop_queue(dev);
939 writel(value, &lp->eth_regs->ethintfc); 937 writel(value, &lp->eth_regs->ethintfc);
940 korina_restart(dev); 938 schedule_work(&lp->restart_task);
941} 939}
942 940
943/* Ethernet Tx Underflow interrupt */ 941/* Ethernet Tx Underflow interrupt */
@@ -962,11 +960,8 @@ static irqreturn_t korina_und_interrupt(int irq, void *dev_id)
962static void korina_tx_timeout(struct net_device *dev) 960static void korina_tx_timeout(struct net_device *dev)
963{ 961{
964 struct korina_private *lp = netdev_priv(dev); 962 struct korina_private *lp = netdev_priv(dev);
965 unsigned long flags;
966 963
967 spin_lock_irqsave(&lp->lock, flags); 964 schedule_work(&lp->restart_task);
968 korina_restart(dev);
969 spin_unlock_irqrestore(&lp->lock, flags);
970} 965}
971 966
972/* Ethernet Rx Overflow interrupt */ 967/* Ethernet Rx Overflow interrupt */
@@ -1086,6 +1081,8 @@ static int korina_close(struct net_device *dev)
1086 1081
1087 napi_disable(&lp->napi); 1082 napi_disable(&lp->napi);
1088 1083
1084 cancel_work_sync(&lp->restart_task);
1085
1089 free_irq(lp->rx_irq, dev); 1086 free_irq(lp->rx_irq, dev);
1090 free_irq(lp->tx_irq, dev); 1087 free_irq(lp->tx_irq, dev);
1091 free_irq(lp->ovr_irq, dev); 1088 free_irq(lp->ovr_irq, dev);
@@ -1198,6 +1195,8 @@ static int korina_probe(struct platform_device *pdev)
1198 } 1195 }
1199 setup_timer(&lp->media_check_timer, korina_poll_media, (unsigned long) dev); 1196 setup_timer(&lp->media_check_timer, korina_poll_media, (unsigned long) dev);
1200 1197
1198 INIT_WORK(&lp->restart_task, korina_restart_task);
1199
1201 printk(KERN_INFO "%s: " DRV_NAME "-" DRV_VERSION " " DRV_RELDATE "\n", 1200 printk(KERN_INFO "%s: " DRV_NAME "-" DRV_VERSION " " DRV_RELDATE "\n",
1202 dev->name); 1201 dev->name);
1203out: 1202out: