Skip to content

Commit 1a9e489

Browse files
Rajendra Nayakandersson
authored andcommitted
spi: spi-geni-qcom: Use OPP API to set clk/perf state
geni spi needs to express a perforamnce state requirement on CX depending on the frequency of the clock rates. Use OPP table from DT to register with OPP framework and use dev_pm_opp_set_rate() to set the clk/perf state. Signed-off-by: Rajendra Nayak <[email protected]> Reviewed-by: Matthias Kaehlcke <[email protected]> Acked-by: Mark Brown <[email protected]> Cc: Alok Chauhan <[email protected]> Cc: Akash Asthana <[email protected]> Cc: [email protected] Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Bjorn Andersson <[email protected]>
1 parent a5819b5 commit 1a9e489

File tree

1 file changed

+23
-3
lines changed

1 file changed

+23
-3
lines changed

drivers/spi/spi-geni-qcom.c

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#include <linux/log2.h>
88
#include <linux/module.h>
99
#include <linux/platform_device.h>
10+
#include <linux/pm_opp.h>
1011
#include <linux/pm_runtime.h>
1112
#include <linux/qcom-geni-se.h>
1213
#include <linux/spi/spi.h>
@@ -95,7 +96,6 @@ static int get_spi_clk_cfg(unsigned int speed_hz,
9596
{
9697
unsigned long sclk_freq;
9798
unsigned int actual_hz;
98-
struct geni_se *se = &mas->se;
9999
int ret;
100100

101101
ret = geni_se_clk_freq_match(&mas->se,
@@ -112,9 +112,9 @@ static int get_spi_clk_cfg(unsigned int speed_hz,
112112

113113
dev_dbg(mas->dev, "req %u=>%u sclk %lu, idx %d, div %d\n", speed_hz,
114114
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);
116116
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);
118118
return ret;
119119
}
120120

@@ -568,6 +568,17 @@ static int spi_geni_probe(struct platform_device *pdev)
568568
mas->se.wrapper = dev_get_drvdata(dev->parent);
569569
mas->se.base = base;
570570
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+
}
571582

572583
spi->bus_num = -1;
573584
spi->dev.of_node = dev->of_node;
@@ -614,6 +625,9 @@ static int spi_geni_probe(struct platform_device *pdev)
614625
spi_geni_probe_runtime_disable:
615626
pm_runtime_disable(dev);
616627
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);
617631
return ret;
618632
}
619633

@@ -627,6 +641,9 @@ static int spi_geni_remove(struct platform_device *pdev)
627641

628642
free_irq(mas->irq, spi);
629643
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);
630647
return 0;
631648
}
632649

@@ -636,6 +653,9 @@ static int __maybe_unused spi_geni_runtime_suspend(struct device *dev)
636653
struct spi_geni_master *mas = spi_master_get_devdata(spi);
637654
int ret;
638655

656+
/* Drop the performance state vote */
657+
dev_pm_opp_set_rate(dev, 0);
658+
639659
ret = geni_se_resources_off(&mas->se);
640660
if (ret)
641661
return ret;

0 commit comments

Comments
 (0)