]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/input/touchscreen/ads7846.c
[PATCH 3/6] ads7846: replace spin_lock_irqsave
[linux-2.6-omap-h63xx.git] / drivers / input / touchscreen / ads7846.c
index e1f94fb4518af0e6b1cbcfcedae3c8871e69105c..8200a03ee2d7f7927be9b4c3ff70abeeec30a73f 100644 (file)
@@ -2,7 +2,8 @@
  * ADS7846 based touchscreen and sensor driver
  *
  * Copyright (c) 2005 David Brownell
- * Copyright (c) 2006 Imre Deak <imre.deak@nokia.com>
+ * Copyright (c) 2006 Nokia Corporation
+ * Various changes: Imre Deak <imre.deak@nokia.com>
  *
  * Using code from:
  *  - corgi_ts.c
@@ -44,7 +45,7 @@
  * edge triggered IRQs on some platforms like the OMAP1/2. These
  * platforms don't handle the ARM lazy IRQ disabling properly, thus we
  * have to maintain our own SW IRQ disabled status. This should be
- * removed as soon as the affected platforms' IRQ handling is fixed.
+ * removed as soon as the affected platform's IRQ handling is fixed.
  *
  * app note sbaa036 talks in more detail about accurate sampling...
  * that ought to help in situations like LCDs inducing noise (which
@@ -79,14 +80,10 @@ struct ads7846 {
        u16                     model;
        u16                     vref_delay_usecs;
        u16                     x_plate_ohms;
-       u16                     pressure_max;
 
        u8                      read_x, read_y, read_z1, read_z2, pwrdown;
        u16                     dummy;          /* for the pwrdown read */
        struct ts_event         tc;
-       u16                     last_x;
-       u16                     last_y;
-       u16                     last_pressure;
 
        struct spi_transfer     xfer[10];
        struct spi_message      msg[5];
@@ -338,19 +335,18 @@ static ssize_t ads7846_disable_store(struct device *dev,
                                     const char *buf, size_t count)
 {
        struct ads7846 *ts = dev_get_drvdata(dev);
-       unsigned long flags;
        char *endp;
        int i;
 
        i = simple_strtoul(buf, &endp, 10);
-       spin_lock_irqsave(&ts->lock, flags);
+       spin_lock_irq(&ts->lock);
 
        if (i)
                ads7846_disable(ts);
        else
                ads7846_enable(ts);
 
-       spin_unlock_irqrestore(&ts->lock, flags);
+       spin_unlock_irq(&ts->lock);
 
        return count;
 }
@@ -399,18 +395,6 @@ static void ads7846_rx(void *ads)
        } else
                Rt = 0;
 
-       if (Rt > ts->pressure_max) {
-               if (ts->last_pressure) {
-                       x = ts->last_x;
-                       y = ts->last_y;
-               }
-               Rt = ts->pressure_max;
-       }
-
-       ts->last_x = x;
-       ts->last_y = y;
-       ts->last_pressure = Rt;
-
        /* NOTE:  "pendown" is inferred from pressure; we don't rely on
         * being able to check nPENIRQ status, or "friendly" trigger modes
         * (both-edges is much better than just-falling or low-level).
@@ -474,10 +458,11 @@ static void ads7846_debounce(void *ads)
        t = list_entry(m->transfers.prev, struct spi_transfer, transfer_list);
        val = (*(u16 *)t->rx_buf) >> 3;
 
-       if (!ts->read_cnt || (abs(ts->last_read - val) > ts->debounce_tol &&
-                             ts->read_cnt < ts->debounce_max)) {
+       if (!ts->read_cnt || (abs(ts->last_read - val) > ts->debounce_tol
+                               && ts->read_cnt < ts->debounce_max)) {
                /* Repeat it, if this was the first read or the read wasn't
-                * consistent enough */
+                * consistent enough
+                */
                ts->read_cnt++;
                ts->last_read = val;
        } else {
@@ -511,10 +496,14 @@ static irqreturn_t ads7846_irq(int irq, void *handle, struct pt_regs *regs)
        spin_lock_irqsave(&ts->lock, flags);
        if (likely(!ts->irq_disabled && !ts->disabled)) {
                if (!ts->irq_disabled) {
+                       /* REVISIT irq logic for many ARM chips has cloned a
+                        * bug wherein disabling an irq in its handler won't
+                        * work;(it's disabled lazily, and too late to work.
+                        * until all their irq logic is fixed, we must shadow
+                        * that state here.
+                        */
                        ts->irq_disabled = 1;
-                       /* The following has at the moment no effect whatsoever
-                        * on OMAP, that's why we maintain the disabled
-                        * state ourselves */
+
                        disable_irq(ts->spi->irq);
                }
                if (!ts->pending) {
@@ -542,8 +531,6 @@ static void ads7846_disable(struct ads7846 *ts)
                        disable_irq(ts->spi->irq);
                }
        } else {
-               unsigned long flags;
-
                /* polling; force a final SPI completion;
                 * that will clean things up neatly
                 */
@@ -551,9 +538,9 @@ static void ads7846_disable(struct ads7846 *ts)
                        mod_timer(&ts->timer, jiffies);
 
                while (ts->pendown || ts->pending) {
-                       spin_unlock_irqrestore(&ts->lock, flags);
+                       spin_unlock_irq(&ts->lock);
                        msleep(1);
-                       spin_lock_irqsave(&ts->lock, flags);
+                       spin_lock_irq(&ts->lock);
                }
        }
 
@@ -578,14 +565,13 @@ static void ads7846_enable(struct ads7846 *ts)
 static int ads7846_suspend(struct spi_device *spi, pm_message_t message)
 {
        struct ads7846 *ts = dev_get_drvdata(&spi->dev);
-       unsigned long   flags;
 
-       spin_lock_irqsave(&ts->lock, flags);
+       spin_lock_irq(&ts->lock);
 
        spi->dev.power.power_state = message;
        ads7846_disable(ts);
 
-       spin_unlock_irqrestore(&ts->lock, flags);
+       spin_unlock_irq(&ts->lock);
 
        return 0;
 
@@ -594,14 +580,13 @@ static int ads7846_suspend(struct spi_device *spi, pm_message_t message)
 static int ads7846_resume(struct spi_device *spi)
 {
        struct ads7846 *ts = dev_get_drvdata(&spi->dev);
-       unsigned long flags;
 
-       spin_lock_irqsave(&ts->lock, flags);
+       spin_lock_irq(&ts->lock);
 
        spi->dev.power.power_state = PMSG_ON;
        ads7846_enable(ts);
 
-       spin_unlock_irqrestore(&ts->lock, flags);
+       spin_unlock_irq(&ts->lock);
 
        return 0;
 }
@@ -664,7 +649,6 @@ static int __devinit ads7846_probe(struct spi_device *spi)
        ts->model = pdata->model ? : 7846;
        ts->vref_delay_usecs = pdata->vref_delay_usecs ? : 100;
        ts->x_plate_ohms = pdata->x_plate_ohms ? : 400;
-       ts->pressure_max = pdata->pressure_max ? : ~0;
        ts->debounce_max = pdata->debounce_max ? : 1;
        ts->debounce_tol = pdata->debounce_tol ? : 10;