diff --git a/linux-core/drm_compat.c b/linux-core/drm_compat.c index 08d20d0..5ba2915 100644 --- a/linux-core/drm_compat.c +++ b/linux-core/drm_compat.c @@ -576,6 +576,7 @@ static void free_layer(struct idr *idp, struct idr_layer *p) spin_unlock_irqrestore(&idp->lock, flags); } +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22)) /** * idr_for_each - iterate through all stored pointers * @idp: idr handle @@ -677,4 +678,5 @@ void idr_remove_all(struct idr *idp) idp->layers = 0; } EXPORT_SYMBOL(idr_remove_all); +#endif /* 2.6.22 check */ #endif diff --git a/linux-core/drm_crtc.h b/linux-core/drm_crtc.h index 75db5b0..4b4be02 100644 --- a/linux-core/drm_crtc.h +++ b/linux-core/drm_crtc.h @@ -488,7 +488,9 @@ 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); + void *edid); +extern int drm_probe_edid_modes(struct drm_output *output, + struct i2c_adapter *adapter); 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 0d06792..1b7135f 100644 --- a/linux-core/drm_edid.c +++ b/linux-core/drm_edid.c @@ -427,21 +427,19 @@ static unsigned char *drm_ddc_read(struct i2c_adapter *adapter) } /** - * drm_add_edid_modes - add modes from EDID data, if available - * @output: output we're probing - * @adapter: i2c adapter to use for DDC + * drm_add_edid_modes - add modes to an output given an EDID + * @output: output to append modes to + * @edid: EDID block to get modes from * - * 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. + * Given an output and an EDID block, extract the modes and add them to + * @output. * - * Return number of modes added or 0 if we couldn't find any. + * Returns number of modes added. */ -int drm_add_edid_modes(struct drm_output *output, struct i2c_adapter *adapter) +int drm_add_edid_modes(struct drm_output *output, void *edid) { - 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); @@ -461,7 +459,25 @@ int drm_add_edid_modes(struct drm_output *output, struct i2c_adapter *adapter) return num_modes; out_err: - kfree(edid); return 0; } EXPORT_SYMBOL(drm_add_edid_modes); + +/** + * drm_probe_edid_modes - add modes from 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. + */ +int drm_probe_edid_modes(struct drm_output *output, struct i2c_adapter *adapter) +{ + struct edid *edid; + + edid = (struct edid *)drm_ddc_read(adapter); + return drm_add_edid_modes(output, edid); +} +EXPORT_SYMBOL(drm_probe_edid_modes); diff --git a/linux-core/intel_lvds.c b/linux-core/intel_lvds.c index 942eb2a..4f50de1 100644 --- a/linux-core/intel_lvds.c +++ b/linux-core/intel_lvds.c @@ -350,6 +350,16 @@ static const struct drm_output_funcs intel_lvds_output_funcs = { .cleanup = intel_lvds_destroy }; +void *intel_lvds_acpi_edid(struct drm_device *dev) +{ + char *edid; + char tmp[] = { 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x30, 0xae, 0x33, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x01, 0x03, 0x80, 0x1e, 0x13, 0x78, 0xea, 0xcd, 0x75, 0x91, 0x55, 0x4f, 0x8b, 0x26, 0x21, 0x50, 0x54, 0x21, 0x08, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x32, 0x26, 0xa0, 0x40, 0x51, 0x84, 0x1a, 0x30, 0x30, 0x20, 0x36, 0x00, 0x2f, 0xbe, 0x10, 0x00, 0x00, 0x19, 0xd5, 0x1f, 0xa0, 0x40, 0x51, 0x84, 0x1a, 0x30, 0x30, 0x20, 0x36, 0x00, 0x2f, 0xbe, 0x10, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x90, 0x0a, 0x32, 0x90, 0x0a, 0x28, 0x14, 0x01, 0x00, 0x4c, 0xa3, 0x57, 0x44, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x4c, 0x54, 0x4e, 0x31, 0x34, 0x31, 0x57, 0x44, 0x2d, 0x4c, 0x30, 0x35, 0x0a, 0x00, 0xa6 }; + edid = kmalloc(256, GFP_KERNEL); + memcpy(edid, tmp, 256); + + return edid; +} + /** * intel_lvds_init - setup LVDS outputs on this device * @dev: drm device @@ -405,6 +415,8 @@ void intel_lvds_init(struct drm_device *dev) } } + drm_add_edid_modes(output, intel_lvds_acpi_edid(dev)); + /* * If we didn't get EDID, try checking if the panel is already turned * on. If so, assume that whatever is currently programmed is the diff --git a/linux-core/intel_modes.c b/linux-core/intel_modes.c index 601770e..5c1d9ed 100644 --- a/linux-core/intel_modes.c +++ b/linux-core/intel_modes.c @@ -51,5 +51,5 @@ int intel_ddc_get_modes(struct drm_output *output) { struct intel_output *intel_output = output->driver_private; - return drm_add_edid_modes(output, &intel_output->ddc_bus->adapter); + return drm_probe_edid_modes(output, &intel_output->ddc_bus->adapter); }