* [PATCH v2 1/3] dt-bindings: net: pse-pd: add poll-interval-ms property
2026-03-23 20:12 [PATCH v2 0/3] net: pse-pd: add poll path and LED trigger support Carlo Szelinsky
@ 2026-03-23 20:12 ` Carlo Szelinsky
2026-03-24 9:53 ` Kory Maincent
2026-03-26 9:30 ` Krzysztof Kozlowski
2026-03-23 20:12 ` [PATCH v2 2/3] net: pse-pd: add devm_pse_poll_helper() Carlo Szelinsky
` (3 subsequent siblings)
4 siblings, 2 replies; 10+ messages in thread
From: Carlo Szelinsky @ 2026-03-23 20:12 UTC (permalink / raw)
To: Oleksij Rempel, Kory Maincent
Cc: Andrew Lunn, David S . Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, netdev, linux-kernel, linux-leds, Carlo Szelinsky
Add the optional poll-interval-ms property for PSE controllers that
use poll-based event detection instead of interrupts. Defaults to
500ms if not specified.
Signed-off-by: Carlo Szelinsky <github@szelinsky.de>
---
.../devicetree/bindings/net/pse-pd/pse-controller.yaml | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/Documentation/devicetree/bindings/net/pse-pd/pse-controller.yaml b/Documentation/devicetree/bindings/net/pse-pd/pse-controller.yaml
index cd09560e0aea..329d020f054c 100644
--- a/Documentation/devicetree/bindings/net/pse-pd/pse-controller.yaml
+++ b/Documentation/devicetree/bindings/net/pse-pd/pse-controller.yaml
@@ -27,6 +27,14 @@ properties:
subnode. This property is deprecated, please use pse-pis instead.
enum: [0, 1]
+ poll-interval-ms:
+ description:
+ Polling interval in milliseconds for PSE controllers using
+ poll-based event detection instead of interrupts. Used when the
+ controller lacks IRQ support or the IRQ line is not wired.
+ default: 500
+ minimum: 50
+
pse-pis:
type: object
description:
--
2.43.0
^ permalink raw reply related [flat|nested] 10+ messages in thread* Re: [PATCH v2 1/3] dt-bindings: net: pse-pd: add poll-interval-ms property
2026-03-23 20:12 ` [PATCH v2 1/3] dt-bindings: net: pse-pd: add poll-interval-ms property Carlo Szelinsky
@ 2026-03-24 9:53 ` Kory Maincent
2026-03-26 9:30 ` Krzysztof Kozlowski
1 sibling, 0 replies; 10+ messages in thread
From: Kory Maincent @ 2026-03-24 9:53 UTC (permalink / raw)
To: Carlo Szelinsky
Cc: Oleksij Rempel, Andrew Lunn, David S . Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni, netdev, linux-kernel, linux-leds
On Mon, 23 Mar 2026 21:12:23 +0100
Carlo Szelinsky <github@szelinsky.de> wrote:
> Add the optional poll-interval-ms property for PSE controllers that
> use poll-based event detection instead of interrupts. Defaults to
> 500ms if not specified.
>
> Signed-off-by: Carlo Szelinsky <github@szelinsky.de>
Reviewed-by: Kory Maincent <kory.maincent@bootlin.com>
Thank you!
--
Köry Maincent, Bootlin
Embedded Linux and kernel engineering
https://bootlin.com
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH v2 1/3] dt-bindings: net: pse-pd: add poll-interval-ms property
2026-03-23 20:12 ` [PATCH v2 1/3] dt-bindings: net: pse-pd: add poll-interval-ms property Carlo Szelinsky
2026-03-24 9:53 ` Kory Maincent
@ 2026-03-26 9:30 ` Krzysztof Kozlowski
1 sibling, 0 replies; 10+ messages in thread
From: Krzysztof Kozlowski @ 2026-03-26 9:30 UTC (permalink / raw)
To: Carlo Szelinsky, Oleksij Rempel, Kory Maincent
Cc: Andrew Lunn, David S . Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, netdev, linux-kernel, linux-leds
On 23/03/2026 21:12, Carlo Szelinsky wrote:
> Add the optional poll-interval-ms property for PSE controllers that
> use poll-based event detection instead of interrupts. Defaults to
> 500ms if not specified.
>
> Signed-off-by: Carlo Szelinsky <github@szelinsky.de>
Please use scripts/get_maintainers.pl to get a list of necessary people
and lists to CC. It might happen, that command when run on an older
kernel, gives you outdated entries. Therefore please be sure you base
your patches on recent Linux kernel.
Tools like b4 or scripts/get_maintainer.pl provide you proper list of
people, so fix your workflow. Tools might also fail if you work on some
ancient tree (don't, instead use mainline) or work on fork of kernel
(don't, instead use mainline). Just use b4 and everything should be
fine, although remember about `b4 prep --auto-to-cc` if you added new
patches to the patchset.
You missed at least devicetree list (maybe more), so this won't be
tested by automated tooling. Performing review on untested code might be
a waste of time.
Please kindly resend and include all necessary To/Cc entries.
Best regards,
Krzysztof
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH v2 2/3] net: pse-pd: add devm_pse_poll_helper()
2026-03-23 20:12 [PATCH v2 0/3] net: pse-pd: add poll path and LED trigger support Carlo Szelinsky
2026-03-23 20:12 ` [PATCH v2 1/3] dt-bindings: net: pse-pd: add poll-interval-ms property Carlo Szelinsky
@ 2026-03-23 20:12 ` Carlo Szelinsky
2026-03-23 20:12 ` [PATCH v2 3/3] net: pse-pd: add LED trigger support via notification path Carlo Szelinsky
` (2 subsequent siblings)
4 siblings, 0 replies; 10+ messages in thread
From: Carlo Szelinsky @ 2026-03-23 20:12 UTC (permalink / raw)
To: Oleksij Rempel, Kory Maincent
Cc: Andrew Lunn, David S . Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, netdev, linux-kernel, linux-leds, Carlo Szelinsky
Extract the common event handling loop from pse_isr() into a shared
pse_handle_events() function, and add a generic poll-based alternative
to the IRQ path for PSE controllers that lack interrupt support or
have IRQ lines not wired on the board.
The new devm_pse_poll_helper() function sets up a delayed work that
periodically calls the driver's map_event callback to detect state
changes, feeding events into the existing ntf_fifo / pse_send_ntf_worker
notification pipeline. This reuses the same pse_irq_desc interface as
the IRQ path — the driver provides a map_event callback that populates
per-PI notification arrays.
The poll interval is configurable via the DT property "poll-interval-ms"
and defaults to 500ms, balancing responsiveness against I2C bus load.
Signed-off-by: Carlo Szelinsky <github@szelinsky.de>
---
drivers/net/pse-pd/pse_core.c | 148 +++++++++++++++++++++++++++-------
include/linux/pse-pd/pse.h | 12 +++
2 files changed, 130 insertions(+), 30 deletions(-)
diff --git a/drivers/net/pse-pd/pse_core.c b/drivers/net/pse-pd/pse_core.c
index 3beaaaeec9e1..3202c19ef602 100644
--- a/drivers/net/pse-pd/pse_core.c
+++ b/drivers/net/pse-pd/pse_core.c
@@ -18,6 +18,13 @@
#define PSE_PW_D_LIMIT INT_MAX
+/*
+ * Default poll interval for controllers without IRQ support.
+ * 500ms provides a reasonable trade-off between responsiveness
+ * (event detection, PD detection) and I2C bus utilization.
+ */
+#define PSE_DEFAULT_POLL_INTERVAL_MS 500
+
static DEFINE_MUTEX(pse_list_mutex);
static LIST_HEAD(pse_controller_list);
static DEFINE_XARRAY_ALLOC(pse_pw_d_map);
@@ -1114,6 +1121,8 @@ EXPORT_SYMBOL_GPL(pse_controller_register);
*/
void pse_controller_unregister(struct pse_controller_dev *pcdev)
{
+ if (pcdev->polling)
+ cancel_delayed_work_sync(&pcdev->poll_work);
pse_flush_pw_ds(pcdev);
pse_release_pis(pcdev);
if (pcdev->irq)
@@ -1238,66 +1247,103 @@ static int pse_set_config_isr(struct pse_controller_dev *pcdev, int id,
}
/**
- * pse_isr - IRQ handler for PSE
- * @irq: irq number
- * @data: pointer to user interrupt structure
+ * pse_handle_events - Process PSE events for all PIs
+ * @pcdev: a pointer to the PSE controller device
+ * @notifs: per-PI notification array
+ * @notifs_mask: bitmask of PIs with events
*
- * Return: irqreturn_t - status of IRQ
+ * Common event handling shared between IRQ and poll paths.
+ * Caller must hold pcdev->lock.
*/
-static irqreturn_t pse_isr(int irq, void *data)
+static void pse_handle_events(struct pse_controller_dev *pcdev,
+ unsigned long *notifs,
+ unsigned long notifs_mask)
{
- struct pse_controller_dev *pcdev;
- unsigned long notifs_mask = 0;
- struct pse_irq_desc *desc;
- struct pse_irq *h = data;
- int ret, i;
-
- desc = &h->desc;
- pcdev = h->pcdev;
-
- /* Clear notifs mask */
- memset(h->notifs, 0, pcdev->nr_lines * sizeof(*h->notifs));
- mutex_lock(&pcdev->lock);
- ret = desc->map_event(irq, pcdev, h->notifs, ¬ifs_mask);
- if (ret || !notifs_mask) {
- mutex_unlock(&pcdev->lock);
- return IRQ_NONE;
- }
+ int i;
for_each_set_bit(i, ¬ifs_mask, pcdev->nr_lines) {
- unsigned long notifs, rnotifs;
+ unsigned long pi_notifs, rnotifs;
struct pse_ntf ntf = {};
+ int ret;
/* Do nothing PI not described */
if (!pcdev->pi[i].rdev)
continue;
- notifs = h->notifs[i];
+ pi_notifs = notifs[i];
if (pse_pw_d_is_sw_pw_control(pcdev, pcdev->pi[i].pw_d)) {
- ret = pse_set_config_isr(pcdev, i, notifs);
+ ret = pse_set_config_isr(pcdev, i, pi_notifs);
if (ret)
- notifs |= ETHTOOL_PSE_EVENT_SW_PW_CONTROL_ERROR;
+ pi_notifs |= ETHTOOL_PSE_EVENT_SW_PW_CONTROL_ERROR;
}
- dev_dbg(h->pcdev->dev,
- "Sending PSE notification EVT 0x%lx\n", notifs);
+ dev_dbg(pcdev->dev,
+ "Sending PSE notification EVT 0x%lx\n", pi_notifs);
- ntf.notifs = notifs;
+ ntf.notifs = pi_notifs;
ntf.id = i;
kfifo_in_spinlocked(&pcdev->ntf_fifo, &ntf, 1,
&pcdev->ntf_fifo_lock);
schedule_work(&pcdev->ntf_work);
- rnotifs = pse_to_regulator_notifs(notifs);
+ rnotifs = pse_to_regulator_notifs(pi_notifs);
regulator_notifier_call_chain(pcdev->pi[i].rdev, rnotifs,
NULL);
}
+}
+
+/**
+ * pse_isr - IRQ handler for PSE
+ * @irq: irq number
+ * @data: pointer to user interrupt structure
+ *
+ * Return: irqreturn_t - status of IRQ
+ */
+static irqreturn_t pse_isr(int irq, void *data)
+{
+ struct pse_controller_dev *pcdev;
+ unsigned long notifs_mask = 0;
+ struct pse_irq *h = data;
+ int ret;
+ pcdev = h->pcdev;
+
+ /* Clear notifs mask */
+ memset(h->notifs, 0, pcdev->nr_lines * sizeof(*h->notifs));
+ mutex_lock(&pcdev->lock);
+ ret = h->desc.map_event(irq, pcdev, h->notifs, ¬ifs_mask);
+ if (ret || !notifs_mask) {
+ mutex_unlock(&pcdev->lock);
+ return IRQ_NONE;
+ }
+
+ pse_handle_events(pcdev, h->notifs, notifs_mask);
mutex_unlock(&pcdev->lock);
return IRQ_HANDLED;
}
+static void pse_poll_worker(struct work_struct *work)
+{
+ struct pse_controller_dev *pcdev =
+ container_of(work, struct pse_controller_dev,
+ poll_work.work);
+ unsigned long notifs_mask = 0;
+ int ret;
+
+ memset(pcdev->poll_notifs, 0,
+ pcdev->nr_lines * sizeof(*pcdev->poll_notifs));
+ mutex_lock(&pcdev->lock);
+ ret = pcdev->poll_desc.map_event(0, pcdev, pcdev->poll_notifs,
+ ¬ifs_mask);
+ if (!ret && notifs_mask)
+ pse_handle_events(pcdev, pcdev->poll_notifs, notifs_mask);
+ mutex_unlock(&pcdev->lock);
+
+ schedule_delayed_work(&pcdev->poll_work,
+ msecs_to_jiffies(pcdev->poll_interval_ms));
+}
+
/**
* devm_pse_irq_helper - Register IRQ based PSE event notifier
* @pcdev: a pointer to the PSE
@@ -1351,6 +1397,48 @@ int devm_pse_irq_helper(struct pse_controller_dev *pcdev, int irq,
}
EXPORT_SYMBOL_GPL(devm_pse_irq_helper);
+/**
+ * devm_pse_poll_helper - Register poll-based PSE event notifier
+ * @pcdev: a pointer to the PSE controller device
+ * @d: PSE event description (uses same pse_irq_desc as IRQ path)
+ *
+ * For PSE controllers without IRQ support or with IRQ not wired. Sets
+ * up a delayed work that periodically calls the driver's map_event
+ * callback to detect state changes, feeding events into the standard
+ * notification pipeline.
+ *
+ * Return: 0 on success and errno on failure
+ */
+int devm_pse_poll_helper(struct pse_controller_dev *pcdev,
+ const struct pse_irq_desc *d)
+{
+ struct device *dev = pcdev->dev;
+
+ if (!d || !d->map_event || !d->name)
+ return -EINVAL;
+
+ pcdev->poll_desc = *d;
+ pcdev->poll_notifs = devm_kcalloc(dev, pcdev->nr_lines,
+ sizeof(*pcdev->poll_notifs),
+ GFP_KERNEL);
+ if (!pcdev->poll_notifs)
+ return -ENOMEM;
+
+ of_property_read_u32(dev->of_node, "poll-interval-ms",
+ &pcdev->poll_interval_ms);
+ if (!pcdev->poll_interval_ms)
+ pcdev->poll_interval_ms = PSE_DEFAULT_POLL_INTERVAL_MS;
+
+ INIT_DELAYED_WORK(&pcdev->poll_work, pse_poll_worker);
+ pcdev->polling = true;
+
+ schedule_delayed_work(&pcdev->poll_work,
+ msecs_to_jiffies(pcdev->poll_interval_ms));
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(devm_pse_poll_helper);
+
/* PSE control section */
static void __pse_control_release(struct kref *kref)
diff --git a/include/linux/pse-pd/pse.h b/include/linux/pse-pd/pse.h
index 4e5696cfade7..44d5d10e239d 100644
--- a/include/linux/pse-pd/pse.h
+++ b/include/linux/pse-pd/pse.h
@@ -292,6 +292,11 @@ struct pse_ntf {
* @pi: table of PSE PIs described in this controller device
* @no_of_pse_pi: flag set if the pse_pis devicetree node is not used
* @irq: PSE interrupt
+ * @polling: flag indicating poll-based event detection is active
+ * @poll_interval_ms: poll interval in milliseconds
+ * @poll_work: delayed work for poll-based event detection
+ * @poll_desc: copy of the driver's event descriptor for polling
+ * @poll_notifs: per-PI notification scratch space for poll worker
* @pis_prio_max: Maximum value allowed for the PSE PIs priority
* @supp_budget_eval_strategies: budget evaluation strategies supported
* by the PSE
@@ -312,6 +317,11 @@ struct pse_controller_dev {
struct pse_pi *pi;
bool no_of_pse_pi;
int irq;
+ bool polling;
+ unsigned int poll_interval_ms;
+ struct delayed_work poll_work;
+ struct pse_irq_desc poll_desc;
+ unsigned long *poll_notifs;
unsigned int pis_prio_max;
u32 supp_budget_eval_strategies;
struct work_struct ntf_work;
@@ -345,6 +355,8 @@ int devm_pse_controller_register(struct device *dev,
struct pse_controller_dev *pcdev);
int devm_pse_irq_helper(struct pse_controller_dev *pcdev, int irq,
int irq_flags, const struct pse_irq_desc *d);
+int devm_pse_poll_helper(struct pse_controller_dev *pcdev,
+ const struct pse_irq_desc *d);
struct pse_control *of_pse_control_get(struct device_node *node,
struct phy_device *phydev);
--
2.43.0
^ permalink raw reply related [flat|nested] 10+ messages in thread* [PATCH v2 3/3] net: pse-pd: add LED trigger support via notification path
2026-03-23 20:12 [PATCH v2 0/3] net: pse-pd: add poll path and LED trigger support Carlo Szelinsky
2026-03-23 20:12 ` [PATCH v2 1/3] dt-bindings: net: pse-pd: add poll-interval-ms property Carlo Szelinsky
2026-03-23 20:12 ` [PATCH v2 2/3] net: pse-pd: add devm_pse_poll_helper() Carlo Szelinsky
@ 2026-03-23 20:12 ` Carlo Szelinsky
2026-03-25 4:39 ` kernel test robot
2026-03-25 4:39 ` kernel test robot
2026-03-24 9:52 ` [PATCH v2 0/3] net: pse-pd: add poll path and LED trigger support Kory Maincent
2026-03-26 7:46 ` Oleksij Rempel
4 siblings, 2 replies; 10+ messages in thread
From: Carlo Szelinsky @ 2026-03-23 20:12 UTC (permalink / raw)
To: Oleksij Rempel, Kory Maincent
Cc: Andrew Lunn, David S . Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, netdev, linux-kernel, linux-leds, Carlo Szelinsky
Add per-PI "delivering" and "enabled" LED triggers to the PSE core
subsystem. Instead of polling from LED-specific code, LED state is
updated from the shared pse_handle_events() function whenever the
IRQ or poll path detects a state change.
This ensures LED triggers react to the same events that drive netlink
notifications and regulator callbacks, without duplicating the polling
logic.
Signed-off-by: Carlo Szelinsky <github@szelinsky.de>
---
drivers/net/pse-pd/pse_core.c | 119 +++++++++++++++++++++++++++++++++-
include/linux/pse-pd/pse.h | 22 +++++++
2 files changed, 140 insertions(+), 1 deletion(-)
diff --git a/drivers/net/pse-pd/pse_core.c b/drivers/net/pse-pd/pse_core.c
index 3202c19ef602..0e96c22493a4 100644
--- a/drivers/net/pse-pd/pse_core.c
+++ b/drivers/net/pse-pd/pse_core.c
@@ -12,6 +12,7 @@
#include <linux/phy.h>
#include <linux/pse-pd/pse.h>
#include <linux/regulator/driver.h>
+#include <linux/leds.h>
#include <linux/regulator/machine.h>
#include <linux/rtnetlink.h>
#include <net/net_trackers.h>
@@ -1037,6 +1038,107 @@ static void pse_send_ntf_worker(struct work_struct *work)
}
}
+#if IS_ENABLED(CONFIG_LEDS_TRIGGERS)
+/**
+ * pse_led_update - Update LED triggers for a PI based on current state
+ * @pcdev: PSE controller device
+ * @id: PI index
+ *
+ * Queries the current power status and admin state of the PI and
+ * fires LED trigger events on state changes. Called from the
+ * notification path whenever any event occurs for this PI.
+ *
+ * Must be called with pcdev->lock held.
+ */
+static void pse_led_update(struct pse_controller_dev *pcdev, int id)
+{
+ struct pse_pi_led_triggers *trigs;
+ struct pse_pw_status pw_status = {};
+ struct pse_admin_state admin_state = {};
+ bool delivering, enabled;
+
+ if (!pcdev->pi_led_trigs)
+ return;
+
+ trigs = &pcdev->pi_led_trigs[id];
+ if (!trigs->delivering.name)
+ return;
+
+ if (pcdev->ops->pi_get_pw_status(pcdev, id, &pw_status))
+ return;
+ if (pcdev->ops->pi_get_admin_state(pcdev, id, &admin_state))
+ return;
+
+ delivering = pw_status.c33_pw_status ==
+ ETHTOOL_C33_PSE_PW_D_STATUS_DELIVERING;
+ enabled = admin_state.c33_admin_state ==
+ ETHTOOL_C33_PSE_ADMIN_STATE_ENABLED;
+
+ if (trigs->last_delivering != delivering) {
+ trigs->last_delivering = delivering;
+ led_trigger_event(&trigs->delivering,
+ delivering ? LED_FULL : LED_OFF);
+ }
+
+ if (trigs->last_enabled != enabled) {
+ trigs->last_enabled = enabled;
+ led_trigger_event(&trigs->enabled,
+ enabled ? LED_FULL : LED_OFF);
+ }
+}
+
+static int pse_led_triggers_register(struct pse_controller_dev *pcdev)
+{
+ struct device *dev = pcdev->dev;
+ const char *node_name;
+ int i, ret;
+
+ node_name = dev->of_node ? dev->of_node->name : dev_name(dev);
+
+ pcdev->pi_led_trigs = devm_kcalloc(dev, pcdev->nr_lines,
+ sizeof(*pcdev->pi_led_trigs),
+ GFP_KERNEL);
+ if (!pcdev->pi_led_trigs)
+ return -ENOMEM;
+
+ for (i = 0; i < pcdev->nr_lines; i++) {
+ struct pse_pi_led_triggers *trigs = &pcdev->pi_led_trigs[i];
+
+ /* Skip PIs not described in device tree */
+ if (!pcdev->no_of_pse_pi && !pcdev->pi[i].np)
+ continue;
+
+ trigs->delivering.name = devm_kasprintf(dev, GFP_KERNEL,
+ "%s:port%d:delivering",
+ node_name, i);
+ if (!trigs->delivering.name)
+ return -ENOMEM;
+
+ ret = devm_led_trigger_register(dev, &trigs->delivering);
+ if (ret)
+ return ret;
+
+ trigs->enabled.name = devm_kasprintf(dev, GFP_KERNEL,
+ "%s:port%d:enabled",
+ node_name, i);
+ if (!trigs->enabled.name)
+ return -ENOMEM;
+
+ ret = devm_led_trigger_register(dev, &trigs->enabled);
+ if (ret)
+ return ret;
+ }
+
+ return 0;
+}
+#else
+static inline void pse_led_update(struct pse_controller_dev *pcdev, int id) {}
+static int pse_led_triggers_register(struct pse_controller_dev *pcdev)
+{
+ return 0;
+}
+#endif /* CONFIG_LEDS_TRIGGERS */
+
/**
* pse_controller_register - register a PSE controller device
* @pcdev: a pointer to the initialized PSE controller device
@@ -1111,6 +1213,14 @@ int pse_controller_register(struct pse_controller_dev *pcdev)
list_add(&pcdev->list, &pse_controller_list);
mutex_unlock(&pse_list_mutex);
+ ret = pse_led_triggers_register(pcdev);
+ if (ret) {
+ dev_warn(pcdev->dev, "Failed to register LED triggers: %d\n",
+ ret);
+ /* Ensure pse_led_update() is a no-op on partial failure */
+ pcdev->pi_led_trigs = NULL;
+ }
+
return 0;
}
EXPORT_SYMBOL_GPL(pse_controller_register);
@@ -1266,7 +1376,14 @@ static void pse_handle_events(struct pse_controller_dev *pcdev,
struct pse_ntf ntf = {};
int ret;
- /* Do nothing PI not described */
+ /* Update LEDs for described PIs regardless of consumer state.
+ * LED triggers are registered at controller init, before any
+ * PHY claims a PSE control, so rdev may still be NULL here.
+ */
+ if (pcdev->no_of_pse_pi || pcdev->pi[i].np)
+ pse_led_update(pcdev, i);
+
+ /* Skip regulator/netlink path for PIs without consumers */
if (!pcdev->pi[i].rdev)
continue;
diff --git a/include/linux/pse-pd/pse.h b/include/linux/pse-pd/pse.h
index 44d5d10e239d..0058636a6299 100644
--- a/include/linux/pse-pd/pse.h
+++ b/include/linux/pse-pd/pse.h
@@ -10,6 +10,7 @@
#include <linux/kfifo.h>
#include <uapi/linux/ethtool.h>
#include <uapi/linux/ethtool_netlink_generated.h>
+#include <linux/leds.h>
#include <linux/regulator/driver.h>
/* Maximum current in uA according to IEEE 802.3-2022 Table 145-1 */
@@ -266,6 +267,23 @@ struct pse_pi {
int pw_allocated_mW;
};
+#if IS_ENABLED(CONFIG_LEDS_TRIGGERS)
+/**
+ * struct pse_pi_led_triggers - LED trigger state for a PSE PI
+ *
+ * @delivering: LED trigger for power delivering state
+ * @enabled: LED trigger for admin enabled state
+ * @last_delivering: cached delivering state for change detection
+ * @last_enabled: cached enabled state for change detection
+ */
+struct pse_pi_led_triggers {
+ struct led_trigger delivering;
+ struct led_trigger enabled;
+ bool last_delivering;
+ bool last_enabled;
+};
+#endif
+
/**
* struct pse_ntf - PSE notification element
*
@@ -303,6 +321,7 @@ struct pse_ntf {
* @ntf_work: workqueue for PSE notification management
* @ntf_fifo: PSE notifications FIFO
* @ntf_fifo_lock: protect @ntf_fifo writer
+ * @pi_led_trigs: per-PI LED trigger state array
*/
struct pse_controller_dev {
const struct pse_controller_ops *ops;
@@ -327,6 +346,9 @@ struct pse_controller_dev {
struct work_struct ntf_work;
DECLARE_KFIFO_PTR(ntf_fifo, struct pse_ntf);
spinlock_t ntf_fifo_lock; /* Protect @ntf_fifo writer */
+#if IS_ENABLED(CONFIG_LEDS_TRIGGERS)
+ struct pse_pi_led_triggers *pi_led_trigs;
+#endif
};
/**
--
2.43.0
^ permalink raw reply related [flat|nested] 10+ messages in thread* Re: [PATCH v2 3/3] net: pse-pd: add LED trigger support via notification path
2026-03-23 20:12 ` [PATCH v2 3/3] net: pse-pd: add LED trigger support via notification path Carlo Szelinsky
@ 2026-03-25 4:39 ` kernel test robot
2026-03-25 4:39 ` kernel test robot
1 sibling, 0 replies; 10+ messages in thread
From: kernel test robot @ 2026-03-25 4:39 UTC (permalink / raw)
To: Carlo Szelinsky, Oleksij Rempel, Kory Maincent
Cc: llvm, oe-kbuild-all, Andrew Lunn, David S . Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni, netdev, linux-kernel, linux-leds,
Carlo Szelinsky
Hi Carlo,
kernel test robot noticed the following build errors:
[auto build test ERROR on robh/for-next]
[also build test ERROR on net-next/main net/main linus/master v7.0-rc5 next-20260324]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]
url: https://github.com/intel-lab-lkp/linux/commits/Carlo-Szelinsky/dt-bindings-net-pse-pd-add-poll-interval-ms-property/20260325-040935
base: https://git.kernel.org/pub/scm/linux/kernel/git/robh/linux.git for-next
patch link: https://lore.kernel.org/r/20260323201225.1836561-4-github%40szelinsky.de
patch subject: [PATCH v2 3/3] net: pse-pd: add LED trigger support via notification path
config: hexagon-randconfig-001-20260325 (https://download.01.org/0day-ci/archive/20260325/202603251254.o5PqMBRU-lkp@intel.com/config)
compiler: clang version 19.1.7 (https://github.com/llvm/llvm-project cd708029e0b2869e80abe31ddb175f7c35361f90)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260325/202603251254.o5PqMBRU-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202603251254.o5PqMBRU-lkp@intel.com/
All errors (new ones prefixed by >>):
>> drivers/net/pse-pd/pse_core.c:1221:10: error: no member named 'pi_led_trigs' in 'struct pse_controller_dev'
1221 | pcdev->pi_led_trigs = NULL;
| ~~~~~ ^
1 error generated.
vim +1221 drivers/net/pse-pd/pse_core.c
1141
1142 /**
1143 * pse_controller_register - register a PSE controller device
1144 * @pcdev: a pointer to the initialized PSE controller device
1145 *
1146 * Return: 0 on success and failure value on error
1147 */
1148 int pse_controller_register(struct pse_controller_dev *pcdev)
1149 {
1150 size_t reg_name_len;
1151 int ret, i;
1152
1153 mutex_init(&pcdev->lock);
1154 INIT_LIST_HEAD(&pcdev->pse_control_head);
1155 spin_lock_init(&pcdev->ntf_fifo_lock);
1156 ret = kfifo_alloc(&pcdev->ntf_fifo, pcdev->nr_lines, GFP_KERNEL);
1157 if (ret) {
1158 dev_err(pcdev->dev, "failed to allocate kfifo notifications\n");
1159 return ret;
1160 }
1161 INIT_WORK(&pcdev->ntf_work, pse_send_ntf_worker);
1162
1163 if (!pcdev->nr_lines)
1164 pcdev->nr_lines = 1;
1165
1166 if (!pcdev->ops->pi_get_admin_state ||
1167 !pcdev->ops->pi_get_pw_status) {
1168 dev_err(pcdev->dev,
1169 "Mandatory status report callbacks are missing");
1170 return -EINVAL;
1171 }
1172
1173 ret = of_load_pse_pis(pcdev);
1174 if (ret)
1175 return ret;
1176
1177 if (pcdev->ops->setup_pi_matrix) {
1178 ret = pcdev->ops->setup_pi_matrix(pcdev);
1179 if (ret)
1180 return ret;
1181 }
1182
1183 /* Each regulator name len is pcdev dev name + 7 char +
1184 * int max digit number (10) + 1
1185 */
1186 reg_name_len = strlen(dev_name(pcdev->dev)) + 18;
1187
1188 /* Register PI regulators */
1189 for (i = 0; i < pcdev->nr_lines; i++) {
1190 char *reg_name;
1191
1192 /* Do not register regulator for PIs not described */
1193 if (!pcdev->no_of_pse_pi && !pcdev->pi[i].np)
1194 continue;
1195
1196 reg_name = devm_kzalloc(pcdev->dev, reg_name_len, GFP_KERNEL);
1197 if (!reg_name)
1198 return -ENOMEM;
1199
1200 snprintf(reg_name, reg_name_len, "pse-%s_pi%d",
1201 dev_name(pcdev->dev), i);
1202
1203 ret = devm_pse_pi_regulator_register(pcdev, reg_name, i);
1204 if (ret)
1205 return ret;
1206 }
1207
1208 ret = pse_register_pw_ds(pcdev);
1209 if (ret)
1210 return ret;
1211
1212 mutex_lock(&pse_list_mutex);
1213 list_add(&pcdev->list, &pse_controller_list);
1214 mutex_unlock(&pse_list_mutex);
1215
1216 ret = pse_led_triggers_register(pcdev);
1217 if (ret) {
1218 dev_warn(pcdev->dev, "Failed to register LED triggers: %d\n",
1219 ret);
1220 /* Ensure pse_led_update() is a no-op on partial failure */
> 1221 pcdev->pi_led_trigs = NULL;
1222 }
1223
1224 return 0;
1225 }
1226 EXPORT_SYMBOL_GPL(pse_controller_register);
1227
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply [flat|nested] 10+ messages in thread* Re: [PATCH v2 3/3] net: pse-pd: add LED trigger support via notification path
2026-03-23 20:12 ` [PATCH v2 3/3] net: pse-pd: add LED trigger support via notification path Carlo Szelinsky
2026-03-25 4:39 ` kernel test robot
@ 2026-03-25 4:39 ` kernel test robot
1 sibling, 0 replies; 10+ messages in thread
From: kernel test robot @ 2026-03-25 4:39 UTC (permalink / raw)
To: Carlo Szelinsky, Oleksij Rempel, Kory Maincent
Cc: oe-kbuild-all, Andrew Lunn, David S . Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni, netdev, linux-kernel, linux-leds,
Carlo Szelinsky
Hi Carlo,
kernel test robot noticed the following build errors:
[auto build test ERROR on robh/for-next]
[also build test ERROR on net-next/main net/main linus/master v7.0-rc5 next-20260324]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]
url: https://github.com/intel-lab-lkp/linux/commits/Carlo-Szelinsky/dt-bindings-net-pse-pd-add-poll-interval-ms-property/20260325-040935
base: https://git.kernel.org/pub/scm/linux/kernel/git/robh/linux.git for-next
patch link: https://lore.kernel.org/r/20260323201225.1836561-4-github%40szelinsky.de
patch subject: [PATCH v2 3/3] net: pse-pd: add LED trigger support via notification path
config: sh-randconfig-002-20260325 (https://download.01.org/0day-ci/archive/20260325/202603251250.cuMCk5Yv-lkp@intel.com/config)
compiler: sh4-linux-gcc (GCC) 15.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260325/202603251250.cuMCk5Yv-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202603251250.cuMCk5Yv-lkp@intel.com/
All errors (new ones prefixed by >>):
drivers/net/pse-pd/pse_core.c: In function 'pse_controller_register':
>> drivers/net/pse-pd/pse_core.c:1221:22: error: 'struct pse_controller_dev' has no member named 'pi_led_trigs'
1221 | pcdev->pi_led_trigs = NULL;
| ^~
vim +1221 drivers/net/pse-pd/pse_core.c
1141
1142 /**
1143 * pse_controller_register - register a PSE controller device
1144 * @pcdev: a pointer to the initialized PSE controller device
1145 *
1146 * Return: 0 on success and failure value on error
1147 */
1148 int pse_controller_register(struct pse_controller_dev *pcdev)
1149 {
1150 size_t reg_name_len;
1151 int ret, i;
1152
1153 mutex_init(&pcdev->lock);
1154 INIT_LIST_HEAD(&pcdev->pse_control_head);
1155 spin_lock_init(&pcdev->ntf_fifo_lock);
1156 ret = kfifo_alloc(&pcdev->ntf_fifo, pcdev->nr_lines, GFP_KERNEL);
1157 if (ret) {
1158 dev_err(pcdev->dev, "failed to allocate kfifo notifications\n");
1159 return ret;
1160 }
1161 INIT_WORK(&pcdev->ntf_work, pse_send_ntf_worker);
1162
1163 if (!pcdev->nr_lines)
1164 pcdev->nr_lines = 1;
1165
1166 if (!pcdev->ops->pi_get_admin_state ||
1167 !pcdev->ops->pi_get_pw_status) {
1168 dev_err(pcdev->dev,
1169 "Mandatory status report callbacks are missing");
1170 return -EINVAL;
1171 }
1172
1173 ret = of_load_pse_pis(pcdev);
1174 if (ret)
1175 return ret;
1176
1177 if (pcdev->ops->setup_pi_matrix) {
1178 ret = pcdev->ops->setup_pi_matrix(pcdev);
1179 if (ret)
1180 return ret;
1181 }
1182
1183 /* Each regulator name len is pcdev dev name + 7 char +
1184 * int max digit number (10) + 1
1185 */
1186 reg_name_len = strlen(dev_name(pcdev->dev)) + 18;
1187
1188 /* Register PI regulators */
1189 for (i = 0; i < pcdev->nr_lines; i++) {
1190 char *reg_name;
1191
1192 /* Do not register regulator for PIs not described */
1193 if (!pcdev->no_of_pse_pi && !pcdev->pi[i].np)
1194 continue;
1195
1196 reg_name = devm_kzalloc(pcdev->dev, reg_name_len, GFP_KERNEL);
1197 if (!reg_name)
1198 return -ENOMEM;
1199
1200 snprintf(reg_name, reg_name_len, "pse-%s_pi%d",
1201 dev_name(pcdev->dev), i);
1202
1203 ret = devm_pse_pi_regulator_register(pcdev, reg_name, i);
1204 if (ret)
1205 return ret;
1206 }
1207
1208 ret = pse_register_pw_ds(pcdev);
1209 if (ret)
1210 return ret;
1211
1212 mutex_lock(&pse_list_mutex);
1213 list_add(&pcdev->list, &pse_controller_list);
1214 mutex_unlock(&pse_list_mutex);
1215
1216 ret = pse_led_triggers_register(pcdev);
1217 if (ret) {
1218 dev_warn(pcdev->dev, "Failed to register LED triggers: %d\n",
1219 ret);
1220 /* Ensure pse_led_update() is a no-op on partial failure */
> 1221 pcdev->pi_led_trigs = NULL;
1222 }
1223
1224 return 0;
1225 }
1226 EXPORT_SYMBOL_GPL(pse_controller_register);
1227
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH v2 0/3] net: pse-pd: add poll path and LED trigger support
2026-03-23 20:12 [PATCH v2 0/3] net: pse-pd: add poll path and LED trigger support Carlo Szelinsky
` (2 preceding siblings ...)
2026-03-23 20:12 ` [PATCH v2 3/3] net: pse-pd: add LED trigger support via notification path Carlo Szelinsky
@ 2026-03-24 9:52 ` Kory Maincent
2026-03-26 7:46 ` Oleksij Rempel
4 siblings, 0 replies; 10+ messages in thread
From: Kory Maincent @ 2026-03-24 9:52 UTC (permalink / raw)
To: Carlo Szelinsky
Cc: Oleksij Rempel, Andrew Lunn, David S . Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni, netdev, linux-kernel, linux-leds
On Mon, 23 Mar 2026 21:12:22 +0100
Carlo Szelinsky <github@szelinsky.de> wrote:
> This series adds poll-based event detection and LED trigger support
> to the PSE core subsystem.
I just saw it but, for next version please add net-next prefixes in your patch
subject, as described here:
https://elixir.bootlin.com/linux/v6.19.3/source/Documentation/process/maintainer-netdev.rst#L64
> Patches 1-2 introduce the poll path independently of LED support,
> so it can be tested in isolation on boards with and without IRQ
> configured.
Great, I will test it when I have a bit of spare time.
> Patch 3 adds LED triggers that hook into the shared event handling
> path introduced by patch 2.
>
> Changes since v1:
> - Split single patch into 3 separate patches
> - Extracted pse_handle_events() and devm_pse_poll_helper() as a
> standalone poll path (patches 1-2), testable without LED code
> - Added DT binding for poll-interval-ms as a separate patch
> - Renamed led-poll-interval-ms to poll-interval-ms for generic use
> - Fire LED triggers from the notification path rather than a
> separate poll loop
>
> Tested on Realtek RTL9303 with HS104 PoE chip, poll path only
> (without IRQ configured). Verified PD connect/disconnect notifications
> and LED trigger state changes. Testing with IRQ configured is still
> needed to verify the refactored pse_isr() path.
>
> Link:
> https://lore.kernel.org/all/20260314235916.2391678-1-github@szelinsky.de/
>
> Carlo Szelinsky (3):
> dt-bindings: net: pse-pd: add poll-interval-ms property
> net: pse-pd: add devm_pse_poll_helper()
> net: pse-pd: add LED trigger support via notification path
>
> .../bindings/net/pse-pd/pse-controller.yaml | 8 +
> drivers/net/pse-pd/pse_core.c | 267 ++++++++++++++++--
> include/linux/pse-pd/pse.h | 34 +++
> 3 files changed, 278 insertions(+), 31 deletions(-)
Regards,
--
Köry Maincent, Bootlin
Embedded Linux and kernel engineering
https://bootlin.com
^ permalink raw reply [flat|nested] 10+ messages in thread* Re: [PATCH v2 0/3] net: pse-pd: add poll path and LED trigger support
2026-03-23 20:12 [PATCH v2 0/3] net: pse-pd: add poll path and LED trigger support Carlo Szelinsky
` (3 preceding siblings ...)
2026-03-24 9:52 ` [PATCH v2 0/3] net: pse-pd: add poll path and LED trigger support Kory Maincent
@ 2026-03-26 7:46 ` Oleksij Rempel
4 siblings, 0 replies; 10+ messages in thread
From: Oleksij Rempel @ 2026-03-26 7:46 UTC (permalink / raw)
To: Carlo Szelinsky
Cc: Kory Maincent, Andrew Lunn, David S . Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni, netdev, linux-kernel, linux-leds
Hi Carlo,
Thank you for your work,
Can you please take a look at this automated review, there are some good
points:
https://sashiko.dev/#/patchset/20260323201225.1836561-1-github%40szelinsky.de
Best Regards,
Oleksij
On Mon, Mar 23, 2026 at 09:12:22PM +0100, Carlo Szelinsky wrote:
> This series adds poll-based event detection and LED trigger support
> to the PSE core subsystem.
>
> Patches 1-2 introduce the poll path independently of LED support,
> so it can be tested in isolation on boards with and without IRQ
> configured.
>
> Patch 3 adds LED triggers that hook into the shared event handling
> path introduced by patch 2.
>
> Changes since v1:
> - Split single patch into 3 separate patches
> - Extracted pse_handle_events() and devm_pse_poll_helper() as a
> standalone poll path (patches 1-2), testable without LED code
> - Added DT binding for poll-interval-ms as a separate patch
> - Renamed led-poll-interval-ms to poll-interval-ms for generic use
> - Fire LED triggers from the notification path rather than a
> separate poll loop
>
> Tested on Realtek RTL9303 with HS104 PoE chip, poll path only
> (without IRQ configured). Verified PD connect/disconnect notifications
> and LED trigger state changes. Testing with IRQ configured is still
> needed to verify the refactored pse_isr() path.
>
> Link: https://lore.kernel.org/all/20260314235916.2391678-1-github@szelinsky.de/
>
> Carlo Szelinsky (3):
> dt-bindings: net: pse-pd: add poll-interval-ms property
> net: pse-pd: add devm_pse_poll_helper()
> net: pse-pd: add LED trigger support via notification path
>
> .../bindings/net/pse-pd/pse-controller.yaml | 8 +
> drivers/net/pse-pd/pse_core.c | 267 ++++++++++++++++--
> include/linux/pse-pd/pse.h | 34 +++
> 3 files changed, 278 insertions(+), 31 deletions(-)
>
> --
> 2.43.0
>
>
--
Pengutronix e.K. | |
Steuerwalder Str. 21 | http://www.pengutronix.de/ |
31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
^ permalink raw reply [flat|nested] 10+ messages in thread