netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v1 net-next 1/1] net: fec: add stop mode request on/off implemention
@ 2015-07-22 10:13 Fugang Duan
  2015-07-26 23:26 ` David Miller
  0 siblings, 1 reply; 4+ messages in thread
From: Fugang Duan @ 2015-07-22 10:13 UTC (permalink / raw)
  To: davem; +Cc: netdev, Frank.Li, stephen, b38611

The current driver depends on platform data to implement stop mode
request on/off that call api pdata->sleep_mode_enable().

To reduce arch platform redundancy code, since the function only set
SOC GPR register bit to request stop mode of/off, so we can move the
function into driver. And the specifix GPR register offset and MASK
bit can be transferred from DTS.

Signed-off-by: Fugang Duan <B38611@freescale.com>
---
 Documentation/devicetree/bindings/net/fsl-fec.txt |  3 +
 drivers/net/ethernet/freescale/fec.h              |  8 +++
 drivers/net/ethernet/freescale/fec_main.c         | 87 +++++++++++++++++++----
 3 files changed, 84 insertions(+), 14 deletions(-)

diff --git a/Documentation/devicetree/bindings/net/fsl-fec.txt b/Documentation/devicetree/bindings/net/fsl-fec.txt
index a9eb611..f0936c3 100644
--- a/Documentation/devicetree/bindings/net/fsl-fec.txt
+++ b/Documentation/devicetree/bindings/net/fsl-fec.txt
@@ -24,6 +24,9 @@ Optional properties:
   number to 1.
 - fsl,magic-packet : If present, indicates that the hardware supports waking
   up via magic packet.
+- fsl,wakeup_irq : The property defines the wakeup irq index in enet irq source.
+- stop-mode : The property defines gpr register bits of stop mode control, the
+  format is <&gpr req_gpr req_bit>.
 
 Optional subnodes:
 - mdio : specifies the mdio bus in the FEC, used as a container for phy nodes
diff --git a/drivers/net/ethernet/freescale/fec.h b/drivers/net/ethernet/freescale/fec.h
index 1eee73c..1a09b68 100644
--- a/drivers/net/ethernet/freescale/fec.h
+++ b/drivers/net/ethernet/freescale/fec.h
@@ -431,6 +431,12 @@ struct bufdesc_ex {
 /* Controller supports RACC register */
 #define FEC_QUIRK_HAS_RACC		(1 << 12)
 
+struct fec_enet_stop_mode {
+	struct regmap *gpr;
+	u8 req_gpr;
+	u8 req_bit;
+};
+
 struct fec_enet_priv_tx_q {
 	int index;
 	unsigned char *tx_bounce[TX_RING_SIZE];
@@ -518,6 +524,8 @@ struct fec_enet_private {
 	bool	bufdesc_ex;
 	int	pause_flag;
 	int	wol_flag;
+	int	wake_irq;
+	struct	fec_enet_stop_mode gprctl;
 	u32	quirks;
 
 	struct	napi_struct napi;
diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c
index 1f89c59..8ab03f4 100644
--- a/drivers/net/ethernet/freescale/fec_main.c
+++ b/drivers/net/ethernet/freescale/fec_main.c
@@ -58,6 +58,8 @@
 #include <linux/if_vlan.h>
 #include <linux/pinctrl/consumer.h>
 #include <linux/prefetch.h>
+#include <linux/mfd/syscon.h>
+#include <linux/regmap.h>
 
 #include <asm/cacheflush.h>
 
@@ -1099,11 +1101,27 @@ fec_restart(struct net_device *ndev)
 
 }
 
+static int fec_enet_stop_mode(struct fec_enet_private *fep, bool enabled)
+{
+	if (IS_ERR_OR_NULL(fep->gprctl.gpr))
+		return 0;
+
+	if (enabled)
+		regmap_update_bits(fep->gprctl.gpr, fep->gprctl.req_gpr,
+				   1 << fep->gprctl.req_bit,
+				   1 << fep->gprctl.req_bit);
+	else
+		regmap_update_bits(fep->gprctl.gpr, fep->gprctl.req_gpr,
+				   1 << fep->gprctl.req_bit,
+				   0);
+
+	return 0;
+}
+
 static void
 fec_stop(struct net_device *ndev)
 {
 	struct fec_enet_private *fep = netdev_priv(ndev);
-	struct fec_platform_data *pdata = fep->pdev->dev.platform_data;
 	u32 rmii_mode = readl(fep->hwp + FEC_R_CNTRL) & (1 << 8);
 	u32 val;
 
@@ -1133,8 +1151,7 @@ fec_stop(struct net_device *ndev)
 		val |= (FEC_ECR_MAGICEN | FEC_ECR_SLEEP);
 		writel(val, fep->hwp + FEC_ECNTRL);
 
-		if (pdata && pdata->sleep_mode_enable)
-			pdata->sleep_mode_enable(true);
+		fec_enet_stop_mode(fep, true);
 	}
 	writel(fep->phy_speed, fep->hwp + FEC_MII_SPEED);
 
@@ -2578,15 +2595,10 @@ fec_enet_set_wol(struct net_device *ndev, struct ethtool_wolinfo *wol)
 		return -EINVAL;
 
 	device_set_wakeup_enable(&ndev->dev, wol->wolopts & WAKE_MAGIC);
-	if (device_may_wakeup(&ndev->dev)) {
+	if (device_may_wakeup(&ndev->dev))
 		fep->wol_flag |= FEC_WOL_FLAG_ENABLE;
-		if (fep->irq[0] > 0)
-			enable_irq_wake(fep->irq[0]);
-	} else {
+	else
 		fep->wol_flag &= (~FEC_WOL_FLAG_ENABLE);
-		if (fep->irq[0] > 0)
-			disable_irq_wake(fep->irq[0]);
-	}
 
 	return 0;
 }
@@ -3267,6 +3279,41 @@ fec_enet_get_queue_num(struct platform_device *pdev, int *num_tx, int *num_rx)
 
 }
 
+static void fec_enet_of_parse_stop_mode(struct platform_device *pdev)
+{
+	struct net_device *dev = platform_get_drvdata(pdev);
+	struct device_node *np = pdev->dev.of_node;
+	struct fec_enet_private *fep = netdev_priv(dev);
+	struct device_node *node;
+	phandle phandle;
+	u32 out_val[3];
+	int ret;
+
+	ret = of_property_read_u32_array(np, "stop-mode", out_val, 3);
+	if (ret) {
+		dev_dbg(&pdev->dev, "no stop-mode property\n");
+		return;
+	}
+
+	phandle = *out_val;
+	node = of_find_node_by_phandle(phandle);
+	if (!node) {
+		dev_dbg(&pdev->dev, "could not find gpr node by phandle\n");
+		return;
+	}
+
+	fep->gprctl.gpr = syscon_node_to_regmap(node);
+	if (IS_ERR(fep->gprctl.gpr)) {
+		dev_dbg(&pdev->dev, "could not find gpr regmap\n");
+		return;
+	}
+
+	of_node_put(node);
+
+	fep->gprctl.req_gpr = out_val[1];
+	fep->gprctl.req_bit = out_val[2];
+}
+
 static int
 fec_probe(struct platform_device *pdev)
 {
@@ -3324,6 +3371,8 @@ fec_probe(struct platform_device *pdev)
 
 	platform_set_drvdata(pdev, ndev);
 
+	fec_enet_of_parse_stop_mode(pdev);
+
 	if (of_get_property(np, "fsl,magic-packet", NULL))
 		fep->wol_flag |= FEC_WOL_HAS_MAGIC_PACKET;
 
@@ -3425,6 +3474,12 @@ fec_probe(struct platform_device *pdev)
 		fep->irq[i] = irq;
 	}
 
+	ret = of_property_read_u32(np, "fsl,wakeup_irq", &irq);
+	if (!ret && irq < FEC_IRQ_NUM)
+		fep->wake_irq = fep->irq[irq];
+	else
+		fep->wake_irq = fep->irq[0];
+
 	init_completion(&fep->mdio_done);
 	ret = fec_enet_mii_init(pdev);
 	if (ret)
@@ -3503,8 +3558,12 @@ static int __maybe_unused fec_suspend(struct device *dev)
 		netif_tx_unlock_bh(ndev);
 		fec_stop(ndev);
 		fec_enet_clk_enable(ndev, false);
-		if (!(fep->wol_flag & FEC_WOL_FLAG_ENABLE))
+		if (!(fep->wol_flag & FEC_WOL_FLAG_ENABLE)) {
 			pinctrl_pm_select_sleep_state(&fep->pdev->dev);
+		} else {
+			disable_irq(fep->wake_irq);
+			enable_irq_wake(fep->wake_irq);
+		}
 	}
 	rtnl_unlock();
 
@@ -3524,7 +3583,6 @@ static int __maybe_unused fec_resume(struct device *dev)
 {
 	struct net_device *ndev = dev_get_drvdata(dev);
 	struct fec_enet_private *fep = netdev_priv(ndev);
-	struct fec_platform_data *pdata = fep->pdev->dev.platform_data;
 	int ret;
 	int val;
 
@@ -3542,8 +3600,9 @@ static int __maybe_unused fec_resume(struct device *dev)
 			goto failed_clk;
 		}
 		if (fep->wol_flag & FEC_WOL_FLAG_ENABLE) {
-			if (pdata && pdata->sleep_mode_enable)
-				pdata->sleep_mode_enable(false);
+			disable_irq_wake(fep->wake_irq);
+			fec_enet_stop_mode(fep, false);
+			enable_irq(fep->wake_irq);
 			val = readl(fep->hwp + FEC_ECNTRL);
 			val &= ~(FEC_ECR_MAGICEN | FEC_ECR_SLEEP);
 			writel(val, fep->hwp + FEC_ECNTRL);
-- 
1.9.1

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

* Re: [PATCH v1 net-next 1/1] net: fec: add stop mode request on/off implemention
  2015-07-22 10:13 [PATCH v1 net-next 1/1] net: fec: add stop mode request on/off implemention Fugang Duan
@ 2015-07-26 23:26 ` David Miller
  2015-07-27  1:27   ` Duan Andy
  2015-07-28  8:55   ` Duan Andy
  0 siblings, 2 replies; 4+ messages in thread
From: David Miller @ 2015-07-26 23:26 UTC (permalink / raw)
  To: b38611; +Cc: netdev, Frank.Li, stephen

From: Fugang Duan <b38611@freescale.com>
Date: Wed, 22 Jul 2015 18:13:43 +0800

> The current driver depends on platform data to implement stop mode
> request on/off that call api pdata->sleep_mode_enable().
> 
> To reduce arch platform redundancy code, since the function only set
> SOC GPR register bit to request stop mode of/off, so we can move the
> function into driver. And the specifix GPR register offset and MASK
> bit can be transferred from DTS.
> 
> Signed-off-by: Fugang Duan <B38611@freescale.com>

Doesn't this break stop mode on those devices until the DTS is
updated?

That's really unfortunate, because you're leaving all of the platform
data and implementation there, yet it's going to be unused.

I really think you need to keep the code using the platform data bits
around until all the DTSs are updated.

No matter what you tell me about how DTSs are updated (don't even
mention the details, I do not care) you simply cannot keep the
platform data code around and not use it.  It is completely
nonsensible to have code that would properly function and properly
support a feature for the device in the kernel, yet not use it.

Period.

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

* RE: [PATCH v1 net-next 1/1] net: fec: add stop mode request on/off implemention
  2015-07-26 23:26 ` David Miller
@ 2015-07-27  1:27   ` Duan Andy
  2015-07-28  8:55   ` Duan Andy
  1 sibling, 0 replies; 4+ messages in thread
From: Duan Andy @ 2015-07-27  1:27 UTC (permalink / raw)
  To: David Miller; +Cc: netdev, Li Frank, stephen

From: David Miller <davem@davemloft.net> Sent: Monday, July 27, 2015 7:27 AM
> To: Duan Fugang-B38611
> Cc: netdev@vger.kernel.org; Li Frank-B20596; stephen@networkplumber.org
> Subject: Re: [PATCH v1 net-next 1/1] net: fec: add stop mode request
> on/off implemention
> 
> From: Fugang Duan <b38611@freescale.com>
> Date: Wed, 22 Jul 2015 18:13:43 +0800
> 
> > The current driver depends on platform data to implement stop mode
> > request on/off that call api pdata->sleep_mode_enable().
> >
> > To reduce arch platform redundancy code, since the function only set
> > SOC GPR register bit to request stop mode of/off, so we can move the
> > function into driver. And the specifix GPR register offset and MASK
> > bit can be transferred from DTS.
> >
> > Signed-off-by: Fugang Duan <B38611@freescale.com>
> 
> Doesn't this break stop mode on those devices until the DTS is updated?
> 
> That's really unfortunate, because you're leaving all of the platform
> data and implementation there, yet it's going to be unused.
> 
> I really think you need to keep the code using the platform data bits
> around until all the DTSs are updated.
> 
> No matter what you tell me about how DTSs are updated (don't even mention
> the details, I do not care) you simply cannot keep the platform data code
> around and not use it.  It is completely nonsensible to have code that
> would properly function and properly support a feature for the device in
> the kernel, yet not use it.
> 
> Period.

Thanks for your comments.

Firstly, I will send some board dts patches (and test).
Secondly, the net/next tree have no platform data for stop mode because others suggest us to use dts not platform data, and there have no any boards support stop mode in net/next, so this doesn't break any boards in net/next.

Regards,
Andy

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

* RE: [PATCH v1 net-next 1/1] net: fec: add stop mode request on/off implemention
  2015-07-26 23:26 ` David Miller
  2015-07-27  1:27   ` Duan Andy
@ 2015-07-28  8:55   ` Duan Andy
  1 sibling, 0 replies; 4+ messages in thread
