All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH RFC 0/9]net: stmmac PM related fixes.
@ 2013-11-18 11:30 srinivas.kandagatla
  2013-11-18 11:31 ` [PATCH RFC 1/9] net: stmmac: support max-speed device tree property srinivas.kandagatla
                   ` (12 more replies)
  0 siblings, 13 replies; 28+ messages in thread
From: srinivas.kandagatla @ 2013-11-18 11:30 UTC (permalink / raw)
  To: Giuseppe Cavallaro, netdev; +Cc: linux-kernel, srinivas.kandagatla

From: Srinivas Kandagatla <srinivas.kandagatla@st.com>

Hi Peppe,

During PM_SUSPEND_FREEZE testing, I have noticed that PM support in STMMAC is
partly broken. I had to re-arrange the code to do PM correctly. There were lot
of things I did not like personally and some bits did not work in the first
place. I thought this is the nice opportunity to clean the mess up.

Here is what I did:

1> Test PM suspend freeeze via pm_test
It did not work for following reasons.
 - If the power to gmac is removed when it enters in low power state.
stmmac_resume could not cope up with such behaviour, it was expecting the ip
register contents to be still same as before entering low power, This
assumption is wrong. So I started to add some code to do Hardware
initialization, thats when I started to re-arrange the code. stmmac_open
contains both resource and memory allocations and hardware initialization. I
had to separate these two things in two different functions.

These two patches do that
  net: stmmac: move dma allocation to new function
  net: stmmac: move hardware setup for stmmac_open to new function

And rest of the other patches are fixing the loose ends, things like mdio
reset, which might be necessary in cases likes hibernation(I did not test).

In hibernation cases the driver was just unregistering with subsystems and
releasing resources which I did not like and its not necessary to do this as
part of PM. So using the same stmmac_suspend/resume made more sense for
hibernation cases than using stmmac_open/release.
Also fixed a NULL pointer dereference bug too.

2> Test WOL via PM_SUSPEND_FREEZE
Did get an wakeup interrupt, but could not wakeup a freeze system.
So I had to add pm_wakeup_event to the driver.
net: stmmac: notify the PM core of a wakeup event. patch.

Also few patches like 
  net: stmmac: make stmmac_mdio_reset non-static
  net: stmmac: restore pinstate in pm resume.
helps the resume function to reset the phy and put back the pins in default
state.

Comments?

Thanks,
srini

Srinivas Kandagatla (9):
  net: stmmac: support max-speed device tree property
  net: stmmac: mdio: remove reset gpio free
  net: stmmac: move dma allocation to new function
  net: stmmac: move hardware setup for stmmac_open to new function
  net: stmmac: make stmmac_mdio_reset non-static
  net: stmmac: fix power mangement suspend-resume case
  net: stmmac: use suspend functions for hibernation
  net: stmmac: restore pinstate in pm resume.
  net: stmmac: notify the PM core of a wakeup event.

 drivers/net/ethernet/stmicro/stmmac/stmmac.h       |    4 +-
 drivers/net/ethernet/stmicro/stmmac/stmmac_main.c  |  360 ++++++++++----------
 drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c  |    3 +-
 .../net/ethernet/stmicro/stmmac/stmmac_platform.c  |   51 +--
 include/linux/stmmac.h                             |    1 +
 5 files changed, 209 insertions(+), 210 deletions(-)

-- 
1.7.6.5


^ permalink raw reply	[flat|nested] 28+ messages in thread

* [PATCH RFC 1/9] net: stmmac: support max-speed device tree property
  2013-11-18 11:30 [PATCH RFC 0/9]net: stmmac PM related fixes srinivas.kandagatla
@ 2013-11-18 11:31 ` srinivas.kandagatla
  2013-11-18 11:31 ` [PATCH RFC 2/9] net: stmmac: mdio: remove reset gpio free srinivas.kandagatla
                   ` (11 subsequent siblings)
  12 siblings, 0 replies; 28+ messages in thread
From: srinivas.kandagatla @ 2013-11-18 11:31 UTC (permalink / raw)
  To: Giuseppe Cavallaro, netdev; +Cc: linux-kernel, srinivas.kandagatla

From: Srinivas Kandagatla <srinivas.kandagatla@st.com>

This patch adds support to "max-speed" property which is a standard
ethernet device tree property. max-speed specifies maximum speed
(specified in megabits per second) supported the device.

Depending on the clocking schemes some of the boards can only support
few link speeds, so having a way to limit the link speed in the mac
driver would allow such setups to work reliably.

Without this patch there is no way to tell the driver to limit the
link speed.

Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@st.com>
---
 drivers/net/ethernet/stmicro/stmmac/stmmac_main.c  |    4 +++-
 .../net/ethernet/stmicro/stmmac/stmmac_platform.c  |    4 ++++
 include/linux/stmmac.h                             |    1 +
 3 files changed, 8 insertions(+), 1 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index 8d4ccd3..f72c6a2 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -784,6 +784,7 @@ static int stmmac_init_phy(struct net_device *dev)
 	char phy_id_fmt[MII_BUS_ID_SIZE + 3];
 	char bus_id[MII_BUS_ID_SIZE];
 	int interface = priv->plat->interface;
+	int max_speed = priv->plat->max_speed;
 	priv->oldlink = 0;
 	priv->speed = 0;
 	priv->oldduplex = -1;
@@ -808,7 +809,8 @@ static int stmmac_init_phy(struct net_device *dev)
 
 	/* Stop Advertising 1000BASE Capability if interface is not GMII */
 	if ((interface == PHY_INTERFACE_MODE_MII) ||
-	    (interface == PHY_INTERFACE_MODE_RMII))
+	    (interface == PHY_INTERFACE_MODE_RMII) ||
+		(max_speed < 1000 &&  max_speed > 0))
 		phydev->advertising &= ~(SUPPORTED_1000baseT_Half |
 					 SUPPORTED_1000baseT_Full);
 
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
index 51c9069..3073c50 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
@@ -42,6 +42,10 @@ static int stmmac_probe_config_dt(struct platform_device *pdev,
 	*mac = of_get_mac_address(np);
 	plat->interface = of_get_phy_mode(np);
 
+	/* Get max speed of operation from device tree */
+	if (of_property_read_u32(np, "max-speed", &plat->max_speed))
+		plat->max_speed = -1;
+
 	plat->bus_id = of_alias_get_id(np, "ethernet");
 	if (plat->bus_id < 0)
 		plat->bus_id = 0;
diff --git a/include/linux/stmmac.h b/include/linux/stmmac.h
index bb5deb0..33ace71 100644
--- a/include/linux/stmmac.h
+++ b/include/linux/stmmac.h
@@ -110,6 +110,7 @@ struct plat_stmmacenet_data {
 	int force_sf_dma_mode;
 	int force_thresh_dma_mode;
 	int riwt_off;
+	int max_speed;
 	void (*fix_mac_speed)(void *priv, unsigned int speed);
 	void (*bus_setup)(void __iomem *ioaddr);
 	int (*init)(struct platform_device *pdev);
-- 
1.7.6.5


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH RFC 2/9] net: stmmac: mdio: remove reset gpio free
  2013-11-18 11:30 [PATCH RFC 0/9]net: stmmac PM related fixes srinivas.kandagatla
  2013-11-18 11:31 ` [PATCH RFC 1/9] net: stmmac: support max-speed device tree property srinivas.kandagatla
@ 2013-11-18 11:31 ` srinivas.kandagatla
  2013-11-18 11:31 ` [PATCH RFC 3/9] net: stmmac: move dma allocation to new function srinivas.kandagatla
                   ` (10 subsequent siblings)
  12 siblings, 0 replies; 28+ messages in thread
From: srinivas.kandagatla @ 2013-11-18 11:31 UTC (permalink / raw)
  To: Giuseppe Cavallaro, netdev; +Cc: linux-kernel, srinivas.kandagatla

From: Srinivas Kandagatla <srinivas.kandagatla@st.com>

This patch removes gpio_free for reset line of the phy, driver stores
the gpio number in its private data-structure to use in future. As the
driver uses this pin in future this pin should not be freed.

Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@st.com>
---
 drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c |    1 -
 1 files changed, 0 insertions(+), 1 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c
index fe7bc99..aab12d2 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c
@@ -166,7 +166,6 @@ static int stmmac_mdio_reset(struct mii_bus *bus)
 			udelay(data->delays[1]);
 			gpio_set_value(reset_gpio, active_low ? 1 : 0);
 			udelay(data->delays[2]);
-			gpio_free(reset_gpio);
 		}
 	}
 #endif
-- 
1.7.6.5


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH RFC 3/9] net: stmmac: move dma allocation to new function
  2013-11-18 11:30 [PATCH RFC 0/9]net: stmmac PM related fixes srinivas.kandagatla
  2013-11-18 11:31 ` [PATCH RFC 1/9] net: stmmac: support max-speed device tree property srinivas.kandagatla
  2013-11-18 11:31 ` [PATCH RFC 2/9] net: stmmac: mdio: remove reset gpio free srinivas.kandagatla
@ 2013-11-18 11:31 ` srinivas.kandagatla
  2013-11-18 11:32 ` [PATCH RFC 4/9] net: stmmac: move hardware setup for stmmac_open " srinivas.kandagatla
                   ` (9 subsequent siblings)
  12 siblings, 0 replies; 28+ messages in thread
From: srinivas.kandagatla @ 2013-11-18 11:31 UTC (permalink / raw)
  To: Giuseppe Cavallaro, netdev; +Cc: linux-kernel, srinivas.kandagatla

From: Srinivas Kandagatla <srinivas.kandagatla@st.com>

This patch moves dma resource allocation to a new function
alloc_dma_desc_resources, the reason for moving this to a new function
is to keep the memory allocations in a separate function. One more reason
it to get suspend and hibernation cases working without releasing and
allocating these resources during suspend-resume and freeze-restore
cases.

Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@st.com>
---
 drivers/net/ethernet/stmicro/stmmac/stmmac_main.c |  169 +++++++++++----------
 1 files changed, 85 insertions(+), 84 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index f72c6a2..296457c 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -1004,66 +1004,6 @@ static int init_dma_desc_rings(struct net_device *dev)
 		pr_debug("%s: txsize %d, rxsize %d, bfsize %d\n", __func__,
 			 txsize, rxsize, bfsize);
 
-	if (priv->extend_desc) {
-		priv->dma_erx = dma_alloc_coherent(priv->device, rxsize *
-						   sizeof(struct
-							  dma_extended_desc),
-						   &priv->dma_rx_phy,
-						   GFP_KERNEL);
-		if (!priv->dma_erx)
-			goto err_dma;
-
-		priv->dma_etx = dma_alloc_coherent(priv->device, txsize *
-						   sizeof(struct
-							  dma_extended_desc),
-						   &priv->dma_tx_phy,
-						   GFP_KERNEL);
-		if (!priv->dma_etx) {
-			dma_free_coherent(priv->device, priv->dma_rx_size *
-					sizeof(struct dma_extended_desc),
-					priv->dma_erx, priv->dma_rx_phy);
-			goto err_dma;
-		}
-	} else {
-		priv->dma_rx = dma_alloc_coherent(priv->device, rxsize *
-						  sizeof(struct dma_desc),
-						  &priv->dma_rx_phy,
-						  GFP_KERNEL);
-		if (!priv->dma_rx)
-			goto err_dma;
-
-		priv->dma_tx = dma_alloc_coherent(priv->device, txsize *
-						  sizeof(struct dma_desc),
-						  &priv->dma_tx_phy,
-						  GFP_KERNEL);
-		if (!priv->dma_tx) {
-			dma_free_coherent(priv->device, priv->dma_rx_size *
-					sizeof(struct dma_desc),
-					priv->dma_rx, priv->dma_rx_phy);
-			goto err_dma;
-		}
-	}
-
-	priv->rx_skbuff_dma = kmalloc_array(rxsize, sizeof(dma_addr_t),
-					    GFP_KERNEL);
-	if (!priv->rx_skbuff_dma)
-		goto err_rx_skbuff_dma;
-
-	priv->rx_skbuff = kmalloc_array(rxsize, sizeof(struct sk_buff *),
-					GFP_KERNEL);
-	if (!priv->rx_skbuff)
-		goto err_rx_skbuff;
-
-	priv->tx_skbuff_dma = kmalloc_array(txsize, sizeof(dma_addr_t),
-					    GFP_KERNEL);
-	if (!priv->tx_skbuff_dma)
-		goto err_tx_skbuff_dma;
-
-	priv->tx_skbuff = kmalloc_array(txsize, sizeof(struct sk_buff *),
-					GFP_KERNEL);
-	if (!priv->tx_skbuff)
-		goto err_tx_skbuff;
-
 	if (netif_msg_probe(priv)) {
 		pr_debug("(%s) dma_rx_phy=0x%08x dma_tx_phy=0x%08x\n", __func__,
 			 (u32) priv->dma_rx_phy, (u32) priv->dma_tx_phy);
@@ -1131,30 +1071,6 @@ static int init_dma_desc_rings(struct net_device *dev)
 err_init_rx_buffers:
 	while (--i >= 0)
 		stmmac_free_rx_buffers(priv, i);
-	kfree(priv->tx_skbuff);
-err_tx_skbuff:
-	kfree(priv->tx_skbuff_dma);
-err_tx_skbuff_dma:
-	kfree(priv->rx_skbuff);
-err_rx_skbuff:
-	kfree(priv->rx_skbuff_dma);
-err_rx_skbuff_dma:
-	if (priv->extend_desc) {
-		dma_free_coherent(priv->device, priv->dma_tx_size *
-				  sizeof(struct dma_extended_desc),
-				  priv->dma_etx, priv->dma_tx_phy);
-		dma_free_coherent(priv->device, priv->dma_rx_size *
-				  sizeof(struct dma_extended_desc),
-				  priv->dma_erx, priv->dma_rx_phy);
-	} else {
-		dma_free_coherent(priv->device,
-				priv->dma_tx_size * sizeof(struct dma_desc),
-				priv->dma_tx, priv->dma_tx_phy);
-		dma_free_coherent(priv->device,
-				priv->dma_rx_size * sizeof(struct dma_desc),
-				priv->dma_rx, priv->dma_rx_phy);
-	}
-err_dma:
 	return ret;
 }
 
@@ -1190,6 +1106,85 @@ static void dma_free_tx_skbufs(struct stmmac_priv *priv)
 	}
 }
 
+static int alloc_dma_desc_resources(struct stmmac_priv *priv)
+{
+	unsigned int txsize = priv->dma_tx_size;
+	unsigned int rxsize = priv->dma_rx_size;
+	int ret = -ENOMEM;
+
+	priv->rx_skbuff_dma = kmalloc_array(rxsize, sizeof(dma_addr_t),
+					    GFP_KERNEL);
+	if (!priv->rx_skbuff_dma)
+		return -ENOMEM;
+
+	priv->rx_skbuff = kmalloc_array(rxsize, sizeof(struct sk_buff *),
+					GFP_KERNEL);
+	if (!priv->rx_skbuff)
+		goto err_rx_skbuff;
+
+	priv->tx_skbuff_dma = kmalloc_array(txsize, sizeof(dma_addr_t),
+					    GFP_KERNEL);
+	if (!priv->tx_skbuff_dma)
+		goto err_tx_skbuff_dma;
+
+	priv->tx_skbuff = kmalloc_array(txsize, sizeof(struct sk_buff *),
+					GFP_KERNEL);
+	if (!priv->tx_skbuff)
+		goto err_tx_skbuff;
+
+	if (priv->extend_desc) {
+		priv->dma_erx = dma_alloc_coherent(priv->device, rxsize *
+						   sizeof(struct
+							  dma_extended_desc),
+						   &priv->dma_rx_phy,
+						   GFP_KERNEL);
+		if (!priv->dma_erx)
+			goto err_dma;
+
+		priv->dma_etx = dma_alloc_coherent(priv->device, txsize *
+						   sizeof(struct
+							  dma_extended_desc),
+						   &priv->dma_tx_phy,
+						   GFP_KERNEL);
+		if (!priv->dma_etx) {
+			dma_free_coherent(priv->device, priv->dma_rx_size *
+					sizeof(struct dma_extended_desc),
+					priv->dma_erx, priv->dma_rx_phy);
+			goto err_dma;
+		}
+	} else {
+		priv->dma_rx = dma_alloc_coherent(priv->device, rxsize *
+						  sizeof(struct dma_desc),
+						  &priv->dma_rx_phy,
+						  GFP_KERNEL);
+		if (!priv->dma_rx)
+			goto err_dma;
+
+		priv->dma_tx = dma_alloc_coherent(priv->device, txsize *
+						  sizeof(struct dma_desc),
+						  &priv->dma_tx_phy,
+						  GFP_KERNEL);
+		if (!priv->dma_tx) {
+			dma_free_coherent(priv->device, priv->dma_rx_size *
+					sizeof(struct dma_desc),
+					priv->dma_rx, priv->dma_rx_phy);
+			goto err_dma;
+		}
+	}
+
+	return 0;
+
+err_dma:
+	kfree(priv->tx_skbuff);
+err_tx_skbuff:
+	kfree(priv->tx_skbuff_dma);
+err_tx_skbuff_dma:
+	kfree(priv->rx_skbuff);
+err_rx_skbuff:
+	kfree(priv->rx_skbuff_dma);
+	return ret;
+}
+
 static void free_dma_desc_resources(struct stmmac_priv *priv)
 {
 	/* Release the DMA TX/RX socket buffers */
@@ -1631,6 +1626,12 @@ static int stmmac_open(struct net_device *dev)
 	priv->dma_rx_size = STMMAC_ALIGN(dma_rxsize);
 	priv->dma_buf_sz = STMMAC_ALIGN(buf_sz);
 
+	alloc_dma_desc_resources(priv);
+	if (ret < 0) {
+		pr_err("%s: DMA descriptors allocation failed\n", __func__);
+		goto dma_desc_error;
+	}
+
 	ret = init_dma_desc_rings(dev);
 	if (ret < 0) {
 		pr_err("%s: DMA descriptors initialization failed\n", __func__);
-- 
1.7.6.5


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH RFC 4/9] net: stmmac: move hardware setup for stmmac_open to new function
  2013-11-18 11:30 [PATCH RFC 0/9]net: stmmac PM related fixes srinivas.kandagatla
                   ` (2 preceding siblings ...)
  2013-11-18 11:31 ` [PATCH RFC 3/9] net: stmmac: move dma allocation to new function srinivas.kandagatla
@ 2013-11-18 11:32 ` srinivas.kandagatla
  2013-11-18 11:32 ` [PATCH RFC 5/9] net: stmmac: make stmmac_mdio_reset non-static srinivas.kandagatla
                   ` (8 subsequent siblings)
  12 siblings, 0 replies; 28+ messages in thread
From: srinivas.kandagatla @ 2013-11-18 11:32 UTC (permalink / raw)
  To: Giuseppe Cavallaro, netdev; +Cc: linux-kernel, srinivas.kandagatla

From: Srinivas Kandagatla <srinivas.kandagatla@st.com>

This patch moves hardware setup part of the code in stmmac_open to a new
function stmmac_hw_setup, the reason for doing this is to make hw
initialization independent function so that PM functions can re-use it to
re-initialize the IP after returning from low power state.
This will also avoid code duplication across stmmac_resume/restore and
stmmac_open.

Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@st.com>
---
 drivers/net/ethernet/stmicro/stmmac/stmmac_main.c |  155 ++++++++++++---------
 1 files changed, 88 insertions(+), 67 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index 296457c..ea34ebc 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -1594,6 +1594,86 @@ static void stmmac_init_tx_coalesce(struct stmmac_priv *priv)
 }
 
 /**
+ * stmmac_hw_setup: setup mac in a usable state.
+ *  @dev : pointer to the device structure.
+ *  Description:
+ *  This function sets up the ip in a usable state.
+ *  Return value:
+ *  0 on success and an appropriate (-)ve integer as defined in errno.h
+ *  file on failure.
+ */
+static int stmmac_hw_setup(struct net_device *dev)
+{
+	struct stmmac_priv *priv = netdev_priv(dev);
+	int ret;
+
+	ret = init_dma_desc_rings(dev);
+	if (ret < 0) {
+		pr_err("%s: DMA descriptors initialization failed\n", __func__);
+		return ret;
+	}
+	/* DMA initialization and SW reset */
+	ret = stmmac_init_dma_engine(priv);
+	if (ret < 0) {
+		pr_err("%s: DMA engine initialization failed\n", __func__);
+		return ret;
+	}
+
+	/* Copy the MAC addr into the HW  */
+	priv->hw->mac->set_umac_addr(priv->ioaddr, dev->dev_addr, 0);
+
+	/* If required, perform hw setup of the bus. */
+	if (priv->plat->bus_setup)
+		priv->plat->bus_setup(priv->ioaddr);
+
+	/* Initialize the MAC Core */
+	priv->hw->mac->core_init(priv->ioaddr);
+
+	/* Enable the MAC Rx/Tx */
+	stmmac_set_mac(priv->ioaddr, true);
+
+	/* Set the HW DMA mode and the COE */
+	stmmac_dma_operation_mode(priv);
+
+	stmmac_mmc_setup(priv);
+
+	ret = stmmac_init_ptp(priv);
+	if (ret)
+		pr_warn("%s: failed PTP initialisation\n", __func__);
+
+#ifdef CONFIG_STMMAC_DEBUG_FS
+	ret = stmmac_init_fs(dev);
+	if (ret < 0)
+		pr_warn("%s: failed debugFS registration\n", __func__);
+#endif
+	/* Start the ball rolling... */
+	pr_debug("%s: DMA RX/TX processes started...\n", dev->name);
+	priv->hw->dma->start_tx(priv->ioaddr);
+	priv->hw->dma->start_rx(priv->ioaddr);
+
+	/* Dump DMA/MAC registers */
+	if (netif_msg_hw(priv)) {
+		priv->hw->mac->dump_regs(priv->ioaddr);
+		priv->hw->dma->dump_regs(priv->ioaddr);
+	}
+	priv->tx_lpi_timer = STMMAC_DEFAULT_TWT_LS;
+
+	priv->eee_enabled = stmmac_eee_init(priv);
+
+	stmmac_init_tx_coalesce(priv);
+
+	if ((priv->use_riwt) && (priv->hw->dma->rx_watchdog)) {
+		priv->rx_riwt = MAX_DMA_RIWT;
+		priv->hw->dma->rx_watchdog(priv->ioaddr, MAX_DMA_RIWT);
+	}
+
+	if (priv->pcs && priv->hw->mac->ctrl_ane)
+		priv->hw->mac->ctrl_ane(priv->ioaddr, 0);
+
+	return 0;
+}
+
+/**
  *  stmmac_open - open entry point of the driver
  *  @dev : pointer to the device structure.
  *  Description:
@@ -1621,6 +1701,10 @@ static int stmmac_open(struct net_device *dev)
 		}
 	}
 
+	/* Extra statistics */
+	memset(&priv->xstats, 0, sizeof(struct stmmac_extra_stats));
+	priv->xstats.threshold = tc;
+
 	/* Create and initialize the TX/RX descriptors chains. */
 	priv->dma_tx_size = STMMAC_ALIGN(dma_txsize);
 	priv->dma_rx_size = STMMAC_ALIGN(dma_rxsize);
@@ -1632,28 +1716,14 @@ static int stmmac_open(struct net_device *dev)
 		goto dma_desc_error;
 	}
 
-	ret = init_dma_desc_rings(dev);
+	ret = stmmac_hw_setup(dev);
 	if (ret < 0) {
-		pr_err("%s: DMA descriptors initialization failed\n", __func__);
-		goto dma_desc_error;
-	}
-
-	/* DMA initialization and SW reset */
-	ret = stmmac_init_dma_engine(priv);
-	if (ret < 0) {
-		pr_err("%s: DMA engine initialization failed\n", __func__);
+		pr_err("%s: Hw setup failed\n", __func__);
 		goto init_error;
 	}
 
-	/* Copy the MAC addr into the HW  */
-	priv->hw->mac->set_umac_addr(priv->ioaddr, dev->dev_addr, 0);
-
-	/* If required, perform hw setup of the bus. */
-	if (priv->plat->bus_setup)
-		priv->plat->bus_setup(priv->ioaddr);
-
-	/* Initialize the MAC Core */
-	priv->hw->mac->core_init(priv->ioaddr);
+	if (priv->phydev)
+		phy_start(priv->phydev);
 
 	/* Request the IRQ lines */
 	ret = request_irq(dev->irq, stmmac_interrupt,
@@ -1686,55 +1756,6 @@ static int stmmac_open(struct net_device *dev)
 		}
 	}
 
-	/* Enable the MAC Rx/Tx */
-	stmmac_set_mac(priv->ioaddr, true);
-
-	/* Set the HW DMA mode and the COE */
-	stmmac_dma_operation_mode(priv);
-
-	/* Extra statistics */
-	memset(&priv->xstats, 0, sizeof(struct stmmac_extra_stats));
-	priv->xstats.threshold = tc;
-
-	stmmac_mmc_setup(priv);
-
-	ret = stmmac_init_ptp(priv);
-	if (ret)
-		pr_warn("%s: failed PTP initialisation\n", __func__);
-
-#ifdef CONFIG_STMMAC_DEBUG_FS
-	ret = stmmac_init_fs(dev);
-	if (ret < 0)
-		pr_warn("%s: failed debugFS registration\n", __func__);
-#endif
-	/* Start the ball rolling... */
-	pr_debug("%s: DMA RX/TX processes started...\n", dev->name);
-	priv->hw->dma->start_tx(priv->ioaddr);
-	priv->hw->dma->start_rx(priv->ioaddr);
-
-	/* Dump DMA/MAC registers */
-	if (netif_msg_hw(priv)) {
-		priv->hw->mac->dump_regs(priv->ioaddr);
-		priv->hw->dma->dump_regs(priv->ioaddr);
-	}
-
-	if (priv->phydev)
-		phy_start(priv->phydev);
-
-	priv->tx_lpi_timer = STMMAC_DEFAULT_TWT_LS;
-
-	priv->eee_enabled = stmmac_eee_init(priv);
-
-	stmmac_init_tx_coalesce(priv);
-
-	if ((priv->use_riwt) && (priv->hw->dma->rx_watchdog)) {
-		priv->rx_riwt = MAX_DMA_RIWT;
-		priv->hw->dma->rx_watchdog(priv->ioaddr, MAX_DMA_RIWT);
-	}
-
-	if (priv->pcs && priv->hw->mac->ctrl_ane)
-		priv->hw->mac->ctrl_ane(priv->ioaddr, 0);
-
 	napi_enable(&priv->napi);
 	netif_start_queue(dev);
 
-- 
1.7.6.5


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH RFC 5/9] net: stmmac: make stmmac_mdio_reset non-static
  2013-11-18 11:30 [PATCH RFC 0/9]net: stmmac PM related fixes srinivas.kandagatla
                   ` (3 preceding siblings ...)
  2013-11-18 11:32 ` [PATCH RFC 4/9] net: stmmac: move hardware setup for stmmac_open " srinivas.kandagatla
@ 2013-11-18 11:32 ` srinivas.kandagatla
  2013-11-18 11:32 ` [PATCH RFC 6/9] net: stmmac: fix power mangement suspend-resume case srinivas.kandagatla
                   ` (7 subsequent siblings)
  12 siblings, 0 replies; 28+ messages in thread
From: srinivas.kandagatla @ 2013-11-18 11:32 UTC (permalink / raw)
  To: Giuseppe Cavallaro, netdev; +Cc: linux-kernel, srinivas.kandagatla

From: Srinivas Kandagatla <srinivas.kandagatla@st.com>

This patch promotes stmmac_mdio_reset function from static to
non-static, so that power management functions can decide to reset if
the IP comes out from lowe power state specially hibernation cases.

Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@st.com>
---
 drivers/net/ethernet/stmicro/stmmac/stmmac.h      |    1 +
 drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c |    2 +-
 2 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac.h b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
index 22f89ff..8c3fed3 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac.h
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
@@ -112,6 +112,7 @@ extern int phyaddr;
 
 int stmmac_mdio_unregister(struct net_device *ndev);
 int stmmac_mdio_register(struct net_device *ndev);
+int stmmac_mdio_reset(struct mii_bus *mii);
 void stmmac_set_ethtool_ops(struct net_device *netdev);
 extern const struct stmmac_desc_ops enh_desc_ops;
 extern const struct stmmac_desc_ops ndesc_ops;
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c
index aab12d2..a468eb1 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c
@@ -128,7 +128,7 @@ static int stmmac_mdio_write(struct mii_bus *bus, int phyaddr, int phyreg,
  * @bus: points to the mii_bus structure
  * Description: reset the MII bus
  */
-static int stmmac_mdio_reset(struct mii_bus *bus)
+int stmmac_mdio_reset(struct mii_bus *bus)
 {
 #if defined(CONFIG_STMMAC_PLATFORM)
 	struct net_device *ndev = bus->priv;
-- 
1.7.6.5


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH RFC 6/9] net: stmmac: fix power mangement suspend-resume case
  2013-11-18 11:30 [PATCH RFC 0/9]net: stmmac PM related fixes srinivas.kandagatla
                   ` (4 preceding siblings ...)
  2013-11-18 11:32 ` [PATCH RFC 5/9] net: stmmac: make stmmac_mdio_reset non-static srinivas.kandagatla
@ 2013-11-18 11:32 ` srinivas.kandagatla
  2013-11-18 11:32 ` [PATCH RFC 7/9] net: stmmac: use suspend functions for hibernation srinivas.kandagatla
                   ` (6 subsequent siblings)
  12 siblings, 0 replies; 28+ messages in thread
From: srinivas.kandagatla @ 2013-11-18 11:32 UTC (permalink / raw)
  To: Giuseppe Cavallaro, netdev; +Cc: linux-kernel, srinivas.kandagatla

From: Srinivas Kandagatla <srinivas.kandagatla@st.com>

The driver PM resume assumes that the IP is still powered up and the
all the register contents are not disturbed when it comes out of low
power suspend case. This assumption is wrong, basically the driver
should not consider any state of registers after it comes out of low
power. However driver can keep the part of the IP powered up if its a
wake up source. But it can not assume the register state of the IP. Also
its possible that SOC glue layer can take the power off the IP if its
not wake-up source to reduce the power consumption.

This patch re initializes hardware by calling stmmac_hw_setup function in
resume case.

Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@st.com>
---
 drivers/net/ethernet/stmicro/stmmac/stmmac_main.c |   12 ++++++------
 1 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index ea34ebc..3b0c18a 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -2876,18 +2876,18 @@ int stmmac_resume(struct net_device *ndev)
 	 * this bit because it can generate problems while resuming
 	 * 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);
-	else
+	} else {
 		/* enable the clk prevously disabled */
 		clk_prepare_enable(priv->stmmac_clk);
+		/* reset the phy so that it's ready */
+		stmmac_mdio_reset(priv->mii);
+	}
 
 	netif_device_attach(ndev);
 
-	/* Enable the MAC and DMA */
-	stmmac_set_mac(priv->ioaddr, true);
-	priv->hw->dma->start_tx(priv->ioaddr);
-	priv->hw->dma->start_rx(priv->ioaddr);
+	stmmac_hw_setup(ndev);
 
 	napi_enable(&priv->napi);
 
-- 
1.7.6.5


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH RFC 7/9] net: stmmac: use suspend functions for hibernation
  2013-11-18 11:30 [PATCH RFC 0/9]net: stmmac PM related fixes srinivas.kandagatla
                   ` (5 preceding siblings ...)
  2013-11-18 11:32 ` [PATCH RFC 6/9] net: stmmac: fix power mangement suspend-resume case srinivas.kandagatla
@ 2013-11-18 11:32 ` srinivas.kandagatla
  2013-11-18 11:32 ` [PATCH RFC 8/9] net: stmmac: restore pinstate in pm resume srinivas.kandagatla
                   ` (5 subsequent siblings)
  12 siblings, 0 replies; 28+ messages in thread
From: srinivas.kandagatla @ 2013-11-18 11:32 UTC (permalink / raw)
  To: Giuseppe Cavallaro, netdev; +Cc: linux-kernel, srinivas.kandagatla

From: Srinivas Kandagatla <srinivas.kandagatla@st.com>

In hibernation freeze case the driver just releases the resources like
dma buffers, irqs, unregisters the drivers and during restore it does
register, request the resources. This is not really necessary, as part
of power management all the data structures are intact, all the
previously allocated resources can be used after coming out of low
power.

This patch uses the suspend and resume callbacks for freeze and
restore which initializes the hardware correctly without unregistering
or releasing the resources, this should also help in reducing the time
to restore.

Also this patch fixes a bug in stmmac_pltfr_restore and
stmmac_pltfr_freeze where it tries to get hold of platform data via
dev_get_platdata call, which would return NULL in device tree cases and
the next if statement would crash as there is no NULL check.

Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@st.com>
---
 drivers/net/ethernet/stmicro/stmmac/stmmac.h       |    2 -
 drivers/net/ethernet/stmicro/stmmac/stmmac_main.c  |   16 -------
 .../net/ethernet/stmicro/stmmac/stmmac_platform.c  |   47 +++++--------------
 3 files changed, 13 insertions(+), 52 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac.h b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
index 8c3fed3..90350e9 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac.h
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
@@ -119,8 +119,6 @@ extern const struct stmmac_desc_ops ndesc_ops;
 extern const struct stmmac_hwtimestamp stmmac_ptp;
 int stmmac_ptp_register(struct stmmac_priv *priv);
 void stmmac_ptp_unregister(struct stmmac_priv *priv);
-int stmmac_freeze(struct net_device *ndev);
-int stmmac_restore(struct net_device *ndev);
 int stmmac_resume(struct net_device *ndev);
 int stmmac_suspend(struct net_device *ndev);
 int stmmac_dvr_remove(struct net_device *ndev);
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index 3b0c18a..5b4bd7d 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -2900,22 +2900,6 @@ int stmmac_resume(struct net_device *ndev)
 
 	return 0;
 }
-
-int stmmac_freeze(struct net_device *ndev)
-{
-	if (!ndev || !netif_running(ndev))
-		return 0;
-
-	return stmmac_release(ndev);
-}
-
-int stmmac_restore(struct net_device *ndev)
-{
-	if (!ndev || !netif_running(ndev))
-		return 0;
-
-	return stmmac_open(ndev);
-}
 #endif /* CONFIG_PM */
 
 /* Driver can be configured w/ and w/ both PCI and Platf drivers
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
index 3073c50..6bdda55 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
@@ -209,57 +209,36 @@ static int stmmac_pltfr_remove(struct platform_device *pdev)
 }
 
 #ifdef CONFIG_PM
-static int stmmac_pltfr_suspend(struct device *dev)
-{
-	struct net_device *ndev = dev_get_drvdata(dev);
-
-	return stmmac_suspend(ndev);
-}
-
-static int stmmac_pltfr_resume(struct device *dev)
-{
-	struct net_device *ndev = dev_get_drvdata(dev);
-
-	return stmmac_resume(ndev);
-}
-
-int stmmac_pltfr_freeze(struct device *dev)
+int stmmac_pltfr_suspend(struct device *dev)
 {
 	int ret;
-	struct plat_stmmacenet_data *plat_dat = dev_get_platdata(dev);
 	struct net_device *ndev = dev_get_drvdata(dev);
+	struct stmmac_priv *priv = netdev_priv(ndev);
 	struct platform_device *pdev = to_platform_device(dev);
 
-	ret = stmmac_freeze(ndev);
-	if (plat_dat->exit)
-		plat_dat->exit(pdev);
+	ret = stmmac_suspend(ndev);
+	if (priv->plat->exit)
+		priv->plat->exit(pdev);
 
 	return ret;
 }
 
-int stmmac_pltfr_restore(struct device *dev)
+int stmmac_pltfr_resume(struct device *dev)
 {
-	struct plat_stmmacenet_data *plat_dat = dev_get_platdata(dev);
 	struct net_device *ndev = dev_get_drvdata(dev);
+	struct stmmac_priv *priv = netdev_priv(ndev);
 	struct platform_device *pdev = to_platform_device(dev);
 
-	if (plat_dat->init)
-		plat_dat->init(pdev);
+	if (priv->plat->init)
+		priv->plat->init(pdev);
 
-	return stmmac_restore(ndev);
+	return stmmac_resume(ndev);
 }
-
-static const struct dev_pm_ops stmmac_pltfr_pm_ops = {
-	.suspend = stmmac_pltfr_suspend,
-	.resume = stmmac_pltfr_resume,
-	.freeze = stmmac_pltfr_freeze,
-	.thaw = stmmac_pltfr_restore,
-	.restore = stmmac_pltfr_restore,
-};
-#else
-static const struct dev_pm_ops stmmac_pltfr_pm_ops;
 #endif /* CONFIG_PM */
 
+static SIMPLE_DEV_PM_OPS(stmmac_pltfr_pm_ops,
+			stmmac_pltfr_suspend, stmmac_pltfr_resume);
+
 static const struct of_device_id stmmac_dt_ids[] = {
 	{ .compatible = "st,spear600-gmac"},
 	{ .compatible = "snps,dwmac-3.610"},
-- 
1.7.6.5


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH RFC 8/9] net: stmmac: restore pinstate in pm resume.
  2013-11-18 11:30 [PATCH RFC 0/9]net: stmmac PM related fixes srinivas.kandagatla
                   ` (6 preceding siblings ...)
  2013-11-18 11:32 ` [PATCH RFC 7/9] net: stmmac: use suspend functions for hibernation srinivas.kandagatla
@ 2013-11-18 11:32 ` srinivas.kandagatla
  2013-11-18 11:32 ` [PATCH RFC 9/9] net: stmmac: notify the PM core of a wakeup event srinivas.kandagatla
                   ` (4 subsequent siblings)
  12 siblings, 0 replies; 28+ messages in thread
From: srinivas.kandagatla @ 2013-11-18 11:32 UTC (permalink / raw)
  To: Giuseppe Cavallaro, netdev; +Cc: linux-kernel, srinivas.kandagatla

From: Srinivas Kandagatla <srinivas.kandagatla@st.com>

This patch adds code to restore default pinstate of the pins when it
comes back from low power state. Without this patch the state of the
pins would be unknown and the driver would not work.

This patch also adds code to put the pins in to sleep state when the
driver enters low power state.

Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@st.com>
---
 drivers/net/ethernet/stmicro/stmmac/stmmac_main.c |    3 +++
 1 files changed, 3 insertions(+), 0 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index 5b4bd7d..c0b5716 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -43,6 +43,7 @@
 #include <linux/dma-mapping.h>
 #include <linux/slab.h>
 #include <linux/prefetch.h>
+#include <linux/pinctrl/consumer.h>
 #ifdef CONFIG_STMMAC_DEBUG_FS
 #include <linux/debugfs.h>
 #include <linux/seq_file.h>
@@ -2853,6 +2854,7 @@ int stmmac_suspend(struct net_device *ndev)
 		priv->hw->mac->pmt(priv->ioaddr, priv->wolopts);
 	else {
 		stmmac_set_mac(priv->ioaddr, false);
+		pinctrl_pm_select_sleep_state(priv->device);
 		/* Disable clock in case of PWM is off */
 		clk_disable_unprepare(priv->stmmac_clk);
 	}
@@ -2879,6 +2881,7 @@ int stmmac_resume(struct net_device *ndev)
 	if (device_may_wakeup(priv->device)) {
 		priv->hw->mac->pmt(priv->ioaddr, 0);
 	} else {
+		pinctrl_pm_select_default_state(priv->device);
 		/* enable the clk prevously disabled */
 		clk_prepare_enable(priv->stmmac_clk);
 		/* reset the phy so that it's ready */
-- 
1.7.6.5


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH RFC 9/9] net: stmmac: notify the PM core of a wakeup event.
  2013-11-18 11:30 [PATCH RFC 0/9]net: stmmac PM related fixes srinivas.kandagatla
                   ` (7 preceding siblings ...)
  2013-11-18 11:32 ` [PATCH RFC 8/9] net: stmmac: restore pinstate in pm resume srinivas.kandagatla
@ 2013-11-18 11:32 ` srinivas.kandagatla
  2013-11-19  5:24 ` [PATCH RFC 0/9]net: stmmac PM related fixes Giuseppe CAVALLARO
                   ` (3 subsequent siblings)
  12 siblings, 0 replies; 28+ messages in thread
From: srinivas.kandagatla @ 2013-11-18 11:32 UTC (permalink / raw)
  To: Giuseppe Cavallaro, netdev; +Cc: linux-kernel, srinivas.kandagatla

From: Srinivas Kandagatla <srinivas.kandagatla@st.com>

In PM_SUSPEND_FREEZE and WOL(Wakeup On Lan) case, when the driver gets a
wakeup event, either the driver or platform specific PM code should notify
the pm core about it, so that the system can wakeup from low power.

In cases where there is no involvement of platform specific PM, it
becomes driver responsibility to notify the PM core to wakeup the
system.

Without this WOL with PM_SUSPEND_FREEZE does not work on STi based SOCs.

Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@st.com>
---
 drivers/net/ethernet/stmicro/stmmac/stmmac.h      |    1 +
 drivers/net/ethernet/stmicro/stmmac/stmmac_main.c |    9 +++++++--
 2 files changed, 8 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac.h b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
index 90350e9..de9f95c 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac.h
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
@@ -105,6 +105,7 @@ struct stmmac_priv {
 	unsigned int default_addend;
 	u32 adv_ts;
 	int use_riwt;
+	int irq_wake;
 	spinlock_t ptp_lock;
 };
 
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index c0b5716..2d5eea7 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -2309,6 +2309,9 @@ static irqreturn_t stmmac_interrupt(int irq, void *dev_id)
 	struct net_device *dev = (struct net_device *)dev_id;
 	struct stmmac_priv *priv = netdev_priv(dev);
 
+	if (priv->irq_wake)
+		pm_wakeup_event(priv->device, 0);
+
 	if (unlikely(!dev)) {
 		pr_err("%s: invalid dev pointer\n", __func__);
 		return IRQ_NONE;
@@ -2850,9 +2853,10 @@ int stmmac_suspend(struct net_device *ndev)
 	stmmac_clear_descriptors(priv);
 
 	/* 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);
-	else {
+		priv->irq_wake = 1;
+	} else {
 		stmmac_set_mac(priv->ioaddr, false);
 		pinctrl_pm_select_sleep_state(priv->device);
 		/* Disable clock in case of PWM is off */
@@ -2880,6 +2884,7 @@ int stmmac_resume(struct net_device *ndev)
 	 */
 	if (device_may_wakeup(priv->device)) {
 		priv->hw->mac->pmt(priv->ioaddr, 0);
+		priv->irq_wake = 0;
 	} else {
 		pinctrl_pm_select_default_state(priv->device);
 		/* enable the clk prevously disabled */
-- 
1.7.6.5


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* Re: [PATCH RFC 0/9]net: stmmac PM related fixes.
  2013-11-18 11:30 [PATCH RFC 0/9]net: stmmac PM related fixes srinivas.kandagatla
                   ` (8 preceding siblings ...)
  2013-11-18 11:32 ` [PATCH RFC 9/9] net: stmmac: notify the PM core of a wakeup event srinivas.kandagatla
@ 2013-11-19  5:24 ` Giuseppe CAVALLARO
  2013-11-19  9:03   ` srinivas kandagatla
  2013-12-02 10:48   ` srinivas kandagatla
  2014-01-14 10:05 ` srinivas kandagatla
                   ` (2 subsequent siblings)
  12 siblings, 2 replies; 28+ messages in thread
From: Giuseppe CAVALLARO @ 2013-11-19  5:24 UTC (permalink / raw)
  To: srinivas.kandagatla; +Cc: netdev, linux-kernel

On 11/18/2013 12:30 PM, srinivas.kandagatla@st.com wrote:
> From: Srinivas Kandagatla <srinivas.kandagatla@st.com>
>
> Hi Peppe,
>
> During PM_SUSPEND_FREEZE testing, I have noticed that PM support in STMMAC is
> partly broken. I had to re-arrange the code to do PM correctly. There were lot
> of things I did not like personally and some bits did not work in the first
> place. I thought this is the nice opportunity to clean the mess up.
>
> Here is what I did:
>
> 1> Test PM suspend freeeze via pm_test
> It did not work for following reasons.
>   - If the power to gmac is removed when it enters in low power state.
> stmmac_resume could not cope up with such behaviour, it was expecting the ip
> register contents to be still same as before entering low power, This
> assumption is wrong. So I started to add some code to do Hardware
> initialization, thats when I started to re-arrange the code. stmmac_open
> contains both resource and memory allocations and hardware initialization. I
> had to separate these two things in two different functions.
>
> These two patches do that
>    net: stmmac: move dma allocation to new function
>    net: stmmac: move hardware setup for stmmac_open to new function
>
> And rest of the other patches are fixing the loose ends, things like mdio
> reset, which might be necessary in cases likes hibernation(I did not test).
>
> In hibernation cases the driver was just unregistering with subsystems and
> releasing resources which I did not like and its not necessary to do this as
> part of PM. So using the same stmmac_suspend/resume made more sense for
> hibernation cases than using stmmac_open/release.
> Also fixed a NULL pointer dereference bug too.
>
> 2> Test WOL via PM_SUSPEND_FREEZE
> Did get an wakeup interrupt, but could not wakeup a freeze system.
> So I had to add pm_wakeup_event to the driver.
> net: stmmac: notify the PM core of a wakeup event. patch.
>
> Also few patches like
>    net: stmmac: make stmmac_mdio_reset non-static
>    net: stmmac: restore pinstate in pm resume.
> helps the resume function to reset the phy and put back the pins in default
> state.
>
> Comments?

Srini, as we had internally discussed before sending the patches to the
net ML, I agreed with your work. Some parts of the PM stuff was fully
tested on our product kernels (where the PM was a bit different
especially on HoM) and nobody raised issues to me for this code.
Also some rework you did, for example to move the dma allocation in
a new function is fine for me.

So you continue to have my Acked-by for all.

peppe

>
> Thanks,
> srini
>
> Srinivas Kandagatla (9):
>    net: stmmac: support max-speed device tree property
>    net: stmmac: mdio: remove reset gpio free
>    net: stmmac: move dma allocation to new function
>    net: stmmac: move hardware setup for stmmac_open to new function
>    net: stmmac: make stmmac_mdio_reset non-static
>    net: stmmac: fix power mangement suspend-resume case
>    net: stmmac: use suspend functions for hibernation
>    net: stmmac: restore pinstate in pm resume.
>    net: stmmac: notify the PM core of a wakeup event.
>
>   drivers/net/ethernet/stmicro/stmmac/stmmac.h       |    4 +-
>   drivers/net/ethernet/stmicro/stmmac/stmmac_main.c  |  360 ++++++++++----------
>   drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c  |    3 +-
>   .../net/ethernet/stmicro/stmmac/stmmac_platform.c  |   51 +--
>   include/linux/stmmac.h                             |    1 +
>   5 files changed, 209 insertions(+), 210 deletions(-)
>


^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH RFC 0/9]net: stmmac PM related fixes.
  2013-11-19  5:24 ` [PATCH RFC 0/9]net: stmmac PM related fixes Giuseppe CAVALLARO
@ 2013-11-19  9:03   ` srinivas kandagatla
  2013-12-02 10:48   ` srinivas kandagatla
  1 sibling, 0 replies; 28+ messages in thread
From: srinivas kandagatla @ 2013-11-19  9:03 UTC (permalink / raw)
  To: Giuseppe CAVALLARO; +Cc: netdev, linux-kernel

On 19/11/13 05:24, Giuseppe CAVALLARO wrote:
> 
> So you continue to have my Acked-by for all.
> 

Thanks for the Ack Peppe.
> peppe


^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH RFC 0/9]net: stmmac PM related fixes.
  2013-11-19  5:24 ` [PATCH RFC 0/9]net: stmmac PM related fixes Giuseppe CAVALLARO
  2013-11-19  9:03   ` srinivas kandagatla
@ 2013-12-02 10:48   ` srinivas kandagatla
  2013-12-02 16:18     ` David Miller
  1 sibling, 1 reply; 28+ messages in thread
From: srinivas kandagatla @ 2013-12-02 10:48 UTC (permalink / raw)
  To: Giuseppe CAVALLARO; +Cc: netdev, linux-kernel, David Miller

Hi Dave,
Do you have any plans to take this series?

Peppe already Acked these series

Please let me know if you want me to rebase these patches on any
particular branch.

Thanks,
srini

On 19/11/13 05:24, Giuseppe CAVALLARO wrote:
> On 11/18/2013 12:30 PM, srinivas.kandagatla@st.com wrote:
>> From: Srinivas Kandagatla <srinivas.kandagatla@st.com>
>>
>> Hi Peppe,
>>
>> During PM_SUSPEND_FREEZE testing, I have noticed that PM support in
>> STMMAC is
>> partly broken. I had to re-arrange the code to do PM correctly. There
>> were lot
>> of things I did not like personally and some bits did not work in the
>> first
>> place. I thought this is the nice opportunity to clean the mess up.
>>
>> Here is what I did:
>>
>> 1> Test PM suspend freeeze via pm_test
>> It did not work for following reasons.
>>   - If the power to gmac is removed when it enters in low power state.
>> stmmac_resume could not cope up with such behaviour, it was expecting
>> the ip
>> register contents to be still same as before entering low power, This
>> assumption is wrong. So I started to add some code to do Hardware
>> initialization, thats when I started to re-arrange the code. stmmac_open
>> contains both resource and memory allocations and hardware
>> initialization. I
>> had to separate these two things in two different functions.
>>
>> These two patches do that
>>    net: stmmac: move dma allocation to new function
>>    net: stmmac: move hardware setup for stmmac_open to new function
>>
>> And rest of the other patches are fixing the loose ends, things like mdio
>> reset, which might be necessary in cases likes hibernation(I did not
>> test).
>>
>> In hibernation cases the driver was just unregistering with subsystems
>> and
>> releasing resources which I did not like and its not necessary to do
>> this as
>> part of PM. So using the same stmmac_suspend/resume made more sense for
>> hibernation cases than using stmmac_open/release.
>> Also fixed a NULL pointer dereference bug too.
>>
>> 2> Test WOL via PM_SUSPEND_FREEZE
>> Did get an wakeup interrupt, but could not wakeup a freeze system.
>> So I had to add pm_wakeup_event to the driver.
>> net: stmmac: notify the PM core of a wakeup event. patch.
>>
>> Also few patches like
>>    net: stmmac: make stmmac_mdio_reset non-static
>>    net: stmmac: restore pinstate in pm resume.
>> helps the resume function to reset the phy and put back the pins in
>> default
>> state.
>>
>> Comments?
> 
> Srini, as we had internally discussed before sending the patches to the
> net ML, I agreed with your work. Some parts of the PM stuff was fully
> tested on our product kernels (where the PM was a bit different
> especially on HoM) and nobody raised issues to me for this code.
> Also some rework you did, for example to move the dma allocation in
> a new function is fine for me.
> 
> So you continue to have my Acked-by for all.
> 
> peppe
> 
>>
>> Thanks,
>> srini
>>
>> Srinivas Kandagatla (9):
>>    net: stmmac: support max-speed device tree property
>>    net: stmmac: mdio: remove reset gpio free
>>    net: stmmac: move dma allocation to new function
>>    net: stmmac: move hardware setup for stmmac_open to new function
>>    net: stmmac: make stmmac_mdio_reset non-static
>>    net: stmmac: fix power mangement suspend-resume case
>>    net: stmmac: use suspend functions for hibernation
>>    net: stmmac: restore pinstate in pm resume.
>>    net: stmmac: notify the PM core of a wakeup event.
>>
>>   drivers/net/ethernet/stmicro/stmmac/stmmac.h       |    4 +-
>>   drivers/net/ethernet/stmicro/stmmac/stmmac_main.c  |  360
>> ++++++++++----------
>>   drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c  |    3 +-
>>   .../net/ethernet/stmicro/stmmac/stmmac_platform.c  |   51 +--
>>   include/linux/stmmac.h                             |    1 +
>>   5 files changed, 209 insertions(+), 210 deletions(-)
>>
> 
> 
> 


^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH RFC 0/9]net: stmmac PM related fixes.
  2013-12-02 10:48   ` srinivas kandagatla
@ 2013-12-02 16:18     ` David Miller
  0 siblings, 0 replies; 28+ messages in thread
From: David Miller @ 2013-12-02 16:18 UTC (permalink / raw)
  To: srinivas.kandagatla; +Cc: peppe.cavallaro, netdev, linux-kernel

From: srinivas kandagatla <srinivas.kandagatla@st.com>
Date: Mon, 2 Dec 2013 10:48:32 +0000

> Do you have any plans to take this series?

They aren't queued up in "Under Review" state in patchwork, so no.

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH RFC 0/9]net: stmmac PM related fixes.
  2013-11-18 11:30 [PATCH RFC 0/9]net: stmmac PM related fixes srinivas.kandagatla
                   ` (9 preceding siblings ...)
  2013-11-19  5:24 ` [PATCH RFC 0/9]net: stmmac PM related fixes Giuseppe CAVALLARO
