From d6c831e0e5a0ef97eb054dd3eb382d66b1bffc40 Mon Sep 17 00:00:00 2001 From: Victor Shyba Date: Tue, 20 Dec 2016 05:19:08 -0300 Subject: generic: mtd: backport SPI_NOR_HAS_LOCK This flag was added to 4.9 with upstream commit 76a4707de5e18dc32d9cb4e990686140c5664a15. Signed-off-by: Victor Shyba [refresh and adjust platform patches, fix commit message] Signed-off-by: Mathias Kresin --- ...mtd-backport-v4.7-0day-patches-from-Boris.patch | 62 +++++++++------------- ...0074-mtd-nand-import-nand_hw_control_init.patch | 51 +++++------------- 2 files changed, 36 insertions(+), 77 deletions(-) (limited to 'target/linux/oxnas') diff --git a/target/linux/oxnas/patches-4.4/0072-mtd-backport-v4.7-0day-patches-from-Boris.patch b/target/linux/oxnas/patches-4.4/0072-mtd-backport-v4.7-0day-patches-from-Boris.patch index 2fbbd774c9..b45d3aa579 100644 --- a/target/linux/oxnas/patches-4.4/0072-mtd-backport-v4.7-0day-patches-from-Boris.patch +++ b/target/linux/oxnas/patches-4.4/0072-mtd-backport-v4.7-0day-patches-from-Boris.patch @@ -3942,7 +3942,7 @@ Signed-off-by: John Crispin struct flash_info { char *name; -@@ -60,14 +61,20 @@ struct flash_info { +@@ -60,15 +61,20 @@ struct flash_info { u16 addr_width; u16 flags; @@ -3954,6 +3954,7 @@ Signed-off-by: John Crispin -#define SPI_NOR_DUAL_READ 0x20 /* Flash supports Dual Read */ -#define SPI_NOR_QUAD_READ 0x40 /* Flash supports Quad Read */ -#define USE_FSR 0x80 /* use flag status register */ +-#define SPI_NOR_HAS_LOCK 0x100 /* Flash supports lock/unlock via SR */ +#define SECT_4K BIT(0) /* SPINOR_OP_BE_4K works uniformly */ +#define SPI_NOR_NO_ERASE BIT(1) /* No erase command needed */ +#define SST_WRITE BIT(2) /* use SST byte programming */ @@ -3971,7 +3972,7 @@ Signed-off-by: John Crispin }; #define JEDEC_MFR(info) ((info)->id[0]) -@@ -313,6 +320,29 @@ static void spi_nor_unlock_and_unprep(st +@@ -314,6 +320,29 @@ static void spi_nor_unlock_and_unprep(st } /* @@ -4001,7 +4002,7 @@ Signed-off-by: John Crispin * Erase an address range on the nor chip. The address range may extend * one or more erase sectors. Return an error is there is a problem erasing. */ -@@ -371,10 +401,9 @@ static int spi_nor_erase(struct mtd_info +@@ -372,10 +401,9 @@ static int spi_nor_erase(struct mtd_info while (len) { write_enable(nor); @@ -4014,7 +4015,7 @@ Signed-off-by: John Crispin addr += mtd->erasesize; len -= mtd->erasesize; -@@ -387,17 +416,13 @@ static int spi_nor_erase(struct mtd_info +@@ -388,17 +416,13 @@ static int spi_nor_erase(struct mtd_info write_disable(nor); @@ -4034,7 +4035,7 @@ Signed-off-by: John Crispin } static void stm_get_locked_range(struct spi_nor *nor, u8 sr, loff_t *ofs, -@@ -415,32 +440,58 @@ static void stm_get_locked_range(struct +@@ -416,32 +440,58 @@ static void stm_get_locked_range(struct } else { pow = ((sr & mask) ^ mask) >> shift; *len = mtd->size >> pow; @@ -4100,7 +4101,7 @@ Signed-off-by: John Crispin * Sample table portion for 8MB flash (Winbond w25q64fw): * * SEC | TB | BP2 | BP1 | BP0 | Prot Length | Protected Portion -@@ -453,26 +504,55 @@ static int stm_is_locked_sr(struct spi_n +@@ -454,26 +504,55 @@ static int stm_is_locked_sr(struct spi_n * 0 | 0 | 1 | 0 | 1 | 2 MB | Upper 1/4 * 0 | 0 | 1 | 1 | 0 | 4 MB | Upper 1/2 * X | X | 1 | 1 | 1 | 8 MB | ALL @@ -4165,7 +4166,7 @@ Signed-off-by: John Crispin /* * Need smallest pow such that: -@@ -483,7 +563,7 @@ static int stm_lock(struct spi_nor *nor, +@@ -484,7 +563,7 @@ static int stm_lock(struct spi_nor *nor, * * pow = ceil(log2(size / len)) = log2(size) - floor(log2(len)) */ @@ -4174,7 +4175,7 @@ Signed-off-by: John Crispin val = mask - (pow << shift); if (val & ~mask) return -EINVAL; -@@ -491,14 +571,27 @@ static int stm_lock(struct spi_nor *nor, +@@ -492,14 +571,27 @@ static int stm_lock(struct spi_nor *nor, if (!(val & mask)) return -EINVAL; @@ -4205,7 +4206,7 @@ Signed-off-by: John Crispin } /* -@@ -509,17 +602,43 @@ static int stm_lock(struct spi_nor *nor, +@@ -510,17 +602,43 @@ static int stm_lock(struct spi_nor *nor, static int stm_unlock(struct spi_nor *nor, loff_t ofs, uint64_t len) { struct mtd_info *mtd = &nor->mtd; @@ -4253,7 +4254,7 @@ Signed-off-by: John Crispin /* * Need largest pow such that: * -@@ -529,8 +648,8 @@ static int stm_unlock(struct spi_nor *no +@@ -530,8 +648,8 @@ static int stm_unlock(struct spi_nor *no * * pow = floor(log2(size / len)) = log2(size) - ceil(log2(len)) */ @@ -4264,7 +4265,7 @@ Signed-off-by: John Crispin val = 0; /* fully unlocked */ } else { val = mask - (pow << shift); -@@ -539,14 +658,28 @@ static int stm_unlock(struct spi_nor *no +@@ -540,14 +658,28 @@ static int stm_unlock(struct spi_nor *no return -EINVAL; } @@ -4296,7 +4297,7 @@ Signed-off-by: John Crispin } /* -@@ -736,8 +869,8 @@ static const struct flash_info spi_nor_i +@@ -737,8 +869,8 @@ static const struct flash_info spi_nor_i { "n25q032a", INFO(0x20bb16, 0, 64 * 1024, 64, SPI_NOR_QUAD_READ) }, { "n25q064", INFO(0x20ba17, 0, 64 * 1024, 128, SECT_4K | SPI_NOR_QUAD_READ) }, { "n25q064a", INFO(0x20bb17, 0, 64 * 1024, 128, SECT_4K | SPI_NOR_QUAD_READ) }, @@ -4307,7 +4308,7 @@ Signed-off-by: John Crispin { "n25q256a", INFO(0x20ba19, 0, 64 * 1024, 512, SECT_4K | SPI_NOR_QUAD_READ) }, { "n25q512a", INFO(0x20bb20, 0, 64 * 1024, 1024, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ) }, { "n25q512ax3", INFO(0x20ba20, 0, 64 * 1024, 1024, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ) }, -@@ -771,6 +904,7 @@ static const struct flash_info spi_nor_i +@@ -772,6 +904,7 @@ static const struct flash_info spi_nor_i { "s25fl008k", INFO(0xef4014, 0, 64 * 1024, 16, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, { "s25fl016k", INFO(0xef4015, 0, 64 * 1024, 32, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, { "s25fl064k", INFO(0xef4017, 0, 64 * 1024, 128, SECT_4K) }, @@ -4315,7 +4316,7 @@ Signed-off-by: John Crispin { "s25fl132k", INFO(0x014016, 0, 64 * 1024, 64, SECT_4K) }, { "s25fl164k", INFO(0x014017, 0, 64 * 1024, 128, SECT_4K) }, { "s25fl204k", INFO(0x014013, 0, 64 * 1024, 8, SECT_4K | SPI_NOR_DUAL_READ) }, -@@ -834,11 +968,23 @@ static const struct flash_info spi_nor_i +@@ -835,11 +968,23 @@ static const struct flash_info spi_nor_i { "w25x16", INFO(0xef3015, 0, 64 * 1024, 32, SECT_4K) }, { "w25x32", INFO(0xef3016, 0, 64 * 1024, 64, SECT_4K) }, { "w25q32", INFO(0xef4016, 0, 64 * 1024, 64, SECT_4K) }, @@ -4342,7 +4343,7 @@ Signed-off-by: John Crispin { "w25q80", INFO(0xef5014, 0, 64 * 1024, 16, SECT_4K) }, { "w25q80bl", INFO(0xef4014, 0, 64 * 1024, 16, SECT_4K) }, { "w25q128", INFO(0xef4018, 0, 64 * 1024, 256, SECT_4K) }, -@@ -861,7 +1007,7 @@ static const struct flash_info *spi_nor_ +@@ -862,7 +1007,7 @@ static const struct flash_info *spi_nor_ tmp = nor->read_reg(nor, SPINOR_OP_RDID, id, SPI_NOR_MAX_ID_LEN); if (tmp < 0) { @@ -4351,7 +4352,7 @@ Signed-off-by: John Crispin return ERR_PTR(tmp); } -@@ -872,7 +1018,7 @@ static const struct flash_info *spi_nor_ +@@ -873,7 +1018,7 @@ static const struct flash_info *spi_nor_ return &spi_nor_ids[tmp]; } } @@ -4360,7 +4361,7 @@ Signed-off-by: John Crispin id[0], id[1], id[2]); return ERR_PTR(-ENODEV); } -@@ -1018,6 +1164,8 @@ static int macronix_quad_enable(struct s +@@ -1019,6 +1164,8 @@ static int macronix_quad_enable(struct s int ret, val; val = read_sr(nor); @@ -4369,7 +4370,7 @@ Signed-off-by: John Crispin write_enable(nor); write_sr(nor, val | SR_QUAD_EN_MX); -@@ -1099,7 +1247,7 @@ static int set_quad_mode(struct spi_nor +@@ -1100,7 +1247,7 @@ static int set_quad_mode(struct spi_nor static int spi_nor_check(struct spi_nor *nor) { if (!nor->dev || !nor->read || !nor->write || @@ -4378,7 +4379,7 @@ Signed-off-by: John Crispin pr_err("spi-nor: please fill all the necessary fields!\n"); return -EINVAL; } -@@ -1112,7 +1260,7 @@ int spi_nor_scan(struct spi_nor *nor, co +@@ -1113,7 +1260,7 @@ int spi_nor_scan(struct spi_nor *nor, co const struct flash_info *info = NULL; struct device *dev = nor->dev; struct mtd_info *mtd = &nor->mtd; @@ -4387,30 +4388,15 @@ Signed-off-by: John Crispin int ret; int i; -@@ -1162,9 +1310,11 @@ int spi_nor_scan(struct spi_nor *nor, co - if (JEDEC_MFR(info) == SNOR_MFR_ATMEL || - JEDEC_MFR(info) == SNOR_MFR_INTEL || - JEDEC_MFR(info) == SNOR_MFR_MACRONIX || -- JEDEC_MFR(info) == SNOR_MFR_SST) { -+ JEDEC_MFR(info) == SNOR_MFR_SST || -+ info->flags & SPI_NOR_HAS_LOCK) { +@@ -1167,6 +1314,7 @@ int spi_nor_scan(struct spi_nor *nor, co + info->flags & SPI_NOR_HAS_LOCK) { write_enable(nor); write_sr(nor, 0); + spi_nor_wait_till_ready(nor); } if (!mtd->name) -@@ -1178,7 +1328,8 @@ int spi_nor_scan(struct spi_nor *nor, co - mtd->_read = spi_nor_read; - - /* NOR protection support for STmicro/Micron chips and similar */ -- if (JEDEC_MFR(info) == SNOR_MFR_MICRON) { -+ if (JEDEC_MFR(info) == SNOR_MFR_MICRON || -+ info->flags & SPI_NOR_HAS_LOCK) { - nor->flash_lock = stm_lock; - nor->flash_unlock = stm_unlock; - nor->flash_is_locked = stm_is_locked; -@@ -1198,6 +1349,8 @@ int spi_nor_scan(struct spi_nor *nor, co +@@ -1201,6 +1349,8 @@ int spi_nor_scan(struct spi_nor *nor, co if (info->flags & USE_FSR) nor->flags |= SNOR_F_USE_FSR; @@ -4419,7 +4405,7 @@ Signed-off-by: John Crispin #ifdef CONFIG_MTD_SPI_NOR_USE_4K_SECTORS /* prefer "small sector" erase if possible */ -@@ -1300,6 +1453,12 @@ int spi_nor_scan(struct spi_nor *nor, co +@@ -1303,6 +1453,12 @@ int spi_nor_scan(struct spi_nor *nor, co nor->addr_width = 3; } diff --git a/target/linux/oxnas/patches-4.4/0074-mtd-nand-import-nand_hw_control_init.patch b/target/linux/oxnas/patches-4.4/0074-mtd-nand-import-nand_hw_control_init.patch index 6f1979b11b..4b3260c41b 100644 --- a/target/linux/oxnas/patches-4.4/0074-mtd-nand-import-nand_hw_control_init.patch +++ b/target/linux/oxnas/patches-4.4/0074-mtd-nand-import-nand_hw_control_init.patch @@ -25,11 +25,9 @@ Signed-off-by: Boris Brezillon include/linux/mtd/nand.h | 7 +++++++ 14 files changed, 20 insertions(+), 26 deletions(-) -diff --git a/drivers/mtd/nand/bf5xx_nand.c b/drivers/mtd/nand/bf5xx_nand.c -index 37da423..3962f55 100644 --- a/drivers/mtd/nand/bf5xx_nand.c +++ b/drivers/mtd/nand/bf5xx_nand.c -@@ -761,8 +761,7 @@ static int bf5xx_nand_probe(struct platform_device *pdev) +@@ -748,8 +748,7 @@ static int bf5xx_nand_probe(struct platf platform_set_drvdata(pdev, info); @@ -39,11 +37,9 @@ index 37da423..3962f55 100644 info->device = &pdev->dev; info->platform = plat; -diff --git a/drivers/mtd/nand/brcmnand/brcmnand.c b/drivers/mtd/nand/brcmnand/brcmnand.c -index 8eb2c64..82ec36b 100644 --- a/drivers/mtd/nand/brcmnand/brcmnand.c +++ b/drivers/mtd/nand/brcmnand/brcmnand.c -@@ -2370,8 +2370,7 @@ int brcmnand_probe(struct platform_device *pdev, struct brcmnand_soc *soc) +@@ -2156,8 +2156,7 @@ int brcmnand_probe(struct platform_devic init_completion(&ctrl->done); init_completion(&ctrl->dma_done); @@ -53,11 +49,9 @@ index 8eb2c64..82ec36b 100644 INIT_LIST_HEAD(&ctrl->host_list); /* NAND register range */ -diff --git a/drivers/mtd/nand/docg4.c b/drivers/mtd/nand/docg4.c -index 4731699..7af2a3c 100644 --- a/drivers/mtd/nand/docg4.c +++ b/drivers/mtd/nand/docg4.c -@@ -1249,8 +1249,7 @@ static void __init init_mtd_structs(struct mtd_info *mtd) +@@ -1227,8 +1227,7 @@ static void __init init_mtd_structs(stru nand->options = NAND_BUSWIDTH_16 | NAND_NO_SUBPAGE_WRITE; nand->IO_ADDR_R = nand->IO_ADDR_W = doc->virtadr + DOC_IOSPACE_DATA; nand->controller = &nand->hwcontrol; @@ -67,11 +61,9 @@ index 4731699..7af2a3c 100644 /* methods */ nand->cmdfunc = docg4_command; -diff --git a/drivers/mtd/nand/fsl_elbc_nand.c b/drivers/mtd/nand/fsl_elbc_nand.c -index 60a88f2..113f76e 100644 --- a/drivers/mtd/nand/fsl_elbc_nand.c +++ b/drivers/mtd/nand/fsl_elbc_nand.c -@@ -879,8 +879,7 @@ static int fsl_elbc_nand_probe(struct platform_device *pdev) +@@ -866,8 +866,7 @@ static int fsl_elbc_nand_probe(struct pl } elbc_fcm_ctrl->counter++; @@ -81,11 +73,9 @@ index 60a88f2..113f76e 100644 fsl_lbc_ctrl_dev->nand = elbc_fcm_ctrl; } else { elbc_fcm_ctrl = fsl_lbc_ctrl_dev->nand; -diff --git a/drivers/mtd/nand/fsl_ifc_nand.c b/drivers/mtd/nand/fsl_ifc_nand.c -index 4e9e5fd..0a177b1 100644 --- a/drivers/mtd/nand/fsl_ifc_nand.c +++ b/drivers/mtd/nand/fsl_ifc_nand.c -@@ -987,8 +987,7 @@ static int fsl_ifc_nand_probe(struct platform_device *dev) +@@ -1073,8 +1073,7 @@ static int fsl_ifc_nand_probe(struct pla ifc_nand_ctrl->addr = NULL; fsl_ifc_ctrl_dev->nand = ifc_nand_ctrl; @@ -95,11 +85,9 @@ index 4e9e5fd..0a177b1 100644 } else { ifc_nand_ctrl = fsl_ifc_ctrl_dev->nand; } -diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c -index 77533f7..53ea796 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c -@@ -3191,8 +3191,7 @@ static void nand_set_defaults(struct nand_chip *chip, int busw) +@@ -3202,8 +3202,7 @@ static void nand_set_defaults(struct nan if (!chip->controller) { chip->controller = &chip->hwcontrol; @@ -109,11 +97,9 @@ index 77533f7..53ea796 100644 } } -diff --git a/drivers/mtd/nand/ndfc.c b/drivers/mtd/nand/ndfc.c -index 218c789..28e6118 100644 --- a/drivers/mtd/nand/ndfc.c +++ b/drivers/mtd/nand/ndfc.c -@@ -218,8 +218,7 @@ static int ndfc_probe(struct platform_device *ofdev) +@@ -220,8 +220,7 @@ static int ndfc_probe(struct platform_de ndfc = &ndfc_ctrl[cs]; ndfc->chip_select = cs; @@ -123,11 +109,9 @@ index 218c789..28e6118 100644 ndfc->ofdev = ofdev; dev_set_drvdata(&ofdev->dev, ndfc); -diff --git a/drivers/mtd/nand/pxa3xx_nand.c b/drivers/mtd/nand/pxa3xx_nand.c -index 436dd6d..b121bf4 100644 --- a/drivers/mtd/nand/pxa3xx_nand.c +++ b/drivers/mtd/nand/pxa3xx_nand.c -@@ -1810,8 +1810,7 @@ static int alloc_nand_resource(struct platform_device *pdev) +@@ -1739,8 +1739,7 @@ static int alloc_nand_resource(struct pl chip->cmdfunc = nand_cmdfunc; } @@ -137,11 +121,9 @@ index 436dd6d..b121bf4 100644 info->clk = devm_clk_get(&pdev->dev, NULL); if (IS_ERR(info->clk)) { dev_err(&pdev->dev, "failed to get nand clock\n"); -diff --git a/drivers/mtd/nand/s3c2410.c b/drivers/mtd/nand/s3c2410.c -index d9309cf..b1734d7 100644 --- a/drivers/mtd/nand/s3c2410.c +++ b/drivers/mtd/nand/s3c2410.c -@@ -977,8 +977,7 @@ static int s3c24xx_nand_probe(struct platform_device *pdev) +@@ -955,8 +955,7 @@ static int s3c24xx_nand_probe(struct pla platform_set_drvdata(pdev, info); @@ -151,11 +133,9 @@ index d9309cf..b1734d7 100644 /* get the clock source and enable it */ -diff --git a/drivers/mtd/nand/sunxi_nand.c b/drivers/mtd/nand/sunxi_nand.c -index e414b31..8b5dadc 100644 --- a/drivers/mtd/nand/sunxi_nand.c +++ b/drivers/mtd/nand/sunxi_nand.c -@@ -2175,8 +2175,7 @@ static int sunxi_nfc_probe(struct platform_device *pdev) +@@ -1426,8 +1426,7 @@ static int sunxi_nfc_probe(struct platfo return -ENOMEM; nfc->dev = dev; @@ -165,11 +145,9 @@ index e414b31..8b5dadc 100644 INIT_LIST_HEAD(&nfc->chips); r = platform_get_resource(pdev, IORESOURCE_MEM, 0); -diff --git a/drivers/mtd/nand/txx9ndfmc.c b/drivers/mtd/nand/txx9ndfmc.c -index 04d63f5..0a14fda 100644 --- a/drivers/mtd/nand/txx9ndfmc.c +++ b/drivers/mtd/nand/txx9ndfmc.c -@@ -303,8 +303,7 @@ static int __init txx9ndfmc_probe(struct platform_device *dev) +@@ -304,8 +304,7 @@ static int __init txx9ndfmc_probe(struct dev_info(&dev->dev, "CLK:%ldMHz HOLD:%d SPW:%d\n", (gbusclk + 500000) / 1000000, hold, spw); @@ -179,11 +157,9 @@ index 04d63f5..0a14fda 100644 platform_set_drvdata(dev, drvdata); txx9ndfmc_initialize(dev); -diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h -index 8dd6e01..f6a2d5e 100644 --- a/include/linux/mtd/nand.h +++ b/include/linux/mtd/nand.h -@@ -460,6 +460,13 @@ struct nand_hw_control { +@@ -461,6 +461,13 @@ struct nand_hw_control { wait_queue_head_t wq; }; @@ -197,6 +173,3 @@ index 8dd6e01..f6a2d5e 100644 /** * struct nand_ecc_ctrl - Control structure for ECC * @mode: ECC mode --- -2.10.2 - -- cgit v1.2.3