mediatek: switch to Linux version 6.1
[openwrt/staging/dangole.git] / target / linux / mediatek / patches-5.15 / 120-01-v5.18-mtd-nand-ecc-Add-infrastructure-to-support-hardware-.patch
diff --git a/target/linux/mediatek/patches-5.15/120-01-v5.18-mtd-nand-ecc-Add-infrastructure-to-support-hardware-.patch b/target/linux/mediatek/patches-5.15/120-01-v5.18-mtd-nand-ecc-Add-infrastructure-to-support-hardware-.patch
deleted file mode 100644 (file)
index 7fb62e7..0000000
+++ /dev/null
@@ -1,214 +0,0 @@
-From ad4944aa0b02cb043afe20bc2a018c161e65c992 Mon Sep 17 00:00:00 2001
-From: Miquel Raynal <miquel.raynal@bootlin.com>
-Date: Thu, 16 Dec 2021 12:16:38 +0100
-Subject: [PATCH 01/15] mtd: nand: ecc: Add infrastructure to support hardware
- engines
-
-Add the necessary helpers to register/unregister hardware ECC engines
-that will be called from ECC engine drivers.
-
-Also add helpers to get the right engine from the user
-perspective. Keep a reference of the in use ECC engine in order to
-prevent modules to be unloaded. Put the reference when the engine gets
-retired.
-
-A static list of hardware (only) ECC engines is setup to keep track of
-the registered engines.
-
-Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
-Link: https://lore.kernel.org/linux-mtd/20211216111654.238086-13-miquel.raynal@bootlin.com
-(cherry picked from commit 96489c1c0b53131b0e1ec33e2060538379ad6152)
----
- drivers/mtd/nand/core.c  | 10 +++--
- drivers/mtd/nand/ecc.c   | 88 ++++++++++++++++++++++++++++++++++++++++
- include/linux/mtd/nand.h | 28 +++++++++++++
- 3 files changed, 123 insertions(+), 3 deletions(-)
-
---- a/drivers/mtd/nand/core.c
-+++ b/drivers/mtd/nand/core.c
-@@ -232,7 +232,9 @@ static int nanddev_get_ecc_engine(struct
-               nand->ecc.engine = nand_ecc_get_on_die_hw_engine(nand);
-               break;
-       case NAND_ECC_ENGINE_TYPE_ON_HOST:
--              pr_err("On-host hardware ECC engines not supported yet\n");
-+              nand->ecc.engine = nand_ecc_get_on_host_hw_engine(nand);
-+              if (PTR_ERR(nand->ecc.engine) == -EPROBE_DEFER)
-+                      return -EPROBE_DEFER;
-               break;
-       default:
-               pr_err("Missing ECC engine type\n");
-@@ -252,7 +254,7 @@ static int nanddev_put_ecc_engine(struct
- {
-       switch (nand->ecc.ctx.conf.engine_type) {
-       case NAND_ECC_ENGINE_TYPE_ON_HOST:
--              pr_err("On-host hardware ECC engines not supported yet\n");
-+              nand_ecc_put_on_host_hw_engine(nand);
-               break;
-       case NAND_ECC_ENGINE_TYPE_NONE:
-       case NAND_ECC_ENGINE_TYPE_SOFT:
-@@ -297,7 +299,9 @@ int nanddev_ecc_engine_init(struct nand_
-       /* Look for the ECC engine to use */
-       ret = nanddev_get_ecc_engine(nand);
-       if (ret) {
--              pr_err("No ECC engine found\n");
-+              if (ret != -EPROBE_DEFER)
-+                      pr_err("No ECC engine found\n");
-+
-               return ret;
-       }
---- a/drivers/mtd/nand/ecc.c
-+++ b/drivers/mtd/nand/ecc.c
-@@ -96,6 +96,12 @@
- #include <linux/module.h>
- #include <linux/mtd/nand.h>
- #include <linux/slab.h>
-+#include <linux/of.h>
-+#include <linux/of_device.h>
-+#include <linux/of_platform.h>
-+
-+static LIST_HEAD(on_host_hw_engines);
-+static DEFINE_MUTEX(on_host_hw_engines_mutex);
- /**
-  * nand_ecc_init_ctx - Init the ECC engine context
-@@ -611,6 +617,88 @@ struct nand_ecc_engine *nand_ecc_get_on_
- }
- EXPORT_SYMBOL(nand_ecc_get_on_die_hw_engine);
-+int nand_ecc_register_on_host_hw_engine(struct nand_ecc_engine *engine)
-+{
-+      struct nand_ecc_engine *item;
-+
-+      if (!engine)
-+              return -EINVAL;
-+
-+      /* Prevent multiple registrations of one engine */
-+      list_for_each_entry(item, &on_host_hw_engines, node)
-+              if (item == engine)
-+                      return 0;
-+
-+      mutex_lock(&on_host_hw_engines_mutex);
-+      list_add_tail(&engine->node, &on_host_hw_engines);
-+      mutex_unlock(&on_host_hw_engines_mutex);
-+
-+      return 0;
-+}
-+EXPORT_SYMBOL(nand_ecc_register_on_host_hw_engine);
-+
-+int nand_ecc_unregister_on_host_hw_engine(struct nand_ecc_engine *engine)
-+{
-+      if (!engine)
-+              return -EINVAL;
-+
-+      mutex_lock(&on_host_hw_engines_mutex);
-+      list_del(&engine->node);
-+      mutex_unlock(&on_host_hw_engines_mutex);
-+
-+      return 0;
-+}
-+EXPORT_SYMBOL(nand_ecc_unregister_on_host_hw_engine);
-+
-+static struct nand_ecc_engine *nand_ecc_match_on_host_hw_engine(struct device *dev)
-+{
-+      struct nand_ecc_engine *item;
-+
-+      list_for_each_entry(item, &on_host_hw_engines, node)
-+              if (item->dev == dev)
-+                      return item;
-+
-+      return NULL;
-+}
-+
-+struct nand_ecc_engine *nand_ecc_get_on_host_hw_engine(struct nand_device *nand)
-+{
-+      struct nand_ecc_engine *engine = NULL;
-+      struct device *dev = &nand->mtd.dev;
-+      struct platform_device *pdev;
-+      struct device_node *np;
-+
-+      if (list_empty(&on_host_hw_engines))
-+              return NULL;
-+
-+      /* Check for an explicit nand-ecc-engine property */
-+      np = of_parse_phandle(dev->of_node, "nand-ecc-engine", 0);
-+      if (np) {
-+              pdev = of_find_device_by_node(np);
-+              if (!pdev)
-+                      return ERR_PTR(-EPROBE_DEFER);
-+
-+              engine = nand_ecc_match_on_host_hw_engine(&pdev->dev);
-+              platform_device_put(pdev);
-+              of_node_put(np);
-+
-+              if (!engine)
-+                      return ERR_PTR(-EPROBE_DEFER);
-+      }
-+
-+      if (engine)
-+              get_device(engine->dev);
-+
-+      return engine;
-+}
-+EXPORT_SYMBOL(nand_ecc_get_on_host_hw_engine);
-+
-+void nand_ecc_put_on_host_hw_engine(struct nand_device *nand)
-+{
-+      put_device(nand->ecc.engine->dev);
-+}
-+EXPORT_SYMBOL(nand_ecc_put_on_host_hw_engine);
-+
- MODULE_LICENSE("GPL");
- MODULE_AUTHOR("Miquel Raynal <miquel.raynal@bootlin.com>");
- MODULE_DESCRIPTION("Generic ECC engine");
---- a/include/linux/mtd/nand.h
-+++ b/include/linux/mtd/nand.h
-@@ -264,11 +264,35 @@ struct nand_ecc_engine_ops {
- };
- /**
-+ * enum nand_ecc_engine_integration - How the NAND ECC engine is integrated
-+ * @NAND_ECC_ENGINE_INTEGRATION_INVALID: Invalid value
-+ * @NAND_ECC_ENGINE_INTEGRATION_PIPELINED: Pipelined engine, performs on-the-fly
-+ *                                         correction, does not need to copy
-+ *                                         data around
-+ * @NAND_ECC_ENGINE_INTEGRATION_EXTERNAL: External engine, needs to bring the
-+ *                                        data into its own area before use
-+ */
-+enum nand_ecc_engine_integration {
-+      NAND_ECC_ENGINE_INTEGRATION_INVALID,
-+      NAND_ECC_ENGINE_INTEGRATION_PIPELINED,
-+      NAND_ECC_ENGINE_INTEGRATION_EXTERNAL,
-+};
-+
-+/**
-  * struct nand_ecc_engine - ECC engine abstraction for NAND devices
-+ * @dev: Host device
-+ * @node: Private field for registration time
-  * @ops: ECC engine operations
-+ * @integration: How the engine is integrated with the host
-+ *               (only relevant on %NAND_ECC_ENGINE_TYPE_ON_HOST engines)
-+ * @priv: Private data
-  */
- struct nand_ecc_engine {
-+      struct device *dev;
-+      struct list_head node;
-       struct nand_ecc_engine_ops *ops;
-+      enum nand_ecc_engine_integration integration;
-+      void *priv;
- };
- void of_get_nand_ecc_user_config(struct nand_device *nand);
-@@ -279,8 +303,12 @@ int nand_ecc_prepare_io_req(struct nand_
- int nand_ecc_finish_io_req(struct nand_device *nand,
-                          struct nand_page_io_req *req);
- bool nand_ecc_is_strong_enough(struct nand_device *nand);
-+int nand_ecc_register_on_host_hw_engine(struct nand_ecc_engine *engine);
-+int nand_ecc_unregister_on_host_hw_engine(struct nand_ecc_engine *engine);
- struct nand_ecc_engine *nand_ecc_get_sw_engine(struct nand_device *nand);
- struct nand_ecc_engine *nand_ecc_get_on_die_hw_engine(struct nand_device *nand);
-+struct nand_ecc_engine *nand_ecc_get_on_host_hw_engine(struct nand_device *nand);
-+void nand_ecc_put_on_host_hw_engine(struct nand_device *nand);
- #if IS_ENABLED(CONFIG_MTD_NAND_ECC_SW_HAMMING)
- struct nand_ecc_engine *nand_ecc_sw_hamming_get_engine(void);