|
@@ -166,23 +166,68 @@ void drm_sysfs_destroy(void)
|
|
|
/*
|
|
|
* Connector properties
|
|
|
*/
|
|
|
-static ssize_t status_show(struct device *device,
|
|
|
+static ssize_t status_store(struct device *device,
|
|
|
struct device_attribute *attr,
|
|
|
- char *buf)
|
|
|
+ const char *buf, size_t count)
|
|
|
{
|
|
|
struct drm_connector *connector = to_drm_connector(device);
|
|
|
- enum drm_connector_status status;
|
|
|
+ struct drm_device *dev = connector->dev;
|
|
|
+ enum drm_connector_status old_status;
|
|
|
int ret;
|
|
|
|
|
|
- ret = mutex_lock_interruptible(&connector->dev->mode_config.mutex);
|
|
|
+ ret = mutex_lock_interruptible(&dev->mode_config.mutex);
|
|
|
if (ret)
|
|
|
return ret;
|
|
|
|
|
|
- status = connector->funcs->detect(connector, true);
|
|
|
- mutex_unlock(&connector->dev->mode_config.mutex);
|
|
|
+ old_status = connector->status;
|
|
|
+
|
|
|
+ if (sysfs_streq(buf, "detect")) {
|
|
|
+ connector->force = 0;
|
|
|
+ connector->status = connector->funcs->detect(connector, true);
|
|
|
+ } else if (sysfs_streq(buf, "on")) {
|
|
|
+ connector->force = DRM_FORCE_ON;
|
|
|
+ } else if (sysfs_streq(buf, "on-digital")) {
|
|
|
+ connector->force = DRM_FORCE_ON_DIGITAL;
|
|
|
+ } else if (sysfs_streq(buf, "off")) {
|
|
|
+ connector->force = DRM_FORCE_OFF;
|
|
|
+ } else
|
|
|
+ ret = -EINVAL;
|
|
|
+
|
|
|
+ if (ret == 0 && connector->force) {
|
|
|
+ if (connector->force == DRM_FORCE_ON ||
|
|
|
+ connector->force == DRM_FORCE_ON_DIGITAL)
|
|
|
+ connector->status = connector_status_connected;
|
|
|
+ else
|
|
|
+ connector->status = connector_status_disconnected;
|
|
|
+ if (connector->funcs->force)
|
|
|
+ connector->funcs->force(connector);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (old_status != connector->status) {
|
|
|
+ DRM_DEBUG_KMS("[CONNECTOR:%d:%s] status updated from %d to %d\n",
|
|
|
+ connector->base.id,
|
|
|
+ connector->name,
|
|
|
+ old_status, connector->status);
|
|
|
+
|
|
|
+ dev->mode_config.delayed_event = true;
|
|
|
+ if (dev->mode_config.poll_enabled)
|
|
|
+ schedule_delayed_work(&dev->mode_config.output_poll_work,
|
|
|
+ 0);
|
|
|
+ }
|
|
|
+
|
|
|
+ mutex_unlock(&dev->mode_config.mutex);
|
|
|
+
|
|
|
+ return ret;
|
|
|
+}
|
|
|
+
|
|
|
+static ssize_t status_show(struct device *device,
|
|
|
+ struct device_attribute *attr,
|
|
|
+ char *buf)
|
|
|
+{
|
|
|
+ struct drm_connector *connector = to_drm_connector(device);
|
|
|
|
|
|
return snprintf(buf, PAGE_SIZE, "%s\n",
|
|
|
- drm_get_connector_status_name(status));
|
|
|
+ drm_get_connector_status_name(connector->status));
|
|
|
}
|
|
|
|
|
|
static ssize_t dpms_show(struct device *device,
|
|
@@ -339,7 +384,7 @@ static ssize_t select_subconnector_show(struct device *device,
|
|
|
drm_get_dvi_i_select_name((int)subconnector));
|
|
|
}
|
|
|
|
|
|
-static DEVICE_ATTR_RO(status);
|
|
|
+static DEVICE_ATTR_RW(status);
|
|
|
static DEVICE_ATTR_RO(enabled);
|
|
|
static DEVICE_ATTR_RO(dpms);
|
|
|
static DEVICE_ATTR_RO(modes);
|