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 if (ret == -EOPNOTSUPP) 582 ret = 0; 583 ph->xops->xfer_put(ph, t); 584 585 return ret; 586 } 587 588 static int scmi_pinctrl_pin_request(const struct scmi_protocol_handle *ph, 589 u32 pin) 590 { 591 return scmi_pinctrl_request_free(ph, pin, PIN_TYPE, PINCTRL_REQUEST); 592 } 593 594 static int scmi_pinctrl_pin_free(const struct scmi_protocol_handle *ph, u32 pin) 595 { 596 return scmi_pinctrl_request_free(ph, pin, PIN_TYPE, PINCTRL_RELEASE); 597 } 598 599 static int scmi_pinctrl_get_group_info(const struct scmi_protocol_handle *ph, 600 u32 selector) 601 { 602 struct scmi_pinctrl_info *pi = ph->get_priv(ph); 603 struct scmi_group_info *group; 604 int ret; 605 606 if (selector >= pi->nr_groups) 607 return -EINVAL; 608 609 group = &pi->groups[selector]; 610 if (group->present) 611 return 0; 612 613 ret = scmi_pinctrl_attributes(ph, GROUP_TYPE, selector, group->name, 614 &group->nr_pins); 615 if (ret) 616 return ret; 617 618 if (!group->nr_pins) { 619 dev_err(ph->dev, "Group %d has 0 elements", selector); 620 return -ENODATA; 621 } 622 623 group->group_pins = kmalloc_array(group->nr_pins, 624 sizeof(*group->group_pins), 625 GFP_KERNEL); 626 if (!group->group_pins) 627 return -ENOMEM; 628 629 ret = scmi_pinctrl_list_associations(ph, selector, GROUP_TYPE, 630 group->nr_pins, group->group_pins); 631 if (ret) { 632 kfree(group->group_pins); 633 return ret; 634 } 635 636 group->present = true; 637 return 0; 638 } 639 640 static int scmi_pinctrl_get_group_name(const struct scmi_protocol_handle *ph, 641 u32 selector, const char **name) 642 { 643 struct scmi_pinctrl_info *pi = ph->get_priv(ph); 644 int ret; 645 646 if (!name) 647 return -EINVAL; 648 649 ret = scmi_pinctrl_get_group_info(ph, selector); 650 if (ret) 651 return ret; 652 653 *name = pi->groups[selector].name; 654 655 return 0; 656 } 657 658 static int scmi_pinctrl_group_pins_get(const struct scmi_protocol_handle *ph, 659 u32 selector, const u32 **pins, 660 u32 *nr_pins) 661 { 662 struct scmi_pinctrl_info *pi = ph->get_priv(ph); 663 int ret; 664 665 if (!pins || !nr_pins) 666 return -EINVAL; 667 668 ret = scmi_pinctrl_get_group_info(ph, selector); 669 if (ret) 670 return ret; 671 672 *pins = pi->groups[selector].group_pins; 673 *nr_pins = pi->groups[selector].nr_pins; 674 675 return 0; 676 } 677 678 static int scmi_pinctrl_get_function_info(const struct scmi_protocol_handle *ph, 679 u32 selector) 680 { 681 struct scmi_pinctrl_info *pi = ph->get_priv(ph); 682 struct scmi_function_info *func; 683 int ret; 684 685 if (selector >= pi->nr_functions) 686 return -EINVAL; 687 688 func = &pi->functions[selector]; 689 if (func->present) 690 return 0; 691 692 ret = scmi_pinctrl_attributes(ph, FUNCTION_TYPE, selector, func->name, 693 &func->nr_groups); 694 if (ret) 695 return ret; 696 697 if (!func->nr_groups) { 698 dev_err(ph->dev, "Function %d has 0 elements", selector); 699 return -ENODATA; 700 } 701 702 func->groups = kmalloc_array(func->nr_groups, sizeof(*func->groups), 703 GFP_KERNEL); 704 if (!func->groups) 705 return -ENOMEM; 706 707 ret = scmi_pinctrl_list_associations(ph, selector, FUNCTION_TYPE, 708 func->nr_groups, func->groups); 709 if (ret) { 710 kfree(func->groups); 711 return ret; 712 } 713 714 func->present = true; 715 return 0; 716 } 717 718 static int scmi_pinctrl_get_function_name(const struct scmi_protocol_handle *ph, 719 u32 selector, const char **name) 720 { 721 struct scmi_pinctrl_info *pi = ph->get_priv(ph); 722 int ret; 723 724 if (!name) 725 return -EINVAL; 726 727 ret = scmi_pinctrl_get_function_info(ph, selector); 728 if (ret) 729 return ret; 730 731 *name = pi->functions[selector].name; 732 return 0; 733 } 734 735 static int 736 scmi_pinctrl_function_groups_get(const struct scmi_protocol_handle *ph, 737 u32 selector, u32 *nr_groups, 738 const u32 **groups) 739 { 740 struct scmi_pinctrl_info *pi = ph->get_priv(ph); 741 int ret; 742 743 if (!groups || !nr_groups) 744 return -EINVAL; 745 746 ret = scmi_pinctrl_get_function_info(ph, selector); 747 if (ret) 748 return ret; 749 750 *groups = pi->functions[selector].groups; 751 *nr_groups = pi->functions[selector].nr_groups; 752 753 return 0; 754 } 755 756 static int scmi_pinctrl_mux_set(const struct scmi_protocol_handle *ph, 757 u32 selector, u32 group) 758 { 759 return scmi_pinctrl_function_select(ph, group, GROUP_TYPE, selector); 760 } 761 762 static int scmi_pinctrl_get_pin_info(const struct scmi_protocol_handle *ph, 763 u32 selector) 764 { 765 struct scmi_pinctrl_info *pi = ph->get_priv(ph); 766 struct scmi_pin_info *pin; 767 int ret; 768 769 if (selector >= pi->nr_pins) 770 return -EINVAL; 771 772 pin = &pi->pins[selector]; 773 if (pin->present) 774 return 0; 775 776 ret = scmi_pinctrl_attributes(ph, PIN_TYPE, selector, pin->name, NULL); 777 if (ret) 778 return ret; 779 780 pin->present = true; 781 return 0; 782 } 783 784 static int scmi_pinctrl_get_pin_name(const struct scmi_protocol_handle *ph, 785 u32 selector, const char **name) 786 { 787 struct scmi_pinctrl_info *pi = ph->get_priv(ph); 788 int ret; 789 790 if (!name) 791 return -EINVAL; 792 793 ret = scmi_pinctrl_get_pin_info(ph, selector); 794 if (ret) 795 return ret; 796 797 *name = pi->pins[selector].name; 798 799 return 0; 800 } 801 802 static int scmi_pinctrl_name_get(const struct scmi_protocol_handle *ph, 803 u32 selector, 804 enum scmi_pinctrl_selector_type type, 805 const char **name) 806 { 807 switch (type) { 808 case PIN_TYPE: 809 return scmi_pinctrl_get_pin_name(ph, selector, name); 810 case GROUP_TYPE: 811 return scmi_pinctrl_get_group_name(ph, selector, name); 812 case FUNCTION_TYPE: 813 return scmi_pinctrl_get_function_name(ph, selector, name); 814 default: 815 return -EINVAL; 816 } 817 } 818 819 static const struct scmi_pinctrl_proto_ops pinctrl_proto_ops = { 820 .count_get = scmi_pinctrl_count_get, 821 .name_get = scmi_pinctrl_name_get, 822 .group_pins_get = scmi_pinctrl_group_pins_get, 823 .function_groups_get = scmi_pinctrl_function_groups_get, 824 .mux_set = scmi_pinctrl_mux_set, 825 .settings_get_one = scmi_pinctrl_settings_get_one, 826 .settings_get_all = scmi_pinctrl_settings_get_all, 827 .settings_conf = scmi_pinctrl_settings_conf, 828 .pin_request = scmi_pinctrl_pin_request, 829 .pin_free = scmi_pinctrl_pin_free, 830 }; 831 832 static int scmi_pinctrl_protocol_init(const struct scmi_protocol_handle *ph) 833 { 834 int ret; 835 struct scmi_pinctrl_info *pinfo; 836 837 dev_dbg(ph->dev, "Pinctrl Version %d.%d\n", 838 PROTOCOL_REV_MAJOR(ph->version), PROTOCOL_REV_MINOR(ph->version)); 839 840 pinfo = devm_kzalloc(ph->dev, sizeof(*pinfo), GFP_KERNEL); 841 if (!pinfo) 842 return -ENOMEM; 843 844 ret = scmi_pinctrl_attributes_get(ph, pinfo); 845 if (ret) 846 return ret; 847 848 pinfo->pins = devm_kcalloc(ph->dev, pinfo->nr_pins, 849 sizeof(*pinfo->pins), GFP_KERNEL); 850 if (!pinfo->pins) 851 return -ENOMEM; 852 853 pinfo->groups = devm_kcalloc(ph->dev, pinfo->nr_groups, 854 sizeof(*pinfo->groups), GFP_KERNEL); 855 if (!pinfo->groups) 856 return -ENOMEM; 857 858 pinfo->functions = devm_kcalloc(ph->dev, pinfo->nr_functions, 859 sizeof(*pinfo->functions), GFP_KERNEL); 860 if (!pinfo->functions) 861 return -ENOMEM; 862 863 return ph->set_priv(ph, pinfo); 864 } 865 866 static int scmi_pinctrl_protocol_deinit(const struct scmi_protocol_handle *ph) 867 { 868 int i; 869 struct scmi_pinctrl_info *pi = ph->get_priv(ph); 870 871 /* Free groups_pins allocated in scmi_pinctrl_get_group_info */ 872 for (i = 0; i < pi->nr_groups; i++) { 873 if (pi->groups[i].present) { 874 kfree(pi->groups[i].group_pins); 875 pi->groups[i].present = false; 876 } 877 } 878 879 /* Free groups allocated in scmi_pinctrl_get_function_info */ 880 for (i = 0; i < pi->nr_functions; i++) { 881 if (pi->functions[i].present) { 882 kfree(pi->functions[i].groups); 883 pi->functions[i].present = false; 884 } 885 } 886 887 return 0; 888 } 889 890 static const struct scmi_protocol scmi_pinctrl = { 891 .id = SCMI_PROTOCOL_PINCTRL, 892 .owner = THIS_MODULE, 893 .instance_init = &scmi_pinctrl_protocol_init, 894 .instance_deinit = &scmi_pinctrl_protocol_deinit, 895 .ops = &pinctrl_proto_ops, 896 .supported_version = SCMI_PROTOCOL_SUPPORTED_VERSION, 897 }; 898 899 DEFINE_SCMI_PROTOCOL_REGISTER_UNREGISTER(pinctrl, scmi_pinctrl) 900