From patchwork Fri Jul 23 07:58:53 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrew Jeffery X-Patchwork-Id: 485487 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-18.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 3BBB4C4338F for ; Fri, 23 Jul 2021 07:59:25 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 250AE60EBD for ; Fri, 23 Jul 2021 07:59:25 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234327AbhGWHSu (ORCPT ); Fri, 23 Jul 2021 03:18:50 -0400 Received: from new2-smtp.messagingengine.com ([66.111.4.224]:41225 "EHLO new2-smtp.messagingengine.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233291AbhGWHSu (ORCPT ); Fri, 23 Jul 2021 03:18:50 -0400 Received: from compute4.internal (compute4.nyi.internal [10.202.2.44]) by mailnew.nyi.internal (Postfix) with ESMTP id 7666558163D; Fri, 23 Jul 2021 03:59:23 -0400 (EDT) Received: from mailfrontend2 ([10.202.2.163]) by compute4.internal (MEProxy); Fri, 23 Jul 2021 03:59:23 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=aj.id.au; h=from :to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; s=fm3; bh=prvFZBuvGwZue C8BLyYXlLV7gDV0lQGJkUtNBW/Q/Ok=; b=jnQpu3WBtUnqmRHaHOWk3RoktPD77 Gl8xQKvUlATXmBTuldAeI8Z8tdxsxmq7b7pLPFpwH86If5Qwf9CCKlk7Dw+dexjp D2TZkQZPvARdqTIlsAEXBpJ8pyee/lgXS38gy/wmNEHJQT/KrcJSKT5EB1OLl2TE 7BeG6W9ffCJXIsV3PwdLQ/fra6etZ97+SgSzgMDw1ggMAMK+HBUG7lqJ5gU4eqSF hreIqJ++/63Y1PapuplHevVMX0NVIbJ9RovuT+R+wu2clEbGvbtuxfKDXbLlqibu xYmBlj++AltwC9KvZn/7Mh9lXXlEbbzLZPED1k6RwhsYM89cEa8mVd+tg== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:content-transfer-encoding:date:from :in-reply-to:message-id:mime-version:references:subject:to :x-me-proxy:x-me-proxy:x-me-sender:x-me-sender:x-sasl-enc; s= fm3; bh=prvFZBuvGwZueC8BLyYXlLV7gDV0lQGJkUtNBW/Q/Ok=; b=RJsjaRJ0 qZR2nFVvDiApiQqvcXDUhDirmvRrVxdmV3F/t2wsw9pb7cIkt57wyR7zfOq6pv/1 QAqGcYbDVSFEo/ZK8hwNktOdFJczkEm4uNZP8b6j4MYMVQ0f16eeAQKoU2v2WUAw iO75/9jU5E91lzbMBrkJYBAS1b75F/rladRduWSBuwYx5aSQS4pqlU5jyN2Ppvg7 LnpH9CBIDXYcmj+mNkxD9+Yjb/I0PkfYc5G0rbRyHZCQ8Xfgg3qgDR7+tMvPw2tm glRZ2lAeCiloUufE7GYX37cpCRLDjDqU5K0nhbIhEktdPXHahg0ufDLeQrQ0FICw u6BYLFjb0ytAmQ== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedvtddrfeejgdduvddvucetufdoteggodetrfdotf fvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdfqfgfvpdfurfetoffkrfgpnffqhgen uceurghilhhouhhtmecufedttdenucenucfjughrpefhvffufffkofgjfhgggfestdekre dtredttdenucfhrhhomheptehnughrvgifucflvghffhgvrhihuceorghnughrvgifsegr jhdrihgurdgruheqnecuggftrfgrthhtvghrnhepjefgvdevheetkeevgeegleelgfelte etjeffleffvdduudevieffgeetleevhfetnecuvehluhhsthgvrhfuihiivgeptdenucfr rghrrghmpehmrghilhhfrhhomheprghnughrvgifsegrjhdrihgurdgruh X-ME-Proxy: Received: by mail.messagingengine.com (Postfix) with ESMTPA; Fri, 23 Jul 2021 03:59:19 -0400 (EDT) From: Andrew Jeffery To: linux-leds@vger.kernel.org, linux-gpio@vger.kernel.org Cc: clg@kaod.org, robh+dt@kernel.org, joel@jms.id.au, pavel@ucw.cz, linus.walleij@linaro.org, devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-aspeed@lists.ozlabs.org, linux-kernel@vger.kernel.org Subject: [RFC PATCH 1/6] pinctrl: Add pinctrl_gpio_as_pin() Date: Fri, 23 Jul 2021 17:28:53 +0930 Message-Id: <20210723075858.376378-2-andrew@aj.id.au> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210723075858.376378-1-andrew@aj.id.au> References: <20210723075858.376378-1-andrew@aj.id.au> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-leds@vger.kernel.org Allow gpiochips to map the GPIO numberspace onto a pin numberspace when the register layout for GPIO control is implemented in terms of the pin numberspace. This requirement sounds kind of strange, but the patch is driven by trying to resolve a bug in the leds-pca955x driver where this mapping is not correctly performed. Signed-off-by: Andrew Jeffery --- drivers/pinctrl/core.c | 19 +++++++++++++++++++ include/linux/pinctrl/pinctrl.h | 3 +++ 2 files changed, 22 insertions(+) diff --git a/drivers/pinctrl/core.c b/drivers/pinctrl/core.c index a4ac87c8b4f8..9c788f0e2844 100644 --- a/drivers/pinctrl/core.c +++ b/drivers/pinctrl/core.c @@ -738,6 +738,25 @@ int pinctrl_get_group_selector(struct pinctrl_dev *pctldev, return -EINVAL; } +int pinctrl_gpio_as_pin(struct pinctrl_dev *pctldev, unsigned int gpio) +{ + struct pinctrl_gpio_range *range; + int pin; + + range = pinctrl_match_gpio_range(pctldev, gpio); + if (!range) + return -ENODEV; + + mutex_lock(&pctldev->mutex); + + pin = gpio_to_pin(range, gpio); + + mutex_unlock(&pctldev->mutex); + + return pin; +} +EXPORT_SYMBOL_GPL(pinctrl_find_gpio_range_from_pin); + bool pinctrl_gpio_can_use_line(unsigned gpio) { struct pinctrl_dev *pctldev; diff --git a/include/linux/pinctrl/pinctrl.h b/include/linux/pinctrl/pinctrl.h index 70b45d28e7a9..1ceebc499cc4 100644 --- a/include/linux/pinctrl/pinctrl.h +++ b/include/linux/pinctrl/pinctrl.h @@ -182,6 +182,9 @@ extern struct pinctrl_dev *pinctrl_find_and_add_gpio_range(const char *devname, extern struct pinctrl_gpio_range * pinctrl_find_gpio_range_from_pin(struct pinctrl_dev *pctldev, unsigned int pin); + +extern int pinctrl_gpio_as_pin(struct pinctrl_dev *pctldev, unsigned int gpio); + extern int pinctrl_get_group_pins(struct pinctrl_dev *pctldev, const char *pin_group, const unsigned **pins, unsigned *num_pins); From patchwork Fri Jul 23 07:58:54 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrew Jeffery X-Patchwork-Id: 484891 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-18.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id BC153C4338F for ; Fri, 23 Jul 2021 07:59:32 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id A4E6160EE6 for ; Fri, 23 Jul 2021 07:59:32 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234370AbhGWHS5 (ORCPT ); Fri, 23 Jul 2021 03:18:57 -0400 Received: from new2-smtp.messagingengine.com ([66.111.4.224]:40317 "EHLO new2-smtp.messagingengine.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234350AbhGWHSz (ORCPT ); Fri, 23 Jul 2021 03:18:55 -0400 Received: from compute4.internal (compute4.nyi.internal [10.202.2.44]) by mailnew.nyi.internal (Postfix) with ESMTP id 1EAE1581648; Fri, 23 Jul 2021 03:59:28 -0400 (EDT) Received: from mailfrontend2 ([10.202.2.163]) by compute4.internal (MEProxy); Fri, 23 Jul 2021 03:59:28 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=aj.id.au; h=from :to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; s=fm3; bh=FL7d3DKD/w/mD 2Cy6ISU7AvGUnJr6NtK3PC+jbi7Vek=; b=JSZnIxLpHBR3Njwf2tb7V9IoNe/HJ jylTJnK1aspzSiYLtzIXiWXN0emgYGI7xozW+Xobmzh0k+s08qPx3qT9G/m6XNNM M3ExHWI34mojpdfjTqDgMHXrUHFtcvklGzx2hYcjy2vjCjLtXlCvrjHNlR+bb2iy zsNftFoEgxWr9dW2wbs9CWwHErsfz563TCpqBUPJH1TJdy8HM05B8o/3aTpFplmx ozGxM50nYeZ/XlEnyhYqcVwFNcBSjD5tV+Yk2wI0vLy0lbsIXml0MbQzqkdKcwkM wtMaZcNzUP1UR1AjcXAyEP9yqMd90265R8QimGMDhKNLeJCBk/MrmtwoQ== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:content-transfer-encoding:date:from :in-reply-to:message-id:mime-version:references:subject:to :x-me-proxy:x-me-proxy:x-me-sender:x-me-sender:x-sasl-enc; s= fm3; bh=FL7d3DKD/w/mD2Cy6ISU7AvGUnJr6NtK3PC+jbi7Vek=; b=EeTsDFpJ AHLazN3xvoV6v35U9PMiextcf+3Jrm7k51n6N/W6EdwQoCOdjRvAZttJGCow4/SA 9vtMd0JULQzphfOkUNBCYpIcPyLIjcFplJvE4TXYLU/ADy2PJkVAt4yNa2p3tTqy Tlr/jmVdSIG8iZ1BbxxKdU1anCBrQYQyneIE6NmAX9BGuITYMzEFTBlVg0KTmf5y q0G6s4akqYkmP6KA9FOxCyyaoVoWuCstE2jAUvQlDdbCEPsTATEDutKn4LpLjz3W c4cyDeIdm4vS8CelnRSCOuagPTGQooqA2f4d8M41Idyp7Rp8zKlhxsT1/Bl/0jmK 5bberMT3Bc6cZQ== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedvtddrfeejgdduvddvucetufdoteggodetrfdotf fvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdfqfgfvpdfurfetoffkrfgpnffqhgen uceurghilhhouhhtmecufedttdenucenucfjughrpefhvffufffkofgjfhgggfestdekre dtredttdenucfhrhhomheptehnughrvgifucflvghffhgvrhihuceorghnughrvgifsegr jhdrihgurdgruheqnecuggftrfgrthhtvghrnhepjefgvdevheetkeevgeegleelgfelte etjeffleffvdduudevieffgeetleevhfetnecuvehluhhsthgvrhfuihiivgepudenucfr rghrrghmpehmrghilhhfrhhomheprghnughrvgifsegrjhdrihgurdgruh X-ME-Proxy: Received: by mail.messagingengine.com (Postfix) with ESMTPA; Fri, 23 Jul 2021 03:59:23 -0400 (EDT) From: Andrew Jeffery To: linux-leds@vger.kernel.org, linux-gpio@vger.kernel.org Cc: clg@kaod.org, robh+dt@kernel.org, joel@jms.id.au, pavel@ucw.cz, linus.walleij@linaro.org, devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-aspeed@lists.ozlabs.org, linux-kernel@vger.kernel.org Subject: [RFC PATCH 2/6] pinctrl: Add hook for device-specific map parsing Date: Fri, 23 Jul 2021 17:28:54 +0930 Message-Id: <20210723075858.376378-3-andrew@aj.id.au> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210723075858.376378-1-andrew@aj.id.au> References: <20210723075858.376378-1-andrew@aj.id.au> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-leds@vger.kernel.org The devicetree binding for the PCA955x LED/GPIO expanders was not written with pinctrl in mind. To maintain compatibility with existing devicetrees while implementing pinctrl support for the PCA955x devices, add the ability to parse a custom device node layout to pinctrl. Signed-off-by: Andrew Jeffery --- drivers/pinctrl/core.c | 6 +++++- include/linux/pinctrl/pinctrl.h | 1 + 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/pinctrl/core.c b/drivers/pinctrl/core.c index 9c788f0e2844..e4862552eb9b 100644 --- a/drivers/pinctrl/core.c +++ b/drivers/pinctrl/core.c @@ -1063,7 +1063,11 @@ static struct pinctrl *create_pinctrl(struct device *dev, INIT_LIST_HEAD(&p->states); INIT_LIST_HEAD(&p->dt_maps); - ret = pinctrl_dt_to_map(p, pctldev); + if (pctldev && pctldev->desc->pctlops->dt_dev_to_map) { + ret = pctldev->desc->pctlops->dt_dev_to_map(pctldev, dev); + } else { + ret = pinctrl_dt_to_map(p, pctldev); + } if (ret < 0) { kfree(p); return ERR_PTR(ret); diff --git a/include/linux/pinctrl/pinctrl.h b/include/linux/pinctrl/pinctrl.h index 1ceebc499cc4..2eeec0af61fe 100644 --- a/include/linux/pinctrl/pinctrl.h +++ b/include/linux/pinctrl/pinctrl.h @@ -95,6 +95,7 @@ struct pinctrl_ops { unsigned *num_pins); void (*pin_dbg_show) (struct pinctrl_dev *pctldev, struct seq_file *s, unsigned offset); + int (*dt_dev_to_map) (struct pinctrl_dev *pctldev, struct device *dev); int (*dt_node_to_map) (struct pinctrl_dev *pctldev, struct device_node *np_config, struct pinctrl_map **map, unsigned *num_maps); From patchwork Fri Jul 23 07:58:55 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrew Jeffery X-Patchwork-Id: 485486 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-18.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 4898FC432BE for ; Fri, 23 Jul 2021 07:59:40 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 3068960E91 for ; Fri, 23 Jul 2021 07:59:40 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234344AbhGWHTF (ORCPT ); Fri, 23 Jul 2021 03:19:05 -0400 Received: from new2-smtp.messagingengine.com ([66.111.4.224]:43503 "EHLO new2-smtp.messagingengine.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234350AbhGWHTA (ORCPT ); Fri, 23 Jul 2021 03:19:00 -0400 Received: from compute6.internal (compute6.nyi.internal [10.202.2.46]) by mailnew.nyi.internal (Postfix) with ESMTP id B51B0581634; Fri, 23 Jul 2021 03:59:33 -0400 (EDT) Received: from mailfrontend2 ([10.202.2.163]) by compute6.internal (MEProxy); Fri, 23 Jul 2021 03:59:33 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=aj.id.au; h=from :to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; s=fm3; bh=lCh2Ol//vFzVk VzvlKjdk4D6bA8X97QIfM65YqzjWeo=; b=jdBRuHFMnKFlOCCNQPKIEybqwAopa MEJ3HKX9ui5l16fPMib0XL8B8ANUoDow/9lbH8twqsnioQl9cU7y+BWGyIqEtt0L AveczEFwCGbBvoMOR9lAW8ZiH3Wrb/lRRLES/AerF3qmbrpjTVF9fRgcSXFuIn4m ogbYdRaUY/fNjDuxPgx1KX0KrQIpafK3Ru7/Afh2x5oPaTm1xdPArZiuajI0Yx82 yG4wqkfk8EOw8aWyTEpHhhta6k7bLFBdyBwN4sm0z7e4qXiDIBIGecDlDGtWh/Pw c8ihOZ/ZIZ1wMXHqMkrsHMuEKRNSgfTTjCWiQUNG0mXS7oGdc/s0PKmNg== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:content-transfer-encoding:date:from :in-reply-to:message-id:mime-version:references:subject:to :x-me-proxy:x-me-proxy:x-me-sender:x-me-sender:x-sasl-enc; s= fm3; bh=lCh2Ol//vFzVkVzvlKjdk4D6bA8X97QIfM65YqzjWeo=; b=ATQntg3w 725zYM152ggKUEOaWPIJouN2EHEi0cxWquoF1vurrPLcjFtIreXf5MvUrk59VspV qCv2DkxKsHziEuK+ZyuH2wYcaEsmQAkLxbL43vBcuKSu2Vhq1us3Pr1OvhRnn54K 2n4KJGOK1m9COFN2wrw/VnQmcDwlZLW2nM3hBLJcukLN5Svwpn5Mbzp+2uiWh341 BqlUz27ROp8KXFAJcSubcqV8w/S9PdAdpIdbkXvakO+3/N9VOGKeFBH196aM398L 7M3p/UuzRylDkVKzHhLOXAPszuiZKCAM50xhEITRhBPhZ8YryV+PAHEp4rpfWFI5 p4VkCCcMwZrQ0A== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedvtddrfeejgdduvddvucetufdoteggodetrfdotf fvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdfqfgfvpdfurfetoffkrfgpnffqhgen uceurghilhhouhhtmecufedttdenucenucfjughrpefhvffufffkofgjfhgggfestdekre dtredttdenucfhrhhomheptehnughrvgifucflvghffhgvrhihuceorghnughrvgifsegr jhdrihgurdgruheqnecuggftrfgrthhtvghrnhepjefgvdevheetkeevgeegleelgfelte etjeffleffvdduudevieffgeetleevhfetnecuvehluhhsthgvrhfuihiivgeptdenucfr rghrrghmpehmrghilhhfrhhomheprghnughrvgifsegrjhdrihgurdgruh X-ME-Proxy: Received: by mail.messagingengine.com (Postfix) with ESMTPA; Fri, 23 Jul 2021 03:59:28 -0400 (EDT) From: Andrew Jeffery To: linux-leds@vger.kernel.org, linux-gpio@vger.kernel.org Cc: clg@kaod.org, robh+dt@kernel.org, joel@jms.id.au, pavel@ucw.cz, linus.walleij@linaro.org, devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-aspeed@lists.ozlabs.org, linux-kernel@vger.kernel.org Subject: [RFC PATCH 3/6] leds: pca955x: Relocate chipdef-related descriptors Date: Fri, 23 Jul 2021 17:28:55 +0930 Message-Id: <20210723075858.376378-4-andrew@aj.id.au> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210723075858.376378-1-andrew@aj.id.au> References: <20210723075858.376378-1-andrew@aj.id.au> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-leds@vger.kernel.org Reduce code-motion noise when implementing pinctrl. Signed-off-by: Andrew Jeffery --- drivers/leds/leds-pca955x.c | 76 ++++++++++++++++++------------------- 1 file changed, 38 insertions(+), 38 deletions(-) diff --git a/drivers/leds/leds-pca955x.c b/drivers/leds/leds-pca955x.c index 7087ca4592fc..6614291b288e 100644 --- a/drivers/leds/leds-pca955x.c +++ b/drivers/leds/leds-pca955x.c @@ -75,44 +75,6 @@ struct pca955x_chipdef { int slv_addr_shift; /* Number of bits to ignore */ }; -static struct pca955x_chipdef pca955x_chipdefs[] = { - [pca9550] = { - .bits = 2, - .slv_addr = /* 110000x */ 0x60, - .slv_addr_shift = 1, - }, - [pca9551] = { - .bits = 8, - .slv_addr = /* 1100xxx */ 0x60, - .slv_addr_shift = 3, - }, - [pca9552] = { - .bits = 16, - .slv_addr = /* 1100xxx */ 0x60, - .slv_addr_shift = 3, - }, - [ibm_pca9552] = { - .bits = 16, - .slv_addr = /* 0110xxx */ 0x30, - .slv_addr_shift = 3, - }, - [pca9553] = { - .bits = 4, - .slv_addr = /* 110001x */ 0x62, - .slv_addr_shift = 1, - }, -}; - -static const struct i2c_device_id pca955x_id[] = { - { "pca9550", pca9550 }, - { "pca9551", pca9551 }, - { "pca9552", pca9552 }, - { "ibm-pca9552", ibm_pca9552 }, - { "pca9553", pca9553 }, - { } -}; -MODULE_DEVICE_TABLE(i2c, pca955x_id); - struct pca955x { struct mutex lock; struct pca955x_led *leds; @@ -415,6 +377,44 @@ pca955x_get_pdata(struct i2c_client *client, struct pca955x_chipdef *chip) return pdata; } +static struct pca955x_chipdef pca955x_chipdefs[] = { + [pca9550] = { + .bits = 2, + .slv_addr = /* 110000x */ 0x60, + .slv_addr_shift = 1, + }, + [pca9551] = { + .bits = 8, + .slv_addr = /* 1100xxx */ 0x60, + .slv_addr_shift = 3, + }, + [pca9552] = { + .bits = 16, + .slv_addr = /* 1100xxx */ 0x60, + .slv_addr_shift = 3, + }, + [ibm_pca9552] = { + .bits = 16, + .slv_addr = /* 0110xxx */ 0x30, + .slv_addr_shift = 3, + }, + [pca9553] = { + .bits = 4, + .slv_addr = /* 110001x */ 0x62, + .slv_addr_shift = 1, + }, +}; + +static const struct i2c_device_id pca955x_id[] = { + { "pca9550", pca9550 }, + { "pca9551", pca9551 }, + { "pca9552", pca9552 }, + { "ibm-pca9552", ibm_pca9552 }, + { "pca9553", pca9553 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, pca955x_id); + static const struct of_device_id of_pca955x_match[] = { { .compatible = "nxp,pca9550", .data = (void *)pca9550 }, { .compatible = "nxp,pca9551", .data = (void *)pca9551 }, From patchwork Fri Jul 23 07:58:56 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrew Jeffery X-Patchwork-Id: 484890 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-18.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id E2746C4320A for ; Fri, 23 Jul 2021 07:59:42 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id CDB3E60EE6 for ; Fri, 23 Jul 2021 07:59:42 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234385AbhGWHTG (ORCPT ); Fri, 23 Jul 2021 03:19:06 -0400 Received: from new2-smtp.messagingengine.com ([66.111.4.224]:47031 "EHLO new2-smtp.messagingengine.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234376AbhGWHTE (ORCPT ); Fri, 23 Jul 2021 03:19:04 -0400 Received: from compute4.internal (compute4.nyi.internal [10.202.2.44]) by mailnew.nyi.internal (Postfix) with ESMTP id 2FBCA581648; Fri, 23 Jul 2021 03:59:38 -0400 (EDT) Received: from mailfrontend2 ([10.202.2.163]) by compute4.internal (MEProxy); Fri, 23 Jul 2021 03:59:38 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=aj.id.au; h=from :to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; s=fm3; bh=SMX8m+YSURBok a0Y4s6uw+SSNshgRk1Rz/kH60UznJo=; b=FYtpMWf1LBo9jfhviI6WyCJ+K9ooA /wyvKrWsvEoDcXz9UIznr4ZVzNkx9+6TeEDC+IubGhDVNOk654C5rwdRuIVDwq1G G/SsFvUSYlF0TKgEWIdUXS8vcal8BTR5Bt5c1iTL3xoDKsQIShGzcxvnTt3xy7Y7 OjvWGZWtBY/pJJaq/b+8A+d260y8cviyrHqtlBZJv0pnUA8w3rqIFpwpaeF6Y75i XBpPjSXUAOWOFNTF48qMOhBZQpbg8kpZBugMFPO1tQsIWu59YfqM8nzXTsvDrpnS BKMMeBiTaHBpVq+bPmGH/nfGHiThIixjgZbu6npUGN8yNdTKlwyDssUgA== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:content-transfer-encoding:date:from :in-reply-to:message-id:mime-version:references:subject:to :x-me-proxy:x-me-proxy:x-me-sender:x-me-sender:x-sasl-enc; s= fm3; bh=SMX8m+YSURBoka0Y4s6uw+SSNshgRk1Rz/kH60UznJo=; b=fXjA7rXd gkdE7zRkiYYAs9SgGMyvSiCBfl/Z4SaP2gWRWDKOoySUlNmRMXhQdEATW0pJrBas Z1un7AYOG5lhEEtkXCzI7JU3RGbUsq6zCpCeora0kiiRTzSohpJ/ngrfZjS4KY7m B605ccfFJ7aYGbe7qIeyI9MaMkTYpP53yKcsos+noGsyWuScgnf/KCTxT3ZfGlju 0ZioXW0+x3COD8x8TtcSPaxbCdTdrLsBBDr+dzNeSwYGa9IWEty5HoX3ZC29L9AR 6fBuA22ZJ/ha6EVKEy7vVPMP+qs+JPo6gd6xwYpDppofVACNRqhjvCBcx3rRNudy jvsyJUHS43QW5w== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedvtddrfeejgdduvddvucetufdoteggodetrfdotf fvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdfqfgfvpdfurfetoffkrfgpnffqhgen uceurghilhhouhhtmecufedttdenucenucfjughrpefhvffufffkofgjfhgggfestdekre dtredttdenucfhrhhomheptehnughrvgifucflvghffhgvrhihuceorghnughrvgifsegr jhdrihgurdgruheqnecuggftrfgrthhtvghrnhepvddvuefftdeuhedujedvgffhgfevvd ehgedtjeetudeiteekhffhfeejheettdffnecuffhomhgrihhnpehmuhigrdhgrhhouhhp necuvehluhhsthgvrhfuihiivgeptdenucfrrghrrghmpehmrghilhhfrhhomheprghnug hrvgifsegrjhdrihgurdgruh X-ME-Proxy: Received: by mail.messagingengine.com (Postfix) with ESMTPA; Fri, 23 Jul 2021 03:59:34 -0400 (EDT) From: Andrew Jeffery To: linux-leds@vger.kernel.org, linux-gpio@vger.kernel.org Cc: clg@kaod.org, robh+dt@kernel.org, joel@jms.id.au, pavel@ucw.cz, linus.walleij@linaro.org, devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-aspeed@lists.ozlabs.org, linux-kernel@vger.kernel.org Subject: [RFC PATCH 4/6] leds: pca955x: Use pinctrl to map GPIOs to pins Date: Fri, 23 Jul 2021 17:28:56 +0930 Message-Id: <20210723075858.376378-5-andrew@aj.id.au> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210723075858.376378-1-andrew@aj.id.au> References: <20210723075858.376378-1-andrew@aj.id.au> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-leds@vger.kernel.org The leds-pca955x driver currently assumes that the GPIO numberspace and the pin numberspace are the same. This quickly falls apart with a devicetree binding such as the following: pca0: pca9552@61 { compatible = "nxp,pca9552"; reg = <0x61>; #address-cells = <1>; #size-cells = <0>; gpio-controller; #gpio-cells = <2>; led@0 { reg = <0>; type = ; }; gpio@1 { reg = <1>; type = ; }; }; This results in a gpiochip with 1 gpio at offset 0 that should control a pin at offset 1 on the pca9552. Instead the accessing GPIO 0 of the gpiochip attempts to drive pin 0. Making the GPIO controller cover the entire chip opens up conflicts between the LED and GPIO controllers for the pins. What's needed is a mapping between the GPIO numberspace and the pin numberspace, with mutually exclusive access to each pin for the LED and GPIO controllers. Broadly, this is the responsibility of the pinctrl and pinmux subsystems. Rework the driver to implement pinctrl and pinmux (despite the lack of actual mux hardware), and back the gpiochip and LED controller on to the resulting pin controller. This effort implements a custom devicetree device mapping callback for pinctrl to parse maps from the existing devicetree binding for the PCA955x devices. Subnodes that set `type = ` automatically have a mux group map generated for the default state. This causes probe() to claim the appropriate LED pins for the LED controller from the pinctroller. If subnodes of `type = ` are specified then the gpiochip implements the correct behaviour for what the binding intended - an appropriate GPIO pin mapping is generated and applied to the pincontroller for the specified number of pins. For future PCA955x devicetree nodes, devices that require a mix of LED and GPIO pins can specify the number and numberspace mappings with the `ngpios` and `gpio-ranges` properties from generic GPIO binding. Thus the only subnodes that need to be specified are those for the LEDs. The result is that we now have an accurate mapping between GPIO and pin numberspaces with mutually exclusive access to the pins. In addition, any pin conflict issues can be resolved through the usual debugfs properties exposed by the pinctrl subsystem. Signed-off-by: Andrew Jeffery --- drivers/leds/leds-pca955x.c | 478 +++++++++++++++++++++++++++++++----- 1 file changed, 422 insertions(+), 56 deletions(-) diff --git a/drivers/leds/leds-pca955x.c b/drivers/leds/leds-pca955x.c index 6614291b288e..9e08dbb05bc5 100644 --- a/drivers/leds/leds-pca955x.c +++ b/drivers/leds/leds-pca955x.c @@ -45,6 +45,8 @@ #include #include #include +#include +#include #include #include #include @@ -73,6 +75,7 @@ struct pca955x_chipdef { int bits; u8 slv_addr; /* 7-bit slave address mask */ int slv_addr_shift; /* Number of bits to ignore */ + struct pinctrl_desc *pinctrl; }; struct pca955x { @@ -80,6 +83,8 @@ struct pca955x { struct pca955x_led *leds; struct pca955x_chipdef *chipdef; struct i2c_client *client; + struct pinctrl_desc *pctldesc; + struct pinctrl_dev *pctldev; #ifdef CONFIG_LEDS_PCA955X_GPIO struct gpio_chip gpio; #endif @@ -253,6 +258,15 @@ static int pca955x_led_set(struct led_classdev *led_cdev, return ret; } +static int +pca955x_set_pin_value(struct pca955x *pca955x, unsigned int pin, int val) +{ + struct led_classdev *cdev = &pca955x->leds[pin].led_cdev; + int state = val ? PCA955X_GPIO_HIGH : PCA955X_GPIO_LOW; + + return pca955x_led_set(cdev, state); +} + #ifdef CONFIG_LEDS_PCA955X_GPIO /* * Read the INPUT register, which contains the state of LEDs. @@ -271,64 +285,348 @@ static int pca955x_read_input(struct i2c_client *client, int n, u8 *val) } -static int pca955x_gpio_request_pin(struct gpio_chip *gc, unsigned int offset) +static void +pca955x_gpio_set_value(struct gpio_chip *gc, unsigned int offset, int val) { struct pca955x *pca955x = gpiochip_get_data(gc); - struct pca955x_led *led = &pca955x->leds[offset]; + int pin; - if (led->type == PCA955X_TYPE_GPIO) - return 0; + pin = pinctrl_gpio_as_pin(pca955x->pctldev, gc->base + offset); + if (pin < 0) { + dev_err(gc->parent, "Failed to look up pin for GPIO %d\n", + offset); + return; + } - return -EBUSY; -} - -static int pca955x_set_value(struct gpio_chip *gc, unsigned int offset, - int val) -{ - struct pca955x *pca955x = gpiochip_get_data(gc); - struct pca955x_led *led = &pca955x->leds[offset]; - - if (val) - return pca955x_led_set(&led->led_cdev, PCA955X_GPIO_HIGH); - - return pca955x_led_set(&led->led_cdev, PCA955X_GPIO_LOW); -} - -static void pca955x_gpio_set_value(struct gpio_chip *gc, unsigned int offset, - int val) -{ - pca955x_set_value(gc, offset, val); + pca955x_set_pin_value(pca955x, pin, val); } static int pca955x_gpio_get_value(struct gpio_chip *gc, unsigned int offset) { struct pca955x *pca955x = gpiochip_get_data(gc); - struct pca955x_led *led = &pca955x->leds[offset]; u8 reg = 0; + int pin; + + pin = pinctrl_gpio_as_pin(pca955x->pctldev, gc->base + offset); + if (pin < 0) + return pin; /* There is nothing we can do about errors */ - pca955x_read_input(pca955x->client, led->led_num / 8, ®); + pca955x_read_input(pca955x->client, pin / 8, ®); - return !!(reg & (1 << (led->led_num % 8))); + return !!(reg & (1 << (pin % 8))); } -static int pca955x_gpio_direction_input(struct gpio_chip *gc, - unsigned int offset) +static int +pca955x_gpio_direction_input(struct gpio_chip *gc, unsigned int offset) { struct pca955x *pca955x = gpiochip_get_data(gc); - struct pca955x_led *led = &pca955x->leds[offset]; + struct led_classdev *cdev; + int pin; - /* To use as input ensure pin is not driven. */ - return pca955x_led_set(&led->led_cdev, PCA955X_GPIO_INPUT); + pin = pinctrl_gpio_as_pin(pca955x->pctldev, gc->base + offset); + if (pin < 0) + return pin; + + cdev = &pca955x->leds[pin].led_cdev; + + return pca955x_led_set(cdev, PCA955X_GPIO_INPUT); } -static int pca955x_gpio_direction_output(struct gpio_chip *gc, - unsigned int offset, int val) +static int +pca955x_gpio_direction_output(struct gpio_chip *gc, unsigned int offset, + int val) { - return pca955x_set_value(gc, offset, val); + struct pca955x *pca955x = gpiochip_get_data(gc); + int pin; + + pin = pinctrl_gpio_as_pin(pca955x->pctldev, gc->base + offset); + if (pin < 0) + return pin; + + return pca955x_set_pin_value(pca955x, pin, val); +} + +static int +pca955x_gpio_request_pin(struct gpio_chip *gc, unsigned int offset) +{ + return pinctrl_gpio_request(gc->base + offset); +} + +static void +pca955x_gpio_free_pin(struct gpio_chip *gc, unsigned int offset) +{ + int rc; + + /* Go high-impedance */ + rc = pca955x_gpio_direction_input(gc, offset); + if (rc < 0) + dev_err(gc->parent, "Failed to set direction for GPIO %u:%u\n", gc->base, offset); + + pinctrl_gpio_free(gc->base + offset); } #endif /* CONFIG_LEDS_PCA955X_GPIO */ +static const struct pinctrl_pin_desc pca9552_pinctrl_pins[] = { + PINCTRL_PIN(0, "LED0"), + PINCTRL_PIN(1, "LED1"), + PINCTRL_PIN(2, "LED2"), + PINCTRL_PIN(3, "LED3"), + PINCTRL_PIN(4, "LED4"), + PINCTRL_PIN(5, "LED5"), + PINCTRL_PIN(6, "LED6"), + PINCTRL_PIN(7, "LED7"), + PINCTRL_PIN(8, "LED8"), + PINCTRL_PIN(9, "LED9"), + PINCTRL_PIN(10, "LED10"), + PINCTRL_PIN(11, "LED11"), + PINCTRL_PIN(12, "LED12"), + PINCTRL_PIN(13, "LED13"), + PINCTRL_PIN(14, "LED14"), + PINCTRL_PIN(15, "LED15"), +}; + +static const char * const pca9552_groups[] = { + "LED0", "LED1", "LED2", "LED3", "LED4", "LED5", "LED6", "LED7", + "LED8", "LED9", "LED10", "LED11", "LED12", "LED13", "LED14", "LED15", +}; + +static const unsigned int pca9552_group_pins[] = { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, +}; + +static const char *pca955x_pinctrl_dev_name(struct pca955x *pca955x) +{ + /* The controller is its only consumer via leds and gpios */ + return dev_name(&pca955x->client->dev); +} + +static int pca955x_pinctrl_get_groups_count(struct pinctrl_dev *pctldev) +{ + struct pca955x *pca955x = pinctrl_dev_get_drvdata(pctldev); + + /* We have as many groups as we have LEDs */ + return pca955x->chipdef->bits; +} + +static const char * +pca955x_pinctrl_get_group_name(struct pinctrl_dev *pctldev, unsigned int selector) +{ + struct pca955x *pca955x = pinctrl_dev_get_drvdata(pctldev); + + if (unlikely(selector > pca955x->chipdef->bits)) { + dev_err(&pca955x->client->dev, + "Group selector (%u) exceeds groups count (%u)\n", + selector, pca955x->chipdef->bits); + return NULL; + } + + if (unlikely(selector > ARRAY_SIZE(pca9552_groups))) { + dev_err(&pca955x->client->dev, + "Group selector (%u) exceeds the supported group count (%u)\n", + selector, ARRAY_SIZE(pca9552_groups)); + return NULL; + } + + return pca9552_groups[selector]; +} + +static int +pca955x_pinctrl_get_group_pins(struct pinctrl_dev *pctldev, unsigned int selector, + const unsigned int **pins, unsigned int *num_pins) +{ + struct pca955x *pca955x = pinctrl_dev_get_drvdata(pctldev); + + if (unlikely(selector > pca955x->chipdef->bits)) { + dev_err(&pca955x->client->dev, + "Group selector (%u) exceeds groups count (%u)\n", + selector, pca955x->chipdef->bits); + return -EINVAL; + } + + if (unlikely(selector > ARRAY_SIZE(pca9552_group_pins))) { + dev_err(&pca955x->client->dev, + "Group selector (%u) exceeds the supported group count (%u)\n", + selector, ARRAY_SIZE(pca9552_groups)); + return -EINVAL; + } + + *pins = &pca9552_group_pins[selector]; + *num_pins = 1; + + return 0; +} + +static int pca955x_pinmux_get_functions_count(struct pinctrl_dev *pctldev) +{ + return 1; +} + +static const char * +pca955x_pinmux_get_function_name(struct pinctrl_dev *pctldev, unsigned int selector) +{ + struct pca955x *pca955x = pinctrl_dev_get_drvdata(pctldev); + + if (selector != 0) + dev_err(&pca955x->client->dev, "Only the 'LED' function is supported"); + + return "LED"; +} + +static int pca955x_pinmux_get_function_groups(struct pinctrl_dev *pctldev, + unsigned int selector, + const char * const **groups, + unsigned int *num_groups) +{ + struct pca955x *pca955x = pinctrl_dev_get_drvdata(pctldev); + + if (unlikely(pca955x->chipdef->bits > ARRAY_SIZE(pca9552_groups))) { + dev_warn(&pca955x->client->dev, + "Unsupported PCA955x configuration, LED count exceed LED group count\n"); + return -EINVAL; + } + + if (selector != 0) + dev_err(&pca955x->client->dev, "Only the 'LED' function is supported"); + + *groups = &pca9552_groups[0]; + *num_groups = pca955x->chipdef->bits; + + return 0; +} + +static int +pca955x_pinmux_set_mux(struct pinctrl_dev *pctldev, unsigned int func_selector, + unsigned int group_selector) +{ + /* There's no actual mux as such. */ + return 0; +} + +/* + * Implement pinctrl map parsing in a way that's backwards compatible with the + * existing devicetree binding. + */ +static int +pca955x_dt_dev_to_map(struct pinctrl_dev *pctldev, struct device *dev) +{ + struct pca955x *pca955x = pinctrl_dev_get_drvdata(pctldev); + struct pinctrl_desc *pctldesc = pca955x->pctldesc; + struct fwnode_handle *child; + struct pinctrl_map *maps; + unsigned int i = 0; + int rc; + + if (WARN_ON(dev != &pca955x->client->dev)) + return -EINVAL; + + /* Only 1 possible mux config per LED, no further allocations needed */ + maps = devm_kmalloc_array(dev, pca955x->chipdef->bits, sizeof(*maps), GFP_KERNEL); + if (!maps) + return -ENOMEM; + + device_for_each_child_node(dev, child) { + struct pinctrl_map *m; + u32 type; + u32 reg; + + /* Default to PCA955X_TYPE_LED as we do in pca955x_get_pdata */ + rc = fwnode_property_read_u32(child, "type", &type); + if (rc == -EINVAL) + type = PCA955X_TYPE_LED; + else if (rc < 0) + goto cleanup_maps; + + if (type != PCA955X_TYPE_LED) + continue; + + rc = fwnode_property_read_u32(child, "reg", ®); + if (rc < 0) + goto cleanup_maps; + + if (i >= pca955x->chipdef->bits) { + dev_err(dev, + "The number of pin configuration nodes exceeds the number of available pins (%u)\n", + pca955x->chipdef->bits); + break; + } + + m = &maps[i]; + + m->dev_name = pctldesc->name; + m->name = PINCTRL_STATE_DEFAULT; + m->type = PIN_MAP_TYPE_MUX_GROUP; + m->ctrl_dev_name = pctldesc->name; + m->data.mux.function = "LED"; + m->data.mux.group = devm_kasprintf(dev, GFP_KERNEL, "LED%d", reg); + if (!m->data.mux.group) { + rc = -ENOMEM; + goto cleanup_maps; + } + + i++; + } + + /* Trim the map allocation as required */ + if (i < pca955x->chipdef->bits) { + struct pinctrl_map *trimmed; + + trimmed = devm_krealloc(dev, maps, i * sizeof(*maps), GFP_KERNEL); + if (trimmed) + maps = trimmed; + else + dev_warn(dev, "Failed to trim pinctrl maps\n"); + } + + pinctrl_register_mappings(maps, i); + + return 0; + +cleanup_maps: + while (i--) + devm_kfree(dev, maps[i].data.mux.group); + + devm_kfree(dev, maps); + + return rc; +} + +static void +pca955x_dt_free_map(struct pinctrl_dev *pctldev, struct pinctrl_map *map, + unsigned int num_maps) +{ + struct pca955x *pca955x = pinctrl_dev_get_drvdata(pctldev); + struct device *dev = &pca955x->client->dev; + struct pinctrl_map *iter = map; + + if (!iter) + return; + + while (num_maps) { + devm_kfree(dev, iter->data.mux.group); + iter++; + num_maps--; + } + + devm_kfree(dev, map); +} + +static const struct pinctrl_ops pca955x_pinctrl_ops = { + .get_groups_count = pca955x_pinctrl_get_groups_count, + .get_group_name = pca955x_pinctrl_get_group_name, + .get_group_pins = pca955x_pinctrl_get_group_pins, + .dt_dev_to_map = pca955x_dt_dev_to_map, + .dt_free_map = pca955x_dt_free_map, +}; + +static const struct pinmux_ops pca955x_pinmux_ops = { + .get_functions_count = pca955x_pinmux_get_functions_count, + .get_function_name = pca955x_pinmux_get_function_name, + .get_function_groups = pca955x_pinmux_get_function_groups, + .set_mux = pca955x_pinmux_set_mux, + .strict = true, +}; + static struct pca955x_platform_data * pca955x_get_pdata(struct i2c_client *client, struct pca955x_chipdef *chip) { @@ -434,7 +732,12 @@ static int pca955x_probe(struct i2c_client *client, struct i2c_adapter *adapter; int i, err; struct pca955x_platform_data *pdata; - int ngpios = 0; + u32 ngpios = 0; + struct fwnode_handle *fwnode; + + fwnode = dev_fwnode(&client->dev); + if (!fwnode) + return -ENODATA; chip = &pca955x_chipdefs[id->driver_data]; adapter = client->adapter; @@ -476,12 +779,35 @@ static int pca955x_probe(struct i2c_client *client, if (!pca955x->leds) return -ENOMEM; + pca955x->pctldesc = devm_kzalloc(&client->dev, + sizeof(*pca955x->pctldesc), GFP_KERNEL); + if (!pca955x->pctldesc) + return -ENOMEM; + i2c_set_clientdata(client, pca955x); mutex_init(&pca955x->lock); pca955x->client = client; pca955x->chipdef = chip; + /* pinctrl */ + pca955x->pctldesc->name = pca955x_pinctrl_dev_name(pca955x); + if (!pca955x->pctldesc->name) + return -ENOMEM; + + pca955x->pctldesc->pins = &pca9552_pinctrl_pins[0]; + pca955x->pctldesc->npins = chip->bits; + pca955x->pctldesc->pctlops = &pca955x_pinctrl_ops; + pca955x->pctldesc->pmxops = &pca955x_pinmux_ops; + pca955x->pctldesc->owner = THIS_MODULE; + + err = devm_pinctrl_register_and_init(&client->dev, pca955x->pctldesc, + pca955x, &pca955x->pctldev); + if (err) { + dev_err(&client->dev, "Failed to register pincontroller: %d\n", err); + return err; + } + for (i = 0; i < chip->bits; i++) { pca955x_led = &pca955x->leds[i]; pca955x_led->led_num = i; @@ -527,6 +853,12 @@ static int pca955x_probe(struct i2c_client *client, } } + err = pinctrl_enable(pca955x->pctldev); + if (err) { + dev_err(&client->dev, "Failed to enable pincontroller: %d\n", err); + return err; + } + /* PWM0 is used for half brightness or 50% duty cycle */ err = pca955x_write_pwm(client, 0, 255 - LED_HALF); if (err) @@ -546,30 +878,64 @@ static int pca955x_probe(struct i2c_client *client, return err; #ifdef CONFIG_LEDS_PCA955X_GPIO - if (ngpios) { - pca955x->gpio.label = "gpio-pca955x"; - pca955x->gpio.direction_input = pca955x_gpio_direction_input; - pca955x->gpio.direction_output = pca955x_gpio_direction_output; - pca955x->gpio.set = pca955x_gpio_set_value; - pca955x->gpio.get = pca955x_gpio_get_value; - pca955x->gpio.request = pca955x_gpio_request_pin; - pca955x->gpio.can_sleep = 1; - pca955x->gpio.base = -1; - pca955x->gpio.ngpio = ngpios; - pca955x->gpio.parent = &client->dev; - pca955x->gpio.owner = THIS_MODULE; + /* Always register the gpiochip, no-longer conditional on ngpios */ + pca955x->gpio.label = "gpio-pca955x"; + pca955x->gpio.direction_input = pca955x_gpio_direction_input; + pca955x->gpio.direction_output = pca955x_gpio_direction_output; + pca955x->gpio.set = pca955x_gpio_set_value; + pca955x->gpio.get = pca955x_gpio_get_value; + pca955x->gpio.request = pca955x_gpio_request_pin; + pca955x->gpio.free = pca955x_gpio_free_pin; + pca955x->gpio.can_sleep = 1; + pca955x->gpio.base = -1; + pca955x->gpio.parent = &client->dev; + pca955x->gpio.owner = THIS_MODULE; - err = devm_gpiochip_add_data(&client->dev, &pca955x->gpio, - pca955x); - if (err) { - /* Use data->gpio.dev as a flag for freeing gpiochip */ - pca955x->gpio.parent = NULL; - dev_warn(&client->dev, "could not add gpiochip\n"); + if (!ngpios) { + err = fwnode_property_read_u32(fwnode, "ngpios", &ngpios); + if (err < 0 && err != -EINVAL) return err; + } + + if (!ngpios) + ngpios = chip->bits; + + + pca955x->gpio.ngpio = ngpios; + + err = devm_gpiochip_add_data(&client->dev, &pca955x->gpio, pca955x); + if (err) { + /* Use data->gpio.dev as a flag for freeing gpiochip */ + pca955x->gpio.parent = NULL; + dev_warn(&client->dev, "could not add gpiochip\n"); + return err; + } + + if (!device_property_present(&client->dev, "gpio-ranges")) { + struct fwnode_handle *child; + unsigned int i = 0; + + device_for_each_child_node(&client->dev, child) { + u32 type; + u32 reg; + + err = fwnode_property_read_u32(child, "reg", ®); + if (err < 0) + return err; + + err = fwnode_property_read_u32(child, "type", &type); + if (err < 0) + continue; + + /* XXX: Do something less wasteful? */ + err = gpiochip_add_pin_range(&pca955x->gpio, + pca955x_pinctrl_dev_name(pca955x), + i, reg, 1); + if (err) + return err; + + i++; } - dev_info(&client->dev, "gpios %i...%i\n", - pca955x->gpio.base, pca955x->gpio.base + - pca955x->gpio.ngpio - 1); } #endif From patchwork Fri Jul 23 07:58:57 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrew Jeffery X-Patchwork-Id: 485485 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-18.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED, USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 4DC67C43214 for ; Fri, 23 Jul 2021 07:59:49 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 3B39F60F22 for ; Fri, 23 Jul 2021 07:59:49 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234359AbhGWHTO (ORCPT ); Fri, 23 Jul 2021 03:19:14 -0400 Received: from new2-smtp.messagingengine.com ([66.111.4.224]:59977 "EHLO new2-smtp.messagingengine.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234404AbhGWHTK (ORCPT ); Fri, 23 Jul 2021 03:19:10 -0400 Received: from compute3.internal (compute3.nyi.internal [10.202.2.43]) by mailnew.nyi.internal (Postfix) with ESMTP id 9F669581634; Fri, 23 Jul 2021 03:59:43 -0400 (EDT) Received: from mailfrontend2 ([10.202.2.163]) by compute3.internal (MEProxy); Fri, 23 Jul 2021 03:59:43 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=aj.id.au; h=from :to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; s=fm3; bh=M4brAVDojAQdO LA2SxZ90X+cdLlh9vmdPo456Vzq22Y=; b=UaJkAHfSJlqvnLlAxoVYhMu3YGzIW C8YJ40iQz6oS+vLeDZVdyww2Cj8HAxYPlcTcbNzB6fis99yiJfVPMq1dcPhreeZd D2Fg/WWiN1YIyoGtoPH4KiIGzCFXY7vXWdxgSTnhjaACW97200Nb19HyEje1UaVS 69AyaIaGURK1s6JF+AdipI1TYP1UsAqZ0SqjhudGp4xqttsHWi/LjySiHy7NFSeR DMIUGZcpnWvCU05o9rRiIU6uC7LPq637dMWJCAFe7MQyacqI902mz62/CnMxEgNi s9QP58ybb/iRtDFQYEX6nXfVhwhILYVW+C0oxGAbYUuN+KqktTEBUKnAw== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:content-transfer-encoding:date:from :in-reply-to:message-id:mime-version:references:subject:to :x-me-proxy:x-me-proxy:x-me-sender:x-me-sender:x-sasl-enc; s= fm3; bh=M4brAVDojAQdOLA2SxZ90X+cdLlh9vmdPo456Vzq22Y=; b=MuqPGjGj z4RqTO2akb/D6DrmY7u2KCRcbO82GvxBZGdgcG4eGCO8PnaCbEZSbaIjfgg8e7fc nVaxtbL4mAkGAgcDMaLLdF/QYV0SN572zXfFkOU9bmtyrDOvf8mcEqMymYhH1Spi V3ySplcMvCaoxjPsdeFNhPeB7vfm0WVpsPJG4BJ3flFV9SOmKFmIDyHryiY82pz4 zIoFZHvoyWgcq21XbbO0M7QAua7V7i8UywG4pwh0rqGuDMb/5FhSlrxViU4ibTV0 R9Th43nCXkjxbHZleHo0KXKV/ZknPSvLgi7fIs4euCGGLBJKuJYNEUlC71uP2xtq f9cncUhGeDr/1A== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedvtddrfeejgdduvddvucetufdoteggodetrfdotf fvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdfqfgfvpdfurfetoffkrfgpnffqhgen uceurghilhhouhhtmecufedttdenucenucfjughrpefhvffufffkofgjfhgggfestdekre dtredttdenucfhrhhomheptehnughrvgifucflvghffhgvrhihuceorghnughrvgifsegr jhdrihgurdgruheqnecuggftrfgrthhtvghrnhepjefgvdevheetkeevgeegleelgfelte etjeffleffvdduudevieffgeetleevhfetnecuvehluhhsthgvrhfuihiivgeptdenucfr rghrrghmpehmrghilhhfrhhomheprghnughrvgifsegrjhdrihgurdgruh X-ME-Proxy: Received: by mail.messagingengine.com (Postfix) with ESMTPA; Fri, 23 Jul 2021 03:59:38 -0400 (EDT) From: Andrew Jeffery To: linux-leds@vger.kernel.org, linux-gpio@vger.kernel.org Cc: clg@kaod.org, robh+dt@kernel.org, joel@jms.id.au, pavel@ucw.cz, linus.walleij@linaro.org, devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-aspeed@lists.ozlabs.org, linux-kernel@vger.kernel.org Subject: [RFC PATCH 5/6] ARM: dts: rainier: Add presence-detect and fault indictor GPIO expander Date: Fri, 23 Jul 2021 17:28:57 +0930 Message-Id: <20210723075858.376378-6-andrew@aj.id.au> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210723075858.376378-1-andrew@aj.id.au> References: <20210723075858.376378-1-andrew@aj.id.au> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-leds@vger.kernel.org Expose the ability for the hardware to indicate that it is present, and if it is present, for the BMC to mark it as faulty. Signed-off-by: Andrew Jeffery --- arch/arm/boot/dts/aspeed-bmc-ibm-rainier.dts | 76 ++++++++++++++++++++ 1 file changed, 76 insertions(+) diff --git a/arch/arm/boot/dts/aspeed-bmc-ibm-rainier.dts b/arch/arm/boot/dts/aspeed-bmc-ibm-rainier.dts index 941c0489479a..84651d090965 100644 --- a/arch/arm/boot/dts/aspeed-bmc-ibm-rainier.dts +++ b/arch/arm/boot/dts/aspeed-bmc-ibm-rainier.dts @@ -1685,6 +1685,82 @@ eeprom@50 { compatible = "atmel,24c64"; reg = <0x50>; }; + + dbp0: led-controller@60 { + compatible = "nxp,pca9552"; + reg = <0x60>; + #address-cells = <1>; + #size-cells = <0>; + + gpio-controller; + #gpio-cells = <2>; + ngpios = <8>; + gpio-ranges = <&dbp0 0 8 8>; + + led@0 { + label = "led-fault-0"; + reg = <0>; + retain-state-shutdown; + default-state = "keep"; + type = ; + }; + + led@1 { + label = "led-fault-1"; + reg = <1>; + retain-state-shutdown; + default-state = "keep"; + type = ; + }; + + led@2 { + label = "led-fault-2"; + reg = <2>; + retain-state-shutdown; + default-state = "keep"; + type = ; + }; + + led@3 { + label = "led-fault-3"; + reg = <3>; + retain-state-shutdown; + default-state = "keep"; + type = ; + }; + + led@4 { + label = "led-fault-4"; + reg = <4>; + retain-state-shutdown; + default-state = "keep"; + type = ; + }; + + led@5 { + label = "led-fault-5"; + reg = <5>; + retain-state-shutdown; + default-state = "keep"; + type = ; + }; + + led@6 { + label = "led-fault-6"; + reg = <6>; + retain-state-shutdown; + default-state = "keep"; + type = ; + }; + + led@7 { + label = "led-fault-7"; + reg = <7>; + retain-state-shutdown; + default-state = "keep"; + type = ; + }; + }; }; &i2c14 { From patchwork Fri Jul 23 07:58:58 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrew Jeffery X-Patchwork-Id: 484889 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-18.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 6515DC4338F for ; Fri, 23 Jul 2021 07:59:50 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 4F90D60EFD for ; Fri, 23 Jul 2021 07:59:50 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234403AbhGWHTP (ORCPT ); Fri, 23 Jul 2021 03:19:15 -0400 Received: from new2-smtp.messagingengine.com ([66.111.4.224]:40889 "EHLO new2-smtp.messagingengine.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234366AbhGWHTO (ORCPT ); Fri, 23 Jul 2021 03:19:14 -0400 Received: from compute6.internal (compute6.nyi.internal [10.202.2.46]) by mailnew.nyi.internal (Postfix) with ESMTP id 2448D58163D; Fri, 23 Jul 2021 03:59:48 -0400 (EDT) Received: from mailfrontend2 ([10.202.2.163]) by compute6.internal (MEProxy); Fri, 23 Jul 2021 03:59:48 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=aj.id.au; h=from :to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; s=fm3; bh=yMNleqijxoKWL G2/iRJF83Hp6/4Eiy8KM4eaq0aduKo=; b=d0ZxzPrInqmmJP9WyhsLKYYrWHtdz r5nUAh83q6FssL1zuVYuCT3Kx5bWW/WpfCmg5IdWiSa+E1Xu8kWFG21GY4ZUwg6+ KU3YlW3jjKfCgAxzzZx1ywevWx4/NuSvUq3ltkyRR3BRnCHMtMBe1hyeOvWW1dkV HxEbV0QoBIPOROvEju0lOlDYLOQ2G8p1pKrP4W2ovSxx8VmMNByFpzx3GEA1isdX JFEqYUj9OzdWxqyAhu0gmDed5dTRvPWPdk97etYuwNgXk/QYMRn4cP97OHVvVazp k3BL5fXVxEU177pOY3vFB/q50Br1eG9YtCs1OXjVCUoS642Zv1EnlhNgQ== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:content-transfer-encoding:date:from :in-reply-to:message-id:mime-version:references:subject:to :x-me-proxy:x-me-proxy:x-me-sender:x-me-sender:x-sasl-enc; s= fm3; bh=yMNleqijxoKWLG2/iRJF83Hp6/4Eiy8KM4eaq0aduKo=; b=KVj3Hgfs h6uD4VUrAKDHz2z3yxYCgknIa1eJ2IjcSO7JVhUu/zgJVuH9bWcR+tYTrEOl/nnK 6goAiSC2RDdqXn2cTQN8usnF2OiHVNaUNf73dNHz6YFipat4GXpV7NAUUJ3FZ/nG eBHMQO8lhtgmrZcDrKnvyW+DupCLTool/bdTQa004zAC2YFGj3pCzP6gnhxkF+Z2 HSCRNo3NTqyL0Pvn2EAop4qM40IdLsuHLngRtqKEyyMScsV5Qf1xNq5nq3UQLwk7 4QuglNsdYoHmVdp5Kk5UYwyYLZluxLM9nIXi8h0LFXT55QLCv7kG6UaZscxrtXsw 8fqkFHBTAykO2Q== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedvtddrfeejgdduvddvucetufdoteggodetrfdotf fvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdfqfgfvpdfurfetoffkrfgpnffqhgen uceurghilhhouhhtmecufedttdenucenucfjughrpefhvffufffkofgjfhgggfestdekre dtredttdenucfhrhhomheptehnughrvgifucflvghffhgvrhihuceorghnughrvgifsegr jhdrihgurdgruheqnecuggftrfgrthhtvghrnhepjefgvdevheetkeevgeegleelgfelte etjeffleffvdduudevieffgeetleevhfetnecuvehluhhsthgvrhfuihiivgepudenucfr rghrrghmpehmrghilhhfrhhomheprghnughrvgifsegrjhdrihgurdgruh X-ME-Proxy: Received: by mail.messagingengine.com (Postfix) with ESMTPA; Fri, 23 Jul 2021 03:59:43 -0400 (EDT) From: Andrew Jeffery To: linux-leds@vger.kernel.org, linux-gpio@vger.kernel.org Cc: clg@kaod.org, robh+dt@kernel.org, joel@jms.id.au, pavel@ucw.cz, linus.walleij@linaro.org, devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-aspeed@lists.ozlabs.org, linux-kernel@vger.kernel.org Subject: [RFC PATCH 6/6] pinctrl: Check get_group_pins callback on init Date: Fri, 23 Jul 2021 17:28:58 +0930 Message-Id: <20210723075858.376378-7-andrew@aj.id.au> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210723075858.376378-1-andrew@aj.id.au> References: <20210723075858.376378-1-andrew@aj.id.au> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-leds@vger.kernel.org Do configurations exist where this doesn't make sense? I lost some time to debugging the fact that I was missing the callback :( Signed-off-by: Andrew Jeffery --- drivers/pinctrl/core.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/pinctrl/core.c b/drivers/pinctrl/core.c index e4862552eb9b..4c436a419856 100644 --- a/drivers/pinctrl/core.c +++ b/drivers/pinctrl/core.c @@ -1994,7 +1994,8 @@ static int pinctrl_check_ops(struct pinctrl_dev *pctldev) if (!ops || !ops->get_groups_count || - !ops->get_group_name) + !ops->get_group_name || + !ops->get_group_pins) return -EINVAL; return 0;