summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2018-05-18 08:48:40 +0100
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2018-06-05 11:41:59 +0200
commit72571f26757ee81afed5716bad0b4a27cc1bf9f8 (patch)
treed211df9f2ad030df57f80d46b7bc1f008c3a1e1e
parentffedc7ade784610549592baef51895d96e747b7a (diff)
downloadlinux-stable-72571f26757ee81afed5716bad0b4a27cc1bf9f8.tar.gz
linux-stable-72571f26757ee81afed5716bad0b4a27cc1bf9f8.tar.bz2
linux-stable-72571f26757ee81afed5716bad0b4a27cc1bf9f8.zip
drm/i915/lvds: Move acpi lid notification registration to registration phase
commit b9eb9c92899a509fe258d38dd6c214b1de69eee0 upstream. Delay registering ourselves with the acpi lid notification mechanism until we are registering the connectors after initialisation is complete. This prevents a possibility of trying to handle the lid notification before we are ready with the danger of chasing uninitialised function pointers. BUG: unable to handle kernel NULL pointer dereference at 0000000000000000 IP: (null) PGD 0 P4D 0 Oops: 0010 [#1] PREEMPT SMP PTI Modules linked in: arc4(+) iwldvm(+) i915(+) mac80211 i2c_algo_bit coretemp mei_wdt iwlwifi drm_kms_helper kvm_intel wmi_bmof iTCO_wdt iTCO_vendor_support kvm snd_hda_codec_conexant snd_hda_codec_generic drm psmouse cfg80211 irqbypass input_leds pcspkr i2c_i801 snd_hda_intel snd_hda_codec thinkpad_acpi snd_hda_core mei_me lpc_ich snd_hwdep e1000e wmi nvram snd_pcm mei snd_timer shpchp ptp pps_core rfkill syscopyarea snd intel_agp sysfillrect intel_gtt soundcore sysimgblt battery led_class fb_sys_fops ac rtc_cmos agpgart evdev mac_hid acpi_cpufreq ip_tables x_tables ext4 crc32c_generic crc16 mbcache jbd2 fscrypto crypto_simd glue_helper cryptd aes_x86_64 xts algif_skcipher af_alg dm_crypt dm_mod sd_mod uas usb_storage serio_raw atkbd libps2 ahci libahci uhci_hcd libata scsi_mod ehci_pci ehci_hcd usbcore usb_common i8042 serio CPU: 1 PID: 378 Comm: systemd-logind Not tainted 4.16.8-1-ARCH #1 Hardware name: LENOVO 7454CTO/7454CTO, BIOS 6DET72WW (3.22 ) 10/25/2012 RIP: 0010: (null) RSP: 0018:ffffaf4580c33a18 EFLAGS: 00010287 RAX: 0000000000000000 RBX: ffff947533558000 RCX: 000000000000003e RDX: ffffffffc0aa80c0 RSI: ffffaf4580c33a3c RDI: ffff947534e4c000 RBP: ffff947533558338 R08: ffff947534598930 R09: ffffffffc0a928b1 R10: ffffd8f181d5fd40 R11: 0000000000000000 R12: ffffffffc0a928b1 R13: ffff947533558368 R14: ffffffffc0a928a9 R15: ffff947534e4c000 FS: 00007f3dc4ddb940(0000) GS:ffff947539280000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 0000000000000000 CR3: 000000006e214000 CR4: 00000000000406e0 Call Trace: ? intel_modeset_setup_hw_state+0x385/0xf60 [i915] ? __intel_display_resume+0x1e/0xc0 [i915] ? intel_display_resume+0xcc/0x120 [i915] ? intel_lid_notify+0xbc/0xc0 [i915] ? notifier_call_chain+0x47/0x70 ? blocking_notifier_call_chain+0x3e/0x60 ? acpi_lid_notify_state+0x8f/0x1d0 ? acpi_lid_update_state+0x49/0x70 ? acpi_lid_input_open+0x60/0x90 ? input_open_device+0x5d/0xa0 ? evdev_open+0x1ba/0x1e0 [evdev] ? chrdev_open+0xa3/0x1b0 ? cdev_put.part.0+0x20/0x20 ? do_dentry_open+0x14c/0x300 ? path_openat+0x30c/0x1240 ? current_time+0x16/0x60 ? do_filp_open+0x93/0x100 ? __check_object_size+0xfb/0x180 ? do_sys_open+0x186/0x210 ? do_syscall_64+0x74/0x190 ? entry_SYSCALL_64_after_hwframe+0x3d/0xa2 Code: Bad RIP value. RIP: (null) RSP: ffffaf4580c33a18 CR2: 0000000000000000 Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=106559 Fixes: c1c7af608920 ("drm/i915: force mode set at lid open time") Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Cc: Daniel Vetter <daniel.vetter@ffwll.ch> Reviewed-by: Jani Nikula <jani.nikula@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20180518074840.16194-1-chris@chris-wilson.co.uk Cc: stable@vger.kernel.org (cherry picked from commit e578a570dc7c20475774d1ff993825e3bd7a7011) Signed-off-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--drivers/gpu/drm/i915/intel_lvds.c43
1 files changed, 32 insertions, 11 deletions
diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c
index 240308f1b6dd..b898f010b189 100644
--- a/drivers/gpu/drm/i915/intel_lvds.c
+++ b/drivers/gpu/drm/i915/intel_lvds.c
@@ -565,6 +565,36 @@ exit:
return NOTIFY_OK;
}
+static int
+intel_lvds_connector_register(struct drm_connector *connector)
+{
+ struct intel_lvds_connector *lvds = to_lvds_connector(connector);
+ int ret;
+
+ ret = intel_connector_register(connector);
+ if (ret)
+ return ret;
+
+ lvds->lid_notifier.notifier_call = intel_lid_notify;
+ if (acpi_lid_notifier_register(&lvds->lid_notifier)) {
+ DRM_DEBUG_KMS("lid notifier registration failed\n");
+ lvds->lid_notifier.notifier_call = NULL;
+ }
+
+ return 0;
+}
+
+static void
+intel_lvds_connector_unregister(struct drm_connector *connector)
+{
+ struct intel_lvds_connector *lvds = to_lvds_connector(connector);
+
+ if (lvds->lid_notifier.notifier_call)
+ acpi_lid_notifier_unregister(&lvds->lid_notifier);
+
+ intel_connector_unregister(connector);
+}
+
/**
* intel_lvds_destroy - unregister and free LVDS structures
* @connector: connector to free
@@ -577,9 +607,6 @@ static void intel_lvds_destroy(struct drm_connector *connector)
struct intel_lvds_connector *lvds_connector =
to_lvds_connector(connector);
- if (lvds_connector->lid_notifier.notifier_call)
- acpi_lid_notifier_unregister(&lvds_connector->lid_notifier);
-
if (!IS_ERR_OR_NULL(lvds_connector->base.edid))
kfree(lvds_connector->base.edid);
@@ -600,8 +627,8 @@ static const struct drm_connector_funcs intel_lvds_connector_funcs = {
.fill_modes = drm_helper_probe_single_connector_modes,
.atomic_get_property = intel_digital_connector_atomic_get_property,
.atomic_set_property = intel_digital_connector_atomic_set_property,
- .late_register = intel_connector_register,
- .early_unregister = intel_connector_unregister,
+ .late_register = intel_lvds_connector_register,
+ .early_unregister = intel_lvds_connector_unregister,
.destroy = intel_lvds_destroy,
.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
.atomic_duplicate_state = intel_digital_connector_duplicate_state,
@@ -1149,12 +1176,6 @@ out:
lvds_encoder->a3_power = lvds & LVDS_A3_POWER_MASK;
- lvds_connector->lid_notifier.notifier_call = intel_lid_notify;
- if (acpi_lid_notifier_register(&lvds_connector->lid_notifier)) {
- DRM_DEBUG_KMS("lid notifier registration failed\n");
- lvds_connector->lid_notifier.notifier_call = NULL;
- }
-
return;
failed: