linux-spi.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 1/8] Spi: sprd-adi: Getting panic reason before reboot
@ 2023-08-15  2:34 Jiansheng Wu
  2023-08-15  2:34 ` [PATCH 2/8] Spi: sprd-adi: Modify reboot method Jiansheng Wu
                   ` (8 more replies)
  0 siblings, 9 replies; 11+ messages in thread
From: Jiansheng Wu @ 2023-08-15  2:34 UTC (permalink / raw)
  To: Mark Brown, Orson Zhai, Baolin Wang, Chunyan Zhang
  Cc: linux-spi, linux-kernel, yongzhi.chen, xiaoqing.wu, jianshengwu16

Registered adi_panic_event to panic_notifier_list, that is used to
get panic reason and judge restart causes before system reboot.
It's can improve reboot reasons from panic.

Signed-off-by: Jiansheng Wu <jiansheng.wu@unisoc.com>
---
 drivers/spi/spi-sprd-adi.c | 46 ++++++++++++++++++++++++++++++++++----
 1 file changed, 42 insertions(+), 4 deletions(-)

diff --git a/drivers/spi/spi-sprd-adi.c b/drivers/spi/spi-sprd-adi.c
index 22e39c4c12c4..dd00d63a3cd0 100644
--- a/drivers/spi/spi-sprd-adi.c
+++ b/drivers/spi/spi-sprd-adi.c
@@ -12,6 +12,7 @@
 #include <linux/module.h>
 #include <linux/of.h>
 #include <linux/of_device.h>
+#include <linux/panic_notifier.h>
 #include <linux/platform_device.h>
 #include <linux/reboot.h>
 #include <linux/spi/spi.h>
@@ -128,6 +129,8 @@
 #define WDG_LOAD_MASK			GENMASK(15, 0)
 #define WDG_UNLOCK_KEY			0xe551
 
