diff options
-rw-r--r-- | drivers/pinctrl/core.h | 2 | ||||
-rw-r--r-- | drivers/pinctrl/pinmux.c | 68 |
2 files changed, 69 insertions, 1 deletions
diff --git a/drivers/pinctrl/core.h b/drivers/pinctrl/core.h index 1cae3723bbed..5b3ff134d6db 100644 --- a/drivers/pinctrl/core.h +++ b/drivers/pinctrl/core.h | |||
@@ -126,6 +126,7 @@ struct pinctrl_setting { | |||
126 | * @owner: The name of the entity owning the pin. Typically, this is the name | 126 | * @owner: The name of the entity owning the pin. Typically, this is the name |
127 | * of the device that called pinctrl_get(). Alternatively, it may be the | 127 | * of the device that called pinctrl_get(). Alternatively, it may be the |
128 | * name of the GPIO passed to pinctrl_request_gpio(). | 128 | * name of the GPIO passed to pinctrl_request_gpio(). |
129 | * @mux_setting: The most recent selected mux setting for this pin, if any. | ||
129 | */ | 130 | */ |
130 | struct pin_desc { | 131 | struct pin_desc { |
131 | struct pinctrl_dev *pctldev; | 132 | struct pinctrl_dev *pctldev; |
@@ -135,6 +136,7 @@ struct pin_desc { | |||
135 | #ifdef CONFIG_PINMUX | 136 | #ifdef CONFIG_PINMUX |
136 | unsigned usecount; | 137 | unsigned usecount; |
137 | const char *owner; | 138 | const char *owner; |
139 | const struct pinctrl_setting_mux *mux_setting; | ||
138 | #endif | 140 | #endif |
139 | }; | 141 | }; |
140 | 142 | ||
diff --git a/drivers/pinctrl/pinmux.c b/drivers/pinctrl/pinmux.c index 4852ebe5712e..86e401754116 100644 --- a/drivers/pinctrl/pinmux.c +++ b/drivers/pinctrl/pinmux.c | |||
@@ -187,6 +187,7 @@ static const char *pin_free(struct pinctrl_dev *pctldev, int pin, | |||
187 | 187 | ||
188 | owner = desc->owner; | 188 | owner = desc->owner; |
189 | desc->owner = NULL; | 189 | desc->owner = NULL; |
190 | desc->mux_setting = NULL; | ||
190 | module_put(pctldev->owner); | 191 | module_put(pctldev->owner); |
191 | 192 | ||
192 | return owner; | 193 | return owner; |
@@ -378,7 +379,34 @@ void pinmux_free_setting(struct pinctrl_setting const *setting) | |||
378 | int pinmux_enable_setting(struct pinctrl_setting const *setting) | 379 | int pinmux_enable_setting(struct pinctrl_setting const *setting) |
379 | { | 380 | { |
380 | struct pinctrl_dev *pctldev = setting->pctldev; | 381 | struct pinctrl_dev *pctldev = setting->pctldev; |
382 | const struct pinctrl_ops *pctlops = pctldev->desc->pctlops; | ||
381 | const struct pinmux_ops *ops = pctldev->desc->pmxops; | 383 | const struct pinmux_ops *ops = pctldev->desc->pmxops; |
384 | int ret; | ||
385 | const unsigned *pins; | ||
386 | unsigned num_pins; | ||
387 | int i; | ||
388 | struct pin_desc *desc; | ||
389 | |||
390 | ret = pctlops->get_group_pins(pctldev, setting->data.mux.group, | ||
391 | &pins, &num_pins); | ||
392 | if (ret) { | ||
393 | /* errors only affect debug data, so just warn */ | ||
394 | dev_warn(pctldev->dev, | ||
395 | "could not get pins for group selector %d\n", | ||
396 | setting->data.mux.group); | ||
397 | num_pins = 0; | ||
398 | } | ||
399 | |||
400 | for (i = 0; i < num_pins; i++) { | ||
401 | desc = pin_desc_get(pctldev, pins[i]); | ||
402 | if (desc == NULL) { | ||
403 | dev_warn(pctldev->dev, | ||
404 | "could not get pin desc for pin %d\n", | ||
405 | pins[i]); | ||
406 | continue; | ||
407 | } | ||
408 | desc->mux_setting = &(setting->data.mux); | ||
409 | } | ||
382 | 410 | ||
383 | return ops->enable(pctldev, setting->data.mux.func, | 411 | return ops->enable(pctldev, setting->data.mux.func, |
384 | setting->data.mux.group); | 412 | setting->data.mux.group); |
@@ -387,7 +415,34 @@ int pinmux_enable_setting(struct pinctrl_setting const *setting) | |||
387 | void pinmux_disable_setting(struct pinctrl_setting const *setting) | 415 | void pinmux_disable_setting(struct pinctrl_setting const *setting) |
388 | { | 416 | { |
389 | struct pinctrl_dev *pctldev = setting->pctldev; | 417 | struct pinctrl_dev *pctldev = setting->pctldev; |
418 | const struct pinctrl_ops *pctlops = pctldev->desc->pctlops; | ||
390 | const struct pinmux_ops *ops = pctldev->desc->pmxops; | 419 | const struct pinmux_ops *ops = pctldev->desc->pmxops; |
420 | int ret; | ||
421 | const unsigned *pins; | ||
422 | unsigned num_pins; | ||
423 | int i; | ||
424 | struct pin_desc *desc; | ||
425 | |||
426 | ret = pctlops->get_group_pins(pctldev, setting->data.mux.group, | ||
427 | &pins, &num_pins); | ||
428 | if (ret) { | ||
429 | /* errors only affect debug data, so just warn */ | ||
430 | dev_warn(pctldev->dev, | ||
431 | "could not get pins for group selector %d\n", | ||
432 | setting->data.mux.group); | ||
433 | num_pins = 0; | ||
434 | } | ||
435 | |||
436 | for (i = 0; i < num_pins; i++) { | ||
437 | desc = pin_desc_get(pctldev, pins[i]); | ||
438 | if (desc == NULL) { | ||
439 | dev_warn(pctldev->dev, | ||
440 | "could not get pin desc for pin %d\n", | ||
441 | pins[i]); | ||
442 | continue; | ||
443 | } | ||
444 | desc->mux_setting = NULL; | ||
445 | } | ||
391 | 446 | ||
392 | ops->disable(pctldev, setting->data.mux.func, setting->data.mux.group); | 447 | ops->disable(pctldev, setting->data.mux.func, setting->data.mux.group); |
393 | } | 448 | } |
@@ -433,6 +488,8 @@ static int pinmux_functions_show(struct seq_file *s, void *what) | |||
433 | static int pinmux_pins_show(struct seq_file *s, void *what) | 488 | static int pinmux_pins_show(struct seq_file *s, void *what) |
434 | { | 489 | { |
435 | struct pinctrl_dev *pctldev = s->private; | 490 | struct pinctrl_dev *pctldev = s->private; |
491 | const struct pinctrl_ops *pctlops = pctldev->desc->pctlops; | ||
492 | const struct pinmux_ops *pmxops = pctldev->desc->pmxops; | ||
436 | unsigned i, pin; | 493 | unsigned i, pin; |
437 | 494 | ||
438 | seq_puts(s, "Pinmux settings per pin\n"); | 495 | seq_puts(s, "Pinmux settings per pin\n"); |
@@ -455,10 +512,19 @@ static int pinmux_pins_show(struct seq_file *s, void *what) | |||
455 | !strcmp(desc->owner, pinctrl_dev_get_name(pctldev))) | 512 | !strcmp(desc->owner, pinctrl_dev_get_name(pctldev))) |
456 | is_hog = true; | 513 | is_hog = true; |
457 | 514 | ||
458 | seq_printf(s, "pin %d (%s): %s%s\n", pin, | 515 | seq_printf(s, "pin %d (%s): %s%s", pin, |
459 | desc->name ? desc->name : "unnamed", | 516 | desc->name ? desc->name : "unnamed", |
460 | desc->owner ? desc->owner : "UNCLAIMED", | 517 | desc->owner ? desc->owner : "UNCLAIMED", |
461 | is_hog ? " (HOG)" : ""); | 518 | is_hog ? " (HOG)" : ""); |
519 | |||
520 | if (desc->mux_setting) | ||
521 | seq_printf(s, " function %s group %s\n", | ||
522 | pmxops->get_function_name(pctldev, | ||
523 | desc->mux_setting->func), | ||
524 | pctlops->get_group_name(pctldev, | ||
525 | desc->mux_setting->group)); | ||
526 | else | ||
527 | seq_printf(s, "\n"); | ||
462 | } | 528 | } |
463 | 529 | ||
464 | mutex_unlock(&pinctrl_mutex); | 530 | mutex_unlock(&pinctrl_mutex); |