misc: fs_loader: Switching private data allocation to DM auto allocation

Switching private data manual allocation to driver model auto allocation
so users no longer need to deallocate themself because this would be
deallocated by driver model when the device is no longer required.

Signed-off-by: Tien Fong Chee <tien.fong.chee@intel.com>
Reviewed-by: Simon Glass <sjg@chromium.org>
This commit is contained in:
Tien Fong Chee 2018-12-10 21:29:44 +08:00 committed by Tom Rini
parent 9652cfd9ee
commit 31a2cf1ca4
3 changed files with 56 additions and 119 deletions

View file

@ -74,17 +74,16 @@ Firmware storage device described in device tree source
File system firmware Loader API File system firmware Loader API
------------------------------- -------------------------------
int request_firmware_into_buf(struct device_platdata *plat, int request_firmware_into_buf(struct udevice *dev,
const char *name, const char *name,
void *buf, size_t size, u32 offset, void *buf, size_t size, u32 offset)
struct firmware **firmwarep)
-------------------------------------------------------------------- --------------------------------------------------------------------
Load firmware into a previously allocated buffer Load firmware into a previously allocated buffer
Parameters: Parameters:
1. struct device_platdata *plat 1. struct udevice *dev
Platform data such as storage and partition firmware loading from An instance of a driver
2. const char *name 2. const char *name
name of firmware file name of firmware file
@ -98,36 +97,16 @@ Parameters:
5. u32 offset 5. u32 offset
offset of a file for start reading into buffer offset of a file for start reading into buffer
6. struct firmware **firmwarep
pointer to firmware image
return: return:
size of total read size of total read
-ve when error -ve when error
Description: Description:
The firmware is loaded directly into the buffer pointed to by buf and The firmware is loaded directly into the buffer pointed to by buf
the @firmwarep data member is pointed at buf
Note: Memory would be allocated for firmware image, hence user should
free() *firmwarep and *firmwarep->priv structs after usage of
request_firmware_into_buf(), otherwise it will always leak memory
while subsequent calls of request_firmware_into_buf() with the same
*firmwarep argument. Those arguments can be free through calling API
below release_firmware();
Example of creating firmware loader instance and calling Example of creating firmware loader instance and calling
request_firmware_into_buf API: request_firmware_into_buf API:
if (uclass_get_device(UCLASS_FS_FIRMWARE_LOADER, 0, &dev)) { if (uclass_get_device(UCLASS_FS_FIRMWARE_LOADER, 0, &dev)) {
request_firmware_into_buf(dev->plat, filename, buffer_location, request_firmware_into_buf(dev, filename, buffer_location,
buffer_size, offset_ofreading, &fw); buffer_size, offset_ofreading);
} }
void release_firmware(struct firmware *firmware)
------------------------------------------------
Release the resource associated with a firmware image
Parameters:
1. struct firmware *firmware
Firmware resource to release

View file

