From nobody Wed Sep 30 16:19:37 2026 Received: from mx0a-0031df01.pphosted.com (mx0a-0031df01.pphosted.com [205.220.168.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 6E38C3EC2FF for ; Thu, 6 Aug 2026 20:57:18 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=205.220.168.131 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786049842; cv=none; b=LMByDKO88/hgTkqBKwQKXoIp3+12j4aHe51qeyHIh1zIltitByTY177Fs5hUJQSWm6flAWMYNODnrhQp+Q03iykFp0Ok2YGGYgkdY0x/epC+9z+it4ssx7vKML+2n1cZRQrwXjgHQQZTrKeyI11eYKSe/fKHgk6unfzsM+58fqc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786049842; c=relaxed/simple; bh=MD5I+VArbC1H63/X/zCUsjSZIDHA/CM8wfB/bAIAthE=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=HqG5DJDRICgEdT9izitZnAyLSqXAHzPCwK9eIAmuj7JhR6K5v6sLn9VFyGTuS/Wxh1yHozCCfeQc1VNV2JulkEjQaCEfKhKZoShAZ97aMrqXp/DgupNk6Hm195fNjYLdpHGhFQzvDMb3qq8PCwCyt3DhCWSIGiUjsQ68oc2mKVA= 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=pXMWxeTh; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b=I6VCRhny; arc=none smtp.client-ip=205.220.168.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="pXMWxeTh"; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b="I6VCRhny" Received: from pps.filterd (m0279866.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 676IHUvA2401958 for ; Thu, 6 Aug 2026 20:57:14 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= 6bBCWNJUB84UpOgg5BY1iXXPsRYauvBdtILg7E28C0U=; b=pXMWxeThI8cjN0uv KVt41gCnjEEaZUSn+V9h/n7yxFekG++alz4My9Prgow+7u1dpqvcGG0Mll5KBU8N YVkaHmrRM1BL5v7ZhNSMyGGrCQ7yg6UxidXoHwrCHs0tAcrtNMi5qi9nOEvy/f0T qjR9i6qeUsXrTQNKa52HOSz6WBDTC/BD3fSiPjFgP63opEYRYgwM+0fQGjj6VQDS wrK6z48DLo3KOe/fk7m5UoZeD0o+FBJnwxBAnEASh0lO41e+Rai4g4XXBzEUjUAZ 9elfmQXehYDvdukvF0dxN+41rzSS04tQd2Qy0t/5G4Pj+9NiJCaLpFUEL7CiRHMl 6lZ4kw== Received: from mail-pg1-f197.google.com (mail-pg1-f197.google.com [209.85.215.197]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 4fvy6jgppf-1 (version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NOT) for ; Thu, 06 Aug 2026 20:57:13 +0000 (GMT) Received: by mail-pg1-f197.google.com with SMTP id 41be03b00d2f7-ca8aee88725so3729047a12.3 for ; Thu, 06 Aug 2026 13:57:13 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oss.qualcomm.com; s=google; t=1786049832; x=1786654632; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :content-type:mime-version:subject:date:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=6bBCWNJUB84UpOgg5BY1iXXPsRYauvBdtILg7E28C0U=; b=I6VCRhnyaIJTd/Kmx98Ku10nhPIBTeSOrIhnsrA7tNHuAcKQbNnfyOi7CQypBSFjOR XRmV7HD1eEFufkGATIy2ZKYMVI5b5iAFB1jQwY9UZ2IXCa/KPl0HIhoEXywzvf9sUHJG ncQajP6yuhxzHAP6d6SkSM2e2+vqAjEHwg1f5SmwqOaSkL3iQxyBUqJ/+A9IfGloYAsL uIGmEc4T0MTcShP8dAxxvpTi+OFcQkybiTUwiDlYRoUPYeAf2pZwGAyq8doE+eOsud5H 15wLWetNyc18J2mW8PoG5JvFJ0CJ9fMaOCPt7sbQM22dNLHCM7hxMRZl8EN5pWSZsB2a i7pQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1786049832; x=1786654632; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :content-type:mime-version:subject:date:from:x-gm-gg :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to :content-type; bh=6bBCWNJUB84UpOgg5BY1iXXPsRYauvBdtILg7E28C0U=; b=OfuHhQ/7tZuzvOWM8Aylv2NE3BwkjgoA8gkcM3g2JbWfO+E7RIb8Veovb5Cl5WRRzo ISdoSvmcRz3NIK215MmR5mm7MUOMYaaRsTT42rmV/v7urirv2W7A1zmrBitzr4HD7n0a HqfyBHJthj4x2tEQhKTWnEG0CfroNiQaWJXhycGFaAWE0IwOIXkuqBAZUSRU9TNwkpUb Y+1VksP37Gt5oFa0cPcmN8NWmgrcvi2+rGbleAjbrDRwW0p0bTe9g2VcCl4N41J1US4N GBUIEYkRDd40m5ChWJIbVXu3H2xzJDvd3xhoyGYVdTQ5Oqv4wi11Y5uMg4kDsefBIJCr oOtg== X-Gm-Message-State: AOJu0YybWORJTWf2DiAIglDUcFdE+6ocz/tVZ8x87wLZBjodq8GTg95m ms0nZ7/IU/7SsQmlEItgShxb1ysgZc3t5TJzZE3SlayWcpz/2apF13YEjpXRp2XYfAh+EOpegmv hRLwAL3jmWqAP4qqPk/nOyIiNhBaDVPfiC4jalGEzagIixiaqnhWFo4YMuE0yatnmqTg= X-Gm-Gg: AR+sD12VdatO4Ia3S/WbEp3NoZtPN2SSRE+amzaVskb6L+OuvxdtosTHURYfEehGt+b 9QXfsQk3sr7Rzyn+zYvEa6EaCYTer1eosTH/oY82tdhmx1or7EUsgcPx7gCbNwbHWzTdxzdCkwH Va9DEzuTOLrHKN3f89i6GlPLaEn9wFZ1iyNXAMtr8Avl31uo/FkEWIptzOILSuIHDnS9CCgk/v7 Vk4OENZfNIdjH7tjSL708lBnSvRzrChEcAbnad4j2LYNhJ45+hBeZj7F+/7nUMqoTJaMj8zMvtE 5v+iZvR7EgSY0bIIIlSUaVLNFvxmzC1fpM5aY3lmuklM7xGl7M+ZpNHQNhloHA+9kQDcO4OSnJN EmZE7j7RmUbbV8b67y/tUsfAKDm7aAw== X-Received: by 2002:a05:6a21:3a82:b0:3c3:704d:57c4 with SMTP id adf61e73a8af0-3cb85ded954mr22189213637.12.1786049832140; Thu, 06 Aug 2026 13:57:12 -0700 (PDT) X-Received: by 2002:a05:6a21:3a82:b0:3c3:704d:57c4 with SMTP id adf61e73a8af0-3cb85ded954mr22189169637.12.1786049831727; Thu, 06 Aug 2026 13:57:11 -0700 (PDT) Received: from hu-kamalw-hyd.qualcomm.com ([202.46.22.19]) by smtp.gmail.com with ESMTPSA id 5a478bee46e88-315bc667f1csm116641eec.12.2026.08.06.13.57.07 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 06 Aug 2026 13:57:11 -0700 (PDT) From: Kamal Wadhwa Date: Fri, 07 Aug 2026 02:26:30 +0530 Subject: [PATCH 1/2] dt-bindings: soc: qcom: qcom,pmic-glink: Document RTC client properties 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: <20260807-rtc-glink-cleanup-v1-1-7801e4d69c4f@oss.qualcomm.com> References: <20260807-rtc-glink-cleanup-v1-0-7801e4d69c4f@oss.qualcomm.com> In-Reply-To: <20260807-rtc-glink-cleanup-v1-0-7801e4d69c4f@oss.qualcomm.com> To: Alexandre Belloni , Bjorn Andersson , Konrad Dybcio , Rob Herring , Krzysztof Kozlowski , Conor Dooley Cc: linux-kernel@vger.kernel.org, linux-rtc@vger.kernel.org, linux-arm-msm@vger.kernel.org, devicetree@vger.kernel.org, Kamal Wadhwa , Raj Aryan X-Mailer: b4 0.15.2 X-Developer-Signature: v=1; a=ed25519-sha256; t=1786049822; l=1194; i=kamal.wadhwa@oss.qualcomm.com; s=20260406; h=from:subject:message-id; bh=MD5I+VArbC1H63/X/zCUsjSZIDHA/CM8wfB/bAIAthE=; b=toKd43o3cpn3nv/npS75mCQTi7r5OfqMdiI5G8BIj1R7PIQ5xV7RIwoVj1UMPgF3Qou2XZs9x i5Oan3QM94RCyASDrn89qABVFr5fQG+1RxI6Xurwxwi+OueBp5D37LE X-Developer-Key: i=kamal.wadhwa@oss.qualcomm.com; a=ed25519; pk=ylH1NxUZkBpYsmww89g6zVxpS0q8qthtzcORkYxn/Ag= X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwODA2MDE2MyBTYWx0ZWRfX1FWq7WSJF+gs EWATD31p7uQWgEQBwDxjWq8HoMBTxU6GUZfdbonMgVLjJouekcL5+j4GUNEpCQj0v3iThXOsv9b 2QO3zfvpEmNAJS0McXnEqmECebZ04HxlL1nq+U/1gwaUNmX9F69Ibu57hvhIg/wqIcsAdveRvT0 Vi8VUd8v1ZZCkfVVVF5A5sIccpNVOOLCB7G0gxPWDdVCxQYQ1iey9GT+8zQYdYSmvs1UJwJa5RY nnkuV4ZsbEKn9lDKe8b8dqaF8NgZ4qBVZACO4EFy0TlbS5Mi7ME7Frm9XtxEW0L279I4xf2EvSj 4RKJmLXYBOtjC7bnsqC6EPNEBnddW/vbM8IsP2++QXxsdPmD7n8NJ7+GTvVeBeokxY8QAeu5E0y 9pYtxOHKn5Fm7hnwAlWC2CNznQY01XGRIJ8Pyx6f3hZgVVRWrwL3wF4MJIUl/PPlYjWnKWyMYY8 mMZL66VSt2neNq58c7g== X-Proofpoint-Spam-Info: AW1haW4tMjYwODA2MDE2MyBTYWx0ZWRfX/jzr9vdIownc aEJawKhefaTrIiTB3qmaj4dZFMlW04YsnxOpjzW/gdYTtJtp3udQZW+ej/CQ3zqR8FDGutd4cZV 823ukkB22z98Kce0w7rwP8KtUu0V8+w= X-Proofpoint-ORIG-GUID: Th2pPI-xD4FfidozuKU9Zkg9IMxIAnxc X-Proofpoint-GUID: Th2pPI-xD4FfidozuKU9Zkg9IMxIAnxc X-Authority-Analysis: v=2.4 cv=e5Y2j6p/ c=1 sm=1 tr=0 ts=6a74f529 cx=c_pps a=rz3CxIlbcmazkYymdCej/Q==:117 a=fChuTYTh2wq5r3m49p7fHw==:17 a=IkcTkHD0fZMA:10 a=Sv0fKeRqtYgA:10 a=s4-Qcg_JpJYA:10 a=VkNPw1HP01LnGYTKEx00:22 a=u7WPNUs3qKkmUXheDGA7:22 a=YMgV9FUhrdKAYTUUvYB2:22 a=EUspDBNiAAAA:8 a=qoOW9mG7lyo1mN_lm6gA:9 a=QEXdDO2ut3YA:10 a=bFCP_H2QrGi7Okbo017w:22 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-08-06_02,2026-08-06_01,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 clxscore=1015 adultscore=0 spamscore=0 priorityscore=1501 impostorscore=0 bulkscore=0 lowpriorityscore=0 phishscore=0 suspectscore=0 malwarescore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2606150000 definitions=main-2608060163 The pmic_glink driver can now register an RTC auxiliary device on glymur, whose PMIC exposes an RTC over GLINK (see rtc-glink driver). Document the allow-set-time flag it consumes from the parent pmic-glink node. Assisted-by: Claude:claude-sonnet-5 Signed-off-by: Raj Aryan Signed-off-by: Kamal Wadhwa --- Documentation/devicetree/bindings/soc/qcom/qcom,pmic-glink.yaml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Documentation/devicetree/bindings/soc/qcom/qcom,pmic-glink.yam= l b/Documentation/devicetree/bindings/soc/qcom/qcom,pmic-glink.yaml index 16ad4f5698fc..38db1ff473c0 100644 --- a/Documentation/devicetree/bindings/soc/qcom/qcom,pmic-glink.yaml +++ b/Documentation/devicetree/bindings/soc/qcom/qcom,pmic-glink.yaml @@ -79,6 +79,11 @@ properties: - const: charge_limit_end - const: charge_limit_delta =20 + allow-set-time: + $ref: /schemas/types.yaml#/definitions/flag + description: + Indicates that the setting of RTC time is allowed by the host CPU. + patternProperties: '^connector@\d$': $ref: /schemas/connector/usb-connector.yaml# --=20 2.43.0 From nobody Wed Sep 30 16:19:37 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 55A654DBD8C for ; Thu, 6 Aug 2026 20:57:40 +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=1786049866; cv=none; b=RjJAHnaCJg0vnYoDDn0OVTZApkZ7FviQytwyo/MnH2+whM69FNlgASnTCk7Rk+i6gJ28FINJnBJalK95wvhC49CZkIWTbkQbULkMosDKhYhT7QNy3Qw0UGsR6fIiFuzWdRg/1UmPV72WMwAItArwA+NQyj2Ylhnf3LnrbTHE7mw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786049866; c=relaxed/simple; bh=x+MRZH90hm65VMG3ngwkdI5VIRnbua7WatjVs6iBRyA=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=dMz3p/4f9sTzdF12g3QUBbRxGiy/K27CFGbwog69mnaHf1/qxE+QfH4aTkP0DdPxzM4YOVOlWE7fauhGurmSI+FcLUDqzWdbVG9JO/jVtLy2PwmTiojhsiA4r/u2slg/mN7DeZtmlxx4Tzh1paHB2IJmY1JhnAHByv9bpqASryU= 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=JSR7VIbz; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b=OwUsBD+v; 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="JSR7VIbz"; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b="OwUsBD+v" 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 676IHwPC2704701 for ; Thu, 6 Aug 2026 20:57:38 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= Y+8TrZkpEFnhn5F2E3bQ04hIXxyfTiO/aiemUcJ2Jhc=; b=JSR7VIbzRzT15uBK S383/jyHn8yH40NEGN9pZ/arTZd2bXwCgQsYi29JzpT1h3Sa7BV5uGj/2DzLrJs5 LD8i+Vk4gHU3l0U2rXQkHaxIiFHBbzCXxjZ15bOg3m9xN5tNjFnUkylukbkH4mxe gmRGZNJzwWFqFtaH4S7zyQSgt8SG2O9iFdWgqT4Axy07g12y1sek3/xQ0XwQjKPA UhNwMkwRtbIvG0xrRCGQbGUW7SKB5CYEZiY3Xs+Y0uaFN+dh0bxh39LiESX6Tdtb pVX1Pg+yTdWtm6LCcPxjJLZEMkl+e1GxJM7yDVcNI7uHv3OJ8Y1XFjq4drpJCwS5 PFINWw== Received: from mail-pj1-f70.google.com (mail-pj1-f70.google.com [209.85.216.70]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 4fvy6h8rj1-1 (version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NOT) for ; Thu, 06 Aug 2026 20:57:36 +0000 (GMT) Received: by mail-pj1-f70.google.com with SMTP id 98e67ed59e1d1-38e475f83a2so4173424a91.1 for ; Thu, 06 Aug 2026 13:57:35 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oss.qualcomm.com; s=google; t=1786049837; x=1786654637; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :content-type:mime-version:subject:date:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=Y+8TrZkpEFnhn5F2E3bQ04hIXxyfTiO/aiemUcJ2Jhc=; b=OwUsBD+vV39AXNi0IBuKsOfkyZrS6CPKqZQRKiKLl/9i5T9x8ir07RPW/UOJvg8Raq JX1aIVIQDdqTKOTfgdjPWZxTP784fpabfp+G2Wpv46D0Nhch3Ligb5SNnG4N0fMjTFCx F95WvEhLNsmTmX/ZvYUKHxMuC/E8jCIknCEXnTsO6kfRNjNZ72+vvHCyUTmiy3+kL9VY Bld0PKG5AWcHIBljBi0sx4no4Icl2O83lNZLAyrSLHb1qWYRpTGjlezARw0hItx3gyHN Yd5ZXrIKNQyzgr+US8UFriw8eskSbEEAQpjpFUU8mgmElUIXc1pPxpPmSDQMLOzldi3d NxuQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1786049837; x=1786654637; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :content-type:mime-version:subject:date:from:x-gm-gg :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to :content-type; bh=Y+8TrZkpEFnhn5F2E3bQ04hIXxyfTiO/aiemUcJ2Jhc=; b=CVMR90TxRhjLwhwfK93bkrvIkYa6E1xknhlSElaoMYvHRKSc8zZSSM3aLWfUo4eCOu An43SYRczqkiHUH11nBvbW0Kd5hjUCColiBpFX1l3WBWbWzY5/ZzaaFAdgJFs2Hmb1qf iX9UzfmO+90TYURzjQWJyqnRPDhdZRo7+nl01TDTqi65jgmZ603lQGyXDFvl4aJOoXSo Z2VC+i+johdG6tljH8sKT3n0PYXZ9FauVW29GuLK1hi8X1F9PBlNh1dBlxazYfnQYR2s DZ0pVEtf/i9zLabo6dHn+tes+o53jG8hk444k/ms9FVgdiyt+3cGS4ZwPboG9UWKUA5B NAMQ== X-Gm-Message-State: AOJu0Yzaa4BE9wBlAS0NXM2p5UCzd/wV+LzSw9qwvCJNe/SEgqJnJxJi HOTMN2zfTdMx2U0TBgkFZ9jccqUkiwiQrDpEQx7uJ/qQGvAmTbU+H+oRJpsDXPh6m13DiyXSMNK l7V+lue+DTgoJBNPbuHj32mtBeKvqfLa6HU1NCnP1LBov2AbtKgaQxugo6Q3u3fVbliE= X-Gm-Gg: AR+sD11ubx0f+17oN5HljdqUHWm3IMuIpXU7W7VvzS26xvU5Ngz+IJy/837qVwASiGk p3ndIUcG5/6IQGpImduhbNzkQM+mu7G+Awzw/KfPuYfeWPPmlUh9ayl7jnOiMH1FprkXkeVmQkb COqaqBptbgtYR5s/teaArMqIGq1kz/3cXuYvHVk9X10Vmz+SJIEePIDD2yBxunki2H+h6SzNJYm 4UfrYxvPPnft0HM361PUrxnBBCjEkqxAWmIO2PjBvdRDJAt73IaMohceYKdgRnRVLRfmHt4oKvC qgXmWRp4KXu9srR12qjB4IMDzQvhMc3on+uRa9Lj25awmQUKQ6HZtVhoFyw8KxmkZ0jALPclI/X VH68WzNDEiMXXNwJ52RXBCDZHuUvXDQ== X-Received: by 2002:a05:6a21:a04:b0:3bf:9aa9:b2a4 with SMTP id adf61e73a8af0-3cb85ef91f7mr22475887637.20.1786049836735; Thu, 06 Aug 2026 13:57:16 -0700 (PDT) X-Received: by 2002:a05:6a21:a04:b0:3bf:9aa9:b2a4 with SMTP id adf61e73a8af0-3cb85ef91f7mr22475844637.20.1786049836235; Thu, 06 Aug 2026 13:57:16 -0700 (PDT) Received: from hu-kamalw-hyd.qualcomm.com ([202.46.22.19]) by smtp.gmail.com with ESMTPSA id 5a478bee46e88-315bc667f1csm116641eec.12.2026.08.06.13.57.12 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 06 Aug 2026 13:57:15 -0700 (PDT) From: Kamal Wadhwa Date: Fri, 07 Aug 2026 02:26:31 +0530 Subject: [PATCH 2/2] rtc: qcom: rtc-glink: Add PMIC GLINK RTC driver and extend pmic_glink 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: <20260807-rtc-glink-cleanup-v1-2-7801e4d69c4f@oss.qualcomm.com> References: <20260807-rtc-glink-cleanup-v1-0-7801e4d69c4f@oss.qualcomm.com> In-Reply-To: <20260807-rtc-glink-cleanup-v1-0-7801e4d69c4f@oss.qualcomm.com> To: Alexandre Belloni , Bjorn Andersson , Konrad Dybcio , Rob Herring , Krzysztof Kozlowski , Conor Dooley Cc: linux-kernel@vger.kernel.org, linux-rtc@vger.kernel.org, linux-arm-msm@vger.kernel.org, devicetree@vger.kernel.org, Kamal Wadhwa , Raj Aryan X-Mailer: b4 0.15.2 X-Developer-Signature: v=1; a=ed25519-sha256; t=1786049822; l=27044; i=kamal.wadhwa@oss.qualcomm.com; s=20260406; h=from:subject:message-id; bh=x+MRZH90hm65VMG3ngwkdI5VIRnbua7WatjVs6iBRyA=; b=b26gKlvoKWedxgtbnzFyDLsh8w6B6PLbRXDTIk++NukeEvlVhsfKVVlTglRiBQbYyeUuK6l2y 2fUC9bRLUeKAPkVGz26vAVfhFFTeSJmn5wR3wrxjKz/by5JYOcTr0ZE X-Developer-Key: i=kamal.wadhwa@oss.qualcomm.com; a=ed25519; pk=ylH1NxUZkBpYsmww89g6zVxpS0q8qthtzcORkYxn/Ag= X-Proofpoint-GUID: Ms9BAlh8vhYYawv2X_8gVFernMyBK4aS X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwODA2MDE2MyBTYWx0ZWRfX5Svv/qqjrD95 UziYWUuZlwfrQrdH0d4oJLjqpqZTNAYjyZMugpb86Y8WfJUE/LuwhZXdZRce444eO+mLKVFYEr2 9pP3SaRBdKWjT1Q3K3jaWTVQZPpP52Fn6RBw1T51JuK2JSpxNQZQtGHyZyFO1QaLKXmVDjzHplr DEQ8b1eA4zZIgzSytu04/EV/GFx3O9Yjq6VflzNbPs+HX+LmCY41Y4HIwYg93Eg1iYm1kSgk8w0 l8q2AhLJrj6dKfMq3qi/5qUjyA1wzxOjApgsZoGuZizIjN6qY8dVQ0li4EsD22ncylZAe8LDPFV 4gLlyZY6ArSyZl3oa6HRJkfMA1IsjYk6aYYvzJOdqEOrhL1WiK2+oMoVDYKFAE4UesYzl6+cY9e wpDMsALm/WH+UKF/jJk9+amJeqJAbUSyGQ1LS+Ug3y+D76GiuCynNoyXPezSfRPaQ8OHqGnaDeV EtP2N2UagZOv2OE7AyA== X-Proofpoint-Spam-Info: AW1haW4tMjYwODA2MDE2MyBTYWx0ZWRfX3Vv5MzySmTYP KniZIGMI8/n1sT2lHX2DtEybw9ndtwhEg09aF6afyMgnsUz3ecqEt6lQF7NjePFsuzCJblGBeXO FwSj0dykPBFRYHHimn+6CQkWSOJoqdo= X-Proofpoint-ORIG-GUID: Ms9BAlh8vhYYawv2X_8gVFernMyBK4aS X-Authority-Analysis: v=2.4 cv=MbpcfZ/f c=1 sm=1 tr=0 ts=6a74f541 cx=c_pps a=0uOsjrqzRL749jD1oC5vDA==:117 a=fChuTYTh2wq5r3m49p7fHw==:17 a=IkcTkHD0fZMA:10 a=Sv0fKeRqtYgA:10 a=s4-Qcg_JpJYA:10 a=VkNPw1HP01LnGYTKEx00:22 a=u7WPNUs3qKkmUXheDGA7:22 a=ZpdpYltYx_vBUK5n70dp:22 a=EUspDBNiAAAA:8 a=VwQbUJbxAAAA:8 a=aiWOJFc-Rkiic33xYCEA:9 a=QEXdDO2ut3YA:10 a=mQ_c8vxmzFEMiUWkPHU9:22 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-08-06_02,2026-08-06_01,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 phishscore=0 adultscore=0 priorityscore=1501 clxscore=1015 malwarescore=0 bulkscore=0 lowpriorityscore=0 suspectscore=0 spamscore=0 impostorscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2606150000 definitions=main-2608060163 Add a new RTC driver that communicates with the PMIC firmware over the GLINK transport layer. The driver supports reading time and alarm functionality via GET_PROPERTY and SET_PROPERTY opcodes. Time is read via GET_PROPERTY (opcode 0x62) using QCOM_RTC_GLINK_TIME property (0x00). Alarm set and enable are handled via SET_PROPERTY (opcode 0x63) using QCOM_RTC_GLINK_ALARM and QCOM_RTC_GLINK_ALARM_ENABLE properties respectively. GET_PROPERTY and SET_PROPERTY responses share the same firmware message layout, with the firmware echoing back the property value. Both opcodes are handled by a common callback path accordingly. Also extend pmic_glink to register the RTC as a PMIC GLINK client and add PMIC GLINK RTC client support for glymur. Assisted-by: Claude:claude-sonnet-5 Signed-off-by: Raj Aryan Signed-off-by: Kamal Wadhwa --- MAINTAINERS | 7 + drivers/rtc/Kconfig | 10 + drivers/rtc/Makefile | 1 + drivers/rtc/rtc-qcom-glink.c | 690 ++++++++++++++++++++++++++++++++= ++++ drivers/soc/qcom/pmic_glink.c | 22 +- include/linux/soc/qcom/pmic_glink.h | 1 + 6 files changed, 730 insertions(+), 1 deletion(-) diff --git a/MAINTAINERS b/MAINTAINERS index 5f178a5ff026..752cf667b8ad 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -22505,6 +22505,13 @@ S: Maintained F: Documentation/devicetree/bindings/power/supply/qcom,pmi8998-charger.yaml F: drivers/power/supply/qcom_smbx.c =20 +QUALCOMM PMIC GLINK RTC DRIVER +M: Kamal Wadhwa +L: linux-rtc@vger.kernel.org +L: linux-arm-msm@vger.kernel.org +S: Maintained +F: drivers/rtc/rtc-qcom-glink.c + QUALCOMM PPE DRIVER M: Luo Jie L: netdev@vger.kernel.org diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index 01def8231873..3ac39704b2e1 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig @@ -1836,6 +1836,16 @@ config RTC_DRV_PM8XXX To compile this driver as a module, choose M here: the module will be called rtc-pm8xxx. =20 +config RTC_DRV_QCOM_GLINK + tristate "Qualcomm PMIC GLINK RTC" + depends on QCOM_PMIC_GLINK + help + Say Y here to enable support for the RTC exposed by the PMIC + over the GLINK transport on Qualcomm platforms. + + This driver can also be built as a module. If so, the module + will be called rtc-qcom-glink. + config RTC_DRV_TEGRA tristate "NVIDIA Tegra Internal RTC driver" depends on ARCH_TEGRA || COMPILE_TEST diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile index 0347645b021f..8215a1fc29fb 100644 --- a/drivers/rtc/Makefile +++ b/drivers/rtc/Makefile @@ -73,6 +73,7 @@ obj-$(CONFIG_RTC_DRV_FM3130) +=3D rtc-fm3130.o obj-$(CONFIG_RTC_DRV_FSL_FTM_ALARM) +=3D rtc-fsl-ftm-alarm.o obj-$(CONFIG_RTC_DRV_FTRTC010) +=3D rtc-ftrtc010.o obj-$(CONFIG_RTC_DRV_GENERIC) +=3D rtc-generic.o +obj-$(CONFIG_RTC_DRV_QCOM_GLINK) +=3D rtc-qcom-glink.o obj-$(CONFIG_RTC_DRV_GOLDFISH) +=3D rtc-goldfish.o obj-$(CONFIG_RTC_DRV_HID_SENSOR_TIME) +=3D rtc-hid-sensor-time.o obj-$(CONFIG_RTC_DRV_HYM8563) +=3D rtc-hym8563.o diff --git a/drivers/rtc/rtc-qcom-glink.c b/drivers/rtc/rtc-qcom-glink.c new file mode 100644 index 000000000000..611f06a3cc5c --- /dev/null +++ b/drivers/rtc/rtc-qcom-glink.c @@ -0,0 +1,690 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define RTC_GLINK_SET_PROPERTY 0x63 +#define RTC_GLINK_GET_PROPERTY 0x65 +#define RTC_GLINK_GET_RTC_TICKS 0x67 +#define RTC_GLINK_GET_REAL_TIME 0x68 +#define RTC_GLINK_SET_REAL_TIME 0x69 +#define RTC_GLINK_ALARM_EXPIRED 0x6A + +enum qcom_rtc_glink_properties { + QCOM_RTC_GLINK_TIME =3D 0, + QCOM_RTC_GLINK_ALARM_TIME, + QCOM_RTC_GLINK_ALARM_ENABLE, +}; + +struct qcom_rtc_glink_msg { + struct pmic_glink_hdr hdr; + __le32 property; + __le32 value; +}; + +struct qcom_rtc_glink_generic_req { + struct pmic_glink_hdr hdr; +}; + +struct qcom_rtc_glink_status_resp { + struct pmic_glink_hdr hdr; + __le32 return_status; +}; + +struct qcom_rtc_glink_ticks_resp { + struct pmic_glink_hdr hdr; + __le32 return_status; + __le32 rtc_ticks; +}; + +struct qcom_rtc_glink_real_time_resp { + struct pmic_glink_hdr hdr; + __le32 return_status; + __le32 real_time_data[4]; +}; + +struct qcom_rtc_glink_set_real_time_req { + struct pmic_glink_hdr hdr; + __le32 real_time_data[4]; +}; + +struct qcom_rtc_glink { + struct device *dev; + struct pmic_glink_client *client; + struct rtc_device *rtc; + + /* Serializes requests: only one may be in flight at a time */ + struct mutex lock; + struct completion ack; + struct work_struct alarm_work; + + /* Protects service_up and request_pending across callback contexts */ + spinlock_t state_lock; + bool service_up; + bool request_pending; + + int error; + u32 resp_value; + u32 offset; + struct rtc_time resp_tm; + bool resp_valid; + bool allow_set_time; +}; + +static int qcom_rtc_glink_request(struct qcom_rtc_glink *rtc_glink, + void *data, size_t len) +{ + unsigned long flags; + unsigned long left; + int ret; + + /* + * Reinit the completion before request_pending becomes visible to + * qcom_rtc_glink_pdr_tify(), so a concurrent SSR down-transition + * can't complete() a stale completion that gets wiped out by + * reinit_completion() right after. + */ + reinit_completion(&rtc_glink->ack); + rtc_glink->error =3D 0; + rtc_glink->resp_valid =3D false; + + spin_lock_irqsave(&rtc_glink->state_lock, flags); + if (!rtc_glink->service_up) { + spin_unlock_irqrestore(&rtc_glink->state_lock, flags); + return -ECONNRESET; + } + rtc_glink->request_pending =3D true; + spin_unlock_irqrestore(&rtc_glink->state_lock, flags); + + ret =3D pmic_glink_send(rtc_glink->client, data, len); + if (ret < 0) { + spin_lock_irqsave(&rtc_glink->state_lock, flags); + rtc_glink->request_pending =3D false; + spin_unlock_irqrestore(&rtc_glink->state_lock, flags); + return ret; + } + + left =3D wait_for_completion_timeout(&rtc_glink->ack, HZ); + spin_lock_irqsave(&rtc_glink->state_lock, flags); + rtc_glink->request_pending =3D false; + spin_unlock_irqrestore(&rtc_glink->state_lock, flags); + if (!left) + return -ETIMEDOUT; + + return rtc_glink->error; +} + +static int qcom_rtc_glink_set_property(struct qcom_rtc_glink *rtc_glink, + u32 property, u32 value) +{ + struct qcom_rtc_glink_msg msg =3D { + .hdr.owner =3D cpu_to_le32(PMIC_GLINK_OWNER_RTC), + .hdr.type =3D cpu_to_le32(PMIC_GLINK_REQ_RESP), + .hdr.opcode =3D cpu_to_le32(RTC_GLINK_SET_PROPERTY), + .property =3D cpu_to_le32(property), + .value =3D cpu_to_le32(value), + }; + int ret; + + dev_dbg(rtc_glink->dev, + "TX opcode=3D0x%x property=3D%u value=3D%u\n", + RTC_GLINK_SET_PROPERTY, property, value); + mutex_lock(&rtc_glink->lock); + ret =3D qcom_rtc_glink_request(rtc_glink, &msg, sizeof(msg)); + mutex_unlock(&rtc_glink->lock); + return ret; +} + +static int qcom_rtc_glink_get_property(struct qcom_rtc_glink *rtc_glink, + u32 property, u32 *value) +{ + struct qcom_rtc_glink_msg msg =3D { + .hdr.owner =3D cpu_to_le32(PMIC_GLINK_OWNER_RTC), + .hdr.type =3D cpu_to_le32(PMIC_GLINK_REQ_RESP), + .hdr.opcode =3D cpu_to_le32(RTC_GLINK_GET_PROPERTY), + .property =3D cpu_to_le32(property), + }; + int ret; + + dev_dbg(rtc_glink->dev, + "TX opcode=3D0x%x property=3D%u\n", + RTC_GLINK_GET_PROPERTY, property); + mutex_lock(&rtc_glink->lock); + ret =3D qcom_rtc_glink_request(rtc_glink, &msg, sizeof(msg)); + if (!ret) { + if (!rtc_glink->resp_valid) + ret =3D -EIO; + else + *value =3D rtc_glink->resp_value; + } + mutex_unlock(&rtc_glink->lock); + return ret; +} + +static int qcom_rtc_glink_get_ticks(struct qcom_rtc_glink *rtc_glink, + u32 *ticks) +{ + struct qcom_rtc_glink_generic_req msg =3D { + .hdr.owner =3D cpu_to_le32(PMIC_GLINK_OWNER_RTC), + .hdr.type =3D cpu_to_le32(PMIC_GLINK_REQ_RESP), + .hdr.opcode =3D cpu_to_le32(RTC_GLINK_GET_RTC_TICKS), + }; + int ret; + + dev_dbg(rtc_glink->dev, "TX opcode=3D0x%x\n", RTC_GLINK_GET_RTC_TICKS); + mutex_lock(&rtc_glink->lock); + ret =3D qcom_rtc_glink_request(rtc_glink, &msg, sizeof(msg)); + if (!ret) { + if (!rtc_glink->resp_valid) + ret =3D -EIO; + else + *ticks =3D rtc_glink->resp_value; + } + mutex_unlock(&rtc_glink->lock); + return ret; +} + +static int qcom_rtc_glink_get_real_time(struct qcom_rtc_glink *rtc_glink, + struct rtc_time *tm) +{ + struct qcom_rtc_glink_generic_req msg =3D { + .hdr.owner =3D cpu_to_le32(PMIC_GLINK_OWNER_RTC), + .hdr.type =3D cpu_to_le32(PMIC_GLINK_REQ_RESP), + .hdr.opcode =3D cpu_to_le32(RTC_GLINK_GET_REAL_TIME), + }; + int ret; + + dev_dbg(rtc_glink->dev, "TX opcode=3D0x%x\n", RTC_GLINK_GET_REAL_TIME); + mutex_lock(&rtc_glink->lock); + ret =3D qcom_rtc_glink_request(rtc_glink, &msg, sizeof(msg)); + if (!ret) { + if (!rtc_glink->resp_valid) + ret =3D -EIO; + else + *tm =3D rtc_glink->resp_tm; + } + mutex_unlock(&rtc_glink->lock); + return ret; +} + +static int qcom_rtc_glink_set_real_time(struct qcom_rtc_glink *rtc_glink, + struct rtc_time *tm) +{ + struct qcom_rtc_glink_set_real_time_req msg =3D {}; + u32 w0, w1; + int ret; + + w0 =3D ((tm->tm_year + 1900) & 0xffff) | + (((tm->tm_mon + 1) & 0xff) << 16) | + ((tm->tm_mday & 0xff) << 24); + w1 =3D (tm->tm_hour & 0xff) | + ((tm->tm_min & 0xff) << 8) | + ((tm->tm_sec & 0xff) << 16) | + (1U << 24); + msg.hdr.owner =3D cpu_to_le32(PMIC_GLINK_OWNER_RTC); + msg.hdr.type =3D cpu_to_le32(PMIC_GLINK_REQ_RESP); + msg.hdr.opcode =3D cpu_to_le32(RTC_GLINK_SET_REAL_TIME); + msg.real_time_data[0] =3D cpu_to_le32(w0); + msg.real_time_data[1] =3D cpu_to_le32(w1); + msg.real_time_data[2] =3D 0; + msg.real_time_data[3] =3D 0; + dev_dbg(rtc_glink->dev, + "TX opcode=3D0x%x data=3D%08x %08x\n", + RTC_GLINK_SET_REAL_TIME, w0, w1); + mutex_lock(&rtc_glink->lock); + ret =3D qcom_rtc_glink_request(rtc_glink, &msg, sizeof(msg)); + mutex_unlock(&rtc_glink->lock); + return ret; +} + +static int qcom_rtc_glink_get_time(struct qcom_rtc_glink *rtc_glink, + struct rtc_time *time) +{ + u32 ticks; + int ret; + + ret =3D qcom_rtc_glink_get_real_time(rtc_glink, time); + if (!ret) + return 0; + dev_warn(rtc_glink->dev, "0x68 failed (%d), falling back\n", ret); + + ret =3D qcom_rtc_glink_get_ticks(rtc_glink, &ticks); + if (!ret) { + rtc_time64_to_tm((time64_t)ticks + rtc_glink->offset, time); + return 0; + } + + ret =3D qcom_rtc_glink_get_property(rtc_glink, QCOM_RTC_GLINK_TIME, + &ticks); + if (!ret && ticks !=3D U32_MAX) { + rtc_time64_to_tm((time64_t)ticks + rtc_glink->offset, time); + return 0; + } + + dev_err(rtc_glink->dev, "all time sources failed\n"); + return -EIO; +} + +static int qcom_rtc_glink_set_time(struct qcom_rtc_glink *rtc_glink, + struct rtc_time *time) +{ + time64_t t =3D rtc_tm_to_time64(time); + u32 ticks; + int ret; + + if (!rtc_glink->allow_set_time) + return -EOPNOTSUPP; + + ret =3D qcom_rtc_glink_set_real_time(rtc_glink, time); + if (ret) + dev_warn(rtc_glink->dev, "0x69 failed (%d)\n", ret); + + ret =3D qcom_rtc_glink_set_property(rtc_glink, QCOM_RTC_GLINK_TIME, (u32)= t); + if (ret) + return ret; + + ret =3D qcom_rtc_glink_get_ticks(rtc_glink, &ticks); + if (!ret && ticks !=3D U32_MAX) { + rtc_glink->offset =3D (u32)t - ticks; + } else { + dev_warn(rtc_glink->dev, "no tick source for offset\n"); + return -EIO; + } + + return 0; +} + +static int qcom_rtc_glink_set_alarm_en(struct qcom_rtc_glink *rtc_glink, + int enabled) +{ + return qcom_rtc_glink_set_property(rtc_glink, + QCOM_RTC_GLINK_ALARM_ENABLE, + enabled); +} + +static int qcom_rtc_glink_set_alarm(struct qcom_rtc_glink *rtc_glink, + struct rtc_wkalrm *alarm) +{ + time64_t alarm_t =3D rtc_tm_to_time64(&alarm->time); + struct rtc_time now_tm; + time64_t now_real, secs_until_alarm; + u32 fw_current, fw_alarm; + int ret; + + ret =3D qcom_rtc_glink_get_time(rtc_glink, &now_tm); + if (ret) + return ret; + now_real =3D rtc_tm_to_time64(&now_tm); + secs_until_alarm =3D alarm_t - now_real; + dev_dbg(rtc_glink->dev, + "set_alarm: now_real=3D%lld alarm_t=3D%lld delta=3D%lld\n", + now_real, alarm_t, secs_until_alarm); + if (secs_until_alarm < 0) + return -EINVAL; + if (secs_until_alarm > U32_MAX) + return -ERANGE; + + ret =3D qcom_rtc_glink_get_property(rtc_glink, QCOM_RTC_GLINK_TIME, + &fw_current); + if (ret) + return ret; + if (fw_current =3D=3D U32_MAX) + fw_current =3D 0; + fw_alarm =3D fw_current + (u32)secs_until_alarm; + dev_dbg(rtc_glink->dev, + "set_alarm: fw_current=3D%u fw_alarm=3D%u\n", + fw_current, fw_alarm); + + ret =3D qcom_rtc_glink_set_alarm_en(rtc_glink, 0); + if (ret) + return ret; + + ret =3D qcom_rtc_glink_set_property(rtc_glink, + QCOM_RTC_GLINK_ALARM_TIME, fw_alarm); + if (ret) + return ret; + + return qcom_rtc_glink_set_alarm_en(rtc_glink, alarm->enabled); +} + +static int qcom_rtc_glink_get_alarm(struct qcom_rtc_glink *rtc_glink, + struct rtc_wkalrm *alarm) +{ + u32 fw_alarm_time, fw_current, alarm_en; + struct rtc_time now_tm; + time64_t now_real, secs_until_alarm, alarm_real; + int ret; + + ret =3D qcom_rtc_glink_get_property(rtc_glink, + QCOM_RTC_GLINK_ALARM_TIME, + &fw_alarm_time); + if (ret) + return ret; + + ret =3D qcom_rtc_glink_get_property(rtc_glink, QCOM_RTC_GLINK_TIME, + &fw_current); + if (ret) + return ret; + + ret =3D qcom_rtc_glink_get_property(rtc_glink, + QCOM_RTC_GLINK_ALARM_ENABLE, + &alarm_en); + if (ret) + return ret; + if (fw_current =3D=3D U32_MAX) + fw_current =3D 0; + + ret =3D qcom_rtc_glink_get_time(rtc_glink, &now_tm); + if (ret) + return ret; + now_real =3D rtc_tm_to_time64(&now_tm); + secs_until_alarm =3D (time64_t)fw_alarm_time - (time64_t)fw_current; + alarm_real =3D now_real + secs_until_alarm; + dev_dbg(rtc_glink->dev, + "get_alarm: now_real=3D%lld fw_current=3D%u fw_alarm=3D%u delta=3D%lld\n= ", + now_real, fw_current, fw_alarm_time, secs_until_alarm); + rtc_time64_to_tm(alarm_real, &alarm->time); + alarm->enabled =3D !!alarm_en; + return 0; +} + +static void qcom_rtc_glink_alarm_work(struct work_struct *work) +{ + struct qcom_rtc_glink *rtc_glink =3D + container_of(work, struct qcom_rtc_glink, alarm_work); + int ret; + + ret =3D qcom_rtc_glink_set_alarm_en(rtc_glink, 0); + if (ret) + dev_err(rtc_glink->dev, + "failed to disable alarm after expiry (%d)\n", ret); + rtc_update_irq(rtc_glink->rtc, 1, RTC_IRQF | RTC_AF); +} + +static void qcom_rtc_glink_callback(const void *data, size_t len, void *pr= iv) +{ + struct qcom_rtc_glink *rtc_glink =3D priv; + const struct pmic_glink_hdr *hdr =3D data; + unsigned long flags; + bool pending; + + if (len < sizeof(*hdr)) + return; + + dev_dbg(rtc_glink->dev, + "RX opcode=3D0x%x type=3D0x%x owner=3D0x%x len=3D%zu\n", + le32_to_cpu(hdr->opcode), le32_to_cpu(hdr->type), + le32_to_cpu(hdr->owner), len); + + if (le32_to_cpu(hdr->opcode) =3D=3D RTC_GLINK_ALARM_EXPIRED) { + dev_info(rtc_glink->dev, "alarm expired\n"); + schedule_work(&rtc_glink->alarm_work); + return; + } + + /* + * Hold state_lock across the pending check and the response fields + * below: qcom_rtc_glink_pdr_notify() writes the same error/resp_* + * fields under this lock when it force-completes a request on an + * SSR down-transition, and the two must not race. Dropping the + * response here if !pending also covers requests that already + * timed out or were aborted; qcom_rtc_glink_request() will call + * reinit_completion() again before this response could be mistaken + * for a later request's. + */ + spin_lock_irqsave(&rtc_glink->state_lock, flags); + pending =3D rtc_glink->request_pending; + + if (!pending) { + spin_unlock_irqrestore(&rtc_glink->state_lock, flags); + dev_dbg(rtc_glink->dev, + "dropping stale response opcode=3D0x%x\n", + le32_to_cpu(hdr->opcode)); + return; + } + + switch (le32_to_cpu(hdr->opcode)) { + case RTC_GLINK_GET_PROPERTY: + fallthrough; + case RTC_GLINK_SET_PROPERTY: { + const struct qcom_rtc_glink_msg *msg =3D data; + + if (len < sizeof(struct pmic_glink_hdr) + sizeof(__le32)) { + rtc_glink->error =3D -EINVAL; + break; + } + rtc_glink->resp_value =3D le32_to_cpu(msg->property); + rtc_glink->resp_valid =3D true; + rtc_glink->error =3D 0; + dev_dbg(rtc_glink->dev, "ACK opcode=3D0x%x resp_value=3D%u\n", + le32_to_cpu(hdr->opcode), rtc_glink->resp_value); + break; + } + + case RTC_GLINK_GET_RTC_TICKS: { + const struct qcom_rtc_glink_ticks_resp *resp =3D data; + + if (len < sizeof(*resp)) { + rtc_glink->error =3D -EINVAL; + break; + } + if (le32_to_cpu(resp->return_status)) { + rtc_glink->error =3D -EIO; + break; + } + rtc_glink->resp_value =3D le32_to_cpu(resp->rtc_ticks); + rtc_glink->resp_valid =3D true; + rtc_glink->error =3D 0; + dev_dbg(rtc_glink->dev, "ACK opcode=3D0x%x ticks=3D%u\n", + RTC_GLINK_GET_RTC_TICKS, rtc_glink->resp_value); + break; + } + + case RTC_GLINK_GET_REAL_TIME: { + const struct qcom_rtc_glink_real_time_resp *resp =3D data; + u32 w0, w1; + + if (len < sizeof(*resp)) { + rtc_glink->error =3D -EINVAL; + break; + } + if (le32_to_cpu(resp->return_status)) { + rtc_glink->error =3D -EIO; + break; + } + w0 =3D le32_to_cpu(resp->real_time_data[0]); + w1 =3D le32_to_cpu(resp->real_time_data[1]); + rtc_glink->resp_tm.tm_year =3D (w0 & 0xffff) - 1900; + rtc_glink->resp_tm.tm_mon =3D ((w0 >> 16) & 0xff) - 1; + rtc_glink->resp_tm.tm_mday =3D (w0 >> 24) & 0xff; + rtc_glink->resp_tm.tm_hour =3D w1 & 0xff; + rtc_glink->resp_tm.tm_min =3D (w1 >> 8) & 0xff; + rtc_glink->resp_tm.tm_sec =3D (w1 >> 16) & 0xff; + rtc_glink->resp_valid =3D true; + rtc_glink->error =3D 0; + dev_dbg(rtc_glink->dev, + "ACK opcode=3D0x%x %04d-%02d-%02d %02d:%02d:%02d\n", + RTC_GLINK_GET_REAL_TIME, + rtc_glink->resp_tm.tm_year + 1900, + rtc_glink->resp_tm.tm_mon + 1, + rtc_glink->resp_tm.tm_mday, + rtc_glink->resp_tm.tm_hour, + rtc_glink->resp_tm.tm_min, + rtc_glink->resp_tm.tm_sec); + break; + } + + case RTC_GLINK_SET_REAL_TIME: { + const struct qcom_rtc_glink_status_resp *resp =3D data; + + if (len < sizeof(*resp)) { + rtc_glink->error =3D -EINVAL; + break; + } + rtc_glink->error =3D le32_to_cpu(resp->return_status) ? -EIO : 0; + dev_dbg(rtc_glink->dev, "ACK opcode=3D0x%x status=3D%u\n", + RTC_GLINK_SET_REAL_TIME, + le32_to_cpu(resp->return_status)); + break; + } + + default: + spin_unlock_irqrestore(&rtc_glink->state_lock, flags); + dev_warn(rtc_glink->dev, + "unhandled RX opcode=3D0x%x len=3D%zu\n", + le32_to_cpu(hdr->opcode), len); + return; + } + + spin_unlock_irqrestore(&rtc_glink->state_lock, flags); + complete(&rtc_glink->ack); +} + +static void qcom_rtc_glink_pdr_notify(void *priv, int state) +{ + struct qcom_rtc_glink *rtc_glink =3D priv; + unsigned long flags; + bool up =3D (state =3D=3D SERVREG_SERVICE_STATE_UP); + + spin_lock_irqsave(&rtc_glink->state_lock, flags); + rtc_glink->service_up =3D up; + if (!up && rtc_glink->request_pending) { + rtc_glink->error =3D -ECONNRESET; + rtc_glink->resp_valid =3D false; + complete(&rtc_glink->ack); + } + spin_unlock_irqrestore(&rtc_glink->state_lock, flags); +} + +static int qcom_rtc_glink_read_time(struct device *dev, struct rtc_time *t= m) +{ + return qcom_rtc_glink_get_time(dev_get_drvdata(dev), tm); +} + +static int qcom_rtc_glink_set_time_dev(struct device *dev, struct rtc_time= *tm) +{ + return qcom_rtc_glink_set_time(dev_get_drvdata(dev), tm); +} + +static int qcom_rtc_glink_read_alarm(struct device *dev, + struct rtc_wkalrm *alrm) +{ + return qcom_rtc_glink_get_alarm(dev_get_drvdata(dev), alrm); +} + +static int qcom_rtc_glink_set_alarm_dev(struct device *dev, + struct rtc_wkalrm *alrm) +{ + return qcom_rtc_glink_set_alarm(dev_get_drvdata(dev), alrm); +} + +static int qcom_rtc_glink_alarm_irq_enable(struct device *dev, + unsigned int enabled) +{ + return qcom_rtc_glink_set_alarm_en(dev_get_drvdata(dev), enabled); +} + +static const struct rtc_class_ops qcom_rtc_glink_rtc_ops =3D { + .read_time =3D qcom_rtc_glink_read_time, + .set_time =3D qcom_rtc_glink_set_time_dev, + .read_alarm =3D qcom_rtc_glink_read_alarm, + .set_alarm =3D qcom_rtc_glink_set_alarm_dev, + .alarm_irq_enable =3D qcom_rtc_glink_alarm_irq_enable, +}; + +static const struct of_device_id qcom_rtc_glink_of_variants[] =3D { + { .compatible =3D "qcom,glymur-pmic-glink" }, + {} +}; + +static int qcom_rtc_glink_probe(struct auxiliary_device *adev, + const struct auxiliary_device_id *id) +{ + struct device *dev =3D &adev->dev; + struct qcom_rtc_glink *rtc_glink; + + if (!of_match_device(qcom_rtc_glink_of_variants, dev->parent)) + return -ENXIO; + + rtc_glink =3D devm_kzalloc(dev, sizeof(*rtc_glink), GFP_KERNEL); + if (!rtc_glink) + return -ENOMEM; + + rtc_glink->dev =3D dev; + rtc_glink->allow_set_time =3D device_property_read_bool(dev->parent, + "allow-set-time"); + + mutex_init(&rtc_glink->lock); + spin_lock_init(&rtc_glink->state_lock); + init_completion(&rtc_glink->ack); + INIT_WORK(&rtc_glink->alarm_work, qcom_rtc_glink_alarm_work); + dev_set_drvdata(dev, rtc_glink); + + rtc_glink->client =3D devm_pmic_glink_client_alloc(dev, + PMIC_GLINK_OWNER_RTC, + qcom_rtc_glink_callback, + qcom_rtc_glink_pdr_notify, + rtc_glink); + if (IS_ERR(rtc_glink->client)) + return dev_err_probe(dev, PTR_ERR(rtc_glink->client), + "failed to allocate glink client\n"); + + pmic_glink_client_register(rtc_glink->client); + + device_init_wakeup(dev, true); + + rtc_glink->rtc =3D devm_rtc_allocate_device(dev); + if (IS_ERR(rtc_glink->rtc)) + return dev_err_probe(dev, PTR_ERR(rtc_glink->rtc), + "failed to allocate RTC device\n"); + + rtc_glink->rtc->ops =3D &qcom_rtc_glink_rtc_ops; + rtc_glink->rtc->range_min =3D 0; + rtc_glink->rtc->range_max =3D U32_MAX; + + return devm_rtc_register_device(rtc_glink->rtc); +} + +static void qcom_rtc_glink_remove(struct auxiliary_device *adev) +{ + struct qcom_rtc_glink *rtc_glink =3D dev_get_drvdata(&adev->dev); + /* + * Nothing left to arm alarm_work after this returns: the glink + * client (and its callback/pdr_notify) is torn down by devm after + * .remove() returns, and rtc_update_irq() below still targets a + * live devm-managed rtc device. + */ + cancel_work_sync(&rtc_glink->alarm_work); +} + +static const struct auxiliary_device_id qcom_rtc_glink_id_table[] =3D { + { .name =3D "pmic_glink.rtc-glink" }, + {} +}; + +MODULE_DEVICE_TABLE(auxiliary, qcom_rtc_glink_id_table); + +static struct auxiliary_driver qcom_rtc_glink_driver =3D { + .name =3D "qcom_pmic_rtc_glink", + .id_table =3D qcom_rtc_glink_id_table, + .probe =3D qcom_rtc_glink_probe, + .remove =3D qcom_rtc_glink_remove, +}; + +module_auxiliary_driver(qcom_rtc_glink_driver); +MODULE_DESCRIPTION("Qualcomm PMIC GLINK RTC driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/soc/qcom/pmic_glink.c b/drivers/soc/qcom/pmic_glink.c index 3042261578aa..7ee70a31ba15 100644 --- a/drivers/soc/qcom/pmic_glink.c +++ b/drivers/soc/qcom/pmic_glink.c @@ -21,6 +21,7 @@ enum { PMIC_GLINK_CLIENT_BATT =3D 0, PMIC_GLINK_CLIENT_ALTMODE, PMIC_GLINK_CLIENT_UCSI, + PMIC_GLINK_CLIENT_RTC, }; =20 struct pmic_glink_data { @@ -40,6 +41,7 @@ struct pmic_glink { struct auxiliary_device altmode_aux; struct auxiliary_device ps_aux; struct auxiliary_device ucsi_aux; + struct auxiliary_device rtc_aux; =20 /* serializing client_state and pdr_state updates */ struct mutex state_lock; @@ -341,6 +343,12 @@ static int pmic_glink_probe(struct platform_device *pd= ev) goto out_release_altmode_aux; } =20 + if (pg->data->client_mask & BIT(PMIC_GLINK_CLIENT_RTC)) { + ret =3D pmic_glink_add_aux_device(pg, &pg->rtc_aux, "rtc-glink"); + if (ret) + goto out_release_ps_aux; + } + if (pg->data->charger_pdr_service_name && pg->data->charger_pdr_service_p= ath) { service =3D pdr_add_lookup(pg->pdr, pg->data->charger_pdr_service_name, pg->data->charger_pdr_service_path); @@ -358,6 +366,9 @@ static int pmic_glink_probe(struct platform_device *pde= v) return 0; =20 out_release_aux_devices: + if (pg->data->client_mask & BIT(PMIC_GLINK_CLIENT_RTC)) + pmic_glink_del_aux_device(pg, &pg->rtc_aux); +out_release_ps_aux: if (pg->data->client_mask & BIT(PMIC_GLINK_CLIENT_BATT)) pmic_glink_del_aux_device(pg, &pg->ps_aux); out_release_altmode_aux: @@ -384,11 +395,20 @@ static void pmic_glink_remove(struct platform_device = *pdev) pmic_glink_del_aux_device(pg, &pg->altmode_aux); if (pg->data->client_mask & BIT(PMIC_GLINK_CLIENT_UCSI)) pmic_glink_del_aux_device(pg, &pg->ucsi_aux); + if (pg->data->client_mask & BIT(PMIC_GLINK_CLIENT_RTC)) + pmic_glink_del_aux_device(pg, &pg->rtc_aux); =20 guard(mutex)(&__pmic_glink_lock); __pmic_glink =3D NULL; } =20 +static const struct pmic_glink_data pmic_glink_glymur_data =3D { + .client_mask =3D BIT(PMIC_GLINK_CLIENT_BATT) | + BIT(PMIC_GLINK_CLIENT_ALTMODE) | + BIT(PMIC_GLINK_CLIENT_UCSI) | + BIT(PMIC_GLINK_CLIENT_RTC), +}; + static const struct pmic_glink_data pmic_glink_adsp_data =3D { .client_mask =3D BIT(PMIC_GLINK_CLIENT_BATT) | BIT(PMIC_GLINK_CLIENT_ALTMODE) | @@ -404,7 +424,7 @@ static const struct pmic_glink_data pmic_glink_soccp_da= ta =3D { }; =20 static const struct of_device_id pmic_glink_of_match[] =3D { - { .compatible =3D "qcom,glymur-pmic-glink", .data =3D &pmic_glink_soccp_d= ata }, + { .compatible =3D "qcom,glymur-pmic-glink", .data =3D &pmic_glink_glymur_= data }, { .compatible =3D "qcom,kaanapali-pmic-glink", .data =3D &pmic_glink_socc= p_data }, { .compatible =3D "qcom,pmic-glink", .data =3D &pmic_glink_adsp_data }, {} diff --git a/include/linux/soc/qcom/pmic_glink.h b/include/linux/soc/qcom/p= mic_glink.h index 7cddf1027752..11031b06b810 100644 --- a/include/linux/soc/qcom/pmic_glink.h +++ b/include/linux/soc/qcom/pmic_glink.h @@ -11,6 +11,7 @@ struct pmic_glink_client; #define PMIC_GLINK_OWNER_BATTMGR 32778 #define PMIC_GLINK_OWNER_USBC 32779 #define PMIC_GLINK_OWNER_USBC_PAN 32780 +#define PMIC_GLINK_OWNER_RTC 32784 =20 #define PMIC_GLINK_REQ_RESP 1 #define PMIC_GLINK_NOTIFY 2 --=20 2.43.0