diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index bdcda36..f6cf23b 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -24,6 +24,8 @@ * Eric Anholt */ +#include +#include #include #include "drmP.h" #include "intel_drv.h" @@ -1995,6 +1997,76 @@ intel_user_framebuffer_create(struct drm_device *dev, return fb; } +static void lid_event(struct input_handle *handle, unsigned int type, + unsigned int code, int value) +{ + if (code != SW_LID) + return; + + if (value) { + DRM_ERROR("received lid close event\n"); + } else { + DRM_ERROR("received lid open event\n"); + } +} + +static int lid_connect(struct input_handler *handler, struct input_dev *dev, + const struct input_device_id *id) +{ + struct input_handle *handle; + int ret; + + handle = kzalloc(sizeof(*handle), GFP_KERNEL); + if (!handle) + return -ENOMEM; + + handle->dev = dev; + handle->handler = handler; + handle->name = "i915-lid"; + + ret = input_register_handle(handle); + if (ret) { + DRM_ERROR("failed to register lid handler: %d\n", ret); + kfree(handle); + return ret; + } + + ret = input_open_device(handle); + if (ret) { + DRM_ERROR("failed to open lid device: %d\n", ret); + input_unregister_handle(handle); + kfree(handle); + return ret; + } + + return 0; +} + +static void lid_disconnect(struct input_handle *handle) +{ + input_close_device(handle); + input_unregister_handle(handle); + kfree(handle); +} + +static const struct input_device_id lid_ids[] = { + { + .flags = INPUT_DEVICE_ID_MATCH_SWBIT, + .swbit = { [BIT_WORD(SW_LID)] = BIT_MASK(SW_LID) }, + }, + { }, +}; + +MODULE_DEVICE_TABLE(input, lid_ids); + +static struct input_handler lid_handler = { + .event = lid_event, + .connect = lid_connect, + .disconnect = lid_disconnect, + .name = "i915-lid", + .id_table = lid_ids, +}; + static const struct drm_mode_config_funcs intel_mode_funcs = { .fb_create = intel_user_framebuffer_create, .fb_changed = intelfb_probe, @@ -2038,10 +2110,16 @@ void intel_modeset_init(struct drm_device *dev) } intel_setup_outputs(dev); + + if (input_register_handler(&lid_handler)) + DRM_ERROR("failed to register lid handler\n"); + else + DRM_ERROR("registered lid handler\n"); } void intel_modeset_cleanup(struct drm_device *dev) { + input_unregister_handler(&lid_handler); drm_mode_config_cleanup(dev); }