All of lore.kernel.org
 help / color / mirror / Atom feed
From: Tero Kristo <t-kristo@ti.com>
To: tony@atomide.com, paul@pwsan.com, linux-omap@vger.kernel.org
Cc: linux-arm-kernel@lists.infradead.org
Subject: [PATCHv3 16/35] ARM: OMAP2+: PRM: move SoC specific init calls within a generic API
Date: Wed, 25 Feb 2015 21:04:26 +0200	[thread overview]
Message-ID: <1424891085-10392-17-git-send-email-t-kristo@ti.com> (raw)
In-Reply-To: <1424891085-10392-1-git-send-email-t-kristo@ti.com>

This gets rid of need for some exported driver APIs, and simplifies the
initialization of the PRM driver. Done in preparation to make PRM a
separate driver. The init data is now also passed to the SoC specific
implementations, allowing future expansion to add feature flags etc.

Signed-off-by: Tero Kristo <t-kristo@ti.com>
---
 arch/arm/mach-omap2/io.c           |   21 ++++++++--------
 arch/arm/mach-omap2/prcm-common.h  |    4 +++
 arch/arm/mach-omap2/prm.h          |    1 +
 arch/arm/mach-omap2/prm2xxx.c      |    3 +--
 arch/arm/mach-omap2/prm2xxx.h      |    2 +-
 arch/arm/mach-omap2/prm33xx.c      |    3 +--
 arch/arm/mach-omap2/prm33xx.h      |    2 +-
 arch/arm/mach-omap2/prm3xxx.c      |    4 +--
 arch/arm/mach-omap2/prm3xxx.h      |    2 +-
 arch/arm/mach-omap2/prm44xx.c      |    3 +--
 arch/arm/mach-omap2/prm44xx.h      |    1 -
 arch/arm/mach-omap2/prm44xx_54xx.h |    4 ++-
 arch/arm/mach-omap2/prm54xx.h      |    1 -
 arch/arm/mach-omap2/prm7xx.h       |    2 +-
 arch/arm/mach-omap2/prm_common.c   |   47 +++++++++++++++++++++++++++---------
 15 files changed, 62 insertions(+), 38 deletions(-)

diff --git a/arch/arm/mach-omap2/io.c b/arch/arm/mach-omap2/io.c
index 622ee3b..7632dfe 100644
--- a/arch/arm/mach-omap2/io.c
+++ b/arch/arm/mach-omap2/io.c
@@ -386,7 +386,7 @@ void __init omap2420_init_early(void)
 			       OMAP2_L3_IO_ADDRESS(OMAP2420_SMS_BASE));
 	omap2_control_base_init();
 	omap2xxx_check_revision();
-	omap2xxx_prm_init();
+	omap2_prcm_base_init();
 	omap2xxx_cm_init();
 	omap2xxx_voltagedomains_init();
 	omap242x_powerdomains_init();
@@ -413,7 +413,7 @@ void __init omap2430_init_early(void)
 			       OMAP2_L3_IO_ADDRESS(OMAP243X_SMS_BASE));
 	omap2_control_base_init();
 	omap2xxx_check_revision();
-	omap2xxx_prm_init();
+	omap2_prcm_base_init();
 	omap2xxx_cm_init();
 	omap2xxx_voltagedomains_init();
 	omap243x_powerdomains_init();
@@ -453,7 +453,8 @@ void __init omap3_init_early(void)
 	omap2_control_base_init();
 	omap3xxx_check_revision();
 	omap3xxx_check_features();
-	omap3xxx_prm_init();
+	omap2_prcm_base_init();
+	omap3xxx_prm_init(NULL);
 	omap3xxx_cm_init();
 	omap3xxx_voltagedomains_init();
 	omap3xxx_powerdomains_init();
@@ -551,7 +552,7 @@ void __init ti814x_init_early(void)
 	omap2_control_base_init();
 	omap3xxx_check_revision();
 	ti81xx_check_features();
-	am33xx_prm_init();
+	omap2_prcm_base_init();
 	am33xx_cm_init();
 	omap3xxx_voltagedomains_init();
 	omap3xxx_powerdomains_init();
@@ -569,7 +570,7 @@ void __init ti816x_init_early(void)
 	omap2_control_base_init();
 	omap3xxx_check_revision();
 	ti81xx_check_features();
-	am33xx_prm_init();
+	omap2_prcm_base_init();
 	am33xx_cm_init();
 	omap3xxx_voltagedomains_init();
 	omap3xxx_powerdomains_init();
@@ -589,7 +590,7 @@ void __init am33xx_init_early(void)
 	omap2_control_base_init();
 	omap3xxx_check_revision();
 	am33xx_check_features();
-	am33xx_prm_init();
+	omap2_prcm_base_init();
 	am33xx_cm_init();
 	am33xx_powerdomains_init();
 	am33xx_clockdomains_init();
@@ -612,7 +613,7 @@ void __init am43xx_init_early(void)
 	omap2_control_base_init();
 	omap3xxx_check_revision();
 	am33xx_check_features();
-	omap44xx_prm_init();
+	omap2_prcm_base_init();
 	omap4_cm_init();
 	am43xx_powerdomains_init();
 	am43xx_clockdomains_init();
@@ -638,7 +639,7 @@ void __init omap4430_init_early(void)
 	omap2_set_globals_prcm_mpu(OMAP2_L4_IO_ADDRESS(OMAP4430_PRCM_MPU_BASE));
 	omap4xxx_check_revision();
 	omap4xxx_check_features();
-	omap44xx_prm_init();
+	omap2_prcm_base_init();
 	omap4_cm_init();
 	omap4_pm_init_early();
 	omap44xx_voltagedomains_init();
@@ -667,7 +668,7 @@ void __init omap5_init_early(void)
 				  OMAP2_L4_IO_ADDRESS(OMAP54XX_CTRL_BASE));
 	omap2_set_globals_prcm_mpu(OMAP2_L4_IO_ADDRESS(OMAP54XX_PRCM_MPU_BASE));
 	omap4_pm_init_early();
-	omap44xx_prm_init();
+	omap2_prcm_base_init();
 	omap5xxx_check_revision();
 	omap4_cm_init();
 	omap54xx_voltagedomains_init();
@@ -694,7 +695,7 @@ void __init dra7xx_init_early(void)
 				  OMAP2_L4_IO_ADDRESS(DRA7XX_CTRL_BASE));
 	omap2_set_globals_prcm_mpu(OMAP2_L4_IO_ADDRESS(OMAP54XX_PRCM_MPU_BASE));
 	omap4_pm_init_early();
-	omap44xx_prm_init();
+	omap2_prcm_base_init();
 	dra7xxx_check_revision();
 	omap4_cm_init();
 	dra7xx_powerdomains_init();
diff --git a/arch/arm/mach-omap2/prcm-common.h b/arch/arm/mach-omap2/prcm-common.h
index 9e4dd0b..461bdc4 100644
--- a/arch/arm/mach-omap2/prcm-common.h
+++ b/arch/arm/mach-omap2/prcm-common.h
@@ -524,12 +524,16 @@ struct omap_prcm_irq_setup {
  * @mem: IO mem pointer for this module
  * @offset: module base address offset from the IO base
  * @flags: PRCM module init flags
+ * @init: low level PRCM init function for this module
+ * @np: device node for this PRCM module
  */
 struct omap_prcm_init_data {
 	int index;
 	void __iomem *mem;
 	s16 offset;
 	u16 flags;
+	int (*init)(const struct omap_prcm_init_data *data);
+	struct device_node *np;
 };
 
 extern void omap_prcm_irq_cleanup(void);
diff --git a/arch/arm/mach-omap2/prm.h b/arch/arm/mach-omap2/prm.h
index 6707333..3936e6c 100644
--- a/arch/arm/mach-omap2/prm.h
+++ b/arch/arm/mach-omap2/prm.h
@@ -21,6 +21,7 @@ extern u16 prm_features;
 extern void omap2_set_globals_prm(void __iomem *prm);
 int omap_prcm_init(void);
 int omap2_prm_base_init(void);
+int omap2_prcm_base_init(void);
 # endif
 
 /*
diff --git a/arch/arm/mach-omap2/prm2xxx.c b/arch/arm/mach-omap2/prm2xxx.c
index 29e203f..752018ce 100644
--- a/arch/arm/mach-omap2/prm2xxx.c
+++ b/arch/arm/mach-omap2/prm2xxx.c
@@ -220,9 +220,8 @@ static struct prm_ll_data omap2xxx_prm_ll_data = {
 	.clear_mod_irqs = &omap2xxx_prm_clear_mod_irqs,
 };
 
-int __init omap2xxx_prm_init(void)
+int __init omap2xxx_prm_init(const struct omap_prcm_init_data *data)
 {
-	omap2_prm_base_init();
 	return prm_register(&omap2xxx_prm_ll_data);
 }
 
diff --git a/arch/arm/mach-omap2/prm2xxx.h b/arch/arm/mach-omap2/prm2xxx.h
index 9c91f4f..9008a9e 100644
--- a/arch/arm/mach-omap2/prm2xxx.h
+++ b/arch/arm/mach-omap2/prm2xxx.h
@@ -124,7 +124,7 @@
 extern int omap2xxx_clkdm_sleep(struct clockdomain *clkdm);
 extern int omap2xxx_clkdm_wakeup(struct clockdomain *clkdm);
 
-extern int __init omap2xxx_prm_init(void);
+int __init omap2xxx_prm_init(const struct omap_prcm_init_data *data);
 
 #endif
 
diff --git a/arch/arm/mach-omap2/prm33xx.c b/arch/arm/mach-omap2/prm33xx.c
index 1e052aa..dcb5001 100644
--- a/arch/arm/mach-omap2/prm33xx.c
+++ b/arch/arm/mach-omap2/prm33xx.c
@@ -378,9 +378,8 @@ static struct prm_ll_data am33xx_prm_ll_data = {
 	.reset_system			= am33xx_prm_global_warm_sw_reset,
 };
 
-int __init am33xx_prm_init(void)
+int __init am33xx_prm_init(const struct omap_prcm_init_data *data)
 {
-	omap2_prm_base_init();
 	return prm_register(&am33xx_prm_ll_data);
 }
 
diff --git a/arch/arm/mach-omap2/prm33xx.h b/arch/arm/mach-omap2/prm33xx.h
index 98ac41f..2bc4ec5 100644
--- a/arch/arm/mach-omap2/prm33xx.h
+++ b/arch/arm/mach-omap2/prm33xx.h
@@ -118,7 +118,7 @@
 #define AM33XX_PM_CEFUSE_PWRSTST		AM33XX_PRM_REGADDR(AM33XX_PRM_CEFUSE_MOD, 0x0004)
 
 #ifndef __ASSEMBLER__
-int am33xx_prm_init(void);
+int am33xx_prm_init(const struct omap_prcm_init_data *data);
 
 #endif /* ASSEMBLER */
 #endif
diff --git a/arch/arm/mach-omap2/prm3xxx.c b/arch/arm/mach-omap2/prm3xxx.c
index a347993..62680aa 100644
--- a/arch/arm/mach-omap2/prm3xxx.c
+++ b/arch/arm/mach-omap2/prm3xxx.c
@@ -670,12 +670,10 @@ static struct prm_ll_data omap3xxx_prm_ll_data = {
 	.vp_clear_txdone = &omap3_prm_vp_clear_txdone,
 };
 
-int __init omap3xxx_prm_init(void)
+int __init omap3xxx_prm_init(const struct omap_prcm_init_data *data)
 {
 	omap2_clk_legacy_provider_init(TI_CLKM_PRM,
 				       prm_base + OMAP3430_IVA2_MOD);
-	omap2_prm_base_init();
-
 	if (omap3_has_io_wakeup())
 		prm_features |= PRM_HAS_IO_WAKEUP;
 
diff --git a/arch/arm/mach-omap2/prm3xxx.h b/arch/arm/mach-omap2/prm3xxx.h
index 55e4c89..5f095ee 100644
--- a/arch/arm/mach-omap2/prm3xxx.h
+++ b/arch/arm/mach-omap2/prm3xxx.h
@@ -140,7 +140,7 @@ extern u32 omap3_prm_vcvp_read(u8 offset);
 extern void omap3_prm_vcvp_write(u32 val, u8 offset);
 extern u32 omap3_prm_vcvp_rmw(u32 mask, u32 bits, u8 offset);
 
-extern int __init omap3xxx_prm_init(void);
+int __init omap3xxx_prm_init(const struct omap_prcm_init_data *data);
 void omap3xxx_prm_iva_idle(void);
 void omap3_prm_reset_modem(void);
 int omap3xxx_prm_clear_global_cold_reset(void);
diff --git a/arch/arm/mach-omap2/prm44xx.c b/arch/arm/mach-omap2/prm44xx.c
index b479a33..e3f2d31 100644
--- a/arch/arm/mach-omap2/prm44xx.c
+++ b/arch/arm/mach-omap2/prm44xx.c
@@ -703,9 +703,8 @@ static struct prm_ll_data omap44xx_prm_ll_data = {
 	.vp_clear_txdone	= omap4_prm_vp_clear_txdone,
 };
 
-int __init omap44xx_prm_init(void)
+int __init omap44xx_prm_init(const struct omap_prcm_init_data *data)
 {
-	omap2_prm_base_init();
 	omap_prm_base_init();
 
 	if (cpu_is_omap44xx() || soc_is_omap54xx() || soc_is_dra7xx())
diff --git a/arch/arm/mach-omap2/prm44xx.h b/arch/arm/mach-omap2/prm44xx.h
index 7db2422..efd6035 100644
--- a/arch/arm/mach-omap2/prm44xx.h
+++ b/arch/arm/mach-omap2/prm44xx.h
@@ -26,7 +26,6 @@
 #define __ARCH_ARM_MACH_OMAP2_PRM44XX_H
 
 #include "prm44xx_54xx.h"
-#include "prcm-common.h"
 #include "prm.h"
 
 #define OMAP4430_PRM_BASE		0x4a306000
diff --git a/arch/arm/mach-omap2/prm44xx_54xx.h b/arch/arm/mach-omap2/prm44xx_54xx.h
index a470185..3f139eb 100644
--- a/arch/arm/mach-omap2/prm44xx_54xx.h
+++ b/arch/arm/mach-omap2/prm44xx_54xx.h
@@ -23,6 +23,8 @@
 #ifndef __ARCH_ARM_MACH_OMAP2_PRM44XX_54XX_H
 #define __ARCH_ARM_MACH_OMAP2_PRM44XX_54XX_H
 
+#include "prcm-common.h"
+
 /* Function prototypes */
 #ifndef __ASSEMBLER__
 
@@ -34,7 +36,7 @@ extern u32 omap4_prm_vcvp_read(u8 offset);
 extern void omap4_prm_vcvp_write(u32 val, u8 offset);
 extern u32 omap4_prm_vcvp_rmw(u32 mask, u32 bits, u8 offset);
 
-extern int __init omap44xx_prm_init(void);
+int __init omap44xx_prm_init(const struct omap_prcm_init_data *data);
 
 #endif
 
diff --git a/arch/arm/mach-omap2/prm54xx.h b/arch/arm/mach-omap2/prm54xx.h
index e441101..1eb22ff 100644
--- a/arch/arm/mach-omap2/prm54xx.h
+++ b/arch/arm/mach-omap2/prm54xx.h
@@ -22,7 +22,6 @@
 #define __ARCH_ARM_MACH_OMAP2_PRM54XX_H
 
 #include "prm44xx_54xx.h"
-#include "prcm-common.h"
 #include "prm.h"
 
 #define OMAP54XX_PRM_BASE		0x4ae06000
diff --git a/arch/arm/mach-omap2/prm7xx.h b/arch/arm/mach-omap2/prm7xx.h
index 4bb50fbf..cc1e6a2 100644
--- a/arch/arm/mach-omap2/prm7xx.h
+++ b/arch/arm/mach-omap2/prm7xx.h
@@ -22,8 +22,8 @@
 #ifndef __ARCH_ARM_MACH_OMAP2_PRM7XX_H
 #define __ARCH_ARM_MACH_OMAP2_PRM7XX_H
 
-#include "prm44xx_54xx.h"
 #include "prcm-common.h"
+#include "prm44xx_54xx.h"
 #include "prm.h"
 
 #define DRA7XX_PRM_BASE		0x4ae06000
diff --git a/arch/arm/mach-omap2/prm_common.c b/arch/arm/mach-omap2/prm_common.c
index a943e14..7c1ad89 100644
--- a/arch/arm/mach-omap2/prm_common.c
+++ b/arch/arm/mach-omap2/prm_common.c
@@ -32,6 +32,7 @@
 #include "prm2xxx_3xxx.h"
 #include "prm2xxx.h"
 #include "prm3xxx.h"
+#include "prm33xx.h"
 #include "prm44xx.h"
 #include "common.h"
 #include "clock.h"
@@ -633,12 +634,14 @@ int prm_unregister(struct prm_ll_data *pld)
 	return 0;
 }
 
-static struct omap_prcm_init_data prm_data = {
+static struct omap_prcm_init_data omap2_prm_data __initdata = {
 	.index = TI_CLKM_PRM,
+	.init = omap2xxx_prm_init,
 };
 
-static struct omap_prcm_init_data omap3_prm_data = {
+static struct omap_prcm_init_data omap3_prm_data __initdata = {
 	.index = TI_CLKM_PRM,
+	.init = omap3xxx_prm_init,
 
 	/*
 	 * IVA2 offset is a negative value, must offset the prm_base
@@ -647,22 +650,32 @@ static struct omap_prcm_init_data omap3_prm_data = {
 	.offset = -OMAP3430_IVA2_MOD,
 };
 
-static struct omap_prcm_init_data scrm_data = {
+static struct omap_prcm_init_data am3_prm_data __initdata = {
+	.index = TI_CLKM_PRM,
+	.init = am33xx_prm_init,
+};
+
+static struct omap_prcm_init_data omap4_prm_data __initdata = {
+	.index = TI_CLKM_PRM,
+	.init = omap44xx_prm_init,
+};
+
+static struct omap_prcm_init_data scrm_data __initdata = {
 	.index = TI_CLKM_SCRM,
 };
 
-static const struct of_device_id omap_prcm_dt_match_table[] = {
-	{ .compatible = "ti,am3-prcm", .data = &prm_data },
-	{ .compatible = "ti,am4-prcm", .data = &prm_data },
-	{ .compatible = "ti,dm814-prcm", .data = &prm_data },
-	{ .compatible = "ti,dm816-prcm", .data = &prm_data },
-	{ .compatible = "ti,omap2-prcm", .data = &prm_data },
+static const struct of_device_id omap_prcm_dt_match_table[] __initconst = {
+	{ .compatible = "ti,am3-prcm", .data = &am3_prm_data },
+	{ .compatible = "ti,am4-prcm", .data = &omap4_prm_data },
+	{ .compatible = "ti,dm814-prcm", .data = &am3_prm_data },
+	{ .compatible = "ti,dm816-prcm", .data = &am3_prm_data },
+	{ .compatible = "ti,omap2-prcm", .data = &omap2_prm_data },
 	{ .compatible = "ti,omap3-prm", .data = &omap3_prm_data },
-	{ .compatible = "ti,omap4-prm", .data = &prm_data },
+	{ .compatible = "ti,omap4-prm", .data = &omap4_prm_data },
 	{ .compatible = "ti,omap4-scrm", .data = &scrm_data },
-	{ .compatible = "ti,omap5-prm", .data = &prm_data },
+	{ .compatible = "ti,omap5-prm", .data = &omap4_prm_data },
 	{ .compatible = "ti,omap5-scrm", .data = &scrm_data },
-	{ .compatible = "ti,dra7-prm", .data = &prm_data },
+	{ .compatible = "ti,dra7-prm", .data = &omap4_prm_data },
 	{ }
 };
 
@@ -691,11 +704,21 @@ int __init omap2_prm_base_init(void)
 			prm_base = mem + data->offset;
 
 		data->mem = mem;
+
+		data->np = np;
+
+		if (data->init)
+			data->init(data);
 	}
 
 	return 0;
 }
 
+int __init omap2_prcm_base_init(void)
+{
+	return omap2_prm_base_init();
+}
+
 /**
  * omap_prcm_init - low level init for the PRCM drivers
  *
-- 
1.7.9.5


WARNING: multiple messages have this Message-ID (diff)
From: t-kristo@ti.com (Tero Kristo)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCHv3 16/35] ARM: OMAP2+: PRM: move SoC specific init calls within a generic API
Date: Wed, 25 Feb 2015 21:04:26 +0200	[thread overview]
Message-ID: <1424891085-10392-17-git-send-email-t-kristo@ti.com> (raw)
In-Reply-To: <1424891085-10392-1-git-send-email-t-kristo@ti.com>

This gets rid of need for some exported driver APIs, and simplifies the
initialization of the PRM driver. Done in preparation to make PRM a
separate driver. The init data is now also passed to the SoC specific
implementations, allowing future expansion to add feature flags etc.

Signed-off-by: Tero Kristo <t-kristo@ti.com>
---
 arch/arm/mach-omap2/io.c           |   21 ++++++++--------
 arch/arm/mach-omap2/prcm-common.h  |    4 +++
 arch/arm/mach-omap2/prm.h          |    1 +
 arch/arm/mach-omap2/prm2xxx.c      |    3 +--
 arch/arm/mach-omap2/prm2xxx.h      |    2 +-
 arch/arm/mach-omap2/prm33xx.c      |    3 +--
 arch/arm/mach-omap2/prm33xx.h      |    2 +-
 arch/arm/mach-omap2/prm3xxx.c      |    4 +--
 arch/arm/mach-omap2/prm3xxx.h      |    2 +-
 arch/arm/mach-omap2/prm44xx.c      |    3 +--
 arch/arm/mach-omap2/prm44xx.h      |    1 -
 arch/arm/mach-omap2/prm44xx_54xx.h |    4 ++-
 arch/arm/mach-omap2/prm54xx.h      |    1 -
 arch/arm/mach-omap2/prm7xx.h       |    2 +-
 arch/arm/mach-omap2/prm_common.c   |   47 +++++++++++++++++++++++++++---------
 15 files changed, 62 insertions(+), 38 deletions(-)

diff --git a/arch/arm/mach-omap2/io.c b/arch/arm/mach-omap2/io.c
index 622ee3b..7632dfe 100644
--- a/arch/arm/mach-omap2/io.c
+++ b/arch/arm/mach-omap2/io.c
@@ -386,7 +386,7 @@ void __init omap2420_init_early(void)
 			       OMAP2_L3_IO_ADDRESS(OMAP2420_SMS_BASE));
 	omap2_control_base_init();
 	omap2xxx_check_revision();
-	omap2xxx_prm_init();
+	omap2_prcm_base_init();
 	omap2xxx_cm_init();
 	omap2xxx_voltagedomains_init();
 	omap242x_powerdomains_init();
@@ -413,7 +413,7 @@ void __init omap2430_init_early(void)
 			       OMAP2_L3_IO_ADDRESS(OMAP243X_SMS_BASE));
 	omap2_control_base_init();
 	omap2xxx_check_revision();
-	omap2xxx_prm_init();
+	omap2_prcm_base_init();
 	omap2xxx_cm_init();
 	omap2xxx_voltagedomains_init();
 	omap243x_powerdomains_init();
@@ -453,7 +453,8 @@ void __init omap3_init_early(void)
 	omap2_control_base_init();
 	omap3xxx_check_revision();
 	omap3xxx_check_features();
-	omap3xxx_prm_init();
+	omap2_prcm_base_init();
+	omap3xxx_prm_init(NULL);
 	omap3xxx_cm_init();
 	omap3xxx_voltagedomains_init();
 	omap3xxx_powerdomains_init();
@@ -551,7 +552,7 @@ void __init ti814x_init_early(void)
 	omap2_control_base_init();
 	omap3xxx_check_revision();
 	ti81xx_check_features();
-	am33xx_prm_init();
+	omap2_prcm_base_init();
 	am33xx_cm_init();
 	omap3xxx_voltagedomains_init();
 	omap3xxx_powerdomains_init();
@@ -569,7 +570,7 @@ void __init ti816x_init_early(void)
 	omap2_control_base_init();
 	omap3xxx_check_revision();
 	ti81xx_check_features();
-	am33xx_prm_init();
+	omap2_prcm_base_init();
 	am33xx_cm_init();
 	omap3xxx_voltagedomains_init();
 	omap3xxx_powerdomains_init();
@@ -589,7 +590,7 @@ void __init am33xx_init_early(void)
 	omap2_control_base_init();
 	omap3xxx_check_revision();
 	am33xx_check_features();
-	am33xx_prm_init();
+	omap2_prcm_base_init();
 	am33xx_cm_init();
 	am33xx_powerdomains_init();
 	am33xx_clockdomains_init();
@@ -612,7 +613,7 @@ void __init am43xx_init_early(void)
 	omap2_control_base_init();
 	omap3xxx_check_revision();
 	am33xx_check_features();
-	omap44xx_prm_init();
+	omap2_prcm_base_init();
 	omap4_cm_init();
 	am43xx_powerdomains_init();
 	am43xx_clockdomains_init();
@@ -638,7 +639,7 @@ void __init omap4430_init_early(void)
 	omap2_set_globals_prcm_mpu(OMAP2_L4_IO_ADDRESS(OMAP4430_PRCM_MPU_BASE));
 	omap4xxx_check_revision();
 	omap4xxx_check_features();
-	omap44xx_prm_init();
+	omap2_prcm_base_init();
 	omap4_cm_init();
 	omap4_pm_init_early();
 	omap44xx_voltagedomains_init();
@@ -667,7 +668,7 @@ void __init omap5_init_early(void)
 				  OMAP2_L4_IO_ADDRESS(OMAP54XX_CTRL_BASE));
 	omap2_set_globals_prcm_mpu(OMAP2_L4_IO_ADDRESS(OMAP54XX_PRCM_MPU_BASE));
 	omap4_pm_init_early();
-	omap44xx_prm_init();
+	omap2_prcm_base_init();
 	omap5xxx_check_revision();
 	omap4_cm_init();
 	omap54xx_voltagedomains_init();
@@ -694,7 +695,7 @@ void __init dra7xx_init_early(void)
 				  OMAP2_L4_IO_ADDRESS(DRA7XX_CTRL_BASE));
 	omap2_set_globals_prcm_mpu(OMAP2_L4_IO_ADDRESS(OMAP54XX_PRCM_MPU_BASE));
 	omap4_pm_init_early();
-	omap44xx_prm_init();
+	omap2_prcm_base_init();
 	dra7xxx_check_revision();
 	omap4_cm_init();
 	dra7xx_powerdomains_init();
diff --git a/arch/arm/mach-omap2/prcm-common.h b/arch/arm/mach-omap2/prcm-common.h
index 9e4dd0b..461bdc4 100644
--- a/arch/arm/mach-omap2/prcm-common.h
+++ b/arch/arm/mach-omap2/prcm-common.h
@@ -524,12 +524,16 @@ struct omap_prcm_irq_setup {
  * @mem: IO mem pointer for this module
  * @offset: module base address offset from the IO base
  * @flags: PRCM module init flags
+ * @init: low level PRCM init function for this module
+ * @np: device node for this PRCM module
  */
 struct omap_prcm_init_data {
 	int index;
 	void __iomem *mem;
 	s16 offset;
 	u16 flags;
+	int (*init)(const struct omap_prcm_init_data *data);
+	struct device_node *np;
 };
 
 extern void omap_prcm_irq_cleanup(void);
diff --git a/arch/arm/mach-omap2/prm.h b/arch/arm/mach-omap2/prm.h
index 6707333..3936e6c 100644
--- a/arch/arm/mach-omap2/prm.h
+++ b/arch/arm/mach-omap2/prm.h
@@ -21,6 +21,7 @@ extern u16 prm_features;
 extern void omap2_set_globals_prm(void __iomem *prm);
 int omap_prcm_init(void);
 int omap2_prm_base_init(void);
+int omap2_prcm_base_init(void);
 # endif
 
 /*
diff --git a/arch/arm/mach-omap2/prm2xxx.c b/arch/arm/mach-omap2/prm2xxx.c
index 29e203f..752018ce 100644
--- a/arch/arm/mach-omap2/prm2xxx.c
+++ b/arch/arm/mach-omap2/prm2xxx.c
@@ -220,9 +220,8 @@ static struct prm_ll_data omap2xxx_prm_ll_data = {
 	.clear_mod_irqs = &omap2xxx_prm_clear_mod_irqs,
 };
 
-int __init omap2xxx_prm_init(void)
+int __init omap2xxx_prm_init(const struct omap_prcm_init_data *data)
 {
-	omap2_prm_base_init();
 	return prm_register(&omap2xxx_prm_ll_data);
 }
 
diff --git a/arch/arm/mach-omap2/prm2xxx.h b/arch/arm/mach-omap2/prm2xxx.h
index 9c91f4f..9008a9e 100644
--- a/arch/arm/mach-omap2/prm2xxx.h
+++ b/arch/arm/mach-omap2/prm2xxx.h
@@ -124,7 +124,7 @@
 extern int omap2xxx_clkdm_sleep(struct clockdomain *clkdm);
 extern int omap2xxx_clkdm_wakeup(struct clockdomain *clkdm);
 
-extern int __init omap2xxx_prm_init(void);
+int __init omap2xxx_prm_init(const struct omap_prcm_init_data *data);
 
 #endif
 
diff --git a/arch/arm/mach-omap2/prm33xx.c b/arch/arm/mach-omap2/prm33xx.c
index 1e052aa..dcb5001 100644
--- a/arch/arm/mach-omap2/prm33xx.c
+++ b/arch/arm/mach-omap2/prm33xx.c
@@ -378,9 +378,8 @@ static struct prm_ll_data am33xx_prm_ll_data = {
 	.reset_system			= am33xx_prm_global_warm_sw_reset,
 };
 
-int __init am33xx_prm_init(void)
+int __init am33xx_prm_init(const struct omap_prcm_init_data *data)
 {
-	omap2_prm_base_init();
 	return prm_register(&am33xx_prm_ll_data);
 }
 
diff --git a/arch/arm/mach-omap2/prm33xx.h b/arch/arm/mach-omap2/prm33xx.h
index 98ac41f..2bc4ec5 100644
--- a/arch/arm/mach-omap2/prm33xx.h
+++ b/arch/arm/mach-omap2/prm33xx.h
@@ -118,7 +118,7 @@
 #define AM33XX_PM_CEFUSE_PWRSTST		AM33XX_PRM_REGADDR(AM33XX_PRM_CEFUSE_MOD, 0x0004)
 
 #ifndef __ASSEMBLER__
-int am33xx_prm_init(void);
+int am33xx_prm_init(const struct omap_prcm_init_data *data);
 
 #endif /* ASSEMBLER */
 #endif
diff --git a/arch/arm/mach-omap2/prm3xxx.c b/arch/arm/mach-omap2/prm3xxx.c
index a347993..62680aa 100644
--- a/arch/arm/mach-omap2/prm3xxx.c
+++ b/arch/arm/mach-omap2/prm3xxx.c
@@ -670,12 +670,10 @@ static struct prm_ll_data omap3xxx_prm_ll_data = {
 	.vp_clear_txdone = &omap3_prm_vp_clear_txdone,
 };
 
-int __init omap3xxx_prm_init(void)
+int __init omap3xxx_prm_init(const struct omap_prcm_init_data *data)
 {
 	omap2_clk_legacy_provider_init(TI_CLKM_PRM,
 				       prm_base + OMAP3430_IVA2_MOD);
-	omap2_prm_base_init();
-
 	if (omap3_has_io_wakeup())
 		prm_features |= PRM_HAS_IO_WAKEUP;
 
diff --git a/arch/arm/mach-omap2/prm3xxx.h b/arch/arm/mach-omap2/prm3xxx.h
index 55e4c89..5f095ee 100644
--- a/arch/arm/mach-omap2/prm3xxx.h
+++ b/arch/arm/mach-omap2/prm3xxx.h
@@ -140,7 +140,7 @@ extern u32 omap3_prm_vcvp_read(u8 offset);
 extern void omap3_prm_vcvp_write(u32 val, u8 offset);
 extern u32 omap3_prm_vcvp_rmw(u32 mask, u32 bits, u8 offset);
 
-extern int __init omap3xxx_prm_init(void);
+int __init omap3xxx_prm_init(const struct omap_prcm_init_data *data);
 void omap3xxx_prm_iva_idle(void);
 void omap3_prm_reset_modem(void);
 int omap3xxx_prm_clear_global_cold_reset(void);
diff --git a/arch/arm/mach-omap2/prm44xx.c b/arch/arm/mach-omap2/prm44xx.c
index b479a33..e3f2d31 100644
--- a/arch/arm/mach-omap2/prm44xx.c
+++ b/arch/arm/mach-omap2/prm44xx.c
@@ -703,9 +703,8 @@ static struct prm_ll_data omap44xx_prm_ll_data = {
 	.vp_clear_txdone	= omap4_prm_vp_clear_txdone,
 };
 
-int __init omap44xx_prm_init(void)
+int __init omap44xx_prm_init(const struct omap_prcm_init_data *data)
 {
-	omap2_prm_base_init();
 	omap_prm_base_init();
 
 	if (cpu_is_omap44xx() || soc_is_omap54xx() || soc_is_dra7xx())
diff --git a/arch/arm/mach-omap2/prm44xx.h b/arch/arm/mach-omap2/prm44xx.h
index 7db2422..efd6035 100644
--- a/arch/arm/mach-omap2/prm44xx.h
+++ b/arch/arm/mach-omap2/prm44xx.h
@@ -26,7 +26,6 @@
 #define __ARCH_ARM_MACH_OMAP2_PRM44XX_H
 
 #include "prm44xx_54xx.h"
-#include "prcm-common.h"
 #include "prm.h"
 
 #define OMAP4430_PRM_BASE		0x4a306000
diff --git a/arch/arm/mach-omap2/prm44xx_54xx.h b/arch/arm/mach-omap2/prm44xx_54xx.h
index a470185..3f139eb 100644
--- a/arch/arm/mach-omap2/prm44xx_54xx.h
+++ b/arch/arm/mach-omap2/prm44xx_54xx.h
@@ -23,6 +23,8 @@
 #ifndef __ARCH_ARM_MACH_OMAP2_PRM44XX_54XX_H
 #define __ARCH_ARM_MACH_OMAP2_PRM44XX_54XX_H
 
+#include "prcm-common.h"
+
 /* Function prototypes */
 #ifndef __ASSEMBLER__
 
@@ -34,7 +36,7 @@ extern u32 omap4_prm_vcvp_read(u8 offset);
 extern void omap4_prm_vcvp_write(u32 val, u8 offset);
 extern u32 omap4_prm_vcvp_rmw(u32 mask, u32 bits, u8 offset);
 
-extern int __init omap44xx_prm_init(void);
+int __init omap44xx_prm_init(const struct omap_prcm_init_data *data);
 
 #endif
 
diff --git a/arch/arm/mach-omap2/prm54xx.h b/arch/arm/mach-omap2/prm54xx.h
index e441101..1eb22ff 100644
--- a/arch/arm/mach-omap2/prm54xx.h
+++ b/arch/arm/mach-omap2/prm54xx.h
@@ -22,7 +22,6 @@
 #define __ARCH_ARM_MACH_OMAP2_PRM54XX_H
 
 #include "prm44xx_54xx.h"
-#include "prcm-common.h"
 #include "prm.h"
 
 #define OMAP54XX_PRM_BASE		0x4ae06000
diff --git a/arch/arm/mach-omap2/prm7xx.h b/arch/arm/mach-omap2/prm7xx.h
index 4bb50fbf..cc1e6a2 100644
--- a/arch/arm/mach-omap2/prm7xx.h
+++ b/arch/arm/mach-omap2/prm7xx.h
@@ -22,8 +22,8 @@
 #ifndef __ARCH_ARM_MACH_OMAP2_PRM7XX_H
 #define __ARCH_ARM_MACH_OMAP2_PRM7XX_H
 
-#include "prm44xx_54xx.h"
 #include "prcm-common.h"
+#include "prm44xx_54xx.h"
 #include "prm.h"
 
 #define DRA7XX_PRM_BASE		0x4ae06000
diff --git a/arch/arm/mach-omap2/prm_common.c b/arch/arm/mach-omap2/prm_common.c
index a943e14..7c1ad89 100644
--- a/arch/arm/mach-omap2/prm_common.c
+++ b/arch/arm/mach-omap2/prm_common.c
@@ -32,6 +32,7 @@
 #include "prm2xxx_3xxx.h"
 #include "prm2xxx.h"
 #include "prm3xxx.h"
+#include "prm33xx.h"
 #include "prm44xx.h"
 #include "common.h"
 #include "clock.h"
@@ -633,12 +634,14 @@ int prm_unregister(struct prm_ll_data *pld)
 	return 0;
 }
 
-static struct omap_prcm_init_data prm_data = {
+static struct omap_prcm_init_data omap2_prm_data __initdata = {
 	.index = TI_CLKM_PRM,
+	.init = omap2xxx_prm_init,
 };
 
-static struct omap_prcm_init_data omap3_prm_data = {
+static struct omap_prcm_init_data omap3_prm_data __initdata = {
 	.index = TI_CLKM_PRM,
+	.init = omap3xxx_prm_init,
 
 	/*
 	 * IVA2 offset is a negative value, must offset the prm_base
@@ -647,22 +650,32 @@ static struct omap_prcm_init_data omap3_prm_data = {
 	.offset = -OMAP3430_IVA2_MOD,
 };
 
-static struct omap_prcm_init_data scrm_data = {
+static struct omap_prcm_init_data am3_prm_data __initdata = {
+	.index = TI_CLKM_PRM,
+	.init = am33xx_prm_init,
+};
+
+static struct omap_prcm_init_data omap4_prm_data __initdata = {
+	.index = TI_CLKM_PRM,
+	.init = omap44xx_prm_init,
+};
+
+static struct omap_prcm_init_data scrm_data __initdata = {
 	.index = TI_CLKM_SCRM,
 };
 
-static const struct of_device_id omap_prcm_dt_match_table[] = {
-	{ .compatible = "ti,am3-prcm", .data = &prm_data },
-	{ .compatible = "ti,am4-prcm", .data = &prm_data },
-	{ .compatible = "ti,dm814-prcm", .data = &prm_data },
-	{ .compatible = "ti,dm816-prcm", .data = &prm_data },
-	{ .compatible = "ti,omap2-prcm", .data = &prm_data },
+static const struct of_device_id omap_prcm_dt_match_table[] __initconst = {
+	{ .compatible = "ti,am3-prcm", .data = &am3_prm_data },
+	{ .compatible = "ti,am4-prcm", .data = &omap4_prm_data },
+	{ .compatible = "ti,dm814-prcm", .data = &am3_prm_data },
+	{ .compatible = "ti,dm816-prcm", .data = &am3_prm_data },
+	{ .compatible = "ti,omap2-prcm", .data = &omap2_prm_data },
 	{ .compatible = "ti,omap3-prm", .data = &omap3_prm_data },
-	{ .compatible = "ti,omap4-prm", .data = &prm_data },
+	{ .compatible = "ti,omap4-prm", .data = &omap4_prm_data },
 	{ .compatible = "ti,omap4-scrm", .data = &scrm_data },
-	{ .compatible = "ti,omap5-prm", .data = &prm_data },
+	{ .compatible = "ti,omap5-prm", .data = &omap4_prm_data },
 	{ .compatible = "ti,omap5-scrm", .data = &scrm_data },
-	{ .compatible = "ti,dra7-prm", .data = &prm_data },
+	{ .compatible = "ti,dra7-prm", .data = &omap4_prm_data },
 	{ }
 };
 
@@ -691,11 +704,21 @@ int __init omap2_prm_base_init(void)
 			prm_base = mem + data->offset;
 
 		data->mem = mem;
+
+		data->np = np;
+
+		if (data->init)
+			data->init(data);
 	}
 
 	return 0;
 }
 
+int __init omap2_prcm_base_init(void)
+{
+	return omap2_prm_base_init();
+}
+
 /**
  * omap_prcm_init - low level init for the PRCM drivers
  *
-- 
1.7.9.5

  parent reply	other threads:[~2015-02-25 19:05 UTC|newest]

Thread overview: 100+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-02-25 19:04 [PATCHv3 00/35] ARM: OMAP2+: PRCM / SCM cleanups against 4.0-rc1 Tero Kristo
2015-02-25 19:04 ` Tero Kristo
2015-02-25 19:04 ` [PATCHv3 01/35] ARM: OMAP2+: PRCM: rename of_prcm_init to omap_prcm_init Tero Kristo
2015-02-25 19:04   ` Tero Kristo
2015-02-25 19:04 ` [PATCHv3 02/35] ARM: OMAP3: PRM: invert the wkst_mask for the prm_clear_mod_irqs Tero Kristo
2015-02-25 19:04   ` Tero Kristo
2015-02-25 19:04 ` [PATCHv3 03/35] ARM: OMAP2+: PRM: add generic API for clear_mod_irqs Tero Kristo
2015-02-25 19:04   ` Tero Kristo
2015-02-25 19:08   ` Felipe Balbi
2015-02-25 19:08     ` Felipe Balbi
2015-02-25 19:04 ` [PATCHv3 04/35] ARM: OMAP3+: PRM: add common APIs for prm_vp_check/clear_txdone Tero Kristo
2015-02-25 19:04   ` Tero Kristo
2015-02-25 19:09   ` Felipe Balbi
2015-02-25 19:09     ` Felipe Balbi
2015-02-25 19:44     ` Tero Kristo
2015-02-25 19:44       ` Tero Kristo
2015-02-25 19:04 ` [PATCHv3 05/35] ARM: OMAP4+: PRM: move omap_prm_base_init under OMAP4 PRM driver Tero Kristo
2015-02-25 19:04   ` Tero Kristo
2015-02-25 19:04 ` [PATCHv3 06/35] ARM: OMAP4+: CM: move omap_cm_base_init under OMAP4 CM driver Tero Kristo
2015-02-25 19:04   ` Tero Kristo
2015-02-25 19:04 ` [PATCHv3 07/35] ARM: OMAP4: PRM: move omap4xxx_prm_init earlier in init order Tero Kristo
2015-02-25 19:04   ` Tero Kristo
2015-02-25 19:04 ` [PATCHv3 08/35] clk: ti: fix ti_clk_get_reg_addr error handling Tero Kristo
2015-02-25 19:04   ` Tero Kristo
2015-03-06 19:18   ` Mike Turquette
2015-03-06 19:18     ` Mike Turquette
2015-03-17 18:38     ` Tony Lindgren
2015-03-17 18:38       ` Tony Lindgren
2015-03-18  7:06       ` Tero Kristo
2015-03-18  7:06         ` Tero Kristo
2015-03-18 17:02         ` Tony Lindgren
2015-03-18 17:02           ` Tony Lindgren
2015-03-19  7:14           ` Tero Kristo
2015-03-19  7:14             ` Tero Kristo
2015-03-20  7:00     ` Tero Kristo
2015-03-20  7:00       ` Tero Kristo
2015-02-25 19:04 ` [PATCHv3 09/35] Documentation: DT: document PRCM compatible strings for dm81x SoCs Tero Kristo
2015-02-25 19:04   ` Tero Kristo
2015-02-25 19:04 ` [PATCHv3 10/35] ARM: OMAP2+: PRCM: add support for static clock memmap indices Tero Kristo
2015-02-25 19:04   ` Tero Kristo
2015-02-25 19:04 ` [PATCHv3 11/35] ARM: OMAP2+: clock: move clock provider infrastructure to clock driver Tero Kristo
2015-02-25 19:04   ` Tero Kristo
2015-02-25 19:04 ` [PATCHv3 12/35] ARM: OMAP2+: PRCM: split PRCM module init to their own driver files Tero Kristo
2015-02-25 19:04   ` Tero Kristo
2015-02-25 19:04 ` [PATCHv3 13/35] ARM: OMAP2+: CM: determine CM base address from device tree Tero Kristo
2015-02-25 19:04   ` Tero Kristo
2015-02-25 19:04 ` [PATCHv3 14/35] ARM: OMAP2+: PRM: determine PRM " Tero Kristo
2015-02-25 19:04   ` Tero Kristo
2015-02-25 19:04 ` [PATCHv3 15/35] ARM: OMAP2+: control: determine control module base address from DT Tero Kristo
2015-02-25 19:04   ` Tero Kristo
2015-02-25 19:04 ` Tero Kristo [this message]
2015-02-25 19:04   ` [PATCHv3 16/35] ARM: OMAP2+: PRM: move SoC specific init calls within a generic API Tero Kristo
2015-02-25 19:04 ` [PATCHv3 17/35] ARM: OMAP4+: PRM: determine prm_device_inst based on DT compatibility Tero Kristo
2015-02-25 19:04   ` Tero Kristo
2015-02-25 19:04 ` [PATCHv3 18/35] ARM: OMAP2+: CM: move SoC specific init calls within a generic API Tero Kristo
2015-02-25 19:04   ` Tero Kristo
2015-02-25 19:04 ` [PATCHv3 19/35] ARM: OMAP4+: PRM: setup prm_features from the PRM init time flags Tero Kristo
2015-02-25 19:04   ` Tero Kristo
2015-02-25 19:04 ` [PATCHv3 20/35] ARM: OMAP4+: PRM: get rid of cpu_is_omap44xx calls from interrupt init Tero Kristo
2015-02-25 19:04   ` Tero Kristo
2015-02-25 19:04 ` [PATCHv3 21/35] ARM: OMAP2+: clock: add low-level support for regmap Tero Kristo
2015-02-25 19:04   ` Tero Kristo
2015-02-25 19:04 ` [PATCHv3 22/35] ARM: OMAP2+: control: remove API for getting control module base address Tero Kristo
2015-02-25 19:04   ` Tero Kristo
2015-02-25 19:04 ` [PATCHv3 23/35] ARM: OMAP2+: id: cache omap_type value Tero Kristo
2015-02-25 19:04   ` Tero Kristo
2015-02-25 19:04 ` [PATCHv3 24/35] ARM: OMAP2+: control: add syscon support for register accesses Tero Kristo
2015-02-25 19:04   ` Tero Kristo
2015-02-25 19:04 ` [PATCHv3 25/35] ARM: dts: omap24xx: merge control module features under scrm node Tero Kristo
2015-02-25 19:04   ` Tero Kristo
2015-02-25 19:04 ` [PATCHv3 26/35] ARM: dts: omap3: " Tero Kristo
2015-02-25 19:04   ` Tero Kristo
2015-02-25 19:04 ` [PATCHv3 27/35] ARM: dts: am33xx: " Tero Kristo
2015-02-25 19:04   ` Tero Kristo
2015-02-25 19:04 ` [PATCHv3 28/35] ARM: dts: am43xx-epos-evm: fix pinmux node layout Tero Kristo
2015-02-25 19:04   ` Tero Kristo
2015-02-25 19:04 ` [PATCHv3 29/35] ARM: dts: am4372: merge control module features under scrm node Tero Kristo
2015-02-25 19:04   ` Tero Kristo
2015-02-25 19:04 ` [PATCHv3 30/35] ARM: dts: omap4: add system control module node Tero Kristo
2015-02-25 19:04   ` Tero Kristo
2015-02-25 19:04 ` [PATCHv3 31/35] ARM: OMAP4: display: convert display to use syscon for dsi muxing Tero Kristo
2015-02-25 19:04   ` Tero Kristo
2015-02-25 19:04 ` [PATCHv3 32/35] ARM: OMAP4+: control: remove support for legacy pad read/write Tero Kristo
2015-02-25 19:04   ` Tero Kristo
2015-02-25 19:04 ` [PATCHv3 33/35] ARM: dts: omap5: add system control module node Tero Kristo
2015-02-25 19:04   ` Tero Kristo
2015-02-25 19:04 ` [PATCHv3 34/35] ARM: dts: dra7: " Tero Kristo
2015-02-25 19:04   ` Tero Kristo
2015-03-11 17:17   ` Tony Lindgren
2015-03-11 17:17     ` Tony Lindgren
2015-03-11 19:08     ` Tero Kristo
2015-03-11 19:08       ` Tero Kristo
2015-03-11 19:26       ` Tony Lindgren
2015-03-11 19:26         ` Tony Lindgren
2015-03-11 19:57         ` Tero Kristo
2015-03-11 19:57           ` Tero Kristo
2015-03-11 21:00           ` Tony Lindgren
2015-03-11 21:00             ` Tony Lindgren
2015-02-25 19:04 ` [PATCHv3 35/35] ARM: OMAP4+: control: add support for initializing control module via DT Tero Kristo
2015-02-25 19:04   ` Tero Kristo

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1424891085-10392-17-git-send-email-t-kristo@ti.com \
    --to=t-kristo@ti.com \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-omap@vger.kernel.org \
    --cc=paul@pwsan.com \
    --cc=tony@atomide.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.