From mboxrd@z Thu Jan 1 00:00:00 1970 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 522243E558C for ; Thu, 21 May 2026 14:26:06 +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=1779373567; cv=none; b=u+mQUeUf8AVfxtgNvvsS7v5KKy5RFcWD/nTZuuYmxAwt78yXFzjUIRAY7LwyWhbaGYLGAIcsdS2wlGRStZ08Rv8D+QlUyXshI3mqtBrTn+DljXiiJDBSYbh4fmshd79N7i88GXNu+Lc+faR7Q+G7Mvh+IV3drHG6xOqR++rXAZU= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779373567; c=relaxed/simple; bh=H4VTxzwSRDhkXmVBottIruqP1ZHQ+WtaCvrCsMy96vg=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=NYMPEQ3Cich+OMf/H0BLuCCurbfzCulqXf8jZsh8kI/Rle+YwdbprcA1LA3Brcx3x7DWjL+t1RAEEmjcN5+7ZsH0dJP2Tdhw/VxNoS4UxjSy2GfJjSmYnjHL4l6bSSjy8sf2i4wgaToXwPx0+fMEPwa3KbGQorr6E0qV/KGt+NA= 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=RQHAJ6xO; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b=WS+F8gAR; 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="RQHAJ6xO"; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b="WS+F8gAR" Received: from pps.filterd (m0279873.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 64L99oR03009546 for ; Thu, 21 May 2026 14:26:05 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= 1RJryf+QQ2nHWkSW1Rv1c9yfe/EC2A5M6ANbh5cksho=; b=RQHAJ6xO0vGBkGRE uvR6rr+9JWiU5FQxd6TnFURk05TpVYl7Bj45/i3LlhpELp44ouRdwfjOTzHqMz43 AYdR+aTYNiClwfD6erwLCwQyYrx5bhxOvQfrAjI0e59+nEwXnPfa5ENqdCB29qQf BuzklE55CbiWif4neygznujZnlHrJo6gsiBE7Aeo+9o7W3ZxeFbpdd80AM+aeSLx 9pdg5+dBjLy8A76/MFztw9VqDXhIHE44jVzRPzqW5CczNfgMeDHMAXn44JvqDVxK vHQHbwZ/QC0e6HMIQfhaAqaWLe9EEiCE4OY4L6yMMpBtS0AxFPzgPd3qr5T9YpEH sHZ92Q== Received: from mail-ua1-f69.google.com (mail-ua1-f69.google.com [209.85.222.69]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 4e9sr32n8j-1 (version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NOT) for ; Thu, 21 May 2026 14:26:05 +0000 (GMT) Received: by mail-ua1-f69.google.com with SMTP id a1e0cc1a2514c-95ce6d50ea7so2441342241.1 for ; Thu, 21 May 2026 07:26:05 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oss.qualcomm.com; s=google; t=1779373564; x=1779978364; 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=1RJryf+QQ2nHWkSW1Rv1c9yfe/EC2A5M6ANbh5cksho=; b=WS+F8gAR1xUTsKyC4AKmwwAx0hNK4N6lT0enxwAJSzas7fThjZUxoCbjnWBy8RvYSm nxdgNK2eUBcmmgB/uXj99JwAGxeoY+4CnOPKnWgf52zf+l9WoSipjuq9vVYrz0DfgYYQ k05g8CwW42M3SRfJpLv1x50gi7HiVatQh6TL6UyqmtAZde31T4XNtWacKnTP8b1p2fpm DlTsh0jdk7WHsPfbLSidbNbJGBzWz8UA6fuLUc/OR27jL5K7cIjlJLjrvDS4rWvk3ZiV NM22TWE1iIycgQ1/GvBw81E3msTSfYcvxycwDd5spZ2mnHVVWLKgE0TUYR9YatpUT624 Q3ew== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1779373564; x=1779978364; 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=1RJryf+QQ2nHWkSW1Rv1c9yfe/EC2A5M6ANbh5cksho=; b=BMBwe68jtz3DIL8ITgSxdK9ILH0A0zifY0k39HgaAf/kRcfVuKHMDa4tA4q3bjiUAR KxTE+x33GwKkW7EvpsKvUwj2C9EPqv6KdUaIcgoQiBGffzuAoWQYa+Gw+Ay59IF1ZAYo v+obH2Yq+Bvv7eS0Um+vR3o69VfActeDN5eX6tX1DaWzy8G1RYH5++tHXmsV9RYZV4RU KFWQJ5fn0DEmK/jn4pOPn67MaH3fIXDJppFND8R7n6S5YhXdE+Q3D17DR5EJHK8fvhBa 3RC5n7xL9W1OuxdZKO9EmKatUtqmN5HSPbKgderjRIHu1Jvmpv4W3NkrIvWz0bQhdY/S FjwA== X-Gm-Message-State: AOJu0YwYP74hlp/5TcubVZw28KD5eHbYQuaZt/WHtNf7dT4h7Rb/N+9w w2JpHnvueZ2RdV1N4sxpz2v/1s/PLDCAqKQ86plXrIclU/2JkHQwTuRrWMPSlyKSQ8txTMltK0p PBHGkwEI2HeEfQykrzotrdK+b+MlrC6d8Iaw7SZ+I53YOXxYrIy6Rfblnkceeb7ehVy0= X-Gm-Gg: Acq92OHi6W49uIx5gn29xltyPQXtr4f2tyvgLx6dpLpJ2Tmj5ZnQHv6BnloPXibbtJ2 tkXhaYP9qJC2Co+GchDnYcL87WTkaJK8V4rtdYthDEFyeH1BhnwbHaLMvBDNwKR+yy8r2HR2Kz7 aXdSydHHnYgmxMHrM8PV4lSt+cOc9NPOAR95rDBBMm7S8NzUR4jPmxLdQ59KcvUDMWwRjg4tIW/ MymKq6cryJ/v1e4DLt+7QuZWZf9qdphL846TAHVJmC2W/H8SkNFhQcwHAoBOtNzrn7gRz6J/ele 0mqHR4W8SIFz2SmPuSnFbUny8LjT6rxxnvuuN5eJTHfikB70jlmDX0VFdVGJ3kE7n3CyrDWDiby YSBhpzi9h9OyVEZbWVAFPE1e4FVniWSwYsPmdeqmHf4GDzQcsBDI= X-Received: by 2002:a05:6102:5708:b0:62f:4387:fcb4 with SMTP id ada2fe7eead31-6737bf05370mr2075989137.0.1779373564373; Thu, 21 May 2026 07:26:04 -0700 (PDT) X-Received: by 2002:a05:6102:5708:b0:62f:4387:fcb4 with SMTP id ada2fe7eead31-6737bf05370mr2075933137.0.1779373563922; Thu, 21 May 2026 07:26:03 -0700 (PDT) Received: from brgl-qcom.local ([2a01:cb1d:dc:7e00:bb10:ae82:b7c3:d15a]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-4903c9abbadsm30441925e9.8.2026.05.21.07.26.02 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 21 May 2026 07:26:03 -0700 (PDT) From: Bartosz Golaszewski Date: Thu, 21 May 2026 16:25:40 +0200 Subject: [PATCH v4 07/10] 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: <20260521-nvmem-unbind-v4-7-7fa136759491@oss.qualcomm.com> References: <20260521-nvmem-unbind-v4-0-7fa136759491@oss.qualcomm.com> In-Reply-To: <20260521-nvmem-unbind-v4-0-7fa136759491@oss.qualcomm.com> To: Srinivas Kandagatla , Bartosz Golaszewski , Johan Hovold , Loic Poulain 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=6098; i=bartosz.golaszewski@oss.qualcomm.com; h=from:subject:message-id; bh=H4VTxzwSRDhkXmVBottIruqP1ZHQ+WtaCvrCsMy96vg=; b=owEBbQKS/ZANAwAKAQWdLsv/NoTDAcsmYgBqDxXryjDO6S4xFqu7taQUTpSvMBR34GFbgcZMk Jwh5RpvgIGJAjMEAAEKAB0WIQSR5RMt5bVGHXuiZfwFnS7L/zaEwwUCag8V6wAKCRAFnS7L/zaE w2iYD/wPhBHboBsC7QOdQIAnpAVqvtE2zsy2uPII8IC4hQnd81Vilgm0E0VyDoP8zKCBE0f3MPA xJ0W20mI2pH7jNsW45VuAkbwZYiDlZfpwoOg/9qbwoIxnKRQFUtHsgHvGPTQoe0Ls5pRUffU8Ul +RYYNzYc02zd9bCcXqUGs1nisFk6jOAbjbC7hsUW/mv9bU/gsxvJgJDwth4vvJ7ltQjEXSF1y6K QrRvBGl+ZiF+nv963jHAG0v1ITRPT4fa85FZX3PTAzjXjlqkqNZQH5Flj9MKf1nXIR6CRR57g0n nnYKglA1RFEf4s8VGfqiZtKXZuoIJoV/XCpUo+xzZbmHlCM5zYrBuN+unpAAX8W6CSI1tOowkYb gr7k9Jpmj33EaalgF6m4U2bsaiXkSZ9DEv+tr5/6N+Fly7lK0g1l4DwZj9DNOMUy2qMiNhw8a8b cEztkgW+JJDWzGr12R2AjPU88KvF1rrcGyl1Eve4eLuqLElaoMOS6Im+toAaWnKY0w+bCX/V9oO NAcPAi3g5eHiOCPc4SOE8ibV/w+1iL/IWla8u7CNqPUOmd6bT4fTsJAk/90CXe8ihNAb4OFh7Ra 2052mXZmU7NJR7VlIx9l6jIafKleHJn5jTbr3sLebO/9sxOQHMhiBKXZxxsNMjJZ36RXIUVPlpg z/wwYCLXlMsO3+A== X-Developer-Key: i=bartosz.golaszewski@oss.qualcomm.com; a=openpgp; fpr=169DEB6C0BC3C46013D2C79F11A72EA01471D772 X-Proofpoint-GUID: _vk7MRKm4YpfiIatHdQ7kN84BZcZjEFA X-Proofpoint-ORIG-GUID: _vk7MRKm4YpfiIatHdQ7kN84BZcZjEFA X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNTIxMDE0NCBTYWx0ZWRfX3+KPrjB7q/ZE RAg/quyyt+X7rWvd6mRpoH8X3e52hLfsRRhK3be3Udh7vE8hpKe8woSAcN78zrJb09Q57nydsTA sDBjnol6ZAn3tCnduv6lol4hxXZzvFVwAMqRnhgIKgl3s62dI7X1sl+qQ6SFIHmKpm1vX+yJRlY o1SC/D5FpI4Mb0x3XxEvEsu053nK6C6/fnAjuJgs1yG0AhvksKv0DrXUu8JKkU1hF2+HA74skb7 b9KiY0bpnfn1M5GOKl8w8AGGvOQr93NzsHJ4HlN3rJrLGOlml0vSaRilt2bJwp4d7bXyM8HOZjM 9L4gIU+wXF8E7BEWzdec9YfNP0jxxen97bJIWs59hHIxoZ2HJT9Iyk82SnpYAnHz/aXYqNjuZYg WvZyOCie+xhcxwpxu4rLvUfhxl+WCDpjLfqKjMLeP0J13x90h9kE+LdzF8w5K/CHUozl/NX2ztE z3cQt5dj3F+RBQmz3Fg== X-Authority-Analysis: v=2.4 cv=L+YtheT8 c=1 sm=1 tr=0 ts=6a0f15fd cx=c_pps a=UbhLPJ621ZpgOD2l3yZY1w==:117 a=xqWC_Br6kY4A:10 a=IkcTkHD0fZMA:10 a=NGcC8JguVDcA:10 a=s4-Qcg_JpJYA:10 a=VkNPw1HP01LnGYTKEx00:22 a=u7WPNUs3qKkmUXheDGA7:22 a=rJkE3RaqiGZ5pbrm-msn:22 a=EUspDBNiAAAA:8 a=IQ43IFojRXP4T6AthesA:9 a=QEXdDO2ut3YA:10 a=TOPH6uDL9cOC6tEoww4z:22 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-05-21_02,2026-05-18_01,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 spamscore=0 suspectscore=0 priorityscore=1501 malwarescore=0 bulkscore=0 lowpriorityscore=0 phishscore=0 clxscore=1015 adultscore=0 impostorscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2605130000 definitions=main-2605210144 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 24e079240ebbb0899d6d91f8147210a64d4414cb..b6429aae99e0deef502b1929debc47a09986925d 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, wr_ok; - if (!nvmem->reg_write) + if (!ops->reg_write) return -EOPNOTSUPP; ret = gpiod_set_value_cansleep(nvmem->wp_gpio, 0); if (ret) return ret; - wr_ok = nvmem->reg_write(nvmem->priv, offset, val, bytes); + wr_ok = ops->reg_write(nvmem->priv, offset, val, bytes); ret = gpiod_set_value_cansleep(nvmem->wp_gpio, 1); if (ret) @@ -286,6 +289,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) @@ -294,10 +299,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; @@ -328,6 +333,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 @@ -336,7 +342,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; @@ -537,6 +543,7 @@ static void nvmem_release(struct device *dev) ida_free(&nvmem_ida, nvmem->id); gpiod_put(nvmem->wp_gpio); + kfree(nvmem->ops); kfree(nvmem); } @@ -897,6 +904,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; @@ -910,8 +918,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); } @@ -921,6 +936,7 @@ struct nvmem_device *nvmem_register(const struct nvmem_config *config) nvmem->dev.type = &nvmem_provider_type; nvmem->dev.bus = &nvmem_bus_type; nvmem->dev.parent = config->dev; + nvmem->ops = ops; device_initialize(&nvmem->dev); @@ -937,6 +953,9 @@ 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->owner = config->owner; if (!nvmem->owner && config->dev->driver) nvmem->owner = config->dev->driver->owner; @@ -946,8 +965,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) @@ -973,7 +990,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