aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/radeon/radeon_kms.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/radeon/radeon_kms.c')
-rw-r--r--drivers/gpu/drm/radeon/radeon_kms.c35
1 files changed, 29 insertions, 6 deletions
diff --git a/drivers/gpu/drm/radeon/radeon_kms.c b/drivers/gpu/drm/radeon/radeon_kms.c
index 1d73f16b5d97..414b4acf6947 100644
--- a/drivers/gpu/drm/radeon/radeon_kms.c
+++ b/drivers/gpu/drm/radeon/radeon_kms.c
@@ -29,6 +29,7 @@
29#include "drm_sarea.h" 29#include "drm_sarea.h"
30#include "radeon.h" 30#include "radeon.h"
31#include "radeon_drm.h" 31#include "radeon_drm.h"
32#include "radeon_asic.h"
32 33
33#include <linux/vga_switcheroo.h> 34#include <linux/vga_switcheroo.h>
34#include <linux/slab.h> 35#include <linux/slab.h>
@@ -167,17 +168,39 @@ static void radeon_set_filp_rights(struct drm_device *dev,
167int radeon_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) 168int radeon_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
168{ 169{
169 struct radeon_device *rdev = dev->dev_private; 170 struct radeon_device *rdev = dev->dev_private;
170 struct drm_radeon_info *info; 171 struct drm_radeon_info *info = data;
171 struct radeon_mode_info *minfo = &rdev->mode_info; 172 struct radeon_mode_info *minfo = &rdev->mode_info;
172 uint32_t *value_ptr; 173 uint32_t value, *value_ptr;
173 uint32_t value; 174 uint64_t value64, *value_ptr64;
174 struct drm_crtc *crtc; 175 struct drm_crtc *crtc;
175 int i, found; 176 int i, found;
176 177
177 info = data; 178 /* TIMESTAMP is a 64-bit value, needs special handling. */
179 if (info->request == RADEON_INFO_TIMESTAMP) {
180 if (rdev->family >= CHIP_R600) {
181 value_ptr64 = (uint64_t*)((unsigned long)info->value);
182 if (rdev->family >= CHIP_TAHITI) {
183 value64 = si_get_gpu_clock(rdev);
184 } else {
185 value64 = r600_get_gpu_clock(rdev);
186 }
187
188 if (DRM_COPY_TO_USER(value_ptr64, &value64, sizeof(value64))) {
189 DRM_ERROR("copy_to_user %s:%u\n", __func__, __LINE__);
190 return -EFAULT;
191 }
192 return 0;
193 } else {
194 DRM_DEBUG_KMS("timestamp is r6xx+ only!\n");
195 return -EINVAL;
196 }
197 }
198
178 value_ptr = (uint32_t *)((unsigned long)info->value); 199 value_ptr = (uint32_t *)((unsigned long)info->value);
179 if (DRM_COPY_FROM_USER(&value, value_ptr, sizeof(value))) 200 if (DRM_COPY_FROM_USER(&value, value_ptr, sizeof(value))) {
201 DRM_ERROR("copy_from_user %s:%u\n", __func__, __LINE__);
180 return -EFAULT; 202 return -EFAULT;
203 }
181 204
182 switch (info->request) { 205 switch (info->request) {
183 case RADEON_INFO_DEVICE_ID: 206 case RADEON_INFO_DEVICE_ID:
@@ -337,7 +360,7 @@ int radeon_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
337 return -EINVAL; 360 return -EINVAL;
338 } 361 }
339 if (DRM_COPY_TO_USER(value_ptr, &value, sizeof(uint32_t))) { 362 if (DRM_COPY_TO_USER(value_ptr, &value, sizeof(uint32_t))) {
340 DRM_ERROR("copy_to_user\n"); 363 DRM_ERROR("copy_to_user %s:%u\n", __func__, __LINE__);
341 return -EFAULT; 364 return -EFAULT;
342 } 365 }
343 return 0; 366 return 0;