Received: by 2002:ab2:6816:0:b0:1f9:5764:f03e with SMTP id t22csp2511826lqo; Mon, 20 May 2024 08:05:03 -0700 (PDT) X-Forwarded-Encrypted: i=3; AJvYcCV4cXwky/d4aDgf977X8HLIoYrctxHf/iALpLgZR2Y+YIZrOtGHDiCa6X0/janLFMFsOdd8pnZkUHQ9zsMrjPgQ2y2M3DUkq1SmaiRNgA== X-Google-Smtp-Source: AGHT+IHsDJ6L4rOz4SRi+4nuNurdkHw0Wsihp86oZ0PUJcjsr9BQfFrYkSr+nbpt5zjd+5LDkT77 X-Received: by 2002:a05:6a21:601:b0:1af:cbd3:ab48 with SMTP id adf61e73a8af0-1afde0af528mr24934906637.3.1716217503146; Mon, 20 May 2024 08:05:03 -0700 (PDT) ARC-Seal: i=2; a=rsa-sha256; t=1716217503; cv=pass; d=google.com; s=arc-20160816; b=qc7O5nXaROx5udwAK/y/6UZgX1ojARECnbLjxmbakBD0FRl5xqR3g9oGykOF1iGBLg D+f3ny3oDeMGkw4+ZeeBpgvYZI5tYHjseb9l912Y1QQO/ujTjdZbrVSQajn9S3ICDLpB 412KoerVUg0AjgaOjkwEBdNrvyMPEDei5nVPDw2dUsSk+Bm+ccS8nqEusVDyhADQG790 ++v3vOC1MxAok8fKh4CoTKMLGqakOoG9fnQZ8E8dNssKqwAB/vTXcKj8V9mUtJNDD7k6 Irhv465xwXIuxOFsq2HLW5DOt+k6oBq1+MkQNMovB5o1Tk1sZlz0vPzk+VRRJkysXdv2 iS9g== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=content-transfer-encoding:mime-version:list-unsubscribe :list-subscribe:list-id:precedence:references:in-reply-to:message-id :date:subject:cc:to:from:dkim-signature; bh=M5zviEf5A12KnXDSQllyVorIBh12Tl6r4o0V0p+XKTg=; fh=tOGL3DMYymSxH3vpPAcJimxPOMoeUmt+FijAejH+o3I=; b=HIrAJbj7/piEBr4odlBudRNf/CcCbotHoMrTQGXQEzTchoEwhpO6XfMRSTDZ9h4umu mxCfEwPXdmjMHZ1xKNe/ZGxFV9kwl6DPCqpsTpoHdzFGJaK0FgZR7IYNsWjUBQo09AuA hBjFiFPyp3D77+7p0Q8Qu808XG8hsQjWaWlNuRQ7bh+Z9sEy51JOb7fR/68/+6XC7z3O eNuy+TizOh63r/Ol/fpsQ4dqjMZhcExCZFhZtb2k0PhLud97dfARletcOWIxKv4QHCBd TFkeM1LjylKcN8D5eVr7zl+aYbyIN5qOoYvLBeCKjofmt/EmZ/U4rcX3Cz+S/0CKJgi7 QbXg==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@linux.dev header.s=key1 header.b=xduTDc1x; 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-183879-linux.lists.archive=gmail.com@vger.kernel.org designates 139.178.88.99 as permitted sender) smtp.mailfrom="linux-kernel+bounces-183879-linux.lists.archive=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linux.dev Return-Path: Received: from sv.mirrors.kernel.org (sv.mirrors.kernel.org. [139.178.88.99]) by mx.google.com with ESMTPS id d2e1a72fcca58-6f4d2aee1f6si60571b3a.158.2024.05.20.08.05.02 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 20 May 2024 08:05:03 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel+bounces-183879-linux.lists.archive=gmail.com@vger.kernel.org designates 139.178.88.99 as permitted sender) client-ip=139.178.88.99; Authentication-Results: mx.google.com; dkim=pass header.i=@linux.dev header.s=key1 header.b=xduTDc1x; 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-183879-linux.lists.archive=gmail.com@vger.kernel.org designates 139.178.88.99 as permitted sender) smtp.mailfrom="linux-kernel+bounces-183879-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 sv.mirrors.kernel.org (Postfix) with ESMTPS id C0891281276 for ; Mon, 20 May 2024 15:05:02 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id BD955137752; Mon, 20 May 2024 15:04:38 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b="xduTDc1x" Received: from out-172.mta0.migadu.com (out-172.mta0.migadu.com [91.218.175.172]) (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 398E228E7 for ; Mon, 20 May 2024 15:04:35 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=91.218.175.172 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1716217477; cv=none; b=pImyk+Wncgqtd7dBF5rLOmpYyeyFqdPvdcAdj/DjkA/iH1KxiKSw2QNqrLUMnqM9tTZIWuf/R6mYavW4U8/x3pINEv2HOlD/gRmn4TDxQ1q2SpTPd7FAzSlhq1sQwoOH/Yry12B9Z2/vVwQc6C2HjAVBP+kA2EG/TjaJCFzKLYM= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1716217477; c=relaxed/simple; bh=rZJaNLBVEf+aK2rDOIXSWaoAcXGZCiPjotRHJZW2cj0=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=uTjCo6bTaK+n9fPk6CZcJdx4GJFbRiqgUVJ4q878I97dF9oCCp6gI0/fGPwwUeH5wklSuUQTFerE9aHlFj6tuuNcZOyVop+WZMeP1SqKPSChqwhhBqbDp5ymXLHZRojKmc6IzFN0tNsUUwgAz/it2/3v+luxfUQvwOlusWPn1jU= 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=xduTDc1x; arc=none smtp.client-ip=91.218.175.172 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: linus.walleij@linaro.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.dev; s=key1; t=1716217474; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=M5zviEf5A12KnXDSQllyVorIBh12Tl6r4o0V0p+XKTg=; b=xduTDc1xFMCmLLPJTZC6FSmby3/D/cKU1Fr3zpI1koYGiES/CQsult1CS8u6WgO6odOyqX g0i5amQ0sxSbUeqDZNLCzwtYPLeydD6MuUp2FF0Un7jMKYBThmk/D/6MEKrs6X56HCG/W+ 3Q4ULtmQEt3q8JPlcqVftRTcTJJrnoU= X-Envelope-To: michal.simek@amd.com X-Envelope-To: linux-gpio@vger.kernel.org X-Envelope-To: sai.krishna.potthuri@amd.com 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: sean.anderson@linux.dev X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. From: Sean Anderson To: Linus Walleij , Michal Simek , linux-gpio@vger.kernel.org Cc: Krishna Potthuri , 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 Date: Mon, 20 May 2024 11:04:24 -0400 Message-Id: <20240520150424.2531458-3-sean.anderson@linux.dev> In-Reply-To: <20240520150424.2531458-1-sean.anderson@linux.dev> References: <20240520150424.2531458-1-sean.anderson@linux.dev> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Migadu-Flow: FLOW_OUT 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; -- 2.35.1.1320.gc452695387.dirty