diff options
author | Maxim Levitsky <maximlevitsky@gmail.com> | 2010-09-06 17:26:07 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2010-10-21 05:54:13 -0400 |
commit | 58b3dd449feaa997129bde23592c6a31da039e4e (patch) | |
tree | f2ea7542e56dccc9750593248e0651b914b4302c /drivers/media/IR/ir-sysfs.c | |
parent | c6ef1e7fdc752bbaeacb3570cf955ba2ad60c61b (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.c | 27 |
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 | */ |
266 | int ir_register_class(struct input_dev *input_dev) | 266 | int 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 | |||
291 | int 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 |