All of lore.kernel.org
 help / color / mirror / Atom feed
* [Xenomai-help] [PATCH] fix mscan init on mpc5121
@ 2012-01-05  9:31 Fabrice Gasnier
  2012-01-09 20:31 ` Gilles Chanteperdrix
  0 siblings, 1 reply; 2+ messages in thread
From: Fabrice Gasnier @ 2012-01-05  9:31 UTC (permalink / raw)
  To: xenomai

insmod xeno_rtcan_mscan gets stuck on MPC5121.
driver enters an endless loop at init.
Adapt it using linux driver behavior.

Signed-off-by: Fabrice Gasnier <fabrice.gasnier@domain.hid>
---
 ksrc/drivers/can/mscan/rtcan_mscan.c |   38 ++++++++++++++++++++++++++++++++-
 1 files changed, 36 insertions(+), 2 deletions(-)

diff --git a/ksrc/drivers/can/mscan/rtcan_mscan.c b/ksrc/drivers/can/mscan/rtcan_mscan.c
index d25fc5a..edd590e 100644
--- a/ksrc/drivers/can/mscan/rtcan_mscan.c
+++ b/ksrc/drivers/can/mscan/rtcan_mscan.c
@@ -40,6 +40,8 @@
 #include "rtcan_mscan_regs.h"
 #include "rtcan_mscan.h"
 
+#define MSCAN_SET_MODE_RETRIES	255
+
 /**
  *  Reception Interrupt handler
  *
@@ -306,11 +308,41 @@ static int rtcan_mscan_mode_stop(struct rtcan_device *dev,
 
 	/* Switch to sleep mode */
 	setbits8(&regs->canctl0, MSCAN_SLPRQ);
+	reg = in_8(&regs->canctl1);
+	while (!(reg & MSCAN_SLPAK) &&
+	        (rinit < MSCAN_SET_MODE_RETRIES)) {
+		if (likely(lock_ctx != NULL))
+			rtdm_lock_put_irqrestore(&dev->device_lock, *lock_ctx);
+		/* Busy sleep 1 microsecond */
+		rtdm_task_busy_sleep(1000);
+		if (likely(lock_ctx != NULL))
+			rtdm_lock_get_irqsave(&dev->device_lock, *lock_ctx);
+		rinit++;
+		reg = in_8(&regs->canctl1);
+	}
+	/*
+	 * The mscan controller will fail to enter sleep mode,
+	 * while there are irregular activities on bus, like
+	 * somebody keeps retransmitting. This behavior is
+	 * undocumented and seems to differ between mscan built
+	 * in mpc5200b and mpc5200. We proceed in that case,
+	 * since otherwise the slprq will be kept set and the
+	 * controller will get stuck. NOTE: INITRQ or CSWAI
+	 * will abort all active transmit actions, if still
+	 * any, at once.
+	 */
+	if (rinit >= MSCAN_SET_MODE_RETRIES)
+		rtdm_printk("rtcan_mscan: device failed to enter sleep mode. "
+				"We proceed anyhow.\n");
+	else
+		dev->state = CAN_STATE_SLEEPING;
+
+	rinit = 0;
 	setbits8(&regs->canctl0, MSCAN_INITRQ);
 
 	reg = in_8(&regs->canctl1);
-	while (!(reg & MSCAN_SLPAK) ||
-	       !(reg & MSCAN_INITAK)) {
+	while (!(reg & MSCAN_INITAK) &&
+	        (rinit < MSCAN_SET_MODE_RETRIES)) {
 		if (likely(lock_ctx != NULL))
 			rtdm_lock_put_irqrestore(&dev->device_lock, *lock_ctx);
 		/* Busy sleep 1 microsecond */
@@ -320,6 +352,8 @@ static int rtcan_mscan_mode_stop(struct rtcan_device *dev,
 		rinit++;
 		reg = in_8(&regs->canctl1);
 	}
+	if (rinit >= MSCAN_SET_MODE_RETRIES)
+		ret = -ENODEV;
 
 	/* Volatile state could have changed while we slept busy. */
 	dev->state = CAN_STATE_STOPPED;
-- 
1.7.0.4



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

* Re: [Xenomai-help] [PATCH] fix mscan init on mpc5121
  2012-01-05  9:31 [Xenomai-help] [PATCH] fix mscan init on mpc5121 Fabrice Gasnier
@ 2012-01-09 20:31 ` Gilles Chanteperdrix
  0 siblings, 0 replies; 2+ messages in thread
From: Gilles Chanteperdrix @ 2012-01-09 20:31 UTC (permalink / raw)
  To: Fabrice Gasnier; +Cc: xenomai

On 01/05/2012 10:31 AM, Fabrice Gasnier wrote:
> insmod xeno_rtcan_mscan gets stuck on MPC5121.
> driver enters an endless loop at init.
> Adapt it using linux driver behavior.
> 
> Signed-off-by: Fabrice Gasnier <fabrice.gasnier@domain.hid>

Applied, thanks.

-- 
                                                                Gilles.


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

end of thread, other threads:[~2012-01-09 20:31 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-01-05  9:31 [Xenomai-help] [PATCH] fix mscan init on mpc5121 Fabrice Gasnier
2012-01-09 20:31 ` Gilles Chanteperdrix

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.