Received: by 2002:ab2:784b:0:b0:1fd:adc2:8405 with SMTP id m11csp491660lqp; Mon, 10 Jun 2024 09:59:38 -0700 (PDT) X-Forwarded-Encrypted: i=3; AJvYcCU6dDq+qTa/mIpBqm726A/jca/9zi5+q6KVEzVQJldYGlllsCEnq2561CzvMxAXHk0eD4Xz7zsstS+/c4X5tqr+/4GK5FW0mFgw3uwgBg== X-Google-Smtp-Source: AGHT+IG0kfH940lim/yIERS/4CSWHAIIIBATLJrFAiW16kG0l6Bgprf2spe10PGot6FL14noT92J X-Received: by 2002:a50:8e45:0:b0:57c:546b:d303 with SMTP id 4fb4d7f45d1cf-57c546bd3a3mr6327229a12.25.1718038777975; Mon, 10 Jun 2024 09:59:37 -0700 (PDT) ARC-Seal: i=2; a=rsa-sha256; t=1718038777; cv=pass; d=google.com; s=arc-20160816; b=wTmI1eAy0nfJnBVrGEVpifLMNtyrAojbAsWvoc8Oo6pOvf1TK2Y2xHNt6nrxrXBuTs agNh/qhCSLXoPfyOZQKHo3+9raSkN/bxE3ueIBRqP2Rs4a7uRQlZwLiIWDrIo46an53w E4gzHgEyeYlISbKTdRsY9ZOI6yl8Xzv55QtRtWFB3xPJj262Xmnc6DEKNg7mH3HRynRd fZRRoMcbNGK9MGeSkhMQmRLX8JoRQ1dkJ4YRAN2Py5MLmwiK4C3edLJ5PLdESQqo4SeW 6x6AZDhM0WhSsxeM8TtqibLDhgjEqu8+9nwQcjav5cSbJNZJshvfWRclaqoLIreMfifx dEXA== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=content-transfer-encoding:in-reply-to:from:content-language :references:cc:to:subject:mime-version:list-unsubscribe :list-subscribe:list-id:precedence:date:message-id:dkim-signature; bh=fdhovgqT7zjoOedUP7hNDAxwuKT33nzYsDI2SddjkRk=; fh=mjtJ6CSuVN1iEKLM6jgn+x1wddGcotlHx3WDNcUM5cc=; b=u5zZ4C+oPnUy8UomMXwdG0Lbi5NPSPhFgFd7Ho7xZZi7KfzHuJmx0ks25E3tG3N0KD dzEHfujTRGEgOj0iWCJZnmXceR7mRa/K8RU5wIIh47ERAQDKSqkjZcVNEoKRfri81OE/ zSOtekRdNLzzi2lY1PSZPXAUWmSMWud7Wzf4osK4JwpwNH6LrDIEk7xVbRRSb5mYnx5E x9wkhOn+JQ+ObyfcgOGr+6N0Yslf50TwRg+VTho9X0EBX0AgoCxo5g5hhyq/5XjaHojj Y7P0nMsLwPIwIIndbrbB7LgeOmg4dZhynktwOcRiO4v2/6vruPTBN0wYTIlAKg497qPw qnFA==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@linux.dev header.s=key1 header.b=coekRUGy; arc=pass (i=1 spf=pass spfdomain=linux.dev dkim=pass dkdomain=linux.dev dmarc=pass fromdomain=linux.dev); spf=pass (google.com: domain of linux-kernel+bounces-208631-linux.lists.archive=gmail.com@vger.kernel.org designates 147.75.80.249 as permitted sender) smtp.mailfrom="linux-kernel+bounces-208631-linux.lists.archive=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linux.dev Return-Path: Received: from am.mirrors.kernel.org (am.mirrors.kernel.org. [147.75.80.249]) by mx.google.com with ESMTPS id 4fb4d7f45d1cf-57c82b28827si1010330a12.186.2024.06.10.09.59.37 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 10 Jun 2024 09:59:37 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel+bounces-208631-linux.lists.archive=gmail.com@vger.kernel.org designates 147.75.80.249 as permitted sender) client-ip=147.75.80.249; Authentication-Results: mx.google.com; dkim=pass header.i=@linux.dev header.s=key1 header.b=coekRUGy; arc=pass (i=1 spf=pass spfdomain=linux.dev dkim=pass dkdomain=linux.dev dmarc=pass fromdomain=linux.dev); spf=pass (google.com: domain of linux-kernel+bounces-208631-linux.lists.archive=gmail.com@vger.kernel.org designates 147.75.80.249 as permitted sender) smtp.mailfrom="linux-kernel+bounces-208631-linux.lists.archive=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linux.dev Received: from smtp.subspace.kernel.org (wormhole.subspace.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by am.mirrors.kernel.org (Postfix) with ESMTPS id 78ADB1F217D6 for ; Mon, 10 Jun 2024 16:59:31 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 6BBEA147C6E; Mon, 10 Jun 2024 16:59:16 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b="coekRUGy" Received: from out-173.mta0.migadu.com (out-173.mta0.migadu.com [91.218.175.173]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 6C2F11465A1 for ; Mon, 10 Jun 2024 16:59:12 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=91.218.175.173 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1718038755; cv=none; b=mTqJPFeiFiVJyRXl7tYHRotwjUW3aAjYoT4JIgAkPh/7ytn6KGeZCMochPoet19zBErYBnvyrykxcGzWWN1B+Er2c4veuVMbNg7/Z1AGhL8Cgk2MkFPrTzDxrfgbEm+Xnz9PWbihXdrs4KcoOA25Z59vBs1/SKXW3oGDivS3PJQ= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1718038755; c=relaxed/simple; bh=l90dOxP0UjRDbMI8RAA7HmW05i5eREmoM0QaokN/SLg=; h=Message-ID:Date:MIME-Version:Subject:To:Cc:References:From: In-Reply-To:Content-Type; b=cYB5xgNnkqnKkiMEX38u8s6zrXP0S/4UeqgGCU8XU3GONlnOXV+U+OLvsJt/73MDD/P3PvXW+tYuZ/bVYzjm8lJcuZJdGaHJUloBhwZTBAX/xSzMCDbiWwhSukEcj0nMXLlzMQUjUbCxgz7Lqo+vfVQD/ZzD6OeX1vg/CeER+zc= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev; spf=pass smtp.mailfrom=linux.dev; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b=coekRUGy; arc=none smtp.client-ip=91.218.175.173 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.dev X-Envelope-To: sai.krishna.potthuri@amd.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.dev; s=key1; t=1718038750; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=fdhovgqT7zjoOedUP7hNDAxwuKT33nzYsDI2SddjkRk=; b=coekRUGyb9Y7ezSuJt1zIu+Ti/tusFcIA1RITV+M48P46CbeYbTz5p1uGp3/KiYPQ5lcuR sj7m+gJXWjWLQ9fR0VYHkAczIQRwGkyOJE/SYFUgD1zqngwV6wm/Nl1Q2xIzR+NOkK/c/3 NUBKbBMhw6wgpEtnuS3nKncuNlWmwYc= X-Envelope-To: linus.walleij@linaro.org X-Envelope-To: michal.simek@amd.com X-Envelope-To: linux-gpio@vger.kernel.org X-Envelope-To: linux-kernel@vger.kernel.org X-Envelope-To: andy.shevchenko@gmail.com X-Envelope-To: linux-arm-kernel@lists.infradead.org X-Envelope-To: srinivas.goud@amd.com Message-ID: Date: Mon, 10 Jun 2024 12:59:06 -0400 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Subject: Re: [PATCH v2 2/2] pinctrl: zynqmp: Support muxing individual pins To: "Potthuri, Sai Krishna" Cc: Linus Walleij , "Simek, Michal" , "linux-gpio@vger.kernel.org" , "linux-kernel@vger.kernel.org" , Andy Shevchenko , "linux-arm-kernel@lists.infradead.org" , "Goud, Srinivas" References: <20240520150424.2531458-1-sean.anderson@linux.dev> <20240520150424.2531458-3-sean.anderson@linux.dev> Content-Language: en-US X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. From: Sean Anderson In-Reply-To: Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 7bit X-Migadu-Flow: FLOW_OUT Hi Sai Krishna, On 6/10/24 08:16, Potthuri, Sai Krishna wrote: > Hi Sean, > >> -----Original Message----- >> From: Sean Anderson >> Sent: Monday, May 20, 2024 8:34 PM >> To: Linus Walleij ; Simek, Michal >> ; linux-gpio@vger.kernel.org >> Cc: Potthuri, Sai Krishna ; linux- >> kernel@vger.kernel.org; Andy Shevchenko ; >> linux-arm-kernel@lists.infradead.org; Sean Anderson >> >> Subject: [PATCH v2 2/2] pinctrl: zynqmp: Support muxing individual pins >> >> While muxing groups of pins at once can be convenient for large interfaces, >> it can also be rigid. This is because the group is set to all pins which support >> a particular function, even though not all pins may be used. For example, >> the sdhci0 function may be used with a 8-bit eMMC, 4-bit SD card, or even a >> 1-bit SD card. In these cases, the extra pins may be repurposed for other >> uses, but this is not currently allowed. >> >> There is not too much point in pin "groups" when there are not actual pin >> groups at the hardware level. The pins can all be muxed individually, so >> there's no point in adding artificial groups on top. >> Just mux the pins like the hardware allows. >> >> To this effect, add a new group for each pin which can be muxed. These >> groups are part of each function the pin can be muxed to. We treat group >> selectors beyond the number of groups as "pin" groups. To set this up, we >> initialize groups before functions, and then create a bitmap of used pins for >> each function. These used pins are appended to the function's list of >> groups. >> >> Signed-off-by: Sean Anderson >> --- >> >> Changes in v2: >> - Use __set_bit instead of set_bit >> - Use size_add when calculating the number of kcalloc members >> - Expand commit message with some more motivation >> >> drivers/pinctrl/pinctrl-zynqmp.c | 61 ++++++++++++++++++++++---------- >> 1 file changed, 43 insertions(+), 18 deletions(-) >> >> diff --git a/drivers/pinctrl/pinctrl-zynqmp.c b/drivers/pinctrl/pinctrl- >> zynqmp.c >> index 5c46b7d7ebcb..7cc1e43fb07c 100644 >> --- a/drivers/pinctrl/pinctrl-zynqmp.c >> +++ b/drivers/pinctrl/pinctrl-zynqmp.c >> @@ -10,6 +10,7 @@ >> >> #include >> >> +#include >> #include >> #include >> #include >> @@ -97,7 +98,7 @@ static int zynqmp_pctrl_get_groups_count(struct >> pinctrl_dev *pctldev) { >> struct zynqmp_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); >> >> - return pctrl->ngroups; >> + return pctrl->ngroups + zynqmp_desc.npins; >> } >> >> static const char *zynqmp_pctrl_get_group_name(struct pinctrl_dev >> *pctldev, @@ -105,7 +106,10 @@ static const char >> *zynqmp_pctrl_get_group_name(struct pinctrl_dev *pctldev, { >> struct zynqmp_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); >> >> - return pctrl->groups[selector].name; >> + if (selector < pctrl->ngroups) >> + return pctrl->groups[selector].name; >> + >> + return zynqmp_desc.pins[selector - pctrl->ngroups].name; >> } >> >> static int zynqmp_pctrl_get_group_pins(struct pinctrl_dev *pctldev, @@ - >> 115,8 +119,13 @@ static int zynqmp_pctrl_get_group_pins(struct >> pinctrl_dev *pctldev, { >> struct zynqmp_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); >> >> - *pins = pctrl->groups[selector].pins; >> - *npins = pctrl->groups[selector].npins; >> + if (selector < pctrl->ngroups) { >> + *pins = pctrl->groups[selector].pins; >> + *npins = pctrl->groups[selector].npins; >> + } else { >> + *pins = &zynqmp_desc.pins[selector - pctrl- >> >ngroups].number; >> + *npins = 1; >> + } >> >> return 0; >> } >> @@ -560,10 +569,12 @@ static int >> zynqmp_pinctrl_prepare_func_groups(struct device *dev, u32 fid, { >> u16 resp[NUM_GROUPS_PER_RESP] = {0}; >> const char **fgroups; >> - int ret, index, i; >> + int ret, index, i, pin; >> + unsigned int npins; >> + unsigned long *used_pins __free(bitmap) = >> + bitmap_zalloc(zynqmp_desc.npins, GFP_KERNEL); >> >> - fgroups = devm_kcalloc(dev, func->ngroups, sizeof(*fgroups), >> GFP_KERNEL); >> - if (!fgroups) >> + if (!used_pins) >> return -ENOMEM; >> >> for (index = 0; index < func->ngroups; index += >> NUM_GROUPS_PER_RESP) { @@ -578,23 +589,37 @@ static int >> zynqmp_pinctrl_prepare_func_groups(struct device *dev, u32 fid, >> if (resp[i] == RESERVED_GROUP) >> continue; >> >> - fgroups[index + i] = devm_kasprintf(dev, >> GFP_KERNEL, >> - "%s_%d_grp", >> - func->name, >> - index + i); >> - if (!fgroups[index + i]) >> - return -ENOMEM; >> - >> groups[resp[i]].name = devm_kasprintf(dev, >> GFP_KERNEL, >> "%s_%d_grp", >> func->name, >> index + i); >> if (!groups[resp[i]].name) >> return -ENOMEM; >> + >> + for (pin = 0; pin < groups[resp[i]].npins; pin++) >> + __set_bit(groups[resp[i]].pins[pin], >> used_pins); >> } >> } >> done: >> + npins = bitmap_weight(used_pins, zynqmp_desc.npins); >> + fgroups = devm_kcalloc(dev, size_add(func->ngroups, npins), >> + sizeof(*fgroups), GFP_KERNEL); >> + if (!fgroups) >> + return -ENOMEM; >> + >> + for (i = 0; i < func->ngroups; i++) { >> + fgroups[i] = devm_kasprintf(dev, GFP_KERNEL, "%s_%d_grp", >> + func->name, i); >> + if (!fgroups[i]) >> + return -ENOMEM; >> + } >> + >> + pin = 0; >> + for_each_set_bit(pin, used_pins, zynqmp_desc.npins) >> + fgroups[i++] = zynqmp_desc.pins[pin].name; >> + >> func->groups = fgroups; >> + func->ngroups += npins; >> >> return 0; >> } >> @@ -772,6 +797,10 @@ static int >> zynqmp_pinctrl_prepare_function_info(struct device *dev, >> if (!groups) >> return -ENOMEM; >> >> + ret = zynqmp_pinctrl_prepare_group_pins(dev, groups, pctrl- >> >ngroups); >> + if (ret) >> + return ret; >> + >> for (i = 0; i < pctrl->nfuncs; i++) { >> ret = zynqmp_pinctrl_prepare_func_groups(dev, i, &funcs[i], >> groups); >> @@ -779,10 +808,6 @@ static int >> zynqmp_pinctrl_prepare_function_info(struct device *dev, >> return ret; >> } >> >> - ret = zynqmp_pinctrl_prepare_group_pins(dev, groups, pctrl- >> >ngroups); >> - if (ret) >> - return ret; >> - >> pctrl->funcs = funcs; >> pctrl->groups = groups; >> > While testing this patch, observed that some more changes required in the > other functions like set_mux, pin_config_group_set. Pasted the diff below. Thanks for catching this. I will incorporate these changes into v3. > diff --git a/drivers/pinctrl/pinctrl-zynqmp.c b/drivers/pinctrl/pinctrl-zynqmp.c > index 636e56f7cd92..c82074819be3 100644 > --- a/drivers/pinctrl/pinctrl-zynqmp.c > +++ b/drivers/pinctrl/pinctrl-zynqmp.c > @@ -206,12 +206,18 @@ static int zynqmp_pinmux_set_mux(struct pinctrl_dev *pctldev, > unsigned int function, > unsigned int group) > { > - struct zynqmp_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); > - const struct zynqmp_pctrl_group *pgrp = &pctrl->groups[group]; > + const unsigned *pins; > + unsigned npins; > int ret, i; > > - for (i = 0; i < pgrp->npins; i++) { > - unsigned int pin = pgrp->pins[i]; > + ret = zynqmp_pctrl_get_group_pins(pctldev, group, &pins, &npins); > + if (ret) { This function cannot fail, so we don't need to check the return. > + dev_err(pctldev->dev, "Get group pins failed for group %u\n", group); > + return ret; > + } > + > + for (i = 0; i < npins; i++) { > + unsigned int pin = pins[i]; > > ret = zynqmp_pm_pinctrl_set_function(pin, function); > if (ret) { > @@ -476,13 +482,18 @@ static int zynqmp_pinconf_group_set(struct pinctrl_dev *pctldev, > unsigned long *configs, > unsigned int num_configs) > { > - int i, ret; > - struct zynqmp_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); > - const struct zynqmp_pctrl_group *pgrp = &pctrl->groups[selector]; > - > - for (i = 0; i < pgrp->npins; i++) { > - ret = zynqmp_pinconf_cfg_set(pctldev, pgrp->pins[i], configs, > - num_configs); > + const unsigned *pins; > + unsigned npins; > + int i, ret; > + > + ret = zynqmp_pctrl_get_group_pins(pctldev, selector, &pins, &npins); > + if (ret) { ditto > + dev_err(pctldev->dev, "Get group pins failed for group %u\n", selector); > + return ret; > + } > + > + for (i = 0; i < npins; i++) { > + ret = zynqmp_pinconf_cfg_set(pctldev, pins[i], configs, num_configs); > if (ret) > return ret; > } > > Regards > Sai Krishna --Sean