[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20130510082521.GA2125@ab42.lan>
Date: Fri, 10 May 2013 10:25:23 +0200
From: Christian Ruppert <christian.ruppert@...lis.com>
To: Stephen Warren <swarren@...dotorg.org>
Cc: Linus Walleij <linus.walleij@...aro.org>,
Patrice CHOTARD <patrice.chotard@...com>,
"linux-kernel@...r.kernel.org" <linux-kernel@...r.kernel.org>,
Grant Likely <grant.likely@...retlab.ca>,
Rob Herring <rob.herring@...xeda.com>,
Rob Landley <rob@...dley.net>,
Sascha Leuenberger <sascha.leuenberger@...lis.com>,
Pierrick Hascoet <pierrick.hascoet@...lis.com>,
"devicetree-discuss@...ts.ozlabs.org"
<devicetree-discuss@...ts.ozlabs.org>,
"linux-doc@...r.kernel.org" <linux-doc@...r.kernel.org>
Subject: Re: [PATCH 1/2] pinmux: Add TB10x pinmux driver
On Wed, May 08, 2013 at 02:01:53PM -0600, Stephen Warren wrote:
> On 05/08/2013 10:41 AM, Christian Ruppert wrote:
> ...
> > What do you think about the following modification to the pinctrl/GPIO
> > frameworks instead (not yet a formal patch, more a request for comment
> > to illustrate what I mean. If you agree, I will clean it up and submit a
> > proper patch after discussion).
> >
> > It adds a dt_gpiorange_xlate function to the pinctrl callbacks which
> > defaults to the conventional behaviour using kernel logical pin numbers.
> > However, pin controllers which provide more complex mechanisms can
> > define #gpio-range-cells and provide this callback in order to keep
> > Linux pin numbering inside the kernel.
>
> Can you provide an example of the DT content, and explain exactly what
> this patch does with it; what effect it has on the existing GPIO or
> pinctrl code?
The patch does not change the default behaviour of the kernel: In case
no dt_gpiorange_xlate callback is defined for a given driver (e.g. for
pre-existing drivers), the default function simply interprets the first
argument as Linux pin number and the second as pin count, same as now.
New drivers can use the callback to translate device specific pin
references to Linux pin numbers (in the idea of of_xlate in the GPIO
framework or xlate in the irqchip framework).
In the case of TB10x, I was thinking of something in the lines of
iomux: iomux@...0601c {
#gpio-range-cells = <1>; /* one cell used for gpiorange phandle */
compatible = "abilis,tb10x-iomux";
reg = <0xFF10601c 0x4>;
pctl_gpio_a: pctl-gpio-a { /* define phandle to GPIOA I/O function */
pingrp = "gpioa_pins";
};
pctl_gpio_b: pctl-gpio-b { /* define phandle to GPIOB I/O function */
pingrp = "gpiob_pins";
};
pctl_uart0: pctl-uart0 { /* define phandle to UART0 I/O function */
pingrp = "uart0_pins";
};
};
uart@...00000 {
compatible = "snps,dw-apb-uart";
reg = <0xFF100000 0x100>;
clock-frequency = <166666666>;
interrupts = <25 1>;
reg-shift = <2>;
reg-io-width = <4>;
pinctrl-names = "default"; /* For non-GPIO modules, request I/O */
pinctrl-0 = <&pctl_uart0>; /* functions normally */
};
gpioa: gpio@...40000 {
compatible = "abilis,tb10x-gpio";
reg = <0xFF140000 0x1000>;
gpio-controller;
#gpio-cells = <2>;
gpio-ranges = <&iomux &pctl_gpio_a>; /* (*1) */
};
gpioa: gpio@...40000 {
compatible = "abilis,tb10x-gpio";
reg = <0xFF140000 0x1000>;
gpio-controller;
#gpio-cells = <2>;
pinctrl-names = "default" /* here the GPIO controller requests */
pinctrl-0 = <&pctl_gpio_b>; /* the entire GPIOB port explicitly */
gpio-ranges = <&iomux &pctl_gpio_b>; /* (*2) */
};
(*1) TB100 GPIO ranges are defined as a phandle to the I/O function
which provides all pins of a given GPIO port. This function is not
necessarily requested from pinctrl and GPIO ports may overlap with
other functions. The pin controller knows about this and provides
whatever GPIO pin is available after mapping other requested
functions.
(*2) Here, the entire GPIOB port is explicitly requested by the GPIO
module, i.e. all pins of the port are made available as GPIOs.
The xlate function in pinctrl-tb10x.c would look something like this:
static int tb10x_dt_gpiorange_xlate(struct pinctrl_dev *pctldev,
struct device_node *np,
u32 *rangespec, int rangespecsize,
u32 *pin_offset, u32 *npins)
{
const char *name;
int ret;
struct tb10x_pinfuncgrp *pfg;
struct device_node *dn;
if (rangespecsize != 1)
return -EINVAL;
dn = of_find_node_by_phandle(rangespec[0]);
if (!dn)
return -EINVAL;
of_node_put(dn);
ret = of_property_read_string(dn, "pingrp", &name);
if (ret)
return ret;
pfg = tb10x_get_pinfuncgrp(name);
if (IS_ERR(pfg))
return PTR_ERR(pfg);
if (!pfg->isgpio)
return -EINVAL;
*pin_offset = pfg->pins[0];
*npins = pfg->pincnt;
return 0;
}
Other drivers may use physical pin numbers, assign integer identifiers
to each GPIO bank or use some other numbering scheme documented in
Documentation/devicetree/bindings.
Greetings,
Christian
--
Christian Ruppert , <christian.ruppert@...lis.com>
/|
Tel: +41/(0)22 816 19-42 //| 3, Chemin du Pré-Fleuri
_// | bilis Systems CH-1228 Plan-les-Ouates
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Powered by blists - more mailing lists