Received: by 2002:a05:7412:2a91:b0:fc:a2b0:25d7 with SMTP id u17csp701341rdh; Wed, 14 Feb 2024 08:53:16 -0800 (PST) X-Forwarded-Encrypted: i=3; AJvYcCX6AaG68UUPEefGMZfr4NqMGvwYlpns9qVcTacXrMC7nfycm11z7VhtPVALzfccnFHFfzTEAtsGLH9cCPxXI6nnmrUl8tPYBB4voFc9Cg== X-Google-Smtp-Source: AGHT+IEbMqxKeBjGxDwl2fffj6aE4mk1cUo+qRHawDQcGqnWeJ5EX2zUztLQ2nBgZWlVbhvNZs99 X-Received: by 2002:a05:6358:41a2:b0:178:75cb:18dc with SMTP id w34-20020a05635841a200b0017875cb18dcmr2528414rwc.10.1707929595846; Wed, 14 Feb 2024 08:53:15 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1707929595; cv=pass; d=google.com; s=arc-20160816; b=hn+PqSaO/ZOya0VfrH0ibExp4OArh7+EOvxawA1bVya9eWOMiEf25KT12fOdsn6lxF AlF5tFFz4XaGFJCQjiq2DavAWxM5EDnsDsgCqyrwHP59IJrVUzkFvPbSMTwpK9qIeYKz cmiBrHAtOuDgkFFRAyxaKD4P+8YIzFzykMx+gAsYKLFGbIAsBXgsu8GAW48AcjKJ5UXU am6TdDXxW2QcHqMKjC9vmy6W1FPyHNEHxdgMJuiZ45wLDgRcBAe2mphxfM2JYfaAywlK 4ybsMn7RC3WRdTZxxGra1nRia/o7DM9WzmfxOjl2WRXTbBYvRRhFa5n0mtkDpG2xJXLC FKoQ== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:list-unsubscribe:list-subscribe:list-id:precedence :subject:date:from:dkim-signature; bh=oJ14tHqSqLHFtg6avp0X1Ritv/bgPHCct9WWR86lzjo=; fh=7vSv77f6QY3eh3Id4cjO7Gl0tIPohlCYDvHlTKXJFg4=; b=ZXDqBYTUANohvOmW9+WIQ1EUmZbSwf93JoMjr6EpBvxFm2pyNuE6XaTAMRlCIXmSkr KHuCy3UHNGgbpP4O8jju/uf+2NYNG6tqOqyb/iZhbY95fbcR1I8iINcetzNYC1t8cZTz jf/PnOkVadwAuwixwuxKwTM/1iCA1O5fLbJeu9m4rHTywHngYA+NuoO0QjPR+6g1d5G6 cuWlfVzK/EF7p+4LPBMbL1qYr4ZaZDiM4TZ1v3pIS+/l7xIr153wHwvdGSgHsuH0FK9R 82DICw7BmEhsNk5GYBI6U20ddRKfydjD9jLEs7UOUq0lazX7vLLC9M7IFIsE4sXJRG1Y bomw==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@bootlin.com header.s=gm1 header.b=j9wNif49; arc=pass (i=1 spf=pass spfdomain=bootlin.com dkim=pass dkdomain=bootlin.com dmarc=pass fromdomain=bootlin.com); spf=pass (google.com: domain of linux-kernel+bounces-65522-linux.lists.archive=gmail.com@vger.kernel.org designates 147.75.48.161 as permitted sender) smtp.mailfrom="linux-kernel+bounces-65522-linux.lists.archive=gmail.com@vger.kernel.org"; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=bootlin.com X-Forwarded-Encrypted: i=2; AJvYcCXVLVUqjJ9Jm2W0cRb3q8SqfMFz8qQbYD+rnHrmiua9u2cZyduWaZIRejgho010/6xdEnruVUR+ATDugEj6Xz2Kwi6agr/v2cm3/tOalw== Return-Path: Received: from sy.mirrors.kernel.org (sy.mirrors.kernel.org. [147.75.48.161]) by mx.google.com with ESMTPS id y17-20020a63b511000000b005cf5bf8e7a5si3956428pge.430.2024.02.14.08.53.15 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 14 Feb 2024 08:53:15 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-65522-linux.lists.archive=gmail.com@vger.kernel.org designates 147.75.48.161 as permitted sender) client-ip=147.75.48.161; Authentication-Results: mx.google.com; dkim=pass header.i=@bootlin.com header.s=gm1 header.b=j9wNif49; arc=pass (i=1 spf=pass spfdomain=bootlin.com dkim=pass dkdomain=bootlin.com dmarc=pass fromdomain=bootlin.com); spf=pass (google.com: domain of linux-kernel+bounces-65522-linux.lists.archive=gmail.com@vger.kernel.org designates 147.75.48.161 as permitted sender) smtp.mailfrom="linux-kernel+bounces-65522-linux.lists.archive=gmail.com@vger.kernel.org"; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=bootlin.com 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 sy.mirrors.kernel.org (Postfix) with ESMTPS id A273AB27795 for ; Wed, 14 Feb 2024 16:27:00 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 42A1060BBB; Wed, 14 Feb 2024 16:24:59 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b="j9wNif49" Received: from relay3-d.mail.gandi.net (relay3-d.mail.gandi.net [217.70.183.195]) (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 60A475F871; Wed, 14 Feb 2024 16:24:55 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=217.70.183.195 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707927898; cv=none; b=g6SPC49ejLtYEdoZ4SifplYh1YCZnqPe2ulkov6l+eIbF0f832UgHtGspkjfBfa7FsuvkPSXY15Aw/Br32NYx4xooGtP4ZNbYBO+hPwqEy6eiekA8DtwZcEBcl1w8CaKMECeX54NYAXEAOtiGv87AbWC8nL8qFjF70M6MbgRRcE= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707927898; c=relaxed/simple; bh=VOfDw64xrAjLKL7SdlbDSsAR3K/CMdlWhNnXfibl/HE=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=kMSTDzA/SSjO48tjLBKDQrZvEz70MewzjNvn8OUD3TmNKjLn0zNsRz7tfKqisvOZlJvYMfqlu49RfqJ5fOZJVgcgMBCnwUUwCo5oHtmLFv9gax2mjGBBOj4oz7pmDT2o+Q0ZAmxcNEq6Q3x+gzArLcMAlb3xRC6KtlpaZEbgr0M= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com; spf=pass smtp.mailfrom=bootlin.com; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b=j9wNif49; arc=none smtp.client-ip=217.70.183.195 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bootlin.com Received: by mail.gandi.net (Postfix) with ESMTPSA id D2B3860007; Wed, 14 Feb 2024 16:24:52 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=gm1; t=1707927893; 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=oJ14tHqSqLHFtg6avp0X1Ritv/bgPHCct9WWR86lzjo=; b=j9wNif49vyuB2N1ghzZdkYvXJqOuDxV5K/Bldfi6wun0Dm4St/QW8qVvmsniMdQNAVjdux fdjzOJeQ8JFIcPHNUnSazEhL49lZEUk3oQLWhS2JDjbItD/P5snFOqYU4/0lkF7dC+l1V+ sTaPtDu38kiFYbHT/4QoqFLwDIw0fN5kbgUms2Sfv89z5dSfYEyMqvsaJrN4KTpWhufaD2 UGHCNDOPeAw1R0Q039aeKRlxcjaAZcWwsAneDh46npdB3nUHBguxcwYkzrDQIhMKThYDVU OPTfx7eZilXMG6v7fqVRljHF77nY1TZFxer30Y4qof4lz5kG/tizbRvwBCKpOg== From: =?utf-8?q?Th=C3=A9o_Lebrun?= Date: Wed, 14 Feb 2024 17:24:05 +0100 Subject: [PATCH 12/23] gpio: nomadik: request dynamic ID allocation Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 8bit Message-Id: <20240214-mbly-gpio-v1-12-f88c0ccf372b@bootlin.com> References: <20240214-mbly-gpio-v1-0-f88c0ccf372b@bootlin.com> In-Reply-To: <20240214-mbly-gpio-v1-0-f88c0ccf372b@bootlin.com> To: Linus Walleij , Bartosz Golaszewski , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Philipp Zabel , Thomas Bogendoerfer Cc: linux-gpio@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-mips@vger.kernel.org, Gregory CLEMENT , Vladimir Kondratiev , Thomas Petazzoni , Tawfik Bayouk , =?utf-8?q?Th=C3=A9o_Lebrun?= X-Mailer: b4 0.12.4 X-GND-Sasl: theo.lebrun@bootlin.com Move away from statically allocated GPIO IDs. Switch to dynamic ID allocation. Static IDs are deprecated because they cause issues when multiple GPIO controllers are to be found on the same platform. Add a bit of complexity to do pin number -> GPIO chip + offset. Previously, bank number and offsets were retrieved using division and remainder (bank size being constant 32). Now, to get the pin number matching a bank base, we must know the sum of ngpios of previous banks. This is done in find_nmk_gpio_from_pin() which also exposes the offset inside the bank. Also remove the assumption that bank sizes are constant. Instead of using NMK_GPIO_PER_CHIP as bank size, use nmk_gpio_chips[i]->ngpio. Signed-off-by: Théo Lebrun --- drivers/gpio/gpio-nomadik.c | 2 +- drivers/pinctrl/nomadik/pinctrl-nomadik.c | 55 +++++++++++++++++++++---------- 2 files changed, 38 insertions(+), 19 deletions(-) diff --git a/drivers/gpio/gpio-nomadik.c b/drivers/gpio/gpio-nomadik.c index e39477e1a58f..8d47aef8d2c4 100644 --- a/drivers/gpio/gpio-nomadik.c +++ b/drivers/gpio/gpio-nomadik.c @@ -516,7 +516,7 @@ struct nmk_gpio_chip *nmk_gpio_populate_chip(struct device_node *np, nmk_chip->bank = id; chip = &nmk_chip->chip; - chip->base = id * NMK_GPIO_PER_CHIP; + chip->base = -1; chip->ngpio = NMK_GPIO_PER_CHIP; chip->label = dev_name(&gpio_pdev->dev); chip->parent = &gpio_pdev->dev; diff --git a/drivers/pinctrl/nomadik/pinctrl-nomadik.c b/drivers/pinctrl/nomadik/pinctrl-nomadik.c index 8099dd947701..c7693fbc0484 100644 --- a/drivers/pinctrl/nomadik/pinctrl-nomadik.c +++ b/drivers/pinctrl/nomadik/pinctrl-nomadik.c @@ -530,25 +530,33 @@ static int nmk_get_group_pins(struct pinctrl_dev *pctldev, unsigned int selector return 0; } -static struct nmk_gpio_chip *find_nmk_gpio_from_pin(unsigned int pin) +/* This makes the mapping from pin number to a GPIO chip. We also return the pin + * offset in the GPIO chip for convenience (and to avoid a second loop). + */ +static struct nmk_gpio_chip *find_nmk_gpio_from_pin(unsigned int pin, + unsigned int *offset) { - int i; + int i, j = 0; struct nmk_gpio_chip *nmk_gpio; + /* We assume that pins are allocated in bank order. */ for (i = 0; i < NMK_MAX_BANKS; i++) { nmk_gpio = nmk_gpio_chips[i]; if (!nmk_gpio) continue; - if (pin >= nmk_gpio->chip.base && - pin < nmk_gpio->chip.base + nmk_gpio->chip.ngpio) + if (pin >= j && pin < j + nmk_gpio->chip.ngpio) { + if (offset) + *offset = pin - j; return nmk_gpio; + } + j += nmk_gpio->chip.ngpio; } return NULL; } static struct gpio_chip *find_gc_from_pin(unsigned int pin) { - struct nmk_gpio_chip *nmk_gpio = find_nmk_gpio_from_pin(pin); + struct nmk_gpio_chip *nmk_gpio = find_nmk_gpio_from_pin(pin, NULL); if (nmk_gpio) return &nmk_gpio->chip; @@ -903,8 +911,19 @@ static int nmk_pmx_set(struct pinctrl_dev *pctldev, unsigned int function, * Then mask the pins that need to be sleeping now when we're * switching to the ALT C function. */ - for (i = 0; i < g->grp.npins; i++) - slpm[g->grp.pins[i] / NMK_GPIO_PER_CHIP] &= ~BIT(g->grp.pins[i]); + for (i = 0; i < g->grp.npins; i++) { + struct nmk_gpio_chip *nmk_chip; + + nmk_chip = find_nmk_gpio_from_pin(g->grp.pins[i], NULL); + if (!nmk_chip) { + dev_err(npct->dev, + "invalid pin offset %d in group %s at index %d\n", + g->grp.pins[i], g->grp.name, i); + goto out_pre_slpm_init; + } + + slpm[nmk_chip->bank] &= ~BIT(g->grp.pins[i]); + } nmk_gpio_glitch_slpm_init(slpm); } @@ -912,7 +931,7 @@ static int nmk_pmx_set(struct pinctrl_dev *pctldev, unsigned int function, struct nmk_gpio_chip *nmk_chip; unsigned int bit; - nmk_chip = find_nmk_gpio_from_pin(g->grp.pins[i]); + nmk_chip = find_nmk_gpio_from_pin(g->grp.pins[i], &bit); if (!nmk_chip) { dev_err(npct->dev, "invalid pin offset %d in group %s at index %d\n", @@ -923,7 +942,6 @@ static int nmk_pmx_set(struct pinctrl_dev *pctldev, unsigned int function, g->grp.pins[i], g->altsetting); clk_enable(nmk_chip->clk); - bit = g->grp.pins[i] % NMK_GPIO_PER_CHIP; /* * If the pin is switching to altfunc, and there was an * interrupt installed on it which has been lazy disabled, @@ -954,17 +972,18 @@ static int nmk_pmx_set(struct pinctrl_dev *pctldev, unsigned int function, ret = 0; out_glitch: - if (glitch) { + if (glitch) nmk_gpio_glitch_slpm_restore(slpm); +out_pre_slpm_init: + if (glitch) spin_unlock_irqrestore(&nmk_gpio_slpm_lock, flags); - } return ret; } static int nmk_gpio_request_enable(struct pinctrl_dev *pctldev, struct pinctrl_gpio_range *range, - unsigned int offset) + unsigned int pin) { struct nmk_pinctrl *npct = pinctrl_dev_get_drvdata(pctldev); struct nmk_gpio_chip *nmk_chip; @@ -982,10 +1001,11 @@ static int nmk_gpio_request_enable(struct pinctrl_dev *pctldev, chip = range->gc; nmk_chip = gpiochip_get_data(chip); - dev_dbg(npct->dev, "enable pin %u as GPIO\n", offset); + dev_dbg(npct->dev, "enable pin %u as GPIO\n", pin); + + find_nmk_gpio_from_pin(pin, &bit); clk_enable(nmk_chip->clk); - bit = offset % NMK_GPIO_PER_CHIP; /* There is no glitch when converting any pin to GPIO */ __nmk_gpio_set_mode(nmk_chip, bit, NMK_GPIO_ALT_GPIO); clk_disable(nmk_chip->clk); @@ -995,11 +1015,11 @@ static int nmk_gpio_request_enable(struct pinctrl_dev *pctldev, static void nmk_gpio_disable_free(struct pinctrl_dev *pctldev, struct pinctrl_gpio_range *range, - unsigned int offset) + unsigned int pin) { struct nmk_pinctrl *npct = pinctrl_dev_get_drvdata(pctldev); - dev_dbg(npct->dev, "disable pin %u as GPIO\n", offset); + dev_dbg(npct->dev, "disable pin %u as GPIO\n", pin); /* Set the pin to some default state, GPIO is usually default */ } @@ -1040,7 +1060,7 @@ static int nmk_pin_config_set(struct pinctrl_dev *pctldev, unsigned int pin, int pull, slpm, output, val, i; bool lowemi, gpiomode, sleep; - nmk_chip = find_nmk_gpio_from_pin(pin); + nmk_chip = find_nmk_gpio_from_pin(pin, &bit); if (!nmk_chip) { dev_err(npct->dev, "invalid pin offset %d\n", pin); @@ -1098,7 +1118,6 @@ static int nmk_pin_config_set(struct pinctrl_dev *pctldev, unsigned int pin, lowemi ? "on" : "off"); clk_enable(nmk_chip->clk); - bit = pin % NMK_GPIO_PER_CHIP; if (gpiomode) /* No glitch when going to GPIO mode */ __nmk_gpio_set_mode(nmk_chip, bit, NMK_GPIO_ALT_GPIO); -- 2.43.1