We want to remove uses of do_gettimeofday() from the kernel since the resulting timeval structure overflows in 2038. This is not a problem for this particular use, but do_gettimeofday() is also not an appropriate method for measuring time intervals, since it requires a conversion into microseconds and is complicated to work with.
ktime_get() is a better replacement, as it works with the monontonic kernel timebase and requires a minimum of computation.
I'm slightly changing the output from microseconds to nanoseconds here, to avoid introducing a new division operation. This should be fine since the value is only used for debugging.
Signed-off-by: Arnd Bergmann arnd@arndb.de --- drivers/gpu/drm/via/via_drv.h | 4 ++-- drivers/gpu/drm/via/via_irq.c | 21 +++++++-------------- 2 files changed, 9 insertions(+), 16 deletions(-)
diff --git a/drivers/gpu/drm/via/via_drv.h b/drivers/gpu/drm/via/via_drv.h index 9873942ca8f4..6d1ae834484c 100644 --- a/drivers/gpu/drm/via/via_drv.h +++ b/drivers/gpu/drm/via/via_drv.h @@ -74,9 +74,9 @@ typedef struct drm_via_private { volatile uint32_t *last_pause_ptr; volatile uint32_t *hw_addr_ptr; drm_via_ring_buffer_t ring; - struct timeval last_vblank; + ktime_t last_vblank; int last_vblank_valid; - unsigned usec_per_vblank; + ktime_t nsec_per_vblank; atomic_t vbl_received; drm_via_state_t hc_state; char pci_buf[VIA_PCI_BUF_SIZE]; diff --git a/drivers/gpu/drm/via/via_irq.c b/drivers/gpu/drm/via/via_irq.c index ea8172c747a2..24e71578af4d 100644 --- a/drivers/gpu/drm/via/via_irq.c +++ b/drivers/gpu/drm/via/via_irq.c @@ -88,13 +88,6 @@ static int via_num_unichrome = ARRAY_SIZE(via_unichrome_irqs); static int via_irqmap_unichrome[] = {-1, -1, -1, 0, -1, 1};
-static unsigned time_diff(struct timeval *now, struct timeval *then) -{ - return (now->tv_usec >= then->tv_usec) ? - now->tv_usec - then->tv_usec : - 1000000 - (then->tv_usec - now->tv_usec); -} - u32 via_get_vblank_counter(struct drm_device *dev, unsigned int pipe) { drm_via_private_t *dev_priv = dev->dev_private; @@ -111,7 +104,7 @@ irqreturn_t via_driver_irq_handler(int irq, void *arg) drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private; u32 status; int handled = 0; - struct timeval cur_vblank; + ktime_t cur_vblank; drm_via_irq_t *cur_irq = dev_priv->via_irqs; int i;
@@ -119,18 +112,18 @@ irqreturn_t via_driver_irq_handler(int irq, void *arg) if (status & VIA_IRQ_VBLANK_PENDING) { atomic_inc(&dev_priv->vbl_received); if (!(atomic_read(&dev_priv->vbl_received) & 0x0F)) { - do_gettimeofday(&cur_vblank); + cur_vblank = ktime_get(); if (dev_priv->last_vblank_valid) { - dev_priv->usec_per_vblank = - time_diff(&cur_vblank, - &dev_priv->last_vblank) >> 4; + dev_priv->nsec_per_vblank = + ktime_sub(cur_vblank, + dev_priv->last_vblank) >> 4; } dev_priv->last_vblank = cur_vblank; dev_priv->last_vblank_valid = 1; } if (!(atomic_read(&dev_priv->vbl_received) & 0xFF)) { - DRM_DEBUG("US per vblank is: %u\n", - dev_priv->usec_per_vblank); + DRM_DEBUG("nsec per vblank is: %llu\n", + ktime_to_ns(dev_priv->nsec_per_vblank)); } drm_handle_vblank(dev, 0); handled = 1;