clk: Add a .get_parent operation

This allows clk_get_parent() to work with non-CCF clock drivers.

Cover-letter:
clk: uclass fixes and improvements
This series fixes a few issues found while writing a clk driver for a
new SoC (Bouffalo Lab BL808), and adds the new functionality needed to
implement a hierarchy of clocks in a single device (without the CCF).
The .get_parent hook will be useful on other platforms as well; I plan
to use it to implement PLL rate setting on sunxi.
END

Series-to: Lukasz Majewski <lukma@denx.de>
Series-to: Sean Anderson <seanga2@gmail.com>
Series-to: Simon Glass <sjg@chromium.org>

Signed-off-by: Samuel Holland <samuel@sholland.org>
This commit is contained in:
Samuel Holland 2022-12-02 00:38:24 -06:00
parent 60d1c55b4a
commit 6cf1bae1b1
2 changed files with 14 additions and 6 deletions

View File

@ -485,6 +485,7 @@ ulong clk_get_rate(struct clk *clk)
struct clk *clk_get_parent(struct clk *clk)
{
const struct clk_ops *ops;
struct udevice *pdev;
struct clk *pclk;
@ -492,12 +493,17 @@ struct clk *clk_get_parent(struct clk *clk)
if (!clk_valid(clk))
return ERR_PTR(-ENODEV);
pdev = dev_get_parent(clk->dev);
if (!pdev)
return ERR_PTR(-ENODEV);
pclk = dev_get_clk_ptr(pdev);
if (!pclk)
return ERR_PTR(-ENODEV);
ops = clk_dev_ops(clk->dev);
if (ops->get_parent) {
pclk = ops->get_parent(clk);
} else {
pdev = dev_get_parent(clk->dev);
if (!pdev)
return ERR_PTR(-ENODEV);
pclk = dev_get_clk_ptr(pdev);
if (!pclk)
return ERR_PTR(-ENODEV);
}
return pclk;
}

View File

@ -22,6 +22,7 @@ struct ofnode_phandle_args;
* @round_rate: Adjust a rate to the exact rate a clock can provide.
* @get_rate: Get current clock rate.
* @set_rate: Set current clock rate.
* @get_parent: Get current clock parent
* @set_parent: Set current clock parent
* @enable: Enable a clock.
* @disable: Disable a clock.
@ -36,6 +37,7 @@ struct clk_ops {
ulong (*round_rate)(struct clk *clk, ulong rate);
ulong (*get_rate)(struct clk *clk);
ulong (*set_rate)(struct clk *clk, ulong rate);
struct clk *(*get_parent)(struct clk *clk);
int (*set_parent)(struct clk *clk, struct clk *parent);
int (*enable)(struct clk *clk);
int (*disable)(struct clk *clk);