diff options
Diffstat (limited to 'drivers/gpu/drm/i915/intel_sdvo.c')
-rw-r--r-- | drivers/gpu/drm/i915/intel_sdvo.c | 78 |
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 | ||
2384 | static void | 2384 | static void |
2385 | intel_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 | |||
2398 | static int | ||
2385 | intel_sdvo_connector_init(struct intel_sdvo_connector *connector, | 2399 | intel_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 | |||
2435 | err2: | ||
2436 | drm_sysfs_connector_remove(drm_connector); | ||
2437 | err1: | ||
2438 | drm_connector_cleanup(drm_connector); | ||
2439 | |||
2440 | return ret; | ||
2403 | } | 2441 | } |
2404 | 2442 | ||
2405 | static void | 2443 | static 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 | ||