env: mmc: fix offsets relative to the end of the partition

According to the help text, you can set negative offsets to indicated
that the offset is relative to the end of the parition. But kconfig
doesn't let you specify negative hex values. I think this fell through
the cracks when converting the symbol from a '#define' to a kconfig
option.

Introduce a new boolean kconfig option to switch on the "relative to the
end" behavior.

Signed-off-by: Michael Walle <mwalle@kernel.org>
Reviewed-by: Quentin Schulz <quentin.schulz@cherry.de>
Signed-off-by: Peng Fan <peng.fan@nxp.com>
diff --git a/env/Kconfig b/env/Kconfig
index 58a0666..c30785d 100644
--- a/env/Kconfig
+++ b/env/Kconfig
@@ -231,14 +231,6 @@
 	  These two #defines specify the offset and size of the environment
 	  area within the specified MMC device.
 
-	  If offset is positive (the usual case), it is treated as relative to
-	  the start of the MMC partition. If offset is negative, it is treated
-	  as relative to the end of the MMC partition. This can be useful if
-	  your board may be fitted with different MMC devices, which have
-	  different sizes for the MMC partitions, and you always want the
-	  environment placed at the very end of the partition, to leave the
-	  maximum possible space before it, to store other data.
-
 	  These two values are in units of bytes, but must be aligned to an
 	  MMC sector boundary.
 
@@ -249,9 +241,6 @@
 	  valid backup copy in case the other copy is corrupted, e.g. due
 	  to a power failure during a "saveenv" operation.
 
-	  This value may also be positive or negative; this is handled in the
-	  same way as CONFIG_ENV_OFFSET.
-
 	  In case CONFIG_ENV_MMC_EMMC_HW_PARTITION is 1 (i.e. environment in eMMC boot
 	  partition) then setting CONFIG_ENV_OFFSET_REDUND to the same value
 	  as CONFIG_ENV_OFFSET makes use of the second eMMC boot partition for
@@ -618,9 +607,18 @@
 	  Offset from the start of the device (or partition).
 
 	  This offset may be interpreted differently depending on the chosen
-	  ENV_IS_IN_* options. For example, for ENV_IS_IN_MMC=y, this offset may
-	  be negative to indicate an offset backwards from the end of the
-	  partition. See the relevant help messages for more details.
+	  ENV_IS_IN_* options. See the relevant help messages for more details.
+
+config ENV_OFFSET_RELATIVE_END
+	bool "Offset is relative to the end of the partition"
+	depends on ENV_IS_IN_MMC
+	help
+	  Treat the environment offset as relative to the end of the MMC
+	  hardware partition. This can be useful if your board may be fitted
+	  with different MMC devices, which have different sizes for the MMC
+	  hardware partitions, and you always want the environment placed at the
+	  very end of the partition, to leave the maximum possible space before
+	  it, to store other data.
 
 config ENV_OFFSET_REDUND
 	hex "Redundant environment offset"
@@ -633,9 +631,19 @@
 	  environment location.
 
 	  This offset may be interpreted differently depending on the chosen
-	  ENV_IS_IN_* options. For example, for ENV_IS_IN_MMC=y, this offset may
-	  be negative to indicate an offset backwards from the end of the
-	  partition. See the relevant help messages for more details.
+	  ENV_IS_IN_* options. See the relevant help messages for more details.
+
+config ENV_OFFSET_REDUND_RELATIVE_END
+	bool "Offset is relative to the end of the partition"
+	depends on SYS_REDUNDAND_ENVIRONMENT
+	depends on ENV_IS_IN_MMC
+	help
+	  Treat the redundant environment offset as relative to the end of the
+	  MMC hardware partition. This can be useful if your board may be
+	  fitted with different MMC devices, which have different sizes for the
+	  MMC hardware partitions, and you always want the environment placed at
+	  the very end of the partition, to leave the maximum possible space
+	  before it, to store other data.
 
 config ENV_SIZE
 	hex "Environment Size"
diff --git a/env/mmc.c b/env/mmc.c
index 11375bd..46ffa63 100644
--- a/env/mmc.c
+++ b/env/mmc.c
@@ -29,11 +29,19 @@
 
 #else
 /* Default ENV offset when not defined in Device Tree */
+#if !defined(CONFIG_ENV_OFFSET_RELATIVE_END)
 #define ENV_MMC_OFFSET		CONFIG_ENV_OFFSET
+#else
+#define ENV_MMC_OFFSET		(-(CONFIG_ENV_OFFSET))
+#endif
 
 #if defined(CONFIG_ENV_OFFSET_REDUND)
+#if !defined(CONFIG_ENV_OFFSET_REDUND_RELATIVE_END)
 #define ENV_MMC_OFFSET_REDUND	CONFIG_ENV_OFFSET_REDUND
 #else
+#define ENV_MMC_OFFSET_REDUND	(-(CONFIG_ENV_OFFSET_REDUND))
+#endif
+#else
 #define ENV_MMC_OFFSET_REDUND	ENV_MMC_INVALID_OFFSET
 #endif
 #endif