diff options
author | Mauro Carvalho Chehab <mchehab@redhat.com> | 2010-03-31 15:07:49 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2010-05-17 23:53:04 -0400 |
commit | 92f4fc10d7ba01fd84abbfae963d379c73ba5a0f (patch) | |
tree | 7f6023f8b86d284dd437948c02b28bb93476844b /drivers/media/video/cx88 | |
parent | 716aab44df8bb9bdf16abea9013890274329b61f (diff) |
V4L/DVB: cx88: Only start IR if the input device is opened
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video/cx88')
-rw-r--r-- | drivers/media/video/cx88/cx88-input.c | 69 | ||||
-rw-r--r-- | drivers/media/video/cx88/cx88-video.c | 6 | ||||
-rw-r--r-- | drivers/media/video/cx88/cx88.h | 6 |
3 files changed, 66 insertions, 15 deletions
diff --git a/drivers/media/video/cx88/cx88-input.c b/drivers/media/video/cx88/cx88-input.c index 8b52546c6e1d..8bd95be89e67 100644 --- a/drivers/media/video/cx88/cx88-input.c +++ b/drivers/media/video/cx88/cx88-input.c | |||
@@ -40,6 +40,10 @@ struct cx88_IR { | |||
40 | struct cx88_core *core; | 40 | struct cx88_core *core; |
41 | struct input_dev *input; | 41 | struct input_dev *input; |
42 | struct ir_input_state ir; | 42 | struct ir_input_state ir; |
43 | struct ir_dev_props props; | ||
44 | |||
45 | int users; | ||
46 | |||
43 | char name[32]; | 47 | char name[32]; |
44 | char phys[32]; | 48 | char phys[32]; |
45 | 49 | ||
@@ -161,8 +165,16 @@ static enum hrtimer_restart cx88_ir_work(struct hrtimer *timer) | |||
161 | return HRTIMER_RESTART; | 165 | return HRTIMER_RESTART; |
162 | } | 166 | } |
163 | 167 | ||
164 | void cx88_ir_start(struct cx88_core *core, struct cx88_IR *ir) | 168 | static int __cx88_ir_start(void *priv) |
165 | { | 169 | { |
170 | struct cx88_core *core = priv; | ||
171 | struct cx88_IR *ir; | ||
172 | |||
173 | if (!core || !core->ir) | ||
174 | return -EINVAL; | ||
175 | |||
176 | ir = core->ir; | ||
177 | |||
166 | if (ir->polling) { | 178 | if (ir->polling) { |
167 | hrtimer_init(&ir->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); | 179 | hrtimer_init(&ir->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); |
168 | ir->timer.function = cx88_ir_work; | 180 | ir->timer.function = cx88_ir_work; |
@@ -175,10 +187,18 @@ void cx88_ir_start(struct cx88_core *core, struct cx88_IR *ir) | |||
175 | cx_write(MO_DDS_IO, 0xa80a80); /* 4 kHz sample rate */ | 187 | cx_write(MO_DDS_IO, 0xa80a80); /* 4 kHz sample rate */ |
176 | cx_write(MO_DDSCFG_IO, 0x5); /* enable */ | 188 | cx_write(MO_DDSCFG_IO, 0x5); /* enable */ |
177 | } | 189 | } |
190 | return 0; | ||
178 | } | 191 | } |
179 | 192 | ||
180 | void cx88_ir_stop(struct cx88_core *core, struct cx88_IR *ir) | 193 | static void __cx88_ir_stop(void *priv) |
181 | { | 194 | { |
195 | struct cx88_core *core = priv; | ||
196 | struct cx88_IR *ir; | ||
197 | |||
198 | if (!core || !core->ir) | ||
199 | return; | ||
200 | |||
201 | ir = core->ir; | ||
182 | if (ir->sampling) { | 202 | if (ir->sampling) { |
183 | cx_write(MO_DDSCFG_IO, 0x0); | 203 | cx_write(MO_DDSCFG_IO, 0x0); |
184 | core->pci_irqmask &= ~PCI_INT_IR_SMPINT; | 204 | core->pci_irqmask &= ~PCI_INT_IR_SMPINT; |
@@ -188,6 +208,37 @@ void cx88_ir_stop(struct cx88_core *core, struct cx88_IR *ir) | |||
188 | hrtimer_cancel(&ir->timer); | 208 | hrtimer_cancel(&ir->timer); |
189 | } | 209 | } |
190 | 210 | ||
211 | int cx88_ir_start(struct cx88_core *core) | ||
212 | { | ||
213 | if (core->ir->users) | ||
214 | return __cx88_ir_start(core); | ||
215 | |||
216 | return 0; | ||
217 | } | ||
218 | |||
219 | void cx88_ir_stop(struct cx88_core *core) | ||
220 | { | ||
221 | if (core->ir->users) | ||
222 | __cx88_ir_stop(core); | ||
223 | } | ||
224 | |||
225 | static int cx88_ir_open(void *priv) | ||
226 | { | ||
227 | struct cx88_core *core = priv; | ||
228 | |||
229 | core->ir->users++; | ||
230 | return __cx88_ir_start(core); | ||
231 | } | ||
232 | |||
233 | static void cx88_ir_close(void *priv) | ||
234 | { | ||
235 | struct cx88_core *core = priv; | ||
236 | |||
237 | core->ir->users--; | ||
238 | if (!core->ir->users) | ||
239 | __cx88_ir_stop(core); | ||
240 | } | ||
241 | |||
191 | /* ---------------------------------------------------------------------- */ | 242 | /* ---------------------------------------------------------------------- */ |
192 | 243 | ||
193 | int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci) | 244 | 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) | |||
383 | ir->core = core; | 434 | ir->core = core; |
384 | core->ir = ir; | 435 | core->ir = ir; |
385 | 436 | ||
386 | cx88_ir_start(core, ir); | 437 | ir->props.priv = core; |
438 | ir->props.open = cx88_ir_open; | ||
439 | ir->props.close = cx88_ir_close; | ||
387 | 440 | ||
388 | /* all done */ | 441 | /* all done */ |
389 | err = ir_input_register(ir->input, ir_codes, NULL, MODULE_NAME); | 442 | err = ir_input_register(ir->input, ir_codes, &ir->props, MODULE_NAME); |
390 | if (err) | 443 | if (err) |
391 | goto err_out_stop; | 444 | goto err_out_free; |
392 | 445 | ||
393 | return 0; | 446 | return 0; |
394 | 447 | ||
395 | err_out_stop: | ||
396 | cx88_ir_stop(core, ir); | ||
397 | core->ir = NULL; | ||
398 | err_out_free: | 448 | err_out_free: |
449 | core->ir = NULL; | ||
399 | kfree(ir); | 450 | kfree(ir); |
400 | return err; | 451 | return err; |
401 | } | 452 | } |
@@ -408,7 +459,7 @@ int cx88_ir_fini(struct cx88_core *core) | |||
408 | if (NULL == ir) | 459 | if (NULL == ir) |
409 | return 0; | 460 | return 0; |
410 | 461 | ||
411 | cx88_ir_stop(core, ir); | 462 | cx88_ir_stop(core); |
412 | ir_input_unregister(ir->input); | 463 | ir_input_unregister(ir->input); |
413 | kfree(ir); | 464 | kfree(ir); |
414 | 465 | ||
diff --git a/drivers/media/video/cx88/cx88-video.c b/drivers/media/video/cx88/cx88-video.c index 48c450f4a85a..8e414f7aa76e 100644 --- a/drivers/media/video/cx88/cx88-video.c +++ b/drivers/media/video/cx88/cx88-video.c | |||
@@ -1977,7 +1977,7 @@ static void __devexit cx8800_finidev(struct pci_dev *pci_dev) | |||
1977 | } | 1977 | } |
1978 | 1978 | ||
1979 | if (core->ir) | 1979 | if (core->ir) |
1980 | cx88_ir_stop(core, core->ir); | 1980 | cx88_ir_stop(core); |
1981 | 1981 | ||
1982 | cx88_shutdown(core); /* FIXME */ | 1982 | cx88_shutdown(core); /* FIXME */ |
1983 | pci_disable_device(pci_dev); | 1983 | pci_disable_device(pci_dev); |
@@ -2015,7 +2015,7 @@ static int cx8800_suspend(struct pci_dev *pci_dev, pm_message_t state) | |||
2015 | spin_unlock(&dev->slock); | 2015 | spin_unlock(&dev->slock); |
2016 | 2016 | ||
2017 | if (core->ir) | 2017 | if (core->ir) |
2018 | cx88_ir_stop(core, core->ir); | 2018 | cx88_ir_stop(core); |
2019 | /* FIXME -- shutdown device */ | 2019 | /* FIXME -- shutdown device */ |
2020 | cx88_shutdown(core); | 2020 | cx88_shutdown(core); |
2021 | 2021 | ||
@@ -2056,7 +2056,7 @@ static int cx8800_resume(struct pci_dev *pci_dev) | |||
2056 | /* FIXME: re-initialize hardware */ | 2056 | /* FIXME: re-initialize hardware */ |
2057 | cx88_reset(core); | 2057 | cx88_reset(core); |
2058 | if (core->ir) | 2058 | if (core->ir) |
2059 | cx88_ir_start(core, core->ir); | 2059 | cx88_ir_start(core); |
2060 | 2060 | ||
2061 | cx_set(MO_PCI_INTMSK, core->pci_irqmask); | 2061 | cx_set(MO_PCI_INTMSK, core->pci_irqmask); |
2062 | 2062 | ||
diff --git a/drivers/media/video/cx88/cx88.h b/drivers/media/video/cx88/cx88.h index b5f054d124f1..bdb03d336536 100644 --- a/drivers/media/video/cx88/cx88.h +++ b/drivers/media/video/cx88/cx88.h | |||
@@ -41,7 +41,7 @@ | |||
41 | 41 | ||
42 | #include <linux/version.h> | 42 | #include <linux/version.h> |
43 | #include <linux/mutex.h> | 43 | #include <linux/mutex.h> |
44 | #define CX88_VERSION_CODE KERNEL_VERSION(0,0,7) | 44 | #define CX88_VERSION_CODE KERNEL_VERSION(0, 0, 8) |
45 | 45 | ||
46 | #define UNSET (-1U) | 46 | #define UNSET (-1U) |
47 | 47 | ||
@@ -683,8 +683,8 @@ s32 cx88_dsp_detect_stereo_sap(struct cx88_core *core); | |||
683 | int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci); | 683 | int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci); |
684 | int cx88_ir_fini(struct cx88_core *core); | 684 | int cx88_ir_fini(struct cx88_core *core); |
685 | void cx88_ir_irq(struct cx88_core *core); | 685 | void cx88_ir_irq(struct cx88_core *core); |
686 | void cx88_ir_start(struct cx88_core *core, struct cx88_IR *ir); | 686 | int cx88_ir_start(struct cx88_core *core); |
687 | void cx88_ir_stop(struct cx88_core *core, struct cx88_IR *ir); | 687 | void cx88_ir_stop(struct cx88_core *core); |
688 | 688 | ||
689 | /* ----------------------------------------------------------- */ | 689 | /* ----------------------------------------------------------- */ |
690 | /* cx88-mpeg.c */ | 690 | /* cx88-mpeg.c */ |