linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v3 1/2] can: m_can: move Message RAM initialization to function
@ 2017-05-05 11:46 Quentin Schulz
  2017-05-05 11:46 ` [PATCH v3 2/2] can: m_can: add deep Suspend/Resume support Quentin Schulz
  0 siblings, 1 reply; 3+ messages in thread
From: Quentin Schulz @ 2017-05-05 11:46 UTC (permalink / raw)
  To: wg, mkl, mario.huettel, socketcan
  Cc: Quentin Schulz, linux-can, netdev, linux-kernel,
	alexandre.belloni, thomas.petazzoni

To avoid possible ECC/parity checksum errors when reading an
uninitialized buffer, the entire Message RAM is initialized when probing
the driver. This initialization is done in the same function reading the
Device Tree properties.

This patch moves the RAM initialization to a separate function so it can
be called separately from device initialization from Device Tree.

Signed-off-by: Quentin Schulz <quentin.schulz@free-electrons.com>
---
 drivers/net/can/m_can/m_can.c | 24 +++++++++++++++---------
 1 file changed, 15 insertions(+), 9 deletions(-)

diff --git a/drivers/net/can/m_can/m_can.c b/drivers/net/can/m_can/m_can.c
index bf8fdaeb955e..3f0445440146 100644
--- a/drivers/net/can/m_can/m_can.c
+++ b/drivers/net/can/m_can/m_can.c
@@ -1489,6 +1489,20 @@ static int register_m_can_dev(struct net_device *dev)
 	return register_candev(dev);
 }
 
+static void m_can_init_ram(struct m_can_priv *priv)
+{
+	int end, i, start;
+
+	/* initialize the entire Message RAM in use to avoid possible
+	 * ECC/parity checksum errors when reading an uninitialized buffer
+	 */
+	start = priv->mcfg[MRAM_SIDF].off;
+	end = priv->mcfg[MRAM_TXB].off +
+		priv->mcfg[MRAM_TXB].num * TXB_ELEMENT_SIZE;
+	for (i = start; i < end; i += 4)
+		writel(0x0, priv->mram_base + i);
+}
+
 static void m_can_of_parse_mram(struct m_can_priv *priv,
 				const u32 *mram_config_vals)
 {
@@ -1529,15 +1543,7 @@ static void m_can_of_parse_mram(struct m_can_priv *priv,
 		priv->mcfg[MRAM_TXE].off, priv->mcfg[MRAM_TXE].num,
 		priv->mcfg[MRAM_TXB].off, priv->mcfg[MRAM_TXB].num);
 
-	/* initialize the entire Message RAM in use to avoid possible
-	 * ECC/parity checksum errors when reading an uninitialized buffer
-	 */
-	start = priv->mcfg[MRAM_SIDF].off;
-	end = priv->mcfg[MRAM_TXB].off +
-		priv->mcfg[MRAM_TXB].num * TXB_ELEMENT_SIZE;
-	for (i = start; i < end; i += 4)
-		writel(0x0, priv->mram_base + i);
-
+	m_can_init_ram(priv);
 }
 
 static int m_can_plat_probe(struct platform_device *pdev)
-- 
2.11.0

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

* [PATCH v3 2/2] can: m_can: add deep Suspend/Resume support
  2017-05-05 11:46 [PATCH v3 1/2] can: m_can: move Message RAM initialization to function Quentin Schulz
@ 2017-05-05 11:46 ` Quentin Schulz
  2017-05-05 12:06   ` Marc Kleine-Budde
  0 siblings, 1 reply; 3+ messages in thread
From: Quentin Schulz @ 2017-05-05 11:46 UTC (permalink / raw)
  To: wg, mkl, mario.huettel, socketcan
  Cc: Quentin Schulz, linux-can, netdev, linux-kernel,
	alexandre.belloni, thomas.petazzoni

This adds Power Management deep Suspend/Resume support for Bosch M_CAN
chip.

When entering deep sleep, the clocks are gated, the interrupts are
disabled. When resuming from deep sleep, the chip needs to be
reinitialized, the clocks ungated and the interrupts enabled.

Signed-off-by: Quentin Schulz <quentin.schulz@free-electrons.com>
---

v3:
 - do not close/reopen the can interface (which was previously done when
 calling m_can_close), basically do the same routine as in probe but
 it does not close/open the can device,
 - update commit log,

v2:
 - fix erroneous commit log,

 drivers/net/can/m_can/m_can.c | 17 ++++++++++++++---
 1 file changed, 14 insertions(+), 3 deletions(-)

diff --git a/drivers/net/can/m_can/m_can.c b/drivers/net/can/m_can/m_can.c
index 3f0445440146..0a06690febe2 100644
--- a/drivers/net/can/m_can/m_can.c
+++ b/drivers/net/can/m_can/m_can.c
@@ -1672,10 +1672,9 @@ static __maybe_unused int m_can_suspend(struct device *dev)
 	if (netif_running(ndev)) {
 		netif_stop_queue(ndev);
 		netif_device_detach(ndev);
+		m_can_stop(ndev);
 	}
 
-	/* TODO: enter low power */
-
 	priv->can.state = CAN_STATE_SLEEPING;
 
 	return 0;
@@ -1686,11 +1685,23 @@ static __maybe_unused int m_can_resume(struct device *dev)
 	struct net_device *ndev = dev_get_drvdata(dev);
 	struct m_can_priv *priv = netdev_priv(ndev);
 
-	/* TODO: exit low power */
+	m_can_init_ram(priv);
 
 	priv->can.state = CAN_STATE_ERROR_ACTIVE;
 
 	if (netif_running(ndev)) {
+		int ret = clk_prepare_enable(priv->hclk);
+
+		if (ret)
+			return ret;
+
+		ret = clk_prepare_enable(priv->cclk);
+		if (ret) {
+			clk_disable_unprepare(priv->hclk);
+			return ret;
+		}
+
+		m_can_start(ndev);
 		netif_device_attach(ndev);
 		netif_start_queue(ndev);
 	}
-- 
2.11.0

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

* Re: [PATCH v3 2/2] can: m_can: add deep Suspend/Resume support
  2017-05-05 11:46 ` [PATCH v3 2/2] can: m_can: add deep Suspend/Resume support Quentin Schulz
