* CPM2 SCC/SMC break handling broken
@ 2006-10-26 8:02 Laurent Pinchart
2006-10-26 21:18 ` Ricardo Scop
0 siblings, 1 reply; 9+ messages in thread
From: Laurent Pinchart @ 2006-10-26 8:02 UTC (permalink / raw)
To: linuxppc-embedded
Hi everybody,
I need to generate a break on a CPM2 SMC serial port (same issue with SCC
serial ports).
The tcsendbreak() man page states that the function should generate a break
between 250ms and 500ms, but testing showed that the break is one character
long (10 bits in 8N1 mode).
Breaks are handled by the tty layer (drivers/char/tty_io.c), the generic
serial layer (drivers/serial/serial_core.c) and the CPM driver
(drivers/char/cpm_uart/cpm_uart_core.c).
As the tty driver (drivers/serial/serial_core.c) defines a break handler
(break_ctl), the tty layer calls send_break to send the break:
static int send_break(struct tty_struct *tty, unsigned int duration)
{
tty->driver->break_ctl(tty, -1);
if (!signal_pending(current)) {
msleep_interruptible(duration);
}
tty->driver->break_ctl(tty, 0);
if (signal_pending(current))
return -EINTR;
return 0;
}
tty->driver->break_ctl just forwards the call to the CPM driver, which does
static void cpm_uart_break_ctl(struct uart_port *port, int break_state)
{
struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port;
int line = pinfo - cpm_uart_ports;
pr_debug("CPM uart[%d]:break ctrl, break_state: %d\n", port->line,
break_state);
if (break_state)
cpm_line_cr_cmd(line, CPM_CR_STOP_TX);
else
cpm_line_cr_cmd(line, CPM_CR_RESTART_TX);
}
CPM_CR_STOP_TX is documented to generate a break of BRKCR characters. The
BRKCR register is initialized to 1, so only 1 break character is sent, which
won't last between 250ms and 500ms.
cpm_uart_break_ctl() is not told how long the break must last, so it can't
modify BRKCR before sending CPM_CR_STOP_TX. A solution would be to let the
driver handle the break itself instead of having tty_io.c calling
send_break(). To do that, the driver (serial_core.c) must not declare a break
handler. This would obviously break all other serial drivers. Another
solution would be to have a new platform handler for CPM serial ports which
will turn the I/O ports to low-level outputs. This sounds more like a hack to
me though.
Could anyone think of a proper solution which would not disturb the other
drivers too much ?
Laurent Pinchart
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: CPM2 SCC/SMC break handling broken
2006-10-26 8:02 CPM2 SCC/SMC break handling broken Laurent Pinchart
@ 2006-10-26 21:18 ` Ricardo Scop
2006-10-27 9:01 ` Laurent Pinchart
0 siblings, 1 reply; 9+ messages in thread
From: Ricardo Scop @ 2006-10-26 21:18 UTC (permalink / raw)
To: Laurent Pinchart, linuxppc-embedded
On Thursday 26 October 2006 06:02, Laurent Pinchart wrote:
> Hi everybody,
>
> I need to generate a break on a CPM2 SMC serial port (same issue with S=
CC
> serial ports).
>
> The tcsendbreak() man page states that the function should generate a b=
reak
> between 250ms and 500ms, but testing showed that the break is one chara=
cter
> long (10 bits in 8N1 mode).
[snip]
> CPM_CR_STOP_TX is documented to generate a break of BRKCR characters. T=
he
> BRKCR register is initialized to 1, so only 1 break character is sent,
> which won't last between 250ms and 500ms.
[snip]
> Could anyone think of a proper solution which would not disturb the oth=
er
> drivers too much ?
Well, one could always set the BRKCR parameter to the maximum number of b=
reak=20
characters permitted by it's size, since the break condition will anyway =
end=20
as soon as the RESTART TX command is issued as a consequence of the=20
tty->driver->break_ctl(tty, 0) call. But I did not test this.
HTH,
--=20
Ricardo Scop.
\|/
___ -*-
(@ @)/|\
/ V \| R SCOP Consult.
/( )\ Linux-based communications
--^^---^^+------------------------------
rscop@matrix.com.br
+55 51 999-36-777
Porto Alegre, RS - BRazil
--
P. S.: "If you have any trouble sounding condescending, find a Unix user =
to
show you how it's done." -- Scott Adams, creator of "Dilbert"
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: CPM2 SCC/SMC break handling broken
2006-10-26 21:18 ` Ricardo Scop
@ 2006-10-27 9:01 ` Laurent Pinchart
2006-10-27 18:20 ` Ricardo Scop
0 siblings, 1 reply; 9+ messages in thread
From: Laurent Pinchart @ 2006-10-27 9:01 UTC (permalink / raw)
To: Ricardo Scop; +Cc: linuxppc-embedded
Hi Ricardo,
> > Hi everybody,
> >
> > I need to generate a break on a CPM2 SMC serial port (same issue with SCC
> > serial ports).
> >
> > The tcsendbreak() man page states that the function should generate a
> > break between 250ms and 500ms, but testing showed that the break is one
> > character long (10 bits in 8N1 mode).
>
> [snip]
>
> > CPM_CR_STOP_TX is documented to generate a break of BRKCR characters. The
> > BRKCR register is initialized to 1, so only 1 break character is sent,
> > which won't last between 250ms and 500ms.
>
> [snip]
>
> > Could anyone think of a proper solution which would not disturb the other
> > drivers too much ?
>
> Well, one could always set the BRKCR parameter to the maximum number of
> break characters permitted by it's size, since the break condition will
> anyway end as soon as the RESTART TX command is issued as a consequence of
> the tty->driver->break_ctl(tty, 0) call. But I did not test this.
That's a very good idea, but the documentation is a bit misleading here. I
tested the CPM2 behaviour, and found out that the break will last BRKCR
characters, even if a RESTART TX command is sent sooner.
The user manual states
"The SMC sends a programmable number of break characters according to BRKCR
and reverts to idle or sends data if a RESTART TRANSMIT is issued before
completion."
I suppose they meant that, if a RESTART TX command is issued before completion
of the break sequence, the SMC will send data at the end of the break
sequence. This is at least the behaviour I noticed after trying your idea.
Laurent Pinchart
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: CPM2 SCC/SMC break handling broken
2006-10-27 9:01 ` Laurent Pinchart
@ 2006-10-27 18:20 ` Ricardo Scop
2006-10-30 15:23 ` Laurent Pinchart
0 siblings, 1 reply; 9+ messages in thread
From: Ricardo Scop @ 2006-10-27 18:20 UTC (permalink / raw)
To: Laurent Pinchart; +Cc: linuxppc-embedded
Hi Laurent,
On Friday 27 October 2006 07:01, Laurent Pinchart wrote:
> Hi Ricardo,
>
> > > Hi everybody,
> > >
> > > I need to generate a break on a CPM2 SMC serial port (same issue wi=
th
> > > SCC serial ports).
> > >
> > > The tcsendbreak() man page states that the function should generate=
a
> > > break between 250ms and 500ms, but testing showed that the break is=
one
> > > character long (10 bits in 8N1 mode).
> >
> > [snip]
> >
> > > CPM_CR_STOP_TX is documented to generate a break of BRKCR character=
s.
> > > The BRKCR register is initialized to 1, so only 1 break character i=
s
> > > sent, which won't last between 250ms and 500ms.
> >
> > [snip]
> >
> > > Could anyone think of a proper solution which would not disturb the
> > > other drivers too much ?
> >
> > Well, one could always set the BRKCR parameter to the maximum number =
of
> > break characters permitted by it's size, since the break condition wi=
ll
> > anyway end as soon as the RESTART TX command is issued as a consequen=
ce
> > of the tty->driver->break_ctl(tty, 0) call. But I did not test this.
>
> That's a very good idea, but the documentation is a bit misleading here=
=2E I
> tested the CPM2 behaviour, and found out that the break will last BRKCR
> characters, even if a RESTART TX command is sent sooner.
>
> The user manual states
>
> "The SMC sends a programmable number of break characters according to B=
RKCR
> and reverts to idle or sends data if a RESTART TRANSMIT is issued befor=
e
> completion."
>
> I suppose they meant that, if a RESTART TX command is issued before
> completion of the break sequence, the SMC will send data at the end of =
the
> break sequence. This is at least the behaviour I noticed after trying y=
our
> idea.
Too bad.... :( One more good idea to the junk bin.
Hmm, just a wild shot you can try, while you're at that: what about setti=
ng=20
BRKCR to zero and issuing another STOP TRANSMIT, just before the RESTART=20
TRANSMIT?=20
Another reasonable shot would be to disable and reenable the transmitter =
in an=20
attempt to stop the break sequence; though I don't know what happens to t=
he=20
SMC state machine in this case.
Too wild guesses? Well, maybe someone at Freescale can have a better idea=
=2E :)
Best regards,
Ricardo Scop.
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: CPM2 SCC/SMC break handling broken
2006-10-27 18:20 ` Ricardo Scop
@ 2006-10-30 15:23 ` Laurent Pinchart
2006-10-30 15:40 ` Vitaly Bordug
0 siblings, 1 reply; 9+ messages in thread
From: Laurent Pinchart @ 2006-10-30 15:23 UTC (permalink / raw)
To: Ricardo Scop; +Cc: linuxppc-embedded
Hi Ricardo,
> > > > I need to generate a break on a CPM2 SMC serial port (same issue with
> > > > SCC serial ports).
> > > >
> > > > The tcsendbreak() man page states that the function should generate a
> > > > break between 250ms and 500ms, but testing showed that the break is
> > > > one character long (10 bits in 8N1 mode).
> > >
> > > [snip]
> > >
> > > > CPM_CR_STOP_TX is documented to generate a break of BRKCR characters.
> > > > The BRKCR register is initialized to 1, so only 1 break character is
> > > > sent, which won't last between 250ms and 500ms.
> > >
> > > [snip]
> > >
> > > > Could anyone think of a proper solution which would not disturb the
> > > > other drivers too much ?
> > >
> > > Well, one could always set the BRKCR parameter to the maximum number of
> > > break characters permitted by it's size, since the break condition will
> > > anyway end as soon as the RESTART TX command is issued as a consequence
> > > of the tty->driver->break_ctl(tty, 0) call. But I did not test this.
> >
> > That's a very good idea, but the documentation is a bit misleading here.
> > I tested the CPM2 behaviour, and found out that the break will last BRKCR
> > characters, even if a RESTART TX command is sent sooner.
> >
> > The user manual states
> >
> > "The SMC sends a programmable number of break characters according to
> > BRKCR and reverts to idle or sends data if a RESTART TRANSMIT is issued
> > before completion."
> >
> > I suppose they meant that, if a RESTART TX command is issued before
> > completion of the break sequence, the SMC will send data at the end of
> > the break sequence. This is at least the behaviour I noticed after trying
> > your idea.
>
> Too bad.... :( One more good idea to the junk bin.
>
> Hmm, just a wild shot you can try, while you're at that: what about setting
> BRKCR to zero and issuing another STOP TRANSMIT, just before the RESTART
> TRANSMIT?
Wow, congratulations. I wouldn't have thought about that.
static void cpm_uart_break_ctl(struct uart_port *port, int break_state)
{
struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port;
int line = pinfo - cpm_uart_ports;
volatile u16 *brkcr = IS_SMC(pinfo) ? &pinfo->smcup->smc_brkcr
: &pinfo->sccup->scc_brkcr;
pr_debug("CPM uart[%d]:break ctrl, break_state: %d\n", port->line,
break_state);
if (break_state)
{
*brkcr = 32767;
cpm_line_cr_cmd(line, CPM_CR_STOP_TX);
}
else
{
*brkcr = 0;
cpm_line_cr_cmd(line, CPM_CR_STOP_TX);
cpm_line_cr_cmd(line, CPM_CR_RESTART_TX);
}
}
This is a bit hackish though, but it works and doesn't require any API
modification.
Vitaly, could you give me your opinion ?
> Another reasonable shot would be to disable and reenable the transmitter in
> an attempt to stop the break sequence; though I don't know what happens to
> the SMC state machine in this case.
>
> Too wild guesses? Well, maybe someone at Freescale can have a better idea.
> :)
I could try contacting them, but they will probably tell me that I should just
set BRKCR to the number of characters I want to send. I doubt they will care
that the kernel break handling code doesn't allow us to do that easily.
Thanks for your help.
Best regards,
Laurent Pinchart
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: CPM2 SCC/SMC break handling broken
2006-10-30 15:23 ` Laurent Pinchart
@ 2006-10-30 15:40 ` Vitaly Bordug
2006-10-30 21:52 ` Ricardo Scop
2006-10-31 7:58 ` [PATCH] CPM UART: Fix break generation Laurent Pinchart
0 siblings, 2 replies; 9+ messages in thread
From: Vitaly Bordug @ 2006-10-30 15:40 UTC (permalink / raw)
To: Laurent Pinchart; +Cc: linuxppc-embedded
On Mon, 30 Oct 2006 16:23:51 +0100
Laurent Pinchart <laurent.pinchart@tbox.biz> wrote:
> Hi Ricardo,
>
> > > > > I need to generate a break on a CPM2 SMC serial port (same issue with
> > > > > SCC serial ports).
> > > > >
> > > > > The tcsendbreak() man page states that the function should generate a
> > > > > break between 250ms and 500ms, but testing showed that the break is
> > > > > one character long (10 bits in 8N1 mode).
> > > >
> > > > [snip]
> > > >
> > > > > CPM_CR_STOP_TX is documented to generate a break of BRKCR characters.
> > > > > The BRKCR register is initialized to 1, so only 1 break character is
> > > > > sent, which won't last between 250ms and 500ms.
> > > >
> > > > [snip]
> > > >
> > > > > Could anyone think of a proper solution which would not disturb the
> > > > > other drivers too much ?
> > > >
> > > > Well, one could always set the BRKCR parameter to the maximum number of
> > > > break characters permitted by it's size, since the break condition will
> > > > anyway end as soon as the RESTART TX command is issued as a consequence
> > > > of the tty->driver->break_ctl(tty, 0) call. But I did not test this.
> > >
> > > That's a very good idea, but the documentation is a bit misleading here.
> > > I tested the CPM2 behaviour, and found out that the break will last BRKCR
> > > characters, even if a RESTART TX command is sent sooner.
> > >
> > > The user manual states
> > >
> > > "The SMC sends a programmable number of break characters according to
> > > BRKCR and reverts to idle or sends data if a RESTART TRANSMIT is issued
> > > before completion."
> > >
> > > I suppose they meant that, if a RESTART TX command is issued before
> > > completion of the break sequence, the SMC will send data at the end of
> > > the break sequence. This is at least the behaviour I noticed after trying
> > > your idea.
> >
> > Too bad.... :( One more good idea to the junk bin.
> >
> > Hmm, just a wild shot you can try, while you're at that: what about setting
> > BRKCR to zero and issuing another STOP TRANSMIT, just before the RESTART
> > TRANSMIT?
>
> Wow, congratulations. I wouldn't have thought about that.
>
> static void cpm_uart_break_ctl(struct uart_port *port, int break_state)
> {
> struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port;
> int line = pinfo - cpm_uart_ports;
> volatile u16 *brkcr = IS_SMC(pinfo) ? &pinfo->smcup->smc_brkcr
> : &pinfo->sccup->scc_brkcr;
>
> pr_debug("CPM uart[%d]:break ctrl, break_state: %d\n", port->line,
> break_state);
>
> if (break_state)
> {
> *brkcr = 32767;
> cpm_line_cr_cmd(line, CPM_CR_STOP_TX);
> }
> else
> {
> *brkcr = 0;
> cpm_line_cr_cmd(line, CPM_CR_STOP_TX);
> cpm_line_cr_cmd(line, CPM_CR_RESTART_TX);
> }
> }
>
> This is a bit hackish though, but it works and doesn't require any API
> modification.
>
> Vitaly, could you give me your opinion ?
I'm fine with this change. Can you provide a sorta more complete reference why it is required?
I understood in general, but as author, you can explain the reason more clear I beleive...
Thanks.
-V
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: CPM2 SCC/SMC break handling broken
2006-10-30 15:40 ` Vitaly Bordug
@ 2006-10-30 21:52 ` Ricardo Scop
2006-10-31 7:58 ` [PATCH] CPM UART: Fix break generation Laurent Pinchart
1 sibling, 0 replies; 9+ messages in thread
From: Ricardo Scop @ 2006-10-30 21:52 UTC (permalink / raw)
To: Vitaly Bordug, Laurent Pinchart; +Cc: linuxppc-embedded
Hi Laurent,
On Monday 30 October 2006 13:40, Vitaly Bordug wrote:
> On Mon, 30 Oct 2006 16:23:51 +0100
>
> Laurent Pinchart <laurent.pinchart@tbox.biz> wrote:
> > Hi Ricardo,
> >
> > > > > > I need to generate a break on a CPM2 SMC serial port (same is=
sue
> > > > > > with SCC serial ports).
> > > > > >
> > > > > > The tcsendbreak() man page states that the function should
> > > > > > generate a break between 250ms and 500ms, but testing showed =
that
> > > > > > the break is one character long (10 bits in 8N1 mode).
> > > > >
> > > > > [snip]
> > > > >
> > > > > > CPM_CR_STOP_TX is documented to generate a break of BRKCR
> > > > > > characters. The BRKCR register is initialized to 1, so only 1
> > > > > > break character is sent, which won't last between 250ms and
> > > > > > 500ms.
> > > > >
> > > > > [snip]
> > > > >
> > > > > > Could anyone think of a proper solution which would not distu=
rb
> > > > > > the other drivers too much ?
> > > > >
> > > > > Well, one could always set the BRKCR parameter to the maximum
> > > > > number of break characters permitted by it's size, since the br=
eak
> > > > > condition will anyway end as soon as the RESTART TX command is
> > > > > issued as a consequence of the tty->driver->break_ctl(tty, 0) c=
all.
> > > > > But I did not test this.
> > > >
> > > > That's a very good idea, but the documentation is a bit misleadin=
g
> > > > here. I tested the CPM2 behaviour, and found out that the break w=
ill
> > > > last BRKCR characters, even if a RESTART TX command is sent soone=
r.
> > > >
> > > > The user manual states
> > > >
> > > > "The SMC sends a programmable number of break characters accordin=
g to
> > > > BRKCR and reverts to idle or sends data if a RESTART TRANSMIT is
> > > > issued before completion."
> > > >
> > > > I suppose they meant that, if a RESTART TX command is issued befo=
re
> > > > completion of the break sequence, the SMC will send data at the e=
nd
> > > > of the break sequence. This is at least the behaviour I noticed a=
fter
> > > > trying your idea.
> > >
> > > Too bad.... :( One more good idea to the junk bin.
> > >
> > > Hmm, just a wild shot you can try, while you're at that: what about
> > > setting BRKCR to zero and issuing another STOP TRANSMIT, just befor=
e
> > > the RESTART TRANSMIT?
> >
> > Wow, congratulations. I wouldn't have thought about that.
Thanks.
BTW, thank you for trying that out. My fingers are much lazier than my br=
ain.
Cheers,
--=20
Ricardo Scop.
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH] CPM UART: Fix break generation
2006-10-30 15:40 ` Vitaly Bordug
2006-10-30 21:52 ` Ricardo Scop
@ 2006-10-31 7:58 ` Laurent Pinchart
2006-10-31 9:04 ` Pantelis Antoniou
1 sibling, 1 reply; 9+ messages in thread
From: Laurent Pinchart @ 2006-10-31 7:58 UTC (permalink / raw)
To: Vitaly Bordug; +Cc: linuxppc-embedded
When generating a break condition on a serial port, the CPM must be told
beforehand how long the break should be. Unfortunately, this information is
not available through the current serial break handling API. This patch works
around the problem by requesting a 32767 characters break followed by a 0
characters break after the requested duration. The CPM will stop the first
break when the second one is requested. This might not work with future CPM
revisions.
Signed-off-by: Laurent Pinchart <laurent@pclaurent.technotrade>
---
drivers/serial/cpm_uart/cpm_uart_core.c | 9 +++++++++
1 files changed, 9 insertions(+), 0 deletions(-)
diff --git a/drivers/serial/cpm_uart/cpm_uart_core.c
b/drivers/serial/cpm_uart/cpm_uart_core.c
index c29d87d..aa0a284 100644
--- a/drivers/serial/cpm_uart/cpm_uart_core.c
+++ b/drivers/serial/cpm_uart/cpm_uart_core.c
@@ -239,14 +239,23 @@ static void cpm_uart_break_ctl(struct ua
{
struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port;
int line = pinfo - cpm_uart_ports;
+ volatile u16 *brkcr = IS_SMC(pinfo) ? &pinfo->smcup->smc_brkcr
+ : &pinfo->sccup->scc_brkcr;
pr_debug("CPM uart[%d]:break ctrl, break_state: %d\n", port->line,
break_state);
if (break_state)
+ {
+ *brkcr = 32767;
cpm_line_cr_cmd(line, CPM_CR_STOP_TX);
+ }
else
+ {
+ *brkcr = 0;
+ cpm_line_cr_cmd(line, CPM_CR_STOP_TX);
cpm_line_cr_cmd(line, CPM_CR_RESTART_TX);
+ }
}
/*
--
1.4.GIT
^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [PATCH] CPM UART: Fix break generation
2006-10-31 7:58 ` [PATCH] CPM UART: Fix break generation Laurent Pinchart
@ 2006-10-31 9:04 ` Pantelis Antoniou
0 siblings, 0 replies; 9+ messages in thread
From: Pantelis Antoniou @ 2006-10-31 9:04 UTC (permalink / raw)
To: Laurent Pinchart; +Cc: linuxppc-embedded
On 31 =CE=9F=CE=BA=CF=84 2006, at 9:58 =CE=A0=CE=9C, Laurent Pinchart =
wrote:
> When generating a break condition on a serial port, the CPM must be =20=
> told
> beforehand how long the break should be. Unfortunately, this =20
> information is
> not available through the current serial break handling API. This =20
> patch works
> around the problem by requesting a 32767 characters break followed =20
> by a 0
> characters break after the requested duration. The CPM will stop =20
> the first
> break when the second one is requested. This might not work with =20
> future CPM
> revisions.
>
ACK,
Nice one Laurent ;)
Regards
Pantelis
^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2006-10-31 9:05 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-10-26 8:02 CPM2 SCC/SMC break handling broken Laurent Pinchart
2006-10-26 21:18 ` Ricardo Scop
2006-10-27 9:01 ` Laurent Pinchart
2006-10-27 18:20 ` Ricardo Scop
2006-10-30 15:23 ` Laurent Pinchart
2006-10-30 15:40 ` Vitaly Bordug
2006-10-30 21:52 ` Ricardo Scop
2006-10-31 7:58 ` [PATCH] CPM UART: Fix break generation Laurent Pinchart
2006-10-31 9:04 ` Pantelis Antoniou
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).