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.
main
Jerome Glisse 2007-11-09 15:47:24 +01:00
parent d983ed90cb
commit ffb89d4c3b
3 changed files with 36 additions and 18 deletions

View File

@ -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 bool drm_output_rename(struct drm_output *output, const char *name);
extern void drm_fb_release(struct file *filp); extern void drm_fb_release(struct file *filp);
extern int drm_add_edid_modes(struct drm_output *output, extern struct edid *drm_get_edid(struct drm_output *output,
struct i2c_adapter *adapter); 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_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 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, extern struct drm_display_mode *drm_mode_duplicate(struct drm_device *dev,

View File

@ -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 * @output: output we're probing
* @adapter: i2c adapter to use for DDC * @adapter: i2c adapter to use for DDC
* *
* Poke the given output's i2c channel to grab EDID data if possible. If we * Poke the given output's i2c channel to grab EDID data if possible.
* 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. * 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; struct edid *edid;
int num_modes = 0;
edid = (struct edid *)drm_ddc_read(adapter); edid = (struct edid *)drm_ddc_read(adapter);
if (!edid) { if (!edid) {
dev_warn(&output->dev->pdev->dev, "%s: no EDID data\n", dev_warn(&output->dev->pdev->dev, "%s: no EDID data\n",
output->name); output->name);
goto out_err; return NULL;
} }
if (!edid_valid(edid)) { if (!edid_valid(edid)) {
dev_warn(&output->dev->pdev->dev, "%s: EDID invalid.\n", dev_warn(&output->dev->pdev->dev, "%s: EDID invalid.\n",
output->name); 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_established_modes(output, edid);
num_modes += add_standard_modes(output, edid); num_modes += add_standard_modes(output, edid);
num_modes += add_detailed_info(output, edid); num_modes += add_detailed_info(output, edid);
return num_modes; return num_modes;
out_err:
kfree(edid);
return 0;
} }
EXPORT_SYMBOL(drm_add_edid_modes); EXPORT_SYMBOL(drm_add_edid_modes);

View File

@ -50,6 +50,13 @@ bool intel_ddc_probe(struct drm_output *output)
int intel_ddc_get_modes(struct drm_output *output) int intel_ddc_get_modes(struct drm_output *output)
{ {
struct intel_output *intel_output = output->driver_private; 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;
} }