drm/sysfb: simpledrm: Improve panel-size validation

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: 2a6d731a8f ("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
This commit is contained in:
Thomas Zimmermann 2026-06-25 11:39:34 +02:00
parent 03f1a3545b
commit 3a75a07619

View File

@ -193,6 +193,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
*/
@ -594,7 +627,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;
@ -658,8 +691,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 {