|
|
@@ -13,6 +13,7 @@
|
|
|
*/
|
|
|
|
|
|
#include <media/rc-core.h>
|
|
|
+#include <linux/atomic.h>
|
|
|
#include <linux/spinlock.h>
|
|
|
#include <linux/delay.h>
|
|
|
#include <linux/input.h>
|
|
|
@@ -723,10 +724,6 @@ int rc_open(struct rc_dev *rdev)
|
|
|
return -EINVAL;
|
|
|
|
|
|
mutex_lock(&rdev->lock);
|
|
|
- if (!rdev->initialized) {
|
|
|
- rval = -EINVAL;
|
|
|
- goto unlock;
|
|
|
- }
|
|
|
|
|
|
if (!rdev->users++ && rdev->open != NULL)
|
|
|
rval = rdev->open(rdev);
|
|
|
@@ -734,7 +731,6 @@ int rc_open(struct rc_dev *rdev)
|
|
|
if (rval)
|
|
|
rdev->users--;
|
|
|
|
|
|
-unlock:
|
|
|
mutex_unlock(&rdev->lock);
|
|
|
|
|
|
return rval;
|
|
|
@@ -879,11 +875,10 @@ static ssize_t show_protocols(struct device *device,
|
|
|
if (!dev)
|
|
|
return -EINVAL;
|
|
|
|
|
|
+ if (!atomic_read(&dev->initialized))
|
|
|
+ return -ERESTARTSYS;
|
|
|
+
|
|
|
mutex_lock(&dev->lock);
|
|
|
- if (!dev->initialized) {
|
|
|
- mutex_unlock(&dev->lock);
|
|
|
- return -EINVAL;
|
|
|
- }
|
|
|
|
|
|
if (fattr->type == RC_FILTER_NORMAL) {
|
|
|
enabled = dev->enabled_protocols;
|
|
|
@@ -1064,6 +1059,9 @@ static ssize_t store_protocols(struct device *device,
|
|
|
if (!dev)
|
|
|
return -EINVAL;
|
|
|
|
|
|
+ if (!atomic_read(&dev->initialized))
|
|
|
+ return -ERESTARTSYS;
|
|
|
+
|
|
|
if (fattr->type == RC_FILTER_NORMAL) {
|
|
|
IR_dprintk(1, "Normal protocol change requested\n");
|
|
|
current_protocols = &dev->enabled_protocols;
|
|
|
@@ -1084,10 +1082,6 @@ static ssize_t store_protocols(struct device *device,
|
|
|
}
|
|
|
|
|
|
mutex_lock(&dev->lock);
|
|
|
- if (!dev->initialized) {
|
|
|
- rc = -EINVAL;
|
|
|
- goto out;
|
|
|
- }
|
|
|
|
|
|
old_protocols = *current_protocols;
|
|
|
new_protocols = old_protocols;
|
|
|
@@ -1168,11 +1162,10 @@ static ssize_t show_filter(struct device *device,
|
|
|
if (!dev)
|
|
|
return -EINVAL;
|
|
|
|
|
|
+ if (!atomic_read(&dev->initialized))
|
|
|
+ return -ERESTARTSYS;
|
|
|
+
|
|
|
mutex_lock(&dev->lock);
|
|
|
- if (!dev->initialized) {
|
|
|
- mutex_unlock(&dev->lock);
|
|
|
- return -EINVAL;
|
|
|
- }
|
|
|
|
|
|
if (fattr->type == RC_FILTER_NORMAL)
|
|
|
filter = &dev->scancode_filter;
|
|
|
@@ -1223,6 +1216,9 @@ static ssize_t store_filter(struct device *device,
|
|
|
if (!dev)
|
|
|
return -EINVAL;
|
|
|
|
|
|
+ if (!atomic_read(&dev->initialized))
|
|
|
+ return -ERESTARTSYS;
|
|
|
+
|
|
|
ret = kstrtoul(buf, 0, &val);
|
|
|
if (ret < 0)
|
|
|
return ret;
|
|
|
@@ -1241,10 +1237,6 @@ static ssize_t store_filter(struct device *device,
|
|
|
return -EINVAL;
|
|
|
|
|
|
mutex_lock(&dev->lock);
|
|
|
- if (!dev->initialized) {
|
|
|
- ret = -EINVAL;
|
|
|
- goto unlock;
|
|
|
- }
|
|
|
|
|
|
new_filter = *filter;
|
|
|
if (fattr->mask)
|
|
|
@@ -1431,6 +1423,7 @@ int rc_register_device(struct rc_dev *dev)
|
|
|
dev->minor = minor;
|
|
|
dev_set_name(&dev->dev, "rc%u", dev->minor);
|
|
|
dev_set_drvdata(&dev->dev, dev);
|
|
|
+ atomic_set(&dev->initialized, 0);
|
|
|
|
|
|
dev->dev.groups = dev->sysfs_groups;
|
|
|
dev->sysfs_groups[attr++] = &rc_dev_protocol_attr_grp;
|
|
|
@@ -1455,10 +1448,6 @@ int rc_register_device(struct rc_dev *dev)
|
|
|
dev->input_dev->phys = dev->input_phys;
|
|
|
dev->input_dev->name = dev->input_name;
|
|
|
|
|
|
- rc = input_register_device(dev->input_dev);
|
|
|
- if (rc)
|
|
|
- goto out_table;
|
|
|
-
|
|
|
/*
|
|
|
* Default delay of 250ms is too short for some protocols, especially
|
|
|
* since the timeout is currently set to 250ms. Increase it to 500ms,
|
|
|
@@ -1474,6 +1463,11 @@ int rc_register_device(struct rc_dev *dev)
|
|
|
*/
|
|
|
dev->input_dev->rep[REP_PERIOD] = 125;
|
|
|
|
|
|
+ /* rc_open will be called here */
|
|
|
+ rc = input_register_device(dev->input_dev);
|
|
|
+ if (rc)
|
|
|
+ goto out_table;
|
|
|
+
|
|
|
path = kobject_get_path(&dev->dev.kobj, GFP_KERNEL);
|
|
|
dev_info(&dev->dev, "%s as %s\n",
|
|
|
dev->input_name ?: "Unspecified device", path ?: "N/A");
|
|
|
@@ -1497,8 +1491,9 @@ int rc_register_device(struct rc_dev *dev)
|
|
|
dev->enabled_protocols = rc_type;
|
|
|
}
|
|
|
|
|
|
+ /* Allow the RC sysfs nodes to be accessible */
|
|
|
mutex_lock(&dev->lock);
|
|
|
- dev->initialized = true;
|
|
|
+ atomic_set(&dev->initialized, 1);
|
|
|
mutex_unlock(&dev->lock);
|
|
|
|
|
|
IR_dprintk(1, "Registered rc%u (driver: %s, remote: %s, mode %s)\n",
|