Merge git://git.infradead.org/users/eparis/audit
[cascardo/linux.git] / drivers / gpu / drm / i915 / intel_sdvo.c
index 95bdfb3..d27155a 100644 (file)
@@ -1461,7 +1461,7 @@ static void intel_enable_sdvo(struct intel_encoder *encoder)
        u32 temp;
        bool input1, input2;
        int i;
-       u8 status;
+       bool success;
 
        temp = I915_READ(intel_sdvo->sdvo_reg);
        if ((temp & SDVO_ENABLE) == 0) {
@@ -1475,12 +1475,12 @@ static void intel_enable_sdvo(struct intel_encoder *encoder)
        for (i = 0; i < 2; i++)
                intel_wait_for_vblank(dev, intel_crtc->pipe);
 
-       status = intel_sdvo_get_trained_inputs(intel_sdvo, &input1, &input2);
+       success = intel_sdvo_get_trained_inputs(intel_sdvo, &input1, &input2);
        /* Warn if the device reported failure to sync.
         * A lot of SDVO devices fail to notify of sync, but it's
         * a given it the status is a success, we succeeded.
         */
-       if (status == SDVO_CMD_STATUS_SUCCESS && !input1) {
+       if (success && !input1) {
                DRM_DEBUG_KMS("First %s output reported failure to "
                                "sync\n", SDVO_NAME(intel_sdvo));
        }
@@ -2382,24 +2382,62 @@ intel_sdvo_get_slave_addr(struct drm_device *dev, struct intel_sdvo *sdvo)
 }
 
 static void
+intel_sdvo_connector_unregister(struct intel_connector *intel_connector)
+{
+       struct drm_connector *drm_connector;
+       struct intel_sdvo *sdvo_encoder;
+
+       drm_connector = &intel_connector->base;
+       sdvo_encoder = intel_attached_sdvo(&intel_connector->base);
+
+       sysfs_remove_link(&drm_connector->kdev->kobj,
+                         sdvo_encoder->ddc.dev.kobj.name);
+       intel_connector_unregister(intel_connector);
+}
+
+static int
 intel_sdvo_connector_init(struct intel_sdvo_connector *connector,
                          struct intel_sdvo *encoder)
 {
-       drm_connector_init(encoder->base.base.dev,
-                          &connector->base.base,
+       struct drm_connector *drm_connector;
+       int ret;
+
+       drm_connector = &connector->base.base;
+       ret = drm_connector_init(encoder->base.base.dev,
+                          drm_connector,
                           &intel_sdvo_connector_funcs,
                           connector->base.base.connector_type);
+       if (ret < 0)
+               return ret;
 
-       drm_connector_helper_add(&connector->base.base,
+       drm_connector_helper_add(drm_connector,
                                 &intel_sdvo_connector_helper_funcs);
 
        connector->base.base.interlace_allowed = 1;
        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_sdvo_connector_unregister;
 
        intel_connector_attach_encoder(&connector->base, &encoder->base);
-       drm_sysfs_connector_add(&connector->base.base);
+       ret = drm_sysfs_connector_add(drm_connector);
+       if (ret < 0)
+               goto err1;
+
+       ret = sysfs_create_link(&encoder->ddc.dev.kobj,
+                               &drm_connector->kdev->kobj,
+                               encoder->ddc.dev.kobj.name);
+       if (ret < 0)
+               goto err2;
+
+       return 0;
+
+err2:
+       drm_sysfs_connector_remove(drm_connector);
+err1:
+       drm_connector_cleanup(drm_connector);
+
+       return ret;
 }
 
 static void
@@ -2459,7 +2497,11 @@ intel_sdvo_dvi_init(struct intel_sdvo *intel_sdvo, int device)
                intel_sdvo->is_hdmi = true;
        }
 
-       intel_sdvo_connector_init(intel_sdvo_connector, intel_sdvo);
+       if (intel_sdvo_connector_init(intel_sdvo_connector, intel_sdvo) < 0) {
+               kfree(intel_sdvo_connector);
+               return false;
+       }
+
        if (intel_sdvo->is_hdmi)
                intel_sdvo_add_hdmi_properties(intel_sdvo, intel_sdvo_connector);
 
@@ -2490,7 +2532,10 @@ intel_sdvo_tv_init(struct intel_sdvo *intel_sdvo, int type)
 
        intel_sdvo->is_tv = true;
 
-       intel_sdvo_connector_init(intel_sdvo_connector, intel_sdvo);
+       if (intel_sdvo_connector_init(intel_sdvo_connector, intel_sdvo) < 0) {
+               kfree(intel_sdvo_connector);
+               return false;
+       }
 
        if (!intel_sdvo_tv_create_property(intel_sdvo, intel_sdvo_connector, type))
                goto err;
@@ -2534,8 +2579,11 @@ intel_sdvo_analog_init(struct intel_sdvo *intel_sdvo, int device)
                intel_sdvo_connector->output_flag = SDVO_OUTPUT_RGB1;
        }
 
-       intel_sdvo_connector_init(intel_sdvo_connector,
-                                 intel_sdvo);
+       if (intel_sdvo_connector_init(intel_sdvo_connector, intel_sdvo) < 0) {
+               kfree(intel_sdvo_connector);
+               return false;
+       }
+
        return true;
 }
 
@@ -2566,7 +2614,11 @@ intel_sdvo_lvds_init(struct intel_sdvo *intel_sdvo, int device)
                intel_sdvo_connector->output_flag = SDVO_OUTPUT_LVDS1;
        }
 
-       intel_sdvo_connector_init(intel_sdvo_connector, intel_sdvo);
+       if (intel_sdvo_connector_init(intel_sdvo_connector, intel_sdvo) < 0) {
+               kfree(intel_sdvo_connector);
+               return false;
+       }
+
        if (!intel_sdvo_create_enhance_property(intel_sdvo, intel_sdvo_connector))
                goto err;
 
@@ -2980,7 +3032,7 @@ bool intel_sdvo_init(struct drm_device *dev, uint32_t sdvo_reg, bool is_sdvob)
         * simplistic anyway to express such constraints, so just give up on
         * cloning for SDVO encoders.
         */
-       intel_sdvo->base.cloneable = false;
+       intel_sdvo->base.cloneable = 0;
 
        intel_sdvo_select_ddc_bus(dev_priv, intel_sdvo, sdvo_reg);