Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/1.1/patches/2230975/?format=api
{ "id": 2230975, "url": "http://patchwork.ozlabs.org/api/1.1/patches/2230975/?format=api", "web_url": "http://patchwork.ozlabs.org/project/qemu-devel/patch/20260430091832.1846637-4-kchiu@axiado.com/", "project": { "id": 14, "url": "http://patchwork.ozlabs.org/api/1.1/projects/14/?format=api", "name": "QEMU Development", "link_name": "qemu-devel", "list_id": "qemu-devel.nongnu.org", "list_email": "qemu-devel@nongnu.org", "web_url": "", "scm_url": "", "webscm_url": "" }, "msgid": "<20260430091832.1846637-4-kchiu@axiado.com>", "date": "2026-04-30T09:18:31", "name": "[v2,3/4] hw/gpio: Add Cadence GPIO controller", "commit_ref": null, "pull_url": null, "state": "new", "archived": false, "hash": "35894453be4c30e56a78824e0f862873fb641a80", "submitter": { "id": 92340, "url": "http://patchwork.ozlabs.org/api/1.1/people/92340/?format=api", "name": "Kuan-Jui Chiu", "email": "kchiu@axiado.com" }, "delegate": null, "mbox": "http://patchwork.ozlabs.org/project/qemu-devel/patch/20260430091832.1846637-4-kchiu@axiado.com/mbox/", "series": [ { "id": 502248, "url": "http://patchwork.ozlabs.org/api/1.1/series/502248/?format=api", "web_url": "http://patchwork.ozlabs.org/project/qemu-devel/list/?series=502248", "date": "2026-04-30T09:18:30", "name": "Add Axiado SoC AX3000 and EVK board", "version": 2, "mbox": "http://patchwork.ozlabs.org/series/502248/mbox/" } ], "comments": "http://patchwork.ozlabs.org/api/patches/2230975/comments/", "check": "pending", "checks": "http://patchwork.ozlabs.org/api/patches/2230975/checks/", "tags": {}, "headers": { "Return-Path": "<qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org>", "X-Original-To": "incoming@patchwork.ozlabs.org", "Delivered-To": "patchwork-incoming@legolas.ozlabs.org", "Authentication-Results": [ "legolas.ozlabs.org;\n\tdkim=pass (2048-bit key;\n unprotected) header.d=axiado.com header.i=@axiado.com header.a=rsa-sha256\n header.s=selector1 header.b=w+lPCXLW;\n\tdkim-atps=neutral", "legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org\n (client-ip=209.51.188.17; helo=lists1p.gnu.org;\n envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org;\n receiver=patchwork.ozlabs.org)" ], "Received": [ "from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17])\n\t(using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits))\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4g5pXb4Zgpz1yHZ\n\tfor <incoming@patchwork.ozlabs.org>; Thu, 30 Apr 2026 19:19:43 +1000 (AEST)", "from localhost ([::1] helo=lists1p.gnu.org)\n\tby lists1p.gnu.org with esmtp (Exim 4.90_1)\n\t(envelope-from <qemu-devel-bounces@nongnu.org>)\n\tid 1wINXt-0007HU-CF; Thu, 30 Apr 2026 05:18:57 -0400", "from eggs.gnu.org ([2001:470:142:3::10])\n by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256)\n (Exim 4.90_1) (envelope-from <kchiu@axiado.com>) id 1wINXn-0007Ge-Ko\n for qemu-devel@nongnu.org; Thu, 30 Apr 2026 05:18:52 -0400", "from\n mail-southcentralusazlp170120001.outbound.protection.outlook.com\n ([2a01:111:f403:c10d::1] helo=SN4PR2101CU001.outbound.protection.outlook.com)\n by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256)\n (Exim 4.90_1) (envelope-from <kchiu@axiado.com>) id 1wINXl-0005d6-7I\n for qemu-devel@nongnu.org; Thu, 30 Apr 2026 05:18:51 -0400", "from DS7PR03CA0093.namprd03.prod.outlook.com (2603:10b6:5:3b7::8) by\n EAYPR18MB988350.namprd18.prod.outlook.com (2603:10b6:303:2bf::8) with\n Microsoft SMTP Server (version=TLS1_2,\n cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9846.26; Thu, 30 Apr\n 2026 09:18:42 +0000", "from DS3PEPF0000C37A.namprd04.prod.outlook.com\n (2603:10b6:5:3b7:cafe::78) by DS7PR03CA0093.outlook.office365.com\n (2603:10b6:5:3b7::8) with Microsoft SMTP Server (version=TLS1_3,\n cipher=TLS_AES_256_GCM_SHA384) id 15.20.9846.28 via Frontend Transport; Thu,\n 30 Apr 2026 09:18:42 +0000", "from smtp.corp.axiado.com (64.62.143.114) by\n DS3PEPF0000C37A.mail.protection.outlook.com (10.167.23.4) with Microsoft SMTP\n Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.20.9846.18 via\n Frontend Transport; Thu, 30 Apr 2026 09:18:42 +0000", "from axiado.com (vm-swbuild01.axiadoRD [10.4.1.181])\n by smtp.corp.axiado.com (Postfix) with ESMTP id 4E1D34186B5D;\n Thu, 30 Apr 2026 02:16:49 -0700 (PDT)" ], "ARC-Seal": "i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none;\n b=wB/L1Oz4gJ55akf6VrOu244fUS9FbZ4Sd0LiEZNZ4SQnC4W+kig+kDGDDYKeizx7YB5b0+Rn9Zl2rajBRwhsNQ0ZvB0DzWoVAPmC9SxWfUgZMmH51l1EidVE6zHQezVzjTjuuMWzppECkUA4PLi56xyuKvyVIz3EwOUBqX+oUlmdvhhIC243iTuY6vwFDOVrTf7vdw7oosEUz2denZyeXpfme98tRpcG3f+mSW2wB5j1iUI7WrBHykiFzJkcw2ca6/vwwKm6dryv3SuoxaiKIBogq/Z9sMEizMyh9Qxjia5Uf7o4CyZ3BAqicsezXxA2Bo7+FtAJ7fYB+lOIYS77Qw==", "ARC-Message-Signature": "i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com;\n s=arcselector10001;\n h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1;\n bh=mQORqzmq212r6OC/ulsYXrIxCwa6X14bNYVIVwgQ1xM=;\n b=lW4SLsYjFjaAevwmJ2w0Wy2lGA9VwSAvtCe+F7ryZJIIosaI35C/V7nBkwtbr5ZnxhH1Akx/HvYZDqnvnmPoyWdIh9yhRuHBOj80TWdyokyQBVN/bgUF50QhH7KqTV1Hw7t4RlsPq2m3BtCvxm27ApBTXdTFwWH6dg0T2gsYfqM+KKRQDAv3KgvfVau8OznYn3VUTv4KS29mohnt79yV5DVh4+QNrIEbt86iaF6nW7ziLGbZ0WfsQxsO9qPtaB9sWFql8eNQP6jhkzhF8syc037LsYxLQOObT/t14A/bDSlb5cjdSLOco1/yPWzt6afN+UXQ8X6G7ORMZnFAckURww==", "ARC-Authentication-Results": "i=1; mx.microsoft.com 1; spf=fail (sender ip is\n 64.62.143.114) smtp.rcpttodomain=axiado.com smtp.mailfrom=axiado.com;\n dmarc=none action=none header.from=axiado.com; dkim=none (message not\n signed); arc=none (0)", "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed; d=axiado.com;\n s=selector1;\n h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck;\n bh=mQORqzmq212r6OC/ulsYXrIxCwa6X14bNYVIVwgQ1xM=;\n b=w+lPCXLWYBadQJO5t8sU/2y8JiSNCFlNHovN3uo6IkCok/rnFRNZ0zJLT30J/JzRGSAd05baCBN/tk18ox+KuI7peZcSkGpCVNfGLxNjGaWNGOGv3wBjKt7NGXS+LB6wSUwO+IkCpvF3QW4M9edD0cnUZNCqOlIBfw8w73Sk4jW8ffAuI3zIVevLhRUVJoSM0z9N2a4G6MLv5W8tOPG5PlOcqmLO0tmHyriFJDY2SG11p9INZmVf5B4IWPxdsdH0KERtlDUXWYtuJFa4Nu7XGZ9dXaYpoLOh1g7/9BfGDMxbX4CRt6A0wv0kFtD9g1NbWga1Rh9l7kCoYkRjdKigQw==", "X-MS-Exchange-Authentication-Results": "spf=fail (sender IP is 64.62.143.114)\n smtp.mailfrom=axiado.com; dkim=none (message not signed)\n header.d=none;dmarc=none action=none header.from=axiado.com;", "Received-SPF": [ "Fail (protection.outlook.com: domain of axiado.com does not\n designate 64.62.143.114 as permitted sender) receiver=protection.outlook.com;\n client-ip=64.62.143.114; helo=smtp.corp.axiado.com;", "pass client-ip=2a01:111:f403:c10d::1;\n envelope-from=kchiu@axiado.com;\n helo=SN4PR2101CU001.outbound.protection.outlook.com" ], "From": "Kuan-Jui Chiu <kchiu@axiado.com>", "To": "qemu-devel@nongnu.org", "Cc": "Kuan-Jui Chiu <kchiu@axiado.com>", "Subject": "[PATCH v2 3/4] hw/gpio: Add Cadence GPIO controller", "Date": "Thu, 30 Apr 2026 02:18:31 -0700", "Message-Id": "<20260430091832.1846637-4-kchiu@axiado.com>", "X-Mailer": "git-send-email 2.34.1", "In-Reply-To": "<20260430091832.1846637-1-kchiu@axiado.com>", "References": "<20260430091832.1846637-1-kchiu@axiado.com>", "MIME-Version": "1.0", "Content-Transfer-Encoding": "8bit", "X-EOPAttributedMessage": "0", "X-MS-PublicTrafficType": "Email", "X-MS-TrafficTypeDiagnostic": "DS3PEPF0000C37A:EE_|EAYPR18MB988350:EE_", "Content-Type": "text/plain", "X-MS-Office365-Filtering-Correlation-Id": "46fc2e3d-8da1-4d00-d5ce-08dea69978e2", "X-MS-Exchange-SenderADCheck": "1", "X-MS-Exchange-AntiSpam-Relay": "0", "X-Microsoft-Antispam": "BCL:0;\n ARA:13230040|82310400026|376014|34020700016|1800799024|36860700016|56012099003|18002099003|22082099003;", "X-Microsoft-Antispam-Message-Info": "\n dKC/tt8rE1BaBhXLR+juxEwoCz+1k0yJDxmXBWsXWQsP7ozF3czPmgkk6w+uoTMPMaGIrTGk5QEP+LXBZT4IGDB2sXQw9k/AnKTS6Il4xhHCYDFRqwQf/xTno4VWqZUZLJmsIB0jh9h1aIK5DzScQLULThLpfqDBbcc3jnZdCunXko21+q9Rg2fBGQKbVLtg5DGMd6weOVbnHVujwD4pLqRKl/7p0z4RngVTHTby6obw1STl9BQsIHjaHQoP0TjXNOZpxw96DfpdhFgXRc5Jz3eWGMaowpjID7QoXr6KznixplEK4uAn3cLAxsmJvuYKNhmzTa5rlZTU/rQsy6NUDj07Ey1OcX1rbJBIji79TrCbviPz8Ejw4YjNGP8ZHpC77Bd+oVF++0WbvQsoQQen8j3eHV+1jDcbW2iq9kh1VVe1QSSXOG3RjsJiDj4cZCbEkdAEYhpbfkFv+DXtRLfN6vM6zC6umQuzQkMUrXAVowz71hJbd2wFMjMcoJ7fb+QNaJD2Dv+zird22WPdGKurAvdBzTc4AM8mOEQl4D6I7Ty4vSujQq52GblKeDuS0coaFXGQOnxkoJK8dCy2aCxdpUwQZ26wYRAx3RsAY/aLX3NxFkA72gM+PaszIt2sM8MIiCVxVlX84Gh+0vjxLLeM8UW5CrUs6kgdSkAk07G7E7W2OUklNUHhDdIUwlKkKEicfnEBK+vTjUrQZMvoqhzw4cKv6Js8V1gPcVdEtKbGogWXx+2t973KtzfY7iRsozAvKPQmegy5azn6bQB0B3QVJg==", "X-Forefront-Antispam-Report": "CIP:64.62.143.114; CTRY:US; LANG:en; SCL:1; SRV:;\n IPV:NLI; SFV:NSPM; H:smtp.corp.axiado.com; PTR:InfoDomainNonexistent;\n CAT:NONE;\n SFS:(13230040)(82310400026)(376014)(34020700016)(1800799024)(36860700016)(56012099003)(18002099003)(22082099003);\n DIR:OUT; SFP:1102;", "X-MS-Exchange-AntiSpam-MessageData-ChunkCount": "1", "X-MS-Exchange-AntiSpam-MessageData-0": "\n Li1zs6hkkb/oKNHtHHm17Zy7KsWMD0imhZDMWW0njFxiYc/qXakj3b34Ps5DepmMS1Oohhw33+7SC2+A5XYhTGXUTji+E8oTBP0/x9DqlTjUIozUtJuoYti/4BlKcDnvDybFsCgq2U2NtMtXjOS+XCfxLSaiuJiRre9mV+wIglMHwQ7guVvJw2Z9BgboMEXaSY/ILYFqR6NurPnS9VmyvMPzTty9cDJke+OfP5pg9O3iFXGnf7LmKWl38VCAHUfJZWIiBUB++KyAZV4inBL97Dlz8TCpaGLgS472WmSQhpGf+jG8/DCbomn6A0ydoLj8PcItNfQogPuBhaKo0OCj1ZrziKbFPItQAX9CRVBCn2n2w83gGuQBXVOWLD4hjrYF5nEU/qSxh7SeF+wqfcplbludIN5O6aOQh0r9UVKwI4M6fY+x9mZ461AJWRpbBMCW", "X-OriginatorOrg": "axiado.com", "X-MS-Exchange-CrossTenant-OriginalArrivalTime": "30 Apr 2026 09:18:42.0249 (UTC)", "X-MS-Exchange-CrossTenant-Network-Message-Id": "\n 46fc2e3d-8da1-4d00-d5ce-08dea69978e2", "X-MS-Exchange-CrossTenant-Id": "ff2db17c-4338-408e-9036-2dee8e3e17d7", "X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp": "\n TenantId=ff2db17c-4338-408e-9036-2dee8e3e17d7; Ip=[64.62.143.114];\n Helo=[smtp.corp.axiado.com]", "X-MS-Exchange-CrossTenant-AuthSource": "\n DS3PEPF0000C37A.namprd04.prod.outlook.com", "X-MS-Exchange-CrossTenant-AuthAs": "Anonymous", "X-MS-Exchange-CrossTenant-FromEntityHeader": "HybridOnPrem", "X-MS-Exchange-Transport-CrossTenantHeadersStamped": "EAYPR18MB988350", "X-Spam_score_int": "-20", "X-Spam_score": "-2.1", "X-Spam_bar": "--", "X-Spam_report": "(-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1,\n DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1,\n SPF_HELO_PASS=-0.001,\n SPF_PASS=-0.001 autolearn=ham autolearn_force=no", "X-Spam_action": "no action", "X-BeenThere": "qemu-devel@nongnu.org", "X-Mailman-Version": "2.1.29", "Precedence": "list", "List-Id": "qemu development <qemu-devel.nongnu.org>", "List-Unsubscribe": "<https://lists.nongnu.org/mailman/options/qemu-devel>,\n <mailto:qemu-devel-request@nongnu.org?subject=unsubscribe>", "List-Archive": "<https://lists.nongnu.org/archive/html/qemu-devel>", "List-Post": "<mailto:qemu-devel@nongnu.org>", "List-Help": "<mailto:qemu-devel-request@nongnu.org?subject=help>", "List-Subscribe": "<https://lists.nongnu.org/mailman/listinfo/qemu-devel>,\n <mailto:qemu-devel-request@nongnu.org?subject=subscribe>", "Errors-To": "qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org", "Sender": "qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org" }, "content": "This patch add a new model for Cadence GPIO controller which\nsupports 32 pins and interrupts for level-triggered/edge-triggered type on\ninput pins.\n\nAlso define new trace functions for analysis purpose and new configuration to\nenable this model.\n\nSigned-off-by: Kuan-Jui Chiu <kchiu@axiado.com>\n---\n hw/gpio/Kconfig | 3 +\n hw/gpio/cadence_gpio.c | 301 +++++++++++++++++++++++++++++++++\n hw/gpio/meson.build | 1 +\n hw/gpio/trace-events | 5 +\n include/hw/gpio/cadence_gpio.h | 55 ++++++\n 5 files changed, 365 insertions(+)\n create mode 100644 hw/gpio/cadence_gpio.c\n create mode 100644 include/hw/gpio/cadence_gpio.h", "diff": "diff --git a/hw/gpio/Kconfig b/hw/gpio/Kconfig\nindex a209294c20..fcc7c70bd5 100644\n--- a/hw/gpio/Kconfig\n+++ b/hw/gpio/Kconfig\n@@ -30,3 +30,6 @@ config PCF8574\n \n config ZAURUS_SCOOP\n bool\n+\n+config CADENCE_GPIO\n+ bool\ndiff --git a/hw/gpio/cadence_gpio.c b/hw/gpio/cadence_gpio.c\nnew file mode 100644\nindex 0000000000..2410753abc\n--- /dev/null\n+++ b/hw/gpio/cadence_gpio.c\n@@ -0,0 +1,301 @@\n+/*\n+ * Cadence GPIO emulation.\n+ *\n+ * Author: Kuan-Jui Chiu <kchiu@axiado.com>\n+ *\n+ * SPDX-License-Identifier: GPL-2.0-or-later\n+ */\n+\n+#include \"qemu/osdep.h\"\n+#include \"hw/gpio/cadence_gpio.h\"\n+#include \"hw/core/irq.h\"\n+#include \"migration/vmstate.h\"\n+#include \"qemu/log.h\"\n+#include \"trace.h\"\n+\n+static void cdns_gpio_update_irq(CadenceGPIOState *s)\n+{\n+ qemu_set_irq(s->irq, s->isr ? 1 : 0);\n+}\n+\n+static void cdns_gpio_update_isr_per_line(CadenceGPIOState *s, int line,\n+ uint32_t new)\n+{\n+ uint32_t old = extract32(s->inpvr, line, 1);\n+ uint32_t ivr = extract32(s->ivr, line, 1);\n+\n+ /* Deassert in bypass mode or not input pin */\n+ if (extract32(s->bmr, line, 1) || !extract32(s->dmr, line, 1) ||\n+ extract32(s->imr, line, 1)) {\n+ s->isr = deposit32(s->isr, line, 1, 0);\n+ return;\n+ }\n+\n+ if (extract32(s->itr, line, 1)) {\n+ /* Level-triggered */\n+ if (ivr && new) {\n+ /* High level */\n+ s->isr = deposit32(s->isr, line, 1, 1);\n+ }\n+ if (!ivr && !new) {\n+ /* Low level */\n+ s->isr = deposit32(s->isr, line, 1, 1);\n+ }\n+ } else {\n+ /* Edge-triggered */\n+ if (extract32(s->ioar, line, 1) && (old != new)) {\n+ /* On any edge */\n+ s->isr = deposit32(s->isr, line, 1, 1);\n+ } else {\n+ if (ivr && !old && new) {\n+ /* Rising edge */\n+ s->isr = deposit32(s->isr, line, 1, 1);\n+ }\n+ if (!ivr && old && !new) {\n+ /* Falling edge */\n+ s->isr = deposit32(s->isr, line, 1, 1);\n+ }\n+ }\n+ }\n+}\n+\n+static void cdns_gpio_update_isr(CadenceGPIOState *s)\n+{\n+ for (int i = 0; i < CDNS_GPIO_NUM; i++) {\n+ uint32_t level = extract32(s->inpvr, i, 1);\n+ cdns_gpio_update_isr_per_line(s, i, level);\n+ }\n+}\n+\n+static void cdns_gpio_set(void *opaque, int line, int level)\n+{\n+ CadenceGPIOState *s = CADENCE_GPIO(opaque);\n+ uint32_t new = level ? 1 : 0;\n+\n+ trace_cdns_gpio_set(DEVICE(s)->canonical_path, line, level);\n+\n+ cdns_gpio_update_isr_per_line(s, line, new);\n+\n+ /* Sync INPVR with new value */\n+ s->inpvr = deposit32(s->inpvr, line, 1, new);\n+\n+ cdns_gpio_update_irq(s);\n+}\n+\n+static inline void cdns_gpio_update_output_irq(CadenceGPIOState *s)\n+{\n+ for (int i = 0; i < CDNS_GPIO_NUM; i++) {\n+ /* Forward the output value to corresponding irq */\n+ if (!extract32(s->bmr, i, 1) && !extract32(s->dmr, i, 1) &&\n+ extract32(s->oer, i, 1) && s->output[i]) {\n+ qemu_set_irq(s->output[i], extract32(s->ovr, i, 1));\n+ }\n+ }\n+}\n+\n+static uint64_t cdns_gpio_read(void *opaque, hwaddr offset, unsigned size)\n+{\n+ CadenceGPIOState *s = CADENCE_GPIO(opaque);\n+ uint32_t reg_value = 0x0;\n+\n+ switch (offset) {\n+ case CDNS_GPIO_BYPASS_MODE:\n+ reg_value = s->bmr;\n+ break;\n+\n+ case CDNS_GPIO_DIRECTION_MODE:\n+ reg_value = s->dmr;\n+ break;\n+\n+ case CDNS_GPIO_OUTPUT_EN:\n+ reg_value = s->oer;\n+ break;\n+\n+ case CDNS_GPIO_OUTPUT_VALUE:\n+ reg_value = s->ovr;\n+ break;\n+\n+ case CDNS_GPIO_INPUT_VALUE:\n+ reg_value = s->inpvr;\n+ break;\n+\n+ case CDNS_GPIO_IRQ_MASK:\n+ reg_value = s->imr;\n+ break;\n+\n+ case CDNS_GPIO_IRQ_STATUS:\n+ reg_value = s->isr;\n+ break;\n+\n+ case CDNS_GPIO_IRQ_TYPE:\n+ reg_value = s->itr;\n+ break;\n+\n+ case CDNS_GPIO_IRQ_VALUE:\n+ reg_value = s->ivr;\n+ break;\n+\n+ case CDNS_GPIO_IRQ_ANY_EDGE:\n+ reg_value = s->ioar;\n+ break;\n+\n+ default:\n+ qemu_log_mask(LOG_GUEST_ERROR, \"[%s]%s: Bad register at offset 0x%\"\n+ HWADDR_PRIx \"\\n\", TYPE_CADENCE_GPIO, __func__, offset);\n+ break;\n+ }\n+\n+ trace_cdns_gpio_read(DEVICE(s)->canonical_path, offset, reg_value);\n+\n+ return reg_value;\n+}\n+\n+static void cdns_gpio_write(void *opaque, hwaddr offset, uint64_t value,\n+ unsigned size)\n+{\n+ CadenceGPIOState *s = CADENCE_GPIO(opaque);\n+\n+ trace_cdns_gpio_write(DEVICE(s)->canonical_path, offset, value);\n+\n+ switch (offset) {\n+ case CDNS_GPIO_BYPASS_MODE:\n+ s->bmr = value;\n+ cdns_gpio_update_output_irq(s);\n+ cdns_gpio_update_isr(s);\n+ cdns_gpio_update_irq(s);\n+ break;\n+\n+ case CDNS_GPIO_DIRECTION_MODE:\n+ s->dmr = value;\n+ cdns_gpio_update_output_irq(s);\n+ cdns_gpio_update_isr(s);\n+ cdns_gpio_update_irq(s);\n+ break;\n+\n+ case CDNS_GPIO_OUTPUT_EN:\n+ s->oer = value;\n+ cdns_gpio_update_output_irq(s);\n+ break;\n+\n+ case CDNS_GPIO_OUTPUT_VALUE:\n+ s->ovr = value;\n+ cdns_gpio_update_output_irq(s);\n+ break;\n+\n+ case CDNS_GPIO_IRQ_EN:\n+ s->imr &= ~value;\n+ cdns_gpio_update_isr(s);\n+ cdns_gpio_update_irq(s);\n+ break;\n+\n+ case CDNS_GPIO_IRQ_DIS:\n+ s->imr |= value;\n+ cdns_gpio_update_isr(s);\n+ cdns_gpio_update_irq(s);\n+ break;\n+\n+ case CDNS_GPIO_IRQ_TYPE:\n+ s->itr = value;\n+ break;\n+\n+ case CDNS_GPIO_IRQ_VALUE:\n+ s->ivr = value;\n+ break;\n+\n+ case CDNS_GPIO_IRQ_ANY_EDGE:\n+ s->ioar = value;\n+ break;\n+\n+ case CDNS_GPIO_INPUT_VALUE:\n+ case CDNS_GPIO_IRQ_MASK:\n+ case CDNS_GPIO_IRQ_STATUS:\n+ /* Read-Only */\n+ break;\n+\n+ default:\n+ qemu_log_mask(LOG_GUEST_ERROR, \"[%s]%s: Bad register at offset 0x%\"\n+ HWADDR_PRIx \"\\n\", TYPE_CADENCE_GPIO, __func__, offset);\n+ break;\n+ }\n+}\n+\n+static const MemoryRegionOps cdns_gpio_ops = {\n+ .read = cdns_gpio_read,\n+ .write = cdns_gpio_write,\n+ .valid.min_access_size = 4,\n+ .valid.max_access_size = 4,\n+ .endianness = DEVICE_LITTLE_ENDIAN,\n+};\n+\n+static const VMStateDescription vmstate_cdns_gpio = {\n+ .name = TYPE_CADENCE_GPIO,\n+ .version_id = 1,\n+ .minimum_version_id = 1,\n+ .fields = (const VMStateField[]) {\n+ VMSTATE_UINT32(bmr, CadenceGPIOState),\n+ VMSTATE_UINT32(dmr, CadenceGPIOState),\n+ VMSTATE_UINT32(oer, CadenceGPIOState),\n+ VMSTATE_UINT32(ovr, CadenceGPIOState),\n+ VMSTATE_UINT32(inpvr, CadenceGPIOState),\n+ VMSTATE_UINT32(imr, CadenceGPIOState),\n+ VMSTATE_UINT32(isr, CadenceGPIOState),\n+ VMSTATE_UINT32(itr, CadenceGPIOState),\n+ VMSTATE_UINT32(ivr, CadenceGPIOState),\n+ VMSTATE_UINT32(ioar, CadenceGPIOState),\n+ VMSTATE_END_OF_LIST()\n+ }\n+};\n+\n+static void cdns_gpio_reset(DeviceState *dev)\n+{\n+ CadenceGPIOState *s = CADENCE_GPIO(dev);\n+\n+ s->bmr = 0;\n+ s->dmr = 0;\n+ s->oer = 0;\n+ s->ovr = 0;\n+ s->inpvr = 0;\n+ s->imr = 0xffffffff;\n+ s->isr = 0;\n+ s->itr = 0;\n+ s->ivr = 0;\n+ s->ioar = 0;\n+}\n+\n+static void cdns_gpio_init(Object *obj)\n+{\n+ CadenceGPIOState *s = CADENCE_GPIO(obj);\n+\n+ memory_region_init_io(&s->iomem, obj, &cdns_gpio_ops, s,\n+ TYPE_CADENCE_GPIO, CDNS_GPIO_REG_SIZE);\n+\n+ qdev_init_gpio_in(DEVICE(s), cdns_gpio_set, CDNS_GPIO_NUM);\n+ qdev_init_gpio_out(DEVICE(s), s->output, CDNS_GPIO_NUM);\n+\n+ sysbus_init_irq(SYS_BUS_DEVICE(obj), &s->irq);\n+ sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->iomem);\n+}\n+\n+static void cdns_gpio_class_init(ObjectClass *klass, const void *data)\n+{\n+ DeviceClass *dc = DEVICE_CLASS(klass);\n+\n+ device_class_set_legacy_reset(dc, cdns_gpio_reset);\n+ dc->vmsd = &vmstate_cdns_gpio;\n+ dc->desc = \"Cadence GPIO controller\";\n+}\n+\n+static const TypeInfo cdns_gpio_info = {\n+ .name = TYPE_CADENCE_GPIO,\n+ .parent = TYPE_SYS_BUS_DEVICE,\n+ .instance_size = sizeof(CadenceGPIOState),\n+ .instance_init = cdns_gpio_init,\n+ .class_init = cdns_gpio_class_init,\n+};\n+\n+static void cdns_gpio_register_types(void)\n+{\n+ type_register_static(&cdns_gpio_info);\n+}\n+\n+type_init(cdns_gpio_register_types)\ndiff --git a/hw/gpio/meson.build b/hw/gpio/meson.build\nindex 6a67ee958f..0555f44b6a 100644\n--- a/hw/gpio/meson.build\n+++ b/hw/gpio/meson.build\n@@ -19,3 +19,4 @@ system_ss.add(when: 'CONFIG_ASPEED_SOC', if_true: files('aspeed_gpio.c'))\n system_ss.add(when: 'CONFIG_ASPEED_SOC', if_true: files('aspeed_sgpio.c'))\n system_ss.add(when: 'CONFIG_SIFIVE_GPIO', if_true: files('sifive_gpio.c'))\n system_ss.add(when: 'CONFIG_PCF8574', if_true: files('pcf8574.c'))\n+system_ss.add(when: 'CONFIG_CADENCE_GPIO', if_true: files('cadence_gpio.c'))\ndiff --git a/hw/gpio/trace-events b/hw/gpio/trace-events\nindex cea896b28f..80ca783a03 100644\n--- a/hw/gpio/trace-events\n+++ b/hw/gpio/trace-events\n@@ -46,3 +46,8 @@ stm32l4x5_gpio_read(char *gpio, uint64_t addr) \"GPIO%s addr: 0x%\" PRIx64 \" \"\n stm32l4x5_gpio_write(char *gpio, uint64_t addr, uint64_t data) \"GPIO%s addr: 0x%\" PRIx64 \" val: 0x%\" PRIx64 \"\"\n stm32l4x5_gpio_update_idr(char *gpio, uint32_t old_idr, uint32_t new_idr) \"GPIO%s from: 0x%x to: 0x%x\"\n stm32l4x5_gpio_pins(char *gpio, uint16_t disconnected, uint16_t high) \"GPIO%s disconnected pins: 0x%x levels: 0x%x\"\n+\n+# cadence_gpio.c\n+cdns_gpio_read(const char *path, uint64_t offset, uint32_t value) \"%s:reg[0x%04\" PRIx64 \"] -> 0x%\" PRIx32\n+cdns_gpio_write(const char *path, uint64_t offset, uint64_t value) \"%s:reg[0x%04\" PRIx64 \"] <- 0x%04\" PRIx64\n+cdns_gpio_set(const char *path, int line, int level) \"%s:[%d] <- %d\"\ndiff --git a/include/hw/gpio/cadence_gpio.h b/include/hw/gpio/cadence_gpio.h\nnew file mode 100644\nindex 0000000000..ed3f77b894\n--- /dev/null\n+++ b/include/hw/gpio/cadence_gpio.h\n@@ -0,0 +1,55 @@\n+/*\n+ * Cadence GPIO registers definition.\n+ *\n+ * Author: Kuan-Jui Chiu <kchiu@axiado.com>\n+ *\n+ * SPDX-License-Identifier: GPL-2.0-or-later\n+ */\n+\n+#ifndef CADENCE_GPIO_H\n+#define CADENCE_GPIO_H\n+\n+#include \"hw/core/sysbus.h\"\n+#include \"qom/object.h\"\n+\n+#define TYPE_CADENCE_GPIO \"cadence_gpio\"\n+OBJECT_DECLARE_SIMPLE_TYPE(CadenceGPIOState, CADENCE_GPIO)\n+\n+#define CDNS_GPIO_REG_SIZE 0x400\n+#define CDNS_GPIO_NUM 32\n+\n+#define CDNS_GPIO_BYPASS_MODE 0x00\n+#define CDNS_GPIO_DIRECTION_MODE 0x04\n+#define CDNS_GPIO_OUTPUT_EN 0x08\n+#define CDNS_GPIO_OUTPUT_VALUE 0x0c\n+#define CDNS_GPIO_INPUT_VALUE 0x10\n+#define CDNS_GPIO_IRQ_MASK 0x14\n+#define CDNS_GPIO_IRQ_EN 0x18\n+#define CDNS_GPIO_IRQ_DIS 0x1c\n+#define CDNS_GPIO_IRQ_STATUS 0x20\n+#define CDNS_GPIO_IRQ_TYPE 0x24\n+#define CDNS_GPIO_IRQ_VALUE 0x28\n+#define CDNS_GPIO_IRQ_ANY_EDGE 0x2c\n+\n+struct CadenceGPIOState {\n+ /*< private >*/\n+ SysBusDevice parent_obj;\n+\n+ /*< public >*/\n+ MemoryRegion iomem;\n+\n+ uint32_t bmr;\n+ uint32_t dmr;\n+ uint32_t oer;\n+ uint32_t ovr;\n+ uint32_t inpvr;\n+ uint32_t imr;\n+ uint32_t isr;\n+ uint32_t itr;\n+ uint32_t ivr;\n+ uint32_t ioar;\n+ qemu_irq irq;\n+ qemu_irq output[CDNS_GPIO_NUM];\n+};\n+\n+#endif /* CADENCE_GPIO_H */\n", "prefixes": [ "v2", "3/4" ] }