]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
pinctrl: add a pin_base for sparse gpio-ranges
authorChanho Park <chanho61.park@samsung.com>
Fri, 11 Nov 2011 09:47:58 +0000 (18:47 +0900)
committerLinus Walleij <linus.walleij@linaro.org>
Wed, 30 Nov 2011 15:18:52 +0000 (16:18 +0100)
This patch enables mapping a base offset of gpio ranges with
a pin offset even if does'nt matched. A base of pinctrl_gpio_range
means a base offset of gpio. However, we cannot convert gpio to pin
number for sparse gpio ranges just only using a gpio base offset.
We can convert a gpio to real pin number(even if not matched) using
a new pin_base which means a base pin offset of requested gpio range.
Now, the pin control subsystem passes the pin base offset to the
pinmux driver.

For example, let's assume below two gpio ranges in the system.

static struct pinctrl_gpio_range gpio_range_a = {
    .name = "chip a",
    .id = 0,
    .base = 32,
    .pin_base = 32,
    .npins = 16,
    .gc = &chip_a;
};

static struct pinctrl_gpio_range gpio_range_b = {
    .name = "chip b",
    .id = 0,
    .base = 48,
    .pin_base = 64,
    .npins = 8,
    .gc = &chip_b;
};

We can calucalate a exact pin ranges even if doesn't matched with gpio ranges.

chip a:
    gpio-range : [32 .. 47]
    pin-range  : [32 .. 47]
chip b:
    gpio-range : [48 .. 55]
    pin-range  : [64 .. 71]

Signed-off-by: Chanho Park <chanho61.park@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
Documentation/pinctrl.txt
drivers/pinctrl/pinmux-sirf.c
drivers/pinctrl/pinmux-u300.c
drivers/pinctrl/pinmux.c
include/linux/pinctrl/pinctrl.h
include/linux/pinctrl/pinmux.h

index f78ebce09b9b9fb9cdb0ec8d2026f9bbb010fdcc..b33c84c421bf9351d58bd7665e2afea1f5617173 100644 (file)
@@ -214,19 +214,20 @@ static struct pinctrl_gpio_range gpio_range_a = {
        .name = "chip a",
        .id = 0,
        .base = 32,
+       .pin_base = 32,
        .npins = 16,
        .gc = &chip_a;
 };
 
