You could add a function pointer to functionCall in the kernel, initialize it to NULL, and wait for the module to set the pointer to a non-NULL value. Code in readdir would check for the pointer being non-NULL before dereferencing it. This requires the module to know about the function pointer in the kernel by either making the pointer global or similarly easy to access from a module.
If you don't want the driver to know about this modification to the kernel, you could modify readdir to look for the driver to load, then use find_symbol (as mentioned by @chrisharris) to get the address of functionCall, and assign the returned value to some private function pointer somewhere in readdir.
One way to answer the "is the driver loaded" question would be to use register_module_notifier()
static int
my_load_notify(struct notifier_block *self, unsigned long val, void *data)
{
struct module *m = data;
if (0 == strcmp(m->name, "myDriver")) {
// set function pointer(s)
}
}
static struct notifier_block module_load_nb = {
.notifier_call = my_load_notify,
};
static int
my_init(void)
{
...
register_module_notifier(&module_load_nb);
...
}