diff options
author | Masahiro Yamada <yamada.masahiro@socionext.com> | 2016-05-31 04:05:15 -0400 |
---|---|---|
committer | Linus Walleij <linus.walleij@linaro.org> | 2016-05-31 06:47:18 -0400 |
commit | 94bf176b9784e55f3f5fe1015cd9cbc168743563 (patch) | |
tree | 8a92150c9fa3f5ce1baa3272def94b5ec73e8eb7 /drivers/pinctrl/uniphier | |
parent | 72e5706aa786f6640b229717b7d9d537058c59cf (diff) |
pinctrl: uniphier: support pin configuration in sparse pin space
Unfortunately, the pin number of the new SoC, PH1-LD11, is not
contiguous. The base frame work must be adjusted to support the new
SoC pinctrl driver. The pin_desc_get() exploits radix-tree for pin
look-up, so it works more efficiently with sparse pin space.
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Diffstat (limited to 'drivers/pinctrl/uniphier')
-rw-r--r-- | drivers/pinctrl/uniphier/pinctrl-uniphier-core.c | 86 |
1 files changed, 42 insertions, 44 deletions
diff --git a/drivers/pinctrl/uniphier/pinctrl-uniphier-core.c b/drivers/pinctrl/uniphier/pinctrl-uniphier-core.c index 017b84fd9333..39e33757dfda 100644 --- a/drivers/pinctrl/uniphier/pinctrl-uniphier-core.c +++ b/drivers/pinctrl/uniphier/pinctrl-uniphier-core.c | |||
@@ -64,10 +64,10 @@ static int uniphier_pctl_get_group_pins(struct pinctrl_dev *pctldev, | |||
64 | static void uniphier_pctl_pin_dbg_show(struct pinctrl_dev *pctldev, | 64 | static void uniphier_pctl_pin_dbg_show(struct pinctrl_dev *pctldev, |
65 | struct seq_file *s, unsigned offset) | 65 | struct seq_file *s, unsigned offset) |
66 | { | 66 | { |
67 | const struct pinctrl_pin_desc *pin = &pctldev->desc->pins[offset]; | 67 | const struct pin_desc *desc = pin_desc_get(pctldev, offset); |
68 | const char *pull_dir, *drv_type; | 68 | const char *pull_dir, *drv_type; |
69 | 69 | ||
70 | switch (uniphier_pin_get_pull_dir(pin->drv_data)) { | 70 | switch (uniphier_pin_get_pull_dir(desc->drv_data)) { |
71 | case UNIPHIER_PIN_PULL_UP: | 71 | case UNIPHIER_PIN_PULL_UP: |
72 | pull_dir = "UP"; | 72 | pull_dir = "UP"; |
73 | break; | 73 | break; |
@@ -87,7 +87,7 @@ static void uniphier_pctl_pin_dbg_show(struct pinctrl_dev *pctldev, | |||
87 | BUG(); | 87 | BUG(); |
88 | } | 88 | } |
89 | 89 | ||
90 | switch (uniphier_pin_get_drv_type(pin->drv_data)) { | 90 | switch (uniphier_pin_get_drv_type(desc->drv_data)) { |
91 | case UNIPHIER_PIN_DRV_1BIT: | 91 | case UNIPHIER_PIN_DRV_1BIT: |
92 | drv_type = "4/8(mA)"; | 92 | drv_type = "4/8(mA)"; |
93 | break; | 93 | break; |
@@ -129,12 +129,12 @@ static const struct pinctrl_ops uniphier_pctlops = { | |||
129 | }; | 129 | }; |
130 | 130 | ||
131 | static int uniphier_conf_pin_bias_get(struct pinctrl_dev *pctldev, | 131 | static int uniphier_conf_pin_bias_get(struct pinctrl_dev *pctldev, |
132 | const struct pinctrl_pin_desc *pin, | 132 | const struct pin_desc *desc, |
133 | enum pin_config_param param) | 133 | enum pin_config_param param) |
134 | { | 134 | { |
135 | struct uniphier_pinctrl_priv *priv = pinctrl_dev_get_drvdata(pctldev); | 135 | struct uniphier_pinctrl_priv *priv = pinctrl_dev_get_drvdata(pctldev); |
136 | enum uniphier_pin_pull_dir pull_dir = | 136 | enum uniphier_pin_pull_dir pull_dir = |
137 | uniphier_pin_get_pull_dir(pin->drv_data); | 137 | uniphier_pin_get_pull_dir(desc->drv_data); |
138 | unsigned int pupdctrl, reg, shift, val; | 138 | unsigned int pupdctrl, reg, shift, val; |
139 | unsigned int expected = 1; | 139 | unsigned int expected = 1; |
140 | int ret; | 140 | int ret; |
@@ -164,7 +164,7 @@ static int uniphier_conf_pin_bias_get(struct pinctrl_dev *pctldev, | |||
164 | BUG(); | 164 | BUG(); |
165 | } | 165 | } |
166 | 166 | ||
167 | pupdctrl = uniphier_pin_get_pupdctrl(pin->drv_data); | 167 | pupdctrl = uniphier_pin_get_pupdctrl(desc->drv_data); |
168 | 168 | ||
169 | reg = UNIPHIER_PINCTRL_PUPDCTRL_BASE + pupdctrl / 32 * 4; | 169 | reg = UNIPHIER_PINCTRL_PUPDCTRL_BASE + pupdctrl / 32 * 4; |
170 | shift = pupdctrl % 32; | 170 | shift = pupdctrl % 32; |
@@ -179,12 +179,12 @@ static int uniphier_conf_pin_bias_get(struct pinctrl_dev *pctldev, | |||
179 | } | 179 | } |
180 | 180 | ||
181 | static int uniphier_conf_pin_drive_get(struct pinctrl_dev *pctldev, | 181 | static int uniphier_conf_pin_drive_get(struct pinctrl_dev *pctldev, |
182 | const struct pinctrl_pin_desc *pin, | 182 | const struct pin_desc *desc, |
183 | u16 *strength) | 183 | u16 *strength) |
184 | { | 184 | { |
185 | struct uniphier_pinctrl_priv *priv = pinctrl_dev_get_drvdata(pctldev); | 185 | struct uniphier_pinctrl_priv *priv = pinctrl_dev_get_drvdata(pctldev); |
186 | enum uniphier_pin_drv_type type = | 186 | enum uniphier_pin_drv_type type = |
187 | uniphier_pin_get_drv_type(pin->drv_data); | 187 | uniphier_pin_get_drv_type(desc->drv_data); |
188 | const unsigned int strength_1bit[] = {4, 8}; | 188 | const unsigned int strength_1bit[] = {4, 8}; |
189 | const unsigned int strength_2bit[] = {8, 12, 16, 20}; | 189 | const unsigned int strength_2bit[] = {8, 12, 16, 20}; |
190 | const unsigned int strength_3bit[] = {4, 5, 7, 9, 11, 12, 14, 16}; | 190 | const unsigned int strength_3bit[] = {4, 5, 7, 9, 11, 12, 14, 16}; |
@@ -222,7 +222,7 @@ static int uniphier_conf_pin_drive_get(struct pinctrl_dev *pctldev, | |||
222 | return -EINVAL; | 222 | return -EINVAL; |
223 | } | 223 | } |
224 | 224 | ||
225 | drvctrl = uniphier_pin_get_drvctrl(pin->drv_data); | 225 | drvctrl = uniphier_pin_get_drvctrl(desc->drv_data); |
226 | drvctrl *= width; | 226 | drvctrl *= width; |
227 | 227 | ||
228 | reg += drvctrl / 32 * 4; | 228 | reg += drvctrl / 32 * 4; |
@@ -239,10 +239,10 @@ static int uniphier_conf_pin_drive_get(struct pinctrl_dev *pctldev, | |||
239 | } | 239 | } |
240 | 240 | ||
241 | static int uniphier_conf_pin_input_enable_get(struct pinctrl_dev *pctldev, | 241 | static int uniphier_conf_pin_input_enable_get(struct pinctrl_dev *pctldev, |
242 | const struct pinctrl_pin_desc *pin) | 242 | const struct pin_desc *desc) |
243 | { | 243 | { |
244 | struct uniphier_pinctrl_priv *priv = pinctrl_dev_get_drvdata(pctldev); | 244 | struct uniphier_pinctrl_priv *priv = pinctrl_dev_get_drvdata(pctldev); |
245 | unsigned int iectrl = uniphier_pin_get_iectrl(pin->drv_data); | 245 | unsigned int iectrl = uniphier_pin_get_iectrl(desc->drv_data); |
246 | unsigned int val; | 246 | unsigned int val; |
247 | int ret; | 247 | int ret; |
248 | 248 | ||
@@ -261,7 +261,7 @@ static int uniphier_conf_pin_config_get(struct pinctrl_dev *pctldev, | |||
261 | unsigned pin, | 261 | unsigned pin, |
262 | unsigned long *configs) | 262 | unsigned long *configs) |
263 | { | 263 | { |
264 | const struct pinctrl_pin_desc *pin_desc = &pctldev->desc->pins[pin]; | 264 | const struct pin_desc *desc = pin_desc_get(pctldev, pin); |
265 | enum pin_config_param param = pinconf_to_config_param(*configs); | 265 | enum pin_config_param param = pinconf_to_config_param(*configs); |
266 | bool has_arg = false; | 266 | bool has_arg = false; |
267 | u16 arg; | 267 | u16 arg; |
@@ -271,14 +271,14 @@ static int uniphier_conf_pin_config_get(struct pinctrl_dev *pctldev, | |||
271 | case PIN_CONFIG_BIAS_DISABLE: | 271 | case PIN_CONFIG_BIAS_DISABLE: |
272 | case PIN_CONFIG_BIAS_PULL_UP: | 272 | case PIN_CONFIG_BIAS_PULL_UP: |
273 | case PIN_CONFIG_BIAS_PULL_DOWN: | 273 | case PIN_CONFIG_BIAS_PULL_DOWN: |
274 | ret = uniphier_conf_pin_bias_get(pctldev, pin_desc, param); | 274 | ret = uniphier_conf_pin_bias_get(pctldev, desc, param); |
275 | break; | 275 | break; |
276 | case PIN_CONFIG_DRIVE_STRENGTH: | 276 | case PIN_CONFIG_DRIVE_STRENGTH: |
277 | ret = uniphier_conf_pin_drive_get(pctldev, pin_desc, &arg); | 277 | ret = uniphier_conf_pin_drive_get(pctldev, desc, &arg); |
278 | has_arg = true; | 278 | has_arg = true; |
279 | break; | 279 | break; |
280 | case PIN_CONFIG_INPUT_ENABLE: | 280 | case PIN_CONFIG_INPUT_ENABLE: |
281 | ret = uniphier_conf_pin_input_enable_get(pctldev, pin_desc); | 281 | ret = uniphier_conf_pin_input_enable_get(pctldev, desc); |
282 | break; | 282 | break; |
283 | default: | 283 | default: |
284 | /* unsupported parameter */ | 284 | /* unsupported parameter */ |
@@ -293,13 +293,12 @@ static int uniphier_conf_pin_config_get(struct pinctrl_dev *pctldev, | |||
293 | } | 293 | } |
294 | 294 | ||
295 | static int uniphier_conf_pin_bias_set(struct pinctrl_dev *pctldev, | 295 | static int uniphier_conf_pin_bias_set(struct pinctrl_dev *pctldev, |
296 | const struct pinctrl_pin_desc *pin, | 296 | const struct pin_desc *desc, |
297 | enum pin_config_param param, | 297 | enum pin_config_param param, u16 arg) |
298 | u16 arg) | ||
299 | { | 298 | { |
300 | struct uniphier_pinctrl_priv *priv = pinctrl_dev_get_drvdata(pctldev); | 299 | struct uniphier_pinctrl_priv *priv = pinctrl_dev_get_drvdata(pctldev); |
301 | enum uniphier_pin_pull_dir pull_dir = | 300 | enum uniphier_pin_pull_dir pull_dir = |
302 | uniphier_pin_get_pull_dir(pin->drv_data); | 301 | uniphier_pin_get_pull_dir(desc->drv_data); |
303 | unsigned int pupdctrl, reg, shift; | 302 | unsigned int pupdctrl, reg, shift; |
304 | unsigned int val = 1; | 303 | unsigned int val = 1; |
305 | 304 | ||
@@ -310,8 +309,8 @@ static int uniphier_conf_pin_bias_set(struct pinctrl_dev *pctldev, | |||
310 | if (pull_dir == UNIPHIER_PIN_PULL_UP_FIXED || | 309 | if (pull_dir == UNIPHIER_PIN_PULL_UP_FIXED || |
311 | pull_dir == UNIPHIER_PIN_PULL_DOWN_FIXED) { | 310 | pull_dir == UNIPHIER_PIN_PULL_DOWN_FIXED) { |
312 | dev_err(pctldev->dev, | 311 | dev_err(pctldev->dev, |
313 | "can not disable pull register for pin %u (%s)\n", | 312 | "can not disable pull register for pin %s\n", |
314 | pin->number, pin->name); | 313 | desc->name); |
315 | return -EINVAL; | 314 | return -EINVAL; |
316 | } | 315 | } |
317 | val = 0; | 316 | val = 0; |
@@ -321,8 +320,8 @@ static int uniphier_conf_pin_bias_set(struct pinctrl_dev *pctldev, | |||
321 | return 0; | 320 | return 0; |
322 | if (pull_dir != UNIPHIER_PIN_PULL_UP) { | 321 | if (pull_dir != UNIPHIER_PIN_PULL_UP) { |
323 | dev_err(pctldev->dev, | 322 | dev_err(pctldev->dev, |
324 | "pull-up is unsupported for pin %u (%s)\n", | 323 | "pull-up is unsupported for pin %s\n", |
325 | pin->number, pin->name); | 324 | desc->name); |
326 | return -EINVAL; | 325 | return -EINVAL; |
327 | } | 326 | } |
328 | if (arg == 0) { | 327 | if (arg == 0) { |
@@ -335,8 +334,8 @@ static int uniphier_conf_pin_bias_set(struct pinctrl_dev *pctldev, | |||
335 | return 0; | 334 | return 0; |
336 | if (pull_dir != UNIPHIER_PIN_PULL_DOWN) { | 335 | if (pull_dir != UNIPHIER_PIN_PULL_DOWN) { |
337 | dev_err(pctldev->dev, | 336 | dev_err(pctldev->dev, |
338 | "pull-down is unsupported for pin %u (%s)\n", | 337 | "pull-down is unsupported for pin %s\n", |
339 | pin->number, pin->name); | 338 | desc->name); |
340 | return -EINVAL; | 339 | return -EINVAL; |
341 | } | 340 | } |
342 | if (arg == 0) { | 341 | if (arg == 0) { |
@@ -347,8 +346,8 @@ static int uniphier_conf_pin_bias_set(struct pinctrl_dev *pctldev, | |||
347 | case PIN_CONFIG_BIAS_PULL_PIN_DEFAULT: | 346 | case PIN_CONFIG_BIAS_PULL_PIN_DEFAULT: |
348 | if (pull_dir == UNIPHIER_PIN_PULL_NONE) { | 347 | if (pull_dir == UNIPHIER_PIN_PULL_NONE) { |
349 | dev_err(pctldev->dev, | 348 | dev_err(pctldev->dev, |
350 | "pull-up/down is unsupported for pin %u (%s)\n", | 349 | "pull-up/down is unsupported for pin %s\n", |
351 | pin->number, pin->name); | 350 | desc->name); |
352 | return -EINVAL; | 351 | return -EINVAL; |
353 | } | 352 | } |
354 | 353 | ||
@@ -359,7 +358,7 @@ static int uniphier_conf_pin_bias_set(struct pinctrl_dev *pctldev, | |||
359 | BUG(); | 358 | BUG(); |
360 | } | 359 | } |
361 | 360 | ||
362 | pupdctrl = uniphier_pin_get_pupdctrl(pin->drv_data); | 361 | pupdctrl = uniphier_pin_get_pupdctrl(desc->drv_data); |
363 | 362 | ||
364 | reg = UNIPHIER_PINCTRL_PUPDCTRL_BASE + pupdctrl / 32 * 4; | 363 | reg = UNIPHIER_PINCTRL_PUPDCTRL_BASE + pupdctrl / 32 * 4; |
365 | shift = pupdctrl % 32; | 364 | shift = pupdctrl % 32; |
@@ -368,12 +367,12 @@ static int uniphier_conf_pin_bias_set(struct pinctrl_dev *pctldev, | |||
368 | } | 367 | } |
369 | 368 | ||
370 | static int uniphier_conf_pin_drive_set(struct pinctrl_dev *pctldev, | 369 | static int uniphier_conf_pin_drive_set(struct pinctrl_dev *pctldev, |
371 | const struct pinctrl_pin_desc *pin, | 370 | const struct pin_desc *desc, |
372 | u16 strength) | 371 | u16 strength) |
373 | { | 372 | { |
374 | struct uniphier_pinctrl_priv *priv = pinctrl_dev_get_drvdata(pctldev); | 373 | struct uniphier_pinctrl_priv *priv = pinctrl_dev_get_drvdata(pctldev); |
375 | enum uniphier_pin_drv_type type = | 374 | enum uniphier_pin_drv_type type = |
376 | uniphier_pin_get_drv_type(pin->drv_data); | 375 | uniphier_pin_get_drv_type(desc->drv_data); |
377 | const unsigned int strength_1bit[] = {4, 8, -1}; | 376 | const unsigned int strength_1bit[] = {4, 8, -1}; |
378 | const unsigned int strength_2bit[] = {8, 12, 16, 20, -1}; | 377 | const unsigned int strength_2bit[] = {8, 12, 16, 20, -1}; |
379 | const unsigned int strength_3bit[] = {4, 5, 7, 9, 11, 12, 14, 16, -1}; | 378 | const unsigned int strength_3bit[] = {4, 5, 7, 9, 11, 12, 14, 16, -1}; |
@@ -398,8 +397,8 @@ static int uniphier_conf_pin_drive_set(struct pinctrl_dev *pctldev, | |||
398 | break; | 397 | break; |
399 | default: | 398 | default: |
400 | dev_err(pctldev->dev, | 399 | dev_err(pctldev->dev, |
401 | "cannot change drive strength for pin %u (%s)\n", | 400 | "cannot change drive strength for pin %s\n", |
402 | pin->number, pin->name); | 401 | desc->name); |
403 | return -EINVAL; | 402 | return -EINVAL; |
404 | } | 403 | } |
405 | 404 | ||
@@ -410,14 +409,14 @@ static int uniphier_conf_pin_drive_set(struct pinctrl_dev *pctldev, | |||
410 | 409 | ||
411 | if (val == 0) { | 410 | if (val == 0) { |
412 | dev_err(pctldev->dev, | 411 | dev_err(pctldev->dev, |
413 | "unsupported drive strength %u mA for pin %u (%s)\n", | 412 | "unsupported drive strength %u mA for pin %s\n", |
414 | strength, pin->number, pin->name); | 413 | strength, desc->name); |
415 | return -EINVAL; | 414 | return -EINVAL; |
416 | } | 415 | } |
417 | 416 | ||
418 | val--; | 417 | val--; |
419 | 418 | ||
420 | drvctrl = uniphier_pin_get_drvctrl(pin->drv_data); | 419 | drvctrl = uniphier_pin_get_drvctrl(desc->drv_data); |
421 | drvctrl *= width; | 420 | drvctrl *= width; |
422 | 421 | ||
423 | reg += drvctrl / 32 * 4; | 422 | reg += drvctrl / 32 * 4; |
@@ -429,11 +428,11 @@ static int uniphier_conf_pin_drive_set(struct pinctrl_dev *pctldev, | |||
429 | } | 428 | } |
430 | 429 | ||
431 | static int uniphier_conf_pin_input_enable(struct pinctrl_dev *pctldev, | 430 | static int uniphier_conf_pin_input_enable(struct pinctrl_dev *pctldev, |
432 | const struct pinctrl_pin_desc *pin, | 431 | const struct pin_desc *desc, |
433 | u16 enable) | 432 | u16 enable) |
434 | { | 433 | { |
435 | struct uniphier_pinctrl_priv *priv = pinctrl_dev_get_drvdata(pctldev); | 434 | struct uniphier_pinctrl_priv *priv = pinctrl_dev_get_drvdata(pctldev); |
436 | unsigned int iectrl = uniphier_pin_get_iectrl(pin->drv_data); | 435 | unsigned int iectrl = uniphier_pin_get_iectrl(desc->drv_data); |
437 | 436 | ||
438 | if (enable == 0) { | 437 | if (enable == 0) { |
439 | /* | 438 | /* |
@@ -457,7 +456,7 @@ static int uniphier_conf_pin_config_set(struct pinctrl_dev *pctldev, | |||
457 | unsigned long *configs, | 456 | unsigned long *configs, |
458 | unsigned num_configs) | 457 | unsigned num_configs) |
459 | { | 458 | { |
460 | const struct pinctrl_pin_desc *pin_desc = &pctldev->desc->pins[pin]; | 459 | const struct pin_desc *desc = pin_desc_get(pctldev, pin); |
461 | int i, ret; | 460 | int i, ret; |
462 | 461 | ||
463 | for (i = 0; i < num_configs; i++) { | 462 | for (i = 0; i < num_configs; i++) { |
@@ -470,16 +469,15 @@ static int uniphier_conf_pin_config_set(struct pinctrl_dev *pctldev, | |||
470 | case PIN_CONFIG_BIAS_PULL_UP: | 469 | case PIN_CONFIG_BIAS_PULL_UP: |
471 | case PIN_CONFIG_BIAS_PULL_DOWN: | 470 | case PIN_CONFIG_BIAS_PULL_DOWN: |
472 | case PIN_CONFIG_BIAS_PULL_PIN_DEFAULT: | 471 | case PIN_CONFIG_BIAS_PULL_PIN_DEFAULT: |
473 | ret = uniphier_conf_pin_bias_set(pctldev, pin_desc, | 472 | ret = uniphier_conf_pin_bias_set(pctldev, desc, |
474 | param, arg); | 473 | param, arg); |
475 | break; | 474 | break; |
476 | case PIN_CONFIG_DRIVE_STRENGTH: | 475 | case PIN_CONFIG_DRIVE_STRENGTH: |
477 | ret = uniphier_conf_pin_drive_set(pctldev, pin_desc, | 476 | ret = uniphier_conf_pin_drive_set(pctldev, desc, arg); |
478 | arg); | ||
479 | break; | 477 | break; |
480 | case PIN_CONFIG_INPUT_ENABLE: | 478 | case PIN_CONFIG_INPUT_ENABLE: |
481 | ret = uniphier_conf_pin_input_enable(pctldev, | 479 | ret = uniphier_conf_pin_input_enable(pctldev, desc, |
482 | pin_desc, arg); | 480 | arg); |
483 | break; | 481 | break; |
484 | default: | 482 | default: |
485 | dev_err(pctldev->dev, | 483 | dev_err(pctldev->dev, |
@@ -561,7 +559,7 @@ static int uniphier_pmx_set_one_mux(struct pinctrl_dev *pctldev, unsigned pin, | |||
561 | 559 | ||
562 | /* some pins need input-enabling */ | 560 | /* some pins need input-enabling */ |
563 | ret = uniphier_conf_pin_input_enable(pctldev, | 561 | ret = uniphier_conf_pin_input_enable(pctldev, |
564 | &pctldev->desc->pins[pin], 1); | 562 | pin_desc_get(pctldev, pin), 1); |
565 | if (ret) | 563 | if (ret) |
566 | return ret; | 564 | return ret; |
567 | 565 | ||