Commit 71dd6c0d authored by David Bauer's avatar David Bauer Committed by David S. Miller

net: phy: add support for reset-controller

This commit adds support for PHY reset pins handled by a reset controller.
Signed-off-by: default avatarDavid Bauer <mail@david-bauer.net>
Reviewed-by: default avatarAndrew Lunn <andrew@lunn.ch>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent b54dd90c
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
#include <linux/of_gpio.h> #include <linux/of_gpio.h>
#include <linux/netdevice.h> #include <linux/netdevice.h>
#include <linux/etherdevice.h> #include <linux/etherdevice.h>
#include <linux/reset.h>
#include <linux/skbuff.h> #include <linux/skbuff.h>
#include <linux/spinlock.h> #include <linux/spinlock.h>
#include <linux/mm.h> #include <linux/mm.h>
...@@ -57,8 +58,23 @@ static int mdiobus_register_gpiod(struct mdio_device *mdiodev) ...@@ -57,8 +58,23 @@ static int mdiobus_register_gpiod(struct mdio_device *mdiodev)
mdiodev->reset = gpiod; mdiodev->reset = gpiod;
/* Assert the reset signal again */ return 0;
mdio_device_reset(mdiodev, 1); }
static int mdiobus_register_reset(struct mdio_device *mdiodev)
{
struct reset_control *reset = NULL;
if (mdiodev->dev.of_node)
reset = devm_reset_control_get_exclusive(&mdiodev->dev,
"phy");
if (PTR_ERR(reset) == -ENOENT ||
PTR_ERR(reset) == -ENOTSUPP)
reset = NULL;
else if (IS_ERR(reset))
return PTR_ERR(reset);
mdiodev->reset_ctrl = reset;
return 0; return 0;
} }
...@@ -74,6 +90,13 @@ int mdiobus_register_device(struct mdio_device *mdiodev) ...@@ -74,6 +90,13 @@ int mdiobus_register_device(struct mdio_device *mdiodev)
err = mdiobus_register_gpiod(mdiodev); err = mdiobus_register_gpiod(mdiodev);
if (err) if (err)
return err; return err;
err = mdiobus_register_reset(mdiodev);
if (err)
return err;
/* Assert the reset signal */
mdio_device_reset(mdiodev, 1);
} }
mdiodev->bus->mdio_map[mdiodev->addr] = mdiodev; mdiodev->bus->mdio_map[mdiodev->addr] = mdiodev;
......
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
#include <linux/mii.h> #include <linux/mii.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/phy.h> #include <linux/phy.h>
#include <linux/reset.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/string.h> #include <linux/string.h>
#include <linux/unistd.h> #include <linux/unistd.h>
...@@ -116,10 +117,18 @@ void mdio_device_reset(struct mdio_device *mdiodev, int value) ...@@ -116,10 +117,18 @@ void mdio_device_reset(struct mdio_device *mdiodev, int value)
{ {
unsigned int d; unsigned int d;
if (!mdiodev->reset) if (!mdiodev->reset && !mdiodev->reset_ctrl)
return; return;
gpiod_set_value(mdiodev->reset, value); if (mdiodev->reset)
gpiod_set_value(mdiodev->reset, 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; d = value ? mdiodev->reset_assert_delay : mdiodev->reset_deassert_delay;
if (d) if (d)
......
...@@ -40,6 +40,7 @@ struct mdio_device { ...@@ -40,6 +40,7 @@ struct mdio_device {
int addr; int addr;
int flags; int flags;
struct gpio_desc *reset; struct gpio_desc *reset;
struct reset_control *reset_ctrl;
unsigned int reset_assert_delay; unsigned int reset_assert_delay;
unsigned int reset_deassert_delay; unsigned int reset_deassert_delay;
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment