Thread (34 messages) 34 messages, 2 authors, 2015-02-25

[PATCHv2 29/33] ARM: OMAP2+: control: convert to use syscon for register accesses

From: Tero Kristo <hidden>
Date: 2015-02-13 16:12:48
Also in: linux-omap
Subsystem: arm port, common clk framework, omap clock framework support, omap2+ support, the rest, ti clock driver · Maintainers: Russell King, Michael Turquette, Stephen Boyd, Paul Walmsley, Aaro Koskinen, Andreas Kemnade, Kevin Hilman, Roger Quadros, Tony Lindgren, Linus Torvalds, Tero Kristo

Control driver now uses syscon for accessing its register space. Also,
the clock driver under control module are using the same syscon
address space now.

Signed-off-by: Tero Kristo <redacted>
---
 arch/arm/mach-omap2/clock.h   |    1 +
 arch/arm/mach-omap2/control.c |   89 ++++++++++++++++++++++++++++++++---------
 include/linux/clk/ti.h        |    2 +-
 3 files changed, 71 insertions(+), 21 deletions(-)
diff --git a/arch/arm/mach-omap2/clock.h b/arch/arm/mach-omap2/clock.h
index 6a4dfe7..ddaabf1 100644
--- a/arch/arm/mach-omap2/clock.h
+++ b/arch/arm/mach-omap2/clock.h
@@ -241,6 +241,7 @@ enum {
 	CLK_MEMMAP_INDEX_CM1,
 	CLK_MEMMAP_INDEX_CM2,
 	CLK_MEMMAP_INDEX_SCRM,
+	CLK_MEMMAP_INDEX_CTRL,
 };
 
 extern struct ti_clk_features ti_clk_features;
diff --git a/arch/arm/mach-omap2/control.c b/arch/arm/mach-omap2/control.c
index da41288..a6d987b 100644
--- a/arch/arm/mach-omap2/control.c
+++ b/arch/arm/mach-omap2/control.c
@@ -15,6 +15,8 @@
 #include <linux/kernel.h>
 #include <linux/io.h>
 #include <linux/of_address.h>
+#include <linux/regmap.h>
+#include <linux/mfd/syscon.h>
 
 #include "soc.h"
 #include "iomap.h"
@@ -34,6 +36,7 @@
 
 static void __iomem *omap2_ctrl_base;
 static void __iomem *omap4_ctrl_pad_base;
