V4L/DVB: cx88: Only start IR if the input device is opened
authorMauro Carvalho Chehab <mchehab@redhat.com>
Wed, 31 Mar 2010 19:07:49 +0000 (16:07 -0300)
committerMauro Carvalho Chehab <mchehab@redhat.com>
Tue, 18 May 2010 03:53:04 +0000 (00:53 -0300)
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
drivers/media/video/cx88/cx88-input.c
drivers/media/video/cx88/cx88-video.c
drivers/media/video/cx88/cx88.h

index 8b52546c6e1d787eb1bae9829d273166f1e4745f..8bd95be89e67558865c90d5eb12d241ddbe2451c 100644 (file)
@@ -40,6 +40,10 @@ struct cx88_IR {
        struct cx88_core *core;
        struct input_dev *input;
        struct ir_input_state ir;
+       struct ir_dev_props props;
+
+       int users;
+
        char name[32];
        char phys[32];
 
@@ -161,8 +165,16 @@ static enum hrtimer_restart cx88_ir_work(struct hrtimer *timer)
        return HRTIMER_RESTART;
 }
 
-void cx88_ir_start(struct cx88_core *core, struct cx88_IR *ir)
+static int __cx88_ir_start(void *priv)
 {
+       struct cx88_core *core = priv;
+       struct cx88_IR *ir;
+
+       if (!core || !core->ir)
+               return -EINVAL;
+
+       ir = core->ir;
+
        if (ir->polling) {
                hrtimer_init(&ir->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
                ir->timer.function = cx88_ir_work;
@@ -175,10 +187,18 @@ void cx88_ir_start(struct cx88_core *core, struct cx88_IR *ir)
                cx_write(MO_DDS_IO, 0xa80a80);  /* 4 kHz sample rate */
                cx_write(MO_DDSCFG_IO, 0x5);    /* enable */
        }
+       return 0;
 }
 
-void cx88_ir_stop(struct cx88_core *core, struct cx88_IR *ir)
+static void __cx88_ir_stop(void *priv)
 {
+       struct cx88_core *core = priv;
+       struct cx88_IR *ir;
+
+       if (!core || !core->ir)
+               return;
+
+       ir = core->ir;
        if (ir->sampling) {
                cx_write(MO_DDSCFG_IO, 0x0);
                core->pci_irqmask &= ~PCI_INT_IR_SMPINT;
@@ -188,6 +208,37 @@ void cx88_ir_stop(struct cx88_core *core, struct cx88_IR *ir)
                hrtimer_cancel(&ir->timer);
 }
 
+int cx88_ir_start(struct cx88_core *core)
+{
+       if (core->ir->users)
+               return __cx88_ir_start(core);
+
+       return 0;
+}
+
+void cx88_ir_stop(struct cx88_core *core)
+{
+       if (core->ir->users)
+               __cx88_ir_stop(core);
+}
+
+static int cx88_ir_open(void *priv)
+{
+       struct cx88_core *core = priv;
+
+       core->ir->users++;
+       return __cx88_ir_start(core);
+}
+
+static void cx88_ir_close(void *priv)
+{
+       struct cx88_core *core = priv;
+
+       core->ir->users--;
+       if (!core->ir->users)
+               __cx88_ir_stop(core);
+}
+
 /* ---------------------------------------------------------------------- */
 
 int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci)
@@ -383,19 +434,19 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci)
        ir->core = core;
        core->ir = ir;
 
-       cx88_ir_start(core, ir);
+       ir->props.priv = core;
+       ir->props.open = cx88_ir_open;
+       ir->props.close = cx88_ir_close;
 
        /* all done */
-       err = ir_input_register(ir->input, ir_codes, NULL, MODULE_NAME);
+       err = ir_input_register(ir->input, ir_codes, &ir->props, MODULE_NAME);
        if (err)
-               goto err_out_stop;
+               goto err_out_free;
 
        return 0;
 
- err_out_stop:
-       cx88_ir_stop(core, ir);
-       core->ir = NULL;
  err_out_free:
+       core->ir = NULL;
        kfree(ir);
        return err;
 }
@@ -408,7 +459,7 @@ int cx88_ir_fini(struct cx88_core *core)
        if (NULL == ir)
                return 0;
 
-       cx88_ir_stop(core, ir);
+       cx88_ir_stop(core);
        ir_input_unregister(ir->input);
        kfree(ir);
 
index 48c450f4a85a2ad6b7e7ff9cd08c0dde8dae01e4..8e414f7aa76e5b5c695230eec008198060dcfe3a 100644 (file)
@@ -1977,7 +1977,7 @@ static void __devexit cx8800_finidev(struct pci_dev *pci_dev)
        }
 
        if (core->ir)
-               cx88_ir_stop(core, core->ir);
+               cx88_ir_stop(core);
 
        cx88_shutdown(core); /* FIXME */
        pci_disable_device(pci_dev);
@@ -2015,7 +2015,7 @@ static int cx8800_suspend(struct pci_dev *pci_dev, pm_message_t state)
        spin_unlock(&dev->slock);
 
        if (core->ir)
-               cx88_ir_stop(core, core->ir);
+               cx88_ir_stop(core);
        /* FIXME -- shutdown device */
        cx88_shutdown(core);
 
@@ -2056,7 +2056,7 @@ static int cx8800_resume(struct pci_dev *pci_dev)
        /* FIXME: re-initialize hardware */
        cx88_reset(core);
        if (core->ir)
-               cx88_ir_start(core, core->ir);
+               cx88_ir_start(core);
 
        cx_set(MO_PCI_INTMSK, core->pci_irqmask);
 
index b5f054d124f1693c6383b90f58919ed593a7c176..bdb03d33653610efbe4f69a5b613c4629620e2b1 100644 (file)
@@ -41,7 +41,7 @@
 
 #include <linux/version.h>
 #include <linux/mutex.h>
-#define CX88_VERSION_CODE KERNEL_VERSION(0,0,7)
+#define CX88_VERSION_CODE KERNEL_VERSION(0, 0, 8)
 
 #define UNSET (-1U)
 
@@ -683,8 +683,8 @@ s32 cx88_dsp_detect_stereo_sap(struct cx88_core *core);
 int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci);
 int cx88_ir_fini(struct cx88_core *core);
 void cx88_ir_irq(struct cx88_core *core);
-void cx88_ir_start(struct cx88_core *core, struct cx88_IR *ir);
-void cx88_ir_stop(struct cx88_core *core, struct cx88_IR *ir);
+int cx88_ir_start(struct cx88_core *core);
+void cx88_ir_stop(struct cx88_core *core);
 
 /* ----------------------------------------------------------- */
 /* cx88-mpeg.c                                                 */