diff options
| -rw-r--r-- | drivers/net/can/ti_hecc.c | 51 |
1 files changed, 48 insertions, 3 deletions
diff --git a/drivers/net/can/ti_hecc.c b/drivers/net/can/ti_hecc.c index 8332e242b0be..b861cd561074 100644 --- a/drivers/net/can/ti_hecc.c +++ b/drivers/net/can/ti_hecc.c | |||
| @@ -826,7 +826,6 @@ static int ti_hecc_open(struct net_device *ndev) | |||
| 826 | return err; | 826 | return err; |
| 827 | } | 827 | } |
| 828 | 828 | ||
| 829 | clk_enable(priv->clk); | ||
| 830 | ti_hecc_start(ndev); | 829 | ti_hecc_start(ndev); |
| 831 | napi_enable(&priv->napi); | 830 | napi_enable(&priv->napi); |
| 832 | netif_start_queue(ndev); | 831 | netif_start_queue(ndev); |
| @@ -842,7 +841,6 @@ static int ti_hecc_close(struct net_device *ndev) | |||
| 842 | napi_disable(&priv->napi); | 841 | napi_disable(&priv->napi); |
| 843 | ti_hecc_stop(ndev); | 842 | ti_hecc_stop(ndev); |
| 844 | free_irq(ndev->irq, ndev); | 843 | free_irq(ndev->irq, ndev); |
| 845 | clk_disable(priv->clk); | ||
| 846 | close_candev(ndev); | 844 | close_candev(ndev); |
| 847 | 845 | ||
| 848 | return 0; | 846 | return 0; |
| @@ -928,6 +926,7 @@ static int ti_hecc_probe(struct platform_device *pdev) | |||
| 928 | netif_napi_add(ndev, &priv->napi, ti_hecc_rx_poll, | 926 | netif_napi_add(ndev, &priv->napi, ti_hecc_rx_poll, |
| 929 | HECC_DEF_NAPI_WEIGHT); | 927 | HECC_DEF_NAPI_WEIGHT); |
| 930 | 928 | ||
| 929 | clk_enable(priv->clk); | ||
| 931 | err = register_candev(ndev); | 930 | err = register_candev(ndev); |
| 932 | if (err) { | 931 | if (err) { |
| 933 | dev_err(&pdev->dev, "register_candev() failed\n"); | 932 | dev_err(&pdev->dev, "register_candev() failed\n"); |
| @@ -956,6 +955,7 @@ static int __devexit ti_hecc_remove(struct platform_device *pdev) | |||
| 956 | struct net_device *ndev = platform_get_drvdata(pdev); | 955 | struct net_device *ndev = platform_get_drvdata(pdev); |
| 957 | struct ti_hecc_priv *priv = netdev_priv(ndev); | 956 | struct ti_hecc_priv *priv = netdev_priv(ndev); |
| 958 | 957 | ||
| 958 | clk_disable(priv->clk); | ||
| 959 | clk_put(priv->clk); | 959 | clk_put(priv->clk); |
| 960 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 960 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
| 961 | iounmap(priv->base); | 961 | iounmap(priv->base); |
| @@ -967,6 +967,48 @@ static int __devexit ti_hecc_remove(struct platform_device *pdev) | |||
| 967 | return 0; | 967 | return 0; |
| 968 | } | 968 | } |
| 969 | 969 | ||
| 970 | |||
| 971 | #ifdef CONFIG_PM | ||
| 972 | static int ti_hecc_suspend(struct platform_device *pdev, pm_message_t state) | ||
| 973 | { | ||
| 974 | struct net_device *dev = platform_get_drvdata(pdev); | ||
| 975 | struct ti_hecc_priv *priv = netdev_priv(dev); | ||
| 976 | |||
| 977 | if (netif_running(dev)) { | ||
| 978 | netif_stop_queue(dev); | ||
| 979 | netif_device_detach(dev); | ||
| 980 | } | ||
| 981 | |||
| 982 | hecc_set_bit(priv, HECC_CANMC, HECC_CANMC_PDR); | ||
| 983 | priv->can.state = CAN_STATE_SLEEPING; | ||
| 984 | |||
| 985 | clk_disable(priv->clk); | ||
| 986 | |||
| 987 | return 0; | ||
| 988 | } | ||
| 989 | |||
| 990 | static int ti_hecc_resume(struct platform_device *pdev) | ||
| 991 | { | ||
| 992 | struct net_device *dev = platform_get_drvdata(pdev); | ||
| 993 | struct ti_hecc_priv *priv = netdev_priv(dev); | ||
| 994 | |||
| 995 | clk_enable(priv->clk); | ||
| 996 | |||
| 997 | hecc_clear_bit(priv, HECC_CANMC, HECC_CANMC_PDR); | ||
| 998 | priv->can.state = CAN_STATE_ERROR_ACTIVE; | ||
| 999 | |||
| 1000 | if (netif_running(dev)) { | ||
| 1001 | netif_device_attach(dev); | ||
| 1002 | netif_start_queue(dev); | ||
| 1003 | } | ||
| 1004 | |||
| 1005 | return 0; | ||
| 1006 | } | ||
| 1007 | #else | ||
| 1008 | #define ti_hecc_suspend NULL | ||
| 1009 | #define ti_hecc_resume NULL | ||
| 1010 | #endif | ||
| 1011 | |||
| 970 | /* TI HECC netdevice driver: platform driver structure */ | 1012 | /* TI HECC netdevice driver: platform driver structure */ |
| 971 | static struct platform_driver ti_hecc_driver = { | 1013 | static struct platform_driver ti_hecc_driver = { |
| 972 | .driver = { | 1014 | .driver = { |
| @@ -975,6 +1017,8 @@ static struct platform_driver ti_hecc_driver = { | |||
| 975 | }, | 1017 | }, |
| 976 | .probe = ti_hecc_probe, | 1018 | .probe = ti_hecc_probe, |
| 977 | .remove = __devexit_p(ti_hecc_remove), | 1019 | .remove = __devexit_p(ti_hecc_remove), |
| 1020 | .suspend = ti_hecc_suspend, | ||
| 1021 | .resume = ti_hecc_resume, | ||
| 978 | }; | 1022 | }; |
| 979 | 1023 | ||
| 980 | static int __init ti_hecc_init_driver(void) | 1024 | static int __init ti_hecc_init_driver(void) |
| @@ -982,14 +1026,15 @@ static int __init ti_hecc_init_driver(void) | |||
| 982 | printk(KERN_INFO DRV_DESC "\n"); | 1026 | printk(KERN_INFO DRV_DESC "\n"); |
| 983 | return platform_driver_register(&ti_hecc_driver); | 1027 | return platform_driver_register(&ti_hecc_driver); |
| 984 | } | 1028 | } |
| 985 | module_init(ti_hecc_init_driver); | ||
| 986 | 1029 | ||
| 987 | static void __exit ti_hecc_exit_driver(void) | 1030 | static void __exit ti_hecc_exit_driver(void) |
| 988 | { | 1031 | { |
| 989 | printk(KERN_INFO DRV_DESC " unloaded\n"); | 1032 | printk(KERN_INFO DRV_DESC " unloaded\n"); |
| 990 | platform_driver_unregister(&ti_hecc_driver); | 1033 | platform_driver_unregister(&ti_hecc_driver); |
| 991 | } | 1034 | } |
| 1035 | |||
| 992 | module_exit(ti_hecc_exit_driver); | 1036 | module_exit(ti_hecc_exit_driver); |
| 1037 | module_init(ti_hecc_init_driver); | ||
| 993 | 1038 | ||
| 994 | MODULE_AUTHOR("Anant Gole <anantgole@ti.com>"); | 1039 | MODULE_AUTHOR("Anant Gole <anantgole@ti.com>"); |
| 995 | MODULE_LICENSE("GPL v2"); | 1040 | MODULE_LICENSE("GPL v2"); |
