diff options
-rw-r--r-- | drivers/gpu/drm/drm_sysfs.c | 61 |
1 files changed, 53 insertions, 8 deletions
diff --git a/drivers/gpu/drm/drm_sysfs.c b/drivers/gpu/drm/drm_sysfs.c index 5c99d3773212..ffc305fc2076 100644 --- a/drivers/gpu/drm/drm_sysfs.c +++ b/drivers/gpu/drm/drm_sysfs.c | |||
@@ -166,23 +166,68 @@ void drm_sysfs_destroy(void) | |||
166 | /* | 166 | /* |
167 | * Connector properties | 167 | * Connector properties |
168 | */ | 168 | */ |
169 | static ssize_t status_show(struct device *device, | 169 | static ssize_t status_store(struct device *device, |
170 | struct device_attribute *attr, | 170 | struct device_attribute *attr, |
171 | char *buf) | 171 | const char *buf, size_t count) |
172 | { | 172 | { |
173 | struct drm_connector *connector = to_drm_connector(device); | 173 | struct drm_connector *connector = to_drm_connector(device); |
174 | enum drm_connector_status status; | 174 | struct drm_device *dev = connector->dev; |
175 | enum drm_connector_status old_status; | ||
175 | int ret; | 176 | int ret; |
176 | 177 | ||
177 | ret = mutex_lock_interruptible(&connector->dev->mode_config.mutex); | 178 | ret = mutex_lock_interruptible(&dev->mode_config.mutex); |
178 | if (ret) | 179 | if (ret) |
179 | return ret; | 180 | return ret; |
180 | 181 | ||
181 | status = connector->funcs->detect(connector, true); | 182 | old_status = connector->status; |
182 | mutex_unlock(&connector->dev->mode_config.mutex); | 183 | |
184 | if (sysfs_streq(buf, "detect")) { | ||
185 | connector->force = 0; | ||
186 | connector->status = connector->funcs->detect(connector, true); | ||
187 | } else if (sysfs_streq(buf, "on")) { | ||
188 | connector->force = DRM_FORCE_ON; | ||
189 | } else if (sysfs_streq(buf, "on-digital")) { | ||
190 | connector->force = DRM_FORCE_ON_DIGITAL; | ||
191 | } else if (sysfs_streq(buf, "off")) { | ||
192 | connector->force = DRM_FORCE_OFF; | ||
193 | } else | ||
194 | ret = -EINVAL; | ||
195 | |||
196 | if (ret == 0 && connector->force) { | ||
197 | if (connector->force == DRM_FORCE_ON || | ||
198 | connector->force == DRM_FORCE_ON_DIGITAL) | ||
199 | connector->status = connector_status_connected; | ||
200 | else | ||
201 | connector->status = connector_status_disconnected; | ||
202 | if (connector->funcs->force) | ||
203 | connector->funcs->force(connector); | ||
204 | } | ||
205 | |||
206 | if (old_status != connector->status) { | ||
207 | DRM_DEBUG_KMS("[CONNECTOR:%d:%s] status updated from %d to %d\n", | ||
208 | connector->base.id, | ||
209 | connector->name, | ||
210 | old_status, connector->status); | ||
211 | |||
212 | dev->mode_config.delayed_event = true; | ||
213 | if (dev->mode_config.poll_enabled) | ||
214 | schedule_delayed_work(&dev->mode_config.output_poll_work, | ||
215 | 0); | ||
216 | } | ||
217 | |||
218 | mutex_unlock(&dev->mode_config.mutex); | ||
219 | |||
220 | return ret; | ||
221 | } | ||
222 | |||
223 | static ssize_t status_show(struct device *device, | ||
224 | struct device_attribute *attr, | ||
225 | char *buf) | ||
226 | { | ||
227 | struct drm_connector *connector = to_drm_connector(device); | ||
183 | 228 | ||
184 | return snprintf(buf, PAGE_SIZE, "%s\n", | 229 | return snprintf(buf, PAGE_SIZE, "%s\n", |
185 | drm_get_connector_status_name(status)); | 230 | drm_get_connector_status_name(connector->status)); |
186 | } | 231 | } |
187 | 232 | ||
188 | static ssize_t dpms_show(struct device *device, | 233 | static ssize_t dpms_show(struct device *device, |
@@ -339,7 +384,7 @@ static ssize_t select_subconnector_show(struct device *device, | |||
339 | drm_get_dvi_i_select_name((int)subconnector)); | 384 | drm_get_dvi_i_select_name((int)subconnector)); |
340 | } | 385 | } |
341 | 386 | ||
342 | static DEVICE_ATTR_RO(status); | 387 | static DEVICE_ATTR_RW(status); |
343 | static DEVICE_ATTR_RO(enabled); | 388 | static DEVICE_ATTR_RO(enabled); |
344 | static DEVICE_ATTR_RO(dpms); | 389 | static DEVICE_ATTR_RO(dpms); |
345 | static DEVICE_ATTR_RO(modes); | 390 | static DEVICE_ATTR_RO(modes); |