stmmac: add clk management support
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>
This commit is contained in:
parent
39b401dbd3
commit
ba1377ffe9
@ -22,6 +22,8 @@
|
|||||||
|
|
||||||
#define STMMAC_RESOURCE_NAME "stmmaceth"
|
#define STMMAC_RESOURCE_NAME "stmmaceth"
|
||||||
#define DRV_MODULE_VERSION "Feb_2012"
|
#define DRV_MODULE_VERSION "Feb_2012"
|
||||||
|
|
||||||
|
#include <linux/clk.h>
|
||||||
#include <linux/stmmac.h>
|
#include <linux/stmmac.h>
|
||||||
#include <linux/phy.h>
|
#include <linux/phy.h>
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
@ -79,6 +81,9 @@ struct stmmac_priv {
|
|||||||
struct stmmac_counters mmc;
|
struct stmmac_counters mmc;
|
||||||
struct dma_features dma_cap;
|
struct dma_features dma_cap;
|
||||||
int hw_cap_support;
|
int hw_cap_support;
|
||||||
|
#ifdef CONFIG_HAVE_CLK
|
||||||
|
struct clk *stmmac_clk;
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
extern int phyaddr;
|
extern int phyaddr;
|
||||||
@ -97,3 +102,41 @@ int stmmac_dvr_remove(struct net_device *ndev);
|
|||||||
struct stmmac_priv *stmmac_dvr_probe(struct device *device,
|
struct stmmac_priv *stmmac_dvr_probe(struct device *device,
|
||||||
struct plat_stmmacenet_data *plat_dat,
|
struct plat_stmmacenet_data *plat_dat,
|
||||||
void __iomem *addr);
|
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 */
|
||||||
|
@ -904,6 +904,8 @@ static int stmmac_open(struct net_device *dev)
|
|||||||
struct stmmac_priv *priv = netdev_priv(dev);
|
struct stmmac_priv *priv = netdev_priv(dev);
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
stmmac_clk_enable(priv);
|
||||||
|
|
||||||
stmmac_check_ether_addr(priv);
|
stmmac_check_ether_addr(priv);
|
||||||
|
|
||||||
/* MDIO bus Registration */
|
/* MDIO bus Registration */
|
||||||
@ -911,13 +913,15 @@ static int stmmac_open(struct net_device *dev)
|
|||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
pr_debug("%s: MDIO bus (id: %d) registration failed",
|
pr_debug("%s: MDIO bus (id: %d) registration failed",
|
||||||
__func__, priv->plat->bus_id);
|
__func__, priv->plat->bus_id);
|
||||||
return ret;
|
goto open_clk_dis;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_STMMAC_TIMER
|
#ifdef CONFIG_STMMAC_TIMER
|
||||||
priv->tm = kzalloc(sizeof(struct stmmac_timer *), GFP_KERNEL);
|
priv->tm = kzalloc(sizeof(struct stmmac_timer *), GFP_KERNEL);
|
||||||
if (unlikely(priv->tm == NULL))
|
if (unlikely(priv->tm == NULL)) {
|
||||||
return -ENOMEM;
|
ret = -ENOMEM;
|
||||||
|
goto open_clk_dis;
|
||||||
|
}
|
||||||
|
|
||||||
priv->tm->freq = tmrate;
|
priv->tm->freq = tmrate;
|
||||||
|
|
||||||
@ -1034,6 +1038,8 @@ open_error:
|
|||||||
if (priv->phydev)
|
if (priv->phydev)
|
||||||
phy_disconnect(priv->phydev);
|
phy_disconnect(priv->phydev);
|
||||||
|
|
||||||
|
open_clk_dis:
|
||||||
|
stmmac_clk_disable(priv);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1086,6 +1092,7 @@ static int stmmac_release(struct net_device *dev)
|
|||||||
stmmac_exit_fs();
|
stmmac_exit_fs();
|
||||||
#endif
|
#endif
|
||||||
stmmac_mdio_unregister(dev);
|
stmmac_mdio_unregister(dev);
|
||||||
|
stmmac_clk_disable(priv);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -1880,6 +1887,9 @@ struct stmmac_priv *stmmac_dvr_probe(struct device *device,
|
|||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (stmmac_clk_get(priv))
|
||||||
|
goto error;
|
||||||
|
|
||||||
return priv;
|
return priv;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
@ -1949,9 +1959,11 @@ int stmmac_suspend(struct net_device *ndev)
|
|||||||
/* Enable Power down mode by programming the PMT regs */
|
/* Enable Power down mode by programming the PMT regs */
|
||||||
if (device_may_wakeup(priv->device))
|
if (device_may_wakeup(priv->device))
|
||||||
priv->hw->mac->pmt(priv->ioaddr, priv->wolopts);
|
priv->hw->mac->pmt(priv->ioaddr, priv->wolopts);
|
||||||
else
|
else {
|
||||||
stmmac_set_mac(priv->ioaddr, false);
|
stmmac_set_mac(priv->ioaddr, false);
|
||||||
|
/* Disable clock in case of PWM is off */
|
||||||
|
stmmac_clk_disable(priv);
|
||||||
|
}
|
||||||
spin_unlock(&priv->lock);
|
spin_unlock(&priv->lock);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -1972,6 +1984,9 @@ int stmmac_resume(struct net_device *ndev)
|
|||||||
* from another devices (e.g. serial console). */
|
* from another devices (e.g. serial console). */
|
||||||
if (device_may_wakeup(priv->device))
|
if (device_may_wakeup(priv->device))
|
||||||
priv->hw->mac->pmt(priv->ioaddr, 0);
|
priv->hw->mac->pmt(priv->ioaddr, 0);
|
||||||
|
else
|
||||||
|
/* enable the clk prevously disabled */
|
||||||
|
stmmac_clk_enable(priv);
|
||||||
|
|
||||||
netif_device_attach(ndev);
|
netif_device_attach(ndev);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user