diff options
Diffstat (limited to 'drivers/media/video/saa7134/saa7134-input.c')
-rw-r--r-- | drivers/media/video/saa7134/saa7134-input.c | 48 |
1 files changed, 34 insertions, 14 deletions
diff --git a/drivers/media/video/saa7134/saa7134-input.c b/drivers/media/video/saa7134/saa7134-input.c index 83887d1876a9..5d2bf15239f7 100644 --- a/drivers/media/video/saa7134/saa7134-input.c +++ b/drivers/media/video/saa7134/saa7134-input.c | |||
@@ -131,6 +131,23 @@ static void saa7134_input_timer(unsigned long data) | |||
131 | mod_timer(&ir->timer, timeout); | 131 | mod_timer(&ir->timer, timeout); |
132 | } | 132 | } |
133 | 133 | ||
134 | static void saa7134_ir_start(struct saa7134_dev *dev, struct saa7134_ir *ir) | ||
135 | { | ||
136 | if (ir->polling) { | ||
137 | init_timer(&ir->timer); | ||
138 | ir->timer.function = saa7134_input_timer; | ||
139 | ir->timer.data = (unsigned long)dev; | ||
140 | ir->timer.expires = jiffies + HZ; | ||
141 | add_timer(&ir->timer); | ||
142 | } | ||
143 | } | ||
144 | |||
145 | static void saa7134_ir_stop(struct saa7134_dev *dev) | ||
146 | { | ||
147 | if (dev->remote->polling) | ||
148 | del_timer_sync(&dev->remote->timer); | ||
149 | } | ||
150 | |||
134 | int saa7134_input_init1(struct saa7134_dev *dev) | 151 | int saa7134_input_init1(struct saa7134_dev *dev) |
135 | { | 152 | { |
136 | struct saa7134_ir *ir; | 153 | struct saa7134_ir *ir; |
@@ -141,6 +158,7 @@ int saa7134_input_init1(struct saa7134_dev *dev) | |||
141 | u32 mask_keyup = 0; | 158 | u32 mask_keyup = 0; |
142 | int polling = 0; | 159 | int polling = 0; |
143 | int ir_type = IR_TYPE_OTHER; | 160 | int ir_type = IR_TYPE_OTHER; |
161 | int err; | ||
144 | 162 | ||
145 | if (dev->has_remote != SAA7134_REMOTE_GPIO) | 163 | if (dev->has_remote != SAA7134_REMOTE_GPIO) |
146 | return -ENODEV; | 164 | return -ENODEV; |
@@ -267,9 +285,8 @@ int saa7134_input_init1(struct saa7134_dev *dev) | |||
267 | ir = kzalloc(sizeof(*ir), GFP_KERNEL); | 285 | ir = kzalloc(sizeof(*ir), GFP_KERNEL); |
268 | input_dev = input_allocate_device(); | 286 | input_dev = input_allocate_device(); |
269 | if (!ir || !input_dev) { | 287 | if (!ir || !input_dev) { |
270 | kfree(ir); | 288 | err = -ENOMEM; |
271 | input_free_device(input_dev); | 289 | goto err_out_free; |
272 | return -ENOMEM; | ||
273 | } | 290 | } |
274 | 291 | ||
275 | ir->dev = input_dev; | 292 | ir->dev = input_dev; |
@@ -300,18 +317,22 @@ int saa7134_input_init1(struct saa7134_dev *dev) | |||
300 | } | 317 | } |
301 | input_dev->cdev.dev = &dev->pci->dev; | 318 | input_dev->cdev.dev = &dev->pci->dev; |
302 | 319 | ||
303 | /* all done */ | ||
304 | dev->remote = ir; | 320 | dev->remote = ir; |
305 | if (ir->polling) { | 321 | saa7134_ir_start(dev, ir); |
306 | init_timer(&ir->timer); | 322 | |
307 | ir->timer.function = saa7134_input_timer; | 323 | err = input_register_device(ir->dev); |
308 | ir->timer.data = (unsigned long)dev; | 324 | if (err) |
309 | ir->timer.expires = jiffies + HZ; | 325 | goto err_out_stop; |
310 | add_timer(&ir->timer); | ||
311 | } | ||
312 | 326 | ||
313 | input_register_device(ir->dev); | ||
314 | return 0; | 327 | return 0; |
328 | |||
329 | err_out_stop: | ||
330 | saa7134_ir_stop(dev); | ||
331 | dev->remote = NULL; | ||
332 | err_out_free: | ||
333 | input_free_device(input_dev); | ||
334 | kfree(ir); | ||
335 | return err; | ||
315 | } | 336 | } |
316 | 337 | ||
317 | void saa7134_input_fini(struct saa7134_dev *dev) | 338 | void saa7134_input_fini(struct saa7134_dev *dev) |
@@ -319,8 +340,7 @@ void saa7134_input_fini(struct saa7134_dev *dev) | |||
319 | if (NULL == dev->remote) | 340 | if (NULL == dev->remote) |
320 | return; | 341 | return; |
321 | 342 | ||
322 | if (dev->remote->polling) | 343 | saa7134_ir_stop(dev); |
323 | del_timer_sync(&dev->remote->timer); | ||
324 | input_unregister_device(dev->remote->dev); | 344 | input_unregister_device(dev->remote->dev); |
325 | kfree(dev->remote); | 345 | kfree(dev->remote); |
326 | dev->remote = NULL; | 346 | dev->remote = NULL; |