All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 0/2] Coldfire m5441x: add RCM power-on reason driver
@ 2026-06-07  8:49 Jean-Michel Hautbois
  2026-06-07  8:49 ` [PATCH v2 1/2] power: reset: add MCF5441x " Jean-Michel Hautbois
  2026-06-07  8:49 ` [PATCH v2 2/2] m68k: coldfire/5441x: register mcf-rcm-reset platform device Jean-Michel Hautbois
  0 siblings, 2 replies; 4+ messages in thread
From: Jean-Michel Hautbois @ 2026-06-07  8:49 UTC (permalink / raw)
  To: Geert Uytterhoeven, Sebastian Reichel, Greg Ungerer
  Cc: linux-m68k, linux-kernel, linux-pm, Jean-Michel Hautbois

This series adds a power_on_reason driver for the Freescale ColdFire
MCF5441x Reset Controller Module.

The MCF5441x has six documented sources of reset (power-on, external
pin, software, PLL loss-of-clock, PLL loss-of-lock and core watchdog
timeout). They are latched in the Reset Status Register (RSR) at
0xec090001. The new driver decodes that register once at probe time
and exposes the result through the power_on_reason sysfs ABI.

Patch 1 is the driver. Patch 2 registers the platform device at the
SoC level so every MCF5441x board picks the driver up automatically.

The driver is scoped to MCF5441x. Other ColdFire variants document an
RSR at different addresses with different bit layouts; covering them
is left for follow-up patches by anyone with the relevant boards.

Tested on a MCF5441x board: after sysrq-b, the sysfs attribute
reports "software reset".

Signed-off-by: Jean-Michel Hautbois <jeanmichel.hautbois@yoseli.org>
---
Changes in v2:
- Describe the RSR layout in the driver instead of a separate m68k
  header patch, so the driver can be built with COMPILE_TEST.
- Allow building under COMPILE_TEST (depends on M5441x || COMPILE_TEST).
- Add a platform_device_id table and drop the now-redundant
  MODULE_ALIAS (Sebastian Reichel).
- Drop the standalone "define RSR cause bits" patch; the layout now
  lives in the driver. The series is two patches instead of three.
- Link to v1: https://patch.msgid.link/20260602-coldfire-rcm-power-on-reason-v1-0-fbc3eab0c016@yoseli.org

---
Jean-Michel Hautbois (2):
      power: reset: add MCF5441x RCM power-on reason driver
      m68k: coldfire/5441x: register mcf-rcm-reset platform device

 MAINTAINERS                         |   6 ++
 arch/m68k/coldfire/m5441x.c         |  25 +++++++
 drivers/power/reset/Kconfig         |  12 ++++
 drivers/power/reset/Makefile        |   1 +
 drivers/power/reset/mcf-rcm-reset.c | 126 ++++++++++++++++++++++++++++++++++++
 5 files changed, 170 insertions(+)
---
base-commit: 979c294509f9248fe1e7c358d582fb37dd5ca12d
change-id: 20260528-coldfire-rcm-power-on-reason-7a234acfdddd

Best regards,
--  
Jean-Michel Hautbois <jeanmichel.hautbois@yoseli.org>


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

* [PATCH v2 1/2] power: reset: add MCF5441x RCM power-on reason driver
  2026-06-07  8:49 [PATCH v2 0/2] Coldfire m5441x: add RCM power-on reason driver Jean-Michel Hautbois
