aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/sh
diff options
context:
space:
mode:
authorPaul Mundt <lethal@linux-sh.org>2012-07-11 04:17:10 -0400
committerPaul Mundt <lethal@linux-sh.org>2012-07-11 04:17:10 -0400
commitd93a891ff9e21a017e4d66d29784614768db567a (patch)
treeaf5e48f5177548a4a51ede4cf4363218e5d2625d /drivers/sh
parentca5481c68e9fbcea62bb3c78ae6cccf99ca8fb73 (diff)
sh: pfc: pinctrl legacy function support.
This maps out all of the function types to pinctrl function groups. Presently this is restricted to one pin per function to maintain compatability with legacy behaviour. This will be extended as groups are introduced and exiting users migrated. Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Diffstat (limited to 'drivers/sh')
-rw-r--r--drivers/sh/pfc/pinctrl.c165
1 files changed, 132 insertions, 33 deletions
diff --git a/drivers/sh/pfc/pinctrl.c b/drivers/sh/pfc/pinctrl.c
index 6008328594ff..f62659aa68cc 100644
--- a/drivers/sh/pfc/pinctrl.c
+++ b/drivers/sh/pfc/pinctrl.c
@@ -14,6 +14,7 @@
14#include <linux/sh_pfc.h> 14#include <linux/sh_pfc.h>
15#include <linux/err.h> 15#include <linux/err.h>
16#include <linux/slab.h> 16#include <linux/slab.h>
17#include <linux/spinlock.h>
17#include <linux/platform_device.h> 18#include <linux/platform_device.h>
18#include <linux/pinctrl/consumer.h> 19#include <linux/pinctrl/consumer.h>
19#include <linux/pinctrl/pinctrl.h> 20#include <linux/pinctrl/pinctrl.h>
@@ -25,8 +26,13 @@ struct sh_pfc_pinctrl {
25 struct pinctrl_dev *pctl; 26 struct pinctrl_dev *pctl;
26 struct sh_pfc *pfc; 27 struct sh_pfc *pfc;
27 28
29 struct pinmux_gpio **functions;
30 unsigned int nr_functions;
31
28 struct pinctrl_pin_desc *pads; 32 struct pinctrl_pin_desc *pads;
29 unsigned int nr_pads; 33 unsigned int nr_pads;
34
35 spinlock_t lock;
30}; 36};
31 37
32static struct sh_pfc_pinctrl *sh_pfc_pmx; 38static struct sh_pfc_pinctrl *sh_pfc_pmx;
@@ -57,14 +63,30 @@ static struct pinctrl_ops sh_pfc_pinctrl_ops = {
57 .get_group_pins = sh_pfc_get_group_pins, 63 .get_group_pins = sh_pfc_get_group_pins,
58}; 64};
59 65
66static int sh_pfc_get_functions_count(struct pinctrl_dev *pctldev)
67{
68 struct sh_pfc_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev);
69
70 return pmx->nr_functions;
71}
72
73static const char *sh_pfc_get_function_name(struct pinctrl_dev *pctldev,
74 unsigned selector)
75{
76 struct sh_pfc_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev);
77
78 return pmx->functions[selector]->name;
79}
60 80
61/*
62 * No function support yet
63 */
64static int sh_pfc_get_function_groups(struct pinctrl_dev *pctldev, unsigned func, 81static int sh_pfc_get_function_groups(struct pinctrl_dev *pctldev, unsigned func,
65 const char * const **groups, 82 const char * const **groups,
66 unsigned * const num_groups) 83 unsigned * const num_groups)
67{ 84{
85 struct sh_pfc_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev);
86
87 *groups = &pmx->functions[func]->name;
88 *num_groups = 1;
89
68 return 0; 90 return 0;
69} 91}
70 92
@@ -79,41 +101,50 @@ static void sh_pfc_noop_disable(struct pinctrl_dev *pctldev, unsigned func,
79{ 101{
80} 102}
81 103
104static inline int sh_pfc_config_function(struct sh_pfc *pfc, unsigned offset)
105{
106 if (sh_pfc_config_gpio(pfc, offset,
107 PINMUX_TYPE_FUNCTION,
108 GPIO_CFG_DRYRUN) != 0)
109 return -EINVAL;
110
111 if (sh_pfc_config_gpio(pfc, offset,
112 PINMUX_TYPE_FUNCTION,
113 GPIO_CFG_REQ) != 0)
114 return -EINVAL;
115
116 return 0;
117}
118
82static int sh_pfc_gpio_request_enable(struct pinctrl_dev *pctldev, 119static int sh_pfc_gpio_request_enable(struct pinctrl_dev *pctldev,
83 struct pinctrl_gpio_range *range, 120 struct pinctrl_gpio_range *range,
84 unsigned offset) 121 unsigned offset)
85{ 122{
86 struct sh_pfc_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev); 123 struct sh_pfc_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev);
87 struct sh_pfc *pfc = pmx->pfc; 124 struct sh_pfc *pfc = pmx->pfc;
88 struct pinmux_data_reg *dummy;
89 unsigned long flags; 125 unsigned long flags;
90 int i, ret, pinmux_type; 126 int ret, pinmux_type;
91
92 ret = -EINVAL;
93 127
94 spin_lock_irqsave(&pfc->lock, flags); 128 spin_lock_irqsave(&pfc->lock, flags);
95 129
96 if ((pfc->gpios[offset].flags & PINMUX_FLAG_TYPE) != PINMUX_TYPE_NONE) 130 pinmux_type = pfc->gpios[offset].flags & PINMUX_FLAG_TYPE;
97 goto err;
98
99 /* setup pin function here if no data is associated with pin */
100 if (sh_pfc_get_data_reg(pfc, offset, &dummy, &i) != 0) {
101 pinmux_type = PINMUX_TYPE_FUNCTION;
102
103 if (sh_pfc_config_gpio(pfc, offset,
104 pinmux_type,
105 GPIO_CFG_DRYRUN) != 0)
106 goto err;
107 131
108 if (sh_pfc_config_gpio(pfc, offset, 132 switch (pinmux_type) {
109 pinmux_type, 133 case PINMUX_TYPE_FUNCTION:
110 GPIO_CFG_REQ) != 0) 134 pr_notice_once("Use of GPIO API for function requests is "
135 "deprecated, convert to pinctrl\n");
136 /* handle for now */
137 ret = sh_pfc_config_function(pfc, offset);
138 if (unlikely(ret < 0))
111 goto err; 139 goto err;
112 } else
113 pinmux_type = PINMUX_TYPE_GPIO;
114 140
115 pfc->gpios[offset].flags &= ~PINMUX_FLAG_TYPE; 141 break;
116 pfc->gpios[offset].flags |= pinmux_type; 142 case PINMUX_TYPE_GPIO:
143 break;
144 default:
145 pr_err("Unsupported mux type (%d), bailing...\n", pinmux_type);
146 return -ENOTSUPP;
147 }
117 148
118 ret = 0; 149 ret = 0;
119 150
@@ -138,9 +169,6 @@ static void sh_pfc_gpio_disable_free(struct pinctrl_dev *pctldev,
138 169
139 sh_pfc_config_gpio(pfc, offset, pinmux_type, GPIO_CFG_FREE); 170 sh_pfc_config_gpio(pfc, offset, pinmux_type, GPIO_CFG_FREE);
140 171
141 pfc->gpios[offset].flags &= ~PINMUX_FLAG_TYPE;
142 pfc->gpios[offset].flags |= PINMUX_TYPE_NONE;
143
144 spin_unlock_irqrestore(&pfc->lock, flags); 172 spin_unlock_irqrestore(&pfc->lock, flags);
145} 173}
146 174
@@ -195,8 +223,8 @@ err:
195} 223}
196 224
197static struct pinmux_ops sh_pfc_pinmux_ops = { 225static struct pinmux_ops sh_pfc_pinmux_ops = {
198 .get_functions_count = sh_pfc_get_noop_count, 226 .get_functions_count = sh_pfc_get_functions_count,
199 .get_function_name = sh_pfc_get_noop_name, 227 .get_function_name = sh_pfc_get_function_name,
200 .get_function_groups = sh_pfc_get_function_groups, 228 .get_function_groups = sh_pfc_get_function_groups,
201 .enable = sh_pfc_noop_enable, 229 .enable = sh_pfc_noop_enable,
202 .disable = sh_pfc_noop_disable, 230 .disable = sh_pfc_noop_disable,
@@ -208,6 +236,13 @@ static struct pinmux_ops sh_pfc_pinmux_ops = {
208static int sh_pfc_pinconf_get(struct pinctrl_dev *pctldev, unsigned pin, 236static int sh_pfc_pinconf_get(struct pinctrl_dev *pctldev, unsigned pin,
209 unsigned long *config) 237 unsigned long *config)
210{ 238{
239 enum pin_config_param param = (enum pin_config_param)(*config);
240
241 switch (param) {
242 default:
243 break;
244 }
245
211 return -ENOTSUPP; 246 return -ENOTSUPP;
212} 247}
213 248
@@ -238,19 +273,44 @@ static struct pinctrl_desc sh_pfc_pinctrl_desc = {
238 273
239int sh_pfc_register_pinctrl(struct sh_pfc *pfc) 274int sh_pfc_register_pinctrl(struct sh_pfc *pfc)
240{ 275{
241 sh_pfc_pmx = kmalloc(sizeof(struct sh_pfc_pinctrl), GFP_KERNEL); 276 sh_pfc_pmx = kzalloc(sizeof(struct sh_pfc_pinctrl), GFP_KERNEL);
242 if (unlikely(!sh_pfc_pmx)) 277 if (unlikely(!sh_pfc_pmx))
243 return -ENOMEM; 278 return -ENOMEM;
244 279
280 spin_lock_init(&sh_pfc_pmx->lock);
281
245 sh_pfc_pmx->pfc = pfc; 282 sh_pfc_pmx->pfc = pfc;
246 283
247 return 0; 284 return 0;
248} 285}
249 286
287static inline void __devinit sh_pfc_map_one_gpio(struct sh_pfc *pfc,
288 struct sh_pfc_pinctrl *pmx,
289 struct pinmux_gpio *gpio,
290 unsigned offset)
291{
292 struct pinmux_data_reg *dummy;
293 unsigned long flags;
294 int bit;
295
296 gpio->flags &= ~PINMUX_FLAG_TYPE;
297
298 if (sh_pfc_get_data_reg(pfc, offset, &dummy, &bit) == 0)
299 gpio->flags |= PINMUX_TYPE_GPIO;
300 else {
301 gpio->flags |= PINMUX_TYPE_FUNCTION;
302
303 spin_lock_irqsave(&pmx->lock, flags);
304 pmx->nr_functions++;
305 spin_unlock_irqrestore(&pmx->lock, flags);
306 }
307}
308
250/* pinmux ranges -> pinctrl pin descs */ 309/* pinmux ranges -> pinctrl pin descs */
251static int __devinit sh_pfc_map_gpios(struct sh_pfc *pfc, 310static int __devinit sh_pfc_map_gpios(struct sh_pfc *pfc,
252 struct sh_pfc_pinctrl *pmx) 311 struct sh_pfc_pinctrl *pmx)
253{ 312{
313 unsigned long flags;
254 int i; 314 int i;
255 315
256 pmx->nr_pads = pfc->last_gpio - pfc->first_gpio + 1; 316 pmx->nr_pads = pfc->last_gpio - pfc->first_gpio + 1;
@@ -262,6 +322,8 @@ static int __devinit sh_pfc_map_gpios(struct sh_pfc *pfc,
262 return -ENOMEM; 322 return -ENOMEM;
263 } 323 }
264 324
325 spin_lock_irqsave(&pfc->lock, flags);
326
265 /* 327 /*
266 * We don't necessarily have a 1:1 mapping between pin and linux 328 * We don't necessarily have a 1:1 mapping between pin and linux
267 * GPIO number, as the latter maps to the associated enum_id. 329 * GPIO number, as the latter maps to the associated enum_id.
@@ -274,14 +336,43 @@ static int __devinit sh_pfc_map_gpios(struct sh_pfc *pfc,
274 336
275 pin->number = pfc->first_gpio + i; 337 pin->number = pfc->first_gpio + i;
276 pin->name = gpio->name; 338 pin->name = gpio->name;
339
340 sh_pfc_map_one_gpio(pfc, pmx, gpio, i);
277 } 341 }
278 342
343 spin_unlock_irqrestore(&pfc->lock, flags);
344
279 sh_pfc_pinctrl_desc.pins = pmx->pads; 345 sh_pfc_pinctrl_desc.pins = pmx->pads;
280 sh_pfc_pinctrl_desc.npins = pmx->nr_pads; 346 sh_pfc_pinctrl_desc.npins = pmx->nr_pads;
281 347
282 return 0; 348 return 0;
283} 349}
284 350
351static int __devinit sh_pfc_map_functions(struct sh_pfc *pfc,
352 struct sh_pfc_pinctrl *pmx)
353{
354 unsigned long flags;
355 int i, fn;
356
357 pmx->functions = kzalloc(pmx->nr_functions * sizeof(void *),
358 GFP_KERNEL);
359 if (unlikely(!pmx->functions))
360 return -ENOMEM;
361
362 spin_lock_irqsave(&pmx->lock, flags);
363
364 for (i = fn = 0; i < pmx->nr_pads; i++) {
365 struct pinmux_gpio *gpio = pfc->gpios + i;
366
367 if ((gpio->flags & PINMUX_FLAG_TYPE) == PINMUX_TYPE_FUNCTION)
368 pmx->functions[fn++] = gpio;
369 }
370
371 spin_unlock_irqrestore(&pmx->lock, flags);
372
373 return 0;
374}
375
285static int __devinit sh_pfc_pinctrl_probe(struct platform_device *pdev) 376static int __devinit sh_pfc_pinctrl_probe(struct platform_device *pdev)
286{ 377{
287 struct sh_pfc *pfc; 378 struct sh_pfc *pfc;
@@ -296,11 +387,15 @@ static int __devinit sh_pfc_pinctrl_probe(struct platform_device *pdev)
296 if (unlikely(ret != 0)) 387 if (unlikely(ret != 0))
297 return ret; 388 return ret;
298 389
390 ret = sh_pfc_map_functions(pfc, sh_pfc_pmx);
391 if (unlikely(ret != 0))
392 goto free_pads;
393
299 sh_pfc_pmx->pctl = pinctrl_register(&sh_pfc_pinctrl_desc, &pdev->dev, 394 sh_pfc_pmx->pctl = pinctrl_register(&sh_pfc_pinctrl_desc, &pdev->dev,
300 sh_pfc_pmx); 395 sh_pfc_pmx);
301 if (IS_ERR(sh_pfc_pmx->pctl)) { 396 if (IS_ERR(sh_pfc_pmx->pctl)) {
302 ret = PTR_ERR(sh_pfc_pmx->pctl); 397 ret = PTR_ERR(sh_pfc_pmx->pctl);
303 goto out; 398 goto free_functions;
304 } 399 }
305 400
306 sh_pfc_gpio_range.npins = pfc->last_gpio - pfc->first_gpio + 1; 401 sh_pfc_gpio_range.npins = pfc->last_gpio - pfc->first_gpio + 1;
@@ -313,9 +408,12 @@ static int __devinit sh_pfc_pinctrl_probe(struct platform_device *pdev)
313 408
314 return 0; 409 return 0;
315 410
316out: 411free_functions:
412 kfree(sh_pfc_pmx->functions);
413free_pads:
317 kfree(sh_pfc_pmx->pads); 414 kfree(sh_pfc_pmx->pads);
318 kfree(sh_pfc_pmx); 415 kfree(sh_pfc_pmx);
416
319 return ret; 417 return ret;
320} 418}
321 419
@@ -328,6 +426,7 @@ static int __devexit sh_pfc_pinctrl_remove(struct platform_device *pdev)
328 426
329 platform_set_drvdata(pdev, NULL); 427 platform_set_drvdata(pdev, NULL);
330 428
429 kfree(sh_pfc_pmx->functions);
331 kfree(sh_pfc_pmx->pads); 430 kfree(sh_pfc_pmx->pads);
332 kfree(sh_pfc_pmx); 431 kfree(sh_pfc_pmx);
333 432