From: Matt Turner <mattst88@gmail.com>
To: Richard Henderson <richard.henderson@linaro.org>,
Magnus Lindholm <linmag7@gmail.com>,
Guenter Roeck <linux@roeck-us.net>
Cc: linux-alpha@vger.kernel.org, linux-kernel@vger.kernel.org,
linux-hwmon@vger.kernel.org, linux-doc@vger.kernel.org,
Matt Turner <mattst88@gmail.com>
Subject: [PATCH 7/7] hwmon: (marvel-env) Notify userspace of environmental events
Date: Sat, 14 Nov 2026 12:39:53 -0500 [thread overview]
Message-ID: <20261114-marvel-env-v1-7-890328e4b7e5@gmail.com> (raw)
In-Reply-To: <20261114-marvel-env-v1-0-890328e4b7e5@gmail.com>
The firmware reports each change of a sensor's state as a system event
machine check. On one, reread every node from a workqueue and notify
userspace of the alarms that changed. The notifier runs in machine check
context, so it only queues an irq_work, which queues the work.
Assisted-by: Claude:claude-opus-5-5
Signed-off-by: Matt Turner <mattst88@gmail.com>
---
Documentation/hwmon/marvel-env.rst | 4 ++
drivers/hwmon/Kconfig | 1 +
drivers/hwmon/marvel-env.c | 89 ++++++++++++++++++++++++++++++++++++--
3 files changed, 90 insertions(+), 4 deletions(-)
diff --git a/Documentation/hwmon/marvel-env.rst b/Documentation/hwmon/marvel-env.rst
index db36127c3805..f88feba7bfe4 100644
--- a/Documentation/hwmon/marvel-env.rst
+++ b/Documentation/hwmon/marvel-env.rst
@@ -27,6 +27,10 @@ A refresh keeps the boot CPU in the console with interrupts disabled for up
to 300 ms per unit, so a unit is refreshed at most once every
``update_interval`` milliseconds (10000 by default).
+The firmware also reports every change of state as a system event machine
+check. When one arrives, the driver refreshes all units and notifies
+userspace through the alarm attributes.
+
Sysfs entries
-------------
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
index 50a1bf966f30..6d17c2e89a7c 100644
--- a/drivers/hwmon/Kconfig
+++ b/drivers/hwmon/Kconfig
@@ -1258,6 +1258,7 @@ config SENSORS_MACSMC_HWMON
config SENSORS_MARVEL_ENV
tristate "Marvel (EV7) AlphaServer environmental sensors"
depends on ALPHA_MARVEL || ALPHA_GENERIC
+ select IRQ_WORK
help
If you say yes here you get support for the temperature, fan,
voltage and power supply sensors of Marvel AlphaServers (the
diff --git a/drivers/hwmon/marvel-env.c b/drivers/hwmon/marvel-env.c
index cdc7e059e17b..3dd2ea658fa3 100644
--- a/drivers/hwmon/marvel-env.c
+++ b/drivers/hwmon/marvel-env.c
@@ -11,13 +11,16 @@
*/
#include <linux/hwmon.h>
+#include <linux/irq_work.h>
#include <linux/jiffies.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/mutex.h>
+#include <linux/notifier.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/string.h>
+#include <linux/workqueue.h>
#include <asm/gct.h>
#include <asm/marvel_env.h>
@@ -81,17 +84,22 @@ struct marvel_env_node {
struct marvel_env_chan {
struct marvel_env_node *node;
unsigned int pkt; /* packet offset in the node */
+ u8 last_status;
char label[32];
};
struct marvel_env_data {
struct device *dev;
+ struct device *hwmon;
struct mutex lock; /* serializes refreshes and reads */
unsigned int update_interval; /* ms */
struct marvel_env_node *nodes;
unsigned int nr_nodes;
struct marvel_env_chan *chans[hwmon_max];
unsigned int nr_chans[hwmon_max];
+ struct irq_work irq_work;
+ struct work_struct work;
+ struct notifier_block nb;
};
static const char * const pe_names[] = {
@@ -226,6 +234,7 @@ static void marvel_env_add_chan(struct marvel_env_data *data,
c = &data->chans[type][data->nr_chans[type]++];
c->node = n;
c->pkt = pkt;
+ c->last_status = env_status(n, pkt + env_status_off(type));
if (n->cabinet || n->drawer)
len = scnprintf(c->label, sizeof(c->label), "Cab%u Dra%u ",
@@ -460,6 +469,72 @@ static const struct {
{ hwmon_power, HWMON_P_ALARM | HWMON_P_LABEL },
};
+static const u32 marvel_env_alarm[hwmon_max] = {
+ [hwmon_temp] = hwmon_temp_max_alarm,
+ [hwmon_fan] = hwmon_fan_min_alarm,
+ [hwmon_in] = hwmon_in_alarm,
+ [hwmon_power] = hwmon_power_alarm,
+};
+
+/* Reread everything after a system event and report changed alarms. */
+static void marvel_env_event_work(struct work_struct *work)
+{
+ struct marvel_env_data *data =
+ container_of(work, struct marvel_env_data, work);
+ unsigned int i, k;
+
+ mutex_lock(&data->lock);
+ for (i = 0; i < data->nr_nodes; i++) {
+ data->nodes[i].valid = false;
+ marvel_env_refresh(data, &data->nodes[i]);
+ }
+
+ for (k = 0; k < ARRAY_SIZE(marvel_env_hwmon); k++) {
+ enum hwmon_sensor_types type = marvel_env_hwmon[k].type;
+
+ for (i = 0; i < data->nr_chans[type]; i++) {
+ struct marvel_env_chan *c = &data->chans[type][i];
+ u8 status = env_status(c->node,
+ c->pkt + env_status_off(type));
+
+ if (status == c->last_status)
+ continue;
+ c->last_status = status;
+ hwmon_notify_event(data->hwmon, type,
+ marvel_env_alarm[type], i);
+ }
+ }
+ mutex_unlock(&data->lock);
+}
+
+static void marvel_env_irq_work(struct irq_work *irq_work)
+{
+ struct marvel_env_data *data =
+ container_of(irq_work, struct marvel_env_data, irq_work);
+
+ schedule_work(&data->work);
+}
+
+/* Runs in machine check context, so only queue the irq_work. */
+static int marvel_env_event(struct notifier_block *nb, unsigned long action,
+ void *unused)
+{
+ struct marvel_env_data *data =
+ container_of(nb, struct marvel_env_data, nb);
+
+ irq_work_queue(&data->irq_work);
+ return NOTIFY_OK;
+}
+
+static void marvel_env_unregister(void *arg)
+{
+ struct marvel_env_data *data = arg;
+
+ atomic_notifier_chain_unregister(&marvel_env_notifier, &data->nb);
+ irq_work_sync(&data->irq_work);
+ cancel_work_sync(&data->work);
+}
+
static const struct hwmon_channel_info * const marvel_env_chip_info =
HWMON_CHANNEL_INFO(chip, HWMON_C_UPDATE_INTERVAL);
@@ -469,7 +544,6 @@ static int marvel_env_probe(struct platform_device *pdev)
const struct hwmon_channel_info **info;
struct marvel_env_data *data;
struct hwmon_chip_info *chip;
- struct device *hwmon;
unsigned int i, k, nr_info = 0;
data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
@@ -534,9 +608,16 @@ static int marvel_env_probe(struct platform_device *pdev)
chip->ops = &marvel_env_ops;
chip->info = info;
- hwmon = devm_hwmon_device_register_with_info(dev, DRVNAME, data, chip,
- NULL);
- return PTR_ERR_OR_ZERO(hwmon);
+ data->hwmon = devm_hwmon_device_register_with_info(dev, DRVNAME, data,
+ chip, NULL);
+ if (IS_ERR(data->hwmon))
+ return PTR_ERR(data->hwmon);
+
+ init_irq_work(&data->irq_work, marvel_env_irq_work);
+ INIT_WORK(&data->work, marvel_env_event_work);
+ data->nb.notifier_call = marvel_env_event;
+ atomic_notifier_chain_register(&marvel_env_notifier, &data->nb);
+ return devm_add_action_or_reset(dev, marvel_env_unregister, data);
}
static struct platform_driver marvel_env_driver = {
--
2.56.1
next prev parent reply other threads:[~2026-11-14 17:40 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-11-14 17:39 [PATCH 0/7] alpha: marvel: environmental sensors Matt Turner
2026-11-14 17:39 ` [PATCH 1/7] alpha: marvel: report environmental events without VERBOSE_MCHECK Matt Turner
2026-11-14 17:43 ` sashiko-bot
2026-11-14 17:39 ` [PATCH 2/7] alpha: marvel: fix the environmental subpacket layout Matt Turner
2026-11-14 17:44 ` sashiko-bot
2026-11-14 17:39 ` [PATCH 3/7] alpha: marvel: refresh environmental readings through the console Matt Turner
2026-11-14 17:47 ` sashiko-bot
2026-11-14 17:39 ` [PATCH 4/7] alpha: marvel: register a platform device for the environmental sensors Matt Turner
2026-11-14 17:44 ` sashiko-bot
2026-11-14 17:39 ` [PATCH 5/7] hwmon: Add driver for Marvel AlphaServer " Matt Turner
2026-11-14 17:57 ` sashiko-bot
2026-11-14 17:39 ` [PATCH 6/7] alpha: marvel: notify environmental events Matt Turner
2026-11-14 17:45 ` sashiko-bot
2026-11-14 17:39 ` Matt Turner [this message]
2026-11-14 17:52 ` [PATCH 7/7] hwmon: (marvel-env) Notify userspace of " sashiko-bot
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=20261114-marvel-env-v1-7-890328e4b7e5@gmail.com \
--to=mattst88@gmail.com \
--cc=linmag7@gmail.com \
--cc=linux-alpha@vger.kernel.org \
--cc=linux-doc@vger.kernel.org \
--cc=linux-hwmon@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux@roeck-us.net \
--cc=richard.henderson@linaro.org \
/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 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.