diff options
Diffstat (limited to 'recipes/linux/linux-openmoko-2.6.32/0017-s3c2410_ts-ignore-unexpected-interrupts.patch')
-rw-r--r-- | recipes/linux/linux-openmoko-2.6.32/0017-s3c2410_ts-ignore-unexpected-interrupts.patch | 114 |
1 files changed, 114 insertions, 0 deletions
diff --git a/recipes/linux/linux-openmoko-2.6.32/0017-s3c2410_ts-ignore-unexpected-interrupts.patch b/recipes/linux/linux-openmoko-2.6.32/0017-s3c2410_ts-ignore-unexpected-interrupts.patch new file mode 100644 index 0000000000..0da1261d39 --- /dev/null +++ b/recipes/linux/linux-openmoko-2.6.32/0017-s3c2410_ts-ignore-unexpected-interrupts.patch @@ -0,0 +1,114 @@ +From fd25a512062b198af666bbdab805e8d6b51ed166 Mon Sep 17 00:00:00 2001 +From: Gennady Kupava <gb@bsdmn.com> +Date: Sun, 27 Jun 2010 10:01:54 +0200 +Subject: [PATCH 17/22] s3c2410_ts: ignore unexpected interrupts + +--- + drivers/input/touchscreen/s3c2410_ts.c | 30 +++++++++++++++++++++++++++++- + 1 files changed, 29 insertions(+), 1 deletions(-) + +diff --git a/drivers/input/touchscreen/s3c2410_ts.c b/drivers/input/touchscreen/s3c2410_ts.c +index 97def9d..fd0b7d4 100644 +--- a/drivers/input/touchscreen/s3c2410_ts.c ++++ b/drivers/input/touchscreen/s3c2410_ts.c +@@ -47,6 +47,9 @@ + * 2009-04-09: Nelson Castillo <arhuaco@freaks-unidos.net> + * - Use s3c-adc API (Vasily Khoruzhick <anarsoul@gmail.com> provided + * a working example for a simpler version of this driver). ++ ++ * 2010-06-01: Gennady Kupava <gb@bsdmn.com> ++ * - Improve interrupt handling + */ + + #include <linux/errno.h> +@@ -120,10 +123,15 @@ struct s3c2410ts { + struct kfifo *event_fifo; + struct s3c_adc_client *adc_client; + unsigned adc_selected; ++ int expectedintr; /* which interrupt we are waiting for */ + }; + + static struct s3c2410ts ts; + ++#define WAITFORINT_UP (0) ++#define WAITFORINT_DOWN (1) ++#define WAITFORINT_NOTHING (2) ++ + static void __iomem *base_addr; + + /* +@@ -282,6 +290,19 @@ static irqreturn_t stylus_updown(int irq, void *dev_id) + ts.is_down = !(data0 & S3C2410_ADCDAT0_UPDOWN) && + !(data1 & S3C2410_ADCDAT0_UPDOWN); + ++ /* situations below can actually happen on openmoko hardware while ++ various debugging facilities are turned off */ ++ if (ts.expectedintr == WAITFORINT_NOTHING) ++ return IRQ_HANDLED; ++ if (!ts.is_down && ts.expectedintr == WAITFORINT_DOWN) { ++ writel(WAIT4INT (0), base_addr + S3C2410_ADCTSC); ++ return IRQ_HANDLED; ++ } else if (ts.is_down && ts.expectedintr == WAITFORINT_UP) { ++ writel(WAIT4INT (1), base_addr + S3C2410_ADCTSC); ++ return IRQ_HANDLED; ++ } ++ ts.expectedintr = WAITFORINT_NOTHING; ++ + event_type = ts.is_down ? 'D' : 'U'; + + if (unlikely(__kfifo_put(ts.event_fifo, (unsigned char *)&event_type, +@@ -291,8 +312,10 @@ static irqreturn_t stylus_updown(int irq, void *dev_id) + + if (ts.is_down) + s3c2410_ts_start_adc_conversion(); +- else ++ else { ++ ts.expectedintr = WAITFORINT_DOWN; + writel(WAIT4INT(0), base_addr + S3C2410_ADCTSC); ++ } + + mod_timer(&event_send_timer, jiffies + 1); + +@@ -327,6 +350,7 @@ static void stylus_adc_action(struct s3c_adc_client *client, unsigned p0, unsign + case -1: + /* Too much noise. Ignore the event. */ + ts_filter_chain_clear(ts.chain); ++ ts.expectedintr = WAITFORINT_UP; + writel(WAIT4INT(1), base_addr + S3C2410_ADCTSC); + return; + }; +@@ -336,6 +360,7 @@ static void stylus_adc_action(struct s3c_adc_client *client, unsigned p0, unsign + /* This will only happen if we have a bug. */ + TSPRINTK("FIFO full\n"); + ++ ts.expectedintr = WAITFORINT_UP; + writel(WAIT4INT(1), base_addr + S3C2410_ADCTSC); + mod_timer(&event_send_timer, jiffies + 1); + +@@ -373,6 +398,7 @@ static int __init s3c2410ts_probe(struct platform_device *pdev) + if (!strcmp(pdev->name, "s3c2410-ts")) + s3c2410_ts_connect(); + ++ ts.expectedintr = WAITFORINT_DOWN; + writel(WAIT4INT(0), base_addr + S3C2410_ADCTSC); + + /* Initialise input stuff */ +@@ -482,6 +508,7 @@ static int s3c2410ts_remove(struct platform_device *pdev) + + static int s3c2410ts_suspend(struct platform_device *pdev, pm_message_t state) + { ++ ts.expectedintr = WAITFORINT_NOTHING; + writel(TSC_SLEEP, base_addr + S3C2410_ADCTSC); + writel(readl(base_addr + S3C2410_ADCCON) | S3C2410_ADCCON_STDBM, + base_addr + S3C2410_ADCCON); +@@ -493,6 +520,7 @@ static int s3c2410ts_suspend(struct platform_device *pdev, pm_message_t state) + static int s3c2410ts_resume(struct platform_device *pdev) + { + ts_filter_chain_clear(ts.chain); ++ ts.expectedintr = WAITFORINT_DOWN; + enable_irq(IRQ_TC); + writel(WAIT4INT(0), base_addr + S3C2410_ADCTSC); + +-- +1.7.1.1 + |