Re: pinctrl:when two device use the same pin

From: Linus Walleij
Date: Thu Jun 13 2013 - 03:43:47 EST


On Thu, Jun 13, 2013 at 4:43 AM, xulinuxkernel <xulinuxkernel@xxxxxxxxx> wrote:

> I am using the kernel pinctrl subsystem, and I have a problem,when two
> devices use the same pin,how about the consumer devices handle the conflict
> pins? some thing like this:
> assumer the device A and B use the same pin pin0,
> device A: device
> B calling the API
> devm_pinctrl_get_select(&dev_a,"dev_a");
> devm_pinctrl_get_select(&dev_b,"dev_b");
> then the deviceB should be return error,or wait for device A release pin0?
> like schedule()? or something else?

So you have one of two problems:

- You are trying to probe two drivers on the system, both making
use of the same pins *at the same time*, this would obviously
be plain wrong. In this case the solution would be not to add
the unused device in the first place.

- You are using the same pins with two different devices at
runtime, i.e. dev A and B actually use the same pins on the
same one running system.

I assume it's the latter situation, which appear in a few practical
situations, such as a SD card slot being reconfigured into a debug
port becuase we want to get some non-SD-type data out on the
SD card connector. (We have this on the ux500.)

The solution to this situation is described in Documentation/pinctrl.txt
under the heading "Runtime pinmuxing", below is a copy but I think
the basic problem is that you rely on devm_pinctrl_get_select()
to be done at probe instead of retrieveing the pinctrl state handlers
and activeley switching between them at runtime using
pinctrl_select_state() which is what you should do.

Device A should have two states: one which is not using any
pins, and one where it's actively using it's pins, and the same
for device B. At runtime, the drivers shall just activate the state
using the pins when they actually do that.


Copy from Documentation/pinctrl.txt:

Runtime pinmuxing
=================

It is possible to mux a certain function in and out at runtime, say to move
an SPI port from one set of pins to another set of pins. Say for example for
spi0 in the example above, we expose two different groups of pins for the same
function, but with different named in the mapping as described under
"Advanced mapping" above. So that for an SPI device, we have two states named
"pos-A" and "pos-B".

This snippet first muxes the function in the pins defined by group A, enables
it, disables and releases it, and muxes it in on the pins defined by group B:

#include <linux/pinctrl/consumer.h>

struct pinctrl *p;
struct pinctrl_state *s1, *s2;

foo_probe()
{
/* Setup */
p = devm_pinctrl_get(&device);
if (IS_ERR(p))
...

s1 = pinctrl_lookup_state(foo->p, "pos-A");
if (IS_ERR(s1))
...

s2 = pinctrl_lookup_state(foo->p, "pos-B");
if (IS_ERR(s2))
...
}

foo_switch()
{
/* Enable on position A */
ret = pinctrl_select_state(s1);
if (ret < 0)
...

...

/* Enable on position B */
ret = pinctrl_select_state(s2);
if (ret < 0)
...

...
}

The above has to be done from process context. The reservation of the pins
will be done when the state is activated, so in effect one specific pin
can be used by different functions at different times on a running system.


Yours,
Linus Walleij
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/