@ 2014-01-14 10:05 ` srinivas kandagatla
  2014-01-15 21:49   ` David Miller
  2014-01-16 10:48 ` [PATCH v2 0/9] net: " srinivas.kandagatla
  2014-01-16 10:50 ` srinivas.kandagatla
  12 siblings, 1 reply; 28+ messages in thread
From: srinivas kandagatla @ 2014-01-14 10:05 UTC (permalink / raw)
  To: srinivas.kandagatla, Giuseppe Cavallaro, David Miller
  Cc: netdev, linux-kernel

Hi Dave/Peppe,
Do you have any plans to take this series?

Peppe already Acked these series.

Please let me know if you want me to rebase these patches to a
particular branch.

Thanks,
srini

On 18/11/13 11:30, srinivas.kandagatla@st.com wrote:
> From: Srinivas Kandagatla <srinivas.kandagatla@st.com>
> 
> Hi Peppe,
> 
> During PM_SUSPEND_FREEZE testing, I have noticed that PM support in STMMAC is
> partly broken. I had to re-arrange the code to do PM correctly. There were lot
> of things I did not like personally and some bits did not work in the first
> place. I thought this is the nice opportunity to clean the mess up.
> 
> Here is what I did:
>  any
> 1> Test PM suspend freeeze via pm_test
> It did not work for following reasons.
>  - If the power to gmac is removed when it enters in low power state.
> stmmac_resume could not cope up with such behaviour, it was expecting the ip
> register contents to be still same as before entering low power, This
> assumption is wrong. So I started to add some code to do Hardware
> initialization, thats when I started to re-arrange the code. stmmac_open
> contains both resource and memory allocations and hardware initialization. I
> had to separate these two things in two different functions.
> 
> These two patches do that
>   net: stmmac: move dma allocation to new function
>   net: stmmac: move hardware setup for stmmac_open to new function
> 
> And rest of the other patches are fixing the loose ends, things like mdio
> reset, which might be necessary in cases likes hibernation(I did not test).
> 
> In hibernation cases the driver was just unregistering with subsystems and
> releasing resources which I did not like and its not necessary to do this as
> part of PM. So using the same stmmac_suspend/resume made more sense for
> hibernation cases than using stmmac_open/release.
> Also fixed a NULL pointer dereference bug too.
> 
> 2> Test WOL via PM_SUSPEND_FREEZE
> Did get an wakeup interrupt, but could not wakeup a freeze system.
> So I had to add pm_wakeup_event to the driver.
> net: stmmac: notify the PM core of a wakeup event. patch.
> 
> Also few patches like 
>   net: stmmac: make stmmac_mdio_reset non-static
>   net: stmmac: restore pinstate in pm resume.
> helps the resume function to reset the phy and put back the pins in default
> state.
> 
> Comments?
> 
> Thanks,
> srini
> 
> Srinivas Kandagatla (9):
>   net: stmmac: support max-speed device tree property
>   net: stmmac: mdio: remove reset gpio free
>   net: stmmac: move dma allocation to new function
>   net: stmmac: move hardware setup for stmmac_open to new function
>   net: stmmac: make stmmac_mdio_reset non-static
>   net: stmmac: fix power mangement suspend-resume case
>   net: stmmac: use suspend functions for hibernation
>   net: stmmac: restore pinstate in pm resume.
>   net: stmmac: notify the PM core of a wakeup event.
> 
>  drivers/net/ethernet/stmicro/stmmac/stmmac.h       |    4 +-
>  drivers/net/ethernet/stmicro/stmmac/stmmac_main.c  |  360 ++++++++++----------
>  drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c  |    3 +-
>  .../net/ethernet/stmicro/stmmac/stmmac_platform.c  |   51 +--
>  include/linux/stmmac.h                             |    1 +
>  5 files changed, 209 insertions(+), 210 deletions(-)
> 


