diff mbox series

[rfd] saving old mice -- button glitching/debouncing

Message ID 20181214232437.GA8310@amd (mailing list archive)
State New, archived
Headers show
Series [rfd] saving old mice -- button glitching/debouncing | expand

Commit Message

Pavel Machek Dec. 14, 2018, 11:24 p.m. UTC
I believe I have hardware problem, but I'm kind of hoping software
could help me...?

Mouse wheel on my machine started glitching on my machine, generating
double-clicks when I click it once. Which unfortunately is quite
annoying: texts are pasted twice, two tabs are closed instead of one,
....

Event: time 1544733054.903129, type 4 (EV_MSC), code 4 (MSC_SCAN), value 90003
Event: time 1544733054.903129, type 1 (EV_KEY), code 274 (BTN_MIDDLE), value 1
Event: time 1544733054.903129, -------------- EV_SYN ------------
            1544733054.967251, type 4 (EV_MSC), code 4 (MSC_SCAN), value 90003
Event: time 1544733054.967251, type 1 (EV_KEY), code 274 (BTN_MIDDLE), value 0
Event: time 1544733054.967251, -------------- EV_SYN ------------
Event: time 1544733054.975144, type 4 (EV_MSC), code 4 (MSC_SCAN), value 90003
Event: time 1544733054.975144, type 1 (EV_KEY), code 274 (BTN_MIDDLE), value 1
Event: time 1544733054.975144, -------------- EV_SYN ------------
     : time 1544733065.127190, type 4 (EV_MSC), code 4 (MSC_SCAN), value 90003
Event: time 1544733065.127190, type 1 (EV_KEY), code 274 (BTN_MIDDLE), value 0
Event: time 1544733065.127190, -------------- EV_SYN ------------

Now, I could just buy a new mouse, but it seems that most optical mice
die like this... so maybe it would be nice to have an option to
debounce the buttons, so that the useful life of mice is extended a
bit?

(So... I have two mice with that fault -- cheap to replace, but button
in thinkpad X220 started doing that, too. That one will not be so
cheap to fix :-( ).

It is possible that some X versions already do something like this.

Patch is obviously not ready; but:

a) would it be useful to people

b) would it be acceptable if done properly? (cmd line option to
enable, avoiding duplicate/wrong events?)

Thanks,
								Pavel
Signed-off-by: Pavel Machek <pavel@ucw.cz>

Comments

Dmitry Torokhov Dec. 15, 2018, 12:19 a.m. UTC | #1
Hi Pavel,

On Fri, Dec 14, 2018 at 3:24 PM Pavel Machek <pavel@ucw.cz> wrote:
>
>
> I believe I have hardware problem, but I'm kind of hoping software
> could help me...?
>
> Mouse wheel on my machine started glitching on my machine, generating
> double-clicks when I click it once. Which unfortunately is quite
> annoying: texts are pasted twice, two tabs are closed instead of one,
> ....
>
> Event: time 1544733054.903129, type 4 (EV_MSC), code 4 (MSC_SCAN), value 90003
> Event: time 1544733054.903129, type 1 (EV_KEY), code 274 (BTN_MIDDLE), value 1
> Event: time 1544733054.903129, -------------- EV_SYN ------------
>             1544733054.967251, type 4 (EV_MSC), code 4 (MSC_SCAN), value 90003
> Event: time 1544733054.967251, type 1 (EV_KEY), code 274 (BTN_MIDDLE), value 0
> Event: time 1544733054.967251, -------------- EV_SYN ------------
> Event: time 1544733054.975144, type 4 (EV_MSC), code 4 (MSC_SCAN), value 90003
> Event: time 1544733054.975144, type 1 (EV_KEY), code 274 (BTN_MIDDLE), value 1
> Event: time 1544733054.975144, -------------- EV_SYN ------------
>      : time 1544733065.127190, type 4 (EV_MSC), code 4 (MSC_SCAN), value 90003
> Event: time 1544733065.127190, type 1 (EV_KEY), code 274 (BTN_MIDDLE), value 0
> Event: time 1544733065.127190, -------------- EV_SYN ------------
>
> Now, I could just buy a new mouse, but it seems that most optical mice
> die like this... so maybe it would be nice to have an option to
> debounce the buttons, so that the useful life of mice is extended a
> bit?
>
> (So... I have two mice with that fault -- cheap to replace, but button
> in thinkpad X220 started doing that, too. That one will not be so
> cheap to fix :-( ).
>
> It is possible that some X versions already do something like this.
>
> Patch is obviously not ready; but:
>
> a) would it be useful to people
>
> b) would it be acceptable if done properly? (cmd line option to
> enable, avoiding duplicate/wrong events?)

I'd say if you are attached to failing hardware, solve it in
userspace. Have a utility/daemon that you run (from udev?) that:

- "grabs" input device with EVIOCGRAB
- does the debouncing/filtering/adjusting for the dirty sensor
- reinject events back into kernel with /dev/uinput

It will add some latency, but should be workable.

Thanks.
Vojtech Pavlik Dec. 15, 2018, 8:55 a.m. UTC | #2
On Sat, Dec 15, 2018 at 12:24:37AM +0100, Pavel Machek wrote:

> Patch is obviously not ready; but:
> 
> a) would it be useful to people

Probably not.

Mice already do internal software/hardware debouncing on switches. If you
see duplicate clicks making it all the way to the kernel driver, something
is very wrong with the switch, to the point where it'll soon fail
completely.

Hence the value of doing extra processing in the kernel is very limited.

> b) would it be acceptable if done properly? (cmd line option to
> enable, avoiding duplicate/wrong events?)

Well, for one, you shouldn't be using a timer, all the debouncing can be
done by math on the event timestamps.

You'd also have a hard time distinguishing between doubleclicks and bounces.

Since the mice already filter the quick bounces and there is significant
delay (100ms on USB, similar on PS/2) between updates from the hardware, a
real doubleclick can look absolutely the same as what you observe as a
bounce.

As such, it couldn't be enabled by default.

If you really want to go this way, a userspace solution is the better choice.
Pavel Machek Dec. 15, 2018, 9:47 a.m. UTC | #3
Hi!

> > Patch is obviously not ready; but:
> > 
> > a) would it be useful to people
> 
> Probably not.
> 
> Mice already do internal software/hardware debouncing on switches. If you
> see duplicate clicks making it all the way to the kernel driver, something
> is very wrong with the switch, to the point where it'll soon fail
> completely.

It seems mice normally survive 2 years under my use. This one has left
button repaired and middle button failing... If debouncing gives it
one more year, it will be success...

> > b) would it be acceptable if done properly? (cmd line option to
> > enable, avoiding duplicate/wrong events?)
> 
> Well, for one, you shouldn't be using a timer, all the debouncing can be
> done by math on the event timestamps.

