7
7
#include <linux/log2.h>
8
8
#include <linux/module.h>
9
9
#include <linux/platform_device.h>
10
+ #include <linux/pm_opp.h>
10
11
#include <linux/pm_runtime.h>
11
12
#include <linux/qcom-geni-se.h>
12
13
#include <linux/spi/spi.h>
@@ -95,7 +96,6 @@ static int get_spi_clk_cfg(unsigned int speed_hz,
95
96
{
96
97
unsigned long sclk_freq ;
97
98
unsigned int actual_hz ;
98
- struct geni_se * se = & mas -> se ;
99
99
int ret ;
100
100
101
101
ret = geni_se_clk_freq_match (& mas -> se ,
@@ -112,9 +112,9 @@ static int get_spi_clk_cfg(unsigned int speed_hz,
112
112
113
113
dev_dbg (mas -> dev , "req %u=>%u sclk %lu, idx %d, div %d\n" , speed_hz ,
114
114
actual_hz , sclk_freq , * clk_idx , * clk_div );
115
- ret = clk_set_rate ( se -> clk , sclk_freq );
115
+ ret = dev_pm_opp_set_rate ( mas -> dev , sclk_freq );
116
116
if (ret )
117
- dev_err (mas -> dev , "clk_set_rate failed %d\n" , ret );
117
+ dev_err (mas -> dev , "dev_pm_opp_set_rate failed %d\n" , ret );
118
118
return ret ;
119
119
}
120
120
@@ -568,6 +568,17 @@ static int spi_geni_probe(struct platform_device *pdev)
568
568
mas -> se .wrapper = dev_get_drvdata (dev -> parent );
569
569
mas -> se .base = base ;
570
570
mas -> se .clk = clk ;
571
+ mas -> se .opp_table = dev_pm_opp_set_clkname (& pdev -> dev , "se" );
572
+ if (IS_ERR (mas -> se .opp_table ))
573
+ return PTR_ERR (mas -> se .opp_table );
574
+ /* OPP table is optional */
575
+ ret = dev_pm_opp_of_add_table (& pdev -> dev );
576
+ if (!ret ) {
577
+ mas -> se .has_opp_table = true;
578
+ } else if (ret != - ENODEV ) {
579
+ dev_err (& pdev -> dev , "invalid OPP table in device tree\n" );
580
+ return ret ;
581
+ }
571
582
572
583
spi -> bus_num = -1 ;
573
584
spi -> dev .of_node = dev -> of_node ;
@@ -614,6 +625,9 @@ static int spi_geni_probe(struct platform_device *pdev)
614
625
spi_geni_probe_runtime_disable :
615
626
pm_runtime_disable (dev );
616
627
spi_master_put (spi );
628
+ if (mas -> se .has_opp_table )
629
+ dev_pm_opp_of_remove_table (& pdev -> dev );
630
+ dev_pm_opp_put_clkname (mas -> se .opp_table );
617
631
return ret ;
618
632
}
619
633
@@ -627,6 +641,9 @@ static int spi_geni_remove(struct platform_device *pdev)
627
641
628
642
free_irq (mas -> irq , spi );
629
643
pm_runtime_disable (& pdev -> dev );
644
+ if (mas -> se .has_opp_table )
645
+ dev_pm_opp_of_remove_table (& pdev -> dev );
646
+ dev_pm_opp_put_clkname (mas -> se .opp_table );
630
647
return 0 ;
631
648
}
632
649
@@ -636,6 +653,9 @@ static int __maybe_unused spi_geni_runtime_suspend(struct device *dev)
636
653
struct spi_geni_master * mas = spi_master_get_devdata (spi );
637
654
int ret ;
638
655
656
+ /* Drop the performance state vote */
657
+ dev_pm_opp_set_rate (dev , 0 );
658
+
639
659
ret = geni_se_resources_off (& mas -> se );
640
660
if (ret )
641
661
return ret ;
0 commit comments