Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 542fbaaa authored by Jean-Philippe Brucker's avatar Jean-Philippe Brucker Committed by Greg Kroah-Hartman
Browse files

mtd: cfi_cmdset_0001: Support the absence of protection registers



[ Upstream commit b359ed5184aebf9d987e54abc5dae7ac03ed29ae ]

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: default avatarJean-Philippe Brucker <jean-philippe@linaro.org>
Tested-by: default avatarSudeep Holla <sudeep.holla@arm.com>
Tested-by: default avatarCatalin Marinas <catalin.marinas@arm.com>
Signed-off-by: default avatarVignesh Raghavendra <vigneshr@ti.com>
Stable-dep-of: 565fe150624e ("mtd: cfi_cmdset_0001: Byte swap OTP info")
Signed-off-by: default avatarSasha Levin <sashal@kernel.org>
parent 1e4f431c
Loading
Loading
Loading
Loading
+8 −5
Original line number Diff line number Diff line
@@ -420,6 +420,7 @@ read_pri_intelext(struct map_info *map, __u16 adr)
		extra_size = 0;

		/* Protection Register info */
		if (extp->NumProtectionFields)
			extra_size += (extp->NumProtectionFields - 1) *
				      sizeof(struct cfi_intelext_otpinfo);
	}
@@ -695,12 +696,14 @@ 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 */
		if (extp->NumProtectionFields)
			offs = (extp->NumProtectionFields - 1) *
			       sizeof(struct cfi_intelext_otpinfo);