Skip to content

Commit

Permalink
arc-emac: add reset support
Browse files Browse the repository at this point in the history
lets see if that brings something
  • Loading branch information
mmind committed Feb 24, 2016
1 parent 0b5f268 commit a943c58
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 0 deletions.
7 changes: 7 additions & 0 deletions drivers/net/ethernet/arc/emac.h
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,12 @@ struct buffer_state {
DEFINE_DMA_UNMAP_LEN(len);
};

struct arc_emac_mdio_bus_data {
int reset_gpio;
int active_low;
u32 delays[3];
};

/**
* struct arc_emac_priv - Storage of EMAC's private information.
* @dev: Pointer to the current device.
Expand Down Expand Up @@ -131,6 +137,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
51 changes: 51 additions & 0 deletions drivers/net/ethernet/arc/emac_mdio.c
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,37 @@ 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;

printk("%s\n", __func__);
if (data->reset_gpio < 0)
return 0;

printk("%s setting 1\n", __func__);
gpio_direction_output(data->reset_gpio,
data->active_low ? 1 : 0);
if (data->delays[0])
msleep(DIV_ROUND_UP(data->delays[0], 1000));

gpio_set_value(data->reset_gpio, data->active_low ? 0 : 1);
if (data->delays[1])
msleep(DIV_ROUND_UP(data->delays[1], 1000));

gpio_set_value(data->reset_gpio, data->active_low ? 1 : 0);
if (data->delays[2])
msleep(DIV_ROUND_UP(data->delays[2], 1000));

return 0;
}

/**
* arc_mdio_probe - MDIO probe function.
* @priv: Pointer to ARC EMAC private data structure.
Expand All @@ -109,6 +140,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,12 +155,26 @@ 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 = of_get_named_gpio(np, "snps,reset-gpio", 0);
data->active_low = of_property_read_bool(np, "snps,reset-active-low");
of_property_read_u32_array(np, "snps,reset-delays-us", data->delays, 3);

if (data->reset_gpio >= 0) {
error = gpio_request(data->reset_gpio, "mdio-reset");
if (error < 0)
return error;
}

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

error = of_mdiobus_register(bus, priv->dev->of_node);
if (error) {
dev_err(priv->dev, "cannot register MDIO bus %s\n", bus->name);
if (data->reset_gpio >= 0)
gpio_free(data->reset_gpio);
mdiobus_free(bus);
return error;
}
Expand All @@ -143,7 +190,11 @@ int arc_mdio_probe(struct arc_emac_priv *priv)
*/
int arc_mdio_remove(struct arc_emac_priv *priv)
{
struct arc_emac_mdio_bus_data *data = &priv->bus_data;

mdiobus_unregister(priv->bus);
if (data->reset_gpio >= 0)
gpio_free(data->reset_gpio);
mdiobus_free(priv->bus);
priv->bus = NULL;

Expand Down

0 comments on commit a943c58

Please sign in to comment.