* [PATCH net-next 0/5] net: phy: further decouple provider from consumer part
@ 2026-03-07 21:30 Heiner Kallweit
2026-03-07 21:31 ` [PATCH net-next 1/5] net: phy: move mdio_device reset handling functions in the code Heiner Kallweit
` (4 more replies)
0 siblings, 5 replies; 7+ messages in thread
From: Heiner Kallweit @ 2026-03-07 21:30 UTC (permalink / raw)
To: Andrew Lunn, Russell King - ARM Linux, Jakub Kicinski,
Paolo Abeni, David Miller, Eric Dumazet
Cc: netdev@vger.kernel.org, Philipp Zabel
This series aims at further decoupling the provider and consumer part
in phylib.
Heiner Kallweit (5):
net: phy: move mdio_device reset handling functions in the code
net: phy: make mdio_device.c part of libphy
net: phy: move (of_)mdio_find_bus to mdio_bus_provider.c
net: phy: move registering mdio_bus_class and mdio_bus_type to libphy
net: phy: move remaining provider code to mdio_bus_provider.c
drivers/net/phy/Makefile | 6 +-
drivers/net/phy/mdio-private.h | 11 -
drivers/net/phy/mdio_bus.c | 385 ----------------------------
drivers/net/phy/mdio_bus_provider.c | 319 +++++++++++++++++++++++
drivers/net/phy/mdio_device.c | 165 +++++++-----
drivers/net/phy/phy_device.c | 13 +
drivers/net/phy/phylib-internal.h | 7 +
include/linux/mdio.h | 2 -
include/linux/phy.h | 3 -
9 files changed, 441 insertions(+), 470 deletions(-)
delete mode 100644 drivers/net/phy/mdio-private.h
--
2.53.0
^ permalink raw reply [flat|nested] 7+ messages in thread* [PATCH net-next 1/5] net: phy: move mdio_device reset handling functions in the code 2026-03-07 21:30 [PATCH net-next 0/5] net: phy: further decouple provider from consumer part Heiner Kallweit @ 2026-03-07 21:31 ` Heiner Kallweit 2026-03-07 21:32 ` [PATCH net-next 2/5] net: phy: make mdio_device.c part of libphy Heiner Kallweit ` (3 subsequent siblings) 4 siblings, 0 replies; 7+ messages in thread From: Heiner Kallweit @ 2026-03-07 21:31 UTC (permalink / raw) To: Andrew Lunn, Russell King - ARM Linux, Jakub Kicinski, Paolo Abeni, David Miller, Eric Dumazet Cc: netdev@vger.kernel.org, Philipp Zabel In preparation of a follow-up patch this moves reset-related functions in the code. Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com> --- drivers/net/phy/mdio_device.c | 162 +++++++++++++++++----------------- 1 file changed, 81 insertions(+), 81 deletions(-) diff --git a/drivers/net/phy/mdio_device.c b/drivers/net/phy/mdio_device.c index b8a5a183819..da4fb7484c7 100644 --- a/drivers/net/phy/mdio_device.c +++ b/drivers/net/phy/mdio_device.c @@ -24,6 +24,87 @@ #include <linux/property.h> #include "mdio-private.h" +/** + * mdio_device_register_reset - Read and initialize the reset properties of + * an mdio device + * @mdiodev: mdio_device structure + * + * Return: Zero if successful, negative error code on failure + */ +int mdio_device_register_reset(struct mdio_device *mdiodev) +{ + struct reset_control *reset; + + /* Deassert the optional reset signal */ + mdiodev->reset_gpio = gpiod_get_optional(&mdiodev->dev, + "reset", GPIOD_OUT_LOW); + if (IS_ERR(mdiodev->reset_gpio)) + return PTR_ERR(mdiodev->reset_gpio); + + if (mdiodev->reset_gpio) + gpiod_set_consumer_name(mdiodev->reset_gpio, "PHY reset"); + + reset = reset_control_get_optional_exclusive(&mdiodev->dev, "phy"); + if (IS_ERR(reset)) { + gpiod_put(mdiodev->reset_gpio); + mdiodev->reset_gpio = NULL; + return PTR_ERR(reset); + } + + mdiodev->reset_ctrl = reset; + + /* Read optional firmware properties */ + device_property_read_u32(&mdiodev->dev, "reset-assert-us", + &mdiodev->reset_assert_delay); + device_property_read_u32(&mdiodev->dev, "reset-deassert-us", + &mdiodev->reset_deassert_delay); + + return 0; +} + +/** + * mdio_device_unregister_reset - uninitialize the reset properties of + * an mdio device + * @mdiodev: mdio_device structure + */ +void mdio_device_unregister_reset(struct mdio_device *mdiodev) +{ + gpiod_put(mdiodev->reset_gpio); + mdiodev->reset_gpio = NULL; + reset_control_put(mdiodev->reset_ctrl); + mdiodev->reset_ctrl = NULL; + mdiodev->reset_assert_delay = 0; + mdiodev->reset_deassert_delay = 0; +} + +void mdio_device_reset(struct mdio_device *mdiodev, int value) +{ + unsigned int d; + + if (!mdiodev->reset_gpio && !mdiodev->reset_ctrl) + return; + + if (mdiodev->reset_state == value) + return; + + if (mdiodev->reset_gpio) + gpiod_set_value_cansleep(mdiodev->reset_gpio, value); + + if (mdiodev->reset_ctrl) { + if (value) + reset_control_assert(mdiodev->reset_ctrl); + else + reset_control_deassert(mdiodev->reset_ctrl); + } + + d = value ? mdiodev->reset_assert_delay : mdiodev->reset_deassert_delay; + if (d) + fsleep(d); + + mdiodev->reset_state = value; +} +EXPORT_SYMBOL(mdio_device_reset); + void mdio_device_free(struct mdio_device *mdiodev) { put_device(&mdiodev->dev); @@ -108,87 +189,6 @@ void mdio_device_remove(struct mdio_device *mdiodev) } EXPORT_SYMBOL(mdio_device_remove); -/** - * mdio_device_register_reset - Read and initialize the reset properties of - * an mdio device - * @mdiodev: mdio_device structure - * - * Return: Zero if successful, negative error code on failure - */ -int mdio_device_register_reset(struct mdio_device *mdiodev) -{ - struct reset_control *reset; - - /* Deassert the optional reset signal */ - mdiodev->reset_gpio = gpiod_get_optional(&mdiodev->dev, - "reset", GPIOD_OUT_LOW); - if (IS_ERR(mdiodev->reset_gpio)) - return PTR_ERR(mdiodev->reset_gpio); - - if (mdiodev->reset_gpio) - gpiod_set_consumer_name(mdiodev->reset_gpio, "PHY reset"); - - reset = reset_control_get_optional_exclusive(&mdiodev->dev, "phy"); - if (IS_ERR(reset)) { - gpiod_put(mdiodev->reset_gpio); - mdiodev->reset_gpio = NULL; - return PTR_ERR(reset); - } - - mdiodev->reset_ctrl = reset; - - /* Read optional firmware properties */ - device_property_read_u32(&mdiodev->dev, "reset-assert-us", - &mdiodev->reset_assert_delay); - device_property_read_u32(&mdiodev->dev, "reset-deassert-us", - &mdiodev->reset_deassert_delay); - - return 0; -} - -/** - * mdio_device_unregister_reset - uninitialize the reset properties of - * an mdio device - * @mdiodev: mdio_device structure - */ -void mdio_device_unregister_reset(struct mdio_device *mdiodev) -{ - gpiod_put(mdiodev->reset_gpio); - mdiodev->reset_gpio = NULL; - reset_control_put(mdiodev->reset_ctrl); - mdiodev->reset_ctrl = NULL; - mdiodev->reset_assert_delay = 0; - mdiodev->reset_deassert_delay = 0; -} - -void mdio_device_reset(struct mdio_device *mdiodev, int value) -{ - unsigned int d; - - if (!mdiodev->reset_gpio && !mdiodev->reset_ctrl) - return; - - if (mdiodev->reset_state == value) - return; - - if (mdiodev->reset_gpio) - gpiod_set_value_cansleep(mdiodev->reset_gpio, value); - - if (mdiodev->reset_ctrl) { - if (value) - reset_control_assert(mdiodev->reset_ctrl); - else - reset_control_deassert(mdiodev->reset_ctrl); - } - - d = value ? mdiodev->reset_assert_delay : mdiodev->reset_deassert_delay; - if (d) - fsleep(d); - - mdiodev->reset_state = value; -} -EXPORT_SYMBOL(mdio_device_reset); - /** * mdio_probe - probe an MDIO device * @dev: device to probe -- 2.53.0 ^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH net-next 2/5] net: phy: make mdio_device.c part of libphy 2026-03-07 21:30 [PATCH net-next 0/5] net: phy: further decouple provider from consumer part Heiner Kallweit 2026-03-07 21:31 ` [PATCH net-next 1/5] net: phy: move mdio_device reset handling functions in the code Heiner Kallweit @ 2026-03-07 21:32 ` Heiner Kallweit 2026-03-08 13:15 ` kernel test robot 2026-03-07 21:32 ` [PATCH net-next 3/5] net: phy: move (of_)mdio_find_bus to mdio_bus_provider.c Heiner Kallweit ` (2 subsequent siblings) 4 siblings, 1 reply; 7+ messages in thread From: Heiner Kallweit @ 2026-03-07 21:32 UTC (permalink / raw) To: Andrew Lunn, Russell King - ARM Linux, Jakub Kicinski, Paolo Abeni, David Miller, Eric Dumazet Cc: netdev@vger.kernel.org, Philipp Zabel This patch - makes mdio_device.c part of libphy - makes mdio_device_(un)register_reset() static - moves mdiobus_(un)register_device() from mdio_bus.c to mdio_device.c, stops exporting both functions and makes them private to phylib This further decouples the MDIO consumer functionality from libphy. Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com> --- drivers/net/phy/Makefile | 6 ++--- drivers/net/phy/mdio-private.h | 11 --------- drivers/net/phy/mdio_bus.c | 36 ---------------------------- drivers/net/phy/mdio_device.c | 39 ++++++++++++++++++++++++++++--- drivers/net/phy/phylib-internal.h | 4 ++++ include/linux/mdio.h | 2 -- 6 files changed, 43 insertions(+), 55 deletions(-) delete mode 100644 drivers/net/phy/mdio-private.h diff --git a/drivers/net/phy/Makefile b/drivers/net/phy/Makefile index 3a34917adea..8d262b4e2be 100644 --- a/drivers/net/phy/Makefile +++ b/drivers/net/phy/Makefile @@ -3,8 +3,8 @@ libphy-y := phy.o phy-c45.o phy-core.o phy_device.o \ linkmode.o phy_link_topology.o \ - phy_caps.o mdio_bus_provider.o phy_port.o -mdio-bus-y += mdio_bus.o mdio_device.o + phy_caps.o mdio_bus_provider.o phy_port.o \ + mdio_device.o ifdef CONFIG_PHYLIB # built-in whenever PHYLIB is built-in or module @@ -15,7 +15,7 @@ libphy-$(CONFIG_SWPHY) += swphy.o libphy-$(CONFIG_LED_TRIGGER_PHY) += phy_led_triggers.o libphy-$(CONFIG_OPEN_ALLIANCE_HELPERS) += open_alliance_helpers.o -obj-$(CONFIG_MDIO_BUS) += mdio-bus.o +obj-$(CONFIG_MDIO_BUS) += mdio_bus.o obj-$(CONFIG_PHYLINK) += phylink.o obj-$(CONFIG_PHYLIB) += libphy.o obj-$(CONFIG_PHYLIB) += mdio_devres.o diff --git a/drivers/net/phy/mdio-private.h b/drivers/net/phy/mdio-private.h deleted file mode 100644 index 8bc6d9088af..00000000000 --- a/drivers/net/phy/mdio-private.h +++ /dev/null @@ -1,11 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ -#ifndef __MDIO_PRIVATE_H -#define __MDIO_PRIVATE_H - -/* MDIO internal helpers - */ - -int mdio_device_register_reset(struct mdio_device *mdiodev); -void mdio_device_unregister_reset(struct mdio_device *mdiodev); - -#endif /* __MDIO_PRIVATE_H */ diff --git a/drivers/net/phy/mdio_bus.c b/drivers/net/phy/mdio_bus.c index 48c0447e6a8..a30c679feec 100644 --- a/drivers/net/phy/mdio_bus.c +++ b/drivers/net/phy/mdio_bus.c @@ -29,46 +29,10 @@ #include <linux/string.h> #include <linux/uaccess.h> #include <linux/unistd.h> -#include "mdio-private.h" #define CREATE_TRACE_POINTS #include <trace/events/mdio.h> -int mdiobus_register_device(struct mdio_device *mdiodev) -{ - int err; - - if (mdiodev->bus->mdio_map[mdiodev->addr]) - return -EBUSY; - - if (mdiodev->flags & MDIO_DEVICE_FLAG_PHY) { - err = mdio_device_register_reset(mdiodev); - if (err) - return err; - - /* Assert the reset signal */ - mdio_device_reset(mdiodev, 1); - } - - mdiodev->bus->mdio_map[mdiodev->addr] = mdiodev; - - return 0; -} -EXPORT_SYMBOL(mdiobus_register_device); - -int mdiobus_unregister_device(struct mdio_device *mdiodev) -{ - if (mdiodev->bus->mdio_map[mdiodev->addr] != mdiodev) - return -EINVAL; - - mdio_device_unregister_reset(mdiodev); - - mdiodev->bus->mdio_map[mdiodev->addr] = NULL; - - return 0; -} -EXPORT_SYMBOL(mdiobus_unregister_device); - static struct mdio_device *mdiobus_find_device(struct mii_bus *bus, int addr) { bool addr_valid = addr >= 0 && addr < ARRAY_SIZE(bus->mdio_map); diff --git a/drivers/net/phy/mdio_device.c b/drivers/net/phy/mdio_device.c index da4fb7484c7..56080d3d2d2 100644 --- a/drivers/net/phy/mdio_device.c +++ b/drivers/net/phy/mdio_device.c @@ -22,7 +22,7 @@ #include <linux/string.h> #include <linux/unistd.h> #include <linux/property.h> -#include "mdio-private.h" +#include "phylib-internal.h" /** * mdio_device_register_reset - Read and initialize the reset properties of @@ -31,7 +31,7 @@ * * Return: Zero if successful, negative error code on failure */ -int mdio_device_register_reset(struct mdio_device *mdiodev) +static int mdio_device_register_reset(struct mdio_device *mdiodev) { struct reset_control *reset; @@ -67,7 +67,7 @@ int mdio_device_register_reset(struct mdio_device *mdiodev) * an mdio device * @mdiodev: mdio_device structure */ -void mdio_device_unregister_reset(struct mdio_device *mdiodev) +static void mdio_device_unregister_reset(struct mdio_device *mdiodev) { gpiod_put(mdiodev->reset_gpio); mdiodev->reset_gpio = NULL; @@ -189,6 +189,39 @@ void mdio_device_remove(struct mdio_device *mdiodev) } EXPORT_SYMBOL(mdio_device_remove); +int mdiobus_register_device(struct mdio_device *mdiodev) +{ + int err; + + if (mdiodev->bus->mdio_map[mdiodev->addr]) + return -EBUSY; + + if (mdiodev->flags & MDIO_DEVICE_FLAG_PHY) { + err = mdio_device_register_reset(mdiodev); + if (err) + return err; + + /* Assert the reset signal */ + mdio_device_reset(mdiodev, 1); + } + + mdiodev->bus->mdio_map[mdiodev->addr] = mdiodev; + + return 0; +} + +int mdiobus_unregister_device(struct mdio_device *mdiodev) +{ + if (mdiodev->bus->mdio_map[mdiodev->addr] != mdiodev) + return -EINVAL; + + mdio_device_unregister_reset(mdiodev); + + mdiodev->bus->mdio_map[mdiodev->addr] = NULL; + + return 0; +} + /** * mdio_probe - probe an MDIO device * @dev: device to probe diff --git a/drivers/net/phy/phylib-internal.h b/drivers/net/phy/phylib-internal.h index dc9592c6bb8..bfb1aa82386 100644 --- a/drivers/net/phy/phylib-internal.h +++ b/drivers/net/phy/phylib-internal.h @@ -6,6 +6,7 @@ #ifndef __PHYLIB_INTERNAL_H #define __PHYLIB_INTERNAL_H +struct mdio_device; struct phy_device; /* @@ -20,6 +21,9 @@ void of_set_phy_timing_role(struct phy_device *phydev); int phy_speed_down_core(struct phy_device *phydev); void phy_check_downshift(struct phy_device *phydev); +int mdiobus_register_device(struct mdio_device *mdiodev); +int mdiobus_unregister_device(struct mdio_device *mdiodev); + int genphy_c45_read_eee_adv(struct phy_device *phydev, unsigned long *adv); #endif /* __PHYLIB_INTERNAL_H */ diff --git a/include/linux/mdio.h b/include/linux/mdio.h index 5d1203b9af2..f4f9d960944 100644 --- a/include/linux/mdio.h +++ b/include/linux/mdio.h @@ -688,8 +688,6 @@ static inline int mdiodev_c45_write(struct mdio_device *mdiodev, u32 devad, val); } -int mdiobus_register_device(struct mdio_device *mdiodev); -int mdiobus_unregister_device(struct mdio_device *mdiodev); bool mdiobus_is_registered_device(struct mii_bus *bus, int addr); struct phy_device *mdiobus_get_phy(struct mii_bus *bus, int addr); -- 2.53.0 ^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH net-next 2/5] net: phy: make mdio_device.c part of libphy 2026-03-07 21:32 ` [PATCH net-next 2/5] net: phy: make mdio_device.c part of libphy Heiner Kallweit @ 2026-03-08 13:15 ` kernel test robot 0 siblings, 0 replies; 7+ messages in thread From: kernel test robot @ 2026-03-08 13:15 UTC (permalink / raw) To: Heiner Kallweit, Andrew Lunn, Russell King - ARM Linux, Jakub Kicinski, Paolo Abeni, David Miller, Eric Dumazet Cc: oe-kbuild-all, netdev, Philipp Zabel Hi Heiner, kernel test robot noticed the following build errors: [auto build test ERROR on net-next/main] url: https://github.com/intel-lab-lkp/linux/commits/Heiner-Kallweit/net-phy-move-mdio_device-reset-handling-functions-in-the-code/20260308-053505 base: net-next/main patch link: https://lore.kernel.org/r/8600cf79-7604-43c1-8cc0-306e58e31153%40gmail.com patch subject: [PATCH net-next 2/5] net: phy: make mdio_device.c part of libphy config: sparc64-randconfig-002-20260308 (https://download.01.org/0day-ci/archive/20260308/202603082137.KWkiQ4Ij-lkp@intel.com/config) compiler: sparc64-linux-gcc (GCC) 8.5.0 reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260308/202603082137.KWkiQ4Ij-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/202603082137.KWkiQ4Ij-lkp@intel.com/ All errors (new ones prefixed by >>): sparc64-linux-ld: drivers/phy/broadcom/phy-bcm-ns-usb3.o: in function `bcm_ns_usb3_mdio_driver_init': >> drivers/phy/broadcom/phy-bcm-ns-usb3.c:241: undefined reference to `mdio_driver_register' sparc64-linux-ld: drivers/phy/broadcom/phy-bcm-ns-usb3.o: in function `bcm_ns_usb3_mdio_driver_exit': >> drivers/phy/broadcom/phy-bcm-ns-usb3.c:241: undefined reference to `mdio_driver_unregister' sparc64-linux-ld: drivers/phy/broadcom/phy-bcm-ns2-pcie.o: in function `ns2_pci_phy_driver_init': >> drivers/phy/broadcom/phy-bcm-ns2-pcie.c:82: undefined reference to `mdio_driver_register' sparc64-linux-ld: drivers/phy/broadcom/phy-bcm-ns2-pcie.o: in function `ns2_pci_phy_driver_exit': >> drivers/phy/broadcom/phy-bcm-ns2-pcie.c:82: undefined reference to `mdio_driver_unregister' vim +241 drivers/phy/broadcom/phy-bcm-ns-usb3.c af850e14a7ae49 drivers/phy/broadcom/phy-bcm-ns-usb3.c Rafał Miłecki 2017-06-08 240 36a94760c98954 drivers/phy/broadcom/phy-bcm-ns-usb3.c Rafał Miłecki 2020-11-13 @241 mdio_module_driver(bcm_ns_usb3_mdio_driver); e5666281d9eadb drivers/phy/phy-bcm-ns-usb3.c Rafał Miłecki 2016-08-12 242 -- 0-DAY CI Kernel Test Service https://github.com/intel/lkp-tests/wiki ^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH net-next 3/5] net: phy: move (of_)mdio_find_bus to mdio_bus_provider.c 2026-03-07 21:30 [PATCH net-next 0/5] net: phy: further decouple provider from consumer part Heiner Kallweit 2026-03-07 21:31 ` [PATCH net-next 1/5] net: phy: move mdio_device reset handling functions in the code Heiner Kallweit 2026-03-07 21:32 ` [PATCH net-next 2/5] net: phy: make mdio_device.c part of libphy Heiner Kallweit @ 2026-03-07 21:32 ` Heiner Kallweit 2026-03-07 21:33 ` [PATCH net-next 4/5] net: phy: move registering mdio_bus_class and mdio_bus_type to libphy Heiner Kallweit 2026-03-07 21:34 ` [PATCH net-next 5/5] net: phy: move remaining provider code to mdio_bus_provider.c Heiner Kallweit 4 siblings, 0 replies; 7+ messages in thread From: Heiner Kallweit @ 2026-03-07 21:32 UTC (permalink / raw) To: Andrew Lunn, Russell King - ARM Linux, Jakub Kicinski, Paolo Abeni, David Miller, Eric Dumazet Cc: netdev@vger.kernel.org, Philipp Zabel Functionality outside libphy shouldn't access mdio_bus_class directly. So move both functions to the provider side. This is a step towards making mdio_bus_class private to libphy. Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com> --- drivers/net/phy/mdio_bus.c | 44 ----------------------------- drivers/net/phy/mdio_bus_provider.c | 44 +++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+), 44 deletions(-) diff --git a/drivers/net/phy/mdio_bus.c b/drivers/net/phy/mdio_bus.c index a30c679feec..c9a495390d2 100644 --- a/drivers/net/phy/mdio_bus.c +++ b/drivers/net/phy/mdio_bus.c @@ -276,50 +276,6 @@ const struct class mdio_bus_class = { }; EXPORT_SYMBOL_GPL(mdio_bus_class); -/** - * mdio_find_bus - Given the name of a mdiobus, find the mii_bus. - * @mdio_name: The name of a mdiobus. - * - * Return: a reference to the mii_bus, or NULL if none found. The - * embedded struct device will have its reference count incremented, - * and this must be put_deviced'ed once the bus is finished with. - */ -struct mii_bus *mdio_find_bus(const char *mdio_name) -{ - struct device *d; - - d = class_find_device_by_name(&mdio_bus_class, mdio_name); - return d ? to_mii_bus(d) : NULL; -} -EXPORT_SYMBOL(mdio_find_bus); - -#if IS_ENABLED(CONFIG_OF_MDIO) -/** - * of_mdio_find_bus - Given an mii_bus node, find the mii_bus. - * @mdio_bus_np: Pointer to the mii_bus. - * - * Return: a reference to the mii_bus, or NULL if none found. The - * embedded struct device will have its reference count incremented, - * and this must be put once the bus is finished with. - * - * Because the association of a device_node and mii_bus is made via - * of_mdiobus_register(), the mii_bus cannot be found before it is - * registered with of_mdiobus_register(). - * - */ -struct mii_bus *of_mdio_find_bus(struct device_node *mdio_bus_np) -{ - struct device *d; - - if (!mdio_bus_np) - return NULL; - - d = class_find_device_by_of_node(&mdio_bus_class, mdio_bus_np); - return d ? to_mii_bus(d) : NULL; -} -EXPORT_SYMBOL(of_mdio_find_bus); -#endif - static void mdiobus_stats_acct(struct mdio_bus_stats *stats, bool op, int ret) { preempt_disable(); diff --git a/drivers/net/phy/mdio_bus_provider.c b/drivers/net/phy/mdio_bus_provider.c index 4b063740574..d50fe6eb4b0 100644 --- a/drivers/net/phy/mdio_bus_provider.c +++ b/drivers/net/phy/mdio_bus_provider.c @@ -440,3 +440,47 @@ void mdiobus_free(struct mii_bus *bus) put_device(&bus->dev); } EXPORT_SYMBOL(mdiobus_free); + +/** + * mdio_find_bus - Given the name of a mdiobus, find the mii_bus. + * @mdio_name: The name of a mdiobus. + * + * Return: a reference to the mii_bus, or NULL if none found. The + * embedded struct device will have its reference count incremented, + * and this must be put_deviced'ed once the bus is finished with. + */ +struct mii_bus *mdio_find_bus(const char *mdio_name) +{ + struct device *d; + + d = class_find_device_by_name(&mdio_bus_class, mdio_name); + return d ? to_mii_bus(d) : NULL; +} +EXPORT_SYMBOL(mdio_find_bus); + +#if IS_ENABLED(CONFIG_OF_MDIO) +/** + * of_mdio_find_bus - Given an mii_bus node, find the mii_bus. + * @mdio_bus_np: Pointer to the mii_bus. + * + * Return: a reference to the mii_bus, or NULL if none found. The + * embedded struct device will have its reference count incremented, + * and this must be put once the bus is finished with. + * + * Because the association of a device_node and mii_bus is made via + * of_mdiobus_register(), the mii_bus cannot be found before it is + * registered with of_mdiobus_register(). + * + */ +struct mii_bus *of_mdio_find_bus(struct device_node *mdio_bus_np) +{ + struct device *d; + + if (!mdio_bus_np) + return NULL; + + d = class_find_device_by_of_node(&mdio_bus_class, mdio_bus_np); + return d ? to_mii_bus(d) : NULL; +} +EXPORT_SYMBOL(of_mdio_find_bus); +#endif -- 2.53.0 ^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH net-next 4/5] net: phy: move registering mdio_bus_class and mdio_bus_type to libphy 2026-03-07 21:30 [PATCH net-next 0/5] net: phy: further decouple provider from consumer part Heiner Kallweit ` (2 preceding siblings ...) 2026-03-07 21:32 ` [PATCH net-next 3/5] net: phy: move (of_)mdio_find_bus to mdio_bus_provider.c Heiner Kallweit @ 2026-03-07 21:33 ` Heiner Kallweit 2026-03-07 21:34 ` [PATCH net-next 5/5] net: phy: move remaining provider code to mdio_bus_provider.c Heiner Kallweit 4 siblings, 0 replies; 7+ messages in thread From: Heiner Kallweit @ 2026-03-07 21:33 UTC (permalink / raw) To: Andrew Lunn, Russell King - ARM Linux, Jakub Kicinski, Paolo Abeni, David Miller, Eric Dumazet Cc: netdev@vger.kernel.org, Philipp Zabel The MDIO consumer side shouldn't register class and bus_type. Therefore move this to libphy. Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com> --- drivers/net/phy/mdio_bus.c | 23 ----------------------- drivers/net/phy/phy_device.c | 13 +++++++++++++ 2 files changed, 13 insertions(+), 23 deletions(-) diff --git a/drivers/net/phy/mdio_bus.c b/drivers/net/phy/mdio_bus.c index c9a495390d2..9fb47332602 100644 --- a/drivers/net/phy/mdio_bus.c +++ b/drivers/net/phy/mdio_bus.c @@ -905,28 +905,5 @@ const struct bus_type mdio_bus_type = { }; EXPORT_SYMBOL(mdio_bus_type); -static int __init mdio_bus_init(void) -{ - int ret; - - ret = class_register(&mdio_bus_class); - if (!ret) { - ret = bus_register(&mdio_bus_type); - if (ret) - class_unregister(&mdio_bus_class); - } - - return ret; -} - -static void __exit mdio_bus_exit(void) -{ - class_unregister(&mdio_bus_class); - bus_unregister(&mdio_bus_type); -} - -subsys_initcall(mdio_bus_init); -module_exit(mdio_bus_exit); - MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("MDIO bus/device layer"); diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c index d1cbcfc3d2a..0edff47478c 100644 --- a/drivers/net/phy/phy_device.c +++ b/drivers/net/phy/phy_device.c @@ -3913,6 +3913,14 @@ static int __init phy_init(void) { int rc; + rc = class_register(&mdio_bus_class); + if (rc) + return rc; + + rc = bus_register(&mdio_bus_type); + if (rc) + goto err_class; + rtnl_lock(); ethtool_set_ethtool_phy_ops(&phy_ethtool_phy_ops); phylib_register_stubs(); @@ -3941,6 +3949,9 @@ static int __init phy_init(void) phylib_unregister_stubs(); ethtool_set_ethtool_phy_ops(NULL); rtnl_unlock(); + bus_unregister(&mdio_bus_type); +err_class: + class_unregister(&mdio_bus_class); return rc; } @@ -3953,6 +3964,8 @@ static void __exit phy_exit(void) phylib_unregister_stubs(); ethtool_set_ethtool_phy_ops(NULL); rtnl_unlock(); + bus_unregister(&mdio_bus_type); + class_unregister(&mdio_bus_class); } subsys_initcall(phy_init); -- 2.53.0 ^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH net-next 5/5] net: phy: move remaining provider code to mdio_bus_provider.c 2026-03-07 21:30 [PATCH net-next 0/5] net: phy: further decouple provider from consumer part Heiner Kallweit ` (3 preceding siblings ...) 2026-03-07 21:33 ` [PATCH net-next 4/5] net: phy: move registering mdio_bus_class and mdio_bus_type to libphy Heiner Kallweit @ 2026-03-07 21:34 ` Heiner Kallweit 4 siblings, 0 replies; 7+ messages in thread From: Heiner Kallweit @ 2026-03-07 21:34 UTC (permalink / raw) To: Andrew Lunn, Russell King - ARM Linux, Jakub Kicinski, Paolo Abeni, David Miller, Eric Dumazet Cc: netdev@vger.kernel.org, Philipp Zabel This moves definition of mdio_bus class and bus_type to the provider side, what allows to make them private to libphy. As a prerequisite MDIO statistics handling is moved to the provider side as well. Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com> --- drivers/net/phy/mdio_bus.c | 282 ---------------------------- drivers/net/phy/mdio_bus_provider.c | 275 +++++++++++++++++++++++++++ drivers/net/phy/phylib-internal.h | 3 + include/linux/phy.h | 3 - 4 files changed, 278 insertions(+), 285 deletions(-) diff --git a/drivers/net/phy/mdio_bus.c b/drivers/net/phy/mdio_bus.c index 9fb47332602..00d0e4159e9 100644 --- a/drivers/net/phy/mdio_bus.c +++ b/drivers/net/phy/mdio_bus.c @@ -10,20 +10,14 @@ #include <linux/device.h> #include <linux/errno.h> -#include <linux/etherdevice.h> #include <linux/ethtool.h> -#include <linux/gpio/consumer.h> #include <linux/init.h> #include <linux/io.h> #include <linux/kernel.h> #include <linux/mii.h> #include <linux/mm.h> #include <linux/module.h> -#include <linux/netdevice.h> -#include <linux/of_device.h> -#include <linux/of_mdio.h> #include <linux/phy.h> -#include <linux/reset.h> #include <linux/slab.h> #include <linux/spinlock.h> #include <linux/string.h> @@ -64,218 +58,6 @@ bool mdiobus_is_registered_device(struct mii_bus *bus, int addr) } EXPORT_SYMBOL(mdiobus_is_registered_device); -/** - * mdiobus_release - mii_bus device release callback - * @d: the target struct device that contains the mii_bus - * - * Description: called when the last reference to an mii_bus is - * dropped, to free the underlying memory. - */ -static void mdiobus_release(struct device *d) -{ - struct mii_bus *bus = to_mii_bus(d); - - WARN(bus->state != MDIOBUS_RELEASED && - /* for compatibility with error handling in drivers */ - bus->state != MDIOBUS_ALLOCATED, - "%s: not in RELEASED or ALLOCATED state\n", - bus->id); - - if (bus->state == MDIOBUS_RELEASED) - fwnode_handle_put(dev_fwnode(d)); - - kfree(bus); -} - -struct mdio_bus_stat_attr { - struct device_attribute attr; - int address; - unsigned int field_offset; -}; - -static struct mdio_bus_stat_attr *to_sattr(struct device_attribute *attr) -{ - return container_of(attr, struct mdio_bus_stat_attr, attr); -} - -static u64 mdio_bus_get_stat(struct mdio_bus_stats *s, unsigned int offset) -{ - const u64_stats_t *stats = (const void *)s + offset; - unsigned int start; - u64 val = 0; - - do { - start = u64_stats_fetch_begin(&s->syncp); - val = u64_stats_read(stats); - } while (u64_stats_fetch_retry(&s->syncp, start)); - - return val; -} - -static ssize_t mdio_bus_stat_field_show(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - struct mdio_bus_stat_attr *sattr = to_sattr(attr); - struct mii_bus *bus = to_mii_bus(dev); - u64 val = 0; - - if (sattr->address < 0) { - /* get global stats */ - for (int i = 0; i < PHY_MAX_ADDR; i++) - val += mdio_bus_get_stat(&bus->stats[i], - sattr->field_offset); - } else { - val = mdio_bus_get_stat(&bus->stats[sattr->address], - sattr->field_offset); - } - - return sysfs_emit(buf, "%llu\n", val); -} - -static ssize_t mdio_bus_device_stat_field_show(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - struct mdio_bus_stat_attr *sattr = to_sattr(attr); - struct mdio_device *mdiodev = to_mdio_device(dev); - struct mii_bus *bus = mdiodev->bus; - int addr = mdiodev->addr; - u64 val; - - val = mdio_bus_get_stat(&bus->stats[addr], sattr->field_offset); - - return sysfs_emit(buf, "%llu\n", val); -} - -#define MDIO_BUS_STATS_ATTR(field) \ -static const struct mdio_bus_stat_attr dev_attr_mdio_bus_##field = { \ - .attr = __ATTR(field, 0444, mdio_bus_stat_field_show, NULL), \ - .address = -1, \ - .field_offset = offsetof(struct mdio_bus_stats, field), \ -}; \ -static const struct mdio_bus_stat_attr dev_attr_mdio_bus_device_##field = { \ - .attr = __ATTR(field, 0444, mdio_bus_device_stat_field_show, NULL), \ - .field_offset = offsetof(struct mdio_bus_stats, field), \ -} - -MDIO_BUS_STATS_ATTR(transfers); -MDIO_BUS_STATS_ATTR(errors); -MDIO_BUS_STATS_ATTR(writes); -MDIO_BUS_STATS_ATTR(reads); - -#define MDIO_BUS_STATS_ADDR_ATTR_DECL(field, addr, file) \ -static const struct mdio_bus_stat_attr \ -dev_attr_mdio_bus_addr_##field##_##addr = { \ - .attr = { .attr = { .name = file, .mode = 0444 }, \ - .show = mdio_bus_stat_field_show, \ - }, \ - .address = addr, \ - .field_offset = offsetof(struct mdio_bus_stats, field), \ -} - -#define MDIO_BUS_STATS_ADDR_ATTR(field, addr) \ - MDIO_BUS_STATS_ADDR_ATTR_DECL(field, addr, \ - __stringify(field) "_" __stringify(addr)) - -#define MDIO_BUS_STATS_ADDR_ATTR_GROUP_DECL(addr) \ - MDIO_BUS_STATS_ADDR_ATTR(transfers, addr); \ - MDIO_BUS_STATS_ADDR_ATTR(errors, addr); \ - MDIO_BUS_STATS_ADDR_ATTR(writes, addr); \ - MDIO_BUS_STATS_ADDR_ATTR(reads, addr) \ - -MDIO_BUS_STATS_ADDR_ATTR_GROUP_DECL(0); -MDIO_BUS_STATS_ADDR_ATTR_GROUP_DECL(1); -MDIO_BUS_STATS_ADDR_ATTR_GROUP_DECL(2); -MDIO_BUS_STATS_ADDR_ATTR_GROUP_DECL(3); -MDIO_BUS_STATS_ADDR_ATTR_GROUP_DECL(4); -MDIO_BUS_STATS_ADDR_ATTR_GROUP_DECL(5); -MDIO_BUS_STATS_ADDR_ATTR_GROUP_DECL(6); -MDIO_BUS_STATS_ADDR_ATTR_GROUP_DECL(7); -MDIO_BUS_STATS_ADDR_ATTR_GROUP_DECL(8); -MDIO_BUS_STATS_ADDR_ATTR_GROUP_DECL(9); -MDIO_BUS_STATS_ADDR_ATTR_GROUP_DECL(10); -MDIO_BUS_STATS_ADDR_ATTR_GROUP_DECL(11); -MDIO_BUS_STATS_ADDR_ATTR_GROUP_DECL(12); -MDIO_BUS_STATS_ADDR_ATTR_GROUP_DECL(13); -MDIO_BUS_STATS_ADDR_ATTR_GROUP_DECL(14); -MDIO_BUS_STATS_ADDR_ATTR_GROUP_DECL(15); -MDIO_BUS_STATS_ADDR_ATTR_GROUP_DECL(16); -MDIO_BUS_STATS_ADDR_ATTR_GROUP_DECL(17); -MDIO_BUS_STATS_ADDR_ATTR_GROUP_DECL(18); -MDIO_BUS_STATS_ADDR_ATTR_GROUP_DECL(19); -MDIO_BUS_STATS_ADDR_ATTR_GROUP_DECL(20); -MDIO_BUS_STATS_ADDR_ATTR_GROUP_DECL(21); -MDIO_BUS_STATS_ADDR_ATTR_GROUP_DECL(22); -MDIO_BUS_STATS_ADDR_ATTR_GROUP_DECL(23); -MDIO_BUS_STATS_ADDR_ATTR_GROUP_DECL(24); -MDIO_BUS_STATS_ADDR_ATTR_GROUP_DECL(25); -MDIO_BUS_STATS_ADDR_ATTR_GROUP_DECL(26); -MDIO_BUS_STATS_ADDR_ATTR_GROUP_DECL(27); -MDIO_BUS_STATS_ADDR_ATTR_GROUP_DECL(28); -MDIO_BUS_STATS_ADDR_ATTR_GROUP_DECL(29); -MDIO_BUS_STATS_ADDR_ATTR_GROUP_DECL(30); -MDIO_BUS_STATS_ADDR_ATTR_GROUP_DECL(31); - -#define MDIO_BUS_STATS_ADDR_ATTR_GROUP(addr) \ - &dev_attr_mdio_bus_addr_transfers_##addr.attr.attr, \ - &dev_attr_mdio_bus_addr_errors_##addr.attr.attr, \ - &dev_attr_mdio_bus_addr_writes_##addr.attr.attr, \ - &dev_attr_mdio_bus_addr_reads_##addr.attr.attr \ - -static const struct attribute *const mdio_bus_statistics_attrs[] = { - &dev_attr_mdio_bus_transfers.attr.attr, - &dev_attr_mdio_bus_errors.attr.attr, - &dev_attr_mdio_bus_writes.attr.attr, - &dev_attr_mdio_bus_reads.attr.attr, - MDIO_BUS_STATS_ADDR_ATTR_GROUP(0), - MDIO_BUS_STATS_ADDR_ATTR_GROUP(1), - MDIO_BUS_STATS_ADDR_ATTR_GROUP(2), - MDIO_BUS_STATS_ADDR_ATTR_GROUP(3), - MDIO_BUS_STATS_ADDR_ATTR_GROUP(4), - MDIO_BUS_STATS_ADDR_ATTR_GROUP(5), - MDIO_BUS_STATS_ADDR_ATTR_GROUP(6), - MDIO_BUS_STATS_ADDR_ATTR_GROUP(7), - MDIO_BUS_STATS_ADDR_ATTR_GROUP(8), - MDIO_BUS_STATS_ADDR_ATTR_GROUP(9), - MDIO_BUS_STATS_ADDR_ATTR_GROUP(10), - MDIO_BUS_STATS_ADDR_ATTR_GROUP(11), - MDIO_BUS_STATS_ADDR_ATTR_GROUP(12), - MDIO_BUS_STATS_ADDR_ATTR_GROUP(13), - MDIO_BUS_STATS_ADDR_ATTR_GROUP(14), - MDIO_BUS_STATS_ADDR_ATTR_GROUP(15), - MDIO_BUS_STATS_ADDR_ATTR_GROUP(16), - MDIO_BUS_STATS_ADDR_ATTR_GROUP(17), - MDIO_BUS_STATS_ADDR_ATTR_GROUP(18), - MDIO_BUS_STATS_ADDR_ATTR_GROUP(19), - MDIO_BUS_STATS_ADDR_ATTR_GROUP(20), - MDIO_BUS_STATS_ADDR_ATTR_GROUP(21), - MDIO_BUS_STATS_ADDR_ATTR_GROUP(22), - MDIO_BUS_STATS_ADDR_ATTR_GROUP(23), - MDIO_BUS_STATS_ADDR_ATTR_GROUP(24), - MDIO_BUS_STATS_ADDR_ATTR_GROUP(25), - MDIO_BUS_STATS_ADDR_ATTR_GROUP(26), - MDIO_BUS_STATS_ADDR_ATTR_GROUP(27), - MDIO_BUS_STATS_ADDR_ATTR_GROUP(28), - MDIO_BUS_STATS_ADDR_ATTR_GROUP(29), - MDIO_BUS_STATS_ADDR_ATTR_GROUP(30), - MDIO_BUS_STATS_ADDR_ATTR_GROUP(31), - NULL, -}; - -static const struct attribute_group mdio_bus_statistics_group = { - .name = "statistics", - .attrs_const = mdio_bus_statistics_attrs, -}; -__ATTRIBUTE_GROUPS(mdio_bus_statistics); - -const struct class mdio_bus_class = { - .name = "mdio_bus", - .dev_release = mdiobus_release, - .dev_groups = mdio_bus_statistics_groups, -}; -EXPORT_SYMBOL_GPL(mdio_bus_class); - static void mdiobus_stats_acct(struct mdio_bus_stats *stats, bool op, int ret) { preempt_disable(); @@ -841,69 +623,5 @@ int mdiobus_c45_modify_changed(struct mii_bus *bus, int addr, int devad, } EXPORT_SYMBOL_GPL(mdiobus_c45_modify_changed); -/** - * mdio_bus_match - determine if given MDIO driver supports the given - * MDIO device - * @dev: target MDIO device - * @drv: given MDIO driver - * - * Return: 1 if the driver supports the device, 0 otherwise - * - * Description: This may require calling the devices own match function, - * since different classes of MDIO devices have different match criteria. - */ -static int mdio_bus_match(struct device *dev, const struct device_driver *drv) -{ - const struct mdio_driver *mdiodrv = to_mdio_driver(drv); - struct mdio_device *mdio = to_mdio_device(dev); - - /* Both the driver and device must type-match */ - if (!(mdiodrv->mdiodrv.flags & MDIO_DEVICE_IS_PHY) != - !(mdio->flags & MDIO_DEVICE_FLAG_PHY)) - return 0; - - if (of_driver_match_device(dev, drv)) - return 1; - - if (mdio->bus_match) - return mdio->bus_match(dev, drv); - - return 0; -} - -static int mdio_uevent(const struct device *dev, struct kobj_uevent_env *env) -{ - int rc; - - /* Some devices have extra OF data and an OF-style MODALIAS */ - rc = of_device_uevent_modalias(dev, env); - if (rc != -ENODEV) - return rc; - - return 0; -} - -static const struct attribute *const mdio_bus_device_statistics_attrs[] = { - &dev_attr_mdio_bus_device_transfers.attr.attr, - &dev_attr_mdio_bus_device_errors.attr.attr, - &dev_attr_mdio_bus_device_writes.attr.attr, - &dev_attr_mdio_bus_device_reads.attr.attr, - NULL, -}; - -static const struct attribute_group mdio_bus_device_statistics_group = { - .name = "statistics", - .attrs_const = mdio_bus_device_statistics_attrs, -}; -__ATTRIBUTE_GROUPS(mdio_bus_device_statistics); - -const struct bus_type mdio_bus_type = { - .name = "mdio_bus", - .dev_groups = mdio_bus_device_statistics_groups, - .match = mdio_bus_match, - .uevent = mdio_uevent, -}; -EXPORT_SYMBOL(mdio_bus_type); - MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("MDIO bus/device layer"); diff --git a/drivers/net/phy/mdio_bus_provider.c b/drivers/net/phy/mdio_bus_provider.c index d50fe6eb4b0..bc0f10ba150 100644 --- a/drivers/net/phy/mdio_bus_provider.c +++ b/drivers/net/phy/mdio_bus_provider.c @@ -28,6 +28,281 @@ #include <linux/string.h> #include <linux/uaccess.h> #include <linux/unistd.h> +#include "phylib-internal.h" + +/** + * mdiobus_release - mii_bus device release callback + * @d: the target struct device that contains the mii_bus + * + * Description: called when the last reference to an mii_bus is + * dropped, to free the underlying memory. + */ +static void mdiobus_release(struct device *d) +{ + struct mii_bus *bus = to_mii_bus(d); + + WARN(bus->state != MDIOBUS_RELEASED && + /* for compatibility with error handling in drivers */ + bus->state != MDIOBUS_ALLOCATED, + "%s: not in RELEASED or ALLOCATED state\n", + bus->id); + + if (bus->state == MDIOBUS_RELEASED) + fwnode_handle_put(dev_fwnode(d)); + + kfree(bus); +} + +struct mdio_bus_stat_attr { + struct device_attribute attr; + int address; + unsigned int field_offset; +}; + +static struct mdio_bus_stat_attr *to_sattr(struct device_attribute *attr) +{ + return container_of(attr, struct mdio_bus_stat_attr, attr); +} + +static u64 mdio_bus_get_stat(struct mdio_bus_stats *s, unsigned int offset) +{ + const u64_stats_t *stats = (const void *)s + offset; + unsigned int start; + u64 val = 0; + + do { + start = u64_stats_fetch_begin(&s->syncp); + val = u64_stats_read(stats); + } while (u64_stats_fetch_retry(&s->syncp, start)); + + return val; +} + +static ssize_t mdio_bus_stat_field_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct mdio_bus_stat_attr *sattr = to_sattr(attr); + struct mii_bus *bus = to_mii_bus(dev); + u64 val = 0; + + if (sattr->address < 0) { + /* get global stats */ + for (int i = 0; i < PHY_MAX_ADDR; i++) + val += mdio_bus_get_stat(&bus->stats[i], + sattr->field_offset); + } else { + val = mdio_bus_get_stat(&bus->stats[sattr->address], + sattr->field_offset); + } + + return sysfs_emit(buf, "%llu\n", val); +} + +static ssize_t mdio_bus_device_stat_field_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct mdio_bus_stat_attr *sattr = to_sattr(attr); + struct mdio_device *mdiodev = to_mdio_device(dev); + struct mii_bus *bus = mdiodev->bus; + int addr = mdiodev->addr; + u64 val; + + val = mdio_bus_get_stat(&bus->stats[addr], sattr->field_offset); + + return sysfs_emit(buf, "%llu\n", val); +} + +#define MDIO_BUS_STATS_ATTR(field) \ +static const struct mdio_bus_stat_attr dev_attr_mdio_bus_##field = { \ + .attr = __ATTR(field, 0444, mdio_bus_stat_field_show, NULL), \ + .address = -1, \ + .field_offset = offsetof(struct mdio_bus_stats, field), \ +}; \ +static const struct mdio_bus_stat_attr dev_attr_mdio_bus_device_##field = { \ + .attr = __ATTR(field, 0444, mdio_bus_device_stat_field_show, NULL), \ + .field_offset = offsetof(struct mdio_bus_stats, field), \ +} + +MDIO_BUS_STATS_ATTR(transfers); +MDIO_BUS_STATS_ATTR(errors); +MDIO_BUS_STATS_ATTR(writes); +MDIO_BUS_STATS_ATTR(reads); + +#define MDIO_BUS_STATS_ADDR_ATTR_DECL(field, addr, file) \ +static const struct mdio_bus_stat_attr \ +dev_attr_mdio_bus_addr_##field##_##addr = { \ + .attr = { .attr = { .name = file, .mode = 0444 }, \ + .show = mdio_bus_stat_field_show, \ + }, \ + .address = addr, \ + .field_offset = offsetof(struct mdio_bus_stats, field), \ +} + +#define MDIO_BUS_STATS_ADDR_ATTR(field, addr) \ + MDIO_BUS_STATS_ADDR_ATTR_DECL(field, addr, \ + __stringify(field) "_" __stringify(addr)) + +#define MDIO_BUS_STATS_ADDR_ATTR_GROUP_DECL(addr) \ + MDIO_BUS_STATS_ADDR_ATTR(transfers, addr); \ + MDIO_BUS_STATS_ADDR_ATTR(errors, addr); \ + MDIO_BUS_STATS_ADDR_ATTR(writes, addr); \ + MDIO_BUS_STATS_ADDR_ATTR(reads, addr) \ + +MDIO_BUS_STATS_ADDR_ATTR_GROUP_DECL(0); +MDIO_BUS_STATS_ADDR_ATTR_GROUP_DECL(1); +MDIO_BUS_STATS_ADDR_ATTR_GROUP_DECL(2); +MDIO_BUS_STATS_ADDR_ATTR_GROUP_DECL(3); +MDIO_BUS_STATS_ADDR_ATTR_GROUP_DECL(4); +MDIO_BUS_STATS_ADDR_ATTR_GROUP_DECL(5); +MDIO_BUS_STATS_ADDR_ATTR_GROUP_DECL(6); +MDIO_BUS_STATS_ADDR_ATTR_GROUP_DECL(7); +MDIO_BUS_STATS_ADDR_ATTR_GROUP_DECL(8); +MDIO_BUS_STATS_ADDR_ATTR_GROUP_DECL(9); +MDIO_BUS_STATS_ADDR_ATTR_GROUP_DECL(10); +MDIO_BUS_STATS_ADDR_ATTR_GROUP_DECL(11); +MDIO_BUS_STATS_ADDR_ATTR_GROUP_DECL(12); +MDIO_BUS_STATS_ADDR_ATTR_GROUP_DECL(13); +MDIO_BUS_STATS_ADDR_ATTR_GROUP_DECL(14); +MDIO_BUS_STATS_ADDR_ATTR_GROUP_DECL(15); +MDIO_BUS_STATS_ADDR_ATTR_GROUP_DECL(16); +MDIO_BUS_STATS_ADDR_ATTR_GROUP_DECL(17); +MDIO_BUS_STATS_ADDR_ATTR_GROUP_DECL(18); +MDIO_BUS_STATS_ADDR_ATTR_GROUP_DECL(19); +MDIO_BUS_STATS_ADDR_ATTR_GROUP_DECL(20); +MDIO_BUS_STATS_ADDR_ATTR_GROUP_DECL(21); +MDIO_BUS_STATS_ADDR_ATTR_GROUP_DECL(22); +MDIO_BUS_STATS_ADDR_ATTR_GROUP_DECL(23); +MDIO_BUS_STATS_ADDR_ATTR_GROUP_DECL(24); +MDIO_BUS_STATS_ADDR_ATTR_GROUP_DECL(25); +MDIO_BUS_STATS_ADDR_ATTR_GROUP_DECL(26); +MDIO_BUS_STATS_ADDR_ATTR_GROUP_DECL(27); +MDIO_BUS_STATS_ADDR_ATTR_GROUP_DECL(28); +MDIO_BUS_STATS_ADDR_ATTR_GROUP_DECL(29); +MDIO_BUS_STATS_ADDR_ATTR_GROUP_DECL(30); +MDIO_BUS_STATS_ADDR_ATTR_GROUP_DECL(31); + +#define MDIO_BUS_STATS_ADDR_ATTR_GROUP(addr) \ + &dev_attr_mdio_bus_addr_transfers_##addr.attr.attr, \ + &dev_attr_mdio_bus_addr_errors_##addr.attr.attr, \ + &dev_attr_mdio_bus_addr_writes_##addr.attr.attr, \ + &dev_attr_mdio_bus_addr_reads_##addr.attr.attr \ + +static const struct attribute *const mdio_bus_statistics_attrs[] = { + &dev_attr_mdio_bus_transfers.attr.attr, + &dev_attr_mdio_bus_errors.attr.attr, + &dev_attr_mdio_bus_writes.attr.attr, + &dev_attr_mdio_bus_reads.attr.attr, + MDIO_BUS_STATS_ADDR_ATTR_GROUP(0), + MDIO_BUS_STATS_ADDR_ATTR_GROUP(1), + MDIO_BUS_STATS_ADDR_ATTR_GROUP(2), + MDIO_BUS_STATS_ADDR_ATTR_GROUP(3), + MDIO_BUS_STATS_ADDR_ATTR_GROUP(4), + MDIO_BUS_STATS_ADDR_ATTR_GROUP(5), + MDIO_BUS_STATS_ADDR_ATTR_GROUP(6), + MDIO_BUS_STATS_ADDR_ATTR_GROUP(7), + MDIO_BUS_STATS_ADDR_ATTR_GROUP(8), + MDIO_BUS_STATS_ADDR_ATTR_GROUP(9), + MDIO_BUS_STATS_ADDR_ATTR_GROUP(10), + MDIO_BUS_STATS_ADDR_ATTR_GROUP(11), + MDIO_BUS_STATS_ADDR_ATTR_GROUP(12), + MDIO_BUS_STATS_ADDR_ATTR_GROUP(13), + MDIO_BUS_STATS_ADDR_ATTR_GROUP(14), + MDIO_BUS_STATS_ADDR_ATTR_GROUP(15), + MDIO_BUS_STATS_ADDR_ATTR_GROUP(16), + MDIO_BUS_STATS_ADDR_ATTR_GROUP(17), + MDIO_BUS_STATS_ADDR_ATTR_GROUP(18), + MDIO_BUS_STATS_ADDR_ATTR_GROUP(19), + MDIO_BUS_STATS_ADDR_ATTR_GROUP(20), + MDIO_BUS_STATS_ADDR_ATTR_GROUP(21), + MDIO_BUS_STATS_ADDR_ATTR_GROUP(22), + MDIO_BUS_STATS_ADDR_ATTR_GROUP(23), + MDIO_BUS_STATS_ADDR_ATTR_GROUP(24), + MDIO_BUS_STATS_ADDR_ATTR_GROUP(25), + MDIO_BUS_STATS_ADDR_ATTR_GROUP(26), + MDIO_BUS_STATS_ADDR_ATTR_GROUP(27), + MDIO_BUS_STATS_ADDR_ATTR_GROUP(28), + MDIO_BUS_STATS_ADDR_ATTR_GROUP(29), + MDIO_BUS_STATS_ADDR_ATTR_GROUP(30), + MDIO_BUS_STATS_ADDR_ATTR_GROUP(31), + NULL, +}; + +static const struct attribute_group mdio_bus_statistics_group = { + .name = "statistics", + .attrs_const = mdio_bus_statistics_attrs, +}; +__ATTRIBUTE_GROUPS(mdio_bus_statistics); + +const struct class mdio_bus_class = { + .name = "mdio_bus", + .dev_release = mdiobus_release, + .dev_groups = mdio_bus_statistics_groups, +}; + +/** + * mdio_bus_match - determine if given MDIO driver supports the given + * MDIO device + * @dev: target MDIO device + * @drv: given MDIO driver + * + * Return: 1 if the driver supports the device, 0 otherwise + * + * Description: This may require calling the devices own match function, + * since different classes of MDIO devices have different match criteria. + */ +static int mdio_bus_match(struct device *dev, const struct device_driver *drv) +{ + const struct mdio_driver *mdiodrv = to_mdio_driver(drv); + struct mdio_device *mdio = to_mdio_device(dev); + + /* Both the driver and device must type-match */ + if (!(mdiodrv->mdiodrv.flags & MDIO_DEVICE_IS_PHY) != + !(mdio->flags & MDIO_DEVICE_FLAG_PHY)) + return 0; + + if (of_driver_match_device(dev, drv)) + return 1; + + if (mdio->bus_match) + return mdio->bus_match(dev, drv); + + return 0; +} + +static int mdio_uevent(const struct device *dev, struct kobj_uevent_env *env) +{ + int rc; + + /* Some devices have extra OF data and an OF-style MODALIAS */ + rc = of_device_uevent_modalias(dev, env); + if (rc != -ENODEV) + return rc; + + return 0; +} + +static const struct attribute *const mdio_bus_device_statistics_attrs[] = { + &dev_attr_mdio_bus_device_transfers.attr.attr, + &dev_attr_mdio_bus_device_errors.attr.attr, + &dev_attr_mdio_bus_device_writes.attr.attr, + &dev_attr_mdio_bus_device_reads.attr.attr, + NULL, +}; + +static const struct attribute_group mdio_bus_device_statistics_group = { + .name = "statistics", + .attrs_const = mdio_bus_device_statistics_attrs, +}; +__ATTRIBUTE_GROUPS(mdio_bus_device_statistics); + +const struct bus_type mdio_bus_type = { + .name = "mdio_bus", + .dev_groups = mdio_bus_device_statistics_groups, + .match = mdio_bus_match, + .uevent = mdio_uevent, +}; /** * mdiobus_alloc_size - allocate a mii_bus structure diff --git a/drivers/net/phy/phylib-internal.h b/drivers/net/phy/phylib-internal.h index bfb1aa82386..664ed7faa51 100644 --- a/drivers/net/phy/phylib-internal.h +++ b/drivers/net/phy/phylib-internal.h @@ -9,6 +9,9 @@ struct mdio_device; struct phy_device; +extern const struct bus_type mdio_bus_type; +extern const struct class mdio_bus_class; + /* * phy_supported_speeds - return all speeds currently supported by a PHY device */ diff --git a/include/linux/phy.h b/include/linux/phy.h index e9b0d7427b0..5de4b172cd0 100644 --- a/include/linux/phy.h +++ b/include/linux/phy.h @@ -2446,9 +2446,6 @@ int __phy_hwtstamp_set(struct phy_device *phydev, struct phy_port *phy_get_sfp_port(struct phy_device *phydev); -extern const struct bus_type mdio_bus_type; -extern const struct class mdio_bus_class; - /** * phy_module_driver() - Helper macro for registering PHY drivers * @__phy_drivers: array of PHY drivers to register -- 2.53.0 ^ permalink raw reply related [flat|nested] 7+ messages in thread
end of thread, other threads:[~2026-03-08 13:15 UTC | newest] Thread overview: 7+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2026-03-07 21:30 [PATCH net-next 0/5] net: phy: further decouple provider from consumer part Heiner Kallweit 2026-03-07 21:31 ` [PATCH net-next 1/5] net: phy: move mdio_device reset handling functions in the code Heiner Kallweit 2026-03-07 21:32 ` [PATCH net-next 2/5] net: phy: make mdio_device.c part of libphy Heiner Kallweit 2026-03-08 13:15 ` kernel test robot 2026-03-07 21:32 ` [PATCH net-next 3/5] net: phy: move (of_)mdio_find_bus to mdio_bus_provider.c Heiner Kallweit 2026-03-07 21:33 ` [PATCH net-next 4/5] net: phy: move registering mdio_bus_class and mdio_bus_type to libphy Heiner Kallweit 2026-03-07 21:34 ` [PATCH net-next 5/5] net: phy: move remaining provider code to mdio_bus_provider.c Heiner Kallweit
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox