stmmac: Add an optional register interface clock
The DWMAC block on certain SoCs (such as IMG Pistachio) have a second clock which must be enabled in order to access the peripheral's register interface, so add support for requesting and enabling an optional "pclk". Signed-off-by: Andrew Bresticker <abrestic@chromium.org> Cc: James Hartley <james.hartley@imgtec.com> Cc: Arnd Bergmann <arnd@arndb.de> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Родитель
2790460e14
Коммит
5f9755d26f
|
@ -35,10 +35,11 @@ Optional properties:
|
||||||
- reset-names: Should contain the reset signal name "stmmaceth", if a
|
- reset-names: Should contain the reset signal name "stmmaceth", if a
|
||||||
reset phandle is given
|
reset phandle is given
|
||||||
- max-frame-size: See ethernet.txt file in the same directory
|
- max-frame-size: See ethernet.txt file in the same directory
|
||||||
- clocks: If present, the first clock should be the GMAC main clock,
|
- clocks: If present, the first clock should be the GMAC main clock and
|
||||||
further clocks may be specified in derived bindings.
|
the second clock should be peripheral's register interface clock. Further
|
||||||
|
clocks may be specified in derived bindings.
|
||||||
- clock-names: One name for each entry in the clocks property, the
|
- clock-names: One name for each entry in the clocks property, the
|
||||||
first one should be "stmmaceth".
|
first one should be "stmmaceth" and the second one should be "pclk".
|
||||||
- clk_ptp_ref: this is the PTP reference clock; in case of the PTP is
|
- clk_ptp_ref: this is the PTP reference clock; in case of the PTP is
|
||||||
available this clock is used for programming the Timestamp Addend Register.
|
available this clock is used for programming the Timestamp Addend Register.
|
||||||
If not passed then the system clock will be used and this is fine on some
|
If not passed then the system clock will be used and this is fine on some
|
||||||
|
|
|
@ -97,6 +97,7 @@ struct stmmac_priv {
|
||||||
int wolopts;
|
int wolopts;
|
||||||
int wol_irq;
|
int wol_irq;
|
||||||
struct clk *stmmac_clk;
|
struct clk *stmmac_clk;
|
||||||
|
struct clk *pclk;
|
||||||
struct reset_control *stmmac_rst;
|
struct reset_control *stmmac_rst;
|
||||||
int clk_csr;
|
int clk_csr;
|
||||||
struct timer_list eee_ctrl_timer;
|
struct timer_list eee_ctrl_timer;
|
||||||
|
|
|
@ -2849,6 +2849,16 @@ struct stmmac_priv *stmmac_dvr_probe(struct device *device,
|
||||||
}
|
}
|
||||||
clk_prepare_enable(priv->stmmac_clk);
|
clk_prepare_enable(priv->stmmac_clk);
|
||||||
|
|
||||||
|
priv->pclk = devm_clk_get(priv->device, "pclk");
|
||||||
|
if (IS_ERR(priv->pclk)) {
|
||||||
|
if (PTR_ERR(priv->pclk) == -EPROBE_DEFER) {
|
||||||
|
ret = -EPROBE_DEFER;
|
||||||
|
goto error_pclk_get;
|
||||||
|
}
|
||||||
|
priv->pclk = NULL;
|
||||||
|
}
|
||||||
|
clk_prepare_enable(priv->pclk);
|
||||||
|
|
||||||
priv->stmmac_rst = devm_reset_control_get(priv->device,
|
priv->stmmac_rst = devm_reset_control_get(priv->device,
|
||||||
STMMAC_RESOURCE_NAME);
|
STMMAC_RESOURCE_NAME);
|
||||||
if (IS_ERR(priv->stmmac_rst)) {
|
if (IS_ERR(priv->stmmac_rst)) {
|
||||||
|
@ -2934,6 +2944,8 @@ error_mdio_register:
|
||||||
error_netdev_register:
|
error_netdev_register:
|
||||||
netif_napi_del(&priv->napi);
|
netif_napi_del(&priv->napi);
|
||||||
error_hw_init:
|
error_hw_init:
|
||||||
|
clk_disable_unprepare(priv->pclk);
|
||||||
|
error_pclk_get:
|
||||||
clk_disable_unprepare(priv->stmmac_clk);
|
clk_disable_unprepare(priv->stmmac_clk);
|
||||||
error_clk_get:
|
error_clk_get:
|
||||||
free_netdev(ndev);
|
free_netdev(ndev);
|
||||||
|
@ -2965,6 +2977,7 @@ int stmmac_dvr_remove(struct net_device *ndev)
|
||||||
unregister_netdev(ndev);
|
unregister_netdev(ndev);
|
||||||
if (priv->stmmac_rst)
|
if (priv->stmmac_rst)
|
||||||
reset_control_assert(priv->stmmac_rst);
|
reset_control_assert(priv->stmmac_rst);
|
||||||
|
clk_disable_unprepare(priv->pclk);
|
||||||
clk_disable_unprepare(priv->stmmac_clk);
|
clk_disable_unprepare(priv->stmmac_clk);
|
||||||
free_netdev(ndev);
|
free_netdev(ndev);
|
||||||
|
|
||||||
|
@ -3011,6 +3024,7 @@ int stmmac_suspend(struct net_device *ndev)
|
||||||
stmmac_set_mac(priv->ioaddr, false);
|
stmmac_set_mac(priv->ioaddr, false);
|
||||||
pinctrl_pm_select_sleep_state(priv->device);
|
pinctrl_pm_select_sleep_state(priv->device);
|
||||||
/* Disable clock in case of PWM is off */
|
/* Disable clock in case of PWM is off */
|
||||||
|
clk_disable(priv->pclk);
|
||||||
clk_disable(priv->stmmac_clk);
|
clk_disable(priv->stmmac_clk);
|
||||||
}
|
}
|
||||||
spin_unlock_irqrestore(&priv->lock, flags);
|
spin_unlock_irqrestore(&priv->lock, flags);
|
||||||
|
@ -3051,6 +3065,7 @@ int stmmac_resume(struct net_device *ndev)
|
||||||
pinctrl_pm_select_default_state(priv->device);
|
pinctrl_pm_select_default_state(priv->device);
|
||||||
/* enable the clk prevously disabled */
|
/* enable the clk prevously disabled */
|
||||||
clk_enable(priv->stmmac_clk);
|
clk_enable(priv->stmmac_clk);
|
||||||
|
clk_enable(priv->pclk);
|
||||||
/* reset the phy so that it's ready */
|
/* reset the phy so that it's ready */
|
||||||
if (priv->mii)
|
if (priv->mii)
|
||||||
stmmac_mdio_reset(priv->mii);
|
stmmac_mdio_reset(priv->mii);
|
||||||
|
|
Загрузка…
Ссылка в новой задаче