* Handling of automatic flow control in UART drivers
@ 2014-10-13 14:48 Johannes Thumshirn
2014-10-13 17:09 ` Grant Edwards
2014-10-13 17:13 ` Peter Hurley
0 siblings, 2 replies; 6+ messages in thread
From: Johannes Thumshirn @ 2014-10-13 14:48 UTC (permalink / raw)
To: linux-serial; +Cc: Geißler Andreas, Johannes Thumshirn
Hi,
We have problem with automatic flow control (i.e. auto RTS/CTS handshaking) in
our uart driver (men_z135_uart.c). It's probably less a technical but a problem
with me understanding the API.
I active the hardware auto flow control feature on the CRTSCTS flag in my
uart_ops->set_termios() function. But then the RTS flag is set on every call of
the uart_ops->set_mctrl() function, this seems to confuse the hardware. Is there
a way to tell the tty layer that flow control is handled solely by hardware?
I.e. is there a way of telling serial core to leave out the calls to
uart_set_mctrl()/uart_clear_mctrl() in uart_throttle()/uart_unthrottle(), or is
setting UPF_FLOW_HARD and then implementing a dummy port->ops->{un}throttle()
the correct way?
Are there any drivers that use a hardware's automatic flow control feature I can
use as an example? A fast grep on AFE reveals some spots, but I can't really
find a difference to my implementation.
Thanks in advance,
Johannes
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: Handling of automatic flow control in UART drivers
2014-10-13 14:48 Handling of automatic flow control in UART drivers Johannes Thumshirn
@ 2014-10-13 17:09 ` Grant Edwards
2014-10-13 17:13 ` Peter Hurley
1 sibling, 0 replies; 6+ messages in thread
From: Grant Edwards @ 2014-10-13 17:09 UTC (permalink / raw)
To: linux-serial
On 2014-10-13, Johannes Thumshirn <johannes.thumshirn@men.de> wrote:
> I active the hardware auto flow control feature on the CRTSCTS flag
> in my uart_ops->set_termios() function. But then the RTS flag is set
> on every call of the uart_ops->set_mctrl() function, this seems to
> confuse the hardware.
Perhaps in that situation you should ignore the RTS setting in
set_mctrl() if CRTSCTS is enabled.
--
Grant Edwards grant.b.edwards Yow! Zippy's brain cells
at are straining to bridge
gmail.com synapses ...
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: Handling of automatic flow control in UART drivers
2014-10-13 14:48 Handling of automatic flow control in UART drivers Johannes Thumshirn
2014-10-13 17:09 ` Grant Edwards
@ 2014-10-13 17:13 ` Peter Hurley
2014-10-14 9:22 ` Johannes Thumshirn
1 sibling, 1 reply; 6+ messages in thread
From: Peter Hurley @ 2014-10-13 17:13 UTC (permalink / raw)
To: Johannes Thumshirn, linux-serial; +Cc: Geißler Andreas
On 10/13/2014 10:48 AM, Johannes Thumshirn wrote:
> Hi,
>
> We have problem with automatic flow control (i.e. auto RTS/CTS handshaking) in
> our uart driver (men_z135_uart.c). It's probably less a technical but a problem
> with me understanding the API.
>
> I active the hardware auto flow control feature on the CRTSCTS flag in my
> uart_ops->set_termios() function. But then the RTS flag is set on every call of
> the uart_ops->set_mctrl() function, this seems to confuse the hardware. Is there
> a way to tell the tty layer that flow control is handled solely by hardware?
> I.e. is there a way of telling serial core to leave out the calls to
> uart_set_mctrl()/uart_clear_mctrl() in uart_throttle()/uart_unthrottle(), or is
> setting UPF_FLOW_HARD and then implementing a dummy port->ops->{un}throttle()
> the correct way?
>
> Are there any drivers that use a hardware's automatic flow control feature I can
> use as an example? A fast grep on AFE reveals some spots, but I can't really
> find a difference to my implementation.
uart_throttle()/uart_unthrottle() is essentially broken.
If the RTS pin is driveable, then the UART driver must respond to TIOCM_RTS
set and clear in the ->set_mctrl() handler, regardless of any mode selected
in termios or other mode such as autoRTS.
This requirement exists because both userspace and other kernel drivers may
want to drive RTS for their own purposes.
For example, a bluetooth UART HCI may allow the bluetooth module to sleep
and wakes up the module by driving RTS low for a certain length of time;
if autoRTS prevents MCR writes from driving RTS, then the wake up never
happens. (see drivers/bluetooth/hci_ath.c : ath_wakeup_ar3k() for the
equally broken workaround of turning off CRTSCTS via an internal
tty core function which is going away soon).
The reason why TI 16c750-based AFE doesn't have to bother with this is
because, on that hardware, the MCR RTS bit overrides the autoRTS state;
ie., RTS = MCR_RTS & autoRTS.
If your hardware treats the two states orthogonally then you'll need
to turn off autoRTS mode if TIOCM_RTS is being cleared.
The amba-pl011.c driver does this; see drivers/tty/serial/amba-pl011.c:
pl011_set_mctrl().
Regards,
Peter Hurley
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: Handling of automatic flow control in UART drivers
2014-10-13 17:13 ` Peter Hurley
@ 2014-10-14 9:22 ` Johannes Thumshirn
2014-10-14 11:18 ` Peter Hurley
0 siblings, 1 reply; 6+ messages in thread
From: Johannes Thumshirn @ 2014-10-14 9:22 UTC (permalink / raw)
To: Peter Hurley; +Cc: Johannes Thumshirn, linux-serial, Geißler Andreas
On Mon, Oct 13, 2014 at 01:13:21PM -0400, Peter Hurley wrote:
> On 10/13/2014 10:48 AM, Johannes Thumshirn wrote:
> > Hi,
> >
> > We have problem with automatic flow control (i.e. auto RTS/CTS handshaking) in
> > our uart driver (men_z135_uart.c). It's probably less a technical but a problem
> > with me understanding the API.
> >
> > I active the hardware auto flow control feature on the CRTSCTS flag in my
> > uart_ops->set_termios() function. But then the RTS flag is set on every call of
> > the uart_ops->set_mctrl() function, this seems to confuse the hardware. Is there
> > a way to tell the tty layer that flow control is handled solely by hardware?
> > I.e. is there a way of telling serial core to leave out the calls to
> > uart_set_mctrl()/uart_clear_mctrl() in uart_throttle()/uart_unthrottle(), or is
> > setting UPF_FLOW_HARD and then implementing a dummy port->ops->{un}throttle()
> > the correct way?
> >
> > Are there any drivers that use a hardware's automatic flow control feature I can
> > use as an example? A fast grep on AFE reveals some spots, but I can't really
> > find a difference to my implementation.
>
> uart_throttle()/uart_unthrottle() is essentially broken.
>
> If the RTS pin is driveable, then the UART driver must respond to TIOCM_RTS
> set and clear in the ->set_mctrl() handler, regardless of any mode selected
> in termios or other mode such as autoRTS.
>
> This requirement exists because both userspace and other kernel drivers may
> want to drive RTS for their own purposes.
>
> For example, a bluetooth UART HCI may allow the bluetooth module to sleep
> and wakes up the module by driving RTS low for a certain length of time;
> if autoRTS prevents MCR writes from driving RTS, then the wake up never
> happens. (see drivers/bluetooth/hci_ath.c : ath_wakeup_ar3k() for the
> equally broken workaround of turning off CRTSCTS via an internal
> tty core function which is going away soon).
>
> The reason why TI 16c750-based AFE doesn't have to bother with this is
> because, on that hardware, the MCR RTS bit overrides the autoRTS state;
> ie., RTS = MCR_RTS & autoRTS.
>
> If your hardware treats the two states orthogonally then you'll need
> to turn off autoRTS mode if TIOCM_RTS is being cleared.
> The amba-pl011.c driver does this; see drivers/tty/serial/amba-pl011.c:
> pl011_set_mctrl().
Thanks for the info.
We've actually found the problem. When using auto flow control we need to
disable the modem status IRQs, in order to work.
The only problem that arises here is, when the modem status IRQs are disabled
the uart_ops->start_tx() isn't called anymore. But there should be work arounds
available.
Thanks,
Johannes
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: Handling of automatic flow control in UART drivers
2014-10-14 9:22 ` Johannes Thumshirn
@ 2014-10-14 11:18 ` Peter Hurley
2014-10-23 5:51 ` Johannes Thumshirn
0 siblings, 1 reply; 6+ messages in thread
From: Peter Hurley @ 2014-10-14 11:18 UTC (permalink / raw)
To: Johannes Thumshirn; +Cc: linux-serial, Geißler Andreas
On 10/14/2014 05:22 AM, Johannes Thumshirn wrote:
> On Mon, Oct 13, 2014 at 01:13:21PM -0400, Peter Hurley wrote:
>> On 10/13/2014 10:48 AM, Johannes Thumshirn wrote:
>>> Hi,
>>>
>>> We have problem with automatic flow control (i.e. auto RTS/CTS handshaking) in
>>> our uart driver (men_z135_uart.c). It's probably less a technical but a problem
>>> with me understanding the API.
>>>
>>> I active the hardware auto flow control feature on the CRTSCTS flag in my
>>> uart_ops->set_termios() function. But then the RTS flag is set on every call of
>>> the uart_ops->set_mctrl() function, this seems to confuse the hardware. Is there
>>> a way to tell the tty layer that flow control is handled solely by hardware?
>>> I.e. is there a way of telling serial core to leave out the calls to
>>> uart_set_mctrl()/uart_clear_mctrl() in uart_throttle()/uart_unthrottle(), or is
>>> setting UPF_FLOW_HARD and then implementing a dummy port->ops->{un}throttle()
>>> the correct way?
>>>
>>> Are there any drivers that use a hardware's automatic flow control feature I can
>>> use as an example? A fast grep on AFE reveals some spots, but I can't really
>>> find a difference to my implementation.
>>
>> uart_throttle()/uart_unthrottle() is essentially broken.
>>
>> If the RTS pin is driveable, then the UART driver must respond to TIOCM_RTS
>> set and clear in the ->set_mctrl() handler, regardless of any mode selected
>> in termios or other mode such as autoRTS.
>>
>> This requirement exists because both userspace and other kernel drivers may
>> want to drive RTS for their own purposes.
>>
>> For example, a bluetooth UART HCI may allow the bluetooth module to sleep
>> and wakes up the module by driving RTS low for a certain length of time;
>> if autoRTS prevents MCR writes from driving RTS, then the wake up never
>> happens. (see drivers/bluetooth/hci_ath.c : ath_wakeup_ar3k() for the
>> equally broken workaround of turning off CRTSCTS via an internal
>> tty core function which is going away soon).
>>
>> The reason why TI 16c750-based AFE doesn't have to bother with this is
>> because, on that hardware, the MCR RTS bit overrides the autoRTS state;
>> ie., RTS = MCR_RTS & autoRTS.
>>
>> If your hardware treats the two states orthogonally then you'll need
>> to turn off autoRTS mode if TIOCM_RTS is being cleared.
>> The amba-pl011.c driver does this; see drivers/tty/serial/amba-pl011.c:
>> pl011_set_mctrl().
>
> Thanks for the info.
>
> We've actually found the problem. When using auto flow control we need to
> disable the modem status IRQs, in order to work.
So the UART still raises modem status interrupts for DCTS when autoCTS is on?
> The only problem that arises here is, when the modem status IRQs are disabled
> the uart_ops->start_tx() isn't called anymore. But there should be work arounds
> available.
Almost certainly this is because ->hw_stopped has been set. The serial core
does this in two places (besides uart_handle_cts_change()):
uart_port_startup() after initializing the port and, in
uart_set_termios(), which, if you set UPF_HARD_FLOW, the serial core will skip.
Regards,
Peter Hurley
[Note: there's been some changes to flow control for 3.18; hw_stopped was moved
to uart_port].
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: Handling of automatic flow control in UART drivers
2014-10-14 11:18 ` Peter Hurley
@ 2014-10-23 5:51 ` Johannes Thumshirn
0 siblings, 0 replies; 6+ messages in thread
From: Johannes Thumshirn @ 2014-10-23 5:51 UTC (permalink / raw)
To: Peter Hurley; +Cc: Johannes Thumshirn, linux-serial, Geißler Andreas
On Tue, Oct 14, 2014 at 07:18:58AM -0400, Peter Hurley wrote:
> On 10/14/2014 05:22 AM, Johannes Thumshirn wrote:
> > On Mon, Oct 13, 2014 at 01:13:21PM -0400, Peter Hurley wrote:
> >> On 10/13/2014 10:48 AM, Johannes Thumshirn wrote:
> >>> Hi,
> >>>
> >>> We have problem with automatic flow control (i.e. auto RTS/CTS handshaking) in
> >>> our uart driver (men_z135_uart.c). It's probably less a technical but a problem
> >>> with me understanding the API.
> >>>
> >>> I active the hardware auto flow control feature on the CRTSCTS flag in my
> >>> uart_ops->set_termios() function. But then the RTS flag is set on every call of
> >>> the uart_ops->set_mctrl() function, this seems to confuse the hardware. Is there
> >>> a way to tell the tty layer that flow control is handled solely by hardware?
> >>> I.e. is there a way of telling serial core to leave out the calls to
> >>> uart_set_mctrl()/uart_clear_mctrl() in uart_throttle()/uart_unthrottle(), or is
> >>> setting UPF_FLOW_HARD and then implementing a dummy port->ops->{un}throttle()
> >>> the correct way?
> >>>
> >>> Are there any drivers that use a hardware's automatic flow control feature I can
> >>> use as an example? A fast grep on AFE reveals some spots, but I can't really
> >>> find a difference to my implementation.
> >>
> >> uart_throttle()/uart_unthrottle() is essentially broken.
> >>
> >> If the RTS pin is driveable, then the UART driver must respond to TIOCM_RTS
> >> set and clear in the ->set_mctrl() handler, regardless of any mode selected
> >> in termios or other mode such as autoRTS.
> >>
> >> This requirement exists because both userspace and other kernel drivers may
> >> want to drive RTS for their own purposes.
> >>
> >> For example, a bluetooth UART HCI may allow the bluetooth module to sleep
> >> and wakes up the module by driving RTS low for a certain length of time;
> >> if autoRTS prevents MCR writes from driving RTS, then the wake up never
> >> happens. (see drivers/bluetooth/hci_ath.c : ath_wakeup_ar3k() for the
> >> equally broken workaround of turning off CRTSCTS via an internal
> >> tty core function which is going away soon).
> >>
> >> The reason why TI 16c750-based AFE doesn't have to bother with this is
> >> because, on that hardware, the MCR RTS bit overrides the autoRTS state;
> >> ie., RTS = MCR_RTS & autoRTS.
> >>
> >> If your hardware treats the two states orthogonally then you'll need
> >> to turn off autoRTS mode if TIOCM_RTS is being cleared.
> >> The amba-pl011.c driver does this; see drivers/tty/serial/amba-pl011.c:
> >> pl011_set_mctrl().
> >
> > Thanks for the info.
> >
> > We've actually found the problem. When using auto flow control we need to
> > disable the modem status IRQs, in order to work.
>
> So the UART still raises modem status interrupts for DCTS when autoCTS is on?
>
> > The only problem that arises here is, when the modem status IRQs are disabled
> > the uart_ops->start_tx() isn't called anymore. But there should be work arounds
> > available.
>
> Almost certainly this is because ->hw_stopped has been set. The serial core
> does this in two places (besides uart_handle_cts_change()):
> uart_port_startup() after initializing the port and, in
> uart_set_termios(), which, if you set UPF_HARD_FLOW, the serial core will skip.
>
> Regards,
> Peter Hurley
>
> [Note: there's been some changes to flow control for 3.18; hw_stopped was moved
> to uart_port].
>
Sorry for the late reply, I've been a bit busy.
We've found a solution to the problem and I'll post a patch for review in a few
days.
Thanks again,
Johannes
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2014-10-23 5:51 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-10-13 14:48 Handling of automatic flow control in UART drivers Johannes Thumshirn
2014-10-13 17:09 ` Grant Edwards
2014-10-13 17:13 ` Peter Hurley
2014-10-14 9:22 ` Johannes Thumshirn
2014-10-14 11:18 ` Peter Hurley
2014-10-23 5:51 ` Johannes Thumshirn
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).