* [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(®s->canctl0, MSCAN_SLPRQ);
+ reg = in_8(®s->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(®s->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(®s->canctl0, MSCAN_INITRQ);
reg = in_8(®s->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(®s->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
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.