From: Duan Andy @ 2015-07-28  8:55 UTC (permalink / raw)
  To: Duan Andy, David Miller; +Cc: netdev, Li Frank

Hi, David,

From: Duan Fugang-B38611 Sent: Monday, July 27, 2015 9:28 AM
> To: 'David Miller'
> Cc: netdev@vger.kernel.org; Li Frank-B20596; stephen@networkplumber.org
> Subject: RE: [PATCH v1 net-next 1/1] net: fec: add stop mode request
> on/off implemention
> 
> From: David Miller <davem@davemloft.net> Sent: Monday, July 27, 2015 7:27
> AM
> > To: Duan Fugang-B38611
> > Cc: netdev@vger.kernel.org; Li Frank-B20596;
> > stephen@networkplumber.org
> > Subject: Re: [PATCH v1 net-next 1/1] net: fec: add stop mode request
> > on/off implemention
> >
> > From: Fugang Duan <b38611@freescale.com>
> > Date: Wed, 22 Jul 2015 18:13:43 +0800
> >
> > > The current driver depends on platform data to implement stop mode
> > > request on/off that call api pdata->sleep_mode_enable().
> > >
> > > To reduce arch platform redundancy code, since the function only set
> > > SOC GPR register bit to request stop mode of/off, so we can move the
> > > function into driver. And the specifix GPR register offset and MASK
> > > bit can be transferred from DTS.
> > >
> > > Signed-off-by: Fugang Duan <B38611@freescale.com>
> >
> > Doesn't this break stop mode on those devices until the DTS is updated?
> >
> > That's really unfortunate, because you're leaving all of the platform
> > data and implementation there, yet it's going to be unused.
> >
> > I really think you need to keep the code using the platform data bits
> > around until all the DTSs are updated.
> >
> > No matter what you tell me about how DTSs are updated (don't even
> > mention the details, I do not care) you simply cannot keep the
> > platform data code around and not use it.  It is completely
> > nonsensible to have code that would properly function and properly
> > support a feature for the device in the kernel, yet not use it.
> >
> > Period.
> 
> Thanks for your comments.
> 
> Firstly, I will send some board dts patches (and test).
> Secondly, the net/next tree have no platform data for stop mode because
> others suggest us to use dts not platform data, and there have no any
> boards support stop mode in net/next, so this doesn't break any boards in
> net/next.
> 
> Regards,
> Andy

I remove platform data callback is because there have no any platform use stop mode function. That is to remove redundant code.

I tested the patch on 4.1 with extra patches (imx pm support patches), it works fine.
But Linux next still loss i.MX power management patches, so wakeup source cannot work in next.

So the patch itself has no problem. You can accept it now, or after imx pm patches enter to next, and then I will send it again with imx6x/7x support.

Regards,
Andy

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

end of thread, other threads:[~2015-07-28  8:55 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-07-22 10:13 [PATCH v1 net-next 1/1] net: fec: add stop mode request on/off implemention Fugang Duan
2015-07-26 23:26 ` David Miller
2015-07-27  1:27   ` Duan Andy
2015-07-28  8:55   ` Duan Andy

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).