Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/1.0/patches/2175855/?format=api
{ "id": 2175855, "url": "http://patchwork.ozlabs.org/api/1.0/patches/2175855/?format=api", "project": { "id": 14, "url": "http://patchwork.ozlabs.org/api/1.0/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": "<20251219-aspeed-sgpio-v5-3-fd5593178144@google.com>", "date": "2025-12-19T07:04:16", "name": "[v5,3/6] hw/gpio/aspeed_sgpio: Implement SGPIO interrupt handling", "commit_ref": null, "pull_url": null, "state": "new", "archived": false, "hash": "bb9c68ac45e9203f88678aa78cdafaa99ec5251a", "submitter": { "id": 91652, "url": "http://patchwork.ozlabs.org/api/1.0/people/91652/?format=api", "name": "Yubin Zou", "email": "yubinz@google.com" }, "delegate": null, "mbox": "http://patchwork.ozlabs.org/project/qemu-devel/patch/20251219-aspeed-sgpio-v5-3-fd5593178144@google.com/mbox/", "series": [ { "id": 485958, "url": "http://patchwork.ozlabs.org/api/1.0/series/485958/?format=api", "date": "2025-12-19T07:04:13", "name": "hw/gpio/aspeed_sgpio: Add Aspeed Serial GPIO (SGPIO) controller model", "version": 5, "mbox": "http://patchwork.ozlabs.org/series/485958/mbox/" } ], "check": "pending", "checks": "http://patchwork.ozlabs.org/api/patches/2175855/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=google.com header.i=@google.com header.a=rsa-sha256\n header.s=20230601 header.b=0d1Bn2j1;\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=lists.gnu.org;\n envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org;\n receiver=patchwork.ozlabs.org)" ], "Received": [ "from lists.gnu.org (lists.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 4dXdqR40zrz1y3t\n\tfor <incoming@patchwork.ozlabs.org>; Fri, 19 Dec 2025 18:06:11 +1100 (AEDT)", "from localhost ([::1] helo=lists1p.gnu.org)\n\tby lists.gnu.org with esmtp (Exim 4.90_1)\n\t(envelope-from <qemu-devel-bounces@nongnu.org>)\n\tid 1vWUXh-0003rO-7h; Fri, 19 Dec 2025 02:04:49 -0500", "from eggs.gnu.org ([2001:470:142:3::10])\n by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256)\n (Exim 4.90_1) (envelope-from\n <3C_lEaQYKCmIYUBINZGOOGLE.COMQEMU-DEVELNONGNU.ORG@flex--yubinz.bounces.google.com>)\n id 1vWUXf-0003qq-MN\n for qemu-devel@nongnu.org; Fri, 19 Dec 2025 02:04:47 -0500", "from mail-pg1-x54a.google.com ([2607:f8b0:4864:20::54a])\n by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128)\n (Exim 4.90_1) (envelope-from\n <3C_lEaQYKCmIYUBINZGOOGLE.COMQEMU-DEVELNONGNU.ORG@flex--yubinz.bounces.google.com>)\n id 1vWUXd-0001bX-Rn\n for qemu-devel@nongnu.org; Fri, 19 Dec 2025 02:04:47 -0500", "by mail-pg1-x54a.google.com with SMTP id\n 41be03b00d2f7-b99763210e5so2702353a12.3\n for <qemu-devel@nongnu.org>; Thu, 18 Dec 2025 23:04:44 -0800 (PST)" ], "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=google.com; s=20230601; t=1766127883; x=1766732683; darn=nongnu.org;\n h=cc:to:from:subject:message-id:references:mime-version:in-reply-to\n :date:from:to:cc:subject:date:message-id:reply-to;\n bh=UEXr5Jd09L+9AgjqhDamfCsOvdLjpKDjLgvtKDEVv/A=;\n b=0d1Bn2j186Hnv8ozG0gqwzQxcRHgtrfF1mM9sQYAnYZ1xxlSu3nB5kmYUNaErJH2gy\n bP6eLzRTZkaUISy1rCp3OeTRN53bGZsjkAecW8qn8T8IKaBpH5e+bZLK2QDXx4Nt44BA\n Bf1OdGuFOU5NsSD1IhiVx6p0OQN9a5zFiKJcseKh+0DAyGFcVB78YGfFXh/N9pWdy3kv\n 8Bjb0GTgIZ8ht92DOYkeA7wACgYZrXEOHsJP00qlWtFxnM2KZ7jxTwB/SDZ6jEUhtZqv\n Jte7/UoqujlCEaUmkZHA5wreDs+daSVgWqPP36SxaMPbYHXqh4jdL8OQE1TE5vtIAQk4\n FPkQ==", "X-Google-DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=1e100.net; s=20230601; t=1766127883; x=1766732683;\n h=cc:to:from:subject:message-id:references:mime-version:in-reply-to\n :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to;\n bh=UEXr5Jd09L+9AgjqhDamfCsOvdLjpKDjLgvtKDEVv/A=;\n b=tp3hAbNOE15aKSr+WUIE6K/2jptznjUOTZcCa7fKGKFb9iMDiEh6zDJSXpNs51e8XP\n msR8dcWtx90D3bMXigqJkxD5CweALPhYcoCGyCtOZMCgSDv2iMijwgLkvNzB2p5XPhcP\n DPYu5ps7r6I/j3jaUi8tVYm5Q/m0ezQEdSviDIUazfuGVApuyM1MjS5WCtKe1DxFT6bm\n lrzkpf2CrtCY8wkFMgcV7+Wiqsl2kBD4KXnq5F2yWzZJbo5NwHJl/xBFJfaqJdcSZPwj\n QC5uxOxb+1G/7WqZf1zkBkZ3Txv3JAEg4GCr6RqhjR2HN3TZbziOzuFlCf3K225mgRRX\n sueA==", "X-Gm-Message-State": "AOJu0Yx/DiCXJpu2KclHBw/IS9Ct91ioVqfU/QrMf4cWgxepFgopYiGn\n xgsnv94UT7XfrOQ3MI55kf1WbYDCakQmWHqbIZdXFqnJ6HcvcTMOev5jPN1WJxweaPpeLav2f42\n yorS93hfy0KmGZlOF9vr7IeW2WVlYHFEDbijvH5OvZxgIrhWcFsw92uTYBij2t7ciuuod8daCgv\n LU4ync0fJbdQ0K05z4MDkhSmiEdCjAACmomRU=", "X-Google-Smtp-Source": "\n AGHT+IFQQ9YZMoX0ZMrrP+p1npcnsCJjUs8Y262JyoJ75fqq4xrKIFdV5u3LRiZGW12xibCgVRtyqUfm0fo=", "X-Received": "from dlah10.prod.google.com\n ([2002:a05:701b:260a:b0:11f:4424:33c4])\n (user=yubinz job=prod-delivery.src-stubby-dispatcher) by\n 2002:a05:7022:987:b0:11b:ca88:c4f7\n with SMTP id a92af1059eb24-12172309d60mr2088850c88.40.1766127883124; Thu, 18\n Dec 2025 23:04:43 -0800 (PST)", "Date": "Fri, 19 Dec 2025 07:04:16 +0000", "In-Reply-To": "<20251219-aspeed-sgpio-v5-0-fd5593178144@google.com>", "Mime-Version": "1.0", "References": "<20251219-aspeed-sgpio-v5-0-fd5593178144@google.com>", "X-Mailer": "b4 0.14.2", "Message-ID": "<20251219-aspeed-sgpio-v5-3-fd5593178144@google.com>", "Subject": "[PATCH v5 3/6] hw/gpio/aspeed_sgpio: Implement SGPIO interrupt\n handling", "From": "Yubin Zou <yubinz@google.com>", "To": "qemu-devel@nongnu.org", "Cc": "\" =?utf-8?q?C=C3=A9dric_Le_Goater?= \" <clg@kaod.org>,\n Peter Maydell <peter.maydell@linaro.org>,\n Steven Lee <steven_lee@aspeedtech.com>, Troy Lee <leetroy@gmail.com>,\n Jamin Lin <jamin_lin@aspeedtech.com>,\n Andrew Jeffery <andrew@codeconstruct.com.au>, Joel Stanley <joel@jms.id.au>,\n Fabiano Rosas <farosas@suse.de>, Laurent Vivier <lvivier@redhat.com>,\n Paolo Bonzini <pbonzini@redhat.com>,\n Kane-Chen-AS <kane_chen@aspeedtech.com>,\n Nabih Estefan <nabihestefan@google.com>, qemu-arm@nongnu.org,\n Yubin Zou <yubinz@google.com>", "Content-Type": "text/plain; charset=\"utf-8\"", "Received-SPF": "pass client-ip=2607:f8b0:4864:20::54a;\n envelope-from=3C_lEaQYKCmIYUBINZGOOGLE.COMQEMU-DEVELNONGNU.ORG@flex--yubinz.bounces.google.com;\n helo=mail-pg1-x54a.google.com", "X-Spam_score_int": "-95", "X-Spam_score": "-9.6", "X-Spam_bar": "---------", "X-Spam_report": "(-9.6 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_MED=-0.001,\n DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1,\n RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001,\n USER_IN_DEF_DKIM_WL=-7.5 autolearn=unavailable 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-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": "The SGPIO controller can generate interrupts based on various pin state\nchanges, such as rising/falling edges or high/low levels. This change\nadds the necessary logic to detect these events, update the interrupt\nstatus registers, and signal the interrupt to the SoC.\n\nSigned-off-by: Yubin Zou <yubinz@google.com>\n---\n include/hw/gpio/aspeed_sgpio.h | 2 +\n hw/gpio/aspeed_sgpio.c | 126 ++++++++++++++++++++++++++++++++++++++++-\n 2 files changed, 126 insertions(+), 2 deletions(-)", "diff": "diff --git a/include/hw/gpio/aspeed_sgpio.h b/include/hw/gpio/aspeed_sgpio.h\nindex 60279a597c722f94fba406d60cb30a52ef9544bc..8a11a9998c013cb2e4be99690ecd7bcd9dcb5815 100644\n--- a/include/hw/gpio/aspeed_sgpio.h\n+++ b/include/hw/gpio/aspeed_sgpio.h\n@@ -58,7 +58,9 @@ struct AspeedSGPIOState {\n \n /*< public >*/\n MemoryRegion iomem;\n+ int pending;\n qemu_irq irq;\n+ qemu_irq sgpios[ASPEED_SGPIO_MAX_PIN_PAIR];\n uint32_t ctrl_regs[ASPEED_SGPIO_MAX_PIN_PAIR];\n uint32_t int_regs[ASPEED_SGPIO_MAX_INT];\n };\ndiff --git a/hw/gpio/aspeed_sgpio.c b/hw/gpio/aspeed_sgpio.c\nindex 927c711cb3aef889c47c9a9156fe4241981c5efa..a058a3edcabd346a048e2b61740a3972a5e5a871 100644\n--- a/hw/gpio/aspeed_sgpio.c\n+++ b/hw/gpio/aspeed_sgpio.c\n@@ -12,9 +12,130 @@\n #include \"qemu/error-report.h\"\n #include \"qapi/error.h\"\n #include \"qapi/visitor.h\"\n+#include \"hw/irq.h\"\n #include \"hw/qdev-properties.h\"\n #include \"hw/gpio/aspeed_sgpio.h\"\n \n+/*\n+ * For each set of gpios there are three sensitivity registers that control\n+ * the interrupt trigger mode.\n+ *\n+ * | 2 | 1 | 0 | trigger mode\n+ * -----------------------------\n+ * | 0 | 0 | 0 | falling-edge\n+ * | 0 | 0 | 1 | rising-edge\n+ * | 0 | 1 | 0 | level-low\n+ * | 0 | 1 | 1 | level-high\n+ * | 1 | X | X | dual-edge\n+ */\n+\n+/* GPIO Interrupt Triggers */\n+#define ASPEED_FALLING_EDGE 0\n+#define ASPEED_RISING_EDGE 1\n+#define ASPEED_LEVEL_LOW 2\n+#define ASPEED_LEVEL_HIGH 3\n+#define ASPEED_DUAL_EDGE 4\n+\n+static void aspeed_clear_irq(AspeedSGPIOState *s, int idx)\n+{\n+ uint32_t reg_index = idx / 32;\n+ uint32_t bit_index = idx % 32;\n+ uint32_t pending = extract32(s->int_regs[reg_index], bit_index, 1);\n+\n+ assert(s->pending >= pending);\n+\n+ /* No change to s->pending if pending is 0 */\n+ s->pending -= pending;\n+\n+ /*\n+ * The write acknowledged the interrupt regardless of whether it\n+ * was pending or not. The post-condition is that it mustn't be\n+ * pending. Unconditionally clear the status bit.\n+ */\n+ s->int_regs[reg_index] = deposit32(s->int_regs[reg_index], bit_index, 1, 0);\n+}\n+\n+static void aspeed_evaluate_irq(AspeedSGPIOState *s, int sgpio_prev_high,\n+ int sgpio_curr_high, int idx)\n+{\n+ uint32_t ctrl = s->ctrl_regs[idx];\n+ uint32_t falling_edge = 0, rising_edge = 0;\n+ uint32_t int_trigger = SHARED_FIELD_EX32(ctrl, SGPIO_INT_TYPE);\n+ uint32_t int_enabled = SHARED_FIELD_EX32(ctrl, SGPIO_INT_EN);\n+ uint32_t reg_index = idx / 32;\n+ uint32_t bit_index = idx % 32;\n+\n+ if (!int_enabled) {\n+ return;\n+ }\n+\n+ /* Detect edges */\n+ if (sgpio_curr_high && !sgpio_prev_high) {\n+ rising_edge = 1;\n+ } else if (!sgpio_curr_high && sgpio_prev_high) {\n+ falling_edge = 1;\n+ }\n+\n+ if (((int_trigger == ASPEED_FALLING_EDGE) && falling_edge) ||\n+ ((int_trigger == ASPEED_RISING_EDGE) && rising_edge) ||\n+ ((int_trigger == ASPEED_LEVEL_LOW) && !sgpio_curr_high) ||\n+ ((int_trigger == ASPEED_LEVEL_HIGH) && sgpio_curr_high) ||\n+ ((int_trigger >= ASPEED_DUAL_EDGE) && (rising_edge || falling_edge)))\n+ {\n+ s->int_regs[reg_index] = deposit32(s->int_regs[reg_index],\n+ bit_index, 1, 1);\n+ /* Trigger the VIC IRQ */\n+ s->pending++;\n+ }\n+}\n+\n+static void aspeed_sgpio_update(AspeedSGPIOState *s, uint32_t idx,\n+ uint32_t value)\n+{\n+ uint32_t old = s->ctrl_regs[idx];\n+ uint32_t new = value;\n+ uint32_t diff = (old ^ new);\n+ if (diff) {\n+ /* If the interrupt clear bit is set */\n+ if (SHARED_FIELD_EX32(new, SGPIO_INT_STATUS)) {\n+ aspeed_clear_irq(s, idx);\n+ /* Clear the interrupt clear bit */\n+ new &= ~SGPIO_INT_STATUS_MASK;\n+ }\n+\n+ /* Update the control register. */\n+ s->ctrl_regs[idx] = new;\n+\n+ /* If the output value is changed */\n+ if (SHARED_FIELD_EX32(diff, SGPIO_SERIAL_OUT_VAL)) {\n+ /* ...trigger the line-state IRQ */\n+ qemu_set_irq(s->sgpios[idx], 1);\n+ }\n+\n+ /* If the input value is changed */\n+ if (SHARED_FIELD_EX32(diff, SGPIO_SERIAL_IN_VAL)) {\n+ aspeed_evaluate_irq(s,\n+ SHARED_FIELD_EX32(old, SGPIO_SERIAL_IN_VAL),\n+ SHARED_FIELD_EX32(new, SGPIO_SERIAL_IN_VAL),\n+ idx);\n+ }\n+ }\n+ qemu_set_irq(s->irq, !!(s->pending));\n+}\n+\n+static uint64_t aspeed_sgpio_2700_read_int_status_reg(AspeedSGPIOState *s,\n+ uint32_t reg)\n+{\n+ uint32_t idx = reg - R_SGPIO_INT_STATUS_0;\n+ if (idx >= ASPEED_SGPIO_MAX_INT) {\n+ qemu_log_mask(LOG_GUEST_ERROR,\n+ \"%s: interrupt status index: %d, out of bounds\\n\",\n+ __func__, idx);\n+ return 0;\n+ }\n+ return s->int_regs[idx];\n+}\n+\n static uint64_t aspeed_sgpio_2700_read_control_reg(AspeedSGPIOState *s,\n uint32_t reg)\n {\n@@ -38,7 +159,7 @@ static void aspeed_sgpio_2700_write_control_reg(AspeedSGPIOState *s,\n __func__, idx);\n return;\n }\n- s->ctrl_regs[idx] = data;\n+ aspeed_sgpio_update(s, idx, data);\n }\n \n static uint64_t aspeed_sgpio_2700_read(void *opaque, hwaddr offset,\n@@ -52,6 +173,7 @@ static uint64_t aspeed_sgpio_2700_read(void *opaque, hwaddr offset,\n \n switch (reg) {\n case R_SGPIO_INT_STATUS_0 ... R_SGPIO_INT_STATUS_7:\n+ value = aspeed_sgpio_2700_read_int_status_reg(s, reg);\n break;\n case R_SGPIO_0_CONTROL ... R_SGPIO_255_CONTROL:\n value = aspeed_sgpio_2700_read_control_reg(s, reg);\n@@ -116,7 +238,7 @@ static void aspeed_sgpio_set_pin_level(AspeedSGPIOState *s, int pin, bool level)\n } else {\n value &= ~bit_mask;\n }\n- s->ctrl_regs[pin >> 1] = value;\n+ aspeed_sgpio_update(s, pin >> 1, value);\n }\n \n static void aspeed_sgpio_get_pin(Object *obj, Visitor *v, const char *name,\n", "prefixes": [ "v5", "3/6" ] }