+#define PANIC_REASON_LEN_MAX		20
+
 struct sprd_adi_wdg {
 	u32 base;
 	u32 rst_sts;
@@ -155,6 +158,31 @@ struct sprd_adi {
 	const struct sprd_adi_data *data;
 };
 
+static char *panic_reason;
+static int adi_panic_event(struct notifier_block *self, unsigned long val, void *reason)
+{
+	if (reason == NULL)
+		return 0;
+
+	if (strlen(reason) < PANIC_REASON_LEN_MAX)
+		memcpy(panic_reason, reason, strlen(reason));
+	else
+		memcpy(panic_reason, reason, PANIC_REASON_LEN_MAX);
+
+	return 0;
+}
+
+static struct notifier_block adi_panic_event_nb = {
+	.notifier_call  = adi_panic_event,
+	.priority       = INT_MAX,
+};
+
+static int adi_get_panic_reason_init(void)
+{
+	atomic_notifier_chain_register(&panic_notifier_list, &adi_panic_event_nb);
+	return 0;
+}
+
 static int sprd_adi_check_addr(struct sprd_adi *sadi, u32 reg)
 {
 	if (reg >= sadi->data->slave_addr_size) {
@@ -378,9 +406,15 @@ static int sprd_adi_restart(struct notifier_block *this, unsigned long mode,
 					     restart_handler);
 	u32 val, reboot_mode = 0;
 
-	if (!cmd)
-		reboot_mode = HWRST_STATUS_NORMAL;
-	else if (!strncmp(cmd, "recovery", 8))
+	if (!cmd) {
+		if (strlen(panic_reason)) {
+			reboot_mode = HWRST_STATUS_PANIC;
+			if (strstr(panic_reason, "tospanic"))
+				reboot_mode = HWRST_STATUS_SECURITY;
+		} else {
+			reboot_mode = HWRST_STATUS_NORMAL;
+		}
+	} else if (!strncmp(cmd, "recovery", 8))
 		reboot_mode = HWRST_STATUS_RECOVERY;
 	else if (!strncmp(cmd, "alarm", 5))
 		reboot_mode = HWRST_STATUS_ALARM;
@@ -520,6 +554,10 @@ static int sprd_adi_probe(struct platform_device *pdev)
 	u16 num_chipselect;
 	int ret;
 
+	panic_reason = devm_kzalloc(&pdev->dev, (sizeof(char))*PANIC_REASON_LEN_MAX, GFP_KERNEL);
+	if (!panic_reason)
+		return -ENOMEM;
+
 	if (!np) {
 		dev_err(&pdev->dev, "can not find the adi bus node\n");
 		return -ENODEV;
@@ -573,7 +611,7 @@ static int sprd_adi_probe(struct platform_device *pdev)
 	}
 
 	sprd_adi_hw_init(sadi);
-
+	adi_get_panic_reason_init();
 	if (sadi->data->wdg_rst)
 		sadi->data->wdg_rst(sadi);
 
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH 2/8] Spi: sprd-adi: Modify reboot method
  2023-08-15  2:34 [PATCH 1/8] Spi: sprd-adi: Getting panic reason before reboot Jiansheng Wu
@ 2023-08-15  2:34 ` Jiansheng Wu
  2023-08-15  2:34 ` [PATCH 3/8] Spi: sprd-adi: Added the cause of reboot Jiansheng Wu
                   ` (7 subsequent siblings)
  8 siblings, 0 replies; 11+ messages in thread
From: Jiansheng Wu @ 2023-08-15  2:34 UTC (permalink / raw)
  To: Mark Brown, Orson Zhai, Baolin Wang, Chunyan Zhang
  Cc: linux-spi, linux-kernel, yongzhi.chen, xiaoqing.wu, jianshengwu16

Changing reboot mode on pmic, that write reset-reg to trigger reboot.
Before this, It used watchdog to reboot system, that's not the best
way.

Signed-off-by: Xiaoqing Wu <xiaoqing.wu@unisoc.com>
Signed-off-by: Jiansheng Wu <jiansheng.wu@unisoc.com>
---
 drivers/spi/spi-sprd-adi.c | 117 ++++++++++++++-----------------------
 1 file changed, 44 insertions(+), 73 deletions(-)

diff --git a/drivers/spi/spi-sprd-adi.c b/drivers/spi/spi-sprd-adi.c
index dd00d63a3cd0..734245492680 100644
--- a/drivers/spi/spi-sprd-adi.c
+++ b/drivers/spi/spi-sprd-adi.c
@@ -107,6 +107,14 @@
 #define PMIC_MODULE_EN			0xc08
 #define PMIC_CLK_EN			0xc18
 #define PMIC_WDG_BASE			0x80
+#define SC2730_MODULE_EN		0x1808
+#define SC2730_CLK_EN			0x1810
+#define SC2730_WDG_BASE			0x40
+#define SC2730_RST_STATUS		0x1bac
+#define SC2730_SWRST_CTRL0              0x1bf8
+#define SC2730_SOFT_RST_HW              0x1824
+#define REG_RST_EN                      BIT(4)
+#define REG_SOFT_RST                    BIT(0)
 
 /* Definition of PMIC reset status register */
 #define HWRST_STATUS_SECURITY		0x02
@@ -131,20 +139,16 @@
 
 #define PANIC_REASON_LEN_MAX		20
 
-struct sprd_adi_wdg {
-	u32 base;
-	u32 rst_sts;
-	u32 wdg_en;
-	u32 wdg_clk;
-};
-
 struct sprd_adi_data {
 	u32 slave_offset;
 	u32 slave_addr_size;
 	int (*read_check)(u32 val, u32 reg);
-	int (*restart)(struct notifier_block *this,
-		       unsigned long mode, void *cmd);
-	void (*wdg_rst)(void *p);
+	u32 rst_sts;
+	u32 swrst_base;
+	u32 softrst_base;
+	u32 wdg_base;
+	u32 wdg_en;
+	u32 wdg_clk;
 };
 
 struct sprd_adi {
@@ -386,21 +390,19 @@ static int sprd_adi_transfer_one(struct spi_controller *ctlr,
 	return ret;
 }
 
-static void sprd_adi_set_wdt_rst_mode(void *p)
+static void sprd_adi_set_wdt_rst_mode(struct sprd_adi *sadi)
 {
-#if IS_ENABLED(CONFIG_SPRD_WATCHDOG)
+#if IS_ENABLED(CONFIG_SPRD_WATCHDOG) || IS_ENABLED(CONFIG_SPRD_WATCHDOG_FIQ)
 	u32 val;
-	struct sprd_adi *sadi = (struct sprd_adi *)p;
 
 	/* Init watchdog reset mode */
-	sprd_adi_read(sadi, PMIC_RST_STATUS, &val);
+	sprd_adi_read(sadi, sadi->data->rst_sts, &val);
 	val |= HWRST_STATUS_WATCHDOG;
-	sprd_adi_write(sadi, PMIC_RST_STATUS, val);
+	sprd_adi_write(sadi, sadi->data->rst_sts, val);
 #endif
 }
 
-static int sprd_adi_restart(struct notifier_block *this, unsigned long mode,
-				  void *cmd, struct sprd_adi_wdg *wdg)
+static int sprd_adi_restart_handler(struct notifier_block *this, unsigned long mode, void *cmd)
 {
 	struct sprd_adi *sadi = container_of(this, struct sprd_adi,
 					     restart_handler);
@@ -442,40 +444,20 @@ static int sprd_adi_restart(struct notifier_block *this, unsigned long mode,
 		reboot_mode = HWRST_STATUS_NORMAL;
 
 	/* Record the reboot mode */
-	sprd_adi_read(sadi, wdg->rst_sts, &val);
-	val &= ~HWRST_STATUS_WATCHDOG;
+	sprd_adi_read(sadi, sadi->data->rst_sts, &val);
+	val &= ~0xFF;
 	val |= reboot_mode;
-	sprd_adi_write(sadi, wdg->rst_sts, val);
-
-	/* Enable the interface clock of the watchdog */
-	sprd_adi_read(sadi, wdg->wdg_en, &val);
-	val |= BIT_WDG_EN;
-	sprd_adi_write(sadi, wdg->wdg_en, val);
-
-	/* Enable the work clock of the watchdog */
-	sprd_adi_read(sadi, wdg->wdg_clk, &val);
-	val |= BIT_WDG_EN;
-	sprd_adi_write(sadi, wdg->wdg_clk, val);
-
-	/* Unlock the watchdog */
-	sprd_adi_write(sadi, wdg->base + REG_WDG_LOCK, WDG_UNLOCK_KEY);
+	sprd_adi_write(sadi, sadi->data->rst_sts, val);
 
-	sprd_adi_read(sadi, wdg->base + REG_WDG_CTRL, &val);
-	val |= BIT_WDG_NEW;
-	sprd_adi_write(sadi, wdg->base + REG_WDG_CTRL, val);
+	/*enable register reboot mode*/
+	sprd_adi_read(sadi, sadi->data->swrst_base, &val);
+	val |= REG_RST_EN;
+	sprd_adi_write(sadi, sadi->data->swrst_base, val);
 
-	/* Load the watchdog timeout value, 50ms is always enough. */
-	sprd_adi_write(sadi, wdg->base + REG_WDG_LOAD_HIGH, 0);
-	sprd_adi_write(sadi, wdg->base + REG_WDG_LOAD_LOW,
-		       WDG_LOAD_VAL & WDG_LOAD_MASK);
-
-	/* Start the watchdog to reset system */
-	sprd_adi_read(sadi, wdg->base + REG_WDG_CTRL, &val);
-	val |= BIT_WDG_RUN | BIT_WDG_RST;
-	sprd_adi_write(sadi, wdg->base + REG_WDG_CTRL, val);
-
-	/* Lock the watchdog */
-	sprd_adi_write(sadi, wdg->base + REG_WDG_LOCK, ~WDG_UNLOCK_KEY);
+	/*enable soft reboot mode */
+	sprd_adi_read(sadi, sadi->data->softrst_base, &val);
+	val |= REG_SOFT_RST;
+	sprd_adi_write(sadi, sadi->data->softrst_base, val);
 
 	mdelay(1000);
 
@@ -483,19 +465,6 @@ static int sprd_adi_restart(struct notifier_block *this, unsigned long mode,
 	return NOTIFY_DONE;
 }
 
-static int sprd_adi_restart_sc9860(struct notifier_block *this,
-					   unsigned long mode, void *cmd)
-{
-	struct sprd_adi_wdg wdg = {
-		.base = PMIC_WDG_BASE,
-		.rst_sts = PMIC_RST_STATUS,
-		.wdg_en = PMIC_MODULE_EN,
-		.wdg_clk = PMIC_CLK_EN,
-	};
-
-	return sprd_adi_restart(this, mode, cmd, &wdg);
-}
-
 static void sprd_adi_hw_init(struct sprd_adi *sadi)
 {
 	struct device_node *np = sadi->dev->of_node;
@@ -612,8 +581,7 @@ static int sprd_adi_probe(struct platform_device *pdev)
 
 	sprd_adi_hw_init(sadi);
 	adi_get_panic_reason_init();
-	if (sadi->data->wdg_rst)
-		sadi->data->wdg_rst(sadi);
+	sprd_adi_set_wdt_rst_mode(sadi);
 
 	ctlr->dev.of_node = pdev->dev.of_node;
 	ctlr->bus_num = pdev->id;
@@ -628,14 +596,12 @@ static int sprd_adi_probe(struct platform_device *pdev)
 		goto put_ctlr;
 	}
 
-	if (sadi->data->restart) {
-		sadi->restart_handler.notifier_call = sadi->data->restart;
-		sadi->restart_handler.priority = 128;
-		ret = register_restart_handler(&sadi->restart_handler);
-		if (ret) {
-			dev_err(&pdev->dev, "can not register restart handler\n");
-			goto put_ctlr;
-		}
+	sadi->restart_handler.notifier_call = sprd_adi_restart_handler;
+	sadi->restart_handler.priority = 130;
+	ret = register_restart_handler(&sadi->restart_handler);
+	if (ret) {
+		dev_err(&pdev->dev, "can not register restart handler\n");
+		goto put_ctlr;
 	}
 
 	return 0;
@@ -657,8 +623,10 @@ static struct sprd_adi_data sc9860_data = {
 	.slave_offset = ADI_10BIT_SLAVE_OFFSET,
 	.slave_addr_size = ADI_10BIT_SLAVE_ADDR_SIZE,
 	.read_check = sprd_adi_read_check_r2,
-	.restart = sprd_adi_restart_sc9860,
-	.wdg_rst = sprd_adi_set_wdt_rst_mode,
+	.rst_sts = PMIC_RST_STATUS,
+	.wdg_base = PMIC_WDG_BASE,
+	.wdg_en = PMIC_MODULE_EN,
+	.wdg_clk = PMIC_CLK_EN,
 };
 
 static struct sprd_adi_data sc9863_data = {
@@ -671,6 +639,9 @@ static struct sprd_adi_data ums512_data = {
 	.slave_offset = ADI_15BIT_SLAVE_OFFSET,
 	.slave_addr_size = ADI_15BIT_SLAVE_ADDR_SIZE,
 	.read_check = sprd_adi_read_check_r3,
+	.rst_sts = SC2730_RST_STATUS,
+	.swrst_base = SC2730_SWRST_CTRL0,
+	.softrst_base = SC2730_SOFT_RST_HW,
 };
 
 static const struct of_device_id sprd_adi_of_match[] = {
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH 3/8] Spi: sprd-adi: Added the cause of reboot
  2023-08-15  2:34 [PATCH 1/8] Spi: sprd-adi: Getting panic reason before reboot Jiansheng Wu
  2023-08-15  2:34 ` [PATCH 2/8] Spi: sprd-adi: Modify reboot method Jiansheng Wu
@ 2023-08-15  2:34 ` Jiansheng Wu
  2023-08-15  2:34 ` [PATCH 4/8] Spi: sprd-adi: Supported multi parameter configurations Jiansheng Wu
                   ` (6 subsequent siblings)
  8 siblings, 0 replies; 11+ messages in thread
From: Jiansheng Wu @ 2023-08-15  2:34 UTC (permalink / raw)
  To: Mark Brown, Orson Zhai, Baolin Wang, Chunyan Zhang
  Cc: linux-spi, linux-kernel, yongzhi.chen, xiaoqing.wu, jianshengwu16

Added the silent and dmverity methods to reboot mode that the system
need enter the silent or secboot mode after restarting system.

Signed-off-by: Jiansheng Wu <jiansheng.wu@unisoc.com>
---
 drivers/spi/spi-sprd-adi.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/drivers/spi/spi-sprd-adi.c b/drivers/spi/spi-sprd-adi.c
index 734245492680..569a66943e8d 100644
--- a/drivers/spi/spi-sprd-adi.c
+++ b/drivers/spi/spi-sprd-adi.c
@@ -118,6 +118,7 @@
 
 /* Definition of PMIC reset status register */
 #define HWRST_STATUS_SECURITY		0x02
+#define HWRST_STATUS_SECBOOT		0x03
 #define HWRST_STATUS_RECOVERY		0x20
 #define HWRST_STATUS_NORMAL		0x40
 #define HWRST_STATUS_ALARM		0x50
@@ -129,6 +130,7 @@
 #define HWRST_STATUS_AUTODLOADER	0xa0
 #define HWRST_STATUS_IQMODE		0xb0
 #define HWRST_STATUS_SPRDISK		0xc0
+#define HWRST_STATUS_SILENT             0xd0
 #define HWRST_STATUS_FACTORYTEST	0xe0
 #define HWRST_STATUS_WATCHDOG		0xf0
 
@@ -438,8 +440,12 @@ static int sprd_adi_restart_handler(struct notifier_block *this, unsigned long m
 		reboot_mode = HWRST_STATUS_SPRDISK;
 	else if (!strncmp(cmd, "tospanic", 8))
 		reboot_mode = HWRST_STATUS_SECURITY;
+	else if (!strncmp(cmd, "dm-verity", 9))
+		reboot_mode = HWRST_STATUS_SECBOOT;
 	else if (!strncmp(cmd, "factorytest", 11))
 		reboot_mode = HWRST_STATUS_FACTORYTEST;
+	else if (!strncmp(cmd, "silent", 6))
+		reboot_mode = HWRST_STATUS_SILENT;
 	else
 		reboot_mode = HWRST_STATUS_NORMAL;
 
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH 4/8] Spi: sprd-adi: Supported multi parameter configurations
  2023-08-15  2:34 [PATCH 1/8] Spi: sprd-adi: Getting panic reason before reboot Jiansheng Wu
  2023-08-15  2:34 ` [PATCH 2/8] Spi: sprd-adi: Modify reboot method Jiansheng Wu
  2023-08-15  2:34 ` [PATCH 3/8] Spi: sprd-adi: Added the cause of reboot Jiansheng Wu
@ 2023-08-15  2:34 ` Jiansheng Wu
  2023-08-15  2:34 ` [PATCH 5/8] Spi: sprd-adi: Checking panic reason from sml Jiansheng Wu
                   ` (5 subsequent siblings)
  8 siblings, 0 replies; 11+ messages in thread
From: Jiansheng Wu @ 2023-08-15  2:34 UTC (permalink / raw)
  To: Mark Brown, Orson Zhai, Baolin Wang, Chunyan Zhang
  Cc: linux-spi, linux-kernel, yongzhi.chen, xiaoqing.wu, jianshengwu16

It is supporting multi hardware and multi config on adi driver.
That we can define different parameter on boards' dts, and configure
cannels on adi-device.

Signed-off-by: Jiansheng Wu <jiansheng.wu@unisoc.com>
---
 drivers/spi/spi-sprd-adi.c | 35 ++++++++++++++++++++++++++++++++++-
 1 file changed, 34 insertions(+), 1 deletion(-)

diff --git a/drivers/spi/spi-sprd-adi.c b/drivers/spi/spi-sprd-adi.c
index 569a66943e8d..eea64d20279e 100644
--- a/drivers/spi/spi-sprd-adi.c
+++ b/drivers/spi/spi-sprd-adi.c
@@ -140,6 +140,8 @@
 #define WDG_UNLOCK_KEY			0xe551
 
 #define PANIC_REASON_LEN_MAX		20
+/*Adi single soft multi hard*/
+#define SPRD_ADI_MAGIC_LEN_MAX          5
 
 struct sprd_adi_data {
 	u32 slave_offset;
@@ -471,12 +473,40 @@ static int sprd_adi_restart_handler(struct notifier_block *this, unsigned long m
 	return NOTIFY_DONE;
 }
 
+static void sprd_adi_power_ssmh(char *adi_supply)
+{
+	struct device_node *cmdline_node;
+	const char *cmd_line, *adi_type;
+	char adi_value[SPRD_ADI_MAGIC_LEN_MAX] = "";
+	int ret;
+
+	cmdline_node = of_find_node_by_path("/chosen");
+	ret = of_property_read_string(cmdline_node, "bootargs", &cmd_line);
+	if (ret) {
+		pr_err("can't parse bootargs property\n");
+		return;
+	}
+
+	adi_type = strstr(cmd_line, "power.from.extern=");
+	if (!adi_type) {
+		pr_err("can't find power.from.extern\n");
+		return;
+	}
+
+	sscanf(adi_type, "power.from.extern=%s\n", adi_value);
+	if (!adi_value[0])
+		return;
+
+	strcat(adi_supply, adi_value);
+}
+
 static void sprd_adi_hw_init(struct sprd_adi *sadi)
 {
 	struct device_node *np = sadi->dev->of_node;
 	int i, size, chn_cnt;
 	const __be32 *list;
 	u32 tmp;
+	char adi_supply[25] = "sprd,hw-channels";
 
 	/* Set all channels as default priority */
 	writel_relaxed(0, sadi->base + REG_ADI_CHN_PRIL);
@@ -488,7 +518,10 @@ static void sprd_adi_hw_init(struct sprd_adi *sadi)
 	writel_relaxed(tmp, sadi->base + REG_ADI_GSSI_CFG0);
 
 	/* Set hardware channels setting */
-	list = of_get_property(np, "sprd,hw-channels", &size);
+	sprd_adi_power_ssmh(adi_supply);
+	dev_info(sadi->dev, "adi supply is %s\n", adi_supply);
+
+	list = of_get_property(np, adi_supply, &size);
 	if (!list || !size) {
 		dev_info(sadi->dev, "no hw channels setting in node\n");
 		return;
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH 5/8] Spi: sprd-adi: Checking panic reason from sml
  2023-08-15  2:34 [PATCH 1/8] Spi: sprd-adi: Getting panic reason before reboot Jiansheng Wu
                   ` (2 preceding siblings ...)
  2023-08-15  2:34 ` [PATCH 4/8] Spi: sprd-adi: Supported multi parameter configurations Jiansheng Wu
@ 2023-08-15  2:34 ` Jiansheng Wu
  2023-08-15  2:34 ` [PATCH 6/8] Spi: sprd-adi: Supported adi controller on UMS9620 Jiansheng Wu
                   ` (4 subsequent siblings)
  8 siblings, 0 replies; 11+ messages in thread
From: Jiansheng Wu @ 2023-08-15  2:34 UTC (permalink / raw)
  To: Mark Brown, Orson Zhai, Baolin Wang, Chunyan Zhang
  Cc: linux-spi, linux-kernel, yongzhi.chen, xiaoqing.wu, jianshengwu16

Checking panic reason from sml and recording reboot mode to pmic's reg.
It used to check reboot reason on next boot.

Signed-off-by: XiaoQing Wu <xiaoqing.wu@unisoc.com>
Signed-off-by: Jiansheng Wu <jiansheng.wu@unisoc.com>
---
 drivers/spi/spi-sprd-adi.c | 12 ++++++++----
 1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/drivers/spi/spi-sprd-adi.c b/drivers/spi/spi-sprd-adi.c
index eea64d20279e..c31035fffe4c 100644
--- a/drivers/spi/spi-sprd-adi.c
+++ b/drivers/spi/spi-sprd-adi.c
@@ -119,6 +119,7 @@
 /* Definition of PMIC reset status register */
 #define HWRST_STATUS_SECURITY		0x02
 #define HWRST_STATUS_SECBOOT		0x03
+#define HWRST_STATUS_SML_PANIC          0x04
 #define HWRST_STATUS_RECOVERY		0x20
 #define HWRST_STATUS_NORMAL		0x40
 #define HWRST_STATUS_ALARM		0x50
@@ -410,7 +411,7 @@ static int sprd_adi_restart_handler(struct notifier_block *this, unsigned long m
 {
 	struct sprd_adi *sadi = container_of(this, struct sprd_adi,
 					     restart_handler);
-	u32 val, reboot_mode = 0;
+	u32 val = 0, reboot_mode = 0, sml_mode;
 
 	if (!cmd) {
 		if (strlen(panic_reason)) {
@@ -453,9 +454,12 @@ static int sprd_adi_restart_handler(struct notifier_block *this, unsigned long m
 
 	/* Record the reboot mode */
 	sprd_adi_read(sadi, sadi->data->rst_sts, &val);
-	val &= ~0xFF;
-	val |= reboot_mode;
-	sprd_adi_write(sadi, sadi->data->rst_sts, val);
+	sml_mode = val & 0xFF;
+	if (sml_mode != HWRST_STATUS_SML_PANIC && sml_mode != HWRST_STATUS_SECURITY) {
+		val &= ~0xFF;
+		val |= reboot_mode;
+		sprd_adi_write(sadi, sadi->data->rst_sts, val);
+	}
 
 	/*enable register reboot mode*/
 	sprd_adi_read(sadi, sadi->data->swrst_base, &val);
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH 6/8] Spi: sprd-adi: Supported adi controller on UMS9620
  2023-08-15  2:34 [PATCH 1/8] Spi: sprd-adi: Getting panic reason before reboot Jiansheng Wu
                   ` (3 preceding siblings ...)
  2023-08-15  2:34 ` [PATCH 5/8] Spi: sprd-adi: Checking panic reason from sml Jiansheng Wu
@ 2023-08-15  2:34 ` Jiansheng Wu
  2023-08-15  2:34 ` [PATCH 7/8] Spi: sprd-adi: Waiting write_cmd is finished Jiansheng Wu
                   ` (3 subsequent siblings)
  8 siblings, 0 replies; 11+ messages in thread
From: Jiansheng Wu @ 2023-08-15  2:34 UTC (permalink / raw)
  To: Mark Brown, Orson Zhai, Baolin Wang, Chunyan Zhang
  Cc: linux-spi, linux-kernel, yongzhi.chen, xiaoqing.wu, jianshengwu16

Added ADI-controller on UMS9620 and reset regs on UMP9620, that is
a PMIC SoC integrated in UMS9620.

Signed-off-by: XiaoQing Wu <xiaoqing.wu@unisoc.com>
Signed-off-by: Jiansheng Wu <jiansheng.wu@unisoc.com>
---
 drivers/spi/spi-sprd-adi.c | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/drivers/spi/spi-sprd-adi.c b/drivers/spi/spi-sprd-adi.c
index c31035fffe4c..0b20c228e119 100644
--- a/drivers/spi/spi-sprd-adi.c
+++ b/drivers/spi/spi-sprd-adi.c
@@ -111,6 +111,9 @@
 #define SC2730_CLK_EN			0x1810
 #define SC2730_WDG_BASE			0x40
 #define SC2730_RST_STATUS		0x1bac
+#define UMP9620_RST_STATUS		0x23ac
+#define UMP9620_SWRST_CTRL0             0x23f8
+#define UMP9620_SOFT_RST_HW             0x2024
 #define SC2730_SWRST_CTRL0              0x1bf8
 #define SC2730_SOFT_RST_HW              0x1824
 #define REG_RST_EN                      BIT(4)
@@ -687,6 +690,14 @@ static struct sprd_adi_data ums512_data = {
 	.softrst_base = SC2730_SOFT_RST_HW,
 };
 
+static struct sprd_adi_data ums9620_data = {
+	.slave_offset = ADI_15BIT_SLAVE_OFFSET,
+	.slave_addr_size = ADI_15BIT_SLAVE_ADDR_SIZE,
+	.rst_sts = UMP9620_RST_STATUS,
+	.swrst_base = UMP9620_SWRST_CTRL0,
+	.softrst_base = UMP9620_SOFT_RST_HW,
+};
+
 static const struct of_device_id sprd_adi_of_match[] = {
 	{
 		.compatible = "sprd,sc9860-adi",
@@ -700,6 +711,10 @@ static const struct of_device_id sprd_adi_of_match[] = {
 		.compatible = "sprd,ums512-adi",
 		.data = &ums512_data,
 	},
+	{
+		.compatible = "sprd,ums9620-adi",
+		.data = &ums9620_data,
+	},
 	{ },
 };
 MODULE_DEVICE_TABLE(of, sprd_adi_of_match);
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH 7/8] Spi: sprd-adi: Waiting write_cmd is finished
  2023-08-15  2:34 [PATCH 1/8] Spi: sprd-adi: Getting panic reason before reboot Jiansheng Wu
                   ` (4 preceding siblings ...)
  2023-08-15  2:34 ` [PATCH 6/8] Spi: sprd-adi: Supported adi controller on UMS9620 Jiansheng Wu
@ 2023-08-15  2:34 ` Jiansheng Wu
  2023-08-15  2:34 ` [PATCH 8/8] spi: add sprd ADI for UMS9620 Jiansheng Wu
                   ` (2 subsequent siblings)
  8 siblings, 0 replies; 11+ messages in thread
From: Jiansheng Wu @ 2023-08-15  2:34 UTC (permalink / raw)
  To: Mark Brown, Orson Zhai, Baolin Wang, Chunyan Zhang
  Cc: linux-spi, linux-kernel, yongzhi.chen, xiaoqing.wu, jianshengwu16

Checeking state on write_cmd, and return flag of result. It is a new
function on UMS9620 to verify that the data transfer is complete.

Signed-off-by: XiaoQing Wu <xiaoqing.wu@unisoc.com>
Signed-off-by: Jiansheng Wu <jiansheng.wu@unisoc.com>
---
 drivers/spi/spi-sprd-adi.c | 24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)

diff --git a/drivers/spi/spi-sprd-adi.c b/drivers/spi/spi-sprd-adi.c
index 0b20c228e119..8c518c227549 100644
--- a/drivers/spi/spi-sprd-adi.c
+++ b/drivers/spi/spi-sprd-adi.c
@@ -48,6 +48,7 @@
 #define RD_ADDR_MASK			GENMASK(30, 16)
 
 /* Bits definitions for register REG_ADI_ARM_FIFO_STS */
+#define BIT_ARM_WR_FREQ			BIT(31)
 #define BIT_FIFO_FULL			BIT(11)
 #define BIT_FIFO_EMPTY			BIT(10)
 
@@ -78,6 +79,7 @@
 
 #define ADI_FIFO_DRAIN_TIMEOUT		1000
 #define ADI_READ_TIMEOUT		2000
+#define ADI_WRITE_TIMEOUT		2000
 
 /*
  * Read back address from REG_ADI_RD_DATA bit[30:16] which maps to:
@@ -150,6 +152,7 @@
 struct sprd_adi_data {
 	u32 slave_offset;
 	u32 slave_addr_size;
+	int (*write_wait)(void __iomem *adi_base);
 	int (*read_check)(u32 val, u32 reg);
 	u32 rst_sts;
 	u32 swrst_base;
@@ -247,6 +250,22 @@ static int sprd_adi_read_check(u32 val, u32 addr)
 	return 0;
 }
 
+static int sprd_adi_write_wait(void __iomem *adi_base)
+{
+	unsigned int write_timeout = ADI_WRITE_TIMEOUT;
+	u32 val;
+
+	do {
+		val = readl_relaxed(adi_base + REG_ADI_ARM_FIFO_STS);
+		if (!(val & BIT_ARM_WR_FREQ))
+			return 0;
+		cpu_relax();
+	} while (--write_timeout);
+
+	pr_err("ADI write fail, sts = 0x%02x\n", val);
+	return -EBUSY;
+}
+
 static int sprd_adi_read_check_r2(u32 val, u32 reg)
 {
 	return sprd_adi_read_check(val, reg & RDBACK_ADDR_MASK_R2);
@@ -365,8 +384,12 @@ static int sprd_adi_write(struct sprd_adi *sadi, u32 reg, u32 val)
 	if (timeout == 0) {
 		dev_err(sadi->dev, "write fifo is full\n");
 		ret = -EBUSY;
+		goto out;
 	}
 
+	if (sadi->data->write_wait)
+		ret = sadi->data->write_wait(sadi->base);
+
 out:
 	if (sadi->hwlock)
 		hwspin_unlock_irqrestore(sadi->hwlock, &flags);
@@ -691,6 +714,7 @@ static struct sprd_adi_data ums512_data = {
 };
 
 static struct sprd_adi_data ums9620_data = {
+	.write_wait = sprd_adi_write_wait,
 	.slave_offset = ADI_15BIT_SLAVE_OFFSET,
 	.slave_addr_size = ADI_15BIT_SLAVE_ADDR_SIZE,
 	.rst_sts = UMP9620_RST_STATUS,
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH 8/8] spi: add sprd ADI for UMS9620
  2023-08-15  2:34 [PATCH 1/8] Spi: sprd-adi: Getting panic reason before reboot Jiansheng Wu
                   ` (5 preceding siblings ...)
  2023-08-15  2:34 ` [PATCH 7/8] Spi: sprd-adi: Waiting write_cmd is finished Jiansheng Wu
@ 2023-08-15  2:34 ` Jiansheng Wu
  2023-08-15  5:41   ` Krzysztof Kozlowski
  2023-08-15  8:22 ` [PATCH 1/8] Spi: sprd-adi: Getting panic reason before reboot Thomas Weißschuh
  2023-08-15 13:21 ` Mark Brown
  8 siblings, 1 reply; 11+ messages in thread
From: Jiansheng Wu @ 2023-08-15  2:34 UTC (permalink / raw)
  To: Mark Brown, Orson Zhai, Baolin Wang, Chunyan Zhang
  Cc: linux-spi, linux-kernel, yongzhi.chen, xiaoqing.wu, jianshengwu16

This patch adds support for UMS9620.

Signed-off-by: Jiansheng Wu <jiansheng.wu@unisoc.com>
---
 Documentation/devicetree/bindings/spi/sprd,spi-adi.yaml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/spi/sprd,spi-adi.yaml b/Documentation/devicetree/bindings/spi/sprd,spi-adi.yaml
index 903b06f88b1b..8efea6dfcf25 100644
--- a/Documentation/devicetree/bindings/spi/sprd,spi-adi.yaml
+++ b/Documentation/devicetree/bindings/spi/sprd,spi-adi.yaml
@@ -51,6 +51,7 @@ properties:
       - sprd,sc9860-adi
       - sprd,sc9863-adi
       - sprd,ums512-adi
+      - sprd,ums9620-adi
 
   reg:
     maxItems: 1
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* Re: [PATCH 8/8] spi: add sprd ADI for UMS9620
  2023-08-15  2:34 ` [PATCH 8/8] spi: add sprd ADI for UMS9620 Jiansheng Wu
@ 2023-08-15  5:41   ` Krzysztof Kozlowski
  0 siblings, 0 replies; 11+ messages in thread
From: Krzysztof Kozlowski @ 2023-08-15  5:41 UTC (permalink / raw)
  To: Jiansheng Wu, Mark Brown, Orson Zhai, Baolin Wang, Chunyan Zhang
  Cc: linux-spi, linux-kernel, yongzhi.chen, xiaoqing.wu, jianshengwu16

On 15/08/2023 04:34, Jiansheng Wu wrote:
> This patch adds support for UMS9620.
> 
> Signed-off-by: Jiansheng Wu <jiansheng.wu@unisoc.com>

2. Please use scripts/get_maintainers.pl to get a list of necessary
people and lists to CC. It might happen, that command when run on an
older kernel, gives you outdated entries. Therefore please be sure you
base your patches on recent Linux kernel.

You missed at least DT list (maybe more), so this won't be tested by
automated tooling. Performing review on untested code might be a waste
of time, thus I will skip this patch entirely till you follow the
process allowing the patch to be tested.

Please kindly resend and include all necessary To/Cc entries.

1. Please use subject prefixes matching the subsystem. You can get them
for example with `git log --oneline -- DIRECTORY_OR_FILE` on the
directory your patch is touching.

> ---
>  Documentation/devicetree/bindings/spi/sprd,spi-adi.yaml | 1 +
>  1 file changed, 1 insertion(+)
> 
Best regards,
Krzysztof


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH 1/8] Spi: sprd-adi: Getting panic reason before reboot
  2023-08-15  2:34 [PATCH 1/8] Spi: sprd-adi: Getting panic reason before reboot Jiansheng Wu
                   ` (6 preceding siblings ...)
  2023-08-15  2:34 ` [PATCH 8/8] spi: add sprd ADI for UMS9620 Jiansheng Wu
@ 2023-08-15  8:22 ` Thomas Weißschuh
  2023-08-15 13:21 ` Mark Brown
  8 siblings, 0 replies; 11+ messages in thread
From: Thomas Weißschuh @ 2023-08-15  8:22 UTC (permalink / raw)
  To: Jiansheng Wu
  Cc: Mark Brown, Orson Zhai, Baolin Wang, Chunyan Zhang, linux-spi,
	linux-kernel, yongzhi.chen, xiaoqing.wu, jianshengwu16

On 2023-08-15 10:34:19+0800, Jiansheng Wu wrote:
> Registered adi_panic_event to panic_notifier_list, that is used to
> get panic reason and judge restart causes before system reboot.
> It's can improve reboot reasons from panic.
> 
> Signed-off-by: Jiansheng Wu <jiansheng.wu@unisoc.com>
> ---
>  drivers/spi/spi-sprd-adi.c | 46 ++++++++++++++++++++++++++++++++++----
>  1 file changed, 42 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/spi/spi-sprd-adi.c b/drivers/spi/spi-sprd-adi.c
> index 22e39c4c12c4..dd00d63a3cd0 100644
> --- a/drivers/spi/spi-sprd-adi.c
> +++ b/drivers/spi/spi-sprd-adi.c
> @@ -12,6 +12,7 @@
>  #include <linux/module.h>
>  #include <linux/of.h>
>  #include <linux/of_device.h>
> +#include <linux/panic_notifier.h>
>  #include <linux/platform_device.h>
>  #include <linux/reboot.h>
>  #include <linux/spi/spi.h>
> @@ -128,6 +129,8 @@
>  #define WDG_LOAD_MASK			GENMASK(15, 0)
>  #define WDG_UNLOCK_KEY			0xe551
>  
> +#define PANIC_REASON_LEN_MAX		20
> +
>  struct sprd_adi_wdg {
>  	u32 base;
>  	u32 rst_sts;
> @@ -155,6 +158,31 @@ struct sprd_adi {
>  	const struct sprd_adi_data *data;
>  };
>  
> +static char *panic_reason;
> +static int adi_panic_event(struct notifier_block *self, unsigned long val, void *reason)
> +{
> +	if (reason == NULL)
> +		return 0;
> +
> +	if (strlen(reason) < PANIC_REASON_LEN_MAX)
> +		memcpy(panic_reason, reason, strlen(reason));
> +	else
> +		memcpy(panic_reason, reason, PANIC_REASON_LEN_MAX);

This will truncate the trailing '\0'.
The string logic below will be invalid on a non-null-terminated byte
array.
strscpy() would avoid the issue.

> +
> +	return 0;
> +}
> +
> +static struct notifier_block adi_panic_event_nb = {
> +	.notifier_call  = adi_panic_event,
> +	.priority       = INT_MAX,
> +};
> +
> +static int adi_get_panic_reason_init(void)
> +{
> +	atomic_notifier_chain_register(&panic_notifier_list, &adi_panic_event_nb);
> +	return 0;
> +}
> +
>  static int sprd_adi_check_addr(struct sprd_adi *sadi, u32 reg)
>  {
>  	if (reg >= sadi->data->slave_addr_size) {
> @@ -378,9 +406,15 @@ static int sprd_adi_restart(struct notifier_block *this, unsigned long mode,
>  					     restart_handler);
>  	u32 val, reboot_mode = 0;
>  
> -	if (!cmd)
> -		reboot_mode = HWRST_STATUS_NORMAL;
> -	else if (!strncmp(cmd, "recovery", 8))
> +	if (!cmd) {
> +		if (strlen(panic_reason)) {
> +			reboot_mode = HWRST_STATUS_PANIC;
> +			if (strstr(panic_reason, "tospanic"))
> +				reboot_mode = HWRST_STATUS_SECURITY;
> +		} else {
> +			reboot_mode = HWRST_STATUS_NORMAL;
> +		}
> +	} else if (!strncmp(cmd, "recovery", 8))
>  		reboot_mode = HWRST_STATUS_RECOVERY;
>  	else if (!strncmp(cmd, "alarm", 5))
>  		reboot_mode = HWRST_STATUS_ALARM;
> @@ -520,6 +554,10 @@ static int sprd_adi_probe(struct platform_device *pdev)
>  	u16 num_chipselect;
>  	int ret;
>  
> +	panic_reason = devm_kzalloc(&pdev->dev, (sizeof(char))*PANIC_REASON_LEN_MAX, GFP_KERNEL);

sizeof(char) is guaranteed to be 1 by the C standard.

It seems weird to devm_alloc() something that will be stored in a static
buffer. If multiple devices are bound to the driver the results will be
weird.
Also if the device is unbound the notifier won't be unregistered and
panic_mode will point to freed memory.

> +	if (!panic_reason)
> +		return -ENOMEM;
> +
>  	if (!np) {
>  		dev_err(&pdev->dev, "can not find the adi bus node\n");
>  		return -ENODEV;
> @@ -573,7 +611,7 @@ static int sprd_adi_probe(struct platform_device *pdev)
>  	}
>  
>  	sprd_adi_hw_init(sadi);
> -
> +	adi_get_panic_reason_init();

Why drop the empty line?

>  	if (sadi->data->wdg_rst)
>  		sadi->data->wdg_rst(sadi);
>  
> -- 
> 2.17.1
> 

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH 1/8] Spi: sprd-adi: Getting panic reason before reboot
  2023-08-15  2:34 [PATCH 1/8] Spi: sprd-adi: Getting panic reason before reboot Jiansheng Wu
                   ` (7 preceding siblings ...)
  2023-08-15  8:22 ` [PATCH 1/8] Spi: sprd-adi: Getting panic reason before reboot Thomas Weißschuh
@ 2023-08-15 13:21 ` Mark Brown
  8 siblings, 0 replies; 11+ messages in thread
From: Mark Brown @ 2023-08-15 13:21 UTC (permalink / raw)
  To: Jiansheng Wu
  Cc: Orson Zhai, Baolin Wang, Chunyan Zhang, linux-spi, linux-kernel,
	yongzhi.chen, xiaoqing.wu, jianshengwu16

[-- Attachment #1: Type: text/plain, Size: 279 bytes --]

On Tue, Aug 15, 2023 at 10:34:19AM +0800, Jiansheng Wu wrote:

> +	if (strlen(reason) < PANIC_REASON_LEN_MAX)
> +		memcpy(panic_reason, reason, strlen(reason));
> +	else
> +		memcpy(panic_reason, reason, PANIC_REASON_LEN_MAX);

There's length limited strcpy() variants for this.

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2023-08-15 13:23 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-08-15  2:34 [PATCH 1/8] Spi: sprd-adi: Getting panic reason before reboot Jiansheng Wu
2023-08-15  2:34 ` [PATCH 2/8] Spi: sprd-adi: Modify reboot method Jiansheng Wu
2023-08-15  2:34 ` [PATCH 3/8] Spi: sprd-adi: Added the cause of reboot Jiansheng Wu
2023-08-15  2:34 ` [PATCH 4/8] Spi: sprd-adi: Supported multi parameter configurations Jiansheng Wu
2023-08-15  2:34 ` [PATCH 5/8] Spi: sprd-adi: Checking panic reason from sml Jiansheng Wu
2023-08-15  2:34 ` [PATCH 6/8] Spi: sprd-adi: Supported adi controller on UMS9620 Jiansheng Wu
2023-08-15  2:34 ` [PATCH 7/8] Spi: sprd-adi: Waiting write_cmd is finished Jiansheng Wu
2023-08-15  2:34 ` [PATCH 8/8] spi: add sprd ADI for UMS9620 Jiansheng Wu
2023-08-15  5:41   ` Krzysztof Kozlowski
2023-08-15  8:22 ` [PATCH 1/8] Spi: sprd-adi: Getting panic reason before reboot Thomas Weißschuh
2023-08-15 13:21 ` Mark Brown

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).