diff options
Diffstat (limited to 'drivers/media')
-rw-r--r-- | drivers/media/rc/rc-main.c | 20 |
1 files changed, 17 insertions, 3 deletions
diff --git a/drivers/media/rc/rc-main.c b/drivers/media/rc/rc-main.c index 46da365c9c84..02e2f38c9c85 100644 --- a/drivers/media/rc/rc-main.c +++ b/drivers/media/rc/rc-main.c | |||
@@ -22,6 +22,10 @@ | |||
22 | #include <linux/module.h> | 22 | #include <linux/module.h> |
23 | #include "rc-core-priv.h" | 23 | #include "rc-core-priv.h" |
24 | 24 | ||
25 | /* Bitmap to store allocated device numbers from 0 to IRRCV_NUM_DEVICES - 1 */ | ||
26 | #define IRRCV_NUM_DEVICES 256 | ||
27 | DECLARE_BITMAP(ir_core_dev_number, IRRCV_NUM_DEVICES); | ||
28 | |||
25 | /* Sizes are in bytes, 256 bytes allows for 32 entries on x64 */ | 29 | /* Sizes are in bytes, 256 bytes allows for 32 entries on x64 */ |
26 | #define IR_TAB_MIN_SIZE 256 | 30 | #define IR_TAB_MIN_SIZE 256 |
27 | #define IR_TAB_MAX_SIZE 8192 | 31 | #define IR_TAB_MAX_SIZE 8192 |
@@ -1065,10 +1069,9 @@ EXPORT_SYMBOL_GPL(rc_free_device); | |||
1065 | int rc_register_device(struct rc_dev *dev) | 1069 | int rc_register_device(struct rc_dev *dev) |
1066 | { | 1070 | { |
1067 | static bool raw_init = false; /* raw decoders loaded? */ | 1071 | static bool raw_init = false; /* raw decoders loaded? */ |
1068 | static atomic_t devno = ATOMIC_INIT(0); | ||
1069 | struct rc_map *rc_map; | 1072 | struct rc_map *rc_map; |
1070 | const char *path; | 1073 | const char *path; |
1071 | int rc; | 1074 | int rc, devno; |
1072 | 1075 | ||
1073 | if (!dev || !dev->map_name) | 1076 | if (!dev || !dev->map_name) |
1074 | return -EINVAL; | 1077 | return -EINVAL; |
@@ -1096,7 +1099,15 @@ int rc_register_device(struct rc_dev *dev) | |||
1096 | */ | 1099 | */ |
1097 | mutex_lock(&dev->lock); | 1100 | mutex_lock(&dev->lock); |
1098 | 1101 | ||
1099 | dev->devno = (unsigned long)(atomic_inc_return(&devno) - 1); | 1102 | do { |
1103 | devno = find_first_zero_bit(ir_core_dev_number, | ||
1104 | IRRCV_NUM_DEVICES); | ||
1105 | /* No free device slots */ | ||
1106 | if (devno >= IRRCV_NUM_DEVICES) | ||
1107 | return -ENOMEM; | ||
1108 | } while (test_and_set_bit(devno, ir_core_dev_number)); | ||
1109 | |||
1110 | dev->devno = devno; | ||
1100 | dev_set_name(&dev->dev, "rc%ld", dev->devno); | 1111 | dev_set_name(&dev->dev, "rc%ld", dev->devno); |
1101 | dev_set_drvdata(&dev->dev, dev); | 1112 | dev_set_drvdata(&dev->dev, dev); |
1102 | rc = device_add(&dev->dev); | 1113 | rc = device_add(&dev->dev); |
@@ -1186,6 +1197,7 @@ out_dev: | |||
1186 | device_del(&dev->dev); | 1197 | device_del(&dev->dev); |
1187 | out_unlock: | 1198 | out_unlock: |
1188 | mutex_unlock(&dev->lock); | 1199 | mutex_unlock(&dev->lock); |
1200 | clear_bit(dev->devno, ir_core_dev_number); | ||
1189 | return rc; | 1201 | return rc; |
1190 | } | 1202 | } |
1191 | EXPORT_SYMBOL_GPL(rc_register_device); | 1203 | EXPORT_SYMBOL_GPL(rc_register_device); |
@@ -1197,6 +1209,8 @@ void rc_unregister_device(struct rc_dev *dev) | |||
1197 | 1209 | ||
1198 | del_timer_sync(&dev->timer_keyup); | 1210 | del_timer_sync(&dev->timer_keyup); |
1199 | 1211 | ||
1212 | clear_bit(dev->devno, ir_core_dev_number); | ||
1213 | |||
1200 | if (dev->driver_type == RC_DRIVER_IR_RAW) | 1214 | if (dev->driver_type == RC_DRIVER_IR_RAW) |
1201 | ir_raw_event_unregister(dev); | 1215 | ir_raw_event_unregister(dev); |
1202 | 1216 | ||