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