From nobody Fri Sep 25 10:38:03 2026 Received: from mx0b-0031df01.pphosted.com (mx0b-0031df01.pphosted.com [205.220.180.131]) (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 E94CB36494B; Mon, 14 Sep 2026 04:39:20 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=205.220.180.131 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789360762; cv=none; b=A9ua08IHGfzP6HOsIR3/PZV0F8QXLr77ET1E2b0zEt8FVzULby+KaZ/HnB4z2GPUl/tdz8CK8YUZJ+jSZb87qjP4huZzzD2ga0ijidjx+94PyMsTYHpGJcw2tJc0chYoHjX84cEbvcHUGMtU9s0aue1wJGBp+K9qzWPvOOshs+0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789360762; c=relaxed/simple; bh=Jf//lRDz3flR2m9+z2nB27S+N9VfH8xw32JAlPzTShA=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=NZidpwaM+i+pg2gpi5YdEuQL1NubMe+OXWzOpOAQgK8irlqJ7BlolLHOIADf1HbjEndALZYSTcbUGm0m1M4JtM73a8HYT/KlZbR5HD3J6Ph6WPuueuCNjp3qZwJeWB3MBhO4VAbz+DfNXxGm3n+eYSbXO7G45xClZ/zqBc0zBwQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com; spf=pass smtp.mailfrom=oss.qualcomm.com; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b=OfpN3HFK; arc=none smtp.client-ip=205.220.180.131 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b="OfpN3HFK" Received: from pps.filterd (m0279868.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 68E2ejIH3349103; Mon, 14 Sep 2026 04:38:52 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=qualcomm.com; h= cc:content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s=qcppdkim1; bh= 3txe3yu6jGxScXy2YvkNYUJwJvPmVYDUc+F0+CCds34=; b=OfpN3HFKNWJhyMD6 HcOA5kB9PxZN6onRmoxnkuOYbxXpjruFJV5r6Asvc54g8H721bwNYDq6W6NgEe4+ Y74adieNF7DbIjOO9RrCkAGAdlJkYPqzQ2w1+joOs589U/mnM/ThPWDs+2g7ybCq uTYPXS6nLoHMEiXPi9uSUgMHneeaNMjSD65AVNVMa1yc+DxoWj9dU1a+g+bR/Ain ndelylfvrKDdP4TGb071aiC5Q9ibPhTzTFsFYyFtQPtaSKOijD6kNEGqxHAQ7Pd2 rE8SLVLMKOkihQVdNIL7UsC6tLGiK14nZxPGo0Lef4q/aS5HRkWsXW+wY1B7e6G5 Yka7Ow== Received: from apblrppmta02.qualcomm.com (blr-bdr-fw-01_GlobalNAT_AllZones-Outside.qualcomm.com [103.229.18.19]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 4gmy9dd0qw-1 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NOT); Mon, 14 Sep 2026 04:38:51 +0000 (GMT) Received: from pps.filterd (apblrppmta02.qualcomm.com [127.0.0.1]) by APBLRPPMTA02.qualcomm.com (8.18.1.11/8.18.1.11) with ESMTP id 68E4cnfQ811242; Mon, 14 Sep 2026 04:38:49 GMT Received: from hu-ffaruque-hyd.qualcomm.com (hu-ffaruque-hyd.qualcomm.com [10.147.245.31]) by APBLRPPMTA02.qualcomm.com (PPS) with ESMTP id 68E4cm1k811221; Mon, 14 Sep 2026 04:38:49 +0000 (GMT) From: Faruque Ansari Date: Mon, 14 Sep 2026 10:08:45 +0530 Subject: [PATCH v3 1/3] dt-bindings: nvmem: layouts: Add PSCRR NVMEM layout 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 Message-Id: <20260914-pscrr-provider-v3-1-c45cb16542e8@oss.qualcomm.com> References: <20260914-pscrr-provider-v3-0-c45cb16542e8@oss.qualcomm.com> In-Reply-To: <20260914-pscrr-provider-v3-0-c45cb16542e8@oss.qualcomm.com> To: Oleksij Rempel , Pengutronix Kernel Team , Sebastian Reichel , Rob Herring , Krzysztof Kozlowski , Wim Van Sebroeck , Guenter Roeck , Benson Leung , Tzung-Bi Shih , Srinivas Kandagatla , Daniel Lezcano Cc: linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org, linux-pm@vger.kernel.org, devicetree@vger.kernel.org, linux-watchdog@vger.kernel.org, kernel@pengutronix.de, Liam Girdwood , Mark Brown , "Rafael J. Wysocki" , Zhang Rui , Lukasz Luba , =?utf-8?q?S=C3=B8ren_Andersen?= , Guenter Roeck , Matti Vaittinen , Ahmad Fatoum , Andrew Morton , avaneesh.dwivedi@oss.qualcomm.com, Umang Chheda , Faruque Ansari X-Mailer: b4 0.14.3 X-Proofpoint-Reinject: loops=2 maxloops=12 X-QCInternal: smtphost X-QCInternal: smtphost X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwOTE0MDA2MSBTYWx0ZWRfX/GylF/Y7QMW5 hDVmY/J5Ct6CYYdHaneh2x1DsNYQM2kpV1/YTFC7vZDypfXI2JiCyTeu/OQbZX67Z1QAmWZ8X33 Tevdi737BVkCP0ERYMsOEoOvmeYYD9wY4fTiHnisXxwxEFLeNGXu1fxE4l54+qZfT3caI+oKmiT 2zGwCunygpaPf5T0ppM9WW5q3Mu8pfaoBKT09G10D/WlPo4ocg07IKqmBSZpWKYUsxri1feS04b JJkEK00rWsaAiTT2jYi9YPxBkYddaql383SbP54D5DY3VURhCyve6wRi98LUIX25tYeW/z2Pce8 jf0DX+2Ayuw6fJ8wwYsvEvTm1spVTjHY4BDDrTx0UH0fn+Wx5EBEODemXjGG0MIjyCBc5/BZumL HaRagGNbSx2XEehGAhdcPj95z1tynWRfLJMxHdmLpF0jemV24TtoY17vsf0bcdtFHObSi5Xqk+f sabknjtu4qOE9mCyxdw== X-Proofpoint-Spam-Info: AW1haW4tMjYwOTE0MDA2MSBTYWx0ZWRfX9rsEnXumNPKu qCcfdDs3rmnVyluNk8FyLnmv+lTZzCYy4DHfJk0aNLbuh2Kd5G7QQI2sz0N2U0GAYVT3t9RzPEx uJv8QBRIp/XPuuMGvFeocOyqpuIrfIc= X-Proofpoint-GUID: s8esPd92c-UOiuQyFCC_OUsilfC16_zX X-Authority-Analysis: v=2.4 cv=OeUNnRTY c=1 sm=1 tr=0 ts=6aa77a5c cx=c_pps a=Ou0eQOY4+eZoSc0qltEV5Q==:117 a=Ou0eQOY4+eZoSc0qltEV5Q==:17 a=IkcTkHD0fZMA:10 a=VdqzKS8jKosA:10 a=VkNPw1HP01LnGYTKEx00:22 a=u7WPNUs3qKkmUXheDGA7:22 a=ZpdpYltYx_vBUK5n70dp:22 a=gEfo2CItAAAA:8 a=EUspDBNiAAAA:8 a=VwQbUJbxAAAA:8 a=T2scfIwO0EnMTC8JHKIA:9 a=QEXdDO2ut3YA:10 a=sptkURWiP4Gy88Gu7hUp:22 X-Proofpoint-ORIG-GUID: s8esPd92c-UOiuQyFCC_OUsilfC16_zX X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1176,Hydra:6.1.134,FMLib:17.12.100.49 definitions=2026-09-14_01,2026-09-13_01,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 lowpriorityscore=0 malwarescore=0 phishscore=0 bulkscore=0 spamscore=0 priorityscore=1501 suspectscore=0 impostorscore=0 adultscore=0 clxscore=1015 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2609040000 definitions=main-2609140061 Add a schema for the PSCRR NVMEM layout, which persists the power state change reason in a single NVMEM cell so it survives a power cycle and can be read back on the next boot. Signed-off-by: Faruque Ansari Reviewed-by: Rob Herring (Arm) --- .../bindings/nvmem/layouts/nvmem-layout.yaml | 1 + .../bindings/nvmem/layouts/pscrr-nvmem.yaml | 87 ++++++++++++++++++= ++++ MAINTAINERS | 1 + 3 files changed, 89 insertions(+) diff --git a/Documentation/devicetree/bindings/nvmem/layouts/nvmem-layout.y= aml b/Documentation/devicetree/bindings/nvmem/layouts/nvmem-layout.yaml index 382507060651..24545db61416 100644 --- a/Documentation/devicetree/bindings/nvmem/layouts/nvmem-layout.yaml +++ b/Documentation/devicetree/bindings/nvmem/layouts/nvmem-layout.yaml @@ -21,6 +21,7 @@ oneOf: - $ref: fixed-layout.yaml - $ref: kontron,sl28-vpd.yaml - $ref: onie,tlv-layout.yaml + - $ref: pscrr-nvmem.yaml - $ref: u-boot,env.yaml =20 properties: diff --git a/Documentation/devicetree/bindings/nvmem/layouts/pscrr-nvmem.ya= ml b/Documentation/devicetree/bindings/nvmem/layouts/pscrr-nvmem.yaml new file mode 100644 index 000000000000..118669d33f5c --- /dev/null +++ b/Documentation/devicetree/bindings/nvmem/layouts/pscrr-nvmem.yaml @@ -0,0 +1,87 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/nvmem/layouts/pscrr-nvmem.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: NVMEM layout for the Power State Change Reason recorder (PSCRR) + +maintainers: + - Faruque Ansari + - Oleksij Rempel + +description: + An NVMEM layout for a Power State Change Reason (PSCRR) recorder. The + reboot or shutdown cause is persisted into a single small NVMEM cell, + such as an RTC scratch register, a PMIC SDAM (Scratch Data Access Memory) + byte, or an EEPROM byte, so the reason survives a power cycle and can be + read back on the next boot. + +select: false + +properties: + compatible: + const: pscrr-nvmem + + "#address-cells": + const: 1 + + "#size-cells": + const: 1 + +patternProperties: + "^.*@[0-9a-f]+$": + type: object + description: + The single NVMEM cell used to persist the power state change reason. + + properties: + reg: + items: + - items: + - description: Offset, in bytes, of the cell within the + parent NVMEM device. + - const: 1 + description: + Offset and size, in bytes, of the cell within the parent NVMEM + device. The reason value occupies a single byte, so the size + must be 1. + + bits: + $ref: /schemas/types.yaml#/definitions/uint32-array + items: + - minimum: 0 + maximum: 7 + description: + Bit offset within the byte addressed by reg. + - minimum: 1 + maximum: 8 + description: + Number of bits used to store the reason. Must be wide enough + to hold every value of enum psc_reason (currently 4 bits or + more). + description: + Optional. When absent, the whole byte addressed by reg is used. + + required: + - reg + + additionalProperties: false + +required: + - compatible + +additionalProperties: false + +examples: + - | + nvmem-layout { + compatible =3D "pscrr-nvmem"; + #address-cells =3D <1>; + #size-cells =3D <1>; + + reboot-reason-persist@49 { + reg =3D <0x49 0x1>; + bits =3D <0 4>; + }; + }; diff --git a/MAINTAINERS b/MAINTAINERS index 19b9f6605d98..51f31e95f4ea 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -21693,6 +21693,7 @@ R: Pengutronix Kernel Team L: linux-pm@vger.kernel.org S: Maintained F: Documentation/ABI/testing/sysfs-kernel-pscrr +F: Documentation/devicetree/bindings/nvmem/layouts/pscrr-nvmem.yaml F: drivers/power/reset/pscrr/ F: include/linux/pscrr.h F: tools/testing/selftests/pscrr/ --=20 2.34.1 From nobody Fri Sep 25 10:38:03 2026 Received: from mx0b-0031df01.pphosted.com (mx0b-0031df01.pphosted.com [205.220.180.131]) (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 B0B5D37187F; Mon, 14 Sep 2026 04:39:21 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=205.220.180.131 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789360763; cv=none; b=HWF4zMrXXLaN+cfSNqKlrH4u2a7IWvkBM1AKn94B9QyGHGqRDEKFRSX6DbJsZCC2mR1UKCCIq6NEJlG6ZuAP7TJXTm6ZPgaKfUOjWIe/zLYF1jYkz6IAsav3dn81lJR5XX/0A/uVsdEDPLZR6TZsnatsaSw/BNmkzswCMTxmYzg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789360763; c=relaxed/simple; bh=15LMnO2wrHN3YSxzTuWxS1uP+Ve8hcmU5iWTTs9VkJE=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=CA9/VQibtTJhdjjwAQK6mLsWivYSzp1mJj45hvvVA9QRP9ZBoaPzySq+ur+NIcH2ku9YwJA27FbQ6DyD5d1ujWNVgFnpwsXdUs/c85GjmoiMnSgmYSBJXuCyNpjyx3M17+sjNsiwiuDSrapVqNrEM8xIgPR9WUGhUPyzrhjMueM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com; spf=pass smtp.mailfrom=oss.qualcomm.com; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b=iO/gV6lT; arc=none smtp.client-ip=205.220.180.131 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b="iO/gV6lT" Received: from pps.filterd (m0279870.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 68E2eSCi3671285; Mon, 14 Sep 2026 04:38:52 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=qualcomm.com; h= cc:content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s=qcppdkim1; bh= kdTc+KLQyEBRM2aXQDsAocP22KpoZQf7glsEGlA2jiY=; b=iO/gV6lTIW1Mkb3v 1/zpKYNO9r9Z01s6nmlkDSw3cfLCX/1mKC2A4tU40JrwBzHun2/pfcxQpll6kYcD aLY7tOoTTF4DGAMKdpqWPKCLbEFBzJNfs4keBv3k69hSB31Tj2biNL0IkeXhyUjr TLwcXlPlEpbtU+pmhDX/R1TYqDuLyarBguqvzYHXROGwjNxvmIZ+olGwRMnx0tr+ pJjoxxUswqa/BWrA/8k5l/ozgoza7BXQDla6M/VNHMzfsYTu0nwXWVM6Loiz10TV EYzNLR2X7ZXjrMtFwXnFCll+i4lqUkmqJ5p2iA9082jPKQlKaDedoWLx63/7sM6H G1xgLg== Received: from apblrppmta02.qualcomm.com (blr-bdr-fw-01_GlobalNAT_AllZones-Outside.qualcomm.com [103.229.18.19]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 4gp3hsrug2-1 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NOT); Mon, 14 Sep 2026 04:38:52 +0000 (GMT) Received: from pps.filterd (apblrppmta02.qualcomm.com [127.0.0.1]) by APBLRPPMTA02.qualcomm.com (8.18.1.11/8.18.1.11) with ESMTP id 68E4cn2h811256; Mon, 14 Sep 2026 04:38:49 GMT Received: from hu-ffaruque-hyd.qualcomm.com (hu-ffaruque-hyd.qualcomm.com [10.147.245.31]) by APBLRPPMTA02.qualcomm.com (PPS) with ESMTP id 68E4cm1l811221; Mon, 14 Sep 2026 04:38:49 +0000 (GMT) From: Faruque Ansari Date: Mon, 14 Sep 2026 10:08:46 +0530 Subject: [PATCH v3 2/3] power: reset: Add PSCRR NVMEM recorder 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 Message-Id: <20260914-pscrr-provider-v3-2-c45cb16542e8@oss.qualcomm.com> References: <20260914-pscrr-provider-v3-0-c45cb16542e8@oss.qualcomm.com> In-Reply-To: <20260914-pscrr-provider-v3-0-c45cb16542e8@oss.qualcomm.com> To: Oleksij Rempel , Pengutronix Kernel Team , Sebastian Reichel , Rob Herring , Krzysztof Kozlowski , Wim Van Sebroeck , Guenter Roeck , Benson Leung , Tzung-Bi Shih , Srinivas Kandagatla , Daniel Lezcano Cc: linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org, linux-pm@vger.kernel.org, devicetree@vger.kernel.org, linux-watchdog@vger.kernel.org, kernel@pengutronix.de, Liam Girdwood , Mark Brown , "Rafael J. Wysocki" , Zhang Rui , Lukasz Luba , =?utf-8?q?S=C3=B8ren_Andersen?= , Guenter Roeck , Matti Vaittinen , Ahmad Fatoum , Andrew Morton , avaneesh.dwivedi@oss.qualcomm.com, Umang Chheda , Faruque Ansari X-Mailer: b4 0.14.3 X-Proofpoint-Reinject: loops=2 maxloops=12 X-QCInternal: smtphost X-QCInternal: smtphost X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwOTE0MDA2MSBTYWx0ZWRfX+3lr2EVZT1Fg zxOASOXV9Tyn0l8PzpnzkiVzyyi8g8qMORwqfW/fACFuxk0+B0zEML9/eVBUheU3ZJwOeD3fN38 bHXGFsU7f/XmVIJUSObAgaFDZqLY19TQ5or9MfT0WBD5D0eWptaQ9AsSbtxl3NB1EZJ9LiuBrV1 Dn25UvKiwSNrZUhT40VeQPEF0uheR2m/o5Jo5H+XqhgD0sNV5KhrQuVFxm/OYXWzwx5xx+O6Pqw /ehEOPv2xPqZOeWyUWiw80BS0tLCWWFCZwFTkmu4SYZk96VlicOa/LOygOmHDNEUQCK/ziIzMaY hte1gbiG78gMFJXdMszXh1x3Qh7FNDX+O6UK2wjkZdusBtj9L6rVSMPM6c0LMYS1sMs677clETU jeg70CAn+zZrZUiVrRP3Ag7ItAXCC2qpYKLEe4i3fdOvhpPj0Ia/zzNWi9kTw28pswHEiAraqqy 89F/rd/fBWrRZvdTZEw== X-Authority-Analysis: v=2.4 cv=IZwSymqa c=1 sm=1 tr=0 ts=6aa77a5c cx=c_pps a=Ou0eQOY4+eZoSc0qltEV5Q==:117 a=Ou0eQOY4+eZoSc0qltEV5Q==:17 a=IkcTkHD0fZMA:10 a=VdqzKS8jKosA:10 a=VkNPw1HP01LnGYTKEx00:22 a=u7WPNUs3qKkmUXheDGA7:22 a=gowsoOTTUOVcmtlkKump:22 a=EUspDBNiAAAA:8 a=4NpiubGSDSypE1FgfBwA:9 a=QEXdDO2ut3YA:10 X-Proofpoint-GUID: A8ZkH-16WYdNgX8asI71vGKHz_mLZR5i X-Proofpoint-Spam-Info: AW1haW4tMjYwOTE0MDA2MSBTYWx0ZWRfXxj2twiQCAnbf eDfxRwJ/Yfra4czHxssRbqjxwOo8rs8LIqiqe4kxAYCIaMpJKYD0qfLTiI8o5Cb1FtnK7sUuDm5 jHoEyqHJV2kZv6RnDBj12oMLCXQAXbI= X-Proofpoint-ORIG-GUID: A8ZkH-16WYdNgX8asI71vGKHz_mLZR5i X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1176,Hydra:6.1.134,FMLib:17.12.100.49 definitions=2026-09-14_01,2026-09-13_01,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 suspectscore=0 adultscore=0 impostorscore=0 malwarescore=0 phishscore=0 clxscore=1015 bulkscore=0 lowpriorityscore=0 priorityscore=1501 spamscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2609040000 definitions=main-2609140061 Record the power state change reason into a NVMEM cell (a PMIC SDAM byte, RTC scratch register, or EEPROM) and read it back on the next boot, so the cause survives a power cycle. The recorder is implemented as an NVMEM layout driver: it owns the single cell described by its layout binding and adds it to the parent NVMEM device, rather than acting as a standalone consumer of someone else's cell. Co-developed-by: Oleksij Rempel Signed-off-by: Oleksij Rempel Signed-off-by: Faruque Ansari --- drivers/power/reset/pscrr/Kconfig | 14 ++ drivers/power/reset/pscrr/Makefile | 1 + drivers/power/reset/pscrr/pscrr-nvmem.c | 269 ++++++++++++++++++++++++++++= ++++ 3 files changed, 284 insertions(+) diff --git a/drivers/power/reset/pscrr/Kconfig b/drivers/power/reset/pscrr/= Kconfig index 72de82731b53..459b05ba32d3 100644 --- a/drivers/power/reset/pscrr/Kconfig +++ b/drivers/power/reset/pscrr/Kconfig @@ -31,3 +31,17 @@ menuconfig PSCRR unless hardware provides the reset cause. =20 If unsure, say N. + +if PSCRR + +config PSCRR_NVMEM + tristate "PSCRR NVMEM recorder provider" + depends on NVMEM_LAYOUTS + help + PSCRR recorder that stores the power state change reason in a + small NVMEM cell (such as an RTC scratch register) and reads it + back on the next boot, so the cause survives a power cycle. + + If unsure, say N. + +endif # PSCRR diff --git a/drivers/power/reset/pscrr/Makefile b/drivers/power/reset/pscrr= /Makefile index e5530a858971..95c80c80c7da 100644 --- a/drivers/power/reset/pscrr/Makefile +++ b/drivers/power/reset/pscrr/Makefile @@ -1,2 +1,3 @@ # SPDX-License-Identifier: GPL-2.0 obj-$(CONFIG_PSCRR) +=3D pscrr.o +obj-$(CONFIG_PSCRR_NVMEM) +=3D pscrr-nvmem.o diff --git a/drivers/power/reset/pscrr/pscrr-nvmem.c b/drivers/power/reset/= pscrr/pscrr-nvmem.c new file mode 100644 index 000000000000..64f67f0521e0 --- /dev/null +++ b/drivers/power/reset/pscrr/pscrr-nvmem.c @@ -0,0 +1,269 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * pscrr-nvmem.c - NVMEM layout driver for PSCRR + * + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + * Copyright (C) 2025 Pengutronix, Oleksij Rempel + */ + +#include +#include +#include +#include +#include +#include +#include + +struct pscrr_nvmem { + struct nvmem_device *nvmem; + u32 offset; /* byte offset of the cell, from reg[0] */ + u32 bit_offset; /* 0 when the cell has no "bits" property */ + u32 nbits; /* BITS_PER_BYTE when the cell has no "bits" property */ + enum psc_reason reason; +}; + +static inline u8 pscrr_nvmem_mask(struct pscrr_nvmem *priv) +{ + return (u8)GENMASK(priv->bit_offset + priv->nbits - 1, priv->bit_offset); +} + +static int pscrr_nvmem_raw_read(struct pscrr_nvmem *priv, u8 *raw) +{ + int ret; + + ret =3D nvmem_device_read(priv->nvmem, priv->offset, sizeof(*raw), raw); + + return ret < 0 ? ret : 0; +} + +static int pscrr_nvmem_raw_write(struct pscrr_nvmem *priv, u8 raw) +{ + int ret; + + ret =3D nvmem_device_write(priv->nvmem, priv->offset, sizeof(raw), &raw); + + return ret < 0 ? ret : 0; +} + +static int pscrr_nvmem_cell_read(struct pscrr_nvmem *priv, u8 *out) +{ + u8 raw, mask =3D pscrr_nvmem_mask(priv); + int ret; + + ret =3D pscrr_nvmem_raw_read(priv, &raw); + if (ret) + return ret; + + *out =3D (raw & mask) >> priv->bit_offset; + + return 0; +} + +static int pscrr_nvmem_cell_write(struct pscrr_nvmem *priv, u8 val) +{ + u8 raw, mask =3D pscrr_nvmem_mask(priv); + int ret; + + /* Sub-byte cell: preserve the neighbouring bits, read-modify-write. */ + if (priv->nbits < BITS_PER_BYTE) { + ret =3D pscrr_nvmem_raw_read(priv, &raw); + if (ret) + return ret; + } else { + raw =3D 0; + } + + raw =3D (raw & ~mask) | ((val << priv->bit_offset) & mask); + + return pscrr_nvmem_raw_write(priv, raw); +} + +static int pscrr_nvmem_read_reasons(struct pscrr_provider *p, + unsigned long *reasons) +{ + struct pscrr_nvmem *priv =3D p->priv; + + /* + * Report the reason latched at probe (or overwritten by a later + * record); the cell itself was cleared at probe, so it is not read + * live here. + */ + set_bit(READ_ONCE(priv->reason), reasons); + + return 0; +} + +static int pscrr_nvmem_write_reason(struct pscrr_provider *p, + enum psc_reason reason) +{ + struct pscrr_nvmem *priv =3D p->priv; + int ret; + + if (reason >=3D PSCR_REASON_COUNT) + return -EINVAL; + + ret =3D pscrr_nvmem_cell_write(priv, reason); + if (ret) + return ret; + + WRITE_ONCE(priv->reason, reason); + + return 0; +} + +static const struct pscrr_provider_ops pscrr_nvmem_ops =3D { + .read_reasons =3D pscrr_nvmem_read_reasons, + .write_reason =3D pscrr_nvmem_write_reason, +}; + +static struct device_node *pscrr_nvmem_get_cell(struct device *dev, + struct nvmem_device *nvmem, + u32 reg[2]) +{ + struct device_node *layout_np, *cell_np =3D NULL; + + layout_np =3D of_nvmem_layout_get_container(nvmem); + if (!layout_np) + return ERR_PTR(-ENOENT); + + for_each_child_of_node_scoped(layout_np, child) { + if (of_property_read_u32_array(child, "reg", reg, 2)) + continue; + + cell_np =3D of_node_get(child); + break; + } + of_node_put(layout_np); + + return cell_np ?: ERR_PTR(dev_err_probe(dev, -ENOENT, + "missing pscr nvmem cell\n")); +} + +static int pscrr_nvmem_add_cells(struct nvmem_layout *layout) +{ + struct device *dev =3D &layout->dev; + struct pscrr_nvmem *priv; + struct device_node *cell_np; + struct nvmem_cell_info info =3D { }; + u32 reg[2], bits[2]; + u8 val; + int ret; + + priv =3D devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + priv->nvmem =3D layout->nvmem; + + cell_np =3D pscrr_nvmem_get_cell(dev, priv->nvmem, reg); + if (IS_ERR(cell_np)) + return PTR_ERR(cell_np); + + /* The reason is a single byte; a bit cell still occupies one. */ + if (reg[1] !=3D sizeof(val)) { + of_node_put(cell_np); + return dev_err_probe(dev, -EINVAL, + "unsupported pscr nvmem cell size\n"); + } + priv->offset =3D reg[0]; + + if (!of_property_read_u32_array(cell_np, "bits", bits, ARRAY_SIZE(bits)))= { + priv->bit_offset =3D bits[0]; + priv->nbits =3D bits[1]; + } else { + priv->bit_offset =3D 0; + priv->nbits =3D BITS_PER_BYTE; + } + + if (priv->bit_offset + priv->nbits > BITS_PER_BYTE * reg[1]) { + of_node_put(cell_np); + return dev_err_probe(dev, -EINVAL, "bits exceed cell size\n"); + } + + /* PSCR_REASON_COUNT must fit in the allotted bits. */ + if (PSCR_REASON_COUNT > (1U << priv->nbits)) { + of_node_put(cell_np); + return dev_err_probe(dev, -EINVAL, + "too few bits for the reason range\n"); + } + + /* + * The cell survives resets, so at boot it still holds whatever the + * previous session recorded before it went down. Latch that as this + * boot's reason, then clear the cell back to PSCR_UNKNOWN: if this + * session is later cut short by an abrupt reset that never runs the + * recorder (watchdog power-cycle, sudden power loss), the next boot + * reads "unknown" instead of a stale reason left over from an earlier + * cycle. + */ + ret =3D pscrr_nvmem_cell_read(priv, &val); + if (ret) { + of_node_put(cell_np); + return dev_err_probe(dev, ret, + "failed to read the pscr nvmem cell\n"); + } + + priv->reason =3D val < PSCR_REASON_COUNT ? val : PSCR_UNKNOWN; + + ret =3D pscrr_nvmem_cell_write(priv, PSCR_UNKNOWN); + if (ret) { + of_node_put(cell_np); + return dev_err_probe(dev, ret, + "failed to clear the pscr nvmem cell\n"); + } + + info.name =3D kasprintf(GFP_KERNEL, "%pOFn", cell_np); + if (!info.name) { + of_node_put(cell_np); + return -ENOMEM; + } + info.offset =3D reg[0]; + info.bytes =3D reg[1]; + info.bit_offset =3D priv->bit_offset; + info.nbits =3D priv->nbits; + info.np =3D cell_np; + + ret =3D nvmem_add_one_cell(priv->nvmem, &info); + kfree(info.name); + if (ret) { + of_node_put(cell_np); + return ret; + } + + return PTR_ERR_OR_ZERO(devm_pscrr_provider_register(dev, "nvmem", + &pscrr_nvmem_ops, NULL, + priv)); +} + +static int pscrr_nvmem_probe(struct nvmem_layout *layout) +{ + layout->add_cells =3D pscrr_nvmem_add_cells; + + return nvmem_layout_register(layout); +} + +static void pscrr_nvmem_remove(struct nvmem_layout *layout) +{ + nvmem_layout_unregister(layout); +} + +static const struct of_device_id pscrr_nvmem_of_match[] =3D { + { .compatible =3D "pscrr-nvmem" }, + { } +}; +MODULE_DEVICE_TABLE(of, pscrr_nvmem_of_match); + +static struct nvmem_layout_driver pscrr_nvmem_layout =3D { + .driver =3D { + .name =3D "pscrr-nvmem", + .of_match_table =3D pscrr_nvmem_of_match, + }, + .probe =3D pscrr_nvmem_probe, + .remove =3D pscrr_nvmem_remove, +}; +module_nvmem_layout_driver(pscrr_nvmem_layout); + +MODULE_AUTHOR("Oleksij Rempel "); +MODULE_AUTHOR("Faruque Ansari "); +MODULE_DESCRIPTION("NVMEM recorder provider for PSCRR"); +MODULE_LICENSE("GPL"); --=20 2.34.1 From nobody Fri Sep 25 10:38:03 2026 Received: from mx0b-0031df01.pphosted.com (mx0b-0031df01.pphosted.com [205.220.180.131]) (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 4E7593750CC; Mon, 14 Sep 2026 04:39:22 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=205.220.180.131 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789360764; cv=none; b=uIO/Za/oy8TvGtOAMLBeBovO7daTiyGjjJUW1gNzFR7WfgIMg1kgN/w1ytxUJQ5BHwOul6qtRBPAcnlZ75oHteNrf8Dc/sU8ERp62B5+Cvu9/llxuP8vX7ScGZ1T/FFzFqsztb4lhLRuHgsIEvbvNxtxtm0Qot9ZiRxn/amEvTk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789360764; c=relaxed/simple; bh=CcfGecDBtOLIQE2iImJJOfkKpM/+XnQ0SnOWaiW8HII=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=PAKg393XK97lm8J0hwIXhuLjILeSC76z5XTdJ9XAx8BNRe+IDhi77zFt0B6O9ioNkkpPxz890bXCrG7OvWEoAcHck9b29fGbsNPBXs/FNmVRoa0jwFuNtgiy7LGbKYL8gGTqZbwzUGrQzgjsZSYWFP3zYuXvsp5vz/kjnCBNfLU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com; spf=pass smtp.mailfrom=oss.qualcomm.com; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b=mgodD7HT; arc=none smtp.client-ip=205.220.180.131 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b="mgodD7HT" Received: from pps.filterd (m0279868.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 68E2eTxW3348570; Mon, 14 Sep 2026 04:38:53 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=qualcomm.com; h= cc:content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s=qcppdkim1; bh= L5BjR9yuX0w9A8iBbpgDFPH2EoKDQ8C+CtRTeqM63T8=; b=mgodD7HTMaqiFSGe NlgWWrCq0Jts1bXkaSLAicwMIDP5XCLJegmyD3gJEk4U43U1fQ5pK/fMJtrEFNZ2 u5+5HSt8Fpi2IZBIScOdpQ7MMXeAhwzjQ8YbUyONZQmmftpgUFNDZ8GrCeSbQX80 wLJQfycn6n1vRDjb1kOTMzkxfZY3P6OTuxv3BuZ2B0kk/q936MfQQwI97P5hZAgS dtUW7Iez2fdfYq5y/QVdGDCBM2QGyTiSWj8wq2tmEAP1MveuOeJlE6QgOWJbW1Rj 2ck2+Kn0xQko33VtEazOOam/Ob/W5M8F2llzYyaSpifQa7shP6omZRs/L+p34Qsb F1wHew== Received: from apblrppmta02.qualcomm.com (blr-bdr-fw-01_GlobalNAT_AllZones-Outside.qualcomm.com [103.229.18.19]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 4gmy9dd0qy-1 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NOT); Mon, 14 Sep 2026 04:38:52 +0000 (GMT) Received: from pps.filterd (apblrppmta02.qualcomm.com [127.0.0.1]) by APBLRPPMTA02.qualcomm.com (8.18.1.11/8.18.1.11) with ESMTP id 68E4cnvn811237; Mon, 14 Sep 2026 04:38:50 GMT Received: from hu-ffaruque-hyd.qualcomm.com (hu-ffaruque-hyd.qualcomm.com [10.147.245.31]) by APBLRPPMTA02.qualcomm.com (PPS) with ESMTP id 68E4cm1m811221; Mon, 14 Sep 2026 04:38:50 +0000 (GMT) From: Faruque Ansari Date: Mon, 14 Sep 2026 10:08:47 +0530 Subject: [PATCH v3 3/3] arm64: dts: qcom: lemans: Add PSCRR NVMEM recorder node 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 Message-Id: <20260914-pscrr-provider-v3-3-c45cb16542e8@oss.qualcomm.com> References: <20260914-pscrr-provider-v3-0-c45cb16542e8@oss.qualcomm.com> In-Reply-To: <20260914-pscrr-provider-v3-0-c45cb16542e8@oss.qualcomm.com> To: Oleksij Rempel , Pengutronix Kernel Team , Sebastian Reichel , Rob Herring , Krzysztof Kozlowski , Wim Van Sebroeck , Guenter Roeck , Benson Leung , Tzung-Bi Shih , Srinivas Kandagatla , Daniel Lezcano Cc: linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org, linux-pm@vger.kernel.org, devicetree@vger.kernel.org, linux-watchdog@vger.kernel.org, kernel@pengutronix.de, Liam Girdwood , Mark Brown , "Rafael J. Wysocki" , Zhang Rui , Lukasz Luba , =?utf-8?q?S=C3=B8ren_Andersen?= , Guenter Roeck , Matti Vaittinen , Ahmad Fatoum , Andrew Morton , avaneesh.dwivedi@oss.qualcomm.com, Umang Chheda , Faruque Ansari X-Mailer: b4 0.14.3 X-Proofpoint-Reinject: loops=2 maxloops=12 X-QCInternal: smtphost X-QCInternal: smtphost X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwOTE0MDA2MSBTYWx0ZWRfXxamR2s54QrSk lrhUMVt6i5swlXs8Eugp2YV4BfAcwRcUiecNGE7l/2ranUNFUw4Ck+qfDJtdOzUQ0IQ1PAfebyY sHQY5hJBDOh/UZ889A83TlUsyNvwdqE7jnicN0RpxO52sMp7OpMLbjpAEycH40N0zDBrnueDLHL nBCbCVIjT515aASv4eG2NPOWEY0Wodjss0ihz2hd45ebUOcTAOkUHgEY6hDbQhmJ1wbvugPul9C gojYdRm/KvoZbEWTjLtqrU0BQiuiT7DBP6p3RkAlCwBJ54fTm4o6HFYO+72HqjmtJf7uX+s8uGA AF3bImR5QYPzApIIBMlemqYxs99tVbjOwvZAhk+UC4BmzHIEnaHKPN5XNnK6cvNnF3Lm8Lf9Z9Y hFoW3d0KxKg/SutJZKP7SZDfsrp3ca/iOk7orKYZZ1CJfYlEbdkd4xIB/M0FJ1Sd57Ks91S1F0h bb0uSP+lTHHhLMPTviw== X-Proofpoint-Spam-Info: AW1haW4tMjYwOTE0MDA2MSBTYWx0ZWRfXwDXB4lZJcA8y PdCYNEEWkn0QCI9cRlLSiOeQjSIFgYPqXaZYLu1pQSYgt8ODJ9qjWsVO5c17n8SXK3JPovswc9H 9E39I4byS58O16d3GtO/b6NwttTpMd8= X-Proofpoint-GUID: Q9XvnXEMV2OO3vUJYlZxGVu3m5fb4CKC X-Authority-Analysis: v=2.4 cv=OeUNnRTY c=1 sm=1 tr=0 ts=6aa77a5c cx=c_pps a=Ou0eQOY4+eZoSc0qltEV5Q==:117 a=Ou0eQOY4+eZoSc0qltEV5Q==:17 a=IkcTkHD0fZMA:10 a=VdqzKS8jKosA:10 a=VkNPw1HP01LnGYTKEx00:22 a=u7WPNUs3qKkmUXheDGA7:22 a=ZpdpYltYx_vBUK5n70dp:22 a=gg1OsQjKW_mRkEzLfZkA:9 a=QEXdDO2ut3YA:10 X-Proofpoint-ORIG-GUID: Q9XvnXEMV2OO3vUJYlZxGVu3m5fb4CKC X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1176,Hydra:6.1.134,FMLib:17.12.100.49 definitions=2026-09-14_01,2026-09-13_01,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 lowpriorityscore=0 malwarescore=0 phishscore=0 bulkscore=0 spamscore=0 priorityscore=1501 suspectscore=0 impostorscore=0 adultscore=0 clxscore=1015 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2609040000 definitions=main-2609140061 The PSCRR NVMEM recorder needs a persistent storage cell to save the power state change reason before shutdown or reset. Without a described NVMEM cell, the recorder has no platform storage where it can preserve that reason for the next boot. Add a pscrr-nvmem layout under the PMIC SDAM and describe a one-byte cell at offset 0x49. The recorder uses the lower four bits of this cell to persist the power state change reason across resets. --- arch/arm64/boot/dts/qcom/lemans-pmics.dtsi | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/lemans-pmics.dtsi b/arch/arm64/boot/d= ts/qcom/lemans-pmics.dtsi index 500f715931aa..180d180be3c6 100644 --- a/arch/arm64/boot/dts/qcom/lemans-pmics.dtsi +++ b/arch/arm64/boot/dts/qcom/lemans-pmics.dtsi @@ -186,6 +186,17 @@ reboot_reason: reboot-reason@48 { reg =3D <0x48 0x1>; bits =3D <1 7>; }; + + nvmem-layout { + compatible =3D "pscrr-nvmem"; + #address-cells =3D <1>; + #size-cells =3D <1>; + + reboot_reason_persist: reboot-reason-persist@49 { + reg =3D <0x49 0x1>; + bits =3D <0 4>; + }; + }; }; }; =20 --=20 2.34.1