Skip to content

Commit 57291ce

Browse files
swarrenLinus Walleij
authored andcommitted
pinctrl: core device tree mapping table parsing support
During pinctrl_get(), if the client device has a device tree node, look for the common pinctrl properties there. If found, parse the referenced device tree nodes, with the help of the pinctrl drivers, and generate mapping table entries from them. During pinctrl_put(), free any results of device tree parsing. Acked-by: Dong Aisheng <[email protected]> Signed-off-by: Stephen Warren <[email protected]> Signed-off-by: Linus Walleij <[email protected]>
1 parent d26bc49 commit 57291ce

File tree

6 files changed

+357
-18
lines changed

6 files changed

+357
-18
lines changed

drivers/pinctrl/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ ccflags-$(CONFIG_DEBUG_PINCTRL) += -DDEBUG
55
obj-$(CONFIG_PINCTRL) += core.o
66
obj-$(CONFIG_PINMUX) += pinmux.o
77
obj-$(CONFIG_PINCONF) += pinconf.o
8+
obj-$(CONFIG_OF) += devicetree.o
89
obj-$(CONFIG_GENERIC_PINCONF) += pinconf-generic.o
910
obj-$(CONFIG_PINCTRL_PXA3xx) += pinctrl-pxa3xx.o
1011
obj-$(CONFIG_PINCTRL_MMP2) += pinctrl-mmp2.o

drivers/pinctrl/core.c

Lines changed: 55 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
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 {
4546
DEFINE_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) */
5152
static 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
}
788798
EXPORT_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

870905
static 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

drivers/pinctrl/core.h

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,12 +52,15 @@ struct pinctrl_dev {
5252
* @dev: the device using this pin control handle
5353
* @states: a list of states for this device
5454
* @state: the current state
55+
* @dt_maps: the mapping table chunks dynamically parsed from device tree for
56+
* this device, if any
5557
*/
5658
struct pinctrl {
5759
struct list_head node;
5860
struct device *dev;
5961
struct list_head states;
6062
struct pinctrl_state *state;
63+
struct list_head dt_maps;
6164
};
6265

6366
/**
@@ -100,7 +103,8 @@ struct pinctrl_setting_configs {
100103
* struct pinctrl_setting - an individual mux or config setting
101104
* @node: list node for struct pinctrl_settings's @settings field
102105
* @type: the type of setting
103-
* @pctldev: pin control device handling to be programmed
106+
* @pctldev: pin control device handling to be programmed. Not used for
107+
* PIN_MAP_TYPE_DUMMY_STATE.
104108
* @data: Data specific to the setting type
105109
*/
106110
struct pinctrl_setting {
@@ -153,4 +157,9 @@ static inline struct pin_desc *pin_desc_get(struct pinctrl_dev *pctldev,
153157
return radix_tree_lookup(&pctldev->pin_desc_tree, pin);
154158
}
155159

160+
int pinctrl_register_map(struct pinctrl_map const *maps, unsigned num_maps,
161+
bool dup, bool locked);
162+
void pinctrl_unregister_map(struct pinctrl_map const *map);
163+
156164
extern struct mutex pinctrl_mutex;
165+
extern struct list_head pinctrldev_list;

0 commit comments

Comments
 (0)