From nobody Tue Apr 7 13:08:27 2026 Received: from forward205a.mail.yandex.net (forward205a.mail.yandex.net [178.154.239.88]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A3802388E40; Fri, 13 Mar 2026 09:24:33 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=178.154.239.88 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773393875; cv=none; b=MXOYVmDot6dKF1QEapbLxbeJZVF/UbYIapfgaI9d1DNjNWTj+JPSLZfbhNUjTFmz5hANrqnf1N1TR0LKyDf+NmmGmvPeNcKqYdwq6sJ28b299y0DP0W3dtLnwYRMCBPIcGNmxBXm4WGtXY4wix7KyL9az+/7IR1I57TCqw3vFtM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773393875; c=relaxed/simple; bh=ndwdqa6bd2iLxTHW2zZ8bxP3iHLI/h99PAJbL9mQdAk=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=e/ozOTrpnOCuNGUa3SiScjQ2YT1MSgcQAm5WeMkU8EiSGj9q6Uhpc5VN5XIrGykufdc/wsO9kKfD3GIREPS63xog06Y8IqZA8AuW86UGioIfLEfBOa7zvHowmtE7i00bF0esQL8zVFQteqUvvlScPJAW0Hn47274i50BINnJ4LM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=onurozkan.dev; spf=pass smtp.mailfrom=onurozkan.dev; dkim=pass (1024-bit key) header.d=onurozkan.dev header.i=@onurozkan.dev header.b=mu1V+iMp; arc=none smtp.client-ip=178.154.239.88 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=onurozkan.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=onurozkan.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=onurozkan.dev header.i=@onurozkan.dev header.b="mu1V+iMp" Received: from forward103a.mail.yandex.net (forward103a.mail.yandex.net [IPv6:2a02:6b8:c0e:500:1:45:d181:d103]) by forward205a.mail.yandex.net (Yandex) with ESMTPS id 288A6CBF89; Fri, 13 Mar 2026 12:17:57 +0300 (MSK) Received: from mail-nwsmtp-smtp-production-main-81.vla.yp-c.yandex.net (mail-nwsmtp-smtp-production-main-81.vla.yp-c.yandex.net [IPv6:2a02:6b8:c0f:571a:0:640:23e3:0]) by forward103a.mail.yandex.net (Yandex) with ESMTPS id A936B80CCD; Fri, 13 Mar 2026 12:17:48 +0300 (MSK) Received: by mail-nwsmtp-smtp-production-main-81.vla.yp-c.yandex.net (smtp/Yandex) with ESMTPSA id 3HEusrTGkmI0-kVMePrg5; Fri, 13 Mar 2026 12:17:48 +0300 X-Yandex-Fwd: 1 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=onurozkan.dev; s=mail; t=1773393468; bh=8Epwrrsq7LNYAHxJtynlSWzfRvuMl+7kFlXFQuGSZEk=; h=Cc:Message-ID:References:Date:In-Reply-To:Subject:To:From; b=mu1V+iMp1Xlzhfek9S3EnnAnGcQ053OJM6Y8J21ZaB4/uqXpVs0Wku53axPXjVrOt DsRyi303B52/nHGUO6eStJibo+60fyRz4ElzlHRokiAooXE68nnhYUCqFJ1rFaWwGo nvBn7CiH/bMvzMKwQ99Ts39LnzCA89TtAO0Pp2uo= Authentication-Results: mail-nwsmtp-smtp-production-main-81.vla.yp-c.yandex.net; dkim=pass header.i=@onurozkan.dev From: =?UTF-8?q?Onur=20=C3=96zkan?= To: linux-kernel@vger.kernel.org Cc: dakr@kernel.org, aliceryhl@google.com, daniel.almeida@collabora.com, airlied@gmail.com, simona@ffwll.ch, dri-devel@lists.freedesktop.org, rust-for-linux@vger.kernel.org, =?UTF-8?q?Onur=20=C3=96zkan?= , Deborah Brouwer Subject: [PATCH v1 RESEND 1/4] drm/tyr: clear reset IRQ before soft reset Date: Fri, 13 Mar 2026 12:16:41 +0300 Message-ID: <20260313091646.16938-2-work@onurozkan.dev> X-Mailer: git-send-email 2.51.2 In-Reply-To: <20260313091646.16938-1-work@onurozkan.dev> References: <20260313091646.16938-1-work@onurozkan.dev> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Clear RESET_COMPLETED before writing GPU_CMD_SOFT_RESET. This is also used in drivers/gpu/drm/panfrost/panfrost_gpu.c::panfrost_gpu_soft_reset and avoids seeing old reset-complete status from a previous reset. Tested-by: Deborah Brouwer Signed-off-by: Onur =C3=96zkan Reviewed-by: Boris Brezillon --- drivers/gpu/drm/tyr/driver.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/gpu/drm/tyr/driver.rs b/drivers/gpu/drm/tyr/driver.rs index 69eff2a9e116..f7951804e4e0 100644 --- a/drivers/gpu/drm/tyr/driver.rs +++ b/drivers/gpu/drm/tyr/driver.rs @@ -91,6 +91,8 @@ unsafe impl Send for TyrDrmDeviceData {} unsafe impl Sync for TyrDrmDeviceData {} =20 fn issue_soft_reset(dev: &Device, iomem: &Devres) -> Result { + // Clear any stale reset-complete IRQ state before issuing a new soft = reset. + regs::GPU_IRQ_CLEAR.write(dev, iomem, regs::GPU_IRQ_RAWSTAT_RESET_COMP= LETED)?; regs::GPU_CMD.write(dev, iomem, regs::GPU_CMD_SOFT_RESET)?; =20 poll::read_poll_timeout( --=20 2.51.2 From nobody Tue Apr 7 13:08:27 2026 Received: from forward202a.mail.yandex.net (forward202a.mail.yandex.net [178.154.239.91]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 03BCB38838E; Fri, 13 Mar 2026 09:25:18 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=178.154.239.91 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773393920; cv=none; b=edj1Mse8THmCmjrjvRGfvgUYevJ1gRy/GK88ZYg7Q2da89c2XPTSZ+7D9mIh66O7PeJZs5YymtZNItFHEl1pWWh+g6UZ66giAk0ImSi3i3mWvUo5tSZVqpyB4W/BVCLiaLqbyykBfL6yutQBOPJhJ3jOSDk3n8Vja/RaQvFAzHY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773393920; c=relaxed/simple; bh=rvm/cuYhtXHic2YIzGwAshEiwloJulsPUxFUfu0WHmQ=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=PkMNOjgp4xrTrkDM035wRoWwBtK5h6dNxRIb3F8ZEjRITcep+Sc40/yQsJd4hSBbJP1dsE2b7F1Kup5PLaKRN+CDm1XkFYTlRfTeCzWeIS36uDpdC65JY9TJH+IlCbgq9oPkUtufOIPi5mUyYOAUoQwrHVyvnt5kXUgMa9ntZg8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=onurozkan.dev; spf=pass smtp.mailfrom=onurozkan.dev; dkim=pass (1024-bit key) header.d=onurozkan.dev header.i=@onurozkan.dev header.b=cPa6NVKt; arc=none smtp.client-ip=178.154.239.91 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=onurozkan.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=onurozkan.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=onurozkan.dev header.i=@onurozkan.dev header.b="cPa6NVKt" Received: from forward100a.mail.yandex.net (forward100a.mail.yandex.net [IPv6:2a02:6b8:c0e:500:1:45:d181:d100]) by forward202a.mail.yandex.net (Yandex) with ESMTPS id C56ED8B939; Fri, 13 Mar 2026 12:17:58 +0300 (MSK) Received: from mail-nwsmtp-smtp-production-main-81.vla.yp-c.yandex.net (mail-nwsmtp-smtp-production-main-81.vla.yp-c.yandex.net [IPv6:2a02:6b8:c0f:571a:0:640:23e3:0]) by forward100a.mail.yandex.net (Yandex) with ESMTPS id 6AD42C01F9; Fri, 13 Mar 2026 12:17:51 +0300 (MSK) Received: by mail-nwsmtp-smtp-production-main-81.vla.yp-c.yandex.net (smtp/Yandex) with ESMTPSA id 3HEusrTGkmI0-oTA9aIN3; Fri, 13 Mar 2026 12:17:50 +0300 X-Yandex-Fwd: 1 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=onurozkan.dev; s=mail; t=1773393470; bh=296Sx8eOcmyen+kU5beNbjuR6rH7VCIG+e4tSjMIXSc=; h=Cc:Message-ID:References:Date:In-Reply-To:Subject:To:From; b=cPa6NVKt8iG3PHz9TchJYe5y1/ot+M2RswBlrdx3pkecqLo52GUn6vMSBfRaCZySv QTcpW0qyH4BvsRmVCynJhslr1lX03YTJZwca6Mbo6CxpSG4PUpeq0Cs8fZEcIeaWoa NbFMDBftw67jzg3FVB44fJSQKT1Gq1jkcwL/Xt1U= Authentication-Results: mail-nwsmtp-smtp-production-main-81.vla.yp-c.yandex.net; dkim=pass header.i=@onurozkan.dev From: =?UTF-8?q?Onur=20=C3=96zkan?= To: linux-kernel@vger.kernel.org Cc: dakr@kernel.org, aliceryhl@google.com, daniel.almeida@collabora.com, airlied@gmail.com, simona@ffwll.ch, dri-devel@lists.freedesktop.org, rust-for-linux@vger.kernel.org, =?UTF-8?q?Onur=20=C3=96zkan?= , Deborah Brouwer Subject: [PATCH v1 RESEND 2/4] rust: add Work::disable_sync Date: Fri, 13 Mar 2026 12:16:42 +0300 Message-ID: <20260313091646.16938-3-work@onurozkan.dev> X-Mailer: git-send-email 2.51.2 In-Reply-To: <20260313091646.16938-1-work@onurozkan.dev> References: <20260313091646.16938-1-work@onurozkan.dev> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Add Work::disable_sync() as a safe wrapper for disable_work_sync(). Drivers can use this during teardown to stop new queueing and wait for queued or running work to finish before dropping related resources. Tested-by: Deborah Brouwer Signed-off-by: Onur =C3=96zkan --- rust/kernel/workqueue.rs | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/rust/kernel/workqueue.rs b/rust/kernel/workqueue.rs index 706e833e9702..6acc7b5ba31c 100644 --- a/rust/kernel/workqueue.rs +++ b/rust/kernel/workqueue.rs @@ -530,6 +530,21 @@ pub unsafe fn raw_get(ptr: *const Self) -> *mut bindin= gs::work_struct { // the compiler does not complain that the `work` field is unused. unsafe { Opaque::cast_into(core::ptr::addr_of!((*ptr).work)) } } + + /// Disables this work item and waits for queued/running executions to= finish. + /// + /// # Safety + /// + /// Must be called from a sleepable context if the work was last queue= d on a non-BH + /// workqueue. + #[inline] + pub unsafe fn disable_sync(&self) { + let ptr: *const Self =3D self; + // SAFETY: `self` points to a valid initialized work. + let raw_work =3D unsafe { Self::raw_get(ptr) }; + // SAFETY: `raw_work` is a valid embedded `work_struct`. + unsafe { bindings::disable_work_sync(raw_work) }; + } } =20 /// Declares that a type contains a [`Work`]. --=20 2.51.2 From nobody Tue Apr 7 13:08:27 2026 Received: from forward204a.mail.yandex.net (forward204a.mail.yandex.net [178.154.239.89]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A19D4367F35; Fri, 13 Mar 2026 09:24:12 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=178.154.239.89 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773393854; cv=none; b=ZnvAOM59CCnI1DjnP5ri57kAGaJpIkSxl+atooISSy/r7t1R5FeGtwsrclcMOYXLQZ2yQDUQC0kWQomrZRNszDs2y63EDjo00uEuN9WRwCHrY52mfqjxCZiGrvzn5qQQXwC7GfjcQZZBW0t55U2I7XOgspyuZ2pNtRxtibiG9Sk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773393854; c=relaxed/simple; bh=l2zVABx0ukHupTK6cqX0MYpdDRqgh2ztr5w6jsiRguQ=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=NACQLTu5nt0CYqfpPWYcTbkop5JwIlNkwZU65PHTdo7Ct5lKKTLb/9lZGBuuhDsGKV8mg2tlPQkaB2ZP5inI+Y4RHWYTK+IGRrSJK0mZ1XLMxvFG8l3095oO94XNxAMLxwxVe+Xw6wx5UsNzdOh7qKUD3hxSLrx2tLmMj0F0Ar8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=onurozkan.dev; spf=pass smtp.mailfrom=onurozkan.dev; dkim=pass (1024-bit key) header.d=onurozkan.dev header.i=@onurozkan.dev header.b=gHaIEutB; arc=none smtp.client-ip=178.154.239.89 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=onurozkan.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=onurozkan.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=onurozkan.dev header.i=@onurozkan.dev header.b="gHaIEutB" Received: from forward102a.mail.yandex.net (forward102a.mail.yandex.net [IPv6:2a02:6b8:c0e:500:1:45:d181:d102]) by forward204a.mail.yandex.net (Yandex) with ESMTPS id D79658370F; Fri, 13 Mar 2026 12:18:00 +0300 (MSK) Received: from mail-nwsmtp-smtp-production-main-81.vla.yp-c.yandex.net (mail-nwsmtp-smtp-production-main-81.vla.yp-c.yandex.net [IPv6:2a02:6b8:c0f:571a:0:640:23e3:0]) by forward102a.mail.yandex.net (Yandex) with ESMTPS id 2EFB8C00BD; Fri, 13 Mar 2026 12:17:53 +0300 (MSK) Received: by mail-nwsmtp-smtp-production-main-81.vla.yp-c.yandex.net (smtp/Yandex) with ESMTPSA id 3HEusrTGkmI0-BP8TrAT5; Fri, 13 Mar 2026 12:17:52 +0300 X-Yandex-Fwd: 1 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=onurozkan.dev; s=mail; t=1773393472; bh=tdqZdIhYVneZTBKoqZpd0WXEPrwKrA6bsUPN0bxfmEQ=; h=Cc:Message-ID:References:Date:In-Reply-To:Subject:To:From; b=gHaIEutBFRdy7RkBqeg/y8j/aSGIwNuscD3rYoELHt5ldb05h+76hDxXJTQC/Q5Q6 5Zjw9znOQCww5bC5jc/oApxZlCEoVxLwNWbBXY5ktMHfH2Rmd4uljXqO4z20Tfngdf ccrmyZrW7AgYRDQwy3uVpDCPhNAw5xfploqGEkZo= Authentication-Results: mail-nwsmtp-smtp-production-main-81.vla.yp-c.yandex.net; dkim=pass header.i=@onurozkan.dev From: =?UTF-8?q?Onur=20=C3=96zkan?= To: linux-kernel@vger.kernel.org Cc: dakr@kernel.org, aliceryhl@google.com, daniel.almeida@collabora.com, airlied@gmail.com, simona@ffwll.ch, dri-devel@lists.freedesktop.org, rust-for-linux@vger.kernel.org, =?UTF-8?q?Onur=20=C3=96zkan?= , Deborah Brouwer Subject: [PATCH v1 RESEND 3/4] rust: add ordered workqueue wrapper Date: Fri, 13 Mar 2026 12:16:43 +0300 Message-ID: <20260313091646.16938-4-work@onurozkan.dev> X-Mailer: git-send-email 2.51.2 In-Reply-To: <20260313091646.16938-1-work@onurozkan.dev> References: <20260313091646.16938-1-work@onurozkan.dev> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Add an owned OrderedQueue wrapper for alloc_ordered_workqueue() and destroy_workqueue(). This gives Rust drivers a simple way to create and own an ordered workqueue with automatic cleanup in Drop. Tested-by: Deborah Brouwer Signed-off-by: Onur =C3=96zkan --- rust/helpers/workqueue.c | 6 +++++ rust/kernel/workqueue.rs | 47 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+) diff --git a/rust/helpers/workqueue.c b/rust/helpers/workqueue.c index ce1c3a5b2150..7cd3b000a5b6 100644 --- a/rust/helpers/workqueue.c +++ b/rust/helpers/workqueue.c @@ -14,3 +14,9 @@ __rust_helper void rust_helper_init_work_with_key(struct = work_struct *work, INIT_LIST_HEAD(&work->entry); work->func =3D func; } + +__rust_helper struct workqueue_struct * +rust_helper_alloc_ordered_workqueue(const char *name, unsigned int flags) +{ + return alloc_ordered_workqueue("%s", flags, name); +} diff --git a/rust/kernel/workqueue.rs b/rust/kernel/workqueue.rs index 6acc7b5ba31c..d5aa61a5ef93 100644 --- a/rust/kernel/workqueue.rs +++ b/rust/kernel/workqueue.rs @@ -195,6 +195,7 @@ types::Opaque, }; use core::marker::PhantomData; +use core::ptr::NonNull; =20 /// Creates a [`Work`] initialiser with the given name and a newly-created= lock class. #[macro_export] @@ -346,6 +347,52 @@ pub fn try_spawn( } } =20 +/// A kernel work queue that allocates and owns an ordered `workqueue_stru= ct`. +/// +/// Unlike [`Queue`], [`OrderedQueue`] takes ownership of the underlying C +/// workqueue and automatically destroys it when dropped. +pub struct OrderedQueue(NonNull); + +// SAFETY: Workqueue objects are thread-safe to share and use concurrently. +unsafe impl Send for OrderedQueue {} +// SAFETY: Workqueue objects are thread-safe to share and use concurrently. +unsafe impl Sync for OrderedQueue {} + +impl OrderedQueue { + /// Allocates an ordered workqueue. + /// + /// It is equivalent to C's `alloc_ordered_workqueue()`. + pub fn new(name: &'static CStr, flags: u32) -> Result { + // SAFETY: `name` is a `&'static CStr`, guaranteeing a valid, null= -terminated C + // string pointer for the duration of this call. + let ptr =3D unsafe { bindings::alloc_ordered_workqueue(name.as_cha= r_ptr(), flags) }; + let ptr =3D NonNull::new(ptr).ok_or(ENOMEM)?; + Ok(Self(ptr)) + } + + /// Enqueues a work item. + /// + /// This may fail if the work item is already enqueued in a workqueue. + /// + /// The work item will be submitted using `WORK_CPU_UNBOUND`. + pub fn enqueue(&self, w: W) -> W::EnqueueOutput + where + W: RawWorkItem + Send + 'static, + { + // SAFETY: `self.0` is valid while `self` is alive. + unsafe { Queue::from_raw(self.0.as_ptr()) }.enqueue(w) + } +} + +impl Drop for OrderedQueue { + fn drop(&mut self) { + // SAFETY: + // - Pointer comes from `alloc_ordered_workqueue()` and is owned b= y `self`. + // - `OrderedQueue` does not expose delayed scheduling API. + unsafe { bindings::destroy_workqueue(self.0.as_ptr()) }; + } +} + /// A helper type used in [`try_spawn`]. /// /// [`try_spawn`]: Queue::try_spawn --=20 2.51.2 From nobody Tue Apr 7 13:08:27 2026 Received: from forward203a.mail.yandex.net (forward203a.mail.yandex.net [178.154.239.90]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 9CF97367F35; Fri, 13 Mar 2026 09:25:01 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=178.154.239.90 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773393903; cv=none; b=AsFWtkIDrxEkJM2uD+GmhXHuj249qMhDmW+rvMhDETYIrcl7Sqg1iErBPMm9nhXL/BWq9xHLVtX2S+iSYnOYetpP9GQUWxEZ3OxyucHpmf0P4qkSjQ1uQRBOzPV6d8LeYL9cls9CdPHuj4EP2G+ErQ3HYNEMj0KTJO9H/jwzKSU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773393903; c=relaxed/simple; bh=VKkxm89BC319b2zccKXH84zwdSw78Bn9VZfWuXmckRQ=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=lCHjJ2l6TgZXh2e6LAs/b5OG+eyFiU4Ap7CRM63pqtuA1txWSk2HVf2P2DtPCq5/QLwRjPkEW2vIQlx8DcCOSJWrKXQ8CC06qh9YvSKEB7WPzS7qdTtiVAjkS8+Ge4enMiNAVr2xIhQK1bYLZLVYEDJ5vn0M+HcdNPQa/fFd1dY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=onurozkan.dev; spf=pass smtp.mailfrom=onurozkan.dev; dkim=pass (1024-bit key) header.d=onurozkan.dev header.i=@onurozkan.dev header.b=o6V5EXYb; arc=none smtp.client-ip=178.154.239.90 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=onurozkan.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=onurozkan.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=onurozkan.dev header.i=@onurozkan.dev header.b="o6V5EXYb" Received: from forward100a.mail.yandex.net (forward100a.mail.yandex.net [IPv6:2a02:6b8:c0e:500:1:45:d181:d100]) by forward203a.mail.yandex.net (Yandex) with ESMTPS id E854B8B52D; Fri, 13 Mar 2026 12:18:02 +0300 (MSK) Received: from mail-nwsmtp-smtp-production-main-81.vla.yp-c.yandex.net (mail-nwsmtp-smtp-production-main-81.vla.yp-c.yandex.net [IPv6:2a02:6b8:c0f:571a:0:640:23e3:0]) by forward100a.mail.yandex.net (Yandex) with ESMTPS id 1F36BC0210; Fri, 13 Mar 2026 12:17:55 +0300 (MSK) Received: by mail-nwsmtp-smtp-production-main-81.vla.yp-c.yandex.net (smtp/Yandex) with ESMTPSA id 3HEusrTGkmI0-lTVYqrRv; Fri, 13 Mar 2026 12:17:54 +0300 X-Yandex-Fwd: 1 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=onurozkan.dev; s=mail; t=1773393474; bh=9dj0+25F18WQitVKF1FKkRi87RpcIXAE7se35EAxq/U=; h=Cc:Message-ID:References:Date:In-Reply-To:Subject:To:From; b=o6V5EXYbZIrlufNMT5CY6vcHF7CLZMGWPOQIIQNWOypaP9l6gc+r731hUx6nvR8zA 1SDMpbmI/bhyJmP/hzKn5QuXQ73NRm+kLVhDQeHKxs7sY/Sj0jJH3z8Sw7bG6kSm5p EFx1e4qthJCkZb97tKcrNIBUk9452wNT+ztqElNs= Authentication-Results: mail-nwsmtp-smtp-production-main-81.vla.yp-c.yandex.net; dkim=pass header.i=@onurozkan.dev From: =?UTF-8?q?Onur=20=C3=96zkan?= To: linux-kernel@vger.kernel.org Cc: dakr@kernel.org, aliceryhl@google.com, daniel.almeida@collabora.com, airlied@gmail.com, simona@ffwll.ch, dri-devel@lists.freedesktop.org, rust-for-linux@vger.kernel.org, =?UTF-8?q?Onur=20=C3=96zkan?= , Deborah Brouwer Subject: [PATCH v1 RESEND 4/4] drm/tyr: add GPU reset handling Date: Fri, 13 Mar 2026 12:16:44 +0300 Message-ID: <20260313091646.16938-5-work@onurozkan.dev> X-Mailer: git-send-email 2.51.2 In-Reply-To: <20260313091646.16938-1-work@onurozkan.dev> References: <20260313091646.16938-1-work@onurozkan.dev> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Move Tyr reset logic into a new reset module and add async reset work. This adds: - ResetHandle with internal controller state - a dedicated ordered reset workqueue - a pending flag to avoid duplicate queued resets - run_reset() as the shared synchronous reset helper Probe now calls reset::run_reset() before normal init. Driver data now keeps ResetHandle so reset work is drained before clocks and regulators are dropped. Tested-by: Deborah Brouwer Signed-off-by: Onur =C3=96zkan --- drivers/gpu/drm/tyr/driver.rs | 40 +++----- drivers/gpu/drm/tyr/reset.rs | 180 ++++++++++++++++++++++++++++++++++ drivers/gpu/drm/tyr/tyr.rs | 1 + 3 files changed, 192 insertions(+), 29 deletions(-) create mode 100644 drivers/gpu/drm/tyr/reset.rs diff --git a/drivers/gpu/drm/tyr/driver.rs b/drivers/gpu/drm/tyr/driver.rs index f7951804e4e0..c80238a21ff2 100644 --- a/drivers/gpu/drm/tyr/driver.rs +++ b/drivers/gpu/drm/tyr/driver.rs @@ -6,11 +6,8 @@ OptionalClk, // }, device::{ - Bound, - Core, - Device, // + Core, // }, - devres::Devres, dma::{ Device as DmaDevice, DmaMask, // @@ -22,10 +19,7 @@ Registered, UnregisteredDevice, // }, - io::poll, - new_mutex, - of, - platform, + new_mutex, of, platform, prelude::*, regulator, regulator::Regulator, @@ -35,17 +29,15 @@ Arc, Mutex, // }, - time, // }; =20 use crate::{ file::TyrDrmFileData, fw::Firmware, gem::BoData, - gpu, gpu::GpuInfo, mmu::Mmu, - regs, // + reset, // }; =20 pub(crate) type IoMem =3D kernel::io::mem::IoMem; @@ -62,6 +54,11 @@ pub(crate) struct TyrPlatformDriverData { =20 #[pin_data] pub(crate) struct TyrDrmDeviceData { + // `ResetHandle::drop()` drains queued/running works and this must hap= pen + // before clocks/regulators are dropped. So keep this field before the= m to + // ensure the correct drop order. + pub(crate) reset: reset::ResetHandle, + pub(crate) pdev: ARef, =20 pub(crate) fw: Arc, @@ -90,22 +87,6 @@ unsafe impl Send for TyrDrmDeviceData {} // SAFETY: This will be removed in a future patch. unsafe impl Sync for TyrDrmDeviceData {} =20 -fn issue_soft_reset(dev: &Device, iomem: &Devres) -> Result { - // Clear any stale reset-complete IRQ state before issuing a new soft = reset. - regs::GPU_IRQ_CLEAR.write(dev, iomem, regs::GPU_IRQ_RAWSTAT_RESET_COMP= LETED)?; - regs::GPU_CMD.write(dev, iomem, regs::GPU_CMD_SOFT_RESET)?; - - poll::read_poll_timeout( - || regs::GPU_IRQ_RAWSTAT.read(dev, iomem), - |status| *status & regs::GPU_IRQ_RAWSTAT_RESET_COMPLETED !=3D 0, - time::Delta::from_millis(1), - time::Delta::from_millis(100), - ) - .inspect_err(|_| dev_err!(dev, "GPU reset failed."))?; - - Ok(()) -} - kernel::of_device_table!( OF_TABLE, MODULE_OF_TABLE, @@ -138,8 +119,7 @@ fn probe( let request =3D pdev.io_request_by_index(0).ok_or(ENODEV)?; let iomem =3D Arc::pin_init(request.iomap_sized::(), GFP_KE= RNEL)?; =20 - issue_soft_reset(pdev.as_ref(), &iomem)?; - gpu::l2_power_on(pdev.as_ref(), &iomem)?; + reset::run_reset(pdev.as_ref(), &iomem)?; =20 let gpu_info =3D GpuInfo::new(pdev.as_ref(), &iomem)?; gpu_info.log(pdev); @@ -153,6 +133,7 @@ fn probe( =20 let uninit_ddev =3D UnregisteredDevice::::new(pdev.a= s_ref())?; let platform: ARef =3D pdev.into(); + let reset =3D reset::ResetHandle::new(platform.clone(), iomem.clon= e())?; =20 let mmu =3D Mmu::new(pdev, iomem.as_arc_borrow(), &gpu_info)?; =20 @@ -178,6 +159,7 @@ fn probe( _mali: mali_regulator, _sram: sram_regulator, }), + reset, gpu_info, }); let ddev =3D Registration::new_foreign_owned(uninit_ddev, pdev.as_= ref(), data, 0)?; diff --git a/drivers/gpu/drm/tyr/reset.rs b/drivers/gpu/drm/tyr/reset.rs new file mode 100644 index 000000000000..29dfae98b0dd --- /dev/null +++ b/drivers/gpu/drm/tyr/reset.rs @@ -0,0 +1,180 @@ +// SPDX-License-Identifier: GPL-2.0 or MIT + +//! Provides asynchronous reset handling for the Tyr DRM driver via +//! [`ResetHandle`], which runs reset work on a dedicated ordered +//! workqueue and avoids duplicate pending resets. + +use kernel::{ + device::{ + Bound, + Device, // + }, + devres::Devres, + io::poll, + platform, + prelude::*, + sync::{ + aref::ARef, + atomic::{ + Acquire, + Atomic, + Relaxed, + Release, // + }, + Arc, + }, + time, + workqueue::{ + self, + Work, // + }, +}; + +use crate::{ + driver::IoMem, + gpu, + regs, // +}; + +/// Manages asynchronous GPU reset handling and ensures only a single reset +/// work is pending at a time. +#[pin_data] +struct Controller { + /// Platform device reference needed for reset operations and logging. + pdev: ARef, + /// Mapped register space needed for reset operations. + iomem: Arc>, + /// Atomic flag for controlling the scheduling pending state. + pending: Atomic, + /// Dedicated ordered workqueue for reset operations. + wq: workqueue::OrderedQueue, + /// Work item backing async reset processing. + #[pin] + work: Work, +} + +kernel::impl_has_work! { + impl HasWork for Controller { self.work } +} + +impl workqueue::WorkItem for Controller { + type Pointer =3D Arc; + + fn run(this: Arc) { + this.reset_work(); + } +} + +impl Controller { + /// Creates a [`Controller`] instance. + fn new(pdev: ARef, iomem: Arc>) -> Res= ult> { + let wq =3D workqueue::OrderedQueue::new(c"tyr-reset-wq", 0)?; + + Arc::pin_init( + try_pin_init!(Self { + pdev, + iomem, + pending: Atomic::new(false), + wq, + work <- kernel::new_work!("tyr::reset"), + }), + GFP_KERNEL, + ) + } + + /// Processes one scheduled reset request. + /// + /// Panthor reference: + /// - drivers/gpu/drm/panthor/panthor_device.c::panthor_device_reset_w= ork() + fn reset_work(self: &Arc) { + dev_info!(self.pdev.as_ref(), "GPU reset work is started.\n"); + + // SAFETY: `Controller` is part of driver-private data and only ex= ists + // while the platform device is bound. + let pdev =3D unsafe { self.pdev.as_ref().as_bound() }; + if let Err(e) =3D run_reset(pdev, &self.iomem) { + dev_err!(self.pdev.as_ref(), "GPU reset failed: {:?}\n", e); + } else { + dev_info!(self.pdev.as_ref(), "GPU reset work is done.\n"); + } + + self.pending.store(false, Release); + } +} + +/// Reset handle that shuts down pending work gracefully on drop. +pub(crate) struct ResetHandle(Arc); + +impl ResetHandle { + /// Creates a [`ResetHandle`] instance. + pub(crate) fn new(pdev: ARef, iomem: Arc>) -> Result { + Ok(Self(Controller::new(pdev, iomem)?)) + } + + /// Schedules reset work. + #[expect(dead_code)] + pub(crate) fn schedule(&self) { + // TODO: Similar to `panthor_device_schedule_reset()` in Panthor, = add a + // power management check once Tyr supports it. + + // Keep only one reset request running or queued. If one is alread= y pending, + // we ignore new schedule requests. + if self.0.pending.cmpxchg(false, true, Relaxed).is_ok() + && self.0.wq.enqueue(self.0.clone()).is_err() + { + self.0.pending.store(false, Release); + } + } + + /// Returns true if a reset is queued or in progress. + /// + /// Note that the state can change immediately after the return. + #[inline] + #[expect(dead_code)] + pub(crate) fn is_pending(&self) -> bool { + self.0.pending.load(Acquire) + } +} + +impl Drop for ResetHandle { + fn drop(&mut self) { + // Drain queued/running work and block future queueing attempts fo= r this + // work item before clocks/regulators are torn down. + // SAFETY: drop executes in a sleepable context. + unsafe { self.0.work.disable_sync() }; + } +} + +/// Issues a soft reset command and waits for reset-complete IRQ status. +fn issue_soft_reset(dev: &Device, iomem: &Devres) -> Result { + // Clear any stale reset-complete IRQ state before issuing a new soft = reset. + regs::GPU_IRQ_CLEAR.write(dev, iomem, regs::GPU_IRQ_RAWSTAT_RESET_COMP= LETED)?; + regs::GPU_CMD.write(dev, iomem, regs::GPU_CMD_SOFT_RESET)?; + + poll::read_poll_timeout( + || regs::GPU_IRQ_RAWSTAT.read(dev, iomem), + |status| *status & regs::GPU_IRQ_RAWSTAT_RESET_COMPLETED !=3D 0, + time::Delta::from_millis(1), + time::Delta::from_millis(100), + ) + .inspect_err(|_| dev_err!(dev, "GPU reset failed."))?; + + Ok(()) +} + +/// Runs one synchronous GPU reset pass. +/// +/// Its visibility is `pub(super)` only so the probe path can run an +/// initial reset; it is not part of this module's public API. +/// +/// On success, the GPU is left in a state suitable for reinitialization. +/// +/// The reset sequence is as follows: +/// 1. Trigger a GPU soft reset. +/// 2. Wait for the reset-complete IRQ status. +/// 3. Power L2 back on. +pub(super) fn run_reset(dev: &Device, iomem: &Devres) -> Res= ult { + issue_soft_reset(dev, iomem)?; + gpu::l2_power_on(dev, iomem)?; + Ok(()) +} diff --git a/drivers/gpu/drm/tyr/tyr.rs b/drivers/gpu/drm/tyr/tyr.rs index 18b0668bb217..d0349bc49f27 100644 --- a/drivers/gpu/drm/tyr/tyr.rs +++ b/drivers/gpu/drm/tyr/tyr.rs @@ -14,6 +14,7 @@ mod gpu; mod mmu; mod regs; +mod reset; mod slot; mod vm; =20 --=20 2.51.2