All of lore.kernel.org
 help / color / mirror / Atom feed
From: Sean Anderson <seanga2@gmail.com>
To: u-boot@lists.denx.de
Subject: [PATCH v9 14/21] riscv: Clean up IPI initialization code
Date: Wed, 22 Apr 2020 22:33:13 -0400	[thread overview]
Message-ID: <20200423023320.1380090-15-seanga2@gmail.com> (raw)
In-Reply-To: <20200423023320.1380090-1-seanga2@gmail.com>

The previous IPI code initialized the device whenever the first call was
made to a riscv_*_ipi function. This made it difficult to determine when
the IPI device was initialized. This patch introduces a new function
riscv_init_ipi. It is called once during arch_cpu_init_dm. Before this
point, no riscv_*_ipi functions should be called.

Signed-off-by: Sean Anderson <seanga2@gmail.com>
Reviewed-by: Rick Chen <rick@andestech.com>
---

Changes in v9:
- Fix type of ret variable in riscv_ipi_init
Changes in v7:
- Split IPI clearing off into its own patch

Changes in v6:
- Fix some formatting
- Clear IPIs before enabling interrupts instead of using a ipi_ready flag
- Only print messages on error in smp code

Changes in v5:
- New

 arch/riscv/cpu/cpu.c          |  6 ++++
 arch/riscv/include/asm/smp.h  | 43 +++++++++++++++++++++++++++
 arch/riscv/lib/andes_plic.c   | 34 ++++++++-------------
 arch/riscv/lib/sbi_ipi.c      |  5 ++++
 arch/riscv/lib/sifive_clint.c | 33 +++++++--------------
 arch/riscv/lib/smp.c          | 56 ++++++++---------------------------
 6 files changed, 90 insertions(+), 87 deletions(-)

diff --git a/arch/riscv/cpu/cpu.c b/arch/riscv/cpu/cpu.c
index e457f6acbf..f851374255 100644
--- a/arch/riscv/cpu/cpu.c
+++ b/arch/riscv/cpu/cpu.c
@@ -96,6 +96,12 @@ int arch_cpu_init_dm(void)
 			csr_write(CSR_SATP, 0);
 	}
 
+#ifdef CONFIG_SMP
+	ret = riscv_init_ipi();
+	if (ret)
+		return ret;
+#endif
+
 	return 0;
 }
 
diff --git a/arch/riscv/include/asm/smp.h b/arch/riscv/include/asm/smp.h
index 74de92ed13..1b428856b2 100644
--- a/arch/riscv/include/asm/smp.h
+++ b/arch/riscv/include/asm/smp.h
@@ -51,4 +51,47 @@ void handle_ipi(ulong hart);
  */
 int smp_call_function(ulong addr, ulong arg0, ulong arg1, int wait);
 
+/**
+ * riscv_init_ipi() - Initialize inter-process interrupt (IPI) driver
+ *
+ * Platform code must provide this function. This function is called once after
+ * the cpu driver is initialized. No other riscv_*_ipi() calls will be made
+ * before this function is called.
+ *
+ * @return 0 if OK, -ve on error
+ */
+int riscv_init_ipi(void);
+
+/**
+ * riscv_send_ipi() - Send inter-processor interrupt (IPI)
+ *
+ * Platform code must provide this function.
+ *
+ * @hart: Hart ID of receiving hart
+ * @return 0 if OK, -ve on error
+ */
+int riscv_send_ipi(int hart);
+
+/**
+ * riscv_clear_ipi() - Clear inter-processor interrupt (IPI)
+ *
+ * Platform code must provide this function.
+ *
+ * @hart: Hart ID of hart to be cleared
+ * @return 0 if OK, -ve on error
+ */
+int riscv_clear_ipi(int hart);
+
+/**
+ * riscv_get_ipi() - Get status of inter-processor interrupt (IPI)
+ *
+ * Platform code must provide this function.
+ *
+ * @hart: Hart ID of hart to be checked
+ * @pending: Pointer to variable with result of the check,
+ *           1 if IPI is pending, 0 otherwise
+ * @return 0 if OK, -ve on error
+ */
+int riscv_get_ipi(int hart, int *pending);
+
 #endif
