diff options
Diffstat (limited to 'drivers/net/phy/mdio_bus.c')
-rw-r--r-- | drivers/net/phy/mdio_bus.c | 127 |
1 files changed, 35 insertions, 92 deletions
diff --git a/drivers/net/phy/mdio_bus.c b/drivers/net/phy/mdio_bus.c index 6ceee82b2839..0af20faad69d 100644 --- a/drivers/net/phy/mdio_bus.c +++ b/drivers/net/phy/mdio_bus.c @@ -8,32 +8,32 @@ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt -#include <linux/kernel.h> -#include <linux/string.h> -#include <linux/errno.h> -#include <linux/unistd.h> -#include <linux/slab.h> -#include <linux/interrupt.h> -#include <linux/init.h> #include <linux/delay.h> #include <linux/device.h> +#include <linux/errno.h> +#include <linux/etherdevice.h> +#include <linux/ethtool.h> #include <linux/gpio.h> #include <linux/gpio/consumer.h> +#include <linux/init.h> +#include <linux/interrupt.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/of_gpio.h> -#include <linux/netdevice.h> -#include <linux/etherdevice.h> +#include <linux/of_mdio.h> +#include <linux/phy.h> #include <linux/reset.h> #include <linux/skbuff.h> +#include <linux/slab.h> #include <linux/spinlock.h> -#include <linux/mm.h> -#include <linux/module.h> -#include <linux/mii.h> -#include <linux/ethtool.h> -#include <linux/phy.h> -#include <linux/io.h> +#include <linux/string.h> #include <linux/uaccess.h> +#include <linux/unistd.h> #define CREATE_TRACE_POINTS #include <trace/events/mdio.h> @@ -165,79 +165,6 @@ struct mii_bus *mdiobus_alloc_size(size_t size) } EXPORT_SYMBOL(mdiobus_alloc_size); -static void _devm_mdiobus_free(struct device *dev, void *res) -{ - struct mii_bus *bus = *(struct mii_bus **)res; - - if (bus->is_managed_registered && bus->state == MDIOBUS_REGISTERED) - mdiobus_unregister(bus); - - mdiobus_free(bus); -} - -static int devm_mdiobus_match(struct device *dev, void *res, void *data) -{ - struct mii_bus **r = res; - - if (WARN_ON(!r || !*r)) - return 0; - - return *r == data; -} - -/** - * devm_mdiobus_alloc_size - Resource-managed mdiobus_alloc_size() - * @dev: Device to allocate mii_bus for - * @sizeof_priv: Space to allocate for private structure. - * - * Managed mdiobus_alloc_size. mii_bus allocated with this function is - * automatically freed on driver detach. - * - * If an mii_bus allocated with this function needs to be freed separately, - * devm_mdiobus_free() must be used. - * - * RETURNS: - * Pointer to allocated mii_bus on success, NULL on failure. - */ -struct mii_bus *devm_mdiobus_alloc_size(struct device *dev, int sizeof_priv) -{ - struct mii_bus **ptr, *bus; - - ptr = devres_alloc(_devm_mdiobus_free, sizeof(*ptr), GFP_KERNEL); - if (!ptr) - return NULL; - - /* use raw alloc_dr for kmalloc caller tracing */ - bus = mdiobus_alloc_size(sizeof_priv); - if (bus) { - *ptr = bus; - devres_add(dev, ptr); - bus->is_managed = 1; - } else { - devres_free(ptr); - } - - return bus; -} -EXPORT_SYMBOL_GPL(devm_mdiobus_alloc_size); - -/** - * devm_mdiobus_free - Resource-managed mdiobus_free() - * @dev: Device this mii_bus belongs to - * @bus: the mii_bus associated with the device - * - * Free mii_bus allocated with devm_mdiobus_alloc_size(). - */ -void devm_mdiobus_free(struct device *dev, struct mii_bus *bus) -{ - int rc; - - rc = devres_release(dev, _devm_mdiobus_free, - devm_mdiobus_match, bus); - WARN_ON(rc); -} -EXPORT_SYMBOL_GPL(devm_mdiobus_free); - /** * mdiobus_release - mii_bus device release callback * @d: the target struct device that contains the mii_bus @@ -627,8 +554,10 @@ int __mdiobus_register(struct mii_bus *bus, struct module *owner) bus->reset_gpiod = gpiod; gpiod_set_value_cansleep(gpiod, 1); - udelay(bus->reset_delay_us); + fsleep(bus->reset_delay_us); gpiod_set_value_cansleep(gpiod, 0); + if (bus->reset_post_delay_us > 0) + fsleep(bus->reset_post_delay_us); } if (bus->reset) { @@ -739,10 +668,24 @@ EXPORT_SYMBOL(mdiobus_free); */ struct phy_device *mdiobus_scan(struct mii_bus *bus, int addr) { - struct phy_device *phydev; + struct phy_device *phydev = ERR_PTR(-ENODEV); int err; - phydev = get_phy_device(bus, addr, false); + switch (bus->probe_capabilities) { + case MDIOBUS_NO_CAP: + case MDIOBUS_C22: + phydev = get_phy_device(bus, addr, false); + break; + case MDIOBUS_C45: + phydev = get_phy_device(bus, addr, true); + break; + case MDIOBUS_C22_C45: + phydev = get_phy_device(bus, addr, false); + if (IS_ERR(phydev)) + phydev = get_phy_device(bus, addr, true); + break; + } + if (IS_ERR(phydev)) return phydev; |