Skip to content

Commit

Permalink
stmmac: add clk management support
Browse files Browse the repository at this point in the history
this patch adds the way to enable/disable the MAC
clock when call the open/close and resume/restore
functions.
This has been tested on ST platforms and SPEAr; thanks
to Francesco and Deepak.

Signed-off-by: Deepak Sikri <deepak.sikri@st.com>
Tested-by: Francesco Virlinzi <francesco.virlinzi@st.com>
Signed-off-by: Giuseppe Cavallaro <peppe.cavallaro@st.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Giuseppe CAVALLARO authored and David S. Miller committed Apr 4, 2012
1 parent 39b401d commit ba1377f
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 5 deletions.
43 changes: 43 additions & 0 deletions drivers/net/ethernet/stmicro/stmmac/stmmac.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@

#define STMMAC_RESOURCE_NAME "stmmaceth"
#define DRV_MODULE_VERSION "Feb_2012"

#include <linux/clk.h>
#include <linux/stmmac.h>
#include <linux/phy.h>
#include "common.h"
Expand Down Expand Up @@ -79,6 +81,9 @@ struct stmmac_priv {
struct stmmac_counters mmc;
struct dma_features dma_cap;
int hw_cap_support;
#ifdef CONFIG_HAVE_CLK
struct clk *stmmac_clk;
#endif
};

extern int phyaddr;
Expand All @@ -97,3 +102,41 @@ int stmmac_dvr_remove(struct net_device *ndev);
struct stmmac_priv *stmmac_dvr_probe(struct device *device,
struct plat_stmmacenet_data *plat_dat,
void __iomem *addr);

#ifdef CONFIG_HAVE_CLK
static inline int stmmac_clk_enable(struct stmmac_priv *priv)
{
if (priv->stmmac_clk)
return clk_enable(priv->stmmac_clk);

return 0;
}

static inline void stmmac_clk_disable(struct stmmac_priv *priv)
{
if (priv->stmmac_clk)
clk_disable(priv->stmmac_clk);
}
static inline int stmmac_clk_get(struct stmmac_priv *priv)
{
priv->stmmac_clk = clk_get(priv->device, NULL);

if (IS_ERR(priv->stmmac_clk)) {
pr_err("%s: ERROR clk_get failed\n", __func__);
return PTR_ERR(priv->stmmac_clk);
}
return 0;
}
#else
static inline int stmmac_clk_enable(struct stmmac_priv *priv)
{
return 0;
}
static inline void stmmac_clk_disable(struct stmmac_priv *priv)
{
}
static inline int stmmac_clk_get(struct stmmac_priv *priv)
{
return 0;
}
#endif /* CONFIG_HAVE_CLK */
25 changes: 20 additions & 5 deletions drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -904,20 +904,24 @@ static int stmmac_open(struct net_device *dev)
struct stmmac_priv *priv = netdev_priv(dev);
int ret;

stmmac_clk_enable(priv);

stmmac_check_ether_addr(priv);

/* MDIO bus Registration */
ret = stmmac_mdio_register(dev);
if (ret < 0) {
pr_debug("%s: MDIO bus (id: %d) registration failed",
__func__, priv->plat->bus_id);
return ret;
goto open_clk_dis;
}

#ifdef CONFIG_STMMAC_TIMER
priv->tm = kzalloc(sizeof(struct stmmac_timer *), GFP_KERNEL);
if (unlikely(priv->tm == NULL))
return -ENOMEM;
if (unlikely(priv->tm == NULL)) {
ret = -ENOMEM;
goto open_clk_dis;
}

priv->tm->freq = tmrate;

Expand Down Expand Up @@ -1034,6 +1038,8 @@ static int stmmac_open(struct net_device *dev)
if (priv->phydev)
phy_disconnect(priv->phydev);

open_clk_dis:
stmmac_clk_disable(priv);
return ret;
}

Expand Down Expand Up @@ -1086,6 +1092,7 @@ static int stmmac_release(struct net_device *dev)
stmmac_exit_fs();
#endif
stmmac_mdio_unregister(dev);
stmmac_clk_disable(priv);

return 0;
}
Expand Down Expand Up @@ -1880,6 +1887,9 @@ struct stmmac_priv *stmmac_dvr_probe(struct device *device,
goto error;
}

if (stmmac_clk_get(priv))
goto error;

return priv;

error:
Expand Down Expand Up @@ -1949,9 +1959,11 @@ int stmmac_suspend(struct net_device *ndev)
/* Enable Power down mode by programming the PMT regs */
if (device_may_wakeup(priv->device))
priv->hw->mac->pmt(priv->ioaddr, priv->wolopts);
else
else {
stmmac_set_mac(priv->ioaddr, false);

/* Disable clock in case of PWM is off */
stmmac_clk_disable(priv);
}
spin_unlock(&priv->lock);
return 0;
}
Expand All @@ -1972,6 +1984,9 @@ int stmmac_resume(struct net_device *ndev)
* from another devices (e.g. serial console). */
if (device_may_wakeup(priv->device))
priv->hw->mac->pmt(priv->ioaddr, 0);
else
/* enable the clk prevously disabled */
stmmac_clk_enable(priv);

netif_device_attach(ndev);

Expand Down

0 comments on commit ba1377f

Please sign in to comment.