^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH RFC 0/9]net: stmmac PM related fixes.
  2014-01-14 10:05 ` srinivas kandagatla
@ 2014-01-15 21:49   ` David Miller
  0 siblings, 0 replies; 28+ messages in thread
From: David Miller @ 2014-01-15 21:49 UTC (permalink / raw)
  To: srinivas.kandagatla; +Cc: peppe.cavallaro, netdev, linux-kernel

From: srinivas kandagatla <srinivas.kandagatla@st.com>
Date: Tue, 14 Jan 2014 10:05:54 +0000

> Do you have any plans to take this series?
> 
> Peppe already Acked these series.
> 
> Please let me know if you want me to rebase these patches to a
> particular branch.

Please respin them against net-next and be sure to include Peppe's
ACKs.

^ permalink raw reply	[flat|nested] 28+ messages in thread

* [PATCH v2 0/9] net: stmmac PM related fixes.
  2013-11-18 11:30 [PATCH RFC 0/9]net: stmmac PM related fixes srinivas.kandagatla
                   ` (10 preceding siblings ...)
  2014-01-14 10:05 ` srinivas kandagatla
@ 2014-01-16 10:48 ` srinivas.kandagatla
  2014-01-16 23:24   ` David Miller
  2014-01-16 10:50 ` srinivas.kandagatla
  12 siblings, 1 reply; 28+ messages in thread
From: srinivas.kandagatla @ 2014-01-16 10:48 UTC (permalink / raw)
  To: netdev; +Cc: Giuseppe CAVALLARO, linux-kernel, srinivas.kandagatla

From: Srinivas Kandagatla <srinivas.kandagatla@st.com>

Hi Peppe/Dave,

During PM_SUSPEND_FREEZE testing, I have noticed that PM support in STMMAC is
partly broken. I had to re-arrange the code to do PM correctly. There were lot
of things I did not like personally and some bits did not work in the first
place. I thought this is the nice opportunity to clean the mess up.

Here is what I did:
 any
1> Test PM suspend freeze via pm_test
It did not work for following reasons.
 - If the power to gmac is removed when it enters in low power state.
stmmac_resume could not cope up with such behaviour, it was expecting the ip
register contents to be still same as before entering low power, This
assumption is wrong. So I started to add some code to do Hardware
initialization, thats when I started to re-arrange the code. stmmac_open
contains both resource and memory allocations and hardware initialization. I
had to separate these two things in two different functions.

These two patches do that
  net: stmmac: move dma allocation to new function
  net: stmmac: move hardware setup for stmmac_open to new function

And rest of the other patches are fixing the loose ends, things like mdio
reset, which might be necessary in cases likes hibernation(I did not test).

In hibernation cases the driver was just unregistering with subsystems and
releasing resources which I did not like and its not necessary to do this as
part of PM. So using the same stmmac_suspend/resume made more sense for
hibernation cases than using stmmac_open/release.
Also fixed a NULL pointer dereference bug too.

2> Test WOL via PM_SUSPEND_FREEZE
Did get an wakeup interrupt, but could not wakeup a freeze system.
So I had to add pm_wakeup_event to the driver.
net: stmmac: notify the PM core of a wakeup event. patch.

Also few patches like 
  net: stmmac: make stmmac_mdio_reset non-static
  net: stmmac: restore pinstate in pm resume.
helps the resume function to reset the phy and put back the pins in default
state.

Changes since RFC:
	- Rebased to net-next on Dave's suggestion.

All these patches are Acked by Peppe.

Thanks,
srini

Srinivas Kandagatla (9):
  net: stmmac: support max-speed device tree property
  net: stmmac: mdio: remove reset gpio free
  net: stmmac: move dma allocation to new function
  net: stmmac: move hardware setup for stmmac_open to new function
  net: stmmac: make stmmac_mdio_reset non-static
  net: stmmac: fix power management suspend-resume case
  net: stmmac: use suspend functions for hibernation
  net: stmmac: restore pinstate in pm resume.
  net: stmmac: notify the PM core of a wakeup event.

 drivers/net/ethernet/stmicro/stmmac/stmmac.h       |    4 +-
 drivers/net/ethernet/stmicro/stmmac/stmmac_main.c  |  361 ++++++++++----------
 drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c  |    3 +-
 .../net/ethernet/stmicro/stmmac/stmmac_platform.c  |   48 +--
 include/linux/stmmac.h                             |    1 +
 5 files changed, 209 insertions(+), 208 deletions(-)

-- 
1.7.6.5


^ permalink raw reply	[flat|nested] 28+ messages in thread

* [PATCH v2 0/9] net: stmmac PM related fixes.
  2013-11-18 11:30 [PATCH RFC 0/9]net: stmmac PM related fixes srinivas.kandagatla
                   ` (11 preceding siblings ...)
  2014-01-16 10:48 ` [PATCH v2 0/9] net: " srinivas.kandagatla
@ 2014-01-16 10:50 ` srinivas.kandagatla
  2014-01-16 10:51   ` [PATCH v2 1/9] net: stmmac: support max-speed device tree property srinivas.kandagatla
                     ` (8 more replies)
  12 siblings, 9 replies; 28+ messages in thread