@ 2017-05-05 12:06   ` Marc Kleine-Budde
  0 siblings, 0 replies; 3+ messages in thread
From: Marc Kleine-Budde @ 2017-05-05 12:06 UTC (permalink / raw)
  To: Quentin Schulz, wg, mario.huettel, socketcan
  Cc: linux-can, netdev, linux-kernel, alexandre.belloni, thomas.petazzoni


[-- Attachment #1.1: Type: text/plain, Size: 2548 bytes --]

On 05/05/2017 01:46 PM, Quentin Schulz wrote:
> This adds Power Management deep Suspend/Resume support for Bosch M_CAN
> chip.
> 
> When entering deep sleep, the clocks are gated, the interrupts are
> disabled. When resuming from deep sleep, the chip needs to be
> reinitialized, the clocks ungated and the interrupts enabled.
> 
> Signed-off-by: Quentin Schulz <quentin.schulz@free-electrons.com>
> ---
> 
> v3:
>  - do not close/reopen the can interface (which was previously done when
>  calling m_can_close), basically do the same routine as in probe but
>  it does not close/open the can device,

much better!

>  - update commit log,
> 
> v2:
>  - fix erroneous commit log,
> 
>  drivers/net/can/m_can/m_can.c | 17 ++++++++++++++---
>  1 file changed, 14 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/net/can/m_can/m_can.c b/drivers/net/can/m_can/m_can.c
> index 3f0445440146..0a06690febe2 100644
> --- a/drivers/net/can/m_can/m_can.c
> +++ b/drivers/net/can/m_can/m_can.c
> @@ -1672,10 +1672,9 @@ static __maybe_unused int m_can_suspend(struct device *dev)
>  	if (netif_running(ndev)) {
>  		netif_stop_queue(ndev);
>  		netif_device_detach(ndev);
> +		m_can_stop(ndev);
>  	}
>  
> -	/* TODO: enter low power */
> -
>  	priv->can.state = CAN_STATE_SLEEPING;
>  
>  	return 0;
> @@ -1686,11 +1685,23 @@ static __maybe_unused int m_can_resume(struct device *dev)
>  	struct net_device *ndev = dev_get_drvdata(dev);
>  	struct m_can_priv *priv = netdev_priv(ndev);
>  
> -	/* TODO: exit low power */
> +	m_can_init_ram(priv);
>  
>  	priv->can.state = CAN_STATE_ERROR_ACTIVE;
>  
>  	if (netif_running(ndev)) {
> +		int ret = clk_prepare_enable(priv->hclk);
> +
> +		if (ret)
> +			return ret;
> +
> +		ret = clk_prepare_enable(priv->cclk);
> +		if (ret) {
> +			clk_disable_unprepare(priv->hclk);
> +			return ret;
> +		}
> +
> +		m_can_start(ndev);

Using m_can_stop() m_can_start() here is the way to go. However, when
looking at this hook we se, that the m_can_start/stop functions are not
symmetric (as they should be). Either move the clock handling to
completely in or out of m_can_start/stop.

>  		netif_device_attach(ndev);
>  		netif_start_queue(ndev);
>  	}
> 

Marc

-- 
Pengutronix e.K.                  | Marc Kleine-Budde           |
Industrial Linux Solutions        | Phone: +49-231-2826-924     |
Vertretung West/Dortmund          | Fax:   +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686  | http://www.pengutronix.de   |


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

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

end of thread, other threads:[~2017-05-05 12:07 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-05-05 11:46 [PATCH v3 1/2] can: m_can: move Message RAM initialization to function Quentin Schulz
2017-05-05 11:46 ` [PATCH v3 2/2] can: m_can: add deep Suspend/Resume support Quentin Schulz
2017-05-05 12:06   ` Marc Kleine-Budde

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).