Not... really, right? You need to send an release some time after
button indicates release if bounce did not happen. It is similar to
autorepeat needing a timer.

Let me gain some experience with the patch. I don't think hardware
does as heavy debouncing as you describe.

Best regards,
									
									Pavel
Vojtech Pavlik Dec. 15, 2018, 10:12 a.m. UTC | #4
On Sat, Dec 15, 2018 at 10:47:22AM +0100, Pavel Machek wrote:

> > > b) would it be acceptable if done properly? (cmd line option to
> > > enable, avoiding duplicate/wrong events?)
> > 
> > Well, for one, you shouldn't be using a timer, all the debouncing can be
> > done by math on the event timestamps.
> 
> Not... really, right? You need to send an release some time after
> button indicates release if bounce did not happen. It is similar to
> autorepeat needing a timer.

You can send the first release and ignore all presses and releases in a
time window after that.

> Let me gain some experience with the patch. I don't think hardware
> does as heavy debouncing as you describe.

Microswitches vibrate significantly when clicked. Without hardware
debouncing, you'd have many clicks instead of one even on a new mouse.
Pavel Machek Dec. 15, 2018, 10:29 a.m. UTC | #5
On Sat 2018-12-15 11:12:21, Vojtech Pavlik wrote:
> On Sat, Dec 15, 2018 at 10:47:22AM +0100, Pavel Machek wrote:
> 
> > > > b) would it be acceptable if done properly? (cmd line option to
> > > > enable, avoiding duplicate/wrong events?)
> > > 
> > > Well, for one, you shouldn't be using a timer, all the debouncing can be
> > > done by math on the event timestamps.
> > 
> > Not... really, right? You need to send an release some time after
> > button indicates release if bounce did not happen. It is similar to
> > autorepeat needing a timer.
> 
> You can send the first release and ignore all presses and releases in a
> time window after that.

I could, and it would work for glitches on release, but that would do
very bad things if switch glitched on press, right?

"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XX           " ->
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX              " ... ok

"XX XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX..." ->
"XX                                  ..." ... bad idea. [Maybe could be
detected with "XX " being unusually short?]

But I believe I see 

"XXXXXXXXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXXX" on X220 device, too.

									Pavel
Joerg Riechardt Dec. 15, 2018, 1:55 p.m. UTC | #6
Am 15.12.2018 um 00:24 schrieb Pavel Machek:

> Mouse wheel on my machine started glitching on my machine, generating
> double-clicks when I click it once.

> Event: time 1544733054.903129, type 4 (EV_MSC), code 4 (MSC_SCAN), value 90003
> Event: time 1544733054.903129, type 1 (EV_KEY), code 274 (BTN_MIDDLE), value 1
> Event: time 1544733054.903129, -------------- EV_SYN ------------
>              1544733054.967251, type 4 (EV_MSC), code 4 (MSC_SCAN), value 90003
> Event: time 1544733054.967251, type 1 (EV_KEY), code 274 (BTN_MIDDLE), value 0
> Event: time 1544733054.967251, -------------- EV_SYN ------------
> Event: time 1544733054.975144, type 4 (EV_MSC), code 4 (MSC_SCAN), value 90003
> Event: time 1544733054.975144, type 1 (EV_KEY), code 274 (BTN_MIDDLE), value 1
> Event: time 1544733054.975144, -------------- EV_SYN ------------
>       : time 1544733065.127190, type 4 (EV_MSC), code 4 (MSC_SCAN), value 90003
> Event: time 1544733065.127190, type 1 (EV_KEY), code 274 (BTN_MIDDLE), value 0
> Event: time 1544733065.127190, -------------- EV_SYN ------------

There is only 8 ms glitch in this example. If it's always that short, it 
can be filtered out safely.
Joerg
kernel test robot Dec. 18, 2018, 3:26 p.m. UTC | #7
Hi Pavel,

I love your patch! Perhaps something to improve:

[auto build test WARNING on input/next]
[also build test WARNING on v4.20-rc7 next-20181218]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url:    https://github.com/0day-ci/linux/commits/Pavel-Machek/saving-old-mice-button-glitching-debouncing/20181216-025214
base:   https://git.kernel.org/pub/scm/linux/kernel/git/dtor/input.git next
reproduce: make htmldocs

All warnings (new ones prefixed by >>):

   WARNING: convert(1) not found, for SVG to PDF conversion install ImageMagick (https://www.imagemagick.org)
   include/net/cfg80211.h:4216: warning: Function parameter or member 'wext.ibss' not described in 'wireless_dev'
   include/net/cfg80211.h:4216: warning: Function parameter or member 'wext.connect' not described in 'wireless_dev'
   include/net/cfg80211.h:4216: warning: Function parameter or member 'wext.keys' not described in 'wireless_dev'
   include/net/cfg80211.h:4216: warning: Function parameter or member 'wext.ie' not described in 'wireless_dev'
   include/net/cfg80211.h:4216: warning: Function parameter or member 'wext.ie_len' not described in 'wireless_dev'
   include/net/cfg80211.h:4216: warning: Function parameter or member 'wext.bssid' not described in 'wireless_dev'
   include/net/cfg80211.h:4216: warning: Function parameter or member 'wext.ssid' not described in 'wireless_dev'
   include/net/cfg80211.h:4216: warning: Function parameter or member 'wext.default_key' not described in 'wireless_dev'
   include/net/cfg80211.h:4216: warning: Function parameter or member 'wext.default_mgmt_key' not described in 'wireless_dev'
   include/net/cfg80211.h:4216: warning: Function parameter or member 'wext.prev_bssid_valid' not described in 'wireless_dev'
   include/net/mac80211.h:2282: warning: Function parameter or member 'radiotap_timestamp.units_pos' not described in 'ieee80211_hw'
   include/net/mac80211.h:2282: warning: Function parameter or member 'radiotap_timestamp.accuracy' not described in 'ieee80211_hw'
   include/net/mac80211.h:955: warning: Function parameter or member 'control.rates' not described in 'ieee80211_tx_info'
   include/net/mac80211.h:955: warning: Function parameter or member 'control.rts_cts_rate_idx' not described in 'ieee80211_tx_info'
   include/net/mac80211.h:955: warning: Function parameter or member 'control.use_rts' not described in 'ieee80211_tx_info'
   include/net/mac80211.h:955: warning: Function parameter or member 'control.use_cts_prot' not described in 'ieee80211_tx_info'
   include/net/mac80211.h:955: warning: Function parameter or member 'control.short_preamble' not described in 'ieee80211_tx_info'
   include/net/mac80211.h:955: warning: Function parameter or member 'control.skip_table' not described in 'ieee80211_tx_info'
   include/net/mac80211.h:955: warning: Function parameter or member 'control.jiffies' not described in 'ieee80211_tx_info'
   include/net/mac80211.h:955: warning: Function parameter or member 'control.vif' not described in 'ieee80211_tx_info'
   include/net/mac80211.h:955: warning: Function parameter or member 'control.hw_key' not described in 'ieee80211_tx_info'
   include/net/mac80211.h:955: warning: Function parameter or member 'control.flags' not described in 'ieee80211_tx_info'
   include/net/mac80211.h:955: warning: Function parameter or member 'control.enqueue_time' not described in 'ieee80211_tx_info'
   include/net/mac80211.h:955: warning: Function parameter or member 'ack' not described in 'ieee80211_tx_info'
   include/net/mac80211.h:955: warning: Function parameter or member 'ack.cookie' not described in 'ieee80211_tx_info'
   include/net/mac80211.h:955: warning: Function parameter or member 'status.rates' not described in 'ieee80211_tx_info'
   include/net/mac80211.h:955: warning: Function parameter or member 'status.ack_signal' not described in 'ieee80211_tx_info'
   include/net/mac80211.h:955: warning: Function parameter or member 'status.ampdu_ack_len' not described in 'ieee80211_tx_info'
   include/net/mac80211.h:955: warning: Function parameter or member 'status.ampdu_len' not described in 'ieee80211_tx_info'
   include/net/mac80211.h:955: warning: Function parameter or member 'status.antenna' not described in 'ieee80211_tx_info'
   include/net/mac80211.h:955: warning: Function parameter or member 'status.tx_time' not described in 'ieee80211_tx_info'
   include/net/mac80211.h:955: warning: Function parameter or member 'status.is_valid_ack_signal' not described in 'ieee80211_tx_info'
   include/net/mac80211.h:955: warning: Function parameter or member 'status.status_driver_data' not described in 'ieee80211_tx_info'
   include/net/mac80211.h:955: warning: Function parameter or member 'driver_rates' not described in 'ieee80211_tx_info'
   include/net/mac80211.h:955: warning: Function parameter or member 'pad' not described in 'ieee80211_tx_info'
   include/net/mac80211.h:955: warning: Function parameter or member 'rate_driver_data' not described in 'ieee80211_tx_info'
   net/mac80211/sta_info.h:586: warning: Function parameter or member 'rx_stats_avg' not described in 'sta_info'
   net/mac80211/sta_info.h:586: warning: Function parameter or member 'rx_stats_avg.signal' not described in 'sta_info'
   net/mac80211/sta_info.h:586: warning: Function parameter or member 'rx_stats_avg.chain_signal' not described in 'sta_info'
   net/mac80211/sta_info.h:586: warning: Function parameter or member 'status_stats.filtered' not described in 'sta_info'
   net/mac80211/sta_info.h:586: warning: Function parameter or member 'status_stats.retry_failed' not described in 'sta_info'
   net/mac80211/sta_info.h:586: warning: Function parameter or member 'status_stats.retry_count' not described in 'sta_info'
   net/mac80211/sta_info.h:586: warning: Function parameter or member 'status_stats.lost_packets' not described in 'sta_info'
   net/mac80211/sta_info.h:586: warning: Function parameter or member 'status_stats.last_tdls_pkt_time' not described in 'sta_info'
   net/mac80211/sta_info.h:586: warning: Function parameter or member 'status_stats.msdu_retries' not described in 'sta_info'
   net/mac80211/sta_info.h:586: warning: Function parameter or member 'status_stats.msdu_failed' not described in 'sta_info'
   net/mac80211/sta_info.h:586: warning: Function parameter or member 'status_stats.last_ack' not described in 'sta_info'
   net/mac80211/sta_info.h:586: warning: Function parameter or member 'status_stats.last_ack_signal' not described in 'sta_info'
   net/mac80211/sta_info.h:586: warning: Function parameter or member 'status_stats.ack_signal_filled' not described in 'sta_info'
   net/mac80211/sta_info.h:586: warning: Function parameter or member 'tx_stats.packets' not described in 'sta_info'
   net/mac80211/sta_info.h:586: warning: Function parameter or member 'tx_stats.bytes' not described in 'sta_info'
   net/mac80211/sta_info.h:586: warning: Function parameter or member 'tx_stats.last_rate' not described in 'sta_info'
   net/mac80211/sta_info.h:586: warning: Function parameter or member 'tx_stats.msdu' not described in 'sta_info'
   kernel/sched/fair.c:3719: warning: Function parameter or member 'flags' not described in 'attach_entity_load_avg'
   include/linux/dma-buf.h:307: warning: Function parameter or member 'cb_excl.cb' not described in 'dma_buf'
   include/linux/dma-buf.h:307: warning: Function parameter or member 'cb_excl.poll' not described in 'dma_buf'
   include/linux/dma-buf.h:307: warning: Function parameter or member 'cb_excl.active' not described in 'dma_buf'
   include/linux/dma-buf.h:307: warning: Function parameter or member 'cb_shared.cb' not described in 'dma_buf'
   include/linux/dma-buf.h:307: warning: Function parameter or member 'cb_shared.poll' not described in 'dma_buf'
   include/linux/dma-buf.h:307: warning: Function parameter or member 'cb_shared.active' not described in 'dma_buf'
   include/linux/dma-fence-array.h:54: warning: Function parameter or member 'work' not described in 'dma_fence_array'
   include/linux/gpio/driver.h:142: warning: Function parameter or member 'request_key' not described in 'gpio_irq_chip'
   include/linux/iio/iio.h:270: warning: Function parameter or member 'scan_type.sign' not described in 'iio_chan_spec'
   include/linux/iio/iio.h:270: warning: Function parameter or member 'scan_type.realbits' not described in 'iio_chan_spec'
   include/linux/iio/iio.h:270: warning: Function parameter or member 'scan_type.storagebits' not described in 'iio_chan_spec'
   include/linux/iio/iio.h:270: warning: Function parameter or member 'scan_type.shift' not described in 'iio_chan_spec'
   include/linux/iio/iio.h:270: warning: Function parameter or member 'scan_type.repeat' not described in 'iio_chan_spec'
   include/linux/iio/iio.h:270: warning: Function parameter or member 'scan_type.endianness' not described in 'iio_chan_spec'
   include/linux/iio/hw-consumer.h:1: warning: no structured comments found
>> include/linux/input.h:192: warning: Function parameter or member 'debounce_key' not described in 'input_dev'
   include/linux/input/sparse-keymap.h:46: warning: Function parameter or member 'sw' not described in 'key_entry'
   include/linux/mtd/rawnand.h:752: warning: Function parameter or member 'timings.sdr' not described in 'nand_data_interface'
   include/linux/mtd/rawnand.h:817: warning: Function parameter or member 'buf' not described in 'nand_op_data_instr'
   include/linux/mtd/rawnand.h:817: warning: Function parameter or member 'buf.in' not described in 'nand_op_data_instr'
   include/linux/mtd/rawnand.h:817: warning: Function parameter or member 'buf.out' not described in 'nand_op_data_instr'
   include/linux/mtd/rawnand.h:863: warning: Function parameter or member 'ctx' not described in 'nand_op_instr'
   include/linux/mtd/rawnand.h:863: warning: Function parameter or member 'ctx.cmd' not described in 'nand_op_instr'
   include/linux/mtd/rawnand.h:863: warning: Function parameter or member 'ctx.addr' not described in 'nand_op_instr'
   include/linux/mtd/rawnand.h:863: warning: Function parameter or member 'ctx.data' not described in 'nand_op_instr'
   include/linux/mtd/rawnand.h:863: warning: Function parameter or member 'ctx.waitrdy' not described in 'nand_op_instr'
   include/linux/mtd/rawnand.h:1016: warning: Function parameter or member 'ctx' not described in 'nand_op_parser_pattern_elem'
   include/linux/mtd/rawnand.h:1016: warning: Function parameter or member 'ctx.addr' not described in 'nand_op_parser_pattern_elem'
   include/linux/mtd/rawnand.h:1016: warning: Function parameter or member 'ctx.data' not described in 'nand_op_parser_pattern_elem'
   include/linux/mtd/rawnand.h:1319: warning: Function parameter or member 'manufacturer.desc' not described in 'nand_chip'
   include/linux/mtd/rawnand.h:1319: warning: Function parameter or member 'manufacturer.priv' not described in 'nand_chip'
   include/linux/regulator/driver.h:222: warning: Function parameter or member 'resume_early' not described in 'regulator_ops'
   drivers/regulator/core.c:4306: warning: Excess function parameter 'state' description in 'regulator_suspend_late'
   arch/s390/include/asm/cio.h:245: warning: Function parameter or member 'esw.esw0' not described in 'irb'
   arch/s390/include/asm/cio.h:245: warning: Function parameter or member 'esw.esw1' not described in 'irb'
   arch/s390/include/asm/cio.h:245: warning: Function parameter or member 'esw.esw2' not described in 'irb'
   arch/s390/include/asm/cio.h:245: warning: Function parameter or member 'esw.esw3' not described in 'irb'
   arch/s390/include/asm/cio.h:245: warning: Function parameter or member 'esw.eadm' not described in 'irb'
   drivers/usb/typec/mux.c:186: warning: Function parameter or member 'mux' not described in 'typec_mux_unregister'
   drivers/usb/typec/mux.c:186: warning: Excess function parameter 'sw' description in 'typec_mux_unregister'
   include/drm/drm_drv.h:610: warning: Function parameter or member 'gem_prime_pin' not described in 'drm_driver'
   include/drm/drm_drv.h:610: warning: Function parameter or member 'gem_prime_unpin' not described in 'drm_driver'
   include/drm/drm_drv.h:610: warning: Function parameter or member 'gem_prime_res_obj' not described in 'drm_driver'
   include/drm/drm_drv.h:610: warning: Function parameter or member 'gem_prime_get_sg_table' not described in 'drm_driver'
   include/drm/drm_drv.h:610: warning: Function parameter or member 'gem_prime_import_sg_table' not described in 'drm_driver'
   include/drm/drm_drv.h:610: warning: Function parameter or member 'gem_prime_vmap' not described in 'drm_driver'
   include/drm/drm_drv.h:610: warning: Function parameter or member 'gem_prime_vunmap' not described in 'drm_driver'
   include/drm/drm_drv.h:610: warning: Function parameter or member 'gem_prime_mmap' not described in 'drm_driver'
   drivers/gpu/drm/drm_prime.c:342: warning: Function parameter or member 'attach' not described in 'drm_gem_unmap_dma_buf'
   drivers/gpu/drm/drm_prime.c:342: warning: Function parameter or member 'sgt' not described in 'drm_gem_unmap_dma_buf'
   drivers/gpu/drm/drm_prime.c:342: warning: Function parameter or member 'dir' not described in 'drm_gem_unmap_dma_buf'
   drivers/gpu/drm/drm_prime.c:438: warning: Function parameter or member 'dma_buf' not described in 'drm_gem_dmabuf_kmap_atomic'
   drivers/gpu/drm/drm_prime.c:438: warning: Function parameter or member 'page_num' not described in 'drm_gem_dmabuf_kmap_atomic'
   drivers/gpu/drm/drm_prime.c:450: warning: Function parameter or member 'dma_buf' not described in 'drm_gem_dmabuf_kunmap_atomic'
   drivers/gpu/drm/drm_prime.c:450: warning: Function parameter or member 'page_num' not described in 'drm_gem_dmabuf_kunmap_atomic'
   drivers/gpu/drm/drm_prime.c:450: warning: Function parameter or member 'addr' not described in 'drm_gem_dmabuf_kunmap_atomic'
   drivers/gpu/drm/drm_prime.c:461: warning: Function parameter or member 'dma_buf' not described in 'drm_gem_dmabuf_kmap'
   drivers/gpu/drm/drm_prime.c:461: warning: Function parameter or member 'page_num' not described in 'drm_gem_dmabuf_kmap'
   drivers/gpu/drm/drm_prime.c:473: warning: Function parameter or member 'dma_buf' not described in 'drm_gem_dmabuf_kunmap'
   drivers/gpu/drm/drm_prime.c:473: warning: Function parameter or member 'page_num' not described in 'drm_gem_dmabuf_kunmap'
   drivers/gpu/drm/drm_prime.c:473: warning: Function parameter or member 'addr' not described in 'drm_gem_dmabuf_kunmap'
   include/media/v4l2-dev.h:42: warning: Enum value 'VFL_TYPE_MAX' not described in enum 'vfl_devnode_type'
   include/linux/skbuff.h:850: warning: Function parameter or member 'dev_scratch' not described in 'sk_buff'
   include/linux/skbuff.h:850: warning: Function parameter or member 'ip_defrag_offset' not described in 'sk_buff'
   include/linux/skbuff.h:850: warning: Function parameter or member 'skb_mstamp' not described in 'sk_buff'
   include/linux/skbuff.h:850: warning: Function parameter or member '__cloned_offset' not described in 'sk_buff'
   include/linux/skbuff.h:850: warning: Function parameter or member 'head_frag' not described in 'sk_buff'
   include/linux/skbuff.h:850: warning: Function parameter or member '__unused' not described in 'sk_buff'
   include/linux/skbuff.h:850: warning: Function parameter or member '__pkt_type_offset' not described in 'sk_buff'
   include/linux/skbuff.h:850: warning: Function parameter or member 'pfmemalloc' not described in 'sk_buff'
   include/linux/skbuff.h:850: warning: Function parameter or member 'encapsulation' not described in 'sk_buff'
   include/linux/skbuff.h:850: warning: Function parameter or member 'encap_hdr_csum' not described in 'sk_buff'
   include/linux/skbuff.h:850: warning: Function parameter or member 'csum_valid' not described in 'sk_buff'
   include/linux/skbuff.h:850: warning: Function parameter or member 'csum_complete_sw' not described in 'sk_buff'
   include/linux/skbuff.h:850: warning: Function parameter or member 'csum_level' not described in 'sk_buff'
   include/linux/skbuff.h:850: warning: Function parameter or member 'inner_protocol_type' not described in 'sk_buff'
   include/linux/skbuff.h:850: warning: Function parameter or member 'remcsum_offload' not described in 'sk_buff'
   include/linux/skbuff.h:850: warning: Function parameter or member 'offload_fwd_mark' not described in 'sk_buff'
   include/linux/skbuff.h:850: warning: Function parameter or member 'offload_mr_fwd_mark' not described in 'sk_buff'
   include/linux/skbuff.h:850: warning: Function parameter or member 'sender_cpu' not described in 'sk_buff'
   include/linux/skbuff.h:850: warning: Function parameter or member 'reserved_tailroom' not described in 'sk_buff'
   include/linux/skbuff.h:850: warning: Function parameter or member 'inner_ipproto' not described in 'sk_buff'
   include/net/sock.h:234: warning: Function parameter or member 'skc_addrpair' not described in 'sock_common'
   include/net/sock.h:234: warning: Function parameter or member 'skc_portpair' not described in 'sock_common'
   include/net/sock.h:234: warning: Function parameter or member 'skc_ipv6only' not described in 'sock_common'
   include/net/sock.h:234: warning: Function parameter or member 'skc_net_refcnt' not described in 'sock_common'
   include/net/sock.h:234: warning: Function parameter or member 'skc_v6_daddr' not described in 'sock_common'
   include/net/sock.h:234: warning: Function parameter or member 'skc_v6_rcv_saddr' not described in 'sock_common'
   include/net/sock.h:234: warning: Function parameter or member 'skc_cookie' not described in 'sock_common'
   include/net/sock.h:234: warning: Function parameter or member 'skc_listener' not described in 'sock_common'
   include/net/sock.h:234: warning: Function parameter or member 'skc_tw_dr' not described in 'sock_common'
   include/net/sock.h:234: warning: Function parameter or member 'skc_rcv_wnd' not described in 'sock_common'
   include/net/sock.h:234: warning: Function parameter or member 'skc_tw_rcv_nxt' not described in 'sock_common'
   include/net/sock.h:488: warning: Function parameter or member 'sk_backlog.rmem_alloc' not described in 'sock'
   include/net/sock.h:488: warning: Function parameter or member 'sk_backlog.len' not described in 'sock'
   include/net/sock.h:488: warning: Function parameter or member 'sk_backlog.head' not described in 'sock'
   include/net/sock.h:488: warning: Function parameter or member 'sk_backlog.tail' not described in 'sock'
   include/net/sock.h:488: warning: Function parameter or member 'sk_wq_raw' not described in 'sock'
   include/net/sock.h:488: warning: Function parameter or member 'tcp_rtx_queue' not described in 'sock'
   include/net/sock.h:488: warning: Function parameter or member 'sk_route_forced_caps' not described in 'sock'
   include/linux/netdevice.h:1955: warning: Function parameter or member 'adj_list.upper' not described in 'net_device'
   include/linux/netdevice.h:1955: warning: Function parameter or member 'adj_list.lower' not described in 'net_device'
   include/linux/netdevice.h:1955: warning: Function parameter or member 'gso_partial_features' not described in 'net_device'
   include/linux/netdevice.h:1955: warning: Function parameter or member 'switchdev_ops' not described in 'net_device'
   include/linux/netdevice.h:1955: warning: Function parameter or member 'l3mdev_ops' not described in 'net_device'
   include/linux/netdevice.h:1955: warning: Function parameter or member 'xfrmdev_ops' not described in 'net_device'
   include/linux/netdevice.h:1955: warning: Function parameter or member 'name_assign_type' not described in 'net_device'
   include/linux/netdevice.h:1955: warning: Function parameter or member 'ieee802154_ptr' not described in 'net_device'
   include/linux/netdevice.h:1955: warning: Function parameter or member 'mpls_ptr' not described in 'net_device'
   include/linux/netdevice.h:1955: warning: Function parameter or member 'xdp_prog' not described in 'net_device'
   include/linux/netdevice.h:1955: warning: Function parameter or member 'gro_flush_timeout' not described in 'net_device'
   include/linux/netdevice.h:1955: warning: Function parameter or member 'nf_hooks_ingress' not described in 'net_device'
   include/linux/netdevice.h:1955: warning: Function parameter or member '____cacheline_aligned_in_smp' not described in 'net_device'
   include/linux/netdevice.h:1955: warning: Function parameter or member 'qdisc_hash' not described in 'net_device'
   include/linux/phylink.h:56: warning: Function parameter or member '__ETHTOOL_DECLARE_LINK_MODE_MASK(advertising' not described in 'phylink_link_state'
   include/linux/phylink.h:56: warning: Function parameter or member '__ETHTOOL_DECLARE_LINK_MODE_MASK(lp_advertising' not described in 'phylink_link_state'

vim +192 include/linux/input.h

4369c64c7 Henrik Rydberg        2012-09-15   38  
4369c64c7 Henrik Rydberg        2012-09-15   39  /**
8006479c9 Dmitry Torokhov       2007-08-30   40   * struct input_dev - represents an input device
8006479c9 Dmitry Torokhov       2007-08-30   41   * @name: name of the device
8006479c9 Dmitry Torokhov       2007-08-30   42   * @phys: physical path to the device in the system hierarchy
8006479c9 Dmitry Torokhov       2007-08-30   43   * @uniq: unique identification code for the device (if device has it)
8006479c9 Dmitry Torokhov       2007-08-30   44   * @id: id of the device (struct input_id)
85b772003 Henrik Rydberg        2010-12-18   45   * @propbit: bitmap of device properties and quirks
8006479c9 Dmitry Torokhov       2007-08-30   46   * @evbit: bitmap of types of events supported by the device (EV_KEY,
8006479c9 Dmitry Torokhov       2007-08-30   47   *	EV_REL, etc.)
8006479c9 Dmitry Torokhov       2007-08-30   48   * @keybit: bitmap of keys/buttons this device has
8006479c9 Dmitry Torokhov       2007-08-30   49   * @relbit: bitmap of relative axes for the device
8006479c9 Dmitry Torokhov       2007-08-30   50   * @absbit: bitmap of absolute axes for the device
8006479c9 Dmitry Torokhov       2007-08-30   51   * @mscbit: bitmap of miscellaneous events supported by the device
8006479c9 Dmitry Torokhov       2007-08-30   52   * @ledbit: bitmap of leds present on the device
8006479c9 Dmitry Torokhov       2007-08-30   53   * @sndbit: bitmap of sound effects supported by the device
8006479c9 Dmitry Torokhov       2007-08-30   54   * @ffbit: bitmap of force feedback effects supported by the device
8006479c9 Dmitry Torokhov       2007-08-30   55   * @swbit: bitmap of switches present on the device
63a6404d8 Henrik Rydberg        2010-06-10   56   * @hint_events_per_packet: average number of events generated by the
63a6404d8 Henrik Rydberg        2010-06-10   57   *	device in a packet (between EV_SYN/SYN_REPORT events). Used by
63a6404d8 Henrik Rydberg        2010-06-10   58   *	event handlers to estimate size of the buffer needed to hold
63a6404d8 Henrik Rydberg        2010-06-10   59   *	events.
8006479c9 Dmitry Torokhov       2007-08-30   60   * @keycodemax: size of keycode table
8006479c9 Dmitry Torokhov       2007-08-30   61   * @keycodesize: size of elements in keycode table
8006479c9 Dmitry Torokhov       2007-08-30   62   * @keycode: map of scancodes to keycodes for this device
8613e4c28 Mauro Carvalho Chehab 2010-09-09   63   * @getkeycode: optional legacy method to retrieve current keymap.
8006479c9 Dmitry Torokhov       2007-08-30   64   * @setkeycode: optional method to alter current keymap, used to implement
66d2a5952 Dmitry Torokhov       2009-12-01   65   *	sparse keymaps. If not supplied default mechanism will be used.
66d2a5952 Dmitry Torokhov       2009-12-01   66   *	The method is being called while holding event_lock and thus must
66d2a5952 Dmitry Torokhov       2009-12-01   67   *	not sleep
8006479c9 Dmitry Torokhov       2007-08-30   68   * @ff: force feedback structure associated with the device if device
8006479c9 Dmitry Torokhov       2007-08-30   69   *	supports force feedback effects
8006479c9 Dmitry Torokhov       2007-08-30   70   * @repeat_key: stores key code of the last key pressed; used to implement
8006479c9 Dmitry Torokhov       2007-08-30   71   *	software autorepeat
8006479c9 Dmitry Torokhov       2007-08-30   72   * @timer: timer for software autorepeat
8006479c9 Dmitry Torokhov       2007-08-30   73   * @rep: current values for autorepeat parameters (delay, rate)
8d18fba28 Henrik Rydberg        2012-09-15   74   * @mt: pointer to multitouch state
86b17f76f Dmitry Torokhov       2010-11-29   75   * @absinfo: array of &struct input_absinfo elements holding information
d31b2865a Daniel Mack           2010-08-02   76   *	about absolute axes (current value, min, max, flat, fuzz,
d31b2865a Daniel Mack           2010-08-02   77   *	resolution)
8006479c9 Dmitry Torokhov       2007-08-30   78   * @key: reflects current state of device's keys/buttons
8006479c9 Dmitry Torokhov       2007-08-30   79   * @led: reflects current state of device's LEDs
8006479c9 Dmitry Torokhov       2007-08-30   80   * @snd: reflects current state of sound effects
8006479c9 Dmitry Torokhov       2007-08-30   81   * @sw: reflects current state of device's switches
8006479c9 Dmitry Torokhov       2007-08-30   82   * @open: this method is called when the very first user calls
8006479c9 Dmitry Torokhov       2007-08-30   83   *	input_open_device(). The driver must prepare the device
8006479c9 Dmitry Torokhov       2007-08-30   84   *	to start generating events (start polling thread,
8006479c9 Dmitry Torokhov       2007-08-30   85   *	request an IRQ, submit URB, etc.)
8006479c9 Dmitry Torokhov       2007-08-30   86   * @close: this method is called when the very last user calls
8006479c9 Dmitry Torokhov       2007-08-30   87   *	input_close_device().
8006479c9 Dmitry Torokhov       2007-08-30   88   * @flush: purges the device. Most commonly used to get rid of force
8006479c9 Dmitry Torokhov       2007-08-30   89   *	feedback effects loaded into the device when disconnecting
8006479c9 Dmitry Torokhov       2007-08-30   90   *	from it
8006479c9 Dmitry Torokhov       2007-08-30   91   * @event: event handler for events sent _to_ the device, like EV_LED
8006479c9 Dmitry Torokhov       2007-08-30   92   *	or EV_SND. The device is expected to carry out the requested
8006479c9 Dmitry Torokhov       2007-08-30   93   *	action (turn on a LED, play sound, etc.) The call is protected
8006479c9 Dmitry Torokhov       2007-08-30   94   *	by @event_lock and must not sleep
8006479c9 Dmitry Torokhov       2007-08-30   95   * @grab: input handle that currently has the device grabbed (via
8006479c9 Dmitry Torokhov       2007-08-30   96   *	EVIOCGRAB ioctl). When a handle grabs a device it becomes sole
8006479c9 Dmitry Torokhov       2007-08-30   97   *	recipient for all input events coming from the device
83510e5f5 Masanari Iida         2016-07-13   98   * @event_lock: this spinlock is taken when input core receives
8006479c9 Dmitry Torokhov       2007-08-30   99   *	and processes a new event for the device (in input_event()).
8006479c9 Dmitry Torokhov       2007-08-30  100   *	Code that accesses and/or modifies parameters of a device
8006479c9 Dmitry Torokhov       2007-08-30  101   *	(such as keymap or absmin, absmax, absfuzz, etc.) after device
8006479c9 Dmitry Torokhov       2007-08-30  102   *	has been registered with input core must take this lock.
8006479c9 Dmitry Torokhov       2007-08-30  103   * @mutex: serializes calls to open(), close() and flush() methods
8006479c9 Dmitry Torokhov       2007-08-30  104   * @users: stores number of users (input handlers) that opened this
8006479c9 Dmitry Torokhov       2007-08-30  105   *	device. It is used by input_open_device() and input_close_device()
8006479c9 Dmitry Torokhov       2007-08-30  106   *	to make sure that dev->open() is only called when the first
8006479c9 Dmitry Torokhov       2007-08-30  107   *	user opens device and dev->close() is called when the very
8006479c9 Dmitry Torokhov       2007-08-30  108   *	last user closes the device
8006479c9 Dmitry Torokhov       2007-08-30  109   * @going_away: marks devices that are in a middle of unregistering and
8006479c9 Dmitry Torokhov       2007-08-30  110   *	causes input_open_device*() fail with -ENODEV.
8006479c9 Dmitry Torokhov       2007-08-30  111   * @dev: driver model's view of this device
8006479c9 Dmitry Torokhov       2007-08-30  112   * @h_list: list of input handles associated with the device. When
8006479c9 Dmitry Torokhov       2007-08-30  113   *	accessing the list dev->mutex must be held
8006479c9 Dmitry Torokhov       2007-08-30  114   * @node: used to place the device onto input_dev_list
800963fd5 Henrik Rydberg        2012-11-10  115   * @num_vals: number of values queued in the current frame
800963fd5 Henrik Rydberg        2012-11-10  116   * @max_vals: maximum number of values queued in a frame
800963fd5 Henrik Rydberg        2012-11-10  117   * @vals: array of values queued in the current frame
2be975c6d Dmitry Torokhov       2012-11-03  118   * @devres_managed: indicates that devices is managed with devres framework
2be975c6d Dmitry Torokhov       2012-11-03  119   *	and needs not be explicitly unregistered or freed.
8006479c9 Dmitry Torokhov       2007-08-30  120   */
^1da177e4 Linus Torvalds        2005-04-16  121  struct input_dev {
5b6271bda Dmitry Torokhov       2005-06-30  122  	const char *name;
5b6271bda Dmitry Torokhov       2005-06-30  123  	const char *phys;
5b6271bda Dmitry Torokhov       2005-06-30  124  	const char *uniq;
^1da177e4 Linus Torvalds        2005-04-16  125  	struct input_id id;
^1da177e4 Linus Torvalds        2005-04-16  126  
85b772003 Henrik Rydberg        2010-12-18  127  	unsigned long propbit[BITS_TO_LONGS(INPUT_PROP_CNT)];
85b772003 Henrik Rydberg        2010-12-18  128  
7b19ada2e Jiri Slaby            2007-10-18  129  	unsigned long evbit[BITS_TO_LONGS(EV_CNT)];
7b19ada2e Jiri Slaby            2007-10-18  130  	unsigned long keybit[BITS_TO_LONGS(KEY_CNT)];
7b19ada2e Jiri Slaby            2007-10-18  131  	unsigned long relbit[BITS_TO_LONGS(REL_CNT)];
7b19ada2e Jiri Slaby            2007-10-18  132  	unsigned long absbit[BITS_TO_LONGS(ABS_CNT)];
7b19ada2e Jiri Slaby            2007-10-18  133  	unsigned long mscbit[BITS_TO_LONGS(MSC_CNT)];
7b19ada2e Jiri Slaby            2007-10-18  134  	unsigned long ledbit[BITS_TO_LONGS(LED_CNT)];
7b19ada2e Jiri Slaby            2007-10-18  135  	unsigned long sndbit[BITS_TO_LONGS(SND_CNT)];
7b19ada2e Jiri Slaby            2007-10-18  136  	unsigned long ffbit[BITS_TO_LONGS(FF_CNT)];
7b19ada2e Jiri Slaby            2007-10-18  137  	unsigned long swbit[BITS_TO_LONGS(SW_CNT)];
^1da177e4 Linus Torvalds        2005-04-16  138  
63a6404d8 Henrik Rydberg        2010-06-10  139  	unsigned int hint_events_per_packet;
63a6404d8 Henrik Rydberg        2010-06-10  140  
^1da177e4 Linus Torvalds        2005-04-16  141  	unsigned int keycodemax;
^1da177e4 Linus Torvalds        2005-04-16  142  	unsigned int keycodesize;
^1da177e4 Linus Torvalds        2005-04-16  143  	void *keycode;
8613e4c28 Mauro Carvalho Chehab 2010-09-09  144  
58b939959 Dmitry Torokhov       2010-03-08  145  	int (*setkeycode)(struct input_dev *dev,
8613e4c28 Mauro Carvalho Chehab 2010-09-09  146  			  const struct input_keymap_entry *ke,
8613e4c28 Mauro Carvalho Chehab 2010-09-09  147  			  unsigned int *old_keycode);
aebd636bd Dmitry Torokhov       2011-01-31  148  	int (*getkeycode)(struct input_dev *dev,
8613e4c28 Mauro Carvalho Chehab 2010-09-09  149  			  struct input_keymap_entry *ke);
^1da177e4 Linus Torvalds        2005-04-16  150  
509ca1a93 Anssi Hannula         2006-07-19  151  	struct ff_device *ff;
509ca1a93 Anssi Hannula         2006-07-19  152  
507fbe1d7 Pavel Machek          2018-12-15  153  	int debounce_key;
^1da177e4 Linus Torvalds        2005-04-16  154  	unsigned int repeat_key;
^1da177e4 Linus Torvalds        2005-04-16  155  	struct timer_list timer;
^1da177e4 Linus Torvalds        2005-04-16  156  
d31b2865a Daniel Mack           2010-08-02  157  	int rep[REP_CNT];
^1da177e4 Linus Torvalds        2005-04-16  158  
8d18fba28 Henrik Rydberg        2012-09-15  159  	struct input_mt *mt;
40d007e7d Henrik Rydberg        2010-07-15  160  
d31b2865a Daniel Mack           2010-08-02  161  	struct input_absinfo *absinfo;
d31b2865a Daniel Mack           2010-08-02  162  
7b19ada2e Jiri Slaby            2007-10-18  163  	unsigned long key[BITS_TO_LONGS(KEY_CNT)];
7b19ada2e Jiri Slaby            2007-10-18  164  	unsigned long led[BITS_TO_LONGS(LED_CNT)];
7b19ada2e Jiri Slaby            2007-10-18  165  	unsigned long snd[BITS_TO_LONGS(SND_CNT)];
7b19ada2e Jiri Slaby            2007-10-18  166  	unsigned long sw[BITS_TO_LONGS(SW_CNT)];
^1da177e4 Linus Torvalds        2005-04-16  167  
^1da177e4 Linus Torvalds        2005-04-16  168  	int (*open)(struct input_dev *dev);
^1da177e4 Linus Torvalds        2005-04-16  169  	void (*close)(struct input_dev *dev);
^1da177e4 Linus Torvalds        2005-04-16  170  	int (*flush)(struct input_dev *dev, struct file *file);
^1da177e4 Linus Torvalds        2005-04-16  171  	int (*event)(struct input_dev *dev, unsigned int type, unsigned int code, int value);
^1da177e4 Linus Torvalds        2005-04-16  172  
2be852792 Arnd Bergmann         2010-03-04  173  	struct input_handle __rcu *grab;
0fbf87caf Dmitry Torokhov       2005-05-29  174  
8006479c9 Dmitry Torokhov       2007-08-30  175  	spinlock_t event_lock;
8006479c9 Dmitry Torokhov       2007-08-30  176  	struct mutex mutex;
8006479c9 Dmitry Torokhov       2007-08-30  177  
0fbf87caf Dmitry Torokhov       2005-05-29  178  	unsigned int users;
ffd0db971 Dmitry Torokhov       2009-09-16  179  	bool going_away;
0fbf87caf Dmitry Torokhov       2005-05-29  180  
9657d75c5 Dmitry Torokhov       2007-06-14  181  	struct device dev;
^1da177e4 Linus Torvalds        2005-04-16  182  
^1da177e4 Linus Torvalds        2005-04-16  183  	struct list_head	h_list;
^1da177e4 Linus Torvalds        2005-04-16  184  	struct list_head	node;
4369c64c7 Henrik Rydberg        2012-09-15  185  
4369c64c7 Henrik Rydberg        2012-09-15  186  	unsigned int num_vals;
4369c64c7 Henrik Rydberg        2012-09-15  187  	unsigned int max_vals;
4369c64c7 Henrik Rydberg        2012-09-15  188  	struct input_value *vals;
2be975c6d Dmitry Torokhov       2012-11-03  189  
2be975c6d Dmitry Torokhov       2012-11-03  190  	bool devres_managed;
^1da177e4 Linus Torvalds        2005-04-16  191  };
9657d75c5 Dmitry Torokhov       2007-06-14 @192  #define to_input_dev(d) container_of(d, struct input_dev, dev)
^1da177e4 Linus Torvalds        2005-04-16  193  

:::::: The code at line 192 was first introduced by commit
:::::: 9657d75c5f0f7d0a9cb507521d3ad1436aea28c9 Input: convert from class devices to standard devices

:::::: TO: Dmitry Torokhov <dtor@insightbb.com>
:::::: CC: Dmitry Torokhov <dtor@insightbb.com>

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation
diff mbox series

Patch

diff --git a/drivers/input/input.c b/drivers/input/input.c
index 3304aaa..ce0d081 100644
--- a/drivers/input/input.c
+++ b/drivers/input/input.c
@@ -40,6 +40,11 @@  static DEFINE_IDA(input_ida);
 static LIST_HEAD(input_dev_list);
 static LIST_HEAD(input_handler_list);
 
+static void input_repeat_key(struct timer_list *t);
+static void input_debounce_key(struct timer_list *t);
+
+static int debounce = 20;
+
 /*
  * input_mutex protects access to both input_dev_list and input_handler_list.
  * This also causes input_[un]register_device and input_[un]register_handler
@@ -77,6 +82,7 @@  static void input_start_autorepeat(struct input_dev *dev, int code)
 	if (test_bit(EV_REP, dev->evbit) &&
 	    dev->rep[REP_PERIOD] && dev->rep[REP_DELAY] &&
 	    dev->timer.function) {
+		dev->timer.function = input_repeat_key;
 		dev->repeat_key = code;
 		mod_timer(&dev->timer,
 			  jiffies + msecs_to_jiffies(dev->rep[REP_DELAY]));
@@ -88,18 +94,42 @@  static void input_stop_autorepeat(struct input_dev *dev)
 	del_timer(&dev->timer);
 }
 
+static void input_start_debounce(struct input_dev *dev, int code)
+{
+	dev->timer.function = input_debounce_key;
+	dev->debounce_key = code;
+	mod_timer(&dev->timer,
+		  jiffies + msecs_to_jiffies(debounce));
+}
+
+static void input_stop_debounce(struct input_dev *dev)
+{
+	del_timer(&dev->timer);
+	dev->debounce_key = -1;
+}
+
 /*
  * Pass event first through all filters and then, if event has not been
  * filtered out, through all open handles. This function is called with
  * dev->event_lock held and interrupts disabled.
  */
-static unsigned int input_to_handler(struct input_handle *handle,
+static unsigned int input_to_handler(struct input_dev *dev, struct input_handle *handle,
 			struct input_value *vals, unsigned int count)
 {
 	struct input_handler *handler = handle->handler;
 	struct input_value *end = vals;
 	struct input_value *v;
 
+	if (!test_bit(EV_REP, dev->evbit) && test_bit(EV_KEY, dev->evbit) && debounce)
+		for (v = vals; v != vals + count; v++) {
+			if (v->type == EV_KEY && v->value == 0 && dev->debounce_key == -1) {
+				input_start_debounce(dev, v->code);
+				v->code = -2;
+			}
+			if (v->type == EV_KEY && v->value == 1 && dev->debounce_key == v->code)
+				input_stop_debounce(dev);
+		}
+
 	if (handler->filter) {
 		for (v = vals; v != vals + count; v++) {
 			if (handler->filter(handle, v->type, v->code, v->value))
@@ -117,8 +147,9 @@  static unsigned int input_to_handler(struct input_handle *handle,
 	if (handler->events)
 		handler->events(handle, vals, count);
 	else if (handler->event)
-		for (v = vals; v != vals + count; v++)
+		for (v = vals; v != vals + count; v++) {
 			handler->event(handle, v->type, v->code, v->value);
+		}
 
 	return count;
 }
@@ -141,11 +172,11 @@  static void input_pass_values(struct input_dev *dev,
 
 	handle = rcu_dereference(dev->grab);
 	if (handle) {
-		count = input_to_handler(handle, vals, count);
+		count = input_to_handler(dev, handle, vals, count);
 	} else {
 		list_for_each_entry_rcu(handle, &dev->h_list, d_node)
 			if (handle->open) {
-				count = input_to_handler(handle, vals, count);
+				count = input_to_handler(dev, handle, vals, count);
 				if (!count)
 					break;
 			}
@@ -203,6 +234,27 @@  static void input_repeat_key(struct timer_list *t)
 	spin_unlock_irqrestore(&dev->event_lock, flags);
 }
 
+/*
+ * Generate software autorepeat event. Note that we take
+ * dev->event_lock here to avoid racing with input_event
+ * which may cause keys get "stuck".
+ */
+static void input_debounce_key(struct timer_list *t)
+{
+	struct input_dev *dev = from_timer(dev, t, timer);
+	unsigned long flags;
+
+	struct input_value vals[] =  {
+		{ EV_KEY, dev->debounce_key, 0 },
+		input_value_sync
+	};
+
+	spin_lock_irqsave(&dev->event_lock, flags);
+	input_pass_values(dev, vals, ARRAY_SIZE(vals));
+	input_stop_debounce(dev);
+	spin_unlock_irqrestore(&dev->event_lock, flags);
+}
+
 #define INPUT_IGNORE_EVENT	0
 #define INPUT_PASS_TO_HANDLERS	1
 #define INPUT_PASS_TO_DEVICE	2
@@ -2109,6 +2161,8 @@  int input_register_device(struct input_dev *dev)
 	/* Every input device generates EV_SYN/SYN_REPORT events. */
 	__set_bit(EV_SYN, dev->evbit);
 
+	dev->debounce_key = -1;
+
 	/* KEY_RESERVED is not supposed to be transmitted to userspace. */
 	__clear_bit(KEY_RESERVED, dev->keybit);
 
diff --git a/include/linux/input.h b/include/linux/input.h
index 7c7516e..b2458b2 100644
--- a/include/linux/input.h
+++ b/include/linux/input.h
@@ -150,6 +150,7 @@  struct input_dev {
 
 	struct ff_device *ff;
 
+	int debounce_key;
 	unsigned int repeat_key;
 	struct timer_list timer;