Validate the panel size from the device-tree node against the
limitations of struct drm_display_mode. The type only stores sizes
in 16-bit fields. Fail transparently on errors; do not warn.

Signed-off-by: Thomas Zimmermann <[email protected]>
Fixes: 2a6d731a8f16 ("drm/simpledrm: Allow physical width and height 
configuration via panel node")
Cc: Rayyan Ansari <[email protected]>
Cc: <[email protected]> # v6.4+
---
 drivers/gpu/drm/sysfb/simpledrm.c | 35 ++++++++++++++++++++++++++++---
 1 file changed, 32 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/sysfb/simpledrm.c 
b/drivers/gpu/drm/sysfb/simpledrm.c
index 03bd19fadccd..5c1db0785d92 100644
--- a/drivers/gpu/drm/sysfb/simpledrm.c
+++ b/drivers/gpu/drm/sysfb/simpledrm.c
@@ -200,6 +200,35 @@ simplefb_get_memory_of(struct drm_device *dev, struct 
device_node *of_node)
        return res;
 }
 
+static u16
+__simplefb_get_panel_size_mm_of(struct drm_device *dev, struct device_node 
*of_panel_node,
+                               const char *name)
+{
+       int ret;
+       u32 value;
+
+       ret = of_property_read_u32(of_panel_node, name, &value);
+       if (ret || value > U16_MAX) {
+               drm_dbg(dev, "simplefb: cannot parse panel %s: value %u, error 
%d\n",
+                       name, value, ret);
+               return 0; /* not an error, simply ignore */
+       }
+
+       return value;
+}
+
+static u16
+simplefb_get_panel_width_mm_of(struct drm_device *dev, struct device_node 
*of_panel_node)
+{
+       return __simplefb_get_panel_size_mm_of(dev, of_panel_node, "width-mm");
+}
+
+static u16
+simplefb_get_panel_height_mm_of(struct drm_device *dev, struct device_node 
*of_panel_node)
+{
+       return __simplefb_get_panel_size_mm_of(dev, of_panel_node, "height-mm");
+}
+
 /*
  * Simple Framebuffer device
  */
@@ -601,7 +630,7 @@ static struct simpledrm_device 
*simpledrm_device_create(struct drm_driver *drv,
        struct drm_sysfb_device *sysfb;
        struct drm_device *dev;
        int width, height, stride;
-       int width_mm = 0, height_mm = 0;
+       u16 width_mm = 0, height_mm = 0;
        struct device_node *panel_node;
        const struct drm_format_info *format;
        struct resource *res, *mem = NULL;
@@ -665,8 +694,8 @@ static struct simpledrm_device 
*simpledrm_device_create(struct drm_driver *drv,
                        return ERR_CAST(mem);
                panel_node = of_parse_phandle(of_node, "panel", 0);
                if (panel_node) {
-                       simplefb_read_u32_of(dev, panel_node, "width-mm", 
&width_mm);
-                       simplefb_read_u32_of(dev, panel_node, "height-mm", 
&height_mm);
+                       width_mm = simplefb_get_panel_width_mm_of(dev, 
panel_node);
+                       height_mm = simplefb_get_panel_height_mm_of(dev, 
panel_node);
                        of_node_put(panel_node);
                }
        } else {
-- 
2.54.0

Reply via email to