lkml.org 
[lkml]   [2022]   [Jun]   [7]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH v6 2/5] firmware: sysfb: Add sysfb_disable() helper function
    Date
    This can be used by subsystems to unregister a platform device registered
    by sysfb and also to disable future platform device registration in sysfb.

    Suggested-by: Daniel Vetter <daniel.vetter@ffwll.ch>
    Signed-off-by: Javier Martinez Canillas <javierm@redhat.com>
    Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
    ---

    Changes in v6:
    - Drop sysfb_try_unregister() helper since is no longer needed.

    Changes in v4:
    - Make sysfb_disable() to also attempt to unregister a device.

    Changes in v2:
    - Add kernel-doc comments and include in other_interfaces.rst (Daniel Vetter).

    .../driver-api/firmware/other_interfaces.rst | 6 +++
    drivers/firmware/sysfb.c | 54 ++++++++++++++++---
    include/linux/sysfb.h | 13 +++++
    3 files changed, 67 insertions(+), 6 deletions(-)

    diff --git a/Documentation/driver-api/firmware/other_interfaces.rst b/Documentation/driver-api/firmware/other_interfaces.rst
    index b81794e0cfbb..06ac89adaafb 100644
    --- a/Documentation/driver-api/firmware/other_interfaces.rst
    +++ b/Documentation/driver-api/firmware/other_interfaces.rst
    @@ -13,6 +13,12 @@ EDD Interfaces
    .. kernel-doc:: drivers/firmware/edd.c
    :internal:

    +Generic System Framebuffers Interface
    +-------------------------------------
    +
    +.. kernel-doc:: drivers/firmware/sysfb.c
    + :export:
    +
    Intel Stratix10 SoC Service Layer
    ---------------------------------
    Some features of the Intel Stratix10 SoC require a level of privilege
    diff --git a/drivers/firmware/sysfb.c b/drivers/firmware/sysfb.c
    index b032f40a92de..1f276f108cc9 100644
    --- a/drivers/firmware/sysfb.c
    +++ b/drivers/firmware/sysfb.c
    @@ -34,21 +34,59 @@
    #include <linux/screen_info.h>
    #include <linux/sysfb.h>

    +static struct platform_device *pd;
    +static DEFINE_MUTEX(disable_lock);
    +static bool disabled;
    +
    +static bool sysfb_unregister(void)
    +{
    + if (IS_ERR_OR_NULL(pd))
    + return false;
    +
    + platform_device_unregister(pd);
    + pd = NULL;
    +
    + return true;
    +}
    +
    +/**
    + * sysfb_disable() - disable the Generic System Framebuffers support
    + *
    + * This disables the registration of system framebuffer devices that match the
    + * generic drivers that make use of the system framebuffer set up by firmware.
    + *
    + * It also unregisters a device if this was already registered by sysfb_init().
    + *
    + * Context: The function can sleep. A @disable_lock mutex is acquired to serialize
    + * against sysfb_init(), that registers a system framebuffer device.
    + */
    +void sysfb_disable(void)
    +{
    + mutex_lock(&disable_lock);
    + sysfb_unregister();
    + disabled = true;
    + mutex_unlock(&disable_lock);
    +}
    +EXPORT_SYMBOL_GPL(sysfb_disable);
    +
    static __init int sysfb_init(void)
    {
    struct screen_info *si = &screen_info;
    struct simplefb_platform_data mode;
    - struct platform_device *pd;
    const char *name;
    bool compatible;
    - int ret;
    + int ret = 0;
    +
    + mutex_lock(&disable_lock);
    + if (disabled)
    + goto unlock_mutex;

    /* try to create a simple-framebuffer device */
    compatible = sysfb_parse_mode(si, &mode);
    if (compatible) {
    pd = sysfb_create_simplefb(si, &mode);
    if (!IS_ERR(pd))
    - return 0;
    + goto unlock_mutex;
    }

    /* if the FB is incompatible, create a legacy framebuffer device */
    @@ -60,8 +98,10 @@ static __init int sysfb_init(void)
    name = "platform-framebuffer";

    pd = platform_device_alloc(name, 0);
    - if (!pd)
    - return -ENOMEM;
    + if (!pd) {
    + ret = -ENOMEM;
    + goto unlock_mutex;
    + }

    sysfb_apply_efi_quirks(pd);

    @@ -73,9 +113,11 @@ static __init int sysfb_init(void)
    if (ret)
    goto err;

    - return 0;
    + goto unlock_mutex;
    err:
    platform_device_put(pd);
    +unlock_mutex:
    + mutex_unlock(&disable_lock);
    return ret;
    }

    diff --git a/include/linux/sysfb.h b/include/linux/sysfb.h
    index 708152e9037b..e9baee4ae361 100644
    --- a/include/linux/sysfb.h
    +++ b/include/linux/sysfb.h
    @@ -55,6 +55,19 @@ struct efifb_dmi_info {
    int flags;
    };

    +#ifdef CONFIG_SYSFB
    +
    +void sysfb_disable(void);
    +
    +#else /* CONFIG_SYSFB */
    +
    +static inline void sysfb_disable(void)
    +{
    +
    +}
    +
    +#endif /* CONFIG_SYSFB */
    +
    #ifdef CONFIG_EFI

    extern struct efifb_dmi_info efifb_dmi_list[];
    --
    2.36.1
    \
     
     \ /
      Last update: 2022-06-07 23:03    [W:3.098 / U:0.112 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site