Add support for reading and configuring the OPP table in the GENI I2C
driver. This enables setting the frequency based on device tree data,
removing dependency on bootloader configuration.
Signed-off-by: Manikanta Mylavarapu <quic_mmanikan@quicinc.com>
---
drivers/i2c/busses/i2c-qcom-geni.c | 27 ++++++++++++++++++++++++---
1 file changed, 24 insertions(+), 3 deletions(-)
diff --git a/drivers/i2c/busses/i2c-qcom-geni.c b/drivers/i2c/busses/i2c-qcom-geni.c
index ff2289b52c84..85b7f25e0c6e 100644
--- a/drivers/i2c/busses/i2c-qcom-geni.c
+++ b/drivers/i2c/busses/i2c-qcom-geni.c
@@ -13,6 +13,7 @@
#include <linux/module.h>
#include <linux/of.h>
#include <linux/platform_device.h>
+#include <linux/pm_opp.h>
#include <linux/pm_runtime.h>
#include <linux/soc/qcom/geni-se.h>
#include <linux/spinlock.h>
@@ -779,11 +780,13 @@ static int setup_gpi_dma(struct geni_i2c_dev *gi2c)
static int geni_i2c_probe(struct platform_device *pdev)
{
- struct geni_i2c_dev *gi2c;
+ const struct geni_i2c_desc *desc = NULL;
u32 proto, tx_depth, fifo_disable;
- int ret;
struct device *dev = &pdev->dev;
- const struct geni_i2c_desc *desc = NULL;
+ unsigned long freq = ULONG_MAX;
+ struct geni_i2c_dev *gi2c;
+ struct dev_pm_opp *opp;
+ int ret;
gi2c = devm_kzalloc(dev, sizeof(*gi2c), GFP_KERNEL);
if (!gi2c)
@@ -814,6 +817,24 @@ static int geni_i2c_probe(struct platform_device *pdev)
gi2c->clk_freq_out = I2C_MAX_STANDARD_MODE_FREQ;
}
+ ret = devm_pm_opp_set_clkname(&pdev->dev, "se");
+ if (ret)
+ return ret;
+
+ /* OPP table is optional */
+ ret = devm_pm_opp_of_add_table(dev);
+ if (!ret) {
+ opp = dev_pm_opp_find_freq_floor(dev, &freq);
+ if (IS_ERR(opp))
+ return dev_err_probe(dev, PTR_ERR(opp), "failed to find the frequency\n");
+ dev_pm_opp_put(opp);
+ ret = dev_pm_opp_set_rate(dev, freq);
+ if (ret)
+ return dev_err_probe(dev, ret, "failed to set the rate=%ld\n", freq);
+ } else if (ret && ret != -ENODEV) {
+ return dev_err_probe(&pdev->dev, ret, "invalid OPP table in device tree\n");
+ }
+
if (has_acpi_companion(dev))
ACPI_COMPANION_SET(&gi2c->adap.dev, ACPI_COMPANION(dev));
--
2.34.1
Hi Manikanta, ... > @@ -814,6 +817,24 @@ static int geni_i2c_probe(struct platform_device *pdev) > gi2c->clk_freq_out = I2C_MAX_STANDARD_MODE_FREQ; > } > > + ret = devm_pm_opp_set_clkname(&pdev->dev, "se"); /&pdev->dev/dev/ > + if (ret) > + return ret; > + > + /* OPP table is optional */ > + ret = devm_pm_opp_of_add_table(dev); > + if (!ret) { > + opp = dev_pm_opp_find_freq_floor(dev, &freq); > + if (IS_ERR(opp)) > + return dev_err_probe(dev, PTR_ERR(opp), "failed to find the frequency\n"); > + dev_pm_opp_put(opp); > + ret = dev_pm_opp_set_rate(dev, freq); > + if (ret) > + return dev_err_probe(dev, ret, "failed to set the rate=%ld\n", freq); %lu Thanks, Andi > + } else if (ret && ret != -ENODEV) {
On 9/5/2025 3:57 AM, Andi Shyti wrote: >> @@ -814,6 +817,24 @@ static int geni_i2c_probe(struct platform_device *pdev) >> gi2c->clk_freq_out = I2C_MAX_STANDARD_MODE_FREQ; >> } >> >> + ret = devm_pm_opp_set_clkname(&pdev->dev, "se"); > > /&pdev->dev/dev/ > Hi Andi, Okay, sure. I will update in the next version. >> + if (ret) >> + return ret; >> + >> + /* OPP table is optional */ >> + ret = devm_pm_opp_of_add_table(dev); >> + if (!ret) { >> + opp = dev_pm_opp_find_freq_floor(dev, &freq); >> + if (IS_ERR(opp)) >> + return dev_err_probe(dev, PTR_ERR(opp), "failed to find the frequency\n"); >> + dev_pm_opp_put(opp); >> + ret = dev_pm_opp_set_rate(dev, freq); >> + if (ret) >> + return dev_err_probe(dev, ret, "failed to set the rate=%ld\n", freq); > > %lu > Okay, sure. I will update in the next version. Thanks & Regards, Manikanta.
© 2016 - 2025 Red Hat, Inc.