diff options
Diffstat (limited to 'linux-core')
| -rw-r--r-- | linux-core/ati_pcigart.c | 21 | ||||
| -rw-r--r-- | linux-core/drm_object.c | 57 | ||||
| -rw-r--r-- | linux-core/drm_objects.h | 6 | 
3 files changed, 33 insertions, 51 deletions
| diff --git a/linux-core/ati_pcigart.c b/linux-core/ati_pcigart.c index f7752b5e..34081d4f 100644 --- a/linux-core/ati_pcigart.c +++ b/linux-core/ati_pcigart.c @@ -36,9 +36,6 @@  # define ATI_PCIGART_PAGE_SIZE		4096	/**< PCI GART page size */  # define ATI_PCIGART_PAGE_MASK		(~(ATI_PCIGART_PAGE_SIZE-1)) -#define ATI_PCIE_WRITE 0x4 -#define ATI_PCIE_READ 0x8 -  static int drm_ati_alloc_pcigart_table(struct drm_device *dev,  				       struct drm_ati_pcigart_info *gart_info)  { @@ -108,7 +105,6 @@ int drm_ati_pcigart_init(struct drm_device *dev, struct drm_ati_pcigart_info *ga  	dma_addr_t bus_address = 0;  	int i, j, ret = 0;  	int max_pages; -	dma_addr_t entry_addr;  	if (!entry) {  		DRM_ERROR("no scatter/gather memory!\n"); @@ -155,26 +151,27 @@ int drm_ati_pcigart_init(struct drm_device *dev, struct drm_ati_pcigart_info *ga  			goto done;  		} -		entry_addr = entry->busaddr[i];  		for (j = 0; j < (PAGE_SIZE / ATI_PCIGART_PAGE_SIZE); j++) { -			page_base = (u32) entry_addr & ATI_PCIGART_PAGE_MASK;  			switch(gart_info->gart_reg_if) {  			case DRM_ATI_GART_IGP: -				page_base |= (upper_32_bits(entry_addr) & 0xff) << 4; -				page_base |= ATI_PCIE_READ | ATI_PCIE_WRITE; +				page_base = (u32) entry->busaddr[i] & ATI_PCIGART_PAGE_MASK; +				page_base |= (upper_32_bits(entry->busaddr[i]) & 0xff) << 4; +				*pci_gart = cpu_to_le32((page_base) | 0xc);  				break;  			case DRM_ATI_GART_PCIE: +				page_base = (u32)(entry->busaddr[i] & ATI_PCIGART_PAGE_MASK);  				page_base >>= 8; -				page_base |= (upper_32_bits(entry_addr) & 0xff) << 24; -				page_base |= 0xc; +				page_base |= (upper_32_bits(entry->busaddr[i]) & 0xff) << 24; +				*pci_gart = cpu_to_le32((page_base >> 8) | 0xc);  				break;  			default:  			case DRM_ATI_GART_PCI: +				page_base = (u32) entry->busaddr[i]; +				*pci_gart = cpu_to_le32(page_base);  				break;  			} -			*pci_gart = cpu_to_le32(page_base);  			pci_gart++; -			entry_addr += ATI_PCIGART_PAGE_SIZE; +			page_base += ATI_PCIGART_PAGE_SIZE;  		}  	} diff --git a/linux-core/drm_object.c b/linux-core/drm_object.c index 10924cf5..2994b716 100644 --- a/linux-core/drm_object.c +++ b/linux-core/drm_object.c @@ -39,7 +39,7 @@ int drm_add_user_object(struct drm_file *priv, struct drm_user_object *item,  	DRM_ASSERT_LOCKED(&dev->struct_mutex);  	/* The refcount will be bumped to 1 when we add the ref object below. */ -	kref_init(&item->refcount); +	atomic_set(&item->refcount, 0);  	item->shareable = shareable;  	item->owner = priv; @@ -83,20 +83,16 @@ struct drm_user_object *drm_lookup_user_object(struct drm_file *priv, uint32_t k  }  EXPORT_SYMBOL(drm_lookup_user_object); -static void drm_user_object_free(struct kref *kref) +static void drm_deref_user_object(struct drm_file *priv, struct drm_user_object *item)  { -	struct drm_user_object *item = container_of(kref, struct drm_user_object, refcount); +	struct drm_device *dev = priv->minor->dev;  	int ret; -	struct drm_device *dev = item->owner->minor->dev; - -	ret = drm_ht_remove_item(&dev->object_hash, &item->hash); -	BUG_ON(ret); -	item->remove(item->owner, item); -} -static void drm_deref_user_object(struct drm_user_object *item) -{ -	kref_put(&item->refcount, drm_user_object_free); +	if (atomic_dec_and_test(&item->refcount)) { +		ret = drm_ht_remove_item(&dev->object_hash, &item->hash); +		BUG_ON(ret); +		item->remove(priv, item); +	}  }  static int drm_object_ref_action(struct drm_file *priv, struct drm_user_object *ro, @@ -106,7 +102,7 @@ static int drm_object_ref_action(struct drm_file *priv, struct drm_user_object *  	switch (action) {  	case _DRM_REF_USE: -		kref_get(&ro->refcount); +		atomic_inc(&ro->refcount);  		break;  	default:  		if (!ro->ref_struct_locked) { @@ -150,7 +146,7 @@ int drm_add_ref_object(struct drm_file *priv, struct drm_user_object *referenced  	if (NULL !=  	    (item =  	     drm_lookup_ref_object(priv, referenced_object, ref_action))) { -		kref_get(&item->refcount); +		atomic_inc(&item->refcount);  		return drm_object_ref_action(priv, referenced_object,  					     ref_action);  	} @@ -161,10 +157,8 @@ int drm_add_ref_object(struct drm_file *priv, struct drm_user_object *referenced  		return -ENOMEM;  	} -	kref_init(&item->refcount); -	kref_get(&item->refcount); +	atomic_set(&item->refcount, 1);  	item->hash.key = (unsigned long)referenced_object; -	item->owner = priv;  	ret = drm_ht_insert_item(ht, &item->hash);  	item->unref_action = ref_action; @@ -211,34 +205,27 @@ static void drm_remove_other_references(struct drm_file *priv,  	}  } -void drm_object_ref_free(struct kref *kref) -{ -	struct drm_ref_object *item = container_of(kref, struct drm_ref_object, refcount); -	struct drm_user_object *user_object = (struct drm_user_object *) item->hash.key; -	struct drm_file *priv = item->owner; -	struct drm_open_hash *ht = &priv->refd_object_hash[item->unref_action]; -	int ret; - -	ret = drm_ht_remove_item(ht, &item->hash); -	BUG_ON(ret); -	list_del_init(&item->list); -	if (item->unref_action == _DRM_REF_USE) -		drm_remove_other_references(priv, user_object); -	drm_ctl_free(item, sizeof(*item), DRM_MEM_OBJECTS); -} -  void drm_remove_ref_object(struct drm_file *priv, struct drm_ref_object *item)  { +	int ret;  	struct drm_user_object *user_object = (struct drm_user_object *) item->hash.key; +	struct drm_open_hash *ht = &priv->refd_object_hash[item->unref_action];  	enum drm_ref_type unref_action;  	DRM_ASSERT_LOCKED(&priv->minor->dev->struct_mutex);  	unref_action = item->unref_action; -	kref_put(&item->refcount, drm_object_ref_free); +	if (atomic_dec_and_test(&item->refcount)) { +		ret = drm_ht_remove_item(ht, &item->hash); +		BUG_ON(ret); +		list_del_init(&item->list); +		if (unref_action == _DRM_REF_USE) +			drm_remove_other_references(priv, user_object); +		drm_ctl_free(item, sizeof(*item), DRM_MEM_OBJECTS); +	}  	switch (unref_action) {  	case _DRM_REF_USE: -		drm_deref_user_object(user_object); +		drm_deref_user_object(priv, user_object);  		break;  	default:  		BUG_ON(!user_object->unref); diff --git a/linux-core/drm_objects.h b/linux-core/drm_objects.h index 427a9170..770fbc56 100644 --- a/linux-core/drm_objects.h +++ b/linux-core/drm_objects.h @@ -65,8 +65,7 @@ struct drm_user_object {  	struct drm_hash_item hash;  	struct list_head list;  	enum drm_object_type type; -	struct kref refcount; - +	atomic_t refcount;  	int shareable;  	struct drm_file *owner;  	void (*ref_struct_locked) (struct drm_file *priv, @@ -87,9 +86,8 @@ struct drm_user_object {  struct drm_ref_object {  	struct drm_hash_item hash;  	struct list_head list; -	struct kref refcount; +	atomic_t refcount;  	enum drm_ref_type unref_action; -	struct drm_file *owner;  };  /** | 
