Received: by 2002:ac0:a5a6:0:0:0:0:0 with SMTP id m35-v6csp648508imm; Sat, 8 Sep 2018 06:22:08 -0700 (PDT) X-Google-Smtp-Source: ANB0VdYh+3KOr1y4MYEbv8R4Iq4JQajIduin7D18Kg5dVhrZCirrHeu/UTbdFD73DMpLN/3j2lhz X-Received: by 2002:a62:ea05:: with SMTP id t5-v6mr14002177pfh.228.1536412928616; Sat, 08 Sep 2018 06:22:08 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1536412928; cv=none; d=google.com; s=arc-20160816; b=ws17WjirSiAxZaYxSZzObi8itr9jSH192/CpJjBLfdNdWzQAf9bTSl5mB1Z4+cLXik U9ktMQTVdfqCNYdOgx8hxnlsx8ZkJP5lKmQ5UIAFbG9m5JM2BikhIVVu6AYgNamvebvJ GCel8ojxevV8R2oCr+DR97DlN1S2MUk6TX1+uERNh45KdHfZKUnuo1f6vfXiKeopMPq/ gkkZcU7Ndh4xVRkocgR6mE5XLz2VFRNWKZsZ+VXja0kFMdG7y4WIWwa49n57SJym0yN6 B7ylaOJJ3RcTxjPsRjm5+X/7owUd14Kc2cxCxtCL2LJYHuqgQb2jeElO21iKXMpl//FS K7og== 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=3RVMszzhPytHPhn/eAJITVq/4BY2TnAnnsNdD4Pgbzo=; b=aEpGzbqcON83BreTRM4a7nFltMF9j6OJsNtZ08T3JdPxgTJOvIULxg49GhYfObSsbl 1r4T21Uwq7sdgF+9fM8C9MN37U3yum7uBJ+luHvU9YATOA6NUAg06ZFQlAspoW0MInG9 7py5gM1ojo75dv6emi3T53dIfTV4GCEjg+QuP3zFWnoFQIljt+kGzV40Uifr5y0MEmwm sLyx1Fhr3B1hgFc+9edKmLYzSy7kiBjJIkkNP+eApzlxDkwhRcx8BID+Zwxp+KwtnsuT atOQo5hgmNKGrbYtCcob6mw2GGNEOPOgNmlEXN5i5G8BvTqlllnFOvwa/0n4SFzrjrV4 LMwg== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@obeliks.de header.s=jul2017 header.b=iPCxHzny; 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 v21-v6si11029246plo.397.2018.09.08.06.21.52; Sat, 08 Sep 2018 06:22:08 -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=iPCxHzny; 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 S1726735AbeIHSGa (ORCPT + 99 others); Sat, 8 Sep 2018 14:06:30 -0400 Received: from scopuli.esotechnik.de ([79.143.188.15]:52669 "EHLO mail.esotechnik.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726498AbeIHSG3 (ORCPT ); Sat, 8 Sep 2018 14:06:29 -0400 Received: by mail.esotechnik.net (Postfix) with ESMTPSA id 58425AE0B84; Sat, 8 Sep 2018 15:14:05 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=obeliks.de; s=jul2017; t=1536412445; 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=3RVMszzhPytHPhn/eAJITVq/4BY2TnAnnsNdD4Pgbzo=; b=iPCxHznyAkPcGHkzBfYTNK4raVh+SjxM3Vxj04F2VzRGWPXRVMoRlHRa1S08da2a9loVAA L32E8avPfVapetio4fU4yZfG68Y0MGIorJjQ6GOpdstyHcxZPtcsfqJavQ48CVEkX1bHsF yI7MJg+OPDAlzArIywL/0oEdOXS4+6vjwujQ/NBQ3hFZfJ3wea1aJAuZR0YzdBGrnu3835 zzHfGVKVoUiGXDphTZ9giV9Ht7Ii0mmkXcMhwMU5gGW7cxScNxV+9oFfV4BaiDggls4ONx WhDlmEAfGdX4Nv5d4z934H5NZhFijMYKGOfZqKXdpsKUE5I29W/I8/1VV3hyqA== From: Bernhard Frauendienst To: David Woodhouse , Brian Norris , Boris Brezillon , Marek Vasut , Richard Weinberger , Rob Herring , Mark Rutland Cc: Bernhard Frauendienst , Miquel Raynal , linux-mtd@lists.infradead.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v3 3/3] mtd: mtdconcat: add dt driver for concat devices Date: Sat, 8 Sep 2018 15:13:45 +0200 Message-Id: <20180908131345.8145-4-kernel@nospam.obeliks.de> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20180908131345.8145-1-kernel@nospam.obeliks.de> References: <20180908131345.8145-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..8421a0a30606 --- /dev/null +++ b/drivers/mtd/composite/Makefile @@ -0,0 +1,6 @@ +# 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 points to an 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.18.0