Skip to content

Commit

Permalink
net: arc_emac: support the phy reset for emac driver
Browse files Browse the repository at this point in the history
This patch adds to support the emac phy reset.

Different boards may require different phy reset duration. Add property
phy-reset-duration for emac driver, so that the boards that need
a longer reset duration can specify it in their device tree.

Signed-off-by: Heiko Stuebner <heiko@sntech.de>
Signed-off-by: Caesar Wang <wxt@rock-chips.com>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: netdev@vger.kernel.org
Cc: Alexander Kochetkov <al.kochet@gmail.com>
Cc: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Caesar Wang authored and David S. Miller committed Mar 16, 2016
1 parent 8700eee commit 1bddd96
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 0 deletions.
6 changes: 6 additions & 0 deletions drivers/net/ethernet/arc/emac.h
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,11 @@ struct buffer_state {
DEFINE_DMA_UNMAP_LEN(len);
};

struct arc_emac_mdio_bus_data {
struct gpio_desc *reset_gpio;
int msec;
};

/**
* struct arc_emac_priv - Storage of EMAC's private information.
* @dev: Pointer to the current device.
Expand Down Expand Up @@ -131,6 +136,7 @@ struct arc_emac_priv {
struct device *dev;
struct phy_device *phy_dev;
struct mii_bus *bus;
struct arc_emac_mdio_bus_data bus_data;

void __iomem *regs;
struct clk *clk;
Expand Down
37 changes: 37 additions & 0 deletions drivers/net/ethernet/arc/emac_mdio.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include <linux/delay.h>
#include <linux/of_mdio.h>
#include <linux/platform_device.h>
#include <linux/gpio/consumer.h>

#include "emac.h"

Expand Down Expand Up @@ -98,6 +99,25 @@ static int arc_mdio_write(struct mii_bus *bus, int phy_addr,
return arc_mdio_complete_wait(priv);
}

/**
* arc_mdio_reset
* @bus: points to the mii_bus structure
* Description: reset the MII bus
*/
int arc_mdio_reset(struct mii_bus *bus)
{
struct arc_emac_priv *priv = bus->priv;
struct arc_emac_mdio_bus_data *data = &priv->bus_data;

if (data->reset_gpio) {
gpiod_set_value_cansleep(data->reset_gpio, 1);
msleep(data->msec);
gpiod_set_value_cansleep(data->reset_gpio, 0);
}

return 0;
}

/**
* arc_mdio_probe - MDIO probe function.
* @priv: Pointer to ARC EMAC private data structure.
Expand All @@ -109,6 +129,8 @@ static int arc_mdio_write(struct mii_bus *bus, int phy_addr,
*/
int arc_mdio_probe(struct arc_emac_priv *priv)
{
struct arc_emac_mdio_bus_data *data = &priv->bus_data;
struct device_node *np = priv->dev->of_node;
struct mii_bus *bus;
int error;

Expand All @@ -122,6 +144,21 @@ int arc_mdio_probe(struct arc_emac_priv *priv)
bus->name = "Synopsys MII Bus",
bus->read = &arc_mdio_read;
bus->write = &arc_mdio_write;
bus->reset = &arc_mdio_reset;

/* optional reset-related properties */
data->reset_gpio = devm_gpiod_get_optional(priv->dev, "phy-reset",
GPIOD_OUT_LOW);
if (IS_ERR(data->reset_gpio)) {
error = PTR_ERR(data->reset_gpio);
dev_err(priv->dev, "Failed to request gpio: %d\n", error);
return error;
}

of_property_read_u32(np, "phy-reset-duration", &data->msec);
/* A sane reset duration should not be longer than 1s */
if (data->msec > 1000)
data->msec = 1;

snprintf(bus->id, MII_BUS_ID_SIZE, "%s", bus->name);

Expand Down

0 comments on commit 1bddd96

Please sign in to comment.