blob: af6701516fd5afcdb670c2fb801e5f01c67172b9 [file]
From fdce891d362019055b6c8af7e855d30111b07a2a Mon Sep 17 00:00:00 2001
From: Sasha Levin <sashal@kernel.org>
Date: Sat, 12 Sep 2026 11:20:12 -0400
Subject: drm/sysfb: simpledrm: Improve panel-size validation
From: Thomas Zimmermann <tzimmermann@suse.de>
[ Upstream commit 3a75a0761914d01c7362adf1f906cc1d1762c189 ]
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.
v3:
- move comments to a more prominent place (Thierry)
v2:
- only use initialized values in debugging output (Sashiko)
Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
Reviewed-by: Thierry Reding <treding@nvidia.com>
Reviewed-by: Maxime Ripard <mripard@kernel.org>
Reviewed-by: Javier Martinez Canillas <javierm@redhat.com>
Fixes: 2a6d731a8f16 ("drm/simpledrm: Allow physical width and height configuration via panel node")
Cc: Rayyan Ansari <rayyan@ansari.sh>
Cc: <stable@vger.kernel.org> # v6.4+
Link: https://patch.msgid.link/20260625094509.157581-3-tzimmermann@suse.de
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/gpu/drm/tiny/simpledrm.c | 49 ++++++++++++++++++++++++++++++--
1 file changed, 46 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/tiny/simpledrm.c b/drivers/gpu/drm/tiny/simpledrm.c
index 30676b1073034..2abe80eec793b 100644
--- a/drivers/gpu/drm/tiny/simpledrm.c
+++ b/drivers/gpu/drm/tiny/simpledrm.c
@@ -210,6 +210,39 @@ simplefb_get_memory_of(struct drm_device *dev, struct device_node *of_node)
return res;
}
+static int __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) {
+ drm_dbg(dev, "simplefb: cannot parse panel %s: error %d\n",
+ name, ret);
+ return ret;
+ } else if (value > U16_MAX) {
+ drm_dbg(dev, "simplefb: panel %s of %u exceeds maximum value\n",
+ name, value);
+ return -EINVAL;
+ }
+
+ return value;
+}
+
+static int 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 int 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
*/
@@ -625,7 +658,7 @@ static struct simpledrm_device *simpledrm_device_create(struct drm_driver *drv,
struct simpledrm_device *sdev;
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;
@@ -685,8 +718,18 @@ 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);
+ /*
+ * Ignore errors from parsing the physical panel
+ * size. Using the pre-initialized sizes of 0 will
+ * make drm_sysfb_mode() calculate a default physical
+ * size based on a resolution of 96 dpi.
+ */
+ ret = simplefb_get_panel_width_mm_of(dev, panel_node);
+ if (ret > 0)
+ width_mm = ret;
+ ret = simplefb_get_panel_height_mm_of(dev, panel_node);
+ if (ret > 0)
+ height_mm = ret;
of_node_put(panel_node);
}
} else {
--
2.53.0