From nobody Tue Apr 7 04:36:43 2026 Received: from metis.whiteo.stw.pengutronix.de (metis.whiteo.stw.pengutronix.de [185.203.201.7]) (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 7ECCC39D6DF for ; Mon, 16 Mar 2026 14:05:36 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.203.201.7 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773669939; cv=none; b=bVbHG9DDw+20SypO1GTiXD12a0vZtidx7gR+wH6XtMWCb4SmZkT5plxONQGJphErEWSWNvjTKjF999a73mZX0knMn0utfvScN/kQm1rwFYObVED68VSL5VUPNuui+TksnkBovVJlrlpv29BrQc1PiMYI48CQxi2hEXRYID37ymE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773669939; c=relaxed/simple; bh=t1m5r7CayI6J+TJGV41Vm5A0TW9XZzJtu68dbuJEe/0=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=MKXywa4aptEMomaXhn1uDaeNCLDVPXL5RdxYp7Hayb++LNcAvUxKDVoWhNYmgN6eHRlgnRDeES3/0Wh0wgd+nW7icEBSsW4ZJAzENW5TetyXs4nd6JlwERmFPeYOXYoBk84lmREKPd4cn+YhvG0PppwAkxWIxXnnZiVe6fWsG50= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=pengutronix.de; spf=pass smtp.mailfrom=pengutronix.de; arc=none smtp.client-ip=185.203.201.7 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=pengutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=pengutronix.de Received: from drehscheibe.grey.stw.pengutronix.de ([2a0a:edc0:0:c01:1d::a2]) by metis.whiteo.stw.pengutronix.de with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1w28ZI-0002G5-E8; Mon, 16 Mar 2026 15:05:16 +0100 Received: from dude04.red.stw.pengutronix.de ([2a0a:edc0:0:1101:1d::ac] helo=dude04) by drehscheibe.grey.stw.pengutronix.de with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1w28ZH-000a8M-2b; Mon, 16 Mar 2026 15:05:15 +0100 Received: from ore by dude04 with local (Exim 4.98.2) (envelope-from ) id 1w28ZH-00000005two-30DU; Mon, 16 Mar 2026 15:05:15 +0100 From: Oleksij Rempel To: Guenter Roeck , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Lee Jones , Peter Rosin , Linus Walleij Cc: Oleksij Rempel , kernel@pengutronix.de, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, linux-hwmon@vger.kernel.org, linux-gpio@vger.kernel.org, David Jander Subject: [PATCH v5 3/7] pinctrl: core: Make pin group callbacks optional Date: Mon, 16 Mar 2026 15:05:08 +0100 Message-ID: <20260316140514.1406588-4-o.rempel@pengutronix.de> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20260316140514.1406588-1-o.rempel@pengutronix.de> References: <20260316140514.1406588-1-o.rempel@pengutronix.de> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-SA-Exim-Connect-IP: 2a0a:edc0:0:c01:1d::a2 X-SA-Exim-Mail-From: ore@pengutronix.de X-SA-Exim-Scanned: No (on metis.whiteo.stw.pengutronix.de); SAEximRunCond expanded to false X-PTX-Original-Recipient: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Currently, the pinctrl core strictly requires all drivers to implement .get_groups_count and .get_group_name callbacks in their pinctrl_ops. However, for simple pinctrl drivers that act purely as GPIO controllers and pin-specific configuration proxies (without any concept of muxing or pin groups), this strict requirement forces the implementation of dummy callbacks just to satisfy pinctrl_check_ops(). Relax this requirement by making the group callbacks optional. Update the core and debugfs (pinconf) functions to check for the existence of these callbacks before invoking them, allowing simple drivers to omit group boilerplate entirely. Suggested-by: Linus Walleij Signed-off-by: Oleksij Rempel Reviewed-by: Linus Walleij --- changes v5: - no changes changes v4: - add Reviewed-by: Linus Walleij ... changes v3: - no changes --- drivers/pinctrl/core.c | 25 ++++++++++++++++++++----- drivers/pinctrl/pinconf.c | 18 +++++++++++++----- 2 files changed, 33 insertions(+), 10 deletions(-) diff --git a/drivers/pinctrl/core.c b/drivers/pinctrl/core.c index b5e97689589f..920e025622d6 100644 --- a/drivers/pinctrl/core.c +++ b/drivers/pinctrl/core.c @@ -621,8 +621,13 @@ static int pinctrl_generic_group_name_to_selector(stru= ct pinctrl_dev *pctldev, const char *function) { const struct pinctrl_ops *ops =3D pctldev->desc->pctlops; - int ngroups =3D ops->get_groups_count(pctldev); int selector =3D 0; + int ngroups; + + if (!ops->get_groups_count || !ops->get_group_name) + return -EINVAL; + + ngroups =3D ops->get_groups_count(pctldev); =20 /* See if this pctldev has this group */ while (selector < ngroups) { @@ -737,8 +742,15 @@ int pinctrl_get_group_selector(struct pinctrl_dev *pct= ldev, const char *pin_group) { const struct pinctrl_ops *pctlops =3D pctldev->desc->pctlops; - unsigned int ngroups =3D pctlops->get_groups_count(pctldev); unsigned int group_selector =3D 0; + unsigned int ngroups; + + if (!pctlops->get_groups_count || !pctlops->get_group_name) { + dev_err(pctldev->dev, "does not support pin groups\n"); + return -EINVAL; + } + + ngroups =3D pctlops->get_groups_count(pctldev); =20 while (group_selector < ngroups) { const char *gname =3D pctlops->get_group_name(pctldev, @@ -1769,6 +1781,11 @@ static int pinctrl_groups_show(struct seq_file *s, v= oid *what) =20 mutex_lock(&pctldev->mutex); =20 + if (!ops->get_groups_count || !ops->get_group_name) { + mutex_unlock(&pctldev->mutex); + return 0; + } + ngroups =3D ops->get_groups_count(pctldev); =20 seq_puts(s, "registered pin groups:\n"); @@ -2050,9 +2067,7 @@ static int pinctrl_check_ops(struct pinctrl_dev *pctl= dev) { const struct pinctrl_ops *ops =3D pctldev->desc->pctlops; =20 - if (!ops || - !ops->get_groups_count || - !ops->get_group_name) + if (!ops) return -EINVAL; =20 return 0; diff --git a/drivers/pinctrl/pinconf.c b/drivers/pinctrl/pinconf.c index dca963633b5d..feab87e8530d 100644 --- a/drivers/pinctrl/pinconf.c +++ b/drivers/pinctrl/pinconf.c @@ -273,10 +273,13 @@ void pinconf_show_setting(struct seq_file *s, setting->data.configs.group_or_pin); break; case PIN_MAP_TYPE_CONFIGS_GROUP: - seq_printf(s, "group %s (%d)", - pctlops->get_group_name(pctldev, - setting->data.configs.group_or_pin), - setting->data.configs.group_or_pin); + if (pctlops->get_group_name) + seq_printf(s, "group %s (%d)", + pctlops->get_group_name(pctldev, + setting->data.configs.group_or_pin), + setting->data.configs.group_or_pin); + else + seq_printf(s, "group (%d)", setting->data.configs.group_or_pin); break; default: break; @@ -348,8 +351,13 @@ static int pinconf_groups_show(struct seq_file *s, voi= d *what) { struct pinctrl_dev *pctldev =3D s->private; const struct pinctrl_ops *pctlops =3D pctldev->desc->pctlops; - unsigned int ngroups =3D pctlops->get_groups_count(pctldev); unsigned int selector =3D 0; + unsigned int ngroups; + + if (!pctlops->get_groups_count || !pctlops->get_group_name) + return 0; + + ngroups =3D pctlops->get_groups_count(pctldev); =20 seq_puts(s, "Pin config settings per pin group\n"); seq_puts(s, "Format: group (name): configs\n"); --=20 2.47.3