From mboxrd@z Thu Jan 1 00:00:00 1970 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 80C46381B0D for ; Wed, 29 Apr 2026 15:43:51 +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=1777477439; cv=none; b=PUvqu5webjsEd7vAp5eAnDVhYWCzwkywlXCCAr++L128/T62E/ojtEvA5eJLcecKn4z1KXA44zYWRtzh6NUlCY12bBdccAVi6ohtaQCGmDLob0PgiflDvh+GUWOAJlYS5hhb3Ehb4wVXFYksufI7bvrMNcLZfyD638s1xs/f4E8= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777477439; c=relaxed/simple; bh=jsug+Y09XZlkvTamN3ahaEVBTj9TqJtY4YU5YQYegn4=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=bC9P5XnCAYm0OlkQ2+BsPVKdo1TscihqRnoDoIqtjs4yMLx9soUS90ooG/6Z1UJEhnjSuxW7u+BDyFDMvaPPMeMnpiNyoJeDYfRlV8evRdiyb43EJKUrkOtNHKzS1hjHO06/WNdOwS8g1vnJEMNEch4RuiAI2JSQYzuDJzi5v/c= 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=WIiDpzDl; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b=JfriCxn6; 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="WIiDpzDl"; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b="JfriCxn6" Received: from pps.filterd (m0279865.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 63TCM1uJ2485210 for ; Wed, 29 Apr 2026 15:43:49 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= u2Stv53JCIIR1m+8FHqA3ncouBn3DLNgZtRvVete0xc=; b=WIiDpzDluTVs4th1 t4QYsmGkMGIKFbt037kvISzYmLw0DmbNRc9zvY0hEj3cCJDYHpGOKlHgxFfF3TXd 45kBat9IcDCbTK3AuWN3s5HdO0XbeVEed90rR7yc8LkzVT4S2E2FbGPu3K7+dDpZ SAHQOpWA/WsZtdC4/IkM6DVMVErq3Yw6JFdU12RUgRPebwKYMvhn1Z2zIeQXShfA qtz9p4Z95ErxddYH5eLh5drTl1VFFlm8beOFS5BiRWP8a3V4P9Qz0DzpR7jjjP34 U2qOxiK4R6EMjB4nglM6iok3fjZTZpi5ATXRXelDyuPXnoWzJ4xafrQDTAH6BU7P so6QgQ== Received: from mail-qt1-f200.google.com (mail-qt1-f200.google.com [209.85.160.200]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 4duhx90qy4-1 (version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NOT) for ; Wed, 29 Apr 2026 15:43:49 +0000 (GMT) Received: by mail-qt1-f200.google.com with SMTP id d75a77b69052e-50d826ed6f9so21470981cf.1 for ; Wed, 29 Apr 2026 08:43:49 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oss.qualcomm.com; s=google; t=1777477428; x=1778082228; 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=u2Stv53JCIIR1m+8FHqA3ncouBn3DLNgZtRvVete0xc=; b=JfriCxn6i7VmV1nGS4JaRscKxTFgEFTvaiNwh4K5mh4/ReCoXoLfCvBsTHi79veaEl B4I0vq3En2ZbB+GoLUElZtttECSsyvj5Sf6a8FEw5wi2tl2kSgVjLAGm/YdRY4evjUoS xPD8xWdDgth8RnidvBiTS9HYo3osGLIop6zGZqwx6VQGCw1Q9YUX9RRaAPAu8rP9sbVF 6NjCvjMtsB7Cq48I2kEtQCH3IaAXE4VBgeYVAjdnohnY8UNZy+6m8U8Cm8Cg9SoohO7M CCI2LxFe8ww7aME2Pht2oMM98rQKTG0J002r44MInTRJ5rcim0oFduI5wx6AGk6pjqj3 W2/Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1777477428; x=1778082228; 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=u2Stv53JCIIR1m+8FHqA3ncouBn3DLNgZtRvVete0xc=; b=nFlBQmXB4hDu9VqhksDyT8VNZuAXaPBa57U89uhj201sluP7dSqSwxzY2vJCHJ9nt1 R4JLhbi+Y1X4tIPuVElNKbpAkWIY6mKtgkouaOD1vrxPAEBD8QN8quTkGt5Jgm2SwTSS 4V2LozYTnm9xXwW0xunRSZKO80fyNemIiTTqybTvWYi/1Ure5S56JS8+b7wTjYbrnwfR qK4kSnoZM/I6p9+0KG5StEcjmjF4v6IX+lKz0iOfOdWxf/mA7T1MyNPves69coWU5zDW X+uHBjN/DB7ilg7SlUIjXq/cQ218MxiYa4DNn4iA5VLtDwmuIOuuiqp05DaPB2nMoMM0 8ReA== X-Gm-Message-State: AOJu0YzBuksWw8VRKBD1acjw1P2ER4ppK+fh281tzg82CI78W3NK0Dpd pX6E083f1vPAgiB9E9ulU39iS5uL6OlppbVkbUIZ4TsDIsm8E3QeEMDa/ojstfvSD4urPn5fCjI kGjqjkh+o6ST3oIFxpdj8JAUl7O0N3NCdUVcrEYaeAzR9Kj2qjMrf03a3fTirF5ICQYc= X-Gm-Gg: AeBDiesZBL4l34pBVmPJ1wdix2HnS2VUHNmbNaxvjbIFYHwTYzlUMr4C0pwsWV701Q+ ES5wftrYl4NcMfP5Srnu5fReqTEFRPxPzT5MWoygVGlPNnSX2eDdl9GpNjLFzLT9gVJ6QUOyinG 5chKSuFGT8DDZsd0T2sbDiHv7KiZJ9jkNW4i/yjWGSQBQXTdVFByLyev8Y9+sycpJQjjNYP3P9I s0FIk/HdBOGhZszOTqs7pamUWL6P1DS2Xqnt92B0p9RHIVKNxjQxiXF1d6/QfIPZ6xfpu1VqwIe 8t4nDcpSeyJmuXkGA702dPEammLIZpgLAsx9x2IchBTC1xwj30BWiMH4giJ7r5EOKZotPwcy5Ns 6BPuaEddgrTgS9BkdrRwwzvLB6hJmko+Z9dLnfNTIA9ZZtdMWNynJ3dODxaz3rw== X-Received: by 2002:a05:622a:15d3:b0:50f:c278:c007 with SMTP id d75a77b69052e-510199fc38emr48826421cf.2.1777477428480; Wed, 29 Apr 2026 08:43:48 -0700 (PDT) X-Received: by 2002:a05:622a:15d3:b0:50f:c278:c007 with SMTP id d75a77b69052e-510199fc38emr48826011cf.2.1777477428016; Wed, 29 Apr 2026 08:43:48 -0700 (PDT) Received: from brgl-qcom.local ([2a01:cb1d:dc:7e00:e9c0:e45a:1dbc:c82a]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-447b3d481b2sm6837552f8f.4.2026.04.29.08.43.46 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 29 Apr 2026 08:43:46 -0700 (PDT) From: Bartosz Golaszewski Date: Wed, 29 Apr 2026 17:43:21 +0200 Subject: [PATCH v3 6/9] nvmem: split out the reg_read/write() callbacks out of struct nvmem_device 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: 7bit Message-Id: <20260429-nvmem-unbind-v3-6-2a694f95395b@oss.qualcomm.com> References: <20260429-nvmem-unbind-v3-0-2a694f95395b@oss.qualcomm.com> In-Reply-To: <20260429-nvmem-unbind-v3-0-2a694f95395b@oss.qualcomm.com> To: Srinivas Kandagatla , Bartosz Golaszewski , Johan Hovold Cc: linux-kernel@vger.kernel.org, brgl@kernel.org, Bartosz Golaszewski X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=5856; i=bartosz.golaszewski@oss.qualcomm.com; h=from:subject:message-id; bh=jsug+Y09XZlkvTamN3ahaEVBTj9TqJtY4YU5YQYegn4=; b=owEBbQKS/ZANAwAKAQWdLsv/NoTDAcsmYgBp8icm3xpKX0Lc3E9snCwMnKBWmCJd0XRYDGnT0 Gp2IDzIyRyJAjMEAAEKAB0WIQSR5RMt5bVGHXuiZfwFnS7L/zaEwwUCafInJgAKCRAFnS7L/zaE w94kD/9e5OSWiWk3camxe8bBhKLb4gZpOL5dctK0bVj/ZsRTosW+/QKGE8kb5H/f1BBo9jV2L6M LIo7lQfTw/rISA2l2Jw80qjYMqbKowhlo1J/3zKGM8FAxU2mSTTa8Rk3Yjh4GJ6CT+07iorWDQR hZOD0GqUDOlLwrMzuKb7gynAkpgW3L/PLpG4z1avSOWbXLi7g05JtUnJJgvGGbWXo+C5Hr55OId N/qDubgyZF8+0X1Ana7dn48D5Zb10CxFyQszjllBbYJvZD0w1zOaXt5fNQx299Pf60l8n3f+/en ELYLJ1r/o9ur7r+8KQLcgFIgeQJ2Nkz/f23JS6lwr/shKUuM//fuFI13RU6FaII7RNdf35lzCfz GiyBtBQLEz4nI/ZRI0HEnkQoquXWgDLwfi0OUAQTYh/7adnhGshOk5334/yLzISua2ExHLXIkcC jC2PMIfnu2KJH+jhVPInv7reuDgo3ZJEzWhwnJUgSg+DOALca4DAVoJ9OxYitqGH2eP6/2i1w/5 CCu4picgJ/1XnIiO7jG0+sQRxP35rF+OyoKPixSD51p9YkfVYuXubmsWWQT0fJD8r2laz422X3T RZwTmnK6sL7wxNGotVsRGTR+yqrPgGJLd8WeRoJuvDWltJc2uqDII4QanxCoKaTD2MMzb+xt+VY oVhDq8vZ4MkcUDA== X-Developer-Key: i=bartosz.golaszewski@oss.qualcomm.com; a=openpgp; fpr=169DEB6C0BC3C46013D2C79F11A72EA01471D772 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNDI5MDE1OCBTYWx0ZWRfXw7p9GfoO/suk FyFWHwl3R0ebGit9DHnyaP9qUmDkVQzGcCgQplIvn8K9PIXW4Nq/sV7P809fnALlEjneU8UWOg+ 8IeGwgw9hSWy870N4wkiLXZD1m7qbHvgiSiHtm9iczi1jFVCSbR1tg9G3dNm4SxQuo/gQK7BB2K /ek6iWue4LWVb2XKep/zJ6a+kYRMqBxXMuStuy8MldrAQYp/e1iaCyOB9viFjQA72ZLff6ZgA5f 0wO6HeGclVoE7zAeGPthnOMBIfedadJgxTfe9Hof0vHPUS0OWiX9lLZvU4otFW8u79oZnWXiZfu G1q2TaJK6HnLuoccN+jwsCCZZFu9RXERdYGi1Ii/lOkabSv5t5B0MnADdhrkhEz1bRXcFsMGQ47 BzJHVcSiEFDzoj0NTckNK6kekTEzMzhXqzVT8Odh6SdLuj8VmgasgC5txZPx5l1MR3oy5w22/iq qbtxXS4G3DHB3clkMfA== X-Proofpoint-ORIG-GUID: R77CVTZLXjLMhQv7YmxSrSv240G0utv3 X-Authority-Analysis: v=2.4 cv=O5oJeh9W c=1 sm=1 tr=0 ts=69f22735 cx=c_pps a=JbAStetqSzwMeJznSMzCyw==:117 a=xqWC_Br6kY4A:10 a=IkcTkHD0fZMA:10 a=A5OVakUREuEA:10 a=s4-Qcg_JpJYA:10 a=VkNPw1HP01LnGYTKEx00:22 a=u7WPNUs3qKkmUXheDGA7:22 a=Um2Pa8k9VHT-vaBCBUpS:22 a=EUspDBNiAAAA:8 a=IQ43IFojRXP4T6AthesA:9 a=QEXdDO2ut3YA:10 a=uxP6HrT_eTzRwkO_Te1X:22 X-Proofpoint-GUID: R77CVTZLXjLMhQv7YmxSrSv240G0utv3 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1143,Hydra:6.1.51,FMLib:17.12.100.49 definitions=2026-04-29_01,2026-04-28_01,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 spamscore=0 clxscore=1015 adultscore=0 phishscore=0 suspectscore=0 impostorscore=0 bulkscore=0 priorityscore=1501 lowpriorityscore=0 malwarescore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2604200000 definitions=main-2604290158 The reg_read/write() fields of struct nvmem_device point to memory owned by the nvmem provider. They must not be dereferenced after the provider is unregistered. Ahead of protecting against accesses to invalid memory with SRCU, move the callbacks into a separate structure the address of which is stored in nvmem_device. Signed-off-by: Bartosz Golaszewski --- drivers/nvmem/core.c | 37 +++++++++++++++++++++++++++---------- drivers/nvmem/internals.h | 9 +++++++-- 2 files changed, 34 insertions(+), 12 deletions(-) diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c index bca2cce793451bb46ede9e672dec6ec20f369fd8..83ef4858939c471daabd4641f9746d92b43daf5d 100644 --- a/drivers/nvmem/core.c +++ b/drivers/nvmem/core.c @@ -57,25 +57,28 @@ static BLOCKING_NOTIFIER_HEAD(nvmem_notifier); static int __nvmem_reg_read(struct nvmem_device *nvmem, unsigned int offset, void *val, size_t bytes) { - if (!nvmem->reg_read) + struct nvmem_operations *ops = nvmem->ops; + + if (!ops->reg_read) return -EOPNOTSUPP; - return nvmem->reg_read(nvmem->priv, offset, val, bytes); + return ops->reg_read(nvmem->priv, offset, val, bytes); } static int __nvmem_reg_write(struct nvmem_device *nvmem, unsigned int offset, void *val, size_t bytes) { + struct nvmem_operations *ops = nvmem->ops; int ret, written; - if (!nvmem->reg_write) + if (!ops->reg_write) return -EOPNOTSUPP; ret = gpiod_set_value_cansleep(nvmem->wp_gpio, 0); if (ret) return ret; - written = nvmem->reg_write(nvmem->priv, offset, val, bytes); + written = ops->reg_write(nvmem->priv, offset, val, bytes); ret = gpiod_set_value_cansleep(nvmem->wp_gpio, 1); if (ret) @@ -280,6 +283,8 @@ static ssize_t bin_attr_nvmem_write(struct file *filp, struct kobject *kobj, static umode_t nvmem_bin_attr_get_umode(struct nvmem_device *nvmem) { + struct nvmem_operations *ops = nvmem->ops; + umode_t mode = 0400; if (!nvmem->root_only) @@ -288,10 +293,10 @@ static umode_t nvmem_bin_attr_get_umode(struct nvmem_device *nvmem) if (!nvmem->read_only) mode |= 0200; - if (!nvmem->reg_write) + if (!ops->reg_write) mode &= ~0200; - if (!nvmem->reg_read) + if (!ops->reg_read) mode &= ~0444; return mode; @@ -322,6 +327,7 @@ static umode_t nvmem_attr_is_visible(struct kobject *kobj, { struct device *dev = kobj_to_dev(kobj); struct nvmem_device *nvmem = to_nvmem_device(dev); + struct nvmem_operations *ops = nvmem->ops; /* * If the device has no .reg_write operation, do not allow @@ -330,7 +336,7 @@ static umode_t nvmem_attr_is_visible(struct kobject *kobj, * can be forced into read-write mode using the 'force_ro' * attribute. */ - if (attr == &dev_attr_force_ro.attr && !nvmem->reg_write) + if (attr == &dev_attr_force_ro.attr && !ops->reg_write) return 0; /* Attribute not visible */ return attr->mode; @@ -531,6 +537,7 @@ static void nvmem_release(struct device *dev) ida_free(&nvmem_ida, nvmem->id); gpiod_put(nvmem->wp_gpio); + kfree(nvmem->ops); kfree(nvmem); } @@ -891,6 +898,7 @@ EXPORT_SYMBOL_GPL(nvmem_layout_unregister); struct nvmem_device *nvmem_register(const struct nvmem_config *config) { + struct nvmem_operations *ops; struct nvmem_device *nvmem; int rval; @@ -904,8 +912,15 @@ struct nvmem_device *nvmem_register(const struct nvmem_config *config) if (!nvmem) return ERR_PTR(-ENOMEM); + ops = kzalloc_obj(*ops); + if (!ops) { + kfree(nvmem); + return ERR_PTR(-ENOMEM); + } + rval = ida_alloc(&nvmem_ida, GFP_KERNEL); if (rval < 0) { + kfree(ops); kfree(nvmem); return ERR_PTR(rval); } @@ -931,6 +946,10 @@ struct nvmem_device *nvmem_register(const struct nvmem_config *config) INIT_LIST_HEAD(&nvmem->cells); nvmem->fixup_dt_cell_info = config->fixup_dt_cell_info; + ops->reg_read = config->reg_read; + ops->reg_write = config->reg_write; + + nvmem->ops = ops; nvmem->owner = config->owner; if (!nvmem->owner && config->dev->driver) nvmem->owner = config->dev->driver->owner; @@ -940,8 +959,6 @@ struct nvmem_device *nvmem_register(const struct nvmem_config *config) nvmem->root_only = config->root_only; nvmem->priv = config->priv; nvmem->type = config->type; - nvmem->reg_read = config->reg_read; - nvmem->reg_write = config->reg_write; nvmem->keepout = config->keepout; nvmem->nkeepout = config->nkeepout; if (config->of_node) @@ -967,7 +984,7 @@ struct nvmem_device *nvmem_register(const struct nvmem_config *config) goto err_put_device; nvmem->read_only = device_property_present(config->dev, "read-only") || - config->read_only || !nvmem->reg_write; + config->read_only || !ops->reg_write; #ifdef CONFIG_NVMEM_SYSFS nvmem->dev.groups = nvmem_dev_groups; diff --git a/drivers/nvmem/internals.h b/drivers/nvmem/internals.h index 7cbc55f40259fc4315c41979ad8bf75c36bcb056..070eef89ffca78fe033aaaada0f91c257fe2f166 100644 --- a/drivers/nvmem/internals.h +++ b/drivers/nvmem/internals.h @@ -7,6 +7,12 @@ #include #include +/* Hold pointers to callbacks owned by the nvmem provider module. */ +struct nvmem_operations { + nvmem_reg_read_t reg_read; + nvmem_reg_write_t reg_write; +}; + struct nvmem_device { struct module *owner; struct device dev; @@ -26,10 +32,9 @@ struct nvmem_device { struct nvmem_cell_info *cell); const struct nvmem_keepout *keepout; unsigned int nkeepout; - nvmem_reg_read_t reg_read; - nvmem_reg_write_t reg_write; struct gpio_desc *wp_gpio; struct nvmem_layout *layout; + struct nvmem_operations *ops; void *priv; bool sysfs_cells_populated; }; -- 2.47.3