[OpenWrt-Devel] [PATCH] BB: lantiq: Concatenate multiple flash chips for lantiq-flash

Eddi De Pieri eddi at depieri.net
Fri Nov 7 08:00:55 EST 2014


please wait to aplpy this patch...

I've found two potential regression in:

-      for (type = rom_probe_types; !ltq_mtd->mtd && *type; type++) {
-              ltq_mtd->mtd = do_map_probe(*type, ltq_mtd->map);
-      }

and

+              if (!ltq_mtd->mtd) {

Regards


On Fri, Nov 7, 2014 at 1:20 PM, Eddi De Pieri <eddi at depieri.net> wrote:

> From: Maikel Bloemendal <openwrt at maikelenyvonne.nl>
>
> Signed-off-by: Maikel Bloemendal <openwrt at maikelenyvonne.nl>
> Acked-by: Eddi De Pieri <eddi at depieri.net>
> ---
>  .../0202-owrt-lantiq-multiple-flash.patch          |  218
> ++++++++++++++++++++
>  1 file changed, 218 insertions(+)
>  create mode 100644 target/linux/lantiq/patches-3.10/0202
> -owrt-lantiq-multiple-flash.patch
>
> diff --git a/target/linux/lantiq/patches-3.10/0202-owrt-lantiq-multiple-flash.patch
> b/target/linux/lantiq/patches-3.10/0202-owrt-lantiq-multiple-flash.patch
> new file mode 100644
> index 0000000..021e6fc
> --- /dev/null
> +++
> b/target/linux/lantiq/patches-3.10/0202-owrt-lantiq-multiple-flash.patch
> @@ -0,0 +1,218 @@
> +--- "a/drivers/mtd/maps/lantiq-flash.c"
> ++++ "b/drivers/mtd/maps/lantiq-flash.c"
> +@@ -20,6 +20,7 @@
> + #include <linux/mtd/cfi.h>
> + #include <linux/platform_device.h>
> + #include <linux/mtd/physmap.h>
> ++#include <linux/mtd/concat.h>
> + #include <linux/of.h>
> +
> + #include <lantiq_soc.h>
> +@@ -39,10 +40,12 @@
> +       LTQ_NOR_NORMAL
> + };
> +
> ++#define MAX_RESOURCES         4
> ++
> + struct ltq_mtd {
> +-      struct resource *res;
> +-      struct mtd_info *mtd;
> +-      struct map_info *map;
> ++      struct mtd_info *mtd[MAX_RESOURCES];
> ++      struct mtd_info *cmtd;
> ++      struct map_info map[MAX_RESOURCES];
> + };
> +
> + static const char ltq_map_name[] = "ltq_nor";
> +@@ -110,12 +113,39 @@
> + }
> +
> + static int
> ++ltq_mtd_remove(struct platform_device *pdev)
> ++{
> ++      struct ltq_mtd *ltq_mtd = platform_get_drvdata(pdev);
> ++      int i;
> ++
> ++      if (ltq_mtd == NULL)
> ++              return 0;
> ++
> ++      if (ltq_mtd->cmtd) {
> ++              mtd_device_unregister(ltq_mtd->cmtd);
> ++              if (ltq_mtd->cmtd != ltq_mtd->mtd[0])
> ++                      mtd_concat_destroy(ltq_mtd->cmtd);
> ++      }
> ++
> ++      for (i = 0; i < MAX_RESOURCES; i++) {
> ++              if (ltq_mtd->mtd[i] != NULL)
> ++                      map_destroy(ltq_mtd->mtd[i]);
> ++      }
> ++
> ++      kfree(ltq_mtd);
> ++
> ++      return 0;
> ++}
> ++
> ++static int
> + ltq_mtd_probe(struct platform_device *pdev)
> + {
> +       struct mtd_part_parser_data ppdata;
> +       struct ltq_mtd *ltq_mtd;
> +       struct cfi_private *cfi;
> +-      int err;
> ++      int err = 0;
> ++      int i;
> ++      int devices_found = 0;
> +
> +       static const char *rom_probe_types[] = {
> +               "cfi_probe", "jedec_probe", NULL
> +@@ -131,88 +161,86 @@
> +       ltq_mtd = kzalloc(sizeof(struct ltq_mtd), GFP_KERNEL);
> +       platform_set_drvdata(pdev, ltq_mtd);
> +
> +-      ltq_mtd->res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +-      if (!ltq_mtd->res) {
> +-              dev_err(&pdev->dev, "failed to get memory resource\n");
> +-              err = -ENOENT;
> +-              goto err_out;
> +-      }
> +-
> +-      ltq_mtd->map = kzalloc(sizeof(struct map_info), GFP_KERNEL);
> +-      if (of_find_property(pdev->dev.of_node, "lantiq,noxip", NULL))
> +-              ltq_mtd->map->phys = NO_XIP;
> +-      else
> +-              ltq_mtd->map->phys = ltq_mtd->res->start;
> +-      ltq_mtd->res->start;
> +-      ltq_mtd->map->size = resource_size(ltq_mtd->res);
> +-      ltq_mtd->map->virt = devm_ioremap_resource(&pdev->dev,
> ltq_mtd->res);
> +-      if (IS_ERR(ltq_mtd->map->virt)) {
> +-              err = PTR_ERR(ltq_mtd->map->virt);
> +-              goto err_out;
> +-      }
> ++      for (i = 0; i < pdev->num_resources; i++) {
> ++              printk(KERN_NOTICE "lantiq nor flash device: %.8llx at
> %.8llx\n",
> ++                     (unsigned long
> long)resource_size(&pdev->resource[i]),
> ++                     (unsigned long long)pdev->resource[i].start);
> ++
> ++              if (!devm_request_mem_region(&pdev->dev,
> ++                      pdev->resource[i].start,
> ++                      resource_size(&pdev->resource[i]),
> ++                      dev_name(&pdev->dev))) {
> ++                      dev_err(&pdev->dev, "Could not reserve memory
> region\n");
> ++                      err = -ENOMEM;
> ++                      goto err_out;
> ++              }
> +
> +-      ltq_mtd->map->name = ltq_map_name;
> +-      ltq_mtd->map->bankwidth = 2;
> +-      ltq_mtd->map->read = ltq_read16;
> +-      ltq_mtd->map->write = ltq_write16;
> +-      ltq_mtd->map->copy_from = ltq_copy_from;
> +-      ltq_mtd->map->copy_to = ltq_copy_to;
> ++              ltq_mtd->map[i].name = ltq_map_name;
> ++              ltq_mtd->map[i].bankwidth = 2;
> ++              ltq_mtd->map[i].read = ltq_read16;
> ++              ltq_mtd->map[i].write = ltq_write16;
> ++              ltq_mtd->map[i].copy_from = ltq_copy_from;
> ++              ltq_mtd->map[i].copy_to = ltq_copy_to;
> ++
> ++              if (of_find_property(pdev->dev.of_node, "lantiq,noxip",
> NULL))
> ++                      ltq_mtd->map[i].phys = NO_XIP;
> ++              else
> ++                      ltq_mtd->map[i].phys = pdev->resource[i].start;
> ++              ltq_mtd->map[i].size = resource_size(&pdev->resource[i]);
> ++              ltq_mtd->map[i].virt = devm_ioremap(&pdev->dev,
> ltq_mtd->map[i].phys,
> ++                                               ltq_mtd->map[i].size);
> ++              if (ltq_mtd->map[i].virt == NULL) {
> ++                      dev_err(&pdev->dev, "Failed to ioremap flash
> region\n");
> ++                      err = PTR_ERR(ltq_mtd->map[i].virt);
> ++                      goto err_out;
> ++              }
> +
> +-      ltq_mtd->map->map_priv_1 = LTQ_NOR_PROBING;
> ++              ltq_mtd->map[i].map_priv_1 = LTQ_NOR_PROBING;
> ++              ltq_mtd->mtd[i] = do_map_probe("cfi_probe",
> &ltq_mtd->map[i]);
> ++              ltq_mtd->map[i].map_priv_1 = LTQ_NOR_NORMAL;
> ++
> ++              if (!ltq_mtd->mtd) {
> ++                      dev_err(&pdev->dev, "probing failed\n");
> ++                      err = -ENXIO;
> ++                      goto err_out;
> ++              } else {
> ++                      devices_found++;
> ++              }
> +
> +-      for (type = rom_probe_types; !ltq_mtd->mtd && *type; type++) {
> +-              ltq_mtd->mtd = do_map_probe(*type, ltq_mtd->map);
> +-      }
> +-
> +-      ltq_mtd->map->map_priv_1 = LTQ_NOR_NORMAL;
> ++              ltq_mtd->mtd[i]->owner = THIS_MODULE;
> ++              ltq_mtd->mtd[i]->dev.parent = &pdev->dev;
> +
> +-      if (!ltq_mtd->mtd) {
> +-              dev_err(&pdev->dev, "probing failed\n");
> +-              err = -ENXIO;
> +-              goto err_free;
> ++              cfi = ltq_mtd->map[i].fldrv_priv;
> ++              cfi->addr_unlock1 ^= 1;
> ++              cfi->addr_unlock2 ^= 1;
> ++      }
> ++
> ++      if (devices_found == 1) {
> ++              ltq_mtd->cmtd = ltq_mtd->mtd[0];
> ++      } else if (devices_found > 1) {
> ++              /*
> ++               * We detected multiple devices. Concatenate them together.
> ++               */
> ++              ltq_mtd->cmtd = mtd_concat_create(ltq_mtd->mtd,
> devices_found, dev_name(&pdev->dev));
> ++              if (ltq_mtd->cmtd == NULL)
> ++                      err = -ENXIO;
> +       }
> +
> +-      ltq_mtd->mtd->owner = THIS_MODULE;
> +-
> +-      cfi = ltq_mtd->map->fldrv_priv;
> +-      cfi->addr_unlock1 ^= 1;
> +-      cfi->addr_unlock2 ^= 1;
> +-
> +       ppdata.of_node = pdev->dev.of_node;
> +-      err = mtd_device_parse_register(ltq_mtd->mtd, ltq_probe_types,
> ++      err = mtd_device_parse_register(ltq_mtd->cmtd, ltq_probe_types,
> +                                       &ppdata, NULL, 0);
> +       if (err) {
> +               dev_err(&pdev->dev, "failed to add partitions\n");
> +-              goto err_destroy;
> ++              goto err_out;
> +       }
> +
> +       return 0;
> +
> +-err_destroy:
> +-      map_destroy(ltq_mtd->mtd);
> +-err_free:
> +-      kfree(ltq_mtd->map);
> + err_out:
> +-      kfree(ltq_mtd);
> ++      ltq_mtd_remove(pdev);
> +       return err;
> + }
> +
> +-static int
> +-ltq_mtd_remove(struct platform_device *pdev)
> +-{
> +-      struct ltq_mtd *ltq_mtd = platform_get_drvdata(pdev);
> +-
> +-      if (ltq_mtd) {
> +-              if (ltq_mtd->mtd) {
> +-                      mtd_device_unregister(ltq_mtd->mtd);
> +-                      map_destroy(ltq_mtd->mtd);
> +-              }
> +-              kfree(ltq_mtd->map);
> +-              kfree(ltq_mtd);
> +-      }
> +-      return 0;
> +-}
> +-
> + static const struct of_device_id ltq_mtd_match[] = {
> +       { .compatible = "lantiq,nor" },
> +       {},
> --
> 1.7.10.4
> _______________________________________________
> openwrt-devel mailing list
> openwrt-devel at lists.openwrt.org
> https://lists.openwrt.org/cgi-bin/mailman/listinfo/openwrt-devel
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.infradead.org/pipermail/openwrt-devel/attachments/20141107/c8ae6651/attachment.htm>
-------------- next part --------------
_______________________________________________
openwrt-devel mailing list
openwrt-devel at lists.openwrt.org
https://lists.openwrt.org/cgi-bin/mailman/listinfo/openwrt-devel


More information about the openwrt-devel mailing list