aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mtd/chips/cfi_cmdset_0001.c
diff options
context:
space:
mode:
authorJean-Philippe Brucker <jean-philippe@linaro.org>2020-04-17 16:23:26 +0200
committerVignesh Raghavendra <vigneshr@ti.com>2020-04-30 23:42:57 +0530
commitb359ed5184aebf9d987e54abc5dae7ac03ed29ae (patch)
tree1f759caf05875f0c88a400bb93e86c08d5e93aa4 /drivers/mtd/chips/cfi_cmdset_0001.c
parentLinux 5.7-rc2 (diff)
downloadlinux-dev-b359ed5184aebf9d987e54abc5dae7ac03ed29ae.tar.xz
linux-dev-b359ed5184aebf9d987e54abc5dae7ac03ed29ae.zip
mtd: cfi_cmdset_0001: Support the absence of protection registers
The flash controller implemented by the Arm Base platform behaves like the Intel StrataFlash J3 device, but omits several features. In particular it doesn't implement a protection register, so "Number of Protection register fields" in the Primary Vendor-Specific Extended Query, is 0. The Intel StrataFlash J3 datasheet only lists 1 as a valid value for NumProtectionFields. It describes the field as: "Number of Protection register fields in JEDEC ID space. “00h,” indicates that 256 protection bytes are available" While a value of 0 may arguably not be architecturally valid, the driver's current behavior is certainly wrong: if NumProtectionFields is 0, read_pri_intelext() adds a negative value to the unsigned extra_size, and ends up in an infinite loop. Fix it by ignoring a NumProtectionFields of 0. Signed-off-by: Jean-Philippe Brucker <jean-philippe@linaro.org> Tested-by: Sudeep Holla <sudeep.holla@arm.com> Tested-by: Catalin Marinas <catalin.marinas@arm.com> Signed-off-by: Vignesh Raghavendra <vigneshr@ti.com>
Diffstat (limited to '')
-rw-r--r--drivers/mtd/chips/cfi_cmdset_0001.c13
1 files changed, 8 insertions, 5 deletions
diff --git a/drivers/mtd/chips/cfi_cmdset_0001.c b/drivers/mtd/chips/cfi_cmdset_0001.c
index 142c0f9485fe..42001c49833b 100644
--- a/drivers/mtd/chips/cfi_cmdset_0001.c
+++ b/drivers/mtd/chips/cfi_cmdset_0001.c
@@ -420,8 +420,9 @@ read_pri_intelext(struct map_info *map, __u16 adr)
extra_size = 0;
/* Protection Register info */
- extra_size += (extp->NumProtectionFields - 1) *
- sizeof(struct cfi_intelext_otpinfo);
+ if (extp->NumProtectionFields)
+ extra_size += (extp->NumProtectionFields - 1) *
+ sizeof(struct cfi_intelext_otpinfo);
}
if (extp->MinorVersion >= '1') {
@@ -695,14 +696,16 @@ static int cfi_intelext_partition_fixup(struct mtd_info *mtd,
*/
if (extp && extp->MajorVersion == '1' && extp->MinorVersion >= '3'
&& extp->FeatureSupport & (1 << 9)) {
+ int offs = 0;
struct cfi_private *newcfi;
struct flchip *chip;
struct flchip_shared *shared;
- int offs, numregions, numparts, partshift, numvirtchips, i, j;
+ int numregions, numparts, partshift, numvirtchips, i, j;
/* Protection Register info */
- offs = (extp->NumProtectionFields - 1) *
- sizeof(struct cfi_intelext_otpinfo);
+ if (extp->NumProtectionFields)
+ offs = (extp->NumProtectionFields - 1) *
+ sizeof(struct cfi_intelext_otpinfo);
/* Burst Read info */
offs += extp->extra[offs+1]+2;