From: srinivas.kandagatla @ 2014-01-16 10:50 UTC (permalink / raw)
  To: netdev
  Cc: Giuseppe CAVALLARO, David Miller, linux-kernel, srinivas.kandagatla

From: Srinivas Kandagatla <srinivas.kandagatla@st.com>

Hi Peppe/Dave,

During PM_SUSPEND_FREEZE testing, I have noticed that PM support in STMMAC is
partly broken. I had to re-arrange the code to do PM correctly. There were lot
of things I did not like personally and some bits did not work in the first
place. I thought this is the nice opportunity to clean the mess up.

Here is what I did:
 any
1> Test PM suspend freeze via pm_test
It did not work for following reasons.
 - If the power to gmac is removed when it enters in low power state.
stmmac_resume could not cope up with such behaviour, it was expecting the ip
register contents to be still same as before entering low power, This
assumption is wrong. So I started to add some code to do Hardware
initialization, thats when I started to re-arrange the code. stmmac_open
contains both resource and memory allocations and hardware initialization. I
had to separate these two things in two different functions.

These two patches do that
  net: stmmac: move dma allocation to new function
  net: stmmac: move hardware setup for stmmac_open to new function

And rest of the other patches are fixing the loose ends, things like mdio
reset, which might be necessary in cases likes hibernation(I did not test).

In hibernation cases the driver was just unregistering with subsystems and
releasing resources which I did not like and its not necessary to do this as
part of PM. So using the same stmmac_suspend/resume made more sense for
hibernation cases than using stmmac_open/release.
Also fixed a NULL pointer dereference bug too.

2> Test WOL via PM_SUSPEND_FREEZE
Did get an wakeup interrupt, but could not wakeup a freeze system.
So I had to add pm_wakeup_event to the driver.
net: stmmac: notify the PM core of a wakeup event. patch.

Also few patches like 
  net: stmmac: make stmmac_mdio_reset non-static
  net: stmmac: restore pinstate in pm resume.
helps the resume function to reset the phy and put back the pins in default
state.

Changes since RFC:
	- Rebased to net-next on Dave's suggestion.

All these patches are Acked by Peppe.

Thanks,
srini

Srinivas Kandagatla (9):
  net: stmmac: support max-speed device tree property
  net: stmmac: mdio: remove reset gpio free
  net: stmmac: move dma allocation to new function
  net: stmmac: move hardware setup for stmmac_open to new function
  net: stmmac: make stmmac_mdio_reset non-static
  net: stmmac: fix power management suspend-resume case
  net: stmmac: use suspend functions for hibernation
  net: stmmac: restore pinstate in pm resume.
  net: stmmac: notify the PM core of a wakeup event.

 drivers/net/ethernet/stmicro/stmmac/stmmac.h       |    4 +-
 drivers/net/ethernet/stmicro/stmmac/stmmac_main.c  |  361 ++++++++++----------
 drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c  |    3 +-
 .../net/ethernet/stmicro/stmmac/stmmac_platform.c  |   48 +--
 include/linux/stmmac.h                             |    1 +
 5 files changed, 209 insertions(+), 208 deletions(-)

-- 
1.7.6.5


^ permalink raw reply	[flat|nested] 28+ messages in thread

* [PATCH v2 1/9] net: stmmac: support max-speed device tree property
  2014-01-16 10:50 ` srinivas.kandagatla
@ 2014-01-16 10:51   ` srinivas.kandagatla
  2014-01-16 10:51   ` [PATCH v2 2/9] net: stmmac: mdio: remove reset gpio free srinivas.kandagatla
                     ` (7 subsequent siblings)
  8 siblings, 0 replies; 28+ messages in thread
From: srinivas.kandagatla @ 2014-01-16 10:51 UTC (permalink / raw)
  To: netdev
  Cc: Giuseppe CAVALLARO, David Miller, linux-kernel, srinivas.kandagatla

From: Srinivas Kandagatla <srinivas.kandagatla@st.com>

This patch adds support to "max-speed" property which is a standard
Ethernet device tree property. max-speed specifies maximum speed
(specified in megabits per second) supported the device.

Depending on the clocking schemes some of the boards can only support
few link speeds, so having a way to limit the link speed in the mac
driver would allow such setups to work reliably.

Without this patch there is no way to tell the driver to limit the
link speed.

Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@st.com>
Acked-by: Giuseppe Cavallaro <peppe.cavallaro@st.com>
---
 drivers/net/ethernet/stmicro/stmmac/stmmac_main.c  |    4 +++-
 .../net/ethernet/stmicro/stmmac/stmmac_platform.c  |    4 ++++
 include/linux/stmmac.h                             |    1 +
 3 files changed, 8 insertions(+), 1 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index ecdc8ab..15192c0 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -776,6 +776,7 @@ static int stmmac_init_phy(struct net_device *dev)
 	char phy_id_fmt[MII_BUS_ID_SIZE + 3];
 	char bus_id[MII_BUS_ID_SIZE];
 	int interface = priv->plat->interface;
+	int max_speed = priv->plat->max_speed;
 	priv->oldlink = 0;
 	priv->speed = 0;
 	priv->oldduplex = -1;
@@ -800,7 +801,8 @@ static int stmmac_init_phy(struct net_device *dev)
 
 	/* Stop Advertising 1000BASE Capability if interface is not GMII */
 	if ((interface == PHY_INTERFACE_MODE_MII) ||
-	    (interface == PHY_INTERFACE_MODE_RMII))
+	    (interface == PHY_INTERFACE_MODE_RMII) ||
+		(max_speed < 1000 &&  max_speed > 0))
 		phydev->advertising &= ~(SUPPORTED_1000baseT_Half |
 					 SUPPORTED_1000baseT_Full);
 
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
index 38bd1f4..9377ee6 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
@@ -42,6 +42,10 @@ static int stmmac_probe_config_dt(struct platform_device *pdev,
 	*mac = of_get_mac_address(np);
 	plat->interface = of_get_phy_mode(np);
 
+	/* Get max speed of operation from device tree */
+	if (of_property_read_u32(np, "max-speed", &plat->max_speed))
+		plat->max_speed = -1;
+
 	plat->bus_id = of_alias_get_id(np, "ethernet");
 	if (plat->bus_id < 0)
 		plat->bus_id = 0;
diff --git a/include/linux/stmmac.h b/include/linux/stmmac.h
index bb5deb0..33ace71 100644
--- a/include/linux/stmmac.h
+++ b/include/linux/stmmac.h
@@ -110,6 +110,7 @@ struct plat_stmmacenet_data {
 	int force_sf_dma_mode;
 	int force_thresh_dma_mode;
 	int riwt_off;
+	int max_speed;
 	void (*fix_mac_speed)(void *priv, unsigned int speed);
 	void (*bus_setup)(void __iomem *ioaddr);
 	int (*init)(struct platform_device *pdev);
-- 
1.7.6.5


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH v2 2/9] net: stmmac: mdio: remove reset gpio free
  2014-01-16 10:50 ` srinivas.kandagatla
  2014-01-16 10:51   ` [PATCH v2 1/9] net: stmmac: support max-speed device tree property srinivas.kandagatla
@ 2014-01-16 10:51   ` srinivas.kandagatla
  2014-01-16 10:52   ` [PATCH v2 3/9] net: stmmac: move dma allocation to new function srinivas.kandagatla
                     ` (6 subsequent siblings)
  8 siblings, 0 replies; 28+ messages in thread
From: srinivas.kandagatla @ 2014-01-16 10:51 UTC (permalink / raw)
  To: netdev
  Cc: Giuseppe CAVALLARO, David Miller, linux-kernel, srinivas.kandagatla

From: Srinivas Kandagatla <srinivas.kandagatla@st.com>

This patch removes gpio_free for reset line of the phy, driver stores
the gpio number in its private data-structure to use in future. As the
driver uses this pin in future this pin should not be freed.

Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@st.com>
Acked-by: Giuseppe Cavallaro <peppe.cavallaro@st.com>
---
 drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c |    1 -
 1 files changed, 0 insertions(+), 1 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c
index fe7bc99..aab12d2 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c
@@ -166,7 +166,6 @@ static int stmmac_mdio_reset(struct mii_bus *bus)
 			udelay(data->delays[1]);
 			gpio_set_value(reset_gpio, active_low ? 1 : 0);
 			udelay(data->delays[2]);
-			gpio_free(reset_gpio);
 		}
 	}
 #endif
-- 
1.7.6.5


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH v2 3/9] net: stmmac: move dma allocation to new function
  2014-01-16 10:50 ` srinivas.kandagatla
  2014-01-16 10:51   ` [PATCH v2 1/9] net: stmmac: support max-speed device tree property srinivas.kandagatla
  2014-01-16 10:51   ` [PATCH v2 2/9] net: stmmac: mdio: remove reset gpio free srinivas.kandagatla
@ 2014-01-16 10:52   ` srinivas.kandagatla
  2014-01-16 10:52   ` [PATCH v2 4/9] net: stmmac: move hardware setup for stmmac_open " srinivas.kandagatla
                     ` (5 subsequent siblings)
  8 siblings, 0 replies; 28+ messages in thread
From: srinivas.kandagatla @ 2014-01-16 10:52 UTC (permalink / raw)
  To: netdev
  Cc: Giuseppe CAVALLARO, David Miller, linux-kernel, srinivas.kandagatla

From: Srinivas Kandagatla <srinivas.kandagatla@st.com>

This patch moves dma resource allocation to a new function
alloc_dma_desc_resources, the reason for moving this to a new function
is to keep the memory allocations in a separate function. One more reason
it to get suspend and hibernation cases working without releasing and
allocating these resources during suspend-resume and freeze-restore
cases.

Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@st.com>
Acked-by: Giuseppe Cavallaro <peppe.cavallaro@st.com>
---
 drivers/net/ethernet/stmicro/stmmac/stmmac_main.c |  169 +++++++++++----------
 1 files changed, 85 insertions(+), 84 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index 15192c0..532f2b4 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -996,66 +996,6 @@ static int init_dma_desc_rings(struct net_device *dev)
 		pr_debug("%s: txsize %d, rxsize %d, bfsize %d\n", __func__,
 			 txsize, rxsize, bfsize);
 
-	if (priv->extend_desc) {
-		priv->dma_erx = dma_alloc_coherent(priv->device, rxsize *
-						   sizeof(struct
-							  dma_extended_desc),
-						   &priv->dma_rx_phy,
-						   GFP_KERNEL);
-		if (!priv->dma_erx)
-			goto err_dma;
-
-		priv->dma_etx = dma_alloc_coherent(priv->device, txsize *
-						   sizeof(struct
-							  dma_extended_desc),
-						   &priv->dma_tx_phy,
-						   GFP_KERNEL);
-		if (!priv->dma_etx) {
-			dma_free_coherent(priv->device, priv->dma_rx_size *
-					sizeof(struct dma_extended_desc),
-					priv->dma_erx, priv->dma_rx_phy);
-			goto err_dma;
-		}
-	} else {
-		priv->dma_rx = dma_alloc_coherent(priv->device, rxsize *
-						  sizeof(struct dma_desc),
-						  &priv->dma_rx_phy,
-						  GFP_KERNEL);
-		if (!priv->dma_rx)
-			goto err_dma;
-
-		priv->dma_tx = dma_alloc_coherent(priv->device, txsize *
-						  sizeof(struct dma_desc),
-						  &priv->dma_tx_phy,
-						  GFP_KERNEL);
-		if (!priv->dma_tx) {
-			dma_free_coherent(priv->device, priv->dma_rx_size *
-					sizeof(struct dma_desc),
-					priv->dma_rx, priv->dma_rx_phy);
-			goto err_dma;
-		}
-	}
-
-	priv->rx_skbuff_dma = kmalloc_array(rxsize, sizeof(dma_addr_t),
-					    GFP_KERNEL);
-	if (!priv->rx_skbuff_dma)
-		goto err_rx_skbuff_dma;
-
-	priv->rx_skbuff = kmalloc_array(rxsize, sizeof(struct sk_buff *),
-					GFP_KERNEL);
-	if (!priv->rx_skbuff)
-		goto err_rx_skbuff;
-
-	priv->tx_skbuff_dma = kmalloc_array(txsize, sizeof(dma_addr_t),
-					    GFP_KERNEL);
-	if (!priv->tx_skbuff_dma)
-		goto err_tx_skbuff_dma;
-
-	priv->tx_skbuff = kmalloc_array(txsize, sizeof(struct sk_buff *),
-					GFP_KERNEL);
-	if (!priv->tx_skbuff)
-		goto err_tx_skbuff;
-
 	if (netif_msg_probe(priv)) {
 		pr_debug("(%s) dma_rx_phy=0x%08x dma_tx_phy=0x%08x\n", __func__,
 			 (u32) priv->dma_rx_phy, (u32) priv->dma_tx_phy);
@@ -1123,30 +1063,6 @@ static int init_dma_desc_rings(struct net_device *dev)
 err_init_rx_buffers:
 	while (--i >= 0)
 		stmmac_free_rx_buffers(priv, i);
-	kfree(priv->tx_skbuff);
-err_tx_skbuff:
-	kfree(priv->tx_skbuff_dma);
-err_tx_skbuff_dma:
-	kfree(priv->rx_skbuff);
-err_rx_skbuff:
-	kfree(priv->rx_skbuff_dma);
-err_rx_skbuff_dma:
-	if (priv->extend_desc) {
-		dma_free_coherent(priv->device, priv->dma_tx_size *
-				  sizeof(struct dma_extended_desc),
-				  priv->dma_etx, priv->dma_tx_phy);
-		dma_free_coherent(priv->device, priv->dma_rx_size *
-				  sizeof(struct dma_extended_desc),
-				  priv->dma_erx, priv->dma_rx_phy);
-	} else {
-		dma_free_coherent(priv->device,
-				priv->dma_tx_size * sizeof(struct dma_desc),
-				priv->dma_tx, priv->dma_tx_phy);
-		dma_free_coherent(priv->device,
-				priv->dma_rx_size * sizeof(struct dma_desc),
-				priv->dma_rx, priv->dma_rx_phy);
-	}
-err_dma:
 	return ret;
 }
 
@@ -1182,6 +1098,85 @@ static void dma_free_tx_skbufs(struct stmmac_priv *priv)
 	}
 }
 
+static int alloc_dma_desc_resources(struct stmmac_priv *priv)
+{
+	unsigned int txsize = priv->dma_tx_size;
+	unsigned int rxsize = priv->dma_rx_size;
+	int ret = -ENOMEM;
+
+	priv->rx_skbuff_dma = kmalloc_array(rxsize, sizeof(dma_addr_t),
+					    GFP_KERNEL);
+	if (!priv->rx_skbuff_dma)
+		return -ENOMEM;
+
+	priv->rx_skbuff = kmalloc_array(rxsize, sizeof(struct sk_buff *),
+					GFP_KERNEL);
+	if (!priv->rx_skbuff)
+		goto err_rx_skbuff;
+
+	priv->tx_skbuff_dma = kmalloc_array(txsize, sizeof(dma_addr_t),
+					    GFP_KERNEL);
+	if (!priv->tx_skbuff_dma)
+		goto err_tx_skbuff_dma;
+
+	priv->tx_skbuff = kmalloc_array(txsize, sizeof(struct sk_buff *),
+					GFP_KERNEL);
+	if (!priv->tx_skbuff)
+		goto err_tx_skbuff;
+
+	if (priv->extend_desc) {
+		priv->dma_erx = dma_alloc_coherent(priv->device, rxsize *
+						   sizeof(struct
+							  dma_extended_desc),
+						   &priv->dma_rx_phy,
+						   GFP_KERNEL);
+		if (!priv->dma_erx)
+			goto err_dma;
+
+		priv->dma_etx = dma_alloc_coherent(priv->device, txsize *
+						   sizeof(struct
+							  dma_extended_desc),
+						   &priv->dma_tx_phy,
+						   GFP_KERNEL);
+		if (!priv->dma_etx) {
+			dma_free_coherent(priv->device, priv->dma_rx_size *
+					sizeof(struct dma_extended_desc),
+					priv->dma_erx, priv->dma_rx_phy);
+			goto err_dma;
+		}
+	} else {
+		priv->dma_rx = dma_alloc_coherent(priv->device, rxsize *
+						  sizeof(struct dma_desc),
+						  &priv->dma_rx_phy,
+						  GFP_KERNEL);
+		if (!priv->dma_rx)
+			goto err_dma;
+
+		priv->dma_tx = dma_alloc_coherent(priv->device, txsize *
+						  sizeof(struct dma_desc),
+						  &priv->dma_tx_phy,
+						  GFP_KERNEL);
+		if (!priv->dma_tx) {
+			dma_free_coherent(priv->device, priv->dma_rx_size *
+					sizeof(struct dma_desc),
+					priv->dma_rx, priv->dma_rx_phy);
+			goto err_dma;
+		}
+	}
+
+	return 0;
+
+err_dma:
+	kfree(priv->tx_skbuff);
+err_tx_skbuff:
+	kfree(priv->tx_skbuff_dma);
+err_tx_skbuff_dma:
+	kfree(priv->rx_skbuff);
+err_rx_skbuff:
+	kfree(priv->rx_skbuff_dma);
+	return ret;
+}
+
 static void free_dma_desc_resources(struct stmmac_priv *priv)
 {
 	/* Release the DMA TX/RX socket buffers */
@@ -1623,6 +1618,12 @@ static int stmmac_open(struct net_device *dev)
 	priv->dma_rx_size = STMMAC_ALIGN(dma_rxsize);
 	priv->dma_buf_sz = STMMAC_ALIGN(buf_sz);
 
+	alloc_dma_desc_resources(priv);
+	if (ret < 0) {
+		pr_err("%s: DMA descriptors allocation failed\n", __func__);
+		goto dma_desc_error;
+	}
+
 	ret = init_dma_desc_rings(dev);
 	if (ret < 0) {
 		pr_err("%s: DMA descriptors initialization failed\n", __func__);
-- 
1.7.6.5


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH v2 4/9] net: stmmac: move hardware setup for stmmac_open to new function
  2014-01-16 10:50 ` srinivas.kandagatla
                     ` (2 preceding siblings ...)
  2014-01-16 10:52   ` [PATCH v2 3/9] net: stmmac: move dma allocation to new function srinivas.kandagatla
@ 2014-01-16 10:52   ` srinivas.kandagatla
  2014-01-16 10:52   ` [PATCH v2 5/9] net: stmmac: make stmmac_mdio_reset non-static srinivas.kandagatla
                     ` (4 subsequent siblings)
  8 siblings, 0 replies; 28+ messages in thread
From: srinivas.kandagatla @ 2014-01-16 10:52 UTC (permalink / raw)
  To: netdev
  Cc: Giuseppe CAVALLARO, David Miller, linux-kernel, srinivas.kandagatla

From: Srinivas Kandagatla <srinivas.kandagatla@st.com>

This patch moves hardware setup part of the code in stmmac_open to a new
function stmmac_hw_setup, the reason for doing this is to make hw
initialization independent function so that PM functions can re-use it to
re-initialize the IP after returning from low power state.
This will also avoid code duplication across stmmac_resume/restore and
stmmac_open.

Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@st.com>
Acked-by: Giuseppe Cavallaro <peppe.cavallaro@st.com>
---
 drivers/net/ethernet/stmicro/stmmac/stmmac_main.c |  155 ++++++++++++---------
 1 files changed, 88 insertions(+), 67 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index 532f2b4..341c8dc 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -1586,6 +1586,86 @@ static void stmmac_init_tx_coalesce(struct stmmac_priv *priv)
 }
 
 /**
+ * stmmac_hw_setup: setup mac in a usable state.
+ *  @dev : pointer to the device structure.
+ *  Description:
+ *  This function sets up the ip in a usable state.
+ *  Return value:
+ *  0 on success and an appropriate (-)ve integer as defined in errno.h
+ *  file on failure.
+ */
+static int stmmac_hw_setup(struct net_device *dev)
+{
+	struct stmmac_priv *priv = netdev_priv(dev);
+	int ret;
+
+	ret = init_dma_desc_rings(dev);
+	if (ret < 0) {
+		pr_err("%s: DMA descriptors initialization failed\n", __func__);
+		return ret;
+	}
+	/* DMA initialization and SW reset */
+	ret = stmmac_init_dma_engine(priv);
+	if (ret < 0) {
+		pr_err("%s: DMA engine initialization failed\n", __func__);
+		return ret;
+	}
+
+	/* Copy the MAC addr into the HW  */
+	priv->hw->mac->set_umac_addr(priv->ioaddr, dev->dev_addr, 0);
+
+	/* If required, perform hw setup of the bus. */
+	if (priv->plat->bus_setup)
+		priv->plat->bus_setup(priv->ioaddr);
+
+	/* Initialize the MAC Core */
+	priv->hw->mac->core_init(priv->ioaddr);
+
+	/* Enable the MAC Rx/Tx */
+	stmmac_set_mac(priv->ioaddr, true);
+
+	/* Set the HW DMA mode and the COE */
+	stmmac_dma_operation_mode(priv);
+
+	stmmac_mmc_setup(priv);
+
+	ret = stmmac_init_ptp(priv);
+	if (ret)
+		pr_warn("%s: failed PTP initialisation\n", __func__);
+
+#ifdef CONFIG_STMMAC_DEBUG_FS
+	ret = stmmac_init_fs(dev);
+	if (ret < 0)
+		pr_warn("%s: failed debugFS registration\n", __func__);
+#endif
+	/* Start the ball rolling... */
+	pr_debug("%s: DMA RX/TX processes started...\n", dev->name);
+	priv->hw->dma->start_tx(priv->ioaddr);
+	priv->hw->dma->start_rx(priv->ioaddr);
+
+	/* Dump DMA/MAC registers */
+	if (netif_msg_hw(priv)) {
+		priv->hw->mac->dump_regs(priv->ioaddr);
+		priv->hw->dma->dump_regs(priv->ioaddr);
+	}
+	priv->tx_lpi_timer = STMMAC_DEFAULT_TWT_LS;
+
+	priv->eee_enabled = stmmac_eee_init(priv);
+
+	stmmac_init_tx_coalesce(priv);
+
+	if ((priv->use_riwt) && (priv->hw->dma->rx_watchdog)) {
+		priv->rx_riwt = MAX_DMA_RIWT;
+		priv->hw->dma->rx_watchdog(priv->ioaddr, MAX_DMA_RIWT);
+	}
+
+	if (priv->pcs && priv->hw->mac->ctrl_ane)
+		priv->hw->mac->ctrl_ane(priv->ioaddr, 0);
+
+	return 0;
+}
+
+/**
  *  stmmac_open - open entry point of the driver
  *  @dev : pointer to the device structure.
  *  Description:
@@ -1613,6 +1693,10 @@ static int stmmac_open(struct net_device *dev)
 		}
 	}
 
+	/* Extra statistics */
+	memset(&priv->xstats, 0, sizeof(struct stmmac_extra_stats));
+	priv->xstats.threshold = tc;
+
 	/* Create and initialize the TX/RX descriptors chains. */
 	priv->dma_tx_size = STMMAC_ALIGN(dma_txsize);
 	priv->dma_rx_size = STMMAC_ALIGN(dma_rxsize);
@@ -1624,28 +1708,14 @@ static int stmmac_open(struct net_device *dev)
 		goto dma_desc_error;
 	}
 
-	ret = init_dma_desc_rings(dev);
+	ret = stmmac_hw_setup(dev);
 	if (ret < 0) {
-		pr_err("%s: DMA descriptors initialization failed\n", __func__);
-		goto dma_desc_error;
-	}
-
-	/* DMA initialization and SW reset */
-	ret = stmmac_init_dma_engine(priv);
-	if (ret < 0) {
-		pr_err("%s: DMA engine initialization failed\n", __func__);
+		pr_err("%s: Hw setup failed\n", __func__);
 		goto init_error;
 	}
 
-	/* Copy the MAC addr into the HW  */
-	priv->hw->mac->set_umac_addr(priv->ioaddr, dev->dev_addr, 0);
-
-	/* If required, perform hw setup of the bus. */
-	if (priv->plat->bus_setup)
-		priv->plat->bus_setup(priv->ioaddr);
-
-	/* Initialize the MAC Core */
-	priv->hw->mac->core_init(priv->ioaddr);
+	if (priv->phydev)
+		phy_start(priv->phydev);
 
 	/* Request the IRQ lines */
 	ret = request_irq(dev->irq, stmmac_interrupt,
@@ -1678,55 +1748,6 @@ static int stmmac_open(struct net_device *dev)
 		}
 	}
 
-	/* Enable the MAC Rx/Tx */
-	stmmac_set_mac(priv->ioaddr, true);
-
-	/* Set the HW DMA mode and the COE */
-	stmmac_dma_operation_mode(priv);
-
-	/* Extra statistics */
-	memset(&priv->xstats, 0, sizeof(struct stmmac_extra_stats));
-	priv->xstats.threshold = tc;
-
-	stmmac_mmc_setup(priv);
-
-	ret = stmmac_init_ptp(priv);
-	if (ret)
-		pr_warn("%s: failed PTP initialisation\n", __func__);
-
-#ifdef CONFIG_STMMAC_DEBUG_FS
-	ret = stmmac_init_fs(dev);
-	if (ret < 0)
-		pr_warn("%s: failed debugFS registration\n", __func__);
-#endif
-	/* Start the ball rolling... */
-	pr_debug("%s: DMA RX/TX processes started...\n", dev->name);
-	priv->hw->dma->start_tx(priv->ioaddr);
-	priv->hw->dma->start_rx(priv->ioaddr);
-
-	/* Dump DMA/MAC registers */
-	if (netif_msg_hw(priv)) {
-		priv->hw->mac->dump_regs(priv->ioaddr);
-		priv->hw->dma->dump_regs(priv->ioaddr);
-	}
-
-	if (priv->phydev)
-		phy_start(priv->phydev);
-
-	priv->tx_lpi_timer = STMMAC_DEFAULT_TWT_LS;
-
-	priv->eee_enabled = stmmac_eee_init(priv);
-
-	stmmac_init_tx_coalesce(priv);
-
-	if ((priv->use_riwt) && (priv->hw->dma->rx_watchdog)) {
-		priv->rx_riwt = MAX_DMA_RIWT;
-		priv->hw->dma->rx_watchdog(priv->ioaddr, MAX_DMA_RIWT);
-	}
-
-	if (priv->pcs && priv->hw->mac->ctrl_ane)
-		priv->hw->mac->ctrl_ane(priv->ioaddr, 0);
-
 	napi_enable(&priv->napi);
 	netif_start_queue(dev);
 
-- 
1.7.6.5


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH v2 5/9] net: stmmac: make stmmac_mdio_reset non-static
  2014-01-16 10:50 ` srinivas.kandagatla
                     ` (3 preceding siblings ...)
  2014-01-16 10:52   ` [PATCH v2 4/9] net: stmmac: move hardware setup for stmmac_open " srinivas.kandagatla
@ 2014-01-16 10:52   ` srinivas.kandagatla
  2014-01-16 10:52   ` [PATCH v2 6/9] net: stmmac: fix power management suspend-resume case srinivas.kandagatla
                     ` (3 subsequent siblings)
  8 siblings, 0 replies; 28+ messages in thread
From: srinivas.kandagatla @ 2014-01-16 10:52 UTC (permalink / raw)
  To: netdev
  Cc: Giuseppe CAVALLARO, David Miller, linux-kernel, srinivas.kandagatla

From: Srinivas Kandagatla <srinivas.kandagatla@st.com>

This patch promotes stmmac_mdio_reset function from static to
non-static, so that power management functions can decide to reset if
the IP comes out from lowe power state specially hibernation cases.

Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@st.com>
Acked-by: Giuseppe Cavallaro <peppe.cavallaro@st.com>
---
 drivers/net/ethernet/stmicro/stmmac/stmmac.h      |    1 +
 drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c |    2 +-
 2 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac.h b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
index 92be6b3..5a568015 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac.h
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
@@ -110,6 +110,7 @@ struct stmmac_priv {
 
 int stmmac_mdio_unregister(struct net_device *ndev);
 int stmmac_mdio_register(struct net_device *ndev);
+int stmmac_mdio_reset(struct mii_bus *mii);
 void stmmac_set_ethtool_ops(struct net_device *netdev);
 extern const struct stmmac_desc_ops enh_desc_ops;
 extern const struct stmmac_desc_ops ndesc_ops;
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c
index aab12d2..a468eb1 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c
@@ -128,7 +128,7 @@ static int stmmac_mdio_write(struct mii_bus *bus, int phyaddr, int phyreg,
  * @bus: points to the mii_bus structure
  * Description: reset the MII bus
  */
-static int stmmac_mdio_reset(struct mii_bus *bus)
+int stmmac_mdio_reset(struct mii_bus *bus)
 {
 #if defined(CONFIG_STMMAC_PLATFORM)
 	struct net_device *ndev = bus->priv;
-- 
1.7.6.5


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH v2 6/9] net: stmmac: fix power management suspend-resume case
  2014-01-16 10:50 ` srinivas.kandagatla
                     ` (4 preceding siblings ...)
  2014-01-16 10:52   ` [PATCH v2 5/9] net: stmmac: make stmmac_mdio_reset non-static srinivas.kandagatla
@ 2014-01-16 10:52   ` srinivas.kandagatla
  2014-01-16 10:52   ` [PATCH v2 7/9] net: stmmac: use suspend functions for hibernation srinivas.kandagatla
                     ` (2 subsequent siblings)
  8 siblings, 0 replies; 28+ messages in thread
From: srinivas.kandagatla @ 2014-01-16 10:52 UTC (permalink / raw)
  To: netdev
  Cc: Giuseppe CAVALLARO, David Miller, linux-kernel, srinivas.kandagatla

From: Srinivas Kandagatla <srinivas.kandagatla@st.com>

The driver PM resume assumes that the IP is still powered up and the
all the register contents are not disturbed when it comes out of low
power suspend case. This assumption is wrong, basically the driver
should not consider any state of registers after it comes out of low
power. However driver can keep the part of the IP powered up if its a
wake up source. But it can not assume the register state of the IP. Also
its possible that SOC glue layer can take the power off the IP if its
not wake-up source to reduce the power consumption.

This patch re initializes hardware by calling stmmac_hw_setup function in
resume case.

Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@st.com>
Acked-by: Giuseppe Cavallaro <peppe.cavallaro@st.com>
---
 drivers/net/ethernet/stmicro/stmmac/stmmac_main.c |   13 +++++++------
 1 files changed, 7 insertions(+), 6 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index 341c8dc..742a83f 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -2887,18 +2887,19 @@ int stmmac_resume(struct net_device *ndev)
 	 * this bit because it can generate problems while resuming
 	 * 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);
-	else
+	} else {
 		/* enable the clk prevously disabled */
 		clk_prepare_enable(priv->stmmac_clk);
+		/* reset the phy so that it's ready */
+		if (priv->mii)
+			stmmac_mdio_reset(priv->mii);
+	}
 
 	netif_device_attach(ndev);
 
-	/* Enable the MAC and DMA */
-	stmmac_set_mac(priv->ioaddr, true);
-	priv->hw->dma->start_tx(priv->ioaddr);
-	priv->hw->dma->start_rx(priv->ioaddr);
+	stmmac_hw_setup(ndev);
 
 	napi_enable(&priv->napi);
 
-- 
1.7.6.5


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH v2 7/9] net: stmmac: use suspend functions for hibernation
  2014-01-16 10:50 ` srinivas.kandagatla
                     ` (5 preceding siblings ...)
  2014-01-16 10:52   ` [PATCH v2 6/9] net: stmmac: fix power management suspend-resume case srinivas.kandagatla
@ 2014-01-16 10:52   ` srinivas.kandagatla
  2014-01-16 10:52   ` [PATCH v2 8/9] net: stmmac: restore pinstate in pm resume srinivas.kandagatla
  2014-01-16 10:53   ` [PATCH v2 9/9] net: stmmac: notify the PM core of a wakeup event srinivas.kandagatla
  8 siblings, 0 replies; 28+ messages in thread
From: srinivas.kandagatla @ 2014-01-16 10:52 UTC (permalink / raw)
  To: netdev
  Cc: Giuseppe CAVALLARO, David Miller, linux-kernel, srinivas.kandagatla

From: Srinivas Kandagatla <srinivas.kandagatla@st.com>

In hibernation freeze case the driver just releases the resources like
dma buffers, irqs, unregisters the drivers and during restore it does
register, request the resources. This is not really necessary, as part
of power management all the data structures are intact, all the
previously allocated resources can be used after coming out of low
power.

This patch uses the suspend and resume callbacks for freeze and
restore which initializes the hardware correctly without unregistering
or releasing the resources, this should also help in reducing the time
to restore.

Also this patch fixes a bug in stmmac_pltfr_restore and
stmmac_pltfr_freeze where it tries to get hold of platform data via
dev_get_platdata call, which would return NULL in device tree cases and
the next if statement would crash as there is no NULL check.

Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@st.com>
Acked-by: Giuseppe Cavallaro <peppe.cavallaro@st.com>
---
 drivers/net/ethernet/stmicro/stmmac/stmmac.h       |    2 -
 drivers/net/ethernet/stmicro/stmmac/stmmac_main.c  |   16 -------
 .../net/ethernet/stmicro/stmmac/stmmac_platform.c  |   44 +++++--------------
 3 files changed, 12 insertions(+), 50 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac.h b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
index 5a568015..027f1dd 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac.h
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
@@ -117,8 +117,6 @@ extern const struct stmmac_desc_ops ndesc_ops;
 extern const struct stmmac_hwtimestamp stmmac_ptp;
 int stmmac_ptp_register(struct stmmac_priv *priv);
 void stmmac_ptp_unregister(struct stmmac_priv *priv);
-int stmmac_freeze(struct net_device *ndev);
-int stmmac_restore(struct net_device *ndev);
 int stmmac_resume(struct net_device *ndev);
 int stmmac_suspend(struct net_device *ndev);
 int stmmac_dvr_remove(struct net_device *ndev);
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index 742a83f..c1298a0 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -2912,22 +2912,6 @@ int stmmac_resume(struct net_device *ndev)
 
 	return 0;
 }
-
-int stmmac_freeze(struct net_device *ndev)
-{
-	if (!ndev || !netif_running(ndev))
-		return 0;
-
-	return stmmac_release(ndev);
-}
-
-int stmmac_restore(struct net_device *ndev)
-{
-	if (!ndev || !netif_running(ndev))
-		return 0;
-
-	return stmmac_open(ndev);
-}
 #endif /* CONFIG_PM */
 
 /* Driver can be configured w/ and w/ both PCI and Platf drivers
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
index 9377ee6..6d0bf22 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
@@ -211,55 +211,35 @@ static int stmmac_pltfr_remove(struct platform_device *pdev)
 #ifdef CONFIG_PM
 static int stmmac_pltfr_suspend(struct device *dev)
 {
-	struct net_device *ndev = dev_get_drvdata(dev);
-
-	return stmmac_suspend(ndev);
-}
-
-static int stmmac_pltfr_resume(struct device *dev)
-{
-	struct net_device *ndev = dev_get_drvdata(dev);
-
-	return stmmac_resume(ndev);
-}
-
-static int stmmac_pltfr_freeze(struct device *dev)
-{
 	int ret;
-	struct plat_stmmacenet_data *plat_dat = dev_get_platdata(dev);
 	struct net_device *ndev = dev_get_drvdata(dev);
+	struct stmmac_priv *priv = netdev_priv(ndev);
 	struct platform_device *pdev = to_platform_device(dev);
 
-	ret = stmmac_freeze(ndev);
-	if (plat_dat->exit)
-		plat_dat->exit(pdev);
+	ret = stmmac_suspend(ndev);
+	if (priv->plat->exit)
+		priv->plat->exit(pdev);
 
 	return ret;
 }
 
-static int stmmac_pltfr_restore(struct device *dev)
+static int stmmac_pltfr_resume(struct device *dev)
 {
-	struct plat_stmmacenet_data *plat_dat = dev_get_platdata(dev);
 	struct net_device *ndev = dev_get_drvdata(dev);
+	struct stmmac_priv *priv = netdev_priv(ndev);
 	struct platform_device *pdev = to_platform_device(dev);
 
-	if (plat_dat->init)
-		plat_dat->init(pdev);
+	if (priv->plat->init)
+		priv->plat->init(pdev);
 
-	return stmmac_restore(ndev);
+	return stmmac_resume(ndev);
 }
 
-static const struct dev_pm_ops stmmac_pltfr_pm_ops = {
-	.suspend = stmmac_pltfr_suspend,
-	.resume = stmmac_pltfr_resume,
-	.freeze = stmmac_pltfr_freeze,
-	.thaw = stmmac_pltfr_restore,
-	.restore = stmmac_pltfr_restore,
-};
-#else
-static const struct dev_pm_ops stmmac_pltfr_pm_ops;
 #endif /* CONFIG_PM */
 
+static SIMPLE_DEV_PM_OPS(stmmac_pltfr_pm_ops,
+			stmmac_pltfr_suspend, stmmac_pltfr_resume);
+
 static const struct of_device_id stmmac_dt_ids[] = {
 	{ .compatible = "st,spear600-gmac"},
 	{ .compatible = "snps,dwmac-3.610"},
-- 
1.7.6.5


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH v2 8/9] net: stmmac: restore pinstate in pm resume.
  2014-01-16 10:50 ` srinivas.kandagatla
                     ` (6 preceding siblings ...)
  2014-01-16 10:52   ` [PATCH v2 7/9] net: stmmac: use suspend functions for hibernation srinivas.kandagatla
@ 2014-01-16 10:52   ` srinivas.kandagatla
  2014-01-16 10:53   ` [PATCH v2 9/9] net: stmmac: notify the PM core of a wakeup event srinivas.kandagatla
  8 siblings, 0 replies; 28+ messages in thread
From: srinivas.kandagatla @ 2014-01-16 10:52 UTC (permalink / raw)
  To: netdev
  Cc: Giuseppe CAVALLARO, David Miller, linux-kernel, srinivas.kandagatla

From: Srinivas Kandagatla <srinivas.kandagatla@st.com>

This patch adds code to restore default pinstate of the pins when it
comes back from low power state. Without this patch the state of the
pins would be unknown and the driver would not work.

This patch also adds code to put the pins in to sleep state when the
driver enters low power state.

Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@st.com>
Acked-by: Giuseppe Cavallaro <peppe.cavallaro@st.com>
---
 drivers/net/ethernet/stmicro/stmmac/stmmac_main.c |    3 +++
 1 files changed, 3 insertions(+), 0 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index c1298a0..df7d8d6 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -43,6 +43,7 @@
 #include <linux/dma-mapping.h>
 #include <linux/slab.h>
 #include <linux/prefetch.h>
+#include <linux/pinctrl/consumer.h>
 #ifdef CONFIG_STMMAC_DEBUG_FS
 #include <linux/debugfs.h>
 #include <linux/seq_file.h>
@@ -2864,6 +2865,7 @@ int stmmac_suspend(struct net_device *ndev)
 		priv->hw->mac->pmt(priv->ioaddr, priv->wolopts);
 	else {
 		stmmac_set_mac(priv->ioaddr, false);
+		pinctrl_pm_select_sleep_state(priv->device);
 		/* Disable clock in case of PWM is off */
 		clk_disable_unprepare(priv->stmmac_clk);
 	}
@@ -2890,6 +2892,7 @@ int stmmac_resume(struct net_device *ndev)
 	if (device_may_wakeup(priv->device)) {
 		priv->hw->mac->pmt(priv->ioaddr, 0);
 	} else {
+		pinctrl_pm_select_default_state(priv->device);
 		/* enable the clk prevously disabled */
 		clk_prepare_enable(priv->stmmac_clk);
 		/* reset the phy so that it's ready */
-- 
1.7.6.5


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH v2 9/9] net: stmmac: notify the PM core of a wakeup event.
  2014-01-16 10:50 ` srinivas.kandagatla
                     ` (7 preceding siblings ...)
  2014-01-16 10:52   ` [PATCH v2 8/9] net: stmmac: restore pinstate in pm resume srinivas.kandagatla
@ 2014-01-16 10:53   ` srinivas.kandagatla
  8 siblings, 0 replies; 28+ messages in thread
From: srinivas.kandagatla @ 2014-01-16 10:53 UTC (permalink / raw)
  To: netdev
  Cc: Giuseppe CAVALLARO, David Miller, linux-kernel, srinivas.kandagatla

From: Srinivas Kandagatla <srinivas.kandagatla@st.com>

In PM_SUSPEND_FREEZE and WOL(Wakeup On Lan) case, when the driver gets a
wakeup event, either the driver or platform specific PM code should notify
the pm core about it, so that the system can wakeup from low power.

In cases where there is no involvement of platform specific PM, it
becomes driver responsibility to notify the PM core to wakeup the
system.

Without this WOL with PM_SUSPEND_FREEZE does not work on STi based SOCs.

Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@st.com>
Acked-by: Giuseppe Cavallaro <peppe.cavallaro@st.com>
---
 drivers/net/ethernet/stmicro/stmmac/stmmac.h      |    1 +
 drivers/net/ethernet/stmicro/stmmac/stmmac_main.c |    9 +++++++--
 2 files changed, 8 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac.h b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
index 027f1dd..73709e9 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac.h
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
@@ -105,6 +105,7 @@ struct stmmac_priv {
 	unsigned int default_addend;
 	u32 adv_ts;
 	int use_riwt;
+	int irq_wake;
 	spinlock_t ptp_lock;
 };
 
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index df7d8d6..cddcf76 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -2320,6 +2320,9 @@ static irqreturn_t stmmac_interrupt(int irq, void *dev_id)
 	struct net_device *dev = (struct net_device *)dev_id;
 	struct stmmac_priv *priv = netdev_priv(dev);
 
+	if (priv->irq_wake)
+		pm_wakeup_event(priv->device, 0);
+
 	if (unlikely(!dev)) {
 		pr_err("%s: invalid dev pointer\n", __func__);
 		return IRQ_NONE;
@@ -2861,9 +2864,10 @@ int stmmac_suspend(struct net_device *ndev)
 	stmmac_clear_descriptors(priv);
 
 	/* 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);
-	else {
+		priv->irq_wake = 1;
+	} else {
 		stmmac_set_mac(priv->ioaddr, false);
 		pinctrl_pm_select_sleep_state(priv->device);
 		/* Disable clock in case of PWM is off */
@@ -2891,6 +2895,7 @@ int stmmac_resume(struct net_device *ndev)
 	 */
 	if (device_may_wakeup(priv->device)) {
 		priv->hw->mac->pmt(priv->ioaddr, 0);
+		priv->irq_wake = 0;
 	} else {
 		pinctrl_pm_select_default_state(priv->device);
 		/* enable the clk prevously disabled */
-- 
1.7.6.5


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* Re: [PATCH v2 0/9] net: stmmac PM related fixes.
  2014-01-16 10:48 ` [PATCH v2 0/9] net: " srinivas.kandagatla
@ 2014-01-16 23:24   ` David Miller
  0 siblings, 0 replies; 28+ messages in thread
From: David Miller @ 2014-01-16 23:24 UTC (permalink / raw)
  To: srinivas.kandagatla; +Cc: netdev, peppe.cavallaro, linux-kernel

From: <srinivas.kandagatla@st.com>
Date: Thu, 16 Jan 2014 10:48:41 +0000

> During PM_SUSPEND_FREEZE testing, I have noticed that PM support in STMMAC is
> partly broken. I had to re-arrange the code to do PM correctly. There were lot
> of things I did not like personally and some bits did not work in the first
> place. I thought this is the nice opportunity to clean the mess up.

Series applied to net-next, thanks.

^ permalink raw reply	[flat|nested] 28+ messages in thread

end of thread, other threads:[~2014-01-16 23:24 UTC | newest]

Thread overview: 28+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-11-18 11:30 [PATCH RFC 0/9]net: stmmac PM related fixes srinivas.kandagatla
2013-11-18 11:31 ` [PATCH RFC 1/9] net: stmmac: support max-speed device tree property srinivas.kandagatla
2013-11-18 11:31 ` [PATCH RFC 2/9] net: stmmac: mdio: remove reset gpio free srinivas.kandagatla
2013-11-18 11:31 ` [PATCH RFC 3/9] net: stmmac: move dma allocation to new function srinivas.kandagatla
2013-11-18 11:32 ` [PATCH RFC 4/9] net: stmmac: move hardware setup for stmmac_open " srinivas.kandagatla
2013-11-18 11:32 ` [PATCH RFC 5/9] net: stmmac: make stmmac_mdio_reset non-static srinivas.kandagatla
2013-11-18 11:32 ` [PATCH RFC 6/9] net: stmmac: fix power mangement suspend-resume case srinivas.kandagatla
2013-11-18 11:32 ` [PATCH RFC 7/9] net: stmmac: use suspend functions for hibernation srinivas.kandagatla
2013-11-18 11:32 ` [PATCH RFC 8/9] net: stmmac: restore pinstate in pm resume srinivas.kandagatla
2013-11-18 11:32 ` [PATCH RFC 9/9] net: stmmac: notify the PM core of a wakeup event srinivas.kandagatla
2013-11-19  5:24 ` [PATCH RFC 0/9]net: stmmac PM related fixes Giuseppe CAVALLARO
2013-11-19  9:03   ` srinivas kandagatla
2013-12-02 10:48   ` srinivas kandagatla
2013-12-02 16:18     ` David Miller
2014-01-14 10:05 ` srinivas kandagatla
2014-01-15 21:49   ` David Miller
2014-01-16 10:48 ` [PATCH v2 0/9] net: " srinivas.kandagatla
2014-01-16 23:24   ` David Miller
2014-01-16 10:50 ` srinivas.kandagatla
2014-01-16 10:51   ` [PATCH v2 1/9] net: stmmac: support max-speed device tree property srinivas.kandagatla
2014-01-16 10:51   ` [PATCH v2 2/9] net: stmmac: mdio: remove reset gpio free srinivas.kandagatla
2014-01-16 10:52   ` [PATCH v2 3/9] net: stmmac: move dma allocation to new function srinivas.kandagatla
2014-01-16 10:52   ` [PATCH v2 4/9] net: stmmac: move hardware setup for stmmac_open " srinivas.kandagatla
2014-01-16 10:52   ` [PATCH v2 5/9] net: stmmac: make stmmac_mdio_reset non-static srinivas.kandagatla
2014-01-16 10:52   ` [PATCH v2 6/9] net: stmmac: fix power management suspend-resume case srinivas.kandagatla
2014-01-16 10:52   ` [PATCH v2 7/9] net: stmmac: use suspend functions for hibernation srinivas.kandagatla
2014-01-16 10:52   ` [PATCH v2 8/9] net: stmmac: restore pinstate in pm resume srinivas.kandagatla
2014-01-16 10:53   ` [PATCH v2 9/9] net: stmmac: notify the PM core of a wakeup event srinivas.kandagatla

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.