-static struct pinctrl_gpio_range gpio_range_a = {
+static struct pinctrl_gpio_range gpio_range_b = {
        .name = "chip b",
        .id = 0,
        .base = 48,
+       .pin_base = 64,
        .npins = 8,
        .gc = &chip_b;
 };
 
-
 {
        struct pinctrl_dev *pctl;
        ...
@@ -235,11 +236,24 @@ static struct pinctrl_gpio_range gpio_range_a = {
 }
 
 So this complex system has one pin controller handling two different
-GPIO chips. Chip a has 16 pins and chip b has 8 pins. They are mapped in
-the global GPIO pin space at:
+GPIO chips. "chip a" has 16 pins and "chip b" has 8 pins. The "chip a" and
+"chip b" have different .pin_base, which means a start pin number of the
+GPIO range.
+
+The GPIO range of "chip a" starts from the GPIO base of 32 and actual
+pin range also starts from 32. However "chip b" has different starting
+offset for the GPIO range and pin range. The GPIO range of "chip b" starts
+from GPIO number 48, while the pin range of "chip b" starts from 64.
 
-chip a: [32 .. 47]
-chip b: [48 .. 55]
+We can convert a gpio number to actual pin number using this "pin_base".
+They are mapped in the global GPIO pin space at:
+
+chip a:
+ - GPIO range : [32 .. 47]
+ - pin range  : [32 .. 47]
+chip b:
+ - GPIO range : [48 .. 55]
+ - pin range  : [64 .. 71]
 
 When GPIO-specific functions in the pin control subsystem are called, these
 ranges will be used to look up the appropriate pin controller by inspecting
@@ -249,28 +263,12 @@ will be called on that specific pin controller.
 
 For all functionalities dealing with pin biasing, pin muxing etc, the pin
 controller subsystem will subtract the range's .base offset from the passed
-in gpio pin number, and pass that on to the pin control driver, so the driver
-will get an offset into its handled number range. Further it is also passed
+in gpio number, and add the ranges's .pin_base offset to retrive a pin number.
+After that, the subsystem passes it on to the pin control driver, so the driver
+will get an pin number into its handled number range. Further it is also passed
 the range ID value, so that the pin controller knows which range it should
 deal with.
 
-For example: if a user issues pinctrl_gpio_set_foo(50), the pin control
-subsystem will find that the second range on this pin controller matches,
-subtract the base 48 and call the
-pinctrl_driver_gpio_set_foo(pinctrl, range, 2) where the latter function has
-this signature:
-
-int pinctrl_driver_gpio_set_foo(struct pinctrl_dev *pctldev,
-    struct pinctrl_gpio_range *rangeid,
-    unsigned offset);
-
-Now the driver knows that we want to do some GPIO-specific operation on the
-second GPIO range handled by "chip b", at offset 2 in that specific range.
-
-(If the GPIO subsystem is ever refactored to use a local per-GPIO controller
-pin space, this mapping will need to be augmented accordingly.)
-
-
 PINMUX interfaces
 =================
 
index d76cae620956900361d729d6f9b9f436580018be..c3ade82c516bca2ba8cff851ab5acd1377086f59 100644 (file)
@@ -1067,7 +1067,7 @@ static int sirfsoc_pinmux_request_gpio(struct pinctrl_dev *pmxdev,
        spmx = pinctrl_dev_get_drvdata(pmxdev);
 
        muxval = readl(spmx->gpio_virtbase + SIRFSOC_GPIO_PAD_EN(group));
-       muxval = muxval | (1 << offset);
+       muxval = muxval | (1 << (offset - range->pin_base));
        writel(muxval, spmx->gpio_virtbase + SIRFSOC_GPIO_PAD_EN(group));
 
        return 0;
@@ -1100,21 +1100,25 @@ static struct pinctrl_gpio_range sirfsoc_gpio_ranges[] = {
                .name = "sirfsoc-gpio*",
                .id = 0,
                .base = 0,
+               .pin_base = 0,
                .npins = 32,
        }, {
                .name = "sirfsoc-gpio*",
                .id = 1,
                .base = 32,
+               .pin_base = 32,
                .npins = 32,
        }, {
                .name = "sirfsoc-gpio*",
                .id = 2,
                .base = 64,
+               .pin_base = 64,
                .npins = 32,
        }, {
                .name = "sirfsoc-gpio*",
                .id = 3,
                .base = 96,
+               .pin_base = 96,
                .npins = 19,
        },
 };
index 145a84dc16e6dccc0986c7bec7e7b77bc0d98ac8..bcf61bee7763842aa488d9e871efd4b2f2b8f383 100644 (file)
@@ -1026,6 +1026,7 @@ static struct pinctrl_gpio_range u300_gpio_range = {
        .name = "COH901*",
        .id = 0,
        .base = 0,
+       .pin_base = 0,
        .npins = 64,
 };
 
index 4b35661bdfe9d98173aa066c1adaff509d6ee178..d27b77d0ee88573aee80a8df61640da0814a3d99 100644 (file)
@@ -233,7 +233,7 @@ int pinmux_request_gpio(unsigned gpio)
                return -EINVAL;
 
        /* Convert to the pin controllers number space */
-       pin = gpio - range->base;
+       pin = gpio - range->base + range->pin_base;
 
        /* Conjure some name stating what chip and pin this is taken by */
        snprintf(gpiostr, 15, "%s:%d", range->name, gpio);
@@ -267,7 +267,7 @@ void pinmux_free_gpio(unsigned gpio)
                return;
 
        /* Convert to the pin controllers number space */
-       pin = gpio - range->base;
+       pin = gpio - range->base + range->pin_base;
 
        func = pin_free(pctldev, pin, range);
        kfree(func);
index 04c011038f32080ff6489c5a8cd11aad4878f571..f17fac4b51f185dc789475203643ef918a7b5956 100644 (file)
@@ -45,6 +45,7 @@ struct pinctrl_pin_desc {
  * @name: a name for the chip in this range
  * @id: an ID number for the chip in this range
  * @base: base offset of the GPIO range
+ * @pin_base: base pin number of the GPIO range
  * @npins: number of pins in the GPIO range, including the base number
  * @gc: an optional pointer to a gpio_chip
  */
@@ -53,6 +54,7 @@ struct pinctrl_gpio_range {
        const char *name;
        unsigned int id;
        unsigned int base;
+       unsigned int pin_base;
        unsigned int npins;
        struct gpio_chip *gc;
 };
index 350e32a98c6aadcdc93ae1d7c12c0b3e3426d506..bb7a9792f1eafc9c8ab4985f43c662bdadca765f 100644 (file)
@@ -52,7 +52,7 @@ struct pinctrl_dev;
  * @disable: disable a certain muxing selector with a certain pin group
  * @gpio_request_enable: requests and enables GPIO on a certain pin.
  *     Implement this only if you can mux every pin individually as GPIO. The
- *     affected GPIO range is passed along with an offset into that
+ *     affected GPIO range is passed along with an offset(pin number) into that
  *     specific GPIO range - function selectors and pin groups are orthogonal
  *     to this, the core will however make sure the pins do not collide
  */