• xiongxin's avatar
    gpio: dwapb: mask/unmask IRQ when disable/enale it · 1cc3542c
    xiongxin authored
    In the hardware implementation of the I2C HID driver based on DesignWare
    GPIO IRQ chip, when the user continues to use the I2C HID device in the
    suspend process, the I2C HID interrupt will be masked after the resume
    process is finished.
    
    This is because the disable_irq()/enable_irq() of the DesignWare GPIO
    driver does not synchronize the IRQ mask register state. In normal use
    of the I2C HID procedure, the GPIO IRQ irq_mask()/irq_unmask() functions
    are called in pairs. In case of an exception, i2c_hid_core_suspend()
    calls disable_irq() to disable the GPIO IRQ. With low probability, this
    causes irq_unmask() to not be called, which causes the GPIO IRQ to be
    masked and not unmasked in enable_irq(), raising an exception.
    
    Add synchronization to the masked register state in the
    dwapb_irq_enable()/dwapb_irq_disable() function. mask the GPIO IRQ
    before disabling it. After enabling the GPIO IRQ, unmask the IRQ.
    
    Fixes: 7779b345 ("gpio: add a driver for the Synopsys DesignWare APB GPIO block")
    Cc: stable@kernel.org
    Co-developed-by: default avatarRiwen Lu <luriwen@kylinos.cn>
    Signed-off-by: default avatarRiwen Lu <luriwen@kylinos.cn>
    Signed-off-by: default avatarxiongxin <xiongxin@kylinos.cn>
    Acked-by: default avatarSerge Semin <fancer.lancer@gmail.com>
    Reviewed-by: default avatarAndy Shevchenko <andy@kernel.org>
    Signed-off-by: default avatarBartosz Golaszewski <bartosz.golaszewski@linaro.org>
    1cc3542c
gpio-dwapb.c 21 KB