diff --git a/drivers/i3c/master/renesas-i3c.c b/drivers/i3c/master/renesas-i3c.c index bb1d11693ec9..c1ab4edb3ab3 100644 --- a/drivers/i3c/master/renesas-i3c.c +++ b/drivers/i3c/master/renesas-i3c.c @@ -258,10 +258,13 @@ struct renesas_i3c { u32 free_pos; u32 i2c_STDBR; u32 i3c_STDBR; + unsigned long rate; u8 addrs[RENESAS_I3C_MAX_DEVS]; struct renesas_i3c_xferqueue xferqueue; void __iomem *regs; struct clk_bulk_data *clks; + struct reset_control *presetn; + struct reset_control *tresetn; u8 num_clks; }; @@ -482,22 +485,21 @@ static int renesas_i3c_bus_init(struct i3c_master_controller *m) struct i3c_bus *bus = i3c_master_get_bus(m); struct i3c_device_info info = {}; struct i2c_timings t; - unsigned long rate; u32 double_SBR, val; int cks, pp_high_ticks, pp_low_ticks, i3c_total_ticks; int od_high_ticks, od_low_ticks, i2c_total_ticks; int ret; - rate = clk_get_rate(i3c->clks[RENESAS_I3C_TCLK_IDX].clk); - if (!rate) + i3c->rate = clk_get_rate(i3c->clks[RENESAS_I3C_TCLK_IDX].clk); + if (!i3c->rate) return -EINVAL; ret = renesas_i3c_reset(i3c); if (ret) return ret; - i2c_total_ticks = DIV_ROUND_UP(rate, bus->scl_rate.i2c); - i3c_total_ticks = DIV_ROUND_UP(rate, bus->scl_rate.i3c); + i2c_total_ticks = DIV_ROUND_UP(i3c->rate, bus->scl_rate.i2c); + i3c_total_ticks = DIV_ROUND_UP(i3c->rate, bus->scl_rate.i3c); i2c_parse_fw_timings(&m->dev, &t, true); @@ -510,7 +512,7 @@ static int renesas_i3c_bus_init(struct i3c_master_controller *m) pp_high_ticks = ((i3c_total_ticks * 5) / 10); else pp_high_ticks = DIV_ROUND_UP(I3C_BUS_THIGH_MIXED_MAX_NS, - NSEC_PER_SEC / rate); + NSEC_PER_SEC / i3c->rate); pp_low_ticks = i3c_total_ticks - pp_high_ticks; if ((od_low_ticks / 2) <= 0xFF && pp_low_ticks < 0x3F) @@ -518,7 +520,7 @@ static int renesas_i3c_bus_init(struct i3c_master_controller *m) i2c_total_ticks /= 2; i3c_total_ticks /= 2; - rate /= 2; + i3c->rate /= 2; } /* SCL clock period calculation in Open-drain mode */ @@ -539,8 +541,8 @@ static int renesas_i3c_bus_init(struct i3c_master_controller *m) STDBR_SBRLP(pp_low_ticks) | STDBR_SBRHP(pp_high_ticks); - od_low_ticks -= t.scl_fall_ns / (NSEC_PER_SEC / rate) + 1; - od_high_ticks -= t.scl_rise_ns / (NSEC_PER_SEC / rate) + 1; + od_low_ticks -= t.scl_fall_ns / (NSEC_PER_SEC / i3c->rate) + 1; + od_high_ticks -= t.scl_rise_ns / (NSEC_PER_SEC / i3c->rate) + 1; i3c->i2c_STDBR = (double_SBR ? STDBR_DSBRPO : 0) | STDBR_SBRLO(double_SBR, od_low_ticks) | STDBR_SBRHO(double_SBR, od_high_ticks) | @@ -591,13 +593,13 @@ static int renesas_i3c_bus_init(struct i3c_master_controller *m) renesas_set_bit(i3c->regs, SCSTRCTL, SCSTRCTL_ACKTWE); /* Bus condition timing */ - val = DIV_ROUND_UP(I3C_BUS_TBUF_MIXED_FM_MIN_NS, NSEC_PER_SEC / rate); + val = DIV_ROUND_UP(I3C_BUS_TBUF_MIXED_FM_MIN_NS, NSEC_PER_SEC / i3c->rate); renesas_writel(i3c->regs, BFRECDT, BFRECDT_FRECYC(val)); - val = DIV_ROUND_UP(I3C_BUS_TAVAL_MIN_NS, NSEC_PER_SEC / rate); + val = DIV_ROUND_UP(I3C_BUS_TAVAL_MIN_NS, NSEC_PER_SEC / i3c->rate); renesas_writel(i3c->regs, BAVLCDT, BAVLCDT_AVLCYC(val)); - val = DIV_ROUND_UP(I3C_BUS_TIDLE_MIN_NS, NSEC_PER_SEC / rate); + val = DIV_ROUND_UP(I3C_BUS_TIDLE_MIN_NS, NSEC_PER_SEC / i3c->rate); renesas_writel(i3c->regs, BIDLCDT, BIDLCDT_IDLCYC(val)); ret = i3c_master_get_free_addr(m, 0); @@ -1300,7 +1302,6 @@ static const struct renesas_i3c_irq_desc renesas_i3c_irqs[] = { static int renesas_i3c_probe(struct platform_device *pdev) { struct renesas_i3c *i3c; - struct reset_control *reset; int ret, i; i3c = devm_kzalloc(&pdev->dev, sizeof(*i3c), GFP_KERNEL); @@ -1318,14 +1319,14 @@ static int renesas_i3c_probe(struct platform_device *pdev) RENESAS_I3C_TCLK_IDX, ret); i3c->num_clks = ret; - reset = devm_reset_control_get_optional_exclusive_deasserted(&pdev->dev, "tresetn"); - if (IS_ERR(reset)) - return dev_err_probe(&pdev->dev, PTR_ERR(reset), + i3c->tresetn = devm_reset_control_get_optional_exclusive_deasserted(&pdev->dev, "tresetn"); + if (IS_ERR(i3c->tresetn)) + return dev_err_probe(&pdev->dev, PTR_ERR(i3c->tresetn), "Error: missing tresetn ctrl\n"); - reset = devm_reset_control_get_optional_exclusive_deasserted(&pdev->dev, "presetn"); - if (IS_ERR(reset)) - return dev_err_probe(&pdev->dev, PTR_ERR(reset), + i3c->presetn = devm_reset_control_get_optional_exclusive_deasserted(&pdev->dev, "presetn"); + if (IS_ERR(i3c->presetn)) + return dev_err_probe(&pdev->dev, PTR_ERR(i3c->presetn), "Error: missing presetn ctrl\n"); spin_lock_init(&i3c->xferqueue.lock);