lkml.org 
[lkml]   [2020]   [Dec]   [28]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 4.19 147/346] Input: ads7846 - fix race that causes missing releases
    Date
    From: David Jander <david@protonic.nl>

    [ Upstream commit e52cd628a03f72a547dbf90ccb703ee64800504a ]

    If touchscreen is released while busy reading HWMON device, the release
    can be missed. The IRQ thread is not started because no touch is active
    and BTN_TOUCH release event is never sent.

    Fixes: f5a28a7d4858f94a ("Input: ads7846 - avoid pen up/down when reading hwmon")
    Co-developed-by: Oleksij Rempel <o.rempel@pengutronix.de>
    Signed-off-by: David Jander <david@protonic.nl>
    Signed-off-by: Oleksij Rempel <o.rempel@pengutronix.de>
    Link: https://lore.kernel.org/r/20201027105416.18773-1-o.rempel@pengutronix.de
    Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
    Signed-off-by: Sasha Levin <sashal@kernel.org>
    ---
    drivers/input/touchscreen/ads7846.c | 44 +++++++++++++++++------------
    1 file changed, 26 insertions(+), 18 deletions(-)

    diff --git a/drivers/input/touchscreen/ads7846.c b/drivers/input/touchscreen/ads7846.c
    index a2f45aefce08a..0fbad337e45a3 100644
    --- a/drivers/input/touchscreen/ads7846.c
    +++ b/drivers/input/touchscreen/ads7846.c
    @@ -199,6 +199,26 @@ struct ads7846 {
    #define REF_ON (READ_12BIT_DFR(x, 1, 1))
    #define REF_OFF (READ_12BIT_DFR(y, 0, 0))

    +static int get_pendown_state(struct ads7846 *ts)
    +{
    + if (ts->get_pendown_state)
    + return ts->get_pendown_state();
    +
    + return !gpio_get_value(ts->gpio_pendown);
    +}
    +
    +static void ads7846_report_pen_up(struct ads7846 *ts)
    +{
    + struct input_dev *input = ts->input;
    +
    + input_report_key(input, BTN_TOUCH, 0);
    + input_report_abs(input, ABS_PRESSURE, 0);
    + input_sync(input);
    +
    + ts->pendown = false;
    + dev_vdbg(&ts->spi->dev, "UP\n");
    +}
    +
    /* Must be called with ts->lock held */
    static void ads7846_stop(struct ads7846 *ts)
    {
    @@ -215,6 +235,10 @@ static void ads7846_stop(struct ads7846 *ts)
    static void ads7846_restart(struct ads7846 *ts)
    {
    if (!ts->disabled && !ts->suspended) {
    + /* Check if pen was released since last stop */
    + if (ts->pendown && !get_pendown_state(ts))
    + ads7846_report_pen_up(ts);
    +
    /* Tell IRQ thread that it may poll the device. */
    ts->stopped = false;
    mb();
    @@ -605,14 +629,6 @@ static const struct attribute_group ads784x_attr_group = {

    /*--------------------------------------------------------------------------*/

    -static int get_pendown_state(struct ads7846 *ts)
    -{
    - if (ts->get_pendown_state)
    - return ts->get_pendown_state();
    -
    - return !gpio_get_value(ts->gpio_pendown);
    -}
    -
    static void null_wait_for_sync(void)
    {
    }
    @@ -871,16 +887,8 @@ static irqreturn_t ads7846_irq(int irq, void *handle)
    msecs_to_jiffies(TS_POLL_PERIOD));
    }

    - if (ts->pendown && !ts->stopped) {
    - struct input_dev *input = ts->input;
    -
    - input_report_key(input, BTN_TOUCH, 0);
    - input_report_abs(input, ABS_PRESSURE, 0);
    - input_sync(input);
    -
    - ts->pendown = false;
    - dev_vdbg(&ts->spi->dev, "UP\n");
    - }
    + if (ts->pendown && !ts->stopped)
    + ads7846_report_pen_up(ts);

    return IRQ_HANDLED;
    }
    --
    2.27.0


    \
     
     \ /
      Last update: 2020-12-28 17:09    [W:3.001 / U:0.608 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site