Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+25 −2
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@
#include <linux/of_gpio.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/reset.h>
#include <linux/skbuff.h>
#include <linux/spinlock.h>
#include <linux/mm.h>
@@ -57,8 +58,23 @@ static int mdiobus_register_gpiod(struct mdio_device *mdiodev)

	mdiodev->reset = gpiod;

	/* Assert the reset signal again */
	mdio_device_reset(mdiodev, 1);
	return 0;
}

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;
}
@@ -74,6 +90,13 @@ int mdiobus_register_device(struct mdio_device *mdiodev)
		err = mdiobus_register_gpiod(mdiodev);
		if (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;
+11 −2
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@
#include <linux/mii.h>
#include <linux/module.h>
#include <linux/phy.h>
#include <linux/reset.h>
#include <linux/slab.h>
#include <linux/string.h>
#include <linux/unistd.h>
@@ -116,11 +117,19 @@ void mdio_device_reset(struct mdio_device *mdiodev, int value)
{
	unsigned int d;

	if (!mdiodev->reset)
	if (!mdiodev->reset && !mdiodev->reset_ctrl)
		return;

	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;
	if (d)
		usleep_range(d, d + max_t(unsigned int, d / 10, 100));
+1 −0
Original line number Diff line number Diff line
@@ -40,6 +40,7 @@ struct mdio_device {
	int addr;
	int flags;
	struct gpio_desc *reset;
	struct reset_control *reset_ctrl;
	unsigned int reset_assert_delay;
	unsigned int reset_deassert_delay;
};