Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/1.2/patches/2220929/?format=api
{ "id": 2220929, "url": "http://patchwork.ozlabs.org/api/1.2/patches/2220929/?format=api", "web_url": "http://patchwork.ozlabs.org/project/uboot/patch/20260408121841.186410-2-aswin.murugan@oss.qualcomm.com/", "project": { "id": 18, "url": "http://patchwork.ozlabs.org/api/1.2/projects/18/?format=api", "name": "U-Boot", "link_name": "uboot", "list_id": "u-boot.lists.denx.de", "list_email": "u-boot@lists.denx.de", "web_url": null, "scm_url": null, "webscm_url": null, "list_archive_url": "", "list_archive_url_format": "", "commit_url_format": "" }, "msgid": "<20260408121841.186410-2-aswin.murugan@oss.qualcomm.com>", "list_archive_url": null, "date": "2026-04-08T12:18:35", "name": "[v4,1/7] misc: Add support for bit fields in NVMEM cells", "commit_ref": null, "pull_url": null, "state": "new", "archived": false, "hash": "a21e4182fbbe78b30d5154acb677c3ddc67122d0", "submitter": { "id": 90811, "url": "http://patchwork.ozlabs.org/api/1.2/people/90811/?format=api", "name": "Aswin Murugan", "email": "aswin.murugan@oss.qualcomm.com" }, "delegate": { "id": 151538, "url": "http://patchwork.ozlabs.org/api/1.2/users/151538/?format=api", "username": "kcxt", "first_name": "Casey", "last_name": "Connolly", "email": "casey.connolly@linaro.org" }, "mbox": "http://patchwork.ozlabs.org/project/uboot/patch/20260408121841.186410-2-aswin.murugan@oss.qualcomm.com/mbox/", "series": [ { "id": 499133, "url": "http://patchwork.ozlabs.org/api/1.2/series/499133/?format=api", "web_url": "http://patchwork.ozlabs.org/project/uboot/list/?series=499133", "date": "2026-04-08T12:18:34", "name": "qcom: Add NVMEM bitfield support and reboot���mode integration", "version": 4, "mbox": "http://patchwork.ozlabs.org/series/499133/mbox/" } ], "comments": "http://patchwork.ozlabs.org/api/patches/2220929/comments/", "check": "pending", "checks": "http://patchwork.ozlabs.org/api/patches/2220929/checks/", "tags": {}, "related": [], "headers": { "Return-Path": "<u-boot-bounces@lists.denx.de>", "X-Original-To": "incoming@patchwork.ozlabs.org", "Delivered-To": "patchwork-incoming@legolas.ozlabs.org", "Authentication-Results": [ "legolas.ozlabs.org;\n\tdkim=pass (2048-bit key;\n unprotected) header.d=qualcomm.com header.i=@qualcomm.com header.a=rsa-sha256\n header.s=qcppdkim1 header.b=m8Y++KxK;\n\tdkim=pass (2048-bit key;\n unprotected) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com\n header.a=rsa-sha256 header.s=google header.b=HE0tZlnB;\n\tdkim-atps=neutral", "legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de\n (client-ip=2a01:238:438b:c500:173d:9f52:ddab:ee01; helo=phobos.denx.de;\n envelope-from=u-boot-bounces@lists.denx.de; receiver=patchwork.ozlabs.org)", "phobos.denx.de;\n dmarc=none (p=none dis=none) header.from=oss.qualcomm.com", "phobos.denx.de;\n spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de", "phobos.denx.de;\n\tdkim=pass (2048-bit key;\n unprotected) header.d=qualcomm.com header.i=@qualcomm.com\n header.b=\"m8Y++KxK\";\n\tdkim=pass (2048-bit key;\n unprotected) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com\n header.b=\"HE0tZlnB\";\n\tdkim-atps=neutral", "phobos.denx.de; dmarc=none (p=none dis=none)\n header.from=oss.qualcomm.com", "phobos.denx.de;\n spf=pass smtp.mailfrom=aswin.murugan@oss.qualcomm.com" ], "Received": [ "from phobos.denx.de (phobos.denx.de\n [IPv6:2a01:238:438b:c500:173d:9f52:ddab:ee01])\n\t(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n\t key-exchange x25519)\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4frMbR5LBQz1xy1\n\tfor <incoming@patchwork.ozlabs.org>; Wed, 08 Apr 2026 22:20:35 +1000 (AEST)", "from h2850616.stratoserver.net (localhost [IPv6:::1])\n\tby phobos.denx.de (Postfix) with ESMTP id AC61884118;\n\tWed, 8 Apr 2026 14:20:33 +0200 (CEST)", "by phobos.denx.de (Postfix, from userid 109)\n id 6FC028404A; Wed, 8 Apr 2026 14:20:32 +0200 (CEST)", "from mx0a-0031df01.pphosted.com (mx0a-0031df01.pphosted.com\n [205.220.168.131])\n (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits))\n (No client certificate requested)\n by phobos.denx.de (Postfix) with ESMTPS id C3B8584120\n for <u-boot@lists.denx.de>; Wed, 8 Apr 2026 14:20:29 +0200 (CEST)", "from pps.filterd (m0279863.ppops.net [127.0.0.1])\n by mx0a-0031df01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id\n 638B29s1263342\n for <u-boot@lists.denx.de>; Wed, 8 Apr 2026 12:20:28 GMT", "from mail-pg1-f198.google.com (mail-pg1-f198.google.com\n [209.85.215.198])\n by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 4dd7t239mx-1\n (version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NOT)\n for <u-boot@lists.denx.de>; Wed, 08 Apr 2026 12:20:27 +0000 (GMT)", "by mail-pg1-f198.google.com with SMTP id\n 41be03b00d2f7-c709551ec08so10110677a12.3\n for <u-boot@lists.denx.de>; Wed, 08 Apr 2026 05:20:27 -0700 (PDT)", "from hu-aswinm-blr.qualcomm.com\n (blr-bdr-fw-01_GlobalNAT_AllZones-Outside.qualcomm.com. [103.229.18.19])\n by smtp.gmail.com with ESMTPSA id\n d2e1a72fcca58-82cf9a24039sm20512602b3a.0.2026.04.08.05.20.17\n (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);\n Wed, 08 Apr 2026 05:20:25 -0700 (PDT)" ], "X-Spam-Checker-Version": "SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de", "X-Spam-Level": "", "X-Spam-Status": "No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED,\n DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_BLOCKED,\n RCVD_IN_VALIDITY_CERTIFIED_BLOCKED,RCVD_IN_VALIDITY_RPBL_BLOCKED,\n SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.2", "DKIM-Signature": [ "v=1; a=rsa-sha256; c=relaxed/relaxed; d=qualcomm.com; h=\n content-transfer-encoding:content-type:date:from:in-reply-to\n :message-id:mime-version:references:subject:to; s=qcppdkim1; bh=\n 7gmz65N45KppacmQTZ8HP0PtbwNgWbJFVMftib9X0WU=; b=m8Y++KxKCwshQiaQ\n rzT1Ule9+1Xijyu5bIntZ2mlLBaJ4+oa1nIHmNrbBxwL0kzSptsiEXhDBZ0rxX2+\n fIqsaFdlNGXwyrZwvq1jD1CNSUM5sSIBvLOd93W/ttkCZDoUJ83pJ7nYq3XB23dr\n EeVRospVLqhky09ohiSn4BZ59TbCpA1xU14W3RSwX60j7RMxtowDQLd0pYtxDpJN\n Um+W2XlqRPKOaO+04LOD1oWOqWOTPUNprJ2MvTidsyQnrzSE2MdviIbR7MQSvOeq\n 1Jr1Vn5YETwgKh5E2SHWt9TLSPfgXVRaQzMNu5eojrhoQHW1Ic8LCg9IH891TJ4p\n +Nanyg==", "v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=oss.qualcomm.com; s=google; t=1775650827; x=1776255627; darn=lists.denx.de;\n h=content-transfer-encoding:mime-version:references:in-reply-to\n :message-id:date:subject:to:from:from:to:cc:subject:date:message-id\n :reply-to; bh=7gmz65N45KppacmQTZ8HP0PtbwNgWbJFVMftib9X0WU=;\n b=HE0tZlnB5kF8+SgdGSbdTZsGd1zjL4lnVGl6fi1tVtueoWf0oK9KTSrJGxoDkq+Kel\n Mr67o2iEvtJuntWVRJy6W1JEl0FhnDGqvM13nIPLdRlvYaNS7F0A+fspNK/ppuVirqQI\n jJaUGVoHqUIewGGOO3wQrGUo2Vf+UPfqetZtQU3OLPX1vcGETHX0v1tEBe3rDilnjXZs\n aW9m70gTM7gb8GHw9Re9uX0OvPlYt6YqNvPhwFCPTHOW2X24DZkWZgYexDfWQ9mCd1P8\n G+I5AFJha76QDQ9z/llowxyxf1Dv0NVxpX9JTGCmgPOZhUNulX1ckoBr0DkoFLamFD6G\n M24Q==" ], "X-Google-DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=1e100.net; s=20251104; t=1775650827; x=1776255627;\n h=content-transfer-encoding:mime-version:references:in-reply-to\n :message-id:date:subject:to:from:x-gm-gg:x-gm-message-state:from:to\n :cc:subject:date:message-id:reply-to;\n bh=7gmz65N45KppacmQTZ8HP0PtbwNgWbJFVMftib9X0WU=;\n b=d1r6IXzZoNK51wUVUwnIma67nQR2ePQi0W9rnFv2y5ssBc1/TTIxs7gevqRCyzdC54\n wcODN0DT6GKV+u7qSzVS0N1bD+dMc0EOGw7uASUx5Dc3vjgKzSwdMVKACetCeLriip5F\n qP6tpX2mL+cu4uULZNvwSdjgGU4hJ6z5MbyRf2RVORhHvHJ7AQLiVI3/G8h6nRCQmKTh\n A/XpmVgn++tt3bMx3ZLEil15/ibjeg4xz2S4gwy3ivw7wKFmpRrz+dzJ3srKSkfRd1eE\n nptEK6vvDvWBsd2wCoPBjgzxGNVsowrqOzlRnz542uTiMkKUMiDSBGaakNe5xoSdt+EC\n CNgA==", "X-Forwarded-Encrypted": "i=1;\n AJvYcCXjP9zdtoN9k+HwcJSl7QVX8ibULv3aIpzGLKuFktklJeiLjTsvgbQJQNRnYnUuv8//vjjQBMc=@lists.denx.de", "X-Gm-Message-State": "AOJu0Yzpv2p0SwSkFXPbM4CvJnAfdUkiPZ1Cce5ed61Hj0014sYLUQeC\n hR/dLepegymkRdgvF543qjMPnvtRa5djz6atIIxxvRHsWq3Q/218Twtx8F4NbfXQEer3jajeEfd\n FvodSYp9AyQXC/fE7M5Kp0IkrxUZeIxUNSaQ2fyo2cvu4ieZKcddQV+8I", "X-Gm-Gg": "AeBDievmiTKUijc9x+blkHgxeJBU3iG5Ej3Y0+lYHIWZHHCop8LUEvSXaMGDrVwM4uj\n 9KwtAcG8p2o2kzrA1l+2FyUTWHbEGk8IqFKR2SJc8PdqiM1Ge47zjIEQxS+nxXy7VOmyBKBuxM+\n z7xT+qO0XuR1RM9o4m3kt1wxOUSsof4MeD/SGdcDU04TEgaSuH3vS6sy98ruLrTpukCauUDMy7j\n fMIg5jJPFAcSUQe4CKpQYQG/HhkZr+de1PWDkCL1sT/DAJ5oysluLWepwG/pRn1PjLe5rZQ0D4s\n XKt50lVf6bWt/Rb591uIrjY7O2rj6GhL/SSbTfVr5+dEUgtCDCRcH0VP3h6z8SCbkexcbQb2JZz\n XeTCyZgImSwhAt1NHZ+hKHZnwME+DA1NZwQ/UYBjhOWa2kkcZrZS1RKbqfRm7VTLP0ZXu0Xz6Yc\n QnZrbXMar0CgvdD7j9VSJTu550n8ZvRhBfG6suGI5P", "X-Received": [ "by 2002:a05:6a00:418e:b0:82a:7893:e14f with SMTP id\n d2e1a72fcca58-82d0dbb9939mr21606511b3a.41.1775650826714;\n Wed, 08 Apr 2026 05:20:26 -0700 (PDT)", "by 2002:a05:6a00:418e:b0:82a:7893:e14f with SMTP id\n d2e1a72fcca58-82d0dbb9939mr21606468b3a.41.1775650826151;\n Wed, 08 Apr 2026 05:20:26 -0700 (PDT)" ], "From": "Aswin Murugan <aswin.murugan@oss.qualcomm.com>", "To": "trini@konsulko.com, aswin.murugan@oss.qualcomm.com,\n casey.connolly@linaro.org, neil.armstrong@linaro.org,\n sumit.garg@kernel.org, sjg@chromium.org, seanga2@gmail.com,\n sughosh.ganu@arm.com, gchan9527@gmail.com, ilias.apalodimas@linaro.org,\n mkorpershoek@kernel.org, marek.vasut+renesas@mailbox.org,\n hs@nabladev.com, msp@baylibre.com, ravi@prevas.dk,\n dinesh.maniyam@altera.com, sajattack@postmarketos.org,\n peng.fan@nxp.com, quentin.schulz@cherry.de,\n jamie.gibbons@microchip.com, mateuslima.ti@gmail.com,\n justin@tidylabs.net, wens@kernel.org, n-francis@ti.com,\n ycliang@andestech.com, jerome.forissier@arm.com, clamor95@gmail.com,\n u-boot@lists.denx.de, u-boot-qcom@groups.io", "Subject": "[PATCH v4 1/7] misc: Add support for bit fields in NVMEM cells", "Date": "Wed, 8 Apr 2026 17:48:35 +0530", "Message-Id": "<20260408121841.186410-2-aswin.murugan@oss.qualcomm.com>", "X-Mailer": "git-send-email 2.34.1", "In-Reply-To": "<20260408121841.186410-1-aswin.murugan@oss.qualcomm.com>", "References": "<20260408121841.186410-1-aswin.murugan@oss.qualcomm.com>", "MIME-Version": "1.0", "Content-Type": "text/plain; charset=UTF-8", "Content-Transfer-Encoding": "8bit", "X-Authority-Analysis": "v=2.4 cv=De0nbPtW c=1 sm=1 tr=0 ts=69d6480b cx=c_pps\n a=Qgeoaf8Lrialg5Z894R3/Q==:117 a=Ou0eQOY4+eZoSc0qltEV5Q==:17\n a=IkcTkHD0fZMA:10 a=A5OVakUREuEA:10 a=s4-Qcg_JpJYA:10\n a=VkNPw1HP01LnGYTKEx00:22 a=u7WPNUs3qKkmUXheDGA7:22 a=yOCtJkima9RkubShWh1s:22\n a=EUspDBNiAAAA:8 a=T-YsAnR6KVLXiY_LWkEA:9 a=3ZKOabzyN94A:10 a=QEXdDO2ut3YA:10\n a=x9snwWr2DeNwDh03kgHS:22", "X-Proofpoint-Spam-Details-Enc": "AW1haW4tMjYwNDA4MDExMiBTYWx0ZWRfXxQVwbdIezp2q\n VdAByeWdzgUiynkMc0L5tB+xImyVX0Gk/pghWpmPS/dabk1SziwhKuBh95V5QOEhR8fLRweLEcb\n C1MtfwUuaWr5luDz8Bq85FXXx+VPQbY74BY+W8wgr4Jmsd9Waj9uP2rStx3yfJHy4YGXBPMuyYF\n mIZH6tBZU2Fj30NgPDnGubvANgth7KM6kcN5LUBVLOopoWaWq1AtM/8nqaPZgGlbalCo4maPbvm\n 2lW929TVwuxbR25rPylGs46Xa8o0PtpZXP4+wo1cAYWQa9m4UGsGeaEk9uOu+tSHjBNEMnoeRcB\n HFDXiGFWzfQ0BWPuV7JEC9cooHgcTUXOrQM/8wrHSDMziPdBWRRv7uvdBEnP3QH/3fWGBlIzSQr\n Kymfn25uySj2ezSsrH57G4dVcHGRGM7Zhxeubo73r7+4nEILB1J6yUz4bcjdZwfUCF3wdAbpfti\n MA4jA7voeP/tup6WxFA==", "X-Proofpoint-ORIG-GUID": "qsYlJH8wwZ3lj9xUJNgfKa8XSVhgzGcv", "X-Proofpoint-GUID": "qsYlJH8wwZ3lj9xUJNgfKa8XSVhgzGcv", "X-Proofpoint-Virus-Version": "vendor=baseguard\n engine=ICAP:2.0.293,Aquarius:18.0.1143,Hydra:6.1.51,FMLib:17.12.100.49\n definitions=2026-04-08_03,2026-04-08_01,2025-10-01_01", "X-Proofpoint-Spam-Details": "rule=outbound_notspam policy=outbound score=0\n spamscore=0 clxscore=1015 bulkscore=0 phishscore=0 priorityscore=1501\n malwarescore=0 lowpriorityscore=0 suspectscore=0 impostorscore=0 adultscore=0\n classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0\n reason=mlx scancount=1 engine=8.22.0-2604010000 definitions=main-2604080112", "X-BeenThere": "u-boot@lists.denx.de", "X-Mailman-Version": "2.1.39", "Precedence": "list", "List-Id": "U-Boot discussion <u-boot.lists.denx.de>", "List-Unsubscribe": "<https://lists.denx.de/options/u-boot>,\n <mailto:u-boot-request@lists.denx.de?subject=unsubscribe>", "List-Archive": "<https://lists.denx.de/pipermail/u-boot/>", "List-Post": "<mailto:u-boot@lists.denx.de>", "List-Help": "<mailto:u-boot-request@lists.denx.de?subject=help>", "List-Subscribe": "<https://lists.denx.de/listinfo/u-boot>,\n <mailto:u-boot-request@lists.denx.de?subject=subscribe>", "Errors-To": "u-boot-bounces@lists.denx.de", "Sender": "\"U-Boot\" <u-boot-bounces@lists.denx.de>", "X-Virus-Scanned": "clamav-milter 0.103.8 at phobos.denx.de", "X-Virus-Status": "Clean" }, "content": "NVMEM cells currently only support byte-level access. Many hardware\nregisters pack multiple fields into single bytes, requiring bit-level\ngranularity. For example, Qualcomm PMIC PON registers store a 7-bit\nreboot reason field within a single byte, with bit 0 reserved for other\npurposes.\n\nAdd support for the optional 'bits' property in NVMEM cell device tree\nbindings. This property specifies <bit_offset num_bits> to define a bit\nfield within the cell's register space.\n\nImplement bit‑field handling in the driver to max u32 size\n\nExample device tree usage:\n reboot-reason@48 {\n reg = <0x48 0x01>;\n bits = <1 7>; /* 7 bits starting at bit 1 */\n };\n\nThis reads bits [7:1] from the byte at offset 0x48, leaving bit 0\nuntouched during write operations.\n\nCells without the 'bits' property continue to work unchanged, ensuring\nbackward compatibility with existing device trees.\n\nSigned-off-by: Aswin Murugan <aswin.murugan@oss.qualcomm.com>\n---\nChanges in v4:\n1. Explicitly interpret hardware bytes as little-endian for bitfield operations to ensure\n consistent behavior across architectures\n Read path: Hardware LE → CPU native → bit extraction → return CPU native\n Write path: CPU native → bit manipulation → convert to LE → write to hardware\n2. Removed const pointer write violation in nvmem_cell_write()\n3. Replaced unsafe bit shift expressions with GENMASK() macro to avoid undefined behavior\n when nbits == 32\n4. Consolidated size validation logic for clarity\n\nChanges in v3:\n1. Simplified bit field handling to maximum u32 size (32 bits).\n2. Enforced strict size matching (size == cell->size) when nbits == 0.\n---\n drivers/misc/nvmem.c | 166 +++++++++++++++++++++++++++++++++++++------\n include/nvmem.h | 4 ++\n 2 files changed, 148 insertions(+), 22 deletions(-)", "diff": "diff --git a/drivers/misc/nvmem.c b/drivers/misc/nvmem.c\nindex 33e80858565..7cca34b09d5 100644\n--- a/drivers/misc/nvmem.c\n+++ b/drivers/misc/nvmem.c\n@@ -12,55 +12,163 @@\n #include <dm/ofnode.h>\n #include <dm/read.h>\n #include <dm/uclass.h>\n+#include <linux/bitops.h>\n+#include <linux/kernel.h>\n+#include <asm/byteorder.h>\n \n-int nvmem_cell_read(struct nvmem_cell *cell, void *buf, size_t size)\n+/* Maximum supported NVMEM cell size */\n+#define MAX_NVMEM_CELL_SIZE sizeof(u32) /* 4 bytes */\n+\n+/**\n+ * nvmem_cell_read_raw() - Read raw bytes from NVMEM cell without bit field extraction\n+ * @cell: NVMEM cell to read from\n+ * @buf: Buffer to store read data\n+ * @size: Size of buffer\n+ *\n+ * This is an internal helper that reads raw bytes from hardware without applying\n+ * bit field extraction. Used by both nvmem_cell_read() and nvmem_cell_write().\n+ * Caller must validate buffer size before calling this function.\n+ *\n+ * Return: Number of bytes read on success, negative error code on failure\n+ */\n+static int nvmem_cell_read_raw(struct nvmem_cell *cell, void *buf, size_t size)\n {\n-\tdev_dbg(cell->nvmem, \"%s: off=%u size=%zu\\n\", __func__, cell->offset, size);\n-\tif (size != cell->size)\n-\t\treturn -EINVAL;\n+\tint ret;\n+\n+\tmemset(buf, 0, size);\n \n \tswitch (cell->nvmem->driver->id) {\n \tcase UCLASS_I2C_EEPROM:\n-\t\treturn i2c_eeprom_read(cell->nvmem, cell->offset, buf, size);\n-\tcase UCLASS_MISC: {\n-\t\tint ret = misc_read(cell->nvmem, cell->offset, buf, size);\n-\n+\t\tret = i2c_eeprom_read(cell->nvmem, cell->offset, buf, cell->size);\n+\t\tbreak;\n+\tcase UCLASS_MISC:\n+\t\tret = misc_read(cell->nvmem, cell->offset, buf, cell->size);\n \t\tif (ret < 0)\n \t\t\treturn ret;\n-\t\tif (ret != size)\n+\t\tif (ret != cell->size)\n \t\t\treturn -EIO;\n-\t\treturn 0;\n-\t}\n+\t\tret = 0;\n+\t\tbreak;\n \tcase UCLASS_RTC:\n-\t\treturn dm_rtc_read(cell->nvmem, cell->offset, buf, size);\n+\t\tret = dm_rtc_read(cell->nvmem, cell->offset, buf, cell->size);\n+\t\tbreak;\n \tdefault:\n \t\treturn -ENOSYS;\n \t}\n+\n+\tif (ret)\n+\t\treturn ret;\n+\n+\treturn cell->size;\n+}\n+\n+int nvmem_cell_read(struct nvmem_cell *cell, void *buf, size_t size)\n+{\n+\tint ret, bytes_needed;\n+\tu32 value;\n+\n+\tdev_dbg(cell->nvmem, \"%s: off=%u size=%zu\\n\", __func__, cell->offset, size);\n+\n+\tif (cell->nbits) {\n+\t\tif (size != MAX_NVMEM_CELL_SIZE) {\n+\t\t\tdev_dbg(cell->nvmem, \"bit field requires buffer size %d, got %zu\\n\",\n+\t\t\t\tMAX_NVMEM_CELL_SIZE, size);\n+\t\t\treturn -EINVAL;\n+\t\t}\n+\n+\t\tbytes_needed = DIV_ROUND_UP(cell->nbits + cell->bit_offset, BITS_PER_BYTE);\n+\t\tif (bytes_needed > cell->size || bytes_needed > MAX_NVMEM_CELL_SIZE) {\n+\t\t\tdev_dbg(cell->nvmem, \"bit field requires %d bytes, cell size %zu\\n\",\n+\t\t\t\tbytes_needed, cell->size);\n+\t\t\treturn -EINVAL;\n+\t\t}\n+\t} else {\n+\t\tif (size != cell->size) {\n+\t\t\tdev_dbg(cell->nvmem, \"buffer size %zu must match cell size %zu\\n\",\n+\t\t\t\tsize, cell->size);\n+\t\t\treturn -EINVAL;\n+\t\t}\n+\t}\n+\n+\tret = nvmem_cell_read_raw(cell, buf, size);\n+\tif (ret < 0)\n+\t\treturn ret;\n+\n+\tif (cell->nbits) {\n+\t\tvalue = le32_to_cpu(*((__le32 *)buf));\n+\t\tvalue >>= cell->bit_offset;\n+\t\tvalue &= GENMASK(cell->nbits - 1, 0);\n+\t\t*(u32 *)buf = value;\n+\t}\n+\n+\treturn 0;\n }\n \n int nvmem_cell_write(struct nvmem_cell *cell, const void *buf, size_t size)\n {\n+\tint ret, bytes_needed;\n+\tu32 current, value, mask;\n+\n \tdev_dbg(cell->nvmem, \"%s: off=%u size=%zu\\n\", __func__, cell->offset, size);\n-\tif (size != cell->size)\n-\t\treturn -EINVAL;\n+\n+\tif (cell->nbits) {\n+\t\tif (size != MAX_NVMEM_CELL_SIZE) {\n+\t\t\tdev_dbg(cell->nvmem, \"bit field requires buffer size %d, got %zu\\n\",\n+\t\t\t\tMAX_NVMEM_CELL_SIZE, size);\n+\t\t\treturn -EINVAL;\n+\t\t}\n+\n+\t\tbytes_needed = DIV_ROUND_UP(cell->nbits + cell->bit_offset, BITS_PER_BYTE);\n+\t\tif (bytes_needed > cell->size || bytes_needed > MAX_NVMEM_CELL_SIZE) {\n+\t\t\tdev_dbg(cell->nvmem, \"bit field requires %d bytes, cell size %zu\\n\",\n+\t\t\t\tbytes_needed, cell->size);\n+\t\t\treturn -EINVAL;\n+\t\t}\n+\n+\t\tret = nvmem_cell_read_raw(cell, ¤t, sizeof(current));\n+\t\tif (ret < 0)\n+\t\t\treturn ret;\n+\n+\t\tcurrent = le32_to_cpu(*((__le32 *)¤t));\n+\t\tvalue = *(const u32 *)buf;\n+\t\tvalue &= GENMASK(cell->nbits - 1, 0);\n+\t\tvalue <<= cell->bit_offset;\n+\n+\t\tmask = GENMASK(cell->nbits - 1, 0) << cell->bit_offset;\n+\n+\t\tcurrent = (current & ~mask) | value;\n+\t\tbuf = ¤t;\n+\t} else {\n+\t\tif (size != cell->size) {\n+\t\t\tdev_dbg(cell->nvmem, \"buffer size %zu must match cell size %zu\\n\",\n+\t\t\t\tsize, cell->size);\n+\t\t\treturn -EINVAL;\n+\t\t}\n+\t}\n \n \tswitch (cell->nvmem->driver->id) {\n \tcase UCLASS_I2C_EEPROM:\n-\t\treturn i2c_eeprom_write(cell->nvmem, cell->offset, buf, size);\n-\tcase UCLASS_MISC: {\n-\t\tint ret = misc_write(cell->nvmem, cell->offset, buf, size);\n-\n+\t\tret = i2c_eeprom_write(cell->nvmem, cell->offset, buf, cell->size);\n+\t\tbreak;\n+\tcase UCLASS_MISC:\n+\t\tret = misc_write(cell->nvmem, cell->offset, buf, cell->size);\n \t\tif (ret < 0)\n \t\t\treturn ret;\n-\t\tif (ret != size)\n+\t\tif (ret != cell->size)\n \t\t\treturn -EIO;\n-\t\treturn 0;\n-\t}\n+\t\tret = 0;\n+\t\tbreak;\n \tcase UCLASS_RTC:\n-\t\treturn dm_rtc_write(cell->nvmem, cell->offset, buf, size);\n+\t\tret = dm_rtc_write(cell->nvmem, cell->offset, buf, cell->size);\n+\t\tbreak;\n \tdefault:\n \t\treturn -ENOSYS;\n \t}\n+\n+\tif (ret)\n+\t\treturn ret;\n+\n+\treturn 0;\n }\n \n /**\n@@ -128,6 +236,20 @@ int nvmem_cell_get_by_index(struct udevice *dev, int index,\n \n \tcell->offset = offset;\n \tcell->size = size;\n+\n+\tret = ofnode_read_u32_index(args.node, \"bits\", 0, &cell->bit_offset);\n+\tif (ret) {\n+\t\tcell->bit_offset = 0;\n+\t\tcell->nbits = 0;\n+\t} else {\n+\t\tret = ofnode_read_u32_index(args.node, \"bits\", 1, &cell->nbits);\n+\t\tif (ret)\n+\t\t\treturn -EINVAL;\n+\n+\t\tif (cell->bit_offset + cell->nbits > cell->size * 8)\n+\t\t\treturn -EINVAL;\n+\t}\n+\n \treturn 0;\n }\n \ndiff --git a/include/nvmem.h b/include/nvmem.h\nindex e6a8a98828b..dd82122f16f 100644\n--- a/include/nvmem.h\n+++ b/include/nvmem.h\n@@ -26,11 +26,15 @@\n * @nvmem: The backing storage device\n * @offset: The offset of the cell from the start of @nvmem\n * @size: The size of the cell, in bytes\n+ * @bit_offset: Bit offset within the cell (0 for byte-level access)\n+ * @nbits: Number of bits to use (0 for byte-level access)\n */\n struct nvmem_cell {\n \tstruct udevice *nvmem;\n \tunsigned int offset;\n \tsize_t size;\n+\tunsigned int bit_offset;\n+\tunsigned int nbits;\n };\n \n struct udevice;\n", "prefixes": [ "v4", "1/7" ] }