[RFC 2/7] ARM: OMAP4+: PRCM: add support for registering PRCM partition against DT node

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



The PRCM core code contains a notion of PRCM partition and instances, and
all PRCM driver register accesses are done through the partitions.

The APIs provided in this patch make it possible for PRCM child nodes
to map their register spaces against proper PRCM partition, and access
the correct partition ID through the common PRCM APIs.

Signed-off-by: Tero Kristo <t-kristo@xxxxxx>
---
 arch/arm/mach-omap2/cm_common.c   |   12 +++++++++
 arch/arm/mach-omap2/prcm-common.h |    5 ++++
 arch/arm/mach-omap2/prm_common.c  |   53 +++++++++++++++++++++++++++++++++++++
 3 files changed, 70 insertions(+)

diff --git a/arch/arm/mach-omap2/cm_common.c b/arch/arm/mach-omap2/cm_common.c
index 23e8bce..541ecaa 100644
--- a/arch/arm/mach-omap2/cm_common.c
+++ b/arch/arm/mach-omap2/cm_common.c
@@ -23,6 +23,8 @@
 #include "cm33xx.h"
 #include "cm44xx.h"
 #include "clock.h"
+#include "prcm43xx.h"
+#include "prcm44xx.h"
 
 /*
  * cm_ll_data: function pointers to SoC-specific implementations of
@@ -225,11 +227,13 @@ int cm_unregister(struct cm_ll_data *cld)
 static struct omap_prcm_init_data cm_data __initdata = {
 	.index = TI_CLKM_CM,
 	.init = omap4_cm_init,
+	.part = OMAP4430_CM1_PARTITION,
 };
 
 static struct omap_prcm_init_data cm2_data __initdata = {
 	.index = TI_CLKM_CM2,
 	.init = omap4_cm_init,
+	.part = OMAP4430_CM2_PARTITION,
 };
 #endif
 
@@ -268,6 +272,7 @@ static struct omap_prcm_init_data am4_prcm_data __initdata = {
 	.index = TI_CLKM_CM,
 	.flags = CM_NO_CLOCKS | CM_SINGLE_INSTANCE,
 	.init = omap4_cm_init,
+	.part = AM43XX_CM_PARTITION,
 };
 #endif
 
@@ -316,6 +321,7 @@ int __init omap2_cm_base_init(void)
 	const struct of_device_id *match;
 	struct omap_prcm_init_data *data;
 	void __iomem *mem;
+	int ret;
 
 	for_each_matching_node_and_match(np, omap_cm_dt_match_table, &match) {
 		data = (struct omap_prcm_init_data *)match->data;
@@ -337,6 +343,12 @@ int __init omap2_cm_base_init(void)
 		if (data->init && (data->flags & CM_SINGLE_INSTANCE ||
 				   (cm_base && cm2_base)))
 			data->init(data);
+
+		if (data->part) {
+			ret = omap_prcm_map_partition(np, data->part);
+			if (ret)
+				return ret;
+		}
 	}
 
 	return 0;
diff --git a/arch/arm/mach-omap2/prcm-common.h b/arch/arm/mach-omap2/prcm-common.h
index 6ae0b3a..037754d 100644
--- a/arch/arm/mach-omap2/prcm-common.h
+++ b/arch/arm/mach-omap2/prcm-common.h
@@ -527,6 +527,7 @@ struct omap_prcm_irq_setup {
  * @device_inst_offset: device instance offset within the module address space
  * @init: low level PRCM init function for this module
  * @np: device node for this PRCM module
+ * @part: PRCM partition ID, applicable for OMAP4+ only
  */
 struct omap_prcm_init_data {
 	int index;
@@ -536,6 +537,7 @@ struct omap_prcm_init_data {
 	s32 device_inst_offset;
 	int (*init)(const struct omap_prcm_init_data *data);
 	struct device_node *np;
+	u8 part;
 };
 
 extern void omap_prcm_irq_cleanup(void);
@@ -545,6 +547,9 @@ extern int omap_prcm_event_to_irq(const char *event);
 extern void omap_prcm_irq_prepare(void);
 extern void omap_prcm_irq_complete(void);
 
+int omap_prcm_map_partition(struct device_node *np, u8 part);
+int omap_prcm_get_partition(struct device_node *np);
+
 # endif
 
 #endif
diff --git a/arch/arm/mach-omap2/prm_common.c b/arch/arm/mach-omap2/prm_common.c
index 7add799..a3f0aef 100644
--- a/arch/arm/mach-omap2/prm_common.c
+++ b/arch/arm/mach-omap2/prm_common.c
@@ -37,6 +37,7 @@
 #include "prm54xx.h"
 #include "prm7xx.h"
 #include "prcm43xx.h"
+#include "prcm44xx.h"
 #include "common.h"
 #include "clock.h"
 #include "cm.h"
@@ -77,6 +78,8 @@ u16 prm_features;
 static struct prm_ll_data null_prm_ll_data;
 static struct prm_ll_data *prm_ll_data = &null_prm_ll_data;
 
+static struct device_node *prcm_base_nodes[OMAP4_MAX_PRCM_PARTITIONS];
+
 /* Private functions */
 
 /*
@@ -670,6 +673,7 @@ static struct omap_prcm_init_data omap4_prm_data __initdata = {
 	.init = omap44xx_prm_init,
 	.device_inst_offset = OMAP4430_PRM_DEVICE_INST,
 	.flags = PRM_HAS_IO_WAKEUP | PRM_HAS_VOLTAGE | PRM_IRQ_DEFAULT,
+	.part = OMAP4430_PRM_PARTITION,
 };
 #endif
 
@@ -679,6 +683,7 @@ static struct omap_prcm_init_data omap5_prm_data __initdata = {
 	.init = omap44xx_prm_init,
 	.device_inst_offset = OMAP54XX_PRM_DEVICE_INST,
 	.flags = PRM_HAS_IO_WAKEUP | PRM_HAS_VOLTAGE,
+	.part = OMAP54XX_PRM_PARTITION,
 };
 #endif
 
@@ -688,6 +693,7 @@ static struct omap_prcm_init_data dra7_prm_data __initdata = {
 	.init = omap44xx_prm_init,
 	.device_inst_offset = DRA7XX_PRM_DEVICE_INST,
 	.flags = PRM_HAS_IO_WAKEUP,
+	.part = DRA7XX_PRM_PARTITION,
 };
 #endif
 
@@ -696,12 +702,14 @@ static struct omap_prcm_init_data am4_prm_data __initdata = {
 	.index = TI_CLKM_PRM,
 	.init = omap44xx_prm_init,
 	.device_inst_offset = AM43XX_PRM_DEVICE_INST,
+	.part = AM43XX_PRM_PARTITION,
 };
 #endif
 
 #if defined(CONFIG_ARCH_OMAP4) || defined(CONFIG_SOC_OMAP5)
 static struct omap_prcm_init_data scrm_data __initdata = {
 	.index = TI_CLKM_SCRM,
+	.part = OMAP4430_SCRM_PARTITION,
 };
 #endif
 
@@ -749,6 +757,7 @@ int __init omap2_prm_base_init(void)
 	const struct of_device_id *match;
 	struct omap_prcm_init_data *data;
 	void __iomem *mem;
+	int ret;
 
 	for_each_matching_node_and_match(np, omap_prcm_dt_match_table, &match) {
 		data = (struct omap_prcm_init_data *)match->data;
@@ -766,6 +775,12 @@ int __init omap2_prm_base_init(void)
 
 		if (data->init)
 			data->init(data);
+
+		if (data->part) {
+			ret = omap_prcm_map_partition(np, data->part);
+			if (ret)
+				return ret;
+		}
 	}
 
 	return 0;
@@ -815,3 +830,41 @@ static int __init prm_late_init(void)
 	return 0;
 }
 subsys_initcall(prm_late_init);
+
+/**
+ * omap_prcm_map_partition - maps a PRCM partition for a DT node
+ * @np: device node to map
+ * @part: PRCM partition ID for this node
+ *
+ * Maps a device tree node against a particular PRCM partition. This
+ * mapping can be used to determine the PRCM partition for the
+ * children of this node later on. Returns 0 on success, negative error
+ * value in failure.
+ */
+int __init omap_prcm_map_partition(struct device_node *np, u8 part)
+{
+	if (prcm_base_nodes[part])
+		return -EBUSY;
+
+	prcm_base_nodes[part] = np;
+
+	return 0;
+}
+
+/**
+ * omap_prcm_get_partition - gets PRCM partition ID for a DT node
+ * @np: device node to get PRCM partition for
+ *
+ * Gets the PRCM partition ID for a device tree node. Returns the
+ * partition ID, or negative error value in failure.
+ */
+int __init omap_prcm_get_partition(struct device_node *np)
+{
+	int i;
+
+	for (i = 0; i < OMAP4_MAX_PRCM_PARTITIONS; i++)
+		if (np == prcm_base_nodes[i])
+			return i;
+
+	return -ENOENT;
+}
-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Index of Archives]     [Linux Arm (vger)]     [ARM Kernel]     [ARM MSM]     [Linux Tegra]     [Linux WPAN Networking]     [Linux Wireless Networking]     [Maemo Users]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite Trails]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux