summaryrefslogtreecommitdiffstats
path: root/drivers/pinctrl/pinmux.c
diff options
context:
space:
mode:
authorTony Lindgren <tony@atomide.com>2016-12-27 12:20:01 -0500
committerLinus Walleij <linus.walleij@linaro.org>2017-01-03 03:26:18 -0500
commita76edc89b100e4fefb2a5c00cd8cd557437659e7 (patch)
tree0131d6cad80d2ed78c97b485b0a2d9cf2a446877 /drivers/pinctrl/pinmux.c
parentc033a718f615b6b3ddc83ce3e0a217c30bd09cb5 (diff)
pinctrl: core: Add generic pinctrl functions for managing groups
We can add generic helpers for function handling for cases where the pin controller driver does not need to use static arrays. Signed-off-by: Tony Lindgren <tony@atomide.com> [Renamed the Kconfig item and moved things around] Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Diffstat (limited to 'drivers/pinctrl/pinmux.c')
-rw-r--r--drivers/pinctrl/pinmux.c173
1 files changed, 173 insertions, 0 deletions
diff --git a/drivers/pinctrl/pinmux.c b/drivers/pinctrl/pinmux.c
index 9373146f3afc..29ad3151abec 100644
--- a/drivers/pinctrl/pinmux.c
+++ b/drivers/pinctrl/pinmux.c
@@ -682,3 +682,176 @@ void pinmux_init_device_debugfs(struct dentry *devroot,
682} 682}
683 683
684#endif /* CONFIG_DEBUG_FS */ 684#endif /* CONFIG_DEBUG_FS */
685
686#ifdef CONFIG_GENERIC_PINMUX_FUNCTIONS
687
688/**
689 * pinmux_generic_get_function_count() - returns number of functions
690 * @pctldev: pin controller device
691 */
692int pinmux_generic_get_function_count(struct pinctrl_dev *pctldev)
693{
694 return pctldev->num_functions;
695}
696EXPORT_SYMBOL_GPL(pinmux_generic_get_function_count);
697
698/**
699 * pinmux_generic_get_function_name() - returns the function name
700 * @pctldev: pin controller device
701 * @selector: function number
702 */
703const char *
704pinmux_generic_get_function_name(struct pinctrl_dev *pctldev,
705 unsigned int selector)
706{
707 struct function_desc *function;
708
709 function = radix_tree_lookup(&pctldev->pin_function_tree,
710 selector);
711 if (!function)
712 return NULL;
713
714 return function->name;
715}
716EXPORT_SYMBOL_GPL(pinmux_generic_get_function_name);
717
718/**
719 * pinmux_generic_get_function_groups() - gets the function groups
720 * @pctldev: pin controller device
721 * @selector: function number
722 * @groups: array of pin groups
723 * @num_groups: number of pin groups
724 */
725int pinmux_generic_get_function_groups(struct pinctrl_dev *pctldev,
726 unsigned int selector,
727 const char * const **groups,
728 unsigned * const num_groups)
729{
730 struct function_desc *function;
731
732 function = radix_tree_lookup(&pctldev->pin_function_tree,
733 selector);
734 if (!function) {
735 dev_err(pctldev->dev, "%s could not find function%i\n",
736 __func__, selector);
737 return -EINVAL;
738 }
739 *groups = function->group_names;
740 *num_groups = function->num_group_names;
741
742 return 0;
743}
744EXPORT_SYMBOL_GPL(pinmux_generic_get_function_groups);
745
746/**
747 * pinmux_generic_get_function() - returns a function based on the number
748 * @pctldev: pin controller device
749 * @group_selector: function number
750 */
751struct function_desc *pinmux_generic_get_function(struct pinctrl_dev *pctldev,
752 unsigned int selector)
753{
754 struct function_desc *function;
755
756 function = radix_tree_lookup(&pctldev->pin_function_tree,
757 selector);
758 if (!function)
759 return NULL;
760
761 return function;
762}
763EXPORT_SYMBOL_GPL(pinmux_generic_get_function);
764
765/**
766 * pinmux_generic_get_function_groups() - gets the function groups
767 * @pctldev: pin controller device
768 * @name: name of the function
769 * @groups: array of pin groups
770 * @num_groups: number of pin groups
771 * @data: pin controller driver specific data
772 */
773int pinmux_generic_add_function(struct pinctrl_dev *pctldev,
774 const char *name,
775 const char **groups,
776 const unsigned int num_groups,
777 void *data)
778{
779 struct function_desc *function;
780
781 function = devm_kzalloc(pctldev->dev, sizeof(*function), GFP_KERNEL);
782 if (!function)
783 return -ENOMEM;
784
785 function->name = name;
786 function->group_names = groups;
787 function->num_group_names = num_groups;
788 function->data = data;
789
790 radix_tree_insert(&pctldev->pin_function_tree, pctldev->num_functions,
791 function);
792
793 pctldev->num_functions++;
794
795 return 0;
796}
797EXPORT_SYMBOL_GPL(pinmux_generic_add_function);
798
799/**
800 * pinmux_generic_remove_function() - removes a numbered function
801 * @pctldev: pin controller device
802 * @selector: function number
803 *
804 * Note that the caller must take care of locking.
805 */
806int pinmux_generic_remove_function(struct pinctrl_dev *pctldev,
807 unsigned int selector)
808{
809 struct function_desc *function;
810
811 function = radix_tree_lookup(&pctldev->pin_function_tree,
812 selector);
813 if (!function)
814 return -ENOENT;
815
816 radix_tree_delete(&pctldev->pin_function_tree, selector);
817 devm_kfree(pctldev->dev, function);
818
819 pctldev->num_functions--;
820
821 return 0;
822}
823EXPORT_SYMBOL_GPL(pinmux_generic_remove_function);
824
825/**
826 * pinmux_generic_free_functions() - removes all functions
827 * @pctldev: pin controller device
828 *
829 * Note that the caller must take care of locking.
830 */
831void pinmux_generic_free_functions(struct pinctrl_dev *pctldev)
832{
833 struct radix_tree_iter iter;
834 struct function_desc *function;
835 unsigned long *indices;
836 void **slot;
837 int i = 0;
838
839 indices = devm_kzalloc(pctldev->dev, sizeof(*indices) *
840 pctldev->num_functions, GFP_KERNEL);
841 if (!indices)
842 return;
843
844 radix_tree_for_each_slot(slot, &pctldev->pin_function_tree, &iter, 0)
845 indices[i++] = iter.index;
846
847 for (i = 0; i < pctldev->num_functions; i++) {
848 function = radix_tree_lookup(&pctldev->pin_function_tree,
849 indices[i]);
850 radix_tree_delete(&pctldev->pin_function_tree, indices[i]);
851 devm_kfree(pctldev->dev, function);
852 }
853
854 pctldev->num_functions = 0;
855}
856
857#endif /* CONFIG_GENERIC_PINMUX_FUNCTIONS */