mirror of https://gitee.com/openkylin/linux.git
Merge branch 'net-add-reset-controller-driven-PHY-reset'
David Bauer says: ==================== net: add reset-controller driven PHY reset This patchset adds support for a PHY reset driven by a reset-controller. Currently, only GPIO driven resets are supported by the PHY subsystem. It also renames the reset-gpio from 'reset' to 'reset_gpio' to better differentiate between resets wired to a GPIO and resets wired to a reset-controller driven pin. Some systems have the PHY reset-line wired to a pin controlled by a reset-controller (eg. some Atheros AR9132 based boards). In case the bootloader asserts reset before loading the kernel, we currently do not have a clean way of deasserting reset to probe the PHY. v3: - add missing newline in mdio_bus.c v2: - fixed missed rename of "reset" in at803x.c - move initial reset to mdio_device_reset ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
5c2e6e14a0
|
@ -51,6 +51,10 @@ Optional Properties:
|
|||
to ensure the integrated PHY is used. The absence of this property indicates
|
||||
the muxers should be configured so that the external PHY is used.
|
||||
|
||||
- resets: The reset-controller phandle and specifier for the PHY reset signal.
|
||||
|
||||
- reset-names: Must be "phy" for the PHY reset signal.
|
||||
|
||||
- reset-gpios: The GPIO phandle and specifier for the PHY reset signal.
|
||||
|
||||
- reset-assert-us: Delay after the reset was asserted in microseconds.
|
||||
|
@ -67,6 +71,8 @@ ethernet-phy@0 {
|
|||
interrupts = <35 IRQ_TYPE_EDGE_RISING>;
|
||||
reg = <0>;
|
||||
|
||||
resets = <&rst 8>;
|
||||
reset-names = "phy";
|
||||
reset-gpios = <&gpio1 4 GPIO_ACTIVE_LOW>;
|
||||
reset-assert-us = <1000>;
|
||||
reset-deassert-us = <2000>;
|
||||
|
|
|
@ -331,7 +331,7 @@ static void at803x_link_change_notify(struct phy_device *phydev)
|
|||
* in the FIFO. In such cases, the FIFO enters an error mode it
|
||||
* cannot recover from by software.
|
||||
*/
|
||||
if (phydev->state == PHY_NOLINK && phydev->mdio.reset) {
|
||||
if (phydev->state == PHY_NOLINK && phydev->mdio.reset_gpio) {
|
||||
struct at803x_context context;
|
||||
|
||||
at803x_context_save(phydev, &context);
|
||||
|
|
|
@ -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>
|
||||
|
@ -55,10 +56,25 @@ static int mdiobus_register_gpiod(struct mdio_device *mdiodev)
|
|||
return PTR_ERR(gpiod);
|
||||
}
|
||||
|
||||
mdiodev->reset = gpiod;
|
||||
mdiodev->reset_gpio = 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;
|
||||
|
@ -446,8 +469,8 @@ void mdiobus_unregister(struct mii_bus *bus)
|
|||
if (!mdiodev)
|
||||
continue;
|
||||
|
||||
if (mdiodev->reset)
|
||||
gpiod_put(mdiodev->reset);
|
||||
if (mdiodev->reset_gpio)
|
||||
gpiod_put(mdiodev->reset_gpio);
|
||||
|
||||
mdiodev->device_remove(mdiodev);
|
||||
mdiodev->device_free(mdiodev);
|
||||
|
|
|
@ -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,10 +117,18 @@ void mdio_device_reset(struct mdio_device *mdiodev, int value)
|
|||
{
|
||||
unsigned int d;
|
||||
|
||||
if (!mdiodev->reset)
|
||||
if (!mdiodev->reset_gpio && !mdiodev->reset_ctrl)
|
||||
return;
|
||||
|
||||
gpiod_set_value(mdiodev->reset, value);
|
||||
if (mdiodev->reset_gpio)
|
||||
gpiod_set_value(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)
|
||||
|
|
|
@ -39,7 +39,8 @@ struct mdio_device {
|
|||
/* Bus address of the MDIO device (0-31) */
|
||||
int addr;
|
||||
int flags;
|
||||
struct gpio_desc *reset;
|
||||
struct gpio_desc *reset_gpio;
|
||||
struct reset_control *reset_ctrl;
|
||||
unsigned int reset_assert_delay;
|
||||
unsigned int reset_deassert_delay;
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue