Skip to content

Commit ffb16c1

Browse files
Christophe Kerellomiquelraynal
authored andcommitted
mtd: rawnand: stm32_fmc2: Add NAND Write Protect support
This patch adds the support of the WP# signal. WP will be disabled in probe/resume callbacks and will be enabled in remove/suspend callbacks. Signed-off-by: Christophe Kerello <christophe.kerello@foss.st.com> Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com> Link: https://lore.kernel.org/linux-mtd/20220217144755.270679-3-christophe.kerello@foss.st.com
1 parent cb57fae commit ffb16c1

1 file changed

Lines changed: 39 additions & 1 deletion

File tree

drivers/mtd/nand/raw/stm32_fmc2_nand.c

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include <linux/dmaengine.h>
1010
#include <linux/dma-mapping.h>
1111
#include <linux/errno.h>
12+
#include <linux/gpio/consumer.h>
1213
#include <linux/interrupt.h>
1314
#include <linux/iopoll.h>
1415
#include <linux/mfd/syscon.h>
@@ -231,6 +232,7 @@ struct stm32_fmc2_timings {
231232

232233
struct stm32_fmc2_nand {
233234
struct nand_chip chip;
235+
struct gpio_desc *wp_gpio;
234236
struct stm32_fmc2_timings timings;
235237
int ncs;
236238
int cs_used[FMC2_MAX_CE];
@@ -1747,6 +1749,18 @@ static const struct nand_controller_ops stm32_fmc2_nfc_controller_ops = {
17471749
.setup_interface = stm32_fmc2_nfc_setup_interface,
17481750
};
17491751

1752+
static void stm32_fmc2_nfc_wp_enable(struct stm32_fmc2_nand *nand)
1753+
{
1754+
if (nand->wp_gpio)
1755+
gpiod_set_value(nand->wp_gpio, 1);
1756+
}
1757+
1758+
static void stm32_fmc2_nfc_wp_disable(struct stm32_fmc2_nand *nand)
1759+
{
1760+
if (nand->wp_gpio)
1761+
gpiod_set_value(nand->wp_gpio, 0);
1762+
}
1763+
17501764
static int stm32_fmc2_nfc_parse_child(struct stm32_fmc2_nfc *nfc,
17511765
struct device_node *dn)
17521766
{
@@ -1785,6 +1799,18 @@ static int stm32_fmc2_nfc_parse_child(struct stm32_fmc2_nfc *nfc,
17851799
nand->cs_used[i] = cs;
17861800
}
17871801

1802+
nand->wp_gpio = devm_gpiod_get_from_of_node(nfc->dev, dn,
1803+
"wp-gpios", 0,
1804+
GPIOD_OUT_HIGH, "wp");
1805+
if (IS_ERR(nand->wp_gpio)) {
1806+
ret = PTR_ERR(nand->wp_gpio);
1807+
if (ret != -ENOENT)
1808+
return dev_err_probe(nfc->dev, ret,
1809+
"failed to request WP GPIO\n");
1810+
1811+
nand->wp_gpio = NULL;
1812+
}
1813+
17881814
nand_set_flash_node(&nand->chip, dn);
17891815

17901816
return 0;
@@ -1956,10 +1982,12 @@ static int stm32_fmc2_nfc_probe(struct platform_device *pdev)
19561982
chip->options |= NAND_BUSWIDTH_AUTO | NAND_NO_SUBPAGE_WRITE |
19571983
NAND_USES_DMA;
19581984

1985+
stm32_fmc2_nfc_wp_disable(nand);
1986+
19591987
/* Scan to find existence of the device */
19601988
ret = nand_scan(chip, nand->ncs);
19611989
if (ret)
1962-
goto err_release_dma;
1990+
goto err_wp_enable;
19631991

19641992
ret = mtd_device_register(mtd, NULL, 0);
19651993
if (ret)
@@ -1972,6 +2000,9 @@ static int stm32_fmc2_nfc_probe(struct platform_device *pdev)
19722000
err_nand_cleanup:
19732001
nand_cleanup(chip);
19742002

2003+
err_wp_enable:
2004+
stm32_fmc2_nfc_wp_enable(nand);
2005+
19752006
err_release_dma:
19762007
if (nfc->dma_ecc_ch)
19772008
dma_release_channel(nfc->dma_ecc_ch);
@@ -2012,15 +2043,20 @@ static int stm32_fmc2_nfc_remove(struct platform_device *pdev)
20122043

20132044
clk_disable_unprepare(nfc->clk);
20142045

2046+
stm32_fmc2_nfc_wp_enable(nand);
2047+
20152048
return 0;
20162049
}
20172050

20182051
static int __maybe_unused stm32_fmc2_nfc_suspend(struct device *dev)
20192052
{
20202053
struct stm32_fmc2_nfc *nfc = dev_get_drvdata(dev);
2054+
struct stm32_fmc2_nand *nand = &nfc->nand;
20212055

20222056
clk_disable_unprepare(nfc->clk);
20232057

2058+
stm32_fmc2_nfc_wp_enable(nand);
2059+
20242060
pinctrl_pm_select_sleep_state(dev);
20252061

20262062
return 0;
@@ -2042,6 +2078,8 @@ static int __maybe_unused stm32_fmc2_nfc_resume(struct device *dev)
20422078

20432079
stm32_fmc2_nfc_init(nfc);
20442080

2081+
stm32_fmc2_nfc_wp_disable(nand);
2082+
20452083
for (chip_cs = 0; chip_cs < FMC2_MAX_CE; chip_cs++) {
20462084
if (!(nfc->cs_assigned & BIT(chip_cs)))
20472085
continue;

0 commit comments

Comments
 (0)