Commit 832fb4a0 authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'drm-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/airlied/drm-2.6

* 'drm-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/airlied/drm-2.6:
  drm/i915: Fix cursor physical address choice to match the 2D driver.
  drm: stash AGP include under the do-we-have-AGP ifdef
  drm: don't whine about not reading EDID data
  drm/i915: hook up LVDS DPMS property
  drm/i915: remove unnecessary debug output in KMS init
  i915: fix freeing path for gem phys objects.
  drm: create mode_config idr lock
  drm: fix leak of device mappings since multi-master changes.
parents 4a456592 2906f025
...@@ -33,10 +33,11 @@ ...@@ -33,10 +33,11 @@
#include "drmP.h" #include "drmP.h"
#include <linux/module.h> #include <linux/module.h>
#include <asm/agp.h>
#if __OS_HAS_AGP #if __OS_HAS_AGP
#include <asm/agp.h>
/** /**
* Get AGP information. * Get AGP information.
* *
......
...@@ -194,7 +194,6 @@ char *drm_get_connector_status_name(enum drm_connector_status status) ...@@ -194,7 +194,6 @@ char *drm_get_connector_status_name(enum drm_connector_status status)
* @type: object type * @type: object type
* *
* LOCKING: * LOCKING:
* Caller must hold DRM mode_config lock.
* *
* Create a unique identifier based on @ptr in @dev's identifier space. Used * Create a unique identifier based on @ptr in @dev's identifier space. Used
* for tracking modes, CRTCs and connectors. * for tracking modes, CRTCs and connectors.
...@@ -209,15 +208,15 @@ static int drm_mode_object_get(struct drm_device *dev, ...@@ -209,15 +208,15 @@ static int drm_mode_object_get(struct drm_device *dev,
int new_id = 0; int new_id = 0;
int ret; int ret;
WARN(!mutex_is_locked(&dev->mode_config.mutex),
"%s called w/o mode_config lock\n", __func__);
again: again:
if (idr_pre_get(&dev->mode_config.crtc_idr, GFP_KERNEL) == 0) { if (idr_pre_get(&dev->mode_config.crtc_idr, GFP_KERNEL) == 0) {
DRM_ERROR("Ran out memory getting a mode number\n"); DRM_ERROR("Ran out memory getting a mode number\n");
return -EINVAL; return -EINVAL;
} }
mutex_lock(&dev->mode_config.idr_mutex);
ret = idr_get_new_above(&dev->mode_config.crtc_idr, obj, 1, &new_id); ret = idr_get_new_above(&dev->mode_config.crtc_idr, obj, 1, &new_id);
mutex_unlock(&dev->mode_config.idr_mutex);
if (ret == -EAGAIN) if (ret == -EAGAIN)
goto again; goto again;
...@@ -239,16 +238,20 @@ static int drm_mode_object_get(struct drm_device *dev, ...@@ -239,16 +238,20 @@ static int drm_mode_object_get(struct drm_device *dev,
static void drm_mode_object_put(struct drm_device *dev, static void drm_mode_object_put(struct drm_device *dev,
struct drm_mode_object *object) struct drm_mode_object *object)
{ {
mutex_lock(&dev->mode_config.idr_mutex);
idr_remove(&dev->mode_config.crtc_idr, object->id); idr_remove(&dev->mode_config.crtc_idr, object->id);
mutex_unlock(&dev->mode_config.idr_mutex);
} }
void *drm_mode_object_find(struct drm_device *dev, uint32_t id, uint32_t type) void *drm_mode_object_find(struct drm_device *dev, uint32_t id, uint32_t type)
{ {
struct drm_mode_object *obj; struct drm_mode_object *obj = NULL;
mutex_lock(&dev->mode_config.idr_mutex);
obj = idr_find(&dev->mode_config.crtc_idr, id); obj = idr_find(&dev->mode_config.crtc_idr, id);
if (!obj || (obj->type != type) || (obj->id != id)) if (!obj || (obj->type != type) || (obj->id != id))
return NULL; obj = NULL;
mutex_unlock(&dev->mode_config.idr_mutex);
return obj; return obj;
} }
...@@ -786,6 +789,7 @@ EXPORT_SYMBOL(drm_mode_create_dithering_property); ...@@ -786,6 +789,7 @@ EXPORT_SYMBOL(drm_mode_create_dithering_property);
void drm_mode_config_init(struct drm_device *dev) void drm_mode_config_init(struct drm_device *dev)
{ {
mutex_init(&dev->mode_config.mutex); mutex_init(&dev->mode_config.mutex);
mutex_init(&dev->mode_config.idr_mutex);
INIT_LIST_HEAD(&dev->mode_config.fb_list); INIT_LIST_HEAD(&dev->mode_config.fb_list);
INIT_LIST_HEAD(&dev->mode_config.fb_kernel_list); INIT_LIST_HEAD(&dev->mode_config.fb_kernel_list);
INIT_LIST_HEAD(&dev->mode_config.crtc_list); INIT_LIST_HEAD(&dev->mode_config.crtc_list);
......
...@@ -294,6 +294,7 @@ EXPORT_SYMBOL(drm_init); ...@@ -294,6 +294,7 @@ EXPORT_SYMBOL(drm_init);
*/ */
static void drm_cleanup(struct drm_device * dev) static void drm_cleanup(struct drm_device * dev)
{ {
struct drm_map_list *r_list, *list_temp;
DRM_DEBUG("\n"); DRM_DEBUG("\n");
if (!dev) { if (!dev) {
...@@ -325,6 +326,9 @@ static void drm_cleanup(struct drm_device * dev) ...@@ -325,6 +326,9 @@ static void drm_cleanup(struct drm_device * dev)
drm_ht_remove(&dev->map_hash); drm_ht_remove(&dev->map_hash);
drm_ctxbitmap_cleanup(dev); drm_ctxbitmap_cleanup(dev);
list_for_each_entry_safe(r_list, list_temp, &dev->maplist, head)
drm_rmmap(dev, r_list->map);
if (drm_core_check_feature(dev, DRIVER_MODESET)) if (drm_core_check_feature(dev, DRIVER_MODESET))
drm_put_minor(&dev->control); drm_put_minor(&dev->control);
......
...@@ -660,7 +660,7 @@ struct edid *drm_get_edid(struct drm_connector *connector, ...@@ -660,7 +660,7 @@ struct edid *drm_get_edid(struct drm_connector *connector,
edid = (struct edid *)drm_ddc_read(adapter); edid = (struct edid *)drm_ddc_read(adapter);
if (!edid) { if (!edid) {
dev_warn(&connector->dev->pdev->dev, "%s: no EDID data\n", dev_info(&connector->dev->pdev->dev, "%s: no EDID data\n",
drm_get_connector_name(connector)); drm_get_connector_name(connector));
return NULL; return NULL;
} }
......
...@@ -118,12 +118,20 @@ static void drm_master_destroy(struct kref *kref) ...@@ -118,12 +118,20 @@ static void drm_master_destroy(struct kref *kref)
struct drm_master *master = container_of(kref, struct drm_master, refcount); struct drm_master *master = container_of(kref, struct drm_master, refcount);
struct drm_magic_entry *pt, *next; struct drm_magic_entry *pt, *next;
struct drm_device *dev = master->minor->dev; struct drm_device *dev = master->minor->dev;
struct drm_map_list *r_list, *list_temp;
list_del(&master->head); list_del(&master->head);
if (dev->driver->master_destroy) if (dev->driver->master_destroy)
dev->driver->master_destroy(dev, master); dev->driver->master_destroy(dev, master);
list_for_each_entry_safe(r_list, list_temp, &dev->maplist, head) {
if (r_list->master == master) {
drm_rmmap_locked(dev, r_list->map);
r_list = NULL;
}
}
if (master->unique) { if (master->unique) {
drm_free(master->unique, master->unique_size, DRM_MEM_DRIVER); drm_free(master->unique, master->unique_size, DRM_MEM_DRIVER);
master->unique = NULL; master->unique = NULL;
......
...@@ -944,13 +944,14 @@ static int i915_load_modeset_init(struct drm_device *dev) ...@@ -944,13 +944,14 @@ static int i915_load_modeset_init(struct drm_device *dev)
dev->mode_config.fb_base = drm_get_resource_start(dev, fb_bar) & dev->mode_config.fb_base = drm_get_resource_start(dev, fb_bar) &
0xff000000; 0xff000000;
DRM_DEBUG("*** fb base 0x%08lx\n", dev->mode_config.fb_base); if (IS_MOBILE(dev) || IS_I9XX(dev))
if (IS_MOBILE(dev) || (IS_I9XX(dev) && !IS_I965G(dev) && !IS_G33(dev)))
dev_priv->cursor_needs_physical = true; dev_priv->cursor_needs_physical = true;
else else
dev_priv->cursor_needs_physical = false; dev_priv->cursor_needs_physical = false;
if (IS_I965G(dev) || IS_G33(dev))
dev_priv->cursor_needs_physical = false;
ret = i915_probe_agp(dev, &agp_size, &prealloc_size); ret = i915_probe_agp(dev, &agp_size, &prealloc_size);
if (ret) if (ret)
goto kfree_devname; goto kfree_devname;
......
...@@ -3364,7 +3364,7 @@ void i915_gem_free_all_phys_object(struct drm_device *dev) ...@@ -3364,7 +3364,7 @@ void i915_gem_free_all_phys_object(struct drm_device *dev)
{ {
int i; int i;
for (i = 0; i < I915_MAX_PHYS_OBJECT; i++) for (i = I915_GEM_PHYS_CURSOR_0; i <= I915_MAX_PHYS_OBJECT; i++)
i915_gem_free_phys_object(dev, i); i915_gem_free_phys_object(dev, i);
} }
......
...@@ -340,6 +340,18 @@ static void intel_lvds_destroy(struct drm_connector *connector) ...@@ -340,6 +340,18 @@ static void intel_lvds_destroy(struct drm_connector *connector)
kfree(connector); kfree(connector);
} }
static int intel_lvds_set_property(struct drm_connector *connector,
struct drm_property *property,
uint64_t value)
{
struct drm_device *dev = connector->dev;
if (property == dev->mode_config.dpms_property && connector->encoder)
intel_lvds_dpms(connector->encoder, (uint32_t)(value & 0xf));
return 0;
}
static const struct drm_encoder_helper_funcs intel_lvds_helper_funcs = { static const struct drm_encoder_helper_funcs intel_lvds_helper_funcs = {
.dpms = intel_lvds_dpms, .dpms = intel_lvds_dpms,
.mode_fixup = intel_lvds_mode_fixup, .mode_fixup = intel_lvds_mode_fixup,
...@@ -359,6 +371,7 @@ static const struct drm_connector_funcs intel_lvds_connector_funcs = { ...@@ -359,6 +371,7 @@ static const struct drm_connector_funcs intel_lvds_connector_funcs = {
.restore = intel_lvds_restore, .restore = intel_lvds_restore,
.detect = intel_lvds_detect, .detect = intel_lvds_detect,
.fill_modes = drm_helper_probe_single_connector_modes, .fill_modes = drm_helper_probe_single_connector_modes,
.set_property = intel_lvds_set_property,
.destroy = intel_lvds_destroy, .destroy = intel_lvds_destroy,
}; };
......
...@@ -528,7 +528,8 @@ struct drm_mode_group { ...@@ -528,7 +528,8 @@ struct drm_mode_group {
* *
*/ */
struct drm_mode_config { struct drm_mode_config {
struct mutex mutex; /* protects configuration and IDR */ struct mutex mutex; /* protects configuration (mode lists etc.) */
struct mutex idr_mutex; /* for IDR management */
struct idr crtc_idr; /* use this idr for all IDs, fb, crtc, connector, modes - just makes life easier */ struct idr crtc_idr; /* use this idr for all IDs, fb, crtc, connector, modes - just makes life easier */
/* this is limited to one for now */ /* this is limited to one for now */
int num_fb; int num_fb;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment