[RFC] GPIO-based flow control in the cpm_uart driver

Laurent Pinchart laurentp at cse-semaphore.com
Tue May 20 22:50:14 EST 2008

Hi David,

On Tuesday 20 May 2008 02:25, David Brownell wrote:
> On Tuesday 15 April 2008, Laurent Pinchart wrote:
> > I'm implementing flow control and modem control lines support in the
> > cpm_uart driver.
> >
> > The implementation is based on the GPIO lib. Modem control lines are
> > described in the device tree as GPIO resources and accessed through the OF
> > GPIO bindings. The I/O ports have to be initialized as GPIOs in the
> > platform-specific code.
> I don't follow the "have to be" ... why couldn't the platform
> setup code know that if a given UART is being used with hardware
> handshaking, that means a particular pin mux config should be used?

Flow control and modem control lines are two different beasts (although flow 
control uses a subset of the modem control lines).

The UART driver needs to get and set the modem control lines state. This is 
easily handled by the GPIO library without requiring any change to GPIO lib. 
The only requirement, as stated above, is that platform-specific code 
initializes the corresponding pins as GPIOs. I'm not sure to understand what 
you don't get, as my point is that the platform setup code must configure the 
pins appropriately, exactly as you mention in your comment.

> Are there maybe some on-chip routing options, so that for example
> RTS2 could come out on any of three different balls?  (In which
> case that setup code could just be told *which* config to use...)

That's possible yes, but that's not really an issue. Platform setup code is by 
definition platform-specific and has knowledge of the hardware, so it can 
setup pins correctly.

> In this case I'm asking specifically about the normal all-works-ok
> situation ... no errata or similar complications I mention below.
> >  An option would be to export gpio_to_chip from drivers/gpio/gpiolib.c
> >  and use cpm1/2_set_pin in the cpm_uart driver.
> Help me to understand this a bit.  UARTs are a fair example of places
> where I've seen such pin reconfiguration be useful, but it's never
> seemed to be generalizable except possibly as callbacks to SOC-specific
> code (which don't imply updating generic programming interfaces).

Callbacks worked fine on ppc but are now more difficult to implement in 
powerpc. This is why I'm looking for a generic solution based on the device 

> I've seen examples where the hardware flow control normally works, so
> that board setup sets up those pins in "hardware flow control" mode
> when it's told the board has them wired up that way ... but then, some
> chip revisions have errata forcing the driver to use a particular
> port's handshake pins as GPIOs in some cases.  (Obviously troublesome
> except at low data rates, so one hopes the board designers just avoid
> using those UARTs in that mode.)

The issue is that flow control must be configurable. Userspace software can 
turn it on or off. To handle that on CPM2-based platforms, the pins connected 
to CTS and RTS must be switched between GPIO mode (no flow control) and 
dedicated function mode (hard flow control) at runtime in the UART driver.

> I've also seen examples where the UART clock needs to be disabled in
> deeper sleep states, but the system still wants the UART to be a wake
> event source ... by having either the START bit, or maybe BREAK (it
> gives a longer latch period), kick in a gpio-based pin change IRQ on
> the UARTn.RX line.
> Now in *both* of those examples I've seen before, the solution could
> not be generic.  When the pin was used as GPIO, a particular pinmux
> configuration was needed.  (Bitfield X of register Y has value Z ...
> or maybe a couple registers needed to change.)  And when used as a
> UART signal, a different one was used.  (Same setup.  Maybe value Z
> became value W.  Or again, maybe a few registers needed changing.)
> And for different chips in the family, sometimes even different
> revisions of one chip, the W/X/Y/Z/etc values differed even for UART1.
> For other UARTs, the same was true.
> So given that ... how would knowing the GPIO chip help, when I'd
> still need to find out the W/X/Y/Z/etc values?  And if I've got a
> way to convey W/X/Y/Z/etc -- canonical example being a callback to
> the relevant SOC-specific code --  why shouldn't that obviate the
> need for any scheme to look up the gpio chip?

On Freescale PowerPC hardware (specifically CPM2-based, but CPM1 and QE are 
quite similar), pins can either have a dedicated functionality or be used as 
a GPIO. This is handled through a group of registers, which are

- the data register, used in GPIO mode only
- the direction register, used in both GPIO and dedicated modes
- the pin assignment register, used to switch between GPIO and dedicated mode
- the open-drain register, used to switch between push-pull and open drain 

Let's take the UART CTS signal as an example, connected to port C, pin 15. The 
pin is always a push-pull output, so that configuration can be set in 
platform setup code. Let's assume that hard flow control is disabled as 
startup, so platform setup code configures PC15 as a GPIO (pin assignment 
register cleared).

The data register can then be used to set or clear CTS in response to the 
TIOCMSET ioctl. The UART driver just calls gpio_set_value() and everybody is 

Now, when enabling hard flow control, the CTS pin has to be switched to 
dedicated mode. The GPIO lib has no API for that, and abstract GPIO numbers 
can't be mapped to platform-specific pins as there is no API for that.

To switch hard flow control on and off, the UART driver will need either an 
extension to the GPIO API to set and clear the pin assignment register, or a 
way to retrieve a reference to the GPIO chip to call platform-specific GPIO 
functions, not exported through the generic GPIO API.

Laurent Pinchart
CSE Semaphore Belgium

Chaussee de Bruxelles, 732A
B-1410 Waterloo

T +32 (2) 387 42 59
F +32 (2) 387 42 75
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: not available
URL: <http://lists.ozlabs.org/pipermail/linuxppc-dev/attachments/20080520/57fc2285/attachment.pgp>

More information about the Linuxppc-dev mailing list