]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - drivers/gpu/drm/drm_color_mgmt.c
drm: Make drm_atomic_replace_property_blob_from_id() more generic
[karo-tx-linux.git] / drivers / gpu / drm / drm_color_mgmt.c
index cc23b9a505c0d946ee198b84bb8bc90d03358e85..3eda500fc005ea485b4c5ed52bc19bead9a23814 100644 (file)
@@ -43,7 +43,8 @@
  *
  *     Setting this to NULL (blob property value set to 0) means a
  *     linear/pass-thru gamma table should be used. This is generally the
- *     driver boot-up state too.
+ *     driver boot-up state too. Drivers can access this blob through
+ *     &drm_crtc_state.degamma_lut.
  *
  * “DEGAMMA_LUT_SIZE”:
  *     Unsinged range property to give the size of the lookup table to be set
@@ -60,7 +61,8 @@
  *
  *     Setting this to NULL (blob property value set to 0) means a
  *     unit/pass-thru matrix should be used. This is generally the driver
- *     boot-up state too.
+ *     boot-up state too. Drivers can access the blob for the color conversion
+ *     matrix through &drm_crtc_state.ctm.
  *
  * “GAMMA_LUT”:
  *     Blob property to set the gamma lookup table (LUT) mapping pixel data
@@ -72,7 +74,8 @@
  *
  *     Setting this to NULL (blob property value set to 0) means a
  *     linear/pass-thru gamma table should be used. This is generally the
- *     driver boot-up state too.
+ *     driver boot-up state too. Drivers can access this blob through
+ *     &drm_crtc_state.gamma_lut.
  *
  * “GAMMA_LUT_SIZE”:
  *     Unsigned range property to give the size of the lookup table to be set
@@ -218,28 +221,28 @@ int drm_mode_gamma_set_ioctl(struct drm_device *dev,
        struct drm_crtc *crtc;
        void *r_base, *g_base, *b_base;
        int size;
+       struct drm_modeset_acquire_ctx ctx;
        int ret = 0;
 
        if (!drm_core_check_feature(dev, DRIVER_MODESET))
                return -EINVAL;
 
-       drm_modeset_lock_all(dev);
        crtc = drm_crtc_find(dev, crtc_lut->crtc_id);
-       if (!crtc) {
-               ret = -ENOENT;
-               goto out;
-       }
+       if (!crtc)
+               return -ENOENT;
 
-       if (crtc->funcs->gamma_set == NULL) {
-               ret = -ENOSYS;
-               goto out;
-       }
+       if (crtc->funcs->gamma_set == NULL)
+               return -ENOSYS;
 
        /* memcpy into gamma store */
-       if (crtc_lut->gamma_size != crtc->gamma_size) {
-               ret = -EINVAL;
+       if (crtc_lut->gamma_size != crtc->gamma_size)
+               return -EINVAL;
+
+       drm_modeset_acquire_init(&ctx, 0);
+retry:
+       ret = drm_modeset_lock_all_ctx(dev, &ctx);
+       if (ret)
                goto out;
-       }
 
        size = crtc_lut->gamma_size * (sizeof(uint16_t));
        r_base = crtc->gamma_store;
@@ -260,10 +263,17 @@ int drm_mode_gamma_set_ioctl(struct drm_device *dev,
                goto out;
        }
 
-       ret = crtc->funcs->gamma_set(crtc, r_base, g_base, b_base, crtc->gamma_size);
+       ret = crtc->funcs->gamma_set(crtc, r_base, g_base, b_base,
+                                    crtc->gamma_size, &ctx);
 
 out:
-       drm_modeset_unlock_all(dev);
+       if (ret == -EDEADLK) {
+               drm_modeset_backoff(&ctx);
+               goto retry;
+       }
+       drm_modeset_drop_locks(&ctx);
+       drm_modeset_acquire_fini(&ctx);
+
        return ret;
 
 }
@@ -295,19 +305,15 @@ int drm_mode_gamma_get_ioctl(struct drm_device *dev,
        if (!drm_core_check_feature(dev, DRIVER_MODESET))
                return -EINVAL;
 
-       drm_modeset_lock_all(dev);
        crtc = drm_crtc_find(dev, crtc_lut->crtc_id);
-       if (!crtc) {
-               ret = -ENOENT;
-               goto out;
-       }
+       if (!crtc)
+               return -ENOENT;
 
        /* memcpy into gamma store */
-       if (crtc_lut->gamma_size != crtc->gamma_size) {
-               ret = -EINVAL;
-               goto out;
-       }
+       if (crtc_lut->gamma_size != crtc->gamma_size)
+               return -EINVAL;
 
+       drm_modeset_lock(&crtc->mutex, NULL);
        size = crtc_lut->gamma_size * (sizeof(uint16_t));
        r_base = crtc->gamma_store;
        if (copy_to_user((void __user *)(unsigned long)crtc_lut->red, r_base, size)) {
@@ -327,6 +333,6 @@ int drm_mode_gamma_get_ioctl(struct drm_device *dev,
                goto out;
        }
 out:
-       drm_modeset_unlock_all(dev);
+       drm_modeset_unlock(&crtc->mutex);
        return ret;
 }