Re: [RFC PATCH 09/13] driver core: firmware loader: store firmwarename into devres list

From: Borislav Petkov
Date: Wed Jul 25 2012 - 12:15:38 EST


On Wed, Jul 25, 2012 at 01:00:09AM +0800, Ming Lei wrote:
> This patch will store firmware name into devres list of the device
> which is requesting firmware loading, so that we can implement
> auto cache firmware for devices in need.

Stupid question: does this mean that once the firmware name is in the
devres list, it is being cached automatically and device drivers which
don't want that need to explicitly uncache it?

>
> Signed-off-by: Ming Lei <ming.lei@xxxxxxxxxxxxx>
> ---
> drivers/base/firmware_class.c | 66 +++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 66 insertions(+)
>
> diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c
> index 540b2e1..c181e6d 100644
> --- a/drivers/base/firmware_class.c
> +++ b/drivers/base/firmware_class.c
> @@ -115,6 +115,11 @@ struct firmware_priv {
> struct firmware *fw;
> };
>
> +struct fw_name_devm {
> + unsigned long magic;
> + char name[];
> +};
> +
> #define to_fwbuf(d) container_of(d, struct firmware_buf, ref)
>
> /* fw_lock could be moved to 'struct firmware_priv' but since it is just
> @@ -574,6 +579,56 @@ static void fw_set_page_data(struct firmware_buf *buf, struct firmware *fw)
> fw->priv = buf;
> }
>
> +static void fw_name_devm_release(struct device *dev, void *res)
> +{
> + struct fw_name_devm *fwn = res;
> +
> + if (fwn->magic == (unsigned long)&fw_cache)
> + pr_debug("%s: fw_name-%s devm-%p released\n",
> + __func__, fwn->name, res);
> +}
> +
> +static int fw_devm_match(struct device *dev, void *res,
> + void *match_data)
> +{
> + struct fw_name_devm *fwn = res;
> +
> + return (fwn->magic == (unsigned long)&fw_cache) &&
> + !strcmp(fwn->name, match_data);
> +}
> +
> +static struct fw_name_devm *fw_find_devm_name(struct device *dev,
> + const char *name)
> +{
> + struct fw_name_devm *fwn;
> +
> + fwn = devres_find(dev, fw_name_devm_release,
> + fw_devm_match, (void *)name);
> + return fwn;
> +}
> +
> +/* add firmware name into devres list */
> +static int fw_add_devm_name(struct device *dev, const char *name)
> +{
> + struct fw_name_devm *fwn;
> +
> + fwn = fw_find_devm_name(dev, name);
> + if (fwn)
> + return 1;
> +
> + fwn = devres_alloc(fw_name_devm_release, sizeof(struct fw_name_devm) +
> + strlen(name) + 1, GFP_KERNEL);

Alignment and stray newline.

> +
> + if (!fwn)
> + return -ENOMEM;
> +
> + fwn->magic = (unsigned long)&fw_cache;
> + strcpy(fwn->name, name);
> + devres_add(dev, fwn);
> +
> + return 0;
> +}
> +
> static void _request_firmware_cleanup(const struct firmware **firmware_p)
> {
> release_firmware(*firmware_p);
> @@ -690,6 +745,17 @@ static int _request_firmware_load(struct firmware_priv *fw_priv, bool uevent,
>
> fw_set_page_data(buf, fw_priv->fw);
>
> + /*
> + * add firmware name into devres list so that we can auto cache
> + * firmware for device.
> + *
> + * f_dev->parent may has been deleted already, but the problem
> + * should be fixed in devres.
> + *
> + */
> + if (!retval && f_dev->parent)
> + fw_add_devm_name(f_dev->parent, buf->fw_id);
> +
> fw_priv->buf = NULL;
> mutex_unlock(&fw_lock);
>
> --
> 1.7.9.5
>
>

--
Regards/Gruss,
Boris.

Advanced Micro Devices GmbH
Einsteinring 24, 85609 Dornach
GM: Alberto Bozzo
Reg: Dornach, Landkreis Muenchen
HRB Nr. 43632 WEEE Registernr: 129 19551
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/