target: don't build jffs2 nor images by default
[openwrt/svn-archive/archive.git] / target / linux / lantiq / patches-3.7 / 0108-PINCTRL-lantiq-fixes.patch
1 From 13e754b5fff5be1930e2b8fe534a52b608c9e479 Mon Sep 17 00:00:00 2001
2 From: John Crispin <blogic@openwrt.org>
3 Date: Mon, 3 Dec 2012 19:27:28 +0100
4 Subject: [PATCH] PINCTRL: lantiq: fixes
5
6 ---
7 drivers/pinctrl/pinctrl-lantiq.c | 54 ++++++++++++++++++-----------
8 drivers/pinctrl/pinctrl-lantiq.h | 1 +
9 drivers/pinctrl/pinctrl-xway.c | 70 ++++++++++++++++++++++++++++++++++----
10 3 files changed, 99 insertions(+), 26 deletions(-)
11
12 --- a/drivers/pinctrl/pinctrl-lantiq.c
13 +++ b/drivers/pinctrl/pinctrl-lantiq.c
14 @@ -64,11 +64,13 @@ static void ltq_pinctrl_pin_dbg_show(str
15 seq_printf(s, " %s", dev_name(pctldev->dev));
16 }
17
18 -static int ltq_pinctrl_dt_subnode_to_map(struct pinctrl_dev *pctldev,
19 +static void ltq_pinctrl_dt_subnode_to_map(struct pinctrl_dev *pctldev,
20 struct device_node *np,
21 struct pinctrl_map **map)
22 {
23 struct ltq_pinmux_info *info = pinctrl_dev_get_drvdata(pctldev);
24 + struct property *pins = of_find_property(np, "lantiq,pins", NULL);
25 + struct property *groups = of_find_property(np, "lantiq,groups", NULL);
26 unsigned long configs[3];
27 unsigned num_configs = 0;
28 struct property *prop;
29 @@ -76,8 +78,20 @@ static int ltq_pinctrl_dt_subnode_to_map
30 const char *function;
31 int ret, i;
32
33 + if (!pins && !groups) {
34 + dev_err(pctldev->dev, "%s defines neither pins nor groups\n",
35 + np->name);
36 + return;
37 + }
38 +
39 + if (pins && groups) {
40 + dev_err(pctldev->dev, "%s defines both pins and groups\n",
41 + np->name);
42 + return;
43 + }
44 +
45 ret = of_property_read_string(np, "lantiq,function", &function);
46 - if (!ret) {
47 + if (groups && !ret) {
48 of_property_for_each_string(np, "lantiq,groups", prop, group) {
49 (*map)->type = PIN_MAP_TYPE_MUX_GROUP;
50 (*map)->name = function;
51 @@ -85,11 +99,6 @@ static int ltq_pinctrl_dt_subnode_to_map
52 (*map)->data.mux.function = function;
53 (*map)++;
54 }
55 - if (of_find_property(np, "lantiq,pins", NULL))
56 - dev_err(pctldev->dev,
57 - "%s mixes pins and groups settings\n",
58 - np->name);
59 - return 0;
60 }
61
62 for (i = 0; i < info->num_params; i++) {
63 @@ -103,7 +112,7 @@ static int ltq_pinctrl_dt_subnode_to_map
64 }
65
66 if (!num_configs)
67 - return -EINVAL;
68 + return;
69
70 of_property_for_each_string(np, "lantiq,pins", prop, pin) {
71 (*map)->data.configs.configs = kmemdup(configs,
72 @@ -115,7 +124,16 @@ static int ltq_pinctrl_dt_subnode_to_map
73 (*map)->data.configs.num_configs = num_configs;
74 (*map)++;
75 }
76 - return 0;
77 + of_property_for_each_string(np, "lantiq,groups", prop, group) {
78 + (*map)->data.configs.configs = kmemdup(configs,
79 + num_configs * sizeof(unsigned long),
80 + GFP_KERNEL);
81 + (*map)->type = PIN_MAP_TYPE_CONFIGS_GROUP;
82 + (*map)->name = group;
83 + (*map)->data.configs.group_or_pin = group;
84 + (*map)->data.configs.num_configs = num_configs;
85 + (*map)++;
86 + }
87 }
88
89 static int ltq_pinctrl_dt_subnode_size(struct device_node *np)
90 @@ -135,23 +153,19 @@ int ltq_pinctrl_dt_node_to_map(struct pi
91 {
92 struct pinctrl_map *tmp;
93 struct device_node *np;
94 - int ret;
95 + int max_maps = 0;
96
97 - *num_maps = 0;
98 for_each_child_of_node(np_config, np)
99 - *num_maps += ltq_pinctrl_dt_subnode_size(np);
100 - *map = kzalloc(*num_maps * sizeof(struct pinctrl_map), GFP_KERNEL);
101 + max_maps += ltq_pinctrl_dt_subnode_size(np);
102 + *map = kzalloc(max_maps * sizeof(struct pinctrl_map) * 2, GFP_KERNEL);
103 if (!*map)
104 return -ENOMEM;
105 tmp = *map;
106
107 - for_each_child_of_node(np_config, np) {
108 - ret = ltq_pinctrl_dt_subnode_to_map(pctldev, np, &tmp);
109 - if (ret < 0) {
110 - ltq_pinctrl_dt_free_map(pctldev, *map, *num_maps);
111 - return ret;
112 - }
113 - }
114 + for_each_child_of_node(np_config, np)
115 + ltq_pinctrl_dt_subnode_to_map(pctldev, np, &tmp);
116 + *num_maps = ((int)(tmp - *map));
117 +
118 return 0;
119 }
120
121 --- a/drivers/pinctrl/pinctrl-lantiq.h
122 +++ b/drivers/pinctrl/pinctrl-lantiq.h
123 @@ -34,6 +34,7 @@ enum ltq_pinconf_param {
124 LTQ_PINCONF_PARAM_OPEN_DRAIN,
125 LTQ_PINCONF_PARAM_DRIVE_CURRENT,
126 LTQ_PINCONF_PARAM_SLEW_RATE,
127 + LTQ_PINCONF_PARAM_OUTPUT,
128 };
129
130 struct ltq_cfg_param {
131 --- a/drivers/pinctrl/pinctrl-xway.c
132 +++ b/drivers/pinctrl/pinctrl-xway.c
133 @@ -443,7 +443,7 @@ static int xway_pinconf_get(struct pinct
134 else
135 reg = GPIO_OD(pin);
136 *config = LTQ_PINCONF_PACK(param,
137 - !!gpio_getbit(info->membase[0], reg, PORT_PIN(pin)));
138 + !gpio_getbit(info->membase[0], reg, PORT_PIN(pin)));
139 break;
140
141 case LTQ_PINCONF_PARAM_PULL:
142 @@ -466,6 +466,11 @@ static int xway_pinconf_get(struct pinct
143 *config = LTQ_PINCONF_PACK(param, 1);
144 break;
145
146 + case LTQ_PINCONF_PARAM_OUTPUT:
147 + reg = GPIO_DIR(pin);
148 + *config = LTQ_PINCONF_PACK(param,
149 + gpio_getbit(info->membase[0], reg, PORT_PIN(pin)));
150 + break;
151 default:
152 dev_err(pctldev->dev, "Invalid config param %04x\n", param);
153 return -ENOTSUPP;
154 @@ -489,7 +494,10 @@ static int xway_pinconf_set(struct pinct
155 reg = GPIO3_OD;
156 else
157 reg = GPIO_OD(pin);
158 - gpio_setbit(info->membase[0], reg, PORT_PIN(pin));
159 + if (arg == 0)
160 + gpio_setbit(info->membase[0], reg, PORT_PIN(pin));
161 + else
162 + gpio_clearbit(info->membase[0], reg, PORT_PIN(pin));
163 break;
164
165 case LTQ_PINCONF_PARAM_PULL:
166 @@ -515,6 +523,14 @@ static int xway_pinconf_set(struct pinct
167 dev_err(pctldev->dev, "Invalid pull value %d\n", arg);
168 break;
169
170 + case LTQ_PINCONF_PARAM_OUTPUT:
171 + reg = GPIO_DIR(pin);
172 + if (arg == 0)
173 + gpio_clearbit(info->membase[0], reg, PORT_PIN(pin));
174 + else
175 + gpio_setbit(info->membase[0], reg, PORT_PIN(pin));
176 + break;
177 +
178 default:
179 dev_err(pctldev->dev, "Invalid config param %04x\n", param);
180 return -ENOTSUPP;
181 @@ -522,9 +538,25 @@ static int xway_pinconf_set(struct pinct
182 return 0;
183 }
184
185 +int xway_pinconf_group_set(struct pinctrl_dev *pctldev,
186 + unsigned selector,
187 + unsigned long config)
188 +{
189 + struct ltq_pinmux_info *info = pinctrl_dev_get_drvdata(pctldev);
190 + int i, ret = 0;
191 +
192 + for (i = 0; i < info->grps[selector].npins && !ret; i++)
193 + ret = xway_pinconf_set(pctldev,
194 + info->grps[selector].pins[i], config);
195 +
196 + return ret;
197 +}
198 +
199 +
200 struct pinconf_ops xway_pinconf_ops = {
201 .pin_config_get = xway_pinconf_get,
202 .pin_config_set = xway_pinconf_set,
203 + .pin_config_group_set = xway_pinconf_group_set,
204 };
205
206 static struct pinctrl_desc xway_pctrl_desc = {
207 @@ -532,10 +564,9 @@ static struct pinctrl_desc xway_pctrl_de
208 .confops = &xway_pinconf_ops,
209 };
210
211 -static inline int xway_mux_apply(struct pinctrl_dev *pctrldev,
212 +static int mux_apply(struct ltq_pinmux_info *info,
213 int pin, int mux)
214 {
215 - struct ltq_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev);
216 int port = PORT(pin);
217 u32 alt1_reg = GPIO_ALT1(pin);
218
219 @@ -555,9 +586,18 @@ static inline int xway_mux_apply(struct
220 return 0;
221 }
222
223 +static inline int xway_mux_apply(struct pinctrl_dev *pctrldev,
224 + int pin, int mux)
225 +{
226 + struct ltq_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev);
227 +
228 + return mux_apply(info, pin, mux);
229 +}
230 +
231 static const struct ltq_cfg_param xway_cfg_params[] = {
232 {"lantiq,pull", LTQ_PINCONF_PARAM_PULL},
233 {"lantiq,open-drain", LTQ_PINCONF_PARAM_OPEN_DRAIN},
234 + {"lantiq,output", LTQ_PINCONF_PARAM_OUTPUT},
235 };
236
237 static struct ltq_pinmux_info xway_info = {
238 @@ -598,6 +638,10 @@ static int xway_gpio_dir_out(struct gpio
239 {
240 struct ltq_pinmux_info *info = dev_get_drvdata(chip->dev);
241
242 + if (PORT(pin) == PORT3)
243 + gpio_setbit(info->membase[0], GPIO3_OD, PORT_PIN(pin));
244 + else
245 + gpio_setbit(info->membase[0], GPIO_OD(pin), PORT_PIN(pin));
246 gpio_setbit(info->membase[0], GPIO_DIR(pin), PORT_PIN(pin));
247 xway_gpio_set(chip, pin, val);
248
249 @@ -618,6 +662,18 @@ static void xway_gpio_free(struct gpio_c
250 pinctrl_free_gpio(gpio);
251 }
252
253 +static int xway_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
254 +{
255 + struct ltq_pinmux_info *info = dev_get_drvdata(chip->dev);
256 + int i;
257 +
258 + for (i = 0; i < info->num_exin; i++)
259 + if (info->exin[i] == offset)
260 + return ltq_eiu_get_irq(i);
261 +
262 + return -1;
263 +}
264 +
265 static struct gpio_chip xway_chip = {
266 .label = "gpio-xway",
267 .direction_input = xway_gpio_dir_in,
268 @@ -626,6 +682,7 @@ static struct gpio_chip xway_chip = {
269 .set = xway_gpio_set,
270 .request = xway_gpio_req,
271 .free = xway_gpio_free,
272 + .to_irq = xway_gpio_to_irq,
273 .base = -1,
274 };
275