Prepare on-demand decoder module loading by adding a module_name member
to struct proto_names and introducing the related load function.

After this patch of the series the decoder modules are still loaded
unconditionally.

Signed-off-by: Heiner Kallweit <hkallwe...@gmail.com>
---
 drivers/media/rc/rc-main.c | 72 +++++++++++++++++++++++++++++++++++++---------
 1 file changed, 59 insertions(+), 13 deletions(-)

diff --git a/drivers/media/rc/rc-main.c b/drivers/media/rc/rc-main.c
index c47ed33..cede8bc 100644
--- a/drivers/media/rc/rc-main.c
+++ b/drivers/media/rc/rc-main.c
@@ -780,27 +780,28 @@ static struct class rc_class = {
 static struct {
        u64     type;
        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",
-- 
2.6.2

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to