aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pinctrl/core.c
diff options
context:
space:
mode:
authorStephen Warren <swarren@nvidia.com>2012-03-02 15:05:45 -0500
committerLinus Walleij <linus.walleij@linaro.org>2012-03-05 05:20:50 -0500
commit7ecdb16fe63e5b356335ebdc236adfb48cef31e1 (patch)
tree036d9939c64f98e1f85343f15c12ad83c9a2a890 /drivers/pinctrl/core.c
parent57b676f9c1b7cd84397fe5a86c9bd2788ac4bd32 (diff)
pinctrl: refactor struct pinctrl handling in core.c vs pinmux.c
This change separates two aspects of struct pinctrl: a) The data representation of the parsed mapping table, into: 1) The top-level struct pinctrl object, a single entity returned by pinctrl_get(). 2) The parsed version of each mapping table entry, struct pinctrl_setting, of which there is one per mapping table entry. b) The code that handles this; the code for (1) above is in core.c, and the code to parse/execute each entry in (2) above is in pinmux.c, while the iteration over multiple settings is lifted to core.c. This will allow the following future changes: 1) pinctrl_get() API rework, so that struct pinctrl represents all states for the device, and the device can select between them without calling put()/get() again. 2) To support that, a struct pinctrl_state object will be inserted into the data model between the struct pinctrl and struct pinctrl_setting. 3) The mapping table will be extended to allow specification of pin config settings too. To support this, struct pinctrl_setting will be enhanced to store either mux settings or config settings, and functions will be added to pinconf.c to parse/execute pin configuration settings. Signed-off-by: Stephen Warren <swarren@nvidia.com> Acked-by: Linus Walleij <linus.walleij@linaro.org> Acked-by: Dong Aisheng <dong.aisheng@linaro.org> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Diffstat (limited to 'drivers/pinctrl/core.c')
-rw-r--r--drivers/pinctrl/core.c105
1 files changed, 66 insertions, 39 deletions
diff --git a/drivers/pinctrl/core.c b/drivers/pinctrl/core.c
index aefc3394db91..535f8d53c289 100644
--- a/drivers/pinctrl/core.c
+++ b/drivers/pinctrl/core.c
@@ -460,14 +460,15 @@ EXPORT_SYMBOL_GPL(pinctrl_gpio_direction_output);
460 460
461static struct pinctrl *pinctrl_get_locked(struct device *dev, const char *name) 461static struct pinctrl *pinctrl_get_locked(struct device *dev, const char *name)
462{ 462{
463 struct pinctrl_dev *pctldev = NULL; 463 struct pinctrl_dev *pctldev;
464 const char *devname; 464 const char *devname;
465 struct pinctrl *p; 465 struct pinctrl *p;
466 unsigned num_maps = 0; 466 unsigned num_maps = 0;
467 int ret = -ENODEV; 467 int ret;
468 struct pinctrl_maps *maps_node; 468 struct pinctrl_maps *maps_node;
469 int i; 469 int i;
470 struct pinctrl_map const *map; 470 struct pinctrl_map const *map;
471 struct pinctrl_setting *setting;
471 472
472 /* We must have both a dev and state name */ 473 /* We must have both a dev and state name */
473 if (WARN_ON(!dev || !name)) 474 if (WARN_ON(!dev || !name))
@@ -487,39 +488,50 @@ static struct pinctrl *pinctrl_get_locked(struct device *dev, const char *name)
487 dev_err(dev, "failed to alloc struct pinctrl\n"); 488 dev_err(dev, "failed to alloc struct pinctrl\n");
488 return ERR_PTR(-ENOMEM); 489 return ERR_PTR(-ENOMEM);
489 } 490 }
490 pinmux_init_pinctrl_handle(p); 491 p->dev = dev;
492 p->state = name;
493 INIT_LIST_HEAD(&p->settings);
491 494
492 /* Iterate over the pin control maps to locate the right ones */ 495 /* Iterate over the pin control maps to locate the right ones */
493 for_each_maps(maps_node, i, map) { 496 for_each_maps(maps_node, i, map) {
497 /* Map must be for this device */
498 if (strcmp(map->dev_name, devname))
499 continue;
500
501 /* State name must be the one we're looking for */
502 if (strcmp(map->name, name))
503 continue;
504
494 /* 505 /*
495 * First, try to find the pctldev given in the map 506 * Try to find the pctldev given in the map
496 */ 507 */
497 pctldev = get_pinctrl_dev_from_devname(map->ctrl_dev_name); 508 pctldev = get_pinctrl_dev_from_devname(map->ctrl_dev_name);
498 if (!pctldev) { 509 if (!pctldev) {
499 dev_err(dev, "unknown pinctrl device %s in map entry", 510 dev_err(dev, "unknown pinctrl device %s in map entry",
500 map->ctrl_dev_name); 511 map->ctrl_dev_name);
501 pinmux_put(p);
502 kfree(p);
503 /* Eventually, this should trigger deferred probe */ 512 /* Eventually, this should trigger deferred probe */
504 return ERR_PTR(-ENODEV); 513 ret = -ENODEV;
514 goto error;
505 } 515 }
506 516
507 dev_dbg(dev, "in map, found pctldev %s to handle function %s", 517 dev_dbg(dev, "in map, found pctldev %s to handle function %s",
508 dev_name(pctldev->dev), map->function); 518 dev_name(pctldev->dev), map->function);
509 519
510 /* Map must be for this device */ 520 setting = kzalloc(sizeof(*setting), GFP_KERNEL);
511 if (strcmp(map->dev_name, devname)) 521 if (setting == NULL) {
512 continue; 522 dev_err(dev,
523 "failed to alloc struct pinctrl_setting\n");
524 ret = -ENOMEM;
525 goto error;
526 }
513 527
514 /* State name must be the one we're looking for */ 528 setting->pctldev = pctldev;
515 if (strcmp(map->name, name)) 529 ret = pinmux_map_to_setting(map, setting);
516 continue; 530 if (ret < 0)
531 goto error;
532
533 list_add_tail(&setting->node, &p->settings);
517 534
518 ret = pinmux_apply_muxmap(pctldev, p, dev, devname, map);
519 if (ret) {
520 kfree(p);
521 return ERR_PTR(ret);
522 }
523 num_maps++; 535 num_maps++;
524 } 536 }
525 537
@@ -541,6 +553,14 @@ static struct pinctrl *pinctrl_get_locked(struct device *dev, const char *name)
541 list_add_tail(&p->node, &pinctrl_list); 553 list_add_tail(&p->node, &pinctrl_list);
542 554
543 return p; 555 return p;
556
557error:
558 list_for_each_entry(setting, &p->settings, node)
559 pinmux_free_setting(setting);
560
561 kfree(p);
562
563 return ERR_PTR(ret);
544} 564}
545 565
546/** 566/**
@@ -564,13 +584,18 @@ EXPORT_SYMBOL_GPL(pinctrl_get);
564 584
565static void pinctrl_put_locked(struct pinctrl *p) 585static void pinctrl_put_locked(struct pinctrl *p)
566{ 586{
587 struct pinctrl_setting *setting, *n;
588
567 if (p == NULL) 589 if (p == NULL)
568 return; 590 return;
569 591
570 if (p->usecount) 592 if (p->usecount)
571 pr_warn("releasing pin control handle with active users!\n"); 593 pr_warn("releasing pin control handle with active users!\n");
572 /* Free the groups and all acquired pins */ 594 list_for_each_entry_safe(setting, n, &p->settings, node) {
573 pinmux_put(p); 595 pinmux_free_setting(setting);
596 list_del(&setting->node);
597 kfree(setting);
598 }
574 599
575 /* Remove from list */ 600 /* Remove from list */
576 list_del(&p->node); 601 list_del(&p->node);
@@ -592,18 +617,24 @@ EXPORT_SYMBOL_GPL(pinctrl_put);
592 617
593static int pinctrl_enable_locked(struct pinctrl *p) 618static int pinctrl_enable_locked(struct pinctrl *p)
594{ 619{
595 int ret = 0; 620 struct pinctrl_setting *setting;
621 int ret;
596 622
597 if (p == NULL) 623 if (p == NULL)
598 return -EINVAL; 624 return -EINVAL;
599 625
600 if (p->usecount++ == 0) { 626 if (p->usecount++ == 0) {
601 ret = pinmux_enable(p); 627 list_for_each_entry(setting, &p->settings, node) {
602 if (ret) 628 ret = pinmux_enable_setting(setting);
603 p->usecount--; 629 if (ret < 0) {
630 /* FIXME: Difficult to return to prev state */
631 p->usecount--;
632 return ret;
633 }
634 }
604 } 635 }
605 636
606 return ret; 637 return 0;
607} 638}
608 639
609/** 640/**
@@ -622,11 +653,14 @@ EXPORT_SYMBOL_GPL(pinctrl_enable);
622 653
623static void pinctrl_disable_locked(struct pinctrl *p) 654static void pinctrl_disable_locked(struct pinctrl *p)
624{ 655{
656 struct pinctrl_setting *setting;
657
625 if (p == NULL) 658 if (p == NULL)
626 return; 659 return;
627 660
628 if (--p->usecount == 0) { 661 if (--p->usecount == 0) {
629 pinmux_disable(p); 662 list_for_each_entry(setting, &p->settings, node)
663 pinmux_disable_setting(setting);
630 } 664 }
631} 665}
632 666
@@ -857,27 +891,20 @@ static int pinctrl_maps_show(struct seq_file *s, void *what)
857static int pinctrl_show(struct seq_file *s, void *what) 891static int pinctrl_show(struct seq_file *s, void *what)
858{ 892{
859 struct pinctrl *p; 893 struct pinctrl *p;
894 struct pinctrl_setting *setting;
860 895
861 seq_puts(s, "Requested pin control handlers their pinmux maps:\n"); 896 seq_puts(s, "Requested pin control handlers their pinmux maps:\n");
862 897
863 mutex_lock(&pinctrl_mutex); 898 mutex_lock(&pinctrl_mutex);
864 899
865 list_for_each_entry(p, &pinctrl_list, node) { 900 list_for_each_entry(p, &pinctrl_list, node) {
866 struct pinctrl_dev *pctldev = p->pctldev; 901 seq_printf(s, "device: %s state: %s users: %u\n",
902 dev_name(p->dev), p->state, p->usecount);
867 903
868 if (!pctldev) { 904 list_for_each_entry(setting, &p->settings, node) {
869 seq_puts(s, "NO PIN CONTROLLER DEVICE\n"); 905 seq_printf(s, " ");
870 continue; 906 pinmux_dbg_show(s, setting);
871 } 907 }
872
873 seq_printf(s, "device: %s",
874 pinctrl_dev_get_name(p->pctldev));
875
876 pinmux_dbg_show(s, p);
877
878 seq_printf(s, " users: %u map-> %s\n",
879 p->usecount,
880 p->dev ? dev_name(p->dev) : "(system)");
881 } 908 }
882 909
883 mutex_unlock(&pinctrl_mutex); 910 mutex_unlock(&pinctrl_mutex);