diff options
| -rw-r--r-- | drivers/net/korina.c | 27 |
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 | */ |
| 895 | static int korina_restart(struct net_device *dev) | 895 | static 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 | ||
| 934 | static void korina_clear_and_restart(struct net_device *dev, u32 value) | 932 | static 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) | |||
| 962 | static void korina_tx_timeout(struct net_device *dev) | 960 | static 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); |
| 1203 | out: | 1202 | out: |
