Re: [PATCH v12 5/7] i2c: davinci: add support for setting bus frequency
Peter Rosin <[email protected]> Thu, 23 Jul 2026 13:05:35 +0200
| Newsgroups | org.kernel.vger.linux-i2c,org.infradead.lists.linux-arm-kernel,org.kernel.vger.linux-kernel |
|---|---|
| Message-ID | <[email protected]> |
Hi! On 2026-07-19 16:59, Marcus Folkesson wrote: > Populate adapter with clock_Hz and .set_clk_freq() to enable support for > dynamic bus frequency. > > Remove bus_freq_Hz entirely and only use clock_Hz instead. > > Acked-by: Bartosz Golaszewski <[email protected]> > Signed-off-by: Marcus Folkesson <[email protected]> > --- > drivers/i2c/busses/i2c-davinci.c | 33 +++++++++++++++++++++++++-------- > 1 file changed, 25 insertions(+), 8 deletions(-) > > diff --git a/drivers/i2c/busses/i2c-davinci.c b/drivers/i2c/busses/i2c-davinci.c > index f543997c31e9..87fef17bca55 100644 > --- a/drivers/i2c/busses/i2c-davinci.c > +++ b/drivers/i2c/busses/i2c-davinci.c > @@ -132,8 +132,6 @@ struct davinci_i2c_dev { > #ifdef CONFIG_CPU_FREQ > struct notifier_block freq_transition; > #endif > - /* standard bus frequency */ > - unsigned int bus_freq_Hz; > /* Chip has a ICPFUNC register */ > bool has_pfunc; > }; > @@ -171,6 +169,7 @@ static void i2c_davinci_calc_clk_dividers(struct davinci_i2c_dev *dev) > u32 clkh; > u32 clkl; > u32 input_clock = clk_get_rate(dev->clk); > + u32 bus_freq_Hz = dev->adapter.clock_Hz; > > /* NOTE: I2C Clock divider programming info > * As per I2C specs the following formulas provide prescaler > @@ -207,16 +206,16 @@ static void i2c_davinci_calc_clk_dividers(struct davinci_i2c_dev *dev) > if (device_is_compatible(dev->dev, "ti,keystone-i2c")) > d = 6; > > - clk = (input_clock / (psc + 1)) / (dev->bus_freq_Hz); > + clk = (input_clock / (psc + 1)) / (bus_freq_Hz); Repeat bracket comment from 4/7. I.e. clk = input_clock / (psc + 1) / bus_freq_Hz; Cheers, Peter > /* Avoid driving the bus too fast because of rounding errors above */ > - if (input_clock / (psc + 1) / clk > dev->bus_freq_Hz) > + if (input_clock / (psc + 1) / clk > bus_freq_Hz) > clk++; > /* > * According to I2C-BUS Spec 2.1, in FAST-MODE LOW period should be at > * least 1.3uS, which is not the case with 50% duty cycle. Driving HIGH > * to LOW ratio as 1 to 2 is more safe. > */ > - if (dev->bus_freq_Hz > I2C_MAX_STANDARD_MODE_FREQ) > + if (bus_freq_Hz > I2C_MAX_STANDARD_MODE_FREQ) > clkl = (clk << 1) / 3; > else > clkl = (clk >> 1); > @@ -267,7 +266,7 @@ static int i2c_davinci_init(struct davinci_i2c_dev *dev) > davinci_i2c_read_reg(dev, DAVINCI_I2C_CLKL_REG)); > dev_dbg(dev->dev, "CLKH = %d\n", > davinci_i2c_read_reg(dev, DAVINCI_I2C_CLKH_REG)); > - dev_dbg(dev->dev, "bus_freq_Hz = %dHz\n", dev->bus_freq_Hz); > + dev_dbg(dev->dev, "bus_freq_Hz = %dHz\n", dev->adapter.clock_Hz); > > > /* Take the I2C module out of reset: */ > @@ -279,6 +278,23 @@ static int i2c_davinci_init(struct davinci_i2c_dev *dev) > return 0; > } > > +static int davinci_i2c_set_clk(struct i2c_adapter *adap, u32 clock_Hz) > +{ > + struct davinci_i2c_dev *dev = i2c_get_adapdata(adap); > + > + /* put I2C into reset */ > + davinci_i2c_reset_ctrl(dev, 0); > + > + /* compute clock dividers */ > + adap->clock_Hz = clock_Hz; > + i2c_davinci_calc_clk_dividers(dev); > + > + /* Take the I2C module out of reset: */ > + davinci_i2c_reset_ctrl(dev, 1); > + > + return clock_Hz; > +} > + > /* > * This routine does i2c bus recovery by using i2c_generic_scl_recovery > * which is provided by I2C Bus recovery infrastructure. > @@ -755,12 +771,13 @@ static int davinci_i2c_probe(struct platform_device *pdev) > dev->dev = &pdev->dev; > dev->irq = irq; > platform_set_drvdata(pdev, dev); > + adap = &dev->adapter; > > r = device_property_read_u32(&pdev->dev, "clock-frequency", &prop); > if (r) > prop = I2C_MAX_STANDARD_MODE_FREQ; > > - dev->bus_freq_Hz = prop; > + adap->clock_Hz = prop; > > dev->has_pfunc = device_property_present(&pdev->dev, "ti,has-pfunc"); > > @@ -800,7 +817,6 @@ static int davinci_i2c_probe(struct platform_device *pdev) > goto err_unuse_clocks; > } > > - adap = &dev->adapter; > i2c_set_adapdata(adap, dev); > adap->owner = THIS_MODULE; > adap->class = I2C_CLASS_DEPRECATED; > @@ -809,6 +825,7 @@ static int davinci_i2c_probe(struct platform_device *pdev) > adap->dev.parent = &pdev->dev; > adap->timeout = DAVINCI_I2C_TIMEOUT; > adap->dev.of_node = dev_of_node(&pdev->dev); > + adap->set_clk_freq = davinci_i2c_set_clk; > > if (dev->has_pfunc) > adap->bus_recovery_info = &davinci_i2c_scl_recovery_info; >