drm/i915/i2c: Track the parent encoder rather than just the dev
authorChris Wilson <chris@chris-wilson.co.uk>
Tue, 14 Sep 2010 15:46:59 +0000 (16:46 +0100)
committerChris Wilson <chris@chris-wilson.co.uk>
Tue, 14 Sep 2010 20:08:36 +0000 (21:08 +0100)
The SDVO proxy i2c adapter wants to be able to use information stored in
the encoder, so pass that through intel_i2c rather than iterate over all
known encoders every time.

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
drivers/gpu/drm/i915/intel_crt.c
drivers/gpu/drm/i915/intel_drv.h
drivers/gpu/drm/i915/intel_dvo.c
drivers/gpu/drm/i915/intel_hdmi.c
drivers/gpu/drm/i915/intel_i2c.c
drivers/gpu/drm/i915/intel_lvds.c
drivers/gpu/drm/i915/intel_sdvo.c

index b39183bcc9faf90f534fcf5b20761c99a5cc534c..0403ec9e164aa08fe2601fbe305c9cfd218f60bc 100644 (file)
@@ -445,19 +445,17 @@ static void intel_crt_destroy(struct drm_connector *connector)
 
 static int intel_crt_get_modes(struct drm_connector *connector)
 {
-       int ret;
        struct intel_encoder *encoder = intel_attached_encoder(connector);
        struct i2c_adapter *ddc_bus;
        struct drm_device *dev = connector->dev;
-
+       int ret;
 
        ret = intel_ddc_get_modes(connector, encoder->ddc_bus);
        if (ret || !IS_G4X(dev))
                goto end;
 
        /* Try to probe digital port for output in DVI-I -> VGA mode. */
-       ddc_bus = intel_i2c_create(connector->dev, GPIOD, "CRTDDC_D");
-
+       ddc_bus = intel_i2c_create(encoder, GPIOD, "CRTDDC_D");
        if (!ddc_bus) {
                dev_printk(KERN_ERR, &connector->dev->pdev->dev,
                           "DDC bus registration failed for CRTDDC_D.\n");
@@ -545,7 +543,8 @@ void intel_crt_init(struct drm_device *dev)
                if (dev_priv->crt_ddc_bus != 0)
                        i2c_reg = dev_priv->crt_ddc_bus;
        }
-       intel_encoder->ddc_bus = intel_i2c_create(dev, i2c_reg, "CRTDDC_A");
+       intel_encoder->ddc_bus = intel_i2c_create(intel_encoder,
+                                                 i2c_reg, "CRTDDC_A");
        if (!intel_encoder->ddc_bus) {
                dev_printk(KERN_ERR, &dev->pdev->dev, "DDC bus registration "
                           "failed.\n");
index 31f072d31e377d26fe9b6c770a77fb70c12c3f31..8fe6b730c67933197359fd0d0619518f5d546097 100644 (file)
@@ -128,7 +128,7 @@ intel_mode_get_pixel_multiplier(const struct drm_display_mode *mode)
 }
 
 struct intel_i2c_chan {
-       struct drm_device *drm_dev; /* for getting at dev. private (mmio etc.) */
+       struct intel_encoder *encoder;
        u32 reg; /* GPIO reg */
        struct i2c_adapter adapter;
        struct i2c_algo_bit_data algo;
@@ -206,7 +206,8 @@ struct intel_unpin_work {
        bool enable_stall_check;
 };
 
-struct i2c_adapter *intel_i2c_create(struct drm_device *dev, const u32 reg,
+struct i2c_adapter *intel_i2c_create(struct intel_encoder *encoder,
+                                    const u32 reg,
                                     const char *name);
 void intel_i2c_destroy(struct i2c_adapter *adapter);
 int intel_ddc_get_modes(struct drm_connector *c, struct i2c_adapter *adapter);
index df42a9c9afc122964a946d3c3b7cf9efbac414e3..7de7d1a68c075b7034e9be0563c83156ee69e454 100644 (file)
@@ -362,7 +362,8 @@ void intel_dvo_init(struct drm_device *dev)
        intel_encoder = &intel_dvo->base;
 
        /* Set up the DDC bus */
-       intel_encoder->ddc_bus = intel_i2c_create(dev, GPIOD, "DVODDC_D");
+       intel_encoder->ddc_bus = intel_i2c_create(intel_encoder,
+                                                 GPIOD, "DVODDC_D");
        if (!intel_encoder->ddc_bus)
                goto free_intel;
 
@@ -389,10 +390,10 @@ void intel_dvo_init(struct drm_device *dev)
                 */
                if (i2cbus != NULL)
                        intel_i2c_destroy(i2cbus);
-               if (!(i2cbus = intel_i2c_create(dev, gpio,
-                       gpio == GPIOB ? "DVOI2C_B" : "DVOI2C_E"))) {
+               i2cbus = intel_i2c_create(intel_encoder, gpio,
+                                         gpio == GPIOB ?  "DVOI2C_B" : "DVOI2C_E");
+               if (i2cbus == NULL)
                        continue;
-               }
 
                intel_dvo->dev = *dvo;
                ret = dvo->dev_ops->init(&intel_dvo->dev, i2cbus);
index bba0aba15a9632798b8d0f055778b6692637d621..93d5b61bf5bd6ea257d43b5ecb27b3a4eabce198 100644 (file)
@@ -243,26 +243,28 @@ void intel_hdmi_init(struct drm_device *dev, int sdvox_reg)
        /* Set up the DDC bus. */
        if (sdvox_reg == SDVOB) {
                intel_encoder->clone_mask = (1 << INTEL_HDMIB_CLONE_BIT);
-               intel_encoder->ddc_bus = intel_i2c_create(dev, GPIOE, "HDMIB");
+               intel_encoder->ddc_bus = intel_i2c_create(intel_encoder,
+                                                         GPIOE, "HDMIB");
                dev_priv->hotplug_supported_mask |= HDMIB_HOTPLUG_INT_STATUS;
        } else if (sdvox_reg == SDVOC) {
                intel_encoder->clone_mask = (1 << INTEL_HDMIC_CLONE_BIT);
-               intel_encoder->ddc_bus = intel_i2c_create(dev, GPIOD, "HDMIC");
+               intel_encoder->ddc_bus = intel_i2c_create(intel_encoder,
+                                                         GPIOD, "HDMIC");
                dev_priv->hotplug_supported_mask |= HDMIC_HOTPLUG_INT_STATUS;
        } else if (sdvox_reg == HDMIB) {
                intel_encoder->clone_mask = (1 << INTEL_HDMID_CLONE_BIT);
-               intel_encoder->ddc_bus = intel_i2c_create(dev, PCH_GPIOE,
-                                                               "HDMIB");
+               intel_encoder->ddc_bus = intel_i2c_create(intel_encoder,
+                                                         PCH_GPIOE, "HDMIB");
                dev_priv->hotplug_supported_mask |= HDMIB_HOTPLUG_INT_STATUS;
        } else if (sdvox_reg == HDMIC) {
                intel_encoder->clone_mask = (1 << INTEL_HDMIE_CLONE_BIT);
-               intel_encoder->ddc_bus = intel_i2c_create(dev, PCH_GPIOD,
-                                                               "HDMIC");
+               intel_encoder->ddc_bus = intel_i2c_create(intel_encoder,
+                                                         PCH_GPIOD, "HDMIC");
                dev_priv->hotplug_supported_mask |= HDMIC_HOTPLUG_INT_STATUS;
        } else if (sdvox_reg == HDMID) {
                intel_encoder->clone_mask = (1 << INTEL_HDMIF_CLONE_BIT);
-               intel_encoder->ddc_bus = intel_i2c_create(dev, PCH_GPIOF,
-                                                               "HDMID");
+               intel_encoder->ddc_bus = intel_i2c_create(intel_encoder,
+                                                         PCH_GPIOF, "HDMID");
                dev_priv->hotplug_supported_mask |= HDMID_HOTPLUG_INT_STATUS;
        }
        if (!intel_encoder->ddc_bus)
index de03989d6df3e1ff04cd4bcc0b05f199e14f9fcd..d3d65a9cfba14bde84bc579459f35c6c586e935e 100644 (file)
@@ -58,25 +58,31 @@ void intel_i2c_quirk_set(struct drm_device *dev, bool enable)
 
 #define I2C_RISEFALL_TIME 20
 
+static inline struct drm_i915_private *
+get_dev_priv(struct intel_i2c_chan *chan)
+{
+       return chan->encoder->base.dev->dev_private;
+}
+
 static int get_clock(void *data)
 {
        struct intel_i2c_chan *chan = data;
-       struct drm_i915_private *dev_priv = chan->drm_dev->dev_private;
+       struct drm_i915_private *dev_priv = get_dev_priv(chan);
        return (I915_READ(chan->reg) & GPIO_CLOCK_VAL_IN) != 0;
 }
 
 static int get_data(void *data)
 {
        struct intel_i2c_chan *chan = data;
-       struct drm_i915_private *dev_priv = chan->drm_dev->dev_private;
+       struct drm_i915_private *dev_priv = get_dev_priv(chan);
        return (I915_READ(chan->reg) & GPIO_DATA_VAL_IN) != 0;
 }
 
 static void set_clock(void *data, int state_high)
 {
        struct intel_i2c_chan *chan = data;
-       struct drm_device *dev = chan->drm_dev;
-       struct drm_i915_private *dev_priv = chan->drm_dev->dev_private;
+       struct drm_i915_private *dev_priv = get_dev_priv(chan);
+       struct drm_device *dev = dev_priv->dev;
        u32 reserved = 0, clock_bits;
 
        /* On most chips, these bits must be preserved in software. */
@@ -96,8 +102,8 @@ static void set_clock(void *data, int state_high)
 static void set_data(void *data, int state_high)
 {
        struct intel_i2c_chan *chan = data;
-       struct drm_device *dev = chan->drm_dev;
-       struct drm_i915_private *dev_priv = chan->drm_dev->dev_private;
+       struct drm_i915_private *dev_priv = get_dev_priv(chan);
+       struct drm_device *dev = dev_priv->dev;
        u32 reserved = 0, data_bits;
 
        /* On most chips, these bits must be preserved in software. */
@@ -153,16 +159,18 @@ intel_i2c_reset_gmbus(struct drm_device *dev)
  *   %GPIOH
  * see PRM for details on how these different busses are used.
  */
-struct i2c_adapter *intel_i2c_create(struct drm_device *dev, const u32 reg,
+struct i2c_adapter *intel_i2c_create(struct intel_encoder *encoder,
+                                    const u32 reg,
                                     const char *name)
 {
        struct intel_i2c_chan *chan;
+       struct drm_device *dev = encoder->base.dev;
 
        chan = kzalloc(sizeof(struct intel_i2c_chan), GFP_KERNEL);
        if (!chan)
                goto out_free;
 
-       chan->drm_dev = dev;
+       chan->encoder = encoder;
        chan->reg = reg;
        snprintf(chan->adapter.name, I2C_NAME_SIZE, "intel drm %s", name);
        chan->adapter.owner = THIS_MODULE;
@@ -178,7 +186,7 @@ struct i2c_adapter *intel_i2c_create(struct drm_device *dev, const u32 reg,
 
        i2c_set_adapdata(&chan->adapter, chan);
 
-       if(i2c_bit_add_bus(&chan->adapter))
+       if (i2c_bit_add_bus(&chan->adapter))
                goto out_free;
 
        intel_i2c_reset_gmbus(dev);
index b56b59236e31e4434bb2248b6d08248c6d97fc83..2ff4a5cb2d566dd9556b9e607a08a8f3a3200e90 100644 (file)
@@ -899,7 +899,8 @@ void intel_lvds_init(struct drm_device *dev)
         */
 
        /* Set up the DDC bus. */
-       intel_encoder->ddc_bus = intel_i2c_create(dev, gpio, "LVDSDDC_C");
+       intel_encoder->ddc_bus = intel_i2c_create(intel_encoder,
+                                                 gpio, "LVDSDDC_C");
        if (!intel_encoder->ddc_bus) {
                dev_printk(KERN_ERR, &dev->pdev->dev, "DDC bus registration "
                           "failed.\n");
index a812d65fa31e83eb8022c31980e7e6518431fd3d..0e68f96225658726f32e22715a77fe55f7177295 100644 (file)
@@ -184,7 +184,7 @@ struct intel_sdvo_connector {
        u32     cur_dot_crawl,  max_dot_crawl;
 };
 
-static struct intel_sdvo *enc_to_intel_sdvo(struct drm_encoder *encoder)
+static struct intel_sdvo *to_intel_sdvo(struct drm_encoder *encoder)
 {
        return container_of(encoder, struct intel_sdvo, base.base);
 }
@@ -1051,7 +1051,7 @@ static bool intel_sdvo_mode_fixup(struct drm_encoder *encoder,
                                  struct drm_display_mode *mode,
                                  struct drm_display_mode *adjusted_mode)
 {
-       struct intel_sdvo *intel_sdvo = enc_to_intel_sdvo(encoder);
+       struct intel_sdvo *intel_sdvo = to_intel_sdvo(encoder);
        int multiplier;
 
        /* We need to construct preferred input timings based on our
@@ -1093,7 +1093,7 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder,
        struct drm_i915_private *dev_priv = dev->dev_private;
        struct drm_crtc *crtc = encoder->crtc;
        struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
-       struct intel_sdvo *intel_sdvo = enc_to_intel_sdvo(encoder);
+       struct intel_sdvo *intel_sdvo = to_intel_sdvo(encoder);
        u32 sdvox;
        struct intel_sdvo_in_out_map in_out;
        struct intel_sdvo_dtd input_dtd;
@@ -1200,7 +1200,7 @@ static void intel_sdvo_dpms(struct drm_encoder *encoder, int mode)
 {
        struct drm_device *dev = encoder->dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
-       struct intel_sdvo *intel_sdvo = enc_to_intel_sdvo(encoder);
+       struct intel_sdvo *intel_sdvo = to_intel_sdvo(encoder);
        struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc);
        u32 temp;
 
@@ -1899,7 +1899,7 @@ static const struct drm_connector_helper_funcs intel_sdvo_connector_helper_funcs
 
 static void intel_sdvo_enc_destroy(struct drm_encoder *encoder)
 {
-       struct intel_sdvo *intel_sdvo = enc_to_intel_sdvo(encoder);
+       struct intel_sdvo *intel_sdvo = to_intel_sdvo(encoder);
 
        if (intel_sdvo->analog_ddc_bus)
                intel_i2c_destroy(intel_sdvo->analog_ddc_bus);
@@ -1984,35 +1984,15 @@ intel_sdvo_get_digital_encoding_mode(struct intel_sdvo *intel_sdvo, int device)
                                     &intel_sdvo->is_hdmi, 1);
 }
 
-static struct intel_sdvo *
-intel_sdvo_chan_to_intel_sdvo(struct intel_i2c_chan *chan)
-{
-       struct drm_device *dev = chan->drm_dev;
-       struct drm_encoder *encoder;
-
-       list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
-               struct intel_sdvo *intel_sdvo = enc_to_intel_sdvo(encoder);
-               if (intel_sdvo->base.ddc_bus == &chan->adapter)
-                       return intel_sdvo;
-       }
-
-       return NULL;
-}
-
 static int intel_sdvo_master_xfer(struct i2c_adapter *i2c_adap,
                                  struct i2c_msg msgs[], int num)
 {
        struct intel_sdvo *intel_sdvo;
-       struct i2c_algo_bit_data *algo_data;
        const struct i2c_algorithm *algo;
 
-       algo_data = (struct i2c_algo_bit_data *)i2c_adap->algo_data;
-       intel_sdvo =
-               intel_sdvo_chan_to_intel_sdvo((struct intel_i2c_chan *)
-                                             (algo_data->data));
-       if (intel_sdvo == NULL)
-               return -EINVAL;
-
+       intel_sdvo = container_of(i2c_adap->algo_data,
+                                 struct intel_sdvo,
+                                 base);
        algo = intel_sdvo->base.i2c_bus->algo;
 
        intel_sdvo_set_control_bus_switch(intel_sdvo, intel_sdvo->ddc_bus);
@@ -2560,9 +2540,13 @@ bool intel_sdvo_init(struct drm_device *dev, int sdvo_reg)
 
        /* setup the DDC bus. */
        if (IS_SDVOB(sdvo_reg))
-               intel_encoder->i2c_bus = intel_i2c_create(dev, i2c_reg, "SDVOCTRL_E for SDVOB");
+               intel_encoder->i2c_bus =
+                       intel_i2c_create(intel_encoder,
+                                        i2c_reg, "SDVOCTRL_E for SDVOB");
        else
-               intel_encoder->i2c_bus = intel_i2c_create(dev, i2c_reg, "SDVOCTRL_E for SDVOC");
+               intel_encoder->i2c_bus =
+                       intel_i2c_create(intel_encoder,
+                                        i2c_reg, "SDVOCTRL_E for SDVOC");
 
        if (!intel_encoder->i2c_bus)
                goto err_inteloutput;
@@ -2583,14 +2567,20 @@ bool intel_sdvo_init(struct drm_device *dev, int sdvo_reg)
 
        /* setup the DDC bus. */
        if (IS_SDVOB(sdvo_reg)) {
-               intel_encoder->ddc_bus = intel_i2c_create(dev, ddc_reg, "SDVOB DDC BUS");
-               intel_sdvo->analog_ddc_bus = intel_i2c_create(dev, analog_ddc_reg,
-                                               "SDVOB/VGA DDC BUS");
+               intel_encoder->ddc_bus =
+                       intel_i2c_create(intel_encoder,
+                                        ddc_reg, "SDVOB DDC BUS");
+               intel_sdvo->analog_ddc_bus =
+                       intel_i2c_create(intel_encoder,
+                                        analog_ddc_reg, "SDVOB/VGA DDC BUS");
                dev_priv->hotplug_supported_mask |= SDVOB_HOTPLUG_INT_STATUS;
        } else {
-               intel_encoder->ddc_bus = intel_i2c_create(dev, ddc_reg, "SDVOC DDC BUS");
-               intel_sdvo->analog_ddc_bus = intel_i2c_create(dev, analog_ddc_reg,
-                                               "SDVOC/VGA DDC BUS");
+               intel_encoder->ddc_bus =
+                       intel_i2c_create(intel_encoder,
+                                        ddc_reg, "SDVOC DDC BUS");
+               intel_sdvo->analog_ddc_bus =
+                       intel_i2c_create(intel_encoder,
+                                        analog_ddc_reg, "SDVOC/VGA DDC BUS");
                dev_priv->hotplug_supported_mask |= SDVOC_HOTPLUG_INT_STATUS;
        }
        if (intel_encoder->ddc_bus == NULL || intel_sdvo->analog_ddc_bus == NULL)