Hi Andy Shevchenko, Thanks for the review. > -----Original Message----- > From: Andy Shevchenko <andy.shevchenko@xxxxxxxxx> > Sent: Friday, April 23, 2021 9:24 PM > To: Sai Krishna Potthuri <lakshmis@xxxxxxxxxx> > Cc: Linus Walleij <linus.walleij@xxxxxxxxxx>; Rob Herring > <robh+dt@xxxxxxxxxx>; Michal Simek <michals@xxxxxxxxxx>; Greg Kroah- > Hartman <gregkh@xxxxxxxxxxxxxxxxxxx>; linux-arm Mailing List <linux-arm- > kernel@xxxxxxxxxxxxxxxxxxx>; Linux Kernel Mailing List <linux- > kernel@xxxxxxxxxxxxxxx>; devicetree <devicetree@xxxxxxxxxxxxxxx>; open > list:GPIO SUBSYSTEM <linux-gpio@xxxxxxxxxxxxxxx>; git <git@xxxxxxxxxx>; > saikrishna12468@xxxxxxxxx > Subject: Re: [PATCH v6 3/3] pinctrl: Add Xilinx ZynqMP pinctrl driver support > > On Thu, Apr 22, 2021 at 11:31 AM Sai Krishna Potthuri > <lakshmi.sai.krishna.potthuri@xxxxxxxxxx> wrote: > > > > Adding pinctrl driver for Xilinx ZynqMP platform. > > This driver queries pin information from firmware and registers pin > > control accordingly. > > > > Signed-off-by: Sai Krishna Potthuri > > <lakshmi.sai.krishna.potthuri@xxxxxxxxxx> > > You may reduce the number of LOCs by joining some lines. See below. > > ... > > > +config PINCTRL_ZYNQMP > > + tristate "Pinctrl driver for Xilinx ZynqMP" > > + depends on ZYNQMP_FIRMWARE > > + select PINMUX > > + select GENERIC_PINCONF > > + default ZYNQMP_FIRMWARE > > + help > > + This selects the pinctrl driver for Xilinx ZynqMP platform. > > + This driver will query the pin information from the firmware > > + and allow configuring the pins. > > + Configuration can include the mux function to select on those > > + pin(s)/group(s), and various pin configuration parameters > > + such as pull-up, slew rate, etc. > > Missed module name. Is this (module name) a configuration option in Kconfig? > > ... > > > +/* > > + * ZynqMP pin controller > > + * > > + * Copyright (C) 2020 Xilinx, Inc. > > 2021? Couple of versions for this patch series sent in 2020, hence maintaining the same. Is it like we maintain the year when this patch series is applied, which is 2021? > > > + * > > + * Sai Krishna Potthuri <lakshmi.sai.krishna.potthuri@xxxxxxxxxx> > > + * Rajan Vaja <rajan.vaja@xxxxxxxxxx> */ > > ... > > > +#include <linux/init.h> > > +#include <linux/module.h> > > +#include <linux/of_address.h> > > +#include <linux/platform_device.h> > > +#include <linux/firmware/xlnx-zynqmp.h> > > ... > > > +static int zynqmp_pinconf_cfg_get(struct pinctrl_dev *pctldev, > > + unsigned int pin, > > + unsigned long *config) > > +{ > > + unsigned int arg, param = pinconf_to_config_param(*config); > > + int ret; > > > + if (pin >= zynqmp_desc.npins) > > + return -EOPNOTSUPP; > > Is it possible? This is a safe check. Pin information will get from dt files/Xilinx firmware (query pin information for a group)/user application and there are chances of getting wrong pin. > > > + switch (param) { > > + case PIN_CONFIG_SLEW_RATE: > > + param = PM_PINCTRL_CONFIG_SLEW_RATE; > > + ret = zynqmp_pm_pinctrl_get_config(pin, param, &arg); > > + break; > > + case PIN_CONFIG_BIAS_PULL_UP: > > + param = PM_PINCTRL_CONFIG_PULL_CTRL; > > > + ret = zynqmp_pm_pinctrl_get_config(pin, param, &arg); > > + if (arg != PM_PINCTRL_BIAS_PULL_UP) > > + return -EINVAL; > > Error code being shadowed. Instead check it here properly. Are you mentioning the case where ret is also a non-zero? If yes, then I will update this check to if (!ret && arg != PM_PINCTRL_BIAS_PULL_UP) return -EINVAL; ret non-zero case, we are handling at the end of switch case. > > > + arg = 1; > > + break; > > + case PIN_CONFIG_BIAS_PULL_DOWN: > > + param = PM_PINCTRL_CONFIG_PULL_CTRL; > > + ret = zynqmp_pm_pinctrl_get_config(pin, param, &arg); > > + if (arg != PM_PINCTRL_BIAS_PULL_DOWN) > > + return -EINVAL; > > Ditto. Same as above. > > > + arg = 1; > > + break; > > + case PIN_CONFIG_BIAS_DISABLE: > > + param = PM_PINCTRL_CONFIG_BIAS_STATUS; > > + ret = zynqmp_pm_pinctrl_get_config(pin, param, &arg); > > + if (arg != PM_PINCTRL_BIAS_DISABLE) > > + return -EINVAL; > > Ditto. Same as above. > > > + arg = 1; > > + break; > > + case PIN_CONFIG_POWER_SOURCE: > > + param = PM_PINCTRL_CONFIG_VOLTAGE_STATUS; > > + ret = zynqmp_pm_pinctrl_get_config(pin, param, &arg); > > + break; > > + case PIN_CONFIG_INPUT_SCHMITT_ENABLE: > > + param = PM_PINCTRL_CONFIG_SCHMITT_CMOS; > > + ret = zynqmp_pm_pinctrl_get_config(pin, param, &arg); > > + break; > > + case PIN_CONFIG_DRIVE_STRENGTH: > > + param = PM_PINCTRL_CONFIG_DRIVE_STRENGTH; > > + ret = zynqmp_pm_pinctrl_get_config(pin, param, &arg); > > + switch (arg) { > > + case PM_PINCTRL_DRIVE_STRENGTH_2MA: > > + arg = DRIVE_STRENGTH_2MA; > > + break; > > + case PM_PINCTRL_DRIVE_STRENGTH_4MA: > > + arg = DRIVE_STRENGTH_4MA; > > + break; > > + case PM_PINCTRL_DRIVE_STRENGTH_8MA: > > + arg = DRIVE_STRENGTH_8MA; > > + break; > > + case PM_PINCTRL_DRIVE_STRENGTH_12MA: > > + arg = DRIVE_STRENGTH_12MA; > > + break; > > + default: > > + /* Invalid drive strength */ > > + dev_warn(pctldev->dev, > > + "Invalid drive strength for pin %d\n", > > + pin); > > + return -EINVAL; > > + } > > + break; > > + default: > > + ret = -EOPNOTSUPP; > > + break; > > + } > > + > > + if (ret) > > + return ret; > > + > > + param = pinconf_to_config_param(*config); > > + *config = pinconf_to_config_packed(param, arg); > > + > > + return 0; > > +} > > ... > > > + ret = -EOPNOTSUPP; > > Isn't it ENOTSUP for all cases here? Giving 'Operation Not Supported (EOPNOTSUPP)' error, when driver gets a request for unsupported pin or configuration. Can you please elaborate your question if I didn't answer properly. > > ... > > > + ret = zynqmp_pm_query_data(qdata, payload); > > + if (ret) > > + return ret; > > + > > + *ngroups = payload[1]; > > + > > > + return ret; > > return 0; I will fix. > > ... > > > + * Query firmware to get group IDs for each function. Firmware returns > > + * group IDs. Based on group index for the function, group names in > > on the group > > > + * the function are stored. For example, the first group in "eth0" function > > + * is named as "eth0_0" and second group as "eth0_1" and so on. > > and the second > > > + * > > + * Based on the group ID received from the firmware, function stores > name of > > + * the group for that group ID. For example, if "eth0" first group ID > > + * is x, groups[x] name will be stored as "eth0_0". > > + * > > + * Once done for each function, each function would have its group names > > + * and each groups would also have their names. > > each group I will fix all the above. > > ... > > > +done: > > + func->groups = fgroups; > > + > > + return ret; > > return 0; ? > > ... > > > + *nfuncs = payload[1]; > > + > > + return ret; > > Ditto. > > ... > > > + ret = zynqmp_pm_query_data(qdata, payload); > > + if (ret) > > + return ret; > > + > > + memcpy(groups, &payload[1], > PINCTRL_GET_PIN_GROUPS_RESP_LEN); > > + > > + return ret; > > Ditto. > > ... > > > + * Query firmware to get groups available for the given pin. > > + * Based on the firmware response(group IDs for the pin), add > > + * pin number to the respective group's pin array. > > + * > > + * Once all pins are queries, each groups would have its number > > each group > > > + * of pins and pin numbers data. > > ... > > > + return ret; > > return 0; > > ... > > > + * Query number of functions and number of function groups (number > > + * of groups in given function) to allocate required memory buffers > > in the given > > > + * for functions and groups. Once buffers are allocated to store > > + * functions and groups data, query and store required information > > + * (number of groups and group names for each function, number of > > + * pins and pin numbers for each group). > > ... > > > + pctrl->funcs = funcs; > > + pctrl->groups = groups; > > + > > + return ret; > > return 0; > > ... > > > + *npins = payload[1]; > > + > > + return ret; > > Ditto. I will fix all the above similar comments. > > ... > > > + dev_err(&pdev->dev, "pin desc prepare fail with %d\n", > > + ret); > > One line. > > ... > > > + dev_err(&pdev->dev, "function info prepare fail with %d\n", > > + ret); > > Ditto. I will fix all. > > ... > > > + pctrl->pctrl = pinctrl_register(&zynqmp_desc, &pdev->dev, pctrl); > > devm_pinctrl_register() I will update. > > > + if (IS_ERR(pctrl->pctrl)) > > + return PTR_ERR(pctrl->pctrl); > > ... > > > +}; > > > + > > Extra blank line. > > > +MODULE_DEVICE_TABLE(of, zynqmp_pinctrl_of_match); > > ... > > > +}; > > > + > > Ditto. I see some drivers are maintaining the extra line in above two cases. We shouldn't maintain extra line after struct declaration? Regards Sai Krishna > > > +module_platform_driver(zynqmp_pinctrl_driver); > > -- > With Best Regards, > Andy Shevchenko