drm/i915: add unregister callback to connector
authorImre Deak <imre.deak@intel.com>
Tue, 11 Feb 2014 15:12:48 +0000 (17:12 +0200)
committerDaniel Vetter <daniel.vetter@ffwll.ch>
Fri, 14 Feb 2014 10:24:47 +0000 (11:24 +0100)
Since

commit d9255d57147e1dbcebdf6670409c2fa0ac3609e6
Author: Paulo Zanoni <paulo.r.zanoni@intel.com>
Date:   Thu Sep 26 20:05:59 2013 -0300

it became clear that we need to separate the unload sequence into two
parts:

1. remove all interfaces through which new operations on some object
   (crtc, encoder, connector) can be started and make sure all pending
   operations are completed
2. do the actual tear down of the internal representation of the above
   objects

The above commit achieved this separation for connectors by splitting
out the sysfs removal part from the connector's destroy callback and
doing this removal before calling drm_mode_config_cleanup() which does
the actual tear-down of all the drm objects.

Since we'll have to customize the interface removal part for different
types of connectors in the upcoming patches, add a new unregister
callback and move the interface removal part to it.

No functional change.

Signed-off-by: Imre Deak <imre.deak@intel.com>
Reviewed-by: Antti Koskipää <antti.koskipaa@linux.intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
drivers/gpu/drm/i915/i915_drv.h
drivers/gpu/drm/i915/intel_crt.c
drivers/gpu/drm/i915/intel_display.c
drivers/gpu/drm/i915/intel_dp.c
drivers/gpu/drm/i915/intel_drv.h
drivers/gpu/drm/i915/intel_dsi.c
drivers/gpu/drm/i915/intel_dvo.c
drivers/gpu/drm/i915/intel_hdmi.c
drivers/gpu/drm/i915/intel_lvds.c
drivers/gpu/drm/i915/intel_sdvo.c
drivers/gpu/drm/i915/intel_tv.c

index 49889003feb248ddc59bf46b4a082b31a3d77859..d33199452c111df076812b057b8909da7624deec 100644 (file)
@@ -2546,6 +2546,7 @@ extern void intel_modeset_suspend_hw(struct drm_device *dev);
 extern void intel_modeset_init(struct drm_device *dev);
 extern void intel_modeset_gem_init(struct drm_device *dev);
 extern void intel_modeset_cleanup(struct drm_device *dev);
+extern void intel_connector_unregister(struct intel_connector *);
 extern int intel_modeset_vga_set_state(struct drm_device *dev, bool state);
 extern void intel_modeset_setup_hw_state(struct drm_device *dev,
                                         bool force_restore);
index 5b444a4b625caa449d26eebaf12126253344521d..9864aa1ccbe825a09d9b341af911996994b87915 100644 (file)
@@ -833,6 +833,7 @@ void intel_crt_init(struct drm_device *dev)
                crt->base.get_hw_state = intel_crt_get_hw_state;
        }
        intel_connector->get_hw_state = intel_connector_get_hw_state;
+       intel_connector->unregister = intel_connector_unregister;
 
        drm_connector_helper_add(connector, &intel_crt_connector_helper_funcs);
 
index abdeda1098aee5447b0bf2e13b0dd1a74ee8feb1..fd860077d0fe9a9a3937aa9cf982c0f2f56dd9f9 100644 (file)
@@ -11409,6 +11409,14 @@ void intel_modeset_gem_init(struct drm_device *dev)
        intel_setup_overlay(dev);
 }
 
+void intel_connector_unregister(struct intel_connector *intel_connector)
+{
+       struct drm_connector *connector = &intel_connector->base;
+
+       intel_panel_destroy_backlight(connector);
+       drm_sysfs_connector_remove(connector);
+}
+
 void intel_modeset_cleanup(struct drm_device *dev)
 {
        struct drm_i915_private *dev_priv = dev->dev_private;
@@ -11453,8 +11461,10 @@ void intel_modeset_cleanup(struct drm_device *dev)
 
        /* destroy the backlight and sysfs files before encoders/connectors */
        list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
-               intel_panel_destroy_backlight(connector);
-               drm_sysfs_connector_remove(connector);
+               struct intel_connector *intel_connector;
+
+               intel_connector = to_intel_connector(connector);
+               intel_connector->unregister(intel_connector);
        }
 
        drm_mode_config_cleanup(dev);
