{"id":2228710,"url":"http://patchwork.ozlabs.org/api/patches/2228710/?format=json","web_url":"http://patchwork.ozlabs.org/project/linux-gpio/patch/20260427-gpio-mmio-more-v3-3-fe1882351424@kernel.org/","project":{"id":42,"url":"http://patchwork.ozlabs.org/api/projects/42/?format=json","name":"Linux GPIO development","link_name":"linux-gpio","list_id":"linux-gpio.vger.kernel.org","list_email":"linux-gpio@vger.kernel.org","web_url":"","scm_url":"","webscm_url":"","list_archive_url":"","list_archive_url_format":"","commit_url_format":""},"msgid":"<20260427-gpio-mmio-more-v3-3-fe1882351424@kernel.org>","list_archive_url":null,"date":"2026-04-27T08:47:59","name":"[v3,3/3] gpio: altera: Use generic MMIO GPIO","commit_ref":null,"pull_url":null,"state":"new","archived":false,"hash":"69fd2454c1354f1bad5298ae59ff9c90ab10787d","submitter":{"id":92050,"url":"http://patchwork.ozlabs.org/api/people/92050/?format=json","name":"Linus Walleij","email":"linusw@kernel.org"},"delegate":null,"mbox":"http://patchwork.ozlabs.org/project/linux-gpio/patch/20260427-gpio-mmio-more-v3-3-fe1882351424@kernel.org/mbox/","series":[{"id":501608,"url":"http://patchwork.ozlabs.org/api/series/501608/?format=json","web_url":"http://patchwork.ozlabs.org/project/linux-gpio/list/?series=501608","date":"2026-04-27T08:47:59","name":"gpio: Use generic MMIO GPIO some more","version":3,"mbox":"http://patchwork.ozlabs.org/series/501608/mbox/"}],"comments":"http://patchwork.ozlabs.org/api/patches/2228710/comments/","check":"pending","checks":"http://patchwork.ozlabs.org/api/patches/2228710/checks/","tags":{},"related":[],"headers":{"Return-Path":"\n <linux-gpio+bounces-35543-incoming=patchwork.ozlabs.org@vger.kernel.org>","X-Original-To":["incoming@patchwork.ozlabs.org","linux-gpio@vger.kernel.org"],"Delivered-To":"patchwork-incoming@legolas.ozlabs.org","Authentication-Results":["legolas.ozlabs.org;\n\tdkim=pass (2048-bit key;\n unprotected) header.d=kernel.org header.i=@kernel.org header.a=rsa-sha256\n header.s=k20201202 header.b=mwOKvHKW;\n\tdkim-atps=neutral","legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org\n (client-ip=104.64.211.4; helo=sin.lore.kernel.org;\n envelope-from=linux-gpio+bounces-35543-incoming=patchwork.ozlabs.org@vger.kernel.org;\n receiver=patchwork.ozlabs.org)","smtp.subspace.kernel.org;\n\tdkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org\n header.b=\"mwOKvHKW\"","smtp.subspace.kernel.org;\n arc=none smtp.client-ip=10.30.226.201"],"Received":["from sin.lore.kernel.org (sin.lore.kernel.org [104.64.211.4])\n\t(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n\t key-exchange x25519 server-signature ECDSA (secp384r1) server-digest SHA384)\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4g3y056hM7z1yJX\n\tfor <incoming@patchwork.ozlabs.org>; Mon, 27 Apr 2026 18:48:37 +1000 (AEST)","from smtp.subspace.kernel.org (conduit.subspace.kernel.org\n [100.90.174.1])\n\tby sin.lore.kernel.org (Postfix) with ESMTP id DE857300722F\n\tfor <incoming@patchwork.ozlabs.org>; Mon, 27 Apr 2026 08:48:05 +0000 (UTC)","from localhost.localdomain (localhost.localdomain [127.0.0.1])\n\tby smtp.subspace.kernel.org (Postfix) with ESMTP id 8745D39901A;\n\tMon, 27 Apr 2026 08:48:05 +0000 (UTC)","from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org\n [10.30.226.201])\n\t(using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits))\n\t(No client certificate requested)\n\tby smtp.subspace.kernel.org (Postfix) with ESMTPS id 487373A0E80\n\tfor <linux-gpio@vger.kernel.org>; Mon, 27 Apr 2026 08:48:05 +0000 (UTC)","by smtp.kernel.org (Postfix) with ESMTPSA id 2EE72C19425;\n\tMon, 27 Apr 2026 08:48:04 +0000 (UTC)"],"ARC-Seal":"i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116;\n\tt=1777279685; cv=none;\n b=G+VMupU09uN1sAW581Knv3dMuz66uIl4RvnuaPW1U9QcRLwiRnChhNV5kANzRPcjVif4Oce4NSjHJkdRsac3qQ01T+A5JHtd3fEmnlbGywFt2q/JDOZ67Ouqjjt7g9tk1Jt9STL5k73txvC8+VbgA5ON0//KwVwnFXcOZKEz0GI=","ARC-Message-Signature":"i=1; a=rsa-sha256; d=subspace.kernel.org;\n\ts=arc-20240116; t=1777279685; c=relaxed/simple;\n\tbh=vYzKUz2+NwrtujqUJ8eP37nR2g5rrP5ruXmxekhH8fA=;\n\th=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References:\n\t In-Reply-To:To:Cc;\n b=iHBX4uodoemml/AR6Q1pq9Mlx5HkUM9tp9Qpm0BpCC5uD0hOE1uQpN00X7j9q0xYJTlOuikUwGD55Xm4CFTdl3UwwoO8biZE5csmgwyRJRefFNJmBrPg/iAq+ng8jvXkexBjKl/C7m2mFdxS1lq3BWnch6A1iyDhk1ZaoLmelhA=","ARC-Authentication-Results":"i=1; smtp.subspace.kernel.org;\n dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org\n header.b=mwOKvHKW; arc=none smtp.client-ip=10.30.226.201","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org;\n\ts=k20201202; t=1777279685;\n\tbh=vYzKUz2+NwrtujqUJ8eP37nR2g5rrP5ruXmxekhH8fA=;\n\th=From:Date:Subject:References:In-Reply-To:To:Cc:From;\n\tb=mwOKvHKWzj4M13RbXaJ8Cz21OImyIGz+B9wV7EnA2CFvSx87w4xxXWl6rHDwMfze9\n\t zAgOws/KyA200si1rex1wMwjkSnJAruZ5bHnTBM+Zz2qNVrRIDQHIa7f4NPaydmYz6\n\t 5VnIICItGjVtlaCSR1Gy2Lyc4g5io+n4Lvko2qR8d4X9p7eHI+weDSa5mAt0PbiAkn\n\t dNypyfQJG/tskNitIfo4cLz80BVXCqXlHZrIU82MAYMcww8L8Osg4r8A+CaijGJgYC\n\t i234PawkLh7Q30WEjYCslSEaJk1ol1pDM2cuT2yuCymHbuiNvKTnWRfCWCHEoz7V/h\n\t i6sBP29KN2cCQ==","From":"Linus Walleij <linusw@kernel.org>","Date":"Mon, 27 Apr 2026 10:47:59 +0200","Subject":"[PATCH v3 3/3] gpio: altera: Use generic MMIO GPIO","Precedence":"bulk","X-Mailing-List":"linux-gpio@vger.kernel.org","List-Id":"<linux-gpio.vger.kernel.org>","List-Subscribe":"<mailto:linux-gpio+subscribe@vger.kernel.org>","List-Unsubscribe":"<mailto:linux-gpio+unsubscribe@vger.kernel.org>","MIME-Version":"1.0","Content-Type":"text/plain; charset=\"utf-8\"","Content-Transfer-Encoding":"7bit","Message-Id":"<20260427-gpio-mmio-more-v3-3-fe1882351424@kernel.org>","References":"<20260427-gpio-mmio-more-v3-0-fe1882351424@kernel.org>","In-Reply-To":"<20260427-gpio-mmio-more-v3-0-fe1882351424@kernel.org>","To":"Bartosz Golaszewski <brgl@bgdev.pl>,\n Mun Yew Tham <mun.yew.tham@intel.com>","Cc":"linux-gpio@vger.kernel.org, Linus Walleij <linusw@kernel.org>","X-Mailer":"b4 0.15.2"},"content":"From: Linus Walleij <linus.walleij@linaro.org>\n\nIf we use the generic GPIO lib for MMIO in the Altera driver\nwe do not only cut down on the code, we also get get/set_multiple\nfor free.\n\nKeep the local raw spinlock instead of reusing the bgpio spinlock\nbecause it makes the gpiochip and irqchip nicely orthogonal.\n\nSigned-off-by: Linus Walleij <linus.walleij@linaro.org>\n---\n drivers/gpio/Kconfig       |   1 +\n drivers/gpio/gpio-altera.c | 109 +++++++++++----------------------------------\n 2 files changed, 28 insertions(+), 82 deletions(-)","diff":"diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig\nindex 020e51e30317..0e8aad3d4b8f 100644\n--- a/drivers/gpio/Kconfig\n+++ b/drivers/gpio/Kconfig\n@@ -156,6 +156,7 @@ config GPIO_74XX_MMIO\n \n config GPIO_ALTERA\n \ttristate \"Altera GPIO\"\n+\tselect GPIO_GENERIC\n \tselect GPIOLIB_IRQCHIP\n \thelp\n \t  Say Y or M here to build support for the Altera PIO device.\ndiff --git a/drivers/gpio/gpio-altera.c b/drivers/gpio/gpio-altera.c\nindex cb04700c8ccd..fe144360a88d 100644\n--- a/drivers/gpio/gpio-altera.c\n+++ b/drivers/gpio/gpio-altera.c\n@@ -17,6 +17,7 @@\n #include <linux/types.h>\n \n #include <linux/gpio/driver.h>\n+#include <linux/gpio/generic.h>\n \n #define ALTERA_GPIO_MAX_NGPIO\t\t32\n #define ALTERA_GPIO_DATA\t\t0x0\n@@ -26,7 +27,7 @@\n \n /**\n * struct altera_gpio_chip\n-* @gc\t\t\t: GPIO chip structure.\n+* @chip\t\t\t: Generic GPIO chip structure.\n * @regs\t\t\t: memory mapped IO address for the controller registers.\n * @gpio_lock\t\t: synchronization lock so that new irq/set/get requests\n *\t\t\t  will be blocked until the current one completes.\n@@ -34,7 +35,7 @@\n *\t\t\t  (rising, falling, both, high)\n */\n struct altera_gpio_chip {\n-\tstruct gpio_chip gc;\n+\tstruct gpio_generic_chip chip;\n \tvoid __iomem *regs;\n \traw_spinlock_t gpio_lock;\n \tint interrupt_trigger;\n@@ -106,72 +107,6 @@ static unsigned int altera_gpio_irq_startup(struct irq_data *d)\n \treturn 0;\n }\n \n-static int altera_gpio_get(struct gpio_chip *gc, unsigned offset)\n-{\n-\tstruct altera_gpio_chip *altera_gc = gpiochip_get_data(gc);\n-\n-\treturn !!(readl(altera_gc->regs + ALTERA_GPIO_DATA) & BIT(offset));\n-}\n-\n-static int altera_gpio_set(struct gpio_chip *gc, unsigned int offset, int value)\n-{\n-\tstruct altera_gpio_chip *altera_gc = gpiochip_get_data(gc);\n-\tunsigned long flags;\n-\tunsigned int data_reg;\n-\n-\traw_spin_lock_irqsave(&altera_gc->gpio_lock, flags);\n-\tdata_reg = readl(altera_gc->regs + ALTERA_GPIO_DATA);\n-\tif (value)\n-\t\tdata_reg |= BIT(offset);\n-\telse\n-\t\tdata_reg &= ~BIT(offset);\n-\twritel(data_reg, altera_gc->regs + ALTERA_GPIO_DATA);\n-\traw_spin_unlock_irqrestore(&altera_gc->gpio_lock, flags);\n-\n-\treturn 0;\n-}\n-\n-static int altera_gpio_direction_input(struct gpio_chip *gc, unsigned offset)\n-{\n-\tstruct altera_gpio_chip *altera_gc = gpiochip_get_data(gc);\n-\tunsigned long flags;\n-\tunsigned int gpio_ddr;\n-\n-\traw_spin_lock_irqsave(&altera_gc->gpio_lock, flags);\n-\t/* Set pin as input, assumes software controlled IP */\n-\tgpio_ddr = readl(altera_gc->regs + ALTERA_GPIO_DIR);\n-\tgpio_ddr &= ~BIT(offset);\n-\twritel(gpio_ddr, altera_gc->regs + ALTERA_GPIO_DIR);\n-\traw_spin_unlock_irqrestore(&altera_gc->gpio_lock, flags);\n-\n-\treturn 0;\n-}\n-\n-static int altera_gpio_direction_output(struct gpio_chip *gc,\n-\t\tunsigned offset, int value)\n-{\n-\tstruct altera_gpio_chip *altera_gc = gpiochip_get_data(gc);\n-\tunsigned long flags;\n-\tunsigned int data_reg, gpio_ddr;\n-\n-\traw_spin_lock_irqsave(&altera_gc->gpio_lock, flags);\n-\t/* Sets the GPIO value */\n-\tdata_reg = readl(altera_gc->regs + ALTERA_GPIO_DATA);\n-\tif (value)\n-\t\tdata_reg |= BIT(offset);\n-\telse\n-\t\tdata_reg &= ~BIT(offset);\n-\twritel(data_reg, altera_gc->regs + ALTERA_GPIO_DATA);\n-\n-\t/* Set pin as output, assumes software controlled IP */\n-\tgpio_ddr = readl(altera_gc->regs + ALTERA_GPIO_DIR);\n-\tgpio_ddr |= BIT(offset);\n-\twritel(gpio_ddr, altera_gc->regs + ALTERA_GPIO_DIR);\n-\traw_spin_unlock_irqrestore(&altera_gc->gpio_lock, flags);\n-\n-\treturn 0;\n-}\n-\n static void altera_gpio_irq_edge_handler(struct irq_desc *desc)\n {\n \tstruct gpio_chip *gc = irq_desc_get_handler_data(desc);\n@@ -231,9 +166,11 @@ static const struct irq_chip altera_gpio_irq_chip = {\n \n static int altera_gpio_probe(struct platform_device *pdev)\n {\n+\tstruct gpio_generic_chip_config config;\n \tstruct device *dev = &pdev->dev;\n \tint reg, ret;\n \tstruct altera_gpio_chip *altera_gc;\n+\tstruct gpio_generic_chip *chip;\n \tstruct gpio_chip *gc;\n \tstruct gpio_irq_chip *girq;\n \tint mapped_irq;\n@@ -244,7 +181,26 @@ static int altera_gpio_probe(struct platform_device *pdev)\n \n \traw_spin_lock_init(&altera_gc->gpio_lock);\n \n-\tgc = &altera_gc->gc;\n+\taltera_gc->regs = devm_platform_ioremap_resource(pdev, 0);\n+\tif (IS_ERR(altera_gc->regs))\n+\t\treturn dev_err_probe(dev, PTR_ERR(altera_gc->regs),\n+\t\t\t\t     \"failed to ioremap memory resource\\n\");\n+\n+\tchip = &altera_gc->chip;\n+\n+\tconfig = (struct gpio_generic_chip_config) {\n+\t\t.dev = dev,\n+\t\t.sz = 4,\n+\t\t.dat = altera_gc->regs + ALTERA_GPIO_DATA,\n+\t\t.set = altera_gc->regs + ALTERA_GPIO_DATA,\n+\t\t.dirout = altera_gc->regs + ALTERA_GPIO_DIR,\n+\t};\n+\n+\tret = gpio_generic_chip_init(chip, &config);\n+\tif (ret)\n+\t\treturn dev_err_probe(dev, ret, \"unable to init generic GPIO\\n\");\n+\n+\tgc = &chip->gc;\n \n \tif (device_property_read_u32(dev, \"altr,ngpio\", &reg))\n \t\t/* By default assume maximum ngpio */\n@@ -259,22 +215,11 @@ static int altera_gpio_probe(struct platform_device *pdev)\n \t\tgc->ngpio = ALTERA_GPIO_MAX_NGPIO;\n \t}\n \n-\tgc->direction_input\t= altera_gpio_direction_input;\n-\tgc->direction_output\t= altera_gpio_direction_output;\n-\tgc->get\t\t= altera_gpio_get;\n-\tgc->set\t\t= altera_gpio_set;\n-\tgc->owner\t\t= THIS_MODULE;\n-\tgc->parent\t\t= &pdev->dev;\n-\tgc->base\t\t= -1;\n-\n+\tgc->base = -1;\n \tgc->label = devm_kasprintf(dev, GFP_KERNEL, \"%pfw\", dev_fwnode(dev));\n \tif (!gc->label)\n \t\treturn -ENOMEM;\n \n-\taltera_gc->regs = devm_platform_ioremap_resource(pdev, 0);\n-\tif (IS_ERR(altera_gc->regs))\n-\t\treturn dev_err_probe(dev, PTR_ERR(altera_gc->regs), \"failed to ioremap memory resource\\n\");\n-\n \tmapped_irq = platform_get_irq_optional(pdev, 0);\n \tif (mapped_irq < 0)\n \t\tgoto skip_irq;\n@@ -303,7 +248,7 @@ static int altera_gpio_probe(struct platform_device *pdev)\n \tgirq->parents[0] = mapped_irq;\n \n skip_irq:\n-\tret = devm_gpiochip_add_data(dev, &altera_gc->gc, altera_gc);\n+\tret = devm_gpiochip_add_data(dev, gc, altera_gc);\n \tif (ret) {\n \t\tdev_err(&pdev->dev, \"Failed adding memory mapped gpiochip\\n\");\n \t\treturn ret;\n","prefixes":["v3","3/3"]}