1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * System Control and Management Interface (SCMI) Pinctrl Protocol 4 * 5 * Copyright (C) 2024 EPAM 6 * Copyright 2024 NXP 7 */ 8 9 #include <asm/byteorder.h> 10 #include <linux/bits.h> 11 #include <linux/bitfield.h> 12 #include <linux/device.h> 13 #include <linux/module.h> 14 #include <linux/scmi_protocol.h> 15 #include <linux/slab.h> 16 #include <linux/string.h> 17 #include <linux/types.h> 18 19 #include "common.h" 20 #include "protocols.h" 21 22 /* Updated only after ALL the mandatory features for that version are merged */ 23 #define SCMI_PROTOCOL_SUPPORTED_VERSION 0x10000 24 25 #define GET_GROUPS_NR(x) le32_get_bits((x), GENMASK(31, 16)) 26 #define GET_PINS_NR(x) le32_get_bits((x), GENMASK(15, 0)) 27 #define GET_FUNCTIONS_NR(x) le32_get_bits((x), GENMASK(15, 0)) 28 29 #define EXT_NAME_FLAG(x) le32_get_bits((x), BIT(31)) 30 #define NUM_ELEMS(x) le32_get_bits((x), GENMASK(15, 0)) 31 32 #define REMAINING(x) le32_get_bits((x), GENMASK(31, 16)) 33 #define RETURNED(x) le32_get_bits((x), GENMASK(11, 0)) 34 35 #define CONFIG_FLAG_MASK GENMASK(19, 18) 36 #define SELECTOR_MASK GENMASK(17, 16) 37 #define SKIP_CONFIGS_MASK GENMASK(15, 8) 38 #define CONFIG_TYPE_MASK GENMASK(7, 0) 39 40 enum scmi_pinctrl_protocol_cmd { 41 PINCTRL_ATTRIBUTES = 0x3, 42 PINCTRL_LIST_ASSOCIATIONS = 0x4, 43 PINCTRL_SETTINGS_GET = 0x5, 44 PINCTRL_SETTINGS_CONFIGURE = 0x6, 45 PINCTRL_REQUEST = 0x7, 46 PINCTRL_RELEASE = 0x8, 47 PINCTRL_NAME_GET = 0x9, 48 PINCTRL_SET_PERMISSIONS = 0xa, 49 }; 50 51 struct scmi_msg_settings_conf { 52 __le32 identifier; 53 __le32 function_id; 54 __le32 attributes; 55 __le32 configs[]; 56 }; 57 58 struct scmi_msg_settings_get { 59 __le32 identifier; 60 __le32 attributes; 61 }; 62 63 struct scmi_resp_settings_get { 64 __le32 function_selected; 65 __le32 num_configs; 66 __le32 configs[]; 67 }; 68 69 struct scmi_msg_pinctrl_protocol_attributes { 70 __le32 attributes_low; 71 __le32 attributes_high; 72 }; 73 74 struct scmi_msg_pinctrl_attributes { 75 __le32 identifier; 76 __le32 flags; 77 }; 78 79 struct scmi_resp_pinctrl_attributes { 80 __le32 attributes; 81 u8 name[SCMI_SHORT_NAME_MAX_SIZE]; 82 }; 83 84 struct scmi_msg_pinctrl_list_assoc { 85 __le32 identifier; 86 __le32 flags; 87 __le32 index; 88 }; 89 90 struct scmi_resp_pinctrl_list_assoc { 91 __le32 flags; 92 __le16 array[]; 93 }; 94 95 struct scmi_msg_request { 96 __le32 identifier; 97 __le32 flags; 98 }; 99 100 struct scmi_group_info { 101 char name[SCMI_MAX_STR_SIZE]; 102 bool present; 103 u32 *group_pins; 104 u32 nr_pins; 105 }; 106 107 struct scmi_function_info { 108 char name[SCMI_MAX_STR_SIZE]; 109 bool present; 110 u32 *groups; 111 u32 nr_groups; 112 }; 113 114 struct scmi_pin_info { 115 char name[SCMI_MAX_STR_SIZE]; 116 bool present; 117 }; 118 119 struct scmi_pinctrl_info { 120 int nr_groups; 121 int nr_functions; 122 int nr_pins; 123 struct scmi_group_info *groups; 124 struct scmi_function_info *functions; 125 struct scmi_pin_info *pins; 126 }; 127 128 static int scmi_pinctrl_attributes_get(const struct scmi_protocol_handle *ph, 129 struct scmi_pinctrl_info *pi) 130 { 131 int ret; 132 struct scmi_xfer *t; 133 struct scmi_msg_pinctrl_protocol_attributes *attr; 134 135 ret = ph->xops->xfer_get_init(ph, PROTOCOL_ATTRIBUTES, 0, sizeof(*attr), &t); 136 if (ret) 137 return ret; 138 139 attr = t->rx.buf; 140 141 ret = ph->xops->do_xfer(ph, t); 142 if (!ret) { 143 pi->nr_functions = GET_FUNCTIONS_NR(attr->attributes_high); 144 pi->nr_groups = GET_GROUPS_NR(attr->attributes_low); 145 pi->nr_pins = GET_PINS_NR(attr->attributes_low); 146 if (pi->nr_pins == 0) { 147 dev_warn(ph->dev, "returned zero pins\n"); 148 ret = -EINVAL; 149 } 150 } 151 152 ph->xops->xfer_put(ph, t); 153 return ret; 154 } 155 156 static int scmi_pinctrl_count_get(const struct scmi_protocol_handle *ph, 157 enum scmi_pinctrl_selector_type type) 158 { 159 struct scmi_pinctrl_info *pi = ph->get_priv(ph); 160 161 switch (type) { 162 case PIN_TYPE: 163 return pi->nr_pins; 164 case GROUP_TYPE: 165 return pi->nr_groups; 166 case FUNCTION_TYPE: 167 return pi->nr_functions; 168 default: 169 return -EINVAL; 170 } 171 } 172 173 static int scmi_pinctrl_validate_id(const struct scmi_protocol_handle *ph, 174 u32 selector, 175 enum scmi_pinctrl_selector_type type) 176 { 177 int value; 178 179 value = scmi_pinctrl_count_get(ph, type); 180 if (value < 0) 181 return value; 182 183 if (selector >= value || value == 0) 184 return -EINVAL; 185 186 return 0; 187 } 188 189 static int scmi_pinctrl_attributes(const struct scmi_protocol_handle *ph, 190 enum scmi_pinctrl_selector_type type, 191 u32 selector, char *name, 192 u32 *n_elems) 193 { 194 int ret; 195 struct scmi_xfer *t; 196 struct scmi_msg_pinctrl_attributes *tx; 197 struct scmi_resp_pinctrl_attributes *rx; 198 bool ext_name_flag; 199 200 if (!name) 201 return -EINVAL; 202 203 ret = scmi_pinctrl_validate_id(ph, selector, type); 204 if (ret) 205 return ret; 206 207 ret = ph->xops->xfer_get_init(ph, PINCTRL_ATTRIBUTES, sizeof(*tx), 208 sizeof(*rx), &t); 209 if (ret) 210 return ret; 211 212 tx = t->tx.buf; 213 rx = t->rx.buf; 214 tx->identifier = cpu_to_le32(selector); 215 tx->flags = cpu_to_le32(type); 216 217 ret = ph->xops->do_xfer(ph, t); 218 if (!ret) { 219 if (n_elems) 220 *n_elems = NUM_ELEMS(rx->attributes); 221 222 strscpy(name, rx->name, SCMI_SHORT_NAME_MAX_SIZE); 223 224 ext_name_flag = !!EXT_NAME_FLAG(rx->attributes); 225 } 226 227 ph->xops->xfer_put(ph, t); 228 229 if (ret) 230 return ret; 231 /* 232 * If supported overwrite short name with the extended one; 233 * on error just carry on and use already provided short name. 234 */ 235 if (ext_name_flag) 236 ret = ph->hops->extended_name_get(ph, PINCTRL_NAME_GET, 237 selector, (u32 *)&type, name, 238 SCMI_MAX_STR_SIZE); 239 return ret; 240 } 241 242 struct scmi_pinctrl_ipriv { 243 u32 selector; 244 enum scmi_pinctrl_selector_type type; 245 u32 *array; 246 }; 247 248 static void iter_pinctrl_assoc_prepare_message(void *message, 249 u32 desc_index, 250 const void *priv) 251 { 252 struct scmi_msg_pinctrl_list_assoc *msg = message; 253 const struct scmi_pinctrl_ipriv *p = priv; 254 255 msg->identifier = cpu_to_le32(p->selector); 256 msg->flags = cpu_to_le32(p->type); 257 msg->index = cpu_to_le32(desc_index); 258 } 259 260 static int iter_pinctrl_assoc_update_state(struct scmi_iterator_state *st, 261 const void *response, void *priv) 262 { 263 const struct scmi_resp_pinctrl_list_assoc *r = response; 264 265 st->num_returned = RETURNED(r->flags); 266 st->num_remaining = REMAINING(r->flags); 267 268 return 0; 269 } 270 271 static int 272 iter_pinctrl_assoc_process_response(const struct scmi_protocol_handle *ph, 273 const void *response, 274 struct scmi_iterator_state *st, void *priv) 275 { 276 const struct scmi_resp_pinctrl_list_assoc *r = response; 277 struct scmi_pinctrl_ipriv *p = priv; 278 279 p->array[st->desc_index + st->loop_idx] = 280 le16_to_cpu(r->array[st->loop_idx]); 281 282 return 0; 283 } 284 285 static int scmi_pinctrl_list_associations(const struct scmi_protocol_handle *ph, 286 u32 selector, 287 enum scmi_pinctrl_selector_type type, 288 u16 size, u32 *array) 289 { 290 int ret; 291 void *iter; 292 struct scmi_iterator_ops ops = { 293 .prepare_message = iter_pinctrl_assoc_prepare_message, 294 .update_state = iter_pinctrl_assoc_update_state, 295 .process_response = iter_pinctrl_assoc_process_response, 296 }; 297 struct scmi_pinctrl_ipriv ipriv = { 298 .selector = selector, 299 .type = type, 300 .array = array, 301 }; 302 303 if (!array || !size || type == PIN_TYPE) 304 return -EINVAL; 305 306 ret = scmi_pinctrl_validate_id(ph, selector, type); 307 if (ret) 308 return ret; 309 310 iter = ph->hops->iter_response_init(ph, &ops, size, 311 PINCTRL_LIST_ASSOCIATIONS, 312 sizeof(struct scmi_msg_pinctrl_list_assoc), 313 &ipriv); 314 if (IS_ERR(iter)) 315 return PTR_ERR(iter); 316 317 return ph->hops->iter_response_run(iter); 318 } 319 320 struct scmi_settings_get_ipriv { 321 u32 selector; 322 enum scmi_pinctrl_selector_type type; 323 bool get_all; 324 unsigned int *nr_configs; 325 enum scmi_pinctrl_conf_type *config_types; 326 u32 *config_values; 327 }; 328 329 static void 330 iter_pinctrl_settings_get_prepare_message(void *message, u32 desc_index, 331 const void *priv) 332 { 333 struct scmi_msg_settings_get *msg = message; 334 const struct scmi_settings_get_ipriv *p = priv; 335 u32 attributes; 336 337 attributes = FIELD_PREP(SELECTOR_MASK, p->type); 338 339 if (p->get_all) { 340 attributes |= FIELD_PREP(CONFIG_FLAG_MASK, 1) | 341 FIELD_PREP(SKIP_CONFIGS_MASK, desc_index); 342 } else { 343 attributes |= FIELD_PREP(CONFIG_TYPE_MASK, p->config_types[0]); 344 } 345 346 msg->attributes = cpu_to_le32(attributes); 347 msg->identifier = cpu_to_le32(p->selector); 348 } 349 350 static int 351 iter_pinctrl_settings_get_update_state(struct scmi_iterator_state *st, 352 const void *response, void *priv) 353 { 354 const struct scmi_resp_settings_get *r = response; 355 struct scmi_settings_get_ipriv *p = priv; 356 357 if (p->get_all) { 358 st->num_returned = le32_get_bits(r->num_configs, GENMASK(7, 0)); 359 st->num_remaining = le32_get_bits(r->num_configs, GENMASK(31, 24)); 360 } else { 361 st->num_returned = 1; 362 st->num_remaining = 0; 363 } 364 365 return 0; 366 } 367 368 static int 369 iter_pinctrl_settings_get_process_response(const struct scmi_protocol_handle *ph, 370 const void *response, 371 struct scmi_iterator_state *st, 372 void *priv) 373 { 374 const struct scmi_resp_settings_get *r = response; 375 struct scmi_settings_get_ipriv *p = priv; 376 u32 type = le32_get_bits(r->configs[st->loop_idx * 2], GENMASK(7, 0)); 377 u32 val = le32_to_cpu(r->configs[st->loop_idx * 2 + 1]); 378 379 if (p->get_all) { 380 p->config_types[st->desc_index + st->loop_idx] = type; 381 } else { 382 if (p->config_types[0] != type) 383 return -EINVAL; 384 } 385 386 p->config_values[st->desc_index + st->loop_idx] = val; 387 ++*p->nr_configs; 388 389 return 0; 390 } 391 392 static int 393 scmi_pinctrl_settings_get(const struct scmi_protocol_handle *ph, u32 selector, 394 enum scmi_pinctrl_selector_type type, 395 unsigned int *nr_configs, 396 enum scmi_pinctrl_conf_type *config_types, 397 u32 *config_values) 398 { 399 int ret; 400 void *iter; 401 unsigned int max_configs = *nr_configs; 402 struct scmi_iterator_ops ops = { 403 .prepare_message = iter_pinctrl_settings_get_prepare_message, 404 .update_state = iter_pinctrl_settings_get_update_state, 405 .process_response = iter_pinctrl_settings_get_process_response, 406 }; 407 struct scmi_settings_get_ipriv ipriv = { 408 .selector = selector, 409 .type = type, 410 .get_all = (max_configs > 1), 411 .nr_configs = nr_configs, 412 .config_types = config_types, 413 .config_values = config_values, 414 }; 415 416 if (!config_types || !config_values || type == FUNCTION_TYPE) 417 return -EINVAL; 418 419 ret = scmi_pinctrl_validate_id(ph, selector, type); 420 if (ret) 421 return ret; 422 423 /* Prepare to count returned configs */ 424 *nr_configs = 0; 425 iter = ph->hops->iter_response_init(ph, &ops, max_configs, 426 PINCTRL_SETTINGS_GET, 427 sizeof(struct scmi_msg_settings_get), 428 &ipriv); 429 if (IS_ERR(iter)) 430 return PTR_ERR(iter); 431 432 return ph->hops->iter_response_run(iter); 433 } 434 435 static int scmi_pinctrl_settings_get_one(const struct scmi_protocol_handle *ph, 436 u32 selector, 437 enum scmi_pinctrl_selector_type type, 438 enum scmi_pinctrl_conf_type config_type, 439 u32 *config_value) 440 { 441 unsigned int nr_configs = 1; 442 443 return scmi_pinctrl_settings_get(ph, selector, type, &nr_configs, 444 &config_type, config_value); 445 } 446 447 static int scmi_pinctrl_settings_get_all(const struct scmi_protocol_handle *ph, 448 u32 selector, 449 enum scmi_pinctrl_selector_type type, 450 unsigned int *nr_configs, 451 enum scmi_pinctrl_conf_type *config_types, 452 u32 *config_values) 453 { 454 if (!nr_configs || *nr_configs == 0) 455 return -EINVAL; 456 457 return scmi_pinctrl_settings_get(ph, selector, type, nr_configs, 458 config_types, config_values); 459 } 460 461 static int 462 scmi_pinctrl_settings_conf(const struct scmi_protocol_handle *ph, 463 u32 selector, 464 enum scmi_pinctrl_selector_type type, 465 u32 nr_configs, 466 enum scmi_pinctrl_conf_type *config_type, 467 u32 *config_value) 468 { 469 struct scmi_xfer *t; 470 struct scmi_msg_settings_conf *tx; 471 u32 attributes; 472 int ret, i; 473 u32 configs_in_chunk, conf_num = 0; 474 u32 chunk; 475 int max_msg_size = ph->hops->get_max_msg_size(ph); 476 477 if (!config_type || !config_value || type == FUNCTION_TYPE) 478 return -EINVAL; 479 480 ret = scmi_pinctrl_validate_id(ph, selector, type); 481 if (ret) 482 return ret; 483 484 configs_in_chunk = (max_msg_size - sizeof(*tx)) / (sizeof(__le32) * 2); 485 while (conf_num < nr_configs) { 486 chunk = (nr_configs - conf_num > configs_in_chunk) ? 487 configs_in_chunk : nr_configs - conf_num; 488 489 ret = ph->xops->xfer_get_init(ph, PINCTRL_SETTINGS_CONFIGURE, 490 sizeof(*tx) + 491 chunk * 2 * sizeof(__le32), 0, &t); 492 if (ret) 493 break; 494 495 tx = t->tx.buf; 496 tx->identifier = cpu_to_le32(selector); 497 tx->function_id = cpu_to_le32(0xFFFFFFFF); 498 attributes = FIELD_PREP(GENMASK(1, 0), type) | 499 FIELD_PREP(GENMASK(9, 2), chunk); 500 tx->attributes = cpu_to_le32(attributes); 501 502 for (i = 0; i < chunk; i++) { 503 tx->configs[i * 2] = 504 cpu_to_le32(config_type[conf_num + i]); 505 tx->configs[i * 2 + 1] = 506 cpu_to_le32(config_value[conf_num + i]); 507 } 508 509 ret = ph->xops->do_xfer(ph, t); 510 511 ph->xops->xfer_put(ph, t); 512 513 if (ret) 514 break; 515 516 conf_num += chunk; 517 } 518 519 return ret; 520 } 521 522 static int scmi_pinctrl_function_select(const struct scmi_protocol_handle *ph, 523 u32 group, 524 enum scmi_pinctrl_selector_type type, 525 u32 function_id) 526 { 527 int ret; 528 struct scmi_xfer *t; 529 struct scmi_msg_settings_conf *tx; 530 u32 attributes; 531 532 ret = scmi_pinctrl_validate_id(ph, group, type); 533 if (ret) 534 return ret; 535 536 ret = ph->xops->xfer_get_init(ph, PINCTRL_SETTINGS_CONFIGURE, 537 sizeof(*tx), 0, &t); 538 if (ret) 539 return ret; 540 541 tx = t->tx.buf; 542 tx->identifier = cpu_to_le32(group); 543 tx->function_id = cpu_to_le32(function_id); 544 attributes = FIELD_PREP(GENMASK(1, 0), type) | BIT(10); 545 tx->attributes = cpu_to_le32(attributes); 546 547 ret = ph->xops->do_xfer(ph, t); 548 ph->xops->xfer_put(ph, t); 549 550 return ret; 551 } 552 553 static int scmi_pinctrl_request_free(const struct scmi_protocol_handle *ph, 554 u32 identifier, 555 enum scmi_pinctrl_selector_type type, 556 enum scmi_pinctrl_protocol_cmd cmd) 557 { 558 int ret; 559 struct scmi_xfer *t; 560 struct scmi_msg_request *tx; 561 562 if (type == FUNCTION_TYPE) 563 return -EINVAL; 564 565 if (cmd != PINCTRL_REQUEST && cmd != PINCTRL_RELEASE) 566 return -EINVAL; 567 568 ret = scmi_pinctrl_validate_id(ph, identifier, type); 569 if (ret) 570 return ret; 571 572 ret = ph->xops->xfer_get_init(ph, cmd, sizeof(*tx), 0, &t); 573 if (ret) 574 return ret; 575 576 tx = t->tx.buf; 577 tx->identifier = cpu_to_le32(identifier); 578 tx->flags = cpu_to_le32(type); 579 580 ret = ph->xops->do_xfer(ph, t); 581 ph->xops->xfer_put(ph, t); 582 583 return ret; 584 } 585 586 static int scmi_pinctrl_pin_request(const struct scmi_protocol_handle *ph, 587 u32 pin) 588 { 589 return scmi_pinctrl_request_free(ph, pin, PIN_TYPE, PINCTRL_REQUEST); 590 } 591 592 static int scmi_pinctrl_pin_free(const struct scmi_protocol_handle *ph, u32 pin) 593 { 594 return scmi_pinctrl_request_free(ph, pin, PIN_TYPE, PINCTRL_RELEASE); 595 } 596 597 static int scmi_pinctrl_get_group_info(const struct scmi_protocol_handle *ph, 598 u32 selector) 599 { 600 struct scmi_pinctrl_info *pi = ph->get_priv(ph); 601 struct scmi_group_info *group; 602 int ret; 603 604 if (selector >= pi->nr_groups) 605 return -EINVAL; 606 607 group = &pi->groups[selector]; 608 if (group->present) 609 return 0; 610 611 ret = scmi_pinctrl_attributes(ph, GROUP_TYPE, selector, group->name, 612 &group->nr_pins); 613 if (ret) 614 return ret; 615 616 if (!group->nr_pins) { 617 dev_err(ph->dev, "Group %d has 0 elements", selector); 618 return -ENODATA; 619 } 620 621 group->group_pins = kmalloc_array(group->nr_pins, 622 sizeof(*group->group_pins), 623 GFP_KERNEL); 624 if (!group->group_pins) 625 return -ENOMEM; 626 627 ret = scmi_pinctrl_list_associations(ph, selector, GROUP_TYPE, 628 group->nr_pins, group->group_pins); 629 if (ret) { 630 kfree(group->group_pins); 631 return ret; 632 } 633 634 group->present = true; 635 return 0; 636 } 637 638 static int scmi_pinctrl_get_group_name(const struct scmi_protocol_handle *ph, 639 u32 selector, const char **name) 640 { 641 struct scmi_pinctrl_info *pi = ph->get_priv(ph); 642 int ret; 643 644 if (!name) 645 return -EINVAL; 646 647 ret = scmi_pinctrl_get_group_info(ph, selector); 648 if (ret) 649 return ret; 650 651 *name = pi->groups[selector].name; 652 653 return 0; 654 } 655 656 static int scmi_pinctrl_group_pins_get(const struct scmi_protocol_handle *ph, 657 u32 selector, const u32 **pins, 658 u32 *nr_pins) 659 { 660 struct scmi_pinctrl_info *pi = ph->get_priv(ph); 661 int ret; 662 663 if (!pins || !nr_pins) 664 return -EINVAL; 665 666 ret = scmi_pinctrl_get_group_info(ph, selector); 667 if (ret) 668 return ret; 669 670 *pins = pi->groups[selector].group_pins; 671 *nr_pins = pi->groups[selector].nr_pins; 672 673 return 0; 674 } 675 676 static int scmi_pinctrl_get_function_info(const struct scmi_protocol_handle *ph, 677 u32 selector) 678 { 679 struct scmi_pinctrl_info *pi = ph->get_priv(ph); 680 struct scmi_function_info *func; 681 int ret; 682 683 if (selector >= pi->nr_functions) 684 return -EINVAL; 685 686 func = &pi->functions[selector]; 687 if (func->present) 688 return 0; 689 690 ret = scmi_pinctrl_attributes(ph, FUNCTION_TYPE, selector, func->name, 691 &func->nr_groups); 692 if (ret) 693 return ret; 694 695 if (!func->nr_groups) { 696 dev_err(ph->dev, "Function %d has 0 elements", selector); 697 return -ENODATA; 698 } 699 700 func->groups = kmalloc_array(func->nr_groups, sizeof(*func->groups), 701 GFP_KERNEL); 702 if (!func->groups) 703 return -ENOMEM; 704 705 ret = scmi_pinctrl_list_associations(ph, selector, FUNCTION_TYPE, 706 func->nr_groups, func->groups); 707 if (ret) { 708 kfree(func->groups); 709 return ret; 710 } 711 712 func->present = true; 713 return 0; 714 } 715 716 static int scmi_pinctrl_get_function_name(const struct scmi_protocol_handle *ph, 717 u32 selector, const char **name) 718 { 719 struct scmi_pinctrl_info *pi = ph->get_priv(ph); 720 int ret; 721 722 if (!name) 723 return -EINVAL; 724 725 ret = scmi_pinctrl_get_function_info(ph, selector); 726 if (ret) 727 return ret; 728 729 *name = pi->functions[selector].name; 730 return 0; 731 } 732 733 static int 734 scmi_pinctrl_function_groups_get(const struct scmi_protocol_handle *ph, 735 u32 selector, u32 *nr_groups, 736 const u32 **groups) 737 { 738 struct scmi_pinctrl_info *pi = ph->get_priv(ph); 739 int ret; 740 741 if (!groups || !nr_groups) 742 return -EINVAL; 743 744 ret = scmi_pinctrl_get_function_info(ph, selector); 745 if (ret) 746 return ret; 747 748 *groups = pi->functions[selector].groups; 749 *nr_groups = pi->functions[selector].nr_groups; 750 751 return 0; 752 } 753 754 static int scmi_pinctrl_mux_set(const struct scmi_protocol_handle *ph, 755 u32 selector, u32 group) 756 { 757 return scmi_pinctrl_function_select(ph, group, GROUP_TYPE, selector); 758 } 759 760 static int scmi_pinctrl_get_pin_info(const struct scmi_protocol_handle *ph, 761 u32 selector) 762 { 763 struct scmi_pinctrl_info *pi = ph->get_priv(ph); 764 struct scmi_pin_info *pin; 765 int ret; 766 767 if (selector >= pi->nr_pins) 768 return -EINVAL; 769 770 pin = &pi->pins[selector]; 771 if (pin->present) 772 return 0; 773 774 ret = scmi_pinctrl_attributes(ph, PIN_TYPE, selector, pin->name, NULL); 775 if (ret) 776 return ret; 777 778 pin->present = true; 779 return 0; 780 } 781 782 static int scmi_pinctrl_get_pin_name(const struct scmi_protocol_handle *ph, 783 u32 selector, const char **name) 784 { 785 struct scmi_pinctrl_info *pi = ph->get_priv(ph); 786 int ret; 787 788 if (!name) 789 return -EINVAL; 790 791 ret = scmi_pinctrl_get_pin_info(ph, selector); 792 if (ret) 793 return ret; 794 795 *name = pi->pins[selector].name; 796 797 return 0; 798 } 799 800 static int scmi_pinctrl_name_get(const struct scmi_protocol_handle *ph, 801 u32 selector, 802 enum scmi_pinctrl_selector_type type, 803 const char **name) 804 { 805 switch (type) { 806 case PIN_TYPE: 807 return scmi_pinctrl_get_pin_name(ph, selector, name); 808 case GROUP_TYPE: 809 return scmi_pinctrl_get_group_name(ph, selector, name); 810 case FUNCTION_TYPE: 811 return scmi_pinctrl_get_function_name(ph, selector, name); 812 default: 813 return -EINVAL; 814 } 815 } 816 817 static const struct scmi_pinctrl_proto_ops pinctrl_proto_ops = { 818 .count_get = scmi_pinctrl_count_get, 819 .name_get = scmi_pinctrl_name_get, 820 .group_pins_get = scmi_pinctrl_group_pins_get, 821 .function_groups_get = scmi_pinctrl_function_groups_get, 822 .mux_set = scmi_pinctrl_mux_set, 823 .settings_get_one = scmi_pinctrl_settings_get_one, 824 .settings_get_all = scmi_pinctrl_settings_get_all, 825 .settings_conf = scmi_pinctrl_settings_conf, 826 .pin_request = scmi_pinctrl_pin_request, 827 .pin_free = scmi_pinctrl_pin_free, 828 }; 829 830 static int scmi_pinctrl_protocol_init(const struct scmi_protocol_handle *ph) 831 { 832 int ret; 833 struct scmi_pinctrl_info *pinfo; 834 835 dev_dbg(ph->dev, "Pinctrl Version %d.%d\n", 836 PROTOCOL_REV_MAJOR(ph->version), PROTOCOL_REV_MINOR(ph->version)); 837 838 pinfo = devm_kzalloc(ph->dev, sizeof(*pinfo), GFP_KERNEL); 839 if (!pinfo) 840 return -ENOMEM; 841 842 ret = scmi_pinctrl_attributes_get(ph, pinfo); 843 if (ret) 844 return ret; 845 846 pinfo->pins = devm_kcalloc(ph->dev, pinfo->nr_pins, 847 sizeof(*pinfo->pins), GFP_KERNEL); 848 if (!pinfo->pins) 849 return -ENOMEM; 850 851 pinfo->groups = devm_kcalloc(ph->dev, pinfo->nr_groups, 852 sizeof(*pinfo->groups), GFP_KERNEL); 853 if (!pinfo->groups) 854 return -ENOMEM; 855 856 pinfo->functions = devm_kcalloc(ph->dev, pinfo->nr_functions, 857 sizeof(*pinfo->functions), GFP_KERNEL); 858 if (!pinfo->functions) 859 return -ENOMEM; 860 861 return ph->set_priv(ph, pinfo); 862 } 863 864 static int scmi_pinctrl_protocol_deinit(const struct scmi_protocol_handle *ph) 865 { 866 int i; 867 struct scmi_pinctrl_info *pi = ph->get_priv(ph); 868 869 /* Free groups_pins allocated in scmi_pinctrl_get_group_info */ 870 for (i = 0; i < pi->nr_groups; i++) { 871 if (pi->groups[i].present) { 872 kfree(pi->groups[i].group_pins); 873 pi->groups[i].present = false; 874 } 875 } 876 877 /* Free groups allocated in scmi_pinctrl_get_function_info */ 878 for (i = 0; i < pi->nr_functions; i++) { 879 if (pi->functions[i].present) { 880 kfree(pi->functions[i].groups); 881 pi->functions[i].present = false; 882 } 883 } 884 885 return 0; 886 } 887 888 static const struct scmi_protocol scmi_pinctrl = { 889 .id = SCMI_PROTOCOL_PINCTRL, 890 .owner = THIS_MODULE, 891 .instance_init = &scmi_pinctrl_protocol_init, 892 .instance_deinit = &scmi_pinctrl_protocol_deinit, 893 .ops = &pinctrl_proto_ops, 894 .supported_version = SCMI_PROTOCOL_SUPPORTED_VERSION, 895 }; 896 897 DEFINE_SCMI_PROTOCOL_REGISTER_UNREGISTER(pinctrl, scmi_pinctrl) 898