diff options
author | Sriram <srk@ti.com> | 2010-02-21 22:35:36 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-02-22 18:45:53 -0500 |
commit | 35e2da46d25a53e0e19956f533cc29272a6cceb2 (patch) | |
tree | aa06cfa5bd76ce759c6f22f9c6c13719f86a19b2 /drivers/net/can | |
parent | e5f8d9ac46e0291594abaa76bf467a08367bcccf (diff) |
can:ti_hecc: Add pm hook-up
Added the suspend and resume implementation in the HECC (CAN)
driver.
Signed-off-by: K R Baalaaji <krbaalaaji@ti.com>
Signed-off-by: Sriramakrishnan <srk@ti.com>
Acked-by: Anant Gole <anantgole@ti.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/can')
-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"); |