1 From 684818189b04b095b34964ed4a3ea5249a840eab Mon Sep 17 00:00:00 2001
2 From: Andrew Lunn <andrew@lunn.ch>
3 Date: Mon, 17 Apr 2023 17:17:28 +0200
4 Subject: [PATCH 6/9] net: phy: phy_device: Call into the PHY driver to set LED
7 Linux LEDs can be software controlled via the brightness file in /sys.
8 LED drivers need to implement a brightness_set function which the core
9 will call. Implement an intermediary in phy_device, which will call
10 into the phy driver if it implements the necessary function.
12 Signed-off-by: Andrew Lunn <andrew@lunn.ch>
13 Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
14 Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
15 Signed-off-by: David S. Miller <davem@davemloft.net>
17 drivers/net/phy/phy_device.c | 15 ++++++++++++---
18 include/linux/phy.h | 13 +++++++++++++
19 2 files changed, 25 insertions(+), 3 deletions(-)
21 --- a/drivers/net/phy/phy_device.c
22 +++ b/drivers/net/phy/phy_device.c
23 @@ -2934,11 +2934,18 @@ static bool phy_drv_supports_irq(struct
24 return phydrv->config_intr && phydrv->handle_interrupt;
27 -/* Dummy implementation until calls into PHY driver are added */
28 static int phy_led_set_brightness(struct led_classdev *led_cdev,
29 enum led_brightness value)
32 + struct phy_led *phyled = to_phy_led(led_cdev);
33 + struct phy_device *phydev = phyled->phydev;
36 + mutex_lock(&phydev->lock);
37 + err = phydev->drv->led_brightness_set(phydev, phyled->index, value);
38 + mutex_unlock(&phydev->lock);
43 static int of_phy_led(struct phy_device *phydev,
44 @@ -2955,12 +2962,14 @@ static int of_phy_led(struct phy_device
47 cdev = &phyled->led_cdev;
48 + phyled->phydev = phydev;
50 err = of_property_read_u8(led, "reg", &phyled->index);
54 - cdev->brightness_set_blocking = phy_led_set_brightness;
55 + if (phydev->drv->led_brightness_set)
56 + cdev->brightness_set_blocking = phy_led_set_brightness;
57 cdev->max_brightness = 1;
58 init_data.devicename = dev_name(&phydev->mdio.dev);
59 init_data.fwnode = of_fwnode_handle(led);
60 --- a/include/linux/phy.h
61 +++ b/include/linux/phy.h
62 @@ -774,15 +774,19 @@ struct phy_tdr_config {
63 * struct phy_led: An LED driven by the PHY
66 + * @phydev: PHY this LED is attached to
67 * @led_cdev: Standard LED class structure
68 * @index: Number of the LED
71 struct list_head list;
72 + struct phy_device *phydev;
73 struct led_classdev led_cdev;
77 +#define to_phy_led(d) container_of(d, struct phy_led, led_cdev)
80 * struct phy_driver - Driver structure for a particular PHY type
82 @@ -997,6 +1001,15 @@ struct phy_driver {
83 int (*get_sqi)(struct phy_device *dev);
84 /** @get_sqi_max: Get the maximum signal quality indication */
85 int (*get_sqi_max)(struct phy_device *dev);
88 + * @led_brightness_set: Set a PHY LED brightness. Index
89 + * indicates which of the PHYs led should be set. Value
90 + * follows the standard LED class meaning, e.g. LED_OFF,
91 + * LED_HALF, LED_FULL.
93 + int (*led_brightness_set)(struct phy_device *dev,
94 + u8 index, enum led_brightness value);
96 #define to_phy_driver(d) container_of(to_mdio_common_driver(d), \
97 struct phy_driver, mdiodrv)