When trying to split up the initialisation phase and the registration
phase, one immediate problem encountered is trying to use our own i2c
devices before registration with userspace. drm_dp_aux in particular
only offers an interface for setting up the device after we have exposed
the connector via sysfs. In order to break the chicken-and-egg problem,
export drm_dp_aux_init() to minimally prepare the i2c device for
internal use before drm_connector_register().

Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
Cc: Rafael Antognolli <rafael.antognolli at intel.com>
Cc: dri-devel at lists.freedesktop.org
---
 drivers/gpu/drm/drm_dp_helper.c | 18 +++++++++++++-----
 include/drm/drm_dp_helper.h     |  1 +
 2 files changed, 14 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/drm_dp_helper.c b/drivers/gpu/drm/drm_dp_helper.c
index eeaf5a7c3aa7..e1900d386685 100644
--- a/drivers/gpu/drm/drm_dp_helper.c
+++ b/drivers/gpu/drm/drm_dp_helper.c
@@ -774,6 +774,17 @@ static const struct i2c_algorithm drm_dp_i2c_algo = {
        .master_xfer = drm_dp_i2c_xfer,
 };

+void drm_dp_aux_init(struct drm_dp_aux *aux)
+{
+       mutex_init(&aux->hw_mutex);
+       rt_mutex_init(&aux->ddc.bus_lock);
+
+       aux->ddc.algo = &drm_dp_i2c_algo;
+       aux->ddc.algo_data = aux;
+       aux->ddc.retries = 3;
+}
+EXPORT_SYMBOL(drm_dp_aux_init);
+
 /**
  * drm_dp_aux_register() - initialise and register aux channel
  * @aux: DisplayPort AUX channel
@@ -784,11 +795,8 @@ int drm_dp_aux_register(struct drm_dp_aux *aux)
 {
        int ret;

-       mutex_init(&aux->hw_mutex);
-
-       aux->ddc.algo = &drm_dp_i2c_algo;
-       aux->ddc.algo_data = aux;
-       aux->ddc.retries = 3;
+       if (!aux->ddc.algo)
+               drm_dp_aux_init(aux);

        aux->ddc.class = I2C_CLASS_DDC;
        aux->ddc.owner = THIS_MODULE;
diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h
index 5a848e734422..4d85cf2874af 100644
--- a/include/drm/drm_dp_helper.h
+++ b/include/drm/drm_dp_helper.h
@@ -805,6 +805,7 @@ int drm_dp_link_power_up(struct drm_dp_aux *aux, struct 
drm_dp_link *link);
 int drm_dp_link_power_down(struct drm_dp_aux *aux, struct drm_dp_link *link);
 int drm_dp_link_configure(struct drm_dp_aux *aux, struct drm_dp_link *link);

+void drm_dp_aux_init(struct drm_dp_aux *aux);
 int drm_dp_aux_register(struct drm_dp_aux *aux);
 void drm_dp_aux_unregister(struct drm_dp_aux *aux);

-- 
2.8.1

Reply via email to