Merge tag 'modules-next-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git...
[deliverable/linux.git] / drivers / mailbox / mailbox.c
index 19b491d2964f313744513920803e1c327305d7f9..c7fdb57fd166cbf9cb8a0035c56f67a75ff8aa0a 100644 (file)
@@ -318,7 +318,7 @@ struct mbox_chan *mbox_request_channel(struct mbox_client *cl, int index)
                return ERR_PTR(-ENODEV);
        }
 
-       chan = NULL;
+       chan = ERR_PTR(-EPROBE_DEFER);
        list_for_each_entry(mbox, &mbox_cons, node)
                if (mbox->dev->of_node == spec.np) {
                        chan = mbox->of_xlate(mbox, &spec);
@@ -327,7 +327,12 @@ struct mbox_chan *mbox_request_channel(struct mbox_client *cl, int index)
 
        of_node_put(spec.np);
 
-       if (!chan || chan->cl || !try_module_get(mbox->dev->driver->owner)) {
+       if (IS_ERR(chan)) {
+               mutex_unlock(&con_mutex);
+               return chan;
+       }
+
+       if (chan->cl || !try_module_get(mbox->dev->driver->owner)) {
                dev_dbg(dev, "%s: mailbox not free\n", __func__);
                mutex_unlock(&con_mutex);
                return ERR_PTR(-EBUSY);
@@ -357,6 +362,35 @@ struct mbox_chan *mbox_request_channel(struct mbox_client *cl, int index)
 }
 EXPORT_SYMBOL_GPL(mbox_request_channel);
 
+struct mbox_chan *mbox_request_channel_byname(struct mbox_client *cl,
+                                             const char *name)
+{
+       struct device_node *np = cl->dev->of_node;
+       struct property *prop;
+       const char *mbox_name;
+       int index = 0;
+
+       if (!np) {
+               dev_err(cl->dev, "%s() currently only supports DT\n", __func__);
+               return ERR_PTR(-ENOSYS);
+       }
+
+       if (!of_get_property(np, "mbox-names", NULL)) {
+               dev_err(cl->dev,
+                       "%s() requires an \"mbox-names\" property\n", __func__);
+               return ERR_PTR(-ENOSYS);
+       }
+
+       of_property_for_each_string(np, "mbox-names", prop, mbox_name) {
+               if (!strncmp(name, mbox_name, strlen(name)))
+                       break;
+               index++;
+       }
+
+       return mbox_request_channel(cl, index);
+}
+EXPORT_SYMBOL_GPL(mbox_request_channel_byname);
+
 /**
  * mbox_free_channel - The client relinquishes control of a mailbox
  *                     channel by this call.
@@ -390,7 +424,7 @@ of_mbox_index_xlate(struct mbox_controller *mbox,
        int ind = sp->args[0];
 
        if (ind >= mbox->num_chans)
-               return NULL;
+               return ERR_PTR(-EINVAL);
 
        return &mbox->chans[ind];
 }
This page took 0.027469 seconds and 5 git commands to generate.