aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/saa7134/saa7134-input.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/video/saa7134/saa7134-input.c')
-rw-r--r--drivers/media/video/saa7134/saa7134-input.c48
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
134static 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
145static void saa7134_ir_stop(struct saa7134_dev *dev)
146{
147 if (dev->remote->polling)
148 del_timer_sync(&dev->remote->timer);
149}
150
134int saa7134_input_init1(struct saa7134_dev *dev) 151int 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
317void saa7134_input_fini(struct saa7134_dev *dev) 338void 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;