On Sun, Jan 15, 2017 at 10:15:43PM +0900, Akinobu Mita wrote: > This driver reports input events on their interrupts which are triggered > by the sensor's status register changes. But only single bit change is > reported in the interrupt handler. So if there are multiple bits are > changed at almost the same time, other press or release events are ignored. > > This fixes it by detecting all changed bits in the status register. > > Cc: Dmitry Torokhov <dmitry.torokhov@xxxxxxxxx> > Signed-off-by: Akinobu Mita <akinobu.mita@xxxxxxxxx> > --- > * Use for_each_set_bit() to search changed bit > > drivers/input/keyboard/mpr121_touchkey.c | 23 ++++++++++++++--------- > 1 file changed, 14 insertions(+), 9 deletions(-) > > diff --git a/drivers/input/keyboard/mpr121_touchkey.c b/drivers/input/keyboard/mpr121_touchkey.c > index 2558c60..a0210ae 100644 > --- a/drivers/input/keyboard/mpr121_touchkey.c > +++ b/drivers/input/keyboard/mpr121_touchkey.c > @@ -86,7 +86,8 @@ static irqreturn_t mpr_touchkey_interrupt(int irq, void *dev_id) > struct mpr121_touchkey *mpr121 = dev_id; > struct i2c_client *client = mpr121->client; > struct input_dev *input = mpr121->input_dev; > - unsigned int key_num, key_val, pressed; > + unsigned long bit_changed; > + unsigned int key_num; > int reg; > > reg = i2c_smbus_read_byte_data(client, ELE_TOUCH_STATUS_1_ADDR); > @@ -104,18 +105,22 @@ static irqreturn_t mpr_touchkey_interrupt(int irq, void *dev_id) > > reg &= TOUCH_STATUS_MASK; > /* use old press bit to figure out which bit changed */ > - key_num = ffs(reg ^ mpr121->statusbits) - 1; > - pressed = reg & (1 << key_num); > + bit_changed = reg ^ mpr121->statusbits; > mpr121->statusbits = reg; > + for_each_set_bit(key_num, &bit_changed, mpr121->keycount) { > + unsigned int key_val, pressed; > > - key_val = mpr121->keycodes[key_num]; > + pressed = reg & (1 << key_num); Changed to pressed = reg & BIT(key_num); and applied, thank you. > + key_val = mpr121->keycodes[key_num]; > > - input_event(input, EV_MSC, MSC_SCAN, key_num); > - input_report_key(input, key_val, pressed); > - input_sync(input); > + input_event(input, EV_MSC, MSC_SCAN, key_num); > + input_report_key(input, key_val, pressed); > + > + dev_dbg(&client->dev, "key %d %d %s\n", key_num, key_val, > + pressed ? "pressed" : "released"); > > - dev_dbg(&client->dev, "key %d %d %s\n", key_num, key_val, > - pressed ? "pressed" : "released"); > + } > + input_sync(input); > > out: > return IRQ_HANDLED; > -- > 2.7.4 > -- Dmitry -- To unsubscribe from this list: send the line "unsubscribe linux-input" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html