30
30
#include <linux/of_device.h>
31
31
#include <linux/pinctrl/consumer.h>
32
32
#include <linux/platform_device.h>
33
+ #include <linux/pm_runtime.h>
33
34
#include <linux/sched.h>
34
35
#include <linux/slab.h>
35
36
90
91
#define FAST_PLUS_MAX_BITRATE 3400000
91
92
#define HIGHSPEED_MAX_BITRATE 5000000
92
93
94
+ #define I2C_PM_TIMEOUT 10 /* ms */
95
+
93
96
enum lpi2c_imx_mode {
94
97
STANDARD , /* 100+Kbps */
95
98
FAST , /* 400+Kbps */
@@ -274,8 +277,8 @@ static int lpi2c_imx_master_enable(struct lpi2c_imx_struct *lpi2c_imx)
274
277
unsigned int temp ;
275
278
int ret ;
276
279
277
- ret = clk_enable (lpi2c_imx -> clk );
278
- if (ret )
280
+ ret = pm_runtime_get_sync (lpi2c_imx -> adapter . dev . parent );
281
+ if (ret < 0 )
279
282
return ret ;
280
283
281
284
temp = MCR_RST ;
@@ -284,16 +287,17 @@ static int lpi2c_imx_master_enable(struct lpi2c_imx_struct *lpi2c_imx)
284
287
285
288
ret = lpi2c_imx_config (lpi2c_imx );
286
289
if (ret )
287
- goto clk_disable ;
290
+ goto rpm_put ;
288
291
289
292
temp = readl (lpi2c_imx -> base + LPI2C_MCR );
290
293
temp |= MCR_MEN ;
291
294
writel (temp , lpi2c_imx -> base + LPI2C_MCR );
292
295
293
296
return 0 ;
294
297
295
- clk_disable :
296
- clk_disable (lpi2c_imx -> clk );
298
+ rpm_put :
299
+ pm_runtime_mark_last_busy (lpi2c_imx -> adapter .dev .parent );
300
+ pm_runtime_put_autosuspend (lpi2c_imx -> adapter .dev .parent );
297
301
298
302
return ret ;
299
303
}
@@ -306,7 +310,8 @@ static int lpi2c_imx_master_disable(struct lpi2c_imx_struct *lpi2c_imx)
306
310
temp &= ~MCR_MEN ;
307
311
writel (temp , lpi2c_imx -> base + LPI2C_MCR );
308
312
309
- clk_disable (lpi2c_imx -> clk );
313
+ pm_runtime_mark_last_busy (lpi2c_imx -> adapter .dev .parent );
314
+ pm_runtime_put_autosuspend (lpi2c_imx -> adapter .dev .parent );
310
315
311
316
return 0 ;
312
317
}
@@ -606,22 +611,31 @@ static int lpi2c_imx_probe(struct platform_device *pdev)
606
611
return ret ;
607
612
}
608
613
614
+ pm_runtime_set_autosuspend_delay (& pdev -> dev , I2C_PM_TIMEOUT );
615
+ pm_runtime_use_autosuspend (& pdev -> dev );
616
+ pm_runtime_get_noresume (& pdev -> dev );
617
+ pm_runtime_set_active (& pdev -> dev );
618
+ pm_runtime_enable (& pdev -> dev );
619
+
609
620
temp = readl (lpi2c_imx -> base + LPI2C_PARAM );
610
621
lpi2c_imx -> txfifosize = 1 << (temp & 0x0f );
611
622
lpi2c_imx -> rxfifosize = 1 << ((temp >> 8 ) & 0x0f );
612
623
613
- clk_disable (lpi2c_imx -> clk );
614
-
615
624
ret = i2c_add_adapter (& lpi2c_imx -> adapter );
616
625
if (ret )
617
- goto clk_unprepare ;
626
+ goto rpm_disable ;
627
+
628
+ pm_runtime_mark_last_busy (& pdev -> dev );
629
+ pm_runtime_put_autosuspend (& pdev -> dev );
618
630
619
631
dev_info (& lpi2c_imx -> adapter .dev , "LPI2C adapter registered\n" );
620
632
621
633
return 0 ;
622
634
623
- clk_unprepare :
624
- clk_unprepare (lpi2c_imx -> clk );
635
+ rpm_disable :
636
+ pm_runtime_put (& pdev -> dev );
637
+ pm_runtime_disable (& pdev -> dev );
638
+ pm_runtime_dont_use_autosuspend (& pdev -> dev );
625
639
626
640
return ret ;
627
641
}
@@ -632,36 +646,56 @@ static int lpi2c_imx_remove(struct platform_device *pdev)
632
646
633
647
i2c_del_adapter (& lpi2c_imx -> adapter );
634
648
635
- clk_unprepare (lpi2c_imx -> clk );
649
+ pm_runtime_disable (& pdev -> dev );
650
+ pm_runtime_dont_use_autosuspend (& pdev -> dev );
636
651
637
652
return 0 ;
638
653
}
639
654
640
655
#ifdef CONFIG_PM_SLEEP
641
- static int lpi2c_imx_suspend (struct device * dev )
656
+ static int lpi2c_runtime_suspend (struct device * dev )
642
657
{
658
+ struct lpi2c_imx_struct * lpi2c_imx = dev_get_drvdata (dev );
659
+
660
+ clk_disable_unprepare (lpi2c_imx -> clk );
643
661
pinctrl_pm_select_sleep_state (dev );
644
662
645
663
return 0 ;
646
664
}
647
665
648
- static int lpi2c_imx_resume (struct device * dev )
666
+ static int lpi2c_runtime_resume (struct device * dev )
649
667
{
668
+ struct lpi2c_imx_struct * lpi2c_imx = dev_get_drvdata (dev );
669
+ int ret ;
670
+
650
671
pinctrl_pm_select_default_state (dev );
672
+ ret = clk_prepare_enable (lpi2c_imx -> clk );
673
+ if (ret ) {
674
+ dev_err (dev , "failed to enable I2C clock, ret=%d\n" , ret );
675
+ return ret ;
676
+ }
651
677
652
678
return 0 ;
653
679
}
654
- #endif
655
680
656
- static SIMPLE_DEV_PM_OPS (imx_lpi2c_pm , lpi2c_imx_suspend , lpi2c_imx_resume ) ;
681
+ static const struct dev_pm_ops lpi2c_pm_ops = {
682
+ SET_NOIRQ_SYSTEM_SLEEP_PM_OPS (pm_runtime_force_suspend ,
683
+ pm_runtime_force_resume )
684
+ SET_RUNTIME_PM_OPS (lpi2c_runtime_suspend ,
685
+ lpi2c_runtime_resume , NULL )
686
+ };
687
+ #define IMX_LPI2C_PM (&lpi2c_pm_ops)
688
+ #else
689
+ #define IMX_LPI2C_PM NULL
690
+ #endif
657
691
658
692
static struct platform_driver lpi2c_imx_driver = {
659
693
.probe = lpi2c_imx_probe ,
660
694
.remove = lpi2c_imx_remove ,
661
695
.driver = {
662
696
.name = DRIVER_NAME ,
663
697
.of_match_table = lpi2c_imx_of_match ,
664
- .pm = & imx_lpi2c_pm ,
698
+ .pm = IMX_LPI2C_PM ,
665
699
},
666
700
};
667
701
0 commit comments