Skip to content

Commit

Permalink
drm/i915/sdvo: Reorder i2c initialisation before ddc proxy
Browse files Browse the repository at this point in the history
The ddc proxy depends upon the underlying i2c bus being selected. Under
certain configurations, the i2c-adapter functionality is queried during
initialisation and so may trigger an OOPS during boot. Hence, we need to
reorder the initialisation of the ddc proxy until after we hook up the i2c
adapter for the SDVO device.

The condition under which it fails is when the i2c_add_adapter calls
into i2c_detect which will attempt to probe all valid addresses on the
adapter iff there is a pre-existing i2c_driver with the same class as
the freshly added i2c_adapter.

So it appears to depend upon having compiled in (or loaded such a
module before i915.ko) an i2c-driver that likes to futz over the
i2c_adapters claiming DDC support.

Reported-by: Mihai Moldovan <ionic@ionic.de>
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Reviewed-by: Keith Packard <keithp@keithp.com>
Signed-off-by: Keith Packard <keithp@keithp.com>
  • Loading branch information
Chris Wilson authored and Keith Packard committed May 18, 2011
1 parent 61e499b commit 56184e3
Showing 1 changed file with 4 additions and 6 deletions.
10 changes: 4 additions & 6 deletions drivers/gpu/drm/i915/intel_sdvo.c
Original file line number Diff line number Diff line change
Expand Up @@ -2544,21 +2544,19 @@ bool intel_sdvo_init(struct drm_device *dev, int sdvo_reg)
if (!intel_sdvo)
return false;

intel_sdvo->sdvo_reg = sdvo_reg;
intel_sdvo->slave_addr = intel_sdvo_get_slave_addr(dev, sdvo_reg) >> 1;
intel_sdvo_select_i2c_bus(dev_priv, intel_sdvo, sdvo_reg);
if (!intel_sdvo_init_ddc_proxy(intel_sdvo, dev)) {
kfree(intel_sdvo);
return false;
}

intel_sdvo->sdvo_reg = sdvo_reg;

/* encoder type will be decided later */
intel_encoder = &intel_sdvo->base;
intel_encoder->type = INTEL_OUTPUT_SDVO;
/* encoder type will be decided later */
drm_encoder_init(dev, &intel_encoder->base, &intel_sdvo_enc_funcs, 0);

intel_sdvo->slave_addr = intel_sdvo_get_slave_addr(dev, sdvo_reg) >> 1;
intel_sdvo_select_i2c_bus(dev_priv, intel_sdvo, sdvo_reg);

/* Read the regs to test if we can talk to the device */
for (i = 0; i < 0x40; i++) {
u8 byte;
Expand Down

0 comments on commit 56184e3

Please sign in to comment.