Re: [PATCH v3 3/3] mtd: mtdconcat: add dt driver for concat devices

2018-09-14 Thread Bernhard Frauendienst
Hi Rob,

sorry it took me so long to reply, I had to set up mutt first ;)

On Mon, Sep 10, 2018 at 04:47:22PM -0500, Rob Herring wrote:
> On Sat, Sep 8, 2018 at 8:20 AM Bernhard Frauendienst
>  wrote:
> >
> > 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.
> 
> That is the generic way, but I suppose that only works for parallel
> memory mapped devices. So is it just spi-nor that you need to support?

I'm no expert in this domain, or regarding OpenWRT, but as far as I can
tell this only concerns spi-nor devices. It definitely does in my
specific use-case.

> Can we just make reg take multiple chip selects just like the existing
> support takes multiple reg entries?

That sounds like an interesting idea, but I'm afraid it's not a trivial
change, as far as I can tell from looking at spi.c. 

The 'reg' property is currently read in of_spi_parse_dt which gets
passed the spi device created in of_register_spi_device. The latter
would have to create multiple devices from a single OF node, and pass
the chipselect value to of_spi_parse_dt, which would have to parse the
same node multiple times, which feels a bit strange. To make things
worse, of_register_spi_device returns the created device, although that
value seems unused in the current tree (except for error checks).

Am I correct to assume that this change in method signature could be
accteptable since both functions are not exported?

Regards,
Bernhard


Re: [PATCH v3 3/3] mtd: mtdconcat: add dt driver for concat devices

2018-09-14 Thread Bernhard Frauendienst
Hi Rob,

sorry it took me so long to reply, I had to set up mutt first ;)

On Mon, Sep 10, 2018 at 04:47:22PM -0500, Rob Herring wrote:
> On Sat, Sep 8, 2018 at 8:20 AM Bernhard Frauendienst
>  wrote:
> >
> > 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.
> 
> That is the generic way, but I suppose that only works for parallel
> memory mapped devices. So is it just spi-nor that you need to support?

I'm no expert in this domain, or regarding OpenWRT, but as far as I can
tell this only concerns spi-nor devices. It definitely does in my
specific use-case.

> Can we just make reg take multiple chip selects just like the existing
> support takes multiple reg entries?

That sounds like an interesting idea, but I'm afraid it's not a trivial
change, as far as I can tell from looking at spi.c. 

The 'reg' property is currently read in of_spi_parse_dt which gets
passed the spi device created in of_register_spi_device. The latter
would have to create multiple devices from a single OF node, and pass
the chipselect value to of_spi_parse_dt, which would have to parse the
same node multiple times, which feels a bit strange. To make things
worse, of_register_spi_device returns the created device, although that
value seems unused in the current tree (except for error checks).

Am I correct to assume that this change in method signature could be
accteptable since both functions are not exported?

Regards,
Bernhard


Re: [PATCH v3 3/3] mtd: mtdconcat: add dt driver for concat devices

2018-09-10 Thread Rob Herring
On Sat, Sep 8, 2018 at 8:20 AM Bernhard Frauendienst
 wrote:
>
> 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.

That is the generic way, but I suppose that only works for parallel
memory mapped devices. So is it just spi-nor that you need to support?
Can we just make reg take multiple chip selects just like the existing
support takes multiple reg entries?

> 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 = < >;
>
>   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 ..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 ..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 ..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, ker...@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]);
> +  

Re: [PATCH v3 3/3] mtd: mtdconcat: add dt driver for concat devices

2018-09-10 Thread Rob Herring
On Sat, Sep 8, 2018 at 8:20 AM Bernhard Frauendienst
 wrote:
>
> 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.

That is the generic way, but I suppose that only works for parallel
memory mapped devices. So is it just spi-nor that you need to support?
Can we just make reg take multiple chip selects just like the existing
support takes multiple reg entries?

> 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 = < >;
>
>   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 ..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 ..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 ..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, ker...@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]);
> +  

[PATCH v3 3/3] mtd: mtdconcat: add dt driver for concat devices

2018-09-08 Thread Bernhard Frauendienst
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 = < >;

  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 ..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 ..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 ..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, ker...@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(>dev, sizeof(*info), GFP_KERNEL);
+   if (!info)
+   return -ENOMEM;
+   info->devices = devm_kcalloc(>dev, count,
+  

[PATCH v3 3/3] mtd: mtdconcat: add dt driver for concat devices

2018-09-08 Thread Bernhard Frauendienst
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 = < >;

  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 ..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 ..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 ..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, ker...@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(>dev, sizeof(*info), GFP_KERNEL);
+   if (!info)
+   return -ENOMEM;
+   info->devices = devm_kcalloc(>dev, count,
+