index e5aaae3f8e1931105f24dea3b6b83171564caddd..eeb8e7b42f8a641cd1d3fcc2b95cec96f006e589 100644 (file)
@@ -3799,6 +3799,7 @@ intel_dp_init_connector(struct intel_digital_port *intel_dig_port,
                intel_connector->get_hw_state = intel_ddi_connector_get_hw_state;
        else
                intel_connector->get_hw_state = intel_connector_get_hw_state;
+       intel_connector->unregister = intel_connector_unregister;
 
        intel_dp->aux_ch_ctl_reg = intel_dp->output_reg + 0x10;
        if (HAS_DDI(dev)) {
index bff5d0a3f584acd3d2a27a2cc8229070436bfaa6..a4ffc021c317c2ba00db3371c57c750d4ebf6da9 100644 (file)
@@ -187,6 +187,14 @@ struct intel_connector {
         * and active (i.e. dpms ON state). */
        bool (*get_hw_state)(struct intel_connector *);
 
+       /*
+        * Removes all interfaces through which the connector is accessible
+        * - like sysfs, debugfs entries -, so that no new operations can be
+        * started on the connector. Also makes sure all currently pending
+        * operations finish before returing.
+        */
+       void (*unregister)(struct intel_connector *);
+
        /* Panel info for eDP and LVDS */
        struct intel_panel panel;
 
index 6bffbdf149a8be0f154b8a031fe75dfbca3d5ad2..3ee1db1407b054bad37ae3c9f86d050614f05892 100644 (file)
@@ -586,6 +586,7 @@ bool intel_dsi_init(struct drm_device *dev)
        intel_encoder->get_config = intel_dsi_get_config;
 
        intel_connector->get_hw_state = intel_connector_get_hw_state;
+       intel_connector->unregister = intel_connector_unregister;
 
        for (i = 0; i < ARRAY_SIZE(intel_dsi_devices); i++) {
                dsi = &intel_dsi_devices[i];
index eeff998e52efdea93534ffb680582503f9f2a56c..86eeb8b7d435835e722afe86867c8a80890cad9e 100644 (file)
@@ -477,6 +477,7 @@ void intel_dvo_init(struct drm_device *dev)
        intel_encoder->compute_config = intel_dvo_compute_config;
        intel_encoder->mode_set = intel_dvo_mode_set;
        intel_connector->get_hw_state = intel_dvo_connector_get_hw_state;
+       intel_connector->unregister = intel_connector_unregister;
 
        /* Now, try to find a controller */
        for (i = 0; i < ARRAY_SIZE(intel_dvo_devices); i++) {
index c1cbe7f0437fe59d98964fc5d1c75d7dec06d361..98d68ab04de462b9c655ce94cb0b2d02074af66d 100644 (file)
@@ -1236,6 +1236,7 @@ void intel_hdmi_init_connector(struct intel_digital_port *intel_dig_port,
                intel_connector->get_hw_state = intel_ddi_connector_get_hw_state;
        else
                intel_connector->get_hw_state = intel_connector_get_hw_state;
+       intel_connector->unregister = intel_connector_unregister;
 
        intel_hdmi_add_properties(intel_hdmi, connector);
 
index 398460862be6c8c938d94edb3ef13d6bfdf5f914..fecff3c2b9e18aecc13435262def62312cb60037 100644 (file)
@@ -958,6 +958,7 @@ void intel_lvds_init(struct drm_device *dev)
        intel_encoder->get_hw_state = intel_lvds_get_hw_state;
        intel_encoder->get_config = intel_lvds_get_config;
        intel_connector->get_hw_state = intel_connector_get_hw_state;
+       intel_connector->unregister = intel_connector_unregister;
 
        intel_connector_attach_encoder(intel_connector, intel_encoder);
        intel_encoder->type = INTEL_OUTPUT_LVDS;
index 95bdfb3c431c8467b105c616f6d5f9567505804f..cbc2feeda59df91dc790d44b8ef78a807ce6ee15 100644 (file)
@@ -2397,6 +2397,7 @@ intel_sdvo_connector_init(struct intel_sdvo_connector *connector,
        connector->base.base.doublescan_allowed = 0;
        connector->base.base.display_info.subpixel_order = SubPixelHorizontalRGB;
        connector->base.get_hw_state = intel_sdvo_connector_get_hw_state;
+       connector->base.unregister = intel_connector_unregister;
 
        intel_connector_attach_encoder(&connector->base, &encoder->base);
        drm_sysfs_connector_add(&connector->base.base);
index ccd02eca35f0ad4575e64f45668e1fff0f135eca..b64fc1c6ff3f65287258e883ff8a420f931cd9f4 100644 (file)
@@ -1634,6 +1634,7 @@ intel_tv_init(struct drm_device *dev)
        intel_encoder->disable = intel_disable_tv;
        intel_encoder->get_hw_state = intel_tv_get_hw_state;
        intel_connector->get_hw_state = intel_connector_get_hw_state;
+       intel_connector->unregister = intel_connector_unregister;
 
        intel_connector_attach_encoder(intel_connector, intel_encoder);
        intel_encoder->type = INTEL_OUTPUT_TVOUT;