aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915
diff options
context:
space:
mode:
authorMatthew Garrett <mjg@redhat.com>2011-07-12 18:30:52 -0400
committerKeith Packard <keithp@keithp.com>2011-07-13 14:19:47 -0400
commitf5a3d0c4086d1854cbda545092c462b84cba20ce (patch)
treea7ff24f477c618a7680bc617f12366656a0afe23 /drivers/gpu/drm/i915
parent2bf71160f94270319eb965935045f825ec446e8a (diff)
i915: Fix opregion notifications
opregion-based platforms will send ACPI video event 0x80 for a range of notification types for legacy compatibility. This is interpreted as a display switch event, which may not be appropriate in the circumstances. When we receive such an event we should make sure that the platform is genuinely requesting a display switch before passing that event through to userspace. Signed-off-by: Matthew Garrett <mjg@redhat.com> Tested-by: Adam Jackson <ajax@redhat.com> Signed-off-by: Keith Packard <keithp@keithp.com>
Diffstat (limited to 'drivers/gpu/drm/i915')
-rw-r--r--drivers/gpu/drm/i915/intel_opregion.c15
1 files changed, 11 insertions, 4 deletions
diff --git a/drivers/gpu/drm/i915/intel_opregion.c b/drivers/gpu/drm/i915/intel_opregion.c
index d2c710422908..b7c5ddb564d1 100644
--- a/drivers/gpu/drm/i915/intel_opregion.c
+++ b/drivers/gpu/drm/i915/intel_opregion.c
@@ -297,19 +297,26 @@ static int intel_opregion_video_event(struct notifier_block *nb,
297 /* The only video events relevant to opregion are 0x80. These indicate 297 /* The only video events relevant to opregion are 0x80. These indicate
298 either a docking event, lid switch or display switch request. In 298 either a docking event, lid switch or display switch request. In
299 Linux, these are handled by the dock, button and video drivers. 299 Linux, these are handled by the dock, button and video drivers.
300 We might want to fix the video driver to be opregion-aware in 300 */
301 future, but right now we just indicate to the firmware that the
302 request has been handled */
303 301
304 struct opregion_acpi *acpi; 302 struct opregion_acpi *acpi;
303 struct acpi_bus_event *event = data;
304 int ret = NOTIFY_OK;
305
306 if (strcmp(event->device_class, ACPI_VIDEO_CLASS) != 0)
307 return NOTIFY_DONE;
305 308
306 if (!system_opregion) 309 if (!system_opregion)
307 return NOTIFY_DONE; 310 return NOTIFY_DONE;
308 311
309 acpi = system_opregion->acpi; 312 acpi = system_opregion->acpi;
313
314 if (event->type == 0x80 && !(acpi->cevt & 0x1))
315 ret = NOTIFY_BAD;
316
310 acpi->csts = 0; 317 acpi->csts = 0;
311 318
312 return NOTIFY_OK; 319 return ret;
313} 320}
314 321
315static struct notifier_block intel_opregion_notifier = { 322static struct notifier_block intel_opregion_notifier = {