1 /* 2 * Core driver for the pin config portions of the pin control subsystem 3 * 4 * Copyright (C) 2011 ST-Ericsson SA 5 * Written on behalf of Linaro for ST-Ericsson 6 * 7 * Author: Linus Walleij <linus.walleij@linaro.org> 8 * 9 * License terms: GNU General Public License (GPL) version 2 10 */ 11 #define pr_fmt(fmt) "pinconfig core: " fmt 12 13 #include <linux/kernel.h> 14 #include <linux/module.h> 15 #include <linux/init.h> 16 #include <linux/device.h> 17 #include <linux/slab.h> 18 #include <linux/debugfs.h> 19 #include <linux/seq_file.h> 20 #include <linux/uaccess.h> 21 #include <linux/pinctrl/machine.h> 22 #include <linux/pinctrl/pinctrl.h> 23 #include <linux/pinctrl/pinconf.h> 24 #include "core.h" 25 #include "pinconf.h" 26 27 int pinconf_check_ops(struct pinctrl_dev *pctldev) 28 { 29 const struct pinconf_ops *ops = pctldev->desc->confops; 30 31 /* We must be able to read out pin status */ 32 if (!ops->pin_config_get && !ops->pin_config_group_get) { 33 dev_err(pctldev->dev, 34 "pinconf must be able to read out pin status\n"); 35 return -EINVAL; 36 } 37 /* We have to be able to config the pins in SOME way */ 38 if (!ops->pin_config_set && !ops->pin_config_group_set) { 39 dev_err(pctldev->dev, 40 "pinconf has to be able to set a pins config\n"); 41 return -EINVAL; 42 } 43 return 0; 44 } 45 46 int pinconf_validate_map(struct pinctrl_map const *map, int i) 47 { 48 if (!map->data.configs.group_or_pin) { 49 pr_err("failed to register map %s (%d): no group/pin given\n", 50 map->name, i); 51 return -EINVAL; 52 } 53 54 if (!map->data.configs.num_configs || 55 !map->data.configs.configs) { 56 pr_err("failed to register map %s (%d): no configs given\n", 57 map->name, i); 58 return -EINVAL; 59 } 60 61 return 0; 62 } 63 64 int pin_config_get_for_pin(struct pinctrl_dev *pctldev, unsigned pin, 65 unsigned long *config) 66 { 67 const struct pinconf_ops *ops = pctldev->desc->confops; 68 69 if (!ops || !ops->pin_config_get) { 70 dev_err(pctldev->dev, "cannot get pin configuration, missing " 71 "pin_config_get() function in driver\n"); 72 return -EINVAL; 73 } 74 75 return ops->pin_config_get(pctldev, pin, config); 76 } 77 78 /** 79 * pin_config_get() - get the configuration of a single pin parameter 80 * @dev_name: name of the pin controller device for this pin 81 * @name: name of the pin to get the config for 82 * @config: the config pointed to by this argument will be filled in with the 83 * current pin state, it can be used directly by drivers as a numeral, or 84 * it can be dereferenced to any struct. 85 */ 86 int pin_config_get(const char *dev_name, const char *name, 87 unsigned long *config) 88 { 89 struct pinctrl_dev *pctldev; 90 int pin; 91 92 pctldev = get_pinctrl_dev_from_devname(dev_name); 93 if (!pctldev) { 94 pin = -EINVAL; 95 return pin; 96 } 97 98 mutex_lock(&pctldev->mutex); 99 100 pin = pin_get_from_name(pctldev, name); 101 if (pin < 0) 102 goto unlock; 103 104 pin = pin_config_get_for_pin(pctldev, pin, config); 105 106 unlock: 107 mutex_unlock(&pctldev->mutex); 108 return pin; 109 } 110 EXPORT_SYMBOL(pin_config_get); 111 112 static int pin_config_set_for_pin(struct pinctrl_dev *pctldev, unsigned pin, 113 unsigned long config) 114 { 115 const struct pinconf_ops *ops = pctldev->desc->confops; 116 int ret; 117 118 if (!ops || !ops->pin_config_set) { 119 dev_err(pctldev->dev, "cannot configure pin, missing " 120 "config function in driver\n"); 121 return -EINVAL; 122 } 123 124 ret = ops->pin_config_set(pctldev, pin, config); 125 if (ret) { 126 dev_err(pctldev->dev, 127 "unable to set pin configuration on pin %d\n", pin); 128 return ret; 129 } 130 131 return 0; 132 } 133 134 /** 135 * pin_config_set() - set the configuration of a single pin parameter 136 * @dev_name: name of pin controller device for this pin 137 * @name: name of the pin to set the config for 138 * @config: the config in this argument will contain the desired pin state, it 139 * can be used directly by drivers as a numeral, or it can be dereferenced 140 * to any struct. 141 */ 142 int pin_config_set(const char *dev_name, const char *name, 143 unsigned long config) 144 { 145 struct pinctrl_dev *pctldev; 146 int pin, ret; 147 148 pctldev = get_pinctrl_dev_from_devname(dev_name); 149 if (!pctldev) { 150 ret = -EINVAL; 151 return ret; 152 } 153 154 mutex_lock(&pctldev->mutex); 155 156 pin = pin_get_from_name(pctldev, name); 157 if (pin < 0) { 158 ret = pin; 159 goto unlock; 160 } 161 162 ret = pin_config_set_for_pin(pctldev, pin, config); 163 164 unlock: 165 mutex_unlock(&pctldev->mutex); 166 return ret; 167 } 168 EXPORT_SYMBOL(pin_config_set); 169 170 int pin_config_group_get(const char *dev_name, const char *pin_group, 171 unsigned long *config) 172 { 173 struct pinctrl_dev *pctldev; 174 const struct pinconf_ops *ops; 175 int selector, ret; 176 177 pctldev = get_pinctrl_dev_from_devname(dev_name); 178 if (!pctldev) { 179 ret = -EINVAL; 180 return ret; 181 } 182 183 mutex_lock(&pctldev->mutex); 184 185 ops = pctldev->desc->confops; 186 187 if (!ops || !ops->pin_config_group_get) { 188 dev_err(pctldev->dev, "cannot get configuration for pin " 189 "group, missing group config get function in " 190 "driver\n"); 191 ret = -EINVAL; 192 goto unlock; 193 } 194 195 selector = pinctrl_get_group_selector(pctldev, pin_group); 196 if (selector < 0) { 197 ret = selector; 198 goto unlock; 199 } 200 201 ret = ops->pin_config_group_get(pctldev, selector, config); 202 203 unlock: 204 mutex_unlock(&pctldev->mutex); 205 return ret; 206 } 207 EXPORT_SYMBOL(pin_config_group_get); 208 209 int pin_config_group_set(const char *dev_name, const char *pin_group, 210 unsigned long config) 211 { 212 struct pinctrl_dev *pctldev; 213 const struct pinconf_ops *ops; 214 const struct pinctrl_ops *pctlops; 215 int selector; 216 const unsigned *pins; 217 unsigned num_pins; 218 int ret; 219 int i; 220 221 pctldev = get_pinctrl_dev_from_devname(dev_name); 222 if (!pctldev) { 223 ret = -EINVAL; 224 return ret; 225 } 226 227 mutex_lock(&pctldev->mutex); 228 229 ops = pctldev->desc->confops; 230 pctlops = pctldev->desc->pctlops; 231 232 if (!ops || (!ops->pin_config_group_set && !ops->pin_config_set)) { 233 dev_err(pctldev->dev, "cannot configure pin group, missing " 234 "config function in driver\n"); 235 ret = -EINVAL; 236 goto unlock; 237 } 238 239 selector = pinctrl_get_group_selector(pctldev, pin_group); 240 if (selector < 0) { 241 ret = selector; 242 goto unlock; 243 } 244 245 ret = pctlops->get_group_pins(pctldev, selector, &pins, &num_pins); 246 if (ret) { 247 dev_err(pctldev->dev, "cannot configure pin group, error " 248 "getting pins\n"); 249 goto unlock; 250 } 251 252 /* 253 * If the pin controller supports handling entire groups we use that 254 * capability. 255 */ 256 if (ops->pin_config_group_set) { 257 ret = ops->pin_config_group_set(pctldev, selector, config); 258 /* 259 * If the pin controller prefer that a certain group be handled 260 * pin-by-pin as well, it returns -EAGAIN. 261 */ 262 if (ret != -EAGAIN) 263 goto unlock; 264 } 265 266 /* 267 * If the controller cannot handle entire groups, we configure each pin 268 * individually. 269 */ 270 if (!ops->pin_config_set) { 271 ret = 0; 272 goto unlock; 273 } 274 275 for (i = 0; i < num_pins; i++) { 276 ret = ops->pin_config_set(pctldev, pins[i], config); 277 if (ret < 0) 278 goto unlock; 279 } 280 281 ret = 0; 282 283 unlock: 284 mutex_unlock(&pctldev->mutex); 285 286 return ret; 287 } 288 EXPORT_SYMBOL(pin_config_group_set); 289 290 int pinconf_map_to_setting(struct pinctrl_map const *map, 291 struct pinctrl_setting *setting) 292 { 293 struct pinctrl_dev *pctldev = setting->pctldev; 294 int pin; 295 296 switch (setting->type) { 297 case PIN_MAP_TYPE_CONFIGS_PIN: 298 pin = pin_get_from_name(pctldev, 299 map->data.configs.group_or_pin); 300 if (pin < 0) { 301 dev_err(pctldev->dev, "could not map pin config for \"%s\"", 302 map->data.configs.group_or_pin); 303 return pin; 304 } 305 setting->data.configs.group_or_pin = pin; 306 break; 307 case PIN_MAP_TYPE_CONFIGS_GROUP: 308 pin = pinctrl_get_group_selector(pctldev, 309 map->data.configs.group_or_pin); 310 if (pin < 0) { 311 dev_err(pctldev->dev, "could not map group config for \"%s\"", 312 map->data.configs.group_or_pin); 313 return pin; 314 } 315 setting->data.configs.group_or_pin = pin; 316 break; 317 default: 318 return -EINVAL; 319 } 320 321 setting->data.configs.num_configs = map->data.configs.num_configs; 322 setting->data.configs.configs = map->data.configs.configs; 323 324 return 0; 325 } 326 327 void pinconf_free_setting(struct pinctrl_setting const *setting) 328 { 329 } 330 331 int pinconf_apply_setting(struct pinctrl_setting const *setting) 332 { 333 struct pinctrl_dev *pctldev = setting->pctldev; 334 const struct pinconf_ops *ops = pctldev->desc->confops; 335 int i, ret; 336 337 if (!ops) { 338 dev_err(pctldev->dev, "missing confops\n"); 339 return -EINVAL; 340 } 341 342 switch (setting->type) { 343 case PIN_MAP_TYPE_CONFIGS_PIN: 344 if (!ops->pin_config_set) { 345 dev_err(pctldev->dev, "missing pin_config_set op\n"); 346 return -EINVAL; 347 } 348 for (i = 0; i < setting->data.configs.num_configs; i++) { 349 ret = ops->pin_config_set(pctldev, 350 setting->data.configs.group_or_pin, 351 setting->data.configs.configs[i]); 352 if (ret < 0) { 353 dev_err(pctldev->dev, 354 "pin_config_set op failed for pin %d config %08lx\n", 355 setting->data.configs.group_or_pin, 356 setting->data.configs.configs[i]); 357 return ret; 358 } 359 } 360 break; 361 case PIN_MAP_TYPE_CONFIGS_GROUP: 362 if (!ops->pin_config_group_set) { 363 dev_err(pctldev->dev, 364 "missing pin_config_group_set op\n"); 365 return -EINVAL; 366 } 367 for (i = 0; i < setting->data.configs.num_configs; i++) { 368 ret = ops->pin_config_group_set(pctldev, 369 setting->data.configs.group_or_pin, 370 setting->data.configs.configs[i]); 371 if (ret < 0) { 372 dev_err(pctldev->dev, 373 "pin_config_group_set op failed for group %d config %08lx\n", 374 setting->data.configs.group_or_pin, 375 setting->data.configs.configs[i]); 376 return ret; 377 } 378 } 379 break; 380 default: 381 return -EINVAL; 382 } 383 384 return 0; 385 } 386 387 #ifdef CONFIG_DEBUG_FS 388 389 void pinconf_show_map(struct seq_file *s, struct pinctrl_map const *map) 390 { 391 struct pinctrl_dev *pctldev; 392 const struct pinconf_ops *confops; 393 int i; 394 395 pctldev = get_pinctrl_dev_from_devname(map->ctrl_dev_name); 396 if (pctldev) 397 confops = pctldev->desc->confops; 398 else 399 confops = NULL; 400 401 switch (map->type) { 402 case PIN_MAP_TYPE_CONFIGS_PIN: 403 seq_printf(s, "pin "); 404 break; 405 case PIN_MAP_TYPE_CONFIGS_GROUP: 406 seq_printf(s, "group "); 407 break; 408 default: 409 break; 410 } 411 412 seq_printf(s, "%s\n", map->data.configs.group_or_pin); 413 414 for (i = 0; i < map->data.configs.num_configs; i++) { 415 seq_printf(s, "config "); 416 if (confops && confops->pin_config_config_dbg_show) 417 confops->pin_config_config_dbg_show(pctldev, s, 418 map->data.configs.configs[i]); 419 else 420 seq_printf(s, "%08lx", map->data.configs.configs[i]); 421 seq_printf(s, "\n"); 422 } 423 } 424 425 void pinconf_show_setting(struct seq_file *s, 426 struct pinctrl_setting const *setting) 427 { 428 struct pinctrl_dev *pctldev = setting->pctldev; 429 const struct pinctrl_ops *pctlops = pctldev->desc->pctlops; 430 const struct pinconf_ops *confops = pctldev->desc->confops; 431 struct pin_desc *desc; 432 int i; 433 434 switch (setting->type) { 435 case PIN_MAP_TYPE_CONFIGS_PIN: 436 desc = pin_desc_get(setting->pctldev, 437 setting->data.configs.group_or_pin); 438 seq_printf(s, "pin %s (%d)", 439 desc->name ? desc->name : "unnamed", 440 setting->data.configs.group_or_pin); 441 break; 442 case PIN_MAP_TYPE_CONFIGS_GROUP: 443 seq_printf(s, "group %s (%d)", 444 pctlops->get_group_name(pctldev, 445 setting->data.configs.group_or_pin), 446 setting->data.configs.group_or_pin); 447 break; 448 default: 449 break; 450 } 451 452 /* 453 * FIXME: We should really get the pin controler to dump the config 454 * values, so they can be decoded to something meaningful. 455 */ 456 for (i = 0; i < setting->data.configs.num_configs; i++) { 457 seq_printf(s, " "); 458 if (confops && confops->pin_config_config_dbg_show) 459 confops->pin_config_config_dbg_show(pctldev, s, 460 setting->data.configs.configs[i]); 461 else 462 seq_printf(s, "%08lx", 463 setting->data.configs.configs[i]); 464 } 465 466 seq_printf(s, "\n"); 467 } 468 469 static void pinconf_dump_pin(struct pinctrl_dev *pctldev, 470 struct seq_file *s, int pin) 471 { 472 const struct pinconf_ops *ops = pctldev->desc->confops; 473 474 /* no-op when not using generic pin config */ 475 pinconf_generic_dump_pin(pctldev, s, pin); 476 if (ops && ops->pin_config_dbg_show) 477 ops->pin_config_dbg_show(pctldev, s, pin); 478 } 479 480 static int pinconf_pins_show(struct seq_file *s, void *what) 481 { 482 struct pinctrl_dev *pctldev = s->private; 483 const struct pinconf_ops *ops = pctldev->desc->confops; 484 unsigned i, pin; 485 486 if (!ops || !ops->pin_config_get) 487 return 0; 488 489 seq_puts(s, "Pin config settings per pin\n"); 490 seq_puts(s, "Format: pin (name): configs\n"); 491 492 mutex_lock(&pctldev->mutex); 493 494 /* The pin number can be retrived from the pin controller descriptor */ 495 for (i = 0; i < pctldev->desc->npins; i++) { 496 struct pin_desc *desc; 497 498 pin = pctldev->desc->pins[i].number; 499 desc = pin_desc_get(pctldev, pin); 500 /* Skip if we cannot search the pin */ 501 if (desc == NULL) 502 continue; 503 504 seq_printf(s, "pin %d (%s):", pin, 505 desc->name ? desc->name : "unnamed"); 506 507 pinconf_dump_pin(pctldev, s, pin); 508 509 seq_printf(s, "\n"); 510 } 511 512 mutex_unlock(&pctldev->mutex); 513 514 return 0; 515 } 516 517 static void pinconf_dump_group(struct pinctrl_dev *pctldev, 518 struct seq_file *s, unsigned selector, 519 const char *gname) 520 { 521 const struct pinconf_ops *ops = pctldev->desc->confops; 522 523 /* no-op when not using generic pin config */ 524 pinconf_generic_dump_group(pctldev, s, gname); 525 if (ops && ops->pin_config_group_dbg_show) 526 ops->pin_config_group_dbg_show(pctldev, s, selector); 527 } 528 529 static int pinconf_groups_show(struct seq_file *s, void *what) 530 { 531 struct pinctrl_dev *pctldev = s->private; 532 const struct pinctrl_ops *pctlops = pctldev->desc->pctlops; 533 const struct pinconf_ops *ops = pctldev->desc->confops; 534 unsigned ngroups = pctlops->get_groups_count(pctldev); 535 unsigned selector = 0; 536 537 if (!ops || !ops->pin_config_group_get) 538 return 0; 539 540 seq_puts(s, "Pin config settings per pin group\n"); 541 seq_puts(s, "Format: group (name): configs\n"); 542 543 while (selector < ngroups) { 544 const char *gname = pctlops->get_group_name(pctldev, selector); 545 546 seq_printf(s, "%u (%s):", selector, gname); 547 pinconf_dump_group(pctldev, s, selector, gname); 548 seq_printf(s, "\n"); 549 550 selector++; 551 } 552 553 return 0; 554 } 555 556 static int pinconf_pins_open(struct inode *inode, struct file *file) 557 { 558 return single_open(file, pinconf_pins_show, inode->i_private); 559 } 560 561 static int pinconf_groups_open(struct inode *inode, struct file *file) 562 { 563 return single_open(file, pinconf_groups_show, inode->i_private); 564 } 565 566 static const struct file_operations pinconf_pins_ops = { 567 .open = pinconf_pins_open, 568 .read = seq_read, 569 .llseek = seq_lseek, 570 .release = single_release, 571 }; 572 573 static const struct file_operations pinconf_groups_ops = { 574 .open = pinconf_groups_open, 575 .read = seq_read, 576 .llseek = seq_lseek, 577 .release = single_release, 578 }; 579 580 #define MAX_NAME_LEN 15 581 582 struct dbg_cfg { 583 enum pinctrl_map_type map_type; 584 char dev_name[MAX_NAME_LEN+1]; 585 char state_name[MAX_NAME_LEN+1]; 586 char pin_name[MAX_NAME_LEN+1]; 587 }; 588 589 /* 590 * Goal is to keep this structure as global in order to simply read the 591 * pinconf-config file after a write to check config is as expected 592 */ 593 static struct dbg_cfg pinconf_dbg_conf; 594 595 /** 596 * pinconf_dbg_config_print() - display the pinctrl config from the pinctrl 597 * map, of the dev/pin/state that was last written to pinconf-config file. 598 * @s: string filled in with config description 599 * @d: not used 600 */ 601 static int pinconf_dbg_config_print(struct seq_file *s, void *d) 602 { 603 struct pinctrl_maps *maps_node; 604 const struct pinctrl_map *map; 605 struct pinctrl_dev *pctldev = NULL; 606 const struct pinconf_ops *confops = NULL; 607 const struct pinctrl_map_configs *configs; 608 struct dbg_cfg *dbg = &pinconf_dbg_conf; 609 int i, j; 610 bool found = false; 611 unsigned long config; 612 613 mutex_lock(&pctldev->mutex); 614 615 /* Parse the pinctrl map and look for the elected pin/state */ 616 for_each_maps(maps_node, i, map) { 617 if (map->type != dbg->map_type) 618 continue; 619 if (strcmp(map->dev_name, dbg->dev_name)) 620 continue; 621 if (strcmp(map->name, dbg->state_name)) 622 continue; 623 624 for (j = 0; j < map->data.configs.num_configs; j++) { 625 if (!strcmp(map->data.configs.group_or_pin, 626 dbg->pin_name)) { 627 /* 628 * We found the right pin / state, read the 629 * config and he pctldev for later use 630 */ 631 configs = &map->data.configs; 632 pctldev = get_pinctrl_dev_from_devname 633 (map->ctrl_dev_name); 634 found = true; 635 break; 636 } 637 } 638 } 639 640 if (!found) { 641 seq_printf(s, "No config found for dev/state/pin, expected:\n"); 642 seq_printf(s, "Searched dev:%s\n", dbg->dev_name); 643 seq_printf(s, "Searched state:%s\n", dbg->state_name); 644 seq_printf(s, "Searched pin:%s\n", dbg->pin_name); 645 seq_printf(s, "Use: modify config_pin <devname> "\ 646 "<state> <pinname> <value>\n"); 647 goto exit; 648 } 649 650 config = *(configs->configs); 651 seq_printf(s, "Dev %s has config of %s in state %s: 0x%08lX\n", 652 dbg->dev_name, dbg->pin_name, 653 dbg->state_name, config); 654 655 if (pctldev) 656 confops = pctldev->desc->confops; 657 658 if (confops && confops->pin_config_config_dbg_show) 659 confops->pin_config_config_dbg_show(pctldev, s, config); 660 661 exit: 662 mutex_unlock(&pctldev->mutex); 663 664 return 0; 665 } 666 667 /** 668 * pinconf_dbg_config_write() - modify the pinctrl config in the pinctrl 669 * map, of a dev/pin/state entry based on user entries to pinconf-config 670 * @user_buf: contains the modification request with expected format: 671 * modify config_pin <devicename> <state> <pinname> <newvalue> 672 * modify is literal string, alternatives like add/delete not supported yet 673 * config_pin is literal, alternatives like config_mux not supported yet 674 * <devicename> <state> <pinname> are values that should match the pinctrl-maps 675 * <newvalue> reflects the new config and is driver dependant 676 */ 677 static int pinconf_dbg_config_write(struct file *file, 678 const char __user *user_buf, size_t count, loff_t *ppos) 679 { 680 struct pinctrl_maps *maps_node; 681 const struct pinctrl_map *map; 682 struct pinctrl_dev *pctldev = NULL; 683 const struct pinconf_ops *confops = NULL; 684 struct dbg_cfg *dbg = &pinconf_dbg_conf; 685 const struct pinctrl_map_configs *configs; 686 char config[MAX_NAME_LEN+1]; 687 bool found = false; 688 char buf[128]; 689 char *b = &buf[0]; 690 int buf_size; 691 char *token; 692 int i; 693 694 /* Get userspace string and assure termination */ 695 buf_size = min(count, (sizeof(buf)-1)); 696 if (copy_from_user(buf, user_buf, buf_size)) 697 return -EFAULT; 698 buf[buf_size] = 0; 699 700 /* 701 * need to parse entry and extract parameters: 702 * modify configs_pin devicename state pinname newvalue 703 */ 704 705 /* Get arg: 'modify' */ 706 token = strsep(&b, " "); 707 if (!token) 708 return -EINVAL; 709 if (strcmp(token, "modify")) 710 return -EINVAL; 711 712 /* Get arg type: "config_pin" type supported so far */ 713 token = strsep(&b, " "); 714 if (!token) 715 return -EINVAL; 716 if (strcmp(token, "config_pin")) 717 return -EINVAL; 718 dbg->map_type = PIN_MAP_TYPE_CONFIGS_PIN; 719 720 /* get arg 'device_name' */ 721 token = strsep(&b, " "); 722 if (token == NULL) 723 return -EINVAL; 724 if (strlen(token) >= MAX_NAME_LEN) 725 return -EINVAL; 726 strncpy(dbg->dev_name, token, MAX_NAME_LEN); 727 728 /* get arg 'state_name' */ 729 token = strsep(&b, " "); 730 if (token == NULL) 731 return -EINVAL; 732 if (strlen(token) >= MAX_NAME_LEN) 733 return -EINVAL; 734 strncpy(dbg->state_name, token, MAX_NAME_LEN); 735 736 /* get arg 'pin_name' */ 737 token = strsep(&b, " "); 738 if (token == NULL) 739 return -EINVAL; 740 if (strlen(token) >= MAX_NAME_LEN) 741 return -EINVAL; 742 strncpy(dbg->pin_name, token, MAX_NAME_LEN); 743 744 /* get new_value of config' */ 745 token = strsep(&b, " "); 746 if (token == NULL) 747 return -EINVAL; 748 if (strlen(token) >= MAX_NAME_LEN) 749 return -EINVAL; 750 strncpy(config, token, MAX_NAME_LEN); 751 752 mutex_lock(&pinctrl_maps_mutex); 753 754 /* Parse the pinctrl map and look for the selected dev/state/pin */ 755 for_each_maps(maps_node, i, map) { 756 if (strcmp(map->dev_name, dbg->dev_name)) 757 continue; 758 if (map->type != dbg->map_type) 759 continue; 760 if (strcmp(map->name, dbg->state_name)) 761 continue; 762 763 /* we found the right pin / state, so overwrite config */ 764 if (!strcmp(map->data.configs.group_or_pin, dbg->pin_name)) { 765 found = true; 766 pctldev = get_pinctrl_dev_from_devname( 767 map->ctrl_dev_name); 768 configs = &map->data.configs; 769 break; 770 } 771 } 772 773 if (!found) { 774 count = -EINVAL; 775 goto exit; 776 } 777 778 if (pctldev) 779 confops = pctldev->desc->confops; 780 781 if (confops && confops->pin_config_dbg_parse_modify) { 782 for (i = 0; i < configs->num_configs; i++) { 783 confops->pin_config_dbg_parse_modify(pctldev, 784 config, 785 &configs->configs[i]); 786 } 787 } 788 789 exit: 790 mutex_unlock(&pinctrl_maps_mutex); 791 792 return count; 793 } 794 795 static int pinconf_dbg_config_open(struct inode *inode, struct file *file) 796 { 797 return single_open(file, pinconf_dbg_config_print, inode->i_private); 798 } 799 800 static const struct file_operations pinconf_dbg_pinconfig_fops = { 801 .open = pinconf_dbg_config_open, 802 .write = pinconf_dbg_config_write, 803 .read = seq_read, 804 .llseek = seq_lseek, 805 .release = single_release, 806 .owner = THIS_MODULE, 807 }; 808 809 void pinconf_init_device_debugfs(struct dentry *devroot, 810 struct pinctrl_dev *pctldev) 811 { 812 debugfs_create_file("pinconf-pins", S_IFREG | S_IRUGO, 813 devroot, pctldev, &pinconf_pins_ops); 814 debugfs_create_file("pinconf-groups", S_IFREG | S_IRUGO, 815 devroot, pctldev, &pinconf_groups_ops); 816 debugfs_create_file("pinconf-config", (S_IRUGO | S_IWUSR | S_IWGRP), 817 devroot, pctldev, &pinconf_dbg_pinconfig_fops); 818 } 819 820 #endif 821