2626#include <linux/pinctrl/pinctrl.h>
2727#include <linux/pinctrl/machine.h>
2828#include "core.h"
29+ #include "devicetree.h"
2930#include "pinmux.h"
3031#include "pinconf.h"
3132
@@ -45,7 +46,7 @@ struct pinctrl_maps {
4546DEFINE_MUTEX (pinctrl_mutex );
4647
4748/* Global list of pin control devices (struct pinctrl_dev) */
48- static LIST_HEAD (pinctrldev_list );
49+ LIST_HEAD (pinctrldev_list );
4950
5051/* List of pin controller handles (struct pinctrl) */
5152static LIST_HEAD (pinctrl_list );
@@ -579,6 +580,13 @@ static struct pinctrl *create_pinctrl(struct device *dev)
579580 }
580581 p -> dev = dev ;
581582 INIT_LIST_HEAD (& p -> states );
583+ INIT_LIST_HEAD (& p -> dt_maps );
584+
585+ ret = pinctrl_dt_to_map (p );
586+ if (ret < 0 ) {
587+ kfree (p );
588+ return ERR_PTR (ret );
589+ }
582590
583591 devname = dev_name (dev );
584592
@@ -662,6 +670,8 @@ static void pinctrl_put_locked(struct pinctrl *p, bool inlist)
662670 kfree (state );
663671 }
664672
673+ pinctrl_dt_free_maps (p );
674+
665675 if (inlist )
666676 list_del (& p -> node );
667677 kfree (p );
@@ -787,15 +797,8 @@ int pinctrl_select_state(struct pinctrl *p, struct pinctrl_state *state)
787797}
788798EXPORT_SYMBOL_GPL (pinctrl_select_state );
789799
790- /**
791- * pinctrl_register_mappings() - register a set of pin controller mappings
792- * @maps: the pincontrol mappings table to register. This should probably be
793- * marked with __initdata so it can be discarded after boot. This
794- * function will perform a shallow copy for the mapping entries.
795- * @num_maps: the number of maps in the mapping table
796- */
797- int pinctrl_register_mappings (struct pinctrl_map const * maps ,
798- unsigned num_maps )
800+ int pinctrl_register_map (struct pinctrl_map const * maps , unsigned num_maps ,
801+ bool dup , bool locked )
799802{
800803 int i , ret ;
801804 struct pinctrl_maps * maps_node ;
@@ -851,20 +854,52 @@ int pinctrl_register_mappings(struct pinctrl_map const *maps,
851854 }
852855
853856 maps_node -> num_maps = num_maps ;
854- maps_node -> maps = kmemdup (maps , sizeof (* maps ) * num_maps , GFP_KERNEL );
855- if (!maps_node -> maps ) {
856- pr_err ("failed to duplicate mapping table\n" );
857- kfree (maps_node );
858- return - ENOMEM ;
857+ if (dup ) {
858+ maps_node -> maps = kmemdup (maps , sizeof (* maps ) * num_maps ,
859+ GFP_KERNEL );
860+ if (!maps_node -> maps ) {
861+ pr_err ("failed to duplicate mapping table\n" );
862+ kfree (maps_node );
863+ return - ENOMEM ;
864+ }
865+ } else {
866+ maps_node -> maps = maps ;
859867 }
860868
861- mutex_lock (& pinctrl_mutex );
869+ if (!locked )
870+ mutex_lock (& pinctrl_mutex );
862871 list_add_tail (& maps_node -> node , & pinctrl_maps );
863- mutex_unlock (& pinctrl_mutex );
872+ if (!locked )
873+ mutex_unlock (& pinctrl_mutex );
864874
865875 return 0 ;
866876}
867877
878+ /**
879+ * pinctrl_register_mappings() - register a set of pin controller mappings
880+ * @maps: the pincontrol mappings table to register. This should probably be
881+ * marked with __initdata so it can be discarded after boot. This
882+ * function will perform a shallow copy for the mapping entries.
883+ * @num_maps: the number of maps in the mapping table
884+ */
885+ int pinctrl_register_mappings (struct pinctrl_map const * maps ,
886+ unsigned num_maps )
887+ {
888+ return pinctrl_register_map (maps , num_maps , true, false);
889+ }
890+
891+ void pinctrl_unregister_map (struct pinctrl_map const * map )
892+ {
893+ struct pinctrl_maps * maps_node ;
894+
895+ list_for_each_entry (maps_node , & pinctrl_maps , node ) {
896+ if (maps_node -> maps == map ) {
897+ list_del (& maps_node -> node );
898+ return ;
899+ }
900+ }
901+ }
902+
868903#ifdef CONFIG_DEBUG_FS
869904
870905static int pinctrl_pins_show (struct seq_file * s , void * what )
@@ -1231,6 +1266,9 @@ static int pinctrl_check_ops(struct pinctrl_dev *pctldev)
12311266 !ops -> get_group_pins )
12321267 return - EINVAL ;
12331268
1269+ if (ops -> dt_node_to_map && !ops -> dt_free_map )
1270+ return - EINVAL ;
1271+
12341272 return 0 ;
12351273}
12361274
0 commit comments