Merge master.kernel.org:/pub/scm/linux/kernel/git/herbert/crypto-2.6

* master.kernel.org:/pub/scm/linux/kernel/git/herbert/crypto-2.6:
  [CRYPTO] padlock: Fix alignment after aes_ctx rearrange
diff --git a/Documentation/DMA-mapping.txt b/Documentation/DMA-mapping.txt
index 7c717699..63392c9 100644
--- a/Documentation/DMA-mapping.txt
+++ b/Documentation/DMA-mapping.txt
@@ -698,12 +698,12 @@
 always going to be SAC addressable.
 
 The first thing your driver needs to do is query the PCI platform
-layer with your devices DAC addressing capabilities:
+layer if it is capable of handling your devices DAC addressing
+capabilities:
 
-	int pci_dac_set_dma_mask(struct pci_dev *pdev, u64 mask);
+	int pci_dac_dma_supported(struct pci_dev *hwdev, u64 mask);
 
-This routine behaves identically to pci_set_dma_mask.  You may not
-use the following interfaces if this routine fails.
+You may not use the following interfaces if this routine fails.
 
 Next, DMA addresses using this API are kept track of using the
 dma64_addr_t type.  It is guaranteed to be big enough to hold any
diff --git a/Documentation/accounting/delay-accounting.txt b/Documentation/accounting/delay-accounting.txt
new file mode 100644
index 0000000..be215e5
--- /dev/null
+++ b/Documentation/accounting/delay-accounting.txt
@@ -0,0 +1,110 @@
+Delay accounting
+----------------
+
+Tasks encounter delays in execution when they wait
+for some kernel resource to become available e.g. a
+runnable task may wait for a free CPU to run on.
+
+The per-task delay accounting functionality measures
+the delays experienced by a task while
+
+a) waiting for a CPU (while being runnable)
+b) completion of synchronous block I/O initiated by the task
+c) swapping in pages
+
+and makes these statistics available to userspace through
+the taskstats interface.
+
+Such delays provide feedback for setting a task's cpu priority,
+io priority and rss limit values appropriately. Long delays for
+important tasks could be a trigger for raising its corresponding priority.
+
+The functionality, through its use of the taskstats interface, also provides
+delay statistics aggregated for all tasks (or threads) belonging to a
+thread group (corresponding to a traditional Unix process). This is a commonly
+needed aggregation that is more efficiently done by the kernel.
+
+Userspace utilities, particularly resource management applications, can also
+aggregate delay statistics into arbitrary groups. To enable this, delay
+statistics of a task are available both during its lifetime as well as on its
+exit, ensuring continuous and complete monitoring can be done.
+
+
+Interface
+---------
+
+Delay accounting uses the taskstats interface which is described
+in detail in a separate document in this directory. Taskstats returns a
+generic data structure to userspace corresponding to per-pid and per-tgid
+statistics. The delay accounting functionality populates specific fields of
+this structure. See
+     include/linux/taskstats.h
+for a description of the fields pertaining to delay accounting.
+It will generally be in the form of counters returning the cumulative
+delay seen for cpu, sync block I/O, swapin etc.
+
+Taking the difference of two successive readings of a given
+counter (say cpu_delay_total) for a task will give the delay
+experienced by the task waiting for the corresponding resource
+in that interval.
+
+When a task exits, records containing the per-task statistics
+are sent to userspace without requiring a command. If it is the last exiting
+task of a thread group, the per-tgid statistics are also sent. More details
+are given in the taskstats interface description.
+
+The getdelays.c userspace utility in this directory allows simple commands to
+be run and the corresponding delay statistics to be displayed. It also serves
+as an example of using the taskstats interface.
+
+Usage
+-----
+
+Compile the kernel with
+	CONFIG_TASK_DELAY_ACCT=y
+	CONFIG_TASKSTATS=y
+
+Enable the accounting at boot time by adding
+the following to the kernel boot options
+	delayacct
+
+and after the system has booted up, use a utility
+similar to  getdelays.c to access the delays
+seen by a given task or a task group (tgid).
+The utility also allows a given command to be
+executed and the corresponding delays to be
+seen.
+
+General format of the getdelays command
+
+getdelays [-t tgid] [-p pid] [-c cmd...]
+
+
+Get delays, since system boot, for pid 10
+# ./getdelays -p 10
+(output similar to next case)
+
+Get sum of delays, since system boot, for all pids with tgid 5
+# ./getdelays -t 5
+
+
+CPU	count	real total	virtual total	delay total
+	7876	92005750	100000000	24001500
+IO	count	delay total
+	0	0
+MEM	count	delay total
+	0	0
+
+Get delays seen in executing a given simple command
+# ./getdelays -c ls /
+
+bin   data1  data3  data5  dev  home  media  opt   root  srv        sys  usr
+boot  data2  data4  data6  etc  lib   mnt    proc  sbin  subdomain  tmp  var
+
+
+CPU	count	real total	virtual total	delay total
+	6	4000250		4000000		0
+IO	count	delay total
+	0	0
+MEM	count	delay total
+	0	0
diff --git a/Documentation/accounting/getdelays.c b/Documentation/accounting/getdelays.c
new file mode 100644
index 0000000..795ca39
--- /dev/null
+++ b/Documentation/accounting/getdelays.c
@@ -0,0 +1,396 @@
+/* getdelays.c
+ *
+ * Utility to get per-pid and per-tgid delay accounting statistics
+ * Also illustrates usage of the taskstats interface
+ *
+ * Copyright (C) Shailabh Nagar, IBM Corp. 2005
+ * Copyright (C) Balbir Singh, IBM Corp. 2006
+ * Copyright (c) Jay Lan, SGI. 2006
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <unistd.h>
+#include <poll.h>
+#include <string.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <signal.h>
+
+#include <linux/genetlink.h>
+#include <linux/taskstats.h>
+
+/*
+ * Generic macros for dealing with netlink sockets. Might be duplicated
+ * elsewhere. It is recommended that commercial grade applications use
+ * libnl or libnetlink and use the interfaces provided by the library
+ */
+#define GENLMSG_DATA(glh)	((void *)(NLMSG_DATA(glh) + GENL_HDRLEN))
+#define GENLMSG_PAYLOAD(glh)	(NLMSG_PAYLOAD(glh, 0) - GENL_HDRLEN)
+#define NLA_DATA(na)		((void *)((char*)(na) + NLA_HDRLEN))
+#define NLA_PAYLOAD(len)	(len - NLA_HDRLEN)
+
+#define err(code, fmt, arg...) do { printf(fmt, ##arg); exit(code); } while (0)
+int done = 0;
+int rcvbufsz=0;
+
+    char name[100];
+int dbg=0, print_delays=0;
+__u64 stime, utime;
+#define PRINTF(fmt, arg...) {			\
+	    if (dbg) {				\
+		printf(fmt, ##arg);		\
+	    }					\
+	}
+
+/* Maximum size of response requested or message sent */
+#define MAX_MSG_SIZE	256
+/* Maximum number of cpus expected to be specified in a cpumask */
+#define MAX_CPUS	32
+/* Maximum length of pathname to log file */
+#define MAX_FILENAME	256
+
+struct msgtemplate {
+	struct nlmsghdr n;
+	struct genlmsghdr g;
+	char buf[MAX_MSG_SIZE];
+};
+
+char cpumask[100+6*MAX_CPUS];
+
+/*
+ * Create a raw netlink socket and bind
+ */
+static int create_nl_socket(int protocol)
+{
+	int fd;
+	struct sockaddr_nl local;
+
+	fd = socket(AF_NETLINK, SOCK_RAW, protocol);
+	if (fd < 0)
+		return -1;
+
+	if (rcvbufsz)
+		if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF,
+				&rcvbufsz, sizeof(rcvbufsz)) < 0) {
+			printf("Unable to set socket rcv buf size to %d\n",
+			       rcvbufsz);
+			return -1;
+		}
+
+	memset(&local, 0, sizeof(local));
+	local.nl_family = AF_NETLINK;
+
+	if (bind(fd, (struct sockaddr *) &local, sizeof(local)) < 0)
+		goto error;
+
+	return fd;
+error:
+	close(fd);
+	return -1;
+}
+
+
+int send_cmd(int sd, __u16 nlmsg_type, __u32 nlmsg_pid,
+	     __u8 genl_cmd, __u16 nla_type,
+	     void *nla_data, int nla_len)
+{
+	struct nlattr *na;
+	struct sockaddr_nl nladdr;
+	int r, buflen;
+	char *buf;
+
+	struct msgtemplate msg;
+
+	msg.n.nlmsg_len = NLMSG_LENGTH(GENL_HDRLEN);
+	msg.n.nlmsg_type = nlmsg_type;
+	msg.n.nlmsg_flags = NLM_F_REQUEST;
+	msg.n.nlmsg_seq = 0;
+	msg.n.nlmsg_pid = nlmsg_pid;
+	msg.g.cmd = genl_cmd;
+	msg.g.version = 0x1;
+	na = (struct nlattr *) GENLMSG_DATA(&msg);
+	na->nla_type = nla_type;
+	na->nla_len = nla_len + 1 + NLA_HDRLEN;
+	memcpy(NLA_DATA(na), nla_data, nla_len);
+	msg.n.nlmsg_len += NLMSG_ALIGN(na->nla_len);
+
+	buf = (char *) &msg;
+	buflen = msg.n.nlmsg_len ;
+	memset(&nladdr, 0, sizeof(nladdr));
+	nladdr.nl_family = AF_NETLINK;
+	while ((r = sendto(sd, buf, buflen, 0, (struct sockaddr *) &nladdr,
+			   sizeof(nladdr))) < buflen) {
+		if (r > 0) {
+			buf += r;
+			buflen -= r;
+		} else if (errno != EAGAIN)
+			return -1;
+	}
+	return 0;
+}
+
+
+/*
+ * Probe the controller in genetlink to find the family id
+ * for the TASKSTATS family
+ */
+int get_family_id(int sd)
+{
+	struct {
+		struct nlmsghdr n;
+		struct genlmsghdr g;
+		char buf[256];
+	} ans;
+
+	int id, rc;
+	struct nlattr *na;
+	int rep_len;
+
+	strcpy(name, TASKSTATS_GENL_NAME);
+	rc = send_cmd(sd, GENL_ID_CTRL, getpid(), CTRL_CMD_GETFAMILY,
+			CTRL_ATTR_FAMILY_NAME, (void *)name,
+			strlen(TASKSTATS_GENL_NAME)+1);
+
+	rep_len = recv(sd, &ans, sizeof(ans), 0);
+	if (ans.n.nlmsg_type == NLMSG_ERROR ||
+	    (rep_len < 0) || !NLMSG_OK((&ans.n), rep_len))
+		return 0;
+
+	na = (struct nlattr *) GENLMSG_DATA(&ans);
+	na = (struct nlattr *) ((char *) na + NLA_ALIGN(na->nla_len));
+	if (na->nla_type == CTRL_ATTR_FAMILY_ID) {
+		id = *(__u16 *) NLA_DATA(na);
+	}
+	return id;
+}
+
+void print_delayacct(struct taskstats *t)
+{
+	printf("\n\nCPU   %15s%15s%15s%15s\n"
+	       "      %15llu%15llu%15llu%15llu\n"
+	       "IO    %15s%15s\n"
+	       "      %15llu%15llu\n"
+	       "MEM   %15s%15s\n"
+	       "      %15llu%15llu\n\n",
+	       "count", "real total", "virtual total", "delay total",
+	       t->cpu_count, t->cpu_run_real_total, t->cpu_run_virtual_total,
+	       t->cpu_delay_total,
+	       "count", "delay total",
+	       t->blkio_count, t->blkio_delay_total,
+	       "count", "delay total", t->swapin_count, t->swapin_delay_total);
+}
+
+int main(int argc, char *argv[])
+{
+	int c, rc, rep_len, aggr_len, len2, cmd_type;
+	__u16 id;
+	__u32 mypid;
+
+	struct nlattr *na;
+	int nl_sd = -1;
+	int len = 0;
+	pid_t tid = 0;
+	pid_t rtid = 0;
+
+	int fd = 0;
+	int count = 0;
+	int write_file = 0;
+	int maskset = 0;
+	char logfile[128];
+	int loop = 0;
+
+	struct msgtemplate msg;
+
+	while (1) {
+		c = getopt(argc, argv, "dw:r:m:t:p:v:l");
+		if (c < 0)
+			break;
+
+		switch (c) {
+		case 'd':
+			printf("print delayacct stats ON\n");
+			print_delays = 1;
+			break;
+		case 'w':
+			strncpy(logfile, optarg, MAX_FILENAME);
+			printf("write to file %s\n", logfile);
+			write_file = 1;
+			break;
+		case 'r':
+			rcvbufsz = atoi(optarg);
+			printf("receive buf size %d\n", rcvbufsz);
+			if (rcvbufsz < 0)
+				err(1, "Invalid rcv buf size\n");
+			break;
+		case 'm':
+			strncpy(cpumask, optarg, sizeof(cpumask));
+			maskset = 1;
+			printf("cpumask %s maskset %d\n", cpumask, maskset);
+			break;
+		case 't':
+			tid = atoi(optarg);
+			if (!tid)
+				err(1, "Invalid tgid\n");
+			cmd_type = TASKSTATS_CMD_ATTR_TGID;
+			print_delays = 1;
+			break;
+		case 'p':
+			tid = atoi(optarg);
+			if (!tid)
+				err(1, "Invalid pid\n");
+			cmd_type = TASKSTATS_CMD_ATTR_PID;
+			print_delays = 1;
+			break;
+		case 'v':
+			printf("debug on\n");
+			dbg = 1;
+			break;
+		case 'l':
+			printf("listen forever\n");
+			loop = 1;
+			break;
+		default:
+			printf("Unknown option %d\n", c);
+			exit(-1);
+		}
+	}
+
+	if (write_file) {
+		fd = open(logfile, O_WRONLY | O_CREAT | O_TRUNC,
+			  S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
+		if (fd == -1) {
+			perror("Cannot open output file\n");
+			exit(1);
+		}
+	}
+
+	if ((nl_sd = create_nl_socket(NETLINK_GENERIC)) < 0)
+		err(1, "error creating Netlink socket\n");
+
+
+	mypid = getpid();
+	id = get_family_id(nl_sd);
+	if (!id) {
+		printf("Error getting family id, errno %d", errno);
+		goto err;
+	}
+	PRINTF("family id %d\n", id);
+
+	if (maskset) {
+		rc = send_cmd(nl_sd, id, mypid, TASKSTATS_CMD_GET,
+			      TASKSTATS_CMD_ATTR_REGISTER_CPUMASK,
+			      &cpumask, sizeof(cpumask));
+		PRINTF("Sent register cpumask, retval %d\n", rc);
+		if (rc < 0) {
+			printf("error sending register cpumask\n");
+			goto err;
+		}
+	}
+
+	if (tid) {
+		rc = send_cmd(nl_sd, id, mypid, TASKSTATS_CMD_GET,
+			      cmd_type, &tid, sizeof(__u32));
+		PRINTF("Sent pid/tgid, retval %d\n", rc);
+		if (rc < 0) {
+			printf("error sending tid/tgid cmd\n");
+			goto done;
+		}
+	}
+
+	do {
+		int i;
+
+		rep_len = recv(nl_sd, &msg, sizeof(msg), 0);
+		PRINTF("received %d bytes\n", rep_len);
+
+		if (rep_len < 0) {
+			printf("nonfatal reply error: errno %d\n", errno);
+			continue;
+		}
+		if (msg.n.nlmsg_type == NLMSG_ERROR ||
+		    !NLMSG_OK((&msg.n), rep_len)) {
+			printf("fatal reply error,  errno %d\n", errno);
+			goto done;
+		}
+
+		PRINTF("nlmsghdr size=%d, nlmsg_len=%d, rep_len=%d\n",
+		       sizeof(struct nlmsghdr), msg.n.nlmsg_len, rep_len);
+
+
+		rep_len = GENLMSG_PAYLOAD(&msg.n);
+
+		na = (struct nlattr *) GENLMSG_DATA(&msg);
+		len = 0;
+		i = 0;
+		while (len < rep_len) {
+			len += NLA_ALIGN(na->nla_len);
+			switch (na->nla_type) {
+			case TASKSTATS_TYPE_AGGR_TGID:
+				/* Fall through */
+			case TASKSTATS_TYPE_AGGR_PID:
+				aggr_len = NLA_PAYLOAD(na->nla_len);
+				len2 = 0;
+				/* For nested attributes, na follows */
+				na = (struct nlattr *) NLA_DATA(na);
+				done = 0;
+				while (len2 < aggr_len) {
+					switch (na->nla_type) {
+					case TASKSTATS_TYPE_PID:
+						rtid = *(int *) NLA_DATA(na);
+						if (print_delays)
+							printf("PID\t%d\n", rtid);
+						break;
+					case TASKSTATS_TYPE_TGID:
+						rtid = *(int *) NLA_DATA(na);
+						if (print_delays)
+							printf("TGID\t%d\n", rtid);
+						break;
+					case TASKSTATS_TYPE_STATS:
+						count++;
+						if (print_delays)
+							print_delayacct((struct taskstats *) NLA_DATA(na));
+						if (fd) {
+							if (write(fd, NLA_DATA(na), na->nla_len) < 0) {
+								err(1,"write error\n");
+							}
+						}
+						if (!loop)
+							goto done;
+						break;
+					default:
+						printf("Unknown nested nla_type %d\n", na->nla_type);
+						break;
+					}
+					len2 += NLA_ALIGN(na->nla_len);
+					na = (struct nlattr *) ((char *) na + len2);
+				}
+				break;
+
+			default:
+				printf("Unknown nla_type %d\n", na->nla_type);
+				break;
+			}
+			na = (struct nlattr *) (GENLMSG_DATA(&msg) + len);
+		}
+	} while (loop);
+done:
+	if (maskset) {
+		rc = send_cmd(nl_sd, id, mypid, TASKSTATS_CMD_GET,
+			      TASKSTATS_CMD_ATTR_DEREGISTER_CPUMASK,
+			      &cpumask, sizeof(cpumask));
+		printf("Sent deregister mask, retval %d\n", rc);
+		if (rc < 0)
+			err(rc, "error sending deregister cpumask\n");
+	}
+err:
+	close(nl_sd);
+	if (fd)
+		close(fd);
+	return 0;
+}
diff --git a/Documentation/accounting/taskstats.txt b/Documentation/accounting/taskstats.txt
new file mode 100644
index 0000000..92ebf29
--- /dev/null
+++ b/Documentation/accounting/taskstats.txt
@@ -0,0 +1,181 @@
+Per-task statistics interface
+-----------------------------
+
+
+Taskstats is a netlink-based interface for sending per-task and
+per-process statistics from the kernel to userspace.
+
+Taskstats was designed for the following benefits:
+
+- efficiently provide statistics during lifetime of a task and on its exit
+- unified interface for multiple accounting subsystems
+- extensibility for use by future accounting patches
+
+Terminology
+-----------
+
+"pid", "tid" and "task" are used interchangeably and refer to the standard
+Linux task defined by struct task_struct.  per-pid stats are the same as
+per-task stats.
+
+"tgid", "process" and "thread group" are used interchangeably and refer to the
+tasks that share an mm_struct i.e. the traditional Unix process. Despite the
+use of tgid, there is no special treatment for the task that is thread group
+leader - a process is deemed alive as long as it has any task belonging to it.
+
+Usage
+-----
+
+To get statistics during a task's lifetime, userspace opens a unicast netlink
+socket (NETLINK_GENERIC family) and sends commands specifying a pid or a tgid.
+The response contains statistics for a task (if pid is specified) or the sum of
+statistics for all tasks of the process (if tgid is specified).
+
+To obtain statistics for tasks which are exiting, the userspace listener
+sends a register command and specifies a cpumask. Whenever a task exits on
+one of the cpus in the cpumask, its per-pid statistics are sent to the
+registered listener. Using cpumasks allows the data received by one listener
+to be limited and assists in flow control over the netlink interface and is
+explained in more detail below.
+
+If the exiting task is the last thread exiting its thread group,
+an additional record containing the per-tgid stats is also sent to userspace.
+The latter contains the sum of per-pid stats for all threads in the thread
+group, both past and present.
+
+getdelays.c is a simple utility demonstrating usage of the taskstats interface
+for reporting delay accounting statistics. Users can register cpumasks,
+send commands and process responses, listen for per-tid/tgid exit data,
+write the data received to a file and do basic flow control by increasing
+receive buffer sizes.
+
+Interface
+---------
+
+The user-kernel interface is encapsulated in include/linux/taskstats.h
+
+To avoid this documentation becoming obsolete as the interface evolves, only
+an outline of the current version is given. taskstats.h always overrides the
+description here.
+
+struct taskstats is the common accounting structure for both per-pid and
+per-tgid data. It is versioned and can be extended by each accounting subsystem
+that is added to the kernel. The fields and their semantics are defined in the
+taskstats.h file.
+
+The data exchanged between user and kernel space is a netlink message belonging
+to the NETLINK_GENERIC family and using the netlink attributes interface.
+The messages are in the format
+
+    +----------+- - -+-------------+-------------------+
+    | nlmsghdr | Pad |  genlmsghdr | taskstats payload |
+    +----------+- - -+-------------+-------------------+
+
+
+The taskstats payload is one of the following three kinds:
+
+1. Commands: Sent from user to kernel. Commands to get data on
+a pid/tgid consist of one attribute, of type TASKSTATS_CMD_ATTR_PID/TGID,
+containing a u32 pid or tgid in the attribute payload. The pid/tgid denotes
+the task/process for which userspace wants statistics.
+
+Commands to register/deregister interest in exit data from a set of cpus
+consist of one attribute, of type
+TASKSTATS_CMD_ATTR_REGISTER/DEREGISTER_CPUMASK and contain a cpumask in the
+attribute payload. The cpumask is specified as an ascii string of
+comma-separated cpu ranges e.g. to listen to exit data from cpus 1,2,3,5,7,8
+the cpumask would be "1-3,5,7-8". If userspace forgets to deregister interest
+in cpus before closing the listening socket, the kernel cleans up its interest
+set over time. However, for the sake of efficiency, an explicit deregistration
+is advisable.
+
+2. Response for a command: sent from the kernel in response to a userspace
+command. The payload is a series of three attributes of type:
+
+a) TASKSTATS_TYPE_AGGR_PID/TGID : attribute containing no payload but indicates
+a pid/tgid will be followed by some stats.
+
+b) TASKSTATS_TYPE_PID/TGID: attribute whose payload is the pid/tgid whose stats
+is being returned.
+
+c) TASKSTATS_TYPE_STATS: attribute with a struct taskstsats as payload. The
+same structure is used for both per-pid and per-tgid stats.
+
+3. New message sent by kernel whenever a task exits. The payload consists of a
+   series of attributes of the following type:
+
+a) TASKSTATS_TYPE_AGGR_PID: indicates next two attributes will be pid+stats
+b) TASKSTATS_TYPE_PID: contains exiting task's pid
+c) TASKSTATS_TYPE_STATS: contains the exiting task's per-pid stats
+d) TASKSTATS_TYPE_AGGR_TGID: indicates next two attributes will be tgid+stats
+e) TASKSTATS_TYPE_TGID: contains tgid of process to which task belongs
+f) TASKSTATS_TYPE_STATS: contains the per-tgid stats for exiting task's process
+
+
+per-tgid stats
+--------------
+
+Taskstats provides per-process stats, in addition to per-task stats, since
+resource management is often done at a process granularity and aggregating task
+stats in userspace alone is inefficient and potentially inaccurate (due to lack
+of atomicity).
+
+However, maintaining per-process, in addition to per-task stats, within the
+kernel has space and time overheads. To address this, the taskstats code
+accumalates each exiting task's statistics into a process-wide data structure.
+When the last task of a process exits, the process level data accumalated also
+gets sent to userspace (along with the per-task data).
+
+When a user queries to get per-tgid data, the sum of all other live threads in
+the group is added up and added to the accumalated total for previously exited
+threads of the same thread group.
+
+Extending taskstats
+-------------------
+
+There are two ways to extend the taskstats interface to export more
+per-task/process stats as patches to collect them get added to the kernel
+in future:
+
+1. Adding more fields to the end of the existing struct taskstats. Backward
+   compatibility is ensured by the version number within the
+   structure. Userspace will use only the fields of the struct that correspond
+   to the version its using.
+
+2. Defining separate statistic structs and using the netlink attributes
+   interface to return them. Since userspace processes each netlink attribute
+   independently, it can always ignore attributes whose type it does not
+   understand (because it is using an older version of the interface).
+
+
+Choosing between 1. and 2. is a matter of trading off flexibility and
+overhead. If only a few fields need to be added, then 1. is the preferable
+path since the kernel and userspace don't need to incur the overhead of
+processing new netlink attributes. But if the new fields expand the existing
+struct too much, requiring disparate userspace accounting utilities to
+unnecessarily receive large structures whose fields are of no interest, then
+extending the attributes structure would be worthwhile.
+
+Flow control for taskstats
+--------------------------
+
+When the rate of task exits becomes large, a listener may not be able to keep
+up with the kernel's rate of sending per-tid/tgid exit data leading to data
+loss. This possibility gets compounded when the taskstats structure gets
+extended and the number of cpus grows large.
+
+To avoid losing statistics, userspace should do one or more of the following:
+
+- increase the receive buffer sizes for the netlink sockets opened by
+listeners to receive exit data.
+
+- create more listeners and reduce the number of cpus being listened to by
+each listener. In the extreme case, there could be one listener for each cpu.
+Users may also consider setting the cpu affinity of the listener to the subset
+of cpus to which it listens, especially if they are listening to just one cpu.
+
+Despite these measures, if the userspace receives ENOBUFS error messages
+indicated overflow of receive buffers, it should take measures to handle the
+loss of data.
+
+----
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index 149f62b..e11f772 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -448,6 +448,8 @@
 			Format: <area>[,<node>]
 			See also Documentation/networking/decnet.txt.
 
+	delayacct	[KNL] Enable per-task delay accounting
+
 	dhash_entries=	[KNL]
 			Set number of hash buckets for dentry cache.
 
diff --git a/Documentation/memory-barriers.txt b/Documentation/memory-barriers.txt
index 28d1bc3..46b9b38 100644
--- a/Documentation/memory-barriers.txt
+++ b/Documentation/memory-barriers.txt
@@ -1015,10 +1015,9 @@
 There are some more advanced barrier functions:
 
  (*) set_mb(var, value)
- (*) set_wmb(var, value)
 
-     These assign the value to the variable and then insert at least a write
-     barrier after it, depending on the function.  They aren't guaranteed to
+     This assigns the value to the variable and then inserts at least a write
+     barrier after it, depending on the function.  It isn't guaranteed to
      insert anything more than a compiler barrier in a UP compilation.
 
 
diff --git a/Documentation/ramdisk.txt b/Documentation/ramdisk.txt
index 7c25584..52f75b7 100644
--- a/Documentation/ramdisk.txt
+++ b/Documentation/ramdisk.txt
@@ -6,7 +6,7 @@
 	1) Overview
 	2) Kernel Command Line Parameters
 	3) Using "rdev -r"
-	4) An Example of Creating a Compressed RAM Disk 
+	4) An Example of Creating a Compressed RAM Disk
 
 
 1) Overview
@@ -34,7 +34,7 @@
 compatibility reasons, but it may be removed in the future.
 
 The new RAM disk also has the ability to load compressed RAM disk images,
-allowing one to squeeze more programs onto an average installation or 
+allowing one to squeeze more programs onto an average installation or
 rescue floppy disk.
 
 
@@ -51,7 +51,7 @@
 	===================
 
 This parameter tells the RAM disk driver how many bytes to use per block.  The
-default is 512.
+default is 1024 (BLOCK_SIZE).
 
 
 3) Using "rdev -r"
@@ -70,7 +70,7 @@
 ./arch/i386/kernel/setup.c:#define RAMDISK_PROMPT_FLAG          0x8000
 ./arch/i386/kernel/setup.c:#define RAMDISK_LOAD_FLAG            0x4000
 
-Consider a typical two floppy disk setup, where you will have the 
+Consider a typical two floppy disk setup, where you will have the
 kernel on disk one, and have already put a RAM disk image onto disk #2.
 
 Hence you want to set bits 0 to 13 as 0, meaning that your RAM disk
@@ -97,12 +97,12 @@
 	append = "load_ramdisk=1"
 
 
-4) An Example of Creating a Compressed RAM Disk 
+4) An Example of Creating a Compressed RAM Disk
 ----------------------------------------------
 
 To create a RAM disk image, you will need a spare block device to
 construct it on. This can be the RAM disk device itself, or an
-unused disk partition (such as an unmounted swap partition). For this 
+unused disk partition (such as an unmounted swap partition). For this
 example, we will use the RAM disk device, "/dev/ram0".
 
 Note: This technique should not be done on a machine with less than 8 MB
diff --git a/MAINTAINERS b/MAINTAINERS
index a3462c3..e99028c 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -771,6 +771,7 @@
 P:	Jamie Lenehan
 M:	lenehan@twibble.org
 W:	http://twibble.org/dist/dc395x/
+L:	dc395x@twibble.org
 L:	http://lists.twibble.org/mailman/listinfo/dc395x/
 S:	Maintained
 
@@ -1501,6 +1502,7 @@
 M:	yi.zhu@intel.com
 P:	James Ketrenos
 M:	jketreno@linux.intel.com
+L:	ipw2100-devel@lists.sourceforge.net
 L:	http://lists.sourceforge.net/mailman/listinfo/ipw2100-devel
 W:	http://ipw2100.sourceforge.net
 S:	Supported
@@ -1510,6 +1512,7 @@
 M:	yi.zhu@intel.com
 P:	James Ketrenos
 M:	jketreno@linux.intel.com
+L:	ipw2100-devel@lists.sourceforge.net
 L:	http://lists.sourceforge.net/mailman/listinfo/ipw2100-devel
 W:	http://ipw2200.sourceforge.net
 S:	Supported
@@ -2226,6 +2229,7 @@
 
 PCMCIA SUBSYSTEM
 P:	Linux PCMCIA Team
+L:	linux-pcmcia@lists.infradead.org
 L:	http://lists.infradead.org/mailman/listinfo/linux-pcmcia
 T:	git kernel.org:/pub/scm/linux/kernel/git/brodo/pcmcia-2.6.git
 S:	Maintained
@@ -2236,6 +2240,12 @@
 L:	netdev@vger.kernel.org
 S:	Maintained
 
+PER-TASK DELAY ACCOUNTING
+P:	Shailabh Nagar
+M:	nagar@watson.ibm.com
+L:	linux-kernel@vger.kernel.org
+S:	Maintained
+
 PERSONALITY HANDLING
 P:	Christoph Hellwig
 M:	hch@infradead.org
@@ -2763,6 +2773,12 @@
 M:	dsaxena@plexity.net
 S:	Maintained
 
+TASKSTATS STATISTICS INTERFACE
+P:	Shailabh Nagar
+M:	nagar@watson.ibm.com
+L:	linux-kernel@vger.kernel.org
+S:	Maintained
+
 TI PARALLEL LINK CABLE DRIVER
 P:     Romain Lievin
 M:     roms@lpg.ticalc.org
diff --git a/arch/i386/kernel/crash.c b/arch/i386/kernel/crash.c
index 48f0f62..5b96f03 100644
--- a/arch/i386/kernel/crash.c
+++ b/arch/i386/kernel/crash.c
@@ -90,7 +90,7 @@
 	crash_save_this_cpu(regs, cpu);
 }
 
-#ifdef CONFIG_SMP
+#if defined(CONFIG_SMP) && defined(CONFIG_X86_LOCAL_APIC)
 static atomic_t waiting_for_crash_ipi;
 
 static int crash_nmi_callback(struct pt_regs *regs, int cpu)
diff --git a/arch/i386/kernel/setup.c b/arch/i386/kernel/setup.c
index 7864395..f168220 100644
--- a/arch/i386/kernel/setup.c
+++ b/arch/i386/kernel/setup.c
@@ -1327,7 +1327,10 @@
 		res->start = e820.map[i].addr;
 		res->end = res->start + e820.map[i].size - 1;
 		res->flags = IORESOURCE_MEM | IORESOURCE_BUSY;
-		request_resource(&iomem_resource, res);
+		if (request_resource(&iomem_resource, res)) {
+			kfree(res);
+			continue;
+		}
 		if (e820.map[i].type == E820_RAM) {
 			/*
 			 *  We don't know which RAM region contains kernel data,
diff --git a/arch/i386/kernel/traps.c b/arch/i386/kernel/traps.c
index 5cfd4f4..313ac1f 100644
--- a/arch/i386/kernel/traps.c
+++ b/arch/i386/kernel/traps.c
@@ -324,35 +324,35 @@
 
 static void handle_BUG(struct pt_regs *regs)
 {
+	unsigned long eip = regs->eip;
 	unsigned short ud2;
-	unsigned short line;
-	char *file;
-	char c;
-	unsigned long eip;
-
-	eip = regs->eip;
 
 	if (eip < PAGE_OFFSET)
-		goto no_bug;
+		return;
 	if (__get_user(ud2, (unsigned short __user *)eip))
-		goto no_bug;
+		return;
 	if (ud2 != 0x0b0f)
-		goto no_bug;
-	if (__get_user(line, (unsigned short __user *)(eip + 2)))
-		goto bug;
-	if (__get_user(file, (char * __user *)(eip + 4)) ||
-		(unsigned long)file < PAGE_OFFSET || __get_user(c, file))
-		file = "<bad filename>";
+		return;
 
 	printk(KERN_EMERG "------------[ cut here ]------------\n");
-	printk(KERN_EMERG "kernel BUG at %s:%d!\n", file, line);
 
-no_bug:
-	return;
+#ifdef CONFIG_DEBUG_BUGVERBOSE
+	do {
+		unsigned short line;
+		char *file;
+		char c;
 
-	/* Here we know it was a BUG but file-n-line is unavailable */
-bug:
-	printk(KERN_EMERG "Kernel BUG\n");
+		if (__get_user(line, (unsigned short __user *)(eip + 2)))
+			break;
+		if (__get_user(file, (char * __user *)(eip + 4)) ||
+		    (unsigned long)file < PAGE_OFFSET || __get_user(c, file))
+			file = "<bad filename>";
+
+		printk(KERN_EMERG "kernel BUG at %s:%d!\n", file, line);
+		return;
+	} while (0);
+#endif
+	printk(KERN_EMERG "Kernel BUG at [verbose debug info unavailable]\n");
 }
 
 /* This is gone through when something in the kernel
diff --git a/arch/i386/lib/usercopy.c b/arch/i386/lib/usercopy.c
index 4b75212..efc7e7d 100644
--- a/arch/i386/lib/usercopy.c
+++ b/arch/i386/lib/usercopy.c
@@ -843,7 +843,6 @@
 unsigned long
 copy_to_user(void __user *to, const void *from, unsigned long n)
 {
-	might_sleep();
 	BUG_ON((long) n < 0);
 	if (access_ok(VERIFY_WRITE, to, n))
 		n = __copy_to_user(to, from, n);
@@ -870,7 +869,6 @@
 unsigned long
 copy_from_user(void *to, const void __user *from, unsigned long n)
 {
-	might_sleep();
 	BUG_ON((long) n < 0);
 	if (access_ok(VERIFY_READ, from, n))
 		n = __copy_from_user(to, from, n);
diff --git a/arch/sparc64/kernel/head.S b/arch/sparc64/kernel/head.S
index 75684b5..c8e9dc9 100644
--- a/arch/sparc64/kernel/head.S
+++ b/arch/sparc64/kernel/head.S
@@ -551,9 +551,10 @@
 	save	%sp, -192, %sp
 
 	/* Force interrupts to be disabled. */
-	rdpr	%pstate, %o1
-	andn	%o1, PSTATE_IE, %o1
+	rdpr	%pstate, %l0
+	andn	%l0, PSTATE_IE, %o1
 	wrpr	%o1, 0x0, %pstate
