aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/can/dev.c')
-rw-r--r--drivers/net/can/dev.c27
1 files changed, 17 insertions, 10 deletions
diff --git a/drivers/net/can/dev.c b/drivers/net/can/dev.c
index ad535a854e5c..eab132778e67 100644
--- a/drivers/net/can/dev.c
+++ b/drivers/net/can/dev.c
@@ -21,6 +21,7 @@
21#include <linux/slab.h> 21#include <linux/slab.h>
22#include <linux/netdevice.h> 22#include <linux/netdevice.h>
23#include <linux/if_arp.h> 23#include <linux/if_arp.h>
24#include <linux/workqueue.h>
24#include <linux/can.h> 25#include <linux/can.h>
25#include <linux/can/dev.h> 26#include <linux/can/dev.h>
26#include <linux/can/skb.h> 27#include <linux/can/skb.h>
@@ -471,9 +472,8 @@ EXPORT_SYMBOL_GPL(can_free_echo_skb);
471/* 472/*
472 * CAN device restart for bus-off recovery 473 * CAN device restart for bus-off recovery
473 */ 474 */
474static void can_restart(unsigned long data) 475static void can_restart(struct net_device *dev)
475{ 476{
476 struct net_device *dev = (struct net_device *)data;
477 struct can_priv *priv = netdev_priv(dev); 477 struct can_priv *priv = netdev_priv(dev);
478 struct net_device_stats *stats = &dev->stats; 478 struct net_device_stats *stats = &dev->stats;
479 struct sk_buff *skb; 479 struct sk_buff *skb;
@@ -513,6 +513,14 @@ restart:
513 netdev_err(dev, "Error %d during restart", err); 513 netdev_err(dev, "Error %d during restart", err);
514} 514}
515 515
516static void can_restart_work(struct work_struct *work)
517{
518 struct delayed_work *dwork = to_delayed_work(work);
519 struct can_priv *priv = container_of(dwork, struct can_priv, restart_work);
520
521 can_restart(priv->dev);
522}
523
516int can_restart_now(struct net_device *dev) 524int can_restart_now(struct net_device *dev)
517{ 525{
518 struct can_priv *priv = netdev_priv(dev); 526 struct can_priv *priv = netdev_priv(dev);
@@ -526,8 +534,8 @@ int can_restart_now(struct net_device *dev)
526 if (priv->state != CAN_STATE_BUS_OFF) 534 if (priv->state != CAN_STATE_BUS_OFF)
527 return -EBUSY; 535 return -EBUSY;
528 536
529 /* Runs as soon as possible in the timer context */ 537 cancel_delayed_work_sync(&priv->restart_work);
530 mod_timer(&priv->restart_timer, jiffies); 538 can_restart(dev);
531 539
532 return 0; 540 return 0;
533} 541}
@@ -548,8 +556,8 @@ void can_bus_off(struct net_device *dev)
548 netif_carrier_off(dev); 556 netif_carrier_off(dev);
549 557
550 if (priv->restart_ms) 558 if (priv->restart_ms)
551 mod_timer(&priv->restart_timer, 559 schedule_delayed_work(&priv->restart_work,
552 jiffies + (priv->restart_ms * HZ) / 1000); 560 msecs_to_jiffies(priv->restart_ms));
553} 561}
554EXPORT_SYMBOL_GPL(can_bus_off); 562EXPORT_SYMBOL_GPL(can_bus_off);
555 563
@@ -658,6 +666,7 @@ struct net_device *alloc_candev(int sizeof_priv, unsigned int echo_skb_max)
658 return NULL; 666 return NULL;
659 667
660 priv = netdev_priv(dev); 668 priv = netdev_priv(dev);
669 priv->dev = dev;
661 670
662 if (echo_skb_max) { 671 if (echo_skb_max) {
663 priv->echo_skb_max = echo_skb_max; 672 priv->echo_skb_max = echo_skb_max;
@@ -667,7 +676,7 @@ struct net_device *alloc_candev(int sizeof_priv, unsigned int echo_skb_max)
667 676
668 priv->state = CAN_STATE_STOPPED; 677 priv->state = CAN_STATE_STOPPED;
669 678
670 init_timer(&priv->restart_timer); 679 INIT_DELAYED_WORK(&priv->restart_work, can_restart_work);
671 680
672 return dev; 681 return dev;
673} 682}
@@ -748,8 +757,6 @@ int open_candev(struct net_device *dev)
748 if (!netif_carrier_ok(dev)) 757 if (!netif_carrier_ok(dev))
749 netif_carrier_on(dev); 758 netif_carrier_on(dev);
750 759
751 setup_timer(&priv->restart_timer, can_restart, (unsigned long)dev);
752
753 return 0; 760 return 0;
754} 761}
755EXPORT_SYMBOL_GPL(open_candev); 762EXPORT_SYMBOL_GPL(open_candev);
@@ -764,7 +771,7 @@ void close_candev(struct net_device *dev)
764{ 771{
765 struct can_priv *priv = netdev_priv(dev); 772 struct can_priv *priv = netdev_priv(dev);
766 773
767 del_timer_sync(&priv->restart_timer); 774 cancel_delayed_work_sync(&priv->restart_work);
768 can_flush_echo_skb(dev); 775 can_flush_echo_skb(dev);
769} 776}
770EXPORT_SYMBOL_GPL(close_candev); 777EXPORT_SYMBOL_GPL(close_candev);