aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/intel_sdvo.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/i915/intel_sdvo.c')
-rw-r--r--drivers/gpu/drm/i915/intel_sdvo.c78
1 files changed, 65 insertions, 13 deletions
diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c
index 95bdfb3c431c..d27155adf5db 100644
--- a/drivers/gpu/drm/i915/intel_sdvo.c
+++ b/drivers/gpu/drm/i915/intel_sdvo.c
@@ -1461,7 +1461,7 @@ static void intel_enable_sdvo(struct intel_encoder *encoder)
1461 u32 temp; 1461 u32 temp;
1462 bool input1, input2; 1462 bool input1, input2;
1463 int i; 1463 int i;
1464 u8 status; 1464 bool success;
1465 1465
1466 temp = I915_READ(intel_sdvo->sdvo_reg); 1466 temp = I915_READ(intel_sdvo->sdvo_reg);
1467 if ((temp & SDVO_ENABLE) == 0) { 1467 if ((temp & SDVO_ENABLE) == 0) {
@@ -1475,12 +1475,12 @@ static void intel_enable_sdvo(struct intel_encoder *encoder)
1475 for (i = 0; i < 2; i++) 1475 for (i = 0; i < 2; i++)
1476 intel_wait_for_vblank(dev, intel_crtc->pipe); 1476 intel_wait_for_vblank(dev, intel_crtc->pipe);
1477 1477
1478 status = intel_sdvo_get_trained_inputs(intel_sdvo, &input1, &input2); 1478 success = intel_sdvo_get_trained_inputs(intel_sdvo, &input1, &input2);
1479 /* Warn if the device reported failure to sync. 1479 /* Warn if the device reported failure to sync.
1480 * A lot of SDVO devices fail to notify of sync, but it's 1480 * A lot of SDVO devices fail to notify of sync, but it's
1481 * a given it the status is a success, we succeeded. 1481 * a given it the status is a success, we succeeded.
1482 */ 1482 */
1483 if (status == SDVO_CMD_STATUS_SUCCESS && !input1) { 1483 if (success && !input1) {
1484 DRM_DEBUG_KMS("First %s output reported failure to " 1484 DRM_DEBUG_KMS("First %s output reported failure to "
1485 "sync\n", SDVO_NAME(intel_sdvo)); 1485 "sync\n", SDVO_NAME(intel_sdvo));
1486 } 1486 }
@@ -2382,24 +2382,62 @@ intel_sdvo_get_slave_addr(struct drm_device *dev, struct intel_sdvo *sdvo)
2382} 2382}
2383 2383
2384static void 2384static void
2385intel_sdvo_connector_unregister(struct intel_connector *intel_connector)
2386{
2387 struct drm_connector *drm_connector;
2388 struct intel_sdvo *sdvo_encoder;
2389
2390 drm_connector = &intel_connector->base;
2391 sdvo_encoder = intel_attached_sdvo(&intel_connector->base);
2392
2393 sysfs_remove_link(&drm_connector->kdev->kobj,
2394 sdvo_encoder->ddc.dev.kobj.name);
2395 intel_connector_unregister(intel_connector);
2396}
2397
2398static int
2385intel_sdvo_connector_init(struct intel_sdvo_connector *connector, 2399intel_sdvo_connector_init(struct intel_sdvo_connector *connector,
2386 struct intel_sdvo *encoder) 2400 struct intel_sdvo *encoder)
2387{ 2401{
2388 drm_connector_init(encoder->base.base.dev, 2402 struct drm_connector *drm_connector;
2389 &connector->base.base, 2403 int ret;
2404
2405 drm_connector = &connector->base.base;
2406 ret = drm_connector_init(encoder->base.base.dev,
2407 drm_connector,
2390 &intel_sdvo_connector_funcs, 2408 &intel_sdvo_connector_funcs,
2391 connector->base.base.connector_type); 2409 connector->base.base.connector_type);
2410 if (ret < 0)
2411 return ret;
2392 2412
2393 drm_connector_helper_add(&connector->base.base, 2413 drm_connector_helper_add(drm_connector,
2394 &intel_sdvo_connector_helper_funcs); 2414 &intel_sdvo_connector_helper_funcs);
2395 2415
2396 connector->base.base.interlace_allowed = 1; 2416 connector->base.base.interlace_allowed = 1;
2397 connector->base.base.doublescan_allowed = 0; 2417 connector->base.base.doublescan_allowed = 0;
2398 connector->base.base.display_info.subpixel_order = SubPixelHorizontalRGB; 2418 connector->base.base.display_info.subpixel_order = SubPixelHorizontalRGB;
2399 connector->base.get_hw_state = intel_sdvo_connector_get_hw_state; 2419 connector->base.get_hw_state = intel_sdvo_connector_get_hw_state;
2420 connector->base.unregister = intel_sdvo_connector_unregister;
2400 2421
2401 intel_connector_attach_encoder(&connector->base, &encoder->base); 2422 intel_connector_attach_encoder(&connector->base, &encoder->base);
2402 drm_sysfs_connector_add(&connector->base.base); 2423 ret = drm_sysfs_connector_add(drm_connector);
2424 if (ret < 0)
2425 goto err1;
2426
2427 ret = sysfs_create_link(&encoder->ddc.dev.kobj,
2428 &drm_connector->kdev->kobj,
2429 encoder->ddc.dev.kobj.name);
2430 if (ret < 0)
2431 goto err2;
2432
2433 return 0;
2434
2435err2:
2436 drm_sysfs_connector_remove(drm_connector);
2437err1:
2438 drm_connector_cleanup(drm_connector);
2439
2440 return ret;
2403} 2441}
2404 2442
2405static void 2443static void
@@ -2459,7 +2497,11 @@ intel_sdvo_dvi_init(struct intel_sdvo *intel_sdvo, int device)
2459 intel_sdvo->is_hdmi = true; 2497 intel_sdvo->is_hdmi = true;
2460 } 2498 }
2461 2499
2462 intel_sdvo_connector_init(intel_sdvo_connector, intel_sdvo); 2500 if (intel_sdvo_connector_init(intel_sdvo_connector, intel_sdvo) < 0) {
2501 kfree(intel_sdvo_connector);
2502 return false;
2503 }
2504
2463 if (intel_sdvo->is_hdmi) 2505 if (intel_sdvo->is_hdmi)
2464 intel_sdvo_add_hdmi_properties(intel_sdvo, intel_sdvo_connector); 2506 intel_sdvo_add_hdmi_properties(intel_sdvo, intel_sdvo_connector);
2465 2507
@@ -2490,7 +2532,10 @@ intel_sdvo_tv_init(struct intel_sdvo *intel_sdvo, int type)
2490 2532
2491 intel_sdvo->is_tv = true; 2533 intel_sdvo->is_tv = true;
2492 2534
2493 intel_sdvo_connector_init(intel_sdvo_connector, intel_sdvo); 2535 if (intel_sdvo_connector_init(intel_sdvo_connector, intel_sdvo) < 0) {
2536 kfree(intel_sdvo_connector);
2537 return false;
2538 }
2494 2539
2495 if (!intel_sdvo_tv_create_property(intel_sdvo, intel_sdvo_connector, type)) 2540 if (!intel_sdvo_tv_create_property(intel_sdvo, intel_sdvo_connector, type))
2496 goto err; 2541 goto err;
@@ -2534,8 +2579,11 @@ intel_sdvo_analog_init(struct intel_sdvo *intel_sdvo, int device)
2534 intel_sdvo_connector->output_flag = SDVO_OUTPUT_RGB1; 2579 intel_sdvo_connector->output_flag = SDVO_OUTPUT_RGB1;
2535 } 2580 }
2536 2581
2537 intel_sdvo_connector_init(intel_sdvo_connector, 2582 if (intel_sdvo_connector_init(intel_sdvo_connector, intel_sdvo) < 0) {
2538 intel_sdvo); 2583 kfree(intel_sdvo_connector);
2584 return false;
2585 }
2586
2539 return true; 2587 return true;
2540} 2588}
2541 2589
@@ -2566,7 +2614,11 @@ intel_sdvo_lvds_init(struct intel_sdvo *intel_sdvo, int device)
2566 intel_sdvo_connector->output_flag = SDVO_OUTPUT_LVDS1; 2614 intel_sdvo_connector->output_flag = SDVO_OUTPUT_LVDS1;
2567 } 2615 }
2568 2616
2569 intel_sdvo_connector_init(intel_sdvo_connector, intel_sdvo); 2617 if (intel_sdvo_connector_init(intel_sdvo_connector, intel_sdvo) < 0) {
2618 kfree(intel_sdvo_connector);
2619 return false;
2620 }
2621
2570 if (!intel_sdvo_create_enhance_property(intel_sdvo, intel_sdvo_connector)) 2622 if (!intel_sdvo_create_enhance_property(intel_sdvo, intel_sdvo_connector))
2571 goto err; 2623 goto err;
2572 2624
@@ -2980,7 +3032,7 @@ bool intel_sdvo_init(struct drm_device *dev, uint32_t sdvo_reg, bool is_sdvob)
2980 * simplistic anyway to express such constraints, so just give up on 3032 * simplistic anyway to express such constraints, so just give up on
2981 * cloning for SDVO encoders. 3033 * cloning for SDVO encoders.
2982 */ 3034 */
2983 intel_sdvo->base.cloneable = false; 3035 intel_sdvo->base.cloneable = 0;
2984 3036
2985 intel_sdvo_select_ddc_bus(dev_priv, intel_sdvo, sdvo_reg); 3037 intel_sdvo_select_ddc_bus(dev_priv, intel_sdvo, sdvo_reg);
2986 3038