+	rdpr	%pil, %l1
 	wrpr	%g0, 15, %pil
 
 	/* Make the firmware call to jump over to the Linux trap table.  */
@@ -622,11 +623,9 @@
 	call	init_irqwork_curcpu
 	 nop
 
-	/* Now we can turn interrupts back on. */
-	rdpr	%pstate, %o1
-	or	%o1, PSTATE_IE, %o1
-	wrpr	%o1, 0, %pstate
-	wrpr	%g0, 0x0, %pil
+	/* Now we can restore interrupt state. */
+	wrpr	%l0, 0, %pstate
+	wrpr	%l1, 0x0, %pil
 
 	ret
 	 restore
diff --git a/arch/sparc64/kernel/pci_psycho.c b/arch/sparc64/kernel/pci_psycho.c
index 197a7ff..1ec0aab 100644
--- a/arch/sparc64/kernel/pci_psycho.c
+++ b/arch/sparc64/kernel/pci_psycho.c
@@ -1099,9 +1099,6 @@
 {
 	char *name = pbm->name;
 
-	sprintf(name, "PSYCHO%d PBM%c",
-		p->index,
-		(pbm == &p->pbm_A ? 'A' : 'B'));
 	pbm->io_space.name = pbm->mem_space.name = name;
 
 	request_resource(&ioport_resource, &pbm->io_space);
@@ -1203,12 +1200,13 @@
 	pbm->io_space.flags = IORESOURCE_IO;
 	pbm->mem_space.end = pbm->mem_space.start + PSYCHO_MEMSPACE_SIZE;
 	pbm->mem_space.flags = IORESOURCE_MEM;
-	pbm_register_toplevel_resources(p, pbm);
 
 	pbm->parent = p;
 	pbm->prom_node = dp;
 	pbm->name = dp->full_name;
 
+	pbm_register_toplevel_resources(p, pbm);
+
 	printk("%s: PSYCHO PCI Bus Module ver[%x:%x]\n",
 	       pbm->name,
 	       pbm->chip_version, pbm->chip_revision);
diff --git a/arch/sparc64/kernel/time.c b/arch/sparc64/kernel/time.c
index b43de64..094d3e3 100644
--- a/arch/sparc64/kernel/time.c
+++ b/arch/sparc64/kernel/time.c
@@ -928,8 +928,6 @@
 	__asm__ __volatile__("wrpr	%0, 0x0, %%pstate"
 			     : /* no outputs */
 			     : "r" (pstate));
-
-	local_irq_enable();
 }
 
 struct freq_table {
diff --git a/arch/um/Makefile-x86_64 b/arch/um/Makefile-x86_64
index dffd118..9558a7c 100644
--- a/arch/um/Makefile-x86_64
+++ b/arch/um/Makefile-x86_64
@@ -11,6 +11,7 @@
 CHECKFLAGS  += -m64
 AFLAGS += -m64
 LDFLAGS += -m elf_x86_64
+CPPFLAGS += -m64
 
 ELF_ARCH := i386:x86-64
 ELF_FORMAT := elf64-x86-64
diff --git a/arch/um/include/longjmp.h b/arch/um/include/longjmp.h
index 8e70530..1b5c013 100644
--- a/arch/um/include/longjmp.h
+++ b/arch/um/include/longjmp.h
@@ -8,8 +8,8 @@
 	longjmp(*buf, val);	\
 } while(0)
 
-#define UML_SETJMP(buf, enable) ({ \
-	int n; \
+#define UML_SETJMP(buf) ({ \
+	int n, enable;	   \
 	enable = get_signals(); \
 	n = setjmp(*buf); \
 	if(n != 0) \
diff --git a/arch/um/include/os.h b/arch/um/include/os.h
index b6c5249..5316e8a 100644
--- a/arch/um/include/os.h
+++ b/arch/um/include/os.h
@@ -1,4 +1,4 @@
-/* 
+/*
  * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
  * Licensed under the GPL
  */
@@ -15,9 +15,9 @@
 #include "irq_user.h"
 #include "sysdep/tls.h"
 
-#define OS_TYPE_FILE 1 
-#define OS_TYPE_DIR 2 
-#define OS_TYPE_SYMLINK 3 
+#define OS_TYPE_FILE 1
+#define OS_TYPE_DIR 2
+#define OS_TYPE_SYMLINK 3
 #define OS_TYPE_CHARDEV 4
 #define OS_TYPE_BLOCKDEV 5
 #define OS_TYPE_FIFO 6
@@ -61,68 +61,68 @@
 };
 
 #define OPENFLAGS() ((struct openflags) { .r = 0, .w = 0, .s = 0, .c = 0, \
- 					  .t = 0, .a = 0, .e = 0, .cl = 0 })
+					  .t = 0, .a = 0, .e = 0, .cl = 0 })
 
 static inline struct openflags of_read(struct openflags flags)
 {
-	flags.r = 1; 
-	return(flags);
+	flags.r = 1;
+	return flags;
 }
 
 static inline struct openflags of_write(struct openflags flags)
 {
-	flags.w = 1; 
-	return(flags); 
+	flags.w = 1;
+	return flags;
 }
 
 static inline struct openflags of_rdwr(struct openflags flags)
 {
-	return(of_read(of_write(flags)));
+	return of_read(of_write(flags));
 }
 
 static inline struct openflags of_set_rw(struct openflags flags, int r, int w)
 {
 	flags.r = r;
 	flags.w = w;
-	return(flags);
+	return flags;
 }
 
 static inline struct openflags of_sync(struct openflags flags)
