[PATCH 39/49] rc-core: make IR raw handling a separate module

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Make drivers/media/rc/rc-ir-raw.c a separate kernel module.

Drivers which use IR decoding must use these functions:
	rc_register_ir_raw_device()
	rc_unregister_ir_raw_device()
instead of:
	rc_register_device()
	rc_unregister_device()

This allows scancode drivers to skip lots of unnecessary functionality.

Signed-off-by: David Härdeman <david@xxxxxxxxxxx>
---
 drivers/media/common/siano/smsir.c          |    5 +-
 drivers/media/common/siano/smsir.h          |    2 -
 drivers/media/i2c/cx25840/cx25840-ir.c      |    2 -
 drivers/media/pci/cx23885/cx23885-input.c   |   13 +---
 drivers/media/pci/cx23885/cx23888-ir.c      |    2 -
 drivers/media/pci/cx88/cx88-input.c         |   18 +++---
 drivers/media/pci/dm1105/dm1105.c           |    1 
 drivers/media/pci/saa7134/saa7134-input.c   |   14 +++--
 drivers/media/pci/saa7134/saa7134.h         |    2 -
 drivers/media/rc/Makefile                   |    3 +
 drivers/media/rc/ati_remote.c               |    1 
 drivers/media/rc/ene_ir.c                   |    9 +--
 drivers/media/rc/fintek-cir.c               |    7 +-
 drivers/media/rc/gpio-ir-recv.c             |    9 +--
 drivers/media/rc/iguanair.c                 |    7 +-
 drivers/media/rc/img-ir/img-ir-raw.c        |    7 +-
 drivers/media/rc/imon.c                     |    1 
 drivers/media/rc/ite-cir.c                  |    9 +--
 drivers/media/rc/mceusb.c                   |    7 +-
 drivers/media/rc/nuvoton-cir.c              |    7 +-
 drivers/media/rc/rc-core-priv.h             |   10 ++-
 drivers/media/rc/rc-ir-raw.c                |   39 +++++++++----
 drivers/media/rc/rc-loopback.c              |    7 +-
 drivers/media/rc/rc-main.c                  |   36 +-----------
 drivers/media/rc/redrat3.c                  |    7 +-
 drivers/media/rc/streamzap.c                |    7 +-
 drivers/media/rc/ttusbir.c                  |    9 +--
 drivers/media/rc/winbond-cir.c              |    9 +--
 drivers/media/usb/dvb-usb-v2/dvb_usb.h      |    5 +-
 drivers/media/usb/dvb-usb-v2/dvb_usb_core.c |   12 +++-
 drivers/media/usb/dvb-usb-v2/rtl28xxu.c     |    2 -
 drivers/media/usb/dvb-usb/dvb-usb-remote.c  |    9 ++-
 drivers/media/usb/dvb-usb/dvb-usb.h         |    5 +-
 drivers/media/usb/dvb-usb/technisat-usb2.c  |    2 -
 drivers/media/usb/em28xx/em28xx-input.c     |    5 --
 drivers/media/usb/tm6000/tm6000-input.c     |    1 
 include/media/rc-core.h                     |   73 +-----------------------
 include/media/rc-ir-raw.h                   |   83 +++++++++++++++++++++++++++
 38 files changed, 222 insertions(+), 225 deletions(-)
 create mode 100644 include/media/rc-ir-raw.h

diff --git a/drivers/media/common/siano/smsir.c b/drivers/media/common/siano/smsir.c
index 273043e..f6938f4 100644
--- a/drivers/media/common/siano/smsir.c
+++ b/drivers/media/common/siano/smsir.c
@@ -87,14 +87,13 @@ int sms_ir_init(struct smscore_device_t *coredev)
 #endif
 
 	dev->priv = coredev;
-	dev->driver_type = RC_DRIVER_IR_RAW;
 	dev->allowed_protocols = RC_BIT_ALL;
 	dev->map_name = sms_get_board(board_id)->rc_codes;
 	dev->driver_name = MODULE_NAME;
 
 	sms_log("Input device (IR) %s is set for key events", dev->input_name);
 
-	err = rc_register_device(dev);
+	err = rc_register_ir_raw_device(dev);
 	if (err < 0) {
 		sms_err("Failed to register device");
 		rc_free_device(dev);
@@ -108,7 +107,7 @@ int sms_ir_init(struct smscore_device_t *coredev)
 void sms_ir_exit(struct smscore_device_t *coredev)
 {
 	if (coredev->ir.dev)
-		rc_unregister_device(coredev->ir.dev);
+		rc_unregister_ir_raw_device(coredev->ir.dev);
 
 	sms_log("");
 }
diff --git a/drivers/media/common/siano/smsir.h b/drivers/media/common/siano/smsir.h
index fc8b792..05a2b01 100644
--- a/drivers/media/common/siano/smsir.h
+++ b/drivers/media/common/siano/smsir.h
@@ -28,7 +28,7 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 #define __SMS_IR_H__
 
 #include <linux/input.h>
-#include <media/rc-core.h>
+#include <media/rc-ir-raw.h>
 
 #define IR_DEFAULT_TIMEOUT		100
 
diff --git a/drivers/media/i2c/cx25840/cx25840-ir.c b/drivers/media/i2c/cx25840/cx25840-ir.c
index e6588ee..119d4e8 100644
--- a/drivers/media/i2c/cx25840/cx25840-ir.c
+++ b/drivers/media/i2c/cx25840/cx25840-ir.c
@@ -25,7 +25,7 @@
 #include <linux/kfifo.h>
 #include <linux/module.h>
 #include <media/cx25840.h>
-#include <media/rc-core.h>
+#include <media/rc-ir-raw.h>
 
 #include "cx25840-core.h"
 
diff --git a/drivers/media/pci/cx23885/cx23885-input.c b/drivers/media/pci/cx23885/cx23885-input.c
index 1940c18..e2ba28d 100644
--- a/drivers/media/pci/cx23885/cx23885-input.c
+++ b/drivers/media/pci/cx23885/cx23885-input.c
@@ -36,7 +36,7 @@
  */
 
 #include <linux/slab.h>
-#include <media/rc-core.h>
+#include <media/rc-ir-raw.h>
 #include <media/v4l2-subdev.h>
 
 #include "cx23885.h"
@@ -258,7 +258,6 @@ int cx23885_input_init(struct cx23885_dev *dev)
 	struct cx23885_kernel_ir *kernel_ir;
 	struct rc_dev *rc;
 	char *rc_map;
-	enum rc_driver_type driver_type;
 	unsigned long allowed_protos;
 
 	int ret;
@@ -276,28 +275,24 @@ int cx23885_input_init(struct cx23885_dev *dev)
 	case CX23885_BOARD_HAUPPAUGE_HVR1290:
 	case CX23885_BOARD_HAUPPAUGE_HVR1250:
 		/* Integrated CX2388[58] IR controller */
-		driver_type = RC_DRIVER_IR_RAW;
 		allowed_protos = RC_BIT_ALL;
 		/* The grey Hauppauge RC-5 remote */
 		rc_map = RC_MAP_HAUPPAUGE;
 		break;
 	case CX23885_BOARD_TERRATEC_CINERGY_T_PCIE_DUAL:
 		/* Integrated CX23885 IR controller */
-		driver_type = RC_DRIVER_IR_RAW;
 		allowed_protos = RC_BIT_NEC;
 		/* The grey Terratec remote with orange buttons */
 		rc_map = RC_MAP_NEC_TERRATEC_CINERGY_XS;
 		break;
 	case CX23885_BOARD_TEVII_S470:
 		/* Integrated CX23885 IR controller */
-		driver_type = RC_DRIVER_IR_RAW;
 		allowed_protos = RC_BIT_ALL;
 		/* A guess at the remote */
 		rc_map = RC_MAP_TEVII_NEC;
 		break;
 	case CX23885_BOARD_MYGICA_X8507:
 		/* Integrated CX23885 IR controller */
-		driver_type = RC_DRIVER_IR_RAW;
 		allowed_protos = RC_BIT_ALL;
 		/* A guess at the remote */
 		rc_map = RC_MAP_TOTAL_MEDIA_IN_HAND_02;
@@ -305,7 +300,6 @@ int cx23885_input_init(struct cx23885_dev *dev)
 	case CX23885_BOARD_TBS_6980:
 	case CX23885_BOARD_TBS_6981:
 		/* Integrated CX23885 IR controller */
-		driver_type = RC_DRIVER_IR_RAW;
 		allowed_protos = RC_BIT_ALL;
 		/* A guess at the remote */
 		rc_map = RC_MAP_TBS_NEC;
@@ -345,7 +339,6 @@ int cx23885_input_init(struct cx23885_dev *dev)
 		rc->input_id.product = dev->pci->device;
 	}
 	rc->dev.parent = &dev->pci->dev;
-	rc->driver_type = driver_type;
 	rc->allowed_protocols = allowed_protos;
 	rc->priv = kernel_ir;
 	rc->open = cx23885_input_ir_open;
@@ -355,7 +348,7 @@ int cx23885_input_init(struct cx23885_dev *dev)
 
 	/* Go */
 	dev->kernel_ir = kernel_ir;
-	ret = rc_register_device(rc);
+	ret = rc_register_ir_raw_device(rc);
 	if (ret)
 		goto err_out_stop;
 
@@ -379,7 +372,7 @@ void cx23885_input_fini(struct cx23885_dev *dev)
 
 	if (dev->kernel_ir == NULL)
 		return;
-	rc_unregister_device(dev->kernel_ir->rc);
+	rc_unregister_ir_raw_device(dev->kernel_ir->rc);
 	kfree(dev->kernel_ir->phys);
 	kfree(dev->kernel_ir->name);
 	kfree(dev->kernel_ir);
diff --git a/drivers/media/pci/cx23885/cx23888-ir.c b/drivers/media/pci/cx23885/cx23888-ir.c
index 2c951de..c4961f8 100644
--- a/drivers/media/pci/cx23885/cx23888-ir.c
+++ b/drivers/media/pci/cx23885/cx23888-ir.c
@@ -25,7 +25,7 @@
 #include <linux/slab.h>
 
 #include <media/v4l2-device.h>
-#include <media/rc-core.h>
+#include <media/rc-ir-raw.h>
 
 #include "cx23885.h"
 #include "cx23888-ir.h"
diff --git a/drivers/media/pci/cx88/cx88-input.c b/drivers/media/pci/cx88/cx88-input.c
index cb587ce..2b68ede 100644
--- a/drivers/media/pci/cx88/cx88-input.c
+++ b/drivers/media/pci/cx88/cx88-input.c
@@ -29,7 +29,7 @@
 #include <linux/module.h>
 
 #include "cx88.h"
-#include <media/rc-core.h>
+#include <media/rc-ir-raw.h>
 
 #define MODULE_NAME "cx88xx"
 
@@ -474,20 +474,17 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci)
 	dev->open = cx88_ir_open;
 	dev->close = cx88_ir_close;
 	dev->scancode_mask = hardware_mask;
+	ir->core = core;
+	core->ir = ir;
 
 	if (ir->sampling) {
-		dev->driver_type = RC_DRIVER_IR_RAW;
 		dev->timeout = 10 * 1000 * 1000; /* 10 ms */
+		err = rc_register_ir_raw_device(dev);
 	} else {
-		dev->driver_type = RC_DRIVER_SCANCODE;
 		dev->allowed_protocols = rc_type;
+		err = rc_register_device(dev);
 	}
 
-	ir->core = core;
-	core->ir = ir;
-
-	/* all done */
-	err = rc_register_device(dev);
 	if (err)
 		goto err_out_free;
 
@@ -509,7 +506,10 @@ int cx88_ir_fini(struct cx88_core *core)
 		return 0;
 
 	cx88_ir_stop(core);
-	rc_unregister_device(ir->dev);
+	if (ir->sampling)
+		rc_unregister_ir_raw_device(ir->dev);
+	else
+		rc_unregister_device(ir->dev);
 	kfree(ir);
 
 	/* done */
diff --git a/drivers/media/pci/dm1105/dm1105.c b/drivers/media/pci/dm1105/dm1105.c
index e8826c5..015aa07 100644
--- a/drivers/media/pci/dm1105/dm1105.c
+++ b/drivers/media/pci/dm1105/dm1105.c
@@ -752,7 +752,6 @@ static int dm1105_ir_init(struct dm1105_dev *dm1105)
 
 	dev->driver_name = MODULE_NAME;
 	dev->map_name = RC_MAP_DM1105_NEC;
-	dev->driver_type = RC_DRIVER_SCANCODE;
 	dev->input_name = "DVB on-card IR receiver";
 	dev->input_phys = dm1105->ir.input_phys;
 	dev->input_id.bustype = BUS_PCI;
diff --git a/drivers/media/pci/saa7134/saa7134-input.c b/drivers/media/pci/saa7134/saa7134-input.c
index 4ba61ff..27a3f48 100644
--- a/drivers/media/pci/saa7134/saa7134-input.c
+++ b/drivers/media/pci/saa7134/saa7134-input.c
@@ -864,9 +864,6 @@ int saa7134_input_init1(struct saa7134_dev *dev)
 	rc->priv = dev;
 	rc->open = saa7134_ir_open;
 	rc->close = saa7134_ir_close;
-	if (raw_decode)
-		rc->driver_type = RC_DRIVER_IR_RAW;
-
 	rc->input_name = ir->name;
 	rc->input_phys = ir->phys;
 	rc->input_id.bustype = BUS_PCI;
@@ -882,7 +879,11 @@ int saa7134_input_init1(struct saa7134_dev *dev)
 	rc->map_name = ir_codes;
 	rc->driver_name = MODULE_NAME;
 
-	err = rc_register_device(rc);
+	if (raw_decode)
+		err = rc_register_ir_raw_device(rc);
+	else
+		err = rc_register_device(rc);
+
 	if (err)
 		goto err_out_free;
 
@@ -901,7 +902,10 @@ void saa7134_input_fini(struct saa7134_dev *dev)
 		return;
 
 	saa7134_ir_stop(dev);
-	rc_unregister_device(dev->remote->dev);
+	if (dev->remote->raw_decode)
+		rc_unregister_ir_raw_device(dev->remote->dev);
+	else
+		rc_unregister_device(dev->remote->dev);
 	kfree(dev->remote);
 	dev->remote = NULL;
 }
diff --git a/drivers/media/pci/saa7134/saa7134.h b/drivers/media/pci/saa7134/saa7134.h
index 2474e84..5a25486 100644
--- a/drivers/media/pci/saa7134/saa7134.h
+++ b/drivers/media/pci/saa7134/saa7134.h
@@ -39,7 +39,7 @@
 #include <media/v4l2-fh.h>
 #include <media/v4l2-ctrls.h>
 #include <media/tuner.h>
-#include <media/rc-core.h>
+#include <media/rc-ir-raw.h>
 #include <media/ir-kbd-i2c.h>
 #include <media/videobuf-dma-sg.h>
 #include <sound/core.h>
diff --git a/drivers/media/rc/Makefile b/drivers/media/rc/Makefile
index 661f449..ac39628 100644
--- a/drivers/media/rc/Makefile
+++ b/drivers/media/rc/Makefile
@@ -1,8 +1,9 @@
-rc-core-objs	:= rc-main.o rc-keytable.o rc-ir-raw.o
+rc-core-objs	:= rc-main.o rc-keytable.o
 
 obj-y += keymaps/
 
 obj-$(CONFIG_RC_CORE) += rc-core.o
+obj-$(CONFIG_RC_CORE) += rc-ir-raw.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
diff --git a/drivers/media/rc/ati_remote.c b/drivers/media/rc/ati_remote.c
index 6ef5716..170aac8 100644
--- a/drivers/media/rc/ati_remote.c
+++ b/drivers/media/rc/ati_remote.c
@@ -784,7 +784,6 @@ static void ati_remote_rc_init(struct ati_remote *ati_remote)
 	struct rc_dev *rdev = ati_remote->rdev;
 
 	rdev->priv = ati_remote;
-	rdev->driver_type = RC_DRIVER_SCANCODE;
 	rdev->allowed_protocols = RC_BIT_OTHER;
 	rdev->driver_name = "ati_remote";
 
diff --git a/drivers/media/rc/ene_ir.c b/drivers/media/rc/ene_ir.c
index cab5da9..57d61e5 100644
--- a/drivers/media/rc/ene_ir.c
+++ b/drivers/media/rc/ene_ir.c
@@ -39,7 +39,7 @@
 #include <linux/interrupt.h>
 #include <linux/sched.h>
 #include <linux/slab.h>
-#include <media/rc-core.h>
+#include <media/rc-ir-raw.h>
 #include "ene_ir.h"
 
 static int sample_period;
@@ -1053,7 +1053,6 @@ static int ene_probe(struct pnp_dev *pnp_dev, const struct pnp_device_id *id)
 	if (!dev->hw_learning_and_tx_capable)
 		learning_mode_force = false;
 
-	rdev->driver_type = RC_DRIVER_IR_RAW;
 	rdev->allowed_protocols = RC_BIT_ALL;
 	rdev->priv = dev;
 	rdev->open = ene_open;
@@ -1083,7 +1082,7 @@ static int ene_probe(struct pnp_dev *pnp_dev, const struct pnp_device_id *id)
 	device_set_wakeup_capable(&pnp_dev->dev, true);
 	device_set_wakeup_enable(&pnp_dev->dev, true);
 
-	error = rc_register_device(rdev);
+	error = rc_register_ir_raw_device(rdev);
 	if (error < 0)
 		goto exit_free_dev_rdev;
 
@@ -1104,7 +1103,7 @@ static int ene_probe(struct pnp_dev *pnp_dev, const struct pnp_device_id *id)
 exit_release_hw_io:
 	release_region(dev->hw_io, ENE_IO_SIZE);
 exit_unregister_device:
-	rc_unregister_device(rdev);
+	rc_unregister_ir_raw_device(rdev);
 	rdev = NULL;
 exit_free_dev_rdev:
 	rc_free_device(rdev);
@@ -1125,7 +1124,7 @@ static void ene_remove(struct pnp_dev *pnp_dev)
 
 	free_irq(dev->irq, dev);
 	release_region(dev->hw_io, ENE_IO_SIZE);
-	rc_unregister_device(dev->rdev);
+	rc_unregister_ir_raw_device(dev->rdev);
 	kfree(dev);
 }
 
diff --git a/drivers/media/rc/fintek-cir.c b/drivers/media/rc/fintek-cir.c
index f000faf..ce2db15 100644
--- a/drivers/media/rc/fintek-cir.c
+++ b/drivers/media/rc/fintek-cir.c
@@ -32,7 +32,7 @@
 #include <linux/interrupt.h>
 #include <linux/sched.h>
 #include <linux/slab.h>
-#include <media/rc-core.h>
+#include <media/rc-ir-raw.h>
 #include <linux/pci_ids.h>
 
 #include "fintek-cir.h"
@@ -540,7 +540,6 @@ static int fintek_probe(struct pnp_dev *pdev, const struct pnp_device_id *dev_id
 
 	/* Set up the rc device */
 	rdev->priv = fintek;
-	rdev->driver_type = RC_DRIVER_IR_RAW;
 	rdev->allowed_protocols = RC_BIT_ALL;
 	rdev->open = fintek_open;
 	rdev->close = fintek_close;
@@ -569,7 +568,7 @@ static int fintek_probe(struct pnp_dev *pdev, const struct pnp_device_id *dev_id
 			FINTEK_DRIVER_NAME, (void *)fintek))
 		goto exit_free_cir_addr;
 
-	ret = rc_register_device(rdev);
+	ret = rc_register_ir_raw_device(rdev);
 	if (ret)
 		goto exit_free_irq;
 
@@ -609,7 +608,7 @@ static void fintek_remove(struct pnp_dev *pdev)
 	free_irq(fintek->cir_irq, fintek);
 	release_region(fintek->cir_addr, fintek->cir_port_len);
 
-	rc_unregister_device(fintek->rdev);
+	rc_unregister_ir_raw_device(fintek->rdev);
 
 	kfree(fintek);
 }
diff --git a/drivers/media/rc/gpio-ir-recv.c b/drivers/media/rc/gpio-ir-recv.c
index 7d01560..ff30bdb 100644
--- a/drivers/media/rc/gpio-ir-recv.c
+++ b/drivers/media/rc/gpio-ir-recv.c
@@ -20,7 +20,7 @@
 #include <linux/of_gpio.h>
 #include <linux/platform_device.h>
 #include <linux/irq.h>
-#include <media/rc-core.h>
+#include <media/rc-ir-raw.h>
 #include <media/gpio-ir-recv.h>
 
 #define GPIO_IR_DRIVER_NAME	"gpio-rc-recv"
@@ -135,7 +135,6 @@ static int gpio_ir_recv_probe(struct platform_device *pdev)
 	}
 
 	rcdev->priv = gpio_dev;
-	rcdev->driver_type = RC_DRIVER_IR_RAW;
 	rcdev->input_name = GPIO_IR_DEVICE_NAME;
 	rcdev->input_phys = GPIO_IR_DEVICE_NAME "/input0";
 	rcdev->input_id.bustype = BUS_HOST;
@@ -161,7 +160,7 @@ static int gpio_ir_recv_probe(struct platform_device *pdev)
 	if (rc < 0)
 		goto err_gpio_direction_input;
 
-	rc = rc_register_device(rcdev);
+	rc = rc_register_ir_raw_device(rcdev);
 	if (rc < 0) {
 		dev_err(&pdev->dev, "failed to register rc device\n");
 		goto err_register_rc_device;
@@ -179,7 +178,7 @@ static int gpio_ir_recv_probe(struct platform_device *pdev)
 	return 0;
 
 err_request_irq:
-	rc_unregister_device(rcdev);
+	rc_unregister_ir_raw_device(rcdev);
 	rcdev = NULL;
 err_register_rc_device:
 err_gpio_direction_input:
@@ -196,7 +195,7 @@ static int gpio_ir_recv_remove(struct platform_device *pdev)
 	struct gpio_rc_dev *gpio_dev = platform_get_drvdata(pdev);
 
 	free_irq(gpio_to_irq(gpio_dev->gpio_nr), gpio_dev);
-	rc_unregister_device(gpio_dev->rcdev);
+	rc_unregister_ir_raw_device(gpio_dev->rcdev);
 	gpio_free(gpio_dev->gpio_nr);
 	kfree(gpio_dev);
 	return 0;
diff --git a/drivers/media/rc/iguanair.c b/drivers/media/rc/iguanair.c
index 8a4baf5..3b7327a 100644
--- a/drivers/media/rc/iguanair.c
+++ b/drivers/media/rc/iguanair.c
@@ -25,7 +25,7 @@
 #include <linux/usb/input.h>
 #include <linux/slab.h>
 #include <linux/completion.h>
-#include <media/rc-core.h>
+#include <media/rc-ir-raw.h>
 
 #define DRIVER_NAME "iguanair"
 #define BUF_SIZE 152
@@ -513,7 +513,6 @@ static int iguanair_probe(struct usb_interface *intf,
 	rc->input_phys = ir->phys;
 	usb_to_input_id(ir->udev, &rc->input_id);
 	rc->dev.parent = &intf->dev;
-	rc->driver_type = RC_DRIVER_IR_RAW;
 	rc->allowed_protocols = RC_BIT_ALL;
 	rc->priv = ir;
 	rc->open = iguanair_open;
@@ -529,7 +528,7 @@ static int iguanair_probe(struct usb_interface *intf,
 	iguanair_set_tx_carrier(rc, 38000);
 	iguanair_set_tx_mask(rc, 0);
 
-	ret = rc_register_device(rc);
+	ret = rc_register_ir_raw_device(rc);
 	if (ret < 0) {
 		dev_err(&intf->dev, "failed to register rc device %d", ret);
 		goto out2;
@@ -558,7 +557,7 @@ static void iguanair_disconnect(struct usb_interface *intf)
 {
 	struct iguanair *ir = usb_get_intfdata(intf);
 
-	rc_unregister_device(ir->rc);
+	rc_unregister_ir_raw_device(ir->rc);
 	usb_set_intfdata(intf, NULL);
 	usb_kill_urb(ir->urb_in);
 	usb_kill_urb(ir->urb_out);
diff --git a/drivers/media/rc/img-ir/img-ir-raw.c b/drivers/media/rc/img-ir/img-ir-raw.c
index 5b6d8e9..95a4da1 100644
--- a/drivers/media/rc/img-ir/img-ir-raw.c
+++ b/drivers/media/rc/img-ir/img-ir-raw.c
@@ -8,7 +8,7 @@
  */
 
 #include <linux/spinlock.h>
-#include <media/rc-core.h>
+#include <media/rc-ir-raw.h>
 #include "img-ir.h"
 
 #define ECHO_TIMEOUT_MS 150	/* ms between echos */
@@ -112,10 +112,9 @@ int img_ir_probe_raw(struct img_ir_priv *priv)
 	}
 	rdev->priv = priv;
 	rdev->input_name = "IMG Infrared Decoder Raw";
-	rdev->driver_type = RC_DRIVER_IR_RAW;
 
 	/* Register raw decoder */
-	error = rc_register_device(rdev);
+	error = rc_register_ir_raw_device(rdev);
 	if (error) {
 		dev_err(priv->dev, "failed to register raw IR input device\n");
 		rc_free_device(rdev);
@@ -144,7 +143,7 @@ void img_ir_remove_raw(struct img_ir_priv *priv)
 	img_ir_write(priv, IMG_IR_IRQ_CLEAR, IMG_IR_IRQ_EDGE);
 	spin_unlock_irq(&priv->lock);
 
-	rc_unregister_device(rdev);
+	rc_unregister_ir_raw_device(rdev);
 
 	del_timer_sync(&raw->timer);
 }
diff --git a/drivers/media/rc/imon.c b/drivers/media/rc/imon.c
index 2461933..1aa2ac0 100644
--- a/drivers/media/rc/imon.c
+++ b/drivers/media/rc/imon.c
@@ -1875,7 +1875,6 @@ static struct rc_dev *imon_init_rdev(struct imon_context *ictx)
 	rdev->dev.parent = ictx->dev;
 
 	rdev->priv = ictx;
-	rdev->driver_type = RC_DRIVER_SCANCODE;
 	rdev->allowed_protocols = RC_BIT_OTHER | RC_BIT_RC6_MCE; /* iMON PAD or MCE */
 	rdev->change_protocol = imon_ir_change_protocol;
 	rdev->driver_name = MOD_NAME;
diff --git a/drivers/media/rc/ite-cir.c b/drivers/media/rc/ite-cir.c
index 0d404a2..795fbc6 100644
--- a/drivers/media/rc/ite-cir.c
+++ b/drivers/media/rc/ite-cir.c
@@ -40,7 +40,7 @@
 #include <linux/slab.h>
 #include <linux/input.h>
 #include <linux/bitops.h>
-#include <media/rc-core.h>
+#include <media/rc-ir-raw.h>
 #include <linux/pci_ids.h>
 
 #include "ite-cir.h"
@@ -1557,7 +1557,6 @@ static int ite_probe(struct pnp_dev *pdev, const struct pnp_device_id
 
 	/* set up ir-core props */
 	rdev->priv = itdev;
-	rdev->driver_type = RC_DRIVER_IR_RAW;
 	rdev->allowed_protocols = RC_BIT_ALL;
 	rdev->open = ite_open;
 	rdev->close = ite_close;
@@ -1586,7 +1585,7 @@ static int ite_probe(struct pnp_dev *pdev, const struct pnp_device_id
 	rdev->driver_name = ITE_DRIVER_NAME;
 	rdev->map_name = RC_MAP_RC6_MCE;
 
-	ret = rc_register_device(rdev);
+	ret = rc_register_ir_raw_device(rdev);
 	if (ret)
 		goto exit_free_dev_rdev;
 
@@ -1607,7 +1606,7 @@ static int ite_probe(struct pnp_dev *pdev, const struct pnp_device_id
 exit_release_cir_addr:
 	release_region(itdev->cir_addr, itdev->params.io_region_size);
 exit_unregister_device:
-	rc_unregister_device(rdev);
+	rc_unregister_ir_raw_device(rdev);
 	rdev = NULL;
 exit_free_dev_rdev:
 	rc_free_device(rdev);
@@ -1634,7 +1633,7 @@ static void ite_remove(struct pnp_dev *pdev)
 	free_irq(dev->cir_irq, dev);
 	release_region(dev->cir_addr, dev->params.io_region_size);
 
-	rc_unregister_device(dev->rdev);
+	rc_unregister_ir_raw_device(dev->rdev);
 
 	kfree(dev);
 }
diff --git a/drivers/media/rc/mceusb.c b/drivers/media/rc/mceusb.c
index e0c8552..eac87ec 100644
--- a/drivers/media/rc/mceusb.c
+++ b/drivers/media/rc/mceusb.c
@@ -43,7 +43,7 @@
 #include <linux/usb.h>
 #include <linux/usb/input.h>
 #include <linux/pm_wakeup.h>
-#include <media/rc-core.h>
+#include <media/rc-ir-raw.h>
 
 #define DRIVER_VERSION	"1.92"
 #define DRIVER_AUTHOR	"Jarod Wilson <jarod@xxxxxxxxxx>"
@@ -1217,7 +1217,6 @@ static struct rc_dev *mceusb_init_rc_dev(struct mceusb_dev *ir)
 	usb_to_input_id(ir->usbdev, &rc->input_id);
 	rc->dev.parent = dev;
 	rc->priv = ir;
-	rc->driver_type = RC_DRIVER_IR_RAW;
 	rc->allowed_protocols = RC_BIT_ALL;
 	rc->timeout = MS_TO_NS(100);
 	if (!ir->flags.no_tx) {
@@ -1229,7 +1228,7 @@ static struct rc_dev *mceusb_init_rc_dev(struct mceusb_dev *ir)
 	rc->map_name = mceusb_model[ir->model].rc_map ?
 			mceusb_model[ir->model].rc_map : RC_MAP_RC6_MCE;
 
-	ret = rc_register_device(rc);
+	ret = rc_register_ir_raw_device(rc);
 	if (ret < 0) {
 		dev_err(dev, "remote dev registration failed");
 		goto out;
@@ -1414,7 +1413,7 @@ static void mceusb_dev_disconnect(struct usb_interface *intf)
 		return;
 
 	ir->usbdev = NULL;
-	rc_unregister_device(ir->rc);
+	rc_unregister_ir_raw_device(ir->rc);
 	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);
diff --git a/drivers/media/rc/nuvoton-cir.c b/drivers/media/rc/nuvoton-cir.c
index 160d685..a8c9b5f 100644
--- a/drivers/media/rc/nuvoton-cir.c
+++ b/drivers/media/rc/nuvoton-cir.c
@@ -34,7 +34,7 @@
 #include <linux/interrupt.h>
 #include <linux/sched.h>
 #include <linux/slab.h>
-#include <media/rc-core.h>
+#include <media/rc-ir-raw.h>
 #include <linux/pci_ids.h>
 
 #include "nuvoton-cir.h"
@@ -1054,7 +1054,6 @@ static int nvt_probe(struct pnp_dev *pdev, const struct pnp_device_id *dev_id)
 
 	/* Set up the rc device */
 	rdev->priv = nvt;
-	rdev->driver_type = RC_DRIVER_IR_RAW;
 	rdev->allowed_protocols = RC_BIT_ALL;
 	rdev->open = nvt_open;
 	rdev->close = nvt_close;
@@ -1119,7 +1118,7 @@ exit_free_irq:
 exit_release_cir_addr:
 	release_region(nvt->cir_addr, CIR_IOREG_LENGTH);
 exit_unregister_device:
-	rc_unregister_device(rdev);
+	rc_unregister_ir_raw_device(rdev);
 	rdev = NULL;
 exit_free_dev_rdev:
 	rc_free_device(rdev);
@@ -1147,7 +1146,7 @@ static void nvt_remove(struct pnp_dev *pdev)
 	release_region(nvt->cir_addr, CIR_IOREG_LENGTH);
 	release_region(nvt->cir_wake_addr, CIR_IOREG_LENGTH);
 
-	rc_unregister_device(nvt->rdev);
+	rc_unregister_ir_raw_device(nvt->rdev);
 
 	kfree(nvt);
 }
diff --git a/drivers/media/rc/rc-core-priv.h b/drivers/media/rc/rc-core-priv.h
index 0159836..0b32ef8 100644
--- a/drivers/media/rc/rc-core-priv.h
+++ b/drivers/media/rc/rc-core-priv.h
@@ -19,6 +19,12 @@
 #include <linux/slab.h>
 #include <linux/spinlock.h>
 #include <media/rc-core.h>
+#include <media/rc-ir-raw.h>
+
+enum rc_driver_type {
+	RC_DRIVER_SCANCODE = 0,	/* Driver or hardware generates a scancode */
+	RC_DRIVER_IR_RAW,	/* Needs a Infra-Red pulse/space decoder */
+};
 
 struct ir_raw_handler {
 	struct list_head list;
@@ -148,12 +154,8 @@ static inline bool is_timing_event(struct ir_raw_event ev)
 /*
  * Routines from rc-raw.c to be used internally and by decoders
  */
-u64 ir_raw_get_allowed_protocols(void);
-int ir_raw_event_register(struct rc_dev *dev);
-void ir_raw_event_unregister(struct rc_dev *dev);
 int ir_raw_handler_register(struct ir_raw_handler *ir_raw_handler);
 void ir_raw_handler_unregister(struct ir_raw_handler *ir_raw_handler);
-void ir_raw_init(void);
 
 /*
  * Methods from rc-keytable.c to be used internally
diff --git a/drivers/media/rc/rc-ir-raw.c b/drivers/media/rc/rc-ir-raw.c
index 5ed8007..86f5aa7 100644
--- a/drivers/media/rc/rc-ir-raw.c
+++ b/drivers/media/rc/rc-ir-raw.c
@@ -16,6 +16,7 @@
 #include <linux/kthread.h>
 #include <linux/mutex.h>
 #include <linux/kmod.h>
+#include <linux/module.h>
 #include <linux/sched.h>
 #include <linux/freezer.h>
 #include "rc-core-priv.h"
@@ -269,8 +270,7 @@ void ir_raw_event_handle(struct rc_dev *dev)
 EXPORT_SYMBOL_GPL(ir_raw_event_handle);
 
 /* used internally by the sysfs interface */
-u64
-ir_raw_get_allowed_protocols(void)
+static u64 ir_raw_get_allowed_protocols(struct rc_dev *dev)
 {
 	u64 protocols;
 	mutex_lock(&ir_raw_handler_lock);
@@ -287,7 +287,7 @@ static int change_protocol(struct rc_dev *dev, u64 *rc_type) {
 /*
  * Used to (un)register raw event clients
  */
-int ir_raw_event_register(struct rc_dev *dev)
+int rc_register_ir_raw_device(struct rc_dev *dev)
 {
 	int rc;
 	struct ir_raw_handler *handler;
@@ -301,14 +301,16 @@ int ir_raw_event_register(struct rc_dev *dev)
 
 	dev->raw->dev = dev;
 	dev->enabled_protocols = ~0;
+	dev->get_protocols = ir_raw_get_allowed_protocols;
+	dev->driver_type = RC_DRIVER_IR_RAW;
 	dev->change_protocol = change_protocol;
+	spin_lock_init(&dev->raw->lock);
 	rc = kfifo_alloc(&dev->raw->kfifo,
 			 sizeof(struct ir_raw_event) * MAX_IR_EVENT_SIZE,
 			 GFP_KERNEL);
 	if (rc < 0)
 		goto out;
 
-	spin_lock_init(&dev->raw->lock);
 	dev->raw->thread = kthread_run(ir_raw_event_thread, dev->raw,
 				       dev_name(&dev->dev));
 
@@ -317,6 +319,10 @@ int ir_raw_event_register(struct rc_dev *dev)
 		goto out;
 	}
 
+	rc = rc_register_device(dev);
+	if (rc < 0)
+		goto out_thread;
+
 	mutex_lock(&ir_raw_handler_lock);
 	list_add_tail(&dev->raw->list, &ir_raw_client_list);
 	list_for_each_entry(handler, &ir_raw_handler_list, list)
@@ -326,13 +332,16 @@ int ir_raw_event_register(struct rc_dev *dev)
 
 	return 0;
 
+out_thread:
+	kthread_stop(dev->raw->thread);
 out:
 	kfree(dev->raw);
 	dev->raw = NULL;
 	return rc;
 }
+EXPORT_SYMBOL_GPL(rc_register_ir_raw_device);
 
-void ir_raw_event_unregister(struct rc_dev *dev)
+void rc_unregister_ir_raw_device(struct rc_dev *dev)
 {
 	struct ir_raw_handler *handler;
 
@@ -351,7 +360,9 @@ void ir_raw_event_unregister(struct rc_dev *dev)
 	kfifo_free(&dev->raw->kfifo);
 	kfree(dev->raw);
 	dev->raw = NULL;
+	rc_unregister_device(dev);
 }
+EXPORT_SYMBOL_GPL(rc_unregister_ir_raw_device);
 
 /*
  * Extension interface - used to register the IR decoders
@@ -387,10 +398,11 @@ void ir_raw_handler_unregister(struct ir_raw_handler *ir_raw_handler)
 }
 EXPORT_SYMBOL(ir_raw_handler_unregister);
 
-void ir_raw_init(void)
+static struct work_struct wq_load;
+
+static void rc_ir_raw_init_decoders(struct work_struct *work)
 {
 	/* Load the decoder modules */
-
 	load_nec_decode();
 	load_rc5_decode();
 	load_rc6_decode();
@@ -400,8 +412,15 @@ void ir_raw_init(void)
 	load_sharp_decode();
 	load_mce_kbd_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 rc-core.h
-	 */
+static int __init rc_ir_raw_init(void)
+{
+	INIT_WORK(&wq_load, rc_ir_raw_init_decoders);
+	schedule_work(&wq_load);
+	return 0;
 }
+subsys_initcall(rc_ir_raw_init);
+
+MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@xxxxxxxxxx>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/rc/rc-loopback.c b/drivers/media/rc/rc-loopback.c
index f201395..343c8d0 100644
--- a/drivers/media/rc/rc-loopback.c
+++ b/drivers/media/rc/rc-loopback.c
@@ -26,7 +26,7 @@
 #include <linux/device.h>
 #include <linux/module.h>
 #include <linux/sched.h>
-#include <media/rc-core.h>
+#include <media/rc-ir-raw.h>
 
 #define DRIVER_NAME	"rc-loopback"
 #define dprintk(x...)	if (debug) printk(KERN_INFO DRIVER_NAME ": " x)
@@ -227,7 +227,6 @@ static int __init loop_init(void)
 	rc->input_id.version	= 1;
 	rc->driver_name		= DRIVER_NAME;
 	rc->priv		= &loopdev;
-	rc->driver_type		= RC_DRIVER_IR_RAW;
 	rc->allowed_protocols	= RC_BIT_ALL;
 	rc->timeout		= 100 * 1000 * 1000; /* 100 ms */
 	rc->min_timeout		= 1;
@@ -250,7 +249,7 @@ static int __init loop_init(void)
 	loopdev.learning	= false;
 	loopdev.carrierreport	= false;
 
-	ret = rc_register_device(rc);
+	ret = rc_register_ir_raw_device(rc);
 	if (ret < 0) {
 		printk(KERN_ERR DRIVER_NAME ": rc_dev registration failed\n");
 		rc_free_device(rc);
@@ -263,7 +262,7 @@ static int __init loop_init(void)
 
 static void __exit loop_exit(void)
 {
-	rc_unregister_device(loopdev.dev);
+	rc_unregister_ir_raw_device(loopdev.dev);
 }
 
 module_init(loop_init);
diff --git a/drivers/media/rc/rc-main.c b/drivers/media/rc/rc-main.c
index 8729d0a..7caca4f 100644
--- a/drivers/media/rc/rc-main.c
+++ b/drivers/media/rc/rc-main.c
@@ -343,10 +343,7 @@ static ssize_t show_protocols(struct device *device,
 
 	if (fattr->type == RC_FILTER_NORMAL) {
 		enabled = dev->enabled_protocols;
-		if (dev->raw)
-			allowed = ir_raw_get_allowed_protocols();
-		else
-			allowed = dev->allowed_protocols;
+		allowed = dev->allowed_protocols;
 	} else {
 		enabled = dev->enabled_wakeup_protocols;
 		allowed = dev->allowed_wakeup_protocols;
@@ -919,10 +916,7 @@ void rc_init_ir_rx(struct rc_dev *dev, struct rc_ir_rx *rx)
 	rx->rx_enabled = 0x1;
 	rx->rx_connected = 0x1;
 	rx->protocols_enabled[0] = dev->enabled_protocols;
-	if (dev->driver_type == RC_DRIVER_SCANCODE)
-		rx->protocols_supported[0] = dev->allowed_protocols;
-	else
-		rx->protocols_supported[0] = ir_raw_get_allowed_protocols();
+	rx->protocols_supported[0] = dev->allowed_protocols;
 	rx->timeout = dev->timeout;
 	rx->timeout_min = dev->min_timeout;
 	rx->timeout_max = dev->max_timeout;
@@ -1135,9 +1129,6 @@ static void rc_dev_release(struct device *device)
 {
 	struct rc_dev *dev = to_rc_dev(device);
 
-	if (dev->driver_type == RC_DRIVER_IR_RAW)
-		ir_raw_event_unregister(dev);
-
 	kfifo_free(&dev->txfifo);
 	kfree(dev);
 	module_put(THIS_MODULE);
@@ -1267,7 +1258,6 @@ EXPORT_SYMBOL_GPL(rc_free_device);
 
 int rc_register_device(struct rc_dev *dev)
 {
-	static bool raw_init = false; /* raw decoders loaded? */
 	struct rc_map *rc_map = NULL;
 	int attr = 0;
 	int minor;
@@ -1290,18 +1280,6 @@ int rc_register_device(struct rc_dev *dev)
 			goto out_minor;
 	}
 
-	if (dev->driver_type == RC_DRIVER_IR_RAW) {
-		/* Load raw decoders, if they aren't already */
-		if (!raw_init) {
-			IR_dprintk(1, "Loading raw decoders\n");
-			ir_raw_init();
-			raw_init = true;
-		}
-		rc = ir_raw_event_register(dev);
-		if (rc < 0)
-			goto out_minor;
-	}
-
 	dev->dev.groups = dev->sysfs_groups;
 	dev->sysfs_groups[attr++] = &rc_dev_protocol_attr_grp;
 	if (dev->s_filter)
@@ -1319,13 +1297,13 @@ int rc_register_device(struct rc_dev *dev)
 		u64 rc_type = (1 << rc_map->scan[0].protocol);
 		rc = dev->change_protocol(dev, &rc_type);
 		if (rc < 0)
-			goto out_raw;
+			goto out_minor;
 		dev->enabled_protocols = rc_type;
 	}
 
 	rc = cdev_add(&dev->cdev, dev->dev.devt, 1);
 	if (rc)
-		goto out_raw;
+		goto out_minor;
 
 	rc = device_add(&dev->dev);
 	if (rc)
@@ -1347,9 +1325,6 @@ out_dev:
 	device_del(&dev->dev);
 out_cdev:
 	cdev_del(&dev->cdev);
-out_raw:
-	if (dev->driver_type == RC_DRIVER_IR_RAW)
-		ir_raw_event_unregister(dev);
 out_minor:
 	ida_simple_remove(&rc_ida, minor);
 	return rc;
@@ -1377,9 +1352,6 @@ void rc_unregister_device(struct rc_dev *dev)
 
 	cdev_del(&dev->cdev);
 
-	if (dev->driver_type == RC_DRIVER_IR_RAW)
-		ir_raw_event_unregister(dev);
-
 	for (i = 0; i < ARRAY_SIZE(dev->keytables); i++)
 		rc_remove_keytable(dev, i);
 
diff --git a/drivers/media/rc/redrat3.c b/drivers/media/rc/redrat3.c
index 3a931a5..17974bf 100644
--- a/drivers/media/rc/redrat3.c
+++ b/drivers/media/rc/redrat3.c
@@ -52,7 +52,7 @@
 #include <linux/slab.h>
 #include <linux/usb.h>
 #include <linux/usb/input.h>
-#include <media/rc-core.h>
+#include <media/rc-ir-raw.h>
 
 /* Driver Information */
 #define DRIVER_AUTHOR "Jarod Wilson <jarod@xxxxxxxxxx>"
@@ -936,7 +936,6 @@ static struct rc_dev *redrat3_init_rc_dev(struct redrat3_dev *rr3)
 	usb_to_input_id(rr3->udev, &rc->input_id);
 	rc->dev.parent = dev;
 	rc->priv = rr3;
-	rc->driver_type = RC_DRIVER_IR_RAW;
 	rc->allowed_protocols = RC_BIT_ALL;
 	rc->timeout = US_TO_NS(2750);
 	rc->tx_ir = redrat3_transmit_ir;
@@ -945,7 +944,7 @@ static struct rc_dev *redrat3_init_rc_dev(struct redrat3_dev *rr3)
 	rc->rx_resolution = US_TO_NS(2);
 	rc->map_name = RC_MAP_HAUPPAUGE;
 
-	ret = rc_register_device(rc);
+	ret = rc_register_ir_raw_device(rc);
 	if (ret < 0) {
 		dev_err(dev, "remote dev registration failed\n");
 		goto out;
@@ -1114,7 +1113,7 @@ static void redrat3_dev_disconnect(struct usb_interface *intf)
 		return;
 
 	usb_set_intfdata(intf, NULL);
-	rc_unregister_device(rr3->rc);
+	rc_unregister_ir_raw_device(rr3->rc);
 	led_classdev_unregister(&rr3->led);
 	del_timer_sync(&rr3->rx_timeout);
 	redrat3_delete(rr3, udev);
diff --git a/drivers/media/rc/streamzap.c b/drivers/media/rc/streamzap.c
index 2659f66..149e824 100644
--- a/drivers/media/rc/streamzap.c
+++ b/drivers/media/rc/streamzap.c
@@ -36,7 +36,7 @@
 #include <linux/slab.h>
 #include <linux/usb.h>
 #include <linux/usb/input.h>
-#include <media/rc-core.h>
+#include <media/rc-ir-raw.h>
 
 #define DRIVER_VERSION	"1.61"
 #define DRIVER_NAME	"streamzap"
@@ -314,12 +314,11 @@ static struct rc_dev *streamzap_init_rc_dev(struct streamzap_ir *sz)
 	usb_to_input_id(sz->usbdev, &rdev->input_id);
 	rdev->dev.parent = dev;
 	rdev->priv = sz;
-	rdev->driver_type = RC_DRIVER_IR_RAW;
 	rdev->allowed_protocols = RC_BIT_ALL;
 	rdev->driver_name = DRIVER_NAME;
 	rdev->map_name = RC_MAP_STREAMZAP;
 
-	ret = rc_register_device(rdev);
+	ret = rc_register_ir_raw_device(rdev);
 	if (ret < 0) {
 		dev_err(dev, "remote input device register failed\n");
 		goto out;
@@ -484,7 +483,7 @@ static void streamzap_disconnect(struct usb_interface *interface)
 		return;
 
 	sz->usbdev = NULL;
-	rc_unregister_device(sz->rdev);
+	rc_unregister_ir_raw_device(sz->rdev);
 	usb_kill_urb(sz->urb_in);
 	usb_free_urb(sz->urb_in);
 	usb_free_coherent(usbdev, sz->buf_in_len, sz->buf_in, sz->dma_in);
diff --git a/drivers/media/rc/ttusbir.c b/drivers/media/rc/ttusbir.c
index bc214e2..19317e2 100644
--- a/drivers/media/rc/ttusbir.c
+++ b/drivers/media/rc/ttusbir.c
@@ -23,7 +23,7 @@
 #include <linux/usb/input.h>
 #include <linux/slab.h>
 #include <linux/leds.h>
-#include <media/rc-core.h>
+#include <media/rc-ir-raw.h>
 
 #define DRIVER_NAME	"ttusbir"
 #define DRIVER_DESC	"TechnoTrend USB IR Receiver"
@@ -317,7 +317,6 @@ static int ttusbir_probe(struct usb_interface *intf,
 	rc->input_phys = tt->phys;
 	usb_to_input_id(tt->udev, &rc->input_id);
 	rc->dev.parent = &intf->dev;
-	rc->driver_type = RC_DRIVER_IR_RAW;
 	rc->allowed_protocols = RC_BIT_ALL;
 	rc->priv = tt;
 	rc->driver_name = DRIVER_NAME;
@@ -329,7 +328,7 @@ static int ttusbir_probe(struct usb_interface *intf,
 	 */
 	rc->rx_resolution = NS_PER_BIT;
 
-	ret = rc_register_device(rc);
+	ret = rc_register_ir_raw_device(rc);
 	if (ret) {
 		dev_err(&intf->dev, "failed to register rc device %d\n", ret);
 		goto out2;
@@ -347,7 +346,7 @@ static int ttusbir_probe(struct usb_interface *intf,
 
 	return 0;
 out3:
-	rc_unregister_device(rc);
+	rc_unregister_ir_raw_device(rc);
 	rc = NULL;
 out2:
 	led_classdev_unregister(&tt->led);
@@ -378,7 +377,7 @@ static void ttusbir_disconnect(struct usb_interface *intf)
 
 	tt->udev = NULL;
 
-	rc_unregister_device(tt->rc);
+	rc_unregister_ir_raw_device(tt->rc);
 	led_classdev_unregister(&tt->led);
 	for (i = 0; i < NUM_URBS; i++) {
 		usb_kill_urb(tt->urb[i]);
diff --git a/drivers/media/rc/winbond-cir.c b/drivers/media/rc/winbond-cir.c
index 8871109..07da3e0 100644
--- a/drivers/media/rc/winbond-cir.c
+++ b/drivers/media/rc/winbond-cir.c
@@ -54,7 +54,7 @@
 #include <linux/slab.h>
 #include <linux/wait.h>
 #include <linux/sched.h>
-#include <media/rc-core.h>
+#include <media/rc-ir-raw.h>
 
 #define DRVNAME "winbond-cir"
 
@@ -1051,7 +1051,6 @@ wbcir_probe(struct pnp_dev *device, const struct pnp_device_id *dev_id)
 		goto exit_unregister_led;
 	}
 
-	data->dev->driver_type = RC_DRIVER_IR_RAW;
 	data->dev->driver_name = DRVNAME;
 	data->dev->input_name = WBCIR_NAME;
 	data->dev->input_phys = "wbcir/cir0";
@@ -1071,7 +1070,7 @@ wbcir_probe(struct pnp_dev *device, const struct pnp_device_id *dev_id)
 	data->dev->rx_resolution = US_TO_NS(2);
 	data->dev->allowed_protocols = RC_BIT_ALL;
 
-	err = rc_register_device(data->dev);
+	err = rc_register_ir_raw_device(data->dev);
 	if (err)
 		goto exit_free_rc;
 
@@ -1117,7 +1116,7 @@ exit_release_ebase:
 exit_release_wbase:
 	release_region(data->wbase, WAKEUP_IOMEM_LEN);
 exit_unregister_device:
-	rc_unregister_device(data->dev);
+	rc_unregister_ir_raw_device(data->dev);
 	data->dev = NULL;
 exit_free_rc:
 	rc_free_device(data->dev);
@@ -1148,7 +1147,7 @@ wbcir_remove(struct pnp_dev *device)
 	/* Clear BUFF_EN, END_EN, MATCH_EN */
 	wbcir_set_bits(data->wbase + WBCIR_REG_WCEIR_EV_EN, 0x00, 0x07);
 
-	rc_unregister_device(data->dev);
+	rc_unregister_ir_raw_device(data->dev);
 
 	led_classdev_unregister(&data->led);
 
diff --git a/drivers/media/usb/dvb-usb-v2/dvb_usb.h b/drivers/media/usb/dvb-usb-v2/dvb_usb.h
index 124b4ba..ccdf0c6 100644
--- a/drivers/media/usb/dvb-usb-v2/dvb_usb.h
+++ b/drivers/media/usb/dvb-usb-v2/dvb_usb.h
@@ -25,6 +25,7 @@
 #include <linux/usb/input.h>
 #include <linux/firmware.h>
 #include <media/rc-core.h>
+#include <media/rc-ir-raw.h>
 
 #include "dvb_frontend.h"
 #include "dvb_demux.h"
@@ -131,7 +132,7 @@ struct dvb_usb_driver_info {
  * @change_protocol: callback to change protocol
  * @query: called to query an event from the device
  * @interval: time in ms between two queries
- * @driver_type: used to point if a device supports raw mode
+ * @rc_raw: used to point if a device supports raw mode
  * @bulk_mode: device supports bulk mode for rc (disable polling mode)
  */
 struct dvb_usb_rc {
@@ -140,7 +141,7 @@ struct dvb_usb_rc {
 	int (*change_protocol)(struct rc_dev *dev, u64 *rc_type);
 	int (*query) (struct dvb_usb_device *d);
 	unsigned int interval;
-	enum rc_driver_type driver_type;
+	bool rc_raw;
 	bool bulk_mode;
 };
 
diff --git a/drivers/media/usb/dvb-usb-v2/dvb_usb_core.c b/drivers/media/usb/dvb-usb-v2/dvb_usb_core.c
index eaa76ef..ea84894b 100644
--- a/drivers/media/usb/dvb-usb-v2/dvb_usb_core.c
+++ b/drivers/media/usb/dvb-usb-v2/dvb_usb_core.c
@@ -163,12 +163,15 @@ static int dvb_usbv2_remote_init(struct dvb_usb_device *d)
 	/* TODO: likely RC-core should took const char * */
 	dev->driver_name = (char *) d->props->driver_name;
 	dev->map_name = d->rc.map_name;
-	dev->driver_type = d->rc.driver_type;
 	dev->allowed_protocols = d->rc.allowed_protos;
 	dev->change_protocol = d->rc.change_protocol;
 	dev->priv = d;
 
-	ret = rc_register_device(dev);
+	if (d->rc.rc_raw)
+		ret = rc_register_ir_raw_device(dev);
+	else
+		ret = rc_register_device(dev);
+
 	if (ret < 0) {
 		rc_free_device(dev);
 		goto err;
@@ -201,7 +204,10 @@ static int dvb_usbv2_remote_exit(struct dvb_usb_device *d)
 
 	if (d->rc_dev) {
 		cancel_delayed_work_sync(&d->rc_query_work);
-		rc_unregister_device(d->rc_dev);
+		if (d->rc.rc_raw)
+			rc_unregister_ir_raw_device(d->rc_dev);
+		else
+			rc_unregister_device(d->rc_dev);
 		d->rc_dev = NULL;
 	}
 
diff --git a/drivers/media/usb/dvb-usb-v2/rtl28xxu.c b/drivers/media/usb/dvb-usb-v2/rtl28xxu.c
index 15f1e70..0412862 100644
--- a/drivers/media/usb/dvb-usb-v2/rtl28xxu.c
+++ b/drivers/media/usb/dvb-usb-v2/rtl28xxu.c
@@ -1373,7 +1373,7 @@ static int rtl2832u_get_rc_config(struct dvb_usb_device *d,
 		return rtl28xx_wr_reg(d, IR_RX_IE, 0x00);
 
 	rc->allowed_protos = RC_BIT_ALL;
-	rc->driver_type = RC_DRIVER_IR_RAW;
+	rc->rc_raw = true;
 	rc->query = rtl2832u_rc_query;
 	rc->interval = 400;
 
diff --git a/drivers/media/usb/dvb-usb/dvb-usb-remote.c b/drivers/media/usb/dvb-usb/dvb-usb-remote.c
index 5986626..88574d0 100644
--- a/drivers/media/usb/dvb-usb/dvb-usb-remote.c
+++ b/drivers/media/usb/dvb-usb/dvb-usb-remote.c
@@ -273,14 +273,17 @@ static int rc_core_dvb_usb_remote_init(struct dvb_usb_device *d)
 	dev->map_name = d->props.rc.core.rc_codes;
 	dev->change_protocol = d->props.rc.core.change_protocol;
 	dev->allowed_protocols = d->props.rc.core.allowed_protos;
-	dev->driver_type = d->props.rc.core.driver_type;
 	usb_to_input_id(d->udev, &dev->input_id);
 	dev->input_name = "IR-receiver inside an USB DVB receiver";
 	dev->input_phys = d->rc_phys;
 	dev->dev.parent = &d->udev->dev;
 	dev->priv = d;
 
-	err = rc_register_device(dev);
+	if (d->props.rc.core.rc_raw)
+		err = rc_register_ir_raw_device(dev);
+	else
+		err = rc_register_device(dev);
+
 	if (err < 0) {
 		rc_free_device(dev);
 		return err;
@@ -341,6 +344,8 @@ int dvb_usb_remote_exit(struct dvb_usb_device *d)
 		cancel_delayed_work_sync(&d->rc_query_work);
 		if (d->props.rc.mode == DVB_RC_LEGACY)
 			input_unregister_device(d->input_dev);
+		else if (d->props.rc.core.rc_raw)
+			rc_unregister_ir_raw_device(d->rc_dev);
 		else
 			rc_unregister_device(d->rc_dev);
 	}
diff --git a/drivers/media/usb/dvb-usb/dvb-usb.h b/drivers/media/usb/dvb-usb/dvb-usb.h
index ce4c4e3..8e4b31e 100644
--- a/drivers/media/usb/dvb-usb/dvb-usb.h
+++ b/drivers/media/usb/dvb-usb/dvb-usb.h
@@ -15,6 +15,7 @@
 #include <linux/firmware.h>
 #include <linux/mutex.h>
 #include <media/rc-core.h>
+#include <media/rc-ir-raw.h>
 
 #include "dvb_frontend.h"
 #include "dvb_demux.h"
@@ -191,7 +192,7 @@ struct dvb_rc_legacy {
  * @rc_codes: name of rc codes table
  * @protocol: type of protocol(s) currently used by the driver
  * @allowed_protos: protocol(s) supported by the driver
- * @driver_type: Used to point if a device supports raw mode
+ * @rc_raw: Used to point if a device supports raw mode
  * @change_protocol: callback to change protocol
  * @rc_query: called to query an event event.
  * @rc_interval: time in ms between two queries.
@@ -201,7 +202,7 @@ struct dvb_rc {
 	char *rc_codes;
 	u64 protocol;
 	u64 allowed_protos;
-	enum rc_driver_type driver_type;
+	bool rc_raw;
 	int (*change_protocol)(struct rc_dev *dev, u64 *rc_type);
 	char *module_name;
 	int (*rc_query) (struct dvb_usb_device *d);
diff --git a/drivers/media/usb/dvb-usb/technisat-usb2.c b/drivers/media/usb/dvb-usb/technisat-usb2.c
index 98d24ae..288f24c 100644
--- a/drivers/media/usb/dvb-usb/technisat-usb2.c
+++ b/drivers/media/usb/dvb-usb/technisat-usb2.c
@@ -733,7 +733,7 @@ static struct dvb_usb_device_properties technisat_usb2_devices = {
 		.module_name = "technisat-usb2",
 		.rc_query    = technisat_usb2_rc_query,
 		.allowed_protos = RC_BIT_ALL,
-		.driver_type    = RC_DRIVER_IR_RAW,
+		.rc_raw      = true,
 	}
 };
 
diff --git a/drivers/media/usb/em28xx/em28xx-input.c b/drivers/media/usb/em28xx/em28xx-input.c
index 1232e32..8fdb515 100644
--- a/drivers/media/usb/em28xx/em28xx-input.c
+++ b/drivers/media/usb/em28xx/em28xx-input.c
@@ -856,9 +856,6 @@ static int em28xx_ir_suspend(struct em28xx *dev)
 	if (ir)
 		cancel_delayed_work_sync(&ir->work);
 	cancel_delayed_work_sync(&dev->buttons_query_work);
-	/* is canceling delayed work sufficient or does the rc event
-	   kthread needs stopping? kthread is stopped in
-	   ir_raw_event_unregister() */
 	return 0;
 }
 
@@ -870,8 +867,6 @@ static int em28xx_ir_resume(struct em28xx *dev)
 		return 0;
 
 	em28xx_info("Resuming input extension");
-	/* if suspend calls ir_raw_event_unregister(), the should call
-	   ir_raw_event_register() */
 	if (ir)
 		schedule_delayed_work(&ir->work, msecs_to_jiffies(ir->polling));
 	if (dev->num_button_polling_addresses)
diff --git a/drivers/media/usb/tm6000/tm6000-input.c b/drivers/media/usb/tm6000/tm6000-input.c
index 7c9b58d..1d4b191 100644
--- a/drivers/media/usb/tm6000/tm6000-input.c
+++ b/drivers/media/usb/tm6000/tm6000-input.c
@@ -452,7 +452,6 @@ int tm6000_ir_init(struct tm6000_core *dev)
 		ir->polling = 50;
 		INIT_DELAYED_WORK(&ir->work, tm6000_ir_handle_key);
 	}
-	rc->driver_type = RC_DRIVER_SCANCODE;
 
 	snprintf(ir->name, sizeof(ir->name), "tm5600/60x0 IR (%s)",
 						dev->name);
diff --git a/include/media/rc-core.h b/include/media/rc-core.h
index 228510e..25c1d38 100644
--- a/include/media/rc-core.h
+++ b/include/media/rc-core.h
@@ -177,11 +177,6 @@ struct rc_keytable_ioctl {
 	char name[RC_KEYTABLE_NAME_SIZE];
 } __packed;
 
-enum rc_driver_type {
-	RC_DRIVER_SCANCODE = 0,	/* Driver or hardware generates a scancode */
-	RC_DRIVER_IR_RAW,	/* Needs a Infra-Red pulse/space decoder */
-};
-
 /* This is used for the input EVIOC[SG]KEYCODE_V2 ioctls */
 struct rc_scancode {
 	__u16 protocol;
@@ -304,6 +299,7 @@ enum rc_filter_type {
  * @rx_resolution : resolution (in ns) of input sampler
  * @tx_resolution: resolution (in ns) of output sampler
  * @change_protocol: allow changing the protocol used on hardware decoders
+ * @get_protocols: returns a bitmask of allowed protocols
  * @change_wakeup_protocol: allow changing the protocol used for wakeup
  *	filtering
  * @open: callback to allow drivers to enable polling/irq when IR input device
@@ -347,7 +343,7 @@ struct rc_dev {
 	wait_queue_head_t		txwait;
 	wait_queue_head_t		rxwait;
 	struct ir_raw_event_ctrl	*raw;
-	enum rc_driver_type		driver_type;
+	unsigned			driver_type;
 	bool				idle;
 	u64				allowed_protocols;
 	u64				enabled_protocols;
@@ -363,6 +359,7 @@ struct rc_dev {
 	u32				max_timeout;
 	u32				rx_resolution;
 	u32				tx_resolution;
+	u64				(*get_protocols)(struct rc_dev *dev);
 	int				(*change_protocol)(struct rc_dev *dev, u64 *rc_type);
 	int				(*change_wakeup_protocol)(struct rc_dev *dev, u64 *rc_type);
 	int				(*open)(struct rc_dev *dev);
@@ -461,70 +458,6 @@ static inline void rc_keydown_notimeout(struct rc_dev *dev, enum rc_type protoco
 	rc_do_keydown(dev, protocol, scancode, toggle, false);
 }
 
-/*
- * From rc-raw.c
- * The Raw interface is specific to InfraRed. It may be a good idea to
- * split it later into a separate header.
- */
-
-enum raw_event_type {
-	IR_SPACE        = (1 << 0),
-	IR_PULSE        = (1 << 1),
-	IR_START_EVENT  = (1 << 2),
-	IR_STOP_EVENT   = (1 << 3),
-};
-
-struct ir_raw_event {
-	union {
-		u32             duration;
-
-		struct {
-			u32     carrier;
-			u8      duty_cycle;
-		};
-	};
-
-	unsigned                pulse:1;
-	unsigned                reset:1;
-	unsigned                timeout:1;
-	unsigned                carrier_report:1;
-};
-
-#define DEFINE_IR_RAW_EVENT(event) \
-	struct ir_raw_event event = { \
-		{ .duration = 0 } , \
-		.pulse = 0, \
-		.reset = 0, \
-		.timeout = 0, \
-		.carrier_report = 0 }
-
-static inline void init_ir_raw_event(struct ir_raw_event *ev)
-{
-	memset(ev, 0, sizeof(*ev));
-}
-
-#define IR_MAX_DURATION         0xFFFFFFFF      /* a bit more than 4 seconds */
-#define US_TO_NS(usec)		((usec) * 1000)
-#define MS_TO_US(msec)		((msec) * 1000)
-#define MS_TO_NS(msec)		((msec) * 1000 * 1000)
-
-void ir_raw_event_handle(struct rc_dev *dev);
-int ir_raw_event_store(struct rc_dev *dev, struct ir_raw_event *ev);
-int ir_raw_event_store_edge(struct rc_dev *dev, enum raw_event_type type);
-int ir_raw_event_store_with_filter(struct rc_dev *dev,
-				struct ir_raw_event *ev);
-void ir_raw_event_set_idle(struct rc_dev *dev, bool idle);
-int ir_raw_get_tx_event(struct rc_dev *dev, struct rc_event *ev);
-
-static inline void ir_raw_event_reset(struct rc_dev *dev)
-{
-	DEFINE_IR_RAW_EVENT(ev);
-	ev.reset = true;
-
-	ir_raw_event_store(dev, &ev);
-	ir_raw_event_handle(dev);
-}
-
 /* extract mask bits out of data and pack them into the result */
 static inline u32 ir_extract_bits(u32 data, u32 mask)
 {
diff --git a/include/media/rc-ir-raw.h b/include/media/rc-ir-raw.h
new file mode 100644
index 0000000..dad3eb2
--- /dev/null
+++ b/include/media/rc-ir-raw.h
@@ -0,0 +1,83 @@
+/*
+ * Remote Controller core header
+ *
+ * Copyright (C) 2009-2010 by Mauro Carvalho Chehab
+ *
+ * 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.
+ */
+
+#ifndef _RC_IR_RAW
+#define _RC_IR_RAW
+
+#include <linux/spinlock.h>
+#include <linux/kfifo.h>
+#include <media/rc-core.h>
+
+enum raw_event_type {
+	IR_SPACE        = (1 << 0),
+	IR_PULSE        = (1 << 1),
+	IR_START_EVENT  = (1 << 2),
+	IR_STOP_EVENT   = (1 << 3),
+};
+
+struct ir_raw_event {
+	union {
+		u32             duration;
+
+		struct {
+			u32     carrier;
+			u8      duty_cycle;
+		};
+	};
+
+	unsigned                pulse:1;
+	unsigned                reset:1;
+	unsigned                timeout:1;
+	unsigned                carrier_report:1;
+};
+
+#define DEFINE_IR_RAW_EVENT(event) \
+	struct ir_raw_event event = { \
+		{ .duration = 0 } , \
+		.pulse = 0, \
+		.reset = 0, \
+		.timeout = 0, \
+		.carrier_report = 0 }
+
+static inline void init_ir_raw_event(struct ir_raw_event *ev)
+{
+	memset(ev, 0, sizeof(*ev));
+}
+
+#define IR_MAX_DURATION         0xFFFFFFFF      /* a bit more than 4 seconds */
+#define US_TO_NS(usec)		((usec) * 1000)
+#define MS_TO_US(msec)		((msec) * 1000)
+#define MS_TO_NS(msec)		((msec) * 1000 * 1000)
+
+void ir_raw_event_handle(struct rc_dev *dev);
+int ir_raw_event_store(struct rc_dev *dev, struct ir_raw_event *ev);
+int ir_raw_event_store_edge(struct rc_dev *dev, enum raw_event_type type);
+int ir_raw_event_store_with_filter(struct rc_dev *dev,
+				struct ir_raw_event *ev);
+void ir_raw_event_set_idle(struct rc_dev *dev, bool idle);
+int ir_raw_get_tx_event(struct rc_dev *dev, struct rc_event *ev);
+int rc_register_ir_raw_device(struct rc_dev *dev);
+void rc_unregister_ir_raw_device(struct rc_dev *dev);
+
+static inline void ir_raw_event_reset(struct rc_dev *dev)
+{
+	DEFINE_IR_RAW_EVENT(ev);
+	ev.reset = true;
+
+	ir_raw_event_store(dev, &ev);
+	ir_raw_event_handle(dev);
+}
+
+#endif /* _RC_IR_RAW */

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [Linux Input]     [Video for Linux]     [Gstreamer Embedded]     [Mplayer Users]     [Linux USB Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]
  Powered by Linux