Message ID | 20230620062657.3127468-1-miquel.raynal@bootlin.com (mailing list archive) |
---|---|
State | Handled Elsewhere, archived |
Headers | show |
Series | [v4] power: reset: at91-reset: add sysfs interface to the power on reason | expand |
Hi Sebastian, miquel.raynal@bootlin.com wrote on Tue, 20 Jun 2023 08:26:57 +0200: > From: Kamel Bouhara <kamel.bouhara@bootlin.com> > > Introduce a list of generic reset sources and use them to export the > power on reason through sysfs. Update the ABI documentation to describe > this new interface. I just rebased this patch on top of -rc1, no conflict whatsoever, do you need a resend or are you still considering this version? > Signed-off-by: Kamel Bouhara <kamel.bouhara@bootlin.com> > Acked-by: Nicolas Ferre <nicolas.ferre@microchip.com> > [Miquel Raynal: Follow-up on Kamel's work, 4 years later] > Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com> Cheers, Miquèl > --- > > Changes in v4: > * Patch 1/2 was merged. > * Changed the "low-power condition" into a "brown-out reset" as > suggested by Sebastian. > > Changes in v3: > * Made the series bisectable. > * Updated the date and kernel version for this new feature. > * Changed a few definitions as discussed with Sebastian. > > Changes in v2: > * Collected Nicolas' Acked-by > * Dropped the Xtal frequency information (as this may change between > platforms of course). > > .../testing/sysfs-platform-power-on-reason | 12 ++++++ > drivers/power/reset/at91-reset.c | 37 ++++++++++++++----- > include/linux/power/power_on_reason.h | 19 ++++++++++ > 3 files changed, 58 insertions(+), 10 deletions(-) > create mode 100644 Documentation/ABI/testing/sysfs-platform-power-on-reason > create mode 100644 include/linux/power/power_on_reason.h > > diff --git a/Documentation/ABI/testing/sysfs-platform-power-on-reason b/Documentation/ABI/testing/sysfs-platform-power-on-reason > new file mode 100644 > index 000000000000..c3b29dbc64bf > --- /dev/null > +++ b/Documentation/ABI/testing/sysfs-platform-power-on-reason > @@ -0,0 +1,12 @@ > +What: /sys/devices/platform/.../power_on_reason > +Date: June 2023 > +KernelVersion: 6.5 > +Contact: Kamel Bouhara <kamel.bouhara@bootlin.com> > +Description: Shows system power on reason. The following strings/reasons can > + be read (the list can be extended): > + "regular power-up", "RTC wakeup", "watchdog timeout", > + "software reset", "reset button action", "CPU clock failure", > + "crystal oscillator failure", "brown-out reset", > + "unknown reason". > + > + The file is read only. > diff --git a/drivers/power/reset/at91-reset.c b/drivers/power/reset/at91-reset.c > index d6884841a6dc..aa9b012d3d00 100644 > --- a/drivers/power/reset/at91-reset.c > +++ b/drivers/power/reset/at91-reset.c > @@ -18,6 +18,7 @@ > #include <linux/platform_device.h> > #include <linux/reboot.h> > #include <linux/reset-controller.h> > +#include <linux/power/power_on_reason.h> > > #include <soc/at91/at91sam9_ddrsdr.h> > #include <soc/at91/at91sam9_sdramc.h> > @@ -149,44 +150,54 @@ static int at91_reset(struct notifier_block *this, unsigned long mode, > return NOTIFY_DONE; > } > > -static const char * __init at91_reset_reason(struct at91_reset *reset) > +static const char *at91_reset_reason(struct at91_reset *reset) > { > u32 reg = readl(reset->rstc_base + AT91_RSTC_SR); > const char *reason; > > switch ((reg & AT91_RSTC_RSTTYP) >> 8) { > case RESET_TYPE_GENERAL: > - reason = "general reset"; > + reason = POWER_ON_REASON_REGULAR; > break; > case RESET_TYPE_WAKEUP: > - reason = "wakeup"; > + reason = POWER_ON_REASON_RTC; > break; > case RESET_TYPE_WATCHDOG: > - reason = "watchdog reset"; > + reason = POWER_ON_REASON_WATCHDOG; > break; > case RESET_TYPE_SOFTWARE: > - reason = "software reset"; > + reason = POWER_ON_REASON_SOFTWARE; > break; > case RESET_TYPE_USER: > - reason = "user reset"; > + reason = POWER_ON_REASON_RST_BTN; > break; > case RESET_TYPE_CPU_FAIL: > - reason = "CPU clock failure detection"; > + reason = POWER_ON_REASON_CPU_CLK_FAIL; > break; > case RESET_TYPE_XTAL_FAIL: > - reason = "32.768 kHz crystal failure detection"; > + reason = POWER_ON_REASON_XTAL_FAIL; > break; > case RESET_TYPE_ULP2: > - reason = "ULP2 reset"; > + reason = POWER_ON_REASON_BROWN_OUT; > break; > default: > - reason = "unknown reset"; > + reason = POWER_ON_REASON_UNKNOWN; > break; > } > > return reason; > } > > +static ssize_t power_on_reason_show(struct device *dev, > + struct device_attribute *attr, char *buf) > +{ > + struct platform_device *pdev = to_platform_device(dev); > + struct at91_reset *reset = platform_get_drvdata(pdev); > + > + return sprintf(buf, "%s\n", at91_reset_reason(reset)); > +} > +static DEVICE_ATTR_RO(power_on_reason); > + > static const struct of_device_id at91_ramc_of_match[] = { > { > .compatible = "atmel,at91sam9260-sdramc", > @@ -391,6 +402,12 @@ static int __init at91_reset_probe(struct platform_device *pdev) > if (ret) > goto disable_clk; > > + ret = device_create_file(&pdev->dev, &dev_attr_power_on_reason); > + if (ret) { > + dev_err(&pdev->dev, "Could not create sysfs entry\n"); > + return ret; > + } > + > dev_info(&pdev->dev, "Starting after %s\n", at91_reset_reason(reset)); > > return 0; > diff --git a/include/linux/power/power_on_reason.h b/include/linux/power/power_on_reason.h > new file mode 100644 > index 000000000000..95a1ec0c403c > --- /dev/null > +++ b/include/linux/power/power_on_reason.h > @@ -0,0 +1,19 @@ > +/* SPDX-License-Identifier: GPL-2.0-only */ > +/* > + * Author: Kamel Bouhra <kamel.bouhara@bootlin.com> > + */ > + > +#ifndef POWER_ON_REASON_H > +#define POWER_ON_REASON_H > + > +#define POWER_ON_REASON_REGULAR "regular power-up" > +#define POWER_ON_REASON_RTC "RTC wakeup" > +#define POWER_ON_REASON_WATCHDOG "watchdog timeout" > +#define POWER_ON_REASON_SOFTWARE "software reset" > +#define POWER_ON_REASON_RST_BTN "reset button action" > +#define POWER_ON_REASON_CPU_CLK_FAIL "CPU clock failure" > +#define POWER_ON_REASON_XTAL_FAIL "crystal oscillator failure" > +#define POWER_ON_REASON_BROWN_OUT "brown-out reset" > +#define POWER_ON_REASON_UNKNOWN "unknown reason" > + > +#endif /* POWER_ON_REASON_H */
Hi, On Wed, Jul 12, 2023 at 05:58:53PM +0200, Miquel Raynal wrote: > > From: Kamel Bouhara <kamel.bouhara@bootlin.com> > > > > Introduce a list of generic reset sources and use them to export the > > power on reason through sysfs. Update the ABI documentation to describe > > this new interface. > > I just rebased this patch on top of -rc1, no conflict whatsoever, do > you need a resend or are you still considering this version? > > > Signed-off-by: Kamel Bouhara <kamel.bouhara@bootlin.com> > > Acked-by: Nicolas Ferre <nicolas.ferre@microchip.com> > > [Miquel Raynal: Follow-up on Kamel's work, 4 years later] > > Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com> Thanks, queued. -- Sebastian
diff --git a/Documentation/ABI/testing/sysfs-platform-power-on-reason b/Documentation/ABI/testing/sysfs-platform-power-on-reason new file mode 100644 index 000000000000..c3b29dbc64bf --- /dev/null +++ b/Documentation/ABI/testing/sysfs-platform-power-on-reason @@ -0,0 +1,12 @@ +What: /sys/devices/platform/.../power_on_reason +Date: June 2023 +KernelVersion: 6.5 +Contact: Kamel Bouhara <kamel.bouhara@bootlin.com> +Description: Shows system power on reason. The following strings/reasons can + be read (the list can be extended): + "regular power-up", "RTC wakeup", "watchdog timeout", + "software reset", "reset button action", "CPU clock failure", + "crystal oscillator failure", "brown-out reset", + "unknown reason". + + The file is read only. diff --git a/drivers/power/reset/at91-reset.c b/drivers/power/reset/at91-reset.c index d6884841a6dc..aa9b012d3d00 100644 --- a/drivers/power/reset/at91-reset.c +++ b/drivers/power/reset/at91-reset.c @@ -18,6 +18,7 @@ #include <linux/platform_device.h> #include <linux/reboot.h> #include <linux/reset-controller.h> +#include <linux/power/power_on_reason.h> #include <soc/at91/at91sam9_ddrsdr.h> #include <soc/at91/at91sam9_sdramc.h> @@ -149,44 +150,54 @@ static int at91_reset(struct notifier_block *this, unsigned long mode, return NOTIFY_DONE; } -static const char * __init at91_reset_reason(struct at91_reset *reset) +static const char *at91_reset_reason(struct at91_reset *reset) { u32 reg = readl(reset->rstc_base + AT91_RSTC_SR); const char *reason; switch ((reg & AT91_RSTC_RSTTYP) >> 8) { case RESET_TYPE_GENERAL: - reason = "general reset"; + reason = POWER_ON_REASON_REGULAR; break; case RESET_TYPE_WAKEUP: - reason = "wakeup"; + reason = POWER_ON_REASON_RTC; break; case RESET_TYPE_WATCHDOG: - reason = "watchdog reset"; + reason = POWER_ON_REASON_WATCHDOG; break; case RESET_TYPE_SOFTWARE: - reason = "software reset"; + reason = POWER_ON_REASON_SOFTWARE; break; case RESET_TYPE_USER: - reason = "user reset"; + reason = POWER_ON_REASON_RST_BTN; break; case RESET_TYPE_CPU_FAIL: - reason = "CPU clock failure detection"; + reason = POWER_ON_REASON_CPU_CLK_FAIL; break; case RESET_TYPE_XTAL_FAIL: - reason = "32.768 kHz crystal failure detection"; + reason = POWER_ON_REASON_XTAL_FAIL; break; case RESET_TYPE_ULP2: - reason = "ULP2 reset"; + reason = POWER_ON_REASON_BROWN_OUT; break; default: - reason = "unknown reset"; + reason = POWER_ON_REASON_UNKNOWN; break; } return reason; } +static ssize_t power_on_reason_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct platform_device *pdev = to_platform_device(dev); + struct at91_reset *reset = platform_get_drvdata(pdev); + + return sprintf(buf, "%s\n", at91_reset_reason(reset)); +} +static DEVICE_ATTR_RO(power_on_reason); + static const struct of_device_id at91_ramc_of_match[] = { { .compatible = "atmel,at91sam9260-sdramc", @@ -391,6 +402,12 @@ static int __init at91_reset_probe(struct platform_device *pdev) if (ret) goto disable_clk; + ret = device_create_file(&pdev->dev, &dev_attr_power_on_reason); + if (ret) { + dev_err(&pdev->dev, "Could not create sysfs entry\n"); + return ret; + } + dev_info(&pdev->dev, "Starting after %s\n", at91_reset_reason(reset)); return 0; diff --git a/include/linux/power/power_on_reason.h b/include/linux/power/power_on_reason.h new file mode 100644 index 000000000000..95a1ec0c403c --- /dev/null +++ b/include/linux/power/power_on_reason.h @@ -0,0 +1,19 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Author: Kamel Bouhra <kamel.bouhara@bootlin.com> + */ + +#ifndef POWER_ON_REASON_H +#define POWER_ON_REASON_H + +#define POWER_ON_REASON_REGULAR "regular power-up" +#define POWER_ON_REASON_RTC "RTC wakeup" +#define POWER_ON_REASON_WATCHDOG "watchdog timeout" +#define POWER_ON_REASON_SOFTWARE "software reset" +#define POWER_ON_REASON_RST_BTN "reset button action" +#define POWER_ON_REASON_CPU_CLK_FAIL "CPU clock failure" +#define POWER_ON_REASON_XTAL_FAIL "crystal oscillator failure" +#define POWER_ON_REASON_BROWN_OUT "brown-out reset" +#define POWER_ON_REASON_UNKNOWN "unknown reason" + +#endif /* POWER_ON_REASON_H */