get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

GET /api/1.2/patches/2223455/?format=api
HTTP 200 OK
Allow: GET, PUT, PATCH, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 2223455,
    "url": "http://patchwork.ozlabs.org/api/1.2/patches/2223455/?format=api",
    "web_url": "http://patchwork.ozlabs.org/project/opensbi/patch/20260415110002.2610929-4-anup.patel@oss.qualcomm.com/",
    "project": {
        "id": 67,
        "url": "http://patchwork.ozlabs.org/api/1.2/projects/67/?format=api",
        "name": "OpenSBI development",
        "link_name": "opensbi",
        "list_id": "opensbi.lists.infradead.org",
        "list_email": "opensbi@lists.infradead.org",
        "web_url": "https://github.com/riscv/opensbi",
        "scm_url": "",
        "webscm_url": "",
        "list_archive_url": "",
        "list_archive_url_format": "",
        "commit_url_format": "https://github.com/riscv/opensbi/commit/{}"
    },
    "msgid": "<20260415110002.2610929-4-anup.patel@oss.qualcomm.com>",
    "list_archive_url": null,
    "date": "2026-04-15T11:00:02",
    "name": "[3/3] lib: sbi_timer: Add support for timer events",
    "commit_ref": null,
    "pull_url": null,
    "state": "new",
    "archived": false,
    "hash": "8036aad1ae81cccc7baf8ba9799bab381da5bad1",
    "submitter": {
        "id": 92322,
        "url": "http://patchwork.ozlabs.org/api/1.2/people/92322/?format=api",
        "name": "Anup Patel",
        "email": "anup.patel@oss.qualcomm.com"
    },
    "delegate": null,
    "mbox": "http://patchwork.ozlabs.org/project/opensbi/patch/20260415110002.2610929-4-anup.patel@oss.qualcomm.com/mbox/",
    "series": [
        {
            "id": 499967,
            "url": "http://patchwork.ozlabs.org/api/1.2/series/499967/?format=api",
            "web_url": "http://patchwork.ozlabs.org/project/opensbi/list/?series=499967",
            "date": "2026-04-15T11:00:00",
            "name": "Timer events for OpenSBI",
            "version": 1,
            "mbox": "http://patchwork.ozlabs.org/series/499967/mbox/"
        }
    ],
    "comments": "http://patchwork.ozlabs.org/api/patches/2223455/comments/",
    "check": "pending",
    "checks": "http://patchwork.ozlabs.org/api/patches/2223455/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "\n <opensbi-bounces+incoming=patchwork.ozlabs.org@lists.infradead.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 secure) header.d=lists.infradead.org header.i=@lists.infradead.org\n header.a=rsa-sha256 header.s=bombadil.20210309 header.b=4xdD/jyY;\n\tdkim=fail reason=\"signature verification failed\" (2048-bit key;\n unprotected) header.d=qualcomm.com header.i=@qualcomm.com header.a=rsa-sha256\n header.s=qcppdkim1 header.b=iJf0izzW;\n\tdkim-atps=neutral",
            "legolas.ozlabs.org;\n spf=none (no SPF record) smtp.mailfrom=lists.infradead.org\n (client-ip=2607:7c80:54:3::133; helo=bombadil.infradead.org;\n envelope-from=opensbi-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org;\n receiver=patchwork.ozlabs.org)"
        ],
        "Received": [
            "from bombadil.infradead.org (bombadil.infradead.org\n [IPv6:2607:7c80:54:3::133])\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 4fwdTh30yQz1yDF\n\tfor <incoming@patchwork.ozlabs.org>; Wed, 15 Apr 2026 21:00:24 +1000 (AEST)",
            "from localhost ([::1] helo=bombadil.infradead.org)\n\tby bombadil.infradead.org with esmtp (Exim 4.98.2 #2 (Red Hat Linux))\n\tid 1wCxyi-000000010Tx-2P49;\n\tWed, 15 Apr 2026 11:00:16 +0000",
            "from mx0a-0031df01.pphosted.com ([205.220.168.131])\n\tby bombadil.infradead.org with esmtps (Exim 4.98.2 #2 (Red Hat Linux))\n\tid 1wCxyg-000000010Sx-0WHN\n\tfor opensbi@lists.infradead.org;\n\tWed, 15 Apr 2026 11:00:15 +0000",
            "from pps.filterd (m0279865.ppops.net [127.0.0.1])\n\tby mx0a-0031df01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id\n 63F9fBbG1778836;\n\tWed, 15 Apr 2026 11:00:07 GMT",
            "from apblrppmta01.qualcomm.com\n (blr-bdr-fw-01_GlobalNAT_AllZones-Outside.qualcomm.com [103.229.18.19])\n\tby mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 4dhrw0395u-1\n\t(version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT);\n\tWed, 15 Apr 2026 11:00:07 +0000 (GMT)",
            "from pps.filterd (APBLRPPMTA01.qualcomm.com [127.0.0.1])\n\tby APBLRPPMTA01.qualcomm.com (8.18.1.7/8.18.1.7) with ESMTP id\n 63FB03vb029580;\n\tWed, 15 Apr 2026 11:00:03 GMT",
            "from pps.reinject (localhost [127.0.0.1])\n\tby APBLRPPMTA01.qualcomm.com (PPS) with ESMTPS id 4dg5d11e7n-1\n\t(version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT);\n\tWed, 15 Apr 2026 11:00:03 +0000 (GMT)",
            "from APBLRPPMTA01.qualcomm.com (APBLRPPMTA01.qualcomm.com\n [127.0.0.1])\n\tby pps.reinject (8.18.1.12/8.18.1.12) with ESMTP id 63FB03Fa029549;\n\tWed, 15 Apr 2026 11:00:03 GMT",
            "from hu-devc-blr-u24-a.qualcomm.com (hu-anuppate-blr.qualcomm.com\n [10.131.36.165])\n\tby APBLRPPMTA01.qualcomm.com (PPS) with ESMTPS id 63FB03G9029527\n\t(version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT);\n\tWed, 15 Apr 2026 11:00:03 +0000 (GMT)",
            "by hu-devc-blr-u24-a.qualcomm.com (Postfix, from userid 486687)\n\tid D995F21AC3; Wed, 15 Apr 2026 16:30:02 +0530 (+0530)"
        ],
        "DKIM-Signature": [
            "v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed;\n\td=lists.infradead.org; s=bombadil.20210309; h=Sender:\n\tContent-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post:\n\tList-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To:\n\tMessage-ID:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description:\n\tResent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:\n\tList-Owner; bh=C+8jx+hjc6Pink4wB6rSGONMkGD10CyfJI4VFPKBOM4=; b=4xdD/jyYjFx9Wb\n\tmSy8QDxb5gqXxEfOfTfmMwXmy6VzwXiHwND1jlF55TId7Hz4ZgJMrY/JeOqOmmTBJWx3h/ihxoMQZ\n\tsnucRktsnRfhWjm/uinTfYKmTl6SaKGLRoxmFgLGNMVZQ7Ym5L1Zaf3CjZAKmNOqxDpZ5p4JBvlNt\n\tRclECcV576Wk66wo53OUyOWnN42gr/Ac1+9LG1OnGF7bVZ6n7HALID8boKYjU85plpFMLOnvqTZQB\n\tPMpBGwlTpO2Or9ERSiy6hUDeHIwEHtlH9mNZkHsbg0RtJAdwgGA1y5B66S3gkKQAgvHgCfKVJVtxl\n\tx9AFn1P0LLx9kadtVurQ==;",
            "v=1; a=rsa-sha256; c=relaxed/relaxed; d=qualcomm.com; h=\n\tcc:content-transfer-encoding:date:from:in-reply-to:message-id\n\t:mime-version:references:subject:to; s=qcppdkim1; bh=KenWwB23DOw\n\t93neXtj0yfWx/iD2IE/OALb2E0lh+ouA=; b=iJf0izzWcaXaVAXXfHE1mC54AqV\n\tSVTm9eBvh3+dRQBgy5syOXJY3TeCxsUUf5fMjA/NKuCcuMDqHoPw8UVJunItkIj+\n\tqsJ955V02XV4HkE4v2/lXm4P7FiPgEuTfhJimko2gxny8JPWztX/x89zTM2O+NlO\n\tqJ6cV4wyfjsyw7UM+cp+wNjkC6lDMb7VkV7Y+Xeel/DbfRReeZ+UBJFQAobtz+X/\n\tzzxemerOLEmfcIhmXiBhs++tceMJva/JCKV0W/rGQPEa2NMN0z76inv4x5vh8J7I\n\thEob/4rcIB7SWjPsJdFWJ5FHfWh7E9zn82qiAGO4pnq9b8ahYJ4B9qErZQg=="
        ],
        "From": "Anup Patel <anup.patel@oss.qualcomm.com>",
        "To": "Atish Patra <atish.patra@linux.dev>",
        "Cc": "Andrew Jones <andrew.jones@oss.qualcomm.com>,\n        Samuel Holland <samuel.holland@sifive.com>,\n        Anup Patel <anup@brainfault.org>, opensbi@lists.infradead.org,\n        Anup Patel <anup.patel@oss.qualcomm.com>",
        "Subject": "[PATCH 3/3] lib: sbi_timer: Add support for timer events",
        "Date": "Wed, 15 Apr 2026 16:30:02 +0530",
        "Message-ID": "<20260415110002.2610929-4-anup.patel@oss.qualcomm.com>",
        "X-Mailer": "git-send-email 2.43.0",
        "In-Reply-To": "<20260415110002.2610929-1-anup.patel@oss.qualcomm.com>",
        "References": "<20260415110002.2610929-1-anup.patel@oss.qualcomm.com>",
        "MIME-Version": "1.0",
        "X-QCInternal": [
            "smtphost",
            "smtphost"
        ],
        "X-Proofpoint-GUID": "j6z9_XtRwGiT7EBefjBpVHAtfx6CeR41",
        "X-Proofpoint-Spam-Details-Enc": "AW1haW4tMjYwNDE1MDEwMSBTYWx0ZWRfX+JF6NfR06NxA\n fQ+URMojvpzj4942V6gCFkeySm5dGNgljKjdOFKVFJAmq8BvdsT4MlfznDp1e0LhW877wr9Ag0y\n vlXa/k3tu840B+wJlAl/4l5ZNeNqXl1XQRv5ssArrDm1cdJp8jO+GWuikTJ2lj8QCPDl7mt0y7S\n G5CjPY8UvoaCKzrSH6nvVONfion1CVJ6Y+nAroLz61bRzaRzWAs1lnu1FOKFXgOpWvOUgxiekvo\n FxJ6VV9DkmOQtAaf1Jn8kUtJeFrbuUnaTF9VaqFgEEt0EgZylbiOus39yf5iFcoxqz0qYJryt57\n HKuH2xHWU2PYjKdM+POf4u6wkQcZCldLf/Iqc6PCB0/6GQ1agea4KckGdK0yOZGPQhNGrwrBZV5\n Z54G75sry5ifkgo+85PCntt051do4rFgqC36YmBaKJrcHTmVZrQlYVZVakIqv6KKOuWQdHITSya\n UdygeDRx6tGs3iE6AZw==",
        "X-Proofpoint-ORIG-GUID": "j6z9_XtRwGiT7EBefjBpVHAtfx6CeR41",
        "X-Authority-Analysis": "v=2.4 cv=YMGvDxGx c=1 sm=1 tr=0 ts=69df6fb7 cx=c_pps\n a=Ou0eQOY4+eZoSc0qltEV5Q==:117 a=Ou0eQOY4+eZoSc0qltEV5Q==:17\n a=A5OVakUREuEA:10 a=VkNPw1HP01LnGYTKEx00:22 a=u7WPNUs3qKkmUXheDGA7:22\n a=Um2Pa8k9VHT-vaBCBUpS:22 a=EUspDBNiAAAA:8 a=SJzZRhbQ-NMWuBS7QtEA:9",
        "X-Proofpoint-Virus-Version": "vendor=baseguard\n engine=ICAP:2.0.293,Aquarius:18.0.1143,Hydra:6.1.51,FMLib:17.12.100.49\n definitions=2026-04-14_04,2026-04-13_04,2025-10-01_01",
        "X-Proofpoint-Spam-Details": "rule=outbound_notspam policy=outbound score=0\n impostorscore=0 priorityscore=1501 phishscore=0 bulkscore=0 spamscore=0\n suspectscore=0 clxscore=1015 malwarescore=0 adultscore=0 lowpriorityscore=0\n classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0\n reason=mlx scancount=1 engine=8.22.0-2604070000 definitions=main-2604150101",
        "X-CRM114-Version": "20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 ",
        "X-CRM114-CacheID": "sfid-20260415_040014_170026_017865A9 ",
        "X-CRM114-Status": "GOOD (  25.21  )",
        "X-Spam-Score": "-2.7 (--)",
        "X-Spam-Report": "Spam detection software,\n running on the system \"bombadil.infradead.org\",\n has NOT identified this incoming email as spam.  The original\n message has been attached to this so you can view it or label\n similar future email.  If you have any questions, see\n the administrator of that system for details.\n Content preview:  Currently,\n the sbi_timer only supports timer events configured\n    via SBI calls. Introduce struct sbi_timer_event and related functions to\n   allow configuring timer events from any part of OpenSBI. Signed-off-by:\n Anup\n    Patel <anup.patel@oss.qualcomm.com> --- include/sbi/sbi_timer.h | 43\n ++++++++-\n    lib/sbi/sbi_ecall_legacy.c | 4 +- lib/sbi/sbi_ecall_time.c | 4 +-\n lib/sbi/sbi_timer.c\n    | 177 +++++++++ [...]\n Content analysis details:   (-2.7 points, 5.0 required)\n  pts rule name              description\n ---- ----------------------\n --------------------------------------------------\n -0.7 RCVD_IN_DNSWL_LOW      RBL: Sender listed at https://www.dnswl.org/, low\n                             trust\n                             [205.220.168.131 listed in list.dnswl.org]\n  0.0 RCVD_IN_VALIDITY_CERTIFIED_BLOCKED RBL: ADMINISTRATOR NOTICE: The\n                             query to Validity was blocked.  See\n                             https://knowledge.validity.com/hc/en-us/articles/20961730681243\n                              for more information.\n                        [205.220.168.131 listed in\n sa-trusted.bondedsender.org]\n  0.0 RCVD_IN_VALIDITY_SAFE_BLOCKED RBL: ADMINISTRATOR NOTICE: The query to\n                              Validity was blocked.  See\n                             https://knowledge.validity.com/hc/en-us/articles/20961730681243\n                              for more information.\n                             [205.220.168.131 listed in\n sa-accredit.habeas.com]\n -0.0 SPF_PASS               SPF: sender matches SPF record\n  0.0 SPF_HELO_NONE          SPF: HELO does not publish an SPF Record\n -0.1 DKIM_VALID_EF          Message has a valid DKIM or DK signature from\n                             envelope-from domain\n  0.1 DKIM_SIGNED            Message has a DKIM or DK signature,\n not necessarily valid\n -0.1 DKIM_VALID             Message has at least one valid DKIM or DK\n signature\n -1.9 BAYES_00               BODY: Bayes spam probability is 0 to 1%\n                             [score: 0.0000]\n  0.0 RCVD_IN_VALIDITY_RPBL_BLOCKED RBL: ADMINISTRATOR NOTICE: The query to\n                              Validity was blocked.  See\n                             https://knowledge.validity.com/hc/en-us/articles/20961730681243\n                              for more information.\n                           [205.220.168.131 listed in\n bl.score.senderscore.com]",
        "X-BeenThere": "opensbi@lists.infradead.org",
        "X-Mailman-Version": "2.1.34",
        "Precedence": "list",
        "List-Id": "<opensbi.lists.infradead.org>",
        "List-Unsubscribe": "<http://lists.infradead.org/mailman/options/opensbi>,\n <mailto:opensbi-request@lists.infradead.org?subject=unsubscribe>",
        "List-Archive": "<http://lists.infradead.org/pipermail/opensbi/>",
        "List-Post": "<mailto:opensbi@lists.infradead.org>",
        "List-Help": "<mailto:opensbi-request@lists.infradead.org?subject=help>",
        "List-Subscribe": "<http://lists.infradead.org/mailman/listinfo/opensbi>,\n <mailto:opensbi-request@lists.infradead.org?subject=subscribe>",
        "Content-Type": "text/plain; charset=\"us-ascii\"",
        "Content-Transfer-Encoding": "7bit",
        "Sender": "\"opensbi\" <opensbi-bounces@lists.infradead.org>",
        "Errors-To": "opensbi-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org"
    },
    "content": "Currently, the sbi_timer only supports timer events configured via\nSBI calls. Introduce struct sbi_timer_event and related functions\nto allow configuring timer events from any part of OpenSBI.\n\nSigned-off-by: Anup Patel <anup.patel@oss.qualcomm.com>\n---\n include/sbi/sbi_timer.h    |  43 ++++++++-\n lib/sbi/sbi_ecall_legacy.c |   4 +-\n lib/sbi/sbi_ecall_time.c   |   4 +-\n lib/sbi/sbi_timer.c        | 177 +++++++++++++++++++++++++++++++++----\n 4 files changed, 205 insertions(+), 23 deletions(-)",
    "diff": "diff --git a/include/sbi/sbi_timer.h b/include/sbi/sbi_timer.h\nindex 2e1a7879..f23d72db 100644\n--- a/include/sbi/sbi_timer.h\n+++ b/include/sbi/sbi_timer.h\n@@ -10,7 +10,38 @@\n #ifndef __SBI_TIMER_H__\n #define __SBI_TIMER_H__\n \n-#include <sbi/sbi_types.h>\n+#include <sbi/sbi_list.h>\n+\n+/** Timer event abstraction */\n+struct sbi_timer_event {\n+\t/** List head for per-HART event list (Internal) */\n+\tstruct sbi_dlist head;\n+\n+\t/** Hart on which the event is started / running (Internal) */\n+\tint hart_index;\n+\n+\t/** Time stamp when the event expires (Internal) */\n+\tu64 time_stamp;\n+\n+\t/** Event callback to be called upon expiry */\n+\tvoid (*callback)(struct sbi_timer_event *ev);\n+\n+\t/** Event cleanup to be called upon sbi_hart_exit() */\n+\tvoid (*cleanup)(struct sbi_timer_event *ev);\n+\n+\t/** Event specific private data */\n+\tvoid *priv;\n+};\n+\n+#define SBI_INIT_TIMER_EVENT(__ptr, __callback, __cleanup, __priv)\t\\\n+do {\t\t\t\t\t\t\t\t\t\\\n+\tSBI_INIT_LIST_HEAD(&(__ptr)->head);\t\t\t\t\\\n+\t(__ptr)->hart_index = -1;\t\t\t\t\t\\\n+\t(__ptr)->time_stamp = 0;\t\t\t\t\t\\\n+\t(__ptr)->callback = (__callback); \t\t\t\t\\\n+\t(__ptr)->cleanup = (__cleanup); \t\t\t\t\\\n+\t(__ptr)->priv = (__priv); \t\t\t\t\t\\\n+} while (0)\n \n /** Timer hardware device */\n struct sbi_timer_device {\n@@ -86,8 +117,14 @@ void sbi_timer_set_delta(ulong delta);\n void sbi_timer_set_delta_upper(ulong delta_upper);\n #endif\n \n-/** Start timer event for current HART */\n-void sbi_timer_event_start(u64 next_event);\n+/** Start timer event on current HART */\n+void sbi_timer_event_start(struct sbi_timer_event *ev, u64 next_event);\n+\n+/** Stop timer event on current HART */\n+void sbi_timer_event_stop(struct sbi_timer_event *ev);\n+\n+/** Start supervisor timer event on current HART */\n+void sbi_timer_smode_event_start(u64 next_event);\n \n /** Process timer event for current HART */\n void sbi_timer_process(void);\ndiff --git a/lib/sbi/sbi_ecall_legacy.c b/lib/sbi/sbi_ecall_legacy.c\nindex 50a7660d..4501c4ad 100644\n--- a/lib/sbi/sbi_ecall_legacy.c\n+++ b/lib/sbi/sbi_ecall_legacy.c\n@@ -54,9 +54,9 @@ static int sbi_ecall_legacy_handler(unsigned long extid, unsigned long funcid,\n \tswitch (extid) {\n \tcase SBI_EXT_0_1_SET_TIMER:\n #if __riscv_xlen == 32\n-\t\tsbi_timer_event_start((((u64)regs->a1 << 32) | (u64)regs->a0));\n+\t\tsbi_timer_smode_event_start((((u64)regs->a1 << 32) | (u64)regs->a0));\n #else\n-\t\tsbi_timer_event_start((u64)regs->a0);\n+\t\tsbi_timer_smode_event_start((u64)regs->a0);\n #endif\n \t\tbreak;\n \tcase SBI_EXT_0_1_CONSOLE_PUTCHAR:\ndiff --git a/lib/sbi/sbi_ecall_time.c b/lib/sbi/sbi_ecall_time.c\nindex 6ea6f054..a0aa580d 100644\n--- a/lib/sbi/sbi_ecall_time.c\n+++ b/lib/sbi/sbi_ecall_time.c\n@@ -22,9 +22,9 @@ static int sbi_ecall_time_handler(unsigned long extid, unsigned long funcid,\n \n \tif (funcid == SBI_EXT_TIME_SET_TIMER) {\n #if __riscv_xlen == 32\n-\t\tsbi_timer_event_start((((u64)regs->a1 << 32) | (u64)regs->a0));\n+\t\tsbi_timer_smode_event_start((((u64)regs->a1 << 32) | (u64)regs->a0));\n #else\n-\t\tsbi_timer_event_start((u64)regs->a0);\n+\t\tsbi_timer_smode_event_start((u64)regs->a0);\n #endif\n \t} else\n \t\tret = SBI_ENOTSUPP;\ndiff --git a/lib/sbi/sbi_timer.c b/lib/sbi/sbi_timer.c\nindex 9806c033..539157fa 100644\n--- a/lib/sbi/sbi_timer.c\n+++ b/lib/sbi/sbi_timer.c\n@@ -10,9 +10,11 @@\n #include <sbi/riscv_asm.h>\n #include <sbi/riscv_barrier.h>\n #include <sbi/riscv_encoding.h>\n+#include <sbi/riscv_locks.h>\n #include <sbi/sbi_console.h>\n #include <sbi/sbi_error.h>\n #include <sbi/sbi_hart.h>\n+#include <sbi/sbi_hartmask.h>\n #include <sbi/sbi_platform.h>\n #include <sbi/sbi_pmu.h>\n #include <sbi/sbi_scratch.h>\n@@ -20,6 +22,9 @@\n \n struct timer_state {\n \tu64 time_delta;\n+\tspinlock_t event_list_lock;\n+\tstruct sbi_dlist event_list;\n+\tstruct sbi_timer_event smode_ev;\n };\n \n static unsigned long timer_state_off;\n@@ -136,8 +141,119 @@ void sbi_timer_set_delta_upper(ulong delta_upper)\n }\n #endif\n \n-void sbi_timer_event_start(u64 next_event)\n+static void __sbi_timer_update_device(struct timer_state *tstate)\n {\n+\tstruct sbi_timer_event *ev;\n+\n+\tif (!timer_dev)\n+\t\treturn;\n+\n+\tif (sbi_list_empty(&tstate->event_list)) {\n+\t\tif (timer_dev->timer_event_stop)\n+\t\t\ttimer_dev->timer_event_stop();\n+\t\tcsr_clear(CSR_MIE, MIP_MTIP);\n+\t} else {\n+\t\tev = sbi_list_first_entry(&tstate->event_list, struct sbi_timer_event, head);\n+\t\tif (timer_dev->timer_event_start)\n+\t\t\ttimer_dev->timer_event_start(ev->time_stamp);\n+\t\tcsr_set(CSR_MIE, MIP_MTIP);\n+\t}\n+}\n+\n+static void __sbi_timer_event_stop(struct sbi_timer_event *ev)\n+{\n+\tif (ev->hart_index > -1) {\n+\t\tsbi_list_del(&ev->head);\n+\t\tev->hart_index = -1;\n+\t}\n+}\n+\n+void sbi_timer_event_start(struct sbi_timer_event *ev, u64 next_event)\n+{\n+\tstruct sbi_timer_event *tev, *next_ev = NULL;\n+\tstruct timer_state *tstate;\n+\n+\tif (!ev)\n+\t\treturn;\n+\n+\t/* Ensure that event is not on the per-HART event list */\n+\tif (ev->hart_index > -1) {\n+\t\ttstate = sbi_scratch_offset_ptr(sbi_hartindex_to_scratch(ev->hart_index),\n+\t\t\t\t\t\ttimer_state_off);\n+\t\tspin_lock(&tstate->event_list_lock);\n+\t\t__sbi_timer_event_stop(ev);\n+\t\tspin_unlock(&tstate->event_list_lock);\n+\t}\n+\n+\ttstate = sbi_scratch_thishart_offset_ptr(timer_state_off);\n+\tspin_lock(&tstate->event_list_lock);\n+\n+\t/* Find where to insert the event in per-HART event list */\n+\tsbi_list_for_each_entry(tev, &tstate->event_list, head) {\n+\t\tif (next_event < tev->time_stamp) {\n+\t\t\tnext_ev = tev;\n+\t\t\tbreak;\n+\t\t}\n+\t}\n+\n+\t/* Insert the event in per-HART event list */\n+\tev->hart_index = current_hartindex();\n+\tev->time_stamp = next_event;\n+\tif (next_ev)\n+\t\tsbi_list_add(&ev->head, &next_ev->head);\n+\telse\n+\t\tsbi_list_add_tail(&ev->head, &tstate->event_list);\n+\n+\t__sbi_timer_update_device(tstate);\n+\n+\tspin_unlock(&tstate->event_list_lock);\n+}\n+\n+void sbi_timer_event_stop(struct sbi_timer_event *ev)\n+{\n+\tstruct timer_state *tstate;\n+\n+\tif (!ev)\n+\t\treturn;\n+\n+\t/* Ensure that event is not on the per-HART event list */\n+\tif (ev->hart_index > -1) {\n+\t\ttstate = sbi_scratch_offset_ptr(sbi_hartindex_to_scratch(ev->hart_index),\n+\t\t\t\t\t\ttimer_state_off);\n+\t\tspin_lock(&tstate->event_list_lock);\n+\t\t__sbi_timer_event_stop(ev);\n+\t\tspin_unlock(&tstate->event_list_lock);\n+\t}\n+\n+\t/* Re-program timer device on the current HART */\n+\ttstate = sbi_scratch_thishart_offset_ptr(timer_state_off);\n+\tspin_lock(&tstate->event_list_lock);\n+\t__sbi_timer_update_device(tstate);\n+\tspin_unlock(&tstate->event_list_lock);\n+}\n+\n+static void sbi_timer_smode_event_callback(struct sbi_timer_event *ev)\n+{\n+\t/*\n+\t * If sstc extension is available, supervisor can receive the timer\n+\t * directly without M-mode come in between. This function should\n+\t * only invoked if M-mode programs the timer for its own purpose.\n+\t */\n+\tif (!sbi_hart_has_extension(sbi_scratch_thishart_ptr(), SBI_HART_EXT_SSTC))\n+\t\tcsr_set(CSR_MIP, MIP_STIP);\n+}\n+\n+static void sbi_timer_smode_event_cleanup(struct sbi_timer_event *ev)\n+{\n+\tif (!sbi_hart_has_extension(sbi_scratch_thishart_ptr(), SBI_HART_EXT_SSTC))\n+\t\tcsr_clear(CSR_MIP, MIP_STIP);\n+}\n+\n+void sbi_timer_smode_event_start(u64 next_event)\n+{\n+\tstruct timer_state *tstate = sbi_scratch_offset_ptr(sbi_scratch_thishart_ptr(),\n+\t\t\t\t\t\t\t    timer_state_off);\n+\n \tsbi_pmu_ctr_incr_fw(SBI_PMU_FW_SET_TIMER);\n \n \t/**\n@@ -146,23 +262,34 @@ void sbi_timer_event_start(u64 next_event)\n \t */\n \tif (sbi_hart_has_extension(sbi_scratch_thishart_ptr(), SBI_HART_EXT_SSTC)) {\n \t\tcsr_write64(CSR_STIMECMP, next_event);\n-\t} else if (timer_dev && timer_dev->timer_event_start) {\n-\t\ttimer_dev->timer_event_start(next_event);\n+\t} else {\n \t\tcsr_clear(CSR_MIP, MIP_STIP);\n+\t\tsbi_timer_event_start(&tstate->smode_ev, next_event);\n \t}\n-\tcsr_set(CSR_MIE, MIP_MTIP);\n }\n \n void sbi_timer_process(void)\n {\n-\tcsr_clear(CSR_MIE, MIP_MTIP);\n-\t/*\n-\t * If sstc extension is available, supervisor can receive the timer\n-\t * directly without M-mode come in between. This function should\n-\t * only invoked if M-mode programs the timer for its own purpose.\n-\t */\n-\tif (!sbi_hart_has_extension(sbi_scratch_thishart_ptr(), SBI_HART_EXT_SSTC))\n-\t\tcsr_set(CSR_MIP, MIP_STIP);\n+\tstruct timer_state *tstate = sbi_scratch_thishart_offset_ptr(timer_state_off);\n+\tstruct sbi_timer_event *ev;\n+\n+\tspin_lock(&tstate->event_list_lock);\n+\n+\twhile (!sbi_list_empty(&tstate->event_list)) {\n+\t\tev = sbi_list_first_entry(&tstate->event_list, struct sbi_timer_event, head);\n+\t\tif (ev->time_stamp <= sbi_timer_value()) {\n+\t\t\t__sbi_timer_event_stop(ev);\n+\t\t\tif (ev->callback) {\n+\t\t\t\tspin_unlock(&tstate->event_list_lock);\n+\t\t\t\tev->callback(ev);\n+\t\t\t\tspin_lock(&tstate->event_list_lock);\n+\t\t\t}\n+\t\t}\n+\t}\n+\n+\t__sbi_timer_update_device(tstate);\n+\n+\tspin_unlock(&tstate->event_list_lock);\n }\n \n const struct sbi_timer_device *sbi_timer_get_device(void)\n@@ -204,6 +331,11 @@ int sbi_timer_init(struct sbi_scratch *scratch, bool cold_boot)\n \n \ttstate = sbi_scratch_offset_ptr(scratch, timer_state_off);\n \ttstate->time_delta = 0;\n+\tSPIN_LOCK_INIT(tstate->event_list_lock);\n+\tSBI_INIT_LIST_HEAD(&tstate->event_list);\n+\tSBI_INIT_TIMER_EVENT(&tstate->smode_ev,\n+\t\t\t     sbi_timer_smode_event_callback,\n+\t\t\t     sbi_timer_smode_event_cleanup, NULL);\n \n \tif (timer_dev && timer_dev->warm_init) {\n \t\tret = timer_dev->warm_init();\n@@ -216,9 +348,22 @@ int sbi_timer_init(struct sbi_scratch *scratch, bool cold_boot)\n \n void sbi_timer_exit(struct sbi_scratch *scratch)\n {\n-\tif (timer_dev && timer_dev->timer_event_stop)\n-\t\ttimer_dev->timer_event_stop();\n+\tstruct timer_state *tstate = sbi_scratch_thishart_offset_ptr(timer_state_off);\n+\tstruct sbi_timer_event *ev;\n+\n+\tspin_lock(&tstate->event_list_lock);\n+\n+\twhile (!sbi_list_empty(&tstate->event_list)) {\n+\t\tev = sbi_list_first_entry(&tstate->event_list, struct sbi_timer_event, head);\n+\t\t__sbi_timer_event_stop(ev);\n+\t\tif (ev->cleanup) {\n+\t\t\tspin_unlock(&tstate->event_list_lock);\n+\t\t\tev->cleanup(ev);\n+\t\t\tspin_lock(&tstate->event_list_lock);\n+\t\t}\n+\t}\n+\n+\t__sbi_timer_update_device(tstate);\n \n-\tcsr_clear(CSR_MIP, MIP_STIP);\n-\tcsr_clear(CSR_MIE, MIP_MTIP);\n+\tspin_unlock(&tstate->event_list_lock);\n }\n",
    "prefixes": [
        "3/3"
    ]
}