From 78a56aab11234e53b7e94e5a255cc3d27ab0a62b Mon Sep 17 00:00:00 2001
From: Phil Blundell <pb@handhelds.org>
Date: Thu, 18 Jan 2007 00:44:09 -0500
Subject: Input: gpio-keys - keyboard driver for GPIO buttons

This is an interrupt-driven keyboard driver for simple buttons
connected directly to CPU GPIO lines of embedded ARM systems.
It supports pxa architectures and is used by a number of PDAs
and PocketPC phones in the handhelds.org kernel. Support for
other architectures, such as sa11xx and sc2410, will be added
once generic GPIO API is available.

Signed-off-by: Paul Sokolovsky <pmiscml@gmail.com>
Signed-off-by: Philipp Zabel <philipp.zabel@gmail.com>
Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
---
 include/asm-arm/hardware/gpio_keys.h | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)
 create mode 100644 include/asm-arm/hardware/gpio_keys.h

(limited to 'include/asm-arm')

diff --git a/include/asm-arm/hardware/gpio_keys.h b/include/asm-arm/hardware/gpio_keys.h
new file mode 100644
index 000000000000..2b217c7b9312
--- /dev/null
+++ b/include/asm-arm/hardware/gpio_keys.h
@@ -0,0 +1,17 @@
+#ifndef _GPIO_KEYS_H
+#define _GPIO_KEYS_H
+
+struct gpio_keys_button {
+	/* Configuration parameters */
+	int keycode;
+	int gpio;
+	int active_low;
+	char *desc;
+};
+
+struct gpio_keys_platform_data {
+	struct gpio_keys_button *buttons;
+	int nbuttons;
+};
+
+#endif
-- 
cgit v1.2.3


From 75e7153abd220f1c4a731a9613fb705485b56aa8 Mon Sep 17 00:00:00 2001
From: Ralf Baechle <ralf@linux-mips.org>
Date: Fri, 9 Feb 2007 17:08:58 +0000
Subject: [APM] ARM: Convert to use shared APM emulation.

Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
---
 arch/arm/Kconfig               |  29 +-
 arch/arm/common/sharpsl_pm.c   |   2 +-
 arch/arm/kernel/Makefile       |   1 -
 arch/arm/kernel/apm.c          | 672 -----------------------------------------
 arch/arm/mach-pxa/corgi_pm.c   |   2 +-
 arch/arm/mach-pxa/sharpsl_pm.c |   2 +-
 arch/arm/mach-pxa/spitz_pm.c   |   2 +-
 include/asm-arm/apm.h          |  64 ----
 8 files changed, 8 insertions(+), 766 deletions(-)
 delete mode 100644 arch/arm/kernel/apm.c
 delete mode 100644 include/asm-arm/apm.h

(limited to 'include/asm-arm')

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 6783c2e5512d..1523046e092b 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -9,6 +9,7 @@ config ARM
 	bool
 	default y
 	select RTC_LIB
+	select SYS_SUPPORTS_APM_EMULATION
 	help
 	  The ARM series is a line of low-power-consumption RISC chip designs
 	  licensed by ARM Ltd and targeted at embedded applications and
@@ -17,6 +18,9 @@ config ARM
 	  Europe.  There is an ARM Linux project with a web page at
 	  <http://www.arm.linux.org.uk/>.
 
+config SYS_SUPPORTS_APM_EMULATION
+	bool
+
 config GENERIC_TIME
 	bool
 	default n
@@ -856,31 +860,6 @@ menu "Power management options"
 
 source "kernel/power/Kconfig"
 
-config APM
-	tristate "Advanced Power Management Emulation"
-	---help---
-	  APM is a BIOS specification for saving power using several different
-	  techniques. This is mostly useful for battery powered laptops with
-	  APM compliant BIOSes. If you say Y here, the system time will be
-	  reset after a RESUME operation, the /proc/apm device will provide
-	  battery status information, and user-space programs will receive
-	  notification of APM "events" (e.g. battery status change).
-
-	  In order to use APM, you will need supporting software. For location
-	  and more information, read <file:Documentation/pm.txt> and the
-	  Battery Powered Linux mini-HOWTO, available from
-	  <http://www.tldp.org/docs.html#howto>.
-
-	  This driver does not spin down disk drives (see the hdparm(8)
-	  manpage ("man 8 hdparm") for that), and it doesn't turn off
-	  VESA-compliant "green" monitors.
-
-	  Generally, if you don't have a battery in your machine, there isn't
-	  much point in using this driver and you should say N. If you get
-	  random kernel OOPSes or reboots that don't seem to be related to
-	  anything, try disabling/enabling this option (or disabling/enabling
-	  APM in your BIOS).
-
 endmenu
 
 source "net/Kconfig"
diff --git a/arch/arm/common/sharpsl_pm.c b/arch/arm/common/sharpsl_pm.c
index b3599743093b..a3b450f8ef17 100644
--- a/arch/arm/common/sharpsl_pm.c
+++ b/arch/arm/common/sharpsl_pm.c
@@ -27,7 +27,7 @@
 #include <asm/hardware.h>
 #include <asm/mach-types.h>
 #include <asm/irq.h>
-#include <asm/apm.h>
+#include <asm/apm-emulation.h>
 #include <asm/arch/pm.h>
 #include <asm/arch/pxa-regs.h>
 #include <asm/arch/sharpsl.h>
diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile
index ab06a86e85d5..1b935fb94b83 100644
--- a/arch/arm/kernel/Makefile
+++ b/arch/arm/kernel/Makefile
@@ -10,7 +10,6 @@ obj-y		:= compat.o entry-armv.o entry-common.o irq.o \
 		   process.o ptrace.o semaphore.o setup.o signal.o sys_arm.o \
 		   time.o traps.o
 
-obj-$(CONFIG_APM)		+= apm.o
 obj-$(CONFIG_ISA_DMA_API)	+= dma.o
 obj-$(CONFIG_ARCH_ACORN)	+= ecard.o 
 obj-$(CONFIG_FIQ)		+= fiq.o
diff --git a/arch/arm/kernel/apm.c b/arch/arm/kernel/apm.c
deleted file mode 100644
index 2c37b70b17ab..000000000000
--- a/arch/arm/kernel/apm.c
+++ /dev/null
@@ -1,672 +0,0 @@
-/*
- * bios-less APM driver for ARM Linux 
- *  Jamey Hicks <jamey@crl.dec.com>
- *  adapted from the APM BIOS driver for Linux by Stephen Rothwell (sfr@linuxcare.com)
- *
- * APM 1.2 Reference:
- *   Intel Corporation, Microsoft Corporation. Advanced Power Management
- *   (APM) BIOS Interface Specification, Revision 1.2, February 1996.
- *
- * [This document is available from Microsoft at:
- *    http://www.microsoft.com/hwdev/busbios/amp_12.htm]
- */
-#include <linux/module.h>
-#include <linux/poll.h>
-#include <linux/slab.h>
-#include <linux/proc_fs.h>
-#include <linux/miscdevice.h>
-#include <linux/apm_bios.h>
-#include <linux/capability.h>
-#include <linux/sched.h>
-#include <linux/pm.h>
-#include <linux/device.h>
-#include <linux/kernel.h>
-#include <linux/list.h>
-#include <linux/init.h>
-#include <linux/completion.h>
-#include <linux/kthread.h>
-#include <linux/delay.h>
-
-#include <asm/apm.h> /* apm_power_info */
-#include <asm/system.h>
-
-/*
- * The apm_bios device is one of the misc char devices.
- * This is its minor number.
- */
-#define APM_MINOR_DEV	134
-
-/*
- * See Documentation/Config.help for the configuration options.
- *
- * Various options can be changed at boot time as follows:
- * (We allow underscores for compatibility with the modules code)
- *	apm=on/off			enable/disable APM
- */
-
-/*
- * Maximum number of events stored
- */
-#define APM_MAX_EVENTS		16
-
-struct apm_queue {
-	unsigned int		event_head;
-	unsigned int		event_tail;
-	apm_event_t		events[APM_MAX_EVENTS];
-};
-
-/*
- * The per-file APM data
- */
-struct apm_user {
-	struct list_head	list;
-
-	unsigned int		suser: 1;
-	unsigned int		writer: 1;
-	unsigned int		reader: 1;
-
-	int			suspend_result;
-	unsigned int		suspend_state;
-#define SUSPEND_NONE	0		/* no suspend pending */
-#define SUSPEND_PENDING	1		/* suspend pending read */
-#define SUSPEND_READ	2		/* suspend read, pending ack */
-#define SUSPEND_ACKED	3		/* suspend acked */
-#define SUSPEND_WAIT	4		/* waiting for suspend */
-#define SUSPEND_DONE	5		/* suspend completed */
-
-	struct apm_queue	queue;
-};
-
-/*
- * Local variables
- */
-static int suspends_pending;
-static int apm_disabled;
-static struct task_struct *kapmd_tsk;
-
-static DECLARE_WAIT_QUEUE_HEAD(apm_waitqueue);
-static DECLARE_WAIT_QUEUE_HEAD(apm_suspend_waitqueue);
-
-/*
- * This is a list of everyone who has opened /dev/apm_bios
- */
-static DECLARE_RWSEM(user_list_lock);
-static LIST_HEAD(apm_user_list);
-
-/*
- * kapmd info.  kapmd provides us a process context to handle
- * "APM" events within - specifically necessary if we're going
- * to be suspending the system.
- */
-static DECLARE_WAIT_QUEUE_HEAD(kapmd_wait);
-static DEFINE_SPINLOCK(kapmd_queue_lock);
-static struct apm_queue kapmd_queue;
-
-static DEFINE_MUTEX(state_lock);
-
-static const char driver_version[] = "1.13";	/* no spaces */
-
-
-
-/*
- * Compatibility cruft until the IPAQ people move over to the new
- * interface.
- */
-static void __apm_get_power_status(struct apm_power_info *info)
-{
-}
-
-/*
- * This allows machines to provide their own "apm get power status" function.
- */
-void (*apm_get_power_status)(struct apm_power_info *) = __apm_get_power_status;
-EXPORT_SYMBOL(apm_get_power_status);
-
-
-/*
- * APM event queue management.
- */
-static inline int queue_empty(struct apm_queue *q)
-{
-	return q->event_head == q->event_tail;
-}
-
-static inline apm_event_t queue_get_event(struct apm_queue *q)
-{
-	q->event_tail = (q->event_tail + 1) % APM_MAX_EVENTS;
-	return q->events[q->event_tail];
-}
-
-static void queue_add_event(struct apm_queue *q, apm_event_t event)
-{
-	q->event_head = (q->event_head + 1) % APM_MAX_EVENTS;
-	if (q->event_head == q->event_tail) {
-		static int notified;
-
-		if (notified++ == 0)
-		    printk(KERN_ERR "apm: an event queue overflowed\n");
-		q->event_tail = (q->event_tail + 1) % APM_MAX_EVENTS;
-	}
-	q->events[q->event_head] = event;
-}
-
-static void queue_event(apm_event_t event)
-{
-	struct apm_user *as;
-
-	down_read(&user_list_lock);
-	list_for_each_entry(as, &apm_user_list, list) {
-		if (as->reader)
-			queue_add_event(&as->queue, event);
-	}
-	up_read(&user_list_lock);
-	wake_up_interruptible(&apm_waitqueue);
-}
-
-/*
- * queue_suspend_event - queue an APM suspend event.
- *
- * Check that we're in a state where we can suspend.  If not,
- * return -EBUSY.  Otherwise, queue an event to all "writer"
- * users.  If there are no "writer" users, return '1' to
- * indicate that we can immediately suspend.
- */
-static int queue_suspend_event(apm_event_t event, struct apm_user *sender)
-{
-	struct apm_user *as;
-	int ret = 1;
-
-	mutex_lock(&state_lock);
-	down_read(&user_list_lock);
-
-	/*
-	 * If a thread is still processing, we can't suspend, so reject
-	 * the request.
-	 */
-	list_for_each_entry(as, &apm_user_list, list) {
-		if (as != sender && as->reader && as->writer && as->suser &&
-		    as->suspend_state != SUSPEND_NONE) {
-			ret = -EBUSY;
-			goto out;
-		}
-	}
-
-	list_for_each_entry(as, &apm_user_list, list) {
-		if (as != sender && as->reader && as->writer && as->suser) {
-			as->suspend_state = SUSPEND_PENDING;
-			suspends_pending++;
-			queue_add_event(&as->queue, event);
-			ret = 0;
-		}
-	}
- out:
-	up_read(&user_list_lock);
-	mutex_unlock(&state_lock);
-	wake_up_interruptible(&apm_waitqueue);
-	return ret;
-}
-
-static void apm_suspend(void)
-{
-	struct apm_user *as;
-	int err = pm_suspend(PM_SUSPEND_MEM);
-
-	/*
-	 * Anyone on the APM queues will think we're still suspended.
-	 * Send a message so everyone knows we're now awake again.
-	 */
-	queue_event(APM_NORMAL_RESUME);
-
-	/*
-	 * Finally, wake up anyone who is sleeping on the suspend.
-	 */
-	mutex_lock(&state_lock);
-	down_read(&user_list_lock);
-	list_for_each_entry(as, &apm_user_list, list) {
-		if (as->suspend_state == SUSPEND_WAIT ||
-		    as->suspend_state == SUSPEND_ACKED) {
-	  		as->suspend_result = err;
-			as->suspend_state = SUSPEND_DONE;
-		}
-	}
-	up_read(&user_list_lock);
-	mutex_unlock(&state_lock);
-
-	wake_up(&apm_suspend_waitqueue);
-}
-
-static ssize_t apm_read(struct file *fp, char __user *buf, size_t count, loff_t *ppos)
-{
-	struct apm_user *as = fp->private_data;
-	apm_event_t event;
-	int i = count, ret = 0;
-
-	if (count < sizeof(apm_event_t))
-		return -EINVAL;
-
-	if (queue_empty(&as->queue) && fp->f_flags & O_NONBLOCK)
-		return -EAGAIN;
-
-	wait_event_interruptible(apm_waitqueue, !queue_empty(&as->queue));
-
-	while ((i >= sizeof(event)) && !queue_empty(&as->queue)) {
-		event = queue_get_event(&as->queue);
-
-		ret = -EFAULT;
-		if (copy_to_user(buf, &event, sizeof(event)))
-			break;
-
-		mutex_lock(&state_lock);
-		if (as->suspend_state == SUSPEND_PENDING &&
-		    (event == APM_SYS_SUSPEND || event == APM_USER_SUSPEND))
-			as->suspend_state = SUSPEND_READ;
-		mutex_unlock(&state_lock);
-
-		buf += sizeof(event);
-		i -= sizeof(event);
-	}
-
-	if (i < count)
-		ret = count - i;
-
-	return ret;
-}
-
-static unsigned int apm_poll(struct file *fp, poll_table * wait)
-{
-	struct apm_user *as = fp->private_data;
-
-	poll_wait(fp, &apm_waitqueue, wait);
-	return queue_empty(&as->queue) ? 0 : POLLIN | POLLRDNORM;
-}
-
-/*
- * apm_ioctl - handle APM ioctl
- *
- * APM_IOC_SUSPEND
- *   This IOCTL is overloaded, and performs two functions.  It is used to:
- *     - initiate a suspend
- *     - acknowledge a suspend read from /dev/apm_bios.
- *   Only when everyone who has opened /dev/apm_bios with write permission
- *   has acknowledge does the actual suspend happen.
- */
-static int
-apm_ioctl(struct inode * inode, struct file *filp, u_int cmd, u_long arg)
-{
-	struct apm_user *as = filp->private_data;
-	unsigned long flags;
-	int err = -EINVAL;
-
-	if (!as->suser || !as->writer)
-		return -EPERM;
-
-	switch (cmd) {
-	case APM_IOC_SUSPEND:
-		mutex_lock(&state_lock);
-
-		as->suspend_result = -EINTR;
-
-		if (as->suspend_state == SUSPEND_READ) {
-			int pending;
-
-			/*
-			 * If we read a suspend command from /dev/apm_bios,
-			 * then the corresponding APM_IOC_SUSPEND ioctl is
-			 * interpreted as an acknowledge.
-			 */
-			as->suspend_state = SUSPEND_ACKED;
-			suspends_pending--;
-			pending = suspends_pending == 0;
-			mutex_unlock(&state_lock);
-
-			/*
-			 * If there are no further acknowledges required,
-			 * suspend the system.
-			 */
-			if (pending)
-				apm_suspend();
-
-			/*
-			 * Wait for the suspend/resume to complete.  If there
-			 * are pending acknowledges, we wait here for them.
-			 *
-			 * Note: we need to ensure that the PM subsystem does
-			 * not kick us out of the wait when it suspends the
-			 * threads.
-			 */
-			flags = current->flags;
-			current->flags |= PF_NOFREEZE;
-
-			wait_event(apm_suspend_waitqueue,
-				   as->suspend_state == SUSPEND_DONE);
-		} else {
-			as->suspend_state = SUSPEND_WAIT;
-			mutex_unlock(&state_lock);
-
-			/*
-			 * Otherwise it is a request to suspend the system.
-			 * Queue an event for all readers, and expect an
-			 * acknowledge from all writers who haven't already
-			 * acknowledged.
-			 */
-			err = queue_suspend_event(APM_USER_SUSPEND, as);
-			if (err < 0) {
-				/*
-				 * Avoid taking the lock here - this
-				 * should be fine.
-				 */
-				as->suspend_state = SUSPEND_NONE;
-				break;
-			}
-
-			if (err > 0)
-				apm_suspend();
-
-			/*
-			 * Wait for the suspend/resume to complete.  If there
-			 * are pending acknowledges, we wait here for them.
-			 *
-			 * Note: we need to ensure that the PM subsystem does
-			 * not kick us out of the wait when it suspends the
-			 * threads.
-			 */
-			flags = current->flags;
-			current->flags |= PF_NOFREEZE;
-
-			wait_event_interruptible(apm_suspend_waitqueue,
-					 as->suspend_state == SUSPEND_DONE);
-		}
-
-		current->flags = flags;
-
-		mutex_lock(&state_lock);
-		err = as->suspend_result;
-		as->suspend_state = SUSPEND_NONE;
-		mutex_unlock(&state_lock);
-		break;
-	}
-
-	return err;
-}
-
-static int apm_release(struct inode * inode, struct file * filp)
-{
-	struct apm_user *as = filp->private_data;
-	int pending = 0;
-
-	filp->private_data = NULL;
-
-	down_write(&user_list_lock);
-	list_del(&as->list);
-	up_write(&user_list_lock);
-
-	/*
-	 * We are now unhooked from the chain.  As far as new
-	 * events are concerned, we no longer exist.  However, we
-	 * need to balance suspends_pending, which means the
-	 * possibility of sleeping.
-	 */
-	mutex_lock(&state_lock);
-	if (as->suspend_state != SUSPEND_NONE) {
-		suspends_pending -= 1;
-		pending = suspends_pending == 0;
-	}
-	mutex_unlock(&state_lock);
-	if (pending)
-		apm_suspend();
-
-	kfree(as);
-	return 0;
-}
-
-static int apm_open(struct inode * inode, struct file * filp)
-{
-	struct apm_user *as;
-
-	as = kzalloc(sizeof(*as), GFP_KERNEL);
-	if (as) {
-		/*
-		 * XXX - this is a tiny bit broken, when we consider BSD
-		 * process accounting. If the device is opened by root, we
-		 * instantly flag that we used superuser privs. Who knows,
-		 * we might close the device immediately without doing a
-		 * privileged operation -- cevans
-		 */
-		as->suser = capable(CAP_SYS_ADMIN);
-		as->writer = (filp->f_mode & FMODE_WRITE) == FMODE_WRITE;
-		as->reader = (filp->f_mode & FMODE_READ) == FMODE_READ;
-
-		down_write(&user_list_lock);
-		list_add(&as->list, &apm_user_list);
-		up_write(&user_list_lock);
-
-		filp->private_data = as;
-	}
-
-	return as ? 0 : -ENOMEM;
-}
-
-static struct file_operations apm_bios_fops = {
-	.owner		= THIS_MODULE,
-	.read		= apm_read,
-	.poll		= apm_poll,
-	.ioctl		= apm_ioctl,
-	.open		= apm_open,
-	.release	= apm_release,
-};
-
-static struct miscdevice apm_device = {
-	.minor		= APM_MINOR_DEV,
-	.name		= "apm_bios",
-	.fops		= &apm_bios_fops
-};
-
-
-#ifdef CONFIG_PROC_FS
-/*
- * Arguments, with symbols from linux/apm_bios.h.
- *
- *   0) Linux driver version (this will change if format changes)
- *   1) APM BIOS Version.  Usually 1.0, 1.1 or 1.2.
- *   2) APM flags from APM Installation Check (0x00):
- *	bit 0: APM_16_BIT_SUPPORT
- *	bit 1: APM_32_BIT_SUPPORT
- *	bit 2: APM_IDLE_SLOWS_CLOCK
- *	bit 3: APM_BIOS_DISABLED
- *	bit 4: APM_BIOS_DISENGAGED
- *   3) AC line status
- *	0x00: Off-line
- *	0x01: On-line
- *	0x02: On backup power (BIOS >= 1.1 only)
- *	0xff: Unknown
- *   4) Battery status
- *	0x00: High
- *	0x01: Low
- *	0x02: Critical
- *	0x03: Charging
- *	0x04: Selected battery not present (BIOS >= 1.2 only)
- *	0xff: Unknown
- *   5) Battery flag
- *	bit 0: High
- *	bit 1: Low
- *	bit 2: Critical
- *	bit 3: Charging
- *	bit 7: No system battery
- *	0xff: Unknown
- *   6) Remaining battery life (percentage of charge):
- *	0-100: valid
- *	-1: Unknown
- *   7) Remaining battery life (time units):
- *	Number of remaining minutes or seconds
- *	-1: Unknown
- *   8) min = minutes; sec = seconds
- */
-static int apm_get_info(char *buf, char **start, off_t fpos, int length)
-{
-	struct apm_power_info info;
-	char *units;
-	int ret;
-
-	info.ac_line_status = 0xff;
-	info.battery_status = 0xff;
-	info.battery_flag   = 0xff;
-	info.battery_life   = -1;
-	info.time	    = -1;
-	info.units	    = -1;
-
-	if (apm_get_power_status)
-		apm_get_power_status(&info);
-
-	switch (info.units) {
-	default:	units = "?";	break;
-	case 0: 	units = "min";	break;
-	case 1: 	units = "sec";	break;
-	}
-
-	ret = sprintf(buf, "%s 1.2 0x%02x 0x%02x 0x%02x 0x%02x %d%% %d %s\n",
-		     driver_version, APM_32_BIT_SUPPORT,
-		     info.ac_line_status, info.battery_status,
-		     info.battery_flag, info.battery_life,
-		     info.time, units);
-
- 	return ret;
-}
-#endif
-
-static int kapmd(void *arg)
-{
-	do {
-		apm_event_t event;
-		int ret;
-
-		wait_event_interruptible(kapmd_wait,
-				!queue_empty(&kapmd_queue) || kthread_should_stop());
-
-		if (kthread_should_stop())
-			break;
-
-		spin_lock_irq(&kapmd_queue_lock);
-		event = 0;
-		if (!queue_empty(&kapmd_queue))
-			event = queue_get_event(&kapmd_queue);
-		spin_unlock_irq(&kapmd_queue_lock);
-
-		switch (event) {
-		case 0:
-			break;
-
-		case APM_LOW_BATTERY:
-		case APM_POWER_STATUS_CHANGE:
-			queue_event(event);
-			break;
-
-		case APM_USER_SUSPEND:
-		case APM_SYS_SUSPEND:
-			ret = queue_suspend_event(event, NULL);
-			if (ret < 0) {
-				/*
-				 * We were busy.  Try again in 50ms.
-				 */
-				queue_add_event(&kapmd_queue, event);
-				msleep(50);
-			}
-			if (ret > 0)
-				apm_suspend();
-			break;
-
-		case APM_CRITICAL_SUSPEND:
-			apm_suspend();
-			break;
-		}
-	} while (1);
-
-	return 0;
-}
-
-static int __init apm_init(void)
-{
-	int ret;
-
-	if (apm_disabled) {
-		printk(KERN_NOTICE "apm: disabled on user request.\n");
-		return -ENODEV;
-	}
-
-	kapmd_tsk = kthread_create(kapmd, NULL, "kapmd");
-	if (IS_ERR(kapmd_tsk)) {
-		ret = PTR_ERR(kapmd_tsk);
-		kapmd_tsk = NULL;
-		return ret;
-	}
-	kapmd_tsk->flags |= PF_NOFREEZE;
-	wake_up_process(kapmd_tsk);
-
-#ifdef CONFIG_PROC_FS
-	create_proc_info_entry("apm", 0, NULL, apm_get_info);
-#endif
-
-	ret = misc_register(&apm_device);
-	if (ret != 0) {
-		remove_proc_entry("apm", NULL);
-		kthread_stop(kapmd_tsk);
-	}
-
-	return ret;
-}
-
-static void __exit apm_exit(void)
-{
-	misc_deregister(&apm_device);
-	remove_proc_entry("apm", NULL);
-
-	kthread_stop(kapmd_tsk);
-}
-
-module_init(apm_init);
-module_exit(apm_exit);
-
-MODULE_AUTHOR("Stephen Rothwell");
-MODULE_DESCRIPTION("Advanced Power Management");
-MODULE_LICENSE("GPL");
-
-#ifndef MODULE
-static int __init apm_setup(char *str)
-{
-	while ((str != NULL) && (*str != '\0')) {
-		if (strncmp(str, "off", 3) == 0)
-			apm_disabled = 1;
-		if (strncmp(str, "on", 2) == 0)
-			apm_disabled = 0;
-		str = strchr(str, ',');
-		if (str != NULL)
-			str += strspn(str, ", \t");
-	}
-	return 1;
-}
-
-__setup("apm=", apm_setup);
-#endif
-
-/**
- * apm_queue_event - queue an APM event for kapmd
- * @event: APM event
- *
- * Queue an APM event for kapmd to process and ultimately take the
- * appropriate action.  Only a subset of events are handled:
- *   %APM_LOW_BATTERY
- *   %APM_POWER_STATUS_CHANGE
- *   %APM_USER_SUSPEND
- *   %APM_SYS_SUSPEND
- *   %APM_CRITICAL_SUSPEND
- */
-void apm_queue_event(apm_event_t event)
-{
-	unsigned long flags;
-
-	spin_lock_irqsave(&kapmd_queue_lock, flags);
-	queue_add_event(&kapmd_queue, event);
-	spin_unlock_irqrestore(&kapmd_queue_lock, flags);
-
-	wake_up_interruptible(&kapmd_wait);
-}
-EXPORT_SYMBOL(apm_queue_event);
diff --git a/arch/arm/mach-pxa/corgi_pm.c b/arch/arm/mach-pxa/corgi_pm.c
index 4c3de4008a43..165017de8d0d 100644
--- a/arch/arm/mach-pxa/corgi_pm.c
+++ b/arch/arm/mach-pxa/corgi_pm.c
@@ -16,7 +16,7 @@
 #include <linux/delay.h>
 #include <linux/interrupt.h>
 #include <linux/platform_device.h>
-#include <asm/apm.h>
+#include <asm/apm-emulation.h>
 #include <asm/irq.h>
 #include <asm/mach-types.h>
 #include <asm/hardware.h>
diff --git a/arch/arm/mach-pxa/sharpsl_pm.c b/arch/arm/mach-pxa/sharpsl_pm.c
index db6e8f56a75f..b1d8cfca245a 100644
--- a/arch/arm/mach-pxa/sharpsl_pm.c
+++ b/arch/arm/mach-pxa/sharpsl_pm.c
@@ -23,7 +23,7 @@
 
 #include <asm/hardware.h>
 #include <asm/mach-types.h>
-#include <asm/apm.h>
+#include <asm/apm-emulation.h>
 #include <asm/arch/pm.h>
 #include <asm/arch/pxa-regs.h>
 #include <asm/arch/sharpsl.h>
diff --git a/arch/arm/mach-pxa/spitz_pm.c b/arch/arm/mach-pxa/spitz_pm.c
index 40be833079c7..b97d543d9364 100644
--- a/arch/arm/mach-pxa/spitz_pm.c
+++ b/arch/arm/mach-pxa/spitz_pm.c
@@ -16,7 +16,7 @@
 #include <linux/delay.h>
 #include <linux/interrupt.h>
 #include <linux/platform_device.h>
-#include <asm/apm.h>
+#include <asm/apm-emulation.h>
 #include <asm/irq.h>
 #include <asm/mach-types.h>
 #include <asm/hardware.h>
diff --git a/include/asm-arm/apm.h b/include/asm-arm/apm.h
deleted file mode 100644
index d09113b37e4a..000000000000
--- a/include/asm-arm/apm.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/* -*- linux-c -*-
- *
- * (C) 2003 zecke@handhelds.org
- *
- * GPL version 2
- *
- * based on arch/arm/kernel/apm.c
- * factor out the information needed by architectures to provide
- * apm status
- *
- *
- */
-#ifndef ARM_ASM_SA1100_APM_H
-#define ARM_ASM_SA1100_APM_H
-
-#include <linux/apm_bios.h>
-
-/*
- * This structure gets filled in by the machine specific 'get_power_status'
- * implementation.  Any fields which are not set default to a safe value.
- */
-struct apm_power_info {
-	unsigned char	ac_line_status;
-#define APM_AC_OFFLINE			0
-#define APM_AC_ONLINE			1
-#define APM_AC_BACKUP			2
-#define APM_AC_UNKNOWN			0xff
-
-	unsigned char	battery_status;
-#define APM_BATTERY_STATUS_HIGH		0
-#define APM_BATTERY_STATUS_LOW		1
-#define APM_BATTERY_STATUS_CRITICAL	2
-#define APM_BATTERY_STATUS_CHARGING	3
-#define APM_BATTERY_STATUS_NOT_PRESENT	4
-#define APM_BATTERY_STATUS_UNKNOWN	0xff
-
-	unsigned char	battery_flag;
-#define APM_BATTERY_FLAG_HIGH		(1 << 0)
-#define APM_BATTERY_FLAG_LOW		(1 << 1)
-#define APM_BATTERY_FLAG_CRITICAL	(1 << 2)
-#define APM_BATTERY_FLAG_CHARGING	(1 << 3)
-#define APM_BATTERY_FLAG_NOT_PRESENT	(1 << 7)
-#define APM_BATTERY_FLAG_UNKNOWN	0xff
-
-	int		battery_life;
-	int		time;
-	int		units;
-#define APM_UNITS_MINS			0
-#define APM_UNITS_SECS			1
-#define APM_UNITS_UNKNOWN		-1
-
-};
-
-/*
- * This allows machines to provide their own "apm get power status" function.
- */
-extern void (*apm_get_power_status)(struct apm_power_info *);
-
-/*
- * Queue an event (APM_SYS_SUSPEND or APM_CRITICAL_SUSPEND)
- */
-void apm_queue_event(apm_event_t event);
-
-#endif
-- 
cgit v1.2.3


From 4ec031166f6a466a443f462e567f7551096b1741 Mon Sep 17 00:00:00 2001
From: Al Viro <viro@ftp.linux.org.uk>
Date: Fri, 9 Feb 2007 16:38:30 +0000
Subject: [PATCH] kill eth_io_copy_and_sum()

On all targets that sucker boils down to memcpy_fromio(sbk->data, from, len).
The function name is highly misguiding (it _never_ does any checksums), the
last argument is just a noise and simply expanding the call to memcpy_fromio()
gives shorter and more readable source.  For a lot of reasons it has almost
no remaining users, so it's better to just outright kill it.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
---
 drivers/net/3c503.c              | 3 +--
 drivers/net/ac3200.c             | 3 +--
 drivers/net/e2100.c              | 3 +--
 drivers/net/es3210.c             | 2 +-
 drivers/net/smc-mca.c            | 3 +--
 drivers/net/smc-ultra.c          | 3 +--
 drivers/net/smc-ultra32.c        | 3 +--
 drivers/net/wd.c                 | 2 +-
 include/asm-alpha/io.h           | 9 ---------
 include/asm-arm/arch-ixp4xx/io.h | 3 ---
 include/asm-arm/io.h             | 5 -----
 include/asm-cris/io.h            | 5 -----
 include/asm-i386/io.h            | 6 ------
 include/asm-mips/io.h            | 6 ------
 include/asm-parisc/io.h          | 9 ---------
 include/asm-ppc/io.h             | 2 --
 include/asm-x86_64/io.h          | 6 ------
 17 files changed, 8 insertions(+), 65 deletions(-)

(limited to 'include/asm-arm')

diff --git a/drivers/net/3c503.c b/drivers/net/3c503.c
index 7e34c4f07b70..bc7e906571d3 100644
--- a/drivers/net/3c503.c
+++ b/drivers/net/3c503.c
@@ -600,8 +600,7 @@ el2_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring
 	    count -= semi_count;
 	    memcpy_fromio(skb->data + semi_count, base + ei_status.priv, count);
 	} else {
-		/* Packet is in one chunk -- we can copy + cksum. */
-		eth_io_copy_and_sum(skb, base + ring_offset, count, 0);
+		memcpy_fromio(skb->data, base + ring_offset, count);
 	}
 	return;
     }
diff --git a/drivers/net/ac3200.c b/drivers/net/ac3200.c
index c01f87f5bed7..644c408515df 100644
--- a/drivers/net/ac3200.c
+++ b/drivers/net/ac3200.c
@@ -327,8 +327,7 @@ static void ac_block_input(struct net_device *dev, int count, struct sk_buff *sk
 		memcpy_fromio(skb->data + semi_count,
 				ei_status.mem + TX_PAGES*256, count);
 	} else {
-		/* Packet is in one chunk -- we can copy + cksum. */
-		eth_io_copy_and_sum(skb, start, count, 0);
+		memcpy_fromio(skb->data, start, count);
 	}
 }
 
diff --git a/drivers/net/e2100.c b/drivers/net/e2100.c
index c62d9c6363c6..b2b0a96218ca 100644
--- a/drivers/net/e2100.c
+++ b/drivers/net/e2100.c
@@ -355,8 +355,7 @@ e21_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring
 
 	mem_on(ioaddr, shared_mem, (ring_offset>>8));
 
-	/* Packet is always in one chunk -- we can copy + cksum. */
-	eth_io_copy_and_sum(skb, ei_status.mem + (ring_offset & 0xff), count, 0);
+	memcpy_fromio(skb->data, ei_status.mem + (ring_offset & 0xff), count);
 
 	mem_off(ioaddr);
 }
diff --git a/drivers/net/es3210.c b/drivers/net/es3210.c
index 2d2ea94a00bb..822e5bfd1a71 100644
--- a/drivers/net/es3210.c
+++ b/drivers/net/es3210.c
@@ -375,7 +375,7 @@ static void es_block_input(struct net_device *dev, int count, struct sk_buff *sk
 		memcpy_fromio(skb->data + semi_count, ei_status.mem, count);
 	} else {
 		/* Packet is in one chunk. */
-		eth_io_copy_and_sum(skb, xfer_start, count, 0);
+		memcpy_fromio(skb->data, xfer_start, count);
 	}
 }
 
diff --git a/drivers/net/smc-mca.c b/drivers/net/smc-mca.c
index 7122932eac90..ae1ae343beed 100644
--- a/drivers/net/smc-mca.c
+++ b/drivers/net/smc-mca.c
@@ -482,8 +482,7 @@ static void ultramca_block_input(struct net_device *dev, int count, struct sk_bu
 		count -= semi_count;
 		memcpy_fromio(skb->data + semi_count, ei_status.mem + TX_PAGES * 256, count);
 	} else {
-		/* Packet is in one chunk -- we can copy + cksum. */
-		eth_io_copy_and_sum(skb, xfer_start, count, 0);
+		memcpy_fromio(skb->data, xfer_start, count);
 	}
 
 }
diff --git a/drivers/net/smc-ultra.c b/drivers/net/smc-ultra.c
index d70bc9795346..a52b22d7db65 100644
--- a/drivers/net/smc-ultra.c
+++ b/drivers/net/smc-ultra.c
@@ -454,8 +454,7 @@ ultra_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ri
 		count -= semi_count;
 		memcpy_fromio(skb->data + semi_count, ei_status.mem + TX_PAGES * 256, count);
 	} else {
-		/* Packet is in one chunk -- we can copy + cksum. */
-		eth_io_copy_and_sum(skb, xfer_start, count, 0);
+		memcpy_fromio(skb->data, xfer_start, count);
 	}
 
 	outb(0x00, dev->base_addr - ULTRA_NIC_OFFSET);	/* Disable memory. */
diff --git a/drivers/net/smc-ultra32.c b/drivers/net/smc-ultra32.c
index 2c5319c62fa5..88a30e56c64c 100644
--- a/drivers/net/smc-ultra32.c
+++ b/drivers/net/smc-ultra32.c
@@ -395,8 +395,7 @@ static void ultra32_block_input(struct net_device *dev,
 			memcpy_fromio(skb->data + semi_count, ei_status.mem + TX_PAGES * 256, count);
 		}
 	} else {
-		/* Packet is in one chunk -- we can copy + cksum. */
-		eth_io_copy_and_sum(skb, xfer_start, count, 0);
+		memcpy_fromio(skb->data, xfer_start, count);
 	}
 }
 
diff --git a/drivers/net/wd.c b/drivers/net/wd.c
index 7f38012b9c92..a0326818ff2f 100644
--- a/drivers/net/wd.c
+++ b/drivers/net/wd.c
@@ -433,7 +433,7 @@ wd_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_
 		memcpy_fromio(skb->data + semi_count, ei_status.mem + TX_PAGES * 256, count);
 	} else {
 		/* Packet is in one chunk -- we can copy + cksum. */
-		eth_io_copy_and_sum(skb, xfer_start, count, 0);
+		memcpy_fromio(skb->data, xfer_start, count);
 	}
 
 	/* Turn off 16 bit access so that reboot works.	 ISA brain-damage */
diff --git a/include/asm-alpha/io.h b/include/asm-alpha/io.h
index 5d15af24573b..24bdcc8b63aa 100644
--- a/include/asm-alpha/io.h
+++ b/include/asm-alpha/io.h
@@ -524,15 +524,6 @@ extern void outsb (unsigned long port, const void *src, unsigned long count);
 extern void outsw (unsigned long port, const void *src, unsigned long count);
 extern void outsl (unsigned long port, const void *src, unsigned long count);
 
-/*
- * XXX - We don't have csum_partial_copy_fromio() yet, so we cheat here and 
- * just copy it. The net code will then do the checksum later. Presently 
- * only used by some shared memory 8390 Ethernet cards anyway.
- */
-
-#define eth_io_copy_and_sum(skb,src,len,unused) \
-  memcpy_fromio((skb)->data,src,len)
-
 /*
  * The Alpha Jensen hardware for some rather strange reason puts
  * the RTC clock at 0x170 instead of 0x70. Probably due to some
diff --git a/include/asm-arm/arch-ixp4xx/io.h b/include/asm-arm/arch-ixp4xx/io.h
index 0d517267fb63..b7b5414d9320 100644
--- a/include/asm-arm/arch-ixp4xx/io.h
+++ b/include/asm-arm/arch-ixp4xx/io.h
@@ -238,9 +238,6 @@ __ixp4xx_readsl(const volatile void __iomem *bus_addr, u32 *vaddr, u32 count)
 #define memcpy_fromio(a,c,l)		_memcpy_fromio((a),(c),(l))
 #define memcpy_toio(c,a,l)		_memcpy_toio((c),(a),(l))
 
-#define eth_io_copy_and_sum(s,c,l,b) \
-				eth_copy_and_sum((s),__mem_pci(c),(l),(b))
-
 static inline int
 check_signature(const unsigned char __iomem *bus_addr, const unsigned char *signature,
 		int length)
diff --git a/include/asm-arm/io.h b/include/asm-arm/io.h
index 288f76b166d0..5f60b4220906 100644
--- a/include/asm-arm/io.h
+++ b/include/asm-arm/io.h
@@ -182,9 +182,6 @@ extern void _memset_io(volatile void __iomem *, int, size_t);
 #define memcpy_fromio(a,c,l)	_memcpy_fromio((a),__mem_pci(c),(l))
 #define memcpy_toio(c,a,l)	_memcpy_toio(__mem_pci(c),(a),(l))
 
-#define eth_io_copy_and_sum(s,c,l,b) \
-				eth_copy_and_sum((s),__mem_pci(c),(l),(b))
-
 #elif !defined(readb)
 
 #define readb(c)			(__readwrite_bug("readb"),0)
@@ -194,8 +191,6 @@ extern void _memset_io(volatile void __iomem *, int, size_t);
 #define writew(v,c)			__readwrite_bug("writew")
 #define writel(v,c)			__readwrite_bug("writel")
 
-#define eth_io_copy_and_sum(s,c,l,b)	__readwrite_bug("eth_io_copy_and_sum")
-
 #define check_signature(io,sig,len)	(0)
 
 #endif	/* __mem_pci */
diff --git a/include/asm-cris/io.h b/include/asm-cris/io.h
index 716c69bc58f8..d196dd6b2df3 100644
--- a/include/asm-cris/io.h
+++ b/include/asm-cris/io.h
@@ -121,11 +121,6 @@ static inline void writel(unsigned int b, volatile void __iomem *addr)
 #define memcpy_fromio(a,b,c)	memcpy((a),(void *)(b),(c))
 #define memcpy_toio(a,b,c)	memcpy((void *)(a),(b),(c))
 
-/*
- * Again, CRIS does not require mem IO specific function.
- */
-
-#define eth_io_copy_and_sum(a,b,c,d)	eth_copy_and_sum((a),(void __force *)(b),(c),(d))
 
 /* The following is junk needed for the arch-independent code but which
  * we never use in the CRIS port
diff --git a/include/asm-i386/io.h b/include/asm-i386/io.h
index 86ff5e83be2f..59fe616933c4 100644
--- a/include/asm-i386/io.h
+++ b/include/asm-i386/io.h
@@ -218,12 +218,6 @@ static inline void memcpy_toio(volatile void __iomem *dst, const void *src, int
  */
 #define __ISA_IO_base ((char __iomem *)(PAGE_OFFSET))
 
-/*
- * Again, i386 does not require mem IO specific function.
- */
-
-#define eth_io_copy_and_sum(a,b,c,d)		eth_copy_and_sum((a),(void __force *)(b),(c),(d))
-
 /*
  *	Cache management
  *
diff --git a/include/asm-mips/io.h b/include/asm-mips/io.h
index 67f081078904..b6a2eb816628 100644
--- a/include/asm-mips/io.h
+++ b/include/asm-mips/io.h
@@ -555,12 +555,6 @@ extern void pci_iounmap(struct pci_dev *dev, void __iomem *);
  */
 #define __ISA_IO_base ((char *)(isa_slot_offset))
 
-/*
- * We don't have csum_partial_copy_fromio() yet, so we cheat here and
- * just copy it. The net code will then do the checksum later.
- */
-#define eth_io_copy_and_sum(skb,src,len,unused) memcpy_fromio((skb)->data,(src),(len))
-
 /*
  * The caches on some architectures aren't dma-coherent and have need to
  * handle this in software.  There are three types of operations that
diff --git a/include/asm-parisc/io.h b/include/asm-parisc/io.h
index c1963ce19dd2..ca46e7cc0940 100644
--- a/include/asm-parisc/io.h
+++ b/include/asm-parisc/io.h
@@ -191,15 +191,6 @@ void memset_io(volatile void __iomem *addr, unsigned char val, int count);
 void memcpy_fromio(void *dst, const volatile void __iomem *src, int count);
 void memcpy_toio(volatile void __iomem *dst, const void *src, int count);
 
-/*
- * XXX - We don't have csum_partial_copy_fromio() yet, so we cheat here and 
- * just copy it. The net code will then do the checksum later. Presently 
- * only used by some shared memory 8390 Ethernet cards anyway.
- */
-
-#define eth_io_copy_and_sum(skb,src,len,unused) \
-  memcpy_fromio((skb)->data,(src),(len))
-
 /* Port-space IO */
 
 #define inb_p inb
diff --git a/include/asm-ppc/io.h b/include/asm-ppc/io.h
index ccf1a9bb2e43..95d590423cf2 100644
--- a/include/asm-ppc/io.h
+++ b/include/asm-ppc/io.h
@@ -358,8 +358,6 @@ static inline void memcpy_toio(volatile void __iomem *dst, const void *src, int
 }
 #endif
 
-#define eth_io_copy_and_sum(a,b,c,d)		eth_copy_and_sum((a),(void __force *)(void __iomem *)(b),(c),(d))
-
 /*
  * Map in an area of physical address space, for accessing
  * I/O devices etc.
diff --git a/include/asm-x86_64/io.h b/include/asm-x86_64/io.h
index 6ee9fadaaacb..f5d84bb7c948 100644
--- a/include/asm-x86_64/io.h
+++ b/include/asm-x86_64/io.h
@@ -248,12 +248,6 @@ void memset_io(volatile void __iomem *a, int b, size_t c);
  */
 #define __ISA_IO_base ((char __iomem *)(PAGE_OFFSET))
 
-/*
- * Again, x86-64 does not require mem IO specific function.
- */
-
-#define eth_io_copy_and_sum(a,b,c,d)		eth_copy_and_sum((a),(void *)(b),(c),(d))
-
 /* Nothing to do */
 
 #define dma_cache_inv(_start,_size)		do { } while (0)
-- 
cgit v1.2.3


From 4564f9e5fd00767d11fcf61e0d52787706dfcc87 Mon Sep 17 00:00:00 2001
From: Tilman Schmidt <tilman@imap.cc>
Date: Sat, 10 Feb 2007 01:45:00 -0800
Subject: [PATCH] consolidate line discipline number definitions

The line discipline numbers N_* are currently defined for each architecture
individually, but (except for a seeming mistake) identically, in
asm/termios.h.  There is no obvious reason why these numbers should be
architecture specific, nor any apparent relationship with the termios
structure.  The total number of these, NR_LDISCS, is defined in linux/tty.h
anyway.  So I propose the following patch which moves the definitions of
the individual line disciplines to linux/tty.h too.

Three of these numbers (N_MASC, N_PROFIBUS_FDL, and N_SMSBLOCK) are unused
in the current kernel, but the patch still keeps the complete set in case
there are plans to use them yet.

Signed-off-by: Tilman Schmidt <tilman@imap.cc>
Cc: <linux-arch@vger.kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
---
 arch/sparc/kernel/sunos_ioctl.c     |  1 +
 arch/sparc64/kernel/sunos_ioctl32.c |  1 +
 include/asm-alpha/termios.h         | 18 ------------------
 include/asm-arm/termios.h           | 18 ------------------
 include/asm-arm26/termios.h         | 18 ------------------
 include/asm-avr32/termios.h         | 18 ------------------
 include/asm-cris/termios.h          | 18 ------------------
 include/asm-frv/termios.h           | 18 ------------------
 include/asm-h8300/termios.h         | 18 ------------------
 include/asm-i386/termios.h          | 18 ------------------
 include/asm-ia64/termios.h          | 18 ------------------
 include/asm-m32r/termios.h          | 18 ------------------
 include/asm-m68k/termios.h          | 18 ------------------
 include/asm-mips/termios.h          | 18 ------------------
 include/asm-parisc/termios.h        | 18 ------------------
 include/asm-powerpc/termios.h       | 18 ------------------
 include/asm-s390/termios.h          | 18 ------------------
 include/asm-sh/termios.h            | 18 ------------------
 include/asm-sh64/termios.h          | 18 ------------------
 include/asm-sparc/termios.h         | 18 ------------------
 include/asm-sparc64/termios.h       | 18 ------------------
 include/asm-v850/termios.h          | 18 ------------------
 include/asm-x86_64/termios.h        | 18 ------------------
 include/asm-xtensa/termios.h        | 19 -------------------
 include/linux/tty.h                 | 22 +++++++++++++++++++++-
 25 files changed, 23 insertions(+), 398 deletions(-)

(limited to 'include/asm-arm')

diff --git a/arch/sparc/kernel/sunos_ioctl.c b/arch/sparc/kernel/sunos_ioctl.c
index a6ba3d26222c..32e8274e4357 100644
--- a/arch/sparc/kernel/sunos_ioctl.c
+++ b/arch/sparc/kernel/sunos_ioctl.c
@@ -11,6 +11,7 @@
 #include <linux/errno.h>
 #include <linux/string.h>
 #include <linux/termios.h>
+#include <linux/tty.h>
 #include <linux/ioctl.h>
 #include <linux/route.h>
 #include <linux/sockios.h>
diff --git a/arch/sparc64/kernel/sunos_ioctl32.c b/arch/sparc64/kernel/sunos_ioctl32.c
index 3f619ead22cc..a05e43d51755 100644
--- a/arch/sparc64/kernel/sunos_ioctl32.c
+++ b/arch/sparc64/kernel/sunos_ioctl32.c
@@ -11,6 +11,7 @@
 #include <linux/errno.h>
 #include <linux/string.h>
 #include <linux/termios.h>
+#include <linux/tty.h>
 #include <linux/ioctl.h>
 #include <linux/route.h>
 #include <linux/sockios.h>
diff --git a/include/asm-alpha/termios.h b/include/asm-alpha/termios.h
index 1cfd27f0ad73..39e492c3bfa3 100644
--- a/include/asm-alpha/termios.h
+++ b/include/asm-alpha/termios.h
@@ -66,24 +66,6 @@ struct termio {
 #define _VEOL2	6
 #define _VSWTC	7
 
-/* line disciplines */
-#define N_TTY		0
-#define N_SLIP		1
-#define N_MOUSE		2
-#define N_PPP		3
-#define N_STRIP		4
-#define N_AX25		5
-#define N_X25		6	/* X.25 async */
-#define N_6PACK		7
-#define N_MASC		8	/* Reserved for Mobitex module <kaz@cafe.net> */
-#define N_R3964		9	/* Reserved for Simatic R3964 module */
-#define N_PROFIBUS_FDL	10	/* Reserved for Profibus <Dave@mvhi.com> */
-#define N_IRDA		11	/* Linux IrDa - http://irda.sourceforge.net/ */
-#define N_SMSBLOCK	12	/* SMS block mode - for talking to GSM data cards about SMS messages */
-#define N_HDLC		13	/* synchronous HDLC */
-#define N_SYNC_PPP	14
-#define N_HCI		15  /* Bluetooth HCI UART */
-
 #ifdef __KERNEL__
 /*	eof=^D		eol=\0		eol2=\0		erase=del
 	werase=^W	kill=^U		reprint=^R	sxtc=\0
diff --git a/include/asm-arm/termios.h b/include/asm-arm/termios.h
index 7b8f5e8ae063..329c324c4040 100644
--- a/include/asm-arm/termios.h
+++ b/include/asm-arm/termios.h
@@ -49,24 +49,6 @@ struct termio {
 
 /* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */
 
-/* line disciplines */
-#define N_TTY		0
-#define N_SLIP		1
-#define N_MOUSE		2
-#define N_PPP		3
-#define N_STRIP		4
-#define N_AX25		5
-#define N_X25		6	/* X.25 async */
-#define N_6PACK		7
-#define N_MASC		8	/* Reserved for Mobitex module <kaz@cafe.net> */
-#define N_R3964		9	/* Reserved for Simatic R3964 module */
-#define N_PROFIBUS_FDL	10	/* Reserved for Profibus <Dave@mvhi.com> */
-#define N_IRDA		11	/* Linux IrDa - http://irda.sourceforge.net/ */
-#define N_SMSBLOCK	12	/* SMS block mode - for talking to GSM data cards about SMS messages */
-#define N_HDLC		13	/* synchronous HDLC */
-#define N_SYNC_PPP	14
-#define N_HCI		15  /* Bluetooth HCI UART */
-
 #ifdef __KERNEL__
 
 /*
diff --git a/include/asm-arm26/termios.h b/include/asm-arm26/termios.h
index 7b8f5e8ae063..329c324c4040 100644
--- a/include/asm-arm26/termios.h
+++ b/include/asm-arm26/termios.h
@@ -49,24 +49,6 @@ struct termio {
 
 /* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */
 
-/* line disciplines */
-#define N_TTY		0
-#define N_SLIP		1
-#define N_MOUSE		2
-#define N_PPP		3
-#define N_STRIP		4
-#define N_AX25		5
-#define N_X25		6	/* X.25 async */
-#define N_6PACK		7
-#define N_MASC		8	/* Reserved for Mobitex module <kaz@cafe.net> */
-#define N_R3964		9	/* Reserved for Simatic R3964 module */
-#define N_PROFIBUS_FDL	10	/* Reserved for Profibus <Dave@mvhi.com> */
-#define N_IRDA		11	/* Linux IrDa - http://irda.sourceforge.net/ */
-#define N_SMSBLOCK	12	/* SMS block mode - for talking to GSM data cards about SMS messages */
-#define N_HDLC		13	/* synchronous HDLC */
-#define N_SYNC_PPP	14
-#define N_HCI		15  /* Bluetooth HCI UART */
-
 #ifdef __KERNEL__
 
 /*
diff --git a/include/asm-avr32/termios.h b/include/asm-avr32/termios.h
index 615bc0639e5c..0152aba35154 100644
--- a/include/asm-avr32/termios.h
+++ b/include/asm-avr32/termios.h
@@ -46,24 +46,6 @@ struct termio {
 
 /* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */
 
-/* line disciplines */
-#define N_TTY		0
-#define N_SLIP		1
-#define N_MOUSE		2
-#define N_PPP		3
-#define N_STRIP		4
-#define N_AX25		5
-#define N_X25		6	/* X.25 async */
-#define N_6PACK		7
-#define N_MASC		8	/* Reserved for Mobitex module <kaz@cafe.net> */
-#define N_R3964		9	/* Reserved for Simatic R3964 module */
-#define N_PROFIBUS_FDL	10	/* Reserved for Profibus <Dave@mvhi.com> */
-#define N_IRDA		11	/* Linux IR - http://irda.sourceforge.net/ */
-#define N_SMSBLOCK	12	/* SMS block mode - for talking to GSM data cards about SMS messages */
-#define N_HDLC		13	/* synchronous HDLC */
-#define N_SYNC_PPP	14	/* synchronous PPP */
-#define N_HCI		15  /* Bluetooth HCI UART */
-
 #ifdef __KERNEL__
 /*	intr=^C		quit=^\		erase=del	kill=^U
 	eof=^D		vtime=\0	vmin=\1		sxtc=\0
diff --git a/include/asm-cris/termios.h b/include/asm-cris/termios.h
index 5ce1023c5d7b..c9dbd4d43368 100644
--- a/include/asm-cris/termios.h
+++ b/include/asm-cris/termios.h
@@ -40,24 +40,6 @@ struct termio {
 
 /* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */
 
-/* line disciplines */
-#define N_TTY		0
-#define N_SLIP		1
-#define N_MOUSE		2
-#define N_PPP		3
-#define N_STRIP		4
-#define N_AX25		5
-#define N_X25		6	/* X.25 async */
-#define N_6PACK		7
-#define N_MASC		8	/* Reserved for Mobitex module <kaz@cafe.net> */
-#define N_R3964		9	/* Reserved for Simatic R3964 module */
-#define N_PROFIBUS_FDL	10	/* Reserved for Profibus <Dave@mvhi.com> */
-#define N_IRDA		11	/* Linux IR - http://irda.sourceforge.net/ */
-#define N_SMSBLOCK	12	/* SMS block mode - for talking to GSM data cards about SMS messages */
-#define N_HDLC		13	/* synchronous HDLC */
-#define N_SYNC_PPP	14	/* synchronous PPP */
-#define N_BT		15	/* bluetooth */
-
 #ifdef __KERNEL__
 
 /*	intr=^C		quit=^\		erase=del	kill=^U
diff --git a/include/asm-frv/termios.h b/include/asm-frv/termios.h
index 8840cf95e8dd..a62fb5872375 100644
--- a/include/asm-frv/termios.h
+++ b/include/asm-frv/termios.h
@@ -51,24 +51,6 @@ struct termio {
 
 /* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */
 
-/* line disciplines */
-#define N_TTY		0
-#define N_SLIP		1
-#define N_MOUSE		2
-#define N_PPP		3
-#define N_STRIP		4
-#define N_AX25		5
-#define N_X25		6	/* X.25 async */
-#define N_6PACK		7
-#define N_MASC		8	/* Reserved for Mobitex module <kaz@cafe.net> */
-#define N_R3964		9	/* Reserved for Simatic R3964 module */
-#define N_PROFIBUS_FDL	10	/* Reserved for Profibus <Dave@mvhi.com> */
-#define N_IRDA		11	/* Linux IrDa - http://irda.sourceforge.net/ */
-#define N_SMSBLOCK	12	/* SMS block mode - for talking to GSM data cards about SMS messages */
-#define N_HDLC		13	/* synchronous HDLC */
-#define N_SYNC_PPP	14
-#define N_HCI		15  /* Bluetooth HCI UART */
-
 #ifdef __KERNEL__
 #include <asm-generic/termios.h>
 #endif
diff --git a/include/asm-h8300/termios.h b/include/asm-h8300/termios.h
index e2319f992af2..fb2925d08c49 100644
--- a/include/asm-h8300/termios.h
+++ b/include/asm-h8300/termios.h
@@ -49,24 +49,6 @@ struct termio {
 
 /* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */
 
-/* line disciplines */
-#define N_TTY		0
-#define N_SLIP		1
-#define N_MOUSE		2
-#define N_PPP		3
-#define N_STRIP		4
-#define N_AX25		5
-#define N_X25		6	/* X.25 async */
-#define N_6PACK		7
-#define N_MASC		8	/* Reserved for Mobitex module <kaz@cafe.net> */
-#define N_R3964		9	/* Reserved for Simatic R3964 module */
-#define N_PROFIBUS_FDL	10	/* Reserved for Profibus <Dave@mvhi.com> */
-#define N_IRDA		11	/* Linux IrDa - http://irda.sourceforge.net/ */
-#define N_SMSBLOCK	12	/* SMS block mode - for talking to GSM data cards about SMS messages */
-#define N_HDLC		13	/* synchronous HDLC */
-#define N_SYNC_PPP	14
-#define N_HCI		15  /* Bluetooth HCI UART */
-
 #ifdef __KERNEL__
 
 /*
diff --git a/include/asm-i386/termios.h b/include/asm-i386/termios.h
index 03f548536d6b..7c99678a8f86 100644
--- a/include/asm-i386/termios.h
+++ b/include/asm-i386/termios.h
@@ -39,24 +39,6 @@ struct termio {
 
 /* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */
 
-/* line disciplines */
-#define N_TTY		0
-#define N_SLIP		1
-#define N_MOUSE		2
-#define N_PPP		3
-#define N_STRIP		4
-#define N_AX25		5
-#define N_X25		6	/* X.25 async */
-#define N_6PACK		7
-#define N_MASC		8	/* Reserved for Mobitex module <kaz@cafe.net> */
-#define N_R3964		9	/* Reserved for Simatic R3964 module */
-#define N_PROFIBUS_FDL	10	/* Reserved for Profibus <Dave@mvhi.com> */
-#define N_IRDA		11	/* Linux IR - http://irda.sourceforge.net/ */
-#define N_SMSBLOCK	12	/* SMS block mode - for talking to GSM data cards about SMS messages */
-#define N_HDLC		13	/* synchronous HDLC */
-#define N_SYNC_PPP	14	/* synchronous PPP */
-#define N_HCI		15  /* Bluetooth HCI UART */
-
 #ifdef __KERNEL__
 #include <linux/module.h>
 
diff --git a/include/asm-ia64/termios.h b/include/asm-ia64/termios.h
index 42c95693240c..08750c2d3607 100644
--- a/include/asm-ia64/termios.h
+++ b/include/asm-ia64/termios.h
@@ -46,24 +46,6 @@ struct termio {
 
 /* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */
 
-/* line disciplines */
-#define N_TTY		0
-#define N_SLIP		1
-#define N_MOUSE		2
-#define N_PPP		3
-#define N_STRIP		4
-#define N_AX25		5
-#define N_X25		6	/* X.25 async */
-#define N_6PACK		7
-#define N_MASC		8	/* Reserved for Mobitex module <kaz@cafe.net> */
-#define N_R3964		9	/* Reserved for Simatic R3964 module */
-#define N_PROFIBUS_FDL	10	/* Reserved for Profibus <Dave@mvhi.com> */
-#define N_IRDA		11	/* Linux IR - http://irda.sourceforge.net/ */
-#define N_SMSBLOCK	12	/* SMS block mode - for talking to GSM data cards about SMS msgs */
-#define N_HDLC		13	/* synchronous HDLC */
-#define N_SYNC_PPP	14	/* synchronous PPP */
-#define N_HCI		15  /* Bluetooth HCI UART */
-
 # ifdef __KERNEL__
 
 /*	intr=^C		quit=^\		erase=del	kill=^U
diff --git a/include/asm-m32r/termios.h b/include/asm-m32r/termios.h
index 0b245fdeefbf..4943dd8db44d 100644
--- a/include/asm-m32r/termios.h
+++ b/include/asm-m32r/termios.h
@@ -39,24 +39,6 @@ struct termio {
 
 /* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */
 
-/* line disciplines */
-#define N_TTY		0
-#define N_SLIP		1
-#define N_MOUSE		2
-#define N_PPP		3
-#define N_STRIP		4
-#define N_AX25		5
-#define N_X25		6	/* X.25 async */
-#define N_6PACK		7
-#define N_MASC		8	/* Reserved for Mobitex module <kaz@cafe.net> */
-#define N_R3964		9	/* Reserved for Simatic R3964 module */
-#define N_PROFIBUS_FDL	10	/* Reserved for Profibus <Dave@mvhi.com> */
-#define N_IRDA		11	/* Linux IR - http://irda.sourceforge.net/ */
-#define N_SMSBLOCK	12	/* SMS block mode - for talking to GSM data cards about SMS messages */
-#define N_HDLC		13	/* synchronous HDLC */
-#define N_SYNC_PPP	14	/* synchronous PPP */
-#define N_HCI		15  /* Bluetooth HCI UART */
-
 #ifdef __KERNEL__
 #include <linux/module.h>
 
diff --git a/include/asm-m68k/termios.h b/include/asm-m68k/termios.h
index 857f0c9a9120..00edabd76168 100644
--- a/include/asm-m68k/termios.h
+++ b/include/asm-m68k/termios.h
@@ -49,24 +49,6 @@ struct termio {
 
 /* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */
 
-/* line disciplines */
-#define N_TTY		0
-#define N_SLIP		1
-#define N_MOUSE		2
-#define N_PPP		3
-#define N_STRIP		4
-#define N_AX25		5
-#define N_X25		6	/* X.25 async */
-#define N_6PACK		7
-#define N_MASC		8	/* Reserved for Mobitex module <kaz@cafe.net> */
-#define N_R3964		9	/* Reserved for Simatic R3964 module */
-#define N_PROFIBUS_FDL	10	/* Reserved for Profibus <Dave@mvhi.com> */
-#define N_IRDA		11	/* Linux IrDa - http://irda.sourceforge.net/ */
-#define N_SMSBLOCK	12	/* SMS block mode - for talking to GSM data cards about SMS messages */
-#define N_HDLC		13	/* synchronous HDLC */
-#define N_SYNC_PPP	14
-#define N_HCI		15  /* Bluetooth HCI UART */
-
 #ifdef __KERNEL__
 
 /*
diff --git a/include/asm-mips/termios.h b/include/asm-mips/termios.h
index 4906204d34fe..2ce07f4be369 100644
--- a/include/asm-mips/termios.h
+++ b/include/asm-mips/termios.h
@@ -87,24 +87,6 @@ struct termio {
 #define TIOCM_OUT2	0x4000
 #define TIOCM_LOOP	0x8000
 
-/* line disciplines */
-#define N_TTY		0
-#define N_SLIP		1
-#define N_MOUSE		2
-#define N_PPP		3
-#define N_STRIP		4
-#define N_AX25		5
-#define N_X25		6		/* X.25 async */
-#define N_6PACK		7
-#define N_MASC		8	/* Reserved fo Mobitex module <kaz@cafe.net> */
-#define N_R3964		9	/* Reserved for Simatic R3964 module */
-#define N_PROFIBUS_FDL	10	/* Reserved for Profibus <Dave@mvhi.com> */
-#define N_IRDA		11	/* Linux IrDa - http://irda.sourceforge.net/ */
-#define N_SMSBLOCK	12	/* SMS block mode - for talking to GSM data cards about SMS messages */
-#define N_HDLC		13	/* synchronous HDLC */
-#define N_SYNC_PPP	14	/* synchronous PPP */
-#define N_HCI		15	/* Bluetooth HCI UART */
-
 #ifdef __KERNEL__
 
 #include <linux/string.h>
diff --git a/include/asm-parisc/termios.h b/include/asm-parisc/termios.h
index 6965e8f6c3e1..5345b3420475 100644
--- a/include/asm-parisc/termios.h
+++ b/include/asm-parisc/termios.h
@@ -39,24 +39,6 @@ struct termio {
 
 /* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */
 
-/* line disciplines */
-#define N_TTY		0
-#define N_SLIP		1
-#define N_MOUSE		2
-#define N_PPP		3
-#define N_STRIP		4
-#define N_AX25		5
-#define N_X25		6	/* X.25 async */
-#define N_6PACK		7
-#define N_MASC		8	/* Reserved for Mobitex module <kaz@cafe.net> */
-#define N_R3964		9	/* Reserved for Simatic R3964 module */
-#define N_PROFIBUS_FDL	10	/* Reserved for Profibus <Dave@mvhi.com> */
-#define N_IRDA		11	/* Linux IR - http://irda.sourceforge.net/ */
-#define N_SMSBLOCK	12	/* SMS block mode - for talking to GSM data cards about SMS messages */
-#define N_HDLC		13	/* synchronous HDLC */
-#define N_SYNC_PPP	14
-#define N_HCI		15  /* Bluetooth HCI UART */
-
 #ifdef __KERNEL__
 
 /*	intr=^C		quit=^\		erase=del	kill=^U
diff --git a/include/asm-powerpc/termios.h b/include/asm-powerpc/termios.h
index 7f80a019b6a0..2c14fea07c8a 100644
--- a/include/asm-powerpc/termios.h
+++ b/include/asm-powerpc/termios.h
@@ -71,24 +71,6 @@ struct termio {
 #define _VEOL2	8
 #define _VSWTC	9
 
-/* line disciplines */
-#define N_TTY		0
-#define N_SLIP		1
-#define N_MOUSE		2
-#define N_PPP		3
-#define N_STRIP		4
-#define N_AX25		5
-#define N_X25		6	/* X.25 async */
-#define N_6PACK		7
-#define N_MASC		8	/* Reserved for Mobitex module <kaz@cafe.net> */
-#define N_R3964		9	/* Reserved for Simatic R3964 module */
-#define N_PROFIBUS_FDL	10	/* Reserved for Profibus <Dave@mvhi.com> */
-#define N_IRDA		11	/* Linux IrDa - http://www.cs.uit.no/~dagb/irda/irda.html */
-#define N_SMSBLOCK	12	/* SMS block mode - for talking to GSM data cards about SMS messages */
-#define N_HDLC		13	/* synchronous HDLC */
-#define N_SYNC_PPP	14
-#define N_HCI		15  /* Bluetooth HCI UART */
-
 #ifdef __KERNEL__
 /*                   ^C  ^\ del  ^U  ^D   1   0   0   0   0  ^W  ^R  ^Z  ^Q  ^S  ^V  ^U  */
 #define INIT_C_CC "\003\034\177\025\004\001\000\000\000\000\027\022\032\021\023\026\025" 
diff --git a/include/asm-s390/termios.h b/include/asm-s390/termios.h
index 62b23caf370e..a3480e25eb4b 100644
--- a/include/asm-s390/termios.h
+++ b/include/asm-s390/termios.h
@@ -47,24 +47,6 @@ struct termio {
 
 /* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */
 
-/* line disciplines */
-#define N_TTY		0
-#define N_SLIP		1
-#define N_MOUSE		2
-#define N_PPP		3
-#define N_STRIP		4
-#define N_AX25		5
-#define N_X25		6	/* X.25 async */
-#define N_6PACK		7
-#define N_MASC		8	/* Reserved for Mobitex module <kaz@cafe.net> */
-#define N_R3964		9	/* Reserved for Simatic R3964 module */
-#define N_PROFIBUS_FDL	10	/* Reserved for Profibus <Dave@mvhi.com> */
-#define N_IRDA		11	/* Linux IR - http://irda.sourceforge.net/ */
-#define N_SMSBLOCK	12	/* SMS block mode - for talking to GSM data cards about SMS messages */
-#define N_HDLC		13	/* synchronous HDLC */
-#define N_SYNC_PPP	14	/* synchronous PPP */
-#define N_HCI		15  /* Bluetooth HCI UART */
-
 #ifdef __KERNEL__
 
 /*	intr=^C		quit=^\		erase=del	kill=^U
diff --git a/include/asm-sh/termios.h b/include/asm-sh/termios.h
index 44edfd471443..e7c8f86ef890 100644
--- a/include/asm-sh/termios.h
+++ b/include/asm-sh/termios.h
@@ -39,24 +39,6 @@ struct termio {
 
 /* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */
 
-/* line disciplines */
-#define N_TTY		0
-#define N_SLIP		1
-#define N_MOUSE		2
-#define N_PPP		3
-#define N_STRIP		4
-#define N_AX25		5
-#define N_X25		6	/* X.25 async */
-#define N_6PACK		7
-#define N_MASC		8	/* Reserved for Mobitex module <kaz@cafe.net> */
-#define N_R3964		9	/* Reserved for Simatic R3964 module */
-#define N_PROFIBUS_FDL	10	/* Reserved for Profibus <Dave@mvhi.com> */
-#define N_IRDA		11	/* Linux IR - http://irda.sourceforge.net/ */
-#define N_SMSBLOCK	12	/* SMS block mode - for talking to GSM data cards about SMS messages */
-#define N_HDLC		13	/* synchronous HDLC */
-#define N_SYNC_PPP	14
-#define N_HCI		15  /* Bluetooth HCI UART */
-
 #ifdef __KERNEL__
 
 /*	intr=^C		quit=^\		erase=del	kill=^U
diff --git a/include/asm-sh64/termios.h b/include/asm-sh64/termios.h
index 4a9c7fb411bc..dc44e6ed3a7c 100644
--- a/include/asm-sh64/termios.h
+++ b/include/asm-sh64/termios.h
@@ -50,24 +50,6 @@ struct termio {
 
 /* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */
 
-/* line disciplines */
-#define N_TTY		0
-#define N_SLIP		1
-#define N_MOUSE		2
-#define N_PPP		3
-#define N_STRIP		4
-#define N_AX25		5
-#define N_X25		6	/* X.25 async */
-#define N_6PACK		7
-#define N_MASC		8	/* Reserved for Mobitex module <kaz@cafe.net> */
-#define N_R3964		9	/* Reserved for Simatic R3964 module */
-#define N_PROFIBUS_FDL	10	/* Reserved for Profibus <Dave@mvhi.com> */
-#define N_IRDA		11	/* Linux IR - http://www.cs.uit.no/~dagb/irda/irda.html */
-#define N_SMSBLOCK	12	/* SMS block mode - for talking to GSM data cards about SMS messages */
-#define N_HDLC		13	/* synchronous HDLC */
-#define N_SYNC_PPP	14
-#define N_HCI		15	/* Bluetooth HCI UART */
-
 #ifdef __KERNEL__
 
 /*	intr=^C		quit=^\		erase=del	kill=^U
diff --git a/include/asm-sparc/termios.h b/include/asm-sparc/termios.h
index d05f83c80989..d767f206ab33 100644
--- a/include/asm-sparc/termios.h
+++ b/include/asm-sparc/termios.h
@@ -45,24 +45,6 @@ struct winsize {
 	unsigned short ws_ypixel;
 };
 
-/* line disciplines */
-#define N_TTY		0
-#define N_SLIP		1
-#define N_MOUSE		2
-#define N_PPP		3
-#define N_STRIP		4
-#define N_AX25		5
-#define N_X25		6
-#define N_6PACK		7
-#define N_MASC		8	/* Reserved for Mobitex module <kaz@cafe.net> */
-#define N_R3964		9	/* Reserved for Simatic R3964 module */
-#define N_PROFIBUS_FDL	10	/* Reserved for Profibus <Dave@mvhi.com> */
-#define N_IRDA		11	/* Linux IrDa - http://irda.sourceforge.net/ */
-#define N_SMSBLOCK	12	/* SMS block mode - for talking to GSM data cards about SMS messages */
-#define N_HDLC		13	/* synchronous HDLC */
-#define N_SYNC_PPP	14	/* synchronous PPP */
-#define N_HCI		15  /* Bluetooth HCI UART */
-
 #ifdef __KERNEL__
 #include <linux/module.h>
 
diff --git a/include/asm-sparc64/termios.h b/include/asm-sparc64/termios.h
index ee26a071c677..f05d390993d5 100644
--- a/include/asm-sparc64/termios.h
+++ b/include/asm-sparc64/termios.h
@@ -45,24 +45,6 @@ struct winsize {
 	unsigned short ws_ypixel;
 };
 
-/* line disciplines */
-#define N_TTY		0
-#define N_SLIP		1
-#define N_MOUSE		2
-#define N_PPP		3
-#define N_STRIP		4
-#define N_AX25		5
-#define N_X25		6
-#define N_6PACK		7
-#define N_MASC		8	/* Reserved for Mobitex module <kaz@cafe.net> */
-#define N_R3964		9	/* Reserved for Simatic R3964 module */
-#define N_PROFIBUS_FDL	10	/* Reserved for Profibus <Dave@mvhi.com> */
-#define N_IRDA		11	/* Linux IrDa - http://irda.sourceforge.net/ */
-#define N_SMSBLOCK	12	/* SMS block mode - for talking to GSM data cards about SMS messages */
-#define N_HDLC		13	/* synchronous HDLC */
-#define N_SYNC_PPP	14	/* synchronous PPP */
-#define N_HCI		15  /* Bluetooth HCI UART */
-
 #ifdef __KERNEL__
 #include <linux/module.h>
 
diff --git a/include/asm-v850/termios.h b/include/asm-v850/termios.h
index 79e97b59806e..c2c2b1d58776 100644
--- a/include/asm-v850/termios.h
+++ b/include/asm-v850/termios.h
@@ -39,24 +39,6 @@ struct termio {
 
 /* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */
 
-/* line disciplines */
-#define N_TTY		0
-#define N_SLIP		1
-#define N_MOUSE		2
-#define N_PPP		3
-#define N_STRIP		4
-#define N_AX25		5
-#define N_X25		6	/* X.25 async */
-#define N_6PACK		7
-#define N_MASC		8	/* Reserved for Mobitex module <kaz@cafe.net> */
-#define N_R3964		9	/* Reserved for Simatic R3964 module */
-#define N_PROFIBUS_FDL	10	/* Reserved for Profibus <Dave@mvhi.com> */
-#define N_IRDA		11	/* Linux IR - http://irda.sourceforge.net/ */
-#define N_SMSBLOCK	12	/* SMS block mode - for talking to GSM data cards about SMS messages */
-#define N_HDLC		13	/* synchronous HDLC */
-#define N_SYNC_PPP	14	/* synchronous PPP */
-#define N_HCI		15  /* Bluetooth HCI UART */
-
 #ifdef __KERNEL__
 
 /*	intr=^C		quit=^\		erase=del	kill=^U
diff --git a/include/asm-x86_64/termios.h b/include/asm-x86_64/termios.h
index 443b225537f0..35ee59b78329 100644
--- a/include/asm-x86_64/termios.h
+++ b/include/asm-x86_64/termios.h
@@ -39,24 +39,6 @@ struct termio {
 
 /* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */
 
-/* line disciplines */
-#define N_TTY		0
-#define N_SLIP		1
-#define N_MOUSE		2
-#define N_PPP		3
-#define N_STRIP		4
-#define N_AX25		5
-#define N_X25		6	/* X.25 async */
-#define N_6PACK		7
-#define N_MASC		8	/* Reserved for Mobitex module <kaz@cafe.net> */
-#define N_R3964		9	/* Reserved for Simatic R3964 module */
-#define N_PROFIBUS_FDL	10	/* Reserved for Profibus <Dave@mvhi.com> */
-#define N_IRDA		11	/* Linux IR - http://irda.sourceforge.net/ */
-#define N_SMSBLOCK	12	/* SMS block mode - for talking to GSM data cards about SMS messages */
-#define N_HDLC		13	/* synchronous HDLC */
-#define N_SYNC_PPP	14	/* synchronous PPP */
-#define N_HCI		15  /* Bluetooth HCI UART */
-
 #ifdef __KERNEL__
 
 /*	intr=^C		quit=^\		erase=del	kill=^U
diff --git a/include/asm-xtensa/termios.h b/include/asm-xtensa/termios.h
index 83c6aed1d115..f14b42c8dac0 100644
--- a/include/asm-xtensa/termios.h
+++ b/include/asm-xtensa/termios.h
@@ -52,25 +52,6 @@ struct termio {
 
 /* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */
 
-/* Line disciplines */
-
-#define N_TTY		0
-#define N_SLIP		1
-#define N_MOUSE		2
-#define N_PPP		3
-#define N_STRIP		4
-#define N_AX25		5
-#define N_X25		6	/* X.25 async */
-#define N_6PACK		7
-#define N_MASC		8	/* Reserved for Mobitex module <kaz@cafe.net> */
-#define N_R3964		9	/* Reserved for Simatic R3964 module */
-#define N_PROFIBUS_FDL	10	/* Reserved for Profibus <Dave@mvhi.com> */
-#define N_IRDA		11	/* Linux IR - http://irda.sourceforge.net/ */
-#define N_SMSBLOCK	12	/* SMS block mode - for talking to GSM data cards about SMS messages */
-#define N_HDLC		13	/* synchronous HDLC */
-#define N_SYNC_PPP	14
-#define N_HCI		15      /* Bluetooth HCI UART */
-
 #ifdef __KERNEL__
 
 /*	intr=^C		quit=^\		erase=del	kill=^U
diff --git a/include/linux/tty.h b/include/linux/tty.h
index 0161a8c6dbf6..8427c9e98e6b 100644
--- a/include/linux/tty.h
+++ b/include/linux/tty.h
@@ -24,7 +24,27 @@
 #define NR_PTYS	CONFIG_LEGACY_PTY_COUNT   /* Number of legacy ptys */
 #define NR_UNIX98_PTY_DEFAULT	4096      /* Default maximum for Unix98 ptys */
 #define NR_UNIX98_PTY_MAX	(1 << MINORBITS) /* Absolute limit */
-#define NR_LDISCS		16
+#define NR_LDISCS		17
+
+/* line disciplines */
+#define N_TTY		0
+#define N_SLIP		1
+#define N_MOUSE		2
+#define N_PPP		3
+#define N_STRIP		4
+#define N_AX25		5
+#define N_X25		6	/* X.25 async */
+#define N_6PACK		7
+#define N_MASC		8	/* Reserved for Mobitex module <kaz@cafe.net> */
+#define N_R3964		9	/* Reserved for Simatic R3964 module */
+#define N_PROFIBUS_FDL	10	/* Reserved for Profibus <Dave@mvhi.com> */
+#define N_IRDA		11	/* Linux IrDa - http://irda.sourceforge.net/ */
+#define N_SMSBLOCK	12	/* SMS block mode - for talking to GSM data */
+				/* cards about SMS messages */
+#define N_HDLC		13	/* synchronous HDLC */
+#define N_SYNC_PPP	14	/* synchronous PPP */
+#define N_HCI		15	/* Bluetooth HCI UART */
+#define N_GIGASET_M101	16	/* Siemens Gigaset M101 serial DECT adapter */
 
 /*
  * This character is the same as _POSIX_VDISABLE: it cannot be used as
-- 
cgit v1.2.3


From 16cf5b39b81b95d1e3d81df3ba8c82cadf54f551 Mon Sep 17 00:00:00 2001
From: Tilman Schmidt <tilman@imap.cc>
Date: Sat, 10 Feb 2007 01:45:41 -0800
Subject: [PATCH] fix sparse warnings from {asm,net}/checksum.h

Rename the variable "sum" in the __range_ok macros to avoid name collisions
causing lots of "symbol shadows an earlier one" warnings by sparse.

Signed-off-by: Tilman Schmidt <tilman@imap.cc>
Cc: Russell King <rmk@arm.linux.org.uk>
Cc: Andi Kleen <ak@suse.de>
Cc: Hirokazu Takata <takata@linux-m32r.org>
Acked-by: Ian Molton <spyro@f2s.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
---
 include/asm-arm/uaccess.h       | 4 ++--
 include/asm-arm26/uaccess-asm.h | 4 ++--
 include/asm-i386/uaccess.h      | 4 ++--
 include/asm-m32r/uaccess.h      | 4 ++--
 include/asm-x86_64/uaccess.h    | 4 ++--
 5 files changed, 10 insertions(+), 10 deletions(-)

(limited to 'include/asm-arm')

diff --git a/include/asm-arm/uaccess.h b/include/asm-arm/uaccess.h
index 5f420a0149f1..c92df958802e 100644
--- a/include/asm-arm/uaccess.h
+++ b/include/asm-arm/uaccess.h
@@ -76,10 +76,10 @@ static inline void set_fs(mm_segment_t fs)
 
 /* We use 33-bit arithmetic here... */
 #define __range_ok(addr,size) ({ \
-	unsigned long flag, sum; \
+	unsigned long flag, roksum; \
 	__chk_user_ptr(addr);	\
 	__asm__("adds %1, %2, %3; sbcccs %1, %1, %0; movcc %0, #0" \
-		: "=&r" (flag), "=&r" (sum) \
+		: "=&r" (flag), "=&r" (roksum) \
 		: "r" (addr), "Ir" (size), "0" (current_thread_info()->addr_limit) \
 		: "cc"); \
 	flag; })
diff --git a/include/asm-arm26/uaccess-asm.h b/include/asm-arm26/uaccess-asm.h
index 19f798e338c9..ade76ec02995 100644
--- a/include/asm-arm26/uaccess-asm.h
+++ b/include/asm-arm26/uaccess-asm.h
@@ -34,9 +34,9 @@ static inline void set_fs (mm_segment_t fs)
 }
 
 #define __range_ok(addr,size) ({					\
-	unsigned long flag, sum;					\
+	unsigned long flag, roksum;					\
 	__asm__ __volatile__("subs %1, %0, %3; cmpcs %1, %2; movcs %0, #0" \
-		: "=&r" (flag), "=&r" (sum)				\
+		: "=&r" (flag), "=&r" (roksum)				\
 		: "r" (addr), "Ir" (size), "0" (current_thread_info()->addr_limit)	\
 		: "cc");						\
 	flag; })
diff --git a/include/asm-i386/uaccess.h b/include/asm-i386/uaccess.h
index eef5133b9ce2..70829ae3ad52 100644
--- a/include/asm-i386/uaccess.h
+++ b/include/asm-i386/uaccess.h
@@ -54,10 +54,10 @@ extern struct movsl_mask {
  * This needs 33-bit arithmetic. We have a carry...
  */
 #define __range_ok(addr,size) ({ \
-	unsigned long flag,sum; \
+	unsigned long flag,roksum; \
 	__chk_user_ptr(addr); \
 	asm("addl %3,%1 ; sbbl %0,%0; cmpl %1,%4; sbbl $0,%0" \
-		:"=&r" (flag), "=r" (sum) \
+		:"=&r" (flag), "=r" (roksum) \
 		:"1" (addr),"g" ((int)(size)),"rm" (current_thread_info()->addr_limit.seg)); \
 	flag; })
 
diff --git a/include/asm-m32r/uaccess.h b/include/asm-m32r/uaccess.h
index 26e978c7e3b4..bd8c83765a5c 100644
--- a/include/asm-m32r/uaccess.h
+++ b/include/asm-m32r/uaccess.h
@@ -68,7 +68,7 @@ static inline void set_fs(mm_segment_t s)
  * This needs 33-bit arithmetic. We have a carry...
  */
 #define __range_ok(addr,size) ({					\
-	unsigned long flag, sum; 					\
+	unsigned long flag, roksum; 					\
 	__chk_user_ptr(addr);						\
 	asm ( 								\
 		"	cmpu	%1, %1    ; clear cbit\n"		\
@@ -76,7 +76,7 @@ static inline void set_fs(mm_segment_t s)
 		"	subx	%0, %0\n"				\
 		"	cmpu	%4, %1\n"				\
 		"	subx	%0, %5\n"				\
-		: "=&r" (flag), "=r" (sum)				\
+		: "=&r" (flag), "=r" (roksum)				\
 		: "1" (addr), "r" ((int)(size)), 			\
 		  "r" (current_thread_info()->addr_limit.seg), "r" (0)	\
 		: "cbit" );						\
diff --git a/include/asm-x86_64/uaccess.h b/include/asm-x86_64/uaccess.h
index c0eac519840b..8079e29c14fd 100644
--- a/include/asm-x86_64/uaccess.h
+++ b/include/asm-x86_64/uaccess.h
@@ -37,11 +37,11 @@
  * Uhhuh, this needs 65-bit arithmetic. We have a carry..
  */
 #define __range_not_ok(addr,size) ({ \
-	unsigned long flag,sum; \
+	unsigned long flag,roksum; \
 	__chk_user_ptr(addr); \
 	asm("# range_ok\n\r" \
 		"addq %3,%1 ; sbbq %0,%0 ; cmpq %1,%4 ; sbbq $0,%0"  \
-		:"=&r" (flag), "=r" (sum) \
+		:"=&r" (flag), "=r" (roksum) \
 		:"1" (addr),"g" ((long)(size)),"g" (current_thread_info()->addr_limit.seg)); \
 	flag; })
 
-- 
cgit v1.2.3


From c530cba649692512070e8c0131ba3eccade09269 Mon Sep 17 00:00:00 2001
From: "Robert P. J. Day" <rpjday@mindspring.com>
Date: Sat, 10 Feb 2007 01:46:17 -0800
Subject: [PATCH] Remove the last reference to rwlock_is_locked() macro.

Remove the lone, remaining reference to the long-deceased
rwlock_is_locked() macro.

Signed-off-by: Robert P. J. Day <rpjday@mindspring.com>
Cc: Russell King <rmk@arm.linux.org.uk>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
---
 include/asm-arm/spinlock.h | 1 -
 1 file changed, 1 deletion(-)

(limited to 'include/asm-arm')

diff --git a/include/asm-arm/spinlock.h b/include/asm-arm/spinlock.h
index 861092fbaa53..800ba5254daf 100644
--- a/include/asm-arm/spinlock.h
+++ b/include/asm-arm/spinlock.h
@@ -85,7 +85,6 @@ static inline void __raw_spin_unlock(raw_spinlock_t *lock)
  * Write locks are easy - we just set bit 31.  When unlocking, we can
  * just write zero since the lock is exclusively held.
  */
-#define rwlock_is_locked(x)	(*((volatile unsigned int *)(x)) != 0)
 
 static inline void __raw_write_lock(raw_rwlock_t *rw)
 {
-- 
cgit v1.2.3


From 69c202afa8ad6d6c1c673d8f9d47b43a0a3604e5 Mon Sep 17 00:00:00 2001
From: Andrea Paterniani <a.paterniani@swapp-eng.it>
Date: Mon, 12 Feb 2007 00:52:39 -0800
Subject: [PATCH] SPI: Freescale iMX SPI controller driver (BIS+)

Add the SPI controller driver for Freescale i.MX(S/L/1).
Main features summary:

 > Per chip setup via board specific code and/or protocol driver.
 > Per transfer setup.
 > PIO transfers.
 > DMA transfers.
 > Managing of NULL tx / rx buffer for rd only / wr only transfers.

This patch replace patch-2.6.20-rc4-spi_imx with the following changes:
 > Few cosmetic changes.
 > Function map_dma_buffers now return 0 for success and -1 for failure.
 > Solved a bug inside spi_imx_probe function (wrong error path).
 > Solved a bug inside setup function (bad undo setup for max_speed_hz).
 > For read-only transfers, always write zero bytes.

This is almost the same as the 'BIS' version sent by Andrea, except for
updating the 'DUMMY' byte so that read-only transfers shift out zeroes.
That part of the API changed recently, since some half duplex peripheral
chips require that semantic.

Signed-off-by: Andrea Paterniani <a.paterniani@swapp-eng.it>
Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
---
 drivers/spi/Kconfig                |    8 +
 drivers/spi/Makefile               |    1 +
 drivers/spi/spi_imx.c              | 1769 ++++++++++++++++++++++++++++++++++++
 include/asm-arm/arch-imx/spi_imx.h |   72 ++
 4 files changed, 1850 insertions(+)
 create mode 100644 drivers/spi/spi_imx.c
 create mode 100644 include/asm-arm/arch-imx/spi_imx.h

(limited to 'include/asm-arm')

diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
index 2a2f44d1367d..b217a65453f5 100644
--- a/drivers/spi/Kconfig
+++ b/drivers/spi/Kconfig
@@ -75,6 +75,13 @@ config SPI_BUTTERFLY
 	  inexpensive battery powered microcontroller evaluation board.
 	  This same cable can be used to flash new firmware.
 
+config SPI_IMX
+	tristate "Freescale iMX SPI controller"
+	depends on SPI_MASTER && ARCH_IMX && EXPERIMENTAL
+	help
+	  This enables using the Freescale iMX SPI controller in master
+	  mode.
+
 config SPI_MPC83xx
 	tristate "Freescale MPC83xx SPI controller"
 	depends on SPI_MASTER && PPC_83xx && EXPERIMENTAL
@@ -94,6 +101,7 @@ config SPI_OMAP_UWIRE
 	help
 	  This hooks up to the MicroWire controller on OMAP1 chips.
 
+
 config SPI_PXA2XX
 	tristate "PXA2xx SSP SPI master"
 	depends on SPI_MASTER && ARCH_PXA && EXPERIMENTAL
diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile
index f1a3b96b2a63..e01104d1ebf8 100644
--- a/drivers/spi/Makefile
+++ b/drivers/spi/Makefile
@@ -13,6 +13,7 @@ obj-$(CONFIG_SPI_MASTER)		+= spi.o
 # SPI master controller drivers (bus)
 obj-$(CONFIG_SPI_BITBANG)		+= spi_bitbang.o
 obj-$(CONFIG_SPI_BUTTERFLY)		+= spi_butterfly.o
+obj-$(CONFIG_SPI_IMX)			+= spi_imx.o
 obj-$(CONFIG_SPI_PXA2XX)		+= pxa2xx_spi.o
 obj-$(CONFIG_SPI_OMAP_UWIRE)		+= omap_uwire.o
 obj-$(CONFIG_SPI_MPC83xx)		+= spi_mpc83xx.o
diff --git a/drivers/spi/spi_imx.c b/drivers/spi/spi_imx.c
new file mode 100644
index 000000000000..6ccf8a12a21d
--- /dev/null
+++ b/drivers/spi/spi_imx.c
@@ -0,0 +1,1769 @@
+/*
+ * drivers/spi/spi_imx.c
+ *
+ * Copyright (C) 2006 SWAPP
+ *	Andrea Paterniani <a.paterniani@swapp-eng.it>
+ *
+ * Initial version inspired by:
+ *	linux-2.6.17-rc3-mm1/drivers/spi/pxa2xx_spi.c
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/ioport.h>
+#include <linux/errno.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <linux/dma-mapping.h>
+#include <linux/spi/spi.h>
+#include <linux/workqueue.h>
+#include <linux/delay.h>
+
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/hardware.h>
+#include <asm/delay.h>
+
+#include <asm/arch/hardware.h>
+#include <asm/arch/imx-dma.h>
+#include <asm/arch/spi_imx.h>
+
+/*-------------------------------------------------------------------------*/
+/* SPI Registers offsets from peripheral base address */
+#define SPI_RXDATA		(0x00)
+#define SPI_TXDATA		(0x04)
+#define SPI_CONTROL		(0x08)
+#define SPI_INT_STATUS		(0x0C)
+#define SPI_TEST		(0x10)
+#define SPI_PERIOD		(0x14)
+#define SPI_DMA			(0x18)
+#define SPI_RESET		(0x1C)
+
+/* SPI Control Register Bit Fields & Masks */
+#define SPI_CONTROL_BITCOUNT_MASK	(0xF)		/* Bit Count Mask */
+#define SPI_CONTROL_BITCOUNT(n)		(((n) - 1) & SPI_CONTROL_BITCOUNT_MASK)
+#define SPI_CONTROL_POL			(0x1 << 4)      /* Clock Polarity Mask */
+#define SPI_CONTROL_POL_ACT_HIGH	(0x0 << 4)      /* Active high pol. (0=idle) */
+#define SPI_CONTROL_POL_ACT_LOW		(0x1 << 4)      /* Active low pol. (1=idle) */
+#define SPI_CONTROL_PHA			(0x1 << 5)      /* Clock Phase Mask */
+#define SPI_CONTROL_PHA_0		(0x0 << 5)      /* Clock Phase 0 */
+#define SPI_CONTROL_PHA_1		(0x1 << 5)      /* Clock Phase 1 */
+#define SPI_CONTROL_SSCTL		(0x1 << 6)      /* /SS Waveform Select Mask */
+#define SPI_CONTROL_SSCTL_0		(0x0 << 6)      /* Master: /SS stays low between SPI burst
+							   Slave: RXFIFO advanced by BIT_COUNT */
+#define SPI_CONTROL_SSCTL_1		(0x1 << 6)      /* Master: /SS insert pulse between SPI burst
+							   Slave: RXFIFO advanced by /SS rising edge */
+#define SPI_CONTROL_SSPOL		(0x1 << 7)      /* /SS Polarity Select Mask */
+#define SPI_CONTROL_SSPOL_ACT_LOW	(0x0 << 7)      /* /SS Active low */
+#define SPI_CONTROL_SSPOL_ACT_HIGH	(0x1 << 7)      /* /SS Active high */
+#define SPI_CONTROL_XCH			(0x1 << 8)      /* Exchange */
+#define SPI_CONTROL_SPIEN		(0x1 << 9)      /* SPI Module Enable */
+#define SPI_CONTROL_MODE		(0x1 << 10)     /* SPI Mode Select Mask */
+#define SPI_CONTROL_MODE_SLAVE		(0x0 << 10)     /* SPI Mode Slave */
+#define SPI_CONTROL_MODE_MASTER		(0x1 << 10)     /* SPI Mode Master */
+#define SPI_CONTROL_DRCTL		(0x3 << 11)     /* /SPI_RDY Control Mask */
+#define SPI_CONTROL_DRCTL_0		(0x0 << 11)     /* Ignore /SPI_RDY */
+#define SPI_CONTROL_DRCTL_1		(0x1 << 11)     /* /SPI_RDY falling edge triggers input */
+#define SPI_CONTROL_DRCTL_2		(0x2 << 11)     /* /SPI_RDY active low level triggers input */
+#define SPI_CONTROL_DATARATE		(0x7 << 13)     /* Data Rate Mask */
+#define SPI_PERCLK2_DIV_MIN		(0)		/* PERCLK2:4 */
+#define SPI_PERCLK2_DIV_MAX		(7)		/* PERCLK2:512 */
+#define SPI_CONTROL_DATARATE_MIN	(SPI_PERCLK2_DIV_MAX << 13)
+#define SPI_CONTROL_DATARATE_MAX	(SPI_PERCLK2_DIV_MIN << 13)
+#define SPI_CONTROL_DATARATE_BAD	(SPI_CONTROL_DATARATE_MIN + 1)
+
+/* SPI Interrupt/Status Register Bit Fields & Masks */
+#define SPI_STATUS_TE	(0x1 << 0)	/* TXFIFO Empty Status */
+#define SPI_STATUS_TH	(0x1 << 1)      /* TXFIFO Half Status */
+#define SPI_STATUS_TF	(0x1 << 2)      /* TXFIFO Full Status */
+#define SPI_STATUS_RR	(0x1 << 3)      /* RXFIFO Data Ready Status */
+#define SPI_STATUS_RH	(0x1 << 4)      /* RXFIFO Half Status */
+#define SPI_STATUS_RF	(0x1 << 5)      /* RXFIFO Full Status */
+#define SPI_STATUS_RO	(0x1 << 6)      /* RXFIFO Overflow */
+#define SPI_STATUS_BO	(0x1 << 7)      /* Bit Count Overflow */
+#define SPI_STATUS	(0xFF)		/* SPI Status Mask */
+#define SPI_INTEN_TE	(0x1 << 8)      /* TXFIFO Empty Interrupt Enable */
+#define SPI_INTEN_TH	(0x1 << 9)      /* TXFIFO Half Interrupt Enable */
+#define SPI_INTEN_TF	(0x1 << 10)     /* TXFIFO Full Interrupt Enable */
+#define SPI_INTEN_RE	(0x1 << 11)     /* RXFIFO Data Ready Interrupt Enable */
+#define SPI_INTEN_RH	(0x1 << 12)     /* RXFIFO Half Interrupt Enable */
+#define SPI_INTEN_RF	(0x1 << 13)     /* RXFIFO Full Interrupt Enable */
+#define SPI_INTEN_RO	(0x1 << 14)     /* RXFIFO Overflow Interrupt Enable */
+#define SPI_INTEN_BO	(0x1 << 15)     /* Bit Count Overflow Interrupt Enable */
+#define SPI_INTEN	(0xFF << 8)	/* SPI Interrupt Enable Mask */
+
+/* SPI Test Register Bit Fields & Masks */
+#define SPI_TEST_TXCNT		(0xF << 0)	/* TXFIFO Counter */
+#define SPI_TEST_RXCNT_LSB	(4)		/* RXFIFO Counter LSB */
+#define SPI_TEST_RXCNT		(0xF << 4)	/* RXFIFO Counter */
+#define SPI_TEST_SSTATUS	(0xF << 8)	/* State Machine Status */
+#define SPI_TEST_LBC		(0x1 << 14)	/* Loop Back Control */
+
+/* SPI Period Register Bit Fields & Masks */
+#define SPI_PERIOD_WAIT		(0x7FFF << 0)	/* Wait Between Transactions */
+#define SPI_PERIOD_MAX_WAIT	(0x7FFF)	/* Max Wait Between
+							Transactions */
+#define SPI_PERIOD_CSRC		(0x1 << 15)	/* Period Clock Source Mask */
+#define SPI_PERIOD_CSRC_BCLK	(0x0 << 15)	/* Period Clock Source is
+							Bit Clock */
+#define SPI_PERIOD_CSRC_32768	(0x1 << 15)	/* Period Clock Source is
+							32.768 KHz Clock */
+
+/* SPI DMA Register Bit Fields & Masks */
+#define SPI_DMA_RHDMA	(0xF << 4)	/* RXFIFO Half Status */
+#define SPI_DMA_RFDMA	(0x1 << 5)      /* RXFIFO Full Status */
+#define SPI_DMA_TEDMA	(0x1 << 6)      /* TXFIFO Empty Status */
+#define SPI_DMA_THDMA	(0x1 << 7)      /* TXFIFO Half Status */
+#define SPI_DMA_RHDEN	(0x1 << 12)	/* RXFIFO Half DMA Request Enable */
+#define SPI_DMA_RFDEN	(0x1 << 13)     /* RXFIFO Full DMA Request Enable */
+#define SPI_DMA_TEDEN	(0x1 << 14)     /* TXFIFO Empty DMA Request Enable */
+#define SPI_DMA_THDEN	(0x1 << 15)     /* TXFIFO Half DMA Request Enable */
+
+/* SPI Soft Reset Register Bit Fields & Masks */
+#define SPI_RESET_START	(0x1)		/* Start */
+
+/* Default SPI configuration values */
+#define SPI_DEFAULT_CONTROL		\
+(					\
+	SPI_CONTROL_BITCOUNT(16) | 	\
+	SPI_CONTROL_POL_ACT_HIGH |	\
+	SPI_CONTROL_PHA_0 |		\
+	SPI_CONTROL_SPIEN |		\
+	SPI_CONTROL_SSCTL_1 |		\
+	SPI_CONTROL_MODE_MASTER |	\
+	SPI_CONTROL_DRCTL_0 |		\
+	SPI_CONTROL_DATARATE_MIN	\
+)
+#define SPI_DEFAULT_ENABLE_LOOPBACK	(0)
+#define SPI_DEFAULT_ENABLE_DMA		(0)
+#define SPI_DEFAULT_PERIOD_WAIT		(8)
+/*-------------------------------------------------------------------------*/
+
+
+/*-------------------------------------------------------------------------*/
+/* TX/RX SPI FIFO size */
+#define SPI_FIFO_DEPTH			(8)
+#define SPI_FIFO_BYTE_WIDTH		(2)
+#define SPI_FIFO_OVERFLOW_MARGIN	(2)
+
+/* DMA burst lenght for half full/empty request trigger */
+#define SPI_DMA_BLR			(SPI_FIFO_DEPTH * SPI_FIFO_BYTE_WIDTH / 2)
+
+/* Dummy char output to achieve reads.
+   Choosing something different from all zeroes may help pattern recogition
+   for oscilloscope analysis, but may break some drivers. */
+#define SPI_DUMMY_u8			0
+#define SPI_DUMMY_u16			((SPI_DUMMY_u8 << 8) | SPI_DUMMY_u8)
+#define SPI_DUMMY_u32			((SPI_DUMMY_u16 << 16) | SPI_DUMMY_u16)
+
+/**
+ * Macro to change a u32 field:
+ * @r : register to edit
+ * @m : bit mask
+ * @v : new value for the field correctly bit-alligned
+*/
+#define u32_EDIT(r, m, v)		r = (r & ~(m)) | (v)
+
+/* Message state */
+#define START_STATE			((void*)0)
+#define RUNNING_STATE			((void*)1)
+#define DONE_STATE			((void*)2)
+#define ERROR_STATE			((void*)-1)
+
+/* Queue state */
+#define QUEUE_RUNNING			(0)
+#define QUEUE_STOPPED			(1)
+
+#define IS_DMA_ALIGNED(x) 		(((u32)(x) & 0x03) == 0)
+/*-------------------------------------------------------------------------*/
+
+
+/*-------------------------------------------------------------------------*/
+/* Driver data structs */
+
+/* Context */
+struct driver_data {
+	/* Driver model hookup */
+	struct platform_device *pdev;
+
+	/* SPI framework hookup */
+	struct spi_master *master;
+
+	/* IMX hookup */
+	struct spi_imx_master *master_info;
+
+	/* Memory resources and SPI regs virtual address */
+	struct resource *ioarea;
+	void __iomem *regs;
+
+	/* SPI RX_DATA physical address */
+	dma_addr_t rd_data_phys;
+
+	/* Driver message queue */
+	struct workqueue_struct	*workqueue;
+	struct work_struct work;
+	spinlock_t lock;
+	struct list_head queue;
+	int busy;
+	int run;
+
+	/* Message Transfer pump */
+	struct tasklet_struct pump_transfers;
+
+	/* Current message, transfer and state */
+	struct spi_message *cur_msg;
+	struct spi_transfer *cur_transfer;
+	struct chip_data *cur_chip;
+
+	/* Rd / Wr buffers pointers */
+	size_t len;
+	void *tx;
+	void *tx_end;
+	void *rx;
+	void *rx_end;
+
+	u8 rd_only;
+	u8 n_bytes;
+	int cs_change;
+
+	/* Function pointers */
+	irqreturn_t (*transfer_handler)(struct driver_data *drv_data);
+	void (*cs_control)(u32 command);
+
+	/* DMA setup */
+	int rx_channel;
+	int tx_channel;
+	dma_addr_t rx_dma;
+	dma_addr_t tx_dma;
+	int rx_dma_needs_unmap;
+	int tx_dma_needs_unmap;
+	size_t tx_map_len;
+	u32 dummy_dma_buf ____cacheline_aligned;
+};
+
+/* Runtime state */
+struct chip_data {
+	u32 control;
+	u32 period;
+	u32 test;
+
+	u8 enable_dma:1;
+	u8 bits_per_word;
+	u8 n_bytes;
+	u32 max_speed_hz;
+
+	void (*cs_control)(u32 command);
+};
+/*-------------------------------------------------------------------------*/
+
+
+static void pump_messages(struct work_struct *work);
+
+static int flush(struct driver_data *drv_data)
+{
+	unsigned long limit = loops_per_jiffy << 1;
+	void __iomem *regs = drv_data->regs;
+	volatile u32 d;
+
+	dev_dbg(&drv_data->pdev->dev, "flush\n");
+	do {
+		while (readl(regs + SPI_INT_STATUS) & SPI_STATUS_RR)
+			d = readl(regs + SPI_RXDATA);
+	} while ((readl(regs + SPI_CONTROL) & SPI_CONTROL_XCH) && limit--);
+
+	return limit;
+}
+
+static void restore_state(struct driver_data *drv_data)
+{
+	void __iomem *regs = drv_data->regs;
+	struct chip_data *chip = drv_data->cur_chip;
+
+	/* Load chip registers */
+	dev_dbg(&drv_data->pdev->dev,
+		"restore_state\n"
+		"    test    = 0x%08X\n"
+		"    control = 0x%08X\n",
+		chip->test,
+		chip->control);
+	writel(chip->test, regs + SPI_TEST);
+	writel(chip->period, regs + SPI_PERIOD);
+	writel(0, regs + SPI_INT_STATUS);
+	writel(chip->control, regs + SPI_CONTROL);
+}
+
+static void null_cs_control(u32 command)
+{
+}
+
+static inline u32 data_to_write(struct driver_data *drv_data)
+{
+	return ((u32)(drv_data->tx_end - drv_data->tx)) / drv_data->n_bytes;
+}
+
+static inline u32 data_to_read(struct driver_data *drv_data)
+{
+	return ((u32)(drv_data->rx_end - drv_data->rx)) / drv_data->n_bytes;
+}
+
+static int write(struct driver_data *drv_data)
+{
+	void __iomem *regs = drv_data->regs;
+	void *tx = drv_data->tx;
+	void *tx_end = drv_data->tx_end;
+	u8 n_bytes = drv_data->n_bytes;
+	u32 remaining_writes;
+	u32 fifo_avail_space;
+	u32 n;
+	u16 d;
+
+	/* Compute how many fifo writes to do */
+	remaining_writes = (u32)(tx_end - tx) / n_bytes;
+	fifo_avail_space = SPI_FIFO_DEPTH -
+				(readl(regs + SPI_TEST) & SPI_TEST_TXCNT);
+	if (drv_data->rx && (fifo_avail_space > SPI_FIFO_OVERFLOW_MARGIN))
+		/* Fix misunderstood receive overflow */
+		fifo_avail_space -= SPI_FIFO_OVERFLOW_MARGIN;
+	n = min(remaining_writes, fifo_avail_space);
+
+	dev_dbg(&drv_data->pdev->dev,
+		"write type %s\n"
+		"    remaining writes = %d\n"
+		"    fifo avail space = %d\n"
+		"    fifo writes      = %d\n",
+		(n_bytes == 1) ? "u8" : "u16",
+		remaining_writes,
+		fifo_avail_space,
+		n);
+
+	if (n > 0) {
+		/* Fill SPI TXFIFO */
+		if (drv_data->rd_only) {
+			tx += n * n_bytes;
+			while (n--)
+				writel(SPI_DUMMY_u16, regs + SPI_TXDATA);
+		} else {
+			if (n_bytes == 1) {
+				while (n--) {
+					d = *(u8*)tx;
+					writel(d, regs + SPI_TXDATA);
+					tx += 1;
+				}
+			} else {
+				while (n--) {
+					d = *(u16*)tx;
+					writel(d, regs + SPI_TXDATA);
+					tx += 2;
+				}
+			}
+		}
+
+		/* Trigger transfer */
+		writel(readl(regs + SPI_CONTROL) | SPI_CONTROL_XCH,
+			regs + SPI_CONTROL);
+
+		/* Update tx pointer */
+		drv_data->tx = tx;
+	}
+
+	return (tx >= tx_end);
+}
+
+static int read(struct driver_data *drv_data)
+{
+	void __iomem *regs = drv_data->regs;
+	void *rx = drv_data->rx;
+	void *rx_end = drv_data->rx_end;
+	u8 n_bytes = drv_data->n_bytes;
+	u32 remaining_reads;
+	u32 fifo_rxcnt;
+	u32 n;
+	u16 d;
+
+	/* Compute how many fifo reads to do */
+	remaining_reads = (u32)(rx_end - rx) / n_bytes;
+	fifo_rxcnt = (readl(regs + SPI_TEST) & SPI_TEST_RXCNT) >>
+			SPI_TEST_RXCNT_LSB;
+	n = min(remaining_reads, fifo_rxcnt);
+
+	dev_dbg(&drv_data->pdev->dev,
+		"read type %s\n"
+		"    remaining reads = %d\n"
+		"    fifo rx count   = %d\n"
+		"    fifo reads      = %d\n",
+		(n_bytes == 1) ? "u8" : "u16",
+		remaining_reads,
+		fifo_rxcnt,
+		n);
+
+	if (n > 0) {
+		/* Read SPI RXFIFO */
+		if (n_bytes == 1) {
+			while (n--) {
+				d = readl(regs + SPI_RXDATA);
+				*((u8*)rx) = d;
+				rx += 1;
+			}
+		} else {
+			while (n--) {
+				d = readl(regs + SPI_RXDATA);
+				*((u16*)rx) = d;
+				rx += 2;
+			}
+		}
+
+		/* Update rx pointer */
+		drv_data->rx = rx;
+	}
+
+	return (rx >= rx_end);
+}
+
+static void *next_transfer(struct driver_data *drv_data)
+{
+	struct spi_message *msg = drv_data->cur_msg;
+	struct spi_transfer *trans = drv_data->cur_transfer;
+
+	/* Move to next transfer */
+	if (trans->transfer_list.next != &msg->transfers) {
+		drv_data->cur_transfer =
+			list_entry(trans->transfer_list.next,
+					struct spi_transfer,
+					transfer_list);
+		return RUNNING_STATE;
+	}
+
+	return DONE_STATE;
+}
+
+static int map_dma_buffers(struct driver_data *drv_data)
+{
+	struct spi_message *msg;
+	struct device *dev;
+	void *buf;
+
+	drv_data->rx_dma_needs_unmap = 0;
+	drv_data->tx_dma_needs_unmap = 0;
+
+	if (!drv_data->master_info->enable_dma ||
+		!drv_data->cur_chip->enable_dma)
+			return -1;
+
+	msg = drv_data->cur_msg;
+	dev = &msg->spi->dev;
+	if (msg->is_dma_mapped) {
+		if (drv_data->tx_dma)
+			/* The caller provided at least dma and cpu virtual
+			   address for write; pump_transfers() will consider the
+			   transfer as write only if cpu rx virtual address is
+			   NULL */
+			return 0;
+
+		if (drv_data->rx_dma) {
+			/* The caller provided dma and cpu virtual address to
+			   performe read only transfer -->
+			   use drv_data->dummy_dma_buf for dummy writes to
+			   achive reads */
+			buf = &drv_data->dummy_dma_buf;
+			drv_data->tx_map_len = sizeof(drv_data->dummy_dma_buf);
+			drv_data->tx_dma = dma_map_single(dev,
+							buf,
+							drv_data->tx_map_len,
+							DMA_TO_DEVICE);
+			if (dma_mapping_error(drv_data->tx_dma))
+				return -1;
+
+			drv_data->tx_dma_needs_unmap = 1;
+
+			/* Flags transfer as rd_only for pump_transfers() DMA
+			   regs programming (should be redundant) */
+			drv_data->tx = NULL;
+
+			return 0;
+		}
+	}
+
+	if (!IS_DMA_ALIGNED(drv_data->rx) || !IS_DMA_ALIGNED(drv_data->tx))
+		return -1;
+
+	/* NULL rx means write-only transfer and no map needed
+	   since rx DMA will not be used */
+	if (drv_data->rx) {
+		buf = drv_data->rx;
+		drv_data->rx_dma = dma_map_single(
+					dev,
+					buf,
+					drv_data->len,
+					DMA_FROM_DEVICE);
+		if (dma_mapping_error(drv_data->rx_dma))
+			return -1;
+		drv_data->rx_dma_needs_unmap = 1;
+	}
+
+	if (drv_data->tx == NULL) {
+		/* Read only message --> use drv_data->dummy_dma_buf for dummy
+		   writes to achive reads */
+		buf = &drv_data->dummy_dma_buf;
+		drv_data->tx_map_len = sizeof(drv_data->dummy_dma_buf);
+	} else {
+		buf = drv_data->tx;
+		drv_data->tx_map_len = drv_data->len;
+	}
+	drv_data->tx_dma = dma_map_single(dev,
+					buf,
+					drv_data->tx_map_len,
+					DMA_TO_DEVICE);
+	if (dma_mapping_error(drv_data->tx_dma)) {
+		if (drv_data->rx_dma) {
+			dma_unmap_single(dev,
+					drv_data->rx_dma,
+					drv_data->len,
+					DMA_FROM_DEVICE);
+			drv_data->rx_dma_needs_unmap = 0;
+		}
+		return -1;
+	}
+	drv_data->tx_dma_needs_unmap = 1;
+
+	return 0;
+}
+
+static void unmap_dma_buffers(struct driver_data *drv_data)
+{
+	struct spi_message *msg = drv_data->cur_msg;
+	struct device *dev = &msg->spi->dev;
+
+	if (drv_data->rx_dma_needs_unmap) {
+		dma_unmap_single(dev,
+				drv_data->rx_dma,
+				drv_data->len,
+				DMA_FROM_DEVICE);
+		drv_data->rx_dma_needs_unmap = 0;
+	}
+	if (drv_data->tx_dma_needs_unmap) {
+		dma_unmap_single(dev,
+				drv_data->tx_dma,
+				drv_data->tx_map_len,
+				DMA_TO_DEVICE);
+		drv_data->tx_dma_needs_unmap = 0;
+	}
+}
+
+/* Caller already set message->status (dma is already blocked) */
+static void giveback(struct spi_message *message, struct driver_data *drv_data)
+{
+	void __iomem *regs = drv_data->regs;
+
+	/* Bring SPI to sleep; restore_state() and pump_transfer()
+	   will do new setup */
+	writel(0, regs + SPI_INT_STATUS);
+	writel(0, regs + SPI_DMA);
+
+	drv_data->cs_control(SPI_CS_DEASSERT);
+
+	message->state = NULL;
+	if (message->complete)
+		message->complete(message->context);
+
+	drv_data->cur_msg = NULL;
+	drv_data->cur_transfer = NULL;
+	drv_data->cur_chip = NULL;
+	queue_work(drv_data->workqueue, &drv_data->work);
+}
+
+static void dma_err_handler(int channel, void *data, int errcode)
+{
+	struct driver_data *drv_data = data;
+	struct spi_message *msg = drv_data->cur_msg;
+
+	dev_dbg(&drv_data->pdev->dev, "dma_err_handler\n");
+
+	/* Disable both rx and tx dma channels */
+	imx_dma_disable(drv_data->rx_channel);
+	imx_dma_disable(drv_data->tx_channel);
+
+	if (flush(drv_data) == 0)
+		dev_err(&drv_data->pdev->dev,
+				"dma_err_handler - flush failed\n");
+
+	unmap_dma_buffers(drv_data);
+
+	msg->state = ERROR_STATE;
+	tasklet_schedule(&drv_data->pump_transfers);
+}
+
+static void dma_tx_handler(int channel, void *data)
+{
+	struct driver_data *drv_data = data;
+
+	dev_dbg(&drv_data->pdev->dev, "dma_tx_handler\n");
+
+	imx_dma_disable(channel);
+
+	/* Now waits for TX FIFO empty */
+	writel(readl(drv_data->regs + SPI_INT_STATUS) | SPI_INTEN_TE,
+			drv_data->regs + SPI_INT_STATUS);
+}
+
+static irqreturn_t dma_transfer(struct driver_data *drv_data)
+{
+	u32 status;
+	struct spi_message *msg = drv_data->cur_msg;
+	void __iomem *regs = drv_data->regs;
+	unsigned long limit;
+
+	status = readl(regs + SPI_INT_STATUS);
+
+	if ((status & SPI_INTEN_RO) && (status & SPI_STATUS_RO)) {
+		writel(status & ~SPI_INTEN, regs + SPI_INT_STATUS);
+
+		imx_dma_disable(drv_data->rx_channel);
+		unmap_dma_buffers(drv_data);
+
+		if (flush(drv_data) == 0)
+			dev_err(&drv_data->pdev->dev,
+				"dma_transfer - flush failed\n");
+
+		dev_warn(&drv_data->pdev->dev,
+				"dma_transfer - fifo overun\n");
+
+		msg->state = ERROR_STATE;
+		tasklet_schedule(&drv_data->pump_transfers);
+
+		return IRQ_HANDLED;
+	}
+
+	if (status & SPI_STATUS_TE) {
+		writel(status & ~SPI_INTEN_TE, regs + SPI_INT_STATUS);
+
+		if (drv_data->rx) {
+			/* Wait end of transfer before read trailing data */
+			limit = loops_per_jiffy << 1;
+			while ((readl(regs + SPI_CONTROL) & SPI_CONTROL_XCH) &&
+					limit--);
+
+			if (limit == 0)
+				dev_err(&drv_data->pdev->dev,
+					"dma_transfer - end of tx failed\n");
+			else
+				dev_dbg(&drv_data->pdev->dev,
+					"dma_transfer - end of tx\n");
+
+			imx_dma_disable(drv_data->rx_channel);
+			unmap_dma_buffers(drv_data);
+
+			/* Calculate number of trailing data and read them */
+			dev_dbg(&drv_data->pdev->dev,
+				"dma_transfer - test = 0x%08X\n",
+				readl(regs + SPI_TEST));
+			drv_data->rx = drv_data->rx_end -
+					((readl(regs + SPI_TEST) &
+					SPI_TEST_RXCNT) >>
+					SPI_TEST_RXCNT_LSB)*drv_data->n_bytes;
+			read(drv_data);
+		} else {
+			/* Write only transfer */
+			unmap_dma_buffers(drv_data);
+
+			if (flush(drv_data) == 0)
+				dev_err(&drv_data->pdev->dev,
+					"dma_transfer - flush failed\n");
+		}
+
+		/* End of transfer, update total byte transfered */
+		msg->actual_length += drv_data->len;
+
+		/* Release chip select if requested, transfer delays are
+		   handled in pump_transfers() */
+		if (drv_data->cs_change)
+			drv_data->cs_control(SPI_CS_DEASSERT);
+
+		/* Move to next transfer */
+		msg->state = next_transfer(drv_data);
+
+		/* Schedule transfer tasklet */
+		tasklet_schedule(&drv_data->pump_transfers);
+
+		return IRQ_HANDLED;
+	}
+
+	/* Opps problem detected */
+	return IRQ_NONE;
+}
+
+static irqreturn_t interrupt_wronly_transfer(struct driver_data *drv_data)
+{
+	struct spi_message *msg = drv_data->cur_msg;
+	void __iomem *regs = drv_data->regs;
+	u32 status;
+	irqreturn_t handled = IRQ_NONE;
+
+	status = readl(regs + SPI_INT_STATUS);
+
+	while (status & SPI_STATUS_TH) {
+		dev_dbg(&drv_data->pdev->dev,
+			"interrupt_wronly_transfer - status = 0x%08X\n", status);
+
+		/* Pump data */
+		if (write(drv_data)) {
+			writel(readl(regs + SPI_INT_STATUS) & ~SPI_INTEN,
+				regs + SPI_INT_STATUS);
+
+			dev_dbg(&drv_data->pdev->dev,
+				"interrupt_wronly_transfer - end of tx\n");
+
+			if (flush(drv_data) == 0)
+				dev_err(&drv_data->pdev->dev,
+					"interrupt_wronly_transfer - "
+					"flush failed\n");
+
+			/* End of transfer, update total byte transfered */
+			msg->actual_length += drv_data->len;
+
+			/* Release chip select if requested, transfer delays are
+			   handled in pump_transfers */
+			if (drv_data->cs_change)
+				drv_data->cs_control(SPI_CS_DEASSERT);
+
+			/* Move to next transfer */
+			msg->state = next_transfer(drv_data);
+
+			/* Schedule transfer tasklet */
+			tasklet_schedule(&drv_data->pump_transfers);
+
+			return IRQ_HANDLED;
+		}
+
+		status = readl(regs + SPI_INT_STATUS);
+
+		/* We did something */
+		handled = IRQ_HANDLED;
+	}
+
+	return handled;
+}
+
+static irqreturn_t interrupt_transfer(struct driver_data *drv_data)
+{
+	struct spi_message *msg = drv_data->cur_msg;
+	void __iomem *regs = drv_data->regs;
+	u32 status;
+	irqreturn_t handled = IRQ_NONE;
+	unsigned long limit;
+
+	status = readl(regs + SPI_INT_STATUS);
+
+	while (status & (SPI_STATUS_TH | SPI_STATUS_RO)) {
+		dev_dbg(&drv_data->pdev->dev,
+			"interrupt_transfer - status = 0x%08X\n", status);
+
+		if (status & SPI_STATUS_RO) {
+			writel(readl(regs + SPI_INT_STATUS) & ~SPI_INTEN,
+				regs + SPI_INT_STATUS);
+
+			dev_warn(&drv_data->pdev->dev,
+				"interrupt_transfer - fifo overun\n"
+				"    data not yet written = %d\n"
+				"    data not yet read    = %d\n",
+				data_to_write(drv_data),
+				data_to_read(drv_data));
+
+			if (flush(drv_data) == 0)
+				dev_err(&drv_data->pdev->dev,
+					"interrupt_transfer - flush failed\n");
+
+			msg->state = ERROR_STATE;
+			tasklet_schedule(&drv_data->pump_transfers);
+
+			return IRQ_HANDLED;
+		}
+
+		/* Pump data */
+		read(drv_data);
+		if (write(drv_data)) {
+			writel(readl(regs + SPI_INT_STATUS) & ~SPI_INTEN,
+				regs + SPI_INT_STATUS);
+
+			dev_dbg(&drv_data->pdev->dev,
+				"interrupt_transfer - end of tx\n");
+
+			/* Read trailing bytes */
+			limit = loops_per_jiffy << 1;
+			while ((read(drv_data) == 0) && limit--);
+
+			if (limit == 0)
+				dev_err(&drv_data->pdev->dev,
+					"interrupt_transfer - "
+					"trailing byte read failed\n");
+			else
+				dev_dbg(&drv_data->pdev->dev,
+					"interrupt_transfer - end of rx\n");
+
+			/* End of transfer, update total byte transfered */
+			msg->actual_length += drv_data->len;
+
+			/* Release chip select if requested, transfer delays are
+			   handled in pump_transfers */
+			if (drv_data->cs_change)
+				drv_data->cs_control(SPI_CS_DEASSERT);
+
+			/* Move to next transfer */
+			msg->state = next_transfer(drv_data);
+
+			/* Schedule transfer tasklet */
+			tasklet_schedule(&drv_data->pump_transfers);
+
+			return IRQ_HANDLED;
+		}
+
+		status = readl(regs + SPI_INT_STATUS);
+
+		/* We did something */
+		handled = IRQ_HANDLED;
+	}
+
+	return handled;
+}
+
+static irqreturn_t spi_int(int irq, void *dev_id)
+{
+	struct driver_data *drv_data = (struct driver_data *)dev_id;
+
+	if (!drv_data->cur_msg) {
+		dev_err(&drv_data->pdev->dev,
+			"spi_int - bad message state\n");
+		/* Never fail */
+		return IRQ_HANDLED;
+	}
+
+	return drv_data->transfer_handler(drv_data);
+}
+
+static inline u32 spi_speed_hz(u32 data_rate)
+{
+	return imx_get_perclk2() / (4 << ((data_rate) >> 13));
+}
+
+static u32 spi_data_rate(u32 speed_hz)
+{
+	u32 div;
+	u32 quantized_hz = imx_get_perclk2() >> 2;
+
+	for (div = SPI_PERCLK2_DIV_MIN;
+		div <= SPI_PERCLK2_DIV_MAX;
+		div++, quantized_hz >>= 1) {
+			if (quantized_hz <= speed_hz)
+				/* Max available speed LEQ required speed */
+				return div << 13;
+	}
+	return SPI_CONTROL_DATARATE_BAD;
+}
+
+static void pump_transfers(unsigned long data)
+{
+	struct driver_data *drv_data = (struct driver_data *)data;
+	struct spi_message *message;
+	struct spi_transfer *transfer, *previous;
+	struct chip_data *chip;
+	void __iomem *regs;
+	u32 tmp, control;
+
+	dev_dbg(&drv_data->pdev->dev, "pump_transfer\n");
+
+	message = drv_data->cur_msg;
+
+	/* Handle for abort */
+	if (message->state == ERROR_STATE) {
+		message->status = -EIO;
+		giveback(message, drv_data);
+		return;
+	}
+
+	/* Handle end of message */
+	if (message->state == DONE_STATE) {
+		message->status = 0;
+		giveback(message, drv_data);
+		return;
+	}
+
+	chip = drv_data->cur_chip;
+
+	/* Delay if requested at end of transfer*/
+	transfer = drv_data->cur_transfer;
+	if (message->state == RUNNING_STATE) {
+		previous = list_entry(transfer->transfer_list.prev,
+					struct spi_transfer,
+					transfer_list);
+		if (previous->delay_usecs)
+			udelay(previous->delay_usecs);
+	} else {
+		/* START_STATE */
+		message->state = RUNNING_STATE;
+		drv_data->cs_control = chip->cs_control;
+	}
+
+	transfer = drv_data->cur_transfer;
+	drv_data->tx = (void *)transfer->tx_buf;
+	drv_data->tx_end = drv_data->tx + transfer->len;
+	drv_data->rx = transfer->rx_buf;
+	drv_data->rx_end = drv_data->rx + transfer->len;
+	drv_data->rx_dma = transfer->rx_dma;
+	drv_data->tx_dma = transfer->tx_dma;
+	drv_data->len = transfer->len;
+	drv_data->cs_change = transfer->cs_change;
+	drv_data->rd_only = (drv_data->tx == NULL);
+
+	regs = drv_data->regs;
+	control = readl(regs + SPI_CONTROL);
+
+	/* Bits per word setup */
+	tmp = transfer->bits_per_word;
+	if (tmp == 0) {
+		/* Use device setup */
+		tmp = chip->bits_per_word;
+		drv_data->n_bytes = chip->n_bytes;
+	} else
+		/* Use per-transfer setup */
+		drv_data->n_bytes = (tmp <= 8) ? 1 : 2;
+	u32_EDIT(control, SPI_CONTROL_BITCOUNT_MASK, tmp - 1);
+
+	/* Speed setup (surely valid because already checked) */
+	tmp = transfer->speed_hz;
+	if (tmp == 0)
+		tmp = chip->max_speed_hz;
+	tmp = spi_data_rate(tmp);
+	u32_EDIT(control, SPI_CONTROL_DATARATE, tmp);
+
+	writel(control, regs + SPI_CONTROL);
+
+	/* Assert device chip-select */
+	drv_data->cs_control(SPI_CS_ASSERT);
+
+	/* DMA cannot read/write SPI FIFOs other than 16 bits at a time; hence
+	   if bits_per_word is less or equal 8 PIO transfers are performed.
+	   Moreover DMA is convinient for transfer length bigger than FIFOs
+	   byte size. */
+	if ((drv_data->n_bytes == 2) &&
+		(drv_data->len > SPI_FIFO_DEPTH*SPI_FIFO_BYTE_WIDTH) &&
+		(map_dma_buffers(drv_data) == 0)) {
+		dev_dbg(&drv_data->pdev->dev,
+			"pump dma transfer\n"
+			"    tx      = %p\n"
+			"    tx_dma  = %08X\n"
+			"    rx      = %p\n"
+			"    rx_dma  = %08X\n"
+			"    len     = %d\n",
+			drv_data->tx,
+			(unsigned int)drv_data->tx_dma,
+			drv_data->rx,
+			(unsigned int)drv_data->rx_dma,
+			drv_data->len);
+
+		/* Ensure we have the correct interrupt handler */
+		drv_data->transfer_handler = dma_transfer;
+
+		/* Trigger transfer */
+		writel(readl(regs + SPI_CONTROL) | SPI_CONTROL_XCH,
+			regs + SPI_CONTROL);
+
+		/* Setup tx DMA */
+		if (drv_data->tx)
+			/* Linear source address */
+			CCR(drv_data->tx_channel) =
+				CCR_DMOD_FIFO |
+				CCR_SMOD_LINEAR |
+				CCR_SSIZ_32 | CCR_DSIZ_16 |
+				CCR_REN;
+		else
+			/* Read only transfer -> fixed source address for
+			   dummy write to achive read */
+			CCR(drv_data->tx_channel) =
+				CCR_DMOD_FIFO |
+				CCR_SMOD_FIFO |
+				CCR_SSIZ_32 | CCR_DSIZ_16 |
+				CCR_REN;
+
+		imx_dma_setup_single(
+			drv_data->tx_channel,
+			drv_data->tx_dma,
+			drv_data->len,
+			drv_data->rd_data_phys + 4,
+			DMA_MODE_WRITE);
+
+		if (drv_data->rx) {
+			/* Setup rx DMA for linear destination address */
+			CCR(drv_data->rx_channel) =
+				CCR_DMOD_LINEAR |
+				CCR_SMOD_FIFO |
+				CCR_DSIZ_32 | CCR_SSIZ_16 |
+				CCR_REN;
+			imx_dma_setup_single(
+				drv_data->rx_channel,
+				drv_data->rx_dma,
+				drv_data->len,
+				drv_data->rd_data_phys,
+				DMA_MODE_READ);
+			imx_dma_enable(drv_data->rx_channel);
+
+			/* Enable SPI interrupt */
+			writel(SPI_INTEN_RO, regs + SPI_INT_STATUS);
+
+			/* Set SPI to request DMA service on both
+			   Rx and Tx half fifo watermark */
+			writel(SPI_DMA_RHDEN | SPI_DMA_THDEN, regs + SPI_DMA);
+		} else
+			/* Write only access -> set SPI to request DMA
+			   service on Tx half fifo watermark */
+			writel(SPI_DMA_THDEN, regs + SPI_DMA);
+
+		imx_dma_enable(drv_data->tx_channel);
+	} else {
+		dev_dbg(&drv_data->pdev->dev,
+			"pump pio transfer\n"
+			"    tx      = %p\n"
+			"    rx      = %p\n"
+			"    len     = %d\n",
+			drv_data->tx,
+			drv_data->rx,
+			drv_data->len);
+
+		/* Ensure we have the correct interrupt handler	*/
+		if (drv_data->rx)
+			drv_data->transfer_handler = interrupt_transfer;
+		else
+			drv_data->transfer_handler = interrupt_wronly_transfer;
+
+		/* Enable SPI interrupt */
+		if (drv_data->rx)
+			writel(SPI_INTEN_TH | SPI_INTEN_RO,
+				regs + SPI_INT_STATUS);
+		else
+			writel(SPI_INTEN_TH, regs + SPI_INT_STATUS);
+	}
+}
+
+static void pump_messages(struct work_struct *work)
+{
+	struct driver_data *drv_data =
+				container_of(work, struct driver_data, work);
+	unsigned long flags;
+
+	/* Lock queue and check for queue work */
+	spin_lock_irqsave(&drv_data->lock, flags);
+	if (list_empty(&drv_data->queue) || drv_data->run == QUEUE_STOPPED) {
+		drv_data->busy = 0;
+		spin_unlock_irqrestore(&drv_data->lock, flags);
+		return;
+	}
+
+	/* Make sure we are not already running a message */
+	if (drv_data->cur_msg) {
+		spin_unlock_irqrestore(&drv_data->lock, flags);
+		return;
+	}
+
+	/* Extract head of queue */
+	drv_data->cur_msg = list_entry(drv_data->queue.next,
+					struct spi_message, queue);
+	list_del_init(&drv_data->cur_msg->queue);
+	drv_data->busy = 1;
+	spin_unlock_irqrestore(&drv_data->lock, flags);
+
+	/* Initial message state */
+	drv_data->cur_msg->state = START_STATE;
+	drv_data->cur_transfer = list_entry(drv_data->cur_msg->transfers.next,
+						struct spi_transfer,
+						transfer_list);
+
+	/* Setup the SPI using the per chip configuration */
+	drv_data->cur_chip = spi_get_ctldata(drv_data->cur_msg->spi);
+	restore_state(drv_data);
+
+	/* Mark as busy and launch transfers */
+	tasklet_schedule(&drv_data->pump_transfers);
+}
+
+static int transfer(struct spi_device *spi, struct spi_message *msg)
+{
+	struct driver_data *drv_data = spi_master_get_devdata(spi->master);
+	u32 min_speed_hz, max_speed_hz, tmp;
+	struct spi_transfer *trans;
+	unsigned long flags;
+
+	msg->actual_length = 0;
+
+	/* Per transfer setup check */
+	min_speed_hz = spi_speed_hz(SPI_CONTROL_DATARATE_MIN);
+	max_speed_hz = spi->max_speed_hz;
+	list_for_each_entry(trans, &msg->transfers, transfer_list) {
+		tmp = trans->bits_per_word;
+		if (tmp > 16) {
+			dev_err(&drv_data->pdev->dev,
+				"message rejected : "
+				"invalid transfer bits_per_word (%d bits)\n",
+				tmp);
+			goto msg_rejected;
+		}
+		tmp = trans->speed_hz;
+		if (tmp) {
+			if (tmp < min_speed_hz) {
+				dev_err(&drv_data->pdev->dev,
+					"message rejected : "
+					"device min speed (%d Hz) exceeds "
+					"required transfer speed (%d Hz)\n",
+					min_speed_hz,
+					tmp);
+				goto msg_rejected;
+			} else if (tmp > max_speed_hz) {
+				dev_err(&drv_data->pdev->dev,
+					"message rejected : "
+					"transfer speed (%d Hz) exceeds "
+					"device max speed (%d Hz)\n",
+					tmp,
+					max_speed_hz);
+				goto msg_rejected;
+			}
+		}
+	}
+
+	/* Message accepted */
+	msg->status = -EINPROGRESS;
+	msg->state = START_STATE;
+
+	spin_lock_irqsave(&drv_data->lock, flags);
+	if (drv_data->run == QUEUE_STOPPED) {
+		spin_unlock_irqrestore(&drv_data->lock, flags);
+		return -ESHUTDOWN;
+	}
+
+	list_add_tail(&msg->queue, &drv_data->queue);
+	if (drv_data->run == QUEUE_RUNNING && !drv_data->busy)
+		queue_work(drv_data->workqueue, &drv_data->work);
+
+	spin_unlock_irqrestore(&drv_data->lock, flags);
+	return 0;
+
+msg_rejected:
+	/* Message rejected and not queued */
+	msg->status = -EINVAL;
+	msg->state = ERROR_STATE;
+	if (msg->complete)
+		msg->complete(msg->context);
+	return -EINVAL;
+}
+
+/* On first setup bad values must free chip_data memory since will cause
+   spi_new_device to fail. Bad value setup from protocol driver are simply not
+   applied and notified to the calling driver. */
+static int setup(struct spi_device *spi)
+{
+	struct spi_imx_chip *chip_info;
+	struct chip_data *chip;
+	int first_setup = 0;
+	u32 tmp;
+	int status = 0;
+
+	/* Get controller data */
+	chip_info = spi->controller_data;
+
+	/* Get controller_state */
+	chip = spi_get_ctldata(spi);
+	if (chip == NULL) {
+		first_setup = 1;
+
+		chip = kzalloc(sizeof(struct chip_data), GFP_KERNEL);
+		if (!chip) {
+			dev_err(&spi->dev,
+				"setup - cannot allocate controller state");
+			return -ENOMEM;
+		}
+		chip->control = SPI_DEFAULT_CONTROL;
+
+		if (chip_info == NULL) {
+			/* spi_board_info.controller_data not is supplied */
+			chip_info = kzalloc(sizeof(struct spi_imx_chip),
+						GFP_KERNEL);
+			if (!chip_info) {
+				dev_err(&spi->dev,
+					"setup - "
+					"cannot allocate controller data");
+				status = -ENOMEM;
+				goto err_first_setup;
+			}
+			/* Set controller data default value */
+			chip_info->enable_loopback =
+						SPI_DEFAULT_ENABLE_LOOPBACK;
+			chip_info->enable_dma = SPI_DEFAULT_ENABLE_DMA;
+			chip_info->ins_ss_pulse = 1;
+			chip_info->bclk_wait = SPI_DEFAULT_PERIOD_WAIT;
+			chip_info->cs_control = null_cs_control;
+		}
+	}
+
+	/* Now set controller state based on controller data */
+
+	if (first_setup) {
+		/* SPI loopback */
+		if (chip_info->enable_loopback)
+			chip->test = SPI_TEST_LBC;
+		else
+			chip->test = 0;
+
+		/* SPI dma driven */
+		chip->enable_dma = chip_info->enable_dma;
+
+		/* SPI /SS pulse between spi burst */
+		if (chip_info->ins_ss_pulse)
+			u32_EDIT(chip->control,
+				SPI_CONTROL_SSCTL, SPI_CONTROL_SSCTL_1);
+		else
+			u32_EDIT(chip->control,
+				SPI_CONTROL_SSCTL, SPI_CONTROL_SSCTL_0);
+
+		/* SPI bclk waits between each bits_per_word spi burst */
+		if (chip_info->bclk_wait > SPI_PERIOD_MAX_WAIT) {
+			dev_err(&spi->dev,
+				"setup - "
+				"bclk_wait exceeds max allowed (%d)\n",
+				SPI_PERIOD_MAX_WAIT);
+			goto err_first_setup;
+		}
+		chip->period = SPI_PERIOD_CSRC_BCLK |
+				(chip_info->bclk_wait & SPI_PERIOD_WAIT);
+	}
+
+	/* SPI mode */
+	tmp = spi->mode;
+	if (tmp & SPI_LSB_FIRST) {
+		status = -EINVAL;
+		if (first_setup) {
+			dev_err(&spi->dev,
+				"setup - "
+				"HW doesn't support LSB first transfer\n");
+			goto err_first_setup;
+		} else {
+			dev_err(&spi->dev,
+				"setup - "
+				"HW doesn't support LSB first transfer, "
+				"default to MSB first\n");
+			spi->mode &= ~SPI_LSB_FIRST;
+		}
+	}
+	if (tmp & SPI_CS_HIGH) {
+		u32_EDIT(chip->control,
+				SPI_CONTROL_SSPOL, SPI_CONTROL_SSPOL_ACT_HIGH);
+	}
+	switch (tmp & SPI_MODE_3) {
+	case SPI_MODE_0:
+		tmp = 0;
+		break;
+	case SPI_MODE_1:
+		tmp = SPI_CONTROL_PHA_1;
+		break;
+	case SPI_MODE_2:
+		tmp = SPI_CONTROL_POL_ACT_LOW;
+		break;
+	default:
+		/* SPI_MODE_3 */
+		tmp = SPI_CONTROL_PHA_1 | SPI_CONTROL_POL_ACT_LOW;
+		break;
+	}
+	u32_EDIT(chip->control, SPI_CONTROL_POL | SPI_CONTROL_PHA, tmp);
+
+	/* SPI word width */
+	tmp = spi->bits_per_word;
+	if (tmp == 0) {
+		tmp = 8;
+		spi->bits_per_word = 8;
+	} else if (tmp > 16) {
+		status = -EINVAL;
+		dev_err(&spi->dev,
+			"setup - "
+			"invalid bits_per_word (%d)\n",
+			tmp);
+		if (first_setup)
+			goto err_first_setup;
+		else {
+			/* Undo setup using chip as backup copy */
+			tmp = chip->bits_per_word;
+			spi->bits_per_word = tmp;
+		}
+	}
+	chip->bits_per_word = tmp;
+	u32_EDIT(chip->control, SPI_CONTROL_BITCOUNT_MASK, tmp - 1);
+	chip->n_bytes = (tmp <= 8) ? 1 : 2;
+
+	/* SPI datarate */
+	tmp = spi_data_rate(spi->max_speed_hz);
+	if (tmp == SPI_CONTROL_DATARATE_BAD) {
+		status = -EINVAL;
+		dev_err(&spi->dev,
+			"setup - "
+			"HW min speed (%d Hz) exceeds required "
+			"max speed (%d Hz)\n",
+			spi_speed_hz(SPI_CONTROL_DATARATE_MIN),
+			spi->max_speed_hz);
+		if (first_setup)
+			goto err_first_setup;
+		else
+			/* Undo setup using chip as backup copy */
+			spi->max_speed_hz = chip->max_speed_hz;
+	} else {
+		u32_EDIT(chip->control, SPI_CONTROL_DATARATE, tmp);
+		/* Actual rounded max_speed_hz */
+		tmp = spi_speed_hz(tmp);
+		spi->max_speed_hz = tmp;
+		chip->max_speed_hz = tmp;
+	}
+
+	/* SPI chip-select management */
+	if (chip_info->cs_control)
+		chip->cs_control = chip_info->cs_control;
+	else
+		chip->cs_control = null_cs_control;
+
+	/* Save controller_state */
+	spi_set_ctldata(spi, chip);
+
+	/* Summary */
+	dev_dbg(&spi->dev,
+		"setup succeded\n"
+		"    loopback enable   = %s\n"
+		"    dma enable        = %s\n"
+		"    insert /ss pulse  = %s\n"
+		"    period wait       = %d\n"
+		"    mode              = %d\n"
+		"    bits per word     = %d\n"
+		"    min speed         = %d Hz\n"
+		"    rounded max speed = %d Hz\n",
+		chip->test & SPI_TEST_LBC ? "Yes" : "No",
+		chip->enable_dma ? "Yes" : "No",
+		chip->control & SPI_CONTROL_SSCTL ? "Yes" : "No",
+		chip->period & SPI_PERIOD_WAIT,
+		spi->mode,
+		spi->bits_per_word,
+		spi_speed_hz(SPI_CONTROL_DATARATE_MIN),
+		spi->max_speed_hz);
+
+err_first_setup:
+	kfree(chip);
+	return status;
+}
+
+static void cleanup(const struct spi_device *spi)
+{
+	struct chip_data *chip = spi_get_ctldata((struct spi_device *)spi);
+	kfree(chip);
+}
+
+static int init_queue(struct driver_data *drv_data)
+{
+	INIT_LIST_HEAD(&drv_data->queue);
+	spin_lock_init(&drv_data->lock);
+
+	drv_data->run = QUEUE_STOPPED;
+	drv_data->busy = 0;
+
+	tasklet_init(&drv_data->pump_transfers,
+			pump_transfers,	(unsigned long)drv_data);
+
+	INIT_WORK(&drv_data->work, pump_messages);
+	drv_data->workqueue = create_singlethread_workqueue(
+					drv_data->master->cdev.dev->bus_id);
+	if (drv_data->workqueue == NULL)
+		return -EBUSY;
+
+	return 0;
+}
+
+static int start_queue(struct driver_data *drv_data)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&drv_data->lock, flags);
+
+	if (drv_data->run == QUEUE_RUNNING || drv_data->busy) {
+		spin_unlock_irqrestore(&drv_data->lock, flags);
+		return -EBUSY;
+	}
+
+	drv_data->run = QUEUE_RUNNING;
+	drv_data->cur_msg = NULL;
+	drv_data->cur_transfer = NULL;
+	drv_data->cur_chip = NULL;
+	spin_unlock_irqrestore(&drv_data->lock, flags);
+
+	queue_work(drv_data->workqueue, &drv_data->work);
+
+	return 0;
+}
+
+static int stop_queue(struct driver_data *drv_data)
+{
+	unsigned long flags;
+	unsigned limit = 500;
+	int status = 0;
+
+	spin_lock_irqsave(&drv_data->lock, flags);
+
+	/* This is a bit lame, but is optimized for the common execution path.
+	 * A wait_queue on the drv_data->busy could be used, but then the common
+	 * execution path (pump_messages) would be required to call wake_up or
+	 * friends on every SPI message. Do this instead */
+	drv_data->run = QUEUE_STOPPED;
+	while (!list_empty(&drv_data->queue) && drv_data->busy && limit--) {
+		spin_unlock_irqrestore(&drv_data->lock, flags);
+		msleep(10);
+		spin_lock_irqsave(&drv_data->lock, flags);
+	}
+
+	if (!list_empty(&drv_data->queue) || drv_data->busy)
+		status = -EBUSY;
+
+	spin_unlock_irqrestore(&drv_data->lock, flags);
+
+	return status;
+}
+
+static int destroy_queue(struct driver_data *drv_data)
+{
+	int status;
+
+	status = stop_queue(drv_data);
+	if (status != 0)
+		return status;
+
+	if (drv_data->workqueue)
+		destroy_workqueue(drv_data->workqueue);
+
+	return 0;
+}
+
+static int spi_imx_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct spi_imx_master *platform_info;
+	struct spi_master *master;
+	struct driver_data *drv_data = NULL;
+	struct resource *res;
+	int irq, status = 0;
+
+	platform_info = dev->platform_data;
+	if (platform_info == NULL) {
+		dev_err(&pdev->dev, "probe - no platform data supplied\n");
+		status = -ENODEV;
+		goto err_no_pdata;
+	}
+
+	/* Allocate master with space for drv_data */
+	master = spi_alloc_master(dev, sizeof(struct driver_data));
+	if (!master) {
+		dev_err(&pdev->dev, "probe - cannot alloc spi_master\n");
+		status = -ENOMEM;
+		goto err_no_mem;
+	}
+	drv_data = spi_master_get_devdata(master);
+	drv_data->master = master;
+	drv_data->master_info = platform_info;
+	drv_data->pdev = pdev;
+
+	master->bus_num = pdev->id;
+	master->num_chipselect = platform_info->num_chipselect;
+	master->cleanup = cleanup;
+	master->setup = setup;
+	master->transfer = transfer;
+
+	drv_data->dummy_dma_buf = SPI_DUMMY_u32;
+
+	/* Find and map resources */
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res) {
+		dev_err(&pdev->dev, "probe - MEM resources not defined\n");
+		status = -ENODEV;
+		goto err_no_iores;
+	}
+	drv_data->ioarea = request_mem_region(res->start,
+						res->end - res->start + 1,
+						pdev->name);
+	if (drv_data->ioarea == NULL) {
+		dev_err(&pdev->dev, "probe - cannot reserve region\n");
+		status = -ENXIO;
+		goto err_no_iores;
+	}
+	drv_data->regs = ioremap(res->start, res->end - res->start + 1);
+	if (drv_data->regs == NULL) {
+		dev_err(&pdev->dev, "probe - cannot map IO\n");
+		status = -ENXIO;
+		goto err_no_iomap;
+	}
+	drv_data->rd_data_phys = (dma_addr_t)res->start;
+
+	/* Attach to IRQ */
+	irq = platform_get_irq(pdev, 0);
+	if (irq < 0) {
+		dev_err(&pdev->dev, "probe - IRQ resource not defined\n");
+		status = -ENODEV;
+		goto err_no_irqres;
+	}
+	status = request_irq(irq, spi_int, IRQF_DISABLED, dev->bus_id, drv_data);
+	if (status < 0) {
+		dev_err(&pdev->dev, "probe - cannot get IRQ (%d)\n", status);
+		goto err_no_irqres;
+	}
+
+	/* Setup DMA if requested */
+	drv_data->tx_channel = -1;
+	drv_data->rx_channel = -1;
+	if (platform_info->enable_dma) {
+		/* Get rx DMA channel */
+		status = imx_dma_request_by_prio(&drv_data->rx_channel,
+			"spi_imx_rx", DMA_PRIO_HIGH);
+		if (status < 0) {
+			dev_err(dev,
+				"probe - problem (%d) requesting rx channel\n",
+				status);
+			goto err_no_rxdma;
+		} else
+			imx_dma_setup_handlers(drv_data->rx_channel, NULL,
+						dma_err_handler, drv_data);
+
+		/* Get tx DMA channel */
+		status = imx_dma_request_by_prio(&drv_data->tx_channel,
+						"spi_imx_tx", DMA_PRIO_MEDIUM);
+		if (status < 0) {
+			dev_err(dev,
+				"probe - problem (%d) requesting tx channel\n",
+				status);
+			imx_dma_free(drv_data->rx_channel);
+			goto err_no_txdma;
+		} else
+			imx_dma_setup_handlers(drv_data->tx_channel,
+						dma_tx_handler, dma_err_handler,
+						drv_data);
+
+		/* Set request source and burst length for allocated channels */
+		switch (drv_data->pdev->id) {
+		case 1:
+			/* Using SPI1 */
+			RSSR(drv_data->rx_channel) = DMA_REQ_SPI1_R;
+			RSSR(drv_data->tx_channel) = DMA_REQ_SPI1_T;
+			break;
+		case 2:
+			/* Using SPI2 */
+			RSSR(drv_data->rx_channel) = DMA_REQ_SPI2_R;
+			RSSR(drv_data->tx_channel) = DMA_REQ_SPI2_T;
+			break;
+		default:
+			dev_err(dev, "probe - bad SPI Id\n");
+			imx_dma_free(drv_data->rx_channel);
+			imx_dma_free(drv_data->tx_channel);
+			status = -ENODEV;
+			goto err_no_devid;
+		}
+		BLR(drv_data->rx_channel) = SPI_DMA_BLR;
+		BLR(drv_data->tx_channel) = SPI_DMA_BLR;
+	}
+
+	/* Load default SPI configuration */
+	writel(SPI_RESET_START, drv_data->regs + SPI_RESET);
+	writel(0, drv_data->regs + SPI_RESET);
+	writel(SPI_DEFAULT_CONTROL, drv_data->regs + SPI_CONTROL);
+
+	/* Initial and start queue */
+	status = init_queue(drv_data);
+	if (status != 0) {
+		dev_err(&pdev->dev, "probe - problem initializing queue\n");
+		goto err_init_queue;
+	}
+	status = start_queue(drv_data);
+	if (status != 0) {
+		dev_err(&pdev->dev, "probe - problem starting queue\n");
+		goto err_start_queue;
+	}
+
+	/* Register with the SPI framework */
+	platform_set_drvdata(pdev, drv_data);
+	status = spi_register_master(master);
+	if (status != 0) {
+		dev_err(&pdev->dev, "probe - problem registering spi master\n");
+		goto err_spi_register;
+	}
+
+	dev_dbg(dev, "probe succeded\n");
+	return 0;
+
+err_init_queue:
+err_start_queue:
+err_spi_register:
+	destroy_queue(drv_data);
+
+err_no_rxdma:
+err_no_txdma:
+err_no_devid:
+	free_irq(irq, drv_data);
+
+err_no_irqres:
+	iounmap(drv_data->regs);
+
+err_no_iomap:
+	release_resource(drv_data->ioarea);
+	kfree(drv_data->ioarea);
+
+err_no_iores:
+	spi_master_put(master);
+
+err_no_pdata:
+err_no_mem:
+	return status;
+}
+
+static int __devexit spi_imx_remove(struct platform_device *pdev)
+{
+	struct driver_data *drv_data = platform_get_drvdata(pdev);
+	int irq;
+	int status = 0;
+
+	if (!drv_data)
+		return 0;
+
+	tasklet_kill(&drv_data->pump_transfers);
+
+	/* Remove the queue */
+	status = destroy_queue(drv_data);
+	if (status != 0) {
+		dev_err(&pdev->dev, "queue remove failed (%d)\n", status);
+		return status;
+	}
+
+	/* Reset SPI */
+	writel(SPI_RESET_START, drv_data->regs + SPI_RESET);
+	writel(0, drv_data->regs + SPI_RESET);
+
+	/* Release DMA */
+	if (drv_data->master_info->enable_dma) {
+		RSSR(drv_data->rx_channel) = 0;
+		RSSR(drv_data->tx_channel) = 0;
+		imx_dma_free(drv_data->tx_channel);
+		imx_dma_free(drv_data->rx_channel);
+	}
+
+	/* Release IRQ */
+	irq = platform_get_irq(pdev, 0);
+	if (irq >= 0)
+		free_irq(irq, drv_data);
+
+	/* Release map resources */
+	iounmap(drv_data->regs);
+	release_resource(drv_data->ioarea);
+	kfree(drv_data->ioarea);
+
+	/* Disconnect from the SPI framework */
+	spi_unregister_master(drv_data->master);
+	spi_master_put(drv_data->master);
+
+	/* Prevent double remove */
+	platform_set_drvdata(pdev, NULL);
+
+	dev_dbg(&pdev->dev, "remove succeded\n");
+
+	return 0;
+}
+
+static void spi_imx_shutdown(struct platform_device *pdev)
+{
+	struct driver_data *drv_data = platform_get_drvdata(pdev);
+
+	/* Reset SPI */
+	writel(SPI_RESET_START, drv_data->regs + SPI_RESET);
+	writel(0, drv_data->regs + SPI_RESET);
+
+	dev_dbg(&pdev->dev, "shutdown succeded\n");
+}
+
+#ifdef CONFIG_PM
+static int suspend_devices(struct device *dev, void *pm_message)
+{
+	pm_message_t *state = pm_message;
+
+	if (dev->power.power_state.event != state->event) {
+		dev_warn(dev, "pm state does not match request\n");
+		return -1;
+	}
+
+	return 0;
+}
+
+static int spi_imx_suspend(struct platform_device *pdev, pm_message_t state)
+{
+	struct driver_data *drv_data = platform_get_drvdata(pdev);
+	int status = 0;
+
+	status = stop_queue(drv_data);
+	if (status != 0) {
+		dev_warn(&pdev->dev, "suspend cannot stop queue\n");
+		return status;
+	}
+
+	dev_dbg(&pdev->dev, "suspended\n");
+
+	return 0;
+}
+
+static int spi_imx_resume(struct platform_device *pdev)
+{
+	struct driver_data *drv_data = platform_get_drvdata(pdev);
+	int status = 0;
+
+	/* Start the queue running */
+	status = start_queue(drv_data);
+	if (status != 0)
+		dev_err(&pdev->dev, "problem starting queue (%d)\n", status);
+	else
+		dev_dbg(&pdev->dev, "resumed\n");
+
+	return status;
+}
+#else
+#define spi_imx_suspend NULL
+#define spi_imx_resume NULL
+#endif /* CONFIG_PM */
+
+static struct platform_driver driver = {
+	.driver = {
+		.name = "imx-spi",
+		.bus = &platform_bus_type,
+		.owner = THIS_MODULE,
+	},
+	.probe = spi_imx_probe,
+	.remove = __devexit_p(spi_imx_remove),
+	.shutdown = spi_imx_shutdown,
+	.suspend = spi_imx_suspend,
+	.resume = spi_imx_resume,
+};
+
+static int __init spi_imx_init(void)
+{
+	return platform_driver_register(&driver);
+}
+module_init(spi_imx_init);
+
+static void __exit spi_imx_exit(void)
+{
+	platform_driver_unregister(&driver);
+}
+module_exit(spi_imx_exit);
+
+MODULE_AUTHOR("Andrea Paterniani, <a.paterniani@swapp-eng.it>");
+MODULE_DESCRIPTION("iMX SPI Contoller Driver");
+MODULE_LICENSE("GPL");
diff --git a/include/asm-arm/arch-imx/spi_imx.h b/include/asm-arm/arch-imx/spi_imx.h
new file mode 100644
index 000000000000..2165449e976e
--- /dev/null
+++ b/include/asm-arm/arch-imx/spi_imx.h
@@ -0,0 +1,72 @@
+/*
+ * include/asm-arm/arch-imx/spi_imx.h
+ *
+ * Copyright (C) 2006 SWAPP
+ *	Andrea Paterniani <a.paterniani@swapp-eng.it>
+ *
+ * Initial version inspired by:
+ *	linux-2.6.17-rc3-mm1/include/asm-arm/arch-pxa/pxa2xx_spi.h
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef SPI_IMX_H_
+#define SPI_IMX_H_
+
+
+/*-------------------------------------------------------------------------*/
+/**
+ * struct spi_imx_master - device.platform_data for SPI controller devices.
+ * @num_chipselect: chipselects are used to distinguish individual
+ *	SPI slaves, and are numbered from zero to num_chipselects - 1.
+ *	each slave has a chipselect signal, but it's common that not
+ *	every chipselect is connected to a slave.
+ * @enable_dma: if true enables DMA driven transfers.
+*/
+struct spi_imx_master {
+	u8 num_chipselect;
+	u8 enable_dma:1;
+};
+/*-------------------------------------------------------------------------*/
+
+
+/*-------------------------------------------------------------------------*/
+/**
+ * struct spi_imx_chip - spi_board_info.controller_data for SPI
+ * slave devices, copied to spi_device.controller_data.
+ * @enable_loopback : used for test purpouse to internally connect RX and TX
+ *	sections.
+ * @enable_dma : enables dma transfer (provided that controller driver has
+ *	dma enabled too).
+ * @ins_ss_pulse : enable /SS pulse insertion between SPI burst.
+ * @bclk_wait : number of bclk waits between each bits_per_word SPI burst.
+ * @cs_control : function pointer to board-specific function to assert/deassert
+ *	I/O port to control HW generation of devices chip-select.
+*/
+struct spi_imx_chip {
+	u8	enable_loopback:1;
+	u8	enable_dma:1;
+	u8	ins_ss_pulse:1;
+	u16	bclk_wait:15;
+	void (*cs_control)(u32 control);
+};
+
+/* Chip-select state */
+#define SPI_CS_ASSERT			(1 << 0)
+#define SPI_CS_DEASSERT			(1 << 1)
+/*-------------------------------------------------------------------------*/
+
+
+#endif /* SPI_IMX_H_*/
-- 
cgit v1.2.3


