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 - 2026 Red Hat, Inc.