-{ 
-	flags.s = 1; 
-	return(flags); 
+{
+	flags.s = 1;
+	return flags;
 }
 
 static inline struct openflags of_create(struct openflags flags)
-{ 
-	flags.c = 1; 
-	return(flags); 
+{
+	flags.c = 1;
+	return flags;
 }
- 
+
 static inline struct openflags of_trunc(struct openflags flags)
-{ 
-	flags.t = 1; 
-	return(flags); 
+{
+	flags.t = 1;
+	return flags;
 }
- 
+
 static inline struct openflags of_append(struct openflags flags)
-{ 
-	flags.a = 1; 
-	return(flags); 
+{
+	flags.a = 1;
+	return flags;
 }
- 
+
 static inline struct openflags of_excl(struct openflags flags)
-{ 
-	flags.e = 1; 
-	return(flags); 
+{
+	flags.e = 1;
+	return flags;
 }
 
 static inline struct openflags of_cloexec(struct openflags flags)
-{ 
-	flags.cl = 1; 
-	return(flags); 
+{
+	flags.cl = 1;
+	return flags;
 }
-  
+
 /* file.c */
 extern int os_stat_file(const char *file_name, struct uml_stat *buf);
 extern int os_stat_fd(const int fd, struct uml_stat *buf);
@@ -204,7 +204,7 @@
 
 extern int os_map_memory(void *virt, int fd, unsigned long long off,
 			 unsigned long len, int r, int w, int x);
-extern int os_protect_memory(void *addr, unsigned long len, 
+extern int os_protect_memory(void *addr, unsigned long len,
 			     int r, int w, int x);
 extern int os_unmap_memory(void *addr, int len);
 extern int os_drop_memory(void *addr, int length);
diff --git a/arch/um/kernel/vmlinux.lds.S b/arch/um/kernel/vmlinux.lds.S
index 72acdce..f8aeb44 100644
--- a/arch/um/kernel/vmlinux.lds.S
+++ b/arch/um/kernel/vmlinux.lds.S
@@ -1,5 +1,3 @@
-/* in case the preprocessor is a 32bit one */
-#undef i386
 #ifdef CONFIG_LD_SCRIPT_STATIC
 #include "uml.lds.S"
 #else
diff --git a/arch/um/os-Linux/process.c b/arch/um/os-Linux/process.c
index b1cda81..b98d3ca 100644
--- a/arch/um/os-Linux/process.c
+++ b/arch/um/os-Linux/process.c
@@ -273,12 +273,12 @@
 int run_kernel_thread(int (*fn)(void *), void *arg, void **jmp_ptr)
 {
 	jmp_buf buf;
-	int n, enable;
+	int n;
 
 	*jmp_ptr = &buf;
-	n = UML_SETJMP(&buf, enable);
+	n = UML_SETJMP(&buf);
 	if(n != 0)
-		return(n);
+		return n;
 	(*fn)(arg);
-	return(0);
+	return 0;
 }
diff --git a/arch/um/os-Linux/skas/process.c b/arch/um/os-Linux/skas/process.c
index bf35572..7baf90f 100644
--- a/arch/um/os-Linux/skas/process.c
+++ b/arch/um/os-Linux/skas/process.c
@@ -435,7 +435,6 @@
 {
 	unsigned long flags;
 	jmp_buf switch_buf, fork_buf;
-	int enable;
 
 	*switch_buf_ptr = &switch_buf;
 	*fork_buf_ptr = &fork_buf;
@@ -450,7 +449,7 @@
 	 */
 	flags = get_signals();
 	block_signals();
-	if(UML_SETJMP(&fork_buf, enable) == 0)
+	if(UML_SETJMP(&fork_buf) == 0)
 		new_thread_proc(stack, handler);
 
 	remove_sigstack();
@@ -467,21 +466,19 @@
 void thread_wait(void *sw, void *fb)
 {
 	jmp_buf buf, **switch_buf = sw, *fork_buf;
-	int enable;
 
 	*switch_buf = &buf;
 	fork_buf = fb;
-	if(UML_SETJMP(&buf, enable) == 0)
+	if(UML_SETJMP(&buf) == 0)
 		siglongjmp(*fork_buf, INIT_JMP_REMOVE_SIGSTACK);
 }
 
 void switch_threads(void *me, void *next)
 {
 	jmp_buf my_buf, **me_ptr = me, *next_buf = next;
-	int enable;
 
 	*me_ptr = &my_buf;
-	if(UML_SETJMP(&my_buf, enable) == 0)
+	if(UML_SETJMP(&my_buf) == 0)
 		UML_LONGJMP(next_buf, 1);
 }
 
@@ -495,14 +492,14 @@
 int start_idle_thread(void *stack, void *switch_buf_ptr, void **fork_buf_ptr)
 {
 	jmp_buf **switch_buf = switch_buf_ptr;
-	int n, enable;
+	int n;
 
 	set_handler(SIGWINCH, (__sighandler_t) sig_handler,
 		    SA_ONSTACK | SA_RESTART, SIGUSR1, SIGIO, SIGALRM,
 		    SIGVTALRM, -1);
 
 	*fork_buf_ptr = &initial_jmpbuf;
-	n = UML_SETJMP(&initial_jmpbuf, enable);
+	n = UML_SETJMP(&initial_jmpbuf);
 	switch(n){
 	case INIT_JMP_NEW_THREAD:
 		new_thread_proc((void *) stack, new_thread_handler);
@@ -529,14 +526,13 @@
 void initial_thread_cb_skas(void (*proc)(void *), void *arg)
 {
 	jmp_buf here;
-	int enable;
 
 	cb_proc = proc;
 	cb_arg = arg;
 	cb_back = &here;
 
 	block_signals();
-	if(UML_SETJMP(&here, enable) == 0)
+	if(UML_SETJMP(&here) == 0)
 		UML_LONGJMP(&initial_jmpbuf, INIT_JMP_CALLBACK);
 	unblock_signals();
 
diff --git a/arch/um/os-Linux/uaccess.c b/arch/um/os-Linux/uaccess.c
index e523719..865f6a6 100644
--- a/arch/um/os-Linux/uaccess.c
+++ b/arch/um/os-Linux/uaccess.c
@@ -14,11 +14,10 @@
 					int n), int *faulted_out)
 {
 	unsigned long *faddrp = (unsigned long *) fault_addr, ret;
-	int enable;
 
 	jmp_buf jbuf;
 	*fault_catcher = &jbuf;
-	if(UML_SETJMP(&jbuf, enable) == 0){
+	if(UML_SETJMP(&jbuf) == 0){
 		(*op)(to, from, n);
 		ret = 0;
 		*faulted_out = 0;
diff --git a/block/ioctl.c b/block/ioctl.c
index 9cfa2e1..309760b 100644
--- a/block/ioctl.c
+++ b/block/ioctl.c
@@ -72,7 +72,7 @@
 			bdevp = bdget_disk(disk, part);
 			if (!bdevp)
 				return -ENOMEM;
-			mutex_lock(&bdevp->bd_mutex);
+			mutex_lock_nested(&bdevp->bd_mutex, BD_MUTEX_PARTITION);
 			if (bdevp->bd_openers) {
 				mutex_unlock(&bdevp->bd_mutex);
 				bdput(bdevp);
@@ -82,7 +82,7 @@
 			fsync_bdev(bdevp);
 			invalidate_bdev(bdevp, 0);
 
-			mutex_lock(&bdev->bd_mutex);
+			mutex_lock_nested(&bdev->bd_mutex, BD_MUTEX_WHOLE);
 			delete_partition(disk, part);
 			mutex_unlock(&bdev->bd_mutex);
 			mutex_unlock(&bdevp->bd_mutex);
diff --git a/drivers/block/Kconfig b/drivers/block/Kconfig
index 93d9474..b5382ce 100644
--- a/drivers/block/Kconfig
+++ b/drivers/block/Kconfig
@@ -400,6 +400,16 @@
 	  what are you doing. If you are using IBM S/390, then set this to
 	  8192.
 
+config BLK_DEV_RAM_BLOCKSIZE
+	int "Default RAM disk block size (bytes)"
+	depends on BLK_DEV_RAM
+	default "1024"
+	help
+	  The default value is 1024 kilobytes.  PAGE_SIZE is a much more
+	  efficient choice however.  The default is kept to ensure initrd
+	  setups function - apparently needed by the rd_load_image routine
+	  that supposes the filesystem in the image uses a 1024 blocksize.
+
 config BLK_DEV_INITRD
 	bool "Initial RAM filesystem and RAM disk (initramfs/initrd) support"
 	depends on BROKEN || !FRV
diff --git a/drivers/block/cpqarray.c b/drivers/block/cpqarray.c
index 757f42d..78082ed 100644
--- a/drivers/block/cpqarray.c
+++ b/drivers/block/cpqarray.c
@@ -1739,8 +1739,6 @@
 	     (log_index < id_ctlr_buf->nr_drvs)
 	     && (log_unit < NWD);
 	     log_unit++) {
-		struct gendisk *disk = ida_gendisk[ctlr][log_unit];
-
 		size = sizeof(sense_log_drv_stat_t);
 
 		/*
diff --git a/drivers/block/rd.c b/drivers/block/rd.c
index 3cf246a..a3f64bf 100644
--- a/drivers/block/rd.c
+++ b/drivers/block/rd.c
@@ -84,7 +84,7 @@
  * behaviour. The default is still BLOCK_SIZE (needed by rd_load_image that
  * supposes the filesystem in the image uses a BLOCK_SIZE blocksize).
  */
-static int rd_blocksize = BLOCK_SIZE;		/* blocksize of the RAM disks */
+static int rd_blocksize = CONFIG_BLK_DEV_RAM_BLOCKSIZE;
 
 /*
  * Copyright (C) 2000 Linus Torvalds.
diff --git a/drivers/char/nsc_gpio.c b/drivers/char/nsc_gpio.c
index 5b91e4e..7719bd7 100644
--- a/drivers/char/nsc_gpio.c
+++ b/drivers/char/nsc_gpio.c
@@ -68,13 +68,11 @@
 			amp->gpio_config(m, ~1, 0);
 			break;
 		case 'T':
-			dev_dbg(dev, "GPIO%d output is push pull\n",
-			       m);
+			dev_dbg(dev, "GPIO%d output is push pull\n", m);
 			amp->gpio_config(m, ~2, 2);
 			break;
 		case 't':
-			dev_dbg(dev, "GPIO%d output is open drain\n",
-			       m);
+			dev_dbg(dev, "GPIO%d output is open drain\n", m);
 			amp->gpio_config(m, ~2, 0);
 			break;
 		case 'P':
diff --git a/drivers/char/pc8736x_gpio.c b/drivers/char/pc8736x_gpio.c
index 11bd78c..645eb81 100644
--- a/drivers/char/pc8736x_gpio.c
+++ b/drivers/char/pc8736x_gpio.c
@@ -212,22 +212,21 @@
 	pc8736x_gpio_set(index, !pc8736x_gpio_current(index));
 }
 
-static struct nsc_gpio_ops pc8736x_access = {
+static struct nsc_gpio_ops pc8736x_gpio_ops = {
 	.owner		= THIS_MODULE,
 	.gpio_config	= pc8736x_gpio_configure,
 	.gpio_dump	= nsc_gpio_dump,
 	.gpio_get	= pc8736x_gpio_get,
 	.gpio_set	= pc8736x_gpio_set,
-	.gpio_set_high	= pc8736x_gpio_set_high,
-	.gpio_set_low	= pc8736x_gpio_set_low,
 	.gpio_change	= pc8736x_gpio_change,
 	.gpio_current	= pc8736x_gpio_current
 };
+EXPORT_SYMBOL(pc8736x_gpio_ops);
 
 static int pc8736x_gpio_open(struct inode *inode, struct file *file)
 {
 	unsigned m = iminor(inode);
-	file->private_data = &pc8736x_access;
+	file->private_data = &pc8736x_gpio_ops;
 
 	dev_dbg(&pdev->dev, "open %d\n", m);
 
@@ -236,7 +235,7 @@
 	return nonseekable_open(inode, file);
 }
 
-static const struct file_operations pc8736x_gpio_fops = {
+static const struct file_operations pc8736x_gpio_fileops = {
 	.owner	= THIS_MODULE,
 	.open	= pc8736x_gpio_open,
 	.write	= nsc_gpio_write,
@@ -278,7 +277,7 @@
 		dev_err(&pdev->dev, "no device found\n");
 		goto undo_platform_dev_add;
 	}
-	pc8736x_access.dev = &pdev->dev;
+	pc8736x_gpio_ops.dev = &pdev->dev;
 
 	/* Verify that chip and it's GPIO unit are both enabled.
 	   My BIOS does this, so I take minimum action here
@@ -328,7 +327,7 @@
 	pc8736x_init_shadow();
 
 	/* ignore minor errs, and succeed */
-	cdev_init(&pc8736x_gpio_cdev, &pc8736x_gpio_fops);
+	cdev_init(&pc8736x_gpio_cdev, &pc8736x_gpio_fileops);
 	cdev_add(&pc8736x_gpio_cdev, devid, PC8736X_GPIO_CT);
 
 	return 0;
@@ -355,7 +354,5 @@
 	platform_device_put(pdev);
 }
 
-EXPORT_SYMBOL(pc8736x_access);
-
 module_init(pc8736x_gpio_init);
 module_exit(pc8736x_gpio_cleanup);
diff --git a/drivers/char/scx200_gpio.c b/drivers/char/scx200_gpio.c
index 425c587..b956c7b 100644
--- a/drivers/char/scx200_gpio.c
+++ b/drivers/char/scx200_gpio.c
@@ -5,7 +5,6 @@
 
    Copyright (c) 2001,2002 Christer Weinigel <wingel@nano-system.com> */
 
-#include <linux/config.h>
 #include <linux/device.h>
 #include <linux/fs.h>
 #include <linux/module.h>
@@ -22,37 +21,37 @@
 #include <linux/scx200_gpio.h>
 #include <linux/nsc_gpio.h>
 
-#define NAME "scx200_gpio"
-#define DEVNAME NAME
+#define DRVNAME "scx200_gpio"
 
 static struct platform_device *pdev;
 
 MODULE_AUTHOR("Christer Weinigel <wingel@nano-system.com>");
-MODULE_DESCRIPTION("NatSemi SCx200 GPIO Pin Driver");
+MODULE_DESCRIPTION("NatSemi/AMD SCx200 GPIO Pin Driver");
 MODULE_LICENSE("GPL");
 
 static int major = 0;		/* default to dynamic major */
 module_param(major, int, 0);
 MODULE_PARM_DESC(major, "Major device number");
 
-struct nsc_gpio_ops scx200_access = {
+#define MAX_PINS 32		/* 64 later, when known ok */
+
+struct nsc_gpio_ops scx200_gpio_ops = {
 	.owner		= THIS_MODULE,
 	.gpio_config	= scx200_gpio_configure,
 	.gpio_dump	= nsc_gpio_dump,
 	.gpio_get	= scx200_gpio_get,
 	.gpio_set	= scx200_gpio_set,
-	.gpio_set_high	= scx200_gpio_set_high,
-	.gpio_set_low	= scx200_gpio_set_low,
 	.gpio_change	= scx200_gpio_change,
 	.gpio_current	= scx200_gpio_current
 };
+EXPORT_SYMBOL(scx200_gpio_ops);
 
 static int scx200_gpio_open(struct inode *inode, struct file *file)
 {
 	unsigned m = iminor(inode);
-	file->private_data = &scx200_access;
+	file->private_data = &scx200_gpio_ops;
 
-	if (m > 63)
+	if (m >= MAX_PINS)
 		return -EINVAL;
 	return nonseekable_open(inode, file);
 }
@@ -62,8 +61,7 @@
 	return 0;
 }
 
-
-static const struct file_operations scx200_gpio_fops = {
+static const struct file_operations scx200_gpio_fileops = {
 	.owner   = THIS_MODULE,
 	.write   = nsc_gpio_write,
 	.read    = nsc_gpio_read,
@@ -71,21 +69,20 @@
 	.release = scx200_gpio_release,
 };
 
-struct cdev *scx200_devices;
-static int num_pins = 32;
+struct cdev scx200_gpio_cdev;  /* use 1 cdev for all pins */
 
 static int __init scx200_gpio_init(void)
 {
-	int rc, i;
-	dev_t dev = MKDEV(major, 0);
+	int rc;
+	dev_t devid;
 
 	if (!scx200_gpio_present()) {
-		printk(KERN_ERR NAME ": no SCx200 gpio present\n");
+		printk(KERN_ERR DRVNAME ": no SCx200 gpio present\n");
 		return -ENODEV;
 	}
 
 	/* support dev_dbg() with pdev->dev */
-	pdev = platform_device_alloc(DEVNAME, 0);
+	pdev = platform_device_alloc(DRVNAME, 0);
 	if (!pdev)
 		return -ENOMEM;
 
@@ -94,37 +91,25 @@
 		goto undo_malloc;
 
 	/* nsc_gpio uses dev_dbg(), so needs this */
-	scx200_access.dev = &pdev->dev;
+	scx200_gpio_ops.dev = &pdev->dev;
 
-	if (major)
-		rc = register_chrdev_region(dev, num_pins, "scx200_gpio");
-	else {
-		rc = alloc_chrdev_region(&dev, 0, num_pins, "scx200_gpio");
-		major = MAJOR(dev);
+	if (major) {
+		devid = MKDEV(major, 0);
+		rc = register_chrdev_region(devid, MAX_PINS, "scx200_gpio");
+	} else {
+		rc = alloc_chrdev_region(&devid, 0, MAX_PINS, "scx200_gpio");
+		major = MAJOR(devid);
 	}
 	if (rc < 0) {
 		dev_err(&pdev->dev, "SCx200 chrdev_region err: %d\n", rc);
 		goto undo_platform_device_add;
 	}
-	scx200_devices = kzalloc(num_pins * sizeof(struct cdev), GFP_KERNEL);
-	if (!scx200_devices) {
-		rc = -ENOMEM;
-		goto undo_chrdev_region;
-	}
-	for (i = 0; i < num_pins; i++) {
-		struct cdev *cdev = &scx200_devices[i];
-		cdev_init(cdev, &scx200_gpio_fops);
-		cdev->owner = THIS_MODULE;
-		rc = cdev_add(cdev, MKDEV(major, i), 1);
-		/* tolerate 'minor' errors */
-		if (rc)
-			dev_err(&pdev->dev, "Error %d on minor %d", rc, i);
-	}
+
+	cdev_init(&scx200_gpio_cdev, &scx200_gpio_fileops);
+	cdev_add(&scx200_gpio_cdev, devid, MAX_PINS);
 
 	return 0; /* succeed */
 
-undo_chrdev_region:
-	unregister_chrdev_region(dev, num_pins);
 undo_platform_device_add:
 	platform_device_del(pdev);
 undo_malloc:
@@ -135,10 +120,11 @@
 
 static void __exit scx200_gpio_cleanup(void)
 {
-	kfree(scx200_devices);
-	unregister_chrdev_region(MKDEV(major, 0), num_pins);
+	cdev_del(&scx200_gpio_cdev);
+	/* cdev_put(&scx200_gpio_cdev); */
+
+	unregister_chrdev_region(MKDEV(major, 0), MAX_PINS);
 	platform_device_unregister(pdev);
-	/* kfree(pdev); */
 }
 
 module_init(scx200_gpio_init);
diff --git a/drivers/char/tpm/tpm.c b/drivers/char/tpm/tpm.c
index 6889e7d..a082a2e 100644
--- a/drivers/char/tpm/tpm.c
+++ b/drivers/char/tpm/tpm.c
@@ -1141,6 +1141,7 @@
 		put_device(dev);
 		clear_bit(chip->dev_num, dev_mask);
 		kfree(chip);
+		kfree(devname);
 		return NULL;
 	}
 
diff --git a/drivers/char/tpm/tpm_tis.c b/drivers/char/tpm/tpm_tis.c
index 3232b19..ee7ac6f 100644
--- a/drivers/char/tpm/tpm_tis.c
+++ b/drivers/char/tpm/tpm_tis.c
@@ -424,6 +424,7 @@
 	iowrite32(interrupt,
 		  chip->vendor.iobase +
 		  TPM_INT_STATUS(chip->vendor.locality));
+	ioread32(chip->vendor.iobase + TPM_INT_STATUS(chip->vendor.locality));
 	return IRQ_HANDLED;
 }
 
@@ -431,23 +432,19 @@
 module_param(interrupts, bool, 0444);
 MODULE_PARM_DESC(interrupts, "Enable interrupts");
 
-static int __devinit tpm_tis_pnp_init(struct pnp_dev *pnp_dev,
-				      const struct pnp_device_id *pnp_id)
+static int tpm_tis_init(struct device *dev, resource_size_t start,
+			resource_size_t len)
 {
 	u32 vendor, intfcaps, intmask;
 	int rc, i;
-	unsigned long start, len;
 	struct tpm_chip *chip;
 
-	start = pnp_mem_start(pnp_dev, 0);
-	len = pnp_mem_len(pnp_dev, 0);
-
 	if (!start)
 		start = TIS_MEM_BASE;
 	if (!len)
 		len = TIS_MEM_LEN;
 
-	if (!(chip = tpm_register_hardware(&pnp_dev->dev, &tpm_tis)))
+	if (!(chip = tpm_register_hardware(dev, &tpm_tis)))
 		return -ENODEV;
 
 	chip->vendor.iobase = ioremap(start, len);
@@ -464,7 +461,7 @@
 	chip->vendor.timeout_c = msecs_to_jiffies(TIS_SHORT_TIMEOUT);
 	chip->vendor.timeout_d = msecs_to_jiffies(TIS_SHORT_TIMEOUT);
 
-	dev_info(&pnp_dev->dev,
+	dev_info(dev,
 		 "1.2 TPM (device-id 0x%X, rev-id %d)\n",
 		 vendor >> 16, ioread8(chip->vendor.iobase + TPM_RID(0)));
 
@@ -472,26 +469,26 @@
 	intfcaps =
 	    ioread32(chip->vendor.iobase +
 		     TPM_INTF_CAPS(chip->vendor.locality));
-	dev_dbg(&pnp_dev->dev, "TPM interface capabilities (0x%x):\n",
+	dev_dbg(dev, "TPM interface capabilities (0x%x):\n",
 		intfcaps);
 	if (intfcaps & TPM_INTF_BURST_COUNT_STATIC)
-		dev_dbg(&pnp_dev->dev, "\tBurst Count Static\n");
+		dev_dbg(dev, "\tBurst Count Static\n");
 	if (intfcaps & TPM_INTF_CMD_READY_INT)
-		dev_dbg(&pnp_dev->dev, "\tCommand Ready Int Support\n");
+		dev_dbg(dev, "\tCommand Ready Int Support\n");
 	if (intfcaps & TPM_INTF_INT_EDGE_FALLING)
-		dev_dbg(&pnp_dev->dev, "\tInterrupt Edge Falling\n");
+		dev_dbg(dev, "\tInterrupt Edge Falling\n");
 	if (intfcaps & TPM_INTF_INT_EDGE_RISING)
-		dev_dbg(&pnp_dev->dev, "\tInterrupt Edge Rising\n");
+		dev_dbg(dev, "\tInterrupt Edge Rising\n");
 	if (intfcaps & TPM_INTF_INT_LEVEL_LOW)
-		dev_dbg(&pnp_dev->dev, "\tInterrupt Level Low\n");
+		dev_dbg(dev, "\tInterrupt Level Low\n");
 	if (intfcaps & TPM_INTF_INT_LEVEL_HIGH)
-		dev_dbg(&pnp_dev->dev, "\tInterrupt Level High\n");
+		dev_dbg(dev, "\tInterrupt Level High\n");
 	if (intfcaps & TPM_INTF_LOCALITY_CHANGE_INT)
-		dev_dbg(&pnp_dev->dev, "\tLocality Change Int Support\n");
+		dev_dbg(dev, "\tLocality Change Int Support\n");
 	if (intfcaps & TPM_INTF_STS_VALID_INT)
-		dev_dbg(&pnp_dev->dev, "\tSts Valid Int Support\n");
+		dev_dbg(dev, "\tSts Valid Int Support\n");
 	if (intfcaps & TPM_INTF_DATA_AVAIL_INT)
-		dev_dbg(&pnp_dev->dev, "\tData Avail Int Support\n");
+		dev_dbg(dev, "\tData Avail Int Support\n");
 
 	if (request_locality(chip, 0) != 0) {
 		rc = -ENODEV;
@@ -594,6 +591,16 @@
 	return rc;
 }
 
+static int __devinit tpm_tis_pnp_init(struct pnp_dev *pnp_dev,
+				      const struct pnp_device_id *pnp_id)
+{
+	resource_size_t start, len;
+	start = pnp_mem_start(pnp_dev, 0);
+	len = pnp_mem_len(pnp_dev, 0);
+
+	return tpm_tis_init(&pnp_dev->dev, start, len);
+}
+
 static int tpm_tis_pnp_suspend(struct pnp_dev *dev, pm_message_t msg)
 {
 	return tpm_pm_suspend(&dev->dev, msg);
@@ -628,8 +635,36 @@
 		    sizeof(tpm_pnp_tbl[TIS_HID_USR_IDX].id), 0444);
 MODULE_PARM_DESC(hid, "Set additional specific HID for this driver to probe");
 
+static struct device_driver tis_drv = {
+	.name = "tpm_tis",
+	.bus = &platform_bus_type,
+	.owner = THIS_MODULE,
+	.suspend = tpm_pm_suspend,
+	.resume = tpm_pm_resume,
+};
+
+static struct platform_device *pdev;
+
+static int force;
+module_param(force, bool, 0444);
+MODULE_PARM_DESC(force, "Force device probe rather than using ACPI entry");
 static int __init init_tis(void)
 {
+	int rc;
+
+	if (force) {
+		rc = driver_register(&tis_drv);
+		if (rc < 0)
+			return rc;
+		if (IS_ERR(pdev=platform_device_register_simple("tpm_tis", -1, NULL, 0)))
+			return PTR_ERR(pdev);
+		if((rc=tpm_tis_init(&pdev->dev, 0, 0)) != 0) {
+			platform_device_unregister(pdev);
+			driver_unregister(&tis_drv);
+		}
+		return rc;
+	}
+
 	return pnp_register_driver(&tis_pnp_driver);
 }
 
@@ -654,7 +689,11 @@
 		tpm_remove_hardware(chip->dev);
 	}
 	spin_unlock(&tis_lock);
-	pnp_unregister_driver(&tis_pnp_driver);
+	if (force) {
+		platform_device_unregister(pdev);
+		driver_unregister(&tis_drv);
+	} else
+		pnp_unregister_driver(&tis_pnp_driver);
 }
 
 module_init(init_tis);
diff --git a/drivers/infiniband/core/cm.c b/drivers/infiniband/core/cm.c
index 3f6705f..f85c97f 100644
--- a/drivers/infiniband/core/cm.c
+++ b/drivers/infiniband/core/cm.c
@@ -701,7 +701,7 @@
 	}
 }
 
-void ib_destroy_cm_id(struct ib_cm_id *cm_id)
+static void cm_destroy_id(struct ib_cm_id *cm_id, int err)
 {
 	struct cm_id_private *cm_id_priv;
 	struct cm_work *work;
@@ -735,12 +735,22 @@
 			       sizeof cm_id_priv->av.port->cm_dev->ca_guid,
 			       NULL, 0);
 		break;
+	case IB_CM_REQ_RCVD:
+		if (err == -ENOMEM) {
+			/* Do not reject to allow future retries. */
+			cm_reset_to_idle(cm_id_priv);
+			spin_unlock_irqrestore(&cm_id_priv->lock, flags);
+		} else {
+			spin_unlock_irqrestore(&cm_id_priv->lock, flags);
+			ib_send_cm_rej(cm_id, IB_CM_REJ_CONSUMER_DEFINED,
+				       NULL, 0, NULL, 0);
+		}
+		break;
 	case IB_CM_MRA_REQ_RCVD:
 	case IB_CM_REP_SENT:
 	case IB_CM_MRA_REP_RCVD:
 		ib_cancel_mad(cm_id_priv->av.port->mad_agent, cm_id_priv->msg);
 		/* Fall through */
-	case IB_CM_REQ_RCVD:
 	case IB_CM_MRA_REQ_SENT:
 	case IB_CM_REP_RCVD:
 	case IB_CM_MRA_REP_SENT:
@@ -775,6 +785,11 @@
 	kfree(cm_id_priv->private_data);
 	kfree(cm_id_priv);
 }
+
+void ib_destroy_cm_id(struct ib_cm_id *cm_id)
+{
+	cm_destroy_id(cm_id, 0);
+}
 EXPORT_SYMBOL(ib_destroy_cm_id);
 
 int ib_cm_listen(struct ib_cm_id *cm_id, __be64 service_id, __be64 service_mask,
@@ -1163,7 +1178,7 @@
 	}
 	cm_deref_id(cm_id_priv);
 	if (ret)
-		ib_destroy_cm_id(&cm_id_priv->id);
+		cm_destroy_id(&cm_id_priv->id, ret);
 }
 
 static void cm_format_mra(struct cm_mra_msg *mra_msg,
diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c
index 863f64b..d6f99d5 100644
--- a/drivers/infiniband/core/cma.c
+++ b/drivers/infiniband/core/cma.c
@@ -262,14 +262,14 @@
 static int cma_acquire_ib_dev(struct rdma_id_private *id_priv)
 {
 	struct cma_device *cma_dev;
-	union ib_gid *gid;
+	union ib_gid gid;
 	int ret = -ENODEV;
 
-	gid = ib_addr_get_sgid(&id_priv->id.route.addr.dev_addr);
+	ib_addr_get_sgid(&id_priv->id.route.addr.dev_addr, &gid),
 
 	mutex_lock(&lock);
 	list_for_each_entry(cma_dev, &dev_list, list) {
-		ret = ib_find_cached_gid(cma_dev->device, gid,
+		ret = ib_find_cached_gid(cma_dev->device, &gid,
 					 &id_priv->id.port_num, NULL);
 		if (!ret) {
 			cma_attach_to_dev(id_priv, cma_dev);
@@ -812,6 +812,7 @@
 		cma_modify_qp_err(&id_priv->id);
 		status = ib_event->param.rej_rcvd.reason;
 		event = RDMA_CM_EVENT_REJECTED;
+		private_data_len = IB_CM_REJ_PRIVATE_DATA_SIZE;
 		break;
 	default:
 		printk(KERN_ERR "RDMA CMA: unexpected IB CM event: %d",
@@ -1134,8 +1135,8 @@
 	struct ib_sa_path_rec path_rec;
 
 	memset(&path_rec, 0, sizeof path_rec);
-	path_rec.sgid = *ib_addr_get_sgid(addr);
-	path_rec.dgid = *ib_addr_get_dgid(addr);
+	ib_addr_get_sgid(addr, &path_rec.sgid);
+	ib_addr_get_dgid(addr, &path_rec.dgid);
 	path_rec.pkey = cpu_to_be16(ib_addr_get_pkey(addr));
 	path_rec.numb_path = 1;
 
@@ -1263,7 +1264,7 @@
 {
 	struct cma_device *cma_dev;
 	struct ib_port_attr port_attr;
-	union ib_gid *gid;
+	union ib_gid gid;
 	u16 pkey;
 	int ret;
 	u8 p;
@@ -1284,8 +1285,7 @@
 	}
 
 port_found:
-	gid = ib_addr_get_sgid(&id_priv->id.route.addr.dev_addr);
-	ret = ib_get_cached_gid(cma_dev->device, p, 0, gid);
+	ret = ib_get_cached_gid(cma_dev->device, p, 0, &gid);
 	if (ret)
 		goto out;
 
@@ -1293,6 +1293,7 @@
 	if (ret)
 		goto out;
 
+	ib_addr_set_sgid(&id_priv->id.route.addr.dev_addr, &gid);
 	ib_addr_set_pkey(&id_priv->id.route.addr.dev_addr, pkey);
 	id_priv->id.port_num = p;
 	cma_attach_to_dev(id_priv, cma_dev);
@@ -1339,6 +1340,7 @@
 {
 	struct cma_work *work;
 	struct sockaddr_in *src_in, *dst_in;
+	union ib_gid gid;
 	int ret;
 
 	work = kzalloc(sizeof *work, GFP_KERNEL);
@@ -1351,8 +1353,8 @@
 			goto err;
 	}
 
-	ib_addr_set_dgid(&id_priv->id.route.addr.dev_addr,
-			 ib_addr_get_sgid(&id_priv->id.route.addr.dev_addr));
+	ib_addr_get_sgid(&id_priv->id.route.addr.dev_addr, &gid);
+	ib_addr_set_dgid(&id_priv->id.route.addr.dev_addr, &gid);
 
 	if (cma_zero_addr(&id_priv->id.route.addr.src_addr)) {
 		src_in = (struct sockaddr_in *)&id_priv->id.route.addr.src_addr;
diff --git a/drivers/infiniband/core/fmr_pool.c b/drivers/infiniband/core/fmr_pool.c
index 615fe9c..86a3b2d 100644
--- a/drivers/infiniband/core/fmr_pool.c
+++ b/drivers/infiniband/core/fmr_pool.c
@@ -426,7 +426,7 @@
 struct ib_pool_fmr *ib_fmr_pool_map_phys(struct ib_fmr_pool *pool_handle,
 					 u64                *page_list,
 					 int                 list_len,
-					 u64                *io_virtual_address)
+					 u64                 io_virtual_address)
 {
 	struct ib_fmr_pool *pool = pool_handle;
 	struct ib_pool_fmr *fmr;
@@ -440,7 +440,7 @@
 	fmr = ib_fmr_cache_lookup(pool,
 				  page_list,
 				  list_len,
-				  *io_virtual_address);
+				  io_virtual_address);
 	if (fmr) {
 		/* found in cache */
 		++fmr->ref_count;
@@ -464,7 +464,7 @@
 	spin_unlock_irqrestore(&pool->pool_lock, flags);
 
 	result = ib_map_phys_fmr(fmr->fmr, page_list, list_len,
-				 *io_virtual_address);
+				 io_virtual_address);
 
 	if (result) {
 		spin_lock_irqsave(&pool->pool_lock, flags);
@@ -481,7 +481,7 @@
 	fmr->ref_count = 1;
 
 	if (pool->cache_bucket) {
-		fmr->io_virtual_address = *io_virtual_address;
+		fmr->io_virtual_address = io_virtual_address;
 		fmr->page_list_len      = list_len;
 		memcpy(fmr->page_list, page_list, list_len * sizeof(*page_list));
 
diff --git a/drivers/infiniband/core/sa_query.c b/drivers/infiniband/core/sa_query.c
index e911c99..aeda484 100644
--- a/drivers/infiniband/core/sa_query.c
+++ b/drivers/infiniband/core/sa_query.c
@@ -488,13 +488,13 @@
 	spin_unlock_irqrestore(&tid_lock, flags);
 }
 
-static int send_mad(struct ib_sa_query *query, int timeout_ms)
+static int send_mad(struct ib_sa_query *query, int timeout_ms, gfp_t gfp_mask)
 {
 	unsigned long flags;
 	int ret, id;
 
 retry:
-	if (!idr_pre_get(&query_idr, GFP_ATOMIC))
+	if (!idr_pre_get(&query_idr, gfp_mask))
 		return -ENOMEM;
 	spin_lock_irqsave(&idr_lock, flags);
 	ret = idr_get_new(&query_idr, query, &id);
@@ -630,7 +630,7 @@
 
 	*sa_query = &query->sa_query;
 
-	ret = send_mad(&query->sa_query, timeout_ms);
+	ret = send_mad(&query->sa_query, timeout_ms, gfp_mask);
 	if (ret < 0)
 		goto err2;
 
@@ -752,7 +752,7 @@
 
 	*sa_query = &query->sa_query;
 
-	ret = send_mad(&query->sa_query, timeout_ms);
+	ret = send_mad(&query->sa_query, timeout_ms, gfp_mask);
 	if (ret < 0)
 		goto err2;
 
@@ -844,7 +844,7 @@
 
 	*sa_query = &query->sa_query;
 
-	ret = send_mad(&query->sa_query, timeout_ms);
+	ret = send_mad(&query->sa_query, timeout_ms, gfp_mask);
 	if (ret < 0)
 		goto err2;
 
diff --git a/drivers/infiniband/hw/mthca/mthca_av.c b/drivers/infiniband/hw/mthca/mthca_av.c
index b12aa03..e215041 100644
--- a/drivers/infiniband/hw/mthca/mthca_av.c
+++ b/drivers/infiniband/hw/mthca/mthca_av.c
@@ -303,9 +303,10 @@
 	memset(attr, 0, sizeof *attr);
 	attr->dlid          = be16_to_cpu(ah->av->dlid);
 	attr->sl            = be32_to_cpu(ah->av->sl_tclass_flowlabel) >> 28;
-	attr->static_rate   = ah->av->msg_sr & 0x7;
-	attr->src_path_bits = ah->av->g_slid & 0x7F;
 	attr->port_num      = be32_to_cpu(ah->av->port_pd) >> 24;
+	attr->static_rate   = mthca_rate_to_ib(dev, ah->av->msg_sr & 0x7,
+					       attr->port_num);
+	attr->src_path_bits = ah->av->g_slid & 0x7F;
 	attr->ah_flags      = mthca_ah_grh_present(ah) ? IB_AH_GRH : 0;
 
 	if (attr->ah_flags) {
diff --git a/drivers/infiniband/hw/mthca/mthca_qp.c b/drivers/infiniband/hw/mthca/mthca_qp.c
index 490fc78..cd8b672 100644
--- a/drivers/infiniband/hw/mthca/mthca_qp.c
+++ b/drivers/infiniband/hw/mthca/mthca_qp.c
@@ -222,9 +222,8 @@
 			 (PAGE_SIZE - 1));
 }
 
-static void mthca_wq_init(struct mthca_wq *wq)
+static void mthca_wq_reset(struct mthca_wq *wq)
 {
-	/* mthca_alloc_qp_common() initializes the locks */
 	wq->next_ind  = 0;
 	wq->last_comp = wq->max - 1;
 	wq->head      = 0;
@@ -845,10 +844,10 @@
 			mthca_cq_clean(dev, to_mcq(qp->ibqp.recv_cq), qp->qpn,
 				       qp->ibqp.srq ? to_msrq(qp->ibqp.srq) : NULL);
 
-		mthca_wq_init(&qp->sq);
+		mthca_wq_reset(&qp->sq);
 		qp->sq.last = get_send_wqe(qp, qp->sq.max - 1);
 
-		mthca_wq_init(&qp->rq);
+		mthca_wq_reset(&qp->rq);
 		qp->rq.last = get_recv_wqe(qp, qp->rq.max - 1);
 
 		if (mthca_is_memfree(dev)) {
@@ -1112,9 +1111,9 @@
 	qp->atomic_rd_en = 0;
 	qp->resp_depth   = 0;
 	qp->sq_policy    = send_policy;
-	mthca_wq_init(&qp->sq);
-	mthca_wq_init(&qp->rq);
-	/* these are initialized separately so lockdep can tell them apart */
+	mthca_wq_reset(&qp->sq);
+	mthca_wq_reset(&qp->rq);
+
 	spin_lock_init(&qp->sq.lock);
 	spin_lock_init(&qp->rq.lock);
 
diff --git a/drivers/infiniband/ulp/iser/iser_verbs.c b/drivers/infiniband/ulp/iser/iser_verbs.c
index ff117bb..72febf1 100644
--- a/drivers/infiniband/ulp/iser/iser_verbs.c
+++ b/drivers/infiniband/ulp/iser/iser_verbs.c
@@ -594,7 +594,7 @@
 	mem  = ib_fmr_pool_map_phys(ib_conn->fmr_pool,
 				    page_list,
 				    page_vec->length,
-				    &io_addr);
+				    io_addr);
 
 	if (IS_ERR(mem)) {
 		status = (int)PTR_ERR(mem);
diff --git a/drivers/infiniband/ulp/srp/ib_srp.c b/drivers/infiniband/ulp/srp/ib_srp.c
index 4e22afe..8f472e7 100644
--- a/drivers/infiniband/ulp/srp/ib_srp.c
+++ b/drivers/infiniband/ulp/srp/ib_srp.c
@@ -615,9 +615,10 @@
 				(sg_dma_address(&scat[i]) & dev->fmr_page_mask) + j;
 
 	req->fmr = ib_fmr_pool_map_phys(dev->fmr_pool,
-					dma_pages, page_cnt, &io_addr);
+					dma_pages, page_cnt, io_addr);
 	if (IS_ERR(req->fmr)) {
 		ret = PTR_ERR(req->fmr);
+		req->fmr = NULL;
 		goto out;
 	}
 
diff --git a/drivers/leds/leds-net48xx.c b/drivers/leds/leds-net48xx.c
index 35ee52f..713c4a8 100644
--- a/drivers/leds/leds-net48xx.c
+++ b/drivers/leds/leds-net48xx.c
@@ -18,6 +18,7 @@
 #include <asm/io.h>
 #include <linux/scx200_gpio.h>
 
+#define DRVNAME "net48xx-led"
 #define NET48XX_ERROR_LED_GPIO	20
 
 static struct platform_device *pdev;
@@ -66,13 +67,13 @@
 }
 
 static struct platform_driver net48xx_led_driver = {
-	.driver.owner	= THIS_MODULE,
 	.probe		= net48xx_led_probe,
 	.remove		= net48xx_led_remove,
 	.suspend	= net48xx_led_suspend,
 	.resume		= net48xx_led_resume,
 	.driver		= {
-		.name = "net48xx-led",
+		.name		= DRVNAME,
+		.owner		= THIS_MODULE,
 	},
 };
 
@@ -89,7 +90,7 @@
 	if (ret < 0)
 		goto out;
 
-	pdev = platform_device_register_simple("net48xx-led", -1, NULL, 0);
+	pdev = platform_device_register_simple(DRVNAME, -1, NULL, 0);
 	if (IS_ERR(pdev)) {
 		ret = PTR_ERR(pdev);
 		platform_driver_unregister(&net48xx_led_driver);
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
index f5b9f18..7ff1d88 100644
--- a/drivers/rtc/Kconfig
+++ b/drivers/rtc/Kconfig
@@ -121,6 +121,16 @@
 	  This driver can also be built as a module. If so, the module
 	  will be called rtc-ds1553.
 
+config RTC_DRV_ISL1208
+	tristate "Intersil 1208"
+	depends on RTC_CLASS && I2C
+	help
+	  If you say yes here you get support for the
+	  Intersil 1208 RTC chip.
+
+	  This driver can also be built as a module. If so, the module
+	  will be called rtc-isl1208.
+
 config RTC_DRV_DS1672
 	tristate "Dallas/Maxim DS1672"
 	depends on RTC_CLASS && I2C
diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile
index 5422071..bbcfb09 100644
--- a/drivers/rtc/Makefile
+++ b/drivers/rtc/Makefile
@@ -12,6 +12,7 @@
 obj-$(CONFIG_RTC_INTF_DEV)	+= rtc-dev.o
 
 obj-$(CONFIG_RTC_DRV_X1205)	+= rtc-x1205.o
+obj-$(CONFIG_RTC_DRV_ISL1208)	+= rtc-isl1208.o
 obj-$(CONFIG_RTC_DRV_TEST)	+= rtc-test.o
 obj-$(CONFIG_RTC_DRV_DS1307)	+= rtc-ds1307.o
 obj-$(CONFIG_RTC_DRV_DS1672)	+= rtc-ds1672.o
diff --git a/drivers/rtc/rtc-isl1208.c b/drivers/rtc/rtc-isl1208.c
new file mode 100644
index 0000000..f324d0a
--- /dev/null
+++ b/drivers/rtc/rtc-isl1208.c
@@ -0,0 +1,591 @@
+/*
+ * Intersil ISL1208 rtc class driver
+ *
+ * Copyright 2005,2006 Hebert Valerio Riedel <hvr@gnu.org>
+ *
+ *  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.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/i2c.h>
+#include <linux/bcd.h>
+#include <linux/rtc.h>
+
+#define DRV_NAME "isl1208"
+#define DRV_VERSION "0.2"
+
+/* Register map */
+/* rtc section */
+#define ISL1208_REG_SC  0x00
+#define ISL1208_REG_MN  0x01
+#define ISL1208_REG_HR  0x02
+#define ISL1208_REG_HR_MIL     (1<<7) /* 24h/12h mode */
+#define ISL1208_REG_HR_PM      (1<<5) /* PM/AM bit in 12h mode */
+#define ISL1208_REG_DT  0x03
+#define ISL1208_REG_MO  0x04
+#define ISL1208_REG_YR  0x05
+#define ISL1208_REG_DW  0x06
+#define ISL1208_RTC_SECTION_LEN 7
+
+/* control/status section */
+#define ISL1208_REG_SR  0x07
+#define ISL1208_REG_SR_ARST    (1<<7) /* auto reset */
+#define ISL1208_REG_SR_XTOSCB  (1<<6) /* crystal oscillator */
+#define ISL1208_REG_SR_WRTC    (1<<4) /* write rtc */
+#define ISL1208_REG_SR_ALM     (1<<2) /* alarm */
+#define ISL1208_REG_SR_BAT     (1<<1) /* battery */
+#define ISL1208_REG_SR_RTCF    (1<<0) /* rtc fail */
+#define ISL1208_REG_INT 0x08
+#define ISL1208_REG_09  0x09 /* reserved */
+#define ISL1208_REG_ATR 0x0a
+#define ISL1208_REG_DTR 0x0b
+
+/* alarm section */
+#define ISL1208_REG_SCA 0x0c
+#define ISL1208_REG_MNA 0x0d
+#define ISL1208_REG_HRA 0x0e
+#define ISL1208_REG_DTA 0x0f
+#define ISL1208_REG_MOA 0x10
+#define ISL1208_REG_DWA 0x11
+#define ISL1208_ALARM_SECTION_LEN 6
+
+/* user section */
+#define ISL1208_REG_USR1 0x12
+#define ISL1208_REG_USR2 0x13
+#define ISL1208_USR_SECTION_LEN 2
+
+/* i2c configuration */
+#define ISL1208_I2C_ADDR 0xde
+
+static unsigned short normal_i2c[] = {
+	ISL1208_I2C_ADDR>>1, I2C_CLIENT_END
+};
+I2C_CLIENT_INSMOD; /* defines addr_data */
+
+static int isl1208_attach_adapter(struct i2c_adapter *adapter);
+static int isl1208_detach_client(struct i2c_client *client);
+
+static struct i2c_driver isl1208_driver = {
+	.driver		= {
+		.name	= DRV_NAME,
+	},
+	.id		= I2C_DRIVERID_ISL1208,
+	.attach_adapter = &isl1208_attach_adapter,
+	.detach_client	= &isl1208_detach_client,
+};
+
+/* block read */
+static int
+isl1208_i2c_read_regs(struct i2c_client *client, u8 reg, u8 buf[],
+		       unsigned len)
+{
+	u8 reg_addr[1] = { reg };
+	struct i2c_msg msgs[2] = {
+		{ client->addr, client->flags, sizeof(reg_addr), reg_addr },
+		{ client->addr, client->flags | I2C_M_RD, len, buf }
+	};
+	int ret;
+
+	BUG_ON(len == 0);
+	BUG_ON(reg > ISL1208_REG_USR2);
+	BUG_ON(reg + len > ISL1208_REG_USR2 + 1);
+
+	ret = i2c_transfer(client->adapter, msgs, 2);
+	if (ret > 0)
+		ret = 0;
+	return ret;
+}
+
+/* block write */
+static int
+isl1208_i2c_set_regs(struct i2c_client *client, u8 reg, u8 const buf[],
+		       unsigned len)
+{
+	u8 i2c_buf[ISL1208_REG_USR2 + 2];
+	struct i2c_msg msgs[1] = {
+		{ client->addr, client->flags, len + 1, i2c_buf }
+	};
+	int ret;
+
+	BUG_ON(len == 0);
+	BUG_ON(reg > ISL1208_REG_USR2);
+	BUG_ON(reg + len > ISL1208_REG_USR2 + 1);
+
+	i2c_buf[0] = reg;
+	memcpy(&i2c_buf[1], &buf[0], len);
+
+	ret = i2c_transfer(client->adapter, msgs, 1);
+	if (ret > 0)
+		ret = 0;
+	return ret;
+}
+
+/* simple check to see wether we have a isl1208 */
+static int isl1208_i2c_validate_client(struct i2c_client *client)
+{
+	u8 regs[ISL1208_RTC_SECTION_LEN] = { 0, };
+	u8 zero_mask[ISL1208_RTC_SECTION_LEN] = {
+		0x80, 0x80, 0x40, 0xc0, 0xe0, 0x00, 0xf8
+	};
+	int i;
+	int ret;
+
+	ret = isl1208_i2c_read_regs(client, 0, regs, ISL1208_RTC_SECTION_LEN);
+	if (ret < 0)
+		return ret;
+
+	for (i = 0; i < ISL1208_RTC_SECTION_LEN; ++i) {
+		if (regs[i] & zero_mask[i]) /* check if bits are cleared */
+			return -ENODEV;
+	}
+
+	return 0;
+}
+
+static int isl1208_i2c_get_sr(struct i2c_client *client)
+{
+	return i2c_smbus_read_byte_data(client, ISL1208_REG_SR) == -1 ? -EIO:0;
+}
+
+static int isl1208_i2c_get_atr(struct i2c_client *client)
+{
+	int atr = i2c_smbus_read_byte_data(client, ISL1208_REG_ATR);
+
+	if (atr < 0)
+		return -EIO;
+
+	/* The 6bit value in the ATR register controls the load
+	 * capacitance C_load * in steps of 0.25pF
+	 *
+	 * bit (1<<5) of the ATR register is inverted
+	 *
+	 * C_load(ATR=0x20) =  4.50pF
+	 * C_load(ATR=0x00) = 12.50pF
+	 * C_load(ATR=0x1f) = 20.25pF
+	 *
+	 */
+
+	atr &= 0x3f; /* mask out lsb */
+	atr ^= 1<<5; /* invert 6th bit */
+	atr += 2*9; /* add offset of 4.5pF; unit[atr] = 0.25pF */
+
+	return atr;
+}
+
+static int isl1208_i2c_get_dtr(struct i2c_client *client)
+{
+	int dtr = i2c_smbus_read_byte_data(client, ISL1208_REG_DTR);
+
+	if (dtr < 0)
+		return -EIO;
+
+	/* dtr encodes adjustments of {-60,-40,-20,0,20,40,60} ppm */
+	dtr = ((dtr & 0x3) * 20) * (dtr & (1<<2) ? -1 : 1);
+
+	return dtr;
+}
+
+static int isl1208_i2c_get_usr(struct i2c_client *client)
+{
+	u8 buf[ISL1208_USR_SECTION_LEN] = { 0, };
+	int ret;
+
+	ret = isl1208_i2c_read_regs (client, ISL1208_REG_USR1, buf,
+				   ISL1208_USR_SECTION_LEN);
+	if (ret < 0)
+		return ret;
+
+	return (buf[1] << 8) | buf[0];
+}
+
+static int isl1208_i2c_set_usr(struct i2c_client *client, u16 usr)
+{
+	u8 buf[ISL1208_USR_SECTION_LEN];
+
+	buf[0] = usr & 0xff;
+	buf[1] = (usr >> 8) & 0xff;
+
+	return isl1208_i2c_set_regs (client, ISL1208_REG_USR1, buf,
+				     ISL1208_USR_SECTION_LEN);
+}
+
+static int isl1208_rtc_proc(struct device *dev, struct seq_file *seq)
+{
+	struct i2c_client *const client = to_i2c_client(dev);
+	int sr, dtr, atr, usr;
+
+	sr = isl1208_i2c_get_sr(client);
+	if (sr < 0) {
+		dev_err(&client->dev, "%s: reading SR failed\n", __func__);
+		return sr;
+	}
+
+	seq_printf(seq, "status_reg\t:%s%s%s%s%s%s (0x%.2x)\n",
+		   (sr & ISL1208_REG_SR_RTCF) ? " RTCF" : "",
+		   (sr & ISL1208_REG_SR_BAT) ? " BAT" : "",
+		   (sr & ISL1208_REG_SR_ALM) ? " ALM" : "",
+		   (sr & ISL1208_REG_SR_WRTC) ? " WRTC" : "",
+		   (sr & ISL1208_REG_SR_XTOSCB) ? " XTOSCB" : "",
+		   (sr & ISL1208_REG_SR_ARST) ? " ARST" : "",
+		   sr);
+
+	seq_printf(seq, "batt_status\t: %s\n",
+		   (sr & ISL1208_REG_SR_RTCF) ? "bad" : "okay");
+
+	dtr = isl1208_i2c_get_dtr(client);
+	if (dtr >= 0 -1)
+		seq_printf(seq, "digital_trim\t: %d ppm\n", dtr);
+
+	atr = isl1208_i2c_get_atr(client);
+	if (atr >= 0)
+		seq_printf(seq, "analog_trim\t: %d.%.2d pF\n",
+			   atr>>2, (atr&0x3)*25);
+
+	usr = isl1208_i2c_get_usr(client);
+	if (usr >= 0)
+		seq_printf(seq, "user_data\t: 0x%.4x\n", usr);
+
+	return 0;
+}
+
+
+static int isl1208_i2c_read_time(struct i2c_client *client,
+				 struct rtc_time *tm)
+{
+	int sr;
+	u8 regs[ISL1208_RTC_SECTION_LEN] = { 0, };
+
+	sr = isl1208_i2c_get_sr(client);
+	if (sr < 0) {
+		dev_err(&client->dev, "%s: reading SR failed\n", __func__);
+		return -EIO;
+	}
+
+	sr = isl1208_i2c_read_regs(client, 0, regs, ISL1208_RTC_SECTION_LEN);
+	if (sr < 0) {
+		dev_err(&client->dev, "%s: reading RTC section failed\n",
+			__func__);
+		return sr;
+	}
+
+	tm->tm_sec = BCD2BIN(regs[ISL1208_REG_SC]);
+	tm->tm_min = BCD2BIN(regs[ISL1208_REG_MN]);
+	{ /* HR field has a more complex interpretation */
+		const u8 _hr = regs[ISL1208_REG_HR];
+		if (_hr & ISL1208_REG_HR_MIL) /* 24h format */
+			tm->tm_hour = BCD2BIN(_hr & 0x3f);
+		else { // 12h format
+			tm->tm_hour = BCD2BIN(_hr & 0x1f);
+			if (_hr & ISL1208_REG_HR_PM) /* PM flag set */
+				tm->tm_hour += 12;
+		}
+	}
+
+	tm->tm_mday = BCD2BIN(regs[ISL1208_REG_DT]);
+	tm->tm_mon = BCD2BIN(regs[ISL1208_REG_MO]) - 1; /* rtc starts at 1 */
+	tm->tm_year = BCD2BIN(regs[ISL1208_REG_YR]) + 100;
+	tm->tm_wday = BCD2BIN(regs[ISL1208_REG_DW]);
+
+	return 0;
+}
+
+static int isl1208_i2c_read_alarm(struct i2c_client *client,
+				  struct rtc_wkalrm *alarm)
+{
+	struct rtc_time *const tm = &alarm->time;
+	u8 regs[ISL1208_ALARM_SECTION_LEN] = { 0, };
+	int sr;
+
+	sr = isl1208_i2c_get_sr(client);
+	if (sr < 0) {
+		dev_err(&client->dev, "%s: reading SR failed\n", __func__);
+		return sr;
+	}
+
+	sr = isl1208_i2c_read_regs(client, ISL1208_REG_SCA, regs,
+				  ISL1208_ALARM_SECTION_LEN);
+	if (sr < 0) {
+		dev_err(&client->dev, "%s: reading alarm section failed\n",
+			__func__);
+		return sr;
+	}
+
+	/* MSB of each alarm register is an enable bit */
+	tm->tm_sec  = BCD2BIN(regs[ISL1208_REG_SCA-ISL1208_REG_SCA] & 0x7f);
+	tm->tm_min  = BCD2BIN(regs[ISL1208_REG_MNA-ISL1208_REG_SCA] & 0x7f);
+	tm->tm_hour = BCD2BIN(regs[ISL1208_REG_HRA-ISL1208_REG_SCA] & 0x3f);
+	tm->tm_mday = BCD2BIN(regs[ISL1208_REG_DTA-ISL1208_REG_SCA] & 0x3f);
+	tm->tm_mon  = BCD2BIN(regs[ISL1208_REG_MOA-ISL1208_REG_SCA] & 0x1f)-1;
+	tm->tm_wday = BCD2BIN(regs[ISL1208_REG_DWA-ISL1208_REG_SCA] & 0x03);
+
+	return 0;
+}
+
+static int isl1208_rtc_read_time(struct device *dev, struct rtc_time *tm)
+{
+	return isl1208_i2c_read_time(to_i2c_client(dev), tm);
+}
+
+static int isl1208_i2c_set_time(struct i2c_client *client,
+				struct rtc_time const *tm)
+{
+	int sr;
+	u8 regs[ISL1208_RTC_SECTION_LEN] = { 0, };
+
+	regs[ISL1208_REG_SC] = BIN2BCD(tm->tm_sec);
+	regs[ISL1208_REG_MN] = BIN2BCD(tm->tm_min);
+	regs[ISL1208_REG_HR] = BIN2BCD(tm->tm_hour) | ISL1208_REG_HR_MIL;
+
+	regs[ISL1208_REG_DT] = BIN2BCD(tm->tm_mday);
+	regs[ISL1208_REG_MO] = BIN2BCD(tm->tm_mon + 1);
+	regs[ISL1208_REG_YR] = BIN2BCD(tm->tm_year - 100);
+
+	regs[ISL1208_REG_DW] = BIN2BCD(tm->tm_wday & 7);
+
+	sr = isl1208_i2c_get_sr(client);
+	if (sr < 0) {
+		dev_err(&client->dev, "%s: reading SR failed\n", __func__);
+		return sr;
+	}
+
+	/* set WRTC */
+	sr = i2c_smbus_write_byte_data (client, ISL1208_REG_SR,
+				       sr | ISL1208_REG_SR_WRTC);
+	if (sr < 0) {
+		dev_err(&client->dev, "%s: writing SR failed\n", __func__);
+		return sr;
+	}
+
+	/* write RTC registers */
+	sr = isl1208_i2c_set_regs(client, 0, regs, ISL1208_RTC_SECTION_LEN);
+	if (sr < 0) {
+		dev_err(&client->dev, "%s: writing RTC section failed\n",
+			__func__);
+		return sr;
+	}
+
+	/* clear WRTC again */
+	sr = i2c_smbus_write_byte_data (client, ISL1208_REG_SR,
+				       sr & ~ISL1208_REG_SR_WRTC);
+	if (sr < 0) {
+		dev_err(&client->dev, "%s: writing SR failed\n", __func__);
+		return sr;
+	}
+
+	return 0;
+}
+
+
+static int isl1208_rtc_set_time(struct device *dev, struct rtc_time *tm)
+{
+	return isl1208_i2c_set_time(to_i2c_client(dev), tm);
+}
+
+static int isl1208_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
+{
+	return isl1208_i2c_read_alarm(to_i2c_client(dev), alarm);
+}
+
+static struct rtc_class_ops isl1208_rtc_ops = {
+	.proc		= isl1208_rtc_proc,
+	.read_time	= isl1208_rtc_read_time,
+	.set_time	= isl1208_rtc_set_time,
+	.read_alarm	= isl1208_rtc_read_alarm,
+	//.set_alarm	= isl1208_rtc_set_alarm,
+};
+
+/* sysfs interface */
+
+static ssize_t isl1208_sysfs_show_atrim(struct device *dev,
+					struct device_attribute *attr,
+					char *buf)
+{
+	int atr;
+
+	atr = isl1208_i2c_get_atr(to_i2c_client(dev));
+	if (atr < 0)
+		return atr;
+
+	return sprintf(buf, "%d.%.2d pF\n", atr>>2, (atr&0x3)*25);
+}
+static DEVICE_ATTR(atrim, S_IRUGO, isl1208_sysfs_show_atrim, NULL);
+
+static ssize_t isl1208_sysfs_show_dtrim(struct device *dev,
+					struct device_attribute *attr,
+					char *buf)
+{
+	int dtr;
+
+	dtr = isl1208_i2c_get_dtr(to_i2c_client(dev));
+	if (dtr < 0)
+		return dtr;
+
+	return sprintf(buf, "%d ppm\n", dtr);
+}
+static DEVICE_ATTR(dtrim, S_IRUGO, isl1208_sysfs_show_dtrim, NULL);
+
+static ssize_t isl1208_sysfs_show_usr(struct device *dev,
+				       struct device_attribute *attr,
+				       char *buf)
+{
+	int usr;
+
+	usr = isl1208_i2c_get_usr(to_i2c_client(dev));
+	if (usr < 0)
+		return usr;
+
+	return sprintf(buf, "0x%.4x\n", usr);
+}
+
+static ssize_t isl1208_sysfs_store_usr(struct device *dev,
+				       struct device_attribute *attr,
+				       const char *buf, size_t count)
+{
+	int usr = -1;
+
+	if (buf[0] == '0' && (buf[1] == 'x' || buf[1] == 'X')) {
+		if (sscanf(buf, "%x", &usr) != 1)
+			return -EINVAL;
+	} else {
+		if (sscanf(buf, "%d", &usr) != 1)
+			return -EINVAL;
+	}
+
+	if (usr < 0 || usr > 0xffff)
+		return -EINVAL;
+
+	return isl1208_i2c_set_usr(to_i2c_client(dev), usr) ? -EIO : count;
+}
+static DEVICE_ATTR(usr, S_IRUGO | S_IWUSR, isl1208_sysfs_show_usr,
+		   isl1208_sysfs_store_usr);
+
+static int
+isl1208_probe(struct i2c_adapter *adapter, int addr, int kind)
+{
+	int rc = 0;
+	struct i2c_client *new_client = NULL;
+	struct rtc_device *rtc = NULL;
+
+	if (!i2c_check_functionality(adapter, I2C_FUNC_I2C)) {
+		rc = -ENODEV;
+		goto failout;
+	}
+
+	new_client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL);
+	if (new_client == NULL) {
+		rc = -ENOMEM;
+		goto failout;
+	}
+
+	new_client->addr = addr;
+	new_client->adapter = adapter;
+	new_client->driver = &isl1208_driver;
+	new_client->flags = 0;
+	strcpy(new_client->name, DRV_NAME);
+
+	if (kind < 0) {
+		rc = isl1208_i2c_validate_client(new_client);
+		if (rc < 0)
+			goto failout;
+	}
+
+	rc = i2c_attach_client(new_client);
+	if (rc < 0)
+		goto failout;
+
+	dev_info(&new_client->dev,
+		 "chip found, driver version " DRV_VERSION "\n");
+
+	rtc = rtc_device_register(isl1208_driver.driver.name,
+				  &new_client->dev,
+				  &isl1208_rtc_ops, THIS_MODULE);
+
+	if (IS_ERR(rtc)) {
+		rc = PTR_ERR(rtc);
+		goto failout_detach;
+	}
+
+	i2c_set_clientdata(new_client, rtc);
+
+	rc = isl1208_i2c_get_sr(new_client);
+	if (rc < 0) {
+		dev_err(&new_client->dev, "reading status failed\n");
+		goto failout_unregister;
+	}
+
+	if (rc & ISL1208_REG_SR_RTCF)
+		dev_warn(&new_client->dev, "rtc power failure detected, "
+			 "please set clock.\n");
+
+	rc = device_create_file(&new_client->dev, &dev_attr_atrim);
+	if (rc < 0)
+		goto failout_unregister;
+	rc = device_create_file(&new_client->dev, &dev_attr_dtrim);
+	if (rc < 0)
+		goto failout_atrim;
+	rc = device_create_file(&new_client->dev, &dev_attr_usr);
+	if (rc < 0)
+		goto failout_dtrim;
+
+	return 0;
+
+ failout_dtrim:
+	device_remove_file(&new_client->dev, &dev_attr_dtrim);
+ failout_atrim:
+	device_remove_file(&new_client->dev, &dev_attr_atrim);
+ failout_unregister:
+	rtc_device_unregister(rtc);
+ failout_detach:
+	i2c_detach_client(new_client);
+ failout:
+	kfree(new_client);
+	return rc;
+}
+
+static int
+isl1208_attach_adapter (struct i2c_adapter *adapter)
+{
+	return i2c_probe(adapter, &addr_data, isl1208_probe);
+}
+
+static int
+isl1208_detach_client(struct i2c_client *client)
+{
+	int rc;
+	struct rtc_device *const rtc = i2c_get_clientdata(client);
+
+	if (rtc)
+		rtc_device_unregister(rtc); /* do we need to kfree? */
+
+	rc = i2c_detach_client(client);
+	if (rc)
+		return rc;
+
+	kfree(client);
+
+	return 0;
+}
+
+/* module management */
+
+static int __init isl1208_init(void)
+{
+	return i2c_add_driver(&isl1208_driver);
+}
+
+static void __exit isl1208_exit(void)
+{
+	i2c_del_driver(&isl1208_driver);
+}
+
+MODULE_AUTHOR("Herbert Valerio Riedel <hvr@gnu.org>");
+MODULE_DESCRIPTION("Intersil ISL1208 RTC driver");
+MODULE_LICENSE("GPL");
+MODULE_VERSION(DRV_VERSION);
+
+module_init(isl1208_init);
+module_exit(isl1208_exit);
diff --git a/drivers/serial/sunsab.c b/drivers/serial/sunsab.c
index 0dbd4df..979497f 100644
--- a/drivers/serial/sunsab.c
+++ b/drivers/serial/sunsab.c
@@ -1052,7 +1052,7 @@
 	if (err)
 		return err;
 
-	err = sunsab_init_one(&up[0], op, 0,
+	err = sunsab_init_one(&up[1], op, 0,
 			      (inst * 2) + 1);
 	if (err) {
 		of_iounmap(up[0].port.membase,
diff --git a/drivers/serial/sunsu.c b/drivers/serial/sunsu.c
index 93bdaa3..d3a5aee 100644
--- a/drivers/serial/sunsu.c
+++ b/drivers/serial/sunsu.c
@@ -1200,6 +1200,11 @@
 	if (up->port.type == PORT_UNKNOWN)
 		return -ENODEV;
 
+	printk("%s: %s port at %lx, irq %u\n",
+	       to_of_device(up->port.dev)->node->full_name,
+	       (up->su_type == SU_PORT_KBD) ? "Keyboard" : "Mouse",
+	       up->port.mapbase, up->port.irq);
+
 #ifdef CONFIG_SERIO
 	serio = &up->serio;
 	serio->port_data = up;
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index 3badb48..6533b0f 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -1518,6 +1518,26 @@
 
 	  <file:Documentation/fb/pxafb.txt> describes the available parameters.
 
+config FB_MBX
+	tristate "2700G LCD framebuffer support"
+	depends on FB && ARCH_PXA
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+	---help---
+	  Framebuffer driver for the Intel 2700G (Marathon) Graphics
+	  Accelerator
+
+config FB_MBX_DEBUG
+       bool "Enable debugging info via debugfs"
+       depends on FB_MBX && DEBUG_FS
+       default n
+       ---help---
+         Enable this if you want debugging information using the debug
+         filesystem (debugfs)
+
+         If unsure, say N.
+
 config FB_W100
 	tristate "W100 frame buffer support"
 	depends on FB && PXA_SHARPSL
diff --git a/drivers/video/Makefile b/drivers/video/Makefile
index 6283d01..95563c9 100644
--- a/drivers/video/Makefile
+++ b/drivers/video/Makefile
@@ -38,6 +38,7 @@
 obj-$(CONFIG_FB_KYRO)             += kyro/
 obj-$(CONFIG_FB_SAVAGE)		  += savage/
 obj-$(CONFIG_FB_GEODE)		  += geode/
+obj-$(CONFIG_FB_MBX)		  += mbx/
 obj-$(CONFIG_FB_I810)             += vgastate.o
 obj-$(CONFIG_FB_NEOMAGIC)         += neofb.o vgastate.o
 obj-$(CONFIG_FB_VIRGE)            += virgefb.o
diff --git a/drivers/video/mbx/Makefile b/drivers/video/mbx/Makefile
new file mode 100644
index 0000000..16c1165
--- /dev/null
+++ b/drivers/video/mbx/Makefile
@@ -0,0 +1,4 @@
+# Makefile for the 2700G controller driver.
+
+obj-$(CONFIG_FB_MBX)	   += mbxfb.o
+obj-$(CONFIG_FB_MBX_DEBUG) += mbxfbdebugfs.o
diff --git a/drivers/video/mbx/mbxdebugfs.c b/drivers/video/mbx/mbxdebugfs.c
new file mode 100644
index 0000000..84aab3a
--- /dev/null
+++ b/drivers/video/mbx/mbxdebugfs.c
@@ -0,0 +1,188 @@
+#include <linux/debugfs.h>
+
+#define BIG_BUFFER_SIZE	(1024)
+
+static char big_buffer[BIG_BUFFER_SIZE];
+
+struct mbxfb_debugfs_data {
+	struct dentry *dir;
+	struct dentry *sysconf;
+	struct dentry *clock;
+	struct dentry *display;
+	struct dentry *gsctl;
+};
+
+static int open_file_generic(struct inode *inode, struct file *file)
+{
+	file->private_data = inode->u.generic_ip;
+	return 0;
+}
+
+static ssize_t write_file_dummy(struct file *file, const char __user *buf,
+				size_t count, loff_t *ppos)
+{
+	return count;
+}
+
+static ssize_t sysconf_read_file(struct file *file, char __user *userbuf,
+				 size_t count, loff_t *ppos)
+{
+	char * s = big_buffer;
+
+	s += sprintf(s, "SYSCFG = %08lx\n", SYSCFG);
+	s += sprintf(s, "PFBASE = %08lx\n", PFBASE);
+	s += sprintf(s, "PFCEIL = %08lx\n", PFCEIL);
+	s += sprintf(s, "POLLFLAG = %08lx\n", POLLFLAG);
+	s += sprintf(s, "SYSRST = %08lx\n", SYSRST);
+
+	return  simple_read_from_buffer(userbuf, count, ppos,
+					big_buffer, s-big_buffer);
+}
+
+
+static ssize_t gsctl_read_file(struct file *file, char __user *userbuf,
+			       size_t count, loff_t *ppos)
+{
+	char * s = big_buffer;
+
+	s += sprintf(s, "GSCTRL = %08lx\n", GSCTRL);
+	s += sprintf(s, "VSCTRL = %08lx\n", VSCTRL);
+	s += sprintf(s, "GBBASE = %08lx\n", GBBASE);
+	s += sprintf(s, "VBBASE = %08lx\n", VBBASE);
+	s += sprintf(s, "GDRCTRL = %08lx\n", GDRCTRL);
+	s += sprintf(s, "VCMSK = %08lx\n", VCMSK);
+	s += sprintf(s, "GSCADR = %08lx\n", GSCADR);
+	s += sprintf(s, "VSCADR = %08lx\n", VSCADR);
+	s += sprintf(s, "VUBASE = %08lx\n", VUBASE);
+	s += sprintf(s, "VVBASE = %08lx\n", VVBASE);
+	s += sprintf(s, "GSADR = %08lx\n", GSADR);
+	s += sprintf(s, "VSADR = %08lx\n", VSADR);
+	s += sprintf(s, "HCCTRL = %08lx\n", HCCTRL);
+	s += sprintf(s, "HCSIZE = %08lx\n", HCSIZE);
+	s += sprintf(s, "HCPOS = %08lx\n", HCPOS);
+	s += sprintf(s, "HCBADR = %08lx\n", HCBADR);
+	s += sprintf(s, "HCCKMSK = %08lx\n", HCCKMSK);
+	s += sprintf(s, "GPLUT = %08lx\n", GPLUT);
+
+	return  simple_read_from_buffer(userbuf, count, ppos,
+					big_buffer, s-big_buffer);
+}
+
+static ssize_t display_read_file(struct file *file, char __user *userbuf,
+				 size_t count, loff_t *ppos)
+{
+	char * s = big_buffer;
+
+	s += sprintf(s, "DSCTRL = %08lx\n", DSCTRL);
+	s += sprintf(s, "DHT01 = %08lx\n", DHT01);
+	s += sprintf(s, "DHT02 = %08lx\n", DHT02);
+	s += sprintf(s, "DHT03 = %08lx\n", DHT03);
+	s += sprintf(s, "DVT01 = %08lx\n", DVT01);
+	s += sprintf(s, "DVT02 = %08lx\n", DVT02);
+	s += sprintf(s, "DVT03 = %08lx\n", DVT03);
+	s += sprintf(s, "DBCOL = %08lx\n", DBCOL);
+	s += sprintf(s, "BGCOLOR = %08lx\n", BGCOLOR);
+	s += sprintf(s, "DINTRS = %08lx\n", DINTRS);
+	s += sprintf(s, "DINTRE = %08lx\n", DINTRE);
+	s += sprintf(s, "DINTRCNT = %08lx\n", DINTRCNT);
+	s += sprintf(s, "DSIG = %08lx\n", DSIG);
+	s += sprintf(s, "DMCTRL = %08lx\n", DMCTRL);
+	s += sprintf(s, "CLIPCTRL = %08lx\n", CLIPCTRL);
+	s += sprintf(s, "SPOCTRL = %08lx\n", SPOCTRL);
+	s += sprintf(s, "SVCTRL = %08lx\n", SVCTRL);
+	s += sprintf(s, "DLSTS = %08lx\n", DLSTS);
+	s += sprintf(s, "DLLCTRL = %08lx\n", DLLCTRL);
+	s += sprintf(s, "DVLNUM = %08lx\n", DVLNUM);
+	s += sprintf(s, "DUCTRL = %08lx\n", DUCTRL);
+	s += sprintf(s, "DVECTRL = %08lx\n", DVECTRL);
+	s += sprintf(s, "DHDET = %08lx\n", DHDET);
+	s += sprintf(s, "DVDET = %08lx\n", DVDET);
+	s += sprintf(s, "DODMSK = %08lx\n", DODMSK);
+	s += sprintf(s, "CSC01 = %08lx\n", CSC01);
+	s += sprintf(s, "CSC02 = %08lx\n", CSC02);
+	s += sprintf(s, "CSC03 = %08lx\n", CSC03);
+	s += sprintf(s, "CSC04 = %08lx\n", CSC04);
+	s += sprintf(s, "CSC05 = %08lx\n", CSC05);
+
+	return  simple_read_from_buffer(userbuf, count, ppos,
+					big_buffer, s-big_buffer);
+}
+
+static ssize_t clock_read_file(struct file *file, char __user *userbuf,
+			       size_t count, loff_t *ppos)
+{
+	char * s = big_buffer;
+
+	s += sprintf(s, "SYSCLKSRC = %08lx\n", SYSCLKSRC);
+	s += sprintf(s, "PIXCLKSRC = %08lx\n", PIXCLKSRC);
+	s += sprintf(s, "CLKSLEEP = %08lx\n", CLKSLEEP);
+	s += sprintf(s, "COREPLL = %08lx\n", COREPLL);
+	s += sprintf(s, "DISPPLL = %08lx\n", DISPPLL);
+	s += sprintf(s, "PLLSTAT = %08lx\n", PLLSTAT);
+	s += sprintf(s, "VOVRCLK = %08lx\n", VOVRCLK);
+	s += sprintf(s, "PIXCLK = %08lx\n", PIXCLK);
+	s += sprintf(s, "MEMCLK = %08lx\n", MEMCLK);
+	s += sprintf(s, "M24CLK = %08lx\n", M24CLK);
+	s += sprintf(s, "MBXCLK = %08lx\n", MBXCLK);
+	s += sprintf(s, "SDCLK = %08lx\n", SDCLK);
+	s += sprintf(s, "PIXCLKDIV = %08lx\n", PIXCLKDIV);
+
+	return  simple_read_from_buffer(userbuf, count, ppos,
+					big_buffer, s-big_buffer);
+}
+
+static struct file_operations sysconf_fops = {
+	.read = sysconf_read_file,
+	.write = write_file_dummy,
+	.open = open_file_generic,
+};
+
+static struct file_operations clock_fops = {
+	.read = clock_read_file,
+	.write = write_file_dummy,
+	.open = open_file_generic,
+};
+
+static struct file_operations display_fops = {
+	.read = display_read_file,
+	.write = write_file_dummy,
+	.open = open_file_generic,
+};
+
+static struct file_operations gsctl_fops = {
+	.read = gsctl_read_file,
+	.write = write_file_dummy,
+	.open = open_file_generic,
+};
+
+
+static void __devinit mbxfb_debugfs_init(struct fb_info *fbi)
+{
+	struct mbxfb_info *mfbi = fbi->par;
+	struct mbxfb_debugfs_data *dbg;
+
+	dbg = kzalloc(sizeof(struct mbxfb_debugfs_data), GFP_KERNEL);
+	mfbi->debugfs_data = dbg;
+
+	dbg->dir = debugfs_create_dir("mbxfb", NULL);
+	dbg->sysconf = debugfs_create_file("sysconf", 0444, dbg->dir,
+				      fbi, &sysconf_fops);
+	dbg->clock = debugfs_create_file("clock", 0444, dbg->dir,
+				    fbi, &clock_fops);
+	dbg->display = debugfs_create_file("display", 0444, dbg->dir,
+				      fbi, &display_fops);
+	dbg->gsctl = debugfs_create_file("gsctl", 0444, dbg->dir,
+				    fbi, &gsctl_fops);
+}
+
+static void __devexit mbxfb_debugfs_remove(struct fb_info *fbi)
+{
+	struct mbxfb_info *mfbi = fbi->par;
+	struct mbxfb_debugfs_data *dbg = mfbi->debugfs_data;
+
+	debugfs_remove(dbg->gsctl);
+	debugfs_remove(dbg->display);
+	debugfs_remove(dbg->clock);
+	debugfs_remove(dbg->sysconf);
+	debugfs_remove(dbg->dir);
+}
diff --git a/drivers/video/mbx/mbxfb.c b/drivers/video/mbx/mbxfb.c
new file mode 100644
index 0000000..6849ab7
--- /dev/null
+++ b/drivers/video/mbx/mbxfb.c
@@ -0,0 +1,683 @@
+/*
+ *  linux/drivers/video/mbx/mbxfb.c
+ *
+ *  Copyright (C) 2006 Compulab, Ltd.
+ *  Mike Rapoport <mike@compulab.co.il>
+ *
+ *   Based on pxafb.c
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file COPYING in the main directory of this archive for
+ * more details.
+ *
+ *   Intel 2700G (Marathon) Graphics Accelerator Frame Buffer Driver
+ *
+ */
+
+#include <linux/delay.h>
+#include <linux/fb.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+
+#include <asm/io.h>
+
+#include <video/mbxfb.h>
+
+#include "regs.h"
+#include "reg_bits.h"
+
+static unsigned long virt_base_2700;
+
+#define MIN_XRES	16
+#define MIN_YRES	16
+#define MAX_XRES	2048
+#define MAX_YRES	2048
+
+#define MAX_PALETTES	16
+
+/* FIXME: take care of different chip revisions with different sizes
+   of ODFB */
+#define MEMORY_OFFSET	0x60000
+
+struct mbxfb_info {
+	struct device *dev;
+
+	struct resource *fb_res;
+	struct resource *fb_req;
+
+	struct resource *reg_res;
+	struct resource *reg_req;
+
+	void __iomem *fb_virt_addr;
+	unsigned long fb_phys_addr;
+
+	void __iomem *reg_virt_addr;
+	unsigned long reg_phys_addr;
+
+	int (*platform_probe) (struct fb_info * fb);
+	int (*platform_remove) (struct fb_info * fb);
+
+	u32 pseudo_palette[MAX_PALETTES];
+#ifdef CONFIG_FB_MBX_DEBUG
+	void *debugfs_data;
+#endif
+
+};
+
+static struct fb_var_screeninfo mbxfb_default __devinitdata = {
+	.xres = 640,
+	.yres = 480,
+	.xres_virtual = 640,
+	.yres_virtual = 480,
+	.bits_per_pixel = 16,
+	.red = {11, 5, 0},
+	.green = {5, 6, 0},
+	.blue = {0, 5, 0},
+	.activate = FB_ACTIVATE_TEST,
+	.height = -1,
+	.width = -1,
+	.pixclock = 40000,
+	.left_margin = 48,
+	.right_margin = 16,
+	.upper_margin = 33,
+	.lower_margin = 10,
+	.hsync_len = 96,
+	.vsync_len = 2,
+	.vmode = FB_VMODE_NONINTERLACED,
+	.sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+};
+
+static struct fb_fix_screeninfo mbxfb_fix  __devinitdata = {
+	.id = "MBX",
+	.type = FB_TYPE_PACKED_PIXELS,
+	.visual = FB_VISUAL_TRUECOLOR,
+	.xpanstep = 0,
+	.ypanstep = 0,
+	.ywrapstep = 0,
+	.accel = FB_ACCEL_NONE,
+};
+
+struct pixclock_div {
+	u8 m;
+	u8 n;
+	u8 p;
+};
+
+static unsigned int mbxfb_get_pixclock(unsigned int pixclock_ps,
+				       struct pixclock_div *div)
+{
+	u8 m, n, p;
+	unsigned int err = 0;
+	unsigned int min_err = ~0x0;
+	unsigned int clk;
+	unsigned int best_clk = 0;
+	unsigned int ref_clk = 13000;	/* FIXME: take from platform data */
+	unsigned int pixclock;
+
+	/* convert pixclock to KHz */
+	pixclock = PICOS2KHZ(pixclock_ps);
+
+	for (m = 1; m < 64; m++) {
+		for (n = 1; n < 8; n++) {
+			for (p = 0; p < 8; p++) {
+				clk = (ref_clk * m) / (n * (1 << p));
+				err = (clk > pixclock) ? (clk - pixclock) :
+					(pixclock - clk);
+				if (err < min_err) {
+					min_err = err;
+					best_clk = clk;
+					div->m = m;
+					div->n = n;
+					div->p = p;
+				}
+			}
+		}
+	}
+	return KHZ2PICOS(best_clk);
+}
+
+static int mbxfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
+			   u_int trans, struct fb_info *info)
+{
+	u32 val, ret = 1;
+
+	if (regno < MAX_PALETTES) {
+		u32 *pal = info->pseudo_palette;
+
+		val = (red & 0xf800) | ((green & 0xfc00) >> 5) |
+			((blue & 0xf800) >> 11);
+		pal[regno] = val;
+		ret = 0;
+	}
+
+	return ret;
+}
+
+static int mbxfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
+{
+	struct pixclock_div div;
+
+	var->pixclock = mbxfb_get_pixclock(var->pixclock, &div);
+
+	if (var->xres < MIN_XRES)
+		var->xres = MIN_XRES;
+	if (var->yres < MIN_YRES)
+		var->yres = MIN_YRES;
+	if (var->xres > MAX_XRES)
+		return -EINVAL;
+	if (var->yres > MAX_YRES)
+		return -EINVAL;
+	var->xres_virtual = max(var->xres_virtual, var->xres);
+	var->yres_virtual = max(var->yres_virtual, var->yres);
+
+	switch (var->bits_per_pixel) {
+		/* 8 bits-per-pixel is not supported yet */
+	case 8:
+		return -EINVAL;
+	case 16:
+		var->green.length = (var->green.length == 5) ? 5 : 6;
+		var->red.length = 5;
+		var->blue.length = 5;
+		var->transp.length = 6 - var->green.length;
+		var->blue.offset = 0;
+		var->green.offset = 5;
+		var->red.offset = 5 + var->green.length;
+		var->transp.offset = (5 + var->red.offset) & 15;
+		break;
+	case 24:		/* RGB 888   */
+	case 32:		/* RGBA 8888 */
+		var->red.offset = 16;
+		var->red.length = 8;
+		var->green.offset = 8;
+		var->green.length = 8;
+		var->blue.offset = 0;
+		var->blue.length = 8;
+		var->transp.length = var->bits_per_pixel - 24;
+		var->transp.offset = (var->transp.length) ? 24 : 0;
+		break;
+	}
+	var->red.msb_right = 0;
+	var->green.msb_right = 0;
+	var->blue.msb_right = 0;
+	var->transp.msb_right = 0;
+
+	return 0;
+}
+
+static int mbxfb_set_par(struct fb_info *info)
+{
+	struct fb_var_screeninfo *var = &info->var;
+	struct pixclock_div div;
+	ushort hbps, ht, hfps, has;
+	ushort vbps, vt, vfps, vas;
+	u32 gsctrl = readl(GSCTRL);
+	u32 gsadr = readl(GSADR);
+
+	info->fix.line_length = var->xres_virtual * var->bits_per_pixel / 8;
+
+	/* setup color mode */
+	gsctrl &= ~(FMsk(GSCTRL_GPIXFMT));
+	/* FIXME: add *WORKING* support for 8-bits per color */
+	if (info->var.bits_per_pixel == 8) {
+		return -EINVAL;
+	} else {
+		fb_dealloc_cmap(&info->cmap);
+		gsctrl &= ~GSCTRL_LUT_EN;
+
+		info->fix.visual = FB_VISUAL_TRUECOLOR;
+		switch (info->var.bits_per_pixel) {
+		case 16:
+			if (info->var.green.length == 5)
+				gsctrl |= GSCTRL_GPIXFMT_ARGB1555;
+			else
+				gsctrl |= GSCTRL_GPIXFMT_RGB565;
+			break;
+		case 24:
+			gsctrl |= GSCTRL_GPIXFMT_RGB888;
+			break;
+		case 32:
+			gsctrl |= GSCTRL_GPIXFMT_ARGB8888;
+			break;
+		}
+	}
+
+	/* setup resolution */
+	gsctrl &= ~(FMsk(GSCTRL_GSWIDTH) | FMsk(GSCTRL_GSHEIGHT));
+	gsctrl |= Gsctrl_Width(info->var.xres - 1) |
+		Gsctrl_Height(info->var.yres - 1);
+	writel(gsctrl, GSCTRL);
+	udelay(1000);
+
+	gsadr &= ~(FMsk(GSADR_SRCSTRIDE));
+	gsadr |= Gsadr_Srcstride(info->var.xres * info->var.bits_per_pixel /
+				 (8 * 16) - 1);
+	writel(gsadr, GSADR);
+	udelay(1000);
+
+	/* setup timings */
+	var->pixclock = mbxfb_get_pixclock(info->var.pixclock, &div);
+
+	writel((Disp_Pll_M(div.m) | Disp_Pll_N(div.n) |
+		Disp_Pll_P(div.p) | DISP_PLL_EN), DISPPLL);
+
+	hbps = var->hsync_len;
+	has = hbps + var->left_margin;
+	hfps = has + var->xres;
+	ht = hfps + var->right_margin;
+
+	vbps = var->vsync_len;
+	vas = vbps + var->upper_margin;
+	vfps = vas + var->yres;
+	vt = vfps + var->lower_margin;
+
+	writel((Dht01_Hbps(hbps) | Dht01_Ht(ht)), DHT01);
+	writel((Dht02_Hlbs(has) | Dht02_Has(has)), DHT02);
+	writel((Dht03_Hfps(hfps) | Dht03_Hrbs(hfps)), DHT03);
+	writel((Dhdet_Hdes(has) | Dhdet_Hdef(hfps)), DHDET);
+
+	writel((Dvt01_Vbps(vbps) | Dvt01_Vt(vt)), DVT01);
+	writel((Dvt02_Vtbs(vas) | Dvt02_Vas(vas)), DVT02);
+	writel((Dvt03_Vfps(vfps) | Dvt03_Vbbs(vfps)), DVT03);
+	writel((Dvdet_Vdes(vas) | Dvdet_Vdef(vfps)), DVDET);
+	writel((Dvectrl_Vevent(vfps) | Dvectrl_Vfetch(vbps)), DVECTRL);
+
+	writel((readl(DSCTRL) | DSCTRL_SYNCGEN_EN), DSCTRL);
+
+	return 0;
+}
+
+static int mbxfb_blank(int blank, struct fb_info *info)
+{
+	switch (blank) {
+	case FB_BLANK_POWERDOWN:
+	case FB_BLANK_VSYNC_SUSPEND:
+	case FB_BLANK_HSYNC_SUSPEND:
+	case FB_BLANK_NORMAL:
+		writel((readl(DSCTRL) & ~DSCTRL_SYNCGEN_EN), DSCTRL);
+		udelay(1000);
+		writel((readl(PIXCLK) & ~PIXCLK_EN), PIXCLK);
+		udelay(1000);
+		writel((readl(VOVRCLK) & ~VOVRCLK_EN), VOVRCLK);
+		udelay(1000);
+		break;
+	case FB_BLANK_UNBLANK:
+		writel((readl(DSCTRL) | DSCTRL_SYNCGEN_EN), DSCTRL);
+		udelay(1000);
+		writel((readl(PIXCLK) | PIXCLK_EN), PIXCLK);
+		udelay(1000);
+		break;
+	}
+	return 0;
+}
+
+static struct fb_ops mbxfb_ops = {
+	.owner = THIS_MODULE,
+	.fb_check_var = mbxfb_check_var,
+	.fb_set_par = mbxfb_set_par,
+	.fb_setcolreg = mbxfb_setcolreg,
+	.fb_fillrect = cfb_fillrect,
+	.fb_copyarea = cfb_copyarea,
+	.fb_imageblit = cfb_imageblit,
+	.fb_blank = mbxfb_blank,
+};
+
+/*
+  Enable external SDRAM controller. Assume that all clocks are active
+  by now.
+*/
+static void __devinit setup_memc(struct fb_info *fbi)
+{
+	struct mbxfb_info *mfbi = fbi->par;
+	unsigned long tmp;
+	int i;
+
+	/* FIXME: use platfrom specific parameters */
+	/* setup SDRAM controller */
+	writel((LMCFG_LMC_DS | LMCFG_LMC_TS | LMCFG_LMD_TS |
+		LMCFG_LMA_TS),
+	       LMCFG);
+	udelay(1000);
+
+	writel(LMPWR_MC_PWR_ACT, LMPWR);
+	udelay(1000);
+
+	/* setup SDRAM timings */
+	writel((Lmtim_Tras(7) | Lmtim_Trp(3) | Lmtim_Trcd(3) |
+		Lmtim_Trc(9) | Lmtim_Tdpl(2)),
+	       LMTIM);
+	udelay(1000);
+	/* setup SDRAM refresh rate */
+	writel(0xc2b, LMREFRESH);
+	udelay(1000);
+	/* setup SDRAM type parameters */
+	writel((LMTYPE_CASLAT_3 | LMTYPE_BKSZ_2 | LMTYPE_ROWSZ_11 |
+		LMTYPE_COLSZ_8),
+	       LMTYPE);
+	udelay(1000);
+	/* enable memory controller */
+	writel(LMPWR_MC_PWR_ACT, LMPWR);
+	udelay(1000);
+
+	/* perform dummy reads */
+	for ( i = 0; i < 16; i++ ) {
+		tmp = readl(fbi->screen_base);
+	}
+}
+
+static void enable_clocks(struct fb_info *fbi)
+{
+	/* enable clocks */
+	writel(SYSCLKSRC_PLL_2, SYSCLKSRC);
+	udelay(1000);
+	writel(PIXCLKSRC_PLL_1, PIXCLKSRC);
+	udelay(1000);
+	writel(0x00000000, CLKSLEEP);
+	udelay(1000);
+	writel((Core_Pll_M(0x17) | Core_Pll_N(0x3) | Core_Pll_P(0x0) |
+		CORE_PLL_EN),
+	       COREPLL);
+	udelay(1000);
+	writel((Disp_Pll_M(0x1b) | Disp_Pll_N(0x7) | Disp_Pll_P(0x1) |
+		DISP_PLL_EN),
+	       DISPPLL);
+
+	writel(0x00000000, VOVRCLK);
+	udelay(1000);
+	writel(PIXCLK_EN, PIXCLK);
+	udelay(1000);
+	writel(MEMCLK_EN, MEMCLK);
+	udelay(1000);
+	writel(0x00000006, M24CLK);
+	udelay(1000);
+	writel(0x00000006, MBXCLK);
+	udelay(1000);
+	writel(SDCLK_EN, SDCLK);
+	udelay(1000);
+	writel(0x00000001, PIXCLKDIV);
+	udelay(1000);
+}
+
+static void __devinit setup_graphics(struct fb_info *fbi)
+{
+	unsigned long gsctrl;
+
+	gsctrl = GSCTRL_GAMMA_EN | Gsctrl_Width(fbi->var.xres - 1) |
+		Gsctrl_Height(fbi->var.yres - 1);
+	switch (fbi->var.bits_per_pixel) {
+	case 16:
+		if (fbi->var.green.length == 5)
+			gsctrl |= GSCTRL_GPIXFMT_ARGB1555;
+		else
+			gsctrl |= GSCTRL_GPIXFMT_RGB565;
+		break;
+	case 24:
+		gsctrl |= GSCTRL_GPIXFMT_RGB888;
+		break;
+	case 32:
+		gsctrl |= GSCTRL_GPIXFMT_ARGB8888;
+		break;
+	}
+
+	writel(gsctrl, GSCTRL);
+	udelay(1000);
+	writel(0x00000000, GBBASE);
+	udelay(1000);
+	writel(0x00ffffff, GDRCTRL);
+	udelay(1000);
+	writel((GSCADR_STR_EN | Gscadr_Gbase_Adr(0x6000)), GSCADR);
+	udelay(1000);
+	writel(0x00000000, GPLUT);
+	udelay(1000);
+}
+
+static void __devinit setup_display(struct fb_info *fbi)
+{
+	unsigned long dsctrl = 0;
+
+	dsctrl = DSCTRL_BLNK_POL;
+	if (fbi->var.sync & FB_SYNC_HOR_HIGH_ACT)
+		dsctrl |= DSCTRL_HS_POL;
+	if (fbi->var.sync & FB_SYNC_VERT_HIGH_ACT)
+		dsctrl |= DSCTRL_VS_POL;
+	writel(dsctrl, DSCTRL);
+	udelay(1000);
+	writel(0xd0303010, DMCTRL);
+	udelay(1000);
+	writel((readl(DSCTRL) | DSCTRL_SYNCGEN_EN), DSCTRL);
+}
+
+static void __devinit enable_controller(struct fb_info *fbi)
+{
+	writel(SYSRST_RST, SYSRST);
+	udelay(1000);
+
+
+	enable_clocks(fbi);
+	setup_memc(fbi);
+	setup_graphics(fbi);
+	setup_display(fbi);
+}
+
+#ifdef CONFIG_PM
+/*
+ * Power management hooks.  Note that we won't be called from IRQ context,
+ * unlike the blank functions above, so we may sleep.
+ */
+static int mbxfb_suspend(struct platform_device *dev, pm_message_t state)
+{
+	/* make frame buffer memory enter self-refresh mode */
+	writel(LMPWR_MC_PWR_SRM, LMPWR);
+	while (LMPWRSTAT != LMPWRSTAT_MC_PWR_SRM)
+		; /* empty statement */
+
+	/* reset the device, since it's initial state is 'mostly sleeping' */
+	writel(SYSRST_RST, SYSRST);
+	return 0;
+}
+
+static int mbxfb_resume(struct platform_device *dev)
+{
+	struct fb_info *fbi = platform_get_drvdata(dev);
+
+	enable_clocks(fbi);
+/* 	setup_graphics(fbi); */
+/* 	setup_display(fbi); */
+
+	writel((readl(DSCTRL) | DSCTRL_SYNCGEN_EN), DSCTRL);
+	return 0;
+}
+#else
+#define mbxfb_suspend	NULL
+#define mbxfb_resume	NULL
+#endif
+
+/* debugfs entries */
+#ifndef CONFIG_FB_MBX_DEBUG
+#define mbxfb_debugfs_init(x)	do {} while(0)
+#define mbxfb_debugfs_remove(x)	do {} while(0)
+#endif
+
+#define res_size(_r) (((_r)->end - (_r)->start) + 1)
+
+static int __devinit mbxfb_probe(struct platform_device *dev)
+{
+	int ret;
+	struct fb_info *fbi;
+	struct mbxfb_info *mfbi;
+	struct mbxfb_platform_data *pdata;
+
+	dev_dbg(dev, "mbxfb_probe\n");
+
+	fbi = framebuffer_alloc(sizeof(struct mbxfb_info), &dev->dev);
+	if (fbi == NULL) {
+		dev_err(&dev->dev, "framebuffer_alloc failed\n");
+		return -ENOMEM;
+	}
+
+	mfbi = fbi->par;
+	fbi->pseudo_palette = mfbi->pseudo_palette;
+	pdata = dev->dev.platform_data;
+	if (pdata->probe)
+		mfbi->platform_probe = pdata->probe;
+	if (pdata->remove)
+		mfbi->platform_remove = pdata->remove;
+
+	mfbi->fb_res = platform_get_resource(dev, IORESOURCE_MEM, 0);
+	mfbi->reg_res = platform_get_resource(dev, IORESOURCE_MEM, 1);
+
+	if (!mfbi->fb_res || !mfbi->reg_res) {
+		dev_err(&dev->dev, "no resources found\n");
+		ret = -ENODEV;
+		goto err1;
+	}
+
+	mfbi->fb_req = request_mem_region(mfbi->fb_res->start,
+					  res_size(mfbi->fb_res), dev->name);
+	if (mfbi->fb_req == NULL) {
+		dev_err(&dev->dev, "failed to claim framebuffer memory\n");
+		ret = -EINVAL;
+		goto err1;
+	}
+	mfbi->fb_phys_addr = mfbi->fb_res->start;
+
+	mfbi->reg_req = request_mem_region(mfbi->reg_res->start,
+					   res_size(mfbi->reg_res), dev->name);
+	if (mfbi->reg_req == NULL) {
+		dev_err(&dev->dev, "failed to claim Marathon registers\n");
+		ret = -EINVAL;
+		goto err2;
+	}
+	mfbi->reg_phys_addr = mfbi->reg_res->start;
+
+	mfbi->reg_virt_addr = ioremap_nocache(mfbi->reg_phys_addr,
+					      res_size(mfbi->reg_req));
+	if (!mfbi->reg_virt_addr) {
+		dev_err(&dev->dev, "failed to ioremap Marathon registers\n");
+		ret = -EINVAL;
+		goto err3;
+	}
+	virt_base_2700 = (unsigned long)mfbi->reg_virt_addr;
+
+	mfbi->fb_virt_addr = ioremap_nocache(mfbi->fb_phys_addr,
+					     res_size(mfbi->fb_req));
+	if (!mfbi->reg_virt_addr) {
+		dev_err(&dev->dev, "failed to ioremap frame buffer\n");
+		ret = -EINVAL;
+		goto err4;
+	}
+
+	/* FIXME: get from platform */
+	fbi->screen_base = (char __iomem *)(mfbi->fb_virt_addr + 0x60000);
+	fbi->screen_size = 8 * 1024 * 1024;	/* 8 Megs */
+	fbi->fbops = &mbxfb_ops;
+
+	fbi->var = mbxfb_default;
+	fbi->fix = mbxfb_fix;
+	fbi->fix.smem_start = mfbi->fb_phys_addr + 0x60000;
+	fbi->fix.smem_len = 8 * 1024 * 1024;
+	fbi->fix.line_length = 640 * 2;
+
+	ret = fb_alloc_cmap(&fbi->cmap, 256, 0);
+	if (ret < 0) {
+		dev_err(&dev->dev, "fb_alloc_cmap failed\n");
+		ret = -EINVAL;
+		goto err5;
+	}
+
+	platform_set_drvdata(dev, fbi);
+
+	printk(KERN_INFO "fb%d: mbx frame buffer device\n", fbi->node);
+
+	if (mfbi->platform_probe)
+		mfbi->platform_probe(fbi);
+
+	enable_controller(fbi);
+
+	mbxfb_debugfs_init(fbi);
+
+	ret = register_framebuffer(fbi);
+	if (ret < 0) {
+		dev_err(&dev->dev, "register_framebuffer failed\n");
+		ret = -EINVAL;
+		goto err6;
+	}
+
+	return 0;
+
+err6:
+	fb_dealloc_cmap(&fbi->cmap);
+err5:
+	iounmap(mfbi->fb_virt_addr);
+err4:
+	iounmap(mfbi->reg_virt_addr);
+err3:
+	release_mem_region(mfbi->reg_res->start, res_size(mfbi->reg_res));
+err2:
+	release_mem_region(mfbi->fb_res->start, res_size(mfbi->fb_res));
+err1:
+	framebuffer_release(fbi);
+
+	return ret;
+}
+
+static int __devexit mbxfb_remove(struct platform_device *dev)
+{
+	struct fb_info *fbi = platform_get_drvdata(dev);
+
+	writel(SYSRST_RST, SYSRST);
+	udelay(1000);
+
+	mbxfb_debugfs_remove(fbi);
+
+	if (fbi) {
+		struct mbxfb_info *mfbi = fbi->par;
+
+		unregister_framebuffer(fbi);
+		if (mfbi) {
+			if (mfbi->platform_remove)
+				mfbi->platform_remove(fbi);
+
+			if (mfbi->fb_virt_addr)
+				iounmap(mfbi->fb_virt_addr);
+			if (mfbi->reg_virt_addr)
+				iounmap(mfbi->reg_virt_addr);
+			if (mfbi->reg_req)
+				release_mem_region(mfbi->reg_req->start,
+						   res_size(mfbi->reg_req));
+			if (mfbi->fb_req)
+				release_mem_region(mfbi->fb_req->start,
+						   res_size(mfbi->fb_req));
+		}
+		framebuffer_release(fbi);
+	}
+
+	return 0;
+}
+
+static struct platform_driver mbxfb_driver = {
+	.probe = mbxfb_probe,
+	.remove = mbxfb_remove,
+	.suspend = mbxfb_suspend,
+	.resume = mbxfb_resume,
+	.driver = {
+		.name = "mbx-fb",
+	},
+};
+
+int __devinit mbxfb_init(void)
+{
+	return platform_driver_register(&mbxfb_driver);
+}
+
+static void __devexit mbxfb_exit(void)
+{
+	platform_driver_unregister(&mbxfb_driver);
+}
+
+module_init(mbxfb_init);
+module_exit(mbxfb_exit);
+
+MODULE_DESCRIPTION("loadable framebuffer driver for Marathon device");
+MODULE_AUTHOR("Mike Rapoport, Compulab");
+MODULE_LICENSE("GPL");
diff --git a/drivers/video/mbx/reg_bits.h b/drivers/video/mbx/reg_bits.h
new file mode 100644
index 0000000..c226a8e
--- /dev/null
+++ b/drivers/video/mbx/reg_bits.h
@@ -0,0 +1,418 @@
+#ifndef __REG_BITS_2700G_
+#define __REG_BITS_2700G_
+
+/* use defines from asm-arm/arch-pxa/bitfields.h for bit fields access */
+#define UData(Data)	((unsigned long) (Data))
+#define Fld(Size, Shft)	(((Size) << 16) + (Shft))
+#define FSize(Field)	((Field) >> 16)
+#define FShft(Field)	((Field) & 0x0000FFFF)
+#define FMsk(Field)	(((UData (1) << FSize (Field)) - 1) << FShft (Field))
+#define FAlnMsk(Field)	((UData (1) << FSize (Field)) - 1)
+#define F1stBit(Field)	(UData (1) << FShft (Field))
+
+#define SYSRST_RST	(1 << 0)
+
+/* SYSCLKSRC - SYSCLK Source Control Register */
+#define SYSCLKSRC_SEL	Fld(2,0)
+#define SYSCLKSRC_REF	((0x0) << FShft(SYSCLKSRC_SEL))
+#define SYSCLKSRC_PLL_1	((0x1) << FShft(SYSCLKSRC_SEL))
+#define SYSCLKSRC_PLL_2	((0x2) << FShft(SYSCLKSRC_SEL))
+
+/* PIXCLKSRC - PIXCLK Source Control Register */
+#define PIXCLKSRC_SEL	Fld(2,0)
+#define PIXCLKSRC_REF	((0x0) << FShft(PIXCLKSRC_SEL))
+#define PIXCLKSRC_PLL_1	((0x1) << FShft(PIXCLKSRC_SEL))
+#define PIXCLKSRC_PLL_2	((0x2) << FShft(PIXCLKSRC_SEL))
+
+/* Clock Disable Register */
+#define CLKSLEEP_SLP	(1 << 0)
+
+/* Core PLL Control Register */
+#define CORE_PLL_M	Fld(6,7)
+#define Core_Pll_M(x)	((x) << FShft(CORE_PLL_M))
+#define CORE_PLL_N	Fld(3,4)
+#define Core_Pll_N(x)	((x) << FShft(CORE_PLL_N))
+#define CORE_PLL_P	Fld(3,1)
+#define Core_Pll_P(x)	((x) << FShft(CORE_PLL_P))
+#define CORE_PLL_EN	(1 << 0)
+
+/* Display PLL Control Register */
+#define DISP_PLL_M	Fld(6,7)
+#define Disp_Pll_M(x)	((x) << FShft(DISP_PLL_M))
+#define DISP_PLL_N	Fld(3,4)
+#define Disp_Pll_N(x)	((x) << FShft(DISP_PLL_N))
+#define DISP_PLL_P	Fld(3,1)
+#define Disp_Pll_P(x)	((x) << FShft(DISP_PLL_P))
+#define DISP_PLL_EN	(1 << 0)
+
+/* PLL status register */
+#define PLLSTAT_CORE_PLL_LOST_L	(1 << 3)
+#define PLLSTAT_CORE_PLL_LSTS	(1 << 2)
+#define PLLSTAT_DISP_PLL_LOST_L	(1 << 1)
+#define PLLSTAT_DISP_PLL_LSTS	(1 << 0)
+
+/* Video and scale clock control register */
+#define VOVRCLK_EN	(1 << 0)
+
+/* Pixel clock control register */
+#define PIXCLK_EN	(1 << 0)
+
+/* Memory clock control register */
+#define MEMCLK_EN	(1 << 0)
+
+/* MBX clock control register */
+#define MBXCLK_DIV	Fld(2,2)
+#define MBXCLK_DIV_1	((0x0) << FShft(MBXCLK_DIV))
+#define MBXCLK_DIV_2	((0x1) << FShft(MBXCLK_DIV))
+#define MBXCLK_DIV_3	((0x2) << FShft(MBXCLK_DIV))
+#define MBXCLK_DIV_4	((0x3) << FShft(MBXCLK_DIV))
+#define MBXCLK_EN	Fld(2,0)
+#define MBXCLK_EN_NONE	((0x0) << FShft(MBXCLK_EN))
+#define MBXCLK_EN_2D	((0x1) << FShft(MBXCLK_EN))
+#define MBXCLK_EN_BOTH	((0x2) << FShft(MBXCLK_EN))
+
+/* M24 clock control register */
+#define M24CLK_DIV	Fld(2,1)
+#define M24CLK_DIV_1	((0x0) << FShft(M24CLK_DIV))
+#define M24CLK_DIV_2	((0x1) << FShft(M24CLK_DIV))
+#define M24CLK_DIV_3	((0x2) << FShft(M24CLK_DIV))
+#define M24CLK_DIV_4	((0x3) << FShft(M24CLK_DIV))
+#define M24CLK_EN	(1 << 0)
+
+/* SDRAM clock control register */
+#define SDCLK_EN	(1 << 0)
+
+/* PixClk Divisor Register */
+#define PIXCLKDIV_PD	Fld(9,0)
+#define Pixclkdiv_Pd(x)	((x) << FShft(PIXCLKDIV_PD))
+
+/* LCD Config control register */
+#define LCDCFG_IN_FMT	Fld(3,28)
+#define Lcdcfg_In_Fmt(x)	((x) << FShft(LCDCFG_IN_FMT))
+#define LCDCFG_LCD1DEN_POL	(1 << 27)
+#define LCDCFG_LCD1FCLK_POL	(1 << 26)
+#define LCDCFG_LCD1LCLK_POL	(1 << 25)
+#define LCDCFG_LCD1D_POL	(1 << 24)
+#define LCDCFG_LCD2DEN_POL	(1 << 23)
+#define LCDCFG_LCD2FCLK_POL	(1 << 22)
+#define LCDCFG_LCD2LCLK_POL	(1 << 21)
+#define LCDCFG_LCD2D_POL	(1 << 20)
+#define LCDCFG_LCD1_TS		(1 << 19)
+#define LCDCFG_LCD1D_DS		(1 << 18)
+#define LCDCFG_LCD1C_DS		(1 << 17)
+#define LCDCFG_LCD1_IS_IN	(1 << 16)
+#define LCDCFG_LCD2_TS		(1 << 3)
+#define LCDCFG_LCD2D_DS		(1 << 2)
+#define LCDCFG_LCD2C_DS		(1 << 1)
+#define LCDCFG_LCD2_IS_IN	(1 << 0)
+
+/* On-Die Frame Buffer Power Control Register */
+#define ODFBPWR_SLOW	(1 << 2)
+#define ODFBPWR_MODE	Fld(2,0)
+#define ODFBPWR_MODE_ACT	((0x0) << FShft(ODFBPWR_MODE))
+#define ODFBPWR_MODE_ACT_LP	((0x1) << FShft(ODFBPWR_MODE))
+#define ODFBPWR_MODE_SLEEP	((0x2) << FShft(ODFBPWR_MODE))
+#define ODFBPWR_MODE_SHUTD	((0x3) << FShft(ODFBPWR_MODE))
+
+/* On-Die Frame Buffer Power State Status Register */
+#define ODFBSTAT_ACT	(1 << 2)
+#define ODFBSTAT_SLP	(1 << 1)
+#define ODFBSTAT_SDN	(1 << 0)
+
+/* LMRST - Local Memory (SDRAM) Reset */
+#define LMRST_MC_RST	(1 << 0)
+
+/* LMCFG - Local Memory (SDRAM) Configuration Register */
+#define LMCFG_LMC_DS	(1 << 5)
+#define LMCFG_LMD_DS	(1 << 4)
+#define LMCFG_LMA_DS	(1 << 3)
+#define LMCFG_LMC_TS	(1 << 2)
+#define LMCFG_LMD_TS	(1 << 1)
+#define LMCFG_LMA_TS	(1 << 0)
+
+/* LMPWR - Local Memory (SDRAM) Power Control Register */
+#define LMPWR_MC_PWR_CNT	Fld(2,0)
+#define LMPWR_MC_PWR_ACT	((0x0) << FShft(LMPWR_MC_PWR_CNT)) /* Active */
+#define LMPWR_MC_PWR_SRM	((0x1) << FShft(LMPWR_MC_PWR_CNT)) /* Self-refresh */
+#define LMPWR_MC_PWR_DPD	((0x3) << FShft(LMPWR_MC_PWR_CNT)) /* deep power down */
+
+/* LMPWRSTAT - Local Memory (SDRAM) Power Status Register */
+#define LMPWRSTAT_MC_PWR_CNT	Fld(2,0)
+#define LMPWRSTAT_MC_PWR_ACT	((0x0) << FShft(LMPWRSTAT_MC_PWR_CNT)) /* Active */
+#define LMPWRSTAT_MC_PWR_SRM	((0x1) << FShft(LMPWRSTAT_MC_PWR_CNT)) /* Self-refresh */
+#define LMPWRSTAT_MC_PWR_DPD	((0x3) << FShft(LMPWRSTAT_MC_PWR_CNT)) /* deep power down */
+
+/* LMTYPE - Local Memory (SDRAM) Type Register */
+#define LMTYPE_CASLAT	Fld(3,10)
+#define LMTYPE_CASLAT_1	((0x1) << FShft(LMTYPE_CASLAT))
+#define LMTYPE_CASLAT_2	((0x2) << FShft(LMTYPE_CASLAT))
+#define LMTYPE_CASLAT_3	((0x3) << FShft(LMTYPE_CASLAT))
+#define LMTYPE_BKSZ	Fld(2,8)
+#define LMTYPE_BKSZ_1	((0x1) << FShft(LMTYPE_BKSZ))
+#define LMTYPE_BKSZ_2	((0x2) << FShft(LMTYPE_BKSZ))
+#define LMTYPE_ROWSZ	Fld(4,4)
+#define LMTYPE_ROWSZ_11	((0xb) << FShft(LMTYPE_ROWSZ))
+#define LMTYPE_ROWSZ_12	((0xc) << FShft(LMTYPE_ROWSZ))
+#define LMTYPE_ROWSZ_13	((0xd) << FShft(LMTYPE_ROWSZ))
+#define LMTYPE_COLSZ	Fld(4,0)
+#define LMTYPE_COLSZ_7	((0x7) << FShft(LMTYPE_COLSZ))
+#define LMTYPE_COLSZ_8	((0x8) << FShft(LMTYPE_COLSZ))
+#define LMTYPE_COLSZ_9	((0x9) << FShft(LMTYPE_COLSZ))
+#define LMTYPE_COLSZ_10	((0xa) << FShft(LMTYPE_COLSZ))
+#define LMTYPE_COLSZ_11	((0xb) << FShft(LMTYPE_COLSZ))
+#define LMTYPE_COLSZ_12	((0xc) << FShft(LMTYPE_COLSZ))
+
+/* LMTIM - Local Memory (SDRAM) Timing Register */
+#define LMTIM_TRAS	Fld(4,16)
+#define Lmtim_Tras(x)	((x) << FShft(LMTIM_TRAS))
+#define LMTIM_TRP	Fld(4,12)
+#define Lmtim_Trp(x)	((x) << FShft(LMTIM_TRP))
+#define LMTIM_TRCD	Fld(4,8)
+#define Lmtim_Trcd(x)	((x) << FShft(LMTIM_TRCD))
+#define LMTIM_TRC	Fld(4,4)
+#define Lmtim_Trc(x)	((x) << FShft(LMTIM_TRC))
+#define LMTIM_TDPL	Fld(4,0)
+#define Lmtim_Tdpl(x)	((x) << FShft(LMTIM_TDPL))
+
+/* LMREFRESH - Local Memory (SDRAM) tREF Control Register */
+#define LMREFRESH_TREF	Fld(2,0)
+#define Lmrefresh_Tref(x)	((x) << FShft(LMREFRESH_TREF))
+
+/* GSCTRL - Graphics surface control register */
+#define GSCTRL_LUT_EN	(1 << 31)
+#define GSCTRL_GPIXFMT	Fld(4,27)
+#define GSCTRL_GPIXFMT_INDEXED	((0x0) << FShft(GSCTRL_GPIXFMT))
+#define GSCTRL_GPIXFMT_ARGB4444	((0x4) << FShft(GSCTRL_GPIXFMT))
+#define GSCTRL_GPIXFMT_ARGB1555	((0x5) << FShft(GSCTRL_GPIXFMT))
+#define GSCTRL_GPIXFMT_RGB888	((0x6) << FShft(GSCTRL_GPIXFMT))
+#define GSCTRL_GPIXFMT_RGB565	((0x7) << FShft(GSCTRL_GPIXFMT))
+#define GSCTRL_GPIXFMT_ARGB8888	((0x8) << FShft(GSCTRL_GPIXFMT))
+#define GSCTRL_GAMMA_EN	(1 << 26)
+
+#define GSCTRL_GSWIDTH Fld(11,11)
+#define Gsctrl_Width(Pixel)	/* Display Width [1..2048 pix.]  */ \
+                        (((Pixel) - 1) << FShft(GSCTRL_GSWIDTH))
+
+#define GSCTRL_GSHEIGHT Fld(11,0)
+#define Gsctrl_Height(Pixel)	/* Display Height [1..2048 pix.]  */ \
+                        (((Pixel) - 1) << FShft(GSCTRL_GSHEIGHT))
+
+/* GBBASE fileds */
+#define GBBASE_GLALPHA Fld(8,24)
+#define Gbbase_Glalpha(x)	((x) << FShft(GBBASE_GLALPHA))
+
+#define GBBASE_COLKEY Fld(24,0)
+#define Gbbase_Colkey(x)	((x) << FShft(GBBASE_COLKEY))
+
+/* GDRCTRL fields */
+#define GDRCTRL_PIXDBL	(1 << 31)
+#define GDRCTRL_PIXHLV	(1 << 30)
+#define GDRCTRL_LNDBL	(1 << 29)
+#define GDRCTRL_LNHLV	(1 << 28)
+#define GDRCTRL_COLKEYM	Fld(24,0)
+#define Gdrctrl_Colkeym(x)	((x) << FShft(GDRCTRL_COLKEYM))
+
+/* GSCADR graphics stream control address register fields */
+#define GSCADR_STR_EN	(1 << 31)
+#define GSCADR_COLKEY_EN	(1 << 30)
+#define GSCADR_COLKEYSCR	(1 << 29)
+#define GSCADR_BLEND_M	Fld(2,27)
+#define GSCADR_BLEND_NONE	((0x0) << FShft(GSCADR_BLEND_M))
+#define GSCADR_BLEND_INV	((0x1) << FShft(GSCADR_BLEND_M))
+#define GSCADR_BLEND_GLOB	((0x2) << FShft(GSCADR_BLEND_M))
+#define GSCADR_BLEND_PIX	((0x3) << FShft(GSCADR_BLEND_M))
+#define GSCADR_BLEND_POS	Fld(2,24)
+#define GSCADR_BLEND_GFX	((0x0) << FShft(GSCADR_BLEND_POS))
+#define GSCADR_BLEND_VID	((0x1) << FShft(GSCADR_BLEND_POS))
+#define GSCADR_BLEND_CUR	((0x2) << FShft(GSCADR_BLEND_POS))
+#define GSCADR_GBASE_ADR	Fld(23,0)
+#define Gscadr_Gbase_Adr(x)	((x) << FShft(GSCADR_GBASE_ADR))
+
+/* GSADR graphics stride address register fields */
+#define GSADR_SRCSTRIDE	Fld(10,22)
+#define Gsadr_Srcstride(x)	((x) << FShft(GSADR_SRCSTRIDE))
+#define GSADR_XSTART	Fld(11,11)
+#define Gsadr_Xstart(x)		((x) << FShft(GSADR_XSTART))
+#define GSADR_YSTART	Fld(11,0)
+#define Gsadr_Ystart(y)		((y) << FShft(GSADR_YSTART))
+
+/* GPLUT graphics palette register fields */
+#define GPLUT_LUTADR	Fld(8,24)
+#define Gplut_Lutadr(x)	((x) << FShft(GPLUT_LUTADR))
+#define GPLUT_LUTDATA	Fld(24,0)
+#define Gplut_Lutdata(x)	((x) << FShft(GPLUT_LUTDATA))
+
+/* HCCTRL - Hardware Cursor Register fields */
+#define HCCTRL_CUR_EN	(1 << 31)
+#define HCCTRL_COLKEY_EN	(1 << 29)
+#define HCCTRL_COLKEYSRC	(1 << 28)
+#define HCCTRL_BLEND_M	Fld(2,26)
+#define HCCTRL_BLEND_NONE	((0x0) << FShft(HCCTRL_BLEND_M))
+#define HCCTRL_BLEND_INV	((0x1) << FShft(HCCTRL_BLEND_M))
+#define HCCTRL_BLEND_GLOB	((0x2) << FShft(HCCTRL_BLEND_M))
+#define HCCTRL_BLEND_PIX	((0x3) << FShft(HCCTRL_BLEND_M))
+#define HCCTRL_CPIXFMT	Fld(3,23)
+#define HCCTRL_CPIXFMT_RGB332	((0x3) << FShft(HCCTRL_CPIXFMT))
+#define HCCTRL_CPIXFMT_ARGB4444	((0x4) << FShft(HCCTRL_CPIXFMT))
+#define HCCTRL_CPIXFMT_ARGB1555	((0x5) << FShft(HCCTRL_CPIXFMT))
+#define HCCTRL_CBASE_ADR	Fld(23,0)
+#define Hcctrl_Cbase_Adr(x)	((x) << FShft(HCCTRL_CBASE_ADR))
+
+/* HCSIZE Hardware Cursor Size Register fields */
+#define HCSIZE_BLEND_POS	Fld(2,29)
+#define HCSIZE_BLEND_GFX	((0x0) << FShft(HCSIZE_BLEND_POS))
+#define HCSIZE_BLEND_VID	((0x1) << FShft(HCSIZE_BLEND_POS))
+#define HCSIZE_BLEND_CUR	((0x2) << FShft(HCSIZE_BLEND_POS))
+#define HCSIZE_CWIDTH	Fld(3,16)
+#define Hcsize_Cwidth(x)	((x) << FShft(HCSIZE_CWIDTH))
+#define HCSIZE_CHEIGHT	Fld(3,0)
+#define Hcsize_Cheight(x)	((x) << FShft(HCSIZE_CHEIGHT))
+
+/* HCPOS Hardware Cursor Position Register fields */
+#define HCPOS_SWITCHSRC	(1 << 30)
+#define HCPOS_CURBLINK	Fld(6,24)
+#define Hcpos_Curblink(x)	((x) << FShft(HCPOS_CURBLINK))
+#define HCPOS_XSTART	Fld(12,12)
+#define Hcpos_Xstart(x)	((x) << FShft(HCPOS_XSTART))
+#define HCPOS_YSTART	Fld(12,0)
+#define Hcpos_Ystart(y)	((y) << FShft(HCPOS_YSTART))
+
+/* HCBADR Hardware Cursor Blend Address Register */
+#define HCBADR_GLALPHA	Fld(8,24)
+#define Hcbadr_Glalpha(x)	((x) << FShft(HCBADR_GLALPHA))
+#define HCBADR_COLKEY	Fld(24,0)
+#define Hcbadr_Colkey(x)	((x) << FShft(HCBADR_COLKEY))
+
+/* HCCKMSK - Hardware Cursor Color Key Mask Register */
+#define HCCKMSK_COLKEY_M	Fld(24,0)
+#define Hcckmsk_Colkey_M(x)	((x) << FShft(HCCKMSK_COLKEY_M))
+
+/* DSCTRL - Display sync control register */
+#define DSCTRL_SYNCGEN_EN	(1 << 31)
+#define DSCTRL_DPL_RST		(1 << 29)
+#define DSCTRL_PWRDN_M		(1 << 28)
+#define DSCTRL_UPDSYNCCNT	(1 << 26)
+#define DSCTRL_UPDINTCNT	(1 << 25)
+#define DSCTRL_UPDCNT		(1 << 24)
+#define DSCTRL_UPDWAIT	Fld(4,16)
+#define Dsctrl_Updwait(x)	((x) << FShft(DSCTRL_UPDWAIT))
+#define DSCTRL_CLKPOL		(1 << 11)
+#define DSCTRL_CSYNC_EN		(1 << 10)
+#define DSCTRL_VS_SLAVE		(1 << 7)
+#define DSCTRL_HS_SLAVE		(1 << 6)
+#define DSCTRL_BLNK_POL		(1 << 5)
+#define DSCTRL_BLNK_DIS		(1 << 4)
+#define DSCTRL_VS_POL		(1 << 3)
+#define DSCTRL_VS_DIS		(1 << 2)
+#define DSCTRL_HS_POL		(1 << 1)
+#define DSCTRL_HS_DIS		(1 << 0)
+
+/* DHT01 - Display horizontal timing register 01 */
+#define DHT01_HBPS	Fld(12,16)
+#define Dht01_Hbps(x)	((x) << FShft(DHT01_HBPS))
+#define DHT01_HT	Fld(12,0)
+#define Dht01_Ht(x)	((x) << FShft(DHT01_HT))
+
+/* DHT02 - Display horizontal timing register 02 */
+#define DHT02_HAS	Fld(12,16)
+#define Dht02_Has(x)	((x) << FShft(DHT02_HAS))
+#define DHT02_HLBS	Fld(12,0)
+#define Dht02_Hlbs(x)	((x) << FShft(DHT02_HLBS))
+
+/* DHT03 - Display horizontal timing register 03 */
+#define DHT03_HFPS	Fld(12,16)
+#define Dht03_Hfps(x)	((x) << FShft(DHT03_HFPS))
+#define DHT03_HRBS	Fld(12,0)
+#define Dht03_Hrbs(x)	((x) << FShft(DHT03_HRBS))
+
+/* DVT01 - Display vertical timing register 01 */
+#define DVT01_VBPS	Fld(12,16)
+#define Dvt01_Vbps(x)	((x) << FShft(DVT01_VBPS))
+#define DVT01_VT	Fld(12,0)
+#define Dvt01_Vt(x)	((x) << FShft(DVT01_VT))
+
+/* DVT02 - Display vertical timing register 02 */
+#define DVT02_VAS	Fld(12,16)
+#define Dvt02_Vas(x)	((x) << FShft(DVT02_VAS))
+#define DVT02_VTBS	Fld(12,0)
+#define Dvt02_Vtbs(x)	((x) << FShft(DVT02_VTBS))
+
+/* DVT03 - Display vertical timing register 03 */
+#define DVT03_VFPS	Fld(12,16)
+#define Dvt03_Vfps(x)	((x) << FShft(DVT03_VFPS))
+#define DVT03_VBBS	Fld(12,0)
+#define Dvt03_Vbbs(x)	((x) << FShft(DVT03_VBBS))
+
+/* DVECTRL - display vertical event control register */
+#define DVECTRL_VEVENT	Fld(12,16)
+#define Dvectrl_Vevent(x)	((x) << FShft(DVECTRL_VEVENT))
+#define DVECTRL_VFETCH	Fld(12,0)
+#define Dvectrl_Vfetch(x)	((x) << FShft(DVECTRL_VFETCH))
+
+/* DHDET - display horizontal DE timing register */
+#define DHDET_HDES	Fld(12,16)
+#define Dhdet_Hdes(x)	((x) << FShft(DHDET_HDES))
+#define DHDET_HDEF	Fld(12,0)
+#define Dhdet_Hdef(x)	((x) << FShft(DHDET_HDEF))
+
+/* DVDET - display vertical DE timing register */
+#define DVDET_VDES	Fld(12,16)
+#define Dvdet_Vdes(x)	((x) << FShft(DVDET_VDES))
+#define DVDET_VDEF	Fld(12,0)
+#define Dvdet_Vdef(x)	((x) << FShft(DVDET_VDEF))
+
+/* DODMSK - display output data mask register */
+#define DODMSK_MASK_LVL	(1 << 31)
+#define DODMSK_BLNK_LVL	(1 << 30)
+#define DODMSK_MASK_B	Fld(8,16)
+#define Dodmsk_Mask_B(x)	((x) << FShft(DODMSK_MASK_B))
+#define DODMSK_MASK_G	Fld(8,8)
+#define Dodmsk_Mask_G(x)	((x) << FShft(DODMSK_MASK_G))
+#define DODMSK_MASK_R	Fld(8,0)
+#define Dodmsk_Mask_R(x)	((x) << FShft(DODMSK_MASK_R))
+
+/* DBCOL - display border color control register */
+#define DBCOL_BORDCOL	Fld(24,0)
+#define Dbcol_Bordcol(x)	((x) << FShft(DBCOL_BORDCOL))
+
+/* DVLNUM - display vertical line number register */
+#define DVLNUM_VLINE	Fld(12,0)
+#define Dvlnum_Vline(x)	((x) << FShft(DVLNUM_VLINE))
+
+/* DMCTRL - Display Memory Control Register */
+#define DMCTRL_MEM_REF	Fld(2,30)
+#define DMCTRL_MEM_REF_ACT	((0x0) << FShft(DMCTRL_MEM_REF))
+#define DMCTRL_MEM_REF_HB	((0x1) << FShft(DMCTRL_MEM_REF))
+#define DMCTRL_MEM_REF_VB	((0x2) << FShft(DMCTRL_MEM_REF))
+#define DMCTRL_MEM_REF_BOTH	((0x3) << FShft(DMCTRL_MEM_REF))
+#define DMCTRL_UV_THRHLD	Fld(6,24)
+#define Dmctrl_Uv_Thrhld(x)	((x) << FShft(DMCTRL_UV_THRHLD))
+#define DMCTRL_V_THRHLD		Fld(7,16)
+#define Dmctrl_V_Thrhld(x)	((x) << FShft(DMCTRL_V_THRHLD))
+#define DMCTRL_D_THRHLD		Fld(7,8)
+#define Dmctrl_D_Thrhld(x)	((x) << FShft(DMCTRL_D_THRHLD))
+#define DMCTRL_BURSTLEN	Fld(6,0)
+#define Dmctrl_Burstlen(x)	((x) << FShft(DMCTRL_BURSTLEN))
+
+
+/* DLSTS - display load status register */
+#define DLSTS_RLD_ADONE	(1 << 23)
+/* #define DLSTS_RLD_ADOUT	Fld(23,0) */
+
+/* DLLCTRL - display list load control register */
+#define DLLCTRL_RLD_ADRLN	Fld(8,24)
+#define Dllctrl_Rld_Adrln(x)	((x) << FShft(DLLCTRL_RLD_ADRLN))
+
+/* SPOCTRL - Scale Pitch/Order Control Register */
+#define SPOCTRL_H_SC_BP		(1 << 31)
+#define SPOCTRL_V_SC_BP		(1 << 30)
+#define SPOCTRL_HV_SC_OR	(1 << 29)
+#define SPOCTRL_VS_UR_C		(1 << 27)
+#define SPOCTRL_VORDER	Fld(2,16)
+#define SPOCTRL_VORDER_1TAP	((0x0) << FShft(SPOCTRL_VORDER))
+#define SPOCTRL_VORDER_2TAP	((0x1) << FShft(SPOCTRL_VORDER))
+#define SPOCTRL_VORDER_4TAP	((0x3) << FShft(SPOCTRL_VORDER))
+#define SPOCTRL_VPITCH	Fld(16,0)
+#define Spoctrl_Vpitch(x)	((x) << FShft(SPOCTRL_VPITCH))
+
+#endif /* __REG_BITS_2700G_ */
diff --git a/drivers/video/mbx/regs.h b/drivers/video/mbx/regs.h
new file mode 100644
index 0000000..ad20be0
--- /dev/null
+++ b/drivers/video/mbx/regs.h
@@ -0,0 +1,195 @@
+#ifndef __REGS_2700G_
+#define __REGS_2700G_
+
+/* extern unsigned long virt_base_2700; */
+/* #define __REG_2700G(x)	(*(volatile unsigned long*)((x)+virt_base_2700)) */
+#define __REG_2700G(x)	((x)+virt_base_2700)
+
+/* System Configuration Registers (0x0000_0000  0x0000_0010) */
+#define SYSCFG		__REG_2700G(0x00000000)
+#define PFBASE		__REG_2700G(0x00000004)
+#define PFCEIL		__REG_2700G(0x00000008)
+#define POLLFLAG	__REG_2700G(0x0000000c)
+#define SYSRST		__REG_2700G(0x00000010)
+
+/* Interrupt Control Registers (0x0000_0014  0x0000_002F) */
+#define NINTPW		__REG_2700G(0x00000014)
+#define MINTENABLE	__REG_2700G(0x00000018)
+#define MINTSTAT	__REG_2700G(0x0000001c)
+#define SINTENABLE	__REG_2700G(0x00000020)
+#define SINTSTAT	__REG_2700G(0x00000024)
+#define SINTCLR		__REG_2700G(0x00000028)
+
+/* Clock Control Registers (0x0000_002C  0x0000_005F) */
+#define SYSCLKSRC	__REG_2700G(0x0000002c)
+#define PIXCLKSRC	__REG_2700G(0x00000030)
+#define CLKSLEEP	__REG_2700G(0x00000034)
+#define COREPLL		__REG_2700G(0x00000038)
+#define DISPPLL		__REG_2700G(0x0000003c)
+#define PLLSTAT		__REG_2700G(0x00000040)
+#define VOVRCLK		__REG_2700G(0x00000044)
+#define PIXCLK		__REG_2700G(0x00000048)
+#define MEMCLK		__REG_2700G(0x0000004c)
+#define M24CLK		__REG_2700G(0x00000054)
+#define MBXCLK		__REG_2700G(0x00000054)
+#define SDCLK		__REG_2700G(0x00000058)
+#define PIXCLKDIV	__REG_2700G(0x0000005c)
+
+/* LCD Port Control Register (0x0000_0060  0x0000_006F) */
+#define LCD_CONFIG	__REG_2700G(0x00000060)
+
+/* On-Die Frame Buffer Registers (0x0000_0064  0x0000_006B) */
+#define ODFBPWR		__REG_2700G(0x00000064)
+#define ODFBSTAT	__REG_2700G(0x00000068)
+
+/* GPIO Registers (0x0000_006C  0x0000_007F) */
+#define GPIOCGF		__REG_2700G(0x0000006c)
+#define GPIOHI		__REG_2700G(0x00000070)
+#define GPIOLO		__REG_2700G(0x00000074)
+#define GPIOSTAT	__REG_2700G(0x00000078)
+
+/* Pulse Width Modulator (PWM) Registers (0x0000_0200  0x0000_02FF) */
+#define PWMRST		__REG_2700G(0x00000200)
+#define PWMCFG		__REG_2700G(0x00000204)
+#define PWM0DIV		__REG_2700G(0x00000210)
+#define PWM0DUTY	__REG_2700G(0x00000214)
+#define PWM0PER		__REG_2700G(0x00000218)
+#define PWM1DIV		__REG_2700G(0x00000220)
+#define PWM1DUTY	__REG_2700G(0x00000224)
+#define PWM1PER		__REG_2700G(0x00000228)
+
+/* Identification (ID) Registers (0x0000_0300  0x0000_0FFF) */
+#define ID		__REG_2700G(0x00000FF0)
+
+/* Local Memory (SDRAM) Interface Registers (0x0000_1000  0x0000_1FFF) */
+#define LMRST		__REG_2700G(0x00001000)
+#define LMCFG		__REG_2700G(0x00001004)
+#define LMPWR		__REG_2700G(0x00001008)
+#define LMPWRSTAT	__REG_2700G(0x0000100c)
+#define LMCEMR		__REG_2700G(0x00001010)
+#define LMTYPE		__REG_2700G(0x00001014)
+#define LMTIM		__REG_2700G(0x00001018)
+#define LMREFRESH	__REG_2700G(0x0000101c)
+#define LMPROTMIN	__REG_2700G(0x00001020)
+#define LMPROTMAX	__REG_2700G(0x00001024)
+#define LMPROTCFG	__REG_2700G(0x00001028)
+#define LMPROTERR	__REG_2700G(0x0000102c)
+
+/* Plane Controller Registers (0x0000_2000  0x0000_2FFF) */
+#define GSCTRL		__REG_2700G(0x00002000)
+#define VSCTRL		__REG_2700G(0x00002004)
+#define GBBASE		__REG_2700G(0x00002020)
+#define VBBASE		__REG_2700G(0x00002024)
+#define GDRCTRL		__REG_2700G(0x00002040)
+#define VCMSK		__REG_2700G(0x00002044)
+#define GSCADR		__REG_2700G(0x00002060)
+#define VSCADR		__REG_2700G(0x00002064)
+#define VUBASE		__REG_2700G(0x00002084)
+#define VVBASE		__REG_2700G(0x000020a4)
+#define GSADR		__REG_2700G(0x000020c0)
+#define VSADR		__REG_2700G(0x000020c4)
+#define HCCTRL		__REG_2700G(0x00002100)
+#define HCSIZE		__REG_2700G(0x00002110)
+#define HCPOS		__REG_2700G(0x00002120)
+#define HCBADR		__REG_2700G(0x00002130)
+#define HCCKMSK		__REG_2700G(0x00002140)
+#define GPLUT		__REG_2700G(0x00002150)
+#define DSCTRL		__REG_2700G(0x00002154)
+#define DHT01		__REG_2700G(0x00002158)
+#define DHT02		__REG_2700G(0x0000215c)
+#define DHT03		__REG_2700G(0x00002160)
+#define DVT01		__REG_2700G(0x00002164)
+#define DVT02		__REG_2700G(0x00002168)
+#define DVT03		__REG_2700G(0x0000216c)
+#define DBCOL		__REG_2700G(0x00002170)
+#define BGCOLOR		__REG_2700G(0x00002174)
+#define DINTRS		__REG_2700G(0x00002178)
+#define DINTRE		__REG_2700G(0x0000217c)
+#define DINTRCNT	__REG_2700G(0x00002180)
+#define DSIG		__REG_2700G(0x00002184)
+#define DMCTRL		__REG_2700G(0x00002188)
+#define CLIPCTRL	__REG_2700G(0x0000218c)
+#define SPOCTRL		__REG_2700G(0x00002190)
+#define SVCTRL		__REG_2700G(0x00002194)
+
+/* 0x0000_2198 */
+/* 0x0000_21A8 VSCOEFF[0:4] Video Scalar Vertical Coefficient [0:4] 4.14.5 */
+#define VSCOEFF0	__REG_2700G(0x00002198)
+#define VSCOEFF1	__REG_2700G(0x0000219c)
+#define VSCOEFF2	__REG_2700G(0x000021a0)
+#define VSCOEFF3	__REG_2700G(0x000021a4)
+#define VSCOEFF4	__REG_2700G(0x000021a8)
+
+#define SHCTRL		__REG_2700G(0x000021b0)
+
+/* 0x0000_21B4 */
+/* 0x0000_21D4 HSCOEFF[0:8] Video Scalar Horizontal Coefficient [0:8] 4.14.7 */
+#define HSCOEFF0	__REG_2700G(0x000021b4)
+#define HSCOEFF1	__REG_2700G(0x000021b8)
+#define HSCOEFF2	__REG_2700G(0x000021bc)
+#define HSCOEFF3	__REG_2700G(0x000021b0)
+#define HSCOEFF4	__REG_2700G(0x000021c4)
+#define HSCOEFF5	__REG_2700G(0x000021c8)
+#define HSCOEFF6	__REG_2700G(0x000021cc)
+#define HSCOEFF7	__REG_2700G(0x000021d0)
+#define HSCOEFF8	__REG_2700G(0x000021d4)
+
+#define SSSIZE		__REG_2700G(0x000021D8)
+
+/* 0x0000_2200 */
+/* 0x0000_2240 VIDGAM[0:16] Video Gamma LUT Index [0:16] 4.15.2 */
+#define VIDGAM0		__REG_2700G(0x00002200)
+#define VIDGAM1		__REG_2700G(0x00002204)
+#define VIDGAM2		__REG_2700G(0x00002208)
+#define VIDGAM3		__REG_2700G(0x0000220c)
+#define VIDGAM4		__REG_2700G(0x00002210)
+#define VIDGAM5		__REG_2700G(0x00002214)
+#define VIDGAM6		__REG_2700G(0x00002218)
+#define VIDGAM7		__REG_2700G(0x0000221c)
+#define VIDGAM8		__REG_2700G(0x00002220)
+#define VIDGAM9		__REG_2700G(0x00002224)
+#define VIDGAM10	__REG_2700G(0x00002228)
+#define VIDGAM11	__REG_2700G(0x0000222c)
+#define VIDGAM12	__REG_2700G(0x00002230)
+#define VIDGAM13	__REG_2700G(0x00002234)
+#define VIDGAM14	__REG_2700G(0x00002238)
+#define VIDGAM15	__REG_2700G(0x0000223c)
+#define VIDGAM16	__REG_2700G(0x00002240)
+
+/* 0x0000_2250 */
+/* 0x0000_2290 GFXGAM[0:16] Graphics Gamma LUT Index [0:16] 4.15.3 */
+#define GFXGAM0		__REG_2700G(0x00002250)
+#define GFXGAM1		__REG_2700G(0x00002254)
+#define GFXGAM2		__REG_2700G(0x00002258)
+#define GFXGAM3		__REG_2700G(0x0000225c)
+#define GFXGAM4		__REG_2700G(0x00002260)
+#define GFXGAM5		__REG_2700G(0x00002264)
+#define GFXGAM6		__REG_2700G(0x00002268)
+#define GFXGAM7		__REG_2700G(0x0000226c)
+#define GFXGAM8		__REG_2700G(0x00002270)
+#define GFXGAM9		__REG_2700G(0x00002274)
+#define GFXGAM10	__REG_2700G(0x00002278)
+#define GFXGAM11	__REG_2700G(0x0000227c)
+#define GFXGAM12	__REG_2700G(0x00002280)
+#define GFXGAM13	__REG_2700G(0x00002284)
+#define GFXGAM14	__REG_2700G(0x00002288)
+#define GFXGAM15	__REG_2700G(0x0000228c)
+#define GFXGAM16	__REG_2700G(0x00002290)
+
+#define DLSTS		__REG_2700G(0x00002300)
+#define DLLCTRL		__REG_2700G(0x00002304)
+#define DVLNUM		__REG_2700G(0x00002308)
+#define DUCTRL		__REG_2700G(0x0000230c)
+#define DVECTRL		__REG_2700G(0x00002310)
+#define DHDET		__REG_2700G(0x00002314)
+#define DVDET		__REG_2700G(0x00002318)
+#define DODMSK		__REG_2700G(0x0000231c)
+#define CSC01		__REG_2700G(0x00002330)
+#define CSC02		__REG_2700G(0x00002334)
+#define CSC03		__REG_2700G(0x00002338)
+#define CSC04		__REG_2700G(0x0000233c)
+#define CSC05		__REG_2700G(0x00002340)
+
+#define FB_MEMORY_START	__REG_2700G(0x00060000)
+
+#endif /* __REGS_2700G_ */
diff --git a/fs/char_dev.c b/fs/char_dev.c
index a4cbc67..3483d3c 100644
--- a/fs/char_dev.c
+++ b/fs/char_dev.c
@@ -182,6 +182,28 @@
 	return 0;
 }
 
+/**
+ * register_chrdev() - Register a major number for character devices.
+ * @major: major device number or 0 for dynamic allocation
+ * @name: name of this range of devices
+ * @fops: file operations associated with this devices
+ *
+ * If @major == 0 this functions will dynamically allocate a major and return
+ * its number.
+ *
+ * If @major > 0 this function will attempt to reserve a device with the given
+ * major number and will return zero on success.
+ *
+ * Returns a -ve errno on failure.
+ *
+ * The name of this device has nothing to do with the name of the device in
+ * /dev. It only helps to keep track of the different owners of devices. If
+ * your module name has only one type of devices it's ok to use e.g. the name
+ * of the module here.
+ *
+ * This function registers a range of 256 minor numbers. The first minor number
+ * is 0.
+ */
 int register_chrdev(unsigned int major, const char *name,
 		    const struct file_operations *fops)
 {
diff --git a/fs/namei.c b/fs/namei.c
index c9750d7..e01070d 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -1712,8 +1712,14 @@
 	if (error)
 		goto exit_dput;
 	error = __do_follow_link(&path, nd);
-	if (error)
+	if (error) {
+		/* Does someone understand code flow here? Or it is only
+		 * me so stupid? Anathema to whoever designed this non-sense
+		 * with "intent.open".
+		 */
+		release_open_intent(nd);
 		return error;
+	}
 	nd->flags &= ~LOOKUP_PARENT;
 	if (nd->last_type == LAST_BIND)
 		goto ok;
diff --git a/fs/proc/array.c b/fs/proc/array.c
index 7495d3e..0b615d6 100644
--- a/fs/proc/array.c
+++ b/fs/proc/array.c
@@ -74,6 +74,7 @@
 #include <linux/times.h>
 #include <linux/cpuset.h>
 #include <linux/rcupdate.h>
+#include <linux/delayacct.h>
 
 #include <asm/uaccess.h>
 #include <asm/pgtable.h>
@@ -411,7 +412,7 @@
 
 	res = sprintf(buffer,"%d (%s) %c %d %d %d %d %d %lu %lu \
 %lu %lu %lu %lu %lu %ld %ld %ld %ld %d 0 %llu %lu %ld %lu %lu %lu %lu %lu \
-%lu %lu %lu %lu %lu %lu %lu %lu %d %d %lu %lu\n",
+%lu %lu %lu %lu %lu %lu %lu %lu %d %d %lu %lu %llu\n",
 		task->pid,
 		tcomm,
 		state,
@@ -455,7 +456,8 @@
 		task->exit_signal,
 		task_cpu(task),
 		task->rt_priority,
-		task->policy);
+		task->policy,
+		(unsigned long long)delayacct_blkio_ticks(task));
 	if(mm)
 		mmput(mm);
 	return res;
diff --git a/fs/proc/base.c b/fs/proc/base.c
index 243a94a..474eae3 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -1339,6 +1339,7 @@
 			inode->i_uid = 0;
 			inode->i_gid = 0;
 		}
+		inode->i_mode &= ~(S_ISUID | S_ISGID);
 		security_task_to_inode(task, inode);
 		put_task_struct(task);
 		return 1;
@@ -1389,6 +1390,7 @@
 					inode->i_uid = 0;
 					inode->i_gid = 0;
 				}
+				inode->i_mode &= ~(S_ISUID | S_ISGID);
 				security_task_to_inode(task, inode);
 				put_task_struct(task);
 				return 1;
diff --git a/fs/reiserfs/procfs.c b/fs/reiserfs/procfs.c
index 5d8a8cf..c533ec1 100644
--- a/fs/reiserfs/procfs.c
+++ b/fs/reiserfs/procfs.c
@@ -492,9 +492,17 @@
 
 int reiserfs_proc_info_init(struct super_block *sb)
 {
+	char b[BDEVNAME_SIZE];
+	char *s;
+
+	/* Some block devices use /'s */
+	strlcpy(b, reiserfs_bdevname(sb), BDEVNAME_SIZE);
+	s = strchr(b, '/');
+	if (s)
+		*s = '!';
+
 	spin_lock_init(&__PINFO(sb).lock);
-	REISERFS_SB(sb)->procdir =
-	    proc_mkdir(reiserfs_bdevname(sb), proc_info_root);
+	REISERFS_SB(sb)->procdir = proc_mkdir(b, proc_info_root);
 	if (REISERFS_SB(sb)->procdir) {
 		REISERFS_SB(sb)->procdir->owner = THIS_MODULE;
 		REISERFS_SB(sb)->procdir->data = sb;
@@ -508,13 +516,22 @@
 		return 0;
 	}
 	reiserfs_warning(sb, "reiserfs: cannot create /proc/%s/%s",
-			 proc_info_root_name, reiserfs_bdevname(sb));
+			 proc_info_root_name, b);
 	return 1;
 }
 
 int reiserfs_proc_info_done(struct super_block *sb)
 {
 	struct proc_dir_entry *de = REISERFS_SB(sb)->procdir;
+	char b[BDEVNAME_SIZE];
+	char *s;
+
+	/* Some block devices use /'s */
+	strlcpy(b, reiserfs_bdevname(sb), BDEVNAME_SIZE);
+	s = strchr(b, '/');
+	if (s)
+		*s = '!';
+
 	if (de) {
 		remove_proc_entry("journal", de);
 		remove_proc_entry("oidmap", de);
@@ -528,7 +545,7 @@
 	__PINFO(sb).exiting = 1;
 	spin_unlock(&__PINFO(sb).lock);
 	if (proc_info_root) {
-		remove_proc_entry(reiserfs_bdevname(sb), proc_info_root);
+		remove_proc_entry(b, proc_info_root);
 		REISERFS_SB(sb)->procdir = NULL;
 	}
 	return 0;
diff --git a/include/asm-alpha/barrier.h b/include/asm-alpha/barrier.h
index 681ff58..384dc08d 100644
--- a/include/asm-alpha/barrier.h
+++ b/include/asm-alpha/barrier.h
@@ -30,7 +30,4 @@
 #define set_mb(var, value) \
 do { var = value; mb(); } while (0)
 
-#define set_wmb(var, value) \
-do { var = value; wmb(); } while (0)
-
 #endif		/* __BARRIER_H */
diff --git a/include/asm-arm/system.h b/include/asm-arm/system.h
index 6001feb..0947cbf 100644
--- a/include/asm-arm/system.h
+++ b/include/asm-arm/system.h
@@ -176,7 +176,6 @@
 #define wmb() mb()
 #define read_barrier_depends() do { } while(0)
 #define set_mb(var, value)  do { var = value; mb(); } while (0)
-#define set_wmb(var, value) do { var = value; wmb(); } while (0)
 #define nop() __asm__ __volatile__("mov\tr0,r0\t@ nop\n\t");
 
 /*
diff --git a/include/asm-arm26/system.h b/include/asm-arm26/system.h
index d1f69d7..00ae32a 100644
--- a/include/asm-arm26/system.h
+++ b/include/asm-arm26/system.h
@@ -90,7 +90,6 @@
 
 #define read_barrier_depends() do { } while(0)
 #define set_mb(var, value)  do { var = value; mb(); } while (0)
-#define set_wmb(var, value) do { var = value; wmb(); } while (0)
 
 /*
  * We assume knowledge of how
diff --git a/include/asm-cris/system.h b/include/asm-cris/system.h
index b1c593b..b869f61 100644
--- a/include/asm-cris/system.h
+++ b/include/asm-cris/system.h
@@ -17,7 +17,6 @@
 #define wmb() mb()
 #define read_barrier_depends() do { } while(0)
 #define set_mb(var, value)  do { var = value; mb(); } while (0)
-#define set_wmb(var, value) do { var = value; wmb(); } while (0)
 
 #ifdef CONFIG_SMP
 #define smp_mb()        mb()
diff --git a/include/asm-frv/system.h b/include/asm-frv/system.h
index 351863d..1166899 100644
--- a/include/asm-frv/system.h
+++ b/include/asm-frv/system.h
@@ -179,7 +179,6 @@
 #define rmb()			asm volatile ("membar" : : :"memory")
 #define wmb()			asm volatile ("membar" : : :"memory")
 #define set_mb(var, value)	do { var = value; mb(); } while (0)
-#define set_wmb(var, value)	do { var = value; wmb(); } while (0)
 
 #define smp_mb()		mb()
 #define smp_rmb()		rmb()
diff --git a/include/asm-generic/Kbuild.asm b/include/asm-generic/Kbuild.asm
index d8d0bce..6b16dda 100644
--- a/include/asm-generic/Kbuild.asm
+++ b/include/asm-generic/Kbuild.asm
@@ -1,11 +1,8 @@
 unifdef-y += a.out.h auxvec.h byteorder.h errno.h fcntl.h ioctl.h	\
-	ioctls.h ipcbuf.h irq.h mman.h msgbuf.h param.h poll.h		\
+	ioctls.h ipcbuf.h mman.h msgbuf.h param.h poll.h		\
 	posix_types.h ptrace.h resource.h sembuf.h shmbuf.h shmparam.h	\
 	sigcontext.h siginfo.h signal.h socket.h sockios.h stat.h	\
 	statfs.h termbits.h termios.h timex.h types.h unistd.h user.h
 
-# These really shouldn't be exported
-unifdef-y += atomic.h io.h
-
 # These probably shouldn't be exported
 unifdef-y += elf.h page.h
diff --git a/include/asm-h8300/system.h b/include/asm-h8300/system.h
index 134e092..5084a9d 100644
--- a/include/asm-h8300/system.h
+++ b/include/asm-h8300/system.h
@@ -84,7 +84,6 @@
 #define wmb()  asm volatile (""   : : :"memory")
 #define set_rmb(var, value)    do { xchg(&var, value); } while (0)
 #define set_mb(var, value)     set_rmb(var, value)
-#define set_wmb(var, value)    do { var = value; wmb(); } while (0)
 
 #ifdef CONFIG_SMP
 #define smp_mb()	mb()
diff --git a/include/asm-i386/system.h b/include/asm-i386/system.h
index 2db168e..49928eb 100644
--- a/include/asm-i386/system.h
+++ b/include/asm-i386/system.h
@@ -453,8 +453,6 @@
 #define set_mb(var, value) do { var = value; barrier(); } while (0)
 #endif
 
-#define set_wmb(var, value) do { var = value; wmb(); } while (0)
-
 #include <linux/irqflags.h>
 
 /*
diff --git a/include/asm-ia64/system.h b/include/asm-ia64/system.h
index 65db43c..fc9677b 100644
--- a/include/asm-ia64/system.h
+++ b/include/asm-ia64/system.h
@@ -98,12 +98,11 @@
 #endif
 
 /*
- * XXX check on these---I suspect what Linus really wants here is
+ * XXX check on this ---I suspect what Linus really wants here is
  * acquire vs release semantics but we can't discuss this stuff with
  * Linus just yet.  Grrr...
  */
 #define set_mb(var, value)	do { (var) = (value); mb(); } while (0)
-#define set_wmb(var, value)	do { (var) = (value); mb(); } while (0)
 
 #define safe_halt()         ia64_pal_halt_light()    /* PAL_HALT_LIGHT */
 
diff --git a/include/asm-m32r/system.h b/include/asm-m32r/system.h
index 311cebf..9e618af 100644
--- a/include/asm-m32r/system.h
+++ b/include/asm-m32r/system.h
@@ -336,7 +336,6 @@
 #endif
 
 #define set_mb(var, value) do { xchg(&var, value); } while (0)
-#define set_wmb(var, value) do { var = value; wmb(); } while (0)
 
 #define arch_align_stack(x) (x)
 
diff --git a/include/asm-m68k/system.h b/include/asm-m68k/system.h
index d6dd805..131a0cb 100644
--- a/include/asm-m68k/system.h
+++ b/include/asm-m68k/system.h
@@ -80,7 +80,6 @@
 #define wmb()		barrier()
 #define read_barrier_depends()	do { } while(0)
 #define set_mb(var, value)    do { xchg(&var, value); } while (0)
-#define set_wmb(var, value)    do { var = value; wmb(); } while (0)
 
 #define smp_mb()	barrier()
 #define smp_rmb()	barrier()
diff --git a/include/asm-m68knommu/system.h b/include/asm-m68knommu/system.h
index 2bbe2db..2a81449 100644
--- a/include/asm-m68knommu/system.h
+++ b/include/asm-m68knommu/system.h
@@ -106,7 +106,6 @@
 #define wmb()  asm volatile (""   : : :"memory")
 #define set_rmb(var, value)    do { xchg(&var, value); } while (0)
 #define set_mb(var, value)     set_rmb(var, value)
-#define set_wmb(var, value)    do { var = value; wmb(); } while (0)
 
 #ifdef CONFIG_SMP
 #define smp_mb()	mb()
diff --git a/include/asm-mips/system.h b/include/asm-mips/system.h
index 13c98dd..dcb4701 100644
--- a/include/asm-mips/system.h
+++ b/include/asm-mips/system.h
@@ -143,9 +143,6 @@
 #define set_mb(var, value) \
 do { var = value; mb(); } while (0)
 
-#define set_wmb(var, value) \
-do { var = value; wmb(); } while (0)
-
 /*
  * switch_to(n) should switch tasks to task nr n, first
  * checking that n isn't the current task, in which case it does nothing.
diff --git a/include/asm-parisc/system.h b/include/asm-parisc/system.h
index 5fe2d23..74f037a 100644
--- a/include/asm-parisc/system.h
+++ b/include/asm-parisc/system.h
@@ -143,8 +143,6 @@
 #define read_barrier_depends()		do { } while(0)
 
 #define set_mb(var, value)		do { var = value; mb(); } while (0)
-#define set_wmb(var, value)		do { var = value; wmb(); } while (0)
-
 
 #ifndef CONFIG_PA20
 /* Because kmalloc only guarantees 8-byte alignment for kmalloc'd data,
diff --git a/include/asm-powerpc/system.h b/include/asm-powerpc/system.h
index c656951..7307aa7 100644
--- a/include/asm-powerpc/system.h
+++ b/include/asm-powerpc/system.h
@@ -39,7 +39,6 @@
 #define read_barrier_depends()  do { } while(0)
 
 #define set_mb(var, value)	do { var = value; mb(); } while (0)
-#define set_wmb(var, value)	do { var = value; wmb(); } while (0)
 
 #ifdef __KERNEL__
 #ifdef CONFIG_SMP
diff --git a/include/asm-ppc/system.h b/include/asm-ppc/system.h
index fb49c0c..7389435 100644
--- a/include/asm-ppc/system.h
+++ b/include/asm-ppc/system.h
@@ -33,7 +33,6 @@
 #define read_barrier_depends()  do { } while(0)
 
 #define set_mb(var, value)	do { var = value; mb(); } while (0)
-#define set_wmb(var, value)	do { var = value; wmb(); } while (0)
 
 #ifdef CONFIG_SMP
 #define smp_mb()	mb()
diff --git a/include/asm-s390/system.h b/include/asm-s390/system.h
index 9ab186f..36a3a85 100644
--- a/include/asm-s390/system.h
+++ b/include/asm-s390/system.h
@@ -299,7 +299,6 @@
 
 
 #define set_mb(var, value)      do { var = value; mb(); } while (0)
-#define set_wmb(var, value)     do { var = value; wmb(); } while (0)
 
 #ifdef __s390x__
 
diff --git a/include/asm-sh/system.h b/include/asm-sh/system.h
index ce2e606..ad35ad4 100644
--- a/include/asm-sh/system.h
+++ b/include/asm-sh/system.h
@@ -101,7 +101,6 @@
 #endif
 
 #define set_mb(var, value) do { xchg(&var, value); } while (0)
-#define set_wmb(var, value) do { var = value; wmb(); } while (0)
 
 /* Interrupt Control */
 static __inline__ void local_irq_enable(void)
diff --git a/include/asm-sh64/system.h b/include/asm-sh64/system.h
index 7606f6e..87ef6f1 100644
--- a/include/asm-sh64/system.h
+++ b/include/asm-sh64/system.h
@@ -66,7 +66,6 @@
 
 #define set_rmb(var, value) do { xchg(&var, value); } while (0)
 #define set_mb(var, value) set_rmb(var, value)
-#define set_wmb(var, value) do { var = value; wmb(); } while (0)
 
 /* Interrupt Control */
 #ifndef HARD_CLI
diff --git a/include/asm-sparc/system.h b/include/asm-sparc/system.h
index cb7dda1..100c3ea 100644
--- a/include/asm-sparc/system.h
+++ b/include/asm-sparc/system.h
@@ -199,7 +199,6 @@
 #define wmb()	mb()
 #define read_barrier_depends()	do { } while(0)
 #define set_mb(__var, __value)  do { __var = __value; mb(); } while(0)
-#define set_wmb(__var, __value) set_mb(__var, __value)
 #define smp_mb()	__asm__ __volatile__("":::"memory")
 #define smp_rmb()	__asm__ __volatile__("":::"memory")
 #define smp_wmb()	__asm__ __volatile__("":::"memory")
diff --git a/include/asm-sparc64/system.h b/include/asm-sparc64/system.h
index 4ca6860..a8b7432 100644
--- a/include/asm-sparc64/system.h
+++ b/include/asm-sparc64/system.h
@@ -123,8 +123,6 @@
 #define read_barrier_depends()		do { } while(0)
 #define set_mb(__var, __value) \
 	do { __var = __value; membar_storeload_storestore(); } while(0)
-#define set_wmb(__var, __value) \
-	do { __var = __value; wmb(); } while(0)
 
 #ifdef CONFIG_SMP
 #define smp_mb()	mb()
diff --git a/include/asm-v850/system.h b/include/asm-v850/system.h
index 7091af4..da39916 100644
--- a/include/asm-v850/system.h
+++ b/include/asm-v850/system.h
@@ -68,7 +68,6 @@
 #define read_barrier_depends()	((void)0)
 #define set_rmb(var, value)	do { xchg (&var, value); } while (0)
 #define set_mb(var, value)	set_rmb (var, value)
-#define set_wmb(var, value)	do { var = value; wmb (); } while (0)
 
 #define smp_mb()	mb ()
 #define smp_rmb()	rmb ()
diff --git a/include/asm-x86_64/system.h b/include/asm-x86_64/system.h
index f67f287..6bf170b 100644
--- a/include/asm-x86_64/system.h
+++ b/include/asm-x86_64/system.h
@@ -240,7 +240,6 @@
 #endif
 #define read_barrier_depends()	do {} while(0)
 #define set_mb(var, value) do { (void) xchg(&var, value); } while (0)
-#define set_wmb(var, value) do { var = value; wmb(); } while (0)
 
 #define warn_if_not_ulong(x) do { unsigned long foo; (void) (&(x) == &foo); } while (0)
 
diff --git a/include/asm-xtensa/system.h b/include/asm-xtensa/system.h
index f986170..932bda9 100644
--- a/include/asm-xtensa/system.h
+++ b/include/asm-xtensa/system.h
@@ -99,7 +99,6 @@
 #endif
 
 #define set_mb(var, value)	do { var = value; mb(); } while (0)
-#define set_wmb(var, value)	do { var = value; wmb(); } while (0)
 
 #if !defined (__ASSEMBLY__)
 
diff --git a/include/linux/delayacct.h b/include/linux/delayacct.h
new file mode 100644
index 0000000..7e8b601
--- /dev/null
+++ b/include/linux/delayacct.h
@@ -0,0 +1,119 @@
+/* delayacct.h - per-task delay accounting
+ *
+ * Copyright (C) Shailabh Nagar, IBM Corp. 2006
+ *
+ * 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.
+ *
+ */
+
+#ifndef _LINUX_DELAYACCT_H
+#define _LINUX_DELAYACCT_H
+
+#include <linux/sched.h>
+#include <linux/taskstats_kern.h>
+
+/*
+ * Per-task flags relevant to delay accounting
+ * maintained privately to avoid exhausting similar flags in sched.h:PF_*
+ * Used to set current->delays->flags
+ */
+#define DELAYACCT_PF_SWAPIN	0x00000001	/* I am doing a swapin */
+
+#ifdef CONFIG_TASK_DELAY_ACCT
+
+extern int delayacct_on;	/* Delay accounting turned on/off */
+extern kmem_cache_t *delayacct_cache;
+extern void delayacct_init(void);
+extern void __delayacct_tsk_init(struct task_struct *);
+extern void __delayacct_tsk_exit(struct task_struct *);
+extern void __delayacct_blkio_start(void);
+extern void __delayacct_blkio_end(void);
+extern int __delayacct_add_tsk(struct taskstats *, struct task_struct *);
+extern __u64 __delayacct_blkio_ticks(struct task_struct *);
+
+static inline void delayacct_set_flag(int flag)
+{
+	if (current->delays)
+		current->delays->flags |= flag;
+}
+
+static inline void delayacct_clear_flag(int flag)
+{
+	if (current->delays)
+		current->delays->flags &= ~flag;
+}
+
+static inline void delayacct_tsk_init(struct task_struct *tsk)
+{
+	/* reinitialize in case parent's non-null pointer was dup'ed*/
+	tsk->delays = NULL;
+	if (unlikely(delayacct_on))
+		__delayacct_tsk_init(tsk);
+}
+
+static inline void delayacct_tsk_exit(struct task_struct *tsk)
+{
+	if (tsk->delays)
+		__delayacct_tsk_exit(tsk);
+}
+
+static inline void delayacct_blkio_start(void)
+{
+	if (current->delays)
+		__delayacct_blkio_start();
+}
+
+static inline void delayacct_blkio_end(void)
+{
+	if (current->delays)
+		__delayacct_blkio_end();
+}
+
+static inline int delayacct_add_tsk(struct taskstats *d,
+					struct task_struct *tsk)
+{
+	if (likely(!delayacct_on))
+		return -EINVAL;
+	if (!tsk->delays)
+		return 0;
+	return __delayacct_add_tsk(d, tsk);
+}
+
+static inline __u64 delayacct_blkio_ticks(struct task_struct *tsk)
+{
+	if (tsk->delays)
+		return __delayacct_blkio_ticks(tsk);
+	return 0;
+}
+
+#else
+static inline void delayacct_set_flag(int flag)
+{}
+static inline void delayacct_clear_flag(int flag)
+{}
+static inline void delayacct_init(void)
+{}
+static inline void delayacct_tsk_init(struct task_struct *tsk)
+{}
+static inline void delayacct_tsk_exit(struct task_struct *tsk)
+{}
+static inline void delayacct_blkio_start(void)
+{}
+static inline void delayacct_blkio_end(void)
+{}
+static inline int delayacct_add_tsk(struct taskstats *d,
+					struct task_struct *tsk)
+{ return 0; }
+static inline __u64 delayacct_blkio_ticks(struct task_struct *tsk)
+{ return 0; }
+#endif /* CONFIG_TASK_DELAY_ACCT */
+
+#endif
diff --git a/include/linux/i2c-id.h b/include/linux/i2c-id.h
index 21338bb..9418519 100644
--- a/include/linux/i2c-id.h
+++ b/include/linux/i2c-id.h
@@ -115,6 +115,7 @@
 #define I2C_DRIVERID_BT866	85	/* Conexant bt866 video encoder */
 #define I2C_DRIVERID_KS0127	86	/* Samsung ks0127 video decoder */
 #define I2C_DRIVERID_TLV320AIC23B 87	/* TI TLV320AIC23B audio codec  */
+#define I2C_DRIVERID_ISL1208	88	/* Intersil ISL1208 RTC		*/
 
 #define I2C_DRIVERID_I2CDEV	900
 #define I2C_DRIVERID_ARP        902    /* SMBus ARP Client              */
diff --git a/include/linux/if_vlan.h b/include/linux/if_vlan.h
index eef0876..383627a 100644
--- a/include/linux/if_vlan.h
+++ b/include/linux/if_vlan.h
@@ -23,8 +23,8 @@
 struct vlan_dev_info;
 struct hlist_node;
 
-#include <linux/proc_fs.h> /* for proc_dir_entry */
 #include <linux/netdevice.h>
+#include <linux/etherdevice.h>
 
 #define VLAN_HLEN	4		/* The additional bytes (on top of the Ethernet header)
 					 * that VLAN requires.
@@ -185,7 +185,8 @@
 		 * This allows the VLAN to have a different MAC than the underlying
 		 * device, and still route correctly.
 		 */
-		if (!memcmp(eth_hdr(skb)->h_dest, skb->dev->dev_addr, ETH_ALEN))
+		if (!compare_ether_addr(eth_hdr(skb)->h_dest,
+				       	skb->dev->dev_addr))
 			skb->pkt_type = PACKET_HOST;
 		break;
 	};
diff --git a/include/linux/kthread.h b/include/linux/kthread.h
index 7cce5df..1c65e7a 100644
--- a/include/linux/kthread.h
+++ b/include/linux/kthread.h
@@ -28,7 +28,6 @@
 
 void kthread_bind(struct task_struct *k, unsigned int cpu);
 int kthread_stop(struct task_struct *k);
-int kthread_stop_sem(struct task_struct *k, struct semaphore *s);
 int kthread_should_stop(void);
 
 #endif /* _LINUX_KTHREAD_H */
diff --git a/include/linux/list.h b/include/linux/list.h
index 6b74adf..65a5b5c 100644
--- a/include/linux/list.h
+++ b/include/linux/list.h
@@ -265,6 +265,17 @@
 }
 
 /**
+ * list_is_last - tests whether @list is the last entry in list @head
+ * @list: the entry to test
+ * @head: the head of the list
+ */
+static inline int list_is_last(const struct list_head *list,
+				const struct list_head *head)
+{
+	return list->next == head;
+}
+
+/**
  * list_empty - tests whether a list is empty
  * @head: the list to test.
  */
diff --git a/include/linux/module.h b/include/linux/module.h
index d06c74f..0dfb794 100644
--- a/include/linux/module.h
+++ b/include/linux/module.h
@@ -362,10 +362,8 @@
 
 /* Returns module and fills in value, defined and namebuf, or NULL if
    symnum out of range. */
-struct module *module_get_kallsym(unsigned int symnum,
-				  unsigned long *value,
-				  char *type,
-				  char namebuf[128]);
+struct module *module_get_kallsym(unsigned int symnum, unsigned long *value,
+				char *type, char *name, size_t namelen);
 
 /* Look for this name: can be of form module:name. */
 unsigned long module_kallsyms_lookup_name(const char *name);
@@ -535,8 +533,8 @@
 
 static inline struct module *module_get_kallsym(unsigned int symnum,
 						unsigned long *value,
-						char *type,
-						char namebuf[128])
+						char *type, char *name,
+						size_t namelen)
 {
 	return NULL;
 }
diff --git a/include/linux/namei.h b/include/linux/namei.h
index 58cb3d3..45511a5 100644
--- a/include/linux/namei.h
+++ b/include/linux/namei.h
@@ -11,7 +11,7 @@
 	struct file *file;
 };
 
-enum { MAX_NESTED_LINKS = 5 };
+enum { MAX_NESTED_LINKS = 8 };
 
 struct nameidata {
 	struct dentry	*dentry;
diff --git a/include/linux/nsc_gpio.h b/include/linux/nsc_gpio.h
index 135742c..7da0cf3 100644
--- a/include/linux/nsc_gpio.h
+++ b/include/linux/nsc_gpio.h
@@ -25,8 +25,6 @@
 	void	(*gpio_dump)	(struct nsc_gpio_ops *amp, unsigned iminor);
 	int	(*gpio_get)	(unsigned iminor);
 	void	(*gpio_set)	(unsigned iminor, int state);
-	void	(*gpio_set_high)(unsigned iminor);
-	void	(*gpio_set_low)	(unsigned iminor);
 	void	(*gpio_change)	(unsigned iminor);
 	int	(*gpio_current)	(unsigned iminor);
 	struct device*	dev;	/* for dev_dbg() support, set in init  */
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 1c876e2..6afa72e 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -463,6 +463,10 @@
 #ifdef CONFIG_BSD_PROCESS_ACCT
 	struct pacct_struct pacct;	/* per-process accounting information */
 #endif
+#ifdef CONFIG_TASKSTATS
+	spinlock_t stats_lock;
+	struct taskstats *stats;
+#endif
 };
 
 /* Context switch must be unlocked if interrupts are to be enabled */
@@ -537,7 +541,7 @@
 struct backing_dev_info;
 struct reclaim_state;
 
-#ifdef CONFIG_SCHEDSTATS
+#if defined(CONFIG_SCHEDSTATS) || defined(CONFIG_TASK_DELAY_ACCT)
 struct sched_info {
 	/* cumulative counters */
 	unsigned long	cpu_time,	/* time spent on the cpu */
@@ -548,9 +552,53 @@
 	unsigned long	last_arrival,	/* when we last ran on a cpu */
 			last_queued;	/* when we were last queued to run */
 };
+#endif /* defined(CONFIG_SCHEDSTATS) || defined(CONFIG_TASK_DELAY_ACCT) */
 
+#ifdef CONFIG_SCHEDSTATS
 extern struct file_operations proc_schedstat_operations;
+#endif /* CONFIG_SCHEDSTATS */
+
+#ifdef CONFIG_TASK_DELAY_ACCT
+struct task_delay_info {
+	spinlock_t	lock;
+	unsigned int	flags;	/* Private per-task flags */
+
+	/* For each stat XXX, add following, aligned appropriately
+	 *
+	 * struct timespec XXX_start, XXX_end;
+	 * u64 XXX_delay;
+	 * u32 XXX_count;
+	 *
+	 * Atomicity of updates to XXX_delay, XXX_count protected by
+	 * single lock above (split into XXX_lock if contention is an issue).
+	 */
+
+	/*
+	 * XXX_count is incremented on every XXX operation, the delay
+	 * associated with the operation is added to XXX_delay.
+	 * XXX_delay contains the accumulated delay time in nanoseconds.
+	 */
+	struct timespec blkio_start, blkio_end;	/* Shared by blkio, swapin */
+	u64 blkio_delay;	/* wait for sync block io completion */
+	u64 swapin_delay;	/* wait for swapin block io completion */
+	u32 blkio_count;	/* total count of the number of sync block */
+				/* io operations performed */
+	u32 swapin_count;	/* total count of the number of swapin block */
+				/* io operations performed */
+};
+#endif	/* CONFIG_TASK_DELAY_ACCT */
+
+static inline int sched_info_on(void)
+{
+#ifdef CONFIG_SCHEDSTATS
+	return 1;
+#elif defined(CONFIG_TASK_DELAY_ACCT)
+	extern int delayacct_on;
+	return delayacct_on;
+#else
+	return 0;
 #endif
+}
 
 enum idle_type
 {
@@ -747,7 +795,7 @@
 	cpumask_t cpus_allowed;
 	unsigned int time_slice, first_time_slice;
 
-#ifdef CONFIG_SCHEDSTATS
+#if defined(CONFIG_SCHEDSTATS) || defined(CONFIG_TASK_DELAY_ACCT)
 	struct sched_info sched_info;
 #endif
 
@@ -945,6 +993,10 @@
 	 * cache last used pipe for splice
 	 */
 	struct pipe_inode_info *splice_pipe;
+#ifdef	CONFIG_TASK_DELAY_ACCT
+	spinlock_t delays_lock;
+	struct task_delay_info *delays;
+#endif
 };
 
 static inline pid_t process_group(struct task_struct *tsk)
diff --git a/include/linux/taskstats.h b/include/linux/taskstats.h
new file mode 100644
index 0000000..f1cb6cd
--- /dev/null
+++ b/include/linux/taskstats.h
@@ -0,0 +1,137 @@
+/* taskstats.h - exporting per-task statistics
+ *
+ * Copyright (C) Shailabh Nagar, IBM Corp. 2006
+ *           (C) Balbir Singh,   IBM Corp. 2006
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2.1 of the GNU Lesser General Public License
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it would be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef _LINUX_TASKSTATS_H
+#define _LINUX_TASKSTATS_H
+
+/* Format for per-task data returned to userland when
+ *	- a task exits
+ *	- listener requests stats for a task
+ *
+ * The struct is versioned. Newer versions should only add fields to
+ * the bottom of the struct to maintain backward compatibility.
+ *
+ *
+ * To add new fields
+ *	a) bump up TASKSTATS_VERSION
+ *	b) add comment indicating new version number at end of struct
+ *	c) add new fields after version comment; maintain 64-bit alignment
+ */
+
+#define TASKSTATS_VERSION	1
+
+struct taskstats {
+
+	/* Version 1 */
+	__u16	version;
+	__u16	padding[3];	/* Userspace should not interpret the padding
+				 * field which can be replaced by useful
+				 * fields if struct taskstats is extended.
+				 */
+
+	/* Delay accounting fields start
+	 *
+	 * All values, until comment "Delay accounting fields end" are
+	 * available only if delay accounting is enabled, even though the last
+	 * few fields are not delays
+	 *
+	 * xxx_count is the number of delay values recorded
+	 * xxx_delay_total is the corresponding cumulative delay in nanoseconds
+	 *
+	 * xxx_delay_total wraps around to zero on overflow
+	 * xxx_count incremented regardless of overflow
+	 */
+
+	/* Delay waiting for cpu, while runnable
+	 * count, delay_total NOT updated atomically
+	 */
+	__u64	cpu_count;
+	__u64	cpu_delay_total;
+
+	/* Following four fields atomically updated using task->delays->lock */
+
+	/* Delay waiting for synchronous block I/O to complete
+	 * does not account for delays in I/O submission
+	 */
+	__u64	blkio_count;
+	__u64	blkio_delay_total;
+
+	/* Delay waiting for page fault I/O (swap in only) */
+	__u64	swapin_count;
+	__u64	swapin_delay_total;
+
+	/* cpu "wall-clock" running time
+	 * On some architectures, value will adjust for cpu time stolen
+	 * from the kernel in involuntary waits due to virtualization.
+	 * Value is cumulative, in nanoseconds, without a corresponding count
+	 * and wraps around to zero silently on overflow
+	 */
+	__u64	cpu_run_real_total;
+
+	/* cpu "virtual" running time
+	 * Uses time intervals seen by the kernel i.e. no adjustment
+	 * for kernel's involuntary waits due to virtualization.
+	 * Value is cumulative, in nanoseconds, without a corresponding count
+	 * and wraps around to zero silently on overflow
+	 */
+	__u64	cpu_run_virtual_total;
+	/* Delay accounting fields end */
+	/* version 1 ends here */
+};
+
+
+/*
+ * Commands sent from userspace
+ * Not versioned. New commands should only be inserted at the enum's end
+ * prior to __TASKSTATS_CMD_MAX
+ */
+
+enum {
+	TASKSTATS_CMD_UNSPEC = 0,	/* Reserved */
+	TASKSTATS_CMD_GET,		/* user->kernel request/get-response */
+	TASKSTATS_CMD_NEW,		/* kernel->user event */
+	__TASKSTATS_CMD_MAX,
+};
+
+#define TASKSTATS_CMD_MAX (__TASKSTATS_CMD_MAX - 1)
+
+enum {
+	TASKSTATS_TYPE_UNSPEC = 0,	/* Reserved */
+	TASKSTATS_TYPE_PID,		/* Process id */
+	TASKSTATS_TYPE_TGID,		/* Thread group id */
+	TASKSTATS_TYPE_STATS,		/* taskstats structure */
+	TASKSTATS_TYPE_AGGR_PID,	/* contains pid + stats */
+	TASKSTATS_TYPE_AGGR_TGID,	/* contains tgid + stats */
+	__TASKSTATS_TYPE_MAX,
+};
+
+#define TASKSTATS_TYPE_MAX (__TASKSTATS_TYPE_MAX - 1)
+
+enum {
+	TASKSTATS_CMD_ATTR_UNSPEC = 0,
+	TASKSTATS_CMD_ATTR_PID,
+	TASKSTATS_CMD_ATTR_TGID,
+	TASKSTATS_CMD_ATTR_REGISTER_CPUMASK,
+	TASKSTATS_CMD_ATTR_DEREGISTER_CPUMASK,
+	__TASKSTATS_CMD_ATTR_MAX,
+};
+
+#define TASKSTATS_CMD_ATTR_MAX (__TASKSTATS_CMD_ATTR_MAX - 1)
+
+/* NETLINK_GENERIC related info */
+
+#define TASKSTATS_GENL_NAME	"TASKSTATS"
+#define TASKSTATS_GENL_VERSION	0x1
+
+#endif /* _LINUX_TASKSTATS_H */
diff --git a/include/linux/taskstats_kern.h b/include/linux/taskstats_kern.h
new file mode 100644
index 0000000..16894b7
--- /dev/null
+++ b/include/linux/taskstats_kern.h
@@ -0,0 +1,89 @@
+/* taskstats_kern.h - kernel header for per-task statistics interface
+ *
+ * Copyright (C) Shailabh Nagar, IBM Corp. 2006
+ *           (C) Balbir Singh,   IBM Corp. 2006
+ */
+
+#ifndef _LINUX_TASKSTATS_KERN_H
+#define _LINUX_TASKSTATS_KERN_H
+
+#include <linux/taskstats.h>
+#include <linux/sched.h>
+#include <net/genetlink.h>
+
+#ifdef CONFIG_TASKSTATS
+extern kmem_cache_t *taskstats_cache;
+extern struct mutex taskstats_exit_mutex;
+
+static inline void taskstats_exit_free(struct taskstats *tidstats)
+{
+	if (tidstats)
+		kmem_cache_free(taskstats_cache, tidstats);
+}
+
+static inline void taskstats_tgid_init(struct signal_struct *sig)
+{
+	spin_lock_init(&sig->stats_lock);
+	sig->stats = NULL;
+}
+
+static inline void taskstats_tgid_alloc(struct signal_struct *sig)
+{
+	struct taskstats *stats;
+	unsigned long flags;
+
+	stats = kmem_cache_zalloc(taskstats_cache, SLAB_KERNEL);
+	if (!stats)
+		return;
+
+	spin_lock_irqsave(&sig->stats_lock, flags);
+	if (!sig->stats) {
+		sig->stats = stats;
+		stats = NULL;
+	}
+	spin_unlock_irqrestore(&sig->stats_lock, flags);
+
+	if (stats)
+		kmem_cache_free(taskstats_cache, stats);
+}
+
+static inline void taskstats_tgid_free(struct signal_struct *sig)
+{
+	struct taskstats *stats = NULL;
+	unsigned long flags;
+
+	spin_lock_irqsave(&sig->stats_lock, flags);
+	if (sig->stats) {
+		stats = sig->stats;
+		sig->stats = NULL;
+	}
+	spin_unlock_irqrestore(&sig->stats_lock, flags);
+	if (stats)
+		kmem_cache_free(taskstats_cache, stats);
+}
+
+extern void taskstats_exit_alloc(struct taskstats **, unsigned int *);
+extern void taskstats_exit_send(struct task_struct *, struct taskstats *, int, unsigned int);
+extern void taskstats_init_early(void);
+extern void taskstats_tgid_alloc(struct signal_struct *);
+#else
+static inline void taskstats_exit_alloc(struct taskstats **ptidstats, unsigned int *mycpu)
+{}
+static inline void taskstats_exit_free(struct taskstats *ptidstats)
+{}
+static inline void taskstats_exit_send(struct task_struct *tsk,
+				       struct taskstats *tidstats,
+				       int group_dead, unsigned int cpu)
+{}
+static inline void taskstats_tgid_init(struct signal_struct *sig)
+{}
+static inline void taskstats_tgid_alloc(struct signal_struct *sig)
+{}
+static inline void taskstats_tgid_free(struct signal_struct *sig)
+{}
+static inline void taskstats_init_early(void)
+{}
+#endif /* CONFIG_TASKSTATS */
+
+#endif
+
diff --git a/include/linux/time.h b/include/linux/time.h
index c05f8bb..a5b7399 100644
--- a/include/linux/time.h
+++ b/include/linux/time.h
@@ -71,6 +71,18 @@
 extern void set_normalized_timespec(struct timespec *ts, time_t sec, long nsec);
 
 /*
+ * sub = lhs - rhs, in normalized form
+ */
+static inline struct timespec timespec_sub(struct timespec lhs,
+						struct timespec rhs)
+{
+	struct timespec ts_delta;
+	set_normalized_timespec(&ts_delta, lhs.tv_sec - rhs.tv_sec,
+				lhs.tv_nsec - rhs.tv_nsec);
+	return ts_delta;
+}
+
+/*
  * Returns true if the timespec is norm, false if denorm:
  */
 #define timespec_valid(ts) \
diff --git a/include/linux/vmalloc.h b/include/linux/vmalloc.h
index f6024ab..71b6363 100644
--- a/include/linux/vmalloc.h
+++ b/include/linux/vmalloc.h
@@ -11,6 +11,7 @@
 #define VM_ALLOC	0x00000002	/* vmalloc() */
 #define VM_MAP		0x00000004	/* vmap()ed pages */
 #define VM_USERMAP	0x00000008	/* suitable for remap_vmalloc_range */
+#define VM_VPAGES	0x00000010	/* buffer for pages was vmalloc'ed */
 /* bits [20..32] reserved for arch specific ioremap internals */
 
 /*
diff --git a/include/net/genetlink.h b/include/net/genetlink.h
index 805de50..8c22872 100644
--- a/include/net/genetlink.h
+++ b/include/net/genetlink.h
@@ -150,4 +150,24 @@
 	return nlmsg_unicast(genl_sock, skb, pid);
 }
 
+/**
+ * gennlmsg_data - head of message payload
+ * @gnlh: genetlink messsage header
+ */
+static inline void *genlmsg_data(const struct genlmsghdr *gnlh)
+{
+	return ((unsigned char *) gnlh + GENL_HDRLEN);
+}
+
+/**
+ * genlmsg_len - length of message payload
+ * @gnlh: genetlink message header
+ */
+static inline int genlmsg_len(const struct genlmsghdr *gnlh)
+{
+	struct nlmsghdr *nlh = (struct nlmsghdr *)((unsigned char *)gnlh -
+							NLMSG_HDRLEN);
+	return (nlh->nlmsg_len - GENL_HDRLEN - NLMSG_HDRLEN);
+}
+
 #endif	/* __NET_GENERIC_NETLINK_H */
diff --git a/include/rdma/ib_addr.h b/include/rdma/ib_addr.h
index fcb5ba87d..0ff6739 100644
--- a/include/rdma/ib_addr.h
+++ b/include/rdma/ib_addr.h
@@ -89,9 +89,10 @@
 	dev_addr->broadcast[9] = (unsigned char) pkey;
 }
 
-static inline union ib_gid *ib_addr_get_sgid(struct rdma_dev_addr *dev_addr)
+static inline void ib_addr_get_sgid(struct rdma_dev_addr *dev_addr,
+				    union ib_gid *gid)
 {
-	return 	(union ib_gid *) (dev_addr->src_dev_addr + 4);
+	memcpy(gid, dev_addr->src_dev_addr + 4, sizeof *gid);
 }
 
 static inline void ib_addr_set_sgid(struct rdma_dev_addr *dev_addr,
@@ -100,9 +101,10 @@
 	memcpy(dev_addr->src_dev_addr + 4, gid, sizeof *gid);
 }
 
-static inline union ib_gid *ib_addr_get_dgid(struct rdma_dev_addr *dev_addr)
+static inline void ib_addr_get_dgid(struct rdma_dev_addr *dev_addr,
+				    union ib_gid *gid)
 {
-	return 	(union ib_gid *) (dev_addr->dst_dev_addr + 4);
+	memcpy(gid, dev_addr->dst_dev_addr + 4, sizeof *gid);
 }
 
 static inline void ib_addr_set_dgid(struct rdma_dev_addr *dev_addr,
diff --git a/include/rdma/ib_fmr_pool.h b/include/rdma/ib_fmr_pool.h
index 4ace54c..00dadbf 100644
--- a/include/rdma/ib_fmr_pool.h
+++ b/include/rdma/ib_fmr_pool.h
@@ -88,7 +88,7 @@
 struct ib_pool_fmr *ib_fmr_pool_map_phys(struct ib_fmr_pool *pool_handle,
 					 u64                *page_list,
 					 int                 list_len,
-					 u64                *io_virtual_address);
+					 u64                 io_virtual_address);
 
 int ib_fmr_pool_unmap(struct ib_pool_fmr *fmr);
 
diff --git a/include/video/mbxfb.h b/include/video/mbxfb.h
new file mode 100644
index 0000000..3bde0f5
--- /dev/null
+++ b/include/video/mbxfb.h
@@ -0,0 +1,28 @@
+#ifndef __MBX_FB_H
+#define __MBX_FB_H
+
+struct mbxfb_val {
+	unsigned int	defval;
+	unsigned int	min;
+	unsigned int	max;
+};
+
+struct fb_info;
+
+struct mbxfb_platform_data {
+		/* Screen info */
+		struct mbxfb_val xres;
+		struct mbxfb_val yres;
+		struct mbxfb_val bpp;
+
+		/* Memory info */
+		unsigned long memsize; /* if 0 use ODFB? */
+		unsigned long timings1;
+		unsigned long timings2;
+		unsigned long timings3;
+
+		int (*probe)(struct fb_info *fb);
+		int (*remove)(struct fb_info *fb);
+};
+
+#endif /* __MBX_FB_H */
diff --git a/init/Kconfig b/init/Kconfig
index a5b073a..a099fc6 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -158,6 +158,30 @@
 	  for processing it. A preliminary version of these tools is available
 	  at <http://www.physik3.uni-rostock.de/tim/kernel/utils/acct/>.
 
+config TASKSTATS
+	bool "Export task/process statistics through netlink (EXPERIMENTAL)"
+	depends on NET
+	default n
+	help
+	  Export selected statistics for tasks/processes through the
+	  generic netlink interface. Unlike BSD process accounting, the
+	  statistics are available during the lifetime of tasks/processes as
+	  responses to commands. Like BSD accounting, they are sent to user
+	  space on task exit.
+
+	  Say N if unsure.
+
+config TASK_DELAY_ACCT
+	bool "Enable per-task delay accounting (EXPERIMENTAL)"
+	depends on TASKSTATS
+	help
+	  Collect information on time spent by a task waiting for system
+	  resources like cpu, synchronous block I/O completion and swapping
+	  in pages. Such statistics can help in setting a task's priorities
+	  relative to other tasks for cpu, io, rss limits etc.
+
+	  Say N if unsure.
+
 config SYSCTL
 	bool "Sysctl support" if EMBEDDED
 	default y
diff --git a/init/main.c b/init/main.c
index 628b8e9..8651a72 100644
--- a/init/main.c
+++ b/init/main.c
@@ -41,6 +41,8 @@
 #include <linux/cpu.h>
 #include <linux/cpuset.h>
 #include <linux/efi.h>
+#include <linux/taskstats_kern.h>
+#include <linux/delayacct.h>
 #include <linux/unistd.h>
 #include <linux/rmap.h>
 #include <linux/mempolicy.h>
@@ -574,6 +576,8 @@
 	proc_root_init();
 #endif
 	cpuset_init();
+	taskstats_init_early();
+	delayacct_init();
 
 	check_bugs();
 
diff --git a/kernel/Makefile b/kernel/Makefile
index 47dbcd5..d62ec66 100644
--- a/kernel/Makefile
+++ b/kernel/Makefile
@@ -48,6 +48,8 @@
 obj-$(CONFIG_SECCOMP) += seccomp.o
 obj-$(CONFIG_RCU_TORTURE_TEST) += rcutorture.o
 obj-$(CONFIG_RELAY) += relay.o
+obj-$(CONFIG_TASK_DELAY_ACCT) += delayacct.o
+obj-$(CONFIG_TASKSTATS) += taskstats.o
 
 ifneq ($(CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER),y)
 # According to Alan Modra <alan@linuxcare.com.au>, the -fno-omit-frame-pointer is
diff --git a/kernel/acct.c b/kernel/acct.c
index f18e0b8..2a7c933 100644
--- a/kernel/acct.c
+++ b/kernel/acct.c
@@ -488,7 +488,7 @@
 		old_encode_dev(tty_devnum(current->signal->tty)) : 0;
 	read_unlock(&tasklist_lock);
 
-	spin_lock(&current->sighand->siglock);
+	spin_lock_irq(&current->sighand->siglock);
 	ac.ac_utime = encode_comp_t(jiffies_to_AHZ(cputime_to_jiffies(pacct->ac_utime)));
 	ac.ac_stime = encode_comp_t(jiffies_to_AHZ(cputime_to_jiffies(pacct->ac_stime)));
 	ac.ac_flag = pacct->ac_flag;
@@ -496,7 +496,7 @@
 	ac.ac_minflt = encode_comp_t(pacct->ac_minflt);
 	ac.ac_majflt = encode_comp_t(pacct->ac_majflt);
 	ac.ac_exitcode = pacct->ac_exitcode;
-	spin_unlock(&current->sighand->siglock);
+	spin_unlock_irq(&current->sighand->siglock);
 	ac.ac_io = encode_comp_t(0 /* current->io_usage */);	/* %% */
 	ac.ac_rw = encode_comp_t(ac.ac_io / 1024);
 	ac.ac_swaps = encode_comp_t(0);
diff --git a/kernel/delayacct.c b/kernel/delayacct.c
new file mode 100644
index 0000000..f05392d
--- /dev/null
+++ b/kernel/delayacct.c
@@ -0,0 +1,178 @@
+/* delayacct.c - per-task delay accounting
+ *
+ * Copyright (C) Shailabh Nagar, IBM Corp. 2006
+ *
+ * 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 would 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/sched.h>
+#include <linux/slab.h>
+#include <linux/time.h>
+#include <linux/sysctl.h>
+#include <linux/delayacct.h>
+
+int delayacct_on __read_mostly;	/* Delay accounting turned on/off */
+kmem_cache_t *delayacct_cache;
+
+static int __init delayacct_setup_enable(char *str)
+{
+	delayacct_on = 1;
+	return 1;
+}
+__setup("delayacct", delayacct_setup_enable);
+
+void delayacct_init(void)
+{
+	delayacct_cache = kmem_cache_create("delayacct_cache",
+					sizeof(struct task_delay_info),
+					0,
+					SLAB_PANIC,
+					NULL, NULL);
+	delayacct_tsk_init(&init_task);
+}
+
+void __delayacct_tsk_init(struct task_struct *tsk)
+{
+	spin_lock_init(&tsk->delays_lock);
+	/* No need to acquire tsk->delays_lock for allocation here unless
+	   __delayacct_tsk_init called after tsk is attached to tasklist
+	*/
+	tsk->delays = kmem_cache_zalloc(delayacct_cache, SLAB_KERNEL);
+	if (tsk->delays)
+		spin_lock_init(&tsk->delays->lock);
+}
+
+void __delayacct_tsk_exit(struct task_struct *tsk)
+{
+	struct task_delay_info *delays = tsk->delays;
+	spin_lock(&tsk->delays_lock);
+	tsk->delays = NULL;
+	spin_unlock(&tsk->delays_lock);
+	kmem_cache_free(delayacct_cache, delays);
+}
+
+/*
+ * Start accounting for a delay statistic using
+ * its starting timestamp (@start)
+ */
+
+static inline void delayacct_start(struct timespec *start)
+{
+	do_posix_clock_monotonic_gettime(start);
+}
+
+/*
+ * Finish delay accounting for a statistic using
+ * its timestamps (@start, @end), accumalator (@total) and @count
+ */
+
+static void delayacct_end(struct timespec *start, struct timespec *end,
+				u64 *total, u32 *count)
+{
+	struct timespec ts;
+	s64 ns;
+
+	do_posix_clock_monotonic_gettime(end);
+	ts = timespec_sub(*end, *start);
+	ns = timespec_to_ns(&ts);
+	if (ns < 0)
+		return;
+
+	spin_lock(&current->delays->lock);
+	*total += ns;
+	(*count)++;
+	spin_unlock(&current->delays->lock);
+}
+
+void __delayacct_blkio_start(void)
+{
+	delayacct_start(&current->delays->blkio_start);
+}
+
+void __delayacct_blkio_end(void)
+{
+	if (current->delays->flags & DELAYACCT_PF_SWAPIN)
+		/* Swapin block I/O */
+		delayacct_end(&current->delays->blkio_start,
+			&current->delays->blkio_end,
+			&current->delays->swapin_delay,
+			&current->delays->swapin_count);
+	else	/* Other block I/O */
+		delayacct_end(&current->delays->blkio_start,
+			&current->delays->blkio_end,
+			&current->delays->blkio_delay,
+			&current->delays->blkio_count);
+}
+
+int __delayacct_add_tsk(struct taskstats *d, struct task_struct *tsk)
+{
+	s64 tmp;
+	struct timespec ts;
+	unsigned long t1,t2,t3;
+
+	spin_lock(&tsk->delays_lock);
+
+	/* Though tsk->delays accessed later, early exit avoids
+	 * unnecessary returning of other data
+	 */
+	if (!tsk->delays)
+		goto done;
+
+	tmp = (s64)d->cpu_run_real_total;
+	cputime_to_timespec(tsk->utime + tsk->stime, &ts);
+	tmp += timespec_to_ns(&ts);
+	d->cpu_run_real_total = (tmp < (s64)d->cpu_run_real_total) ? 0 : tmp;
+
+	/*
+	 * No locking available for sched_info (and too expensive to add one)
+	 * Mitigate by taking snapshot of values
+	 */
+	t1 = tsk->sched_info.pcnt;
+	t2 = tsk->sched_info.run_delay;
+	t3 = tsk->sched_info.cpu_time;
+
+	d->cpu_count += t1;
+
+	jiffies_to_timespec(t2, &ts);
+	tmp = (s64)d->cpu_delay_total + timespec_to_ns(&ts);
+	d->cpu_delay_total = (tmp < (s64)d->cpu_delay_total) ? 0 : tmp;
+
+	tmp = (s64)d->cpu_run_virtual_total + (s64)jiffies_to_usecs(t3) * 1000;
+	d->cpu_run_virtual_total =
+		(tmp < (s64)d->cpu_run_virtual_total) ?	0 : tmp;
+
+	/* zero XXX_total, non-zero XXX_count implies XXX stat overflowed */
+
+	spin_lock(&tsk->delays->lock);
+	tmp = d->blkio_delay_total + tsk->delays->blkio_delay;
+	d->blkio_delay_total = (tmp < d->blkio_delay_total) ? 0 : tmp;
+	tmp = d->swapin_delay_total + tsk->delays->swapin_delay;
+	d->swapin_delay_total = (tmp < d->swapin_delay_total) ? 0 : tmp;
+	d->blkio_count += tsk->delays->blkio_count;
+	d->swapin_count += tsk->delays->swapin_count;
+	spin_unlock(&tsk->delays->lock);
+
+done:
+	spin_unlock(&tsk->delays_lock);
+	return 0;
+}
+
+__u64 __delayacct_blkio_ticks(struct task_struct *tsk)
+{
+	__u64 ret;
+
+	spin_lock(&tsk->delays->lock);
+	ret = nsec_to_clock_t(tsk->delays->blkio_delay +
+				tsk->delays->swapin_delay);
+	spin_unlock(&tsk->delays->lock);
+	return ret;
+}
+
diff --git a/kernel/exit.c b/kernel/exit.c
index 6664c08..dba194a 100644
--- a/kernel/exit.c
+++ b/kernel/exit.c
@@ -25,6 +25,8 @@
 #include <linux/mount.h>
 #include <linux/proc_fs.h>
 #include <linux/mempolicy.h>
+#include <linux/taskstats_kern.h>
+#include <linux/delayacct.h>
 #include <linux/cpuset.h>
 #include <linux/syscalls.h>
 #include <linux/signal.h>
@@ -843,7 +845,9 @@
 fastcall NORET_TYPE void do_exit(long code)
 {
 	struct task_struct *tsk = current;
+	struct taskstats *tidstats;
 	int group_dead;
+	unsigned int mycpu;
 
 	profile_task_exit(tsk);
 
@@ -881,6 +885,8 @@
 				current->comm, current->pid,
 				preempt_count());
 
+	taskstats_exit_alloc(&tidstats, &mycpu);
+
 	acct_update_integrals(tsk);
 	if (tsk->mm) {
 		update_hiwater_rss(tsk->mm);
@@ -900,6 +906,10 @@
 #endif
 	if (unlikely(tsk->audit_context))
 		audit_free(tsk);
+	taskstats_exit_send(tsk, tidstats, group_dead, mycpu);
+	taskstats_exit_free(tidstats);
+	delayacct_tsk_exit(tsk);
+
 	exit_mm(tsk);
 
 	if (group_dead)
diff --git a/kernel/fork.c b/kernel/fork.c
index 926e5a6..1b0f7b1 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -43,6 +43,8 @@
 #include <linux/rmap.h>
 #include <linux/acct.h>
 #include <linux/cn_proc.h>
+#include <linux/delayacct.h>
+#include <linux/taskstats_kern.h>
 
 #include <asm/pgtable.h>
 #include <asm/pgalloc.h>
@@ -818,6 +820,7 @@
 	if (clone_flags & CLONE_THREAD) {
 		atomic_inc(&current->signal->count);
 		atomic_inc(&current->signal->live);
+		taskstats_tgid_alloc(current->signal);
 		return 0;
 	}
 	sig = kmem_cache_alloc(signal_cachep, GFP_KERNEL);
@@ -862,6 +865,7 @@
 	INIT_LIST_HEAD(&sig->cpu_timers[0]);
 	INIT_LIST_HEAD(&sig->cpu_timers[1]);
 	INIT_LIST_HEAD(&sig->cpu_timers[2]);
+	taskstats_tgid_init(sig);
 
 	task_lock(current->group_leader);
 	memcpy(sig->rlim, current->signal->rlim, sizeof sig->rlim);
@@ -883,6 +887,7 @@
 void __cleanup_signal(struct signal_struct *sig)
 {
 	exit_thread_group_keys(sig);
+	taskstats_tgid_free(sig);
 	kmem_cache_free(signal_cachep, sig);
 }
 
@@ -1000,6 +1005,7 @@
 		goto bad_fork_cleanup_put_domain;
 
 	p->did_exec = 0;
+	delayacct_tsk_init(p);	/* Must remain after dup_task_struct() */
 	copy_flags(clone_flags, p);
 	p->pid = pid;
 	retval = -EFAULT;
diff --git a/kernel/kallsyms.c b/kernel/kallsyms.c
index 39277dd..ab16a5a 100644
--- a/kernel/kallsyms.c
+++ b/kernel/kallsyms.c
@@ -275,8 +275,8 @@
 static int get_ksymbol_mod(struct kallsym_iter *iter)
 {
 	iter->owner = module_get_kallsym(iter->pos - kallsyms_num_syms,
-					 &iter->value,
-					 &iter->type, iter->name);
+					 &iter->value, &iter->type,
+					 iter->name, sizeof(iter->name));
 	if (iter->owner == NULL)
 		return 0;
 
diff --git a/kernel/kthread.c b/kernel/kthread.c
index 24be714..4f9c60e 100644
--- a/kernel/kthread.c
+++ b/kernel/kthread.c
@@ -216,23 +216,6 @@
  */
 int kthread_stop(struct task_struct *k)
 {
-	return kthread_stop_sem(k, NULL);
-}
-EXPORT_SYMBOL(kthread_stop);
-
-/**
- * kthread_stop_sem - stop a thread created by kthread_create().
- * @k: thread created by kthread_create().
- * @s: semaphore that @k waits on while idle.
- *
- * Does essentially the same thing as kthread_stop() above, but wakes
- * @k by calling up(@s).
- *
- * Returns the result of threadfn(), or %-EINTR if wake_up_process()
- * was never called.
- */
-int kthread_stop_sem(struct task_struct *k, struct semaphore *s)
-{
 	int ret;
 
 	mutex_lock(&kthread_stop_lock);
@@ -246,10 +229,7 @@
 
 	/* Now set kthread_should_stop() to true, and wake it up. */
 	kthread_stop_info.k = k;
-	if (s)
-		up(s);
-	else
-		wake_up_process(k);
+	wake_up_process(k);
 	put_task_struct(k);
 
 	/* Once it dies, reset stop ptr, gather result and we're done. */
@@ -260,7 +240,7 @@
 
 	return ret;
 }
-EXPORT_SYMBOL(kthread_stop_sem);
+EXPORT_SYMBOL(kthread_stop);
 
 static __init int helper_init(void)
 {
diff --git a/kernel/module.c b/kernel/module.c
index 35e1b1f..2a19cd4 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -2019,10 +2019,8 @@
 	return NULL;
 }
 
-struct module *module_get_kallsym(unsigned int symnum,
-				  unsigned long *value,
-				  char *type,
-				  char namebuf[128])
+struct module *module_get_kallsym(unsigned int symnum, unsigned long *value,
+				char *type, char *name, size_t namelen)
 {
 	struct module *mod;
 
@@ -2031,9 +2029,8 @@
 		if (symnum < mod->num_symtab) {
 			*value = mod->symtab[symnum].st_value;
 			*type = mod->symtab[symnum].st_info;
-			strncpy(namebuf,
-				mod->strtab + mod->symtab[symnum].st_name,
-				127);
+			strlcpy(name, mod->strtab + mod->symtab[symnum].st_name,
+				namelen);
 			mutex_unlock(&module_mutex);
 			return mod;
 		}
diff --git a/kernel/rtmutex-tester.c b/kernel/rtmutex-tester.c
index 494dac8..948bd8f 100644
--- a/kernel/rtmutex-tester.c
+++ b/kernel/rtmutex-tester.c
@@ -275,6 +275,7 @@
 
 		/* Wait for the next command to be executed */
 		schedule();
+		try_to_freeze();
 
 		if (signal_pending(current))
 			flush_signals(current);
diff --git a/kernel/sched.c b/kernel/sched.c
index d714611..b44b9a4 100644
--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -51,6 +51,7 @@
 #include <linux/times.h>
 #include <linux/acct.h>
 #include <linux/kprobes.h>
+#include <linux/delayacct.h>
 #include <asm/tlb.h>
 
 #include <asm/unistd.h>
@@ -501,9 +502,36 @@
 	.release = single_release,
 };
 
+/*
+ * Expects runqueue lock to be held for atomicity of update
+ */
+static inline void
+rq_sched_info_arrive(struct rq *rq, unsigned long delta_jiffies)
+{
+	if (rq) {
+		rq->rq_sched_info.run_delay += delta_jiffies;
+		rq->rq_sched_info.pcnt++;
+	}
+}
+
+/*
+ * Expects runqueue lock to be held for atomicity of update
+ */
+static inline void
+rq_sched_info_depart(struct rq *rq, unsigned long delta_jiffies)
+{
+	if (rq)
+		rq->rq_sched_info.cpu_time += delta_jiffies;
+}
 # define schedstat_inc(rq, field)	do { (rq)->field++; } while (0)
 # define schedstat_add(rq, field, amt)	do { (rq)->field += (amt); } while (0)
 #else /* !CONFIG_SCHEDSTATS */
+static inline void
+rq_sched_info_arrive(struct rq *rq, unsigned long delta_jiffies)
+{}
+static inline void
+rq_sched_info_depart(struct rq *rq, unsigned long delta_jiffies)
+{}
 # define schedstat_inc(rq, field)	do { } while (0)
 # define schedstat_add(rq, field, amt)	do { } while (0)
 #endif
@@ -523,7 +551,7 @@
 	return rq;
 }
 
-#ifdef CONFIG_SCHEDSTATS
+#if defined(CONFIG_SCHEDSTATS) || defined(CONFIG_TASK_DELAY_ACCT)
 /*
  * Called when a process is dequeued from the active array and given
  * the cpu.  We should note that with the exception of interactive
@@ -551,21 +579,16 @@
  */
 static void sched_info_arrive(struct task_struct *t)
 {
-	unsigned long now = jiffies, diff = 0;
-	struct rq *rq = task_rq(t);
+	unsigned long now = jiffies, delta_jiffies = 0;
 
 	if (t->sched_info.last_queued)
-		diff = now - t->sched_info.last_queued;
+		delta_jiffies = now - t->sched_info.last_queued;
 	sched_info_dequeued(t);
-	t->sched_info.run_delay += diff;
+	t->sched_info.run_delay += delta_jiffies;
 	t->sched_info.last_arrival = now;
 	t->sched_info.pcnt++;
 
-	if (!rq)
-		return;
-
-	rq->rq_sched_info.run_delay += diff;
-	rq->rq_sched_info.pcnt++;
+	rq_sched_info_arrive(task_rq(t), delta_jiffies);
 }
 
 /*
@@ -585,8 +608,9 @@
  */
 static inline void sched_info_queued(struct task_struct *t)
 {
-	if (!t->sched_info.last_queued)
-		t->sched_info.last_queued = jiffies;
+	if (unlikely(sched_info_on()))
+		if (!t->sched_info.last_queued)
+			t->sched_info.last_queued = jiffies;
 }
 
 /*
@@ -595,13 +619,10 @@
  */
 static inline void sched_info_depart(struct task_struct *t)
 {
-	struct rq *rq = task_rq(t);
-	unsigned long diff = jiffies - t->sched_info.last_arrival;
+	unsigned long delta_jiffies = jiffies - t->sched_info.last_arrival;
 
-	t->sched_info.cpu_time += diff;
-
-	if (rq)
-		rq->rq_sched_info.cpu_time += diff;
+	t->sched_info.cpu_time += delta_jiffies;
+	rq_sched_info_depart(task_rq(t), delta_jiffies);
 }
 
 /*
@@ -610,7 +631,7 @@
  * the idle task.)  We are only called when prev != next.
  */
 static inline void
-sched_info_switch(struct task_struct *prev, struct task_struct *next)
+__sched_info_switch(struct task_struct *prev, struct task_struct *next)
 {
 	struct rq *rq = task_rq(prev);
 
@@ -625,10 +646,16 @@
 	if (next != rq->idle)
 		sched_info_arrive(next);
 }
+static inline void
+sched_info_switch(struct task_struct *prev, struct task_struct *next)
+{
+	if (unlikely(sched_info_on()))
+		__sched_info_switch(prev, next);
+}
 #else
 #define sched_info_queued(t)		do { } while (0)
 #define sched_info_switch(t, next)	do { } while (0)
-#endif /* CONFIG_SCHEDSTATS */
+#endif /* CONFIG_SCHEDSTATS || CONFIG_TASK_DELAY_ACCT */
 
 /*
  * Adding/removing a task to/from a priority array:
@@ -1530,8 +1557,9 @@
 
 	INIT_LIST_HEAD(&p->run_list);
 	p->array = NULL;
-#ifdef CONFIG_SCHEDSTATS
-	memset(&p->sched_info, 0, sizeof(p->sched_info));
+#if defined(CONFIG_SCHEDSTATS) || defined(CONFIG_TASK_DELAY_ACCT)
+	if (unlikely(sched_info_on()))
+		memset(&p->sched_info, 0, sizeof(p->sched_info));
 #endif
 #if defined(CONFIG_SMP) && defined(__ARCH_WANT_UNLOCKED_CTXSW)
 	p->oncpu = 0;
@@ -1788,7 +1816,15 @@
 		WARN_ON(rq->prev_mm);
 		rq->prev_mm = oldmm;
 	}
+	/*
+	 * Since the runqueue lock will be released by the next
+	 * task (which is an invalid locking op but in the case
+	 * of the scheduler it's an obvious special-case), so we
+	 * do an early lockdep release here:
+	 */
+#ifndef __ARCH_WANT_UNLOCKED_CTXSW
 	spin_release(&rq->lock.dep_map, 1, _THIS_IP_);
+#endif
 
 	/* Here we just switch the register state and the stack. */
 	switch_to(prev, next, prev);
@@ -4526,9 +4562,11 @@
 {
 	struct rq *rq = &__raw_get_cpu_var(runqueues);
 
+	delayacct_blkio_start();
 	atomic_inc(&rq->nr_iowait);
 	schedule();
 	atomic_dec(&rq->nr_iowait);
+	delayacct_blkio_end();
 }
 EXPORT_SYMBOL(io_schedule);
 
@@ -4537,9 +4575,11 @@
 	struct rq *rq = &__raw_get_cpu_var(runqueues);
 	long ret;
 
+	delayacct_blkio_start();
 	atomic_inc(&rq->nr_iowait);
 	ret = schedule_timeout(timeout);
 	atomic_dec(&rq->nr_iowait);
+	delayacct_blkio_end();
 	return ret;
 }
 
diff --git a/kernel/softirq.c b/kernel/softirq.c
index fd12f25..0f08a84 100644
--- a/kernel/softirq.c
+++ b/kernel/softirq.c
@@ -311,8 +311,6 @@
 	softirq_vec[nr].action = action;
 }
 
-EXPORT_UNUSED_SYMBOL(open_softirq);  /*  June 2006  */
-
 /* Tasklets */
 struct tasklet_head
 {
diff --git a/kernel/taskstats.c b/kernel/taskstats.c
new file mode 100644
index 0000000..f45179c
--- /dev/null
+++ b/kernel/taskstats.c
@@ -0,0 +1,568 @@
+/*
+ * taskstats.c - Export per-task statistics to userland
+ *
+ * Copyright (C) Shailabh Nagar, IBM Corp. 2006
+ *           (C) Balbir Singh,   IBM Corp. 2006
+ *
+ * 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/kernel.h>
+#include <linux/taskstats_kern.h>
+#include <linux/delayacct.h>
+#include <linux/cpumask.h>
+#include <linux/percpu.h>
+#include <net/genetlink.h>
+#include <asm/atomic.h>
+
+/*
+ * Maximum length of a cpumask that can be specified in
+ * the TASKSTATS_CMD_ATTR_REGISTER/DEREGISTER_CPUMASK attribute
+ */
+#define TASKSTATS_CPUMASK_MAXLEN	(100+6*NR_CPUS)
+
+static DEFINE_PER_CPU(__u32, taskstats_seqnum) = { 0 };
+static int family_registered;
+kmem_cache_t *taskstats_cache;
+
+static struct genl_family family = {
+	.id		= GENL_ID_GENERATE,
+	.name		= TASKSTATS_GENL_NAME,
+	.version	= TASKSTATS_GENL_VERSION,
+	.maxattr	= TASKSTATS_CMD_ATTR_MAX,
+};
+
+static struct nla_policy taskstats_cmd_get_policy[TASKSTATS_CMD_ATTR_MAX+1]
+__read_mostly = {
+	[TASKSTATS_CMD_ATTR_PID]  = { .type = NLA_U32 },
+	[TASKSTATS_CMD_ATTR_TGID] = { .type = NLA_U32 },
+	[TASKSTATS_CMD_ATTR_REGISTER_CPUMASK] = { .type = NLA_STRING },
+	[TASKSTATS_CMD_ATTR_DEREGISTER_CPUMASK] = { .type = NLA_STRING },};
+
+struct listener {
+	struct list_head list;
+	pid_t pid;
+	char valid;
+};
+
+struct listener_list {
+	struct rw_semaphore sem;
+	struct list_head list;
+};
+static DEFINE_PER_CPU(struct listener_list, listener_array);
+
+enum actions {
+	REGISTER,
+	DEREGISTER,
+	CPU_DONT_CARE
+};
+
+static int prepare_reply(struct genl_info *info, u8 cmd, struct sk_buff **skbp,
+			void **replyp, size_t size)
+{
+	struct sk_buff *skb;
+	void *reply;
+
+	/*
+	 * If new attributes are added, please revisit this allocation
+	 */
+	skb = nlmsg_new(size);
+	if (!skb)
+		return -ENOMEM;
+
+	if (!info) {
+		int seq = get_cpu_var(taskstats_seqnum)++;
+		put_cpu_var(taskstats_seqnum);
+
+		reply = genlmsg_put(skb, 0, seq,
+				family.id, 0, 0,
+				cmd, family.version);
+	} else
+		reply = genlmsg_put(skb, info->snd_pid, info->snd_seq,
+				family.id, 0, 0,
+				cmd, family.version);
+	if (reply == NULL) {
+		nlmsg_free(skb);
+		return -EINVAL;
+	}
+
+	*skbp = skb;
+	*replyp = reply;
+	return 0;
+}
+
+/*
+ * Send taskstats data in @skb to listener with nl_pid @pid
+ */
+static int send_reply(struct sk_buff *skb, pid_t pid)
+{
+	struct genlmsghdr *genlhdr = nlmsg_data((struct nlmsghdr *)skb->data);
+	void *reply = genlmsg_data(genlhdr);
+	int rc;
+
+	rc = genlmsg_end(skb, reply);
+	if (rc < 0) {
+		nlmsg_free(skb);
+		return rc;
+	}
+
+	return genlmsg_unicast(skb, pid);
+}
+
+/*
+ * Send taskstats data in @skb to listeners registered for @cpu's exit data
+ */
+static int send_cpu_listeners(struct sk_buff *skb, unsigned int cpu)
+{
+	struct genlmsghdr *genlhdr = nlmsg_data((struct nlmsghdr *)skb->data);
+	struct listener_list *listeners;
+	struct listener *s, *tmp;
+	struct sk_buff *skb_next, *skb_cur = skb;
+	void *reply = genlmsg_data(genlhdr);
+	int rc, ret, delcount = 0;
+
+	rc = genlmsg_end(skb, reply);
+	if (rc < 0) {
+		nlmsg_free(skb);
+		return rc;
+	}
+
+	rc = 0;
+	listeners = &per_cpu(listener_array, cpu);
+	down_read(&listeners->sem);
+	list_for_each_entry_safe(s, tmp, &listeners->list, list) {
+		skb_next = NULL;
+		if (!list_is_last(&s->list, &listeners->list)) {
+			skb_next = skb_clone(skb_cur, GFP_KERNEL);
+			if (!skb_next) {
+				nlmsg_free(skb_cur);
+				rc = -ENOMEM;
+				break;
+			}
+		}
+		ret = genlmsg_unicast(skb_cur, s->pid);
+		if (ret == -ECONNREFUSED) {
+			s->valid = 0;
+			delcount++;
+			rc = ret;
+		}
+		skb_cur = skb_next;
+	}
+	up_read(&listeners->sem);
+
+	if (!delcount)
+		return rc;
+
+	/* Delete invalidated entries */
+	down_write(&listeners->sem);
+	list_for_each_entry_safe(s, tmp, &listeners->list, list) {
+		if (!s->valid) {
+			list_del(&s->list);
+			kfree(s);
+		}
+	}
+	up_write(&listeners->sem);
+	return rc;
+}
+
+static int fill_pid(pid_t pid, struct task_struct *pidtsk,
+		struct taskstats *stats)
+{
+	int rc;
+	struct task_struct *tsk = pidtsk;
+
+	if (!pidtsk) {
+		read_lock(&tasklist_lock);
+		tsk = find_task_by_pid(pid);
+		if (!tsk) {
+			read_unlock(&tasklist_lock);
+			return -ESRCH;
+		}
+		get_task_struct(tsk);
+		read_unlock(&tasklist_lock);
+	} else
+		get_task_struct(tsk);
+
+	/*
+	 * Each accounting subsystem adds calls to its functions to
+	 * fill in relevant parts of struct taskstsats as follows
+	 *
+	 *	rc = per-task-foo(stats, tsk);
+	 *	if (rc)
+	 *		goto err;
+	 */
+
+	rc = delayacct_add_tsk(stats, tsk);
+	stats->version = TASKSTATS_VERSION;
+
+	/* Define err: label here if needed */
+	put_task_struct(tsk);
+	return rc;
+
+}
+
+static int fill_tgid(pid_t tgid, struct task_struct *tgidtsk,
+		struct taskstats *stats)
+{
+	struct task_struct *tsk, *first;
+	unsigned long flags;
+
+	/*
+	 * Add additional stats from live tasks except zombie thread group
+	 * leaders who are already counted with the dead tasks
+	 */
+	first = tgidtsk;
+	if (!first) {
+		read_lock(&tasklist_lock);
+		first = find_task_by_pid(tgid);
+		if (!first) {
+			read_unlock(&tasklist_lock);
+			return -ESRCH;
+		}
+		get_task_struct(first);
+		read_unlock(&tasklist_lock);
+	} else
+		get_task_struct(first);
+
+	/* Start with stats from dead tasks */
+	spin_lock_irqsave(&first->signal->stats_lock, flags);
+	if (first->signal->stats)
+		memcpy(stats, first->signal->stats, sizeof(*stats));
+	spin_unlock_irqrestore(&first->signal->stats_lock, flags);
+
+	tsk = first;
+	read_lock(&tasklist_lock);
+	do {
+		if (tsk->exit_state == EXIT_ZOMBIE && thread_group_leader(tsk))
+			continue;
+		/*
+		 * Accounting subsystem can call its functions here to
+		 * fill in relevant parts of struct taskstsats as follows
+		 *
+		 *	per-task-foo(stats, tsk);
+		 */
+		delayacct_add_tsk(stats, tsk);
+
+	} while_each_thread(first, tsk);
+	read_unlock(&tasklist_lock);
+	stats->version = TASKSTATS_VERSION;
+
+	/*
+	 * Accounting subsytems can also add calls here to modify
+	 * fields of taskstats.
+	 */
+
+	return 0;
+}
+
+
+static void fill_tgid_exit(struct task_struct *tsk)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&tsk->signal->stats_lock, flags);
+	if (!tsk->signal->stats)
+		goto ret;
+
+	/*
+	 * Each accounting subsystem calls its functions here to
+	 * accumalate its per-task stats for tsk, into the per-tgid structure
+	 *
+	 *	per-task-foo(tsk->signal->stats, tsk);
+	 */
+	delayacct_add_tsk(tsk->signal->stats, tsk);
+ret:
+	spin_unlock_irqrestore(&tsk->signal->stats_lock, flags);
+	return;
+}
+
+static int add_del_listener(pid_t pid, cpumask_t *maskp, int isadd)
+{
+	struct listener_list *listeners;
+	struct listener *s, *tmp;
+	unsigned int cpu;
+	cpumask_t mask = *maskp;
+
+	if (!cpus_subset(mask, cpu_possible_map))
+		return -EINVAL;
+
+	if (isadd == REGISTER) {
+		for_each_cpu_mask(cpu, mask) {
+			s = kmalloc_node(sizeof(struct listener), GFP_KERNEL,
+					 cpu_to_node(cpu));
+			if (!s)
+				goto cleanup;
+			s->pid = pid;
+			INIT_LIST_HEAD(&s->list);
+			s->valid = 1;
+
+			listeners = &per_cpu(listener_array, cpu);
+			down_write(&listeners->sem);
+			list_add(&s->list, &listeners->list);
+			up_write(&listeners->sem);
+		}
+		return 0;
+	}
+
+	/* Deregister or cleanup */
+cleanup:
+	for_each_cpu_mask(cpu, mask) {
+		listeners = &per_cpu(listener_array, cpu);
+		down_write(&listeners->sem);
+		list_for_each_entry_safe(s, tmp, &listeners->list, list) {
+			if (s->pid == pid) {
+				list_del(&s->list);
+				kfree(s);
+				break;
+			}
+		}
+		up_write(&listeners->sem);
+	}
+	return 0;
+}
+
+static int parse(struct nlattr *na, cpumask_t *mask)
+{
+	char *data;
+	int len;
+	int ret;
+
+	if (na == NULL)
+		return 1;
+	len = nla_len(na);
+	if (len > TASKSTATS_CPUMASK_MAXLEN)
+		return -E2BIG;
+	if (len < 1)
+		return -EINVAL;
+	data = kmalloc(len, GFP_KERNEL);
+	if (!data)
+		return -ENOMEM;
+	nla_strlcpy(data, na, len);
+	ret = cpulist_parse(data, *mask);
+	kfree(data);
+	return ret;
+}
+
+static int taskstats_user_cmd(struct sk_buff *skb, struct genl_info *info)
+{
+	int rc = 0;
+	struct sk_buff *rep_skb;
+	struct taskstats stats;
+	void *reply;
+	size_t size;
+	struct nlattr *na;
+	cpumask_t mask;
+
+	rc = parse(info->attrs[TASKSTATS_CMD_ATTR_REGISTER_CPUMASK], &mask);
+	if (rc < 0)
+		return rc;
+	if (rc == 0)
+		return add_del_listener(info->snd_pid, &mask, REGISTER);
+
+	rc = parse(info->attrs[TASKSTATS_CMD_ATTR_DEREGISTER_CPUMASK], &mask);
+	if (rc < 0)
+		return rc;
+	if (rc == 0)
+		return add_del_listener(info->snd_pid, &mask, DEREGISTER);
+
+	/*
+	 * Size includes space for nested attributes
+	 */
+	size = nla_total_size(sizeof(u32)) +
+		nla_total_size(sizeof(struct taskstats)) + nla_total_size(0);
+
+	memset(&stats, 0, sizeof(stats));
+	rc = prepare_reply(info, TASKSTATS_CMD_NEW, &rep_skb, &reply, size);
+	if (rc < 0)
+		return rc;
+
+	if (info->attrs[TASKSTATS_CMD_ATTR_PID]) {
+		u32 pid = nla_get_u32(info->attrs[TASKSTATS_CMD_ATTR_PID]);
+		rc = fill_pid(pid, NULL, &stats);
+		if (rc < 0)
+			goto err;
+
+		na = nla_nest_start(rep_skb, TASKSTATS_TYPE_AGGR_PID);
+		NLA_PUT_U32(rep_skb, TASKSTATS_TYPE_PID, pid);
+		NLA_PUT_TYPE(rep_skb, struct taskstats, TASKSTATS_TYPE_STATS,
+				stats);
+	} else if (info->attrs[TASKSTATS_CMD_ATTR_TGID]) {
+		u32 tgid = nla_get_u32(info->attrs[TASKSTATS_CMD_ATTR_TGID]);
+		rc = fill_tgid(tgid, NULL, &stats);
+		if (rc < 0)
+			goto err;
+
+		na = nla_nest_start(rep_skb, TASKSTATS_TYPE_AGGR_TGID);
+		NLA_PUT_U32(rep_skb, TASKSTATS_TYPE_TGID, tgid);
+		NLA_PUT_TYPE(rep_skb, struct taskstats, TASKSTATS_TYPE_STATS,
+				stats);
+	} else {
+		rc = -EINVAL;
+		goto err;
+	}
+
+	nla_nest_end(rep_skb, na);
+
+	return send_reply(rep_skb, info->snd_pid);
+
+nla_put_failure:
+	return genlmsg_cancel(rep_skb, reply);
+err:
+	nlmsg_free(rep_skb);
+	return rc;
+}
+
+void taskstats_exit_alloc(struct taskstats **ptidstats, unsigned int *mycpu)
+{
+	struct listener_list *listeners;
+	struct taskstats *tmp;
+	/*
+	 * This is the cpu on which the task is exiting currently and will
+	 * be the one for which the exit event is sent, even if the cpu
+	 * on which this function is running changes later.
+	 */
+	*mycpu = raw_smp_processor_id();
+
+	*ptidstats = NULL;
+	tmp = kmem_cache_zalloc(taskstats_cache, SLAB_KERNEL);
+	if (!tmp)
+		return;
+
+	listeners = &per_cpu(listener_array, *mycpu);
+	down_read(&listeners->sem);
+	if (!list_empty(&listeners->list)) {
+		*ptidstats = tmp;
+		tmp = NULL;
+	}
+	up_read(&listeners->sem);
+	kfree(tmp);
+}
+
+/* Send pid data out on exit */
+void taskstats_exit_send(struct task_struct *tsk, struct taskstats *tidstats,
+			int group_dead, unsigned int mycpu)
+{
+	int rc;
+	struct sk_buff *rep_skb;
+	void *reply;
+	size_t size;
+	int is_thread_group;
+	struct nlattr *na;
+	unsigned long flags;
+
+	if (!family_registered || !tidstats)
+		return;
+
+	spin_lock_irqsave(&tsk->signal->stats_lock, flags);
+	is_thread_group = tsk->signal->stats ? 1 : 0;
+	spin_unlock_irqrestore(&tsk->signal->stats_lock, flags);
+
+	rc = 0;
+	/*
+	 * Size includes space for nested attributes
+	 */
+	size = nla_total_size(sizeof(u32)) +
+		nla_total_size(sizeof(struct taskstats)) + nla_total_size(0);
+
+	if (is_thread_group)
+		size = 2 * size;	/* PID + STATS + TGID + STATS */
+
+	rc = prepare_reply(NULL, TASKSTATS_CMD_NEW, &rep_skb, &reply, size);
+	if (rc < 0)
+		goto ret;
+
+	rc = fill_pid(tsk->pid, tsk, tidstats);
+	if (rc < 0)
+		goto err_skb;
+
+	na = nla_nest_start(rep_skb, TASKSTATS_TYPE_AGGR_PID);
+	NLA_PUT_U32(rep_skb, TASKSTATS_TYPE_PID, (u32)tsk->pid);
+	NLA_PUT_TYPE(rep_skb, struct taskstats, TASKSTATS_TYPE_STATS,
+			*tidstats);
+	nla_nest_end(rep_skb, na);
+
+	if (!is_thread_group)
+		goto send;
+
+	/*
+	 * tsk has/had a thread group so fill the tsk->signal->stats structure
+	 * Doesn't matter if tsk is the leader or the last group member leaving
+	 */
+
+	fill_tgid_exit(tsk);
+	if (!group_dead)
+		goto send;
+
+	na = nla_nest_start(rep_skb, TASKSTATS_TYPE_AGGR_TGID);
+	NLA_PUT_U32(rep_skb, TASKSTATS_TYPE_TGID, (u32)tsk->tgid);
+	/* No locking needed for tsk->signal->stats since group is dead */
+	NLA_PUT_TYPE(rep_skb, struct taskstats, TASKSTATS_TYPE_STATS,
+			*tsk->signal->stats);
+	nla_nest_end(rep_skb, na);
+
+send:
+	send_cpu_listeners(rep_skb, mycpu);
+	return;
+
+nla_put_failure:
+	genlmsg_cancel(rep_skb, reply);
+	goto ret;
+err_skb:
+	nlmsg_free(rep_skb);
+ret:
+	return;
+}
+
+static struct genl_ops taskstats_ops = {
+	.cmd		= TASKSTATS_CMD_GET,
+	.doit		= taskstats_user_cmd,
+	.policy		= taskstats_cmd_get_policy,
+};
+
+/* Needed early in initialization */
+void __init taskstats_init_early(void)
+{
+	unsigned int i;
+
+	taskstats_cache = kmem_cache_create("taskstats_cache",
+						sizeof(struct taskstats),
+						0, SLAB_PANIC, NULL, NULL);
+	for_each_possible_cpu(i) {
+		INIT_LIST_HEAD(&(per_cpu(listener_array, i).list));
+		init_rwsem(&(per_cpu(listener_array, i).sem));
+	}
+}
+
+static int __init taskstats_init(void)
+{
+	int rc;
+
+	rc = genl_register_family(&family);
+	if (rc)
+		return rc;
+
+	rc = genl_register_ops(&family, &taskstats_ops);
+	if (rc < 0)
+		goto err;
+
+	family_registered = 1;
+	return 0;
+err:
+	genl_unregister_family(&family);
+	return rc;
+}
+
+/*
+ * late initcall ensures initialization of statistics collection
+ * mechanisms precedes initialization of the taskstats interface
+ */
+late_initcall(taskstats_init);
diff --git a/kernel/timer.c b/kernel/timer.c
index 2a87430..05809c2 100644
--- a/kernel/timer.c
+++ b/kernel/timer.c
@@ -374,6 +374,7 @@
 		int ret = try_to_del_timer_sync(timer);
 		if (ret >= 0)
 			return ret;
+		cpu_relax();
 	}
 }
 
@@ -968,6 +969,7 @@
 }
 
 
+static int timekeeping_suspended;
 /*
  * timekeeping_resume - Resumes the generic timekeeping subsystem.
  * @dev:	unused
@@ -983,6 +985,18 @@
 	write_seqlock_irqsave(&xtime_lock, flags);
 	/* restart the last cycle value */
 	clock->cycle_last = clocksource_read(clock);
+	clock->error = 0;
+	timekeeping_suspended = 0;
+	write_sequnlock_irqrestore(&xtime_lock, flags);
+	return 0;
+}
+
+static int timekeeping_suspend(struct sys_device *dev, pm_message_t state)
+{
+	unsigned long flags;
+
+	write_seqlock_irqsave(&xtime_lock, flags);
+	timekeeping_suspended = 1;
 	write_sequnlock_irqrestore(&xtime_lock, flags);
 	return 0;
 }
@@ -990,6 +1004,7 @@
 /* sysfs resume/suspend bits for timekeeping */
 static struct sysdev_class timekeeping_sysclass = {
 	.resume		= timekeeping_resume,
+	.suspend	= timekeeping_suspend,
 	set_kset_name("timekeeping"),
 };
 
@@ -1100,13 +1115,16 @@
 {
 	cycle_t offset;
 
-	clock->xtime_nsec += (s64)xtime.tv_nsec << clock->shift;
+	/* Make sure we're fully resumed: */
+	if (unlikely(timekeeping_suspended))
+		return;
 
 #ifdef CONFIG_GENERIC_TIME
 	offset = (clocksource_read(clock) - clock->cycle_last) & clock->mask;
 #else
 	offset = clock->cycle_interval;
 #endif
+	clock->xtime_nsec += (s64)xtime.tv_nsec << clock->shift;
 
 	/* normally this loop will run just once, however in the
 	 * case of lost or late ticks, it will accumulate correctly.
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index e5889b1..554ee68 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -158,7 +158,7 @@
 
 config DEBUG_LOCK_ALLOC
 	bool "Lock debugging: detect incorrect freeing of live locks"
-	depends on TRACE_IRQFLAGS_SUPPORT && STACKTRACE_SUPPORT && LOCKDEP_SUPPORT
+	depends on DEBUG_KERNEL && TRACE_IRQFLAGS_SUPPORT && STACKTRACE_SUPPORT && LOCKDEP_SUPPORT
 	select DEBUG_SPINLOCK
 	select DEBUG_MUTEXES
 	select DEBUG_RWSEMS
@@ -173,7 +173,7 @@
 
 config PROVE_LOCKING
 	bool "Lock debugging: prove locking correctness"
-	depends on TRACE_IRQFLAGS_SUPPORT && STACKTRACE_SUPPORT && LOCKDEP_SUPPORT
+	depends on DEBUG_KERNEL && TRACE_IRQFLAGS_SUPPORT && STACKTRACE_SUPPORT && LOCKDEP_SUPPORT
 	select LOCKDEP
 	select DEBUG_SPINLOCK
 	select DEBUG_MUTEXES
@@ -216,7 +216,7 @@
 
 config LOCKDEP
 	bool
-	depends on TRACE_IRQFLAGS_SUPPORT && STACKTRACE_SUPPORT && LOCKDEP_SUPPORT
+	depends on DEBUG_KERNEL && TRACE_IRQFLAGS_SUPPORT && STACKTRACE_SUPPORT && LOCKDEP_SUPPORT
 	select STACKTRACE
 	select FRAME_POINTER
 	select KALLSYMS
@@ -224,13 +224,14 @@
 
 config DEBUG_LOCKDEP
 	bool "Lock dependency engine debugging"
-	depends on LOCKDEP
+	depends on DEBUG_KERNEL && LOCKDEP
 	help
 	  If you say Y here, the lock dependency engine will do
 	  additional runtime checks to debug itself, at the price
 	  of more runtime overhead.
 
 config TRACE_IRQFLAGS
+	depends on DEBUG_KERNEL
 	bool
 	default y
 	depends on TRACE_IRQFLAGS_SUPPORT
@@ -256,6 +257,7 @@
 
 config STACKTRACE
 	bool
+	depends on DEBUG_KERNEL
 	depends on STACKTRACE_SUPPORT
 
 config DEBUG_KOBJECT
diff --git a/lib/idr.c b/lib/idr.c
index 4d09681..16d2143 100644
--- a/lib/idr.c
+++ b/lib/idr.c
@@ -38,14 +38,15 @@
 static struct idr_layer *alloc_layer(struct idr *idp)
 {
 	struct idr_layer *p;
+	unsigned long flags;
 
-	spin_lock(&idp->lock);
+	spin_lock_irqsave(&idp->lock, flags);
 	if ((p = idp->id_free)) {
 		idp->id_free = p->ary[0];
 		idp->id_free_cnt--;
 		p->ary[0] = NULL;
 	}
-	spin_unlock(&idp->lock);
+	spin_unlock_irqrestore(&idp->lock, flags);
 	return(p);
 }
 
@@ -59,12 +60,14 @@
 
 static void free_layer(struct idr *idp, struct idr_layer *p)
 {
+	unsigned long flags;
+
 	/*
 	 * Depends on the return element being zeroed.
 	 */
-	spin_lock(&idp->lock);
+	spin_lock_irqsave(&idp->lock, flags);
 	__free_layer(idp, p);
-	spin_unlock(&idp->lock);
+	spin_unlock_irqrestore(&idp->lock, flags);
 }
 
 /**
@@ -168,6 +171,7 @@
 {
 	struct idr_layer *p, *new;
 	int layers, v, id;
+	unsigned long flags;
 
 	id = starting_id;
 build_up:
@@ -191,14 +195,14 @@
 			 * The allocation failed.  If we built part of
 			 * the structure tear it down.
 			 */
-			spin_lock(&idp->lock);
+			spin_lock_irqsave(&idp->lock, flags);
 			for (new = p; p && p != idp->top; new = p) {
 				p = p->ary[0];
 				new->ary[0] = NULL;
 				new->bitmap = new->count = 0;
 				__free_layer(idp, new);
 			}
-			spin_unlock(&idp->lock);
+			spin_unlock_irqrestore(&idp->lock, flags);
 			return -1;
 		}
 		new->ary[0] = p;
diff --git a/mm/memory.c b/mm/memory.c
index dc0d82c..109e986 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -47,6 +47,7 @@
 #include <linux/pagemap.h>
 #include <linux/rmap.h>
 #include <linux/module.h>
+#include <linux/delayacct.h>
 #include <linux/init.h>
 
 #include <asm/pgalloc.h>
@@ -1549,9 +1550,9 @@
 		flush_cache_page(vma, address, pte_pfn(orig_pte));
 		entry = mk_pte(new_page, vma->vm_page_prot);
 		entry = maybe_mkwrite(pte_mkdirty(entry), vma);
+		lazy_mmu_prot_update(entry);
 		ptep_establish(vma, address, page_table, entry);
 		update_mmu_cache(vma, address, entry);
-		lazy_mmu_prot_update(entry);
 		lru_cache_add_active(new_page);
 		page_add_new_anon_rmap(new_page, vma, address);
 
@@ -1934,6 +1935,7 @@
 		migration_entry_wait(mm, pmd, address);
 		goto out;
 	}
+	delayacct_set_flag(DELAYACCT_PF_SWAPIN);
 	page = lookup_swap_cache(entry);
 	if (!page) {
  		swapin_readahead(entry, address, vma);
@@ -1946,6 +1948,7 @@
 			page_table = pte_offset_map_lock(mm, pmd, address, &ptl);
 			if (likely(pte_same(*page_table, orig_pte)))
 				ret = VM_FAULT_OOM;
+			delayacct_clear_flag(DELAYACCT_PF_SWAPIN);
 			goto unlock;
 		}
 
@@ -1955,6 +1958,7 @@
 		grab_swap_token();
 	}
 
+	delayacct_clear_flag(DELAYACCT_PF_SWAPIN);
 	mark_page_accessed(page);
 	lock_page(page);
 
diff --git a/mm/nommu.c b/mm/nommu.c
index 5151c44..c576df7 100644
--- a/mm/nommu.c
+++ b/mm/nommu.c
@@ -1070,6 +1070,7 @@
 	vma->vm_start = vma->vm_pgoff << PAGE_SHIFT;
 	return 0;
 }
+EXPORT_SYMBOL(remap_pfn_range);
 
 void swap_unplug_io_fn(struct backing_dev_info *bdi, struct page *page)
 {
@@ -1090,6 +1091,7 @@
 			 int even_cows)
 {
 }
+EXPORT_SYMBOL(unmap_mapping_range);
 
 /*
  * Check that a process has enough memory to allocate a new virtual
diff --git a/mm/vmalloc.c b/mm/vmalloc.c
index 7b45079..266162d 100644
--- a/mm/vmalloc.c
+++ b/mm/vmalloc.c
@@ -340,7 +340,7 @@
 			__free_page(area->pages[i]);
 		}
 
-		if (area->nr_pages > PAGE_SIZE/sizeof(struct page *))
+		if (area->flags & VM_VPAGES)
 			vfree(area->pages);
 		else
 			kfree(area->pages);
@@ -427,9 +427,10 @@
 
 	area->nr_pages = nr_pages;
 	/* Please note that the recursion is strictly bounded. */
-	if (array_size > PAGE_SIZE)
+	if (array_size > PAGE_SIZE) {
 		pages = __vmalloc_node(array_size, gfp_mask, PAGE_KERNEL, node);
-	else
+		area->flags |= VM_VPAGES;
+	} else
 		pages = kmalloc_node(array_size, (gfp_mask & ~__GFP_HIGHMEM), node);
 	area->pages = pages;
 	if (!area->pages) {
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index 44f6a18..476aa39 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -257,11 +257,11 @@
 }
 
 
-static void skb_drop_fraglist(struct sk_buff *skb)
+static void skb_drop_list(struct sk_buff **listp)
 {
-	struct sk_buff *list = skb_shinfo(skb)->frag_list;
+	struct sk_buff *list = *listp;
 
-	skb_shinfo(skb)->frag_list = NULL;
+	*listp = NULL;
 
 	do {
 		struct sk_buff *this = list;
@@ -270,6 +270,11 @@
 	} while (list);
 }
 
+static inline void skb_drop_fraglist(struct sk_buff *skb)
+{
+	skb_drop_list(&skb_shinfo(skb)->frag_list);
+}
+
 static void skb_clone_fraglist(struct sk_buff *skb)
 {
 	struct sk_buff *list;
@@ -830,41 +835,75 @@
 
 int ___pskb_trim(struct sk_buff *skb, unsigned int len)
 {
+	struct sk_buff **fragp;
+	struct sk_buff *frag;
 	int offset = skb_headlen(skb);
 	int nfrags = skb_shinfo(skb)->nr_frags;
 	int i;
+	int err;
+
+	if (skb_cloned(skb) &&
+	    unlikely((err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC))))
+		return err;
 
 	for (i = 0; i < nfrags; i++) {
 		int end = offset + skb_shinfo(skb)->frags[i].size;
-		if (end > len) {
-			if (skb_cloned(skb)) {
-				if (pskb_expand_head(skb, 0, 0, GFP_ATOMIC))
-					return -ENOMEM;
-			}
-			if (len <= offset) {
-				put_page(skb_shinfo(skb)->frags[i].page);
-				skb_shinfo(skb)->nr_frags--;
-			} else {
-				skb_shinfo(skb)->frags[i].size = len - offset;
-			}
+
+		if (end < len) {
+			offset = end;
+			continue;
 		}
-		offset = end;
+
+		if (len > offset)
+			skb_shinfo(skb)->frags[i++].size = len - offset;
+
+		skb_shinfo(skb)->nr_frags = i;
+
+		for (; i < nfrags; i++)
+			put_page(skb_shinfo(skb)->frags[i].page);
+
+		if (skb_shinfo(skb)->frag_list)
+			skb_drop_fraglist(skb);
+		break;
 	}
 
-	if (offset < len) {
+	for (fragp = &skb_shinfo(skb)->frag_list; (frag = *fragp);
+	     fragp = &frag->next) {
+		int end = offset + frag->len;
+
+		if (skb_shared(frag)) {
+			struct sk_buff *nfrag;
+
+			nfrag = skb_clone(frag, GFP_ATOMIC);
+			if (unlikely(!nfrag))
+				return -ENOMEM;
+
+			nfrag->next = frag->next;
+			frag = nfrag;
+			*fragp = frag;
+		}
+
+		if (end < len) {
+			offset = end;
+			continue;
+		}
+
+		if (end > len &&
+		    unlikely((err = pskb_trim(frag, len - offset))))
+			return err;
+
+		if (frag->next)
+			skb_drop_list(&frag->next);
+		break;
+	}
+
+	if (len > skb_headlen(skb)) {
 		skb->data_len -= skb->len - len;
 		skb->len       = len;
 	} else {
-		if (len <= skb_headlen(skb)) {
-			skb->len      = len;
-			skb->data_len = 0;
-			skb->tail     = skb->data + len;
-			if (skb_shinfo(skb)->frag_list && !skb_cloned(skb))
-				skb_drop_fraglist(skb);
-		} else {
-			skb->data_len -= skb->len - len;
-			skb->len       = len;
-		}
+		skb->len       = len;
+		skb->data_len  = 0;
+		skb->tail      = skb->data + len;
 	}
 
 	return 0;
diff --git a/net/ipv4/ip_input.c b/net/ipv4/ip_input.c
index e1a7dba..184c78c 100644
--- a/net/ipv4/ip_input.c
+++ b/net/ipv4/ip_input.c
@@ -428,6 +428,9 @@
 		goto drop;
 	}
 
+	/* Remove any debris in the socket control block */
+	memset(&(IPCB(skb)->opt), 0, sizeof(struct ip_options));
+
 	return NF_HOOK(PF_INET, NF_IP_PRE_ROUTING, skb, dev, NULL,
 		       ip_rcv_finish);
 
diff --git a/net/sched/sch_htb.c b/net/sched/sch_htb.c
index 34afe41..cd0a973 100644
--- a/net/sched/sch_htb.c
+++ b/net/sched/sch_htb.c
@@ -196,7 +196,7 @@
     struct qdisc_rate_table *rate;	/* rate table of the class itself */
     struct qdisc_rate_table *ceil;	/* ceiling rate (limits borrows too) */
     long buffer,cbuffer;		/* token bucket depth/rate */
-    long mbuffer;			/* max wait time */
+    psched_tdiff_t mbuffer;		/* max wait time */
     long tokens,ctokens;		/* current number of tokens */
     psched_time_t t_c;			/* checkpoint time */
 };
@@ -1601,7 +1601,7 @@
 		/* set class to be in HTB_CAN_SEND state */
 		cl->tokens = hopt->buffer;
 		cl->ctokens = hopt->cbuffer;
-		cl->mbuffer = 60000000; /* 1min */
+		cl->mbuffer = PSCHED_JIFFIE2US(HZ*60) /* 1min */
 		PSCHED_GET_TIME(cl->t_c);
 		cl->cmode = HTB_CAN_SEND;
 
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 2e8b4df..a91c961 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -523,12 +523,16 @@
 			goto out_free;
 		}
 
-		rc = may_context_mount_sb_relabel(sid, sbsec, tsec);
-		if (rc)
-			goto out_free;
-
-		if (!fscontext)
+		if (!fscontext) {
+			rc = may_context_mount_sb_relabel(sid, sbsec, tsec);
+			if (rc)
+				goto out_free;
 			sbsec->sid = sid;
+		} else {
+			rc = may_context_mount_inode_relabel(sid, sbsec, tsec);
+			if (rc)
+				goto out_free;
+		}
 		sbsec->mntpoint_sid = sid;
 
 		sbsec->behavior = SECURITY_FS_USE_MNTPOINT;