Merge commit 'v2.6.31-rc4' into next
diff --git a/drivers/input/keyboard/sh_keysc.c b/drivers/input/keyboard/sh_keysc.c
index cea70e6..0714bf2 100644
--- a/drivers/input/keyboard/sh_keysc.c
+++ b/drivers/input/keyboard/sh_keysc.c
@@ -128,7 +128,7 @@
 	struct resource *res;
 	struct input_dev *input;
 	char clk_name[8];
-	int i, k;
+	int i;
 	int irq, error;
 
 	if (!pdev->dev.platform_data) {
@@ -195,17 +195,19 @@
 	input->id.product = 0x0001;
 	input->id.version = 0x0100;
 
+	input->keycode = pdata->keycodes;
+	input->keycodesize = sizeof(pdata->keycodes[0]);
+	input->keycodemax = ARRAY_SIZE(pdata->keycodes);
+
 	error = request_irq(irq, sh_keysc_isr, 0, pdev->name, pdev);
 	if (error) {
 		dev_err(&pdev->dev, "failed to request IRQ\n");
 		goto err4;
 	}
 
-	for (i = 0; i < SH_KEYSC_MAXKEYS; i++) {
-		k = pdata->keycodes[i];
-		if (k)
-			input_set_capability(input, EV_KEY, k);
-	}
+	for (i = 0; i < SH_KEYSC_MAXKEYS; i++)
+		__set_bit(pdata->keycodes[i], input->keybit);
+	__clear_bit(KEY_RESERVED, input->keybit);
 
 	error = input_register_device(input);
 	if (error) {
@@ -221,7 +223,9 @@
 	iowrite16(KYCR2_IRQ_LEVEL, priv->iomem_base + KYCR2_OFFS);
 
 	device_init_wakeup(&pdev->dev, 1);
+
 	return 0;
+
  err5:
 	free_irq(irq, pdev);
  err4:
@@ -252,6 +256,7 @@
 
 	platform_set_drvdata(pdev, NULL);
 	kfree(priv);
+
 	return 0;
 }
 
@@ -267,11 +272,12 @@
 	if (device_may_wakeup(dev)) {
 		value |= 0x80;
 		enable_irq_wake(irq);
-	}
-	else
+	} else {
 		value &= ~0x80;
+	}
 
 	iowrite16(value, priv->iomem_base + KYCR1_OFFS);
+
 	return 0;
 }
 
diff --git a/drivers/input/misc/cobalt_btns.c b/drivers/input/misc/cobalt_btns.c
index d114d3a..ee73d72 100644
--- a/drivers/input/misc/cobalt_btns.c
+++ b/drivers/input/misc/cobalt_btns.c
@@ -116,7 +116,7 @@
 	}
 
 	bdev->poll_dev = poll_dev;
-	bdev->reg = ioremap(res->start, res->end - res->start + 1);
+	bdev->reg = ioremap(res->start, resource_size(res));
 	dev_set_drvdata(&pdev->dev, bdev);
 
 	error = input_register_polled_device(poll_dev);
diff --git a/drivers/input/misc/dm355evm_keys.c b/drivers/input/misc/dm355evm_keys.c
index a63315c..0918aca 100644
--- a/drivers/input/misc/dm355evm_keys.c
+++ b/drivers/input/misc/dm355evm_keys.c
@@ -23,30 +23,16 @@
  * pressed, or its autorepeat kicks in, an event is sent.  This driver
  * read those events from the small (32 event) queue and reports them.
  *
- * Because we communicate with the MSP430 using I2C, and all I2C calls
- * in Linux sleep, we need to cons up a kind of threaded IRQ handler
- * using a work_struct.  The IRQ is active low, but we use it through
- * the GPIO controller so we can trigger on falling edges.
- *
  * Note that physically there can only be one of these devices.
  *
  * This driver was tested with firmware revision A4.
  */
 struct dm355evm_keys {
-	struct work_struct	work;
 	struct input_dev	*input;
 	struct device		*dev;
 	int			irq;
 };
 
-static irqreturn_t dm355evm_keys_irq(int irq, void *_keys)
-{
-	struct dm355evm_keys	*keys = _keys;
-
-	schedule_work(&keys->work);
-	return IRQ_HANDLED;
-}
-
 /* These initial keycodes can be remapped by dm355evm_setkeycode(). */
 static struct {
 	u16	event;
@@ -110,13 +96,12 @@
 	{ 0x3169, KEY_PAUSE, },
 };
 
-static void dm355evm_keys_work(struct work_struct *work)
+/* runs in an IRQ thread -- can (and will!) sleep */
+static irqreturn_t dm355evm_keys_irq(int irq, void *_keys)
 {
-	struct dm355evm_keys	*keys;
+	struct dm355evm_keys	*keys = _keys;
 	int			status;
 
-	keys = container_of(work, struct dm355evm_keys, work);
-
 	/* For simplicity we ignore INPUT_COUNT and just read
 	 * events until we get the "queue empty" indicator.
 	 * Reading INPUT_LOW decrements the count.
@@ -183,6 +168,19 @@
 		input_report_key(keys->input, keycode, 0);
 		input_sync(keys->input);
 	}
+	return IRQ_HANDLED;
+}
+
+/*
+ * Because we communicate with the MSP430 using I2C, and all I2C calls
+ * in Linux sleep, we use a threaded IRQ handler.  The IRQ itself is
+ * active low, but we go through the GPIO controller so we can trigger
+ * on falling edges and not worry about enabling/disabling the IRQ in
+ * the keypress handling path.
+ */
+static irqreturn_t dm355evm_keys_hardirq(int irq, void *_keys)
+{
+	return IRQ_WAKE_THREAD;
 }
 
 static int dm355evm_setkeycode(struct input_dev *dev, int index, int keycode)
@@ -233,7 +231,6 @@
 
 	keys->dev = &pdev->dev;
 	keys->input = input;
-	INIT_WORK(&keys->work, dm355evm_keys_work);
 
 	/* set up "threaded IRQ handler" */
 	status = platform_get_irq(pdev, 0);
@@ -260,9 +257,10 @@
 
 	/* REVISIT:  flush the event queue? */
 
-	status = request_irq(keys->irq, dm355evm_keys_irq,
-			     IRQF_TRIGGER_FALLING,
-			     dev_name(&pdev->dev), keys);
+	status = request_threaded_irq(keys->irq,
+			dm355evm_keys_hardirq, dm355evm_keys_irq,
+			IRQF_TRIGGER_FALLING,
+			dev_name(&pdev->dev), keys);
 	if (status < 0)
 		goto fail1;
 
diff --git a/drivers/input/serio/at32psif.c b/drivers/input/serio/at32psif.c
index 41fda8c..a6fb7a3 100644
--- a/drivers/input/serio/at32psif.c
+++ b/drivers/input/serio/at32psif.c
@@ -231,7 +231,7 @@
 		goto out_free_io;
 	}
 
-	psif->regs = ioremap(regs->start, regs->end - regs->start + 1);
+	psif->regs = ioremap(regs->start, resource_size(regs));
 	if (!psif->regs) {
 		ret = -ENOMEM;
 		dev_dbg(&pdev->dev, "could not map I/O memory\n");
diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig
index 72e2712..07703bc 100644
--- a/drivers/input/touchscreen/Kconfig
+++ b/drivers/input/touchscreen/Kconfig
@@ -366,11 +366,11 @@
 	  be called atmel-wm97xx.
 
 config TOUCHSCREEN_WM97XX_MAINSTONE
-	tristate "WM97xx Mainstone accelerated touch"
+	tristate "WM97xx Mainstone/Palm accelerated touch"
 	depends on TOUCHSCREEN_WM97XX && ARCH_PXA
 	help
 	  Say Y here for support for streaming mode with WM97xx touchscreens
-	  on Mainstone systems.
+	  on Mainstone, Palm Tungsten T5, TX and LifeDrive systems.
 
 	  If unsure, say N.
 
@@ -406,6 +406,7 @@
 	  - IRTOUCHSYSTEMS/UNITOP
 	  - IdealTEK URTC1000
 	  - GoTop Super_Q2/GogoPen/PenPower tablets
+	  - JASTEC USB Touch Controller/DigiTech DTR-02U
 
 	  Have a look at <http://linux.chapter7.ch/touchkit/> for
 	  a usage description and the required user-space stuff.
@@ -468,6 +469,11 @@
 	bool "GoTop Super_Q2/GogoPen/PenPower tablet device support" if EMBEDDED
 	depends on TOUCHSCREEN_USB_COMPOSITE
 
+config TOUCHSCREEN_USB_JASTEC
+	default y
+	bool "JASTEC/DigiTech DTR-02U USB touch controller device support" if EMBEDDED
+	depends on TOUCHSCREEN_USB_COMPOSITE
+
 config TOUCHSCREEN_TOUCHIT213
 	tristate "Sahara TouchIT-213 touchscreen"
 	select SERIO
@@ -492,6 +498,7 @@
 
 config TOUCHSCREEN_W90X900
 	tristate "W90P910 touchscreen driver"
+	depends on HAVE_CLK
 	help
 	  Say Y here if you have a W90P910 based touchscreen.
 
diff --git a/drivers/input/touchscreen/atmel_tsadcc.c b/drivers/input/touchscreen/atmel_tsadcc.c
index 055969e..9c7fce4 100644
--- a/drivers/input/touchscreen/atmel_tsadcc.c
+++ b/drivers/input/touchscreen/atmel_tsadcc.c
@@ -204,14 +204,14 @@
 		goto err_free_dev;
 	}
 
-	if (!request_mem_region(res->start, res->end - res->start + 1,
+	if (!request_mem_region(res->start, resource_size(res),
 				"atmel tsadcc regs")) {
 		dev_err(&pdev->dev, "resources is unavailable.\n");
 		err = -EBUSY;
 		goto err_free_dev;
 	}
 
-	tsc_base = ioremap(res->start, res->end - res->start + 1);
+	tsc_base = ioremap(res->start, resource_size(res));
 	if (!tsc_base) {
 		dev_err(&pdev->dev, "failed to map registers.\n");
 		err = -ENOMEM;
@@ -286,7 +286,7 @@
 err_unmap_regs:
 	iounmap(tsc_base);
 err_release_mem:
-	release_mem_region(res->start, res->end - res->start + 1);
+	release_mem_region(res->start, resource_size(res));
 err_free_dev:
 	input_free_device(ts_dev->input);
 err_free_mem:
@@ -305,7 +305,7 @@
 
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	iounmap(tsc_base);
-	release_mem_region(res->start, res->end - res->start + 1);
+	release_mem_region(res->start, resource_size(res));
 
 	clk_disable(ts_dev->clk);
 	clk_put(ts_dev->clk);
diff --git a/drivers/input/touchscreen/mainstone-wm97xx.c b/drivers/input/touchscreen/mainstone-wm97xx.c
index 4cc047a..8fc3b08 100644
--- a/drivers/input/touchscreen/mainstone-wm97xx.c
+++ b/drivers/input/touchscreen/mainstone-wm97xx.c
@@ -31,9 +31,11 @@
 #include <linux/interrupt.h>
 #include <linux/wm97xx.h>
 #include <linux/io.h>
+#include <linux/gpio.h>
+
 #include <mach/regs-ac97.h>
 
-#define VERSION		"0.13"
+#include <asm/mach-types.h>
 
 struct continuous {
 	u16 id;    /* codec id */
@@ -62,6 +64,7 @@
 /* continuous speed index */
 static int sp_idx;
 static u16 last, tries;
+static int irq;
 
 /*
  * Pen sampling frequency (Hz) in continuous mode.
@@ -171,7 +174,7 @@
 
 static int wm97xx_acc_startup(struct wm97xx *wm)
 {
-	int idx = 0;
+	int idx = 0, ret = 0;
 
 	/* check we have a codec */
 	if (wm->ac97 == NULL)
@@ -191,18 +194,40 @@
 		 "mainstone accelerated touchscreen driver, %d samples/sec\n",
 		 cinfo[sp_idx].speed);
 
+	/* IRQ driven touchscreen is used on Palm hardware */
+	if (machine_is_palmt5() || machine_is_palmtx() || machine_is_palmld()) {
+		pen_int = 1;
+		irq = 27;
+		/* There is some obscure mutant of WM9712 interbred with WM9713
+		 * used on Palm HW */
+		wm->variant = WM97xx_WM1613;
+	} else if (machine_is_mainstone() && pen_int)
+		irq = 4;
+
+	if (irq) {
+		ret = gpio_request(irq, "Touchscreen IRQ");
+		if (ret)
+			goto out;
+
+		ret = gpio_direction_input(irq);
+		if (ret) {
+			gpio_free(irq);
+			goto out;
+		}
+
+		wm->pen_irq = gpio_to_irq(irq);
+		set_irq_type(wm->pen_irq, IRQ_TYPE_EDGE_BOTH);
+	} else /* pen irq not supported */
+		pen_int = 0;
+
 	/* codec specific irq config */
 	if (pen_int) {
 		switch (wm->id) {
 		case WM9705_ID2:
-			wm->pen_irq = IRQ_GPIO(4);
-			set_irq_type(IRQ_GPIO(4), IRQ_TYPE_EDGE_BOTH);
 			break;
 		case WM9712_ID2:
 		case WM9713_ID2:
-			/* enable pen down interrupt */
 			/* use PEN_DOWN GPIO 13 to assert IRQ on GPIO line 2 */
-			wm->pen_irq = MAINSTONE_AC97_IRQ;
 			wm97xx_config_gpio(wm, WM97XX_GPIO_13, WM97XX_GPIO_IN,
 					   WM97XX_GPIO_POL_HIGH,
 					   WM97XX_GPIO_STICKY,
@@ -220,23 +245,17 @@
 		}
 	}
 
-	return 0;
+out:
+	return ret;
 }
 
 static void wm97xx_acc_shutdown(struct wm97xx *wm)
 {
 	/* codec specific deconfig */
 	if (pen_int) {
-		switch (wm->id & 0xffff) {
-		case WM9705_ID2:
-			wm->pen_irq = 0;
-			break;
-		case WM9712_ID2:
-		case WM9713_ID2:
-			/* disable interrupt */
-			wm->pen_irq = 0;
-			break;
-		}
+		if (irq)
+			gpio_free(irq);
+		wm->pen_irq = 0;
 	}
 }
 
diff --git a/drivers/input/touchscreen/ucb1400_ts.c b/drivers/input/touchscreen/ucb1400_ts.c
index 6954f55..e854835 100644
--- a/drivers/input/touchscreen/ucb1400_ts.c
+++ b/drivers/input/touchscreen/ucb1400_ts.c
@@ -128,9 +128,10 @@
 	return ucb1400_adc_read(ucb->ac97, 0, adcsync);
 }
 
-static inline int ucb1400_ts_pen_down(struct snd_ac97 *ac97)
+static inline int ucb1400_ts_pen_up(struct snd_ac97 *ac97)
 {
 	unsigned short val = ucb1400_reg_read(ac97, UCB_TS_CR);
+
 	return val & (UCB_TS_CR_TSPX_LOW | UCB_TS_CR_TSMX_LOW);
 }
 
@@ -209,7 +210,7 @@
 
 		msleep(10);
 
-		if (ucb1400_ts_pen_down(ucb->ac97)) {
+		if (ucb1400_ts_pen_up(ucb->ac97)) {
 			ucb1400_ts_irq_enable(ucb->ac97);
 
 			/*
diff --git a/drivers/input/touchscreen/usbtouchscreen.c b/drivers/input/touchscreen/usbtouchscreen.c
index fb7cb9b..c07be07 100644
--- a/drivers/input/touchscreen/usbtouchscreen.c
+++ b/drivers/input/touchscreen/usbtouchscreen.c
@@ -13,6 +13,7 @@
  *  - IdealTEK URTC1000
  *  - General Touch
  *  - GoTop Super_Q2/GogoPen/PenPower tablets
+ *  - JASTEC USB touch controller/DigiTech DTR-02U
  *
  * Copyright (C) 2004-2007 by Daniel Ritz <daniel.ritz@gmx.ch>
  * Copyright (C) by Todd E. Johnson (mtouchusb.c)
@@ -118,6 +119,7 @@
 	DEVTYPE_IDEALTEK,
 	DEVTYPE_GENERAL_TOUCH,
 	DEVTYPE_GOTOP,
+	DEVTYPE_JASTEC,
 };
 
 #define USB_DEVICE_HID_CLASS(vend, prod) \
@@ -191,6 +193,10 @@
 	{USB_DEVICE(0x08f2, 0x00f4), .driver_info = DEVTYPE_GOTOP},
 #endif
 
+#ifdef CONFIG_TOUCHSCREEN_USB_JASTEC
+	{USB_DEVICE(0x0f92, 0x0001), .driver_info = DEVTYPE_JASTEC},
+#endif
+
 	{}
 };
 
@@ -559,6 +565,21 @@
 	dev->x = ((pkt[1] & 0x38) << 4) | pkt[2];
 	dev->y = ((pkt[1] & 0x07) << 7) | pkt[3];
 	dev->touch = pkt[0] & 0x01;
+
+	return 1;
+}
+#endif
+
+/*****************************************************************************
+ * JASTEC Part
+ */
+#ifdef CONFIG_TOUCHSCREEN_USB_JASTEC
+static int jastec_read_data(struct usbtouch_usb *dev, unsigned char *pkt)
+{
+	dev->x = ((pkt[0] & 0x3f) << 6) | (pkt[2] & 0x3f);
+	dev->y = ((pkt[1] & 0x3f) << 6) | (pkt[3] & 0x3f);
+	dev->touch = (pkt[0] & 0x40) >> 6;
+
 	return 1;
 }
 #endif
@@ -702,6 +723,17 @@
 		.read_data	= gotop_read_data,
 	},
 #endif
+
+#ifdef CONFIG_TOUCHSCREEN_USB_JASTEC
+	[DEVTYPE_JASTEC] = {
+		.min_xc		= 0x0,
+		.max_xc		= 0x0fff,
+		.min_yc		= 0x0,
+		.max_yc		= 0x0fff,
+		.rept_size	= 4,
+		.read_data	= jastec_read_data,
+	},
+#endif
 };
 
 
diff --git a/drivers/input/touchscreen/w90p910_ts.c b/drivers/input/touchscreen/w90p910_ts.c
index 6071f58..dc4c9d6 100644
--- a/drivers/input/touchscreen/w90p910_ts.c
+++ b/drivers/input/touchscreen/w90p910_ts.c
@@ -13,6 +13,7 @@
 #include <linux/module.h>
 #include <linux/platform_device.h>
 #include <linux/io.h>
+#include <linux/clk.h>
 #include <linux/input.h>
 #include <linux/interrupt.h>
 
@@ -47,8 +48,8 @@
 struct w90p910_ts {
 	struct input_dev *input;
 	struct timer_list timer;
+	struct clk *clk;
 	int irq_num;
-	void __iomem *clocken;
 	void __iomem *ts_reg;
 	spinlock_t lock;
 	enum ts_state state;
@@ -166,8 +167,7 @@
 	unsigned long val;
 
 	/* enable the ADC clock */
-	val = __raw_readl(w90p910_ts->clocken);
-	__raw_writel(val | ADC_CLK_EN, w90p910_ts->clocken);
+	clk_enable(w90p910_ts->clk);
 
 	__raw_writel(ADC_RST1, w90p910_ts->ts_reg);
 	msleep(1);
@@ -211,8 +211,7 @@
 	del_timer_sync(&w90p910_ts->timer);
 
 	/* stop the ADC clock */
-	val = __raw_readl(w90p910_ts->clocken);
-	__raw_writel(val & ~ADC_CLK_EN, w90p910_ts->clocken);
+	clk_disable(w90p910_ts->clk);
 }
 
 static int __devinit w90x900ts_probe(struct platform_device *pdev)
@@ -241,26 +240,24 @@
 		goto fail1;
 	}
 
-	if (!request_mem_region(res->start, res->end - res->start + 1,
+	if (!request_mem_region(res->start, resource_size(res),
 				pdev->name)) {
 		err = -EBUSY;
 		goto fail1;
 	}
 
-	w90p910_ts->ts_reg = ioremap(res->start, res->end - res->start + 1);
+	w90p910_ts->ts_reg = ioremap(res->start, resource_size(res));
 	if (!w90p910_ts->ts_reg) {
 		err = -ENOMEM;
 		goto fail2;
 	}
 
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
-	if (!res) {
-		err = -ENXIO;
+	w90p910_ts->clk = clk_get(&pdev->dev, NULL);
+	if (IS_ERR(w90p910_ts->clk)) {
+		err = PTR_ERR(w90p910_ts->clk);
 		goto fail3;
 	}
 
-	w90p910_ts->clocken = (void __iomem *)res->start;
-
 	input_dev->name = "W90P910 TouchScreen";
 	input_dev->phys = "w90p910ts/event0";
 	input_dev->id.bustype = BUS_HOST;
@@ -283,20 +280,21 @@
 	if (request_irq(w90p910_ts->irq_num, w90p910_ts_interrupt,
 			IRQF_DISABLED, "w90p910ts", w90p910_ts)) {
 		err = -EBUSY;
-		goto fail3;
+		goto fail4;
 	}
 
 	err = input_register_device(w90p910_ts->input);
 	if (err)
-		goto fail4;
+		goto fail5;
 
 	platform_set_drvdata(pdev, w90p910_ts);
 
 	return 0;
 
-fail4:	free_irq(w90p910_ts->irq_num, w90p910_ts);
+fail5:	free_irq(w90p910_ts->irq_num, w90p910_ts);
+fail4:	clk_put(w90p910_ts->clk);
 fail3:	iounmap(w90p910_ts->ts_reg);
-fail2:	release_mem_region(res->start, res->end - res->start + 1);
+fail2:	release_mem_region(res->start, resource_size(res));
 fail1:	input_free_device(input_dev);
 	kfree(w90p910_ts);
 	return err;
@@ -311,8 +309,10 @@
 	del_timer_sync(&w90p910_ts->timer);
 	iounmap(w90p910_ts->ts_reg);
 
+	clk_put(w90p910_ts->clk);
+
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	release_mem_region(res->start, res->end - res->start + 1);
+	release_mem_region(res->start, resource_size(res));
 
 	input_unregister_device(w90p910_ts->input);
 	kfree(w90p910_ts);
diff --git a/drivers/input/touchscreen/wm97xx-core.c b/drivers/input/touchscreen/wm97xx-core.c
index 2957d48..252eb11 100644
--- a/drivers/input/touchscreen/wm97xx-core.c
+++ b/drivers/input/touchscreen/wm97xx-core.c
@@ -204,7 +204,7 @@
 	else
 		reg &= ~gpio;
 
-	if (wm->id == WM9712_ID2)
+	if (wm->id == WM9712_ID2 && wm->variant != WM97xx_WM1613)
 		wm97xx_reg_write(wm, AC97_GPIO_STATUS, reg << 1);
 	else
 		wm97xx_reg_write(wm, AC97_GPIO_STATUS, reg);
@@ -307,7 +307,7 @@
 					 WM97XX_GPIO_13);
 		}
 
-		if (wm->id == WM9712_ID2)
+		if (wm->id == WM9712_ID2 && wm->variant != WM97xx_WM1613)
 			wm97xx_reg_write(wm, AC97_GPIO_STATUS, (status &
 						~WM97XX_GPIO_13) << 1);
 		else
@@ -582,6 +582,8 @@
 
 	wm->id = wm97xx_reg_read(wm, AC97_VENDOR_ID2);
 
+	wm->variant = WM97xx_GENERIC;
+
 	dev_info(wm->dev, "detected a wm97%02x codec\n", wm->id & 0xff);
 
 	switch (wm->id & 0xff) {
diff --git a/include/linux/wm97xx.h b/include/linux/wm97xx.h
index 6f69968..0c98781 100644
--- a/include/linux/wm97xx.h
+++ b/include/linux/wm97xx.h
@@ -16,6 +16,12 @@
 #include <linux/platform_device.h>
 
 /*
+ * WM97xx variants
+ */
+#define	WM97xx_GENERIC			0x0000
+#define	WM97xx_WM1613			0x1613
+
+/*
  * WM97xx AC97 Touchscreen registers
  */
 #define AC97_WM97XX_DIGITISER1		0x76
@@ -283,6 +289,7 @@
 	unsigned pen_is_down:1;		/* Pen is down */
 	unsigned aux_waiting:1;		/* aux measurement waiting */
 	unsigned pen_probably_down:1;	/* used in polling mode */
+	u16 variant;			/* WM97xx chip variant */
 	u16 suspend_mode;               /* PRP in suspend mode */
 };