forked from openwrt/openwrt
-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
generic: 6.1: backport patch adding support for LED PHY
Backport patch adding support for LED PHY directly in PHY ops struct. Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
- Loading branch information
Showing
4 changed files
with
603 additions
and
0 deletions.
There are no files selected for viewing
62 changes: 62 additions & 0 deletions
62
...inux/generic/backport-6.1/750-v6.6-01-led-trig-netdev-Fix-requesting-offload-device.patch
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
From 7df1f14c04cbb1950e79c19793420f87227c3e80 Mon Sep 17 00:00:00 2001 | ||
From: Andrew Lunn <andrew@lunn.ch> | ||
Date: Tue, 8 Aug 2023 23:04:33 +0200 | ||
Subject: [PATCH 1/4] led: trig: netdev: Fix requesting offload device | ||
|
||
When the netdev trigger is activates, it tries to determine what | ||
device the LED blinks for, and what the current blink mode is. | ||
|
||
The documentation for hw_control_get() says: | ||
|
||
* Return 0 on success, a negative error number on failing parsing the | ||
* initial mode. Error from this function is NOT FATAL as the device | ||
* may be in a not supported initial state by the attached LED trigger. | ||
*/ | ||
|
||
For the Marvell PHY and the Armada 370-rd board, the initial LED blink | ||
mode is not supported by the trigger, so it returns an error. This | ||
resulted in not getting the device the LED is blinking for. As a | ||
result, the device is unknown and offloaded is never performed. | ||
|
||
Change to condition to always get the device if offloading is | ||
supported, and reduce the scope of testing for an error from | ||
hw_control_get() to skip setting trigger internal state if there is an | ||
error. | ||
|
||
Reviewed-by: Simon Horman <simon.horman@corigine.com> | ||
Signed-off-by: Andrew Lunn <andrew@lunn.ch> | ||
Tested-by: Daniel Golle <daniel@makrotopia.org> | ||
Link: https://lore.kernel.org/r/20230808210436.838995-2-andrew@lunn.ch | ||
Signed-off-by: Jakub Kicinski <kuba@kernel.org> | ||
--- | ||
drivers/leds/trigger/ledtrig-netdev.c | 8 +++++--- | ||
1 file changed, 5 insertions(+), 3 deletions(-) | ||
|
||
diff --git a/drivers/leds/trigger/ledtrig-netdev.c b/drivers/leds/trigger/ledtrig-netdev.c | ||
index c9bc5a91ec83..3d215a556e20 100644 | ||
--- a/drivers/leds/trigger/ledtrig-netdev.c | ||
+++ b/drivers/leds/trigger/ledtrig-netdev.c | ||
@@ -564,15 +564,17 @@ static int netdev_trig_activate(struct led_classdev *led_cdev) | ||
/* Check if hw control is active by default on the LED. | ||
* Init already enabled mode in hw control. | ||
*/ | ||
- if (supports_hw_control(led_cdev) && | ||
- !led_cdev->hw_control_get(led_cdev, &mode)) { | ||
+ if (supports_hw_control(led_cdev)) { | ||
dev = led_cdev->hw_control_get_device(led_cdev); | ||
if (dev) { | ||
const char *name = dev_name(dev); | ||
|
||
set_device_name(trigger_data, name, strlen(name)); | ||
trigger_data->hw_control = true; | ||
- trigger_data->mode = mode; | ||
+ | ||
+ rc = led_cdev->hw_control_get(led_cdev, &mode); | ||
+ if (!rc) | ||
+ trigger_data->mode = mode; | ||
} | ||
} | ||
|
||
-- | ||
2.40.1 | ||
|
156 changes: 156 additions & 0 deletions
156
...neric/backport-6.1/750-v6.6-02-net-phy-phy_device-Call-into-the-PHY-driver-to-set-L.patch
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,156 @@ | ||
From 1dcc03c9a7a824a31eaaecdfaa03542fb25feb6c Mon Sep 17 00:00:00 2001 | ||
From: Andrew Lunn <andrew@lunn.ch> | ||
Date: Tue, 8 Aug 2023 23:04:34 +0200 | ||
Subject: [PATCH 2/4] net: phy: phy_device: Call into the PHY driver to set LED | ||
offload | ||
|
||
Linux LEDs can be requested to perform hardware accelerated blinking | ||
to indicate link, RX, TX etc. Pass the rules for blinking to the PHY | ||
driver, if it implements the ops needed to determine if a given | ||
pattern can be offloaded, to offload it, and what the current offload | ||
is. Additionally implement the op needed to get what device the LED is | ||
for. | ||
|
||
Reviewed-by: Simon Horman <simon.horman@corigine.com> | ||
Signed-off-by: Andrew Lunn <andrew@lunn.ch> | ||
Tested-by: Daniel Golle <daniel@makrotopia.org> | ||
Link: https://lore.kernel.org/r/20230808210436.838995-3-andrew@lunn.ch | ||
Signed-off-by: Jakub Kicinski <kuba@kernel.org> | ||
--- | ||
drivers/net/phy/phy_device.c | 68 ++++++++++++++++++++++++++++++++++++ | ||
include/linux/phy.h | 33 +++++++++++++++++ | ||
2 files changed, 101 insertions(+) | ||
|
||
diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c | ||
index 3e9909b30938..17cb3e07216a 100644 | ||
--- a/drivers/net/phy/phy_device.c | ||
+++ b/drivers/net/phy/phy_device.c | ||
@@ -3020,6 +3020,61 @@ static int phy_led_blink_set(struct led_classdev *led_cdev, | ||
return err; | ||
} | ||
|
||
+static __maybe_unused struct device * | ||
+phy_led_hw_control_get_device(struct led_classdev *led_cdev) | ||
+{ | ||
+ struct phy_led *phyled = to_phy_led(led_cdev); | ||
+ struct phy_device *phydev = phyled->phydev; | ||
+ | ||
+ if (phydev->attached_dev) | ||
+ return &phydev->attached_dev->dev; | ||
+ return NULL; | ||
+} | ||
+ | ||
+static int __maybe_unused | ||
+phy_led_hw_control_get(struct led_classdev *led_cdev, | ||
+ unsigned long *rules) | ||
+{ | ||
+ struct phy_led *phyled = to_phy_led(led_cdev); | ||
+ struct phy_device *phydev = phyled->phydev; | ||
+ int err; | ||
+ | ||
+ mutex_lock(&phydev->lock); | ||
+ err = phydev->drv->led_hw_control_get(phydev, phyled->index, rules); | ||
+ mutex_unlock(&phydev->lock); | ||
+ | ||
+ return err; | ||
+} | ||
+ | ||
+static int __maybe_unused | ||
+phy_led_hw_control_set(struct led_classdev *led_cdev, | ||
+ unsigned long rules) | ||
+{ | ||
+ struct phy_led *phyled = to_phy_led(led_cdev); | ||
+ struct phy_device *phydev = phyled->phydev; | ||
+ int err; | ||
+ | ||
+ mutex_lock(&phydev->lock); | ||
+ err = phydev->drv->led_hw_control_set(phydev, phyled->index, rules); | ||
+ mutex_unlock(&phydev->lock); | ||
+ | ||
+ return err; | ||
+} | ||
+ | ||
+static __maybe_unused int phy_led_hw_is_supported(struct led_classdev *led_cdev, | ||
+ unsigned long rules) | ||
+{ | ||
+ struct phy_led *phyled = to_phy_led(led_cdev); | ||
+ struct phy_device *phydev = phyled->phydev; | ||
+ int err; | ||
+ | ||
+ mutex_lock(&phydev->lock); | ||
+ err = phydev->drv->led_hw_is_supported(phydev, phyled->index, rules); | ||
+ mutex_unlock(&phydev->lock); | ||
+ | ||
+ return err; | ||
+} | ||
+ | ||
static void phy_leds_unregister(struct phy_device *phydev) | ||
{ | ||
struct phy_led *phyled; | ||
@@ -3057,6 +3112,19 @@ static int of_phy_led(struct phy_device *phydev, | ||
cdev->brightness_set_blocking = phy_led_set_brightness; | ||
if (phydev->drv->led_blink_set) | ||
cdev->blink_set = phy_led_blink_set; | ||
+ | ||
+#ifdef CONFIG_LEDS_TRIGGERS | ||
+ if (phydev->drv->led_hw_is_supported && | ||
+ phydev->drv->led_hw_control_set && | ||
+ phydev->drv->led_hw_control_get) { | ||
+ cdev->hw_control_is_supported = phy_led_hw_is_supported; | ||
+ cdev->hw_control_set = phy_led_hw_control_set; | ||
+ cdev->hw_control_get = phy_led_hw_control_get; | ||
+ cdev->hw_control_trigger = "netdev"; | ||
+ } | ||
+ | ||
+ cdev->hw_control_get_device = phy_led_hw_control_get_device; | ||
+#endif | ||
cdev->max_brightness = 1; | ||
init_data.devicename = dev_name(&phydev->mdio.dev); | ||
init_data.fwnode = of_fwnode_handle(led); | ||
diff --git a/include/linux/phy.h b/include/linux/phy.h | ||
index b963ce22e7c7..3c1ceedd1b77 100644 | ||
--- a/include/linux/phy.h | ||
+++ b/include/linux/phy.h | ||
@@ -1105,6 +1105,39 @@ struct phy_driver { | ||
int (*led_blink_set)(struct phy_device *dev, u8 index, | ||
unsigned long *delay_on, | ||
unsigned long *delay_off); | ||
+ /** | ||
+ * @led_hw_is_supported: Can the HW support the given rules. | ||
+ * @dev: PHY device which has the LED | ||
+ * @index: Which LED of the PHY device | ||
+ * @rules The core is interested in these rules | ||
+ * | ||
+ * Return 0 if yes, -EOPNOTSUPP if not, or an error code. | ||
+ */ | ||
+ int (*led_hw_is_supported)(struct phy_device *dev, u8 index, | ||
+ unsigned long rules); | ||
+ /** | ||
+ * @led_hw_control_set: Set the HW to control the LED | ||
+ * @dev: PHY device which has the LED | ||
+ * @index: Which LED of the PHY device | ||
+ * @rules The rules used to control the LED | ||
+ * | ||
+ * Returns 0, or a an error code. | ||
+ */ | ||
+ int (*led_hw_control_set)(struct phy_device *dev, u8 index, | ||
+ unsigned long rules); | ||
+ /** | ||
+ * @led_hw_control_get: Get how the HW is controlling the LED | ||
+ * @dev: PHY device which has the LED | ||
+ * @index: Which LED of the PHY device | ||
+ * @rules Pointer to the rules used to control the LED | ||
+ * | ||
+ * Set *@rules to how the HW is currently blinking. Returns 0 | ||
+ * on success, or a error code if the current blinking cannot | ||
+ * be represented in rules, or some other error happens. | ||
+ */ | ||
+ int (*led_hw_control_get)(struct phy_device *dev, u8 index, | ||
+ unsigned long *rules); | ||
+ | ||
}; | ||
#define to_phy_driver(d) container_of(to_mdio_common_driver(d), \ | ||
struct phy_driver, mdiodrv) | ||
-- | ||
2.40.1 | ||
|
Oops, something went wrong.