aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/IR/ir-sysfs.c
diff options
context:
space:
mode:
authorMaxim Levitsky <maximlevitsky@gmail.com>2010-09-06 17:26:07 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2010-10-21 05:54:13 -0400
commit58b3dd449feaa997129bde23592c6a31da039e4e (patch)
treef2ea7542e56dccc9750593248e0651b914b4302c /drivers/media/IR/ir-sysfs.c
parentc6ef1e7fdc752bbaeacb3570cf955ba2ad60c61b (diff)
[media] IR: make sure we register the input device when it is safe to do so
As soon as input device is registered, it might be accessed (and it is) This can trigger a hardware interrupt that can access not yet initialized ir->raw, (by sending a sample) This can be reproduced by holding down a remote button and reloading the module. And this always crashes the systems where hardware decides to send an interrupt right at the moment it is enabled. Signed-off-by: Maxim Levitsky <maximlevitsky@gmail.com> Acked-by: Jarod Wilson <jarod@redhat.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/IR/ir-sysfs.c')
-rw-r--r--drivers/media/IR/ir-sysfs.c27
1 files changed, 17 insertions, 10 deletions
diff --git a/drivers/media/IR/ir-sysfs.c b/drivers/media/IR/ir-sysfs.c
index 186807aa226d..38423a8da871 100644
--- a/drivers/media/IR/ir-sysfs.c
+++ b/drivers/media/IR/ir-sysfs.c
@@ -265,8 +265,6 @@ static struct device_type rc_dev_type = {
265 */ 265 */
266int ir_register_class(struct input_dev *input_dev) 266int ir_register_class(struct input_dev *input_dev)
267{ 267{
268 int rc;
269 const char *path;
270 struct ir_input_dev *ir_dev = input_get_drvdata(input_dev); 268 struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
271 int devno = find_first_zero_bit(&ir_core_dev_number, 269 int devno = find_first_zero_bit(&ir_core_dev_number,
272 IRRCV_NUM_DEVICES); 270 IRRCV_NUM_DEVICES);
@@ -275,17 +273,28 @@ int ir_register_class(struct input_dev *input_dev)
275 return devno; 273 return devno;
276 274
277 ir_dev->dev.type = &rc_dev_type; 275 ir_dev->dev.type = &rc_dev_type;
276 ir_dev->devno = devno;
278 277
279 ir_dev->dev.class = &ir_input_class; 278 ir_dev->dev.class = &ir_input_class;
280 ir_dev->dev.parent = input_dev->dev.parent; 279 ir_dev->dev.parent = input_dev->dev.parent;
280 input_dev->dev.parent = &ir_dev->dev;
281 dev_set_name(&ir_dev->dev, "rc%d", devno); 281 dev_set_name(&ir_dev->dev, "rc%d", devno);
282 dev_set_drvdata(&ir_dev->dev, ir_dev); 282 dev_set_drvdata(&ir_dev->dev, ir_dev);
283 rc = device_register(&ir_dev->dev); 283 return device_register(&ir_dev->dev);
284 if (rc) 284};
285 return rc; 285
286/**
287 * ir_register_input - registers ir input device with input subsystem
288 * @input_dev: the struct input_dev descriptor of the device
289 */
290
291int ir_register_input(struct input_dev *input_dev)
292{
293 struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
294 int rc;
295 const char *path;
286 296
287 297
288 input_dev->dev.parent = &ir_dev->dev;
289 rc = input_register_device(input_dev); 298 rc = input_register_device(input_dev);
290 if (rc < 0) { 299 if (rc < 0) {
291 device_del(&ir_dev->dev); 300 device_del(&ir_dev->dev);
@@ -301,11 +310,9 @@ int ir_register_class(struct input_dev *input_dev)
301 path ? path : "N/A"); 310 path ? path : "N/A");
302 kfree(path); 311 kfree(path);
303 312
304 ir_dev->devno = devno; 313 set_bit(ir_dev->devno, &ir_core_dev_number);
305 set_bit(devno, &ir_core_dev_number);
306
307 return 0; 314 return 0;
308}; 315}
309 316
310/** 317/**
311 * ir_unregister_class() - removes the sysfs for sysfs for 318 * ir_unregister_class() - removes the sysfs for sysfs for