From: Uwe Kleine-König <u.kleine-koe...@pengutronix.de>

This handler updates the non-active MMC boot partition and after a
successful update makes the updated partition the active one. This way
the machine should continue to be bootable when the update fails.

Signed-off-by: Uwe Kleine-König <u.kleine-koe...@pengutronix.de>
---
 arch/arm/mach-imx/imx-bbu-internal.c | 71 ++++++++++++++++++++++++++++++++++++
 1 file changed, 71 insertions(+)

diff --git a/arch/arm/mach-imx/imx-bbu-internal.c 
b/arch/arm/mach-imx/imx-bbu-internal.c
index 254ccb6369e6..c8a8b5b689fc 100644
--- a/arch/arm/mach-imx/imx-bbu-internal.c
+++ b/arch/arm/mach-imx/imx-bbu-internal.c
@@ -29,6 +29,7 @@
 #include <linux/mtd/mtd-abi.h>
 #include <linux/stat.h>
 #include <ioctl.h>
+#include <environment.h>
 #include <mach/bbu.h>
 
 #define FLASH_HEADER_OFFSET_MMC                0x400
@@ -369,6 +370,63 @@ static int imx_bbu_internal_v2_update(struct bbu_handler 
*handler, struct bbu_da
        return ret;
 }
 
+static int imx_bbu_internal_v2_mmcboot_update(struct bbu_handler *handler,
+                                             struct bbu_data *data)
+{
+       struct imx_internal_bbu_handler *imx_handler =
+               container_of(handler, struct imx_internal_bbu_handler, handler);
+       int ret;
+       uint32_t *barker;
+       char *bootpartvar;
+       const char *bootpart;
+       char *devicefile;
+
+       barker = data->image + imx_handler->flash_header_offset;
+
+       if (*barker != IVT_BARKER) {
+               printf("Board does not provide DCD data and this image is no 
imximage\n");
+               return -EINVAL;
+       }
+
+       ret = asprintf(&bootpartvar, "%s.boot", data->devicefile);
+       if (ret < 0) {
+               printf("Failed to allocate string for boot variable\n");
+               return ret;
+       }
+
+       bootpart = getenv(bootpartvar);
+
+       if (!strcmp(bootpart, "boot0")) {
+               bootpart = "boot1";
+       } else {
+               bootpart = "boot0";
+       }
+
+       ret = asprintf(&devicefile, "/dev/%s.%s", data->devicefile, bootpart);
+       if (ret < 0) {
+               printf("Failed to allocate string for boot partition device 
file\n");
+               goto free_bootpartvar;
+       }
+
+       ret = imx_bbu_check_prereq(devicefile, data);
+       if (ret)
+               goto free_devicefile;
+
+       ret = imx_bbu_write_device(imx_handler, devicefile, data, data->image, 
data->len);
+
+       if (!ret)
+               /* on success switch boot source */
+               ret = setenv(bootpartvar, bootpart);
+
+free_devicefile:
+       free(devicefile);
+
+free_bootpartvar:
+       free(bootpartvar);
+
+       return ret;
+}
+
 static int imx_bbu_external_update(struct bbu_handler *handler, struct 
bbu_data *data)
 {
        struct imx_internal_bbu_handler *imx_handler =
@@ -498,6 +556,19 @@ int imx6_bbu_internal_mmc_register_handler(const char 
*name, char *devicefile,
        return __register_handler(imx_handler);
 }
 
+int imx6_bbu_internal_mmcboot_register_handler(const char *name, char 
*devicefile,
+                                              unsigned long flags)
+{
+       struct imx_internal_bbu_handler *imx_handler;
+
+       imx_handler = __init_handler(name, devicefile, flags);
+       imx_handler->flash_header_offset = FLASH_HEADER_OFFSET_MMC;
+
+       imx_handler->handler.handler = imx_bbu_internal_v2_mmcboot_update;
+
+       return __register_handler(imx_handler);
+}
+
 /*
  * Register a i.MX53 internal boot update handler for i2c/spi
  * EEPROMs / flashes. Nearly the same as MMC/SD, but we do not need to
-- 
2.14.2


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

Reply via email to