29b62880abd31632c11512ed45d1543ff8a31c02
[openwrt/staging/ansuel.git] /
1 From 784866bc4f9f25e0494b77750f95af2a2619e498 Mon Sep 17 00:00:00 2001
2 From: Miquel Raynal <miquel.raynal@bootlin.com>
3 Date: Thu, 16 Dec 2021 12:16:41 +0100
4 Subject: [PATCH 03/15] mtd: nand: ecc: Provide a helper to retrieve a
5 pilelined engine device
6
7 In a pipelined engine situation, we might either have the host which
8 internally has support for error correction, or have it using an
9 external hardware block for this purpose. In the former case, the host
10 is also the ECC engine. In the latter case, it is not. In order to get
11 the right pointers on the right devices (for example: in order to devm_*
12 allocate variables), let's introduce this helper which can safely be
13 called by pipelined ECC engines in order to retrieve the right device
14 structure.
15
16 Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
17 Link: https://lore.kernel.org/linux-mtd/20211216111654.238086-16-miquel.raynal@bootlin.com
18 (cherry picked from commit 5145abeb0649acf810a32e63bd762e617a9b3309)
19 ---
20 drivers/mtd/nand/ecc.c | 31 +++++++++++++++++++++++++++++++
21 include/linux/mtd/nand.h | 1 +
22 2 files changed, 32 insertions(+)
23
24 --- a/drivers/mtd/nand/ecc.c
25 +++ b/drivers/mtd/nand/ecc.c
26 @@ -699,6 +699,37 @@ void nand_ecc_put_on_host_hw_engine(stru
27 }
28 EXPORT_SYMBOL(nand_ecc_put_on_host_hw_engine);
29
30 +/*
31 + * In the case of a pipelined engine, the device registering the ECC
32 + * engine is not necessarily the ECC engine itself but may be a host controller.
33 + * It is then useful to provide a helper to retrieve the right device object
34 + * which actually represents the ECC engine.
35 + */
36 +struct device *nand_ecc_get_engine_dev(struct device *host)
37 +{
38 + struct platform_device *ecc_pdev;
39 + struct device_node *np;
40 +
41 + /*
42 + * If the device node contains this property, it means we need to follow
43 + * it in order to get the right ECC engine device we are looking for.
44 + */
45 + np = of_parse_phandle(host->of_node, "nand-ecc-engine", 0);
46 + if (!np)
47 + return host;
48 +
49 + ecc_pdev = of_find_device_by_node(np);
50 + if (!ecc_pdev) {
51 + of_node_put(np);
52 + return NULL;
53 + }
54 +
55 + platform_device_put(ecc_pdev);
56 + of_node_put(np);
57 +
58 + return &ecc_pdev->dev;
59 +}
60 +
61 MODULE_LICENSE("GPL");
62 MODULE_AUTHOR("Miquel Raynal <miquel.raynal@bootlin.com>");
63 MODULE_DESCRIPTION("Generic ECC engine");
64 --- a/include/linux/mtd/nand.h
65 +++ b/include/linux/mtd/nand.h
66 @@ -309,6 +309,7 @@ struct nand_ecc_engine *nand_ecc_get_sw_
67 struct nand_ecc_engine *nand_ecc_get_on_die_hw_engine(struct nand_device *nand);
68 struct nand_ecc_engine *nand_ecc_get_on_host_hw_engine(struct nand_device *nand);
69 void nand_ecc_put_on_host_hw_engine(struct nand_device *nand);
70 +struct device *nand_ecc_get_engine_dev(struct device *host);
71
72 #if IS_ENABLED(CONFIG_MTD_NAND_ECC_SW_HAMMING)
73 struct nand_ecc_engine *nand_ecc_sw_hamming_get_engine(void);