aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2014-06-04 02:02:28 -0400
committerDave Airlie <airlied@redhat.com>2014-06-04 19:54:29 -0400
commit4f71d0cb76339a10fd445b0b281acc45c71b6271 (patch)
tree9badd446ee865db48ebebe77ed8f4e3b3ca089aa
parent885ae1c55ae46ee1064bc7cb99dc45ddd8bd0328 (diff)
drm/dp: add a hw mutex around the transfer functions. (v2)
This should avoid races between connector probing and HPD irqs in the future, currently mode_config.mutex blocks this possibility. Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch> Signed-off-by: Dave Airlie <airlied@redhat.com>
-rw-r--r--drivers/gpu/drm/drm_dp_helper.c21
-rw-r--r--drivers/gpu/drm/i915/intel_dp.c10
-rw-r--r--drivers/gpu/drm/radeon/atombios_dp.c5
-rw-r--r--drivers/gpu/drm/radeon/radeon_i2c.c2
-rw-r--r--drivers/gpu/drm/tegra/dpaux.c4
-rw-r--r--include/drm/drm_dp_helper.h7
6 files changed, 29 insertions, 20 deletions
diff --git a/drivers/gpu/drm/drm_dp_helper.c b/drivers/gpu/drm/drm_dp_helper.c
index 494219ccdf96..08e33b8b13a4 100644
--- a/drivers/gpu/drm/drm_dp_helper.c
+++ b/drivers/gpu/drm/drm_dp_helper.c
@@ -216,7 +216,7 @@ i2c_dp_aux_prepare_bus(struct i2c_adapter *adapter)
216 * 216 *
217 * IMPORTANT: 217 * IMPORTANT:
218 * This interface is deprecated, please switch to the new dp aux helpers and 218 * This interface is deprecated, please switch to the new dp aux helpers and
219 * drm_dp_aux_register_i2c_bus(). 219 * drm_dp_aux_register().
220 */ 220 */
221int 221int
222i2c_dp_aux_add_bus(struct i2c_adapter *adapter) 222i2c_dp_aux_add_bus(struct i2c_adapter *adapter)
@@ -382,7 +382,10 @@ static int drm_dp_dpcd_access(struct drm_dp_aux *aux, u8 request,
382 * transactions. 382 * transactions.
383 */ 383 */
384 for (retry = 0; retry < 7; retry++) { 384 for (retry = 0; retry < 7; retry++) {
385
386 mutex_lock(&aux->hw_mutex);
385 err = aux->transfer(aux, &msg); 387 err = aux->transfer(aux, &msg);
388 mutex_unlock(&aux->hw_mutex);
386 if (err < 0) { 389 if (err < 0) {
387 if (err == -EBUSY) 390 if (err == -EBUSY)
388 continue; 391 continue;
@@ -596,7 +599,9 @@ static int drm_dp_i2c_do_msg(struct drm_dp_aux *aux, struct drm_dp_aux_msg *msg)
596 * before giving up the AUX transaction. 599 * before giving up the AUX transaction.
597 */ 600 */
598 for (retry = 0; retry < 7; retry++) { 601 for (retry = 0; retry < 7; retry++) {
602 mutex_lock(&aux->hw_mutex);
599 err = aux->transfer(aux, msg); 603 err = aux->transfer(aux, msg);
604 mutex_unlock(&aux->hw_mutex);
600 if (err < 0) { 605 if (err < 0) {
601 if (err == -EBUSY) 606 if (err == -EBUSY)
602 continue; 607 continue;
@@ -729,13 +734,15 @@ static const struct i2c_algorithm drm_dp_i2c_algo = {
729}; 734};
730 735
731/** 736/**
732 * drm_dp_aux_register_i2c_bus() - register an I2C adapter for I2C-over-AUX 737 * drm_dp_aux_register() - initialise and register aux channel
733 * @aux: DisplayPort AUX channel 738 * @aux: DisplayPort AUX channel
734 * 739 *
735 * Returns 0 on success or a negative error code on failure. 740 * Returns 0 on success or a negative error code on failure.
736 */ 741 */
737int drm_dp_aux_register_i2c_bus(struct drm_dp_aux *aux) 742int drm_dp_aux_register(struct drm_dp_aux *aux)
738{ 743{
744 mutex_init(&aux->hw_mutex);
745
739 aux->ddc.algo = &drm_dp_i2c_algo; 746 aux->ddc.algo = &drm_dp_i2c_algo;
740 aux->ddc.algo_data = aux; 747 aux->ddc.algo_data = aux;
741 aux->ddc.retries = 3; 748 aux->ddc.retries = 3;
@@ -750,14 +757,14 @@ int drm_dp_aux_register_i2c_bus(struct drm_dp_aux *aux)
750 757
751 return i2c_add_adapter(&aux->ddc); 758 return i2c_add_adapter(&aux->ddc);
752} 759}
753EXPORT_SYMBOL(drm_dp_aux_register_i2c_bus); 760EXPORT_SYMBOL(drm_dp_aux_register);
754 761
755/** 762/**
756 * drm_dp_aux_unregister_i2c_bus() - unregister an I2C-over-AUX adapter 763 * drm_dp_aux_unregister() - unregister an AUX adapter
757 * @aux: DisplayPort AUX channel 764 * @aux: DisplayPort AUX channel
758 */ 765 */
759void drm_dp_aux_unregister_i2c_bus(struct drm_dp_aux *aux) 766void drm_dp_aux_unregister(struct drm_dp_aux *aux)
760{ 767{
761 i2c_del_adapter(&aux->ddc); 768 i2c_del_adapter(&aux->ddc);
762} 769}
763EXPORT_SYMBOL(drm_dp_aux_unregister_i2c_bus); 770EXPORT_SYMBOL(drm_dp_aux_unregister);
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index c4d883921282..d01bb430b5bc 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -702,9 +702,9 @@ intel_dp_aux_init(struct intel_dp *intel_dp, struct intel_connector *connector)
702 DRM_DEBUG_KMS("registering %s bus for %s\n", name, 702 DRM_DEBUG_KMS("registering %s bus for %s\n", name,
703 connector->base.kdev->kobj.name); 703 connector->base.kdev->kobj.name);
704 704
705 ret = drm_dp_aux_register_i2c_bus(&intel_dp->aux); 705 ret = drm_dp_aux_register(&intel_dp->aux);
706 if (ret < 0) { 706 if (ret < 0) {
707 DRM_ERROR("drm_dp_aux_register_i2c_bus() for %s failed (%d)\n", 707 DRM_ERROR("drm_dp_aux_register() for %s failed (%d)\n",
708 name, ret); 708 name, ret);
709 return; 709 return;
710 } 710 }
@@ -714,7 +714,7 @@ intel_dp_aux_init(struct intel_dp *intel_dp, struct intel_connector *connector)
714 intel_dp->aux.ddc.dev.kobj.name); 714 intel_dp->aux.ddc.dev.kobj.name);
715 if (ret < 0) { 715 if (ret < 0) {
716 DRM_ERROR("sysfs_create_link() for %s failed (%d)\n", name, ret); 716 DRM_ERROR("sysfs_create_link() for %s failed (%d)\n", name, ret);
717 drm_dp_aux_unregister_i2c_bus(&intel_dp->aux); 717 drm_dp_aux_unregister(&intel_dp->aux);
718 } 718 }
719} 719}
720 720
@@ -3662,7 +3662,7 @@ void intel_dp_encoder_destroy(struct drm_encoder *encoder)
3662 struct intel_dp *intel_dp = &intel_dig_port->dp; 3662 struct intel_dp *intel_dp = &intel_dig_port->dp;
3663 struct drm_device *dev = intel_dp_to_dev(intel_dp); 3663 struct drm_device *dev = intel_dp_to_dev(intel_dp);
3664 3664
3665 drm_dp_aux_unregister_i2c_bus(&intel_dp->aux); 3665 drm_dp_aux_unregister(&intel_dp->aux);
3666 drm_encoder_cleanup(encoder); 3666 drm_encoder_cleanup(encoder);
3667 if (is_edp(intel_dp)) { 3667 if (is_edp(intel_dp)) {
3668 cancel_delayed_work_sync(&intel_dp->panel_vdd_work); 3668 cancel_delayed_work_sync(&intel_dp->panel_vdd_work);
@@ -4244,7 +4244,7 @@ intel_dp_init_connector(struct intel_digital_port *intel_dig_port,
4244 intel_dp->psr_setup_done = false; 4244 intel_dp->psr_setup_done = false;
4245 4245
4246 if (!intel_edp_init_connector(intel_dp, intel_connector, &power_seq)) { 4246 if (!intel_edp_init_connector(intel_dp, intel_connector, &power_seq)) {
4247 drm_dp_aux_unregister_i2c_bus(&intel_dp->aux); 4247 drm_dp_aux_unregister(&intel_dp->aux);
4248 if (is_edp(intel_dp)) { 4248 if (is_edp(intel_dp)) {
4249 cancel_delayed_work_sync(&intel_dp->panel_vdd_work); 4249 cancel_delayed_work_sync(&intel_dp->panel_vdd_work);
4250 mutex_lock(&dev->mode_config.connection_mutex); 4250 mutex_lock(&dev->mode_config.connection_mutex);
diff --git a/drivers/gpu/drm/radeon/atombios_dp.c b/drivers/gpu/drm/radeon/atombios_dp.c
index 225f6c66effa..a54c44181a0f 100644
--- a/drivers/gpu/drm/radeon/atombios_dp.c
+++ b/drivers/gpu/drm/radeon/atombios_dp.c
@@ -222,11 +222,12 @@ void radeon_dp_aux_init(struct radeon_connector *radeon_connector)
222 radeon_connector->ddc_bus->rec.hpd = radeon_connector->hpd.hpd; 222 radeon_connector->ddc_bus->rec.hpd = radeon_connector->hpd.hpd;
223 radeon_connector->ddc_bus->aux.dev = radeon_connector->base.kdev; 223 radeon_connector->ddc_bus->aux.dev = radeon_connector->base.kdev;
224 radeon_connector->ddc_bus->aux.transfer = radeon_dp_aux_transfer; 224 radeon_connector->ddc_bus->aux.transfer = radeon_dp_aux_transfer;
225 ret = drm_dp_aux_register_i2c_bus(&radeon_connector->ddc_bus->aux); 225
226 ret = drm_dp_aux_register(&radeon_connector->ddc_bus->aux);
226 if (!ret) 227 if (!ret)
227 radeon_connector->ddc_bus->has_aux = true; 228 radeon_connector->ddc_bus->has_aux = true;
228 229
229 WARN(ret, "drm_dp_aux_register_i2c_bus() failed with error %d\n", ret); 230 WARN(ret, "drm_dp_aux_register() failed with error %d\n", ret);
230} 231}
231 232
232/***** general DP utility functions *****/ 233/***** general DP utility functions *****/
diff --git a/drivers/gpu/drm/radeon/radeon_i2c.c b/drivers/gpu/drm/radeon/radeon_i2c.c
index 427ee4d6d0b5..add622008407 100644
--- a/drivers/gpu/drm/radeon/radeon_i2c.c
+++ b/drivers/gpu/drm/radeon/radeon_i2c.c
@@ -988,7 +988,7 @@ void radeon_i2c_destroy(struct radeon_i2c_chan *i2c)
988 return; 988 return;
989 i2c_del_adapter(&i2c->adapter); 989 i2c_del_adapter(&i2c->adapter);
990 if (i2c->has_aux) 990 if (i2c->has_aux)
991 drm_dp_aux_unregister_i2c_bus(&i2c->aux); 991 drm_dp_aux_unregister(&i2c->aux);
992 kfree(i2c); 992 kfree(i2c);
993} 993}
994 994
diff --git a/drivers/gpu/drm/tegra/dpaux.c b/drivers/gpu/drm/tegra/dpaux.c
index 005c19bd92df..2b725ba7facc 100644
--- a/drivers/gpu/drm/tegra/dpaux.c
+++ b/drivers/gpu/drm/tegra/dpaux.c
@@ -332,7 +332,7 @@ static int tegra_dpaux_probe(struct platform_device *pdev)
332 dpaux->aux.transfer = tegra_dpaux_transfer; 332 dpaux->aux.transfer = tegra_dpaux_transfer;
333 dpaux->aux.dev = &pdev->dev; 333 dpaux->aux.dev = &pdev->dev;
334