From nobody Sat Jun 13 03:35:41 2026 Received: from mail-pj1-f52.google.com (mail-pj1-f52.google.com [209.85.216.52]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id EBD733F0A98 for ; Wed, 29 Apr 2026 11:29:44 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.216.52 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777462186; cv=none; b=F1P3VXUtkp7Q7CqEGSR7bqDMZFVjdJVREghzomYG5yC6B1jD+JqBERiq6s+09V29Oxx4xN7E5z/HVN+P0WPXJGcT7HH8+J2+TgQQpb+JQa5MEYi13N8GMg+B21Ald5qfzMQDkkXZ52IBnGARHb2cBi8i51QGRKZwa3MXJoqt3Hs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777462186; c=relaxed/simple; bh=OGjx/rpqLanYJw8wyMx1GZX57lDgWW7QcL/E9ij2zVU=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=eCOSuQrLDLC0WlUfj51yHS/YGeB6CZstneRmfX6ACT2KTv7bOkjvpNuvxyy2itmw6it3uGUzrBm4W+7mJzYFSVvefVmDSMVSNZ8fRbbV/f/NWG6FExfRdPH6RliZu7NR6BqsJE0Z0gXUc7yYoVXYOnFw5D9GlPwaAWXEF2QKkq0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=inventec.com; spf=pass smtp.mailfrom=inventec.com; dkim=pass (2048-bit key) header.d=inventec.com header.i=@inventec.com header.b=OFR3PCy1; arc=none smtp.client-ip=209.85.216.52 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=inventec.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=inventec.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=inventec.com header.i=@inventec.com header.b="OFR3PCy1" Received: by mail-pj1-f52.google.com with SMTP id 98e67ed59e1d1-35e576110adso555473a91.0 for ; Wed, 29 Apr 2026 04:29:44 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=inventec.com; s=google; t=1777462184; x=1778066984; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=Z3ThBxdaxluBFioSVhIDwm332ADtoHWnIdue1Mw0j4g=; b=OFR3PCy1oI7IM7lPa2f8IScX275q0vkpIabpbNLvQX2Px2xl0paPcc9FAPLARMENcz Zb+BNWoAV4SKQdFGdpCD1fd2Fb53/zExFSVrfkaiAKmqvJew0uCty/JG866EODMRhHJg ev21yUxDFZFDl95nMs3XgNJLp3orvQySvmmbw6LBRZNPpvsExpaTg7UmmAzacjIMwiFH qj86abV288yq5QZ7DyRmoW4M5NGqcRON7CJt6TFpXF0uPcubm93vHsXMFWHURw0/ZUsY HqZefugvhcjAMzaJeqAByeGcaLR6eXTjKKGwyL4+bzbp+HqQFcBRoEfnSHgOn+moknBM 5/rg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1777462184; x=1778066984; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-gg:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to; bh=Z3ThBxdaxluBFioSVhIDwm332ADtoHWnIdue1Mw0j4g=; b=cNQYPscz2uBMQUWHUYQL4JvPw8+xtF8kOnJGID8Dlk/ogMOKSGPN96LzHQ4UL2zTR2 C7OdNgUM9NXPbFno20K2V/LdDq8tQ4TKHnYjhn1yww94HX6KqvpmTtBooS19l2rVOiut tZXDx/L9ySHYpbdKCiZPx/O7ihTao5V6B6UJwHhkSFsd/CxbcsixQRiO9nZ6v5pLhrZQ ju/H/1kkyV+FEhLFsSjcW7c7T3eHwk5qF1X0gXuLkt9OkfWpeGWZMhnwi2F+RoOAMF5q hZslxISNUcjC8J18LpsjVcu9LZww0Kf6ONyFEa28SpRHgAepr2pXTTd4xEUPUrU9tjcR ijYQ== X-Forwarded-Encrypted: i=1; AFNElJ8VgDPcdAXtYum67YgxQ6gLXundO+t3xe4czcDbKu2qprHl7+iddbab7PO8OTcArs8TCfu3mg7wkFxy1Zw=@vger.kernel.org X-Gm-Message-State: AOJu0YyEEn+CRKJld8CIjR9kTxm0ckBo2Or2lYX8AiXIQbtlMZOK4d0+ 4zmHxzDWkl5nlZvGhFdtQL0EjgjatWtkazZLKskGOob6P/gxvJxgpLj1xISziomMq7TSBEFqV5O f9JQ2r1s= X-Gm-Gg: AeBDieskSkCkEib7GaA1l6RGwnda1QAXWDMlXQgkAVGIGpQ+ajfBvVM+mjHvxl9VQ+w g3S8odKqYrMAziiRWj6FWmQx85uqP+fX06kv2QH0BOkD1n9775vsFqFkmOEX3hQ5C43B8fcbUIo 6RToAJKYYjzEfszxiSZ4B0Z0BS/KgaD/ro+vDQFyXdlAEZr+O0AnUaBamtd1OK7dyV3n0NCCRDx yNy61GvIkvc0PdMGO+GWsxx2wnp7xCDBCRFxMNIM0DlnOgyb+RkjSlegbQ6lvchDHVjIy30cDt4 bwdOP+0Q0j6ZmlwJtPHN+PZU1yCuiX+Ny88TiTPPONFv+0sa7eL9BG7CJTtACOA17FTl/KVhPUY 28AGMjBrmnhSDDAf/CNAKl+8dtUbbMbcDYMT0roV7E774wX6ZWjL+KIHy42X61DIWI7uB8Be3pO PHVjmBbQPb09AHX86wbL5uEPIMipx1ddMsDdkWWdHW X-Received: by 2002:a17:90b:2689:b0:35f:b9f1:fded with SMTP id 98e67ed59e1d1-364a2695f5fmr2309132a91.12.1777462184381; Wed, 29 Apr 2026 04:29:44 -0700 (PDT) Received: from [127.0.1.1] ([123.51.235.216]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-364a41520dbsm1923048a91.3.2026.04.29.04.29.42 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 29 Apr 2026 04:29:43 -0700 (PDT) From: Brian Chiang Date: Wed, 29 Apr 2026 11:29:36 +0000 Subject: [PATCH v7 1/2] dt-bindings: trivial: Add q50sn12072 and q54sn120a1 support 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: <20260429-add-support-for-q50sn12072-and-q54sn120a1-v7-1-f1f83d2039f7@inventec.com> References: <20260429-add-support-for-q50sn12072-and-q54sn120a1-v7-0-f1f83d2039f7@inventec.com> In-Reply-To: <20260429-add-support-for-q50sn12072-and-q54sn120a1-v7-0-f1f83d2039f7@inventec.com> To: Rob Herring , Krzysztof Kozlowski , Conor Dooley , Guenter Roeck Cc: devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-hwmon@vger.kernel.org, Jack Cheng , Brian Chiang , Jack Cheng X-Mailer: b4 0.13.0 X-Developer-Signature: v=1; a=ed25519-sha256; t=1777462179; l=1150; i=chiang.brian@inventec.com; s=20260316; h=from:subject:message-id; bh=371ndBFO++Ux/UDUOyIuv35ZzqLJAZsYGZPm32hIp6Q=; b=zucl2ZGby4rwo6Cs5LCVkf8Hj5atEBuyD2LeUMwSOhmXHoPl65un72V63KStsMG23EpO88vXv RvQP1VPtaxVB3tR4SUlqW2YLaZKO03wlYN23g6kHI0xx4lz/vX5F9q6 X-Developer-Key: i=chiang.brian@inventec.com; a=ed25519; pk=q+NqJYuJbGpA9KS9941D7f+8PVVW+k7DvaGgFykBiUc= From: Jack Cheng Add support for the Delta Electronics q50sn12072 and q54sn120a1 1/4 Brick DC/DC Regulated Power Modules. Signed-off-by: Jack Cheng Acked-by: Rob Herring (Arm) --- Documentation/devicetree/bindings/trivial-devices.yaml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Documentation/devicetree/bindings/trivial-devices.yaml b/Docum= entation/devicetree/bindings/trivial-devices.yaml index a482aeadcd44..d4b78154df82 100644 --- a/Documentation/devicetree/bindings/trivial-devices.yaml +++ b/Documentation/devicetree/bindings/trivial-devices.yaml @@ -96,7 +96,11 @@ properties: # Delta Electronics DPS920AB 920W 54V Power Supply - delta,dps920ab # 1/4 Brick DC/DC Regulated Power Module + - delta,q50sn12072 + # 1/4 Brick DC/DC Regulated Power Module - delta,q54sj108a2 + # 1/4 Brick DC/DC Regulated Power Module + - delta,q54sn120a1 # Devantech SRF02 ultrasonic ranger in I2C mode - devantech,srf02 # Devantech SRF08 ultrasonic ranger --=20 2.43.0 From nobody Sat Jun 13 03:35:41 2026 Received: from mail-pj1-f49.google.com (mail-pj1-f49.google.com [209.85.216.49]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id B78D53F1640 for ; Wed, 29 Apr 2026 11:29:47 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.216.49 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777462190; cv=none; b=N/K5PpC+cpOCpOvDg5oOjBnNDvZHUuT4NzEPHrD8fLC1ss7aClA6xRuEvyOa4sw7CgrhIkVxcftn1zul9REsiMq6i5q40HuwAraSJm4eKgTRxPVfyYF7eMQ5DosEtRelUPDfhUbeSMBc0l1BnRYWhJ0oyCvwmXlIjTE1bs5nxl8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777462190; c=relaxed/simple; bh=K41T3rcjgbgyPptj//cSWR3+F8YkJtn7jiqqKBE53C0=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=WiSq6MaxyNLl3tE5nGyGMe6hOL7JgG7GgoOt7t7RcPPg9gR8B6aBnkVv61c8ezYNX2hUXll9JEAmkzzf7Tl5cejzUBph02/+7hqDKsUt0EYQfdrEETkveke/OMjzpMUCvgZBf0sHiU/A0GQ2Xne2ifeXSrmPnnE421SrMZcuFD4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=inventec.com; spf=pass smtp.mailfrom=inventec.com; dkim=pass (2048-bit key) header.d=inventec.com header.i=@inventec.com header.b=BIkjLLTI; arc=none smtp.client-ip=209.85.216.49 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=inventec.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=inventec.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=inventec.com header.i=@inventec.com header.b="BIkjLLTI" Received: by mail-pj1-f49.google.com with SMTP id 98e67ed59e1d1-35d95017a68so8428262a91.3 for ; Wed, 29 Apr 2026 04:29:47 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=inventec.com; s=google; t=1777462187; x=1778066987; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=U5855hz31Y7sal0t7qD4FX3i6nclNMjvKAZM2P5Bg0s=; b=BIkjLLTIL0U2DJboWglRhtJNVZbdge0x/k+tjaCdqSlxG5Td7OHIY72er2B+sASgXr tgk4AWkPNeEwWIOA//TwIb9REjdHiA0kxi1wurY4J5HWkg9RC8qqu26oZx+mbM+hkiM5 g9vCzTCpXU9Eguqs4P6ECqy7fDnv5OjHMiwdWnFMEYXKVmoWcYXxm9IrrxJCAnYaMw0l qKKMWxVn3Jp7iUQPdcO+EpIDwMQiUPdFaZdycTc42frmHFlMGpeExlVzu2IphCcQrYHG tYaqFeYLtyCccWSGLVCgLz+2RwUzIur+psqnYe75s9o/nLm2t9Ki9cpPtrHOz5IvX7Yx REig== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1777462187; x=1778066987; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-gg:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to; bh=U5855hz31Y7sal0t7qD4FX3i6nclNMjvKAZM2P5Bg0s=; b=kKz0pH+X6qv3Hi/pW99qgakFkS5Ad6H9RxfLfDm+EO/z8oSFthgxp7hcCSkNt29s6T fWcF7FE8fj+wY6RIuLo/HKv35tMRow+tnb6Qr8rx8fK6yFQLBMZgX6GUAi0qqHPqyYlr wP7hGSCZm+JDHVM80LqzjnvRyUp4UgRQIoqpglgzFlRMJT63jlSx25hc1wcetU6dj5aE RuyEWIl3/ikytCQ6b54Lwp800oq56vanO56CeSez/Umy8SUtZDjIfz9/v7V3oLfW9sI2 XJY/+rYeMWV7tkCRFB6UotBs4w+HhokmjVaSLjGeejYsTNdGvvLcHAafZVX5Py7TXIrk APMw== X-Forwarded-Encrypted: i=1; AFNElJ9Gfi0fjrR8TS/R8A1cAsogZLOYO+eAm7Gye0pfBkugz72ATh21tPz2nkU/k2QUo74Fgf1Mk6BxdTCQvII=@vger.kernel.org X-Gm-Message-State: AOJu0YyG/dEuCJKKv+3KmV9o3VWhIqYT0qMD8hgPCdMKND9zUJeOk5z3 Ob4Zqj21R5sa/zDurg8JeRyu+3PBW1BW41+sBKOZ0xWnATkenMfyQqOGHb551M1bvtc= X-Gm-Gg: AeBDieuQ1+sJrJ9Pg2jEZvoVdB7szdpb5WvvlnyOBOqnql9/KxrdLhJsN79oM7FFlri dHEG14qvjTB5/GXYirkbPQpF+YVFI/Tx093LA1GakkonWx/CW3w8tH9wLaF749ANTLABLE9Jgji 0RclFnM4fSj87MtATeFIY3adHs1wTooFu9JN0sNSC7cn2u8kRgreUmI6CAoH+Xc/dgAKJyz8xS/ Z1HtxA83xRvOkH6IHRBPTeOFeeqgATg9FvLq3g/tTgHA/d/fLUg57dduDF5n5oV0J+HESSZMwy7 OST2I/BmrAI8mYDDLzs3WM5PH0gZdU+2sTilUmAdVueKd4Fk0HQZVvsFX+26re+MvsM3VWAigdu N/3wYkykVjCiMsTnch4RZiwWj0DGU7MauDTorjjCDVIRcSh48eUeNA02vfqPZHJFWVS78jgAzpg lz6PFw4JbFmtHYxGJFMxyLN70OOIrGVWkVdODr+PT9 X-Received: by 2002:a17:90a:fc4d:b0:35b:e690:c5ad with SMTP id 98e67ed59e1d1-36492064122mr7627259a91.25.1777462187031; Wed, 29 Apr 2026 04:29:47 -0700 (PDT) Received: from [127.0.1.1] ([123.51.235.216]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-364a41520dbsm1923048a91.3.2026.04.29.04.29.44 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 29 Apr 2026 04:29:46 -0700 (PDT) From: Brian Chiang Date: Wed, 29 Apr 2026 11:29:37 +0000 Subject: [PATCH v7 2/2] hwmon: (pmbus/q54sj108a2) Add support for q50sn12072 and q54sn120a1 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: <20260429-add-support-for-q50sn12072-and-q54sn120a1-v7-2-f1f83d2039f7@inventec.com> References: <20260429-add-support-for-q50sn12072-and-q54sn120a1-v7-0-f1f83d2039f7@inventec.com> In-Reply-To: <20260429-add-support-for-q50sn12072-and-q54sn120a1-v7-0-f1f83d2039f7@inventec.com> To: Rob Herring , Krzysztof Kozlowski , Conor Dooley , Guenter Roeck Cc: devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-hwmon@vger.kernel.org, Jack Cheng , Brian Chiang , Jack Cheng X-Mailer: b4 0.13.0 X-Developer-Signature: v=1; a=ed25519-sha256; t=1777462179; l=15274; i=chiang.brian@inventec.com; s=20260316; h=from:subject:message-id; bh=JlU4Y0cdkIZt0xD+yV2GO3lVXzOlCW9/wsCINaC8wQI=; b=g3es5GRaOAv9fipQyaMlripoHsjUuedTi15kmv9rj1JaTm8+z6ejXJ5BN0hQAptYeq5kzqDQn v/34Q9n59RbCeM2LuP7e9n8lXrdC6NoWWgL3DIbCOPQzLcVPR+VhooZ X-Developer-Key: i=chiang.brian@inventec.com; a=ed25519; pk=q+NqJYuJbGpA9KS9941D7f+8PVVW+k7DvaGgFykBiUc= From: Jack Cheng The Q50SN12072 and Q54SN120A1 are high-efficiency, high-density DC-DC power module from Delta Power Modules. The Q50SN12072, quarter brick, single output 12V. This product provides up to 1200 watts of output power at 38~60V. The Q50SN12072 offers peak efficiency up to 98.3%@54Vin. The Q54SN120A1, quarter brick, single output 12V. This product provides up to 1300 watts of output power at 40~60V. The Q54SN120A1 offers peak efficiency up to 98.1%@54Vin. Add support for them to q54sj108a2 driver. Signed-off-by: Jack Cheng Co-developed-by: Brian Chiang Signed-off-by: Brian Chiang --- drivers/hwmon/pmbus/q54sj108a2.c | 238 ++++++++++++++++++++++++-----------= ---- 1 file changed, 147 insertions(+), 91 deletions(-) diff --git a/drivers/hwmon/pmbus/q54sj108a2.c b/drivers/hwmon/pmbus/q54sj10= 8a2.c index d5d60a9af8c5..50539555a74e 100644 --- a/drivers/hwmon/pmbus/q54sj108a2.c +++ b/drivers/hwmon/pmbus/q54sj108a2.c @@ -22,7 +22,9 @@ #define PMBUS_FLASH_KEY_WRITE 0xEC =20 enum chips { - q54sj108a2 + q50sn12072, + q54sj108a2, + q54sn120a1 }; =20 enum { @@ -55,10 +57,24 @@ struct q54sj108a2_data { #define to_psu(x, y) container_of((x), struct q54sj108a2_data, debugfs_ent= ries[(y)]) =20 static struct pmbus_driver_info q54sj108a2_info[] =3D { - [q54sj108a2] =3D { + [q50sn12072] =3D { .pages =3D 1, + /* Source : Delta Q50SN12072 */ + .format[PSC_VOLTAGE_OUT] =3D linear, + .format[PSC_TEMPERATURE] =3D linear, + .format[PSC_VOLTAGE_IN] =3D linear, + .format[PSC_CURRENT_OUT] =3D linear, =20 + .func[0] =3D PMBUS_HAVE_VIN | PMBUS_HAVE_IIN | PMBUS_HAVE_PIN | + PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT | + PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT | + PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP | + PMBUS_HAVE_STATUS_INPUT | PMBUS_HAVE_POUT, + }, + [q54sj108a2] =3D { + .pages =3D 1, /* Source : Delta Q54SJ108A2 */ + .format[PSC_VOLTAGE_OUT] =3D linear, .format[PSC_TEMPERATURE] =3D linear, .format[PSC_VOLTAGE_IN] =3D linear, .format[PSC_CURRENT_OUT] =3D linear, @@ -69,6 +85,20 @@ static struct pmbus_driver_info q54sj108a2_info[] =3D { PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP | PMBUS_HAVE_STATUS_INPUT, }, + [q54sn120a1] =3D { + .pages =3D 1, + /* Source : Delta Q54SN120A1 */ + .format[PSC_VOLTAGE_OUT] =3D linear, + .format[PSC_TEMPERATURE] =3D linear, + .format[PSC_VOLTAGE_IN] =3D linear, + .format[PSC_CURRENT_OUT] =3D linear, + + .func[0] =3D PMBUS_HAVE_VIN | PMBUS_HAVE_IIN | PMBUS_HAVE_PIN | + PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT | + PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT | + PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP | + PMBUS_HAVE_STATUS_INPUT | PMBUS_HAVE_POUT, + }, }; =20 static ssize_t q54sj108a2_debugfs_read(struct file *file, char __user *buf, @@ -83,73 +113,77 @@ static ssize_t q54sj108a2_debugfs_read(struct file *fi= le, char __user *buf, char *out =3D data; char *res; =20 + rc =3D pmbus_lock_interruptible(psu->client); + if (rc) + return rc; + switch (idx) { case Q54SJ108A2_DEBUGFS_OPERATION: rc =3D i2c_smbus_read_byte_data(psu->client, PMBUS_OPERATION); if (rc < 0) - return rc; + goto unlock; =20 rc =3D snprintf(data, 3, "%02x", rc); break; case Q54SJ108A2_DEBUGFS_WRITEPROTECT: rc =3D i2c_smbus_read_byte_data(psu->client, PMBUS_WRITE_PROTECT); if (rc < 0) - return rc; + goto unlock; =20 rc =3D snprintf(data, 3, "%02x", rc); break; case Q54SJ108A2_DEBUGFS_VOOV_RESPONSE: rc =3D i2c_smbus_read_byte_data(psu->client, PMBUS_VOUT_OV_FAULT_RESPONS= E); if (rc < 0) - return rc; + goto unlock; =20 rc =3D snprintf(data, 3, "%02x", rc); break; case Q54SJ108A2_DEBUGFS_IOOC_RESPONSE: rc =3D i2c_smbus_read_byte_data(psu->client, PMBUS_IOUT_OC_FAULT_RESPONS= E); if (rc < 0) - return rc; + goto unlock; =20 rc =3D snprintf(data, 3, "%02x", rc); break; case Q54SJ108A2_DEBUGFS_PMBUS_VERSION: rc =3D i2c_smbus_read_byte_data(psu->client, PMBUS_REVISION); if (rc < 0) - return rc; + goto unlock; =20 rc =3D snprintf(data, 3, "%02x", rc); break; case Q54SJ108A2_DEBUGFS_MFR_ID: rc =3D i2c_smbus_read_block_data(psu->client, PMBUS_MFR_ID, data); if (rc < 0) - return rc; + goto unlock; break; case Q54SJ108A2_DEBUGFS_MFR_MODEL: rc =3D i2c_smbus_read_block_data(psu->client, PMBUS_MFR_MODEL, data); if (rc < 0) - return rc; + goto unlock; break; case Q54SJ108A2_DEBUGFS_MFR_REVISION: rc =3D i2c_smbus_read_block_data(psu->client, PMBUS_MFR_REVISION, data); if (rc < 0) - return rc; + goto unlock; break; case Q54SJ108A2_DEBUGFS_MFR_LOCATION: rc =3D i2c_smbus_read_block_data(psu->client, PMBUS_MFR_LOCATION, data); if (rc < 0) - return rc; + goto unlock; break; case Q54SJ108A2_DEBUGFS_BLACKBOX_READ_OFFSET: rc =3D i2c_smbus_read_byte_data(psu->client, READ_HISTORY_EVENT_NUMBER); if (rc < 0) - return rc; + goto unlock; =20 rc =3D snprintf(data, 3, "%02x", rc); break; case Q54SJ108A2_DEBUGFS_BLACKBOX_READ: rc =3D i2c_smbus_read_block_data(psu->client, READ_HISTORY_EVENTS, data); if (rc < 0) - return rc; + goto unlock; =20 res =3D bin2hex(data_char, data, rc); rc =3D res - data_char; @@ -158,16 +192,22 @@ static ssize_t q54sj108a2_debugfs_read(struct file *f= ile, char __user *buf, case Q54SJ108A2_DEBUGFS_FLASH_KEY: rc =3D i2c_smbus_read_block_data(psu->client, PMBUS_FLASH_KEY_WRITE, dat= a); if (rc < 0) - return rc; + goto unlock; =20 res =3D bin2hex(data_char, data, rc); rc =3D res - data_char; out =3D data_char; break; default: - return -EINVAL; + rc =3D -EINVAL; + goto unlock; } =20 +unlock: + pmbus_unlock(psu->client); + if (rc < 0) + return rc; + out[rc] =3D '\n'; rc +=3D 2; =20 @@ -183,27 +223,51 @@ static ssize_t q54sj108a2_debugfs_write(struct file *= file, const char __user *bu int *idxp =3D file->private_data; int idx =3D *idxp; struct q54sj108a2_data *psu =3D to_psu(idxp, idx); + int original_wp; + int rc_restore; =20 - rc =3D i2c_smbus_write_byte_data(psu->client, PMBUS_WRITE_PROTECT, 0); - if (rc) - return rc; - + /* + * Parse user input before acquiring the PMBus lock. Since calling + * kstrtou8_from_user() while holding pmbus_lock_interruptible() + * may introduce a denial of service risk. + */ switch (idx) { case Q54SJ108A2_DEBUGFS_OPERATION: + case Q54SJ108A2_DEBUGFS_VOOV_RESPONSE: + case Q54SJ108A2_DEBUGFS_IOOC_RESPONSE: + case Q54SJ108A2_DEBUGFS_BLACKBOX_SET_OFFSET: rc =3D kstrtou8_from_user(buf, count, 0, &dst_data); if (rc < 0) return rc; + break; + case Q54SJ108A2_DEBUGFS_CLEARFAULT: + case Q54SJ108A2_DEBUGFS_STOREDEFAULT: + case Q54SJ108A2_DEBUGFS_BLACKBOX_ERASE: + break; + default: + return -EINVAL; + } =20 - rc =3D i2c_smbus_write_byte_data(psu->client, PMBUS_OPERATION, dst_data); - if (rc < 0) - return rc; + rc =3D pmbus_lock_interruptible(psu->client); + if (rc) + return rc; + + original_wp =3D i2c_smbus_read_byte_data(psu->client, PMBUS_WRITE_PROTECT= ); + if (original_wp < 0) { + rc =3D original_wp; + goto unlock; + } + + rc =3D i2c_smbus_write_byte_data(psu->client, PMBUS_WRITE_PROTECT, 0); + if (rc < 0) + goto unlock; =20 + switch (idx) { + case Q54SJ108A2_DEBUGFS_OPERATION: + rc =3D i2c_smbus_write_byte_data(psu->client, PMBUS_OPERATION, dst_data); break; case Q54SJ108A2_DEBUGFS_CLEARFAULT: rc =3D i2c_smbus_write_byte(psu->client, PMBUS_CLEAR_FAULTS); - if (rc < 0) - return rc; - break; case Q54SJ108A2_DEBUGFS_STOREDEFAULT: flash_key[0] =3D 0x7E; @@ -212,52 +276,35 @@ static ssize_t q54sj108a2_debugfs_write(struct file *= file, const char __user *bu flash_key[3] =3D 0x42; rc =3D i2c_smbus_write_block_data(psu->client, PMBUS_FLASH_KEY_WRITE, 4,= flash_key); if (rc < 0) - return rc; - + break; rc =3D i2c_smbus_write_byte(psu->client, STORE_DEFAULT_ALL); - if (rc < 0) - return rc; - break; case Q54SJ108A2_DEBUGFS_VOOV_RESPONSE: - rc =3D kstrtou8_from_user(buf, count, 0, &dst_data); - if (rc < 0) - return rc; - rc =3D i2c_smbus_write_byte_data(psu->client, PMBUS_VOUT_OV_FAULT_RESPON= SE, dst_data); - if (rc < 0) - return rc; - break; case Q54SJ108A2_DEBUGFS_IOOC_RESPONSE: - rc =3D kstrtou8_from_user(buf, count, 0, &dst_data); - if (rc < 0) - return rc; - rc =3D i2c_smbus_write_byte_data(psu->client, PMBUS_IOUT_OC_FAULT_RESPON= SE, dst_data); - if (rc < 0) - return rc; - break; case Q54SJ108A2_DEBUGFS_BLACKBOX_ERASE: rc =3D i2c_smbus_write_byte(psu->client, ERASE_BLACKBOX_DATA); - if (rc < 0) - return rc; - break; case Q54SJ108A2_DEBUGFS_BLACKBOX_SET_OFFSET: - rc =3D kstrtou8_from_user(buf, count, 0, &dst_data); - if (rc < 0) - return rc; - rc =3D i2c_smbus_write_byte_data(psu->client, SET_HISTORY_EVENT_OFFSET, = dst_data); - if (rc < 0) - return rc; - break; - default: - return -EINVAL; } + /* + * Always restore WRITE_PROTECT and preserve the original error in + * rc; only surface the restore failure if the operation itself was + * successful. + */ + rc_restore =3D i2c_smbus_write_byte_data(psu->client, PMBUS_WRITE_PROTECT= , original_wp); + if (rc_restore < 0 && rc >=3D 0) + rc =3D rc_restore; + +unlock: + pmbus_unlock(psu->client); + if (rc < 0) + return rc; =20 return count; } @@ -270,7 +317,9 @@ static const struct file_operations q54sj108a2_fops =3D= { }; =20 static const struct i2c_device_id q54sj108a2_id[] =3D { + { "q50sn12072", q50sn12072 }, { "q54sj108a2", q54sj108a2 }, + { "q54sn120a1", q54sn120a1 }, { }, }; =20 @@ -280,6 +329,7 @@ static int q54sj108a2_probe(struct i2c_client *client) { struct device *dev =3D &client->dev; u8 buf[I2C_SMBUS_BLOCK_MAX + 1]; + const struct i2c_device_id *mid; enum chips chip_id; int ret, i; struct dentry *debugfs; @@ -292,14 +342,9 @@ static int q54sj108a2_probe(struct i2c_client *client) I2C_FUNC_SMBUS_BLOCK_DATA)) return -ENODEV; =20 - if (client->dev.of_node) - chip_id =3D (enum chips)(unsigned long)of_device_get_match_data(dev); - else - chip_id =3D i2c_match_id(q54sj108a2_id, client)->driver_data; - ret =3D i2c_smbus_read_block_data(client, PMBUS_MFR_ID, buf); if (ret < 0) { - dev_err(&client->dev, "Failed to read Manufacturer ID\n"); + dev_err(dev, "Failed to read Manufacturer ID\n"); return ret; } if (ret !=3D 6 || strncmp(buf, "DELTA", 5)) { @@ -308,19 +353,25 @@ static int q54sj108a2_probe(struct i2c_client *client) return -ENODEV; } =20 - /* - * The chips support reading PMBUS_MFR_MODEL. - */ ret =3D i2c_smbus_read_block_data(client, PMBUS_MFR_MODEL, buf); if (ret < 0) { dev_err(dev, "Failed to read Manufacturer Model\n"); return ret; } - if (ret !=3D 14 || strncmp(buf, "Q54SJ108A2", 10)) { - buf[ret] =3D '\0'; + buf[ret] =3D '\0'; + for (mid =3D q54sj108a2_id; mid->name[0]; mid++) { + if (!strncasecmp(mid->name, buf, strlen(mid->name))) + break; + } + if (!mid->name[0]) { dev_err(dev, "Unsupported Manufacturer Model '%s'\n", buf); return -ENODEV; } + chip_id =3D mid->driver_data; + + if (strcmp(client->name, mid->name) !=3D 0) + dev_notice(dev, "Device mismatch: Configured %s, detected %s\n", + client->name, mid->name); =20 ret =3D i2c_smbus_read_block_data(client, PMBUS_MFR_REVISION, buf); if (ret < 0) { @@ -333,16 +384,17 @@ static int q54sj108a2_probe(struct i2c_client *client) return -ENODEV; } =20 - ret =3D pmbus_do_probe(client, &q54sj108a2_info[chip_id]); - if (ret) - return ret; - psu =3D devm_kzalloc(&client->dev, sizeof(*psu), GFP_KERNEL); if (!psu) return 0; =20 + psu->chip =3D chip_id; psu->client =3D client; =20 + ret =3D pmbus_do_probe(client, &q54sj108a2_info[chip_id]); + if (ret) + return ret; + debugfs =3D pmbus_get_debugfs_dir(client); =20 q54sj108a2_dir =3D debugfs_create_dir(client->name, debugfs); @@ -359,9 +411,6 @@ static int q54sj108a2_probe(struct i2c_client *client) debugfs_create_file("write_protect", 0444, q54sj108a2_dir, &psu->debugfs_entries[Q54SJ108A2_DEBUGFS_WRITEPROTECT], &q54sj108a2_fops); - debugfs_create_file("store_default", 0200, q54sj108a2_dir, - &psu->debugfs_entries[Q54SJ108A2_DEBUGFS_STOREDEFAULT], - &q54sj108a2_fops); debugfs_create_file("vo_ov_response", 0644, q54sj108a2_dir, &psu->debugfs_entries[Q54SJ108A2_DEBUGFS_VOOV_RESPONSE], &q54sj108a2_fops); @@ -383,27 +432,34 @@ static int q54sj108a2_probe(struct i2c_client *client) debugfs_create_file("mfr_location", 0444, q54sj108a2_dir, &psu->debugfs_entries[Q54SJ108A2_DEBUGFS_MFR_LOCATION], &q54sj108a2_fops); - debugfs_create_file("blackbox_erase", 0200, q54sj108a2_dir, - &psu->debugfs_entries[Q54SJ108A2_DEBUGFS_BLACKBOX_ERASE], - &q54sj108a2_fops); - debugfs_create_file("blackbox_read_offset", 0444, q54sj108a2_dir, - &psu->debugfs_entries[Q54SJ108A2_DEBUGFS_BLACKBOX_READ_OFFSET], - &q54sj108a2_fops); - debugfs_create_file("blackbox_set_offset", 0200, q54sj108a2_dir, - &psu->debugfs_entries[Q54SJ108A2_DEBUGFS_BLACKBOX_SET_OFFSET], - &q54sj108a2_fops); - debugfs_create_file("blackbox_read", 0444, q54sj108a2_dir, - &psu->debugfs_entries[Q54SJ108A2_DEBUGFS_BLACKBOX_READ], - &q54sj108a2_fops); - debugfs_create_file("flash_key", 0444, q54sj108a2_dir, - &psu->debugfs_entries[Q54SJ108A2_DEBUGFS_FLASH_KEY], - &q54sj108a2_fops); + if (psu->chip =3D=3D q54sj108a2) { + debugfs_create_file("store_default", 0200, q54sj108a2_dir, + &psu->debugfs_entries[Q54SJ108A2_DEBUGFS_STOREDEFAULT], + &q54sj108a2_fops); + debugfs_create_file("blackbox_erase", 0200, q54sj108a2_dir, + &psu->debugfs_entries[Q54SJ108A2_DEBUGFS_BLACKBOX_ERASE], + &q54sj108a2_fops); + debugfs_create_file("blackbox_read_offset", 0444, q54sj108a2_dir, + &psu->debugfs_entries[Q54SJ108A2_DEBUGFS_BLACKBOX_READ_OFFSET], + &q54sj108a2_fops); + debugfs_create_file("blackbox_read", 0444, q54sj108a2_dir, + &psu->debugfs_entries[Q54SJ108A2_DEBUGFS_BLACKBOX_READ], + &q54sj108a2_fops); + debugfs_create_file("blackbox_set_offset", 0200, q54sj108a2_dir, + &psu->debugfs_entries[Q54SJ108A2_DEBUGFS_BLACKBOX_SET_OFFSET], + &q54sj108a2_fops); + debugfs_create_file("flash_key", 0444, q54sj108a2_dir, + &psu->debugfs_entries[Q54SJ108A2_DEBUGFS_FLASH_KEY], + &q54sj108a2_fops); + } =20 return 0; } =20 static const struct of_device_id q54sj108a2_of_match[] =3D { - { .compatible =3D "delta,q54sj108a2", .data =3D (void *)q54sj108a2 }, + { .compatible =3D "delta,q50sn12072" }, + { .compatible =3D "delta,q54sj108a2" }, + { .compatible =3D "delta,q54sn120a1" }, { }, }; =20 @@ -421,6 +477,6 @@ static struct i2c_driver q54sj108a2_driver =3D { module_i2c_driver(q54sj108a2_driver); =20 MODULE_AUTHOR("Xiao.Ma "); -MODULE_DESCRIPTION("PMBus driver for Delta Q54SJ108A2 series modules"); +MODULE_DESCRIPTION("PMBus driver for Delta Q54SJ108A2 and compatibles"); MODULE_LICENSE("GPL"); MODULE_IMPORT_NS("PMBUS"); --=20 2.43.0