Preallocate the format-conversion state's storage in the plane's
atomic_check function if a format conversion is necessary. Allows
the update to fail if no memory is available. Avoids the same
allocation within atomic_update, which may not fail.

Signed-off-by: Thomas Zimmermann <tzimmerm...@suse.de>
---
 drivers/gpu/drm/solomon/ssd130x.c | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/drivers/gpu/drm/solomon/ssd130x.c 
b/drivers/gpu/drm/solomon/ssd130x.c
index dccbfe33edb5e..d3761e48bca12 100644
--- a/drivers/gpu/drm/solomon/ssd130x.c
+++ b/drivers/gpu/drm/solomon/ssd130x.c
@@ -638,6 +638,7 @@ static int ssd130x_primary_plane_atomic_check(struct 
drm_plane *plane,
        struct ssd130x_device *ssd130x = drm_to_ssd130x(drm);
        struct drm_plane_state *plane_state = 
drm_atomic_get_new_plane_state(state, plane);
        struct ssd130x_plane_state *ssd130x_state = 
to_ssd130x_plane_state(plane_state);
+       struct drm_shadow_plane_state *shadow_plane_state = 
&ssd130x_state->base;
        struct drm_crtc *crtc = plane_state->crtc;
        struct drm_crtc_state *crtc_state = NULL;
        const struct drm_format_info *fi;
@@ -662,6 +663,16 @@ static int ssd130x_primary_plane_atomic_check(struct 
drm_plane *plane,
 
        pitch = drm_format_info_min_pitch(fi, 0, ssd130x->width);
 
+       if (plane_state->fb->format != fi) {
+               void *buf;
+
+               /* format conversion necessary; reserve buffer */
+               buf = 
drm_format_conv_state_reserve(&shadow_plane_state->fmtcnv_state,
+                                                   pitch, GFP_KERNEL);
+               if (!buf)
+                       return -ENOMEM;
+       }
+
        ssd130x_state->buffer = kcalloc(pitch, ssd130x->height, GFP_KERNEL);
        if (!ssd130x_state->buffer)
                return -ENOMEM;
-- 
2.42.0

Reply via email to