summaryrefslogtreecommitdiff
path: root/drivers/media/rc/rc-main.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/rc/rc-main.c')
-rw-r--r--drivers/media/rc/rc-main.c88
1 files changed, 65 insertions, 23 deletions
diff --git a/drivers/media/rc/rc-main.c b/drivers/media/rc/rc-main.c
index 3f0f71ada..1042fa331 100644
--- a/drivers/media/rc/rc-main.c
+++ b/drivers/media/rc/rc-main.c
@@ -61,7 +61,7 @@ struct rc_map *rc_map_get(const char *name)
struct rc_map_list *map;
map = seek_rc_map(name);
-#ifdef MODULE
+#ifdef CONFIG_MODULES
if (!map) {
int rc = request_module("%s", name);
if (rc < 0) {
@@ -777,30 +777,31 @@ static struct class rc_class = {
* used by the sysfs protocols file. Note that the order
* of the entries is relevant.
*/
-static struct {
+static const struct {
u64 type;
- char *name;
+ const char *name;
+ const char *module_name;
} proto_names[] = {
- { RC_BIT_NONE, "none" },
- { RC_BIT_OTHER, "other" },
- { RC_BIT_UNKNOWN, "unknown" },
+ { RC_BIT_NONE, "none", NULL },
+ { RC_BIT_OTHER, "other", NULL },
+ { RC_BIT_UNKNOWN, "unknown", NULL },
{ RC_BIT_RC5 |
- RC_BIT_RC5X, "rc-5" },
- { RC_BIT_NEC, "nec" },
+ RC_BIT_RC5X, "rc-5", "ir-rc5-decoder" },
+ { RC_BIT_NEC, "nec", "ir-nec-decoder" },
{ RC_BIT_RC6_0 |
RC_BIT_RC6_6A_20 |
RC_BIT_RC6_6A_24 |
RC_BIT_RC6_6A_32 |
- RC_BIT_RC6_MCE, "rc-6" },
- { RC_BIT_JVC, "jvc" },
+ RC_BIT_RC6_MCE, "rc-6", "ir-rc6-decoder" },
+ { RC_BIT_JVC, "jvc", "ir-jvc-decoder" },
{ RC_BIT_SONY12 |
RC_BIT_SONY15 |
- RC_BIT_SONY20, "sony" },
- { RC_BIT_RC5_SZ, "rc-5-sz" },
- { RC_BIT_SANYO, "sanyo" },
- { RC_BIT_SHARP, "sharp" },
- { RC_BIT_MCE_KBD, "mce_kbd" },
- { RC_BIT_XMP, "xmp" },
+ RC_BIT_SONY20, "sony", "ir-sony-decoder" },
+ { RC_BIT_RC5_SZ, "rc-5-sz", "ir-rc5-decoder" },
+ { RC_BIT_SANYO, "sanyo", "ir-sanyo-decoder" },
+ { RC_BIT_SHARP, "sharp", "ir-sharp-decoder" },
+ { RC_BIT_MCE_KBD, "mce_kbd", "ir-mce_kbd-decoder" },
+ { RC_BIT_XMP, "xmp", "ir-xmp-decoder" },
};
/**
@@ -979,6 +980,48 @@ static int parse_protocol_change(u64 *protocols, const char *buf)
return count;
}
+static void ir_raw_load_modules(u64 *protocols)
+
+{
+ u64 available;
+ int i, ret;
+
+ for (i = 0; i < ARRAY_SIZE(proto_names); i++) {
+ if (proto_names[i].type == RC_BIT_NONE ||
+ proto_names[i].type & (RC_BIT_OTHER | RC_BIT_UNKNOWN))
+ continue;
+
+ available = ir_raw_get_allowed_protocols();
+ if (!(*protocols & proto_names[i].type & ~available))
+ continue;
+
+ if (!proto_names[i].module_name) {
+ pr_err("Can't enable IR protocol %s\n",
+ proto_names[i].name);
+ *protocols &= ~proto_names[i].type;
+ continue;
+ }
+
+ ret = request_module("%s", proto_names[i].module_name);
+ if (ret < 0) {
+ pr_err("Couldn't load IR protocol module %s\n",
+ proto_names[i].module_name);
+ *protocols &= ~proto_names[i].type;
+ continue;
+ }
+ msleep(20);
+ available = ir_raw_get_allowed_protocols();
+ if (!(*protocols & proto_names[i].type & ~available))
+ continue;
+
+ pr_err("Loaded IR protocol module %s, \
+ but protocol %s still not available\n",
+ proto_names[i].module_name,
+ proto_names[i].name);
+ *protocols &= ~proto_names[i].type;
+ }
+}
+
/**
* store_protocols() - changes the current/wakeup IR protocol(s)
* @device: the device descriptor
@@ -1045,6 +1088,9 @@ static ssize_t store_protocols(struct device *device,
goto out;
}
+ if (dev->driver_type == RC_DRIVER_IR_RAW)
+ ir_raw_load_modules(&new_protocols);
+
if (new_protocols != old_protocols) {
*current_protocols = new_protocols;
IR_dprintk(1, "Protocols changed to 0x%llx\n",
@@ -1420,17 +1466,13 @@ int rc_register_device(struct rc_dev *dev)
dev->input_dev->rep[REP_PERIOD] = 125;
path = kobject_get_path(&dev->dev.kobj, GFP_KERNEL);
- printk(KERN_INFO "%s: %s as %s\n",
- dev_name(&dev->dev),
- dev->input_name ? dev->input_name : "Unspecified device",
- path ? path : "N/A");
+ dev_info(&dev->dev, "%s as %s\n",
+ dev->input_name ?: "Unspecified device", path ?: "N/A");
kfree(path);
if (dev->driver_type == RC_DRIVER_IR_RAW) {
- /* Load raw decoders, if they aren't already */
if (!raw_init) {
- IR_dprintk(1, "Loading raw decoders\n");
- ir_raw_init();
+ request_module_nowait("ir-lirc-codec");
raw_init = true;
}
/* calls ir_register_device so unlock mutex here*/