]> Pileus Git - ~andy/linux/blobdiff - drivers/video/of_display_timing.c
Merge branch 'drm-next' of git://people.freedesktop.org/~airlied/linux
[~andy/linux] / drivers / video / of_display_timing.c
index 2894e0300a33fb8676a7ca8f12b913b5b99ad76b..171821ddd78de381a866e9912bece023a8fcaca5 100644 (file)
@@ -53,22 +53,16 @@ static int parse_timing_property(const struct device_node *np, const char *name,
 }
 
 /**
- * of_get_display_timing - parse display_timing entry from device_node
+ * of_parse_display_timing - parse display_timing entry from device_node
  * @np: device_node with the properties
  **/
-static struct display_timing *of_get_display_timing(const struct device_node
-                                                   *np)
+static int of_parse_display_timing(const struct device_node *np,
+               struct display_timing *dt)
 {
-       struct display_timing *dt;
        u32 val = 0;
        int ret = 0;
 
-       dt = kzalloc(sizeof(*dt), GFP_KERNEL);
-       if (!dt) {
-               pr_err("%s: could not allocate display_timing struct\n",
-                       of_node_full_name(np));
-               return NULL;
-       }
+       memset(dt, 0, sizeof(*dt));
 
        ret |= parse_timing_property(np, "hback-porch", &dt->hback_porch);
        ret |= parse_timing_property(np, "hfront-porch", &dt->hfront_porch);
@@ -104,12 +98,38 @@ static struct display_timing *of_get_display_timing(const struct device_node
        if (ret) {
                pr_err("%s: error reading timing properties\n",
                        of_node_full_name(np));
-               kfree(dt);
-               return NULL;
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+/**
+ * of_get_display_timing - parse a display_timing entry
+ * @np: device_node with the timing subnode
+ * @name: name of the timing node
+ * @dt: display_timing struct to fill
+ **/
+int of_get_display_timing(struct device_node *np, const char *name,
+               struct display_timing *dt)
+{
+       struct device_node *timing_np;
+
+       if (!np) {
+               pr_err("%s: no devicenode given\n", of_node_full_name(np));
+               return -EINVAL;
        }
 
-       return dt;
+       timing_np = of_find_node_by_name(np, name);
+       if (!timing_np) {
+               pr_err("%s: could not find node '%s'\n",
+                       of_node_full_name(np), name);
+               return -ENOENT;
+       }
+
+       return of_parse_display_timing(timing_np, dt);
 }
+EXPORT_SYMBOL_GPL(of_get_display_timing);
 
 /**
  * of_get_display_timings - parse all display_timing entries from a device_node
@@ -177,9 +197,17 @@ struct display_timings *of_get_display_timings(struct device_node *np)
 
        for_each_child_of_node(timings_np, entry) {
                struct display_timing *dt;
+               int r;
 
-               dt = of_get_display_timing(entry);
+               dt = kzalloc(sizeof(*dt), GFP_KERNEL);
                if (!dt) {
+                       pr_err("%s: could not allocate display_timing struct\n",
+                                       of_node_full_name(np));
+                       goto timingfail;
+               }
+
+               r = of_parse_display_timing(entry, dt);
+               if (r) {
                        /*
                         * to not encourage wrong devicetrees, fail in case of
                         * an error