stm32mp: stm32prog: add support for delete option in flashlayout
authorPatrick Delaunay <patrick.delaunay@st.com>
Wed, 18 Mar 2020 08:24:57 +0000 (09:24 +0100)
committerPatrick Delaunay <patrick.delaunay@st.com>
Thu, 14 May 2020 07:02:12 +0000 (09:02 +0200)
Add support for delete option 'D' in flashlayout for
full device or for partitions

Signed-off-by: Patrick Delaunay <patrick.delaunay@st.com>
Reviewed-by: Patrice Chotard <patrice.chotard@st.com>
arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c

index 3e521d42f22c095223148d3efbf93f84d9feb471..3573c04d169e9a0c1f4f78eda1c559bd3c0b78f1 100644 (file)
 
 #define OPT_SELECT     BIT(0)
 #define OPT_EMPTY      BIT(1)
+#define OPT_DELETE     BIT(2)
 
 #define IS_SELECT(part)        ((part)->option & OPT_SELECT)
 #define IS_EMPTY(part) ((part)->option & OPT_EMPTY)
+#define IS_DELETE(part)        ((part)->option & OPT_DELETE)
 
 #define ALT_BUF_LEN                    SZ_1K
 
@@ -158,6 +160,9 @@ static int parse_option(struct stm32prog_data *data,
                case 'E':
                        part->option |= OPT_EMPTY;
                        break;
+               case 'D':
+                       part->option |= OPT_DELETE;
+                       break;
                default:
                        result = -EINVAL;
                        stm32prog_err("Layout line %d: invalid option '%c' in %s)",
@@ -1293,10 +1298,80 @@ void stm32prog_next_phase(struct stm32prog_data *data)
                puts("Phase=END\n");
 }
 
+static int part_delete(struct stm32prog_data *data,
+                      struct stm32prog_part_t *part)
+{
+       int ret = 0;
+#ifdef CONFIG_MMC
+       unsigned long blks, blks_offset, blks_size;
+       struct blk_desc *block_dev = NULL;
+ #endif
+#ifdef CONFIG_MTD
+       char cmdbuf[40];
+       char devstr[10];
+#endif
+
+       printf("Erasing %s ", part->name);
+       switch (part->target) {
+#ifdef CONFIG_MMC
+       case STM32PROG_MMC:
+               printf("on mmc %d: ", part->dev->dev_id);
+               block_dev = mmc_get_blk_desc(part->dev->mmc);
+               blks_offset = lldiv(part->addr, part->dev->mmc->read_bl_len);
+               blks_size = lldiv(part->size, part->dev->mmc->read_bl_len);
+               /* -1 or -2 : delete boot partition of MMC
+                * need to switch to associated hwpart 1 or 2
+                */
+               if (part->part_id < 0)
+                       if (blk_select_hwpart_devnum(IF_TYPE_MMC,
+                                                    part->dev->dev_id,
+                                                    -part->part_id))
+                               return -1;
+
+               blks = blk_derase(block_dev, blks_offset, blks_size);
+
+               /* return to user partition */
+               if (part->part_id < 0)
+                       blk_select_hwpart_devnum(IF_TYPE_MMC,
+                                                part->dev->dev_id, 0);
+               if (blks != blks_size) {
+                       ret = -1;
+                       stm32prog_err("%s (0x%x): MMC erase failed",
+                                     part->name, part->id);
+               }
+               break;
+#endif
+#ifdef CONFIG_MTD
+       case STM32PROG_NOR:
+       case STM32PROG_NAND:
+       case STM32PROG_SPI_NAND:
+               get_mtd_by_target(devstr, part->target, part->dev->dev_id);
+               printf("on %s: ", devstr);
+               sprintf(cmdbuf, "mtd erase %s 0x%llx 0x%llx",
+                       devstr, part->addr, part->size);
+               if (run_command(cmdbuf, 0)) {
+                       ret = -1;
+                       stm32prog_err("%s (0x%x): MTD erase commands failed (%s)",
+                                     part->name, part->id, cmdbuf);
+               }
+               break;
+#endif
+       default:
+               ret = -1;
+               stm32prog_err("%s (0x%x): erase invalid", part->name, part->id);
+               break;
+       }
+       if (!ret)
+               printf("done\n");
+
+       return ret;
+}
+
 static void stm32prog_devices_init(struct stm32prog_data *data)
 {
        int i;
        int ret;
+       struct stm32prog_part_t *part;
 
        ret = treat_partition_list(data);
        if (ret)
@@ -1309,10 +1384,40 @@ static void stm32prog_devices_init(struct stm32prog_data *data)
                        goto error;
        }
 
+       /* delete RAW partition before create partition */
+       for (i = 0; i < data->part_nb; i++) {
+               part = &data->part_array[i];
+
+               if (part->part_type != RAW_IMAGE)
+                       continue;
+
+               if (!IS_SELECT(part) || !IS_DELETE(part))
+                       continue;
+
+               ret = part_delete(data, part);
+               if (ret)
+                       goto error;
+       }
+
        ret = create_partitions(data);
        if (ret)
                goto error;
 
+       /* delete partition GPT or MTD */
+       for (i = 0; i < data->part_nb; i++) {
+               part = &data->part_array[i];
+
+               if (part->part_type == RAW_IMAGE)
+                       continue;
+
+               if (!IS_SELECT(part) || !IS_DELETE(part))
+                       continue;
+
+               ret = part_delete(data, part);
+               if (ret)
+                       goto error;
+       }
+
        return;
 
 error: