From patchwork Wed Jul 19 22:02:23 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Daniel Golle X-Patchwork-Id: 704519 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id CCC54C0015E for ; Wed, 19 Jul 2023 22:03:11 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229512AbjGSWDK (ORCPT ); Wed, 19 Jul 2023 18:03:10 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:42744 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229503AbjGSWDK (ORCPT ); Wed, 19 Jul 2023 18:03:10 -0400 Received: from pidgin.makrotopia.org (pidgin.makrotopia.org [185.142.180.65]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A9B801FF6; Wed, 19 Jul 2023 15:03:07 -0700 (PDT) Received: from local by pidgin.makrotopia.org with esmtpsa (TLS1.3:TLS_AES_256_GCM_SHA384:256) (Exim 4.96) (envelope-from ) id 1qMFFf-0008JI-1v; Wed, 19 Jul 2023 22:02:31 +0000 Date: Wed, 19 Jul 2023 23:02:23 +0100 From: Daniel Golle To: Jens Axboe , Ulf Hansson , Miquel Raynal , Richard Weinberger , Vignesh Raghavendra , Dave Chinner , Matthew Wilcox , Thomas =?iso-8859-1?q?Wei=DFschuh?= , Jan Kara , Daniel Golle , Damien Le Moal , Ming Lei , Min Li , Christian Loehle , Adrian Hunter , Hannes Reinecke , Jack Wang , Florian Fainelli , Yeqi Fu , Avri Altman , Hans de Goede , Ye Bin , Greg Kroah-Hartman , =?utf-8?b?UmFmYcWCIE1pxYJl?= =?utf-8?b?Y2tp?= , linux-block@vger.kernel.org, linux-kernel@vger.kernel.org, linux-mmc@vger.kernel.org, linux-mtd@lists.infradead.org Subject: [RFC PATCH 1/6] mmc: core: set card fwnode_handle Message-ID: <42b56531a91e88eea8f57d6be0b01124e67c5232.1689802933.git.daniel@makrotopia.org> References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: Precedence: bulk List-ID: X-Mailing-List: linux-mmc@vger.kernel.org Instead of just populating dev.of_node, also set fwnode in case it isn't set yet and of_node is present. Signed-off-by: Daniel Golle --- drivers/mmc/core/bus.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/mmc/core/bus.c b/drivers/mmc/core/bus.c index 2c3074a605fc4..ecf6e23e4c307 100644 --- a/drivers/mmc/core/bus.c +++ b/drivers/mmc/core/bus.c @@ -361,6 +361,8 @@ int mmc_add_card(struct mmc_card *card) mmc_add_card_debugfs(card); card->dev.of_node = mmc_of_find_child_device(card->host, 0); + if (card->dev.of_node && !card->dev.fwnode) + card->dev.fwnode = &card->dev.of_node->fwnode; device_enable_async_suspend(&card->dev); From patchwork Wed Jul 19 22:02:45 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Daniel Golle X-Patchwork-Id: 705135 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 8C84EC001DF for ; Wed, 19 Jul 2023 22:03:28 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230127AbjGSWD1 (ORCPT ); Wed, 19 Jul 2023 18:03:27 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:42852 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230211AbjGSWDY (ORCPT ); Wed, 19 Jul 2023 18:03:24 -0400 Received: from pidgin.makrotopia.org (pidgin.makrotopia.org [185.142.180.65]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 88BDA2122; Wed, 19 Jul 2023 15:03:19 -0700 (PDT) Received: from local by pidgin.makrotopia.org with esmtpsa (TLS1.3:TLS_AES_256_GCM_SHA384:256) (Exim 4.96) (envelope-from ) id 1qMFG1-0008Ji-2q; Wed, 19 Jul 2023 22:02:53 +0000 Date: Wed, 19 Jul 2023 23:02:45 +0100 From: Daniel Golle To: Jens Axboe , Ulf Hansson , Miquel Raynal , Richard Weinberger , Vignesh Raghavendra , Dave Chinner , Matthew Wilcox , Thomas =?iso-8859-1?q?Wei=DFschuh?= , Jan Kara , Daniel Golle , Damien Le Moal , Ming Lei , Min Li , Christian Loehle , Adrian Hunter , Hannes Reinecke , Jack Wang , Florian Fainelli , Yeqi Fu , Avri Altman , Hans de Goede , Ye Bin , Greg Kroah-Hartman , =?utf-8?b?UmFmYcWCIE1pxYJl?= =?utf-8?b?Y2tp?= , linux-block@vger.kernel.org, linux-kernel@vger.kernel.org, linux-mmc@vger.kernel.org, linux-mtd@lists.infradead.org Subject: [RFC PATCH 2/6] mmc: block: set fwnode of disk devices Message-ID: <1ce5f56df546cec25ef741f381286f1d7c33d000.1689802933.git.daniel@makrotopia.org> References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: Precedence: bulk List-ID: X-Mailing-List: linux-mmc@vger.kernel.org Set fwnode of disk devices to 'block', 'boot0' and 'boot1' subnodes of the mmc-card. This is done in preparation for having the eMMC act as NVMEM provider. Signed-off-by: Daniel Golle --- drivers/mmc/core/block.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/mmc/core/block.c b/drivers/mmc/core/block.c index f701efb1fa785..fc1a9f31bd253 100644 --- a/drivers/mmc/core/block.c +++ b/drivers/mmc/core/block.c @@ -2413,6 +2413,8 @@ static struct mmc_blk_data *mmc_blk_alloc_req(struct mmc_card *card, int area_type, unsigned int part_type) { + struct fwnode_handle *fwnode; + struct device *ddev; struct mmc_blk_data *md; int devidx, ret; char cap_str[10]; @@ -2509,6 +2511,12 @@ static struct mmc_blk_data *mmc_blk_alloc_req(struct mmc_card *card, blk_queue_write_cache(md->queue.queue, cache_enabled, fua_enabled); + ddev = disk_to_dev(md->disk); + fwnode = device_get_named_child_node(subname ? md->parent->parent : + md->parent, + subname ? subname : "block"); + ddev->fwnode = fwnode; + string_get_size((u64)size, 512, STRING_UNITS_2, cap_str, sizeof(cap_str)); pr_info("%s: %s %s %s%s\n", From patchwork Wed Jul 19 22:03:05 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Daniel Golle X-Patchwork-Id: 704518 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 87295C0015E for ; Wed, 19 Jul 2023 22:03:47 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230107AbjGSWDq (ORCPT ); Wed, 19 Jul 2023 18:03:46 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43530 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229574AbjGSWDp (ORCPT ); Wed, 19 Jul 2023 18:03:45 -0400 Received: from pidgin.makrotopia.org (pidgin.makrotopia.org [185.142.180.65]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id DDBB2213D; Wed, 19 Jul 2023 15:03:29 -0700 (PDT) Received: from local by pidgin.makrotopia.org with esmtpsa (TLS1.3:TLS_AES_256_GCM_SHA384:256) (Exim 4.96) (envelope-from ) id 1qMFGL-0008Kc-1x; Wed, 19 Jul 2023 22:03:13 +0000 Date: Wed, 19 Jul 2023 23:03:05 +0100 From: Daniel Golle To: Jens Axboe , Ulf Hansson , Miquel Raynal , Richard Weinberger , Vignesh Raghavendra , Dave Chinner , Matthew Wilcox , Thomas =?iso-8859-1?q?Wei=DFschuh?= , Jan Kara , Daniel Golle , Damien Le Moal , Ming Lei , Min Li , Christian Loehle , Adrian Hunter , Hannes Reinecke , Jack Wang , Florian Fainelli , Yeqi Fu , Avri Altman , Hans de Goede , Ye Bin , Greg Kroah-Hartman , =?utf-8?b?UmFmYcWCIE1pxYJl?= =?utf-8?b?Y2tp?= , linux-block@vger.kernel.org, linux-kernel@vger.kernel.org, linux-mmc@vger.kernel.org, linux-mtd@lists.infradead.org Subject: [RFC PATCH 3/6] block: add new genhd flag GENHD_FL_NO_NVMEM Message-ID: <96510d925cb0ca1a3a132f8f8affd4bbdafd8fc9.1689802933.git.daniel@makrotopia.org> References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: Precedence: bulk List-ID: X-Mailing-List: linux-mmc@vger.kernel.org Add new flag to destinguish block devices which should not act as an NVMEM provider, such as for example an emulated block device on top of an MTD partition which already acts as an NVMEM provider itself. Signed-off-by: Daniel Golle --- include/linux/blkdev.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index 2f5371b8482c0..e853d1815be15 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -80,11 +80,14 @@ struct partition_meta_info { * ``GENHD_FL_NO_PART``: partition support is disabled. The kernel will not * scan for partitions from add_disk, and users can't add partitions manually. * + * ``GENHD_FL_NO_NVMEM``: NVMEM emulation is disabled. The kernel will not + * emulate an NVMEM device on top of this disk. */ enum { GENHD_FL_REMOVABLE = 1 << 0, GENHD_FL_HIDDEN = 1 << 1, GENHD_FL_NO_PART = 1 << 2, + GENHD_FL_NO_NVMEM = 1 << 3, }; enum { From patchwork Wed Jul 19 22:03:24 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Daniel Golle X-Patchwork-Id: 705134 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 94A0FC001E0 for ; Wed, 19 Jul 2023 22:04:32 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229766AbjGSWEb (ORCPT ); Wed, 19 Jul 2023 18:04:31 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44152 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229492AbjGSWEa (ORCPT ); Wed, 19 Jul 2023 18:04:30 -0400 Received: from pidgin.makrotopia.org (pidgin.makrotopia.org [185.142.180.65]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 0EB251FD9; Wed, 19 Jul 2023 15:04:23 -0700 (PDT) Received: from local by pidgin.makrotopia.org with esmtpsa (TLS1.3:TLS_AES_256_GCM_SHA384:256) (Exim 4.96) (envelope-from ) id 1qMFGe-0008Lk-2E; Wed, 19 Jul 2023 22:03:32 +0000 Date: Wed, 19 Jul 2023 23:03:24 +0100 From: Daniel Golle To: Jens Axboe , Ulf Hansson , Miquel Raynal , Richard Weinberger , Vignesh Raghavendra , Dave Chinner , Matthew Wilcox , Thomas =?iso-8859-1?q?Wei=DFschuh?= , Jan Kara , Daniel Golle , Damien Le Moal , Ming Lei , Min Li , Christian Loehle , Adrian Hunter , Hannes Reinecke , Jack Wang , Florian Fainelli , Yeqi Fu , Avri Altman , Hans de Goede , Ye Bin , Greg Kroah-Hartman , =?utf-8?b?UmFmYcWCIE1pxYJl?= =?utf-8?b?Y2tp?= , linux-block@vger.kernel.org, linux-kernel@vger.kernel.org, linux-mmc@vger.kernel.org, linux-mtd@lists.infradead.org Subject: [RFC PATCH 4/6] mtd: blkdevs: set GENHD_FL_NO_NVMEM Message-ID: <65171d5da3daba24315ecdfef6727442baae5bbf.1689802933.git.daniel@makrotopia.org> References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: Precedence: bulk List-ID: X-Mailing-List: linux-mmc@vger.kernel.org As the MTD subsystem already acts as an NVMEM provider, emulated mtdblock devices should not be considered NVMEM providers. Signed-off-by: Daniel Golle --- drivers/mtd/mtd_blkdevs.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/mtd/mtd_blkdevs.c b/drivers/mtd/mtd_blkdevs.c index ff18636e08897..82d5afba6a25a 100644 --- a/drivers/mtd/mtd_blkdevs.c +++ b/drivers/mtd/mtd_blkdevs.c @@ -362,6 +362,7 @@ int add_mtd_blktrans_dev(struct mtd_blktrans_dev *new) gd->flags |= GENHD_FL_NO_PART; } + gd->flags |= GENHD_FL_NO_NVMEM; set_capacity(gd, ((u64)new->size * tr->blksize) >> 9); /* Create the request queue */ From patchwork Wed Jul 19 22:03:49 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Daniel Golle X-Patchwork-Id: 704517 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id AE47FC001B0 for ; Wed, 19 Jul 2023 22:05:13 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230146AbjGSWFM (ORCPT ); Wed, 19 Jul 2023 18:05:12 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45080 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230253AbjGSWFL (ORCPT ); Wed, 19 Jul 2023 18:05:11 -0400 Received: from pidgin.makrotopia.org (pidgin.makrotopia.org [185.142.180.65]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id DE5C22699; Wed, 19 Jul 2023 15:04:51 -0700 (PDT) Received: from local by pidgin.makrotopia.org with esmtpsa (TLS1.3:TLS_AES_256_GCM_SHA384:256) (Exim 4.96) (envelope-from ) id 1qMFH4-0008NR-0M; Wed, 19 Jul 2023 22:03:58 +0000 Date: Wed, 19 Jul 2023 23:03:49 +0100 From: Daniel Golle To: Jens Axboe , Ulf Hansson , Miquel Raynal , Richard Weinberger , Vignesh Raghavendra , Dave Chinner , Matthew Wilcox , Thomas =?iso-8859-1?q?Wei=DFschuh?= , Jan Kara , Daniel Golle , Damien Le Moal , Ming Lei , Min Li , Christian Loehle , Adrian Hunter , Hannes Reinecke , Jack Wang , Florian Fainelli , Yeqi Fu , Avri Altman , Hans de Goede , Ye Bin , Greg Kroah-Hartman , =?utf-8?b?UmFmYcWCIE1pxYJl?= =?utf-8?b?Y2tp?= , linux-block@vger.kernel.org, linux-kernel@vger.kernel.org, linux-mmc@vger.kernel.org, linux-mtd@lists.infradead.org Subject: [RFC PATCH 5/6] mtd: ubi: block: set GENHD_FL_NO_NVMEM Message-ID: <077dbe0a6354edc3acded24e2552cfc3f2968903.1689802933.git.daniel@makrotopia.org> References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: Precedence: bulk List-ID: X-Mailing-List: linux-mmc@vger.kernel.org As the UBI volumes may already act as a NVMEM providers, emulated ubiblock devices should not be considered NVMEM providers. Signed-off-by: Daniel Golle --- drivers/mtd/ubi/block.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/mtd/ubi/block.c b/drivers/mtd/ubi/block.c index 1d5148371991b..62d9461395b37 100644 --- a/drivers/mtd/ubi/block.c +++ b/drivers/mtd/ubi/block.c @@ -410,7 +410,7 @@ int ubiblock_create(struct ubi_volume_info *vi) ret = -ENODEV; goto out_cleanup_disk; } - gd->flags |= GENHD_FL_NO_PART; + gd->flags |= GENHD_FL_NO_PART | GENHD_FL_NO_NVMEM; gd->private_data = dev; sprintf(gd->disk_name, "ubiblock%d_%d", dev->ubi_num, dev->vol_id); set_capacity(gd, disk_capacity); From patchwork Wed Jul 19 22:04:17 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Daniel Golle X-Patchwork-Id: 705133 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 224D7C0015E for ; Wed, 19 Jul 2023 22:05:21 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230281AbjGSWFU (ORCPT ); Wed, 19 Jul 2023 18:05:20 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45178 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230292AbjGSWFT (ORCPT ); Wed, 19 Jul 2023 18:05:19 -0400 Received: from pidgin.makrotopia.org (pidgin.makrotopia.org [185.142.180.65]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 65C0F210C; Wed, 19 Jul 2023 15:04:53 -0700 (PDT) Received: from local by pidgin.makrotopia.org with esmtpsa (TLS1.3:TLS_AES_256_GCM_SHA384:256) (Exim 4.96) (envelope-from ) id 1qMFHW-0008Ns-0m; Wed, 19 Jul 2023 22:04:26 +0000 Date: Wed, 19 Jul 2023 23:04:17 +0100 From: Daniel Golle To: Jens Axboe , Ulf Hansson , Miquel Raynal , Richard Weinberger , Vignesh Raghavendra , Dave Chinner , Matthew Wilcox , Thomas =?iso-8859-1?q?Wei=DFschuh?= , Jan Kara , Daniel Golle , Damien Le Moal , Ming Lei , Min Li , Christian Loehle , Adrian Hunter , Hannes Reinecke , Jack Wang , Florian Fainelli , Yeqi Fu , Avri Altman , Hans de Goede , Ye Bin , Greg Kroah-Hartman , =?utf-8?b?UmFmYcWCIE1pxYJl?= =?utf-8?b?Y2tp?= , linux-block@vger.kernel.org, linux-kernel@vger.kernel.org, linux-mmc@vger.kernel.org, linux-mtd@lists.infradead.org Subject: [RFC PATCH 6/6] block: implement NVMEM provider Message-ID: References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: Precedence: bulk List-ID: X-Mailing-List: linux-mmc@vger.kernel.org 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 --- block/Kconfig | 8 ++ block/Makefile | 1 + block/blk-nvmem.c | 187 ++++++++++++++++++++++++++++++++++++++++ block/blk.h | 13 +++ block/genhd.c | 2 + block/partitions/core.c | 2 + 6 files changed, 213 insertions(+) create mode 100644 block/blk-nvmem.c diff --git a/block/Kconfig b/block/Kconfig index 86122e459fe04..185573877964d 100644 --- a/block/Kconfig +++ b/block/Kconfig @@ -218,6 +218,14 @@ config BLK_MQ_VIRTIO config BLK_PM def_bool PM +config BLK_NVMEM + bool "Block device NVMEM provider" + depends on OF + help + Allow block devices (or partitions) to act as NVMEM prodivers, + typically using if an eMMC is used to store MAC addresses or Wi-Fi + calibration data on embedded devices. + # do not use in new code config BLOCK_HOLDER_DEPRECATED bool diff --git a/block/Makefile b/block/Makefile index 46ada9dc8bbfe..03c0bfa8642df 100644 --- a/block/Makefile +++ b/block/Makefile @@ -34,6 +34,7 @@ obj-$(CONFIG_BLK_DEV_ZONED) += blk-zoned.o obj-$(CONFIG_BLK_WBT) += blk-wbt.o obj-$(CONFIG_BLK_DEBUG_FS) += blk-mq-debugfs.o obj-$(CONFIG_BLK_DEBUG_FS_ZONED)+= blk-mq-debugfs-zoned.o +obj-$(CONFIG_BLK_NVMEM) += blk-nvmem.o obj-$(CONFIG_BLK_SED_OPAL) += sed-opal.o obj-$(CONFIG_BLK_PM) += blk-pm.o obj-$(CONFIG_BLK_INLINE_ENCRYPTION) += blk-crypto.o blk-crypto-profile.o \ diff --git a/block/blk-nvmem.c b/block/blk-nvmem.c new file mode 100644 index 0000000000000..8238511049f56 --- /dev/null +++ b/block/blk-nvmem.c @@ -0,0 +1,187 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * block device NVMEM provider + * + * Copyright (c) 2023 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 block_device *bdev; + struct list_head list; +}; + +static int blk_nvmem_reg_read(void *priv, unsigned int from, + void *val, size_t bytes) +{ + pgoff_t f_index = from >> PAGE_SHIFT; + struct address_space *mapping; + struct blk_nvmem *bnv = priv; + size_t bytes_left = bytes; + struct folio *folio; + unsigned long offs, to_read; + void *p; + + if (!bnv->bdev) + return -ENODEV; + + offs = from & ((1 << PAGE_SHIFT) - 1); + mapping = bnv->bdev->bd_inode->i_mapping; + + while (bytes_left) { + folio = read_mapping_folio(mapping, f_index++, NULL); + if (IS_ERR(folio)) + return PTR_ERR(folio); + + 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); + } + + return bytes_left == 0 ? 0 : -EIO; +} + +void blk_register_nvmem(struct block_device *bdev) +{ + struct fwnode_handle *fw_parts = NULL, *fw_part_c, *fw_part = NULL; + struct nvmem_config config = {}; + const char *partname, *uuid; + struct device *dev, *p0dev; + struct blk_nvmem *bnv; + u32 reg; + + /* + * skip devices which set GENHD_FL_NO_NVMEM + * + * This flag is used for mtdblock and ubiblock devices because + * both, MTD and UBI already implement their own NVMEM provider. + * To avoid registering multiple NVMEM providers for the same + * device node, skip the block NVMEM provider. + */ + if (bdev->bd_disk->flags & GENHD_FL_NO_NVMEM) + return; + + /* skip too large devices */ + if (bdev_nr_bytes(bdev) > INT_MAX) + return; + + dev = &bdev->bd_device; + if (!bdev_is_partition(bdev)) { + fw_part = dev->fwnode; + + if (!fw_part && dev->parent) + fw_part = dev->parent->fwnode; + + goto no_parts; + } + + p0dev = &bdev->bd_disk->part0->bd_device; + fw_parts = device_get_named_child_node(p0dev, "partitions"); + if (!fw_parts) + fw_parts = device_get_named_child_node(p0dev->parent, "partitions"); + + if (!fw_parts) + return; + + fwnode_for_each_child_node(fw_parts, fw_part_c) { + if (!fwnode_property_read_string(fw_part_c, "uuid", &uuid) && + (!bdev->bd_meta_info || strncmp(uuid, + bdev->bd_meta_info->uuid, + PARTITION_META_INFO_UUIDLTH))) + continue; + + if (!fwnode_property_read_string(fw_part_c, "partname", &partname) && + (!bdev->bd_meta_info || strncmp(partname, + bdev->bd_meta_info->volname, + PARTITION_META_INFO_VOLNAMELTH))) + continue; + + /* + * partition addresses (reg) in device tree greater than + * DISK_MAX_PARTS can be used to match uuid or partname only + */ + if (!fwnode_property_read_u32(fw_part_c, "reg", ®) && + reg < DISK_MAX_PARTS && bdev->bd_partno != reg) + continue; + + fw_part = fw_part_c; + break; + } + +no_parts: + if (!fwnode_device_is_compatible(fw_part, "nvmem-cells")) + return; + + bnv = kzalloc(sizeof(struct blk_nvmem), GFP_KERNEL); + if (!bnv) + return; + + 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(fw_part); + + bnv->bdev = bdev; + bnv->nvmem = nvmem_register(&config); + if (IS_ERR(bnv->nvmem)) { + /* Just ignore if there is no NVMEM support in the kernel */ + if (PTR_ERR(bnv->nvmem) != -EOPNOTSUPP) + dev_err_probe(&bdev->bd_device, PTR_ERR(bnv->nvmem), + "Failed to register NVMEM device\n"); + + kfree(bnv); + return; + } + + mutex_lock(&devices_mutex); + list_add_tail(&bnv->list, &nvmem_devices); + mutex_unlock(&devices_mutex); +} + +void blk_unregister_nvmem(struct block_device *bdev) +{ + struct blk_nvmem *bnv_c, *bnv = NULL; + + mutex_lock(&devices_mutex); + list_for_each_entry(bnv_c, &nvmem_devices, list) + if (bnv_c->bdev == bdev) { + 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); +} diff --git a/block/blk.h b/block/blk.h index 686712e138352..7423d0d5494e9 100644 --- a/block/blk.h +++ b/block/blk.h @@ -515,4 +515,17 @@ static inline int req_ref_read(struct request *req) return atomic_read(&req->ref); } +#ifdef CONFIG_BLK_NVMEM +void blk_register_nvmem(struct block_device *bdev); +void blk_unregister_nvmem(struct block_device *bdev); +#else +static inline void blk_register_nvmem(struct block_device *bdev) +{ +} + +static inline void blk_unregister_nvmem(struct block_device *bdev) +{ +} +#endif + #endif /* BLK_INTERNAL_H */ diff --git a/block/genhd.c b/block/genhd.c index 3d287b32d50df..b306e0f407bb2 100644 --- a/block/genhd.c +++ b/block/genhd.c @@ -527,6 +527,7 @@ int __must_check device_add_disk(struct device *parent, struct gendisk *disk, disk_update_readahead(disk); disk_add_events(disk); set_bit(GD_ADDED, &disk->state); + blk_register_nvmem(disk->part0); return 0; out_unregister_bdi: @@ -569,6 +570,7 @@ static void blk_report_disk_dead(struct gendisk *disk) if (bdev->bd_holder_ops && bdev->bd_holder_ops->mark_dead) bdev->bd_holder_ops->mark_dead(bdev); mutex_unlock(&bdev->bd_holder_lock); + blk_unregister_nvmem(bdev); put_device(&bdev->bd_device); rcu_read_lock(); diff --git a/block/partitions/core.c b/block/partitions/core.c index 13a7341299a91..68bd655f5e68e 100644 --- a/block/partitions/core.c +++ b/block/partitions/core.c @@ -404,6 +404,8 @@ static struct block_device *add_partition(struct gendisk *disk, int partno, /* suppress uevent if the disk suppresses it */ if (!dev_get_uevent_suppress(ddev)) kobject_uevent(&pdev->kobj, KOBJ_ADD); + + blk_register_nvmem(bdev); return bdev; out_del: