diff options
author | John Crispin <john@openwrt.org> | 2015-03-16 07:41:24 +0000 |
---|---|---|
committer | John Crispin <john@openwrt.org> | 2015-03-16 07:41:24 +0000 |
commit | c0a15a57bda510fac081d536013d16446baf6813 (patch) | |
tree | 941690d0c41e1342dbcdac9639e64605e230af51 /target/linux/sunxi/patches-3.14/284-ir-backports-from-3.15.patch | |
parent | eb396d656911024685f1f514036aec091669211f (diff) | |
download | upstream-c0a15a57bda510fac081d536013d16446baf6813.tar.gz upstream-c0a15a57bda510fac081d536013d16446baf6813.tar.bz2 upstream-c0a15a57bda510fac081d536013d16446baf6813.zip |
sunxi: drop 3.14 support
Signed-off-by: John Crispin <blogic@openwrt.org>
SVN-Revision: 44824
Diffstat (limited to 'target/linux/sunxi/patches-3.14/284-ir-backports-from-3.15.patch')
-rw-r--r-- | target/linux/sunxi/patches-3.14/284-ir-backports-from-3.15.patch | 1210 |
1 files changed, 0 insertions, 1210 deletions
diff --git a/target/linux/sunxi/patches-3.14/284-ir-backports-from-3.15.patch b/target/linux/sunxi/patches-3.14/284-ir-backports-from-3.15.patch deleted file mode 100644 index 9e703e7dce..0000000000 --- a/target/linux/sunxi/patches-3.14/284-ir-backports-from-3.15.patch +++ /dev/null @@ -1,1210 +0,0 @@ -From 00942d1a1bd93ac108c1b92d504c568a37be1833 Mon Sep 17 00:00:00 2001 -From: James Hogan <james.hogan@imgtec.com> -Date: Fri, 17 Jan 2014 10:58:49 -0300 -Subject: [PATCH] [media] media: rc: add sysfs scancode filtering interface - -Add and document a generic sysfs based scancode filtering interface for -making use of IR data matching hardware to filter out uninteresting -scancodes. Two filters exist, one for normal operation and one for -filtering scancodes which are permitted to wake the system from suspend. - -The following files are added to /sys/class/rc/rc?/: - - filter: normal scancode filter value - - filter_mask: normal scancode filter mask - - wakeup_filter: wakeup scancode filter value - - wakeup_filter_mask: wakeup scancode filter mask - -A new s_filter() driver callback is added which must arrange for the -specified filter to be applied at the right time. Drivers can convert -the scancode filter into a raw IR data filter, which can be applied -immediately or later (for wake up filters). - -Signed-off-by: James Hogan <james.hogan@imgtec.com> -Cc: Mauro Carvalho Chehab <m.chehab@samsung.com> -Cc: linux-media@vger.kernel.org -Cc: Rob Landley <rob@landley.net> -Cc: linux-doc@vger.kernel.org -Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com> ---- - Documentation/ABI/testing/sysfs-class-rc | 58 +++++++++++++ - drivers/media/rc/rc-main.c | 136 +++++++++++++++++++++++++++++++ - include/media/rc-core.h | 29 +++++++ - 3 files changed, 223 insertions(+) - -From 7b802ce7e8c67510389fdbbe29edd87a75df3a93 Mon Sep 17 00:00:00 2001 -From: James Hogan <james.hogan@imgtec.com> -Date: Mon, 10 Feb 2014 18:31:56 -0300 -Subject: [PATCH] [media] rc-main: store_filter: pass errors to userland -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Propagate errors returned by drivers from the s_filter callback back to -userland when updating scancode filters. This allows userland to see -when the filter couldn't be updated, usually because it's not a valid -filter for the hardware. - -Previously the filter was being updated conditionally on success of -s_filter, but the write always reported success back to userland. - -Reported-by: Antti Seppälä <a.seppala@gmail.com> -Signed-off-by: James Hogan <james.hogan@imgtec.com> -Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com> ---- - drivers/media/rc/rc-main.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -From b8c7d915087c97a21fa415fa0e860e59739da202 Mon Sep 17 00:00:00 2001 -From: James Hogan <james.hogan@imgtec.com> -Date: Fri, 28 Feb 2014 20:17:02 -0300 -Subject: [PATCH] [media] rc-main: add generic scancode filtering -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Add generic scancode filtering of RC input events, and fall back to -permitting any RC_FILTER_NORMAL scancode filter to be set if no s_filter -callback exists. This allows raw IR decoder events to be filtered, and -potentially allows hardware decoders to set looser filters and rely on -generic code to filter out the corner cases. - -Signed-off-by: James Hogan <james.hogan@imgtec.com> -Reviewed-by: Antti Seppälä <a.seppala@gmail.com> -Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com> ---- - drivers/media/rc/rc-main.c | 20 +++++++++++++------- - 1 file changed, 13 insertions(+), 7 deletions(-) - -From 1a1934fab0c920f0d3bceeb60c9fe2dae8a56be9 Mon Sep 17 00:00:00 2001 -From: James Hogan <james.hogan@imgtec.com> -Date: Fri, 28 Feb 2014 20:17:03 -0300 -Subject: [PATCH] [media] rc: abstract access to allowed/enabled protocols -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -The allowed and enabled protocol masks need to be expanded to be per -filter type in order to support wakeup filter protocol selection. To -ease that process abstract access to the rc_dev::allowed_protos and -rc_dev::enabled_protocols members with inline functions. - -Signed-off-by: James Hogan <james.hogan@imgtec.com> -Reviewed-by: Antti Seppälä <a.seppala@gmail.com> -Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com> ---- - drivers/hid/hid-picolcd_cir.c | 2 +- - drivers/media/common/siano/smsir.c | 2 +- - drivers/media/i2c/ir-kbd-i2c.c | 4 ++-- - drivers/media/pci/cx23885/cx23885-input.c | 2 +- - drivers/media/pci/cx88/cx88-input.c | 2 +- - drivers/media/rc/ati_remote.c | 2 +- - drivers/media/rc/ene_ir.c | 2 +- - drivers/media/rc/fintek-cir.c | 2 +- - drivers/media/rc/gpio-ir-recv.c | 4 ++-- - drivers/media/rc/iguanair.c | 2 +- - drivers/media/rc/imon.c | 7 ++++--- - drivers/media/rc/ir-jvc-decoder.c | 2 +- - drivers/media/rc/ir-lirc-codec.c | 2 +- - drivers/media/rc/ir-mce_kbd-decoder.c | 2 +- - drivers/media/rc/ir-nec-decoder.c | 2 +- - drivers/media/rc/ir-raw.c | 2 +- - drivers/media/rc/ir-rc5-decoder.c | 6 +++--- - drivers/media/rc/ir-rc5-sz-decoder.c | 2 +- - drivers/media/rc/ir-rc6-decoder.c | 6 +++--- - drivers/media/rc/ir-sanyo-decoder.c | 2 +- - drivers/media/rc/ir-sharp-decoder.c | 2 +- - drivers/media/rc/ir-sony-decoder.c | 10 +++++----- - drivers/media/rc/ite-cir.c | 2 +- - drivers/media/rc/mceusb.c | 2 +- - drivers/media/rc/nuvoton-cir.c | 2 +- - drivers/media/rc/rc-loopback.c | 2 +- - drivers/media/rc/redrat3.c | 2 +- - drivers/media/rc/st_rc.c | 2 +- - drivers/media/rc/streamzap.c | 2 +- - drivers/media/rc/ttusbir.c | 2 +- - drivers/media/rc/winbond-cir.c | 2 +- - drivers/media/usb/dvb-usb-v2/dvb_usb_core.c | 2 +- - drivers/media/usb/dvb-usb/dvb-usb-remote.c | 2 +- - drivers/media/usb/em28xx/em28xx-input.c | 8 ++++---- - drivers/media/usb/tm6000/tm6000-input.c | 2 +- - include/media/rc-core.h | 22 ++++++++++++++++++++++ - 36 files changed, 73 insertions(+), 50 deletions(-) - -From acff5f24732acc8a55d0a0f0ee1d19442267df63 Mon Sep 17 00:00:00 2001 -From: James Hogan <james.hogan@imgtec.com> -Date: Fri, 28 Feb 2014 20:17:04 -0300 -Subject: [PATCH] [media] rc: add allowed/enabled wakeup protocol masks -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Only a single allowed and enabled protocol mask currently exists in -struct rc_dev, however to support a separate wakeup filter protocol two -of each are needed, ideally as an array. - -Therefore make both rc_dev::allowed_protos and rc_dev::enabled_protocols -arrays, update all users to reference the first element -(RC_FILTER_NORMAL), and add a couple more helper functions for drivers -to use for setting the allowed and enabled wakeup protocols. - -We also rename allowed_protos to allowed_protocols while we're at it, -which is more consistent with enabled_protocols. - -Signed-off-by: James Hogan <james.hogan@imgtec.com> -Reviewed-by: Antti Seppälä <a.seppala@gmail.com> -Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com> ---- - drivers/media/rc/rc-main.c | 10 +++++----- - include/media/rc-core.h | 32 ++++++++++++++++++++++++-------- - 2 files changed, 29 insertions(+), 13 deletions(-) - -From ab88c66deace78989aa71cb139284cf7fb227ba4 Mon Sep 17 00:00:00 2001 -From: James Hogan <james.hogan@imgtec.com> -Date: Fri, 28 Feb 2014 20:17:05 -0300 -Subject: [PATCH] [media] rc: add wakeup_protocols sysfs file -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Add a wakeup_protocols sysfs file which controls the new -rc_dev::enabled_protocols[RC_FILTER_WAKEUP], which is the mask of -protocols that are used for the wakeup filter. - -A new RC driver callback change_wakeup_protocol() is called to change -the wakeup protocol mask. - -Signed-off-by: James Hogan <james.hogan@imgtec.com> -Reviewed-by: Antti Seppälä <a.seppala@gmail.com> -Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com> ---- - Documentation/ABI/testing/sysfs-class-rc | 23 +++++- - .../DocBook/media/v4l/remote_controllers.xml | 20 +++++- - drivers/media/rc/rc-main.c | 82 +++++++++++++--------- - include/media/rc-core.h | 3 + - 4 files changed, 90 insertions(+), 38 deletions(-) - -From 6bea25af147fcddcd8fd4557f4184c847c5c6ffd Mon Sep 17 00:00:00 2001 -From: James Hogan <james.hogan@imgtec.com> -Date: Fri, 28 Feb 2014 20:17:06 -0300 -Subject: [PATCH] [media] rc-main: automatically refresh filter on protocol - change -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -When either of the normal or wakeup filter protocols are changed, -refresh the corresponding scancode filter, i.e. try and set the same -scancode filter with the new protocol. If that fails clear the filter -instead. - -If no protocol was selected the filter is just cleared, and if no -s_filter callback exists the filter is left unmodified. - -Similarly clear the filter mask when the filter is set if no protocol is -currently selected. - -This simplifies driver code which no longer has to explicitly worry -about modifying the filter on a protocol change. This also allows the -change_wakeup_protocol callback to be omitted entirely if there is only -a single available wakeup protocol at a time, since selecting no -protocol will automatically clear the wakeup filter, disabling wakeup. - -Signed-off-by: James Hogan <james.hogan@imgtec.com> -Reviewed-by: Antti Seppälä <a.seppala@gmail.com> -Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com> ---- - drivers/media/rc/rc-main.c | 41 +++++++++++++++++++++++++++++++++++++++-- - 1 file changed, 39 insertions(+), 2 deletions(-) - -From 262912335c823a2bbcc87003ee55d62cc27f4e48 Mon Sep 17 00:00:00 2001 -From: James Hogan <james.hogan@imgtec.com> -Date: Sat, 1 Mar 2014 19:52:25 -0300 -Subject: [PATCH] [media] rc-main: fix missing unlock if no devno left - -While playing with make coccicheck I noticed this message: -drivers/media/rc/rc-main.c:1245:3-9: preceding lock on line 1238 - -It was introduced by commit 587d1b06e07b ([media] rc-core: reuse device -numbers) which returns -ENOMEM after a mutex_lock without first -unlocking it when there are no more device numbers left. The added code -doesn't depend on the device lock, so move it before the lock is taken. - -Signed-off-by: James Hogan <james.hogan@imgtec.com> -Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com> ---- - drivers/media/rc/rc-main.c | 16 ++++++++-------- - 1 file changed, 8 insertions(+), 8 deletions(-) - ---- a/drivers/hid/hid-picolcd_cir.c -+++ b/drivers/hid/hid-picolcd_cir.c -@@ -114,7 +114,7 @@ int picolcd_init_cir(struct picolcd_data - - rdev->priv = data; - rdev->driver_type = RC_DRIVER_IR_RAW; -- rdev->allowed_protos = RC_BIT_ALL; -+ rc_set_allowed_protocols(rdev, RC_BIT_ALL); - rdev->open = picolcd_cir_open; - rdev->close = picolcd_cir_close; - rdev->input_name = data->hdev->name; ---- a/drivers/media/common/siano/smsir.c -+++ b/drivers/media/common/siano/smsir.c -@@ -88,7 +88,7 @@ int sms_ir_init(struct smscore_device_t - - dev->priv = coredev; - dev->driver_type = RC_DRIVER_IR_RAW; -- dev->allowed_protos = RC_BIT_ALL; -+ rc_set_allowed_protocols(dev, RC_BIT_ALL); - dev->map_name = sms_get_board(board_id)->rc_codes; - dev->driver_name = MODULE_NAME; - ---- a/drivers/media/i2c/ir-kbd-i2c.c -+++ b/drivers/media/i2c/ir-kbd-i2c.c -@@ -431,8 +431,8 @@ static int ir_probe(struct i2c_client *c - * Initialize the other fields of rc_dev - */ - rc->map_name = ir->ir_codes; -- rc->allowed_protos = rc_type; -- rc->enabled_protocols = rc_type; -+ rc_set_allowed_protocols(rc, rc_type); -+ rc_set_enabled_protocols(rc, rc_type); - if (!rc->driver_name) - rc->driver_name = MODULE_NAME; - ---- a/drivers/media/pci/cx23885/cx23885-input.c -+++ b/drivers/media/pci/cx23885/cx23885-input.c -@@ -346,7 +346,7 @@ int cx23885_input_init(struct cx23885_de - } - rc->dev.parent = &dev->pci->dev; - rc->driver_type = driver_type; -- rc->allowed_protos = allowed_protos; -+ rc_set_allowed_protocols(rc, allowed_protos); - rc->priv = kernel_ir; - rc->open = cx23885_input_ir_open; - rc->close = cx23885_input_ir_close; ---- a/drivers/media/pci/cx88/cx88-input.c -+++ b/drivers/media/pci/cx88/cx88-input.c -@@ -469,7 +469,7 @@ int cx88_ir_init(struct cx88_core *core, - dev->timeout = 10 * 1000 * 1000; /* 10 ms */ - } else { - dev->driver_type = RC_DRIVER_SCANCODE; -- dev->allowed_protos = rc_type; -+ rc_set_allowed_protocols(dev, rc_type); - } - - ir->core = core; ---- a/drivers/media/rc/ati_remote.c -+++ b/drivers/media/rc/ati_remote.c -@@ -784,7 +784,7 @@ static void ati_remote_rc_init(struct at - - rdev->priv = ati_remote; - rdev->driver_type = RC_DRIVER_SCANCODE; -- rdev->allowed_protos = RC_BIT_OTHER; -+ rc_set_allowed_protocols(rdev, RC_BIT_OTHER); - rdev->driver_name = "ati_remote"; - - rdev->open = ati_remote_rc_open; ---- a/drivers/media/rc/ene_ir.c -+++ b/drivers/media/rc/ene_ir.c -@@ -1059,7 +1059,7 @@ static int ene_probe(struct pnp_dev *pnp - learning_mode_force = false; - - rdev->driver_type = RC_DRIVER_IR_RAW; -- rdev->allowed_protos = RC_BIT_ALL; -+ rc_set_allowed_protocols(rdev, RC_BIT_ALL); - rdev->priv = dev; - rdev->open = ene_open; - rdev->close = ene_close; ---- a/drivers/media/rc/fintek-cir.c -+++ b/drivers/media/rc/fintek-cir.c -@@ -541,7 +541,7 @@ static int fintek_probe(struct pnp_dev * - /* Set up the rc device */ - rdev->priv = fintek; - rdev->driver_type = RC_DRIVER_IR_RAW; -- rdev->allowed_protos = RC_BIT_ALL; -+ rc_set_allowed_protocols(rdev, RC_BIT_ALL); - rdev->open = fintek_open; - rdev->close = fintek_close; - rdev->input_name = FINTEK_DESCRIPTION; ---- a/drivers/media/rc/gpio-ir-recv.c -+++ b/drivers/media/rc/gpio-ir-recv.c -@@ -145,9 +145,9 @@ static int gpio_ir_recv_probe(struct pla - rcdev->dev.parent = &pdev->dev; - rcdev->driver_name = GPIO_IR_DRIVER_NAME; - if (pdata->allowed_protos) -- rcdev->allowed_protos = pdata->allowed_protos; -+ rc_set_allowed_protocols(rcdev, pdata->allowed_protos); - else -- rcdev->allowed_protos = RC_BIT_ALL; -+ rc_set_allowed_protocols(rcdev, RC_BIT_ALL); - rcdev->map_name = pdata->map_name ?: RC_MAP_EMPTY; - - gpio_dev->rcdev = rcdev; ---- a/drivers/media/rc/iguanair.c -+++ b/drivers/media/rc/iguanair.c -@@ -494,7 +494,7 @@ static int iguanair_probe(struct usb_int - usb_to_input_id(ir->udev, &rc->input_id); - rc->dev.parent = &intf->dev; - rc->driver_type = RC_DRIVER_IR_RAW; -- rc->allowed_protos = RC_BIT_ALL; -+ rc_set_allowed_protocols(rc, RC_BIT_ALL); - rc->priv = ir; - rc->open = iguanair_open; - rc->close = iguanair_close; ---- a/drivers/media/rc/imon.c -+++ b/drivers/media/rc/imon.c -@@ -1017,7 +1017,7 @@ static int imon_ir_change_protocol(struc - unsigned char ir_proto_packet[] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x86 }; - -- if (*rc_type && !(*rc_type & rc->allowed_protos)) -+ if (*rc_type && !rc_protocols_allowed(rc, *rc_type)) - dev_warn(dev, "Looks like you're trying to use an IR protocol " - "this device does not support\n"); - -@@ -1867,7 +1867,8 @@ static struct rc_dev *imon_init_rdev(str - - rdev->priv = ictx; - rdev->driver_type = RC_DRIVER_SCANCODE; -- rdev->allowed_protos = RC_BIT_OTHER | RC_BIT_RC6_MCE; /* iMON PAD or MCE */ -+ /* iMON PAD or MCE */ -+ rc_set_allowed_protocols(rdev, RC_BIT_OTHER | RC_BIT_RC6_MCE); - rdev->change_protocol = imon_ir_change_protocol; - rdev->driver_name = MOD_NAME; - -@@ -1880,7 +1881,7 @@ static struct rc_dev *imon_init_rdev(str - - if (ictx->product == 0xffdc) { - imon_get_ffdc_type(ictx); -- rdev->allowed_protos = ictx->rc_type; -+ rc_set_allowed_protocols(rdev, ictx->rc_type); - } - - imon_set_display_type(ictx); ---- a/drivers/media/rc/ir-jvc-decoder.c -+++ b/drivers/media/rc/ir-jvc-decoder.c -@@ -47,7 +47,7 @@ static int ir_jvc_decode(struct rc_dev * - { - struct jvc_dec *data = &dev->raw->jvc; - -- if (!(dev->enabled_protocols & RC_BIT_JVC)) -+ if (!rc_protocols_enabled(dev, RC_BIT_JVC)) - return 0; - - if (!is_timing_event(ev)) { ---- a/drivers/media/rc/ir-lirc-codec.c -+++ b/drivers/media/rc/ir-lirc-codec.c -@@ -35,7 +35,7 @@ static int ir_lirc_decode(struct rc_dev - struct lirc_codec *lirc = &dev->raw->lirc; - int sample; - -- if (!(dev->enabled_protocols & RC_BIT_LIRC)) -+ if (!rc_protocols_enabled(dev, RC_BIT_LIRC)) - return 0; - - if (!dev->raw->lirc.drv || !dev->raw->lirc.drv->rbuf) ---- a/drivers/media/rc/ir-mce_kbd-decoder.c -+++ b/drivers/media/rc/ir-mce_kbd-decoder.c -@@ -216,7 +216,7 @@ static int ir_mce_kbd_decode(struct rc_d - u32 scancode; - unsigned long delay; - -- if (!(dev->enabled_protocols & RC_BIT_MCE_KBD)) -+ if (!rc_protocols_enabled(dev, RC_BIT_MCE_KBD)) - return 0; - - if (!is_timing_event(ev)) { ---- a/drivers/media/rc/ir-nec-decoder.c -+++ b/drivers/media/rc/ir-nec-decoder.c -@@ -52,7 +52,7 @@ static int ir_nec_decode(struct rc_dev * - u8 address, not_address, command, not_command; - bool send_32bits = false; - -- if (!(dev->enabled_protocols & RC_BIT_NEC)) -+ if (!rc_protocols_enabled(dev, RC_BIT_NEC)) - return 0; - - if (!is_timing_event(ev)) { ---- a/drivers/media/rc/ir-raw.c -+++ b/drivers/media/rc/ir-raw.c -@@ -256,7 +256,7 @@ int ir_raw_event_register(struct rc_dev - return -ENOMEM; - - dev->raw->dev = dev; -- dev->enabled_protocols = ~0; -+ rc_set_enabled_protocols(dev, ~0); - rc = kfifo_alloc(&dev->raw->kfifo, - sizeof(struct ir_raw_event) * MAX_IR_EVENT_SIZE, - GFP_KERNEL); ---- a/drivers/media/rc/ir-rc5-decoder.c -+++ b/drivers/media/rc/ir-rc5-decoder.c -@@ -52,7 +52,7 @@ static int ir_rc5_decode(struct rc_dev * - u8 toggle; - u32 scancode; - -- if (!(dev->enabled_protocols & (RC_BIT_RC5 | RC_BIT_RC5X))) -+ if (!rc_protocols_enabled(dev, RC_BIT_RC5 | RC_BIT_RC5X)) - return 0; - - if (!is_timing_event(ev)) { -@@ -128,7 +128,7 @@ again: - if (data->wanted_bits == RC5X_NBITS) { - /* RC5X */ - u8 xdata, command, system; -- if (!(dev->enabled_protocols & RC_BIT_RC5X)) { -+ if (!rc_protocols_enabled(dev, RC_BIT_RC5X)) { - data->state = STATE_INACTIVE; - return 0; - } -@@ -145,7 +145,7 @@ again: - } else { - /* RC5 */ - u8 command, system; -- if (!(dev->enabled_protocols & RC_BIT_RC5)) { -+ if (!rc_protocols_enabled(dev, RC_BIT_RC5)) { - data->state = STATE_INACTIVE; - return 0; - } ---- a/drivers/media/rc/ir-rc5-sz-decoder.c -+++ b/drivers/media/rc/ir-rc5-sz-decoder.c -@@ -48,7 +48,7 @@ static int ir_rc5_sz_decode(struct rc_de - u8 toggle, command, system; - u32 scancode; - -- if (!(dev->enabled_protocols & RC_BIT_RC5_SZ)) -+ if (!rc_protocols_enabled(dev, RC_BIT_RC5_SZ)) - return 0; - - if (!is_timing_event(ev)) { ---- a/drivers/media/rc/ir-rc6-decoder.c -+++ b/drivers/media/rc/ir-rc6-decoder.c -@@ -89,9 +89,9 @@ static int ir_rc6_decode(struct rc_dev * - u32 scancode; - u8 toggle; - -- if (!(dev->enabled_protocols & -- (RC_BIT_RC6_0 | RC_BIT_RC6_6A_20 | RC_BIT_RC6_6A_24 | -- RC_BIT_RC6_6A_32 | RC_BIT_RC6_MCE))) -+ if (!rc_protocols_enabled(dev, RC_BIT_RC6_0 | RC_BIT_RC6_6A_20 | -+ RC_BIT_RC6_6A_24 | RC_BIT_RC6_6A_32 | -+ RC_BIT_RC6_MCE)) - return 0; - - if (!is_timing_event(ev)) { ---- a/drivers/media/rc/ir-sanyo-decoder.c -+++ b/drivers/media/rc/ir-sanyo-decoder.c -@@ -58,7 +58,7 @@ static int ir_sanyo_decode(struct rc_dev - u32 scancode; - u8 address, command, not_command; - -- if (!(dev->enabled_protocols & RC_BIT_SANYO)) -+ if (!rc_protocols_enabled(dev, RC_BIT_SANYO)) - return 0; - - if (!is_timing_event(ev)) { ---- a/drivers/media/rc/ir-sony-decoder.c -+++ b/drivers/media/rc/ir-sony-decoder.c -@@ -45,8 +45,8 @@ static int ir_sony_decode(struct rc_dev - u32 scancode; - u8 device, subdevice, function; - -- if (!(dev->enabled_protocols & -- (RC_BIT_SONY12 | RC_BIT_SONY15 | RC_BIT_SONY20))) -+ if (!rc_protocols_enabled(dev, RC_BIT_SONY12 | RC_BIT_SONY15 | -+ RC_BIT_SONY20)) - return 0; - - if (!is_timing_event(ev)) { -@@ -124,7 +124,7 @@ static int ir_sony_decode(struct rc_dev - - switch (data->count) { - case 12: -- if (!(dev->enabled_protocols & RC_BIT_SONY12)) { -+ if (!rc_protocols_enabled(dev, RC_BIT_SONY12)) { - data->state = STATE_INACTIVE; - return 0; - } -@@ -133,7 +133,7 @@ static int ir_sony_decode(struct rc_dev - function = bitrev8((data->bits >> 4) & 0xFE); - break; - case 15: -- if (!(dev->enabled_protocols & RC_BIT_SONY15)) { -+ if (!rc_protocols_enabled(dev, RC_BIT_SONY15)) { - data->state = STATE_INACTIVE; - return 0; - } -@@ -142,7 +142,7 @@ static int ir_sony_decode(struct rc_dev - function = bitrev8((data->bits >> 7) & 0xFE); - break; - case 20: -- if (!(dev->enabled_protocols & RC_BIT_SONY20)) { -+ if (!rc_protocols_enabled(dev, RC_BIT_SONY20)) { - data->state = STATE_INACTIVE; - return 0; - } ---- a/drivers/media/rc/ite-cir.c -+++ b/drivers/media/rc/ite-cir.c -@@ -1563,7 +1563,7 @@ static int ite_probe(struct pnp_dev *pde - /* set up ir-core props */ - rdev->priv = itdev; - rdev->driver_type = RC_DRIVER_IR_RAW; -- rdev->allowed_protos = RC_BIT_ALL; -+ rc_set_allowed_protocols(rdev, RC_BIT_ALL); - rdev->open = ite_open; - rdev->close = ite_close; - rdev->s_idle = ite_s_idle; ---- a/drivers/media/rc/mceusb.c -+++ b/drivers/media/rc/mceusb.c -@@ -1217,7 +1217,7 @@ static struct rc_dev *mceusb_init_rc_dev - rc->dev.parent = dev; - rc->priv = ir; - rc->driver_type = RC_DRIVER_IR_RAW; -- rc->allowed_protos = RC_BIT_ALL; -+ rc_set_allowed_protocols(rc, RC_BIT_ALL); - rc->timeout = MS_TO_NS(100); - if (!ir->flags.no_tx) { - rc->s_tx_mask = mceusb_set_tx_mask; ---- a/drivers/media/rc/nuvoton-cir.c -+++ b/drivers/media/rc/nuvoton-cir.c -@@ -1042,7 +1042,7 @@ static int nvt_probe(struct pnp_dev *pde - /* Set up the rc device */ - rdev->priv = nvt; - rdev->driver_type = RC_DRIVER_IR_RAW; -- rdev->allowed_protos = RC_BIT_ALL; -+ rc_set_allowed_protocols(rdev, RC_BIT_ALL); - rdev->open = nvt_open; - rdev->close = nvt_close; - rdev->tx_ir = nvt_tx_ir; ---- a/drivers/media/rc/rc-loopback.c -+++ b/drivers/media/rc/rc-loopback.c -@@ -195,7 +195,7 @@ static int __init loop_init(void) - rc->map_name = RC_MAP_EMPTY; - rc->priv = &loopdev; - rc->driver_type = RC_DRIVER_IR_RAW; -- rc->allowed_protos = RC_BIT_ALL; -+ rc_set_allowed_protocols(rc, RC_BIT_ALL); - rc->timeout = 100 * 1000 * 1000; /* 100 ms */ - rc->min_timeout = 1; - rc->max_timeout = UINT_MAX; ---- a/drivers/media/rc/rc-main.c -+++ b/drivers/media/rc/rc-main.c -@@ -633,6 +633,7 @@ EXPORT_SYMBOL_GPL(rc_repeat); - static void ir_do_keydown(struct rc_dev *dev, int scancode, - u32 keycode, u8 toggle) - { -+ struct rc_scancode_filter *filter; - bool new_event = !dev->keypressed || - dev->last_scancode != scancode || - dev->last_toggle != toggle; -@@ -640,6 +641,11 @@ static void ir_do_keydown(struct rc_dev - if (new_event && dev->keypressed) - ir_do_keyup(dev, false); - -+ /* Generic scancode filtering */ -+ filter = &dev->scancode_filters[RC_FILTER_NORMAL]; -+ if (filter->mask && ((scancode ^ filter->data) & filter->mask)) -+ return; -+ - input_event(dev->input_dev, EV_MSC, MSC_SCAN, scancode); - - if (new_event && keycode != KEY_RESERVED) { -@@ -795,13 +801,38 @@ static struct { - }; - - /** -- * show_protocols() - shows the current IR protocol(s) -+ * struct rc_filter_attribute - Device attribute relating to a filter type. -+ * @attr: Device attribute. -+ * @type: Filter type. -+ * @mask: false for filter value, true for filter mask. -+ */ -+struct rc_filter_attribute { -+ struct device_attribute attr; -+ enum rc_filter_type type; -+ bool mask; -+}; -+#define to_rc_filter_attr(a) container_of(a, struct rc_filter_attribute, attr) -+ -+#define RC_PROTO_ATTR(_name, _mode, _show, _store, _type) \ -+ struct rc_filter_attribute dev_attr_##_name = { \ -+ .attr = __ATTR(_name, _mode, _show, _store), \ -+ .type = (_type), \ -+ } -+#define RC_FILTER_ATTR(_name, _mode, _show, _store, _type, _mask) \ -+ struct rc_filter_attribute dev_attr_##_name = { \ -+ .attr = __ATTR(_name, _mode, _show, _store), \ -+ .type = (_type), \ -+ .mask = (_mask), \ -+ } -+ -+/** -+ * show_protocols() - shows the current/wakeup IR protocol(s) - * @device: the device descriptor - * @mattr: the device attribute struct (unused) - * @buf: a pointer to the output buffer - * - * This routine is a callback routine for input read the IR protocol type(s). -- * it is trigged by reading /sys/class/rc/rc?/protocols. -+ * it is trigged by reading /sys/class/rc/rc?/[wakeup_]protocols. - * It returns the protocol names of supported protocols. - * Enabled protocols are printed in brackets. - * -@@ -812,6 +843,7 @@ static ssize_t show_protocols(struct dev - struct device_attribute *mattr, char *buf) - { - struct rc_dev *dev = to_rc_dev(device); -+ struct rc_filter_attribute *fattr = to_rc_filter_attr(mattr); - u64 allowed, enabled; - char *tmp = buf; - int i; -@@ -822,9 +854,10 @@ static ssize_t show_protocols(struct dev - - mutex_lock(&dev->lock); - -- enabled = dev->enabled_protocols; -- if (dev->driver_type == RC_DRIVER_SCANCODE) -- allowed = dev->allowed_protos; -+ enabled = dev->enabled_protocols[fattr->type]; -+ if (dev->driver_type == RC_DRIVER_SCANCODE || -+ fattr->type == RC_FILTER_WAKEUP) -+ allowed = dev->allowed_protocols[fattr->type]; - else if (dev->raw) - allowed = ir_raw_get_allowed_protocols(); - else { -@@ -856,14 +889,14 @@ static ssize_t show_protocols(struct dev - } - - /** -- * store_protocols() - changes the current IR protocol(s) -+ * store_protocols() - changes the current/wakeup IR protocol(s) - * @device: the device descriptor - * @mattr: the device attribute struct (unused) - * @buf: a pointer to the input buffer - * @len: length of the input buffer - * - * This routine is for changing the IR protocol type. -- * It is trigged by writing to /sys/class/rc/rc?/protocols. -+ * It is trigged by writing to /sys/class/rc/rc?/[wakeup_]protocols. - * Writing "+proto" will add a protocol to the list of enabled protocols. - * Writing "-proto" will remove a protocol from the list of enabled protocols. - * Writing "proto" will enable only "proto". -@@ -880,12 +913,15 @@ static ssize_t store_protocols(struct de - size_t len) - { - struct rc_dev *dev = to_rc_dev(device); -+ struct rc_filter_attribute *fattr = to_rc_filter_attr(mattr); - bool enable, disable; - const char *tmp; -- u64 type; -+ u64 old_type, type; - u64 mask; - int rc, i, count = 0; - ssize_t ret; -+ int (*change_protocol)(struct rc_dev *dev, u64 *rc_type); -+ struct rc_scancode_filter local_filter, *filter; - - /* Device is being removed */ - if (!dev) -@@ -898,7 +934,8 @@ static ssize_t store_protocols(struct de - ret = -EINVAL; - goto out; - } -- type = dev->enabled_protocols; -+ old_type = dev->enabled_protocols[fattr->type]; -+ type = old_type; - - while ((tmp = strsep((char **) &data, " \n")) != NULL) { - if (!*tmp) -@@ -946,8 +983,10 @@ static ssize_t store_protocols(struct de - goto out; - } - -- if (dev->change_protocol) { -- rc = dev->change_protocol(dev, &type); -+ change_protocol = (fattr->type == RC_FILTER_NORMAL) -+ ? dev->change_protocol : dev->change_wakeup_protocol; -+ if (change_protocol) { -+ rc = change_protocol(dev, &type); - if (rc < 0) { - IR_dprintk(1, "Error setting protocols to 0x%llx\n", - (long long)type); -@@ -956,10 +995,40 @@ static ssize_t store_protocols(struct de - } - } - -- dev->enabled_protocols = type; -+ dev->enabled_protocols[fattr->type] = type; - IR_dprintk(1, "Current protocol(s): 0x%llx\n", - (long long)type); - -+ /* -+ * If the protocol is changed the filter needs updating. -+ * Try setting the same filter with the new protocol (if any). -+ * Fall back to clearing the filter. -+ */ -+ filter = &dev->scancode_filters[fattr->type]; -+ if (old_type != type && filter->mask) { -+ local_filter = *filter; -+ if (!type) { -+ /* no protocol => clear filter */ -+ ret = -1; -+ } else if (!dev->s_filter) { -+ /* generic filtering => accept any filter */ -+ ret = 0; -+ } else { -+ /* hardware filtering => try setting, otherwise clear */ -+ ret = dev->s_filter(dev, fattr->type, &local_filter); -+ } -+ if (ret < 0) { -+ /* clear the filter */ -+ local_filter.data = 0; -+ local_filter.mask = 0; -+ if (dev->s_filter) -+ dev->s_filter(dev, fattr->type, &local_filter); -+ } -+ -+ /* commit the new filter */ -+ *filter = local_filter; -+ } -+ - ret = len; - - out: -@@ -967,6 +1036,115 @@ out: - return ret; - } - -+/** -+ * show_filter() - shows the current scancode filter value or mask -+ * @device: the device descriptor -+ * @attr: the device attribute struct -+ * @buf: a pointer to the output buffer -+ * -+ * This routine is a callback routine to read a scancode filter value or mask. -+ * It is trigged by reading /sys/class/rc/rc?/[wakeup_]filter[_mask]. -+ * It prints the current scancode filter value or mask of the appropriate filter -+ * type in hexadecimal into @buf and returns the size of the buffer. -+ * -+ * Bits of the filter value corresponding to set bits in the filter mask are -+ * compared against input scancodes and non-matching scancodes are discarded. -+ * -+ * dev->lock is taken to guard against races between device registration, -+ * store_filter and show_filter. -+ */ -+static ssize_t show_filter(struct device *device, -+ struct device_attribute *attr, -+ char *buf) -+{ -+ struct rc_dev *dev = to_rc_dev(device); -+ struct rc_filter_attribute *fattr = to_rc_filter_attr(attr); -+ u32 val; -+ -+ /* Device is being removed */ -+ if (!dev) -+ return -EINVAL; -+ -+ mutex_lock(&dev->lock); -+ if (fattr->mask) -+ val = dev->scancode_filters[fattr->type].mask; -+ else -+ val = dev->scancode_filters[fattr->type].data; -+ mutex_unlock(&dev->lock); -+ -+ return sprintf(buf, "%#x\n", val); -+} -+ -+/** -+ * store_filter() - changes the scancode filter value -+ * @device: the device descriptor -+ * @attr: the device attribute struct -+ * @buf: a pointer to the input buffer -+ * @len: length of the input buffer -+ * -+ * This routine is for changing a scancode filter value or mask. -+ * It is trigged by writing to /sys/class/rc/rc?/[wakeup_]filter[_mask]. -+ * Returns -EINVAL if an invalid filter value for the current protocol was -+ * specified or if scancode filtering is not supported by the driver, otherwise -+ * returns @len. -+ * -+ * Bits of the filter value corresponding to set bits in the filter mask are -+ * compared against input scancodes and non-matching scancodes are discarded. -+ * -+ * dev->lock is taken to guard against races between device registration, -+ * store_filter and show_filter. -+ */ -+static ssize_t store_filter(struct device *device, -+ struct device_attribute *attr, -+ const char *buf, -+ size_t count) -+{ -+ struct rc_dev *dev = to_rc_dev(device); -+ struct rc_filter_attribute *fattr = to_rc_filter_attr(attr); -+ struct rc_scancode_filter local_filter, *filter; -+ int ret; -+ unsigned long val; -+ -+ /* Device is being removed */ -+ if (!dev) -+ return -EINVAL; -+ -+ ret = kstrtoul(buf, 0, &val); -+ if (ret < 0) -+ return ret; -+ -+ /* Scancode filter not supported (but still accept 0) */ -+ if (!dev->s_filter && fattr->type != RC_FILTER_NORMAL) -+ return val ? -EINVAL : count; -+ -+ mutex_lock(&dev->lock); -+ -+ /* Tell the driver about the new filter */ -+ filter = &dev->scancode_filters[fattr->type]; -+ local_filter = *filter; -+ if (fattr->mask) -+ local_filter.mask = val; -+ else -+ local_filter.data = val; -+ if (!dev->enabled_protocols[fattr->type] && local_filter.mask) { -+ /* refuse to set a filter unless a protocol is enabled */ -+ ret = -EINVAL; -+ goto unlock; -+ } -+ if (dev->s_filter) { -+ ret = dev->s_filter(dev, fattr->type, &local_filter); -+ if (ret < 0) -+ goto unlock; -+ } -+ -+ /* Success, commit the new filter */ -+ *filter = local_filter; -+ -+unlock: -+ mutex_unlock(&dev->lock); -+ return (ret < 0) ? ret : count; -+} -+ - static void rc_dev_release(struct device *device) - { - } -@@ -996,11 +1174,26 @@ static int rc_dev_uevent(struct device * - /* - * Static device attribute struct with the sysfs attributes for IR's - */ --static DEVICE_ATTR(protocols, S_IRUGO | S_IWUSR, -- show_protocols, store_protocols); -+static RC_PROTO_ATTR(protocols, S_IRUGO | S_IWUSR, -+ show_protocols, store_protocols, RC_FILTER_NORMAL); -+static RC_PROTO_ATTR(wakeup_protocols, S_IRUGO | S_IWUSR, -+ show_protocols, store_protocols, RC_FILTER_WAKEUP); -+static RC_FILTER_ATTR(filter, S_IRUGO|S_IWUSR, -+ show_filter, store_filter, RC_FILTER_NORMAL, false); -+static RC_FILTER_ATTR(filter_mask, S_IRUGO|S_IWUSR, -+ show_filter, store_filter, RC_FILTER_NORMAL, true); -+static RC_FILTER_ATTR(wakeup_filter, S_IRUGO|S_IWUSR, -+ show_filter, store_filter, RC_FILTER_WAKEUP, false); -+static RC_FILTER_ATTR(wakeup_filter_mask, S_IRUGO|S_IWUSR, -+ show_filter, store_filter, RC_FILTER_WAKEUP, true); - - static struct attribute *rc_dev_attrs[] = { -- &dev_attr_protocols.attr, -+ &dev_attr_protocols.attr.attr, -+ &dev_attr_wakeup_protocols.attr.attr, -+ &dev_attr_filter.attr.attr, -+ &dev_attr_filter_mask.attr.attr, -+ &dev_attr_wakeup_filter.attr.attr, -+ &dev_attr_wakeup_filter_mask.attr.attr, - NULL, - }; - -@@ -1091,14 +1284,6 @@ int rc_register_device(struct rc_dev *de - if (dev->close) - dev->input_dev->close = ir_close; - -- /* -- * Take the lock here, as the device sysfs node will appear -- * when device_add() is called, which may trigger an ir-keytable udev -- * rule, which will in turn call show_protocols and access -- * dev->enabled_protocols before it has been initialized. -- */ -- mutex_lock(&dev->lock); -- - do { - devno = find_first_zero_bit(ir_core_dev_number, - IRRCV_NUM_DEVICES); -@@ -1107,6 +1292,14 @@ int rc_register_device(struct rc_dev *de - return -ENOMEM; - } while (test_and_set_bit(devno, ir_core_dev_number)); - -+ /* -+ * Take the lock here, as the device sysfs node will appear -+ * when device_add() is called, which may trigger an ir-keytable udev -+ * rule, which will in turn call show_protocols and access -+ * dev->enabled_protocols before it has been initialized. -+ */ -+ mutex_lock(&dev->lock); -+ - dev->devno = devno; - dev_set_name(&dev->dev, "rc%ld", dev->devno); - dev_set_drvdata(&dev->dev, dev); -@@ -1172,7 +1365,7 @@ int rc_register_device(struct rc_dev *de - rc = dev->change_protocol(dev, &rc_type); - if (rc < 0) - goto out_raw; -- dev->enabled_protocols = rc_type; -+ dev->enabled_protocols[RC_FILTER_NORMAL] = rc_type; - } - - mutex_unlock(&dev->lock); ---- a/drivers/media/rc/redrat3.c -+++ b/drivers/media/rc/redrat3.c -@@ -922,7 +922,7 @@ static struct rc_dev *redrat3_init_rc_de - rc->dev.parent = dev; - rc->priv = rr3; - rc->driver_type = RC_DRIVER_IR_RAW; -- rc->allowed_protos = RC_BIT_ALL; -+ rc_set_allowed_protocols(rc, RC_BIT_ALL); - rc->timeout = US_TO_NS(2750); - rc->tx_ir = redrat3_transmit_ir; - rc->s_tx_carrier = redrat3_set_tx_carrier; ---- a/drivers/media/rc/st_rc.c -+++ b/drivers/media/rc/st_rc.c -@@ -287,7 +287,7 @@ static int st_rc_probe(struct platform_d - st_rc_hardware_init(rc_dev); - - rdev->driver_type = RC_DRIVER_IR_RAW; -- rdev->allowed_protos = RC_BIT_ALL; -+ rc_set_allowed_protocols(rdev, RC_BIT_ALL); - /* rx sampling rate is 10Mhz */ - rdev->rx_resolution = 100; - rdev->timeout = US_TO_NS(MAX_SYMB_TIME); ---- a/drivers/media/rc/streamzap.c -+++ b/drivers/media/rc/streamzap.c -@@ -322,7 +322,7 @@ static struct rc_dev *streamzap_init_rc_ - rdev->dev.parent = dev; - rdev->priv = sz; - rdev->driver_type = RC_DRIVER_IR_RAW; -- rdev->allowed_protos = RC_BIT_ALL; -+ rc_set_allowed_protocols(rdev, RC_BIT_ALL); - rdev->driver_name = DRIVER_NAME; - rdev->map_name = RC_MAP_STREAMZAP; - ---- a/drivers/media/rc/ttusbir.c -+++ b/drivers/media/rc/ttusbir.c -@@ -318,7 +318,7 @@ static int ttusbir_probe(struct usb_inte - usb_to_input_id(tt->udev, &rc->input_id); - rc->dev.parent = &intf->dev; - rc->driver_type = RC_DRIVER_IR_RAW; -- rc->allowed_protos = RC_BIT_ALL; -+ rc_set_allowed_protocols(rc, RC_BIT_ALL); - rc->priv = tt; - rc->driver_name = DRIVER_NAME; - rc->map_name = RC_MAP_TT_1500; ---- a/drivers/media/rc/winbond-cir.c -+++ b/drivers/media/rc/winbond-cir.c -@@ -1082,7 +1082,7 @@ wbcir_probe(struct pnp_dev *device, cons - data->dev->dev.parent = &device->dev; - data->dev->timeout = MS_TO_NS(100); - data->dev->rx_resolution = US_TO_NS(2); -- data->dev->allowed_protos = RC_BIT_ALL; -+ rc_set_allowed_protocols(data->dev, RC_BIT_ALL); - - err = rc_register_device(data->dev); - if (err) ---- a/drivers/media/usb/dvb-usb/dvb-usb-remote.c -+++ b/drivers/media/usb/dvb-usb/dvb-usb-remote.c -@@ -272,7 +272,7 @@ static int rc_core_dvb_usb_remote_init(s - dev->driver_name = d->props.rc.core.module_name; - dev->map_name = d->props.rc.core.rc_codes; - dev->change_protocol = d->props.rc.core.change_protocol; -- dev->allowed_protos = d->props.rc.core.allowed_protos; -+ rc_set_allowed_protocols(dev, d->props.rc.core.allowed_protos); - dev->driver_type = d->props.rc.core.driver_type; - usb_to_input_id(d->udev, &dev->input_id); - dev->input_name = "IR-receiver inside an USB DVB receiver"; ---- a/drivers/media/usb/dvb-usb-v2/dvb_usb_core.c -+++ b/drivers/media/usb/dvb-usb-v2/dvb_usb_core.c -@@ -164,7 +164,7 @@ static int dvb_usbv2_remote_init(struct - dev->driver_name = (char *) d->props->driver_name; - dev->map_name = d->rc.map_name; - dev->driver_type = d->rc.driver_type; -- dev->allowed_protos = d->rc.allowed_protos; -+ rc_set_allowed_protocols(dev, d->rc.allowed_protos); - dev->change_protocol = d->rc.change_protocol; - dev->priv = d; - ---- a/drivers/media/usb/em28xx/em28xx-input.c -+++ b/drivers/media/usb/em28xx/em28xx-input.c -@@ -725,7 +725,7 @@ static int em28xx_ir_init(struct em28xx - case EM2820_BOARD_HAUPPAUGE_WINTV_USB_2: - rc->map_name = RC_MAP_HAUPPAUGE; - ir->get_key_i2c = em28xx_get_key_em_haup; -- rc->allowed_protos = RC_BIT_RC5; -+ rc_set_allowed_protocols(rc, RC_BIT_RC5); - break; - case EM2820_BOARD_LEADTEK_WINFAST_USBII_DELUXE: - rc->map_name = RC_MAP_WINFAST_USBII_DELUXE; -@@ -741,7 +741,7 @@ static int em28xx_ir_init(struct em28xx - switch (dev->chip_id) { - case CHIP_ID_EM2860: - case CHIP_ID_EM2883: -- rc->allowed_protos = RC_BIT_RC5 | RC_BIT_NEC; -+ rc_set_allowed_protocols(rc, RC_BIT_RC5 | RC_BIT_NEC); - ir->get_key = default_polling_getkey; - break; - case CHIP_ID_EM2884: -@@ -749,8 +749,8 @@ static int em28xx_ir_init(struct em28xx - case CHIP_ID_EM28174: - case CHIP_ID_EM28178: - ir->get_key = em2874_polling_getkey; -- rc->allowed_protos = RC_BIT_RC5 | RC_BIT_NEC | -- RC_BIT_RC6_0; -+ rc_set_allowed_protocols(rc, RC_BIT_RC5 | RC_BIT_NEC | -+ RC_BIT_RC6_0); - break; - default: - err = -ENODEV; ---- a/drivers/media/usb/tm6000/tm6000-input.c -+++ b/drivers/media/usb/tm6000/tm6000-input.c -@@ -422,7 +422,7 @@ int tm6000_ir_init(struct tm6000_core *d - ir->rc = rc; - - /* input setup */ -- rc->allowed_protos = RC_BIT_RC5 | RC_BIT_NEC; -+ rc_set_allowed_protocols(rc, RC_BIT_RC5 | RC_BIT_NEC); - /* Neded, in order to support NEC remotes with 24 or 32 bits */ - rc->scanmask = 0xffff; - rc->priv = ir; ---- a/include/media/rc-core.h -+++ b/include/media/rc-core.h -@@ -35,6 +35,29 @@ enum rc_driver_type { - }; - - /** -+ * struct rc_scancode_filter - Filter scan codes. -+ * @data: Scancode data to match. -+ * @mask: Mask of bits of scancode to compare. -+ */ -+struct rc_scancode_filter { -+ u32 data; -+ u32 mask; -+}; -+ -+/** -+ * enum rc_filter_type - Filter type constants. -+ * @RC_FILTER_NORMAL: Filter for normal operation. -+ * @RC_FILTER_WAKEUP: Filter for waking from suspend. -+ * @RC_FILTER_MAX: Number of filter types. -+ */ -+enum rc_filter_type { -+ RC_FILTER_NORMAL = 0, -+ RC_FILTER_WAKEUP, -+ -+ RC_FILTER_MAX -+}; -+ -+/** - * struct rc_dev - represents a remote control device - * @dev: driver model's view of this device - * @input_name: name of the input child device -@@ -50,8 +73,10 @@ enum rc_driver_type { - * @input_dev: the input child device used to communicate events to userspace - * @driver_type: specifies if protocol decoding is done in hardware or software - * @idle: used to keep track of RX state -- * @allowed_protos: bitmask with the supported RC_BIT_* protocols -- * @enabled_protocols: bitmask with the enabled RC_BIT_* protocols -+ * @allowed_protocols: bitmask with the supported RC_BIT_* protocols for each -+ * filter type -+ * @enabled_protocols: bitmask with the enabled RC_BIT_* protocols for each -+ * filter type - * @scanmask: some hardware decoders are not capable of providing the full - * scancode to the application. As this is a hardware limit, we can't do - * anything with it. Yet, as the same keycode table can be used with other -@@ -70,7 +95,10 @@ enum rc_driver_type { - * @max_timeout: maximum timeout supported by device - * @rx_resolution : resolution (in ns) of input sampler - * @tx_resolution: resolution (in ns) of output sampler -+ * @scancode_filters: scancode filters (indexed by enum rc_filter_type) - * @change_protocol: allow changing the protocol used on hardware decoders -+ * @change_wakeup_protocol: allow changing the protocol used for wakeup -+ * filtering - * @open: callback to allow drivers to enable polling/irq when IR input device - * is opened. - * @close: callback to allow drivers to disable polling/irq when IR input device -@@ -84,6 +112,7 @@ enum rc_driver_type { - * device doesn't interrupt host until it sees IR pulses - * @s_learning_mode: enable wide band receiver used for learning - * @s_carrier_report: enable carrier reports -+ * @s_filter: set the scancode filter of a given type - */ - struct rc_dev { - struct device dev; -@@ -99,8 +128,8 @@ struct rc_dev { - struct input_dev *input_dev; - enum rc_driver_type driver_type; - bool idle; -- u64 allowed_protos; -- u64 enabled_protocols; -+ u64 allowed_protocols[RC_FILTER_MAX]; -+ u64 enabled_protocols[RC_FILTER_MAX]; - u32 users; - u32 scanmask; - void *priv; -@@ -116,7 +145,9 @@ struct rc_dev { - u32 max_timeout; - u32 rx_resolution; - u32 tx_resolution; -+ struct rc_scancode_filter scancode_filters[RC_FILTER_MAX]; - int (*change_protocol)(struct rc_dev *dev, u64 *rc_type); -+ int (*change_wakeup_protocol)(struct rc_dev *dev, u64 *rc_type); - int (*open)(struct rc_dev *dev); - void (*close)(struct rc_dev *dev); - int (*s_tx_mask)(struct rc_dev *dev, u32 mask); -@@ -127,10 +158,49 @@ struct rc_dev { - void (*s_idle)(struct rc_dev *dev, bool enable); - int (*s_learning_mode)(struct rc_dev *dev, int enable); - int (*s_carrier_report) (struct rc_dev *dev, int enable); -+ int (*s_filter)(struct rc_dev *dev, -+ enum rc_filter_type type, -+ struct rc_scancode_filter *filter); - }; - - #define to_rc_dev(d) container_of(d, struct rc_dev, dev) - -+static inline bool rc_protocols_allowed(struct rc_dev *rdev, u64 protos) -+{ -+ return rdev->allowed_protocols[RC_FILTER_NORMAL] & protos; -+} -+ -+/* should be called prior to registration or with mutex held */ -+static inline void rc_set_allowed_protocols(struct rc_dev *rdev, u64 protos) -+{ -+ rdev->allowed_protocols[RC_FILTER_NORMAL] = protos; -+} -+ -+static inline bool rc_protocols_enabled(struct rc_dev *rdev, u64 protos) -+{ -+ return rdev->enabled_protocols[RC_FILTER_NORMAL] & protos; -+} -+ -+/* should be called prior to registration or with mutex held */ -+static inline void rc_set_enabled_protocols(struct rc_dev *rdev, u64 protos) -+{ -+ rdev->enabled_protocols[RC_FILTER_NORMAL] = protos; -+} -+ -+/* should be called prior to registration or with mutex held */ -+static inline void rc_set_allowed_wakeup_protocols(struct rc_dev *rdev, -+ u64 protos) -+{ -+ rdev->allowed_protocols[RC_FILTER_WAKEUP] = protos; -+} -+ -+/* should be called prior to registration or with mutex held */ -+static inline void rc_set_enabled_wakeup_protocols(struct rc_dev *rdev, -+ u64 protos) -+{ -+ rdev->enabled_protocols[RC_FILTER_WAKEUP] = protos; -+} -+ - /* - * From rc-main.c - * Those functions can be used on any type of Remote Controller. They |