@ 2026-06-07  8:49 ` Jean-Michel Hautbois
  2026-06-17 14:27   ` Uwe Kleine-König
  2026-06-07  8:49 ` [PATCH v2 2/2] m68k: coldfire/5441x: register mcf-rcm-reset platform device Jean-Michel Hautbois
  1 sibling, 1 reply; 4+ messages in thread
From: Jean-Michel Hautbois @ 2026-06-07  8:49 UTC (permalink / raw)
  To: Geert Uytterhoeven, Sebastian Reichel, Greg Ungerer
  Cc: linux-m68k, linux-kernel, linux-pm, Jean-Michel Hautbois

Add a driver that decodes the Reset Status Register (RSR) of the
Freescale ColdFire MCF5441x Reset Controller Module at probe time
and exposes the cause via the power_on_reason sysfs ABI.

The RSR can latch several cause bits simultaneously (Reference
Manual chapter 12.3.2); the driver picks one cause per a priority
that favours the most explanatory diagnostic.

The register layout is described in the driver so it can be built
with COMPILE_TEST on any architecture.

Signed-off-by: Jean-Michel Hautbois <jeanmichel.hautbois@yoseli.org>
---
 MAINTAINERS                         |   6 ++
 drivers/power/reset/Kconfig         |  12 ++++
 drivers/power/reset/Makefile        |   1 +
 drivers/power/reset/mcf-rcm-reset.c | 126 ++++++++++++++++++++++++++++++++++++
 4 files changed, 145 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index e035a3be797c..a82adb6fa40f 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -10196,6 +10196,12 @@ S:	Maintained
 F:	drivers/mmc/host/sdhci-esdhc-mcf.c
 F:	include/linux/platform_data/mmc-esdhc-mcf.h
 
+FREESCALE COLDFIRE M5441X RCM POWER-ON REASON DRIVER
+M:	Jean-Michel Hautbois <jeanmichel.hautbois@yoseli.org>
+L:	linux-m68k@lists.linux-m68k.org
+S:	Maintained
+F:	drivers/power/reset/mcf-rcm-reset.c
+
 FREESCALE DIU FRAMEBUFFER DRIVER
 M:	Timur Tabi <timur@kernel.org>
 L:	linux-fbdev@vger.kernel.org
diff --git a/drivers/power/reset/Kconfig b/drivers/power/reset/Kconfig
index 124afb99febe..bce996bbef28 100644
--- a/drivers/power/reset/Kconfig
+++ b/drivers/power/reset/Kconfig
@@ -128,6 +128,18 @@ config POWER_RESET_LINKSTATION
 
 	  Say Y here if you have a Buffalo LinkStation LS421D/E.
 
+config POWER_RESET_MCF_RCM
+	tristate "Freescale ColdFire RCM power-on reason driver"
+	depends on M5441x || COMPILE_TEST
+	depends on HAS_IOMEM
+	help
+	  This driver exposes the cause of the last reset on Freescale
+	  ColdFire 5441x SoCs through the standard power_on_reason sysfs
+	  ABI. It reads the Reset Status Register (RSR) of the Reset
+	  Controller Module once at probe time and reports a normalised
+	  string (regular power-up, reset button action, software reset
+	  or unknown reason).
+
 config POWER_RESET_MACSMC
 	tristate "Apple SMC reset/power-off driver"
 	depends on MFD_MACSMC
diff --git a/drivers/power/reset/Makefile b/drivers/power/reset/Makefile
index d7ae97241a83..e31cab4ba78e 100644
--- a/drivers/power/reset/Makefile
+++ b/drivers/power/reset/Makefile
@@ -13,6 +13,7 @@ obj-$(CONFIG_POWER_RESET_GPIO) += gpio-poweroff.o
 obj-$(CONFIG_POWER_RESET_GPIO_RESTART) += gpio-restart.o
 obj-$(CONFIG_POWER_RESET_HISI) += hisi-reboot.o
 obj-$(CONFIG_POWER_RESET_LINKSTATION) += linkstation-poweroff.o
+obj-$(CONFIG_POWER_RESET_MCF_RCM) += mcf-rcm-reset.o
 obj-$(CONFIG_POWER_RESET_MACSMC) += macsmc-reboot.o
 obj-$(CONFIG_POWER_RESET_MSM) += msm-poweroff.o
 obj-$(CONFIG_POWER_RESET_MT6323) += mt6323-poweroff.o
diff --git a/drivers/power/reset/mcf-rcm-reset.c b/drivers/power/reset/mcf-rcm-reset.c
new file mode 100644
index 000000000000..a3164bdcdfb3
--- /dev/null
+++ b/drivers/power/reset/mcf-rcm-reset.c
@@ -0,0 +1,126 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Freescale ColdFire MCF5441x RCM power-on reason driver
+ *
+ * Copyright (C) 2026 Jean-Michel Hautbois <jeanmichel.hautbois@yoseli.org>
+ */
+
+#include <linux/io.h>
+#include <linux/mod_devicetable.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/power/power_on_reason.h>
+
+/*
+ * Reset Status Register (RSR) layout, MCF54418 Reference Manual chapter
+ * 12.3.2. The register is 8-bit read-only and latches the cause (or
+ * causes) of the most recent reset until the next one occurs.
+ */
+#define MCF_RSR_SOFT		0x20	/* Last reset caused by software */
+#define MCF_RSR_LOC		0x10	/* Last reset caused by PLL loss of clock */
+#define MCF_RSR_POR		0x08	/* Last reset caused by power-on */
+#define MCF_RSR_EXT		0x04	/* Last reset caused by external pin */
+#define MCF_RSR_WDRCORE		0x02	/* Last reset caused by core watchdog */
+#define MCF_RSR_LOL		0x01	/* Last reset caused by PLL loss of lock */
+
+#define MCF_RSR_KNOWN_CAUSES	(MCF_RSR_POR | MCF_RSR_EXT | MCF_RSR_WDRCORE | \
+				 MCF_RSR_LOC | MCF_RSR_LOL | MCF_RSR_SOFT)
+
+struct mcf_rcm {
+	const char *reason;
+};
+
+/*
+ * Decode RSR into a power_on_reason string.
+ *
+ * The MCF5441x Reset Status Register can latch several cause bits at the
+ * same time (Reference Manual chapter 12.3.2: "one or more status bits
+ * may be set at the same time"). A power-on, for example, also resets
+ * the PLL and may co-flag LOC and LOL during the boot sequence. The
+ * power_on_reason ABI carries a single string, so this routine picks
+ * one cause; the chosen priority surfaces the most explanatory one for
+ * diagnostics:
+ *
+ *   POR              cold boot dominates any spurious co-flagged cause
+ *   EXT              operator action via the RESET pin
+ *   WDRCORE          core watchdog timeout, a fault to investigate
+ *   LOC, LOL         PLL clock or lock failure, hardware fault
+ *   SOFT             explicit software-requested reset
+ */
+static const char *mcf_rcm_decode(u8 rsr)
+{
+	if (rsr & MCF_RSR_POR)
+		return POWER_ON_REASON_REGULAR;
+	if (rsr & MCF_RSR_EXT)
+		return POWER_ON_REASON_RST_BTN;
+	if (rsr & MCF_RSR_WDRCORE)
+		return POWER_ON_REASON_WATCHDOG;
+	if (rsr & (MCF_RSR_LOC | MCF_RSR_LOL))
+		return POWER_ON_REASON_CPU_CLK_FAIL;
+	if (rsr & MCF_RSR_SOFT)
+		return POWER_ON_REASON_SOFTWARE;
+	return POWER_ON_REASON_UNKNOWN;
+}
+
+static ssize_t power_on_reason_show(struct device *dev,
+				    struct device_attribute *attr, char *buf)
+{
+	struct mcf_rcm *rcm = platform_get_drvdata(to_platform_device(dev));
+
+	return sysfs_emit(buf, "%s\n", rcm->reason);
+}
+static DEVICE_ATTR_RO(power_on_reason);
+
+static struct attribute *mcf_rcm_attrs[] = {
+	&dev_attr_power_on_reason.attr,
+	NULL,
+};
+ATTRIBUTE_GROUPS(mcf_rcm);
+
+static int mcf_rcm_probe(struct platform_device *pdev)
+{
+	struct mcf_rcm *rcm;
+	void __iomem *base;
+	u8 rsr;
+
+	rcm = devm_kzalloc(&pdev->dev, sizeof(*rcm), GFP_KERNEL);
+	if (!rcm)
+		return -ENOMEM;
+
+	base = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(base))
+		return PTR_ERR(base);
+
+	rsr = readb_relaxed(base);
+	rcm->reason = mcf_rcm_decode(rsr);
+
+	platform_set_drvdata(pdev, rcm);
+
+	if (!(rsr & MCF_RSR_KNOWN_CAUSES))
+		dev_warn(&pdev->dev, "Unknown reset cause (RSR=0x%02x)\n", rsr);
+	else
+		dev_info(&pdev->dev, "Starting after %s (RSR=0x%02x)\n",
+			 rcm->reason, rsr);
+
+	return 0;
+}
+
+static const struct platform_device_id mcf_rcm_id[] = {
+	{ "mcf-rcm-reset", 0 },
+	{ }
+};
+MODULE_DEVICE_TABLE(platform, mcf_rcm_id);
+
+static struct platform_driver mcf_rcm_driver = {
+	.probe = mcf_rcm_probe,
+	.id_table = mcf_rcm_id,
+	.driver = {
+		.name = "mcf-rcm-reset",
+		.dev_groups = mcf_rcm_groups,
+	},
+};
+module_platform_driver(mcf_rcm_driver);
+
+MODULE_AUTHOR("Jean-Michel Hautbois <jeanmichel.hautbois@yoseli.org>");
+MODULE_DESCRIPTION("Freescale ColdFire RCM power-on reason driver");
+MODULE_LICENSE("GPL");

-- 
2.39.5


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

* [PATCH v2 2/2] m68k: coldfire/5441x: register mcf-rcm-reset platform device
  2026-06-07  8:49 [PATCH v2 0/2] Coldfire m5441x: add RCM power-on reason driver Jean-Michel Hautbois
  2026-06-07  8:49 ` [PATCH v2 1/2] power: reset: add MCF5441x " Jean-Michel Hautbois
@ 2026-06-07  8:49 ` Jean-Michel Hautbois
  1 sibling, 0 replies; 4+ messages in thread
From: Jean-Michel Hautbois @ 2026-06-07  8:49 UTC (permalink / raw)
  To: Geert Uytterhoeven, Sebastian Reichel, Greg Ungerer
  Cc: linux-m68k, linux-kernel, linux-pm, Jean-Michel Hautbois

Add SoC-level registration of the mcf-rcm-reset platform device so the
power_on_reason sysfs attribute is created on every MCF5441x board
without per-board boilerplate.

Signed-off-by: Jean-Michel Hautbois <jeanmichel.hautbois@yoseli.org>
---
 arch/m68k/coldfire/m5441x.c | 25 +++++++++++++++++++++++++
 1 file changed, 25 insertions(+)

diff --git a/arch/m68k/coldfire/m5441x.c b/arch/m68k/coldfire/m5441x.c
index 7a25cfc7ac07..852e52d95eaf 100644
--- a/arch/m68k/coldfire/m5441x.c
+++ b/arch/m68k/coldfire/m5441x.c
@@ -11,6 +11,7 @@
 #include <linux/init.h>
 #include <linux/io.h>
 #include <linux/clk.h>
+#include <linux/platform_device.h>
 #include <asm/machdep.h>
 #include <asm/coldfire.h>
 #include <asm/mcfsim.h>
@@ -239,6 +240,30 @@ static void __init m5441x_fec_init(void)
 	__raw_writeb(0x03, MCFGPIO_PAR_FEC);
 }
 
+/*
+ * Reset Controller Module status register. Exposed to userspace as
+ * /sys/devices/platform/mcf-rcm-reset/power_on_reason by the mcf-rcm-reset
+ * driver (drivers/power/reset/mcf-rcm-reset.c).
+ */
+static struct resource m5441x_rcm_resource[] = {
+	{
+		.start	= MCF_RSR,
+		.end	= MCF_RSR,
+		.flags	= IORESOURCE_MEM,
+	},
+};
+
+static int __init m5441x_rcm_init(void)
+{
+	struct platform_device *pdev;
+
+	pdev = platform_device_register_simple("mcf-rcm-reset", -1,
+					       m5441x_rcm_resource,
+					       ARRAY_SIZE(m5441x_rcm_resource));
+	return PTR_ERR_OR_ZERO(pdev);
+}
+arch_initcall(m5441x_rcm_init);
+
 void __init config_BSP(char *commandp, int size)
 {
 	m5441x_clk_init();

-- 
2.39.5


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

* Re: [PATCH v2 1/2] power: reset: add MCF5441x RCM power-on reason driver
  2026-06-07  8:49 ` [PATCH v2 1/2] power: reset: add MCF5441x " Jean-Michel Hautbois
