summaryrefslogtreecommitdiff
path: root/drivers/fwu-mdata
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/fwu-mdata')
-rw-r--r--drivers/fwu-mdata/fwu-mdata-uclass.c11
-rw-r--r--drivers/fwu-mdata/gpt_blk.c23
-rw-r--r--drivers/fwu-mdata/raw_mtd.c78
3 files changed, 68 insertions, 44 deletions
diff --git a/drivers/fwu-mdata/fwu-mdata-uclass.c b/drivers/fwu-mdata/fwu-mdata-uclass.c
index 0a8edaaa418..92abb94dcc9 100644
--- a/drivers/fwu-mdata/fwu-mdata-uclass.c
+++ b/drivers/fwu-mdata/fwu-mdata-uclass.c
@@ -5,7 +5,6 @@
#define LOG_CATEGORY UCLASS_FWU_MDATA
-#include <common.h>
#include <dm.h>
#include <efi_loader.h>
#include <fwu.h>
@@ -20,7 +19,8 @@
*
* Return: 0 if OK, -ve on error
*/
-int fwu_read_mdata(struct udevice *dev, struct fwu_mdata *mdata, bool primary)
+int fwu_read_mdata(struct udevice *dev, struct fwu_mdata *mdata, bool primary,
+ uint32_t size)
{
const struct fwu_mdata_ops *ops = device_get_ops(dev);
@@ -29,7 +29,7 @@ int fwu_read_mdata(struct udevice *dev, struct fwu_mdata *mdata, bool primary)
return -ENOSYS;
}
- return ops->read_mdata(dev, mdata, primary);
+ return ops->read_mdata(dev, mdata, primary, size);
}
/**
@@ -37,7 +37,8 @@ int fwu_read_mdata(struct udevice *dev, struct fwu_mdata *mdata, bool primary)
*
* Return: 0 if OK, -ve on error
*/
-int fwu_write_mdata(struct udevice *dev, struct fwu_mdata *mdata, bool primary)
+int fwu_write_mdata(struct udevice *dev, struct fwu_mdata *mdata, bool primary,
+ uint32_t size)
{
const struct fwu_mdata_ops *ops = device_get_ops(dev);
@@ -46,7 +47,7 @@ int fwu_write_mdata(struct udevice *dev, struct fwu_mdata *mdata, bool primary)
return -ENOSYS;
}
- return ops->write_mdata(dev, mdata, primary);
+ return ops->write_mdata(dev, mdata, primary, size);
}
UCLASS_DRIVER(fwu_mdata) = {
diff --git a/drivers/fwu-mdata/gpt_blk.c b/drivers/fwu-mdata/gpt_blk.c
index c7284916c4e..97eac3611f7 100644
--- a/drivers/fwu-mdata/gpt_blk.c
+++ b/drivers/fwu-mdata/gpt_blk.c
@@ -81,15 +81,14 @@ static int gpt_get_mdata_disk_part(struct blk_desc *desc,
return -ENOENT;
}
-static int gpt_read_write_mdata(struct blk_desc *desc,
- struct fwu_mdata *mdata,
- u8 access, u32 part_num)
+static int gpt_read_write_mdata(struct blk_desc *desc, struct fwu_mdata *mdata,
+ u8 access, u32 part_num, u32 size)
{
int ret;
u32 len, blk_start, blkcnt;
struct disk_partition info;
- ALLOC_CACHE_ALIGN_BUFFER_PAD(struct fwu_mdata, mdata_aligned, 1,
+ ALLOC_CACHE_ALIGN_BUFFER_PAD(u8, mdata_aligned, size,
desc->blksz);
if (!mdata)
@@ -101,7 +100,7 @@ static int gpt_read_write_mdata(struct blk_desc *desc,
return -ENOENT;
}
- len = sizeof(*mdata);
+ len = size;
blkcnt = BLOCK_CNT(len, desc);
if (blkcnt > info.size) {
log_debug("Block count exceeds FWU metadata partition size\n");
@@ -114,7 +113,7 @@ static int gpt_read_write_mdata(struct blk_desc *desc,
log_debug("Error reading FWU metadata from the device\n");
return -EIO;
}
- memcpy(mdata, mdata_aligned, sizeof(struct fwu_mdata));
+ memcpy(mdata, mdata_aligned, size);
} else {
if (blk_dwrite(desc, blk_start, blkcnt, mdata) != blkcnt) {
log_debug("Error writing FWU metadata to the device\n");
@@ -164,7 +163,7 @@ static int fwu_mdata_gpt_blk_probe(struct udevice *dev)
}
static int fwu_gpt_read_mdata(struct udevice *dev, struct fwu_mdata *mdata,
- bool primary)
+ bool primary, u32 size)
{
struct fwu_mdata_gpt_blk_priv *priv = dev_get_priv(dev);
struct blk_desc *desc = dev_get_uclass_plat(priv->blk_dev);
@@ -177,11 +176,13 @@ static int fwu_gpt_read_mdata(struct udevice *dev, struct fwu_mdata *mdata,
}
return gpt_read_write_mdata(desc, mdata, MDATA_READ,
- primary ? g_mdata_part[0] : g_mdata_part[1]);
+ primary ?
+ g_mdata_part[0] : g_mdata_part[1],
+ size);
}
static int fwu_gpt_write_mdata(struct udevice *dev, struct fwu_mdata *mdata,
- bool primary)
+ bool primary, u32 size)
{
struct fwu_mdata_gpt_blk_priv *priv = dev_get_priv(dev);
struct blk_desc *desc = dev_get_uclass_plat(priv->blk_dev);
@@ -194,7 +195,9 @@ static int fwu_gpt_write_mdata(struct udevice *dev, struct fwu_mdata *mdata,
}
return gpt_read_write_mdata(desc, mdata, MDATA_WRITE,
- primary ? g_mdata_part[0] : g_mdata_part[1]);
+ primary ?
+ g_mdata_part[0] : g_mdata_part[1],
+ size);
}
static const struct fwu_mdata_ops fwu_gpt_blk_ops = {
diff --git a/drivers/fwu-mdata/raw_mtd.c b/drivers/fwu-mdata/raw_mtd.c
index 17e45179738..78a709f766c 100644
--- a/drivers/fwu-mdata/raw_mtd.c
+++ b/drivers/fwu-mdata/raw_mtd.c
@@ -12,22 +12,11 @@
#include <linux/errno.h>
#include <linux/types.h>
-/* Internal helper structure to move data around */
-struct fwu_mdata_mtd_priv {
- struct mtd_info *mtd;
- char pri_label[50];
- char sec_label[50];
- u32 pri_offset;
- u32 sec_offset;
-};
-
enum fwu_mtd_op {
FWU_MTD_READ,
FWU_MTD_WRITE,
};
-extern struct fwu_mtd_image_info fwu_mtd_images[];
-
static bool mtd_is_aligned_with_block_size(struct mtd_info *mtd, u64 size)
{
return !do_div(size, mtd->erasesize);
@@ -97,22 +86,24 @@ lock:
return ret;
}
-static int fwu_mtd_read_mdata(struct udevice *dev, struct fwu_mdata *mdata, bool primary)
+static int fwu_mtd_read_mdata(struct udevice *dev, struct fwu_mdata *mdata,
+ bool primary, u32 size)
{
struct fwu_mdata_mtd_priv *mtd_priv = dev_get_priv(dev);
struct mtd_info *mtd = mtd_priv->mtd;
u32 offs = primary ? mtd_priv->pri_offset : mtd_priv->sec_offset;
- return mtd_io_data(mtd, offs, sizeof(struct fwu_mdata), mdata, FWU_MTD_READ);
+ return mtd_io_data(mtd, offs, size, mdata, FWU_MTD_READ);
}
-static int fwu_mtd_write_mdata(struct udevice *dev, struct fwu_mdata *mdata, bool primary)
+static int fwu_mtd_write_mdata(struct udevice *dev, struct fwu_mdata *mdata,
+ bool primary, u32 size)
{
struct fwu_mdata_mtd_priv *mtd_priv = dev_get_priv(dev);
struct mtd_info *mtd = mtd_priv->mtd;
u32 offs = primary ? mtd_priv->pri_offset : mtd_priv->sec_offset;
- return mtd_io_data(mtd, offs, sizeof(struct fwu_mdata), mdata, FWU_MTD_WRITE);
+ return mtd_io_data(mtd, offs, size, mdata, FWU_MTD_WRITE);
}
static int flash_partition_offset(struct udevice *dev, const char *part_name, fdt_addr_t *offset)
@@ -132,7 +123,7 @@ static int flash_partition_offset(struct udevice *dev, const char *part_name, fd
return (int)size;
}
-static int fwu_mdata_mtd_of_to_plat(struct udevice *dev)
+static int get_fwu_mdata_dev(struct udevice *dev)
{
struct fwu_mdata_mtd_priv *mtd_priv = dev_get_priv(dev);
const fdt32_t *phandle_p = NULL;
@@ -142,8 +133,6 @@ static int fwu_mdata_mtd_of_to_plat(struct udevice *dev)
fdt_addr_t offset;
int ret, size;
u32 phandle;
- ofnode bank;
- int off_img;
/* Find the FWU mdata storage device */
phandle_p = ofnode_get_property(dev_ofnode(dev),
@@ -197,8 +186,28 @@ static int fwu_mdata_mtd_of_to_plat(struct udevice *dev)
return ret;
mtd_priv->sec_offset = offset;
- off_img = 0;
+ return 0;
+}
+
+static int fwu_mtd_image_info_populate(struct udevice *dev, u8 nbanks,
+ u16 nimages)
+{
+ struct fwu_mtd_image_info *mtd_images;
+ struct fwu_mdata_mtd_priv *mtd_priv = dev_get_priv(dev);
+ struct udevice *mtd_dev = mtd_priv->mtd->dev;
+ fdt_addr_t offset;
+ ofnode bank;
+ int off_img;
+ u32 total_images;
+ total_images = nbanks * nimages;
+ mtd_priv->fwu_mtd_images = malloc(sizeof(struct fwu_mtd_image_info) *
+ total_images);
+ if (!mtd_priv->fwu_mtd_images)
+ return -ENOMEM;
+
+ off_img = 0;
+ mtd_images = mtd_priv->fwu_mtd_images;
ofnode_for_each_subnode(bank, dev_ofnode(dev)) {
int bank_num, bank_offset, bank_size;
const char *bank_name;
@@ -217,8 +226,7 @@ static int fwu_mdata_mtd_of_to_plat(struct udevice *dev)
int image_num, image_offset, image_size;
const char *uuid;
- if (off_img == CONFIG_FWU_NUM_BANKS *
- CONFIG_FWU_NUM_IMAGES_PER_BANK) {
+ if (off_img == total_images) {
log_err("DT provides more images than configured!\n");
break;
}
@@ -228,11 +236,11 @@ static int fwu_mdata_mtd_of_to_plat(struct udevice *dev)
ofnode_read_u32(image, "offset", &image_offset);
ofnode_read_u32(image, "size", &image_size);
- fwu_mtd_images[off_img].start = bank_offset + image_offset;
- fwu_mtd_images[off_img].size = image_size;
- fwu_mtd_images[off_img].bank_num = bank_num;
- fwu_mtd_images[off_img].image_num = image_num;
- strcpy(fwu_mtd_images[off_img].uuidbuf, uuid);
+ mtd_images[off_img].start = bank_offset + image_offset;
+ mtd_images[off_img].size = image_size;
+ mtd_images[off_img].bank_num = bank_num;
+ mtd_images[off_img].image_num = image_num;
+ strcpy(mtd_images[off_img].uuidbuf, uuid);
log_debug("\tImage%d: %s @0x%x\n\n",
image_num, uuid, bank_offset + image_offset);
off_img++;
@@ -244,8 +252,21 @@ static int fwu_mdata_mtd_of_to_plat(struct udevice *dev)
static int fwu_mdata_mtd_probe(struct udevice *dev)
{
- /* Ensure the metadata can be read. */
- return fwu_get_mdata(NULL);
+ u8 nbanks;
+ u16 nimages;
+ int ret;
+
+ ret = get_fwu_mdata_dev(dev);
+ if (ret)
+ return ret;
+
+ nbanks = CONFIG_FWU_NUM_BANKS;
+ nimages = CONFIG_FWU_NUM_IMAGES_PER_BANK;
+ ret = fwu_mtd_image_info_populate(dev, nbanks, nimages);
+ if (ret)
+ return ret;
+
+ return 0;
}
static struct fwu_mdata_ops fwu_mtd_ops = {
@@ -264,6 +285,5 @@ U_BOOT_DRIVER(fwu_mdata_mtd) = {
.of_match = fwu_mdata_ids,
.ops = &fwu_mtd_ops,
.probe = fwu_mdata_mtd_probe,
- .of_to_plat = fwu_mdata_mtd_of_to_plat,
.priv_auto = sizeof(struct fwu_mdata_mtd_priv),
};