lkml.org 
[lkml]   [2022]   [Sep]   [26]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 5.10 054/141] gpiolib: cdev: Set lineevent_state::irq after IRQ register successfully
    Date
    From: Meng Li <Meng.Li@windriver.com>

    commit 69bef19d6b9700e96285f4b4e28691cda3dcd0d1 upstream.

    When running gpio test on nxp-ls1028 platform with below command
    gpiomon --num-events=3 --rising-edge gpiochip1 25
    There will be a warning trace as below:
    Call trace:
    free_irq+0x204/0x360
    lineevent_free+0x64/0x70
    gpio_ioctl+0x598/0x6a0
    __arm64_sys_ioctl+0xb4/0x100
    invoke_syscall+0x5c/0x130
    ......
    el0t_64_sync+0x1a0/0x1a4
    The reason of this issue is that calling request_threaded_irq()
    function failed, and then lineevent_free() is invoked to release
    the resource. Since the lineevent_state::irq was already set, so
    the subsequent invocation of free_irq() would trigger the above
    warning call trace. To fix this issue, set the lineevent_state::irq
    after the IRQ register successfully.

    Fixes: 468242724143 ("gpiolib: cdev: refactor lineevent cleanup into lineevent_free")
    Cc: stable@vger.kernel.org
    Signed-off-by: Meng Li <Meng.Li@windriver.com>
    Reviewed-by: Kent Gibson <warthog618@gmail.com>
    Signed-off-by: Bartosz Golaszewski <brgl@bgdev.pl>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
    ---
    drivers/gpio/gpiolib-cdev.c | 5 +++--
    1 file changed, 3 insertions(+), 2 deletions(-)

    --- a/drivers/gpio/gpiolib-cdev.c
    +++ b/drivers/gpio/gpiolib-cdev.c
    @@ -1769,7 +1769,6 @@ static int lineevent_create(struct gpio_
    ret = -ENODEV;
    goto out_free_le;
    }
    - le->irq = irq;

    if (eflags & GPIOEVENT_REQUEST_RISING_EDGE)
    irqflags |= test_bit(FLAG_ACTIVE_LOW, &desc->flags) ?
    @@ -1783,7 +1782,7 @@ static int lineevent_create(struct gpio_
    init_waitqueue_head(&le->wait);

    /* Request a thread to read the events */
    - ret = request_threaded_irq(le->irq,
    + ret = request_threaded_irq(irq,
    lineevent_irq_handler,
    lineevent_irq_thread,
    irqflags,
    @@ -1792,6 +1791,8 @@ static int lineevent_create(struct gpio_
    if (ret)
    goto out_free_le;

    + le->irq = irq;
    +
    fd = get_unused_fd_flags(O_RDONLY | O_CLOEXEC);
    if (fd < 0) {
    ret = fd;

    \
     
     \ /
      Last update: 2022-09-26 13:02    [W:4.050 / U:0.104 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site