drm: Lighten sysfs connector 'status'
Since the beginning, sysfs/connector/status has done a heavyweight detection of the current connector status. But no user, such as upowerd or logind, has ever desired to initiate a probe. Move the probing into a new attribute so that existing readers get the behaviour they desire. v2: David Herrmann suggested using "echo detect > /sys/.../status" to trigger the probing, which is a fine idea. This extends that to also allow the user to apply the force detection overrides at runtime. v3: Now with airlied's email address fixed! Requires sysfs_streq() Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> Cc: Daniel Vetter <daniel.vetter@ffwll.ch> Cc: David Herrmann <dh.herrmann@gmail.com> Cc: Dave Airlie <airlied@redhat.com> Cc: Alex Deucher <alexdeucher@gmail.com> Reviewed-by: David Herrmann <dh.herrmann@gmail.com> Reviewed-by: Alex Deucher <alexander.deucher@amd.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
This commit is contained in:
parent
3461b30b3e
commit
c484f02d0f
|
@ -166,23 +166,68 @@ void drm_sysfs_destroy(void)
|
|||
/*
|
||||
* Connector properties
|
||||
*/
|
||||
static ssize_t status_store(struct device *device,
|
||||
struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
struct drm_connector *connector = to_drm_connector(device);
|
||||
struct drm_device *dev = connector->dev;
|
||||
enum drm_connector_status old_status;
|
||||
int ret;
|
||||
|
||||
ret = mutex_lock_interruptible(&dev->mode_config.mutex);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
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);
|
||||
enum drm_connector_status status;
|
||||
int ret;
|
||||
|
||||
ret = mutex_lock_interruptible(&connector->dev->mode_config.mutex);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
status = connector->funcs->detect(connector, true);
|
||||
mutex_unlock(&connector->dev->mode_config.mutex);
|
||||
|
||||
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);
|
||||
|
|
Loading…
Reference in New Issue