Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

pinctrl: add a pin_base for sparse gpio-ranges

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>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>

authored by

Chanho Park and committed by
Linus Walleij
3c739ad0 33d58949

+34 -29
+23 -25
Documentation/pinctrl.txt
··· 214 214 .name = "chip a", 215 215 .id = 0, 216 216 .base = 32, 217 + .pin_base = 32, 217 218 .npins = 16, 218 219 .gc = &chip_a; 219 220 }; 220 221 221 - static struct pinctrl_gpio_range gpio_range_a = { 222 + static struct pinctrl_gpio_range gpio_range_b = { 222 223 .name = "chip b", 223 224 .id = 0, 224 225 .base = 48, 226 + .pin_base = 64, 225 227 .npins = 8, 226 228 .gc = &chip_b; 227 229 }; 228 - 229 230 230 231 { 231 232 struct pinctrl_dev *pctl; ··· 236 235 } 237 236 238 237 So this complex system has one pin controller handling two different 239 - GPIO chips. Chip a has 16 pins and chip b has 8 pins. They are mapped in 240 - the global GPIO pin space at: 238 + GPIO chips. "chip a" has 16 pins and "chip b" has 8 pins. The "chip a" and 239 + "chip b" have different .pin_base, which means a start pin number of the 240 + GPIO range. 241 241 242 - chip a: [32 .. 47] 243 - chip b: [48 .. 55] 242 + The GPIO range of "chip a" starts from the GPIO base of 32 and actual 243 + pin range also starts from 32. However "chip b" has different starting 244 + offset for the GPIO range and pin range. The GPIO range of "chip b" starts 245 + from GPIO number 48, while the pin range of "chip b" starts from 64. 246 + 247 + We can convert a gpio number to actual pin number using this "pin_base". 248 + They are mapped in the global GPIO pin space at: 249 + 250 + chip a: 251 + - GPIO range : [32 .. 47] 252 + - pin range : [32 .. 47] 253 + chip b: 254 + - GPIO range : [48 .. 55] 255 + - pin range : [64 .. 71] 244 256 245 257 When GPIO-specific functions in the pin control subsystem are called, these 246 258 ranges will be used to look up the appropriate pin controller by inspecting ··· 263 249 264 250 For all functionalities dealing with pin biasing, pin muxing etc, the pin 265 251 controller subsystem will subtract the range's .base offset from the passed 266 - in gpio pin number, and pass that on to the pin control driver, so the driver 267 - will get an offset into its handled number range. Further it is also passed 252 + in gpio number, and add the ranges's .pin_base offset to retrive a pin number. 253 + After that, the subsystem passes it on to the pin control driver, so the driver 254 + will get an pin number into its handled number range. Further it is also passed 268 255 the range ID value, so that the pin controller knows which range it should 269 256 deal with. 270 - 271 - For example: if a user issues pinctrl_gpio_set_foo(50), the pin control 272 - subsystem will find that the second range on this pin controller matches, 273 - subtract the base 48 and call the 274 - pinctrl_driver_gpio_set_foo(pinctrl, range, 2) where the latter function has 275 - this signature: 276 - 277 - int pinctrl_driver_gpio_set_foo(struct pinctrl_dev *pctldev, 278 - struct pinctrl_gpio_range *rangeid, 279 - unsigned offset); 280 - 281 - Now the driver knows that we want to do some GPIO-specific operation on the 282 - second GPIO range handled by "chip b", at offset 2 in that specific range. 283 - 284 - (If the GPIO subsystem is ever refactored to use a local per-GPIO controller 285 - pin space, this mapping will need to be augmented accordingly.) 286 - 287 257 288 258 PINMUX interfaces 289 259 =================
+5 -1
drivers/pinctrl/pinmux-sirf.c
··· 1067 1067 spmx = pinctrl_dev_get_drvdata(pmxdev); 1068 1068 1069 1069 muxval = readl(spmx->gpio_virtbase + SIRFSOC_GPIO_PAD_EN(group)); 1070 - muxval = muxval | (1 << offset); 1070 + muxval = muxval | (1 << (offset - range->pin_base)); 1071 1071 writel(muxval, spmx->gpio_virtbase + SIRFSOC_GPIO_PAD_EN(group)); 1072 1072 1073 1073 return 0; ··· 1100 1100 .name = "sirfsoc-gpio*", 1101 1101 .id = 0, 1102 1102 .base = 0, 1103 + .pin_base = 0, 1103 1104 .npins = 32, 1104 1105 }, { 1105 1106 .name = "sirfsoc-gpio*", 1106 1107 .id = 1, 1107 1108 .base = 32, 1109 + .pin_base = 32, 1108 1110 .npins = 32, 1109 1111 }, { 1110 1112 .name = "sirfsoc-gpio*", 1111 1113 .id = 2, 1112 1114 .base = 64, 1115 + .pin_base = 64, 1113 1116 .npins = 32, 1114 1117 }, { 1115 1118 .name = "sirfsoc-gpio*", 1116 1119 .id = 3, 1117 1120 .base = 96, 1121 + .pin_base = 96, 1118 1122 .npins = 19, 1119 1123 }, 1120 1124 };
+1
drivers/pinctrl/pinmux-u300.c
··· 1026 1026 .name = "COH901*", 1027 1027 .id = 0, 1028 1028 .base = 0, 1029 + .pin_base = 0, 1029 1030 .npins = 64, 1030 1031 }; 1031 1032
+2 -2
drivers/pinctrl/pinmux.c
··· 229 229 return -EINVAL; 230 230 231 231 /* Convert to the pin controllers number space */ 232 - pin = gpio - range->base; 232 + pin = gpio - range->base + range->pin_base; 233 233 234 234 /* Conjure some name stating what chip and pin this is taken by */ 235 235 snprintf(gpiostr, 15, "%s:%d", range->name, gpio); ··· 263 263 return; 264 264 265 265 /* Convert to the pin controllers number space */ 266 - pin = gpio - range->base; 266 + pin = gpio - range->base + range->pin_base; 267 267 268 268 func = pin_free(pctldev, pin, range); 269 269 kfree(func);
+2
include/linux/pinctrl/pinctrl.h
··· 45 45 * @name: a name for the chip in this range 46 46 * @id: an ID number for the chip in this range 47 47 * @base: base offset of the GPIO range 48 + * @pin_base: base pin number of the GPIO range 48 49 * @npins: number of pins in the GPIO range, including the base number 49 50 * @gc: an optional pointer to a gpio_chip 50 51 */ ··· 54 53 const char *name; 55 54 unsigned int id; 56 55 unsigned int base; 56 + unsigned int pin_base; 57 57 unsigned int npins; 58 58 struct gpio_chip *gc; 59 59 };
+1 -1
include/linux/pinctrl/pinmux.h
··· 52 52 * @disable: disable a certain muxing selector with a certain pin group 53 53 * @gpio_request_enable: requests and enables GPIO on a certain pin. 54 54 * Implement this only if you can mux every pin individually as GPIO. The 55 - * affected GPIO range is passed along with an offset into that 55 + * affected GPIO range is passed along with an offset(pin number) into that 56 56 * specific GPIO range - function selectors and pin groups are orthogonal 57 57 * to this, the core will however make sure the pins do not collide 58 58 */