Commit e277026b authored by Conor Dooley's avatar Conor Dooley

firmware: microchip: move buffer allocation into mpfs_auto_update_set_image_address()

This buffer is used exclusively by mpfs_auto_update_set_image_address(),
so move the management of it there, employing the recently added cleanup
infrastructure to avoid littering the function with gotos.
Signed-off-by: default avatarConor Dooley <conor.dooley@microchip.com>
parent a2bf9dfe
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
* *
* Author: Conor Dooley <conor.dooley@microchip.com> * Author: Conor Dooley <conor.dooley@microchip.com>
*/ */
#include <linux/cleanup.h>
#include <linux/debugfs.h> #include <linux/debugfs.h>
#include <linux/firmware.h> #include <linux/firmware.h>
#include <linux/math.h> #include <linux/math.h>
...@@ -233,15 +234,17 @@ static int mpfs_auto_update_verify_image(struct fw_upload *fw_uploader) ...@@ -233,15 +234,17 @@ static int mpfs_auto_update_verify_image(struct fw_upload *fw_uploader)
return ret; return ret;
} }
static int mpfs_auto_update_set_image_address(struct mpfs_auto_update_priv *priv, char *buffer, static int mpfs_auto_update_set_image_address(struct mpfs_auto_update_priv *priv,
u32 image_address, loff_t directory_address) u32 image_address, loff_t directory_address)
{ {
struct erase_info erase; struct erase_info erase;
size_t erase_size = AUTO_UPDATE_DIRECTORY_SIZE; size_t erase_size = round_up(AUTO_UPDATE_DIRECTORY_SIZE, (u64)priv->flash->erasesize);
size_t bytes_written = 0, bytes_read = 0; size_t bytes_written = 0, bytes_read = 0;
char *buffer __free(kfree) = kzalloc(erase_size, GFP_KERNEL);
int ret; int ret;
erase_size = round_up(erase_size, (u64)priv->flash->erasesize); if (!buffer)
return -ENOMEM;
erase.addr = AUTO_UPDATE_DIRECTORY_BASE; erase.addr = AUTO_UPDATE_DIRECTORY_BASE;
erase.len = erase_size; erase.len = erase_size;
...@@ -287,7 +290,7 @@ static int mpfs_auto_update_set_image_address(struct mpfs_auto_update_priv *priv ...@@ -287,7 +290,7 @@ static int mpfs_auto_update_set_image_address(struct mpfs_auto_update_priv *priv
return ret; return ret;
if (bytes_written != erase_size) if (bytes_written != erase_size)
return ret; return -EIO;
return 0; return 0;
} }
...@@ -297,7 +300,6 @@ static int mpfs_auto_update_write_bitstream(struct fw_upload *fw_uploader, const ...@@ -297,7 +300,6 @@ static int mpfs_auto_update_write_bitstream(struct fw_upload *fw_uploader, const
{ {
struct mpfs_auto_update_priv *priv = fw_uploader->dd_handle; struct mpfs_auto_update_priv *priv = fw_uploader->dd_handle;
struct erase_info erase; struct erase_info erase;
char *buffer;
loff_t directory_address = AUTO_UPDATE_UPGRADE_DIRECTORY; loff_t directory_address = AUTO_UPDATE_UPGRADE_DIRECTORY;
size_t erase_size = AUTO_UPDATE_DIRECTORY_SIZE; size_t erase_size = AUTO_UPDATE_DIRECTORY_SIZE;
size_t bytes_written = 0; size_t bytes_written = 0;
...@@ -313,16 +315,12 @@ static int mpfs_auto_update_write_bitstream(struct fw_upload *fw_uploader, const ...@@ -313,16 +315,12 @@ static int mpfs_auto_update_write_bitstream(struct fw_upload *fw_uploader, const
image_address = AUTO_UPDATE_BITSTREAM_BASE + image_address = AUTO_UPDATE_BITSTREAM_BASE +
AUTO_UPDATE_UPGRADE_INDEX * priv->size_per_bitstream; AUTO_UPDATE_UPGRADE_INDEX * priv->size_per_bitstream;
buffer = devm_kzalloc(priv->dev, erase_size, GFP_KERNEL);
if (!buffer)
return -ENOMEM;
/* /*
* For bitstream info, the descriptor is written to a fixed offset, * For bitstream info, the descriptor is written to a fixed offset,
* so there is no need to set the image address. * so there is no need to set the image address.
*/ */
if (!is_info) { if (!is_info) {
ret = mpfs_auto_update_set_image_address(priv, buffer, image_address, directory_address); ret = mpfs_auto_update_set_image_address(priv, image_address, directory_address);
if (ret) { if (ret) {
dev_err(priv->dev, "failed to set image address in the SPI directory: %d\n", ret); dev_err(priv->dev, "failed to set image address in the SPI directory: %d\n", ret);
return ret; return ret;
...@@ -345,7 +343,7 @@ static int mpfs_auto_update_write_bitstream(struct fw_upload *fw_uploader, const ...@@ -345,7 +343,7 @@ static int mpfs_auto_update_write_bitstream(struct fw_upload *fw_uploader, const
dev_info(priv->dev, "Erasing the flash at address (0x%x)\n", image_address); dev_info(priv->dev, "Erasing the flash at address (0x%x)\n", image_address);
ret = mtd_erase(priv->flash, &erase); ret = mtd_erase(priv->flash, &erase);
if (ret) if (ret)
goto out; return ret;
/* /*
* No parsing etc of the bitstream is required. The system controller * No parsing etc of the bitstream is required. The system controller
...@@ -355,19 +353,15 @@ static int mpfs_auto_update_write_bitstream(struct fw_upload *fw_uploader, const ...@@ -355,19 +353,15 @@ static int mpfs_auto_update_write_bitstream(struct fw_upload *fw_uploader, const
dev_info(priv->dev, "Writing the image to the flash at address (0x%x)\n", image_address); dev_info(priv->dev, "Writing the image to the flash at address (0x%x)\n", image_address);
ret = mtd_write(priv->flash, (loff_t)image_address, size, &bytes_written, data); ret = mtd_write(priv->flash, (loff_t)image_address, size, &bytes_written, data);
if (ret) if (ret)
goto out; return ret;
if (bytes_written != size) { if (bytes_written != size)
ret = -EIO; return -EIO;
goto out;
}
*written = bytes_written; *written = bytes_written;
dev_info(priv->dev, "Wrote 0x%zx bytes to the flash\n", bytes_written); dev_info(priv->dev, "Wrote 0x%zx bytes to the flash\n", bytes_written);
out: return 0;
devm_kfree(priv->dev, buffer);
return ret;
} }
static enum fw_upload_err mpfs_auto_update_write(struct fw_upload *fw_uploader, const u8 *data, static enum fw_upload_err mpfs_auto_update_write(struct fw_upload *fw_uploader, const u8 *data,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment