926 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 * ZynqMP pin controller4 *5 * Copyright (C) 2020, 2021 Xilinx, Inc.6 *7 * Sai Krishna Potthuri <lakshmi.sai.krishna.potthuri@xilinx.com>8 * Rajan Vaja <rajan.vaja@xilinx.com>9 */10 11#include <dt-bindings/pinctrl/pinctrl-zynqmp.h>12 13#include <linux/bitmap.h>14#include <linux/init.h>15#include <linux/module.h>16#include <linux/of_address.h>17#include <linux/platform_device.h>18 19#include <linux/firmware/xlnx-zynqmp.h>20 21#include <linux/pinctrl/pinconf-generic.h>22#include <linux/pinctrl/pinconf.h>23#include <linux/pinctrl/pinctrl.h>24#include <linux/pinctrl/pinmux.h>25 26#include "core.h"27#include "pinctrl-utils.h"28 29#define ZYNQMP_PIN_PREFIX "MIO"30#define PINCTRL_GET_FUNC_NAME_RESP_LEN 1631#define MAX_FUNC_NAME_LEN 1632#define MAX_GROUP_PIN 5033#define MAX_PIN_GROUPS 5034#define END_OF_FUNCTIONS "END_OF_FUNCTIONS"35#define NUM_GROUPS_PER_RESP 636 37#define PINCTRL_GET_FUNC_GROUPS_RESP_LEN 1238#define PINCTRL_GET_PIN_GROUPS_RESP_LEN 1239#define NA_GROUP 0xFFFF40#define RESERVED_GROUP 0xFFFE41 42#define DRIVE_STRENGTH_2MA 243#define DRIVE_STRENGTH_4MA 444#define DRIVE_STRENGTH_8MA 845#define DRIVE_STRENGTH_12MA 1246 47/**48 * struct zynqmp_pmux_function - a pinmux function49 * @name: Name of the pin mux function50 * @groups: List of pin groups for this function51 * @ngroups: Number of entries in @groups52 * @node: Firmware node matching with the function53 *54 * This structure holds information about pin control function55 * and function group names supporting that function.56 */57struct zynqmp_pmux_function {58 char name[MAX_FUNC_NAME_LEN];59 const char * const *groups;60 unsigned int ngroups;61};62 63/**64 * struct zynqmp_pinctrl - driver data65 * @pctrl: Pin control device66 * @groups: Pin groups67 * @ngroups: Number of @groups68 * @funcs: Pin mux functions69 * @nfuncs: Number of @funcs70 *71 * This struct is stored as driver data and used to retrieve72 * information regarding pin control functions, groups and73 * group pins.74 */75struct zynqmp_pinctrl {76 struct pinctrl_dev *pctrl;77 const struct zynqmp_pctrl_group *groups;78 unsigned int ngroups;79 const struct zynqmp_pmux_function *funcs;80 unsigned int nfuncs;81};82 83/**84 * struct zynqmp_pctrl_group - Pin control group info85 * @name: Group name86 * @pins: Group pin numbers87 * @npins: Number of pins in the group88 */89struct zynqmp_pctrl_group {90 const char *name;91 unsigned int pins[MAX_GROUP_PIN];92 unsigned int npins;93};94 95static struct pinctrl_desc zynqmp_desc;96 97static int zynqmp_pctrl_get_groups_count(struct pinctrl_dev *pctldev)98{99 struct zynqmp_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);100 101 return pctrl->ngroups + zynqmp_desc.npins;102}103 104static const char *zynqmp_pctrl_get_group_name(struct pinctrl_dev *pctldev,105 unsigned int selector)106{107 struct zynqmp_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);108 109 if (selector < pctrl->ngroups)110 return pctrl->groups[selector].name;111 112 return zynqmp_desc.pins[selector - pctrl->ngroups].name;113}114 115static int zynqmp_pctrl_get_group_pins(struct pinctrl_dev *pctldev,116 unsigned int selector,117 const unsigned int **pins,118 unsigned int *npins)119{120 struct zynqmp_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);121 122 if (selector < pctrl->ngroups) {123 *pins = pctrl->groups[selector].pins;124 *npins = pctrl->groups[selector].npins;125 } else {126 *pins = &zynqmp_desc.pins[selector - pctrl->ngroups].number;127 *npins = 1;128 }129 130 return 0;131}132 133static const struct pinctrl_ops zynqmp_pctrl_ops = {134 .get_groups_count = zynqmp_pctrl_get_groups_count,135 .get_group_name = zynqmp_pctrl_get_group_name,136 .get_group_pins = zynqmp_pctrl_get_group_pins,137 .dt_node_to_map = pinconf_generic_dt_node_to_map_all,138 .dt_free_map = pinctrl_utils_free_map,139};140 141static int zynqmp_pinmux_request_pin(struct pinctrl_dev *pctldev,142 unsigned int pin)143{144 int ret;145 146 ret = zynqmp_pm_pinctrl_request(pin);147 if (ret) {148 dev_err(pctldev->dev, "request failed for pin %u\n", pin);149 return ret;150 }151 152 return 0;153}154 155static int zynqmp_pmux_get_functions_count(struct pinctrl_dev *pctldev)156{157 struct zynqmp_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);158 159 return pctrl->nfuncs;160}161 162static const char *zynqmp_pmux_get_function_name(struct pinctrl_dev *pctldev,163 unsigned int selector)164{165 struct zynqmp_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);166 167 return pctrl->funcs[selector].name;168}169 170/**171 * zynqmp_pmux_get_function_groups() - Get groups for the function172 * @pctldev: Pincontrol device pointer.173 * @selector: Function ID174 * @groups: Group names.175 * @num_groups: Number of function groups.176 *177 * Get function's group count and group names.178 *179 * Return: 0180 */181static int zynqmp_pmux_get_function_groups(struct pinctrl_dev *pctldev,182 unsigned int selector,183 const char * const **groups,184 unsigned * const num_groups)185{186 struct zynqmp_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);187 188 *groups = pctrl->funcs[selector].groups;189 *num_groups = pctrl->funcs[selector].ngroups;190 191 return 0;192}193 194/**195 * zynqmp_pinmux_set_mux() - Set requested function for the group196 * @pctldev: Pincontrol device pointer.197 * @function: Function ID.198 * @group: Group ID.199 *200 * Loop through all pins of the group and call firmware API201 * to set requested function for all pins in the group.202 *203 * Return: 0 on success else error code.204 */205static int zynqmp_pinmux_set_mux(struct pinctrl_dev *pctldev,206 unsigned int function,207 unsigned int group)208{209 const unsigned int *pins;210 unsigned int npins;211 int ret, i;212 213 zynqmp_pctrl_get_group_pins(pctldev, group, &pins, &npins);214 for (i = 0; i < npins; i++) {215 ret = zynqmp_pm_pinctrl_set_function(pins[i], function);216 if (ret) {217 dev_err(pctldev->dev, "set mux failed for pin %u\n",218 pins[i]);219 return ret;220 }221 }222 223 return 0;224}225 226static int zynqmp_pinmux_release_pin(struct pinctrl_dev *pctldev,227 unsigned int pin)228{229 int ret;230 231 ret = zynqmp_pm_pinctrl_release(pin);232 if (ret) {233 dev_err(pctldev->dev, "free pin failed for pin %u\n",234 pin);235 return ret;236 }237 238 return 0;239}240 241static const struct pinmux_ops zynqmp_pinmux_ops = {242 .request = zynqmp_pinmux_request_pin,243 .get_functions_count = zynqmp_pmux_get_functions_count,244 .get_function_name = zynqmp_pmux_get_function_name,245 .get_function_groups = zynqmp_pmux_get_function_groups,246 .set_mux = zynqmp_pinmux_set_mux,247 .free = zynqmp_pinmux_release_pin,248};249 250/**251 * zynqmp_pinconf_cfg_get() - get config value for the pin252 * @pctldev: Pin control device pointer.253 * @pin: Pin number.254 * @config: Value of config param.255 *256 * Get value of the requested configuration parameter for the257 * given pin.258 *259 * Return: 0 on success else error code.260 */261static int zynqmp_pinconf_cfg_get(struct pinctrl_dev *pctldev,262 unsigned int pin,263 unsigned long *config)264{265 unsigned int arg, param = pinconf_to_config_param(*config);266 int ret;267 268 switch (param) {269 case PIN_CONFIG_SLEW_RATE:270 param = PM_PINCTRL_CONFIG_SLEW_RATE;271 ret = zynqmp_pm_pinctrl_get_config(pin, param, &arg);272 break;273 case PIN_CONFIG_BIAS_PULL_UP:274 param = PM_PINCTRL_CONFIG_PULL_CTRL;275 ret = zynqmp_pm_pinctrl_get_config(pin, param, &arg);276 if (arg != PM_PINCTRL_BIAS_PULL_UP)277 return -EINVAL;278 279 arg = 1;280 break;281 case PIN_CONFIG_BIAS_PULL_DOWN:282 param = PM_PINCTRL_CONFIG_PULL_CTRL;283 ret = zynqmp_pm_pinctrl_get_config(pin, param, &arg);284 if (arg != PM_PINCTRL_BIAS_PULL_DOWN)285 return -EINVAL;286 287 arg = 1;288 break;289 case PIN_CONFIG_BIAS_DISABLE:290 param = PM_PINCTRL_CONFIG_BIAS_STATUS;291 ret = zynqmp_pm_pinctrl_get_config(pin, param, &arg);292 if (arg != PM_PINCTRL_BIAS_DISABLE)293 return -EINVAL;294 295 arg = 1;296 break;297 case PIN_CONFIG_POWER_SOURCE:298 param = PM_PINCTRL_CONFIG_VOLTAGE_STATUS;299 ret = zynqmp_pm_pinctrl_get_config(pin, param, &arg);300 break;301 case PIN_CONFIG_INPUT_SCHMITT_ENABLE:302 param = PM_PINCTRL_CONFIG_SCHMITT_CMOS;303 ret = zynqmp_pm_pinctrl_get_config(pin, param, &arg);304 break;305 case PIN_CONFIG_DRIVE_STRENGTH:306 param = PM_PINCTRL_CONFIG_DRIVE_STRENGTH;307 ret = zynqmp_pm_pinctrl_get_config(pin, param, &arg);308 switch (arg) {309 case PM_PINCTRL_DRIVE_STRENGTH_2MA:310 arg = DRIVE_STRENGTH_2MA;311 break;312 case PM_PINCTRL_DRIVE_STRENGTH_4MA:313 arg = DRIVE_STRENGTH_4MA;314 break;315 case PM_PINCTRL_DRIVE_STRENGTH_8MA:316 arg = DRIVE_STRENGTH_8MA;317 break;318 case PM_PINCTRL_DRIVE_STRENGTH_12MA:319 arg = DRIVE_STRENGTH_12MA;320 break;321 default:322 /* Invalid drive strength */323 dev_warn(pctldev->dev,324 "Invalid drive strength for pin %d\n",325 pin);326 return -EINVAL;327 }328 break;329 default:330 ret = -ENOTSUPP;331 break;332 }333 334 if (ret)335 return ret;336 337 param = pinconf_to_config_param(*config);338 *config = pinconf_to_config_packed(param, arg);339 340 return 0;341}342 343/**344 * zynqmp_pinconf_cfg_set() - Set requested config for the pin345 * @pctldev: Pincontrol device pointer.346 * @pin: Pin number.347 * @configs: Configuration to set.348 * @num_configs: Number of configurations.349 *350 * Loop through all configurations and call firmware API351 * to set requested configurations for the pin.352 *353 * Return: 0 on success else error code.354 */355static int zynqmp_pinconf_cfg_set(struct pinctrl_dev *pctldev,356 unsigned int pin, unsigned long *configs,357 unsigned int num_configs)358{359 int i, ret;360 361 for (i = 0; i < num_configs; i++) {362 unsigned int param = pinconf_to_config_param(configs[i]);363 unsigned int arg = pinconf_to_config_argument(configs[i]);364 unsigned int value;365 366 switch (param) {367 case PIN_CONFIG_SLEW_RATE:368 param = PM_PINCTRL_CONFIG_SLEW_RATE;369 ret = zynqmp_pm_pinctrl_set_config(pin, param, arg);370 break;371 case PIN_CONFIG_BIAS_PULL_UP:372 param = PM_PINCTRL_CONFIG_PULL_CTRL;373 arg = PM_PINCTRL_BIAS_PULL_UP;374 ret = zynqmp_pm_pinctrl_set_config(pin, param, arg);375 break;376 case PIN_CONFIG_BIAS_PULL_DOWN:377 param = PM_PINCTRL_CONFIG_PULL_CTRL;378 arg = PM_PINCTRL_BIAS_PULL_DOWN;379 ret = zynqmp_pm_pinctrl_set_config(pin, param, arg);380 break;381 case PIN_CONFIG_BIAS_DISABLE:382 param = PM_PINCTRL_CONFIG_BIAS_STATUS;383 arg = PM_PINCTRL_BIAS_DISABLE;384 ret = zynqmp_pm_pinctrl_set_config(pin, param, arg);385 break;386 case PIN_CONFIG_INPUT_SCHMITT_ENABLE:387 param = PM_PINCTRL_CONFIG_SCHMITT_CMOS;388 ret = zynqmp_pm_pinctrl_set_config(pin, param, arg);389 break;390 case PIN_CONFIG_DRIVE_STRENGTH:391 switch (arg) {392 case DRIVE_STRENGTH_2MA:393 value = PM_PINCTRL_DRIVE_STRENGTH_2MA;394 break;395 case DRIVE_STRENGTH_4MA:396 value = PM_PINCTRL_DRIVE_STRENGTH_4MA;397 break;398 case DRIVE_STRENGTH_8MA:399 value = PM_PINCTRL_DRIVE_STRENGTH_8MA;400 break;401 case DRIVE_STRENGTH_12MA:402 value = PM_PINCTRL_DRIVE_STRENGTH_12MA;403 break;404 default:405 /* Invalid drive strength */406 dev_warn(pctldev->dev,407 "Invalid drive strength for pin %d\n",408 pin);409 return -EINVAL;410 }411 412 param = PM_PINCTRL_CONFIG_DRIVE_STRENGTH;413 ret = zynqmp_pm_pinctrl_set_config(pin, param, value);414 break;415 case PIN_CONFIG_POWER_SOURCE:416 param = PM_PINCTRL_CONFIG_VOLTAGE_STATUS;417 ret = zynqmp_pm_pinctrl_get_config(pin, param, &value);418 419 if (arg != value)420 dev_warn(pctldev->dev,421 "Invalid IO Standard requested for pin %d\n",422 pin);423 424 break;425 case PIN_CONFIG_BIAS_HIGH_IMPEDANCE:426 param = PM_PINCTRL_CONFIG_TRI_STATE;427 arg = PM_PINCTRL_TRI_STATE_ENABLE;428 ret = zynqmp_pm_pinctrl_set_config(pin, param, arg);429 break;430 case PIN_CONFIG_MODE_LOW_POWER:431 /*432 * These cases are mentioned in dts but configurable433 * registers are unknown. So falling through to ignore434 * boot time warnings as of now.435 */436 ret = 0;437 break;438 case PIN_CONFIG_OUTPUT_ENABLE:439 param = PM_PINCTRL_CONFIG_TRI_STATE;440 arg = PM_PINCTRL_TRI_STATE_DISABLE;441 ret = zynqmp_pm_pinctrl_set_config(pin, param, arg);442 break;443 default:444 dev_warn(pctldev->dev,445 "unsupported configuration parameter '%u'\n",446 param);447 ret = -ENOTSUPP;448 break;449 }450 451 param = pinconf_to_config_param(configs[i]);452 arg = pinconf_to_config_argument(configs[i]);453 if (ret)454 dev_warn(pctldev->dev,455 "failed to set: pin %u param %u value %u\n",456 pin, param, arg);457 }458 459 return 0;460}461 462/**463 * zynqmp_pinconf_group_set() - Set requested config for the group464 * @pctldev: Pincontrol device pointer.465 * @selector: Group ID.466 * @configs: Configuration to set.467 * @num_configs: Number of configurations.468 *469 * Call function to set configs for each pin in the group.470 *471 * Return: 0 on success else error code.472 */473static int zynqmp_pinconf_group_set(struct pinctrl_dev *pctldev,474 unsigned int selector,475 unsigned long *configs,476 unsigned int num_configs)477{478 const unsigned int *pins;479 unsigned int npins;480 int i, ret;481 482 zynqmp_pctrl_get_group_pins(pctldev, selector, &pins, &npins);483 for (i = 0; i < npins; i++) {484 ret = zynqmp_pinconf_cfg_set(pctldev, pins[i], configs,485 num_configs);486 if (ret)487 return ret;488 }489 490 return 0;491}492 493static const struct pinconf_ops zynqmp_pinconf_ops = {494 .is_generic = true,495 .pin_config_get = zynqmp_pinconf_cfg_get,496 .pin_config_set = zynqmp_pinconf_cfg_set,497 .pin_config_group_set = zynqmp_pinconf_group_set,498};499 500static struct pinctrl_desc zynqmp_desc = {501 .name = "zynqmp_pinctrl",502 .owner = THIS_MODULE,503 .pctlops = &zynqmp_pctrl_ops,504 .pmxops = &zynqmp_pinmux_ops,505 .confops = &zynqmp_pinconf_ops,506};507 508static int zynqmp_pinctrl_get_function_groups(u32 fid, u32 index, u16 *groups)509{510 struct zynqmp_pm_query_data qdata = {0};511 u32 payload[PAYLOAD_ARG_CNT];512 int ret;513 514 qdata.qid = PM_QID_PINCTRL_GET_FUNCTION_GROUPS;515 qdata.arg1 = fid;516 qdata.arg2 = index;517 518 ret = zynqmp_pm_query_data(qdata, payload);519 if (ret)520 return ret;521 522 memcpy(groups, &payload[1], PINCTRL_GET_FUNC_GROUPS_RESP_LEN);523 524 return 0;525}526 527static int zynqmp_pinctrl_get_func_num_groups(u32 fid, unsigned int *ngroups)528{529 struct zynqmp_pm_query_data qdata = {0};530 u32 payload[PAYLOAD_ARG_CNT];531 int ret;532 533 qdata.qid = PM_QID_PINCTRL_GET_NUM_FUNCTION_GROUPS;534 qdata.arg1 = fid;535 536 ret = zynqmp_pm_query_data(qdata, payload);537 if (ret)538 return ret;539 540 *ngroups = payload[1];541 542 return 0;543}544 545/**546 * zynqmp_pinctrl_prepare_func_groups() - prepare function and groups data547 * @dev: Device pointer.548 * @fid: Function ID.549 * @func: Function data.550 * @groups: Groups data.551 *552 * Query firmware to get group IDs for each function. Firmware returns553 * group IDs. Based on the group index for the function, group names in554 * the function are stored. For example, the first group in "eth0" function555 * is named as "eth0_0" and the second group as "eth0_1" and so on.556 *557 * Based on the group ID received from the firmware, function stores name of558 * the group for that group ID. For example, if "eth0" first group ID559 * is x, groups[x] name will be stored as "eth0_0".560 *561 * Once done for each function, each function would have its group names562 * and each group would also have their names.563 *564 * Return: 0 on success else error code.565 */566static int zynqmp_pinctrl_prepare_func_groups(struct device *dev, u32 fid,567 struct zynqmp_pmux_function *func,568 struct zynqmp_pctrl_group *groups)569{570 u16 resp[NUM_GROUPS_PER_RESP] = {0};571 const char **fgroups;572 int ret, index, i, pin;573 unsigned int npins;574 unsigned long *used_pins __free(bitmap) =575 bitmap_zalloc(zynqmp_desc.npins, GFP_KERNEL);576 577 if (!used_pins)578 return -ENOMEM;579 580 for (index = 0; index < func->ngroups; index += NUM_GROUPS_PER_RESP) {581 ret = zynqmp_pinctrl_get_function_groups(fid, index, resp);582 if (ret)583 return ret;584 585 for (i = 0; i < NUM_GROUPS_PER_RESP; i++) {586 if (resp[i] == NA_GROUP)587 goto done;588 589 if (resp[i] == RESERVED_GROUP)590 continue;591 592 groups[resp[i]].name = devm_kasprintf(dev, GFP_KERNEL,593 "%s_%d_grp",594 func->name,595 index + i);596 if (!groups[resp[i]].name)597 return -ENOMEM;598 599 for (pin = 0; pin < groups[resp[i]].npins; pin++)600 __set_bit(groups[resp[i]].pins[pin], used_pins);601 }602 }603done:604 npins = bitmap_weight(used_pins, zynqmp_desc.npins);605 fgroups = devm_kcalloc(dev, size_add(func->ngroups, npins),606 sizeof(*fgroups), GFP_KERNEL);607 if (!fgroups)608 return -ENOMEM;609 610 for (i = 0; i < func->ngroups; i++) {611 fgroups[i] = devm_kasprintf(dev, GFP_KERNEL, "%s_%d_grp",612 func->name, i);613 if (!fgroups[i])614 return -ENOMEM;615 }616 617 pin = 0;618 for_each_set_bit(pin, used_pins, zynqmp_desc.npins)619 fgroups[i++] = zynqmp_desc.pins[pin].name;620 621 func->groups = fgroups;622 func->ngroups += npins;623 624 return 0;625}626 627static void zynqmp_pinctrl_get_function_name(u32 fid, char *name)628{629 struct zynqmp_pm_query_data qdata = {0};630 u32 payload[PAYLOAD_ARG_CNT];631 632 qdata.qid = PM_QID_PINCTRL_GET_FUNCTION_NAME;633 qdata.arg1 = fid;634 635 /*636 * Name of the function is maximum 16 bytes and cannot637 * accommodate the return value in SMC buffers, hence ignoring638 * the return value for this specific qid.639 */640 zynqmp_pm_query_data(qdata, payload);641 memcpy(name, payload, PINCTRL_GET_FUNC_NAME_RESP_LEN);642}643 644static int zynqmp_pinctrl_get_num_functions(unsigned int *nfuncs)645{646 struct zynqmp_pm_query_data qdata = {0};647 u32 payload[PAYLOAD_ARG_CNT];648 int ret;649 650 qdata.qid = PM_QID_PINCTRL_GET_NUM_FUNCTIONS;651 652 ret = zynqmp_pm_query_data(qdata, payload);653 if (ret)654 return ret;655 656 *nfuncs = payload[1];657 658 return 0;659}660 661static int zynqmp_pinctrl_get_pin_groups(u32 pin, u32 index, u16 *groups)662{663 struct zynqmp_pm_query_data qdata = {0};664 u32 payload[PAYLOAD_ARG_CNT];665 int ret;666 667 qdata.qid = PM_QID_PINCTRL_GET_PIN_GROUPS;668 qdata.arg1 = pin;669 qdata.arg2 = index;670 671 ret = zynqmp_pm_query_data(qdata, payload);672 if (ret)673 return ret;674 675 memcpy(groups, &payload[1], PINCTRL_GET_PIN_GROUPS_RESP_LEN);676 677 return 0;678}679 680static void zynqmp_pinctrl_group_add_pin(struct zynqmp_pctrl_group *group,681 unsigned int pin)682{683 group->pins[group->npins++] = pin;684}685 686/**687 * zynqmp_pinctrl_create_pin_groups() - assign pins to respective groups688 * @dev: Device pointer.689 * @groups: Groups data.690 * @pin: Pin number.691 *692 * Query firmware to get groups available for the given pin.693 * Based on the firmware response(group IDs for the pin), add694 * pin number to the respective group's pin array.695 *696 * Once all pins are queries, each group would have its number697 * of pins and pin numbers data.698 *699 * Return: 0 on success else error code.700 */701static int zynqmp_pinctrl_create_pin_groups(struct device *dev,702 struct zynqmp_pctrl_group *groups,703 unsigned int pin)704{705 u16 resp[NUM_GROUPS_PER_RESP] = {0};706 int ret, i, index = 0;707 708 do {709 ret = zynqmp_pinctrl_get_pin_groups(pin, index, resp);710 if (ret)711 return ret;712 713 for (i = 0; i < NUM_GROUPS_PER_RESP; i++) {714 if (resp[i] == NA_GROUP)715 return ret;716 717 if (resp[i] == RESERVED_GROUP)718 continue;719 720 zynqmp_pinctrl_group_add_pin(&groups[resp[i]], pin);721 }722 index += NUM_GROUPS_PER_RESP;723 } while (index <= MAX_PIN_GROUPS);724 725 return 0;726}727 728/**729 * zynqmp_pinctrl_prepare_group_pins() - prepare each group's pin data730 * @dev: Device pointer.731 * @groups: Groups data.732 * @ngroups: Number of groups.733 *734 * Prepare pin number and number of pins data for each pins.735 *736 * Return: 0 on success else error code.737 */738static int zynqmp_pinctrl_prepare_group_pins(struct device *dev,739 struct zynqmp_pctrl_group *groups,740 unsigned int ngroups)741{742 unsigned int pin;743 int ret;744 745 for (pin = 0; pin < zynqmp_desc.npins; pin++) {746 ret = zynqmp_pinctrl_create_pin_groups(dev, groups, zynqmp_desc.pins[pin].number);747 if (ret)748 return ret;749 }750 751 return 0;752}753 754/**755 * zynqmp_pinctrl_prepare_function_info() - prepare function info756 * @dev: Device pointer.757 * @pctrl: Pin control driver data.758 *759 * Query firmware for functions, groups and pin information and760 * prepare pin control driver data.761 *762 * Query number of functions and number of function groups (number763 * of groups in the given function) to allocate required memory buffers764 * for functions and groups. Once buffers are allocated to store765 * functions and groups data, query and store required information766 * (number of groups and group names for each function, number of767 * pins and pin numbers for each group).768 *769 * Return: 0 on success else error code.770 */771static int zynqmp_pinctrl_prepare_function_info(struct device *dev,772 struct zynqmp_pinctrl *pctrl)773{774 struct zynqmp_pmux_function *funcs;775 struct zynqmp_pctrl_group *groups;776 int ret, i;777 778 ret = zynqmp_pinctrl_get_num_functions(&pctrl->nfuncs);779 if (ret)780 return ret;781 782 funcs = devm_kcalloc(dev, pctrl->nfuncs, sizeof(*funcs), GFP_KERNEL);783 if (!funcs)784 return -ENOMEM;785 786 for (i = 0; i < pctrl->nfuncs; i++) {787 zynqmp_pinctrl_get_function_name(i, funcs[i].name);788 789 ret = zynqmp_pinctrl_get_func_num_groups(i, &funcs[i].ngroups);790 if (ret)791 return ret;792 793 pctrl->ngroups += funcs[i].ngroups;794 }795 796 groups = devm_kcalloc(dev, pctrl->ngroups, sizeof(*groups), GFP_KERNEL);797 if (!groups)798 return -ENOMEM;799 800 ret = zynqmp_pinctrl_prepare_group_pins(dev, groups, pctrl->ngroups);801 if (ret)802 return ret;803 804 for (i = 0; i < pctrl->nfuncs; i++) {805 ret = zynqmp_pinctrl_prepare_func_groups(dev, i, &funcs[i],806 groups);807 if (ret)808 return ret;809 }810 811 pctrl->funcs = funcs;812 pctrl->groups = groups;813 814 return 0;815}816 817static int zynqmp_pinctrl_get_num_pins(unsigned int *npins)818{819 struct zynqmp_pm_query_data qdata = {0};820 u32 payload[PAYLOAD_ARG_CNT];821 int ret;822 823 qdata.qid = PM_QID_PINCTRL_GET_NUM_PINS;824 825 ret = zynqmp_pm_query_data(qdata, payload);826 if (ret)827 return ret;828 829 *npins = payload[1];830 831 return 0;832}833 834/**835 * zynqmp_pinctrl_prepare_pin_desc() - prepare pin description info836 * @dev: Device pointer.837 * @zynqmp_pins: Pin information.838 * @npins: Number of pins.839 *840 * Query number of pins information from firmware and prepare pin841 * description containing pin number and pin name.842 *843 * Return: 0 on success else error code.844 */845static int zynqmp_pinctrl_prepare_pin_desc(struct device *dev,846 const struct pinctrl_pin_desc847 **zynqmp_pins,848 unsigned int *npins)849{850 struct pinctrl_pin_desc *pins, *pin;851 int ret;852 int i;853 854 ret = zynqmp_pinctrl_get_num_pins(npins);855 if (ret)856 return ret;857 858 pins = devm_kcalloc(dev, *npins, sizeof(*pins), GFP_KERNEL);859 if (!pins)860 return -ENOMEM;861 862 for (i = 0; i < *npins; i++) {863 pin = &pins[i];864 pin->number = i;865 pin->name = devm_kasprintf(dev, GFP_KERNEL, "%s%d",866 ZYNQMP_PIN_PREFIX, i);867 if (!pin->name)868 return -ENOMEM;869 }870 871 *zynqmp_pins = pins;872 873 return 0;874}875 876static int zynqmp_pinctrl_probe(struct platform_device *pdev)877{878 struct zynqmp_pinctrl *pctrl;879 int ret;880 881 pctrl = devm_kzalloc(&pdev->dev, sizeof(*pctrl), GFP_KERNEL);882 if (!pctrl)883 return -ENOMEM;884 885 ret = zynqmp_pinctrl_prepare_pin_desc(&pdev->dev,886 &zynqmp_desc.pins,887 &zynqmp_desc.npins);888 if (ret) {889 dev_err(&pdev->dev, "pin desc prepare fail with %d\n", ret);890 return ret;891 }892 893 ret = zynqmp_pinctrl_prepare_function_info(&pdev->dev, pctrl);894 if (ret) {895 dev_err(&pdev->dev, "function info prepare fail with %d\n", ret);896 return ret;897 }898 899 pctrl->pctrl = devm_pinctrl_register(&pdev->dev, &zynqmp_desc, pctrl);900 if (IS_ERR(pctrl->pctrl))901 return PTR_ERR(pctrl->pctrl);902 903 platform_set_drvdata(pdev, pctrl);904 905 return ret;906}907 908static const struct of_device_id zynqmp_pinctrl_of_match[] = {909 { .compatible = "xlnx,zynqmp-pinctrl" },910 { }911};912MODULE_DEVICE_TABLE(of, zynqmp_pinctrl_of_match);913 914static struct platform_driver zynqmp_pinctrl_driver = {915 .driver = {916 .name = "zynqmp-pinctrl",917 .of_match_table = zynqmp_pinctrl_of_match,918 },919 .probe = zynqmp_pinctrl_probe,920};921module_platform_driver(zynqmp_pinctrl_driver);922 923MODULE_AUTHOR("Sai Krishna Potthuri <lakshmi.sai.krishna.potthuri@xilinx.com>");924MODULE_DESCRIPTION("ZynqMP Pin Controller Driver");925MODULE_LICENSE("GPL v2");926