diff --git a/arch/riscv/lib/andes_plic.c b/arch/riscv/lib/andes_plic.c
index 20529ab3eb..5cf29df670 100644
--- a/arch/riscv/lib/andes_plic.c
+++ b/arch/riscv/lib/andes_plic.c
@@ -30,20 +30,6 @@
 #define SEND_IPI_TO_HART(hart)  (0x80 >> (hart))
 
 DECLARE_GLOBAL_DATA_PTR;
-static int init_plic(void);
-
-#define PLIC_BASE_GET(void)						\
-	do {								\
-		long *ret;						\
-									\
-		if (!gd->arch.plic) {					\
-			ret = syscon_get_first_range(RISCV_SYSCON_PLIC); \
-			if (IS_ERR(ret))				\
-				return PTR_ERR(ret);			\
-			gd->arch.plic = ret;				\
-			init_plic();					\
-		}							\
-	} while (0)
 
 static int enable_ipi(int hart)
 {
@@ -93,13 +79,21 @@ static int init_plic(void)
 	return -ENODEV;
 }
 
+int riscv_init_ipi(void)
+{
+	long *ret = syscon_get_first_range(RISCV_SYSCON_PLIC);
+
+	if (IS_ERR(ret))
+		return PTR_ERR(ret);
+	gd->arch.plic = ret;
+
+	return init_plic();
+}
+
 int riscv_send_ipi(int hart)
 {
-	unsigned int ipi;
+	unsigned int ipi = (SEND_IPI_TO_HART(hart) << (8 * gd->arch.boot_hart));
 
-	PLIC_BASE_GET();
-
-	ipi = (SEND_IPI_TO_HART(hart) << (8 * gd->arch.boot_hart));
 	writel(ipi, (void __iomem *)PENDING_REG(gd->arch.plic,
 				gd->arch.boot_hart));
 
@@ -110,8 +104,6 @@ int riscv_clear_ipi(int hart)
 {
 	u32 source_id;
 
-	PLIC_BASE_GET();
-
 	source_id = readl((void __iomem *)CLAIM_REG(gd->arch.plic, hart));
 	writel(source_id, (void __iomem *)CLAIM_REG(gd->arch.plic, hart));
 
@@ -120,8 +112,6 @@ int riscv_clear_ipi(int hart)
 
 int riscv_get_ipi(int hart, int *pending)
 {
-	PLIC_BASE_GET();
-
 	*pending = readl((void __iomem *)PENDING_REG(gd->arch.plic,
 						     gd->arch.boot_hart));
 	*pending = !!(*pending & SEND_IPI_TO_HART(hart));
diff --git a/arch/riscv/lib/sbi_ipi.c b/arch/riscv/lib/sbi_ipi.c
index abafca9e5c..d02e2b4c48 100644
--- a/arch/riscv/lib/sbi_ipi.c
+++ b/arch/riscv/lib/sbi_ipi.c
@@ -8,6 +8,11 @@
 #include <asm/encoding.h>
 #include <asm/sbi.h>
 
+int riscv_init_ipi(void)
+{
+	return 0;
+}
+
 int riscv_send_ipi(int hart)
 {
 	ulong mask;
diff --git a/arch/riscv/lib/sifive_clint.c b/arch/riscv/lib/sifive_clint.c
index 5e0d25720b..78fc6c868d 100644
--- a/arch/riscv/lib/sifive_clint.c
+++ b/arch/riscv/lib/sifive_clint.c
@@ -24,22 +24,8 @@
 
 DECLARE_GLOBAL_DATA_PTR;
 
-#define CLINT_BASE_GET(void)						\
-	do {								\
-		long *ret;						\
-									\
-		if (!gd->arch.clint) {					\
-			ret = syscon_get_first_range(RISCV_SYSCON_CLINT); \
-			if (IS_ERR(ret))				\
-				return PTR_ERR(ret);			\
-			gd->arch.clint = ret;				\
-		}							\
-	} while (0)
-
 int riscv_get_time(u64 *time)
 {
-	CLINT_BASE_GET();
-
 	*time = readq((void __iomem *)MTIME_REG(gd->arch.clint));
 
 	return 0;
@@ -47,17 +33,24 @@ int riscv_get_time(u64 *time)
 
 int riscv_set_timecmp(int hart, u64 cmp)
 {
-	CLINT_BASE_GET();
-
 	writeq(cmp, (void __iomem *)MTIMECMP_REG(gd->arch.clint, hart));
 
 	return 0;
 }
 
+int riscv_init_ipi(void)
+{
+	long *ret = syscon_get_first_range(RISCV_SYSCON_CLINT);
+
+	if (IS_ERR(ret))
+		return PTR_ERR(ret);
+	gd->arch.clint = ret;
+
+	return 0;
+}
+
 int riscv_send_ipi(int hart)
 {
-	CLINT_BASE_GET();
-
 	writel(1, (void __iomem *)MSIP_REG(gd->arch.clint, hart));
 
 	return 0;
@@ -65,8 +58,6 @@ int riscv_send_ipi(int hart)
 
 int riscv_clear_ipi(int hart)
 {
-	CLINT_BASE_GET();
-
 	writel(0, (void __iomem *)MSIP_REG(gd->arch.clint, hart));
 
 	return 0;
@@ -74,8 +65,6 @@ int riscv_clear_ipi(int hart)
 
 int riscv_get_ipi(int hart, int *pending)
 {
-	CLINT_BASE_GET();
-
 	*pending = readl((void __iomem *)MSIP_REG(gd->arch.clint, hart));
 
 	return 0;
diff --git a/arch/riscv/lib/smp.c b/arch/riscv/lib/smp.c
index 17adb35730..fe992eb00f 100644
--- a/arch/riscv/lib/smp.c
+++ b/arch/riscv/lib/smp.c
@@ -12,38 +12,6 @@
 
 DECLARE_GLOBAL_DATA_PTR;
 
-/**
- * riscv_send_ipi() - Send inter-processor interrupt (IPI)
- *
- * Platform code must provide this function.
- *
- * @hart: Hart ID of receiving hart
- * @return 0 if OK, -ve on error
- */
-extern int riscv_send_ipi(int hart);
-
-/**
- * riscv_clear_ipi() - Clear inter-processor interrupt (IPI)
- *
- * Platform code must provide this function.
- *
- * @hart: Hart ID of hart to be cleared
- * @return 0 if OK, -ve on error
- */
-extern int riscv_clear_ipi(int hart);
-
-/**
- * riscv_get_ipi() - Get status of inter-processor interrupt (IPI)
- *
- * Platform code must provide this function.
- *
- * @hart: Hart ID of hart to be checked
- * @pending: Pointer to variable with result of the check,
- *           1 if IPI is pending, 0 otherwise
- * @return 0 if OK, -ve on error
- */
-extern int riscv_get_ipi(int hart, int *pending);
-
 static int send_ipi_many(struct ipi_data *ipi, int wait)
 {
 	ofnode node, cpus;
@@ -114,7 +82,6 @@ void handle_ipi(ulong hart)
 		return;
 
 	__smp_mb();
-
 	smp_function = (void (*)(ulong, ulong, ulong))gd->arch.ipi[hart].addr;
 	invalidate_icache_all();
 
@@ -124,7 +91,13 @@ void handle_ipi(ulong hart)
 	 */
 	ret = riscv_clear_ipi(hart);
 	if (ret) {
-		pr_err("Cannot clear IPI of hart %ld\n", hart);
+		pr_err("Cannot clear IPI of hart %ld (error %d)\n", hart, ret);
+		return;
+	}
+
+	/* Sanity check */
+	if (!smp_function) {
+		pr_err("smp_function is NULL on hart %ld\n", hart);
 		return;
 	}
 
@@ -133,14 +106,11 @@ void handle_ipi(ulong hart)
 
 int smp_call_function(ulong addr, ulong arg0, ulong arg1, int wait)
 {
-	int ret = 0;
-	struct ipi_data ipi;
+	struct ipi_data ipi = {
+		.addr = addr,
+		.arg0 = arg0,
+		.arg1 = arg1,
+	};
 
-	ipi.addr = addr;
-	ipi.arg0 = arg0;
-	ipi.arg1 = arg1;
-
-	ret = send_ipi_many(&ipi, wait);
-
-	return ret;
+	return send_ipi_many(&ipi, wait);
 }
-- 
2.25.1

  parent reply	other threads:[~2020-04-23  2:33 UTC|newest]

Thread overview: 25+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-04-23  2:32 [PATCH v9 00/21] riscv: Add Sipeed Maix support Sean Anderson
2020-04-23  2:33 ` [PATCH v9 01/21] clk: Always use the supplied struct clk Sean Anderson
2020-04-23  2:33 ` [PATCH v9 02/21] clk: Check that ops of composite clock components exist before calling Sean Anderson
2020-04-23  2:33 ` [PATCH v9 03/21] clk: Unconditionally recursively en-/dis-able clocks Sean Anderson
2020-04-23  2:33 ` [PATCH v9 04/21] clk: Fix clk_get_by_* handling of index Sean Anderson
2020-04-23  2:33 ` [PATCH v9 05/21] clk: Add K210 pll support Sean Anderson
2020-04-23  2:33 ` [PATCH v9 06/21] clk: Add a bypass clock for K210 Sean Anderson
2020-04-23  2:33 ` [PATCH v9 07/21] clk: Add K210 clock support Sean Anderson
2020-04-23  2:33 ` [PATCH v9 08/21] dm: Add support for simple-pm-bus Sean Anderson
2020-04-23  2:33 ` [PATCH v9 09/21] dm: Fix error handling for dev_read_addr_ptr Sean Anderson
2020-04-23  2:33 ` [PATCH v9 10/21] reset: Add generic reset driver Sean Anderson
2020-04-23  2:33 ` [PATCH v9 11/21] lib: Always set errno in hcreate_r Sean Anderson
2020-04-23  2:33 ` [PATCH v9 12/21] riscv: Add headers for asm/global_data.h Sean Anderson
2020-04-23  2:33 ` [PATCH v9 13/21] riscv: Clear pending interrupts before enabling IPIs Sean Anderson
2020-04-23  2:33 ` Sean Anderson [this message]
2020-04-23  2:33 ` [PATCH v9 15/21] riscv: Add option to support RISC-V privileged spec 1.9 Sean Anderson
2020-04-23  2:33 ` [PATCH v9 16/21] riscv: Allow use of reset drivers Sean Anderson
2020-04-23  2:33 ` [PATCH v9 17/21] riscv: Try to get cpu frequency from a "clocks" node if it exists Sean Anderson
2020-04-23  2:33 ` [PATCH v9 18/21] riscv: Enable cpu clock if it is present Sean Anderson
2020-04-25  7:54   ` Pragnesh Patel
2020-05-03  2:34     ` Sean Anderson
2020-04-23  2:33 ` [PATCH v9 19/21] riscv: Add device tree for K210 and Sipeed Maix BitM Sean Anderson
2020-04-23  2:33 ` [PATCH v9 20/21] doc: riscv: Add documentation for Sipeed Maix Bit Sean Anderson
2020-04-23  2:33 ` [PATCH v9 21/21] riscv: Add Sipeed Maix support Sean Anderson
2020-05-03  2:35 [PATCH v9 00/21] " Sean Anderson
2020-05-03  2:35 ` [PATCH v9 14/21] riscv: Clean up IPI initialization code Sean Anderson

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=20200423023320.1380090-15-seanga2@gmail.com \
    --to=seanga2@gmail.com \
    --cc=u-boot@lists.denx.de \
    /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.