Received: by 2002:ac0:a5a6:0:0:0:0:0 with SMTP id m35-v6csp2095391imm; Fri, 7 Sep 2018 10:42:09 -0700 (PDT) X-Google-Smtp-Source: ANB0VdbqktJbT7ts8irvJW+j1SMcvWNw3pP6aUxZmwH+Ub07t/cMKaHwRsUJMgDu59HujYwNLkEd X-Received: by 2002:a17:902:8345:: with SMTP id z5-v6mr9021546pln.147.1536342129778; Fri, 07 Sep 2018 10:42:09 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1536342129; cv=none; d=google.com; s=arc-20160816; b=u570QJTfALlXADb9auYtfdhiOY87G+oukohG+a2ktjEM8txxPoyLkCfyfXJPahz6po s9yzpWYO94TksGd1/1SwV8UjB+ZpDe7u17FgM4T7F5vhEeCF/uciXAqVnPv1J1+4tW/M 7DFzMFTHQCvbUbyx4iVYuiQu9SPAjhm2RHCvRB4FrSRvS82PkDTEKj3mufzWjVOZSmrx JdxI5P62gA18YYQYXYdj3PnIvM2IbXRKSKaQkuE2K4SyRuLYqWR0OO5atPeFQi+7zvqC xwHMzGLFbOE1KPr0yE8GIaX3vLeltKEjJkBumtA2g0fQxgaAWCKN5nM1DzUqX8DDEcpN gTLw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:dkim-signature; bh=mOi9XOi6dVlrwYf4wFJGLywyz++uoc+vhfVWt2oFhmI=; b=JJQpPaMJMt5mNhQ6wsVAcgTvoAMne6k7SQFiWWbKg62p3SjB9DfpgU4E7MIdZjclZB QN3pjQ/VWxrutlmdX46kqDyhEISeIO6UcdQTKFbO1ADd+abANapt1UGHKCtNGaOUDWKn dm2rMC9XKwGkSMzMtRNfYGgL5WacDp8ANglGPq0lD2RTjLZ3wX8Zz/CmZSL+9sPJNJqV SWe0qEcBpinam77aDq7no25Mq33RpgdV7G8nw+3vCHi8Cgh8eCb43z8npEfiQJx3P5sP Vx3yR9R0bk+MPgL5dUP/oCwrPX2Qtbocjog1ciHaKE9CgRofpl1BbIttbPygvbQFJc6E N/hw== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@obeliks.de header.s=jul2017 header.b=V71Y2S3D; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=obeliks.de Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id c13-v6si8259940pfi.256.2018.09.07.10.41.53; Fri, 07 Sep 2018 10:42:09 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=fail header.i=@obeliks.de header.s=jul2017 header.b=V71Y2S3D; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=obeliks.de Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727693AbeIGWWo (ORCPT + 99 others); Fri, 7 Sep 2018 18:22:44 -0400 Received: from scopuli.esotechnik.de ([79.143.188.15]:54169 "EHLO mail.esotechnik.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726614AbeIGWWn (ORCPT ); Fri, 7 Sep 2018 18:22:43 -0400 Received: by mail.esotechnik.net (Postfix) with ESMTPSA id 05EFAAE0B84; Fri, 7 Sep 2018 19:35:18 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=obeliks.de; s=jul2017; t=1536341718; h=from:from:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:content-type: content-transfer-encoding:in-reply-to:in-reply-to: references:references; bh=mOi9XOi6dVlrwYf4wFJGLywyz++uoc+vhfVWt2oFhmI=; b=V71Y2S3D+517o4FO5eiOL8Q/PL6chgOynXL7gydgrwMEiOfG6+F1qHE1z4ukq+CT60aUSF bw0x2horA9L+bykl2HxllNIoklrp/iziyheQkD/vL2A9X+EUsO87NJac5AmIDOghlH11mo KLOB0VEM/Svx6VgeuJmn4cgeZawoKPqf82v9fQmcxDf1Y2q+wG8L92ZnefyE4z0v++7lsf kNHIYS1DyjteLMkd9SlHgSMNfIM2dNbYdn+jneRtzqBi2xd81WTg1pN3MaRGxXnDxQ2geJ bszCKkvtelIYFJwnVBVLhT8Qitd+BB/yqbqT4RROWpH/Cv9zLBlcxxfjgLAwbg== From: Bernhard Frauendienst To: David Woodhouse , Brian Norris , Boris Brezillon , Marek Vasut , Richard Weinberger Cc: Miquel Raynal , linux-kernel@vger.kernel.org, linux-mtd@lists.infradead.org Subject: [PATCH v2 3/3] mtd: mtdconcat: add dt driver for concat devices Date: Fri, 7 Sep 2018 19:35:15 +0200 Message-Id: <20180907173515.19990-4-kernel@nospam.obeliks.de> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20180907173515.19990-1-kernel@nospam.obeliks.de> References: <20180907173515.19990-1-kernel@nospam.obeliks.de> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Some mtd drivers like physmap variants have support for concatenating multiple mtd devices, but there is no generic way to define such a concat device from within the device tree. This is useful for some SoC boards that use multiple flash chips as memory banks of a single mtd device, with partitions spanning chip borders. This commit adds a driver for creating virtual mtd-concat devices. They must have a compatible = "mtd-concat" line, and define a list of devices to concat in the 'devices' property, for example: flash { compatible = "mtd-concat"; devices = <&flash0 &flash1>; partitions { ... }; }; The driver is added to the very end of the mtd Makefile to increase the likelyhood of all child devices already being loaded at the time of probing, preventing unnecessary deferred probes. Signed-off-by: Bernhard Frauendienst --- drivers/mtd/Kconfig | 2 + drivers/mtd/Makefile | 3 + drivers/mtd/composite/Kconfig | 12 +++ drivers/mtd/composite/Makefile | 7 ++ drivers/mtd/composite/virt_concat.c | 128 ++++++++++++++++++++++++++++ 5 files changed, 152 insertions(+) create mode 100644 drivers/mtd/composite/Kconfig create mode 100644 drivers/mtd/composite/Makefile create mode 100644 drivers/mtd/composite/virt_concat.c diff --git a/drivers/mtd/Kconfig b/drivers/mtd/Kconfig index c77f537323ec..6345d886d458 100644 --- a/drivers/mtd/Kconfig +++ b/drivers/mtd/Kconfig @@ -339,4 +339,6 @@ source "drivers/mtd/spi-nor/Kconfig" source "drivers/mtd/ubi/Kconfig" +source "drivers/mtd/composite/Kconfig" + endif # MTD diff --git a/drivers/mtd/Makefile b/drivers/mtd/Makefile index 93473d215a38..57af7190b063 100644 --- a/drivers/mtd/Makefile +++ b/drivers/mtd/Makefile @@ -36,3 +36,6 @@ obj-y += chips/ lpddr/ maps/ devices/ nand/ tests/ obj-$(CONFIG_MTD_SPI_NOR) += spi-nor/ obj-$(CONFIG_MTD_UBI) += ubi/ + +# Composite drivers must be loaded last +obj-y += composite/ diff --git a/drivers/mtd/composite/Kconfig b/drivers/mtd/composite/Kconfig new file mode 100644 index 000000000000..0490fc0284bb --- /dev/null +++ b/drivers/mtd/composite/Kconfig @@ -0,0 +1,12 @@ +menu "Composite MTD device drivers" + depends on MTD!=n + +config MTD_VIRT_CONCAT + tristate "Virtual concat MTD device" + help + This driver allows creation of a virtual MTD concat device, which + concatenates multiple underlying MTD devices to a single device. + This is required by some SoC boards where multiple memory banks are + used as one device with partitions spanning across device boundaries. + +endmenu diff --git a/drivers/mtd/composite/Makefile b/drivers/mtd/composite/Makefile new file mode 100644 index 000000000000..7f4bdeee0e0a --- /dev/null +++ b/drivers/mtd/composite/Makefile @@ -0,0 +1,7 @@ +# SPDX-License-Identifier: GPL-2.0 +# +# linux/drivers/mtd/composite/Makefile +# + +obj-$(CONFIG_MTD_VIRT_CONCAT) += virt_concat.o + diff --git a/drivers/mtd/composite/virt_concat.c b/drivers/mtd/composite/virt_concat.c new file mode 100644 index 000000000000..76918d4ef07f --- /dev/null +++ b/drivers/mtd/composite/virt_concat.c @@ -0,0 +1,128 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Virtual concat MTD device driver + * + * Copyright (C) 2018 Bernhard Frauendienst + * Author: Bernhard Frauendienst, kernel@nospam.obeliks.de + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * struct of_virt_concat - platform device driver data. + * @cmtd the final mtd_concat device + * @num_devices the number of devices in @devices + * @devices array of devices already loaded + */ +struct of_virt_concat { + struct mtd_info *cmtd; + int num_devices; + struct mtd_info **devices; +}; + +static int virt_concat_remove(struct platform_device *pdev) +{ + struct of_virt_concat *info; + int i; + + info = platform_get_drvdata(pdev); + if (!info) + return 0; + + // unset data for when this is called after a probe error + platform_set_drvdata(pdev, NULL); + + if (info->cmtd) { + mtd_device_unregister(info->cmtd); + mtd_concat_destroy(info->cmtd); + } + + if (info->devices) { + for (i = 0; i < info->num_devices; i++) + put_mtd_device(info->devices[i]); + } + + return 0; +} + +static int virt_concat_probe(struct platform_device *pdev) +{ + struct device_node *node = pdev->dev.of_node; + struct of_phandle_iterator it; + struct of_virt_concat *info; + struct mtd_info *mtd; + int err = 0, count; + + count = of_count_phandle_with_args(node, "devices", NULL); + if (count <= 0) + return -EINVAL; + + info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL); + if (!info) + return -ENOMEM; + info->devices = devm_kcalloc(&pdev->dev, count, + sizeof(*(info->devices)), GFP_KERNEL); + if (!info->devices) { + err = -ENOMEM; + goto err_remove; + } + + platform_set_drvdata(pdev, info); + + of_for_each_phandle(&it, err, node, "devices", NULL, 0) { + mtd = get_mtd_device_by_node(it.node); + if (IS_ERR(mtd)) { + of_node_put(it.node); + err = -EPROBE_DEFER; + goto err_remove; + } + + info->devices[info->num_devices++] = mtd; + } + + info->cmtd = mtd_concat_create(info->devices, info->num_devices, + dev_name(&pdev->dev)); + if (!info->cmtd) { + err = -ENXIO; + goto err_remove; + } + + info->cmtd->dev.parent = &pdev->dev; + mtd_set_of_node(info->cmtd, node); + mtd_device_register(info->cmtd, NULL, 0); + + return 0; + +err_remove: + virt_concat_remove(pdev); + + return err; +} + +static const struct of_device_id virt_concat_of_match[] = { + { .compatible = "mtd-concat", }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, virt_concat_of_match); + +static struct platform_driver virt_concat_driver = { + .probe = virt_concat_probe, + .remove = virt_concat_remove, + .driver = { + .name = "virt-mtdconcat", + .of_match_table = virt_concat_of_match, + }, +}; + +module_platform_driver(virt_concat_driver); + +MODULE_LICENSE("GPL v2"); +MODULE_AUTHOR("Bernhard Frauendienst "); +MODULE_DESCRIPTION("Virtual concat MTD device driver"); -- 2.17.1