hwmon: add Altera SoC FPGA hardware monitoring support
Subsystems (4)
[email protected]
maintainerv6 cover hwmon: add Altera SoC FPGA hardware monitoring support
From: Tze Yee Ng <[email protected]>
This series adds hardware monitor support for Altera SoC FPGA devices. Temperature and voltage sensors are accessed through the Stratix 10 service layer and Secure Device Manager (SDM).
Patch 1 adds async HWMON SMC support to stratix10-svc and registers the socfpga-hwmon platform device.
Patch 2 adds the socfpga-hwmon driver, documentation, Kconfig, and MAINTAINERS entry.
Changes in v6:
- Rebase on torvalds/master (given “Linux 7.2-rc4”)
- No functional changes in Patch 1 and Patch 2
Changes in v5:
- Rebase on dinguyen/socfpga_svc_fixes_for_v7.2
- Address Sashiko review feedback on socfpga-hwmon (Patch 2):
- Poll async responses until HWMON_TIMEOUT instead of a fixed 3-iteration retry loop (~3 ms), fixing premature timeouts on silicon
- Add MODULE_ALIAS("platform:socfpga-hwmon")
- No functional changes in Patch 1
Changes in v4:
- Address maintainer and review feedback on socfpga-hwmon (Patch 2):
- Register devm_add_action_or_reset() before devm_hwmon_device_register_with_info() to fix devres teardown order
- Remove unreferenced completion and pre-poll wait_for_completion_io_timeout() from async reads; poll directly with a retry loop after async_send()
- No functional changes in Patch 1
Changes in v3:
- Address review feedback on socfpga-hwmon (Patch 2):
- Fix 16-bit Q8.8 temperature sign extension
- Drop unused async callback; pass NULL to stratix10_svc_async_send()
- Document and retain pre-poll wait (RSU pattern; firmware needs time before async_poll())
- Align async poll retry behaviour with RSU
- Use uninterruptible wait_for_completion_timeout() for sync reads
- Handle -EINVAL and -EOPNOTSUPP when falling back to sync mode
- Defer SVC channel cleanup via devm_add_action_or_reset()
- No functional changes in Patch 1
Changes in v2:
- Drop altr,stratix10-hwmon DT binding and intel,stratix10-svc hwmon child property
- Drop Stratix 10 SoCDK DTS hwmon node
- Register socfpga-hwmon from stratix10-svc (RSU-style)
- Replace DT channel parsing with hardcoded Stratix 10 and Agilex tables
- Rename driver/module to socfpga-hwmon (CONFIG_SENSORS_ALTERA_SOCFPGA_HWMON)
- Add Agilex channel support
- Fix SDM value conversion (Q8.8 degrees Celsius and Q16 volts to hwmon millidegrees/millivolts)
- Improve sync-mode error handling via last_err
Previous version:
https://lore.kernel.org/all/[email protected]/
Tze Yee Ng (2):
firmware: stratix10-svc: add async HWMON read commands and register
socfpga-hwmon device
hwmon: add Altera SoC FPGA hardware monitoring driver
Documentation/hwmon/index.rst | 1 + Documentation/hwmon/socfpga-hwmon.rst | 34 ++ MAINTAINERS | 8 + drivers/firmware/stratix10-svc.c | 46 +- drivers/hwmon/Kconfig | 10 + drivers/hwmon/Makefile | 1 + drivers/hwmon/socfpga-hwmon.c | 579 +++++++++++++++++++ include/linux/firmware/intel/stratix10-smc.h | 38 ++ 8 files changed, 714 insertions(+), 3 deletions(-) create mode 100644 Documentation/hwmon/socfpga-hwmon.rst create mode 100644 drivers/hwmon/socfpga-hwmon.c
Signature · 1 line
2.43.7
[email protected]
maintainerPATCH v6 1/2 firmware: stratix10-svc: add async HWMON read commands and register socfpga-hwmon device
From: Tze Yee Ng <[email protected]>
Add asynchronous Stratix 10 service layer support for hardware monitor temperature and voltage read commands in stratix10_svc_async_send() and stratix10_svc_async_prepare_response().
Register a socfpga-hwmon platform device from the service layer driver when hardware monitor support is enabled, similar to the RSU device.
---
Changes in v6:
- No functional changes from v5
Changes in v5:
- No functional changes from v4
Changes in v3:
- No functional changes from v2
Changes in v2:
- Extend patch scope beyond async SMC support: register socfpga-hwmon platform device from stratix10-svc when CONFIG_SENSORS_ALTERA_SOCFPGA_HWMON is enabled
- Follow RSU-style registration; RSU probe error handling is unchanged
- Add err_unregister_clients to unregister hwmon and RSU on populate failure
- Unregister hwmon platform device in stratix10-svc remove()
--- drivers/firmware/stratix10-svc.c | 46 ++++++++++++++++++-- include/linux/firmware/intel/stratix10-smc.h | 38 ++++++++++++++++ 2 files changed, 81 insertions(+), 3 deletions(-)
drivers/firmware/stratix10-svc.c +43 -3
@@ -45,6 +45,7 @@/* stratix10 service layer clients */ #define STRATIX10_RSU "stratix10-rsu" +#define SOCFPGA_HWMON "socfpga-hwmon"/* Maximum number of SDM client IDs. */ #define MAX_SDM_CLIENT_IDS 16
@@ -104,9 +105,11 @@ struct stratix10_svc_chan;/** * struct stratix10_svc - svc private data * @stratix10_svc_rsu: pointer to stratix10 RSU device +* @stratix10_svc_hwmon: pointer to stratix10 HWMON device */ struct stratix10_svc {struct platform_device *stratix10_svc_rsu; +struct platform_device *stratix10_svc_hwmon; };/**
@@ -1329,6 +1332,14 @@ int stratix10_svc_async_send(struct stratix10_svc_chan *chan, void *msg, args.a0 =INTEL_SIP_SMC_ASYNC_RSU_NOTIFY ; args.a2 = p_msg->arg[0 ];break ; +case COMMAND_HWMON_READTEMP : + args.a0 =INTEL_SIP_SMC_ASYNC_HWMON_READTEMP ; + args.a2 = p_msg->arg[0 ]; +break ; +case COMMAND_HWMON_READVOLT : + args.a0 =INTEL_SIP_SMC_ASYNC_HWMON_READVOLT ; + args.a2 = p_msg->arg[0 ]; +break ;default :dev_err (ctrl->dev,"Invalid command ,%d\n" , p_msg->command); ret = -EINVAL ;
@@ -1422,6 +1433,10 @@ static int stratix10_svc_async_prepare_response(struct stratix10_svc_chan *chan,*/ data->kaddr1 = (void *)&handle->res;break ; +case COMMAND_HWMON_READTEMP : +case COMMAND_HWMON_READVOLT : + data->kaddr1 = (void *)&handle->res.a2; +break ;default :dev_alert (ctrl->dev,"Invalid command\n ,%d" , p_msg->command);
@@ -2013,16 +2028,38 @@ static int stratix10_svc_drv_probe(struct platform_device *pdev)if (ret) goto err_put_device; +if (IS_ENABLED (CONFIG_SENSORS_ALTERA_SOCFPGA_HWMON )) { + svc->stratix10_svc_hwmon = +platform_device_alloc (SOCFPGA_HWMON ,0 ); +if (!svc->stratix10_svc_hwmon) { +dev_err (dev,"failed to allocate %s device\n" , +SOCFPGA_HWMON ); + }else { + svc->stratix10_svc_hwmon->dev.parent = dev; + + ret =platform_device_add (svc->stratix10_svc_hwmon); +if (ret) { +dev_err (dev,"failed to add %s device: %d\n" , +SOCFPGA_HWMON , ret); +platform_device_put (svc->stratix10_svc_hwmon); + svc->stratix10_svc_hwmon =NULL ; + } + } + } + ret =of_platform_default_populate (dev_of_node (dev),NULL , dev);if (ret) - goto err_unregister_rsu_dev; + goto err_unregister_clients;pr_info ("Intel Service Layer Driver Initialized\n" );return 0 ; -err_unregister_rsu_dev: -platform_device_unregister (svc->stratix10_svc_rsu); +err_unregister_clients: +if (svc->stratix10_svc_hwmon) +platform_device_unregister (svc->stratix10_svc_hwmon); +if (svc->stratix10_svc_rsu) +platform_device_unregister (svc->stratix10_svc_rsu); goto err_free_fifos; err_put_device:platform_device_put (svc->stratix10_svc_rsu);
@@ -2046,6 +2083,9 @@ static void stratix10_svc_drv_remove(struct platform_device *pdev)struct stratix10_svc_controller *ctrl =platform_get_drvdata (pdev);struct stratix10_svc *svc = ctrl->svc; +if (svc->stratix10_svc_hwmon) +platform_device_unregister (svc->stratix10_svc_hwmon); +stratix10_svc_async_exit (ctrl);of_platform_depopulate (ctrl->dev);
include/linux/firmware/intel/stratix10-smc.h +38 -0
@@ -695,6 +695,44 @@ INTEL_SIP_SMC_FAST_CALL_VAL(INTEL_SIP_SMC_FUNCID_FPGA_CONFIG_COMPLETED_WRITE)#define INTEL_SIP_SMC_ASYNC_POLL \ INTEL_SIP_SMC_ASYNC_VAL(INTEL_SIP_SMC_ASYNC_FUNC_ID_POLL) +/** +* Request INTEL_SIP_SMC_ASYNC_HWMON_READTEMP +* Async call to request temperature +* +* Call register usage: +* a0 INTEL_SIP_SMC_ASYNC_HWMON_READTEMP +* a1 transaction job id +* a2 Temperature Channel +* a3-a17 not used +* +* Return status +* a0 INTEL_SIP_SMC_STATUS_OK, INTEL_SIP_SMC_STATUS_REJECTED +* or INTEL_SIP_SMC_STATUS_BUSY +* a1-a17 not used +*/ +#define INTEL_SIP_SMC_ASYNC_FUNC_ID_HWMON_READTEMP 0xE8 +#define INTEL_SIP_SMC_ASYNC_HWMON_READTEMP \ + INTEL_SIP_SMC_ASYNC_VAL(INTEL_SIP_SMC_ASYNC_FUNC_ID_HWMON_READTEMP) + +/** +* Request INTEL_SIP_SMC_ASYNC_HWMON_READVOLT +* Async call to request voltage +* +* Call register usage: +* a0 INTEL_SIP_SMC_ASYNC_HWMON_READVOLT +* a1 transaction job id +* a2 Voltage Channel +* a3-a17 not used +* +* Return status +* a0 INTEL_SIP_SMC_STATUS_OK, INTEL_SIP_SMC_STATUS_REJECTED +* or INTEL_SIP_SMC_STATUS_BUSY +* a1-a17 not used +*/ +#define INTEL_SIP_SMC_ASYNC_FUNC_ID_HWMON_READVOLT 0xE9 +#define INTEL_SIP_SMC_ASYNC_HWMON_READVOLT \ + INTEL_SIP_SMC_ASYNC_VAL(INTEL_SIP_SMC_ASYNC_FUNC_ID_HWMON_READVOLT) +/** * Request INTEL_SIP_SMC_ASYNC_RSU_GET_SPT * Async call to get RSU SPT from SDM.
Signature · 1 line
2.43.7
[email protected]
AI reviewRe: [PATCH v6 1/2] firmware: stratix10-svc: add async HWMON read commands and register socfpga-hwmon device
Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
New issues:
- [Medium] Hardware monitoring functionality is registered as a platform device rather than an auxiliary device, violating hwmon subsystem layering rules.
Pre-existing issues:
- [High] Asynchronous service layer APIs and resources are destroyed before client devices are unregistered, leading to a Use-After-Free and NULL pointer dereference race condition. --
--- Patch [1]: [PATCH v6 1/2] firmware: stratix10-svc: add async HWMON read commands and register socfpga-hwmon device --- commit 552947f984c2b5770daa9717c679362b5561cfa3
Author: Tze Yee Ng <[email protected]>
firmware: stratix10-svc: add async HWMON read commands and register socfpga-hwmon device
Add asynchronous Stratix 10 service layer support for hardware monitor temperature and voltage read commands in stratix10_svc_async_send() and stratix10_svc_async_prepare_response().
Register a socfpga-hwmon platform device from the service layer driver when hardware monitor support is enabled, similar to the RSU device.
Quoted 4 lines
drivers/firmware/stratix10-svc.c +0
-0
[ ... ]
Quoted 4 lines
drivers/firmware/stratix10-svc.c +0
-0@@ -2013,16 +2028,38 @@ static int stratix10_svc_drv_probe(struct platform_device *pdev)if (ret) goto err_put_device;
drivers/firmware/stratix10-svc.c static int stratix10_svc_drv_probe(struct platform_device *pdev) · line 2040
Quoted 10 lines
drivers/firmware/stratix10-svc.c +10
-0+if (IS_ENABLED (CONFIG_SENSORS_ALTERA_SOCFPGA_HWMON )) { + svc->stratix10_svc_hwmon = +platform_device_alloc (SOCFPGA_HWMON ,0 ); +if (!svc->stratix10_svc_hwmon) { +dev_err (dev,"failed to allocate %s device\n" , +SOCFPGA_HWMON ); + }else { + svc->stratix10_svc_hwmon->dev.parent = dev; + + ret =platform_device_add (svc->stratix10_svc_hwmon);
[Severity: Medium]
Should the hardware monitoring functionality be implemented as an auxiliary device driver instead of a platform device?
The hardware monitoring subsystem guidelines state that when hardware monitoring is a secondary function of a chip, it should be implemented as an auxiliary device and reside in drivers/hwmon/.
Does registering socfpga-hwmon directly as a platform device from this firmware service driver bypass the architectural layering rules for hwmon?
[ ... ]
drivers/firmware/stratix10-svc.c static void stratix10_svc_drv_remove(struct platform_device *pdev) · line 2091
Quoted 10 lines
drivers/firmware/stratix10-svc.c +3
-0@@ -2046,6 +2083,9 @@ static void stratix10_svc_drv_remove(struct platform_device *pdev)struct stratix10_svc_controller *ctrl =platform_get_drvdata (pdev);struct stratix10_svc *svc = ctrl->svc; +if (svc->stratix10_svc_hwmon) +platform_device_unregister (svc->stratix10_svc_hwmon); +stratix10_svc_async_exit (ctrl);of_platform_depopulate (ctrl->dev);
[Severity: High]
This is a pre-existing issue, but can the destruction order in stratix10_svc_drv_remove() lead to a NULL pointer dereference or a use-after-free race condition?
When stratix10_svc_async_exit() is called, it destroys the async ID pool and sets actrl->invoke_fn to NULL:
drivers/firmware/stratix10-svc.c:stratix10_svc_async_exit() {
...
ida_destroy(&actrl->async_id_pool);
actrl->invoke_fn = NULL;
...
}However, the RSU client device is unregistered after this destruction step via platform_device_unregister(svc->stratix10_svc_rsu).
If a user interacts with a client device's sysfs attribute while the module is being unloaded, could the still-active client device invoke stratix10_svc_async_send()?
If so, it would concurrently access freed asynchronous channels or attempt to execute actrl->invoke_fn(actrl, &args, &res) after it has been locklessly cleared, resulting in a kernel crash.
Would it be safer to unregister all child and client devices before the resources they depend on are torn down?
Signature · 1 line
Sashiko AI review · https://sashiko.dev/#/patchset/[email protected]?part=1
Guenter Roeck
maintainerRe: [PATCH v6 1/2] firmware: stratix10-svc: add async HWMON read commands and register socfpga-hwmon device
Quoted 46 lines · On 7/19/26 20:37, [email protected] wrote:
Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
New issues:
- [Medium] Hardware monitoring functionality is registered as a platform device rather than an auxiliary device, violating hwmon subsystem layering rules.Pre-existing issues:
- [High] Asynchronous service layer APIs and resources are destroyed before client devices are unregistered, leading to a Use-After-Free and NULL pointer dereference race condition. ----- Patch [1]: [PATCH v6 1/2] firmware: stratix10-svc: add async HWMON read commands and register socfpga-hwmon device --- commit
552947f984c2b5770daa9717c679362b5561cfa3
Author: Tze Yee Ng <[email protected]>firmware: stratix10-svc: add async HWMON read commands and register socfpga-hwmon device
Add asynchronous Stratix 10 service layer support for hardware monitor temperature and voltage read commands in
stratix10_svc_async_send()andstratix10_svc_async_prepare_response().Register a socfpga-hwmon platform device from the service layer driver when hardware monitor support is enabled, similar to the RSU device.
Quoted 4 lines
drivers/firmware/stratix10-svc.c +0
-0[ ... ]
Quoted 4 lines
drivers/firmware/stratix10-svc.c +0
-0@@ -2013,16 +2028,38 @@ static int stratix10_svc_drv_probe(struct platform_device *pdev)if (ret) goto err_put_device;drivers/firmware/stratix10-svc.c static int stratix10_svc_drv_probe(struct platform_device *pdev) · line 2040
Quoted 10 lines
drivers/firmware/stratix10-svc.c +10
-0+if (IS_ENABLED (CONFIG_SENSORS_ALTERA_SOCFPGA_HWMON )) { + svc->stratix10_svc_hwmon = +platform_device_alloc (SOCFPGA_HWMON ,0 ); +if (!svc->stratix10_svc_hwmon) { +dev_err (dev,"failed to allocate %s device\n" , +SOCFPGA_HWMON ); + }else { + svc->stratix10_svc_hwmon->dev.parent = dev; + + ret =platform_device_add (svc->stratix10_svc_hwmon);[Severity: Medium]
Should the hardware monitoring functionality be implemented as an auxiliary device driver instead of a platform device?
Quoted 7 lines
The hardware monitoring subsystem guidelines state that when hardware monitoring is a secondary function of a chip, it should be implemented as an auxiliary device and reside in
drivers/hwmon/.Does registering socfpga-hwmon directly as a platform device from this firmware service driver bypass the architectural layering rules for hwmon?
It should be implemented as auxiliary driver, but feel free to ignore since I only recently added this guidance to Sashiko.
Quoted 10 lines
[ ... ]
Quoted 9 lines
drivers/firmware/stratix10-svc.c +3
-0@@ -2046,6 +2083,9 @@ static void stratix10_svc_drv_remove(struct platform_device *pdev)struct stratix10_svc_controller *ctrl =platform_get_drvdata (pdev);struct stratix10_svc *svc = ctrl->svc; +if (svc->stratix10_svc_hwmon) +platform_device_unregister (svc->stratix10_svc_hwmon); +stratix10_svc_async_exit (ctrl);
Quoted 7 lines
drivers/firmware/stratix10-svc.c static void stratix10_svc_drv_remove(struct platform_device *pdev) · line 2091
Quoted 1 line
drivers/firmware/stratix10-svc.c +0
-0of_platform_depopulate (ctrl->dev);[Severity: High]
This is a pre-existing issue, but can the destruction order instratix10_svc_drv_remove()lead to a NULL pointer dereference or a use-after-free race condition?
Pre-existing, so your call if you want to fix it or not.
Thanks,
Guenter
Quoted 24 lines
When
stratix10_svc_async_exit()is called, it destroys the async ID pool and setsactrl->invoke_fnto NULL:drivers/firmware/stratix10-svc.c:stratix10_svc_async_exit() { ... ida_destroy(&actrl->async_id_pool); actrl->invoke_fn = NULL; ... }However, the RSU client device is unregistered after this destruction step via
platform_device_unregister(svc->stratix10_svc_rsu).If a user interacts with a client device's sysfs attribute while the module is being unloaded, could the still-active client device invoke
stratix10_svc_async_send()?If so, it would concurrently access freed asynchronous channels or attempt to execute
actrl->invoke_fn(actrl, &args, &res)after it has been locklessly cleared, resulting in a kernel crash.Would it be safer to unregister all child and client devices before the resources they depend on are torn down?
NG, TZE YEE
maintainerRe: [PATCH v6 1/2] firmware: stratix10-svc: add async HWMON read commands and register socfpga-hwmon device
Quoted 61 lines · Guenter Roeck
Quoted 60 lines · On 7/19/26 20:37, [email protected] wrote:
Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
New issues:
- [Medium] Hardware monitoring functionality is registered as a platform device rather than an auxiliary device, violating hwmon subsystem layering rules.Pre-existing issues:
- [High] Asynchronous service layer APIs and resources are destroyed before client devices are unregistered, leading to a Use-After-Free and NULL pointer dereference race condition.Signature · 14 lines
--- Patch [1]: [PATCH v6 1/2] firmware: stratix10-svc: add async HWMON read commands and register socfpga-hwmon device --- commit 552947f984c2b5770daa9717c679362b5561cfa3 Author: Tze Yee Ng <[email protected]> firmware: stratix10-svc: add async HWMON read commands and register socfpga-hwmon device Add asynchronous Stratix 10 service layer support for hardware monitor temperature and voltage read commands in stratix10_svc_async_send() and stratix10_svc_async_prepare_response(). Register a socfpga-hwmon platform device from the service layer driver when hardware monitor support is enabled, similar to the RSU device.Quoted 5 lines
drivers/firmware/ renamed from drivers/firmware/stratix10-svc.c +0
-0
stratix10-svc.c
indexc24ca5823078f..fc38afed5b7fe100644drivers/firmware/stratix10-svc.c +0
-0[ ... ]
Quoted 4 lines
drivers/firmware/stratix10-svc.c +0
-0@@ -2013,16 +2028,38 @@ static int stratix10_svc_drv_probe(struct platform_device *pdev) if (ret) goto err_put_device;drivers/firmware/stratix10-svc.c static int stratix10_svc_drv_probe(struct · line 2040
Quoted 10 lines
drivers/firmware/stratix10-svc.c +10
-0+ if (IS_ENABLED(CONFIG_SENSORS_ALTERA_SOCFPGA_HWMON)) { + svc->stratix10_svc_hwmon = + platform_device_alloc(SOCFPGA_HWMON, 0); + if (!svc->stratix10_svc_hwmon) { + dev_err(dev, "failed to allocate %s device\n", + SOCFPGA_HWMON); + } else { + svc->stratix10_svc_hwmon->dev.parent = dev; + + ret = platform_device_add(svc->stratix10_svc_hwmon);[Severity: Medium]
Should the hardware monitoring functionality be implemented as an auxiliary
device driver instead of a platform device?The hardware monitoring subsystem guidelines state that when hardware monitoring is a secondary function of a chip, it should be implemented as an
auxiliary device and reside indrivers/hwmon/.
Quoted 8 lines
Quoted 4 lines
Does registering socfpga-hwmon directly as a platform device from this firmware service driver bypass the architectural layering rules for hwmon?
It should be implemented as auxiliary driver, but feel free to ignore since I only recently added this guidance to Sashiko.
Thanks. I'll keep the platform device registration for this series. I’m happy to look at converting socfpga-hwmon to an auxiliary device in a follow-up if preferred.
Quoted 17 lines
Quoted 17 lines
[ ... ]
Quoted 10 lines
drivers/firmware/stratix10-svc.c +0
-0@@ -2046,6 +2083,9 @@ static void stratix10_svc_drv_remove(struct platform_device *pdev)struct
stratix10_svc_controller*ctrl =platform_get_drvdata(pdev);
structstratix10_svc*svc =ctrl->svc;
+ if (svc->stratix10_svc_hwmon)
+platform_device_unregister(svc->stratix10_svc_hwmon); +
stratix10_svc_async_exit(ctrl);of_platform_depopulate(ctrl->dev);[Severity: High]
This is a pre-existing issue, but can the destruction order instratix10_svc_drv_remove()lead to a NULL pointer dereference or a use-after-free race condition?
Quoted 5 lines
Pre-existing, so your call if you want to fix it or not.
Thanks,
Guenter
It is fixed in
https://lore.kernel.org/all/6630a1568f162d9455e0580f7ccadc262db4718e.1784007275.git.adrian.ho.yin.ng@altera.com/
Quoted 29 lines
Quoted 28 lines
When
stratix10_svc_async_exit()is called, it destroys the async ID pool and setsactrl->invoke_fnto NULL:drivers/firmware/stratix10-svc.c:stratix10_svc_async_exit() {
...
ida_destroy(&actrl->async_id_pool);actrl->invoke_fn= NULL;
...
}However, the RSU client device is unregistered after this destruction step
viaplatform_device_unregister(svc->stratix10_svc_rsu).If a user interacts with a client device's sysfs attribute while the module
is being unloaded, could the still-active client device invokestratix10_svc_async_send()?If so, it would concurrently access freed asynchronous channels or attempt
to executeactrl->invoke_fn(actrl, &args, &res)after it has been locklessly
cleared, resulting in a kernel crash.Would it be safer to unregister all child and client devices before the resources they depend on are torn down?
[email protected]
maintainerPATCH v6 2/2 hwmon: add Altera SoC FPGA hardware monitoring driver
In reply to [email protected]From: Tze Yee Ng <[email protected]>
Add a hardware monitor driver for Altera SoC FPGA devices using the Stratix 10 service layer. Sensor channels are selected based on the service layer compatible string.
---
Changes in v6:
- No functional changes from v5
Changes in v5:
- Poll async responses until HWMON_TIMEOUT (2 s) instead of a fixed 3-iteration retry loop (~3 ms), fixing premature timeouts observed on silicon
- Add MODULE_ALIAS("platform:socfpga-hwmon")
Changes in v4:
- Register devm_add_action_or_reset() before devm_hwmon_device_register_with_info(); drop manual channel cleanup on hwmon registration failure
- Remove unreferenced async completion and pre-poll wait_for_completion_io_timeout(); poll directly after async_send() with the existing retry loop
Changes in v3:
- Fix 16-bit signed Q8.8 temperature conversion (cast through s16)
- Remove unused async callback; pass NULL to stratix10_svc_async_send()
- Keep wait_for_completion_io_timeout() before polling with comment explaining the service layer never invokes the callback but firmware needs time to complete the transaction (RSU pattern)
- Align async poll loop with RSU (retry on failure instead of aborting)
- Use wait_for_completion_timeout() for synchronous reads
- Handle -EINVAL and -EOPNOTSUPP when async client registration fails
- Defer SVC channel/async cleanup via devm_add_action_or_reset(); drop .remove()
Changes in v2:
- Drop altr,stratix10-hwmon OF compatible and DT channel parsing
- Select channels from hardcoded tables using parent SVC compatible (intel,stratix10-svc or intel,agilex-svc)
- Rename driver from stratix10-hwmon to socfpga-hwmon
- Rename Kconfig symbol to CONFIG_SENSORS_ALTERA_SOCFPGA_HWMON
- Add Agilex voltage and temperature channel tables
- Convert SDM Q8.8 degrees Celsius to hwmon millidegrees
- Convert SDM Q16 volts to hwmon millivolts
- Use socfpga_hwmon as hwmon sysfs device name
- Add last_err for synchronous SVC read error propagation
- Update Documentation/hwmon and MAINTAINERS accordingly
--- Documentation/hwmon/index.rst | 1 + Documentation/hwmon/socfpga-hwmon.rst | 34 ++ MAINTAINERS | 8 + drivers/hwmon/Kconfig | 10 + drivers/hwmon/Makefile | 1 + drivers/hwmon/socfpga-hwmon.c | 579 ++++++++++++++++++++++++++ 6 files changed, 633 insertions(+) create mode 100644 Documentation/hwmon/socfpga-hwmon.rst create mode 100644 drivers/hwmon/socfpga-hwmon.c
Documentation/hwmon/index.rst +1 -0
@@ -254,6 +254,7 @@ Hardware Monitoring Kernel Drivers sparx5-temp spd5118 stpddc60 + socfpga-hwmon surface_fan sy7636a-hwmon tc654
Documentation/hwmon/socfpga-hwmon.rst new file +34 -0
@@ -0,0 +1,34 @@ +.. SPDX-License-Identifier: GPL-2.0 + +Kernel driver socfpga-hwmon +============================= + +Supported chips: + + * Altera Stratix 10 SoC FPGA + * Altera Agilex SoC FPGA + +Authors: + - Nazim Amirul <[email protected]> + - Tze Yee Ng <[email protected]> + +Description +----------- + +This driver supports hardware monitoring for Altera SoC +FPGA devices through the Secure Device Manager and Stratix 10 service layer. + +The following sensor types are supported: + + * temperature + * voltage + +Usage Notes +----------- + +The stratix10-svc driver registers a socfpga-hwmon platform device when +hardware monitor support is enabled. Sensor channels are selected in the +driver based on the service layer compatible string: + + * intel,stratix10-svc + * intel,agilex-svc
MAINTAINERS +8 -0
@@ -965,6 +965,14 @@ L: [email protected] S: Maintained F: drivers/gpio/gpio-altera.c +ALTERA SoC FPGA HWMON DRIVER +M: Nazim Amirul <[email protected]> +M: Tze Yee Ng <[email protected]> +L: [email protected] +S: Maintained +F: Documentation/hwmon/socfpga-hwmon.rst +F: drivers/hwmon/socfpga-hwmon.c + ALTERA TRIPLE SPEED ETHERNET DRIVER M: Boon Khai Ng <[email protected]> L: [email protected]
drivers/hwmon/Kconfig +10 -0
@@ -2160,6 +2160,16 @@ config SENSORS_SMSC47M192 This driver can also be built as a module. If so, the module will be called smsc47m192. +config SENSORS_ALTERA_SOCFPGA_HWMON + tristate "Altera SoC FPGA hardware monitoring features" + depends on INTEL_STRATIX10_SERVICE + help + If you say yes here you get support for the temperature and + voltage sensors of Altera SoC FPGA devices. + + This driver can also be built as a module. If so, the module + will be called socfpga-hwmon. + config SENSORS_SMSC47B397 tristate "SMSC LPC47B397-NC" depends on HAS_IOPORT
drivers/hwmon/Makefile +1 -0
@@ -221,6 +221,7 @@ obj-$(CONFIG_SENSORS_SMPRO) += smpro-hwmon.o obj-$(CONFIG_SENSORS_SMSC47B397)+= smsc47b397.o obj-$(CONFIG_SENSORS_SMSC47M1) += smsc47m1.o obj-$(CONFIG_SENSORS_SMSC47M192)+= smsc47m192.o +obj-$(CONFIG_SENSORS_ALTERA_SOCFPGA_HWMON) += socfpga-hwmon.o obj-$(CONFIG_SENSORS_SPARX5) += sparx5-temp.o obj-$(CONFIG_SENSORS_SPD5118) += spd5118.o obj-$(CONFIG_SENSORS_STTS751) += stts751.o
drivers/hwmon/socfpga-hwmon.c new file +579 -0
579 lines not on this page · raw message
Signature · 1 line
2.43.7
[email protected]
AI reviewRe: [PATCH v6 2/2] hwmon: add Altera SoC FPGA hardware monitoring driver
Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider: - [High] Missing break in async poll loop causes severe kernel log spam and unnecessary blocking on hard…
Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
- [High] Missing break in async poll loop causes severe kernel log spam and unnecessary blocking on hard errors.
- [High] Synchronous read timeouts leave stale requests in the channel FIFO, causing all subsequent reads to process stale data and return mismatched sensor values. --
--- Patch [2]: [PATCH v6 2/2] hwmon: add Altera SoC FPGA hardware monitoring driver --- commit ab6c0c0f95d3890d759e04d9d9aecd151d6406fd
Author: Tze Yee Ng <[email protected]>
Subject: hwmon: add Altera SoC FPGA hardware monitoring driver
This commit adds a hardware monitoring driver for Altera SoC FPGA devices using the Stratix 10 service layer.
Quoted 5 lines
drivers/hwmon/socfpga-hwmon.c new file +0
-0
[ ... ]
Quoted 4 lines
drivers/hwmon/socfpga-hwmon.c new file +4
-0+static int socfpga_hwmon_async_read (struct device *dev, +enum hwmon_sensor_types type, +struct stratix10_svc_client_msg *msg) +{
[ ... ]
drivers/hwmon/socfpga-hwmon.c line 218
Quoted 8 lines
drivers/hwmon/socfpga-hwmon.c new file +8
-0+ ret = -ETIMEDOUT ; +while (!time_after (jiffies, deadline)) { + status =stratix10_svc_async_poll (priv->chan, handle, &data); +if (status == -EAGAIN ) { +dev_dbg (dev,"Async message is still in progress\n" ); + }else if (status <0 ) { +dev_alert (dev,"Failed to poll async message: %d\n" , status); + ret = -ETIMEDOUT ;
[Severity: High]
Does this loop need a break statement here when status < 0?
If stratix10_svc_async_poll() returns a hard error, the code sets ret = -ETIMEDOUT but continues to loop for up to 2 seconds. This could flood the kernel log with dev_alert() messages on every 1ms retry.
Quoted 6 lines
drivers/hwmon/socfpga-hwmon.c new file +6
-0+ }else if (status ==0 ) { + ret =0 ; +break ; + } +msleep (HWMON_RETRY_SLEEP_MS ); + }
[ ... ]
Quoted 4 lines
drivers/hwmon/socfpga-hwmon.c new file +4
-0+static int socfpga_hwmon_sync_read (struct device *dev, +enum hwmon_sensor_types type, +struct stratix10_svc_client_msg *msg) +{
[ ... ]
drivers/hwmon/socfpga-hwmon.c line 272
Quoted 9 lines
drivers/hwmon/socfpga-hwmon.c new file +9
-0+ ret =stratix10_svc_send (priv->chan, msg); +if (ret <0 ) + goto status_done; + + ret =wait_for_completion_timeout (&priv->completion,HWMON_TIMEOUT ); +if (!ret) { +dev_err (priv->client.dev,"timeout waiting for SMC call\n" ); + ret = -ETIMEDOUT ; + goto status_done;
[Severity: High]
If a timeout occurs here, could the unfulfilled request remain in the SVC channel's FIFO?
When the timeout hits, this path calls stratix10_svc_done() which stops the worker thread, but it doesn't appear to remove the request from chan->svc_fifo.
Would the next sensor read enqueue a new request and receive the stale data from this timed-out request, permanently desynchronizing all subsequent sensor readings?
Quoted 8 lines
drivers/hwmon/socfpga-hwmon.c new file +8
-0+ } + + ret = priv->last_err; + +status_done: +stratix10_svc_done (priv->chan); +return ret; +}
Signature · 1 line
Sashiko AI review · https://sashiko.dev/#/patchset/[email protected]?part=2
Guenter Roeck
maintainerRe: [PATCH v6 2/2] hwmon: add Altera SoC FPGA hardware monitoring driver
Quoted 24 lines · On 7/19/26 20:36, [email protected] wrote:
Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
- [High] Missing break in async poll loop causes severe kernel log spam and unnecessary blocking on hard errors.
- [High] Synchronous read timeouts leave stale requests in the channel FIFO, causing all subsequent reads to process stale data and return mismatched sensor values. ----- Patch [2]: [PATCH v6 2/2] hwmon: add Altera SoC FPGA hardware monitoring driver --- commit
ab6c0c0f95d3890d759e04d9d9aecd151d6406fd
Author: Tze Yee Ng <[email protected]>
Subject: hwmon: add Altera SoC FPGA hardware monitoring driverThis commit adds a hardware monitoring driver for Altera SoC FPGA devices using the Stratix 10 service layer.
Quoted 5 lines
drivers/hwmon/socfpga-hwmon.c new file +0
-0[ ... ]
Quoted 4 lines
drivers/hwmon/socfpga-hwmon.c new file +4
-0+static int socfpga_hwmon_async_read (struct device *dev, +enum hwmon_sensor_types type, +struct stratix10_svc_client_msg *msg) +{[ ... ]
Quoted 5 lines
drivers/hwmon/socfpga-hwmon.c line 215
Quoted 5 lines
drivers/hwmon/socfpga-hwmon.c new file +5
-0+ ret = -ETIMEDOUT ; +while (!time_after (jiffies, deadline)) { + status =stratix10_svc_async_poll (priv->chan, handle, &data); +if (status == -EAGAIN ) { +dev_dbg (dev,"Async message is still in progress\n" );
This also creates a lot of noise if debugging is active. I don't know how long the command usually takes, but it does seem to me that this debug message isn't really helpful.
Quoted 11 lines
drivers/hwmon/socfpga-hwmon.c line 218
Quoted 3 lines
drivers/hwmon/socfpga-hwmon.c new file +3
-0+ }else if (status <0 ) { +dev_alert (dev,"Failed to poll async message: %d\n" , status); + ret = -ETIMEDOUT ;[Severity: High]
Does this loop need a break statement here when status < 0?If
stratix10_svc_async_poll()returns a hard error, the code sets ret =-ETIMEDOUTbut continues to loop for up to 2 seconds. This could flood the kernel log withdev_alert()messages on every 1ms retry.
Sashiko has a good point, especially since the function returns -EINVAL which, if seen, seems to be _real_ hard error and retrying seems pointless. Also, why replace -EINVAL with -ETIMEDOUT ? That would need an explanation.
On top of that, "ret = -ETIMEDOUT;" is pointless here since ret is already set to -ETIMEDOUT.
Oh, and the called code already displays an error message unless the parameters are bad.
Quoted 5 lines
drivers/hwmon/socfpga-hwmon.c line 223
Quoted 5 lines
drivers/hwmon/socfpga-hwmon.c new file +5
-0+ }else if (status ==0 ) { + ret =0 ; +break ; + } +msleep (HWMON_RETRY_SLEEP_MS );
I would suggest to use usleep_range().
Quoted 21 lines
Quoted 1 line
drivers/hwmon/socfpga-hwmon.c new file +1
-0+ }[ ... ]
Quoted 4 lines
drivers/hwmon/socfpga-hwmon.c new file +4
-0+static int socfpga_hwmon_sync_read (struct device *dev, +enum hwmon_sensor_types type, +struct stratix10_svc_client_msg *msg) +{[ ... ]
drivers/hwmon/socfpga-hwmon.c line 272
Quoted 9 lines
drivers/hwmon/socfpga-hwmon.c new file +9
-0+ ret =stratix10_svc_send (priv->chan, msg); +if (ret <0 ) + goto status_done; + + ret =wait_for_completion_timeout (&priv->completion,HWMON_TIMEOUT ); +if (!ret) { +dev_err (priv->client.dev,"timeout waiting for SMC call\n" ); + ret = -ETIMEDOUT ; + goto status_done;[Severity: High]
If a timeout occurs here, could the unfulfilled request remain in the SVC channel's FIFO?
Quoted 7 lines
When the timeout hits, this path calls
stratix10_svc_done()which stops the worker thread, but it doesn't appear to remove the request fromchan->svc_fifo.Would the next sensor read enqueue a new request and receive the stale data from this timed-out request, permanently desynchronizing all subsequent sensor readings?
Please either address or explain why it is not a problem.
Thanks,
Guenter
Quoted 9 lines
Quoted 8 lines
drivers/hwmon/socfpga-hwmon.c new file +8
-0+ } + + ret = priv->last_err; + +status_done: +stratix10_svc_done (priv->chan); +return ret; +}
NG, TZE YEE
maintainerRe: [PATCH v6 2/2] hwmon: add Altera SoC FPGA hardware monitoring driver
Quoted 60 lines · Guenter Roeck
Quoted 36 lines · On 7/19/26 20:36, [email protected] wrote:
Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
- [High] Missing break in async poll loop causes severe kernel log spam and unnecessary blocking on hard errors.
- [High] Synchronous read timeouts leave stale requests in the channel FIFO, causing all subsequent reads to process stale data and return mismatched sensor values.Signature · 9 lines
--- Patch [2]: [PATCH v6 2/2] hwmon: add Altera SoC FPGA hardware monitoring driver --- commit ab6c0c0f95d3890d759e04d9d9aecd151d6406fd Author: Tze Yee Ng <[email protected]> Subject: hwmon: add Altera SoC FPGA hardware monitoring driver This commit adds a hardware monitoring driver for Altera SoC FPGA devices using the Stratix 10 service layer.Quoted 6 lines
drivers/hwmon/socfpga- renamed from drivers/hwmon/socfpga-hwmon.c +0
-0
hwmon.c
new file mode 100644
index 0000000000000..72418201b65d6drivers/hwmon/socfpga-hwmon.c new file +0
-0[ ... ]
Quoted 4 lines
drivers/hwmon/socfpga-hwmon.c new file +4
-0+static int socfpga_hwmon_async_read (struct device *dev, + enum hwmon_sensor_types type, + struct stratix10_svc_client_msg *msg) +{[ ... ]
Quoted 5 lines
+ ret =
-ETIMEDOUT;
+ while (!time_after(jiffies, deadline)) {
+ status =stratix10_svc_async_poll(priv->chan, handle, &data); + if (status ==-EAGAIN) {
+dev_dbg(dev, "Async message is still in progress\n");This also creates a lot of noise if debugging is active. I don't know how long the command usually takes, but it does seem to me that this debug message isn't really helpful.
Quoted 5 lines
Quoted 4 lines
+ } else if (status < 0) {
+dev_alert(dev, "Failed to poll async message: %d\n", status);
+ ret =-ETIMEDOUT;Quoted 7 lines
[Severity: High]
Does this loop need a break statement here when status < 0?If
stratix10_svc_async_poll()returns a hard error, the code sets ret =-ETIMEDOUTbut continues to loop for up to 2 seconds. This could flood the kernel log withdev_alert()messages on every 1ms retry.Sashiko has a good point, especially since the function returns
-EINVALwhich, if seen, seems to be _real_ hard error and retrying seems pointless. Also, why replace-EINVALwith-ETIMEDOUT? That would need an explanation.
Quoted 6 lines
On top of that, "ret =
-ETIMEDOUT;" is pointless here since ret is already set to-ETIMEDOUT.Oh, and the called code already displays an error message unless the parameters are bad.
Agreed. In v7 I'll break out of the poll loop on hard errors, return the real poll error instead of -ETIMEDOUT, drop the redundant alert (SVC already logs) and remove the -EAGAIN debug print.
Quoted 8 lines
Quoted 5 lines
Quoted 5 lines
+ } else if (status == 0) {
+ ret = 0;
+ break;
+ }
+msleep(HWMON_RETRY_SLEEP_MS);I would suggest to use
usleep_range().
Agreed. In v7 I'll switch the short waits to usleep_range().
Quoted 33 lines
Quoted 25 lines
Quoted 1 line
+ }
[ ... ]
Quoted 4 lines
drivers/hwmon/socfpga-hwmon.c new file +4
-0+static int socfpga_hwmon_sync_read (struct device *dev, + enum hwmon_sensor_types type, + struct stratix10_svc_client_msg *msg) +{[ ... ]
Quoted 10 lines
+ ret =
stratix10_svc_send(priv->chan, msg);
+ if (ret < 0)
+ gotostatus_done;
+
+ ret =wait_for_completion_timeout(&priv->completion, HWMON_TIMEOUT);
+ if (!ret) {
+dev_err(priv->client.dev, "timeout waiting for SMC call\n"); + ret =-ETIMEDOUT;
+ gotostatus_done;[Severity: High]
If a timeout occurs here, could the unfulfilled request remain in the SVC channel's FIFO?When the timeout hits, this path calls
stratix10_svc_done()which stops the
worker thread, but it doesn't appear to remove the request from chan-Quoted 7 lines
Quoted 1 line
svc_fifo.Would the next sensor read enqueue a new request and receive the stale data
from this timed-out request, permanently desynchronizing all subsequent sensor readings?
Quoted 5 lines
Please either address or explain why it is not a problem.
Thanks,
Guenter
Yes, that race is real if the worker exits via kthread_should_stop() before dequeuing. stratix10_svc_done() stops the thread but does not flush svc_fifo.
For this driver I will invalidate an in-flight transfer generation after a timeout so a late/stale callback cannot complete the next read. A proper FIFO drain in stratix10_svc_done() would still be useful as a follow-up in the service layer.
Quoted 10 lines
Quoted 9 lines
Quoted 8 lines
+ }
drivers/hwmon/socfpga-hwmon.c new file +7
-0+ + ret = priv->last_err; + +status_done: + stratix10_svc_done(priv->chan); + return ret; +}