@ -16,9 +16,22 @@
DECLARE_GLOBAL_DATA_PTR; DECLARE_GLOBAL_DATA_PTR;
struct firmware_priv { /**
const char *name; /* Filename */ * struct firmware - A place for storing firmware and its attribute data.
u32 offset; /* Offset of reading a file */ *
* This holds information about a firmware and its content.
*
* @size: Size of a file
* @data: Buffer for file
* @priv: Firmware loader private fields
* @name: Filename
* @offset: Offset of reading a file
*/
struct firmware {
size_t size;
const u8 *data;
const char *name;
u32 offset;
}; };
#ifdef CONFIG_CMD_UBIFS #ifdef CONFIG_CMD_UBIFS
@ -88,74 +101,42 @@ static int select_fs_dev(struct device_platdata *plat)
/** /**
* _request_firmware_prepare - Prepare firmware struct. * _request_firmware_prepare - Prepare firmware struct.
* *
* @dev: An instance of a driver.
* @name: Name of firmware file. * @name: Name of firmware file.
* @dbuf: Address of buffer to load firmware into. * @dbuf: Address of buffer to load firmware into.
* @size: Size of buffer. * @size: Size of buffer.
* @offset: Offset of a file for start reading into buffer. * @offset: Offset of a file for start reading into buffer.
* @firmwarep: Pointer to pointer to firmware image.
* *
* Return: Negative value if fail, 0 for successful. * Return: Negative value if fail, 0 for successful.
*/ */
static int _request_firmware_prepare(const char *name, void *dbuf, static int _request_firmware_prepare(struct udevice *dev,
size_t size, u32 offset, const char *name, void *dbuf,
struct firmware **firmwarep) size_t size, u32 offset)
{ {
if (!name || name[0] == '\0') if (!name || name[0] == '\0')
return -EINVAL; return -EINVAL;
/* No memory allocation is required if *firmwarep is allocated */ struct firmware *firmwarep = dev_get_priv(dev);
if (!(*firmwarep)) {
(*firmwarep) = calloc(1, sizeof(struct firmware));
if (!(*firmwarep))
return -ENOMEM;
(*firmwarep)->priv = calloc(1, sizeof(struct firmware_priv)); if (!firmwarep)
if (!(*firmwarep)->priv) { return -ENOMEM;
free(*firmwarep);
return -ENOMEM;
}
} else if (!(*firmwarep)->priv) {
(*firmwarep)->priv = calloc(1, sizeof(struct firmware_priv));
if (!(*firmwarep)->priv) {
free(*firmwarep);
return -ENOMEM;
}
}
((struct firmware_priv *)((*firmwarep)->priv))->name = name; firmwarep->name = name;
((struct firmware_priv *)((*firmwarep)->priv))->offset = offset; firmwarep->offset = offset;
(*firmwarep)->data = dbuf; firmwarep->data = dbuf;
(*firmwarep)->size = size; firmwarep->size = size;
return 0; return 0;
} }
/**
* release_firmware - Release the resource associated with a firmware image
* @firmware: Firmware resource to release
*/
void release_firmware(struct firmware *firmware)
{
if (firmware) {
if (firmware->priv) {
free(firmware->priv);
firmware->priv = NULL;
}
free(firmware);
}
}
/** /**
* fw_get_filesystem_firmware - load firmware into an allocated buffer. * fw_get_filesystem_firmware - load firmware into an allocated buffer.
* @plat: Platform data such as storage and partition firmware loading from. * @dev: An instance of a driver.
* @firmware: pointer to firmware image.
* *
* Return: Size of total read, negative value when error. * Return: Size of total read, negative value when error.
*/ */
static int fw_get_filesystem_firmware(struct device_platdata *plat, static int fw_get_filesystem_firmware(struct udevice *dev)
struct firmware *firmware)
{ {
struct firmware_priv *fw_priv = NULL;
loff_t actread; loff_t actread;
char *storage_interface, *dev_part, *ubi_mtdpart, *ubi_volume; char *storage_interface, *dev_part, *ubi_mtdpart, *ubi_volume;
int ret; int ret;
@ -178,20 +159,23 @@ static int fw_get_filesystem_firmware(struct device_platdata *plat,
else else
ret = -ENODEV; ret = -ENODEV;
} else { } else {
ret = select_fs_dev(plat); ret = select_fs_dev(dev->platdata);
} }
if (ret) if (ret)
goto out; goto out;
fw_priv = firmware->priv; struct firmware *firmwarep = dev_get_priv(dev);
ret = fs_read(fw_priv->name, (ulong)map_to_sysmem(firmware->data), if (!firmwarep)
fw_priv->offset, firmware->size, &actread); return -ENOMEM;
ret = fs_read(firmwarep->name, (ulong)map_to_sysmem(firmwarep->data),
firmwarep->offset, firmwarep->size, &actread);
if (ret) { if (ret) {
debug("Error: %d Failed to read %s from flash %lld != %zu.\n", debug("Error: %d Failed to read %s from flash %lld != %zu.\n",
ret, fw_priv->name, actread, firmware->size); ret, firmwarep->name, actread, firmwarep->size);
} else { } else {
ret = actread; ret = actread;
} }
@ -205,33 +189,30 @@ out:
/** /**
* request_firmware_into_buf - Load firmware into a previously allocated buffer. * request_firmware_into_buf - Load firmware into a previously allocated buffer.
* @plat: Platform data such as storage and partition firmware loading from. * @dev: An instance of a driver.
* @name: Name of firmware file. * @name: Name of firmware file.
* @buf: Address of buffer to load firmware into. * @buf: Address of buffer to load firmware into.
* @size: Size of buffer. * @size: Size of buffer.
* @offset: Offset of a file for start reading into buffer. * @offset: Offset of a file for start reading into buffer.
* @firmwarep: Pointer to firmware image.
* *
* The firmware is loaded directly into the buffer pointed to by @buf and * The firmware is loaded directly into the buffer pointed to by @buf.
* the @firmwarep data member is pointed at @buf.
* *
* Return: Size of total read, negative value when error. * Return: Size of total read, negative value when error.
*/ */
int request_firmware_into_buf(struct device_platdata *plat, int request_firmware_into_buf(struct udevice *dev,
const char *name, const char *name,
void *buf, size_t size, u32 offset, void *buf, size_t size, u32 offset)
struct firmware **firmwarep)
{ {
int ret; int ret;
if (!plat) if (!dev)
return -EINVAL; return -EINVAL;
ret = _request_firmware_prepare(name, buf, size, offset, firmwarep); ret = _request_firmware_prepare(dev, name, buf, size, offset);
if (ret < 0) /* error */ if (ret < 0) /* error */
return ret; return ret;
ret = fw_get_filesystem_firmware(plat, *firmwarep); ret = fw_get_filesystem_firmware(dev);
return ret; return ret;
} }
@ -286,6 +267,7 @@ U_BOOT_DRIVER(fs_loader) = {
.probe = fs_loader_probe, .probe = fs_loader_probe,
.ofdata_to_platdata = fs_loader_ofdata_to_platdata, .ofdata_to_platdata = fs_loader_ofdata_to_platdata,
.platdata_auto_alloc_size = sizeof(struct device_platdata), .platdata_auto_alloc_size = sizeof(struct device_platdata),
.priv_auto_alloc_size = sizeof(struct firmware),
}; };
UCLASS_DRIVER(fs_loader) = { UCLASS_DRIVER(fs_loader) = {

View file

@ -8,21 +8,6 @@
#include <dm.h> #include <dm.h>
/**
* struct firmware - A place for storing firmware and its attribute data.
*
* This holds information about a firmware and its content.
*
* @size: Size of a file
* @data: Buffer for file
* @priv: Firmware loader private fields
*/
struct firmware {
size_t size;
const u8 *data;
void *priv;
};
/** /**
* struct phandle_part - A place for storing phandle of node and its partition * struct phandle_part - A place for storing phandle of node and its partition
* *
@ -52,28 +37,19 @@ struct device_platdata {
char *ubivol; char *ubivol;
}; };
/**
* release_firmware - Release the resource associated with a firmware image
* @firmware: Firmware resource to release
*/
void release_firmware(struct firmware *firmware);
/** /**
* request_firmware_into_buf - Load firmware into a previously allocated buffer. * request_firmware_into_buf - Load firmware into a previously allocated buffer.
* @plat: Platform data such as storage and partition firmware loading from. * @dev: An instance of a driver.
* @name: Name of firmware file. * @name: Name of firmware file.
* @buf: Address of buffer to load firmware into. * @buf: Address of buffer to load firmware into.
* @size: Size of buffer. * @size: Size of buffer.
* @offset: Offset of a file for start reading into buffer. * @offset: Offset of a file for start reading into buffer.
* @firmwarep: Pointer to firmware image.
* *
* The firmware is loaded directly into the buffer pointed to by @buf and * The firmware is loaded directly into the buffer pointed to by @buf.
* the @firmwarep data member is pointed at @buf.
* *
* Return: Size of total read, negative value when error. * Return: Size of total read, negative value when error.
*/ */
int request_firmware_into_buf(struct device_platdata *plat, int request_firmware_into_buf(struct udevice *dev,
const char *name, const char *name,
void *buf, size_t size, u32 offset, void *buf, size_t size, u32 offset);
struct firmware **firmwarep);
#endif #endif