diff options
| author | Dave Airlie <airlied@redhat.com> | 2014-06-04 02:02:28 -0400 |
|---|---|---|
| committer | Dave Airlie <airlied@redhat.com> | 2014-06-04 19:54:29 -0400 |
| commit | 4f71d0cb76339a10fd445b0b281acc45c71b6271 (patch) | |
| tree | 9badd446ee865db48ebebe77ed8f4e3b3ca089aa | |
| parent | 885ae1c55ae46ee1064bc7cb99dc45ddd8bd0328 (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.c | 21 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/intel_dp.c | 10 | ||||
| -rw-r--r-- | drivers/gpu/drm/radeon/atombios_dp.c | 5 | ||||
| -rw-r--r-- | drivers/gpu/drm/radeon/radeon_i2c.c | 2 | ||||
| -rw-r--r-- | drivers/gpu/drm/tegra/dpaux.c | 4 | ||||
| -rw-r--r-- | include/drm/drm_dp_helper.h | 7 |
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 | */ |
| 221 | int | 221 | int |
| 222 | i2c_dp_aux_add_bus(struct i2c_adapter *adapter) | 222 | i2c_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 | */ |
| 737 | int drm_dp_aux_register_i2c_bus(struct drm_dp_aux *aux) | 742 | int 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 | } |
| 753 | EXPORT_SYMBOL(drm_dp_aux_register_i2c_bus); | 760 | EXPORT_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 | */ |
| 759 | void drm_dp_aux_unregister_i2c_bus(struct drm_dp_aux *aux) | 766 | void 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 | } |
| 763 | EXPORT_SYMBOL(drm_dp_aux_unregister_i2c_bus); | 770 | EXPORT_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 | |||
