From ffb89d4c3b6650551aaab06076896540a78faddf Mon Sep 17 00:00:00 2001 From: Jerome Glisse Date: Fri, 9 Nov 2007 15:47:24 +0100 Subject: [PATCH] drm: split edid handling in get_edid & add_edid_mode This way driver can get_edid in output status detection (using all workaround which are in get_edid) and then provide this edid data in get_mode callback of output. --- linux-core/drm_crtc.h | 5 +++-- linux-core/drm_edid.c | 40 +++++++++++++++++++++++++--------------- linux-core/intel_modes.c | 9 ++++++++- 3 files changed, 36 insertions(+), 18 deletions(-) diff --git a/linux-core/drm_crtc.h b/linux-core/drm_crtc.h index d97cd19..9dd00b3 100644 --- a/linux-core/drm_crtc.h +++ b/linux-core/drm_crtc.h @@ -487,8 +487,9 @@ extern void drm_output_destroy(struct drm_output *output); extern bool drm_output_rename(struct drm_output *output, const char *name); extern void drm_fb_release(struct file *filp); -extern int drm_add_edid_modes(struct drm_output *output, - struct i2c_adapter *adapter); +extern struct edid *drm_get_edid(struct drm_output *output, + struct i2c_adapter *adapter); +extern int drm_add_edid_modes(struct drm_output *output, struct edid *edid); extern void drm_mode_probed_add(struct drm_output *output, struct drm_display_mode *mode); extern void drm_mode_remove(struct drm_output *output, struct drm_display_mode *mode); extern struct drm_display_mode *drm_mode_duplicate(struct drm_device *dev, diff --git a/linux-core/drm_edid.c b/linux-core/drm_edid.c index d7d3939..b8eee1a 100644 --- a/linux-core/drm_edid.c +++ b/linux-core/drm_edid.c @@ -427,41 +427,51 @@ static unsigned char *drm_ddc_read(struct i2c_adapter *adapter) } /** - * drm_add_edid_modes - add modes from EDID data, if available + * drm_get_edid - get EDID data, if available * @output: output we're probing * @adapter: i2c adapter to use for DDC * - * Poke the given output's i2c channel to grab EDID data if possible. If we - * get any, add the specified modes to the output's mode list. - * - * Return number of modes added or 0 if we couldn't find any. + * Poke the given output's i2c channel to grab EDID data if possible. + * + * Return edid data or NULL if we couldn't find any. */ -int drm_add_edid_modes(struct drm_output *output, struct i2c_adapter *adapter) +struct edid *drm_get_edid(struct drm_output *output, + struct i2c_adapter *adapter) { struct edid *edid; - int num_modes = 0; edid = (struct edid *)drm_ddc_read(adapter); if (!edid) { dev_warn(&output->dev->pdev->dev, "%s: no EDID data\n", output->name); - goto out_err; + return NULL; } - if (!edid_valid(edid)) { dev_warn(&output->dev->pdev->dev, "%s: EDID invalid.\n", output->name); - goto out_err; + kfree(edid); + return NULL; } + return edid; +} +EXPORT_SYMBOL(drm_get_edid); + +/** + * drm_add_edid_modes - add modes from EDID data, if available + * @output: output we're probing + * @edid: edid data + * + * Add the specified modes to the output's mode list. + * + * Return number of modes added or 0 if we couldn't find any. + */ +int drm_add_edid_modes(struct drm_output *output, struct edid *edid) +{ + int num_modes = 0; num_modes += add_established_modes(output, edid); num_modes += add_standard_modes(output, edid); num_modes += add_detailed_info(output, edid); - return num_modes; - -out_err: - kfree(edid); - return 0; } EXPORT_SYMBOL(drm_add_edid_modes); diff --git a/linux-core/intel_modes.c b/linux-core/intel_modes.c index 601770e..346cf1a 100644 --- a/linux-core/intel_modes.c +++ b/linux-core/intel_modes.c @@ -50,6 +50,13 @@ bool intel_ddc_probe(struct drm_output *output) int intel_ddc_get_modes(struct drm_output *output) { struct intel_output *intel_output = output->driver_private; + struct edid *edid; + int ret = 0; - return drm_add_edid_modes(output, &intel_output->ddc_bus->adapter); + edid = drm_get_edid(output, &intel_output->ddc_bus->adapter); + if (edid) { + ret = drm_add_edid_modes(output, edid); + kfree(edid); + } + return ret; } -- 2.7.4