@ 2026-06-17 14:27   ` Uwe Kleine-König
  0 siblings, 0 replies; 4+ messages in thread
From: Uwe Kleine-König @ 2026-06-17 14:27 UTC (permalink / raw)
  To: Jean-Michel Hautbois
  Cc: Geert Uytterhoeven, Sebastian Reichel, Greg Ungerer, linux-m68k,
	linux-kernel, linux-pm

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

Hello Jean-Michel,

On Sun, Jun 07, 2026 at 10:49:53AM +0200, Jean-Michel Hautbois wrote:
> +static const struct platform_device_id mcf_rcm_id[] = {
> +	{ "mcf-rcm-reset", 0 },

Please drop the 0 here (and the , before it).

> +	{ }
> +};

Best regards
Uwe

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

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

end of thread, other threads:[~2026-06-17 14:27 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-06-07  8:49 [PATCH v2 0/2] Coldfire m5441x: add RCM power-on reason driver Jean-Michel Hautbois
2026-06-07  8:49 ` [PATCH v2 1/2] power: reset: add MCF5441x " Jean-Michel Hautbois
2026-06-17 14:27   ` Uwe Kleine-König
2026-06-07  8:49 ` [PATCH v2 2/2] m68k: coldfire/5441x: register mcf-rcm-reset platform device Jean-Michel Hautbois

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.