diff options
Diffstat (limited to 'drivers/net/phy/mdio_device.c')
| -rw-r--r-- | drivers/net/phy/mdio_device.c | 60 |
1 files changed, 60 insertions, 0 deletions
diff --git a/drivers/net/phy/mdio_device.c b/drivers/net/phy/mdio_device.c index f64176e0e197..6e90ed42cd98 100644 --- a/drivers/net/phy/mdio_device.c +++ b/drivers/net/phy/mdio_device.c @@ -22,6 +22,7 @@ #include <linux/string.h> #include <linux/unistd.h> #include <linux/property.h> +#include "mdio-private.h" void mdio_device_free(struct mdio_device *mdiodev) { @@ -77,6 +78,8 @@ EXPORT_SYMBOL(mdio_device_create); /** * mdio_device_register - Register the mdio device on the MDIO bus * @mdiodev: mdio_device structure to be added to the MDIO bus + * + * Return: Zero if successful, negative error code on failure */ int mdio_device_register(struct mdio_device *mdiodev) { @@ -118,6 +121,59 @@ 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; @@ -152,6 +208,8 @@ EXPORT_SYMBOL(mdio_device_reset); * * Description: Take care of setting up the mdio_device structure * and calling the driver to probe the device. + * + * Return: Zero if successful, negative error code on failure */ static int mdio_probe(struct device *dev) { @@ -202,6 +260,8 @@ static void mdio_shutdown(struct device *dev) /** * mdio_driver_register - register an mdio_driver with the MDIO layer * @drv: new mdio_driver to register + * + * Return: Zero if successful, negative error code on failure */ int mdio_driver_register(struct mdio_driver *drv) { |
