Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v3.8-rc6 534 lines 13 kB view raw
1/* 2 * Copyright 2012 Freescale Semiconductor, Inc. 3 * 4 * The code contained herein is licensed under the GNU General Public 5 * License. You may obtain a copy of the GNU General Public License 6 * Version 2 or later at the following locations: 7 * 8 * http://www.opensource.org/licenses/gpl-license.html 9 * http://www.gnu.org/copyleft/gpl.html 10 */ 11 12#include <linux/err.h> 13#include <linux/init.h> 14#include <linux/io.h> 15#include <linux/module.h> 16#include <linux/of.h> 17#include <linux/of_address.h> 18#include <linux/pinctrl/machine.h> 19#include <linux/pinctrl/pinconf.h> 20#include <linux/pinctrl/pinctrl.h> 21#include <linux/pinctrl/pinmux.h> 22#include <linux/platform_device.h> 23#include <linux/slab.h> 24#include "core.h" 25#include "pinctrl-mxs.h" 26 27#define SUFFIX_LEN 4 28 29struct mxs_pinctrl_data { 30 struct device *dev; 31 struct pinctrl_dev *pctl; 32 void __iomem *base; 33 struct mxs_pinctrl_soc_data *soc; 34}; 35 36static int mxs_get_groups_count(struct pinctrl_dev *pctldev) 37{ 38 struct mxs_pinctrl_data *d = pinctrl_dev_get_drvdata(pctldev); 39 40 return d->soc->ngroups; 41} 42 43static const char *mxs_get_group_name(struct pinctrl_dev *pctldev, 44 unsigned group) 45{ 46 struct mxs_pinctrl_data *d = pinctrl_dev_get_drvdata(pctldev); 47 48 return d->soc->groups[group].name; 49} 50 51static int mxs_get_group_pins(struct pinctrl_dev *pctldev, unsigned group, 52 const unsigned **pins, unsigned *num_pins) 53{ 54 struct mxs_pinctrl_data *d = pinctrl_dev_get_drvdata(pctldev); 55 56 *pins = d->soc->groups[group].pins; 57 *num_pins = d->soc->groups[group].npins; 58 59 return 0; 60} 61 62static void mxs_pin_dbg_show(struct pinctrl_dev *pctldev, struct seq_file *s, 63 unsigned offset) 64{ 65 seq_printf(s, " %s", dev_name(pctldev->dev)); 66} 67 68static int mxs_dt_node_to_map(struct pinctrl_dev *pctldev, 69 struct device_node *np, 70 struct pinctrl_map **map, unsigned *num_maps) 71{ 72 struct pinctrl_map *new_map; 73 char *group = NULL; 74 unsigned new_num = 1; 75 unsigned long config = 0; 76 unsigned long *pconfig; 77 int length = strlen(np->name) + SUFFIX_LEN; 78 bool purecfg = false; 79 u32 val, reg; 80 int ret, i = 0; 81 82 /* Check for pin config node which has no 'reg' property */ 83 if (of_property_read_u32(np, "reg", &reg)) 84 purecfg = true; 85 86 ret = of_property_read_u32(np, "fsl,drive-strength", &val); 87 if (!ret) 88 config = val | MA_PRESENT; 89 ret = of_property_read_u32(np, "fsl,voltage", &val); 90 if (!ret) 91 config |= val << VOL_SHIFT | VOL_PRESENT; 92 ret = of_property_read_u32(np, "fsl,pull-up", &val); 93 if (!ret) 94 config |= val << PULL_SHIFT | PULL_PRESENT; 95 96 /* Check for group node which has both mux and config settings */ 97 if (!purecfg && config) 98 new_num = 2; 99 100 new_map = kzalloc(sizeof(*new_map) * new_num, GFP_KERNEL); 101 if (!new_map) 102 return -ENOMEM; 103 104 if (!purecfg) { 105 new_map[i].type = PIN_MAP_TYPE_MUX_GROUP; 106 new_map[i].data.mux.function = np->name; 107 108 /* Compose group name */ 109 group = kzalloc(length, GFP_KERNEL); 110 if (!group) { 111 ret = -ENOMEM; 112 goto free; 113 } 114 snprintf(group, length, "%s.%d", np->name, reg); 115 new_map[i].data.mux.group = group; 116 i++; 117 } 118 119 if (config) { 120 pconfig = kmemdup(&config, sizeof(config), GFP_KERNEL); 121 if (!pconfig) { 122 ret = -ENOMEM; 123 goto free_group; 124 } 125 126 new_map[i].type = PIN_MAP_TYPE_CONFIGS_GROUP; 127 new_map[i].data.configs.group_or_pin = purecfg ? np->name : 128 group; 129 new_map[i].data.configs.configs = pconfig; 130 new_map[i].data.configs.num_configs = 1; 131 } 132 133 *map = new_map; 134 *num_maps = new_num; 135 136 return 0; 137 138free_group: 139 if (!purecfg) 140 kfree(group); 141free: 142 kfree(new_map); 143 return ret; 144} 145 146static void mxs_dt_free_map(struct pinctrl_dev *pctldev, 147 struct pinctrl_map *map, unsigned num_maps) 148{ 149 u32 i; 150 151 for (i = 0; i < num_maps; i++) { 152 if (map[i].type == PIN_MAP_TYPE_MUX_GROUP) 153 kfree(map[i].data.mux.group); 154 if (map[i].type == PIN_MAP_TYPE_CONFIGS_GROUP) 155 kfree(map[i].data.configs.configs); 156 } 157 158 kfree(map); 159} 160 161static struct pinctrl_ops mxs_pinctrl_ops = { 162 .get_groups_count = mxs_get_groups_count, 163 .get_group_name = mxs_get_group_name, 164 .get_group_pins = mxs_get_group_pins, 165 .pin_dbg_show = mxs_pin_dbg_show, 166 .dt_node_to_map = mxs_dt_node_to_map, 167 .dt_free_map = mxs_dt_free_map, 168}; 169 170static int mxs_pinctrl_get_funcs_count(struct pinctrl_dev *pctldev) 171{ 172 struct mxs_pinctrl_data *d = pinctrl_dev_get_drvdata(pctldev); 173 174 return d->soc->nfunctions; 175} 176 177static const char *mxs_pinctrl_get_func_name(struct pinctrl_dev *pctldev, 178 unsigned function) 179{ 180 struct mxs_pinctrl_data *d = pinctrl_dev_get_drvdata(pctldev); 181 182 return d->soc->functions[function].name; 183} 184 185static int mxs_pinctrl_get_func_groups(struct pinctrl_dev *pctldev, 186 unsigned group, 187 const char * const **groups, 188 unsigned * const num_groups) 189{ 190 struct mxs_pinctrl_data *d = pinctrl_dev_get_drvdata(pctldev); 191 192 *groups = d->soc->functions[group].groups; 193 *num_groups = d->soc->functions[group].ngroups; 194 195 return 0; 196} 197 198static int mxs_pinctrl_enable(struct pinctrl_dev *pctldev, unsigned selector, 199 unsigned group) 200{ 201 struct mxs_pinctrl_data *d = pinctrl_dev_get_drvdata(pctldev); 202 struct mxs_group *g = &d->soc->groups[group]; 203 void __iomem *reg; 204 u8 bank, shift; 205 u16 pin; 206 u32 i; 207 208 for (i = 0; i < g->npins; i++) { 209 bank = PINID_TO_BANK(g->pins[i]); 210 pin = PINID_TO_PIN(g->pins[i]); 211 reg = d->base + d->soc->regs->muxsel; 212 reg += bank * 0x20 + pin / 16 * 0x10; 213 shift = pin % 16 * 2; 214 215 writel(0x3 << shift, reg + CLR); 216 writel(g->muxsel[i] << shift, reg + SET); 217 } 218 219 return 0; 220} 221 222static struct pinmux_ops mxs_pinmux_ops = { 223 .get_functions_count = mxs_pinctrl_get_funcs_count, 224 .get_function_name = mxs_pinctrl_get_func_name, 225 .get_function_groups = mxs_pinctrl_get_func_groups, 226 .enable = mxs_pinctrl_enable, 227}; 228 229static int mxs_pinconf_get(struct pinctrl_dev *pctldev, 230 unsigned pin, unsigned long *config) 231{ 232 return -ENOTSUPP; 233} 234 235static int mxs_pinconf_set(struct pinctrl_dev *pctldev, 236 unsigned pin, unsigned long config) 237{ 238 return -ENOTSUPP; 239} 240 241static int mxs_pinconf_group_get(struct pinctrl_dev *pctldev, 242 unsigned group, unsigned long *config) 243{ 244 struct mxs_pinctrl_data *d = pinctrl_dev_get_drvdata(pctldev); 245 246 *config = d->soc->groups[group].config; 247 248 return 0; 249} 250 251static int mxs_pinconf_group_set(struct pinctrl_dev *pctldev, 252 unsigned group, unsigned long config) 253{ 254 struct mxs_pinctrl_data *d = pinctrl_dev_get_drvdata(pctldev); 255 struct mxs_group *g = &d->soc->groups[group]; 256 void __iomem *reg; 257 u8 ma, vol, pull, bank, shift; 258 u16 pin; 259 u32 i; 260 261 ma = CONFIG_TO_MA(config); 262 vol = CONFIG_TO_VOL(config); 263 pull = CONFIG_TO_PULL(config); 264 265 for (i = 0; i < g->npins; i++) { 266 bank = PINID_TO_BANK(g->pins[i]); 267 pin = PINID_TO_PIN(g->pins[i]); 268 269 /* drive */ 270 reg = d->base + d->soc->regs->drive; 271 reg += bank * 0x40 + pin / 8 * 0x10; 272 273 /* mA */ 274 if (config & MA_PRESENT) { 275 shift = pin % 8 * 4; 276 writel(0x3 << shift, reg + CLR); 277 writel(ma << shift, reg + SET); 278 } 279 280 /* vol */ 281 if (config & VOL_PRESENT) { 282 shift = pin % 8 * 4 + 2; 283 if (vol) 284 writel(1 << shift, reg + SET); 285 else 286 writel(1 << shift, reg + CLR); 287 } 288 289 /* pull */ 290 if (config & PULL_PRESENT) { 291 reg = d->base + d->soc->regs->pull; 292 reg += bank * 0x10; 293 shift = pin; 294 if (pull) 295 writel(1 << shift, reg + SET); 296 else 297 writel(1 << shift, reg + CLR); 298 } 299 } 300 301 /* cache the config value for mxs_pinconf_group_get() */ 302 g->config = config; 303 304 return 0; 305} 306 307static void mxs_pinconf_dbg_show(struct pinctrl_dev *pctldev, 308 struct seq_file *s, unsigned pin) 309{ 310 /* Not support */ 311} 312 313static void mxs_pinconf_group_dbg_show(struct pinctrl_dev *pctldev, 314 struct seq_file *s, unsigned group) 315{ 316 unsigned long config; 317 318 if (!mxs_pinconf_group_get(pctldev, group, &config)) 319 seq_printf(s, "0x%lx", config); 320} 321 322static struct pinconf_ops mxs_pinconf_ops = { 323 .pin_config_get = mxs_pinconf_get, 324 .pin_config_set = mxs_pinconf_set, 325 .pin_config_group_get = mxs_pinconf_group_get, 326 .pin_config_group_set = mxs_pinconf_group_set, 327 .pin_config_dbg_show = mxs_pinconf_dbg_show, 328 .pin_config_group_dbg_show = mxs_pinconf_group_dbg_show, 329}; 330 331static struct pinctrl_desc mxs_pinctrl_desc = { 332 .pctlops = &mxs_pinctrl_ops, 333 .pmxops = &mxs_pinmux_ops, 334 .confops = &mxs_pinconf_ops, 335 .owner = THIS_MODULE, 336}; 337 338static int mxs_pinctrl_parse_group(struct platform_device *pdev, 339 struct device_node *np, int idx, 340 const char **out_name) 341{ 342 struct mxs_pinctrl_data *d = platform_get_drvdata(pdev); 343 struct mxs_group *g = &d->soc->groups[idx]; 344 struct property *prop; 345 const char *propname = "fsl,pinmux-ids"; 346 char *group; 347 int length = strlen(np->name) + SUFFIX_LEN; 348 u32 val, i; 349 350 group = devm_kzalloc(&pdev->dev, length, GFP_KERNEL); 351 if (!group) 352 return -ENOMEM; 353 if (of_property_read_u32(np, "reg", &val)) 354 snprintf(group, length, "%s", np->name); 355 else 356 snprintf(group, length, "%s.%d", np->name, val); 357 g->name = group; 358 359 prop = of_find_property(np, propname, &length); 360 if (!prop) 361 return -EINVAL; 362 g->npins = length / sizeof(u32); 363 364 g->pins = devm_kzalloc(&pdev->dev, g->npins * sizeof(*g->pins), 365 GFP_KERNEL); 366 if (!g->pins) 367 return -ENOMEM; 368 369 g->muxsel = devm_kzalloc(&pdev->dev, g->npins * sizeof(*g->muxsel), 370 GFP_KERNEL); 371 if (!g->muxsel) 372 return -ENOMEM; 373 374 of_property_read_u32_array(np, propname, g->pins, g->npins); 375 for (i = 0; i < g->npins; i++) { 376 g->muxsel[i] = MUXID_TO_MUXSEL(g->pins[i]); 377 g->pins[i] = MUXID_TO_PINID(g->pins[i]); 378 } 379 380 if (out_name) 381 *out_name = g->name; 382 383 return 0; 384} 385 386static int mxs_pinctrl_probe_dt(struct platform_device *pdev, 387 struct mxs_pinctrl_data *d) 388{ 389 struct mxs_pinctrl_soc_data *soc = d->soc; 390 struct device_node *np = pdev->dev.of_node; 391 struct device_node *child; 392 struct mxs_function *f; 393 const char *gpio_compat = "fsl,mxs-gpio"; 394 const char *fn, *fnull = ""; 395 int i = 0, idxf = 0, idxg = 0; 396 int ret; 397 u32 val; 398 399 child = of_get_next_child(np, NULL); 400 if (!child) { 401 dev_err(&pdev->dev, "no group is defined\n"); 402 return -ENOENT; 403 } 404 405 /* Count total functions and groups */ 406 fn = fnull; 407 for_each_child_of_node(np, child) { 408 if (of_device_is_compatible(child, gpio_compat)) 409 continue; 410 soc->ngroups++; 411 /* Skip pure pinconf node */ 412 if (of_property_read_u32(child, "reg", &val)) 413 continue; 414 if (strcmp(fn, child->name)) { 415 fn = child->name; 416 soc->nfunctions++; 417 } 418 } 419 420 soc->functions = devm_kzalloc(&pdev->dev, soc->nfunctions * 421 sizeof(*soc->functions), GFP_KERNEL); 422 if (!soc->functions) 423 return -ENOMEM; 424 425 soc->groups = devm_kzalloc(&pdev->dev, soc->ngroups * 426 sizeof(*soc->groups), GFP_KERNEL); 427 if (!soc->groups) 428 return -ENOMEM; 429 430 /* Count groups for each function */ 431 fn = fnull; 432 f = &soc->functions[idxf]; 433 for_each_child_of_node(np, child) { 434 if (of_device_is_compatible(child, gpio_compat)) 435 continue; 436 if (of_property_read_u32(child, "reg", &val)) 437 continue; 438 if (strcmp(fn, child->name)) { 439 f = &soc->functions[idxf++]; 440 f->name = fn = child->name; 441 } 442 f->ngroups++; 443 }; 444 445 /* Get groups for each function */ 446 idxf = 0; 447 fn = fnull; 448 for_each_child_of_node(np, child) { 449 if (of_device_is_compatible(child, gpio_compat)) 450 continue; 451 if (of_property_read_u32(child, "reg", &val)) { 452 ret = mxs_pinctrl_parse_group(pdev, child, 453 idxg++, NULL); 454 if (ret) 455 return ret; 456 continue; 457 } 458 459 if (strcmp(fn, child->name)) { 460 f = &soc->functions[idxf++]; 461 f->groups = devm_kzalloc(&pdev->dev, f->ngroups * 462 sizeof(*f->groups), 463 GFP_KERNEL); 464 if (!f->groups) 465 return -ENOMEM; 466 fn = child->name; 467 i = 0; 468 } 469 ret = mxs_pinctrl_parse_group(pdev, child, idxg++, 470 &f->groups[i++]); 471 if (ret) 472 return ret; 473 } 474 475 return 0; 476} 477 478int mxs_pinctrl_probe(struct platform_device *pdev, 479 struct mxs_pinctrl_soc_data *soc) 480{ 481 struct device_node *np = pdev->dev.of_node; 482 struct mxs_pinctrl_data *d; 483 int ret; 484 485 d = devm_kzalloc(&pdev->dev, sizeof(*d), GFP_KERNEL); 486 if (!d) 487 return -ENOMEM; 488 489 d->dev = &pdev->dev; 490 d->soc = soc; 491 492 d->base = of_iomap(np, 0); 493 if (!d->base) 494 return -EADDRNOTAVAIL; 495 496 mxs_pinctrl_desc.pins = d->soc->pins; 497 mxs_pinctrl_desc.npins = d->soc->npins; 498 mxs_pinctrl_desc.name = dev_name(&pdev->dev); 499 500 platform_set_drvdata(pdev, d); 501 502 ret = mxs_pinctrl_probe_dt(pdev, d); 503 if (ret) { 504 dev_err(&pdev->dev, "dt probe failed: %d\n", ret); 505 goto err; 506 } 507 508 d->pctl = pinctrl_register(&mxs_pinctrl_desc, &pdev->dev, d); 509 if (!d->pctl) { 510 dev_err(&pdev->dev, "Couldn't register MXS pinctrl driver\n"); 511 ret = -EINVAL; 512 goto err; 513 } 514 515 return 0; 516 517err: 518 platform_set_drvdata(pdev, NULL); 519 iounmap(d->base); 520 return ret; 521} 522EXPORT_SYMBOL_GPL(mxs_pinctrl_probe); 523 524int mxs_pinctrl_remove(struct platform_device *pdev) 525{ 526 struct mxs_pinctrl_data *d = platform_get_drvdata(pdev); 527 528 platform_set_drvdata(pdev, NULL); 529 pinctrl_unregister(d->pctl); 530 iounmap(d->base); 531 532 return 0; 533} 534EXPORT_SYMBOL_GPL(mxs_pinctrl_remove);