From: Chris Wilson Date: Tue, 17 May 2011 13:03:50 +0000 (+0100) Subject: drm/i915/sdvo: Reorder i2c initialisation before ddc proxy X-Git-Tag: v3.0-rc3~42^2~46^2~1 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=56184e3da005e0259fc628706351b54fcc4527db;p=profile%2Fivi%2Fkernel-x86-ivi.git drm/i915/sdvo: Reorder i2c initialisation before ddc proxy 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 Signed-off-by: Chris Wilson Reviewed-by: Keith Packard Signed-off-by: Keith Packard --- diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c index 4324f33..754086f 100644 --- a/drivers/gpu/drm/i915/intel_sdvo.c +++ b/drivers/gpu/drm/i915/intel_sdvo.c @@ -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;