aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <m.chehab@samsung.com>2014-01-14 14:27:55 -0500
committerMauro Carvalho Chehab <m.chehab@samsung.com>2014-01-15 08:46:37 -0500
commit587d1b06e07b4a079453c74ba9edf17d21931049 (patch)
tree27085d4b19b5d52f252bc5a0b3f63752cb69009c /drivers/media
parentc3aed262186841bf01feb9603885671ea567ebd9 (diff)
[media] rc-core: reuse device numbers
Before changeset d8b4b5822f51e, the remote controller device numbers were released when the device were unregistered. That helped to maintain some sanity, as, when USB devices are replugged, the remote controller would get the same number. Restore the same behaviour. Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
Diffstat (limited to 'drivers/media')
-rw-r--r--drivers/media/rc/rc-main.c20
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
27DECLARE_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);
1065int rc_register_device(struct rc_dev *dev) 1069int 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);
1187out_unlock: 1198out_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}
1191EXPORT_SYMBOL_GPL(rc_register_device); 1203EXPORT_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