diff options
| author | Thomas Richard (TI) <thomas.richard@bootlin.com> | 2026-05-19 18:06:58 +0300 |
|---|---|---|
| committer | Nishanth Menon <nm@ti.com> | 2026-05-26 14:44:33 +0300 |
| commit | 3c5912373340cb79db6585f0fcd8107198d4933d (patch) | |
| tree | 11e147da8454d472c2415a1bb7f72fcfc397c502 | |
| parent | 703b341fdd875c2d9c30a835021689e5a430a39a (diff) | |
| download | linux-3c5912373340cb79db6585f0fcd8107198d4933d.tar.xz | |
clk: keystone: sci-clk: Add restore_context() operation
Implement the restore_context() operation to restore the clock rate
and the clock parent state. The clock rate is saved in sci_clk struct
during set_rate() and recalc_rate() operations. The parent index
is saved in sci_clk struct during set_parent() operation. During
clock registration, the core retrieves each clockâs parent using
get_parent() operation to ensure the internal clock tree reflects
the actual hardware state, including any configurations made by the
bootloader. So we also save the parent index in get_parent().
Reviewed-by: Dhruva Gole <d-gole@ti.com>
Reviewed-by: Kendall Willis <k-willis@ti.com>
Acked-by: Stephen Boyd <sboyd@kernel.org>
Reviewed-by: Brian Masney <bmasney@redhat.com>
Signed-off-by: Thomas Richard (TI) <thomas.richard@bootlin.com>
Link: https://patch.msgid.link/20260519-ti-sci-jacinto-s2r-restore-irq-v9-3-c550a8ae0f31@bootlin.com
Signed-off-by: Nishanth Menon <nm@ti.com>
| -rw-r--r-- | drivers/clk/keystone/sci-clk.c | 45 |
1 files changed, 37 insertions, 8 deletions
diff --git a/drivers/clk/keystone/sci-clk.c b/drivers/clk/keystone/sci-clk.c index 9d5071223f4c..7c0f7b3e89e0 100644 --- a/drivers/clk/keystone/sci-clk.c +++ b/drivers/clk/keystone/sci-clk.c @@ -47,6 +47,8 @@ struct sci_clk_provider { * @node: Link for handling clocks probed via DT * @cached_req: Cached requested freq for determine rate calls * @cached_res: Cached result freq for determine rate calls + * @parent_id: Parent index for this clock + * @rate: Clock rate */ struct sci_clk { struct clk_hw hw; @@ -58,6 +60,8 @@ struct sci_clk { struct list_head node; unsigned long cached_req; unsigned long cached_res; + int parent_id; + unsigned long rate; }; #define to_sci_clk(_hw) container_of(_hw, struct sci_clk, hw) @@ -150,6 +154,8 @@ static unsigned long sci_clk_recalc_rate(struct clk_hw *hw, return 0; } + clk->rate = freq; + return freq; } @@ -210,10 +216,15 @@ static int sci_clk_set_rate(struct clk_hw *hw, unsigned long rate, unsigned long parent_rate) { struct sci_clk *clk = to_sci_clk(hw); + int ret; - return clk->provider->ops->set_freq(clk->provider->sci, clk->dev_id, - clk->clk_id, rate / 10 * 9, rate, - rate / 10 * 11); + ret = clk->provider->ops->set_freq(clk->provider->sci, clk->dev_id, + clk->clk_id, rate / 10 * 9, rate, + rate / 10 * 11); + if (!ret) + clk->rate = rate; + + return ret; } /** @@ -234,12 +245,13 @@ static u8 sci_clk_get_parent(struct clk_hw *hw) dev_err(clk->provider->dev, "get-parent failed for dev=%d, clk=%d, ret=%d\n", clk->dev_id, clk->clk_id, ret); + clk->parent_id = ret; return 0; } - parent_id = parent_id - clk->clk_id - 1; + clk->parent_id = parent_id - clk->clk_id - 1; - return (u8)parent_id; + return (u8)clk->parent_id; } /** @@ -252,12 +264,28 @@ static u8 sci_clk_get_parent(struct clk_hw *hw) static int sci_clk_set_parent(struct clk_hw *hw, u8 index) { struct sci_clk *clk = to_sci_clk(hw); + int ret; clk->cached_req = 0; - return clk->provider->ops->set_parent(clk->provider->sci, clk->dev_id, - clk->clk_id, - index + 1 + clk->clk_id); + ret = clk->provider->ops->set_parent(clk->provider->sci, clk->dev_id, + clk->clk_id, + index + 1 + clk->clk_id); + if (!ret) + clk->parent_id = index; + + return ret; +} + +static void sci_clk_restore_context(struct clk_hw *hw) +{ + struct sci_clk *clk = to_sci_clk(hw); + + if (clk->num_parents > 1 && clk->parent_id >= 0) + sci_clk_set_parent(hw, (u8)clk->parent_id); + + if (clk->rate) + sci_clk_set_rate(hw, clk->rate, 0); } static const struct clk_ops sci_clk_ops = { @@ -269,6 +297,7 @@ static const struct clk_ops sci_clk_ops = { .set_rate = sci_clk_set_rate, .get_parent = sci_clk_get_parent, .set_parent = sci_clk_set_parent, + .restore_context = sci_clk_restore_context, }; /** |
