kernel: update linux 3.8 to 3.8.3
[openwrt/staging/dedeckeh.git] / target / linux / lantiq / patches-3.8 / 0007-PINCTRL-lantiq-add-pin_config_group_set-support.patch
1 From 325ba34823f454c35c814d72022ba736ad56a1d4 Mon Sep 17 00:00:00 2001
2 From: John Crispin <blogic@openwrt.org>
3 Date: Wed, 30 Jan 2013 18:21:48 +0100
4 Subject: [PATCH 07/40] PINCTRL: lantiq: add pin_config_group_set support
5
6 While converting all the boards supported by OpenWrt to OF I noticed that this
7 feature is missing. Adding it makes the devicetrees more readable.
8
9 Signed-off-by: John Crispin <blogic@openwrt.org>
10 ---
11 drivers/pinctrl/pinctrl-lantiq.c | 54 ++++++++++++++++++++++++--------------
12 drivers/pinctrl/pinctrl-xway.c | 15 +++++++++++
13 2 files changed, 49 insertions(+), 20 deletions(-)
14
15 --- a/drivers/pinctrl/pinctrl-lantiq.c
16 +++ b/drivers/pinctrl/pinctrl-lantiq.c
17 @@ -64,11 +64,13 @@ static void ltq_pinctrl_pin_dbg_show(str
18 seq_printf(s, " %s", dev_name(pctldev->dev));
19 }
20
21 -static int ltq_pinctrl_dt_subnode_to_map(struct pinctrl_dev *pctldev,
22 +static void ltq_pinctrl_dt_subnode_to_map(struct pinctrl_dev *pctldev,
23 struct device_node *np,
24 struct pinctrl_map **map)
25 {
26 struct ltq_pinmux_info *info = pinctrl_dev_get_drvdata(pctldev);
27 + struct property *pins = of_find_property(np, "lantiq,pins", NULL);
28 + struct property *groups = of_find_property(np, "lantiq,groups", NULL);
29 unsigned long configs[3];
30 unsigned num_configs = 0;
31 struct property *prop;
32 @@ -76,8 +78,20 @@ static int ltq_pinctrl_dt_subnode_to_map
33 const char *function;
34 int ret, i;
35
36 + if (!pins && !groups) {
37 + dev_err(pctldev->dev, "%s defines neither pins nor groups\n",
38 + np->name);
39 + return;
40 + }
41 +
42 + if (pins && groups) {
43 + dev_err(pctldev->dev, "%s defines both pins and groups\n",
44 + np->name);
45 + return;
46 + }
47 +
48 ret = of_property_read_string(np, "lantiq,function", &function);
49 - if (!ret) {
50 + if (groups && !ret) {
51 of_property_for_each_string(np, "lantiq,groups", prop, group) {
52 (*map)->type = PIN_MAP_TYPE_MUX_GROUP;
53 (*map)->name = function;
54 @@ -85,11 +99,6 @@ static int ltq_pinctrl_dt_subnode_to_map
55 (*map)->data.mux.function = function;
56 (*map)++;
57 }
58 - if (of_find_property(np, "lantiq,pins", NULL))
59 - dev_err(pctldev->dev,
60 - "%s mixes pins and groups settings\n",
61 - np->name);
62 - return 0;
63 }
64
65 for (i = 0; i < info->num_params; i++) {
66 @@ -103,7 +112,7 @@ static int ltq_pinctrl_dt_subnode_to_map
67 }
68
69 if (!num_configs)
70 - return -EINVAL;
71 + return;
72
73 of_property_for_each_string(np, "lantiq,pins", prop, pin) {
74 (*map)->data.configs.configs = kmemdup(configs,
75 @@ -115,7 +124,16 @@ static int ltq_pinctrl_dt_subnode_to_map
76 (*map)->data.configs.num_configs = num_configs;
77 (*map)++;
78 }
79 - return 0;
80 + of_property_for_each_string(np, "lantiq,groups", prop, group) {
81 + (*map)->data.configs.configs = kmemdup(configs,
82 + num_configs * sizeof(unsigned long),
83 + GFP_KERNEL);
84 + (*map)->type = PIN_MAP_TYPE_CONFIGS_GROUP;
85 + (*map)->name = group;
86 + (*map)->data.configs.group_or_pin = group;
87 + (*map)->data.configs.num_configs = num_configs;
88 + (*map)++;
89 + }
90 }
91
92 static int ltq_pinctrl_dt_subnode_size(struct device_node *np)
93 @@ -135,23 +153,19 @@ static int ltq_pinctrl_dt_node_to_map(st
94 {
95 struct pinctrl_map *tmp;
96 struct device_node *np;
97 - int ret;
98 + int max_maps = 0;
99
100 - *num_maps = 0;
101 for_each_child_of_node(np_config, np)
102 - *num_maps += ltq_pinctrl_dt_subnode_size(np);
103 - *map = kzalloc(*num_maps * sizeof(struct pinctrl_map), GFP_KERNEL);
104 + max_maps += ltq_pinctrl_dt_subnode_size(np);
105 + *map = kzalloc(max_maps * sizeof(struct pinctrl_map) * 2, GFP_KERNEL);
106 if (!*map)
107 return -ENOMEM;
108 tmp = *map;
109
110 - for_each_child_of_node(np_config, np) {
111 - ret = ltq_pinctrl_dt_subnode_to_map(pctldev, np, &tmp);
112 - if (ret < 0) {
113 - ltq_pinctrl_dt_free_map(pctldev, *map, *num_maps);
114 - return ret;
115 - }
116 - }
117 + for_each_child_of_node(np_config, np)
118 + ltq_pinctrl_dt_subnode_to_map(pctldev, np, &tmp);
119 + *num_maps = ((int)(tmp - *map));
120 +
121 return 0;
122 }
123
124 --- a/drivers/pinctrl/pinctrl-xway.c
125 +++ b/drivers/pinctrl/pinctrl-xway.c
126 @@ -522,9 +522,24 @@ static int xway_pinconf_set(struct pinct
127 return 0;
128 }
129
130 +int xway_pinconf_group_set(struct pinctrl_dev *pctldev,
131 + unsigned selector,
132 + unsigned long config)
133 +{
134 + struct ltq_pinmux_info *info = pinctrl_dev_get_drvdata(pctldev);
135 + int i, ret = 0;
136 +
137 + for (i = 0; i < info->grps[selector].npins && !ret; i++)
138 + ret = xway_pinconf_set(pctldev,
139 + info->grps[selector].pins[i], config);
140 +
141 + return ret;
142 +}
143 +
144 static struct pinconf_ops xway_pinconf_ops = {
145 .pin_config_get = xway_pinconf_get,
146 .pin_config_set = xway_pinconf_set,
147 + .pin_config_group_set = xway_pinconf_group_set,
148 };
149
150 static struct pinctrl_desc xway_pctrl_desc = {