{"id":2221031,"url":"http://patchwork.ozlabs.org/api/1.1/patches/2221031/?format=json","web_url":"http://patchwork.ozlabs.org/project/linux-gpio/patch/20260408-dev-b4-aaeon-mcu-driver-v5-4-ad98bd481668@bootlin.com/","project":{"id":42,"url":"http://patchwork.ozlabs.org/api/1.1/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":""},"msgid":"<20260408-dev-b4-aaeon-mcu-driver-v5-4-ad98bd481668@bootlin.com>","date":"2026-04-08T17:21:57","name":"[v5,4/5] gpio: aaeon: Add GPIO driver for SRG-IMX8P MCU","commit_ref":null,"pull_url":null,"state":"new","archived":false,"hash":"392ff5f4bd502a6d7c29b985c0cd0061ac499050","submitter":{"id":82054,"url":"http://patchwork.ozlabs.org/api/1.1/people/82054/?format=json","name":"Thomas Perrot (Schneider Electric)","email":"thomas.perrot@bootlin.com"},"delegate":null,"mbox":"http://patchwork.ozlabs.org/project/linux-gpio/patch/20260408-dev-b4-aaeon-mcu-driver-v5-4-ad98bd481668@bootlin.com/mbox/","series":[{"id":499169,"url":"http://patchwork.ozlabs.org/api/1.1/series/499169/?format=json","web_url":"http://patchwork.ozlabs.org/project/linux-gpio/list/?series=499169","date":"2026-04-08T17:21:53","name":"Add support for AAEON SRG-IMX8P MCU","version":5,"mbox":"http://patchwork.ozlabs.org/series/499169/mbox/"}],"comments":"http://patchwork.ozlabs.org/api/patches/2221031/comments/","check":"pending","checks":"http://patchwork.ozlabs.org/api/patches/2221031/checks/","tags":{},"headers":{"Return-Path":"\n <linux-gpio+bounces-34898-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=bootlin.com header.i=@bootlin.com header.a=rsa-sha256\n header.s=dkim header.b=E66nM9my;\n\tdkim-atps=neutral","legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org\n (client-ip=2600:3c09:e001:a7::12fc:5321; helo=sto.lore.kernel.org;\n envelope-from=linux-gpio+bounces-34898-incoming=patchwork.ozlabs.org@vger.kernel.org;\n receiver=patchwork.ozlabs.org)","smtp.subspace.kernel.org;\n\tdkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com\n header.b=\"E66nM9my\"","smtp.subspace.kernel.org;\n arc=none smtp.client-ip=185.246.85.4","smtp.subspace.kernel.org;\n dmarc=pass (p=reject dis=none) header.from=bootlin.com","smtp.subspace.kernel.org;\n spf=pass smtp.mailfrom=bootlin.com"],"Received":["from sto.lore.kernel.org (sto.lore.kernel.org\n [IPv6:2600:3c09:e001:a7::12fc:5321])\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 4frVJS0QXgz1xv0\n\tfor <incoming@patchwork.ozlabs.org>; Thu, 09 Apr 2026 03:23:04 +1000 (AEST)","from smtp.subspace.kernel.org (conduit.subspace.kernel.org\n [100.90.174.1])\n\tby sto.lore.kernel.org (Postfix) with ESMTP id D96A8301DA73\n\tfor <incoming@patchwork.ozlabs.org>; Wed,  8 Apr 2026 17:22:49 +0000 (UTC)","from localhost.localdomain (localhost.localdomain [127.0.0.1])\n\tby smtp.subspace.kernel.org (Postfix) with ESMTP id 7634A3D88F6;\n\tWed,  8 Apr 2026 17:22:34 +0000 (UTC)","from smtpout-03.galae.net (smtpout-03.galae.net [185.246.85.4])\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 A22F73D88E1;\n\tWed,  8 Apr 2026 17:22:31 +0000 (UTC)","from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233])\n\tby smtpout-03.galae.net (Postfix) with ESMTPS id 47E504E42971;\n\tWed,  8 Apr 2026 17:22:30 +0000 (UTC)","from mail.galae.net (mail.galae.net [212.83.136.155])\n\tby smtpout-01.galae.net (Postfix) with ESMTPS id 1C8F2603CE;\n\tWed,  8 Apr 2026 17:22:30 +0000 (UTC)","from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon)\n with ESMTPSA id 48C9D1045017E;\n\tWed,  8 Apr 2026 19:22:26 +0200 (CEST)"],"ARC-Seal":"i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116;\n\tt=1775668954; cv=none;\n b=Y3s7lqlbYYjr/gC1ob1+1u2/VJ4LsRedNOhmipRr3oqslMxkzSuPWMI88kijTQsMiGNrnG0dsU9X03sbQmTbhPpRTXX0RJh7NxcYxJOQddxK/OP+xqp4Rc+JLuxSaaqnyTFiqndvi+3aF7vb+WWObJ52vAktu9WIZUsNVhA9AMo=","ARC-Message-Signature":"i=1; a=rsa-sha256; d=subspace.kernel.org;\n\ts=arc-20240116; t=1775668954; c=relaxed/simple;\n\tbh=v9xa34NsM/733dZZsF2EFxXDKrVTDCSNlIjmbFFkKS4=;\n\th=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References:\n\t In-Reply-To:To:Cc;\n b=pODMWUA53cBEeGAU068JjaDAt9aXhFuuT7WeqcBuasPo/e2BmY61uP2mj01Z8kv9PwkUS4iWyC9dcccRzEDl+ocF3kH+14SZheN0dsLmKn+ylP6/jzCXcxaVljNQUsAsFU8OqtEl8J1ZN7dmsjWYImERGcrxYRQo+DfTHW9+eLs=","ARC-Authentication-Results":"i=1; smtp.subspace.kernel.org;\n dmarc=pass (p=reject dis=none) header.from=bootlin.com;\n spf=pass smtp.mailfrom=bootlin.com;\n dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com\n header.b=E66nM9my; arc=none smtp.client-ip=185.246.85.4","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim;\n\tt=1775668948; h=from:subject:date:message-id:to:cc:mime-version:content-type:\n\t content-transfer-encoding:in-reply-to:references;\n\tbh=uGaHyLmHBgoLoCNYKyPIGDrV5F1S4zCIqJmASlnBZ3A=;\n\tb=E66nM9myFRwMfkr0OM0M9oQJpaBhsTX5ozHVjqqf4ks+dpLVvMFwfXiublDGikuVlwG6uA\n\tVZUfqBR3wO+PV1Xkp1reGxr4H3qje8p7D2b/QhEu9VsbpR3L+QRUHnYI23YKuTZHB3spPQ\n\tL1C/0rDu0LuMqSPSNyyZVnxB946hsdMkra1KC0llYM5WUjaAGIam2mwSJomYWsAijnw0t9\n\txZiqmLo6UdQ+V4cd0cfzsCAAh9/1Zsd0f/roAyBG6tKWTGQmG4tS2/kbmccWqJob9tuEx1\n\tnMjPuxr40nkhY9kmxIKcrLCjUi6pv7q8ryNs2dgrw+9ekipdna0KJ/ShsE1hgA==","From":"\"Thomas Perrot (Schneider Electric)\" <thomas.perrot@bootlin.com>","Date":"Wed, 08 Apr 2026 19:21:57 +0200","Subject":"[PATCH v5 4/5] gpio: aaeon: Add GPIO driver for SRG-IMX8P MCU","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":"8bit","Message-Id":"<20260408-dev-b4-aaeon-mcu-driver-v5-4-ad98bd481668@bootlin.com>","References":"<20260408-dev-b4-aaeon-mcu-driver-v5-0-ad98bd481668@bootlin.com>","In-Reply-To":"<20260408-dev-b4-aaeon-mcu-driver-v5-0-ad98bd481668@bootlin.com>","To":"Rob Herring <robh@kernel.org>, Krzysztof Kozlowski <krzk+dt@kernel.org>,\n  Conor Dooley <conor+dt@kernel.org>, Linus Walleij <linusw@kernel.org>,\n  Bartosz Golaszewski <brgl@kernel.org>, Shawn Guo <shawnguo@kernel.org>,\n  Sascha Hauer <s.hauer@pengutronix.de>,\n  Pengutronix Kernel Team <kernel@pengutronix.de>,\n  Fabio Estevam <festevam@gmail.com>,\n =?utf-8?b?SsOpcsOpbWllIERhdXRoZXJpYmVz?= <jeremie.dautheribes@bootlin.com>,\n  Wim Van Sebroeck <wim@linux-watchdog.org>,\n  Guenter Roeck <linux@roeck-us.net>, Lee Jones <lee@kernel.org>","Cc":"devicetree@vger.kernel.org, linux-kernel@vger.kernel.org,\n linux-gpio@vger.kernel.org, imx@lists.linux.dev,\n linux-arm-kernel@lists.infradead.org, linux-watchdog@vger.kernel.org,\n Thomas Petazzoni <thomas.petazzoni@bootlin.com>,\n Miquel Raynal <miquel.raynal@bootlin.com>,\n \"Thomas Perrot (Schneider Electric)\" <thomas.perrot@bootlin.com>,\n Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>","X-Mailer":"b4 0.14.3","X-Developer-Signature":"v=1; a=openpgp-sha256; l=9293;\n i=thomas.perrot@bootlin.com; h=from:subject:message-id;\n bh=v9xa34NsM/733dZZsF2EFxXDKrVTDCSNlIjmbFFkKS4=;\n b=owEB7QES/pANAwAKAZ/ACwVx/grtAcsmYgBp1o7DXswAZEWgkNODBVIH4qsAc1QkgxUO5Q5iN\n +k/7iWtP/OJAbMEAAEKAB0WIQSHQHfGpqMKIwOoEiGfwAsFcf4K7QUCadaOwwAKCRCfwAsFcf4K\n 7WfmC/wKcHMFCKPQ5kL5r7vwM0pN9xQ3Fvuk5oY6CP2SJpPTh9F4YRC5lc/C31PT2zHtfIXHjFs\n efeHEsxOFDu5vKRo6RgE0TtdpBiNBsW1ODJ2wTipdM2kM5J/1yjmh0FzWkjPwXqqmMgoviCNceC\n C5VPvzzfNNsbv0bTyJf5cxe1a01kjeUtDSZqjVN+sF5yHLHPDDTW99tK5Z6b9YyHFA1Yoldvm2y\n +LEJa2beTrBJVbl1ci0QZcfQ7b/Q1pOVSxtgr8u7xBKLlxpiffTLFsEiXydXgQX7G5/QkxlFGdv\n XAmmPmks6d8U+7/hKLmCtHoQR7LtqoT26EpALsC/q2pPLabd3i5njh+Xvpp4odGuBZGd2g+g9cb\n 184wNgOxKwkN7z7uU2FZ9pa6CjMMkPW4aPcZZoTRgpDwVl3WUyppqnVaNfI1iZ+SnMYStfo/gD/\n 0YRI2eiMFtx3lTDrHf3i269NJHjfpIlhqSXmeCj63E0xcG3GrsPFcZhvGG20+bkC7dGzc=","X-Developer-Key":"i=thomas.perrot@bootlin.com; a=openpgp;\n fpr=874077C6A6A30A2303A812219FC00B0571FE0AED","X-Last-TLS-Session-Version":"TLSv1.3"},"content":"Add GPIO driver for the Aaeon SRG-IMX8P embedded controller. This\ndriver supports 7 GPO (General Purpose Output) pins and 12 GPIO pins\nthat can be configured as inputs or outputs.\n\nThe driver implements proper state management for GPO pins (which are\noutput-only) and full direction control for GPIO pins. During probe,\nall pins are reset to a known state (GPOs low, GPIOs as inputs) to\nprevent undefined behavior across system reboots, as the MCU does not\nreset GPIO states on soft reboot.\n\nCo-developed-by: Jérémie Dautheribes (Schneider Electric) <jeremie.dautheribes@bootlin.com>\nSigned-off-by: Jérémie Dautheribes (Schneider Electric) <jeremie.dautheribes@bootlin.com>\nAcked-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>\nReviewed-by: Linus Walleij <linusw@kernel.org>\nSigned-off-by: Thomas Perrot (Schneider Electric) <thomas.perrot@bootlin.com>\n---\n MAINTAINERS                   |   1 +\n drivers/gpio/Kconfig          |   9 ++\n drivers/gpio/Makefile         |   1 +\n drivers/gpio/gpio-aaeon-mcu.c | 229 ++++++++++++++++++++++++++++++++++++++++++\n 4 files changed, 240 insertions(+)","diff":"diff --git a/MAINTAINERS b/MAINTAINERS\nindex f91b6a1826d0..2538f8c4bc14 100644\n--- a/MAINTAINERS\n+++ b/MAINTAINERS\n@@ -191,6 +191,7 @@ M:\tThomas Perrot <thomas.perrot@bootlin.com>\n R:\tJérémie Dautheribes <jeremie.dautheribes@bootlin.com>\n S:\tMaintained\n F:\tDocumentation/devicetree/bindings/mfd/aaeon,srg-imx8p-mcu.yaml\n+F:\tdrivers/gpio/gpio-aaeon-mcu.c\n F:\tdrivers/mfd/aaeon-mcu.c\n F:\tinclude/linux/mfd/aaeon-mcu.h\n \ndiff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig\nindex c74da29253e8..4b37b5a15958 100644\n--- a/drivers/gpio/Kconfig\n+++ b/drivers/gpio/Kconfig\n@@ -157,6 +157,15 @@ config GPIO_74XX_MMIO\n \t    8 bits:\t74244 (Input), 74273 (Output)\n \t    16 bits:\t741624 (Input), 7416374 (Output)\n \n+config GPIO_AAEON_MCU\n+\ttristate \"Aaeon MCU GPIO support\"\n+\tdepends on MFD_AAEON_MCU\n+\thelp\n+\t  Select this option to enable GPIO support for the Aaeon SRG-IMX8P\n+\t  onboard MCU. This driver provides access to GPIO pins and GPO\n+\t  (General Purpose Output) pins controlled by the microcontroller.\n+\t  The driver handles both input and output configuration.\n+\n config GPIO_ALTERA\n \ttristate \"Altera GPIO\"\n \tselect GPIOLIB_IRQCHIP\ndiff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile\nindex 2421a8fd3733..1ba6318bc558 100644\n--- a/drivers/gpio/Makefile\n+++ b/drivers/gpio/Makefile\n@@ -29,6 +29,7 @@ obj-$(CONFIG_GPIO_104_IDI_48)\t\t+= gpio-104-idi-48.o\n obj-$(CONFIG_GPIO_104_IDIO_16)\t\t+= gpio-104-idio-16.o\n obj-$(CONFIG_GPIO_74X164)\t\t+= gpio-74x164.o\n obj-$(CONFIG_GPIO_74XX_MMIO)\t\t+= gpio-74xx-mmio.o\n+obj-$(CONFIG_GPIO_AAEON_MCU)\t\t+= gpio-aaeon-mcu.o\n obj-$(CONFIG_GPIO_ADNP)\t\t\t+= gpio-adnp.o\n obj-$(CONFIG_GPIO_ADP5520)\t\t+= gpio-adp5520.o\n obj-$(CONFIG_GPIO_ADP5585)\t\t+= gpio-adp5585.o\ndiff --git a/drivers/gpio/gpio-aaeon-mcu.c b/drivers/gpio/gpio-aaeon-mcu.c\nnew file mode 100644\nindex 000000000000..a37d3dc83795\n--- /dev/null\n+++ b/drivers/gpio/gpio-aaeon-mcu.c\n@@ -0,0 +1,229 @@\n+// SPDX-License-Identifier: GPL-2.0-or-later\n+/*\n+ * Aaeon MCU GPIO driver\n+ *\n+ * Copyright (C) 2026 Bootlin\n+ * Author: Jérémie Dautheribes <jeremie.dautheribes@bootlin.com>\n+ * Author: Thomas Perrot <thomas.perrot@bootlin.com>\n+ */\n+\n+#include <linux/bitops.h>\n+#include <linux/gpio/driver.h>\n+#include <linux/mfd/aaeon-mcu.h>\n+#include <linux/module.h>\n+#include <linux/platform_device.h>\n+#include <linux/regmap.h>\n+\n+#define AAEON_MCU_CONFIG_GPIO_INPUT\t0x69\n+#define AAEON_MCU_CONFIG_GPIO_OUTPUT\t0x6F\n+#define AAEON_MCU_READ_GPIO\t\t0x72\n+#define AAEON_MCU_WRITE_GPIO\t\t0x77\n+\n+#define AAEON_MCU_CONTROL_GPO\t\t0x6C\n+\n+#define MAX_GPIOS\t12\n+#define MAX_GPOS\t7\n+\n+struct aaeon_mcu_gpio {\n+\tstruct gpio_chip gc;\n+\tstruct regmap *regmap;\n+\tDECLARE_BITMAP(dir_in, MAX_GPOS + MAX_GPIOS);\n+\tDECLARE_BITMAP(gpo_state, MAX_GPOS);\n+};\n+\n+static int aaeon_mcu_gpio_config_input_cmd(struct aaeon_mcu_gpio *data,\n+\t\t\t\t\t   unsigned int offset)\n+{\n+\treturn regmap_write(data->regmap,\n+\t\t\t    AAEON_MCU_REG(AAEON_MCU_CONFIG_GPIO_INPUT, offset - 7),\n+\t\t\t    0);\n+}\n+\n+static int aaeon_mcu_gpo_set_cmd(struct aaeon_mcu_gpio *data, unsigned int offset, int value)\n+{\n+\treturn regmap_write(data->regmap,\n+\t\t\t    AAEON_MCU_REG(AAEON_MCU_CONTROL_GPO, offset + 1),\n+\t\t\t    !!value);\n+}\n+\n+static int aaeon_mcu_gpio_direction_input(struct gpio_chip *gc, unsigned int offset)\n+{\n+\tstruct aaeon_mcu_gpio *data = gpiochip_get_data(gc);\n+\tint ret;\n+\n+\tif (offset < MAX_GPOS) {\n+\t\tdev_err(gc->parent,\n+\t\t\t\"offset %d is a GPO (output-only) pin, cannot be configured as input\\n\",\n+\t\t\toffset);\n+\t\treturn -EOPNOTSUPP;\n+\t}\n+\n+\tret = aaeon_mcu_gpio_config_input_cmd(data, offset);\n+\tif (ret < 0)\n+\t\treturn ret;\n+\n+\t__set_bit(offset, data->dir_in);\n+\n+\treturn 0;\n+}\n+\n+static int aaeon_mcu_gpio_config_output_cmd(struct aaeon_mcu_gpio *data,\n+\t\t\t\t\t    unsigned int offset,\n+\t\t\t\t\t    int value)\n+{\n+\tint ret;\n+\n+\tret = regmap_write(data->regmap,\n+\t\t\t   AAEON_MCU_REG(AAEON_MCU_CONFIG_GPIO_OUTPUT, offset - 7),\n+\t\t\t   0);\n+\tif (ret < 0)\n+\t\treturn ret;\n+\n+\treturn regmap_write(data->regmap,\n+\t\t\t    AAEON_MCU_REG(AAEON_MCU_WRITE_GPIO, offset - 7),\n+\t\t\t    !!value);\n+}\n+\n+static int aaeon_mcu_gpio_direction_output(struct gpio_chip *gc, unsigned int offset, int value)\n+{\n+\tstruct aaeon_mcu_gpio *data = gpiochip_get_data(gc);\n+\tint ret;\n+\n+\tif (offset < MAX_GPOS) {\n+\t\tret = aaeon_mcu_gpo_set_cmd(data, offset, value);\n+\t\tif (ret)\n+\t\t\treturn ret;\n+\t\t__assign_bit(offset, data->gpo_state, value);\n+\t\treturn 0;\n+\t}\n+\n+\tret = aaeon_mcu_gpio_config_output_cmd(data, offset, value);\n+\tif (ret < 0)\n+\t\treturn ret;\n+\n+\t__clear_bit(offset, data->dir_in);\n+\n+\treturn 0;\n+}\n+\n+static int aaeon_mcu_gpio_get_direction(struct gpio_chip *gc, unsigned int offset)\n+{\n+\tstruct aaeon_mcu_gpio *data = gpiochip_get_data(gc);\n+\n+\treturn test_bit(offset, data->dir_in) ?\n+\t\tGPIO_LINE_DIRECTION_IN : GPIO_LINE_DIRECTION_OUT;\n+}\n+\n+static int aaeon_mcu_gpio_get(struct gpio_chip *gc, unsigned int offset)\n+{\n+\tstruct aaeon_mcu_gpio *data = gpiochip_get_data(gc);\n+\tunsigned int rsp;\n+\tint ret;\n+\n+\tif (offset < MAX_GPOS)\n+\t\treturn test_bit(offset, data->gpo_state);\n+\n+\tret = regmap_read(data->regmap,\n+\t\t\t  AAEON_MCU_REG(AAEON_MCU_READ_GPIO, offset - 7),\n+\t\t\t  &rsp);\n+\tif (ret < 0)\n+\t\treturn ret;\n+\n+\treturn rsp;\n+}\n+\n+static int aaeon_mcu_gpio_set_cmd(struct aaeon_mcu_gpio *data, unsigned int offset, int value)\n+{\n+\treturn regmap_write(data->regmap,\n+\t\t\t    AAEON_MCU_REG(AAEON_MCU_WRITE_GPIO, offset - 7),\n+\t\t\t    !!value);\n+}\n+\n+static int aaeon_mcu_gpio_set(struct gpio_chip *gc, unsigned int offset,\n+\t\t\t      int value)\n+{\n+\tstruct aaeon_mcu_gpio *data = gpiochip_get_data(gc);\n+\tint ret;\n+\n+\tif (offset >= MAX_GPOS)\n+\t\treturn aaeon_mcu_gpio_set_cmd(data, offset, value);\n+\n+\tret = aaeon_mcu_gpo_set_cmd(data, offset, value);\n+\tif (ret)\n+\t\treturn ret;\n+\t__assign_bit(offset, data->gpo_state, value);\n+\treturn 0;\n+}\n+\n+static const struct gpio_chip aaeon_mcu_chip = {\n+\t.label\t\t\t= \"gpio-aaeon-mcu\",\n+\t.owner\t\t\t= THIS_MODULE,\n+\t.get_direction\t\t= aaeon_mcu_gpio_get_direction,\n+\t.direction_input\t= aaeon_mcu_gpio_direction_input,\n+\t.direction_output\t= aaeon_mcu_gpio_direction_output,\n+\t.get\t\t\t= aaeon_mcu_gpio_get,\n+\t.set\t\t\t= aaeon_mcu_gpio_set,\n+\t.base\t\t\t= -1,\n+\t.ngpio\t\t\t= MAX_GPOS + MAX_GPIOS,\n+\t.can_sleep\t\t= true,\n+};\n+\n+static void aaeon_mcu_gpio_reset(struct aaeon_mcu_gpio *data, struct device *dev)\n+{\n+\tunsigned int i;\n+\tint ret;\n+\n+\t/* Reset all GPOs */\n+\tfor (i = 0; i < MAX_GPOS; i++) {\n+\t\tret = aaeon_mcu_gpo_set_cmd(data, i, 0);\n+\t\tif (ret < 0)\n+\t\t\tdev_warn(dev, \"Failed to reset GPO %u state: %d\\n\", i, ret);\n+\t\t__clear_bit(i, data->dir_in);\n+\t}\n+\n+\t/* Reset all GPIOs */\n+\tfor (i = MAX_GPOS; i < MAX_GPOS + MAX_GPIOS; i++) {\n+\t\tret = aaeon_mcu_gpio_config_input_cmd(data, i);\n+\t\tif (ret < 0)\n+\t\t\tdev_warn(dev, \"Failed to reset GPIO %u state: %d\\n\", i, ret);\n+\t\t__set_bit(i, data->dir_in);\n+\t}\n+}\n+\n+static int aaeon_mcu_gpio_probe(struct platform_device *pdev)\n+{\n+\tstruct aaeon_mcu_gpio *data;\n+\n+\tdata = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);\n+\tif (!data)\n+\t\treturn -ENOMEM;\n+\n+\tdata->regmap = dev_get_regmap(pdev->dev.parent, NULL);\n+\tif (!data->regmap)\n+\t\treturn -ENODEV;\n+\n+\tdata->gc = aaeon_mcu_chip;\n+\tdata->gc.parent = pdev->dev.parent;\n+\n+\t/*\n+\t * Reset all GPIO states to a known configuration. The MCU does not\n+\t * reset GPIO state on soft reboot, only on power cycle (hard reboot).\n+\t * Without this reset, GPIOs would retain their previous state across\n+\t * reboots, which could lead to unexpected behavior.\n+\t */\n+\taaeon_mcu_gpio_reset(data, &pdev->dev);\n+\n+\treturn devm_gpiochip_add_data(&pdev->dev, &data->gc, data);\n+}\n+\n+static struct platform_driver aaeon_mcu_gpio_driver = {\n+\t.driver = {\n+\t\t.name = \"aaeon-mcu-gpio\",\n+\t},\n+\t.probe = aaeon_mcu_gpio_probe,\n+};\n+module_platform_driver(aaeon_mcu_gpio_driver);\n+\n+MODULE_DESCRIPTION(\"GPIO interface for Aaeon MCU\");\n+MODULE_AUTHOR(\"Jérémie Dautheribes <jeremie.dautheribes@bootlin.com>\");\n+MODULE_LICENSE(\"GPL\");\n","prefixes":["v5","4/5"]}