From nobody Thu Apr 2 17:15:14 2026 Received: from forward103b.mail.yandex.net (forward103b.mail.yandex.net [178.154.239.150]) (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 DEFEA2EDD62; Wed, 11 Feb 2026 19:54:55 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=178.154.239.150 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770839699; cv=none; b=PInytty98VOP/muOpxq5O6DxnWJDih/uQp99KFPep/NAE0W+THqBT4QyCDgbtD0V7kyS+6IUtNGcXcco3DLc1pJlqBYXoACtQlL71oWjneGOWiIfK/GVDD2lz1fPWw0H4igeziUxyPJMb2Jdfd6K0Ygy/KVw8c6Ia4wNHqZmHTY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770839699; c=relaxed/simple; bh=zGHlXKDYrJluZ5MkoqttAQNx/xy0GXIVqTPejTbV/V8=; h=From:To:Cc:Subject:Date:Message-ID:MIME-Version:Content-Type; b=B7rhBtoOnH6x9TGbtYOkQv44xUF2ECKL6MiJH8QUJoNzSi1sjwcC3DMupBp5QkrQeA0XkWS6ErZptU2XF+5WVmEDM+1tKFLT5BMeLMNCfy8y4jNBsHNdYS91vctH99rhNN1zQ93z6ze7b8MmpYVGZnKZ9mz3Ke6Lo2g65u7Fh4c= 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=Ca2b7sBP; arc=none smtp.client-ip=178.154.239.150 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="Ca2b7sBP" 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 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 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/57= 3210018 Signed-off-by: Onur =C3=96zkan --- 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()?; =20 let mali_regulator =3D Regulator::::get(pdev.a= s_ref(), c_str!("mali"))?; - let sram_regulator =3D Regulator::::get(pdev.a= s_ref(), c_str!("sram"))?; + let sram_regulator =3D + Regulator::::get_optional(pdev.as_ref(), c= _str!("sram"))?; =20 let request =3D pdev.io_request_by_index(0).ok_or(ENODEV)?; let iomem =3D Arc::pin_init(request.iomap_sized::(), GFP_KE= RNEL)?; @@ -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> { }) } =20 + 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 =3D from_err_ptr(unsafe { + bindings::regulator_get_optional(dev.as_raw(), name.as_char_pt= r()) + }); + + let inner =3D match inner { + Ok(inner) =3D> inner, + Err(ENODEV) =3D> return Ok(None), + Err(err) =3D> 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 =3D 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) } =20 + /// 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) } =20 + /// Obtains an optional [`Regulator`] instance from the system and ena= bles it. + pub fn get_optional(dev: &Device, name: &CStr) -> Result>= { + match Regulator::::get_optional_internal(dev, name)? { + Some(regulator) =3D> { + let enabled_regulator =3D + regulator.try_into_enabled().map_err(|error| error.err= or)?; + Ok(Some(enabled_regulator)) + } + None =3D> 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 --=20 2.51.2