summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiquel Raynal <miquel.raynal@bootlin.com>2021-05-26 11:32:40 +0200
committerMiquel Raynal <miquel.raynal@bootlin.com>2021-05-26 16:26:32 +0200
commitb85c943d181ac58e3a34a5f79c73d421f4da7b00 (patch)
tree97fcc5ffc019c5599f47a96d4d89635f1584032c
parent10e96f8b4e7521197a50b370ce0923ab6a8d0ca0 (diff)
mtd: rawnand: Add a helper to parse the gpio-cs DT property
New chips may feature a lot of CS because of their extended length. As many controllers have been designed a decade ago, they usually only feature just a couple. This does not mean that the entire range of these chips cannot be accessed: it is just a matter of adding more GPIO CS in the hardware design. A DT property has been added to describe the CS array: cs-gpios. Here is the code parsing it this new property, allocating what needs to be, requesting the GPIOs and returning an array with the additional available CS. The first entries of this array are left empty and are reserved for native CS. Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com> Link: https://lore.kernel.org/linux-mtd/20210526093242.183847-3-miquel.raynal@bootlin.com
-rw-r--r--drivers/mtd/nand/raw/nand_base.c39
-rw-r--r--include/linux/mtd/rawnand.h4
2 files changed, 43 insertions, 0 deletions
diff --git a/drivers/mtd/nand/raw/nand_base.c b/drivers/mtd/nand/raw/nand_base.c
index 22974a53077f..57a583149cc0 100644
--- a/drivers/mtd/nand/raw/nand_base.c
+++ b/drivers/mtd/nand/raw/nand_base.c
@@ -42,6 +42,7 @@
#include <linux/io.h>
#include <linux/mtd/partitions.h>
#include <linux/of.h>
+#include <linux/of_gpio.h>
#include <linux/gpio/consumer.h>
#include "internals.h"
@@ -5249,6 +5250,44 @@ static int of_get_nand_secure_regions(struct nand_chip *chip)
return 0;
}
+/**
+ * rawnand_dt_parse_gpio_cs - Parse the gpio-cs property of a controller
+ * @dev: Device that will be parsed. Also used for managed allocations.
+ * @cs_array: Array of GPIO desc pointers allocated on success
+ * @ncs_array: Number of entries in @cs_array updated on success.
+ * @return 0 on success, an error otherwise.
+ */
+int rawnand_dt_parse_gpio_cs(struct device *dev, struct gpio_desc ***cs_array,
+ unsigned int *ncs_array)
+{
+ struct device_node *np = dev->of_node;
+ struct gpio_desc **descs;
+ int ndescs, i;
+
+ ndescs = of_gpio_named_count(np, "cs-gpios");
+ if (ndescs < 0) {
+ dev_dbg(dev, "No valid cs-gpios property\n");
+ return 0;
+ }
+
+ descs = devm_kcalloc(dev, ndescs, sizeof(*descs), GFP_KERNEL);
+ if (!descs)
+ return -ENOMEM;
+
+ for (i = 0; i < ndescs; i++) {
+ descs[i] = gpiod_get_index_optional(dev, "cs", i,
+ GPIOD_OUT_HIGH);
+ if (IS_ERR(descs[i]))
+ return PTR_ERR(descs[i]);
+ }
+
+ *ncs_array = ndescs;
+ *cs_array = descs;
+
+ return 0;
+}
+EXPORT_SYMBOL(rawnand_dt_parse_gpio_cs);
+
static int rawnand_dt_init(struct nand_chip *chip)
{
struct nand_device *nand = mtd_to_nanddev(nand_to_mtd(chip));
diff --git a/include/linux/mtd/rawnand.h b/include/linux/mtd/rawnand.h
index d41d39360fff..b2f9dd3cbd69 100644
--- a/include/linux/mtd/rawnand.h
+++ b/include/linux/mtd/rawnand.h
@@ -1595,4 +1595,8 @@ static inline void *nand_get_data_buf(struct nand_chip *chip)
return chip->data_buf;
}
+/* Parse the gpio-cs property */
+int rawnand_dt_parse_gpio_cs(struct device *dev, struct gpio_desc ***cs_array,
+ unsigned int *ncs_array);
+
#endif /* __LINUX_MTD_RAWNAND_H */