Received: by 2002:a05:7208:9594:b0:7e:5202:c8b4 with SMTP id gs20csp2492186rbb; Wed, 28 Feb 2024 03:43:30 -0800 (PST) X-Forwarded-Encrypted: i=3; AJvYcCVMOF6jyAXUdKqrWdl79Glq7d3qkZPjRb2uUxOUqBVGzfgUbPFCo0iJfCVENr30S8sbCuusDa47OkKlla3YNunbW+MwI0AR1mMTTdGXJw== X-Google-Smtp-Source: AGHT+IGCtbFx3hJwce5Qv6V6QeQpRyDP0orKMlwyaTlJcBt828vbptpsQXZYDP+WyLz6igJWqFJk X-Received: by 2002:aa7:cb45:0:b0:565:14dc:a503 with SMTP id w5-20020aa7cb45000000b0056514dca503mr8320375edt.32.1709120610120; Wed, 28 Feb 2024 03:43:30 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1709120610; cv=pass; d=google.com; s=arc-20160816; b=bNWYF7zF1392wFDplSpB6OFM5VumvXJ2M9fQTnPf4kfHnhz0Y+QJdwJpB1/Yn8YTkW 8Xl2GvUPFDA8+jrR0x7e63GL2/Xu9ADUhIvQrKgDEFExCFHu/FTdf2vtPohXrWYkKE/N l60FvePjfHjQNHobFjxEKd5xjBlFRvWPVnKhMNF1V7joz4Tq9MA7pg3W4n9I2DIdhq/t eNUAaXSZtxi0clXHaYOXwb4SvyxjXLcU/osrN89rF5zkh73aB1Yu/sw2Kib88g/h3BT+ POH43oPBUaRKw3nfZ365xM4rRd6KMqgqWVAEbKZBShAx37M5B1m6bUMdavviOYglq1Ds BSdA== 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=It/BSKt5Sbfkf+TU6yukAJhR+S2DFSVZHDKVJ3bhbAM=; fh=FEGj322JUxHP58NgFBs9atrc2KpQCnFuCu2ueZtAhdY=; b=HuuI3ljkjqmZu43hvm844iR4obHZ1iYxKc2XIoJj1wgvzvEiCI+cAfE8DAi5azjxlP EDulmXD582ryF0FP3YF50hicTpEnm5mQrD0AmZStuBo3H5VXTYT/FuSfJLQrJQCKtSJu dDNbe4SrF+aZIr5rxckRSfmg9UveznRqwEvNN8f1JytmGGh7lFH1sAGWKahhz6JqyL6Z Tc12H/PX+VOw02/qVGw6CxdcUKSUvWl3ExzoyNdLM7L2G5jp2oZe60GnF4l64axilgmy zIPOBXizNC+jLKmEtw8QYVAfXPf0wj3fVVI3rNWq+hAOJHaaEBgFNR1gxj1HyxRnZXDc RjjQ==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@bootlin.com header.s=gm1 header.b=fAROkT0H; 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-84896-linux.lists.archive=gmail.com@vger.kernel.org designates 2604:1380:4601:e00::3 as permitted sender) smtp.mailfrom="linux-kernel+bounces-84896-linux.lists.archive=gmail.com@vger.kernel.org"; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=bootlin.com Return-Path: Received: from am.mirrors.kernel.org (am.mirrors.kernel.org. [2604:1380:4601:e00::3]) by mx.google.com with ESMTPS id r15-20020a056402234f00b00565af2eb331si617598eda.89.2024.02.28.03.43.30 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 28 Feb 2024 03:43:30 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-84896-linux.lists.archive=gmail.com@vger.kernel.org designates 2604:1380:4601:e00::3 as permitted sender) client-ip=2604:1380:4601:e00::3; Authentication-Results: mx.google.com; dkim=pass header.i=@bootlin.com header.s=gm1 header.b=fAROkT0H; 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-84896-linux.lists.archive=gmail.com@vger.kernel.org designates 2604:1380:4601:e00::3 as permitted sender) smtp.mailfrom="linux-kernel+bounces-84896-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 am.mirrors.kernel.org (Postfix) with ESMTPS id 228561F27020 for ; Wed, 28 Feb 2024 11:33:38 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id ABDF815A4B1; Wed, 28 Feb 2024 11:28:30 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b="fAROkT0H" Received: from relay8-d.mail.gandi.net (relay8-d.mail.gandi.net [217.70.183.201]) (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 866CE14EFC9; Wed, 28 Feb 2024 11:28:26 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=217.70.183.201 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1709119709; cv=none; b=IoKWXCiHZs4i08JHjrWnJKmOX7NInD74caILRo5bDmbk/DGMVrrdAajIyiRUXw9YzcBG/go1yA2xADDdlT1nknY1EJ9oTTL/WUJmg/WFYdP3DIenbPhmppBD9etBA0p0NpZi+PKQV/3eVQFTHrXGAWvxsTmWAzZJP87sIaX2gGs= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1709119709; c=relaxed/simple; bh=U2lbS9LDrBJq41Jr4wQmSyBLCS56Kq+xmsOSxI9mx1M=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=VB2uBnFBMIG8Ycw0W6h01rWuPXe8vkoMMcPfUAaEPtozThQsKL9imTHT1swAL1GsxZj4ge5hiU1B2hVKAOXJrs9icwMjU3o27RUqvuv0Qvp2mYf1mFZtaoBnhTCnAMfdYGXbkh/WQFlMuI7vwboKLgW/adr1akaejIh3Ksp7fuQ= 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=fAROkT0H; arc=none smtp.client-ip=217.70.183.201 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 5B3F91BF213; Wed, 28 Feb 2024 11:28:24 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=gm1; t=1709119705; 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=It/BSKt5Sbfkf+TU6yukAJhR+S2DFSVZHDKVJ3bhbAM=; b=fAROkT0Hljn5SK22F8DzfJSaVfYf9hwl7TSS6FLJHagWJICZGEGoCBYro5wdyTEQGg5sex PfWvQrkyVSCbrrwBZjYE7fD+upJ0pPOiyWnHDdEiJsWbavgEHjCCOqgcZdPFV8EgLOApt9 VVwdTwG+A9gSrjUw3sWqcrVUHJG6djYJRnLDooJ1+1eA7J30kH5tIfKIeDCwFGCTCyOKDS KaJ7q/7J/+3Xw20SGCgO1si1njCcnboMtg4X7xpGHJVqqHj+YdFRezhjwLTW11up2gichH B9M5I+Vyr5UHay46vfBmjJsNG+3LZ6GrpC2tLJbDnV4TGMcBTL10/KIYLPa7TQ== From: =?utf-8?q?Th=C3=A9o_Lebrun?= Date: Wed, 28 Feb 2024 12:28:17 +0100 Subject: [PATCH v2 19/30] 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: <20240228-mbly-gpio-v2-19-3ba757474006@bootlin.com> References: <20240228-mbly-gpio-v2-0-3ba757474006@bootlin.com> In-Reply-To: <20240228-mbly-gpio-v2-0-3ba757474006@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.13.0 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 | 54 ++++++++++++++++++++----------- 2 files changed, 37 insertions(+), 19 deletions(-) diff --git a/drivers/gpio/gpio-nomadik.c b/drivers/gpio/gpio-nomadik.c index fb821a9b6c5f..b7d76cc901dc 100644 --- a/drivers/gpio/gpio-nomadik.c +++ b/drivers/gpio/gpio-nomadik.c @@ -519,7 +519,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_dev); chip->parent = gpio_dev; diff --git a/drivers/pinctrl/nomadik/pinctrl-nomadik.c b/drivers/pinctrl/nomadik/pinctrl-nomadik.c index b74378302229..5633f0ec2715 100644 --- a/drivers/pinctrl/nomadik/pinctrl-nomadik.c +++ b/drivers/pinctrl/nomadik/pinctrl-nomadik.c @@ -531,25 +531,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; @@ -905,8 +913,18 @@ static int nmk_pmx_set(struct pinctrl_dev *pctldev, unsigned int function, * switching to the ALT C function. */ for (i = 0; i < g->grp.npins; i++) { - unsigned int bit = g->grp.pins[i] % NMK_GPIO_PER_CHIP; - slpm[g->grp.pins[i] / NMK_GPIO_PER_CHIP] &= ~BIT(bit); + struct nmk_gpio_chip *nmk_chip; + unsigned int bit; + + 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", + g->grp.pins[i], g->grp.name, i); + goto out_pre_slpm_init; + } + + slpm[nmk_chip->bank] &= ~BIT(bit); } nmk_gpio_glitch_slpm_init(slpm); } @@ -915,7 +933,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", @@ -926,7 +944,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, @@ -957,17 +974,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; @@ -985,10 +1003,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); @@ -998,11 +1017,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 */ } @@ -1043,7 +1062,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); @@ -1101,7 +1120,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.44.0