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 A269544D00E for ; Tue, 28 Apr 2026 14:23:22 +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=1777386205; cv=none; b=IceEZ6MEEFUeZXzAusGcUCUAb+Rv7BrEmTGus/lat0ig5Zs97LSyl+42PHobzYhKZ3ylpVFl2BGa8Xs0eTwnD41jQo2/wilIuzRHuZTPtjQsxhbJoPVKvALo8cW3JJ67lnIbGbI4vIXhnsnbCHQSKS5wc4A50ITzagBEsOYF438= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777386205; c=relaxed/simple; bh=lN5UQLAw786XNpBVzweElxIfw6eaZ0HrStvnhyBZ5No=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=llkF1ig9OmO01ty8bHj+I1tr/ZTObcjLPpKzlx/OjdPEi526WA+oFpuSdBSkSwXpfo1ZAkyRAv7y/iKRkcZpG6i7TYNUZ6nAk1gp76R2wulM+hMJyU+yAFceyxsmn51UnVL4/5jiO5bMDqVeZL2GMo0oZlrGpLHjBzsdhhrrsuY= 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=b1SqOvwx; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b=gTcMsmYT; 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="b1SqOvwx"; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b="gTcMsmYT" Received: from pps.filterd (m0279871.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 63SACMYv2928881 for ; Tue, 28 Apr 2026 14:23:21 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= Wfgrsp3+OXcemYYLvo9SkPw2QHC3Nuf+HBxk2NFolPw=; b=b1SqOvwxePq20lsa leNNsisiDEHCvr4Yyygj/28n9cMo3mjjjiOsw0r/GuEHg2L2RDbdhrI1a92eKHJ6 4+r2Fw/O47qGZy33jZ7WwA/3VF8gto6MSn3uyP6ScvCZ2FlhfuJnccjToE8EyLaT M8q+KP9+kjv80xsdnMVQC4d3X1Wuq8BkDY5r04Z7ruIAgCuLGlgbK73cWq/h5ak9 nEg/ezjKhI3XbUZ1zzcD9t//Ejsqb/0LAkCtv8mBe43lNY2McRws/gSWIzcoyEJl X87uFQV2bBH8gdevOHCKddTRDLBk6WcJSQ63vny4PJhCrCKmfs5efc0B7HXASypL wkQjBQ== Received: from mail-vk1-f200.google.com (mail-vk1-f200.google.com [209.85.221.200]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 4dttxh8wrm-1 (version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NOT) for ; Tue, 28 Apr 2026 14:23:21 +0000 (GMT) Received: by mail-vk1-f200.google.com with SMTP id 71dfb90a1353d-56f6c90b142so18108445e0c.0 for ; Tue, 28 Apr 2026 07:23:21 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oss.qualcomm.com; s=google; t=1777386199; x=1777990999; 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=Wfgrsp3+OXcemYYLvo9SkPw2QHC3Nuf+HBxk2NFolPw=; b=gTcMsmYTXzIdSnVrxo5mKFcXnuBbYNLh1kIdlmVybNZp5WVLkg0my1pt3cR6/Gdhwh eM3EqtCgJSlxEbd3+n0roILXQBc5ojfYDXVA4O1CJDc7opiPSC1NHxQV/YxPoHqE51ZJ LLXGZimk14DPitsgwbSV1rSzzgO0ARmJI2ce7YgOLOinYNcGqirWW9sqUd+5FlewON8d oroWRNfv/IRjUuS8wKMZ7YEh/n4lnpLIEniC1lqpp1xW2+eQ/UcqOO0dTP00+gcPGJPt qMvW0+5AKJCKEPDsDeF+zqGAJALugMD3qkfal1210768I3PQbfAZfhe0xIoE5Ggk+Aww kXdQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1777386199; x=1777990999; 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=Wfgrsp3+OXcemYYLvo9SkPw2QHC3Nuf+HBxk2NFolPw=; b=CDdGzVSY/LYSJCDn/8sHvVx++0sOeoN4cAzJHPpA7Gby71rEu+LHUXjgysJS/jr/Km diBiuk7giAK291LgiS6bvJoFE29f6C7widxbXODZixnjbaQwloJ8ijfnhEmQm2XnJWLM zu3Ee9t5DdilJ5NiA4G8Ml/8r17LPZnTwSebwD3ANx5eCcvKZe2L44DCqYUyhxCBgFbS NjPvd/pdlAOvqes2dbQ3YZGTRsyyLAo21HBKCeDcXuZxLXl4YgIgbSlpLRBuD/Cl4u0d 69k9RzCBOtWkyK7Oo2Rxp1CDgnqtV1vfRKg1aosL4vHfNlz113AUWxAWDBQxAnLmqezb SfQA== X-Forwarded-Encrypted: i=1; AFNElJ8rYXrSJHjE96lisyOUodmcJIXWMkea82zMO5n5739wQ15L2WDDSZ75KeIN0iEjTqPoMaADSFJErrH2/xG44g==@vger.kernel.org X-Gm-Message-State: AOJu0Yx42xIylTruauc5eaFcZ2QLNZMbwgSrRfEZy9D9JJ8qgMAYUo9b Ua8BuvAN6EOGOmAkqVsro2p90fOgvGRfRLSl3Fe3UYYqlTSZp7zMd4ka8XBA3AFUqnLOKvNTQc8 oduXzijXrEgned13QwQ8nb/TeBWoGmWC0e68t3sTHX8dEpCxkMECmcg7qILGKKNj5QWH/NA== X-Gm-Gg: AeBDietcYu83iLOMvoptIgwI/yUAS0/XPrS3xidCh0InOFHo6SP6F4Be781xUU0ID22 DvWMdTikIpSnIdwnf2KDpyWgtVPcoyegBRtM0mzhpUDG09mgu5yCp9KnJy+Od6l3Yc6cuzyoMRN r0R2YdDpZT3mzbWOnifeGuZQc1yjbf5unQmiNdvL9xCZc08Jm2Ygwav/Bfimzah3FWXUwTzAFCc 6ku6//bsF4j07LyW10Rq7qW2smAgzmSpkWHiIu5QYb9ucBa+shOM7KbqEHpanjooOmRNQ1AFD3R TOELtk8qGaQx1hiivaY4Azn3AVMb837v10Z9602fqgLdSTZhdPMtMfk33J8c4jeylduiNaBtoDm Rgz5xJOoqXQqEyECP2R5YEJrFG+bzpT4L2aEFhvaahU4yoo8k5L5d66Tc6ETZHit0zHfHWShZ1u kb0vuQR2ZCF/1mNphpBJEd435MRQ0= X-Received: by 2002:a05:6122:4201:b0:56c:860b:c34e with SMTP id 71dfb90a1353d-573a55b83fcmr1685529e0c.8.1777386198270; Tue, 28 Apr 2026 07:23:18 -0700 (PDT) X-Received: by 2002:a05:6122:4201:b0:56c:860b:c34e with SMTP id 71dfb90a1353d-573a55b83fcmr1685459e0c.8.1777386197727; Tue, 28 Apr 2026 07:23:17 -0700 (PDT) Received: from QCOM-eG0v1AUPpu.na.qualcomm.com ([2a01:e0a:830:450:653f:4d28:6a78:a6ca]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-bb80ba9b8c8sm107072666b.48.2026.04.28.07.23.15 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 28 Apr 2026 07:23:16 -0700 (PDT) From: Loic Poulain Date: Tue, 28 Apr 2026 16:23:08 +0200 Subject: [PATCH 3/9] block: implement NVMEM provider Precedence: bulk X-Mailing-List: linux-wireless@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: <20260428-block-as-nvmem-v1-3-6ad23e75190a@oss.qualcomm.com> References: <20260428-block-as-nvmem-v1-0-6ad23e75190a@oss.qualcomm.com> In-Reply-To: <20260428-block-as-nvmem-v1-0-6ad23e75190a@oss.qualcomm.com> To: Ulf Hansson , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Bjorn Andersson , Konrad Dybcio , Jens Axboe , Johannes Berg , Jeff Johnson , Bartosz Golaszewski , Marcel Holtmann , Luiz Augusto von Dentz , Balakrishna Godavarthi , Rocky Liao , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Simon Horman Cc: linux-mmc@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-msm@vger.kernel.org, linux-block@vger.kernel.org, linux-wireless@vger.kernel.org, ath10k@lists.infradead.org, linux-bluetooth@vger.kernel.org, netdev@vger.kernel.org, daniel@makrotopia.org, Loic Poulain X-Mailer: b4 0.14.2 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNDI4MDEzNiBTYWx0ZWRfX5nqW5Y/m6SpC df3F64nXDphLI97K8qUL7Hdv/7JTeMbtyfDvKVS9US2sJck+3T14TOX9pQMfDHczuZ8ZK1wn4d9 CKrjJ1+U/IvYQt+OD7jN29feOjYyKGXGABoYvz8oULgysKXJpSm4Ieral8fANh9KoaNPT7zH8gh Ilhrd1tQOa9Jm1qXZ+kJxSwPh2kGqyhNxnwoQHue+sfREuzVx4kYxy8FTU2qADl30syrysqVk+m yjpkQN6OPwzq6N+pgOvvONVPVlGleptMlkiR7clcf8bTxWVo1wY2c4CUU3SMFftZ2h6ckjI3P45 j3ttnWkasv3wz6Z8LMjhkdwbDJH/kWWY7ko0l4cpKeZZVDUiukq6f9E3uYlqEq8KbD81o5/C5qe 4C86AYkKxK8ElqgxDsq3qflUitY5uFW1FjPzPaUg0c2CkRHdjlpedG+9tYuJH1xEP6Q2N6CvDwr 7mthiB5Un15WMhYmREQ== X-Authority-Analysis: v=2.4 cv=Uu5T8ewB c=1 sm=1 tr=0 ts=69f0c2d9 cx=c_pps a=wuOIiItHwq1biOnFUQQHKA==:117 a=xqWC_Br6kY4A:10 a=IkcTkHD0fZMA:10 a=A5OVakUREuEA:10 a=s4-Qcg_JpJYA:10 a=VkNPw1HP01LnGYTKEx00:22 a=u7WPNUs3qKkmUXheDGA7:22 a=3WHJM1ZQz_JShphwDgj5:22 a=VT4XjZGOAAAA:8 a=EUspDBNiAAAA:8 a=0xOXAJtWE3glxeOP_3AA:9 a=QEXdDO2ut3YA:10 a=XD7yVLdPMpWraOa8Un9W:22 a=6CpsfURP9XNmmWg3j1mJ:22 X-Proofpoint-ORIG-GUID: KN1m02D8qD4qrcfLWK1pvfm3VFBSCaVt X-Proofpoint-GUID: KN1m02D8qD4qrcfLWK1pvfm3VFBSCaVt 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-28_04,2026-04-28_01,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 malwarescore=0 spamscore=0 phishscore=0 adultscore=0 clxscore=1015 suspectscore=0 impostorscore=0 bulkscore=0 priorityscore=1501 lowpriorityscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2604200000 definitions=main-2604280136 From: Daniel Golle On embedded devices using an eMMC it is common that one or more partitions on the eMMC are used to store MAC addresses and Wi-Fi calibration EEPROM data. Allow referencing the partition in device tree for the kernel and Wi-Fi drivers accessing it via the NVMEM layer. Signed-off-by: Daniel Golle Signed-off-by: Loic Poulain --- block/Kconfig | 9 +++ block/Makefile | 1 + block/blk-nvmem.c | 164 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 174 insertions(+) diff --git a/block/Kconfig b/block/Kconfig index 15027963472d7b40e27b9097a5993c457b5b3054..0b33747e16dc33473683706f75c92bdf8b648f7c 100644 --- a/block/Kconfig +++ b/block/Kconfig @@ -209,6 +209,15 @@ config BLK_INLINE_ENCRYPTION_FALLBACK by falling back to the kernel crypto API when inline encryption hardware is not present. +config BLK_NVMEM + bool "Block device NVMEM provider" + depends on OF + depends on NVMEM + help + Allow block devices (or partitions) to act as NVMEM providers, + typically used with eMMC to store MAC addresses or Wi-Fi + calibration data on embedded devices. + source "block/partitions/Kconfig" config BLK_PM diff --git a/block/Makefile b/block/Makefile index 7dce2e44276c4274c11a0a61121c83d9c43d6e0c..d7ac389e71902bc091a8800ea266190a43b3e63d 100644 --- a/block/Makefile +++ b/block/Makefile @@ -36,3 +36,4 @@ obj-$(CONFIG_BLK_INLINE_ENCRYPTION) += blk-crypto.o blk-crypto-profile.o \ blk-crypto-sysfs.o obj-$(CONFIG_BLK_INLINE_ENCRYPTION_FALLBACK) += blk-crypto-fallback.o obj-$(CONFIG_BLOCK_HOLDER_DEPRECATED) += holder.o +obj-$(CONFIG_BLK_NVMEM) += blk-nvmem.o diff --git a/block/blk-nvmem.c b/block/blk-nvmem.c new file mode 100644 index 0000000000000000000000000000000000000000..01b67c638a6dfd1393043024b6a7f3ebb947a57c --- /dev/null +++ b/block/blk-nvmem.c @@ -0,0 +1,164 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * block device NVMEM provider + * + * Copyright (c) 2024 Daniel Golle + * + * Useful on devices using a partition on an eMMC for MAC addresses or + * Wi-Fi calibration EEPROM data. + */ + +#include "blk.h" +#include +#include +#include +#include + +/* List of all NVMEM devices */ +static LIST_HEAD(nvmem_devices); +static DEFINE_MUTEX(devices_mutex); + +struct blk_nvmem { + struct nvmem_device *nvmem; + struct device *dev; + struct list_head list; +}; + +static int blk_nvmem_reg_read(void *priv, unsigned int from, + void *val, size_t bytes) +{ + blk_mode_t mode = BLK_OPEN_READ | BLK_OPEN_RESTRICT_WRITES; + unsigned long offs = from & ~PAGE_MASK, to_read; + pgoff_t f_index = from >> PAGE_SHIFT; + struct blk_nvmem *bnv = priv; + size_t bytes_left = bytes; + struct file *bdev_file; + struct folio *folio; + void *p; + int ret = 0; + + bdev_file = bdev_file_open_by_dev(bnv->dev->devt, mode, priv, NULL); + if (!bdev_file) + return -ENODEV; + + if (IS_ERR(bdev_file)) + return PTR_ERR(bdev_file); + + while (bytes_left) { + folio = read_mapping_folio(bdev_file->f_mapping, f_index++, NULL); + if (IS_ERR(folio)) { + ret = PTR_ERR(folio); + goto err_release_bdev; + } + to_read = min_t(unsigned long, bytes_left, PAGE_SIZE - offs); + p = folio_address(folio) + offset_in_folio(folio, offs); + memcpy(val, p, to_read); + offs = 0; + bytes_left -= to_read; + val += to_read; + folio_put(folio); + } + +err_release_bdev: + fput(bdev_file); + + return ret; +} + +static int blk_nvmem_register(struct device *dev) +{ + struct device_node *np = dev_of_node(dev); + struct block_device *bdev = dev_to_bdev(dev); + struct nvmem_config config = {}; + struct blk_nvmem *bnv; + + /* skip devices which do not have a device tree node */ + if (!np) + return 0; + + /* skip devices without an nvmem layout defined */ + if (!of_get_child_by_name(np, "nvmem-layout")) + return 0; + + /* + * skip block device too large to be represented as NVMEM devices + * which are using an 'int' as address + */ + if (bdev_nr_bytes(bdev) > INT_MAX) + return -EFBIG; + + bnv = kzalloc_obj(*bnv); + if (!bnv) + return -ENOMEM; + + config.id = NVMEM_DEVID_NONE; + config.dev = &bdev->bd_device; + config.name = dev_name(&bdev->bd_device); + config.owner = THIS_MODULE; + config.priv = bnv; + config.reg_read = blk_nvmem_reg_read; + config.size = bdev_nr_bytes(bdev); + config.word_size = 1; + config.stride = 1; + config.read_only = true; + config.root_only = true; + config.ignore_wp = true; + config.of_node = to_of_node(dev->fwnode); + + bnv->dev = &bdev->bd_device; + bnv->nvmem = nvmem_register(&config); + if (IS_ERR(bnv->nvmem)) { + dev_err_probe(&bdev->bd_device, PTR_ERR(bnv->nvmem), + "Failed to register NVMEM device\n"); + + kfree(bnv); + return PTR_ERR(bnv->nvmem); + } + + mutex_lock(&devices_mutex); + list_add_tail(&bnv->list, &nvmem_devices); + mutex_unlock(&devices_mutex); + + return 0; +} + +static void blk_nvmem_unregister(struct device *dev) +{ + struct blk_nvmem *bnv_c, *bnv = NULL; + + mutex_lock(&devices_mutex); + list_for_each_entry(bnv_c, &nvmem_devices, list) { + if (bnv_c->dev == dev) { + bnv = bnv_c; + break; + } + } + + if (!bnv) { + mutex_unlock(&devices_mutex); + return; + } + + list_del(&bnv->list); + mutex_unlock(&devices_mutex); + nvmem_unregister(bnv->nvmem); + kfree(bnv); +} + +static struct class_interface blk_nvmem_bus_interface __refdata = { + .class = &block_class, + .add_dev = &blk_nvmem_register, + .remove_dev = &blk_nvmem_unregister, +}; + +static int __init blk_nvmem_init(void) +{ + int ret; + + ret = class_interface_register(&blk_nvmem_bus_interface); + if (ret) + return ret; + + return 0; +} +device_initcall(blk_nvmem_init); -- 2.34.1