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>
This commit is contained in:
parent
2bf71160f9
commit
f5a3d0c408
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
|
|
@ -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 = {
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue