From patchwork Sun Dec 17 22:19:52 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Daniel Golle X-Patchwork-Id: 180084 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7300:24d3:b0:fb:cd0c:d3e with SMTP id r19csp910511dyi; Sun, 17 Dec 2023 14:23:05 -0800 (PST) X-Google-Smtp-Source: AGHT+IFYFXUmQR9unfUtKBW66SsheME7lKIIyFgPE19VJNHV6zuBFdYqEWKwNDI+bX7fQuPQxRk3 X-Received: by 2002:a05:6a20:e117:b0:194:5f27:6f33 with SMTP id kr23-20020a056a20e11700b001945f276f33mr566480pzb.1.1702851785302; Sun, 17 Dec 2023 14:23:05 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1702851785; cv=none; d=google.com; s=arc-20160816; b=UhvIM7wFYr990StTJFwi4GCSMii5azwEBrhhxmeP5lDMsHJ59YD5d6OPDyUh6bfds5 RdgSNYSnIjLD+vr/dDQHyX/n9TPXfZl9RxyOkFNsk2k8156XJH/7PtToXR32++L3IpsX W7c2S1onJ+kz586IbEKR/p8fvo/imDqCzyzIgb5hFyOPnkIa0ruPuvDJLvKW092ebBBV sXGUPXMMKh1XsggtqKaUJstT7ssij+K1BQZuoJh1dvzNnadHnYxrs0H7OKpeA0WRQiLM bR6MVG5oV68TIl8UNshi2WnrVlb0gcw7nRxTnL5WInk2qPO9/agg00fk/pT6mDiAQ9Q7 wTeA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=in-reply-to:content-disposition:mime-version:list-unsubscribe :list-subscribe:list-id:precedence:references:message-id:subject:to :from:date; bh=T8fdep8+mdF1J9MnMm82b1jp8g1JSfRq0dUfV4RSgpU=; fh=75NJMYqoRo4jeDl32jx04p3D1q0Fgi4sqch+OCznfHk=; b=nZnDOylQXdcFxq3WfqT4skt4soN9HBvP2rMwNYbEoAVNIdk7mZdr/EbqkkDwl0OLia oydP4C6+MDq9Avc6rlV4+Zq1TC63DfaSEwnnT4PU6hPVBW6rY1tqBDaOpXkBLFDjiHxz OxYpIXrP2cMmrgF5dkB9yYfSNO0l4nqR/d7dkJf333VprYUM0MuRlt6PuuuSCZ/CKyT9 zTyp/LnCkwLiSJeALduhNsooLHr/1A0oizdURexq7yUW7aglZ9lt2JlAi2x1Zo/2js3u xvS6D/SN1enllypGsBdtv3DkW1sD5SuNoVSTe5+l4c7WBcmwRlrOIlqSXKJGrM60g54X mUSg== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-kernel+bounces-2849-ouuuleilei=gmail.com@vger.kernel.org designates 147.75.48.161 as permitted sender) smtp.mailfrom="linux-kernel+bounces-2849-ouuuleilei=gmail.com@vger.kernel.org" Received: from sy.mirrors.kernel.org (sy.mirrors.kernel.org. [147.75.48.161]) by mx.google.com with ESMTPS id y20-20020a63e254000000b005c1ce3c9617si16298210pgj.901.2023.12.17.14.23.04 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 17 Dec 2023 14:23:05 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-2849-ouuuleilei=gmail.com@vger.kernel.org designates 147.75.48.161 as permitted sender) client-ip=147.75.48.161; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-kernel+bounces-2849-ouuuleilei=gmail.com@vger.kernel.org designates 147.75.48.161 as permitted sender) smtp.mailfrom="linux-kernel+bounces-2849-ouuuleilei=gmail.com@vger.kernel.org" Received: from smtp.subspace.kernel.org (wormhole.subspace.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by sy.mirrors.kernel.org (Postfix) with ESMTPS id A32CAB227A1 for ; Sun, 17 Dec 2023 22:20:44 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 8BD3B4B135; Sun, 17 Dec 2023 22:20:07 +0000 (UTC) X-Original-To: linux-kernel@vger.kernel.org Received: from pidgin.makrotopia.org (pidgin.makrotopia.org [185.142.180.65]) (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 C03704B151; Sun, 17 Dec 2023 22:20:00 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=makrotopia.org Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=makrotopia.org Received: from local by pidgin.makrotopia.org with esmtpsa (TLS1.3:TLS_AES_256_GCM_SHA384:256) (Exim 4.96.2) (envelope-from ) id 1rEzUI-0001c5-12; Sun, 17 Dec 2023 22:19:55 +0000 Date: Sun, 17 Dec 2023 22:19:52 +0000 From: Daniel Golle To: Miquel Raynal , Richard Weinberger , Vignesh Raghavendra , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Daniel Golle , linux-mtd@lists.infradead.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v6 4/7] mtd: ubi: attach from device tree Message-ID: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1785569513555929871 X-GMAIL-MSGID: 1785569513555929871 Introduce device tree compatible 'linux,ubi' and attach compatible MTD devices using the MTD add notifier. This is needed for a UBI device to be available early at boot (and not only after late_initcall), so volumes on them can be used eg. as NVMEM providers for other drivers. Signed-off-by: Daniel Golle --- drivers/mtd/ubi/build.c | 135 ++++++++++++++++++++++++++++------------ 1 file changed, 96 insertions(+), 39 deletions(-) diff --git a/drivers/mtd/ubi/build.c b/drivers/mtd/ubi/build.c index 7d4ff1193db6f..8c3f763e4ddb8 100644 --- a/drivers/mtd/ubi/build.c +++ b/drivers/mtd/ubi/build.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #include "ubi.h" @@ -1219,43 +1220,43 @@ static struct mtd_info * __init open_mtd_device(const char *mtd_dev) return mtd; } -static int __init ubi_init(void) +static void ubi_notify_add(struct mtd_info *mtd) { - int err, i, k; + struct device_node *np = mtd_get_of_node(mtd); + int err; - /* Ensure that EC and VID headers have correct size */ - BUILD_BUG_ON(sizeof(struct ubi_ec_hdr) != 64); - BUILD_BUG_ON(sizeof(struct ubi_vid_hdr) != 64); + if (!of_device_is_compatible(np, "linux,ubi")) + return; - if (mtd_devs > UBI_MAX_DEVICES) { - pr_err("UBI error: too many MTD devices, maximum is %d\n", - UBI_MAX_DEVICES); - return -EINVAL; - } + /* + * we are already holding &mtd_table_mutex, but still need + * to bump refcount + */ + err = __get_mtd_device(mtd); + if (err) + return; - /* Create base sysfs directory and sysfs files */ - err = class_register(&ubi_class); + /* called while holding mtd_table_mutex */ + mutex_lock_nested(&ubi_devices_mutex, SINGLE_DEPTH_NESTING); + err = ubi_attach_mtd_dev(mtd, UBI_DEV_NUM_AUTO, 0, 0, false, false); + mutex_unlock(&ubi_devices_mutex); if (err < 0) - return err; - - err = misc_register(&ubi_ctrl_cdev); - if (err) { - pr_err("UBI error: cannot register device\n"); - goto out; - } + __put_mtd_device(mtd); +} - ubi_wl_entry_slab = kmem_cache_create("ubi_wl_entry_slab", - sizeof(struct ubi_wl_entry), - 0, 0, NULL); - if (!ubi_wl_entry_slab) { - err = -ENOMEM; - goto out_dev_unreg; - } +static void ubi_notify_remove(struct mtd_info *mtd) +{ + /* do nothing for now */ +} - err = ubi_debugfs_init(); - if (err) - goto out_slab; +static struct mtd_notifier ubi_mtd_notifier = { + .add = ubi_notify_add, + .remove = ubi_notify_remove, +}; +static int __init ubi_init_attach(void) +{ + int err, i, k; /* Attach MTD devices */ for (i = 0; i < mtd_devs; i++) { @@ -1304,25 +1305,79 @@ static int __init ubi_init(void) } } + return 0; + +out_detach: + for (k = 0; k < i; k++) + if (ubi_devices[k]) { + mutex_lock(&ubi_devices_mutex); + ubi_detach_mtd_dev(ubi_devices[k]->ubi_num, 1); + mutex_unlock(&ubi_devices_mutex); + } + return err; +} +#ifndef CONFIG_MTD_UBI_MODULE +late_initcall(ubi_init_attach); +#endif + +static int __init ubi_init(void) +{ + int err; + + /* Ensure that EC and VID headers have correct size */ + BUILD_BUG_ON(sizeof(struct ubi_ec_hdr) != 64); + BUILD_BUG_ON(sizeof(struct ubi_vid_hdr) != 64); + + if (mtd_devs > UBI_MAX_DEVICES) { + pr_err("UBI error: too many MTD devices, maximum is %d\n", + UBI_MAX_DEVICES); + return -EINVAL; + } + + /* Create base sysfs directory and sysfs files */ + err = class_register(&ubi_class); + if (err < 0) + return err; + + err = misc_register(&ubi_ctrl_cdev); + if (err) { + pr_err("UBI error: cannot register device\n"); + goto out; + } + + ubi_wl_entry_slab = kmem_cache_create("ubi_wl_entry_slab", + sizeof(struct ubi_wl_entry), + 0, 0, NULL); + if (!ubi_wl_entry_slab) { + err = -ENOMEM; + goto out_dev_unreg; + } + + err = ubi_debugfs_init(); + if (err) + goto out_slab; + err = ubiblock_init(); if (err) { pr_err("UBI error: block: cannot initialize, error %d\n", err); /* See comment above re-ubi_is_module(). */ if (ubi_is_module()) - goto out_detach; + goto out_slab; + } + + register_mtd_user(&ubi_mtd_notifier); + + if (ubi_is_module()) { + err = ubi_init_attach(); + if (err) + goto out_mtd_notifier; } return 0; -out_detach: - for (k = 0; k < i; k++) - if (ubi_devices[k]) { - mutex_lock(&ubi_devices_mutex); - ubi_detach_mtd_dev(ubi_devices[k]->ubi_num, 1); - mutex_unlock(&ubi_devices_mutex); - } - ubi_debugfs_exit(); +out_mtd_notifier: + unregister_mtd_user(&ubi_mtd_notifier); out_slab: kmem_cache_destroy(ubi_wl_entry_slab); out_dev_unreg: @@ -1332,13 +1387,15 @@ static int __init ubi_init(void) pr_err("UBI error: cannot initialize UBI, error %d\n", err); return err; } -late_initcall(ubi_init); +device_initcall(ubi_init); + static void __exit ubi_exit(void) { int i; ubiblock_exit(); + unregister_mtd_user(&ubi_mtd_notifier); for (i = 0; i < UBI_MAX_DEVICES; i++) if (ubi_devices[i]) {