summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOlivier Dufour2012-11-14 13:50:25 +0100
committerOlivier Dufour2012-12-21 15:15:41 +0100
commit6a9493bf395971a420326320f65a286c9b664a91 (patch)
tree7039c7bc4b8dd66f83b4c7741be2ce408ed0001a
parentc47216c9e5f22da281ca79ea9589584cef6b376d (diff)
cleo/linux/drv/net/arm: switch off ethernet clocks, refs #2633
-rw-r--r--cleopatre/linux-2.6.25.10-spc300/drivers/net/arm/synop3504.c66
-rw-r--r--cleopatre/linux-2.6.25.10-spc300/drivers/net/arm/synop3504_hw.c80
-rw-r--r--cleopatre/linux-2.6.25.10-spc300/drivers/net/arm/synop3504_hw.h5
3 files changed, 149 insertions, 2 deletions
diff --git a/cleopatre/linux-2.6.25.10-spc300/drivers/net/arm/synop3504.c b/cleopatre/linux-2.6.25.10-spc300/drivers/net/arm/synop3504.c
index 51a728a9d7..9119cbc7f6 100644
--- a/cleopatre/linux-2.6.25.10-spc300/drivers/net/arm/synop3504.c
+++ b/cleopatre/linux-2.6.25.10-spc300/drivers/net/arm/synop3504.c
@@ -1633,6 +1633,66 @@ static int synop3504_init(struct net_device *dev)
return 0;
}// synop3504_init
+#ifdef CONFIG_PM
+
+/**
+ * Suspend Synop3504 interface.
+ * \param pdev platform device
+ * \param state target suspend state
+ * \return error code
+ */
+static int synop3504_suspend(struct platform_device *pdev, pm_message_t mesg)
+{
+ struct net_device *dev = platform_get_drvdata(pdev);
+ struct net_priv *priv = NULL;
+ Synopsys *synop = NULL;
+
+ priv = netdev_priv(dev);
+ if(priv == NULL)
+ return -1;
+ synop = &priv->synop;
+ if(synop == NULL)
+ return -1;
+
+ netif_device_detach(dev);
+
+ SynopsysSuspendClk(synop);
+
+ return 0;
+}
+
+/**
+ * Resume Synop3504 interface.
+ * \param pdev platform device
+ * \return error code
+ */
+static int synop3504_resume(struct platform_device *pdev)
+{
+ struct net_device *dev = platform_get_drvdata(pdev);
+ struct net_priv *priv = NULL;
+ Synopsys *synop = NULL;
+ struct phy_device *phydev = NULL;
+
+ priv = netdev_priv(dev);
+ if(priv == NULL)
+ return -1;
+ synop = &priv->synop;
+ if(synop == NULL)
+ return -1;
+ phydev = priv->phydev;
+ if (phydev == NULL)
+ return -1;
+
+ SynopsysResumeClk(synop);
+ SynopsysSetMiiClkCap(synop, phydev->speed);
+
+ netif_device_attach(dev);
+
+ return 0;
+}
+
+#endif /* CONFIG_PM */
+
/**
* Number of devices registered
*/
@@ -1854,8 +1914,10 @@ static struct platform_driver synop3504_eth_driver = {
.name = "synopsys3504",
.owner = THIS_MODULE,
},
- .suspend = NULL,
- .resume = NULL,
+#ifdef CONFIG_PM
+ .suspend = synop3504_suspend,
+ .resume = synop3504_resume,
+#endif
.remove = __exit_p(synop3504_module_remove),
};
diff --git a/cleopatre/linux-2.6.25.10-spc300/drivers/net/arm/synop3504_hw.c b/cleopatre/linux-2.6.25.10-spc300/drivers/net/arm/synop3504_hw.c
index 5004d48ce3..1d0119a4f9 100644
--- a/cleopatre/linux-2.6.25.10-spc300/drivers/net/arm/synop3504_hw.c
+++ b/cleopatre/linux-2.6.25.10-spc300/drivers/net/arm/synop3504_hw.c
@@ -227,6 +227,86 @@ void SynopsysInit(Synopsys *synop, uint32_t txaddr, uint32_t rxaddr)
TRACE("OK\n");
}// SynopsysInit
+#ifdef CONFIG_PM
+
+/**
+ * Disable all clocks to enter suspend mode.
+ * \param synop synopsys context structure.
+ */
+void SynopsysSuspendClk(Synopsys *synop)
+{
+ if(synop->mac_id == 1)
+ {
+ RB_CLK_CMD_ETH1_TX_VA = CLK_CMD_OFF;
+ RB_CLK_CMD_ETH1_RX_VA = CLK_CMD_OFF;
+ }
+ else if(synop->mac_id == 2)
+ {
+ RB_CLK_CMD_ETH2_TX_VA = CLK_CMD_OFF;
+ RB_CLK_CMD_ETH2_RX_VA = CLK_CMD_OFF;
+ }
+}
+
+/**
+ * Enable clocks when returning from suspend mode.
+ * \param synop synopsys context structure.
+ *
+ * /!\ This function only handles the enabling of base clocks. The function
+ * SynopsysSetMiiClkCap must be called right after to make the whole config
+ * clean.
+ */
+void SynopsysResumeClk(Synopsys *synop)
+{
+ if(synop->mac_id == 1)
+ {
+ RB_CLK_CMD_ETH1_TX_VA = CLK_CMD_PLL_ON;
+ while (RB_CLK_STAT_ETH1_TX_VA != CLK_ETH_TX_RX_PLL_IS_ON)
+ ;
+
+ if(synop->mode == IS_RMII)
+ {
+ RB_CLK_CMD_ETH1_RX_VA = CLK_CMD_PLL_ON;
+ while (RB_CLK_STAT_ETH1_RX_VA != CLK_ETH_TX_RX_PLL_IS_ON)
+ ;
+
+ RB_CLK_CMD_ETH1_RMII_VA = CLK_CMD_RMII_PLL_ON;
+ while (RB_CLK_STAT_ETH1_RMII_VA != CLK_ETH_RMII_PLL_IS_ON)
+ ;
+ }
+ else
+ {
+ RB_CLK_CMD_ETH1_RX_VA = CLK_CMD_MII_ON;
+ while (RB_CLK_STAT_ETH1_RX_VA != CLK_ETH_TX_RX_MII_IS_ON)
+ ;
+ }
+ }
+ else if(synop->mac_id == 2)
+ {
+ RB_CLK_CMD_ETH2_TX_VA = CLK_CMD_PLL_ON;
+ while (RB_CLK_STAT_ETH2_TX_VA != CLK_ETH_TX_RX_PLL_IS_ON)
+ ;
+
+ if(synop->mode == IS_RMII)
+ {
+ RB_CLK_CMD_ETH2_RX_VA = CLK_CMD_PLL_ON;
+ while (RB_CLK_STAT_ETH2_RX_VA != CLK_ETH_TX_RX_PLL_IS_ON)
+ ;
+
+ RB_CLK_CMD_ETH2_RMII_VA = CLK_CMD_RMII_PLL_ON;
+ while (RB_CLK_STAT_ETH2_RMII_VA != CLK_ETH_RMII_PLL_IS_ON)
+ ;
+ }
+ else
+ {
+ RB_CLK_CMD_ETH2_RX_VA = CLK_CMD_MII_ON;
+ while (RB_CLK_STAT_ETH2_RX_VA != CLK_ETH_TX_RX_MII_IS_ON)
+ ;
+ }
+ }
+}
+
+#endif /* CONFIG_PM */
+
/**
* Set MII mode clock depending on
* speed chosen by auto-negotiation.
diff --git a/cleopatre/linux-2.6.25.10-spc300/drivers/net/arm/synop3504_hw.h b/cleopatre/linux-2.6.25.10-spc300/drivers/net/arm/synop3504_hw.h
index 9dc04598d6..932d36daee 100644
--- a/cleopatre/linux-2.6.25.10-spc300/drivers/net/arm/synop3504_hw.h
+++ b/cleopatre/linux-2.6.25.10-spc300/drivers/net/arm/synop3504_hw.h
@@ -185,6 +185,11 @@ void SynopsysInit(Synopsys *synop, uint32_t txaddr, uint32_t rxaddr);
void SynopsysReset(Synopsys *synop);
+#ifdef CONFIG_PM
+void SynopsysSuspendClk(Synopsys *synop);
+void SynopsysResumeClk(Synopsys *synop);
+#endif
+
/**
* Set MII mode clock depending on
* speed chosen by auto-negotiation.