9
9
#include <linux/of.h>
10
10
#include <linux/of_platform.h>
11
11
#include <linux/pm_runtime.h>
12
+ #include <linux/pm_opp.h>
12
13
#include <linux/spi/spi.h>
13
14
#include <linux/spi/spi-mem.h>
14
15
@@ -141,6 +142,8 @@ struct qcom_qspi {
141
142
struct clk_bulk_data * clks ;
142
143
struct qspi_xfer xfer ;
143
144
struct icc_path * icc_path_cpu_to_qspi ;
145
+ struct opp_table * opp_table ;
146
+ bool has_opp_table ;
144
147
/* Lock to protect data accessed by IRQs */
145
148
spinlock_t lock ;
146
149
};
@@ -238,7 +241,7 @@ static int qcom_qspi_transfer_one(struct spi_master *master,
238
241
speed_hz = xfer -> speed_hz ;
239
242
240
243
/* In regular operation (SBL_EN=1) core must be 4x transfer clock */
241
- ret = clk_set_rate (ctrl -> clks [ QSPI_CLK_CORE ]. clk , speed_hz * 4 );
244
+ ret = dev_pm_opp_set_rate (ctrl -> dev , speed_hz * 4 );
242
245
if (ret ) {
243
246
dev_err (ctrl -> dev , "Failed to set core clk %d\n" , ret );
244
247
return ret ;
@@ -519,13 +522,30 @@ static int qcom_qspi_probe(struct platform_device *pdev)
519
522
master -> handle_err = qcom_qspi_handle_err ;
520
523
master -> auto_runtime_pm = true;
521
524
525
+ ctrl -> opp_table = dev_pm_opp_set_clkname (& pdev -> dev , "core" );
526
+ if (IS_ERR (ctrl -> opp_table )) {
527
+ ret = PTR_ERR (ctrl -> opp_table );
528
+ goto exit_probe_master_put ;
529
+ }
530
+ /* OPP table is optional */
531
+ ret = dev_pm_opp_of_add_table (& pdev -> dev );
532
+ if (!ret ) {
533
+ ctrl -> has_opp_table = true;
534
+ } else if (ret != - ENODEV ) {
535
+ dev_err (& pdev -> dev , "invalid OPP table in device tree\n" );
536
+ goto exit_probe_master_put ;
537
+ }
538
+
522
539
pm_runtime_enable (dev );
523
540
524
541
ret = spi_register_master (master );
525
542
if (!ret )
526
543
return 0 ;
527
544
528
545
pm_runtime_disable (dev );
546
+ if (ctrl -> has_opp_table )
547
+ dev_pm_opp_of_remove_table (& pdev -> dev );
548
+ dev_pm_opp_put_clkname (ctrl -> opp_table );
529
549
530
550
exit_probe_master_put :
531
551
spi_master_put (master );
@@ -536,11 +556,15 @@ static int qcom_qspi_probe(struct platform_device *pdev)
536
556
static int qcom_qspi_remove (struct platform_device * pdev )
537
557
{
538
558
struct spi_master * master = platform_get_drvdata (pdev );
559
+ struct qcom_qspi * ctrl = spi_master_get_devdata (master );
539
560
540
561
/* Unregister _before_ disabling pm_runtime() so we stop transfers */
541
562
spi_unregister_master (master );
542
563
543
564
pm_runtime_disable (& pdev -> dev );
565
+ if (ctrl -> has_opp_table )
566
+ dev_pm_opp_of_remove_table (& pdev -> dev );
567
+ dev_pm_opp_put_clkname (ctrl -> opp_table );
544
568
545
569
return 0 ;
546
570
}
@@ -551,6 +575,8 @@ static int __maybe_unused qcom_qspi_runtime_suspend(struct device *dev)
551
575
struct qcom_qspi * ctrl = spi_master_get_devdata (master );
552
576
int ret ;
553
577
578
+ /* Drop the performance state vote */
579
+ dev_pm_opp_set_rate (dev , 0 );
554
580
clk_bulk_disable_unprepare (QSPI_NUM_CLKS , ctrl -> clks );
555
581
556
582
ret = icc_disable (ctrl -> icc_path_cpu_to_qspi );
0 commit comments