aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/arc
diff options
context:
space:
mode:
authorCaesar Wang <wxt@rock-chips.com>2016-03-14 04:01:54 -0400
committerDavid S. Miller <davem@davemloft.net>2016-03-16 19:28:01 -0400
commit1bddd96cba03da0a14b3e5144e98c9a6ff17e983 (patch)
treebdd4e8de5e6d5afc74f49ae86c404e2bd73b79e7 /drivers/net/ethernet/arc
parent8700eee6271c932b2747a6b157655f546c27e7ad (diff)
net: arc_emac: support the phy reset for emac driver
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>
Diffstat (limited to 'drivers/net/ethernet/arc')
-rw-r--r--drivers/net/ethernet/arc/emac.h6
-rw-r--r--drivers/net/ethernet/arc/emac_mdio.c37
2 files changed, 43 insertions, 0 deletions
diff --git a/drivers/net/ethernet/arc/emac.h b/drivers/net/ethernet/arc/emac.h
index dae1ac300a49..1a4040397a4b 100644
--- a/drivers/net/ethernet/arc/emac.h
+++ b/drivers/net/ethernet/arc/emac.h
@@ -102,6 +102,11 @@ struct buffer_state {
102 DEFINE_DMA_UNMAP_LEN(len); 102 DEFINE_DMA_UNMAP_LEN(len);
103}; 103};
104 104
105struct arc_emac_mdio_bus_data {
106 struct gpio_desc *reset_gpio;
107 int msec;
108};
109
105/** 110/**
106 * struct arc_emac_priv - Storage of EMAC's private information. 111 * struct arc_emac_priv - Storage of EMAC's private information.
107 * @dev: Pointer to the current device. 112 * @dev: Pointer to the current device.
@@ -131,6 +136,7 @@ struct arc_emac_priv {
131 struct device *dev; 136 struct device *dev;
132 struct phy_device *phy_dev; 137 struct phy_device *phy_dev;
133 struct mii_bus *bus; 138 struct mii_bus *bus;
139 struct arc_emac_mdio_bus_data bus_data;
134 140
135 void __iomem *regs; 141 void __iomem *regs;
136 struct clk *clk; 142 struct clk *clk;
diff --git a/drivers/net/ethernet/arc/emac_mdio.c b/drivers/net/ethernet/arc/emac_mdio.c
index d5ee986936da..caf704264eba 100644
--- a/drivers/net/ethernet/arc/emac_mdio.c
+++ b/drivers/net/ethernet/arc/emac_mdio.c
@@ -7,6 +7,7 @@
7#include <linux/delay.h> 7#include <linux/delay.h>
8#include <linux/of_mdio.h> 8#include <linux/of_mdio.h>
9#include <linux/platform_device.h> 9#include <linux/platform_device.h>
10#include <linux/gpio/consumer.h>
10 11
11#include "emac.h" 12#include "emac.h"
12 13
@@ -99,6 +100,25 @@ static int arc_mdio_write(struct mii_bus *bus, int phy_addr,
99} 100}
100 101
101/** 102/**
103 * arc_mdio_reset
104 * @bus: points to the mii_bus structure
105 * Description: reset the MII bus
106 */
107int arc_mdio_reset(struct mii_bus *bus)
108{
109 struct arc_emac_priv *priv = bus->priv;
110 struct arc_emac_mdio_bus_data *data = &priv->bus_data;
111
112 if (data->reset_gpio) {
113 gpiod_set_value_cansleep(data->reset_gpio, 1);
114 msleep(data->msec);
115 gpiod_set_value_cansleep(data->reset_gpio, 0);
116 }
117
118 return 0;
119}
120
121/**
102 * arc_mdio_probe - MDIO probe function. 122 * arc_mdio_probe - MDIO probe function.
103 * @priv: Pointer to ARC EMAC private data structure. 123 * @priv: Pointer to ARC EMAC private data structure.
104 * 124 *
@@ -109,6 +129,8 @@ static int arc_mdio_write(struct mii_bus *bus, int phy_addr,
109 */ 129 */
110int arc_mdio_probe(struct arc_emac_priv *priv) 130int arc_mdio_probe(struct arc_emac_priv *priv)
111{ 131{
132 struct arc_emac_mdio_bus_data *data = &priv->bus_data;
133 struct device_node *np = priv->dev->of_node;
112 struct mii_bus *bus; 134 struct mii_bus *bus;
113 int error; 135 int error;
114 136
@@ -122,6 +144,21 @@ int arc_mdio_probe(struct arc_emac_priv *priv)
122 bus->name = "Synopsys MII Bus", 144 bus->name = "Synopsys MII Bus",
123 bus->read = &arc_mdio_read; 145 bus->read = &arc_mdio_read;
124 bus->write = &arc_mdio_write; 146 bus->write = &arc_mdio_write;
147 bus->reset = &arc_mdio_reset;
148
149 /* optional reset-related properties */
150 data->reset_gpio = devm_gpiod_get_optional(priv->dev, "phy-reset",
151 GPIOD_OUT_LOW);
152 if (IS_ERR(data->reset_gpio)) {
153 error = PTR_ERR(data->reset_gpio);
154 dev_err(priv->dev, "Failed to request gpio: %d\n", error);
155 return error;
156 }
157
158 of_property_read_u32(np, "phy-reset-duration", &data->msec);
159 /* A sane reset duration should not be longer than 1s */
160 if (data->msec > 1000)
161 data->msec = 1;
125 162
126 snprintf(bus->id, MII_BUS_ID_SIZE, "%s", bus->name); 163 snprintf(bus->id, MII_BUS_ID_SIZE, "%s", bus->name);
127 164