Input: ads7846 - switch to using hrtimer

Use hrtimer instead of the normal timer, since it provides better
sampling resolution. This will:

 - avoid a problem where we have a 1 jiffy poll period and
   dynamic tick on
 - utilize high resolution HW clocks when they are added to
   the hrtimer framework

Signed-off-by: Imre Deak <imre.deak@solidboot.com>
Signed-off-by: Juha Yrjola <juha.yrjola@solidboot.com>
Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
diff --git a/drivers/input/touchscreen/ads7846.c b/drivers/input/touchscreen/ads7846.c
index c34e59b..d983cc5 100644
--- a/drivers/input/touchscreen/ads7846.c
+++ b/drivers/input/touchscreen/ads7846.c
@@ -54,7 +54,8 @@
  * files.
  */
 
-#define	TS_POLL_PERIOD	msecs_to_jiffies(10)
+#define TS_POLL_DELAY	(1 * 1000000)	/* ns delay before the first sample */
+#define TS_POLL_PERIOD	(5 * 1000000)	/* ns delay between samples */
 
 /* this driver doesn't aim at the peak continuous sample rate */
 #define	SAMPLE_BITS	(8 /*cmd*/ + 16 /*sample*/ + 2 /* before, after */)
@@ -99,7 +100,7 @@
 	u16			debounce_rep;
 
 	spinlock_t		lock;
-	struct timer_list	timer;		/* P: lock */
+	struct hrtimer		timer;
 	unsigned		pendown:1;	/* P: lock */
 	unsigned		pending:1;	/* P: lock */
 // FIXME remove "irq_disabled"
@@ -407,10 +408,12 @@
 		Rt = 0;
 
 	/* Sample found inconsistent by debouncing or pressure is beyond
-	* the maximum. Don't report it to user space, repeat at least
-	* once more the measurement */
+	 * the maximum. Don't report it to user space, repeat at least
+	 * once more the measurement
+	 */
 	if (ts->tc.ignore || Rt > ts->pressure_max) {
-		mod_timer(&ts->timer, jiffies + TS_POLL_PERIOD);
+		hrtimer_start(&ts->timer, ktime_set(0, TS_POLL_PERIOD),
+			      HRTIMER_REL);
 		return;
 	}
 
@@ -452,7 +455,7 @@
 	spin_lock_irqsave(&ts->lock, flags);
 
 	ts->pendown = (Rt != 0);
-	mod_timer(&ts->timer, jiffies + TS_POLL_PERIOD);
+	hrtimer_start(&ts->timer, ktime_set(0, TS_POLL_PERIOD), HRTIMER_REL);
 
 	spin_unlock_irqrestore(&ts->lock, flags);
 }
@@ -543,9 +546,9 @@
 				status);
 }
 
-static void ads7846_timer(unsigned long handle)
+static int ads7846_timer(struct hrtimer *handle)
 {
-	struct ads7846	*ts = (void *)handle;
+	struct ads7846	*ts = container_of(handle, struct ads7846, timer);
 	int		status = 0;
 
 	spin_lock_irq(&ts->lock);
@@ -567,6 +570,7 @@
 	}
 
 	spin_unlock_irq(&ts->lock);
+	return HRTIMER_NORESTART;
 }
 
 static irqreturn_t ads7846_irq(int irq, void *handle)
@@ -585,7 +589,8 @@
 			ts->irq_disabled = 1;
 			disable_irq(ts->spi->irq);
 			ts->pending = 1;
-			mod_timer(&ts->timer, jiffies);
+			hrtimer_start(&ts->timer, ktime_set(0, TS_POLL_DELAY),
+					HRTIMER_REL);
 		}
 	}
 	spin_unlock_irqrestore(&ts->lock, flags);
@@ -719,8 +724,7 @@
 	ts->spi = spi;
 	ts->input = input_dev;
 
-	init_timer(&ts->timer);
-	ts->timer.data = (unsigned long) ts;
+	hrtimer_init(&ts->timer, CLOCK_MONOTONIC, HRTIMER_REL);
 	ts->timer.function = ads7846_timer;
 
 	spin_lock_init(&ts->lock);