diff options
author | John Crispin <blogic@openwrt.org> | 2013-02-01 07:04:57 -0500 |
---|---|---|
committer | Linus Walleij <linus.walleij@linaro.org> | 2013-02-05 10:17:22 -0500 |
commit | 3a6b04ca33a225dd64fcd5f4469b7b1088f16c37 (patch) | |
tree | 0d0d77a81897a81fdbe2f065f65d833927e7ac06 /drivers/pinctrl/pinctrl-lantiq.c | |
parent | 7541083fc4d9b24f63ea2e8e7726aeb5b2786176 (diff) |
pinctrl/lantiq: add pin_config_group_set support
While converting all the boards supported by OpenWrt to OF
I noticed that this feature is missing. Adding it makes the
devicetrees more readable.
Signed-off-by: John Crispin <blogic@openwrt.org>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Diffstat (limited to 'drivers/pinctrl/pinctrl-lantiq.c')
-rw-r--r-- | drivers/pinctrl/pinctrl-lantiq.c | 54 |
1 files changed, 34 insertions, 20 deletions
diff --git a/drivers/pinctrl/pinctrl-lantiq.c b/drivers/pinctrl/pinctrl-lantiq.c index 15f501d89026..7d110722dfd1 100644 --- a/drivers/pinctrl/pinctrl-lantiq.c +++ b/drivers/pinctrl/pinctrl-lantiq.c | |||
@@ -64,11 +64,13 @@ static void ltq_pinctrl_pin_dbg_show(struct pinctrl_dev *pctldev, | |||
64 | seq_printf(s, " %s", dev_name(pctldev->dev)); | 64 | seq_printf(s, " %s", dev_name(pctldev->dev)); |
65 | } | 65 | } |
66 | 66 | ||
67 | static int ltq_pinctrl_dt_subnode_to_map(struct pinctrl_dev *pctldev, | 67 | static void ltq_pinctrl_dt_subnode_to_map(struct pinctrl_dev *pctldev, |
68 | struct device_node *np, | 68 | struct device_node *np, |
69 | struct pinctrl_map **map) | 69 | struct pinctrl_map **map) |
70 | { | 70 | { |
71 | struct ltq_pinmux_info *info = pinctrl_dev_get_drvdata(pctldev); | 71 | struct ltq_pinmux_info *info = pinctrl_dev_get_drvdata(pctldev); |
72 | struct property *pins = of_find_property(np, "lantiq,pins", NULL); | ||
73 | struct property *groups = of_find_property(np, "lantiq,groups", NULL); | ||
72 | unsigned long configs[3]; | 74 | unsigned long configs[3]; |
73 | unsigned num_configs = 0; | 75 | unsigned num_configs = 0; |
74 | struct property *prop; | 76 | struct property *prop; |
@@ -76,8 +78,20 @@ static int ltq_pinctrl_dt_subnode_to_map(struct pinctrl_dev *pctldev, | |||
76 | const char *function; | 78 | const char *function; |
77 | int ret, i; | 79 | int ret, i; |
78 | 80 | ||
81 | if (!pins && !groups) { | ||
82 | dev_err(pctldev->dev, "%s defines neither pins nor groups\n", | ||
83 | np->name); | ||
84 | return; | ||
85 | } | ||
86 | |||
87 | if (pins && groups) { | ||
88 | dev_err(pctldev->dev, "%s defines both pins and groups\n", | ||
89 | np->name); | ||
90 | return; | ||
91 | } | ||
92 | |||
79 | ret = of_property_read_string(np, "lantiq,function", &function); | 93 | ret = of_property_read_string(np, "lantiq,function", &function); |
80 | if (!ret) { | 94 | if (groups && !ret) { |
81 | of_property_for_each_string(np, "lantiq,groups", prop, group) { | 95 | of_property_for_each_string(np, "lantiq,groups", prop, group) { |
82 | (*map)->type = PIN_MAP_TYPE_MUX_GROUP; | 96 | (*map)->type = PIN_MAP_TYPE_MUX_GROUP; |
83 | (*map)->name = function; | 97 | (*map)->name = function; |
@@ -85,11 +99,6 @@ static int ltq_pinctrl_dt_subnode_to_map(struct pinctrl_dev *pctldev, | |||
85 | (*map)->data.mux.function = function; | 99 | (*map)->data.mux.function = function; |
86 | (*map)++; | 100 | (*map)++; |
87 | } | 101 | } |
88 | if (of_find_property(np, "lantiq,pins", NULL)) | ||
89 | dev_err(pctldev->dev, | ||
90 | "%s mixes pins and groups settings\n", | ||
91 | np->name); | ||
92 | return 0; | ||
93 | } | 102 | } |
94 | 103 | ||
95 | for (i = 0; i < info->num_params; i++) { | 104 | for (i = 0; i < info->num_params; i++) { |
@@ -103,7 +112,7 @@ static int ltq_pinctrl_dt_subnode_to_map(struct pinctrl_dev *pctldev, | |||
103 | } | 112 | } |
104 | 113 | ||
105 | if (!num_configs) | 114 | if (!num_configs) |
106 | return -EINVAL; | 115 | return; |
107 | 116 | ||
108 | of_property_for_each_string(np, "lantiq,pins", prop, pin) { | 117 | of_property_for_each_string(np, "lantiq,pins", prop, pin) { |
109 | (*map)->data.configs.configs = kmemdup(configs, | 118 | (*map)->data.configs.configs = kmemdup(configs, |
@@ -115,7 +124,16 @@ static int ltq_pinctrl_dt_subnode_to_map(struct pinctrl_dev *pctldev, | |||
115 | (*map)->data.configs.num_configs = num_configs; | 124 | (*map)->data.configs.num_configs = num_configs; |
116 | (*map)++; | 125 | (*map)++; |
117 | } | 126 | } |
118 | return 0; | 127 | of_property_for_each_string(np, "lantiq,groups", prop, group) { |
128 | (*map)->data.configs.configs = kmemdup(configs, | ||
129 | num_configs * sizeof(unsigned long), | ||
130 | GFP_KERNEL); | ||
131 | (*map)->type = PIN_MAP_TYPE_CONFIGS_GROUP; | ||
132 | (*map)->name = group; | ||
133 | (*map)->data.configs.group_or_pin = group; | ||
134 | (*map)->data.configs.num_configs = num_configs; | ||
135 | (*map)++; | ||
136 | } | ||
119 | } | 137 | } |
120 | 138 | ||
121 | static int ltq_pinctrl_dt_subnode_size(struct device_node *np) | 139 | static int ltq_pinctrl_dt_subnode_size(struct device_node *np) |
@@ -135,23 +153,19 @@ static int ltq_pinctrl_dt_node_to_map(struct pinctrl_dev *pctldev, | |||
135 | { | 153 | { |
136 | struct pinctrl_map *tmp; | 154 | struct pinctrl_map *tmp; |
137 | struct device_node *np; | 155 | struct device_node *np; |
138 | int ret; | 156 | int max_maps = 0; |
139 | 157 | ||
140 | *num_maps = 0; | ||
141 | for_each_child_of_node(np_config, np) | 158 | for_each_child_of_node(np_config, np) |
142 | *num_maps += ltq_pinctrl_dt_subnode_size(np); | 159 | max_maps += ltq_pinctrl_dt_subnode_size(np); |
143 | *map = kzalloc(*num_maps * sizeof(struct pinctrl_map), GFP_KERNEL); | 160 | *map = kzalloc(max_maps * sizeof(struct pinctrl_map) * 2, GFP_KERNEL); |
144 | if (!*map) | 161 | if (!*map) |
145 | return -ENOMEM; | 162 | return -ENOMEM; |
146 | tmp = *map; | 163 | tmp = *map; |
147 | 164 | ||
148 | for_each_child_of_node(np_config, np) { | 165 | for_each_child_of_node(np_config, np) |
149 | ret = ltq_pinctrl_dt_subnode_to_map(pctldev, np, &tmp); | 166 | ltq_pinctrl_dt_subnode_to_map(pctldev, np, &tmp); |
150 | if (ret < 0) { | 167 | *num_maps = ((int)(tmp - *map)); |
151 | ltq_pinctrl_dt_free_map(pctldev, *map, *num_maps); | 168 | |
152 | return ret; | ||
153 | } | ||
154 | } | ||
155 | return 0; | 169 | return 0; |
156 | } | 170 | } |
157 | 171 | ||