From: Sean Anderson <seanga2@gmail.com>
To: u-boot@lists.denx.de
Subject: [PATCH v8 14/21] riscv: Clean up IPI initialization code
Date: Fri, 10 Apr 2020 08:28:07 -0400 [thread overview]
Message-ID: <20200410122814.423237-15-seanga2@gmail.com> (raw)
In-Reply-To: <20200410122814.423237-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 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..8484f76386 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)
+{
+ int 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
next prev parent reply other threads:[~2020-04-10 12:28 UTC|newest]
Thread overview: 33+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-04-10 12:27 [PATCH v8 00/21] riscv: Add Sipeed Maix support Sean Anderson
2020-04-10 12:27 ` [PATCH v8 01/21] clk: Always use the supplied struct clk Sean Anderson
2020-04-10 12:27 ` [PATCH v8 02/21] clk: Check that ops of composite clock components exist before calling Sean Anderson
2020-04-10 12:27 ` [PATCH v8 03/21] clk: Unconditionally recursively en-/dis-able clocks Sean Anderson
2020-04-10 12:27 ` [PATCH v8 04/21] clk: Fix clk_get_by_* handling of index Sean Anderson
2020-04-10 12:27 ` [PATCH v8 05/21] clk: Add K210 pll support Sean Anderson
2020-04-10 12:27 ` [PATCH v8 06/21] clk: Add a bypass clock for K210 Sean Anderson
2020-04-10 12:28 ` [PATCH v8 07/21] clk: Add K210 clock support Sean Anderson
2020-04-10 12:28 ` [PATCH v8 08/21] dm: Add support for simple-pm-bus Sean Anderson
2020-04-10 12:28 ` [PATCH v8 09/21] dm: Fix error handling for dev_read_addr_ptr Sean Anderson
2020-04-10 12:28 ` [PATCH v8 10/21] reset: Add generic reset driver Sean Anderson
2020-04-10 12:28 ` [PATCH v8 11/21] lib: Always set errno in hcreate_r Sean Anderson
2020-04-10 12:28 ` [PATCH v8 12/21] riscv: Add headers for asm/global_data.h Sean Anderson
2020-04-10 12:28 ` [PATCH v8 13/21] riscv: Clear pending interrupts before enabling IPIs Sean Anderson
2020-04-10 12:28 ` Sean Anderson [this message]
2020-04-10 12:28 ` [PATCH v8 15/21] riscv: Add option to support RISC-V privileged spec 1.9 Sean Anderson
2020-04-10 12:28 ` [PATCH v8 16/21] riscv: Allow use of reset drivers Sean Anderson
2020-04-10 12:28 ` [PATCH v8 17/21] riscv: Try to get cpu frequency from a "clocks" node if it exists Sean Anderson
2020-04-10 12:28 ` [PATCH v8 18/21] riscv: Enable cpu clock if it is present Sean Anderson
2020-04-10 12:28 ` [PATCH v8 19/21] riscv: Add device tree for K210 and Sipeed Maix BitM Sean Anderson
2020-04-10 12:28 ` [PATCH v8 20/21] doc: riscv: Add documentation for Sipeed Maix Bit Sean Anderson
2020-04-10 12:28 ` [PATCH v8 21/21] riscv: Add Sipeed Maix support Sean Anderson
2020-04-22 5:59 ` [PATCH v8 00/21] " Rick Chen
2020-04-23 1:51 ` Rick Chen
2020-04-23 2:03 ` Sean Anderson
2020-04-23 2:10 ` Bin Meng
2020-04-23 2:12 ` Sean Anderson
2020-04-23 2:28 ` Sean Anderson
2020-04-23 2:52 ` Rick Chen
2020-04-23 8:47 ` Rick Chen
2020-04-23 2:03 ` Sean Anderson
2020-04-23 12:21 ` Tom Rini
2020-04-24 8:26 ` Rick Chen
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=20200410122814.423237-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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox