aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/intel_dp.c
diff options
context:
space:
mode:
authorImre Deak <imre.deak@intel.com>2014-02-11 10:12:49 -0500
committerDaniel Vetter <daniel.vetter@ffwll.ch>2014-02-14 05:24:59 -0500
commit80f65de3c9b8101c1613fa82df500ba6a099a11c (patch)
tree5b07b06c1f846845e910ebd260a009077d81e057 /drivers/gpu/drm/i915/intel_dp.c
parent4932e2c3c716067f3580e1a9687bed9d751549e3 (diff)
drm/i915: dp: fix order of dp aux i2c device cleanup
Atm we set the parent of the dp i2c device to be the correspondig connector device. During driver cleanup we first remove the connector device through intel_modeset_cleanup()->drm_sysfs_connector_remove() and only after that the i2c device through the encoder's destroy callback. This order is not supported by the device core and we'll get a warning, see the below bugzilla ticket. The proper order is to remove first any child device and only then the parent device. The first part of the fix changes the i2c device's parent to be the drm device. Its logical owner is not the connector anyway, but the encoder. Since the encoder doesn't have a device object, the next best choice is the drm device. This is the same what we do in the case of the sdvo i2c device and what the nouveau driver does. The second part creates a symlink in the connector's sysfs directory pointing to the i2c device. This is so, that we keep the current ABI, which also makes sense in case someone wants to look up the i2c device belonging to a specific connector. Reference: http://lists.freedesktop.org/archives/intel-gfx/2014-January/038782.html Reference: http://lists.freedesktop.org/archives/intel-gfx/2014-February/039427.html Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=70523 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>
Diffstat (limited to 'drivers/gpu/drm/i915/intel_dp.c')
-rw-r--r--drivers/gpu/drm/i915/intel_dp.c24
1 files changed, 22 insertions, 2 deletions
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index eeb8e7b42f8a..1ac4b11765c7 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -777,6 +777,16 @@ out:
777 return ret; 777 return ret;
778} 778}
779 779
780static void
781intel_dp_connector_unregister(struct intel_connector *intel_connector)
782{
783 struct intel_dp *intel_dp = intel_attached_dp(&intel_connector->base);
784
785 sysfs_remove_link(&intel_connector->base.kdev->kobj,
786 intel_dp->adapter.dev.kobj.name);
787 intel_connector_unregister(intel_connector);
788}
789
780static int 790static int
781intel_dp_i2c_init(struct intel_dp *intel_dp, 791intel_dp_i2c_init(struct intel_dp *intel_dp,
782 struct intel_connector *intel_connector, const char *name) 792 struct intel_connector *intel_connector, const char *name)
@@ -794,9 +804,19 @@ intel_dp_i2c_init(struct intel_dp *intel_dp,
794 strncpy(intel_dp->adapter.name, name, sizeof(intel_dp->adapter.name) - 1); 804 strncpy(intel_dp->adapter.name, name, sizeof(intel_dp->adapter.name) - 1);
795 intel_dp->adapter.name[sizeof(intel_dp->adapter.name) - 1] = '\0'; 805 intel_dp->adapter.name[sizeof(intel_dp->adapter.name) - 1] = '\0';
796 intel_dp->adapter.algo_data = &intel_dp->algo; 806 intel_dp->adapter.algo_data = &intel_dp->algo;
797 intel_dp->adapter.dev.parent = intel_connector->base.kdev; 807 intel_dp->adapter.dev.parent = intel_connector->base.dev->dev;
798 808
799 ret = i2c_dp_aux_add_bus(&intel_dp->adapter); 809 ret = i2c_dp_aux_add_bus(&intel_dp->adapter);
810 if (ret < 0)
811 return ret;
812
813 ret = sysfs_create_link(&intel_connector->base.kdev->kobj,
814 &intel_dp->adapter.dev.kobj,
815 intel_dp->adapter.dev.kobj.name);
816
817 if (ret < 0)
818 i2c_del_adapter(&intel_dp->adapter);
819
800 return ret; 820 return ret;
801} 821}
802 822
@@ -3799,7 +3819,7 @@ intel_dp_init_connector(struct intel_digital_port *intel_dig_port,
3799 intel_connector->get_hw_state = intel_ddi_connector_get_hw_state; 3819 intel_connector->get_hw_state = intel_ddi_connector_get_hw_state;
3800 else 3820 else
3801 intel_connector->get_hw_state = intel_connector_get_hw_state; 3821 intel_connector->get_hw_state = intel_connector_get_hw_state;
3802 intel_connector->unregister = intel_connector_unregister; 3822 intel_connector->unregister = intel_dp_connector_unregister;
3803 3823
3804 intel_dp->aux_ch_ctl_reg = intel_dp->output_reg + 0x10; 3824 intel_dp->aux_ch_ctl_reg = intel_dp->output_reg + 0x10;
3805 if (HAS_DDI(dev)) { 3825 if (HAS_DDI(dev)) {