summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drm-intel-edp-fixes.patch44
-rw-r--r--kernel.spec28
-rw-r--r--linux-2.6-selinux-mprotect-checks.patch124
-rw-r--r--linux-2.6-sparc-selinux-mprotect-checks.patch35
-rw-r--r--linux-2.6-v4l-dvb-ir-core-update.patch6741
-rw-r--r--mm-slub-do-not-take-expensive-steps-for-slubs-speculative-high-order-allocations.patch78
-rw-r--r--mm-slub-do-not-wake-kswapd-for-slubs-speculative-high-order-allocations.patch52
-rw-r--r--mm-vmscan-if-kswapd-has-been-running-too-long-allow-it-to-sleep.patch47
8 files changed, 2 insertions, 7147 deletions
diff --git a/drm-intel-edp-fixes.patch b/drm-intel-edp-fixes.patch
deleted file mode 100644
index c77ef116c..000000000
--- a/drm-intel-edp-fixes.patch
+++ /dev/null
@@ -1,44 +0,0 @@
-diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
-index f737960..b1f8164 100644
---- a/drivers/gpu/drm/i915/i915_drv.c
-+++ b/drivers/gpu/drm/i915/i915_drv.c
-@@ -509,6 +509,8 @@ i915_pci_remove(struct pci_dev *pdev)
- {
- struct drm_device *dev = pci_get_drvdata(pdev);
-
-+ pci_disable_device(pdev); /* core did previous enable */
-+
- drm_put_dev(dev);
- }
-
-diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
-index 300f64b..2e3db37 100644
---- a/drivers/gpu/drm/i915/intel_dp.c
-+++ b/drivers/gpu/drm/i915/intel_dp.c
-@@ -795,7 +795,8 @@ static bool ironlake_edp_panel_on (struct intel_dp *intel_dp)
- {
- struct drm_device *dev = intel_dp->base.base.dev;
- struct drm_i915_private *dev_priv = dev->dev_private;
-- u32 pp, idle_on_mask = PP_ON | PP_SEQUENCE_STATE_ON_IDLE;
-+ u32 pp, idle_on = PP_ON | PP_SEQUENCE_STATE_ON_IDLE;
-+ u32 idle_on_mask = PP_ON | PP_SEQUENCE_STATE_MASK;
-
- if (I915_READ(PCH_PP_STATUS) & PP_ON)
- return true;
-@@ -816,7 +817,7 @@ static bool ironlake_edp_panel_on (struct intel_dp *intel_dp)
- */
- msleep(300);
-
-- if (wait_for((I915_READ(PCH_PP_STATUS) & idle_on_mask) == idle_on_mask,
-+ if (wait_for((I915_READ(PCH_PP_STATUS) & idle_on_mask) == idle_on,
- 5000))
- DRM_ERROR("panel on wait timed out: 0x%08x\n",
- I915_READ(PCH_PP_STATUS));
-@@ -922,6 +923,7 @@ static void intel_dp_prepare(struct drm_encoder *encoder)
-
- if (is_edp(intel_dp)) {
- ironlake_edp_backlight_off(dev);
-+ ironlake_edp_panel_off(dev);
- ironlake_edp_panel_on(intel_dp);
- if (!is_pch_edp(intel_dp))
- ironlake_edp_pll_on(encoder);
diff --git a/kernel.spec b/kernel.spec
index 0859cc2fe..e8310b0bd 100644
--- a/kernel.spec
+++ b/kernel.spec
@@ -646,8 +646,6 @@ Patch470: die-floppy-die.patch
Patch510: linux-2.6-silence-noise.patch
Patch530: linux-2.6-silence-fbcon-logo.patch
-Patch570: linux-2.6-selinux-mprotect-checks.patch
-Patch580: linux-2.6-sparc-selinux-mprotect-checks.patch
Patch610: hda_intel-prealloc-4mb-dmabuffer.patch
@@ -668,7 +666,6 @@ Patch1810: drm-nouveau-updates.patch
Patch1824: drm-intel-next.patch
# make sure the lvds comes back on lid open
Patch1825: drm-intel-make-lvds-work.patch
-Patch1826: drm-intel-edp-fixes.patch
Patch1827: drm-i915-gen4-has-non-power-of-two-strides.patch
Patch1900: linux-2.6-intel-iommu-igfx.patch
@@ -688,9 +685,6 @@ Patch2901: linux-2.6-v4l-dvb-experimental.patch
Patch2902: linux-2.6-v4l-dvb-uvcvideo-update.patch
Patch2910: linux-2.6-v4l-dvb-add-lgdt3304-support.patch
-Patch2912: linux-2.6-v4l-dvb-ir-core-update.patch
-
-#Patch2916: lirc-staging-2.6.36-fixes.patch
# fs fixes
@@ -710,10 +704,6 @@ Patch12205: runtime_pm_fixups.patch
Patch12303: dmar-disable-when-ricoh-multifunction.patch
-Patch12401: mm-slub-do-not-wake-kswapd-for-slubs-speculative-high-order-allocations.patch
-Patch12402: mm-slub-do-not-take-expensive-steps-for-slubs-speculative-high-order-allocations.patch
-Patch12403: mm-vmscan-if-kswapd-has-been-running-too-long-allow-it-to-sleep.patch
-
%endif
BuildRoot: %{_tmppath}/kernel-%{KVERREL}-root
@@ -1242,12 +1232,6 @@ ApplyPatch linux-2.6-silence-noise.patch
# Make fbcon not show the penguins with 'quiet'
ApplyPatch linux-2.6-silence-fbcon-logo.patch
-# Fix the SELinux mprotect checks on executable mappings
-#ApplyPatch linux-2.6-selinux-mprotect-checks.patch
-# Fix SELinux for sparc
-# FIXME: Can we drop this now? See updated linux-2.6-selinux-mprotect-checks.patch
-#ApplyPatch linux-2.6-sparc-selinux-mprotect-checks.patch
-
# Changes to upstream defaults.
@@ -1271,7 +1255,6 @@ ApplyOptionalPatch drm-nouveau-updates.patch
ApplyOptionalPatch drm-intel-next.patch
ApplyPatch drm-intel-make-lvds-work.patch
ApplyPatch linux-2.6-intel-iommu-igfx.patch
-#ApplyPatch drm-intel-edp-fixes.patch
# rhbz#681285 (i965: crash in brw_wm_surface_state.c::prepare_wm_surfaces()
# where intelObj->mt == NULL)
#ApplyPatch drm-i915-gen4-has-non-power-of-two-strides.patch
@@ -1289,13 +1272,9 @@ ApplyOptionalPatch linux-2.6-v4l-dvb-fixes.patch
ApplyOptionalPatch linux-2.6-v4l-dvb-update.patch
ApplyOptionalPatch linux-2.6-v4l-dvb-experimental.patch
#ApplyPatch linux-2.6-v4l-dvb-uvcvideo-update.patch
-#ApplyPatch linux-2.6-v4l-dvb-ir-core-update.patch
###FIX###ApplyPatch linux-2.6-v4l-dvb-add-lgdt3304-support.patch
-# http://www.lirc.org/
-#ApplyOptionalPatch lirc-staging-2.6.36-fixes.patch
-
# Patches headed upstream
ApplyPatch disable-i8042-check-on-apple-mac.patch
@@ -1312,11 +1291,6 @@ ApplyPatch neuter_intel_microcode_load.patch
# rhbz#605888
ApplyPatch dmar-disable-when-ricoh-multifunction.patch
-### disable, riel reports they aggravate a VM_BUG_ON
-#ApplyPatch mm-slub-do-not-wake-kswapd-for-slubs-speculative-high-order-allocations.patch
-#ApplyPatch mm-slub-do-not-take-expensive-steps-for-slubs-speculative-high-order-allocations.patch
-#ApplyPatch mm-vmscan-if-kswapd-has-been-running-too-long-allow-it-to-sleep.patch
-
# END OF PATCH APPLICATIONS
%endif
@@ -1929,6 +1903,8 @@ fi
- linux-2.6-defaults-pci_no_msi.patch: drop, haven't toggled the default
in many moons.
- linux-2.6-defaults-pci_use_crs.patch: ditto.
+- linux-2.6-selinux-mprotect-checks.patch: upstream a while ago.
+- drop some more unapplied crud.
* Fri Jun 17 2011 Kyle McMartin <kmcmartin@redhat.com> 3.0-0.rc3.git5.1
- Try updating to a git snapshot for the first time in 3.0-rc,
diff --git a/linux-2.6-selinux-mprotect-checks.patch b/linux-2.6-selinux-mprotect-checks.patch
deleted file mode 100644
index 010a63c43..000000000
--- a/linux-2.6-selinux-mprotect-checks.patch
+++ /dev/null
@@ -1,124 +0,0 @@
-This needs a fixed toolchain, and a userspace rebuild to work.
-For these reasons, it's had difficulty getting upstream.
-
-ie, Fedora has a new enough toolchain, and has been rebuilt, so we don't need
-the ifdefs. Other distros don't/haven't, and this patch would break them
-if pushed upstream.
-
-
-Subject: [Fwd: Re: [PATCH] Disable execmem for sparc]
-From: Stephen Smalley <sds@tycho.nsa.gov>
-To: Dave Jones <davej@redhat.com>
-Date: Wed, 28 Apr 2010 16:04:56 -0400
-Message-Id: <1272485096.6013.326.camel@moss-pluto.epoch.ncsc.mil>
-
--------- Forwarded Message --------
-From: Stephen Smalley <sds@tycho.nsa.gov>
-To: David Miller <davem@davemloft.net>
-Cc: tcallawa@redhat.com, dennis@ausil.us, sparclinux@vger.kernel.org, dgilmore@redhat.com, jmorris@namei.org, eparis@parisplace.org
-Subject: Re: [PATCH] Disable execmem for sparc
-Date: Wed, 28 Apr 2010 15:57:57 -0400
-
-On Tue, 2010-04-27 at 11:47 -0700, David Miller wrote:
-> From: "Tom \"spot\" Callaway" <tcallawa@redhat.com>
-> Date: Tue, 27 Apr 2010 14:20:21 -0400
->
-> > [root@apollo ~]$ cat /proc/2174/maps
-> > 00010000-00014000 r-xp 00000000 fd:00 15466577
-> > /sbin/mingetty
-> > 00022000-00024000 rwxp 00002000 fd:00 15466577
-> > /sbin/mingetty
-> > 00024000-00046000 rwxp 00000000 00:00 0
-> > [heap]
->
-> SELINUX probably barfs on the executable heap, the PLT is in the HEAP
-> just like powerpc32 and that's why VM_DATA_DEFAULT_FLAGS has to set
-> both executable and writable.
->
-> You also can't remove the CONFIG_PPC32 ifdefs in selinux, since
-> because of the VM_DATA_DEFAULT_FLAGS setting used still in that arch,
-> the heap will always have executable permission, just like sparc does.
-> You have to support those binaries forever, whether you like it or not.
->
-> Let's just replace the CONFIG_PPC32 ifdef in SELINUX with CONFIG_PPC32
-> || CONFIG_SPARC as in Tom's original patch and let's be done with
-> this.
->
-> In fact I would go through all the arch/ header files and check the
-> VM_DATA_DEFAULT_FLAGS settings and add the necessary new ifdefs to the
-> SELINUX code so that other platforms don't have the pain of having to
-> go through this process too.
-
-To avoid maintaining per-arch ifdefs, it seems that we could just
-directly use (VM_DATA_DEFAULT_FLAGS & VM_EXEC) as the basis for deciding
-whether to enable or disable these checks. VM_DATA_DEFAULT_FLAGS isn't
-constant on some architectures but instead depends on
-current->personality, but we want this applied uniformly. So we'll just
-use the initial task state to determine whether or not to enable these
-checks.
-
-Signed-off-by: Stephen Smalley <sds@tycho.nsa.gov>
-
-diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
-index ebee467..a03fd74 100644
---- a/security/selinux/hooks.c
-+++ b/security/selinux/hooks.c
-@@ -2999,13 +2999,15 @@ static int selinux_file_ioctl(struct file *file, unsigned int cmd,
- return file_has_perm(cred, file, av);
- }
-
-+static int default_noexec;
-+
- static int file_map_prot_check(struct file *file, unsigned long prot, int shared)
- {
- const struct cred *cred = current_cred();
- int rc = 0;
-
--#ifndef CONFIG_PPC32
-- if ((prot & PROT_EXEC) && (!file || (!shared && (prot & PROT_WRITE)))) {
-+ if (default_noexec &&
-+ (prot & PROT_EXEC) && (!file || (!shared && (prot & PROT_WRITE)))) {
- /*
- * We are making executable an anonymous mapping or a
- * private file mapping that will also be writable.
-@@ -3015,7 +3017,6 @@ static int file_map_prot_check(struct file *file, unsigned long prot, int shared
- if (rc)
- goto error;
- }
--#endif
-
- if (file) {
- /* read access is always possible with a mapping */
-@@ -3076,8 +3077,8 @@ static int selinux_file_mprotect(struct vm_area_struct *vma,
- if (selinux_checkreqprot)
- prot = reqprot;
-
--#ifndef CONFIG_PPC32
-- if ((prot & PROT_EXEC) && !(vma->vm_flags & VM_EXEC)) {
-+ if (default_noexec &&
-+ (prot & PROT_EXEC) && !(vma->vm_flags & VM_EXEC)) {
- int rc = 0;
- if (vma->vm_start >= vma->vm_mm->start_brk &&
- vma->vm_end <= vma->vm_mm->brk) {
-@@ -3099,7 +3100,6 @@ static int selinux_file_mprotect(struct vm_area_struct *vma,
- if (rc)
- return rc;
- }
--#endif
-
- return file_map_prot_check(vma->vm_file, prot, vma->vm_flags&VM_SHARED);
- }
-@@ -5662,6 +5662,8 @@ static __init int selinux_init(void)
- /* Set the security state for the initial task. */
- cred_init_security();
-
-+ default_noexec = !(VM_DATA_DEFAULT_FLAGS & VM_EXEC);
-+
- sel_inode_cache = kmem_cache_create("selinux_inode_security",
- sizeof(struct inode_security_struct),
- 0, SLAB_PANIC, NULL);
-
---
-Stephen Smalley
-National Security Agency
-
diff --git a/linux-2.6-sparc-selinux-mprotect-checks.patch b/linux-2.6-sparc-selinux-mprotect-checks.patch
deleted file mode 100644
index cc821e323..000000000
--- a/linux-2.6-sparc-selinux-mprotect-checks.patch
+++ /dev/null
@@ -1,35 +0,0 @@
-diff -up linux-2.6.24.sparc64/security/selinux/hooks.c.BAD linux-2.6.24.sparc64/security/selinux/hooks.c
---- linux-2.6.24.sparc64/security/selinux/hooks.c.BAD 2008-03-21 14:28:06.000000000 -0400
-+++ linux-2.6.24.sparc64/security/selinux/hooks.c 2008-03-21 14:29:10.000000000 -0400
-@@ -3018,6 +3018,7 @@ static int file_map_prot_check(struct fi
- const struct cred *cred = current_cred();
- int rc = 0;
-
-+#ifndef CONFIG_SPARC
- if ((prot & PROT_EXEC) && (!file || (!shared && (prot & PROT_WRITE)))) {
- /*
- * We are making executable an anonymous mapping or a
-@@ -3028,6 +3029,7 @@ static int file_map_prot_check(struct fi
- if (rc)
- goto error;
- }
-+#endif
-
- if (file) {
- /* read access is always possible with a mapping */
-@@ -3081,6 +3081,7 @@ static int selinux_file_mprotect(struct
- if (selinux_checkreqprot)
- prot = reqprot;
-
-+#ifndef CONFIG_SPARC
- if ((prot & PROT_EXEC) && !(vma->vm_flags & VM_EXEC)) {
- rc = 0;
- if (vma->vm_start >= vma->vm_mm->start_brk &&
-@@ -3103,6 +3103,7 @@ static int selinux_file_mprotect(struct
- if (rc)
- return rc;
- }
-+#endif
-
- return file_map_prot_check(vma->vm_file, prot, vma->vm_flags&VM_SHARED);
- }
diff --git a/linux-2.6-v4l-dvb-ir-core-update.patch b/linux-2.6-v4l-dvb-ir-core-update.patch
deleted file mode 100644
index c1105a330..000000000
--- a/linux-2.6-v4l-dvb-ir-core-update.patch
+++ /dev/null
@@ -1,6741 +0,0 @@
-Patch generated from the linuxtv staging/other branch, with a few
-additional pending fixes merged in, and just about everything not
-essential to the ir-core update chopped out.
-
-(Patch generated 2010.07.16)
-
-Signed-off-by: Jarod Wilson <jarod@redhat.com>
-
----
- Documentation/DocBook/media-entities.tmpl | 1
- Documentation/DocBook/media.tmpl | 8
- Documentation/DocBook/v4l/lirc_device_interface.xml | 235 ++++
- Documentation/DocBook/v4l/remote_controllers.xml | 2
- Documentation/dvb/get_dvb_firmware | 19
- Documentation/video4linux/CARDLIST.cx23885 | 6
- drivers/input/evdev.c | 39
- drivers/input/input.c | 268 ++++
- drivers/media/IR/Kconfig | 34
- drivers/media/IR/Makefile | 3
- drivers/media/IR/imon.c | 5
- drivers/media/IR/ir-core-priv.h | 54
- drivers/media/IR/ir-jvc-decoder.c | 152 --
- drivers/media/IR/ir-lirc-codec.c | 283 ++++
- drivers/media/IR/ir-nec-decoder.c | 151 --
- drivers/media/IR/ir-raw-event.c | 167 +-
- drivers/media/IR/ir-rc5-decoder.c | 167 --
- drivers/media/IR/ir-rc6-decoder.c | 153 --
- drivers/media/IR/ir-sony-decoder.c | 155 --
- drivers/media/IR/ir-sysfs.c | 261 ++--
- drivers/media/IR/keymaps/Makefile | 2
- drivers/media/IR/keymaps/rc-lirc.c | 41
- drivers/media/IR/keymaps/rc-rc6-mce.c | 105 +
- drivers/media/IR/lirc_dev.c | 764 +++++++++++++
- drivers/media/IR/mceusb.c | 1143 ++++++++++++++++++++
- drivers/media/common/tuners/tda18271-fe.c | 8
- drivers/media/dvb/mantis/Kconfig | 14
- drivers/media/dvb/mantis/mantis_input.c | 5
- drivers/media/video/cx23885/cx23885-cards.c | 40
- drivers/media/video/cx23885/cx23885-core.c | 11
- drivers/media/video/cx23885/cx23885-dvb.c | 2
- drivers/media/video/cx23885/cx23885-input.c | 317 +----
- drivers/media/video/cx23885/cx23885-ir.c | 2
- drivers/media/video/cx23885/cx23885.h | 12
- drivers/media/video/cx88/cx88-cards.c | 9
- drivers/media/video/cx88/cx88-i2c.c | 6
- drivers/media/video/cx88/cx88-input.c | 46
- drivers/media/video/cx88/cx88.h | 1
- drivers/media/video/em28xx/em28xx-input.c | 80 -
- drivers/media/video/em28xx/em28xx-video.c | 4
- drivers/media/video/em28xx/em28xx.h | 1
- drivers/media/video/hdpvr/hdpvr-core.c | 5
- drivers/media/video/ir-kbd-i2c.c | 14
- drivers/media/video/pvrusb2/pvrusb2-ioread.c | 5
- include/linux/input.h | 39
- include/media/ir-core.h | 8
- include/media/ir-kbd-i2c.h | 2
- include/media/lirc.h | 165 ++
- include/media/lirc_dev.h | 225 +++
- include/media/rc-map.h | 7
- 50 files changed, 3971 insertions(+), 1275 deletions(-)
-
-diff --git a/Documentation/DocBook/media-entities.tmpl b/Documentation/DocBook/media-entities.tmpl
-index 5d4d40f..6ae9715 100644
---- a/Documentation/DocBook/media-entities.tmpl
-+++ b/Documentation/DocBook/media-entities.tmpl
-@@ -218,6 +218,7 @@
- <!ENTITY sub-dev-teletext SYSTEM "v4l/dev-teletext.xml">
- <!ENTITY sub-driver SYSTEM "v4l/driver.xml">
- <!ENTITY sub-libv4l SYSTEM "v4l/libv4l.xml">
-+<!ENTITY sub-lirc_device_interface SYSTEM "v4l/lirc_device_interface.xml">
- <!ENTITY sub-remote_controllers SYSTEM "v4l/remote_controllers.xml">
- <!ENTITY sub-fdl-appendix SYSTEM "v4l/fdl-appendix.xml">
- <!ENTITY sub-close SYSTEM "v4l/func-close.xml">
-diff --git a/Documentation/DocBook/media.tmpl b/Documentation/DocBook/media.tmpl
-index eea564b..f11048d 100644
---- a/Documentation/DocBook/media.tmpl
-+++ b/Documentation/DocBook/media.tmpl
-@@ -28,7 +28,7 @@
- <title>LINUX MEDIA INFRASTRUCTURE API</title>
-
- <copyright>
-- <year>2009</year>
-+ <year>2009-2010</year>
- <holder>LinuxTV Developers</holder>
- </copyright>
-
-@@ -61,7 +61,7 @@ Foundation. A copy of the license is included in the chapter entitled
- in fact it covers several different video standards including
- DVB-T, DVB-S, DVB-C and ATSC. The API is currently being updated
- to documment support also for DVB-S2, ISDB-T and ISDB-S.</para>
-- <para>The third part covers other API's used by all media infrastructure devices</para>
-+ <para>The third part covers Remote Controller API</para>
- <para>For additional information and for the latest development code,
- see: <ulink url="http://linuxtv.org">http://linuxtv.org</ulink>.</para>
- <para>For discussing improvements, reporting troubles, sending new drivers, etc, please mail to: <ulink url="http://vger.kernel.org/vger-lists.html#linux-media">Linux Media Mailing List (LMML).</ulink>.</para>
-@@ -86,7 +86,7 @@ Foundation. A copy of the license is included in the chapter entitled
- </author>
- </authorgroup>
- <copyright>
-- <year>2009</year>
-+ <year>2009-2010</year>
- <holder>Mauro Carvalho Chehab</holder>
- </copyright>
-
-@@ -101,7 +101,7 @@ Foundation. A copy of the license is included in the chapter entitled
- </revhistory>
- </partinfo>
-
--<title>Other API's used by media infrastructure drivers</title>
-+<title>Remote Controller API</title>
- <chapter id="remote_controllers">
- &sub-remote_controllers;
- </chapter>
-diff --git a/Documentation/DocBook/v4l/lirc_device_interface.xml b/Documentation/DocBook/v4l/lirc_device_interface.xml
-new file mode 100644
-index 0000000..0413234
---- /dev/null
-+++ b/Documentation/DocBook/v4l/lirc_device_interface.xml
-@@ -0,0 +1,235 @@
-+<section id="lirc_dev">
-+<title>LIRC Device Interface</title>
-+
-+
-+<section id="lirc_dev_intro">
-+<title>Introduction</title>
-+
-+<para>The LIRC device interface is a bi-directional interface for
-+transporting raw IR data between userspace and kernelspace. Fundamentally,
-+it is just a chardev (/dev/lircX, for X = 0, 1, 2, ...), with a number
-+of standard struct file_operations defined on it. With respect to
-+transporting raw IR data to and fro, the essential fops are read, write
-+and ioctl.</para>
-+
-+<para>Example dmesg output upon a driver registering w/LIRC:</para>
-+ <blockquote>
-+ <para>$ dmesg |grep lirc_dev</para>
-+ <para>lirc_dev: IR Remote Control driver registered, major 248</para>
-+ <para>rc rc0: lirc_dev: driver ir-lirc-codec (mceusb) registered at minor = 0</para>
-+ </blockquote>
-+
-+<para>What you should see for a chardev:</para>
-+ <blockquote>
-+ <para>$ ls -l /dev/lirc*</para>
-+ <para>crw-rw---- 1 root root 248, 0 Jul 2 22:20 /dev/lirc0</para>
-+ </blockquote>
-+</section>
-+
-+<section id="lirc_read">
-+<title>LIRC read fop</title>
-+
-+<para>The lircd userspace daemon reads raw IR data from the LIRC chardev. The
-+exact format of the data depends on what modes a driver supports, and what
-+mode has been selected. lircd obtains supported modes and sets the active mode
-+via the ioctl interface, detailed at <xref linkend="lirc_ioctl"/>. The generally
-+preferred mode is LIRC_MODE_MODE2, in which packets containing an int value
-+describing an IR signal are read from the chardev.</para>
-+
-+<para>See also <ulink url="http://www.lirc.org/html/technical.html">http://www.lirc.org/html/technical.html</ulink> for more info.</para>
-+</section>
-+
-+<section id="lirc_write">
-+<title>LIRC write fop</title>
-+
-+<para>The data written to the chardev is a pulse/space sequence of integer
-+values. Pulses and spaces are only marked implicitly by their position. The
-+data must start and end with a pulse, therefore, the data must always include
-+an unevent number of samples. The write function must block until the data has
-+been transmitted by the hardware.</para>
-+</section>
-+
-+<section id="lirc_ioctl">
-+<title>LIRC ioctl fop</title>
-+
-+<para>The LIRC device's ioctl definition is bound by the ioctl function
-+definition of struct file_operations, leaving us with an unsigned int
-+for the ioctl command and an unsigned long for the arg. For the purposes
-+of ioctl portability across 32-bit and 64-bit, these values are capped
-+to their 32-bit sizes.</para>
-+
-+<para>The following ioctls can be used to change specific hardware settings.
-+In general each driver should have a default set of settings. The driver
-+implementation is expected to re-apply the default settings when the device
-+is closed by user-space, so that every application opening the device can rely
-+on working with the default settings initially.</para>
-+
-+<variablelist>
-+ <varlistentry>
-+ <term>LIRC_GET_FEATURES</term>
-+ <listitem>
-+ <para>Obviously, get the underlying hardware device's features. If a driver
-+ does not announce support of certain features, calling of the corresponding
-+ ioctls is undefined.</para>
-+ </listitem>
-+ </varlistentry>
-+ <varlistentry>
-+ <term>LIRC_GET_SEND_MODE</term>
-+ <listitem>
-+ <para>Get supported transmit mode. Only LIRC_MODE_PULSE is supported by lircd.</para>
-+ </listitem>
-+ </varlistentry>
-+ <varlistentry>
-+ <term>LIRC_GET_REC_MODE</term>
-+ <listitem>
-+ <para>Get supported receive modes. Only LIRC_MODE_MODE2 and LIRC_MODE_LIRCCODE
-+ are supported by lircd.</para>
-+ </listitem>
-+ </varlistentry>
-+ <varlistentry>
-+ <term>LIRC_GET_SEND_CARRIER</term>
-+ <listitem>
-+ <para>Get carrier frequency (in Hz) currently used for transmit.</para>
-+ </listitem>
-+ </varlistentry>
-+ <varlistentry>
-+ <term>LIRC_GET_REC_CARRIER</term>
-+ <listitem>
-+ <para>Get carrier frequency (in Hz) currently used for IR reception.</para>
-+ </listitem>
-+ </varlistentry>
-+ <varlistentry>
-+ <term>LIRC_{G,S}ET_{SEND,REC}_DUTY_CYCLE</term>
-+ <listitem>
-+ <para>Get/set the duty cycle (from 0 to 100) of the carrier signal. Currently,
-+ no special meaning is defined for 0 or 100, but this could be used to switch
-+ off carrier generation in the future, so these values should be reserved.</para>
-+ </listitem>
-+ </varlistentry>
-+ <varlistentry>
-+ <term>LIRC_GET_REC_RESOLUTION</term>
-+ <listitem>
-+ <para>Some receiver have maximum resolution which is defined by internal
-+ sample rate or data format limitations. E.g. it's common that signals can
-+ only be reported in 50 microsecond steps. This integer value is used by
-+ lircd to automatically adjust the aeps tolerance value in the lircd
-+ config file.</para>
-+ </listitem>
-+ </varlistentry>
-+ <varlistentry>
-+ <term>LIRC_GET_M{IN,AX}_TIMEOUT</term>
-+ <listitem>
-+ <para>Some devices have internal timers that can be used to detect when
-+ there's no IR activity for a long time. This can help lircd in detecting
-+ that a IR signal is finished and can speed up the decoding process.
-+ Returns an integer value with the minimum/maximum timeout that can be
-+ set. Some devices have a fixed timeout, in that case both ioctls will
-+ return the same value even though the timeout cannot be changed.</para>
-+ </listitem>
-+ </varlistentry>
-+ <varlistentry>
-+ <term>LIRC_GET_M{IN,AX}_FILTER_{PULSE,SPACE}</term>
-+ <listitem>
-+ <para>Some devices are able to filter out spikes in the incoming signal
-+ using given filter rules. These ioctls return the hardware capabilities
-+ that describe the bounds of the possible filters. Filter settings depend
-+ on the IR protocols that are expected. lircd derives the settings from
-+ all protocols definitions found in its config file.</para>
-+ </listitem>
-+ </varlistentry>
-+ <varlistentry>
-+ <term>LIRC_GET_LENGTH</term>
-+ <listitem>
-+ <para>Retrieves the code length in bits (only for LIRC_MODE_LIRCCODE).
-+ Reads on the device must be done in blocks matching the bit count.
-+ The bit could should be rounded up so that it matches full bytes.</para>
-+ </listitem>
-+ </varlistentry>
-+ <varlistentry>
-+ <term>LIRC_SET_{SEND,REC}_MODE</term>
-+ <listitem>
-+ <para>Set send/receive mode. Largely obsolete for send, as only
-+ LIRC_MODE_PULSE is supported.</para>
-+ </listitem>
-+ </varlistentry>
-+ <varlistentry>
-+ <term>LIRC_SET_{SEND,REC}_CARRIER</term>
-+ <listitem>
-+ <para>Set send/receive carrier (in Hz).</para>
-+ </listitem>
-+ </varlistentry>
-+ <varlistentry>
-+ <term>LIRC_SET_TRANSMITTER_MASK</term>
-+ <listitem>
-+ <para>This enables the given set of transmitters. The first transmitter
-+ is encoded by the least significant bit, etc. When an invalid bit mask
-+ is given, i.e. a bit is set, even though the device does not have so many
-+ transitters, then this ioctl returns the number of available transitters
-+ and does nothing otherwise.</para>
-+ </listitem>
-+ </varlistentry>
-+ <varlistentry>
-+ <term>LIRC_SET_REC_TIMEOUT</term>
-+ <listitem>
-+ <para>Sets the integer value for IR inactivity timeout (cf.
-+ LIRC_GET_MIN_TIMEOUT and LIRC_GET_MAX_TIMEOUT). A value of 0 (if
-+ supported by the hardware) disables all hardware timeouts and data should
-+ be reported as soon as possible. If the exact value cannot be set, then
-+ the next possible value _greater_ than the given value should be set.</para>
-+ </listitem>
-+ </varlistentry>
-+ <varlistentry>
-+ <term>LIRC_SET_REC_TIMEOUT_REPORTS</term>
-+ <listitem>
-+ <para>Enable (1) or disable (0) timeout reports in LIRC_MODE_MODE2. By
-+ default, timeout reports should be turned off.</para>
-+ </listitem>
-+ </varlistentry>
-+ <varlistentry>
-+ <term>LIRC_SET_REC_FILTER_{,PULSE,SPACE}</term>
-+ <listitem>
-+ <para>Pulses/spaces shorter than this are filtered out by hardware. If
-+ filters cannot be set independently for pulse/space, the corresponding
-+ ioctls must return an error and LIRC_SET_REC_FILTER shall be used instead.</para>
-+ </listitem>
-+ </varlistentry>
-+ <varlistentry>
-+ <term>LIRC_SET_MEASURE_CARRIER_MODE</term>
-+ <listitem>
-+ <para>Enable (1)/disable (0) measure mode. If enabled, from the next key
-+ press on, the driver will send LIRC_MODE2_FREQUENCY packets. By default
-+ this should be turned off.</para>
-+ </listitem>
-+ </varlistentry>
-+ <varlistentry>
-+ <term>LIRC_SET_REC_{DUTY_CYCLE,CARRIER}_RANGE</term>
-+ <listitem>
-+ <para>To set a range use LIRC_SET_REC_DUTY_CYCLE_RANGE/LIRC_SET_REC_CARRIER_RANGE
-+ with the lower bound first and later LIRC_SET_REC_DUTY_CYCLE/LIRC_SET_REC_CARRIER
-+ with the upper bound.</para>
-+ </listitem>
-+ </varlistentry>
-+ <varlistentry>
-+ <term>LIRC_NOTIFY_DECODE</term>
-+ <listitem>
-+ <para>This ioctl is called by lircd whenever a successful decoding of an
-+ incoming IR signal could be done. This can be used by supporting hardware
-+ to give visual feedback to the user e.g. by flashing a LED.</para>
-+ </listitem>
-+ </varlistentry>
-+ <varlistentry>
-+ <term>LIRC_SETUP_{START,END}</term>
-+ <listitem>
-+ <para>Setting of several driver parameters can be optimized by encapsulating
-+ the according ioctl calls with LIRC_SETUP_START/LIRC_SETUP_END. When a
-+ driver receives a LIRC_SETUP_START ioctl it can choose to not commit
-+ further setting changes to the hardware until a LIRC_SETUP_END is received.
-+ But this is open to the driver implementation and every driver must also
-+ handle parameter changes which are not encapsulated by LIRC_SETUP_START
-+ and LIRC_SETUP_END. Drivers can also choose to ignore these ioctls.</para>
-+ </listitem>
-+ </varlistentry>
-+</variablelist>
-+
-+</section>
-+</section>
-diff --git a/Documentation/DocBook/v4l/remote_controllers.xml b/Documentation/DocBook/v4l/remote_controllers.xml
-index 73f5eab..3c3b667 100644
---- a/Documentation/DocBook/v4l/remote_controllers.xml
-+++ b/Documentation/DocBook/v4l/remote_controllers.xml
-@@ -173,3 +173,5 @@ keymapping.</para>
- <para>This program demonstrates how to replace the keymap tables.</para>
- &sub-keytable-c;
- </section>
-+
-+&sub-lirc_device_interface;
-diff --git a/Documentation/dvb/get_dvb_firmware b/Documentation/dvb/get_dvb_firmware
-index 239cbdb..9ea94dc 100644
---- a/Documentation/dvb/get_dvb_firmware
-+++ b/Documentation/dvb/get_dvb_firmware
-@@ -26,7 +26,7 @@ use IO::Handle;
- "dec3000s", "vp7041", "dibusb", "nxt2002", "nxt2004",
- "or51211", "or51132_qam", "or51132_vsb", "bluebird",
- "opera1", "cx231xx", "cx18", "cx23885", "pvrusb2", "mpc718",
-- "af9015", "ngene");
-+ "af9015", "ngene", "az6027");
-
- # Check args
- syntax() if (scalar(@ARGV) != 1);
-@@ -567,6 +567,23 @@ sub ngene {
- "$file1, $file2";
- }
-
-+sub az6027{
-+ my $file = "AZ6027_Linux_Driver.tar.gz";
-+ my $url = "http://linux.terratec.de/files/$file";
-+ my $firmware = "dvb-usb-az6027-03.fw";
-+
-+ wgetfile($file, $url);
-+
-+ #untar
-+ if( system("tar xzvf $file $firmware")){
-+ die "failed to untar firmware";
-+ }
-+ if( system("rm $file")){
-+ die ("unable to remove unnecessary files");
-+ }
-+
-+ $firmware;
-+}
- # ---------------------------------------------------------------
- # Utilities
-
-diff --git a/Documentation/video4linux/CARDLIST.cx23885 b/Documentation/video4linux/CARDLIST.cx23885
-index 16ca030..87c4634 100644
---- a/Documentation/video4linux/CARDLIST.cx23885
-+++ b/Documentation/video4linux/CARDLIST.cx23885
-@@ -17,9 +17,9 @@
- 16 -> DVBWorld DVB-S2 2005 [0001:2005]
- 17 -> NetUP Dual DVB-S2 CI [1b55:2a2c]
- 18 -> Hauppauge WinTV-HVR1270 [0070:2211]
-- 19 -> Hauppauge WinTV-HVR1275 [0070:2215]
-- 20 -> Hauppauge WinTV-HVR1255 [0070:2251]
-- 21 -> Hauppauge WinTV-HVR1210 [0070:2291,0070:2295]
-+ 19 -> Hauppauge WinTV-HVR1275 [0070:2215,0070:221d,0070:22f2]
-+ 20 -> Hauppauge WinTV-HVR1255 [0070:2251,0070:2259,0070:22f1]
-+ 21 -> Hauppauge WinTV-HVR1210 [0070:2291,0070:2295,0070:2299,0070:229d,0070:22f0,0070:22f3,0070:22f4,0070:22f5]
- 22 -> Mygica X8506 DMB-TH [14f1:8651]
- 23 -> Magic-Pro ProHDTV Extreme 2 [14f1:8657]
- 24 -> Hauppauge WinTV-HVR1850 [0070:8541]
-diff --git a/Documentation/video4linux/extract_xc3028.pl b/Documentation/video4linux/extract_xc3028.pl
-old mode 100644
-new mode 100755
-diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c
-index 2ee6c7a..b8a5673 100644
---- a/drivers/input/evdev.c
-+++ b/drivers/input/evdev.c
-@@ -515,6 +515,8 @@ static long evdev_do_ioctl(struct file *file, unsigned int cmd,
- struct input_absinfo abs;
- struct ff_effect effect;
- int __user *ip = (int __user *)p;
-+ struct keycode_table_entry kt, *kt_p = p;
-+ char scancode[16];
- unsigned int i, t, u, v;
- int error;
-
-@@ -569,6 +571,43 @@ static long evdev_do_ioctl(struct file *file, unsigned int cmd,
-
- return input_set_keycode(dev, t, v);
-
-+ case EVIOCGKEYCODEBIG:
-+ if (copy_from_user(&kt, kt_p, sizeof(kt)))
-+ return -EFAULT;
-+
-+ if (kt.len > sizeof(scancode))
-+ return -EINVAL;
-+
-+ kt.scancode = scancode;
-+
-+ error = input_get_keycode_big(dev, &kt);
-+ if (error)
-+ return error;
-+
-+ if (copy_to_user(kt_p, &kt, sizeof(kt)))
-+ return -EFAULT;
-+
-+ /* FIXME: probably need some compat32 code */
-+ if (copy_to_user(kt_p->scancode, kt.scancode, kt.len))
-+ return -EFAULT;
-+
-+ return 0;
-+
-+ case EVIOCSKEYCODEBIG:
-+ if (copy_from_user(&kt, kt_p, sizeof(kt)))
-+ return -EFAULT;
-+
-+ if (kt.len > sizeof(scancode))
-+ return -EINVAL;
-+
-+ kt.scancode = scancode;
-+
-+ /* FIXME: probably need some compat32 code */
-+ if (copy_from_user(kt.scancode, kt_p->scancode, kt.len))
-+ return -EFAULT;
-+
-+ return input_set_keycode_big(dev, &kt);
-+
- case EVIOCRMFF:
- return input_ff_erase(dev, (int)(unsigned long) p, file);
-
-diff --git a/drivers/input/input.c b/drivers/input/input.c
-index 9c79bd5..43aeb71 100644
---- a/drivers/input/input.c
-+++ b/drivers/input/input.c
-@@ -568,6 +568,11 @@ static void input_disconnect_device(struct input_dev *dev)
- spin_unlock_irq(&dev->event_lock);
- }
-
-+/*
-+ * Those routines handle the default case where no [gs]etkeycode() is
-+ * defined. In this case, an array indexed by the scancode is used.
-+ */
-+
- static int input_fetch_keycode(struct input_dev *dev, int scancode)
- {
- switch (dev->keycodesize) {
-@@ -582,27 +587,74 @@ static int input_fetch_keycode(struct input_dev *dev, int scancode)
- }
- }
-
--static int input_default_getkeycode(struct input_dev *dev,
-- unsigned int scancode,
-- unsigned int *keycode)
-+/*
-+ * Supports only 8, 16 and 32 bit scancodes. It wouldn't be that
-+ * hard to write some machine-endian logic to support 24 bit scancodes,
-+ * but it seemed overkill. It should also be noticed that, since there
-+ * are, in general, less than 256 scancodes sparsed into the scancode
-+ * space, even with 16 bits, the codespace is sparsed, with leads into
-+ * memory and code ineficiency, when retrieving the entire scancode
-+ * space.
-+ * So, it is highly recommended to implement getkeycodebig/setkeycodebig
-+ * instead of using a normal table approach, when more than 8 bits is
-+ * needed for the scancode.
-+ */
-+static int input_fetch_scancode(struct keycode_table_entry *kt_entry,
-+ u32 *scancode)
- {
-+ switch (kt_entry->len) {
-+ case 1:
-+ *scancode = *((u8 *)kt_entry->scancode);
-+ break;
-+ case 2:
-+ *scancode = *((u16 *)kt_entry->scancode);
-+ break;
-+ case 4:
-+ *scancode = *((u32 *)kt_entry->scancode);
-+ break;
-+ default:
-+ return -EINVAL;
-+ }
-+ return 0;
-+}
-+
-+
-+static int input_default_getkeycode_from_index(struct input_dev *dev,
-+ struct keycode_table_entry *kt_entry)
-+{
-+ u32 scancode = kt_entry->index;
-+
- if (!dev->keycodesize)
- return -EINVAL;
-
- if (scancode >= dev->keycodemax)
- return -EINVAL;
-
-- *keycode = input_fetch_keycode(dev, scancode);
-+ kt_entry->keycode = input_fetch_keycode(dev, scancode);
-+ memcpy(kt_entry->scancode, &scancode, 4);
-
- return 0;
- }
-
-+static int input_default_getkeycode_from_scancode(struct input_dev *dev,
-+ struct keycode_table_entry *kt_entry)
-+{
-+ if (input_fetch_scancode(kt_entry, &kt_entry->index))
-+ return -EINVAL;
-+
-+ return input_default_getkeycode_from_index(dev, kt_entry);
-+}
-+
-+
- static int input_default_setkeycode(struct input_dev *dev,
-- unsigned int scancode,
-- unsigned int keycode)
-+ struct keycode_table_entry *kt_entry)
- {
-- int old_keycode;
-+ u32 old_keycode;
- int i;
-+ u32 scancode;
-+
-+ if (input_fetch_scancode(kt_entry, &scancode))
-+ return -EINVAL;
-
- if (scancode >= dev->keycodemax)
- return -EINVAL;
-@@ -610,32 +662,33 @@ static int input_default_setkeycode(struct input_dev *dev,
- if (!dev->keycodesize)
- return -EINVAL;
-
-- if (dev->keycodesize < sizeof(keycode) && (keycode >> (dev->keycodesize * 8)))
-+ if (dev->keycodesize < sizeof(dev->keycode) &&
-+ (kt_entry->keycode >> (dev->keycodesize * 8)))
- return -EINVAL;
-
- switch (dev->keycodesize) {
- case 1: {
- u8 *k = (u8 *)dev->keycode;
- old_keycode = k[scancode];
-- k[scancode] = keycode;
-+ k[scancode] = kt_entry->keycode;
- break;
- }
- case 2: {
- u16 *k = (u16 *)dev->keycode;
- old_keycode = k[scancode];
-- k[scancode] = keycode;
-+ k[scancode] = kt_entry->keycode;
- break;
- }
- default: {
- u32 *k = (u32 *)dev->keycode;
- old_keycode = k[scancode];
-- k[scancode] = keycode;
-+ k[scancode] = kt_entry->keycode;
- break;
- }
- }
-
- __clear_bit(old_keycode, dev->keybit);
-- __set_bit(keycode, dev->keybit);
-+ __set_bit(kt_entry->keycode, dev->keybit);
-
- for (i = 0; i < dev->keycodemax; i++) {
- if (input_fetch_keycode(dev, i) == old_keycode) {
-@@ -648,6 +701,110 @@ static int input_default_setkeycode(struct input_dev *dev,
- }
-
- /**
-+ * input_get_keycode_big - retrieve keycode currently mapped to a given scancode
-+ * @dev: input device which keymap is being queried
-+ * @kt_entry: keytable entry
-+ *
-+ * This function should be called by anyone interested in retrieving current
-+ * keymap. Presently evdev handlers use it.
-+ */
-+int input_get_keycode_big(struct input_dev *dev,
-+ struct keycode_table_entry *kt_entry)
-+{
-+ if (dev->getkeycode) {
-+ u32 scancode = kt_entry->index;
-+
-+ /*
-+ * Support for legacy drivers, that don't implement the new
-+ * ioctls
-+ */
-+ memcpy(kt_entry->scancode, &scancode, 4);
-+ return dev->getkeycode(dev, scancode,
-+ &kt_entry->keycode);
-+ } else
-+ return dev->getkeycodebig_from_index(dev, kt_entry);
-+}
-+EXPORT_SYMBOL(input_get_keycode_big);
-+
-+/**
-+ * input_set_keycode_big - attribute a keycode to a given scancode
-+ * @dev: input device which keymap is being queried
-+ * @kt_entry: keytable entry
-+ *
-+ * This function should be called by anyone needing to update current
-+ * keymap. Presently keyboard and evdev handlers use it.
-+ */
-+int input_set_keycode_big(struct input_dev *dev,
-+ struct keycode_table_entry *kt_entry)
-+{
-+ unsigned long flags;
-+ int old_keycode;
-+ int retval = -EINVAL;
-+ u32 uninitialized_var(scancode);
-+
-+ if (kt_entry->keycode < 0 || kt_entry->keycode > KEY_MAX)
-+ return -EINVAL;
-+
-+ spin_lock_irqsave(&dev->event_lock, flags);
-+
-+ /*
-+ * We need to know the old scancode, in order to generate a
-+ * keyup effect, if the set operation happens successfully
-+ */
-+ if (dev->getkeycode) {
-+ /*
-+ * Support for legacy drivers, that don't implement the new
-+ * ioctls
-+ */
-+ if (!dev->setkeycode)
-+ goto out;
-+
-+ retval = input_fetch_scancode(kt_entry, &scancode);
-+ if (retval)
-+ goto out;
-+
-+ retval = dev->getkeycode(dev, scancode,
-+ &old_keycode);
-+ } else {
-+ int new_keycode = kt_entry->keycode;
-+
-+ retval = dev->getkeycodebig_from_scancode(dev, kt_entry);
-+ old_keycode = kt_entry->keycode;
-+ kt_entry->keycode = new_keycode;
-+ }
-+
-+ if (retval)
-+ goto out;
-+
-+ if (dev->getkeycode)
-+ retval = dev->setkeycode(dev, scancode,
-+ kt_entry->keycode);
-+ else
-+ retval = dev->setkeycodebig(dev, kt_entry);
-+ if (retval)
-+ goto out;
-+
-+ /*
-+ * Simulate keyup event if keycode is not present
-+ * in the keymap anymore
-+ */
-+ if (test_bit(EV_KEY, dev->evbit) &&
-+ !is_event_supported(old_keycode, dev->keybit, KEY_MAX) &&
-+ __test_and_clear_bit(old_keycode, dev->key)) {
-+
-+ input_pass_event(dev, EV_KEY, old_keycode, 0);
-+ if (dev->sync)
-+ input_pass_event(dev, EV_SYN, SYN_REPORT, 1);
-+ }
-+
-+ out:
-+ spin_unlock_irqrestore(&dev->event_lock, flags);
-+
-+ return retval;
-+}
-+EXPORT_SYMBOL(input_set_keycode_big);
-+
-+/**
- * input_get_keycode - retrieve keycode currently mapped to a given scancode
- * @dev: input device which keymap is being queried
- * @scancode: scancode (or its equivalent for device in question) for which
-@@ -661,13 +818,35 @@ int input_get_keycode(struct input_dev *dev,
- unsigned int scancode, unsigned int *keycode)
- {
- unsigned long flags;
-- int retval;
-
-- spin_lock_irqsave(&dev->event_lock, flags);
-- retval = dev->getkeycode(dev, scancode, keycode);
-- spin_unlock_irqrestore(&dev->event_lock, flags);
-+ if (dev->getkeycode) {
-+ /*
-+ * Use the legacy calls
-+ */
-+ return dev->getkeycode(dev, scancode, keycode);
-+ } else {
-+ int retval;
-+ struct keycode_table_entry kt_entry;
-
-- return retval;
-+ /*
-+ * Userspace is using a legacy call with a driver ported
-+ * to the new way. This is a bad idea with long sparsed
-+ * tables, since lots of the retrieved values will be in
-+ * blank. Also, it makes sense only if the table size is
-+ * lower than 2^32.
-+ */
-+ memset(&kt_entry, 0, sizeof(kt_entry));
-+ kt_entry.len = 4;
-+ kt_entry.index = scancode;
-+ kt_entry.scancode = (char *)&scancode;
-+
-+ spin_lock_irqsave(&dev->event_lock, flags);
-+ retval = dev->getkeycodebig_from_index(dev, &kt_entry);
-+ spin_unlock_irqrestore(&dev->event_lock, flags);
-+
-+ *keycode = kt_entry.keycode;
-+ return retval;
-+ }
- }
- EXPORT_SYMBOL(input_get_keycode);
-
-@@ -692,13 +871,42 @@ int input_set_keycode(struct input_dev *dev,
-
- spin_lock_irqsave(&dev->event_lock, flags);
-
-- retval = dev->getkeycode(dev, scancode, &old_keycode);
-- if (retval)
-- goto out;
-+ if (dev->getkeycode) {
-+ /*
-+ * Use the legacy calls
-+ */
-+ retval = dev->getkeycode(dev, scancode, &old_keycode);
-+ if (retval)
-+ goto out;
-
-- retval = dev->setkeycode(dev, scancode, keycode);
-- if (retval)
-- goto out;
-+ retval = dev->setkeycode(dev, scancode, keycode);
-+ if (retval)
-+ goto out;
-+ } else {
-+ struct keycode_table_entry kt_entry;
-+
-+ /*
-+ * Userspace is using a legacy call with a driver ported
-+ * to the new way. This is a bad idea with long sparsed
-+ * tables, since lots of the retrieved values will be in
-+ * blank. Also, it makes sense only if the table size is
-+ * lower than 2^32.
-+ */
-+ memset(&kt_entry, 0, sizeof(kt_entry));
-+ kt_entry.len = 4;
-+ kt_entry.scancode = (char *)&scancode;
-+
-+ retval = dev->getkeycodebig_from_scancode(dev, &kt_entry);
-+ if (retval)
-+ goto out;
-+
-+ old_keycode = kt_entry.keycode;
-+ kt_entry.keycode = keycode;
-+
-+ retval = dev->setkeycodebig(dev, &kt_entry);
-+ if (retval)
-+ goto out;
-+ }
-
- /* Make sure KEY_RESERVED did not get enabled. */
- __clear_bit(KEY_RESERVED, dev->keybit);
-@@ -1636,11 +1843,17 @@ int input_register_device(struct input_dev *dev)
- dev->rep[REP_PERIOD] = 33;
- }
-
-- if (!dev->getkeycode)
-- dev->getkeycode = input_default_getkeycode;
-+ if (!dev->getkeycode) {
-+ if (!dev->getkeycodebig_from_index)
-+ dev->getkeycodebig_from_index = input_default_getkeycode_from_index;
-+ if (!dev->getkeycodebig_from_scancode)
-+ dev->getkeycodebig_from_scancode = input_default_getkeycode_from_scancode;
-+ }
-
-- if (!dev->setkeycode)
-- dev->setkeycode = input_default_setkeycode;
-+ if (!dev->setkeycode) {
-+ if (!dev->setkeycodebig)
-+ dev->setkeycodebig = input_default_setkeycode;
-+ }
-
- dev_set_name(&dev->dev, "input%ld",
- (unsigned long) atomic_inc_return(&input_no) - 1);
-diff --git a/drivers/media/IR/Kconfig b/drivers/media/IR/Kconfig
-index d22a8ec..e557ae0 100644
---- a/drivers/media/IR/Kconfig
-+++ b/drivers/media/IR/Kconfig
-@@ -8,6 +8,17 @@ config VIDEO_IR
- depends on IR_CORE
- default IR_CORE
-
-+config LIRC
-+ tristate
-+ default y
-+
-+ ---help---
-+ Enable this option to build the Linux Infrared Remote
-+ Control (LIRC) core device interface driver. The LIRC
-+ interface passes raw IR to and from userspace, where the
-+ LIRC daemon handles protocol decoding for IR reception ann
-+ encoding for IR transmitting (aka "blasting").
-+
- source "drivers/media/IR/keymaps/Kconfig"
-
- config IR_NEC_DECODER
-@@ -42,6 +53,7 @@ config IR_RC6_DECODER
- config IR_JVC_DECODER
- tristate "Enable IR raw decoder for the JVC protocol"
- depends on IR_CORE
-+ select BITREVERSE
- default y
-
- ---help---
-@@ -57,6 +69,16 @@ config IR_SONY_DECODER
- Enable this option if you have an infrared remote control which
- uses the Sony protocol, and you need software decoding support.
-
-+config IR_LIRC_CODEC
-+ tristate "Enable IR to LIRC bridge"
-+ depends on IR_CORE
-+ depends on LIRC
-+ default y
-+
-+ ---help---
-+ Enable this option to pass raw IR to and from userspace via
-+ the LIRC interface.
-+
- config IR_IMON
- tristate "SoundGraph iMON Receiver and Display"
- depends on USB_ARCH_HAS_HCD
-@@ -68,3 +90,15 @@ config IR_IMON
-
- To compile this driver as a module, choose M here: the
- module will be called imon.
-+
-+config IR_MCEUSB
-+ tristate "Windows Media Center Ed. eHome Infrared Transceiver"
-+ depends on USB_ARCH_HAS_HCD
-+ depends on IR_CORE
-+ select USB
-+ ---help---
-+ Say Y here if you want to use a Windows Media Center Edition
-+ eHome Infrared Transceiver.
-+
-+ To compile this driver as a module, choose M here: the
-+ module will be called mceusb.
-diff --git a/drivers/media/IR/Makefile b/drivers/media/IR/Makefile
-index b998fcc..2ae4f3a 100644
---- a/drivers/media/IR/Makefile
-+++ b/drivers/media/IR/Makefile
-@@ -5,11 +5,14 @@ obj-y += keymaps/
-
- obj-$(CONFIG_IR_CORE) += ir-core.o
- obj-$(CONFIG_VIDEO_IR) += ir-common.o
-+obj-$(CONFIG_LIRC) += lirc_dev.o
- obj-$(CONFIG_IR_NEC_DECODER) += ir-nec-decoder.o
- obj-$(CONFIG_IR_RC5_DECODER) += ir-rc5-decoder.o
- obj-$(CONFIG_IR_RC6_DECODER) += ir-rc6-decoder.o
- obj-$(CONFIG_IR_JVC_DECODER) += ir-jvc-decoder.o
- obj-$(CONFIG_IR_SONY_DECODER) += ir-sony-decoder.o
-+obj-$(CONFIG_IR_LIRC_CODEC) += ir-lirc-codec.o
-
- # stand-alone IR receivers/transmitters
- obj-$(CONFIG_IR_IMON) += imon.o
-+obj-$(CONFIG_IR_MCEUSB) += mceusb.o
-diff --git a/drivers/media/IR/imon.c b/drivers/media/IR/imon.c
-index 4bbd45f..0195dd5 100644
---- a/drivers/media/IR/imon.c
-+++ b/drivers/media/IR/imon.c
-@@ -1943,7 +1943,7 @@ static struct imon_context *imon_init_intf0(struct usb_interface *intf)
- return ictx;
-
- urb_submit_failed:
-- input_unregister_device(ictx->idev);
-+ ir_input_unregister(ictx->idev);
- input_free_device(ictx->idev);
- idev_setup_failed:
- find_endpoint_failed:
-@@ -2067,6 +2067,7 @@ static void imon_get_ffdc_type(struct imon_context *ictx)
- detected_display_type = IMON_DISPLAY_TYPE_VFD;
- break;
- /* iMON LCD, MCE IR */
-+ case 0x9e:
- case 0x9f:
- dev_info(ictx->dev, "0xffdc iMON LCD, MCE IR");
- detected_display_type = IMON_DISPLAY_TYPE_LCD;
-@@ -2306,7 +2307,7 @@ static void __devexit imon_disconnect(struct usb_interface *interface)
- if (ifnum == 0) {
- ictx->dev_present_intf0 = false;
- usb_kill_urb(ictx->rx_urb_intf0);
-- input_unregister_device(ictx->idev);
-+ ir_input_unregister(ictx->idev);
- if (ictx->display_supported) {
- if (ictx->display_type == IMON_DISPLAY_TYPE_LCD)
- usb_deregister_dev(interface, &imon_lcd_class);
-diff --git a/drivers/media/IR/ir-core-priv.h b/drivers/media/IR/ir-core-priv.h
-index 9a5e65a..babd520 100644
---- a/drivers/media/IR/ir-core-priv.h
-+++ b/drivers/media/IR/ir-core-priv.h
-@@ -22,17 +22,62 @@
- struct ir_raw_handler {
- struct list_head list;
-
-+ u64 protocols; /* which are handled by this handler */
- int (*decode)(struct input_dev *input_dev, struct ir_raw_event event);
-+
-+ /* These two should only be used by the lirc decoder */
- int (*raw_register)(struct input_dev *input_dev);
- int (*raw_unregister)(struct input_dev *input_dev);
- };
-
- struct ir_raw_event_ctrl {
-+ struct list_head list; /* to keep track of raw clients */
- struct work_struct rx_work; /* for the rx decoding workqueue */
- struct kfifo kfifo; /* fifo for the pulse/space durations */
- ktime_t last_event; /* when last event occurred */
- enum raw_event_type last_type; /* last event type */
- struct input_dev *input_dev; /* pointer to the parent input_dev */
-+ u64 enabled_protocols; /* enabled raw protocol decoders */
-+
-+ /* raw decoder state follows */
-+ struct ir_raw_event prev_ev;
-+ struct nec_dec {
-+ int state;
-+ unsigned count;
-+ u32 bits;
-+ } nec;
-+ struct rc5_dec {
-+ int state;
-+ u32 bits;
-+ unsigned count;
-+ unsigned wanted_bits;
-+ } rc5;
-+ struct rc6_dec {
-+ int state;
-+ u8 header;
-+ u32 body;
-+ bool toggle;
-+ unsigned count;
-+ unsigned wanted_bits;
-+ } rc6;
-+ struct sony_dec {
-+ int state;
-+ u32 bits;
-+ unsigned count;
-+ } sony;
-+ struct jvc_dec {
-+ int state;
-+ u16 bits;
-+ u16 old_bits;
-+ unsigned count;
-+ bool first;
-+ bool toggle;
-+ } jvc;
-+ struct lirc_codec {
-+ struct ir_input_dev *ir_dev;
-+ struct lirc_driver *drv;
-+ int lircdata;
-+ } lirc;
- };
-
- /* macros for IR decoders */
-@@ -74,6 +119,7 @@ void ir_unregister_class(struct input_dev *input_dev);
- /*
- * Routines from ir-raw-event.c to be used internally and by decoders
- */
-+u64 ir_raw_get_allowed_protocols(void);
- int ir_raw_event_register(struct input_dev *input_dev);
- void ir_raw_event_unregister(struct input_dev *input_dev);
- int ir_raw_handler_register(struct ir_raw_handler *ir_raw_handler);
-@@ -123,4 +169,12 @@ void ir_raw_init(void);
- #define load_sony_decode() 0
- #endif
-
-+/* from ir-lirc-codec.c */
-+#ifdef CONFIG_IR_LIRC_CODEC_MODULE
-+#define load_lirc_codec() request_module("ir-lirc-codec")
-+#else
-+#define load_lirc_codec() 0
-+#endif
-+
-+
- #endif /* _IR_RAW_EVENT */
-diff --git a/drivers/media/IR/ir-jvc-decoder.c b/drivers/media/IR/ir-jvc-decoder.c
-index 0b80494..8894d8b 100644
---- a/drivers/media/IR/ir-jvc-decoder.c
-+++ b/drivers/media/IR/ir-jvc-decoder.c
-@@ -25,10 +25,6 @@
- #define JVC_TRAILER_PULSE (1 * JVC_UNIT)
- #define JVC_TRAILER_SPACE (35 * JVC_UNIT)
-
--/* Used to register jvc_decoder clients */
--static LIST_HEAD(decoder_list);
--DEFINE_SPINLOCK(decoder_lock);
--
- enum jvc_state {
- STATE_INACTIVE,
- STATE_HEADER_SPACE,
-@@ -38,87 +34,6 @@ enum jvc_state {
- STATE_TRAILER_SPACE,
- };
-
--struct decoder_data {
-- struct list_head list;
-- struct ir_input_dev *ir_dev;
-- int enabled:1;
--
-- /* State machine control */
-- enum jvc_state state;
-- u16 jvc_bits;
-- u16 jvc_old_bits;
-- unsigned count;
-- bool first;
-- bool toggle;
--};
--
--
--/**
-- * get_decoder_data() - gets decoder data
-- * @input_dev: input device
-- *
-- * Returns the struct decoder_data that corresponds to a device
-- */
--static struct decoder_data *get_decoder_data(struct ir_input_dev *ir_dev)
--{
-- struct decoder_data *data = NULL;
--
-- spin_lock(&decoder_lock);
-- list_for_each_entry(data, &decoder_list, list) {
-- if (data->ir_dev == ir_dev)
-- break;
-- }
-- spin_unlock(&decoder_lock);
-- return data;
--}
--
--static ssize_t store_enabled(struct device *d,
-- struct device_attribute *mattr,
-- const char *buf,
-- size_t len)
--{
-- unsigned long value;
-- struct ir_input_dev *ir_dev = dev_get_drvdata(d);
-- struct decoder_data *data = get_decoder_data(ir_dev);
--
-- if (!data)
-- return -EINVAL;
--
-- if (strict_strtoul(buf, 10, &value) || value > 1)
-- return -EINVAL;
--
-- data->enabled = value;
--
-- return len;
--}
--
--static ssize_t show_enabled(struct device *d,
-- struct device_attribute *mattr, char *buf)
--{
-- struct ir_input_dev *ir_dev = dev_get_drvdata(d);
-- struct decoder_data *data = get_decoder_data(ir_dev);
--
-- if (!data)
-- return -EINVAL;
--
-- if (data->enabled)
-- return sprintf(buf, "1\n");
-- else
-- return sprintf(buf, "0\n");
--}
--
--static DEVICE_ATTR(enabled, S_IRUGO | S_IWUSR, show_enabled, store_enabled);
--
--static struct attribute *decoder_attributes[] = {
-- &dev_attr_enabled.attr,
-- NULL
--};
--
--static struct attribute_group decoder_attribute_group = {
-- .name = "jvc_decoder",
-- .attrs = decoder_attributes,
--};
--
- /**
- * ir_jvc_decode() - Decode one JVC pulse or space
- * @input_dev: the struct input_dev descriptor of the device
-@@ -128,14 +43,10 @@ static struct attribute_group decoder_attribute_group = {
- */
- static int ir_jvc_decode(struct input_dev *input_dev, struct ir_raw_event ev)
- {
-- struct decoder_data *data;
- struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
-+ struct jvc_dec *data = &ir_dev->raw->jvc;
-
-- data = get_decoder_data(ir_dev);
-- if (!data)
-- return -EINVAL;
--
-- if (!data->enabled)
-+ if (!(ir_dev->raw->enabled_protocols & IR_TYPE_JVC))
- return 0;
-
- if (IS_RESET(ev)) {
-@@ -188,9 +99,9 @@ static int ir_jvc_decode(struct input_dev *input_dev, struct ir_raw_event ev)
- if (ev.pulse)
- break;
-
-- data->jvc_bits <<= 1;
-+ data->bits <<= 1;
- if (eq_margin(ev.duration, JVC_BIT_1_SPACE, JVC_UNIT / 2)) {
-- data->jvc_bits |= 1;
-+ data->bits |= 1;
- decrease_duration(&ev, JVC_BIT_1_SPACE);
- } else if (eq_margin(ev.duration, JVC_BIT_0_SPACE, JVC_UNIT / 2))
- decrease_duration(&ev, JVC_BIT_0_SPACE);
-@@ -223,13 +134,13 @@ static int ir_jvc_decode(struct input_dev *input_dev, struct ir_raw_event ev)
-
- if (data->first) {
- u32 scancode;
-- scancode = (bitrev8((data->jvc_bits >> 8) & 0xff) << 8) |
-- (bitrev8((data->jvc_bits >> 0) & 0xff) << 0);
-+ scancode = (bitrev8((data->bits >> 8) & 0xff) << 8) |
-+ (bitrev8((data->bits >> 0) & 0xff) << 0);
- IR_dprintk(1, "JVC scancode 0x%04x\n", scancode);
- ir_keydown(input_dev, scancode, data->toggle);
- data->first = false;
-- data->jvc_old_bits = data->jvc_bits;
-- } else if (data->jvc_bits == data->jvc_old_bits) {
-+ data->old_bits = data->bits;
-+ } else if (data->bits == data->old_bits) {
- IR_dprintk(1, "JVC repeat\n");
- ir_repeat(input_dev);
- } else {
-@@ -249,54 +160,9 @@ out:
- return -EINVAL;
- }
-
--static int ir_jvc_register(struct input_dev *input_dev)
--{
-- struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
-- struct decoder_data *data;
-- int rc;
--
-- rc = sysfs_create_group(&ir_dev->dev.kobj, &decoder_attribute_group);
-- if (rc < 0)
-- return rc;
--
-- data = kzalloc(sizeof(*data), GFP_KERNEL);
-- if (!data) {
-- sysfs_remove_group(&ir_dev->dev.kobj, &decoder_attribute_group);
-- return -ENOMEM;
-- }
--
-- data->ir_dev = ir_dev;
-- data->enabled = 1;
--
-- spin_lock(&decoder_lock);
-- list_add_tail(&data->list, &decoder_list);
-- spin_unlock(&decoder_lock);
--
-- return 0;
--}
--
--static int ir_jvc_unregister(struct input_dev *input_dev)
--{
-- struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
-- static struct decoder_data *data;
--
-- data = get_decoder_data(ir_dev);
-- if (!data)
-- return 0;
--
-- sysfs_remove_group(&ir_dev->dev.kobj, &decoder_attribute_group);
--
-- spin_lock(&decoder_lock);
-- list_del(&data->list);
-- spin_unlock(&decoder_lock);
--
-- return 0;
--}
--
- static struct ir_raw_handler jvc_handler = {
-+ .protocols = IR_TYPE_JVC,
- .decode = ir_jvc_decode,
-- .raw_register = ir_jvc_register,
-- .raw_unregister = ir_jvc_unregister,
- };
-
- static int __init ir_jvc_decode_init(void)
-diff --git a/drivers/media/IR/ir-lirc-codec.c b/drivers/media/IR/ir-lirc-codec.c
-new file mode 100644
-index 0000000..afb1ada
---- /dev/null
-+++ b/drivers/media/IR/ir-lirc-codec.c
-@@ -0,0 +1,283 @@
-+/* ir-lirc-codec.c - ir-core to classic lirc interface bridge
-+ *
-+ * Copyright (C) 2010 by Jarod Wilson <jarod@redhat.com>
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation version 2 of the License.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ */
-+
-+#include <linux/sched.h>
-+#include <linux/wait.h>
-+#include <media/lirc.h>
-+#include <media/lirc_dev.h>
-+#include <media/ir-core.h>
-+#include "ir-core-priv.h"
-+
-+#define LIRCBUF_SIZE 256
-+
-+/**
-+ * ir_lirc_decode() - Send raw IR data to lirc_dev to be relayed to the
-+ * lircd userspace daemon for decoding.
-+ * @input_dev: the struct input_dev descriptor of the device
-+ * @duration: the struct ir_raw_event descriptor of the pulse/space
-+ *
-+ * This function returns -EINVAL if the lirc interfaces aren't wired up.
-+ */
-+static int ir_lirc_decode(struct input_dev *input_dev, struct ir_raw_event ev)
-+{
-+ struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
-+
-+ if (!(ir_dev->raw->enabled_protocols & IR_TYPE_LIRC))
-+ return 0;
-+
-+ if (!ir_dev->raw->lirc.drv || !ir_dev->raw->lirc.drv->rbuf)
-+ return -EINVAL;
-+
-+ IR_dprintk(2, "LIRC data transfer started (%uus %s)\n",
-+ TO_US(ev.duration), TO_STR(ev.pulse));
-+
-+ ir_dev->raw->lirc.lircdata += ev.duration / 1000;
-+ if (ev.pulse)
-+ ir_dev->raw->lirc.lircdata |= PULSE_BIT;
-+
-+ lirc_buffer_write(ir_dev->raw->lirc.drv->rbuf,
-+ (unsigned char *) &ir_dev->raw->lirc.lircdata);
-+ wake_up(&ir_dev->raw->lirc.drv->rbuf->wait_poll);
-+
-+ ir_dev->raw->lirc.lircdata = 0;
-+
-+ return 0;
-+}
-+
-+static ssize_t ir_lirc_transmit_ir(struct file *file, const char *buf,
-+ size_t n, loff_t *ppos)
-+{
-+ struct lirc_codec *lirc;
-+ struct ir_input_dev *ir_dev;
-+ int *txbuf; /* buffer with values to transmit */
-+ int ret = 0, count;
-+
-+ lirc = lirc_get_pdata(file);
-+ if (!lirc)
-+ return -EFAULT;
-+
-+ if (n % sizeof(int))
-+ return -EINVAL;
-+
-+ count = n / sizeof(int);
-+ if (count > LIRCBUF_SIZE || count % 2 == 0)
-+ return -EINVAL;
-+
-+ txbuf = kzalloc(sizeof(int) * LIRCBUF_SIZE, GFP_KERNEL);
-+ if (!txbuf)
-+ return -ENOMEM;
-+
-+ if (copy_from_user(txbuf, buf, n)) {
-+ ret = -EFAULT;
-+ goto out;
-+ }
-+
-+ ir_dev = lirc->ir_dev;
-+ if (!ir_dev) {
-+ ret = -EFAULT;
-+ goto out;
-+ }
-+
-+ if (ir_dev->props && ir_dev->props->tx_ir)
-+ ret = ir_dev->props->tx_ir(ir_dev->props->priv, txbuf, (u32)n);
-+
-+out:
-+ kfree(txbuf);
-+ return ret;
-+}
-+
-+static long ir_lirc_ioctl(struct file *filep, unsigned int cmd, unsigned long arg)
-+{
-+ struct lirc_codec *lirc;
-+ struct ir_input_dev *ir_dev;
-+ int ret = 0;
-+ void *drv_data;
-+ unsigned long val;
-+
-+ lirc = lirc_get_pdata(filep);
-+ if (!lirc)
-+ return -EFAULT;
-+
-+ ir_dev = lirc->ir_dev;
-+ if (!ir_dev || !ir_dev->props || !ir_dev->props->priv)
-+ return -EFAULT;
-+
-+ drv_data = ir_dev->props->priv;
-+
-+ switch (cmd) {
-+ case LIRC_SET_TRANSMITTER_MASK:
-+ ret = get_user(val, (unsigned long *)arg);
-+ if (ret)
-+ return ret;
-+
-+ if (ir_dev->props && ir_dev->props->s_tx_mask)
-+ ret = ir_dev->props->s_tx_mask(drv_data, (u32)val);
-+ else
-+ return -EINVAL;
-+ break;
-+
-+ case LIRC_SET_SEND_CARRIER:
-+ ret = get_user(val, (unsigned long *)arg);
-+ if (ret)
-+ return ret;
-+
-+ if (ir_dev->props && ir_dev->props->s_tx_carrier)
-+ ir_dev->props->s_tx_carrier(drv_data, (u32)val);
-+ else
-+ return -EINVAL;
-+ break;
-+
-+ case LIRC_GET_SEND_MODE:
-+ val = LIRC_CAN_SEND_PULSE & LIRC_CAN_SEND_MASK;
-+ ret = put_user(val, (unsigned long *)arg);
-+ break;
-+
-+ case LIRC_SET_SEND_MODE:
-+ ret = get_user(val, (unsigned long *)arg);
-+ if (ret)
-+ return ret;
-+
-+ if (val != (LIRC_MODE_PULSE & LIRC_CAN_SEND_MASK))
-+ return -EINVAL;
-+ break;
-+
-+ default:
-+ return lirc_dev_fop_ioctl(filep, cmd, arg);
-+ }
-+
-+ return ret;
-+}
-+
-+static int ir_lirc_open(void *data)
-+{
-+ return 0;
-+}
-+
-+static void ir_lirc_close(void *data)
-+{
-+ return;
-+}
-+
-+static struct file_operations lirc_fops = {
-+ .owner = THIS_MODULE,
-+ .write = ir_lirc_transmit_ir,
-+ .unlocked_ioctl = ir_lirc_ioctl,
-+ .read = lirc_dev_fop_read,
-+ .poll = lirc_dev_fop_poll,
-+ .open = lirc_dev_fop_open,
-+ .release = lirc_dev_fop_close,
-+};
-+
-+static int ir_lirc_register(struct input_dev *input_dev)
-+{
-+ struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
-+ struct lirc_driver *drv;
-+ struct lirc_buffer *rbuf;
-+ int rc = -ENOMEM;
-+ unsigned long features;
-+
-+ drv = kzalloc(sizeof(struct lirc_driver), GFP_KERNEL);
-+ if (!drv)
-+ return rc;
-+
-+ rbuf = kzalloc(sizeof(struct lirc_buffer), GFP_KERNEL);
-+ if (!drv)
-+ goto rbuf_alloc_failed;
-+
-+ rc = lirc_buffer_init(rbuf, sizeof(int), LIRCBUF_SIZE);
-+ if (rc)
-+ goto rbuf_init_failed;
-+
-+ features = LIRC_CAN_REC_MODE2;
-+ if (ir_dev->props->tx_ir) {
-+ features |= LIRC_CAN_SEND_PULSE;
-+ if (ir_dev->props->s_tx_mask)
-+ features |= LIRC_CAN_SET_TRANSMITTER_MASK;
-+ if (ir_dev->props->s_tx_carrier)
-+ features |= LIRC_CAN_SET_SEND_CARRIER;
-+ }
-+
-+ snprintf(drv->name, sizeof(drv->name), "ir-lirc-codec (%s)",
-+ ir_dev->driver_name);
-+ drv->minor = -1;
-+ drv->features = features;
-+ drv->data = &ir_dev->raw->lirc;
-+ drv->rbuf = rbuf;
-+ drv->set_use_inc = &ir_lirc_open;
-+ drv->set_use_dec = &ir_lirc_close;
-+ drv->code_length = sizeof(struct ir_raw_event) * 8;
-+ drv->fops = &lirc_fops;
-+ drv->dev = &ir_dev->dev;
-+ drv->owner = THIS_MODULE;
-+
-+ drv->minor = lirc_register_driver(drv);
-+ if (drv->minor < 0) {
-+ rc = -ENODEV;
-+ goto lirc_register_failed;
-+ }
-+
-+ ir_dev->raw->lirc.drv = drv;
-+ ir_dev->raw->lirc.ir_dev = ir_dev;
-+ ir_dev->raw->lirc.lircdata = PULSE_MASK;
-+
-+ return 0;
-+
-+lirc_register_failed:
-+rbuf_init_failed:
-+ kfree(rbuf);
-+rbuf_alloc_failed:
-+ kfree(drv);
-+
-+ return rc;
-+}
-+
-+static int ir_lirc_unregister(struct input_dev *input_dev)
-+{
-+ struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
-+ struct lirc_codec *lirc = &ir_dev->raw->lirc;
-+
-+ lirc_unregister_driver(lirc->drv->minor);
-+ lirc_buffer_free(lirc->drv->rbuf);
-+ kfree(lirc->drv);
-+
-+ return 0;
-+}
-+
-+static struct ir_raw_handler lirc_handler = {
-+ .protocols = IR_TYPE_LIRC,
-+ .decode = ir_lirc_decode,
-+ .raw_register = ir_lirc_register,
-+ .raw_unregister = ir_lirc_unregister,
-+};
-+
-+static int __init ir_lirc_codec_init(void)
-+{
-+ ir_raw_handler_register(&lirc_handler);
-+
-+ printk(KERN_INFO "IR LIRC bridge handler initialized\n");
-+ return 0;
-+}
-+
-+static void __exit ir_lirc_codec_exit(void)
-+{
-+ ir_raw_handler_unregister(&lirc_handler);
-+}
-+
-+module_init(ir_lirc_codec_init);
-+module_exit(ir_lirc_codec_exit);
-+
-+MODULE_LICENSE("GPL");
-+MODULE_AUTHOR("Jarod Wilson <jarod@redhat.com>");
-+MODULE_AUTHOR("Red Hat Inc. (http://www.redhat.com)");
-+MODULE_DESCRIPTION("LIRC IR handler bridge");
-diff --git a/drivers/media/IR/ir-nec-decoder.c b/drivers/media/IR/ir-nec-decoder.c
-index ba79233..52e0f37 100644
---- a/drivers/media/IR/ir-nec-decoder.c
-+++ b/drivers/media/IR/ir-nec-decoder.c
-@@ -27,10 +27,6 @@
- #define NEC_TRAILER_PULSE (1 * NEC_UNIT)
- #define NEC_TRAILER_SPACE (10 * NEC_UNIT) /* even longer in reality */
-
--/* Used to register nec_decoder clients */
--static LIST_HEAD(decoder_list);
--static DEFINE_SPINLOCK(decoder_lock);
--
- enum nec_state {
- STATE_INACTIVE,
- STATE_HEADER_SPACE,
-@@ -40,84 +36,6 @@ enum nec_state {
- STATE_TRAILER_SPACE,
- };
-
--struct decoder_data {
-- struct list_head list;
-- struct ir_input_dev *ir_dev;
-- int enabled:1;
--
-- /* State machine control */
-- enum nec_state state;
-- u32 nec_bits;
-- unsigned count;
--};
--
--
--/**
-- * get_decoder_data() - gets decoder data
-- * @input_dev: input device
-- *
-- * Returns the struct decoder_data that corresponds to a device
-- */
--static struct decoder_data *get_decoder_data(struct ir_input_dev *ir_dev)
--{
-- struct decoder_data *data = NULL;
--
-- spin_lock(&decoder_lock);
-- list_for_each_entry(data, &decoder_list, list) {
-- if (data->ir_dev == ir_dev)
-- break;
-- }
-- spin_unlock(&decoder_lock);
-- return data;
--}
--
--static ssize_t store_enabled(struct device *d,
-- struct device_attribute *mattr,
-- const char *buf,
-- size_t len)
--{
-- unsigned long value;
-- struct ir_input_dev *ir_dev = dev_get_drvdata(d);
-- struct decoder_data *data = get_decoder_data(ir_dev);
--
-- if (!data)
-- return -EINVAL;
--
-- if (strict_strtoul(buf, 10, &value) || value > 1)
-- return -EINVAL;
--
-- data->enabled = value;
--
-- return len;
--}
--
--static ssize_t show_enabled(struct device *d,
-- struct device_attribute *mattr, char *buf)
--{
-- struct ir_input_dev *ir_dev = dev_get_drvdata(d);
-- struct decoder_data *data = get_decoder_data(ir_dev);
--
-- if (!data)
-- return -EINVAL;
--
-- if (data->enabled)
-- return sprintf(buf, "1\n");
-- else
-- return sprintf(buf, "0\n");
--}
--
--static DEVICE_ATTR(enabled, S_IRUGO | S_IWUSR, show_enabled, store_enabled);
--
--static struct attribute *decoder_attributes[] = {
-- &dev_attr_enabled.attr,
-- NULL
--};
--
--static struct attribute_group decoder_attribute_group = {
-- .name = "nec_decoder",
-- .attrs = decoder_attributes,
--};
--
- /**
- * ir_nec_decode() - Decode one NEC pulse or space
- * @input_dev: the struct input_dev descriptor of the device
-@@ -127,16 +45,12 @@ static struct attribute_group decoder_attribute_group = {
- */
- static int ir_nec_decode(struct input_dev *input_dev, struct ir_raw_event ev)
- {
-- struct decoder_data *data;
- struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
-+ struct nec_dec *data = &ir_dev->raw->nec;
- u32 scancode;
- u8 address, not_address, command, not_command;
-
-- data = get_decoder_data(ir_dev);
-- if (!data)
-- return -EINVAL;
--
-- if (!data->enabled)
-+ if (!(ir_dev->raw->enabled_protocols & IR_TYPE_NEC))
- return 0;
-
- if (IS_RESET(ev)) {
-@@ -191,9 +105,9 @@ static int ir_nec_decode(struct input_dev *input_dev, struct ir_raw_event ev)
- if (ev.pulse)
- break;
-
-- data->nec_bits <<= 1;
-+ data->bits <<= 1;
- if (eq_margin(ev.duration, NEC_BIT_1_SPACE, NEC_UNIT / 2))
-- data->nec_bits |= 1;
-+ data->bits |= 1;
- else if (!eq_margin(ev.duration, NEC_BIT_0_SPACE, NEC_UNIT / 2))
- break;
- data->count++;
-@@ -222,14 +136,14 @@ static int ir_nec_decode(struct input_dev *input_dev, struct ir_raw_event ev)
- if (!geq_margin(ev.duration, NEC_TRAILER_SPACE, NEC_UNIT / 2))
- break;
-
-- address = bitrev8((data->nec_bits >> 24) & 0xff);
-- not_address = bitrev8((data->nec_bits >> 16) & 0xff);
-- command = bitrev8((data->nec_bits >> 8) & 0xff);
-- not_command = bitrev8((data->nec_bits >> 0) & 0xff);
-+ address = bitrev8((data->bits >> 24) & 0xff);
-+ not_address = bitrev8((data->bits >> 16) & 0xff);
-+ command = bitrev8((data->bits >> 8) & 0xff);
-+ not_command = bitrev8((data->bits >> 0) & 0xff);
-
- if ((command ^ not_command) != 0xff) {
- IR_dprintk(1, "NEC checksum error: received 0x%08x\n",
-- data->nec_bits);
-+ data->bits);
- break;
- }
-
-@@ -256,54 +170,9 @@ static int ir_nec_decode(struct input_dev *input_dev, struct ir_raw_event ev)
- return -EINVAL;
- }
-
--static int ir_nec_register(struct input_dev *input_dev)
--{
-- struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
-- struct decoder_data *data;
-- int rc;
--
-- rc = sysfs_create_group(&ir_dev->dev.kobj, &decoder_attribute_group);
-- if (rc < 0)
-- return rc;
--
-- data = kzalloc(sizeof(*data), GFP_KERNEL);
-- if (!data) {
-- sysfs_remove_group(&ir_dev->dev.kobj, &decoder_attribute_group);
-- return -ENOMEM;
-- }
--
-- data->ir_dev = ir_dev;
-- data->enabled = 1;
--
-- spin_lock(&decoder_lock);
-- list_add_tail(&data->list, &decoder_list);
-- spin_unlock(&decoder_lock);
--
-- return 0;
--}
--
--static int ir_nec_unregister(struct input_dev *input_dev)
--{
-- struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
-- static struct decoder_data *data;
--
-- data = get_decoder_data(ir_dev);
-- if (!data)
-- return 0;
--
-- sysfs_remove_group(&ir_dev->dev.kobj, &decoder_attribute_group);
--
-- spin_lock(&decoder_lock);
-- list_del(&data->list);
-- spin_unlock(&decoder_lock);
--
-- return 0;
--}
--
- static struct ir_raw_handler nec_handler = {
-+ .protocols = IR_TYPE_NEC,
- .decode = ir_nec_decode,
-- .raw_register = ir_nec_register,
-- .raw_unregister = ir_nec_unregister,
- };
-
- static int __init ir_nec_decode_init(void)
-diff --git a/drivers/media/IR/ir-raw-event.c b/drivers/media/IR/ir-raw-event.c
-index ea68a3f..6f192ef 100644
---- a/drivers/media/IR/ir-raw-event.c
-+++ b/drivers/media/IR/ir-raw-event.c
-@@ -20,35 +20,13 @@
- /* Define the max number of pulse/space transitions to buffer */
- #define MAX_IR_EVENT_SIZE 512
-
-+/* Used to keep track of IR raw clients, protected by ir_raw_handler_lock */
-+static LIST_HEAD(ir_raw_client_list);
-+
- /* Used to handle IR raw handler extensions */
--static LIST_HEAD(ir_raw_handler_list);
- static DEFINE_SPINLOCK(ir_raw_handler_lock);
--
--/**
-- * RUN_DECODER() - runs an operation on all IR decoders
-- * @ops: IR raw handler operation to be called
-- * @arg: arguments to be passed to the callback
-- *
-- * Calls ir_raw_handler::ops for all registered IR handlers. It prevents
-- * new decode addition/removal while running, by locking ir_raw_handler_lock
-- * mutex. If an error occurs, it stops the ops. Otherwise, it returns a sum
-- * of the return codes.
-- */
--#define RUN_DECODER(ops, ...) ({ \
-- struct ir_raw_handler *_ir_raw_handler; \
-- int _sumrc = 0, _rc; \
-- spin_lock(&ir_raw_handler_lock); \
-- list_for_each_entry(_ir_raw_handler, &ir_raw_handler_list, list) { \
-- if (_ir_raw_handler->ops) { \
-- _rc = _ir_raw_handler->ops(__VA_ARGS__); \
-- if (_rc < 0) \
-- break; \
-- _sumrc += _rc; \
-- } \
-- } \
-- spin_unlock(&ir_raw_handler_lock); \
-- _sumrc; \
--})
-+static LIST_HEAD(ir_raw_handler_list);
-+static u64 available_protocols;
-
- #ifdef MODULE
- /* Used to load the decoders */
-@@ -58,57 +36,17 @@ static struct work_struct wq_load;
- static void ir_raw_event_work(struct work_struct *work)
- {
- struct ir_raw_event ev;
-+ struct ir_raw_handler *handler;
- struct ir_raw_event_ctrl *raw =
- container_of(work, struct ir_raw_event_ctrl, rx_work);
-
-- while (kfifo_out(&raw->kfifo, &ev, sizeof(ev)) == sizeof(ev))
-- RUN_DECODER(decode, raw->input_dev, ev);
--}
--
--int ir_raw_event_register(struct input_dev *input_dev)
--{
-- struct ir_input_dev *ir = input_get_drvdata(input_dev);
-- int rc;
--
-- ir->raw = kzalloc(sizeof(*ir->raw), GFP_KERNEL);
-- if (!ir->raw)
-- return -ENOMEM;
--
-- ir->raw->input_dev = input_dev;
-- INIT_WORK(&ir->raw->rx_work, ir_raw_event_work);
--
-- rc = kfifo_alloc(&ir->raw->kfifo, sizeof(s64) * MAX_IR_EVENT_SIZE,
-- GFP_KERNEL);
-- if (rc < 0) {
-- kfree(ir->raw);
-- ir->raw = NULL;
-- return rc;
-- }
--
-- rc = RUN_DECODER(raw_register, input_dev);
-- if (rc < 0) {
-- kfifo_free(&ir->raw->kfifo);
-- kfree(ir->raw);
-- ir->raw = NULL;
-- return rc;
-+ while (kfifo_out(&raw->kfifo, &ev, sizeof(ev)) == sizeof(ev)) {
-+ spin_lock(&ir_raw_handler_lock);
-+ list_for_each_entry(handler, &ir_raw_handler_list, list)
-+ handler->decode(raw->input_dev, ev);
-+ spin_unlock(&ir_raw_handler_lock);
-+ raw->prev_ev = ev;
- }
--
-- return rc;
--}
--
--void ir_raw_event_unregister(struct input_dev *input_dev)
--{
-- struct ir_input_dev *ir = input_get_drvdata(input_dev);
--
-- if (!ir->raw)
-- return;
--
-- cancel_work_sync(&ir->raw->rx_work);
-- RUN_DECODER(raw_unregister, input_dev);
--
-- kfifo_free(&ir->raw->kfifo);
-- kfree(ir->raw);
-- ir->raw = NULL;
- }
-
- /**
-@@ -204,23 +142,103 @@ void ir_raw_event_handle(struct input_dev *input_dev)
- }
- EXPORT_SYMBOL_GPL(ir_raw_event_handle);
-
-+/* used internally by the sysfs interface */
-+u64
-+ir_raw_get_allowed_protocols()
-+{
-+ u64 protocols;
-+ spin_lock(&ir_raw_handler_lock);
-+ protocols = available_protocols;
-+ spin_unlock(&ir_raw_handler_lock);
-+ return protocols;
-+}
-+
-+/*
-+ * Used to (un)register raw event clients
-+ */
-+int ir_raw_event_register(struct input_dev *input_dev)
-+{
-+ struct ir_input_dev *ir = input_get_drvdata(input_dev);
-+ int rc;
-+ struct ir_raw_handler *handler;
-+
-+ ir->raw = kzalloc(sizeof(*ir->raw), GFP_KERNEL);
-+ if (!ir->raw)
-+ return -ENOMEM;
-+
-+ ir->raw->input_dev = input_dev;
-+ INIT_WORK(&ir->raw->rx_work, ir_raw_event_work);
-+ ir->raw->enabled_protocols = ~0;
-+ rc = kfifo_alloc(&ir->raw->kfifo, sizeof(s64) * MAX_IR_EVENT_SIZE,
-+ GFP_KERNEL);
-+ if (rc < 0) {
-+ kfree(ir->raw);
-+ ir->raw = NULL;
-+ return rc;
-+ }
-+
-+ spin_lock(&ir_raw_handler_lock);
-+ list_add_tail(&ir->raw->list, &ir_raw_client_list);
-+ list_for_each_entry(handler, &ir_raw_handler_list, list)
-+ if (handler->raw_register)
-+ handler->raw_register(ir->raw->input_dev);
-+ spin_unlock(&ir_raw_handler_lock);
-+
-+ return 0;
-+}
-+
-+void ir_raw_event_unregister(struct input_dev *input_dev)
-+{
-+ struct ir_input_dev *ir = input_get_drvdata(input_dev);
-+ struct ir_raw_handler *handler;
-+
-+ if (!ir->raw)
-+ return;
-+
-+ cancel_work_sync(&ir->raw->rx_work);
-+
-+ spin_lock(&ir_raw_handler_lock);
-+ list_del(&ir->raw->list);
-+ list_for_each_entry(handler, &ir_raw_handler_list, list)
-+ if (handler->raw_unregister)
-+ handler->raw_unregister(ir->raw->input_dev);
-+ spin_unlock(&ir_raw_handler_lock);
-+
-+ kfifo_free(&ir->raw->kfifo);
-+ kfree(ir->raw);
-+ ir->raw = NULL;
-+}
-+
- /*
- * Extension interface - used to register the IR decoders
- */
-
- int ir_raw_handler_register(struct ir_raw_handler *ir_raw_handler)
- {
-+ struct ir_raw_event_ctrl *raw;
-+
- spin_lock(&ir_raw_handler_lock);
- list_add_tail(&ir_raw_handler->list, &ir_raw_handler_list);
-+ if (ir_raw_handler->raw_register)
-+ list_for_each_entry(raw, &ir_raw_client_list, list)
-+ ir_raw_handler->raw_register(raw->input_dev);
-+ available_protocols |= ir_raw_handler->protocols;
- spin_unlock(&ir_raw_handler_lock);
-+
- return 0;
- }
- EXPORT_SYMBOL(ir_raw_handler_register);
-
- void ir_raw_handler_unregister(struct ir_raw_handler *ir_raw_handler)
- {
-+ struct ir_raw_event_ctrl *raw;
-+
- spin_lock(&ir_raw_handler_lock);
- list_del(&ir_raw_handler->list);
-+ if (ir_raw_handler->raw_unregister)
-+ list_for_each_entry(raw, &ir_raw_client_list, list)
-+ ir_raw_handler->raw_unregister(raw->input_dev);
-+ available_protocols &= ~ir_raw_handler->protocols;
- spin_unlock(&ir_raw_handler_lock);
- }
- EXPORT_SYMBOL(ir_raw_handler_unregister);
-@@ -235,6 +253,7 @@ static void init_decoders(struct work_struct *work)
- load_rc6_decode();
- load_jvc_decode();
- load_sony_decode();
-+ load_lirc_codec();
-
- /* If needed, we may later add some init code. In this case,
- it is needed to change the CONFIG_MODULE test at ir-core.h
-diff --git a/drivers/media/IR/ir-rc5-decoder.c b/drivers/media/IR/ir-rc5-decoder.c
-index 23cdb1b..df4770d 100644
---- a/drivers/media/IR/ir-rc5-decoder.c
-+++ b/drivers/media/IR/ir-rc5-decoder.c
-@@ -30,10 +30,6 @@
- #define RC5_BIT_END (1 * RC5_UNIT)
- #define RC5X_SPACE (4 * RC5_UNIT)
-
--/* Used to register rc5_decoder clients */
--static LIST_HEAD(decoder_list);
--static DEFINE_SPINLOCK(decoder_lock);
--
- enum rc5_state {
- STATE_INACTIVE,
- STATE_BIT_START,
-@@ -42,87 +38,6 @@ enum rc5_state {
- STATE_FINISHED,
- };
-
--struct decoder_data {
-- struct list_head list;
-- struct ir_input_dev *ir_dev;
-- int enabled:1;
--
-- /* State machine control */
-- enum rc5_state state;
-- u32 rc5_bits;
-- struct ir_raw_event prev_ev;
-- unsigned count;
-- unsigned wanted_bits;
--};
--
--
--/**
-- * get_decoder_data() - gets decoder data
-- * @input_dev: input device
-- *
-- * Returns the struct decoder_data that corresponds to a device
-- */
--
--static struct decoder_data *get_decoder_data(struct ir_input_dev *ir_dev)
--{
-- struct decoder_data *data = NULL;
--
-- spin_lock(&decoder_lock);
-- list_for_each_entry(data, &decoder_list, list) {
-- if (data->ir_dev == ir_dev)
-- break;
-- }
-- spin_unlock(&decoder_lock);
-- return data;
--}
--
--static ssize_t store_enabled(struct device *d,
-- struct device_attribute *mattr,
-- const char *buf,
-- size_t len)
--{
-- unsigned long value;
-- struct ir_input_dev *ir_dev = dev_get_drvdata(d);
-- struct decoder_data *data = get_decoder_data(ir_dev);
--
-- if (!data)
-- return -EINVAL;
--
-- if (strict_strtoul(buf, 10, &value) || value > 1)
-- return -EINVAL;
--
-- data->enabled = value;
--
-- return len;
--}
--
--static ssize_t show_enabled(struct device *d,
-- struct device_attribute *mattr, char *buf)
--{
-- struct ir_input_dev *ir_dev = dev_get_drvdata(d);
-- struct decoder_data *data = get_decoder_data(ir_dev);
--
-- if (!data)
-- return -EINVAL;
--
-- if (data->enabled)
-- return sprintf(buf, "1\n");
-- else
-- return sprintf(buf, "0\n");
--}
--
--static DEVICE_ATTR(enabled, S_IRUGO | S_IWUSR, show_enabled, store_enabled);
--
--static struct attribute *decoder_attributes[] = {
-- &dev_attr_enabled.attr,
-- NULL
--};
--
--static struct attribute_group decoder_attribute_group = {
-- .name = "rc5_decoder",
-- .attrs = decoder_attributes,
--};
--
- /**
- * ir_rc5_decode() - Decode one RC-5 pulse or space
- * @input_dev: the struct input_dev descriptor of the device
-@@ -132,17 +47,13 @@ static struct attribute_group decoder_attribute_group = {
- */
- static int ir_rc5_decode(struct input_dev *input_dev, struct ir_raw_event ev)
- {
-- struct decoder_data *data;
- struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
-+ struct rc5_dec *data = &ir_dev->raw->rc5;
- u8 toggle;
- u32 scancode;
-
-- data = get_decoder_data(ir_dev);
-- if (!data)
-- return -EINVAL;
--
-- if (!data->enabled)
-- return 0;
-+ if (!(ir_dev->raw->enabled_protocols & IR_TYPE_RC5))
-+ return 0;
-
- if (IS_RESET(ev)) {
- data->state = STATE_INACTIVE;
-@@ -176,16 +87,15 @@ again:
- if (!eq_margin(ev.duration, RC5_BIT_START, RC5_UNIT / 2))
- break;
-
-- data->rc5_bits <<= 1;
-+ data->bits <<= 1;
- if (!ev.pulse)
-- data->rc5_bits |= 1;
-+ data->bits |= 1;
- data->count++;
-- data->prev_ev = ev;
- data->state = STATE_BIT_END;
- return 0;
-
- case STATE_BIT_END:
-- if (!is_transition(&ev, &data->prev_ev))
-+ if (!is_transition(&ev, &ir_dev->raw->prev_ev))
- break;
-
- if (data->count == data->wanted_bits)
-@@ -217,11 +127,11 @@ again:
- if (data->wanted_bits == RC5X_NBITS) {
- /* RC5X */
- u8 xdata, command, system;
-- xdata = (data->rc5_bits & 0x0003F) >> 0;
-- command = (data->rc5_bits & 0x00FC0) >> 6;
-- system = (data->rc5_bits & 0x1F000) >> 12;
-- toggle = (data->rc5_bits & 0x20000) ? 1 : 0;
-- command += (data->rc5_bits & 0x01000) ? 0 : 0x40;
-+ xdata = (data->bits & 0x0003F) >> 0;
-+ command = (data->bits & 0x00FC0) >> 6;
-+ system = (data->bits & 0x1F000) >> 12;
-+ toggle = (data->bits & 0x20000) ? 1 : 0;
-+ command += (data->bits & 0x01000) ? 0 : 0x40;
- scancode = system << 16 | command << 8 | xdata;
-
- IR_dprintk(1, "RC5X scancode 0x%06x (toggle: %u)\n",
-@@ -230,10 +140,10 @@ again:
- } else {
- /* RC5 */
- u8 command, system;
-- command = (data->rc5_bits & 0x0003F) >> 0;
-- system = (data->rc5_bits & 0x007C0) >> 6;
-- toggle = (data->rc5_bits & 0x00800) ? 1 : 0;
-- command += (data->rc5_bits & 0x01000) ? 0 : 0x40;
-+ command = (data->bits & 0x0003F) >> 0;
-+ system = (data->bits & 0x007C0) >> 6;
-+ toggle = (data->bits & 0x00800) ? 1 : 0;
-+ command += (data->bits & 0x01000) ? 0 : 0x40;
- scancode = system << 8 | command;
-
- IR_dprintk(1, "RC5 scancode 0x%04x (toggle: %u)\n",
-@@ -252,54 +162,9 @@ out:
- return -EINVAL;
- }
-
--static int ir_rc5_register(struct input_dev *input_dev)
--{
-- struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
-- struct decoder_data *data;
-- int rc;
--
-- rc = sysfs_create_group(&ir_dev->dev.kobj, &decoder_attribute_group);
-- if (rc < 0)
-- return rc;
--
-- data = kzalloc(sizeof(*data), GFP_KERNEL);
-- if (!data) {
-- sysfs_remove_group(&ir_dev->dev.kobj, &decoder_attribute_group);
-- return -ENOMEM;
-- }
--
-- data->ir_dev = ir_dev;
-- data->enabled = 1;
--
-- spin_lock(&decoder_lock);
-- list_add_tail(&data->list, &decoder_list);
-- spin_unlock(&decoder_lock);
--
-- return 0;
--}
--
--static int ir_rc5_unregister(struct input_dev *input_dev)
--{
-- struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
-- static struct decoder_data *data;
--
-- data = get_decoder_data(ir_dev);
-- if (!data)
-- return 0;
--
-- sysfs_remove_group(&ir_dev->dev.kobj, &decoder_attribute_group);
--
-- spin_lock(&decoder_lock);
-- list_del(&data->list);
-- spin_unlock(&decoder_lock);
--
-- return 0;
--}
--
- static struct ir_raw_handler rc5_handler = {
-+ .protocols = IR_TYPE_RC5,
- .decode = ir_rc5_decode,
-- .raw_register = ir_rc5_register,
-- .raw_unregister = ir_rc5_unregister,
- };
-
- static int __init ir_rc5_decode_init(void)
-diff --git a/drivers/media/IR/ir-rc6-decoder.c b/drivers/media/IR/ir-rc6-decoder.c
-index 2bf479f..f1624b8 100644
---- a/drivers/media/IR/ir-rc6-decoder.c
-+++ b/drivers/media/IR/ir-rc6-decoder.c
-@@ -36,10 +36,6 @@
- #define RC6_STARTBIT_MASK 0x08 /* for the header bits */
- #define RC6_6A_MCE_TOGGLE_MASK 0x8000 /* for the body bits */
-
--/* Used to register rc6_decoder clients */
--static LIST_HEAD(decoder_list);
--static DEFINE_SPINLOCK(decoder_lock);
--
- enum rc6_mode {
- RC6_MODE_0,
- RC6_MODE_6A,
-@@ -58,89 +54,8 @@ enum rc6_state {
- STATE_FINISHED,
- };
-
--struct decoder_data {
-- struct list_head list;
-- struct ir_input_dev *ir_dev;
-- int enabled:1;
--
-- /* State machine control */
-- enum rc6_state state;
-- u8 header;
-- u32 body;
-- struct ir_raw_event prev_ev;
-- bool toggle;
-- unsigned count;
-- unsigned wanted_bits;
--};
--
--
--/**
-- * get_decoder_data() - gets decoder data
-- * @input_dev: input device
-- *
-- * Returns the struct decoder_data that corresponds to a device
-- */
--static struct decoder_data *get_decoder_data(struct ir_input_dev *ir_dev)
--{
-- struct decoder_data *data = NULL;
--
-- spin_lock(&decoder_lock);
-- list_for_each_entry(data, &decoder_list, list) {
-- if (data->ir_dev == ir_dev)
-- break;
-- }
-- spin_unlock(&decoder_lock);
-- return data;
--}
--
--static ssize_t store_enabled(struct device *d,
-- struct device_attribute *mattr,
-- const char *buf,
-- size_t len)
-+static enum rc6_mode rc6_mode(struct rc6_dec *data)
- {
-- unsigned long value;
-- struct ir_input_dev *ir_dev = dev_get_drvdata(d);
-- struct decoder_data *data = get_decoder_data(ir_dev);
--
-- if (!data)
-- return -EINVAL;
--
-- if (strict_strtoul(buf, 10, &value) || value > 1)
-- return -EINVAL;
--
-- data->enabled = value;
--
-- return len;
--}
--
--static ssize_t show_enabled(struct device *d,
-- struct device_attribute *mattr, char *buf)
--{
-- struct ir_input_dev *ir_dev = dev_get_drvdata(d);
-- struct decoder_data *data = get_decoder_data(ir_dev);
--
-- if (!data)
-- return -EINVAL;
--
-- if (data->enabled)
-- return sprintf(buf, "1\n");
-- else
-- return sprintf(buf, "0\n");
--}
--
--static DEVICE_ATTR(enabled, S_IRUGO | S_IWUSR, show_enabled, store_enabled);
--
--static struct attribute *decoder_attributes[] = {
-- &dev_attr_enabled.attr,
-- NULL
--};
--
--static struct attribute_group decoder_attribute_group = {
-- .name = "rc6_decoder",
-- .attrs = decoder_attributes,
--};
--
--static enum rc6_mode rc6_mode(struct decoder_data *data) {
- switch (data->header & RC6_MODE_MASK) {
- case 0:
- return RC6_MODE_0;
-@@ -162,16 +77,12 @@ static enum rc6_mode rc6_mode(struct decoder_data *data) {
- */
- static int ir_rc6_decode(struct input_dev *input_dev, struct ir_raw_event ev)
- {
-- struct decoder_data *data;
- struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
-+ struct rc6_dec *data = &ir_dev->raw->rc6;
- u32 scancode;
- u8 toggle;
-
-- data = get_decoder_data(ir_dev);
-- if (!data)
-- return -EINVAL;
--
-- if (!data->enabled)
-+ if (!(ir_dev->raw->enabled_protocols & IR_TYPE_RC6))
- return 0;
-
- if (IS_RESET(ev)) {
-@@ -223,12 +134,11 @@ again:
- if (ev.pulse)
- data->header |= 1;
- data->count++;
-- data->prev_ev = ev;
- data->state = STATE_HEADER_BIT_END;
- return 0;
-
- case STATE_HEADER_BIT_END:
-- if (!is_transition(&ev, &data->prev_ev))
-+ if (!is_transition(&ev, &ir_dev->raw->prev_ev))
- break;
-
- if (data->count == RC6_HEADER_NBITS)
-@@ -244,12 +154,11 @@ again:
- break;
-
- data->toggle = ev.pulse;
-- data->prev_ev = ev;
- data->state = STATE_TOGGLE_END;
- return 0;
-
- case STATE_TOGGLE_END:
-- if (!is_transition(&ev, &data->prev_ev) ||
-+ if (!is_transition(&ev, &ir_dev->raw->prev_ev) ||
- !geq_margin(ev.duration, RC6_TOGGLE_END, RC6_UNIT / 2))
- break;
-
-@@ -259,7 +168,6 @@ again:
- }
-
- data->state = STATE_BODY_BIT_START;
-- data->prev_ev = ev;
- decrease_duration(&ev, RC6_TOGGLE_END);
- data->count = 0;
-
-@@ -291,13 +199,11 @@ again:
- if (ev.pulse)
- data->body |= 1;
- data->count++;
-- data->prev_ev = ev;
--
- data->state = STATE_BODY_BIT_END;
- return 0;
-
- case STATE_BODY_BIT_END:
-- if (!is_transition(&ev, &data->prev_ev))
-+ if (!is_transition(&ev, &ir_dev->raw->prev_ev))
- break;
-
- if (data->count == data->wanted_bits)
-@@ -348,54 +254,9 @@ out:
- return -EINVAL;
- }
-
--static int ir_rc6_register(struct input_dev *input_dev)
--{
-- struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
-- struct decoder_data *data;
-- int rc;
--
-- rc = sysfs_create_group(&ir_dev->dev.kobj, &decoder_attribute_group);
-- if (rc < 0)
-- return rc;
--
-- data = kzalloc(sizeof(*data), GFP_KERNEL);
-- if (!data) {
-- sysfs_remove_group(&ir_dev->dev.kobj, &decoder_attribute_group);
-- return -ENOMEM;
-- }
--
-- data->ir_dev = ir_dev;
-- data->enabled = 1;
--
-- spin_lock(&decoder_lock);
-- list_add_tail(&data->list, &decoder_list);
-- spin_unlock(&decoder_lock);
--
-- return 0;
--}
--
--static int ir_rc6_unregister(struct input_dev *input_dev)
--{
-- struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
-- static struct decoder_data *data;
--
-- data = get_decoder_data(ir_dev);
-- if (!data)
-- return 0;
--
-- sysfs_remove_group(&ir_dev->dev.kobj, &decoder_attribute_group);
--
-- spin_lock(&decoder_lock);
-- list_del(&data->list);
-- spin_unlock(&decoder_lock);
--
-- return 0;
--}
--
- static struct ir_raw_handler rc6_handler = {
-+ .protocols = IR_TYPE_RC6,
- .decode = ir_rc6_decode,
-- .raw_register = ir_rc6_register,
-- .raw_unregister = ir_rc6_unregister,
- };
-
- static int __init ir_rc6_decode_init(void)
-diff --git a/drivers/media/IR/ir-sony-decoder.c b/drivers/media/IR/ir-sony-decoder.c
-index 9f440c5..b9074f0 100644
---- a/drivers/media/IR/ir-sony-decoder.c
-+++ b/drivers/media/IR/ir-sony-decoder.c
-@@ -23,10 +23,6 @@
- #define SONY_BIT_SPACE (1 * SONY_UNIT)
- #define SONY_TRAILER_SPACE (10 * SONY_UNIT) /* minimum */
-
--/* Used to register sony_decoder clients */
--static LIST_HEAD(decoder_list);
--static DEFINE_SPINLOCK(decoder_lock);
--
- enum sony_state {
- STATE_INACTIVE,
- STATE_HEADER_SPACE,
-@@ -35,84 +31,6 @@ enum sony_state {
- STATE_FINISHED,
- };
-
--struct decoder_data {
-- struct list_head list;
-- struct ir_input_dev *ir_dev;
-- int enabled:1;
--
-- /* State machine control */
-- enum sony_state state;
-- u32 sony_bits;
-- unsigned count;
--};
--
--
--/**
-- * get_decoder_data() - gets decoder data
-- * @input_dev: input device
-- *
-- * Returns the struct decoder_data that corresponds to a device
-- */
--static struct decoder_data *get_decoder_data(struct ir_input_dev *ir_dev)
--{
-- struct decoder_data *data = NULL;
--
-- spin_lock(&decoder_lock);
-- list_for_each_entry(data, &decoder_list, list) {
-- if (data->ir_dev == ir_dev)
-- break;
-- }
-- spin_unlock(&decoder_lock);
-- return data;
--}
--
--static ssize_t store_enabled(struct device *d,
-- struct device_attribute *mattr,
-- const char *buf,
-- size_t len)
--{
-- unsigned long value;
-- struct ir_input_dev *ir_dev = dev_get_drvdata(d);
-- struct decoder_data *data = get_decoder_data(ir_dev);
--
-- if (!data)
-- return -EINVAL;
--
-- if (strict_strtoul(buf, 10, &value) || value > 1)
-- return -EINVAL;
--
-- data->enabled = value;
--
-- return len;
--}
--
--static ssize_t show_enabled(struct device *d,
-- struct device_attribute *mattr, char *buf)
--{
-- struct ir_input_dev *ir_dev = dev_get_drvdata(d);
-- struct decoder_data *data = get_decoder_data(ir_dev);
--
-- if (!data)
-- return -EINVAL;
--
-- if (data->enabled)
-- return sprintf(buf, "1\n");
-- else
-- return sprintf(buf, "0\n");
--}
--
--static DEVICE_ATTR(enabled, S_IRUGO | S_IWUSR, show_enabled, store_enabled);
--
--static struct attribute *decoder_attributes[] = {
-- &dev_attr_enabled.attr,
-- NULL
--};
--
--static struct attribute_group decoder_attribute_group = {
-- .name = "sony_decoder",
-- .attrs = decoder_attributes,
--};
--
- /**
- * ir_sony_decode() - Decode one Sony pulse or space
- * @input_dev: the struct input_dev descriptor of the device
-@@ -122,16 +40,12 @@ static struct attribute_group decoder_attribute_group = {
- */
- static int ir_sony_decode(struct input_dev *input_dev, struct ir_raw_event ev)
- {
-- struct decoder_data *data;
- struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
-+ struct sony_dec *data = &ir_dev->raw->sony;
- u32 scancode;
- u8 device, subdevice, function;
-
-- data = get_decoder_data(ir_dev);
-- if (!data)
-- return -EINVAL;
--
-- if (!data->enabled)
-+ if (!(ir_dev->raw->enabled_protocols & IR_TYPE_SONY))
- return 0;
-
- if (IS_RESET(ev)) {
-@@ -172,9 +86,9 @@ static int ir_sony_decode(struct input_dev *input_dev, struct ir_raw_event ev)
- if (!ev.pulse)
- break;
-
-- data->sony_bits <<= 1;
-+ data->bits <<= 1;
- if (eq_margin(ev.duration, SONY_BIT_1_PULSE, SONY_UNIT / 2))
-- data->sony_bits |= 1;
-+ data->bits |= 1;
- else if (!eq_margin(ev.duration, SONY_BIT_0_PULSE, SONY_UNIT / 2))
- break;
-
-@@ -208,19 +122,19 @@ static int ir_sony_decode(struct input_dev *input_dev, struct ir_raw_event ev)
-
- switch (data->count) {
- case 12:
-- device = bitrev8((data->sony_bits << 3) & 0xF8);
-+ device = bitrev8((data->bits << 3) & 0xF8);
- subdevice = 0;
-- function = bitrev8((data->sony_bits >> 4) & 0xFE);
-+ function = bitrev8((data->bits >> 4) & 0xFE);
- break;
- case 15:
-- device = bitrev8((data->sony_bits >> 0) & 0xFF);
-+ device = bitrev8((data->bits >> 0) & 0xFF);
- subdevice = 0;
-- function = bitrev8((data->sony_bits >> 7) & 0xFD);
-+ function = bitrev8((data->bits >> 7) & 0xFD);
- break;
- case 20:
-- device = bitrev8((data->sony_bits >> 5) & 0xF8);
-- subdevice = bitrev8((data->sony_bits >> 0) & 0xFF);
-- function = bitrev8((data->sony_bits >> 12) & 0xFE);
-+ device = bitrev8((data->bits >> 5) & 0xF8);
-+ subdevice = bitrev8((data->bits >> 0) & 0xFF);
-+ function = bitrev8((data->bits >> 12) & 0xFE);
- break;
- default:
- IR_dprintk(1, "Sony invalid bitcount %u\n", data->count);
-@@ -241,54 +155,9 @@ out:
- return -EINVAL;
- }
-
--static int ir_sony_register(struct input_dev *input_dev)
--{
-- struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
-- struct decoder_data *data;
-- int rc;
--
-- rc = sysfs_create_group(&ir_dev->dev.kobj, &decoder_attribute_group);
-- if (rc < 0)
-- return rc;
--
-- data = kzalloc(sizeof(*data), GFP_KERNEL);
-- if (!data) {
-- sysfs_remove_group(&ir_dev->dev.kobj, &decoder_attribute_group);
-- return -ENOMEM;
-- }
--
-- data->ir_dev = ir_dev;
-- data->enabled = 1;
--
-- spin_lock(&decoder_lock);
-- list_add_tail(&data->list, &decoder_list);
-- spin_unlock(&decoder_lock);
--
-- return 0;
--}
--
--static int ir_sony_unregister(struct input_dev *input_dev)
--{
-- struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
-- static struct decoder_data *data;
--
-- data = get_decoder_data(ir_dev);
-- if (!data)
-- return 0;
--
-- sysfs_remove_group(&ir_dev->dev.kobj, &decoder_attribute_group);
--
-- spin_lock(&decoder_lock);
-- list_del(&data->list);
-- spin_unlock(&decoder_lock);
--
-- return 0;
--}
--
- static struct ir_raw_handler sony_handler = {
-+ .protocols = IR_TYPE_SONY,
- .decode = ir_sony_decode,
-- .raw_register = ir_sony_register,
-- .raw_unregister = ir_sony_unregister,
- };
-
- static int __init ir_sony_decode_init(void)
-diff --git a/drivers/media/IR/ir-sysfs.c b/drivers/media/IR/ir-sysfs.c
-index 2098dd1..a841e51 100644
---- a/drivers/media/IR/ir-sysfs.c
-+++ b/drivers/media/IR/ir-sysfs.c
-@@ -34,122 +34,186 @@ static struct class ir_input_class = {
- };
-
- /**
-- * show_protocol() - shows the current IR protocol
-+ * show_protocols() - shows the current IR protocol(s)
- * @d: 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.
-- * it is trigged by reading /sys/class/rc/rc?/current_protocol.
-- * It returns the protocol name, as understood by the driver.
-+ * 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 returns the protocol names of supported protocols.
-+ * Enabled protocols are printed in brackets.
- */
--static ssize_t show_protocol(struct device *d,
-- struct device_attribute *mattr, char *buf)
-+static ssize_t show_protocols(struct device *d,
-+ struct device_attribute *mattr, char *buf)
- {
-- char *s;
- struct ir_input_dev *ir_dev = dev_get_drvdata(d);
-- u64 ir_type = ir_dev->rc_tab.ir_type;
--
-- IR_dprintk(1, "Current protocol is %lld\n", (long long)ir_type);
--
-- /* FIXME: doesn't support multiple protocols at the same time */
-- if (ir_type == IR_TYPE_UNKNOWN)
-- s = "Unknown";
-- else if (ir_type == IR_TYPE_RC5)
-- s = "rc-5";
-- else if (ir_type == IR_TYPE_NEC)
-- s = "nec";
-- else if (ir_type == IR_TYPE_RC6)
-- s = "rc6";
-- else if (ir_type == IR_TYPE_JVC)
-- s = "jvc";
-- else if (ir_type == IR_TYPE_SONY)
-- s = "sony";
-- else
-- s = "other";
-+ u64 allowed, enabled;
-+ char *tmp = buf;
-+
-+ if (ir_dev->props->driver_type == RC_DRIVER_SCANCODE) {
-+ enabled = ir_dev->rc_tab.ir_type;
-+ allowed = ir_dev->props->allowed_protos;
-+ } else {
-+ enabled = ir_dev->raw->enabled_protocols;
-+ allowed = ir_raw_get_allowed_protocols();
-+ }
-
-- return sprintf(buf, "%s\n", s);
-+ IR_dprintk(1, "allowed - 0x%llx, enabled - 0x%llx\n",
-+ (long long)allowed,
-+ (long long)enabled);
-+
-+ if (allowed & enabled & IR_TYPE_UNKNOWN)
-+ tmp += sprintf(tmp, "[unknown] ");
-+ else if (allowed & IR_TYPE_UNKNOWN)
-+ tmp += sprintf(tmp, "unknown ");
-+
-+ if (allowed & enabled & IR_TYPE_RC5)
-+ tmp += sprintf(tmp, "[rc5] ");
-+ else if (allowed & IR_TYPE_RC5)
-+ tmp += sprintf(tmp, "rc5 ");
-+
-+ if (allowed & enabled & IR_TYPE_NEC)
-+ tmp += sprintf(tmp, "[nec] ");
-+ else if (allowed & IR_TYPE_NEC)
-+ tmp += sprintf(tmp, "nec ");
-+
-+ if (allowed & enabled & IR_TYPE_RC6)
-+ tmp += sprintf(tmp, "[rc6] ");
-+ else if (allowed & IR_TYPE_RC6)
-+ tmp += sprintf(tmp, "rc6 ");
-+
-+ if (allowed & enabled & IR_TYPE_JVC)
-+ tmp += sprintf(tmp, "[jvc] ");
-+ else if (allowed & IR_TYPE_JVC)
-+ tmp += sprintf(tmp, "jvc ");
-+
-+ if (allowed & enabled & IR_TYPE_SONY)
-+ tmp += sprintf(tmp, "[sony] ");
-+ else if (allowed & IR_TYPE_SONY)
-+ tmp += sprintf(tmp, "sony ");
-+
-+ if (allowed & enabled & IR_TYPE_LIRC)
-+ tmp += sprintf(tmp, "[lirc] ");
-+ else if (allowed & IR_TYPE_LIRC)
-+ tmp += sprintf(tmp, "lirc ");
-+
-+ if (tmp != buf)
-+ tmp--;
-+ *tmp = '\n';
-+ return tmp + 1 - buf;
- }
-
- /**
-- * store_protocol() - shows the current IR protocol
-+ * store_protocols() - changes the current IR protocol(s)
- * @d: 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 a callback routine for changing the IR protocol type.
-- * it is trigged by reading /sys/class/rc/rc?/current_protocol.
-- * It changes the IR the protocol name, if the IR type is recognized
-- * by the driver.
-- * If an unknown protocol name is used, returns -EINVAL.
-+ * It is trigged by writing to /sys/class/rc/rc?/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".
-+ * Returns -EINVAL if an invalid protocol combination or unknown protocol name
-+ * is used, otherwise @len.
- */
--static ssize_t store_protocol(struct device *d,
-- struct device_attribute *mattr,
-- const char *data,
-- size_t len)
-+static ssize_t store_protocols(struct device *d,
-+ struct device_attribute *mattr,
-+ const char *data,
-+ size_t len)
- {
- struct ir_input_dev *ir_dev = dev_get_drvdata(d);
-- u64 ir_type = 0;
-- int rc = -EINVAL;
-+ bool enable, disable;
-+ const char *tmp;
-+ u64 type;
-+ u64 mask;
-+ int rc;
- unsigned long flags;
-- char *buf;
--
-- while ((buf = strsep((char **) &data, " \n")) != NULL) {
-- if (!strcasecmp(buf, "rc-5") || !strcasecmp(buf, "rc5"))
-- ir_type |= IR_TYPE_RC5;
-- if (!strcasecmp(buf, "nec"))
-- ir_type |= IR_TYPE_NEC;
-- if (!strcasecmp(buf, "jvc"))
-- ir_type |= IR_TYPE_JVC;
-- if (!strcasecmp(buf, "sony"))
-- ir_type |= IR_TYPE_SONY;
-+
-+ tmp = skip_spaces(data);
-+
-+ if (*tmp == '+') {
-+ enable = true;
-+ disable = false;
-+ tmp++;
-+ } else if (*tmp == '-') {
-+ enable = false;
-+ disable = true;
-+ tmp++;
-+ } else {
-+ enable = false;
-+ disable = false;
- }
-
-- if (!ir_type) {
-+ if (!strncasecmp(tmp, "unknown", 7)) {
-+ tmp += 7;
-+ mask = IR_TYPE_UNKNOWN;
-+ } else if (!strncasecmp(tmp, "rc5", 3)) {
-+ tmp += 3;
-+ mask = IR_TYPE_RC5;
-+ } else if (!strncasecmp(tmp, "nec", 3)) {
-+ tmp += 3;
-+ mask = IR_TYPE_NEC;
-+ } else if (!strncasecmp(tmp, "rc6", 3)) {
-+ tmp += 3;
-+ mask = IR_TYPE_RC6;
-+ } else if (!strncasecmp(tmp, "jvc", 3)) {
-+ tmp += 3;
-+ mask = IR_TYPE_JVC;
-+ } else if (!strncasecmp(tmp, "sony", 4)) {
-+ tmp += 4;
-+ mask = IR_TYPE_SONY;
-+ } else if (!strncasecmp(tmp, "lirc", 4)) {
-+ tmp += 4;
-+ mask = IR_TYPE_LIRC;
-+ } else {
- IR_dprintk(1, "Unknown protocol\n");
- return -EINVAL;
- }
-
-- if (ir_dev->props && ir_dev->props->change_protocol)
-- rc = ir_dev->props->change_protocol(ir_dev->props->priv,
-- ir_type);
--
-- if (rc < 0) {
-- IR_dprintk(1, "Error setting protocol to %lld\n",
-- (long long)ir_type);
-+ tmp = skip_spaces(tmp);
-+ if (*tmp != '\0') {
-+ IR_dprintk(1, "Invalid trailing characters\n");
- return -EINVAL;
- }
-
-- spin_lock_irqsave(&ir_dev->rc_tab.lock, flags);
-- ir_dev->rc_tab.ir_type = ir_type;
-- spin_unlock_irqrestore(&ir_dev->rc_tab.lock, flags);
-+ if (ir_dev->props->driver_type == RC_DRIVER_SCANCODE)
-+ type = ir_dev->rc_tab.ir_type;
-+ else
-+ type = ir_dev->raw->enabled_protocols;
-
-- IR_dprintk(1, "Current protocol(s) is(are) %lld\n",
-- (long long)ir_type);
-+ if (enable)
-+ type |= mask;
-+ else if (disable)
-+ type &= ~mask;
-+ else
-+ type = mask;
-
-- return len;
--}
-+ if (ir_dev->props && ir_dev->props->change_protocol) {
-+ rc = ir_dev->props->change_protocol(ir_dev->props->priv,
-+ type);
-+ if (rc < 0) {
-+ IR_dprintk(1, "Error setting protocols to 0x%llx\n",
-+ (long long)type);
-+ return -EINVAL;
-+ }
-+ }
-
--static ssize_t show_supported_protocols(struct device *d,
-- struct device_attribute *mattr, char *buf)
--{
-- char *orgbuf = buf;
-- struct ir_input_dev *ir_dev = dev_get_drvdata(d);
-+ if (ir_dev->props->driver_type == RC_DRIVER_SCANCODE) {
-+ spin_lock_irqsave(&ir_dev->rc_tab.lock, flags);
-+ ir_dev->rc_tab.ir_type = type;
-+ spin_unlock_irqrestore(&ir_dev->rc_tab.lock, flags);
-+ } else {
-+ ir_dev->raw->enabled_protocols = type;
-+ }
-
-- /* FIXME: doesn't support multiple protocols at the same time */
-- if (ir_dev->props->allowed_protos == IR_TYPE_UNKNOWN)
-- buf += sprintf(buf, "unknown ");
-- if (ir_dev->props->allowed_protos & IR_TYPE_RC5)
-- buf += sprintf(buf, "rc-5 ");
-- if (ir_dev->props->allowed_protos & IR_TYPE_NEC)
-- buf += sprintf(buf, "nec ");
-- if (buf == orgbuf)
-- buf += sprintf(buf, "other ");
-
-- buf += sprintf(buf - 1, "\n");
-+ IR_dprintk(1, "Current protocol(s): 0x%llx\n",
-+ (long long)type);
-
-- return buf - orgbuf;
-+ return len;
- }
-
- #define ADD_HOTPLUG_VAR(fmt, val...) \
-@@ -159,7 +223,7 @@ static ssize_t show_supported_protocols(struct device *d,
- return err; \
- } while (0)
-
--static int ir_dev_uevent(struct device *device, struct kobj_uevent_env *env)
-+static int rc_dev_uevent(struct device *device, struct kobj_uevent_env *env)
- {
- struct ir_input_dev *ir_dev = dev_get_drvdata(device);
-
-@@ -174,34 +238,26 @@ static int ir_dev_uevent(struct device *device, struct kobj_uevent_env *env)
- /*
- * Static device attribute struct with the sysfs attributes for IR's
- */
--static DEVICE_ATTR(protocol, S_IRUGO | S_IWUSR,
-- show_protocol, store_protocol);
--
--static DEVICE_ATTR(supported_protocols, S_IRUGO | S_IWUSR,
-- show_supported_protocols, NULL);
-+static DEVICE_ATTR(protocols, S_IRUGO | S_IWUSR,
-+ show_protocols, store_protocols);
-
--static struct attribute *ir_hw_dev_attrs[] = {
-- &dev_attr_protocol.attr,
-- &dev_attr_supported_protocols.attr,
-+static struct attribute *rc_dev_attrs[] = {
-+ &dev_attr_protocols.attr,
- NULL,
- };
-
--static struct attribute_group ir_hw_dev_attr_grp = {
-- .attrs = ir_hw_dev_attrs,
-+static struct attribute_group rc_dev_attr_grp = {
-+ .attrs = rc_dev_attrs,
- };
-
--static const struct attribute_group *ir_hw_dev_attr_groups[] = {
-- &ir_hw_dev_attr_grp,
-+static const struct attribute_group *rc_dev_attr_groups[] = {
-+ &rc_dev_attr_grp,
- NULL
- };
-
- static struct device_type rc_dev_type = {
-- .groups = ir_hw_dev_attr_groups,
-- .uevent = ir_dev_uevent,
--};
--
--static struct device_type ir_raw_dev_type = {
-- .uevent = ir_dev_uevent,
-+ .groups = rc_dev_attr_groups,
-+ .uevent = rc_dev_uevent,
- };
-
- /**
-@@ -221,12 +277,7 @@ int ir_register_class(struct input_dev *input_dev)
- if (unlikely(devno < 0))
- return devno;
-
-- if (ir_dev->props) {
-- if (ir_dev->props->driver_type == RC_DRIVER_SCANCODE)
-- ir_dev->dev.type = &rc_dev_type;
-- } else
-- ir_dev->dev.type = &ir_raw_dev_type;
--
-+ ir_dev->dev.type = &rc_dev_type;
- ir_dev->dev.class = &ir_input_class;
- ir_dev->dev.parent = input_dev->dev.parent;
- dev_set_name(&ir_dev->dev, "rc%d", devno);
-diff --git a/drivers/media/IR/keymaps/Makefile b/drivers/media/IR/keymaps/Makefile
-index aea649f..86d3d1f 100644
---- a/drivers/media/IR/keymaps/Makefile
-+++ b/drivers/media/IR/keymaps/Makefile
-@@ -37,6 +37,7 @@ obj-$(CONFIG_RC_MAP) += rc-adstech-dvb-t-pci.o \
- rc-kaiomy.o \
- rc-kworld-315u.o \
- rc-kworld-plus-tv-analog.o \
-+ rc-lirc.o \
- rc-manli.o \
- rc-msi-tvanywhere.o \
- rc-msi-tvanywhere-plus.o \
-@@ -57,6 +58,7 @@ obj-$(CONFIG_RC_MAP) += rc-adstech-dvb-t-pci.o \
- rc-pv951.o \
- rc-rc5-hauppauge-new.o \
- rc-rc5-tv.o \
-+ rc-rc6-mce.o \
- rc-real-audio-220-32-keys.o \
- rc-tbs-nec.o \
- rc-terratec-cinergy-xs.o \
-diff --git a/drivers/media/IR/keymaps/rc-lirc.c b/drivers/media/IR/keymaps/rc-lirc.c
-new file mode 100644
-index 0000000..43fcf90
---- /dev/null
-+++ b/drivers/media/IR/keymaps/rc-lirc.c
-@@ -0,0 +1,41 @@
-+/* rc-lirc.c - Empty dummy keytable, for use when its preferred to pass
-+ * all raw IR data to the lirc userspace decoder.
-+ *
-+ * Copyright (c) 2010 by Jarod Wilson <jarod@redhat.com>
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ */
-+
-+#include <media/ir-core.h>
-+
-+static struct ir_scancode lirc[] = {
-+ { },
-+};
-+
-+static struct rc_keymap lirc_map = {
-+ .map = {
-+ .scan = lirc,
-+ .size = ARRAY_SIZE(lirc),
-+ .ir_type = IR_TYPE_LIRC,
-+ .name = RC_MAP_LIRC,
-+ }
-+};
-+
-+static int __init init_rc_map_lirc(void)
-+{
-+ return ir_register_map(&lirc_map);
-+}
-+
-+static void __exit exit_rc_map_lirc(void)
-+{
-+ ir_unregister_map(&lirc_map);
-+}
-+
-+module_init(init_rc_map_lirc)
-+module_exit(exit_rc_map_lirc)
-+
-+MODULE_LICENSE("GPL");
-+MODULE_AUTHOR("Jarod Wilson <jarod@redhat.com>");
-diff --git a/drivers/media/IR/keymaps/rc-rc6-mce.c b/drivers/media/IR/keymaps/rc-rc6-mce.c
-new file mode 100644
-index 0000000..c6726a8
---- /dev/null
-+++ b/drivers/media/IR/keymaps/rc-rc6-mce.c
-@@ -0,0 +1,105 @@
-+/* rc-rc6-mce.c - Keytable for Windows Media Center RC-6 remotes for use
-+ * with the Media Center Edition eHome Infrared Transceiver.
-+ *
-+ * Copyright (c) 2010 by Jarod Wilson <jarod@redhat.com>
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ */
-+
-+#include <media/rc-map.h>
-+
-+static struct ir_scancode rc6_mce[] = {
-+ { 0x800f0415, KEY_REWIND },
-+ { 0x800f0414, KEY_FASTFORWARD },
-+ { 0x800f041b, KEY_PREVIOUS },
-+ { 0x800f041a, KEY_NEXT },
-+
-+ { 0x800f0416, KEY_PLAY },
-+ { 0x800f0418, KEY_PAUSE },
-+ { 0x800f0419, KEY_STOP },
-+ { 0x800f0417, KEY_RECORD },
-+
-+ { 0x800f041e, KEY_UP },
-+ { 0x800f041f, KEY_DOWN },
-+ { 0x800f0420, KEY_LEFT },
-+ { 0x800f0421, KEY_RIGHT },
-+
-+ { 0x800f040b, KEY_ENTER },
-+ { 0x800f0422, KEY_OK },
-+ { 0x800f0423, KEY_EXIT },
-+ { 0x800f040a, KEY_DELETE },
-+
-+ { 0x800f040e, KEY_MUTE },
-+ { 0x800f0410, KEY_VOLUMEUP },
-+ { 0x800f0411, KEY_VOLUMEDOWN },
-+ { 0x800f0412, KEY_CHANNELUP },
-+ { 0x800f0413, KEY_CHANNELDOWN },
-+
-+ { 0x800f0401, KEY_NUMERIC_1 },
-+ { 0x800f0402, KEY_NUMERIC_2 },
-+ { 0x800f0403, KEY_NUMERIC_3 },
-+ { 0x800f0404, KEY_NUMERIC_4 },
-+ { 0x800f0405, KEY_NUMERIC_5 },
-+ { 0x800f0406, KEY_NUMERIC_6 },
-+ { 0x800f0407, KEY_NUMERIC_7 },
-+ { 0x800f0408, KEY_NUMERIC_8 },
-+ { 0x800f0409, KEY_NUMERIC_9 },
-+ { 0x800f0400, KEY_NUMERIC_0 },
-+
-+ { 0x800f041d, KEY_NUMERIC_STAR },
-+ { 0x800f041c, KEY_NUMERIC_POUND },
-+
-+ { 0x800f0446, KEY_TV },
-+ { 0x800f0447, KEY_AUDIO }, /* My Music */
-+ { 0x800f0448, KEY_PVR }, /* RecordedTV */
-+ { 0x800f0449, KEY_CAMERA },
-+ { 0x800f044a, KEY_VIDEO },
-+ { 0x800f0424, KEY_DVD },
-+ { 0x800f0425, KEY_TUNER }, /* LiveTV */
-+ { 0x800f0450, KEY_RADIO },
-+
-+ { 0x800f044c, KEY_LANGUAGE },
-+ { 0x800f0427, KEY_ZOOM }, /* Aspect */
-+
-+ { 0x800f045b, KEY_RED },
-+ { 0x800f045c, KEY_GREEN },
-+ { 0x800f045d, KEY_YELLOW },
-+ { 0x800f045e, KEY_BLUE },
-+
-+ { 0x800f040f, KEY_INFO },
-+ { 0x800f0426, KEY_EPG }, /* Guide */
-+ { 0x800f045a, KEY_SUBTITLE }, /* Caption/Teletext */
-+ { 0x800f044d, KEY_TITLE },
-+
-+ { 0x800f040c, KEY_POWER },
-+ { 0x800f040d, KEY_PROG1 }, /* Windows MCE button */
-+
-+};
-+
-+static struct rc_keymap rc6_mce_map = {
-+ .map = {
-+ .scan = rc6_mce,
-+ .size = ARRAY_SIZE(rc6_mce),
-+ .ir_type = IR_TYPE_RC6,
-+ .name = RC_MAP_RC6_MCE,
-+ }
-+};
-+
-+static int __init init_rc_map_rc6_mce(void)
-+{
-+ return ir_register_map(&rc6_mce_map);
-+}
-+
-+static void __exit exit_rc_map_rc6_mce(void)
-+{
-+ ir_unregister_map(&rc6_mce_map);
-+}
-+
-+module_init(init_rc_map_rc6_mce)
-+module_exit(exit_rc_map_rc6_mce)
-+
-+MODULE_LICENSE("GPL");
-+MODULE_AUTHOR("Jarod Wilson <jarod@redhat.com>");
-diff --git a/drivers/media/IR/lirc_dev.c b/drivers/media/IR/lirc_dev.c
-new file mode 100644
-index 0000000..899891b
---- /dev/null
-+++ b/drivers/media/IR/lirc_dev.c
-@@ -0,0 +1,764 @@
-+/*
-+ * LIRC base driver
-+ *
-+ * by Artur Lipowski <alipowski@interia.pl>
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-+ *
-+ */
-+
-+#include <linux/module.h>
-+#include <linux/kernel.h>
-+#include <linux/sched.h>
-+#include <linux/errno.h>
-+#include <linux/ioctl.h>
-+#include <linux/fs.h>
-+#include <linux/poll.h>
-+#include <linux/completion.h>
-+#include <linux/errno.h>
-+#include <linux/mutex.h>
-+#include <linux/wait.h>
-+#include <linux/unistd.h>
-+#include <linux/kthread.h>
-+#include <linux/bitops.h>
-+#include <linux/device.h>
-+#include <linux/cdev.h>
-+
-+#include <media/lirc.h>
-+#include <media/lirc_dev.h>
-+
-+static int debug;
-+
-+#define IRCTL_DEV_NAME "BaseRemoteCtl"
-+#define NOPLUG -1
-+#define LOGHEAD "lirc_dev (%s[%d]): "
-+
-+static dev_t lirc_base_dev;
-+
-+struct irctl {
-+ struct lirc_driver d;
-+ int attached;
-+ int open;
-+
-+ struct mutex irctl_lock;
-+ struct lirc_buffer *buf;
-+ unsigned int chunk_size;
-+
-+ struct task_struct *task;
-+ long jiffies_to_wait;
-+
-+ struct cdev cdev;
-+};
-+
-+static DEFINE_MUTEX(lirc_dev_lock);
-+
-+static struct irctl *irctls[MAX_IRCTL_DEVICES];
-+
-+/* Only used for sysfs but defined to void otherwise */
-+static struct class *lirc_class;
-+
-+/* helper function
-+ * initializes the irctl structure
-+ */
-+static void init_irctl(struct irctl *ir)
-+{
-+ dev_dbg(ir->d.dev, LOGHEAD "initializing irctl\n",
-+ ir->d.name, ir->d.minor);
-+ mutex_init(&ir->irctl_lock);
-+ ir->d.minor = NOPLUG;
-+}
-+
-+static void cleanup(struct irctl *ir)
-+{
-+ dev_dbg(ir->d.dev, LOGHEAD "cleaning up\n", ir->d.name, ir->d.minor);
-+
-+ device_destroy(lirc_class, MKDEV(MAJOR(lirc_base_dev), ir->d.minor));
-+
-+ if (ir->buf != ir->d.rbuf) {
-+ lirc_buffer_free(ir->buf);
-+ kfree(ir->buf);
-+ }
-+ ir->buf = NULL;
-+}
-+
-+/* helper function
-+ * reads key codes from driver and puts them into buffer
-+ * returns 0 on success
-+ */
-+static int add_to_buf(struct irctl *ir)
-+{
-+ if (ir->d.add_to_buf) {
-+ int res = -ENODATA;
-+ int got_data = 0;
-+
-+ /*
-+ * service the device as long as it is returning
-+ * data and we have space
-+ */
-+get_data:
-+ res = ir->d.add_to_buf(ir->d.data, ir->buf);
-+ if (res == 0) {
-+ got_data++;
-+ goto get_data;
-+ }
-+
-+ if (res == -ENODEV)
-+ kthread_stop(ir->task);
-+
-+ return got_data ? 0 : res;
-+ }
-+
-+ return 0;
-+}
-+
-+/* main function of the polling thread
-+ */
-+static int lirc_thread(void *irctl)
-+{
-+ struct irctl *ir = irctl;
-+
-+ dev_dbg(ir->d.dev, LOGHEAD "poll thread started\n",
-+ ir->d.name, ir->d.minor);
-+
-+ do {
-+ if (ir->open) {
-+ if (ir->jiffies_to_wait) {
-+ set_current_state(TASK_INTERRUPTIBLE);
-+ schedule_timeout(ir->jiffies_to_wait);
-+ }
-+ if (kthread_should_stop())
-+ break;
-+ if (!add_to_buf(ir))
-+ wake_up_interruptible(&ir->buf->wait_poll);
-+ } else {
-+ set_current_state(TASK_INTERRUPTIBLE);
-+ schedule();
-+ }
-+ } while (!kthread_should_stop());
-+
-+ dev_dbg(ir->d.dev, LOGHEAD "poll thread ended\n",
-+ ir->d.name, ir->d.minor);
-+
-+ return 0;
-+}
-+
-+
-+static struct file_operations fops = {
-+ .owner = THIS_MODULE,
-+ .read = lirc_dev_fop_read,
-+ .write = lirc_dev_fop_write,
-+ .poll = lirc_dev_fop_poll,
-+ .unlocked_ioctl = lirc_dev_fop_ioctl,
-+ .open = lirc_dev_fop_open,
-+ .release = lirc_dev_fop_close,
-+};
-+
-+static int lirc_cdev_add(struct irctl *ir)
-+{
-+ int retval;
-+ struct lirc_driver *d = &ir->d;
-+
-+ if (d->fops) {
-+ cdev_init(&ir->cdev, d->fops);
-+ ir->cdev.owner = d->owner;
-+ } else {
-+ cdev_init(&ir->cdev, &fops);
-+ ir->cdev.owner = THIS_MODULE;
-+ }
-+ kobject_set_name(&ir->cdev.kobj, "lirc%d", d->minor);
-+
-+ retval = cdev_add(&ir->cdev, MKDEV(MAJOR(lirc_base_dev), d->minor), 1);
-+ if (retval)
-+ kobject_put(&ir->cdev.kobj);
-+
-+ return retval;
-+}
-+
-+int lirc_register_driver(struct lirc_driver *d)
-+{
-+ struct irctl *ir;
-+ int minor;
-+ int bytes_in_key;
-+ unsigned int chunk_size;
-+ unsigned int buffer_size;
-+ int err;
-+
-+ if (!d) {
-+ printk(KERN_ERR "lirc_dev: lirc_register_driver: "
-+ "driver pointer must be not NULL!\n");
-+ err = -EBADRQC;
-+ goto out;
-+ }
-+
-+ if (MAX_IRCTL_DEVICES <= d->minor) {
-+ dev_err(d->dev, "lirc_dev: lirc_register_driver: "
-+ "\"minor\" must be between 0 and %d (%d)!\n",
-+ MAX_IRCTL_DEVICES-1, d->minor);
-+ err = -EBADRQC;
-+ goto out;
-+ }
-+
-+ if (1 > d->code_length || (BUFLEN * 8) < d->code_length) {
-+ dev_err(d->dev, "lirc_dev: lirc_register_driver: "
-+ "code length in bits for minor (%d) "
-+ "must be less than %d!\n",
-+ d->minor, BUFLEN * 8);
-+ err = -EBADRQC;
-+ goto out;
-+ }
-+
-+ dev_dbg(d->dev, "lirc_dev: lirc_register_driver: sample_rate: %d\n",
-+ d->sample_rate);
-+ if (d->sample_rate) {
-+ if (2 > d->sample_rate || HZ < d->sample_rate) {
-+ dev_err(d->dev, "lirc_dev: lirc_register_driver: "
-+ "sample_rate must be between 2 and %d!\n", HZ);
-+ err = -EBADRQC;
-+ goto out;
-+ }
-+ if (!d->add_to_buf) {
-+ dev_err(d->dev, "lirc_dev: lirc_register_driver: "
-+ "add_to_buf cannot be NULL when "
-+ "sample_rate is set\n");
-+ err = -EBADRQC;
-+ goto out;
-+ }
-+ } else if (!(d->fops && d->fops->read) && !d->rbuf) {
-+ dev_err(d->dev, "lirc_dev: lirc_register_driver: "
-+ "fops->read and rbuf cannot all be NULL!\n");
-+ err = -EBADRQC;
-+ goto out;
-+ } else if (!d->rbuf) {
-+ if (!(d->fops && d->fops->read && d->fops->poll &&
-+ d->fops->unlocked_ioctl)) {
-+ dev_err(d->dev, "lirc_dev: lirc_register_driver: "
-+ "neither read, poll nor unlocked_ioctl can be NULL!\n");
-+ err = -EBADRQC;
-+ goto out;
-+ }
-+ }
-+
-+ mutex_lock(&lirc_dev_lock);
-+
-+ minor = d->minor;
-+
-+ if (minor < 0) {
-+ /* find first free slot for driver */
-+ for (minor = 0; minor < MAX_IRCTL_DEVICES; minor++)
-+ if (!irctls[minor])
-+ break;
-+ if (MAX_IRCTL_DEVICES == minor) {
-+ dev_err(d->dev, "lirc_dev: lirc_register_driver: "
-+ "no free slots for drivers!\n");
-+ err = -ENOMEM;
-+ goto out_lock;
-+ }
-+ } else if (irctls[minor]) {
-+ dev_err(d->dev, "lirc_dev: lirc_register_driver: "
-+ "minor (%d) just registered!\n", minor);
-+ err = -EBUSY;
-+ goto out_lock;
-+ }
-+
-+ ir = kzalloc(sizeof(struct irctl), GFP_KERNEL);
-+ if (!ir) {
-+ err = -ENOMEM;
-+ goto out_lock;
-+ }
-+ init_irctl(ir);
-+ irctls[minor] = ir;
-+ d->minor = minor;
-+
-+ if (d->sample_rate) {
-+ ir->jiffies_to_wait = HZ / d->sample_rate;
-+ } else {
-+ /* it means - wait for external event in task queue */
-+ ir->jiffies_to_wait = 0;
-+ }
-+
-+ /* some safety check 8-) */
-+ d->name[sizeof(d->name)-1] = '\0';
-+
-+ bytes_in_key = BITS_TO_LONGS(d->code_length) +
-+ (d->code_length % 8 ? 1 : 0);
-+ buffer_size = d->buffer_size ? d->buffer_size : BUFLEN / bytes_in_key;
-+ chunk_size = d->chunk_size ? d->chunk_size : bytes_in_key;
-+
-+ if (d->rbuf) {
-+ ir->buf = d->rbuf;
-+ } else {
-+ ir->buf = kmalloc(sizeof(struct lirc_buffer), GFP_KERNEL);
-+ if (!ir->buf) {
-+ err = -ENOMEM;
-+ goto out_lock;
-+ }
-+ err = lirc_buffer_init(ir->buf, chunk_size, buffer_size);
-+ if (err) {
-+ kfree(ir->buf);
-+ goto out_lock;
-+ }
-+ }
-+ ir->chunk_size = ir->buf->chunk_size;
-+
-+ if (d->features == 0)
-+ d->features = LIRC_CAN_REC_LIRCCODE;
-+
-+ ir->d = *d;
-+ ir->d.minor = minor;
-+
-+ device_create(lirc_class, ir->d.dev,
-+ MKDEV(MAJOR(lirc_base_dev), ir->d.minor), NULL,
-+ "lirc%u", ir->d.minor);
-+
-+ if (d->sample_rate) {
-+ /* try to fire up polling thread */
-+ ir->task = kthread_run(lirc_thread, (void *)ir, "lirc_dev");
-+ if (IS_ERR(ir->task)) {
-+ dev_err(d->dev, "lirc_dev: lirc_register_driver: "
-+ "cannot run poll thread for minor = %d\n",
-+ d->minor);
-+ err = -ECHILD;
-+ goto out_sysfs;
-+ }
-+ }
-+
-+ err = lirc_cdev_add(ir);
-+ if (err)
-+ goto out_sysfs;
-+
-+ ir->attached = 1;
-+ mutex_unlock(&lirc_dev_lock);
-+
-+ dev_info(ir->d.dev, "lirc_dev: driver %s registered at minor = %d\n",
-+ ir->d.name, ir->d.minor);
-+ return minor;
-+
-+out_sysfs:
-+ device_destroy(lirc_class, MKDEV(MAJOR(lirc_base_dev), ir->d.minor));
-+out_lock:
-+ mutex_unlock(&lirc_dev_lock);
-+out:
-+ return err;
-+}
-+EXPORT_SYMBOL(lirc_register_driver);
-+
-+int lirc_unregister_driver(int minor)
-+{
-+ struct irctl *ir;
-+
-+ if (minor < 0 || minor >= MAX_IRCTL_DEVICES) {
-+ printk(KERN_ERR "lirc_dev: lirc_unregister_driver: "
-+ "\"minor (%d)\" must be between 0 and %d!\n",
-+ minor, MAX_IRCTL_DEVICES-1);
-+ return -EBADRQC;
-+ }
-+
-+ ir = irctls[minor];
-+
-+ mutex_lock(&lirc_dev_lock);
-+
-+ if (ir->d.minor != minor) {
-+ printk(KERN_ERR "lirc_dev: lirc_unregister_driver: "
-+ "minor (%d) device not registered!", minor);
-+ mutex_unlock(&lirc_dev_lock);
-+ return -ENOENT;
-+ }
-+
-+ /* end up polling thread */
-+ if (ir->task)
-+ kthread_stop(ir->task);
-+
-+ dev_dbg(ir->d.dev, "lirc_dev: driver %s unregistered from minor = %d\n",
-+ ir->d.name, ir->d.minor);
-+
-+ ir->attached = 0;
-+ if (ir->open) {
-+ dev_dbg(ir->d.dev, LOGHEAD "releasing opened driver\n",
-+ ir->d.name, ir->d.minor);
-+ wake_up_interruptible(&ir->buf->wait_poll);
-+ mutex_lock(&ir->irctl_lock);
-+ ir->d.set_use_dec(ir->d.data);
-+ module_put(ir->d.owner);
-+ mutex_unlock(&ir->irctl_lock);
-+ cdev_del(&ir->cdev);
-+ } else {
-+ cleanup(ir);
-+ cdev_del(&ir->cdev);
-+ kfree(ir);
-+ irctls[minor] = NULL;
-+ }
-+
-+ mutex_unlock(&lirc_dev_lock);
-+
-+ return 0;
-+}
-+EXPORT_SYMBOL(lirc_unregister_driver);
-+
-+int lirc_dev_fop_open(struct inode *inode, struct file *file)
-+{
-+ struct irctl *ir;
-+ int retval = 0;
-+
-+ if (iminor(inode) >= MAX_IRCTL_DEVICES) {
-+ printk(KERN_WARNING "lirc_dev [%d]: open result = -ENODEV\n",
-+ iminor(inode));
-+ return -ENODEV;
-+ }
-+
-+ if (mutex_lock_interruptible(&lirc_dev_lock))
-+ return -ERESTARTSYS;
-+
-+ ir = irctls[iminor(inode)];
-+ if (!ir) {
-+ retval = -ENODEV;
-+ goto error;
-+ }
-+ file->private_data = ir;
-+
-+ dev_dbg(ir->d.dev, LOGHEAD "open called\n", ir->d.name, ir->d.minor);
-+
-+ if (ir->d.minor == NOPLUG) {
-+ retval = -ENODEV;
-+ goto error;
-+ }
-+
-+ if (ir->open) {
-+ retval = -EBUSY;
-+ goto error;
-+ }
-+
-+ if (try_module_get(ir->d.owner)) {
-+ ++ir->open;
-+ retval = ir->d.set_use_inc(ir->d.data);
-+
-+ if (retval) {
-+ module_put(ir->d.owner);
-+ --ir->open;
-+ } else {
-+ lirc_buffer_clear(ir->buf);
-+ }
-+ if (ir->task)
-+ wake_up_process(ir->task);
-+ }
-+
-+error:
-+ if (ir)
-+ dev_dbg(ir->d.dev, LOGHEAD "open result = %d\n",
-+ ir->d.name, ir->d.minor, retval);
-+
-+ mutex_unlock(&lirc_dev_lock);
-+
-+ return retval;
-+}
-+EXPORT_SYMBOL(lirc_dev_fop_open);
-+
-+int lirc_dev_fop_close(struct inode *inode, struct file *file)
-+{
-+ struct irctl *ir = irctls[iminor(inode)];
-+
-+ dev_dbg(ir->d.dev, LOGHEAD "close called\n", ir->d.name, ir->d.minor);
-+
-+ WARN_ON(mutex_lock_killable(&lirc_dev_lock));
-+
-+ --ir->open;
-+ if (ir->attached) {
-+ ir->d.set_use_dec(ir->d.data);
-+ module_put(ir->d.owner);
-+ } else {
-+ cleanup(ir);
-+ irctls[ir->d.minor] = NULL;
-+ kfree(ir);
-+ }
-+
-+ mutex_unlock(&lirc_dev_lock);
-+
-+ return 0;
-+}
-+EXPORT_SYMBOL(lirc_dev_fop_close);
-+
-+unsigned int lirc_dev_fop_poll(struct file *file, poll_table *wait)
-+{
-+ struct irctl *ir = irctls[iminor(file->f_dentry->d_inode)];
-+ unsigned int ret;
-+
-+ dev_dbg(ir->d.dev, LOGHEAD "poll called\n", ir->d.name, ir->d.minor);
-+
-+ if (!ir->attached) {
-+ mutex_unlock(&ir->irctl_lock);
-+ return POLLERR;
-+ }
-+
-+ poll_wait(file, &ir->buf->wait_poll, wait);
-+
-+ if (ir->buf)
-+ if (lirc_buffer_empty(ir->buf))
-+ ret = 0;
-+ else
-+ ret = POLLIN | POLLRDNORM;
-+ else
-+ ret = POLLERR;
-+
-+ dev_dbg(ir->d.dev, LOGHEAD "poll result = %d\n",
-+ ir->d.name, ir->d.minor, ret);
-+
-+ return ret;
-+}
-+EXPORT_SYMBOL(lirc_dev_fop_poll);
-+
-+long lirc_dev_fop_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
-+{
-+ unsigned long mode;
-+ int result = 0;
-+ struct irctl *ir = file->private_data;
-+
-+ dev_dbg(ir->d.dev, LOGHEAD "ioctl called (0x%x)\n",
-+ ir->d.name, ir->d.minor, cmd);
-+
-+ if (ir->d.minor == NOPLUG || !ir->attached) {
-+ dev_dbg(ir->d.dev, LOGHEAD "ioctl result = -ENODEV\n",
-+ ir->d.name, ir->d.minor);
-+ return -ENODEV;
-+ }
-+
-+ mutex_lock(&ir->irctl_lock);
-+
-+ switch (cmd) {
-+ case LIRC_GET_FEATURES:
-+ result = put_user(ir->d.features, (unsigned long *)arg);
-+ break;
-+ case LIRC_GET_REC_MODE:
-+ if (!(ir->d.features & LIRC_CAN_REC_MASK)) {
-+ result = -ENOSYS;
-+ break;
-+ }
-+
-+ result = put_user(LIRC_REC2MODE
-+ (ir->d.features & LIRC_CAN_REC_MASK),
-+ (unsigned long *)arg);
-+ break;
-+ case LIRC_SET_REC_MODE:
-+ if (!(ir->d.features & LIRC_CAN_REC_MASK)) {
-+ result = -ENOSYS;
-+ break;
-+ }
-+
-+ result = get_user(mode, (unsigned long *)arg);
-+ if (!result && !(LIRC_MODE2REC(mode) & ir->d.features))
-+ result = -EINVAL;
-+ /*
-+ * FIXME: We should actually set the mode somehow but
-+ * for now, lirc_serial doesn't support mode changing either
-+ */
-+ break;
-+ case LIRC_GET_LENGTH:
-+ result = put_user(ir->d.code_length, (unsigned long *)arg);
-+ break;
-+ case LIRC_GET_MIN_TIMEOUT:
-+ if (!(ir->d.features & LIRC_CAN_SET_REC_TIMEOUT) ||
-+ ir->d.min_timeout == 0) {
-+ result = -ENOSYS;
-+ break;
-+ }
-+
-+ result = put_user(ir->d.min_timeout, (unsigned long *)arg);
-+ break;
-+ case LIRC_GET_MAX_TIMEOUT:
-+ if (!(ir->d.features & LIRC_CAN_SET_REC_TIMEOUT) ||
-+ ir->d.max_timeout == 0) {
-+ result = -ENOSYS;
-+ break;
-+ }
-+
-+ result = put_user(ir->d.max_timeout, (unsigned long *)arg);
-+ break;
-+ default:
-+ result = -EINVAL;
-+ }
-+
-+ dev_dbg(ir->d.dev, LOGHEAD "ioctl result = %d\n",
-+ ir->d.name, ir->d.minor, result);
-+
-+ mutex_unlock(&ir->irctl_lock);
-+
-+ return result;
-+}
-+EXPORT_SYMBOL(lirc_dev_fop_ioctl);
-+
-+ssize_t lirc_dev_fop_read(struct file *file,
-+ char *buffer,
-+ size_t length,
-+ loff_t *ppos)
-+{
-+ struct irctl *ir = irctls[iminor(file->f_dentry->d_inode)];
-+ unsigned char buf[ir->chunk_size];
-+ int ret = 0, written = 0;
-+ DECLARE_WAITQUEUE(wait, current);
-+
-+ dev_dbg(ir->d.dev, LOGHEAD "read called\n", ir->d.name, ir->d.minor);
-+
-+ if (mutex_lock_interruptible(&ir->irctl_lock))
-+ return -ERESTARTSYS;
-+ if (!ir->attached) {
-+ mutex_unlock(&ir->irctl_lock);
-+ return -ENODEV;
-+ }
-+
-+ if (length % ir->chunk_size) {
-+ dev_dbg(ir->d.dev, LOGHEAD "read result = -EINVAL\n",
-+ ir->d.name, ir->d.minor);
-+ mutex_unlock(&ir->irctl_lock);
-+ return -EINVAL;
-+ }
-+
-+ /*
-+ * we add ourselves to the task queue before buffer check
-+ * to avoid losing scan code (in case when queue is awaken somewhere
-+ * between while condition checking and scheduling)
-+ */
-+ add_wait_queue(&ir->buf->wait_poll, &wait);
-+ set_current_state(TASK_INTERRUPTIBLE);
-+
-+ /*
-+ * while we didn't provide 'length' bytes, device is opened in blocking
-+ * mode and 'copy_to_user' is happy, wait for data.
-+ */
-+ while (written < length && ret == 0) {
-+ if (lirc_buffer_empty(ir->buf)) {
-+ /* According to the read(2) man page, 'written' can be
-+ * returned as less than 'length', instead of blocking
-+ * again, returning -EWOULDBLOCK, or returning
-+ * -ERESTARTSYS */
-+ if (written)
-+ break;
-+ if (file->f_flags & O_NONBLOCK) {
-+ ret = -EWOULDBLOCK;
-+ break;
-+ }
-+ if (signal_pending(current)) {
-+ ret = -ERESTARTSYS;
-+ break;
-+ }
-+
-+ mutex_unlock(&ir->irctl_lock);
-+ schedule();
-+ set_current_state(TASK_INTERRUPTIBLE);
-+
-+ if (mutex_lock_interruptible(&ir->irctl_lock)) {
-+ ret = -ERESTARTSYS;
-+ remove_wait_queue(&ir->buf->wait_poll, &wait);
-+ set_current_state(TASK_RUNNING);
-+ goto out_unlocked;
-+ }
-+
-+ if (!ir->attached) {
-+ ret = -ENODEV;
-+ break;
-+ }
-+ } else {
-+ lirc_buffer_read(ir->buf, buf);
-+ ret = copy_to_user((void *)buffer+written, buf,
-+ ir->buf->chunk_size);
-+ written += ir->buf->chunk_size;
-+ }
-+ }
-+
-+ remove_wait_queue(&ir->buf->wait_poll, &wait);
-+ set_current_state(TASK_RUNNING);
-+ mutex_unlock(&ir->irctl_lock);
-+
-+out_unlocked:
-+ dev_dbg(ir->d.dev, LOGHEAD "read result = %s (%d)\n",
-+ ir->d.name, ir->d.minor, ret ? "-EFAULT" : "OK", ret);
-+
-+ return ret ? ret : written;
-+}
-+EXPORT_SYMBOL(lirc_dev_fop_read);
-+
-+void *lirc_get_pdata(struct file *file)
-+{
-+ void *data = NULL;
-+
-+ if (file && file->f_dentry && file->f_dentry->d_inode &&
-+ file->f_dentry->d_inode->i_rdev) {
-+ struct irctl *ir;
-+ ir = irctls[iminor(file->f_dentry->d_inode)];
-+ data = ir->d.data;
-+ }
-+
-+ return data;
-+}
-+EXPORT_SYMBOL(lirc_get_pdata);
-+
-+
-+ssize_t lirc_dev_fop_write(struct file *file, const char *buffer,
-+ size_t length, loff_t *ppos)
-+{
-+ struct irctl *ir = irctls[iminor(file->f_dentry->d_inode)];
-+
-+ dev_dbg(ir->d.dev, LOGHEAD "write called\n", ir->d.name, ir->d.minor);
-+
-+ if (!ir->attached)
-+ return -ENODEV;
-+
-+ return -EINVAL;
-+}
-+EXPORT_SYMBOL(lirc_dev_fop_write);
-+
-+
-+static int __init lirc_dev_init(void)
-+{
-+ int retval;
-+
-+ lirc_class = class_create(THIS_MODULE, "lirc");
-+ if (IS_ERR(lirc_class)) {
-+ retval = PTR_ERR(lirc_class);
-+ printk(KERN_ERR "lirc_dev: class_create failed\n");
-+ goto error;
-+ }
-+
-+ retval = alloc_chrdev_region(&lirc_base_dev, 0, MAX_IRCTL_DEVICES,
-+ IRCTL_DEV_NAME);
-+ if (retval) {
-+ class_destroy(lirc_class);
-+ printk(KERN_ERR "lirc_dev: alloc_chrdev_region failed\n");
-+ goto error;
-+ }
-+
-+
-+ printk(KERN_INFO "lirc_dev: IR Remote Control driver registered, "
-+ "major %d \n", MAJOR(lirc_base_dev));
-+
-+error:
-+ return retval;
-+}
-+
-+
-+
-+static void __exit lirc_dev_exit(void)
-+{
-+ class_destroy(lirc_class);
-+ unregister_chrdev_region(lirc_base_dev, MAX_IRCTL_DEVICES);
-+ printk(KERN_INFO "lirc_dev: module unloaded\n");
-+}
-+
-+module_init(lirc_dev_init);
-+module_exit(lirc_dev_exit);
-+
-+MODULE_DESCRIPTION("LIRC base driver module");
-+MODULE_AUTHOR("Artur Lipowski");
-+MODULE_LICENSE("GPL");
-+
-+module_param(debug, bool, S_IRUGO | S_IWUSR);
-+MODULE_PARM_DESC(debug, "Enable debugging messages");
-diff --git a/drivers/media/IR/mceusb.c b/drivers/media/IR/mceusb.c
-new file mode 100644
-index 0000000..78bf7f7
---- /dev/null
-+++ b/drivers/media/IR/mceusb.c
-@@ -0,0 +1,1143 @@
-+/*
-+ * Driver for USB Windows Media Center Ed. eHome Infrared Transceivers
-+ *
-+ * Copyright (c) 2010 by Jarod Wilson <jarod@redhat.com>
-+ *
-+ * Based on the original lirc_mceusb and lirc_mceusb2 drivers, by Dan
-+ * Conti, Martin Blatter and Daniel Melander, the latter of which was
-+ * in turn also based on the lirc_atiusb driver by Paul Miller. The
-+ * two mce drivers were merged into one by Jarod Wilson, with transmit
-+ * support for the 1st-gen device added primarily by Patrick Calhoun,
-+ * with a bit of tweaks by Jarod. Debugging improvements and proper
-+ * support for what appears to be 3rd-gen hardware added by Jarod.
-+ * Initial port from lirc driver to ir-core drivery by Jarod, based
-+ * partially on a port to an earlier proposed IR infrastructure by
-+ * Jon Smirl, which included enhancements and simplifications to the
-+ * incoming IR buffer parsing routines.
-+ *
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-+ *
-+ */
-+
-+#include <linux/device.h>
-+#include <linux/module.h>
-+#include <linux/slab.h>
-+#include <linux/usb.h>
-+#include <linux/input.h>
-+#include <media/ir-core.h>
-+#include <media/ir-common.h>
-+
-+#define DRIVER_VERSION "1.91"
-+#define DRIVER_AUTHOR "Jarod Wilson <jarod@wilsonet.com>"
-+#define DRIVER_DESC "Windows Media Center Ed. eHome Infrared Transceiver " \
-+ "device driver"
-+#define DRIVER_NAME "mceusb"
-+
-+#define USB_BUFLEN 32 /* USB reception buffer length */
-+#define USB_CTRL_MSG_SZ 2 /* Size of usb ctrl msg on gen1 hw */
-+#define MCE_G1_INIT_MSGS 40 /* Init messages on gen1 hw to throw out */
-+
-+/* MCE constants */
-+#define MCE_CMDBUF_SIZE 384 /* MCE Command buffer length */
-+#define MCE_TIME_UNIT 50 /* Approx 50us resolution */
-+#define MCE_CODE_LENGTH 5 /* Normal length of packet (with header) */
-+#define MCE_PACKET_SIZE 4 /* Normal length of packet (without header) */
-+#define MCE_PACKET_HEADER 0x84 /* Actual header format is 0x80 + num_bytes */
-+#define MCE_CONTROL_HEADER 0x9F /* MCE status header */
-+#define MCE_TX_HEADER_LENGTH 3 /* # of bytes in the initializing tx header */
-+#define MCE_MAX_CHANNELS 2 /* Two transmitters, hardware dependent? */
-+#define MCE_DEFAULT_TX_MASK 0x03 /* Val opts: TX1=0x01, TX2=0x02, ALL=0x03 */
-+#define MCE_PULSE_BIT 0x80 /* Pulse bit, MSB set == PULSE else SPACE */
-+#define MCE_PULSE_MASK 0x7F /* Pulse mask */
-+#define MCE_MAX_PULSE_LENGTH 0x7F /* Longest transmittable pulse symbol */
-+#define MCE_PACKET_LENGTH_MASK 0x1F /* Packet length mask */
-+
-+
-+/* module parameters */
-+#ifdef CONFIG_USB_DEBUG
-+static int debug = 1;
-+#else
-+static int debug;
-+#endif
-+
-+/* general constants */
-+#define SEND_FLAG_IN_PROGRESS 1
-+#define SEND_FLAG_COMPLETE 2
-+#define RECV_FLAG_IN_PROGRESS 3
-+#define RECV_FLAG_COMPLETE 4
-+
-+#define MCEUSB_RX 1
-+#define MCEUSB_TX 2
-+
-+#define VENDOR_PHILIPS 0x0471
-+#define VENDOR_SMK 0x0609
-+#define VENDOR_TATUNG 0x1460
-+#define VENDOR_GATEWAY 0x107b
-+#define VENDOR_SHUTTLE 0x1308
-+#define VENDOR_SHUTTLE2 0x051c
-+#define VENDOR_MITSUMI 0x03ee
-+#define VENDOR_TOPSEED 0x1784
-+#define VENDOR_RICAVISION 0x179d
-+#define VENDOR_ITRON 0x195d
-+#define VENDOR_FIC 0x1509
-+#define VENDOR_LG 0x043e
-+#define VENDOR_MICROSOFT 0x045e
-+#define VENDOR_FORMOSA 0x147a
-+#define VENDOR_FINTEK 0x1934
-+#define VENDOR_PINNACLE 0x2304
-+#define VENDOR_ECS 0x1019
-+#define VENDOR_WISTRON 0x0fb8
-+#define VENDOR_COMPRO 0x185b
-+#define VENDOR_NORTHSTAR 0x04eb
-+#define VENDOR_REALTEK 0x0bda
-+#define VENDOR_TIVO 0x105a
-+
-+static struct usb_device_id mceusb_dev_table[] = {
-+ /* Original Microsoft MCE IR Transceiver (often HP-branded) */
-+ { USB_DEVICE(VENDOR_MICROSOFT, 0x006d) },
-+ /* Philips Infrared Transceiver - Sahara branded */
-+ { USB_DEVICE(VENDOR_PHILIPS, 0x0608) },
-+ /* Philips Infrared Transceiver - HP branded */
-+ { USB_DEVICE(VENDOR_PHILIPS, 0x060c) },
-+ /* Philips SRM5100 */
-+ { USB_DEVICE(VENDOR_PHILIPS, 0x060d) },
-+ /* Philips Infrared Transceiver - Omaura */
-+ { USB_DEVICE(VENDOR_PHILIPS, 0x060f) },
-+ /* Philips Infrared Transceiver - Spinel plus */
-+ { USB_DEVICE(VENDOR_PHILIPS, 0x0613) },
-+ /* Philips eHome Infrared Transceiver */
-+ { USB_DEVICE(VENDOR_PHILIPS, 0x0815) },
-+ /* Realtek MCE IR Receiver */
-+ { USB_DEVICE(VENDOR_REALTEK, 0x0161) },
-+ /* SMK/Toshiba G83C0004D410 */
-+ { USB_DEVICE(VENDOR_SMK, 0x031d) },
-+ /* SMK eHome Infrared Transceiver (Sony VAIO) */
-+ { USB_DEVICE(VENDOR_SMK, 0x0322) },
-+ /* bundled with Hauppauge PVR-150 */
-+ { USB_DEVICE(VENDOR_SMK, 0x0334) },
-+ /* SMK eHome Infrared Transceiver */
-+ { USB_DEVICE(VENDOR_SMK, 0x0338) },
-+ /* Tatung eHome Infrared Transceiver */
-+ { USB_DEVICE(VENDOR_TATUNG, 0x9150) },
-+ /* Shuttle eHome Infrared Transceiver */
-+ { USB_DEVICE(VENDOR_SHUTTLE, 0xc001) },
-+ /* Shuttle eHome Infrared Transceiver */
-+ { USB_DEVICE(VENDOR_SHUTTLE2, 0xc001) },
-+ /* Gateway eHome Infrared Transceiver */
-+ { USB_DEVICE(VENDOR_GATEWAY, 0x3009) },
-+ /* Mitsumi */
-+ { USB_DEVICE(VENDOR_MITSUMI, 0x2501) },
-+ /* Topseed eHome Infrared Transceiver */
-+ { USB_DEVICE(VENDOR_TOPSEED, 0x0001) },
-+ /* Topseed HP eHome Infrared Transceiver */
-+ { USB_DEVICE(VENDOR_TOPSEED, 0x0006) },
-+ /* Topseed eHome Infrared Transceiver */
-+ { USB_DEVICE(VENDOR_TOPSEED, 0x0007) },
-+ /* Topseed eHome Infrared Transceiver */
-+ { USB_DEVICE(VENDOR_TOPSEED, 0x0008) },
-+ /* Topseed eHome Infrared Transceiver */
-+ { USB_DEVICE(VENDOR_TOPSEED, 0x000a) },
-+ /* Topseed eHome Infrared Transceiver */
-+ { USB_DEVICE(VENDOR_TOPSEED, 0x0011) },
-+ /* Ricavision internal Infrared Transceiver */
-+ { USB_DEVICE(VENDOR_RICAVISION, 0x0010) },
-+ /* Itron ione Libra Q-11 */
-+ { USB_DEVICE(VENDOR_ITRON, 0x7002) },
-+ /* FIC eHome Infrared Transceiver */
-+ { USB_DEVICE(VENDOR_FIC, 0x9242) },
-+ /* LG eHome Infrared Transceiver */
-+ { USB_DEVICE(VENDOR_LG, 0x9803) },
-+ /* Microsoft MCE Infrared Transceiver */
-+ { USB_DEVICE(VENDOR_MICROSOFT, 0x00a0) },
-+ /* Formosa eHome Infrared Transceiver */
-+ { USB_DEVICE(VENDOR_FORMOSA, 0xe015) },
-+ /* Formosa21 / eHome Infrared Receiver */
-+ { USB_DEVICE(VENDOR_FORMOSA, 0xe016) },
-+ /* Formosa aim / Trust MCE Infrared Receiver */
-+ { USB_DEVICE(VENDOR_FORMOSA, 0xe017) },
-+ /* Formosa Industrial Computing / Beanbag Emulation Device */
-+ { USB_DEVICE(VENDOR_FORMOSA, 0xe018) },
-+ /* Formosa21 / eHome Infrared Receiver */
-+ { USB_DEVICE(VENDOR_FORMOSA, 0xe03a) },
-+ /* Formosa Industrial Computing AIM IR605/A */
-+ { USB_DEVICE(VENDOR_FORMOSA, 0xe03c) },
-+ /* Formosa Industrial Computing */
-+ { USB_DEVICE(VENDOR_FORMOSA, 0xe03e) },
-+ /* Fintek eHome Infrared Transceiver */
-+ { USB_DEVICE(VENDOR_FINTEK, 0x0602) },
-+ /* Fintek eHome Infrared Transceiver (in the AOpen MP45) */
-+ { USB_DEVICE(VENDOR_FINTEK, 0x0702) },
-+ /* Pinnacle Remote Kit */
-+ { USB_DEVICE(VENDOR_PINNACLE, 0x0225) },
-+ /* Elitegroup Computer Systems IR */
-+ { USB_DEVICE(VENDOR_ECS, 0x0f38) },
-+ /* Wistron Corp. eHome Infrared Receiver */
-+ { USB_DEVICE(VENDOR_WISTRON, 0x0002) },
-+ /* Compro K100 */
-+ { USB_DEVICE(VENDOR_COMPRO, 0x3020) },
-+ /* Compro K100 v2 */
-+ { USB_DEVICE(VENDOR_COMPRO, 0x3082) },
-+ /* Northstar Systems, Inc. eHome Infrared Transceiver */
-+ { USB_DEVICE(VENDOR_NORTHSTAR, 0xe004) },
-+ /* TiVo PC IR Receiver */
-+ { USB_DEVICE(VENDOR_TIVO, 0x2000) },
-+ /* Terminating entry */
-+ { }
-+};
-+
-+static struct usb_device_id gen3_list[] = {
-+ { USB_DEVICE(VENDOR_PINNACLE, 0x0225) },
-+ { USB_DEVICE(VENDOR_TOPSEED, 0x0008) },
-+ {}
-+};
-+
-+static struct usb_device_id microsoft_gen1_list[] = {
-+ { USB_DEVICE(VENDOR_MICROSOFT, 0x006d) },
-+ {}
-+};
-+
-+static struct usb_device_id std_tx_mask_list[] = {
-+ { USB_DEVICE(VENDOR_MICROSOFT, 0x006d) },
-+ { USB_DEVICE(VENDOR_PHILIPS, 0x060c) },
-+ { USB_DEVICE(VENDOR_SMK, 0x031d) },
-+ { USB_DEVICE(VENDOR_SMK, 0x0322) },
-+ { USB_DEVICE(VENDOR_SMK, 0x0334) },
-+ { USB_DEVICE(VENDOR_TOPSEED, 0x0001) },
-+ { USB_DEVICE(VENDOR_TOPSEED, 0x0006) },
-+ { USB_DEVICE(VENDOR_TOPSEED, 0x0007) },
-+ { USB_DEVICE(VENDOR_TOPSEED, 0x0008) },
-+ { USB_DEVICE(VENDOR_TOPSEED, 0x000a) },
-+ { USB_DEVICE(VENDOR_TOPSEED, 0x0011) },
-+ { USB_DEVICE(VENDOR_PINNACLE, 0x0225) },
-+ {}
-+};
-+
-+/* data structure for each usb transceiver */
-+struct mceusb_dev {
-+ /* ir-core bits */
-+ struct ir_input_dev *irdev;
-+ struct ir_dev_props *props;
-+ struct ir_raw_event rawir;
-+
-+ /* core device bits */
-+ struct device *dev;
-+ struct input_dev *idev;
-+
-+ /* usb */
-+ struct usb_device *usbdev;
-+ struct urb *urb_in;
-+ struct usb_endpoint_descriptor *usb_ep_in;
-+ struct usb_endpoint_descriptor *usb_ep_out;
-+
-+ /* buffers and dma */
-+ unsigned char *buf_in;
-+ unsigned int len_in;
-+ u8 cmd; /* MCE command type */
-+ u8 rem; /* Remaining IR data bytes in packet */
-+ dma_addr_t dma_in;
-+ dma_addr_t dma_out;
-+
-+ struct {
-+ u32 connected:1;
-+ u32 tx_mask_inverted:1;
-+ u32 microsoft_gen1:1;
-+ u32 reserved:29;
-+ } flags;
-+
-+ /* transmit support */
-+ int send_flags;
-+ u32 carrier;
-+ unsigned char tx_mask;
-+
-+ char name[128];
-+ char phys[64];
-+};
-+
-+/*
-+ * MCE Device Command Strings
-+ * Device command responses vary from device to device...
-+ * - DEVICE_RESET resets the hardware to its default state
-+ * - GET_REVISION fetches the hardware/software revision, common
-+ * replies are ff 0b 45 ff 1b 08 and ff 0b 50 ff 1b 42
-+ * - GET_CARRIER_FREQ gets the carrier mode and frequency of the
-+ * device, with replies in the form of 9f 06 MM FF, where MM is 0-3,
-+ * meaning clk of 10000000, 2500000, 625000 or 156250, and FF is
-+ * ((clk / frequency) - 1)
-+ * - GET_RX_TIMEOUT fetches the receiver timeout in units of 50us,
-+ * response in the form of 9f 0c msb lsb
-+ * - GET_TX_BITMASK fetches the transmitter bitmask, replies in
-+ * the form of 9f 08 bm, where bm is the bitmask
-+ * - GET_RX_SENSOR fetches the RX sensor setting -- long-range
-+ * general use one or short-range learning one, in the form of
-+ * 9f 14 ss, where ss is either 01 for long-range or 02 for short
-+ * - SET_CARRIER_FREQ sets a new carrier mode and frequency
-+ * - SET_TX_BITMASK sets the transmitter bitmask
-+ * - SET_RX_TIMEOUT sets the receiver timeout
-+ * - SET_RX_SENSOR sets which receiver sensor to use
-+ */
-+static char DEVICE_RESET[] = {0x00, 0xff, 0xaa};
-+static char GET_REVISION[] = {0xff, 0x0b};
-+static char GET_UNKNOWN[] = {0xff, 0x18};
-+static char GET_UNKNOWN2[] = {0x9f, 0x05};
-+static char GET_CARRIER_FREQ[] = {0x9f, 0x07};
-+static char GET_RX_TIMEOUT[] = {0x9f, 0x0d};
-+static char GET_TX_BITMASK[] = {0x9f, 0x13};
-+static char GET_RX_SENSOR[] = {0x9f, 0x15};
-+/* sub in desired values in lower byte or bytes for full command */
-+/* FIXME: make use of these for transmit.
-+static char SET_CARRIER_FREQ[] = {0x9f, 0x06, 0x00, 0x00};
-+static char SET_TX_BITMASK[] = {0x9f, 0x08, 0x00};
-+static char SET_RX_TIMEOUT[] = {0x9f, 0x0c, 0x00, 0x00};
-+static char SET_RX_SENSOR[] = {0x9f, 0x14, 0x00};
-+*/
-+
-+static void mceusb_dev_printdata(struct mceusb_dev *ir, char *buf,
-+ int len, bool out)
-+{
-+ char codes[USB_BUFLEN * 3 + 1];
-+ char inout[9];
-+ int i;
-+ u8 cmd, subcmd, data1, data2;
-+ struct device *dev = ir->dev;
-+ int idx = 0;
-+
-+ /* skip meaningless 0xb1 0x60 header bytes on orig receiver */
-+ if (ir->flags.microsoft_gen1 && !out)
-+ idx = 2;
-+
-+ if (len <= idx)
-+ return;
-+
-+ for (i = 0; i < len && i < USB_BUFLEN; i++)
-+ snprintf(codes + i * 3, 4, "%02x ", buf[i] & 0xFF);
-+
-+ dev_info(dev, "%sx data: %s (length=%d)\n",
-+ (out ? "t" : "r"), codes, len);
-+
-+ if (out)
-+ strcpy(inout, "Request\0");
-+ else
-+ strcpy(inout, "Got\0");
-+
-+ cmd = buf[idx] & 0xff;
-+ subcmd = buf[idx + 1] & 0xff;
-+ data1 = buf[idx + 2] & 0xff;
-+ data2 = buf[idx + 3] & 0xff;
-+
-+ switch (cmd) {
-+ case 0x00:
-+ if (subcmd == 0xff && data1 == 0xaa)
-+ dev_info(dev, "Device reset requested\n");
-+ else
-+ dev_info(dev, "Unknown command 0x%02x 0x%02x\n",
-+ cmd, subcmd);
-+ break;
-+ case 0xff:
-+ switch (subcmd) {
-+ case 0x0b:
-+ if (len == 2)
-+ dev_info(dev, "Get hw/sw rev?\n");
-+ else
-+ dev_info(dev, "hw/sw rev 0x%02x 0x%02x "
-+ "0x%02x 0x%02x\n", data1, data2,
-+ buf[idx + 4], buf[idx + 5]);
-+ break;
-+ case 0xaa:
-+ dev_info(dev, "Device reset requested\n");
-+ break;
-+ case 0xfe:
-+ dev_info(dev, "Previous command not supported\n");
-+ break;
-+ case 0x18:
-+ case 0x1b:
-+ default:
-+ dev_info(dev, "Unknown command 0x%02x 0x%02x\n",
-+ cmd, subcmd);
-+ break;
-+ }
-+ break;
-+ case 0x9f:
-+ switch (subcmd) {
-+ case 0x03:
-+ dev_info(dev, "Ping\n");
-+ break;
-+ case 0x04:
-+ dev_info(dev, "Resp to 9f 05 of 0x%02x 0x%02x\n",
-+ data1, data2);
-+ break;
-+ case 0x06:
-+ dev_info(dev, "%s carrier mode and freq of "
-+ "0x%02x 0x%02x\n", inout, data1, data2);
-+ break;
-+ case 0x07:
-+ dev_info(dev, "Get carrier mode and freq\n");
-+ break;
-+ case 0x08:
-+ dev_info(dev, "%s transmit blaster mask of 0x%02x\n",
-+ inout, data1);
-+ break;
-+ case 0x0c:
-+ /* value is in units of 50us, so x*50/100 or x/2 ms */
-+ dev_info(dev, "%s receive timeout of %d ms\n",
-+ inout, ((data1 << 8) | data2) / 2);
-+ break;
-+ case 0x0d:
-+ dev_info(dev, "Get receive timeout\n");
-+ break;
-+ case 0x13:
-+ dev_info(dev, "Get transmit blaster mask\n");
-+ break;
-+ case 0x14:
-+ dev_info(dev, "%s %s-range receive sensor in use\n",
-+ inout, data1 == 0x02 ? "short" : "long");
-+ break;
-+ case 0x15:
-+ if (len == 2)
-+ dev_info(dev, "Get receive sensor\n");
-+ else
-+ dev_info(dev, "Received pulse count is %d\n",
-+ ((data1 << 8) | data2));
-+ break;
-+ case 0xfe:
-+ dev_info(dev, "Error! Hardware is likely wedged...\n");
-+ break;
-+ case 0x05:
-+ case 0x09:
-+ case 0x0f:
-+ default:
-+ dev_info(dev, "Unknown command 0x%02x 0x%02x\n",
-+ cmd, subcmd);
-+ break;
-+ }
-+ break;
-+ default:
-+ break;
-+ }
-+}
-+
-+static void usb_async_callback(struct urb *urb, struct pt_regs *regs)
-+{
-+ struct mceusb_dev *ir;
-+ int len;
-+
-+ if (!urb)
-+ return;
-+
-+ ir = urb->context;
-+ if (ir) {
-+ len = urb->actual_length;
-+
-+ dev_dbg(ir->dev, "callback called (status=%d len=%d)\n",
-+ urb->status, len);
-+
-+ if (debug)
-+ mceusb_dev_printdata(ir, urb->transfer_buffer,
-+ len, true);
-+ }
-+
-+}
-+
-+/* request incoming or send outgoing usb packet - used to initialize remote */
-+static void mce_request_packet(struct mceusb_dev *ir,
-+ struct usb_endpoint_descriptor *ep,
-+ unsigned char *data, int size, int urb_type)
-+{
-+ int res;
-+ struct urb *async_urb;
-+ struct device *dev = ir->dev;
-+ unsigned char *async_buf;
-+
-+ if (urb_type == MCEUSB_TX) {
-+ async_urb = usb_alloc_urb(0, GFP_KERNEL);
-+ if (unlikely(!async_urb)) {
-+ dev_err(dev, "Error, couldn't allocate urb!\n");
-+ return;
-+ }
-+
-+ async_buf = kzalloc(size, GFP_KERNEL);
-+ if (!async_buf) {
-+ dev_err(dev, "Error, couldn't allocate buf!\n");
-+ usb_free_urb(async_urb);
-+ return;
-+ }
-+
-+ /* outbound data */
-+ usb_fill_int_urb(async_urb, ir->usbdev,
-+ usb_sndintpipe(ir->usbdev, ep->bEndpointAddress),
-+ async_buf, size, (usb_complete_t) usb_async_callback,
-+ ir, ep->bInterval);
-+ memcpy(async_buf, data, size);
-+
-+ } else if (urb_type == MCEUSB_RX) {
-+ /* standard request */
-+ async_urb = ir->urb_in;
-+ ir->send_flags = RECV_FLAG_IN_PROGRESS;
-+
-+ } else {
-+ dev_err(dev, "Error! Unknown urb type %d\n", urb_type);
-+ return;
-+ }
-+
-+ dev_dbg(dev, "receive request called (size=%#x)\n", size);
-+
-+ async_urb->transfer_buffer_length = size;
-+ async_urb->dev = ir->usbdev;
-+
-+ res = usb_submit_urb(async_urb, GFP_ATOMIC);
-+ if (res) {
-+ dev_dbg(dev, "receive request FAILED! (res=%d)\n", res);
-+ return;
-+ }
-+ dev_dbg(dev, "receive request complete (res=%d)\n", res);
-+}
-+
-+static void mce_async_out(struct mceusb_dev *ir, unsigned char *data, int size)
-+{
-+ mce_request_packet(ir, ir->usb_ep_out, data, size, MCEUSB_TX);
-+}
-+
-+static void mce_sync_in(struct mceusb_dev *ir, unsigned char *data, int size)
-+{
-+ mce_request_packet(ir, ir->usb_ep_in, data, size, MCEUSB_RX);
-+}
-+
-+/* Send data out the IR blaster port(s) */
-+static int mceusb_tx_ir(void *priv, int *txbuf, u32 n)
-+{
-+ struct mceusb_dev *ir = priv;
-+ int i, ret = 0;
-+ int count, cmdcount = 0;
-+ unsigned char *cmdbuf; /* MCE command buffer */
-+ long signal_duration = 0; /* Singnal length in us */
-+ struct timeval start_time, end_time;
-+
-+ do_gettimeofday(&start_time);
-+
-+ count = n / sizeof(int);
-+
-+ cmdbuf = kzalloc(sizeof(int) * MCE_CMDBUF_SIZE, GFP_KERNEL);
-+ if (!cmdbuf)
-+ return -ENOMEM;
-+
-+ /* MCE tx init header */
-+ cmdbuf[cmdcount++] = MCE_CONTROL_HEADER;
-+ cmdbuf[cmdcount++] = 0x08;
-+ cmdbuf[cmdcount++] = ir->tx_mask;
-+
-+ /* Generate mce packet data */
-+ for (i = 0; (i < count) && (cmdcount < MCE_CMDBUF_SIZE); i++) {
-+ signal_duration += txbuf[i];
-+ txbuf[i] = txbuf[i] / MCE_TIME_UNIT;
-+
-+ do { /* loop to support long pulses/spaces > 127*50us=6.35ms */
-+
-+ /* Insert mce packet header every 4th entry */
-+ if ((cmdcount < MCE_CMDBUF_SIZE) &&
-+ (cmdcount - MCE_TX_HEADER_LENGTH) %
-+ MCE_CODE_LENGTH == 0)
-+ cmdbuf[cmdcount++] = MCE_PACKET_HEADER;
-+
-+ /* Insert mce packet data */
-+ if (cmdcount < MCE_CMDBUF_SIZE)
-+ cmdbuf[cmdcount++] =
-+ (txbuf[i] < MCE_PULSE_BIT ?
-+ txbuf[i] : MCE_MAX_PULSE_LENGTH) |
-+ (i & 1 ? 0x00 : MCE_PULSE_BIT);
-+ else {
-+ ret = -EINVAL;
-+ goto out;
-+ }
-+
-+ } while ((txbuf[i] > MCE_MAX_PULSE_LENGTH) &&
-+ (txbuf[i] -= MCE_MAX_PULSE_LENGTH));
-+ }
-+
-+ /* Fix packet length in last header */
-+ cmdbuf[cmdcount - (cmdcount - MCE_TX_HEADER_LENGTH) % MCE_CODE_LENGTH] =
-+ 0x80 + (cmdcount - MCE_TX_HEADER_LENGTH) % MCE_CODE_LENGTH - 1;
-+
-+ /* Check if we have room for the empty packet at the end */
-+ if (cmdcount >= MCE_CMDBUF_SIZE) {
-+ ret = -EINVAL;
-+ goto out;
-+ }
-+
-+ /* All mce commands end with an empty packet (0x80) */
-+ cmdbuf[cmdcount++] = 0x80;
-+
-+ /* Transmit the command to the mce device */
-+ mce_async_out(ir, cmdbuf, cmdcount);
-+
-+ /*
-+ * The lircd gap calculation expects the write function to
-+ * wait the time it takes for the ircommand to be sent before
-+ * it returns.
-+ */
-+ do_gettimeofday(&end_time);
-+ signal_duration -= (end_time.tv_usec - start_time.tv_usec) +
-+ (end_time.tv_sec - start_time.tv_sec) * 1000000;
-+
-+ /* delay with the closest number of ticks */
-+ set_current_state(TASK_INTERRUPTIBLE);
-+ schedule_timeout(usecs_to_jiffies(signal_duration));
-+
-+out:
-+ kfree(cmdbuf);
-+ return ret ? ret : n;
-+}
-+
-+/* Sets active IR outputs -- mce devices typically (all?) have two */
-+static int mceusb_set_tx_mask(void *priv, u32 mask)
-+{
-+ struct mceusb_dev *ir = priv;
-+
-+ if (ir->flags.tx_mask_inverted)
-+ ir->tx_mask = (mask != 0x03 ? mask ^ 0x03 : mask) << 1;
-+ else
-+ ir->tx_mask = mask;
-+
-+ return 0;
-+}
-+
-+/* Sets the send carrier frequency and mode */
-+static int mceusb_set_tx_carrier(void *priv, u32 carrier)
-+{
-+ struct mceusb_dev *ir = priv;
-+ int clk = 10000000;
-+ int prescaler = 0, divisor = 0;
-+ unsigned char cmdbuf[4] = { 0x9f, 0x06, 0x00, 0x00 };
-+
-+ /* Carrier has changed */
-+ if (ir->carrier != carrier) {
-+
-+ if (carrier == 0) {
-+ ir->carrier = carrier;
-+ cmdbuf[2] = 0x01;
-+ cmdbuf[3] = 0x80;
-+ dev_dbg(ir->dev, "%s: disabling carrier "
-+ "modulation\n", __func__);
-+ mce_async_out(ir, cmdbuf, sizeof(cmdbuf));
-+ return carrier;
-+ }
-+
-+ for (prescaler = 0; prescaler < 4; ++prescaler) {
-+ divisor = (clk >> (2 * prescaler)) / carrier;
-+ if (divisor <= 0xFF) {
-+ ir->carrier = carrier;
-+ cmdbuf[2] = prescaler;
-+ cmdbuf[3] = divisor;
-+ dev_dbg(ir->dev, "%s: requesting %u HZ "
-+ "carrier\n", __func__, carrier);
-+
-+ /* Transmit new carrier to mce device */
-+ mce_async_out(ir, cmdbuf, sizeof(cmdbuf));
-+ return carrier;
-+ }
-+ }
-+
-+ return -EINVAL;
-+
-+ }
-+
-+ return carrier;
-+}
-+
-+static void mceusb_process_ir_data(struct mceusb_dev *ir, int buf_len)
-+{
-+ struct ir_raw_event rawir = { .pulse = false, .duration = 0 };
-+ int i, start_index = 0;
-+ u8 hdr = MCE_CONTROL_HEADER;
-+
-+ /* skip meaningless 0xb1 0x60 header bytes on orig receiver */
-+ if (ir->flags.microsoft_gen1)
-+ start_index = 2;
-+
-+ for (i = start_index; i < buf_len;) {
-+ if (ir->rem == 0) {
-+ /* decode mce packets of the form (84),AA,BB,CC,DD */
-+ /* IR data packets can span USB messages - rem */
-+ hdr = ir->buf_in[i];
-+ ir->rem = (hdr & MCE_PACKET_LENGTH_MASK);
-+ ir->cmd = (hdr & ~MCE_PACKET_LENGTH_MASK);
-+ dev_dbg(ir->dev, "New data. rem: 0x%02x, cmd: 0x%02x\n",
-+ ir->rem, ir->cmd);
-+ i++;
-+ }
-+
-+ /* don't process MCE commands */
-+ if (hdr == MCE_CONTROL_HEADER || hdr == 0xff) {
-+ ir->rem = 0;
-+ return;
-+ }
-+
-+ for (; (ir->rem > 0) && (i < buf_len); i++) {
-+ ir->rem--;
-+
-+ rawir.pulse = ((ir->buf_in[i] & MCE_PULSE_BIT) != 0);
-+ rawir.duration = (ir->buf_in[i] & MCE_PULSE_MASK)
-+ * MCE_TIME_UNIT * 1000;
-+
-+ if ((ir->buf_in[i] & MCE_PULSE_MASK) == 0x7f) {
-+ if (ir->rawir.pulse == rawir.pulse)
-+ ir->rawir.duration += rawir.duration;
-+ else {
-+ ir->rawir.duration = rawir.duration;
-+ ir->rawir.pulse = rawir.pulse;
-+ }
-+ continue;
-+ }
-+ rawir.duration += ir->rawir.duration;
-+ ir->rawir.duration = 0;
-+ ir->rawir.pulse = rawir.pulse;
-+
-+ dev_dbg(ir->dev, "Storing %s with duration %d\n",
-+ rawir.pulse ? "pulse" : "space",
-+ rawir.duration);
-+
-+ ir_raw_event_store(ir->idev, &rawir);
-+ }
-+
-+ if (ir->buf_in[i] == 0x80 || ir->buf_in[i] == 0x9f)
-+ ir->rem = 0;
-+
-+ dev_dbg(ir->dev, "calling ir_raw_event_handle\n");
-+ ir_raw_event_handle(ir->idev);
-+ }
-+}
-+
-+static void mceusb_dev_recv(struct urb *urb, struct pt_regs *regs)
-+{
-+ struct mceusb_dev *ir;
-+ int buf_len;
-+
-+ if (!urb)
-+ return;
-+
-+ ir = urb->context;
-+ if (!ir) {
-+ usb_unlink_urb(urb);
-+ return;
-+ }
-+
-+ buf_len = urb->actual_length;
-+
-+ if (debug)
-+ mceusb_dev_printdata(ir, urb->transfer_buffer, buf_len, false);
-+
-+ if (ir->send_flags == RECV_FLAG_IN_PROGRESS) {
-+ ir->send_flags = SEND_FLAG_COMPLETE;
-+ dev_dbg(&ir->irdev->dev, "setup answer received %d bytes\n",
-+ buf_len);
-+ }
-+
-+ switch (urb->status) {
-+ /* success */
-+ case 0:
-+ mceusb_process_ir_data(ir, buf_len);
-+ break;
-+
-+ case -ECONNRESET:
-+ case -ENOENT:
-+ case -ESHUTDOWN:
-+ usb_unlink_urb(urb);
-+ return;
-+
-+ case -EPIPE:
-+ default:
-+ break;
-+ }
-+
-+ usb_submit_urb(urb, GFP_ATOMIC);
-+}
-+
-+static void mceusb_gen1_init(struct mceusb_dev *ir)
-+{
-+ int ret;
-+ int maxp = ir->len_in;
-+ struct device *dev = ir->dev;
-+ char *data;
-+
-+ data = kzalloc(USB_CTRL_MSG_SZ, GFP_KERNEL);
-+ if (!data) {
-+ dev_err(dev, "%s: memory allocation failed!\n", __func__);
-+ return;
-+ }
-+
-+ /*
-+ * This is a strange one. Windows issues a set address to the device
-+ * on the receive control pipe and expect a certain value pair back
-+ */
-+ ret = usb_control_msg(ir->usbdev, usb_rcvctrlpipe(ir->usbdev, 0),
-+ USB_REQ_SET_ADDRESS, USB_TYPE_VENDOR, 0, 0,
-+ data, USB_CTRL_MSG_SZ, HZ * 3);
-+ dev_dbg(dev, "%s - ret = %d\n", __func__, ret);
-+ dev_dbg(dev, "%s - data[0] = %d, data[1] = %d\n",
-+ __func__, data[0], data[1]);
-+
-+ /* set feature: bit rate 38400 bps */
-+ ret = usb_control_msg(ir->usbdev, usb_sndctrlpipe(ir->usbdev, 0),
-+ USB_REQ_SET_FEATURE, USB_TYPE_VENDOR,
-+ 0xc04e, 0x0000, NULL, 0, HZ * 3);
-+
-+ dev_dbg(dev, "%s - ret = %d\n", __func__, ret);
-+
-+ /* bRequest 4: set char length to 8 bits */
-+ ret = usb_control_msg(ir->usbdev, usb_sndctrlpipe(ir->usbdev, 0),
-+ 4, USB_TYPE_VENDOR,
-+ 0x0808, 0x0000, NULL, 0, HZ * 3);
-+ dev_dbg(dev, "%s - retB = %d\n", __func__, ret);
-+
-+ /* bRequest 2: set handshaking to use DTR/DSR */
-+ ret = usb_control_msg(ir->usbdev, usb_sndctrlpipe(ir->usbdev, 0),
-+ 2, USB_TYPE_VENDOR,
-+ 0x0000, 0x0100, NULL, 0, HZ * 3);
-+ dev_dbg(dev, "%s - retC = %d\n", __func__, ret);
-+
-+ /* device reset */
-+ mce_async_out(ir, DEVICE_RESET, sizeof(DEVICE_RESET));
-+ mce_sync_in(ir, NULL, maxp);
-+
-+ /* get hw/sw revision? */
-+ mce_async_out(ir, GET_REVISION, sizeof(GET_REVISION));
-+ mce_sync_in(ir, NULL, maxp);
-+
-+ kfree(data);
-+};
-+
-+static void mceusb_gen2_init(struct mceusb_dev *ir)
-+{
-+ int maxp = ir->len_in;
-+
-+ /* device reset */
-+ mce_async_out(ir, DEVICE_RESET, sizeof(DEVICE_RESET));
-+ mce_sync_in(ir, NULL, maxp);
-+
-+ /* get hw/sw revision? */
-+ mce_async_out(ir, GET_REVISION, sizeof(GET_REVISION));
-+ mce_sync_in(ir, NULL, maxp);
-+
-+ /* unknown what the next two actually return... */
-+ mce_async_out(ir, GET_UNKNOWN, sizeof(GET_UNKNOWN));
-+ mce_sync_in(ir, NULL, maxp);
-+ mce_async_out(ir, GET_UNKNOWN2, sizeof(GET_UNKNOWN2));
-+ mce_sync_in(ir, NULL, maxp);
-+}
-+
-+static void mceusb_get_parameters(struct mceusb_dev *ir)
-+{
-+ int maxp = ir->len_in;
-+
-+ /* get the carrier and frequency */
-+ mce_async_out(ir, GET_CARRIER_FREQ, sizeof(GET_CARRIER_FREQ));
-+ mce_sync_in(ir, NULL, maxp);
-+
-+ /* get the transmitter bitmask */
-+ mce_async_out(ir, GET_TX_BITMASK, sizeof(GET_TX_BITMASK));
-+ mce_sync_in(ir, NULL, maxp);
-+
-+ /* get receiver timeout value */
-+ mce_async_out(ir, GET_RX_TIMEOUT, sizeof(GET_RX_TIMEOUT));
-+ mce_sync_in(ir, NULL, maxp);
-+
-+ /* get receiver sensor setting */
-+ mce_async_out(ir, GET_RX_SENSOR, sizeof(GET_RX_SENSOR));
-+ mce_sync_in(ir, NULL, maxp);
-+}
-+
-+static struct input_dev *mceusb_init_input_dev(struct mceusb_dev *ir)
-+{
-+ struct input_dev *idev;
-+ struct ir_dev_props *props;
-+ struct ir_input_dev *irdev;
-+ struct device *dev = ir->dev;
-+ int ret = -ENODEV;
-+
-+ idev = input_allocate_device();
-+ if (!idev) {
-+ dev_err(dev, "remote input dev allocation failed\n");
-+ goto idev_alloc_failed;
-+ }
-+
-+ ret = -ENOMEM;
-+ props = kzalloc(sizeof(struct ir_dev_props), GFP_KERNEL);
-+ if (!props) {
-+ dev_err(dev, "remote ir dev props allocation failed\n");
-+ goto props_alloc_failed;
-+ }
-+
-+ irdev = kzalloc(sizeof(struct ir_input_dev), GFP_KERNEL);
-+ if (!irdev) {
-+ dev_err(dev, "remote ir input dev allocation failed\n");
-+ goto ir_dev_alloc_failed;
-+ }
-+
-+ snprintf(ir->name, sizeof(ir->name), "Media Center Ed. eHome "
-+ "Infrared Remote Transceiver (%04x:%04x)",
-+ le16_to_cpu(ir->usbdev->descriptor.idVendor),
-+ le16_to_cpu(ir->usbdev->descriptor.idProduct));
-+
-+ idev->name = ir->name;
-+ usb_make_path(ir->usbdev, ir->phys, sizeof(ir->phys));
-+ strlcat(ir->phys, "/input0", sizeof(ir->phys));
-+ idev->phys = ir->phys;
-+
-+ props->priv = ir;
-+ props->driver_type = RC_DRIVER_IR_RAW;
-+ props->allowed_protos = IR_TYPE_ALL;
-+ props->s_tx_mask = mceusb_set_tx_mask;
-+ props->s_tx_carrier = mceusb_set_tx_carrier;
-+ props->tx_ir = mceusb_tx_ir;
-+
-+ ir->props = props;
-+ ir->irdev = irdev;
-+
-+ input_set_drvdata(idev, irdev);
-+
-+ ret = ir_input_register(idev, RC_MAP_RC6_MCE, props, DRIVER_NAME);
-+ if (ret < 0) {
-+ dev_err(dev, "remote input device register failed\n");
-+ goto irdev_failed;
-+ }
-+
-+ return idev;
-+
-+irdev_failed:
-+ kfree(irdev);
-+ir_dev_alloc_failed:
-+ kfree(props);
-+props_alloc_failed:
-+ input_free_device(idev);
-+idev_alloc_failed:
-+ return NULL;
-+}
-+
-+static int __devinit mceusb_dev_probe(struct usb_interface *intf,
-+ const struct usb_device_id *id)
-+{
-+ struct usb_device *dev = interface_to_usbdev(intf);
-+ struct usb_host_interface *idesc;
-+ struct usb_endpoint_descriptor *ep = NULL;
-+ struct usb_endpoint_descriptor *ep_in = NULL;
-+ struct usb_endpoint_descriptor *ep_out = NULL;
-+ struct usb_host_config *config;
-+ struct mceusb_dev *ir = NULL;
-+ int pipe, maxp, i;
-+ char buf[63], name[128] = "";
-+ bool is_gen3;
-+ bool is_microsoft_gen1;
-+ bool tx_mask_inverted;
-+
-+ dev_dbg(&intf->dev, ": %s called\n", __func__);
-+
-+ config = dev->actconfig;
-+ idesc = intf->cur_altsetting;
-+
-+ is_gen3 = usb_match_id(intf, gen3_list) ? 1 : 0;
-+ is_microsoft_gen1 = usb_match_id(intf, microsoft_gen1_list) ? 1 : 0;
-+ tx_mask_inverted = usb_match_id(intf, std_tx_mask_list) ? 0 : 1;
-+
-+ /* step through the endpoints to find first bulk in and out endpoint */
-+ for (i = 0; i < idesc->desc.bNumEndpoints; ++i) {
-+ ep = &idesc->endpoint[i].desc;
-+
-+ if ((ep_in == NULL)
-+ && ((ep->bEndpointAddress & USB_ENDPOINT_DIR_MASK)
-+ == USB_DIR_IN)
-+ && (((ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)
-+ == USB_ENDPOINT_XFER_BULK)
-+ || ((ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)
-+ == USB_ENDPOINT_XFER_INT))) {
-+
-+ ep_in = ep;
-+ ep_in->bmAttributes = USB_ENDPOINT_XFER_INT;
-+ ep_in->bInterval = 1;
-+ dev_dbg(&intf->dev, ": acceptable inbound endpoint "
-+ "found\n");
-+ }
-+
-+ if ((ep_out == NULL)
-+ && ((ep->bEndpointAddress & USB_ENDPOINT_DIR_MASK)
-+ == USB_DIR_OUT)
-+ && (((ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)
-+ == USB_ENDPOINT_XFER_BULK)
-+ || ((ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)
-+ == USB_ENDPOINT_XFER_INT))) {
-+
-+ ep_out = ep;
-+ ep_out->bmAttributes = USB_ENDPOINT_XFER_INT;
-+ ep_out->bInterval = 1;
-+ dev_dbg(&intf->dev, ": acceptable outbound endpoint "
-+ "found\n");
-+ }
-+ }
-+ if (ep_in == NULL) {
-+ dev_dbg(&intf->dev, ": inbound and/or endpoint not found\n");
-+ return -ENODEV;
-+ }
-+
-+ pipe = usb_rcvintpipe(dev, ep_in->bEndpointAddress);
-+ maxp = usb_maxpacket(dev, pipe, usb_pipeout(pipe));
-+
-+ ir = kzalloc(sizeof(struct mceusb_dev), GFP_KERNEL);
-+ if (!ir)
-+ goto mem_alloc_fail;
-+
-+ ir->buf_in = usb_alloc_coherent(dev, maxp, GFP_ATOMIC, &ir->dma_in);
-+ if (!ir->buf_in)
-+ goto buf_in_alloc_fail;
-+
-+ ir->urb_in = usb_alloc_urb(0, GFP_KERNEL);
-+ if (!ir->urb_in)
-+ goto urb_in_alloc_fail;
-+
-+ ir->usbdev = dev;
-+ ir->dev = &intf->dev;
-+ ir->len_in = maxp;
-+ ir->flags.microsoft_gen1 = is_microsoft_gen1;
-+ ir->flags.tx_mask_inverted = tx_mask_inverted;
-+
-+ /* Saving usb interface data for use by the transmitter routine */
-+ ir->usb_ep_in = ep_in;
-+ ir->usb_ep_out = ep_out;
-+
-+ if (dev->descriptor.iManufacturer
-+ && usb_string(dev, dev->descriptor.iManufacturer,
-+ buf, sizeof(buf)) > 0)
-+ strlcpy(name, buf, sizeof(name));
-+ if (dev->descriptor.iProduct
-+ && usb_string(dev, dev->descriptor.iProduct,
-+ buf, sizeof(buf)) > 0)
-+ snprintf(name + strlen(name), sizeof(name) - strlen(name),
-+ " %s", buf);
-+
-+ ir->idev = mceusb_init_input_dev(ir);
-+ if (!ir->idev)
-+ goto input_dev_fail;
-+
-+ /* flush buffers on the device */
-+ mce_sync_in(ir, NULL, maxp);
-+ mce_sync_in(ir, NULL, maxp);
-+
-+ /* wire up inbound data handler */
-+ usb_fill_int_urb(ir->urb_in, dev, pipe, ir->buf_in,
-+ maxp, (usb_complete_t) mceusb_dev_recv, ir, ep_in->bInterval);
-+ ir->urb_in->transfer_dma = ir->dma_in;
-+ ir->urb_in->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
-+
-+ /* initialize device */
-+ if (ir->flags.microsoft_gen1)
-+ mceusb_gen1_init(ir);
-+ else if (!is_gen3)
-+ mceusb_gen2_init(ir);
-+
-+ mceusb_get_parameters(ir);
-+
-+ mceusb_set_tx_mask(ir, MCE_DEFAULT_TX_MASK);
-+
-+ usb_set_intfdata(intf, ir);
-+
-+ dev_info(&intf->dev, "Registered %s on usb%d:%d\n", name,
-+ dev->bus->busnum, dev->devnum);
-+
-+ return 0;
-+
-+ /* Error-handling path */
-+input_dev_fail:
-+ usb_free_urb(ir->urb_in);
-+urb_in_alloc_fail:
-+ usb_free_coherent(dev, maxp, ir->buf_in, ir->dma_in);
-+buf_in_alloc_fail:
-+ kfree(ir);
-+mem_alloc_fail:
-+ dev_err(&intf->dev, "%s: device setup failed!\n", __func__);
-+
-+ return -ENOMEM;
-+}
-+
-+
-+static void __devexit mceusb_dev_disconnect(struct usb_interface *intf)
-+{
-+ struct usb_device *dev = interface_to_usbdev(intf);
-+ struct mceusb_dev *ir = usb_get_intfdata(intf);
-+
-+ usb_set_intfdata(intf, NULL);
-+
-+ if (!ir)
-+ return;
-+
-+ ir->usbdev = NULL;
-+ ir_input_unregister(ir->idev);
-+ usb_kill_urb(ir->urb_in);
-+ usb_free_urb(ir->urb_in);
-+ usb_free_coherent(dev, ir->len_in, ir->buf_in, ir->dma_in);
-+
-+ kfree(ir);
-+}
-+
-+static int mceusb_dev_suspend(struct usb_interface *intf, pm_message_t message)
-+{
-+ struct mceusb_dev *ir = usb_get_intfdata(intf);
-+ dev_info(ir->dev, "suspend\n");
-+ usb_kill_urb(ir->urb_in);
-+ return 0;
-+}
-+
-+static int mceusb_dev_resume(struct usb_interface *intf)
-+{
-+ struct mceusb_dev *ir = usb_get_intfdata(intf);
-+ dev_info(ir->dev, "resume\n");
-+ if (usb_submit_urb(ir->urb_in, GFP_ATOMIC))
-+ return -EIO;
-+ return 0;
-+}
-+
-+static struct usb_driver mceusb_dev_driver = {
-+ .name = DRIVER_NAME,
-+ .probe = mceusb_dev_probe,
-+ .disconnect = mceusb_dev_disconnect,
-+ .suspend = mceusb_dev_suspend,
-+ .resume = mceusb_dev_resume,
-+ .reset_resume = mceusb_dev_resume,
-+ .id_table = mceusb_dev_table
-+};
-+
-+static int __init mceusb_dev_init(void)
-+{
-+ int ret;
-+
-+ ret = usb_register(&mceusb_dev_driver);
-+ if (ret < 0)
-+ printk(KERN_ERR DRIVER_NAME
-+ ": usb register failed, result = %d\n", ret);
-+
-+ return ret;
-+}
-+
-+static void __exit mceusb_dev_exit(void)
-+{
-+ usb_deregister(&mceusb_dev_driver);
-+}
-+
-+module_init(mceusb_dev_init);
-+module_exit(mceusb_dev_exit);
-+
-+MODULE_DESCRIPTION(DRIVER_DESC);
-+MODULE_AUTHOR(DRIVER_AUTHOR);
-+MODULE_LICENSE("GPL");
-+MODULE_DEVICE_TABLE(usb, mceusb_dev_table);
-+
-+module_param(debug, bool, S_IRUGO | S_IWUSR);
-+MODULE_PARM_DESC(debug, "Debug enabled or not");
-diff --git a/drivers/media/common/tuners/tda18271-fe.c b/drivers/media/common/tuners/tda18271-fe.c
-index b2e1545..7955e49 100644
---- a/drivers/media/common/tuners/tda18271-fe.c
-+++ b/drivers/media/common/tuners/tda18271-fe.c
-@@ -1249,7 +1249,7 @@ struct dvb_frontend *tda18271_attach(struct dvb_frontend *fe, u8 addr,
- struct tda18271_config *cfg)
- {
- struct tda18271_priv *priv = NULL;
-- int instance;
-+ int instance, ret;
-
- mutex_lock(&tda18271_list_mutex);
-
-@@ -1268,10 +1268,12 @@ struct dvb_frontend *tda18271_attach(struct dvb_frontend *fe, u8 addr,
- priv->cal_initialized = false;
- mutex_init(&priv->lock);
-
-- if (tda_fail(tda18271_get_id(fe)))
-+ ret = tda18271_get_id(fe);
-+ if (tda_fail(ret))
- goto fail;
-
-- if (tda_fail(tda18271_assign_map_layout(fe)))
-+ ret = tda18271_assign_map_layout(fe);
-+ if (tda_fail(ret))
- goto fail;
-
- mutex_lock(&priv->lock);
-diff --git a/drivers/media/dvb/mantis/Kconfig b/drivers/media/dvb/mantis/Kconfig
-index f7b72a3..decdeda 100644
---- a/drivers/media/dvb/mantis/Kconfig
-+++ b/drivers/media/dvb/mantis/Kconfig
-@@ -10,9 +10,15 @@ config MANTIS_CORE
- config DVB_MANTIS
- tristate "MANTIS based cards"
- depends on MANTIS_CORE && DVB_CORE && PCI && I2C
-- select DVB_MB86A16
-- select DVB_ZL10353
-- select DVB_STV0299
-+ select DVB_MB86A16 if !DVB_FE_CUSTOMISE
-+ select DVB_ZL10353 if !DVB_FE_CUSTOMISE
-+ select DVB_STV0299 if !DVB_FE_CUSTOMISE
-+ select DVB_LNBP21 if !DVB_FE_CUSTOMISE
-+ select DVB_STB0899 if !DVB_FE_CUSTOMISE
-+ select DVB_STB6100 if !DVB_FE_CUSTOMISE
-+ select DVB_TDA665x if !DVB_FE_CUSTOMISE
-+ select DVB_TDA10021 if !DVB_FE_CUSTOMISE
-+ select DVB_TDA10023 if !DVB_FE_CUSTOMISE
- select DVB_PLL
- help
- Support for PCI cards based on the Mantis PCI bridge.
-@@ -23,7 +29,7 @@ config DVB_MANTIS
- config DVB_HOPPER
- tristate "HOPPER based cards"
- depends on MANTIS_CORE && DVB_CORE && PCI && I2C
-- select DVB_ZL10353
-+ select DVB_ZL10353 if !DVB_FE_CUSTOMISE
- select DVB_PLL
- help
- Support for PCI cards based on the Hopper PCI bridge.
-diff --git a/drivers/media/dvb/mantis/mantis_input.c b/drivers/media/dvb/mantis/mantis_input.c
-index 3d4e466..a99489b 100644
---- a/drivers/media/dvb/mantis/mantis_input.c
-+++ b/drivers/media/dvb/mantis/mantis_input.c
-@@ -19,7 +19,7 @@
- */
-
- #include <linux/input.h>
--#include <media/ir-common.h>
-+#include <media/ir-core.h>
- #include <linux/pci.h>
-
- #include "dmxdev.h"
-@@ -104,7 +104,6 @@ EXPORT_SYMBOL_GPL(ir_mantis);
- int mantis_input_init(struct mantis_pci *mantis)
- {
- struct input_dev *rc;
-- struct ir_input_state rc_state;
- char name[80], dev[80];
- int err;
-
-@@ -120,8 +119,6 @@ int mantis_input_init(struct mantis_pci *mantis)
- rc->name = name;
- rc->phys = dev;
-
-- ir_input_init(rc, &rc_state, IR_TYPE_OTHER);
--
- rc->id.bustype = BUS_PCI;
- rc->id.vendor = mantis->vendor_id;
- rc->id.product = mantis->device_id;
-diff --git a/drivers/media/video/cx23885/cx23885-cards.c b/drivers/media/video/cx23885/cx23885-cards.c
-index d639186..2014dae 100644
---- a/drivers/media/video/cx23885/cx23885-cards.c
-+++ b/drivers/media/video/cx23885/cx23885-cards.c
-@@ -408,10 +408,18 @@ struct cx23885_subid cx23885_subids[] = {
- .card = CX23885_BOARD_HAUPPAUGE_HVR1275,
- }, {
- .subvendor = 0x0070,
-+ .subdevice = 0x221d,
-+ .card = CX23885_BOARD_HAUPPAUGE_HVR1275,
-+ }, {
-+ .subvendor = 0x0070,
- .subdevice = 0x2251,
- .card = CX23885_BOARD_HAUPPAUGE_HVR1255,
- }, {
- .subvendor = 0x0070,
-+ .subdevice = 0x2259,
-+ .card = CX23885_BOARD_HAUPPAUGE_HVR1255,
-+ }, {
-+ .subvendor = 0x0070,
- .subdevice = 0x2291,
- .card = CX23885_BOARD_HAUPPAUGE_HVR1210,
- }, {
-@@ -419,6 +427,38 @@ struct cx23885_subid cx23885_subids[] = {
- .subdevice = 0x2295,
- .card = CX23885_BOARD_HAUPPAUGE_HVR1210,
- }, {
-+ .subvendor = 0x0070,
-+ .subdevice = 0x2299,
-+ .card = CX23885_BOARD_HAUPPAUGE_HVR1210,
-+ }, {
-+ .subvendor = 0x0070,
-+ .subdevice = 0x229d,
-+ .card = CX23885_BOARD_HAUPPAUGE_HVR1210, /* HVR1215 */
-+ }, {
-+ .subvendor = 0x0070,
-+ .subdevice = 0x22f0,
-+ .card = CX23885_BOARD_HAUPPAUGE_HVR1210,
-+ }, {
-+ .subvendor = 0x0070,
-+ .subdevice = 0x22f1,
-+ .card = CX23885_BOARD_HAUPPAUGE_HVR1255,
-+ }, {
-+ .subvendor = 0x0070,
-+ .subdevice = 0x22f2,
-+ .card = CX23885_BOARD_HAUPPAUGE_HVR1275,
-+ }, {
-+ .subvendor = 0x0070,
-+ .subdevice = 0x22f3,
-+ .card = CX23885_BOARD_HAUPPAUGE_HVR1210, /* HVR1215 */
-+ }, {
-+ .subvendor = 0x0070,
-+ .subdevice = 0x22f4,
-+ .card = CX23885_BOARD_HAUPPAUGE_HVR1210,
-+ }, {
-+ .subvendor = 0x0070,
-+ .subdevice = 0x22f5,
-+ .card = CX23885_BOARD_HAUPPAUGE_HVR1210, /* HVR1215 */
-+ }, {
- .subvendor = 0x14f1,
- .subdevice = 0x8651,
- .card = CX23885_BOARD_MYGICA_X8506,
-diff --git a/drivers/media/video/cx23885/cx23885-core.c b/drivers/media/video/cx23885/cx23885-core.c
-index 0dde57e..ff76f64 100644
---- a/drivers/media/video/cx23885/cx23885-core.c
-+++ b/drivers/media/video/cx23885/cx23885-core.c
-@@ -1142,7 +1142,7 @@ void cx23885_free_buffer(struct videobuf_queue *q, struct cx23885_buffer *buf)
-
- BUG_ON(in_interrupt());
- videobuf_waiton(&buf->vb, 0, 0);
-- videobuf_dma_unmap(q, dma);
-+ videobuf_dma_unmap(q->dev, dma);
- videobuf_dma_free(dma);
- btcx_riscmem_free(to_pci_dev(q->dev), &buf->risc);
- buf->vb.state = VIDEOBUF_NEEDS_INIT;
-@@ -1953,8 +1953,12 @@ static int __devinit cx23885_initdev(struct pci_dev *pci_dev,
- goto fail_irq;
- }
-
-- err = request_irq(pci_dev->irq, cx23885_irq,
-- IRQF_SHARED | IRQF_DISABLED, dev->name, dev);
-+ if (!pci_enable_msi(pci_dev))
-+ err = request_irq(pci_dev->irq, cx23885_irq,
-+ IRQF_DISABLED, dev->name, dev);
-+ else
-+ err = request_irq(pci_dev->irq, cx23885_irq,
-+ IRQF_SHARED | IRQF_DISABLED, dev->name, dev);
- if (err < 0) {
- printk(KERN_ERR "%s: can't get IRQ %d\n",
- dev->name, pci_dev->irq);
-@@ -2000,6 +2004,7 @@ static void __devexit cx23885_finidev(struct pci_dev *pci_dev)
-
- /* unregister stuff */
- free_irq(pci_dev->irq, dev);
-+ pci_disable_msi(pci_dev);
-
- cx23885_dev_unregister(dev);
- v4l2_device_unregister(v4l2_dev);
-diff --git a/drivers/media/video/cx23885/cx23885-dvb.c b/drivers/media/video/cx23885/cx23885-dvb.c
-index 0a199d7..3d70af2 100644
---- a/drivers/media/video/cx23885/cx23885-dvb.c
-+++ b/drivers/media/video/cx23885/cx23885-dvb.c
-@@ -991,7 +991,7 @@ static int dvb_register(struct cx23885_tsport *port)
- ret = videobuf_dvb_register_bus(&port->frontends, THIS_MODULE, port,
- &dev->pci->dev, adapter_nr, 0,
- cx23885_dvb_fe_ioctl_override);
-- if (!ret)
-+ if (ret)
- return ret;
-
- /* init CI & MAC */
-diff --git a/drivers/media/video/cx23885/cx23885-input.c b/drivers/media/video/cx23885/cx23885-input.c
-index 5de6ba9..d0b1613 100644
---- a/drivers/media/video/cx23885/cx23885-input.c
-+++ b/drivers/media/video/cx23885/cx23885-input.c
-@@ -37,161 +37,55 @@
-
- #include <linux/input.h>
- #include <linux/slab.h>
--#include <media/ir-common.h>
-+#include <media/ir-core.h>
- #include <media/v4l2-subdev.h>
-
- #include "cx23885.h"
-
--#define RC5_BITS 14
--#define RC5_HALF_BITS (2*RC5_BITS)
--#define RC5_HALF_BITS_MASK ((1 << RC5_HALF_BITS) - 1)
--
--#define RC5_START_BITS_NORMAL 0x3 /* Command range 0 - 63 */
--#define RC5_START_BITS_EXTENDED 0x2 /* Command range 64 - 127 */
--
--#define RC5_EXTENDED_COMMAND_OFFSET 64
--
- #define MODULE_NAME "cx23885"
-
--static inline unsigned int rc5_command(u32 rc5_baseband)
-+static void convert_measurement(u32 x, struct ir_raw_event *y)
- {
-- return RC5_INSTR(rc5_baseband) +
-- ((RC5_START(rc5_baseband) == RC5_START_BITS_EXTENDED)
-- ? RC5_EXTENDED_COMMAND_OFFSET : 0);
--}
--
--static void cx23885_input_process_raw_rc5(struct cx23885_dev *dev)
--{
-- struct card_ir *ir_input = dev->ir_input;
-- unsigned int code, command;
-- u32 rc5;
--
-- /* Ignore codes that are too short to be valid RC-5 */
-- if (ir_input->last_bit < (RC5_HALF_BITS - 1))
-- return;
--
-- /* The library has the manchester coding backwards; XOR to adapt. */
-- code = (ir_input->code & RC5_HALF_BITS_MASK) ^ RC5_HALF_BITS_MASK;
-- rc5 = ir_rc5_decode(code);
--
-- switch (RC5_START(rc5)) {
-- case RC5_START_BITS_NORMAL:
-- break;
-- case RC5_START_BITS_EXTENDED:
-- /* Don't allow if the remote only emits standard commands */
-- if (ir_input->start == RC5_START_BITS_NORMAL)
-- return;
-- break;
-- default:
-+ if (x == V4L2_SUBDEV_IR_PULSE_RX_SEQ_END) {
-+ y->pulse = false;
-+ y->duration = V4L2_SUBDEV_IR_PULSE_MAX_WIDTH_NS;
- return;
- }
-
-- if (ir_input->addr != RC5_ADDR(rc5))
-- return;
--
-- /* Don't generate a keypress for RC-5 auto-repeated keypresses */
-- command = rc5_command(rc5);
-- if (RC5_TOGGLE(rc5) != RC5_TOGGLE(ir_input->last_rc5) ||
-- command != rc5_command(ir_input->last_rc5) ||
-- /* Catch T == 0, CMD == 0 (e.g. '0') as first keypress after init */
-- RC5_START(ir_input->last_rc5) == 0) {
-- /* This keypress is differnet: not an auto repeat */
-- ir_input_nokey(ir_input->dev, &ir_input->ir);
-- ir_input_keydown(ir_input->dev, &ir_input->ir, command);
-- }
-- ir_input->last_rc5 = rc5;
--
-- /* Schedule when we should do the key up event: ir_input_nokey() */
-- mod_timer(&ir_input->timer_keyup,
-- jiffies + msecs_to_jiffies(ir_input->rc5_key_timeout));
-+ y->pulse = (x & V4L2_SUBDEV_IR_PULSE_LEVEL_MASK) ? true : false;
-+ y->duration = x & V4L2_SUBDEV_IR_PULSE_MAX_WIDTH_NS;
- }
-
--static void cx23885_input_next_pulse_width_rc5(struct cx23885_dev *dev,
-- u32 ns_pulse)
-+static void cx23885_input_process_measurements(struct cx23885_dev *dev,
-+ bool overrun)
- {
-- const int rc5_quarterbit_ns = 444444; /* 32 cycles/36 kHz/2 = 444 us */
-- struct card_ir *ir_input = dev->ir_input;
-- int i, level, quarterbits, halfbits;
--
-- if (!ir_input->active) {
-- ir_input->active = 1;
-- /* assume an initial space that we may not detect or measure */
-- ir_input->code = 0;
-- ir_input->last_bit = 0;
-- }
-+ struct cx23885_kernel_ir *kernel_ir = dev->kernel_ir;
-+ struct ir_raw_event kernel_ir_event;
-
-- if (ns_pulse == V4L2_SUBDEV_IR_PULSE_RX_SEQ_END) {
-- ir_input->last_bit++; /* Account for the final space */
-- ir_input->active = 0;
-- cx23885_input_process_raw_rc5(dev);
-- return;
-- }
--
-- level = (ns_pulse & V4L2_SUBDEV_IR_PULSE_LEVEL_MASK) ? 1 : 0;
--
-- /* Skip any leading space to sync to the start bit */
-- if (ir_input->last_bit == 0 && level == 0)
-- return;
--
-- /*
-- * With valid RC-5 we can get up to two consecutive half-bits in a
-- * single pulse measurment. Experiments have shown that the duration
-- * of a half-bit can vary. Make sure we always end up with an even
-- * number of quarter bits at the same level (mark or space).
-- */
-- ns_pulse &= V4L2_SUBDEV_IR_PULSE_MAX_WIDTH_NS;
-- quarterbits = ns_pulse / rc5_quarterbit_ns;
-- if (quarterbits & 1)
-- quarterbits++;
-- halfbits = quarterbits / 2;
--
-- for (i = 0; i < halfbits; i++) {
-- ir_input->last_bit++;
-- ir_input->code |= (level << ir_input->last_bit);
--
-- if (ir_input->last_bit >= RC5_HALF_BITS-1) {
-- ir_input->active = 0;
-- cx23885_input_process_raw_rc5(dev);
-- /*
-- * If level is 1, a leading mark is invalid for RC5.
-- * If level is 0, we scan past extra intial space.
-- * Either way we don't want to reactivate collecting
-- * marks or spaces here with any left over half-bits.
-- */
-- break;
-- }
-- }
--}
--
--static void cx23885_input_process_pulse_widths_rc5(struct cx23885_dev *dev,
-- bool add_eom)
--{
-- struct card_ir *ir_input = dev->ir_input;
-- struct ir_input_state *ir_input_state = &ir_input->ir;
--
-- u32 ns_pulse[RC5_HALF_BITS+1];
-- ssize_t num = 0;
-+ u32 sd_ir_data[64];
-+ ssize_t num;
- int count, i;
-+ bool handle = false;
-
- do {
-- v4l2_subdev_call(dev->sd_ir, ir, rx_read, (u8 *) ns_pulse,
-- sizeof(ns_pulse), &num);
-+ num = 0;
-+ v4l2_subdev_call(dev->sd_ir, ir, rx_read, (u8 *) sd_ir_data,
-+ sizeof(sd_ir_data), &num);
-
- count = num / sizeof(u32);
-
-- /* Append an end of Rx seq, if the caller requested */
-- if (add_eom && count < ARRAY_SIZE(ns_pulse)) {
-- ns_pulse[count] = V4L2_SUBDEV_IR_PULSE_RX_SEQ_END;
-- count++;
-+ for (i = 0; i < count; i++) {
-+ convert_measurement(sd_ir_data[i], &kernel_ir_event);
-+ ir_raw_event_store(kernel_ir->inp_dev,
-+ &kernel_ir_event);
-+ handle = true;
- }
--
-- /* Just drain the Rx FIFO, if we're called, but not RC-5 */
-- if (ir_input_state->ir_type != IR_TYPE_RC5)
-- continue;
--
-- for (i = 0; i < count; i++)
-- cx23885_input_next_pulse_width_rc5(dev, ns_pulse[i]);
- } while (num != 0);
-+
-+ if (overrun)
-+ ir_raw_event_reset(kernel_ir->inp_dev);
-+ else if (handle)
-+ ir_raw_event_handle(kernel_ir->inp_dev);
- }
-
- void cx23885_input_rx_work_handler(struct cx23885_dev *dev, u32 events)
-@@ -230,7 +124,7 @@ void cx23885_input_rx_work_handler(struct cx23885_dev *dev, u32 events)
- }
-
- if (data_available)
-- cx23885_input_process_pulse_widths_rc5(dev, overrun);
-+ cx23885_input_process_measurements(dev, overrun);
-
- if (overrun) {
- /* If there was a FIFO overrun, clear & restart the device */
-@@ -241,34 +135,15 @@ void cx23885_input_rx_work_handler(struct cx23885_dev *dev, u32 events)
- }
- }
-
--static void cx23885_input_ir_start(struct cx23885_dev *dev)
-+static int cx23885_input_ir_start(struct cx23885_dev *dev)
- {
-- struct card_ir *ir_input = dev->ir_input;
-- struct ir_input_state *ir_input_state = &ir_input->ir;
- struct v4l2_subdev_ir_parameters params;
-
- if (dev->sd_ir == NULL)
-- return;
-+ return -ENODEV;
-
- atomic_set(&dev->ir_input_stopping, 0);
-
-- /* keyup timer set up, if needed */
-- switch (dev->board) {
-- case CX23885_BOARD_HAUPPAUGE_HVR1850:
-- case CX23885_BOARD_HAUPPAUGE_HVR1290:
-- setup_timer(&ir_input->timer_keyup,
-- ir_rc5_timer_keyup, /* Not actually RC-5 specific */
-- (unsigned long) ir_input);
-- if (ir_input_state->ir_type == IR_TYPE_RC5) {
-- /*
-- * RC-5 repeats a held key every
-- * 64 bits * (2 * 32/36000) sec/bit = 113.778 ms
-- */
-- ir_input->rc5_key_timeout = 115;
-- }
-- break;
-- }
--
- v4l2_subdev_call(dev->sd_ir, ir, rx_g_parameters, &params);
- switch (dev->board) {
- case CX23885_BOARD_HAUPPAUGE_HVR1850:
-@@ -299,11 +174,21 @@ static void cx23885_input_ir_start(struct cx23885_dev *dev)
- break;
- }
- v4l2_subdev_call(dev->sd_ir, ir, rx_s_parameters, &params);
-+ return 0;
-+}
-+
-+static int cx23885_input_ir_open(void *priv)
-+{
-+ struct cx23885_kernel_ir *kernel_ir = priv;
-+
-+ if (kernel_ir->cx == NULL)
-+ return -ENODEV;
-+
-+ return cx23885_input_ir_start(kernel_ir->cx);
- }
-
- static void cx23885_input_ir_stop(struct cx23885_dev *dev)
- {
-- struct card_ir *ir_input = dev->ir_input;
- struct v4l2_subdev_ir_parameters params;
-
- if (dev->sd_ir == NULL)
-@@ -327,21 +212,26 @@ static void cx23885_input_ir_stop(struct cx23885_dev *dev)
- }
-
- flush_scheduled_work();
-+}
-
-- switch (dev->board) {
-- case CX23885_BOARD_HAUPPAUGE_HVR1850:
-- case CX23885_BOARD_HAUPPAUGE_HVR1290:
-- del_timer_sync(&ir_input->timer_keyup);
-- break;
-- }
-+static void cx23885_input_ir_close(void *priv)
-+{
-+ struct cx23885_kernel_ir *kernel_ir = priv;
-+
-+ if (kernel_ir->cx != NULL)
-+ cx23885_input_ir_stop(kernel_ir->cx);
- }
-
- int cx23885_input_init(struct cx23885_dev *dev)
- {
-- struct card_ir *ir;
-- struct input_dev *input_dev;
-- char *ir_codes = NULL;
-- int ir_type, ir_addr, ir_start;
-+ struct cx23885_kernel_ir *kernel_ir;
-+ struct input_dev *inp_dev;
-+ struct ir_dev_props *props;
-+
-+ char *rc_map;
-+ enum rc_driver_type driver_type;
-+ unsigned long allowed_protos;
-+
- int ret;
-
- /*
-@@ -354,53 +244,59 @@ int cx23885_input_init(struct cx23885_dev *dev)
- switch (dev->board) {
- case CX23885_BOARD_HAUPPAUGE_HVR1850:
- case CX23885_BOARD_HAUPPAUGE_HVR1290:
-- /* Parameters for the grey Hauppauge remote for the HVR-1850 */
-- ir_codes = RC_MAP_HAUPPAUGE_NEW;
-- ir_type = IR_TYPE_RC5;
-- ir_addr = 0x1e; /* RC-5 system bits emitted by the remote */
-- ir_start = RC5_START_BITS_NORMAL; /* A basic RC-5 remote */
-+ /* Integrated CX23888 IR controller */
-+ driver_type = RC_DRIVER_IR_RAW;
-+ allowed_protos = IR_TYPE_ALL;
-+ /* The grey Hauppauge RC-5 remote */
-+ rc_map = RC_MAP_RC5_HAUPPAUGE_NEW;
- break;
-- }
-- if (ir_codes == NULL)
-+ default:
- return -ENODEV;
--
-- ir = kzalloc(sizeof(*ir), GFP_KERNEL);
-- input_dev = input_allocate_device();
-- if (!ir || !input_dev) {
-- ret = -ENOMEM;
-- goto err_out_free;
- }
-
-- ir->dev = input_dev;
-- ir->addr = ir_addr;
-- ir->start = ir_start;
-+ /* cx23885 board instance kernel IR state */
-+ kernel_ir = kzalloc(sizeof(struct cx23885_kernel_ir), GFP_KERNEL);
-+ if (kernel_ir == NULL)
-+ return -ENOMEM;
-
-- /* init input device */
-- snprintf(ir->name, sizeof(ir->name), "cx23885 IR (%s)",
-- cx23885_boards[dev->board].name);
-- snprintf(ir->phys, sizeof(ir->phys), "pci-%s/ir0", pci_name(dev->pci));
-+ kernel_ir->cx = dev;
-+ kernel_ir->name = kasprintf(GFP_KERNEL, "cx23885 IR (%s)",
-+ cx23885_boards[dev->board].name);
-+ kernel_ir->phys = kasprintf(GFP_KERNEL, "pci-%s/ir0",
-+ pci_name(dev->pci));
-
-- ret = ir_input_init(input_dev, &ir->ir, ir_type);
-- if (ret < 0)
-+ /* input device */
-+ inp_dev = input_allocate_device();
-+ if (inp_dev == NULL) {
-+ ret = -ENOMEM;
- goto err_out_free;
-+ }
-
-- input_dev->name = ir->name;
-- input_dev->phys = ir->phys;
-- input_dev->id.bustype = BUS_PCI;
-- input_dev->id.version = 1;
-+ kernel_ir->inp_dev = inp_dev;
-+ inp_dev->name = kernel_ir->name;
-+ inp_dev->phys = kernel_ir->phys;
-+ inp_dev->id.bustype = BUS_PCI;
-+ inp_dev->id.version = 1;
- if (dev->pci->subsystem_vendor) {
-- input_dev->id.vendor = dev->pci->subsystem_vendor;
-- input_dev->id.product = dev->pci->subsystem_device;
-+ inp_dev->id.vendor = dev->pci->subsystem_vendor;
-+ inp_dev->id.product = dev->pci->subsystem_device;
- } else {
-- input_dev->id.vendor = dev->pci->vendor;
-- input_dev->id.product = dev->pci->device;
-+ inp_dev->id.vendor = dev->pci->vendor;
-+ inp_dev->id.product = dev->pci->device;
- }
-- input_dev->dev.parent = &dev->pci->dev;
--
-- dev->ir_input = ir;
-- cx23885_input_ir_start(dev);
--
-- ret = ir_input_register(ir->dev, ir_codes, NULL, MODULE_NAME);
-+ inp_dev->dev.parent = &dev->pci->dev;
-+
-+ /* kernel ir device properties */
-+ props = &kernel_ir->props;
-+ props->driver_type = driver_type;
-+ props->allowed_protos = allowed_protos;
-+ props->priv = kernel_ir;
-+ props->open = cx23885_input_ir_open;
-+ props->close = cx23885_input_ir_close;
-+
-+ /* Go */
-+ dev->kernel_ir = kernel_ir;
-+ ret = ir_input_register(inp_dev, rc_map, props, MODULE_NAME);
- if (ret)
- goto err_out_stop;
-
-@@ -408,9 +304,12 @@ int cx23885_input_init(struct cx23885_dev *dev)
-
- err_out_stop:
- cx23885_input_ir_stop(dev);
-- dev->ir_input = NULL;
-+ dev->kernel_ir = NULL;
-+ /* TODO: double check clean-up of kernel_ir->inp_dev */
- err_out_free:
-- kfree(ir);
-+ kfree(kernel_ir->phys);
-+ kfree(kernel_ir->name);
-+ kfree(kernel_ir);
- return ret;
- }
-
-@@ -419,9 +318,11 @@ void cx23885_input_fini(struct cx23885_dev *dev)
- /* Always stop the IR hardware from generating interrupts */
- cx23885_input_ir_stop(dev);
-
-- if (dev->ir_input == NULL)
-+ if (dev->kernel_ir == NULL)
- return;
-- ir_input_unregister(dev->ir_input->dev);
-- kfree(dev->ir_input);
-- dev->ir_input = NULL;
-+ ir_input_unregister(dev->kernel_ir->inp_dev);
-+ kfree(dev->kernel_ir->phys);
-+ kfree(dev->kernel_ir->name);
-+ kfree(dev->kernel_ir);
-+ dev->kernel_ir = NULL;
- }
-diff --git a/drivers/media/video/cx23885/cx23885-ir.c b/drivers/media/video/cx23885/cx23885-ir.c
-index 9a677eb..6ceabd4 100644
---- a/drivers/media/video/cx23885/cx23885-ir.c
-+++ b/drivers/media/video/cx23885/cx23885-ir.c
-@@ -53,7 +53,7 @@ void cx23885_ir_rx_work_handler(struct work_struct *work)
- if (events == 0)
- return;
-
-- if (dev->ir_input)
-+ if (dev->kernel_ir)
- cx23885_input_rx_work_handler(dev, events);
- }
-
-diff --git a/drivers/media/video/cx23885/cx23885.h b/drivers/media/video/cx23885/cx23885.h
-index 8d6a55e..a33f2b7 100644
---- a/drivers/media/video/cx23885/cx23885.h
-+++ b/drivers/media/video/cx23885/cx23885.h
-@@ -30,6 +30,7 @@
- #include <media/tveeprom.h>
- #include <media/videobuf-dma-sg.h>
- #include <media/videobuf-dvb.h>
-+#include <media/ir-core.h>
-
- #include "btcx-risc.h"
- #include "cx23885-reg.h"
-@@ -304,6 +305,15 @@ struct cx23885_tsport {
- void *port_priv;
- };
-
-+struct cx23885_kernel_ir {
-+ struct cx23885_dev *cx;
-+ char *name;
-+ char *phys;
-+
-+ struct input_dev *inp_dev;
-+ struct ir_dev_props props;
-+};
-+
- struct cx23885_dev {
- atomic_t refcount;
- struct v4l2_device v4l2_dev;
-@@ -363,7 +373,7 @@ struct cx23885_dev {
- struct work_struct ir_tx_work;
- unsigned long ir_tx_notifications;
-
-- struct card_ir *ir_input;
-+ struct cx23885_kernel_ir *kernel_ir;
- atomic_t ir_input_stopping;
-
- /* V4l */
-diff --git a/drivers/media/video/cx88/cx88-cards.c b/drivers/media/video/cx88/cx88-cards.c
-index 2918a6e..e8416b7 100644
---- a/drivers/media/video/cx88/cx88-cards.c
-+++ b/drivers/media/video/cx88/cx88-cards.c
-@@ -45,6 +45,10 @@ static unsigned int latency = UNSET;
- module_param(latency,int,0444);
- MODULE_PARM_DESC(latency,"pci latency timer");
-
-+static int disable_ir;
-+module_param(disable_ir, int, 0444);
-+MODULE_PARM_DESC(latency, "Disable IR support");
-+
- #define info_printk(core, fmt, arg...) \
- printk(KERN_INFO "%s: " fmt, core->name , ## arg)
-
-@@ -3498,7 +3502,10 @@ struct cx88_core *cx88_core_create(struct pci_dev *pci, int nr)
- }
-
- cx88_card_setup(core);
-- cx88_ir_init(core, pci);
-+ if (!disable_ir) {
-+ cx88_i2c_init_ir(core);
-+ cx88_ir_init(core, pci);
-+ }
-
- return core;
- }
-diff --git a/drivers/media/video/cx88/cx88-i2c.c b/drivers/media/video/cx88/cx88-i2c.c
-index fb39f11..375ad53 100644
---- a/drivers/media/video/cx88/cx88-i2c.c
-+++ b/drivers/media/video/cx88/cx88-i2c.c
-@@ -181,6 +181,11 @@ int cx88_i2c_init(struct cx88_core *core, struct pci_dev *pci)
- } else
- printk("%s: i2c register FAILED\n", core->name);
-
-+ return core->i2c_rc;
-+}
-+
-+void cx88_i2c_init_ir(struct cx88_core *core)
-+{
- /* Instantiate the IR receiver device, if present */
- if (0 == core->i2c_rc) {
- struct i2c_board_info info;
-@@ -207,7 +212,6 @@ int cx88_i2c_init(struct cx88_core *core, struct pci_dev *pci)
- }
- }
- }
-- return core->i2c_rc;
- }
-
- /* ----------------------------------------------------------------------- */
-diff --git a/drivers/media/video/cx88/cx88-input.c b/drivers/media/video/cx88/cx88-input.c
-index e185289..eccc5e4 100644
---- a/drivers/media/video/cx88/cx88-input.c
-+++ b/drivers/media/video/cx88/cx88-input.c
-@@ -30,6 +30,7 @@
- #include <linux/module.h>
-
- #include "cx88.h"
-+#include <media/ir-core.h>
- #include <media/ir-common.h>
-
- #define MODULE_NAME "cx88xx"
-@@ -39,8 +40,8 @@
- struct cx88_IR {
- struct cx88_core *core;
- struct input_dev *input;
-- struct ir_input_state ir;
- struct ir_dev_props props;
-+ u64 ir_type;
-
- int users;
-
-@@ -51,7 +52,6 @@ struct cx88_IR {
- u32 sampling;
- u32 samples[16];
- int scount;
-- unsigned long release;
-
- /* poll external decoder */
- int polling;
-@@ -125,29 +125,21 @@ static void cx88_ir_handle_key(struct cx88_IR *ir)
-
- data = (data << 4) | ((gpio_key & 0xf0) >> 4);
-
-- ir_input_keydown(ir->input, &ir->ir, data);
-- ir_input_nokey(ir->input, &ir->ir);
-+ ir_keydown(ir->input, data, 0);
-
- } else if (ir->mask_keydown) {
- /* bit set on keydown */
-- if (gpio & ir->mask_keydown) {
-- ir_input_keydown(ir->input, &ir->ir, data);
-- } else {
-- ir_input_nokey(ir->input, &ir->ir);
-- }
-+ if (gpio & ir->mask_keydown)
-+ ir_keydown(ir->input, data, 0);
-
- } else if (ir->mask_keyup) {
- /* bit cleared on keydown */
-- if (0 == (gpio & ir->mask_keyup)) {
-- ir_input_keydown(ir->input, &ir->ir, data);
-- } else {
-- ir_input_nokey(ir->input, &ir->ir);
-- }
-+ if (0 == (gpio & ir->mask_keyup))
-+ ir_keydown(ir->input, data, 0);
-
- } else {
- /* can't distinguish keydown/up :-/ */
-- ir_input_keydown(ir->input, &ir->ir, data);
-- ir_input_nokey(ir->input, &ir->ir);
-+ ir_keydown(ir->input, data, 0);
- }
- }
-
-@@ -439,9 +431,7 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci)
- snprintf(ir->name, sizeof(ir->name), "cx88 IR (%s)", core->board.name);
- snprintf(ir->phys, sizeof(ir->phys), "pci-%s/ir0", pci_name(pci));
-
-- err = ir_input_init(input_dev, &ir->ir, ir_type);
-- if (err < 0)
-- goto err_out_free;
-+ ir->ir_type = ir_type;
-
- input_dev->name = ir->name;
- input_dev->phys = ir->phys;
-@@ -516,8 +506,6 @@ void cx88_ir_irq(struct cx88_core *core)
- }
- if (!ir->scount) {
- /* nothing to sample */
-- if (ir->ir.keypressed && time_after(jiffies, ir->release))
-- ir_input_nokey(ir->input, &ir->ir);
- return;
- }
-
-@@ -553,7 +541,7 @@ void cx88_ir_irq(struct cx88_core *core)
-
- if (ircode == 0) { /* key still pressed */
- ir_dprintk("pulse distance decoded repeat code\n");
-- ir->release = jiffies + msecs_to_jiffies(120);
-+ ir_repeat(ir->input);
- break;
- }
-
-@@ -567,10 +555,8 @@ void cx88_ir_irq(struct cx88_core *core)
- break;
- }
-
-- ir_dprintk("Key Code: %x\n", (ircode >> 16) & 0x7f);
--
-- ir_input_keydown(ir->input, &ir->ir, (ircode >> 16) & 0x7f);
-- ir->release = jiffies + msecs_to_jiffies(120);
-+ ir_dprintk("Key Code: %x\n", (ircode >> 16) & 0xff);
-+ ir_keydown(ir->input, (ircode >> 16) & 0xff, 0);
- break;
- case CX88_BOARD_HAUPPAUGE:
- case CX88_BOARD_HAUPPAUGE_DVB_T1:
-@@ -606,16 +592,16 @@ void cx88_ir_irq(struct cx88_core *core)
- if ( dev != 0x1e && dev != 0x1f )
- /* not a hauppauge remote */
- break;
-- ir_input_keydown(ir->input, &ir->ir, code);
-- ir->release = jiffies + msecs_to_jiffies(120);
-+ ir_keydown(ir->input, code, toggle);
- break;
- case CX88_BOARD_PINNACLE_PCTV_HD_800i:
- ircode = ir_decode_biphase(ir->samples, ir->scount, 5, 7);
- ir_dprintk("biphase decoded: %x\n", ircode);
- if ((ircode & 0xfffff000) != 0x3000)
- break;
-- ir_input_keydown(ir->input, &ir->ir, ircode & 0x3f);
-- ir->release = jiffies + msecs_to_jiffies(120);
-+ /* Note: bit 0x800 being the toggle is assumed, not checked
-+ with real hardware */
-+ ir_keydown(ir->input, ircode & 0x3f, ircode & 0x0800 ? 1 : 0);
- break;
- }
-
-diff --git a/drivers/media/video/cx88/cx88.h b/drivers/media/video/cx88/cx88.h
-index bdb03d3..33d161a 100644
---- a/drivers/media/video/cx88/cx88.h
-+++ b/drivers/media/video/cx88/cx88.h
-@@ -636,6 +636,7 @@ extern struct videobuf_queue_ops cx8800_vbi_qops;
- /* cx88-i2c.c */
-
- extern int cx88_i2c_init(struct cx88_core *core, struct pci_dev *pci);
-+extern void cx88_i2c_init_ir(struct cx88_core *core);
-
-
- /* ----------------------------------------------------------- */
-diff --git a/drivers/media/video/em28xx/em28xx-input.c b/drivers/media/video/em28xx/em28xx-input.c
-index 5c3fd94..6759cd5 100644
---- a/drivers/media/video/em28xx/em28xx-input.c
-+++ b/drivers/media/video/em28xx/em28xx-input.c
-@@ -65,17 +65,14 @@ struct em28xx_ir_poll_result {
- struct em28xx_IR {
- struct em28xx *dev;
- struct input_dev *input;
-- struct ir_input_state ir;
- char name[32];
- char phys[32];
-
- /* poll external decoder */
- int polling;
- struct delayed_work work;
-- unsigned int last_toggle:1;
- unsigned int full_code:1;
- unsigned int last_readcount;
-- unsigned int repeat_interval;
-
- int (*get_key)(struct em28xx_IR *, struct em28xx_ir_poll_result *);
-
-@@ -291,67 +288,39 @@ static int em2874_polling_getkey(struct em28xx_IR *ir,
- static void em28xx_ir_handle_key(struct em28xx_IR *ir)
- {
- int result;
-- int do_sendkey = 0;
- struct em28xx_ir_poll_result poll_result;
-
- /* read the registers containing the IR status */
- result = ir->get_key(ir, &poll_result);
-- if (result < 0) {
-+ if (unlikely(result < 0)) {
- dprintk("ir->get_key() failed %d\n", result);
- return;
- }
-
-- dprintk("ir->get_key result tb=%02x rc=%02x lr=%02x data=%02x%02x\n",
-- poll_result.toggle_bit, poll_result.read_count,
-- ir->last_readcount, poll_result.rc_address,
-- poll_result.rc_data[0]);
--
-- if (ir->dev->chip_id == CHIP_ID_EM2874) {
-- /* The em2874 clears the readcount field every time the
-- register is read. The em2860/2880 datasheet says that it
-- is supposed to clear the readcount, but it doesn't. So with
-- the em2874, we are looking for a non-zero read count as
-- opposed to a readcount that is incrementing */
-- ir->last_readcount = 0;
-- }
--
-- if (poll_result.read_count == 0) {
-- /* The button has not been pressed since the last read */
-- } else if (ir->last_toggle != poll_result.toggle_bit) {
-- /* A button has been pressed */
-- dprintk("button has been pressed\n");
-- ir->last_toggle = poll_result.toggle_bit;
-- ir->repeat_interval = 0;
-- do_sendkey = 1;
-- } else if (poll_result.toggle_bit == ir->last_toggle &&
-- poll_result.read_count > 0 &&
-- poll_result.read_count != ir->last_readcount) {
-- /* The button is still being held down */
-- dprintk("button being held down\n");
--
-- /* Debouncer for first keypress */
-- if (ir->repeat_interval++ > 9) {
-- /* Start repeating after 1 second */
-- do_sendkey = 1;
-- }
-- }
--
-- if (do_sendkey) {
-- dprintk("sending keypress\n");
--
-+ if (unlikely(poll_result.read_count != ir->last_readcount)) {
-+ dprintk("%s: toggle: %d, count: %d, key 0x%02x%02x\n", __func__,
-+ poll_result.toggle_bit, poll_result.read_count,
-+ poll_result.rc_address, poll_result.rc_data[0]);
- if (ir->full_code)
-- ir_input_keydown(ir->input, &ir->ir,
-- poll_result.rc_address << 8 |
-- poll_result.rc_data[0]);
-+ ir_keydown(ir->input,
-+ poll_result.rc_address << 8 |
-+ poll_result.rc_data[0],
-+ poll_result.toggle_bit);
- else
-- ir_input_keydown(ir->input, &ir->ir,
-- poll_result.rc_data[0]);
--
-- ir_input_nokey(ir->input, &ir->ir);
-+ ir_keydown(ir->input,
-+ poll_result.rc_data[0],
-+ poll_result.toggle_bit);
-+
-+ if (ir->dev->chip_id == CHIP_ID_EM2874)
-+ /* The em2874 clears the readcount field every time the
-+ register is read. The em2860/2880 datasheet says that it
-+ is supposed to clear the readcount, but it doesn't. So with
-+ the em2874, we are looking for a non-zero read count as
-+ opposed to a readcount that is incrementing */
-+ ir->last_readcount = 0;
-+ else
-+ ir->last_readcount = poll_result.read_count;
- }
--
-- ir->last_readcount = poll_result.read_count;
-- return;
- }
-
- static void em28xx_ir_work(struct work_struct *work)
-@@ -466,11 +435,6 @@ int em28xx_ir_init(struct em28xx *dev)
- usb_make_path(dev->udev, ir->phys, sizeof(ir->phys));
- strlcat(ir->phys, "/input0", sizeof(ir->phys));
-
-- /* Set IR protocol */
-- err = ir_input_init(input_dev, &ir->ir, IR_TYPE_OTHER);
-- if (err < 0)
-- goto err_out_free;
--
- input_dev->name = ir->name;
- input_dev->phys = ir->phys;
- input_dev->id.bustype = BUS_USB;
-diff --git a/drivers/media/video/em28xx/em28xx-video.c b/drivers/media/video/em28xx/em28xx-video.c
-index 20090e3..7b9ec6e 100644
---- a/drivers/media/video/em28xx/em28xx-video.c
-+++ b/drivers/media/video/em28xx/em28xx-video.c
-@@ -654,12 +654,12 @@ static inline int em28xx_isoc_copy_vbi(struct em28xx *dev, struct urb *urb)
- }
-
- if (buf != NULL && dev->capture_type == 2) {
-- if (len > 4 && p[0] == 0x88 && p[1] == 0x88 &&
-+ if (len >= 4 && p[0] == 0x88 && p[1] == 0x88 &&
- p[2] == 0x88 && p[3] == 0x88) {
- p += 4;
- len -= 4;
- }
-- if (len > 4 && p[0] == 0x22 && p[1] == 0x5a) {
-+ if (len >= 4 && p[0] == 0x22 && p[1] == 0x5a) {
- em28xx_isocdbg("Video frame %d, len=%i, %s\n",
- p[2], len, (p[2] & 1) ?
- "odd" : "even");
-diff --git a/drivers/media/video/em28xx/em28xx.h b/drivers/media/video/em28xx/em28xx.h
-index b252d1b..6216786 100644
---- a/drivers/media/video/em28xx/em28xx.h
-+++ b/drivers/media/video/em28xx/em28xx.h
-@@ -32,6 +32,7 @@
- #include <linux/i2c.h>
- #include <linux/mutex.h>
- #include <media/ir-kbd-i2c.h>
-+#include <media/ir-core.h>
- #if defined(CONFIG_VIDEO_EM28XX_DVB) || defined(CONFIG_VIDEO_EM28XX_DVB_MODULE)
- #include <media/videobuf-dvb.h>
- #endif
-diff --git a/drivers/media/video/hdpvr/hdpvr-core.c b/drivers/media/video/hdpvr/hdpvr-core.c
-index 830d47b..0cae5b8 100644
---- a/drivers/media/video/hdpvr/hdpvr-core.c
-+++ b/drivers/media/video/hdpvr/hdpvr-core.c
-@@ -286,6 +286,8 @@ static int hdpvr_probe(struct usb_interface *interface,
- goto error;
- }
-
-+ dev->workqueue = 0;
-+
- /* register v4l2_device early so it can be used for printks */
- if (v4l2_device_register(&interface->dev, &dev->v4l2_dev)) {
- err("v4l2_device_register failed");
-@@ -380,6 +382,9 @@ static int hdpvr_probe(struct usb_interface *interface,
-
- error:
- if (dev) {
-+ /* Destroy single thread */
-+ if (dev->workqueue)
-+ destroy_workqueue(dev->workqueue);
- /* this frees allocated memory */
- hdpvr_delete(dev);
- }
-diff --git a/drivers/media/video/ir-kbd-i2c.c b/drivers/media/video/ir-kbd-i2c.c
-index 29d4397..27ae8bb 100644
---- a/drivers/media/video/ir-kbd-i2c.c
-+++ b/drivers/media/video/ir-kbd-i2c.c
-@@ -47,7 +47,7 @@
- #include <linux/i2c-id.h>
- #include <linux/workqueue.h>
-
--#include <media/ir-common.h>
-+#include <media/ir-core.h>
- #include <media/ir-kbd-i2c.h>
-
- /* ----------------------------------------------------------------------- */
-@@ -272,11 +272,8 @@ static void ir_key_poll(struct IR_i2c *ir)
- return;
- }
-
-- if (0 == rc) {
-- ir_input_nokey(ir->input, &ir->ir);
-- } else {
-- ir_input_keydown(ir->input, &ir->ir, ir_key);
-- }
-+ if (rc)
-+ ir_keydown(ir->input, ir_key, 0);
- }
-
- static void ir_work(struct work_struct *work)
-@@ -439,10 +436,7 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id)
- dev_name(&client->dev));
-
- /* init + register input device */
-- err = ir_input_init(input_dev, &ir->ir, ir_type);
-- if (err < 0)
-- goto err_out_free;
--
-+ ir->ir_type = ir_type;
- input_dev->id.bustype = BUS_I2C;
- input_dev->name = ir->name;
- input_dev->phys = ir->phys;
-diff --git a/drivers/media/video/pvrusb2/pvrusb2-ioread.c b/drivers/media/video/pvrusb2/pvrusb2-ioread.c
-index b482478..bba6115 100644
---- a/drivers/media/video/pvrusb2/pvrusb2-ioread.c
-+++ b/drivers/media/video/pvrusb2/pvrusb2-ioread.c
-@@ -223,7 +223,10 @@ int pvr2_ioread_setup(struct pvr2_ioread *cp,struct pvr2_stream *sp)
- " pvr2_ioread_setup (setup) id=%p",cp);
- pvr2_stream_kill(sp);
- ret = pvr2_stream_set_buffer_count(sp,BUFFER_COUNT);
-- if (ret < 0) return ret;
-+ if (ret < 0) {
-+ mutex_unlock(&cp->mutex);
-+ return ret;
-+ }
- for (idx = 0; idx < BUFFER_COUNT; idx++) {
- bp = pvr2_stream_get_buffer(sp,idx);
- pvr2_buffer_set_buffer(bp,
-diff --git a/include/linux/input.h b/include/linux/input.h
-index 6fcc910..fe2633c 100644
---- a/include/linux/input.h
-+++ b/include/linux/input.h
-@@ -34,7 +34,7 @@ struct input_event {
- * Protocol version.
- */
-
--#define EV_VERSION 0x010000
-+#define EV_VERSION 0x010001
-
- /*
- * IOCTLs (0x00 - 0x7f)
-@@ -56,12 +56,22 @@ struct input_absinfo {
- __s32 resolution;
- };
-
-+struct keycode_table_entry {
-+ __u32 keycode; /* e.g. KEY_A */
-+ __u32 index; /* Index for the given scan/key table, on EVIOCGKEYCODEBIG */
-+ __u32 len; /* Length of the scancode */
-+ __u32 reserved[2]; /* Reserved for future usage */
-+ char *scancode; /* scancode, in machine-endian */
-+};
-+
- #define EVIOCGVERSION _IOR('E', 0x01, int) /* get driver version */
- #define EVIOCGID _IOR('E', 0x02, struct input_id) /* get device ID */
- #define EVIOCGREP _IOR('E', 0x03, unsigned int[2]) /* get repeat settings */
- #define EVIOCSREP _IOW('E', 0x03, unsigned int[2]) /* set repeat settings */
- #define EVIOCGKEYCODE _IOR('E', 0x04, unsigned int[2]) /* get keycode */
- #define EVIOCSKEYCODE _IOW('E', 0x04, unsigned int[2]) /* set keycode */
-+#define EVIOCGKEYCODEBIG _IOR('E', 0x04, struct keycode_table_entry) /* get keycode */
-+#define EVIOCSKEYCODEBIG _IOW('E', 0x04, struct keycode_table_entry) /* set keycode */
-
- #define EVIOCGNAME(len) _IOC(_IOC_READ, 'E', 0x06, len) /* get device name */
- #define EVIOCGPHYS(len) _IOC(_IOC_READ, 'E', 0x07, len) /* get physical location */
-@@ -1066,13 +1076,22 @@ struct ff_effect {
- * @keycodemax: size of keycode table
- * @keycodesize: size of elements in keycode table
- * @keycode: map of scancodes to keycodes for this device
-- * @setkeycode: optional method to alter current keymap, used to implement
-+ * @setkeycode: optional legacy method to alter current keymap, used to
-+ * implement sparse keymaps. Shouldn't be used on new drivers
-+ * @getkeycode: optional legacy method to retrieve current keymap.
-+ * Shouldn't be used on new drivers.
-+ * @setkeycodebig: optional method to alter current keymap, used to implement
- * sparse keymaps. If not supplied default mechanism will be used.
- * The method is being called while holding event_lock and thus must
- * not sleep
-- * @getkeycode: optional method to retrieve current keymap. If not supplied
-- * default mechanism will be used. The method is being called while
-- * holding event_lock and thus must not sleep
-+ * @getkeycodebig_from_index: optional method to retrieve current keymap from
-+ * an array index. If not supplied default mechanism will be used.
-+ * The method is being called while holding event_lock and thus must
-+ * not sleep
-+ * @getkeycodebig_from_scancode: optional method to retrieve current keymap
-+ * from an scancode. If not supplied default mechanism will be used.
-+ * The method is being called while holding event_lock and thus must
-+ * not sleep
- * @ff: force feedback structure associated with the device if device
- * supports force feedback effects
- * @repeat_key: stores key code of the last key pressed; used to implement
-@@ -1147,6 +1166,12 @@ struct input_dev {
- unsigned int scancode, unsigned int keycode);
- int (*getkeycode)(struct input_dev *dev,
- unsigned int scancode, unsigned int *keycode);
-+ int (*setkeycodebig)(struct input_dev *dev,
-+ struct keycode_table_entry *kt_entry);
-+ int (*getkeycodebig_from_index)(struct input_dev *dev,
-+ struct keycode_table_entry *kt_entry);
-+ int (*getkeycodebig_from_scancode)(struct input_dev *dev,
-+ struct keycode_table_entry *kt_entry);
-
- struct ff_device *ff;
-
-@@ -1422,6 +1447,10 @@ int input_get_keycode(struct input_dev *dev,
- unsigned int scancode, unsigned int *keycode);
- int input_set_keycode(struct input_dev *dev,
- unsigned int scancode, unsigned int keycode);
-+int input_get_keycode_big(struct input_dev *dev,
-+ struct keycode_table_entry *kt_entry);
-+int input_set_keycode_big(struct input_dev *dev,
-+ struct keycode_table_entry *kt_entry);
-
- extern struct class input_class;
-
-diff --git a/include/media/ir-core.h b/include/media/ir-core.h
-index ad1303f..513e60d 100644
---- a/include/media/ir-core.h
-+++ b/include/media/ir-core.h
-@@ -47,15 +47,21 @@ enum rc_driver_type {
- * is opened.
- * @close: callback to allow drivers to disable polling/irq when IR input device
- * is opened.
-+ * @s_tx_mask: set transmitter mask (for devices with multiple tx outputs)
-+ * @s_tx_carrier: set transmit carrier frequency
-+ * @tx_ir: transmit IR
- */
- struct ir_dev_props {
- enum rc_driver_type driver_type;
- unsigned long allowed_protos;
- u32 scanmask;
-- void *priv;
-+ void *priv;
- int (*change_protocol)(void *priv, u64 ir_type);
- int (*open)(void *priv);
- void (*close)(void *priv);
-+ int (*s_tx_mask)(void *priv, u32 mask);
-+ int (*s_tx_carrier)(void *priv, u32 carrier);
-+ int (*tx_ir)(void *priv, int *txbuf, u32 n);
- };
-
- struct ir_input_dev {
-diff --git a/include/media/ir-kbd-i2c.h b/include/media/ir-kbd-i2c.h
-index 0506e45..5e96d7a 100644
---- a/include/media/ir-kbd-i2c.h
-+++ b/include/media/ir-kbd-i2c.h
-@@ -11,7 +11,7 @@ struct IR_i2c {
- struct i2c_client *c;
- struct input_dev *input;
- struct ir_input_state ir;
--
-+ u64 ir_type;
- /* Used to avoid fast repeating */
- unsigned char old;
-
-diff --git a/include/media/lirc.h b/include/media/lirc.h
-new file mode 100644
-index 0000000..42c467c
---- /dev/null
-+++ b/include/media/lirc.h
-@@ -0,0 +1,165 @@
-+/*
-+ * lirc.h - linux infrared remote control header file
-+ * last modified 2010/07/13 by Jarod Wilson
-+ */
-+
-+#ifndef _LINUX_LIRC_H
-+#define _LINUX_LIRC_H
-+
-+#include <linux/types.h>
-+#include <linux/ioctl.h>
-+
-+#define PULSE_BIT 0x01000000
-+#define PULSE_MASK 0x00FFFFFF
-+
-+#define LIRC_MODE2_SPACE 0x00000000
-+#define LIRC_MODE2_PULSE 0x01000000
-+#define LIRC_MODE2_FREQUENCY 0x02000000
-+#define LIRC_MODE2_TIMEOUT 0x03000000
-+
-+#define LIRC_VALUE_MASK 0x00FFFFFF
-+#define LIRC_MODE2_MASK 0xFF000000
-+
-+#define LIRC_SPACE(val) (((val)&LIRC_VALUE_MASK) | LIRC_MODE2_SPACE)
-+#define LIRC_PULSE(val) (((val)&LIRC_VALUE_MASK) | LIRC_MODE2_PULSE)
-+#define LIRC_FREQUENCY(val) (((val)&LIRC_VALUE_MASK) | LIRC_MODE2_FREQUENCY)
-+#define LIRC_TIMEOUT(val) (((val)&LIRC_VALUE_MASK) | LIRC_MODE2_TIMEOUT)
-+
-+#define LIRC_VALUE(val) ((val)&LIRC_VALUE_MASK)
-+#define LIRC_MODE2(val) ((val)&LIRC_MODE2_MASK)
-+
-+#define LIRC_IS_SPACE(val) (LIRC_MODE2(val) == LIRC_MODE2_SPACE)
-+#define LIRC_IS_PULSE(val) (LIRC_MODE2(val) == LIRC_MODE2_PULSE)
-+#define LIRC_IS_FREQUENCY(val) (LIRC_MODE2(val) == LIRC_MODE2_FREQUENCY)
-+#define LIRC_IS_TIMEOUT(val) (LIRC_MODE2(val) == LIRC_MODE2_TIMEOUT)
-+
-+/* used heavily by lirc userspace */
-+#define lirc_t int
-+
-+/*** lirc compatible hardware features ***/
-+
-+#define LIRC_MODE2SEND(x) (x)
-+#define LIRC_SEND2MODE(x) (x)
-+#define LIRC_MODE2REC(x) ((x) << 16)
-+#define LIRC_REC2MODE(x) ((x) >> 16)
-+
-+#define LIRC_MODE_RAW 0x00000001
-+#define LIRC_MODE_PULSE 0x00000002
-+#define LIRC_MODE_MODE2 0x00000004
-+#define LIRC_MODE_LIRCCODE 0x00000010
-+
-+
-+#define LIRC_CAN_SEND_RAW LIRC_MODE2SEND(LIRC_MODE_RAW)
-+#define LIRC_CAN_SEND_PULSE LIRC_MODE2SEND(LIRC_MODE_PULSE)
-+#define LIRC_CAN_SEND_MODE2 LIRC_MODE2SEND(LIRC_MODE_MODE2)
-+#define LIRC_CAN_SEND_LIRCCODE LIRC_MODE2SEND(LIRC_MODE_LIRCCODE)
-+
-+#define LIRC_CAN_SEND_MASK 0x0000003f
-+
-+#define LIRC_CAN_SET_SEND_CARRIER 0x00000100
-+#define LIRC_CAN_SET_SEND_DUTY_CYCLE 0x00000200
-+#define LIRC_CAN_SET_TRANSMITTER_MASK 0x00000400
-+
-+#define LIRC_CAN_REC_RAW LIRC_MODE2REC(LIRC_MODE_RAW)
-+#define LIRC_CAN_REC_PULSE LIRC_MODE2REC(LIRC_MODE_PULSE)
-+#define LIRC_CAN_REC_MODE2 LIRC_MODE2REC(LIRC_MODE_MODE2)
-+#define LIRC_CAN_REC_LIRCCODE LIRC_MODE2REC(LIRC_MODE_LIRCCODE)
-+
-+#define LIRC_CAN_REC_MASK LIRC_MODE2REC(LIRC_CAN_SEND_MASK)
-+
-+#define LIRC_CAN_SET_REC_CARRIER (LIRC_CAN_SET_SEND_CARRIER << 16)
-+#define LIRC_CAN_SET_REC_DUTY_CYCLE (LIRC_CAN_SET_SEND_DUTY_CYCLE << 16)
-+
-+#define LIRC_CAN_SET_REC_DUTY_CYCLE_RANGE 0x40000000
-+#define LIRC_CAN_SET_REC_CARRIER_RANGE 0x80000000
-+#define LIRC_CAN_GET_REC_RESOLUTION 0x20000000
-+#define LIRC_CAN_SET_REC_TIMEOUT 0x10000000
-+#define LIRC_CAN_SET_REC_FILTER 0x08000000
-+
-+#define LIRC_CAN_MEASURE_CARRIER 0x02000000
-+
-+#define LIRC_CAN_SEND(x) ((x)&LIRC_CAN_SEND_MASK)
-+#define LIRC_CAN_REC(x) ((x)&LIRC_CAN_REC_MASK)
-+
-+#define LIRC_CAN_NOTIFY_DECODE 0x01000000
-+
-+/*** IOCTL commands for lirc driver ***/
-+
-+#define LIRC_GET_FEATURES _IOR('i', 0x00000000, __u32)
-+
-+#define LIRC_GET_SEND_MODE _IOR('i', 0x00000001, __u32)
-+#define LIRC_GET_REC_MODE _IOR('i', 0x00000002, __u32)
-+#define LIRC_GET_SEND_CARRIER _IOR('i', 0x00000003, __u32)
-+#define LIRC_GET_REC_CARRIER _IOR('i', 0x00000004, __u32)
-+#define LIRC_GET_SEND_DUTY_CYCLE _IOR('i', 0x00000005, __u32)
-+#define LIRC_GET_REC_DUTY_CYCLE _IOR('i', 0x00000006, __u32)
-+#define LIRC_GET_REC_RESOLUTION _IOR('i', 0x00000007, __u32)
-+
-+#define LIRC_GET_MIN_TIMEOUT _IOR('i', 0x00000008, __u32)
-+#define LIRC_GET_MAX_TIMEOUT _IOR('i', 0x00000009, __u32)
-+
-+#define LIRC_GET_MIN_FILTER_PULSE _IOR('i', 0x0000000a, __u32)
-+#define LIRC_GET_MAX_FILTER_PULSE _IOR('i', 0x0000000b, __u32)
-+#define LIRC_GET_MIN_FILTER_SPACE _IOR('i', 0x0000000c, __u32)
-+#define LIRC_GET_MAX_FILTER_SPACE _IOR('i', 0x0000000d, __u32)
-+
-+/* code length in bits, currently only for LIRC_MODE_LIRCCODE */
-+#define LIRC_GET_LENGTH _IOR('i', 0x0000000f, __u32)
-+
-+#define LIRC_SET_SEND_MODE _IOW('i', 0x00000011, __u32)
-+#define LIRC_SET_REC_MODE _IOW('i', 0x00000012, __u32)
-+/* Note: these can reset the according pulse_width */
-+#define LIRC_SET_SEND_CARRIER _IOW('i', 0x00000013, __u32)
-+#define LIRC_SET_REC_CARRIER _IOW('i', 0x00000014, __u32)
-+#define LIRC_SET_SEND_DUTY_CYCLE _IOW('i', 0x00000015, __u32)
-+#define LIRC_SET_REC_DUTY_CYCLE _IOW('i', 0x00000016, __u32)
-+#define LIRC_SET_TRANSMITTER_MASK _IOW('i', 0x00000017, __u32)
-+
-+/*
-+ * when a timeout != 0 is set the driver will send a
-+ * LIRC_MODE2_TIMEOUT data packet, otherwise LIRC_MODE2_TIMEOUT is
-+ * never sent, timeout is disabled by default
-+ */
-+#define LIRC_SET_REC_TIMEOUT _IOW('i', 0x00000018, __u32)
-+
-+/* 1 enables, 0 disables timeout reports in MODE2 */
-+#define LIRC_SET_REC_TIMEOUT_REPORTS _IOW('i', 0x00000019, __u32)
-+
-+/*
-+ * pulses shorter than this are filtered out by hardware (software
-+ * emulation in lirc_dev?)
-+ */
-+#define LIRC_SET_REC_FILTER_PULSE _IOW('i', 0x0000001a, __u32)
-+/*
-+ * spaces shorter than this are filtered out by hardware (software
-+ * emulation in lirc_dev?)
-+ */
-+#define LIRC_SET_REC_FILTER_SPACE _IOW('i', 0x0000001b, __u32)
-+/*
-+ * if filter cannot be set independantly for pulse/space, this should
-+ * be used
-+ */
-+#define LIRC_SET_REC_FILTER _IOW('i', 0x0000001c, __u32)
-+
-+/*
-+ * if enabled from the next key press on the driver will send
-+ * LIRC_MODE2_FREQUENCY packets
-+ */
-+#define LIRC_SET_MEASURE_CARRIER_MODE _IOW('i', 0x0000001d, __u32)
-+
-+/*
-+ * to set a range use
-+ * LIRC_SET_REC_DUTY_CYCLE_RANGE/LIRC_SET_REC_CARRIER_RANGE with the
-+ * lower bound first and later
-+ * LIRC_SET_REC_DUTY_CYCLE/LIRC_SET_REC_CARRIER with the upper bound
-+ */
-+
-+#define LIRC_SET_REC_DUTY_CYCLE_RANGE _IOW('i', 0x0000001e, __u32)
-+#define LIRC_SET_REC_CARRIER_RANGE _IOW('i', 0x0000001f, __u32)
-+
-+#define LIRC_NOTIFY_DECODE _IO('i', 0x00000020)
-+
-+#define LIRC_SETUP_START _IO('i', 0x00000021)
-+#define LIRC_SETUP_END _IO('i', 0x00000022)
-+
-+#endif
-diff --git a/include/media/lirc_dev.h b/include/media/lirc_dev.h
-new file mode 100644
-index 0000000..b1f6066
---- /dev/null
-+++ b/include/media/lirc_dev.h
-@@ -0,0 +1,225 @@
-+/*
-+ * LIRC base driver
-+ *
-+ * by Artur Lipowski <alipowski@interia.pl>
-+ * This code is licensed under GNU GPL
-+ *
-+ */
-+
-+#ifndef _LINUX_LIRC_DEV_H
-+#define _LINUX_LIRC_DEV_H
-+
-+#define MAX_IRCTL_DEVICES 4
-+#define BUFLEN 16
-+
-+#define mod(n, div) ((n) % (div))
-+
-+#include <linux/slab.h>
-+#include <linux/fs.h>
-+#include <linux/ioctl.h>
-+#include <linux/poll.h>
-+#include <linux/kfifo.h>
-+#include <media/lirc.h>
-+
-+struct lirc_buffer {
-+ wait_queue_head_t wait_poll;
-+ spinlock_t fifo_lock;
-+ unsigned int chunk_size;
-+ unsigned int size; /* in chunks */
-+ /* Using chunks instead of bytes pretends to simplify boundary checking
-+ * And should allow for some performance fine tunning later */
-+ struct kfifo fifo;
-+ u8 fifo_initialized;
-+};
-+
-+static inline void lirc_buffer_clear(struct lirc_buffer *buf)
-+{
-+ unsigned long flags;
-+
-+ if (buf->fifo_initialized) {
-+ spin_lock_irqsave(&buf->fifo_lock, flags);
-+ kfifo_reset(&buf->fifo);
-+ spin_unlock_irqrestore(&buf->fifo_lock, flags);
-+ } else
-+ WARN(1, "calling %s on an uninitialized lirc_buffer\n",
-+ __func__);
-+}
-+
-+static inline int lirc_buffer_init(struct lirc_buffer *buf,
-+ unsigned int chunk_size,
-+ unsigned int size)
-+{
-+ int ret;
-+
-+ init_waitqueue_head(&buf->wait_poll);
-+ spin_lock_init(&buf->fifo_lock);
-+ buf->chunk_size = chunk_size;
-+ buf->size = size;
-+ ret = kfifo_alloc(&buf->fifo, size * chunk_size, GFP_KERNEL);
-+ if (ret == 0)
-+ buf->fifo_initialized = 1;
-+
-+ return ret;
-+}
-+
-+static inline void lirc_buffer_free(struct lirc_buffer *buf)
-+{
-+ if (buf->fifo_initialized) {
-+ kfifo_free(&buf->fifo);
-+ buf->fifo_initialized = 0;
-+ } else
-+ WARN(1, "calling %s on an uninitialized lirc_buffer\n",
-+ __func__);
-+}
-+
-+static inline int lirc_buffer_len(struct lirc_buffer *buf)
-+{
-+ int len;
-+ unsigned long flags;
-+
-+ spin_lock_irqsave(&buf->fifo_lock, flags);
-+ len = kfifo_len(&buf->fifo);
-+ spin_unlock_irqrestore(&buf->fifo_lock, flags);
-+
-+ return len;
-+}
-+
-+static inline int lirc_buffer_full(struct lirc_buffer *buf)
-+{
-+ return lirc_buffer_len(buf) == buf->size * buf->chunk_size;
-+}
-+
-+static inline int lirc_buffer_empty(struct lirc_buffer *buf)
-+{
-+ return !lirc_buffer_len(buf);
-+}
-+
-+static inline int lirc_buffer_available(struct lirc_buffer *buf)
-+{
-+ return buf->size - (lirc_buffer_len(buf) / buf->chunk_size);
-+}
-+
-+static inline unsigned int lirc_buffer_read(struct lirc_buffer *buf,
-+ unsigned char *dest)
-+{
-+ unsigned int ret = 0;
-+
-+ if (lirc_buffer_len(buf) >= buf->chunk_size)
-+ ret = kfifo_out_locked(&buf->fifo, dest, buf->chunk_size,
-+ &buf->fifo_lock);
-+ return ret;
-+
-+}
-+
-+static inline unsigned int lirc_buffer_write(struct lirc_buffer *buf,
-+ unsigned char *orig)
-+{
-+ unsigned int ret;
-+
-+ ret = kfifo_in_locked(&buf->fifo, orig, buf->chunk_size,
-+ &buf->fifo_lock);
-+
-+ return ret;
-+}
-+
-+struct lirc_driver {
-+ char name[40];
-+ int minor;
-+ unsigned long code_length;
-+ unsigned int buffer_size; /* in chunks holding one code each */
-+ int sample_rate;
-+ unsigned long features;
-+
-+ unsigned int chunk_size;
-+
-+ void *data;
-+ int min_timeout;
-+ int max_timeout;
-+ int (*add_to_buf) (void *data, struct lirc_buffer *buf);
-+ struct lirc_buffer *rbuf;
-+ int (*set_use_inc) (void *data);
-+ void (*set_use_dec) (void *data);
-+ struct file_operations *fops;
-+ struct device *dev;
-+ struct module *owner;
-+};
-+
-+/* name:
-+ * this string will be used for logs
-+ *
-+ * minor:
-+ * indicates minor device (/dev/lirc) number for registered driver
-+ * if caller fills it with negative value, then the first free minor
-+ * number will be used (if available)
-+ *
-+ * code_length:
-+ * length of the remote control key code expressed in bits
-+ *
-+ * sample_rate:
-+ *
-+ * data:
-+ * it may point to any driver data and this pointer will be passed to
-+ * all callback functions
-+ *
-+ * add_to_buf:
-+ * add_to_buf will be called after specified period of the time or
-+ * triggered by the external event, this behavior depends on value of
-+ * the sample_rate this function will be called in user context. This
-+ * routine should return 0 if data was added to the buffer and
-+ * -ENODATA if none was available. This should add some number of bits
-+ * evenly divisible by code_length to the buffer
-+ *
-+ * rbuf:
-+ * if not NULL, it will be used as a read buffer, you will have to
-+ * write to the buffer by other means, like irq's (see also
-+ * lirc_serial.c).
-+ *
-+ * set_use_inc:
-+ * set_use_inc will be called after device is opened
-+ *
-+ * set_use_dec:
-+ * set_use_dec will be called after device is closed
-+ *
-+ * fops:
-+ * file_operations for drivers which don't fit the current driver model.
-+ *
-+ * Some ioctl's can be directly handled by lirc_dev if the driver's
-+ * ioctl function is NULL or if it returns -ENOIOCTLCMD (see also
-+ * lirc_serial.c).
-+ *
-+ * owner:
-+ * the module owning this struct
-+ *
-+ */
-+
-+
-+/* following functions can be called ONLY from user context
-+ *
-+ * returns negative value on error or minor number
-+ * of the registered device if success
-+ * contents of the structure pointed by p is copied
-+ */
-+extern int lirc_register_driver(struct lirc_driver *d);
-+
-+/* returns negative value on error or 0 if success
-+*/
-+extern int lirc_unregister_driver(int minor);
-+
-+/* Returns the private data stored in the lirc_driver
-+ * associated with the given device file pointer.
-+ */
-+void *lirc_get_pdata(struct file *file);
-+
-+/* default file operations
-+ * used by drivers if they override only some operations
-+ */
-+int lirc_dev_fop_open(struct inode *inode, struct file *file);
-+int lirc_dev_fop_close(struct inode *inode, struct file *file);
-+unsigned int lirc_dev_fop_poll(struct file *file, poll_table *wait);
-+long lirc_dev_fop_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
-+ssize_t lirc_dev_fop_read(struct file *file, char *buffer, size_t length,
-+ loff_t *ppos);
-+ssize_t lirc_dev_fop_write(struct file *file, const char *buffer, size_t length,
-+ loff_t *ppos);
-+
-+#endif
-diff --git a/include/media/rc-map.h b/include/media/rc-map.h
-index c78e99a..a329858 100644
---- a/include/media/rc-map.h
-+++ b/include/media/rc-map.h
-@@ -17,8 +17,13 @@
- #define IR_TYPE_RC6 (1 << 2) /* Philips RC6 protocol */
- #define IR_TYPE_JVC (1 << 3) /* JVC protocol */
- #define IR_TYPE_SONY (1 << 4) /* Sony12/15/20 protocol */
-+#define IR_TYPE_LIRC (1 << 30) /* Pass raw IR to lirc userspace */
- #define IR_TYPE_OTHER (1u << 31)
-
-+#define IR_TYPE_ALL (IR_TYPE_RC5 | IR_TYPE_NEC | IR_TYPE_RC6 | \
-+ IR_TYPE_JVC | IR_TYPE_SONY | IR_TYPE_LIRC | \
-+ IR_TYPE_OTHER)
-+
- struct ir_scancode {
- u32 scancode;
- u32 keycode;
-@@ -87,6 +92,7 @@ void rc_map_init(void);
- #define RC_MAP_KAIOMY "rc-kaiomy"
- #define RC_MAP_KWORLD_315U "rc-kworld-315u"
- #define RC_MAP_KWORLD_PLUS_TV_ANALOG "rc-kworld-plus-tv-analog"
-+#define RC_MAP_LIRC "rc-lirc"
- #define RC_MAP_MANLI "rc-manli"
- #define RC_MAP_MSI_TVANYWHERE_PLUS "rc-msi-tvanywhere-plus"
- #define RC_MAP_MSI_TVANYWHERE "rc-msi-tvanywhere"
-@@ -107,6 +113,7 @@ void rc_map_init(void);
- #define RC_MAP_PV951 "rc-pv951"
- #define RC_MAP_RC5_HAUPPAUGE_NEW "rc-rc5-hauppauge-new"
- #define RC_MAP_RC5_TV "rc-rc5-tv"
-+#define RC_MAP_RC6_MCE "rc-rc6-mce"
- #define RC_MAP_REAL_AUDIO_220_32_KEYS "rc-real-audio-220-32-keys"
- #define RC_MAP_TBS_NEC "rc-tbs-nec"
- #define RC_MAP_TERRATEC_CINERGY_XS "rc-terratec-cinergy-xs"
diff --git a/mm-slub-do-not-take-expensive-steps-for-slubs-speculative-high-order-allocations.patch b/mm-slub-do-not-take-expensive-steps-for-slubs-speculative-high-order-allocations.patch
deleted file mode 100644
index f07c75bad..000000000
--- a/mm-slub-do-not-take-expensive-steps-for-slubs-speculative-high-order-allocations.patch
+++ /dev/null
@@ -1,78 +0,0 @@
-From linux-fsdevel-owner@vger.kernel.org Fri May 13 10:04:18 2011
-From: Mel Gorman <mgorman@suse.de>
-To: Andrew Morton <akpm@linux-foundation.org>
-Cc: James Bottomley <James.Bottomley@HansenPartnership.com>,
- Colin King <colin.king@canonical.com>,
- Raghavendra D Prabhu <raghu.prabhu13@gmail.com>,
- Jan Kara <jack@suse.cz>, Chris Mason <chris.mason@oracle.com>,
- Christoph Lameter <cl@linux.com>,
- Pekka Enberg <penberg@kernel.org>,
- Rik van Riel <riel@redhat.com>,
- Johannes Weiner <hannes@cmpxchg.org>,
- linux-fsdevel <linux-fsdevel@vger.kernel.org>,
- linux-mm <linux-mm@kvack.org>,
- linux-kernel <linux-kernel@vger.kernel.org>,
- linux-ext4 <linux-ext4@vger.kernel.org>,
- Mel Gorman <mgorman@suse.de>
-Subject: [PATCH 3/4] mm: slub: Do not take expensive steps for SLUBs speculative high-order allocations
-Date: Fri, 13 May 2011 15:03:23 +0100
-Message-Id: <1305295404-12129-4-git-send-email-mgorman@suse.de>
-X-Mailing-List: linux-fsdevel@vger.kernel.org
-
-To avoid locking and per-cpu overhead, SLUB optimisically uses
-high-order allocations and falls back to lower allocations if they
-fail. However, by simply trying to allocate, the caller can enter
-compaction or reclaim - both of which are likely to cost more than the
-benefit of using high-order pages in SLUB. On a desktop system, two
-users report that the system is getting stalled with kswapd using large
-amounts of CPU.
-
-This patch prevents SLUB taking any expensive steps when trying to use
-high-order allocations. Instead, it is expected to fall back to smaller
-orders more aggressively. Testing was somewhat inconclusive on how much
-this helped but it makes sense that falling back to order-0 allocations
-is faster than entering compaction or direct reclaim.
-
-Signed-off-by: Mel Gorman <mgorman@suse.de>
----
- mm/page_alloc.c | 3 ++-
- mm/slub.c | 3 ++-
- 2 files changed, 4 insertions(+), 2 deletions(-)
-
-diff --git a/mm/page_alloc.c b/mm/page_alloc.c
-index 9f8a97b..057f1e2 100644
---- a/mm/page_alloc.c
-+++ b/mm/page_alloc.c
-@@ -1972,6 +1972,7 @@ gfp_to_alloc_flags(gfp_t gfp_mask)
- {
- int alloc_flags = ALLOC_WMARK_MIN | ALLOC_CPUSET;
- const gfp_t wait = gfp_mask & __GFP_WAIT;
-+ const gfp_t can_wake_kswapd = !(gfp_mask & __GFP_NO_KSWAPD);
-
- /* __GFP_HIGH is assumed to be the same as ALLOC_HIGH to save a branch. */
- BUILD_BUG_ON(__GFP_HIGH != (__force gfp_t) ALLOC_HIGH);
-@@ -1984,7 +1985,7 @@ gfp_to_alloc_flags(gfp_t gfp_mask)
- */
- alloc_flags |= (__force int) (gfp_mask & __GFP_HIGH);
-
-- if (!wait) {
-+ if (!wait && can_wake_kswapd) {
- /*
- * Not worth trying to allocate harder for
- * __GFP_NOMEMALLOC even if it can't schedule.
-diff --git a/mm/slub.c b/mm/slub.c
-index 98c358d..c5797ab 100644
---- a/mm/slub.c
-+++ b/mm/slub.c
-@@ -1170,7 +1170,8 @@ static struct page *allocate_slab(struct kmem_cache *s, gfp_t flags, int node)
- * Let the initial higher-order allocation fail under memory pressure
- * so we fall-back to the minimum order allocation.
- */
-- alloc_gfp = (flags | __GFP_NOWARN | __GFP_NORETRY | __GFP_NO_KSWAPD) & ~__GFP_NOFAIL;
-+ alloc_gfp = (flags | __GFP_NOWARN | __GFP_NO_KSWAPD) &
-+ ~(__GFP_NOFAIL | __GFP_WAIT | __GFP_REPEAT);
-
- page = alloc_slab_page(alloc_gfp, node, oo);
- if (unlikely(!page)) {
---
-1.7.3.4
diff --git a/mm-slub-do-not-wake-kswapd-for-slubs-speculative-high-order-allocations.patch b/mm-slub-do-not-wake-kswapd-for-slubs-speculative-high-order-allocations.patch
deleted file mode 100644
index d730d971c..000000000
--- a/mm-slub-do-not-wake-kswapd-for-slubs-speculative-high-order-allocations.patch
+++ /dev/null
@@ -1,52 +0,0 @@
-From linux-fsdevel-owner@vger.kernel.org Fri May 13 10:04:00 2011
-From: Mel Gorman <mgorman@suse.de>
-To: Andrew Morton <akpm@linux-foundation.org>
-Cc: James Bottomley <James.Bottomley@HansenPartnership.com>,
- Colin King <colin.king@canonical.com>,
- Raghavendra D Prabhu <raghu.prabhu13@gmail.com>,
- Jan Kara <jack@suse.cz>, Chris Mason <chris.mason@oracle.com>,
- Christoph Lameter <cl@linux.com>,
- Pekka Enberg <penberg@kernel.org>,
- Rik van Riel <riel@redhat.com>,
- Johannes Weiner <hannes@cmpxchg.org>,
- linux-fsdevel <linux-fsdevel@vger.kernel.org>,
- linux-mm <linux-mm@kvack.org>,
- linux-kernel <linux-kernel@vger.kernel.org>,
- linux-ext4 <linux-ext4@vger.kernel.org>,
- Mel Gorman <mgorman@suse.de>
-Subject: [PATCH 2/4] mm: slub: Do not wake kswapd for SLUBs speculative high-order allocations
-Date: Fri, 13 May 2011 15:03:22 +0100
-Message-Id: <1305295404-12129-3-git-send-email-mgorman@suse.de>
-X-Mailing-List: linux-fsdevel@vger.kernel.org
-
-To avoid locking and per-cpu overhead, SLUB optimisically uses
-high-order allocations and falls back to lower allocations if they
-fail. However, by simply trying to allocate, kswapd is woken up to
-start reclaiming at that order. On a desktop system, two users report
-that the system is getting locked up with kswapd using large amounts
-of CPU. Using SLAB instead of SLUB made this problem go away.
-
-This patch prevents kswapd being woken up for high-order allocations.
-Testing indicated that with this patch applied, the system was much
-harder to hang and even when it did, it eventually recovered.
-
-Signed-off-by: Mel Gorman <mgorman@suse.de>
----
- mm/slub.c | 2 +-
- 1 files changed, 1 insertions(+), 1 deletions(-)
-
-diff --git a/mm/slub.c b/mm/slub.c
-index 9d2e5e4..98c358d 100644
---- a/mm/slub.c
-+++ b/mm/slub.c
-@@ -1170,7 +1170,7 @@ static struct page *allocate_slab(struct kmem_cache *s, gfp_t flags, int node)
- * Let the initial higher-order allocation fail under memory pressure
- * so we fall-back to the minimum order allocation.
- */
-- alloc_gfp = (flags | __GFP_NOWARN | __GFP_NORETRY) & ~__GFP_NOFAIL;
-+ alloc_gfp = (flags | __GFP_NOWARN | __GFP_NORETRY | __GFP_NO_KSWAPD) & ~__GFP_NOFAIL;
-
- page = alloc_slab_page(alloc_gfp, node, oo);
- if (unlikely(!page)) {
---
-1.7.3.4
diff --git a/mm-vmscan-if-kswapd-has-been-running-too-long-allow-it-to-sleep.patch b/mm-vmscan-if-kswapd-has-been-running-too-long-allow-it-to-sleep.patch
deleted file mode 100644
index f2c3510ca..000000000
--- a/mm-vmscan-if-kswapd-has-been-running-too-long-allow-it-to-sleep.patch
+++ /dev/null
@@ -1,47 +0,0 @@
-From linux-fsdevel-owner@vger.kernel.org Fri May 13 10:03:52 2011
-From: Mel Gorman <mgorman@suse.de>
-To: Andrew Morton <akpm@linux-foundation.org>
-Cc: James Bottomley <James.Bottomley@HansenPartnership.com>,
- Colin King <colin.king@canonical.com>,
- Raghavendra D Prabhu <raghu.prabhu13@gmail.com>,
- Jan Kara <jack@suse.cz>, Chris Mason <chris.mason@oracle.com>,
- Christoph Lameter <cl@linux.com>,
- Pekka Enberg <penberg@kernel.org>,
- Rik van Riel <riel@redhat.com>,
- Johannes Weiner <hannes@cmpxchg.org>,
- linux-fsdevel <linux-fsdevel@vger.kernel.org>,
- linux-mm <linux-mm@kvack.org>,
- linux-kernel <linux-kernel@vger.kernel.org>,
- linux-ext4 <linux-ext4@vger.kernel.org>,
- Mel Gorman <mgorman@suse.de>
-Subject: [PATCH 4/4] mm: vmscan: If kswapd has been running too long, allow it to sleep
-Date: Fri, 13 May 2011 15:03:24 +0100
-Message-Id: <1305295404-12129-5-git-send-email-mgorman@suse.de>
-X-Mailing-List: linux-fsdevel@vger.kernel.org
-
-Under constant allocation pressure, kswapd can be in the situation where
-sleeping_prematurely() will always return true even if kswapd has been
-running a long time. Check if kswapd needs to be scheduled.
-
-Signed-off-by: Mel Gorman <mgorman@suse.de>
----
- mm/vmscan.c | 4 ++++
- 1 files changed, 4 insertions(+), 0 deletions(-)
-
-diff --git a/mm/vmscan.c b/mm/vmscan.c
-index af24d1e..4d24828 100644
---- a/mm/vmscan.c
-+++ b/mm/vmscan.c
-@@ -2251,6 +2251,10 @@ static bool sleeping_prematurely(pg_data_t *pgdat, int order, long remaining,
- unsigned long balanced = 0;
- bool all_zones_ok = true;
-
-+ /* If kswapd has been running too long, just sleep */
-+ if (need_resched())
-+ return false;
-+
- /* If a direct reclaimer woke kswapd within HZ/10, it's premature */
- if (remaining)
- return true;
---
-1.7.3.4