diff options
author | Jonathan Herman <hermanjl@cs.unc.edu> | 2013-01-17 16:15:55 -0500 |
---|---|---|
committer | Jonathan Herman <hermanjl@cs.unc.edu> | 2013-01-17 16:15:55 -0500 |
commit | 8dea78da5cee153b8af9c07a2745f6c55057fe12 (patch) | |
tree | a8f4d49d63b1ecc92f2fddceba0655b2472c5bd9 /drivers/gpu/drm/sis | |
parent | 406089d01562f1e2bf9f089fd7637009ebaad589 (diff) |
Patched in Tegra support.
Diffstat (limited to 'drivers/gpu/drm/sis')
-rw-r--r-- | drivers/gpu/drm/sis/sis_drv.c | 75 | ||||
-rw-r--r-- | drivers/gpu/drm/sis/sis_drv.h | 7 | ||||
-rw-r--r-- | drivers/gpu/drm/sis/sis_mm.c | 222 |
3 files changed, 117 insertions, 187 deletions
diff --git a/drivers/gpu/drm/sis/sis_drv.c b/drivers/gpu/drm/sis/sis_drv.c index 841065b998a..46d5be6e97e 100644 --- a/drivers/gpu/drm/sis/sis_drv.c +++ b/drivers/gpu/drm/sis/sis_drv.c | |||
@@ -25,13 +25,11 @@ | |||
25 | * | 25 | * |
26 | */ | 26 | */ |
27 | 27 | ||
28 | #include <linux/module.h> | 28 | #include "drmP.h" |
29 | 29 | #include "sis_drm.h" | |
30 | #include <drm/drmP.h> | ||
31 | #include <drm/sis_drm.h> | ||
32 | #include "sis_drv.h" | 30 | #include "sis_drv.h" |
33 | 31 | ||
34 | #include <drm/drm_pciids.h> | 32 | #include "drm_pciids.h" |
35 | 33 | ||
36 | static struct pci_device_id pciidlist[] = { | 34 | static struct pci_device_id pciidlist[] = { |
37 | sisdrv_PCI_IDS | 35 | sisdrv_PCI_IDS |
@@ -40,80 +38,51 @@ static struct pci_device_id pciidlist[] = { | |||
40 | static int sis_driver_load(struct drm_device *dev, unsigned long chipset) | 38 | static int sis_driver_load(struct drm_device *dev, unsigned long chipset) |
41 | { | 39 | { |
42 | drm_sis_private_t *dev_priv; | 40 | drm_sis_private_t *dev_priv; |
43 | 41 | int ret; | |
44 | pci_set_master(dev->pdev); | ||
45 | 42 | ||
46 | dev_priv = kzalloc(sizeof(drm_sis_private_t), GFP_KERNEL); | 43 | dev_priv = kzalloc(sizeof(drm_sis_private_t), GFP_KERNEL); |
47 | if (dev_priv == NULL) | 44 | if (dev_priv == NULL) |
48 | return -ENOMEM; | 45 | return -ENOMEM; |
49 | 46 | ||
50 | idr_init(&dev_priv->object_idr); | ||
51 | dev->dev_private = (void *)dev_priv; | 47 | dev->dev_private = (void *)dev_priv; |
52 | dev_priv->chipset = chipset; | 48 | dev_priv->chipset = chipset; |
49 | ret = drm_sman_init(&dev_priv->sman, 2, 12, 8); | ||
50 | if (ret) | ||
51 | kfree(dev_priv); | ||
53 | 52 | ||
54 | return 0; | 53 | return ret; |
55 | } | 54 | } |
56 | 55 | ||
57 | static int sis_driver_unload(struct drm_device *dev) | 56 | static int sis_driver_unload(struct drm_device *dev) |
58 | { | 57 | { |
59 | drm_sis_private_t *dev_priv = dev->dev_private; | 58 | drm_sis_private_t *dev_priv = dev->dev_private; |
60 | 59 | ||
61 | idr_remove_all(&dev_priv->object_idr); | 60 | drm_sman_takedown(&dev_priv->sman); |
62 | idr_destroy(&dev_priv->object_idr); | ||
63 | |||
64 | kfree(dev_priv); | 61 | kfree(dev_priv); |
65 | 62 | ||
66 | return 0; | 63 | return 0; |
67 | } | 64 | } |
68 | 65 | ||
69 | static const struct file_operations sis_driver_fops = { | ||
70 | .owner = THIS_MODULE, | ||
71 | .open = drm_open, | ||
72 | .release = drm_release, | ||
73 | .unlocked_ioctl = drm_ioctl, | ||
74 | .mmap = drm_mmap, | ||
75 | .poll = drm_poll, | ||
76 | .fasync = drm_fasync, | ||
77 | #ifdef CONFIG_COMPAT | ||
78 | .compat_ioctl = drm_compat_ioctl, | ||
79 | #endif | ||
80 | .llseek = noop_llseek, | ||
81 | }; | ||
82 | |||
83 | static int sis_driver_open(struct drm_device *dev, struct drm_file *file) | ||
84 | { | ||
85 | struct sis_file_private *file_priv; | ||
86 | |||
87 | DRM_DEBUG_DRIVER("\n"); | ||
88 | file_priv = kmalloc(sizeof(*file_priv), GFP_KERNEL); | ||
89 | if (!file_priv) | ||
90 | return -ENOMEM; | ||
91 | |||
92 | file->driver_priv = file_priv; | ||
93 | |||
94 | INIT_LIST_HEAD(&file_priv->obj_list); | ||
95 | |||
96 | return 0; | ||
97 | } | ||
98 | |||
99 | void sis_driver_postclose(struct drm_device *dev, struct drm_file *file) | ||
100 | { | ||
101 | struct sis_file_private *file_priv = file->driver_priv; | ||
102 | |||
103 | kfree(file_priv); | ||
104 | } | ||
105 | |||
106 | static struct drm_driver driver = { | 66 | static struct drm_driver driver = { |
107 | .driver_features = DRIVER_USE_AGP | DRIVER_USE_MTRR, | 67 | .driver_features = DRIVER_USE_AGP | DRIVER_USE_MTRR, |
108 | .load = sis_driver_load, | 68 | .load = sis_driver_load, |
109 | .unload = sis_driver_unload, | 69 | .unload = sis_driver_unload, |
110 | .open = sis_driver_open, | ||
111 | .preclose = sis_reclaim_buffers_locked, | ||
112 | .postclose = sis_driver_postclose, | ||
113 | .dma_quiescent = sis_idle, | 70 | .dma_quiescent = sis_idle, |
71 | .reclaim_buffers = NULL, | ||
72 | .reclaim_buffers_idlelocked = sis_reclaim_buffers_locked, | ||
114 | .lastclose = sis_lastclose, | 73 | .lastclose = sis_lastclose, |
115 | .ioctls = sis_ioctls, | 74 | .ioctls = sis_ioctls, |
116 | .fops = &sis_driver_fops, | 75 | .fops = { |
76 | .owner = THIS_MODULE, | ||
77 | .open = drm_open, | ||
78 | .release = drm_release, | ||
79 | .unlocked_ioctl = drm_ioctl, | ||
80 | .mmap = drm_mmap, | ||
81 | .poll = drm_poll, | ||
82 | .fasync = drm_fasync, | ||
83 | .llseek = noop_llseek, | ||
84 | }, | ||
85 | |||
117 | .name = DRIVER_NAME, | 86 | .name = DRIVER_NAME, |
118 | .desc = DRIVER_DESC, | 87 | .desc = DRIVER_DESC, |
119 | .date = DRIVER_DATE, | 88 | .date = DRIVER_DATE, |
diff --git a/drivers/gpu/drm/sis/sis_drv.h b/drivers/gpu/drm/sis/sis_drv.h index 13b527bb83b..194303c177a 100644 --- a/drivers/gpu/drm/sis/sis_drv.h +++ b/drivers/gpu/drm/sis/sis_drv.h | |||
@@ -44,7 +44,7 @@ enum sis_family { | |||
44 | SIS_CHIP_315 = 1, | 44 | SIS_CHIP_315 = 1, |
45 | }; | 45 | }; |
46 | 46 | ||
47 | #include <drm/drm_mm.h> | 47 | #include "drm_sman.h" |
48 | 48 | ||
49 | 49 | ||
50 | #define SIS_BASE (dev_priv->mmio) | 50 | #define SIS_BASE (dev_priv->mmio) |
@@ -54,15 +54,12 @@ enum sis_family { | |||
54 | typedef struct drm_sis_private { | 54 | typedef struct drm_sis_private { |
55 | drm_local_map_t *mmio; | 55 | drm_local_map_t *mmio; |
56 | unsigned int idle_fault; | 56 | unsigned int idle_fault; |
57 | struct drm_sman sman; | ||
57 | unsigned int chipset; | 58 | unsigned int chipset; |
58 | int vram_initialized; | 59 | int vram_initialized; |
59 | int agp_initialized; | 60 | int agp_initialized; |
60 | unsigned long vram_offset; | 61 | unsigned long vram_offset; |
61 | unsigned long agp_offset; | 62 | unsigned long agp_offset; |
62 | struct drm_mm vram_mm; | ||
63 | struct drm_mm agp_mm; | ||
64 | /** Mapping of userspace keys to mm objects */ | ||
65 | struct idr object_idr; | ||
66 | } drm_sis_private_t; | 63 | } drm_sis_private_t; |
67 | 64 | ||
68 | extern int sis_idle(struct drm_device *dev); | 65 | extern int sis_idle(struct drm_device *dev); |
diff --git a/drivers/gpu/drm/sis/sis_mm.c b/drivers/gpu/drm/sis/sis_mm.c index 2b2f78c428a..7fe2b63412c 100644 --- a/drivers/gpu/drm/sis/sis_mm.c +++ b/drivers/gpu/drm/sis/sis_mm.c | |||
@@ -31,8 +31,8 @@ | |||
31 | * Thomas Hellström <thomas-at-tungstengraphics-dot-com> | 31 | * Thomas Hellström <thomas-at-tungstengraphics-dot-com> |
32 | */ | 32 | */ |
33 | 33 | ||
34 | #include <drm/drmP.h> | 34 | #include "drmP.h" |
35 | #include <drm/sis_drm.h> | 35 | #include "sis_drm.h" |
36 | #include "sis_drv.h" | 36 | #include "sis_drv.h" |
37 | 37 | ||
38 | #include <video/sisfb.h> | 38 | #include <video/sisfb.h> |
@@ -41,18 +41,40 @@ | |||
41 | #define AGP_TYPE 1 | 41 | #define AGP_TYPE 1 |
42 | 42 | ||
43 | 43 | ||
44 | struct sis_memblock { | ||
45 | struct drm_mm_node mm_node; | ||
46 | struct sis_memreq req; | ||
47 | struct list_head owner_list; | ||
48 | }; | ||
49 | |||
50 | #if defined(CONFIG_FB_SIS) || defined(CONFIG_FB_SIS_MODULE) | 44 | #if defined(CONFIG_FB_SIS) || defined(CONFIG_FB_SIS_MODULE) |
51 | /* fb management via fb device */ | 45 | /* fb management via fb device */ |
52 | 46 | ||
53 | #define SIS_MM_ALIGN_SHIFT 0 | 47 | #define SIS_MM_ALIGN_SHIFT 0 |
54 | #define SIS_MM_ALIGN_MASK 0 | 48 | #define SIS_MM_ALIGN_MASK 0 |
55 | 49 | ||
50 | static void *sis_sman_mm_allocate(void *private, unsigned long size, | ||
51 | unsigned alignment) | ||
52 | { | ||
53 | struct sis_memreq req; | ||
54 | |||
55 | req.size = size; | ||
56 | sis_malloc(&req); | ||
57 | if (req.size == 0) | ||
58 | return NULL; | ||
59 | else | ||
60 | return (void *)(unsigned long)~req.offset; | ||
61 | } | ||
62 | |||
63 | static void sis_sman_mm_free(void *private, void *ref) | ||
64 | { | ||
65 | sis_free(~((unsigned long)ref)); | ||
66 | } | ||
67 | |||
68 | static void sis_sman_mm_destroy(void *private) | ||
69 | { | ||
70 | ; | ||
71 | } | ||
72 | |||
73 | static unsigned long sis_sman_mm_offset(void *private, void *ref) | ||
74 | { | ||
75 | return ~((unsigned long)ref); | ||
76 | } | ||
77 | |||
56 | #else /* CONFIG_FB_SIS[_MODULE] */ | 78 | #else /* CONFIG_FB_SIS[_MODULE] */ |
57 | 79 | ||
58 | #define SIS_MM_ALIGN_SHIFT 4 | 80 | #define SIS_MM_ALIGN_SHIFT 4 |
@@ -64,30 +86,47 @@ static int sis_fb_init(struct drm_device *dev, void *data, struct drm_file *file | |||
64 | { | 86 | { |
65 | drm_sis_private_t *dev_priv = dev->dev_private; | 87 | drm_sis_private_t *dev_priv = dev->dev_private; |
66 | drm_sis_fb_t *fb = data; | 88 | drm_sis_fb_t *fb = data; |
89 | int ret; | ||
67 | 90 | ||
68 | mutex_lock(&dev->struct_mutex); | 91 | mutex_lock(&dev->struct_mutex); |
69 | /* Unconditionally init the drm_mm, even though we don't use it when the | 92 | #if defined(CONFIG_FB_SIS) || defined(CONFIG_FB_SIS_MODULE) |
70 | * fb sis driver is available - make cleanup easier. */ | 93 | { |
71 | drm_mm_init(&dev_priv->vram_mm, 0, fb->size >> SIS_MM_ALIGN_SHIFT); | 94 | struct drm_sman_mm sman_mm; |
95 | sman_mm.private = (void *)0xFFFFFFFF; | ||
96 | sman_mm.allocate = sis_sman_mm_allocate; | ||
97 | sman_mm.free = sis_sman_mm_free; | ||
98 | sman_mm.destroy = sis_sman_mm_destroy; | ||
99 | sman_mm.offset = sis_sman_mm_offset; | ||
100 | ret = | ||
101 | drm_sman_set_manager(&dev_priv->sman, VIDEO_TYPE, &sman_mm); | ||
102 | } | ||
103 | #else | ||
104 | ret = drm_sman_set_range(&dev_priv->sman, VIDEO_TYPE, 0, | ||
105 | fb->size >> SIS_MM_ALIGN_SHIFT); | ||
106 | #endif | ||
107 | |||
108 | if (ret) { | ||
109 | DRM_ERROR("VRAM memory manager initialisation error\n"); | ||
110 | mutex_unlock(&dev->struct_mutex); | ||
111 | return ret; | ||
112 | } | ||
72 | 113 | ||
73 | dev_priv->vram_initialized = 1; | 114 | dev_priv->vram_initialized = 1; |
74 | dev_priv->vram_offset = fb->offset; | 115 | dev_priv->vram_offset = fb->offset; |
75 | 116 | ||
76 | mutex_unlock(&dev->struct_mutex); | 117 | mutex_unlock(&dev->struct_mutex); |
77 | DRM_DEBUG("offset = %lu, size = %lu\n", fb->offset, fb->size); | 118 | DRM_DEBUG("offset = %u, size = %u\n", fb->offset, fb->size); |
78 | 119 | ||
79 | return 0; | 120 | return 0; |
80 | } | 121 | } |
81 | 122 | ||
82 | static int sis_drm_alloc(struct drm_device *dev, struct drm_file *file, | 123 | static int sis_drm_alloc(struct drm_device *dev, struct drm_file *file_priv, |
83 | void *data, int pool) | 124 | void *data, int pool) |
84 | { | 125 | { |
85 | drm_sis_private_t *dev_priv = dev->dev_private; | 126 | drm_sis_private_t *dev_priv = dev->dev_private; |
86 | drm_sis_mem_t *mem = data; | 127 | drm_sis_mem_t *mem = data; |
87 | int retval = 0, user_key; | 128 | int retval = 0; |
88 | struct sis_memblock *item; | 129 | struct drm_memblock_item *item; |
89 | struct sis_file_private *file_priv = file->driver_priv; | ||
90 | unsigned long offset; | ||
91 | 130 | ||
92 | mutex_lock(&dev->struct_mutex); | 131 | mutex_lock(&dev->struct_mutex); |
93 | 132 | ||
@@ -99,69 +138,26 @@ static int sis_drm_alloc(struct drm_device *dev, struct drm_file *file, | |||
99 | return -EINVAL; | 138 | return -EINVAL; |
100 | } | 139 | } |
101 | 140 | ||
102 | item = kzalloc(sizeof(*item), GFP_KERNEL); | ||
103 | if (!item) { | ||
104 | retval = -ENOMEM; | ||
105 | goto fail_alloc; | ||
106 | } | ||
107 | |||
108 | mem->size = (mem->size + SIS_MM_ALIGN_MASK) >> SIS_MM_ALIGN_SHIFT; | 141 | mem->size = (mem->size + SIS_MM_ALIGN_MASK) >> SIS_MM_ALIGN_SHIFT; |
109 | if (pool == AGP_TYPE) { | 142 | item = drm_sman_alloc(&dev_priv->sman, pool, mem->size, 0, |
110 | retval = drm_mm_insert_node(&dev_priv->agp_mm, | 143 | (unsigned long)file_priv); |
111 | &item->mm_node, | ||
112 | mem->size, 0); | ||
113 | offset = item->mm_node.start; | ||
114 | } else { | ||
115 | #if defined(CONFIG_FB_SIS) || defined(CONFIG_FB_SIS_MODULE) | ||
116 | item->req.size = mem->size; | ||
117 | sis_malloc(&item->req); | ||
118 | if (item->req.size == 0) | ||
119 | retval = -ENOMEM; | ||
120 | offset = item->req.offset; | ||
121 | #else | ||
122 | retval = drm_mm_insert_node(&dev_priv->vram_mm, | ||
123 | &item->mm_node, | ||
124 | mem->size, 0); | ||
125 | offset = item->mm_node.start; | ||
126 | #endif | ||
127 | } | ||
128 | if (retval) | ||
129 | goto fail_alloc; | ||
130 | 144 | ||
131 | again: | 145 | mutex_unlock(&dev->struct_mutex); |
132 | if (idr_pre_get(&dev_priv->object_idr, GFP_KERNEL) == 0) { | 146 | if (item) { |
147 | mem->offset = ((pool == 0) ? | ||
148 | dev_priv->vram_offset : dev_priv->agp_offset) + | ||
149 | (item->mm-> | ||
150 | offset(item->mm, item->mm_info) << SIS_MM_ALIGN_SHIFT); | ||
151 | mem->free = item->user_hash.key; | ||
152 | mem->size = mem->size << SIS_MM_ALIGN_SHIFT; | ||
153 | } else { | ||
154 | mem->offset = 0; | ||
155 | mem->size = 0; | ||
156 | mem->free = 0; | ||
133 | retval = -ENOMEM; | 157 | retval = -ENOMEM; |
134 | goto fail_idr; | ||
135 | } | 158 | } |
136 | 159 | ||
137 | retval = idr_get_new_above(&dev_priv->object_idr, item, 1, &user_key); | 160 | DRM_DEBUG("alloc %d, size = %d, offset = %d\n", pool, mem->size, |
138 | if (retval == -EAGAIN) | ||
139 | goto again; | ||
140 | if (retval) | ||
141 | goto fail_idr; | ||
142 | |||
143 | list_add(&item->owner_list, &file_priv->obj_list); | ||
144 | mutex_unlock(&dev->struct_mutex); | ||
145 | |||
146 | mem->offset = ((pool == 0) ? | ||
147 | dev_priv->vram_offset : dev_priv->agp_offset) + | ||
148 | (offset << SIS_MM_ALIGN_SHIFT); | ||
149 | mem->free = user_key; | ||
150 | mem->size = mem->size << SIS_MM_ALIGN_SHIFT; | ||
151 | |||
152 | return 0; | ||
153 | |||
154 | fail_idr: | ||
155 | drm_mm_remove_node(&item->mm_node); | ||
156 | fail_alloc: | ||
157 | kfree(item); | ||
158 | mutex_unlock(&dev->struct_mutex); | ||
159 | |||
160 | mem->offset = 0; | ||
161 | mem->size = 0; | ||
162 | mem->free = 0; | ||
163 | |||
164 | DRM_DEBUG("alloc %d, size = %ld, offset = %ld\n", pool, mem->size, | ||
165 | mem->offset); | 161 | mem->offset); |
166 | 162 | ||
167 | return retval; | 163 | return retval; |
@@ -171,28 +167,14 @@ static int sis_drm_free(struct drm_device *dev, void *data, struct drm_file *fil | |||
171 | { | 167 | { |
172 | drm_sis_private_t *dev_priv = dev->dev_private; | 168 | drm_sis_private_t *dev_priv = dev->dev_private; |
173 | drm_sis_mem_t *mem = data; | 169 | drm_sis_mem_t *mem = data; |
174 | struct sis_memblock *obj; | 170 | int ret; |
175 | 171 | ||
176 | mutex_lock(&dev->struct_mutex); | 172 | mutex_lock(&dev->struct_mutex); |
177 | obj = idr_find(&dev_priv->object_idr, mem->free); | 173 | ret = drm_sman_free_key(&dev_priv->sman, mem->free); |
178 | if (obj == NULL) { | ||
179 | mutex_unlock(&dev->struct_mutex); | ||
180 | return -EINVAL; | ||
181 | } | ||
182 | |||
183 | idr_remove(&dev_priv->object_idr, mem->free); | ||
184 | list_del(&obj->owner_list); | ||
185 | if (drm_mm_node_allocated(&obj->mm_node)) | ||
186 | drm_mm_remove_node(&obj->mm_node); | ||
187 | #if defined(CONFIG_FB_SIS) || defined(CONFIG_FB_SIS_MODULE) | ||
188 | else | ||
189 | sis_free(obj->req.offset); | ||
190 | #endif | ||
191 | kfree(obj); | ||
192 | mutex_unlock(&dev->struct_mutex); | 174 | mutex_unlock(&dev->struct_mutex); |
193 | DRM_DEBUG("free = 0x%lx\n", mem->free); | 175 | DRM_DEBUG("free = 0x%lx\n", mem->free); |
194 | 176 | ||
195 | return 0; | 177 | return ret; |
196 | } | 178 | } |
197 | 179 | ||
198 | static int sis_fb_alloc(struct drm_device *dev, void *data, | 180 | static int sis_fb_alloc(struct drm_device *dev, void *data, |
@@ -206,16 +188,24 @@ static int sis_ioctl_agp_init(struct drm_device *dev, void *data, | |||
206 | { | 188 | { |
207 | drm_sis_private_t *dev_priv = dev->dev_private; | 189 | drm_sis_private_t *dev_priv = dev->dev_private; |
208 | drm_sis_agp_t *agp = data; | 190 | drm_sis_agp_t *agp = data; |
191 | int ret; | ||
209 | dev_priv = dev->dev_private; | 192 | dev_priv = dev->dev_private; |
210 | 193 | ||
211 | mutex_lock(&dev->struct_mutex); | 194 | mutex_lock(&dev->struct_mutex); |
212 | drm_mm_init(&dev_priv->agp_mm, 0, agp->size >> SIS_MM_ALIGN_SHIFT); | 195 | ret = drm_sman_set_range(&dev_priv->sman, AGP_TYPE, 0, |
196 | agp->size >> SIS_MM_ALIGN_SHIFT); | ||
197 | |||
198 | if (ret) { | ||
199 | DRM_ERROR("AGP memory manager initialisation error\n"); | ||
200 | mutex_unlock(&dev->struct_mutex); | ||
201 | return ret; | ||
202 | } | ||
213 | 203 | ||
214 | dev_priv->agp_initialized = 1; | 204 | dev_priv->agp_initialized = 1; |
215 | dev_priv->agp_offset = agp->offset; | 205 | dev_priv->agp_offset = agp->offset; |
216 | mutex_unlock(&dev->struct_mutex); | 206 | mutex_unlock(&dev->struct_mutex); |
217 | 207 | ||
218 | DRM_DEBUG("offset = %lu, size = %lu\n", agp->offset, agp->size); | 208 | DRM_DEBUG("offset = %u, size = %u\n", agp->offset, agp->size); |
219 | return 0; | 209 | return 0; |
220 | } | 210 | } |
221 | 211 | ||
@@ -303,55 +293,29 @@ void sis_lastclose(struct drm_device *dev) | |||
303 | return; | 293 | return; |
304 | 294 | ||
305 | mutex_lock(&dev->struct_mutex); | 295 | mutex_lock(&dev->struct_mutex); |
306 | if (dev_priv->vram_initialized) { | 296 | drm_sman_cleanup(&dev_priv->sman); |
307 | drm_mm_takedown(&dev_priv->vram_mm); | 297 | dev_priv->vram_initialized = 0; |
308 | dev_priv->vram_initialized = 0; | 298 | dev_priv->agp_initialized = 0; |
309 | } | ||
310 | if (dev_priv->agp_initialized) { | ||
311 | drm_mm_takedown(&dev_priv->agp_mm); | ||
312 | dev_priv->agp_initialized = 0; | ||
313 | } | ||
314 | dev_priv->mmio = NULL; | 299 | dev_priv->mmio = NULL; |
315 | mutex_unlock(&dev->struct_mutex); | 300 | mutex_unlock(&dev->struct_mutex); |
316 | } | 301 | } |
317 | 302 | ||
318 | void sis_reclaim_buffers_locked(struct drm_device *dev, | 303 | void sis_reclaim_buffers_locked(struct drm_device *dev, |
319 | struct drm_file *file) | 304 | struct drm_file *file_priv) |
320 | { | 305 | { |
321 | struct sis_file_private *file_priv = file->driver_priv; | 306 | drm_sis_private_t *dev_priv = dev->dev_private; |
322 | struct sis_memblock *entry, *next; | ||
323 | |||
324 | if (!(file->minor->master && file->master->lock.hw_lock)) | ||
325 | return; | ||
326 | |||
327 | drm_idlelock_take(&file->master->lock); | ||
328 | 307 | ||
329 | mutex_lock(&dev->struct_mutex); | 308 | mutex_lock(&dev->struct_mutex); |
330 | if (list_empty(&file_priv->obj_list)) { | 309 | if (drm_sman_owner_clean(&dev_priv->sman, (unsigned long)file_priv)) { |
331 | mutex_unlock(&dev->struct_mutex); | 310 | mutex_unlock(&dev->struct_mutex); |
332 | drm_idlelock_release(&file->master->lock); | ||
333 | |||
334 | return; | 311 | return; |
335 | } | 312 | } |
336 | 313 | ||
337 | sis_idle(dev); | 314 | if (dev->driver->dma_quiescent) |
315 | dev->driver->dma_quiescent(dev); | ||
338 | 316 | ||
339 | 317 | drm_sman_owner_cleanup(&dev_priv->sman, (unsigned long)file_priv); | |
340 | list_for_each_entry_safe(entry, next, &file_priv->obj_list, | ||
341 | owner_list) { | ||
342 | list_del(&entry->owner_list); | ||
343 | if (drm_mm_node_allocated(&entry->mm_node)) | ||
344 | drm_mm_remove_node(&entry->mm_node); | ||
345 | #if defined(CONFIG_FB_SIS) || defined(CONFIG_FB_SIS_MODULE) | ||
346 | else | ||
347 | sis_free(entry->req.offset); | ||
348 | #endif | ||
349 | kfree(entry); | ||
350 | } | ||
351 | mutex_unlock(&dev->struct_mutex); | 318 | mutex_unlock(&dev->struct_mutex); |
352 | |||
353 | drm_idlelock_release(&file->master->lock); | ||
354 | |||
355 | return; | 319 | return; |
356 | } | 320 | } |
357 | 321 | ||