diff options
author | Janusz Krzysztofik <jmkrzyszt@gmail.com> | 2020-02-12 03:39:28 +0300 |
---|---|---|
committer | Miquel Raynal <miquel.raynal@bootlin.com> | 2020-03-11 18:17:53 +0300 |
commit | 2b1dcee304b67f3c4e7e2e910be90e36eef46050 (patch) | |
tree | e661137b71fbb73a4549628c04ff681caff83961 /drivers/mtd/nand/raw/ams-delta.c | |
parent | edfd8d9c763f5f91cda663e89f34dccacd8eb586 (diff) | |
download | linux-2b1dcee304b67f3c4e7e2e910be90e36eef46050.tar.xz |
mtd: rawnand: ams-delta: Make the driver custom I/O ready
In order to be merged with "gpio-nand", the driver must support custom
(non-GPIO) I/O accessors.
Allow platforms to omit data GPIO port as well as NWE pin info from
device setup. For the driver to still work on such platform, custom
I/O accessors as well as a custom probe function which initialises the
driver private structure with those accessors must be added to the
driver.
Signed-off-by: Janusz Krzysztofik <jmkrzyszt@gmail.com>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
Link: https://lore.kernel.org/linux-mtd/20200212003929.6682-14-jmkrzyszt@gmail.com
Diffstat (limited to 'drivers/mtd/nand/raw/ams-delta.c')
-rw-r--r-- | drivers/mtd/nand/raw/ams-delta.c | 32 |
1 files changed, 26 insertions, 6 deletions
diff --git a/drivers/mtd/nand/raw/ams-delta.c b/drivers/mtd/nand/raw/ams-delta.c index d8eef3dffa66..5a27170b2808 100644 --- a/drivers/mtd/nand/raw/ams-delta.c +++ b/drivers/mtd/nand/raw/ams-delta.c @@ -43,6 +43,9 @@ struct ams_delta_nand { bool data_in; unsigned int tRP; unsigned int tWP; + u8 (*io_read)(struct ams_delta_nand *this); + void (*io_write)(struct ams_delta_nand *this, + u8 byte); }; static void ams_delta_write_commit(struct ams_delta_nand *priv) @@ -116,18 +119,18 @@ static void ams_delta_write_buf(struct ams_delta_nand *priv, const u8 *buf, ams_delta_dir_output(priv, buf[i++]); while (i < len) - ams_delta_io_write(priv, buf[i++]); + priv->io_write(priv, buf[i++]); } static void ams_delta_read_buf(struct ams_delta_nand *priv, u8 *buf, int len) { int i; - if (!priv->data_in) + if (priv->data_gpiods && !priv->data_in) ams_delta_dir_input(priv); for (i = 0; i < len; i++) - buf[i] = ams_delta_io_read(priv); + buf[i] = priv->io_read(priv); } static void ams_delta_ctrl_cs(struct ams_delta_nand *priv, bool assert) @@ -289,7 +292,8 @@ static int ams_delta_init(struct platform_device *pdev) return err; } - priv->gpiod_nwe = devm_gpiod_get(&pdev->dev, "nwe", GPIOD_OUT_LOW); + priv->gpiod_nwe = devm_gpiod_get_optional(&pdev->dev, "nwe", + GPIOD_OUT_LOW); if (IS_ERR(priv->gpiod_nwe)) { err = PTR_ERR(priv->gpiod_nwe); dev_err(&pdev->dev, "NWE GPIO request failed (%d)\n", err); @@ -311,13 +315,24 @@ static int ams_delta_init(struct platform_device *pdev) } /* Request array of data pins, initialize them as input */ - priv->data_gpiods = devm_gpiod_get_array(&pdev->dev, "data", GPIOD_IN); + priv->data_gpiods = devm_gpiod_get_array_optional(&pdev->dev, "data", + GPIOD_IN); if (IS_ERR(priv->data_gpiods)) { err = PTR_ERR(priv->data_gpiods); dev_err(&pdev->dev, "data GPIO request failed: %d\n", err); return err; } - priv->data_in = true; + if (priv->data_gpiods) { + if (!priv->gpiod_nwe) { + dev_err(&pdev->dev, + "mandatory NWE pin not provided by platform\n"); + return -ENODEV; + } + + priv->io_read = ams_delta_io_read; + priv->io_write = ams_delta_io_write; + priv->data_in = true; + } if (pdev->id_entry) probe = (void *) pdev->id_entry->driver_data; @@ -328,6 +343,11 @@ static int ams_delta_init(struct platform_device *pdev) if (err) return err; + if (!priv->io_read || !priv->io_write) { + dev_err(&pdev->dev, "incomplete device configuration\n"); + return -ENODEV; + } + /* Initialize the NAND controller object embedded in ams_delta_nand. */ priv->base.ops = &ams_delta_ops; nand_controller_init(&priv->base); |