2424#include <linux/of.h>
2525#include <linux/of_device.h>
2626#include <linux/platform_device.h>
27+ #include <linux/pm_runtime.h>
2728#include <linux/regulator/consumer.h>
2829#include <linux/regmap.h>
2930
@@ -266,6 +267,7 @@ struct flexcan_stop_mode {
266267struct flexcan_priv {
267268 struct can_priv can ;
268269 struct can_rx_offload offload ;
270+ struct device * dev ;
269271
270272 struct flexcan_regs __iomem * regs ;
271273 struct flexcan_mb __iomem * tx_mb ;
@@ -444,6 +446,27 @@ static inline void flexcan_error_irq_disable(const struct flexcan_priv *priv)
444446 priv -> write (reg_ctrl , & regs -> ctrl );
445447}
446448
449+ static int flexcan_clks_enable (const struct flexcan_priv * priv )
450+ {
451+ int err ;
452+
453+ err = clk_prepare_enable (priv -> clk_ipg );
454+ if (err )
455+ return err ;
456+
457+ err = clk_prepare_enable (priv -> clk_per );
458+ if (err )
459+ clk_disable_unprepare (priv -> clk_ipg );
460+
461+ return err ;
462+ }
463+
464+ static void flexcan_clks_disable (const struct flexcan_priv * priv )
465+ {
466+ clk_disable_unprepare (priv -> clk_per );
467+ clk_disable_unprepare (priv -> clk_ipg );
468+ }
469+
447470static inline int flexcan_transceiver_enable (const struct flexcan_priv * priv )
448471{
449472 if (!priv -> reg_xceiver )
@@ -570,19 +593,13 @@ static int flexcan_get_berr_counter(const struct net_device *dev,
570593 const struct flexcan_priv * priv = netdev_priv (dev );
571594 int err ;
572595
573- err = clk_prepare_enable (priv -> clk_ipg );
574- if (err )
596+ err = pm_runtime_get_sync (priv -> dev );
597+ if (err < 0 )
575598 return err ;
576599
577- err = clk_prepare_enable (priv -> clk_per );
578- if (err )
579- goto out_disable_ipg ;
580-
581600 err = __flexcan_get_berr_counter (dev , bec );
582601
583- clk_disable_unprepare (priv -> clk_per );
584- out_disable_ipg :
585- clk_disable_unprepare (priv -> clk_ipg );
602+ pm_runtime_put (priv -> dev );
586603
587604 return err ;
588605}
@@ -1215,17 +1232,13 @@ static int flexcan_open(struct net_device *dev)
12151232 struct flexcan_priv * priv = netdev_priv (dev );
12161233 int err ;
12171234
1218- err = clk_prepare_enable (priv -> clk_ipg );
1219- if (err )
1235+ err = pm_runtime_get_sync (priv -> dev );
1236+ if (err < 0 )
12201237 return err ;
12211238
1222- err = clk_prepare_enable (priv -> clk_per );
1223- if (err )
1224- goto out_disable_ipg ;
1225-
12261239 err = open_candev (dev );
12271240 if (err )
1228- goto out_disable_per ;
1241+ goto out_runtime_put ;
12291242
12301243 err = request_irq (dev -> irq , flexcan_irq , IRQF_SHARED , dev -> name , dev );
12311244 if (err )
@@ -1288,10 +1301,8 @@ static int flexcan_open(struct net_device *dev)
12881301 free_irq (dev -> irq , dev );
12891302 out_close :
12901303 close_candev (dev );
1291- out_disable_per :
1292- clk_disable_unprepare (priv -> clk_per );
1293- out_disable_ipg :
1294- clk_disable_unprepare (priv -> clk_ipg );
1304+ out_runtime_put :
1305+ pm_runtime_put (priv -> dev );
12951306
12961307 return err ;
12971308}
@@ -1306,10 +1317,9 @@ static int flexcan_close(struct net_device *dev)
13061317
13071318 can_rx_offload_del (& priv -> offload );
13081319 free_irq (dev -> irq , dev );
1309- clk_disable_unprepare (priv -> clk_per );
1310- clk_disable_unprepare (priv -> clk_ipg );
13111320
13121321 close_candev (dev );
1322+ pm_runtime_put (priv -> dev );
13131323
13141324 can_led_event (dev , CAN_LED_EVENT_STOP );
13151325
@@ -1349,18 +1359,15 @@ static int register_flexcandev(struct net_device *dev)
13491359 struct flexcan_regs __iomem * regs = priv -> regs ;
13501360 u32 reg , err ;
13511361
1352- err = clk_prepare_enable (priv -> clk_ipg );
1362+ err = flexcan_clks_enable (priv );
13531363 if (err )
13541364 return err ;
13551365
1356- err = clk_prepare_enable (priv -> clk_per );
1357- if (err )
1358- goto out_disable_ipg ;
1359-
13601366 /* select "bus clock", chip must be disabled */
13611367 err = flexcan_chip_disable (priv );
13621368 if (err )
1363- goto out_disable_per ;
1369+ goto out_clks_disable ;
1370+
13641371 reg = priv -> read (& regs -> ctrl );
13651372 reg |= FLEXCAN_CTRL_CLK_SRC ;
13661373 priv -> write (reg , & regs -> ctrl );
@@ -1388,15 +1395,21 @@ static int register_flexcandev(struct net_device *dev)
13881395 }
13891396
13901397 err = register_candev (dev );
1398+ if (err )
1399+ goto out_chip_disable ;
13911400
1392- /* disable core and turn off clocks */
1393- out_chip_disable :
1401+ /* Disable core and let pm_runtime_put() disable the clocks.
1402+ * If CONFIG_PM is not enabled, the clocks will stay powered.
1403+ */
13941404 flexcan_chip_disable (priv );
1395- out_disable_per :
1396- clk_disable_unprepare (priv -> clk_per );
1397- out_disable_ipg :
1398- clk_disable_unprepare (priv -> clk_ipg );
1405+ pm_runtime_put (priv -> dev );
1406+
1407+ return 0 ;
13991408
1409+ out_chip_disable :
1410+ flexcan_chip_disable (priv );
1411+ out_clks_disable :
1412+ flexcan_clks_disable (priv );
14001413 return err ;
14011414}
14021415
@@ -1556,6 +1569,7 @@ static int flexcan_probe(struct platform_device *pdev)
15561569 priv -> write = flexcan_write_le ;
15571570 }
15581571
1572+ priv -> dev = & pdev -> dev ;
15591573 priv -> can .clock .freq = clock_freq ;
15601574 priv -> can .bittiming_const = & flexcan_bittiming_const ;
15611575 priv -> can .do_set_mode = flexcan_set_mode ;
@@ -1569,6 +1583,10 @@ static int flexcan_probe(struct platform_device *pdev)
15691583 priv -> devtype_data = devtype_data ;
15701584 priv -> reg_xceiver = reg_xceiver ;
15711585
1586+ pm_runtime_get_noresume (& pdev -> dev );
1587+ pm_runtime_set_active (& pdev -> dev );
1588+ pm_runtime_enable (& pdev -> dev );
1589+
15721590 err = register_flexcandev (dev );
15731591 if (err ) {
15741592 dev_err (& pdev -> dev , "registering netdev failed\n" );
@@ -1595,6 +1613,7 @@ static int flexcan_remove(struct platform_device *pdev)
15951613 struct net_device * dev = platform_get_drvdata (pdev );
15961614
15971615 unregister_flexcandev (dev );
1616+ pm_runtime_disable (& pdev -> dev );
15981617 free_candev (dev );
15991618
16001619 return 0 ;
@@ -1604,7 +1623,7 @@ static int __maybe_unused flexcan_suspend(struct device *device)
16041623{
16051624 struct net_device * dev = dev_get_drvdata (device );
16061625 struct flexcan_priv * priv = netdev_priv (dev );
1607- int err ;
1626+ int err = 0 ;
16081627
16091628 if (netif_running (dev )) {
16101629 /* if wakeup is enabled, enter stop mode
@@ -1617,20 +1636,22 @@ static int __maybe_unused flexcan_suspend(struct device *device)
16171636 err = flexcan_chip_disable (priv );
16181637 if (err )
16191638 return err ;
1639+
1640+ err = pm_runtime_force_suspend (device );
16201641 }
16211642 netif_stop_queue (dev );
16221643 netif_device_detach (dev );
16231644 }
16241645 priv -> can .state = CAN_STATE_SLEEPING ;
16251646
1626- return 0 ;
1647+ return err ;
16271648}
16281649
16291650static int __maybe_unused flexcan_resume (struct device * device )
16301651{
16311652 struct net_device * dev = dev_get_drvdata (device );
16321653 struct flexcan_priv * priv = netdev_priv (dev );
1633- int err ;
1654+ int err = 0 ;
16341655
16351656 priv -> can .state = CAN_STATE_ERROR_ACTIVE ;
16361657 if (netif_running (dev )) {
@@ -1639,14 +1660,35 @@ static int __maybe_unused flexcan_resume(struct device *device)
16391660 if (device_may_wakeup (device )) {
16401661 disable_irq_wake (dev -> irq );
16411662 } else {
1642- err = flexcan_chip_enable ( priv );
1663+ err = pm_runtime_force_resume ( device );
16431664 if (err )
16441665 return err ;
1666+
1667+ err = flexcan_chip_enable (priv );
16451668 }
16461669 }
1670+
1671+ return err ;
1672+ }
1673+
1674+ static int __maybe_unused flexcan_runtime_suspend (struct device * device )
1675+ {
1676+ struct net_device * dev = dev_get_drvdata (device );
1677+ struct flexcan_priv * priv = netdev_priv (dev );
1678+
1679+ flexcan_clks_disable (priv );
1680+
16471681 return 0 ;
16481682}
16491683
1684+ static int __maybe_unused flexcan_runtime_resume (struct device * device )
1685+ {
1686+ struct net_device * dev = dev_get_drvdata (device );
1687+ struct flexcan_priv * priv = netdev_priv (dev );
1688+
1689+ return flexcan_clks_enable (priv );
1690+ }
1691+
16501692static int __maybe_unused flexcan_noirq_suspend (struct device * device )
16511693{
16521694 struct net_device * dev = dev_get_drvdata (device );
@@ -1673,6 +1715,7 @@ static int __maybe_unused flexcan_noirq_resume(struct device *device)
16731715
16741716static const struct dev_pm_ops flexcan_pm_ops = {
16751717 SET_SYSTEM_SLEEP_PM_OPS (flexcan_suspend , flexcan_resume )
1718+ SET_RUNTIME_PM_OPS (flexcan_runtime_suspend , flexcan_runtime_resume , NULL )
16761719 SET_NOIRQ_SYSTEM_SLEEP_PM_OPS (flexcan_noirq_suspend , flexcan_noirq_resume )
16771720};
16781721
0 commit comments