+static struct regmap *omap2_ctrl_syscon;
 
 #if defined(CONFIG_ARCH_OMAP3) && defined(CONFIG_PM)
 struct omap3_scratchpad {
@@ -135,7 +138,6 @@ struct omap3_control_regs {
 static struct omap3_control_regs control_context;
 #endif /* CONFIG_ARCH_OMAP3 && CONFIG_PM */
 
-#define OMAP_CTRL_REGADDR(reg)		(omap2_ctrl_base + (reg))
 #define OMAP4_CTRL_PAD_REGADDR(reg)	(omap4_ctrl_pad_base + (reg))
 
 void __init omap2_set_globals_control(void __iomem *ctrl,
@@ -147,32 +149,71 @@ void __init omap2_set_globals_control(void __iomem *ctrl,
 
 u8 omap_ctrl_readb(u16 offset)
 {
-	return readb_relaxed(OMAP_CTRL_REGADDR(offset));
+	u32 val;
+	u8 byte_offset = offset & 0x3;
+
+	val = omap_ctrl_readl(offset);
+
+	return (val >> (byte_offset * 8)) & 0xff;
 }
 
 u16 omap_ctrl_readw(u16 offset)
 {
-	return readw_relaxed(OMAP_CTRL_REGADDR(offset));
+	u32 val;
+	u16 byte_offset = offset & 0x2;
+
+	val = omap_ctrl_readl(offset);
+
+	return (val >> (byte_offset * 8)) & 0xffff;
 }
 
 u32 omap_ctrl_readl(u16 offset)
 {
-	return readl_relaxed(OMAP_CTRL_REGADDR(offset));
+	u32 val;
+
+	offset &= 0xfffc;
+	if (!omap2_ctrl_syscon)
+		val = readl_relaxed(omap2_ctrl_base + offset);
+	else
+		regmap_read(omap2_ctrl_syscon, offset, &val);
+
+	return val;
 }
 
 void omap_ctrl_writeb(u8 val, u16 offset)
 {
-	writeb_relaxed(val, OMAP_CTRL_REGADDR(offset));
+	u32 tmp;
+	u8 byte_offset = offset & 0x3;
+
+	tmp = omap_ctrl_readl(offset);
+
+	tmp &= 0xffffffff ^ (0xff << (byte_offset * 8));
+	tmp |= val << (byte_offset * 8);
+
+	omap_ctrl_writel(tmp, offset);
 }
 
 void omap_ctrl_writew(u16 val, u16 offset)
 {
-	writew_relaxed(val, OMAP_CTRL_REGADDR(offset));
+	u32 tmp;
+	u8 byte_offset = offset & 0x2;
+
+	tmp = omap_ctrl_readl(offset);
+
+	tmp &= 0xffffffff ^ (0xffff << (byte_offset * 8));
+	tmp |= val << (byte_offset * 8);
+
+	omap_ctrl_writel(tmp, offset);
 }
 
 void omap_ctrl_writel(u32 val, u16 offset)
 {
-	writel_relaxed(val, OMAP_CTRL_REGADDR(offset));
+	offset &= 0xfffc;
+	if (!omap2_ctrl_syscon) {
+		pr_err("%s: early write: %04x\n", __func__, offset);
+		return;
+	}
+	regmap_write(omap2_ctrl_syscon, offset, val);
 }
 
 /*
@@ -611,11 +652,10 @@ void __init omap3_ctrl_init(void)
 
 struct control_init_data {
 	int index;
-	void __iomem *mem;
 };
 
 static const struct control_init_data ctrl_data = {
-	.index = CLK_MEMMAP_INDEX_SCRM,
+	.index = CLK_MEMMAP_INDEX_CTRL,
 };
 
 static struct of_device_id omap_scrm_dt_match_table[] = {
@@ -637,18 +677,14 @@ int __init omap2_control_base_init(void)
 {
 	struct device_node *np;
 	const struct of_device_id *match;
-	struct control_init_data *data;
-	void __iomem *mem;
+	const struct control_init_data *data;
 
 	for_each_matching_node_and_match(np, omap_scrm_dt_match_table, &match) {
-		data = (struct control_init_data *)match->data;
+		data = match->data;
 
-		mem = of_iomap(np, 0);
-		if (!mem)
+		omap2_ctrl_base = of_iomap(np, 0);
+		if (!omap2_ctrl_base)
 			return -ENOMEM;
-
-		omap2_ctrl_base = mem;
-		data->mem = mem;
 	}
 
 	return 0;
@@ -666,13 +702,26 @@ int __init omap_control_init(void)
 	const struct of_device_id *match;
 	const struct control_init_data *data;
 	int ret;
+	struct regmap *syscon;
 
 	for_each_matching_node_and_match(np, omap_scrm_dt_match_table, &match) {
 		data = match->data;
 
-		ret = omap2_clk_provider_init(np, data->index, NULL, data->mem);
-		if (ret)
-			return ret;
+		syscon = syscon_node_to_regmap(np);
+		if (IS_ERR(syscon))
+			return PTR_ERR(syscon);
+
+		if (data->index == CLK_MEMMAP_INDEX_CTRL) {
+			omap2_ctrl_syscon = syscon;
+
+			ret = omap2_clk_provider_init(np, data->index, syscon,
+						      NULL);
+			if (ret)
+				return ret;
+
+			iounmap(omap2_ctrl_base);
+			omap2_ctrl_base = NULL;
+		}
 	}
 
 	return 0;
diff --git a/include/linux/clk/ti.h b/include/linux/clk/ti.h
index 55ef529..00d42a9 100644
--- a/include/linux/clk/ti.h
+++ b/include/linux/clk/ti.h
@@ -215,7 +215,7 @@ struct ti_dt_clk {
 	}
 
 /* Maximum number of clock memmaps */
-#define CLK_MAX_MEMMAPS			4
+#define CLK_MAX_MEMMAPS			5
 
 typedef void (*ti_of_clk_init_cb_t)(struct clk_hw *, struct device_node *);
 
-- 
1.7.9.5
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help