Skip to content

Commit

Permalink
i915: Fix opregion notifications
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Matthew Garrett authored and Keith Packard committed Jul 13, 2011
1 parent 2bf7116 commit f5a3d0c
Show file tree
Hide file tree
Showing 3 changed files with 17 additions and 7 deletions.
7 changes: 4 additions & 3 deletions drivers/acpi/video.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@

#define PREFIX "ACPI: "

#define ACPI_VIDEO_CLASS "video"
#define ACPI_VIDEO_BUS_NAME "Video Bus"
#define ACPI_VIDEO_DEVICE_NAME "Video Device"
#define ACPI_VIDEO_NOTIFY_SWITCH 0x80
Expand Down Expand Up @@ -1445,7 +1444,8 @@ static void acpi_video_bus_notify(struct acpi_device *device, u32 event)
case ACPI_VIDEO_NOTIFY_SWITCH: /* User requested a switch,
* most likely via hotkey. */
acpi_bus_generate_proc_event(device, event, 0);
keycode = KEY_SWITCHVIDEOMODE;
if (!acpi_notifier_call_chain(device, event, 0))
keycode = KEY_SWITCHVIDEOMODE;
break;

case ACPI_VIDEO_NOTIFY_PROBE: /* User plugged in or removed a video
Expand Down Expand Up @@ -1475,7 +1475,8 @@ static void acpi_video_bus_notify(struct acpi_device *device, u32 event)
break;
}

acpi_notifier_call_chain(device, event, 0);
if (event != ACPI_VIDEO_NOTIFY_SWITCH)
acpi_notifier_call_chain(device, event, 0);

if (keycode) {
input_report_key(input, keycode, 1);
Expand Down
15 changes: 11 additions & 4 deletions drivers/gpu/drm/i915/intel_opregion.c
Original file line number Diff line number Diff line change
Expand Up @@ -297,19 +297,26 @@ static int intel_opregion_video_event(struct notifier_block *nb,
/* The only video events relevant to opregion are 0x80. These indicate
either a docking event, lid switch or display switch request. In
Linux, these are handled by the dock, button and video drivers.
We might want to fix the video driver to be opregion-aware in
future, but right now we just indicate to the firmware that the
request has been handled */
*/

struct opregion_acpi *acpi;
struct acpi_bus_event *event = data;
int ret = NOTIFY_OK;

if (strcmp(event->device_class, ACPI_VIDEO_CLASS) != 0)
return NOTIFY_DONE;

if (!system_opregion)
return NOTIFY_DONE;

acpi = system_opregion->acpi;

if (event->type == 0x80 && !(acpi->cevt & 0x1))
ret = NOTIFY_BAD;

acpi->csts = 0;

return NOTIFY_OK;
return ret;
}

static struct notifier_block intel_opregion_notifier = {
Expand Down
2 changes: 2 additions & 0 deletions include/acpi/video.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@

struct acpi_device;

#define ACPI_VIDEO_CLASS "video"

#define ACPI_VIDEO_DISPLAY_CRT 1
#define ACPI_VIDEO_DISPLAY_TV 2
#define ACPI_VIDEO_DISPLAY_DVI 3
Expand Down

0 comments on commit f5a3d0c

Please sign in to comment.