diff options
Diffstat (limited to 'drivers/gpu/drm/drm_crtc.c')
-rw-r--r-- | drivers/gpu/drm/drm_crtc.c | 63 |
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 | } |
2917 | EXPORT_SYMBOL(drm_property_destroy); | 2929 | EXPORT_SYMBOL(drm_property_destroy); |
2918 | 2930 | ||
2919 | void 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 | } | ||
2924 | EXPORT_SYMBOL(drm_connector_attach_property); | ||
2925 | |||
2926 | int 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 | } | ||
2931 | EXPORT_SYMBOL(drm_connector_property_set_value); | ||
2932 | |||
2933 | int 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 | } | ||
2938 | EXPORT_SYMBOL(drm_connector_property_get_value); | ||
2939 | |||
2940 | void drm_object_attach_property(struct drm_mode_object *obj, | 2931 | void 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 | } |
3663 | EXPORT_SYMBOL(drm_mode_config_reset); | 3662 | EXPORT_SYMBOL(drm_mode_config_reset); |
3664 | 3663 | ||