diff options
Diffstat (limited to 'drivers/net/can/dev.c')
-rw-r--r-- | drivers/net/can/dev.c | 27 |
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 | */ |
474 | static void can_restart(unsigned long data) | 475 | static 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 | ||
516 | static 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 | |||
516 | int can_restart_now(struct net_device *dev) | 524 | int 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 | } |
554 | EXPORT_SYMBOL_GPL(can_bus_off); | 562 | EXPORT_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 | } |
755 | EXPORT_SYMBOL_GPL(open_candev); | 762 | EXPORT_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 | } |
770 | EXPORT_SYMBOL_GPL(close_candev); | 777 | EXPORT_SYMBOL_GPL(close_candev); |