aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/drm_crtc.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/drm_crtc.c')
-rw-r--r--drivers/gpu/drm/drm_crtc.c63
1 files changed, 31 insertions, 32 deletions
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index ef1b22144d37..f2d667b8bee2 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -470,10 +470,8 @@ void drm_crtc_cleanup(struct drm_crtc *crtc)
470{ 470{
471 struct drm_device *dev = crtc->dev; 471 struct drm_device *dev = crtc->dev;
472 472
473 if (crtc->gamma_store) { 473 kfree(crtc->gamma_store);
474 kfree(crtc->gamma_store); 474 crtc->gamma_store = NULL;
475 crtc->gamma_store = NULL;
476 }
477 475
478 drm_mode_object_put(dev, &crtc->base); 476 drm_mode_object_put(dev, &crtc->base);
479 list_del(&crtc->head); 477 list_del(&crtc->head);
@@ -555,16 +553,17 @@ int drm_connector_init(struct drm_device *dev,
555 INIT_LIST_HEAD(&connector->probed_modes); 553 INIT_LIST_HEAD(&connector->probed_modes);
556 INIT_LIST_HEAD(&connector->modes); 554 INIT_LIST_HEAD(&connector->modes);
557 connector->edid_blob_ptr = NULL; 555 connector->edid_blob_ptr = NULL;
556 connector->status = connector_status_unknown;
558 557
559 list_add_tail(&connector->head, &dev->mode_config.connector_list); 558 list_add_tail(&connector->head, &dev->mode_config.connector_list);
560 dev->mode_config.num_connector++; 559 dev->mode_config.num_connector++;
561 560
562 if (connector_type != DRM_MODE_CONNECTOR_VIRTUAL) 561 if (connector_type != DRM_MODE_CONNECTOR_VIRTUAL)
563 drm_connector_attach_property(connector, 562 drm_object_attach_property(&connector->base,
564 dev->mode_config.edid_property, 563 dev->mode_config.edid_property,
565 0); 564 0);
566 565
567 drm_connector_attach_property(connector, 566 drm_object_attach_property(&connector->base,
568 dev->mode_config.dpms_property, 0); 567 dev->mode_config.dpms_property, 0);
569 568
570 out: 569 out:
@@ -2280,13 +2279,21 @@ static int framebuffer_check(const struct drm_mode_fb_cmd2 *r)
2280 2279
2281 for (i = 0; i < num_planes; i++) { 2280 for (i = 0; i < num_planes; i++) {
2282 unsigned int width = r->width / (i != 0 ? hsub : 1); 2281 unsigned int width = r->width / (i != 0 ? hsub : 1);
2282 unsigned int height = r->height / (i != 0 ? vsub : 1);
2283 unsigned int cpp = drm_format_plane_cpp(r->pixel_format, i);
2283 2284
2284 if (!r->handles[i]) { 2285 if (!r->handles[i]) {
2285 DRM_DEBUG_KMS("no buffer object handle for plane %d\n", i); 2286 DRM_DEBUG_KMS("no buffer object handle for plane %d\n", i);
2286 return -EINVAL; 2287 return -EINVAL;
2287 } 2288 }
2288 2289
2289 if (r->pitches[i] < drm_format_plane_cpp(r->pixel_format, i) * width) { 2290 if ((uint64_t) width * cpp > UINT_MAX)
2291 return -ERANGE;
2292
2293 if ((uint64_t) height * r->pitches[i] + r->offsets[i] > UINT_MAX)
2294 return -ERANGE;
2295
2296 if (r->pitches[i] < width * cpp) {
2290 DRM_DEBUG_KMS("bad pitch %u for plane %d\n", r->pitches[i], i); 2297 DRM_DEBUG_KMS("bad pitch %u for plane %d\n", r->pitches[i], i);
2291 return -EINVAL; 2298 return -EINVAL;
2292 } 2299 }
@@ -2323,6 +2330,11 @@ int drm_mode_addfb2(struct drm_device *dev,
2323 if (!drm_core_check_feature(dev, DRIVER_MODESET)) 2330 if (!drm_core_check_feature(dev, DRIVER_MODESET))
2324 return -EINVAL; 2331 return -EINVAL;
2325 2332
2333 if (r->flags & ~DRM_MODE_FB_INTERLACED) {
2334 DRM_DEBUG_KMS("bad framebuffer flags 0x%08x\n", r->flags);
2335 return -EINVAL;
2336 }
2337
2326 if ((config->min_width > r->width) || (r->width > config->max_width)) { 2338 if ((config->min_width > r->width) || (r->width > config->max_width)) {
2327 DRM_DEBUG_KMS("bad framebuffer width %d, should be >= %d && <= %d\n", 2339 DRM_DEBUG_KMS("bad framebuffer width %d, should be >= %d && <= %d\n",
2328 r->width, config->min_width, config->max_width); 2340 r->width, config->min_width, config->max_width);
@@ -2916,27 +2928,6 @@ void drm_property_destroy(struct drm_device *dev, struct drm_property *property)
2916} 2928}
2917EXPORT_SYMBOL(drm_property_destroy); 2929EXPORT_SYMBOL(drm_property_destroy);
2918 2930
2919void drm_connector_attach_property(struct drm_connector *connector,
2920 struct drm_property *property, uint64_t init_val)
2921{
2922 drm_object_attach_property(&connector->base, property, init_val);
2923}
2924EXPORT_SYMBOL(drm_connector_attach_property);
2925
2926int drm_connector_property_set_value(struct drm_connector *connector,
2927 struct drm_property *property, uint64_t value)
2928{
2929 return drm_object_property_set_value(&connector->base, property, value);
2930}
2931EXPORT_SYMBOL(drm_connector_property_set_value);
2932
2933int drm_connector_property_get_value(struct drm_connector *connector,
2934 struct drm_property *property, uint64_t *val)
2935{
2936 return drm_object_property_get_value(&connector->base, property, val);
2937}
2938EXPORT_SYMBOL(drm_connector_property_get_value);
2939
2940void drm_object_attach_property(struct drm_mode_object *obj, 2931void drm_object_attach_property(struct drm_mode_object *obj,
2941 struct drm_property *property, 2932 struct drm_property *property,
2942 uint64_t init_val) 2933 uint64_t init_val)
@@ -3173,15 +3164,17 @@ int drm_mode_connector_update_edid_property(struct drm_connector *connector,
3173 /* Delete edid, when there is none. */ 3164 /* Delete edid, when there is none. */
3174 if (!edid) { 3165 if (!edid) {
3175 connector->edid_blob_ptr = NULL; 3166 connector->edid_blob_ptr = NULL;
3176 ret = drm_connector_property_set_value(connector, dev->mode_config.edid_property, 0); 3167 ret = drm_object_property_set_value(&connector->base, dev->mode_config.edid_property, 0);
3177 return ret; 3168 return ret;
3178 } 3169 }
3179 3170
3180 size = EDID_LENGTH * (1 + edid->extensions); 3171 size = EDID_LENGTH * (1 + edid->extensions);
3181 connector->edid_blob_ptr = drm_property_create_blob(connector->dev, 3172 connector->edid_blob_ptr = drm_property_create_blob(connector->dev,
3182 size, edid); 3173 size, edid);
3174 if (!connector->edid_blob_ptr)
3175 return -EINVAL;
3183 3176
3184 ret = drm_connector_property_set_value(connector, 3177 ret = drm_object_property_set_value(&connector->base,
3185 dev->mode_config.edid_property, 3178 dev->mode_config.edid_property,
3186 connector->edid_blob_ptr->base.id); 3179 connector->edid_blob_ptr->base.id);
3187 3180
@@ -3204,6 +3197,9 @@ static bool drm_property_change_is_valid(struct drm_property *property,
3204 for (i = 0; i < property->num_values; i++) 3197 for (i = 0; i < property->num_values; i++)
3205 valid_mask |= (1ULL << property->values[i]); 3198 valid_mask |= (1ULL << property->values[i]);
3206 return !(value & ~valid_mask); 3199 return !(value & ~valid_mask);
3200 } else if (property->flags & DRM_MODE_PROP_BLOB) {
3201 /* Only the driver knows */
3202 return true;
3207 } else { 3203 } else {
3208 int i; 3204 int i;
3209 for (i = 0; i < property->num_values; i++) 3205 for (i = 0; i < property->num_values; i++)
@@ -3245,7 +3241,7 @@ static int drm_mode_connector_set_obj_prop(struct drm_mode_object *obj,
3245 3241
3246 /* store the property value if successful */ 3242 /* store the property value if successful */
3247 if (!ret) 3243 if (!ret)
3248 drm_connector_property_set_value(connector, property, value); 3244 drm_object_property_set_value(&connector->base, property, value);
3249 return ret; 3245 return ret;
3250} 3246}
3251 3247
@@ -3656,9 +3652,12 @@ void drm_mode_config_reset(struct drm_device *dev)
3656 if (encoder->funcs->reset) 3652 if (encoder->funcs->reset)
3657 encoder->funcs->reset(encoder); 3653 encoder->funcs->reset(encoder);
3658 3654
3659 list_for_each_entry(connector, &dev->mode_config.connector_list, head) 3655 list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
3656 connector->status = connector_status_unknown;
3657
3660 if (connector->funcs->reset) 3658 if (connector->funcs->reset)
3661 connector->funcs->reset(connector); 3659 connector->funcs->reset(connector);
3660 }
3662} 3661}
3663EXPORT_SYMBOL(drm_mode_config_reset); 3662EXPORT_SYMBOL(drm_mode_config_reset);
3664 3663