From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 57E82ECD6DA for ; Wed, 11 Feb 2026 19:54:53 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id AC01910E0BE; Wed, 11 Feb 2026 19:54:52 +0000 (UTC) Authentication-Results: gabe.freedesktop.org; dkim=pass (1024-bit key; unprotected) header.d=onurozkan.dev header.i=@onurozkan.dev header.b="Ca2b7sBP"; dkim-atps=neutral Received: from forward103b.mail.yandex.net (forward103b.mail.yandex.net [178.154.239.150]) by gabe.freedesktop.org (Postfix) with ESMTPS id EBB2B10E0BE for ; Wed, 11 Feb 2026 19:54:50 +0000 (UTC) Received: from mail-nwsmtp-smtp-production-main-98.sas.yp-c.yandex.net (mail-nwsmtp-smtp-production-main-98.sas.yp-c.yandex.net [IPv6:2a02:6b8:c23:1ba8:0:640:1638:0]) by forward103b.mail.yandex.net (Yandex) with ESMTPS id 3D5B8C005E; Wed, 11 Feb 2026 22:54:48 +0300 (MSK) Received: by mail-nwsmtp-smtp-production-main-98.sas.yp-c.yandex.net (smtp/Yandex) with ESMTPSA id 9sZcv22Hu8c0-yYzEm5xR; Wed, 11 Feb 2026 22:54:47 +0300 X-Yandex-Fwd: 1 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=onurozkan.dev; s=mail; t=1770839687; bh=tVROmgJcpnBTWH2agRberTX2KctPC87mIpAm+yAPRQI=; h=Message-ID:Date:Cc:Subject:To:From; b=Ca2b7sBPC3FyX/Y1dRNRBOVQgvzeVK8iUQflDo2aNUZPtX9TXQxIbntmY5sBu2vmZ nKtqlNxAhD6N/Wg/ivMpAuvDbLhBSsVwoeOKF32NzxDa870eAwCr30AKmdjmZjitd3 FeL78K6dEA9eDbXt8z2NKaWtI0f87ZYgpEQfmmYE= Authentication-Results: mail-nwsmtp-smtp-production-main-98.sas.yp-c.yandex.net; dkim=pass header.i=@onurozkan.dev From: =?UTF-8?q?Onur=20=C3=96zkan?= To: daniel.almeida@collabora.com, aliceryhl@google.com, dakr@kernel.org, airlied@gmail.com, simona@ffwll.ch, dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, lgirdwood@gmail.com, broonie@kernel.org, ojeda@kernel.org, rust-for-linux@vger.kernel.org Cc: =?UTF-8?q?Onur=20=C3=96zkan?= Subject: [PATCH v1] drm/tyr: make SRAM supply optional like panthor Date: Wed, 11 Feb 2026 22:54:06 +0300 Message-ID: <20260211195406.289634-1-work@onurozkan.dev> X-Mailer: git-send-email 2.51.2 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" On rk3588s, `dmesg | grep 'tyr'` logs: tyr fb000000.gpu: supply SRAM not found, using dummy regulator This happens because Tyr calls Regulator::get() for SRAM, which goes through the non-optional regulator_get() path. If the device tree doesn't provide sram-supply, regulator core falls back to a dummy regulator and writes that log. Panthor handles SRAM as optional and tolerates missing sram-supply. This patch matches that behavior in Tyr by using optional regulator lookup and storing SRAM as Option> which avoids dummy-regulator fallback/noise when SRAM is not described inside the device tree. Link: https://rust-for-linux.zulipchat.com/#narrow/stream/x/topic/x/near/573210018 Signed-off-by: Onur Özkan --- drivers/gpu/drm/tyr/driver.rs | 5 +++-- rust/kernel/regulator.rs | 40 +++++++++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/tyr/driver.rs b/drivers/gpu/drm/tyr/driver.rs index 0389c558c036..e0856deb83ec 100644 --- a/drivers/gpu/drm/tyr/driver.rs +++ b/drivers/gpu/drm/tyr/driver.rs @@ -113,7 +113,8 @@ fn probe( coregroup_clk.prepare_enable()?; let mali_regulator = Regulator::::get(pdev.as_ref(), c_str!("mali"))?; - let sram_regulator = Regulator::::get(pdev.as_ref(), c_str!("sram"))?; + let sram_regulator = + Regulator::::get_optional(pdev.as_ref(), c_str!("sram"))?; let request = pdev.io_request_by_index(0).ok_or(ENODEV)?; let iomem = Arc::pin_init(request.iomap_sized::(), GFP_KERNEL)?; @@ -201,5 +202,5 @@ struct Clocks { #[pin_data] struct Regulators { mali: Regulator, - sram: Regulator, + sram: Option>, } diff --git a/rust/kernel/regulator.rs b/rust/kernel/regulator.rs index 2c44827ad0b7..8d95e5e80051 100644 --- a/rust/kernel/regulator.rs +++ b/rust/kernel/regulator.rs @@ -283,6 +283,29 @@ fn get_internal(dev: &Device, name: &CStr) -> Result> { }) } + fn get_optional_internal(dev: &Device, name: &CStr) -> Result>> { + // SAFETY: It is safe to call `regulator_get_optional()`, on a + // device pointer received from the C code. + let inner = from_err_ptr(unsafe { + bindings::regulator_get_optional(dev.as_raw(), name.as_char_ptr()) + }); + + let inner = match inner { + Ok(inner) => inner, + Err(ENODEV) => return Ok(None), + Err(err) => return Err(err), + }; + + // SAFETY: We can safely trust `inner` to be a pointer to a valid + // regulator if `ERR_PTR` was not returned. + let inner = unsafe { NonNull::new_unchecked(inner) }; + + Ok(Some(Self { + inner, + _phantom: PhantomData, + })) + } + fn enable_internal(&self) -> Result { // SAFETY: Safe as per the type invariants of `Regulator`. to_result(unsafe { bindings::regulator_enable(self.inner.as_ptr()) }) @@ -300,6 +323,11 @@ pub fn get(dev: &Device, name: &CStr) -> Result { Regulator::get_internal(dev, name) } + /// Obtains an optional [`Regulator`] instance from the system. + pub fn get_optional(dev: &Device, name: &CStr) -> Result> { + Regulator::get_optional_internal(dev, name) + } + /// Attempts to convert the regulator to an enabled state. pub fn try_into_enabled(self) -> Result, Error> { // We will be transferring the ownership of our `regulator_get()` count to @@ -329,6 +357,18 @@ pub fn get(dev: &Device, name: &CStr) -> Result { .map_err(|error| error.error) } + /// Obtains an optional [`Regulator`] instance from the system and enables it. + pub fn get_optional(dev: &Device, name: &CStr) -> Result> { + match Regulator::::get_optional_internal(dev, name)? { + Some(regulator) => { + let enabled_regulator = + regulator.try_into_enabled().map_err(|error| error.error)?; + Ok(Some(enabled_regulator)) + } + None => Ok(None), + } + } + /// Attempts to convert the regulator to a disabled state. pub fn try_into_disabled(self) -> Result, Error> { // We will be transferring the ownership of our `regulator_get()` count -- 2.51.2