From mboxrd@z Thu Jan 1 00:00:00 1970 From: Tero Kristo Subject: [PATCHv5 21/35] ARM: OMAP2+: clock: add low-level support for regmap Date: Fri, 20 Mar 2015 20:44:32 +0200 Message-ID: <1426877086-17131-22-git-send-email-t-kristo@ti.com> References: <1426877086-17131-1-git-send-email-t-kristo@ti.com> Mime-Version: 1.0 Content-Type: text/plain Return-path: Received: from arroyo.ext.ti.com ([192.94.94.40]:39512 "EHLO arroyo.ext.ti.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751177AbbCTSqY (ORCPT ); Fri, 20 Mar 2015 14:46:24 -0400 In-Reply-To: <1426877086-17131-1-git-send-email-t-kristo@ti.com> Sender: linux-omap-owner@vger.kernel.org List-Id: linux-omap@vger.kernel.org To: linux-omap@vger.kernel.org, tony@atomide.com, paul@pwsan.com, sakari.ailus@iki.fi Cc: linux-arm-kernel@lists.infradead.org Some of the TI clock providers will be converted to use syscon, thus low-level regmap support is needed for the clock drivers also. This patch adds this support, which can be enabled for individual drivers in later patches. Signed-off-by: Tero Kristo --- arch/arm/mach-omap2/clock.c | 39 ++++++++++++++++++++++++++++++++------ arch/arm/mach-omap2/clock.h | 4 +++- arch/arm/mach-omap2/cm_common.c | 2 +- arch/arm/mach-omap2/control.c | 2 +- arch/arm/mach-omap2/prm_common.c | 2 +- 5 files changed, 39 insertions(+), 10 deletions(-) diff --git a/arch/arm/mach-omap2/clock.c b/arch/arm/mach-omap2/clock.c index 3327128..d9885b8 100644 --- a/arch/arm/mach-omap2/clock.c +++ b/arch/arm/mach-omap2/clock.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include @@ -73,20 +74,37 @@ struct ti_clk_features ti_clk_features; static bool clkdm_control = true; static LIST_HEAD(clk_hw_omap_clocks); -static void __iomem *clk_memmaps[CLK_MAX_MEMMAPS]; + +struct clk_iomap { + struct regmap *regmap; + void __iomem *mem; +}; + +static struct clk_iomap *clk_memmaps[CLK_MAX_MEMMAPS]; static void clk_memmap_writel(u32 val, void __iomem *reg) { struct clk_omap_reg *r = (struct clk_omap_reg *)® + struct clk_iomap *io = clk_memmaps[r->index]; - writel_relaxed(val, clk_memmaps[r->index] + r->offset); + if (io->regmap) + regmap_write(io->regmap, r->offset, val); + else + writel_relaxed(val, io->mem + r->offset); } static u32 clk_memmap_readl(void __iomem *reg) { + u32 val; struct clk_omap_reg *r = (struct clk_omap_reg *)® + struct clk_iomap *io = clk_memmaps[r->index]; + + if (io->regmap) + regmap_read(io->regmap, r->offset, &val); + else + val = readl_relaxed(io->mem + r->offset); - return readl_relaxed(clk_memmaps[r->index] + r->offset); + return val; } void omap2_clk_writel(u32 val, struct clk_hw_omap *clk, void __iomem *reg) @@ -119,18 +137,27 @@ static struct ti_clk_ll_ops omap_clk_ll_ops = { * @match_table: DT device table to match for devices to init * @np: device node pointer for the this clock provider * @index: index for the clock provider - * @mem: iomem pointer for the clock provider memory area + + @syscon: syscon regmap pointer + * @mem: iomem pointer for the clock provider memory area, only used if + * syscon is not provided * * Initializes a clock provider module (CM/PRM etc.), registering * the memory mapping at specified index and initializing the * low level driver infrastructure. Returns 0 in success. */ int __init omap2_clk_provider_init(struct device_node *np, int index, - void __iomem *mem) + struct regmap *syscon, void __iomem *mem) { + struct clk_iomap *io; + ti_clk_ll_ops = &omap_clk_ll_ops; - clk_memmaps[index] = mem; + io = kzalloc(sizeof(*io), GFP_KERNEL); + + io->regmap = syscon; + io->mem = mem; + + clk_memmaps[index] = io; ti_dt_clk_init_provider(np, index); diff --git a/arch/arm/mach-omap2/clock.h b/arch/arm/mach-omap2/clock.h index b6433fc..652ed0a 100644 --- a/arch/arm/mach-omap2/clock.h +++ b/arch/arm/mach-omap2/clock.h @@ -274,8 +274,10 @@ extern const struct clksel_rate div31_1to31_rates[]; extern int omap2_clkops_enable_clkdm(struct clk_hw *hw); extern void omap2_clkops_disable_clkdm(struct clk_hw *hw); +struct regmap; + int __init omap2_clk_provider_init(struct device_node *np, int index, - void __iomem *mem); + struct regmap *syscon, void __iomem *mem); void __init omap2_clk_legacy_provider_init(int index, void __iomem *mem); void __init ti_clk_init_features(void); diff --git a/arch/arm/mach-omap2/cm_common.c b/arch/arm/mach-omap2/cm_common.c index ff24fdf..23e8bce 100644 --- a/arch/arm/mach-omap2/cm_common.c +++ b/arch/arm/mach-omap2/cm_common.c @@ -361,7 +361,7 @@ int __init omap_cm_init(void) if (data->flags & CM_NO_CLOCKS) continue; - ret = omap2_clk_provider_init(np, data->index, data->mem); + ret = omap2_clk_provider_init(np, data->index, NULL, data->mem); if (ret) return ret; } diff --git a/arch/arm/mach-omap2/control.c b/arch/arm/mach-omap2/control.c index 21ff32c..4b40946 100644 --- a/arch/arm/mach-omap2/control.c +++ b/arch/arm/mach-omap2/control.c @@ -676,7 +676,7 @@ int __init omap_control_init(void) for_each_matching_node_and_match(np, omap_scrm_dt_match_table, &match) { data = match->data; - ret = omap2_clk_provider_init(np, data->index, data->mem); + ret = omap2_clk_provider_init(np, data->index, NULL, data->mem); if (ret) return ret; } diff --git a/arch/arm/mach-omap2/prm_common.c b/arch/arm/mach-omap2/prm_common.c index e48241e..da36316 100644 --- a/arch/arm/mach-omap2/prm_common.c +++ b/arch/arm/mach-omap2/prm_common.c @@ -796,7 +796,7 @@ int __init omap_prcm_init(void) for_each_matching_node_and_match(np, omap_prcm_dt_match_table, &match) { data = match->data; - ret = omap2_clk_provider_init(np, data->index, data->mem); + ret = omap2_clk_provider_init(np, data->index, NULL, data->mem); if (ret) return ret; } -- 1.7.9.5 From mboxrd@z Thu Jan 1 00:00:00 1970 From: t-kristo@ti.com (Tero Kristo) Date: Fri, 20 Mar 2015 20:44:32 +0200 Subject: [PATCHv5 21/35] ARM: OMAP2+: clock: add low-level support for regmap In-Reply-To: <1426877086-17131-1-git-send-email-t-kristo@ti.com> References: <1426877086-17131-1-git-send-email-t-kristo@ti.com> Message-ID: <1426877086-17131-22-git-send-email-t-kristo@ti.com> To: linux-arm-kernel@lists.infradead.org List-Id: linux-arm-kernel.lists.infradead.org Some of the TI clock providers will be converted to use syscon, thus low-level regmap support is needed for the clock drivers also. This patch adds this support, which can be enabled for individual drivers in later patches. Signed-off-by: Tero Kristo --- arch/arm/mach-omap2/clock.c | 39 ++++++++++++++++++++++++++++++++------ arch/arm/mach-omap2/clock.h | 4 +++- arch/arm/mach-omap2/cm_common.c | 2 +- arch/arm/mach-omap2/control.c | 2 +- arch/arm/mach-omap2/prm_common.c | 2 +- 5 files changed, 39 insertions(+), 10 deletions(-) diff --git a/arch/arm/mach-omap2/clock.c b/arch/arm/mach-omap2/clock.c index 3327128..d9885b8 100644 --- a/arch/arm/mach-omap2/clock.c +++ b/arch/arm/mach-omap2/clock.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include @@ -73,20 +74,37 @@ struct ti_clk_features ti_clk_features; static bool clkdm_control = true; static LIST_HEAD(clk_hw_omap_clocks); -static void __iomem *clk_memmaps[CLK_MAX_MEMMAPS]; + +struct clk_iomap { + struct regmap *regmap; + void __iomem *mem; +}; + +static struct clk_iomap *clk_memmaps[CLK_MAX_MEMMAPS]; static void clk_memmap_writel(u32 val, void __iomem *reg) { struct clk_omap_reg *r = (struct clk_omap_reg *)® + struct clk_iomap *io = clk_memmaps[r->index]; - writel_relaxed(val, clk_memmaps[r->index] + r->offset); + if (io->regmap) + regmap_write(io->regmap, r->offset, val); + else + writel_relaxed(val, io->mem + r->offset); } static u32 clk_memmap_readl(void __iomem *reg) { + u32 val; struct clk_omap_reg *r = (struct clk_omap_reg *)® + struct clk_iomap *io = clk_memmaps[r->index]; + + if (io->regmap) + regmap_read(io->regmap, r->offset, &val); + else + val = readl_relaxed(io->mem + r->offset); - return readl_relaxed(clk_memmaps[r->index] + r->offset); + return val; } void omap2_clk_writel(u32 val, struct clk_hw_omap *clk, void __iomem *reg) @@ -119,18 +137,27 @@ static struct ti_clk_ll_ops omap_clk_ll_ops = { * @match_table: DT device table to match for devices to init * @np: device node pointer for the this clock provider * @index: index for the clock provider - * @mem: iomem pointer for the clock provider memory area + + @syscon: syscon regmap pointer + * @mem: iomem pointer for the clock provider memory area, only used if + * syscon is not provided * * Initializes a clock provider module (CM/PRM etc.), registering * the memory mapping at specified index and initializing the * low level driver infrastructure. Returns 0 in success. */ int __init omap2_clk_provider_init(struct device_node *np, int index, - void __iomem *mem) + struct regmap *syscon, void __iomem *mem) { + struct clk_iomap *io; + ti_clk_ll_ops = &omap_clk_ll_ops; - clk_memmaps[index] = mem; + io = kzalloc(sizeof(*io), GFP_KERNEL); + + io->regmap = syscon; + io->mem = mem; + + clk_memmaps[index] = io; ti_dt_clk_init_provider(np, index); diff --git a/arch/arm/mach-omap2/clock.h b/arch/arm/mach-omap2/clock.h index b6433fc..652ed0a 100644 --- a/arch/arm/mach-omap2/clock.h +++ b/arch/arm/mach-omap2/clock.h @@ -274,8 +274,10 @@ extern const struct clksel_rate div31_1to31_rates[]; extern int omap2_clkops_enable_clkdm(struct clk_hw *hw); extern void omap2_clkops_disable_clkdm(struct clk_hw *hw); +struct regmap; + int __init omap2_clk_provider_init(struct device_node *np, int index, - void __iomem *mem); + struct regmap *syscon, void __iomem *mem); void __init omap2_clk_legacy_provider_init(int index, void __iomem *mem); void __init ti_clk_init_features(void); diff --git a/arch/arm/mach-omap2/cm_common.c b/arch/arm/mach-omap2/cm_common.c index ff24fdf..23e8bce 100644 --- a/arch/arm/mach-omap2/cm_common.c +++ b/arch/arm/mach-omap2/cm_common.c @@ -361,7 +361,7 @@ int __init omap_cm_init(void) if (data->flags & CM_NO_CLOCKS) continue; - ret = omap2_clk_provider_init(np, data->index, data->mem); + ret = omap2_clk_provider_init(np, data->index, NULL, data->mem); if (ret) return ret; } diff --git a/arch/arm/mach-omap2/control.c b/arch/arm/mach-omap2/control.c index 21ff32c..4b40946 100644 --- a/arch/arm/mach-omap2/control.c +++ b/arch/arm/mach-omap2/control.c @@ -676,7 +676,7 @@ int __init omap_control_init(void) for_each_matching_node_and_match(np, omap_scrm_dt_match_table, &match) { data = match->data; - ret = omap2_clk_provider_init(np, data->index, data->mem); + ret = omap2_clk_provider_init(np, data->index, NULL, data->mem); if (ret) return ret; } diff --git a/arch/arm/mach-omap2/prm_common.c b/arch/arm/mach-omap2/prm_common.c index e48241e..da36316 100644 --- a/arch/arm/mach-omap2/prm_common.c +++ b/arch/arm/mach-omap2/prm_common.c @@ -796,7 +796,7 @@ int __init omap_prcm_init(void) for_each_matching_node_and_match(np, omap_prcm_dt_match_table, &match) { data = match->data; - ret = omap2_clk_provider_init(np, data->index, data->mem); + ret = omap2_clk_provider_init(np, data->index, NULL, data->mem); if (ret) return ret; } -- 1.7.9.5