Re: [PATCH 2/3] power: reset: add MCF5441x RCM power-on reason driver
Sebastian Reichel <[email protected]>
| Newsgroups | org.kernel.vger.linux-m68k,org.kernel.vger.linux-kernel,org.kernel.vger.linux-pm |
|---|---|
| Message-ID | <aiGseFwWJkjCZrfB@venus> |
Hi, On Tue, Jun 02, 2026 at 11:21:22AM +0200, Jean-Michel Hautbois wrote: > 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. > > Signed-off-by: Jean-Michel Hautbois <[email protected]> > --- > MAINTAINERS | 6 ++ > drivers/power/reset/Kconfig | 12 ++++ > drivers/power/reset/Makefile | 1 + > drivers/power/reset/mcf-rcm-reset.c | 109 ++++++++++++++++++++++++++++++++++++ > 4 files changed, 128 insertions(+) > > diff --git a/MAINTAINERS b/MAINTAINERS > index 461a3eed6129..1109bff23ec1 100644 > --- a/MAINTAINERS > +++ b/MAINTAINERS > @@ -10195,6 +10195,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 <[email protected]> > +L: [email protected] > +S: Maintained > +F: drivers/power/reset/mcf-rcm-reset.c > + > FREESCALE DIU FRAMEBUFFER DRIVER > M: Timur Tabi <[email protected]> > L: [email protected] > diff --git a/drivers/power/reset/Kconfig b/drivers/power/reset/Kconfig > index 124afb99febe..003638f652fa 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 If you describe the register layout in the driver, you could add "|| COMPILE_TEST" resulting in much better test coverage. > + 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..666ae1455be1 > --- /dev/null > +++ b/drivers/power/reset/mcf-rcm-reset.c > @@ -0,0 +1,109 @@ > +// SPDX-License-Identifier: GPL-2.0 > +/* > + * Freescale ColdFire MCF5441x RCM power-on reason driver > + * > + * Copyright (C) 2026 Jean-Michel Hautbois <[email protected]> > + */ > + > +#include <linux/io.h> > +#include <linux/module.h> > +#include <linux/platform_device.h> > +#include <linux/power/power_on_reason.h> > + > +#include <asm/m5441xsim.h> > + > +#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, > + .driver = { > + .name = "mcf-rcm-reset", > + .dev_groups = mcf_rcm_groups, > + }, .id_table = mcf_rcm_id, > +}; > +module_platform_driver(mcf_rcm_driver); > + > +MODULE_AUTHOR("Jean-Michel Hautbois <[email protected]>"); > +MODULE_DESCRIPTION("Freescale ColdFire RCM power-on reason driver"); > +MODULE_LICENSE("GPL"); > +MODULE_ALIAS("platform:mcf-rcm-reset"); You can drop the MODULE_ALIAS with the platform ID table being done properly. Otherwise LGTM. -- Sebastian
signature.asc
(application/pgp-signature, 833 B)
-----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEE72YNB0Y/i3JqeVQT2O7X88g7+poFAmohr2gACgkQ2O7X88g7 +prA3xAAhtx7s9ZMrDvndLLu4dNHrOT72Dd8tdogegErykWXaQIf7Q83yb78wLG/ kjXnJqnmzS8Fv25syQPWIgQbxfzQzr4Y4wCMo0FFSGfN0fAezhokxJ1H/rxJ53h3 ZpiRaTGfwae4rfm/xaKaFabZoj2mSJYN4aZKQrqmg/3+73p8QZsWyInQViI0/Gah eQ3c6i0oX3bkePnyx2wVMSUxLAifTxJG2/tj2q87D1QAcgnQm9xXiyd6A+uqxGIs m6V9Xa6m5eIbSk6gD8LE9dHhGa2gpjeZpIjaMLKJhwqkQpWWUrplgOlSZRqc0xcl ssFbSWvkUNJepZlD54z4pvHTvQLw2l3gtUjObzYSZEkaP0mPq/c+s3VFCl/DmnNX evrH3hGaZUc7TJnk+6SDiyuk6sT7YbAsygcZKxeK783evgC+ZKy5TIlJ+NWAGTMu g/KcvecrUEtINz7VJEtYwMqIZHCMb8wAzqcTd8KhWj4KlEqR9FiIVSGmBPVJ/L63 0a9AfnOgGWK0DpVzs0J2wFRo3EP0J3OXx1QQsZ8SkhigmGY0sxbeme8dHhpbjGPQ wxrXKLUggFtaXze0qAApT+mtKOXwfTi6n5oNOikPOAlIUrYDqEyQ6Z7Z6+QuKcAJ QkyqUKAmrSdGHfjfbLDvs/ck8mC2PjthApW+bR5gFxP10y1sElY= =Eg/S -----END PGP SIGNATURE-----