From 4c20386c8d0719b42503efe65abe47ad3fb3d711 Mon Sep 17 00:00:00 2001
From: David Brownell <david-b@pacbell.net>
Date: Mon, 12 Feb 2007 00:53:11 -0800
Subject: [PATCH] GPIO core

This defines a simple and minimalist programming interface for GPIO APIs:

  - Documentation/gpio.txt ... describes things (read it)

  - include/asm-arm/gpio.h ... defines the ARM hook, which just punts
    to <asm/arch/gpio.h> for any implementation

  - include/asm-generic/gpio.h ... implement "can sleep" variants as calling
    the normal ones, for systems that don't handle i2c expanders.

The immediate need for such a cross-architecture API convention is to support
drivers that work the same on AT91 ARM and AVR32 AP7000 chips, which embed many
of the same controllers but have different CPUs.  However, several other users
have been reported, including a driver for a hardware watchdog chip and some
handhelds.org multi-CPU button drivers.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
---
 Documentation/gpio.txt     | 271 +++++++++++++++++++++++++++++++++++++++++++++
 include/asm-arm/gpio.h     |   7 ++
 include/asm-generic/gpio.h |  25 +++++
 3 files changed, 303 insertions(+)
 create mode 100644 Documentation/gpio.txt
 create mode 100644 include/asm-arm/gpio.h
 create mode 100644 include/asm-generic/gpio.h

