Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/ssd130x: Preallocate format-conversion buffer in atomic_check

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.

v6:
* update patch for ssd132x support

Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
Reviewed-by: Javier Martinez Canillas <javierm@redhat.com>
Tested-by: Javier Martinez Canillas <javierm@redhat.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20231009141018.11291-8-tzimmermann@suse.de

+22
+22
drivers/gpu/drm/solomon/ssd130x.c
··· 873 873 struct ssd130x_device *ssd130x = drm_to_ssd130x(drm); 874 874 struct drm_plane_state *plane_state = drm_atomic_get_new_plane_state(state, plane); 875 875 struct ssd130x_plane_state *ssd130x_state = to_ssd130x_plane_state(plane_state); 876 + struct drm_shadow_plane_state *shadow_plane_state = &ssd130x_state->base; 876 877 struct drm_crtc *crtc = plane_state->crtc; 877 878 struct drm_crtc_state *crtc_state = NULL; 878 879 const struct drm_format_info *fi; ··· 898 897 899 898 pitch = drm_format_info_min_pitch(fi, 0, ssd130x->width); 900 899 900 + if (plane_state->fb->format != fi) { 901 + void *buf; 902 + 903 + /* format conversion necessary; reserve buffer */ 904 + buf = drm_format_conv_state_reserve(&shadow_plane_state->fmtcnv_state, 905 + pitch, GFP_KERNEL); 906 + if (!buf) 907 + return -ENOMEM; 908 + } 909 + 901 910 ssd130x_state->buffer = kcalloc(pitch, ssd130x->height, GFP_KERNEL); 902 911 if (!ssd130x_state->buffer) 903 912 return -ENOMEM; ··· 922 911 struct ssd130x_device *ssd130x = drm_to_ssd130x(drm); 923 912 struct drm_plane_state *plane_state = drm_atomic_get_new_plane_state(state, plane); 924 913 struct ssd130x_plane_state *ssd130x_state = to_ssd130x_plane_state(plane_state); 914 + struct drm_shadow_plane_state *shadow_plane_state = &ssd130x_state->base; 925 915 struct drm_crtc *crtc = plane_state->crtc; 926 916 struct drm_crtc_state *crtc_state = NULL; 927 917 const struct drm_format_info *fi; ··· 946 934 return -EINVAL; 947 935 948 936 pitch = drm_format_info_min_pitch(fi, 0, ssd130x->width); 937 + 938 + if (plane_state->fb->format != fi) { 939 + void *buf; 940 + 941 + /* format conversion necessary; reserve buffer */ 942 + buf = drm_format_conv_state_reserve(&shadow_plane_state->fmtcnv_state, 943 + pitch, GFP_KERNEL); 944 + if (!buf) 945 + return -ENOMEM; 946 + } 949 947 950 948 ssd130x_state->buffer = kcalloc(pitch, ssd130x->height, GFP_KERNEL); 951 949 if (!ssd130x_state->buffer)