diff options
Diffstat (limited to 'linux-core')
-rw-r--r-- | linux-core/drm_crtc.c | 59 | ||||
-rw-r--r-- | linux-core/drm_crtc.h | 5 |
2 files changed, 55 insertions, 9 deletions
diff --git a/linux-core/drm_crtc.c b/linux-core/drm_crtc.c index fba275b7..871f8994 100644 --- a/linux-core/drm_crtc.c +++ b/linux-core/drm_crtc.c @@ -592,6 +592,8 @@ struct drm_output *drm_output_create(struct drm_device *dev, drm_output_attach_property(output, dev->mode_config.edid_property, 0); + drm_output_attach_property(output, dev->mode_config.dpms_property, 0); + mutex_unlock(&dev->mode_config.mutex); return output; @@ -729,6 +731,15 @@ void drm_mode_config_init(struct drm_device *dev) dev->mode_config.edid_property = drm_property_create(dev, DRM_MODE_PROP_BLOB | DRM_MODE_PROP_IMMUTABLE, "EDID", 0); + + dev->mode_config.dpms_property = drm_property_create(dev, + DRM_MODE_PROP_ENUM, + "DPMS", 4); + drm_property_add_enum(dev->mode_config.dpms_property, 0, DPMSModeOn, "On"); + drm_property_add_enum(dev->mode_config.dpms_property, 1, DPMSModeStandby, "Standby"); + drm_property_add_enum(dev->mode_config.dpms_property, 2, DPMSModeSuspend, "Suspend"); + drm_property_add_enum(dev->mode_config.dpms_property, 3, DPMSModeOff, "Off"); + } EXPORT_SYMBOL(drm_mode_config_init); @@ -1985,7 +1996,7 @@ int drm_mode_getproperty_ioctl(struct drm_device *dev, int ret = 0, i; int copied; struct drm_property_enum *prop_enum; - struct drm_property_enum __user *enum_ptr; + struct drm_mode_property_enum __user *enum_ptr; struct drm_property_blob *prop_blob; uint32_t *blob_id_ptr; uint64_t __user *values_ptr; @@ -2015,7 +2026,7 @@ int drm_mode_getproperty_ioctl(struct drm_device *dev, if ((out_resp->count_values >= value_count) && value_count) { values_ptr = (uint64_t *)(unsigned long)out_resp->values_ptr; for (i = 0; i < value_count; i++) { - if (put_user(property->values[i], values_ptr + i)) { + if (copy_to_user(values_ptr + i, &property->values[i], sizeof(uint64_t))) { ret = -EFAULT; goto done; } @@ -2024,19 +2035,21 @@ int drm_mode_getproperty_ioctl(struct drm_device *dev, out_resp->count_values = value_count; if (property->flags & DRM_MODE_PROP_ENUM) { + if ((out_resp->count_enum_blobs >= enum_count) && enum_count) { copied = 0; - enum_ptr = (struct drm_property_enum *)(unsigned long)out_resp->enum_blob_ptr; + enum_ptr = (struct drm_mode_property_enum *)(unsigned long)out_resp->enum_blob_ptr; list_for_each_entry(prop_enum, &property->enum_blob_list, head) { - if (put_user(prop_enum->value, &enum_ptr[copied].value)) { + + if (copy_to_user(&enum_ptr[copied].value, &prop_enum->value, sizeof(uint64_t))) { ret = -EFAULT; goto done; } if (copy_to_user(&enum_ptr[copied].name, - prop_enum->name, DRM_PROP_NAME_LEN)) { - ret = -EFAULT; - goto done; + &prop_enum->name, DRM_PROP_NAME_LEN)) { + ret = -EFAULT; + goto done; } copied++; } @@ -2145,3 +2158,35 @@ int drm_mode_output_update_edid_property(struct drm_output *output, unsigned cha return ret; } EXPORT_SYMBOL(drm_mode_output_update_edid_property); + +int drm_mode_output_property_set_ioctl(struct drm_device *dev, + void *data, struct drm_file *file_priv) +{ + struct drm_mode_output_set_property *out_resp = data; + struct drm_output *output; + int ret = -EINVAL; + int i; + + mutex_lock(&dev->mode_config.mutex); + output= idr_find(&dev->mode_config.crtc_idr, out_resp->output_id); + if (!output || (output->id != out_resp->output_id)) { + goto out; + } + + for (i = 0; i < DRM_OUTPUT_MAX_PROPERTY; i++) { + if (output->property_ids[i] == out_resp->prop_id) + break; + } + + if (i == DRM_OUTPUT_MAX_PROPERTY) { + goto out; + } + + if (output->funcs->set_property) + ret = output->funcs->set_property(output, out_resp->prop_id, out_resp->value); + +out: + mutex_unlock(&dev->mode_config.mutex); + return ret; +} + diff --git a/linux-core/drm_crtc.h b/linux-core/drm_crtc.h index 2c77d9d7..ad5ecc5d 100644 --- a/linux-core/drm_crtc.h +++ b/linux-core/drm_crtc.h @@ -242,8 +242,8 @@ struct drm_property_blob { }; struct drm_property_enum { - struct list_head head; uint64_t value; + struct list_head head; unsigned char name[DRM_PROP_NAME_LEN]; }; @@ -396,7 +396,7 @@ struct drm_output_funcs { enum drm_output_status (*detect)(struct drm_output *output); int (*get_modes)(struct drm_output *output); /* JJJ: type checking for properties via property value type */ - bool (*set_property)(struct drm_output *output, int prop, void *val); + bool (*set_property)(struct drm_output *output, int prop, uint64_t val); void (*cleanup)(struct drm_output *output); }; @@ -503,6 +503,7 @@ struct drm_mode_config { /* pointers to standard properties */ struct list_head property_blob_list; struct drm_property *edid_property; + struct drm_property *dpms_property; }; struct drm_output *drm_output_create(struct drm_device *dev, |