lkml.org 
[lkml]   [2017]   [Feb]   [15]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 1/2] firmware: add more flexible request_firmware_async function
    Date
    From: Rafał Miłecki <rafal@milecki.pl>

    So far we got only one function for loading firmware asynchronously:
    request_firmware_nowait. It didn't allow much customization of firmware
    loading process - there is only one bool uevent argument. Moreover this
    bool also controls user helper in an unclear way.

    Resolve this problem by adding a one flexible function and making old
    request_firmware_nowait a simple inline using new solution. This
    implementation:
    1) Modifies only single bits on existing code
    2) Doesn't require adjusting / rewriting current drivers
    3) Adds new function for drivers that need more control over loading a
    firmware. Thanks to using flags more features can be added later.

    Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
    ---
    This patch is based on top of
    [PATCH V2 RESEND] firmware: simplify defining and handling FW_OPT_FALLBACK
    applied on top of Linux 4.10-rc8.

    Ming/Luis/Greg: assuming this gets a positive review, could someone of you pick
    this patchset? Second patch modifies brcmfmac, I'll try to get a proper Ack for
    that one.
    Unless you want this to go through wireless tree, then let me know please.
    ---
    drivers/base/firmware_class.c | 25 ++++++-------------------
    include/linux/firmware.h | 34 +++++++++++++++++++++++++++++-----
    2 files changed, 35 insertions(+), 24 deletions(-)

    diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c
    index d05be1732c8b..7b3f0a018dc3 100644
    --- a/drivers/base/firmware_class.c
    +++ b/drivers/base/firmware_class.c
    @@ -182,18 +182,6 @@ static int __fw_state_check(struct fw_state *fw_st, enum fw_status status)

    #endif /* CONFIG_FW_LOADER_USER_HELPER */

    -/* firmware behavior options */
    -#define FW_OPT_UEVENT (1U << 0)
    -#define FW_OPT_NOWAIT (1U << 1)
    -#ifdef CONFIG_FW_LOADER_USER_HELPER
    -#define FW_OPT_USERHELPER (1U << 2)
    -#else
    -#define FW_OPT_USERHELPER 0
    -#endif
    -#define FW_OPT_NO_WARN (1U << 3)
    -#define FW_OPT_NOCACHE (1U << 4)
    -#define FW_OPT_FALLBACK (1U << 5)
    -
    struct firmware_cache {
    /* firmware_buf instance will be added into the below list */
    spinlock_t lock;
    @@ -1356,7 +1344,7 @@ static void request_firmware_work_func(struct work_struct *work)
    _request_firmware(&fw, fw_work->name, fw_work->device, NULL, 0,
    fw_work->opt_flags);
    fw_work->cont(fw, fw_work->context);
    - put_device(fw_work->device); /* taken in request_firmware_nowait() */
    + put_device(fw_work->device); /* taken in request_firmware_async() */

    module_put(fw_work->module);
    kfree_const(fw_work->name);
    @@ -1364,7 +1352,7 @@ static void request_firmware_work_func(struct work_struct *work)
    }

    /**
    - * request_firmware_nowait - asynchronous version of request_firmware
    + * request_firmware_async - asynchronous version of request_firmware
    * @module: module requesting the firmware
    * @uevent: sends uevent to copy the firmware image if this flag
    * is non-zero else the firmware copy must be done manually.
    @@ -1387,8 +1375,8 @@ static void request_firmware_work_func(struct work_struct *work)
    * - can't sleep at all if @gfp is GFP_ATOMIC.
    **/
    int
    -request_firmware_nowait(
    - struct module *module, bool uevent,
    +request_firmware_async(
    + struct module *module, unsigned int opt_flags,
    const char *name, struct device *device, gfp_t gfp, void *context,
    void (*cont)(const struct firmware *fw, void *context))
    {
    @@ -1407,8 +1395,7 @@ request_firmware_nowait(
    fw_work->device = device;
    fw_work->context = context;
    fw_work->cont = cont;
    - fw_work->opt_flags = FW_OPT_NOWAIT | FW_OPT_FALLBACK |
    - (uevent ? FW_OPT_UEVENT : FW_OPT_USERHELPER);
    + fw_work->opt_flags = FW_OPT_NOWAIT | opt_flags;

    if (!try_module_get(module)) {
    kfree_const(fw_work->name);
    @@ -1421,7 +1408,7 @@ request_firmware_nowait(
    schedule_work(&fw_work->work);
    return 0;
    }
    -EXPORT_SYMBOL(request_firmware_nowait);
    +EXPORT_SYMBOL(request_firmware_async);

    #ifdef CONFIG_PM_SLEEP
    static ASYNC_DOMAIN_EXCLUSIVE(fw_cache_domain);
    diff --git a/include/linux/firmware.h b/include/linux/firmware.h
    index b1f9f0ccb8ac..1f2bf14aa441 100644
    --- a/include/linux/firmware.h
    +++ b/include/linux/firmware.h
    @@ -8,6 +8,18 @@
    #define FW_ACTION_NOHOTPLUG 0
    #define FW_ACTION_HOTPLUG 1

    +/* firmware behavior options */
    +#define FW_OPT_UEVENT (1U << 0)
    +#define FW_OPT_NOWAIT (1U << 1)
    +#ifdef CONFIG_FW_LOADER_USER_HELPER
    +#define FW_OPT_USERHELPER (1U << 2)
    +#else
    +#define FW_OPT_USERHELPER 0
    +#endif
    +#define FW_OPT_NO_WARN (1U << 3)
    +#define FW_OPT_NOCACHE (1U << 4)
    +#define FW_OPT_FALLBACK (1U << 5)
    +
    struct firmware {
    size_t size;
    const u8 *data;
    @@ -41,8 +53,8 @@ struct builtin_fw {
    #if defined(CONFIG_FW_LOADER) || (defined(CONFIG_FW_LOADER_MODULE) && defined(MODULE))
    int request_firmware(const struct firmware **fw, const char *name,
    struct device *device);
    -int request_firmware_nowait(
    - struct module *module, bool uevent,
    +int request_firmware_async(
    + struct module *module, unsigned int opt_flags,
    const char *name, struct device *device, gfp_t gfp, void *context,
    void (*cont)(const struct firmware *fw, void *context));
    int request_firmware_direct(const struct firmware **fw, const char *name,
    @@ -58,8 +70,8 @@ static inline int request_firmware(const struct firmware **fw,
    {
    return -EINVAL;
    }
    -static inline int request_firmware_nowait(
    - struct module *module, bool uevent,
    +static inline int request_firmware_async(
    + struct module *module, unsigned int opt_flags,
    const char *name, struct device *device, gfp_t gfp, void *context,
    void (*cont)(const struct firmware *fw, void *context))
    {
    @@ -82,6 +94,18 @@ static inline int request_firmware_into_buf(const struct firmware **firmware_p,
    {
    return -EINVAL;
    }
    -
    #endif
    +
    +static inline int request_firmware_nowait(
    + struct module *module, bool uevent,
    + const char *name, struct device *device, gfp_t gfp, void *context,
    + void (*cont)(const struct firmware *fw, void *context))
    +{
    + unsigned int opt_flags = FW_OPT_FALLBACK |
    + (uevent ? FW_OPT_UEVENT : FW_OPT_USERHELPER);
    +
    + return request_firmware_async(module, opt_flags, name, device, gfp,
    + context, cont);
    +}
    +
    #endif
    --
    2.11.0
    \
     
     \ /
      Last update: 2017-02-15 23:30    [W:3.340 / U:0.156 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site