(limited to 'include/asm-arm')

diff --git a/Documentation/gpio.txt b/Documentation/gpio.txt
new file mode 100644
index 000000000000..09dd510c4a5f
--- /dev/null
+++ b/Documentation/gpio.txt
@@ -0,0 +1,271 @@
+GPIO Interfaces
+
+This provides an overview of GPIO access conventions on Linux.
+
+
+What is a GPIO?
+===============
+A "General Purpose Input/Output" (GPIO) is a flexible software-controlled
+digital signal.  They are provided from many kinds of chip, and are familiar
+to Linux developers working with embedded and custom hardware.  Each GPIO
+represents a bit connected to a particular pin, or "ball" on Ball Grid Array
+(BGA) packages.  Board schematics show which external hardware connects to
+which GPIOs.  Drivers can be written generically, so that board setup code
+passes such pin configuration data to drivers.
+
+System-on-Chip (SOC) processors heavily rely on GPIOs.  In some cases, every
+non-dedicated pin can be configured as a GPIO; and most chips have at least
+several dozen of them.  Programmable logic devices (like FPGAs) can easily
+provide GPIOs; multifunction chips like power managers, and audio codecs
+often have a few such pins to help with pin scarcity on SOCs; and there are
+also "GPIO Expander" chips that connect using the I2C or SPI serial busses.
+Most PC southbridges have a few dozen GPIO-capable pins (with only the BIOS
+firmware knowing how they're used).
+
+The exact capabilities of GPIOs vary between systems.  Common options:
+
+  - Output values are writable (high=1, low=0).  Some chips also have
+    options about how that value is driven, so that for example only one
+    value might be driven ... supporting "wire-OR" and similar schemes
+    for the other value.
+
+  - Input values are likewise readable (1, 0).  Some chips support readback
+    of pins configured as "output", which is very useful in such "wire-OR"
+    cases (to support bidirectional signaling).  GPIO controllers may have
+    input de-glitch logic, sometimes with software controls.
+
+  - Inputs can often be used as IRQ signals, often edge triggered but
+    sometimes level triggered.  Such IRQs may be configurable as system
+    wakeup events, to wake the system from a low power state.
+
+  - Usually a GPIO will be configurable as either input or output, as needed
+    by different product boards; single direction ones exist too.
+
+  - Most GPIOs can be accessed while holding spinlocks, but those accessed
+    through a serial bus normally can't.  Some systems support both types.
+
+On a given board each GPIO is used for one specific purpose like monitoring
+MMC/SD card insertion/removal, detecting card writeprotect status, driving
+a LED, configuring a transceiver, bitbanging a serial bus, poking a hardware
+watchdog, sensing a switch, and so on.
+
+
+GPIO conventions
+================
+Note that this is called a "convention" because you don't need to do it this
+way, and it's no crime if you don't.  There **are** cases where portability
+is not the main issue; GPIOs are often used for the kind of board-specific
+glue logic that may even change between board revisions, and can't ever be
+used on a board that's wired differently.  Only least-common-denominator
+functionality can be very portable.  Other features are platform-specific,
+and that can be critical for glue logic.
+
+Plus, this doesn't define an implementation framework, just an interface.
+One platform might implement it as simple inline functions accessing chip
+registers; another might implement it by delegating through abstractions
+used for several very different kinds of GPIO controller.
+
+That said, if the convention is supported on their platform, drivers should
+use it when possible:
+
+	#include <asm/gpio.h>
+
+If you stick to this convention then it'll be easier for other developers to
+see what your code is doing, and help maintain it.
+
+
+Identifying GPIOs
+-----------------
+GPIOs are identified by unsigned integers in the range 0..MAX_INT.  That
+reserves "negative" numbers for other purposes like marking signals as
+"not available on this board", or indicating faults.
+
+Platforms define how they use those integers, and usually #define symbols
+for the GPIO lines so that board-specific setup code directly corresponds
+to the relevant schematics.  In contrast, drivers should only use GPIO
+numbers passed to them from that setup code, using platform_data to hold
+board-specific pin configuration data (along with other board specific
+data they need).  That avoids portability problems.
+
+So for example one platform uses numbers 32-159 for GPIOs; while another
+uses numbers 0..63 with one set of GPIO controllers, 64-79 with another
+type of GPIO controller, and on one particular board 80-95 with an FPGA.
+The numbers need not be contiguous; either of those platforms could also
+use numbers 2000-2063 to identify GPIOs in a bank of I2C GPIO expanders.
+
+Whether a platform supports multiple GPIO controllers is currently a
+platform-specific implementation issue.
+
+
+Using GPIOs
+-----------
+One of the first things to do with a GPIO, often in board setup code when
+setting up a platform_device using the GPIO, is mark its direction:
+
+	/* set as input or output, returning 0 or negative errno */
+	int gpio_direction_input(unsigned gpio);
+	int gpio_direction_output(unsigned gpio);
+
+The return value is zero for success, else a negative errno.  It should
+be checked, since the get/set calls don't have error returns and since
+misconfiguration is possible.  (These calls could sleep.)
+
+Setting the direction can fail if the GPIO number is invalid, or when
+that particular GPIO can't be used in that mode.  It's generally a bad
+idea to rely on boot firmware to have set the direction correctly, since
+it probably wasn't validated to do more than boot Linux.  (Similarly,
+that board setup code probably needs to multiplex that pin as a GPIO,
+and configure pullups/pulldowns appropriately.)
+
+
+Spinlock-Safe GPIO access
+-------------------------
+Most GPIO controllers can be accessed with memory read/write instructions.
+That doesn't need to sleep, and can safely be done from inside IRQ handlers.
+
+Use these calls to access such GPIOs:
+
+	/* GPIO INPUT:  return zero or nonzero */
+	int gpio_get_value(unsigned gpio);
+
+	/* GPIO OUTPUT */
+	void gpio_set_value(unsigned gpio, int value);
+
+The values are boolean, zero for low, nonzero for high.  When reading the
+value of an output pin, the value returned should be what's seen on the
+pin ... that won't always match the specified output value, because of
+issues including wire-OR and output latencies.
+
+The get/set calls have no error returns because "invalid GPIO" should have
+been reported earlier in gpio_set_direction().  However, note that not all
+platforms can read the value of output pins; those that can't should always
+return zero.  Also, these calls will be ignored for GPIOs that can't safely
+be accessed wihtout sleeping (see below).
+
+Platform-specific implementations are encouraged to optimise the two
+calls to access the GPIO value in cases where the GPIO number (and for
+output, value) are constant.  It's normal for them to need only a couple
+of instructions in such cases (reading or writing a hardware register),
+and not to need spinlocks.  Such optimized calls can make bitbanging
+applications a lot more efficient (in both space and time) than spending
+dozens of instructions on subroutine calls.
+
+
+GPIO access that may sleep
+--------------------------
+Some GPIO controllers must be accessed using message based busses like I2C
+or SPI.  Commands to read or write those GPIO values require waiting to
+get to the head of a queue to transmit a command and get its response.
+This requires sleeping, which can't be done from inside IRQ handlers.
+
+Platforms that support this type of GPIO distinguish them from other GPIOs
+by returning nonzero from this call:
+
+	int gpio_cansleep(unsigned gpio);
+
+To access such GPIOs, a different set of accessors is defined:
+
+	/* GPIO INPUT:  return zero or nonzero, might sleep */
+	int gpio_get_value_cansleep(unsigned gpio);
+
+	/* GPIO OUTPUT, might sleep */
+	void gpio_set_value_cansleep(unsigned gpio, int value);
+
+Other than the fact that these calls might sleep, and will not be ignored
+for GPIOs that can't be accessed from IRQ handlers, these calls act the
+same as the spinlock-safe calls.
+
+
+Claiming and Releasing GPIOs (OPTIONAL)
+---------------------------------------
+To help catch system configuration errors, two calls are defined.
+However, many platforms don't currently support this mechanism.
+
+	/* request GPIO, returning 0 or negative errno.
+	 * non-null labels may be useful for diagnostics.
+	 */
+	int gpio_request(unsigned gpio, const char *label);
+
+	/* release previously-claimed GPIO */
+	void gpio_free(unsigned gpio);
+
+Passing invalid GPIO numbers to gpio_request() will fail, as will requesting
+GPIOs that have already been claimed with that call.  The return value of
+gpio_request() must be checked.  (These calls could sleep.)
+
+These calls serve two basic purposes.  One is marking the signals which
+are actually in use as GPIOs, for better diagnostics; systems may have
+several hundred potential GPIOs, but often only a dozen are used on any
+given board.  Another is to catch conflicts between drivers, reporting
+errors when drivers wrongly think they have exclusive use of that signal.
+
+These two calls are optional because not not all current Linux platforms
+offer such functionality in their GPIO support; a valid implementation
+could return success for all gpio_request() calls.  Unlike the other calls,
+the state they represent doesn't normally match anything from a hardware
+register; it's just a software bitmap which clearly is not necessary for
+correct operation of hardware or (bug free) drivers.
+
+Note that requesting a GPIO does NOT cause it to be configured in any
+way; it just marks that GPIO as in use.  Separate code must handle any
+pin setup (e.g. controlling which pin the GPIO uses, pullup/pulldown).
+
+
+GPIOs mapped to IRQs
+--------------------
+GPIO numbers are unsigned integers; so are IRQ numbers.  These make up
+two logically distinct namespaces (GPIO 0 need not use IRQ 0).  You can
+map between them using calls like:
+
+	/* map GPIO numbers to IRQ numbers */
+	int gpio_to_irq(unsigned gpio);
+
+	/* map IRQ numbers to GPIO numbers */
+	int irq_to_gpio(unsigned irq);
+
+Those return either the corresponding number in the other namespace, or
+else a negative errno code if the mapping can't be done.  (For example,
+some GPIOs can't used as IRQs.)  It is an unchecked error to use a GPIO
+number that hasn't been marked as an input using gpio_set_direction(), or
+to use an IRQ number that didn't originally come from gpio_to_irq().
+
+These two mapping calls are expected to cost on the order of a single
+addition or subtraction.  They're not allowed to sleep.
+
+Non-error values returned from gpio_to_irq() can be passed to request_irq()
+or free_irq().  They will often be stored into IRQ resources for platform
+devices, by the board-specific initialization code.  Note that IRQ trigger
+options are part of the IRQ interface, e.g. IRQF_TRIGGER_FALLING, as are
+system wakeup capabilities.
+
+Non-error values returned from irq_to_gpio() would most commonly be used
+with gpio_get_value().
+
+
+
+What do these conventions omit?
+===============================
+One of the biggest things these conventions omit is pin multiplexing, since
+this is highly chip-specific and nonportable.  One platform might not need
+explicit multiplexing; another might have just two options for use of any
+given pin; another might have eight options per pin; another might be able
+to route a given GPIO to any one of several pins.  (Yes, those examples all
+come from systems that run Linux today.)
+
+Related to multiplexing is configuration and enabling of the pullups or
+pulldowns integrated on some platforms.  Not all platforms support them,
+or support them in the same way; and any given board might use external
+pullups (or pulldowns) so that the on-chip ones should not be used.
+
+There are other system-specific mechanisms that are not specified here,
+like the aforementioned options for input de-glitching and wire-OR output.
+Hardware may support reading or writing GPIOs in gangs, but that's usually
+configuration dependednt:  for GPIOs sharing the same bank.  (GPIOs are
+commonly grouped in banks of 16 or 32, with a given SOC having several such
+banks.)  Code relying on such mechanisms will necessarily be nonportable.
+
+Dynamic definition of GPIOs is not currently supported; for example, as
+a side effect of configuring an add-on board with some GPIO expanders.
+
+These calls are purely for kernel space, but a userspace API could be built
+on top of it.
diff --git a/include/asm-arm/gpio.h b/include/asm-arm/gpio.h
new file mode 100644
index 000000000000..fff4f800ee42
--- /dev/null
+++ b/include/asm-arm/gpio.h
@@ -0,0 +1,7 @@
+#ifndef _ARCH_ARM_GPIO_H
+#define _ARCH_ARM_GPIO_H
+
+/* not all ARM platforms necessarily support this API ... */
+#include <asm/arch/gpio.h>
+
+#endif /* _ARCH_ARM_GPIO_H */
diff --git a/include/asm-generic/gpio.h b/include/asm-generic/gpio.h
new file mode 100644
index 000000000000..2d0aab1d8611
--- /dev/null
+++ b/include/asm-generic/gpio.h
@@ -0,0 +1,25 @@
+#ifndef _ASM_GENERIC_GPIO_H
+#define _ASM_GENERIC_GPIO_H
+
+/* platforms that don't directly support access to GPIOs through I2C, SPI,
+ * or other blocking infrastructure can use these wrappers.
+ */
+
+static inline int gpio_cansleep(unsigned gpio)
+{
+	return 0;
+}
+
+static inline int gpio_get_value_cansleep(unsigned gpio)
+{
+	might_sleep();
+	return gpio_get_value(gpio);
+}
+
+static inline void gpio_set_value_cansleep(unsigned gpio, int value)
+{
+	might_sleep();
+	gpio_set_value(gpio, value);
+}
+
+#endif /* _ASM_GENERIC_GPIO_H */
-- 
cgit v1.2.3


From 3c729f1ecd23b86a2d6b211d646f57f9da8dfeb1 Mon Sep 17 00:00:00 2001
From: David Brownell <david-b@pacbell.net>
Date: Mon, 12 Feb 2007 00:53:12 -0800
Subject: [PATCH] OMAP GPIO wrappers

This teaches OMAP how to implement the cross-platform GPIO interfaces.

[akpm@osdl.org: cleanups]
Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
---
 include/asm-arm/arch-omap/gpio.h | 66 ++++++++++++++++++++++++++++++++++++++++
 1 file changed, 66 insertions(+)

(limited to 'include/asm-arm')

diff --git a/include/asm-arm/arch-omap/gpio.h b/include/asm-arm/arch-omap/gpio.h
index f486b72070ea..3762a6ae6a7f 100644
--- a/include/asm-arm/arch-omap/gpio.h
+++ b/include/asm-arm/arch-omap/gpio.h
@@ -76,4 +76,70 @@ extern void omap_set_gpio_direction(int gpio, int is_input);
 extern void omap_set_gpio_dataout(int gpio, int enable);
 extern int omap_get_gpio_datain(int gpio);
 
+/*-------------------------------------------------------------------------*/
+
+/* wrappers for "new style" GPIO calls. the old OMAP-specfic ones should
+ * eventually be removed (along with this errno.h inclusion), and maybe
+ * gpios should put MPUIOs last too.
+ */
+
+#include <asm/errno.h>
+
+static inline int gpio_request(unsigned gpio, const char *label)
+{
+	return omap_request_gpio(gpio);
+}
+
+static inline void gpio_free(unsigned gpio)
+{
+	omap_free_gpio(gpio);
+}
+
+static inline int __gpio_set_direction(unsigned gpio, int is_input)
+{
+	if (cpu_class_is_omap2()) {
+		if (gpio > OMAP_MAX_GPIO_LINES)
+			return -EINVAL;
+	} else {
+		if (gpio > (OMAP_MAX_GPIO_LINES + 16 /* MPUIO */))
+			return -EINVAL;
+	}
+	omap_set_gpio_direction(gpio, is_input);
+	return 0;
+}
+
+static inline int gpio_direction_input(unsigned gpio)
+{
+	return __gpio_set_direction(gpio, 1);
+}
+
+static inline int gpio_direction_output(unsigned gpio)
+{
+	return __gpio_set_direction(gpio, 0);
+}
+
+static inline int gpio_get_value(unsigned gpio)
+{
+	return omap_get_gpio_datain(gpio);
+}
+
+static inline void gpio_set_value(unsigned gpio, int value)
+{
+	omap_set_gpio_dataout(gpio, value);
+}
+
+#include <asm-generic/gpio.h>		/* cansleep wrappers */
+
+static inline int gpio_to_irq(unsigned gpio)
+{
+	return OMAP_GPIO_IRQ(gpio);
+}
+
+static inline int irq_to_gpio(unsigned irq)
+{
+	if (cpu_class_is_omap1() && (irq < (IH_MPUIO_BASE + 16)))
+		return (irq - IH_MPUIO_BASE) + OMAP_MAX_GPIO_LINES;
+	return irq - IH_GPIO_BASE;
+}
+
 #endif
-- 
cgit v1.2.3


From a31c4eea2127ee52b5c7c1befada4664963ad030 Mon Sep 17 00:00:00 2001
From: David Brownell <david-b@pacbell.net>
Date: Mon, 12 Feb 2007 00:53:13 -0800
Subject: [PATCH] AT91 GPIO wrappers

This is a first cut at making the AT91 code use the generic GPIO calls.

Note that the original AT91 GPIO calls merged the "mux pin as GPIO" and "set
GPIO direction" functionality into one API call, contrary to what's specified
as a cross-platform portable model.  So this involved a few non-inlinable
functions.

[akpm@osdl.org: cleanups]
Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
---
 arch/arm/mach-at91rm9200/gpio.c        | 48 ++++++++++++++++++++++++++++++++++
 include/asm-arm/arch-at91rm9200/gpio.h | 48 ++++++++++++++++++++++++++++++++--
 2 files changed, 94 insertions(+), 2 deletions(-)

(limited to 'include/asm-arm')

diff --git a/arch/arm/mach-at91rm9200/gpio.c b/arch/arm/mach-at91rm9200/gpio.c
index af22659c8a28..15eb5b6b29f2 100644
--- a/arch/arm/mach-at91rm9200/gpio.c
+++ b/arch/arm/mach-at91rm9200/gpio.c
@@ -64,6 +64,24 @@ static inline unsigned pin_to_mask(unsigned pin)
  */
 
 
+/*
+ * mux the pin to the "GPIO" peripheral role.
+ */
+int __init_or_module at91_set_GPIO_periph(unsigned pin, int use_pullup)
+{
+	void __iomem	*pio = pin_to_controller(pin);
+	unsigned	mask = pin_to_mask(pin);
+
+	if (!pio)
+		return -EINVAL;
+	__raw_writel(mask, pio + PIO_IDR);
+	__raw_writel(mask, pio + (use_pullup ? PIO_PUER : PIO_PUDR));
+	__raw_writel(mask, pio + PIO_PER);
+	return 0;
+}
+EXPORT_SYMBOL(at91_set_GPIO_periph);
+
+
 /*
  * mux the pin to the "A" internal peripheral role.
  */
@@ -181,6 +199,36 @@ EXPORT_SYMBOL(at91_set_multi_drive);
 
 /*--------------------------------------------------------------------------*/
 
+/* new-style GPIO calls; these expect at91_set_GPIO_periph to have been
+ * called, and maybe at91_set_multi_drive() for putout pins.
+ */
+
+int gpio_direction_input(unsigned pin)
+{
+	void __iomem	*pio = pin_to_controller(pin);
+	unsigned	mask = pin_to_mask(pin);
+
+	if (!pio || !(__raw_readl(pio + PIO_PSR) & mask))
+		return -EINVAL;
+	__raw_writel(mask, pio + PIO_OER);
+	return 0;
+}
+EXPORT_SYMBOL(gpio_direction_input);
+
+int gpio_direction_output(unsigned pin)
+{
+	void __iomem	*pio = pin_to_controller(pin);
+	unsigned	mask = pin_to_mask(pin);
+
+	if (!pio || !(__raw_readl(pio + PIO_PSR) & mask))
+		return -EINVAL;
+	__raw_writel(mask, pio + PIO_OER);
+	return 0;
+}
+EXPORT_SYMBOL(gpio_direction_output);
+
+/*--------------------------------------------------------------------------*/
+
 /*
  * assuming the pin is muxed as a gpio output, set its value.
  */
diff --git a/include/asm-arm/arch-at91rm9200/gpio.h b/include/asm-arm/arch-at91rm9200/gpio.h
index a011d27876a2..e09d6528fadf 100644
--- a/include/asm-arm/arch-at91rm9200/gpio.h
+++ b/include/asm-arm/arch-at91rm9200/gpio.h
@@ -179,6 +179,7 @@
 
 #ifndef __ASSEMBLY__
 /* setup setup routines, called from board init or driver probe() */
+extern int __init_or_module at91_set_GPIO_periph(unsigned pin, int use_pullup);
 extern int __init_or_module at91_set_A_periph(unsigned pin, int use_pullup);
 extern int __init_or_module at91_set_B_periph(unsigned pin, int use_pullup);
 extern int __init_or_module at91_set_gpio_input(unsigned pin, int use_pullup);
@@ -193,7 +194,50 @@ extern int at91_get_gpio_value(unsigned pin);
 /* callable only from core power-management code */
 extern void at91_gpio_suspend(void);
 extern void at91_gpio_resume(void);
-#endif
 
-#endif
+/*-------------------------------------------------------------------------*/
+
+/* wrappers for "new style" GPIO calls. the old AT91-specfic ones should
+ * eventually be removed (along with this errno.h inclusion), and the
+ * gpio request/free calls should probably be implemented.
+ */
+
+#include <asm/errno.h>
+
+static inline int gpio_request(unsigned gpio, const char *label)
+{
+	return 0;
+}
+
+static inline void gpio_free(unsigned gpio)
+{
+}
+
+extern int gpio_direction_input(unsigned gpio);
+extern int gpio_direction_output(unsigned gpio);
 
+static inline int gpio_get_value(unsigned gpio)
+{
+	return at91_get_gpio_value(gpio);
+}
+
+static inline void gpio_set_value(unsigned gpio, int value)
+{
+	at91_set_gpio_value(gpio, value);
+}
+
+#include <asm-generic/gpio.h>		/* cansleep wrappers */
+
+static inline int gpio_to_irq(unsigned gpio)
+{
+	return gpio;
+}
+
+static inline int irq_to_gpio(unsigned irq)
+{
+	return irq;
+}
+
+#endif	/* __ASSEMBLY__ */
+
+#endif
-- 
cgit v1.2.3


From 8a898f1c366c858f8dbcb667c1cfcc282b727795 Mon Sep 17 00:00:00 2001
From: Philipp Zabel <philipp.zabel@gmail.com>
Date: Mon, 12 Feb 2007 00:53:14 -0800
Subject: [PATCH] PXA GPIO wrappers

Arch-neutral GPIO calls for PXA.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
---
 include/asm-arm/arch-pxa/gpio.h | 72 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 72 insertions(+)
 create mode 100644 include/asm-arm/arch-pxa/gpio.h

(limited to 'include/asm-arm')

diff --git a/include/asm-arm/arch-pxa/gpio.h b/include/asm-arm/arch-pxa/gpio.h
new file mode 100644
index 000000000000..e67c23821017
--- /dev/null
+++ b/include/asm-arm/arch-pxa/gpio.h
@@ -0,0 +1,72 @@
+/*
+ * linux/include/asm-arm/arch-pxa/gpio.h
+ *
+ * PXA GPIO wrappers for arch-neutral GPIO calls
+ *
+ * Written by Philipp Zabel <philipp.zabel@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#ifndef __ASM_ARCH_PXA_GPIO_H
+#define __ASM_ARCH_PXA_GPIO_H
+
+#include <asm/arch/pxa-regs.h>
+#include <asm/arch/irqs.h>
+#include <asm/arch/hardware.h>
+
+#include <asm/errno.h>
+
+static inline int gpio_request(unsigned gpio, const char *label)
+{
+	return 0;
+}
+
+static inline void gpio_free(unsigned gpio)
+{
+	return;
+}
+
+static inline int gpio_direction_input(unsigned gpio)
+{
+	if (gpio > PXA_LAST_GPIO)
+		return -EINVAL;
+	pxa_gpio_mode(gpio | GPIO_IN);
+}
+
+static inline int gpio_direction_output(unsigned gpio)
+{
+	if (gpio > PXA_LAST_GPIO)
+		return -EINVAL;
+	pxa_gpio_mode(gpio | GPIO_OUT);
+}
+
+/* REVISIT these macros are correct, but suffer code explosion
+ * for non-constant parameters.  Provide out-line versions too.
+ */
+#define gpio_get_value(gpio) \
+	(GPLR(gpio) & GPIO_bit(gpio))
+
+#define gpio_set_value(gpio,value) \
+	((value) ? (GPSR(gpio) = GPIO_bit(gpio)):(GPCR(gpio) = GPIO_bit(gpio)))
+
+#include <asm-generic/gpio.h>			/* cansleep wrappers */
+
+#define gpio_to_irq(gpio)	IRQ_GPIO(gpio)
+#define irq_to_gpio(irq)	IRQ_TO_GPIO(irq)
+
+
+#endif
-- 
cgit v1.2.3


From 920fe7a8d0aba9782d1f924a02ece146acbf6686 Mon Sep 17 00:00:00 2001
From: Philipp Zabel <philipp.zabel@gmail.com>
Date: Mon, 12 Feb 2007 00:53:14 -0800
Subject: [PATCH] SA1100 GPIO wrappers

Arch-neutral GPIO calls for SA-1100.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
---
 include/asm-arm/arch-sa1100/gpio.h | 81 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 81 insertions(+)
 create mode 100644 include/asm-arm/arch-sa1100/gpio.h

(limited to 'include/asm-arm')

diff --git a/include/asm-arm/arch-sa1100/gpio.h b/include/asm-arm/arch-sa1100/gpio.h
new file mode 100644
index 000000000000..a331fe3f6e48
--- /dev/null
+++ b/include/asm-arm/arch-sa1100/gpio.h
@@ -0,0 +1,81 @@
+/*
+ * linux/include/asm-arm/arch-pxa/gpio.h
+ *
+ * SA1100 GPIO wrappers for arch-neutral GPIO calls
+ *
+ * Written by Philipp Zabel <philipp.zabel@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#ifndef __ASM_ARCH_SA1100_GPIO_H
+#define __ASM_ARCH_SA1100_GPIO_H
+
+#include <asm/arch/SA-1100.h>
+#include <asm/arch/irqs.h>
+#include <asm/arch/hardware.h>
+
+#include <asm/errno.h>
+
+static inline int gpio_request(unsigned gpio, const char *label)
+{
+	return 0;
+}
+
+static inline void gpio_free(unsigned gpio)
+{
+	return;
+}
+
+static inline int gpio_direction_input(unsigned gpio)
+{
+	if (gpio > GPIO_MAX)
+		return -EINVAL;
+	GPDR = (GPDR_In << gpio) 0
+}
+
+static inline int gpio_direction_output(unsigned gpio)
+{
+	if (gpio > GPIO_MAX)
+		return -EINVAL;
+	GPDR = (GPDR_Out << gpio) 0
+}
+
+#define gpio_get_value(gpio) \
+	(GPLR & GPIO_GPIO(gpio))
+
+#define gpio_set_value(gpio,value) \
+	((value) ? (GPSR = GPIO_GPIO(gpio)) : (GPCR(gpio) = GPIO_GPIO(gpio)))
+
+#include <asm-generic/gpio.h>			/* cansleep wrappers */
+
+static inline unsigned gpio_to_irq(unsigned gpio)
+{
+	if (gpio < 11)
+		return IRQ_GPIO0 + gpio;
+	else
+		return IRQ_GPIO11 - 11 + gpio;
+}
+
+static inline unsigned irq_to_gpio(unsigned irq)
+{
+	if (irq < IRQ_GPIO11_27)
+		return irq - IRQ_GPIO0;
+	else
+		return irq - IRQ_GPIO11 + 11;
+}
+
+#endif
-- 
cgit v1.2.3


From 390414badebe45a2f556a04ece1fd99191aa6397 Mon Sep 17 00:00:00 2001
From: Philipp Zabel <philipp.zabel@gmail.com>
Date: Mon, 12 Feb 2007 00:53:15 -0800
Subject: [PATCH] S3C2410 GPIO wrappers

Arch-neutral GPIO calls for S3C24xx.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
---
 include/asm-arm/arch-s3c2410/gpio.h | 65 +++++++++++++++++++++++++++++++++++++
 1 file changed, 65 insertions(+)
 create mode 100644 include/asm-arm/arch-s3c2410/gpio.h

(limited to 'include/asm-arm')

diff --git a/include/asm-arm/arch-s3c2410/gpio.h b/include/asm-arm/arch-s3c2410/gpio.h
new file mode 100644
index 000000000000..67b8b9ab22e9
--- /dev/null
+++ b/include/asm-arm/arch-s3c2410/gpio.h
@@ -0,0 +1,65 @@
+/*
+ * linux/include/asm-arm/arch-pxa/gpio.h
+ *
+ * S3C2400 GPIO wrappers for arch-neutral GPIO calls
+ *
+ * Written by Philipp Zabel <philipp.zabel@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#ifndef __ASM_ARCH_PXA_GPIO_H
+#define __ASM_ARCH_PXA_GPIO_H
+
+#include <asm/arch/pxa-regs.h>
+#include <asm/arch/irqs.h>
+#include <asm/arch/hardware.h>
+
+#include <asm/errno.h>
+
+static inline int gpio_request(unsigned gpio, const char *label)
+{
+	return 0;
+}
+
+static inline void gpio_free(unsigned gpio)
+{
+	return;
+}
+
+static inline int gpio_direction_input(unsigned gpio)
+{
+	s3c2410_gpio_cfgpin(gpio, S3C2410_GPIO_INPUT);
+	return 0;
+}
+
+static inline int gpio_direction_output(unsigned gpio)
+{
+	s3c2410_gpio_cfgpin(gpio, S3C2410_GPIO_OUTPUT);
+	return 0;
+}
+
+#define gpio_get_value(gpio)		s3c2410_gpio_getpin(gpio)
+#define gpio_set_value(gpio,value)	s3c2410_gpio_setpin(gpio, value)
+
+#include <asm-generic/gpio.h>			/* cansleep wrappers */
+
+/* FIXME or maybe s3c2400_gpio_getirq() ... */
+#define gpio_to_irq(gpio)		s3c2410_gpio_getirq(gpio)
+
+/* FIXME implement irq_to_gpio() */
+
+#endif
-- 
cgit v1.2.3


From c5a69d57eb48e36f84c0737b5b24ec277d7dbfba Mon Sep 17 00:00:00 2001
From: Tobias Klauser <tklauser@distanz.ch>
Date: Sat, 17 Feb 2007 20:11:19 +0100
Subject: Storage class should be before const qualifier

The C99 specification states in section 6.11.5:

The placement of a storage-class specifier other than at the
beginning of the declaration specifiers in a declaration is an
obsolescent feature.

Signed-off-by: Tobias Klauser <tklauser@distanz.ch>
Signed-off-by: Adrian Bunk <bunk@stusta.de>
---
 arch/mips/kernel/machine_kexec.c                  |  4 ++--
 arch/powerpc/kernel/rtas.c                        |  2 +-
 arch/sh/kernel/cpu/sh2/clock-sh7619.c             |  4 ++--
 arch/sh/kernel/cpu/sh2a/clock-sh7206.c            |  4 ++--
 drivers/ieee1394/ohci1394.c                       |  2 +-
 drivers/input/serio/libps2.c                      |  2 +-
 drivers/media/video/pvrusb2/pvrusb2-audio.c       |  2 +-
 drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c |  2 +-
 drivers/media/video/pvrusb2/pvrusb2-std.c         |  4 ++--
 drivers/media/video/pvrusb2/pvrusb2-tuner.c       |  2 +-
 drivers/media/video/pvrusb2/pvrusb2-video-v4l.c   |  2 +-
 drivers/media/video/pvrusb2/pvrusb2-wm8775.c      |  2 +-
 drivers/scsi/arm/eesox.c                          |  2 +-
 fs/cifs/cifssmb.c                                 |  4 ++--
 include/asm-arm/uaccess.h                         |  6 +++---
 include/asm-arm26/uaccess.h                       | 10 +++++-----
 include/asm-ia64/kexec.h                          |  2 +-
 17 files changed, 28 insertions(+), 28 deletions(-)

(limited to 'include/asm-arm')

diff --git a/arch/mips/kernel/machine_kexec.c b/arch/mips/kernel/machine_kexec.c
index e0ad754c7edd..8f42fa85ac9e 100644
--- a/arch/mips/kernel/machine_kexec.c
+++ b/arch/mips/kernel/machine_kexec.c
@@ -13,8 +13,8 @@
 #include <asm/cacheflush.h>
 #include <asm/page.h>
 
-const extern unsigned char relocate_new_kernel[];
-const extern unsigned int relocate_new_kernel_size;
+extern const unsigned char relocate_new_kernel[];
+extern const unsigned int relocate_new_kernel_size;
 
 extern unsigned long kexec_start_address;
 extern unsigned long kexec_indirection_page;
diff --git a/arch/powerpc/kernel/rtas.c b/arch/powerpc/kernel/rtas.c
index 76b5d7ebdcc6..9d0735a54564 100644
--- a/arch/powerpc/kernel/rtas.c
+++ b/arch/powerpc/kernel/rtas.c
@@ -182,7 +182,7 @@ void rtas_progress(char *s, unsigned short hex)
 	char *os;
 	static int display_character, set_indicator;
 	static int display_width, display_lines, form_feed;
-	const static int *row_width;
+	static const int *row_width;
 	static DEFINE_SPINLOCK(progress_lock);
 	static int current_line;
 	static int pending_newline = 0;  /* did last write end with unprinted newline? */
diff --git a/arch/sh/kernel/cpu/sh2/clock-sh7619.c b/arch/sh/kernel/cpu/sh2/clock-sh7619.c
index d0440b269702..d2c157917999 100644
--- a/arch/sh/kernel/cpu/sh2/clock-sh7619.c
+++ b/arch/sh/kernel/cpu/sh2/clock-sh7619.c
@@ -18,8 +18,8 @@
 #include <asm/freq.h>
 #include <asm/io.h>
 
-const static int pll1rate[]={1,2};
-const static int pfc_divisors[]={1,2,0,4};
+static const int pll1rate[] = {1,2};
+static const int pfc_divisors[] = {1,2,0,4};
 
 #if (CONFIG_SH_CLK_MD == 1) || (CONFIG_SH_CLK_MD == 2)
 #define PLL2 (4)
diff --git a/arch/sh/kernel/cpu/sh2a/clock-sh7206.c b/arch/sh/kernel/cpu/sh2a/clock-sh7206.c
index a9ad309c6a33..82d7f991ef6b 100644
--- a/arch/sh/kernel/cpu/sh2a/clock-sh7206.c
+++ b/arch/sh/kernel/cpu/sh2a/clock-sh7206.c
@@ -18,8 +18,8 @@
 #include <asm/freq.h>
 #include <asm/io.h>
 
-const static int pll1rate[]={1,2,3,4,6,8};
-const static int pfc_divisors[]={1,2,3,4,6,8,12};
+static const int pll1rate[]={1,2,3,4,6,8};
+static const int pfc_divisors[]={1,2,3,4,6,8,12};
 #define ifc_divisors pfc_divisors
 
 #if (CONFIG_SH_CLK_MD == 2)
diff --git a/drivers/ieee1394/ohci1394.c b/drivers/ieee1394/ohci1394.c
index e982d60ac4b7..06fac0d21264 100644
--- a/drivers/ieee1394/ohci1394.c
+++ b/drivers/ieee1394/ohci1394.c
@@ -180,7 +180,7 @@ static int alloc_dma_trm_ctx(struct ti_ohci *ohci, struct dma_trm_ctx *d,
 static void ohci1394_pci_remove(struct pci_dev *pdev);
 
 #ifndef __LITTLE_ENDIAN
-const static size_t hdr_sizes[] = {
+static const size_t hdr_sizes[] = {
 	3,	/* TCODE_WRITEQ */
 	4,	/* TCODE_WRITEB */
 	3,	/* TCODE_WRITE_RESPONSE */
diff --git a/drivers/input/serio/libps2.c b/drivers/input/serio/libps2.c
index b3e84d3bb7f7..10d9d74ae43a 100644
--- a/drivers/input/serio/libps2.c
+++ b/drivers/input/serio/libps2.c
@@ -97,7 +97,7 @@ EXPORT_SYMBOL(ps2_drain);
 
 int ps2_is_keyboard_id(char id_byte)
 {
-	const static char keyboard_ids[] = {
+	static const char keyboard_ids[] = {
 		0xab,	/* Regular keyboards		*/
 		0xac,	/* NCD Sun keyboard		*/
 		0x2b,	/* Trust keyboard, translated	*/
diff --git a/drivers/media/video/pvrusb2/pvrusb2-audio.c b/drivers/media/video/pvrusb2/pvrusb2-audio.c
index 9846c464ec80..122496f36845 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-audio.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-audio.c
@@ -158,7 +158,7 @@ static unsigned int pvr2_msp3400_describe(struct pvr2_msp3400_handler *ctxt,
 }
 
 
-const static struct pvr2_i2c_handler_functions msp3400_funcs = {
+static const struct pvr2_i2c_handler_functions msp3400_funcs = {
 	.detach = (void (*)(void *))pvr2_msp3400_detach,
 	.check = (int (*)(void *))msp3400_check,
 	.update = (void (*)(void *))msp3400_update,
diff --git a/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c b/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c
index 848fb233d808..8df969c4874c 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c
@@ -226,7 +226,7 @@ static void decoder_reset(struct pvr2_v4l_cx2584x *ctxt)
 }
 
 
-const static struct pvr2_i2c_handler_functions hfuncs = {
+static const struct pvr2_i2c_handler_functions hfuncs = {
 	.detach = (void (*)(void *))decoder_detach,
 	.check = (int (*)(void *))decoder_check,
 	.update = (void (*)(void *))decoder_update,
diff --git a/drivers/media/video/pvrusb2/pvrusb2-std.c b/drivers/media/video/pvrusb2/pvrusb2-std.c
index f95c598ff627..c08925557ed4 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-std.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-std.c
@@ -78,14 +78,14 @@ struct std_name {
 #define CSTD_ALL (CSTD_PAL|CSTD_NTSC|CSTD_SECAM)
 
 /* Mapping of standard bits to color system */
-const static struct std_name std_groups[] = {
+static const struct std_name std_groups[] = {
 	{"PAL",CSTD_PAL},
 	{"NTSC",CSTD_NTSC},
 	{"SECAM",CSTD_SECAM},
 };
 
 /* Mapping of standard bits to modulation system */
-const static struct std_name std_items[] = {
+static const struct std_name std_items[] = {
 	{"B",TSTD_B},
 	{"B1",TSTD_B1},
 	{"D",TSTD_D},
diff --git a/drivers/media/video/pvrusb2/pvrusb2-tuner.c b/drivers/media/video/pvrusb2/pvrusb2-tuner.c
index af9f246f8d3f..bb17db3f6434 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-tuner.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-tuner.c
@@ -80,7 +80,7 @@ static unsigned int pvr2_tuner_describe(struct pvr2_tuner_handler *ctxt,char *bu
 }
 
 
-const static struct pvr2_i2c_handler_functions tuner_funcs = {
+static const struct pvr2_i2c_handler_functions tuner_funcs = {
 	.detach = (void (*)(void *))pvr2_tuner_detach,
 	.check = (int (*)(void *))tuner_check,
 	.update = (void (*)(void *))tuner_update,
diff --git a/drivers/media/video/pvrusb2/pvrusb2-video-v4l.c b/drivers/media/video/pvrusb2/pvrusb2-video-v4l.c
index 05f2cddeb47b..2a826464911a 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-video-v4l.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-video-v4l.c
@@ -201,7 +201,7 @@ static unsigned int decoder_describe(struct pvr2_v4l_decoder *ctxt,char *buf,uns
 }
 
 
-const static struct pvr2_i2c_handler_functions hfuncs = {
+static const struct pvr2_i2c_handler_functions hfuncs = {
 	.detach = (void (*)(void *))decoder_detach,
 	.check = (int (*)(void *))decoder_check,
 	.update = (void (*)(void *))decoder_update,
diff --git a/drivers/media/video/pvrusb2/pvrusb2-wm8775.c b/drivers/media/video/pvrusb2/pvrusb2-wm8775.c
index 2413e5198e16..7794c34c355e 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-wm8775.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-wm8775.c
@@ -126,7 +126,7 @@ static void wm8775_update(struct pvr2_v4l_wm8775 *ctxt)
 }
 
 
-const static struct pvr2_i2c_handler_functions hfuncs = {
+static const struct pvr2_i2c_handler_functions hfuncs = {
 	.detach = (void (*)(void *))wm8775_detach,
 	.check = (int (*)(void *))wm8775_check,
 	.update = (void (*)(void *))wm8775_update,
diff --git a/drivers/scsi/arm/eesox.c b/drivers/scsi/arm/eesox.c
index 4677152142d9..d4136524fc46 100644
--- a/drivers/scsi/arm/eesox.c
+++ b/drivers/scsi/arm/eesox.c
@@ -196,7 +196,7 @@ static void eesoxscsi_buffer_in(void *buf, int length, void __iomem *base)
 	const void __iomem *reg_fas = base + EESOX_FAS216_OFFSET;
 	const void __iomem *reg_dmastat = base + EESOX_DMASTAT;
 	const void __iomem *reg_dmadata = base + EESOX_DMADATA;
-	const register unsigned long mask = 0xffff;
+	register const unsigned long mask = 0xffff;
 
 	do {
 		unsigned int status;
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c
index b8e91470c27f..24364106b8f9 100644
--- a/fs/cifs/cifssmb.c
+++ b/fs/cifs/cifssmb.c
@@ -2824,10 +2824,10 @@ GetExtAttrOut:
 
 
 /* security id for everyone */
-const static struct cifs_sid sid_everyone = 
+static const struct cifs_sid sid_everyone =
 		{1, 1, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0}};
 /* group users */
-const static struct cifs_sid sid_user = 
+static const struct cifs_sid sid_user =
 		{1, 2 , {0, 0, 0, 0, 0, 5}, {32, 545, 0, 0}};
 
 /* Convert CIFS ACL to POSIX form */
diff --git a/include/asm-arm/uaccess.h b/include/asm-arm/uaccess.h
index c92df958802e..4c1a3fa9f259 100644
--- a/include/asm-arm/uaccess.h
+++ b/include/asm-arm/uaccess.h
@@ -109,7 +109,7 @@ extern int __get_user_4(void *);
 
 #define get_user(x,p)							\
 	({								\
-		const register typeof(*(p)) __user *__p asm("r0") = (p);\
+		register const typeof(*(p)) __user *__p asm("r0") = (p);\
 		register unsigned long __r2 asm("r2");			\
 		register int __e asm("r0");				\
 		switch (sizeof(*(__p))) {				\
@@ -143,8 +143,8 @@ extern int __put_user_8(void *, unsigned long long);
 
 #define put_user(x,p)							\
 	({								\
-		const register typeof(*(p)) __r2 asm("r2") = (x);	\
-		const register typeof(*(p)) __user *__p asm("r0") = (p);\
+		register const typeof(*(p)) __r2 asm("r2") = (x);	\
+		register const typeof(*(p)) __user *__p asm("r0") = (p);\
 		register int __e asm("r0");				\
 		switch (sizeof(*(__p))) {				\
 		case 1:							\
diff --git a/include/asm-arm26/uaccess.h b/include/asm-arm26/uaccess.h
index 3f2dd1093e58..d64ed84cb2d3 100644
--- a/include/asm-arm26/uaccess.h
+++ b/include/asm-arm26/uaccess.h
@@ -74,7 +74,7 @@ extern int __get_user_bad(void);
 
 #define get_user(x,p)							\
 	({								\
-		const register typeof(*(p)) *__p asm("r0") = (p);	\
+		register const typeof(*(p)) *__p asm("r0") = (p);	\
 		register typeof(*(p)) __r1 asm("r1");			\
 		register int __e asm("r0");				\
 		switch (sizeof(*(p))) {					\
@@ -139,8 +139,8 @@ extern int __put_user_bad(void);
 
 #define put_user(x,p)                                                   \
         ({                                                              \
-                const register typeof(*(p)) __r1 asm("r1") = (x);       \
-                const register typeof(*(p)) *__p asm("r0") = (p);       \
+                register const typeof(*(p)) __r1 asm("r1") = (x);       \
+                register const typeof(*(p)) *__p asm("r0") = (p);       \
                 register int __e asm("r0");                             \
                 switch (sizeof(*(__p))) {                               \
                 case 1:                                                 \
@@ -170,8 +170,8 @@ extern int __put_user_bad(void);
 
 #define put_user(x,p)							\
 	({								\
-		const register typeof(*(p)) __r1 asm("r1") = (x);	\
-		const register typeof(*(p)) *__p asm("r0") = (p);	\
+		register const typeof(*(p)) __r1 asm("r1") = (x);	\
+		register const typeof(*(p)) *__p asm("r0") = (p);	\
 		register int __e asm("r0");				\
 		switch (sizeof(*(p))) {					\
 		case 1:							\
diff --git a/include/asm-ia64/kexec.h b/include/asm-ia64/kexec.h
index 01c36b004747..f2ad469a6ddf 100644
--- a/include/asm-ia64/kexec.h
+++ b/include/asm-ia64/kexec.h
@@ -23,7 +23,7 @@
 
 extern struct kimage *ia64_kimage;
 DECLARE_PER_CPU(u64, ia64_mca_pal_base);
-const extern unsigned int relocate_new_kernel_size;
+extern const unsigned int relocate_new_kernel_size;
 extern void relocate_new_kernel(unsigned long, unsigned long,
 		struct ia64_boot_param *, unsigned long);
 static inline void
-- 
cgit v1.2.3


From 37985b449310b17a815511045455934ede5a90c0 Mon Sep 17 00:00:00 2001
From: Ozzy <linux-ozzy@gmx.de>
Date: Mon, 19 Feb 2007 15:05:42 +0100
Subject: [ARM] 4223/1: ixdp2351 : Fix for a define error

Fix syntax error for a define in ixdp2351.h

Signed-off-by: ozzy <linux-ozzy@gmx.de>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
 include/asm-arm/arch-ixp23xx/ixdp2351.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'include/asm-arm')

diff --git a/include/asm-arm/arch-ixp23xx/ixdp2351.h b/include/asm-arm/arch-ixp23xx/ixdp2351.h
index 4a24f8f15655..d5e8a43d7bbd 100644
--- a/include/asm-arm/arch-ixp23xx/ixdp2351.h
+++ b/include/asm-arm/arch-ixp23xx/ixdp2351.h
@@ -46,7 +46,7 @@
 #define IXDP2351_VIRT_NVRAM_BASE	IXDP2351_BB_AREA_BASE(0x0)
 #define IXDP2351_NVRAM_SIZE		(0x20000)
 
-#define IXDP2351_VIRT_MB_IXF1104_BASE	IXDP3251_BB_AREA_BASE(0x00020000)
+#define IXDP2351_VIRT_MB_IXF1104_BASE	IXDP2351_BB_AREA_BASE(0x00020000)
 #define IXDP2351_VIRT_ADD_UART_BASE	IXDP2351_BB_AREA_BASE(0x000240C0)
 #define IXDP2351_VIRT_FIC_BASE		IXDP2351_BB_AREA_BASE(0x00200000)
 #define IXDP2351_VIRT_DB0_BASE		IXDP2351_BB_AREA_BASE(0x00400000)
-- 
cgit v1.2.3


From 97e412fa9e31414030c1e9ac5e96a985d946af83 Mon Sep 17 00:00:00 2001
From: Russell King <rmk@dyn-67.arm.linux.org.uk>
Date: Tue, 20 Feb 2007 16:11:11 +0000
Subject: [ARM] Fix s3c2410 ALSA audio for typedef elimination

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
 include/asm-arm/arch-s3c2410/audio.h | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

(limited to 'include/asm-arm')

diff --git a/include/asm-arm/arch-s3c2410/audio.h b/include/asm-arm/arch-s3c2410/audio.h
index 65e0acffa1ad..0a6977fb5770 100644
--- a/include/asm-arm/arch-s3c2410/audio.h
+++ b/include/asm-arm/arch-s3c2410/audio.h
@@ -31,9 +31,9 @@ struct s3c24xx_iis_ops {
 	int	(*suspend)(struct s3c24xx_iis_ops *me);
 	int	(*resume)(struct s3c24xx_iis_ops *me);
 
-	int	(*open)(struct s3c24xx_iis_ops *me, snd_pcm_substream_t *strm);
-	int	(*close)(struct s3c24xx_iis_ops *me, snd_pcm_substream_t *strm);
-	int	(*prepare)(struct s3c24xx_iis_ops *me, snd_pcm_substream_t *strm, snd_pcm_runtime_t *rt);
+	int	(*open)(struct s3c24xx_iis_ops *me, struct snd_pcm_substream *strm);
+	int	(*close)(struct s3c24xx_iis_ops *me, struct snd_pcm_substream *strm);
+	int	(*prepare)(struct s3c24xx_iis_ops *me, struct snd_pcm_substream *strm, struct snd_pcm_runtime *rt);
 };
 
 struct s3c24xx_platdata_iis {
-- 
cgit v1.2.3