Re: [PATCHv10 01/41] clk: add support for platform specific clock I/O wrapper functions
From: Tero Kristo <hidden>
Date: 2013-12-16 08:06:01
Also in:
linux-arm-kernel, linux-omap
On 12/15/2013 02:48 AM, Mike Turquette wrote:
Quoting Tero Kristo (2013-11-26 00:05:42)quoted
Current clock wrappers assume simple and direct mapped hardware register access. Improve this support by adding functionality for registering platform specific clock I/O wrappers, which can be used to support various features needed like endianess conversions, indexed regmap support, etc. Default I/O wrapper provided also which uses the existing direct I/O mapped behavior. Signed-off-by: Tero Kristo <redacted>There is a separate discussion on removing regmap for reading omap clk registers. I guess this patch is not needed in that case?
Actually, this is still needed, as I need to map the clocks according to their parent nodes. -Tero
Regards, Mikequoted
--- drivers/clk/clk.c | 68 ++++++++++++++++++++++++++++++++++++++++++ include/linux/clk-provider.h | 15 +++++----- 2 files changed, 75 insertions(+), 8 deletions(-)diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index 2cf2ea6..c331386 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c@@ -34,6 +34,74 @@ static HLIST_HEAD(clk_root_list); static HLIST_HEAD(clk_orphan_list); static LIST_HEAD(clk_notifier_list); +/** + * clk_readl_default - default clock register read support function + * @reg: register to read + * + * Default implementation for reading a clock register. + */ +static u32 clk_readl_default(u32 __iomem *reg) +{ + return readl(reg); +} + +/** + * clk_writel_default - default clock register write support function + * @val: value to write + * @reg: register to write to + * + * Default implementation for writing a clock register. + */ +static void clk_writel_default(u32 val, u32 __iomem *reg) +{ + writel(val, reg); +} + +struct clk_reg_ops clk_reg_ops_default = { + .clk_readl = clk_readl_default, + .clk_writel = clk_writel_default +}; + +static struct clk_reg_ops *clk_reg_ops = &clk_reg_ops_default; + +/** + * clk_register_reg_ops - register access functions for clock registers + * @ops: register level ops + * + * Registers platform or SoC specific operations for reading / writing + * clock registers. + */ +int clk_register_reg_ops(struct clk_reg_ops *ops) +{ + if (!ops) + return -EINVAL; + clk_reg_ops = ops; + return 0; +} + +/** + * clk_readl - read a clock register value from hardware + * @reg: register to read + * + * Uses the registered clk_reg_ops to read a hardware clock register value. + */ +u32 clk_readl(u32 __iomem *reg) +{ + return clk_reg_ops->clk_readl(reg); +} + +/** + * clk_writel - write a clock register value to hardware + * @val: value to write + * @reg: register to write + * + * Uses the registered clk_reg_ops to write a hardware clock register value. + */ +void clk_writel(u32 val, u32 __iomem *reg) +{ + clk_reg_ops->clk_writel(val, reg); +} + /*** locking ***/ static void clk_prepare_lock(void) {diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h index 7e59253..16e4df2 100644 --- a/include/linux/clk-provider.h +++ b/include/linux/clk-provider.h@@ -512,15 +512,14 @@ static inline const char *of_clk_get_parent_name(struct device_node *np, * for improved portability across platforms */ -static inline u32 clk_readl(u32 __iomem *reg) -{ - return readl(reg); -} +struct clk_reg_ops { + u32 (*clk_readl)(u32 __iomem *reg); + void (*clk_writel)(u32 val, u32 __iomem *reg); +}; -static inline void clk_writel(u32 val, u32 __iomem *reg) -{ - writel(val, reg); -} +u32 clk_readl(u32 __iomem *reg); +void clk_writel(u32 val, u32 __iomem *reg); +int clk_register_reg_ops(struct clk_reg_ops *ops); #endif /* CONFIG_COMMON_CLK */ #endif /* CLK_PROVIDER_H */ --1.7.9.5